msl.c revision 6d8c3d738c9b07d73a17ca7400898f27065768de
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 *);
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);
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);
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          break;
3971        }
3972      ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3973    }
3974    case 'N':
3975    case 'n':
3976    {
3977      if (LocaleCompare((const char *) tag,"negate") == 0)
3978        {
3979          MagickBooleanType
3980            gray;
3981
3982          /*
3983            Negate image.
3984          */
3985          if (msl_info->image[n] == (Image *) NULL)
3986            {
3987              ThrowMSLException(OptionError,"NoImagesDefined",
3988                (const char *) tag);
3989              break;
3990            }
3991          gray=MagickFalse;
3992          if (attributes != (const xmlChar **) NULL)
3993            for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3994            {
3995              keyword=(const char *) attributes[i++];
3996              attribute=InterpretImageProperties(msl_info->image_info[n],
3997                msl_info->attributes[n],(const char *) attributes[i]);
3998              CloneString(&value,attribute);
3999              switch (*keyword)
4000              {
4001                case 'C':
4002                case 'c':
4003                {
4004                  if (LocaleCompare(keyword,"channel") == 0)
4005                    {
4006                      option=ParseChannelOption(value);
4007                      if (option < 0)
4008                        ThrowMSLException(OptionError,"UnrecognizedChannelType",
4009                          value);
4010                      channel=(ChannelType) option;
4011                      break;
4012                    }
4013                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
4014                    keyword);
4015                  break;
4016                }
4017                case 'G':
4018                case 'g':
4019                {
4020                  if (LocaleCompare(keyword,"gray") == 0)
4021                    {
4022                      option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
4023                        value);
4024                      if (option < 0)
4025                        ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4026                          value);
4027                      gray=(MagickBooleanType) option;
4028                      break;
4029                    }
4030                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
4031                    keyword);
4032                  break;
4033                }
4034                default:
4035                {
4036                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
4037                    keyword);
4038                  break;
4039                }
4040              }
4041            }
4042          channel_mask=SetPixelChannelMask(msl_info->image[n],channel);
4043          (void) NegateImage(msl_info->image[n],gray,
4044            &msl_info->image[n]->exception);
4045          (void) SetPixelChannelMap(msl_info->image[n],channel_mask);
4046          break;
4047        }
4048      if (LocaleCompare((const char *) tag,"normalize") == 0)
4049        {
4050          /*
4051            Normalize image.
4052          */
4053          if (msl_info->image[n] == (Image *) NULL)
4054            {
4055              ThrowMSLException(OptionError,"NoImagesDefined",
4056                (const char *) tag);
4057              break;
4058            }
4059          if (attributes != (const xmlChar **) NULL)
4060            for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4061            {
4062              keyword=(const char *) attributes[i++];
4063              attribute=InterpretImageProperties(msl_info->image_info[n],
4064                msl_info->attributes[n],(const char *) attributes[i]);
4065              CloneString(&value,attribute);
4066              switch (*keyword)
4067              {
4068                case 'C':
4069                case 'c':
4070                {
4071                  if (LocaleCompare(keyword,"channel") == 0)
4072                    {
4073                      option=ParseChannelOption(value);
4074                      if (option < 0)
4075                        ThrowMSLException(OptionError,"UnrecognizedChannelType",
4076                          value);
4077                      channel=(ChannelType) option;
4078                      break;
4079                    }
4080                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
4081                    keyword);
4082                  break;
4083                }
4084                default:
4085                {
4086                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
4087                    keyword);
4088                  break;
4089                }
4090              }
4091            }
4092          (void) NormalizeImage(msl_info->image[n],
4093            &msl_info->image[n]->exception);
4094          break;
4095        }
4096      ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4097    }
4098    case 'O':
4099    case 'o':
4100    {
4101      if (LocaleCompare((const char *) tag,"oil-paint") == 0)
4102        {
4103          Image
4104            *paint_image;
4105
4106          /*
4107            Oil-paint image.
4108          */
4109          if (msl_info->image[n] == (Image *) NULL)
4110            {
4111              ThrowMSLException(OptionError,"NoImagesDefined",
4112                (const char *) tag);
4113              break;
4114            }
4115          if (attributes != (const xmlChar **) NULL)
4116            for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4117            {
4118              keyword=(const char *) attributes[i++];
4119              attribute=InterpretImageProperties(msl_info->image_info[n],
4120                msl_info->attributes[n],(const char *) attributes[i]);
4121              CloneString(&value,attribute);
4122              switch (*keyword)
4123              {
4124                case 'G':
4125                case 'g':
4126                {
4127                  if (LocaleCompare(keyword,"geometry") == 0)
4128                    {
4129                      flags=ParseGeometry(value,&geometry_info);
4130                      if ((flags & SigmaValue) == 0)
4131                        geometry_info.sigma=1.0;
4132                      break;
4133                    }
4134                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
4135                    keyword);
4136                  break;
4137                }
4138                case 'R':
4139                case 'r':
4140                {
4141                  if (LocaleCompare(keyword,"radius") == 0)
4142                    {
4143                      geometry_info.rho=InterpretLocaleValue(value,
4144                        (char **) NULL);
4145                      break;
4146                    }
4147                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
4148                    keyword);
4149                  break;
4150                }
4151                default:
4152                {
4153                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
4154                    keyword);
4155                  break;
4156                }
4157              }
4158            }
4159          paint_image=OilPaintImage(msl_info->image[n],geometry_info.rho,
4160            &msl_info->image[n]->exception);
4161          if (paint_image == (Image *) NULL)
4162            break;
4163          msl_info->image[n]=DestroyImage(msl_info->image[n]);
4164          msl_info->image[n]=paint_image;
4165          break;
4166        }
4167      if (LocaleCompare((const char *) tag,"opaque") == 0)
4168        {
4169          PixelInfo
4170            fill_color,
4171            target;
4172
4173          /*
4174            Opaque image.
4175          */
4176          if (msl_info->image[n] == (Image *) NULL)
4177            {
4178              ThrowMSLException(OptionError,"NoImagesDefined",
4179                (const char *) tag);
4180              break;
4181            }
4182          (void) QueryMagickColor("none",&target,&exception);
4183          (void) QueryMagickColor("none",&fill_color,&exception);
4184          if (attributes != (const xmlChar **) NULL)
4185            for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4186            {
4187              keyword=(const char *) attributes[i++];
4188              attribute=InterpretImageProperties(msl_info->image_info[n],
4189                msl_info->attributes[n],(const char *) attributes[i]);
4190              CloneString(&value,attribute);
4191              switch (*keyword)
4192              {
4193                case 'C':
4194                case 'c':
4195                {
4196                  if (LocaleCompare(keyword,"channel") == 0)
4197                    {
4198                      option=ParseChannelOption(value);
4199                      if (option < 0)
4200                        ThrowMSLException(OptionError,"UnrecognizedChannelType",
4201                          value);
4202                      channel=(ChannelType) option;
4203                      break;
4204                    }
4205                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
4206                    keyword);
4207                  break;
4208                }
4209                case 'F':
4210                case 'f':
4211                {
4212                  if (LocaleCompare(keyword,"fill") == 0)
4213                    {
4214                      (void) QueryMagickColor(value,&fill_color,&exception);
4215                      break;
4216                    }
4217                  if (LocaleCompare(keyword,"fuzz") == 0)
4218                    {
4219                      msl_info->image[n]->fuzz=InterpretLocaleValue(value,
4220                        (char **) NULL);
4221                      break;
4222                    }
4223                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
4224                    keyword);
4225                  break;
4226                }
4227                default:
4228                {
4229                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
4230                    keyword);
4231                  break;
4232                }
4233              }
4234            }
4235          channel_mask=SetPixelChannelMask(msl_info->image[n],channel);
4236          (void) OpaquePaintImage(msl_info->image[n],&target,&fill_color,
4237            MagickFalse);
4238          (void) SetPixelChannelMap(msl_info->image[n],channel_mask);
4239          break;
4240        }
4241      ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4242    }
4243    case 'P':
4244    case 'p':
4245    {
4246      if (LocaleCompare((const char *) tag,"print") == 0)
4247        {
4248          if (attributes == (const xmlChar **) NULL)
4249            break;
4250          for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4251          {
4252            keyword=(const char *) attributes[i++];
4253            attribute=InterpretImageProperties(msl_info->image_info[n],
4254              msl_info->attributes[n],(const char *) attributes[i]);
4255            CloneString(&value,attribute);
4256            switch (*keyword)
4257            {
4258              case 'O':
4259              case 'o':
4260              {
4261                if (LocaleCompare(keyword,"output") == 0)
4262                  {
4263                    (void) FormatLocaleFile(stdout,"%s",value);
4264                    break;
4265                  }
4266                ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
4267                break;
4268              }
4269              default:
4270              {
4271                ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
4272                break;
4273              }
4274            }
4275          }
4276          break;
4277        }
4278        if (LocaleCompare((const char *) tag, "profile") == 0)
4279          {
4280            if (msl_info->image[n] == (Image *) NULL)
4281              {
4282                ThrowMSLException(OptionError,"NoImagesDefined",
4283                  (const char *) tag);
4284                break;
4285              }
4286            if (attributes == (const xmlChar **) NULL)
4287              break;
4288            for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4289            {
4290              const char
4291                *name;
4292
4293              const StringInfo
4294                *profile;
4295
4296              Image
4297                *profile_image;
4298
4299              ImageInfo
4300                *profile_info;
4301
4302              keyword=(const char *) attributes[i++];
4303              attribute=InterpretImageProperties(msl_info->image_info[n],
4304                msl_info->attributes[n],(const char *) attributes[i]);
4305              CloneString(&value,attribute);
4306              if (*keyword == '+')
4307                {
4308                  /*
4309                    Remove a profile from the image.
4310                  */
4311                  (void) ProfileImage(msl_info->image[n],keyword,
4312                    (const unsigned char *) NULL,0,MagickTrue);
4313                  continue;
4314                }
4315              /*
4316                Associate a profile with the image.
4317              */
4318              profile_info=CloneImageInfo(msl_info->image_info[n]);
4319              profile=GetImageProfile(msl_info->image[n],"iptc");
4320              if (profile != (StringInfo *) NULL)
4321                profile_info->profile=(void *) CloneStringInfo(profile);
4322              profile_image=GetImageCache(profile_info,keyword,&exception);
4323              profile_info=DestroyImageInfo(profile_info);
4324              if (profile_image == (Image *) NULL)
4325                {
4326                  char
4327                    name[MaxTextExtent],
4328                    filename[MaxTextExtent];
4329
4330                  register char
4331                    *p;
4332
4333                  StringInfo
4334                    *profile;
4335
4336                  (void) CopyMagickString(filename,keyword,MaxTextExtent);
4337                  (void) CopyMagickString(name,keyword,MaxTextExtent);
4338                  for (p=filename; *p != '\0'; p++)
4339                    if ((*p == ':') && (IsPathDirectory(keyword) < 0) &&
4340                        (IsPathAccessible(keyword) == MagickFalse))
4341                      {
4342                        register char
4343                          *q;
4344
4345                        /*
4346                          Look for profile name (e.g. name:profile).
4347                        */
4348                        (void) CopyMagickString(name,filename,(size_t)
4349                          (p-filename+1));
4350                        for (q=filename; *q != '\0'; q++)
4351                          *q=(*++p);
4352                        break;
4353                      }
4354                  profile=FileToStringInfo(filename,~0UL,&exception);
4355                  if (profile != (StringInfo *) NULL)
4356                    {
4357                      (void) ProfileImage(msl_info->image[n],name,
4358                        GetStringInfoDatum(profile),(size_t)
4359                        GetStringInfoLength(profile),MagickFalse);
4360                      profile=DestroyStringInfo(profile);
4361                    }
4362                  continue;
4363                }
4364              ResetImageProfileIterator(profile_image);
4365              name=GetNextImageProfile(profile_image);
4366              while (name != (const char *) NULL)
4367              {
4368                profile=GetImageProfile(profile_image,name);
4369                if (profile != (StringInfo *) NULL)
4370                  (void) ProfileImage(msl_info->image[n],name,
4371                    GetStringInfoDatum(profile),(size_t)
4372                    GetStringInfoLength(profile),MagickFalse);
4373                name=GetNextImageProfile(profile_image);
4374              }
4375              profile_image=DestroyImage(profile_image);
4376            }
4377            break;
4378          }
4379      ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4380    }
4381    case 'Q':
4382    case 'q':
4383    {
4384      if (LocaleCompare((const char *) tag,"quantize") == 0)
4385        {
4386          QuantizeInfo
4387            quantize_info;
4388
4389          /*
4390            Quantize image.
4391          */
4392          if (msl_info->image[n] == (Image *) NULL)
4393            {
4394              ThrowMSLException(OptionError,"NoImagesDefined",
4395                (const char *) tag);
4396              break;
4397            }
4398          GetQuantizeInfo(&quantize_info);
4399          if (attributes != (const xmlChar **) NULL)
4400            for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4401            {
4402              keyword=(const char *) attributes[i++];
4403              attribute=InterpretImageProperties(msl_info->image_info[n],
4404                msl_info->attributes[n],(const char *) attributes[i]);
4405              CloneString(&value,attribute);
4406              switch (*keyword)
4407              {
4408                case 'C':
4409                case 'c':
4410                {
4411                  if (LocaleCompare(keyword,"colors") == 0)
4412                    {
4413                      quantize_info.number_colors=StringToLong(value);
4414                      break;
4415                    }
4416                  if (LocaleCompare(keyword,"colorspace") == 0)
4417                    {
4418                      option=ParseCommandOption(MagickColorspaceOptions,
4419                        MagickFalse,value);
4420                      if (option < 0)
4421                        ThrowMSLException(OptionError,
4422                          "UnrecognizedColorspaceType",value);
4423                      quantize_info.colorspace=(ColorspaceType) option;
4424                      break;
4425                    }
4426                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
4427                    keyword);
4428                  break;
4429                }
4430                case 'D':
4431                case 'd':
4432                {
4433                  if (LocaleCompare(keyword,"dither") == 0)
4434                    {
4435                      option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
4436                        value);
4437                      if (option < 0)
4438                        ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4439                          value);
4440                      quantize_info.dither=(MagickBooleanType) option;
4441                      break;
4442                    }
4443                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
4444                    keyword);
4445                  break;
4446                }
4447                case 'M':
4448                case 'm':
4449                {
4450                  if (LocaleCompare(keyword,"measure") == 0)
4451                    {
4452                      option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
4453                        value);
4454                      if (option < 0)
4455                        ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4456                          value);
4457                      quantize_info.measure_error=(MagickBooleanType) option;
4458                      break;
4459                    }
4460                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
4461                    keyword);
4462                  break;
4463                }
4464                case 'T':
4465                case 't':
4466                {
4467                  if (LocaleCompare(keyword,"treedepth") == 0)
4468                    {
4469                      quantize_info.tree_depth=StringToLong(value);
4470                      break;
4471                    }
4472                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
4473                    keyword);
4474                  break;
4475                }
4476                default:
4477                {
4478                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
4479                    keyword);
4480                  break;
4481                }
4482              }
4483            }
4484          (void) QuantizeImage(&quantize_info,msl_info->image[n]);
4485          break;
4486        }
4487      if (LocaleCompare((const char *) tag,"query-font-metrics") == 0)
4488        {
4489          char
4490            text[MaxTextExtent];
4491
4492          MagickBooleanType
4493            status;
4494
4495          TypeMetric
4496            metrics;
4497
4498          /*
4499            Query font metrics.
4500          */
4501          draw_info=CloneDrawInfo(msl_info->image_info[n],
4502            msl_info->draw_info[n]);
4503          angle=0.0;
4504          current=draw_info->affine;
4505          GetAffineMatrix(&affine);
4506          if (attributes != (const xmlChar **) NULL)
4507            for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4508            {
4509              keyword=(const char *) attributes[i++];
4510              attribute=InterpretImageProperties(msl_info->image_info[n],
4511                msl_info->attributes[n],(const char *) attributes[i]);
4512              CloneString(&value,attribute);
4513              switch (*keyword)
4514              {
4515                case 'A':
4516                case 'a':
4517                {
4518                  if (LocaleCompare(keyword,"affine") == 0)
4519                    {
4520                      char
4521                        *p;
4522
4523                      p=value;
4524                      draw_info->affine.sx=InterpretLocaleValue(p,&p);
4525                      if (*p ==',')
4526                        p++;
4527                      draw_info->affine.rx=InterpretLocaleValue(p,&p);
4528                      if (*p ==',')
4529                        p++;
4530                      draw_info->affine.ry=InterpretLocaleValue(p,&p);
4531                      if (*p ==',')
4532                        p++;
4533                      draw_info->affine.sy=InterpretLocaleValue(p,&p);
4534                      if (*p ==',')
4535                        p++;
4536                      draw_info->affine.tx=InterpretLocaleValue(p,&p);
4537                      if (*p ==',')
4538                        p++;
4539                      draw_info->affine.ty=InterpretLocaleValue(p,&p);
4540                      break;
4541                    }
4542                  if (LocaleCompare(keyword,"align") == 0)
4543                    {
4544                      option=ParseCommandOption(MagickAlignOptions,MagickFalse,
4545                        value);
4546                      if (option < 0)
4547                        ThrowMSLException(OptionError,"UnrecognizedAlignType",
4548                          value);
4549                      draw_info->align=(AlignType) option;
4550                      break;
4551                    }
4552                  if (LocaleCompare(keyword,"antialias") == 0)
4553                    {
4554                      option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
4555                        value);
4556                      if (option < 0)
4557                        ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4558                          value);
4559                      draw_info->stroke_antialias=(MagickBooleanType) option;
4560                      draw_info->text_antialias=(MagickBooleanType) option;
4561                      break;
4562                    }
4563                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
4564                    keyword);
4565                  break;
4566                }
4567                case 'D':
4568                case 'd':
4569                {
4570                  if (LocaleCompare(keyword,"density") == 0)
4571                    {
4572                      CloneString(&draw_info->density,value);
4573                      break;
4574                    }
4575                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
4576                    keyword);
4577                  break;
4578                }
4579                case 'E':
4580                case 'e':
4581                {
4582                  if (LocaleCompare(keyword,"encoding") == 0)
4583                    {
4584                      CloneString(&draw_info->encoding,value);
4585                      break;
4586                    }
4587                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
4588                    keyword);
4589                  break;
4590                }
4591                case 'F':
4592                case 'f':
4593                {
4594                  if (LocaleCompare(keyword, "fill") == 0)
4595                    {
4596                      (void) QueryColorDatabase(value,&draw_info->fill,
4597                        &exception);
4598                      break;
4599                    }
4600                  if (LocaleCompare(keyword,"family") == 0)
4601                    {
4602                      CloneString(&draw_info->family,value);
4603                      break;
4604                    }
4605                  if (LocaleCompare(keyword,"font") == 0)
4606                    {
4607                      CloneString(&draw_info->font,value);
4608                      break;
4609                    }
4610                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
4611                    keyword);
4612                  break;
4613                }
4614                case 'G':
4615                case 'g':
4616                {
4617                  if (LocaleCompare(keyword,"geometry") == 0)
4618                    {
4619                      flags=ParsePageGeometry(msl_info->image[n],value,
4620                        &geometry,&exception);
4621                      if ((flags & HeightValue) == 0)
4622                        geometry.height=geometry.width;
4623                      break;
4624                    }
4625                  if (LocaleCompare(keyword,"gravity") == 0)
4626                    {
4627                      option=ParseCommandOption(MagickGravityOptions,MagickFalse,
4628                        value);
4629                      if (option < 0)
4630                        ThrowMSLException(OptionError,"UnrecognizedGravityType",
4631                          value);
4632                      draw_info->gravity=(GravityType) option;
4633                      break;
4634                    }
4635                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
4636                    keyword);
4637                  break;
4638                }
4639                case 'P':
4640                case 'p':
4641                {
4642                  if (LocaleCompare(keyword,"pointsize") == 0)
4643                    {
4644                      draw_info->pointsize=InterpretLocaleValue(value,
4645                        (char **) NULL);
4646                      break;
4647                    }
4648                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
4649                    keyword);
4650                  break;
4651                }
4652                case 'R':
4653                case 'r':
4654                {
4655                  if (LocaleCompare(keyword,"rotate") == 0)
4656                    {
4657                      angle=InterpretLocaleValue(value,(char **) NULL);
4658                      affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
4659                      affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
4660                      affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
4661                      affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
4662                      break;
4663                    }
4664                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
4665                    keyword);
4666                  break;
4667                }
4668                case 'S':
4669                case 's':
4670                {
4671                  if (LocaleCompare(keyword,"scale") == 0)
4672                    {
4673                      flags=ParseGeometry(value,&geometry_info);
4674                      if ((flags & SigmaValue) == 0)
4675                        geometry_info.sigma=1.0;
4676                      affine.sx=geometry_info.rho;
4677                      affine.sy=geometry_info.sigma;
4678                      break;
4679                    }
4680                  if (LocaleCompare(keyword,"skewX") == 0)
4681                    {
4682                      angle=InterpretLocaleValue(value,(char **) NULL);
4683                      affine.ry=cos(DegreesToRadians(fmod(angle,360.0)));
4684                      break;
4685                    }
4686                  if (LocaleCompare(keyword,"skewY") == 0)
4687                    {
4688                      angle=InterpretLocaleValue(value,(char **) NULL);
4689                      affine.rx=cos(DegreesToRadians(fmod(angle,360.0)));
4690                      break;
4691                    }
4692                  if (LocaleCompare(keyword,"stretch") == 0)
4693                    {
4694                      option=ParseCommandOption(MagickStretchOptions,MagickFalse,
4695                        value);
4696                      if (option < 0)
4697                        ThrowMSLException(OptionError,"UnrecognizedStretchType",
4698                          value);
4699                      draw_info->stretch=(StretchType) option;
4700                      break;
4701                    }
4702                  if (LocaleCompare(keyword, "stroke") == 0)
4703                    {
4704                      (void) QueryColorDatabase(value,&draw_info->stroke,
4705                        &exception);
4706                      break;
4707                    }
4708                  if (LocaleCompare(keyword,"strokewidth") == 0)
4709                    {
4710                      draw_info->stroke_width=StringToLong(value);
4711                      break;
4712                    }
4713                  if (LocaleCompare(keyword,"style") == 0)
4714                    {
4715                      option=ParseCommandOption(MagickStyleOptions,MagickFalse,
4716                        value);
4717                      if (option < 0)
4718                        ThrowMSLException(OptionError,"UnrecognizedStyleType",
4719                          value);
4720                      draw_info->style=(StyleType) option;
4721                      break;
4722                    }
4723                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
4724                    keyword);
4725                  break;
4726                }
4727                case 'T':
4728                case 't':
4729                {
4730                  if (LocaleCompare(keyword,"text") == 0)
4731                    {
4732                      CloneString(&draw_info->text,value);
4733                      break;
4734                    }
4735                  if (LocaleCompare(keyword,"translate") == 0)
4736                    {
4737                      flags=ParseGeometry(value,&geometry_info);
4738                      if ((flags & SigmaValue) == 0)
4739                        geometry_info.sigma=1.0;
4740                      affine.tx=geometry_info.rho;
4741                      affine.ty=geometry_info.sigma;
4742                      break;
4743                    }
4744                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
4745                    keyword);
4746                  break;
4747                }
4748                case 'U':
4749                case 'u':
4750                {
4751                  if (LocaleCompare(keyword, "undercolor") == 0)
4752                    {
4753                      (void) QueryColorDatabase(value,&draw_info->undercolor,
4754                        &exception);
4755                      break;
4756                    }
4757                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
4758                    keyword);
4759                  break;
4760                }
4761                case 'W':
4762                case 'w':
4763                {
4764                  if (LocaleCompare(keyword,"weight") == 0)
4765                    {
4766                      draw_info->weight=StringToLong(value);
4767                      break;
4768                    }
4769                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
4770                    keyword);
4771                  break;
4772                }
4773                case 'X':
4774                case 'x':
4775                {
4776                  if (LocaleCompare(keyword,"x") == 0)
4777                    {
4778                      geometry.x=StringToLong(value);
4779                      break;
4780                    }
4781                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
4782                    keyword);
4783                  break;
4784                }
4785                case 'Y':
4786                case 'y':
4787                {
4788                  if (LocaleCompare(keyword,"y") == 0)
4789                    {
4790                      geometry.y=StringToLong(value);
4791                      break;
4792                    }
4793                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
4794                    keyword);
4795                  break;
4796                }
4797                default:
4798                {
4799                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
4800                    keyword);
4801                  break;
4802                }
4803              }
4804            }
4805          (void) FormatLocaleString(text,MaxTextExtent,
4806            "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,(double)
4807            geometry.height,(double) geometry.x,(double) geometry.y);
4808          CloneString(&draw_info->geometry,text);
4809          draw_info->affine.sx=affine.sx*current.sx+affine.ry*current.rx;
4810          draw_info->affine.rx=affine.rx*current.sx+affine.sy*current.rx;
4811          draw_info->affine.ry=affine.sx*current.ry+affine.ry*current.sy;
4812          draw_info->affine.sy=affine.rx*current.ry+affine.sy*current.sy;
4813          draw_info->affine.tx=affine.sx*current.tx+affine.ry*current.ty+
4814            affine.tx;
4815          draw_info->affine.ty=affine.rx*current.tx+affine.sy*current.ty+
4816            affine.ty;
4817          status=GetTypeMetrics(msl_info->attributes[n],draw_info,&metrics);
4818          if (status != MagickFalse)
4819            {
4820              Image
4821                *image;
4822
4823              image=msl_info->attributes[n];
4824              FormatImageProperty(image,"msl:font-metrics.pixels_per_em.x",
4825                "%g",metrics.pixels_per_em.x);
4826              FormatImageProperty(image,"msl:font-metrics.pixels_per_em.y",
4827                "%g",metrics.pixels_per_em.y);
4828              FormatImageProperty(image,"msl:font-metrics.ascent","%g",
4829                metrics.ascent);
4830              FormatImageProperty(image,"msl:font-metrics.descent","%g",
4831                metrics.descent);
4832              FormatImageProperty(image,"msl:font-metrics.width","%g",
4833                metrics.width);
4834              FormatImageProperty(image,"msl:font-metrics.height","%g",
4835                metrics.height);
4836              FormatImageProperty(image,"msl:font-metrics.max_advance","%g",
4837                metrics.max_advance);
4838              FormatImageProperty(image,"msl:font-metrics.bounds.x1","%g",
4839                metrics.bounds.x1);
4840              FormatImageProperty(image,"msl:font-metrics.bounds.y1","%g",
4841                metrics.bounds.y1);
4842              FormatImageProperty(image,"msl:font-metrics.bounds.x2","%g",
4843                metrics.bounds.x2);
4844              FormatImageProperty(image,"msl:font-metrics.bounds.y2","%g",
4845                metrics.bounds.y2);
4846              FormatImageProperty(image,"msl:font-metrics.origin.x","%g",
4847                metrics.origin.x);
4848              FormatImageProperty(image,"msl:font-metrics.origin.y","%g",
4849                metrics.origin.y);
4850            }
4851          draw_info=DestroyDrawInfo(draw_info);
4852          break;
4853        }
4854      ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4855    }
4856    case 'R':
4857    case 'r':
4858    {
4859      if (LocaleCompare((const char *) tag,"raise") == 0)
4860        {
4861          MagickBooleanType
4862            raise;
4863
4864          /*
4865            Raise image.
4866          */
4867          if (msl_info->image[n] == (Image *) NULL)
4868            {
4869              ThrowMSLException(OptionError,"NoImagesDefined",
4870                (const char *) tag);
4871              break;
4872            }
4873          raise=MagickFalse;
4874          SetGeometry(msl_info->image[n],&geometry);
4875          if (attributes != (const xmlChar **) NULL)
4876            for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4877            {
4878              keyword=(const char *) attributes[i++];
4879              attribute=InterpretImageProperties(msl_info->image_info[n],
4880                msl_info->attributes[n],(const char *) attributes[i]);
4881              CloneString(&value,attribute);
4882              switch (*keyword)
4883              {
4884                case 'G':
4885                case 'g':
4886                {
4887                  if (LocaleCompare(keyword,"geometry") == 0)
4888                    {
4889                      flags=ParsePageGeometry(msl_info->image[n],value,
4890                        &geometry,&exception);
4891                      if ((flags & HeightValue) == 0)
4892                        geometry.height=geometry.width;
4893                      break;
4894                    }
4895                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
4896                    keyword);
4897                  break;
4898                }
4899                case 'H':
4900                case 'h':
4901                {
4902                  if (LocaleCompare(keyword,"height") == 0)
4903                    {
4904                      geometry.height=StringToLong(value);
4905                      break;
4906                    }
4907                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
4908                    keyword);
4909                  break;
4910                }
4911                case 'R':
4912                case 'r':
4913                {
4914                  if (LocaleCompare(keyword,"raise") == 0)
4915                    {
4916                      option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
4917                        value);
4918                      if (option < 0)
4919                        ThrowMSLException(OptionError,"UnrecognizedNoiseType",
4920                          value);
4921                      raise=(MagickBooleanType) option;
4922                      break;
4923                    }
4924                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
4925                    keyword);
4926                  break;
4927                }
4928                case 'W':
4929                case 'w':
4930                {
4931                  if (LocaleCompare(keyword,"width") == 0)
4932                    {
4933                      geometry.width=StringToLong(value);
4934                      break;
4935                    }
4936                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
4937                    keyword);
4938                  break;
4939                }
4940                default:
4941                {
4942                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
4943                    keyword);
4944                  break;
4945                }
4946              }
4947            }
4948          (void) RaiseImage(msl_info->image[n],&geometry,raise);
4949          break;
4950        }
4951      if (LocaleCompare((const char *) tag,"read") == 0)
4952        {
4953          if (attributes == (const xmlChar **) NULL)
4954            break;
4955          for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4956          {
4957            keyword=(const char *) attributes[i++];
4958            CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
4959              msl_info->attributes[n],(const char *) attributes[i]));
4960            switch (*keyword)
4961            {
4962              case 'F':
4963              case 'f':
4964              {
4965                if (LocaleCompare(keyword,"filename") == 0)
4966                  {
4967                    Image
4968                      *image;
4969
4970                    (void) CopyMagickString(msl_info->image_info[n]->filename,
4971                      value,MaxTextExtent);
4972                    image=ReadImage(msl_info->image_info[n],&exception);
4973                    CatchException(&exception);
4974                    if (image == (Image *) NULL)
4975                      continue;
4976                    AppendImageToList(&msl_info->image[n],image);
4977                    break;
4978                  }
4979                (void) SetMSLAttributes(msl_info,keyword,value);
4980                break;
4981              }
4982              default:
4983              {
4984                (void) SetMSLAttributes(msl_info,keyword,value);
4985                break;
4986              }
4987            }
4988          }
4989          break;
4990        }
4991      if (LocaleCompare((const char *) tag,"reduce-noise") == 0)
4992        {
4993          Image
4994            *paint_image;
4995
4996          /*
4997            Reduce-noise image.
4998          */
4999          if (msl_info->image[n] == (Image *) NULL)
5000            {
5001              ThrowMSLException(OptionError,"NoImagesDefined",
5002                (const char *) tag);
5003              break;
5004            }
5005          if (attributes != (const xmlChar **) NULL)
5006            for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5007            {
5008              keyword=(const char *) attributes[i++];
5009              attribute=InterpretImageProperties(msl_info->image_info[n],
5010                msl_info->attributes[n],(const char *) attributes[i]);
5011              CloneString(&value,attribute);
5012              switch (*keyword)
5013              {
5014                case 'G':
5015                case 'g':
5016                {
5017                  if (LocaleCompare(keyword,"geometry") == 0)
5018                    {
5019                      flags=ParseGeometry(value,&geometry_info);
5020                      if ((flags & SigmaValue) == 0)
5021                        geometry_info.sigma=1.0;
5022                      break;
5023                    }
5024                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
5025                    keyword);
5026                  break;
5027                }
5028                case 'R':
5029                case 'r':
5030                {
5031                  if (LocaleCompare(keyword,"radius") == 0)
5032                    {
5033                      geometry_info.rho=InterpretLocaleValue(value,
5034                        (char **) NULL);
5035                      break;
5036                    }
5037                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
5038                    keyword);
5039                  break;
5040                }
5041                default:
5042                {
5043                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
5044                    keyword);
5045                  break;
5046                }
5047              }
5048            }
5049          paint_image=StatisticImage(msl_info->image[n],NonpeakStatistic,
5050            (size_t) geometry_info.rho,(size_t) geometry_info.sigma,
5051            &msl_info->image[n]->exception);
5052          if (paint_image == (Image *) NULL)
5053            break;
5054          msl_info->image[n]=DestroyImage(msl_info->image[n]);
5055          msl_info->image[n]=paint_image;
5056          break;
5057        }
5058      else if (LocaleCompare((const char *) tag,"repage") == 0)
5059      {
5060        /* init the values */
5061        width=msl_info->image[n]->page.width;
5062        height=msl_info->image[n]->page.height;
5063        x=msl_info->image[n]->page.x;
5064        y=msl_info->image[n]->page.y;
5065
5066        if (msl_info->image[n] == (Image *) NULL)
5067        {
5068          ThrowMSLException(OptionError,"NoImagesDefined",
5069            (const char *) tag);
5070          break;
5071        }
5072        if (attributes == (const xmlChar **) NULL)
5073        break;
5074        for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5075        {
5076        keyword=(const char *) attributes[i++];
5077        CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
5078          msl_info->attributes[n],(const char *) attributes[i]));
5079        switch (*keyword)
5080        {
5081          case 'G':
5082          case 'g':
5083          {
5084          if (LocaleCompare(keyword,"geometry") == 0)
5085            {
5086              int
5087                flags;
5088
5089              RectangleInfo
5090                geometry;
5091
5092            flags=ParseAbsoluteGeometry(value,&geometry);
5093            if ((flags & WidthValue) != 0)
5094              {
5095                if ((flags & HeightValue) == 0)
5096                  geometry.height=geometry.width;
5097                width=geometry.width;
5098                height=geometry.height;
5099              }
5100            if ((flags & AspectValue) != 0)
5101              {
5102                if ((flags & XValue) != 0)
5103                  x+=geometry.x;
5104                if ((flags & YValue) != 0)
5105                  y+=geometry.y;
5106              }
5107            else
5108              {
5109                if ((flags & XValue) != 0)
5110                  {
5111                    x=geometry.x;
5112                    if ((width == 0) && (geometry.x > 0))
5113                      width=msl_info->image[n]->columns+geometry.x;
5114                  }
5115                if ((flags & YValue) != 0)
5116                  {
5117                    y=geometry.y;
5118                    if ((height == 0) && (geometry.y > 0))
5119                      height=msl_info->image[n]->rows+geometry.y;
5120                  }
5121              }
5122            break;
5123            }
5124          ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5125          break;
5126          }
5127          case 'H':
5128          case 'h':
5129          {
5130          if (LocaleCompare(keyword,"height") == 0)
5131            {
5132            height = StringToLong( value );
5133            break;
5134            }
5135          ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5136          break;
5137          }
5138          case 'W':
5139          case 'w':
5140          {
5141          if (LocaleCompare(keyword,"width") == 0)
5142            {
5143            width = StringToLong( value );
5144            break;
5145            }
5146          ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5147          break;
5148          }
5149          case 'X':
5150          case 'x':
5151          {
5152          if (LocaleCompare(keyword,"x") == 0)
5153            {
5154            x = StringToLong( value );
5155            break;
5156            }
5157          ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5158          break;
5159          }
5160          case 'Y':
5161          case 'y':
5162          {
5163          if (LocaleCompare(keyword,"y") == 0)
5164            {
5165            y = StringToLong( value );
5166            break;
5167            }
5168          ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5169          break;
5170          }
5171          default:
5172          {
5173          ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5174          break;
5175          }
5176        }
5177        }
5178
5179         msl_info->image[n]->page.width=width;
5180         msl_info->image[n]->page.height=height;
5181         msl_info->image[n]->page.x=x;
5182         msl_info->image[n]->page.y=y;
5183        break;
5184      }
5185    else if (LocaleCompare((const char *) tag,"resample") == 0)
5186    {
5187      double
5188        x_resolution,
5189        y_resolution;
5190
5191      if (msl_info->image[n] == (Image *) NULL)
5192        {
5193          ThrowMSLException(OptionError,"NoImagesDefined",
5194            (const char *) tag);
5195          break;
5196        }
5197      if (attributes == (const xmlChar **) NULL)
5198        break;
5199      x_resolution=DefaultResolution;
5200      y_resolution=DefaultResolution;
5201      for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5202      {
5203        keyword=(const char *) attributes[i++];
5204        CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
5205          msl_info->attributes[n],(const char *) attributes[i]));
5206        switch (*keyword)
5207        {
5208          case 'b':
5209          {
5210            if (LocaleCompare(keyword,"blur") == 0)
5211              {
5212                msl_info->image[n]->blur=InterpretLocaleValue(value,
5213                        (char **) NULL);
5214                break;
5215              }
5216            ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5217            break;
5218          }
5219          case 'G':
5220          case 'g':
5221          {
5222            if (LocaleCompare(keyword,"geometry") == 0)
5223              {
5224                ssize_t
5225                  flags;
5226
5227                flags=ParseGeometry(value,&geometry_info);
5228                if ((flags & SigmaValue) == 0)
5229                  geometry_info.sigma*=geometry_info.rho;
5230                x_resolution=geometry_info.rho;
5231                y_resolution=geometry_info.sigma;
5232                break;
5233              }
5234            ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5235            break;
5236          }
5237          case 'X':
5238          case 'x':
5239          {
5240            if (LocaleCompare(keyword,"x-resolution") == 0)
5241              {
5242                x_resolution=InterpretLocaleValue(value,(char **) NULL);
5243                break;
5244              }
5245            ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5246            break;
5247          }
5248          case 'Y':
5249          case 'y':
5250          {
5251            if (LocaleCompare(keyword,"y-resolution") == 0)
5252              {
5253                y_resolution=InterpretLocaleValue(value,(char **) NULL);
5254                break;
5255              }
5256            ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5257            break;
5258          }
5259          default:
5260          {
5261            ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5262            break;
5263          }
5264        }
5265      }
5266      /*
5267        Resample image.
5268      */
5269      {
5270        double
5271          factor;
5272
5273        Image
5274          *resample_image;
5275
5276        factor=1.0;
5277        if (msl_info->image[n]->units == PixelsPerCentimeterResolution)
5278          factor=2.54;
5279        width=(size_t) (x_resolution*msl_info->image[n]->columns/
5280          (factor*(msl_info->image[n]->x_resolution == 0.0 ? DefaultResolution :
5281          msl_info->image[n]->x_resolution))+0.5);
5282        height=(size_t) (y_resolution*msl_info->image[n]->rows/
5283          (factor*(msl_info->image[n]->y_resolution == 0.0 ? DefaultResolution :
5284          msl_info->image[n]->y_resolution))+0.5);
5285        resample_image=ResizeImage(msl_info->image[n],width,height,
5286          msl_info->image[n]->filter,msl_info->image[n]->blur,
5287          &msl_info->image[n]->exception);
5288        if (resample_image == (Image *) NULL)
5289          break;
5290        msl_info->image[n]=DestroyImage(msl_info->image[n]);
5291        msl_info->image[n]=resample_image;
5292      }
5293      break;
5294    }
5295      if (LocaleCompare((const char *) tag,"resize") == 0)
5296        {
5297          double
5298            blur;
5299
5300          FilterTypes
5301            filter;
5302
5303          Image
5304            *resize_image;
5305
5306          /*
5307            Resize image.
5308          */
5309          if (msl_info->image[n] == (Image *) NULL)
5310            {
5311              ThrowMSLException(OptionError,"NoImagesDefined",
5312                (const char *) tag);
5313              break;
5314            }
5315          filter=UndefinedFilter;
5316          blur=1.0;
5317          if (attributes != (const xmlChar **) NULL)
5318            for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5319            {
5320              keyword=(const char *) attributes[i++];
5321              attribute=InterpretImageProperties(msl_info->image_info[n],
5322                msl_info->attributes[n],(const char *) attributes[i]);
5323              CloneString(&value,attribute);
5324              switch (*keyword)
5325              {
5326                case 'F':
5327                case 'f':
5328                {
5329                  if (LocaleCompare(keyword,"filter") == 0)
5330                    {
5331                      option=ParseCommandOption(MagickFilterOptions,MagickFalse,
5332                        value);
5333                      if (option < 0)
5334                        ThrowMSLException(OptionError,"UnrecognizedNoiseType",
5335                          value);
5336                      filter=(FilterTypes) option;
5337                      break;
5338                    }
5339                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
5340                    keyword);
5341                  break;
5342                }
5343                case 'G':
5344                case 'g':
5345                {
5346                  if (LocaleCompare(keyword,"geometry") == 0)
5347                    {
5348                      flags=ParseRegionGeometry(msl_info->image[n],value,
5349                        &geometry,&exception);
5350                      break;
5351                    }
5352                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
5353                    keyword);
5354                  break;
5355                }
5356                case 'H':
5357                case 'h':
5358                {
5359                  if (LocaleCompare(keyword,"height") == 0)
5360                    {
5361                      geometry.height=StringToUnsignedLong(value);
5362                      break;
5363                    }
5364                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
5365                    keyword);
5366                  break;
5367                }
5368                case 'S':
5369                case 's':
5370                {
5371                  if (LocaleCompare(keyword,"support") == 0)
5372                    {
5373                      blur=InterpretLocaleValue(value,(char **) NULL);
5374                      break;
5375                    }
5376                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
5377                    keyword);
5378                  break;
5379                }
5380                case 'W':
5381                case 'w':
5382                {
5383                  if (LocaleCompare(keyword,"width") == 0)
5384                    {
5385                      geometry.width=StringToLong(value);
5386                      break;
5387                    }
5388                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
5389                    keyword);
5390                  break;
5391                }
5392                default:
5393                {
5394                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
5395                    keyword);
5396                  break;
5397                }
5398              }
5399            }
5400          resize_image=ResizeImage(msl_info->image[n],geometry.width,
5401            geometry.height,filter,blur,&msl_info->image[n]->exception);
5402          if (resize_image == (Image *) NULL)
5403            break;
5404          msl_info->image[n]=DestroyImage(msl_info->image[n]);
5405          msl_info->image[n]=resize_image;
5406          break;
5407        }
5408      if (LocaleCompare((const char *) tag,"roll") == 0)
5409        {
5410          Image
5411            *roll_image;
5412
5413          /*
5414            Roll image.
5415          */
5416          if (msl_info->image[n] == (Image *) NULL)
5417            {
5418              ThrowMSLException(OptionError,"NoImagesDefined",
5419                (const char *) tag);
5420              break;
5421            }
5422          SetGeometry(msl_info->image[n],&geometry);
5423          if (attributes != (const xmlChar **) NULL)
5424            for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5425            {
5426              keyword=(const char *) attributes[i++];
5427              attribute=InterpretImageProperties(msl_info->image_info[n],
5428                msl_info->attributes[n],(const char *) attributes[i]);
5429              CloneString(&value,attribute);
5430              switch (*keyword)
5431              {
5432                case 'G':
5433                case 'g':
5434                {
5435                  if (LocaleCompare(keyword,"geometry") == 0)
5436                    {
5437                      flags=ParsePageGeometry(msl_info->image[n],value,
5438                        &geometry,&exception);
5439                      if ((flags & HeightValue) == 0)
5440                        geometry.height=geometry.width;
5441                      break;
5442                    }
5443                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
5444                    keyword);
5445                  break;
5446                }
5447                case 'X':
5448                case 'x':
5449                {
5450                  if (LocaleCompare(keyword,"x") == 0)
5451                    {
5452                      geometry.x=StringToLong(value);
5453                      break;
5454                    }
5455                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
5456                    keyword);
5457                  break;
5458                }
5459                case 'Y':
5460                case 'y':
5461                {
5462                  if (LocaleCompare(keyword,"y") == 0)
5463                    {
5464                      geometry.y=StringToLong(value);
5465                      break;
5466                    }
5467                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
5468                    keyword);
5469                  break;
5470                }
5471                default:
5472                {
5473                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
5474                    keyword);
5475                  break;
5476                }
5477              }
5478            }
5479          roll_image=RollImage(msl_info->image[n],geometry.x,geometry.y,
5480            &msl_info->image[n]->exception);
5481          if (roll_image == (Image *) NULL)
5482            break;
5483          msl_info->image[n]=DestroyImage(msl_info->image[n]);
5484          msl_info->image[n]=roll_image;
5485          break;
5486        }
5487      else if (LocaleCompare((const char *) tag,"roll") == 0)
5488      {
5489        /* init the values */
5490        width=msl_info->image[n]->columns;
5491        height=msl_info->image[n]->rows;
5492        x = y = 0;
5493
5494        if (msl_info->image[n] == (Image *) NULL)
5495        {
5496          ThrowMSLException(OptionError,"NoImagesDefined",
5497            (const char *) tag);
5498          break;
5499        }
5500        if (attributes == (const xmlChar **) NULL)
5501        break;
5502        for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5503        {
5504        keyword=(const char *) attributes[i++];
5505        CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
5506          msl_info->attributes[n],(const char *) attributes[i]));
5507        switch (*keyword)
5508        {
5509          case 'G':
5510          case 'g':
5511          {
5512          if (LocaleCompare(keyword,"geometry") == 0)
5513            {
5514            (void) ParseMetaGeometry(value,&x,&y,&width,&height);
5515            break;
5516            }
5517          ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5518          break;
5519          }
5520          case 'X':
5521          case 'x':
5522          {
5523          if (LocaleCompare(keyword,"x") == 0)
5524            {
5525            x = StringToLong( value );
5526            break;
5527            }
5528          ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5529          break;
5530          }
5531          case 'Y':
5532          case 'y':
5533          {
5534          if (LocaleCompare(keyword,"y") == 0)
5535            {
5536            y = StringToLong( value );
5537            break;
5538            }
5539          ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5540          break;
5541          }
5542          default:
5543          {
5544          ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5545          break;
5546          }
5547        }
5548        }
5549
5550        /*
5551          process image.
5552        */
5553        {
5554        Image
5555          *newImage;
5556
5557        newImage=RollImage(msl_info->image[n], x, y, &msl_info->image[n]->exception);
5558        if (newImage == (Image *) NULL)
5559          break;
5560        msl_info->image[n]=DestroyImage(msl_info->image[n]);
5561        msl_info->image[n]=newImage;
5562        }
5563
5564        break;
5565      }
5566      if (LocaleCompare((const char *) tag,"rotate") == 0)
5567        {
5568          Image
5569            *rotate_image;
5570
5571          /*
5572            Rotate image.
5573          */
5574          if (msl_info->image[n] == (Image *) NULL)
5575            {
5576              ThrowMSLException(OptionError,"NoImagesDefined",
5577                (const char *) tag);
5578              break;
5579            }
5580          if (attributes != (const xmlChar **) NULL)
5581            for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5582            {
5583              keyword=(const char *) attributes[i++];
5584              attribute=InterpretImageProperties(msl_info->image_info[n],
5585                msl_info->attributes[n],(const char *) attributes[i]);
5586              CloneString(&value,attribute);
5587              switch (*keyword)
5588              {
5589                case 'D':
5590                case 'd':
5591                {
5592                  if (LocaleCompare(keyword,"degrees") == 0)
5593                    {
5594                      geometry_info.rho=InterpretLocaleValue(value,
5595                        (char **) NULL);
5596                      break;
5597                    }
5598                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
5599                    keyword);
5600                  break;
5601                }
5602                case 'G':
5603                case 'g':
5604                {
5605                  if (LocaleCompare(keyword,"geometry") == 0)
5606                    {
5607                      flags=ParseGeometry(value,&geometry_info);
5608                      if ((flags & SigmaValue) == 0)
5609                        geometry_info.sigma=1.0;
5610                      break;
5611                    }
5612                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
5613                    keyword);
5614                  break;
5615                }
5616                default:
5617                {
5618                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
5619                    keyword);
5620                  break;
5621                }
5622              }
5623            }
5624          rotate_image=RotateImage(msl_info->image[n],geometry_info.rho,
5625            &msl_info->image[n]->exception);
5626          if (rotate_image == (Image *) NULL)
5627            break;
5628          msl_info->image[n]=DestroyImage(msl_info->image[n]);
5629          msl_info->image[n]=rotate_image;
5630          break;
5631        }
5632      else if (LocaleCompare((const char *) tag,"rotate") == 0)
5633      {
5634        /* init the values */
5635        double  degrees = 0;
5636
5637        if (msl_info->image[n] == (Image *) NULL)
5638        {
5639          ThrowMSLException(OptionError,"NoImagesDefined",
5640            (const char *) tag);
5641          break;
5642        }
5643        if (attributes == (const xmlChar **) NULL)
5644          break;
5645        for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5646        {
5647        keyword=(const char *) attributes[i++];
5648        CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
5649          msl_info->attributes[n],(const char *) attributes[i]));
5650        switch (*keyword)
5651        {
5652          case 'D':
5653          case 'd':
5654          {
5655          if (LocaleCompare(keyword,"degrees") == 0)
5656            {
5657            degrees = InterpretLocaleValue(value,(char **) NULL);
5658            break;
5659            }
5660          ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5661          break;
5662          }
5663          default:
5664          {
5665          ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5666          break;
5667          }
5668        }
5669        }
5670
5671        /*
5672          process image.
5673        */
5674        {
5675        Image
5676          *newImage;
5677
5678        newImage=RotateImage(msl_info->image[n], degrees, &msl_info->image[n]->exception);
5679        if (newImage == (Image *) NULL)
5680          break;
5681        msl_info->image[n]=DestroyImage(msl_info->image[n]);
5682        msl_info->image[n]=newImage;
5683        }
5684
5685        break;
5686      }
5687      ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
5688    }
5689    case 'S':
5690    case 's':
5691    {
5692      if (LocaleCompare((const char *) tag,"sample") == 0)
5693        {
5694          Image
5695            *sample_image;
5696
5697          /*
5698            Sample image.
5699          */
5700          if (msl_info->image[n] == (Image *) NULL)
5701            {
5702              ThrowMSLException(OptionError,"NoImagesDefined",
5703                (const char *) tag);
5704              break;
5705            }
5706          if (attributes != (const xmlChar **) NULL)
5707            for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5708            {
5709              keyword=(const char *) attributes[i++];
5710              attribute=InterpretImageProperties(msl_info->image_info[n],
5711                msl_info->attributes[n],(const char *) attributes[i]);
5712              CloneString(&value,attribute);
5713              switch (*keyword)
5714              {
5715                case 'G':
5716                case 'g':
5717                {
5718                  if (LocaleCompare(keyword,"geometry") == 0)
5719                    {
5720                      flags=ParseRegionGeometry(msl_info->image[n],value,
5721                        &geometry,&exception);
5722                      break;
5723                    }
5724                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
5725                    keyword);
5726                  break;
5727                }
5728                case 'H':
5729                case 'h':
5730                {
5731                  if (LocaleCompare(keyword,"height") == 0)
5732                    {
5733                      geometry.height=StringToUnsignedLong(value);
5734                      break;
5735                    }
5736                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
5737                    keyword);
5738                  break;
5739                }
5740                case 'W':
5741                case 'w':
5742                {
5743                  if (LocaleCompare(keyword,"width") == 0)
5744                    {
5745                      geometry.width=StringToLong(value);
5746                      break;
5747                    }
5748                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
5749                    keyword);
5750                  break;
5751                }
5752                default:
5753                {
5754                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
5755                    keyword);
5756                  break;
5757                }
5758              }
5759            }
5760          sample_image=SampleImage(msl_info->image[n],geometry.width,
5761            geometry.height,&msl_info->image[n]->exception);
5762          if (sample_image == (Image *) NULL)
5763            break;
5764          msl_info->image[n]=DestroyImage(msl_info->image[n]);
5765          msl_info->image[n]=sample_image;
5766          break;
5767        }
5768      if (LocaleCompare((const char *) tag,"scale") == 0)
5769        {
5770          Image
5771            *scale_image;
5772
5773          /*
5774            Scale image.
5775          */
5776          if (msl_info->image[n] == (Image *) NULL)
5777            {
5778              ThrowMSLException(OptionError,"NoImagesDefined",
5779                (const char *) tag);
5780              break;
5781            }
5782          if (attributes != (const xmlChar **) NULL)
5783            for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5784            {
5785              keyword=(const char *) attributes[i++];
5786              attribute=InterpretImageProperties(msl_info->image_info[n],
5787                msl_info->attributes[n],(const char *) attributes[i]);
5788              CloneString(&value,attribute);
5789              switch (*keyword)
5790              {
5791                case 'G':
5792                case 'g':
5793                {
5794                  if (LocaleCompare(keyword,"geometry") == 0)
5795                    {
5796                      flags=ParseRegionGeometry(msl_info->image[n],value,
5797                        &geometry,&exception);
5798                      break;
5799                    }
5800                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
5801                    keyword);
5802                  break;
5803                }
5804                case 'H':
5805                case 'h':
5806                {
5807                  if (LocaleCompare(keyword,"height") == 0)
5808                    {
5809                      geometry.height=StringToUnsignedLong(value);
5810                      break;
5811                    }
5812                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
5813                    keyword);
5814                  break;
5815                }
5816                case 'W':
5817                case 'w':
5818                {
5819                  if (LocaleCompare(keyword,"width") == 0)
5820                    {
5821                      geometry.width=StringToLong(value);
5822                      break;
5823                    }
5824                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
5825                    keyword);
5826                  break;
5827                }
5828                default:
5829                {
5830                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
5831                    keyword);
5832                  break;
5833                }
5834              }
5835            }
5836          scale_image=ScaleImage(msl_info->image[n],geometry.width,
5837            geometry.height,&msl_info->image[n]->exception);
5838          if (scale_image == (Image *) NULL)
5839            break;
5840          msl_info->image[n]=DestroyImage(msl_info->image[n]);
5841          msl_info->image[n]=scale_image;
5842          break;
5843        }
5844      if (LocaleCompare((const char *) tag,"segment") == 0)
5845        {
5846          ColorspaceType
5847            colorspace;
5848
5849          MagickBooleanType
5850            verbose;
5851
5852          /*
5853            Segment image.
5854          */
5855          if (msl_info->image[n] == (Image *) NULL)
5856            {
5857              ThrowMSLException(OptionError,"NoImagesDefined",
5858                (const char *) tag);
5859              break;
5860            }
5861          geometry_info.rho=1.0;
5862          geometry_info.sigma=1.5;
5863          colorspace=RGBColorspace;
5864          verbose=MagickFalse;
5865          if (attributes != (const xmlChar **) NULL)
5866            for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5867            {
5868              keyword=(const char *) attributes[i++];
5869              attribute=InterpretImageProperties(msl_info->image_info[n],
5870                msl_info->attributes[n],(const char *) attributes[i]);
5871              CloneString(&value,attribute);
5872              switch (*keyword)
5873              {
5874                case 'C':
5875                case 'c':
5876                {
5877                  if (LocaleCompare(keyword,"cluster-threshold") == 0)
5878                    {
5879                      geometry_info.rho=InterpretLocaleValue(value,
5880                        (char **) NULL);
5881                      break;
5882                    }
5883                  if (LocaleCompare(keyword,"colorspace") == 0)
5884                    {
5885                      option=ParseCommandOption(MagickColorspaceOptions,
5886                        MagickFalse,value);
5887                      if (option < 0)
5888                        ThrowMSLException(OptionError,
5889                          "UnrecognizedColorspaceType",value);
5890                      colorspace=(ColorspaceType) option;
5891                      break;
5892                    }
5893                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
5894                    keyword);
5895                  break;
5896                }
5897                case 'G':
5898                case 'g':
5899                {
5900                  if (LocaleCompare(keyword,"geometry") == 0)
5901                    {
5902                      flags=ParseGeometry(value,&geometry_info);
5903                      if ((flags & SigmaValue) == 0)
5904                        geometry_info.sigma=1.5;
5905                      break;
5906                    }
5907                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
5908                    keyword);
5909                  break;
5910                }
5911                case 'S':
5912                case 's':
5913                {
5914                  if (LocaleCompare(keyword,"smoothing-threshold") == 0)
5915                    {
5916                      geometry_info.sigma=InterpretLocaleValue(value,
5917                        (char **) NULL);
5918                      break;
5919                    }
5920                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
5921                    keyword);
5922                  break;
5923                }
5924                default:
5925                {
5926                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
5927                    keyword);
5928                  break;
5929                }
5930              }
5931            }
5932          (void) SegmentImage(msl_info->image[n],colorspace,verbose,
5933            geometry_info.rho,geometry_info.sigma);
5934          break;
5935        }
5936      else if (LocaleCompare((const char *) tag, "set") == 0)
5937      {
5938        if (msl_info->image[n] == (Image *) NULL)
5939        {
5940          ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
5941          break;
5942        }
5943
5944        if (attributes == (const xmlChar **) NULL)
5945          break;
5946        for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5947        {
5948          keyword=(const char *) attributes[i++];
5949          CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
5950            msl_info->attributes[n],(const char *) attributes[i]));
5951          switch (*keyword)
5952          {
5953            case 'C':
5954            case 'c':
5955            {
5956              if (LocaleCompare(keyword,"clip-mask") == 0)
5957                {
5958                  for (j=0; j < msl_info->n; j++)
5959                  {
5960                    const char
5961                      *property;
5962
5963                    property=GetImageProperty(msl_info->attributes[j],"id");
5964                    if (LocaleCompare(property,value) == 0)
5965                      {
5966                        SetImageMask(msl_info->image[n],msl_info->image[j]);
5967                        break;
5968                      }
5969                  }
5970                  break;
5971                }
5972              if (LocaleCompare(keyword,"clip-path") == 0)
5973                {
5974                  for (j=0; j < msl_info->n; j++)
5975                  {
5976                    const char
5977                      *property;
5978
5979                    property=GetImageProperty(msl_info->attributes[j],"id");
5980                    if (LocaleCompare(property,value) == 0)
5981                      {
5982                        SetImageClipMask(msl_info->image[n],msl_info->image[j]);
5983                        break;
5984                      }
5985                  }
5986                  break;
5987                }
5988              if (LocaleCompare(keyword,"colorspace") == 0)
5989                {
5990                  ssize_t
5991                    colorspace;
5992
5993                  colorspace=(ColorspaceType) ParseCommandOption(
5994                    MagickColorspaceOptions,MagickFalse,value);
5995                  if (colorspace < 0)
5996                    ThrowMSLException(OptionError,"UnrecognizedColorspace",
5997                      value);
5998                  (void) TransformImageColorspace(msl_info->image[n],
5999                    (ColorspaceType) colorspace);
6000                  break;
6001                }
6002              (void) SetMSLAttributes(msl_info,keyword,value);
6003              (void) SetImageProperty(msl_info->image[n],keyword,value);
6004              break;
6005            }
6006            case 'D':
6007            case 'd':
6008            {
6009              if (LocaleCompare(keyword,"density") == 0)
6010                {
6011                  flags=ParseGeometry(value,&geometry_info);
6012                  msl_info->image[n]->x_resolution=geometry_info.rho;
6013                  msl_info->image[n]->y_resolution=geometry_info.sigma;
6014                  if ((flags & SigmaValue) == 0)
6015                    msl_info->image[n]->y_resolution=
6016                      msl_info->image[n]->x_resolution;
6017                  break;
6018                }
6019              (void) SetMSLAttributes(msl_info,keyword,value);
6020              (void) SetImageProperty(msl_info->image[n],keyword,value);
6021              break;
6022            }
6023            case 'O':
6024            case 'o':
6025            {
6026              if (LocaleCompare(keyword, "opacity") == 0)
6027                {
6028                  ssize_t  opac = OpaqueAlpha,
6029                  len = (ssize_t) strlen( value );
6030
6031                  if (value[len-1] == '%') {
6032                    char  tmp[100];
6033                    (void) CopyMagickString(tmp,value,len);
6034                    opac = StringToLong( tmp );
6035                    opac = (int)(QuantumRange * ((float)opac/100));
6036                  } else
6037                    opac = StringToLong( value );
6038                  (void) SetImageOpacity( msl_info->image[n], (Quantum) opac );
6039                  break;
6040              }
6041              (void) SetMSLAttributes(msl_info,keyword,value);
6042              (void) SetImageProperty(msl_info->image[n],keyword,value);
6043              break;
6044            }
6045            case 'P':
6046            case 'p':
6047            {
6048              if (LocaleCompare(keyword, "page") == 0)
6049              {
6050                char
6051                  page[MaxTextExtent];
6052
6053                const char
6054                  *image_option;
6055
6056                MagickStatusType
6057                  flags;
6058
6059                RectangleInfo
6060                  geometry;
6061
6062                (void) ResetMagickMemory(&geometry,0,sizeof(geometry));
6063                image_option=GetImageOption(msl_info->image_info[n],"page");
6064                if (image_option != (const char *) NULL)
6065                  flags=ParseAbsoluteGeometry(image_option,&geometry);
6066                flags=ParseAbsoluteGeometry(value,&geometry);
6067                (void) FormatLocaleString(page,MaxTextExtent,"%.20gx%.20g",
6068                  (double) geometry.width,(double) geometry.height);
6069                if (((flags & XValue) != 0) || ((flags & YValue) != 0))
6070                  (void) FormatLocaleString(page,MaxTextExtent,
6071                    "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,
6072                    (double) geometry.height,(double) geometry.x,(double)
6073                    geometry.y);
6074                (void) SetImageOption(msl_info->image_info[n],keyword,page);
6075                msl_info->image_info[n]->page=GetPageGeometry(page);
6076                break;
6077              }
6078              (void) SetMSLAttributes(msl_info,keyword,value);
6079              (void) SetImageProperty(msl_info->image[n],keyword,value);
6080              break;
6081            }
6082            default:
6083            {
6084              (void) SetMSLAttributes(msl_info,keyword,value);
6085              (void) SetImageProperty(msl_info->image[n],keyword,value);
6086              break;
6087            }
6088          }
6089        }
6090        break;
6091      }
6092      if (LocaleCompare((const char *) tag,"shade") == 0)
6093        {
6094          Image
6095            *shade_image;
6096
6097          MagickBooleanType
6098            gray;
6099
6100          /*
6101            Shade image.
6102          */
6103          if (msl_info->image[n] == (Image *) NULL)
6104            {
6105              ThrowMSLException(OptionError,"NoImagesDefined",
6106                (const char *) tag);
6107              break;
6108            }
6109          gray=MagickFalse;
6110          if (attributes != (const xmlChar **) NULL)
6111            for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6112            {
6113              keyword=(const char *) attributes[i++];
6114              attribute=InterpretImageProperties(msl_info->image_info[n],
6115                msl_info->attributes[n],(const char *) attributes[i]);
6116              CloneString(&value,attribute);
6117              switch (*keyword)
6118              {
6119                case 'A':
6120                case 'a':
6121                {
6122                  if (LocaleCompare(keyword,"azimuth") == 0)
6123                    {
6124                      geometry_info.rho=InterpretLocaleValue(value,
6125                        (char **) NULL);
6126                      break;
6127                    }
6128                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
6129                    keyword);
6130                  break;
6131                }
6132                case 'E':
6133                case 'e':
6134                {
6135                  if (LocaleCompare(keyword,"elevation") == 0)
6136                    {
6137                      geometry_info.sigma=InterpretLocaleValue(value,
6138                        (char **) NULL);
6139                      break;
6140                    }
6141                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
6142                    keyword);
6143                  break;
6144                }
6145                case 'G':
6146                case 'g':
6147                {
6148                  if (LocaleCompare(keyword,"geometry") == 0)
6149                    {
6150                      flags=ParseGeometry(value,&geometry_info);
6151                      if ((flags & SigmaValue) == 0)
6152                        geometry_info.sigma=1.0;
6153                      break;
6154                    }
6155                  if (LocaleCompare(keyword,"gray") == 0)
6156                    {
6157                      option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
6158                        value);
6159                      if (option < 0)
6160                        ThrowMSLException(OptionError,"UnrecognizedNoiseType",
6161                          value);
6162                      gray=(MagickBooleanType) option;
6163                      break;
6164                    }
6165                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
6166                    keyword);
6167                  break;
6168                }
6169                default:
6170                {
6171                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
6172                    keyword);
6173                  break;
6174                }
6175              }
6176            }
6177          shade_image=ShadeImage(msl_info->image[n],gray,geometry_info.rho,
6178            geometry_info.sigma,&msl_info->image[n]->exception);
6179          if (shade_image == (Image *) NULL)
6180            break;
6181          msl_info->image[n]=DestroyImage(msl_info->image[n]);
6182          msl_info->image[n]=shade_image;
6183          break;
6184        }
6185      if (LocaleCompare((const char *) tag,"shadow") == 0)
6186        {
6187          Image
6188            *shadow_image;
6189
6190          /*
6191            Shear image.
6192          */
6193          if (msl_info->image[n] == (Image *) NULL)
6194            {
6195              ThrowMSLException(OptionError,"NoImagesDefined",
6196                (const char *) tag);
6197              break;
6198            }
6199          if (attributes != (const xmlChar **) NULL)
6200            for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6201            {
6202              keyword=(const char *) attributes[i++];
6203              attribute=InterpretImageProperties(msl_info->image_info[n],
6204                msl_info->attributes[n],(const char *) attributes[i]);
6205              CloneString(&value,attribute);
6206              switch (*keyword)
6207              {
6208                case 'G':
6209                case 'g':
6210                {
6211                  if (LocaleCompare(keyword,"geometry") == 0)
6212                    {
6213                      flags=ParseGeometry(value,&geometry_info);
6214                      if ((flags & SigmaValue) == 0)
6215                        geometry_info.sigma=1.0;
6216                      break;
6217                    }
6218                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
6219                    keyword);
6220                  break;
6221                }
6222                case 'O':
6223                case 'o':
6224                {
6225                  if (LocaleCompare(keyword,"opacity") == 0)
6226                    {
6227                      geometry_info.rho=StringToLong(value);
6228                      break;
6229                    }
6230                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
6231                    keyword);
6232                  break;
6233                }
6234                case 'S':
6235                case 's':
6236                {
6237                  if (LocaleCompare(keyword,"sigma") == 0)
6238                    {
6239                      geometry_info.sigma=StringToLong(value);
6240                      break;
6241                    }
6242                  break;
6243                }
6244                case 'X':
6245                case 'x':
6246                {
6247                  if (LocaleCompare(keyword,"x") == 0)
6248                    {
6249                      geometry_info.xi=InterpretLocaleValue(value,
6250                        (char **) NULL);
6251                      break;
6252                    }
6253                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
6254                    keyword);
6255                  break;
6256                }
6257                case 'Y':
6258                case 'y':
6259                {
6260                  if (LocaleCompare(keyword,"y") == 0)
6261                    {
6262                      geometry_info.psi=StringToLong(value);
6263                      break;
6264                    }
6265                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
6266                    keyword);
6267                  break;
6268                }
6269                default:
6270                {
6271                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
6272                    keyword);
6273                  break;
6274                }
6275              }
6276            }
6277          shadow_image=ShadowImage(msl_info->image[n],geometry_info.rho,
6278            geometry_info.sigma,(ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
6279            ceil(geometry_info.psi-0.5),&msl_info->image[n]->exception);
6280          if (shadow_image == (Image *) NULL)
6281            break;
6282          msl_info->image[n]=DestroyImage(msl_info->image[n]);
6283          msl_info->image[n]=shadow_image;
6284          break;
6285        }
6286      if (LocaleCompare((const char *) tag,"sharpen") == 0)
6287      {
6288        double  radius = 0.0,
6289            sigma = 1.0;
6290
6291        if (msl_info->image[n] == (Image *) NULL)
6292          {
6293            ThrowMSLException(OptionError,"NoImagesDefined",
6294              (const char *) tag);
6295            break;
6296          }
6297        /*
6298        NOTE: sharpen can have no attributes, since we use all the defaults!
6299        */
6300        if (attributes != (const xmlChar **) NULL)
6301        {
6302          for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6303          {
6304          keyword=(const char *) attributes[i++];
6305          CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
6306            msl_info->attributes[n],(const char *) attributes[i]));
6307          switch (*keyword)
6308          {
6309            case 'R':
6310            case 'r':
6311            {
6312              if (LocaleCompare(keyword, "radius") == 0)
6313              {
6314                radius = InterpretLocaleValue(value,(char **) NULL);
6315                break;
6316              }
6317              ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6318              break;
6319            }
6320            case 'S':
6321            case 's':
6322            {
6323              if (LocaleCompare(keyword,"sigma") == 0)
6324              {
6325                sigma = StringToLong( value );
6326                break;
6327              }
6328              ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6329              break;
6330            }
6331            default:
6332            {
6333              ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6334              break;
6335            }
6336          }
6337          }
6338        }
6339
6340        /*
6341          sharpen image.
6342        */
6343        {
6344        Image
6345          *newImage;
6346
6347        newImage=SharpenImage(msl_info->image[n],radius,sigma,&msl_info->image[n]->exception);
6348        if (newImage == (Image *) NULL)
6349          break;
6350        msl_info->image[n]=DestroyImage(msl_info->image[n]);
6351        msl_info->image[n]=newImage;
6352        break;
6353        }
6354      }
6355      else if (LocaleCompare((const char *) tag,"shave") == 0)
6356      {
6357        /* init the values */
6358        width = height = 0;
6359        x = y = 0;
6360
6361        if (msl_info->image[n] == (Image *) NULL)
6362        {
6363          ThrowMSLException(OptionError,"NoImagesDefined",
6364            (const char *) tag);
6365          break;
6366        }
6367        if (attributes == (const xmlChar **) NULL)
6368        break;
6369        for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6370        {
6371        keyword=(const char *) attributes[i++];
6372        CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
6373          msl_info->attributes[n],(const char *) attributes[i]));
6374        switch (*keyword)
6375        {
6376          case 'G':
6377          case 'g':
6378          {
6379          if (LocaleCompare(keyword,"geometry") == 0)
6380            {
6381            (void) ParseMetaGeometry(value,&x,&y,&width,&height);
6382            break;
6383            }
6384          ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6385          break;
6386          }
6387          case 'H':
6388          case 'h':
6389          {
6390          if (LocaleCompare(keyword,"height") == 0)
6391            {
6392            height = StringToLong( value );
6393            break;
6394            }
6395          ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6396          break;
6397          }
6398          case 'W':
6399          case 'w':
6400          {
6401          if (LocaleCompare(keyword,"width") == 0)
6402            {
6403            width = StringToLong( value );
6404            break;
6405            }
6406          ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6407          break;
6408          }
6409          default:
6410          {
6411          ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6412          break;
6413          }
6414        }
6415        }
6416
6417        /*
6418          process image.
6419        */
6420        {
6421        Image
6422          *newImage;
6423        RectangleInfo
6424          rectInfo;
6425
6426        rectInfo.height = height;
6427        rectInfo.width = width;
6428        rectInfo.x = x;
6429        rectInfo.y = y;
6430
6431
6432        newImage=ShaveImage(msl_info->image[n], &rectInfo,
6433          &msl_info->image[n]->exception);
6434        if (newImage == (Image *) NULL)
6435          break;
6436        msl_info->image[n]=DestroyImage(msl_info->image[n]);
6437        msl_info->image[n]=newImage;
6438        }
6439
6440        break;
6441      }
6442      if (LocaleCompare((const char *) tag,"shear") == 0)
6443        {
6444          Image
6445            *shear_image;
6446
6447          /*
6448            Shear image.
6449          */
6450          if (msl_info->image[n] == (Image *) NULL)
6451            {
6452              ThrowMSLException(OptionError,"NoImagesDefined",
6453                (const char *) tag);
6454              break;
6455            }
6456          if (attributes != (const xmlChar **) NULL)
6457            for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6458            {
6459              keyword=(const char *) attributes[i++];
6460              attribute=InterpretImageProperties(msl_info->image_info[n],
6461                msl_info->attributes[n],(const char *) attributes[i]);
6462              CloneString(&value,attribute);
6463              switch (*keyword)
6464              {
6465                case 'F':
6466                case 'f':
6467                {
6468                  if (LocaleCompare(keyword, "fill") == 0)
6469                    {
6470                      (void) QueryColorDatabase(value,
6471                        &msl_info->image[n]->background_color,&exception);
6472                      break;
6473                    }
6474                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
6475                    keyword);
6476                  break;
6477                }
6478                case 'G':
6479                case 'g':
6480                {
6481                  if (LocaleCompare(keyword,"geometry") == 0)
6482                    {
6483                      flags=ParseGeometry(value,&geometry_info);
6484                      if ((flags & SigmaValue) == 0)
6485                        geometry_info.sigma=1.0;
6486                      break;
6487                    }
6488                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
6489                    keyword);
6490                  break;
6491                }
6492                case 'X':
6493                case 'x':
6494                {
6495                  if (LocaleCompare(keyword,"x") == 0)
6496                    {
6497                      geometry_info.rho=InterpretLocaleValue(value,
6498                        (char **) NULL);
6499                      break;
6500                    }
6501                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
6502                    keyword);
6503                  break;
6504                }
6505                case 'Y':
6506                case 'y':
6507                {
6508                  if (LocaleCompare(keyword,"y") == 0)
6509                    {
6510                      geometry_info.sigma=StringToLong(value);
6511                      break;
6512                    }
6513                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
6514                    keyword);
6515                  break;
6516                }
6517                default:
6518                {
6519                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
6520                    keyword);
6521                  break;
6522                }
6523              }
6524            }
6525          shear_image=ShearImage(msl_info->image[n],geometry_info.rho,
6526            geometry_info.sigma,&msl_info->image[n]->exception);
6527          if (shear_image == (Image *) NULL)
6528            break;
6529          msl_info->image[n]=DestroyImage(msl_info->image[n]);
6530          msl_info->image[n]=shear_image;
6531          break;
6532        }
6533      if (LocaleCompare((const char *) tag,"signature") == 0)
6534        {
6535          /*
6536            Signature image.
6537          */
6538          if (msl_info->image[n] == (Image *) NULL)
6539            {
6540              ThrowMSLException(OptionError,"NoImagesDefined",
6541                (const char *) tag);
6542              break;
6543            }
6544          if (attributes != (const xmlChar **) NULL)
6545            for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6546            {
6547              keyword=(const char *) attributes[i++];
6548              attribute=InterpretImageProperties(msl_info->image_info[n],
6549                msl_info->attributes[n],(const char *) attributes[i]);
6550              CloneString(&value,attribute);
6551              switch (*keyword)
6552              {
6553                default:
6554                {
6555                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
6556                    keyword);
6557                  break;
6558                }
6559              }
6560            }
6561          (void) SignatureImage(msl_info->image[n]);
6562          break;
6563        }
6564      if (LocaleCompare((const char *) tag,"solarize") == 0)
6565        {
6566          /*
6567            Solarize image.
6568          */
6569          if (msl_info->image[n] == (Image *) NULL)
6570            {
6571              ThrowMSLException(OptionError,"NoImagesDefined",
6572                (const char *) tag);
6573              break;
6574            }
6575          geometry_info.rho=QuantumRange/2.0;
6576          if (attributes != (const xmlChar **) NULL)
6577            for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6578            {
6579              keyword=(const char *) attributes[i++];
6580              attribute=InterpretImageProperties(msl_info->image_info[n],
6581                msl_info->attributes[n],(const char *) attributes[i]);
6582              CloneString(&value,attribute);
6583              switch (*keyword)
6584              {
6585                case 'G':
6586                case 'g':
6587                {
6588                  if (LocaleCompare(keyword,"geometry") == 0)
6589                    {
6590                      flags=ParseGeometry(value,&geometry_info);
6591                      break;
6592                    }
6593                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
6594                    keyword);
6595                  break;
6596                }
6597                case 'T':
6598                case 't':
6599                {
6600                  if (LocaleCompare(keyword,"threshold") == 0)
6601                    {
6602                      geometry_info.rho=InterpretLocaleValue(value,
6603                        (char **) NULL);
6604                      break;
6605                    }
6606                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
6607                    keyword);
6608                  break;
6609                }
6610                default:
6611                {
6612                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
6613                    keyword);
6614                  break;
6615                }
6616              }
6617            }
6618          (void) SolarizeImage(msl_info->image[n],geometry_info.rho);
6619          break;
6620        }
6621      if (LocaleCompare((const char *) tag,"spread") == 0)
6622        {
6623          Image
6624            *spread_image;
6625
6626          /*
6627            Spread image.
6628          */
6629          if (msl_info->image[n] == (Image *) NULL)
6630            {
6631              ThrowMSLException(OptionError,"NoImagesDefined",
6632                (const char *) tag);
6633              break;
6634            }
6635          if (attributes != (const xmlChar **) NULL)
6636            for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6637            {
6638              keyword=(const char *) attributes[i++];
6639              attribute=InterpretImageProperties(msl_info->image_info[n],
6640                msl_info->attributes[n],(const char *) attributes[i]);
6641              CloneString(&value,attribute);
6642              switch (*keyword)
6643              {
6644                case 'G':
6645                case 'g':
6646                {
6647                  if (LocaleCompare(keyword,"geometry") == 0)
6648                    {
6649                      flags=ParseGeometry(value,&geometry_info);
6650                      if ((flags & SigmaValue) == 0)
6651                        geometry_info.sigma=1.0;
6652                      break;
6653                    }
6654                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
6655                    keyword);
6656                  break;
6657                }
6658                case 'R':
6659                case 'r':
6660                {
6661                  if (LocaleCompare(keyword,"radius") == 0)
6662                    {
6663                      geometry_info.rho=InterpretLocaleValue(value,
6664                        (char **) NULL);
6665                      break;
6666                    }
6667                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
6668                    keyword);
6669                  break;
6670                }
6671                default:
6672                {
6673                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
6674                    keyword);
6675                  break;
6676                }
6677              }
6678            }
6679          spread_image=SpreadImage(msl_info->image[n],geometry_info.rho,
6680            &msl_info->image[n]->exception);
6681          if (spread_image == (Image *) NULL)
6682            break;
6683          msl_info->image[n]=DestroyImage(msl_info->image[n]);
6684          msl_info->image[n]=spread_image;
6685          break;
6686        }
6687      else if (LocaleCompare((const char *) tag,"stegano") == 0)
6688      {
6689        Image *
6690          watermark = (Image*)NULL;
6691
6692        if (msl_info->image[n] == (Image *) NULL)
6693          {
6694            ThrowMSLException(OptionError,"NoImagesDefined",
6695              (const char *) tag);
6696            break;
6697          }
6698        if (attributes == (const xmlChar **) NULL)
6699        break;
6700        for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6701        {
6702        keyword=(const char *) attributes[i++];
6703        CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
6704          msl_info->attributes[n],(const char *) attributes[i]));
6705        switch (*keyword)
6706        {
6707          case 'I':
6708          case 'i':
6709          {
6710          if (LocaleCompare(keyword,"image") == 0)
6711            {
6712            for (j=0; j<msl_info->n;j++)
6713            {
6714              const char *
6715                theAttr = GetImageProperty(msl_info->attributes[j], "id");
6716              if (theAttr && LocaleCompare(theAttr, value) == 0)
6717              {
6718                watermark = msl_info->image[j];
6719                break;
6720              }
6721            }
6722            break;
6723            }
6724          ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6725          break;
6726          }
6727          default:
6728          {
6729          ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6730          break;
6731          }
6732        }
6733        }
6734
6735        /*
6736          process image.
6737        */
6738        if ( watermark != (Image*) NULL )
6739        {
6740        Image
6741          *newImage;
6742
6743        newImage=SteganoImage(msl_info->image[n], watermark, &msl_info->image[n]->exception);
6744        if (newImage == (Image *) NULL)
6745          break;
6746        msl_info->image[n]=DestroyImage(msl_info->image[n]);
6747        msl_info->image[n]=newImage;
6748        break;
6749        } else
6750          ThrowMSLException(OptionError,"MissingWatermarkImage",keyword);
6751      }
6752      else if (LocaleCompare((const char *) tag,"stereo") == 0)
6753      {
6754        Image *
6755          stereoImage = (Image*)NULL;
6756
6757        if (msl_info->image[n] == (Image *) NULL)
6758          {
6759            ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
6760            break;
6761          }
6762        if (attributes == (const xmlChar **) NULL)
6763        break;
6764        for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6765        {
6766        keyword=(const char *) attributes[i++];
6767        CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
6768          msl_info->attributes[n],(const char *) attributes[i]));
6769        switch (*keyword)
6770        {
6771          case 'I':
6772          case 'i':
6773          {
6774          if (LocaleCompare(keyword,"image") == 0)
6775            {
6776            for (j=0; j<msl_info->n;j++)
6777            {
6778              const char *
6779                theAttr = GetImageProperty(msl_info->attributes[j], "id");
6780              if (theAttr && LocaleCompare(theAttr, value) == 0)
6781              {
6782                stereoImage = msl_info->image[j];
6783                break;
6784              }
6785            }
6786            break;
6787            }
6788          ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6789          break;
6790          }
6791          default:
6792          {
6793          ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6794          break;
6795          }
6796        }
6797        }
6798
6799        /*
6800          process image.
6801        */
6802        if ( stereoImage != (Image*) NULL )
6803        {
6804        Image
6805          *newImage;
6806
6807        newImage=StereoImage(msl_info->image[n], stereoImage, &msl_info->image[n]->exception);
6808        if (newImage == (Image *) NULL)
6809          break;
6810        msl_info->image[n]=DestroyImage(msl_info->image[n]);
6811        msl_info->image[n]=newImage;
6812        break;
6813        } else
6814          ThrowMSLException(OptionError,"Missing stereo image",keyword);
6815      }
6816      if (LocaleCompare((const char *) tag,"swap") == 0)
6817        {
6818          Image
6819            *p,
6820            *q,
6821            *swap;
6822
6823          ssize_t
6824            index,
6825            swap_index;
6826
6827          if (msl_info->image[n] == (Image *) NULL)
6828            {
6829              ThrowMSLException(OptionError,"NoImagesDefined",
6830                (const char *) tag);
6831              break;
6832            }
6833          index=(-1);
6834          swap_index=(-2);
6835          if (attributes != (const xmlChar **) NULL)
6836            for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6837            {
6838              keyword=(const char *) attributes[i++];
6839              attribute=InterpretImageProperties(msl_info->image_info[n],
6840                msl_info->attributes[n],(const char *) attributes[i]);
6841              CloneString(&value,attribute);
6842              switch (*keyword)
6843              {
6844                case 'G':
6845                case 'g':
6846                {
6847                  if (LocaleCompare(keyword,"indexes") == 0)
6848                    {
6849                      flags=ParseGeometry(value,&geometry_info);
6850                      index=(ssize_t) geometry_info.rho;
6851                      if ((flags & SigmaValue) == 0)
6852                        swap_index=(ssize_t) geometry_info.sigma;
6853                      break;
6854                    }
6855                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
6856                    keyword);
6857                  break;
6858                }
6859                default:
6860                {
6861                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
6862                    keyword);
6863                  break;
6864                }
6865              }
6866            }
6867          /*
6868            Swap images.
6869          */
6870          p=GetImageFromList(msl_info->image[n],index);
6871          q=GetImageFromList(msl_info->image[n],swap_index);
6872          if ((p == (Image *) NULL) || (q == (Image *) NULL))
6873            {
6874              ThrowMSLException(OptionError,"NoSuchImage",(const char *) tag);
6875              break;
6876            }
6877          swap=CloneImage(p,0,0,MagickTrue,&p->exception);
6878          ReplaceImageInList(&p,CloneImage(q,0,0,MagickTrue,&q->exception));
6879          ReplaceImageInList(&q,swap);
6880          msl_info->image[n]=GetFirstImageInList(q);
6881          break;
6882        }
6883      if (LocaleCompare((const char *) tag,"swirl") == 0)
6884        {
6885          Image
6886            *swirl_image;
6887
6888          /*
6889            Swirl image.
6890          */
6891          if (msl_info->image[n] == (Image *) NULL)
6892            {
6893              ThrowMSLException(OptionError,"NoImagesDefined",
6894                (const char *) tag);
6895              break;
6896            }
6897          if (attributes != (const xmlChar **) NULL)
6898            for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6899            {
6900              keyword=(const char *) attributes[i++];
6901              attribute=InterpretImageProperties(msl_info->image_info[n],
6902                msl_info->attributes[n],(const char *) attributes[i]);
6903              CloneString(&value,attribute);
6904              switch (*keyword)
6905              {
6906                case 'D':
6907                case 'd':
6908                {
6909                  if (LocaleCompare(keyword,"degrees") == 0)
6910                    {
6911                      geometry_info.rho=InterpretLocaleValue(value,
6912                        (char **) NULL);
6913                      break;
6914                    }
6915                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
6916                    keyword);
6917                  break;
6918                }
6919                case 'G':
6920                case 'g':
6921                {
6922                  if (LocaleCompare(keyword,"geometry") == 0)
6923                    {
6924                      flags=ParseGeometry(value,&geometry_info);
6925                      if ((flags & SigmaValue) == 0)
6926                        geometry_info.sigma=1.0;
6927                      break;
6928                    }
6929                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
6930                    keyword);
6931                  break;
6932                }
6933                default:
6934                {
6935                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
6936                    keyword);
6937                  break;
6938                }
6939              }
6940            }
6941          swirl_image=SwirlImage(msl_info->image[n],geometry_info.rho,
6942            &msl_info->image[n]->exception);
6943          if (swirl_image == (Image *) NULL)
6944            break;
6945          msl_info->image[n]=DestroyImage(msl_info->image[n]);
6946          msl_info->image[n]=swirl_image;
6947          break;
6948        }
6949      if (LocaleCompare((const char *) tag,"sync") == 0)
6950        {
6951          /*
6952            Sync image.
6953          */
6954          if (msl_info->image[n] == (Image *) NULL)
6955            {
6956              ThrowMSLException(OptionError,"NoImagesDefined",
6957                (const char *) tag);
6958              break;
6959            }
6960          if (attributes != (const xmlChar **) NULL)
6961            for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6962            {
6963              keyword=(const char *) attributes[i++];
6964              attribute=InterpretImageProperties(msl_info->image_info[n],
6965                msl_info->attributes[n],(const char *) attributes[i]);
6966              CloneString(&value,attribute);
6967              switch (*keyword)
6968              {
6969                default:
6970                {
6971                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
6972                    keyword);
6973                  break;
6974                }
6975              }
6976            }
6977          (void) SyncImage(msl_info->image[n]);
6978          break;
6979        }
6980      ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
6981    }
6982    case 'T':
6983    case 't':
6984    {
6985      if (LocaleCompare((const char *) tag,"map") == 0)
6986        {
6987          Image
6988            *texture_image;
6989
6990          /*
6991            Texture image.
6992          */
6993          if (msl_info->image[n] == (Image *) NULL)
6994            {
6995              ThrowMSLException(OptionError,"NoImagesDefined",
6996                (const char *) tag);
6997              break;
6998            }
6999          texture_image=NewImageList();
7000          if (attributes != (const xmlChar **) NULL)
7001            for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7002            {
7003              keyword=(const char *) attributes[i++];
7004              attribute=InterpretImageProperties(msl_info->image_info[n],
7005                msl_info->attributes[n],(const char *) attributes[i]);
7006              CloneString(&value,attribute);
7007              switch (*keyword)
7008              {
7009                case 'I':
7010                case 'i':
7011                {
7012                  if (LocaleCompare(keyword,"image") == 0)
7013                    for (j=0; j < msl_info->n; j++)
7014                    {
7015                      const char
7016                        *attribute;
7017
7018                      attribute=GetImageProperty(msl_info->attributes[j],"id");
7019                      if ((attribute != (const char *) NULL)  &&
7020                          (LocaleCompare(attribute,value) == 0))
7021                        {
7022                          texture_image=CloneImage(msl_info->image[j],0,0,
7023                            MagickFalse,&exception);
7024                          break;
7025                        }
7026                    }
7027                  break;
7028                }
7029                default:
7030                {
7031                  ThrowMSLException(OptionError,"UnrecognizedAttribute",
7032                    keyword);
7033                  break;
7034                }
7035              }
7036            }
7037          (void) TextureImage(msl_info->image[n],texture_image);
7038          texture_image=DestroyImage(texture_image);
7039          break;
7040        }
7041      else if (LocaleCompare((const char *) tag,"threshold") == 0)
7042      {
7043        /* init the values */
7044        double  threshold = 0;
7045
7046        if (msl_info->image[n] == (Image *) NULL)
7047          {
7048            ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7049            break;
7050          }
7051        if (attributes == (const xmlChar **) NULL)
7052        break;
7053        for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7054        {
7055        keyword=(const char *) attributes[i++];
7056        CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
7057          msl_info->attributes[n],(const char *) attributes[i]));
7058        switch (*keyword)
7059        {
7060          case 'T':
7061          case 't':
7062          {
7063          if (LocaleCompare(keyword,"threshold") == 0)
7064            {
7065            threshold = InterpretLocaleValue(value,(char **) NULL);
7066            break;
7067            }
7068          ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7069          break;
7070          }
7071          default:
7072          {
7073          ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7074          break;
7075          }
7076        }
7077        }
7078
7079        /*
7080          process image.
7081        */
7082        {
7083          BilevelImage(msl_info->image[n],threshold);
7084        break;
7085        }
7086      }
7087      else if (LocaleCompare((const char *) tag, "transparent") == 0)
7088      {
7089        if (msl_info->image[n] == (Image *) NULL)
7090          {
7091            ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7092            break;
7093          }
7094        if (attributes == (const xmlChar **) NULL)
7095          break;
7096        for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7097        {
7098          keyword=(const char *) attributes[i++];
7099          CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
7100            msl_info->attributes[n],(const char *) attributes[i]));
7101          switch (*keyword)
7102          {
7103            case 'C':
7104            case 'c':
7105            {
7106              if (LocaleCompare(keyword,"color") == 0)
7107              {
7108                PixelInfo
7109                  target;
7110
7111                (void) QueryMagickColor(value,&target,&exception);
7112                (void) TransparentPaintImage(msl_info->image[n],&target,
7113                  TransparentAlpha,MagickFalse);
7114                break;
7115              }
7116              ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7117              break;
7118            }
7119            default:
7120            {
7121              ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7122            break;
7123            }
7124          }
7125        }
7126        break;
7127      }
7128      else if (LocaleCompare((const char *) tag, "trim") == 0)
7129      {
7130        if (msl_info->image[n] == (Image *) NULL)
7131          {
7132            ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7133            break;
7134          }
7135
7136        /* no attributes here */
7137
7138        /* process the image */
7139        {
7140          Image
7141            *newImage;
7142          RectangleInfo
7143            rectInfo;
7144
7145          /* all zeros on a crop == trim edges! */
7146          rectInfo.height = rectInfo.width = 0;
7147          rectInfo.x =  rectInfo.y = 0;
7148
7149          newImage=CropImage(msl_info->image[n],&rectInfo, &msl_info->image[n]->exception);
7150          if (newImage == (Image *) NULL)
7151            break;
7152          msl_info->image[n]=DestroyImage(msl_info->image[n]);
7153          msl_info->image[n]=newImage;
7154          break;
7155        }
7156      }
7157      ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7158    }
7159    case 'W':
7160    case 'w':
7161    {
7162      if (LocaleCompare((const char *) tag,"write") == 0)
7163        {
7164          if (msl_info->image[n] == (Image *) NULL)
7165            {
7166              ThrowMSLException(OptionError,"NoImagesDefined",
7167                (const char *) tag);
7168              break;
7169            }
7170          if (attributes == (const xmlChar **) NULL)
7171            break;
7172          for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7173          {
7174            keyword=(const char *) attributes[i++];
7175            CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
7176              msl_info->attributes[n],(const char *) attributes[i]));
7177            switch (*keyword)
7178            {
7179              case 'F':
7180              case 'f':
7181              {
7182                if (LocaleCompare(keyword,"filename") == 0)
7183                  {
7184                    (void) CopyMagickString(msl_info->image[n]->filename,value,
7185                      MaxTextExtent);
7186                    break;
7187                  }
7188                (void) SetMSLAttributes(msl_info,keyword,value);
7189              }
7190              default:
7191              {
7192                (void) SetMSLAttributes(msl_info,keyword,value);
7193                break;
7194              }
7195            }
7196          }
7197
7198          /* process */
7199          {
7200            (void) WriteImage(msl_info->image_info[n], msl_info->image[n]);
7201            break;
7202          }
7203        }
7204      ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7205    }
7206    default:
7207    {
7208      ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7209      break;
7210    }
7211  }
7212  if ( value != NULL )
7213    value=DestroyString(value);
7214  (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  )");
7215}
7216
7217static void MSLEndElement(void *context,const xmlChar *tag)
7218{
7219  ssize_t
7220    n;
7221
7222  MSLInfo
7223    *msl_info;
7224
7225  /*
7226    Called when the end of an element has been detected.
7227  */
7228  (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  SAX.endElement(%s)",
7229    tag);
7230  msl_info=(MSLInfo *) context;
7231  n=msl_info->n;
7232  switch (*tag)
7233  {
7234    case 'C':
7235    case 'c':
7236    {
7237      if (LocaleCompare((const char *) tag,"comment") == 0 )
7238        {
7239          (void) DeleteImageProperty(msl_info->image[n],"comment");
7240          if (msl_info->content == (char *) NULL)
7241            break;
7242          StripString(msl_info->content);
7243          (void) SetImageProperty(msl_info->image[n],"comment",
7244            msl_info->content);
7245          break;
7246        }
7247      break;
7248    }
7249    case 'G':
7250    case 'g':
7251    {
7252      if (LocaleCompare((const char *) tag, "group") == 0 )
7253      {
7254        if (msl_info->group_info[msl_info->number_groups-1].numImages > 0 )
7255        {
7256          ssize_t  i = (ssize_t)
7257            (msl_info->group_info[msl_info->number_groups-1].numImages);
7258          while ( i-- )
7259          {
7260            if (msl_info->image[msl_info->n] != (Image *) NULL)
7261              msl_info->image[msl_info->n]=DestroyImage(msl_info->image[msl_info->n]);
7262            msl_info->attributes[msl_info->n]=DestroyImage(msl_info->attributes[msl_info->n]);
7263            msl_info->image_info[msl_info->n]=DestroyImageInfo(msl_info->image_info[msl_info->n]);
7264            msl_info->n--;
7265          }
7266        }
7267        msl_info->number_groups--;
7268      }
7269      break;
7270    }
7271    case 'I':
7272    case 'i':
7273    {
7274      if (LocaleCompare((const char *) tag, "image") == 0)
7275        MSLPopImage(msl_info);
7276       break;
7277    }
7278    case 'L':
7279    case 'l':
7280    {
7281      if (LocaleCompare((const char *) tag,"label") == 0 )
7282        {
7283          (void) DeleteImageProperty(msl_info->image[n],"label");
7284          if (msl_info->content == (char *) NULL)
7285            break;
7286          StripString(msl_info->content);
7287          (void) SetImageProperty(msl_info->image[n],"label",
7288            msl_info->content);
7289          break;
7290        }
7291      break;
7292    }
7293    case 'M':
7294    case 'm':
7295    {
7296      if (LocaleCompare((const char *) tag, "msl") == 0 )
7297      {
7298        /*
7299          This our base element.
7300            at the moment we don't do anything special
7301            but someday we might!
7302        */
7303      }
7304      break;
7305    }
7306    default:
7307      break;
7308  }
7309  if (msl_info->content != (char *) NULL)
7310    msl_info->content=DestroyString(msl_info->content);
7311}
7312
7313static void MSLCharacters(void *context,const xmlChar *c,int length)
7314{
7315  MSLInfo
7316    *msl_info;
7317
7318  register char
7319    *p;
7320
7321  register ssize_t
7322    i;
7323
7324  /*
7325    Receiving some characters from the parser.
7326  */
7327  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7328    "  SAX.characters(%s,%d)",c,length);
7329  msl_info=(MSLInfo *) context;
7330  if (msl_info->content != (char *) NULL)
7331    msl_info->content=(char *) ResizeQuantumMemory(msl_info->content,
7332      strlen(msl_info->content)+length+MaxTextExtent,
7333      sizeof(*msl_info->content));
7334  else
7335    {
7336      msl_info->content=(char *) NULL;
7337      if (~length >= (MaxTextExtent-1))
7338        msl_info->content=(char *) AcquireQuantumMemory(length+MaxTextExtent,
7339          sizeof(*msl_info->content));
7340      if (msl_info->content != (char *) NULL)
7341        *msl_info->content='\0';
7342    }
7343  if (msl_info->content == (char *) NULL)
7344    return;
7345  p=msl_info->content+strlen(msl_info->content);
7346  for (i=0; i < length; i++)
7347    *p++=c[i];
7348  *p='\0';
7349}
7350
7351static void MSLReference(void *context,const xmlChar *name)
7352{
7353  MSLInfo
7354    *msl_info;
7355
7356  xmlParserCtxtPtr
7357    parser;
7358
7359  /*
7360    Called when an entity reference is detected.
7361  */
7362  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7363    "  SAX.reference(%s)",name);
7364  msl_info=(MSLInfo *) context;
7365  parser=msl_info->parser;
7366  if (*name == '#')
7367    (void) xmlAddChild(parser->node,xmlNewCharRef(msl_info->document,name));
7368  else
7369    (void) xmlAddChild(parser->node,xmlNewReference(msl_info->document,name));
7370}
7371
7372static void MSLIgnorableWhitespace(void *context,const xmlChar *c,int length)
7373{
7374  MSLInfo
7375    *msl_info;
7376
7377  /*
7378    Receiving some ignorable whitespaces from the parser.
7379  */
7380  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7381    "  SAX.ignorableWhitespace(%.30s, %d)",c,length);
7382  msl_info=(MSLInfo *) context;
7383  (void) msl_info;
7384}
7385
7386static void MSLProcessingInstructions(void *context,const xmlChar *target,
7387  const xmlChar *data)
7388{
7389  MSLInfo
7390    *msl_info;
7391
7392  /*
7393    A processing instruction has been parsed.
7394  */
7395  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7396    "  SAX.processingInstruction(%s, %s)",
7397    target,data);
7398  msl_info=(MSLInfo *) context;
7399  (void) msl_info;
7400}
7401
7402static void MSLComment(void *context,const xmlChar *value)
7403{
7404  MSLInfo
7405    *msl_info;
7406
7407  /*
7408    A comment has been parsed.
7409  */
7410  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7411    "  SAX.comment(%s)",value);
7412  msl_info=(MSLInfo *) context;
7413  (void) msl_info;
7414}
7415
7416static void MSLWarning(void *context,const char *format,...)
7417{
7418  char
7419    *message,
7420    reason[MaxTextExtent];
7421
7422  MSLInfo
7423    *msl_info;
7424
7425  va_list
7426    operands;
7427
7428  /**
7429    Display and format a warning messages, gives file, line, position and
7430    extra parameters.
7431  */
7432  va_start(operands,format);
7433  (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  SAX.warning: ");
7434  (void) LogMagickEvent(CoderEvent,GetMagickModule(),format,operands);
7435  msl_info=(MSLInfo *) context;
7436  (void) msl_info;
7437#if !defined(MAGICKCORE_HAVE_VSNPRINTF)
7438  (void) vsprintf(reason,format,operands);
7439#else
7440  (void) vsnprintf(reason,MaxTextExtent,format,operands);
7441#endif
7442  message=GetExceptionMessage(errno);
7443  ThrowMSLException(CoderError,reason,message);
7444  message=DestroyString(message);
7445  va_end(operands);
7446}
7447
7448static void MSLError(void *context,const char *format,...)
7449{
7450  char
7451    reason[MaxTextExtent];
7452
7453  MSLInfo
7454    *msl_info;
7455
7456  va_list
7457    operands;
7458
7459  /*
7460    Display and format a error formats, gives file, line, position and
7461    extra parameters.
7462  */
7463  va_start(operands,format);
7464  (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  SAX.error: ");
7465  (void) LogMagickEvent(CoderEvent,GetMagickModule(),format,operands);
7466  msl_info=(MSLInfo *) context;
7467  (void) msl_info;
7468#if !defined(MAGICKCORE_HAVE_VSNPRINTF)
7469  (void) vsprintf(reason,format,operands);
7470#else
7471  (void) vsnprintf(reason,MaxTextExtent,format,operands);
7472#endif
7473  ThrowMSLException(DelegateFatalError,reason,"SAX error");
7474  va_end(operands);
7475}
7476
7477static void MSLCDataBlock(void *context,const xmlChar *value,int length)
7478{
7479  MSLInfo
7480    *msl_info;
7481
7482   xmlNodePtr
7483     child;
7484
7485  xmlParserCtxtPtr
7486    parser;
7487
7488  /*
7489    Called when a pcdata block has been parsed.
7490  */
7491  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7492    "  SAX.pcdata(%s, %d)",value,length);
7493  msl_info=(MSLInfo *) context;
7494  (void) msl_info;
7495  parser=msl_info->parser;
7496  child=xmlGetLastChild(parser->node);
7497  if ((child != (xmlNodePtr) NULL) && (child->type == XML_CDATA_SECTION_NODE))
7498    {
7499      xmlTextConcat(child,value,length);
7500      return;
7501    }
7502  (void) xmlAddChild(parser->node,xmlNewCDataBlock(parser->myDoc,value,length));
7503}
7504
7505static void MSLExternalSubset(void *context,const xmlChar *name,
7506  const xmlChar *external_id,const xmlChar *system_id)
7507{
7508  MSLInfo
7509    *msl_info;
7510
7511  xmlParserCtxt
7512    parser_context;
7513
7514  xmlParserCtxtPtr
7515    parser;
7516
7517  xmlParserInputPtr
7518    input;
7519
7520  /*
7521    Does this document has an external subset?
7522  */
7523  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7524    "  SAX.externalSubset(%s %s %s)",name,
7525    (external_id != (const xmlChar *) NULL ? (const char *) external_id : " "),
7526    (system_id != (const xmlChar *) NULL ? (const char *) system_id : " "));
7527  msl_info=(MSLInfo *) context;
7528  (void) msl_info;
7529  parser=msl_info->parser;
7530  if (((external_id == NULL) && (system_id == NULL)) ||
7531      ((parser->validate == 0) || (parser->wellFormed == 0) ||
7532      (msl_info->document == 0)))
7533    return;
7534  input=MSLResolveEntity(context,external_id,system_id);
7535  if (input == NULL)
7536    return;
7537  (void) xmlNewDtd(msl_info->document,name,external_id,system_id);
7538  parser_context=(*parser);
7539  parser->inputTab=(xmlParserInputPtr *) xmlMalloc(5*sizeof(*parser->inputTab));
7540  if (parser->inputTab == (xmlParserInputPtr *) NULL)
7541    {
7542      parser->errNo=XML_ERR_NO_MEMORY;
7543      parser->input=parser_context.input;
7544      parser->inputNr=parser_context.inputNr;
7545      parser->inputMax=parser_context.inputMax;
7546      parser->inputTab=parser_context.inputTab;
7547      return;
7548  }
7549  parser->inputNr=0;
7550  parser->inputMax=5;
7551  parser->input=NULL;
7552  xmlPushInput(parser,input);
7553  (void) xmlSwitchEncoding(parser,xmlDetectCharEncoding(parser->input->cur,4));
7554  if (input->filename == (char *) NULL)
7555    input->filename=(char *) xmlStrdup(system_id);
7556  input->line=1;
7557  input->col=1;
7558  input->base=parser->input->cur;
7559  input->cur=parser->input->cur;
7560  input->free=NULL;
7561  xmlParseExternalSubset(parser,external_id,system_id);
7562  while (parser->inputNr > 1)
7563    (void) xmlPopInput(parser);
7564  xmlFreeInputStream(parser->input);
7565  xmlFree(parser->inputTab);
7566  parser->input=parser_context.input;
7567  parser->inputNr=parser_context.inputNr;
7568  parser->inputMax=parser_context.inputMax;
7569  parser->inputTab=parser_context.inputTab;
7570}
7571
7572#if defined(__cplusplus) || defined(c_plusplus)
7573}
7574#endif
7575
7576static MagickBooleanType ProcessMSLScript(const ImageInfo *image_info,Image **image,
7577  ExceptionInfo *exception)
7578{
7579  char
7580    message[MaxTextExtent];
7581
7582  Image
7583    *msl_image;
7584
7585  int
7586    status;
7587
7588  ssize_t
7589    n;
7590
7591  MSLInfo
7592    msl_info;
7593
7594  xmlSAXHandler
7595    sax_modules;
7596
7597  xmlSAXHandlerPtr
7598    sax_handler;
7599
7600  /*
7601    Open image file.
7602  */
7603  assert(image_info != (const ImageInfo *) NULL);
7604  assert(image_info->signature == MagickSignature);
7605  if (image_info->debug != MagickFalse)
7606    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
7607      image_info->filename);
7608  assert(image != (Image **) NULL);
7609  msl_image=AcquireImage(image_info);
7610  status=OpenBlob(image_info,msl_image,ReadBinaryBlobMode,exception);
7611  if (status == MagickFalse)
7612    {
7613      ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
7614        msl_image->filename);
7615      msl_image=DestroyImageList(msl_image);
7616      return(MagickFalse);
7617    }
7618  msl_image->columns=1;
7619  msl_image->rows=1;
7620  /*
7621    Parse MSL file.
7622  */
7623  (void) ResetMagickMemory(&msl_info,0,sizeof(msl_info));
7624  msl_info.exception=exception;
7625  msl_info.image_info=(ImageInfo **) AcquireMagickMemory(
7626    sizeof(*msl_info.image_info));
7627  msl_info.draw_info=(DrawInfo **) AcquireMagickMemory(
7628    sizeof(*msl_info.draw_info));
7629  /* top of the stack is the MSL file itself */
7630  msl_info.image=(Image **) AcquireMagickMemory(sizeof(*msl_info.image));
7631  msl_info.attributes=(Image **) AcquireMagickMemory(
7632    sizeof(*msl_info.attributes));
7633  msl_info.group_info=(MSLGroupInfo *) AcquireMagickMemory(
7634    sizeof(*msl_info.group_info));
7635  if ((msl_info.image_info == (ImageInfo **) NULL) ||
7636      (msl_info.image == (Image **) NULL) ||
7637      (msl_info.attributes == (Image **) NULL) ||
7638      (msl_info.group_info == (MSLGroupInfo *) NULL))
7639    ThrowFatalException(ResourceLimitFatalError,
7640      "UnableToInterpretMSLImage");
7641  *msl_info.image_info=CloneImageInfo(image_info);
7642  *msl_info.draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL);
7643  *msl_info.attributes=AcquireImage(image_info);
7644  msl_info.group_info[0].numImages=0;
7645  /* the first slot is used to point to the MSL file image */
7646  *msl_info.image=msl_image;
7647  if (*image != (Image *) NULL)
7648    MSLPushImage(&msl_info,*image);
7649  (void) xmlSubstituteEntitiesDefault(1);
7650  (void) ResetMagickMemory(&sax_modules,0,sizeof(sax_modules));
7651  sax_modules.internalSubset=MSLInternalSubset;
7652  sax_modules.isStandalone=MSLIsStandalone;
7653  sax_modules.hasInternalSubset=MSLHasInternalSubset;
7654  sax_modules.hasExternalSubset=MSLHasExternalSubset;
7655  sax_modules.resolveEntity=MSLResolveEntity;
7656  sax_modules.getEntity=MSLGetEntity;
7657  sax_modules.entityDecl=MSLEntityDeclaration;
7658  sax_modules.notationDecl=MSLNotationDeclaration;
7659  sax_modules.attributeDecl=MSLAttributeDeclaration;
7660  sax_modules.elementDecl=MSLElementDeclaration;
7661  sax_modules.unparsedEntityDecl=MSLUnparsedEntityDeclaration;
7662  sax_modules.setDocumentLocator=MSLSetDocumentLocator;
7663  sax_modules.startDocument=MSLStartDocument;
7664  sax_modules.endDocument=MSLEndDocument;
7665  sax_modules.startElement=MSLStartElement;
7666  sax_modules.endElement=MSLEndElement;
7667  sax_modules.reference=MSLReference;
7668  sax_modules.characters=MSLCharacters;
7669  sax_modules.ignorableWhitespace=MSLIgnorableWhitespace;
7670  sax_modules.processingInstruction=MSLProcessingInstructions;
7671  sax_modules.comment=MSLComment;
7672  sax_modules.warning=MSLWarning;
7673  sax_modules.error=MSLError;
7674  sax_modules.fatalError=MSLError;
7675  sax_modules.getParameterEntity=MSLGetParameterEntity;
7676  sax_modules.cdataBlock=MSLCDataBlock;
7677  sax_modules.externalSubset=MSLExternalSubset;
7678  sax_handler=(&sax_modules);
7679  msl_info.parser=xmlCreatePushParserCtxt(sax_handler,&msl_info,(char *) NULL,0,
7680    msl_image->filename);
7681  while (ReadBlobString(msl_image,message) != (char *) NULL)
7682  {
7683    n=(ssize_t) strlen(message);
7684    if (n == 0)
7685      continue;
7686    status=xmlParseChunk(msl_info.parser,message,(int) n,MagickFalse);
7687    if (status != 0)
7688      break;
7689    (void) xmlParseChunk(msl_info.parser," ",1,MagickFalse);
7690    if (msl_info.exception->severity >= ErrorException)
7691      break;
7692  }
7693  if (msl_info.exception->severity == UndefinedException)
7694    (void) xmlParseChunk(msl_info.parser," ",1,MagickTrue);
7695  xmlFreeParserCtxt(msl_info.parser);
7696  (void) LogMagickEvent(CoderEvent,GetMagickModule(),"end SAX");
7697  xmlCleanupParser();
7698  msl_info.group_info=(MSLGroupInfo *) RelinquishMagickMemory(
7699    msl_info.group_info);
7700  if (*image == (Image *) NULL)
7701    *image=(*msl_info.image);
7702  if ((*msl_info.image)->exception.severity != UndefinedException)
7703    return(MagickFalse);
7704  return(MagickTrue);
7705}
7706
7707static Image *ReadMSLImage(const ImageInfo *image_info,ExceptionInfo *exception)
7708{
7709  Image
7710    *image;
7711
7712  /*
7713    Open image file.
7714  */
7715  assert(image_info != (const ImageInfo *) NULL);
7716  assert(image_info->signature == MagickSignature);
7717  if (image_info->debug != MagickFalse)
7718    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
7719      image_info->filename);
7720  assert(exception != (ExceptionInfo *) NULL);
7721  assert(exception->signature == MagickSignature);
7722  image=(Image *) NULL;
7723  (void) ProcessMSLScript(image_info,&image,exception);
7724  return(GetFirstImageInList(image));
7725}
7726#endif
7727
7728/*
7729%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7730%                                                                             %
7731%                                                                             %
7732%                                                                             %
7733%   R e g i s t e r M S L I m a g e                                           %
7734%                                                                             %
7735%                                                                             %
7736%                                                                             %
7737%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7738%
7739%  RegisterMSLImage() adds attributes for the MSL image format to
7740%  the list of supported formats.  The attributes include the image format
7741%  tag, a method to read and/or write the format, whether the format
7742%  supports the saving of more than one frame to the same file or blob,
7743%  whether the format supports native in-memory I/O, and a brief
7744%  description of the format.
7745%
7746%  The format of the RegisterMSLImage method is:
7747%
7748%      size_t RegisterMSLImage(void)
7749%
7750*/
7751ModuleExport size_t RegisterMSLImage(void)
7752{
7753  MagickInfo
7754    *entry;
7755
7756  entry=SetMagickInfo("MSL");
7757#if defined(MAGICKCORE_XML_DELEGATE)
7758  entry->decoder=(DecodeImageHandler *) ReadMSLImage;
7759  entry->encoder=(EncodeImageHandler *) WriteMSLImage;
7760#endif
7761  entry->description=ConstantString("Magick Scripting Language");
7762  entry->module=ConstantString("MSL");
7763  (void) RegisterMagickInfo(entry);
7764  return(MagickImageCoderSignature);
7765}
7766
7767#if defined(MAGICKCORE_XML_DELEGATE)
7768/*
7769%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7770%                                                                             %
7771%                                                                             %
7772%                                                                             %
7773%   S e t M S L A t t r i b u t e s                                           %
7774%                                                                             %
7775%                                                                             %
7776%                                                                             %
7777%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7778%
7779%  SetMSLAttributes() ...
7780%
7781%  The format of the SetMSLAttributes method is:
7782%
7783%      MagickBooleanType SetMSLAttributes(MSLInfo *msl_info,
7784%        const char *keyword,const char *value)
7785%
7786%  A description of each parameter follows:
7787%
7788%    o msl_info: the MSL info.
7789%
7790%    o keyword: the keyword.
7791%
7792%    o value: the value.
7793%
7794*/
7795static MagickBooleanType SetMSLAttributes(MSLInfo *msl_info,const char *keyword,
7796  const char *value)
7797{
7798  Image
7799    *attributes;
7800
7801  DrawInfo
7802    *draw_info;
7803
7804  ExceptionInfo
7805    *exception;
7806
7807  GeometryInfo
7808    geometry_info;
7809
7810  Image
7811    *image;
7812
7813  ImageInfo
7814    *image_info;
7815
7816  int
7817    flags;
7818
7819  ssize_t
7820    n;
7821
7822  assert(msl_info != (MSLInfo *) NULL);
7823  if (keyword == (const char *) NULL)
7824    return(MagickTrue);
7825  if (value == (const char *) NULL)
7826    return(MagickTrue);
7827  exception=msl_info->exception;
7828  n=msl_info->n;
7829  attributes=msl_info->attributes[n];
7830  image_info=msl_info->image_info[n];
7831  draw_info=msl_info->draw_info[n];
7832  image=msl_info->image[n];
7833  switch (*keyword)
7834  {
7835    case 'A':
7836    case 'a':
7837    {
7838      if (LocaleCompare(keyword,"adjoin") == 0)
7839        {
7840          ssize_t
7841            adjoin;
7842
7843          adjoin=ParseCommandOption(MagickBooleanOptions,MagickFalse,value);
7844          if (adjoin < 0)
7845            ThrowMSLException(OptionError,"UnrecognizedType",value);
7846          image_info->adjoin=(MagickBooleanType) adjoin;
7847          break;
7848        }
7849      if (LocaleCompare(keyword,"alpha") == 0)
7850        {
7851          ssize_t
7852            alpha;
7853
7854          alpha=ParseCommandOption(MagickAlphaOptions,MagickFalse,value);
7855          if (alpha < 0)
7856            ThrowMSLException(OptionError,"UnrecognizedType",value);
7857          if (image != (Image *) NULL)
7858            (void) SetImageAlphaChannel(image,(AlphaChannelType) alpha,
7859              exception);
7860          break;
7861        }
7862      if (LocaleCompare(keyword,"antialias") == 0)
7863        {
7864          ssize_t
7865            antialias;
7866
7867          antialias=ParseCommandOption(MagickBooleanOptions,MagickFalse,value);
7868          if (antialias < 0)
7869            ThrowMSLException(OptionError,"UnrecognizedGravityType",value);
7870          image_info->antialias=(MagickBooleanType) antialias;
7871          break;
7872        }
7873      if (LocaleCompare(keyword,"area-limit") == 0)
7874        {
7875          MagickSizeType
7876            limit;
7877
7878          limit=MagickResourceInfinity;
7879          if (LocaleCompare(value,"unlimited") != 0)
7880            limit=(MagickSizeType) SiPrefixToDouble(value,100.0);
7881          (void) SetMagickResourceLimit(AreaResource,limit);
7882          break;
7883        }
7884      if (LocaleCompare(keyword,"attenuate") == 0)
7885        {
7886          (void) SetImageOption(image_info,keyword,value);
7887          break;
7888        }
7889      if (LocaleCompare(keyword,"authenticate") == 0)
7890        {
7891          (void) CloneString(&image_info->density,value);
7892          break;
7893        }
7894      ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7895      break;
7896    }
7897    case 'B':
7898    case 'b':
7899    {
7900      if (LocaleCompare(keyword,"background") == 0)
7901        {
7902          (void) QueryColorDatabase(value,&image_info->background_color,
7903            exception);
7904          break;
7905        }
7906      if (LocaleCompare(keyword,"bias") == 0)
7907        {
7908          if (image == (Image *) NULL)
7909            break;
7910          image->bias=SiPrefixToDouble(value,QuantumRange);
7911          break;
7912        }
7913      if (LocaleCompare(keyword,"blue-primary") == 0)
7914        {
7915          if (image == (Image *) NULL)
7916            break;
7917          flags=ParseGeometry(value,&geometry_info);
7918          image->chromaticity.blue_primary.x=geometry_info.rho;
7919          image->chromaticity.blue_primary.y=geometry_info.sigma;
7920          if ((flags & SigmaValue) == 0)
7921            image->chromaticity.blue_primary.y=
7922              image->chromaticity.blue_primary.x;
7923          break;
7924        }
7925      if (LocaleCompare(keyword,"bordercolor") == 0)
7926        {
7927          (void) QueryColorDatabase(value,&image_info->border_color,
7928            exception);
7929          break;
7930        }
7931      ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7932      break;
7933    }
7934    case 'D':
7935    case 'd':
7936    {
7937      if (LocaleCompare(keyword,"density") == 0)
7938        {
7939          (void) CloneString(&image_info->density,value);
7940          (void) CloneString(&draw_info->density,value);
7941          break;
7942        }
7943      ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7944      break;
7945    }
7946    case 'F':
7947    case 'f':
7948    {
7949      if (LocaleCompare(keyword,"fill") == 0)
7950        {
7951          (void) QueryColorDatabase(value,&draw_info->fill,exception);
7952          (void) SetImageOption(image_info,keyword,value);
7953          break;
7954        }
7955      if (LocaleCompare(keyword,"filename") == 0)
7956        {
7957          (void) CopyMagickString(image_info->filename,value,MaxTextExtent);
7958          break;
7959        }
7960      ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7961      break;
7962    }
7963    case 'G':
7964    case 'g':
7965    {
7966      if (LocaleCompare(keyword,"gravity") == 0)
7967        {
7968          ssize_t
7969            gravity;
7970
7971          gravity=ParseCommandOption(MagickGravityOptions,MagickFalse,value);
7972          if (gravity < 0)
7973            ThrowMSLException(OptionError,"UnrecognizedGravityType",value);
7974          (void) SetImageOption(image_info,keyword,value);
7975          break;
7976        }
7977      ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7978      break;
7979    }
7980    case 'I':
7981    case 'i':
7982    {
7983      if (LocaleCompare(keyword,"id") == 0)
7984        {
7985          (void) SetImageProperty(attributes,keyword,value);
7986          break;
7987        }
7988      ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7989      break;
7990    }
7991    case 'M':
7992    case 'm':
7993    {
7994      if (LocaleCompare(keyword,"magick") == 0)
7995        {
7996          (void) CopyMagickString(image_info->magick,value,MaxTextExtent);
7997          break;
7998        }
7999      if (LocaleCompare(keyword,"mattecolor") == 0)
8000        {
8001          (void) QueryColorDatabase(value,&image_info->matte_color,
8002            exception);
8003          break;
8004        }
8005      ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8006      break;
8007    }
8008    case 'P':
8009    case 'p':
8010    {
8011      if (LocaleCompare(keyword,"pointsize") == 0)
8012        {
8013          image_info->pointsize=InterpretLocaleValue(value,(char **) NULL);
8014          draw_info->pointsize=InterpretLocaleValue(value,(char **) NULL);
8015          break;
8016        }
8017      ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8018      break;
8019    }
8020    case 'Q':
8021    case 'q':
8022    {
8023      if (LocaleCompare(keyword,"quality") == 0)
8024        {
8025          image_info->quality=StringToLong(value);
8026          if (image == (Image *) NULL)
8027            break;
8028          image->quality=StringToLong(value);
8029          break;
8030        }
8031      break;
8032    }
8033    case 'S':
8034    case 's':
8035    {
8036      if (LocaleCompare(keyword,"size") == 0)
8037        {
8038          (void) CloneString(&image_info->size,value);
8039          break;
8040        }
8041      if (LocaleCompare(keyword,"stroke") == 0)
8042        {
8043          (void) QueryColorDatabase(value,&draw_info->stroke,exception);
8044          (void) SetImageOption(image_info,keyword,value);
8045          break;
8046        }
8047      ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8048      break;
8049    }
8050    default:
8051    {
8052      ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8053      break;
8054    }
8055  }
8056  return(MagickTrue);
8057}
8058#endif
8059
8060/*
8061%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8062%                                                                             %
8063%                                                                             %
8064%                                                                             %
8065%   U n r e g i s t e r M S L I m a g e                                       %
8066%                                                                             %
8067%                                                                             %
8068%                                                                             %
8069%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8070%
8071%  UnregisterMSLImage() removes format registrations made by the
8072%  MSL module from the list of supported formats.
8073%
8074%  The format of the UnregisterMSLImage method is:
8075%
8076%      UnregisterMSLImage(void)
8077%
8078*/
8079ModuleExport void UnregisterMSLImage(void)
8080{
8081  (void) UnregisterMagickInfo("MSL");
8082}
8083
8084#if defined(MAGICKCORE_XML_DELEGATE)
8085/*
8086%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8087%                                                                             %
8088%                                                                             %
8089%                                                                             %
8090%   W r i t e M S L I m a g e                                                 %
8091%                                                                             %
8092%                                                                             %
8093%                                                                             %
8094%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8095%
8096%  WriteMSLImage() writes an image to a file in MVG image format.
8097%
8098%  The format of the WriteMSLImage method is:
8099%
8100%      MagickBooleanType WriteMSLImage(const ImageInfo *image_info,Image *image)
8101%
8102%  A description of each parameter follows.
8103%
8104%    o image_info: the image info.
8105%
8106%    o image:  The image.
8107%
8108*/
8109static MagickBooleanType WriteMSLImage(const ImageInfo *image_info,Image *image)
8110{
8111  assert(image_info != (const ImageInfo *) NULL);
8112  assert(image_info->signature == MagickSignature);
8113  assert(image != (Image *) NULL);
8114  assert(image->signature == MagickSignature);
8115  if (image->debug != MagickFalse)
8116    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
8117  (void) ReferenceImage(image);
8118  (void) ProcessMSLScript(image_info,&image,&image->exception);
8119  return(MagickTrue);
8120}
8121#endif
8122