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