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