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