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