Home | History | Annotate | Download | only in coders
      1 /*
      2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      3 %                                                                             %
      4 %                                                                             %
      5 %                                                                             %
      6 %                             M   M  SSSSS  L                                 %
      7 %                             MM MM  SS     L                                 %
      8 %                             M M M   SSS   L                                 %
      9 %                             M   M     SS  L                                 %
     10 %                             M   M  SSSSS  LLLLL                             %
     11 %                                                                             %
     12 %                                                                             %
     13 %                    Execute Magick Scripting Language Scripts.               %
     14 %                                                                             %
     15 %                              Software Design                                %
     16 %                                   Cristy                                    %
     17 %                             Leonard Rosenthol                               %
     18 %                             William Radcliffe                               %
     19 %                               December 2001                                 %
     20 %                                                                             %
     21 %                                                                             %
     22 %  Copyright 1999-2019 ImageMagick Studio LLC, a non-profit organization      %
     23 %  dedicated to making software imaging solutions freely available.           %
     24 %                                                                             %
     25 %  You may not use this file except in compliance with the License.  You may  %
     26 %  obtain a copy of the License at                                            %
     27 %                                                                             %
     28 %    https://imagemagick.org/script/license.php                               %
     29 %                                                                             %
     30 %  Unless required by applicable law or agreed to in writing, software        %
     31 %  distributed under the License is distributed on an "AS IS" BASIS,          %
     32 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
     33 %  See the License for the specific language governing permissions and        %
     34 %  limitations under the License.                                             %
     35 %                                                                             %
     36 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     37 %
     38 %
     39 */
     40 
     41 /*
     43   Include declarations.
     44 */
     45 #include "MagickCore/studio.h"
     46 #include "MagickCore/annotate.h"
     47 #include "MagickCore/artifact.h"
     48 #include "MagickCore/attribute.h"
     49 #include "MagickCore/blob.h"
     50 #include "MagickCore/blob-private.h"
     51 #include "MagickCore/cache.h"
     52 #include "MagickCore/cache-view.h"
     53 #include "MagickCore/channel.h"
     54 #include "MagickCore/color.h"
     55 #include "MagickCore/color-private.h"
     56 #include "MagickCore/colormap.h"
     57 #include "MagickCore/composite.h"
     58 #include "MagickCore/constitute.h"
     59 #include "MagickCore/decorate.h"
     60 #include "MagickCore/display.h"
     61 #include "MagickCore/distort.h"
     62 #include "MagickCore/draw.h"
     63 #include "MagickCore/effect.h"
     64 #include "MagickCore/enhance.h"
     65 #include "MagickCore/exception.h"
     66 #include "MagickCore/exception-private.h"
     67 #include "MagickCore/fx.h"
     68 #include "MagickCore/geometry.h"
     69 #include "MagickCore/image.h"
     70 #include "MagickCore/image-private.h"
     71 #include "MagickCore/list.h"
     72 #include "MagickCore/log.h"
     73 #include "MagickCore/magick.h"
     74 #include "MagickCore/memory_.h"
     75 #include "MagickCore/module.h"
     76 #include "MagickCore/option.h"
     77 #include "MagickCore/paint.h"
     78 #include "MagickCore/pixel-accessor.h"
     79 #include "MagickCore/profile.h"
     80 #include "MagickCore/property.h"
     81 #include "MagickCore/quantize.h"
     82 #include "MagickCore/quantum-private.h"
     83 #include "MagickCore/registry.h"
     84 #include "MagickCore/resize.h"
     85 #include "MagickCore/resource_.h"
     86 #include "MagickCore/segment.h"
     87 #include "MagickCore/shear.h"
     88 #include "MagickCore/signature.h"
     89 #include "MagickCore/statistic.h"
     90 #include "MagickCore/static.h"
     91 #include "MagickCore/string_.h"
     92 #include "MagickCore/string-private.h"
     93 #include "MagickCore/transform.h"
     94 #include "MagickCore/threshold.h"
     95 #include "MagickCore/utility.h"
     96 #if defined(MAGICKCORE_XML_DELEGATE)
     97 #  if defined(MAGICKCORE_WINDOWS_SUPPORT)
     98 #    if !defined(__MINGW32__)
     99 #      include <win32config.h>
    100 #    endif
    101 #  endif
    102 #  include <libxml/xmlmemory.h>
    103 #  include <libxml/parserInternals.h>
    104 #  include <libxml/xmlerror.h>
    105 #endif
    106 
    107 /*
    109   Define Declatations.
    110 */
    111 #define ThrowMSLException(severity,tag,reason) \
    112   (void) ThrowMagickException(msl_info->exception,GetMagickModule(),severity, \
    113     tag,"`%s'",reason);
    114 
    115 /*
    117   Typedef declaractions.
    118 */
    119 typedef struct _MSLGroupInfo
    120 {
    121   size_t
    122     numImages;  /* how many images are in this group */
    123 } MSLGroupInfo;
    124 
    125 typedef struct _MSLInfo
    126 {
    127   ExceptionInfo
    128     *exception;
    129 
    130   ssize_t
    131     n,
    132     number_groups;
    133 
    134   ImageInfo
    135     **image_info;
    136 
    137   DrawInfo
    138    **draw_info;
    139 
    140   Image
    141     **attributes,
    142     **image;
    143 
    144   char
    145     *content;
    146 
    147   MSLGroupInfo
    148     *group_info;
    149 
    150 #if defined(MAGICKCORE_XML_DELEGATE)
    151   xmlParserCtxtPtr
    152     parser;
    153 
    154   xmlDocPtr
    155     document;
    156 #endif
    157 } MSLInfo;
    158 
    159 /*
    161   Forward declarations.
    162 */
    163 #if defined(MAGICKCORE_XML_DELEGATE)
    164 static MagickBooleanType
    165   WriteMSLImage(const ImageInfo *,Image *,ExceptionInfo *);
    166 
    167 static MagickBooleanType
    168   SetMSLAttributes(MSLInfo *,const char *,const char *);
    169 #endif
    170 
    171 #if defined(MAGICKCORE_XML_DELEGATE)
    173 
    174 /*
    176 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    177 %                                                                             %
    178 %                                                                             %
    179 %                                                                             %
    180 %   R e a d M S L I m a g e                                                   %
    181 %                                                                             %
    182 %                                                                             %
    183 %                                                                             %
    184 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    185 %
    186 %  ReadMSLImage() reads a Magick Scripting Language file and returns it.
    187 %  It allocates the memory necessary for the new Image structure and returns a
    188 %  pointer to the new image.
    189 %
    190 %  The format of the ReadMSLImage method is:
    191 %
    192 %      Image *ReadMSLImage(const ImageInfo *image_info,ExceptionInfo *exception)
    193 %
    194 %  A description of each parameter follows:
    195 %
    196 %    o image_info: the image info.
    197 %
    198 %    o exception: return any errors or warnings in this structure.
    199 %
    200 */
    201 
    202 #if defined(__cplusplus) || defined(c_plusplus)
    203 extern "C" {
    204 #endif
    205 
    206 static inline Image *GetImageCache(const ImageInfo *image_info,const char *path,
    207   ExceptionInfo *exception)
    208 {
    209   char
    210     key[MagickPathExtent];
    211 
    212   ExceptionInfo
    213     *sans_exception;
    214 
    215   Image
    216     *image;
    217 
    218   ImageInfo
    219     *read_info;
    220 
    221   (void) FormatLocaleString(key,MagickPathExtent,"cache:%s",path);
    222   sans_exception=AcquireExceptionInfo();
    223   image=(Image *) GetImageRegistry(ImageRegistryType,key,sans_exception);
    224   sans_exception=DestroyExceptionInfo(sans_exception);
    225   if (image != (Image *) NULL)
    226     return(image);
    227   read_info=CloneImageInfo(image_info);
    228   (void) CopyMagickString(read_info->filename,path,MagickPathExtent);
    229   image=ReadImage(read_info,exception);
    230   read_info=DestroyImageInfo(read_info);
    231   if (image != (Image *) NULL)
    232     (void) SetImageRegistry(ImageRegistryType,key,image,exception);
    233   return(image);
    234 }
    235 
    236 static int IsPathDirectory(const char *path)
    237 {
    238   MagickBooleanType
    239     status;
    240 
    241   struct stat
    242     attributes;
    243 
    244   if ((path == (const char *) NULL) || (*path == '\0'))
    245     return(MagickFalse);
    246   status=GetPathAttributes(path,&attributes);
    247   if (status == MagickFalse)
    248     return(-1);
    249   if (S_ISDIR(attributes.st_mode) == 0)
    250     return(0);
    251   return(1);
    252 }
    253 
    254 static int MSLIsStandalone(void *context)
    255 {
    256   MSLInfo
    257     *msl_info;
    258 
    259   /*
    260     Is this document tagged standalone?
    261   */
    262   (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  SAX.MSLIsStandalone()");
    263   msl_info=(MSLInfo *) context;
    264   return(msl_info->document->standalone == 1);
    265 }
    266 
    267 static int MSLHasInternalSubset(void *context)
    268 {
    269   MSLInfo
    270     *msl_info;
    271 
    272   /*
    273     Does this document has an internal subset?
    274   */
    275   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
    276     "  SAX.MSLHasInternalSubset()");
    277   msl_info=(MSLInfo *) context;
    278   return(msl_info->document->intSubset != NULL);
    279 }
    280 
    281 static int MSLHasExternalSubset(void *context)
    282 {
    283   MSLInfo
    284     *msl_info;
    285 
    286   /*
    287     Does this document has an external subset?
    288   */
    289   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
    290     "  SAX.MSLHasExternalSubset()");
    291   msl_info=(MSLInfo *) context;
    292   return(msl_info->document->extSubset != NULL);
    293 }
    294 
    295 static void MSLInternalSubset(void *context,const xmlChar *name,
    296   const xmlChar *external_id,const xmlChar *system_id)
    297 {
    298   MSLInfo
    299     *msl_info;
    300 
    301   /*
    302     Does this document has an internal subset?
    303   */
    304   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
    305     "  SAX.internalSubset(%s %s %s)",name,
    306     (external_id != (const xmlChar *) NULL ? (const char *) external_id : " "),
    307     (system_id != (const xmlChar *) NULL ? (const char *) system_id : " "));
    308   msl_info=(MSLInfo *) context;
    309   (void) xmlCreateIntSubset(msl_info->document,name,external_id,system_id);
    310 }
    311 
    312 static xmlParserInputPtr MSLResolveEntity(void *context,
    313   const xmlChar *public_id,const xmlChar *system_id)
    314 {
    315   MSLInfo
    316     *msl_info;
    317 
    318   xmlParserInputPtr
    319     stream;
    320 
    321   /*
    322     Special entity resolver, better left to the parser, it has more
    323     context than the application layer.  The default behaviour is to
    324     not resolve the entities, in that case the ENTITY_REF nodes are
    325     built in the structure (and the parameter values).
    326   */
    327   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
    328     "  SAX.resolveEntity(%s, %s)",
    329     (public_id != (const xmlChar *) NULL ? (const char *) public_id : "none"),
    330     (system_id != (const xmlChar *) NULL ? (const char *) system_id : "none"));
    331   msl_info=(MSLInfo *) context;
    332   stream=xmlLoadExternalEntity((const char *) system_id,(const char *)
    333     public_id,msl_info->parser);
    334   return(stream);
    335 }
    336 
    337 static xmlEntityPtr MSLGetEntity(void *context,const xmlChar *name)
    338 {
    339   MSLInfo
    340     *msl_info;
    341 
    342   /*
    343     Get an entity by name.
    344   */
    345   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
    346     "  SAX.MSLGetEntity(%s)",(const char *) name);
    347   msl_info=(MSLInfo *) context;
    348   return(xmlGetDocEntity(msl_info->document,name));
    349 }
    350 
    351 static xmlEntityPtr MSLGetParameterEntity(void *context,const xmlChar *name)
    352 {
    353   MSLInfo
    354     *msl_info;
    355 
    356   /*
    357     Get a parameter entity by name.
    358   */
    359   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
    360     "  SAX.getParameterEntity(%s)",(const char *) name);
    361   msl_info=(MSLInfo *) context;
    362   return(xmlGetParameterEntity(msl_info->document,name));
    363 }
    364 
    365 static void MSLEntityDeclaration(void *context,const xmlChar *name,int type,
    366   const xmlChar *public_id,const xmlChar *system_id,xmlChar *content)
    367 {
    368   MSLInfo
    369     *msl_info;
    370 
    371   /*
    372     An entity definition has been parsed.
    373   */
    374   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
    375     "  SAX.entityDecl(%s, %d, %s, %s, %s)",name,type,
    376     public_id != (const xmlChar *) NULL ? (const char *) public_id : "none",
    377     system_id != (const xmlChar *) NULL ? (const char *) system_id : "none",
    378     content);
    379   msl_info=(MSLInfo *) context;
    380   if (msl_info->parser->inSubset == 1)
    381     (void) xmlAddDocEntity(msl_info->document,name,type,public_id,system_id,
    382       content);
    383   else
    384     if (msl_info->parser->inSubset == 2)
    385       (void) xmlAddDtdEntity(msl_info->document,name,type,public_id,system_id,
    386         content);
    387 }
    388 
    389 static void MSLAttributeDeclaration(void *context,const xmlChar *element,
    390   const xmlChar *name,int type,int value,const xmlChar *default_value,
    391   xmlEnumerationPtr tree)
    392 {
    393   MSLInfo
    394     *msl_info;
    395 
    396   xmlChar
    397     *fullname,
    398     *prefix;
    399 
    400   xmlParserCtxtPtr
    401     parser;
    402 
    403   /*
    404     An attribute definition has been parsed.
    405   */
    406   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
    407     "  SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",element,name,type,value,
    408     default_value);
    409   msl_info=(MSLInfo *) context;
    410   fullname=(xmlChar *) NULL;
    411   prefix=(xmlChar *) NULL;
    412   parser=msl_info->parser;
    413   fullname=(xmlChar *) xmlSplitQName(parser,name,&prefix);
    414   if (parser->inSubset == 1)
    415     (void) xmlAddAttributeDecl(&parser->vctxt,msl_info->document->intSubset,
    416       element,fullname,prefix,(xmlAttributeType) type,
    417       (xmlAttributeDefault) value,default_value,tree);
    418   else
    419     if (parser->inSubset == 2)
    420       (void) xmlAddAttributeDecl(&parser->vctxt,msl_info->document->extSubset,
    421         element,fullname,prefix,(xmlAttributeType) type,
    422         (xmlAttributeDefault) value,default_value,tree);
    423   if (prefix != (xmlChar *) NULL)
    424     xmlFree(prefix);
    425   if (fullname != (xmlChar *) NULL)
    426     xmlFree(fullname);
    427 }
    428 
    429 static void MSLElementDeclaration(void *context,const xmlChar *name,int type,
    430   xmlElementContentPtr content)
    431 {
    432   MSLInfo
    433     *msl_info;
    434 
    435   xmlParserCtxtPtr
    436     parser;
    437 
    438   /*
    439     An element definition has been parsed.
    440   */
    441   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
    442     "  SAX.elementDecl(%s, %d, ...)",name,type);
    443   msl_info=(MSLInfo *) context;
    444   parser=msl_info->parser;
    445   if (parser->inSubset == 1)
    446     (void) xmlAddElementDecl(&parser->vctxt,msl_info->document->intSubset,
    447       name,(xmlElementTypeVal) type,content);
    448   else
    449     if (parser->inSubset == 2)
    450       (void) xmlAddElementDecl(&parser->vctxt,msl_info->document->extSubset,
    451         name,(xmlElementTypeVal) type,content);
    452 }
    453 
    454 static void MSLNotationDeclaration(void *context,const xmlChar *name,
    455   const xmlChar *public_id,const xmlChar *system_id)
    456 {
    457   MSLInfo
    458     *msl_info;
    459 
    460   xmlParserCtxtPtr
    461     parser;
    462 
    463   /*
    464     What to do when a notation declaration has been parsed.
    465   */
    466   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
    467     "  SAX.notationDecl(%s, %s, %s)",name,
    468     public_id != (const xmlChar *) NULL ? (const char *) public_id : "none",
    469     system_id != (const xmlChar *) NULL ? (const char *) system_id : "none");
    470   msl_info=(MSLInfo *) context;
    471   parser=msl_info->parser;
    472   if (parser->inSubset == 1)
    473     (void) xmlAddNotationDecl(&parser->vctxt,msl_info->document->intSubset,
    474       name,public_id,system_id);
    475   else
    476     if (parser->inSubset == 2)
    477       (void) xmlAddNotationDecl(&parser->vctxt,msl_info->document->intSubset,
    478         name,public_id,system_id);
    479 }
    480 
    481 static void MSLUnparsedEntityDeclaration(void *context,const xmlChar *name,
    482   const xmlChar *public_id,const xmlChar *system_id,const xmlChar *notation)
    483 {
    484   MSLInfo
    485     *msl_info;
    486 
    487   /*
    488     What to do when an unparsed entity declaration is parsed.
    489   */
    490   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
    491     "  SAX.unparsedEntityDecl(%s, %s, %s, %s)",name,
    492     public_id != (const xmlChar *) NULL ? (const char *) public_id : "none",
    493     system_id != (const xmlChar *) NULL ? (const char *) system_id : "none",
    494     notation);
    495   msl_info=(MSLInfo *) context;
    496   (void) xmlAddDocEntity(msl_info->document,name,
    497     XML_EXTERNAL_GENERAL_UNPARSED_ENTITY,public_id,system_id,notation);
    498 
    499 }
    500 
    501 static void MSLSetDocumentLocator(void *context,xmlSAXLocatorPtr location)
    502 {
    503   MSLInfo
    504     *msl_info;
    505 
    506   /*
    507     Receive the document locator at startup, actually xmlDefaultSAXLocator.
    508   */
    509   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
    510     "  SAX.setDocumentLocator()\n");
    511   (void) location;
    512   msl_info=(MSLInfo *) context;
    513   (void) msl_info;
    514 }
    515 
    516 static void MSLStartDocument(void *context)
    517 {
    518   MSLInfo
    519     *msl_info;
    520 
    521   xmlParserCtxtPtr
    522     parser;
    523 
    524   /*
    525     Called when the document start being processed.
    526   */
    527   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
    528     "  SAX.startDocument()");
    529   msl_info=(MSLInfo *) context;
    530   parser=msl_info->parser;
    531   msl_info->document=xmlNewDoc(parser->version);
    532   if (msl_info->document == (xmlDocPtr) NULL)
    533     return;
    534   if (parser->encoding == NULL)
    535     msl_info->document->encoding=NULL;
    536   else
    537     msl_info->document->encoding=xmlStrdup(parser->encoding);
    538   msl_info->document->standalone=parser->standalone;
    539 }
    540 
    541 static void MSLEndDocument(void *context)
    542 {
    543   MSLInfo
    544     *msl_info;
    545 
    546   /*
    547     Called when the document end has been detected.
    548   */
    549   (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  SAX.endDocument()");
    550   msl_info=(MSLInfo *) context;
    551   if (msl_info->content != (char *) NULL)
    552     msl_info->content=DestroyString(msl_info->content);
    553 }
    554 
    555 static void MSLPushImage(MSLInfo *msl_info,Image *image)
    556 {
    557   ssize_t
    558     n;
    559 
    560   if (image != (Image *) NULL)
    561     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
    562   assert(msl_info != (MSLInfo *) NULL);
    563   msl_info->n++;
    564   n=msl_info->n;
    565   msl_info->image_info=(ImageInfo **) ResizeQuantumMemory(msl_info->image_info,
    566     (n+1),sizeof(*msl_info->image_info));
    567   msl_info->draw_info=(DrawInfo **) ResizeQuantumMemory(msl_info->draw_info,
    568     (n+1),sizeof(*msl_info->draw_info));
    569   msl_info->attributes=(Image **) ResizeQuantumMemory(msl_info->attributes,
    570     (n+1),sizeof(*msl_info->attributes));
    571   msl_info->image=(Image **) ResizeQuantumMemory(msl_info->image,(n+1),
    572     sizeof(*msl_info->image));
    573   if ((msl_info->image_info == (ImageInfo **) NULL) ||
    574       (msl_info->draw_info == (DrawInfo **) NULL) ||
    575       (msl_info->attributes == (Image **) NULL) ||
    576       (msl_info->image == (Image **) NULL))
    577     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed")
    578   msl_info->image_info[n]=CloneImageInfo(msl_info->image_info[n-1]);
    579   msl_info->draw_info[n]=CloneDrawInfo(msl_info->image_info[n-1],
    580     msl_info->draw_info[n-1]);
    581   if (image == (Image *) NULL)
    582     msl_info->attributes[n]=AcquireImage(msl_info->image_info[n],
    583       msl_info->exception);
    584   else
    585     msl_info->attributes[n]=CloneImage(image,0,0,MagickTrue,
    586       msl_info->exception);
    587   msl_info->image[n]=(Image *) image;
    588   if ((msl_info->image_info[n] == (ImageInfo *) NULL) ||
    589       (msl_info->attributes[n] == (Image *) NULL))
    590     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed")
    591   if (msl_info->number_groups != 0)
    592     msl_info->group_info[msl_info->number_groups-1].numImages++;
    593 }
    594 
    595 static void MSLPopImage(MSLInfo *msl_info)
    596 {
    597   if (msl_info->number_groups != 0)
    598     return;
    599   if (msl_info->image[msl_info->n] != (Image *) NULL)
    600     msl_info->image[msl_info->n]=DestroyImage(msl_info->image[msl_info->n]);
    601   msl_info->attributes[msl_info->n]=DestroyImage(
    602     msl_info->attributes[msl_info->n]);
    603   msl_info->draw_info[msl_info->n]=DestroyDrawInfo(
    604     msl_info->draw_info[msl_info->n]);
    605   msl_info->image_info[msl_info->n]=DestroyImageInfo(
    606     msl_info->image_info[msl_info->n]);
    607   msl_info->n--;
    608 }
    609 
    610 static void MSLStartElement(void *context,const xmlChar *tag,
    611   const xmlChar **attributes)
    612 {
    613   AffineMatrix
    614     affine,
    615     current;
    616 
    617   ChannelType
    618     channel;
    619 
    620   ChannelType
    621     channel_mask;
    622 
    623   char
    624     *attribute,
    625     key[MagickPathExtent],
    626     *value;
    627 
    628   const char
    629     *keyword;
    630 
    631   double
    632     angle;
    633 
    634   DrawInfo
    635     *draw_info;
    636 
    637   ExceptionInfo
    638     *exception;
    639 
    640   GeometryInfo
    641     geometry_info;
    642 
    643   Image
    644     *image;
    645 
    646   int
    647     flags;
    648 
    649   ssize_t
    650     option,
    651     j,
    652     n,
    653     x,
    654     y;
    655 
    656   MSLInfo
    657     *msl_info;
    658 
    659   RectangleInfo
    660     geometry;
    661 
    662   register ssize_t
    663     i;
    664 
    665   size_t
    666     height,
    667     width;
    668 
    669   /*
    670     Called when an opening tag has been processed.
    671   */
    672   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
    673     "  SAX.startElement(%s",tag);
    674   exception=AcquireExceptionInfo();
    675   msl_info=(MSLInfo *) context;
    676   n=msl_info->n;
    677   keyword=(const char *) NULL;
    678   value=(char *) NULL;
    679   SetGeometryInfo(&geometry_info);
    680   (void) memset(&geometry,0,sizeof(geometry));
    681   channel=DefaultChannels;
    682   switch (*tag)
    683   {
    684     case 'A':
    685     case 'a':
    686     {
    687       if (LocaleCompare((const char *) tag,"add-noise") == 0)
    688         {
    689           Image
    690             *noise_image;
    691 
    692           NoiseType
    693             noise;
    694 
    695           /*
    696             Add noise image.
    697           */
    698           if (msl_info->image[n] == (Image *) NULL)
    699             {
    700               ThrowMSLException(OptionError,"NoImagesDefined",
    701                 (const char *) tag);
    702               break;
    703             }
    704           noise=UniformNoise;
    705           if (attributes != (const xmlChar **) NULL)
    706             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
    707             {
    708               keyword=(const char *) attributes[i++];
    709               attribute=InterpretImageProperties(msl_info->image_info[n],
    710                 msl_info->attributes[n],(const char *) attributes[i],
    711                 exception);
    712               CloneString(&value,attribute);
    713               attribute=DestroyString(attribute);
    714               switch (*keyword)
    715               {
    716                 case 'C':
    717                 case 'c':
    718                 {
    719                   if (LocaleCompare(keyword,"channel") == 0)
    720                     {
    721                       option=ParseChannelOption(value);
    722                       if (option < 0)
    723                         ThrowMSLException(OptionError,"UnrecognizedChannelType",
    724                           value);
    725                       channel=(ChannelType) option;
    726                       break;
    727                     }
    728                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
    729                     keyword);
    730                   break;
    731                 }
    732                 case 'N':
    733                 case 'n':
    734                 {
    735                   if (LocaleCompare(keyword,"noise") == 0)
    736                     {
    737                       option=ParseCommandOption(MagickNoiseOptions,MagickFalse,
    738                         value);
    739                       if (option < 0)
    740                         ThrowMSLException(OptionError,"UnrecognizedNoiseType",
    741                           value);
    742                       noise=(NoiseType) option;
    743                       break;
    744                     }
    745                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
    746                     keyword);
    747                   break;
    748                 }
    749                 default:
    750                 {
    751                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
    752                     keyword);
    753                   break;
    754                 }
    755               }
    756             }
    757           channel_mask=SetImageChannelMask(msl_info->image[n],channel);
    758           noise_image=AddNoiseImage(msl_info->image[n],noise,1.0,
    759             msl_info->exception);
    760           (void) SetPixelChannelMask(msl_info->image[n],channel_mask);
    761           if (noise_image == (Image *) NULL)
    762             break;
    763           msl_info->image[n]=DestroyImage(msl_info->image[n]);
    764           msl_info->image[n]=noise_image;
    765           break;
    766         }
    767       if (LocaleCompare((const char *) tag,"annotate") == 0)
    768         {
    769           char
    770             text[MagickPathExtent];
    771 
    772           /*
    773             Annotate image.
    774           */
    775           if (msl_info->image[n] == (Image *) NULL)
    776             {
    777               ThrowMSLException(OptionError,"NoImagesDefined",
    778                 (const char *) tag);
    779               break;
    780             }
    781           draw_info=CloneDrawInfo(msl_info->image_info[n],
    782             msl_info->draw_info[n]);
    783           angle=0.0;
    784           current=draw_info->affine;
    785           GetAffineMatrix(&affine);
    786           if (attributes != (const xmlChar **) NULL)
    787             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
    788             {
    789               keyword=(const char *) attributes[i++];
    790               attribute=InterpretImageProperties(msl_info->image_info[n],
    791                 msl_info->attributes[n],(const char *) attributes[i],
    792                 exception);
    793               CloneString(&value,attribute);
    794               attribute=DestroyString(attribute);
    795               switch (*keyword)
    796               {
    797                 case 'A':
    798                 case 'a':
    799                 {
    800                   if (LocaleCompare(keyword,"affine") == 0)
    801                     {
    802                       char
    803                         *p;
    804 
    805                       p=value;
    806                       draw_info->affine.sx=StringToDouble(p,&p);
    807                       if (*p ==',')
    808                         p++;
    809                       draw_info->affine.rx=StringToDouble(p,&p);
    810                       if (*p ==',')
    811                         p++;
    812                       draw_info->affine.ry=StringToDouble(p,&p);
    813                       if (*p ==',')
    814                         p++;
    815                       draw_info->affine.sy=StringToDouble(p,&p);
    816                       if (*p ==',')
    817                         p++;
    818                       draw_info->affine.tx=StringToDouble(p,&p);
    819                       if (*p ==',')
    820                         p++;
    821                       draw_info->affine.ty=StringToDouble(p,&p);
    822                       break;
    823                     }
    824                   if (LocaleCompare(keyword,"align") == 0)
    825                     {
    826                       option=ParseCommandOption(MagickAlignOptions,MagickFalse,
    827                         value);
    828                       if (option < 0)
    829                         ThrowMSLException(OptionError,"UnrecognizedAlignType",
    830                           value);
    831                       draw_info->align=(AlignType) option;
    832                       break;
    833                     }
    834                   if (LocaleCompare(keyword,"antialias") == 0)
    835                     {
    836                       option=ParseCommandOption(MagickBooleanOptions,
    837                         MagickFalse,value);
    838                       if (option < 0)
    839                         ThrowMSLException(OptionError,"UnrecognizedBooleanType",
    840                           value);
    841                       draw_info->stroke_antialias=(MagickBooleanType) option;
    842                       draw_info->text_antialias=(MagickBooleanType) option;
    843                       break;
    844                     }
    845                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
    846                     keyword);
    847                   break;
    848                 }
    849                 case 'D':
    850                 case 'd':
    851                 {
    852                   if (LocaleCompare(keyword,"density") == 0)
    853                     {
    854                       CloneString(&draw_info->density,value);
    855                       break;
    856                     }
    857                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
    858                     keyword);
    859                   break;
    860                 }
    861                 case 'E':
    862                 case 'e':
    863                 {
    864                   if (LocaleCompare(keyword,"encoding") == 0)
    865                     {
    866                       CloneString(&draw_info->encoding,value);
    867                       break;
    868                     }
    869                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
    870                     keyword);
    871                   break;
    872                 }
    873                 case 'F':
    874                 case 'f':
    875                 {
    876                   if (LocaleCompare(keyword, "fill") == 0)
    877                     {
    878                       (void) QueryColorCompliance(value,AllCompliance,
    879                         &draw_info->fill,exception);
    880                       break;
    881                     }
    882                   if (LocaleCompare(keyword,"family") == 0)
    883                     {
    884                       CloneString(&draw_info->family,value);
    885                       break;
    886                     }
    887                   if (LocaleCompare(keyword,"font") == 0)
    888                     {
    889                       CloneString(&draw_info->font,value);
    890                       break;
    891                     }
    892                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
    893                     keyword);
    894                   break;
    895                 }
    896                 case 'G':
    897                 case 'g':
    898                 {
    899                   if (LocaleCompare(keyword,"geometry") == 0)
    900                     {
    901                       flags=ParseGravityGeometry(msl_info->image[n],value,
    902                         &geometry,exception);
    903                       break;
    904                     }
    905                   if (LocaleCompare(keyword,"gravity") == 0)
    906                     {
    907                       option=ParseCommandOption(MagickGravityOptions,
    908                         MagickFalse,value);
    909                       if (option < 0)
    910                         ThrowMSLException(OptionError,"UnrecognizedGravityType",
    911                           value);
    912                       draw_info->gravity=(GravityType) option;
    913                       break;
    914                     }
    915                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
    916                     keyword);
    917                   break;
    918                 }
    919                 case 'P':
    920                 case 'p':
    921                 {
    922                   if (LocaleCompare(keyword,"pointsize") == 0)
    923                     {
    924                       draw_info->pointsize=StringToDouble(value,(char **) NULL);
    925                       break;
    926                     }
    927                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
    928                     keyword);
    929                   break;
    930                 }
    931                 case 'R':
    932                 case 'r':
    933                 {
    934                   if (LocaleCompare(keyword,"rotate") == 0)
    935                     {
    936                       angle=StringToDouble(value,(char **) NULL);
    937                       affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
    938                       affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
    939                       affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
    940                       affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
    941                       break;
    942                     }
    943                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
    944                     keyword);
    945                   break;
    946                 }
    947                 case 'S':
    948                 case 's':
    949                 {
    950                   if (LocaleCompare(keyword,"scale") == 0)
    951                     {
    952                       flags=ParseGeometry(value,&geometry_info);
    953                       if ((flags & SigmaValue) == 0)
    954                         geometry_info.sigma=1.0;
    955                       affine.sx=geometry_info.rho;
    956                       affine.sy=geometry_info.sigma;
    957                       break;
    958                     }
    959                   if (LocaleCompare(keyword,"skewX") == 0)
    960                     {
    961                       angle=StringToDouble(value,(char **) NULL);
    962                       affine.ry=tan(DegreesToRadians(fmod((double) angle,
    963                         360.0)));
    964                       break;
    965                     }
    966                   if (LocaleCompare(keyword,"skewY") == 0)
    967                     {
    968                       angle=StringToDouble(value,(char **) NULL);
    969                       affine.rx=tan(DegreesToRadians(fmod((double) angle,
    970                         360.0)));
    971                       break;
    972                     }
    973                   if (LocaleCompare(keyword,"stretch") == 0)
    974                     {
    975                       option=ParseCommandOption(MagickStretchOptions,
    976                         MagickFalse,value);
    977                       if (option < 0)
    978                         ThrowMSLException(OptionError,"UnrecognizedStretchType",
    979                           value);
    980                       draw_info->stretch=(StretchType) option;
    981                       break;
    982                     }
    983                   if (LocaleCompare(keyword, "stroke") == 0)
    984                     {
    985                       (void) QueryColorCompliance(value,AllCompliance,
    986                         &draw_info->stroke,exception);
    987                       break;
    988                     }
    989                   if (LocaleCompare(keyword,"strokewidth") == 0)
    990                     {
    991                       draw_info->stroke_width=StringToLong(value);
    992                       break;
    993                     }
    994                   if (LocaleCompare(keyword,"style") == 0)
    995                     {
    996                       option=ParseCommandOption(MagickStyleOptions,MagickFalse,
    997                         value);
    998                       if (option < 0)
    999                         ThrowMSLException(OptionError,"UnrecognizedStyleType",
   1000                           value);
   1001                       draw_info->style=(StyleType) option;
   1002                       break;
   1003                     }
   1004                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   1005                     keyword);
   1006                   break;
   1007                 }
   1008                 case 'T':
   1009                 case 't':
   1010                 {
   1011                   if (LocaleCompare(keyword,"text") == 0)
   1012                     {
   1013                       CloneString(&draw_info->text,value);
   1014                       break;
   1015                     }
   1016                   if (LocaleCompare(keyword,"translate") == 0)
   1017                     {
   1018                       flags=ParseGeometry(value,&geometry_info);
   1019                       if ((flags & SigmaValue) == 0)
   1020                         geometry_info.sigma=1.0;
   1021                       affine.tx=geometry_info.rho;
   1022                       affine.ty=geometry_info.sigma;
   1023                       break;
   1024                     }
   1025                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   1026                     keyword);
   1027                   break;
   1028                 }
   1029                 case 'U':
   1030                 case 'u':
   1031                 {
   1032                   if (LocaleCompare(keyword, "undercolor") == 0)
   1033                     {
   1034                       (void) QueryColorCompliance(value,AllCompliance,
   1035                         &draw_info->undercolor,exception);
   1036                       break;
   1037                     }
   1038                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   1039                     keyword);
   1040                   break;
   1041                 }
   1042                 case 'W':
   1043                 case 'w':
   1044                 {
   1045                   if (LocaleCompare(keyword,"weight") == 0)
   1046                     {
   1047                       draw_info->weight=StringToLong(value);
   1048                       break;
   1049                     }
   1050                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   1051                     keyword);
   1052                   break;
   1053                 }
   1054                 case 'X':
   1055                 case 'x':
   1056                 {
   1057                   if (LocaleCompare(keyword,"x") == 0)
   1058                     {
   1059                       geometry.x=StringToLong(value);
   1060                       break;
   1061                     }
   1062                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   1063                     keyword);
   1064                   break;
   1065                 }
   1066                 case 'Y':
   1067                 case 'y':
   1068                 {
   1069                   if (LocaleCompare(keyword,"y") == 0)
   1070                     {
   1071                       geometry.y=StringToLong(value);
   1072                       break;
   1073                     }
   1074                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   1075                     keyword);
   1076                   break;
   1077                 }
   1078                 default:
   1079                 {
   1080                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   1081                     keyword);
   1082                   break;
   1083                 }
   1084               }
   1085             }
   1086           (void) FormatLocaleString(text,MagickPathExtent,
   1087             "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,(double)
   1088             geometry.height,(double) geometry.x,(double) geometry.y);
   1089           CloneString(&draw_info->geometry,text);
   1090           draw_info->affine.sx=affine.sx*current.sx+affine.ry*current.rx;
   1091           draw_info->affine.rx=affine.rx*current.sx+affine.sy*current.rx;
   1092           draw_info->affine.ry=affine.sx*current.ry+affine.ry*current.sy;
   1093           draw_info->affine.sy=affine.rx*current.ry+affine.sy*current.sy;
   1094           draw_info->affine.tx=affine.sx*current.tx+affine.ry*current.ty+
   1095             affine.tx;
   1096           draw_info->affine.ty=affine.rx*current.tx+affine.sy*current.ty+
   1097             affine.ty;
   1098           (void) AnnotateImage(msl_info->image[n],draw_info,
   1099             msl_info->exception);
   1100           draw_info=DestroyDrawInfo(draw_info);
   1101           break;
   1102         }
   1103       if (LocaleCompare((const char *) tag,"append") == 0)
   1104         {
   1105           Image
   1106             *append_image;
   1107 
   1108           MagickBooleanType
   1109             stack;
   1110 
   1111           if (msl_info->image[n] == (Image *) NULL)
   1112             {
   1113               ThrowMSLException(OptionError,"NoImagesDefined",
   1114                 (const char *) tag);
   1115               break;
   1116             }
   1117           stack=MagickFalse;
   1118           if (attributes != (const xmlChar **) NULL)
   1119             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   1120             {
   1121               keyword=(const char *) attributes[i++];
   1122               attribute=InterpretImageProperties(msl_info->image_info[n],
   1123                 msl_info->attributes[n],(const char *) attributes[i],
   1124                 exception);
   1125               CloneString(&value,attribute);
   1126               attribute=DestroyString(attribute);
   1127               switch (*keyword)
   1128               {
   1129                 case 'S':
   1130                 case 's':
   1131                 {
   1132                   if (LocaleCompare(keyword,"stack") == 0)
   1133                     {
   1134                       option=ParseCommandOption(MagickBooleanOptions,
   1135                         MagickFalse,value);
   1136                       if (option < 0)
   1137                         ThrowMSLException(OptionError,"UnrecognizedBooleanType",
   1138                           value);
   1139                       stack=(MagickBooleanType) option;
   1140                       break;
   1141                     }
   1142                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   1143                     keyword);
   1144                   break;
   1145                 }
   1146                 default:
   1147                 {
   1148                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   1149                     keyword);
   1150                   break;
   1151                 }
   1152               }
   1153             }
   1154           append_image=AppendImages(msl_info->image[n],stack,
   1155             msl_info->exception);
   1156           if (append_image == (Image *) NULL)
   1157             break;
   1158           msl_info->image[n]=DestroyImage(msl_info->image[n]);
   1159           msl_info->image[n]=append_image;
   1160           break;
   1161         }
   1162       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
   1163       break;
   1164     }
   1165     case 'B':
   1166     case 'b':
   1167     {
   1168       if (LocaleCompare((const char *) tag,"blur") == 0)
   1169         {
   1170           Image
   1171             *blur_image;
   1172 
   1173           /*
   1174             Blur image.
   1175           */
   1176           if (msl_info->image[n] == (Image *) NULL)
   1177             {
   1178               ThrowMSLException(OptionError,"NoImagesDefined",
   1179                 (const char *) tag);
   1180               break;
   1181             }
   1182           if (attributes != (const xmlChar **) NULL)
   1183             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   1184             {
   1185               keyword=(const char *) attributes[i++];
   1186               attribute=InterpretImageProperties(msl_info->image_info[n],
   1187                 msl_info->attributes[n],(const char *) attributes[i],
   1188                 exception);
   1189               CloneString(&value,attribute);
   1190               attribute=DestroyString(attribute);
   1191               switch (*keyword)
   1192               {
   1193                 case 'C':
   1194                 case 'c':
   1195                 {
   1196                   if (LocaleCompare(keyword,"channel") == 0)
   1197                     {
   1198                       option=ParseChannelOption(value);
   1199                       if (option < 0)
   1200                         ThrowMSLException(OptionError,"UnrecognizedChannelType",
   1201                           value);
   1202                       channel=(ChannelType) option;
   1203                       break;
   1204                     }
   1205                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   1206                     keyword);
   1207                   break;
   1208                 }
   1209                 case 'G':
   1210                 case 'g':
   1211                 {
   1212                   if (LocaleCompare(keyword,"geometry") == 0)
   1213                     {
   1214                       flags=ParseGeometry(value,&geometry_info);
   1215                       if ((flags & SigmaValue) == 0)
   1216                         geometry_info.sigma=1.0;
   1217                       break;
   1218                     }
   1219                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   1220                     keyword);
   1221                   break;
   1222                 }
   1223                 case 'R':
   1224                 case 'r':
   1225                 {
   1226                   if (LocaleCompare(keyword,"radius") == 0)
   1227                     {
   1228                       geometry_info.rho=StringToDouble(value,(char **) NULL);
   1229                       break;
   1230                     }
   1231                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   1232                     keyword);
   1233                   break;
   1234                 }
   1235                 case 'S':
   1236                 case 's':
   1237                 {
   1238                   if (LocaleCompare(keyword,"sigma") == 0)
   1239                     {
   1240                       geometry_info.sigma=StringToLong(value);
   1241                       break;
   1242                     }
   1243                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   1244                     keyword);
   1245                   break;
   1246                 }
   1247                 default:
   1248                 {
   1249                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   1250                     keyword);
   1251                   break;
   1252                 }
   1253               }
   1254             }
   1255           channel_mask=SetImageChannelMask(msl_info->image[n],channel);
   1256           blur_image=BlurImage(msl_info->image[n],geometry_info.rho,
   1257             geometry_info.sigma,msl_info->exception);
   1258           (void) SetPixelChannelMask(msl_info->image[n],channel_mask);
   1259           if (blur_image == (Image *) NULL)
   1260             break;
   1261           msl_info->image[n]=DestroyImage(msl_info->image[n]);
   1262           msl_info->image[n]=blur_image;
   1263           break;
   1264         }
   1265       if (LocaleCompare((const char *) tag,"border") == 0)
   1266         {
   1267           Image
   1268             *border_image;
   1269 
   1270           /*
   1271             Border image.
   1272           */
   1273           if (msl_info->image[n] == (Image *) NULL)
   1274             {
   1275               ThrowMSLException(OptionError,"NoImagesDefined",
   1276                 (const char *) tag);
   1277               break;
   1278             }
   1279           SetGeometry(msl_info->image[n],&geometry);
   1280           if (attributes != (const xmlChar **) NULL)
   1281             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   1282             {
   1283               keyword=(const char *) attributes[i++];
   1284               attribute=InterpretImageProperties(msl_info->image_info[n],
   1285                 msl_info->attributes[n],(const char *) attributes[i],
   1286                 exception);
   1287               CloneString(&value,attribute);
   1288               attribute=DestroyString(attribute);
   1289               switch (*keyword)
   1290               {
   1291                 case 'C':
   1292                 case 'c':
   1293                 {
   1294                   if (LocaleCompare(keyword,"compose") == 0)
   1295                     {
   1296                       option=ParseCommandOption(MagickComposeOptions,
   1297                         MagickFalse,value);
   1298                       if (option < 0)
   1299                         ThrowMSLException(OptionError,"UnrecognizedComposeType",
   1300                           value);
   1301                       msl_info->image[n]->compose=(CompositeOperator) option;
   1302                       break;
   1303                     }
   1304                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   1305                     keyword);
   1306                   break;
   1307                 }
   1308                 case 'F':
   1309                 case 'f':
   1310                 {
   1311                   if (LocaleCompare(keyword, "fill") == 0)
   1312                     {
   1313                       (void) QueryColorCompliance(value,AllCompliance,
   1314                         &msl_info->image[n]->border_color,exception);
   1315                       break;
   1316                     }
   1317                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   1318                     keyword);
   1319                   break;
   1320                 }
   1321                 case 'G':
   1322                 case 'g':
   1323                 {
   1324                   if (LocaleCompare(keyword,"geometry") == 0)
   1325                     {
   1326                       flags=ParsePageGeometry(msl_info->image[n],value,
   1327                         &geometry,exception);
   1328                       if ((flags & HeightValue) == 0)
   1329                         geometry.height=geometry.width;
   1330                       break;
   1331                     }
   1332                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   1333                     keyword);
   1334                   break;
   1335                 }
   1336                 case 'H':
   1337                 case 'h':
   1338                 {
   1339                   if (LocaleCompare(keyword,"height") == 0)
   1340                     {
   1341                       geometry.height=StringToLong(value);
   1342                       break;
   1343                     }
   1344                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   1345                     keyword);
   1346                   break;
   1347                 }
   1348                 case 'W':
   1349                 case 'w':
   1350                 {
   1351                   if (LocaleCompare(keyword,"width") == 0)
   1352                     {
   1353                       geometry.width=StringToLong(value);
   1354                       break;
   1355                     }
   1356                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   1357                     keyword);
   1358                   break;
   1359                 }
   1360                 default:
   1361                 {
   1362                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   1363                     keyword);
   1364                   break;
   1365                 }
   1366               }
   1367             }
   1368           border_image=BorderImage(msl_info->image[n],&geometry,
   1369             msl_info->image[n]->compose,msl_info->exception);
   1370           if (border_image == (Image *) NULL)
   1371             break;
   1372           msl_info->image[n]=DestroyImage(msl_info->image[n]);
   1373           msl_info->image[n]=border_image;
   1374           break;
   1375         }
   1376       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
   1377     }
   1378     case 'C':
   1379     case 'c':
   1380     {
   1381       if (LocaleCompare((const char *) tag,"colorize") == 0)
   1382         {
   1383           char
   1384             blend[MagickPathExtent];
   1385 
   1386           Image
   1387             *colorize_image;
   1388 
   1389           PixelInfo
   1390             target;
   1391 
   1392           /*
   1393             Add noise image.
   1394           */
   1395           if (msl_info->image[n] == (Image *) NULL)
   1396             {
   1397               ThrowMSLException(OptionError,"NoImagesDefined",
   1398                 (const char *) tag);
   1399               break;
   1400             }
   1401           GetPixelInfo(msl_info->image[n],&target);
   1402           (void) CopyMagickString(blend,"100",MagickPathExtent);
   1403           if (attributes != (const xmlChar **) NULL)
   1404             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   1405             {
   1406               keyword=(const char *) attributes[i++];
   1407               attribute=InterpretImageProperties(msl_info->image_info[n],
   1408                 msl_info->attributes[n],(const char *) attributes[i],
   1409                 exception);
   1410               CloneString(&value,attribute);
   1411               attribute=DestroyString(attribute);
   1412               switch (*keyword)
   1413               {
   1414                 case 'B':
   1415                 case 'b':
   1416                 {
   1417                   if (LocaleCompare(keyword,"blend") == 0)
   1418                     {
   1419                       (void) CopyMagickString(blend,value,MagickPathExtent);
   1420                       break;
   1421                     }
   1422                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   1423                     keyword);
   1424                   break;
   1425                 }
   1426                 case 'F':
   1427                 case 'f':
   1428                 {
   1429                   if (LocaleCompare(keyword,"fill") == 0)
   1430                     {
   1431                       (void) QueryColorCompliance(value,AllCompliance,
   1432                         &target,msl_info->exception);
   1433                       break;
   1434                     }
   1435                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   1436                     keyword);
   1437                   break;
   1438                 }
   1439                 default:
   1440                 {
   1441                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   1442                     keyword);
   1443                   break;
   1444                 }
   1445               }
   1446             }
   1447           colorize_image=ColorizeImage(msl_info->image[n],blend,&target,
   1448             msl_info->exception);
   1449           if (colorize_image == (Image *) NULL)
   1450             break;
   1451           msl_info->image[n]=DestroyImage(msl_info->image[n]);
   1452           msl_info->image[n]=colorize_image;
   1453           break;
   1454         }
   1455       if (LocaleCompare((const char *) tag, "charcoal") == 0)
   1456       {
   1457         double
   1458             radius = 0.0,
   1459             sigma = 1.0;
   1460 
   1461         if (msl_info->image[n] == (Image *) NULL)
   1462         {
   1463           ThrowMSLException(OptionError,"NoImagesDefined",
   1464             (const char *) tag);
   1465           break;
   1466         }
   1467         /*
   1468           NOTE: charcoal can have no attributes, since we use all the defaults!
   1469         */
   1470         if (attributes != (const xmlChar **) NULL)
   1471         {
   1472           for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   1473           {
   1474             keyword=(const char *) attributes[i++];
   1475             attribute=InterpretImageProperties(msl_info->image_info[n],
   1476               msl_info->attributes[n],(const char *) attributes[i],exception);
   1477             CloneString(&value,attribute);
   1478             attribute=DestroyString(attribute);
   1479           switch (*keyword)
   1480           {
   1481             case 'R':
   1482             case 'r':
   1483             {
   1484               if (LocaleCompare(keyword,"radius") == 0)
   1485               {
   1486                 radius=StringToDouble(value,(char **) NULL);
   1487                 break;
   1488               }
   1489               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   1490               break;
   1491             }
   1492             case 'S':
   1493             case 's':
   1494             {
   1495               if (LocaleCompare(keyword,"sigma") == 0)
   1496               {
   1497                 sigma = StringToLong( value );
   1498                 break;
   1499               }
   1500               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   1501               break;
   1502             }
   1503             default:
   1504             {
   1505               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   1506               break;
   1507             }
   1508           }
   1509           }
   1510         }
   1511 
   1512         /*
   1513           charcoal image.
   1514         */
   1515         {
   1516         Image
   1517           *newImage;
   1518 
   1519         newImage=CharcoalImage(msl_info->image[n],radius,sigma,
   1520           msl_info->exception);
   1521         if (newImage == (Image *) NULL)
   1522           break;
   1523         msl_info->image[n]=DestroyImage(msl_info->image[n]);
   1524         msl_info->image[n]=newImage;
   1525         break;
   1526         }
   1527       }
   1528       if (LocaleCompare((const char *) tag,"chop") == 0)
   1529         {
   1530           Image
   1531             *chop_image;
   1532 
   1533           /*
   1534             Chop image.
   1535           */
   1536           if (msl_info->image[n] == (Image *) NULL)
   1537             {
   1538               ThrowMSLException(OptionError,"NoImagesDefined",
   1539                 (const char *) tag);
   1540               break;
   1541             }
   1542           SetGeometry(msl_info->image[n],&geometry);
   1543           if (attributes != (const xmlChar **) NULL)
   1544             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   1545             {
   1546               keyword=(const char *) attributes[i++];
   1547               attribute=InterpretImageProperties(msl_info->image_info[n],
   1548                 msl_info->attributes[n],(const char *) attributes[i],
   1549                 exception);
   1550               CloneString(&value,attribute);
   1551               attribute=DestroyString(attribute);
   1552               switch (*keyword)
   1553               {
   1554                 case 'G':
   1555                 case 'g':
   1556                 {
   1557                   if (LocaleCompare(keyword,"geometry") == 0)
   1558                     {
   1559                       flags=ParsePageGeometry(msl_info->image[n],value,
   1560                         &geometry,exception);
   1561                       if ((flags & HeightValue) == 0)
   1562                         geometry.height=geometry.width;
   1563                       break;
   1564                     }
   1565                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   1566                     keyword);
   1567                   break;
   1568                 }
   1569                 case 'H':
   1570                 case 'h':
   1571                 {
   1572                   if (LocaleCompare(keyword,"height") == 0)
   1573                     {
   1574                       geometry.height=StringToLong(value);
   1575                       break;
   1576                     }
   1577                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   1578                     keyword);
   1579                   break;
   1580                 }
   1581                 case 'W':
   1582                 case 'w':
   1583                 {
   1584                   if (LocaleCompare(keyword,"width") == 0)
   1585                     {
   1586                       geometry.width=StringToLong(value);
   1587                       break;
   1588                     }
   1589                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   1590                     keyword);
   1591                   break;
   1592                 }
   1593                 case 'X':
   1594                 case 'x':
   1595                 {
   1596                   if (LocaleCompare(keyword,"x") == 0)
   1597                     {
   1598                       geometry.x=StringToLong(value);
   1599                       break;
   1600                     }
   1601                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   1602                     keyword);
   1603                   break;
   1604                 }
   1605                 case 'Y':
   1606                 case 'y':
   1607                 {
   1608                   if (LocaleCompare(keyword,"y") == 0)
   1609                     {
   1610                       geometry.y=StringToLong(value);
   1611                       break;
   1612                     }
   1613                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   1614                     keyword);
   1615                   break;
   1616                 }
   1617                 default:
   1618                 {
   1619                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   1620                     keyword);
   1621                   break;
   1622                 }
   1623               }
   1624             }
   1625           chop_image=ChopImage(msl_info->image[n],&geometry,
   1626             msl_info->exception);
   1627           if (chop_image == (Image *) NULL)
   1628             break;
   1629           msl_info->image[n]=DestroyImage(msl_info->image[n]);
   1630           msl_info->image[n]=chop_image;
   1631           break;
   1632         }
   1633       if (LocaleCompare((const char *) tag,"color-floodfill") == 0)
   1634         {
   1635           PaintMethod
   1636             paint_method;
   1637 
   1638           PixelInfo
   1639             target;
   1640 
   1641           /*
   1642             Color floodfill image.
   1643           */
   1644           if (msl_info->image[n] == (Image *) NULL)
   1645             {
   1646               ThrowMSLException(OptionError,"NoImagesDefined",
   1647                 (const char *) tag);
   1648               break;
   1649             }
   1650           draw_info=CloneDrawInfo(msl_info->image_info[n],
   1651             msl_info->draw_info[n]);
   1652           SetGeometry(msl_info->image[n],&geometry);
   1653           paint_method=FloodfillMethod;
   1654           if (attributes != (const xmlChar **) NULL)
   1655             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   1656             {
   1657               keyword=(const char *) attributes[i++];
   1658               attribute=InterpretImageProperties(msl_info->image_info[n],
   1659                 msl_info->attributes[n],(const char *) attributes[i],
   1660                 exception);
   1661               CloneString(&value,attribute);
   1662               attribute=DestroyString(attribute);
   1663               switch (*keyword)
   1664               {
   1665                 case 'B':
   1666                 case 'b':
   1667                 {
   1668                   if (LocaleCompare(keyword,"bordercolor") == 0)
   1669                     {
   1670                       (void) QueryColorCompliance(value,AllCompliance,
   1671                         &target,exception);
   1672                       paint_method=FillToBorderMethod;
   1673                       break;
   1674                     }
   1675                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   1676                     keyword);
   1677                   break;
   1678                 }
   1679                 case 'F':
   1680                 case 'f':
   1681                 {
   1682                   if (LocaleCompare(keyword,"fill") == 0)
   1683                     {
   1684                       (void) QueryColorCompliance(value,AllCompliance,
   1685                         &draw_info->fill,exception);
   1686                       break;
   1687                     }
   1688                   if (LocaleCompare(keyword,"fuzz") == 0)
   1689                     {
   1690                       msl_info->image[n]->fuzz=StringToDouble(value,
   1691                         (char **) NULL);
   1692                       break;
   1693                     }
   1694                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   1695                     keyword);
   1696                   break;
   1697                 }
   1698                 case 'G':
   1699                 case 'g':
   1700                 {
   1701                   if (LocaleCompare(keyword,"geometry") == 0)
   1702                     {
   1703                       flags=ParsePageGeometry(msl_info->image[n],value,
   1704                         &geometry,exception);
   1705                       if ((flags & HeightValue) == 0)
   1706                         geometry.height=geometry.width;
   1707                       (void) GetOneVirtualPixelInfo(msl_info->image[n],
   1708                         TileVirtualPixelMethod,geometry.x,geometry.y,&target,
   1709                         exception);
   1710                       break;
   1711                     }
   1712                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   1713                     keyword);
   1714                   break;
   1715                 }
   1716                 case 'X':
   1717                 case 'x':
   1718                 {
   1719                   if (LocaleCompare(keyword,"x") == 0)
   1720                     {
   1721                       geometry.x=StringToLong(value);
   1722                       (void) GetOneVirtualPixelInfo(msl_info->image[n],
   1723                         TileVirtualPixelMethod,geometry.x,geometry.y,&target,
   1724                         exception);
   1725                       break;
   1726                     }
   1727                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   1728                     keyword);
   1729                   break;
   1730                 }
   1731                 case 'Y':
   1732                 case 'y':
   1733                 {
   1734                   if (LocaleCompare(keyword,"y") == 0)
   1735                     {
   1736                       geometry.y=StringToLong(value);
   1737                       (void) GetOneVirtualPixelInfo(msl_info->image[n],
   1738                         TileVirtualPixelMethod,geometry.x,geometry.y,&target,
   1739                         exception);
   1740                       break;
   1741                     }
   1742                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   1743                     keyword);
   1744                   break;
   1745                 }
   1746                 default:
   1747                 {
   1748                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   1749                     keyword);
   1750                   break;
   1751                 }
   1752               }
   1753             }
   1754           (void) FloodfillPaintImage(msl_info->image[n],draw_info,&target,
   1755             geometry.x,geometry.y,paint_method == FloodfillMethod ?
   1756             MagickFalse : MagickTrue,msl_info->exception);
   1757           draw_info=DestroyDrawInfo(draw_info);
   1758           break;
   1759         }
   1760       if (LocaleCompare((const char *) tag,"comment") == 0)
   1761         break;
   1762       if (LocaleCompare((const char *) tag,"composite") == 0)
   1763         {
   1764           char
   1765             composite_geometry[MagickPathExtent];
   1766 
   1767           CompositeOperator
   1768             compose;
   1769 
   1770           Image
   1771             *composite_image,
   1772             *rotate_image;
   1773 
   1774           /*
   1775             Composite image.
   1776           */
   1777           if (msl_info->image[n] == (Image *) NULL)
   1778             {
   1779               ThrowMSLException(OptionError,"NoImagesDefined",
   1780                 (const char *) tag);
   1781               break;
   1782             }
   1783           composite_image=NewImageList();
   1784           compose=OverCompositeOp;
   1785           if (attributes != (const xmlChar **) NULL)
   1786             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   1787             {
   1788               keyword=(const char *) attributes[i++];
   1789               attribute=InterpretImageProperties(msl_info->image_info[n],
   1790                 msl_info->attributes[n],(const char *) attributes[i],
   1791                 exception);
   1792               CloneString(&value,attribute);
   1793               attribute=DestroyString(attribute);
   1794               switch (*keyword)
   1795               {
   1796                 case 'C':
   1797                 case 'c':
   1798                 {
   1799                   if (LocaleCompare(keyword,"compose") == 0)
   1800                     {
   1801                       option=ParseCommandOption(MagickComposeOptions,
   1802                         MagickFalse,value);
   1803                       if (option < 0)
   1804                         ThrowMSLException(OptionError,"UnrecognizedComposeType",
   1805                           value);
   1806                       compose=(CompositeOperator) option;
   1807                       break;
   1808                     }
   1809                   break;
   1810                 }
   1811                 case 'I':
   1812                 case 'i':
   1813                 {
   1814                   if (LocaleCompare(keyword,"image") == 0)
   1815                     for (j=0; j < msl_info->n; j++)
   1816                     {
   1817                       const char
   1818                         *attribute;
   1819 
   1820                       attribute=GetImageProperty(msl_info->attributes[j],"id",
   1821                         exception);
   1822                       if ((attribute != (const char *) NULL)  &&
   1823                           (LocaleCompare(attribute,value) == 0))
   1824                         {
   1825                           composite_image=CloneImage(msl_info->image[j],0,0,
   1826                             MagickFalse,exception);
   1827                           break;
   1828                         }
   1829                     }
   1830                   break;
   1831                 }
   1832                 default:
   1833                   break;
   1834               }
   1835             }
   1836           if (composite_image == (Image *) NULL)
   1837             break;
   1838           rotate_image=NewImageList();
   1839           SetGeometry(msl_info->image[n],&geometry);
   1840           if (attributes != (const xmlChar **) NULL)
   1841             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   1842             {
   1843               keyword=(const char *) attributes[i++];
   1844               attribute=InterpretImageProperties(msl_info->image_info[n],
   1845                 msl_info->attributes[n],(const char *) attributes[i],
   1846                 exception);
   1847               CloneString(&value,attribute);
   1848               attribute=DestroyString(attribute);
   1849               switch (*keyword)
   1850               {
   1851                 case 'B':
   1852                 case 'b':
   1853                 {
   1854                   if (LocaleCompare(keyword,"blend") == 0)
   1855                     {
   1856                       (void) SetImageArtifact(composite_image,
   1857                                             "compose:args",value);
   1858                       break;
   1859                     }
   1860                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   1861                     keyword);
   1862                   break;
   1863                 }
   1864                 case 'C':
   1865                 case 'c':
   1866                 {
   1867                   if (LocaleCompare(keyword,"channel") == 0)
   1868                     {
   1869                       option=ParseChannelOption(value);
   1870                       if (option < 0)
   1871                         ThrowMSLException(OptionError,"UnrecognizedChannelType",
   1872                           value);
   1873                       channel=(ChannelType) option;
   1874                       break;
   1875                     }
   1876                   if (LocaleCompare(keyword, "color") == 0)
   1877                     {
   1878                       (void) QueryColorCompliance(value,AllCompliance,
   1879                         &composite_image->background_color,exception);
   1880                       break;
   1881                     }
   1882                   if (LocaleCompare(keyword,"compose") == 0)
   1883                     break;
   1884                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   1885                     keyword);
   1886                   break;
   1887                 }
   1888                 case 'G':
   1889                 case 'g':
   1890                 {
   1891                   if (LocaleCompare(keyword,"geometry") == 0)
   1892                     {
   1893                       flags=ParsePageGeometry(msl_info->image[n],value,
   1894                         &geometry,exception);
   1895                       if ((flags & HeightValue) == 0)
   1896                         geometry.height=geometry.width;
   1897                       break;
   1898                     }
   1899                   if (LocaleCompare(keyword,"gravity") == 0)
   1900                     {
   1901                       option=ParseCommandOption(MagickGravityOptions,
   1902                         MagickFalse,value);
   1903                       if (option < 0)
   1904                         ThrowMSLException(OptionError,"UnrecognizedGravityType",
   1905                           value);
   1906                       msl_info->image[n]->gravity=(GravityType) option;
   1907                       break;
   1908                     }
   1909                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   1910                     keyword);
   1911                   break;
   1912                 }
   1913                 case 'I':
   1914                 case 'i':
   1915                 {
   1916                   if (LocaleCompare(keyword,"image") == 0)
   1917                     break;
   1918                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   1919                     keyword);
   1920                   break;
   1921                 }
   1922                 case 'M':
   1923                 case 'm':
   1924                 {
   1925                   if (LocaleCompare(keyword,"mask") == 0)
   1926                     for (j=0; j < msl_info->n; j++)
   1927                     {
   1928                       const char
   1929                         *attribute;
   1930 
   1931                       attribute=GetImageProperty(msl_info->attributes[j],"id",
   1932                         exception);
   1933                       if ((attribute != (const char *) NULL)  &&
   1934                           (LocaleCompare(value,value) == 0))
   1935                         {
   1936                           SetImageType(composite_image,TrueColorAlphaType,
   1937                             exception);
   1938                           (void) CompositeImage(composite_image,
   1939                             msl_info->image[j],CopyAlphaCompositeOp,MagickTrue,
   1940                             0,0,exception);
   1941                           break;
   1942                         }
   1943                     }
   1944                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   1945                     keyword);
   1946                   break;
   1947                 }
   1948                 case 'O':
   1949                 case 'o':
   1950                 {
   1951                   if (LocaleCompare(keyword,"opacity") == 0)
   1952                     {
   1953                       ssize_t
   1954                         opacity,
   1955                         y;
   1956 
   1957                       register ssize_t
   1958                         x;
   1959 
   1960                       register Quantum
   1961                         *q;
   1962 
   1963                       CacheView
   1964                         *composite_view;
   1965 
   1966                       opacity=StringToLong(value);
   1967                       if (compose != DissolveCompositeOp)
   1968                         {
   1969                           (void) SetImageAlpha(composite_image,(Quantum)
   1970                             opacity,exception);
   1971                           break;
   1972                         }
   1973                       (void) SetImageArtifact(msl_info->image[n],
   1974                                             "compose:args",value);
   1975                       if (composite_image->alpha_trait == UndefinedPixelTrait)
   1976                         (void) SetImageAlpha(composite_image,OpaqueAlpha,
   1977                           exception);
   1978                       composite_view=AcquireAuthenticCacheView(composite_image,exception);
   1979                       for (y=0; y < (ssize_t) composite_image->rows ; y++)
   1980                       {
   1981                         q=GetCacheViewAuthenticPixels(composite_view,0,y,
   1982                           (ssize_t) composite_image->columns,1,exception);
   1983                         for (x=0; x < (ssize_t) composite_image->columns; x++)
   1984                         {
   1985                           if (GetPixelAlpha(composite_image,q) == OpaqueAlpha)
   1986                             SetPixelAlpha(composite_image,
   1987                               ClampToQuantum(opacity),q);
   1988                           q+=GetPixelChannels(composite_image);
   1989                         }
   1990                         if (SyncCacheViewAuthenticPixels(composite_view,exception) == MagickFalse)
   1991                           break;
   1992                       }
   1993                       composite_view=DestroyCacheView(composite_view);
   1994                       break;
   1995                     }
   1996                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   1997                     keyword);
   1998                   break;
   1999                 }
   2000                 case 'R':
   2001                 case 'r':
   2002                 {
   2003                   if (LocaleCompare(keyword,"rotate") == 0)
   2004                     {
   2005                       rotate_image=RotateImage(composite_image,
   2006                         StringToDouble(value,(char **) NULL),exception);
   2007                       break;
   2008                     }
   2009                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   2010                     keyword);
   2011                   break;
   2012                 }
   2013                 case 'T':
   2014                 case 't':
   2015                 {
   2016                   if (LocaleCompare(keyword,"tile") == 0)
   2017                     {
   2018                       MagickBooleanType
   2019                         tile;
   2020 
   2021                       option=ParseCommandOption(MagickBooleanOptions,
   2022                         MagickFalse,value);
   2023                       if (option < 0)
   2024                         ThrowMSLException(OptionError,"UnrecognizedBooleanType",
   2025                           value);
   2026                       tile=(MagickBooleanType) option;
   2027                       (void) tile;
   2028                       if (rotate_image != (Image *) NULL)
   2029                         (void) SetImageArtifact(rotate_image,
   2030                           "compose:outside-overlay","false");
   2031                       else
   2032                         (void) SetImageArtifact(composite_image,
   2033                           "compose:outside-overlay","false");
   2034                        image=msl_info->image[n];
   2035                        height=composite_image->rows;
   2036                        width=composite_image->columns;
   2037                        for (y=0; y < (ssize_t) image->rows; y+=(ssize_t) height)
   2038                          for (x=0; x < (ssize_t) image->columns; x+=(ssize_t) width)
   2039                          {
   2040                            if (rotate_image != (Image *) NULL)
   2041                              (void) CompositeImage(image,rotate_image,compose,
   2042                                MagickTrue,x,y,exception);
   2043                            else
   2044                              (void) CompositeImage(image,composite_image,
   2045                                compose,MagickTrue,x,y,exception);
   2046                          }
   2047                       if (rotate_image != (Image *) NULL)
   2048                         rotate_image=DestroyImage(rotate_image);
   2049                       break;
   2050                     }
   2051                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   2052                     keyword);
   2053                   break;
   2054                 }
   2055                 case 'X':
   2056                 case 'x':
   2057                 {
   2058                   if (LocaleCompare(keyword,"x") == 0)
   2059                     {
   2060                       geometry.x=StringToLong(value);
   2061                       break;
   2062                     }
   2063                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   2064                     keyword);
   2065                   break;
   2066                 }
   2067                 case 'Y':
   2068                 case 'y':
   2069                 {
   2070                   if (LocaleCompare(keyword,"y") == 0)
   2071                     {
   2072                       geometry.y=StringToLong(value);
   2073                       break;
   2074                     }
   2075                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   2076                     keyword);
   2077                   break;
   2078                 }
   2079                 default:
   2080                 {
   2081                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   2082                     keyword);
   2083                   break;
   2084                 }
   2085               }
   2086             }
   2087           image=msl_info->image[n];
   2088           (void) FormatLocaleString(composite_geometry,MagickPathExtent,
   2089             "%.20gx%.20g%+.20g%+.20g",(double) composite_image->columns,
   2090             (double) composite_image->rows,(double) geometry.x,(double)
   2091             geometry.y);
   2092           flags=ParseGravityGeometry(image,composite_geometry,&geometry,
   2093             exception);
   2094           channel_mask=SetImageChannelMask(image,channel);
   2095           if (rotate_image == (Image *) NULL)
   2096             CompositeImage(image,composite_image,compose,MagickTrue,geometry.x,
   2097               geometry.y,exception);
   2098           else
   2099             {
   2100               /*
   2101                 Rotate image.
   2102               */
   2103               geometry.x-=(ssize_t) (rotate_image->columns-
   2104                 composite_image->columns)/2;
   2105               geometry.y-=(ssize_t) (rotate_image->rows-
   2106                 composite_image->rows)/2;
   2107               CompositeImage(image,rotate_image,compose,MagickTrue,geometry.x,
   2108                 geometry.y,exception);
   2109               rotate_image=DestroyImage(rotate_image);
   2110             }
   2111           (void) SetImageChannelMask(image,channel_mask);
   2112           composite_image=DestroyImage(composite_image);
   2113           break;
   2114         }
   2115       if (LocaleCompare((const char *) tag,"contrast") == 0)
   2116         {
   2117           MagickBooleanType
   2118             sharpen;
   2119 
   2120           /*
   2121             Contrast image.
   2122           */
   2123           if (msl_info->image[n] == (Image *) NULL)
   2124             {
   2125               ThrowMSLException(OptionError,"NoImagesDefined",
   2126                 (const char *) tag);
   2127               break;
   2128             }
   2129           sharpen=MagickFalse;
   2130           if (attributes != (const xmlChar **) NULL)
   2131             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   2132             {
   2133               keyword=(const char *) attributes[i++];
   2134               attribute=InterpretImageProperties(msl_info->image_info[n],
   2135                 msl_info->attributes[n],(const char *) attributes[i],
   2136                 exception);
   2137               CloneString(&value,attribute);
   2138               attribute=DestroyString(attribute);
   2139               switch (*keyword)
   2140               {
   2141                 case 'S':
   2142                 case 's':
   2143                 {
   2144                   if (LocaleCompare(keyword,"sharpen") == 0)
   2145                     {
   2146                       option=ParseCommandOption(MagickBooleanOptions,
   2147                         MagickFalse,value);
   2148                       if (option < 0)
   2149                         ThrowMSLException(OptionError,"UnrecognizedBooleanType",
   2150                           value);
   2151                       sharpen=(MagickBooleanType) option;
   2152                       break;
   2153                     }
   2154                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   2155                     keyword);
   2156                   break;
   2157                 }
   2158                 default:
   2159                 {
   2160                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   2161                     keyword);
   2162                   break;
   2163                 }
   2164               }
   2165             }
   2166           (void) ContrastImage(msl_info->image[n],sharpen,
   2167             msl_info->exception);
   2168           break;
   2169         }
   2170       if (LocaleCompare((const char *) tag,"crop") == 0)
   2171         {
   2172           Image
   2173             *crop_image;
   2174 
   2175           /*
   2176             Crop image.
   2177           */
   2178           if (msl_info->image[n] == (Image *) NULL)
   2179             {
   2180               ThrowMSLException(OptionError,"NoImagesDefined",
   2181                 (const char *) tag);
   2182               break;
   2183             }
   2184           SetGeometry(msl_info->image[n],&geometry);
   2185           if (attributes != (const xmlChar **) NULL)
   2186             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   2187             {
   2188               keyword=(const char *) attributes[i++];
   2189               attribute=InterpretImageProperties(msl_info->image_info[n],
   2190                 msl_info->attributes[n],(const char *) attributes[i],
   2191                 exception);
   2192               CloneString(&value,attribute);
   2193               attribute=DestroyString(attribute);
   2194               switch (*keyword)
   2195               {
   2196                 case 'G':
   2197                 case 'g':
   2198                 {
   2199                   if (LocaleCompare(keyword,"geometry") == 0)
   2200                     {
   2201                       flags=ParseGravityGeometry(msl_info->image[n],value,
   2202                         &geometry,exception);
   2203                       break;
   2204                     }
   2205                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   2206                     keyword);
   2207                   break;
   2208                 }
   2209                 case 'H':
   2210                 case 'h':
   2211                 {
   2212                   if (LocaleCompare(keyword,"height") == 0)
   2213                     {
   2214                       geometry.height=StringToLong(value);
   2215                       break;
   2216                     }
   2217                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   2218                     keyword);
   2219                   break;
   2220                 }
   2221                 case 'W':
   2222                 case 'w':
   2223                 {
   2224                   if (LocaleCompare(keyword,"width") == 0)
   2225                     {
   2226                       geometry.width=StringToLong(value);
   2227                       break;
   2228                     }
   2229                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   2230                     keyword);
   2231                   break;
   2232                 }
   2233                 case 'X':
   2234                 case 'x':
   2235                 {
   2236                   if (LocaleCompare(keyword,"x") == 0)
   2237                     {
   2238                       geometry.x=StringToLong(value);
   2239                       break;
   2240                     }
   2241                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   2242                     keyword);
   2243                   break;
   2244                 }
   2245                 case 'Y':
   2246                 case 'y':
   2247                 {
   2248                   if (LocaleCompare(keyword,"y") == 0)
   2249                     {
   2250                       geometry.y=StringToLong(value);
   2251                       break;
   2252                     }
   2253                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   2254                     keyword);
   2255                   break;
   2256                 }
   2257                 default:
   2258                 {
   2259                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   2260                     keyword);
   2261                   break;
   2262                 }
   2263               }
   2264             }
   2265           crop_image=CropImage(msl_info->image[n],&geometry,
   2266             msl_info->exception);
   2267           if (crop_image == (Image *) NULL)
   2268             break;
   2269           msl_info->image[n]=DestroyImage(msl_info->image[n]);
   2270           msl_info->image[n]=crop_image;
   2271           break;
   2272         }
   2273       if (LocaleCompare((const char *) tag,"cycle-colormap") == 0)
   2274         {
   2275           ssize_t
   2276             display;
   2277 
   2278           /*
   2279             Cycle-colormap image.
   2280           */
   2281           if (msl_info->image[n] == (Image *) NULL)
   2282             {
   2283               ThrowMSLException(OptionError,"NoImagesDefined",
   2284                 (const char *) tag);
   2285               break;
   2286             }
   2287           display=0;
   2288           if (attributes != (const xmlChar **) NULL)
   2289             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   2290             {
   2291               keyword=(const char *) attributes[i++];
   2292               attribute=InterpretImageProperties(msl_info->image_info[n],
   2293                 msl_info->attributes[n],(const char *) attributes[i],
   2294                 exception);
   2295               CloneString(&value,attribute);
   2296               attribute=DestroyString(attribute);
   2297               switch (*keyword)
   2298               {
   2299                 case 'D':
   2300                 case 'd':
   2301                 {
   2302                   if (LocaleCompare(keyword,"display") == 0)
   2303                     {
   2304                       display=StringToLong(value);
   2305                       break;
   2306                     }
   2307                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   2308                     keyword);
   2309                   break;
   2310                 }
   2311                 default:
   2312                 {
   2313                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   2314                     keyword);
   2315                   break;
   2316                 }
   2317               }
   2318             }
   2319           (void) CycleColormapImage(msl_info->image[n],display,exception);
   2320           break;
   2321         }
   2322       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
   2323     }
   2324     case 'D':
   2325     case 'd':
   2326     {
   2327       if (LocaleCompare((const char *) tag,"despeckle") == 0)
   2328         {
   2329           Image
   2330             *despeckle_image;
   2331 
   2332           /*
   2333             Despeckle image.
   2334           */
   2335           if (msl_info->image[n] == (Image *) NULL)
   2336             {
   2337               ThrowMSLException(OptionError,"NoImagesDefined",
   2338                 (const char *) tag);
   2339               break;
   2340             }
   2341           if (attributes != (const xmlChar **) NULL)
   2342             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   2343             {
   2344               keyword=(const char *) attributes[i++];
   2345               attribute=InterpretImageProperties(msl_info->image_info[n],
   2346                 msl_info->attributes[n],(const char *) attributes[i],
   2347                 exception);
   2348               CloneString(&value,attribute);
   2349               attribute=DestroyString(attribute);
   2350               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   2351             }
   2352           despeckle_image=DespeckleImage(msl_info->image[n],
   2353             msl_info->exception);
   2354           if (despeckle_image == (Image *) NULL)
   2355             break;
   2356           msl_info->image[n]=DestroyImage(msl_info->image[n]);
   2357           msl_info->image[n]=despeckle_image;
   2358           break;
   2359         }
   2360       if (LocaleCompare((const char *) tag,"display") == 0)
   2361         {
   2362           if (msl_info->image[n] == (Image *) NULL)
   2363             {
   2364               ThrowMSLException(OptionError,"NoImagesDefined",
   2365                 (const char *) tag);
   2366               break;
   2367             }
   2368           if (attributes != (const xmlChar **) NULL)
   2369             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   2370             {
   2371               keyword=(const char *) attributes[i++];
   2372               attribute=InterpretImageProperties(msl_info->image_info[n],
   2373                 msl_info->attributes[n],(const char *) attributes[i],
   2374                 exception);
   2375               CloneString(&value,attribute);
   2376               attribute=DestroyString(attribute);
   2377               switch (*keyword)
   2378               {
   2379                 default:
   2380                 {
   2381                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   2382                     keyword);
   2383                   break;
   2384                 }
   2385               }
   2386             }
   2387           (void) DisplayImages(msl_info->image_info[n],msl_info->image[n],
   2388             msl_info->exception);
   2389           break;
   2390         }
   2391       if (LocaleCompare((const char *) tag,"draw") == 0)
   2392         {
   2393           char
   2394             text[MagickPathExtent];
   2395 
   2396           /*
   2397             Annotate image.
   2398           */
   2399           if (msl_info->image[n] == (Image *) NULL)
   2400             {
   2401               ThrowMSLException(OptionError,"NoImagesDefined",
   2402                 (const char *) tag);
   2403               break;
   2404             }
   2405           draw_info=CloneDrawInfo(msl_info->image_info[n],
   2406             msl_info->draw_info[n]);
   2407           angle=0.0;
   2408           current=draw_info->affine;
   2409           GetAffineMatrix(&affine);
   2410           if (attributes != (const xmlChar **) NULL)
   2411             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   2412             {
   2413               keyword=(const char *) attributes[i++];
   2414               attribute=InterpretImageProperties(msl_info->image_info[n],
   2415                 msl_info->attributes[n],(const char *) attributes[i],
   2416                 exception);
   2417               CloneString(&value,attribute);
   2418               attribute=DestroyString(attribute);
   2419               switch (*keyword)
   2420               {
   2421                 case 'A':
   2422                 case 'a':
   2423                 {
   2424                   if (LocaleCompare(keyword,"affine") == 0)
   2425                     {
   2426                       char
   2427                         *p;
   2428 
   2429                       p=value;
   2430                       draw_info->affine.sx=StringToDouble(p,&p);
   2431                       if (*p ==',')
   2432                         p++;
   2433                       draw_info->affine.rx=StringToDouble(p,&p);
   2434                       if (*p ==',')
   2435                         p++;
   2436                       draw_info->affine.ry=StringToDouble(p,&p);
   2437                       if (*p ==',')
   2438                         p++;
   2439                       draw_info->affine.sy=StringToDouble(p,&p);
   2440                       if (*p ==',')
   2441                         p++;
   2442                       draw_info->affine.tx=StringToDouble(p,&p);
   2443                       if (*p ==',')
   2444                         p++;
   2445                       draw_info->affine.ty=StringToDouble(p,&p);
   2446                       break;
   2447                     }
   2448                   if (LocaleCompare(keyword,"align") == 0)
   2449                     {
   2450                       option=ParseCommandOption(MagickAlignOptions,MagickFalse,
   2451                         value);
   2452                       if (option < 0)
   2453                         ThrowMSLException(OptionError,"UnrecognizedAlignType",
   2454                           value);
   2455                       draw_info->align=(AlignType) option;
   2456                       break;
   2457                     }
   2458                   if (LocaleCompare(keyword,"antialias") == 0)
   2459                     {
   2460                       option=ParseCommandOption(MagickBooleanOptions,
   2461                         MagickFalse,value);
   2462                       if (option < 0)
   2463                         ThrowMSLException(OptionError,"UnrecognizedBooleanType",
   2464                           value);
   2465                       draw_info->stroke_antialias=(MagickBooleanType) option;
   2466                       draw_info->text_antialias=(MagickBooleanType) option;
   2467                       break;
   2468                     }
   2469                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   2470                     keyword);
   2471                   break;
   2472                 }
   2473                 case 'D':
   2474                 case 'd':
   2475                 {
   2476                   if (LocaleCompare(keyword,"density") == 0)
   2477                     {
   2478                       CloneString(&draw_info->density,value);
   2479                       break;
   2480                     }
   2481                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   2482                     keyword);
   2483                   break;
   2484                 }
   2485                 case 'E':
   2486                 case 'e':
   2487                 {
   2488                   if (LocaleCompare(keyword,"encoding") == 0)
   2489                     {
   2490                       CloneString(&draw_info->encoding,value);
   2491                       break;
   2492                     }
   2493                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   2494                     keyword);
   2495                   break;
   2496                 }
   2497                 case 'F':
   2498                 case 'f':
   2499                 {
   2500                   if (LocaleCompare(keyword, "fill") == 0)
   2501                     {
   2502                       (void) QueryColorCompliance(value,AllCompliance,
   2503                         &draw_info->fill,exception);
   2504                       break;
   2505                     }
   2506                   if (LocaleCompare(keyword,"family") == 0)
   2507                     {
   2508                       CloneString(&draw_info->family,value);
   2509                       break;
   2510                     }
   2511                   if (LocaleCompare(keyword,"font") == 0)
   2512                     {
   2513                       CloneString(&draw_info->font,value);
   2514                       break;
   2515                     }
   2516                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   2517                     keyword);
   2518                   break;
   2519                 }
   2520                 case 'G':
   2521                 case 'g':
   2522                 {
   2523                   if (LocaleCompare(keyword,"geometry") == 0)
   2524                     {
   2525                       flags=ParsePageGeometry(msl_info->image[n],value,
   2526                         &geometry,exception);
   2527                       if ((flags & HeightValue) == 0)
   2528                         geometry.height=geometry.width;
   2529                       break;
   2530                     }
   2531                   if (LocaleCompare(keyword,"gravity") == 0)
   2532                     {
   2533                       option=ParseCommandOption(MagickGravityOptions,
   2534                         MagickFalse,value);
   2535                       if (option < 0)
   2536                         ThrowMSLException(OptionError,"UnrecognizedGravityType",
   2537                           value);
   2538                       draw_info->gravity=(GravityType) option;
   2539                       break;
   2540                     }
   2541                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   2542                     keyword);
   2543                   break;
   2544                 }
   2545                 case 'P':
   2546                 case 'p':
   2547                 {
   2548                   if (LocaleCompare(keyword,"points") == 0)
   2549                     {
   2550                       if (LocaleCompare(draw_info->primitive,"path") == 0)
   2551                         {
   2552                           (void) ConcatenateString(&draw_info->primitive," '");
   2553                           ConcatenateString(&draw_info->primitive,value);
   2554                           (void) ConcatenateString(&draw_info->primitive,"'");
   2555                         }
   2556                       else
   2557                         {
   2558                           (void) ConcatenateString(&draw_info->primitive," ");
   2559                           ConcatenateString(&draw_info->primitive,value);
   2560                         }
   2561                       break;
   2562                     }
   2563                   if (LocaleCompare(keyword,"pointsize") == 0)
   2564                     {
   2565                       draw_info->pointsize=StringToDouble(value,
   2566                         (char **) NULL);
   2567                       break;
   2568                     }
   2569                   if (LocaleCompare(keyword,"primitive") == 0)
   2570                     {
   2571                       CloneString(&draw_info->primitive,value);
   2572                       break;
   2573                     }
   2574                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   2575                     keyword);
   2576                   break;
   2577                 }
   2578                 case 'R':
   2579                 case 'r':
   2580                 {
   2581                   if (LocaleCompare(keyword,"rotate") == 0)
   2582                     {
   2583                       angle=StringToDouble(value,(char **) NULL);
   2584                       affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
   2585                       affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
   2586                       affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
   2587                       affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
   2588                       break;
   2589                     }
   2590                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   2591                     keyword);
   2592                   break;
   2593                 }
   2594                 case 'S':
   2595                 case 's':
   2596                 {
   2597                   if (LocaleCompare(keyword,"scale") == 0)
   2598                     {
   2599                       flags=ParseGeometry(value,&geometry_info);
   2600                       if ((flags & SigmaValue) == 0)
   2601                         geometry_info.sigma=1.0;
   2602                       affine.sx=geometry_info.rho;
   2603                       affine.sy=geometry_info.sigma;
   2604                       break;
   2605                     }
   2606                   if (LocaleCompare(keyword,"skewX") == 0)
   2607                     {
   2608                       angle=StringToDouble(value,(char **) NULL);
   2609                       affine.ry=cos(DegreesToRadians(fmod(angle,360.0)));
   2610                       break;
   2611                     }
   2612                   if (LocaleCompare(keyword,"skewY") == 0)
   2613                     {
   2614                       angle=StringToDouble(value,(char **) NULL);
   2615                       affine.rx=cos(DegreesToRadians(fmod(angle,360.0)));
   2616                       break;
   2617                     }
   2618                   if (LocaleCompare(keyword,"stretch") == 0)
   2619                     {
   2620                       option=ParseCommandOption(MagickStretchOptions,
   2621                         MagickFalse,value);
   2622                       if (option < 0)
   2623                         ThrowMSLException(OptionError,"UnrecognizedStretchType",
   2624                           value);
   2625                       draw_info->stretch=(StretchType) option;
   2626                       break;
   2627                     }
   2628                   if (LocaleCompare(keyword, "stroke") == 0)
   2629                     {
   2630                       (void) QueryColorCompliance(value,AllCompliance,
   2631                         &draw_info->stroke,exception);
   2632                       break;
   2633                     }
   2634                   if (LocaleCompare(keyword,"strokewidth") == 0)
   2635                     {
   2636                       draw_info->stroke_width=StringToLong(value);
   2637                       break;
   2638                     }
   2639                   if (LocaleCompare(keyword,"style") == 0)
   2640                     {
   2641                       option=ParseCommandOption(MagickStyleOptions,MagickFalse,
   2642                         value);
   2643                       if (option < 0)
   2644                         ThrowMSLException(OptionError,"UnrecognizedStyleType",
   2645                           value);
   2646                       draw_info->style=(StyleType) option;
   2647                       break;
   2648                     }
   2649                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   2650                     keyword);
   2651                   break;
   2652                 }
   2653                 case 'T':
   2654                 case 't':
   2655                 {
   2656                   if (LocaleCompare(keyword,"text") == 0)
   2657                     {
   2658                       (void) ConcatenateString(&draw_info->primitive," '");
   2659                       (void) ConcatenateString(&draw_info->primitive,value);
   2660                       (void) ConcatenateString(&draw_info->primitive,"'");
   2661                       break;
   2662                     }
   2663                   if (LocaleCompare(keyword,"translate") == 0)
   2664                     {
   2665                       flags=ParseGeometry(value,&geometry_info);
   2666                       if ((flags & SigmaValue) == 0)
   2667                         geometry_info.sigma=1.0;
   2668                       affine.tx=geometry_info.rho;
   2669                       affine.ty=geometry_info.sigma;
   2670                       break;
   2671                     }
   2672                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   2673                     keyword);
   2674                   break;
   2675                 }
   2676                 case 'U':
   2677                 case 'u':
   2678                 {
   2679                   if (LocaleCompare(keyword, "undercolor") == 0)
   2680                     {
   2681                       (void) QueryColorCompliance(value,AllCompliance,
   2682                         &draw_info->undercolor,exception);
   2683                       break;
   2684                     }
   2685                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   2686                     keyword);
   2687                   break;
   2688                 }
   2689                 case 'W':
   2690                 case 'w':
   2691                 {
   2692                   if (LocaleCompare(keyword,"weight") == 0)
   2693                     {
   2694                       draw_info->weight=StringToLong(value);
   2695                       break;
   2696                     }
   2697                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   2698                     keyword);
   2699                   break;
   2700                 }
   2701                 case 'X':
   2702                 case 'x':
   2703                 {
   2704                   if (LocaleCompare(keyword,"x") == 0)
   2705                     {
   2706                       geometry.x=StringToLong(value);
   2707                       break;
   2708                     }
   2709                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   2710                     keyword);
   2711                   break;
   2712                 }
   2713                 case 'Y':
   2714                 case 'y':
   2715                 {
   2716                   if (LocaleCompare(keyword,"y") == 0)
   2717                     {
   2718                       geometry.y=StringToLong(value);
   2719                       break;
   2720                     }
   2721                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   2722                     keyword);
   2723                   break;
   2724                 }
   2725                 default:
   2726                 {
   2727                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   2728                     keyword);
   2729                   break;
   2730                 }
   2731               }
   2732             }
   2733           (void) FormatLocaleString(text,MagickPathExtent,
   2734             "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,(double)
   2735             geometry.height,(double) geometry.x,(double) geometry.y);
   2736           CloneString(&draw_info->geometry,text);
   2737           draw_info->affine.sx=affine.sx*current.sx+affine.ry*current.rx;
   2738           draw_info->affine.rx=affine.rx*current.sx+affine.sy*current.rx;
   2739           draw_info->affine.ry=affine.sx*current.ry+affine.ry*current.sy;
   2740           draw_info->affine.sy=affine.rx*current.ry+affine.sy*current.sy;
   2741           draw_info->affine.tx=affine.sx*current.tx+affine.ry*current.ty+
   2742             affine.tx;
   2743           draw_info->affine.ty=affine.rx*current.tx+affine.sy*current.ty+
   2744             affine.ty;
   2745           (void) DrawImage(msl_info->image[n],draw_info,exception);
   2746           draw_info=DestroyDrawInfo(draw_info);
   2747           break;
   2748         }
   2749       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
   2750     }
   2751     case 'E':
   2752     case 'e':
   2753     {
   2754       if (LocaleCompare((const char *) tag,"edge") == 0)
   2755         {
   2756           Image
   2757             *edge_image;
   2758 
   2759           /*
   2760             Edge image.
   2761           */
   2762           if (msl_info->image[n] == (Image *) NULL)
   2763             {
   2764               ThrowMSLException(OptionError,"NoImagesDefined",
   2765                 (const char *) tag);
   2766               break;
   2767             }
   2768           if (attributes != (const xmlChar **) NULL)
   2769             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   2770             {
   2771               keyword=(const char *) attributes[i++];
   2772               attribute=InterpretImageProperties(msl_info->image_info[n],
   2773                 msl_info->attributes[n],(const char *) attributes[i],
   2774                 exception);
   2775               CloneString(&value,attribute);
   2776               attribute=DestroyString(attribute);
   2777               switch (*keyword)
   2778               {
   2779                 case 'G':
   2780                 case 'g':
   2781                 {
   2782                   if (LocaleCompare(keyword,"geometry") == 0)
   2783                     {
   2784                       flags=ParseGeometry(value,&geometry_info);
   2785                       if ((flags & SigmaValue) == 0)
   2786                         geometry_info.sigma=1.0;
   2787                       break;
   2788                     }
   2789                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   2790                     keyword);
   2791                   break;
   2792                 }
   2793                 case 'R':
   2794                 case 'r':
   2795                 {
   2796                   if (LocaleCompare(keyword,"radius") == 0)
   2797                     {
   2798                       geometry_info.rho=StringToDouble(value,(char **) NULL);
   2799                       break;
   2800                     }
   2801                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   2802                     keyword);
   2803                   break;
   2804                 }
   2805                 default:
   2806                 {
   2807                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   2808                     keyword);
   2809                   break;
   2810                 }
   2811               }
   2812             }
   2813           edge_image=EdgeImage(msl_info->image[n],geometry_info.rho,
   2814             msl_info->exception);
   2815           if (edge_image == (Image *) NULL)
   2816             break;
   2817           msl_info->image[n]=DestroyImage(msl_info->image[n]);
   2818           msl_info->image[n]=edge_image;
   2819           break;
   2820         }
   2821       if (LocaleCompare((const char *) tag,"emboss") == 0)
   2822         {
   2823           Image
   2824             *emboss_image;
   2825 
   2826           /*
   2827             Emboss image.
   2828           */
   2829           if (msl_info->image[n] == (Image *) NULL)
   2830             {
   2831               ThrowMSLException(OptionError,"NoImagesDefined",
   2832                 (const char *) tag);
   2833               break;
   2834             }
   2835           if (attributes != (const xmlChar **) NULL)
   2836             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   2837             {
   2838               keyword=(const char *) attributes[i++];
   2839               attribute=InterpretImageProperties(msl_info->image_info[n],
   2840                 msl_info->attributes[n],(const char *) attributes[i],
   2841                 exception);
   2842               CloneString(&value,attribute);
   2843               attribute=DestroyString(attribute);
   2844               switch (*keyword)
   2845               {
   2846                 case 'G':
   2847                 case 'g':
   2848                 {
   2849                   if (LocaleCompare(keyword,"geometry") == 0)
   2850                     {
   2851                       flags=ParseGeometry(value,&geometry_info);
   2852                       if ((flags & SigmaValue) == 0)
   2853                         geometry_info.sigma=1.0;
   2854                       break;
   2855                     }
   2856                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   2857                     keyword);
   2858                   break;
   2859                 }
   2860                 case 'R':
   2861                 case 'r':
   2862                 {
   2863                   if (LocaleCompare(keyword,"radius") == 0)
   2864                     {
   2865                       geometry_info.rho=StringToDouble(value,
   2866                         (char **) NULL);
   2867                       break;
   2868                     }
   2869                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   2870                     keyword);
   2871                   break;
   2872                 }
   2873                 case 'S':
   2874                 case 's':
   2875                 {
   2876                   if (LocaleCompare(keyword,"sigma") == 0)
   2877                     {
   2878                       geometry_info.sigma=StringToLong(value);
   2879                       break;
   2880                     }
   2881                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   2882                     keyword);
   2883                   break;
   2884                 }
   2885                 default:
   2886                 {
   2887                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   2888                     keyword);
   2889                   break;
   2890                 }
   2891               }
   2892             }
   2893           emboss_image=EmbossImage(msl_info->image[n],geometry_info.rho,
   2894             geometry_info.sigma,msl_info->exception);
   2895           if (emboss_image == (Image *) NULL)
   2896             break;
   2897           msl_info->image[n]=DestroyImage(msl_info->image[n]);
   2898           msl_info->image[n]=emboss_image;
   2899           break;
   2900         }
   2901       if (LocaleCompare((const char *) tag,"enhance") == 0)
   2902         {
   2903           Image
   2904             *enhance_image;
   2905 
   2906           /*
   2907             Enhance image.
   2908           */
   2909           if (msl_info->image[n] == (Image *) NULL)
   2910             {
   2911               ThrowMSLException(OptionError,"NoImagesDefined",
   2912                 (const char *) tag);
   2913               break;
   2914             }
   2915           if (attributes != (const xmlChar **) NULL)
   2916             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   2917             {
   2918               keyword=(const char *) attributes[i++];
   2919               attribute=InterpretImageProperties(msl_info->image_info[n],
   2920                 msl_info->attributes[n],(const char *) attributes[i],
   2921                 exception);
   2922               CloneString(&value,attribute);
   2923               attribute=DestroyString(attribute);
   2924               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   2925             }
   2926           enhance_image=EnhanceImage(msl_info->image[n],
   2927             msl_info->exception);
   2928           if (enhance_image == (Image *) NULL)
   2929             break;
   2930           msl_info->image[n]=DestroyImage(msl_info->image[n]);
   2931           msl_info->image[n]=enhance_image;
   2932           break;
   2933         }
   2934       if (LocaleCompare((const char *) tag,"equalize") == 0)
   2935         {
   2936           /*
   2937             Equalize image.
   2938           */
   2939           if (msl_info->image[n] == (Image *) NULL)
   2940             {
   2941               ThrowMSLException(OptionError,"NoImagesDefined",
   2942                 (const char *) tag);
   2943               break;
   2944             }
   2945           if (attributes != (const xmlChar **) NULL)
   2946             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   2947             {
   2948               keyword=(const char *) attributes[i++];
   2949               attribute=InterpretImageProperties(msl_info->image_info[n],
   2950                 msl_info->attributes[n],(const char *) attributes[i],
   2951                 exception);
   2952               CloneString(&value,attribute);
   2953               attribute=DestroyString(attribute);
   2954               switch (*keyword)
   2955               {
   2956                 default:
   2957                 {
   2958                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   2959                     keyword);
   2960                   break;
   2961                 }
   2962               }
   2963             }
   2964           (void) EqualizeImage(msl_info->image[n],
   2965             msl_info->exception);
   2966           break;
   2967         }
   2968       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
   2969     }
   2970     case 'F':
   2971     case 'f':
   2972     {
   2973       if (LocaleCompare((const char *) tag, "flatten") == 0)
   2974       {
   2975         if (msl_info->image[n] == (Image *) NULL)
   2976         {
   2977           ThrowMSLException(OptionError,"NoImagesDefined",
   2978             (const char *) tag);
   2979           break;
   2980         }
   2981 
   2982         /* no attributes here */
   2983 
   2984         /* process the image */
   2985         {
   2986           Image
   2987             *newImage;
   2988 
   2989           newImage=MergeImageLayers(msl_info->image[n],FlattenLayer,
   2990             msl_info->exception);
   2991           if (newImage == (Image *) NULL)
   2992             break;
   2993           msl_info->image[n]=DestroyImage(msl_info->image[n]);
   2994           msl_info->image[n]=newImage;
   2995           break;
   2996         }
   2997       }
   2998       if (LocaleCompare((const char *) tag,"flip") == 0)
   2999         {
   3000           Image
   3001             *flip_image;
   3002 
   3003           /*
   3004             Flip image.
   3005           */
   3006           if (msl_info->image[n] == (Image *) NULL)
   3007             {
   3008               ThrowMSLException(OptionError,"NoImagesDefined",
   3009                 (const char *) tag);
   3010               break;
   3011             }
   3012           if (attributes != (const xmlChar **) NULL)
   3013             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   3014             {
   3015               keyword=(const char *) attributes[i++];
   3016               attribute=InterpretImageProperties(msl_info->image_info[n],
   3017                 msl_info->attributes[n],(const char *) attributes[i],
   3018                 exception);
   3019               CloneString(&value,attribute);
   3020               attribute=DestroyString(attribute);
   3021               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   3022             }
   3023           flip_image=FlipImage(msl_info->image[n],
   3024             msl_info->exception);
   3025           if (flip_image == (Image *) NULL)
   3026             break;
   3027           msl_info->image[n]=DestroyImage(msl_info->image[n]);
   3028           msl_info->image[n]=flip_image;
   3029           break;
   3030         }
   3031       if (LocaleCompare((const char *) tag,"flop") == 0)
   3032         {
   3033           Image
   3034             *flop_image;
   3035 
   3036           /*
   3037             Flop image.
   3038           */
   3039           if (msl_info->image[n] == (Image *) NULL)
   3040             {
   3041               ThrowMSLException(OptionError,"NoImagesDefined",
   3042                 (const char *) tag);
   3043               break;
   3044             }
   3045           if (attributes != (const xmlChar **) NULL)
   3046             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   3047             {
   3048               keyword=(const char *) attributes[i++];
   3049               attribute=InterpretImageProperties(msl_info->image_info[n],
   3050                 msl_info->attributes[n],(const char *) attributes[i],
   3051                 exception);
   3052               CloneString(&value,attribute);
   3053               attribute=DestroyString(attribute);
   3054               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   3055             }
   3056           flop_image=FlopImage(msl_info->image[n],
   3057             msl_info->exception);
   3058           if (flop_image == (Image *) NULL)
   3059             break;
   3060           msl_info->image[n]=DestroyImage(msl_info->image[n]);
   3061           msl_info->image[n]=flop_image;
   3062           break;
   3063         }
   3064       if (LocaleCompare((const char *) tag,"frame") == 0)
   3065         {
   3066           FrameInfo
   3067             frame_info;
   3068 
   3069           Image
   3070             *frame_image;
   3071 
   3072           /*
   3073             Frame image.
   3074           */
   3075           if (msl_info->image[n] == (Image *) NULL)
   3076             {
   3077               ThrowMSLException(OptionError,"NoImagesDefined",
   3078                 (const char *) tag);
   3079               break;
   3080             }
   3081           (void) memset(&frame_info,0,sizeof(frame_info));
   3082           SetGeometry(msl_info->image[n],&geometry);
   3083           if (attributes != (const xmlChar **) NULL)
   3084             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   3085             {
   3086               keyword=(const char *) attributes[i++];
   3087               attribute=InterpretImageProperties(msl_info->image_info[n],
   3088                 msl_info->attributes[n],(const char *) attributes[i],
   3089                 exception);
   3090               CloneString(&value,attribute);
   3091               attribute=DestroyString(attribute);
   3092               switch (*keyword)
   3093               {
   3094                 case 'C':
   3095                 case 'c':
   3096                 {
   3097                   if (LocaleCompare(keyword,"compose") == 0)
   3098                     {
   3099                       option=ParseCommandOption(MagickComposeOptions,
   3100                         MagickFalse,value);
   3101                       if (option < 0)
   3102                         ThrowMSLException(OptionError,"UnrecognizedComposeType",
   3103                           value);
   3104                       msl_info->image[n]->compose=(CompositeOperator) option;
   3105                       break;
   3106                     }
   3107                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   3108                     keyword);
   3109                   break;
   3110                 }
   3111                 case 'F':
   3112                 case 'f':
   3113                 {
   3114                   if (LocaleCompare(keyword, "fill") == 0)
   3115                     {
   3116                       (void) QueryColorCompliance(value,AllCompliance,
   3117                         &msl_info->image[n]->matte_color,exception);
   3118                       break;
   3119                     }
   3120                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   3121                     keyword);
   3122                   break;
   3123                 }
   3124                 case 'G':
   3125                 case 'g':
   3126                 {
   3127                   if (LocaleCompare(keyword,"geometry") == 0)
   3128                     {
   3129                       flags=ParsePageGeometry(msl_info->image[n],value,
   3130                         &geometry,exception);
   3131                       if ((flags & HeightValue) == 0)
   3132                         geometry.height=geometry.width;
   3133                       frame_info.width=geometry.width;
   3134                       frame_info.height=geometry.height;
   3135                       frame_info.outer_bevel=geometry.x;
   3136                       frame_info.inner_bevel=geometry.y;
   3137                       break;
   3138                     }
   3139                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   3140                     keyword);
   3141                   break;
   3142                 }
   3143                 case 'H':
   3144                 case 'h':
   3145                 {
   3146                   if (LocaleCompare(keyword,"height") == 0)
   3147                     {
   3148                       frame_info.height=StringToLong(value);
   3149                       break;
   3150                     }
   3151                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   3152                     keyword);
   3153                   break;
   3154                 }
   3155                 case 'I':
   3156                 case 'i':
   3157                 {
   3158                   if (LocaleCompare(keyword,"inner") == 0)
   3159                     {
   3160                       frame_info.inner_bevel=StringToLong(value);
   3161                       break;
   3162                     }
   3163                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   3164                     keyword);
   3165                   break;
   3166                 }
   3167                 case 'O':
   3168                 case 'o':
   3169                 {
   3170                   if (LocaleCompare(keyword,"outer") == 0)
   3171                     {
   3172                       frame_info.outer_bevel=StringToLong(value);
   3173                       break;
   3174                     }
   3175                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   3176                     keyword);
   3177                   break;
   3178                 }
   3179                 case 'W':
   3180                 case 'w':
   3181                 {
   3182                   if (LocaleCompare(keyword,"width") == 0)
   3183                     {
   3184                       frame_info.width=StringToLong(value);
   3185                       break;
   3186                     }
   3187                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   3188                     keyword);
   3189                   break;
   3190                 }
   3191                 default:
   3192                 {
   3193                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   3194                     keyword);
   3195                   break;
   3196                 }
   3197               }
   3198             }
   3199           frame_info.x=(ssize_t) frame_info.width;
   3200           frame_info.y=(ssize_t) frame_info.height;
   3201           frame_info.width=msl_info->image[n]->columns+2*frame_info.x;
   3202           frame_info.height=msl_info->image[n]->rows+2*frame_info.y;
   3203           frame_image=FrameImage(msl_info->image[n],&frame_info,
   3204             msl_info->image[n]->compose,msl_info->exception);
   3205           if (frame_image == (Image *) NULL)
   3206             break;
   3207           msl_info->image[n]=DestroyImage(msl_info->image[n]);
   3208           msl_info->image[n]=frame_image;
   3209           break;
   3210         }
   3211       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
   3212     }
   3213     case 'G':
   3214     case 'g':
   3215     {
   3216       if (LocaleCompare((const char *) tag,"gamma") == 0)
   3217         {
   3218           char
   3219             gamma[MagickPathExtent];
   3220 
   3221           PixelInfo
   3222             pixel;
   3223 
   3224           /*
   3225             Gamma image.
   3226           */
   3227           if (msl_info->image[n] == (Image *) NULL)
   3228             {
   3229               ThrowMSLException(OptionError,"NoImagesDefined",
   3230                 (const char *) tag);
   3231               break;
   3232             }
   3233           channel=UndefinedChannel;
   3234           pixel.red=0.0;
   3235           pixel.green=0.0;
   3236           pixel.blue=0.0;
   3237           *gamma='\0';
   3238           if (attributes != (const xmlChar **) NULL)
   3239             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   3240             {
   3241               keyword=(const char *) attributes[i++];
   3242               attribute=InterpretImageProperties(msl_info->image_info[n],
   3243                 msl_info->attributes[n],(const char *) attributes[i],
   3244                 exception);
   3245               CloneString(&value,attribute);
   3246               attribute=DestroyString(attribute);
   3247               switch (*keyword)
   3248               {
   3249                 case 'B':
   3250                 case 'b':
   3251                 {
   3252                   if (LocaleCompare(keyword,"blue") == 0)
   3253                     {
   3254                       pixel.blue=StringToDouble(value,(char **) NULL);
   3255                       break;
   3256                     }
   3257                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   3258                     keyword);
   3259                   break;
   3260                 }
   3261                 case 'C':
   3262                 case 'c':
   3263                 {
   3264                   if (LocaleCompare(keyword,"channel") == 0)
   3265                     {
   3266                       option=ParseChannelOption(value);
   3267                       if (option < 0)
   3268                         ThrowMSLException(OptionError,"UnrecognizedChannelType",
   3269                           value);
   3270                       channel=(ChannelType) option;
   3271                       break;
   3272                     }
   3273                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   3274                     keyword);
   3275                   break;
   3276                 }
   3277                 case 'G':
   3278                 case 'g':
   3279                 {
   3280                   if (LocaleCompare(keyword,"gamma") == 0)
   3281                     {
   3282                       (void) CopyMagickString(gamma,value,MagickPathExtent);
   3283                       break;
   3284                     }
   3285                   if (LocaleCompare(keyword,"green") == 0)
   3286                     {
   3287                       pixel.green=StringToDouble(value,(char **) NULL);
   3288                       break;
   3289                     }
   3290                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   3291                     keyword);
   3292                   break;
   3293                 }
   3294                 case 'R':
   3295                 case 'r':
   3296                 {
   3297                   if (LocaleCompare(keyword,"red") == 0)
   3298                     {
   3299                       pixel.red=StringToDouble(value,(char **) NULL);
   3300                       break;
   3301                     }
   3302                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   3303                     keyword);
   3304                   break;
   3305                 }
   3306                 default:
   3307                 {
   3308                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   3309                     keyword);
   3310                   break;
   3311                 }
   3312               }
   3313             }
   3314           if (*gamma == '\0')
   3315             (void) FormatLocaleString(gamma,MagickPathExtent,"%g,%g,%g",
   3316               (double) pixel.red,(double) pixel.green,(double) pixel.blue);
   3317           (void) GammaImage(msl_info->image[n],strtod(gamma,(char **) NULL),
   3318             msl_info->exception);
   3319           break;
   3320         }
   3321       else if (LocaleCompare((const char *) tag,"get") == 0)
   3322         {
   3323           if (msl_info->image[n] == (Image *) NULL)
   3324             {
   3325               ThrowMSLException(OptionError,"NoImagesDefined",
   3326                 (const char *) tag);
   3327               break;
   3328             }
   3329           if (attributes == (const xmlChar **) NULL)
   3330             break;
   3331           for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   3332           {
   3333             keyword=(const char *) attributes[i++];
   3334             CloneString(&value,(const char *) attributes[i]);
   3335             (void) CopyMagickString(key,value,MagickPathExtent);
   3336             switch (*keyword)
   3337             {
   3338               case 'H':
   3339               case 'h':
   3340               {
   3341                 if (LocaleCompare(keyword,"height") == 0)
   3342                   {
   3343                     (void) FormatLocaleString(value,MagickPathExtent,"%.20g",
   3344                       (double) msl_info->image[n]->rows);
   3345                     (void) SetImageProperty(msl_info->attributes[n],key,value,
   3346                       exception);
   3347                     break;
   3348                   }
   3349                 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   3350               }
   3351               case 'W':
   3352               case 'w':
   3353               {
   3354                 if (LocaleCompare(keyword,"width") == 0)
   3355                   {
   3356                     (void) FormatLocaleString(value,MagickPathExtent,"%.20g",
   3357                       (double) msl_info->image[n]->columns);
   3358                     (void) SetImageProperty(msl_info->attributes[n],key,value,
   3359                       exception);
   3360                     break;
   3361                   }
   3362                 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   3363               }
   3364               default:
   3365               {
   3366                 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   3367                 break;
   3368               }
   3369             }
   3370           }
   3371           break;
   3372         }
   3373     else if (LocaleCompare((const char *) tag, "group") == 0)
   3374     {
   3375       msl_info->number_groups++;
   3376       msl_info->group_info=(MSLGroupInfo *) ResizeQuantumMemory(
   3377         msl_info->group_info,msl_info->number_groups+1UL,
   3378         sizeof(*msl_info->group_info));
   3379       break;
   3380     }
   3381       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
   3382     }
   3383     case 'I':
   3384     case 'i':
   3385     {
   3386       if (LocaleCompare((const char *) tag,"image") == 0)
   3387         {
   3388           MSLPushImage(msl_info,(Image *) NULL);
   3389           if (attributes == (const xmlChar **) NULL)
   3390             break;
   3391           for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   3392           {
   3393             keyword=(const char *) attributes[i++];
   3394             attribute=InterpretImageProperties(msl_info->image_info[n],
   3395               msl_info->attributes[n],(const char *) attributes[i],exception);
   3396             CloneString(&value,attribute);
   3397             attribute=DestroyString(attribute);
   3398             switch (*keyword)
   3399             {
   3400               case 'C':
   3401               case 'c':
   3402               {
   3403                 if (LocaleCompare(keyword,"color") == 0)
   3404                   {
   3405                     Image
   3406                       *next_image;
   3407 
   3408                     (void) CopyMagickString(msl_info->image_info[n]->filename,
   3409                       "xc:",MagickPathExtent);
   3410                     (void) ConcatenateMagickString(msl_info->image_info[n]->
   3411                       filename,value,MagickPathExtent);
   3412                     next_image=ReadImage(msl_info->image_info[n],exception);
   3413                     CatchException(exception);
   3414                     if (next_image == (Image *) NULL)
   3415                       continue;
   3416                     if (msl_info->image[n] == (Image *) NULL)
   3417                       msl_info->image[n]=next_image;
   3418                     else
   3419                       {
   3420                         register Image
   3421                           *p;
   3422 
   3423                         /*
   3424                           Link image into image list.
   3425                         */
   3426                         p=msl_info->image[n];
   3427                         while (p->next != (Image *) NULL)
   3428                           p=GetNextImageInList(p);
   3429                         next_image->previous=p;
   3430                         p->next=next_image;
   3431                       }
   3432                     break;
   3433                   }
   3434                 (void) SetMSLAttributes(msl_info,keyword,value);
   3435                 break;
   3436               }
   3437               default:
   3438               {
   3439                 (void) SetMSLAttributes(msl_info,keyword,value);
   3440                 break;
   3441               }
   3442             }
   3443           }
   3444           break;
   3445         }
   3446       if (LocaleCompare((const char *) tag,"implode") == 0)
   3447         {
   3448           Image
   3449             *implode_image;
   3450 
   3451           /*
   3452             Implode image.
   3453           */
   3454           if (msl_info->image[n] == (Image *) NULL)
   3455             {
   3456               ThrowMSLException(OptionError,"NoImagesDefined",
   3457                 (const char *) tag);
   3458               break;
   3459             }
   3460           if (attributes != (const xmlChar **) NULL)
   3461             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   3462             {
   3463               keyword=(const char *) attributes[i++];
   3464               attribute=InterpretImageProperties(msl_info->image_info[n],
   3465                 msl_info->attributes[n],(const char *) attributes[i],
   3466                 exception);
   3467               CloneString(&value,attribute);
   3468               attribute=DestroyString(attribute);
   3469               switch (*keyword)
   3470               {
   3471                 case 'A':
   3472                 case 'a':
   3473                 {
   3474                   if (LocaleCompare(keyword,"amount") == 0)
   3475                     {
   3476                       geometry_info.rho=StringToDouble(value,
   3477                         (char **) NULL);
   3478                       break;
   3479                     }
   3480                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   3481                     keyword);
   3482                   break;
   3483                 }
   3484                 case 'G':
   3485                 case 'g':
   3486                 {
   3487                   if (LocaleCompare(keyword,"geometry") == 0)
   3488                     {
   3489                       flags=ParseGeometry(value,&geometry_info);
   3490                       if ((flags & SigmaValue) == 0)
   3491                         geometry_info.sigma=1.0;
   3492                       break;
   3493                     }
   3494                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   3495                     keyword);
   3496                   break;
   3497                 }
   3498                 default:
   3499                 {
   3500                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   3501                     keyword);
   3502                   break;
   3503                 }
   3504               }
   3505             }
   3506           implode_image=ImplodeImage(msl_info->image[n],geometry_info.rho,
   3507             msl_info->image[n]->interpolate,msl_info->exception);
   3508           if (implode_image == (Image *) NULL)
   3509             break;
   3510           msl_info->image[n]=DestroyImage(msl_info->image[n]);
   3511           msl_info->image[n]=implode_image;
   3512           break;
   3513         }
   3514       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
   3515     }
   3516     case 'L':
   3517     case 'l':
   3518     {
   3519       if (LocaleCompare((const char *) tag,"label") == 0)
   3520         break;
   3521       if (LocaleCompare((const char *) tag, "level") == 0)
   3522       {
   3523         double
   3524           levelBlack = 0, levelGamma = 1, levelWhite = QuantumRange;
   3525 
   3526         if (msl_info->image[n] == (Image *) NULL)
   3527         {
   3528           ThrowMSLException(OptionError,"NoImagesDefined",
   3529             (const char *) tag);
   3530           break;
   3531         }
   3532         if (attributes == (const xmlChar **) NULL)
   3533           break;
   3534         for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   3535         {
   3536           keyword=(const char *) attributes[i++];
   3537           CloneString(&value,(const char *) attributes[i]);
   3538           (void) CopyMagickString(key,value,MagickPathExtent);
   3539           switch (*keyword)
   3540           {
   3541             case 'B':
   3542             case 'b':
   3543             {
   3544               if (LocaleCompare(keyword,"black") == 0)
   3545               {
   3546                 levelBlack = StringToDouble(value,(char **) NULL);
   3547                 break;
   3548               }
   3549               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   3550               break;
   3551             }
   3552             case 'G':
   3553             case 'g':
   3554             {
   3555               if (LocaleCompare(keyword,"gamma") == 0)
   3556               {
   3557                 levelGamma = StringToDouble(value,(char **) NULL);
   3558                 break;
   3559               }
   3560               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   3561               break;
   3562             }
   3563             case 'W':
   3564             case 'w':
   3565             {
   3566               if (LocaleCompare(keyword,"white") == 0)
   3567               {
   3568                 levelWhite = StringToDouble(value,(char **) NULL);
   3569                 break;
   3570               }
   3571               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   3572               break;
   3573             }
   3574             default:
   3575             {
   3576               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   3577               break;
   3578             }
   3579           }
   3580         }
   3581 
   3582         /* process image */
   3583         LevelImage(msl_info->image[n],levelBlack,levelWhite,levelGamma,
   3584           msl_info->exception);
   3585         break;
   3586       }
   3587     }
   3588     case 'M':
   3589     case 'm':
   3590     {
   3591       if (LocaleCompare((const char *) tag,"magnify") == 0)
   3592         {
   3593           Image
   3594             *magnify_image;
   3595 
   3596           /*
   3597             Magnify image.
   3598           */
   3599           if (msl_info->image[n] == (Image *) NULL)
   3600             {
   3601               ThrowMSLException(OptionError,"NoImagesDefined",
   3602                 (const char *) tag);
   3603               break;
   3604             }
   3605           if (attributes != (const xmlChar **) NULL)
   3606             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   3607             {
   3608               keyword=(const char *) attributes[i++];
   3609               attribute=InterpretImageProperties(msl_info->image_info[n],
   3610                 msl_info->attributes[n],(const char *) attributes[i],
   3611                 exception);
   3612               CloneString(&value,attribute);
   3613               attribute=DestroyString(attribute);
   3614               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   3615             }
   3616           magnify_image=MagnifyImage(msl_info->image[n],
   3617             msl_info->exception);
   3618           if (magnify_image == (Image *) NULL)
   3619             break;
   3620           msl_info->image[n]=DestroyImage(msl_info->image[n]);
   3621           msl_info->image[n]=magnify_image;
   3622           break;
   3623         }
   3624       if (LocaleCompare((const char *) tag,"map") == 0)
   3625         {
   3626           Image
   3627             *affinity_image;
   3628 
   3629           MagickBooleanType
   3630             dither;
   3631 
   3632           QuantizeInfo
   3633             *quantize_info;
   3634 
   3635           /*
   3636             Map image.
   3637           */
   3638           if (msl_info->image[n] == (Image *) NULL)
   3639             {
   3640               ThrowMSLException(OptionError,"NoImagesDefined",
   3641                 (const char *) tag);
   3642               break;
   3643             }
   3644           affinity_image=NewImageList();
   3645           dither=MagickFalse;
   3646           if (attributes != (const xmlChar **) NULL)
   3647             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   3648             {
   3649               keyword=(const char *) attributes[i++];
   3650               attribute=InterpretImageProperties(msl_info->image_info[n],
   3651                 msl_info->attributes[n],(const char *) attributes[i],
   3652                 exception);
   3653               CloneString(&value,attribute);
   3654               attribute=DestroyString(attribute);
   3655               switch (*keyword)
   3656               {
   3657                 case 'D':
   3658                 case 'd':
   3659                 {
   3660                   if (LocaleCompare(keyword,"dither") == 0)
   3661                     {
   3662                       option=ParseCommandOption(MagickBooleanOptions,
   3663                         MagickFalse,value);
   3664                       if (option < 0)
   3665                         ThrowMSLException(OptionError,"UnrecognizedBooleanType",
   3666                           value);
   3667                       dither=(MagickBooleanType) option;
   3668                       break;
   3669                     }
   3670                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   3671                     keyword);
   3672                   break;
   3673                 }
   3674                 case 'I':
   3675                 case 'i':
   3676                 {
   3677                   if (LocaleCompare(keyword,"image") == 0)
   3678                     for (j=0; j < msl_info->n; j++)
   3679                     {
   3680                       const char
   3681                         *attribute;
   3682 
   3683                       attribute=GetImageProperty(msl_info->attributes[j],"id",
   3684                         exception);
   3685                       if ((attribute != (const char *) NULL)  &&
   3686                           (LocaleCompare(attribute,value) == 0))
   3687                         {
   3688                           affinity_image=CloneImage(msl_info->image[j],0,0,
   3689                             MagickFalse,exception);
   3690                           break;
   3691                         }
   3692                     }
   3693                   break;
   3694                 }
   3695                 default:
   3696                 {
   3697                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   3698                     keyword);
   3699                   break;
   3700                 }
   3701               }
   3702             }
   3703           quantize_info=AcquireQuantizeInfo(msl_info->image_info[n]);
   3704           quantize_info->dither_method=dither != MagickFalse ?
   3705             RiemersmaDitherMethod : NoDitherMethod;
   3706           (void) RemapImages(quantize_info,msl_info->image[n],
   3707             affinity_image,exception);
   3708           quantize_info=DestroyQuantizeInfo(quantize_info);
   3709           affinity_image=DestroyImage(affinity_image);
   3710           break;
   3711         }
   3712       if (LocaleCompare((const char *) tag,"matte-floodfill") == 0)
   3713         {
   3714           double
   3715             opacity;
   3716 
   3717           PixelInfo
   3718             target;
   3719 
   3720           PaintMethod
   3721             paint_method;
   3722 
   3723           /*
   3724             Matte floodfill image.
   3725           */
   3726           opacity=0.0;
   3727           if (msl_info->image[n] == (Image *) NULL)
   3728             {
   3729               ThrowMSLException(OptionError,"NoImagesDefined",
   3730                 (const char *) tag);
   3731               break;
   3732             }
   3733           SetGeometry(msl_info->image[n],&geometry);
   3734           paint_method=FloodfillMethod;
   3735           if (attributes != (const xmlChar **) NULL)
   3736             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   3737             {
   3738               keyword=(const char *) attributes[i++];
   3739               attribute=InterpretImageProperties(msl_info->image_info[n],
   3740                 msl_info->attributes[n],(const char *) attributes[i],
   3741                 exception);
   3742               CloneString(&value,attribute);
   3743               attribute=DestroyString(attribute);
   3744               switch (*keyword)
   3745               {
   3746                 case 'B':
   3747                 case 'b':
   3748                 {
   3749                   if (LocaleCompare(keyword,"bordercolor") == 0)
   3750                     {
   3751                       (void) QueryColorCompliance(value,AllCompliance,
   3752                         &target,exception);
   3753                       paint_method=FillToBorderMethod;
   3754                       break;
   3755                     }
   3756                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   3757                     keyword);
   3758                   break;
   3759                 }
   3760                 case 'F':
   3761                 case 'f':
   3762                 {
   3763                   if (LocaleCompare(keyword,"fuzz") == 0)
   3764                     {
   3765                       msl_info->image[n]->fuzz=StringToDouble(value,
   3766                         (char **) NULL);
   3767                       break;
   3768                     }
   3769                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   3770                     keyword);
   3771                   break;
   3772                 }
   3773                 case 'G':
   3774                 case 'g':
   3775                 {
   3776                   if (LocaleCompare(keyword,"geometry") == 0)
   3777                     {
   3778                       flags=ParsePageGeometry(msl_info->image[n],value,
   3779                         &geometry,exception);
   3780                       if ((flags & HeightValue) == 0)
   3781                         geometry.height=geometry.width;
   3782                       (void) GetOneVirtualPixelInfo(msl_info->image[n],
   3783                         TileVirtualPixelMethod,geometry.x,geometry.y,&target,
   3784                         exception);
   3785                       break;
   3786                     }
   3787                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   3788                     keyword);
   3789                   break;
   3790                 }
   3791                 case 'O':
   3792                 case 'o':
   3793                 {
   3794                   if (LocaleCompare(keyword,"opacity") == 0)
   3795                     {
   3796                       opacity=StringToDouble(value,(char **) NULL);
   3797                       break;
   3798                     }
   3799                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   3800                     keyword);
   3801                   break;
   3802                 }
   3803                 case 'X':
   3804                 case 'x':
   3805                 {
   3806                   if (LocaleCompare(keyword,"x") == 0)
   3807                     {
   3808                       geometry.x=StringToLong(value);
   3809                       (void) GetOneVirtualPixelInfo(msl_info->image[n],
   3810                         TileVirtualPixelMethod,geometry.x,geometry.y,&target,
   3811                         exception);
   3812                       break;
   3813                     }
   3814                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   3815                     keyword);
   3816                   break;
   3817                 }
   3818                 case 'Y':
   3819                 case 'y':
   3820                 {
   3821                   if (LocaleCompare(keyword,"y") == 0)
   3822                     {
   3823                       geometry.y=StringToLong(value);
   3824                       (void) GetOneVirtualPixelInfo(msl_info->image[n],
   3825                         TileVirtualPixelMethod,geometry.x,geometry.y,&target,
   3826                         exception);
   3827                       break;
   3828                     }
   3829                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   3830                     keyword);
   3831                   break;
   3832                 }
   3833                 default:
   3834                 {
   3835                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   3836                     keyword);
   3837                   break;
   3838                 }
   3839               }
   3840             }
   3841           draw_info=CloneDrawInfo(msl_info->image_info[n],
   3842             msl_info->draw_info[n]);
   3843           draw_info->fill.alpha=ClampToQuantum(opacity);
   3844           channel_mask=SetImageChannelMask(msl_info->image[n],AlphaChannel);
   3845           (void) FloodfillPaintImage(msl_info->image[n],draw_info,&target,
   3846             geometry.x,geometry.y,paint_method == FloodfillMethod ?
   3847             MagickFalse : MagickTrue,msl_info->exception);
   3848           (void) SetPixelChannelMask(msl_info->image[n],channel_mask);
   3849           draw_info=DestroyDrawInfo(draw_info);
   3850           break;
   3851         }
   3852       if (LocaleCompare((const char *) tag,"median-filter") == 0)
   3853         {
   3854           Image
   3855             *median_image;
   3856 
   3857           /*
   3858             Median-filter image.
   3859           */
   3860           if (msl_info->image[n] == (Image *) NULL)
   3861             {
   3862               ThrowMSLException(OptionError,"NoImagesDefined",
   3863                 (const char *) tag);
   3864               break;
   3865             }
   3866           if (attributes != (const xmlChar **) NULL)
   3867             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   3868             {
   3869               keyword=(const char *) attributes[i++];
   3870               attribute=InterpretImageProperties(msl_info->image_info[n],
   3871                 msl_info->attributes[n],(const char *) attributes[i],
   3872                 exception);
   3873               CloneString(&value,attribute);
   3874               attribute=DestroyString(attribute);
   3875               switch (*keyword)
   3876               {
   3877                 case 'G':
   3878                 case 'g':
   3879                 {
   3880                   if (LocaleCompare(keyword,"geometry") == 0)
   3881                     {
   3882                       flags=ParseGeometry(value,&geometry_info);
   3883                       if ((flags & SigmaValue) == 0)
   3884                         geometry_info.sigma=1.0;
   3885                       break;
   3886                     }
   3887                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   3888                     keyword);
   3889                   break;
   3890                 }
   3891                 case 'R':
   3892                 case 'r':
   3893                 {
   3894                   if (LocaleCompare(keyword,"radius") == 0)
   3895                     {
   3896                       geometry_info.rho=StringToDouble(value,
   3897                         (char **) NULL);
   3898                       break;
   3899                     }
   3900                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   3901                     keyword);
   3902                   break;
   3903                 }
   3904                 default:
   3905                 {
   3906                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   3907                     keyword);
   3908                   break;
   3909                 }
   3910               }
   3911             }
   3912           median_image=StatisticImage(msl_info->image[n],MedianStatistic,
   3913             (size_t) geometry_info.rho,(size_t) geometry_info.sigma,
   3914             msl_info->exception);
   3915           if (median_image == (Image *) NULL)
   3916             break;
   3917           msl_info->image[n]=DestroyImage(msl_info->image[n]);
   3918           msl_info->image[n]=median_image;
   3919           break;
   3920         }
   3921       if (LocaleCompare((const char *) tag,"minify") == 0)
   3922         {
   3923           Image
   3924             *minify_image;
   3925 
   3926           /*
   3927             Minify image.
   3928           */
   3929           if (msl_info->image[n] == (Image *) NULL)
   3930             {
   3931               ThrowMSLException(OptionError,"NoImagesDefined",
   3932                 (const char *) tag);
   3933               break;
   3934             }
   3935           if (attributes != (const xmlChar **) NULL)
   3936             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   3937             {
   3938               keyword=(const char *) attributes[i++];
   3939               attribute=InterpretImageProperties(msl_info->image_info[n],
   3940                 msl_info->attributes[n],(const char *) attributes[i],
   3941                 exception);
   3942               CloneString(&value,attribute);
   3943               attribute=DestroyString(attribute);
   3944               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   3945             }
   3946           minify_image=MinifyImage(msl_info->image[n],
   3947             msl_info->exception);
   3948           if (minify_image == (Image *) NULL)
   3949             break;
   3950           msl_info->image[n]=DestroyImage(msl_info->image[n]);
   3951           msl_info->image[n]=minify_image;
   3952           break;
   3953         }
   3954       if (LocaleCompare((const char *) tag,"msl") == 0 )
   3955         break;
   3956       if (LocaleCompare((const char *) tag,"modulate") == 0)
   3957         {
   3958           char
   3959             modulate[MagickPathExtent];
   3960 
   3961           /*
   3962             Modulate image.
   3963           */
   3964           if (msl_info->image[n] == (Image *) NULL)
   3965             {
   3966               ThrowMSLException(OptionError,"NoImagesDefined",
   3967                 (const char *) tag);
   3968               break;
   3969             }
   3970           geometry_info.rho=100.0;
   3971           geometry_info.sigma=100.0;
   3972           geometry_info.xi=100.0;
   3973           if (attributes != (const xmlChar **) NULL)
   3974             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   3975             {
   3976               keyword=(const char *) attributes[i++];
   3977               attribute=InterpretImageProperties(msl_info->image_info[n],
   3978                 msl_info->attributes[n],(const char *) attributes[i],
   3979                 exception);
   3980               CloneString(&value,attribute);
   3981               attribute=DestroyString(attribute);
   3982               switch (*keyword)
   3983               {
   3984                 case 'B':
   3985                 case 'b':
   3986                 {
   3987                   if (LocaleCompare(keyword,"blackness") == 0)
   3988                     {
   3989                       geometry_info.rho=StringToDouble(value,
   3990                         (char **) NULL);
   3991                       break;
   3992                     }
   3993                   if (LocaleCompare(keyword,"brightness") == 0)
   3994                     {
   3995                       geometry_info.rho=StringToDouble(value,
   3996                         (char **) NULL);
   3997                       break;
   3998                     }
   3999                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   4000                     keyword);
   4001                   break;
   4002                 }
   4003                 case 'F':
   4004                 case 'f':
   4005                 {
   4006                   if (LocaleCompare(keyword,"factor") == 0)
   4007                     {
   4008                       flags=ParseGeometry(value,&geometry_info);
   4009                       break;
   4010                     }
   4011                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   4012                     keyword);
   4013                   break;
   4014                 }
   4015                 case 'H':
   4016                 case 'h':
   4017                 {
   4018                   if (LocaleCompare(keyword,"hue") == 0)
   4019                     {
   4020                       geometry_info.xi=StringToDouble(value,
   4021                         (char **) NULL);
   4022                       break;
   4023                     }
   4024                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   4025                     keyword);
   4026                   break;
   4027                 }
   4028                 case 'L':
   4029                 case 'l':
   4030                 {
   4031                   if (LocaleCompare(keyword,"lightness") == 0)
   4032                     {
   4033                       geometry_info.rho=StringToDouble(value,
   4034                         (char **) NULL);
   4035                       break;
   4036                     }
   4037                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   4038                     keyword);
   4039                   break;
   4040                 }
   4041                 case 'S':
   4042                 case 's':
   4043                 {
   4044                   if (LocaleCompare(keyword,"saturation") == 0)
   4045                     {
   4046                       geometry_info.sigma=StringToDouble(value,
   4047                         (char **) NULL);
   4048                       break;
   4049                     }
   4050                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   4051                     keyword);
   4052                   break;
   4053                 }
   4054                 case 'W':
   4055                 case 'w':
   4056                 {
   4057                   if (LocaleCompare(keyword,"whiteness") == 0)
   4058                     {
   4059                       geometry_info.sigma=StringToDouble(value,
   4060                         (char **) NULL);
   4061                       break;
   4062                     }
   4063                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   4064                     keyword);
   4065                   break;
   4066                 }
   4067                 default:
   4068                 {
   4069                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   4070                     keyword);
   4071                   break;
   4072                 }
   4073               }
   4074             }
   4075           (void) FormatLocaleString(modulate,MagickPathExtent,"%g,%g,%g",
   4076             geometry_info.rho,geometry_info.sigma,geometry_info.xi);
   4077           (void) ModulateImage(msl_info->image[n],modulate,
   4078             msl_info->exception);
   4079           break;
   4080         }
   4081       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
   4082     }
   4083     case 'N':
   4084     case 'n':
   4085     {
   4086       if (LocaleCompare((const char *) tag,"negate") == 0)
   4087         {
   4088           MagickBooleanType
   4089             gray;
   4090 
   4091           /*
   4092             Negate image.
   4093           */
   4094           if (msl_info->image[n] == (Image *) NULL)
   4095             {
   4096               ThrowMSLException(OptionError,"NoImagesDefined",
   4097                 (const char *) tag);
   4098               break;
   4099             }
   4100           gray=MagickFalse;
   4101           if (attributes != (const xmlChar **) NULL)
   4102             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   4103             {
   4104               keyword=(const char *) attributes[i++];
   4105               attribute=InterpretImageProperties(msl_info->image_info[n],
   4106                 msl_info->attributes[n],(const char *) attributes[i],
   4107                 exception);
   4108               CloneString(&value,attribute);
   4109               attribute=DestroyString(attribute);
   4110               switch (*keyword)
   4111               {
   4112                 case 'C':
   4113                 case 'c':
   4114                 {
   4115                   if (LocaleCompare(keyword,"channel") == 0)
   4116                     {
   4117                       option=ParseChannelOption(value);
   4118                       if (option < 0)
   4119                         ThrowMSLException(OptionError,"UnrecognizedChannelType",
   4120                           value);
   4121                       channel=(ChannelType) option;
   4122                       break;
   4123                     }
   4124                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   4125                     keyword);
   4126                   break;
   4127                 }
   4128                 case 'G':
   4129                 case 'g':
   4130                 {
   4131                   if (LocaleCompare(keyword,"gray") == 0)
   4132                     {
   4133                       option=ParseCommandOption(MagickBooleanOptions,
   4134                         MagickFalse,value);
   4135                       if (option < 0)
   4136                         ThrowMSLException(OptionError,"UnrecognizedBooleanType",
   4137                           value);
   4138                       gray=(MagickBooleanType) option;
   4139                       break;
   4140                     }
   4141                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   4142                     keyword);
   4143                   break;
   4144                 }
   4145                 default:
   4146                 {
   4147                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   4148                     keyword);
   4149                   break;
   4150                 }
   4151               }
   4152             }
   4153           channel_mask=SetImageChannelMask(msl_info->image[n],channel);
   4154           (void) NegateImage(msl_info->image[n],gray,
   4155             msl_info->exception);
   4156           (void) SetPixelChannelMask(msl_info->image[n],channel_mask);
   4157           break;
   4158         }
   4159       if (LocaleCompare((const char *) tag,"normalize") == 0)
   4160         {
   4161           /*
   4162             Normalize image.
   4163           */
   4164           if (msl_info->image[n] == (Image *) NULL)
   4165             {
   4166               ThrowMSLException(OptionError,"NoImagesDefined",
   4167                 (const char *) tag);
   4168               break;
   4169             }
   4170           if (attributes != (const xmlChar **) NULL)
   4171             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   4172             {
   4173               keyword=(const char *) attributes[i++];
   4174               attribute=InterpretImageProperties(msl_info->image_info[n],
   4175                 msl_info->attributes[n],(const char *) attributes[i],
   4176                 exception);
   4177               CloneString(&value,attribute);
   4178               attribute=DestroyString(attribute);
   4179               switch (*keyword)
   4180               {
   4181                 case 'C':
   4182                 case 'c':
   4183                 {
   4184                   if (LocaleCompare(keyword,"channel") == 0)
   4185                     {
   4186                       option=ParseChannelOption(value);
   4187                       if (option < 0)
   4188                         ThrowMSLException(OptionError,"UnrecognizedChannelType",
   4189                           value);
   4190                       channel=(ChannelType) option;
   4191                       break;
   4192                     }
   4193                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   4194                     keyword);
   4195                   break;
   4196                 }
   4197                 default:
   4198                 {
   4199                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   4200                     keyword);
   4201                   break;
   4202                 }
   4203               }
   4204             }
   4205           (void) NormalizeImage(msl_info->image[n],
   4206             msl_info->exception);
   4207           break;
   4208         }
   4209       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
   4210     }
   4211     case 'O':
   4212     case 'o':
   4213     {
   4214       if (LocaleCompare((const char *) tag,"oil-paint") == 0)
   4215         {
   4216           Image
   4217             *paint_image;
   4218 
   4219           /*
   4220             Oil-paint image.
   4221           */
   4222           if (msl_info->image[n] == (Image *) NULL)
   4223             {
   4224               ThrowMSLException(OptionError,"NoImagesDefined",
   4225                 (const char *) tag);
   4226               break;
   4227             }
   4228           if (attributes != (const xmlChar **) NULL)
   4229             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   4230             {
   4231               keyword=(const char *) attributes[i++];
   4232               attribute=InterpretImageProperties(msl_info->image_info[n],
   4233                 msl_info->attributes[n],(const char *) attributes[i],
   4234                 exception);
   4235               CloneString(&value,attribute);
   4236               attribute=DestroyString(attribute);
   4237               switch (*keyword)
   4238               {
   4239                 case 'G':
   4240                 case 'g':
   4241                 {
   4242                   if (LocaleCompare(keyword,"geometry") == 0)
   4243                     {
   4244                       flags=ParseGeometry(value,&geometry_info);
   4245                       if ((flags & SigmaValue) == 0)
   4246                         geometry_info.sigma=1.0;
   4247                       break;
   4248                     }
   4249                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   4250                     keyword);
   4251                   break;
   4252                 }
   4253                 case 'R':
   4254                 case 'r':
   4255                 {
   4256                   if (LocaleCompare(keyword,"radius") == 0)
   4257                     {
   4258                       geometry_info.rho=StringToDouble(value,
   4259                         (char **) NULL);
   4260                       break;
   4261                     }
   4262                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   4263                     keyword);
   4264                   break;
   4265                 }
   4266                 default:
   4267                 {
   4268                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   4269                     keyword);
   4270                   break;
   4271                 }
   4272               }
   4273             }
   4274           paint_image=OilPaintImage(msl_info->image[n],geometry_info.rho,
   4275             geometry_info.sigma,msl_info->exception);
   4276           if (paint_image == (Image *) NULL)
   4277             break;
   4278           msl_info->image[n]=DestroyImage(msl_info->image[n]);
   4279           msl_info->image[n]=paint_image;
   4280           break;
   4281         }
   4282       if (LocaleCompare((const char *) tag,"opaque") == 0)
   4283         {
   4284           PixelInfo
   4285             fill_color,
   4286             target;
   4287 
   4288           /*
   4289             Opaque image.
   4290           */
   4291           if (msl_info->image[n] == (Image *) NULL)
   4292             {
   4293               ThrowMSLException(OptionError,"NoImagesDefined",
   4294                 (const char *) tag);
   4295               break;
   4296             }
   4297           (void) QueryColorCompliance("none",AllCompliance,&target,
   4298             exception);
   4299           (void) QueryColorCompliance("none",AllCompliance,&fill_color,
   4300             exception);
   4301           if (attributes != (const xmlChar **) NULL)
   4302             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   4303             {
   4304               keyword=(const char *) attributes[i++];
   4305               attribute=InterpretImageProperties(msl_info->image_info[n],
   4306                 msl_info->attributes[n],(const char *) attributes[i],
   4307                 exception);
   4308               CloneString(&value,attribute);
   4309               attribute=DestroyString(attribute);
   4310               switch (*keyword)
   4311               {
   4312                 case 'C':
   4313                 case 'c':
   4314                 {
   4315                   if (LocaleCompare(keyword,"channel") == 0)
   4316                     {
   4317                       option=ParseChannelOption(value);
   4318                       if (option < 0)
   4319                         ThrowMSLException(OptionError,"UnrecognizedChannelType",
   4320                           value);
   4321                       channel=(ChannelType) option;
   4322                       break;
   4323                     }
   4324                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   4325                     keyword);
   4326                   break;
   4327                 }
   4328                 case 'F':
   4329                 case 'f':
   4330                 {
   4331                   if (LocaleCompare(keyword,"fill") == 0)
   4332                     {
   4333                       (void) QueryColorCompliance(value,AllCompliance,
   4334                         &fill_color,exception);
   4335                       break;
   4336                     }
   4337                   if (LocaleCompare(keyword,"fuzz") == 0)
   4338                     {
   4339                       msl_info->image[n]->fuzz=StringToDouble(value,
   4340                         (char **) NULL);
   4341                       break;
   4342                     }
   4343                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   4344                     keyword);
   4345                   break;
   4346                 }
   4347                 default:
   4348                 {
   4349                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   4350                     keyword);
   4351                   break;
   4352                 }
   4353               }
   4354             }
   4355           channel_mask=SetImageChannelMask(msl_info->image[n],channel);
   4356           (void) OpaquePaintImage(msl_info->image[n],&target,&fill_color,
   4357             MagickFalse,msl_info->exception);
   4358           (void) SetPixelChannelMask(msl_info->image[n],channel_mask);
   4359           break;
   4360         }
   4361       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
   4362     }
   4363     case 'P':
   4364     case 'p':
   4365     {
   4366       if (LocaleCompare((const char *) tag,"print") == 0)
   4367         {
   4368           if (attributes == (const xmlChar **) NULL)
   4369             break;
   4370           for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   4371           {
   4372             keyword=(const char *) attributes[i++];
   4373             attribute=InterpretImageProperties(msl_info->image_info[n],
   4374               msl_info->attributes[n],(const char *) attributes[i],
   4375               exception);
   4376             CloneString(&value,attribute);
   4377             attribute=DestroyString(attribute);
   4378             switch (*keyword)
   4379             {
   4380               case 'O':
   4381               case 'o':
   4382               {
   4383                 if (LocaleCompare(keyword,"output") == 0)
   4384                   {
   4385                     (void) FormatLocaleFile(stdout,"%s",value);
   4386                     break;
   4387                   }
   4388                 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   4389                 break;
   4390               }
   4391               default:
   4392               {
   4393                 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   4394                 break;
   4395               }
   4396             }
   4397           }
   4398           break;
   4399         }
   4400         if (LocaleCompare((const char *) tag, "profile") == 0)
   4401           {
   4402             if (msl_info->image[n] == (Image *) NULL)
   4403               {
   4404                 ThrowMSLException(OptionError,"NoImagesDefined",
   4405                   (const char *) tag);
   4406                 break;
   4407               }
   4408             if (attributes == (const xmlChar **) NULL)
   4409               break;
   4410             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   4411             {
   4412               const char
   4413                 *name;
   4414 
   4415               const StringInfo
   4416                 *profile;
   4417 
   4418               Image
   4419                 *profile_image;
   4420 
   4421               ImageInfo
   4422                 *profile_info;
   4423 
   4424               keyword=(const char *) attributes[i++];
   4425               attribute=InterpretImageProperties(msl_info->image_info[n],
   4426                 msl_info->attributes[n],(const char *) attributes[i],
   4427                 exception);
   4428               CloneString(&value,attribute);
   4429               attribute=DestroyString(attribute);
   4430               if (*keyword == '!')
   4431                 {
   4432                   /*
   4433                     Remove a profile from the image.
   4434                   */
   4435                   (void) ProfileImage(msl_info->image[n],keyword,
   4436                     (const unsigned char *) NULL,0,exception);
   4437                   continue;
   4438                 }
   4439               /*
   4440                 Associate a profile with the image.
   4441               */
   4442               profile_info=CloneImageInfo(msl_info->image_info[n]);
   4443               profile=GetImageProfile(msl_info->image[n],"iptc");
   4444               if (profile != (StringInfo *) NULL)
   4445                 profile_info->profile=(void *) CloneStringInfo(profile);
   4446               profile_image=GetImageCache(profile_info,keyword,exception);
   4447               profile_info=DestroyImageInfo(profile_info);
   4448               if (profile_image == (Image *) NULL)
   4449                 {
   4450                   char
   4451                     name[MagickPathExtent],
   4452                     filename[MagickPathExtent];
   4453 
   4454                   register char
   4455                     *p;
   4456 
   4457                   StringInfo
   4458                     *profile;
   4459 
   4460                   (void) CopyMagickString(filename,keyword,MagickPathExtent);
   4461                   (void) CopyMagickString(name,keyword,MagickPathExtent);
   4462                   for (p=filename; *p != '\0'; p++)
   4463                     if ((*p == ':') && (IsPathDirectory(keyword) < 0) &&
   4464                         (IsPathAccessible(keyword) == MagickFalse))
   4465                       {
   4466                         register char
   4467                           *q;
   4468 
   4469                         /*
   4470                           Look for profile name (e.g. name:profile).
   4471                         */
   4472                         (void) CopyMagickString(name,filename,(size_t)
   4473                           (p-filename+1));
   4474                         for (q=filename; *q != '\0'; q++)
   4475                           *q=(*++p);
   4476                         break;
   4477                       }
   4478                   profile=FileToStringInfo(filename,~0UL,exception);
   4479                   if (profile != (StringInfo *) NULL)
   4480                     {
   4481                       (void) ProfileImage(msl_info->image[n],name,
   4482                         GetStringInfoDatum(profile),(size_t)
   4483                         GetStringInfoLength(profile),exception);
   4484                       profile=DestroyStringInfo(profile);
   4485                     }
   4486                   continue;
   4487                 }
   4488               ResetImageProfileIterator(profile_image);
   4489               name=GetNextImageProfile(profile_image);
   4490               while (name != (const char *) NULL)
   4491               {
   4492                 profile=GetImageProfile(profile_image,name);
   4493                 if (profile != (StringInfo *) NULL)
   4494                   (void) ProfileImage(msl_info->image[n],name,
   4495                     GetStringInfoDatum(profile),(size_t)
   4496                     GetStringInfoLength(profile),exception);
   4497                 name=GetNextImageProfile(profile_image);
   4498               }
   4499               profile_image=DestroyImage(profile_image);
   4500             }
   4501             break;
   4502           }
   4503       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
   4504     }
   4505     case 'Q':
   4506     case 'q':
   4507     {
   4508       if (LocaleCompare((const char *) tag,"quantize") == 0)
   4509         {
   4510           QuantizeInfo
   4511             quantize_info;
   4512 
   4513           /*
   4514             Quantize image.
   4515           */
   4516           if (msl_info->image[n] == (Image *) NULL)
   4517             {
   4518               ThrowMSLException(OptionError,"NoImagesDefined",
   4519                 (const char *) tag);
   4520               break;
   4521             }
   4522           GetQuantizeInfo(&quantize_info);
   4523           if (attributes != (const xmlChar **) NULL)
   4524             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   4525             {
   4526               keyword=(const char *) attributes[i++];
   4527               attribute=InterpretImageProperties(msl_info->image_info[n],
   4528                 msl_info->attributes[n],(const char *) attributes[i],
   4529                 exception);
   4530               CloneString(&value,attribute);
   4531               attribute=DestroyString(attribute);
   4532               switch (*keyword)
   4533               {
   4534                 case 'C':
   4535                 case 'c':
   4536                 {
   4537                   if (LocaleCompare(keyword,"colors") == 0)
   4538                     {
   4539                       quantize_info.number_colors=StringToLong(value);
   4540                       break;
   4541                     }
   4542                   if (LocaleCompare(keyword,"colorspace") == 0)
   4543                     {
   4544                       option=ParseCommandOption(MagickColorspaceOptions,
   4545                         MagickFalse,value);
   4546                       if (option < 0)
   4547                         ThrowMSLException(OptionError,
   4548                           "UnrecognizedColorspaceType",value);
   4549                       quantize_info.colorspace=(ColorspaceType) option;
   4550                       break;
   4551                     }
   4552                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   4553                     keyword);
   4554                   break;
   4555                 }
   4556                 case 'D':
   4557                 case 'd':
   4558                 {
   4559                   if (LocaleCompare(keyword,"dither") == 0)
   4560                     {
   4561                       option=ParseCommandOption(MagickDitherOptions,MagickFalse,
   4562                         value);
   4563                       if (option < 0)
   4564                         ThrowMSLException(OptionError,"UnrecognizedBooleanType",
   4565                           value);
   4566                       quantize_info.dither_method=(DitherMethod) option;
   4567                       break;
   4568                     }
   4569                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   4570                     keyword);
   4571                   break;
   4572                 }
   4573                 case 'M':
   4574                 case 'm':
   4575                 {
   4576                   if (LocaleCompare(keyword,"measure") == 0)
   4577                     {
   4578                       option=ParseCommandOption(MagickBooleanOptions,
   4579                         MagickFalse,value);
   4580                       if (option < 0)
   4581                         ThrowMSLException(OptionError,"UnrecognizedBooleanType",
   4582                           value);
   4583                       quantize_info.measure_error=(MagickBooleanType) option;
   4584                       break;
   4585                     }
   4586                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   4587                     keyword);
   4588                   break;
   4589                 }
   4590                 case 'T':
   4591                 case 't':
   4592                 {
   4593                   if (LocaleCompare(keyword,"treedepth") == 0)
   4594                     {
   4595                       quantize_info.tree_depth=StringToLong(value);
   4596                       break;
   4597                     }
   4598                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   4599                     keyword);
   4600                   break;
   4601                 }
   4602                 default:
   4603                 {
   4604                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   4605                     keyword);
   4606                   break;
   4607                 }
   4608               }
   4609             }
   4610           (void) QuantizeImage(&quantize_info,msl_info->image[n],exception);
   4611           break;
   4612         }
   4613       if (LocaleCompare((const char *) tag,"query-font-metrics") == 0)
   4614         {
   4615           char
   4616             text[MagickPathExtent];
   4617 
   4618           MagickBooleanType
   4619             status;
   4620 
   4621           TypeMetric
   4622             metrics;
   4623 
   4624           /*
   4625             Query font metrics.
   4626           */
   4627           draw_info=CloneDrawInfo(msl_info->image_info[n],
   4628             msl_info->draw_info[n]);
   4629           angle=0.0;
   4630           current=draw_info->affine;
   4631           GetAffineMatrix(&affine);
   4632           if (attributes != (const xmlChar **) NULL)
   4633             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   4634             {
   4635               keyword=(const char *) attributes[i++];
   4636               attribute=InterpretImageProperties(msl_info->image_info[n],
   4637                 msl_info->attributes[n],(const char *) attributes[i],
   4638                 exception);
   4639               CloneString(&value,attribute);
   4640               attribute=DestroyString(attribute);
   4641               switch (*keyword)
   4642               {
   4643                 case 'A':
   4644                 case 'a':
   4645                 {
   4646                   if (LocaleCompare(keyword,"affine") == 0)
   4647                     {
   4648                       char
   4649                         *p;
   4650 
   4651                       p=value;
   4652                       draw_info->affine.sx=StringToDouble(p,&p);
   4653                       if (*p ==',')
   4654                         p++;
   4655                       draw_info->affine.rx=StringToDouble(p,&p);
   4656                       if (*p ==',')
   4657                         p++;
   4658                       draw_info->affine.ry=StringToDouble(p,&p);
   4659                       if (*p ==',')
   4660                         p++;
   4661                       draw_info->affine.sy=StringToDouble(p,&p);
   4662                       if (*p ==',')
   4663                         p++;
   4664                       draw_info->affine.tx=StringToDouble(p,&p);
   4665                       if (*p ==',')
   4666                         p++;
   4667                       draw_info->affine.ty=StringToDouble(p,&p);
   4668                       break;
   4669                     }
   4670                   if (LocaleCompare(keyword,"align") == 0)
   4671                     {
   4672                       option=ParseCommandOption(MagickAlignOptions,MagickFalse,
   4673                         value);
   4674                       if (option < 0)
   4675                         ThrowMSLException(OptionError,"UnrecognizedAlignType",
   4676                           value);
   4677                       draw_info->align=(AlignType) option;
   4678                       break;
   4679                     }
   4680                   if (LocaleCompare(keyword,"antialias") == 0)
   4681                     {
   4682                       option=ParseCommandOption(MagickBooleanOptions,
   4683                         MagickFalse,value);
   4684                       if (option < 0)
   4685                         ThrowMSLException(OptionError,"UnrecognizedBooleanType",
   4686                           value);
   4687                       draw_info->stroke_antialias=(MagickBooleanType) option;
   4688                       draw_info->text_antialias=(MagickBooleanType) option;
   4689                       break;
   4690                     }
   4691                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   4692                     keyword);
   4693                   break;
   4694                 }
   4695                 case 'D':
   4696                 case 'd':
   4697                 {
   4698                   if (LocaleCompare(keyword,"density") == 0)
   4699                     {
   4700                       CloneString(&draw_info->density,value);
   4701                       break;
   4702                     }
   4703                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   4704                     keyword);
   4705                   break;
   4706                 }
   4707                 case 'E':
   4708                 case 'e':
   4709                 {
   4710                   if (LocaleCompare(keyword,"encoding") == 0)
   4711                     {
   4712                       CloneString(&draw_info->encoding,value);
   4713                       break;
   4714                     }
   4715                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   4716                     keyword);
   4717                   break;
   4718                 }
   4719                 case 'F':
   4720                 case 'f':
   4721                 {
   4722                   if (LocaleCompare(keyword, "fill") == 0)
   4723                     {
   4724                       (void) QueryColorCompliance(value,AllCompliance,
   4725                         &draw_info->fill,exception);
   4726                       break;
   4727                     }
   4728                   if (LocaleCompare(keyword,"family") == 0)
   4729                     {
   4730                       CloneString(&draw_info->family,value);
   4731                       break;
   4732                     }
   4733                   if (LocaleCompare(keyword,"font") == 0)
   4734                     {
   4735                       CloneString(&draw_info->font,value);
   4736                       break;
   4737                     }
   4738                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   4739                     keyword);
   4740                   break;
   4741                 }
   4742                 case 'G':
   4743                 case 'g':
   4744                 {
   4745                   if (LocaleCompare(keyword,"geometry") == 0)
   4746                     {
   4747                       flags=ParsePageGeometry(msl_info->image[n],value,
   4748                         &geometry,exception);
   4749                       if ((flags & HeightValue) == 0)
   4750                         geometry.height=geometry.width;
   4751                       break;
   4752                     }
   4753                   if (LocaleCompare(keyword,"gravity") == 0)
   4754                     {
   4755                       option=ParseCommandOption(MagickGravityOptions,
   4756                         MagickFalse,value);
   4757                       if (option < 0)
   4758                         ThrowMSLException(OptionError,"UnrecognizedGravityType",
   4759                           value);
   4760                       draw_info->gravity=(GravityType) option;
   4761                       break;
   4762                     }
   4763                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   4764                     keyword);
   4765                   break;
   4766                 }
   4767                 case 'P':
   4768                 case 'p':
   4769                 {
   4770                   if (LocaleCompare(keyword,"pointsize") == 0)
   4771                     {
   4772                       draw_info->pointsize=StringToDouble(value,
   4773                         (char **) NULL);
   4774                       break;
   4775                     }
   4776                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   4777                     keyword);
   4778                   break;
   4779                 }
   4780                 case 'R':
   4781                 case 'r':
   4782                 {
   4783                   if (LocaleCompare(keyword,"rotate") == 0)
   4784                     {
   4785                       angle=StringToDouble(value,(char **) NULL);
   4786                       affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
   4787                       affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
   4788                       affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
   4789                       affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
   4790                       break;
   4791                     }
   4792                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   4793                     keyword);
   4794                   break;
   4795                 }
   4796                 case 'S':
   4797                 case 's':
   4798                 {
   4799                   if (LocaleCompare(keyword,"scale") == 0)
   4800                     {
   4801                       flags=ParseGeometry(value,&geometry_info);
   4802                       if ((flags & SigmaValue) == 0)
   4803                         geometry_info.sigma=1.0;
   4804                       affine.sx=geometry_info.rho;
   4805                       affine.sy=geometry_info.sigma;
   4806                       break;
   4807                     }
   4808                   if (LocaleCompare(keyword,"skewX") == 0)
   4809                     {
   4810                       angle=StringToDouble(value,(char **) NULL);
   4811                       affine.ry=cos(DegreesToRadians(fmod(angle,360.0)));
   4812                       break;
   4813                     }
   4814                   if (LocaleCompare(keyword,"skewY") == 0)
   4815                     {
   4816                       angle=StringToDouble(value,(char **) NULL);
   4817                       affine.rx=cos(DegreesToRadians(fmod(angle,360.0)));
   4818                       break;
   4819                     }
   4820                   if (LocaleCompare(keyword,"stretch") == 0)
   4821                     {
   4822                       option=ParseCommandOption(MagickStretchOptions,
   4823                         MagickFalse,value);
   4824                       if (option < 0)
   4825                         ThrowMSLException(OptionError,"UnrecognizedStretchType",
   4826                           value);
   4827                       draw_info->stretch=(StretchType) option;
   4828                       break;
   4829                     }
   4830                   if (LocaleCompare(keyword, "stroke") == 0)
   4831                     {
   4832                       (void) QueryColorCompliance(value,AllCompliance,
   4833                         &draw_info->stroke,exception);
   4834                       break;
   4835                     }
   4836                   if (LocaleCompare(keyword,"strokewidth") == 0)
   4837                     {
   4838                       draw_info->stroke_width=StringToLong(value);
   4839                       break;
   4840                     }
   4841                   if (LocaleCompare(keyword,"style") == 0)
   4842                     {
   4843                       option=ParseCommandOption(MagickStyleOptions,MagickFalse,
   4844                         value);
   4845                       if (option < 0)
   4846                         ThrowMSLException(OptionError,"UnrecognizedStyleType",
   4847                           value);
   4848                       draw_info->style=(StyleType) option;
   4849                       break;
   4850                     }
   4851                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   4852                     keyword);
   4853                   break;
   4854                 }
   4855                 case 'T':
   4856                 case 't':
   4857                 {
   4858                   if (LocaleCompare(keyword,"text") == 0)
   4859                     {
   4860                       CloneString(&draw_info->text,value);
   4861                       break;
   4862                     }
   4863                   if (LocaleCompare(keyword,"translate") == 0)
   4864                     {
   4865                       flags=ParseGeometry(value,&geometry_info);
   4866                       if ((flags & SigmaValue) == 0)
   4867                         geometry_info.sigma=1.0;
   4868                       affine.tx=geometry_info.rho;
   4869                       affine.ty=geometry_info.sigma;
   4870                       break;
   4871                     }
   4872                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   4873                     keyword);
   4874                   break;
   4875                 }
   4876                 case 'U':
   4877                 case 'u':
   4878                 {
   4879                   if (LocaleCompare(keyword, "undercolor") == 0)
   4880                     {
   4881                       (void) QueryColorCompliance(value,AllCompliance,
   4882                         &draw_info->undercolor,exception);
   4883                       break;
   4884                     }
   4885                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   4886                     keyword);
   4887                   break;
   4888                 }
   4889                 case 'W':
   4890                 case 'w':
   4891                 {
   4892                   if (LocaleCompare(keyword,"weight") == 0)
   4893                     {
   4894                       draw_info->weight=StringToLong(value);
   4895                       break;
   4896                     }
   4897                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   4898                     keyword);
   4899                   break;
   4900                 }
   4901                 case 'X':
   4902                 case 'x':
   4903                 {
   4904                   if (LocaleCompare(keyword,"x") == 0)
   4905                     {
   4906                       geometry.x=StringToLong(value);
   4907                       break;
   4908                     }
   4909                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   4910                     keyword);
   4911                   break;
   4912                 }
   4913                 case 'Y':
   4914                 case 'y':
   4915                 {
   4916                   if (LocaleCompare(keyword,"y") == 0)
   4917                     {
   4918                       geometry.y=StringToLong(value);
   4919                       break;
   4920                     }
   4921                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   4922                     keyword);
   4923                   break;
   4924                 }
   4925                 default:
   4926                 {
   4927                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   4928                     keyword);
   4929                   break;
   4930                 }
   4931               }
   4932             }
   4933           (void) FormatLocaleString(text,MagickPathExtent,
   4934             "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,(double)
   4935             geometry.height,(double) geometry.x,(double) geometry.y);
   4936           CloneString(&draw_info->geometry,text);
   4937           draw_info->affine.sx=affine.sx*current.sx+affine.ry*current.rx;
   4938           draw_info->affine.rx=affine.rx*current.sx+affine.sy*current.rx;
   4939           draw_info->affine.ry=affine.sx*current.ry+affine.ry*current.sy;
   4940           draw_info->affine.sy=affine.rx*current.ry+affine.sy*current.sy;
   4941           draw_info->affine.tx=affine.sx*current.tx+affine.ry*current.ty+
   4942             affine.tx;
   4943           draw_info->affine.ty=affine.rx*current.tx+affine.sy*current.ty+
   4944             affine.ty;
   4945           status=GetTypeMetrics(msl_info->attributes[n],draw_info,&metrics,
   4946             msl_info->exception);
   4947           if (status != MagickFalse)
   4948             {
   4949               Image
   4950                 *image;
   4951 
   4952               image=msl_info->attributes[n];
   4953               FormatImageProperty(image,"msl:font-metrics.pixels_per_em.x",
   4954                 "%g",metrics.pixels_per_em.x);
   4955               FormatImageProperty(image,"msl:font-metrics.pixels_per_em.y",
   4956                 "%g",metrics.pixels_per_em.y);
   4957               FormatImageProperty(image,"msl:font-metrics.ascent","%g",
   4958                 metrics.ascent);
   4959               FormatImageProperty(image,"msl:font-metrics.descent","%g",
   4960                 metrics.descent);
   4961               FormatImageProperty(image,"msl:font-metrics.width","%g",
   4962                 metrics.width);
   4963               FormatImageProperty(image,"msl:font-metrics.height","%g",
   4964                 metrics.height);
   4965               FormatImageProperty(image,"msl:font-metrics.max_advance","%g",
   4966                 metrics.max_advance);
   4967               FormatImageProperty(image,"msl:font-metrics.bounds.x1","%g",
   4968                 metrics.bounds.x1);
   4969               FormatImageProperty(image,"msl:font-metrics.bounds.y1","%g",
   4970                 metrics.bounds.y1);
   4971               FormatImageProperty(image,"msl:font-metrics.bounds.x2","%g",
   4972                 metrics.bounds.x2);
   4973               FormatImageProperty(image,"msl:font-metrics.bounds.y2","%g",
   4974                 metrics.bounds.y2);
   4975               FormatImageProperty(image,"msl:font-metrics.origin.x","%g",
   4976                 metrics.origin.x);
   4977               FormatImageProperty(image,"msl:font-metrics.origin.y","%g",
   4978                 metrics.origin.y);
   4979             }
   4980           draw_info=DestroyDrawInfo(draw_info);
   4981           break;
   4982         }
   4983       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
   4984     }
   4985     case 'R':
   4986     case 'r':
   4987     {
   4988       if (LocaleCompare((const char *) tag,"raise") == 0)
   4989         {
   4990           MagickBooleanType
   4991             raise;
   4992 
   4993           /*
   4994             Raise image.
   4995           */
   4996           if (msl_info->image[n] == (Image *) NULL)
   4997             {
   4998               ThrowMSLException(OptionError,"NoImagesDefined",
   4999                 (const char *) tag);
   5000               break;
   5001             }
   5002           raise=MagickFalse;
   5003           SetGeometry(msl_info->image[n],&geometry);
   5004           if (attributes != (const xmlChar **) NULL)
   5005             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   5006             {
   5007               keyword=(const char *) attributes[i++];
   5008               attribute=InterpretImageProperties(msl_info->image_info[n],
   5009                 msl_info->attributes[n],(const char *) attributes[i],
   5010                 exception);
   5011               CloneString(&value,attribute);
   5012               attribute=DestroyString(attribute);
   5013               switch (*keyword)
   5014               {
   5015                 case 'G':
   5016                 case 'g':
   5017                 {
   5018                   if (LocaleCompare(keyword,"geometry") == 0)
   5019                     {
   5020                       flags=ParsePageGeometry(msl_info->image[n],value,
   5021                         &geometry,exception);
   5022                       if ((flags & HeightValue) == 0)
   5023                         geometry.height=geometry.width;
   5024                       break;
   5025                     }
   5026                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   5027                     keyword);
   5028                   break;
   5029                 }
   5030                 case 'H':
   5031                 case 'h':
   5032                 {
   5033                   if (LocaleCompare(keyword,"height") == 0)
   5034                     {
   5035                       geometry.height=StringToLong(value);
   5036                       break;
   5037                     }
   5038                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   5039                     keyword);
   5040                   break;
   5041                 }
   5042                 case 'R':
   5043                 case 'r':
   5044                 {
   5045                   if (LocaleCompare(keyword,"raise") == 0)
   5046                     {
   5047                       option=ParseCommandOption(MagickBooleanOptions,
   5048                         MagickFalse,value);
   5049                       if (option < 0)
   5050                         ThrowMSLException(OptionError,"UnrecognizedNoiseType",
   5051                           value);
   5052                       raise=(MagickBooleanType) option;
   5053                       break;
   5054                     }
   5055                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   5056                     keyword);
   5057                   break;
   5058                 }
   5059                 case 'W':
   5060                 case 'w':
   5061                 {
   5062                   if (LocaleCompare(keyword,"width") == 0)
   5063                     {
   5064                       geometry.width=StringToLong(value);
   5065                       break;
   5066                     }
   5067                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   5068                     keyword);
   5069                   break;
   5070                 }
   5071                 default:
   5072                 {
   5073                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   5074                     keyword);
   5075                   break;
   5076                 }
   5077               }
   5078             }
   5079           (void) RaiseImage(msl_info->image[n],&geometry,raise,
   5080             msl_info->exception);
   5081           break;
   5082         }
   5083       if (LocaleCompare((const char *) tag,"read") == 0)
   5084         {
   5085           if (attributes == (const xmlChar **) NULL)
   5086             break;
   5087           for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   5088           {
   5089             keyword=(const char *) attributes[i++];
   5090             attribute=InterpretImageProperties(msl_info->image_info[n],
   5091               msl_info->attributes[n],(const char *) attributes[i],exception);
   5092             CloneString(&value,attribute);
   5093             attribute=DestroyString(attribute);
   5094             switch (*keyword)
   5095             {
   5096               case 'F':
   5097               case 'f':
   5098               {
   5099                 if (LocaleCompare(keyword,"filename") == 0)
   5100                   {
   5101                     Image
   5102                       *image;
   5103 
   5104                     if (value == (char *) NULL)
   5105                       break;
   5106                     (void) CopyMagickString(msl_info->image_info[n]->filename,
   5107                       value,MagickPathExtent);
   5108                     image=ReadImage(msl_info->image_info[n],exception);
   5109                     CatchException(exception);
   5110                     if (image == (Image *) NULL)
   5111                       continue;
   5112                     AppendImageToList(&msl_info->image[n],image);
   5113                     break;
   5114                   }
   5115                 (void) SetMSLAttributes(msl_info,keyword,value);
   5116                 break;
   5117               }
   5118               default:
   5119               {
   5120                 (void) SetMSLAttributes(msl_info,keyword,value);
   5121                 break;
   5122               }
   5123             }
   5124           }
   5125           break;
   5126         }
   5127       if (LocaleCompare((const char *) tag,"reduce-noise") == 0)
   5128         {
   5129           Image
   5130             *paint_image;
   5131 
   5132           /*
   5133             Reduce-noise image.
   5134           */
   5135           if (msl_info->image[n] == (Image *) NULL)
   5136             {
   5137               ThrowMSLException(OptionError,"NoImagesDefined",
   5138                 (const char *) tag);
   5139               break;
   5140             }
   5141           if (attributes != (const xmlChar **) NULL)
   5142             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   5143             {
   5144               keyword=(const char *) attributes[i++];
   5145               attribute=InterpretImageProperties(msl_info->image_info[n],
   5146                 msl_info->attributes[n],(const char *) attributes[i],
   5147                 exception);
   5148               CloneString(&value,attribute);
   5149               attribute=DestroyString(attribute);
   5150               switch (*keyword)
   5151               {
   5152                 case 'G':
   5153                 case 'g':
   5154                 {
   5155                   if (LocaleCompare(keyword,"geometry") == 0)
   5156                     {
   5157                       flags=ParseGeometry(value,&geometry_info);
   5158                       if ((flags & SigmaValue) == 0)
   5159                         geometry_info.sigma=1.0;
   5160                       break;
   5161                     }
   5162                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   5163                     keyword);
   5164                   break;
   5165                 }
   5166                 case 'R':
   5167                 case 'r':
   5168                 {
   5169                   if (LocaleCompare(keyword,"radius") == 0)
   5170                     {
   5171                       geometry_info.rho=StringToDouble(value,
   5172                         (char **) NULL);
   5173                       break;
   5174                     }
   5175                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   5176                     keyword);
   5177                   break;
   5178                 }
   5179                 default:
   5180                 {
   5181                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   5182                     keyword);
   5183                   break;
   5184                 }
   5185               }
   5186             }
   5187           paint_image=StatisticImage(msl_info->image[n],NonpeakStatistic,
   5188             (size_t) geometry_info.rho,(size_t) geometry_info.sigma,
   5189             msl_info->exception);
   5190           if (paint_image == (Image *) NULL)
   5191             break;
   5192           msl_info->image[n]=DestroyImage(msl_info->image[n]);
   5193           msl_info->image[n]=paint_image;
   5194           break;
   5195         }
   5196       else if (LocaleCompare((const char *) tag,"repage") == 0)
   5197       {
   5198         /* init the values */
   5199         width=msl_info->image[n]->page.width;
   5200         height=msl_info->image[n]->page.height;
   5201         x=msl_info->image[n]->page.x;
   5202         y=msl_info->image[n]->page.y;
   5203 
   5204         if (msl_info->image[n] == (Image *) NULL)
   5205         {
   5206           ThrowMSLException(OptionError,"NoImagesDefined",
   5207             (const char *) tag);
   5208           break;
   5209         }
   5210         if (attributes == (const xmlChar **) NULL)
   5211         break;
   5212         for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   5213         {
   5214           keyword=(const char *) attributes[i++];
   5215           attribute=InterpretImageProperties(msl_info->image_info[n],
   5216             msl_info->attributes[n],(const char *) attributes[i],exception);
   5217           CloneString(&value,attribute);
   5218           attribute=DestroyString(attribute);
   5219         switch (*keyword)
   5220         {
   5221           case 'G':
   5222           case 'g':
   5223           {
   5224           if (LocaleCompare(keyword,"geometry") == 0)
   5225             {
   5226               int
   5227                 flags;
   5228 
   5229               RectangleInfo
   5230                 geometry;
   5231 
   5232             flags=ParseAbsoluteGeometry(value,&geometry);
   5233             if ((flags & WidthValue) != 0)
   5234               {
   5235                 if ((flags & HeightValue) == 0)
   5236                   geometry.height=geometry.width;
   5237                 width=geometry.width;
   5238                 height=geometry.height;
   5239               }
   5240             if ((flags & AspectValue) != 0)
   5241               {
   5242                 if ((flags & XValue) != 0)
   5243                   x+=geometry.x;
   5244                 if ((flags & YValue) != 0)
   5245                   y+=geometry.y;
   5246               }
   5247             else
   5248               {
   5249                 if ((flags & XValue) != 0)
   5250                   {
   5251                     x=geometry.x;
   5252                     if ((width == 0) && (geometry.x > 0))
   5253                       width=msl_info->image[n]->columns+geometry.x;
   5254                   }
   5255                 if ((flags & YValue) != 0)
   5256                   {
   5257                     y=geometry.y;
   5258                     if ((height == 0) && (geometry.y > 0))
   5259                       height=msl_info->image[n]->rows+geometry.y;
   5260                   }
   5261               }
   5262             break;
   5263             }
   5264           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   5265           break;
   5266           }
   5267           case 'H':
   5268           case 'h':
   5269           {
   5270           if (LocaleCompare(keyword,"height") == 0)
   5271             {
   5272             height = StringToLong( value );
   5273             break;
   5274             }
   5275           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   5276           break;
   5277           }
   5278           case 'W':
   5279           case 'w':
   5280           {
   5281           if (LocaleCompare(keyword,"width") == 0)
   5282             {
   5283             width = StringToLong( value );
   5284             break;
   5285             }
   5286           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   5287           break;
   5288           }
   5289           case 'X':
   5290           case 'x':
   5291           {
   5292           if (LocaleCompare(keyword,"x") == 0)
   5293             {
   5294             x = StringToLong( value );
   5295             break;
   5296             }
   5297           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   5298           break;
   5299           }
   5300           case 'Y':
   5301           case 'y':
   5302           {
   5303           if (LocaleCompare(keyword,"y") == 0)
   5304             {
   5305             y = StringToLong( value );
   5306             break;
   5307             }
   5308           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   5309           break;
   5310           }
   5311           default:
   5312           {
   5313           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   5314           break;
   5315           }
   5316         }
   5317         }
   5318 
   5319          msl_info->image[n]->page.width=width;
   5320          msl_info->image[n]->page.height=height;
   5321          msl_info->image[n]->page.x=x;
   5322          msl_info->image[n]->page.y=y;
   5323         break;
   5324       }
   5325     else if (LocaleCompare((const char *) tag,"resample") == 0)
   5326     {
   5327       double
   5328         x_resolution,
   5329         y_resolution;
   5330 
   5331       if (msl_info->image[n] == (Image *) NULL)
   5332         {
   5333           ThrowMSLException(OptionError,"NoImagesDefined",
   5334             (const char *) tag);
   5335           break;
   5336         }
   5337       if (attributes == (const xmlChar **) NULL)
   5338         break;
   5339       x_resolution=DefaultResolution;
   5340       y_resolution=DefaultResolution;
   5341       for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   5342       {
   5343         keyword=(const char *) attributes[i++];
   5344         attribute=InterpretImageProperties(msl_info->image_info[n],
   5345           msl_info->attributes[n],(const char *) attributes[i],exception);
   5346         CloneString(&value,attribute);
   5347         attribute=DestroyString(attribute);
   5348         switch (*keyword)
   5349         {
   5350           case 'G':
   5351           case 'g':
   5352           {
   5353             if (LocaleCompare(keyword,"geometry") == 0)
   5354               {
   5355                 ssize_t
   5356                   flags;
   5357 
   5358                 flags=ParseGeometry(value,&geometry_info);
   5359                 if ((flags & SigmaValue) == 0)
   5360                   geometry_info.sigma*=geometry_info.rho;
   5361                 x_resolution=geometry_info.rho;
   5362                 y_resolution=geometry_info.sigma;
   5363                 break;
   5364               }
   5365             ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   5366             break;
   5367           }
   5368           case 'X':
   5369           case 'x':
   5370           {
   5371             if (LocaleCompare(keyword,"x-resolution") == 0)
   5372               {
   5373                 x_resolution=StringToDouble(value,(char **) NULL);
   5374                 break;
   5375               }
   5376             ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   5377             break;
   5378           }
   5379           case 'Y':
   5380           case 'y':
   5381           {
   5382             if (LocaleCompare(keyword,"y-resolution") == 0)
   5383               {
   5384                 y_resolution=StringToDouble(value,(char **) NULL);
   5385                 break;
   5386               }
   5387             ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   5388             break;
   5389           }
   5390           default:
   5391           {
   5392             ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   5393             break;
   5394           }
   5395         }
   5396       }
   5397       /*
   5398         Resample image.
   5399       */
   5400       {
   5401         double
   5402           factor;
   5403 
   5404         Image
   5405           *resample_image;
   5406 
   5407         factor=1.0;
   5408         if (msl_info->image[n]->units == PixelsPerCentimeterResolution)
   5409           factor=2.54;
   5410         width=(size_t) (x_resolution*msl_info->image[n]->columns/
   5411           (factor*(msl_info->image[n]->resolution.x == 0.0 ? DefaultResolution :
   5412           msl_info->image[n]->resolution.x))+0.5);
   5413         height=(size_t) (y_resolution*msl_info->image[n]->rows/
   5414           (factor*(msl_info->image[n]->resolution.y == 0.0 ? DefaultResolution :
   5415           msl_info->image[n]->resolution.y))+0.5);
   5416         resample_image=ResizeImage(msl_info->image[n],width,height,
   5417           msl_info->image[n]->filter,msl_info->exception);
   5418         if (resample_image == (Image *) NULL)
   5419           break;
   5420         msl_info->image[n]=DestroyImage(msl_info->image[n]);
   5421         msl_info->image[n]=resample_image;
   5422       }
   5423       break;
   5424     }
   5425       if (LocaleCompare((const char *) tag,"resize") == 0)
   5426         {
   5427           FilterType
   5428             filter;
   5429 
   5430           Image
   5431             *resize_image;
   5432 
   5433           /*
   5434             Resize image.
   5435           */
   5436           if (msl_info->image[n] == (Image *) NULL)
   5437             {
   5438               ThrowMSLException(OptionError,"NoImagesDefined",
   5439                 (const char *) tag);
   5440               break;
   5441             }
   5442           filter=UndefinedFilter;
   5443           if (attributes != (const xmlChar **) NULL)
   5444             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   5445             {
   5446               keyword=(const char *) attributes[i++];
   5447               attribute=InterpretImageProperties(msl_info->image_info[n],
   5448                 msl_info->attributes[n],(const char *) attributes[i],
   5449                 exception);
   5450               CloneString(&value,attribute);
   5451               attribute=DestroyString(attribute);
   5452               switch (*keyword)
   5453               {
   5454                 case 'F':
   5455                 case 'f':
   5456                 {
   5457                   if (LocaleCompare(keyword,"filter") == 0)
   5458                     {
   5459                       option=ParseCommandOption(MagickFilterOptions,MagickFalse,
   5460                         value);
   5461                       if (option < 0)
   5462                         ThrowMSLException(OptionError,"UnrecognizedNoiseType",
   5463                           value);
   5464                       filter=(FilterType) option;
   5465                       break;
   5466                     }
   5467                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   5468                     keyword);
   5469                   break;
   5470                 }
   5471                 case 'G':
   5472                 case 'g':
   5473                 {
   5474                   if (LocaleCompare(keyword,"geometry") == 0)
   5475                     {
   5476                       flags=ParseRegionGeometry(msl_info->image[n],value,
   5477                         &geometry,exception);
   5478                       break;
   5479                     }
   5480                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   5481                     keyword);
   5482                   break;
   5483                 }
   5484                 case 'H':
   5485                 case 'h':
   5486                 {
   5487                   if (LocaleCompare(keyword,"height") == 0)
   5488                     {
   5489                       geometry.height=StringToUnsignedLong(value);
   5490                       break;
   5491                     }
   5492                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   5493                     keyword);
   5494                   break;
   5495                 }
   5496                 case 'W':
   5497                 case 'w':
   5498                 {
   5499                   if (LocaleCompare(keyword,"width") == 0)
   5500                     {
   5501                       geometry.width=StringToLong(value);
   5502                       break;
   5503                     }
   5504                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   5505                     keyword);
   5506                   break;
   5507                 }
   5508                 default:
   5509                 {
   5510                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   5511                     keyword);
   5512                   break;
   5513                 }
   5514               }
   5515             }
   5516           resize_image=ResizeImage(msl_info->image[n],geometry.width,
   5517             geometry.height,filter,msl_info->exception);
   5518           if (resize_image == (Image *) NULL)
   5519             break;
   5520           msl_info->image[n]=DestroyImage(msl_info->image[n]);
   5521           msl_info->image[n]=resize_image;
   5522           break;
   5523         }
   5524       if (LocaleCompare((const char *) tag,"roll") == 0)
   5525         {
   5526           Image
   5527             *roll_image;
   5528 
   5529           /*
   5530             Roll image.
   5531           */
   5532           if (msl_info->image[n] == (Image *) NULL)
   5533             {
   5534               ThrowMSLException(OptionError,"NoImagesDefined",
   5535                 (const char *) tag);
   5536               break;
   5537             }
   5538           SetGeometry(msl_info->image[n],&geometry);
   5539           if (attributes != (const xmlChar **) NULL)
   5540             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   5541             {
   5542               keyword=(const char *) attributes[i++];
   5543               attribute=InterpretImageProperties(msl_info->image_info[n],
   5544                 msl_info->attributes[n],(const char *) attributes[i],
   5545                 exception);
   5546               CloneString(&value,attribute);
   5547               attribute=DestroyString(attribute);
   5548               switch (*keyword)
   5549               {
   5550                 case 'G':
   5551                 case 'g':
   5552                 {
   5553                   if (LocaleCompare(keyword,"geometry") == 0)
   5554                     {
   5555                       flags=ParsePageGeometry(msl_info->image[n],value,
   5556                         &geometry,exception);
   5557                       if ((flags & HeightValue) == 0)
   5558                         geometry.height=geometry.width;
   5559                       break;
   5560                     }
   5561                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   5562                     keyword);
   5563                   break;
   5564                 }
   5565                 case 'X':
   5566                 case 'x':
   5567                 {
   5568                   if (LocaleCompare(keyword,"x") == 0)
   5569                     {
   5570                       geometry.x=StringToLong(value);
   5571                       break;
   5572                     }
   5573                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   5574                     keyword);
   5575                   break;
   5576                 }
   5577                 case 'Y':
   5578                 case 'y':
   5579                 {
   5580                   if (LocaleCompare(keyword,"y") == 0)
   5581                     {
   5582                       geometry.y=StringToLong(value);
   5583                       break;
   5584                     }
   5585                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   5586                     keyword);
   5587                   break;
   5588                 }
   5589                 default:
   5590                 {
   5591                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   5592                     keyword);
   5593                   break;
   5594                 }
   5595               }
   5596             }
   5597           roll_image=RollImage(msl_info->image[n],geometry.x,geometry.y,
   5598             msl_info->exception);
   5599           if (roll_image == (Image *) NULL)
   5600             break;
   5601           msl_info->image[n]=DestroyImage(msl_info->image[n]);
   5602           msl_info->image[n]=roll_image;
   5603           break;
   5604         }
   5605       else if (LocaleCompare((const char *) tag,"roll") == 0)
   5606       {
   5607         /* init the values */
   5608         width=msl_info->image[n]->columns;
   5609         height=msl_info->image[n]->rows;
   5610         x = y = 0;
   5611 
   5612         if (msl_info->image[n] == (Image *) NULL)
   5613         {
   5614           ThrowMSLException(OptionError,"NoImagesDefined",
   5615             (const char *) tag);
   5616           break;
   5617         }
   5618         if (attributes == (const xmlChar **) NULL)
   5619         break;
   5620         for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   5621         {
   5622           keyword=(const char *) attributes[i++];
   5623           attribute=InterpretImageProperties(msl_info->image_info[n],
   5624             msl_info->attributes[n],(const char *) attributes[i],exception);
   5625           CloneString(&value,attribute);
   5626           attribute=DestroyString(attribute);
   5627         switch (*keyword)
   5628         {
   5629           case 'G':
   5630           case 'g':
   5631           {
   5632           if (LocaleCompare(keyword,"geometry") == 0)
   5633             {
   5634             (void) ParseMetaGeometry(value,&x,&y,&width,&height);
   5635             break;
   5636             }
   5637           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   5638           break;
   5639           }
   5640           case 'X':
   5641           case 'x':
   5642           {
   5643           if (LocaleCompare(keyword,"x") == 0)
   5644             {
   5645             x = StringToLong( value );
   5646             break;
   5647             }
   5648           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   5649           break;
   5650           }
   5651           case 'Y':
   5652           case 'y':
   5653           {
   5654           if (LocaleCompare(keyword,"y") == 0)
   5655             {
   5656             y = StringToLong( value );
   5657             break;
   5658             }
   5659           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   5660           break;
   5661           }
   5662           default:
   5663           {
   5664           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   5665           break;
   5666           }
   5667         }
   5668         }
   5669 
   5670         /*
   5671           process image.
   5672         */
   5673         {
   5674         Image
   5675           *newImage;
   5676 
   5677         newImage=RollImage(msl_info->image[n], x, y, msl_info->exception);
   5678         if (newImage == (Image *) NULL)
   5679           break;
   5680         msl_info->image[n]=DestroyImage(msl_info->image[n]);
   5681         msl_info->image[n]=newImage;
   5682         }
   5683 
   5684         break;
   5685       }
   5686       if (LocaleCompare((const char *) tag,"rotate") == 0)
   5687         {
   5688           Image
   5689             *rotate_image;
   5690 
   5691           /*
   5692             Rotate image.
   5693           */
   5694           if (msl_info->image[n] == (Image *) NULL)
   5695             {
   5696               ThrowMSLException(OptionError,"NoImagesDefined",
   5697                 (const char *) tag);
   5698               break;
   5699             }
   5700           if (attributes != (const xmlChar **) NULL)
   5701             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   5702             {
   5703               keyword=(const char *) attributes[i++];
   5704               attribute=InterpretImageProperties(msl_info->image_info[n],
   5705                 msl_info->attributes[n],(const char *) attributes[i],
   5706                 exception);
   5707               CloneString(&value,attribute);
   5708               attribute=DestroyString(attribute);
   5709               switch (*keyword)
   5710               {
   5711                 case 'D':
   5712                 case 'd':
   5713                 {
   5714                   if (LocaleCompare(keyword,"degrees") == 0)
   5715                     {
   5716                       geometry_info.rho=StringToDouble(value,
   5717                         (char **) NULL);
   5718                       break;
   5719                     }
   5720                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   5721                     keyword);
   5722                   break;
   5723                 }
   5724                 case 'G':
   5725                 case 'g':
   5726                 {
   5727                   if (LocaleCompare(keyword,"geometry") == 0)
   5728                     {
   5729                       flags=ParseGeometry(value,&geometry_info);
   5730                       if ((flags & SigmaValue) == 0)
   5731                         geometry_info.sigma=1.0;
   5732                       break;
   5733                     }
   5734                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   5735                     keyword);
   5736                   break;
   5737                 }
   5738                 default:
   5739                 {
   5740                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   5741                     keyword);
   5742                   break;
   5743                 }
   5744               }
   5745             }
   5746           rotate_image=RotateImage(msl_info->image[n],geometry_info.rho,
   5747             msl_info->exception);
   5748           if (rotate_image == (Image *) NULL)
   5749             break;
   5750           msl_info->image[n]=DestroyImage(msl_info->image[n]);
   5751           msl_info->image[n]=rotate_image;
   5752           break;
   5753         }
   5754       else if (LocaleCompare((const char *) tag,"rotate") == 0)
   5755       {
   5756         /* init the values */
   5757         double  degrees = 0;
   5758 
   5759         if (msl_info->image[n] == (Image *) NULL)
   5760         {
   5761           ThrowMSLException(OptionError,"NoImagesDefined",
   5762             (const char *) tag);
   5763           break;
   5764         }
   5765         if (attributes == (const xmlChar **) NULL)
   5766           break;
   5767         for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   5768         {
   5769           keyword=(const char *) attributes[i++];
   5770           attribute=InterpretImageProperties(msl_info->image_info[n],
   5771             msl_info->attributes[n],(const char *) attributes[i],exception);
   5772           CloneString(&value,attribute);
   5773           attribute=DestroyString(attribute);
   5774         switch (*keyword)
   5775         {
   5776           case 'D':
   5777           case 'd':
   5778           {
   5779           if (LocaleCompare(keyword,"degrees") == 0)
   5780             {
   5781             degrees = StringToDouble(value,(char **) NULL);
   5782             break;
   5783             }
   5784           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   5785           break;
   5786           }
   5787           default:
   5788           {
   5789           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   5790           break;
   5791           }
   5792         }
   5793         }
   5794 
   5795         /*
   5796           process image.
   5797         */
   5798         {
   5799         Image
   5800           *newImage;
   5801 
   5802         newImage=RotateImage(msl_info->image[n], degrees, msl_info->exception);
   5803         if (newImage == (Image *) NULL)
   5804           break;
   5805         msl_info->image[n]=DestroyImage(msl_info->image[n]);
   5806         msl_info->image[n]=newImage;
   5807         }
   5808 
   5809         break;
   5810       }
   5811       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
   5812     }
   5813     case 'S':
   5814     case 's':
   5815     {
   5816       if (LocaleCompare((const char *) tag,"sample") == 0)
   5817         {
   5818           Image
   5819             *sample_image;
   5820 
   5821           /*
   5822             Sample image.
   5823           */
   5824           if (msl_info->image[n] == (Image *) NULL)
   5825             {
   5826               ThrowMSLException(OptionError,"NoImagesDefined",
   5827                 (const char *) tag);
   5828               break;
   5829             }
   5830           if (attributes != (const xmlChar **) NULL)
   5831             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   5832             {
   5833               keyword=(const char *) attributes[i++];
   5834               attribute=InterpretImageProperties(msl_info->image_info[n],
   5835                 msl_info->attributes[n],(const char *) attributes[i],
   5836                 exception);
   5837               CloneString(&value,attribute);
   5838               attribute=DestroyString(attribute);
   5839               switch (*keyword)
   5840               {
   5841                 case 'G':
   5842                 case 'g':
   5843                 {
   5844                   if (LocaleCompare(keyword,"geometry") == 0)
   5845                     {
   5846                       flags=ParseRegionGeometry(msl_info->image[n],value,
   5847                         &geometry,exception);
   5848                       break;
   5849                     }
   5850                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   5851                     keyword);
   5852                   break;
   5853                 }
   5854                 case 'H':
   5855                 case 'h':
   5856                 {
   5857                   if (LocaleCompare(keyword,"height") == 0)
   5858                     {
   5859                       geometry.height=StringToUnsignedLong(value);
   5860                       break;
   5861                     }
   5862                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   5863                     keyword);
   5864                   break;
   5865                 }
   5866                 case 'W':
   5867                 case 'w':
   5868                 {
   5869                   if (LocaleCompare(keyword,"width") == 0)
   5870                     {
   5871                       geometry.width=StringToLong(value);
   5872                       break;
   5873                     }
   5874                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   5875                     keyword);
   5876                   break;
   5877                 }
   5878                 default:
   5879                 {
   5880                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   5881                     keyword);
   5882                   break;
   5883                 }
   5884               }
   5885             }
   5886           sample_image=SampleImage(msl_info->image[n],geometry.width,
   5887             geometry.height,msl_info->exception);
   5888           if (sample_image == (Image *) NULL)
   5889             break;
   5890           msl_info->image[n]=DestroyImage(msl_info->image[n]);
   5891           msl_info->image[n]=sample_image;
   5892           break;
   5893         }
   5894       if (LocaleCompare((const char *) tag,"scale") == 0)
   5895         {
   5896           Image
   5897             *scale_image;
   5898 
   5899           /*
   5900             Scale image.
   5901           */
   5902           if (msl_info->image[n] == (Image *) NULL)
   5903             {
   5904               ThrowMSLException(OptionError,"NoImagesDefined",
   5905                 (const char *) tag);
   5906               break;
   5907             }
   5908           if (attributes != (const xmlChar **) NULL)
   5909             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   5910             {
   5911               keyword=(const char *) attributes[i++];
   5912               attribute=InterpretImageProperties(msl_info->image_info[n],
   5913                 msl_info->attributes[n],(const char *) attributes[i],
   5914                 exception);
   5915               CloneString(&value,attribute);
   5916               attribute=DestroyString(attribute);
   5917               switch (*keyword)
   5918               {
   5919                 case 'G':
   5920                 case 'g':
   5921                 {
   5922                   if (LocaleCompare(keyword,"geometry") == 0)
   5923                     {
   5924                       flags=ParseRegionGeometry(msl_info->image[n],value,
   5925                         &geometry,exception);
   5926                       break;
   5927                     }
   5928                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   5929                     keyword);
   5930                   break;
   5931                 }
   5932                 case 'H':
   5933                 case 'h':
   5934                 {
   5935                   if (LocaleCompare(keyword,"height") == 0)
   5936                     {
   5937                       geometry.height=StringToUnsignedLong(value);
   5938                       break;
   5939                     }
   5940                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   5941                     keyword);
   5942                   break;
   5943                 }
   5944                 case 'W':
   5945                 case 'w':
   5946                 {
   5947                   if (LocaleCompare(keyword,"width") == 0)
   5948                     {
   5949                       geometry.width=StringToLong(value);
   5950                       break;
   5951                     }
   5952                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   5953                     keyword);
   5954                   break;
   5955                 }
   5956                 default:
   5957                 {
   5958                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   5959                     keyword);
   5960                   break;
   5961                 }
   5962               }
   5963             }
   5964           scale_image=ScaleImage(msl_info->image[n],geometry.width,
   5965             geometry.height,msl_info->exception);
   5966           if (scale_image == (Image *) NULL)
   5967             break;
   5968           msl_info->image[n]=DestroyImage(msl_info->image[n]);
   5969           msl_info->image[n]=scale_image;
   5970           break;
   5971         }
   5972       if (LocaleCompare((const char *) tag,"segment") == 0)
   5973         {
   5974           ColorspaceType
   5975             colorspace;
   5976 
   5977           MagickBooleanType
   5978             verbose;
   5979 
   5980           /*
   5981             Segment image.
   5982           */
   5983           if (msl_info->image[n] == (Image *) NULL)
   5984             {
   5985               ThrowMSLException(OptionError,"NoImagesDefined",
   5986                 (const char *) tag);
   5987               break;
   5988             }
   5989           geometry_info.rho=1.0;
   5990           geometry_info.sigma=1.5;
   5991           colorspace=sRGBColorspace;
   5992           verbose=MagickFalse;
   5993           if (attributes != (const xmlChar **) NULL)
   5994             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   5995             {
   5996               keyword=(const char *) attributes[i++];
   5997               attribute=InterpretImageProperties(msl_info->image_info[n],
   5998                 msl_info->attributes[n],(const char *) attributes[i],
   5999                 exception);
   6000               CloneString(&value,attribute);
   6001               attribute=DestroyString(attribute);
   6002               switch (*keyword)
   6003               {
   6004                 case 'C':
   6005                 case 'c':
   6006                 {
   6007                   if (LocaleCompare(keyword,"cluster-threshold") == 0)
   6008                     {
   6009                       geometry_info.rho=StringToDouble(value,
   6010                         (char **) NULL);
   6011                       break;
   6012                     }
   6013                   if (LocaleCompare(keyword,"colorspace") == 0)
   6014                     {
   6015                       option=ParseCommandOption(MagickColorspaceOptions,
   6016                         MagickFalse,value);
   6017                       if (option < 0)
   6018                         ThrowMSLException(OptionError,
   6019                           "UnrecognizedColorspaceType",value);
   6020                       colorspace=(ColorspaceType) option;
   6021                       break;
   6022                     }
   6023                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   6024                     keyword);
   6025                   break;
   6026                 }
   6027                 case 'G':
   6028                 case 'g':
   6029                 {
   6030                   if (LocaleCompare(keyword,"geometry") == 0)
   6031                     {
   6032                       flags=ParseGeometry(value,&geometry_info);
   6033                       if ((flags & SigmaValue) == 0)
   6034                         geometry_info.sigma=1.5;
   6035                       break;
   6036                     }
   6037                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   6038                     keyword);
   6039                   break;
   6040                 }
   6041                 case 'S':
   6042                 case 's':
   6043                 {
   6044                   if (LocaleCompare(keyword,"smoothing-threshold") == 0)
   6045                     {
   6046                       geometry_info.sigma=StringToDouble(value,
   6047                         (char **) NULL);
   6048                       break;
   6049                     }
   6050                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   6051                     keyword);
   6052                   break;
   6053                 }
   6054                 default:
   6055                 {
   6056                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   6057                     keyword);
   6058                   break;
   6059                 }
   6060               }
   6061             }
   6062           (void) SegmentImage(msl_info->image[n],colorspace,verbose,
   6063             geometry_info.rho,geometry_info.sigma,exception);
   6064           break;
   6065         }
   6066       else if (LocaleCompare((const char *) tag, "set") == 0)
   6067       {
   6068         if (msl_info->image[n] == (Image *) NULL)
   6069         {
   6070           ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
   6071           break;
   6072         }
   6073 
   6074         if (attributes == (const xmlChar **) NULL)
   6075           break;
   6076         for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   6077         {
   6078           keyword=(const char *) attributes[i++];
   6079           attribute=InterpretImageProperties(msl_info->image_info[n],
   6080             msl_info->attributes[n],(const char *) attributes[i],exception);
   6081           CloneString(&value,attribute);
   6082           attribute=DestroyString(attribute);
   6083           switch (*keyword)
   6084           {
   6085             case 'C':
   6086             case 'c':
   6087             {
   6088               if (LocaleCompare(keyword,"clip-mask") == 0)
   6089                 {
   6090                   for (j=0; j < msl_info->n; j++)
   6091                   {
   6092                     const char
   6093                       *property;
   6094 
   6095                     property=GetImageProperty(msl_info->attributes[j],"id",
   6096                       exception);
   6097                     if (LocaleCompare(property,value) == 0)
   6098                       {
   6099                         SetImageMask(msl_info->image[n],ReadPixelMask,
   6100                           msl_info->image[j],exception);
   6101                         break;
   6102                       }
   6103                   }
   6104                   break;
   6105                 }
   6106               if (LocaleCompare(keyword,"clip-path") == 0)
   6107                 {
   6108                   for (j=0; j < msl_info->n; j++)
   6109                   {
   6110                     const char
   6111                       *property;
   6112 
   6113                     property=GetImageProperty(msl_info->attributes[j],"id",
   6114                       exception);
   6115                     if (LocaleCompare(property,value) == 0)
   6116                       {
   6117                         SetImageMask(msl_info->image[n],ReadPixelMask,
   6118                           msl_info->image[j],exception);
   6119                         break;
   6120                       }
   6121                   }
   6122                   break;
   6123                 }
   6124               if (LocaleCompare(keyword,"colorspace") == 0)
   6125                 {
   6126                   ssize_t
   6127                     colorspace;
   6128 
   6129                   colorspace=(ColorspaceType) ParseCommandOption(
   6130                     MagickColorspaceOptions,MagickFalse,value);
   6131                   if (colorspace < 0)
   6132                     ThrowMSLException(OptionError,"UnrecognizedColorspace",
   6133                       value);
   6134                   (void) TransformImageColorspace(msl_info->image[n],
   6135                     (ColorspaceType) colorspace,exception);
   6136                   break;
   6137                 }
   6138               (void) SetMSLAttributes(msl_info,keyword,value);
   6139               (void) SetImageProperty(msl_info->image[n],keyword,value,
   6140                 exception);
   6141               break;
   6142             }
   6143             case 'D':
   6144             case 'd':
   6145             {
   6146               if (LocaleCompare(keyword,"density") == 0)
   6147                 {
   6148                   flags=ParseGeometry(value,&geometry_info);
   6149                   msl_info->image[n]->resolution.x=geometry_info.rho;
   6150                   msl_info->image[n]->resolution.y=geometry_info.sigma;
   6151                   if ((flags & SigmaValue) == 0)
   6152                     msl_info->image[n]->resolution.y=
   6153                       msl_info->image[n]->resolution.x;
   6154                   break;
   6155                 }
   6156               (void) SetMSLAttributes(msl_info,keyword,value);
   6157               (void) SetImageProperty(msl_info->image[n],keyword,value,
   6158                 exception);
   6159               break;
   6160             }
   6161             case 'O':
   6162             case 'o':
   6163             {
   6164               if (LocaleCompare(keyword, "opacity") == 0)
   6165                 {
   6166                   ssize_t  opac = OpaqueAlpha,
   6167                   len = (ssize_t) strlen( value );
   6168 
   6169                   if (value[len-1] == '%') {
   6170                     char  tmp[100];
   6171                     (void) CopyMagickString(tmp,value,len);
   6172                     opac = StringToLong( tmp );
   6173                     opac = (int)(QuantumRange * ((float)opac/100));
   6174                   } else
   6175                     opac = StringToLong( value );
   6176                   (void) SetImageAlpha( msl_info->image[n], (Quantum) opac,
   6177                     exception);
   6178                   break;
   6179               }
   6180               (void) SetMSLAttributes(msl_info,keyword,value);
   6181               (void) SetImageProperty(msl_info->image[n],keyword,value,
   6182                 msl_info->exception);
   6183               break;
   6184             }
   6185             case 'P':
   6186             case 'p':
   6187             {
   6188               if (LocaleCompare(keyword, "page") == 0)
   6189               {
   6190                 char
   6191                   page[MagickPathExtent];
   6192 
   6193                 const char
   6194                   *image_option;
   6195 
   6196                 MagickStatusType
   6197                   flags;
   6198 
   6199                 RectangleInfo
   6200                   geometry;
   6201 
   6202                 (void) memset(&geometry,0,sizeof(geometry));
   6203                 image_option=GetImageArtifact(msl_info->image[n],"page");
   6204                 if (image_option != (const char *) NULL)
   6205                   flags=ParseAbsoluteGeometry(image_option,&geometry);
   6206                 flags=ParseAbsoluteGeometry(value,&geometry);
   6207                 (void) FormatLocaleString(page,MagickPathExtent,"%.20gx%.20g",
   6208                   (double) geometry.width,(double) geometry.height);
   6209                 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
   6210                   (void) FormatLocaleString(page,MagickPathExtent,
   6211                     "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,
   6212                     (double) geometry.height,(double) geometry.x,(double)
   6213                     geometry.y);
   6214                 (void) SetImageOption(msl_info->image_info[n],keyword,page);
   6215                 msl_info->image_info[n]->page=GetPageGeometry(page);
   6216                 break;
   6217               }
   6218               (void) SetMSLAttributes(msl_info,keyword,value);
   6219               (void) SetImageProperty(msl_info->image[n],keyword,value,
   6220                 msl_info->exception);
   6221               break;
   6222             }
   6223             default:
   6224             {
   6225               (void) SetMSLAttributes(msl_info,keyword,value);
   6226               (void) SetImageProperty(msl_info->image[n],keyword,value,
   6227                 msl_info->exception);
   6228               break;
   6229             }
   6230           }
   6231         }
   6232         break;
   6233       }
   6234       if (LocaleCompare((const char *) tag,"shade") == 0)
   6235         {
   6236           Image
   6237             *shade_image;
   6238 
   6239           MagickBooleanType
   6240             gray;
   6241 
   6242           /*
   6243             Shade image.
   6244           */
   6245           if (msl_info->image[n] == (Image *) NULL)
   6246             {
   6247               ThrowMSLException(OptionError,"NoImagesDefined",
   6248                 (const char *) tag);
   6249               break;
   6250             }
   6251           gray=MagickFalse;
   6252           if (attributes != (const xmlChar **) NULL)
   6253             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   6254             {
   6255               keyword=(const char *) attributes[i++];
   6256               attribute=InterpretImageProperties(msl_info->image_info[n],
   6257                 msl_info->attributes[n],(const char *) attributes[i],
   6258                 exception);
   6259               CloneString(&value,attribute);
   6260               attribute=DestroyString(attribute);
   6261               switch (*keyword)
   6262               {
   6263                 case 'A':
   6264                 case 'a':
   6265                 {
   6266                   if (LocaleCompare(keyword,"azimuth") == 0)
   6267                     {
   6268                       geometry_info.rho=StringToDouble(value,
   6269                         (char **) NULL);
   6270                       break;
   6271                     }
   6272                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   6273                     keyword);
   6274                   break;
   6275                 }
   6276                 case 'E':
   6277                 case 'e':
   6278                 {
   6279                   if (LocaleCompare(keyword,"elevation") == 0)
   6280                     {
   6281                       geometry_info.sigma=StringToDouble(value,
   6282                         (char **) NULL);
   6283                       break;
   6284                     }
   6285                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   6286                     keyword);
   6287                   break;
   6288                 }
   6289                 case 'G':
   6290                 case 'g':
   6291                 {
   6292                   if (LocaleCompare(keyword,"geometry") == 0)
   6293                     {
   6294                       flags=ParseGeometry(value,&geometry_info);
   6295                       if ((flags & SigmaValue) == 0)
   6296                         geometry_info.sigma=1.0;
   6297                       break;
   6298                     }
   6299                   if (LocaleCompare(keyword,"gray") == 0)
   6300                     {
   6301                       option=ParseCommandOption(MagickBooleanOptions,
   6302                         MagickFalse,value);
   6303                       if (option < 0)
   6304                         ThrowMSLException(OptionError,"UnrecognizedNoiseType",
   6305                           value);
   6306                       gray=(MagickBooleanType) option;
   6307                       break;
   6308                     }
   6309                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   6310                     keyword);
   6311                   break;
   6312                 }
   6313                 default:
   6314                 {
   6315                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   6316                     keyword);
   6317                   break;
   6318                 }
   6319               }
   6320             }
   6321           shade_image=ShadeImage(msl_info->image[n],gray,geometry_info.rho,
   6322             geometry_info.sigma,msl_info->exception);
   6323           if (shade_image == (Image *) NULL)
   6324             break;
   6325           msl_info->image[n]=DestroyImage(msl_info->image[n]);
   6326           msl_info->image[n]=shade_image;
   6327           break;
   6328         }
   6329       if (LocaleCompare((const char *) tag,"shadow") == 0)
   6330         {
   6331           Image
   6332             *shadow_image;
   6333 
   6334           /*
   6335             Shear image.
   6336           */
   6337           if (msl_info->image[n] == (Image *) NULL)
   6338             {
   6339               ThrowMSLException(OptionError,"NoImagesDefined",
   6340                 (const char *) tag);
   6341               break;
   6342             }
   6343           if (attributes != (const xmlChar **) NULL)
   6344             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   6345             {
   6346               keyword=(const char *) attributes[i++];
   6347               attribute=InterpretImageProperties(msl_info->image_info[n],
   6348                 msl_info->attributes[n],(const char *) attributes[i],
   6349                 exception);
   6350               CloneString(&value,attribute);
   6351               attribute=DestroyString(attribute);
   6352               switch (*keyword)
   6353               {
   6354                 case 'G':
   6355                 case 'g':
   6356                 {
   6357                   if (LocaleCompare(keyword,"geometry") == 0)
   6358                     {
   6359                       flags=ParseGeometry(value,&geometry_info);
   6360                       if ((flags & SigmaValue) == 0)
   6361                         geometry_info.sigma=1.0;
   6362                       break;
   6363                     }
   6364                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   6365                     keyword);
   6366                   break;
   6367                 }
   6368                 case 'O':
   6369                 case 'o':
   6370                 {
   6371                   if (LocaleCompare(keyword,"opacity") == 0)
   6372                     {
   6373                       geometry_info.rho=StringToLong(value);
   6374                       break;
   6375                     }
   6376                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   6377                     keyword);
   6378                   break;
   6379                 }
   6380                 case 'S':
   6381                 case 's':
   6382                 {
   6383                   if (LocaleCompare(keyword,"sigma") == 0)
   6384                     {
   6385                       geometry_info.sigma=StringToLong(value);
   6386                       break;
   6387                     }
   6388                   break;
   6389                 }
   6390                 case 'X':
   6391                 case 'x':
   6392                 {
   6393                   if (LocaleCompare(keyword,"x") == 0)
   6394                     {
   6395                       geometry_info.xi=StringToDouble(value,
   6396                         (char **) NULL);
   6397                       break;
   6398                     }
   6399                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   6400                     keyword);
   6401                   break;
   6402                 }
   6403                 case 'Y':
   6404                 case 'y':
   6405                 {
   6406                   if (LocaleCompare(keyword,"y") == 0)
   6407                     {
   6408                       geometry_info.psi=StringToLong(value);
   6409                       break;
   6410                     }
   6411                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   6412                     keyword);
   6413                   break;
   6414                 }
   6415                 default:
   6416                 {
   6417                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   6418                     keyword);
   6419                   break;
   6420                 }
   6421               }
   6422             }
   6423           shadow_image=ShadowImage(msl_info->image[n],geometry_info.rho,
   6424             geometry_info.sigma,(ssize_t) ceil(geometry_info.xi-0.5),
   6425             (ssize_t) ceil(geometry_info.psi-0.5),msl_info->exception);
   6426           if (shadow_image == (Image *) NULL)
   6427             break;
   6428           msl_info->image[n]=DestroyImage(msl_info->image[n]);
   6429           msl_info->image[n]=shadow_image;
   6430           break;
   6431         }
   6432       if (LocaleCompare((const char *) tag,"sharpen") == 0)
   6433       {
   6434         double
   6435             radius = 0.0,
   6436             sigma = 1.0;
   6437 
   6438         if (msl_info->image[n] == (Image *) NULL)
   6439           {
   6440             ThrowMSLException(OptionError,"NoImagesDefined",
   6441               (const char *) tag);
   6442             break;
   6443           }
   6444         /*
   6445         NOTE: sharpen can have no attributes, since we use all the defaults!
   6446         */
   6447         if (attributes != (const xmlChar **) NULL)
   6448         {
   6449           for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   6450           {
   6451             keyword=(const char *) attributes[i++];
   6452             attribute=InterpretImageProperties(msl_info->image_info[n],
   6453               msl_info->attributes[n],(const char *) attributes[i],exception);
   6454             CloneString(&value,attribute);
   6455             attribute=DestroyString(attribute);
   6456           switch (*keyword)
   6457           {
   6458             case 'R':
   6459             case 'r':
   6460             {
   6461               if (LocaleCompare(keyword, "radius") == 0)
   6462               {
   6463                 radius = StringToDouble(value,(char **) NULL);
   6464                 break;
   6465               }
   6466               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   6467               break;
   6468             }
   6469             case 'S':
   6470             case 's':
   6471             {
   6472               if (LocaleCompare(keyword,"sigma") == 0)
   6473               {
   6474                 sigma = StringToLong( value );
   6475                 break;
   6476               }
   6477               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   6478               break;
   6479             }
   6480             default:
   6481             {
   6482               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   6483               break;
   6484             }
   6485           }
   6486           }
   6487         }
   6488 
   6489         /*
   6490           sharpen image.
   6491         */
   6492         {
   6493         Image
   6494           *newImage;
   6495 
   6496         newImage=SharpenImage(msl_info->image[n],radius,sigma,
   6497           msl_info->exception);
   6498         if (newImage == (Image *) NULL)
   6499           break;
   6500         msl_info->image[n]=DestroyImage(msl_info->image[n]);
   6501         msl_info->image[n]=newImage;
   6502         break;
   6503         }
   6504       }
   6505       else if (LocaleCompare((const char *) tag,"shave") == 0)
   6506       {
   6507         /* init the values */
   6508         width = height = 0;
   6509         x = y = 0;
   6510 
   6511         if (msl_info->image[n] == (Image *) NULL)
   6512         {
   6513           ThrowMSLException(OptionError,"NoImagesDefined",
   6514             (const char *) tag);
   6515           break;
   6516         }
   6517         if (attributes == (const xmlChar **) NULL)
   6518         break;
   6519         for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   6520         {
   6521           keyword=(const char *) attributes[i++];
   6522           attribute=InterpretImageProperties(msl_info->image_info[n],
   6523             msl_info->attributes[n],(const char *) attributes[i],exception);
   6524           CloneString(&value,attribute);
   6525           attribute=DestroyString(attribute);
   6526         switch (*keyword)
   6527         {
   6528           case 'G':
   6529           case 'g':
   6530           {
   6531           if (LocaleCompare(keyword,"geometry") == 0)
   6532             {
   6533             (void) ParseMetaGeometry(value,&x,&y,&width,&height);
   6534             break;
   6535             }
   6536           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   6537           break;
   6538           }
   6539           case 'H':
   6540           case 'h':
   6541           {
   6542           if (LocaleCompare(keyword,"height") == 0)
   6543             {
   6544             height = StringToLong( value );
   6545             break;
   6546             }
   6547           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   6548           break;
   6549           }
   6550           case 'W':
   6551           case 'w':
   6552           {
   6553           if (LocaleCompare(keyword,"width") == 0)
   6554             {
   6555             width = StringToLong( value );
   6556             break;
   6557             }
   6558           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   6559           break;
   6560           }
   6561           default:
   6562           {
   6563           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   6564           break;
   6565           }
   6566         }
   6567         }
   6568 
   6569         /*
   6570           process image.
   6571         */
   6572         {
   6573         Image
   6574           *newImage;
   6575         RectangleInfo
   6576           rectInfo;
   6577 
   6578         rectInfo.height = height;
   6579         rectInfo.width = width;
   6580         rectInfo.x = x;
   6581         rectInfo.y = y;
   6582 
   6583 
   6584         newImage=ShaveImage(msl_info->image[n], &rectInfo,
   6585           msl_info->exception);
   6586         if (newImage == (Image *) NULL)
   6587           break;
   6588         msl_info->image[n]=DestroyImage(msl_info->image[n]);
   6589         msl_info->image[n]=newImage;
   6590         }
   6591 
   6592         break;
   6593       }
   6594       if (LocaleCompare((const char *) tag,"shear") == 0)
   6595         {
   6596           Image
   6597             *shear_image;
   6598 
   6599           /*
   6600             Shear image.
   6601           */
   6602           if (msl_info->image[n] == (Image *) NULL)
   6603             {
   6604               ThrowMSLException(OptionError,"NoImagesDefined",
   6605                 (const char *) tag);
   6606               break;
   6607             }
   6608           if (attributes != (const xmlChar **) NULL)
   6609             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   6610             {
   6611               keyword=(const char *) attributes[i++];
   6612               attribute=InterpretImageProperties(msl_info->image_info[n],
   6613                 msl_info->attributes[n],(const char *) attributes[i],
   6614                 exception);
   6615               CloneString(&value,attribute);
   6616               attribute=DestroyString(attribute);
   6617               switch (*keyword)
   6618               {
   6619                 case 'F':
   6620                 case 'f':
   6621                 {
   6622                   if (LocaleCompare(keyword, "fill") == 0)
   6623                     {
   6624                       (void) QueryColorCompliance(value,AllCompliance,
   6625                         &msl_info->image[n]->background_color,exception);
   6626                       break;
   6627                     }
   6628                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   6629                     keyword);
   6630                   break;
   6631                 }
   6632                 case 'G':
   6633                 case 'g':
   6634                 {
   6635                   if (LocaleCompare(keyword,"geometry") == 0)
   6636                     {
   6637                       flags=ParseGeometry(value,&geometry_info);
   6638                       if ((flags & SigmaValue) == 0)
   6639                         geometry_info.sigma=1.0;
   6640                       break;
   6641                     }
   6642                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   6643                     keyword);
   6644                   break;
   6645                 }
   6646                 case 'X':
   6647                 case 'x':
   6648                 {
   6649                   if (LocaleCompare(keyword,"x") == 0)
   6650                     {
   6651                       geometry_info.rho=StringToDouble(value,
   6652                         (char **) NULL);
   6653                       break;
   6654                     }
   6655                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   6656                     keyword);
   6657                   break;
   6658                 }
   6659                 case 'Y':
   6660                 case 'y':
   6661                 {
   6662                   if (LocaleCompare(keyword,"y") == 0)
   6663                     {
   6664                       geometry_info.sigma=StringToLong(value);
   6665                       break;
   6666                     }
   6667                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   6668                     keyword);
   6669                   break;
   6670                 }
   6671                 default:
   6672                 {
   6673                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   6674                     keyword);
   6675                   break;
   6676                 }
   6677               }
   6678             }
   6679           shear_image=ShearImage(msl_info->image[n],geometry_info.rho,
   6680             geometry_info.sigma,msl_info->exception);
   6681           if (shear_image == (Image *) NULL)
   6682             break;
   6683           msl_info->image[n]=DestroyImage(msl_info->image[n]);
   6684           msl_info->image[n]=shear_image;
   6685           break;
   6686         }
   6687       if (LocaleCompare((const char *) tag,"signature") == 0)
   6688         {
   6689           /*
   6690             Signature image.
   6691           */
   6692           if (msl_info->image[n] == (Image *) NULL)
   6693             {
   6694               ThrowMSLException(OptionError,"NoImagesDefined",
   6695                 (const char *) tag);
   6696               break;
   6697             }
   6698           if (attributes != (const xmlChar **) NULL)
   6699             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   6700             {
   6701               keyword=(const char *) attributes[i++];
   6702               attribute=InterpretImageProperties(msl_info->image_info[n],
   6703                 msl_info->attributes[n],(const char *) attributes[i],
   6704                 exception);
   6705               CloneString(&value,attribute);
   6706               attribute=DestroyString(attribute);
   6707               switch (*keyword)
   6708               {
   6709                 default:
   6710                 {
   6711                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   6712                     keyword);
   6713                   break;
   6714                 }
   6715               }
   6716             }
   6717           (void) SignatureImage(msl_info->image[n],exception);
   6718           break;
   6719         }
   6720       if (LocaleCompare((const char *) tag,"solarize") == 0)
   6721         {
   6722           /*
   6723             Solarize image.
   6724           */
   6725           if (msl_info->image[n] == (Image *) NULL)
   6726             {
   6727               ThrowMSLException(OptionError,"NoImagesDefined",
   6728                 (const char *) tag);
   6729               break;
   6730             }
   6731           geometry_info.rho=QuantumRange/2.0;
   6732           if (attributes != (const xmlChar **) NULL)
   6733             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   6734             {
   6735               keyword=(const char *) attributes[i++];
   6736               attribute=InterpretImageProperties(msl_info->image_info[n],
   6737                 msl_info->attributes[n],(const char *) attributes[i],
   6738                 exception);
   6739               CloneString(&value,attribute);
   6740               attribute=DestroyString(attribute);
   6741               switch (*keyword)
   6742               {
   6743                 case 'G':
   6744                 case 'g':
   6745                 {
   6746                   if (LocaleCompare(keyword,"geometry") == 0)
   6747                     {
   6748                       flags=ParseGeometry(value,&geometry_info);
   6749                       break;
   6750                     }
   6751                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   6752                     keyword);
   6753                   break;
   6754                 }
   6755                 case 'T':
   6756                 case 't':
   6757                 {
   6758                   if (LocaleCompare(keyword,"threshold") == 0)
   6759                     {
   6760                       geometry_info.rho=StringToDouble(value,
   6761                         (char **) NULL);
   6762                       break;
   6763                     }
   6764                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   6765                     keyword);
   6766                   break;
   6767                 }
   6768                 default:
   6769                 {
   6770                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   6771                     keyword);
   6772                   break;
   6773                 }
   6774               }
   6775             }
   6776           (void) SolarizeImage(msl_info->image[n],geometry_info.rho,
   6777             msl_info->exception);
   6778           break;
   6779         }
   6780       if (LocaleCompare((const char *) tag,"spread") == 0)
   6781         {
   6782           Image
   6783             *spread_image;
   6784 
   6785           /*
   6786             Spread image.
   6787           */
   6788           if (msl_info->image[n] == (Image *) NULL)
   6789             {
   6790               ThrowMSLException(OptionError,"NoImagesDefined",
   6791                 (const char *) tag);
   6792               break;
   6793             }
   6794           if (attributes != (const xmlChar **) NULL)
   6795             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   6796             {
   6797               keyword=(const char *) attributes[i++];
   6798               attribute=InterpretImageProperties(msl_info->image_info[n],
   6799                 msl_info->attributes[n],(const char *) attributes[i],
   6800                 exception);
   6801               CloneString(&value,attribute);
   6802               attribute=DestroyString(attribute);
   6803               switch (*keyword)
   6804               {
   6805                 case 'G':
   6806                 case 'g':
   6807                 {
   6808                   if (LocaleCompare(keyword,"geometry") == 0)
   6809                     {
   6810                       flags=ParseGeometry(value,&geometry_info);
   6811                       if ((flags & SigmaValue) == 0)
   6812                         geometry_info.sigma=1.0;
   6813                       break;
   6814                     }
   6815                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   6816                     keyword);
   6817                   break;
   6818                 }
   6819                 case 'R':
   6820                 case 'r':
   6821                 {
   6822                   if (LocaleCompare(keyword,"radius") == 0)
   6823                     {
   6824                       geometry_info.rho=StringToDouble(value,
   6825                         (char **) NULL);
   6826                       break;
   6827                     }
   6828                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   6829                     keyword);
   6830                   break;
   6831                 }
   6832                 default:
   6833                 {
   6834                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   6835                     keyword);
   6836                   break;
   6837                 }
   6838               }
   6839             }
   6840           spread_image=SpreadImage(msl_info->image[n],
   6841             msl_info->image[n]->interpolate,geometry_info.rho,
   6842             msl_info->exception);
   6843           if (spread_image == (Image *) NULL)
   6844             break;
   6845           msl_info->image[n]=DestroyImage(msl_info->image[n]);
   6846           msl_info->image[n]=spread_image;
   6847           break;
   6848         }
   6849       else if (LocaleCompare((const char *) tag,"stegano") == 0)
   6850       {
   6851         Image *
   6852           watermark = (Image*) NULL;
   6853 
   6854         if (msl_info->image[n] == (Image *) NULL)
   6855           {
   6856             ThrowMSLException(OptionError,"NoImagesDefined",
   6857               (const char *) tag);
   6858             break;
   6859           }
   6860         if (attributes == (const xmlChar **) NULL)
   6861         break;
   6862         for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   6863         {
   6864           keyword=(const char *) attributes[i++];
   6865           attribute=InterpretImageProperties(msl_info->image_info[n],
   6866             msl_info->attributes[n],(const char *) attributes[i],exception);
   6867           CloneString(&value,attribute);
   6868           attribute=DestroyString(attribute);
   6869         switch (*keyword)
   6870         {
   6871           case 'I':
   6872           case 'i':
   6873           {
   6874           if (LocaleCompare(keyword,"image") == 0)
   6875             {
   6876             for (j=0; j<msl_info->n;j++)
   6877             {
   6878               const char *
   6879                 theAttr = GetImageProperty(msl_info->attributes[j], "id",
   6880                       exception);
   6881               if (theAttr && LocaleCompare(theAttr, value) == 0)
   6882               {
   6883                 watermark = msl_info->image[j];
   6884                 break;
   6885               }
   6886             }
   6887             break;
   6888             }
   6889           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   6890           break;
   6891           }
   6892           default:
   6893           {
   6894           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   6895           break;
   6896           }
   6897         }
   6898         }
   6899 
   6900         /*
   6901           process image.
   6902         */
   6903         if ( watermark != (Image*) NULL )
   6904         {
   6905         Image
   6906           *newImage;
   6907 
   6908         newImage=SteganoImage(msl_info->image[n], watermark, msl_info->exception);
   6909         if (newImage == (Image *) NULL)
   6910           break;
   6911         msl_info->image[n]=DestroyImage(msl_info->image[n]);
   6912         msl_info->image[n]=newImage;
   6913         break;
   6914         } else
   6915           ThrowMSLException(OptionError,"MissingWatermarkImage",keyword);
   6916       }
   6917       else if (LocaleCompare((const char *) tag,"stereo") == 0)
   6918       {
   6919         Image *
   6920           stereoImage = (Image*) NULL;
   6921 
   6922         if (msl_info->image[n] == (Image *) NULL)
   6923           {
   6924             ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
   6925             break;
   6926           }
   6927         if (attributes == (const xmlChar **) NULL)
   6928         break;
   6929         for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   6930         {
   6931           keyword=(const char *) attributes[i++];
   6932           attribute=InterpretImageProperties(msl_info->image_info[n],
   6933             msl_info->attributes[n],(const char *) attributes[i],exception);
   6934           CloneString(&value,attribute);
   6935           attribute=DestroyString(attribute);
   6936         switch (*keyword)
   6937         {
   6938           case 'I':
   6939           case 'i':
   6940           {
   6941           if (LocaleCompare(keyword,"image") == 0)
   6942             {
   6943             for (j=0; j<msl_info->n;j++)
   6944             {
   6945               const char *
   6946                 theAttr = GetImageProperty(msl_info->attributes[j], "id",
   6947                       exception);
   6948               if (theAttr && LocaleCompare(theAttr, value) == 0)
   6949               {
   6950                 stereoImage = msl_info->image[j];
   6951                 break;
   6952               }
   6953             }
   6954             break;
   6955             }
   6956           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   6957           break;
   6958           }
   6959           default:
   6960           {
   6961           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   6962           break;
   6963           }
   6964         }
   6965         }
   6966 
   6967         /*
   6968           process image.
   6969         */
   6970         if ( stereoImage != (Image*) NULL )
   6971         {
   6972         Image
   6973           *newImage;
   6974 
   6975         newImage=StereoImage(msl_info->image[n], stereoImage, msl_info->exception);
   6976         if (newImage == (Image *) NULL)
   6977           break;
   6978         msl_info->image[n]=DestroyImage(msl_info->image[n]);
   6979         msl_info->image[n]=newImage;
   6980         break;
   6981         } else
   6982           ThrowMSLException(OptionError,"Missing stereo image",keyword);
   6983       }
   6984       if (LocaleCompare((const char *) tag,"strip") == 0)
   6985         {
   6986           /*
   6987             Strip image.
   6988           */
   6989           if (msl_info->image[n] == (Image *) NULL)
   6990             {
   6991               ThrowMSLException(OptionError,"NoImagesDefined",
   6992                 (const char *) tag);
   6993               break;
   6994             }
   6995           if (attributes != (const xmlChar **) NULL)
   6996             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   6997             {
   6998               keyword=(const char *) attributes[i++];
   6999               attribute=InterpretImageProperties(msl_info->image_info[n],
   7000                 msl_info->attributes[n],(const char *) attributes[i],
   7001                 exception);
   7002               CloneString(&value,attribute);
   7003               attribute=DestroyString(attribute);
   7004               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   7005             }
   7006           (void) StripImage(msl_info->image[n],msl_info->exception);
   7007           break;
   7008         }
   7009       if (LocaleCompare((const char *) tag,"swap") == 0)
   7010         {
   7011           Image
   7012             *p,
   7013             *q,
   7014             *swap;
   7015 
   7016           ssize_t
   7017             index,
   7018             swap_index;
   7019 
   7020           if (msl_info->image[n] == (Image *) NULL)
   7021             {
   7022               ThrowMSLException(OptionError,"NoImagesDefined",
   7023                 (const char *) tag);
   7024               break;
   7025             }
   7026           index=(-1);
   7027           swap_index=(-2);
   7028           if (attributes != (const xmlChar **) NULL)
   7029             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   7030             {
   7031               keyword=(const char *) attributes[i++];
   7032               attribute=InterpretImageProperties(msl_info->image_info[n],
   7033                 msl_info->attributes[n],(const char *) attributes[i],
   7034                 exception);
   7035               CloneString(&value,attribute);
   7036               attribute=DestroyString(attribute);
   7037               switch (*keyword)
   7038               {
   7039                 case 'G':
   7040                 case 'g':
   7041                 {
   7042                   if (LocaleCompare(keyword,"indexes") == 0)
   7043                     {
   7044                       flags=ParseGeometry(value,&geometry_info);
   7045                       index=(ssize_t) geometry_info.rho;
   7046                       if ((flags & SigmaValue) == 0)
   7047                         swap_index=(ssize_t) geometry_info.sigma;
   7048                       break;
   7049                     }
   7050                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   7051                     keyword);
   7052                   break;
   7053                 }
   7054                 default:
   7055                 {
   7056                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   7057                     keyword);
   7058                   break;
   7059                 }
   7060               }
   7061             }
   7062           /*
   7063             Swap images.
   7064           */
   7065           p=GetImageFromList(msl_info->image[n],index);
   7066           q=GetImageFromList(msl_info->image[n],swap_index);
   7067           if ((p == (Image *) NULL) || (q == (Image *) NULL))
   7068             {
   7069               ThrowMSLException(OptionError,"NoSuchImage",(const char *) tag);
   7070               break;
   7071             }
   7072           swap=CloneImage(p,0,0,MagickTrue,msl_info->exception);
   7073           ReplaceImageInList(&p,CloneImage(q,0,0,MagickTrue,
   7074             msl_info->exception));
   7075           ReplaceImageInList(&q,swap);
   7076           msl_info->image[n]=GetFirstImageInList(q);
   7077           break;
   7078         }
   7079       if (LocaleCompare((const char *) tag,"swirl") == 0)
   7080         {
   7081           Image
   7082             *swirl_image;
   7083 
   7084           /*
   7085             Swirl image.
   7086           */
   7087           if (msl_info->image[n] == (Image *) NULL)
   7088             {
   7089               ThrowMSLException(OptionError,"NoImagesDefined",
   7090                 (const char *) tag);
   7091               break;
   7092             }
   7093           if (attributes != (const xmlChar **) NULL)
   7094             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   7095             {
   7096               keyword=(const char *) attributes[i++];
   7097               attribute=InterpretImageProperties(msl_info->image_info[n],
   7098                 msl_info->attributes[n],(const char *) attributes[i],
   7099                 exception);
   7100               CloneString(&value,attribute);
   7101               attribute=DestroyString(attribute);
   7102               switch (*keyword)
   7103               {
   7104                 case 'D':
   7105                 case 'd':
   7106                 {
   7107                   if (LocaleCompare(keyword,"degrees") == 0)
   7108                     {
   7109                       geometry_info.rho=StringToDouble(value,
   7110                         (char **) NULL);
   7111                       break;
   7112                     }
   7113                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   7114                     keyword);
   7115                   break;
   7116                 }
   7117                 case 'G':
   7118                 case 'g':
   7119                 {
   7120                   if (LocaleCompare(keyword,"geometry") == 0)
   7121                     {
   7122                       flags=ParseGeometry(value,&geometry_info);
   7123                       if ((flags & SigmaValue) == 0)
   7124                         geometry_info.sigma=1.0;
   7125                       break;
   7126                     }
   7127                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   7128                     keyword);
   7129                   break;
   7130                 }
   7131                 default:
   7132                 {
   7133                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   7134                     keyword);
   7135                   break;
   7136                 }
   7137               }
   7138             }
   7139           swirl_image=SwirlImage(msl_info->image[n],geometry_info.rho,
   7140             msl_info->image[n]->interpolate,msl_info->exception);
   7141           if (swirl_image == (Image *) NULL)
   7142             break;
   7143           msl_info->image[n]=DestroyImage(msl_info->image[n]);
   7144           msl_info->image[n]=swirl_image;
   7145           break;
   7146         }
   7147       if (LocaleCompare((const char *) tag,"sync") == 0)
   7148         {
   7149           /*
   7150             Sync image.
   7151           */
   7152           if (msl_info->image[n] == (Image *) NULL)
   7153             {
   7154               ThrowMSLException(OptionError,"NoImagesDefined",
   7155                 (const char *) tag);
   7156               break;
   7157             }
   7158           if (attributes != (const xmlChar **) NULL)
   7159             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   7160             {
   7161               keyword=(const char *) attributes[i++];
   7162               attribute=InterpretImageProperties(msl_info->image_info[n],
   7163                 msl_info->attributes[n],(const char *) attributes[i],
   7164                 exception);
   7165               CloneString(&value,attribute);
   7166               attribute=DestroyString(attribute);
   7167               switch (*keyword)
   7168               {
   7169                 default:
   7170                 {
   7171                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   7172                     keyword);
   7173                   break;
   7174                 }
   7175               }
   7176             }
   7177           (void) SyncImage(msl_info->image[n],exception);
   7178           break;
   7179         }
   7180       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
   7181     }
   7182     case 'T':
   7183     case 't':
   7184     {
   7185       if (LocaleCompare((const char *) tag,"map") == 0)
   7186         {
   7187           Image
   7188             *texture_image;
   7189 
   7190           /*
   7191             Texture image.
   7192           */
   7193           if (msl_info->image[n] == (Image *) NULL)
   7194             {
   7195               ThrowMSLException(OptionError,"NoImagesDefined",
   7196                 (const char *) tag);
   7197               break;
   7198             }
   7199           texture_image=NewImageList();
   7200           if (attributes != (const xmlChar **) NULL)
   7201             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   7202             {
   7203               keyword=(const char *) attributes[i++];
   7204               attribute=InterpretImageProperties(msl_info->image_info[n],
   7205                 msl_info->attributes[n],(const char *) attributes[i],
   7206                 exception);
   7207               CloneString(&value,attribute);
   7208               attribute=DestroyString(attribute);
   7209               switch (*keyword)
   7210               {
   7211                 case 'I':
   7212                 case 'i':
   7213                 {
   7214                   if (LocaleCompare(keyword,"image") == 0)
   7215                     for (j=0; j < msl_info->n; j++)
   7216                     {
   7217                       const char
   7218                         *attribute;
   7219 
   7220                       attribute=GetImageProperty(msl_info->attributes[j],"id",
   7221                       exception);
   7222                       if ((attribute != (const char *) NULL)  &&
   7223                           (LocaleCompare(attribute,value) == 0))
   7224                         {
   7225                           texture_image=CloneImage(msl_info->image[j],0,0,
   7226                             MagickFalse,exception);
   7227                           break;
   7228                         }
   7229                     }
   7230                   break;
   7231                 }
   7232                 default:
   7233                 {
   7234                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
   7235                     keyword);
   7236                   break;
   7237                 }
   7238               }
   7239             }
   7240           (void) TextureImage(msl_info->image[n],texture_image,exception);
   7241           texture_image=DestroyImage(texture_image);
   7242           break;
   7243         }
   7244       else if (LocaleCompare((const char *) tag,"threshold") == 0)
   7245       {
   7246         /* init the values */
   7247         double  threshold = 0;
   7248 
   7249         if (msl_info->image[n] == (Image *) NULL)
   7250           {
   7251             ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
   7252             break;
   7253           }
   7254         if (attributes == (const xmlChar **) NULL)
   7255         break;
   7256         for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   7257         {
   7258           keyword=(const char *) attributes[i++];
   7259           attribute=InterpretImageProperties(msl_info->image_info[n],
   7260             msl_info->attributes[n],(const char *) attributes[i],exception);
   7261           CloneString(&value,attribute);
   7262           attribute=DestroyString(attribute);
   7263         switch (*keyword)
   7264         {
   7265           case 'T':
   7266           case 't':
   7267           {
   7268           if (LocaleCompare(keyword,"threshold") == 0)
   7269             {
   7270             threshold = StringToDouble(value,(char **) NULL);
   7271             break;
   7272             }
   7273           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   7274           break;
   7275           }
   7276           default:
   7277           {
   7278           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   7279           break;
   7280           }
   7281         }
   7282         }
   7283 
   7284         /*
   7285           process image.
   7286         */
   7287         {
   7288           BilevelImage(msl_info->image[n],threshold,exception);
   7289           break;
   7290         }
   7291       }
   7292       else if (LocaleCompare((const char *) tag, "transparent") == 0)
   7293       {
   7294         if (msl_info->image[n] == (Image *) NULL)
   7295           {
   7296             ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
   7297             break;
   7298           }
   7299         if (attributes == (const xmlChar **) NULL)
   7300           break;
   7301         for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   7302         {
   7303           keyword=(const char *) attributes[i++];
   7304           attribute=InterpretImageProperties(msl_info->image_info[n],
   7305             msl_info->attributes[n],(const char *) attributes[i],exception);
   7306           CloneString(&value,attribute);
   7307           attribute=DestroyString(attribute);
   7308           switch (*keyword)
   7309           {
   7310             case 'C':
   7311             case 'c':
   7312             {
   7313               if (LocaleCompare(keyword,"color") == 0)
   7314               {
   7315                 PixelInfo
   7316                   target;
   7317 
   7318                 (void) QueryColorCompliance(value,AllCompliance,&target,
   7319                   exception);
   7320                 (void) TransparentPaintImage(msl_info->image[n],&target,
   7321                   TransparentAlpha,MagickFalse,msl_info->exception);
   7322                 break;
   7323               }
   7324               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   7325               break;
   7326             }
   7327             default:
   7328             {
   7329               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   7330             break;
   7331             }
   7332           }
   7333         }
   7334         break;
   7335       }
   7336       else if (LocaleCompare((const char *) tag, "trim") == 0)
   7337       {
   7338         if (msl_info->image[n] == (Image *) NULL)
   7339           {
   7340             ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
   7341             break;
   7342           }
   7343 
   7344         /* no attributes here */
   7345 
   7346         /* process the image */
   7347         {
   7348           Image
   7349             *newImage;
   7350           RectangleInfo
   7351             rectInfo;
   7352 
   7353           /* all zeros on a crop == trim edges! */
   7354           rectInfo.height = rectInfo.width = 0;
   7355           rectInfo.x =  rectInfo.y = 0;
   7356 
   7357           newImage=CropImage(msl_info->image[n],&rectInfo, msl_info->exception);
   7358           if (newImage == (Image *) NULL)
   7359             break;
   7360           msl_info->image[n]=DestroyImage(msl_info->image[n]);
   7361           msl_info->image[n]=newImage;
   7362           break;
   7363         }
   7364       }
   7365       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
   7366     }
   7367     case 'W':
   7368     case 'w':
   7369     {
   7370       if (LocaleCompare((const char *) tag,"write") == 0)
   7371         {
   7372           if (msl_info->image[n] == (Image *) NULL)
   7373             {
   7374               ThrowMSLException(OptionError,"NoImagesDefined",
   7375                 (const char *) tag);
   7376               break;
   7377             }
   7378           if (attributes == (const xmlChar **) NULL)
   7379             break;
   7380           for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
   7381           {
   7382             keyword=(const char *) attributes[i++];
   7383             attribute=InterpretImageProperties(msl_info->image_info[n],
   7384               msl_info->attributes[n],(const char *) attributes[i],exception);
   7385             CloneString(&value,attribute);
   7386             attribute=DestroyString(attribute);
   7387             switch (*keyword)
   7388             {
   7389               case 'F':
   7390               case 'f':
   7391               {
   7392                 if (LocaleCompare(keyword,"filename") == 0)
   7393                   {
   7394                     (void) CopyMagickString(msl_info->image[n]->filename,value,
   7395                       MagickPathExtent);
   7396                     break;
   7397                   }
   7398                 (void) SetMSLAttributes(msl_info,keyword,value);
   7399               }
   7400               default:
   7401               {
   7402                 (void) SetMSLAttributes(msl_info,keyword,value);
   7403                 break;
   7404               }
   7405             }
   7406           }
   7407 
   7408           /* process */
   7409           {
   7410             *msl_info->image_info[n]->magick='\0';
   7411             (void) WriteImage(msl_info->image_info[n], msl_info->image[n],
   7412               msl_info->exception);
   7413             break;
   7414           }
   7415         }
   7416       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
   7417     }
   7418     default:
   7419     {
   7420       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
   7421       break;
   7422     }
   7423   }
   7424   if (value != (char *) NULL)
   7425     value=DestroyString(value);
   7426   (void) DestroyExceptionInfo(exception);
   7427   (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  )");
   7428 }
   7429 
   7430 static void MSLEndElement(void *context,const xmlChar *tag)
   7431 {
   7432   ssize_t
   7433     n;
   7434 
   7435   MSLInfo
   7436     *msl_info;
   7437 
   7438   /*
   7439     Called when the end of an element has been detected.
   7440   */
   7441   (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  SAX.endElement(%s)",
   7442     tag);
   7443   msl_info=(MSLInfo *) context;
   7444   n=msl_info->n;
   7445   switch (*tag)
   7446   {
   7447     case 'C':
   7448     case 'c':
   7449     {
   7450       if (LocaleCompare((const char *) tag,"comment") == 0 )
   7451         {
   7452           (void) DeleteImageProperty(msl_info->image[n],"comment");
   7453           if (msl_info->content == (char *) NULL)
   7454             break;
   7455           StripString(msl_info->content);
   7456           (void) SetImageProperty(msl_info->image[n],"comment",
   7457             msl_info->content,msl_info->exception);
   7458           break;
   7459         }
   7460       break;
   7461     }
   7462     case 'G':
   7463     case 'g':
   7464     {
   7465       if (LocaleCompare((const char *) tag, "group") == 0 )
   7466       {
   7467         if (msl_info->group_info[msl_info->number_groups-1].numImages > 0 )
   7468         {
   7469           ssize_t  i = (ssize_t)
   7470             (msl_info->group_info[msl_info->number_groups-1].numImages);
   7471           while ( i-- )
   7472           {
   7473             if (msl_info->image[msl_info->n] != (Image *) NULL)
   7474               msl_info->image[msl_info->n]=DestroyImage(
   7475                 msl_info->image[msl_info->n]);
   7476             msl_info->attributes[msl_info->n]=DestroyImage(
   7477                 msl_info->attributes[msl_info->n]);
   7478             msl_info->image_info[msl_info->n]=DestroyImageInfo(
   7479                 msl_info->image_info[msl_info->n]);
   7480             msl_info->n--;
   7481           }
   7482         }
   7483         msl_info->number_groups--;
   7484       }
   7485       break;
   7486     }
   7487     case 'I':
   7488     case 'i':
   7489     {
   7490       if (LocaleCompare((const char *) tag, "image") == 0)
   7491         MSLPopImage(msl_info);
   7492        break;
   7493     }
   7494     case 'L':
   7495     case 'l':
   7496     {
   7497       if (LocaleCompare((const char *) tag,"label") == 0 )
   7498         {
   7499           (void) DeleteImageProperty(msl_info->image[n],"label");
   7500           if (msl_info->content == (char *) NULL)
   7501             break;
   7502           StripString(msl_info->content);
   7503           (void) SetImageProperty(msl_info->image[n],"label",
   7504             msl_info->content,msl_info->exception);
   7505           break;
   7506         }
   7507       break;
   7508     }
   7509     case 'M':
   7510     case 'm':
   7511     {
   7512       if (LocaleCompare((const char *) tag, "msl") == 0 )
   7513       {
   7514         /*
   7515           This our base element.
   7516             at the moment we don't do anything special
   7517             but someday we might!
   7518         */
   7519       }
   7520       break;
   7521     }
   7522     default:
   7523       break;
   7524   }
   7525   if (msl_info->content != (char *) NULL)
   7526     msl_info->content=DestroyString(msl_info->content);
   7527 }
   7528 
   7529 static void MSLCharacters(void *context,const xmlChar *c,int length)
   7530 {
   7531   MSLInfo
   7532     *msl_info;
   7533 
   7534   register char
   7535     *p;
   7536 
   7537   register ssize_t
   7538     i;
   7539 
   7540   /*
   7541     Receiving some characters from the parser.
   7542   */
   7543   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
   7544     "  SAX.characters(%s,%d)",c,length);
   7545   msl_info=(MSLInfo *) context;
   7546   if (msl_info->content != (char *) NULL)
   7547     msl_info->content=(char *) ResizeQuantumMemory(msl_info->content,
   7548       strlen(msl_info->content)+length+MagickPathExtent,
   7549       sizeof(*msl_info->content));
   7550   else
   7551     {
   7552       msl_info->content=(char *) NULL;
   7553       if (~(size_t) length >= (MagickPathExtent-1))
   7554         msl_info->content=(char *) AcquireQuantumMemory(length+MagickPathExtent,
   7555           sizeof(*msl_info->content));
   7556       if (msl_info->content != (char *) NULL)
   7557         *msl_info->content='\0';
   7558     }
   7559   if (msl_info->content == (char *) NULL)
   7560     return;
   7561   p=msl_info->content+strlen(msl_info->content);
   7562   for (i=0; i < length; i++)
   7563     *p++=c[i];
   7564   *p='\0';
   7565 }
   7566 
   7567 static void MSLReference(void *context,const xmlChar *name)
   7568 {
   7569   MSLInfo
   7570     *msl_info;
   7571 
   7572   xmlParserCtxtPtr
   7573     parser;
   7574 
   7575   /*
   7576     Called when an entity reference is detected.
   7577   */
   7578   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
   7579     "  SAX.reference(%s)",name);
   7580   msl_info=(MSLInfo *) context;
   7581   parser=msl_info->parser;
   7582   if (*name == '#')
   7583     (void) xmlAddChild(parser->node,xmlNewCharRef(msl_info->document,name));
   7584   else
   7585     (void) xmlAddChild(parser->node,xmlNewReference(msl_info->document,name));
   7586 }
   7587 
   7588 static void MSLIgnorableWhitespace(void *context,const xmlChar *c,int length)
   7589 {
   7590   MSLInfo
   7591     *msl_info;
   7592 
   7593   /*
   7594     Receiving some ignorable whitespaces from the parser.
   7595   */
   7596   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
   7597     "  SAX.ignorableWhitespace(%.30s, %d)",c,length);
   7598   msl_info=(MSLInfo *) context;
   7599   (void) msl_info;
   7600 }
   7601 
   7602 static void MSLProcessingInstructions(void *context,const xmlChar *target,
   7603   const xmlChar *data)
   7604 {
   7605   MSLInfo
   7606     *msl_info;
   7607 
   7608   /*
   7609     A processing instruction has been parsed.
   7610   */
   7611   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
   7612     "  SAX.processingInstruction(%s, %s)",
   7613     target,data);
   7614   msl_info=(MSLInfo *) context;
   7615   (void) msl_info;
   7616 }
   7617 
   7618 static void MSLComment(void *context,const xmlChar *value)
   7619 {
   7620   MSLInfo
   7621     *msl_info;
   7622 
   7623   /*
   7624     A comment has been parsed.
   7625   */
   7626   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
   7627     "  SAX.comment(%s)",value);
   7628   msl_info=(MSLInfo *) context;
   7629   (void) msl_info;
   7630 }
   7631 
   7632 static void MSLWarning(void *context,const char *format,...)
   7633   magick_attribute((__format__ (__printf__,2,3)));
   7634 
   7635 static void MSLWarning(void *context,const char *format,...)
   7636 {
   7637   char
   7638     *message,
   7639     reason[MagickPathExtent];
   7640 
   7641   MSLInfo
   7642     *msl_info;
   7643 
   7644   va_list
   7645     operands;
   7646 
   7647   /**
   7648     Display and format a warning messages, gives file, line, position and
   7649     extra parameters.
   7650   */
   7651   va_start(operands,format);
   7652   (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  SAX.warning: ");
   7653   (void) LogMagickEvent(CoderEvent,GetMagickModule(),format,operands);
   7654   msl_info=(MSLInfo *) context;
   7655   (void) msl_info;
   7656 #if !defined(MAGICKCORE_HAVE_VSNPRINTF)
   7657   (void) vsprintf(reason,format,operands);
   7658 #else
   7659   (void) vsnprintf(reason,MagickPathExtent,format,operands);
   7660 #endif
   7661   message=GetExceptionMessage(errno);
   7662   ThrowMSLException(CoderError,reason,message);
   7663   message=DestroyString(message);
   7664   va_end(operands);
   7665 }
   7666 
   7667 static void MSLError(void *context,const char *format,...)
   7668   magick_attribute((__format__ (__printf__,2,3)));
   7669 
   7670 static void MSLError(void *context,const char *format,...)
   7671 {
   7672   char
   7673     reason[MagickPathExtent];
   7674 
   7675   MSLInfo
   7676     *msl_info;
   7677 
   7678   va_list
   7679     operands;
   7680 
   7681   /*
   7682     Display and format a error formats, gives file, line, position and
   7683     extra parameters.
   7684   */
   7685   va_start(operands,format);
   7686   (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  SAX.error: ");
   7687   (void) LogMagickEvent(CoderEvent,GetMagickModule(),format,operands);
   7688   msl_info=(MSLInfo *) context;
   7689   (void) msl_info;
   7690 #if !defined(MAGICKCORE_HAVE_VSNPRINTF)
   7691   (void) vsprintf(reason,format,operands);
   7692 #else
   7693   (void) vsnprintf(reason,MagickPathExtent,format,operands);
   7694 #endif
   7695   ThrowMSLException(DelegateFatalError,reason,"SAX error");
   7696   va_end(operands);
   7697 }
   7698 
   7699 static void MSLCDataBlock(void *context,const xmlChar *value,int length)
   7700 {
   7701   MSLInfo
   7702     *msl_info;
   7703 
   7704    xmlNodePtr
   7705      child;
   7706 
   7707   xmlParserCtxtPtr
   7708     parser;
   7709 
   7710   /*
   7711     Called when a pcdata block has been parsed.
   7712   */
   7713   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
   7714     "  SAX.pcdata(%s, %d)",value,length);
   7715   msl_info=(MSLInfo *) context;
   7716   (void) msl_info;
   7717   parser=msl_info->parser;
   7718   child=xmlGetLastChild(parser->node);
   7719   if ((child != (xmlNodePtr) NULL) && (child->type == XML_CDATA_SECTION_NODE))
   7720     {
   7721       xmlTextConcat(child,value,length);
   7722       return;
   7723     }
   7724   (void) xmlAddChild(parser->node,xmlNewCDataBlock(parser->myDoc,value,length));
   7725 }
   7726 
   7727 static void MSLExternalSubset(void *context,const xmlChar *name,
   7728   const xmlChar *external_id,const xmlChar *system_id)
   7729 {
   7730   MSLInfo
   7731     *msl_info;
   7732 
   7733   xmlParserCtxt
   7734     parser_context;
   7735 
   7736   xmlParserCtxtPtr
   7737     parser;
   7738 
   7739   xmlParserInputPtr
   7740     input;
   7741 
   7742   /*
   7743     Does this document has an external subset?
   7744   */
   7745   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
   7746     "  SAX.externalSubset(%s %s %s)",name,
   7747     (external_id != (const xmlChar *) NULL ? (const char *) external_id : " "),
   7748     (system_id != (const xmlChar *) NULL ? (const char *) system_id : " "));
   7749   msl_info=(MSLInfo *) context;
   7750   (void) msl_info;
   7751   parser=msl_info->parser;
   7752   if (((external_id == NULL) && (system_id == NULL)) ||
   7753       ((parser->validate == 0) || (parser->wellFormed == 0) ||
   7754       (msl_info->document == 0)))
   7755     return;
   7756   input=MSLResolveEntity(context,external_id,system_id);
   7757   if (input == NULL)
   7758     return;
   7759   (void) xmlNewDtd(msl_info->document,name,external_id,system_id);
   7760   parser_context=(*parser);
   7761   parser->inputTab=(xmlParserInputPtr *) xmlMalloc(5*sizeof(*parser->inputTab));
   7762   if (parser->inputTab == (xmlParserInputPtr *) NULL)
   7763     {
   7764       parser->errNo=XML_ERR_NO_MEMORY;
   7765       parser->input=parser_context.input;
   7766       parser->inputNr=parser_context.inputNr;
   7767       parser->inputMax=parser_context.inputMax;
   7768       parser->inputTab=parser_context.inputTab;
   7769       return;
   7770   }
   7771   parser->inputNr=0;
   7772   parser->inputMax=5;
   7773   parser->input=NULL;
   7774   xmlPushInput(parser,input);
   7775   (void) xmlSwitchEncoding(parser,xmlDetectCharEncoding(parser->input->cur,4));
   7776   if (input->filename == (char *) NULL)
   7777     input->filename=(char *) xmlStrdup(system_id);
   7778   input->line=1;
   7779   input->col=1;
   7780   input->base=parser->input->cur;
   7781   input->cur=parser->input->cur;
   7782   input->free=NULL;
   7783   xmlParseExternalSubset(parser,external_id,system_id);
   7784   while (parser->inputNr > 1)
   7785     (void) xmlPopInput(parser);
   7786   xmlFreeInputStream(parser->input);
   7787   xmlFree(parser->inputTab);
   7788   parser->input=parser_context.input;
   7789   parser->inputNr=parser_context.inputNr;
   7790   parser->inputMax=parser_context.inputMax;
   7791   parser->inputTab=parser_context.inputTab;
   7792 }
   7793 
   7794 #if defined(__cplusplus) || defined(c_plusplus)
   7795 }
   7796 #endif
   7797 
   7798 static MagickBooleanType ProcessMSLScript(const ImageInfo *image_info,
   7799   Image **image,ExceptionInfo *exception)
   7800 {
   7801   char
   7802     message[MagickPathExtent];
   7803 
   7804   Image
   7805     *msl_image;
   7806 
   7807   int
   7808     status;
   7809 
   7810   ssize_t
   7811     n;
   7812 
   7813   MSLInfo
   7814     msl_info;
   7815 
   7816   xmlSAXHandler
   7817     sax_modules;
   7818 
   7819   xmlSAXHandlerPtr
   7820     sax_handler;
   7821 
   7822   /*
   7823     Open image file.
   7824   */
   7825   assert(image_info != (const ImageInfo *) NULL);
   7826   assert(image_info->signature == MagickCoreSignature);
   7827   if (image_info->debug != MagickFalse)
   7828     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
   7829       image_info->filename);
   7830   assert(image != (Image **) NULL);
   7831   msl_image=AcquireImage(image_info,exception);
   7832   status=OpenBlob(image_info,msl_image,ReadBinaryBlobMode,exception);
   7833   if (status == MagickFalse)
   7834     {
   7835       ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
   7836         msl_image->filename);
   7837       msl_image=DestroyImageList(msl_image);
   7838       return(MagickFalse);
   7839     }
   7840   msl_image->columns=1;
   7841   msl_image->rows=1;
   7842   /*
   7843     Parse MSL file.
   7844   */
   7845   (void) memset(&msl_info,0,sizeof(msl_info));
   7846   msl_info.exception=exception;
   7847   msl_info.image_info=(ImageInfo **) AcquireMagickMemory(
   7848     sizeof(*msl_info.image_info));
   7849   msl_info.draw_info=(DrawInfo **) AcquireMagickMemory(
   7850     sizeof(*msl_info.draw_info));
   7851   /* top of the stack is the MSL file itself */
   7852   msl_info.image=(Image **) AcquireMagickMemory(sizeof(*msl_info.image));
   7853   msl_info.attributes=(Image **) AcquireMagickMemory(
   7854     sizeof(*msl_info.attributes));
   7855   msl_info.group_info=(MSLGroupInfo *) AcquireMagickMemory(
   7856     sizeof(*msl_info.group_info));
   7857   if ((msl_info.image_info == (ImageInfo **) NULL) ||
   7858       (msl_info.draw_info == (DrawInfo **) NULL) ||
   7859       (msl_info.image == (Image **) NULL) ||
   7860       (msl_info.attributes == (Image **) NULL) ||
   7861       (msl_info.group_info == (MSLGroupInfo *) NULL))
   7862     ThrowFatalException(ResourceLimitFatalError,"UnableToInterpretMSLImage");
   7863   *msl_info.image_info=CloneImageInfo(image_info);
   7864   *msl_info.draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL);
   7865   *msl_info.attributes=AcquireImage(image_info,exception);
   7866   msl_info.group_info[0].numImages=0;
   7867   /* the first slot is used to point to the MSL file image */
   7868   *msl_info.image=msl_image;
   7869   if (*image != (Image *) NULL)
   7870     MSLPushImage(&msl_info,*image);
   7871   (void) xmlSubstituteEntitiesDefault(1);
   7872   (void) memset(&sax_modules,0,sizeof(sax_modules));
   7873   sax_modules.internalSubset=MSLInternalSubset;
   7874   sax_modules.isStandalone=MSLIsStandalone;
   7875   sax_modules.hasInternalSubset=MSLHasInternalSubset;
   7876   sax_modules.hasExternalSubset=MSLHasExternalSubset;
   7877   sax_modules.resolveEntity=MSLResolveEntity;
   7878   sax_modules.getEntity=MSLGetEntity;
   7879   sax_modules.entityDecl=MSLEntityDeclaration;
   7880   sax_modules.notationDecl=MSLNotationDeclaration;
   7881   sax_modules.attributeDecl=MSLAttributeDeclaration;
   7882   sax_modules.elementDecl=MSLElementDeclaration;
   7883   sax_modules.unparsedEntityDecl=MSLUnparsedEntityDeclaration;
   7884   sax_modules.setDocumentLocator=MSLSetDocumentLocator;
   7885   sax_modules.startDocument=MSLStartDocument;
   7886   sax_modules.endDocument=MSLEndDocument;
   7887   sax_modules.startElement=MSLStartElement;
   7888   sax_modules.endElement=MSLEndElement;
   7889   sax_modules.reference=MSLReference;
   7890   sax_modules.characters=MSLCharacters;
   7891   sax_modules.ignorableWhitespace=MSLIgnorableWhitespace;
   7892   sax_modules.processingInstruction=MSLProcessingInstructions;
   7893   sax_modules.comment=MSLComment;
   7894   sax_modules.warning=MSLWarning;
   7895   sax_modules.error=MSLError;
   7896   sax_modules.fatalError=MSLError;
   7897   sax_modules.getParameterEntity=MSLGetParameterEntity;
   7898   sax_modules.cdataBlock=MSLCDataBlock;
   7899   sax_modules.externalSubset=MSLExternalSubset;
   7900   sax_handler=(&sax_modules);
   7901   msl_info.parser=xmlCreatePushParserCtxt(sax_handler,&msl_info,(char *) NULL,0,
   7902     msl_image->filename);
   7903   while (ReadBlobString(msl_image,message) != (char *) NULL)
   7904   {
   7905     n=(ssize_t) strlen(message);
   7906     if (n == 0)
   7907       continue;
   7908     status=xmlParseChunk(msl_info.parser,message,(int) n,MagickFalse);
   7909     if (status != 0)
   7910       break;
   7911     (void) xmlParseChunk(msl_info.parser," ",1,MagickFalse);
   7912     if (msl_info.exception->severity >= ErrorException)
   7913       break;
   7914   }
   7915   if (msl_info.exception->severity == UndefinedException)
   7916     (void) xmlParseChunk(msl_info.parser," ",1,MagickTrue);
   7917   /*
   7918     Free resources.
   7919   */
   7920   xmlFreeParserCtxt(msl_info.parser);
   7921   (void) LogMagickEvent(CoderEvent,GetMagickModule(),"end SAX");
   7922   if (*image == (Image *) NULL)
   7923     *image=CloneImage(*msl_info.image,0,0,MagickTrue,exception);
   7924   while (msl_info.n >= 0)
   7925   {
   7926     msl_info.image[msl_info.n]=DestroyImage(msl_info.image[msl_info.n]);
   7927     msl_info.attributes[msl_info.n]=DestroyImage(
   7928       msl_info.attributes[msl_info.n]);
   7929     msl_info.draw_info[msl_info.n]=DestroyDrawInfo(
   7930       msl_info.draw_info[msl_info.n]);
   7931     msl_info.image_info[msl_info.n]=DestroyImageInfo(
   7932       msl_info.image_info[msl_info.n]);
   7933     msl_info.n--;
   7934   }
   7935   msl_info.draw_info=(DrawInfo **) RelinquishMagickMemory(msl_info.draw_info);
   7936   msl_info.image=(Image **) RelinquishMagickMemory(msl_info.image);
   7937   msl_info.attributes=(Image **) RelinquishMagickMemory(msl_info.attributes);
   7938   msl_info.image_info=(ImageInfo **) RelinquishMagickMemory(
   7939     msl_info.image_info);
   7940   msl_info.group_info=(MSLGroupInfo *) RelinquishMagickMemory(
   7941     msl_info.group_info);
   7942   if (msl_info.exception->severity != UndefinedException)
   7943     return(MagickFalse);
   7944   return(MagickTrue);
   7945 }
   7946 
   7947 static Image *ReadMSLImage(const ImageInfo *image_info,ExceptionInfo *exception)
   7948 {
   7949   Image
   7950     *image;
   7951 
   7952   /*
   7953     Open image file.
   7954   */
   7955   assert(image_info != (const ImageInfo *) NULL);
   7956   assert(image_info->signature == MagickCoreSignature);
   7957   if (image_info->debug != MagickFalse)
   7958     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
   7959       image_info->filename);
   7960   assert(exception != (ExceptionInfo *) NULL);
   7961   assert(exception->signature == MagickCoreSignature);
   7962   image=(Image *) NULL;
   7963   (void) ProcessMSLScript(image_info,&image,exception);
   7964   return(GetFirstImageInList(image));
   7965 }
   7966 #endif
   7967 
   7968 /*
   7970 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   7971 %                                                                             %
   7972 %                                                                             %
   7973 %                                                                             %
   7974 %   R e g i s t e r M S L I m a g e                                           %
   7975 %                                                                             %
   7976 %                                                                             %
   7977 %                                                                             %
   7978 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   7979 %
   7980 %  RegisterMSLImage() adds attributes for the MSL image format to
   7981 %  the list of supported formats.  The attributes include the image format
   7982 %  tag, a method to read and/or write the format, whether the format
   7983 %  supports the saving of more than one frame to the same file or blob,
   7984 %  whether the format supports native in-memory I/O, and a brief
   7985 %  description of the format.
   7986 %
   7987 %  The format of the RegisterMSLImage method is:
   7988 %
   7989 %      size_t RegisterMSLImage(void)
   7990 %
   7991 */
   7992 ModuleExport size_t RegisterMSLImage(void)
   7993 {
   7994   MagickInfo
   7995     *entry;
   7996 
   7997 #if defined(MAGICKCORE_XML_DELEGATE)
   7998   xmlInitParser();
   7999 #endif
   8000   entry=AcquireMagickInfo("MSL","MSL","Magick Scripting Language");
   8001 #if defined(MAGICKCORE_XML_DELEGATE)
   8002   entry->decoder=(DecodeImageHandler *) ReadMSLImage;
   8003   entry->encoder=(EncodeImageHandler *) WriteMSLImage;
   8004 #endif
   8005   entry->format_type=ImplicitFormatType;
   8006   (void) RegisterMagickInfo(entry);
   8007   return(MagickImageCoderSignature);
   8008 }
   8009 
   8010 #if defined(MAGICKCORE_XML_DELEGATE)
   8012 /*
   8013 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   8014 %                                                                             %
   8015 %                                                                             %
   8016 %                                                                             %
   8017 %   S e t M S L A t t r i b u t e s                                           %
   8018 %                                                                             %
   8019 %                                                                             %
   8020 %                                                                             %
   8021 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   8022 %
   8023 %  SetMSLAttributes() ...
   8024 %
   8025 %  The format of the SetMSLAttributes method is:
   8026 %
   8027 %      MagickBooleanType SetMSLAttributes(MSLInfo *msl_info,
   8028 %        const char *keyword,const char *value)
   8029 %
   8030 %  A description of each parameter follows:
   8031 %
   8032 %    o msl_info: the MSL info.
   8033 %
   8034 %    o keyword: the keyword.
   8035 %
   8036 %    o value: the value.
   8037 %
   8038 */
   8039 static MagickBooleanType SetMSLAttributes(MSLInfo *msl_info,const char *keyword,
   8040   const char *value)
   8041 {
   8042   Image
   8043     *attributes;
   8044 
   8045   DrawInfo
   8046     *draw_info;
   8047 
   8048   ExceptionInfo
   8049     *exception;
   8050 
   8051   GeometryInfo
   8052     geometry_info;
   8053 
   8054   Image
   8055     *image;
   8056 
   8057   ImageInfo
   8058     *image_info;
   8059 
   8060   int
   8061     flags;
   8062 
   8063   ssize_t
   8064     n;
   8065 
   8066   assert(msl_info != (MSLInfo *) NULL);
   8067   if (keyword == (const char *) NULL)
   8068     return(MagickTrue);
   8069   if (value == (const char *) NULL)
   8070     return(MagickTrue);
   8071   exception=msl_info->exception;
   8072   n=msl_info->n;
   8073   attributes=msl_info->attributes[n];
   8074   image_info=msl_info->image_info[n];
   8075   draw_info=msl_info->draw_info[n];
   8076   image=msl_info->image[n];
   8077   switch (*keyword)
   8078   {
   8079     case 'A':
   8080     case 'a':
   8081     {
   8082       if (LocaleCompare(keyword,"adjoin") == 0)
   8083         {
   8084           ssize_t
   8085             adjoin;
   8086 
   8087           adjoin=ParseCommandOption(MagickBooleanOptions,MagickFalse,value);
   8088           if (adjoin < 0)
   8089             ThrowMSLException(OptionError,"UnrecognizedType",value);
   8090           image_info->adjoin=(MagickBooleanType) adjoin;
   8091           break;
   8092         }
   8093       if (LocaleCompare(keyword,"alpha") == 0)
   8094         {
   8095           ssize_t
   8096             alpha;
   8097 
   8098           alpha=ParseCommandOption(MagickAlphaChannelOptions,MagickFalse,value);
   8099           if (alpha < 0)
   8100             ThrowMSLException(OptionError,"UnrecognizedType",value);
   8101           if (image != (Image *) NULL)
   8102             (void) SetImageAlphaChannel(image,(AlphaChannelOption) alpha,
   8103               exception);
   8104           break;
   8105         }
   8106       if (LocaleCompare(keyword,"antialias") == 0)
   8107         {
   8108           ssize_t
   8109             antialias;
   8110 
   8111           antialias=ParseCommandOption(MagickBooleanOptions,MagickFalse,value);
   8112           if (antialias < 0)
   8113             ThrowMSLException(OptionError,"UnrecognizedGravityType",value);
   8114           image_info->antialias=(MagickBooleanType) antialias;
   8115           break;
   8116         }
   8117       if (LocaleCompare(keyword,"area-limit") == 0)
   8118         {
   8119           MagickSizeType
   8120             limit;
   8121 
   8122           limit=MagickResourceInfinity;
   8123           if (LocaleCompare(value,"unlimited") != 0)
   8124             limit=(MagickSizeType) StringToDoubleInterval(value,100.0);
   8125           (void) SetMagickResourceLimit(AreaResource,limit);
   8126           break;
   8127         }
   8128       if (LocaleCompare(keyword,"attenuate") == 0)
   8129         {
   8130           (void) SetImageOption(image_info,keyword,value);
   8131           break;
   8132         }
   8133       if (LocaleCompare(keyword,"authenticate") == 0)
   8134         {
   8135           (void) CloneString(&image_info->density,value);
   8136           break;
   8137         }
   8138       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   8139       break;
   8140     }
   8141     case 'B':
   8142     case 'b':
   8143     {
   8144       if (LocaleCompare(keyword,"background") == 0)
   8145         {
   8146           (void) QueryColorCompliance(value,AllCompliance,
   8147             &image_info->background_color,exception);
   8148           break;
   8149         }
   8150       if (LocaleCompare(keyword,"blue-primary") == 0)
   8151         {
   8152           if (image == (Image *) NULL)
   8153             break;
   8154           flags=ParseGeometry(value,&geometry_info);
   8155           image->chromaticity.blue_primary.x=geometry_info.rho;
   8156           image->chromaticity.blue_primary.y=geometry_info.sigma;
   8157           if ((flags & SigmaValue) == 0)
   8158             image->chromaticity.blue_primary.y=
   8159               image->chromaticity.blue_primary.x;
   8160           break;
   8161         }
   8162       if (LocaleCompare(keyword,"bordercolor") == 0)
   8163         {
   8164           (void) QueryColorCompliance(value,AllCompliance,
   8165             &image_info->border_color,exception);
   8166           break;
   8167         }
   8168       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   8169       break;
   8170     }
   8171     case 'D':
   8172     case 'd':
   8173     {
   8174       if (LocaleCompare(keyword,"density") == 0)
   8175         {
   8176           (void) CloneString(&image_info->density,value);
   8177           (void) CloneString(&draw_info->density,value);
   8178           break;
   8179         }
   8180       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   8181       break;
   8182     }
   8183     case 'F':
   8184     case 'f':
   8185     {
   8186       if (LocaleCompare(keyword,"fill") == 0)
   8187         {
   8188           (void) QueryColorCompliance(value,AllCompliance,&draw_info->fill,
   8189             exception);
   8190           (void) SetImageOption(image_info,keyword,value);
   8191           break;
   8192         }
   8193       if (LocaleCompare(keyword,"filename") == 0)
   8194         {
   8195           (void) CopyMagickString(image_info->filename,value,MagickPathExtent);
   8196           break;
   8197         }
   8198       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   8199       break;
   8200     }
   8201     case 'G':
   8202     case 'g':
   8203     {
   8204       if (LocaleCompare(keyword,"gravity") == 0)
   8205         {
   8206           ssize_t
   8207             gravity;
   8208 
   8209           gravity=ParseCommandOption(MagickGravityOptions,MagickFalse,value);
   8210           if (gravity < 0)
   8211             ThrowMSLException(OptionError,"UnrecognizedGravityType",value);
   8212           (void) SetImageOption(image_info,keyword,value);
   8213           break;
   8214         }
   8215       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   8216       break;
   8217     }
   8218     case 'I':
   8219     case 'i':
   8220     {
   8221       if (LocaleCompare(keyword,"id") == 0)
   8222         {
   8223           (void) SetImageProperty(attributes,keyword,value,exception);
   8224           break;
   8225         }
   8226       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   8227       break;
   8228     }
   8229     case 'M':
   8230     case 'm':
   8231     {
   8232       if (LocaleCompare(keyword,"magick") == 0)
   8233         {
   8234           (void) CopyMagickString(image_info->magick,value,MagickPathExtent);
   8235           break;
   8236         }
   8237       if (LocaleCompare(keyword,"mattecolor") == 0)
   8238         {
   8239           (void) QueryColorCompliance(value,AllCompliance,
   8240             &image_info->matte_color,exception);
   8241           break;
   8242         }
   8243       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   8244       break;
   8245     }
   8246     case 'P':
   8247     case 'p':
   8248     {
   8249       if (LocaleCompare(keyword,"pointsize") == 0)
   8250         {
   8251           image_info->pointsize=StringToDouble(value,(char **) NULL);
   8252           draw_info->pointsize=StringToDouble(value,(char **) NULL);
   8253           break;
   8254         }
   8255       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   8256       break;
   8257     }
   8258     case 'Q':
   8259     case 'q':
   8260     {
   8261       if (LocaleCompare(keyword,"quality") == 0)
   8262         {
   8263           image_info->quality=StringToLong(value);
   8264           if (image == (Image *) NULL)
   8265             break;
   8266           image->quality=StringToLong(value);
   8267           break;
   8268         }
   8269       break;
   8270     }
   8271     case 'S':
   8272     case 's':
   8273     {
   8274       if (LocaleCompare(keyword,"size") == 0)
   8275         {
   8276           (void) CloneString(&image_info->size,value);
   8277           break;
   8278         }
   8279       if (LocaleCompare(keyword,"stroke") == 0)
   8280         {
   8281           (void) QueryColorCompliance(value,AllCompliance,&draw_info->stroke,
   8282             exception);
   8283           (void) SetImageOption(image_info,keyword,value);
   8284           break;
   8285         }
   8286       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   8287       break;
   8288     }
   8289     default:
   8290     {
   8291       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
   8292       break;
   8293     }
   8294   }
   8295   return(MagickTrue);
   8296 }
   8297 #endif
   8298 
   8299 /*
   8301 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   8302 %                                                                             %
   8303 %                                                                             %
   8304 %                                                                             %
   8305 %   U n r e g i s t e r M S L I m a g e                                       %
   8306 %                                                                             %
   8307 %                                                                             %
   8308 %                                                                             %
   8309 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   8310 %
   8311 %  UnregisterMSLImage() removes format registrations made by the
   8312 %  MSL module from the list of supported formats.
   8313 %
   8314 %  The format of the UnregisterMSLImage method is:
   8315 %
   8316 %      UnregisterMSLImage(void)
   8317 %
   8318 */
   8319 ModuleExport void UnregisterMSLImage(void)
   8320 {
   8321   (void) UnregisterMagickInfo("MSL");
   8322 }
   8323 
   8324 #if defined(MAGICKCORE_XML_DELEGATE)
   8326 /*
   8327 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   8328 %                                                                             %
   8329 %                                                                             %
   8330 %                                                                             %
   8331 %   W r i t e M S L I m a g e                                                 %
   8332 %                                                                             %
   8333 %                                                                             %
   8334 %                                                                             %
   8335 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   8336 %
   8337 %  WriteMSLImage() writes an image to a file in MVG image format.
   8338 %
   8339 %  The format of the WriteMSLImage method is:
   8340 %
   8341 %      MagickBooleanType WriteMSLImage(const ImageInfo *image_info,
   8342 %        Image *image,ExceptionInfo *exception)
   8343 %
   8344 %  A description of each parameter follows.
   8345 %
   8346 %    o image_info: the image info.
   8347 %
   8348 %    o image:  The image.
   8349 %
   8350 %    o exception: return any errors or warnings in this structure.
   8351 %
   8352 */
   8353 static MagickBooleanType WriteMSLImage(const ImageInfo *image_info,Image *image,
   8354   ExceptionInfo *exception)
   8355 {
   8356   Image
   8357     *msl_image;
   8358 
   8359   MagickBooleanType
   8360     status;
   8361 
   8362   assert(image_info != (const ImageInfo *) NULL);
   8363   assert(image_info->signature == MagickCoreSignature);
   8364   assert(image != (Image *) NULL);
   8365   assert(image->signature == MagickCoreSignature);
   8366   if (image->debug != MagickFalse)
   8367     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
   8368   msl_image=CloneImage(image,0,0,MagickTrue,exception);
   8369   status=ProcessMSLScript(image_info,&msl_image,exception);
   8370   msl_image=DestroyImageList(msl_image);
   8371   return(status);
   8372 }
   8373 #endif
   8374