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