]> 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,
1065             "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,(double)
1066             geometry.height,(double) geometry.x,(double) 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+=(ssize_t) height)
1988                          for (x=0; x < (ssize_t) image->columns; x+=(ssize_t) 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             "%.20gx%.20g%+.20g%+.20g",(double) composite_image->columns,
2044             (double) composite_image->rows,(double) geometry.x,(double)
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,
2655             "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,(double)
2656             geometry.height,(double) geometry.x,(double) 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,"%.20g",
3269                       (double) 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,"%.20g",
3281                       (double) 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,
4798             "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,(double)
4799             geometry.height,(double) geometry.x,(double) 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,"%.20gx%.20g",
6052                   (double) geometry.width,(double) geometry.height);
6053                 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
6054                   (void) FormatMagickString(page,MaxTextExtent,
6055                     "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,
6056                     (double) geometry.height,(double) geometry.x,(double)
6057                     geometry.y);
6058                 (void) SetImageOption(msl_info->image_info[n],keyword,page);
6059                 msl_info->image_info[n]->page=GetPageGeometry(page);
6060                 break;
6061               }
6062               (void) SetMSLAttributes(msl_info,keyword,value);
6063               break;
6064             }
6065             default:
6066             {
6067               (void) SetMSLAttributes(msl_info,keyword,value);
6068               break;
6069             }
6070           }
6071         }
6072         break;
6073       }
6074       if (LocaleCompare((const char *) tag,"shade") == 0)
6075         {
6076           Image
6077             *shade_image;
6078
6079           MagickBooleanType
6080             gray;
6081
6082           /*
6083             Shade image.
6084           */
6085           if (msl_info->image[n] == (Image *) NULL)
6086             {
6087               ThrowMSLException(OptionError,"NoImagesDefined",
6088                 (const char *) tag);
6089               break;
6090             }
6091           gray=MagickFalse;
6092           if (attributes != (const xmlChar **) NULL)
6093             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6094             {
6095               keyword=(const char *) attributes[i++];
6096               attribute=InterpretImageProperties(msl_info->image_info[n],
6097                 msl_info->attributes[n],(const char *) attributes[i]);
6098               CloneString(&value,attribute);
6099               switch (*keyword)
6100               {
6101                 case 'A':
6102                 case 'a':
6103                 {
6104                   if (LocaleCompare(keyword,"azimuth") == 0)
6105                     {
6106                       geometry_info.rho=StringToDouble(value);
6107                       break;
6108                     }
6109                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6110                     keyword);
6111                   break;
6112                 }
6113                 case 'E':
6114                 case 'e':
6115                 {
6116                   if (LocaleCompare(keyword,"elevation") == 0)
6117                     {
6118                       geometry_info.sigma=StringToDouble(value);
6119                       break;
6120                     }
6121                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6122                     keyword);
6123                   break;
6124                 }
6125                 case 'G':
6126                 case 'g':
6127                 {
6128                   if (LocaleCompare(keyword,"geometry") == 0)
6129                     {
6130                       flags=ParseGeometry(value,&geometry_info);
6131                       if ((flags & SigmaValue) == 0)
6132                         geometry_info.sigma=1.0;
6133                       break;
6134                     }
6135                   if (LocaleCompare(keyword,"gray") == 0)
6136                     {
6137                       option=ParseMagickOption(MagickBooleanOptions,MagickFalse,
6138                         value);
6139                       if (option < 0)
6140                         ThrowMSLException(OptionError,"UnrecognizedNoiseType",
6141                           value);
6142                       gray=(MagickBooleanType) option;
6143                       break;
6144                     }
6145                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6146                     keyword);
6147                   break;
6148                 }
6149                 default:
6150                 {
6151                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6152                     keyword);
6153                   break;
6154                 }
6155               }
6156             }
6157           shade_image=ShadeImage(msl_info->image[n],gray,geometry_info.rho,
6158             geometry_info.sigma,&msl_info->image[n]->exception);
6159           if (shade_image == (Image *) NULL)
6160             break;
6161           msl_info->image[n]=DestroyImage(msl_info->image[n]);
6162           msl_info->image[n]=shade_image;
6163           break;
6164         }
6165       if (LocaleCompare((const char *) tag,"shadow") == 0)
6166         {
6167           Image
6168             *shadow_image;
6169
6170           /*
6171             Shear image.
6172           */
6173           if (msl_info->image[n] == (Image *) NULL)
6174             {
6175               ThrowMSLException(OptionError,"NoImagesDefined",
6176                 (const char *) tag);
6177               break;
6178             }
6179           if (attributes != (const xmlChar **) NULL)
6180             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6181             {
6182               keyword=(const char *) attributes[i++];
6183               attribute=InterpretImageProperties(msl_info->image_info[n],
6184                 msl_info->attributes[n],(const char *) attributes[i]);
6185               CloneString(&value,attribute);
6186               switch (*keyword)
6187               {
6188                 case 'G':
6189                 case 'g':
6190                 {
6191                   if (LocaleCompare(keyword,"geometry") == 0)
6192                     {
6193                       flags=ParseGeometry(value,&geometry_info);
6194                       if ((flags & SigmaValue) == 0)
6195                         geometry_info.sigma=1.0;
6196                       break;
6197                     }
6198                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6199                     keyword);
6200                   break;
6201                 }
6202                 case 'O':
6203                 case 'o':
6204                 {
6205                   if (LocaleCompare(keyword,"opacity") == 0)
6206                     {
6207                       geometry_info.rho=StringToLong(value);
6208                       break;
6209                     }
6210                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6211                     keyword);
6212                   break;
6213                 }
6214                 case 'S':
6215                 case 's':
6216                 {
6217                   if (LocaleCompare(keyword,"sigma") == 0)
6218                     {
6219                       geometry_info.sigma=StringToLong(value);
6220                       break;
6221                     }
6222                   break;
6223                 }
6224                 case 'X':
6225                 case 'x':
6226                 {
6227                   if (LocaleCompare(keyword,"x") == 0)
6228                     {
6229                       geometry_info.xi=StringToDouble(value);
6230                       break;
6231                     }
6232                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6233                     keyword);
6234                   break;
6235                 }
6236                 case 'Y':
6237                 case 'y':
6238                 {
6239                   if (LocaleCompare(keyword,"y") == 0)
6240                     {
6241                       geometry_info.psi=StringToLong(value);
6242                       break;
6243                     }
6244                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6245                     keyword);
6246                   break;
6247                 }
6248                 default:
6249                 {
6250                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6251                     keyword);
6252                   break;
6253                 }
6254               }
6255             }
6256           shadow_image=ShadowImage(msl_info->image[n],geometry_info.rho,
6257             geometry_info.sigma,(ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
6258             ceil(geometry_info.psi-0.5),&msl_info->image[n]->exception);
6259           if (shadow_image == (Image *) NULL)
6260             break;
6261           msl_info->image[n]=DestroyImage(msl_info->image[n]);
6262           msl_info->image[n]=shadow_image;
6263           break;
6264         }
6265       if (LocaleCompare((const char *) tag,"sharpen") == 0)
6266       {
6267         double  radius = 0.0,
6268             sigma = 1.0;
6269
6270         if (msl_info->image[n] == (Image *) NULL)
6271           {
6272             ThrowMSLException(OptionError,"NoImagesDefined",
6273               (const char *) tag);
6274             break;
6275           }
6276         /*
6277         NOTE: sharpen can have no attributes, since we use all the defaults!
6278         */
6279         if (attributes != (const xmlChar **) NULL)
6280         {
6281           for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6282           {
6283           keyword=(const char *) attributes[i++];
6284           CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
6285             msl_info->attributes[n],(const char *) attributes[i]));
6286           switch (*keyword)
6287           {
6288             case 'R':
6289             case 'r':
6290             {
6291               if (LocaleCompare(keyword, "radius") == 0)
6292               {
6293                 radius = StringToDouble( value );
6294                 break;
6295               }
6296               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6297               break;
6298             }
6299             case 'S':
6300             case 's':
6301             {
6302               if (LocaleCompare(keyword,"sigma") == 0)
6303               {
6304                 sigma = StringToLong( value );
6305                 break;
6306               }
6307               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6308               break;
6309             }
6310             default:
6311             {
6312               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6313               break;
6314             }
6315           }
6316           }
6317         }
6318
6319         /*
6320           sharpen image.
6321         */
6322         {
6323         Image
6324           *newImage;
6325
6326         newImage=SharpenImage(msl_info->image[n],radius,sigma,&msl_info->image[n]->exception);
6327         if (newImage == (Image *) NULL)
6328           break;
6329         msl_info->image[n]=DestroyImage(msl_info->image[n]);
6330         msl_info->image[n]=newImage;
6331         break;
6332         }
6333       }
6334       else if (LocaleCompare((const char *) tag,"shave") == 0)
6335       {
6336         /* init the values */
6337         width = height = 0;
6338         x = y = 0;
6339
6340         if (msl_info->image[n] == (Image *) NULL)
6341         {
6342           ThrowMSLException(OptionError,"NoImagesDefined",
6343             (const char *) tag);
6344           break;
6345         }
6346         if (attributes == (const xmlChar **) NULL)
6347         break;
6348         for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6349         {
6350         keyword=(const char *) attributes[i++];
6351         CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
6352           msl_info->attributes[n],(const char *) attributes[i]));
6353         switch (*keyword)
6354         {
6355           case 'G':
6356           case 'g':
6357           {
6358           if (LocaleCompare(keyword,"geometry") == 0)
6359             {
6360             (void) ParseMetaGeometry(value,&x,&y,&width,&height);
6361             break;
6362             }
6363           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6364           break;
6365           }
6366           case 'H':
6367           case 'h':
6368           {
6369           if (LocaleCompare(keyword,"height") == 0)
6370             {
6371             height = StringToLong( value );
6372             break;
6373             }
6374           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6375           break;
6376           }
6377           case 'W':
6378           case 'w':
6379           {
6380           if (LocaleCompare(keyword,"width") == 0)
6381             {
6382             width = StringToLong( value );
6383             break;
6384             }
6385           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6386           break;
6387           }
6388           default:
6389           {
6390           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6391           break;
6392           }
6393         }
6394         }
6395
6396         /*
6397           process image.
6398         */
6399         {
6400         Image
6401           *newImage;
6402         RectangleInfo
6403           rectInfo;
6404
6405         rectInfo.height = height;
6406         rectInfo.width = width;
6407         rectInfo.x = x;
6408         rectInfo.y = y;
6409
6410
6411         newImage=ShaveImage(msl_info->image[n], &rectInfo,
6412           &msl_info->image[n]->exception);
6413         if (newImage == (Image *) NULL)
6414           break;
6415         msl_info->image[n]=DestroyImage(msl_info->image[n]);
6416         msl_info->image[n]=newImage;
6417         }
6418
6419         break;
6420       }
6421       if (LocaleCompare((const char *) tag,"shear") == 0)
6422         {
6423           Image
6424             *shear_image;
6425
6426           /*
6427             Shear image.
6428           */
6429           if (msl_info->image[n] == (Image *) NULL)
6430             {
6431               ThrowMSLException(OptionError,"NoImagesDefined",
6432                 (const char *) tag);
6433               break;
6434             }
6435           if (attributes != (const xmlChar **) NULL)
6436             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6437             {
6438               keyword=(const char *) attributes[i++];
6439               attribute=InterpretImageProperties(msl_info->image_info[n],
6440                 msl_info->attributes[n],(const char *) attributes[i]);
6441               CloneString(&value,attribute);
6442               switch (*keyword)
6443               {
6444                 case 'F':
6445                 case 'f':
6446                 {
6447                   if (LocaleCompare(keyword, "fill") == 0)
6448                     {
6449                       (void) QueryColorDatabase(value,
6450                         &msl_info->image[n]->background_color,&exception);
6451                       break;
6452                     }
6453                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6454                     keyword);
6455                   break;
6456                 }
6457                 case 'G':
6458                 case 'g':
6459                 {
6460                   if (LocaleCompare(keyword,"geometry") == 0)
6461                     {
6462                       flags=ParseGeometry(value,&geometry_info);
6463                       if ((flags & SigmaValue) == 0)
6464                         geometry_info.sigma=1.0;
6465                       break;
6466                     }
6467                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6468                     keyword);
6469                   break;
6470                 }
6471                 case 'X':
6472                 case 'x':
6473                 {
6474                   if (LocaleCompare(keyword,"x") == 0)
6475                     {
6476                       geometry_info.rho=StringToDouble(value);
6477                       break;
6478                     }
6479                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6480                     keyword);
6481                   break;
6482                 }
6483                 case 'Y':
6484                 case 'y':
6485                 {
6486                   if (LocaleCompare(keyword,"y") == 0)
6487                     {
6488                       geometry_info.sigma=StringToLong(value);
6489                       break;
6490                     }
6491                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6492                     keyword);
6493                   break;
6494                 }
6495                 default:
6496                 {
6497                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6498                     keyword);
6499                   break;
6500                 }
6501               }
6502             }
6503           shear_image=ShearImage(msl_info->image[n],geometry_info.rho,
6504             geometry_info.sigma,&msl_info->image[n]->exception);
6505           if (shear_image == (Image *) NULL)
6506             break;
6507           msl_info->image[n]=DestroyImage(msl_info->image[n]);
6508           msl_info->image[n]=shear_image;
6509           break;
6510         }
6511       if (LocaleCompare((const char *) tag,"signature") == 0)
6512         {
6513           /*
6514             Signature image.
6515           */
6516           if (msl_info->image[n] == (Image *) NULL)
6517             {
6518               ThrowMSLException(OptionError,"NoImagesDefined",
6519                 (const char *) tag);
6520               break;
6521             }
6522           if (attributes != (const xmlChar **) NULL)
6523             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6524             {
6525               keyword=(const char *) attributes[i++];
6526               attribute=InterpretImageProperties(msl_info->image_info[n],
6527                 msl_info->attributes[n],(const char *) attributes[i]);
6528               CloneString(&value,attribute);
6529               switch (*keyword)
6530               {
6531                 default:
6532                 {
6533                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6534                     keyword);
6535                   break;
6536                 }
6537               }
6538             }
6539           (void) SignatureImage(msl_info->image[n]);
6540           break;
6541         }
6542       if (LocaleCompare((const char *) tag,"solarize") == 0)
6543         {
6544           /*
6545             Solarize image.
6546           */
6547           if (msl_info->image[n] == (Image *) NULL)
6548             {
6549               ThrowMSLException(OptionError,"NoImagesDefined",
6550                 (const char *) tag);
6551               break;
6552             }
6553           geometry_info.rho=QuantumRange/2.0;
6554           if (attributes != (const xmlChar **) NULL)
6555             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6556             {
6557               keyword=(const char *) attributes[i++];
6558               attribute=InterpretImageProperties(msl_info->image_info[n],
6559                 msl_info->attributes[n],(const char *) attributes[i]);
6560               CloneString(&value,attribute);
6561               switch (*keyword)
6562               {
6563                 case 'G':
6564                 case 'g':
6565                 {
6566                   if (LocaleCompare(keyword,"geometry") == 0)
6567                     {
6568                       flags=ParseGeometry(value,&geometry_info);
6569                       break;
6570                     }
6571                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6572                     keyword);
6573                   break;
6574                 }
6575                 case 'T':
6576                 case 't':
6577                 {
6578                   if (LocaleCompare(keyword,"threshold") == 0)
6579                     {
6580                       geometry_info.rho=StringToDouble(value);
6581                       break;
6582                     }
6583                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6584                     keyword);
6585                   break;
6586                 }
6587                 default:
6588                 {
6589                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6590                     keyword);
6591                   break;
6592                 }
6593               }
6594             }
6595           (void) SolarizeImage(msl_info->image[n],geometry_info.rho);
6596           break;
6597         }
6598       if (LocaleCompare((const char *) tag,"spread") == 0)
6599         {
6600           Image
6601             *spread_image;
6602
6603           /*
6604             Spread image.
6605           */
6606           if (msl_info->image[n] == (Image *) NULL)
6607             {
6608               ThrowMSLException(OptionError,"NoImagesDefined",
6609                 (const char *) tag);
6610               break;
6611             }
6612           if (attributes != (const xmlChar **) NULL)
6613             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6614             {
6615               keyword=(const char *) attributes[i++];
6616               attribute=InterpretImageProperties(msl_info->image_info[n],
6617                 msl_info->attributes[n],(const char *) attributes[i]);
6618               CloneString(&value,attribute);
6619               switch (*keyword)
6620               {
6621                 case 'G':
6622                 case 'g':
6623                 {
6624                   if (LocaleCompare(keyword,"geometry") == 0)
6625                     {
6626                       flags=ParseGeometry(value,&geometry_info);
6627                       if ((flags & SigmaValue) == 0)
6628                         geometry_info.sigma=1.0;
6629                       break;
6630                     }
6631                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6632                     keyword);
6633                   break;
6634                 }
6635                 case 'R':
6636                 case 'r':
6637                 {
6638                   if (LocaleCompare(keyword,"radius") == 0)
6639                     {
6640                       geometry_info.rho=StringToDouble(value);
6641                       break;
6642                     }
6643                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6644                     keyword);
6645                   break;
6646                 }
6647                 default:
6648                 {
6649                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6650                     keyword);
6651                   break;
6652                 }
6653               }
6654             }
6655           spread_image=SpreadImage(msl_info->image[n],geometry_info.rho,
6656             &msl_info->image[n]->exception);
6657           if (spread_image == (Image *) NULL)
6658             break;
6659           msl_info->image[n]=DestroyImage(msl_info->image[n]);
6660           msl_info->image[n]=spread_image;
6661           break;
6662         }
6663       else if (LocaleCompare((const char *) tag,"stegano") == 0)
6664       {
6665         Image *
6666           watermark = (Image*)NULL;
6667
6668         if (msl_info->image[n] == (Image *) NULL)
6669           {
6670             ThrowMSLException(OptionError,"NoImagesDefined",
6671               (const char *) tag);
6672             break;
6673           }
6674         if (attributes == (const xmlChar **) NULL)
6675         break;
6676         for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6677         {
6678         keyword=(const char *) attributes[i++];
6679         CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
6680           msl_info->attributes[n],(const char *) attributes[i]));
6681         switch (*keyword)
6682         {
6683           case 'I':
6684           case 'i':
6685           {
6686           if (LocaleCompare(keyword,"image") == 0)
6687             {
6688             for (j=0; j<msl_info->n;j++)
6689             {
6690               const char *
6691                 theAttr = GetImageProperty(msl_info->attributes[j], "id");
6692               if (theAttr && LocaleCompare(theAttr, value) == 0)
6693               {
6694                 watermark = msl_info->image[j];
6695                 break;
6696               }
6697             }
6698             break;
6699             }
6700           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6701           break;
6702           }
6703           default:
6704           {
6705           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6706           break;
6707           }
6708         }
6709         }
6710
6711         /*
6712           process image.
6713         */
6714         if ( watermark != (Image*) NULL )
6715         {
6716         Image
6717           *newImage;
6718
6719         newImage=SteganoImage(msl_info->image[n], watermark, &msl_info->image[n]->exception);
6720         if (newImage == (Image *) NULL)
6721           break;
6722         msl_info->image[n]=DestroyImage(msl_info->image[n]);
6723         msl_info->image[n]=newImage;
6724         break;
6725         } else
6726           ThrowMSLException(OptionError,"MissingWatermarkImage",keyword);
6727       }
6728       else if (LocaleCompare((const char *) tag,"stereo") == 0)
6729       {
6730         Image *
6731           stereoImage = (Image*)NULL;
6732
6733         if (msl_info->image[n] == (Image *) NULL)
6734           {
6735             ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
6736             break;
6737           }
6738         if (attributes == (const xmlChar **) NULL)
6739         break;
6740         for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6741         {
6742         keyword=(const char *) attributes[i++];
6743         CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
6744           msl_info->attributes[n],(const char *) attributes[i]));
6745         switch (*keyword)
6746         {
6747           case 'I':
6748           case 'i':
6749           {
6750           if (LocaleCompare(keyword,"image") == 0)
6751             {
6752             for (j=0; j<msl_info->n;j++)
6753             {
6754               const char *
6755                 theAttr = GetImageProperty(msl_info->attributes[j], "id");
6756               if (theAttr && LocaleCompare(theAttr, value) == 0)
6757               {
6758                 stereoImage = msl_info->image[j];
6759                 break;
6760               }
6761             }
6762             break;
6763             }
6764           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6765           break;
6766           }
6767           default:
6768           {
6769           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6770           break;
6771           }
6772         }
6773         }
6774
6775         /*
6776           process image.
6777         */
6778         if ( stereoImage != (Image*) NULL )
6779         {
6780         Image
6781           *newImage;
6782
6783         newImage=StereoImage(msl_info->image[n], stereoImage, &msl_info->image[n]->exception);
6784         if (newImage == (Image *) NULL)
6785           break;
6786         msl_info->image[n]=DestroyImage(msl_info->image[n]);
6787         msl_info->image[n]=newImage;
6788         break;
6789         } else
6790           ThrowMSLException(OptionError,"Missing stereo image",keyword);
6791       }
6792       if (LocaleCompare((const char *) tag,"swap") == 0)
6793         {
6794           Image
6795             *p,
6796             *q,
6797             *swap;
6798
6799           ssize_t
6800             index,
6801             swap_index;
6802
6803           if (msl_info->image[n] == (Image *) NULL)
6804             {
6805               ThrowMSLException(OptionError,"NoImagesDefined",
6806                 (const char *) tag);
6807               break;
6808             }
6809           index=(-1);
6810           swap_index=(-2);
6811           if (attributes != (const xmlChar **) NULL)
6812             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6813             {
6814               keyword=(const char *) attributes[i++];
6815               attribute=InterpretImageProperties(msl_info->image_info[n],
6816                 msl_info->attributes[n],(const char *) attributes[i]);
6817               CloneString(&value,attribute);
6818               switch (*keyword)
6819               {
6820                 case 'G':
6821                 case 'g':
6822                 {
6823                   if (LocaleCompare(keyword,"indexes") == 0)
6824                     {
6825                       flags=ParseGeometry(value,&geometry_info);
6826                       index=(ssize_t) geometry_info.rho;
6827                       if ((flags & SigmaValue) == 0)
6828                         swap_index=(ssize_t) geometry_info.sigma;
6829                       break;
6830                     }
6831                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6832                     keyword);
6833                   break;
6834                 }
6835                 default:
6836                 {
6837                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6838                     keyword);
6839                   break;
6840                 }
6841               }
6842             }
6843           /*
6844             Swap images.
6845           */
6846           p=GetImageFromList(msl_info->image[n],index);
6847           q=GetImageFromList(msl_info->image[n],swap_index);
6848           if ((p == (Image *) NULL) || (q == (Image *) NULL))
6849             {
6850               ThrowMSLException(OptionError,"NoSuchImage",(const char *) tag);
6851               break;
6852             }
6853           swap=CloneImage(p,0,0,MagickTrue,&p->exception);
6854           ReplaceImageInList(&p,CloneImage(q,0,0,MagickTrue,&q->exception));
6855           ReplaceImageInList(&q,swap);
6856           msl_info->image[n]=GetFirstImageInList(q);
6857           break;
6858         }
6859       if (LocaleCompare((const char *) tag,"swirl") == 0)
6860         {
6861           Image
6862             *swirl_image;
6863
6864           /*
6865             Swirl image.
6866           */
6867           if (msl_info->image[n] == (Image *) NULL)
6868             {
6869               ThrowMSLException(OptionError,"NoImagesDefined",
6870                 (const char *) tag);
6871               break;
6872             }
6873           if (attributes != (const xmlChar **) NULL)
6874             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6875             {
6876               keyword=(const char *) attributes[i++];
6877               attribute=InterpretImageProperties(msl_info->image_info[n],
6878                 msl_info->attributes[n],(const char *) attributes[i]);
6879               CloneString(&value,attribute);
6880               switch (*keyword)
6881               {
6882                 case 'D':
6883                 case 'd':
6884                 {
6885                   if (LocaleCompare(keyword,"degrees") == 0)
6886                     {
6887                       geometry_info.rho=StringToDouble(value);
6888                       break;
6889                     }
6890                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6891                     keyword);
6892                   break;
6893                 }
6894                 case 'G':
6895                 case 'g':
6896                 {
6897                   if (LocaleCompare(keyword,"geometry") == 0)
6898                     {
6899                       flags=ParseGeometry(value,&geometry_info);
6900                       if ((flags & SigmaValue) == 0)
6901                         geometry_info.sigma=1.0;
6902                       break;
6903                     }
6904                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6905                     keyword);
6906                   break;
6907                 }
6908                 default:
6909                 {
6910                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6911                     keyword);
6912                   break;
6913                 }
6914               }
6915             }
6916           swirl_image=SwirlImage(msl_info->image[n],geometry_info.rho,
6917             &msl_info->image[n]->exception);
6918           if (swirl_image == (Image *) NULL)
6919             break;
6920           msl_info->image[n]=DestroyImage(msl_info->image[n]);
6921           msl_info->image[n]=swirl_image;
6922           break;
6923         }
6924       if (LocaleCompare((const char *) tag,"sync") == 0)
6925         {
6926           /*
6927             Sync image.
6928           */
6929           if (msl_info->image[n] == (Image *) NULL)
6930             {
6931               ThrowMSLException(OptionError,"NoImagesDefined",
6932                 (const char *) tag);
6933               break;
6934             }
6935           if (attributes != (const xmlChar **) NULL)
6936             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6937             {
6938               keyword=(const char *) attributes[i++];
6939               attribute=InterpretImageProperties(msl_info->image_info[n],
6940                 msl_info->attributes[n],(const char *) attributes[i]);
6941               CloneString(&value,attribute);
6942               switch (*keyword)
6943               {
6944                 default:
6945                 {
6946                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
6947                     keyword);
6948                   break;
6949                 }
6950               }
6951             }
6952           (void) SyncImage(msl_info->image[n]);
6953           break;
6954         }
6955       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
6956     }
6957     case 'T':
6958     case 't':
6959     {
6960       if (LocaleCompare((const char *) tag,"map") == 0)
6961         {
6962           Image
6963             *texture_image;
6964
6965           /*
6966             Texture image.
6967           */
6968           if (msl_info->image[n] == (Image *) NULL)
6969             {
6970               ThrowMSLException(OptionError,"NoImagesDefined",
6971                 (const char *) tag);
6972               break;
6973             }
6974           texture_image=NewImageList();
6975           if (attributes != (const xmlChar **) NULL)
6976             for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6977             {
6978               keyword=(const char *) attributes[i++];
6979               attribute=InterpretImageProperties(msl_info->image_info[n],
6980                 msl_info->attributes[n],(const char *) attributes[i]);
6981               CloneString(&value,attribute);
6982               switch (*keyword)
6983               {
6984                 case 'I':
6985                 case 'i':
6986                 {
6987                   if (LocaleCompare(keyword,"image") == 0)
6988                     for (j=0; j < msl_info->n; j++)
6989                     {
6990                       const char
6991                         *attribute;
6992
6993                       attribute=GetImageProperty(msl_info->attributes[j],"id");
6994                       if ((attribute != (const char *) NULL)  &&
6995                           (LocaleCompare(attribute,value) == 0))
6996                         {
6997                           texture_image=CloneImage(msl_info->image[j],0,0,
6998                             MagickFalse,&exception);
6999                           break;
7000                         }
7001                     }
7002                   break;
7003                 }
7004                 default:
7005                 {
7006                   ThrowMSLException(OptionError,"UnrecognizedAttribute",
7007                     keyword);
7008                   break;
7009                 }
7010               }
7011             }
7012           (void) TextureImage(msl_info->image[n],texture_image);
7013           texture_image=DestroyImage(texture_image);
7014           break;
7015         }
7016       else if (LocaleCompare((const char *) tag,"threshold") == 0)
7017       {
7018         /* init the values */
7019         double  threshold = 0;
7020
7021         if (msl_info->image[n] == (Image *) NULL)
7022           {
7023             ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7024             break;
7025           }
7026         if (attributes == (const xmlChar **) NULL)
7027         break;
7028         for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7029         {
7030         keyword=(const char *) attributes[i++];
7031         CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
7032           msl_info->attributes[n],(const char *) attributes[i]));
7033         switch (*keyword)
7034         {
7035           case 'T':
7036           case 't':
7037           {
7038           if (LocaleCompare(keyword,"threshold") == 0)
7039             {
7040             threshold = StringToDouble( value );
7041             break;
7042             }
7043           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7044           break;
7045           }
7046           default:
7047           {
7048           ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7049           break;
7050           }
7051         }
7052         }
7053
7054         /*
7055           process image.
7056         */
7057         {
7058         BilevelImageChannel(msl_info->image[n],
7059           (ChannelType) ((ssize_t) (AllChannels &~ (ssize_t) OpacityChannel)),
7060           threshold);
7061         break;
7062         }
7063       }
7064       else if (LocaleCompare((const char *) tag, "transparent") == 0)
7065       {
7066         if (msl_info->image[n] == (Image *) NULL)
7067           {
7068             ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7069             break;
7070           }
7071         if (attributes == (const xmlChar **) NULL)
7072           break;
7073         for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7074         {
7075           keyword=(const char *) attributes[i++];
7076           CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
7077             msl_info->attributes[n],(const char *) attributes[i]));
7078           switch (*keyword)
7079           {
7080             case 'C':
7081             case 'c':
7082             {
7083               if (LocaleCompare(keyword,"color") == 0)
7084               {
7085                 MagickPixelPacket
7086                   target;
7087
7088                 (void) QueryMagickColor(value,&target,&exception);
7089                 (void) TransparentPaintImage(msl_info->image[n],&target,
7090                   TransparentOpacity,MagickFalse);
7091                 break;
7092               }
7093               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7094               break;
7095             }
7096             default:
7097             {
7098               ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7099             break;
7100             }
7101           }
7102         }
7103         break;
7104       }
7105       else if (LocaleCompare((const char *) tag, "trim") == 0)
7106       {
7107         if (msl_info->image[n] == (Image *) NULL)
7108           {
7109             ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7110             break;
7111           }
7112
7113         /* no attributes here */
7114
7115         /* process the image */
7116         {
7117           Image
7118             *newImage;
7119           RectangleInfo
7120             rectInfo;
7121
7122           /* all zeros on a crop == trim edges! */
7123           rectInfo.height = rectInfo.width = 0;
7124           rectInfo.x =  rectInfo.y = 0;
7125
7126           newImage=CropImage(msl_info->image[n],&rectInfo, &msl_info->image[n]->exception);
7127           if (newImage == (Image *) NULL)
7128             break;
7129           msl_info->image[n]=DestroyImage(msl_info->image[n]);
7130           msl_info->image[n]=newImage;
7131           break;
7132         }
7133       }
7134       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7135     }
7136     case 'W':
7137     case 'w':
7138     {
7139       if (LocaleCompare((const char *) tag,"write") == 0)
7140         {
7141           if (msl_info->image[n] == (Image *) NULL)
7142             {
7143               ThrowMSLException(OptionError,"NoImagesDefined",
7144                 (const char *) tag);
7145               break;
7146             }
7147           if (attributes == (const xmlChar **) NULL)
7148             break;
7149           for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7150           {
7151             keyword=(const char *) attributes[i++];
7152             CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
7153               msl_info->attributes[n],(const char *) attributes[i]));
7154             switch (*keyword)
7155             {
7156               case 'F':
7157               case 'f':
7158               {
7159                 if (LocaleCompare(keyword,"filename") == 0)
7160                   {
7161                     (void) CopyMagickString(msl_info->image[n]->filename,value,
7162                       MaxTextExtent);
7163                     break;
7164                   }
7165                 (void) SetMSLAttributes(msl_info,keyword,value);
7166               }
7167               default:
7168               {
7169                 (void) SetMSLAttributes(msl_info,keyword,value);
7170                 break;
7171               }
7172             }
7173           }
7174
7175           /* process */
7176           {
7177             (void) WriteImage(msl_info->image_info[n], msl_info->image[n]);
7178             break;
7179           }
7180         }
7181       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7182     }
7183     default:
7184     {
7185       ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7186       break;
7187     }
7188   }
7189   if ( value != NULL )
7190     value=DestroyString(value);
7191   (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  )");
7192 }
7193
7194 static void MSLEndElement(void *context,const xmlChar *tag)
7195 {
7196   ssize_t
7197     n;
7198
7199   MSLInfo
7200     *msl_info;
7201
7202   /*
7203     Called when the end of an element has been detected.
7204   */
7205   (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  SAX.endElement(%s)",
7206     tag);
7207   msl_info=(MSLInfo *) context;
7208   n=msl_info->n;
7209   switch (*tag)
7210   {
7211     case 'C':
7212     case 'c':
7213     {
7214       if (LocaleCompare((const char *) tag,"comment") == 0 )
7215         {
7216           (void) DeleteImageProperty(msl_info->image[n],"comment");
7217           if (msl_info->content == (char *) NULL)
7218             break;
7219           StripString(msl_info->content);
7220           (void) SetImageProperty(msl_info->image[n],"comment",
7221             msl_info->content);
7222           break;
7223         }
7224       break;
7225     }
7226     case 'G':
7227     case 'g':
7228     {
7229       if (LocaleCompare((const char *) tag, "group") == 0 )
7230       {
7231         if (msl_info->group_info[msl_info->number_groups-1].numImages > 0 )
7232         {
7233           ssize_t  i = (ssize_t)
7234             (msl_info->group_info[msl_info->number_groups-1].numImages);
7235           while ( i-- )
7236           {
7237             if (msl_info->image[msl_info->n] != (Image *) NULL)
7238               msl_info->image[msl_info->n]=DestroyImage(msl_info->image[msl_info->n]);
7239             msl_info->attributes[msl_info->n]=DestroyImage(msl_info->attributes[msl_info->n]);
7240             msl_info->image_info[msl_info->n]=DestroyImageInfo(msl_info->image_info[msl_info->n]);
7241             msl_info->n--;
7242           }
7243         }
7244         msl_info->number_groups--;
7245       }
7246       break;
7247     }
7248     case 'I':
7249     case 'i':
7250     {
7251       if (LocaleCompare((const char *) tag, "image") == 0)
7252         MSLPopImage(msl_info);
7253        break;
7254     }
7255     case 'L':
7256     case 'l':
7257     {
7258       if (LocaleCompare((const char *) tag,"label") == 0 )
7259         {
7260           (void) DeleteImageProperty(msl_info->image[n],"label");
7261           if (msl_info->content == (char *) NULL)
7262             break;
7263           StripString(msl_info->content);
7264           (void) SetImageProperty(msl_info->image[n],"label",
7265             msl_info->content);
7266           break;
7267         }
7268       break;
7269     }
7270     case 'M':
7271     case 'm':
7272     {
7273       if (LocaleCompare((const char *) tag, "msl") == 0 )
7274       {
7275         /*
7276           This our base element.
7277             at the moment we don't do anything special
7278             but someday we might!
7279         */
7280       }
7281       break;
7282     }
7283     default:
7284       break;
7285   }
7286   if (msl_info->content != (char *) NULL)
7287     msl_info->content=DestroyString(msl_info->content);
7288 }
7289
7290 static void MSLCharacters(void *context,const xmlChar *c,int length)
7291 {
7292   MSLInfo
7293     *msl_info;
7294
7295   register char
7296     *p;
7297
7298   register ssize_t
7299     i;
7300
7301   /*
7302     Receiving some characters from the parser.
7303   */
7304   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7305     "  SAX.characters(%s,%d)",c,length);
7306   msl_info=(MSLInfo *) context;
7307   if (msl_info->content != (char *) NULL)
7308     msl_info->content=(char *) ResizeQuantumMemory(msl_info->content,
7309       strlen(msl_info->content)+length+MaxTextExtent,
7310       sizeof(*msl_info->content));
7311   else
7312     {
7313       msl_info->content=(char *) NULL;
7314       if (~length >= MaxTextExtent)
7315         msl_info->content=(char *) AcquireQuantumMemory(length+MaxTextExtent,
7316           sizeof(*msl_info->content));
7317       if (msl_info->content != (char *) NULL)
7318         *msl_info->content='\0';
7319     }
7320   if (msl_info->content == (char *) NULL)
7321     return;
7322   p=msl_info->content+strlen(msl_info->content);
7323   for (i=0; i < length; i++)
7324     *p++=c[i];
7325   *p='\0';
7326 }
7327
7328 static void MSLReference(void *context,const xmlChar *name)
7329 {
7330   MSLInfo
7331     *msl_info;
7332
7333   xmlParserCtxtPtr
7334     parser;
7335
7336   /*
7337     Called when an entity reference is detected.
7338   */
7339   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7340     "  SAX.reference(%s)",name);
7341   msl_info=(MSLInfo *) context;
7342   parser=msl_info->parser;
7343   if (*name == '#')
7344     (void) xmlAddChild(parser->node,xmlNewCharRef(msl_info->document,name));
7345   else
7346     (void) xmlAddChild(parser->node,xmlNewReference(msl_info->document,name));
7347 }
7348
7349 static void MSLIgnorableWhitespace(void *context,const xmlChar *c,int length)
7350 {
7351   MSLInfo
7352     *msl_info;
7353
7354   /*
7355     Receiving some ignorable whitespaces from the parser.
7356   */
7357   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7358     "  SAX.ignorableWhitespace(%.30s, %d)",c,length);
7359   msl_info=(MSLInfo *) context;
7360 }
7361
7362 static void MSLProcessingInstructions(void *context,const xmlChar *target,
7363   const xmlChar *data)
7364 {
7365   MSLInfo
7366     *msl_info;
7367
7368   /*
7369     A processing instruction has been parsed.
7370   */
7371   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7372     "  SAX.processingInstruction(%s, %s)",
7373     target,data);
7374   msl_info=(MSLInfo *) context;
7375 }
7376
7377 static void MSLComment(void *context,const xmlChar *value)
7378 {
7379   MSLInfo
7380     *msl_info;
7381
7382   /*
7383     A comment has been parsed.
7384   */
7385   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7386     "  SAX.comment(%s)",value);
7387   msl_info=(MSLInfo *) context;
7388 }
7389
7390 static void MSLWarning(void *context,const char *format,...)
7391 {
7392   char
7393     *message,
7394     reason[MaxTextExtent];
7395
7396   MSLInfo
7397     *msl_info;
7398
7399   va_list
7400     operands;
7401
7402   /**
7403     Display and format a warning messages, gives file, line, position and
7404     extra parameters.
7405   */
7406   va_start(operands,format);
7407   (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  SAX.warning: ");
7408   (void) LogMagickEvent(CoderEvent,GetMagickModule(),format,operands);
7409   msl_info=(MSLInfo *) context;
7410 #if !defined(MAGICKCORE_HAVE_VSNPRINTF)
7411   (void) vsprintf(reason,format,operands);
7412 #else
7413   (void) vsnprintf(reason,MaxTextExtent,format,operands);
7414 #endif
7415   message=GetExceptionMessage(errno);
7416   ThrowMSLException(CoderError,reason,message);
7417   message=DestroyString(message);
7418   va_end(operands);
7419 }
7420
7421 static void MSLError(void *context,const char *format,...)
7422 {
7423   char
7424     reason[MaxTextExtent];
7425
7426   MSLInfo
7427     *msl_info;
7428
7429   va_list
7430     operands;
7431
7432   /*
7433     Display and format a error formats, gives file, line, position and
7434     extra parameters.
7435   */
7436   va_start(operands,format);
7437   (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  SAX.error: ");
7438   (void) LogMagickEvent(CoderEvent,GetMagickModule(),format,operands);
7439   msl_info=(MSLInfo *) context;
7440 #if !defined(MAGICKCORE_HAVE_VSNPRINTF)
7441   (void) vsprintf(reason,format,operands);
7442 #else
7443   (void) vsnprintf(reason,MaxTextExtent,format,operands);
7444 #endif
7445   ThrowMSLException(DelegateFatalError,reason,"SAX error");
7446   va_end(operands);
7447 }
7448
7449 static void MSLCDataBlock(void *context,const xmlChar *value,int length)
7450 {
7451   MSLInfo
7452     *msl_info;
7453
7454    xmlNodePtr
7455      child;
7456
7457   xmlParserCtxtPtr
7458     parser;
7459
7460   /*
7461     Called when a pcdata block has been parsed.
7462   */
7463   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7464     "  SAX.pcdata(%s, %d)",value,length);
7465   msl_info=(MSLInfo *) context;
7466   parser=msl_info->parser;
7467   child=xmlGetLastChild(parser->node);
7468   if ((child != (xmlNodePtr) NULL) && (child->type == XML_CDATA_SECTION_NODE))
7469     {
7470       xmlTextConcat(child,value,length);
7471       return;
7472     }
7473   (void) xmlAddChild(parser->node,xmlNewCDataBlock(parser->myDoc,value,length));
7474 }
7475
7476 static void MSLExternalSubset(void *context,const xmlChar *name,
7477   const xmlChar *external_id,const xmlChar *system_id)
7478 {
7479   MSLInfo
7480     *msl_info;
7481
7482   xmlParserCtxt
7483     parser_context;
7484
7485   xmlParserCtxtPtr
7486     parser;
7487
7488   xmlParserInputPtr
7489     input;
7490
7491   /*
7492     Does this document has an external subset?
7493   */
7494   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7495     "  SAX.externalSubset(%s %s %s)",name,
7496     (external_id != (const xmlChar *) NULL ? (const char *) external_id : " "),
7497     (system_id != (const xmlChar *) NULL ? (const char *) system_id : " "));
7498   msl_info=(MSLInfo *) context;
7499   parser=msl_info->parser;
7500   if (((external_id == NULL) && (system_id == NULL)) ||
7501       ((parser->validate == 0) || (parser->wellFormed == 0) ||
7502       (msl_info->document == 0)))
7503     return;
7504   input=MSLResolveEntity(context,external_id,system_id);
7505   if (input == NULL)
7506     return;
7507   (void) xmlNewDtd(msl_info->document,name,external_id,system_id);
7508   parser_context=(*parser);
7509   parser->inputTab=(xmlParserInputPtr *) xmlMalloc(5*sizeof(*parser->inputTab));
7510   if (parser->inputTab == (xmlParserInputPtr *) NULL)
7511     {
7512       parser->errNo=XML_ERR_NO_MEMORY;
7513       parser->input=parser_context.input;
7514       parser->inputNr=parser_context.inputNr;
7515       parser->inputMax=parser_context.inputMax;
7516       parser->inputTab=parser_context.inputTab;
7517       return;
7518   }
7519   parser->inputNr=0;
7520   parser->inputMax=5;
7521   parser->input=NULL;
7522   xmlPushInput(parser,input);
7523   (void) xmlSwitchEncoding(parser,xmlDetectCharEncoding(parser->input->cur,4));
7524   if (input->filename == (char *) NULL)
7525     input->filename=(char *) xmlStrdup(system_id);
7526   input->line=1;
7527   input->col=1;
7528   input->base=parser->input->cur;
7529   input->cur=parser->input->cur;
7530   input->free=NULL;
7531   xmlParseExternalSubset(parser,external_id,system_id);
7532   while (parser->inputNr > 1)
7533     (void) xmlPopInput(parser);
7534   xmlFreeInputStream(parser->input);
7535   xmlFree(parser->inputTab);
7536   parser->input=parser_context.input;
7537   parser->inputNr=parser_context.inputNr;
7538   parser->inputMax=parser_context.inputMax;
7539   parser->inputTab=parser_context.inputTab;
7540 }
7541
7542 #if defined(__cplusplus) || defined(c_plusplus)
7543 }
7544 #endif
7545
7546 static MagickBooleanType ProcessMSLScript(const ImageInfo *image_info,Image **image,
7547   ExceptionInfo *exception)
7548 {
7549   char
7550     message[MaxTextExtent];
7551
7552   Image
7553     *msl_image;
7554
7555   int
7556     status;
7557
7558   ssize_t
7559     n;
7560
7561   MSLInfo
7562     msl_info;
7563
7564   xmlSAXHandler
7565     sax_modules;
7566
7567   xmlSAXHandlerPtr
7568     sax_handler;
7569
7570   /*
7571     Open image file.
7572   */
7573   assert(image_info != (const ImageInfo *) NULL);
7574   assert(image_info->signature == MagickSignature);
7575   if (image_info->debug != MagickFalse)
7576     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
7577       image_info->filename);
7578   assert(image != (Image **) NULL);
7579   msl_image=AcquireImage(image_info);
7580   status=OpenBlob(image_info,msl_image,ReadBinaryBlobMode,exception);
7581   if (status == MagickFalse)
7582     {
7583       ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
7584         msl_image->filename);
7585       msl_image=DestroyImageList(msl_image);
7586       return(MagickFalse);
7587     }
7588   msl_image->columns=1;
7589   msl_image->rows=1;
7590   /*
7591     Parse MSL file.
7592   */
7593   (void) ResetMagickMemory(&msl_info,0,sizeof(msl_info));
7594   msl_info.exception=exception;
7595   msl_info.image_info=(ImageInfo **) AcquireMagickMemory(
7596     sizeof(*msl_info.image_info));
7597   msl_info.draw_info=(DrawInfo **) AcquireMagickMemory(
7598     sizeof(*msl_info.draw_info));
7599   /* top of the stack is the MSL file itself */
7600   msl_info.image=(Image **) AcquireAlignedMemory(1,sizeof(*msl_info.image));
7601   msl_info.attributes=(Image **) AcquireMagickMemory(
7602     sizeof(*msl_info.attributes));
7603   msl_info.group_info=(MSLGroupInfo *) AcquireMagickMemory(
7604     sizeof(*msl_info.group_info));
7605   if ((msl_info.image_info == (ImageInfo **) NULL) ||
7606       (msl_info.image == (Image **) NULL) ||
7607       (msl_info.attributes == (Image **) NULL) ||
7608       (msl_info.group_info == (MSLGroupInfo *) NULL))
7609     ThrowFatalException(ResourceLimitFatalError,
7610       "UnableToInterpretMSLImage");
7611   *msl_info.image_info=CloneImageInfo(image_info);
7612   *msl_info.draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL);
7613   *msl_info.attributes=AcquireImage(image_info);
7614   msl_info.group_info[0].numImages=0;
7615   /* the first slot is used to point to the MSL file image */
7616   *msl_info.image=msl_image;
7617   if (*image != (Image *) NULL)
7618     MSLPushImage(&msl_info,*image);
7619   (void) xmlSubstituteEntitiesDefault(1);
7620   (void) ResetMagickMemory(&sax_modules,0,sizeof(sax_modules));
7621   sax_modules.internalSubset=MSLInternalSubset;
7622   sax_modules.isStandalone=MSLIsStandalone;
7623   sax_modules.hasInternalSubset=MSLHasInternalSubset;
7624   sax_modules.hasExternalSubset=MSLHasExternalSubset;
7625   sax_modules.resolveEntity=MSLResolveEntity;
7626   sax_modules.getEntity=MSLGetEntity;
7627   sax_modules.entityDecl=MSLEntityDeclaration;
7628   sax_modules.notationDecl=MSLNotationDeclaration;
7629   sax_modules.attributeDecl=MSLAttributeDeclaration;
7630   sax_modules.elementDecl=MSLElementDeclaration;
7631   sax_modules.unparsedEntityDecl=MSLUnparsedEntityDeclaration;
7632   sax_modules.setDocumentLocator=MSLSetDocumentLocator;
7633   sax_modules.startDocument=MSLStartDocument;
7634   sax_modules.endDocument=MSLEndDocument;
7635   sax_modules.startElement=MSLStartElement;
7636   sax_modules.endElement=MSLEndElement;
7637   sax_modules.reference=MSLReference;
7638   sax_modules.characters=MSLCharacters;
7639   sax_modules.ignorableWhitespace=MSLIgnorableWhitespace;
7640   sax_modules.processingInstruction=MSLProcessingInstructions;
7641   sax_modules.comment=MSLComment;
7642   sax_modules.warning=MSLWarning;
7643   sax_modules.error=MSLError;
7644   sax_modules.fatalError=MSLError;
7645   sax_modules.getParameterEntity=MSLGetParameterEntity;
7646   sax_modules.cdataBlock=MSLCDataBlock;
7647   sax_modules.externalSubset=MSLExternalSubset;
7648   sax_handler=(&sax_modules);
7649   msl_info.parser=xmlCreatePushParserCtxt(sax_handler,&msl_info,(char *) NULL,0,
7650     msl_image->filename);
7651   while (ReadBlobString(msl_image,message) != (char *) NULL)
7652   {
7653     n=(ssize_t) strlen(message);
7654     if (n == 0)
7655       continue;
7656     status=xmlParseChunk(msl_info.parser,message,(int) n,MagickFalse);
7657     if (status != 0)
7658       break;
7659     (void) xmlParseChunk(msl_info.parser," ",1,MagickFalse);
7660     if (msl_info.exception->severity >= ErrorException)
7661       break;
7662   }
7663   if (msl_info.exception->severity == UndefinedException)
7664     (void) xmlParseChunk(msl_info.parser," ",1,MagickTrue);
7665   xmlFreeParserCtxt(msl_info.parser);
7666   (void) LogMagickEvent(CoderEvent,GetMagickModule(),"end SAX");
7667   xmlCleanupParser();
7668   msl_info.group_info=(MSLGroupInfo *) RelinquishMagickMemory(
7669     msl_info.group_info);
7670   if (*image == (Image *) NULL)
7671     *image=(*msl_info.image);
7672   if ((*msl_info.image)->exception.severity != UndefinedException)
7673     return(MagickFalse);
7674   return(MagickTrue);
7675 }
7676
7677 static Image *ReadMSLImage(const ImageInfo *image_info,ExceptionInfo *exception)
7678 {
7679   Image
7680     *image;
7681
7682   /*
7683     Open image file.
7684   */
7685   assert(image_info != (const ImageInfo *) NULL);
7686   assert(image_info->signature == MagickSignature);
7687   if (image_info->debug != MagickFalse)
7688     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
7689       image_info->filename);
7690   assert(exception != (ExceptionInfo *) NULL);
7691   assert(exception->signature == MagickSignature);
7692   image=(Image *) NULL;
7693   (void) ProcessMSLScript(image_info,&image,exception);
7694   return(GetFirstImageInList(image));
7695 }
7696 #endif
7697 \f
7698 /*
7699 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7700 %                                                                             %
7701 %                                                                             %
7702 %                                                                             %
7703 %   R e g i s t e r M S L I m a g e                                           %
7704 %                                                                             %
7705 %                                                                             %
7706 %                                                                             %
7707 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7708 %
7709 %  RegisterMSLImage() adds attributes for the MSL image format to
7710 %  the list of supported formats.  The attributes include the image format
7711 %  tag, a method to read and/or write the format, whether the format
7712 %  supports the saving of more than one frame to the same file or blob,
7713 %  whether the format supports native in-memory I/O, and a brief
7714 %  description of the format.
7715 %
7716 %  The format of the RegisterMSLImage method is:
7717 %
7718 %      size_t RegisterMSLImage(void)
7719 %
7720 */
7721 ModuleExport size_t RegisterMSLImage(void)
7722 {
7723   MagickInfo
7724     *entry;
7725
7726   entry=SetMagickInfo("MSL");
7727 #if defined(MAGICKCORE_XML_DELEGATE)
7728   entry->decoder=(DecodeImageHandler *) ReadMSLImage;
7729   entry->encoder=(EncodeImageHandler *) WriteMSLImage;
7730 #endif
7731   entry->description=ConstantString("Magick Scripting Language");
7732   entry->module=ConstantString("MSL");
7733   (void) RegisterMagickInfo(entry);
7734   return(MagickImageCoderSignature);
7735 }
7736 \f
7737 #if defined(MAGICKCORE_XML_DELEGATE)
7738 /*
7739 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7740 %                                                                             %
7741 %                                                                             %
7742 %                                                                             %
7743 %   S e t M S L A t t r i b u t e s                                           %
7744 %                                                                             %
7745 %                                                                             %
7746 %                                                                             %
7747 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7748 %
7749 %  SetMSLAttributes() ...
7750 %
7751 %  The format of the SetMSLAttributes method is:
7752 %
7753 %      MagickBooleanType SetMSLAttributes(MSLInfo *msl_info,
7754 %        const char *keyword,const char *value)
7755 %
7756 %  A description of each parameter follows:
7757 %
7758 %    o msl_info: the MSL info.
7759 %
7760 %    o keyword: the keyword.
7761 %
7762 %    o value: the value.
7763 %
7764 */
7765 static MagickBooleanType SetMSLAttributes(MSLInfo *msl_info,const char *keyword,
7766   const char *value)
7767 {
7768   Image
7769     *attributes;
7770
7771   DrawInfo
7772     *draw_info;
7773
7774   ExceptionInfo
7775     *exception;
7776
7777   GeometryInfo
7778     geometry_info;
7779
7780   Image
7781     *image;
7782
7783   ImageInfo
7784     *image_info;
7785
7786   int
7787     flags;
7788
7789   ssize_t
7790     n;
7791
7792   assert(msl_info != (MSLInfo *) NULL);
7793   if (keyword == (const char *) NULL)
7794     return(MagickTrue);
7795   if (value == (const char *) NULL)
7796     return(MagickTrue);
7797   exception=msl_info->exception;
7798   n=msl_info->n;
7799   attributes=msl_info->attributes[n];
7800   image_info=msl_info->image_info[n];
7801   draw_info=msl_info->draw_info[n];
7802   image=msl_info->image[n];
7803   switch (*keyword)
7804   {
7805     case 'A':
7806     case 'a':
7807     {
7808       if (LocaleCompare(keyword,"adjoin") == 0)
7809         {
7810           ssize_t
7811             adjoin;
7812
7813           adjoin=ParseMagickOption(MagickBooleanOptions,MagickFalse,value);
7814           if (adjoin < 0)
7815             ThrowMSLException(OptionError,"UnrecognizedType",value);
7816           image_info->adjoin=(MagickBooleanType) adjoin;
7817           break;
7818         }
7819       if (LocaleCompare(keyword,"alpha") == 0)
7820         {
7821           ssize_t
7822             alpha;
7823
7824           alpha=ParseMagickOption(MagickAlphaOptions,MagickFalse,value);
7825           if (alpha < 0)
7826             ThrowMSLException(OptionError,"UnrecognizedType",value);
7827           if (image != (Image *) NULL)
7828             (void) SetImageAlphaChannel(image,(AlphaChannelType) alpha);
7829           break;
7830         }
7831       if (LocaleCompare(keyword,"antialias") == 0)
7832         {
7833           ssize_t
7834             antialias;
7835
7836           antialias=ParseMagickOption(MagickBooleanOptions,MagickFalse,value);
7837           if (antialias < 0)
7838             ThrowMSLException(OptionError,"UnrecognizedGravityType",value);
7839           image_info->antialias=(MagickBooleanType) antialias;
7840           break;
7841         }
7842       if (LocaleCompare(keyword,"area-limit") == 0)
7843         {
7844           MagickSizeType
7845             limit;
7846
7847           limit=MagickResourceInfinity;
7848           if (LocaleCompare(value,"unlimited") != 0)
7849             limit=(MagickSizeType) SiPrefixToDouble(value,100.0);
7850           (void) SetMagickResourceLimit(AreaResource,limit);
7851           break;
7852         }
7853       if (LocaleCompare(keyword,"attenuate") == 0)
7854         {
7855           (void) SetImageOption(image_info,keyword,value);
7856           break;
7857         }
7858       if (LocaleCompare(keyword,"authenticate") == 0)
7859         {
7860           (void) CloneString(&image_info->density,value);
7861           break;
7862         }
7863       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7864       break;
7865     }
7866     case 'B':
7867     case 'b':
7868     {
7869       if (LocaleCompare(keyword,"background") == 0)
7870         {
7871           (void) QueryColorDatabase(value,&image_info->background_color,
7872             exception);
7873           break;
7874         }
7875       if (LocaleCompare(keyword,"bias") == 0)
7876         {
7877           if (image == (Image *) NULL)
7878             break;
7879           image->bias=SiPrefixToDouble(value,QuantumRange);
7880           break;
7881         }
7882       if (LocaleCompare(keyword,"blue-primary") == 0)
7883         {
7884           if (image == (Image *) NULL)
7885             break;
7886           flags=ParseGeometry(value,&geometry_info);
7887           image->chromaticity.blue_primary.x=geometry_info.rho;
7888           image->chromaticity.blue_primary.y=geometry_info.sigma;
7889           if ((flags & SigmaValue) == 0)
7890             image->chromaticity.blue_primary.y=
7891               image->chromaticity.blue_primary.x;
7892           break;
7893         }
7894       if (LocaleCompare(keyword,"bordercolor") == 0)
7895         {
7896           (void) QueryColorDatabase(value,&image_info->border_color,
7897             exception);
7898           break;
7899         }
7900       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7901       break;
7902     }
7903     case 'D':
7904     case 'd':
7905     {
7906       if (LocaleCompare(keyword,"density") == 0)
7907         {
7908           (void) CloneString(&image_info->density,value);
7909           (void) CloneString(&draw_info->density,value);
7910           break;
7911         }
7912       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7913       break;
7914     }
7915     case 'F':
7916     case 'f':
7917     {
7918       if (LocaleCompare(keyword,"fill") == 0)
7919         {
7920           (void) QueryColorDatabase(value,&draw_info->fill,exception);
7921           (void) SetImageOption(image_info,keyword,value);
7922           break;
7923         }
7924       if (LocaleCompare(keyword,"filename") == 0)
7925         {
7926           (void) CopyMagickString(image_info->filename,value,MaxTextExtent);
7927           break;
7928         }
7929       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7930       break;
7931     }
7932     case 'G':
7933     case 'g':
7934     {
7935       if (LocaleCompare(keyword,"gravity") == 0)
7936         {
7937           ssize_t
7938             gravity;
7939
7940           gravity=ParseMagickOption(MagickGravityOptions,MagickFalse,value);
7941           if (gravity < 0)
7942             ThrowMSLException(OptionError,"UnrecognizedGravityType",value);
7943           (void) SetImageOption(image_info,keyword,value);
7944           break;
7945         }
7946       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7947       break;
7948     }
7949     case 'I':
7950     case 'i':
7951     {
7952       if (LocaleCompare(keyword,"id") == 0)
7953         {
7954           (void) SetImageProperty(attributes,keyword,value);
7955           break;
7956         }
7957       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7958       break;
7959     }
7960     case 'M':
7961     case 'm':
7962     {
7963       if (LocaleCompare(keyword,"magick") == 0)
7964         {
7965           (void) CopyMagickString(image_info->magick,value,MaxTextExtent);
7966           break;
7967         }
7968       if (LocaleCompare(keyword,"mattecolor") == 0)
7969         {
7970           (void) QueryColorDatabase(value,&image_info->matte_color,
7971             exception);
7972           break;
7973         }
7974       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7975       break;
7976     }
7977     case 'P':
7978     case 'p':
7979     {
7980       if (LocaleCompare(keyword,"pointsize") == 0)
7981         {
7982           image_info->pointsize=StringToDouble(value);
7983           draw_info->pointsize=StringToDouble(value);
7984           break;
7985         }
7986       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7987       break;
7988     }
7989     case 'Q':
7990     case 'q':
7991     {
7992       if (LocaleCompare(keyword,"quality") == 0)
7993         {
7994           image_info->quality=StringToLong(value);
7995           if (image == (Image *) NULL)
7996             break;
7997           image->quality=StringToLong(value);
7998           break;
7999         }
8000       break;
8001     }
8002     case 'S':
8003     case 's':
8004     {
8005       if (LocaleCompare(keyword,"size") == 0)
8006         {
8007           (void) CloneString(&image_info->size,value);
8008           break;
8009         }
8010       if (LocaleCompare(keyword,"stroke") == 0)
8011         {
8012           (void) QueryColorDatabase(value,&draw_info->stroke,exception);
8013           (void) SetImageOption(image_info,keyword,value);
8014           break;
8015         }
8016       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8017       break;
8018     }
8019     default:
8020     {
8021       ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8022       break;
8023     }
8024   }
8025   return(MagickTrue);
8026 }
8027 #endif
8028 \f
8029 /*
8030 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8031 %                                                                             %
8032 %                                                                             %
8033 %                                                                             %
8034 %   U n r e g i s t e r M S L I m a g e                                       %
8035 %                                                                             %
8036 %                                                                             %
8037 %                                                                             %
8038 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8039 %
8040 %  UnregisterMSLImage() removes format registrations made by the
8041 %  MSL module from the list of supported formats.
8042 %
8043 %  The format of the UnregisterMSLImage method is:
8044 %
8045 %      UnregisterMSLImage(void)
8046 %
8047 */
8048 ModuleExport void UnregisterMSLImage(void)
8049 {
8050   (void) UnregisterMagickInfo("MSL");
8051 }
8052 \f
8053 #if defined(MAGICKCORE_XML_DELEGATE)
8054 /*
8055 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8056 %                                                                             %
8057 %                                                                             %
8058 %                                                                             %
8059 %   W r i t e M S L I m a g e                                                 %
8060 %                                                                             %
8061 %                                                                             %
8062 %                                                                             %
8063 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8064 %
8065 %  WriteMSLImage() writes an image to a file in MVG image format.
8066 %
8067 %  The format of the WriteMSLImage method is:
8068 %
8069 %      MagickBooleanType WriteMSLImage(const ImageInfo *image_info,Image *image)
8070 %
8071 %  A description of each parameter follows.
8072 %
8073 %    o image_info: the image info.
8074 %
8075 %    o image:  The image.
8076 %
8077 */
8078 static MagickBooleanType WriteMSLImage(const ImageInfo *image_info,Image *image)
8079 {
8080   assert(image_info != (const ImageInfo *) NULL);
8081   assert(image_info->signature == MagickSignature);
8082   assert(image != (Image *) NULL);
8083   assert(image->signature == MagickSignature);
8084   if (image->debug != MagickFalse)
8085     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
8086   (void) ReferenceImage(image);
8087   (void) ProcessMSLScript(image_info,&image,&image->exception);
8088   return(MagickTrue);
8089 }
8090 #endif