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