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