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