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