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