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