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