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