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