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