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