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