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