]> granicus.if.org Git - imagemagick/blob - coders/msl.c
03e081da7aac9084a537d8a5568172883beb00e1
[imagemagick] / coders / msl.c
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-2015 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 \f
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 \f
107 /*
108   Define Declatations.
109 */
110 #define ThrowMSLException(severity,tag,reason) \
111   (void) ThrowMagickException(msl_info->exception,GetMagickModule(),severity, \
112     tag,"`%s'",reason);
113 \f
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 \f
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 \f
168 #if defined(MAGICKCORE_XML_DELEGATE)
169 \f
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
201 static inline Image *GetImageCache(const ImageInfo *image_info,const char *path,
202   ExceptionInfo *exception)
203 {
204   char
205     key[MaxTextExtent];
206
207   ExceptionInfo
208     *sans_exception;
209
210   Image
211     *image;
212
213   ImageInfo
214     *read_info;
215
216   (void) FormatLocaleString(key,MaxTextExtent,"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,MaxTextExtent);
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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[MaxTextExtent],
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[MaxTextExtent];
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,MaxTextExtent,
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[MaxTextExtent];
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",MaxTextExtent);
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,MaxTextExtent);
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[MaxTextExtent];
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,TrueColorMatteType,
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 != BlendPixelTrait)
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,MaxTextExtent,
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[MaxTextExtent];
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                       CloneString(&draw_info->text,value);
2633                       break;
2634                     }
2635                   if (LocaleCompare(keyword,"translate") == 0)
2636                     {
2637                       flags=ParseGeometry(value,&geometry_info);
2638                       if ((flags & SigmaValue) == 0)
2639                         geometry_info.sigma=1.0;
2640                       affine.tx=geometry_info.rho;
2641                       affine.ty=geometry_info.sigma;
2642                       break;
2643                     }
2644                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2645                     keyword);
2646                   break;
2647                 }
2648                 case 'U':
2649                 case 'u':
2650                 {
2651                   if (LocaleCompare(keyword, "undercolor") == 0)
2652                     {
2653                       (void) QueryColorCompliance(value,AllCompliance,
2654                         &draw_info->undercolor,exception);
2655                       break;
2656                     }
2657                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2658                     keyword);
2659                   break;
2660                 }
2661                 case 'W':
2662                 case 'w':
2663                 {
2664                   if (LocaleCompare(keyword,"weight") == 0)
2665                     {
2666                       draw_info->weight=StringToLong(value);
2667                       break;
2668                     }
2669                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2670                     keyword);
2671                   break;
2672                 }
2673                 case 'X':
2674                 case 'x':
2675                 {
2676                   if (LocaleCompare(keyword,"x") == 0)
2677                     {
2678                       geometry.x=StringToLong(value);
2679                       break;
2680                     }
2681                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2682                     keyword);
2683                   break;
2684                 }
2685                 case 'Y':
2686                 case 'y':
2687                 {
2688                   if (LocaleCompare(keyword,"y") == 0)
2689                     {
2690                       geometry.y=StringToLong(value);
2691                       break;
2692                     }
2693                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2694                     keyword);
2695                   break;
2696                 }
2697                 default:
2698                 {
2699                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2700                     keyword);
2701                   break;
2702                 }
2703               }
2704             }
2705           (void) FormatLocaleString(text,MaxTextExtent,
2706             "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,(double)
2707             geometry.height,(double) geometry.x,(double) geometry.y);
2708           CloneString(&draw_info->geometry,text);
2709           draw_info->affine.sx=affine.sx*current.sx+affine.ry*current.rx;
2710           draw_info->affine.rx=affine.rx*current.sx+affine.sy*current.rx;
2711           draw_info->affine.ry=affine.sx*current.ry+affine.ry*current.sy;
2712           draw_info->affine.sy=affine.rx*current.ry+affine.sy*current.sy;
2713           draw_info->affine.tx=affine.sx*current.tx+affine.ry*current.ty+
2714             affine.tx;
2715           draw_info->affine.ty=affine.rx*current.tx+affine.sy*current.ty+
2716             affine.ty;
2717           (void) DrawImage(msl_info->image[n],draw_info,exception);
2718           draw_info=DestroyDrawInfo(draw_info);
2719           break;
2720         }
2721       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
2722     }
2723     case 'E':
2724     case 'e':
2725     {
2726       if (LocaleCompare((const char *) tag,"edge") == 0)
2727         {
2728           Image
2729             *edge_image;
2730
2731           /*
2732             Edge image.
2733           */
2734           if (msl_info->image[n] == (Image *) NULL)
2735             {
2736               ThrowMSLException(OptionError,"NoImagesDefined",
2737                 (const char *) tag);
2738               break;
2739             }
2740           if (attributes != (const xmlChar **) NULL)
2741             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2742             {
2743               keyword=(const char *) attributes[i++];
2744               attribute=InterpretImageProperties(msl_info->image_info[n],
2745                 msl_info->attributes[n],(const char *) attributes[i],
2746                 exception);
2747               CloneString(&value,attribute);
2748               switch (*keyword)
2749               {
2750                 case 'G':
2751                 case 'g':
2752                 {
2753                   if (LocaleCompare(keyword,"geometry") == 0)
2754                     {
2755                       flags=ParseGeometry(value,&geometry_info);
2756                       if ((flags & SigmaValue) == 0)
2757                         geometry_info.sigma=1.0;
2758                       break;
2759                     }
2760                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2761                     keyword);
2762                   break;
2763                 }
2764                 case 'R':
2765                 case 'r':
2766                 {
2767                   if (LocaleCompare(keyword,"radius") == 0)
2768                     {
2769                       geometry_info.rho=StringToDouble(value,(char **) NULL);
2770                       break;
2771                     }
2772                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2773                     keyword);
2774                   break;
2775                 }
2776                 default:
2777                 {
2778                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2779                     keyword);
2780                   break;
2781                 }
2782               }
2783             }
2784           edge_image=EdgeImage(msl_info->image[n],geometry_info.rho,
2785             msl_info->exception);
2786           if (edge_image == (Image *) NULL)
2787             break;
2788           msl_info->image[n]=DestroyImage(msl_info->image[n]);
2789           msl_info->image[n]=edge_image;
2790           break;
2791         }
2792       if (LocaleCompare((const char *) tag,"emboss") == 0)
2793         {
2794           Image
2795             *emboss_image;
2796
2797           /*
2798             Emboss image.
2799           */
2800           if (msl_info->image[n] == (Image *) NULL)
2801             {
2802               ThrowMSLException(OptionError,"NoImagesDefined",
2803                 (const char *) tag);
2804               break;
2805             }
2806           if (attributes != (const xmlChar **) NULL)
2807             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2808             {
2809               keyword=(const char *) attributes[i++];
2810               attribute=InterpretImageProperties(msl_info->image_info[n],
2811                 msl_info->attributes[n],(const char *) attributes[i],
2812                 exception);
2813               CloneString(&value,attribute);
2814               switch (*keyword)
2815               {
2816                 case 'G':
2817                 case 'g':
2818                 {
2819                   if (LocaleCompare(keyword,"geometry") == 0)
2820                     {
2821                       flags=ParseGeometry(value,&geometry_info);
2822                       if ((flags & SigmaValue) == 0)
2823                         geometry_info.sigma=1.0;
2824                       break;
2825                     }
2826                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2827                     keyword);
2828                   break;
2829                 }
2830                 case 'R':
2831                 case 'r':
2832                 {
2833                   if (LocaleCompare(keyword,"radius") == 0)
2834                     {
2835                       geometry_info.rho=StringToDouble(value,
2836                         (char **) NULL);
2837                       break;
2838                     }
2839                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2840                     keyword);
2841                   break;
2842                 }
2843                 case 'S':
2844                 case 's':
2845                 {
2846                   if (LocaleCompare(keyword,"sigma") == 0)
2847                     {
2848                       geometry_info.sigma=StringToLong(value);
2849                       break;
2850                     }
2851                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2852                     keyword);
2853                   break;
2854                 }
2855                 default:
2856                 {
2857                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2858                     keyword);
2859                   break;
2860                 }
2861               }
2862             }
2863           emboss_image=EmbossImage(msl_info->image[n],geometry_info.rho,
2864             geometry_info.sigma,msl_info->exception);
2865           if (emboss_image == (Image *) NULL)
2866             break;
2867           msl_info->image[n]=DestroyImage(msl_info->image[n]);
2868           msl_info->image[n]=emboss_image;
2869           break;
2870         }
2871       if (LocaleCompare((const char *) tag,"enhance") == 0)
2872         {
2873           Image
2874             *enhance_image;
2875
2876           /*
2877             Enhance image.
2878           */
2879           if (msl_info->image[n] == (Image *) NULL)
2880             {
2881               ThrowMSLException(OptionError,"NoImagesDefined",
2882                 (const char *) tag);
2883               break;
2884             }
2885           if (attributes != (const xmlChar **) NULL)
2886             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2887             {
2888               keyword=(const char *) attributes[i++];
2889               attribute=InterpretImageProperties(msl_info->image_info[n],
2890                 msl_info->attributes[n],(const char *) attributes[i],
2891                 exception);
2892               CloneString(&value,attribute);
2893               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
2894             }
2895           enhance_image=EnhanceImage(msl_info->image[n],
2896             msl_info->exception);
2897           if (enhance_image == (Image *) NULL)
2898             break;
2899           msl_info->image[n]=DestroyImage(msl_info->image[n]);
2900           msl_info->image[n]=enhance_image;
2901           break;
2902         }
2903       if (LocaleCompare((const char *) tag,"equalize") == 0)
2904         {
2905           /*
2906             Equalize image.
2907           */
2908           if (msl_info->image[n] == (Image *) NULL)
2909             {
2910               ThrowMSLException(OptionError,"NoImagesDefined",
2911                 (const char *) tag);
2912               break;
2913             }
2914           if (attributes != (const xmlChar **) NULL)
2915             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2916             {
2917               keyword=(const char *) attributes[i++];
2918               attribute=InterpretImageProperties(msl_info->image_info[n],
2919                 msl_info->attributes[n],(const char *) attributes[i],
2920                 exception);
2921               CloneString(&value,attribute);
2922               switch (*keyword)
2923               {
2924                 default:
2925                 {
2926                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
2927                     keyword);
2928                   break;
2929                 }
2930               }
2931             }
2932           (void) EqualizeImage(msl_info->image[n],
2933             msl_info->exception);
2934           break;
2935         }
2936       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
2937     }
2938     case 'F':
2939     case 'f':
2940     {
2941       if (LocaleCompare((const char *) tag, "flatten") == 0)
2942       {
2943         if (msl_info->image[n] == (Image *) NULL)
2944         {
2945           ThrowMSLException(OptionError,"NoImagesDefined",
2946             (const char *) tag);
2947           break;
2948         }
2949
2950         /* no attributes here */
2951
2952         /* process the image */
2953         {
2954           Image
2955             *newImage;
2956
2957           newImage=MergeImageLayers(msl_info->image[n],FlattenLayer,
2958             msl_info->exception);
2959           if (newImage == (Image *) NULL)
2960             break;
2961           msl_info->image[n]=DestroyImage(msl_info->image[n]);
2962           msl_info->image[n]=newImage;
2963           break;
2964         }
2965       }
2966       if (LocaleCompare((const char *) tag,"flip") == 0)
2967         {
2968           Image
2969             *flip_image;
2970
2971           /*
2972             Flip image.
2973           */
2974           if (msl_info->image[n] == (Image *) NULL)
2975             {
2976               ThrowMSLException(OptionError,"NoImagesDefined",
2977                 (const char *) tag);
2978               break;
2979             }
2980           if (attributes != (const xmlChar **) NULL)
2981             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2982             {
2983               keyword=(const char *) attributes[i++];
2984               attribute=InterpretImageProperties(msl_info->image_info[n],
2985                 msl_info->attributes[n],(const char *) attributes[i],
2986                 exception);
2987               CloneString(&value,attribute);
2988               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
2989             }
2990           flip_image=FlipImage(msl_info->image[n],
2991             msl_info->exception);
2992           if (flip_image == (Image *) NULL)
2993             break;
2994           msl_info->image[n]=DestroyImage(msl_info->image[n]);
2995           msl_info->image[n]=flip_image;
2996           break;
2997         }
2998       if (LocaleCompare((const char *) tag,"flop") == 0)
2999         {
3000           Image
3001             *flop_image;
3002
3003           /*
3004             Flop image.
3005           */
3006           if (msl_info->image[n] == (Image *) NULL)
3007             {
3008               ThrowMSLException(OptionError,"NoImagesDefined",
3009                 (const char *) tag);
3010               break;
3011             }
3012           if (attributes != (const xmlChar **) NULL)
3013             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3014             {
3015               keyword=(const char *) attributes[i++];
3016               attribute=InterpretImageProperties(msl_info->image_info[n],
3017                 msl_info->attributes[n],(const char *) attributes[i],
3018                 exception);
3019               CloneString(&value,attribute);
3020               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3021             }
3022           flop_image=FlopImage(msl_info->image[n],
3023             msl_info->exception);
3024           if (flop_image == (Image *) NULL)
3025             break;
3026           msl_info->image[n]=DestroyImage(msl_info->image[n]);
3027           msl_info->image[n]=flop_image;
3028           break;
3029         }
3030       if (LocaleCompare((const char *) tag,"frame") == 0)
3031         {
3032           FrameInfo
3033             frame_info;
3034
3035           Image
3036             *frame_image;
3037
3038           /*
3039             Frame image.
3040           */
3041           if (msl_info->image[n] == (Image *) NULL)
3042             {
3043               ThrowMSLException(OptionError,"NoImagesDefined",
3044                 (const char *) tag);
3045               break;
3046             }
3047           (void) ResetMagickMemory(&frame_info,0,sizeof(frame_info));
3048           SetGeometry(msl_info->image[n],&geometry);
3049           if (attributes != (const xmlChar **) NULL)
3050             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3051             {
3052               keyword=(const char *) attributes[i++];
3053               attribute=InterpretImageProperties(msl_info->image_info[n],
3054                 msl_info->attributes[n],(const char *) attributes[i],
3055                 exception);
3056               CloneString(&value,attribute);
3057               switch (*keyword)
3058               {
3059                 case 'C':
3060                 case 'c':
3061                 {
3062                   if (LocaleCompare(keyword,"compose") == 0)
3063                     {
3064                       option=ParseCommandOption(MagickComposeOptions,
3065                         MagickFalse,value);
3066                       if (option < 0)
3067                         ThrowMSLException(OptionError,"UnrecognizedComposeType",
3068                           value);
3069                       msl_info->image[n]->compose=(CompositeOperator) option;
3070                       break;
3071                     }
3072                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3073                     keyword);
3074                   break;
3075                 }
3076                 case 'F':
3077                 case 'f':
3078                 {
3079                   if (LocaleCompare(keyword, "fill") == 0)
3080                     {
3081                       (void) QueryColorCompliance(value,AllCompliance,
3082                         &msl_info->image[n]->matte_color,exception);
3083                       break;
3084                     }
3085                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3086                     keyword);
3087                   break;
3088                 }
3089                 case 'G':
3090                 case 'g':
3091                 {
3092                   if (LocaleCompare(keyword,"geometry") == 0)
3093                     {
3094                       flags=ParsePageGeometry(msl_info->image[n],value,
3095                         &geometry,exception);
3096                       if ((flags & HeightValue) == 0)
3097                         geometry.height=geometry.width;
3098                       frame_info.width=geometry.width;
3099                       frame_info.height=geometry.height;
3100                       frame_info.outer_bevel=geometry.x;
3101                       frame_info.inner_bevel=geometry.y;
3102                       break;
3103                     }
3104                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3105                     keyword);
3106                   break;
3107                 }
3108                 case 'H':
3109                 case 'h':
3110                 {
3111                   if (LocaleCompare(keyword,"height") == 0)
3112                     {
3113                       frame_info.height=StringToLong(value);
3114                       break;
3115                     }
3116                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3117                     keyword);
3118                   break;
3119                 }
3120                 case 'I':
3121                 case 'i':
3122                 {
3123                   if (LocaleCompare(keyword,"inner") == 0)
3124                     {
3125                       frame_info.inner_bevel=StringToLong(value);
3126                       break;
3127                     }
3128                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3129                     keyword);
3130                   break;
3131                 }
3132                 case 'O':
3133                 case 'o':
3134                 {
3135                   if (LocaleCompare(keyword,"outer") == 0)
3136                     {
3137                       frame_info.outer_bevel=StringToLong(value);
3138                       break;
3139                     }
3140                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3141                     keyword);
3142                   break;
3143                 }
3144                 case 'W':
3145                 case 'w':
3146                 {
3147                   if (LocaleCompare(keyword,"width") == 0)
3148                     {
3149                       frame_info.width=StringToLong(value);
3150                       break;
3151                     }
3152                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3153                     keyword);
3154                   break;
3155                 }
3156                 default:
3157                 {
3158                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3159                     keyword);
3160                   break;
3161                 }
3162               }
3163             }
3164           frame_info.x=(ssize_t) frame_info.width;
3165           frame_info.y=(ssize_t) frame_info.height;
3166           frame_info.width=msl_info->image[n]->columns+2*frame_info.x;
3167           frame_info.height=msl_info->image[n]->rows+2*frame_info.y;
3168           frame_image=FrameImage(msl_info->image[n],&frame_info,
3169             msl_info->image[n]->compose,msl_info->exception);
3170           if (frame_image == (Image *) NULL)
3171             break;
3172           msl_info->image[n]=DestroyImage(msl_info->image[n]);
3173           msl_info->image[n]=frame_image;
3174           break;
3175         }
3176       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3177     }
3178     case 'G':
3179     case 'g':
3180     {
3181       if (LocaleCompare((const char *) tag,"gamma") == 0)
3182         {
3183           char
3184             gamma[MaxTextExtent];
3185
3186           PixelInfo
3187             pixel;
3188
3189           /*
3190             Gamma image.
3191           */
3192           if (msl_info->image[n] == (Image *) NULL)
3193             {
3194               ThrowMSLException(OptionError,"NoImagesDefined",
3195                 (const char *) tag);
3196               break;
3197             }
3198           channel=UndefinedChannel;
3199           pixel.red=0.0;
3200           pixel.green=0.0;
3201           pixel.blue=0.0;
3202           *gamma='\0';
3203           if (attributes != (const xmlChar **) NULL)
3204             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3205             {
3206               keyword=(const char *) attributes[i++];
3207               attribute=InterpretImageProperties(msl_info->image_info[n],
3208                 msl_info->attributes[n],(const char *) attributes[i],
3209                 exception);
3210               CloneString(&value,attribute);
3211               switch (*keyword)
3212               {
3213                 case 'B':
3214                 case 'b':
3215                 {
3216                   if (LocaleCompare(keyword,"blue") == 0)
3217                     {
3218                       pixel.blue=StringToDouble(value,(char **) NULL);
3219                       break;
3220                     }
3221                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3222                     keyword);
3223                   break;
3224                 }
3225                 case 'C':
3226                 case 'c':
3227                 {
3228                   if (LocaleCompare(keyword,"channel") == 0)
3229                     {
3230                       option=ParseChannelOption(value);
3231                       if (option < 0)
3232                         ThrowMSLException(OptionError,"UnrecognizedChannelType",
3233                           value);
3234                       channel=(ChannelType) option;
3235                       break;
3236                     }
3237                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3238                     keyword);
3239                   break;
3240                 }
3241                 case 'G':
3242                 case 'g':
3243                 {
3244                   if (LocaleCompare(keyword,"gamma") == 0)
3245                     {
3246                       (void) CopyMagickString(gamma,value,MaxTextExtent);
3247                       break;
3248                     }
3249                   if (LocaleCompare(keyword,"green") == 0)
3250                     {
3251                       pixel.green=StringToDouble(value,(char **) NULL);
3252                       break;
3253                     }
3254                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3255                     keyword);
3256                   break;
3257                 }
3258                 case 'R':
3259                 case 'r':
3260                 {
3261                   if (LocaleCompare(keyword,"red") == 0)
3262                     {
3263                       pixel.red=StringToDouble(value,(char **) NULL);
3264                       break;
3265                     }
3266                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3267                     keyword);
3268                   break;
3269                 }
3270                 default:
3271                 {
3272                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3273                     keyword);
3274                   break;
3275                 }
3276               }
3277             }
3278           if (*gamma == '\0')
3279             (void) FormatLocaleString(gamma,MaxTextExtent,"%g,%g,%g",
3280               (double) pixel.red,(double) pixel.green,(double) pixel.blue);
3281           (void) GammaImage(msl_info->image[n],atof(gamma),
3282             msl_info->exception);
3283           break;
3284         }
3285       else if (LocaleCompare((const char *) tag,"get") == 0)
3286         {
3287           if (msl_info->image[n] == (Image *) NULL)
3288             {
3289               ThrowMSLException(OptionError,"NoImagesDefined",
3290                 (const char *) tag);
3291               break;
3292             }
3293           if (attributes == (const xmlChar **) NULL)
3294             break;
3295           for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3296           {
3297             keyword=(const char *) attributes[i++];
3298             CloneString(&value,(const char *) attributes[i]);
3299             (void) CopyMagickString(key,value,MaxTextExtent);
3300             switch (*keyword)
3301             {
3302               case 'H':
3303               case 'h':
3304               {
3305                 if (LocaleCompare(keyword,"height") == 0)
3306                   {
3307                     (void) FormatLocaleString(value,MaxTextExtent,"%.20g",
3308                       (double) msl_info->image[n]->rows);
3309                     (void) SetImageProperty(msl_info->attributes[n],key,value,
3310                       exception);
3311                     break;
3312                   }
3313                 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3314               }
3315               case 'W':
3316               case 'w':
3317               {
3318                 if (LocaleCompare(keyword,"width") == 0)
3319                   {
3320                     (void) FormatLocaleString(value,MaxTextExtent,"%.20g",
3321                       (double) msl_info->image[n]->columns);
3322                     (void) SetImageProperty(msl_info->attributes[n],key,value,
3323                       exception);
3324                     break;
3325                   }
3326                 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3327               }
3328               default:
3329               {
3330                 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3331                 break;
3332               }
3333             }
3334           }
3335           break;
3336         }
3337     else if (LocaleCompare((const char *) tag, "group") == 0)
3338     {
3339       msl_info->number_groups++;
3340       msl_info->group_info=(MSLGroupInfo *) ResizeQuantumMemory(
3341         msl_info->group_info,msl_info->number_groups+1UL,
3342         sizeof(*msl_info->group_info));
3343       break;
3344     }
3345       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3346     }
3347     case 'I':
3348     case 'i':
3349     {
3350       if (LocaleCompare((const char *) tag,"image") == 0)
3351         {
3352           MSLPushImage(msl_info,(Image *) NULL);
3353           if (attributes == (const xmlChar **) NULL)
3354             break;
3355           for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3356           {
3357             keyword=(const char *) attributes[i++];
3358             CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
3359               msl_info->attributes[n],(const char *) attributes[i],exception));
3360             switch (*keyword)
3361             {
3362               case 'C':
3363               case 'c':
3364               {
3365                 if (LocaleCompare(keyword,"color") == 0)
3366                   {
3367                     Image
3368                       *next_image;
3369
3370                     (void) CopyMagickString(msl_info->image_info[n]->filename,
3371                       "xc:",MaxTextExtent);
3372                     (void) ConcatenateMagickString(msl_info->image_info[n]->
3373                       filename,value,MaxTextExtent);
3374                     next_image=ReadImage(msl_info->image_info[n],exception);
3375                     CatchException(exception);
3376                     if (next_image == (Image *) NULL)
3377                       continue;
3378                     if (msl_info->image[n] == (Image *) NULL)
3379                       msl_info->image[n]=next_image;
3380                     else
3381                       {
3382                         register Image
3383                           *p;
3384
3385                         /*
3386                           Link image into image list.
3387                         */
3388                         p=msl_info->image[n];
3389                         while (p->next != (Image *) NULL)
3390                           p=GetNextImageInList(p);
3391                         next_image->previous=p;
3392                         p->next=next_image;
3393                       }
3394                     break;
3395                   }
3396                 (void) SetMSLAttributes(msl_info,keyword,value);
3397                 break;
3398               }
3399               default:
3400               {
3401                 (void) SetMSLAttributes(msl_info,keyword,value);
3402                 break;
3403               }
3404             }
3405           }
3406           break;
3407         }
3408       if (LocaleCompare((const char *) tag,"implode") == 0)
3409         {
3410           Image
3411             *implode_image;
3412
3413           /*
3414             Implode image.
3415           */
3416           if (msl_info->image[n] == (Image *) NULL)
3417             {
3418               ThrowMSLException(OptionError,"NoImagesDefined",
3419                 (const char *) tag);
3420               break;
3421             }
3422           if (attributes != (const xmlChar **) NULL)
3423             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3424             {
3425               keyword=(const char *) attributes[i++];
3426               attribute=InterpretImageProperties(msl_info->image_info[n],
3427                 msl_info->attributes[n],(const char *) attributes[i],
3428                 exception);
3429               CloneString(&value,attribute);
3430               switch (*keyword)
3431               {
3432                 case 'A':
3433                 case 'a':
3434                 {
3435                   if (LocaleCompare(keyword,"amount") == 0)
3436                     {
3437                       geometry_info.rho=StringToDouble(value,
3438                         (char **) NULL);
3439                       break;
3440                     }
3441                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3442                     keyword);
3443                   break;
3444                 }
3445                 case 'G':
3446                 case 'g':
3447                 {
3448                   if (LocaleCompare(keyword,"geometry") == 0)
3449                     {
3450                       flags=ParseGeometry(value,&geometry_info);
3451                       if ((flags & SigmaValue) == 0)
3452                         geometry_info.sigma=1.0;
3453                       break;
3454                     }
3455                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3456                     keyword);
3457                   break;
3458                 }
3459                 default:
3460                 {
3461                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3462                     keyword);
3463                   break;
3464                 }
3465               }
3466             }
3467           implode_image=ImplodeImage(msl_info->image[n],geometry_info.rho,
3468             msl_info->image[n]->interpolate,msl_info->exception);
3469           if (implode_image == (Image *) NULL)
3470             break;
3471           msl_info->image[n]=DestroyImage(msl_info->image[n]);
3472           msl_info->image[n]=implode_image;
3473           break;
3474         }
3475       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3476     }
3477     case 'L':
3478     case 'l':
3479     {
3480       if (LocaleCompare((const char *) tag,"label") == 0)
3481         break;
3482       if (LocaleCompare((const char *) tag, "level") == 0)
3483       {
3484         double
3485           levelBlack = 0, levelGamma = 1, levelWhite = QuantumRange;
3486
3487         if (msl_info->image[n] == (Image *) NULL)
3488         {
3489           ThrowMSLException(OptionError,"NoImagesDefined",
3490             (const char *) tag);
3491           break;
3492         }
3493         if (attributes == (const xmlChar **) NULL)
3494           break;
3495         for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3496         {
3497           keyword=(const char *) attributes[i++];
3498           CloneString(&value,(const char *) attributes[i]);
3499           (void) CopyMagickString(key,value,MaxTextExtent);
3500           switch (*keyword)
3501           {
3502             case 'B':
3503             case 'b':
3504             {
3505               if (LocaleCompare(keyword,"black") == 0)
3506               {
3507                 levelBlack = StringToDouble(value,(char **) NULL);
3508                 break;
3509               }
3510               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3511               break;
3512             }
3513             case 'G':
3514             case 'g':
3515             {
3516               if (LocaleCompare(keyword,"gamma") == 0)
3517               {
3518                 levelGamma = StringToDouble(value,(char **) NULL);
3519                 break;
3520               }
3521               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3522               break;
3523             }
3524             case 'W':
3525             case 'w':
3526             {
3527               if (LocaleCompare(keyword,"white") == 0)
3528               {
3529                 levelWhite = StringToDouble(value,(char **) NULL);
3530                 break;
3531               }
3532               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3533               break;
3534             }
3535             default:
3536             {
3537               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3538               break;
3539             }
3540           }
3541         }
3542
3543         /* process image */
3544         LevelImage(msl_info->image[n],levelBlack,levelWhite,levelGamma,
3545           msl_info->exception);
3546         break;
3547       }
3548     }
3549     case 'M':
3550     case 'm':
3551     {
3552       if (LocaleCompare((const char *) tag,"magnify") == 0)
3553         {
3554           Image
3555             *magnify_image;
3556
3557           /*
3558             Magnify image.
3559           */
3560           if (msl_info->image[n] == (Image *) NULL)
3561             {
3562               ThrowMSLException(OptionError,"NoImagesDefined",
3563                 (const char *) tag);
3564               break;
3565             }
3566           if (attributes != (const xmlChar **) NULL)
3567             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3568             {
3569               keyword=(const char *) attributes[i++];
3570               attribute=InterpretImageProperties(msl_info->image_info[n],
3571                 msl_info->attributes[n],(const char *) attributes[i],
3572                 exception);
3573               CloneString(&value,attribute);
3574               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3575             }
3576           magnify_image=MagnifyImage(msl_info->image[n],
3577             msl_info->exception);
3578           if (magnify_image == (Image *) NULL)
3579             break;
3580           msl_info->image[n]=DestroyImage(msl_info->image[n]);
3581           msl_info->image[n]=magnify_image;
3582           break;
3583         }
3584       if (LocaleCompare((const char *) tag,"map") == 0)
3585         {
3586           Image
3587             *affinity_image;
3588
3589           MagickBooleanType
3590             dither;
3591
3592           QuantizeInfo
3593             *quantize_info;
3594
3595           /*
3596             Map image.
3597           */
3598           if (msl_info->image[n] == (Image *) NULL)
3599             {
3600               ThrowMSLException(OptionError,"NoImagesDefined",
3601                 (const char *) tag);
3602               break;
3603             }
3604           affinity_image=NewImageList();
3605           dither=MagickFalse;
3606           if (attributes != (const xmlChar **) NULL)
3607             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3608             {
3609               keyword=(const char *) attributes[i++];
3610               attribute=InterpretImageProperties(msl_info->image_info[n],
3611                 msl_info->attributes[n],(const char *) attributes[i],
3612                 exception);
3613               CloneString(&value,attribute);
3614               switch (*keyword)
3615               {
3616                 case 'D':
3617                 case 'd':
3618                 {
3619                   if (LocaleCompare(keyword,"dither") == 0)
3620                     {
3621                       option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
3622                         value);
3623                       if (option < 0)
3624                         ThrowMSLException(OptionError,"UnrecognizedBooleanType",
3625                           value);
3626                       dither=(MagickBooleanType) option;
3627                       break;
3628                     }
3629                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3630                     keyword);
3631                   break;
3632                 }
3633                 case 'I':
3634                 case 'i':
3635                 {
3636                   if (LocaleCompare(keyword,"image") == 0)
3637                     for (j=0; j < msl_info->n; j++)
3638                     {
3639                       const char
3640                         *attribute;
3641
3642                       attribute=GetImageProperty(msl_info->attributes[j],"id",
3643                         exception);
3644                       if ((attribute != (const char *) NULL)  &&
3645                           (LocaleCompare(attribute,value) == 0))
3646                         {
3647                           affinity_image=CloneImage(msl_info->image[j],0,0,
3648                             MagickFalse,exception);
3649                           break;
3650                         }
3651                     }
3652                   break;
3653                 }
3654                 default:
3655                 {
3656                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3657                     keyword);
3658                   break;
3659                 }
3660               }
3661             }
3662           quantize_info=AcquireQuantizeInfo(msl_info->image_info[n]);
3663           quantize_info->dither_method=dither != MagickFalse ?
3664             RiemersmaDitherMethod : NoDitherMethod;
3665           (void) RemapImages(quantize_info,msl_info->image[n],
3666             affinity_image,exception);
3667           quantize_info=DestroyQuantizeInfo(quantize_info);
3668           affinity_image=DestroyImage(affinity_image);
3669           break;
3670         }
3671       if (LocaleCompare((const char *) tag,"matte-floodfill") == 0)
3672         {
3673           double
3674             opacity;
3675
3676           PixelInfo
3677             target;
3678
3679           PaintMethod
3680             paint_method;
3681
3682           /*
3683             Matte floodfill image.
3684           */
3685           opacity=0.0;
3686           if (msl_info->image[n] == (Image *) NULL)
3687             {
3688               ThrowMSLException(OptionError,"NoImagesDefined",
3689                 (const char *) tag);
3690               break;
3691             }
3692           SetGeometry(msl_info->image[n],&geometry);
3693           paint_method=FloodfillMethod;
3694           if (attributes != (const xmlChar **) NULL)
3695             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3696             {
3697               keyword=(const char *) attributes[i++];
3698               attribute=InterpretImageProperties(msl_info->image_info[n],
3699                 msl_info->attributes[n],(const char *) attributes[i],
3700                 exception);
3701               CloneString(&value,attribute);
3702               switch (*keyword)
3703               {
3704                 case 'B':
3705                 case 'b':
3706                 {
3707                   if (LocaleCompare(keyword,"bordercolor") == 0)
3708                     {
3709                       (void) QueryColorCompliance(value,AllCompliance,
3710                         &target,exception);
3711                       paint_method=FillToBorderMethod;
3712                       break;
3713                     }
3714                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3715                     keyword);
3716                   break;
3717                 }
3718                 case 'F':
3719                 case 'f':
3720                 {
3721                   if (LocaleCompare(keyword,"fuzz") == 0)
3722                     {
3723                       msl_info->image[n]->fuzz=StringToDouble(value,
3724                         (char **) NULL);
3725                       break;
3726                     }
3727                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3728                     keyword);
3729                   break;
3730                 }
3731                 case 'G':
3732                 case 'g':
3733                 {
3734                   if (LocaleCompare(keyword,"geometry") == 0)
3735                     {
3736                       flags=ParsePageGeometry(msl_info->image[n],value,
3737                         &geometry,exception);
3738                       if ((flags & HeightValue) == 0)
3739                         geometry.height=geometry.width;
3740                       (void) GetOneVirtualPixelInfo(msl_info->image[n],
3741                         TileVirtualPixelMethod,geometry.x,geometry.y,&target,
3742                         exception);
3743                       break;
3744                     }
3745                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3746                     keyword);
3747                   break;
3748                 }
3749                 case 'O':
3750                 case 'o':
3751                 {
3752                   if (LocaleCompare(keyword,"opacity") == 0)
3753                     {
3754                       opacity=StringToDouble(value,(char **) NULL);
3755                       break;
3756                     }
3757                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3758                     keyword);
3759                   break;
3760                 }
3761                 case 'X':
3762                 case 'x':
3763                 {
3764                   if (LocaleCompare(keyword,"x") == 0)
3765                     {
3766                       geometry.x=StringToLong(value);
3767                       (void) GetOneVirtualPixelInfo(msl_info->image[n],
3768                         TileVirtualPixelMethod,geometry.x,geometry.y,&target,
3769                         exception);
3770                       break;
3771                     }
3772                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3773                     keyword);
3774                   break;
3775                 }
3776                 case 'Y':
3777                 case 'y':
3778                 {
3779                   if (LocaleCompare(keyword,"y") == 0)
3780                     {
3781                       geometry.y=StringToLong(value);
3782                       (void) GetOneVirtualPixelInfo(msl_info->image[n],
3783                         TileVirtualPixelMethod,geometry.x,geometry.y,&target,
3784                         exception);
3785                       break;
3786                     }
3787                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3788                     keyword);
3789                   break;
3790                 }
3791                 default:
3792                 {
3793                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3794                     keyword);
3795                   break;
3796                 }
3797               }
3798             }
3799           draw_info=CloneDrawInfo(msl_info->image_info[n],
3800             msl_info->draw_info[n]);
3801           draw_info->fill.alpha=ClampToQuantum(opacity);
3802           channel_mask=SetImageChannelMask(msl_info->image[n],AlphaChannel);
3803           (void) FloodfillPaintImage(msl_info->image[n],draw_info,&target,
3804             geometry.x,geometry.y,paint_method == FloodfillMethod ?
3805             MagickFalse : MagickTrue,msl_info->exception);
3806           (void) SetPixelChannelMask(msl_info->image[n],channel_mask);
3807           draw_info=DestroyDrawInfo(draw_info);
3808           break;
3809         }
3810       if (LocaleCompare((const char *) tag,"median-filter") == 0)
3811         {
3812           Image
3813             *median_image;
3814
3815           /*
3816             Median-filter image.
3817           */
3818           if (msl_info->image[n] == (Image *) NULL)
3819             {
3820               ThrowMSLException(OptionError,"NoImagesDefined",
3821                 (const char *) tag);
3822               break;
3823             }
3824           if (attributes != (const xmlChar **) NULL)
3825             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3826             {
3827               keyword=(const char *) attributes[i++];
3828               attribute=InterpretImageProperties(msl_info->image_info[n],
3829                 msl_info->attributes[n],(const char *) attributes[i],
3830                 exception);
3831               CloneString(&value,attribute);
3832               switch (*keyword)
3833               {
3834                 case 'G':
3835                 case 'g':
3836                 {
3837                   if (LocaleCompare(keyword,"geometry") == 0)
3838                     {
3839                       flags=ParseGeometry(value,&geometry_info);
3840                       if ((flags & SigmaValue) == 0)
3841                         geometry_info.sigma=1.0;
3842                       break;
3843                     }
3844                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3845                     keyword);
3846                   break;
3847                 }
3848                 case 'R':
3849                 case 'r':
3850                 {
3851                   if (LocaleCompare(keyword,"radius") == 0)
3852                     {
3853                       geometry_info.rho=StringToDouble(value,
3854                         (char **) NULL);
3855                       break;
3856                     }
3857                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3858                     keyword);
3859                   break;
3860                 }
3861                 default:
3862                 {
3863                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3864                     keyword);
3865                   break;
3866                 }
3867               }
3868             }
3869           median_image=StatisticImage(msl_info->image[n],MedianStatistic,
3870             (size_t) geometry_info.rho,(size_t) geometry_info.sigma,
3871             msl_info->exception);
3872           if (median_image == (Image *) NULL)
3873             break;
3874           msl_info->image[n]=DestroyImage(msl_info->image[n]);
3875           msl_info->image[n]=median_image;
3876           break;
3877         }
3878       if (LocaleCompare((const char *) tag,"minify") == 0)
3879         {
3880           Image
3881             *minify_image;
3882
3883           /*
3884             Minify image.
3885           */
3886           if (msl_info->image[n] == (Image *) NULL)
3887             {
3888               ThrowMSLException(OptionError,"NoImagesDefined",
3889                 (const char *) tag);
3890               break;
3891             }
3892           if (attributes != (const xmlChar **) NULL)
3893             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3894             {
3895               keyword=(const char *) attributes[i++];
3896               attribute=InterpretImageProperties(msl_info->image_info[n],
3897                 msl_info->attributes[n],(const char *) attributes[i],
3898                 exception);
3899               CloneString(&value,attribute);
3900               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3901             }
3902           minify_image=MinifyImage(msl_info->image[n],
3903             msl_info->exception);
3904           if (minify_image == (Image *) NULL)
3905             break;
3906           msl_info->image[n]=DestroyImage(msl_info->image[n]);
3907           msl_info->image[n]=minify_image;
3908           break;
3909         }
3910       if (LocaleCompare((const char *) tag,"msl") == 0 )
3911         break;
3912       if (LocaleCompare((const char *) tag,"modulate") == 0)
3913         {
3914           char
3915             modulate[MaxTextExtent];
3916
3917           /*
3918             Modulate image.
3919           */
3920           if (msl_info->image[n] == (Image *) NULL)
3921             {
3922               ThrowMSLException(OptionError,"NoImagesDefined",
3923                 (const char *) tag);
3924               break;
3925             }
3926           geometry_info.rho=100.0;
3927           geometry_info.sigma=100.0;
3928           geometry_info.xi=100.0;
3929           if (attributes != (const xmlChar **) NULL)
3930             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3931             {
3932               keyword=(const char *) attributes[i++];
3933               attribute=InterpretImageProperties(msl_info->image_info[n],
3934                 msl_info->attributes[n],(const char *) attributes[i],
3935                 exception);
3936               CloneString(&value,attribute);
3937               switch (*keyword)
3938               {
3939                 case 'B':
3940                 case 'b':
3941                 {
3942                   if (LocaleCompare(keyword,"blackness") == 0)
3943                     {
3944                       geometry_info.rho=StringToDouble(value,
3945                         (char **) NULL);
3946                       break;
3947                     }
3948                   if (LocaleCompare(keyword,"brightness") == 0)
3949                     {
3950                       geometry_info.rho=StringToDouble(value,
3951                         (char **) NULL);
3952                       break;
3953                     }
3954                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3955                     keyword);
3956                   break;
3957                 }
3958                 case 'F':
3959                 case 'f':
3960                 {
3961                   if (LocaleCompare(keyword,"factor") == 0)
3962                     {
3963                       flags=ParseGeometry(value,&geometry_info);
3964                       break;
3965                     }
3966                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3967                     keyword);
3968                   break;
3969                 }
3970                 case 'H':
3971                 case 'h':
3972                 {
3973                   if (LocaleCompare(keyword,"hue") == 0)
3974                     {
3975                       geometry_info.xi=StringToDouble(value,
3976                         (char **) NULL);
3977                       break;
3978                     }
3979                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3980                     keyword);
3981                   break;
3982                 }
3983                 case 'L':
3984                 case 'l':
3985                 {
3986                   if (LocaleCompare(keyword,"lightness") == 0)
3987                     {
3988                       geometry_info.rho=StringToDouble(value,
3989                         (char **) NULL);
3990                       break;
3991                     }
3992                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
3993                     keyword);
3994                   break;
3995                 }
3996                 case 'S':
3997                 case 's':
3998                 {
3999                   if (LocaleCompare(keyword,"saturation") == 0)
4000                     {
4001                       geometry_info.sigma=StringToDouble(value,
4002                         (char **) NULL);
4003                       break;
4004                     }
4005                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4006                     keyword);
4007                   break;
4008                 }
4009                 case 'W':
4010                 case 'w':
4011                 {
4012                   if (LocaleCompare(keyword,"whiteness") == 0)
4013                     {
4014                       geometry_info.sigma=StringToDouble(value,
4015                         (char **) NULL);
4016                       break;
4017                     }
4018                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4019                     keyword);
4020                   break;
4021                 }
4022                 default:
4023                 {
4024                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4025                     keyword);
4026                   break;
4027                 }
4028               }
4029             }
4030           (void) FormatLocaleString(modulate,MaxTextExtent,"%g,%g,%g",
4031             geometry_info.rho,geometry_info.sigma,geometry_info.xi);
4032           (void) ModulateImage(msl_info->image[n],modulate,
4033             msl_info->exception);
4034           break;
4035         }
4036       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4037     }
4038     case 'N':
4039     case 'n':
4040     {
4041       if (LocaleCompare((const char *) tag,"negate") == 0)
4042         {
4043           MagickBooleanType
4044             gray;
4045
4046           /*
4047             Negate image.
4048           */
4049           if (msl_info->image[n] == (Image *) NULL)
4050             {
4051               ThrowMSLException(OptionError,"NoImagesDefined",
4052                 (const char *) tag);
4053               break;
4054             }
4055           gray=MagickFalse;
4056           if (attributes != (const xmlChar **) NULL)
4057             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4058             {
4059               keyword=(const char *) attributes[i++];
4060               attribute=InterpretImageProperties(msl_info->image_info[n],
4061                 msl_info->attributes[n],(const char *) attributes[i],
4062                 exception);
4063               CloneString(&value,attribute);
4064               switch (*keyword)
4065               {
4066                 case 'C':
4067                 case 'c':
4068                 {
4069                   if (LocaleCompare(keyword,"channel") == 0)
4070                     {
4071                       option=ParseChannelOption(value);
4072                       if (option < 0)
4073                         ThrowMSLException(OptionError,"UnrecognizedChannelType",
4074                           value);
4075                       channel=(ChannelType) option;
4076                       break;
4077                     }
4078                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4079                     keyword);
4080                   break;
4081                 }
4082                 case 'G':
4083                 case 'g':
4084                 {
4085                   if (LocaleCompare(keyword,"gray") == 0)
4086                     {
4087                       option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
4088                         value);
4089                       if (option < 0)
4090                         ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4091                           value);
4092                       gray=(MagickBooleanType) option;
4093                       break;
4094                     }
4095                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4096                     keyword);
4097                   break;
4098                 }
4099                 default:
4100                 {
4101                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4102                     keyword);
4103                   break;
4104                 }
4105               }
4106             }
4107           channel_mask=SetImageChannelMask(msl_info->image[n],channel);
4108           (void) NegateImage(msl_info->image[n],gray,
4109             msl_info->exception);
4110           (void) SetPixelChannelMask(msl_info->image[n],channel_mask);
4111           break;
4112         }
4113       if (LocaleCompare((const char *) tag,"normalize") == 0)
4114         {
4115           /*
4116             Normalize image.
4117           */
4118           if (msl_info->image[n] == (Image *) NULL)
4119             {
4120               ThrowMSLException(OptionError,"NoImagesDefined",
4121                 (const char *) tag);
4122               break;
4123             }
4124           if (attributes != (const xmlChar **) NULL)
4125             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4126             {
4127               keyword=(const char *) attributes[i++];
4128               attribute=InterpretImageProperties(msl_info->image_info[n],
4129                 msl_info->attributes[n],(const char *) attributes[i],
4130                 exception);
4131               CloneString(&value,attribute);
4132               switch (*keyword)
4133               {
4134                 case 'C':
4135                 case 'c':
4136                 {
4137                   if (LocaleCompare(keyword,"channel") == 0)
4138                     {
4139                       option=ParseChannelOption(value);
4140                       if (option < 0)
4141                         ThrowMSLException(OptionError,"UnrecognizedChannelType",
4142                           value);
4143                       channel=(ChannelType) option;
4144                       break;
4145                     }
4146                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4147                     keyword);
4148                   break;
4149                 }
4150                 default:
4151                 {
4152                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4153                     keyword);
4154                   break;
4155                 }
4156               }
4157             }
4158           (void) NormalizeImage(msl_info->image[n],
4159             msl_info->exception);
4160           break;
4161         }
4162       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4163     }
4164     case 'O':
4165     case 'o':
4166     {
4167       if (LocaleCompare((const char *) tag,"oil-paint") == 0)
4168         {
4169           Image
4170             *paint_image;
4171
4172           /*
4173             Oil-paint image.
4174           */
4175           if (msl_info->image[n] == (Image *) NULL)
4176             {
4177               ThrowMSLException(OptionError,"NoImagesDefined",
4178                 (const char *) tag);
4179               break;
4180             }
4181           if (attributes != (const xmlChar **) NULL)
4182             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4183             {
4184               keyword=(const char *) attributes[i++];
4185               attribute=InterpretImageProperties(msl_info->image_info[n],
4186                 msl_info->attributes[n],(const char *) attributes[i],
4187                 exception);
4188               CloneString(&value,attribute);
4189               switch (*keyword)
4190               {
4191                 case 'G':
4192                 case 'g':
4193                 {
4194                   if (LocaleCompare(keyword,"geometry") == 0)
4195                     {
4196                       flags=ParseGeometry(value,&geometry_info);
4197                       if ((flags & SigmaValue) == 0)
4198                         geometry_info.sigma=1.0;
4199                       break;
4200                     }
4201                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4202                     keyword);
4203                   break;
4204                 }
4205                 case 'R':
4206                 case 'r':
4207                 {
4208                   if (LocaleCompare(keyword,"radius") == 0)
4209                     {
4210                       geometry_info.rho=StringToDouble(value,
4211                         (char **) NULL);
4212                       break;
4213                     }
4214                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4215                     keyword);
4216                   break;
4217                 }
4218                 default:
4219                 {
4220                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4221                     keyword);
4222                   break;
4223                 }
4224               }
4225             }
4226           paint_image=OilPaintImage(msl_info->image[n],geometry_info.rho,
4227             geometry_info.sigma,msl_info->exception);
4228           if (paint_image == (Image *) NULL)
4229             break;
4230           msl_info->image[n]=DestroyImage(msl_info->image[n]);
4231           msl_info->image[n]=paint_image;
4232           break;
4233         }
4234       if (LocaleCompare((const char *) tag,"opaque") == 0)
4235         {
4236           PixelInfo
4237             fill_color,
4238             target;
4239
4240           /*
4241             Opaque image.
4242           */
4243           if (msl_info->image[n] == (Image *) NULL)
4244             {
4245               ThrowMSLException(OptionError,"NoImagesDefined",
4246                 (const char *) tag);
4247               break;
4248             }
4249           (void) QueryColorCompliance("none",AllCompliance,&target,
4250             exception);
4251           (void) QueryColorCompliance("none",AllCompliance,&fill_color,
4252             exception);
4253           if (attributes != (const xmlChar **) NULL)
4254             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4255             {
4256               keyword=(const char *) attributes[i++];
4257               attribute=InterpretImageProperties(msl_info->image_info[n],
4258                 msl_info->attributes[n],(const char *) attributes[i],
4259                 exception);
4260               CloneString(&value,attribute);
4261               switch (*keyword)
4262               {
4263                 case 'C':
4264                 case 'c':
4265                 {
4266                   if (LocaleCompare(keyword,"channel") == 0)
4267                     {
4268                       option=ParseChannelOption(value);
4269                       if (option < 0)
4270                         ThrowMSLException(OptionError,"UnrecognizedChannelType",
4271                           value);
4272                       channel=(ChannelType) option;
4273                       break;
4274                     }
4275                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4276                     keyword);
4277                   break;
4278                 }
4279                 case 'F':
4280                 case 'f':
4281                 {
4282                   if (LocaleCompare(keyword,"fill") == 0)
4283                     {
4284                       (void) QueryColorCompliance(value,AllCompliance,
4285                         &fill_color,exception);
4286                       break;
4287                     }
4288                   if (LocaleCompare(keyword,"fuzz") == 0)
4289                     {
4290                       msl_info->image[n]->fuzz=StringToDouble(value,
4291                         (char **) NULL);
4292                       break;
4293                     }
4294                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4295                     keyword);
4296                   break;
4297                 }
4298                 default:
4299                 {
4300                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4301                     keyword);
4302                   break;
4303                 }
4304               }
4305             }
4306           channel_mask=SetImageChannelMask(msl_info->image[n],channel);
4307           (void) OpaquePaintImage(msl_info->image[n],&target,&fill_color,
4308             MagickFalse,msl_info->exception);
4309           (void) SetPixelChannelMask(msl_info->image[n],channel_mask);
4310           break;
4311         }
4312       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4313     }
4314     case 'P':
4315     case 'p':
4316     {
4317       if (LocaleCompare((const char *) tag,"print") == 0)
4318         {
4319           if (attributes == (const xmlChar **) NULL)
4320             break;
4321           for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4322           {
4323             keyword=(const char *) attributes[i++];
4324             attribute=InterpretImageProperties(msl_info->image_info[n],
4325               msl_info->attributes[n],(const char *) attributes[i],
4326               exception);
4327             CloneString(&value,attribute);
4328             switch (*keyword)
4329             {
4330               case 'O':
4331               case 'o':
4332               {
4333                 if (LocaleCompare(keyword,"output") == 0)
4334                   {
4335                     (void) FormatLocaleFile(stdout,"%s",value);
4336                     break;
4337                   }
4338                 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
4339                 break;
4340               }
4341               default:
4342               {
4343                 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
4344                 break;
4345               }
4346             }
4347           }
4348           break;
4349         }
4350         if (LocaleCompare((const char *) tag, "profile") == 0)
4351           {
4352             if (msl_info->image[n] == (Image *) NULL)
4353               {
4354                 ThrowMSLException(OptionError,"NoImagesDefined",
4355                   (const char *) tag);
4356                 break;
4357               }
4358             if (attributes == (const xmlChar **) NULL)
4359               break;
4360             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4361             {
4362               const char
4363                 *name;
4364
4365               const StringInfo
4366                 *profile;
4367
4368               Image
4369                 *profile_image;
4370
4371               ImageInfo
4372                 *profile_info;
4373
4374               keyword=(const char *) attributes[i++];
4375               attribute=InterpretImageProperties(msl_info->image_info[n],
4376                 msl_info->attributes[n],(const char *) attributes[i],
4377                 exception);
4378               CloneString(&value,attribute);
4379               if (*keyword == '!')
4380                 {
4381                   /*
4382                     Remove a profile from the image.
4383                   */
4384                   (void) ProfileImage(msl_info->image[n],keyword,
4385                     (const unsigned char *) NULL,0,exception);
4386                   continue;
4387                 }
4388               /*
4389                 Associate a profile with the image.
4390               */
4391               profile_info=CloneImageInfo(msl_info->image_info[n]);
4392               profile=GetImageProfile(msl_info->image[n],"iptc");
4393               if (profile != (StringInfo *) NULL)
4394                 profile_info->profile=(void *) CloneStringInfo(profile);
4395               profile_image=GetImageCache(profile_info,keyword,exception);
4396               profile_info=DestroyImageInfo(profile_info);
4397               if (profile_image == (Image *) NULL)
4398                 {
4399                   char
4400                     name[MaxTextExtent],
4401                     filename[MaxTextExtent];
4402
4403                   register char
4404                     *p;
4405
4406                   StringInfo
4407                     *profile;
4408
4409                   (void) CopyMagickString(filename,keyword,MaxTextExtent);
4410                   (void) CopyMagickString(name,keyword,MaxTextExtent);
4411                   for (p=filename; *p != '\0'; p++)
4412                     if ((*p == ':') && (IsPathDirectory(keyword) < 0) &&
4413                         (IsPathAccessible(keyword) == MagickFalse))
4414                       {
4415                         register char
4416                           *q;
4417
4418                         /*
4419                           Look for profile name (e.g. name:profile).
4420                         */
4421                         (void) CopyMagickString(name,filename,(size_t)
4422                           (p-filename+1));
4423                         for (q=filename; *q != '\0'; q++)
4424                           *q=(*++p);
4425                         break;
4426                       }
4427                   profile=FileToStringInfo(filename,~0UL,exception);
4428                   if (profile != (StringInfo *) NULL)
4429                     {
4430                       (void) ProfileImage(msl_info->image[n],name,
4431                         GetStringInfoDatum(profile),(size_t)
4432                         GetStringInfoLength(profile),exception);
4433                       profile=DestroyStringInfo(profile);
4434                     }
4435                   continue;
4436                 }
4437               ResetImageProfileIterator(profile_image);
4438               name=GetNextImageProfile(profile_image);
4439               while (name != (const char *) NULL)
4440               {
4441                 profile=GetImageProfile(profile_image,name);
4442                 if (profile != (StringInfo *) NULL)
4443                   (void) ProfileImage(msl_info->image[n],name,
4444                     GetStringInfoDatum(profile),(size_t)
4445                     GetStringInfoLength(profile),exception);
4446                 name=GetNextImageProfile(profile_image);
4447               }
4448               profile_image=DestroyImage(profile_image);
4449             }
4450             break;
4451           }
4452       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4453     }
4454     case 'Q':
4455     case 'q':
4456     {
4457       if (LocaleCompare((const char *) tag,"quantize") == 0)
4458         {
4459           QuantizeInfo
4460             quantize_info;
4461
4462           /*
4463             Quantize image.
4464           */
4465           if (msl_info->image[n] == (Image *) NULL)
4466             {
4467               ThrowMSLException(OptionError,"NoImagesDefined",
4468                 (const char *) tag);
4469               break;
4470             }
4471           GetQuantizeInfo(&quantize_info);
4472           if (attributes != (const xmlChar **) NULL)
4473             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4474             {
4475               keyword=(const char *) attributes[i++];
4476               attribute=InterpretImageProperties(msl_info->image_info[n],
4477                 msl_info->attributes[n],(const char *) attributes[i],
4478                 exception);
4479               CloneString(&value,attribute);
4480               switch (*keyword)
4481               {
4482                 case 'C':
4483                 case 'c':
4484                 {
4485                   if (LocaleCompare(keyword,"colors") == 0)
4486                     {
4487                       quantize_info.number_colors=StringToLong(value);
4488                       break;
4489                     }
4490                   if (LocaleCompare(keyword,"colorspace") == 0)
4491                     {
4492                       option=ParseCommandOption(MagickColorspaceOptions,
4493                         MagickFalse,value);
4494                       if (option < 0)
4495                         ThrowMSLException(OptionError,
4496                           "UnrecognizedColorspaceType",value);
4497                       quantize_info.colorspace=(ColorspaceType) option;
4498                       break;
4499                     }
4500                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4501                     keyword);
4502                   break;
4503                 }
4504                 case 'D':
4505                 case 'd':
4506                 {
4507                   if (LocaleCompare(keyword,"dither") == 0)
4508                     {
4509                       option=ParseCommandOption(MagickDitherOptions,MagickFalse,
4510                         value);
4511                       if (option < 0)
4512                         ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4513                           value);
4514                       quantize_info.dither_method=(DitherMethod) option;
4515                       break;
4516                     }
4517                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4518                     keyword);
4519                   break;
4520                 }
4521                 case 'M':
4522                 case 'm':
4523                 {
4524                   if (LocaleCompare(keyword,"measure") == 0)
4525                     {
4526                       option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
4527                         value);
4528                       if (option < 0)
4529                         ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4530                           value);
4531                       quantize_info.measure_error=(MagickBooleanType) option;
4532                       break;
4533                     }
4534                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4535                     keyword);
4536                   break;
4537                 }
4538                 case 'T':
4539                 case 't':
4540                 {
4541                   if (LocaleCompare(keyword,"treedepth") == 0)
4542                     {
4543                       quantize_info.tree_depth=StringToLong(value);
4544                       break;
4545                     }
4546                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4547                     keyword);
4548                   break;
4549                 }
4550                 default:
4551                 {
4552                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4553                     keyword);
4554                   break;
4555                 }
4556               }
4557             }
4558           (void) QuantizeImage(&quantize_info,msl_info->image[n],exception);
4559           break;
4560         }
4561       if (LocaleCompare((const char *) tag,"query-font-metrics") == 0)
4562         {
4563           char
4564             text[MaxTextExtent];
4565
4566           MagickBooleanType
4567             status;
4568
4569           TypeMetric
4570             metrics;
4571
4572           /*
4573             Query font metrics.
4574           */
4575           draw_info=CloneDrawInfo(msl_info->image_info[n],
4576             msl_info->draw_info[n]);
4577           angle=0.0;
4578           current=draw_info->affine;
4579           GetAffineMatrix(&affine);
4580           if (attributes != (const xmlChar **) NULL)
4581             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4582             {
4583               keyword=(const char *) attributes[i++];
4584               attribute=InterpretImageProperties(msl_info->image_info[n],
4585                 msl_info->attributes[n],(const char *) attributes[i],
4586                 exception);
4587               CloneString(&value,attribute);
4588               switch (*keyword)
4589               {
4590                 case 'A':
4591                 case 'a':
4592                 {
4593                   if (LocaleCompare(keyword,"affine") == 0)
4594                     {
4595                       char
4596                         *p;
4597
4598                       p=value;
4599                       draw_info->affine.sx=StringToDouble(p,&p);
4600                       if (*p ==',')
4601                         p++;
4602                       draw_info->affine.rx=StringToDouble(p,&p);
4603                       if (*p ==',')
4604                         p++;
4605                       draw_info->affine.ry=StringToDouble(p,&p);
4606                       if (*p ==',')
4607                         p++;
4608                       draw_info->affine.sy=StringToDouble(p,&p);
4609                       if (*p ==',')
4610                         p++;
4611                       draw_info->affine.tx=StringToDouble(p,&p);
4612                       if (*p ==',')
4613                         p++;
4614                       draw_info->affine.ty=StringToDouble(p,&p);
4615                       break;
4616                     }
4617                   if (LocaleCompare(keyword,"align") == 0)
4618                     {
4619                       option=ParseCommandOption(MagickAlignOptions,MagickFalse,
4620                         value);
4621                       if (option < 0)
4622                         ThrowMSLException(OptionError,"UnrecognizedAlignType",
4623                           value);
4624                       draw_info->align=(AlignType) option;
4625                       break;
4626                     }
4627                   if (LocaleCompare(keyword,"antialias") == 0)
4628                     {
4629                       option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
4630                         value);
4631                       if (option < 0)
4632                         ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4633                           value);
4634                       draw_info->stroke_antialias=(MagickBooleanType) option;
4635                       draw_info->text_antialias=(MagickBooleanType) option;
4636                       break;
4637                     }
4638                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4639                     keyword);
4640                   break;
4641                 }
4642                 case 'D':
4643                 case 'd':
4644                 {
4645                   if (LocaleCompare(keyword,"density") == 0)
4646                     {
4647                       CloneString(&draw_info->density,value);
4648                       break;
4649                     }
4650                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4651                     keyword);
4652                   break;
4653                 }
4654                 case 'E':
4655                 case 'e':
4656                 {
4657                   if (LocaleCompare(keyword,"encoding") == 0)
4658                     {
4659                       CloneString(&draw_info->encoding,value);
4660                       break;
4661                     }
4662                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4663                     keyword);
4664                   break;
4665                 }
4666                 case 'F':
4667                 case 'f':
4668                 {
4669                   if (LocaleCompare(keyword, "fill") == 0)
4670                     {
4671                       (void) QueryColorCompliance(value,AllCompliance,
4672                         &draw_info->fill,exception);
4673                       break;
4674                     }
4675                   if (LocaleCompare(keyword,"family") == 0)
4676                     {
4677                       CloneString(&draw_info->family,value);
4678                       break;
4679                     }
4680                   if (LocaleCompare(keyword,"font") == 0)
4681                     {
4682                       CloneString(&draw_info->font,value);
4683                       break;
4684                     }
4685                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4686                     keyword);
4687                   break;
4688                 }
4689                 case 'G':
4690                 case 'g':
4691                 {
4692                   if (LocaleCompare(keyword,"geometry") == 0)
4693                     {
4694                       flags=ParsePageGeometry(msl_info->image[n],value,
4695                         &geometry,exception);
4696                       if ((flags & HeightValue) == 0)
4697                         geometry.height=geometry.width;
4698                       break;
4699                     }
4700                   if (LocaleCompare(keyword,"gravity") == 0)
4701                     {
4702                       option=ParseCommandOption(MagickGravityOptions,MagickFalse,
4703                         value);
4704                       if (option < 0)
4705                         ThrowMSLException(OptionError,"UnrecognizedGravityType",
4706                           value);
4707                       draw_info->gravity=(GravityType) option;
4708                       break;
4709                     }
4710                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4711                     keyword);
4712                   break;
4713                 }
4714                 case 'P':
4715                 case 'p':
4716                 {
4717                   if (LocaleCompare(keyword,"pointsize") == 0)
4718                     {
4719                       draw_info->pointsize=StringToDouble(value,
4720                         (char **) NULL);
4721                       break;
4722                     }
4723                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4724                     keyword);
4725                   break;
4726                 }
4727                 case 'R':
4728                 case 'r':
4729                 {
4730                   if (LocaleCompare(keyword,"rotate") == 0)
4731                     {
4732                       angle=StringToDouble(value,(char **) NULL);
4733                       affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
4734                       affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
4735                       affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
4736                       affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
4737                       break;
4738                     }
4739                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4740                     keyword);
4741                   break;
4742                 }
4743                 case 'S':
4744                 case 's':
4745                 {
4746                   if (LocaleCompare(keyword,"scale") == 0)
4747                     {
4748                       flags=ParseGeometry(value,&geometry_info);
4749                       if ((flags & SigmaValue) == 0)
4750                         geometry_info.sigma=1.0;
4751                       affine.sx=geometry_info.rho;
4752                       affine.sy=geometry_info.sigma;
4753                       break;
4754                     }
4755                   if (LocaleCompare(keyword,"skewX") == 0)
4756                     {
4757                       angle=StringToDouble(value,(char **) NULL);
4758                       affine.ry=cos(DegreesToRadians(fmod(angle,360.0)));
4759                       break;
4760                     }
4761                   if (LocaleCompare(keyword,"skewY") == 0)
4762                     {
4763                       angle=StringToDouble(value,(char **) NULL);
4764                       affine.rx=cos(DegreesToRadians(fmod(angle,360.0)));
4765                       break;
4766                     }
4767                   if (LocaleCompare(keyword,"stretch") == 0)
4768                     {
4769                       option=ParseCommandOption(MagickStretchOptions,
4770                         MagickFalse,value);
4771                       if (option < 0)
4772                         ThrowMSLException(OptionError,"UnrecognizedStretchType",
4773                           value);
4774                       draw_info->stretch=(StretchType) option;
4775                       break;
4776                     }
4777                   if (LocaleCompare(keyword, "stroke") == 0)
4778                     {
4779                       (void) QueryColorCompliance(value,AllCompliance,
4780                         &draw_info->stroke,exception);
4781                       break;
4782                     }
4783                   if (LocaleCompare(keyword,"strokewidth") == 0)
4784                     {
4785                       draw_info->stroke_width=StringToLong(value);
4786                       break;
4787                     }
4788                   if (LocaleCompare(keyword,"style") == 0)
4789                     {
4790                       option=ParseCommandOption(MagickStyleOptions,MagickFalse,
4791                         value);
4792                       if (option < 0)
4793                         ThrowMSLException(OptionError,"UnrecognizedStyleType",
4794                           value);
4795                       draw_info->style=(StyleType) option;
4796                       break;
4797                     }
4798                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4799                     keyword);
4800                   break;
4801                 }
4802                 case 'T':
4803                 case 't':
4804                 {
4805                   if (LocaleCompare(keyword,"text") == 0)
4806                     {
4807                       CloneString(&draw_info->text,value);
4808                       break;
4809                     }
4810                   if (LocaleCompare(keyword,"translate") == 0)
4811                     {
4812                       flags=ParseGeometry(value,&geometry_info);
4813                       if ((flags & SigmaValue) == 0)
4814                         geometry_info.sigma=1.0;
4815                       affine.tx=geometry_info.rho;
4816                       affine.ty=geometry_info.sigma;
4817                       break;
4818                     }
4819                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4820                     keyword);
4821                   break;
4822                 }
4823                 case 'U':
4824                 case 'u':
4825                 {
4826                   if (LocaleCompare(keyword, "undercolor") == 0)
4827                     {
4828                       (void) QueryColorCompliance(value,AllCompliance,
4829                         &draw_info->undercolor,exception);
4830                       break;
4831                     }
4832                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4833                     keyword);
4834                   break;
4835                 }
4836                 case 'W':
4837                 case 'w':
4838                 {
4839                   if (LocaleCompare(keyword,"weight") == 0)
4840                     {
4841                       draw_info->weight=StringToLong(value);
4842                       break;
4843                     }
4844                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4845                     keyword);
4846                   break;
4847                 }
4848                 case 'X':
4849                 case 'x':
4850                 {
4851                   if (LocaleCompare(keyword,"x") == 0)
4852                     {
4853                       geometry.x=StringToLong(value);
4854                       break;
4855                     }
4856                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4857                     keyword);
4858                   break;
4859                 }
4860                 case 'Y':
4861                 case 'y':
4862                 {
4863                   if (LocaleCompare(keyword,"y") == 0)
4864                     {
4865                       geometry.y=StringToLong(value);
4866                       break;
4867                     }
4868                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4869                     keyword);
4870                   break;
4871                 }
4872                 default:
4873                 {
4874                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4875                     keyword);
4876                   break;
4877                 }
4878               }
4879             }
4880           (void) FormatLocaleString(text,MaxTextExtent,
4881             "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,(double)
4882             geometry.height,(double) geometry.x,(double) geometry.y);
4883           CloneString(&draw_info->geometry,text);
4884           draw_info->affine.sx=affine.sx*current.sx+affine.ry*current.rx;
4885           draw_info->affine.rx=affine.rx*current.sx+affine.sy*current.rx;
4886           draw_info->affine.ry=affine.sx*current.ry+affine.ry*current.sy;
4887           draw_info->affine.sy=affine.rx*current.ry+affine.sy*current.sy;
4888           draw_info->affine.tx=affine.sx*current.tx+affine.ry*current.ty+
4889             affine.tx;
4890           draw_info->affine.ty=affine.rx*current.tx+affine.sy*current.ty+
4891             affine.ty;
4892           status=GetTypeMetrics(msl_info->attributes[n],draw_info,&metrics,
4893             msl_info->exception);
4894           if (status != MagickFalse)
4895             {
4896               Image
4897                 *image;
4898
4899               image=msl_info->attributes[n];
4900               FormatImageProperty(image,"msl:font-metrics.pixels_per_em.x",
4901                 "%g",metrics.pixels_per_em.x);
4902               FormatImageProperty(image,"msl:font-metrics.pixels_per_em.y",
4903                 "%g",metrics.pixels_per_em.y);
4904               FormatImageProperty(image,"msl:font-metrics.ascent","%g",
4905                 metrics.ascent);
4906               FormatImageProperty(image,"msl:font-metrics.descent","%g",
4907                 metrics.descent);
4908               FormatImageProperty(image,"msl:font-metrics.width","%g",
4909                 metrics.width);
4910               FormatImageProperty(image,"msl:font-metrics.height","%g",
4911                 metrics.height);
4912               FormatImageProperty(image,"msl:font-metrics.max_advance","%g",
4913                 metrics.max_advance);
4914               FormatImageProperty(image,"msl:font-metrics.bounds.x1","%g",
4915                 metrics.bounds.x1);
4916               FormatImageProperty(image,"msl:font-metrics.bounds.y1","%g",
4917                 metrics.bounds.y1);
4918               FormatImageProperty(image,"msl:font-metrics.bounds.x2","%g",
4919                 metrics.bounds.x2);
4920               FormatImageProperty(image,"msl:font-metrics.bounds.y2","%g",
4921                 metrics.bounds.y2);
4922               FormatImageProperty(image,"msl:font-metrics.origin.x","%g",
4923                 metrics.origin.x);
4924               FormatImageProperty(image,"msl:font-metrics.origin.y","%g",
4925                 metrics.origin.y);
4926             }
4927           draw_info=DestroyDrawInfo(draw_info);
4928           break;
4929         }
4930       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4931     }
4932     case 'R':
4933     case 'r':
4934     {
4935       if (LocaleCompare((const char *) tag,"raise") == 0)
4936         {
4937           MagickBooleanType
4938             raise;
4939
4940           /*
4941             Raise image.
4942           */
4943           if (msl_info->image[n] == (Image *) NULL)
4944             {
4945               ThrowMSLException(OptionError,"NoImagesDefined",
4946                 (const char *) tag);
4947               break;
4948             }
4949           raise=MagickFalse;
4950           SetGeometry(msl_info->image[n],&geometry);
4951           if (attributes != (const xmlChar **) NULL)
4952             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4953             {
4954               keyword=(const char *) attributes[i++];
4955               attribute=InterpretImageProperties(msl_info->image_info[n],
4956                 msl_info->attributes[n],(const char *) attributes[i],
4957                 exception);
4958               CloneString(&value,attribute);
4959               switch (*keyword)
4960               {
4961                 case 'G':
4962                 case 'g':
4963                 {
4964                   if (LocaleCompare(keyword,"geometry") == 0)
4965                     {
4966                       flags=ParsePageGeometry(msl_info->image[n],value,
4967                         &geometry,exception);
4968                       if ((flags & HeightValue) == 0)
4969                         geometry.height=geometry.width;
4970                       break;
4971                     }
4972                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4973                     keyword);
4974                   break;
4975                 }
4976                 case 'H':
4977                 case 'h':
4978                 {
4979                   if (LocaleCompare(keyword,"height") == 0)
4980                     {
4981                       geometry.height=StringToLong(value);
4982                       break;
4983                     }
4984                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
4985                     keyword);
4986                   break;
4987                 }
4988                 case 'R':
4989                 case 'r':
4990                 {
4991                   if (LocaleCompare(keyword,"raise") == 0)
4992                     {
4993                       option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
4994                         value);
4995                       if (option < 0)
4996                         ThrowMSLException(OptionError,"UnrecognizedNoiseType",
4997                           value);
4998                       raise=(MagickBooleanType) option;
4999                       break;
5000                     }
5001                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5002                     keyword);
5003                   break;
5004                 }
5005                 case 'W':
5006                 case 'w':
5007                 {
5008                   if (LocaleCompare(keyword,"width") == 0)
5009                     {
5010                       geometry.width=StringToLong(value);
5011                       break;
5012                     }
5013                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5014                     keyword);
5015                   break;
5016                 }
5017                 default:
5018                 {
5019                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5020                     keyword);
5021                   break;
5022                 }
5023               }
5024             }
5025           (void) RaiseImage(msl_info->image[n],&geometry,raise,
5026             msl_info->exception);
5027           break;
5028         }
5029       if (LocaleCompare((const char *) tag,"read") == 0)
5030         {
5031           if (attributes == (const xmlChar **) NULL)
5032             break;
5033           for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5034           {
5035             keyword=(const char *) attributes[i++];
5036             CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
5037               msl_info->attributes[n],(const char *) attributes[i],exception));
5038             switch (*keyword)
5039             {
5040               case 'F':
5041               case 'f':
5042               {
5043                 if (LocaleCompare(keyword,"filename") == 0)
5044                   {
5045                     Image
5046                       *image;
5047
5048                     (void) CopyMagickString(msl_info->image_info[n]->filename,
5049                       value,MaxTextExtent);
5050                     image=ReadImage(msl_info->image_info[n],exception);
5051                     CatchException(exception);
5052                     if (image == (Image *) NULL)
5053                       continue;
5054                     AppendImageToList(&msl_info->image[n],image);
5055                     break;
5056                   }
5057                 (void) SetMSLAttributes(msl_info,keyword,value);
5058                 break;
5059               }
5060               default:
5061               {
5062                 (void) SetMSLAttributes(msl_info,keyword,value);
5063                 break;
5064               }
5065             }
5066           }
5067           break;
5068         }
5069       if (LocaleCompare((const char *) tag,"reduce-noise") == 0)
5070         {
5071           Image
5072             *paint_image;
5073
5074           /*
5075             Reduce-noise image.
5076           */
5077           if (msl_info->image[n] == (Image *) NULL)
5078             {
5079               ThrowMSLException(OptionError,"NoImagesDefined",
5080                 (const char *) tag);
5081               break;
5082             }
5083           if (attributes != (const xmlChar **) NULL)
5084             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5085             {
5086               keyword=(const char *) attributes[i++];
5087               attribute=InterpretImageProperties(msl_info->image_info[n],
5088                 msl_info->attributes[n],(const char *) attributes[i],
5089                 exception);
5090               CloneString(&value,attribute);
5091               switch (*keyword)
5092               {
5093                 case 'G':
5094                 case 'g':
5095                 {
5096                   if (LocaleCompare(keyword,"geometry") == 0)
5097                     {
5098                       flags=ParseGeometry(value,&geometry_info);
5099                       if ((flags & SigmaValue) == 0)
5100                         geometry_info.sigma=1.0;
5101                       break;
5102                     }
5103                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5104                     keyword);
5105                   break;
5106                 }
5107                 case 'R':
5108                 case 'r':
5109                 {
5110                   if (LocaleCompare(keyword,"radius") == 0)
5111                     {
5112                       geometry_info.rho=StringToDouble(value,
5113                         (char **) NULL);
5114                       break;
5115                     }
5116                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5117                     keyword);
5118                   break;
5119                 }
5120                 default:
5121                 {
5122                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5123                     keyword);
5124                   break;
5125                 }
5126               }
5127             }
5128           paint_image=StatisticImage(msl_info->image[n],NonpeakStatistic,
5129             (size_t) geometry_info.rho,(size_t) geometry_info.sigma,
5130             msl_info->exception);
5131           if (paint_image == (Image *) NULL)
5132             break;
5133           msl_info->image[n]=DestroyImage(msl_info->image[n]);
5134           msl_info->image[n]=paint_image;
5135           break;
5136         }
5137       else if (LocaleCompare((const char *) tag,"repage") == 0)
5138       {
5139         /* init the values */
5140         width=msl_info->image[n]->page.width;
5141         height=msl_info->image[n]->page.height;
5142         x=msl_info->image[n]->page.x;
5143         y=msl_info->image[n]->page.y;
5144
5145         if (msl_info->image[n] == (Image *) NULL)
5146         {
5147           ThrowMSLException(OptionError,"NoImagesDefined",
5148             (const char *) tag);
5149           break;
5150         }
5151         if (attributes == (const xmlChar **) NULL)
5152         break;
5153         for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5154         {
5155         keyword=(const char *) attributes[i++];
5156         CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
5157           msl_info->attributes[n],(const char *) attributes[i],exception));
5158         switch (*keyword)
5159         {
5160           case 'G':
5161           case 'g':
5162           {
5163           if (LocaleCompare(keyword,"geometry") == 0)
5164             {
5165               int
5166                 flags;
5167
5168               RectangleInfo
5169                 geometry;
5170
5171             flags=ParseAbsoluteGeometry(value,&geometry);
5172             if ((flags & WidthValue) != 0)
5173               {
5174                 if ((flags & HeightValue) == 0)
5175                   geometry.height=geometry.width;
5176                 width=geometry.width;
5177                 height=geometry.height;
5178               }
5179             if ((flags & AspectValue) != 0)
5180               {
5181                 if ((flags & XValue) != 0)
5182                   x+=geometry.x;
5183                 if ((flags & YValue) != 0)
5184                   y+=geometry.y;
5185               }
5186             else
5187               {
5188                 if ((flags & XValue) != 0)
5189                   {
5190                     x=geometry.x;
5191                     if ((width == 0) && (geometry.x > 0))
5192                       width=msl_info->image[n]->columns+geometry.x;
5193                   }
5194                 if ((flags & YValue) != 0)
5195                   {
5196                     y=geometry.y;
5197                     if ((height == 0) && (geometry.y > 0))
5198                       height=msl_info->image[n]->rows+geometry.y;
5199                   }
5200               }
5201             break;
5202             }
5203           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5204           break;
5205           }
5206           case 'H':
5207           case 'h':
5208           {
5209           if (LocaleCompare(keyword,"height") == 0)
5210             {
5211             height = StringToLong( value );
5212             break;
5213             }
5214           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5215           break;
5216           }
5217           case 'W':
5218           case 'w':
5219           {
5220           if (LocaleCompare(keyword,"width") == 0)
5221             {
5222             width = StringToLong( value );
5223             break;
5224             }
5225           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5226           break;
5227           }
5228           case 'X':
5229           case 'x':
5230           {
5231           if (LocaleCompare(keyword,"x") == 0)
5232             {
5233             x = StringToLong( value );
5234             break;
5235             }
5236           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5237           break;
5238           }
5239           case 'Y':
5240           case 'y':
5241           {
5242           if (LocaleCompare(keyword,"y") == 0)
5243             {
5244             y = StringToLong( value );
5245             break;
5246             }
5247           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5248           break;
5249           }
5250           default:
5251           {
5252           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5253           break;
5254           }
5255         }
5256         }
5257
5258          msl_info->image[n]->page.width=width;
5259          msl_info->image[n]->page.height=height;
5260          msl_info->image[n]->page.x=x;
5261          msl_info->image[n]->page.y=y;
5262         break;
5263       }
5264     else if (LocaleCompare((const char *) tag,"resample") == 0)
5265     {
5266       double
5267         x_resolution,
5268         y_resolution;
5269
5270       if (msl_info->image[n] == (Image *) NULL)
5271         {
5272           ThrowMSLException(OptionError,"NoImagesDefined",
5273             (const char *) tag);
5274           break;
5275         }
5276       if (attributes == (const xmlChar **) NULL)
5277         break;
5278       x_resolution=DefaultResolution;
5279       y_resolution=DefaultResolution;
5280       for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5281       {
5282         keyword=(const char *) attributes[i++];
5283         CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
5284           msl_info->attributes[n],(const char *) attributes[i],exception));
5285         switch (*keyword)
5286         {
5287           case 'G':
5288           case 'g':
5289           {
5290             if (LocaleCompare(keyword,"geometry") == 0)
5291               {
5292                 ssize_t
5293                   flags;
5294
5295                 flags=ParseGeometry(value,&geometry_info);
5296                 if ((flags & SigmaValue) == 0)
5297                   geometry_info.sigma*=geometry_info.rho;
5298                 x_resolution=geometry_info.rho;
5299                 y_resolution=geometry_info.sigma;
5300                 break;
5301               }
5302             ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5303             break;
5304           }
5305           case 'X':
5306           case 'x':
5307           {
5308             if (LocaleCompare(keyword,"x-resolution") == 0)
5309               {
5310                 x_resolution=StringToDouble(value,(char **) NULL);
5311                 break;
5312               }
5313             ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5314             break;
5315           }
5316           case 'Y':
5317           case 'y':
5318           {
5319             if (LocaleCompare(keyword,"y-resolution") == 0)
5320               {
5321                 y_resolution=StringToDouble(value,(char **) NULL);
5322                 break;
5323               }
5324             ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5325             break;
5326           }
5327           default:
5328           {
5329             ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5330             break;
5331           }
5332         }
5333       }
5334       /*
5335         Resample image.
5336       */
5337       {
5338         double
5339           factor;
5340
5341         Image
5342           *resample_image;
5343
5344         factor=1.0;
5345         if (msl_info->image[n]->units == PixelsPerCentimeterResolution)
5346           factor=2.54;
5347         width=(size_t) (x_resolution*msl_info->image[n]->columns/
5348           (factor*(msl_info->image[n]->resolution.x == 0.0 ? DefaultResolution :
5349           msl_info->image[n]->resolution.x))+0.5);
5350         height=(size_t) (y_resolution*msl_info->image[n]->rows/
5351           (factor*(msl_info->image[n]->resolution.y == 0.0 ? DefaultResolution :
5352           msl_info->image[n]->resolution.y))+0.5);
5353         resample_image=ResizeImage(msl_info->image[n],width,height,
5354           msl_info->image[n]->filter,msl_info->exception);
5355         if (resample_image == (Image *) NULL)
5356           break;
5357         msl_info->image[n]=DestroyImage(msl_info->image[n]);
5358         msl_info->image[n]=resample_image;
5359       }
5360       break;
5361     }
5362       if (LocaleCompare((const char *) tag,"resize") == 0)
5363         {
5364           FilterTypes
5365             filter;
5366
5367           Image
5368             *resize_image;
5369
5370           /*
5371             Resize image.
5372           */
5373           if (msl_info->image[n] == (Image *) NULL)
5374             {
5375               ThrowMSLException(OptionError,"NoImagesDefined",
5376                 (const char *) tag);
5377               break;
5378             }
5379           filter=UndefinedFilter;
5380           if (attributes != (const xmlChar **) NULL)
5381             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5382             {
5383               keyword=(const char *) attributes[i++];
5384               attribute=InterpretImageProperties(msl_info->image_info[n],
5385                 msl_info->attributes[n],(const char *) attributes[i],
5386                 exception);
5387               CloneString(&value,attribute);
5388               switch (*keyword)
5389               {
5390                 case 'F':
5391                 case 'f':
5392                 {
5393                   if (LocaleCompare(keyword,"filter") == 0)
5394                     {
5395                       option=ParseCommandOption(MagickFilterOptions,MagickFalse,
5396                         value);
5397                       if (option < 0)
5398                         ThrowMSLException(OptionError,"UnrecognizedNoiseType",
5399                           value);
5400                       filter=(FilterTypes) option;
5401                       break;
5402                     }
5403                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5404                     keyword);
5405                   break;
5406                 }
5407                 case 'G':
5408                 case 'g':
5409                 {
5410                   if (LocaleCompare(keyword,"geometry") == 0)
5411                     {
5412                       flags=ParseRegionGeometry(msl_info->image[n],value,
5413                         &geometry,exception);
5414                       break;
5415                     }
5416                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5417                     keyword);
5418                   break;
5419                 }
5420                 case 'H':
5421                 case 'h':
5422                 {
5423                   if (LocaleCompare(keyword,"height") == 0)
5424                     {
5425                       geometry.height=StringToUnsignedLong(value);
5426                       break;
5427                     }
5428                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5429                     keyword);
5430                   break;
5431                 }
5432                 case 'W':
5433                 case 'w':
5434                 {
5435                   if (LocaleCompare(keyword,"width") == 0)
5436                     {
5437                       geometry.width=StringToLong(value);
5438                       break;
5439                     }
5440                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5441                     keyword);
5442                   break;
5443                 }
5444                 default:
5445                 {
5446                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5447                     keyword);
5448                   break;
5449                 }
5450               }
5451             }
5452           resize_image=ResizeImage(msl_info->image[n],geometry.width,
5453             geometry.height,filter,msl_info->exception);
5454           if (resize_image == (Image *) NULL)
5455             break;
5456           msl_info->image[n]=DestroyImage(msl_info->image[n]);
5457           msl_info->image[n]=resize_image;
5458           break;
5459         }
5460       if (LocaleCompare((const char *) tag,"roll") == 0)
5461         {
5462           Image
5463             *roll_image;
5464
5465           /*
5466             Roll image.
5467           */
5468           if (msl_info->image[n] == (Image *) NULL)
5469             {
5470               ThrowMSLException(OptionError,"NoImagesDefined",
5471                 (const char *) tag);
5472               break;
5473             }
5474           SetGeometry(msl_info->image[n],&geometry);
5475           if (attributes != (const xmlChar **) NULL)
5476             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5477             {
5478               keyword=(const char *) attributes[i++];
5479               attribute=InterpretImageProperties(msl_info->image_info[n],
5480                 msl_info->attributes[n],(const char *) attributes[i],
5481                 exception);
5482               CloneString(&value,attribute);
5483               switch (*keyword)
5484               {
5485                 case 'G':
5486                 case 'g':
5487                 {
5488                   if (LocaleCompare(keyword,"geometry") == 0)
5489                     {
5490                       flags=ParsePageGeometry(msl_info->image[n],value,
5491                         &geometry,exception);
5492                       if ((flags & HeightValue) == 0)
5493                         geometry.height=geometry.width;
5494                       break;
5495                     }
5496                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5497                     keyword);
5498                   break;
5499                 }
5500                 case 'X':
5501                 case 'x':
5502                 {
5503                   if (LocaleCompare(keyword,"x") == 0)
5504                     {
5505                       geometry.x=StringToLong(value);
5506                       break;
5507                     }
5508                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5509                     keyword);
5510                   break;
5511                 }
5512                 case 'Y':
5513                 case 'y':
5514                 {
5515                   if (LocaleCompare(keyword,"y") == 0)
5516                     {
5517                       geometry.y=StringToLong(value);
5518                       break;
5519                     }
5520                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5521                     keyword);
5522                   break;
5523                 }
5524                 default:
5525                 {
5526                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5527                     keyword);
5528                   break;
5529                 }
5530               }
5531             }
5532           roll_image=RollImage(msl_info->image[n],geometry.x,geometry.y,
5533             msl_info->exception);
5534           if (roll_image == (Image *) NULL)
5535             break;
5536           msl_info->image[n]=DestroyImage(msl_info->image[n]);
5537           msl_info->image[n]=roll_image;
5538           break;
5539         }
5540       else if (LocaleCompare((const char *) tag,"roll") == 0)
5541       {
5542         /* init the values */
5543         width=msl_info->image[n]->columns;
5544         height=msl_info->image[n]->rows;
5545         x = y = 0;
5546
5547         if (msl_info->image[n] == (Image *) NULL)
5548         {
5549           ThrowMSLException(OptionError,"NoImagesDefined",
5550             (const char *) tag);
5551           break;
5552         }
5553         if (attributes == (const xmlChar **) NULL)
5554         break;
5555         for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5556         {
5557         keyword=(const char *) attributes[i++];
5558         CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
5559           msl_info->attributes[n],(const char *) attributes[i],exception));
5560         switch (*keyword)
5561         {
5562           case 'G':
5563           case 'g':
5564           {
5565           if (LocaleCompare(keyword,"geometry") == 0)
5566             {
5567             (void) ParseMetaGeometry(value,&x,&y,&width,&height);
5568             break;
5569             }
5570           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5571           break;
5572           }
5573           case 'X':
5574           case 'x':
5575           {
5576           if (LocaleCompare(keyword,"x") == 0)
5577             {
5578             x = StringToLong( value );
5579             break;
5580             }
5581           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5582           break;
5583           }
5584           case 'Y':
5585           case 'y':
5586           {
5587           if (LocaleCompare(keyword,"y") == 0)
5588             {
5589             y = StringToLong( value );
5590             break;
5591             }
5592           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5593           break;
5594           }
5595           default:
5596           {
5597           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5598           break;
5599           }
5600         }
5601         }
5602
5603         /*
5604           process image.
5605         */
5606         {
5607         Image
5608           *newImage;
5609
5610         newImage=RollImage(msl_info->image[n], x, y, msl_info->exception);
5611         if (newImage == (Image *) NULL)
5612           break;
5613         msl_info->image[n]=DestroyImage(msl_info->image[n]);
5614         msl_info->image[n]=newImage;
5615         }
5616
5617         break;
5618       }
5619       if (LocaleCompare((const char *) tag,"rotate") == 0)
5620         {
5621           Image
5622             *rotate_image;
5623
5624           /*
5625             Rotate image.
5626           */
5627           if (msl_info->image[n] == (Image *) NULL)
5628             {
5629               ThrowMSLException(OptionError,"NoImagesDefined",
5630                 (const char *) tag);
5631               break;
5632             }
5633           if (attributes != (const xmlChar **) NULL)
5634             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5635             {
5636               keyword=(const char *) attributes[i++];
5637               attribute=InterpretImageProperties(msl_info->image_info[n],
5638                 msl_info->attributes[n],(const char *) attributes[i],
5639                 exception);
5640               CloneString(&value,attribute);
5641               switch (*keyword)
5642               {
5643                 case 'D':
5644                 case 'd':
5645                 {
5646                   if (LocaleCompare(keyword,"degrees") == 0)
5647                     {
5648                       geometry_info.rho=StringToDouble(value,
5649                         (char **) NULL);
5650                       break;
5651                     }
5652                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5653                     keyword);
5654                   break;
5655                 }
5656                 case 'G':
5657                 case 'g':
5658                 {
5659                   if (LocaleCompare(keyword,"geometry") == 0)
5660                     {
5661                       flags=ParseGeometry(value,&geometry_info);
5662                       if ((flags & SigmaValue) == 0)
5663                         geometry_info.sigma=1.0;
5664                       break;
5665                     }
5666                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5667                     keyword);
5668                   break;
5669                 }
5670                 default:
5671                 {
5672                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5673                     keyword);
5674                   break;
5675                 }
5676               }
5677             }
5678           rotate_image=RotateImage(msl_info->image[n],geometry_info.rho,
5679             msl_info->exception);
5680           if (rotate_image == (Image *) NULL)
5681             break;
5682           msl_info->image[n]=DestroyImage(msl_info->image[n]);
5683           msl_info->image[n]=rotate_image;
5684           break;
5685         }
5686       else if (LocaleCompare((const char *) tag,"rotate") == 0)
5687       {
5688         /* init the values */
5689         double  degrees = 0;
5690
5691         if (msl_info->image[n] == (Image *) NULL)
5692         {
5693           ThrowMSLException(OptionError,"NoImagesDefined",
5694             (const char *) tag);
5695           break;
5696         }
5697         if (attributes == (const xmlChar **) NULL)
5698           break;
5699         for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5700         {
5701         keyword=(const char *) attributes[i++];
5702         CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
5703           msl_info->attributes[n],(const char *) attributes[i],exception));
5704         switch (*keyword)
5705         {
5706           case 'D':
5707           case 'd':
5708           {
5709           if (LocaleCompare(keyword,"degrees") == 0)
5710             {
5711             degrees = StringToDouble(value,(char **) NULL);
5712             break;
5713             }
5714           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5715           break;
5716           }
5717           default:
5718           {
5719           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5720           break;
5721           }
5722         }
5723         }
5724
5725         /*
5726           process image.
5727         */
5728         {
5729         Image
5730           *newImage;
5731
5732         newImage=RotateImage(msl_info->image[n], degrees, msl_info->exception);
5733         if (newImage == (Image *) NULL)
5734           break;
5735         msl_info->image[n]=DestroyImage(msl_info->image[n]);
5736         msl_info->image[n]=newImage;
5737         }
5738
5739         break;
5740       }
5741       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
5742     }
5743     case 'S':
5744     case 's':
5745     {
5746       if (LocaleCompare((const char *) tag,"sample") == 0)
5747         {
5748           Image
5749             *sample_image;
5750
5751           /*
5752             Sample image.
5753           */
5754           if (msl_info->image[n] == (Image *) NULL)
5755             {
5756               ThrowMSLException(OptionError,"NoImagesDefined",
5757                 (const char *) tag);
5758               break;
5759             }
5760           if (attributes != (const xmlChar **) NULL)
5761             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5762             {
5763               keyword=(const char *) attributes[i++];
5764               attribute=InterpretImageProperties(msl_info->image_info[n],
5765                 msl_info->attributes[n],(const char *) attributes[i],
5766                 exception);
5767               CloneString(&value,attribute);
5768               switch (*keyword)
5769               {
5770                 case 'G':
5771                 case 'g':
5772                 {
5773                   if (LocaleCompare(keyword,"geometry") == 0)
5774                     {
5775                       flags=ParseRegionGeometry(msl_info->image[n],value,
5776                         &geometry,exception);
5777                       break;
5778                     }
5779                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5780                     keyword);
5781                   break;
5782                 }
5783                 case 'H':
5784                 case 'h':
5785                 {
5786                   if (LocaleCompare(keyword,"height") == 0)
5787                     {
5788                       geometry.height=StringToUnsignedLong(value);
5789                       break;
5790                     }
5791                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5792                     keyword);
5793                   break;
5794                 }
5795                 case 'W':
5796                 case 'w':
5797                 {
5798                   if (LocaleCompare(keyword,"width") == 0)
5799                     {
5800                       geometry.width=StringToLong(value);
5801                       break;
5802                     }
5803                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5804                     keyword);
5805                   break;
5806                 }
5807                 default:
5808                 {
5809                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5810                     keyword);
5811                   break;
5812                 }
5813               }
5814             }
5815           sample_image=SampleImage(msl_info->image[n],geometry.width,
5816             geometry.height,msl_info->exception);
5817           if (sample_image == (Image *) NULL)
5818             break;
5819           msl_info->image[n]=DestroyImage(msl_info->image[n]);
5820           msl_info->image[n]=sample_image;
5821           break;
5822         }
5823       if (LocaleCompare((const char *) tag,"scale") == 0)
5824         {
5825           Image
5826             *scale_image;
5827
5828           /*
5829             Scale image.
5830           */
5831           if (msl_info->image[n] == (Image *) NULL)
5832             {
5833               ThrowMSLException(OptionError,"NoImagesDefined",
5834                 (const char *) tag);
5835               break;
5836             }
5837           if (attributes != (const xmlChar **) NULL)
5838             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5839             {
5840               keyword=(const char *) attributes[i++];
5841               attribute=InterpretImageProperties(msl_info->image_info[n],
5842                 msl_info->attributes[n],(const char *) attributes[i],
5843                 exception);
5844               CloneString(&value,attribute);
5845               switch (*keyword)
5846               {
5847                 case 'G':
5848                 case 'g':
5849                 {
5850                   if (LocaleCompare(keyword,"geometry") == 0)
5851                     {
5852                       flags=ParseRegionGeometry(msl_info->image[n],value,
5853                         &geometry,exception);
5854                       break;
5855                     }
5856                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5857                     keyword);
5858                   break;
5859                 }
5860                 case 'H':
5861                 case 'h':
5862                 {
5863                   if (LocaleCompare(keyword,"height") == 0)
5864                     {
5865                       geometry.height=StringToUnsignedLong(value);
5866                       break;
5867                     }
5868                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5869                     keyword);
5870                   break;
5871                 }
5872                 case 'W':
5873                 case 'w':
5874                 {
5875                   if (LocaleCompare(keyword,"width") == 0)
5876                     {
5877                       geometry.width=StringToLong(value);
5878                       break;
5879                     }
5880                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5881                     keyword);
5882                   break;
5883                 }
5884                 default:
5885                 {
5886                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5887                     keyword);
5888                   break;
5889                 }
5890               }
5891             }
5892           scale_image=ScaleImage(msl_info->image[n],geometry.width,
5893             geometry.height,msl_info->exception);
5894           if (scale_image == (Image *) NULL)
5895             break;
5896           msl_info->image[n]=DestroyImage(msl_info->image[n]);
5897           msl_info->image[n]=scale_image;
5898           break;
5899         }
5900       if (LocaleCompare((const char *) tag,"segment") == 0)
5901         {
5902           ColorspaceType
5903             colorspace;
5904
5905           MagickBooleanType
5906             verbose;
5907
5908           /*
5909             Segment image.
5910           */
5911           if (msl_info->image[n] == (Image *) NULL)
5912             {
5913               ThrowMSLException(OptionError,"NoImagesDefined",
5914                 (const char *) tag);
5915               break;
5916             }
5917           geometry_info.rho=1.0;
5918           geometry_info.sigma=1.5;
5919           colorspace=sRGBColorspace;
5920           verbose=MagickFalse;
5921           if (attributes != (const xmlChar **) NULL)
5922             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5923             {
5924               keyword=(const char *) attributes[i++];
5925               attribute=InterpretImageProperties(msl_info->image_info[n],
5926                 msl_info->attributes[n],(const char *) attributes[i],
5927                 exception);
5928               CloneString(&value,attribute);
5929               switch (*keyword)
5930               {
5931                 case 'C':
5932                 case 'c':
5933                 {
5934                   if (LocaleCompare(keyword,"cluster-threshold") == 0)
5935                     {
5936                       geometry_info.rho=StringToDouble(value,
5937                         (char **) NULL);
5938                       break;
5939                     }
5940                   if (LocaleCompare(keyword,"colorspace") == 0)
5941                     {
5942                       option=ParseCommandOption(MagickColorspaceOptions,
5943                         MagickFalse,value);
5944                       if (option < 0)
5945                         ThrowMSLException(OptionError,
5946                           "UnrecognizedColorspaceType",value);
5947                       colorspace=(ColorspaceType) option;
5948                       break;
5949                     }
5950                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5951                     keyword);
5952                   break;
5953                 }
5954                 case 'G':
5955                 case 'g':
5956                 {
5957                   if (LocaleCompare(keyword,"geometry") == 0)
5958                     {
5959                       flags=ParseGeometry(value,&geometry_info);
5960                       if ((flags & SigmaValue) == 0)
5961                         geometry_info.sigma=1.5;
5962                       break;
5963                     }
5964                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5965                     keyword);
5966                   break;
5967                 }
5968                 case 'S':
5969                 case 's':
5970                 {
5971                   if (LocaleCompare(keyword,"smoothing-threshold") == 0)
5972                     {
5973                       geometry_info.sigma=StringToDouble(value,
5974                         (char **) NULL);
5975                       break;
5976                     }
5977                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5978                     keyword);
5979                   break;
5980                 }
5981                 default:
5982                 {
5983                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
5984                     keyword);
5985                   break;
5986                 }
5987               }
5988             }
5989           (void) SegmentImage(msl_info->image[n],colorspace,verbose,
5990             geometry_info.rho,geometry_info.sigma,exception);
5991           break;
5992         }
5993       else if (LocaleCompare((const char *) tag, "set") == 0)
5994       {
5995         if (msl_info->image[n] == (Image *) NULL)
5996         {
5997           ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
5998           break;
5999         }
6000
6001         if (attributes == (const xmlChar **) NULL)
6002           break;
6003         for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6004         {
6005           keyword=(const char *) attributes[i++];
6006           CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
6007             msl_info->attributes[n],(const char *) attributes[i],exception));
6008           switch (*keyword)
6009           {
6010             case 'C':
6011             case 'c':
6012             {
6013               if (LocaleCompare(keyword,"clip-mask") == 0)
6014                 {
6015                   for (j=0; j < msl_info->n; j++)
6016                   {
6017                     const char
6018                       *property;
6019
6020                     property=GetImageProperty(msl_info->attributes[j],"id",
6021                       exception);
6022                     if (LocaleCompare(property,value) == 0)
6023                       {
6024                         SetImageMask(msl_info->image[n],msl_info->image[j],
6025                           exception);
6026                         break;
6027                       }
6028                   }
6029                   break;
6030                 }
6031               if (LocaleCompare(keyword,"clip-path") == 0)
6032                 {
6033                   for (j=0; j < msl_info->n; j++)
6034                   {
6035                     const char
6036                       *property;
6037
6038                     property=GetImageProperty(msl_info->attributes[j],"id",
6039                       exception);
6040                     if (LocaleCompare(property,value) == 0)
6041                       {
6042                         SetImageMask(msl_info->image[n],msl_info->image[j],
6043                           exception);
6044                         break;
6045                       }
6046                   }
6047                   break;
6048                 }
6049               if (LocaleCompare(keyword,"colorspace") == 0)
6050                 {
6051                   ssize_t
6052                     colorspace;
6053
6054                   colorspace=(ColorspaceType) ParseCommandOption(
6055                     MagickColorspaceOptions,MagickFalse,value);
6056                   if (colorspace < 0)
6057                     ThrowMSLException(OptionError,"UnrecognizedColorspace",
6058                       value);
6059                   (void) TransformImageColorspace(msl_info->image[n],
6060                     (ColorspaceType) colorspace,exception);
6061                   break;
6062                 }
6063               (void) SetMSLAttributes(msl_info,keyword,value);
6064               (void) SetImageProperty(msl_info->image[n],keyword,value,
6065                 exception);
6066               break;
6067             }
6068             case 'D':
6069             case 'd':
6070             {
6071               if (LocaleCompare(keyword,"density") == 0)
6072                 {
6073                   flags=ParseGeometry(value,&geometry_info);
6074                   msl_info->image[n]->resolution.x=geometry_info.rho;
6075                   msl_info->image[n]->resolution.y=geometry_info.sigma;
6076                   if ((flags & SigmaValue) == 0)
6077                     msl_info->image[n]->resolution.y=
6078                       msl_info->image[n]->resolution.x;
6079                   break;
6080                 }
6081               (void) SetMSLAttributes(msl_info,keyword,value);
6082               (void) SetImageProperty(msl_info->image[n],keyword,value,
6083                 exception);
6084               break;
6085             }
6086             case 'O':
6087             case 'o':
6088             {
6089               if (LocaleCompare(keyword, "opacity") == 0)
6090                 {
6091                   ssize_t  opac = OpaqueAlpha,
6092                   len = (ssize_t) strlen( value );
6093
6094                   if (value[len-1] == '%') {
6095                     char  tmp[100];
6096                     (void) CopyMagickString(tmp,value,len);
6097                     opac = StringToLong( tmp );
6098                     opac = (int)(QuantumRange * ((float)opac/100));
6099                   } else
6100                     opac = StringToLong( value );
6101                   (void) SetImageAlpha( msl_info->image[n], (Quantum) opac,
6102                     exception);
6103                   break;
6104               }
6105               (void) SetMSLAttributes(msl_info,keyword,value);
6106               (void) SetImageProperty(msl_info->image[n],keyword,value,
6107                 msl_info->exception);
6108               break;
6109             }
6110             case 'P':
6111             case 'p':
6112             {
6113               if (LocaleCompare(keyword, "page") == 0)
6114               {
6115                 char
6116                   page[MaxTextExtent];
6117
6118                 const char
6119                   *image_option;
6120
6121                 MagickStatusType
6122                   flags;
6123
6124                 RectangleInfo
6125                   geometry;
6126
6127                 (void) ResetMagickMemory(&geometry,0,sizeof(geometry));
6128                 image_option=GetImageArtifact(msl_info->image[n],"page");
6129                 if (image_option != (const char *) NULL)
6130                   flags=ParseAbsoluteGeometry(image_option,&geometry);
6131                 flags=ParseAbsoluteGeometry(value,&geometry);
6132                 (void) FormatLocaleString(page,MaxTextExtent,"%.20gx%.20g",
6133                   (double) geometry.width,(double) geometry.height);
6134                 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
6135                   (void) FormatLocaleString(page,MaxTextExtent,
6136                     "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,
6137                     (double) geometry.height,(double) geometry.x,(double)
6138                     geometry.y);
6139                 (void) SetImageOption(msl_info->image_info[n],keyword,page);
6140                 msl_info->image_info[n]->page=GetPageGeometry(page);
6141                 break;
6142               }
6143               (void) SetMSLAttributes(msl_info,keyword,value);
6144               (void) SetImageProperty(msl_info->image[n],keyword,value,
6145                 msl_info->exception);
6146               break;
6147             }
6148             default:
6149             {
6150               (void) SetMSLAttributes(msl_info,keyword,value);
6151               (void) SetImageProperty(msl_info->image[n],keyword,value,
6152                 msl_info->exception);
6153               break;
6154             }
6155           }
6156         }
6157         break;
6158       }
6159       if (LocaleCompare((const char *) tag,"shade") == 0)
6160         {
6161           Image
6162             *shade_image;
6163
6164           MagickBooleanType
6165             gray;
6166
6167           /*
6168             Shade image.
6169           */
6170           if (msl_info->image[n] == (Image *) NULL)
6171             {
6172               ThrowMSLException(OptionError,"NoImagesDefined",
6173                 (const char *) tag);
6174               break;
6175             }
6176           gray=MagickFalse;
6177           if (attributes != (const xmlChar **) NULL)
6178             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6179             {
6180               keyword=(const char *) attributes[i++];
6181               attribute=InterpretImageProperties(msl_info->image_info[n],
6182                 msl_info->attributes[n],(const char *) attributes[i],
6183                 exception);
6184               CloneString(&value,attribute);
6185               switch (*keyword)
6186               {
6187                 case 'A':
6188                 case 'a':
6189                 {
6190                   if (LocaleCompare(keyword,"azimuth") == 0)
6191                     {
6192                       geometry_info.rho=StringToDouble(value,
6193                         (char **) NULL);
6194                       break;
6195                     }
6196                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6197                     keyword);
6198                   break;
6199                 }
6200                 case 'E':
6201                 case 'e':
6202                 {
6203                   if (LocaleCompare(keyword,"elevation") == 0)
6204                     {
6205                       geometry_info.sigma=StringToDouble(value,
6206                         (char **) NULL);
6207                       break;
6208                     }
6209                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6210                     keyword);
6211                   break;
6212                 }
6213                 case 'G':
6214                 case 'g':
6215                 {
6216                   if (LocaleCompare(keyword,"geometry") == 0)
6217                     {
6218                       flags=ParseGeometry(value,&geometry_info);
6219                       if ((flags & SigmaValue) == 0)
6220                         geometry_info.sigma=1.0;
6221                       break;
6222                     }
6223                   if (LocaleCompare(keyword,"gray") == 0)
6224                     {
6225                       option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
6226                         value);
6227                       if (option < 0)
6228                         ThrowMSLException(OptionError,"UnrecognizedNoiseType",
6229                           value);
6230                       gray=(MagickBooleanType) option;
6231                       break;
6232                     }
6233                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6234                     keyword);
6235                   break;
6236                 }
6237                 default:
6238                 {
6239                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6240                     keyword);
6241                   break;
6242                 }
6243               }
6244             }
6245           shade_image=ShadeImage(msl_info->image[n],gray,geometry_info.rho,
6246             geometry_info.sigma,msl_info->exception);
6247           if (shade_image == (Image *) NULL)
6248             break;
6249           msl_info->image[n]=DestroyImage(msl_info->image[n]);
6250           msl_info->image[n]=shade_image;
6251           break;
6252         }
6253       if (LocaleCompare((const char *) tag,"shadow") == 0)
6254         {
6255           Image
6256             *shadow_image;
6257
6258           /*
6259             Shear image.
6260           */
6261           if (msl_info->image[n] == (Image *) NULL)
6262             {
6263               ThrowMSLException(OptionError,"NoImagesDefined",
6264                 (const char *) tag);
6265               break;
6266             }
6267           if (attributes != (const xmlChar **) NULL)
6268             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6269             {
6270               keyword=(const char *) attributes[i++];
6271               attribute=InterpretImageProperties(msl_info->image_info[n],
6272                 msl_info->attributes[n],(const char *) attributes[i],
6273                 exception);
6274               CloneString(&value,attribute);
6275               switch (*keyword)
6276               {
6277                 case 'G':
6278                 case 'g':
6279                 {
6280                   if (LocaleCompare(keyword,"geometry") == 0)
6281                     {
6282                       flags=ParseGeometry(value,&geometry_info);
6283                       if ((flags & SigmaValue) == 0)
6284                         geometry_info.sigma=1.0;
6285                       break;
6286                     }
6287                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6288                     keyword);
6289                   break;
6290                 }
6291                 case 'O':
6292                 case 'o':
6293                 {
6294                   if (LocaleCompare(keyword,"opacity") == 0)
6295                     {
6296                       geometry_info.rho=StringToLong(value);
6297                       break;
6298                     }
6299                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6300                     keyword);
6301                   break;
6302                 }
6303                 case 'S':
6304                 case 's':
6305                 {
6306                   if (LocaleCompare(keyword,"sigma") == 0)
6307                     {
6308                       geometry_info.sigma=StringToLong(value);
6309                       break;
6310                     }
6311                   break;
6312                 }
6313                 case 'X':
6314                 case 'x':
6315                 {
6316                   if (LocaleCompare(keyword,"x") == 0)
6317                     {
6318                       geometry_info.xi=StringToDouble(value,
6319                         (char **) NULL);
6320                       break;
6321                     }
6322                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6323                     keyword);
6324                   break;
6325                 }
6326                 case 'Y':
6327                 case 'y':
6328                 {
6329                   if (LocaleCompare(keyword,"y") == 0)
6330                     {
6331                       geometry_info.psi=StringToLong(value);
6332                       break;
6333                     }
6334                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6335                     keyword);
6336                   break;
6337                 }
6338                 default:
6339                 {
6340                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6341                     keyword);
6342                   break;
6343                 }
6344               }
6345             }
6346           shadow_image=ShadowImage(msl_info->image[n],geometry_info.rho,
6347             geometry_info.sigma,(ssize_t) ceil(geometry_info.xi-0.5),
6348             (ssize_t) ceil(geometry_info.psi-0.5),msl_info->exception);
6349           if (shadow_image == (Image *) NULL)
6350             break;
6351           msl_info->image[n]=DestroyImage(msl_info->image[n]);
6352           msl_info->image[n]=shadow_image;
6353           break;
6354         }
6355       if (LocaleCompare((const char *) tag,"sharpen") == 0)
6356       {
6357         double 
6358             radius = 0.0,
6359             sigma = 1.0;
6360
6361         if (msl_info->image[n] == (Image *) NULL)
6362           {
6363             ThrowMSLException(OptionError,"NoImagesDefined",
6364               (const char *) tag);
6365             break;
6366           }
6367         /*
6368         NOTE: sharpen can have no attributes, since we use all the defaults!
6369         */
6370         if (attributes != (const xmlChar **) NULL)
6371         {
6372           for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6373           {
6374           keyword=(const char *) attributes[i++];
6375           CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
6376             msl_info->attributes[n],(const char *) attributes[i],exception));
6377           switch (*keyword)
6378           {
6379             case 'R':
6380             case 'r':
6381             {
6382               if (LocaleCompare(keyword, "radius") == 0)
6383               {
6384                 radius = StringToDouble(value,(char **) NULL);
6385                 break;
6386               }
6387               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6388               break;
6389             }
6390             case 'S':
6391             case 's':
6392             {
6393               if (LocaleCompare(keyword,"sigma") == 0)
6394               {
6395                 sigma = StringToLong( value );
6396                 break;
6397               }
6398               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6399               break;
6400             }
6401             default:
6402             {
6403               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6404               break;
6405             }
6406           }
6407           }
6408         }
6409
6410         /*
6411           sharpen image.
6412         */
6413         {
6414         Image
6415           *newImage;
6416
6417         newImage=SharpenImage(msl_info->image[n],radius,sigma,
6418           msl_info->exception);
6419         if (newImage == (Image *) NULL)
6420           break;
6421         msl_info->image[n]=DestroyImage(msl_info->image[n]);
6422         msl_info->image[n]=newImage;
6423         break;
6424         }
6425       }
6426       else if (LocaleCompare((const char *) tag,"shave") == 0)
6427       {
6428         /* init the values */
6429         width = height = 0;
6430         x = y = 0;
6431
6432         if (msl_info->image[n] == (Image *) NULL)
6433         {
6434           ThrowMSLException(OptionError,"NoImagesDefined",
6435             (const char *) tag);
6436           break;
6437         }
6438         if (attributes == (const xmlChar **) NULL)
6439         break;
6440         for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6441         {
6442         keyword=(const char *) attributes[i++];
6443         CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
6444           msl_info->attributes[n],(const char *) attributes[i],exception));
6445         switch (*keyword)
6446         {
6447           case 'G':
6448           case 'g':
6449           {
6450           if (LocaleCompare(keyword,"geometry") == 0)
6451             {
6452             (void) ParseMetaGeometry(value,&x,&y,&width,&height);
6453             break;
6454             }
6455           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6456           break;
6457           }
6458           case 'H':
6459           case 'h':
6460           {
6461           if (LocaleCompare(keyword,"height") == 0)
6462             {
6463             height = StringToLong( value );
6464             break;
6465             }
6466           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6467           break;
6468           }
6469           case 'W':
6470           case 'w':
6471           {
6472           if (LocaleCompare(keyword,"width") == 0)
6473             {
6474             width = StringToLong( value );
6475             break;
6476             }
6477           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6478           break;
6479           }
6480           default:
6481           {
6482           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6483           break;
6484           }
6485         }
6486         }
6487
6488         /*
6489           process image.
6490         */
6491         {
6492         Image
6493           *newImage;
6494         RectangleInfo
6495           rectInfo;
6496
6497         rectInfo.height = height;
6498         rectInfo.width = width;
6499         rectInfo.x = x;
6500         rectInfo.y = y;
6501
6502
6503         newImage=ShaveImage(msl_info->image[n], &rectInfo,
6504           msl_info->exception);
6505         if (newImage == (Image *) NULL)
6506           break;
6507         msl_info->image[n]=DestroyImage(msl_info->image[n]);
6508         msl_info->image[n]=newImage;
6509         }
6510
6511         break;
6512       }
6513       if (LocaleCompare((const char *) tag,"shear") == 0)
6514         {
6515           Image
6516             *shear_image;
6517
6518           /*
6519             Shear image.
6520           */
6521           if (msl_info->image[n] == (Image *) NULL)
6522             {
6523               ThrowMSLException(OptionError,"NoImagesDefined",
6524                 (const char *) tag);
6525               break;
6526             }
6527           if (attributes != (const xmlChar **) NULL)
6528             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6529             {
6530               keyword=(const char *) attributes[i++];
6531               attribute=InterpretImageProperties(msl_info->image_info[n],
6532                 msl_info->attributes[n],(const char *) attributes[i],
6533                 exception);
6534               CloneString(&value,attribute);
6535               switch (*keyword)
6536               {
6537                 case 'F':
6538                 case 'f':
6539                 {
6540                   if (LocaleCompare(keyword, "fill") == 0)
6541                     {
6542                       (void) QueryColorCompliance(value,AllCompliance,
6543                         &msl_info->image[n]->background_color,exception);
6544                       break;
6545                     }
6546                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6547                     keyword);
6548                   break;
6549                 }
6550                 case 'G':
6551                 case 'g':
6552                 {
6553                   if (LocaleCompare(keyword,"geometry") == 0)
6554                     {
6555                       flags=ParseGeometry(value,&geometry_info);
6556                       if ((flags & SigmaValue) == 0)
6557                         geometry_info.sigma=1.0;
6558                       break;
6559                     }
6560                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6561                     keyword);
6562                   break;
6563                 }
6564                 case 'X':
6565                 case 'x':
6566                 {
6567                   if (LocaleCompare(keyword,"x") == 0)
6568                     {
6569                       geometry_info.rho=StringToDouble(value,
6570                         (char **) NULL);
6571                       break;
6572                     }
6573                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6574                     keyword);
6575                   break;
6576                 }
6577                 case 'Y':
6578                 case 'y':
6579                 {
6580                   if (LocaleCompare(keyword,"y") == 0)
6581                     {
6582                       geometry_info.sigma=StringToLong(value);
6583                       break;
6584                     }
6585                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6586                     keyword);
6587                   break;
6588                 }
6589                 default:
6590                 {
6591                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6592                     keyword);
6593                   break;
6594                 }
6595               }
6596             }
6597           shear_image=ShearImage(msl_info->image[n],geometry_info.rho,
6598             geometry_info.sigma,msl_info->exception);
6599           if (shear_image == (Image *) NULL)
6600             break;
6601           msl_info->image[n]=DestroyImage(msl_info->image[n]);
6602           msl_info->image[n]=shear_image;
6603           break;
6604         }
6605       if (LocaleCompare((const char *) tag,"signature") == 0)
6606         {
6607           /*
6608             Signature image.
6609           */
6610           if (msl_info->image[n] == (Image *) NULL)
6611             {
6612               ThrowMSLException(OptionError,"NoImagesDefined",
6613                 (const char *) tag);
6614               break;
6615             }
6616           if (attributes != (const xmlChar **) NULL)
6617             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6618             {
6619               keyword=(const char *) attributes[i++];
6620               attribute=InterpretImageProperties(msl_info->image_info[n],
6621                 msl_info->attributes[n],(const char *) attributes[i],
6622                 exception);
6623               CloneString(&value,attribute);
6624               switch (*keyword)
6625               {
6626                 default:
6627                 {
6628                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6629                     keyword);
6630                   break;
6631                 }
6632               }
6633             }
6634           (void) SignatureImage(msl_info->image[n],exception);
6635           break;
6636         }
6637       if (LocaleCompare((const char *) tag,"solarize") == 0)
6638         {
6639           /*
6640             Solarize image.
6641           */
6642           if (msl_info->image[n] == (Image *) NULL)
6643             {
6644               ThrowMSLException(OptionError,"NoImagesDefined",
6645                 (const char *) tag);
6646               break;
6647             }
6648           geometry_info.rho=QuantumRange/2.0;
6649           if (attributes != (const xmlChar **) NULL)
6650             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6651             {
6652               keyword=(const char *) attributes[i++];
6653               attribute=InterpretImageProperties(msl_info->image_info[n],
6654                 msl_info->attributes[n],(const char *) attributes[i],
6655                 exception);
6656               CloneString(&value,attribute);
6657               switch (*keyword)
6658               {
6659                 case 'G':
6660                 case 'g':
6661                 {
6662                   if (LocaleCompare(keyword,"geometry") == 0)
6663                     {
6664                       flags=ParseGeometry(value,&geometry_info);
6665                       break;
6666                     }
6667                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6668                     keyword);
6669                   break;
6670                 }
6671                 case 'T':
6672                 case 't':
6673                 {
6674                   if (LocaleCompare(keyword,"threshold") == 0)
6675                     {
6676                       geometry_info.rho=StringToDouble(value,
6677                         (char **) NULL);
6678                       break;
6679                     }
6680                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6681                     keyword);
6682                   break;
6683                 }
6684                 default:
6685                 {
6686                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6687                     keyword);
6688                   break;
6689                 }
6690               }
6691             }
6692           (void) SolarizeImage(msl_info->image[n],geometry_info.rho,
6693             msl_info->exception);
6694           break;
6695         }
6696       if (LocaleCompare((const char *) tag,"spread") == 0)
6697         {
6698           Image
6699             *spread_image;
6700
6701           /*
6702             Spread image.
6703           */
6704           if (msl_info->image[n] == (Image *) NULL)
6705             {
6706               ThrowMSLException(OptionError,"NoImagesDefined",
6707                 (const char *) tag);
6708               break;
6709             }
6710           if (attributes != (const xmlChar **) NULL)
6711             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6712             {
6713               keyword=(const char *) attributes[i++];
6714               attribute=InterpretImageProperties(msl_info->image_info[n],
6715                 msl_info->attributes[n],(const char *) attributes[i],
6716                 exception);
6717               CloneString(&value,attribute);
6718               switch (*keyword)
6719               {
6720                 case 'G':
6721                 case 'g':
6722                 {
6723                   if (LocaleCompare(keyword,"geometry") == 0)
6724                     {
6725                       flags=ParseGeometry(value,&geometry_info);
6726                       if ((flags & SigmaValue) == 0)
6727                         geometry_info.sigma=1.0;
6728                       break;
6729                     }
6730                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6731                     keyword);
6732                   break;
6733                 }
6734                 case 'R':
6735                 case 'r':
6736                 {
6737                   if (LocaleCompare(keyword,"radius") == 0)
6738                     {
6739                       geometry_info.rho=StringToDouble(value,
6740                         (char **) NULL);
6741                       break;
6742                     }
6743                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6744                     keyword);
6745                   break;
6746                 }
6747                 default:
6748                 {
6749                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6750                     keyword);
6751                   break;
6752                 }
6753               }
6754             }
6755           spread_image=SpreadImage(msl_info->image[n],geometry_info.rho,
6756             msl_info->image[n]->interpolate,msl_info->exception);
6757           if (spread_image == (Image *) NULL)
6758             break;
6759           msl_info->image[n]=DestroyImage(msl_info->image[n]);
6760           msl_info->image[n]=spread_image;
6761           break;
6762         }
6763       else if (LocaleCompare((const char *) tag,"stegano") == 0)
6764       {
6765         Image *
6766           watermark = (Image*)NULL;
6767
6768         if (msl_info->image[n] == (Image *) NULL)
6769           {
6770             ThrowMSLException(OptionError,"NoImagesDefined",
6771               (const char *) tag);
6772             break;
6773           }
6774         if (attributes == (const xmlChar **) NULL)
6775         break;
6776         for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6777         {
6778         keyword=(const char *) attributes[i++];
6779         CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
6780           msl_info->attributes[n],(const char *) attributes[i],exception));
6781         switch (*keyword)
6782         {
6783           case 'I':
6784           case 'i':
6785           {
6786           if (LocaleCompare(keyword,"image") == 0)
6787             {
6788             for (j=0; j<msl_info->n;j++)
6789             {
6790               const char *
6791                 theAttr = GetImageProperty(msl_info->attributes[j], "id",
6792                       exception);
6793               if (theAttr && LocaleCompare(theAttr, value) == 0)
6794               {
6795                 watermark = msl_info->image[j];
6796                 break;
6797               }
6798             }
6799             break;
6800             }
6801           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6802           break;
6803           }
6804           default:
6805           {
6806           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6807           break;
6808           }
6809         }
6810         }
6811
6812         /*
6813           process image.
6814         */
6815         if ( watermark != (Image*) NULL )
6816         {
6817         Image
6818           *newImage;
6819
6820         newImage=SteganoImage(msl_info->image[n], watermark, msl_info->exception);
6821         if (newImage == (Image *) NULL)
6822           break;
6823         msl_info->image[n]=DestroyImage(msl_info->image[n]);
6824         msl_info->image[n]=newImage;
6825         break;
6826         } else
6827           ThrowMSLException(OptionError,"MissingWatermarkImage",keyword);
6828       }
6829       else if (LocaleCompare((const char *) tag,"stereo") == 0)
6830       {
6831         Image *
6832           stereoImage = (Image*)NULL;
6833
6834         if (msl_info->image[n] == (Image *) NULL)
6835           {
6836             ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
6837             break;
6838           }
6839         if (attributes == (const xmlChar **) NULL)
6840         break;
6841         for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6842         {
6843         keyword=(const char *) attributes[i++];
6844         CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
6845           msl_info->attributes[n],(const char *) attributes[i],exception));
6846         switch (*keyword)
6847         {
6848           case 'I':
6849           case 'i':
6850           {
6851           if (LocaleCompare(keyword,"image") == 0)
6852             {
6853             for (j=0; j<msl_info->n;j++)
6854             {
6855               const char *
6856                 theAttr = GetImageProperty(msl_info->attributes[j], "id",
6857                       exception);
6858               if (theAttr && LocaleCompare(theAttr, value) == 0)
6859               {
6860                 stereoImage = msl_info->image[j];
6861                 break;
6862               }
6863             }
6864             break;
6865             }
6866           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6867           break;
6868           }
6869           default:
6870           {
6871           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6872           break;
6873           }
6874         }
6875         }
6876
6877         /*
6878           process image.
6879         */
6880         if ( stereoImage != (Image*) NULL )
6881         {
6882         Image
6883           *newImage;
6884
6885         newImage=StereoImage(msl_info->image[n], stereoImage, msl_info->exception);
6886         if (newImage == (Image *) NULL)
6887           break;
6888         msl_info->image[n]=DestroyImage(msl_info->image[n]);
6889         msl_info->image[n]=newImage;
6890         break;
6891         } else
6892           ThrowMSLException(OptionError,"Missing stereo image",keyword);
6893       }
6894       if (LocaleCompare((const char *) tag,"strip") == 0)
6895         {
6896           /*
6897             Strip image.
6898           */
6899           if (msl_info->image[n] == (Image *) NULL)
6900             {
6901               ThrowMSLException(OptionError,"NoImagesDefined",
6902                 (const char *) tag);
6903               break;
6904             }
6905           if (attributes != (const xmlChar **) NULL)
6906             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6907             {
6908               keyword=(const char *) attributes[i++];
6909               attribute=InterpretImageProperties(msl_info->image_info[n],
6910                 msl_info->attributes[n],(const char *) attributes[i],
6911                 exception);
6912               CloneString(&value,attribute);
6913               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6914             }
6915           (void) StripImage(msl_info->image[n],msl_info->exception);
6916           break;
6917         }
6918       if (LocaleCompare((const char *) tag,"swap") == 0)
6919         {
6920           Image
6921             *p,
6922             *q,
6923             *swap;
6924
6925           ssize_t
6926             index,
6927             swap_index;
6928
6929           if (msl_info->image[n] == (Image *) NULL)
6930             {
6931               ThrowMSLException(OptionError,"NoImagesDefined",
6932                 (const char *) tag);
6933               break;
6934             }
6935           index=(-1);
6936           swap_index=(-2);
6937           if (attributes != (const xmlChar **) NULL)
6938             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6939             {
6940               keyword=(const char *) attributes[i++];
6941               attribute=InterpretImageProperties(msl_info->image_info[n],
6942                 msl_info->attributes[n],(const char *) attributes[i],
6943                 exception);
6944               CloneString(&value,attribute);
6945               switch (*keyword)
6946               {
6947                 case 'G':
6948                 case 'g':
6949                 {
6950                   if (LocaleCompare(keyword,"indexes") == 0)
6951                     {
6952                       flags=ParseGeometry(value,&geometry_info);
6953                       index=(ssize_t) geometry_info.rho;
6954                       if ((flags & SigmaValue) == 0)
6955                         swap_index=(ssize_t) geometry_info.sigma;
6956                       break;
6957                     }
6958                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6959                     keyword);
6960                   break;
6961                 }
6962                 default:
6963                 {
6964                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6965                     keyword);
6966                   break;
6967                 }
6968               }
6969             }
6970           /*
6971             Swap images.
6972           */
6973           p=GetImageFromList(msl_info->image[n],index);
6974           q=GetImageFromList(msl_info->image[n],swap_index);
6975           if ((p == (Image *) NULL) || (q == (Image *) NULL))
6976             {
6977               ThrowMSLException(OptionError,"NoSuchImage",(const char *) tag);
6978               break;
6979             }
6980           swap=CloneImage(p,0,0,MagickTrue,msl_info->exception);
6981           ReplaceImageInList(&p,CloneImage(q,0,0,MagickTrue,
6982             msl_info->exception));
6983           ReplaceImageInList(&q,swap);
6984           msl_info->image[n]=GetFirstImageInList(q);
6985           break;
6986         }
6987       if (LocaleCompare((const char *) tag,"swirl") == 0)
6988         {
6989           Image
6990             *swirl_image;
6991
6992           /*
6993             Swirl image.
6994           */
6995           if (msl_info->image[n] == (Image *) NULL)
6996             {
6997               ThrowMSLException(OptionError,"NoImagesDefined",
6998                 (const char *) tag);
6999               break;
7000             }
7001           if (attributes != (const xmlChar **) NULL)
7002             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7003             {
7004               keyword=(const char *) attributes[i++];
7005               attribute=InterpretImageProperties(msl_info->image_info[n],
7006                 msl_info->attributes[n],(const char *) attributes[i],
7007                 exception);
7008               CloneString(&value,attribute);
7009               switch (*keyword)
7010               {
7011                 case 'D':
7012                 case 'd':
7013                 {
7014                   if (LocaleCompare(keyword,"degrees") == 0)
7015                     {
7016                       geometry_info.rho=StringToDouble(value,
7017                         (char **) NULL);
7018                       break;
7019                     }
7020                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
7021                     keyword);
7022                   break;
7023                 }
7024                 case 'G':
7025                 case 'g':
7026                 {
7027                   if (LocaleCompare(keyword,"geometry") == 0)
7028                     {
7029                       flags=ParseGeometry(value,&geometry_info);
7030                       if ((flags & SigmaValue) == 0)
7031                         geometry_info.sigma=1.0;
7032                       break;
7033                     }
7034                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
7035                     keyword);
7036                   break;
7037                 }
7038                 default:
7039                 {
7040                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
7041                     keyword);
7042                   break;
7043                 }
7044               }
7045             }
7046           swirl_image=SwirlImage(msl_info->image[n],geometry_info.rho,
7047             msl_info->image[n]->interpolate,msl_info->exception);
7048           if (swirl_image == (Image *) NULL)
7049             break;
7050           msl_info->image[n]=DestroyImage(msl_info->image[n]);
7051           msl_info->image[n]=swirl_image;
7052           break;
7053         }
7054       if (LocaleCompare((const char *) tag,"sync") == 0)
7055         {
7056           /*
7057             Sync image.
7058           */
7059           if (msl_info->image[n] == (Image *) NULL)
7060             {
7061               ThrowMSLException(OptionError,"NoImagesDefined",
7062                 (const char *) tag);
7063               break;
7064             }
7065           if (attributes != (const xmlChar **) NULL)
7066             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7067             {
7068               keyword=(const char *) attributes[i++];
7069               attribute=InterpretImageProperties(msl_info->image_info[n],
7070                 msl_info->attributes[n],(const char *) attributes[i],
7071                 exception);
7072               CloneString(&value,attribute);
7073               switch (*keyword)
7074               {
7075                 default:
7076                 {
7077                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
7078                     keyword);
7079                   break;
7080                 }
7081               }
7082             }
7083           (void) SyncImage(msl_info->image[n],exception);
7084           break;
7085         }
7086       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7087     }
7088     case 'T':
7089     case 't':
7090     {
7091       if (LocaleCompare((const char *) tag,"map") == 0)
7092         {
7093           Image
7094             *texture_image;
7095
7096           /*
7097             Texture image.
7098           */
7099           if (msl_info->image[n] == (Image *) NULL)
7100             {
7101               ThrowMSLException(OptionError,"NoImagesDefined",
7102                 (const char *) tag);
7103               break;
7104             }
7105           texture_image=NewImageList();
7106           if (attributes != (const xmlChar **) NULL)
7107             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7108             {
7109               keyword=(const char *) attributes[i++];
7110               attribute=InterpretImageProperties(msl_info->image_info[n],
7111                 msl_info->attributes[n],(const char *) attributes[i],
7112                 exception);
7113               CloneString(&value,attribute);
7114               switch (*keyword)
7115               {
7116                 case 'I':
7117                 case 'i':
7118                 {
7119                   if (LocaleCompare(keyword,"image") == 0)
7120                     for (j=0; j < msl_info->n; j++)
7121                     {
7122                       const char
7123                         *attribute;
7124
7125                       attribute=GetImageProperty(msl_info->attributes[j],"id",
7126                       exception);
7127                       if ((attribute != (const char *) NULL)  &&
7128                           (LocaleCompare(attribute,value) == 0))
7129                         {
7130                           texture_image=CloneImage(msl_info->image[j],0,0,
7131                             MagickFalse,exception);
7132                           break;
7133                         }
7134                     }
7135                   break;
7136                 }
7137                 default:
7138                 {
7139                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
7140                     keyword);
7141                   break;
7142                 }
7143               }
7144             }
7145           (void) TextureImage(msl_info->image[n],texture_image,exception);
7146           texture_image=DestroyImage(texture_image);
7147           break;
7148         }
7149       else if (LocaleCompare((const char *) tag,"threshold") == 0)
7150       {
7151         /* init the values */
7152         double  threshold = 0;
7153
7154         if (msl_info->image[n] == (Image *) NULL)
7155           {
7156             ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7157             break;
7158           }
7159         if (attributes == (const xmlChar **) NULL)
7160         break;
7161         for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7162         {
7163         keyword=(const char *) attributes[i++];
7164         CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
7165           msl_info->attributes[n],(const char *) attributes[i],exception));
7166         switch (*keyword)
7167         {
7168           case 'T':
7169           case 't':
7170           {
7171           if (LocaleCompare(keyword,"threshold") == 0)
7172             {
7173             threshold = StringToDouble(value,(char **) NULL);
7174             break;
7175             }
7176           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7177           break;
7178           }
7179           default:
7180           {
7181           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7182           break;
7183           }
7184         }
7185         }
7186
7187         /*
7188           process image.
7189         */
7190         {
7191           BilevelImage(msl_info->image[n],threshold,exception);
7192           break;
7193         }
7194       }
7195       else if (LocaleCompare((const char *) tag, "transparent") == 0)
7196       {
7197         if (msl_info->image[n] == (Image *) NULL)
7198           {
7199             ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7200             break;
7201           }
7202         if (attributes == (const xmlChar **) NULL)
7203           break;
7204         for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7205         {
7206           keyword=(const char *) attributes[i++];
7207           CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
7208             msl_info->attributes[n],(const char *) attributes[i],exception));
7209           switch (*keyword)
7210           {
7211             case 'C':
7212             case 'c':
7213             {
7214               if (LocaleCompare(keyword,"color") == 0)
7215               {
7216                 PixelInfo
7217                   target;
7218
7219                 (void) QueryColorCompliance(value,AllCompliance,&target,
7220                   exception);
7221                 (void) TransparentPaintImage(msl_info->image[n],&target,
7222                   TransparentAlpha,MagickFalse,msl_info->exception);
7223                 break;
7224               }
7225               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7226               break;
7227             }
7228             default:
7229             {
7230               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7231             break;
7232             }
7233           }
7234         }
7235         break;
7236       }
7237       else if (LocaleCompare((const char *) tag, "trim") == 0)
7238       {
7239         if (msl_info->image[n] == (Image *) NULL)
7240           {
7241             ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7242             break;
7243           }
7244
7245         /* no attributes here */
7246
7247         /* process the image */
7248         {
7249           Image
7250             *newImage;
7251           RectangleInfo
7252             rectInfo;
7253
7254           /* all zeros on a crop == trim edges! */
7255           rectInfo.height = rectInfo.width = 0;
7256           rectInfo.x =  rectInfo.y = 0;
7257
7258           newImage=CropImage(msl_info->image[n],&rectInfo, msl_info->exception);
7259           if (newImage == (Image *) NULL)
7260             break;
7261           msl_info->image[n]=DestroyImage(msl_info->image[n]);
7262           msl_info->image[n]=newImage;
7263           break;
7264         }
7265       }
7266       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7267     }
7268     case 'W':
7269     case 'w':
7270     {
7271       if (LocaleCompare((const char *) tag,"write") == 0)
7272         {
7273           if (msl_info->image[n] == (Image *) NULL)
7274             {
7275               ThrowMSLException(OptionError,"NoImagesDefined",
7276                 (const char *) tag);
7277               break;
7278             }
7279           if (attributes == (const xmlChar **) NULL)
7280             break;
7281           for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7282           {
7283             keyword=(const char *) attributes[i++];
7284             CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
7285               msl_info->attributes[n],(const char *) attributes[i],exception));
7286             switch (*keyword)
7287             {
7288               case 'F':
7289               case 'f':
7290               {
7291                 if (LocaleCompare(keyword,"filename") == 0)
7292                   {
7293                     (void) CopyMagickString(msl_info->image[n]->filename,value,
7294                       MaxTextExtent);
7295                     break;
7296                   }
7297                 (void) SetMSLAttributes(msl_info,keyword,value);
7298               }
7299               default:
7300               {
7301                 (void) SetMSLAttributes(msl_info,keyword,value);
7302                 break;
7303               }
7304             }
7305           }
7306
7307           /* process */
7308           {
7309             (void) WriteImage(msl_info->image_info[n], msl_info->image[n],
7310               msl_info->exception);
7311             break;
7312           }
7313         }
7314       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7315     }
7316     default:
7317     {
7318       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7319       break;
7320     }
7321   }
7322   if ( value != NULL )
7323     value=DestroyString(value);
7324   (void) DestroyExceptionInfo(exception);
7325   (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  )");
7326 }
7327
7328 static void MSLEndElement(void *context,const xmlChar *tag)
7329 {
7330   ssize_t
7331     n;
7332
7333   MSLInfo
7334     *msl_info;
7335
7336   /*
7337     Called when the end of an element has been detected.
7338   */
7339   (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  SAX.endElement(%s)",
7340     tag);
7341   msl_info=(MSLInfo *) context;
7342   n=msl_info->n;
7343   switch (*tag)
7344   {
7345     case 'C':
7346     case 'c':
7347     {
7348       if (LocaleCompare((const char *) tag,"comment") == 0 )
7349         {
7350           (void) DeleteImageProperty(msl_info->image[n],"comment");
7351           if (msl_info->content == (char *) NULL)
7352             break;
7353           StripString(msl_info->content);
7354           (void) SetImageProperty(msl_info->image[n],"comment",
7355             msl_info->content,msl_info->exception);
7356           break;
7357         }
7358       break;
7359     }
7360     case 'G':
7361     case 'g':
7362     {
7363       if (LocaleCompare((const char *) tag, "group") == 0 )
7364       {
7365         if (msl_info->group_info[msl_info->number_groups-1].numImages > 0 )
7366         {
7367           ssize_t  i = (ssize_t)
7368             (msl_info->group_info[msl_info->number_groups-1].numImages);
7369           while ( i-- )
7370           {
7371             if (msl_info->image[msl_info->n] != (Image *) NULL)
7372               msl_info->image[msl_info->n]=DestroyImage(
7373                 msl_info->image[msl_info->n]);
7374             msl_info->attributes[msl_info->n]=DestroyImage(
7375                 msl_info->attributes[msl_info->n]);
7376             msl_info->image_info[msl_info->n]=DestroyImageInfo(
7377                 msl_info->image_info[msl_info->n]);
7378             msl_info->n--;
7379           }
7380         }
7381         msl_info->number_groups--;
7382       }
7383       break;
7384     }
7385     case 'I':
7386     case 'i':
7387     {
7388       if (LocaleCompare((const char *) tag, "image") == 0)
7389         MSLPopImage(msl_info);
7390        break;
7391     }
7392     case 'L':
7393     case 'l':
7394     {
7395       if (LocaleCompare((const char *) tag,"label") == 0 )
7396         {
7397           (void) DeleteImageProperty(msl_info->image[n],"label");
7398           if (msl_info->content == (char *) NULL)
7399             break;
7400           StripString(msl_info->content);
7401           (void) SetImageProperty(msl_info->image[n],"label",
7402             msl_info->content,msl_info->exception);
7403           break;
7404         }
7405       break;
7406     }
7407     case 'M':
7408     case 'm':
7409     {
7410       if (LocaleCompare((const char *) tag, "msl") == 0 )
7411       {
7412         /*
7413           This our base element.
7414             at the moment we don't do anything special
7415             but someday we might!
7416         */
7417       }
7418       break;
7419     }
7420     default:
7421       break;
7422   }
7423   if (msl_info->content != (char *) NULL)
7424     msl_info->content=DestroyString(msl_info->content);
7425 }
7426
7427 static void MSLCharacters(void *context,const xmlChar *c,int length)
7428 {
7429   MSLInfo
7430     *msl_info;
7431
7432   register char
7433     *p;
7434
7435   register ssize_t
7436     i;
7437
7438   /*
7439     Receiving some characters from the parser.
7440   */
7441   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7442     "  SAX.characters(%s,%d)",c,length);
7443   msl_info=(MSLInfo *) context;
7444   if (msl_info->content != (char *) NULL)
7445     msl_info->content=(char *) ResizeQuantumMemory(msl_info->content,
7446       strlen(msl_info->content)+length+MaxTextExtent,
7447       sizeof(*msl_info->content));
7448   else
7449     {
7450       msl_info->content=(char *) NULL;
7451       if (~length >= (MaxTextExtent-1))
7452         msl_info->content=(char *) AcquireQuantumMemory(length+MaxTextExtent,
7453           sizeof(*msl_info->content));
7454       if (msl_info->content != (char *) NULL)
7455         *msl_info->content='\0';
7456     }
7457   if (msl_info->content == (char *) NULL)
7458     return;
7459   p=msl_info->content+strlen(msl_info->content);
7460   for (i=0; i < length; i++)
7461     *p++=c[i];
7462   *p='\0';
7463 }
7464
7465 static void MSLReference(void *context,const xmlChar *name)
7466 {
7467   MSLInfo
7468     *msl_info;
7469
7470   xmlParserCtxtPtr
7471     parser;
7472
7473   /*
7474     Called when an entity reference is detected.
7475   */
7476   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7477     "  SAX.reference(%s)",name);
7478   msl_info=(MSLInfo *) context;
7479   parser=msl_info->parser;
7480   if (*name == '#')
7481     (void) xmlAddChild(parser->node,xmlNewCharRef(msl_info->document,name));
7482   else
7483     (void) xmlAddChild(parser->node,xmlNewReference(msl_info->document,name));
7484 }
7485
7486 static void MSLIgnorableWhitespace(void *context,const xmlChar *c,int length)
7487 {
7488   MSLInfo
7489     *msl_info;
7490
7491   /*
7492     Receiving some ignorable whitespaces from the parser.
7493   */
7494   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7495     "  SAX.ignorableWhitespace(%.30s, %d)",c,length);
7496   msl_info=(MSLInfo *) context;
7497   (void) msl_info;
7498 }
7499
7500 static void MSLProcessingInstructions(void *context,const xmlChar *target,
7501   const xmlChar *data)
7502 {
7503   MSLInfo
7504     *msl_info;
7505
7506   /*
7507     A processing instruction has been parsed.
7508   */
7509   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7510     "  SAX.processingInstruction(%s, %s)",
7511     target,data);
7512   msl_info=(MSLInfo *) context;
7513   (void) msl_info;
7514 }
7515
7516 static void MSLComment(void *context,const xmlChar *value)
7517 {
7518   MSLInfo
7519     *msl_info;
7520
7521   /*
7522     A comment has been parsed.
7523   */
7524   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7525     "  SAX.comment(%s)",value);
7526   msl_info=(MSLInfo *) context;
7527   (void) msl_info;
7528 }
7529
7530 static void MSLWarning(void *context,const char *format,...)
7531 {
7532   char
7533     *message,
7534     reason[MaxTextExtent];
7535
7536   MSLInfo
7537     *msl_info;
7538
7539   va_list
7540     operands;
7541
7542   /**
7543     Display and format a warning messages, gives file, line, position and
7544     extra parameters.
7545   */
7546   va_start(operands,format);
7547   (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  SAX.warning: ");
7548   (void) LogMagickEvent(CoderEvent,GetMagickModule(),format,operands);
7549   msl_info=(MSLInfo *) context;
7550   (void) msl_info;
7551 #if !defined(MAGICKCORE_HAVE_VSNPRINTF)
7552   (void) vsprintf(reason,format,operands);
7553 #else
7554   (void) vsnprintf(reason,MaxTextExtent,format,operands);
7555 #endif
7556   message=GetExceptionMessage(errno);
7557   ThrowMSLException(CoderError,reason,message);
7558   message=DestroyString(message);
7559   va_end(operands);
7560 }
7561
7562 static void MSLError(void *context,const char *format,...)
7563 {
7564   char
7565     reason[MaxTextExtent];
7566
7567   MSLInfo
7568     *msl_info;
7569
7570   va_list
7571     operands;
7572
7573   /*
7574     Display and format a error formats, gives file, line, position and
7575     extra parameters.
7576   */
7577   va_start(operands,format);
7578   (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  SAX.error: ");
7579   (void) LogMagickEvent(CoderEvent,GetMagickModule(),format,operands);
7580   msl_info=(MSLInfo *) context;
7581   (void) msl_info;
7582 #if !defined(MAGICKCORE_HAVE_VSNPRINTF)
7583   (void) vsprintf(reason,format,operands);
7584 #else
7585   (void) vsnprintf(reason,MaxTextExtent,format,operands);
7586 #endif
7587   ThrowMSLException(DelegateFatalError,reason,"SAX error");
7588   va_end(operands);
7589 }
7590
7591 static void MSLCDataBlock(void *context,const xmlChar *value,int length)
7592 {
7593   MSLInfo
7594     *msl_info;
7595
7596    xmlNodePtr
7597      child;
7598
7599   xmlParserCtxtPtr
7600     parser;
7601
7602   /*
7603     Called when a pcdata block has been parsed.
7604   */
7605   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7606     "  SAX.pcdata(%s, %d)",value,length);
7607   msl_info=(MSLInfo *) context;
7608   (void) msl_info;
7609   parser=msl_info->parser;
7610   child=xmlGetLastChild(parser->node);
7611   if ((child != (xmlNodePtr) NULL) && (child->type == XML_CDATA_SECTION_NODE))
7612     {
7613       xmlTextConcat(child,value,length);
7614       return;
7615     }
7616   (void) xmlAddChild(parser->node,xmlNewCDataBlock(parser->myDoc,value,length));
7617 }
7618
7619 static void MSLExternalSubset(void *context,const xmlChar *name,
7620   const xmlChar *external_id,const xmlChar *system_id)
7621 {
7622   MSLInfo
7623     *msl_info;
7624
7625   xmlParserCtxt
7626     parser_context;
7627
7628   xmlParserCtxtPtr
7629     parser;
7630
7631   xmlParserInputPtr
7632     input;
7633
7634   /*
7635     Does this document has an external subset?
7636   */
7637   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7638     "  SAX.externalSubset(%s %s %s)",name,
7639     (external_id != (const xmlChar *) NULL ? (const char *) external_id : " "),
7640     (system_id != (const xmlChar *) NULL ? (const char *) system_id : " "));
7641   msl_info=(MSLInfo *) context;
7642   (void) msl_info;
7643   parser=msl_info->parser;
7644   if (((external_id == NULL) && (system_id == NULL)) ||
7645       ((parser->validate == 0) || (parser->wellFormed == 0) ||
7646       (msl_info->document == 0)))
7647     return;
7648   input=MSLResolveEntity(context,external_id,system_id);
7649   if (input == NULL)
7650     return;
7651   (void) xmlNewDtd(msl_info->document,name,external_id,system_id);
7652   parser_context=(*parser);
7653   parser->inputTab=(xmlParserInputPtr *) xmlMalloc(5*sizeof(*parser->inputTab));
7654   if (parser->inputTab == (xmlParserInputPtr *) NULL)
7655     {
7656       parser->errNo=XML_ERR_NO_MEMORY;
7657       parser->input=parser_context.input;
7658       parser->inputNr=parser_context.inputNr;
7659       parser->inputMax=parser_context.inputMax;
7660       parser->inputTab=parser_context.inputTab;
7661       return;
7662   }
7663   parser->inputNr=0;
7664   parser->inputMax=5;
7665   parser->input=NULL;
7666   xmlPushInput(parser,input);
7667   (void) xmlSwitchEncoding(parser,xmlDetectCharEncoding(parser->input->cur,4));
7668   if (input->filename == (char *) NULL)
7669     input->filename=(char *) xmlStrdup(system_id);
7670   input->line=1;
7671   input->col=1;
7672   input->base=parser->input->cur;
7673   input->cur=parser->input->cur;
7674   input->free=NULL;
7675   xmlParseExternalSubset(parser,external_id,system_id);
7676   while (parser->inputNr > 1)
7677     (void) xmlPopInput(parser);
7678   xmlFreeInputStream(parser->input);
7679   xmlFree(parser->inputTab);
7680   parser->input=parser_context.input;
7681   parser->inputNr=parser_context.inputNr;
7682   parser->inputMax=parser_context.inputMax;
7683   parser->inputTab=parser_context.inputTab;
7684 }
7685
7686 #if defined(__cplusplus) || defined(c_plusplus)
7687 }
7688 #endif
7689
7690 static MagickBooleanType ProcessMSLScript(const ImageInfo *image_info,
7691   Image **image,ExceptionInfo *exception)
7692 {
7693   char
7694     message[MaxTextExtent];
7695
7696   Image
7697     *msl_image;
7698
7699   int
7700     status;
7701
7702   ssize_t
7703     n;
7704
7705   MSLInfo
7706     msl_info;
7707
7708   xmlSAXHandler
7709     sax_modules;
7710
7711   xmlSAXHandlerPtr
7712     sax_handler;
7713
7714   /*
7715     Open image file.
7716   */
7717   assert(image_info != (const ImageInfo *) NULL);
7718   assert(image_info->signature == MagickSignature);
7719   if (image_info->debug != MagickFalse)
7720     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
7721       image_info->filename);
7722   assert(image != (Image **) NULL);
7723   msl_image=AcquireImage(image_info,exception);
7724   status=OpenBlob(image_info,msl_image,ReadBinaryBlobMode,exception);
7725   if (status == MagickFalse)
7726     {
7727       ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
7728         msl_image->filename);
7729       msl_image=DestroyImageList(msl_image);
7730       return(MagickFalse);
7731     }
7732   msl_image->columns=1;
7733   msl_image->rows=1;
7734   /*
7735     Parse MSL file.
7736   */
7737   (void) ResetMagickMemory(&msl_info,0,sizeof(msl_info));
7738   msl_info.exception=exception;
7739   msl_info.image_info=(ImageInfo **) AcquireMagickMemory(
7740     sizeof(*msl_info.image_info));
7741   msl_info.draw_info=(DrawInfo **) AcquireMagickMemory(
7742     sizeof(*msl_info.draw_info));
7743   /* top of the stack is the MSL file itself */
7744   msl_info.image=(Image **) AcquireMagickMemory(sizeof(*msl_info.image));
7745   msl_info.attributes=(Image **) AcquireMagickMemory(
7746     sizeof(*msl_info.attributes));
7747   msl_info.group_info=(MSLGroupInfo *) AcquireMagickMemory(
7748     sizeof(*msl_info.group_info));
7749   if ((msl_info.image_info == (ImageInfo **) NULL) ||
7750       (msl_info.image == (Image **) NULL) ||
7751       (msl_info.attributes == (Image **) NULL) ||
7752       (msl_info.group_info == (MSLGroupInfo *) NULL))
7753     ThrowFatalException(ResourceLimitFatalError,
7754       "UnableToInterpretMSLImage");
7755   *msl_info.image_info=CloneImageInfo(image_info);
7756   *msl_info.draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL);
7757   *msl_info.attributes=AcquireImage(image_info,exception);
7758   msl_info.group_info[0].numImages=0;
7759   /* the first slot is used to point to the MSL file image */
7760   *msl_info.image=msl_image;
7761   if (*image != (Image *) NULL)
7762     MSLPushImage(&msl_info,*image);
7763   (void) xmlSubstituteEntitiesDefault(1);
7764   (void) ResetMagickMemory(&sax_modules,0,sizeof(sax_modules));
7765   sax_modules.internalSubset=MSLInternalSubset;
7766   sax_modules.isStandalone=MSLIsStandalone;
7767   sax_modules.hasInternalSubset=MSLHasInternalSubset;
7768   sax_modules.hasExternalSubset=MSLHasExternalSubset;
7769   sax_modules.resolveEntity=MSLResolveEntity;
7770   sax_modules.getEntity=MSLGetEntity;
7771   sax_modules.entityDecl=MSLEntityDeclaration;
7772   sax_modules.notationDecl=MSLNotationDeclaration;
7773   sax_modules.attributeDecl=MSLAttributeDeclaration;
7774   sax_modules.elementDecl=MSLElementDeclaration;
7775   sax_modules.unparsedEntityDecl=MSLUnparsedEntityDeclaration;
7776   sax_modules.setDocumentLocator=MSLSetDocumentLocator;
7777   sax_modules.startDocument=MSLStartDocument;
7778   sax_modules.endDocument=MSLEndDocument;
7779   sax_modules.startElement=MSLStartElement;
7780   sax_modules.endElement=MSLEndElement;
7781   sax_modules.reference=MSLReference;
7782   sax_modules.characters=MSLCharacters;
7783   sax_modules.ignorableWhitespace=MSLIgnorableWhitespace;
7784   sax_modules.processingInstruction=MSLProcessingInstructions;
7785   sax_modules.comment=MSLComment;
7786   sax_modules.warning=MSLWarning;
7787   sax_modules.error=MSLError;
7788   sax_modules.fatalError=MSLError;
7789   sax_modules.getParameterEntity=MSLGetParameterEntity;
7790   sax_modules.cdataBlock=MSLCDataBlock;
7791   sax_modules.externalSubset=MSLExternalSubset;
7792   sax_handler=(&sax_modules);
7793   msl_info.parser=xmlCreatePushParserCtxt(sax_handler,&msl_info,(char *) NULL,0,
7794     msl_image->filename);
7795   while (ReadBlobString(msl_image,message) != (char *) NULL)
7796   {
7797     n=(ssize_t) strlen(message);
7798     if (n == 0)
7799       continue;
7800     status=xmlParseChunk(msl_info.parser,message,(int) n,MagickFalse);
7801     if (status != 0)
7802       break;
7803     (void) xmlParseChunk(msl_info.parser," ",1,MagickFalse);
7804     if (msl_info.exception->severity >= ErrorException)
7805       break;
7806   }
7807   if (msl_info.exception->severity == UndefinedException)
7808     (void) xmlParseChunk(msl_info.parser," ",1,MagickTrue);
7809   xmlFreeParserCtxt(msl_info.parser);
7810   (void) LogMagickEvent(CoderEvent,GetMagickModule(),"end SAX");
7811   msl_info.group_info=(MSLGroupInfo *) RelinquishMagickMemory(
7812     msl_info.group_info);
7813   if (*image == (Image *) NULL)
7814     *image=(*msl_info.image);
7815   if (msl_info.exception->severity != UndefinedException)
7816     return(MagickFalse);
7817   return(MagickTrue);
7818 }
7819
7820 static Image *ReadMSLImage(const ImageInfo *image_info,ExceptionInfo *exception)
7821 {
7822   Image
7823     *image;
7824
7825   /*
7826     Open image file.
7827   */
7828   assert(image_info != (const ImageInfo *) NULL);
7829   assert(image_info->signature == MagickSignature);
7830   if (image_info->debug != MagickFalse)
7831     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
7832       image_info->filename);
7833   assert(exception != (ExceptionInfo *) NULL);
7834   assert(exception->signature == MagickSignature);
7835   image=(Image *) NULL;
7836   (void) ProcessMSLScript(image_info,&image,exception);
7837   return(GetFirstImageInList(image));
7838 }
7839 #endif
7840 \f
7841 /*
7842 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7843 %                                                                             %
7844 %                                                                             %
7845 %                                                                             %
7846 %   R e g i s t e r M S L I m a g e                                           %
7847 %                                                                             %
7848 %                                                                             %
7849 %                                                                             %
7850 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7851 %
7852 %  RegisterMSLImage() adds attributes for the MSL image format to
7853 %  the list of supported formats.  The attributes include the image format
7854 %  tag, a method to read and/or write the format, whether the format
7855 %  supports the saving of more than one frame to the same file or blob,
7856 %  whether the format supports native in-memory I/O, and a brief
7857 %  description of the format.
7858 %
7859 %  The format of the RegisterMSLImage method is:
7860 %
7861 %      size_t RegisterMSLImage(void)
7862 %
7863 */
7864 ModuleExport size_t RegisterMSLImage(void)
7865 {
7866   MagickInfo
7867     *entry;
7868
7869 #if defined(MAGICKCORE_XML_DELEGATE)
7870   xmlInitParser();
7871 #endif
7872   entry=SetMagickInfo("MSL");
7873 #if defined(MAGICKCORE_XML_DELEGATE)
7874   entry->decoder=(DecodeImageHandler *) ReadMSLImage;
7875   entry->encoder=(EncodeImageHandler *) WriteMSLImage;
7876 #endif
7877   entry->description=ConstantString("Magick Scripting Language");
7878   entry->module=ConstantString("MSL");
7879   (void) RegisterMagickInfo(entry);
7880   return(MagickImageCoderSignature);
7881 }
7882 \f
7883 #if defined(MAGICKCORE_XML_DELEGATE)
7884 /*
7885 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7886 %                                                                             %
7887 %                                                                             %
7888 %                                                                             %
7889 %   S e t M S L A t t r i b u t e s                                           %
7890 %                                                                             %
7891 %                                                                             %
7892 %                                                                             %
7893 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7894 %
7895 %  SetMSLAttributes() ...
7896 %
7897 %  The format of the SetMSLAttributes method is:
7898 %
7899 %      MagickBooleanType SetMSLAttributes(MSLInfo *msl_info,
7900 %        const char *keyword,const char *value)
7901 %
7902 %  A description of each parameter follows:
7903 %
7904 %    o msl_info: the MSL info.
7905 %
7906 %    o keyword: the keyword.
7907 %
7908 %    o value: the value.
7909 %
7910 */
7911 static MagickBooleanType SetMSLAttributes(MSLInfo *msl_info,const char *keyword,
7912   const char *value)
7913 {
7914   Image
7915     *attributes;
7916
7917   DrawInfo
7918     *draw_info;
7919
7920   ExceptionInfo
7921     *exception;
7922
7923   GeometryInfo
7924     geometry_info;
7925
7926   Image
7927     *image;
7928
7929   ImageInfo
7930     *image_info;
7931
7932   int
7933     flags;
7934
7935   ssize_t
7936     n;
7937
7938   assert(msl_info != (MSLInfo *) NULL);
7939   if (keyword == (const char *) NULL)
7940     return(MagickTrue);
7941   if (value == (const char *) NULL)
7942     return(MagickTrue);
7943   exception=msl_info->exception;
7944   n=msl_info->n;
7945   attributes=msl_info->attributes[n];
7946   image_info=msl_info->image_info[n];
7947   draw_info=msl_info->draw_info[n];
7948   image=msl_info->image[n];
7949   switch (*keyword)
7950   {
7951     case 'A':
7952     case 'a':
7953     {
7954       if (LocaleCompare(keyword,"adjoin") == 0)
7955         {
7956           ssize_t
7957             adjoin;
7958
7959           adjoin=ParseCommandOption(MagickBooleanOptions,MagickFalse,value);
7960           if (adjoin < 0)
7961             ThrowMSLException(OptionError,"UnrecognizedType",value);
7962           image_info->adjoin=(MagickBooleanType) adjoin;
7963           break;
7964         }
7965       if (LocaleCompare(keyword,"alpha") == 0)
7966         {
7967           ssize_t
7968             alpha;
7969
7970           alpha=ParseCommandOption(MagickAlphaChannelOptions,MagickFalse,value);
7971           if (alpha < 0)
7972             ThrowMSLException(OptionError,"UnrecognizedType",value);
7973           if (image != (Image *) NULL)
7974             (void) SetImageAlphaChannel(image,(AlphaChannelOption) alpha,
7975               exception);
7976           break;
7977         }
7978       if (LocaleCompare(keyword,"antialias") == 0)
7979         {
7980           ssize_t
7981             antialias;
7982
7983           antialias=ParseCommandOption(MagickBooleanOptions,MagickFalse,value);
7984           if (antialias < 0)
7985             ThrowMSLException(OptionError,"UnrecognizedGravityType",value);
7986           image_info->antialias=(MagickBooleanType) antialias;
7987           break;
7988         }
7989       if (LocaleCompare(keyword,"area-limit") == 0)
7990         {
7991           MagickSizeType
7992             limit;
7993
7994           limit=MagickResourceInfinity;
7995           if (LocaleCompare(value,"unlimited") != 0)
7996             limit=(MagickSizeType) StringToDoubleInterval(value,100.0);
7997           (void) SetMagickResourceLimit(AreaResource,limit);
7998           break;
7999         }
8000       if (LocaleCompare(keyword,"attenuate") == 0)
8001         {
8002           (void) SetImageOption(image_info,keyword,value);
8003           break;
8004         }
8005       if (LocaleCompare(keyword,"authenticate") == 0)
8006         {
8007           (void) CloneString(&image_info->density,value);
8008           break;
8009         }
8010       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8011       break;
8012     }
8013     case 'B':
8014     case 'b':
8015     {
8016       if (LocaleCompare(keyword,"background") == 0)
8017         {
8018           (void) QueryColorCompliance(value,AllCompliance,
8019             &image_info->background_color,exception);
8020           break;
8021         }
8022       if (LocaleCompare(keyword,"blue-primary") == 0)
8023         {
8024           if (image == (Image *) NULL)
8025             break;
8026           flags=ParseGeometry(value,&geometry_info);
8027           image->chromaticity.blue_primary.x=geometry_info.rho;
8028           image->chromaticity.blue_primary.y=geometry_info.sigma;
8029           if ((flags & SigmaValue) == 0)
8030             image->chromaticity.blue_primary.y=
8031               image->chromaticity.blue_primary.x;
8032           break;
8033         }
8034       if (LocaleCompare(keyword,"bordercolor") == 0)
8035         {
8036           (void) QueryColorCompliance(value,AllCompliance,
8037             &image_info->border_color,exception);
8038           break;
8039         }
8040       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8041       break;
8042     }
8043     case 'D':
8044     case 'd':
8045     {
8046       if (LocaleCompare(keyword,"density") == 0)
8047         {
8048           (void) CloneString(&image_info->density,value);
8049           (void) CloneString(&draw_info->density,value);
8050           break;
8051         }
8052       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8053       break;
8054     }
8055     case 'F':
8056     case 'f':
8057     {
8058       if (LocaleCompare(keyword,"fill") == 0)
8059         {
8060           (void) QueryColorCompliance(value,AllCompliance,&draw_info->fill,
8061             exception);
8062           (void) SetImageOption(image_info,keyword,value);
8063           break;
8064         }
8065       if (LocaleCompare(keyword,"filename") == 0)
8066         {
8067           (void) CopyMagickString(image_info->filename,value,MaxTextExtent);
8068           break;
8069         }
8070       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8071       break;
8072     }
8073     case 'G':
8074     case 'g':
8075     {
8076       if (LocaleCompare(keyword,"gravity") == 0)
8077         {
8078           ssize_t
8079             gravity;
8080
8081           gravity=ParseCommandOption(MagickGravityOptions,MagickFalse,value);
8082           if (gravity < 0)
8083             ThrowMSLException(OptionError,"UnrecognizedGravityType",value);
8084           (void) SetImageOption(image_info,keyword,value);
8085           break;
8086         }
8087       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8088       break;
8089     }
8090     case 'I':
8091     case 'i':
8092     {
8093       if (LocaleCompare(keyword,"id") == 0)
8094         {
8095           (void) SetImageProperty(attributes,keyword,value,exception);
8096           break;
8097         }
8098       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8099       break;
8100     }
8101     case 'M':
8102     case 'm':
8103     {
8104       if (LocaleCompare(keyword,"magick") == 0)
8105         {
8106           (void) CopyMagickString(image_info->magick,value,MaxTextExtent);
8107           break;
8108         }
8109       if (LocaleCompare(keyword,"mattecolor") == 0)
8110         {
8111           (void) QueryColorCompliance(value,AllCompliance,
8112             &image_info->matte_color,exception);
8113           break;
8114         }
8115       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8116       break;
8117     }
8118     case 'P':
8119     case 'p':
8120     {
8121       if (LocaleCompare(keyword,"pointsize") == 0)
8122         {
8123           image_info->pointsize=StringToDouble(value,(char **) NULL);
8124           draw_info->pointsize=StringToDouble(value,(char **) NULL);
8125           break;
8126         }
8127       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8128       break;
8129     }
8130     case 'Q':
8131     case 'q':
8132     {
8133       if (LocaleCompare(keyword,"quality") == 0)
8134         {
8135           image_info->quality=StringToLong(value);
8136           if (image == (Image *) NULL)
8137             break;
8138           image->quality=StringToLong(value);
8139           break;
8140         }
8141       break;
8142     }
8143     case 'S':
8144     case 's':
8145     {
8146       if (LocaleCompare(keyword,"size") == 0)
8147         {
8148           (void) CloneString(&image_info->size,value);
8149           break;
8150         }
8151       if (LocaleCompare(keyword,"stroke") == 0)
8152         {
8153           (void) QueryColorCompliance(value,AllCompliance,&draw_info->stroke,
8154             exception);
8155           (void) SetImageOption(image_info,keyword,value);
8156           break;
8157         }
8158       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8159       break;
8160     }
8161     default:
8162     {
8163       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8164       break;
8165     }
8166   }
8167   return(MagickTrue);
8168 }
8169 #endif
8170 \f
8171 /*
8172 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8173 %                                                                             %
8174 %                                                                             %
8175 %                                                                             %
8176 %   U n r e g i s t e r M S L I m a g e                                       %
8177 %                                                                             %
8178 %                                                                             %
8179 %                                                                             %
8180 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8181 %
8182 %  UnregisterMSLImage() removes format registrations made by the
8183 %  MSL module from the list of supported formats.
8184 %
8185 %  The format of the UnregisterMSLImage method is:
8186 %
8187 %      UnregisterMSLImage(void)
8188 %
8189 */
8190 ModuleExport void UnregisterMSLImage(void)
8191 {
8192   (void) UnregisterMagickInfo("MSL");
8193 #if defined(MAGICKCORE_XML_DELEGATE)
8194   xmlCleanupParser();
8195 #endif
8196 }
8197 \f
8198 #if defined(MAGICKCORE_XML_DELEGATE)
8199 /*
8200 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8201 %                                                                             %
8202 %                                                                             %
8203 %                                                                             %
8204 %   W r i t e M S L I m a g e                                                 %
8205 %                                                                             %
8206 %                                                                             %
8207 %                                                                             %
8208 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8209 %
8210 %  WriteMSLImage() writes an image to a file in MVG image format.
8211 %
8212 %  The format of the WriteMSLImage method is:
8213 %
8214 %      MagickBooleanType WriteMSLImage(const ImageInfo *image_info,
8215 %        Image *image,ExceptionInfo *exception)
8216 %
8217 %  A description of each parameter follows.
8218 %
8219 %    o image_info: the image info.
8220 %
8221 %    o image:  The image.
8222 %
8223 %    o exception: return any errors or warnings in this structure.
8224 %
8225 */
8226 static MagickBooleanType WriteMSLImage(const ImageInfo *image_info,Image *image,
8227   ExceptionInfo *exception)
8228 {
8229   assert(image_info != (const ImageInfo *) NULL);
8230   assert(image_info->signature == MagickSignature);
8231   assert(image != (Image *) NULL);
8232   assert(image->signature == MagickSignature);
8233   if (image->debug != MagickFalse)
8234     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
8235   (void) ReferenceImage(image);
8236   (void) ProcessMSLScript(image_info,&image,exception);
8237   return(MagickTrue);
8238 }
8239 #endif