blob: a11f25ed52631c6cbe10c9cb21bed56996c6b4a1 [file] [log] [blame]
cristy3ed852e2009-09-05 21:47:34 +00001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% %
6% M M SSSSS L %
7% MM MM SS L %
8% M M M SSS L %
9% M M SS L %
10% M M SSSSS LLLLL %
11% %
12% %
13% Execute Magick Scripting Language Scripts. %
14% %
15% Software Design %
16% John Cristy %
17% Leonard Rosenthol %
18% William Radcliffe %
19% December 2001 %
20% %
21% %
cristy7e41fe82010-12-04 23:12:08 +000022% Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization %
cristy3ed852e2009-09-05 21:47:34 +000023% dedicated to making software imaging solutions freely available. %
24% %
25% You may not use this file except in compliance with the License. You may %
26% obtain a copy of the License at %
27% %
28% http://www.imagemagick.org/script/license.php %
29% %
30% Unless required by applicable law or agreed to in writing, software %
31% distributed under the License is distributed on an "AS IS" BASIS, %
32% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
33% See the License for the specific language governing permissions and %
34% limitations under the License. %
35% %
36%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
37%
38%
39*/
40
41/*
42 Include declarations.
43*/
cristy4c08aed2011-07-01 19:47:50 +000044#include "MagickCore/studio.h"
45#include "MagickCore/annotate.h"
46#include "MagickCore/artifact.h"
47#include "MagickCore/blob.h"
48#include "MagickCore/blob-private.h"
49#include "MagickCore/cache.h"
50#include "MagickCore/cache-view.h"
51#include "MagickCore/color.h"
52#include "MagickCore/colormap.h"
53#include "MagickCore/color-private.h"
54#include "MagickCore/composite.h"
55#include "MagickCore/constitute.h"
56#include "MagickCore/decorate.h"
57#include "MagickCore/display.h"
58#include "MagickCore/draw.h"
59#include "MagickCore/effect.h"
60#include "MagickCore/enhance.h"
61#include "MagickCore/exception.h"
62#include "MagickCore/exception-private.h"
63#include "MagickCore/fx.h"
64#include "MagickCore/geometry.h"
65#include "MagickCore/image.h"
66#include "MagickCore/image-private.h"
67#include "MagickCore/list.h"
68#include "MagickCore/log.h"
69#include "MagickCore/magick.h"
70#include "MagickCore/memory_.h"
71#include "MagickCore/module.h"
72#include "MagickCore/option.h"
73#include "MagickCore/paint.h"
74#include "MagickCore/pixel-accessor.h"
75#include "MagickCore/profile.h"
76#include "MagickCore/property.h"
77#include "MagickCore/quantize.h"
78#include "MagickCore/quantum-private.h"
79#include "MagickCore/registry.h"
80#include "MagickCore/resize.h"
81#include "MagickCore/resource_.h"
82#include "MagickCore/segment.h"
83#include "MagickCore/shear.h"
84#include "MagickCore/signature.h"
85#include "MagickCore/static.h"
86#include "MagickCore/string_.h"
87#include "MagickCore/string-private.h"
88#include "MagickCore/transform.h"
89#include "MagickCore/threshold.h"
90#include "MagickCore/utility.h"
cristy3ed852e2009-09-05 21:47:34 +000091#if defined(MAGICKCORE_XML_DELEGATE)
cristy0157aea2010-04-24 21:12:18 +000092# if defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +000093# if defined(__MINGW32__)
94# define _MSC_VER
95# else
96# include <win32config.h>
97# endif
98# endif
99# include <libxml/parser.h>
100# include <libxml/xmlmemory.h>
101# include <libxml/parserInternals.h>
102# include <libxml/xmlerror.h>
103#endif
104
105/*
106 Define Declatations.
107*/
108#define ThrowMSLException(severity,tag,reason) \
109 (void) ThrowMagickException(msl_info->exception,GetMagickModule(),severity, \
110 tag,"`%s'",reason);
111
112/*
113 Typedef declaractions.
114*/
115typedef struct _MSLGroupInfo
116{
cristybb503372010-05-27 20:51:26 +0000117 size_t
cristy3ed852e2009-09-05 21:47:34 +0000118 numImages; /* how many images are in this group */
119} MSLGroupInfo;
120
121typedef struct _MSLInfo
122{
123 ExceptionInfo
124 *exception;
125
cristybb503372010-05-27 20:51:26 +0000126 ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000127 n,
128 number_groups;
129
130 ImageInfo
131 **image_info;
132
133 DrawInfo
134 **draw_info;
135
136 Image
137 **attributes,
138 **image;
139
140 char
141 *content;
142
143 MSLGroupInfo
144 *group_info;
145
146#if defined(MAGICKCORE_XML_DELEGATE)
147 xmlParserCtxtPtr
148 parser;
149
150 xmlDocPtr
151 document;
152#endif
153} MSLInfo;
154
155/*
156 Forward declarations.
157*/
158#if defined(MAGICKCORE_XML_DELEGATE)
159static MagickBooleanType
cristy1e178e72011-08-28 19:44:34 +0000160 WriteMSLImage(const ImageInfo *,Image *,ExceptionInfo *);
cristyb988fe72009-09-16 01:01:10 +0000161
162static MagickBooleanType
cristyb20775d2009-09-16 01:51:41 +0000163 SetMSLAttributes(MSLInfo *,const char *,const char *);
cristy3ed852e2009-09-05 21:47:34 +0000164#endif
165
166#if defined(MAGICKCORE_XML_DELEGATE)
cristyb988fe72009-09-16 01:01:10 +0000167
cristy3ed852e2009-09-05 21:47:34 +0000168/*
169%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
170% %
171% %
172% %
173% R e a d M S L I m a g e %
174% %
175% %
176% %
177%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
178%
179% ReadMSLImage() reads a Magick Scripting Language file and returns it.
180% It allocates the memory necessary for the new Image structure and returns a
181% pointer to the new image.
182%
183% The format of the ReadMSLImage method is:
184%
185% Image *ReadMSLImage(const ImageInfo *image_info,ExceptionInfo *exception)
186%
187% A description of each parameter follows:
188%
189% o image_info: the image info.
190%
191% o exception: return any errors or warnings in this structure.
192%
cristy3ed852e2009-09-05 21:47:34 +0000193*/
194
195#if defined(__cplusplus) || defined(c_plusplus)
196extern "C" {
197#endif
198
cristy4fa36e42009-09-18 14:24:06 +0000199static inline Image *GetImageCache(const ImageInfo *image_info,const char *path,
200 ExceptionInfo *exception)
201{
202 char
203 key[MaxTextExtent];
204
205 ExceptionInfo
206 *sans_exception;
207
208 Image
209 *image;
210
211 ImageInfo
212 *read_info;
213
cristyb51dff52011-05-19 16:55:47 +0000214 (void) FormatLocaleString(key,MaxTextExtent,"cache:%s",path);
cristy4fa36e42009-09-18 14:24:06 +0000215 sans_exception=AcquireExceptionInfo();
216 image=(Image *) GetImageRegistry(ImageRegistryType,key,sans_exception);
217 sans_exception=DestroyExceptionInfo(sans_exception);
218 if (image != (Image *) NULL)
219 return(image);
220 read_info=CloneImageInfo(image_info);
221 (void) CopyMagickString(read_info->filename,path,MaxTextExtent);
222 image=ReadImage(read_info,exception);
223 read_info=DestroyImageInfo(read_info);
224 if (image != (Image *) NULL)
225 (void) SetImageRegistry(ImageRegistryType,key,image,exception);
226 return(image);
227}
228
229static int IsPathDirectory(const char *path)
230{
231 MagickBooleanType
232 status;
233
234 struct stat
235 attributes;
236
237 if ((path == (const char *) NULL) || (*path == '\0'))
238 return(MagickFalse);
239 status=GetPathAttributes(path,&attributes);
240 if (status == MagickFalse)
241 return(-1);
242 if (S_ISDIR(attributes.st_mode) == 0)
243 return(0);
244 return(1);
245}
246
cristy3ed852e2009-09-05 21:47:34 +0000247static int MSLIsStandalone(void *context)
248{
249 MSLInfo
250 *msl_info;
251
252 /*
253 Is this document tagged standalone?
254 */
255 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.MSLIsStandalone()");
256 msl_info=(MSLInfo *) context;
257 return(msl_info->document->standalone == 1);
258}
259
260static int MSLHasInternalSubset(void *context)
261{
262 MSLInfo
263 *msl_info;
264
265 /*
266 Does this document has an internal subset?
267 */
268 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
269 " SAX.MSLHasInternalSubset()");
270 msl_info=(MSLInfo *) context;
271 return(msl_info->document->intSubset != NULL);
272}
273
274static int MSLHasExternalSubset(void *context)
275{
276 MSLInfo
277 *msl_info;
278
279 /*
280 Does this document has an external subset?
281 */
282 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
283 " SAX.MSLHasExternalSubset()");
284 msl_info=(MSLInfo *) context;
285 return(msl_info->document->extSubset != NULL);
286}
287
288static void MSLInternalSubset(void *context,const xmlChar *name,
289 const xmlChar *external_id,const xmlChar *system_id)
290{
291 MSLInfo
292 *msl_info;
293
294 /*
295 Does this document has an internal subset?
296 */
297 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
298 " SAX.internalSubset(%s %s %s)",name,
cristyb988fe72009-09-16 01:01:10 +0000299 (external_id != (const xmlChar *) NULL ? (const char *) external_id : " "),
300 (system_id != (const xmlChar *) NULL ? (const char *) system_id : " "));
cristy3ed852e2009-09-05 21:47:34 +0000301 msl_info=(MSLInfo *) context;
302 (void) xmlCreateIntSubset(msl_info->document,name,external_id,system_id);
303}
304
305static xmlParserInputPtr MSLResolveEntity(void *context,
306 const xmlChar *public_id,const xmlChar *system_id)
307{
308 MSLInfo
309 *msl_info;
310
311 xmlParserInputPtr
312 stream;
313
314 /*
315 Special entity resolver, better left to the parser, it has more
316 context than the application layer. The default behaviour is to
317 not resolve the entities, in that case the ENTITY_REF nodes are
318 built in the structure (and the parameter values).
319 */
320 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
321 " SAX.resolveEntity(%s, %s)",
cristyb988fe72009-09-16 01:01:10 +0000322 (public_id != (const xmlChar *) NULL ? (const char *) public_id : "none"),
323 (system_id != (const xmlChar *) NULL ? (const char *) system_id : "none"));
cristy3ed852e2009-09-05 21:47:34 +0000324 msl_info=(MSLInfo *) context;
325 stream=xmlLoadExternalEntity((const char *) system_id,(const char *)
326 public_id,msl_info->parser);
327 return(stream);
328}
329
330static xmlEntityPtr MSLGetEntity(void *context,const xmlChar *name)
331{
332 MSLInfo
333 *msl_info;
334
335 /*
336 Get an entity by name.
337 */
338 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
cristyb988fe72009-09-16 01:01:10 +0000339 " SAX.MSLGetEntity(%s)",(const char *) name);
cristy3ed852e2009-09-05 21:47:34 +0000340 msl_info=(MSLInfo *) context;
341 return(xmlGetDocEntity(msl_info->document,name));
342}
343
344static xmlEntityPtr MSLGetParameterEntity(void *context,const xmlChar *name)
345{
346 MSLInfo
347 *msl_info;
348
349 /*
350 Get a parameter entity by name.
351 */
352 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
cristyb988fe72009-09-16 01:01:10 +0000353 " SAX.getParameterEntity(%s)",(const char *) name);
cristy3ed852e2009-09-05 21:47:34 +0000354 msl_info=(MSLInfo *) context;
355 return(xmlGetParameterEntity(msl_info->document,name));
356}
357
358static void MSLEntityDeclaration(void *context,const xmlChar *name,int type,
359 const xmlChar *public_id,const xmlChar *system_id,xmlChar *content)
360{
361 MSLInfo
362 *msl_info;
363
364 /*
365 An entity definition has been parsed.
366 */
367 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
368 " SAX.entityDecl(%s, %d, %s, %s, %s)",name,type,
cristyb988fe72009-09-16 01:01:10 +0000369 public_id != (const xmlChar *) NULL ? (const char *) public_id : "none",
370 system_id != (const xmlChar *) NULL ? (const char *) system_id : "none",
371 content);
cristy3ed852e2009-09-05 21:47:34 +0000372 msl_info=(MSLInfo *) context;
373 if (msl_info->parser->inSubset == 1)
374 (void) xmlAddDocEntity(msl_info->document,name,type,public_id,system_id,
375 content);
376 else
377 if (msl_info->parser->inSubset == 2)
378 (void) xmlAddDtdEntity(msl_info->document,name,type,public_id,system_id,
379 content);
380}
381
382static void MSLAttributeDeclaration(void *context,const xmlChar *element,
383 const xmlChar *name,int type,int value,const xmlChar *default_value,
384 xmlEnumerationPtr tree)
385{
386 MSLInfo
387 *msl_info;
388
389 xmlChar
390 *fullname,
391 *prefix;
392
393 xmlParserCtxtPtr
394 parser;
395
396 /*
397 An attribute definition has been parsed.
398 */
399 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
400 " SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",element,name,type,value,
401 default_value);
402 msl_info=(MSLInfo *) context;
403 fullname=(xmlChar *) NULL;
404 prefix=(xmlChar *) NULL;
405 parser=msl_info->parser;
406 fullname=(xmlChar *) xmlSplitQName(parser,name,&prefix);
407 if (parser->inSubset == 1)
408 (void) xmlAddAttributeDecl(&parser->vctxt,msl_info->document->intSubset,
409 element,fullname,prefix,(xmlAttributeType) type,
410 (xmlAttributeDefault) value,default_value,tree);
411 else
412 if (parser->inSubset == 2)
413 (void) xmlAddAttributeDecl(&parser->vctxt,msl_info->document->extSubset,
414 element,fullname,prefix,(xmlAttributeType) type,
415 (xmlAttributeDefault) value,default_value,tree);
416 if (prefix != (xmlChar *) NULL)
417 xmlFree(prefix);
418 if (fullname != (xmlChar *) NULL)
419 xmlFree(fullname);
420}
421
422static void MSLElementDeclaration(void *context,const xmlChar *name,int type,
423 xmlElementContentPtr content)
424{
425 MSLInfo
426 *msl_info;
427
428 xmlParserCtxtPtr
429 parser;
430
431 /*
432 An element definition has been parsed.
433 */
434 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
435 " SAX.elementDecl(%s, %d, ...)",name,type);
436 msl_info=(MSLInfo *) context;
437 parser=msl_info->parser;
438 if (parser->inSubset == 1)
439 (void) xmlAddElementDecl(&parser->vctxt,msl_info->document->intSubset,
440 name,(xmlElementTypeVal) type,content);
441 else
442 if (parser->inSubset == 2)
443 (void) xmlAddElementDecl(&parser->vctxt,msl_info->document->extSubset,
444 name,(xmlElementTypeVal) type,content);
445}
446
447static void MSLNotationDeclaration(void *context,const xmlChar *name,
448 const xmlChar *public_id,const xmlChar *system_id)
449{
450 MSLInfo
451 *msl_info;
452
453 xmlParserCtxtPtr
454 parser;
455
456 /*
457 What to do when a notation declaration has been parsed.
458 */
459 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
460 " SAX.notationDecl(%s, %s, %s)",name,
cristyb988fe72009-09-16 01:01:10 +0000461 public_id != (const xmlChar *) NULL ? (const char *) public_id : "none",
462 system_id != (const xmlChar *) NULL ? (const char *) system_id : "none");
cristy3ed852e2009-09-05 21:47:34 +0000463 msl_info=(MSLInfo *) context;
464 parser=msl_info->parser;
465 if (parser->inSubset == 1)
466 (void) xmlAddNotationDecl(&parser->vctxt,msl_info->document->intSubset,
467 name,public_id,system_id);
468 else
469 if (parser->inSubset == 2)
470 (void) xmlAddNotationDecl(&parser->vctxt,msl_info->document->intSubset,
471 name,public_id,system_id);
472}
473
474static void MSLUnparsedEntityDeclaration(void *context,const xmlChar *name,
475 const xmlChar *public_id,const xmlChar *system_id,const xmlChar *notation)
476{
477 MSLInfo
478 *msl_info;
479
480 /*
481 What to do when an unparsed entity declaration is parsed.
482 */
483 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
484 " SAX.unparsedEntityDecl(%s, %s, %s, %s)",name,
cristyb988fe72009-09-16 01:01:10 +0000485 public_id != (const xmlChar *) NULL ? (const char *) public_id : "none",
486 system_id != (const xmlChar *) NULL ? (const char *) system_id : "none",
487 notation);
cristy3ed852e2009-09-05 21:47:34 +0000488 msl_info=(MSLInfo *) context;
489 (void) xmlAddDocEntity(msl_info->document,name,
490 XML_EXTERNAL_GENERAL_UNPARSED_ENTITY,public_id,system_id,notation);
491
492}
493
494static void MSLSetDocumentLocator(void *context,xmlSAXLocatorPtr location)
495{
496 MSLInfo
497 *msl_info;
498
499 /*
500 Receive the document locator at startup, actually xmlDefaultSAXLocator.
501 */
502 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
503 " SAX.setDocumentLocator()\n");
504 (void) location;
505 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +0000506 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +0000507}
508
509static void MSLStartDocument(void *context)
510{
511 MSLInfo
512 *msl_info;
513
514 xmlParserCtxtPtr
515 parser;
516
517 /*
518 Called when the document start being processed.
519 */
520 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
521 " SAX.startDocument()");
522 msl_info=(MSLInfo *) context;
523 parser=msl_info->parser;
524 msl_info->document=xmlNewDoc(parser->version);
525 if (msl_info->document == (xmlDocPtr) NULL)
526 return;
527 if (parser->encoding == NULL)
528 msl_info->document->encoding=NULL;
529 else
530 msl_info->document->encoding=xmlStrdup(parser->encoding);
531 msl_info->document->standalone=parser->standalone;
532}
533
534static void MSLEndDocument(void *context)
535{
536 MSLInfo
537 *msl_info;
538
539 /*
540 Called when the document end has been detected.
541 */
542 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.endDocument()");
543 msl_info=(MSLInfo *) context;
544 if (msl_info->content != (char *) NULL)
545 msl_info->content=DestroyString(msl_info->content);
546}
547
548static void MSLPushImage(MSLInfo *msl_info,Image *image)
549{
cristybb503372010-05-27 20:51:26 +0000550 ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000551 n;
552
553 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
554 assert(msl_info != (MSLInfo *) NULL);
555 msl_info->n++;
556 n=msl_info->n;
557 msl_info->image_info=(ImageInfo **) ResizeQuantumMemory(msl_info->image_info,
558 (n+1),sizeof(*msl_info->image_info));
559 msl_info->draw_info=(DrawInfo **) ResizeQuantumMemory(msl_info->draw_info,
560 (n+1),sizeof(*msl_info->draw_info));
561 msl_info->attributes=(Image **) ResizeQuantumMemory(msl_info->attributes,
562 (n+1),sizeof(*msl_info->attributes));
563 msl_info->image=(Image **) ResizeQuantumMemory(msl_info->image,(n+1),
564 sizeof(*msl_info->image));
565 if ((msl_info->image_info == (ImageInfo **) NULL) ||
566 (msl_info->draw_info == (DrawInfo **) NULL) ||
567 (msl_info->attributes == (Image **) NULL) ||
568 (msl_info->image == (Image **) NULL))
569 ThrowMSLException(ResourceLimitFatalError,"MemoryAllocationFailed","msl");
570 msl_info->image_info[n]=CloneImageInfo(msl_info->image_info[n-1]);
571 msl_info->draw_info[n]=CloneDrawInfo(msl_info->image_info[n-1],
572 msl_info->draw_info[n-1]);
573 if (image == (Image *) NULL)
574 msl_info->attributes[n]=AcquireImage(msl_info->image_info[n]);
575 else
576 msl_info->attributes[n]=CloneImage(image,0,0,MagickTrue,&image->exception);
577 msl_info->image[n]=(Image *) image;
578 if ((msl_info->image_info[n] == (ImageInfo *) NULL) ||
579 (msl_info->attributes[n] == (Image *) NULL))
580 ThrowMSLException(ResourceLimitFatalError,"MemoryAllocationFailed","msl");
581 if (msl_info->number_groups != 0)
582 msl_info->group_info[msl_info->number_groups-1].numImages++;
583}
584
585static void MSLPopImage(MSLInfo *msl_info)
586{
587 if (msl_info->number_groups != 0)
588 return;
589 if (msl_info->image[msl_info->n] != (Image *) NULL)
590 msl_info->image[msl_info->n]=DestroyImage(msl_info->image[msl_info->n]);
591 msl_info->attributes[msl_info->n]=DestroyImage(
592 msl_info->attributes[msl_info->n]);
593 msl_info->image_info[msl_info->n]=DestroyImageInfo(
594 msl_info->image_info[msl_info->n]);
595 msl_info->n--;
596}
597
598static void MSLStartElement(void *context,const xmlChar *tag,
599 const xmlChar **attributes)
600{
601 AffineMatrix
602 affine,
603 current;
604
605 ChannelType
606 channel;
607
cristybd5a96c2011-08-21 00:04:26 +0000608 ChannelType
609 channel_mask;
610
cristy3ed852e2009-09-05 21:47:34 +0000611 char
612 key[MaxTextExtent],
613 *value;
614
615 const char
616 *attribute,
617 *keyword;
618
619 double
620 angle;
621
622 DrawInfo
623 *draw_info;
624
625 ExceptionInfo
626 exception;
627
628 GeometryInfo
629 geometry_info;
630
631 Image
632 *image;
633
634 int
635 flags;
636
cristybb503372010-05-27 20:51:26 +0000637 ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000638 option,
639 j,
640 n,
641 x,
642 y;
643
644 MSLInfo
645 *msl_info;
646
647 RectangleInfo
648 geometry;
649
cristybb503372010-05-27 20:51:26 +0000650 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000651 i;
652
cristybb503372010-05-27 20:51:26 +0000653 size_t
cristy3ed852e2009-09-05 21:47:34 +0000654 height,
655 width;
656
657 /*
658 Called when an opening tag has been processed.
659 */
660 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
661 " SAX.startElement(%s",tag);
662 GetExceptionInfo(&exception);
663 msl_info=(MSLInfo *) context;
664 n=msl_info->n;
665 keyword=(const char *) NULL;
666 value=(char *) NULL;
667 SetGeometryInfo(&geometry_info);
668 channel=DefaultChannels;
669 switch (*tag)
670 {
671 case 'A':
672 case 'a':
673 {
cristyb988fe72009-09-16 01:01:10 +0000674 if (LocaleCompare((const char *) tag,"add-noise") == 0)
cristy3ed852e2009-09-05 21:47:34 +0000675 {
676 Image
677 *noise_image;
678
679 NoiseType
680 noise;
681
682 /*
683 Add noise image.
684 */
685 if (msl_info->image[n] == (Image *) NULL)
686 {
cristyb988fe72009-09-16 01:01:10 +0000687 ThrowMSLException(OptionError,"NoImagesDefined",
688 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +0000689 break;
690 }
691 noise=UniformNoise;
692 if (attributes != (const xmlChar **) NULL)
693 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
694 {
695 keyword=(const char *) attributes[i++];
696 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +0000697 msl_info->attributes[n],(const char *) attributes[i],
698 &exception);
cristy3ed852e2009-09-05 21:47:34 +0000699 CloneString(&value,attribute);
700 switch (*keyword)
701 {
702 case 'C':
703 case 'c':
704 {
705 if (LocaleCompare(keyword,"channel") == 0)
706 {
707 option=ParseChannelOption(value);
708 if (option < 0)
709 ThrowMSLException(OptionError,"UnrecognizedChannelType",
710 value);
711 channel=(ChannelType) option;
712 break;
713 }
714 ThrowMSLException(OptionError,"UnrecognizedAttribute",
715 keyword);
716 break;
717 }
718 case 'N':
719 case 'n':
720 {
721 if (LocaleCompare(keyword,"noise") == 0)
722 {
cristy042ee782011-04-22 18:48:30 +0000723 option=ParseCommandOption(MagickNoiseOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +0000724 value);
725 if (option < 0)
726 ThrowMSLException(OptionError,"UnrecognizedNoiseType",
727 value);
728 noise=(NoiseType) option;
729 break;
730 }
731 ThrowMSLException(OptionError,"UnrecognizedAttribute",
732 keyword);
733 break;
734 }
735 default:
736 {
737 ThrowMSLException(OptionError,"UnrecognizedAttribute",
738 keyword);
739 break;
740 }
741 }
742 }
cristybd5a96c2011-08-21 00:04:26 +0000743 channel_mask=SetPixelChannelMask(msl_info->image[n],channel);
cristy490408a2011-07-07 14:42:05 +0000744 noise_image=AddNoiseImage(msl_info->image[n],noise,
cristy3ed852e2009-09-05 21:47:34 +0000745 &msl_info->image[n]->exception);
cristybd5a96c2011-08-21 00:04:26 +0000746 (void) SetPixelChannelMap(msl_info->image[n],channel_mask);
cristy3ed852e2009-09-05 21:47:34 +0000747 if (noise_image == (Image *) NULL)
748 break;
749 msl_info->image[n]=DestroyImage(msl_info->image[n]);
750 msl_info->image[n]=noise_image;
751 break;
752 }
cristyb988fe72009-09-16 01:01:10 +0000753 if (LocaleCompare((const char *) tag,"annotate") == 0)
cristy3ed852e2009-09-05 21:47:34 +0000754 {
755 char
756 text[MaxTextExtent];
757
758 /*
759 Annotate image.
760 */
761 if (msl_info->image[n] == (Image *) NULL)
762 {
cristyb988fe72009-09-16 01:01:10 +0000763 ThrowMSLException(OptionError,"NoImagesDefined",
764 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +0000765 break;
766 }
767 draw_info=CloneDrawInfo(msl_info->image_info[n],
768 msl_info->draw_info[n]);
769 angle=0.0;
770 current=draw_info->affine;
771 GetAffineMatrix(&affine);
772 if (attributes != (const xmlChar **) NULL)
773 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
774 {
775 keyword=(const char *) attributes[i++];
776 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +0000777 msl_info->attributes[n],(const char *) attributes[i],
778 &exception);
cristy3ed852e2009-09-05 21:47:34 +0000779 CloneString(&value,attribute);
780 switch (*keyword)
781 {
782 case 'A':
783 case 'a':
784 {
785 if (LocaleCompare(keyword,"affine") == 0)
786 {
787 char
788 *p;
789
790 p=value;
cristyc1acd842011-05-19 23:05:47 +0000791 draw_info->affine.sx=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +0000792 if (*p ==',')
793 p++;
cristyc1acd842011-05-19 23:05:47 +0000794 draw_info->affine.rx=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +0000795 if (*p ==',')
796 p++;
cristyc1acd842011-05-19 23:05:47 +0000797 draw_info->affine.ry=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +0000798 if (*p ==',')
799 p++;
cristyc1acd842011-05-19 23:05:47 +0000800 draw_info->affine.sy=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +0000801 if (*p ==',')
802 p++;
cristyc1acd842011-05-19 23:05:47 +0000803 draw_info->affine.tx=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +0000804 if (*p ==',')
805 p++;
cristyc1acd842011-05-19 23:05:47 +0000806 draw_info->affine.ty=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +0000807 break;
808 }
809 if (LocaleCompare(keyword,"align") == 0)
810 {
cristy042ee782011-04-22 18:48:30 +0000811 option=ParseCommandOption(MagickAlignOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +0000812 value);
813 if (option < 0)
814 ThrowMSLException(OptionError,"UnrecognizedAlignType",
815 value);
816 draw_info->align=(AlignType) option;
817 break;
818 }
819 if (LocaleCompare(keyword,"antialias") == 0)
820 {
cristy042ee782011-04-22 18:48:30 +0000821 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +0000822 value);
823 if (option < 0)
824 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
825 value);
826 draw_info->stroke_antialias=(MagickBooleanType) option;
827 draw_info->text_antialias=(MagickBooleanType) option;
828 break;
829 }
830 ThrowMSLException(OptionError,"UnrecognizedAttribute",
831 keyword);
832 break;
833 }
834 case 'D':
835 case 'd':
836 {
837 if (LocaleCompare(keyword,"density") == 0)
838 {
839 CloneString(&draw_info->density,value);
840 break;
841 }
842 ThrowMSLException(OptionError,"UnrecognizedAttribute",
843 keyword);
844 break;
845 }
846 case 'E':
847 case 'e':
848 {
849 if (LocaleCompare(keyword,"encoding") == 0)
850 {
851 CloneString(&draw_info->encoding,value);
852 break;
853 }
854 ThrowMSLException(OptionError,"UnrecognizedAttribute",
855 keyword);
856 break;
857 }
858 case 'F':
859 case 'f':
860 {
861 if (LocaleCompare(keyword, "fill") == 0)
862 {
863 (void) QueryColorDatabase(value,&draw_info->fill,
864 &exception);
865 break;
866 }
867 if (LocaleCompare(keyword,"family") == 0)
868 {
869 CloneString(&draw_info->family,value);
870 break;
871 }
872 if (LocaleCompare(keyword,"font") == 0)
873 {
874 CloneString(&draw_info->font,value);
875 break;
876 }
877 ThrowMSLException(OptionError,"UnrecognizedAttribute",
878 keyword);
879 break;
880 }
881 case 'G':
882 case 'g':
883 {
884 if (LocaleCompare(keyword,"geometry") == 0)
885 {
cristy860f4e12011-07-28 19:00:28 +0000886 flags=ParseGravityGeometry(msl_info->image[n],value,
cristy3ed852e2009-09-05 21:47:34 +0000887 &geometry,&exception);
cristy3ed852e2009-09-05 21:47:34 +0000888 break;
889 }
890 if (LocaleCompare(keyword,"gravity") == 0)
891 {
cristy860f4e12011-07-28 19:00:28 +0000892 option=ParseCommandOption(MagickGravityOptions,
893 MagickFalse,value);
cristy3ed852e2009-09-05 21:47:34 +0000894 if (option < 0)
895 ThrowMSLException(OptionError,"UnrecognizedGravityType",
896 value);
897 draw_info->gravity=(GravityType) option;
898 break;
899 }
900 ThrowMSLException(OptionError,"UnrecognizedAttribute",
901 keyword);
902 break;
903 }
904 case 'P':
905 case 'p':
906 {
907 if (LocaleCompare(keyword,"pointsize") == 0)
908 {
cristyc1acd842011-05-19 23:05:47 +0000909 draw_info->pointsize=InterpretLocaleValue(value,
910 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000911 break;
912 }
913 ThrowMSLException(OptionError,"UnrecognizedAttribute",
914 keyword);
915 break;
916 }
917 case 'R':
918 case 'r':
919 {
920 if (LocaleCompare(keyword,"rotate") == 0)
921 {
cristyc1acd842011-05-19 23:05:47 +0000922 angle=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000923 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
924 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
925 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
926 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
927 break;
928 }
929 ThrowMSLException(OptionError,"UnrecognizedAttribute",
930 keyword);
931 break;
932 }
933 case 'S':
934 case 's':
935 {
936 if (LocaleCompare(keyword,"scale") == 0)
937 {
938 flags=ParseGeometry(value,&geometry_info);
939 if ((flags & SigmaValue) == 0)
940 geometry_info.sigma=1.0;
941 affine.sx=geometry_info.rho;
942 affine.sy=geometry_info.sigma;
943 break;
944 }
945 if (LocaleCompare(keyword,"skewX") == 0)
946 {
cristyc1acd842011-05-19 23:05:47 +0000947 angle=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000948 affine.ry=tan(DegreesToRadians(fmod((double) angle,
949 360.0)));
950 break;
951 }
952 if (LocaleCompare(keyword,"skewY") == 0)
953 {
cristyc1acd842011-05-19 23:05:47 +0000954 angle=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000955 affine.rx=tan(DegreesToRadians(fmod((double) angle,
956 360.0)));
957 break;
958 }
959 if (LocaleCompare(keyword,"stretch") == 0)
960 {
cristy042ee782011-04-22 18:48:30 +0000961 option=ParseCommandOption(MagickStretchOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +0000962 value);
963 if (option < 0)
964 ThrowMSLException(OptionError,"UnrecognizedStretchType",
965 value);
966 draw_info->stretch=(StretchType) option;
967 break;
968 }
969 if (LocaleCompare(keyword, "stroke") == 0)
970 {
971 (void) QueryColorDatabase(value,&draw_info->stroke,
972 &exception);
973 break;
974 }
975 if (LocaleCompare(keyword,"strokewidth") == 0)
976 {
cristyf2f27272009-12-17 14:48:46 +0000977 draw_info->stroke_width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +0000978 break;
979 }
980 if (LocaleCompare(keyword,"style") == 0)
981 {
cristy042ee782011-04-22 18:48:30 +0000982 option=ParseCommandOption(MagickStyleOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +0000983 value);
984 if (option < 0)
985 ThrowMSLException(OptionError,"UnrecognizedStyleType",
986 value);
987 draw_info->style=(StyleType) option;
988 break;
989 }
990 ThrowMSLException(OptionError,"UnrecognizedAttribute",
991 keyword);
992 break;
993 }
994 case 'T':
995 case 't':
996 {
997 if (LocaleCompare(keyword,"text") == 0)
998 {
999 CloneString(&draw_info->text,value);
1000 break;
1001 }
1002 if (LocaleCompare(keyword,"translate") == 0)
1003 {
1004 flags=ParseGeometry(value,&geometry_info);
1005 if ((flags & SigmaValue) == 0)
1006 geometry_info.sigma=1.0;
1007 affine.tx=geometry_info.rho;
1008 affine.ty=geometry_info.sigma;
1009 break;
1010 }
1011 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1012 keyword);
1013 break;
1014 }
1015 case 'U':
1016 case 'u':
1017 {
1018 if (LocaleCompare(keyword, "undercolor") == 0)
1019 {
1020 (void) QueryColorDatabase(value,&draw_info->undercolor,
1021 &exception);
1022 break;
1023 }
1024 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1025 keyword);
1026 break;
1027 }
1028 case 'W':
1029 case 'w':
1030 {
1031 if (LocaleCompare(keyword,"weight") == 0)
1032 {
cristyf2f27272009-12-17 14:48:46 +00001033 draw_info->weight=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001034 break;
1035 }
1036 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1037 keyword);
1038 break;
1039 }
1040 case 'X':
1041 case 'x':
1042 {
1043 if (LocaleCompare(keyword,"x") == 0)
1044 {
cristyf2f27272009-12-17 14:48:46 +00001045 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001046 break;
1047 }
1048 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1049 keyword);
1050 break;
1051 }
1052 case 'Y':
1053 case 'y':
1054 {
1055 if (LocaleCompare(keyword,"y") == 0)
1056 {
cristyf2f27272009-12-17 14:48:46 +00001057 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001058 break;
1059 }
1060 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1061 keyword);
1062 break;
1063 }
1064 default:
1065 {
1066 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1067 keyword);
1068 break;
1069 }
1070 }
1071 }
cristyb51dff52011-05-19 16:55:47 +00001072 (void) FormatLocaleString(text,MaxTextExtent,
cristye8c25f92010-06-03 00:53:06 +00001073 "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,(double)
1074 geometry.height,(double) geometry.x,(double) geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00001075 CloneString(&draw_info->geometry,text);
cristyef7c8a52010-10-10 13:46:51 +00001076 draw_info->affine.sx=affine.sx*current.sx+affine.ry*current.rx;
1077 draw_info->affine.rx=affine.rx*current.sx+affine.sy*current.rx;
1078 draw_info->affine.ry=affine.sx*current.ry+affine.ry*current.sy;
1079 draw_info->affine.sy=affine.rx*current.ry+affine.sy*current.sy;
1080 draw_info->affine.tx=affine.sx*current.tx+affine.ry*current.ty+
1081 affine.tx;
1082 draw_info->affine.ty=affine.rx*current.tx+affine.sy*current.ty+
1083 affine.ty;
cristy5cbc0162011-08-29 00:36:28 +00001084 (void) AnnotateImage(msl_info->image[n],draw_info,
1085 &msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00001086 draw_info=DestroyDrawInfo(draw_info);
1087 break;
1088 }
cristyb988fe72009-09-16 01:01:10 +00001089 if (LocaleCompare((const char *) tag,"append") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001090 {
1091 Image
1092 *append_image;
1093
1094 MagickBooleanType
1095 stack;
cristyb988fe72009-09-16 01:01:10 +00001096
cristy3ed852e2009-09-05 21:47:34 +00001097 if (msl_info->image[n] == (Image *) NULL)
1098 {
cristyb988fe72009-09-16 01:01:10 +00001099 ThrowMSLException(OptionError,"NoImagesDefined",
1100 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001101 break;
1102 }
1103 stack=MagickFalse;
1104 if (attributes != (const xmlChar **) NULL)
1105 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1106 {
1107 keyword=(const char *) attributes[i++];
1108 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00001109 msl_info->attributes[n],(const char *) attributes[i],
1110 &exception);
cristy3ed852e2009-09-05 21:47:34 +00001111 CloneString(&value,attribute);
1112 switch (*keyword)
1113 {
1114 case 'S':
1115 case 's':
1116 {
1117 if (LocaleCompare(keyword,"stack") == 0)
1118 {
cristy042ee782011-04-22 18:48:30 +00001119 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00001120 value);
1121 if (option < 0)
1122 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
1123 value);
1124 stack=(MagickBooleanType) option;
1125 break;
1126 }
1127 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1128 keyword);
1129 break;
1130 }
1131 default:
1132 {
1133 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1134 keyword);
1135 break;
1136 }
1137 }
1138 }
1139 append_image=AppendImages(msl_info->image[n],stack,
1140 &msl_info->image[n]->exception);
1141 if (append_image == (Image *) NULL)
1142 break;
1143 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1144 msl_info->image[n]=append_image;
1145 break;
1146 }
1147 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
1148 break;
1149 }
1150 case 'B':
1151 case 'b':
1152 {
cristyb988fe72009-09-16 01:01:10 +00001153 if (LocaleCompare((const char *) tag,"blur") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001154 {
1155 Image
1156 *blur_image;
1157
1158 /*
1159 Blur image.
1160 */
1161 if (msl_info->image[n] == (Image *) NULL)
1162 {
cristyb988fe72009-09-16 01:01:10 +00001163 ThrowMSLException(OptionError,"NoImagesDefined",
1164 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001165 break;
1166 }
1167 if (attributes != (const xmlChar **) NULL)
1168 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1169 {
1170 keyword=(const char *) attributes[i++];
1171 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00001172 msl_info->attributes[n],(const char *) attributes[i],
1173 &exception);
cristy3ed852e2009-09-05 21:47:34 +00001174 CloneString(&value,attribute);
1175 switch (*keyword)
1176 {
1177 case 'C':
1178 case 'c':
1179 {
1180 if (LocaleCompare(keyword,"channel") == 0)
1181 {
1182 option=ParseChannelOption(value);
1183 if (option < 0)
1184 ThrowMSLException(OptionError,"UnrecognizedChannelType",
1185 value);
1186 channel=(ChannelType) option;
1187 break;
1188 }
1189 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1190 keyword);
1191 break;
1192 }
1193 case 'G':
1194 case 'g':
1195 {
1196 if (LocaleCompare(keyword,"geometry") == 0)
1197 {
1198 flags=ParseGeometry(value,&geometry_info);
1199 if ((flags & SigmaValue) == 0)
1200 geometry_info.sigma=1.0;
1201 break;
1202 }
1203 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1204 keyword);
1205 break;
1206 }
1207 case 'R':
1208 case 'r':
1209 {
1210 if (LocaleCompare(keyword,"radius") == 0)
1211 {
cristyc1acd842011-05-19 23:05:47 +00001212 geometry_info.rho=InterpretLocaleValue(value,
1213 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00001214 break;
1215 }
1216 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1217 keyword);
1218 break;
1219 }
1220 case 'S':
1221 case 's':
1222 {
1223 if (LocaleCompare(keyword,"sigma") == 0)
1224 {
cristyf2f27272009-12-17 14:48:46 +00001225 geometry_info.sigma=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001226 break;
1227 }
1228 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1229 keyword);
1230 break;
1231 }
1232 default:
1233 {
1234 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1235 keyword);
1236 break;
1237 }
1238 }
1239 }
cristybd5a96c2011-08-21 00:04:26 +00001240 channel_mask=SetPixelChannelMask(msl_info->image[n],channel);
cristyf4ad9df2011-07-08 16:49:03 +00001241 blur_image=BlurImage(msl_info->image[n],geometry_info.rho,
cristy05c0c9a2011-09-05 23:16:13 +00001242 geometry_info.sigma,geometry_info.xi,
1243 &msl_info->image[n]->exception);
cristybd5a96c2011-08-21 00:04:26 +00001244 (void) SetPixelChannelMap(msl_info->image[n],channel_mask);
cristy3ed852e2009-09-05 21:47:34 +00001245 if (blur_image == (Image *) NULL)
1246 break;
1247 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1248 msl_info->image[n]=blur_image;
1249 break;
1250 }
cristyb988fe72009-09-16 01:01:10 +00001251 if (LocaleCompare((const char *) tag,"border") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001252 {
1253 Image
1254 *border_image;
1255
1256 /*
1257 Border image.
1258 */
1259 if (msl_info->image[n] == (Image *) NULL)
1260 {
cristyb988fe72009-09-16 01:01:10 +00001261 ThrowMSLException(OptionError,"NoImagesDefined",
1262 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001263 break;
1264 }
1265 SetGeometry(msl_info->image[n],&geometry);
1266 if (attributes != (const xmlChar **) NULL)
1267 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1268 {
1269 keyword=(const char *) attributes[i++];
1270 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00001271 msl_info->attributes[n],(const char *) attributes[i],
1272 &exception);
cristy3ed852e2009-09-05 21:47:34 +00001273 CloneString(&value,attribute);
1274 switch (*keyword)
1275 {
1276 case 'C':
1277 case 'c':
1278 {
1279 if (LocaleCompare(keyword,"compose") == 0)
1280 {
cristy042ee782011-04-22 18:48:30 +00001281 option=ParseCommandOption(MagickComposeOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00001282 value);
1283 if (option < 0)
1284 ThrowMSLException(OptionError,"UnrecognizedComposeType",
1285 value);
1286 msl_info->image[n]->compose=(CompositeOperator) option;
1287 break;
1288 }
1289 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1290 keyword);
1291 break;
1292 }
1293 case 'F':
1294 case 'f':
1295 {
1296 if (LocaleCompare(keyword, "fill") == 0)
1297 {
1298 (void) QueryColorDatabase(value,
1299 &msl_info->image[n]->border_color,&exception);
1300 break;
1301 }
1302 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1303 keyword);
1304 break;
1305 }
1306 case 'G':
1307 case 'g':
1308 {
1309 if (LocaleCompare(keyword,"geometry") == 0)
1310 {
1311 flags=ParsePageGeometry(msl_info->image[n],value,
1312 &geometry,&exception);
1313 if ((flags & HeightValue) == 0)
1314 geometry.height=geometry.width;
1315 break;
1316 }
1317 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1318 keyword);
1319 break;
1320 }
1321 case 'H':
1322 case 'h':
1323 {
1324 if (LocaleCompare(keyword,"height") == 0)
1325 {
cristyf2f27272009-12-17 14:48:46 +00001326 geometry.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001327 break;
1328 }
1329 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1330 keyword);
1331 break;
1332 }
1333 case 'W':
1334 case 'w':
1335 {
1336 if (LocaleCompare(keyword,"width") == 0)
1337 {
cristyf2f27272009-12-17 14:48:46 +00001338 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001339 break;
1340 }
1341 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1342 keyword);
1343 break;
1344 }
1345 default:
1346 {
1347 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1348 keyword);
1349 break;
1350 }
1351 }
1352 }
1353 border_image=BorderImage(msl_info->image[n],&geometry,
1354 &msl_info->image[n]->exception);
1355 if (border_image == (Image *) NULL)
1356 break;
1357 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1358 msl_info->image[n]=border_image;
1359 break;
1360 }
1361 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
1362 }
1363 case 'C':
1364 case 'c':
1365 {
cristyb988fe72009-09-16 01:01:10 +00001366 if (LocaleCompare((const char *) tag,"colorize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001367 {
1368 char
1369 opacity[MaxTextExtent];
1370
1371 Image
1372 *colorize_image;
1373
1374 PixelPacket
1375 target;
1376
1377 /*
1378 Add noise image.
1379 */
1380 if (msl_info->image[n] == (Image *) NULL)
1381 {
cristyb988fe72009-09-16 01:01:10 +00001382 ThrowMSLException(OptionError,"NoImagesDefined",
1383 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001384 break;
1385 }
1386 target=msl_info->image[n]->background_color;
1387 (void) CopyMagickString(opacity,"100",MaxTextExtent);
1388 if (attributes != (const xmlChar **) NULL)
1389 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1390 {
1391 keyword=(const char *) attributes[i++];
1392 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00001393 msl_info->attributes[n],(const char *) attributes[i],
1394 &exception);
cristy3ed852e2009-09-05 21:47:34 +00001395 CloneString(&value,attribute);
1396 switch (*keyword)
1397 {
1398 case 'F':
1399 case 'f':
1400 {
1401 if (LocaleCompare(keyword,"fill") == 0)
1402 {
1403 (void) QueryColorDatabase(value,&target,
1404 &msl_info->image[n]->exception);
1405 break;
1406 }
1407 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1408 keyword);
1409 break;
1410 }
1411 case 'O':
1412 case 'o':
1413 {
1414 if (LocaleCompare(keyword,"opacity") == 0)
1415 {
1416 (void) CopyMagickString(opacity,value,MaxTextExtent);
1417 break;
1418 }
1419 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1420 keyword);
1421 break;
1422 }
1423 default:
1424 {
1425 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1426 keyword);
1427 break;
1428 }
1429 }
1430 }
1431 colorize_image=ColorizeImage(msl_info->image[n],opacity,target,
1432 &msl_info->image[n]->exception);
1433 if (colorize_image == (Image *) NULL)
1434 break;
1435 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1436 msl_info->image[n]=colorize_image;
1437 break;
1438 }
cristyb988fe72009-09-16 01:01:10 +00001439 if (LocaleCompare((const char *) tag, "charcoal") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001440 {
cristy05c0c9a2011-09-05 23:16:13 +00001441 double bias = 0.0,
1442 radius = 0.0,
cristy3ed852e2009-09-05 21:47:34 +00001443 sigma = 1.0;
1444
1445 if (msl_info->image[n] == (Image *) NULL)
1446 {
cristyb988fe72009-09-16 01:01:10 +00001447 ThrowMSLException(OptionError,"NoImagesDefined",
1448 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001449 break;
1450 }
1451 /*
1452 NOTE: charcoal can have no attributes, since we use all the defaults!
1453 */
1454 if (attributes != (const xmlChar **) NULL)
1455 {
1456 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1457 {
1458 keyword=(const char *) attributes[i++];
1459 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00001460 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00001461 switch (*keyword)
1462 {
cristy05c0c9a2011-09-05 23:16:13 +00001463 case 'B':
1464 case 'b':
1465 {
1466 if (LocaleCompare(keyword, "bias") == 0)
1467 {
1468 bias = InterpretLocaleValue(value,(char **) NULL);
1469 break;
1470 }
1471 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
1472 break;
1473 }
cristy3ed852e2009-09-05 21:47:34 +00001474 case 'R':
1475 case 'r':
1476 {
1477 if (LocaleCompare(keyword, "radius") == 0)
1478 {
cristyc1acd842011-05-19 23:05:47 +00001479 radius = InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00001480 break;
1481 }
1482 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
1483 break;
1484 }
1485 case 'S':
1486 case 's':
1487 {
1488 if (LocaleCompare(keyword,"sigma") == 0)
1489 {
cristyf2f27272009-12-17 14:48:46 +00001490 sigma = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00001491 break;
1492 }
1493 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
1494 break;
1495 }
1496 default:
1497 {
1498 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
1499 break;
1500 }
1501 }
1502 }
1503 }
1504
1505 /*
1506 charcoal image.
1507 */
1508 {
1509 Image
1510 *newImage;
1511
cristy05c0c9a2011-09-05 23:16:13 +00001512 newImage=CharcoalImage(msl_info->image[n],radius,sigma,bias,
cristy3ed852e2009-09-05 21:47:34 +00001513 &msl_info->image[n]->exception);
1514 if (newImage == (Image *) NULL)
1515 break;
1516 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1517 msl_info->image[n]=newImage;
1518 break;
1519 }
1520 }
cristyb988fe72009-09-16 01:01:10 +00001521 if (LocaleCompare((const char *) tag,"chop") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001522 {
1523 Image
1524 *chop_image;
1525
1526 /*
1527 Chop image.
1528 */
1529 if (msl_info->image[n] == (Image *) NULL)
1530 {
cristyb988fe72009-09-16 01:01:10 +00001531 ThrowMSLException(OptionError,"NoImagesDefined",
1532 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001533 break;
1534 }
1535 SetGeometry(msl_info->image[n],&geometry);
1536 if (attributes != (const xmlChar **) NULL)
1537 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1538 {
1539 keyword=(const char *) attributes[i++];
1540 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00001541 msl_info->attributes[n],(const char *) attributes[i],
1542 &exception);
cristy3ed852e2009-09-05 21:47:34 +00001543 CloneString(&value,attribute);
1544 switch (*keyword)
1545 {
1546 case 'G':
1547 case 'g':
1548 {
1549 if (LocaleCompare(keyword,"geometry") == 0)
1550 {
1551 flags=ParsePageGeometry(msl_info->image[n],value,
1552 &geometry,&exception);
1553 if ((flags & HeightValue) == 0)
1554 geometry.height=geometry.width;
1555 break;
1556 }
1557 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1558 keyword);
1559 break;
1560 }
1561 case 'H':
1562 case 'h':
1563 {
1564 if (LocaleCompare(keyword,"height") == 0)
1565 {
cristyf2f27272009-12-17 14:48:46 +00001566 geometry.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001567 break;
1568 }
1569 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1570 keyword);
1571 break;
1572 }
1573 case 'W':
1574 case 'w':
1575 {
1576 if (LocaleCompare(keyword,"width") == 0)
1577 {
cristyf2f27272009-12-17 14:48:46 +00001578 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001579 break;
1580 }
1581 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1582 keyword);
1583 break;
1584 }
1585 case 'X':
1586 case 'x':
1587 {
1588 if (LocaleCompare(keyword,"x") == 0)
1589 {
cristyf2f27272009-12-17 14:48:46 +00001590 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001591 break;
1592 }
1593 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1594 keyword);
1595 break;
1596 }
1597 case 'Y':
1598 case 'y':
1599 {
1600 if (LocaleCompare(keyword,"y") == 0)
1601 {
cristyf2f27272009-12-17 14:48:46 +00001602 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001603 break;
1604 }
1605 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1606 keyword);
1607 break;
1608 }
1609 default:
1610 {
1611 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1612 keyword);
1613 break;
1614 }
1615 }
1616 }
1617 chop_image=ChopImage(msl_info->image[n],&geometry,
1618 &msl_info->image[n]->exception);
1619 if (chop_image == (Image *) NULL)
1620 break;
1621 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1622 msl_info->image[n]=chop_image;
1623 break;
1624 }
cristyb988fe72009-09-16 01:01:10 +00001625 if (LocaleCompare((const char *) tag,"color-floodfill") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001626 {
1627 PaintMethod
1628 paint_method;
1629
cristy4c08aed2011-07-01 19:47:50 +00001630 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00001631 target;
1632
1633 /*
1634 Color floodfill image.
1635 */
1636 if (msl_info->image[n] == (Image *) NULL)
1637 {
cristyb988fe72009-09-16 01:01:10 +00001638 ThrowMSLException(OptionError,"NoImagesDefined",
1639 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001640 break;
1641 }
1642 draw_info=CloneDrawInfo(msl_info->image_info[n],
1643 msl_info->draw_info[n]);
1644 SetGeometry(msl_info->image[n],&geometry);
1645 paint_method=FloodfillMethod;
1646 if (attributes != (const xmlChar **) NULL)
1647 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1648 {
1649 keyword=(const char *) attributes[i++];
1650 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00001651 msl_info->attributes[n],(const char *) attributes[i],
1652 &exception);
cristy3ed852e2009-09-05 21:47:34 +00001653 CloneString(&value,attribute);
1654 switch (*keyword)
1655 {
1656 case 'B':
1657 case 'b':
1658 {
1659 if (LocaleCompare(keyword,"bordercolor") == 0)
1660 {
1661 (void) QueryMagickColor(value,&target,&exception);
1662 paint_method=FillToBorderMethod;
1663 break;
1664 }
1665 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1666 keyword);
1667 break;
1668 }
1669 case 'F':
1670 case 'f':
1671 {
1672 if (LocaleCompare(keyword,"fill") == 0)
1673 {
1674 (void) QueryColorDatabase(value,&draw_info->fill,
1675 &exception);
1676 break;
1677 }
1678 if (LocaleCompare(keyword,"fuzz") == 0)
1679 {
cristyc1acd842011-05-19 23:05:47 +00001680 msl_info->image[n]->fuzz=InterpretLocaleValue(value,
1681 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00001682 break;
1683 }
1684 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1685 keyword);
1686 break;
1687 }
1688 case 'G':
1689 case 'g':
1690 {
1691 if (LocaleCompare(keyword,"geometry") == 0)
1692 {
1693 flags=ParsePageGeometry(msl_info->image[n],value,
1694 &geometry,&exception);
1695 if ((flags & HeightValue) == 0)
1696 geometry.height=geometry.width;
1697 (void) GetOneVirtualMagickPixel(msl_info->image[n],
1698 geometry.x,geometry.y,&target,&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 {
cristyf2f27272009-12-17 14:48:46 +00001710 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001711 (void) GetOneVirtualMagickPixel(msl_info->image[n],
1712 geometry.x,geometry.y,&target,&exception);
1713 break;
1714 }
1715 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1716 keyword);
1717 break;
1718 }
1719 case 'Y':
1720 case 'y':
1721 {
1722 if (LocaleCompare(keyword,"y") == 0)
1723 {
cristyf2f27272009-12-17 14:48:46 +00001724 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001725 (void) GetOneVirtualMagickPixel(msl_info->image[n],
1726 geometry.x,geometry.y,&target,&exception);
1727 break;
1728 }
1729 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1730 keyword);
1731 break;
1732 }
1733 default:
1734 {
1735 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1736 keyword);
1737 break;
1738 }
1739 }
1740 }
cristyd42d9952011-07-08 14:21:50 +00001741 (void) FloodfillPaintImage(msl_info->image[n],draw_info,&target,
1742 geometry.x,geometry.y,paint_method == FloodfillMethod ?
cristy189e84c2011-08-27 18:08:53 +00001743 MagickFalse : MagickTrue,&msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00001744 draw_info=DestroyDrawInfo(draw_info);
1745 break;
1746 }
cristyb988fe72009-09-16 01:01:10 +00001747 if (LocaleCompare((const char *) tag,"comment") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001748 break;
cristyb988fe72009-09-16 01:01:10 +00001749 if (LocaleCompare((const char *) tag,"composite") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001750 {
1751 char
1752 composite_geometry[MaxTextExtent];
1753
1754 CompositeOperator
1755 compose;
1756
1757 Image
1758 *composite_image,
1759 *rotate_image;
1760
1761 PixelPacket
1762 target;
1763
1764 /*
1765 Composite image.
1766 */
1767 if (msl_info->image[n] == (Image *) NULL)
1768 {
cristyb988fe72009-09-16 01:01:10 +00001769 ThrowMSLException(OptionError,"NoImagesDefined",
1770 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001771 break;
1772 }
1773 composite_image=NewImageList();
1774 compose=OverCompositeOp;
1775 if (attributes != (const xmlChar **) NULL)
1776 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1777 {
1778 keyword=(const char *) attributes[i++];
1779 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00001780 msl_info->attributes[n],(const char *) attributes[i],
1781 &exception);
cristy3ed852e2009-09-05 21:47:34 +00001782 CloneString(&value,attribute);
1783 switch (*keyword)
1784 {
1785 case 'C':
1786 case 'c':
1787 {
1788 if (LocaleCompare(keyword,"compose") == 0)
1789 {
cristy042ee782011-04-22 18:48:30 +00001790 option=ParseCommandOption(MagickComposeOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00001791 value);
1792 if (option < 0)
1793 ThrowMSLException(OptionError,"UnrecognizedComposeType",
1794 value);
1795 compose=(CompositeOperator) option;
1796 break;
1797 }
1798 break;
1799 }
1800 case 'I':
1801 case 'i':
1802 {
1803 if (LocaleCompare(keyword,"image") == 0)
1804 for (j=0; j < msl_info->n; j++)
1805 {
1806 const char
1807 *attribute;
cristyb988fe72009-09-16 01:01:10 +00001808
cristy3ed852e2009-09-05 21:47:34 +00001809 attribute=GetImageProperty(msl_info->attributes[j],"id");
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],
cristy018f07f2011-09-04 21:15:19 +00001833 msl_info->attributes[n],(const char *) attributes[i],
1834 &exception);
cristy3ed852e2009-09-05 21:47:34 +00001835 CloneString(&value,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) QueryColorDatabase(value,
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 (void) GetOneVirtualPixel(msl_info->image[n],geometry.x,
1885 geometry.y,&target,&exception);
1886 break;
1887 }
1888 if (LocaleCompare(keyword,"gravity") == 0)
1889 {
cristy042ee782011-04-22 18:48:30 +00001890 option=ParseCommandOption(MagickGravityOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00001891 value);
1892 if (option < 0)
1893 ThrowMSLException(OptionError,"UnrecognizedGravityType",
1894 value);
1895 msl_info->image[n]->gravity=(GravityType) option;
1896 break;
1897 }
1898 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1899 keyword);
1900 break;
1901 }
1902 case 'I':
1903 case 'i':
1904 {
1905 if (LocaleCompare(keyword,"image") == 0)
1906 break;
1907 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1908 keyword);
1909 break;
1910 }
1911 case 'M':
1912 case 'm':
1913 {
1914 if (LocaleCompare(keyword,"mask") == 0)
1915 for (j=0; j < msl_info->n; j++)
1916 {
1917 const char
1918 *attribute;
1919
1920 attribute=GetImageProperty(msl_info->attributes[j],"id");
1921 if ((attribute != (const char *) NULL) &&
1922 (LocaleCompare(value,value) == 0))
1923 {
cristy018f07f2011-09-04 21:15:19 +00001924 SetImageType(composite_image,TrueColorMatteType,
1925 &exception);
cristy3ed852e2009-09-05 21:47:34 +00001926 (void) CompositeImage(composite_image,
1927 CopyOpacityCompositeOp,msl_info->image[j],0,0);
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 {
cristybb503372010-05-27 20:51:26 +00001940 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001941 opacity,
1942 y;
cristyb988fe72009-09-16 01:01:10 +00001943
cristybb503372010-05-27 20:51:26 +00001944 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001945 x;
cristyb988fe72009-09-16 01:01:10 +00001946
cristy4c08aed2011-07-01 19:47:50 +00001947 register Quantum
cristy3ed852e2009-09-05 21:47:34 +00001948 *q;
cristyb988fe72009-09-16 01:01:10 +00001949
cristy3ed852e2009-09-05 21:47:34 +00001950 CacheView
1951 *composite_view;
1952
cristy4c08aed2011-07-01 19:47:50 +00001953 opacity=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001954 if (compose != DissolveCompositeOp)
1955 {
cristyb988fe72009-09-16 01:01:10 +00001956 (void) SetImageOpacity(composite_image,(Quantum)
1957 opacity);
cristy3ed852e2009-09-05 21:47:34 +00001958 break;
1959 }
1960 (void) SetImageArtifact(msl_info->image[n],
1961 "compose:args",value);
1962 if (composite_image->matte != MagickTrue)
cristy4c08aed2011-07-01 19:47:50 +00001963 (void) SetImageOpacity(composite_image,OpaqueAlpha);
cristy3ed852e2009-09-05 21:47:34 +00001964 composite_view=AcquireCacheView(composite_image);
cristybb503372010-05-27 20:51:26 +00001965 for (y=0; y < (ssize_t) composite_image->rows ; y++)
cristyb988fe72009-09-16 01:01:10 +00001966 {
cristy4c08aed2011-07-01 19:47:50 +00001967 q=GetCacheViewAuthenticPixels(composite_view,0,y,
1968 (ssize_t) composite_image->columns,1,&exception);
cristybb503372010-05-27 20:51:26 +00001969 for (x=0; x < (ssize_t) composite_image->columns; x++)
cristyb988fe72009-09-16 01:01:10 +00001970 {
cristy4c08aed2011-07-01 19:47:50 +00001971 if (GetPixelAlpha(composite_image,q) == OpaqueAlpha)
1972 SetPixelAlpha(composite_image,
1973 ClampToQuantum(opacity),q);
cristyed231572011-07-14 02:18:59 +00001974 q+=GetPixelChannels(composite_image);
cristy3ed852e2009-09-05 21:47:34 +00001975 }
1976 if (SyncCacheViewAuthenticPixels(composite_view,&exception) == MagickFalse)
1977 break;
1978 }
1979 composite_view=DestroyCacheView(composite_view);
1980 break;
1981 }
1982 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1983 keyword);
1984 break;
1985 }
1986 case 'R':
1987 case 'r':
1988 {
1989 if (LocaleCompare(keyword,"rotate") == 0)
1990 {
cristyc1acd842011-05-19 23:05:47 +00001991 rotate_image=RotateImage(composite_image,
1992 InterpretLocaleValue(value,(char **) NULL),&exception);
cristy3ed852e2009-09-05 21:47:34 +00001993 break;
1994 }
1995 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1996 keyword);
1997 break;
1998 }
1999 case 'T':
2000 case 't':
2001 {
2002 if (LocaleCompare(keyword,"tile") == 0)
2003 {
2004 MagickBooleanType
2005 tile;
2006
cristy042ee782011-04-22 18:48:30 +00002007 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002008 value);
2009 if (option < 0)
2010 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
2011 value);
2012 tile=(MagickBooleanType) option;
cristyda16f162011-02-19 23:52:17 +00002013 (void) tile;
cristy3ed852e2009-09-05 21:47:34 +00002014 if (rotate_image != (Image *) NULL)
2015 (void) SetImageArtifact(rotate_image,
2016 "compose:outside-overlay","false");
2017 else
2018 (void) SetImageArtifact(composite_image,
2019 "compose:outside-overlay","false");
2020 image=msl_info->image[n];
2021 height=composite_image->rows;
2022 width=composite_image->columns;
cristyeaedf062010-05-29 22:36:02 +00002023 for (y=0; y < (ssize_t) image->rows; y+=(ssize_t) height)
2024 for (x=0; x < (ssize_t) image->columns; x+=(ssize_t) width)
cristy3ed852e2009-09-05 21:47:34 +00002025 {
2026 if (rotate_image != (Image *) NULL)
2027 (void) CompositeImage(image,compose,rotate_image,
2028 x,y);
2029 else
2030 (void) CompositeImage(image,compose,
2031 composite_image,x,y);
2032 }
2033 if (rotate_image != (Image *) NULL)
2034 rotate_image=DestroyImage(rotate_image);
2035 break;
2036 }
2037 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2038 keyword);
2039 break;
2040 }
2041 case 'X':
2042 case 'x':
2043 {
2044 if (LocaleCompare(keyword,"x") == 0)
2045 {
cristyf2f27272009-12-17 14:48:46 +00002046 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002047 (void) GetOneVirtualPixel(msl_info->image[n],geometry.x,
2048 geometry.y,&target,&exception);
2049 break;
2050 }
2051 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2052 keyword);
2053 break;
2054 }
2055 case 'Y':
2056 case 'y':
2057 {
2058 if (LocaleCompare(keyword,"y") == 0)
2059 {
cristyf2f27272009-12-17 14:48:46 +00002060 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002061 (void) GetOneVirtualPixel(msl_info->image[n],geometry.x,
2062 geometry.y,&target,&exception);
2063 break;
2064 }
2065 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2066 keyword);
2067 break;
2068 }
2069 default:
2070 {
2071 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2072 keyword);
2073 break;
2074 }
2075 }
2076 }
2077 image=msl_info->image[n];
cristyb51dff52011-05-19 16:55:47 +00002078 (void) FormatLocaleString(composite_geometry,MaxTextExtent,
cristye8c25f92010-06-03 00:53:06 +00002079 "%.20gx%.20g%+.20g%+.20g",(double) composite_image->columns,
2080 (double) composite_image->rows,(double) geometry.x,(double)
cristyf2faecf2010-05-28 19:19:36 +00002081 geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00002082 flags=ParseGravityGeometry(image,composite_geometry,&geometry,
2083 &exception);
cristybd5a96c2011-08-21 00:04:26 +00002084 channel_mask=SetPixelChannelMask(image,channel);
cristy3ed852e2009-09-05 21:47:34 +00002085 if (rotate_image == (Image *) NULL)
cristyf4ad9df2011-07-08 16:49:03 +00002086 CompositeImage(image,compose,composite_image,geometry.x,geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00002087 else
2088 {
2089 /*
2090 Rotate image.
2091 */
cristybb503372010-05-27 20:51:26 +00002092 geometry.x-=(ssize_t) (rotate_image->columns-
cristy3ed852e2009-09-05 21:47:34 +00002093 composite_image->columns)/2;
cristybb503372010-05-27 20:51:26 +00002094 geometry.y-=(ssize_t) (rotate_image->rows-composite_image->rows)/2;
cristyf4ad9df2011-07-08 16:49:03 +00002095 CompositeImage(image,compose,rotate_image,geometry.x,geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00002096 rotate_image=DestroyImage(rotate_image);
2097 }
cristybd5a96c2011-08-21 00:04:26 +00002098 (void) SetPixelChannelMask(image,channel_mask);
cristy3ed852e2009-09-05 21:47:34 +00002099 composite_image=DestroyImage(composite_image);
2100 break;
2101 }
cristyb988fe72009-09-16 01:01:10 +00002102 if (LocaleCompare((const char *) tag,"contrast") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002103 {
2104 MagickBooleanType
2105 sharpen;
2106
2107 /*
2108 Contrast image.
2109 */
2110 if (msl_info->image[n] == (Image *) NULL)
2111 {
cristyb988fe72009-09-16 01:01:10 +00002112 ThrowMSLException(OptionError,"NoImagesDefined",
2113 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002114 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],
cristy018f07f2011-09-04 21:15:19 +00002122 msl_info->attributes[n],(const char *) attributes[i],
2123 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002124 CloneString(&value,attribute);
2125 switch (*keyword)
2126 {
2127 case 'S':
2128 case 's':
2129 {
2130 if (LocaleCompare(keyword,"sharpen") == 0)
2131 {
cristy042ee782011-04-22 18:48:30 +00002132 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002133 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 }
cristye23ec9d2011-08-16 18:15:40 +00002152 (void) ContrastImage(msl_info->image[n],sharpen,
2153 &msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00002154 break;
2155 }
cristyb988fe72009-09-16 01:01:10 +00002156 if (LocaleCompare((const char *) tag,"crop") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002157 {
2158 Image
2159 *crop_image;
2160
2161 /*
2162 Crop image.
2163 */
2164 if (msl_info->image[n] == (Image *) NULL)
2165 {
cristyb988fe72009-09-16 01:01:10 +00002166 ThrowMSLException(OptionError,"NoImagesDefined",
2167 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002168 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],
cristy018f07f2011-09-04 21:15:19 +00002176 msl_info->attributes[n],(const char *) attributes[i],
2177 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002178 CloneString(&value,attribute);
2179 switch (*keyword)
2180 {
2181 case 'G':
2182 case 'g':
2183 {
2184 if (LocaleCompare(keyword,"geometry") == 0)
2185 {
cristy860f4e12011-07-28 19:00:28 +00002186 flags=ParseGravityGeometry(msl_info->image[n],value,
cristy3ed852e2009-09-05 21:47:34 +00002187 &geometry,&exception);
cristy3ed852e2009-09-05 21:47:34 +00002188 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 {
cristyf2f27272009-12-17 14:48:46 +00002199 geometry.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002200 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 {
cristyf2f27272009-12-17 14:48:46 +00002211 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002212 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 {
cristyf2f27272009-12-17 14:48:46 +00002223 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002224 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 {
cristyf2f27272009-12-17 14:48:46 +00002235 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002236 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->image[n]->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 }
cristyb988fe72009-09-16 01:01:10 +00002258 if (LocaleCompare((const char *) tag,"cycle-colormap") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002259 {
cristybb503372010-05-27 20:51:26 +00002260 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002261 display;
2262
2263 /*
2264 Cycle-colormap image.
2265 */
2266 if (msl_info->image[n] == (Image *) NULL)
2267 {
cristyb988fe72009-09-16 01:01:10 +00002268 ThrowMSLException(OptionError,"NoImagesDefined",
2269 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002270 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],
cristy018f07f2011-09-04 21:15:19 +00002278 msl_info->attributes[n],(const char *) attributes[i],
2279 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002280 CloneString(&value,attribute);
2281 switch (*keyword)
2282 {
2283 case 'D':
2284 case 'd':
2285 {
2286 if (LocaleCompare(keyword,"display") == 0)
2287 {
cristyf2f27272009-12-17 14:48:46 +00002288 display=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002289 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 }
cristy018f07f2011-09-04 21:15:19 +00002303 (void) CycleColormapImage(msl_info->image[n],display,&exception);
cristy3ed852e2009-09-05 21:47:34 +00002304 break;
2305 }
2306 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
2307 }
2308 case 'D':
2309 case 'd':
2310 {
cristyb988fe72009-09-16 01:01:10 +00002311 if (LocaleCompare((const char *) tag,"despeckle") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002312 {
2313 Image
2314 *despeckle_image;
2315
2316 /*
2317 Despeckle image.
2318 */
2319 if (msl_info->image[n] == (Image *) NULL)
2320 {
cristyb988fe72009-09-16 01:01:10 +00002321 ThrowMSLException(OptionError,"NoImagesDefined",
2322 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002323 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],
cristy018f07f2011-09-04 21:15:19 +00002330 msl_info->attributes[n],(const char *) attributes[i],
2331 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002332 CloneString(&value,attribute);
2333 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
2334 }
2335 despeckle_image=DespeckleImage(msl_info->image[n],
2336 &msl_info->image[n]->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 }
cristyb988fe72009-09-16 01:01:10 +00002343 if (LocaleCompare((const char *) tag,"display") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002344 {
2345 if (msl_info->image[n] == (Image *) NULL)
2346 {
cristyb988fe72009-09-16 01:01:10 +00002347 ThrowMSLException(OptionError,"NoImagesDefined",
2348 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002349 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],
cristy018f07f2011-09-04 21:15:19 +00002356 msl_info->attributes[n],(const char *) attributes[i],
2357 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002358 CloneString(&value,attribute);
2359 switch (*keyword)
2360 {
2361 default:
2362 {
2363 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2364 keyword);
2365 break;
2366 }
2367 }
2368 }
cristy051718b2011-08-28 22:49:25 +00002369 (void) DisplayImages(msl_info->image_info[n],msl_info->image[n],
2370 &msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00002371 break;
2372 }
cristyb988fe72009-09-16 01:01:10 +00002373 if (LocaleCompare((const char *) tag,"draw") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002374 {
2375 char
2376 text[MaxTextExtent];
2377
2378 /*
2379 Annotate image.
2380 */
2381 if (msl_info->image[n] == (Image *) NULL)
2382 {
cristyb988fe72009-09-16 01:01:10 +00002383 ThrowMSLException(OptionError,"NoImagesDefined",
2384 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002385 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],
cristy018f07f2011-09-04 21:15:19 +00002397 msl_info->attributes[n],(const char *) attributes[i],
2398 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002399 CloneString(&value,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;
cristyc1acd842011-05-19 23:05:47 +00002411 draw_info->affine.sx=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00002412 if (*p ==',')
2413 p++;
cristyc1acd842011-05-19 23:05:47 +00002414 draw_info->affine.rx=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00002415 if (*p ==',')
2416 p++;
cristyc1acd842011-05-19 23:05:47 +00002417 draw_info->affine.ry=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00002418 if (*p ==',')
2419 p++;
cristyc1acd842011-05-19 23:05:47 +00002420 draw_info->affine.sy=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00002421 if (*p ==',')
2422 p++;
cristyc1acd842011-05-19 23:05:47 +00002423 draw_info->affine.tx=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00002424 if (*p ==',')
2425 p++;
cristyc1acd842011-05-19 23:05:47 +00002426 draw_info->affine.ty=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00002427 break;
2428 }
2429 if (LocaleCompare(keyword,"align") == 0)
2430 {
cristy042ee782011-04-22 18:48:30 +00002431 option=ParseCommandOption(MagickAlignOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002432 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 {
cristy042ee782011-04-22 18:48:30 +00002441 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002442 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) QueryColorDatabase(value,&draw_info->fill,
2484 &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 {
cristy042ee782011-04-22 18:48:30 +00002514 option=ParseCommandOption(MagickGravityOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002515 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,"primitive") == 0)
cristyb988fe72009-09-16 01:01:10 +00002530 {
cristy3ed852e2009-09-05 21:47:34 +00002531 CloneString(&draw_info->primitive,value);
2532 break;
2533 }
2534 if (LocaleCompare(keyword,"pointsize") == 0)
2535 {
cristyc1acd842011-05-19 23:05:47 +00002536 draw_info->pointsize=InterpretLocaleValue(value,
2537 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002538 break;
2539 }
2540 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2541 keyword);
2542 break;
2543 }
2544 case 'R':
2545 case 'r':
2546 {
2547 if (LocaleCompare(keyword,"rotate") == 0)
2548 {
cristyc1acd842011-05-19 23:05:47 +00002549 angle=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002550 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
2551 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
2552 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
2553 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
2554 break;
2555 }
2556 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2557 keyword);
2558 break;
2559 }
2560 case 'S':
2561 case 's':
2562 {
2563 if (LocaleCompare(keyword,"scale") == 0)
2564 {
2565 flags=ParseGeometry(value,&geometry_info);
2566 if ((flags & SigmaValue) == 0)
2567 geometry_info.sigma=1.0;
2568 affine.sx=geometry_info.rho;
2569 affine.sy=geometry_info.sigma;
2570 break;
2571 }
2572 if (LocaleCompare(keyword,"skewX") == 0)
2573 {
cristyc1acd842011-05-19 23:05:47 +00002574 angle=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002575 affine.ry=cos(DegreesToRadians(fmod(angle,360.0)));
2576 break;
2577 }
2578 if (LocaleCompare(keyword,"skewY") == 0)
2579 {
cristyc1acd842011-05-19 23:05:47 +00002580 angle=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002581 affine.rx=cos(DegreesToRadians(fmod(angle,360.0)));
2582 break;
2583 }
2584 if (LocaleCompare(keyword,"stretch") == 0)
2585 {
cristy042ee782011-04-22 18:48:30 +00002586 option=ParseCommandOption(MagickStretchOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002587 value);
2588 if (option < 0)
2589 ThrowMSLException(OptionError,"UnrecognizedStretchType",
2590 value);
2591 draw_info->stretch=(StretchType) option;
2592 break;
2593 }
2594 if (LocaleCompare(keyword, "stroke") == 0)
2595 {
2596 (void) QueryColorDatabase(value,&draw_info->stroke,
2597 &exception);
2598 break;
2599 }
2600 if (LocaleCompare(keyword,"strokewidth") == 0)
2601 {
cristyf2f27272009-12-17 14:48:46 +00002602 draw_info->stroke_width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002603 break;
2604 }
2605 if (LocaleCompare(keyword,"style") == 0)
2606 {
cristy042ee782011-04-22 18:48:30 +00002607 option=ParseCommandOption(MagickStyleOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002608 value);
2609 if (option < 0)
2610 ThrowMSLException(OptionError,"UnrecognizedStyleType",
2611 value);
2612 draw_info->style=(StyleType) option;
2613 break;
2614 }
2615 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2616 keyword);
2617 break;
2618 }
2619 case 'T':
2620 case 't':
2621 {
2622 if (LocaleCompare(keyword,"text") == 0)
2623 {
2624 CloneString(&draw_info->text,value);
2625 break;
2626 }
2627 if (LocaleCompare(keyword,"translate") == 0)
2628 {
2629 flags=ParseGeometry(value,&geometry_info);
2630 if ((flags & SigmaValue) == 0)
2631 geometry_info.sigma=1.0;
2632 affine.tx=geometry_info.rho;
2633 affine.ty=geometry_info.sigma;
2634 break;
2635 }
2636 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2637 keyword);
2638 break;
2639 }
2640 case 'U':
2641 case 'u':
2642 {
2643 if (LocaleCompare(keyword, "undercolor") == 0)
2644 {
2645 (void) QueryColorDatabase(value,&draw_info->undercolor,
2646 &exception);
2647 break;
2648 }
2649 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2650 keyword);
2651 break;
2652 }
2653 case 'W':
2654 case 'w':
2655 {
2656 if (LocaleCompare(keyword,"weight") == 0)
2657 {
cristyf2f27272009-12-17 14:48:46 +00002658 draw_info->weight=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002659 break;
2660 }
2661 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2662 keyword);
2663 break;
2664 }
2665 case 'X':
2666 case 'x':
2667 {
2668 if (LocaleCompare(keyword,"x") == 0)
2669 {
cristyf2f27272009-12-17 14:48:46 +00002670 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002671 break;
2672 }
2673 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2674 keyword);
2675 break;
2676 }
2677 case 'Y':
2678 case 'y':
2679 {
2680 if (LocaleCompare(keyword,"y") == 0)
2681 {
cristyf2f27272009-12-17 14:48:46 +00002682 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002683 break;
2684 }
2685 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2686 keyword);
2687 break;
2688 }
2689 default:
2690 {
2691 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2692 keyword);
2693 break;
2694 }
2695 }
2696 }
cristyb51dff52011-05-19 16:55:47 +00002697 (void) FormatLocaleString(text,MaxTextExtent,
cristye8c25f92010-06-03 00:53:06 +00002698 "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,(double)
2699 geometry.height,(double) geometry.x,(double) geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00002700 CloneString(&draw_info->geometry,text);
cristyef7c8a52010-10-10 13:46:51 +00002701 draw_info->affine.sx=affine.sx*current.sx+affine.ry*current.rx;
2702 draw_info->affine.rx=affine.rx*current.sx+affine.sy*current.rx;
2703 draw_info->affine.ry=affine.sx*current.ry+affine.ry*current.sy;
2704 draw_info->affine.sy=affine.rx*current.ry+affine.sy*current.sy;
2705 draw_info->affine.tx=affine.sx*current.tx+affine.ry*current.ty+
2706 affine.tx;
2707 draw_info->affine.ty=affine.rx*current.tx+affine.sy*current.ty+
2708 affine.ty;
cristy018f07f2011-09-04 21:15:19 +00002709 (void) DrawImage(msl_info->image[n],draw_info,&exception);
cristy3ed852e2009-09-05 21:47:34 +00002710 draw_info=DestroyDrawInfo(draw_info);
2711 break;
2712 }
2713 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
2714 }
2715 case 'E':
2716 case 'e':
2717 {
cristyb988fe72009-09-16 01:01:10 +00002718 if (LocaleCompare((const char *) tag,"edge") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002719 {
2720 Image
2721 *edge_image;
2722
2723 /*
2724 Edge image.
2725 */
2726 if (msl_info->image[n] == (Image *) NULL)
2727 {
cristyb988fe72009-09-16 01:01:10 +00002728 ThrowMSLException(OptionError,"NoImagesDefined",
2729 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002730 break;
2731 }
2732 if (attributes != (const xmlChar **) NULL)
2733 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2734 {
2735 keyword=(const char *) attributes[i++];
2736 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002737 msl_info->attributes[n],(const char *) attributes[i],
2738 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002739 CloneString(&value,attribute);
2740 switch (*keyword)
2741 {
2742 case 'G':
2743 case 'g':
2744 {
2745 if (LocaleCompare(keyword,"geometry") == 0)
2746 {
2747 flags=ParseGeometry(value,&geometry_info);
2748 if ((flags & SigmaValue) == 0)
2749 geometry_info.sigma=1.0;
2750 break;
2751 }
2752 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2753 keyword);
2754 break;
2755 }
2756 case 'R':
2757 case 'r':
2758 {
2759 if (LocaleCompare(keyword,"radius") == 0)
2760 {
cristyc1acd842011-05-19 23:05:47 +00002761 geometry_info.rho=InterpretLocaleValue(value,
2762 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002763 break;
2764 }
2765 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2766 keyword);
2767 break;
2768 }
2769 default:
2770 {
2771 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2772 keyword);
2773 break;
2774 }
2775 }
2776 }
2777 edge_image=EdgeImage(msl_info->image[n],geometry_info.rho,
cristy8ae632d2011-09-05 17:29:53 +00002778 geometry_info.sigma,&msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00002779 if (edge_image == (Image *) NULL)
2780 break;
2781 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2782 msl_info->image[n]=edge_image;
2783 break;
2784 }
cristyb988fe72009-09-16 01:01:10 +00002785 if (LocaleCompare((const char *) tag,"emboss") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002786 {
2787 Image
2788 *emboss_image;
2789
2790 /*
2791 Emboss image.
2792 */
2793 if (msl_info->image[n] == (Image *) NULL)
2794 {
cristyb988fe72009-09-16 01:01:10 +00002795 ThrowMSLException(OptionError,"NoImagesDefined",
2796 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002797 break;
2798 }
2799 if (attributes != (const xmlChar **) NULL)
2800 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2801 {
2802 keyword=(const char *) attributes[i++];
2803 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002804 msl_info->attributes[n],(const char *) attributes[i],
2805 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002806 CloneString(&value,attribute);
2807 switch (*keyword)
2808 {
2809 case 'G':
2810 case 'g':
2811 {
2812 if (LocaleCompare(keyword,"geometry") == 0)
2813 {
2814 flags=ParseGeometry(value,&geometry_info);
2815 if ((flags & SigmaValue) == 0)
2816 geometry_info.sigma=1.0;
2817 break;
2818 }
2819 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2820 keyword);
2821 break;
2822 }
2823 case 'R':
2824 case 'r':
2825 {
2826 if (LocaleCompare(keyword,"radius") == 0)
2827 {
cristyc1acd842011-05-19 23:05:47 +00002828 geometry_info.rho=InterpretLocaleValue(value,
2829 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002830 break;
2831 }
2832 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2833 keyword);
2834 break;
2835 }
2836 case 'S':
2837 case 's':
2838 {
2839 if (LocaleCompare(keyword,"sigma") == 0)
2840 {
cristyf2f27272009-12-17 14:48:46 +00002841 geometry_info.sigma=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002842 break;
2843 }
2844 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2845 keyword);
2846 break;
2847 }
2848 default:
2849 {
2850 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2851 keyword);
2852 break;
2853 }
2854 }
2855 }
2856 emboss_image=EmbossImage(msl_info->image[n],geometry_info.rho,
2857 geometry_info.sigma,&msl_info->image[n]->exception);
2858 if (emboss_image == (Image *) NULL)
2859 break;
2860 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2861 msl_info->image[n]=emboss_image;
2862 break;
2863 }
cristyb988fe72009-09-16 01:01:10 +00002864 if (LocaleCompare((const char *) tag,"enhance") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002865 {
2866 Image
2867 *enhance_image;
2868
2869 /*
2870 Enhance image.
2871 */
2872 if (msl_info->image[n] == (Image *) NULL)
2873 {
cristyb988fe72009-09-16 01:01:10 +00002874 ThrowMSLException(OptionError,"NoImagesDefined",
2875 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002876 break;
2877 }
2878 if (attributes != (const xmlChar **) NULL)
2879 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2880 {
2881 keyword=(const char *) attributes[i++];
2882 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002883 msl_info->attributes[n],(const char *) attributes[i],
2884 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002885 CloneString(&value,attribute);
2886 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
2887 }
2888 enhance_image=EnhanceImage(msl_info->image[n],
2889 &msl_info->image[n]->exception);
2890 if (enhance_image == (Image *) NULL)
2891 break;
2892 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2893 msl_info->image[n]=enhance_image;
2894 break;
2895 }
cristyb988fe72009-09-16 01:01:10 +00002896 if (LocaleCompare((const char *) tag,"equalize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002897 {
2898 /*
2899 Equalize image.
2900 */
2901 if (msl_info->image[n] == (Image *) NULL)
2902 {
cristyb988fe72009-09-16 01:01:10 +00002903 ThrowMSLException(OptionError,"NoImagesDefined",
2904 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002905 break;
2906 }
2907 if (attributes != (const xmlChar **) NULL)
2908 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2909 {
2910 keyword=(const char *) attributes[i++];
2911 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002912 msl_info->attributes[n],(const char *) attributes[i],
2913 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002914 CloneString(&value,attribute);
2915 switch (*keyword)
2916 {
2917 default:
2918 {
2919 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2920 keyword);
2921 break;
2922 }
2923 }
2924 }
cristy6d8c3d72011-08-22 01:20:01 +00002925 (void) EqualizeImage(msl_info->image[n],
2926 &msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00002927 break;
2928 }
2929 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
2930 }
2931 case 'F':
2932 case 'f':
2933 {
cristyb988fe72009-09-16 01:01:10 +00002934 if (LocaleCompare((const char *) tag, "flatten") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002935 {
2936 if (msl_info->image[n] == (Image *) NULL)
2937 {
cristyb988fe72009-09-16 01:01:10 +00002938 ThrowMSLException(OptionError,"NoImagesDefined",
2939 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002940 break;
2941 }
2942
2943 /* no attributes here */
2944
2945 /* process the image */
2946 {
2947 Image
2948 *newImage;
2949
2950 newImage=MergeImageLayers(msl_info->image[n],FlattenLayer,
2951 &msl_info->image[n]->exception);
2952 if (newImage == (Image *) NULL)
2953 break;
2954 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2955 msl_info->image[n]=newImage;
2956 break;
2957 }
2958 }
cristyb988fe72009-09-16 01:01:10 +00002959 if (LocaleCompare((const char *) tag,"flip") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002960 {
2961 Image
2962 *flip_image;
2963
2964 /*
2965 Flip image.
2966 */
2967 if (msl_info->image[n] == (Image *) NULL)
2968 {
cristyb988fe72009-09-16 01:01:10 +00002969 ThrowMSLException(OptionError,"NoImagesDefined",
2970 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002971 break;
2972 }
2973 if (attributes != (const xmlChar **) NULL)
2974 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2975 {
2976 keyword=(const char *) attributes[i++];
2977 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002978 msl_info->attributes[n],(const char *) attributes[i],
2979 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002980 CloneString(&value,attribute);
2981 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
2982 }
2983 flip_image=FlipImage(msl_info->image[n],
2984 &msl_info->image[n]->exception);
2985 if (flip_image == (Image *) NULL)
2986 break;
2987 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2988 msl_info->image[n]=flip_image;
2989 break;
2990 }
cristyb988fe72009-09-16 01:01:10 +00002991 if (LocaleCompare((const char *) tag,"flop") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002992 {
2993 Image
2994 *flop_image;
2995
2996 /*
2997 Flop image.
2998 */
2999 if (msl_info->image[n] == (Image *) NULL)
3000 {
cristyb988fe72009-09-16 01:01:10 +00003001 ThrowMSLException(OptionError,"NoImagesDefined",
3002 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003003 break;
3004 }
3005 if (attributes != (const xmlChar **) NULL)
3006 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3007 {
3008 keyword=(const char *) attributes[i++];
3009 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003010 msl_info->attributes[n],(const char *) attributes[i],
3011 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003012 CloneString(&value,attribute);
3013 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3014 }
3015 flop_image=FlopImage(msl_info->image[n],
3016 &msl_info->image[n]->exception);
3017 if (flop_image == (Image *) NULL)
3018 break;
3019 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3020 msl_info->image[n]=flop_image;
3021 break;
3022 }
cristyb988fe72009-09-16 01:01:10 +00003023 if (LocaleCompare((const char *) tag,"frame") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003024 {
3025 FrameInfo
3026 frame_info;
3027
3028 Image
3029 *frame_image;
3030
3031 /*
3032 Frame image.
3033 */
3034 if (msl_info->image[n] == (Image *) NULL)
3035 {
cristyb988fe72009-09-16 01:01:10 +00003036 ThrowMSLException(OptionError,"NoImagesDefined",
3037 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003038 break;
3039 }
3040 SetGeometry(msl_info->image[n],&geometry);
3041 if (attributes != (const xmlChar **) NULL)
3042 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3043 {
3044 keyword=(const char *) attributes[i++];
3045 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003046 msl_info->attributes[n],(const char *) attributes[i],
3047 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003048 CloneString(&value,attribute);
3049 switch (*keyword)
3050 {
3051 case 'C':
3052 case 'c':
3053 {
3054 if (LocaleCompare(keyword,"compose") == 0)
3055 {
cristy042ee782011-04-22 18:48:30 +00003056 option=ParseCommandOption(MagickComposeOptions,
cristy3ed852e2009-09-05 21:47:34 +00003057 MagickFalse,value);
3058 if (option < 0)
3059 ThrowMSLException(OptionError,"UnrecognizedComposeType",
3060 value);
3061 msl_info->image[n]->compose=(CompositeOperator) option;
3062 break;
3063 }
3064 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3065 keyword);
3066 break;
3067 }
3068 case 'F':
3069 case 'f':
3070 {
3071 if (LocaleCompare(keyword, "fill") == 0)
3072 {
3073 (void) QueryColorDatabase(value,
3074 &msl_info->image[n]->matte_color,&exception);
3075 break;
3076 }
3077 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3078 keyword);
3079 break;
3080 }
3081 case 'G':
3082 case 'g':
3083 {
3084 if (LocaleCompare(keyword,"geometry") == 0)
3085 {
3086 flags=ParsePageGeometry(msl_info->image[n],value,
3087 &geometry,&exception);
3088 if ((flags & HeightValue) == 0)
3089 geometry.height=geometry.width;
3090 frame_info.width=geometry.width;
3091 frame_info.height=geometry.height;
3092 frame_info.outer_bevel=geometry.x;
3093 frame_info.inner_bevel=geometry.y;
3094 break;
3095 }
3096 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3097 keyword);
3098 break;
3099 }
3100 case 'H':
3101 case 'h':
3102 {
3103 if (LocaleCompare(keyword,"height") == 0)
3104 {
cristyf2f27272009-12-17 14:48:46 +00003105 frame_info.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003106 break;
3107 }
3108 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3109 keyword);
3110 break;
3111 }
3112 case 'I':
3113 case 'i':
3114 {
3115 if (LocaleCompare(keyword,"inner") == 0)
3116 {
cristyf2f27272009-12-17 14:48:46 +00003117 frame_info.inner_bevel=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003118 break;
3119 }
3120 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3121 keyword);
3122 break;
3123 }
3124 case 'O':
3125 case 'o':
3126 {
3127 if (LocaleCompare(keyword,"outer") == 0)
3128 {
cristyf2f27272009-12-17 14:48:46 +00003129 frame_info.outer_bevel=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003130 break;
3131 }
3132 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3133 keyword);
3134 break;
3135 }
3136 case 'W':
3137 case 'w':
3138 {
3139 if (LocaleCompare(keyword,"width") == 0)
3140 {
cristyf2f27272009-12-17 14:48:46 +00003141 frame_info.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003142 break;
3143 }
3144 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3145 keyword);
3146 break;
3147 }
3148 default:
3149 {
3150 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3151 keyword);
3152 break;
3153 }
3154 }
3155 }
cristybb503372010-05-27 20:51:26 +00003156 frame_info.x=(ssize_t) frame_info.width;
3157 frame_info.y=(ssize_t) frame_info.height;
cristy3ed852e2009-09-05 21:47:34 +00003158 frame_info.width=msl_info->image[n]->columns+2*frame_info.x;
3159 frame_info.height=msl_info->image[n]->rows+2*frame_info.y;
3160 frame_image=FrameImage(msl_info->image[n],&frame_info,
3161 &msl_info->image[n]->exception);
3162 if (frame_image == (Image *) NULL)
3163 break;
3164 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3165 msl_info->image[n]=frame_image;
3166 break;
3167 }
3168 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3169 }
3170 case 'G':
3171 case 'g':
3172 {
cristyb988fe72009-09-16 01:01:10 +00003173 if (LocaleCompare((const char *) tag,"gamma") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003174 {
3175 char
3176 gamma[MaxTextExtent];
3177
cristy4c08aed2011-07-01 19:47:50 +00003178 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00003179 pixel;
3180
3181 /*
3182 Gamma image.
3183 */
3184 if (msl_info->image[n] == (Image *) NULL)
3185 {
cristyb988fe72009-09-16 01:01:10 +00003186 ThrowMSLException(OptionError,"NoImagesDefined",
3187 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003188 break;
3189 }
3190 channel=UndefinedChannel;
3191 pixel.red=0.0;
3192 pixel.green=0.0;
3193 pixel.blue=0.0;
3194 *gamma='\0';
3195 if (attributes != (const xmlChar **) NULL)
3196 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3197 {
3198 keyword=(const char *) attributes[i++];
3199 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003200 msl_info->attributes[n],(const char *) attributes[i],
3201 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003202 CloneString(&value,attribute);
3203 switch (*keyword)
3204 {
3205 case 'B':
3206 case 'b':
3207 {
3208 if (LocaleCompare(keyword,"blue") == 0)
3209 {
cristyc1acd842011-05-19 23:05:47 +00003210 pixel.blue=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003211 break;
3212 }
3213 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3214 keyword);
3215 break;
3216 }
3217 case 'C':
3218 case 'c':
3219 {
3220 if (LocaleCompare(keyword,"channel") == 0)
3221 {
3222 option=ParseChannelOption(value);
3223 if (option < 0)
3224 ThrowMSLException(OptionError,"UnrecognizedChannelType",
3225 value);
3226 channel=(ChannelType) option;
3227 break;
3228 }
3229 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3230 keyword);
3231 break;
3232 }
3233 case 'G':
3234 case 'g':
3235 {
3236 if (LocaleCompare(keyword,"gamma") == 0)
3237 {
3238 (void) CopyMagickString(gamma,value,MaxTextExtent);
3239 break;
3240 }
3241 if (LocaleCompare(keyword,"green") == 0)
3242 {
cristyc1acd842011-05-19 23:05:47 +00003243 pixel.green=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003244 break;
3245 }
3246 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3247 keyword);
3248 break;
3249 }
3250 case 'R':
3251 case 'r':
3252 {
3253 if (LocaleCompare(keyword,"red") == 0)
3254 {
cristyc1acd842011-05-19 23:05:47 +00003255 pixel.red=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003256 break;
3257 }
3258 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3259 keyword);
3260 break;
3261 }
3262 default:
3263 {
3264 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3265 keyword);
3266 break;
3267 }
3268 }
3269 }
3270 if (*gamma == '\0')
cristyb51dff52011-05-19 16:55:47 +00003271 (void) FormatLocaleString(gamma,MaxTextExtent,"%g,%g,%g",
cristy3ed852e2009-09-05 21:47:34 +00003272 (double) pixel.red,(double) pixel.green,(double) pixel.blue);
cristyb3e7c6c2011-07-24 01:43:55 +00003273 (void) GammaImage(msl_info->image[n],atof(gamma),
3274 &msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00003275 break;
3276 }
cristyb988fe72009-09-16 01:01:10 +00003277 else if (LocaleCompare((const char *) tag,"get") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003278 {
3279 if (msl_info->image[n] == (Image *) NULL)
3280 {
cristyb988fe72009-09-16 01:01:10 +00003281 ThrowMSLException(OptionError,"NoImagesDefined",
3282 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003283 break;
3284 }
3285 if (attributes == (const xmlChar **) NULL)
3286 break;
3287 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3288 {
3289 keyword=(const char *) attributes[i++];
cristyb988fe72009-09-16 01:01:10 +00003290 CloneString(&value,(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003291 (void) CopyMagickString(key,value,MaxTextExtent);
3292 switch (*keyword)
3293 {
3294 case 'H':
3295 case 'h':
3296 {
3297 if (LocaleCompare(keyword,"height") == 0)
3298 {
cristyb51dff52011-05-19 16:55:47 +00003299 (void) FormatLocaleString(value,MaxTextExtent,"%.20g",
cristye8c25f92010-06-03 00:53:06 +00003300 (double) msl_info->image[n]->rows);
cristy3ed852e2009-09-05 21:47:34 +00003301 (void) SetImageProperty(msl_info->attributes[n],key,value);
3302 break;
3303 }
3304 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3305 }
3306 case 'W':
3307 case 'w':
3308 {
3309 if (LocaleCompare(keyword,"width") == 0)
3310 {
cristyb51dff52011-05-19 16:55:47 +00003311 (void) FormatLocaleString(value,MaxTextExtent,"%.20g",
cristye8c25f92010-06-03 00:53:06 +00003312 (double) msl_info->image[n]->columns);
cristy3ed852e2009-09-05 21:47:34 +00003313 (void) SetImageProperty(msl_info->attributes[n],key,value);
3314 break;
3315 }
3316 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3317 }
3318 default:
3319 {
3320 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3321 break;
3322 }
3323 }
3324 }
3325 break;
3326 }
cristyb988fe72009-09-16 01:01:10 +00003327 else if (LocaleCompare((const char *) tag, "group") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003328 {
3329 msl_info->number_groups++;
3330 msl_info->group_info=(MSLGroupInfo *) ResizeQuantumMemory(
3331 msl_info->group_info,msl_info->number_groups+1UL,
3332 sizeof(*msl_info->group_info));
3333 break;
3334 }
3335 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3336 }
3337 case 'I':
3338 case 'i':
3339 {
cristyb988fe72009-09-16 01:01:10 +00003340 if (LocaleCompare((const char *) tag,"image") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003341 {
cristy3ed852e2009-09-05 21:47:34 +00003342 MSLPushImage(msl_info,(Image *) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003343 if (attributes == (const xmlChar **) NULL)
3344 break;
3345 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3346 {
3347 keyword=(const char *) attributes[i++];
3348 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003349 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00003350 switch (*keyword)
3351 {
cristyb988fe72009-09-16 01:01:10 +00003352 case 'C':
3353 case 'c':
cristy3ed852e2009-09-05 21:47:34 +00003354 {
cristyb988fe72009-09-16 01:01:10 +00003355 if (LocaleCompare(keyword,"color") == 0)
3356 {
3357 Image
3358 *next_image;
cristy3ed852e2009-09-05 21:47:34 +00003359
cristyb988fe72009-09-16 01:01:10 +00003360 (void) CopyMagickString(msl_info->image_info[n]->filename,
3361 "xc:",MaxTextExtent);
3362 (void) ConcatenateMagickString(msl_info->image_info[n]->
3363 filename,value,MaxTextExtent);
3364 next_image=ReadImage(msl_info->image_info[n],&exception);
3365 CatchException(&exception);
3366 if (next_image == (Image *) NULL)
3367 continue;
3368 if (msl_info->image[n] == (Image *) NULL)
3369 msl_info->image[n]=next_image;
3370 else
3371 {
3372 register Image
3373 *p;
cristy3ed852e2009-09-05 21:47:34 +00003374
cristyb988fe72009-09-16 01:01:10 +00003375 /*
3376 Link image into image list.
3377 */
3378 p=msl_info->image[n];
3379 while (p->next != (Image *) NULL)
3380 p=GetNextImageInList(p);
3381 next_image->previous=p;
3382 p->next=next_image;
3383 }
3384 break;
3385 }
cristyb20775d2009-09-16 01:51:41 +00003386 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00003387 break;
3388 }
3389 default:
3390 {
cristyb20775d2009-09-16 01:51:41 +00003391 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00003392 break;
3393 }
3394 }
3395 }
3396 break;
3397 }
cristyb988fe72009-09-16 01:01:10 +00003398 if (LocaleCompare((const char *) tag,"implode") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003399 {
3400 Image
3401 *implode_image;
3402
3403 /*
3404 Implode image.
3405 */
3406 if (msl_info->image[n] == (Image *) NULL)
3407 {
cristyb988fe72009-09-16 01:01:10 +00003408 ThrowMSLException(OptionError,"NoImagesDefined",
3409 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003410 break;
3411 }
3412 if (attributes != (const xmlChar **) NULL)
3413 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3414 {
3415 keyword=(const char *) attributes[i++];
3416 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003417 msl_info->attributes[n],(const char *) attributes[i],
3418 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003419 CloneString(&value,attribute);
3420 switch (*keyword)
3421 {
3422 case 'A':
3423 case 'a':
3424 {
3425 if (LocaleCompare(keyword,"amount") == 0)
3426 {
cristyc1acd842011-05-19 23:05:47 +00003427 geometry_info.rho=InterpretLocaleValue(value,
3428 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003429 break;
3430 }
3431 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3432 keyword);
3433 break;
3434 }
3435 case 'G':
3436 case 'g':
3437 {
3438 if (LocaleCompare(keyword,"geometry") == 0)
3439 {
3440 flags=ParseGeometry(value,&geometry_info);
3441 if ((flags & SigmaValue) == 0)
3442 geometry_info.sigma=1.0;
3443 break;
3444 }
3445 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3446 keyword);
3447 break;
3448 }
3449 default:
3450 {
3451 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3452 keyword);
3453 break;
3454 }
3455 }
3456 }
3457 implode_image=ImplodeImage(msl_info->image[n],geometry_info.rho,
cristy76f512e2011-09-12 01:26:56 +00003458 msl_info->image[n]->interpolate,&msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00003459 if (implode_image == (Image *) NULL)
3460 break;
3461 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3462 msl_info->image[n]=implode_image;
3463 break;
3464 }
3465 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3466 }
3467 case 'L':
3468 case 'l':
3469 {
cristyb988fe72009-09-16 01:01:10 +00003470 if (LocaleCompare((const char *) tag,"label") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003471 break;
cristyb988fe72009-09-16 01:01:10 +00003472 if (LocaleCompare((const char *) tag, "level") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003473 {
3474 double
3475 levelBlack = 0, levelGamma = 1, levelWhite = QuantumRange;
3476
3477 if (msl_info->image[n] == (Image *) NULL)
3478 {
cristyb988fe72009-09-16 01:01:10 +00003479 ThrowMSLException(OptionError,"NoImagesDefined",
3480 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003481 break;
3482 }
3483 if (attributes == (const xmlChar **) NULL)
3484 break;
3485 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3486 {
3487 keyword=(const char *) attributes[i++];
cristyb988fe72009-09-16 01:01:10 +00003488 CloneString(&value,(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003489 (void) CopyMagickString(key,value,MaxTextExtent);
3490 switch (*keyword)
3491 {
3492 case 'B':
3493 case 'b':
3494 {
3495 if (LocaleCompare(keyword,"black") == 0)
3496 {
cristyc1acd842011-05-19 23:05:47 +00003497 levelBlack = InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003498 break;
3499 }
3500 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3501 break;
3502 }
3503 case 'G':
3504 case 'g':
3505 {
3506 if (LocaleCompare(keyword,"gamma") == 0)
3507 {
cristyc1acd842011-05-19 23:05:47 +00003508 levelGamma = InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003509 break;
3510 }
3511 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3512 break;
3513 }
3514 case 'W':
3515 case 'w':
3516 {
3517 if (LocaleCompare(keyword,"white") == 0)
3518 {
cristyc1acd842011-05-19 23:05:47 +00003519 levelWhite = InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003520 break;
3521 }
3522 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3523 break;
3524 }
3525 default:
3526 {
3527 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3528 break;
3529 }
3530 }
3531 }
3532
3533 /* process image */
cristy01e9afd2011-08-10 17:38:41 +00003534 LevelImage(msl_info->image[n],levelBlack,levelWhite,levelGamma,
3535 &msl_info->image[n]->exception);
cristyf89cb1d2011-07-07 01:24:37 +00003536 break;
cristy3ed852e2009-09-05 21:47:34 +00003537 }
3538 }
3539 case 'M':
3540 case 'm':
3541 {
cristyb988fe72009-09-16 01:01:10 +00003542 if (LocaleCompare((const char *) tag,"magnify") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003543 {
3544 Image
3545 *magnify_image;
3546
3547 /*
3548 Magnify image.
3549 */
3550 if (msl_info->image[n] == (Image *) NULL)
3551 {
cristyb988fe72009-09-16 01:01:10 +00003552 ThrowMSLException(OptionError,"NoImagesDefined",
3553 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003554 break;
3555 }
3556 if (attributes != (const xmlChar **) NULL)
3557 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3558 {
3559 keyword=(const char *) attributes[i++];
3560 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003561 msl_info->attributes[n],(const char *) attributes[i],
3562 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003563 CloneString(&value,attribute);
3564 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3565 }
3566 magnify_image=MagnifyImage(msl_info->image[n],
3567 &msl_info->image[n]->exception);
3568 if (magnify_image == (Image *) NULL)
3569 break;
3570 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3571 msl_info->image[n]=magnify_image;
3572 break;
3573 }
cristyb988fe72009-09-16 01:01:10 +00003574 if (LocaleCompare((const char *) tag,"map") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003575 {
3576 Image
3577 *affinity_image;
3578
3579 MagickBooleanType
3580 dither;
3581
3582 QuantizeInfo
3583 *quantize_info;
3584
3585 /*
3586 Map image.
3587 */
3588 if (msl_info->image[n] == (Image *) NULL)
3589 {
cristyb988fe72009-09-16 01:01:10 +00003590 ThrowMSLException(OptionError,"NoImagesDefined",
3591 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003592 break;
3593 }
3594 affinity_image=NewImageList();
3595 dither=MagickFalse;
3596 if (attributes != (const xmlChar **) NULL)
3597 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3598 {
3599 keyword=(const char *) attributes[i++];
3600 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003601 msl_info->attributes[n],(const char *) attributes[i],
3602 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003603 CloneString(&value,attribute);
3604 switch (*keyword)
3605 {
3606 case 'D':
3607 case 'd':
3608 {
3609 if (LocaleCompare(keyword,"dither") == 0)
3610 {
cristy042ee782011-04-22 18:48:30 +00003611 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00003612 value);
3613 if (option < 0)
3614 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
3615 value);
3616 dither=(MagickBooleanType) option;
3617 break;
3618 }
3619 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3620 keyword);
3621 break;
3622 }
3623 case 'I':
3624 case 'i':
3625 {
3626 if (LocaleCompare(keyword,"image") == 0)
3627 for (j=0; j < msl_info->n; j++)
3628 {
3629 const char
3630 *attribute;
cristyb988fe72009-09-16 01:01:10 +00003631
cristy3ed852e2009-09-05 21:47:34 +00003632 attribute=GetImageProperty(msl_info->attributes[j],"id");
3633 if ((attribute != (const char *) NULL) &&
3634 (LocaleCompare(attribute,value) == 0))
3635 {
3636 affinity_image=CloneImage(msl_info->image[j],0,0,
3637 MagickFalse,&exception);
3638 break;
3639 }
3640 }
3641 break;
3642 }
3643 default:
3644 {
3645 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3646 keyword);
3647 break;
3648 }
3649 }
3650 }
3651 quantize_info=AcquireQuantizeInfo(msl_info->image_info[n]);
3652 quantize_info->dither=dither;
3653 (void) RemapImages(quantize_info,msl_info->image[n],
cristy018f07f2011-09-04 21:15:19 +00003654 affinity_image,&exception);
cristy3ed852e2009-09-05 21:47:34 +00003655 quantize_info=DestroyQuantizeInfo(quantize_info);
3656 affinity_image=DestroyImage(affinity_image);
3657 break;
3658 }
cristyb988fe72009-09-16 01:01:10 +00003659 if (LocaleCompare((const char *) tag,"matte-floodfill") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003660 {
3661 double
3662 opacity;
3663
cristy4c08aed2011-07-01 19:47:50 +00003664 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00003665 target;
3666
3667 PaintMethod
3668 paint_method;
3669
3670 /*
3671 Matte floodfill image.
3672 */
3673 opacity=0.0;
3674 if (msl_info->image[n] == (Image *) NULL)
3675 {
cristyb988fe72009-09-16 01:01:10 +00003676 ThrowMSLException(OptionError,"NoImagesDefined",
3677 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003678 break;
3679 }
3680 SetGeometry(msl_info->image[n],&geometry);
3681 paint_method=FloodfillMethod;
3682 if (attributes != (const xmlChar **) NULL)
3683 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3684 {
3685 keyword=(const char *) attributes[i++];
3686 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003687 msl_info->attributes[n],(const char *) attributes[i],
3688 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003689 CloneString(&value,attribute);
3690 switch (*keyword)
3691 {
3692 case 'B':
3693 case 'b':
3694 {
3695 if (LocaleCompare(keyword,"bordercolor") == 0)
3696 {
3697 (void) QueryMagickColor(value,&target,&exception);
3698 paint_method=FillToBorderMethod;
3699 break;
3700 }
3701 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3702 keyword);
3703 break;
3704 }
3705 case 'F':
3706 case 'f':
3707 {
3708 if (LocaleCompare(keyword,"fuzz") == 0)
3709 {
cristyc1acd842011-05-19 23:05:47 +00003710 msl_info->image[n]->fuzz=InterpretLocaleValue(value,
3711 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003712 break;
3713 }
3714 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3715 keyword);
3716 break;
3717 }
3718 case 'G':
3719 case 'g':
3720 {
3721 if (LocaleCompare(keyword,"geometry") == 0)
3722 {
3723 flags=ParsePageGeometry(msl_info->image[n],value,
3724 &geometry,&exception);
3725 if ((flags & HeightValue) == 0)
3726 geometry.height=geometry.width;
3727 (void) GetOneVirtualMagickPixel(msl_info->image[n],
3728 geometry.x,geometry.y,&target,&exception);
3729 break;
3730 }
3731 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3732 keyword);
3733 break;
3734 }
3735 case 'O':
3736 case 'o':
3737 {
3738 if (LocaleCompare(keyword,"opacity") == 0)
3739 {
cristyc1acd842011-05-19 23:05:47 +00003740 opacity=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003741 break;
3742 }
3743 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3744 keyword);
3745 break;
3746 }
3747 case 'X':
3748 case 'x':
3749 {
3750 if (LocaleCompare(keyword,"x") == 0)
3751 {
cristyf2f27272009-12-17 14:48:46 +00003752 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003753 (void) GetOneVirtualMagickPixel(msl_info->image[n],
3754 geometry.x,geometry.y,&target,&exception);
3755 break;
3756 }
3757 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3758 keyword);
3759 break;
3760 }
3761 case 'Y':
3762 case 'y':
3763 {
3764 if (LocaleCompare(keyword,"y") == 0)
3765 {
cristyf2f27272009-12-17 14:48:46 +00003766 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003767 (void) GetOneVirtualMagickPixel(msl_info->image[n],
3768 geometry.x,geometry.y,&target,&exception);
3769 break;
3770 }
3771 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3772 keyword);
3773 break;
3774 }
3775 default:
3776 {
3777 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3778 keyword);
3779 break;
3780 }
3781 }
3782 }
3783 draw_info=CloneDrawInfo(msl_info->image_info[n],
3784 msl_info->draw_info[n]);
cristy4c08aed2011-07-01 19:47:50 +00003785 draw_info->fill.alpha=ClampToQuantum(opacity);
cristybd5a96c2011-08-21 00:04:26 +00003786 channel_mask=SetPixelChannelMask(msl_info->image[n],AlphaChannel);
cristyd42d9952011-07-08 14:21:50 +00003787 (void) FloodfillPaintImage(msl_info->image[n],draw_info,&target,
3788 geometry.x,geometry.y,paint_method == FloodfillMethod ?
cristy189e84c2011-08-27 18:08:53 +00003789 MagickFalse : MagickTrue,&msl_info->image[n]->exception);
cristybd5a96c2011-08-21 00:04:26 +00003790 (void) SetPixelChannelMap(msl_info->image[n],channel_mask);
cristy3ed852e2009-09-05 21:47:34 +00003791 draw_info=DestroyDrawInfo(draw_info);
3792 break;
3793 }
cristyb988fe72009-09-16 01:01:10 +00003794 if (LocaleCompare((const char *) tag,"median-filter") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003795 {
3796 Image
3797 *median_image;
3798
3799 /*
3800 Median-filter image.
3801 */
3802 if (msl_info->image[n] == (Image *) NULL)
3803 {
cristyb988fe72009-09-16 01:01:10 +00003804 ThrowMSLException(OptionError,"NoImagesDefined",
3805 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003806 break;
3807 }
3808 if (attributes != (const xmlChar **) NULL)
3809 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3810 {
3811 keyword=(const char *) attributes[i++];
3812 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003813 msl_info->attributes[n],(const char *) attributes[i],
3814 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003815 CloneString(&value,attribute);
3816 switch (*keyword)
3817 {
3818 case 'G':
3819 case 'g':
3820 {
3821 if (LocaleCompare(keyword,"geometry") == 0)
3822 {
3823 flags=ParseGeometry(value,&geometry_info);
3824 if ((flags & SigmaValue) == 0)
3825 geometry_info.sigma=1.0;
3826 break;
3827 }
3828 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3829 keyword);
3830 break;
3831 }
3832 case 'R':
3833 case 'r':
3834 {
3835 if (LocaleCompare(keyword,"radius") == 0)
3836 {
cristyc1acd842011-05-19 23:05:47 +00003837 geometry_info.rho=InterpretLocaleValue(value,
3838 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003839 break;
3840 }
3841 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3842 keyword);
3843 break;
3844 }
3845 default:
3846 {
3847 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3848 keyword);
3849 break;
3850 }
3851 }
3852 }
cristy733678d2011-03-18 21:29:28 +00003853 median_image=StatisticImage(msl_info->image[n],MedianStatistic,
cristy95c38342011-03-18 22:39:51 +00003854 (size_t) geometry_info.rho,(size_t) geometry_info.sigma,
3855 &msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00003856 if (median_image == (Image *) NULL)
3857 break;
3858 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3859 msl_info->image[n]=median_image;
3860 break;
3861 }
cristyb988fe72009-09-16 01:01:10 +00003862 if (LocaleCompare((const char *) tag,"minify") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003863 {
3864 Image
3865 *minify_image;
3866
3867 /*
3868 Minify image.
3869 */
3870 if (msl_info->image[n] == (Image *) NULL)
3871 {
cristyb988fe72009-09-16 01:01:10 +00003872 ThrowMSLException(OptionError,"NoImagesDefined",
3873 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003874 break;
3875 }
3876 if (attributes != (const xmlChar **) NULL)
3877 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3878 {
3879 keyword=(const char *) attributes[i++];
3880 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003881 msl_info->attributes[n],(const char *) attributes[i],
3882 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003883 CloneString(&value,attribute);
3884 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3885 }
3886 minify_image=MinifyImage(msl_info->image[n],
3887 &msl_info->image[n]->exception);
3888 if (minify_image == (Image *) NULL)
3889 break;
3890 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3891 msl_info->image[n]=minify_image;
3892 break;
3893 }
cristyb988fe72009-09-16 01:01:10 +00003894 if (LocaleCompare((const char *) tag,"msl") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00003895 break;
cristyb988fe72009-09-16 01:01:10 +00003896 if (LocaleCompare((const char *) tag,"modulate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003897 {
3898 char
3899 modulate[MaxTextExtent];
3900
3901 /*
3902 Modulate image.
3903 */
3904 if (msl_info->image[n] == (Image *) NULL)
3905 {
cristyb988fe72009-09-16 01:01:10 +00003906 ThrowMSLException(OptionError,"NoImagesDefined",
3907 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003908 break;
3909 }
3910 geometry_info.rho=100.0;
3911 geometry_info.sigma=100.0;
3912 geometry_info.xi=100.0;
3913 if (attributes != (const xmlChar **) NULL)
3914 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3915 {
3916 keyword=(const char *) attributes[i++];
3917 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003918 msl_info->attributes[n],(const char *) attributes[i],
3919 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003920 CloneString(&value,attribute);
3921 switch (*keyword)
3922 {
3923 case 'B':
3924 case 'b':
3925 {
3926 if (LocaleCompare(keyword,"blackness") == 0)
3927 {
cristyc1acd842011-05-19 23:05:47 +00003928 geometry_info.rho=InterpretLocaleValue(value,
3929 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003930 break;
3931 }
3932 if (LocaleCompare(keyword,"brightness") == 0)
3933 {
cristyc1acd842011-05-19 23:05:47 +00003934 geometry_info.rho=InterpretLocaleValue(value,
3935 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003936 break;
3937 }
3938 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3939 keyword);
3940 break;
3941 }
3942 case 'F':
3943 case 'f':
3944 {
3945 if (LocaleCompare(keyword,"factor") == 0)
3946 {
3947 flags=ParseGeometry(value,&geometry_info);
3948 break;
3949 }
3950 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3951 keyword);
3952 break;
3953 }
3954 case 'H':
3955 case 'h':
3956 {
3957 if (LocaleCompare(keyword,"hue") == 0)
3958 {
cristyc1acd842011-05-19 23:05:47 +00003959 geometry_info.xi=InterpretLocaleValue(value,
3960 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003961 break;
3962 }
3963 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3964 keyword);
3965 break;
3966 }
3967 case 'L':
3968 case 'l':
3969 {
3970 if (LocaleCompare(keyword,"lightness") == 0)
3971 {
cristyc1acd842011-05-19 23:05:47 +00003972 geometry_info.rho=InterpretLocaleValue(value,
3973 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003974 break;
3975 }
3976 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3977 keyword);
3978 break;
3979 }
3980 case 'S':
3981 case 's':
3982 {
3983 if (LocaleCompare(keyword,"saturation") == 0)
3984 {
cristyc1acd842011-05-19 23:05:47 +00003985 geometry_info.sigma=InterpretLocaleValue(value,
3986 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003987 break;
3988 }
3989 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3990 keyword);
3991 break;
3992 }
3993 case 'W':
3994 case 'w':
3995 {
3996 if (LocaleCompare(keyword,"whiteness") == 0)
3997 {
cristyc1acd842011-05-19 23:05:47 +00003998 geometry_info.sigma=InterpretLocaleValue(value,
3999 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004000 break;
4001 }
4002 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4003 keyword);
4004 break;
4005 }
4006 default:
4007 {
4008 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4009 keyword);
4010 break;
4011 }
4012 }
4013 }
cristyb51dff52011-05-19 16:55:47 +00004014 (void) FormatLocaleString(modulate,MaxTextExtent,"%g,%g,%g",
cristy3ed852e2009-09-05 21:47:34 +00004015 geometry_info.rho,geometry_info.sigma,geometry_info.xi);
cristy33bd5152011-08-24 01:42:24 +00004016 (void) ModulateImage(msl_info->image[n],modulate,
4017 &msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00004018 break;
4019 }
4020 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4021 }
4022 case 'N':
4023 case 'n':
4024 {
cristyb988fe72009-09-16 01:01:10 +00004025 if (LocaleCompare((const char *) tag,"negate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004026 {
4027 MagickBooleanType
4028 gray;
4029
4030 /*
4031 Negate image.
4032 */
4033 if (msl_info->image[n] == (Image *) NULL)
4034 {
cristyb988fe72009-09-16 01:01:10 +00004035 ThrowMSLException(OptionError,"NoImagesDefined",
4036 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004037 break;
4038 }
4039 gray=MagickFalse;
4040 if (attributes != (const xmlChar **) NULL)
4041 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4042 {
4043 keyword=(const char *) attributes[i++];
4044 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004045 msl_info->attributes[n],(const char *) attributes[i],
4046 &exception);
cristy3ed852e2009-09-05 21:47:34 +00004047 CloneString(&value,attribute);
4048 switch (*keyword)
4049 {
4050 case 'C':
4051 case 'c':
4052 {
4053 if (LocaleCompare(keyword,"channel") == 0)
4054 {
4055 option=ParseChannelOption(value);
4056 if (option < 0)
4057 ThrowMSLException(OptionError,"UnrecognizedChannelType",
4058 value);
4059 channel=(ChannelType) option;
4060 break;
4061 }
4062 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4063 keyword);
4064 break;
4065 }
4066 case 'G':
4067 case 'g':
4068 {
4069 if (LocaleCompare(keyword,"gray") == 0)
4070 {
cristy042ee782011-04-22 18:48:30 +00004071 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004072 value);
4073 if (option < 0)
4074 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4075 value);
4076 gray=(MagickBooleanType) option;
4077 break;
4078 }
4079 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4080 keyword);
4081 break;
4082 }
4083 default:
4084 {
4085 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4086 keyword);
4087 break;
4088 }
4089 }
4090 }
cristybd5a96c2011-08-21 00:04:26 +00004091 channel_mask=SetPixelChannelMask(msl_info->image[n],channel);
cristyb3e7c6c2011-07-24 01:43:55 +00004092 (void) NegateImage(msl_info->image[n],gray,
4093 &msl_info->image[n]->exception);
cristybd5a96c2011-08-21 00:04:26 +00004094 (void) SetPixelChannelMap(msl_info->image[n],channel_mask);
cristy3ed852e2009-09-05 21:47:34 +00004095 break;
4096 }
cristyb988fe72009-09-16 01:01:10 +00004097 if (LocaleCompare((const char *) tag,"normalize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004098 {
4099 /*
4100 Normalize image.
4101 */
4102 if (msl_info->image[n] == (Image *) NULL)
4103 {
cristyb988fe72009-09-16 01:01:10 +00004104 ThrowMSLException(OptionError,"NoImagesDefined",
4105 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004106 break;
4107 }
4108 if (attributes != (const xmlChar **) NULL)
4109 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4110 {
4111 keyword=(const char *) attributes[i++];
4112 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004113 msl_info->attributes[n],(const char *) attributes[i],
4114 &exception);
cristy3ed852e2009-09-05 21:47:34 +00004115 CloneString(&value,attribute);
4116 switch (*keyword)
4117 {
4118 case 'C':
4119 case 'c':
4120 {
4121 if (LocaleCompare(keyword,"channel") == 0)
4122 {
4123 option=ParseChannelOption(value);
4124 if (option < 0)
4125 ThrowMSLException(OptionError,"UnrecognizedChannelType",
4126 value);
4127 channel=(ChannelType) option;
4128 break;
4129 }
4130 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4131 keyword);
4132 break;
4133 }
4134 default:
4135 {
4136 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4137 keyword);
4138 break;
4139 }
4140 }
4141 }
cristye23ec9d2011-08-16 18:15:40 +00004142 (void) NormalizeImage(msl_info->image[n],
4143 &msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00004144 break;
4145 }
4146 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4147 }
4148 case 'O':
4149 case 'o':
4150 {
cristyb988fe72009-09-16 01:01:10 +00004151 if (LocaleCompare((const char *) tag,"oil-paint") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004152 {
4153 Image
4154 *paint_image;
4155
4156 /*
4157 Oil-paint image.
4158 */
4159 if (msl_info->image[n] == (Image *) NULL)
4160 {
cristyb988fe72009-09-16 01:01:10 +00004161 ThrowMSLException(OptionError,"NoImagesDefined",
4162 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004163 break;
4164 }
4165 if (attributes != (const xmlChar **) NULL)
4166 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4167 {
4168 keyword=(const char *) attributes[i++];
4169 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004170 msl_info->attributes[n],(const char *) attributes[i],
4171 &exception);
cristy3ed852e2009-09-05 21:47:34 +00004172 CloneString(&value,attribute);
4173 switch (*keyword)
4174 {
4175 case 'G':
4176 case 'g':
4177 {
4178 if (LocaleCompare(keyword,"geometry") == 0)
4179 {
4180 flags=ParseGeometry(value,&geometry_info);
4181 if ((flags & SigmaValue) == 0)
4182 geometry_info.sigma=1.0;
4183 break;
4184 }
4185 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4186 keyword);
4187 break;
4188 }
4189 case 'R':
4190 case 'r':
4191 {
4192 if (LocaleCompare(keyword,"radius") == 0)
4193 {
cristyc1acd842011-05-19 23:05:47 +00004194 geometry_info.rho=InterpretLocaleValue(value,
4195 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004196 break;
4197 }
4198 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4199 keyword);
4200 break;
4201 }
4202 default:
4203 {
4204 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4205 keyword);
4206 break;
4207 }
4208 }
4209 }
4210 paint_image=OilPaintImage(msl_info->image[n],geometry_info.rho,
cristy14973ba2011-08-27 23:48:07 +00004211 geometry_info.sigma,&msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00004212 if (paint_image == (Image *) NULL)
4213 break;
4214 msl_info->image[n]=DestroyImage(msl_info->image[n]);
4215 msl_info->image[n]=paint_image;
4216 break;
4217 }
cristyb988fe72009-09-16 01:01:10 +00004218 if (LocaleCompare((const char *) tag,"opaque") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004219 {
cristy4c08aed2011-07-01 19:47:50 +00004220 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00004221 fill_color,
4222 target;
4223
4224 /*
4225 Opaque image.
4226 */
4227 if (msl_info->image[n] == (Image *) NULL)
4228 {
cristyb988fe72009-09-16 01:01:10 +00004229 ThrowMSLException(OptionError,"NoImagesDefined",
4230 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004231 break;
4232 }
4233 (void) QueryMagickColor("none",&target,&exception);
4234 (void) QueryMagickColor("none",&fill_color,&exception);
4235 if (attributes != (const xmlChar **) NULL)
4236 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4237 {
4238 keyword=(const char *) attributes[i++];
4239 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004240 msl_info->attributes[n],(const char *) attributes[i],
4241 &exception);
cristy3ed852e2009-09-05 21:47:34 +00004242 CloneString(&value,attribute);
4243 switch (*keyword)
4244 {
4245 case 'C':
4246 case 'c':
4247 {
4248 if (LocaleCompare(keyword,"channel") == 0)
4249 {
4250 option=ParseChannelOption(value);
4251 if (option < 0)
4252 ThrowMSLException(OptionError,"UnrecognizedChannelType",
4253 value);
4254 channel=(ChannelType) option;
4255 break;
4256 }
4257 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4258 keyword);
4259 break;
4260 }
4261 case 'F':
4262 case 'f':
4263 {
4264 if (LocaleCompare(keyword,"fill") == 0)
4265 {
4266 (void) QueryMagickColor(value,&fill_color,&exception);
4267 break;
4268 }
4269 if (LocaleCompare(keyword,"fuzz") == 0)
4270 {
cristyc1acd842011-05-19 23:05:47 +00004271 msl_info->image[n]->fuzz=InterpretLocaleValue(value,
4272 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004273 break;
4274 }
4275 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4276 keyword);
4277 break;
4278 }
4279 default:
4280 {
4281 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4282 keyword);
4283 break;
4284 }
4285 }
4286 }
cristybd5a96c2011-08-21 00:04:26 +00004287 channel_mask=SetPixelChannelMask(msl_info->image[n],channel);
cristyd42d9952011-07-08 14:21:50 +00004288 (void) OpaquePaintImage(msl_info->image[n],&target,&fill_color,
cristy189e84c2011-08-27 18:08:53 +00004289 MagickFalse,&msl_info->image[n]->exception);
cristybd5a96c2011-08-21 00:04:26 +00004290 (void) SetPixelChannelMap(msl_info->image[n],channel_mask);
cristy3ed852e2009-09-05 21:47:34 +00004291 break;
4292 }
4293 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4294 }
4295 case 'P':
4296 case 'p':
4297 {
cristyb988fe72009-09-16 01:01:10 +00004298 if (LocaleCompare((const char *) tag,"print") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004299 {
4300 if (attributes == (const xmlChar **) NULL)
4301 break;
4302 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4303 {
4304 keyword=(const char *) attributes[i++];
4305 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004306 msl_info->attributes[n],(const char *) attributes[i],
4307 &exception);
cristy3ed852e2009-09-05 21:47:34 +00004308 CloneString(&value,attribute);
4309 switch (*keyword)
4310 {
4311 case 'O':
4312 case 'o':
4313 {
4314 if (LocaleCompare(keyword,"output") == 0)
4315 {
cristyb51dff52011-05-19 16:55:47 +00004316 (void) FormatLocaleFile(stdout,"%s",value);
cristy3ed852e2009-09-05 21:47:34 +00004317 break;
4318 }
4319 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
4320 break;
4321 }
4322 default:
4323 {
4324 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
4325 break;
4326 }
4327 }
4328 }
4329 break;
4330 }
cristy4fa36e42009-09-18 14:24:06 +00004331 if (LocaleCompare((const char *) tag, "profile") == 0)
4332 {
cristy4fa36e42009-09-18 14:24:06 +00004333 if (msl_info->image[n] == (Image *) NULL)
4334 {
4335 ThrowMSLException(OptionError,"NoImagesDefined",
4336 (const char *) tag);
4337 break;
4338 }
4339 if (attributes == (const xmlChar **) NULL)
4340 break;
4341 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4342 {
4343 const char
4344 *name;
4345
4346 const StringInfo
4347 *profile;
4348
4349 Image
4350 *profile_image;
4351
4352 ImageInfo
4353 *profile_info;
4354
4355 keyword=(const char *) attributes[i++];
4356 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004357 msl_info->attributes[n],(const char *) attributes[i],
4358 &exception);
cristy4fa36e42009-09-18 14:24:06 +00004359 CloneString(&value,attribute);
4360 if (*keyword == '+')
4361 {
4362 /*
4363 Remove a profile from the image.
4364 */
4365 (void) ProfileImage(msl_info->image[n],keyword,
4366 (const unsigned char *) NULL,0,MagickTrue);
4367 continue;
4368 }
4369 /*
4370 Associate a profile with the image.
4371 */
4372 profile_info=CloneImageInfo(msl_info->image_info[n]);
4373 profile=GetImageProfile(msl_info->image[n],"iptc");
4374 if (profile != (StringInfo *) NULL)
4375 profile_info->profile=(void *) CloneStringInfo(profile);
4376 profile_image=GetImageCache(profile_info,keyword,&exception);
4377 profile_info=DestroyImageInfo(profile_info);
4378 if (profile_image == (Image *) NULL)
4379 {
4380 char
4381 name[MaxTextExtent],
4382 filename[MaxTextExtent];
4383
4384 register char
4385 *p;
4386
4387 StringInfo
4388 *profile;
4389
4390 (void) CopyMagickString(filename,keyword,MaxTextExtent);
4391 (void) CopyMagickString(name,keyword,MaxTextExtent);
4392 for (p=filename; *p != '\0'; p++)
4393 if ((*p == ':') && (IsPathDirectory(keyword) < 0) &&
4394 (IsPathAccessible(keyword) == MagickFalse))
4395 {
4396 register char
4397 *q;
4398
4399 /*
4400 Look for profile name (e.g. name:profile).
4401 */
4402 (void) CopyMagickString(name,filename,(size_t)
4403 (p-filename+1));
4404 for (q=filename; *q != '\0'; q++)
4405 *q=(*++p);
4406 break;
4407 }
4408 profile=FileToStringInfo(filename,~0UL,&exception);
4409 if (profile != (StringInfo *) NULL)
4410 {
4411 (void) ProfileImage(msl_info->image[n],name,
cristybb503372010-05-27 20:51:26 +00004412 GetStringInfoDatum(profile),(size_t)
cristy4fa36e42009-09-18 14:24:06 +00004413 GetStringInfoLength(profile),MagickFalse);
4414 profile=DestroyStringInfo(profile);
4415 }
4416 continue;
4417 }
4418 ResetImageProfileIterator(profile_image);
4419 name=GetNextImageProfile(profile_image);
4420 while (name != (const char *) NULL)
4421 {
4422 profile=GetImageProfile(profile_image,name);
4423 if (profile != (StringInfo *) NULL)
4424 (void) ProfileImage(msl_info->image[n],name,
cristybb503372010-05-27 20:51:26 +00004425 GetStringInfoDatum(profile),(size_t)
cristy4fa36e42009-09-18 14:24:06 +00004426 GetStringInfoLength(profile),MagickFalse);
4427 name=GetNextImageProfile(profile_image);
4428 }
4429 profile_image=DestroyImage(profile_image);
4430 }
4431 break;
4432 }
cristy3ed852e2009-09-05 21:47:34 +00004433 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4434 }
4435 case 'Q':
4436 case 'q':
4437 {
cristyb988fe72009-09-16 01:01:10 +00004438 if (LocaleCompare((const char *) tag,"quantize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004439 {
4440 QuantizeInfo
4441 quantize_info;
4442
4443 /*
4444 Quantize image.
4445 */
4446 if (msl_info->image[n] == (Image *) NULL)
4447 {
cristyb988fe72009-09-16 01:01:10 +00004448 ThrowMSLException(OptionError,"NoImagesDefined",
4449 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004450 break;
4451 }
4452 GetQuantizeInfo(&quantize_info);
4453 if (attributes != (const xmlChar **) NULL)
4454 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4455 {
4456 keyword=(const char *) attributes[i++];
4457 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004458 msl_info->attributes[n],(const char *) attributes[i],
4459 &exception);
cristy3ed852e2009-09-05 21:47:34 +00004460 CloneString(&value,attribute);
4461 switch (*keyword)
4462 {
4463 case 'C':
4464 case 'c':
4465 {
4466 if (LocaleCompare(keyword,"colors") == 0)
4467 {
cristyf2f27272009-12-17 14:48:46 +00004468 quantize_info.number_colors=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004469 break;
4470 }
4471 if (LocaleCompare(keyword,"colorspace") == 0)
4472 {
cristy042ee782011-04-22 18:48:30 +00004473 option=ParseCommandOption(MagickColorspaceOptions,
cristy3ed852e2009-09-05 21:47:34 +00004474 MagickFalse,value);
4475 if (option < 0)
4476 ThrowMSLException(OptionError,
4477 "UnrecognizedColorspaceType",value);
4478 quantize_info.colorspace=(ColorspaceType) option;
4479 break;
4480 }
4481 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4482 keyword);
4483 break;
4484 }
4485 case 'D':
4486 case 'd':
4487 {
4488 if (LocaleCompare(keyword,"dither") == 0)
4489 {
cristy042ee782011-04-22 18:48:30 +00004490 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004491 value);
4492 if (option < 0)
4493 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4494 value);
4495 quantize_info.dither=(MagickBooleanType) option;
4496 break;
4497 }
4498 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4499 keyword);
4500 break;
4501 }
4502 case 'M':
4503 case 'm':
4504 {
4505 if (LocaleCompare(keyword,"measure") == 0)
4506 {
cristy042ee782011-04-22 18:48:30 +00004507 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004508 value);
4509 if (option < 0)
4510 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4511 value);
4512 quantize_info.measure_error=(MagickBooleanType) option;
4513 break;
4514 }
4515 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4516 keyword);
4517 break;
4518 }
4519 case 'T':
4520 case 't':
4521 {
4522 if (LocaleCompare(keyword,"treedepth") == 0)
4523 {
cristyf2f27272009-12-17 14:48:46 +00004524 quantize_info.tree_depth=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004525 break;
4526 }
4527 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4528 keyword);
4529 break;
4530 }
4531 default:
4532 {
4533 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4534 keyword);
4535 break;
4536 }
4537 }
4538 }
cristy018f07f2011-09-04 21:15:19 +00004539 (void) QuantizeImage(&quantize_info,msl_info->image[n],&exception);
cristy3ed852e2009-09-05 21:47:34 +00004540 break;
4541 }
cristyb988fe72009-09-16 01:01:10 +00004542 if (LocaleCompare((const char *) tag,"query-font-metrics") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004543 {
4544 char
4545 text[MaxTextExtent];
4546
4547 MagickBooleanType
4548 status;
4549
4550 TypeMetric
4551 metrics;
4552
4553 /*
4554 Query font metrics.
4555 */
4556 draw_info=CloneDrawInfo(msl_info->image_info[n],
4557 msl_info->draw_info[n]);
4558 angle=0.0;
4559 current=draw_info->affine;
4560 GetAffineMatrix(&affine);
4561 if (attributes != (const xmlChar **) NULL)
4562 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4563 {
4564 keyword=(const char *) attributes[i++];
4565 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004566 msl_info->attributes[n],(const char *) attributes[i],
4567 &exception);
cristy3ed852e2009-09-05 21:47:34 +00004568 CloneString(&value,attribute);
4569 switch (*keyword)
4570 {
4571 case 'A':
4572 case 'a':
4573 {
4574 if (LocaleCompare(keyword,"affine") == 0)
4575 {
4576 char
4577 *p;
4578
4579 p=value;
cristyc1acd842011-05-19 23:05:47 +00004580 draw_info->affine.sx=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004581 if (*p ==',')
4582 p++;
cristyc1acd842011-05-19 23:05:47 +00004583 draw_info->affine.rx=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004584 if (*p ==',')
4585 p++;
cristyc1acd842011-05-19 23:05:47 +00004586 draw_info->affine.ry=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004587 if (*p ==',')
4588 p++;
cristyc1acd842011-05-19 23:05:47 +00004589 draw_info->affine.sy=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004590 if (*p ==',')
4591 p++;
cristyc1acd842011-05-19 23:05:47 +00004592 draw_info->affine.tx=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004593 if (*p ==',')
4594 p++;
cristyc1acd842011-05-19 23:05:47 +00004595 draw_info->affine.ty=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004596 break;
4597 }
4598 if (LocaleCompare(keyword,"align") == 0)
4599 {
cristy042ee782011-04-22 18:48:30 +00004600 option=ParseCommandOption(MagickAlignOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004601 value);
4602 if (option < 0)
4603 ThrowMSLException(OptionError,"UnrecognizedAlignType",
4604 value);
4605 draw_info->align=(AlignType) option;
4606 break;
4607 }
4608 if (LocaleCompare(keyword,"antialias") == 0)
4609 {
cristy042ee782011-04-22 18:48:30 +00004610 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004611 value);
4612 if (option < 0)
4613 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4614 value);
4615 draw_info->stroke_antialias=(MagickBooleanType) option;
4616 draw_info->text_antialias=(MagickBooleanType) option;
4617 break;
4618 }
4619 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4620 keyword);
4621 break;
4622 }
4623 case 'D':
4624 case 'd':
4625 {
4626 if (LocaleCompare(keyword,"density") == 0)
4627 {
4628 CloneString(&draw_info->density,value);
4629 break;
4630 }
4631 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4632 keyword);
4633 break;
4634 }
4635 case 'E':
4636 case 'e':
4637 {
4638 if (LocaleCompare(keyword,"encoding") == 0)
4639 {
4640 CloneString(&draw_info->encoding,value);
4641 break;
4642 }
4643 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4644 keyword);
4645 break;
4646 }
4647 case 'F':
4648 case 'f':
4649 {
4650 if (LocaleCompare(keyword, "fill") == 0)
4651 {
4652 (void) QueryColorDatabase(value,&draw_info->fill,
4653 &exception);
4654 break;
4655 }
4656 if (LocaleCompare(keyword,"family") == 0)
4657 {
4658 CloneString(&draw_info->family,value);
4659 break;
4660 }
4661 if (LocaleCompare(keyword,"font") == 0)
4662 {
4663 CloneString(&draw_info->font,value);
4664 break;
4665 }
4666 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4667 keyword);
4668 break;
4669 }
4670 case 'G':
4671 case 'g':
4672 {
4673 if (LocaleCompare(keyword,"geometry") == 0)
4674 {
4675 flags=ParsePageGeometry(msl_info->image[n],value,
4676 &geometry,&exception);
4677 if ((flags & HeightValue) == 0)
4678 geometry.height=geometry.width;
4679 break;
4680 }
4681 if (LocaleCompare(keyword,"gravity") == 0)
4682 {
cristy042ee782011-04-22 18:48:30 +00004683 option=ParseCommandOption(MagickGravityOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004684 value);
4685 if (option < 0)
4686 ThrowMSLException(OptionError,"UnrecognizedGravityType",
4687 value);
4688 draw_info->gravity=(GravityType) option;
4689 break;
4690 }
4691 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4692 keyword);
4693 break;
4694 }
4695 case 'P':
4696 case 'p':
4697 {
4698 if (LocaleCompare(keyword,"pointsize") == 0)
4699 {
cristyc1acd842011-05-19 23:05:47 +00004700 draw_info->pointsize=InterpretLocaleValue(value,
4701 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004702 break;
4703 }
4704 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4705 keyword);
4706 break;
4707 }
4708 case 'R':
4709 case 'r':
4710 {
4711 if (LocaleCompare(keyword,"rotate") == 0)
4712 {
cristyc1acd842011-05-19 23:05:47 +00004713 angle=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004714 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
4715 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
4716 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
4717 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
4718 break;
4719 }
4720 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4721 keyword);
4722 break;
4723 }
4724 case 'S':
4725 case 's':
4726 {
4727 if (LocaleCompare(keyword,"scale") == 0)
4728 {
4729 flags=ParseGeometry(value,&geometry_info);
4730 if ((flags & SigmaValue) == 0)
4731 geometry_info.sigma=1.0;
4732 affine.sx=geometry_info.rho;
4733 affine.sy=geometry_info.sigma;
4734 break;
4735 }
4736 if (LocaleCompare(keyword,"skewX") == 0)
4737 {
cristyc1acd842011-05-19 23:05:47 +00004738 angle=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004739 affine.ry=cos(DegreesToRadians(fmod(angle,360.0)));
4740 break;
4741 }
4742 if (LocaleCompare(keyword,"skewY") == 0)
4743 {
cristyc1acd842011-05-19 23:05:47 +00004744 angle=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004745 affine.rx=cos(DegreesToRadians(fmod(angle,360.0)));
4746 break;
4747 }
4748 if (LocaleCompare(keyword,"stretch") == 0)
4749 {
cristy042ee782011-04-22 18:48:30 +00004750 option=ParseCommandOption(MagickStretchOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004751 value);
4752 if (option < 0)
4753 ThrowMSLException(OptionError,"UnrecognizedStretchType",
4754 value);
4755 draw_info->stretch=(StretchType) option;
4756 break;
4757 }
4758 if (LocaleCompare(keyword, "stroke") == 0)
4759 {
4760 (void) QueryColorDatabase(value,&draw_info->stroke,
4761 &exception);
4762 break;
4763 }
4764 if (LocaleCompare(keyword,"strokewidth") == 0)
4765 {
cristyf2f27272009-12-17 14:48:46 +00004766 draw_info->stroke_width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004767 break;
4768 }
4769 if (LocaleCompare(keyword,"style") == 0)
4770 {
cristy042ee782011-04-22 18:48:30 +00004771 option=ParseCommandOption(MagickStyleOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004772 value);
4773 if (option < 0)
4774 ThrowMSLException(OptionError,"UnrecognizedStyleType",
4775 value);
4776 draw_info->style=(StyleType) option;
4777 break;
4778 }
4779 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4780 keyword);
4781 break;
4782 }
4783 case 'T':
4784 case 't':
4785 {
4786 if (LocaleCompare(keyword,"text") == 0)
4787 {
4788 CloneString(&draw_info->text,value);
4789 break;
4790 }
4791 if (LocaleCompare(keyword,"translate") == 0)
4792 {
4793 flags=ParseGeometry(value,&geometry_info);
4794 if ((flags & SigmaValue) == 0)
4795 geometry_info.sigma=1.0;
4796 affine.tx=geometry_info.rho;
4797 affine.ty=geometry_info.sigma;
4798 break;
4799 }
4800 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4801 keyword);
4802 break;
4803 }
4804 case 'U':
4805 case 'u':
4806 {
4807 if (LocaleCompare(keyword, "undercolor") == 0)
4808 {
4809 (void) QueryColorDatabase(value,&draw_info->undercolor,
4810 &exception);
4811 break;
4812 }
4813 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4814 keyword);
4815 break;
4816 }
4817 case 'W':
4818 case 'w':
4819 {
4820 if (LocaleCompare(keyword,"weight") == 0)
4821 {
cristyf2f27272009-12-17 14:48:46 +00004822 draw_info->weight=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004823 break;
4824 }
4825 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4826 keyword);
4827 break;
4828 }
4829 case 'X':
4830 case 'x':
4831 {
4832 if (LocaleCompare(keyword,"x") == 0)
4833 {
cristyf2f27272009-12-17 14:48:46 +00004834 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004835 break;
4836 }
4837 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4838 keyword);
4839 break;
4840 }
4841 case 'Y':
4842 case 'y':
4843 {
4844 if (LocaleCompare(keyword,"y") == 0)
4845 {
cristyf2f27272009-12-17 14:48:46 +00004846 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004847 break;
4848 }
4849 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4850 keyword);
4851 break;
4852 }
4853 default:
4854 {
4855 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4856 keyword);
4857 break;
4858 }
4859 }
4860 }
cristyb51dff52011-05-19 16:55:47 +00004861 (void) FormatLocaleString(text,MaxTextExtent,
cristye8c25f92010-06-03 00:53:06 +00004862 "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,(double)
4863 geometry.height,(double) geometry.x,(double) geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00004864 CloneString(&draw_info->geometry,text);
cristyef7c8a52010-10-10 13:46:51 +00004865 draw_info->affine.sx=affine.sx*current.sx+affine.ry*current.rx;
4866 draw_info->affine.rx=affine.rx*current.sx+affine.sy*current.rx;
4867 draw_info->affine.ry=affine.sx*current.ry+affine.ry*current.sy;
4868 draw_info->affine.sy=affine.rx*current.ry+affine.sy*current.sy;
4869 draw_info->affine.tx=affine.sx*current.tx+affine.ry*current.ty+
4870 affine.tx;
4871 draw_info->affine.ty=affine.rx*current.tx+affine.sy*current.ty+
4872 affine.ty;
cristy5cbc0162011-08-29 00:36:28 +00004873 status=GetTypeMetrics(msl_info->attributes[n],draw_info,&metrics,
4874 &msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00004875 if (status != MagickFalse)
4876 {
4877 Image
4878 *image;
4879
4880 image=msl_info->attributes[n];
cristy8cd5b312010-01-07 01:10:24 +00004881 FormatImageProperty(image,"msl:font-metrics.pixels_per_em.x",
cristye7f51092010-01-17 00:39:37 +00004882 "%g",metrics.pixels_per_em.x);
cristy8cd5b312010-01-07 01:10:24 +00004883 FormatImageProperty(image,"msl:font-metrics.pixels_per_em.y",
cristye7f51092010-01-17 00:39:37 +00004884 "%g",metrics.pixels_per_em.y);
4885 FormatImageProperty(image,"msl:font-metrics.ascent","%g",
cristy3ed852e2009-09-05 21:47:34 +00004886 metrics.ascent);
cristye7f51092010-01-17 00:39:37 +00004887 FormatImageProperty(image,"msl:font-metrics.descent","%g",
cristy3ed852e2009-09-05 21:47:34 +00004888 metrics.descent);
cristye7f51092010-01-17 00:39:37 +00004889 FormatImageProperty(image,"msl:font-metrics.width","%g",
cristy3ed852e2009-09-05 21:47:34 +00004890 metrics.width);
cristye7f51092010-01-17 00:39:37 +00004891 FormatImageProperty(image,"msl:font-metrics.height","%g",
cristy3ed852e2009-09-05 21:47:34 +00004892 metrics.height);
cristye7f51092010-01-17 00:39:37 +00004893 FormatImageProperty(image,"msl:font-metrics.max_advance","%g",
cristy3ed852e2009-09-05 21:47:34 +00004894 metrics.max_advance);
cristye7f51092010-01-17 00:39:37 +00004895 FormatImageProperty(image,"msl:font-metrics.bounds.x1","%g",
cristy3ed852e2009-09-05 21:47:34 +00004896 metrics.bounds.x1);
cristye7f51092010-01-17 00:39:37 +00004897 FormatImageProperty(image,"msl:font-metrics.bounds.y1","%g",
cristy3ed852e2009-09-05 21:47:34 +00004898 metrics.bounds.y1);
cristye7f51092010-01-17 00:39:37 +00004899 FormatImageProperty(image,"msl:font-metrics.bounds.x2","%g",
cristy3ed852e2009-09-05 21:47:34 +00004900 metrics.bounds.x2);
cristye7f51092010-01-17 00:39:37 +00004901 FormatImageProperty(image,"msl:font-metrics.bounds.y2","%g",
cristy3ed852e2009-09-05 21:47:34 +00004902 metrics.bounds.y2);
cristye7f51092010-01-17 00:39:37 +00004903 FormatImageProperty(image,"msl:font-metrics.origin.x","%g",
cristy3ed852e2009-09-05 21:47:34 +00004904 metrics.origin.x);
cristye7f51092010-01-17 00:39:37 +00004905 FormatImageProperty(image,"msl:font-metrics.origin.y","%g",
cristy3ed852e2009-09-05 21:47:34 +00004906 metrics.origin.y);
4907 }
4908 draw_info=DestroyDrawInfo(draw_info);
4909 break;
4910 }
4911 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4912 }
4913 case 'R':
4914 case 'r':
4915 {
cristyb988fe72009-09-16 01:01:10 +00004916 if (LocaleCompare((const char *) tag,"raise") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004917 {
4918 MagickBooleanType
4919 raise;
4920
4921 /*
4922 Raise image.
4923 */
4924 if (msl_info->image[n] == (Image *) NULL)
4925 {
cristyb988fe72009-09-16 01:01:10 +00004926 ThrowMSLException(OptionError,"NoImagesDefined",
4927 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004928 break;
4929 }
4930 raise=MagickFalse;
4931 SetGeometry(msl_info->image[n],&geometry);
4932 if (attributes != (const xmlChar **) NULL)
4933 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4934 {
4935 keyword=(const char *) attributes[i++];
4936 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004937 msl_info->attributes[n],(const char *) attributes[i],
4938 &exception);
cristy3ed852e2009-09-05 21:47:34 +00004939 CloneString(&value,attribute);
4940 switch (*keyword)
4941 {
4942 case 'G':
4943 case 'g':
4944 {
4945 if (LocaleCompare(keyword,"geometry") == 0)
4946 {
4947 flags=ParsePageGeometry(msl_info->image[n],value,
4948 &geometry,&exception);
4949 if ((flags & HeightValue) == 0)
4950 geometry.height=geometry.width;
4951 break;
4952 }
4953 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4954 keyword);
4955 break;
4956 }
4957 case 'H':
4958 case 'h':
4959 {
4960 if (LocaleCompare(keyword,"height") == 0)
4961 {
cristyf2f27272009-12-17 14:48:46 +00004962 geometry.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004963 break;
4964 }
4965 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4966 keyword);
4967 break;
4968 }
4969 case 'R':
4970 case 'r':
4971 {
4972 if (LocaleCompare(keyword,"raise") == 0)
4973 {
cristy042ee782011-04-22 18:48:30 +00004974 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004975 value);
4976 if (option < 0)
4977 ThrowMSLException(OptionError,"UnrecognizedNoiseType",
4978 value);
4979 raise=(MagickBooleanType) option;
4980 break;
4981 }
4982 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4983 keyword);
4984 break;
4985 }
4986 case 'W':
4987 case 'w':
4988 {
4989 if (LocaleCompare(keyword,"width") == 0)
4990 {
cristyf2f27272009-12-17 14:48:46 +00004991 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004992 break;
4993 }
4994 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4995 keyword);
4996 break;
4997 }
4998 default:
4999 {
5000 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5001 keyword);
5002 break;
5003 }
5004 }
5005 }
cristy6170ac32011-08-28 14:15:37 +00005006 (void) RaiseImage(msl_info->image[n],&geometry,raise,
5007 &msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00005008 break;
5009 }
cristyb988fe72009-09-16 01:01:10 +00005010 if (LocaleCompare((const char *) tag,"read") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005011 {
5012 if (attributes == (const xmlChar **) NULL)
5013 break;
5014 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5015 {
5016 keyword=(const char *) attributes[i++];
5017 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005018 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00005019 switch (*keyword)
5020 {
5021 case 'F':
5022 case 'f':
5023 {
5024 if (LocaleCompare(keyword,"filename") == 0)
5025 {
5026 Image
5027 *image;
5028
5029 (void) CopyMagickString(msl_info->image_info[n]->filename,
5030 value,MaxTextExtent);
5031 image=ReadImage(msl_info->image_info[n],&exception);
5032 CatchException(&exception);
5033 if (image == (Image *) NULL)
5034 continue;
5035 AppendImageToList(&msl_info->image[n],image);
5036 break;
5037 }
cristy4582cbb2009-09-23 00:35:43 +00005038 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00005039 break;
5040 }
5041 default:
5042 {
cristy4582cbb2009-09-23 00:35:43 +00005043 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00005044 break;
5045 }
5046 }
5047 }
5048 break;
5049 }
cristyb988fe72009-09-16 01:01:10 +00005050 if (LocaleCompare((const char *) tag,"reduce-noise") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005051 {
5052 Image
5053 *paint_image;
5054
5055 /*
5056 Reduce-noise image.
5057 */
5058 if (msl_info->image[n] == (Image *) NULL)
5059 {
cristyb988fe72009-09-16 01:01:10 +00005060 ThrowMSLException(OptionError,"NoImagesDefined",
5061 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005062 break;
5063 }
5064 if (attributes != (const xmlChar **) NULL)
5065 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5066 {
5067 keyword=(const char *) attributes[i++];
5068 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005069 msl_info->attributes[n],(const char *) attributes[i],
5070 &exception);
cristy3ed852e2009-09-05 21:47:34 +00005071 CloneString(&value,attribute);
5072 switch (*keyword)
5073 {
5074 case 'G':
5075 case 'g':
5076 {
5077 if (LocaleCompare(keyword,"geometry") == 0)
5078 {
5079 flags=ParseGeometry(value,&geometry_info);
5080 if ((flags & SigmaValue) == 0)
5081 geometry_info.sigma=1.0;
5082 break;
5083 }
5084 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5085 keyword);
5086 break;
5087 }
5088 case 'R':
5089 case 'r':
5090 {
5091 if (LocaleCompare(keyword,"radius") == 0)
5092 {
cristyc1acd842011-05-19 23:05:47 +00005093 geometry_info.rho=InterpretLocaleValue(value,
5094 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005095 break;
5096 }
5097 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5098 keyword);
5099 break;
5100 }
5101 default:
5102 {
5103 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5104 keyword);
5105 break;
5106 }
5107 }
5108 }
cristy733678d2011-03-18 21:29:28 +00005109 paint_image=StatisticImage(msl_info->image[n],NonpeakStatistic,
cristy95c38342011-03-18 22:39:51 +00005110 (size_t) geometry_info.rho,(size_t) geometry_info.sigma,
5111 &msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00005112 if (paint_image == (Image *) NULL)
5113 break;
5114 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5115 msl_info->image[n]=paint_image;
5116 break;
5117 }
cristyb988fe72009-09-16 01:01:10 +00005118 else if (LocaleCompare((const char *) tag,"repage") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005119 {
5120 /* init the values */
5121 width=msl_info->image[n]->page.width;
5122 height=msl_info->image[n]->page.height;
5123 x=msl_info->image[n]->page.x;
5124 y=msl_info->image[n]->page.y;
5125
5126 if (msl_info->image[n] == (Image *) NULL)
5127 {
cristyb988fe72009-09-16 01:01:10 +00005128 ThrowMSLException(OptionError,"NoImagesDefined",
5129 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005130 break;
5131 }
5132 if (attributes == (const xmlChar **) NULL)
5133 break;
5134 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5135 {
5136 keyword=(const char *) attributes[i++];
5137 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005138 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00005139 switch (*keyword)
5140 {
5141 case 'G':
5142 case 'g':
5143 {
5144 if (LocaleCompare(keyword,"geometry") == 0)
5145 {
5146 int
5147 flags;
5148
5149 RectangleInfo
5150 geometry;
5151
5152 flags=ParseAbsoluteGeometry(value,&geometry);
5153 if ((flags & WidthValue) != 0)
5154 {
5155 if ((flags & HeightValue) == 0)
5156 geometry.height=geometry.width;
5157 width=geometry.width;
5158 height=geometry.height;
5159 }
5160 if ((flags & AspectValue) != 0)
5161 {
5162 if ((flags & XValue) != 0)
5163 x+=geometry.x;
5164 if ((flags & YValue) != 0)
5165 y+=geometry.y;
5166 }
5167 else
5168 {
5169 if ((flags & XValue) != 0)
5170 {
5171 x=geometry.x;
5172 if ((width == 0) && (geometry.x > 0))
5173 width=msl_info->image[n]->columns+geometry.x;
5174 }
5175 if ((flags & YValue) != 0)
5176 {
5177 y=geometry.y;
5178 if ((height == 0) && (geometry.y > 0))
5179 height=msl_info->image[n]->rows+geometry.y;
5180 }
5181 }
5182 break;
5183 }
5184 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5185 break;
5186 }
5187 case 'H':
5188 case 'h':
5189 {
5190 if (LocaleCompare(keyword,"height") == 0)
5191 {
cristyf2f27272009-12-17 14:48:46 +00005192 height = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005193 break;
5194 }
5195 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5196 break;
5197 }
5198 case 'W':
5199 case 'w':
5200 {
5201 if (LocaleCompare(keyword,"width") == 0)
5202 {
cristyf2f27272009-12-17 14:48:46 +00005203 width = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005204 break;
5205 }
5206 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5207 break;
5208 }
5209 case 'X':
5210 case 'x':
5211 {
5212 if (LocaleCompare(keyword,"x") == 0)
5213 {
cristyf2f27272009-12-17 14:48:46 +00005214 x = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005215 break;
5216 }
5217 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5218 break;
5219 }
5220 case 'Y':
5221 case 'y':
5222 {
5223 if (LocaleCompare(keyword,"y") == 0)
5224 {
cristyf2f27272009-12-17 14:48:46 +00005225 y = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005226 break;
5227 }
5228 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5229 break;
5230 }
5231 default:
5232 {
5233 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5234 break;
5235 }
5236 }
5237 }
5238
cristyb988fe72009-09-16 01:01:10 +00005239 msl_info->image[n]->page.width=width;
5240 msl_info->image[n]->page.height=height;
5241 msl_info->image[n]->page.x=x;
5242 msl_info->image[n]->page.y=y;
cristy3ed852e2009-09-05 21:47:34 +00005243 break;
5244 }
cristyb988fe72009-09-16 01:01:10 +00005245 else if (LocaleCompare((const char *) tag,"resample") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005246 {
5247 double
5248 x_resolution,
5249 y_resolution;
5250
5251 if (msl_info->image[n] == (Image *) NULL)
5252 {
cristyb988fe72009-09-16 01:01:10 +00005253 ThrowMSLException(OptionError,"NoImagesDefined",
5254 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005255 break;
5256 }
5257 if (attributes == (const xmlChar **) NULL)
5258 break;
5259 x_resolution=DefaultResolution;
5260 y_resolution=DefaultResolution;
5261 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5262 {
5263 keyword=(const char *) attributes[i++];
5264 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005265 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00005266 switch (*keyword)
5267 {
5268 case 'b':
5269 {
5270 if (LocaleCompare(keyword,"blur") == 0)
5271 {
cristyc1acd842011-05-19 23:05:47 +00005272 msl_info->image[n]->blur=InterpretLocaleValue(value,
5273 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005274 break;
5275 }
5276 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5277 break;
5278 }
5279 case 'G':
5280 case 'g':
5281 {
5282 if (LocaleCompare(keyword,"geometry") == 0)
5283 {
cristybb503372010-05-27 20:51:26 +00005284 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00005285 flags;
5286
5287 flags=ParseGeometry(value,&geometry_info);
5288 if ((flags & SigmaValue) == 0)
5289 geometry_info.sigma*=geometry_info.rho;
5290 x_resolution=geometry_info.rho;
5291 y_resolution=geometry_info.sigma;
5292 break;
5293 }
5294 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5295 break;
5296 }
5297 case 'X':
5298 case 'x':
5299 {
5300 if (LocaleCompare(keyword,"x-resolution") == 0)
5301 {
cristyc1acd842011-05-19 23:05:47 +00005302 x_resolution=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005303 break;
5304 }
5305 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5306 break;
5307 }
5308 case 'Y':
5309 case 'y':
5310 {
5311 if (LocaleCompare(keyword,"y-resolution") == 0)
5312 {
cristyc1acd842011-05-19 23:05:47 +00005313 y_resolution=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005314 break;
5315 }
5316 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5317 break;
5318 }
5319 default:
5320 {
5321 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5322 break;
5323 }
5324 }
5325 }
5326 /*
5327 Resample image.
5328 */
5329 {
5330 double
5331 factor;
5332
5333 Image
5334 *resample_image;
5335
5336 factor=1.0;
5337 if (msl_info->image[n]->units == PixelsPerCentimeterResolution)
5338 factor=2.54;
cristybb503372010-05-27 20:51:26 +00005339 width=(size_t) (x_resolution*msl_info->image[n]->columns/
cristy3ed852e2009-09-05 21:47:34 +00005340 (factor*(msl_info->image[n]->x_resolution == 0.0 ? DefaultResolution :
5341 msl_info->image[n]->x_resolution))+0.5);
cristybb503372010-05-27 20:51:26 +00005342 height=(size_t) (y_resolution*msl_info->image[n]->rows/
cristy3ed852e2009-09-05 21:47:34 +00005343 (factor*(msl_info->image[n]->y_resolution == 0.0 ? DefaultResolution :
5344 msl_info->image[n]->y_resolution))+0.5);
5345 resample_image=ResizeImage(msl_info->image[n],width,height,
5346 msl_info->image[n]->filter,msl_info->image[n]->blur,
5347 &msl_info->image[n]->exception);
5348 if (resample_image == (Image *) NULL)
5349 break;
5350 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5351 msl_info->image[n]=resample_image;
5352 }
5353 break;
5354 }
cristyb988fe72009-09-16 01:01:10 +00005355 if (LocaleCompare((const char *) tag,"resize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005356 {
5357 double
5358 blur;
5359
5360 FilterTypes
5361 filter;
5362
5363 Image
5364 *resize_image;
5365
5366 /*
5367 Resize image.
5368 */
5369 if (msl_info->image[n] == (Image *) NULL)
5370 {
cristyb988fe72009-09-16 01:01:10 +00005371 ThrowMSLException(OptionError,"NoImagesDefined",
5372 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005373 break;
5374 }
5375 filter=UndefinedFilter;
5376 blur=1.0;
5377 if (attributes != (const xmlChar **) NULL)
5378 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5379 {
5380 keyword=(const char *) attributes[i++];
5381 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005382 msl_info->attributes[n],(const char *) attributes[i],
5383 &exception);
cristy3ed852e2009-09-05 21:47:34 +00005384 CloneString(&value,attribute);
5385 switch (*keyword)
5386 {
5387 case 'F':
5388 case 'f':
5389 {
5390 if (LocaleCompare(keyword,"filter") == 0)
5391 {
cristy042ee782011-04-22 18:48:30 +00005392 option=ParseCommandOption(MagickFilterOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00005393 value);
5394 if (option < 0)
5395 ThrowMSLException(OptionError,"UnrecognizedNoiseType",
5396 value);
5397 filter=(FilterTypes) option;
5398 break;
5399 }
5400 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5401 keyword);
5402 break;
5403 }
5404 case 'G':
5405 case 'g':
5406 {
5407 if (LocaleCompare(keyword,"geometry") == 0)
5408 {
5409 flags=ParseRegionGeometry(msl_info->image[n],value,
5410 &geometry,&exception);
5411 break;
5412 }
5413 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5414 keyword);
5415 break;
5416 }
5417 case 'H':
5418 case 'h':
5419 {
5420 if (LocaleCompare(keyword,"height") == 0)
5421 {
cristye27293e2009-12-18 02:53:20 +00005422 geometry.height=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005423 break;
5424 }
5425 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5426 keyword);
5427 break;
5428 }
5429 case 'S':
5430 case 's':
5431 {
5432 if (LocaleCompare(keyword,"support") == 0)
5433 {
cristyc1acd842011-05-19 23:05:47 +00005434 blur=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005435 break;
5436 }
5437 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5438 keyword);
5439 break;
5440 }
5441 case 'W':
5442 case 'w':
5443 {
5444 if (LocaleCompare(keyword,"width") == 0)
5445 {
cristyf2f27272009-12-17 14:48:46 +00005446 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005447 break;
5448 }
5449 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5450 keyword);
5451 break;
5452 }
5453 default:
5454 {
5455 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5456 keyword);
5457 break;
5458 }
5459 }
5460 }
5461 resize_image=ResizeImage(msl_info->image[n],geometry.width,
5462 geometry.height,filter,blur,&msl_info->image[n]->exception);
5463 if (resize_image == (Image *) NULL)
5464 break;
5465 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5466 msl_info->image[n]=resize_image;
5467 break;
5468 }
cristyb988fe72009-09-16 01:01:10 +00005469 if (LocaleCompare((const char *) tag,"roll") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005470 {
5471 Image
5472 *roll_image;
5473
5474 /*
5475 Roll image.
5476 */
5477 if (msl_info->image[n] == (Image *) NULL)
5478 {
cristyb988fe72009-09-16 01:01:10 +00005479 ThrowMSLException(OptionError,"NoImagesDefined",
5480 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005481 break;
5482 }
5483 SetGeometry(msl_info->image[n],&geometry);
5484 if (attributes != (const xmlChar **) NULL)
5485 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5486 {
5487 keyword=(const char *) attributes[i++];
5488 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005489 msl_info->attributes[n],(const char *) attributes[i],
5490 &exception);
cristy3ed852e2009-09-05 21:47:34 +00005491 CloneString(&value,attribute);
5492 switch (*keyword)
5493 {
5494 case 'G':
5495 case 'g':
5496 {
5497 if (LocaleCompare(keyword,"geometry") == 0)
5498 {
5499 flags=ParsePageGeometry(msl_info->image[n],value,
5500 &geometry,&exception);
5501 if ((flags & HeightValue) == 0)
5502 geometry.height=geometry.width;
5503 break;
5504 }
5505 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5506 keyword);
5507 break;
5508 }
5509 case 'X':
5510 case 'x':
5511 {
5512 if (LocaleCompare(keyword,"x") == 0)
5513 {
cristyf2f27272009-12-17 14:48:46 +00005514 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005515 break;
5516 }
5517 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5518 keyword);
5519 break;
5520 }
5521 case 'Y':
5522 case 'y':
5523 {
5524 if (LocaleCompare(keyword,"y") == 0)
5525 {
cristyf2f27272009-12-17 14:48:46 +00005526 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005527 break;
5528 }
5529 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5530 keyword);
5531 break;
5532 }
5533 default:
5534 {
5535 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5536 keyword);
5537 break;
5538 }
5539 }
5540 }
5541 roll_image=RollImage(msl_info->image[n],geometry.x,geometry.y,
5542 &msl_info->image[n]->exception);
5543 if (roll_image == (Image *) NULL)
5544 break;
5545 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5546 msl_info->image[n]=roll_image;
5547 break;
5548 }
cristyb988fe72009-09-16 01:01:10 +00005549 else if (LocaleCompare((const char *) tag,"roll") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005550 {
5551 /* init the values */
5552 width=msl_info->image[n]->columns;
5553 height=msl_info->image[n]->rows;
5554 x = y = 0;
5555
5556 if (msl_info->image[n] == (Image *) NULL)
5557 {
cristyb988fe72009-09-16 01:01:10 +00005558 ThrowMSLException(OptionError,"NoImagesDefined",
5559 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005560 break;
5561 }
5562 if (attributes == (const xmlChar **) NULL)
5563 break;
5564 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5565 {
5566 keyword=(const char *) attributes[i++];
5567 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005568 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00005569 switch (*keyword)
5570 {
5571 case 'G':
5572 case 'g':
5573 {
5574 if (LocaleCompare(keyword,"geometry") == 0)
5575 {
5576 (void) ParseMetaGeometry(value,&x,&y,&width,&height);
5577 break;
5578 }
5579 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5580 break;
5581 }
5582 case 'X':
5583 case 'x':
5584 {
5585 if (LocaleCompare(keyword,"x") == 0)
5586 {
cristyf2f27272009-12-17 14:48:46 +00005587 x = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005588 break;
5589 }
5590 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5591 break;
5592 }
5593 case 'Y':
5594 case 'y':
5595 {
5596 if (LocaleCompare(keyword,"y") == 0)
5597 {
cristyf2f27272009-12-17 14:48:46 +00005598 y = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005599 break;
5600 }
5601 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5602 break;
5603 }
5604 default:
5605 {
5606 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5607 break;
5608 }
5609 }
5610 }
5611
5612 /*
5613 process image.
5614 */
5615 {
5616 Image
5617 *newImage;
5618
5619 newImage=RollImage(msl_info->image[n], x, y, &msl_info->image[n]->exception);
5620 if (newImage == (Image *) NULL)
5621 break;
5622 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5623 msl_info->image[n]=newImage;
5624 }
5625
5626 break;
5627 }
cristyb988fe72009-09-16 01:01:10 +00005628 if (LocaleCompare((const char *) tag,"rotate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005629 {
5630 Image
5631 *rotate_image;
5632
5633 /*
5634 Rotate image.
5635 */
5636 if (msl_info->image[n] == (Image *) NULL)
5637 {
cristyb988fe72009-09-16 01:01:10 +00005638 ThrowMSLException(OptionError,"NoImagesDefined",
5639 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005640 break;
5641 }
5642 if (attributes != (const xmlChar **) NULL)
5643 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5644 {
5645 keyword=(const char *) attributes[i++];
5646 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005647 msl_info->attributes[n],(const char *) attributes[i],
5648 &exception);
cristy3ed852e2009-09-05 21:47:34 +00005649 CloneString(&value,attribute);
5650 switch (*keyword)
5651 {
5652 case 'D':
5653 case 'd':
5654 {
5655 if (LocaleCompare(keyword,"degrees") == 0)
5656 {
cristyc1acd842011-05-19 23:05:47 +00005657 geometry_info.rho=InterpretLocaleValue(value,
5658 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005659 break;
5660 }
5661 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5662 keyword);
5663 break;
5664 }
5665 case 'G':
5666 case 'g':
5667 {
5668 if (LocaleCompare(keyword,"geometry") == 0)
5669 {
5670 flags=ParseGeometry(value,&geometry_info);
5671 if ((flags & SigmaValue) == 0)
5672 geometry_info.sigma=1.0;
5673 break;
5674 }
5675 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5676 keyword);
5677 break;
5678 }
5679 default:
5680 {
5681 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5682 keyword);
5683 break;
5684 }
5685 }
5686 }
5687 rotate_image=RotateImage(msl_info->image[n],geometry_info.rho,
5688 &msl_info->image[n]->exception);
5689 if (rotate_image == (Image *) NULL)
5690 break;
5691 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5692 msl_info->image[n]=rotate_image;
5693 break;
5694 }
cristyb988fe72009-09-16 01:01:10 +00005695 else if (LocaleCompare((const char *) tag,"rotate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005696 {
5697 /* init the values */
5698 double degrees = 0;
5699
5700 if (msl_info->image[n] == (Image *) NULL)
5701 {
cristyb988fe72009-09-16 01:01:10 +00005702 ThrowMSLException(OptionError,"NoImagesDefined",
5703 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005704 break;
5705 }
5706 if (attributes == (const xmlChar **) NULL)
cristy31939262009-09-15 00:23:11 +00005707 break;
cristy3ed852e2009-09-05 21:47:34 +00005708 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5709 {
5710 keyword=(const char *) attributes[i++];
5711 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005712 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00005713 switch (*keyword)
5714 {
5715 case 'D':
5716 case 'd':
5717 {
5718 if (LocaleCompare(keyword,"degrees") == 0)
5719 {
cristyc1acd842011-05-19 23:05:47 +00005720 degrees = InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005721 break;
5722 }
5723 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5724 break;
5725 }
5726 default:
5727 {
5728 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5729 break;
5730 }
5731 }
5732 }
5733
5734 /*
5735 process image.
5736 */
5737 {
5738 Image
5739 *newImage;
5740
5741 newImage=RotateImage(msl_info->image[n], degrees, &msl_info->image[n]->exception);
5742 if (newImage == (Image *) NULL)
5743 break;
5744 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5745 msl_info->image[n]=newImage;
5746 }
5747
5748 break;
5749 }
5750 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
5751 }
5752 case 'S':
5753 case 's':
5754 {
cristyb988fe72009-09-16 01:01:10 +00005755 if (LocaleCompare((const char *) tag,"sample") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005756 {
5757 Image
5758 *sample_image;
5759
5760 /*
5761 Sample image.
5762 */
5763 if (msl_info->image[n] == (Image *) NULL)
5764 {
cristyb988fe72009-09-16 01:01:10 +00005765 ThrowMSLException(OptionError,"NoImagesDefined",
5766 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005767 break;
5768 }
5769 if (attributes != (const xmlChar **) NULL)
5770 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5771 {
5772 keyword=(const char *) attributes[i++];
5773 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005774 msl_info->attributes[n],(const char *) attributes[i],
5775 &exception);
cristy3ed852e2009-09-05 21:47:34 +00005776 CloneString(&value,attribute);
5777 switch (*keyword)
5778 {
5779 case 'G':
5780 case 'g':
5781 {
5782 if (LocaleCompare(keyword,"geometry") == 0)
5783 {
5784 flags=ParseRegionGeometry(msl_info->image[n],value,
5785 &geometry,&exception);
5786 break;
5787 }
5788 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5789 keyword);
5790 break;
5791 }
5792 case 'H':
5793 case 'h':
5794 {
5795 if (LocaleCompare(keyword,"height") == 0)
5796 {
cristye27293e2009-12-18 02:53:20 +00005797 geometry.height=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005798 break;
5799 }
5800 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5801 keyword);
5802 break;
5803 }
5804 case 'W':
5805 case 'w':
5806 {
5807 if (LocaleCompare(keyword,"width") == 0)
5808 {
cristyf2f27272009-12-17 14:48:46 +00005809 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005810 break;
5811 }
5812 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5813 keyword);
5814 break;
5815 }
5816 default:
5817 {
5818 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5819 keyword);
5820 break;
5821 }
5822 }
5823 }
5824 sample_image=SampleImage(msl_info->image[n],geometry.width,
5825 geometry.height,&msl_info->image[n]->exception);
5826 if (sample_image == (Image *) NULL)
5827 break;
5828 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5829 msl_info->image[n]=sample_image;
5830 break;
5831 }
cristyb988fe72009-09-16 01:01:10 +00005832 if (LocaleCompare((const char *) tag,"scale") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005833 {
5834 Image
5835 *scale_image;
5836
5837 /*
5838 Scale image.
5839 */
5840 if (msl_info->image[n] == (Image *) NULL)
5841 {
cristyb988fe72009-09-16 01:01:10 +00005842 ThrowMSLException(OptionError,"NoImagesDefined",
5843 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005844 break;
5845 }
5846 if (attributes != (const xmlChar **) NULL)
5847 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5848 {
5849 keyword=(const char *) attributes[i++];
5850 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005851 msl_info->attributes[n],(const char *) attributes[i],
5852 &exception);
cristy3ed852e2009-09-05 21:47:34 +00005853 CloneString(&value,attribute);
5854 switch (*keyword)
5855 {
5856 case 'G':
5857 case 'g':
5858 {
5859 if (LocaleCompare(keyword,"geometry") == 0)
5860 {
5861 flags=ParseRegionGeometry(msl_info->image[n],value,
5862 &geometry,&exception);
5863 break;
5864 }
5865 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5866 keyword);
5867 break;
5868 }
5869 case 'H':
5870 case 'h':
5871 {
5872 if (LocaleCompare(keyword,"height") == 0)
5873 {
cristye27293e2009-12-18 02:53:20 +00005874 geometry.height=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005875 break;
5876 }
5877 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5878 keyword);
5879 break;
5880 }
5881 case 'W':
5882 case 'w':
5883 {
5884 if (LocaleCompare(keyword,"width") == 0)
5885 {
cristyf2f27272009-12-17 14:48:46 +00005886 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005887 break;
5888 }
5889 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5890 keyword);
5891 break;
5892 }
5893 default:
5894 {
5895 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5896 keyword);
5897 break;
5898 }
5899 }
5900 }
5901 scale_image=ScaleImage(msl_info->image[n],geometry.width,
5902 geometry.height,&msl_info->image[n]->exception);
5903 if (scale_image == (Image *) NULL)
5904 break;
5905 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5906 msl_info->image[n]=scale_image;
5907 break;
5908 }
cristyb988fe72009-09-16 01:01:10 +00005909 if (LocaleCompare((const char *) tag,"segment") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005910 {
5911 ColorspaceType
5912 colorspace;
5913
5914 MagickBooleanType
5915 verbose;
cristyb988fe72009-09-16 01:01:10 +00005916
cristy3ed852e2009-09-05 21:47:34 +00005917 /*
5918 Segment image.
5919 */
5920 if (msl_info->image[n] == (Image *) NULL)
5921 {
cristyb988fe72009-09-16 01:01:10 +00005922 ThrowMSLException(OptionError,"NoImagesDefined",
5923 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005924 break;
5925 }
5926 geometry_info.rho=1.0;
5927 geometry_info.sigma=1.5;
5928 colorspace=RGBColorspace;
5929 verbose=MagickFalse;
5930 if (attributes != (const xmlChar **) NULL)
5931 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5932 {
5933 keyword=(const char *) attributes[i++];
5934 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005935 msl_info->attributes[n],(const char *) attributes[i],
5936 &exception);
cristy3ed852e2009-09-05 21:47:34 +00005937 CloneString(&value,attribute);
5938 switch (*keyword)
5939 {
5940 case 'C':
5941 case 'c':
5942 {
5943 if (LocaleCompare(keyword,"cluster-threshold") == 0)
5944 {
cristyc1acd842011-05-19 23:05:47 +00005945 geometry_info.rho=InterpretLocaleValue(value,
5946 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005947 break;
5948 }
5949 if (LocaleCompare(keyword,"colorspace") == 0)
5950 {
cristy042ee782011-04-22 18:48:30 +00005951 option=ParseCommandOption(MagickColorspaceOptions,
cristy3ed852e2009-09-05 21:47:34 +00005952 MagickFalse,value);
5953 if (option < 0)
5954 ThrowMSLException(OptionError,
5955 "UnrecognizedColorspaceType",value);
5956 colorspace=(ColorspaceType) option;
5957 break;
5958 }
5959 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5960 keyword);
5961 break;
5962 }
5963 case 'G':
5964 case 'g':
5965 {
5966 if (LocaleCompare(keyword,"geometry") == 0)
5967 {
5968 flags=ParseGeometry(value,&geometry_info);
5969 if ((flags & SigmaValue) == 0)
5970 geometry_info.sigma=1.5;
5971 break;
5972 }
5973 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5974 keyword);
5975 break;
5976 }
5977 case 'S':
5978 case 's':
5979 {
5980 if (LocaleCompare(keyword,"smoothing-threshold") == 0)
5981 {
cristyc1acd842011-05-19 23:05:47 +00005982 geometry_info.sigma=InterpretLocaleValue(value,
5983 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005984 break;
5985 }
5986 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5987 keyword);
5988 break;
5989 }
5990 default:
5991 {
5992 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5993 keyword);
5994 break;
5995 }
5996 }
5997 }
5998 (void) SegmentImage(msl_info->image[n],colorspace,verbose,
cristy018f07f2011-09-04 21:15:19 +00005999 geometry_info.rho,geometry_info.sigma,&exception);
cristy3ed852e2009-09-05 21:47:34 +00006000 break;
6001 }
cristyb988fe72009-09-16 01:01:10 +00006002 else if (LocaleCompare((const char *) tag, "set") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006003 {
6004 if (msl_info->image[n] == (Image *) NULL)
6005 {
cristy0b6d0052011-07-27 23:54:16 +00006006 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006007 break;
6008 }
6009
6010 if (attributes == (const xmlChar **) NULL)
6011 break;
6012 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6013 {
6014 keyword=(const char *) attributes[i++];
6015 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006016 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00006017 switch (*keyword)
6018 {
cristy3ed852e2009-09-05 21:47:34 +00006019 case 'C':
6020 case 'c':
6021 {
6022 if (LocaleCompare(keyword,"clip-mask") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006023 {
cristy2c8b6312009-09-16 02:37:23 +00006024 for (j=0; j < msl_info->n; j++)
cristy3ed852e2009-09-05 21:47:34 +00006025 {
cristy2c8b6312009-09-16 02:37:23 +00006026 const char
6027 *property;
6028
6029 property=GetImageProperty(msl_info->attributes[j],"id");
6030 if (LocaleCompare(property,value) == 0)
6031 {
cristy018f07f2011-09-04 21:15:19 +00006032 SetImageMask(msl_info->image[n],msl_info->image[j],
6033 &exception);
cristy2c8b6312009-09-16 02:37:23 +00006034 break;
6035 }
cristy3ed852e2009-09-05 21:47:34 +00006036 }
cristy2c8b6312009-09-16 02:37:23 +00006037 break;
cristy3ed852e2009-09-05 21:47:34 +00006038 }
cristy3ed852e2009-09-05 21:47:34 +00006039 if (LocaleCompare(keyword,"clip-path") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006040 {
cristy2c8b6312009-09-16 02:37:23 +00006041 for (j=0; j < msl_info->n; j++)
cristy3ed852e2009-09-05 21:47:34 +00006042 {
cristy2c8b6312009-09-16 02:37:23 +00006043 const char
6044 *property;
6045
6046 property=GetImageProperty(msl_info->attributes[j],"id");
6047 if (LocaleCompare(property,value) == 0)
6048 {
cristy018f07f2011-09-04 21:15:19 +00006049 SetImageClipMask(msl_info->image[n],msl_info->image[j],
6050 &exception);
cristy2c8b6312009-09-16 02:37:23 +00006051 break;
6052 }
cristy3ed852e2009-09-05 21:47:34 +00006053 }
cristy2c8b6312009-09-16 02:37:23 +00006054 break;
cristy3ed852e2009-09-05 21:47:34 +00006055 }
cristy2c8b6312009-09-16 02:37:23 +00006056 if (LocaleCompare(keyword,"colorspace") == 0)
6057 {
cristybb503372010-05-27 20:51:26 +00006058 ssize_t
cristy2c8b6312009-09-16 02:37:23 +00006059 colorspace;
6060
cristy042ee782011-04-22 18:48:30 +00006061 colorspace=(ColorspaceType) ParseCommandOption(
cristy7e9e6fa2010-11-21 17:06:24 +00006062 MagickColorspaceOptions,MagickFalse,value);
cristy2c8b6312009-09-16 02:37:23 +00006063 if (colorspace < 0)
cristyfb758a52009-09-16 14:36:08 +00006064 ThrowMSLException(OptionError,"UnrecognizedColorspace",
cristy2c8b6312009-09-16 02:37:23 +00006065 value);
6066 (void) TransformImageColorspace(msl_info->image[n],
6067 (ColorspaceType) colorspace);
6068 break;
6069 }
6070 (void) SetMSLAttributes(msl_info,keyword,value);
cristy0b6d0052011-07-27 23:54:16 +00006071 (void) SetImageProperty(msl_info->image[n],keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00006072 break;
6073 }
6074 case 'D':
6075 case 'd':
6076 {
cristy2c8b6312009-09-16 02:37:23 +00006077 if (LocaleCompare(keyword,"density") == 0)
6078 {
6079 flags=ParseGeometry(value,&geometry_info);
6080 msl_info->image[n]->x_resolution=geometry_info.rho;
6081 msl_info->image[n]->y_resolution=geometry_info.sigma;
6082 if ((flags & SigmaValue) == 0)
6083 msl_info->image[n]->y_resolution=
6084 msl_info->image[n]->x_resolution;
6085 break;
6086 }
6087 (void) SetMSLAttributes(msl_info,keyword,value);
cristy0b6d0052011-07-27 23:54:16 +00006088 (void) SetImageProperty(msl_info->image[n],keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00006089 break;
6090 }
6091 case 'O':
6092 case 'o':
6093 {
6094 if (LocaleCompare(keyword, "opacity") == 0)
cristy2c8b6312009-09-16 02:37:23 +00006095 {
cristy4c08aed2011-07-01 19:47:50 +00006096 ssize_t opac = OpaqueAlpha,
cristybb503372010-05-27 20:51:26 +00006097 len = (ssize_t) strlen( value );
cristy3ed852e2009-09-05 21:47:34 +00006098
cristy2c8b6312009-09-16 02:37:23 +00006099 if (value[len-1] == '%') {
6100 char tmp[100];
6101 (void) CopyMagickString(tmp,value,len);
cristyf2f27272009-12-17 14:48:46 +00006102 opac = StringToLong( tmp );
cristy2c8b6312009-09-16 02:37:23 +00006103 opac = (int)(QuantumRange * ((float)opac/100));
6104 } else
cristyf2f27272009-12-17 14:48:46 +00006105 opac = StringToLong( value );
cristy2c8b6312009-09-16 02:37:23 +00006106 (void) SetImageOpacity( msl_info->image[n], (Quantum) opac );
6107 break;
cristy3ed852e2009-09-05 21:47:34 +00006108 }
cristy2c8b6312009-09-16 02:37:23 +00006109 (void) SetMSLAttributes(msl_info,keyword,value);
cristy0b6d0052011-07-27 23:54:16 +00006110 (void) SetImageProperty(msl_info->image[n],keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00006111 break;
6112 }
6113 case 'P':
6114 case 'p':
6115 {
6116 if (LocaleCompare(keyword, "page") == 0)
6117 {
6118 char
6119 page[MaxTextExtent];
6120
6121 const char
6122 *image_option;
6123
6124 MagickStatusType
6125 flags;
6126
6127 RectangleInfo
6128 geometry;
6129
6130 (void) ResetMagickMemory(&geometry,0,sizeof(geometry));
6131 image_option=GetImageOption(msl_info->image_info[n],"page");
6132 if (image_option != (const char *) NULL)
6133 flags=ParseAbsoluteGeometry(image_option,&geometry);
6134 flags=ParseAbsoluteGeometry(value,&geometry);
cristyb51dff52011-05-19 16:55:47 +00006135 (void) FormatLocaleString(page,MaxTextExtent,"%.20gx%.20g",
cristye8c25f92010-06-03 00:53:06 +00006136 (double) geometry.width,(double) geometry.height);
cristy3ed852e2009-09-05 21:47:34 +00006137 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
cristyb51dff52011-05-19 16:55:47 +00006138 (void) FormatLocaleString(page,MaxTextExtent,
cristye8c25f92010-06-03 00:53:06 +00006139 "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,
6140 (double) geometry.height,(double) geometry.x,(double)
cristyf2faecf2010-05-28 19:19:36 +00006141 geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00006142 (void) SetImageOption(msl_info->image_info[n],keyword,page);
6143 msl_info->image_info[n]->page=GetPageGeometry(page);
6144 break;
6145 }
cristy2c8b6312009-09-16 02:37:23 +00006146 (void) SetMSLAttributes(msl_info,keyword,value);
cristy0b6d0052011-07-27 23:54:16 +00006147 (void) SetImageProperty(msl_info->image[n],keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00006148 break;
6149 }
6150 default:
6151 {
cristy2c8b6312009-09-16 02:37:23 +00006152 (void) SetMSLAttributes(msl_info,keyword,value);
cristy0b6d0052011-07-27 23:54:16 +00006153 (void) SetImageProperty(msl_info->image[n],keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00006154 break;
6155 }
6156 }
6157 }
6158 break;
6159 }
cristyb988fe72009-09-16 01:01:10 +00006160 if (LocaleCompare((const char *) tag,"shade") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006161 {
6162 Image
6163 *shade_image;
6164
6165 MagickBooleanType
6166 gray;
6167
6168 /*
6169 Shade image.
6170 */
6171 if (msl_info->image[n] == (Image *) NULL)
6172 {
cristyb988fe72009-09-16 01:01:10 +00006173 ThrowMSLException(OptionError,"NoImagesDefined",
6174 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006175 break;
6176 }
6177 gray=MagickFalse;
6178 if (attributes != (const xmlChar **) NULL)
6179 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6180 {
6181 keyword=(const char *) attributes[i++];
6182 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006183 msl_info->attributes[n],(const char *) attributes[i],
6184 &exception);
cristy3ed852e2009-09-05 21:47:34 +00006185 CloneString(&value,attribute);
6186 switch (*keyword)
6187 {
6188 case 'A':
6189 case 'a':
6190 {
6191 if (LocaleCompare(keyword,"azimuth") == 0)
6192 {
cristyc1acd842011-05-19 23:05:47 +00006193 geometry_info.rho=InterpretLocaleValue(value,
6194 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006195 break;
6196 }
6197 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6198 keyword);
6199 break;
6200 }
6201 case 'E':
6202 case 'e':
6203 {
6204 if (LocaleCompare(keyword,"elevation") == 0)
6205 {
cristyc1acd842011-05-19 23:05:47 +00006206 geometry_info.sigma=InterpretLocaleValue(value,
6207 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006208 break;
6209 }
6210 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6211 keyword);
6212 break;
6213 }
6214 case 'G':
6215 case 'g':
6216 {
6217 if (LocaleCompare(keyword,"geometry") == 0)
6218 {
6219 flags=ParseGeometry(value,&geometry_info);
6220 if ((flags & SigmaValue) == 0)
6221 geometry_info.sigma=1.0;
6222 break;
6223 }
6224 if (LocaleCompare(keyword,"gray") == 0)
6225 {
cristy042ee782011-04-22 18:48:30 +00006226 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00006227 value);
6228 if (option < 0)
6229 ThrowMSLException(OptionError,"UnrecognizedNoiseType",
6230 value);
6231 gray=(MagickBooleanType) option;
6232 break;
6233 }
6234 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6235 keyword);
6236 break;
6237 }
6238 default:
6239 {
6240 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6241 keyword);
6242 break;
6243 }
6244 }
6245 }
6246 shade_image=ShadeImage(msl_info->image[n],gray,geometry_info.rho,
6247 geometry_info.sigma,&msl_info->image[n]->exception);
6248 if (shade_image == (Image *) NULL)
6249 break;
6250 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6251 msl_info->image[n]=shade_image;
6252 break;
6253 }
cristyb988fe72009-09-16 01:01:10 +00006254 if (LocaleCompare((const char *) tag,"shadow") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006255 {
6256 Image
6257 *shadow_image;
6258
6259 /*
6260 Shear image.
6261 */
6262 if (msl_info->image[n] == (Image *) NULL)
6263 {
cristyb988fe72009-09-16 01:01:10 +00006264 ThrowMSLException(OptionError,"NoImagesDefined",
6265 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006266 break;
6267 }
6268 if (attributes != (const xmlChar **) NULL)
6269 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6270 {
6271 keyword=(const char *) attributes[i++];
6272 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006273 msl_info->attributes[n],(const char *) attributes[i],
6274 &exception);
cristy3ed852e2009-09-05 21:47:34 +00006275 CloneString(&value,attribute);
6276 switch (*keyword)
6277 {
6278 case 'G':
6279 case 'g':
6280 {
6281 if (LocaleCompare(keyword,"geometry") == 0)
6282 {
6283 flags=ParseGeometry(value,&geometry_info);
6284 if ((flags & SigmaValue) == 0)
6285 geometry_info.sigma=1.0;
6286 break;
6287 }
6288 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6289 keyword);
6290 break;
6291 }
6292 case 'O':
6293 case 'o':
6294 {
6295 if (LocaleCompare(keyword,"opacity") == 0)
6296 {
cristyf2f27272009-12-17 14:48:46 +00006297 geometry_info.rho=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006298 break;
6299 }
6300 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6301 keyword);
6302 break;
6303 }
6304 case 'S':
6305 case 's':
6306 {
6307 if (LocaleCompare(keyword,"sigma") == 0)
6308 {
cristyf2f27272009-12-17 14:48:46 +00006309 geometry_info.sigma=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006310 break;
6311 }
6312 break;
6313 }
6314 case 'X':
6315 case 'x':
6316 {
6317 if (LocaleCompare(keyword,"x") == 0)
6318 {
cristyc1acd842011-05-19 23:05:47 +00006319 geometry_info.xi=InterpretLocaleValue(value,
6320 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006321 break;
6322 }
6323 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6324 keyword);
6325 break;
6326 }
6327 case 'Y':
6328 case 'y':
6329 {
6330 if (LocaleCompare(keyword,"y") == 0)
6331 {
cristyf2f27272009-12-17 14:48:46 +00006332 geometry_info.psi=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006333 break;
6334 }
6335 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6336 keyword);
6337 break;
6338 }
6339 default:
6340 {
6341 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6342 keyword);
6343 break;
6344 }
6345 }
6346 }
6347 shadow_image=ShadowImage(msl_info->image[n],geometry_info.rho,
cristybb503372010-05-27 20:51:26 +00006348 geometry_info.sigma,(ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
cristy0534a6b2010-03-18 01:19:38 +00006349 ceil(geometry_info.psi-0.5),&msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00006350 if (shadow_image == (Image *) NULL)
6351 break;
6352 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6353 msl_info->image[n]=shadow_image;
6354 break;
6355 }
cristyb988fe72009-09-16 01:01:10 +00006356 if (LocaleCompare((const char *) tag,"sharpen") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006357 {
cristy05c0c9a2011-09-05 23:16:13 +00006358 double bias = 0.0,
6359 radius = 0.0,
cristy3ed852e2009-09-05 21:47:34 +00006360 sigma = 1.0;
6361
6362 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00006363 {
6364 ThrowMSLException(OptionError,"NoImagesDefined",
6365 (const char *) tag);
6366 break;
6367 }
cristy3ed852e2009-09-05 21:47:34 +00006368 /*
6369 NOTE: sharpen can have no attributes, since we use all the defaults!
6370 */
6371 if (attributes != (const xmlChar **) NULL)
6372 {
6373 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6374 {
6375 keyword=(const char *) attributes[i++];
6376 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006377 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00006378 switch (*keyword)
6379 {
cristy05c0c9a2011-09-05 23:16:13 +00006380 case 'B':
6381 case 'b':
6382 {
6383 if (LocaleCompare(keyword, "bias") == 0)
6384 {
6385 bias = InterpretLocaleValue(value,(char **) NULL);
6386 break;
6387 }
6388 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6389 break;
6390 }
cristy3ed852e2009-09-05 21:47:34 +00006391 case 'R':
6392 case 'r':
6393 {
6394 if (LocaleCompare(keyword, "radius") == 0)
6395 {
cristyc1acd842011-05-19 23:05:47 +00006396 radius = InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006397 break;
6398 }
6399 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6400 break;
6401 }
6402 case 'S':
6403 case 's':
6404 {
6405 if (LocaleCompare(keyword,"sigma") == 0)
6406 {
cristyf2f27272009-12-17 14:48:46 +00006407 sigma = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00006408 break;
6409 }
6410 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6411 break;
6412 }
6413 default:
6414 {
6415 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6416 break;
6417 }
6418 }
6419 }
6420 }
6421
6422 /*
6423 sharpen image.
6424 */
6425 {
6426 Image
6427 *newImage;
6428
cristy05c0c9a2011-09-05 23:16:13 +00006429 newImage=SharpenImage(msl_info->image[n],radius,sigma,bias,
6430 &msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00006431 if (newImage == (Image *) NULL)
6432 break;
6433 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6434 msl_info->image[n]=newImage;
6435 break;
6436 }
6437 }
cristyb988fe72009-09-16 01:01:10 +00006438 else if (LocaleCompare((const char *) tag,"shave") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006439 {
6440 /* init the values */
6441 width = height = 0;
6442 x = y = 0;
6443
6444 if (msl_info->image[n] == (Image *) NULL)
6445 {
cristyb988fe72009-09-16 01:01:10 +00006446 ThrowMSLException(OptionError,"NoImagesDefined",
6447 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006448 break;
6449 }
6450 if (attributes == (const xmlChar **) NULL)
6451 break;
6452 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6453 {
6454 keyword=(const char *) attributes[i++];
6455 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006456 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00006457 switch (*keyword)
6458 {
6459 case 'G':
6460 case 'g':
6461 {
6462 if (LocaleCompare(keyword,"geometry") == 0)
6463 {
6464 (void) ParseMetaGeometry(value,&x,&y,&width,&height);
6465 break;
6466 }
6467 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6468 break;
6469 }
6470 case 'H':
6471 case 'h':
6472 {
6473 if (LocaleCompare(keyword,"height") == 0)
6474 {
cristyf2f27272009-12-17 14:48:46 +00006475 height = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00006476 break;
6477 }
6478 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6479 break;
6480 }
6481 case 'W':
6482 case 'w':
6483 {
6484 if (LocaleCompare(keyword,"width") == 0)
6485 {
cristyf2f27272009-12-17 14:48:46 +00006486 width = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00006487 break;
6488 }
6489 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6490 break;
6491 }
6492 default:
6493 {
6494 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6495 break;
6496 }
6497 }
6498 }
6499
6500 /*
6501 process image.
6502 */
6503 {
6504 Image
6505 *newImage;
6506 RectangleInfo
6507 rectInfo;
6508
6509 rectInfo.height = height;
6510 rectInfo.width = width;
6511 rectInfo.x = x;
6512 rectInfo.y = y;
6513
6514
6515 newImage=ShaveImage(msl_info->image[n], &rectInfo,
6516 &msl_info->image[n]->exception);
6517 if (newImage == (Image *) NULL)
6518 break;
6519 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6520 msl_info->image[n]=newImage;
6521 }
6522
6523 break;
6524 }
cristyb988fe72009-09-16 01:01:10 +00006525 if (LocaleCompare((const char *) tag,"shear") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006526 {
6527 Image
6528 *shear_image;
6529
6530 /*
6531 Shear image.
6532 */
6533 if (msl_info->image[n] == (Image *) NULL)
6534 {
cristyb988fe72009-09-16 01:01:10 +00006535 ThrowMSLException(OptionError,"NoImagesDefined",
6536 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006537 break;
6538 }
6539 if (attributes != (const xmlChar **) NULL)
6540 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6541 {
6542 keyword=(const char *) attributes[i++];
6543 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006544 msl_info->attributes[n],(const char *) attributes[i],
6545 &exception);
cristy3ed852e2009-09-05 21:47:34 +00006546 CloneString(&value,attribute);
6547 switch (*keyword)
6548 {
6549 case 'F':
6550 case 'f':
6551 {
6552 if (LocaleCompare(keyword, "fill") == 0)
6553 {
6554 (void) QueryColorDatabase(value,
6555 &msl_info->image[n]->background_color,&exception);
6556 break;
6557 }
6558 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6559 keyword);
6560 break;
6561 }
6562 case 'G':
6563 case 'g':
6564 {
6565 if (LocaleCompare(keyword,"geometry") == 0)
6566 {
6567 flags=ParseGeometry(value,&geometry_info);
6568 if ((flags & SigmaValue) == 0)
6569 geometry_info.sigma=1.0;
6570 break;
6571 }
6572 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6573 keyword);
6574 break;
6575 }
6576 case 'X':
6577 case 'x':
6578 {
6579 if (LocaleCompare(keyword,"x") == 0)
6580 {
cristyc1acd842011-05-19 23:05:47 +00006581 geometry_info.rho=InterpretLocaleValue(value,
6582 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006583 break;
6584 }
6585 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6586 keyword);
6587 break;
6588 }
6589 case 'Y':
6590 case 'y':
6591 {
6592 if (LocaleCompare(keyword,"y") == 0)
6593 {
cristyf2f27272009-12-17 14:48:46 +00006594 geometry_info.sigma=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006595 break;
6596 }
6597 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6598 keyword);
6599 break;
6600 }
6601 default:
6602 {
6603 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6604 keyword);
6605 break;
6606 }
6607 }
6608 }
6609 shear_image=ShearImage(msl_info->image[n],geometry_info.rho,
6610 geometry_info.sigma,&msl_info->image[n]->exception);
6611 if (shear_image == (Image *) NULL)
6612 break;
6613 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6614 msl_info->image[n]=shear_image;
6615 break;
6616 }
cristyb988fe72009-09-16 01:01:10 +00006617 if (LocaleCompare((const char *) tag,"signature") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006618 {
6619 /*
6620 Signature image.
6621 */
6622 if (msl_info->image[n] == (Image *) NULL)
6623 {
cristyb988fe72009-09-16 01:01:10 +00006624 ThrowMSLException(OptionError,"NoImagesDefined",
6625 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006626 break;
6627 }
6628 if (attributes != (const xmlChar **) NULL)
6629 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6630 {
6631 keyword=(const char *) attributes[i++];
6632 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006633 msl_info->attributes[n],(const char *) attributes[i],
6634 &exception);
cristy3ed852e2009-09-05 21:47:34 +00006635 CloneString(&value,attribute);
6636 switch (*keyword)
6637 {
6638 default:
6639 {
6640 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6641 keyword);
6642 break;
6643 }
6644 }
6645 }
cristy018f07f2011-09-04 21:15:19 +00006646 (void) SignatureImage(msl_info->image[n],&exception);
cristy3ed852e2009-09-05 21:47:34 +00006647 break;
6648 }
cristyb988fe72009-09-16 01:01:10 +00006649 if (LocaleCompare((const char *) tag,"solarize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006650 {
6651 /*
6652 Solarize image.
6653 */
6654 if (msl_info->image[n] == (Image *) NULL)
6655 {
cristyb988fe72009-09-16 01:01:10 +00006656 ThrowMSLException(OptionError,"NoImagesDefined",
6657 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006658 break;
6659 }
6660 geometry_info.rho=QuantumRange/2.0;
6661 if (attributes != (const xmlChar **) NULL)
6662 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6663 {
6664 keyword=(const char *) attributes[i++];
6665 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006666 msl_info->attributes[n],(const char *) attributes[i],
6667 &exception);
cristy3ed852e2009-09-05 21:47:34 +00006668 CloneString(&value,attribute);
6669 switch (*keyword)
6670 {
6671 case 'G':
6672 case 'g':
6673 {
6674 if (LocaleCompare(keyword,"geometry") == 0)
6675 {
6676 flags=ParseGeometry(value,&geometry_info);
6677 break;
6678 }
6679 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6680 keyword);
6681 break;
6682 }
6683 case 'T':
6684 case 't':
6685 {
6686 if (LocaleCompare(keyword,"threshold") == 0)
6687 {
cristyc1acd842011-05-19 23:05:47 +00006688 geometry_info.rho=InterpretLocaleValue(value,
6689 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006690 break;
6691 }
6692 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6693 keyword);
6694 break;
6695 }
6696 default:
6697 {
6698 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6699 keyword);
6700 break;
6701 }
6702 }
6703 }
cristy5cbc0162011-08-29 00:36:28 +00006704 (void) SolarizeImage(msl_info->image[n],geometry_info.rho,
6705 &msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00006706 break;
6707 }
cristyb988fe72009-09-16 01:01:10 +00006708 if (LocaleCompare((const char *) tag,"spread") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006709 {
6710 Image
6711 *spread_image;
6712
6713 /*
6714 Spread image.
6715 */
6716 if (msl_info->image[n] == (Image *) NULL)
6717 {
cristyb988fe72009-09-16 01:01:10 +00006718 ThrowMSLException(OptionError,"NoImagesDefined",
6719 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006720 break;
6721 }
6722 if (attributes != (const xmlChar **) NULL)
6723 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6724 {
6725 keyword=(const char *) attributes[i++];
6726 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006727 msl_info->attributes[n],(const char *) attributes[i],
6728 &exception);
cristy3ed852e2009-09-05 21:47:34 +00006729 CloneString(&value,attribute);
6730 switch (*keyword)
6731 {
6732 case 'G':
6733 case 'g':
6734 {
6735 if (LocaleCompare(keyword,"geometry") == 0)
6736 {
6737 flags=ParseGeometry(value,&geometry_info);
6738 if ((flags & SigmaValue) == 0)
6739 geometry_info.sigma=1.0;
6740 break;
6741 }
6742 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6743 keyword);
6744 break;
6745 }
6746 case 'R':
6747 case 'r':
6748 {
6749 if (LocaleCompare(keyword,"radius") == 0)
6750 {
cristyc1acd842011-05-19 23:05:47 +00006751 geometry_info.rho=InterpretLocaleValue(value,
6752 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006753 break;
6754 }
6755 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6756 keyword);
6757 break;
6758 }
6759 default:
6760 {
6761 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6762 keyword);
6763 break;
6764 }
6765 }
6766 }
6767 spread_image=SpreadImage(msl_info->image[n],geometry_info.rho,
cristy5c4e2582011-09-11 19:21:03 +00006768 msl_info->image[n]->interpolate,&msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00006769 if (spread_image == (Image *) NULL)
6770 break;
6771 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6772 msl_info->image[n]=spread_image;
6773 break;
6774 }
cristyb988fe72009-09-16 01:01:10 +00006775 else if (LocaleCompare((const char *) tag,"stegano") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006776 {
6777 Image *
6778 watermark = (Image*)NULL;
6779
6780 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00006781 {
6782 ThrowMSLException(OptionError,"NoImagesDefined",
6783 (const char *) tag);
6784 break;
6785 }
cristy3ed852e2009-09-05 21:47:34 +00006786 if (attributes == (const xmlChar **) NULL)
6787 break;
6788 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6789 {
6790 keyword=(const char *) attributes[i++];
6791 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006792 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00006793 switch (*keyword)
6794 {
6795 case 'I':
6796 case 'i':
6797 {
6798 if (LocaleCompare(keyword,"image") == 0)
6799 {
6800 for (j=0; j<msl_info->n;j++)
6801 {
6802 const char *
6803 theAttr = GetImageProperty(msl_info->attributes[j], "id");
6804 if (theAttr && LocaleCompare(theAttr, value) == 0)
6805 {
6806 watermark = msl_info->image[j];
6807 break;
6808 }
6809 }
6810 break;
6811 }
6812 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6813 break;
6814 }
6815 default:
6816 {
6817 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6818 break;
6819 }
6820 }
6821 }
6822
6823 /*
6824 process image.
6825 */
6826 if ( watermark != (Image*) NULL )
6827 {
6828 Image
6829 *newImage;
6830
6831 newImage=SteganoImage(msl_info->image[n], watermark, &msl_info->image[n]->exception);
6832 if (newImage == (Image *) NULL)
6833 break;
6834 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6835 msl_info->image[n]=newImage;
6836 break;
6837 } else
6838 ThrowMSLException(OptionError,"MissingWatermarkImage",keyword);
6839 }
cristyb988fe72009-09-16 01:01:10 +00006840 else if (LocaleCompare((const char *) tag,"stereo") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006841 {
6842 Image *
6843 stereoImage = (Image*)NULL;
6844
6845 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00006846 {
6847 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
6848 break;
6849 }
cristy3ed852e2009-09-05 21:47:34 +00006850 if (attributes == (const xmlChar **) NULL)
6851 break;
6852 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6853 {
6854 keyword=(const char *) attributes[i++];
6855 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006856 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00006857 switch (*keyword)
6858 {
6859 case 'I':
6860 case 'i':
6861 {
6862 if (LocaleCompare(keyword,"image") == 0)
6863 {
6864 for (j=0; j<msl_info->n;j++)
6865 {
6866 const char *
6867 theAttr = GetImageProperty(msl_info->attributes[j], "id");
6868 if (theAttr && LocaleCompare(theAttr, value) == 0)
6869 {
6870 stereoImage = msl_info->image[j];
6871 break;
6872 }
6873 }
6874 break;
6875 }
6876 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6877 break;
6878 }
6879 default:
6880 {
6881 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6882 break;
6883 }
6884 }
6885 }
6886
6887 /*
6888 process image.
6889 */
6890 if ( stereoImage != (Image*) NULL )
6891 {
6892 Image
6893 *newImage;
6894
6895 newImage=StereoImage(msl_info->image[n], stereoImage, &msl_info->image[n]->exception);
6896 if (newImage == (Image *) NULL)
6897 break;
6898 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6899 msl_info->image[n]=newImage;
6900 break;
6901 } else
6902 ThrowMSLException(OptionError,"Missing stereo image",keyword);
6903 }
cristyb988fe72009-09-16 01:01:10 +00006904 if (LocaleCompare((const char *) tag,"swap") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006905 {
6906 Image
6907 *p,
6908 *q,
6909 *swap;
6910
cristybb503372010-05-27 20:51:26 +00006911 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00006912 index,
6913 swap_index;
6914
6915 if (msl_info->image[n] == (Image *) NULL)
6916 {
cristyb988fe72009-09-16 01:01:10 +00006917 ThrowMSLException(OptionError,"NoImagesDefined",
6918 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006919 break;
6920 }
6921 index=(-1);
6922 swap_index=(-2);
6923 if (attributes != (const xmlChar **) NULL)
6924 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6925 {
6926 keyword=(const char *) attributes[i++];
6927 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006928 msl_info->attributes[n],(const char *) attributes[i],
6929 &exception);
cristy3ed852e2009-09-05 21:47:34 +00006930 CloneString(&value,attribute);
6931 switch (*keyword)
6932 {
6933 case 'G':
6934 case 'g':
6935 {
6936 if (LocaleCompare(keyword,"indexes") == 0)
6937 {
6938 flags=ParseGeometry(value,&geometry_info);
cristybb503372010-05-27 20:51:26 +00006939 index=(ssize_t) geometry_info.rho;
cristy3ed852e2009-09-05 21:47:34 +00006940 if ((flags & SigmaValue) == 0)
cristybb503372010-05-27 20:51:26 +00006941 swap_index=(ssize_t) geometry_info.sigma;
cristy3ed852e2009-09-05 21:47:34 +00006942 break;
6943 }
6944 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6945 keyword);
6946 break;
6947 }
6948 default:
6949 {
6950 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6951 keyword);
6952 break;
6953 }
6954 }
6955 }
6956 /*
6957 Swap images.
6958 */
6959 p=GetImageFromList(msl_info->image[n],index);
6960 q=GetImageFromList(msl_info->image[n],swap_index);
6961 if ((p == (Image *) NULL) || (q == (Image *) NULL))
6962 {
cristyb988fe72009-09-16 01:01:10 +00006963 ThrowMSLException(OptionError,"NoSuchImage",(const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006964 break;
6965 }
6966 swap=CloneImage(p,0,0,MagickTrue,&p->exception);
6967 ReplaceImageInList(&p,CloneImage(q,0,0,MagickTrue,&q->exception));
6968 ReplaceImageInList(&q,swap);
6969 msl_info->image[n]=GetFirstImageInList(q);
6970 break;
6971 }
cristyb988fe72009-09-16 01:01:10 +00006972 if (LocaleCompare((const char *) tag,"swirl") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006973 {
6974 Image
6975 *swirl_image;
6976
6977 /*
6978 Swirl image.
6979 */
6980 if (msl_info->image[n] == (Image *) NULL)
6981 {
cristyb988fe72009-09-16 01:01:10 +00006982 ThrowMSLException(OptionError,"NoImagesDefined",
6983 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006984 break;
6985 }
6986 if (attributes != (const xmlChar **) NULL)
6987 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6988 {
6989 keyword=(const char *) attributes[i++];
6990 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006991 msl_info->attributes[n],(const char *) attributes[i],
6992 &exception);
cristy3ed852e2009-09-05 21:47:34 +00006993 CloneString(&value,attribute);
6994 switch (*keyword)
6995 {
6996 case 'D':
6997 case 'd':
6998 {
6999 if (LocaleCompare(keyword,"degrees") == 0)
7000 {
cristyc1acd842011-05-19 23:05:47 +00007001 geometry_info.rho=InterpretLocaleValue(value,
7002 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00007003 break;
7004 }
7005 ThrowMSLException(OptionError,"UnrecognizedAttribute",
7006 keyword);
7007 break;
7008 }
7009 case 'G':
7010 case 'g':
7011 {
7012 if (LocaleCompare(keyword,"geometry") == 0)
7013 {
7014 flags=ParseGeometry(value,&geometry_info);
7015 if ((flags & SigmaValue) == 0)
7016 geometry_info.sigma=1.0;
7017 break;
7018 }
7019 ThrowMSLException(OptionError,"UnrecognizedAttribute",
7020 keyword);
7021 break;
7022 }
7023 default:
7024 {
7025 ThrowMSLException(OptionError,"UnrecognizedAttribute",
7026 keyword);
7027 break;
7028 }
7029 }
7030 }
7031 swirl_image=SwirlImage(msl_info->image[n],geometry_info.rho,
cristy76f512e2011-09-12 01:26:56 +00007032 msl_info->image[n]->interpolate,&msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00007033 if (swirl_image == (Image *) NULL)
7034 break;
7035 msl_info->image[n]=DestroyImage(msl_info->image[n]);
7036 msl_info->image[n]=swirl_image;
7037 break;
7038 }
cristyb988fe72009-09-16 01:01:10 +00007039 if (LocaleCompare((const char *) tag,"sync") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007040 {
7041 /*
7042 Sync image.
7043 */
7044 if (msl_info->image[n] == (Image *) NULL)
7045 {
cristyb988fe72009-09-16 01:01:10 +00007046 ThrowMSLException(OptionError,"NoImagesDefined",
7047 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00007048 break;
7049 }
7050 if (attributes != (const xmlChar **) NULL)
7051 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7052 {
7053 keyword=(const char *) attributes[i++];
7054 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00007055 msl_info->attributes[n],(const char *) attributes[i],
7056 &exception);
cristy3ed852e2009-09-05 21:47:34 +00007057 CloneString(&value,attribute);
7058 switch (*keyword)
7059 {
7060 default:
7061 {
7062 ThrowMSLException(OptionError,"UnrecognizedAttribute",
7063 keyword);
7064 break;
7065 }
7066 }
7067 }
7068 (void) SyncImage(msl_info->image[n]);
7069 break;
7070 }
7071 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7072 }
7073 case 'T':
7074 case 't':
7075 {
cristyb988fe72009-09-16 01:01:10 +00007076 if (LocaleCompare((const char *) tag,"map") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007077 {
7078 Image
7079 *texture_image;
7080
7081 /*
7082 Texture image.
7083 */
7084 if (msl_info->image[n] == (Image *) NULL)
7085 {
cristyb988fe72009-09-16 01:01:10 +00007086 ThrowMSLException(OptionError,"NoImagesDefined",
7087 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00007088 break;
7089 }
7090 texture_image=NewImageList();
7091 if (attributes != (const xmlChar **) NULL)
7092 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7093 {
7094 keyword=(const char *) attributes[i++];
7095 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00007096 msl_info->attributes[n],(const char *) attributes[i],
7097 &exception);
cristy3ed852e2009-09-05 21:47:34 +00007098 CloneString(&value,attribute);
7099 switch (*keyword)
7100 {
7101 case 'I':
7102 case 'i':
7103 {
7104 if (LocaleCompare(keyword,"image") == 0)
7105 for (j=0; j < msl_info->n; j++)
7106 {
7107 const char
7108 *attribute;
cristyb988fe72009-09-16 01:01:10 +00007109
cristy3ed852e2009-09-05 21:47:34 +00007110 attribute=GetImageProperty(msl_info->attributes[j],"id");
7111 if ((attribute != (const char *) NULL) &&
7112 (LocaleCompare(attribute,value) == 0))
7113 {
7114 texture_image=CloneImage(msl_info->image[j],0,0,
7115 MagickFalse,&exception);
7116 break;
7117 }
7118 }
7119 break;
7120 }
7121 default:
7122 {
7123 ThrowMSLException(OptionError,"UnrecognizedAttribute",
7124 keyword);
7125 break;
7126 }
7127 }
7128 }
7129 (void) TextureImage(msl_info->image[n],texture_image);
7130 texture_image=DestroyImage(texture_image);
7131 break;
7132 }
cristyb988fe72009-09-16 01:01:10 +00007133 else if (LocaleCompare((const char *) tag,"threshold") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007134 {
7135 /* init the values */
7136 double threshold = 0;
7137
7138 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007139 {
7140 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7141 break;
7142 }
cristy3ed852e2009-09-05 21:47:34 +00007143 if (attributes == (const xmlChar **) NULL)
7144 break;
7145 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7146 {
7147 keyword=(const char *) attributes[i++];
7148 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00007149 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00007150 switch (*keyword)
7151 {
7152 case 'T':
7153 case 't':
7154 {
7155 if (LocaleCompare(keyword,"threshold") == 0)
7156 {
cristyc1acd842011-05-19 23:05:47 +00007157 threshold = InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00007158 break;
7159 }
7160 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7161 break;
7162 }
7163 default:
7164 {
7165 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7166 break;
7167 }
7168 }
7169 }
7170
7171 /*
7172 process image.
7173 */
7174 {
cristyf4ad9df2011-07-08 16:49:03 +00007175 BilevelImage(msl_info->image[n],threshold);
cristy3ed852e2009-09-05 21:47:34 +00007176 break;
7177 }
7178 }
cristyb988fe72009-09-16 01:01:10 +00007179 else if (LocaleCompare((const char *) tag, "transparent") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007180 {
7181 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007182 {
7183 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7184 break;
7185 }
cristy3ed852e2009-09-05 21:47:34 +00007186 if (attributes == (const xmlChar **) NULL)
7187 break;
7188 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7189 {
7190 keyword=(const char *) attributes[i++];
7191 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00007192 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00007193 switch (*keyword)
7194 {
7195 case 'C':
7196 case 'c':
7197 {
7198 if (LocaleCompare(keyword,"color") == 0)
7199 {
cristy4c08aed2011-07-01 19:47:50 +00007200 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00007201 target;
7202
7203 (void) QueryMagickColor(value,&target,&exception);
7204 (void) TransparentPaintImage(msl_info->image[n],&target,
cristy189e84c2011-08-27 18:08:53 +00007205 TransparentAlpha,MagickFalse,&msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00007206 break;
7207 }
7208 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7209 break;
7210 }
7211 default:
7212 {
7213 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7214 break;
7215 }
7216 }
7217 }
7218 break;
7219 }
cristyb988fe72009-09-16 01:01:10 +00007220 else if (LocaleCompare((const char *) tag, "trim") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007221 {
7222 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007223 {
7224 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7225 break;
7226 }
cristy3ed852e2009-09-05 21:47:34 +00007227
7228 /* no attributes here */
7229
7230 /* process the image */
7231 {
7232 Image
7233 *newImage;
7234 RectangleInfo
7235 rectInfo;
7236
7237 /* all zeros on a crop == trim edges! */
7238 rectInfo.height = rectInfo.width = 0;
7239 rectInfo.x = rectInfo.y = 0;
7240
7241 newImage=CropImage(msl_info->image[n],&rectInfo, &msl_info->image[n]->exception);
7242 if (newImage == (Image *) NULL)
7243 break;
7244 msl_info->image[n]=DestroyImage(msl_info->image[n]);
7245 msl_info->image[n]=newImage;
7246 break;
7247 }
7248 }
7249 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7250 }
7251 case 'W':
7252 case 'w':
7253 {
cristyb988fe72009-09-16 01:01:10 +00007254 if (LocaleCompare((const char *) tag,"write") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007255 {
7256 if (msl_info->image[n] == (Image *) NULL)
7257 {
cristyb988fe72009-09-16 01:01:10 +00007258 ThrowMSLException(OptionError,"NoImagesDefined",
7259 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00007260 break;
7261 }
7262 if (attributes == (const xmlChar **) NULL)
7263 break;
7264 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7265 {
7266 keyword=(const char *) attributes[i++];
7267 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00007268 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00007269 switch (*keyword)
7270 {
7271 case 'F':
7272 case 'f':
7273 {
7274 if (LocaleCompare(keyword,"filename") == 0)
7275 {
7276 (void) CopyMagickString(msl_info->image[n]->filename,value,
7277 MaxTextExtent);
7278 break;
7279 }
cristy4582cbb2009-09-23 00:35:43 +00007280 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00007281 }
7282 default:
7283 {
cristy4582cbb2009-09-23 00:35:43 +00007284 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00007285 break;
7286 }
7287 }
7288 }
7289
7290 /* process */
7291 {
cristy6f9e0d32011-08-28 16:32:09 +00007292 (void) WriteImage(msl_info->image_info[n], msl_info->image[n],
7293 &msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00007294 break;
7295 }
7296 }
7297 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7298 }
7299 default:
7300 {
7301 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7302 break;
7303 }
7304 }
7305 if ( value != NULL )
7306 value=DestroyString(value);
7307 (void) LogMagickEvent(CoderEvent,GetMagickModule()," )");
7308}
7309
7310static void MSLEndElement(void *context,const xmlChar *tag)
7311{
cristybb503372010-05-27 20:51:26 +00007312 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00007313 n;
7314
7315 MSLInfo
7316 *msl_info;
7317
7318 /*
7319 Called when the end of an element has been detected.
7320 */
7321 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.endElement(%s)",
7322 tag);
7323 msl_info=(MSLInfo *) context;
7324 n=msl_info->n;
7325 switch (*tag)
7326 {
7327 case 'C':
7328 case 'c':
7329 {
cristyb988fe72009-09-16 01:01:10 +00007330 if (LocaleCompare((const char *) tag,"comment") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007331 {
7332 (void) DeleteImageProperty(msl_info->image[n],"comment");
7333 if (msl_info->content == (char *) NULL)
7334 break;
7335 StripString(msl_info->content);
7336 (void) SetImageProperty(msl_info->image[n],"comment",
7337 msl_info->content);
7338 break;
7339 }
7340 break;
7341 }
7342 case 'G':
7343 case 'g':
7344 {
cristyb988fe72009-09-16 01:01:10 +00007345 if (LocaleCompare((const char *) tag, "group") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007346 {
7347 if (msl_info->group_info[msl_info->number_groups-1].numImages > 0 )
7348 {
cristybb503372010-05-27 20:51:26 +00007349 ssize_t i = (ssize_t)
cristy3ed852e2009-09-05 21:47:34 +00007350 (msl_info->group_info[msl_info->number_groups-1].numImages);
7351 while ( i-- )
7352 {
7353 if (msl_info->image[msl_info->n] != (Image *) NULL)
7354 msl_info->image[msl_info->n]=DestroyImage(msl_info->image[msl_info->n]);
7355 msl_info->attributes[msl_info->n]=DestroyImage(msl_info->attributes[msl_info->n]);
7356 msl_info->image_info[msl_info->n]=DestroyImageInfo(msl_info->image_info[msl_info->n]);
7357 msl_info->n--;
7358 }
7359 }
7360 msl_info->number_groups--;
7361 }
7362 break;
7363 }
7364 case 'I':
7365 case 'i':
7366 {
cristyb988fe72009-09-16 01:01:10 +00007367 if (LocaleCompare((const char *) tag, "image") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007368 MSLPopImage(msl_info);
7369 break;
7370 }
7371 case 'L':
7372 case 'l':
7373 {
cristyb988fe72009-09-16 01:01:10 +00007374 if (LocaleCompare((const char *) tag,"label") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007375 {
7376 (void) DeleteImageProperty(msl_info->image[n],"label");
7377 if (msl_info->content == (char *) NULL)
7378 break;
7379 StripString(msl_info->content);
7380 (void) SetImageProperty(msl_info->image[n],"label",
7381 msl_info->content);
7382 break;
7383 }
7384 break;
7385 }
7386 case 'M':
7387 case 'm':
7388 {
cristyb988fe72009-09-16 01:01:10 +00007389 if (LocaleCompare((const char *) tag, "msl") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007390 {
7391 /*
7392 This our base element.
7393 at the moment we don't do anything special
7394 but someday we might!
7395 */
7396 }
7397 break;
7398 }
7399 default:
7400 break;
7401 }
7402 if (msl_info->content != (char *) NULL)
7403 msl_info->content=DestroyString(msl_info->content);
7404}
7405
7406static void MSLCharacters(void *context,const xmlChar *c,int length)
7407{
7408 MSLInfo
7409 *msl_info;
7410
7411 register char
7412 *p;
7413
cristybb503372010-05-27 20:51:26 +00007414 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00007415 i;
7416
7417 /*
7418 Receiving some characters from the parser.
7419 */
7420 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7421 " SAX.characters(%s,%d)",c,length);
7422 msl_info=(MSLInfo *) context;
7423 if (msl_info->content != (char *) NULL)
7424 msl_info->content=(char *) ResizeQuantumMemory(msl_info->content,
7425 strlen(msl_info->content)+length+MaxTextExtent,
7426 sizeof(*msl_info->content));
7427 else
7428 {
7429 msl_info->content=(char *) NULL;
cristy37e0b382011-06-07 13:31:21 +00007430 if (~length >= (MaxTextExtent-1))
cristy3ed852e2009-09-05 21:47:34 +00007431 msl_info->content=(char *) AcquireQuantumMemory(length+MaxTextExtent,
7432 sizeof(*msl_info->content));
7433 if (msl_info->content != (char *) NULL)
7434 *msl_info->content='\0';
7435 }
7436 if (msl_info->content == (char *) NULL)
7437 return;
7438 p=msl_info->content+strlen(msl_info->content);
7439 for (i=0; i < length; i++)
7440 *p++=c[i];
7441 *p='\0';
7442}
7443
7444static void MSLReference(void *context,const xmlChar *name)
7445{
7446 MSLInfo
7447 *msl_info;
7448
7449 xmlParserCtxtPtr
7450 parser;
7451
7452 /*
7453 Called when an entity reference is detected.
7454 */
7455 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7456 " SAX.reference(%s)",name);
7457 msl_info=(MSLInfo *) context;
7458 parser=msl_info->parser;
7459 if (*name == '#')
7460 (void) xmlAddChild(parser->node,xmlNewCharRef(msl_info->document,name));
7461 else
7462 (void) xmlAddChild(parser->node,xmlNewReference(msl_info->document,name));
7463}
7464
7465static void MSLIgnorableWhitespace(void *context,const xmlChar *c,int length)
7466{
7467 MSLInfo
7468 *msl_info;
7469
7470 /*
7471 Receiving some ignorable whitespaces from the parser.
7472 */
7473 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7474 " SAX.ignorableWhitespace(%.30s, %d)",c,length);
7475 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007476 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007477}
7478
7479static void MSLProcessingInstructions(void *context,const xmlChar *target,
7480 const xmlChar *data)
7481{
7482 MSLInfo
7483 *msl_info;
7484
7485 /*
7486 A processing instruction has been parsed.
7487 */
7488 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7489 " SAX.processingInstruction(%s, %s)",
7490 target,data);
7491 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007492 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007493}
7494
7495static void MSLComment(void *context,const xmlChar *value)
7496{
7497 MSLInfo
7498 *msl_info;
7499
7500 /*
7501 A comment has been parsed.
7502 */
7503 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7504 " SAX.comment(%s)",value);
7505 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007506 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007507}
7508
7509static void MSLWarning(void *context,const char *format,...)
7510{
7511 char
7512 *message,
7513 reason[MaxTextExtent];
7514
7515 MSLInfo
7516 *msl_info;
7517
7518 va_list
7519 operands;
7520
7521 /**
7522 Display and format a warning messages, gives file, line, position and
7523 extra parameters.
7524 */
7525 va_start(operands,format);
7526 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.warning: ");
7527 (void) LogMagickEvent(CoderEvent,GetMagickModule(),format,operands);
7528 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007529 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007530#if !defined(MAGICKCORE_HAVE_VSNPRINTF)
7531 (void) vsprintf(reason,format,operands);
7532#else
7533 (void) vsnprintf(reason,MaxTextExtent,format,operands);
7534#endif
7535 message=GetExceptionMessage(errno);
7536 ThrowMSLException(CoderError,reason,message);
7537 message=DestroyString(message);
7538 va_end(operands);
7539}
7540
7541static void MSLError(void *context,const char *format,...)
7542{
7543 char
7544 reason[MaxTextExtent];
7545
7546 MSLInfo
7547 *msl_info;
7548
7549 va_list
7550 operands;
7551
7552 /*
7553 Display and format a error formats, gives file, line, position and
7554 extra parameters.
7555 */
7556 va_start(operands,format);
7557 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.error: ");
7558 (void) LogMagickEvent(CoderEvent,GetMagickModule(),format,operands);
7559 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007560 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007561#if !defined(MAGICKCORE_HAVE_VSNPRINTF)
7562 (void) vsprintf(reason,format,operands);
7563#else
7564 (void) vsnprintf(reason,MaxTextExtent,format,operands);
7565#endif
7566 ThrowMSLException(DelegateFatalError,reason,"SAX error");
7567 va_end(operands);
7568}
7569
7570static void MSLCDataBlock(void *context,const xmlChar *value,int length)
7571{
7572 MSLInfo
7573 *msl_info;
7574
7575 xmlNodePtr
7576 child;
7577
7578 xmlParserCtxtPtr
7579 parser;
7580
7581 /*
7582 Called when a pcdata block has been parsed.
7583 */
7584 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7585 " SAX.pcdata(%s, %d)",value,length);
7586 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007587 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007588 parser=msl_info->parser;
7589 child=xmlGetLastChild(parser->node);
7590 if ((child != (xmlNodePtr) NULL) && (child->type == XML_CDATA_SECTION_NODE))
7591 {
7592 xmlTextConcat(child,value,length);
7593 return;
7594 }
7595 (void) xmlAddChild(parser->node,xmlNewCDataBlock(parser->myDoc,value,length));
7596}
7597
7598static void MSLExternalSubset(void *context,const xmlChar *name,
7599 const xmlChar *external_id,const xmlChar *system_id)
7600{
7601 MSLInfo
7602 *msl_info;
7603
7604 xmlParserCtxt
7605 parser_context;
7606
7607 xmlParserCtxtPtr
7608 parser;
7609
7610 xmlParserInputPtr
7611 input;
7612
7613 /*
7614 Does this document has an external subset?
7615 */
7616 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7617 " SAX.externalSubset(%s %s %s)",name,
cristyb988fe72009-09-16 01:01:10 +00007618 (external_id != (const xmlChar *) NULL ? (const char *) external_id : " "),
7619 (system_id != (const xmlChar *) NULL ? (const char *) system_id : " "));
cristy3ed852e2009-09-05 21:47:34 +00007620 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007621 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007622 parser=msl_info->parser;
7623 if (((external_id == NULL) && (system_id == NULL)) ||
7624 ((parser->validate == 0) || (parser->wellFormed == 0) ||
7625 (msl_info->document == 0)))
7626 return;
7627 input=MSLResolveEntity(context,external_id,system_id);
7628 if (input == NULL)
7629 return;
7630 (void) xmlNewDtd(msl_info->document,name,external_id,system_id);
7631 parser_context=(*parser);
7632 parser->inputTab=(xmlParserInputPtr *) xmlMalloc(5*sizeof(*parser->inputTab));
7633 if (parser->inputTab == (xmlParserInputPtr *) NULL)
7634 {
7635 parser->errNo=XML_ERR_NO_MEMORY;
7636 parser->input=parser_context.input;
7637 parser->inputNr=parser_context.inputNr;
7638 parser->inputMax=parser_context.inputMax;
7639 parser->inputTab=parser_context.inputTab;
7640 return;
7641 }
7642 parser->inputNr=0;
7643 parser->inputMax=5;
7644 parser->input=NULL;
7645 xmlPushInput(parser,input);
7646 (void) xmlSwitchEncoding(parser,xmlDetectCharEncoding(parser->input->cur,4));
7647 if (input->filename == (char *) NULL)
7648 input->filename=(char *) xmlStrdup(system_id);
7649 input->line=1;
7650 input->col=1;
7651 input->base=parser->input->cur;
7652 input->cur=parser->input->cur;
7653 input->free=NULL;
7654 xmlParseExternalSubset(parser,external_id,system_id);
7655 while (parser->inputNr > 1)
7656 (void) xmlPopInput(parser);
7657 xmlFreeInputStream(parser->input);
7658 xmlFree(parser->inputTab);
7659 parser->input=parser_context.input;
7660 parser->inputNr=parser_context.inputNr;
7661 parser->inputMax=parser_context.inputMax;
7662 parser->inputTab=parser_context.inputTab;
7663}
7664
7665#if defined(__cplusplus) || defined(c_plusplus)
7666}
7667#endif
7668
7669static MagickBooleanType ProcessMSLScript(const ImageInfo *image_info,Image **image,
7670 ExceptionInfo *exception)
7671{
cristy3ed852e2009-09-05 21:47:34 +00007672 char
7673 message[MaxTextExtent];
7674
7675 Image
7676 *msl_image;
7677
7678 int
7679 status;
7680
cristybb503372010-05-27 20:51:26 +00007681 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00007682 n;
7683
7684 MSLInfo
7685 msl_info;
7686
cristy5f6f01c2009-11-19 19:36:42 +00007687 xmlSAXHandler
7688 sax_modules;
7689
cristy3ed852e2009-09-05 21:47:34 +00007690 xmlSAXHandlerPtr
cristy5f6f01c2009-11-19 19:36:42 +00007691 sax_handler;
cristy3ed852e2009-09-05 21:47:34 +00007692
7693 /*
7694 Open image file.
7695 */
7696 assert(image_info != (const ImageInfo *) NULL);
7697 assert(image_info->signature == MagickSignature);
7698 if (image_info->debug != MagickFalse)
cristy5f6f01c2009-11-19 19:36:42 +00007699 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
7700 image_info->filename);
cristy3ed852e2009-09-05 21:47:34 +00007701 assert(image != (Image **) NULL);
7702 msl_image=AcquireImage(image_info);
7703 status=OpenBlob(image_info,msl_image,ReadBinaryBlobMode,exception);
7704 if (status == MagickFalse)
7705 {
7706 ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
7707 msl_image->filename);
7708 msl_image=DestroyImageList(msl_image);
7709 return(MagickFalse);
7710 }
7711 msl_image->columns=1;
7712 msl_image->rows=1;
7713 /*
7714 Parse MSL file.
7715 */
7716 (void) ResetMagickMemory(&msl_info,0,sizeof(msl_info));
7717 msl_info.exception=exception;
7718 msl_info.image_info=(ImageInfo **) AcquireMagickMemory(
7719 sizeof(*msl_info.image_info));
7720 msl_info.draw_info=(DrawInfo **) AcquireMagickMemory(
7721 sizeof(*msl_info.draw_info));
7722 /* top of the stack is the MSL file itself */
cristy73bd4a52010-10-05 11:24:23 +00007723 msl_info.image=(Image **) AcquireMagickMemory(sizeof(*msl_info.image));
cristy3ed852e2009-09-05 21:47:34 +00007724 msl_info.attributes=(Image **) AcquireMagickMemory(
7725 sizeof(*msl_info.attributes));
7726 msl_info.group_info=(MSLGroupInfo *) AcquireMagickMemory(
7727 sizeof(*msl_info.group_info));
7728 if ((msl_info.image_info == (ImageInfo **) NULL) ||
7729 (msl_info.image == (Image **) NULL) ||
7730 (msl_info.attributes == (Image **) NULL) ||
7731 (msl_info.group_info == (MSLGroupInfo *) NULL))
7732 ThrowFatalException(ResourceLimitFatalError,
7733 "UnableToInterpretMSLImage");
7734 *msl_info.image_info=CloneImageInfo(image_info);
7735 *msl_info.draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL);
7736 *msl_info.attributes=AcquireImage(image_info);
7737 msl_info.group_info[0].numImages=0;
7738 /* the first slot is used to point to the MSL file image */
7739 *msl_info.image=msl_image;
7740 if (*image != (Image *) NULL)
7741 MSLPushImage(&msl_info,*image);
7742 (void) xmlSubstituteEntitiesDefault(1);
cristy5f6f01c2009-11-19 19:36:42 +00007743 (void) ResetMagickMemory(&sax_modules,0,sizeof(sax_modules));
7744 sax_modules.internalSubset=MSLInternalSubset;
7745 sax_modules.isStandalone=MSLIsStandalone;
7746 sax_modules.hasInternalSubset=MSLHasInternalSubset;
7747 sax_modules.hasExternalSubset=MSLHasExternalSubset;
7748 sax_modules.resolveEntity=MSLResolveEntity;
7749 sax_modules.getEntity=MSLGetEntity;
7750 sax_modules.entityDecl=MSLEntityDeclaration;
7751 sax_modules.notationDecl=MSLNotationDeclaration;
7752 sax_modules.attributeDecl=MSLAttributeDeclaration;
7753 sax_modules.elementDecl=MSLElementDeclaration;
7754 sax_modules.unparsedEntityDecl=MSLUnparsedEntityDeclaration;
7755 sax_modules.setDocumentLocator=MSLSetDocumentLocator;
7756 sax_modules.startDocument=MSLStartDocument;
7757 sax_modules.endDocument=MSLEndDocument;
7758 sax_modules.startElement=MSLStartElement;
7759 sax_modules.endElement=MSLEndElement;
7760 sax_modules.reference=MSLReference;
7761 sax_modules.characters=MSLCharacters;
7762 sax_modules.ignorableWhitespace=MSLIgnorableWhitespace;
7763 sax_modules.processingInstruction=MSLProcessingInstructions;
7764 sax_modules.comment=MSLComment;
7765 sax_modules.warning=MSLWarning;
7766 sax_modules.error=MSLError;
7767 sax_modules.fatalError=MSLError;
7768 sax_modules.getParameterEntity=MSLGetParameterEntity;
7769 sax_modules.cdataBlock=MSLCDataBlock;
7770 sax_modules.externalSubset=MSLExternalSubset;
7771 sax_handler=(&sax_modules);
7772 msl_info.parser=xmlCreatePushParserCtxt(sax_handler,&msl_info,(char *) NULL,0,
cristy3ed852e2009-09-05 21:47:34 +00007773 msl_image->filename);
7774 while (ReadBlobString(msl_image,message) != (char *) NULL)
7775 {
cristybb503372010-05-27 20:51:26 +00007776 n=(ssize_t) strlen(message);
cristy3ed852e2009-09-05 21:47:34 +00007777 if (n == 0)
7778 continue;
7779 status=xmlParseChunk(msl_info.parser,message,(int) n,MagickFalse);
7780 if (status != 0)
7781 break;
7782 (void) xmlParseChunk(msl_info.parser," ",1,MagickFalse);
7783 if (msl_info.exception->severity >= ErrorException)
7784 break;
7785 }
7786 if (msl_info.exception->severity == UndefinedException)
7787 (void) xmlParseChunk(msl_info.parser," ",1,MagickTrue);
7788 xmlFreeParserCtxt(msl_info.parser);
7789 (void) LogMagickEvent(CoderEvent,GetMagickModule(),"end SAX");
7790 xmlCleanupParser();
7791 msl_info.group_info=(MSLGroupInfo *) RelinquishMagickMemory(
7792 msl_info.group_info);
7793 if (*image == (Image *) NULL)
7794 *image=(*msl_info.image);
cristy5f6f01c2009-11-19 19:36:42 +00007795 if ((*msl_info.image)->exception.severity != UndefinedException)
7796 return(MagickFalse);
7797 return(MagickTrue);
cristy3ed852e2009-09-05 21:47:34 +00007798}
7799
7800static Image *ReadMSLImage(const ImageInfo *image_info,ExceptionInfo *exception)
7801{
7802 Image
7803 *image;
7804
7805 /*
7806 Open image file.
7807 */
7808 assert(image_info != (const ImageInfo *) NULL);
7809 assert(image_info->signature == MagickSignature);
7810 if (image_info->debug != MagickFalse)
7811 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
7812 image_info->filename);
7813 assert(exception != (ExceptionInfo *) NULL);
7814 assert(exception->signature == MagickSignature);
7815 image=(Image *) NULL;
7816 (void) ProcessMSLScript(image_info,&image,exception);
7817 return(GetFirstImageInList(image));
7818}
7819#endif
7820
7821/*
7822%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7823% %
7824% %
7825% %
7826% R e g i s t e r M S L I m a g e %
7827% %
7828% %
7829% %
7830%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7831%
7832% RegisterMSLImage() adds attributes for the MSL image format to
7833% the list of supported formats. The attributes include the image format
7834% tag, a method to read and/or write the format, whether the format
7835% supports the saving of more than one frame to the same file or blob,
7836% whether the format supports native in-memory I/O, and a brief
7837% description of the format.
7838%
7839% The format of the RegisterMSLImage method is:
7840%
cristybb503372010-05-27 20:51:26 +00007841% size_t RegisterMSLImage(void)
cristy3ed852e2009-09-05 21:47:34 +00007842%
7843*/
cristybb503372010-05-27 20:51:26 +00007844ModuleExport size_t RegisterMSLImage(void)
cristy3ed852e2009-09-05 21:47:34 +00007845{
7846 MagickInfo
7847 *entry;
7848
7849 entry=SetMagickInfo("MSL");
7850#if defined(MAGICKCORE_XML_DELEGATE)
7851 entry->decoder=(DecodeImageHandler *) ReadMSLImage;
7852 entry->encoder=(EncodeImageHandler *) WriteMSLImage;
7853#endif
7854 entry->description=ConstantString("Magick Scripting Language");
7855 entry->module=ConstantString("MSL");
7856 (void) RegisterMagickInfo(entry);
7857 return(MagickImageCoderSignature);
7858}
7859
cristy6b9f7ed2010-04-24 01:08:02 +00007860#if defined(MAGICKCORE_XML_DELEGATE)
cristy3ed852e2009-09-05 21:47:34 +00007861/*
7862%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7863% %
7864% %
7865% %
cristyb988fe72009-09-16 01:01:10 +00007866% S e t M S L A t t r i b u t e s %
7867% %
7868% %
7869% %
7870%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7871%
7872% SetMSLAttributes() ...
7873%
7874% The format of the SetMSLAttributes method is:
7875%
7876% MagickBooleanType SetMSLAttributes(MSLInfo *msl_info,
cristyb20775d2009-09-16 01:51:41 +00007877% const char *keyword,const char *value)
cristyb988fe72009-09-16 01:01:10 +00007878%
7879% A description of each parameter follows:
7880%
7881% o msl_info: the MSL info.
7882%
cristyb20775d2009-09-16 01:51:41 +00007883% o keyword: the keyword.
7884%
7885% o value: the value.
cristyb988fe72009-09-16 01:01:10 +00007886%
7887*/
cristyb20775d2009-09-16 01:51:41 +00007888static MagickBooleanType SetMSLAttributes(MSLInfo *msl_info,const char *keyword,
7889 const char *value)
cristyb988fe72009-09-16 01:01:10 +00007890{
cristy4582cbb2009-09-23 00:35:43 +00007891 Image
7892 *attributes;
7893
cristyb20775d2009-09-16 01:51:41 +00007894 DrawInfo
7895 *draw_info;
cristyb988fe72009-09-16 01:01:10 +00007896
7897 ExceptionInfo
7898 *exception;
7899
cristy4582cbb2009-09-23 00:35:43 +00007900 GeometryInfo
7901 geometry_info;
7902
cristy4fa36e42009-09-18 14:24:06 +00007903 Image
7904 *image;
7905
cristyb20775d2009-09-16 01:51:41 +00007906 ImageInfo
7907 *image_info;
7908
cristy4582cbb2009-09-23 00:35:43 +00007909 int
7910 flags;
7911
cristybb503372010-05-27 20:51:26 +00007912 ssize_t
cristyb988fe72009-09-16 01:01:10 +00007913 n;
7914
cristyb988fe72009-09-16 01:01:10 +00007915 assert(msl_info != (MSLInfo *) NULL);
cristyb20775d2009-09-16 01:51:41 +00007916 if (keyword == (const char *) NULL)
7917 return(MagickTrue);
7918 if (value == (const char *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007919 return(MagickTrue);
7920 exception=msl_info->exception;
7921 n=msl_info->n;
cristy4582cbb2009-09-23 00:35:43 +00007922 attributes=msl_info->attributes[n];
cristyb20775d2009-09-16 01:51:41 +00007923 image_info=msl_info->image_info[n];
7924 draw_info=msl_info->draw_info[n];
cristy4fa36e42009-09-18 14:24:06 +00007925 image=msl_info->image[n];
cristyb20775d2009-09-16 01:51:41 +00007926 switch (*keyword)
cristyb988fe72009-09-16 01:01:10 +00007927 {
cristyfb758a52009-09-16 14:36:08 +00007928 case 'A':
7929 case 'a':
7930 {
7931 if (LocaleCompare(keyword,"adjoin") == 0)
7932 {
cristybb503372010-05-27 20:51:26 +00007933 ssize_t
cristyfb758a52009-09-16 14:36:08 +00007934 adjoin;
7935
cristy042ee782011-04-22 18:48:30 +00007936 adjoin=ParseCommandOption(MagickBooleanOptions,MagickFalse,value);
cristyfb758a52009-09-16 14:36:08 +00007937 if (adjoin < 0)
7938 ThrowMSLException(OptionError,"UnrecognizedType",value);
7939 image_info->adjoin=(MagickBooleanType) adjoin;
7940 break;
7941 }
cristy4fa36e42009-09-18 14:24:06 +00007942 if (LocaleCompare(keyword,"alpha") == 0)
7943 {
cristybb503372010-05-27 20:51:26 +00007944 ssize_t
cristy4fa36e42009-09-18 14:24:06 +00007945 alpha;
7946
cristy042ee782011-04-22 18:48:30 +00007947 alpha=ParseCommandOption(MagickAlphaOptions,MagickFalse,value);
cristy4fa36e42009-09-18 14:24:06 +00007948 if (alpha < 0)
7949 ThrowMSLException(OptionError,"UnrecognizedType",value);
cristy4582cbb2009-09-23 00:35:43 +00007950 if (image != (Image *) NULL)
cristy63240882011-08-05 19:05:27 +00007951 (void) SetImageAlphaChannel(image,(AlphaChannelType) alpha,
7952 exception);
cristy4582cbb2009-09-23 00:35:43 +00007953 break;
7954 }
7955 if (LocaleCompare(keyword,"antialias") == 0)
7956 {
cristybb503372010-05-27 20:51:26 +00007957 ssize_t
cristy4582cbb2009-09-23 00:35:43 +00007958 antialias;
7959
cristy042ee782011-04-22 18:48:30 +00007960 antialias=ParseCommandOption(MagickBooleanOptions,MagickFalse,value);
cristy4582cbb2009-09-23 00:35:43 +00007961 if (antialias < 0)
7962 ThrowMSLException(OptionError,"UnrecognizedGravityType",value);
7963 image_info->antialias=(MagickBooleanType) antialias;
7964 break;
7965 }
7966 if (LocaleCompare(keyword,"area-limit") == 0)
7967 {
7968 MagickSizeType
7969 limit;
7970
7971 limit=MagickResourceInfinity;
7972 if (LocaleCompare(value,"unlimited") != 0)
cristyf2f27272009-12-17 14:48:46 +00007973 limit=(MagickSizeType) SiPrefixToDouble(value,100.0);
cristy4582cbb2009-09-23 00:35:43 +00007974 (void) SetMagickResourceLimit(AreaResource,limit);
7975 break;
7976 }
7977 if (LocaleCompare(keyword,"attenuate") == 0)
7978 {
7979 (void) SetImageOption(image_info,keyword,value);
7980 break;
7981 }
7982 if (LocaleCompare(keyword,"authenticate") == 0)
7983 {
7984 (void) CloneString(&image_info->density,value);
cristy4fa36e42009-09-18 14:24:06 +00007985 break;
7986 }
cristyfb758a52009-09-16 14:36:08 +00007987 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7988 break;
7989 }
cristyb20775d2009-09-16 01:51:41 +00007990 case 'B':
7991 case 'b':
cristyb988fe72009-09-16 01:01:10 +00007992 {
cristyb20775d2009-09-16 01:51:41 +00007993 if (LocaleCompare(keyword,"background") == 0)
7994 {
cristy2c8b6312009-09-16 02:37:23 +00007995 (void) QueryColorDatabase(value,&image_info->background_color,
cristyb20775d2009-09-16 01:51:41 +00007996 exception);
7997 break;
7998 }
cristy4582cbb2009-09-23 00:35:43 +00007999 if (LocaleCompare(keyword,"bias") == 0)
8000 {
8001 if (image == (Image *) NULL)
8002 break;
cristyf2f27272009-12-17 14:48:46 +00008003 image->bias=SiPrefixToDouble(value,QuantumRange);
cristy4582cbb2009-09-23 00:35:43 +00008004 break;
8005 }
8006 if (LocaleCompare(keyword,"blue-primary") == 0)
8007 {
8008 if (image == (Image *) NULL)
8009 break;
8010 flags=ParseGeometry(value,&geometry_info);
8011 image->chromaticity.blue_primary.x=geometry_info.rho;
8012 image->chromaticity.blue_primary.y=geometry_info.sigma;
8013 if ((flags & SigmaValue) == 0)
8014 image->chromaticity.blue_primary.y=
8015 image->chromaticity.blue_primary.x;
8016 break;
8017 }
cristy2c8b6312009-09-16 02:37:23 +00008018 if (LocaleCompare(keyword,"bordercolor") == 0)
8019 {
8020 (void) QueryColorDatabase(value,&image_info->border_color,
8021 exception);
8022 break;
8023 }
8024 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8025 break;
8026 }
8027 case 'D':
8028 case 'd':
8029 {
8030 if (LocaleCompare(keyword,"density") == 0)
8031 {
8032 (void) CloneString(&image_info->density,value);
8033 (void) CloneString(&draw_info->density,value);
8034 break;
8035 }
cristyb20775d2009-09-16 01:51:41 +00008036 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8037 break;
8038 }
8039 case 'F':
8040 case 'f':
8041 {
8042 if (LocaleCompare(keyword,"fill") == 0)
8043 {
cristy2c8b6312009-09-16 02:37:23 +00008044 (void) QueryColorDatabase(value,&draw_info->fill,exception);
cristya30afaf2009-09-22 13:42:12 +00008045 (void) SetImageOption(image_info,keyword,value);
cristyb20775d2009-09-16 01:51:41 +00008046 break;
8047 }
cristy4582cbb2009-09-23 00:35:43 +00008048 if (LocaleCompare(keyword,"filename") == 0)
8049 {
8050 (void) CopyMagickString(image_info->filename,value,MaxTextExtent);
8051 break;
8052 }
8053 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8054 break;
8055 }
8056 case 'G':
8057 case 'g':
8058 {
8059 if (LocaleCompare(keyword,"gravity") == 0)
8060 {
cristybb503372010-05-27 20:51:26 +00008061 ssize_t
cristy4582cbb2009-09-23 00:35:43 +00008062 gravity;
8063
cristy042ee782011-04-22 18:48:30 +00008064 gravity=ParseCommandOption(MagickGravityOptions,MagickFalse,value);
cristy4582cbb2009-09-23 00:35:43 +00008065 if (gravity < 0)
8066 ThrowMSLException(OptionError,"UnrecognizedGravityType",value);
8067 (void) SetImageOption(image_info,keyword,value);
8068 break;
8069 }
cristyb20775d2009-09-16 01:51:41 +00008070 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8071 break;
8072 }
8073 case 'I':
8074 case 'i':
8075 {
8076 if (LocaleCompare(keyword,"id") == 0)
8077 {
cristy4582cbb2009-09-23 00:35:43 +00008078 (void) SetImageProperty(attributes,keyword,value);
cristy2c8b6312009-09-16 02:37:23 +00008079 break;
8080 }
8081 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8082 break;
8083 }
8084 case 'M':
8085 case 'm':
8086 {
8087 if (LocaleCompare(keyword,"magick") == 0)
8088 {
8089 (void) CopyMagickString(image_info->magick,value,MaxTextExtent);
8090 break;
8091 }
cristy2c8b6312009-09-16 02:37:23 +00008092 if (LocaleCompare(keyword,"mattecolor") == 0)
8093 {
8094 (void) QueryColorDatabase(value,&image_info->matte_color,
8095 exception);
cristyb20775d2009-09-16 01:51:41 +00008096 break;
8097 }
8098 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8099 break;
8100 }
8101 case 'P':
8102 case 'p':
8103 {
8104 if (LocaleCompare(keyword,"pointsize") == 0)
8105 {
cristyc1acd842011-05-19 23:05:47 +00008106 image_info->pointsize=InterpretLocaleValue(value,(char **) NULL);
8107 draw_info->pointsize=InterpretLocaleValue(value,(char **) NULL);
cristyb20775d2009-09-16 01:51:41 +00008108 break;
8109 }
8110 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8111 break;
8112 }
cristy4582cbb2009-09-23 00:35:43 +00008113 case 'Q':
8114 case 'q':
8115 {
8116 if (LocaleCompare(keyword,"quality") == 0)
8117 {
cristyf2f27272009-12-17 14:48:46 +00008118 image_info->quality=StringToLong(value);
cristy4582cbb2009-09-23 00:35:43 +00008119 if (image == (Image *) NULL)
8120 break;
cristyf2f27272009-12-17 14:48:46 +00008121 image->quality=StringToLong(value);
cristy4582cbb2009-09-23 00:35:43 +00008122 break;
8123 }
8124 break;
8125 }
cristyb20775d2009-09-16 01:51:41 +00008126 case 'S':
8127 case 's':
8128 {
8129 if (LocaleCompare(keyword,"size") == 0)
8130 {
cristy2c8b6312009-09-16 02:37:23 +00008131 (void) CloneString(&image_info->size,value);
cristyb20775d2009-09-16 01:51:41 +00008132 break;
8133 }
8134 if (LocaleCompare(keyword,"stroke") == 0)
8135 {
cristy2c8b6312009-09-16 02:37:23 +00008136 (void) QueryColorDatabase(value,&draw_info->stroke,exception);
cristya30afaf2009-09-22 13:42:12 +00008137 (void) SetImageOption(image_info,keyword,value);
cristyb20775d2009-09-16 01:51:41 +00008138 break;
8139 }
8140 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8141 break;
8142 }
8143 default:
8144 {
8145 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8146 break;
cristyb988fe72009-09-16 01:01:10 +00008147 }
8148 }
8149 return(MagickTrue);
8150}
cristy6b9f7ed2010-04-24 01:08:02 +00008151#endif
cristyb988fe72009-09-16 01:01:10 +00008152
8153/*
8154%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8155% %
8156% %
8157% %
cristy3ed852e2009-09-05 21:47:34 +00008158% U n r e g i s t e r M S L I m a g e %
8159% %
8160% %
8161% %
8162%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8163%
8164% UnregisterMSLImage() removes format registrations made by the
8165% MSL module from the list of supported formats.
8166%
8167% The format of the UnregisterMSLImage method is:
8168%
8169% UnregisterMSLImage(void)
8170%
8171*/
8172ModuleExport void UnregisterMSLImage(void)
8173{
8174 (void) UnregisterMagickInfo("MSL");
8175}
8176
8177#if defined(MAGICKCORE_XML_DELEGATE)
8178/*
8179%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8180% %
8181% %
8182% %
8183% W r i t e M S L I m a g e %
8184% %
8185% %
8186% %
8187%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8188%
8189% WriteMSLImage() writes an image to a file in MVG image format.
8190%
8191% The format of the WriteMSLImage method is:
8192%
cristy1e178e72011-08-28 19:44:34 +00008193% MagickBooleanType WriteMSLImage(const ImageInfo *image_info,
8194% Image *image,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00008195%
8196% A description of each parameter follows.
8197%
8198% o image_info: the image info.
8199%
8200% o image: The image.
8201%
cristy1e178e72011-08-28 19:44:34 +00008202% o exception: return any errors or warnings in this structure.
8203%
cristy3ed852e2009-09-05 21:47:34 +00008204*/
cristy1e178e72011-08-28 19:44:34 +00008205static MagickBooleanType WriteMSLImage(const ImageInfo *image_info,Image *image,
8206 ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00008207{
8208 assert(image_info != (const ImageInfo *) NULL);
8209 assert(image_info->signature == MagickSignature);
8210 assert(image != (Image *) NULL);
8211 assert(image->signature == MagickSignature);
8212 if (image->debug != MagickFalse)
8213 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
8214 (void) ReferenceImage(image);
cristy1e178e72011-08-28 19:44:34 +00008215 (void) ProcessMSLScript(image_info,&image,exception);
cristy3ed852e2009-09-05 21:47:34 +00008216 return(MagickTrue);
8217}
8218#endif