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