blob: 042d8ede3fb048b5a34c0b52f7f9207d5469c882 [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,
1242 geometry_info.sigma,&msl_info->image[n]->exception);
cristybd5a96c2011-08-21 00:04:26 +00001243 (void) SetPixelChannelMap(msl_info->image[n],channel_mask);
cristy3ed852e2009-09-05 21:47:34 +00001244 if (blur_image == (Image *) NULL)
1245 break;
1246 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1247 msl_info->image[n]=blur_image;
1248 break;
1249 }
cristyb988fe72009-09-16 01:01:10 +00001250 if (LocaleCompare((const char *) tag,"border") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001251 {
1252 Image
1253 *border_image;
1254
1255 /*
1256 Border image.
1257 */
1258 if (msl_info->image[n] == (Image *) NULL)
1259 {
cristyb988fe72009-09-16 01:01:10 +00001260 ThrowMSLException(OptionError,"NoImagesDefined",
1261 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001262 break;
1263 }
1264 SetGeometry(msl_info->image[n],&geometry);
1265 if (attributes != (const xmlChar **) NULL)
1266 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1267 {
1268 keyword=(const char *) attributes[i++];
1269 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00001270 msl_info->attributes[n],(const char *) attributes[i],
1271 &exception);
cristy3ed852e2009-09-05 21:47:34 +00001272 CloneString(&value,attribute);
1273 switch (*keyword)
1274 {
1275 case 'C':
1276 case 'c':
1277 {
1278 if (LocaleCompare(keyword,"compose") == 0)
1279 {
cristy042ee782011-04-22 18:48:30 +00001280 option=ParseCommandOption(MagickComposeOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00001281 value);
1282 if (option < 0)
1283 ThrowMSLException(OptionError,"UnrecognizedComposeType",
1284 value);
1285 msl_info->image[n]->compose=(CompositeOperator) option;
1286 break;
1287 }
1288 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1289 keyword);
1290 break;
1291 }
1292 case 'F':
1293 case 'f':
1294 {
1295 if (LocaleCompare(keyword, "fill") == 0)
1296 {
1297 (void) QueryColorDatabase(value,
1298 &msl_info->image[n]->border_color,&exception);
1299 break;
1300 }
1301 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1302 keyword);
1303 break;
1304 }
1305 case 'G':
1306 case 'g':
1307 {
1308 if (LocaleCompare(keyword,"geometry") == 0)
1309 {
1310 flags=ParsePageGeometry(msl_info->image[n],value,
1311 &geometry,&exception);
1312 if ((flags & HeightValue) == 0)
1313 geometry.height=geometry.width;
1314 break;
1315 }
1316 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1317 keyword);
1318 break;
1319 }
1320 case 'H':
1321 case 'h':
1322 {
1323 if (LocaleCompare(keyword,"height") == 0)
1324 {
cristyf2f27272009-12-17 14:48:46 +00001325 geometry.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001326 break;
1327 }
1328 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1329 keyword);
1330 break;
1331 }
1332 case 'W':
1333 case 'w':
1334 {
1335 if (LocaleCompare(keyword,"width") == 0)
1336 {
cristyf2f27272009-12-17 14:48:46 +00001337 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001338 break;
1339 }
1340 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1341 keyword);
1342 break;
1343 }
1344 default:
1345 {
1346 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1347 keyword);
1348 break;
1349 }
1350 }
1351 }
1352 border_image=BorderImage(msl_info->image[n],&geometry,
1353 &msl_info->image[n]->exception);
1354 if (border_image == (Image *) NULL)
1355 break;
1356 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1357 msl_info->image[n]=border_image;
1358 break;
1359 }
1360 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
1361 }
1362 case 'C':
1363 case 'c':
1364 {
cristyb988fe72009-09-16 01:01:10 +00001365 if (LocaleCompare((const char *) tag,"colorize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001366 {
1367 char
1368 opacity[MaxTextExtent];
1369
1370 Image
1371 *colorize_image;
1372
1373 PixelPacket
1374 target;
1375
1376 /*
1377 Add noise image.
1378 */
1379 if (msl_info->image[n] == (Image *) NULL)
1380 {
cristyb988fe72009-09-16 01:01:10 +00001381 ThrowMSLException(OptionError,"NoImagesDefined",
1382 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001383 break;
1384 }
1385 target=msl_info->image[n]->background_color;
1386 (void) CopyMagickString(opacity,"100",MaxTextExtent);
1387 if (attributes != (const xmlChar **) NULL)
1388 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1389 {
1390 keyword=(const char *) attributes[i++];
1391 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00001392 msl_info->attributes[n],(const char *) attributes[i],
1393 &exception);
cristy3ed852e2009-09-05 21:47:34 +00001394 CloneString(&value,attribute);
1395 switch (*keyword)
1396 {
1397 case 'F':
1398 case 'f':
1399 {
1400 if (LocaleCompare(keyword,"fill") == 0)
1401 {
1402 (void) QueryColorDatabase(value,&target,
1403 &msl_info->image[n]->exception);
1404 break;
1405 }
1406 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1407 keyword);
1408 break;
1409 }
1410 case 'O':
1411 case 'o':
1412 {
1413 if (LocaleCompare(keyword,"opacity") == 0)
1414 {
1415 (void) CopyMagickString(opacity,value,MaxTextExtent);
1416 break;
1417 }
1418 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1419 keyword);
1420 break;
1421 }
1422 default:
1423 {
1424 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1425 keyword);
1426 break;
1427 }
1428 }
1429 }
1430 colorize_image=ColorizeImage(msl_info->image[n],opacity,target,
1431 &msl_info->image[n]->exception);
1432 if (colorize_image == (Image *) NULL)
1433 break;
1434 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1435 msl_info->image[n]=colorize_image;
1436 break;
1437 }
cristyb988fe72009-09-16 01:01:10 +00001438 if (LocaleCompare((const char *) tag, "charcoal") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001439 {
1440 double radius = 0.0,
1441 sigma = 1.0;
1442
1443 if (msl_info->image[n] == (Image *) NULL)
1444 {
cristyb988fe72009-09-16 01:01:10 +00001445 ThrowMSLException(OptionError,"NoImagesDefined",
1446 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001447 break;
1448 }
1449 /*
1450 NOTE: charcoal can have no attributes, since we use all the defaults!
1451 */
1452 if (attributes != (const xmlChar **) NULL)
1453 {
1454 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1455 {
1456 keyword=(const char *) attributes[i++];
1457 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00001458 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00001459 switch (*keyword)
1460 {
1461 case 'R':
1462 case 'r':
1463 {
1464 if (LocaleCompare(keyword, "radius") == 0)
1465 {
cristyc1acd842011-05-19 23:05:47 +00001466 radius = InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00001467 break;
1468 }
1469 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
1470 break;
1471 }
1472 case 'S':
1473 case 's':
1474 {
1475 if (LocaleCompare(keyword,"sigma") == 0)
1476 {
cristyf2f27272009-12-17 14:48:46 +00001477 sigma = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00001478 break;
1479 }
1480 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
1481 break;
1482 }
1483 default:
1484 {
1485 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
1486 break;
1487 }
1488 }
1489 }
1490 }
1491
1492 /*
1493 charcoal image.
1494 */
1495 {
1496 Image
1497 *newImage;
1498
1499 newImage=CharcoalImage(msl_info->image[n],radius,sigma,
1500 &msl_info->image[n]->exception);
1501 if (newImage == (Image *) NULL)
1502 break;
1503 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1504 msl_info->image[n]=newImage;
1505 break;
1506 }
1507 }
cristyb988fe72009-09-16 01:01:10 +00001508 if (LocaleCompare((const char *) tag,"chop") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001509 {
1510 Image
1511 *chop_image;
1512
1513 /*
1514 Chop image.
1515 */
1516 if (msl_info->image[n] == (Image *) NULL)
1517 {
cristyb988fe72009-09-16 01:01:10 +00001518 ThrowMSLException(OptionError,"NoImagesDefined",
1519 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001520 break;
1521 }
1522 SetGeometry(msl_info->image[n],&geometry);
1523 if (attributes != (const xmlChar **) NULL)
1524 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1525 {
1526 keyword=(const char *) attributes[i++];
1527 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00001528 msl_info->attributes[n],(const char *) attributes[i],
1529 &exception);
cristy3ed852e2009-09-05 21:47:34 +00001530 CloneString(&value,attribute);
1531 switch (*keyword)
1532 {
1533 case 'G':
1534 case 'g':
1535 {
1536 if (LocaleCompare(keyword,"geometry") == 0)
1537 {
1538 flags=ParsePageGeometry(msl_info->image[n],value,
1539 &geometry,&exception);
1540 if ((flags & HeightValue) == 0)
1541 geometry.height=geometry.width;
1542 break;
1543 }
1544 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1545 keyword);
1546 break;
1547 }
1548 case 'H':
1549 case 'h':
1550 {
1551 if (LocaleCompare(keyword,"height") == 0)
1552 {
cristyf2f27272009-12-17 14:48:46 +00001553 geometry.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001554 break;
1555 }
1556 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1557 keyword);
1558 break;
1559 }
1560 case 'W':
1561 case 'w':
1562 {
1563 if (LocaleCompare(keyword,"width") == 0)
1564 {
cristyf2f27272009-12-17 14:48:46 +00001565 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001566 break;
1567 }
1568 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1569 keyword);
1570 break;
1571 }
1572 case 'X':
1573 case 'x':
1574 {
1575 if (LocaleCompare(keyword,"x") == 0)
1576 {
cristyf2f27272009-12-17 14:48:46 +00001577 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001578 break;
1579 }
1580 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1581 keyword);
1582 break;
1583 }
1584 case 'Y':
1585 case 'y':
1586 {
1587 if (LocaleCompare(keyword,"y") == 0)
1588 {
cristyf2f27272009-12-17 14:48:46 +00001589 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001590 break;
1591 }
1592 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1593 keyword);
1594 break;
1595 }
1596 default:
1597 {
1598 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1599 keyword);
1600 break;
1601 }
1602 }
1603 }
1604 chop_image=ChopImage(msl_info->image[n],&geometry,
1605 &msl_info->image[n]->exception);
1606 if (chop_image == (Image *) NULL)
1607 break;
1608 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1609 msl_info->image[n]=chop_image;
1610 break;
1611 }
cristyb988fe72009-09-16 01:01:10 +00001612 if (LocaleCompare((const char *) tag,"color-floodfill") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001613 {
1614 PaintMethod
1615 paint_method;
1616
cristy4c08aed2011-07-01 19:47:50 +00001617 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00001618 target;
1619
1620 /*
1621 Color floodfill image.
1622 */
1623 if (msl_info->image[n] == (Image *) NULL)
1624 {
cristyb988fe72009-09-16 01:01:10 +00001625 ThrowMSLException(OptionError,"NoImagesDefined",
1626 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001627 break;
1628 }
1629 draw_info=CloneDrawInfo(msl_info->image_info[n],
1630 msl_info->draw_info[n]);
1631 SetGeometry(msl_info->image[n],&geometry);
1632 paint_method=FloodfillMethod;
1633 if (attributes != (const xmlChar **) NULL)
1634 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1635 {
1636 keyword=(const char *) attributes[i++];
1637 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00001638 msl_info->attributes[n],(const char *) attributes[i],
1639 &exception);
cristy3ed852e2009-09-05 21:47:34 +00001640 CloneString(&value,attribute);
1641 switch (*keyword)
1642 {
1643 case 'B':
1644 case 'b':
1645 {
1646 if (LocaleCompare(keyword,"bordercolor") == 0)
1647 {
1648 (void) QueryMagickColor(value,&target,&exception);
1649 paint_method=FillToBorderMethod;
1650 break;
1651 }
1652 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1653 keyword);
1654 break;
1655 }
1656 case 'F':
1657 case 'f':
1658 {
1659 if (LocaleCompare(keyword,"fill") == 0)
1660 {
1661 (void) QueryColorDatabase(value,&draw_info->fill,
1662 &exception);
1663 break;
1664 }
1665 if (LocaleCompare(keyword,"fuzz") == 0)
1666 {
cristyc1acd842011-05-19 23:05:47 +00001667 msl_info->image[n]->fuzz=InterpretLocaleValue(value,
1668 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00001669 break;
1670 }
1671 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1672 keyword);
1673 break;
1674 }
1675 case 'G':
1676 case 'g':
1677 {
1678 if (LocaleCompare(keyword,"geometry") == 0)
1679 {
1680 flags=ParsePageGeometry(msl_info->image[n],value,
1681 &geometry,&exception);
1682 if ((flags & HeightValue) == 0)
1683 geometry.height=geometry.width;
1684 (void) GetOneVirtualMagickPixel(msl_info->image[n],
1685 geometry.x,geometry.y,&target,&exception);
1686 break;
1687 }
1688 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1689 keyword);
1690 break;
1691 }
1692 case 'X':
1693 case 'x':
1694 {
1695 if (LocaleCompare(keyword,"x") == 0)
1696 {
cristyf2f27272009-12-17 14:48:46 +00001697 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001698 (void) GetOneVirtualMagickPixel(msl_info->image[n],
1699 geometry.x,geometry.y,&target,&exception);
1700 break;
1701 }
1702 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1703 keyword);
1704 break;
1705 }
1706 case 'Y':
1707 case 'y':
1708 {
1709 if (LocaleCompare(keyword,"y") == 0)
1710 {
cristyf2f27272009-12-17 14:48:46 +00001711 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001712 (void) GetOneVirtualMagickPixel(msl_info->image[n],
1713 geometry.x,geometry.y,&target,&exception);
1714 break;
1715 }
1716 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1717 keyword);
1718 break;
1719 }
1720 default:
1721 {
1722 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1723 keyword);
1724 break;
1725 }
1726 }
1727 }
cristyd42d9952011-07-08 14:21:50 +00001728 (void) FloodfillPaintImage(msl_info->image[n],draw_info,&target,
1729 geometry.x,geometry.y,paint_method == FloodfillMethod ?
cristy189e84c2011-08-27 18:08:53 +00001730 MagickFalse : MagickTrue,&msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00001731 draw_info=DestroyDrawInfo(draw_info);
1732 break;
1733 }
cristyb988fe72009-09-16 01:01:10 +00001734 if (LocaleCompare((const char *) tag,"comment") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001735 break;
cristyb988fe72009-09-16 01:01:10 +00001736 if (LocaleCompare((const char *) tag,"composite") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001737 {
1738 char
1739 composite_geometry[MaxTextExtent];
1740
1741 CompositeOperator
1742 compose;
1743
1744 Image
1745 *composite_image,
1746 *rotate_image;
1747
1748 PixelPacket
1749 target;
1750
1751 /*
1752 Composite image.
1753 */
1754 if (msl_info->image[n] == (Image *) NULL)
1755 {
cristyb988fe72009-09-16 01:01:10 +00001756 ThrowMSLException(OptionError,"NoImagesDefined",
1757 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001758 break;
1759 }
1760 composite_image=NewImageList();
1761 compose=OverCompositeOp;
1762 if (attributes != (const xmlChar **) NULL)
1763 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1764 {
1765 keyword=(const char *) attributes[i++];
1766 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00001767 msl_info->attributes[n],(const char *) attributes[i],
1768 &exception);
cristy3ed852e2009-09-05 21:47:34 +00001769 CloneString(&value,attribute);
1770 switch (*keyword)
1771 {
1772 case 'C':
1773 case 'c':
1774 {
1775 if (LocaleCompare(keyword,"compose") == 0)
1776 {
cristy042ee782011-04-22 18:48:30 +00001777 option=ParseCommandOption(MagickComposeOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00001778 value);
1779 if (option < 0)
1780 ThrowMSLException(OptionError,"UnrecognizedComposeType",
1781 value);
1782 compose=(CompositeOperator) option;
1783 break;
1784 }
1785 break;
1786 }
1787 case 'I':
1788 case 'i':
1789 {
1790 if (LocaleCompare(keyword,"image") == 0)
1791 for (j=0; j < msl_info->n; j++)
1792 {
1793 const char
1794 *attribute;
cristyb988fe72009-09-16 01:01:10 +00001795
cristy3ed852e2009-09-05 21:47:34 +00001796 attribute=GetImageProperty(msl_info->attributes[j],"id");
1797 if ((attribute != (const char *) NULL) &&
1798 (LocaleCompare(attribute,value) == 0))
1799 {
1800 composite_image=CloneImage(msl_info->image[j],0,0,
1801 MagickFalse,&exception);
1802 break;
1803 }
1804 }
1805 break;
1806 }
1807 default:
1808 break;
1809 }
1810 }
1811 if (composite_image == (Image *) NULL)
1812 break;
1813 rotate_image=NewImageList();
1814 SetGeometry(msl_info->image[n],&geometry);
1815 if (attributes != (const xmlChar **) NULL)
1816 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1817 {
1818 keyword=(const char *) attributes[i++];
1819 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00001820 msl_info->attributes[n],(const char *) attributes[i],
1821 &exception);
cristy3ed852e2009-09-05 21:47:34 +00001822 CloneString(&value,attribute);
1823 switch (*keyword)
1824 {
1825 case 'B':
1826 case 'b':
1827 {
1828 if (LocaleCompare(keyword,"blend") == 0)
1829 {
1830 (void) SetImageArtifact(composite_image,
1831 "compose:args",value);
1832 break;
1833 }
1834 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1835 keyword);
1836 break;
1837 }
1838 case 'C':
1839 case 'c':
1840 {
1841 if (LocaleCompare(keyword,"channel") == 0)
1842 {
1843 option=ParseChannelOption(value);
1844 if (option < 0)
1845 ThrowMSLException(OptionError,"UnrecognizedChannelType",
1846 value);
1847 channel=(ChannelType) option;
1848 break;
1849 }
1850 if (LocaleCompare(keyword, "color") == 0)
1851 {
1852 (void) QueryColorDatabase(value,
1853 &composite_image->background_color,&exception);
1854 break;
1855 }
1856 if (LocaleCompare(keyword,"compose") == 0)
1857 break;
1858 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1859 keyword);
1860 break;
1861 }
1862 case 'G':
1863 case 'g':
1864 {
1865 if (LocaleCompare(keyword,"geometry") == 0)
1866 {
1867 flags=ParsePageGeometry(msl_info->image[n],value,
1868 &geometry,&exception);
1869 if ((flags & HeightValue) == 0)
1870 geometry.height=geometry.width;
1871 (void) GetOneVirtualPixel(msl_info->image[n],geometry.x,
1872 geometry.y,&target,&exception);
1873 break;
1874 }
1875 if (LocaleCompare(keyword,"gravity") == 0)
1876 {
cristy042ee782011-04-22 18:48:30 +00001877 option=ParseCommandOption(MagickGravityOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00001878 value);
1879 if (option < 0)
1880 ThrowMSLException(OptionError,"UnrecognizedGravityType",
1881 value);
1882 msl_info->image[n]->gravity=(GravityType) option;
1883 break;
1884 }
1885 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1886 keyword);
1887 break;
1888 }
1889 case 'I':
1890 case 'i':
1891 {
1892 if (LocaleCompare(keyword,"image") == 0)
1893 break;
1894 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1895 keyword);
1896 break;
1897 }
1898 case 'M':
1899 case 'm':
1900 {
1901 if (LocaleCompare(keyword,"mask") == 0)
1902 for (j=0; j < msl_info->n; j++)
1903 {
1904 const char
1905 *attribute;
1906
1907 attribute=GetImageProperty(msl_info->attributes[j],"id");
1908 if ((attribute != (const char *) NULL) &&
1909 (LocaleCompare(value,value) == 0))
1910 {
cristy018f07f2011-09-04 21:15:19 +00001911 SetImageType(composite_image,TrueColorMatteType,
1912 &exception);
cristy3ed852e2009-09-05 21:47:34 +00001913 (void) CompositeImage(composite_image,
1914 CopyOpacityCompositeOp,msl_info->image[j],0,0);
1915 break;
1916 }
1917 }
1918 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1919 keyword);
1920 break;
1921 }
1922 case 'O':
1923 case 'o':
1924 {
1925 if (LocaleCompare(keyword,"opacity") == 0)
1926 {
cristybb503372010-05-27 20:51:26 +00001927 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001928 opacity,
1929 y;
cristyb988fe72009-09-16 01:01:10 +00001930
cristybb503372010-05-27 20:51:26 +00001931 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001932 x;
cristyb988fe72009-09-16 01:01:10 +00001933
cristy4c08aed2011-07-01 19:47:50 +00001934 register Quantum
cristy3ed852e2009-09-05 21:47:34 +00001935 *q;
cristyb988fe72009-09-16 01:01:10 +00001936
cristy3ed852e2009-09-05 21:47:34 +00001937 CacheView
1938 *composite_view;
1939
cristy4c08aed2011-07-01 19:47:50 +00001940 opacity=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001941 if (compose != DissolveCompositeOp)
1942 {
cristyb988fe72009-09-16 01:01:10 +00001943 (void) SetImageOpacity(composite_image,(Quantum)
1944 opacity);
cristy3ed852e2009-09-05 21:47:34 +00001945 break;
1946 }
1947 (void) SetImageArtifact(msl_info->image[n],
1948 "compose:args",value);
1949 if (composite_image->matte != MagickTrue)
cristy4c08aed2011-07-01 19:47:50 +00001950 (void) SetImageOpacity(composite_image,OpaqueAlpha);
cristy3ed852e2009-09-05 21:47:34 +00001951 composite_view=AcquireCacheView(composite_image);
cristybb503372010-05-27 20:51:26 +00001952 for (y=0; y < (ssize_t) composite_image->rows ; y++)
cristyb988fe72009-09-16 01:01:10 +00001953 {
cristy4c08aed2011-07-01 19:47:50 +00001954 q=GetCacheViewAuthenticPixels(composite_view,0,y,
1955 (ssize_t) composite_image->columns,1,&exception);
cristybb503372010-05-27 20:51:26 +00001956 for (x=0; x < (ssize_t) composite_image->columns; x++)
cristyb988fe72009-09-16 01:01:10 +00001957 {
cristy4c08aed2011-07-01 19:47:50 +00001958 if (GetPixelAlpha(composite_image,q) == OpaqueAlpha)
1959 SetPixelAlpha(composite_image,
1960 ClampToQuantum(opacity),q);
cristyed231572011-07-14 02:18:59 +00001961 q+=GetPixelChannels(composite_image);
cristy3ed852e2009-09-05 21:47:34 +00001962 }
1963 if (SyncCacheViewAuthenticPixels(composite_view,&exception) == MagickFalse)
1964 break;
1965 }
1966 composite_view=DestroyCacheView(composite_view);
1967 break;
1968 }
1969 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1970 keyword);
1971 break;
1972 }
1973 case 'R':
1974 case 'r':
1975 {
1976 if (LocaleCompare(keyword,"rotate") == 0)
1977 {
cristyc1acd842011-05-19 23:05:47 +00001978 rotate_image=RotateImage(composite_image,
1979 InterpretLocaleValue(value,(char **) NULL),&exception);
cristy3ed852e2009-09-05 21:47:34 +00001980 break;
1981 }
1982 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1983 keyword);
1984 break;
1985 }
1986 case 'T':
1987 case 't':
1988 {
1989 if (LocaleCompare(keyword,"tile") == 0)
1990 {
1991 MagickBooleanType
1992 tile;
1993
cristy042ee782011-04-22 18:48:30 +00001994 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00001995 value);
1996 if (option < 0)
1997 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
1998 value);
1999 tile=(MagickBooleanType) option;
cristyda16f162011-02-19 23:52:17 +00002000 (void) tile;
cristy3ed852e2009-09-05 21:47:34 +00002001 if (rotate_image != (Image *) NULL)
2002 (void) SetImageArtifact(rotate_image,
2003 "compose:outside-overlay","false");
2004 else
2005 (void) SetImageArtifact(composite_image,
2006 "compose:outside-overlay","false");
2007 image=msl_info->image[n];
2008 height=composite_image->rows;
2009 width=composite_image->columns;
cristyeaedf062010-05-29 22:36:02 +00002010 for (y=0; y < (ssize_t) image->rows; y+=(ssize_t) height)
2011 for (x=0; x < (ssize_t) image->columns; x+=(ssize_t) width)
cristy3ed852e2009-09-05 21:47:34 +00002012 {
2013 if (rotate_image != (Image *) NULL)
2014 (void) CompositeImage(image,compose,rotate_image,
2015 x,y);
2016 else
2017 (void) CompositeImage(image,compose,
2018 composite_image,x,y);
2019 }
2020 if (rotate_image != (Image *) NULL)
2021 rotate_image=DestroyImage(rotate_image);
2022 break;
2023 }
2024 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2025 keyword);
2026 break;
2027 }
2028 case 'X':
2029 case 'x':
2030 {
2031 if (LocaleCompare(keyword,"x") == 0)
2032 {
cristyf2f27272009-12-17 14:48:46 +00002033 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002034 (void) GetOneVirtualPixel(msl_info->image[n],geometry.x,
2035 geometry.y,&target,&exception);
2036 break;
2037 }
2038 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2039 keyword);
2040 break;
2041 }
2042 case 'Y':
2043 case 'y':
2044 {
2045 if (LocaleCompare(keyword,"y") == 0)
2046 {
cristyf2f27272009-12-17 14:48:46 +00002047 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002048 (void) GetOneVirtualPixel(msl_info->image[n],geometry.x,
2049 geometry.y,&target,&exception);
2050 break;
2051 }
2052 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2053 keyword);
2054 break;
2055 }
2056 default:
2057 {
2058 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2059 keyword);
2060 break;
2061 }
2062 }
2063 }
2064 image=msl_info->image[n];
cristyb51dff52011-05-19 16:55:47 +00002065 (void) FormatLocaleString(composite_geometry,MaxTextExtent,
cristye8c25f92010-06-03 00:53:06 +00002066 "%.20gx%.20g%+.20g%+.20g",(double) composite_image->columns,
2067 (double) composite_image->rows,(double) geometry.x,(double)
cristyf2faecf2010-05-28 19:19:36 +00002068 geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00002069 flags=ParseGravityGeometry(image,composite_geometry,&geometry,
2070 &exception);
cristybd5a96c2011-08-21 00:04:26 +00002071 channel_mask=SetPixelChannelMask(image,channel);
cristy3ed852e2009-09-05 21:47:34 +00002072 if (rotate_image == (Image *) NULL)
cristyf4ad9df2011-07-08 16:49:03 +00002073 CompositeImage(image,compose,composite_image,geometry.x,geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00002074 else
2075 {
2076 /*
2077 Rotate image.
2078 */
cristybb503372010-05-27 20:51:26 +00002079 geometry.x-=(ssize_t) (rotate_image->columns-
cristy3ed852e2009-09-05 21:47:34 +00002080 composite_image->columns)/2;
cristybb503372010-05-27 20:51:26 +00002081 geometry.y-=(ssize_t) (rotate_image->rows-composite_image->rows)/2;
cristyf4ad9df2011-07-08 16:49:03 +00002082 CompositeImage(image,compose,rotate_image,geometry.x,geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00002083 rotate_image=DestroyImage(rotate_image);
2084 }
cristybd5a96c2011-08-21 00:04:26 +00002085 (void) SetPixelChannelMask(image,channel_mask);
cristy3ed852e2009-09-05 21:47:34 +00002086 composite_image=DestroyImage(composite_image);
2087 break;
2088 }
cristyb988fe72009-09-16 01:01:10 +00002089 if (LocaleCompare((const char *) tag,"contrast") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002090 {
2091 MagickBooleanType
2092 sharpen;
2093
2094 /*
2095 Contrast image.
2096 */
2097 if (msl_info->image[n] == (Image *) NULL)
2098 {
cristyb988fe72009-09-16 01:01:10 +00002099 ThrowMSLException(OptionError,"NoImagesDefined",
2100 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002101 break;
2102 }
2103 sharpen=MagickFalse;
2104 if (attributes != (const xmlChar **) NULL)
2105 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2106 {
2107 keyword=(const char *) attributes[i++];
2108 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002109 msl_info->attributes[n],(const char *) attributes[i],
2110 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002111 CloneString(&value,attribute);
2112 switch (*keyword)
2113 {
2114 case 'S':
2115 case 's':
2116 {
2117 if (LocaleCompare(keyword,"sharpen") == 0)
2118 {
cristy042ee782011-04-22 18:48:30 +00002119 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002120 value);
2121 if (option < 0)
2122 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
2123 value);
2124 sharpen=(MagickBooleanType) option;
2125 break;
2126 }
2127 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2128 keyword);
2129 break;
2130 }
2131 default:
2132 {
2133 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2134 keyword);
2135 break;
2136 }
2137 }
2138 }
cristye23ec9d2011-08-16 18:15:40 +00002139 (void) ContrastImage(msl_info->image[n],sharpen,
2140 &msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00002141 break;
2142 }
cristyb988fe72009-09-16 01:01:10 +00002143 if (LocaleCompare((const char *) tag,"crop") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002144 {
2145 Image
2146 *crop_image;
2147
2148 /*
2149 Crop image.
2150 */
2151 if (msl_info->image[n] == (Image *) NULL)
2152 {
cristyb988fe72009-09-16 01:01:10 +00002153 ThrowMSLException(OptionError,"NoImagesDefined",
2154 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002155 break;
2156 }
2157 SetGeometry(msl_info->image[n],&geometry);
2158 if (attributes != (const xmlChar **) NULL)
2159 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2160 {
2161 keyword=(const char *) attributes[i++];
2162 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002163 msl_info->attributes[n],(const char *) attributes[i],
2164 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002165 CloneString(&value,attribute);
2166 switch (*keyword)
2167 {
2168 case 'G':
2169 case 'g':
2170 {
2171 if (LocaleCompare(keyword,"geometry") == 0)
2172 {
cristy860f4e12011-07-28 19:00:28 +00002173 flags=ParseGravityGeometry(msl_info->image[n],value,
cristy3ed852e2009-09-05 21:47:34 +00002174 &geometry,&exception);
cristy3ed852e2009-09-05 21:47:34 +00002175 break;
2176 }
2177 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2178 keyword);
2179 break;
2180 }
2181 case 'H':
2182 case 'h':
2183 {
2184 if (LocaleCompare(keyword,"height") == 0)
2185 {
cristyf2f27272009-12-17 14:48:46 +00002186 geometry.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002187 break;
2188 }
2189 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2190 keyword);
2191 break;
2192 }
2193 case 'W':
2194 case 'w':
2195 {
2196 if (LocaleCompare(keyword,"width") == 0)
2197 {
cristyf2f27272009-12-17 14:48:46 +00002198 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002199 break;
2200 }
2201 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2202 keyword);
2203 break;
2204 }
2205 case 'X':
2206 case 'x':
2207 {
2208 if (LocaleCompare(keyword,"x") == 0)
2209 {
cristyf2f27272009-12-17 14:48:46 +00002210 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002211 break;
2212 }
2213 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2214 keyword);
2215 break;
2216 }
2217 case 'Y':
2218 case 'y':
2219 {
2220 if (LocaleCompare(keyword,"y") == 0)
2221 {
cristyf2f27272009-12-17 14:48:46 +00002222 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002223 break;
2224 }
2225 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2226 keyword);
2227 break;
2228 }
2229 default:
2230 {
2231 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2232 keyword);
2233 break;
2234 }
2235 }
2236 }
2237 crop_image=CropImage(msl_info->image[n],&geometry,
2238 &msl_info->image[n]->exception);
2239 if (crop_image == (Image *) NULL)
2240 break;
2241 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2242 msl_info->image[n]=crop_image;
2243 break;
2244 }
cristyb988fe72009-09-16 01:01:10 +00002245 if (LocaleCompare((const char *) tag,"cycle-colormap") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002246 {
cristybb503372010-05-27 20:51:26 +00002247 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002248 display;
2249
2250 /*
2251 Cycle-colormap image.
2252 */
2253 if (msl_info->image[n] == (Image *) NULL)
2254 {
cristyb988fe72009-09-16 01:01:10 +00002255 ThrowMSLException(OptionError,"NoImagesDefined",
2256 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002257 break;
2258 }
2259 display=0;
2260 if (attributes != (const xmlChar **) NULL)
2261 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2262 {
2263 keyword=(const char *) attributes[i++];
2264 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002265 msl_info->attributes[n],(const char *) attributes[i],
2266 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002267 CloneString(&value,attribute);
2268 switch (*keyword)
2269 {
2270 case 'D':
2271 case 'd':
2272 {
2273 if (LocaleCompare(keyword,"display") == 0)
2274 {
cristyf2f27272009-12-17 14:48:46 +00002275 display=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002276 break;
2277 }
2278 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2279 keyword);
2280 break;
2281 }
2282 default:
2283 {
2284 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2285 keyword);
2286 break;
2287 }
2288 }
2289 }
cristy018f07f2011-09-04 21:15:19 +00002290 (void) CycleColormapImage(msl_info->image[n],display,&exception);
cristy3ed852e2009-09-05 21:47:34 +00002291 break;
2292 }
2293 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
2294 }
2295 case 'D':
2296 case 'd':
2297 {
cristyb988fe72009-09-16 01:01:10 +00002298 if (LocaleCompare((const char *) tag,"despeckle") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002299 {
2300 Image
2301 *despeckle_image;
2302
2303 /*
2304 Despeckle image.
2305 */
2306 if (msl_info->image[n] == (Image *) NULL)
2307 {
cristyb988fe72009-09-16 01:01:10 +00002308 ThrowMSLException(OptionError,"NoImagesDefined",
2309 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002310 break;
2311 }
2312 if (attributes != (const xmlChar **) NULL)
2313 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2314 {
2315 keyword=(const char *) attributes[i++];
2316 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002317 msl_info->attributes[n],(const char *) attributes[i],
2318 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002319 CloneString(&value,attribute);
2320 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
2321 }
2322 despeckle_image=DespeckleImage(msl_info->image[n],
2323 &msl_info->image[n]->exception);
2324 if (despeckle_image == (Image *) NULL)
2325 break;
2326 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2327 msl_info->image[n]=despeckle_image;
2328 break;
2329 }
cristyb988fe72009-09-16 01:01:10 +00002330 if (LocaleCompare((const char *) tag,"display") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002331 {
2332 if (msl_info->image[n] == (Image *) NULL)
2333 {
cristyb988fe72009-09-16 01:01:10 +00002334 ThrowMSLException(OptionError,"NoImagesDefined",
2335 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002336 break;
2337 }
2338 if (attributes != (const xmlChar **) NULL)
2339 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2340 {
2341 keyword=(const char *) attributes[i++];
2342 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002343 msl_info->attributes[n],(const char *) attributes[i],
2344 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002345 CloneString(&value,attribute);
2346 switch (*keyword)
2347 {
2348 default:
2349 {
2350 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2351 keyword);
2352 break;
2353 }
2354 }
2355 }
cristy051718b2011-08-28 22:49:25 +00002356 (void) DisplayImages(msl_info->image_info[n],msl_info->image[n],
2357 &msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00002358 break;
2359 }
cristyb988fe72009-09-16 01:01:10 +00002360 if (LocaleCompare((const char *) tag,"draw") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002361 {
2362 char
2363 text[MaxTextExtent];
2364
2365 /*
2366 Annotate image.
2367 */
2368 if (msl_info->image[n] == (Image *) NULL)
2369 {
cristyb988fe72009-09-16 01:01:10 +00002370 ThrowMSLException(OptionError,"NoImagesDefined",
2371 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002372 break;
2373 }
2374 draw_info=CloneDrawInfo(msl_info->image_info[n],
2375 msl_info->draw_info[n]);
2376 angle=0.0;
2377 current=draw_info->affine;
2378 GetAffineMatrix(&affine);
2379 if (attributes != (const xmlChar **) NULL)
2380 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2381 {
2382 keyword=(const char *) attributes[i++];
2383 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002384 msl_info->attributes[n],(const char *) attributes[i],
2385 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002386 CloneString(&value,attribute);
2387 switch (*keyword)
2388 {
2389 case 'A':
2390 case 'a':
2391 {
2392 if (LocaleCompare(keyword,"affine") == 0)
2393 {
2394 char
2395 *p;
2396
2397 p=value;
cristyc1acd842011-05-19 23:05:47 +00002398 draw_info->affine.sx=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00002399 if (*p ==',')
2400 p++;
cristyc1acd842011-05-19 23:05:47 +00002401 draw_info->affine.rx=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00002402 if (*p ==',')
2403 p++;
cristyc1acd842011-05-19 23:05:47 +00002404 draw_info->affine.ry=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00002405 if (*p ==',')
2406 p++;
cristyc1acd842011-05-19 23:05:47 +00002407 draw_info->affine.sy=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00002408 if (*p ==',')
2409 p++;
cristyc1acd842011-05-19 23:05:47 +00002410 draw_info->affine.tx=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00002411 if (*p ==',')
2412 p++;
cristyc1acd842011-05-19 23:05:47 +00002413 draw_info->affine.ty=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00002414 break;
2415 }
2416 if (LocaleCompare(keyword,"align") == 0)
2417 {
cristy042ee782011-04-22 18:48:30 +00002418 option=ParseCommandOption(MagickAlignOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002419 value);
2420 if (option < 0)
2421 ThrowMSLException(OptionError,"UnrecognizedAlignType",
2422 value);
2423 draw_info->align=(AlignType) option;
2424 break;
2425 }
2426 if (LocaleCompare(keyword,"antialias") == 0)
2427 {
cristy042ee782011-04-22 18:48:30 +00002428 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002429 value);
2430 if (option < 0)
2431 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
2432 value);
2433 draw_info->stroke_antialias=(MagickBooleanType) option;
2434 draw_info->text_antialias=(MagickBooleanType) option;
2435 break;
2436 }
2437 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2438 keyword);
2439 break;
2440 }
2441 case 'D':
2442 case 'd':
2443 {
2444 if (LocaleCompare(keyword,"density") == 0)
2445 {
2446 CloneString(&draw_info->density,value);
2447 break;
2448 }
2449 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2450 keyword);
2451 break;
2452 }
2453 case 'E':
2454 case 'e':
2455 {
2456 if (LocaleCompare(keyword,"encoding") == 0)
2457 {
2458 CloneString(&draw_info->encoding,value);
2459 break;
2460 }
2461 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2462 keyword);
2463 break;
2464 }
2465 case 'F':
2466 case 'f':
2467 {
2468 if (LocaleCompare(keyword, "fill") == 0)
2469 {
2470 (void) QueryColorDatabase(value,&draw_info->fill,
2471 &exception);
2472 break;
2473 }
2474 if (LocaleCompare(keyword,"family") == 0)
2475 {
2476 CloneString(&draw_info->family,value);
2477 break;
2478 }
2479 if (LocaleCompare(keyword,"font") == 0)
2480 {
2481 CloneString(&draw_info->font,value);
2482 break;
2483 }
2484 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2485 keyword);
2486 break;
2487 }
2488 case 'G':
2489 case 'g':
2490 {
2491 if (LocaleCompare(keyword,"geometry") == 0)
2492 {
2493 flags=ParsePageGeometry(msl_info->image[n],value,
2494 &geometry,&exception);
2495 if ((flags & HeightValue) == 0)
2496 geometry.height=geometry.width;
2497 break;
2498 }
2499 if (LocaleCompare(keyword,"gravity") == 0)
2500 {
cristy042ee782011-04-22 18:48:30 +00002501 option=ParseCommandOption(MagickGravityOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002502 value);
2503 if (option < 0)
2504 ThrowMSLException(OptionError,"UnrecognizedGravityType",
2505 value);
2506 draw_info->gravity=(GravityType) option;
2507 break;
2508 }
2509 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2510 keyword);
2511 break;
2512 }
2513 case 'P':
2514 case 'p':
2515 {
2516 if (LocaleCompare(keyword,"primitive") == 0)
cristyb988fe72009-09-16 01:01:10 +00002517 {
cristy3ed852e2009-09-05 21:47:34 +00002518 CloneString(&draw_info->primitive,value);
2519 break;
2520 }
2521 if (LocaleCompare(keyword,"pointsize") == 0)
2522 {
cristyc1acd842011-05-19 23:05:47 +00002523 draw_info->pointsize=InterpretLocaleValue(value,
2524 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002525 break;
2526 }
2527 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2528 keyword);
2529 break;
2530 }
2531 case 'R':
2532 case 'r':
2533 {
2534 if (LocaleCompare(keyword,"rotate") == 0)
2535 {
cristyc1acd842011-05-19 23:05:47 +00002536 angle=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002537 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
2538 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
2539 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
2540 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
2541 break;
2542 }
2543 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2544 keyword);
2545 break;
2546 }
2547 case 'S':
2548 case 's':
2549 {
2550 if (LocaleCompare(keyword,"scale") == 0)
2551 {
2552 flags=ParseGeometry(value,&geometry_info);
2553 if ((flags & SigmaValue) == 0)
2554 geometry_info.sigma=1.0;
2555 affine.sx=geometry_info.rho;
2556 affine.sy=geometry_info.sigma;
2557 break;
2558 }
2559 if (LocaleCompare(keyword,"skewX") == 0)
2560 {
cristyc1acd842011-05-19 23:05:47 +00002561 angle=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002562 affine.ry=cos(DegreesToRadians(fmod(angle,360.0)));
2563 break;
2564 }
2565 if (LocaleCompare(keyword,"skewY") == 0)
2566 {
cristyc1acd842011-05-19 23:05:47 +00002567 angle=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002568 affine.rx=cos(DegreesToRadians(fmod(angle,360.0)));
2569 break;
2570 }
2571 if (LocaleCompare(keyword,"stretch") == 0)
2572 {
cristy042ee782011-04-22 18:48:30 +00002573 option=ParseCommandOption(MagickStretchOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002574 value);
2575 if (option < 0)
2576 ThrowMSLException(OptionError,"UnrecognizedStretchType",
2577 value);
2578 draw_info->stretch=(StretchType) option;
2579 break;
2580 }
2581 if (LocaleCompare(keyword, "stroke") == 0)
2582 {
2583 (void) QueryColorDatabase(value,&draw_info->stroke,
2584 &exception);
2585 break;
2586 }
2587 if (LocaleCompare(keyword,"strokewidth") == 0)
2588 {
cristyf2f27272009-12-17 14:48:46 +00002589 draw_info->stroke_width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002590 break;
2591 }
2592 if (LocaleCompare(keyword,"style") == 0)
2593 {
cristy042ee782011-04-22 18:48:30 +00002594 option=ParseCommandOption(MagickStyleOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002595 value);
2596 if (option < 0)
2597 ThrowMSLException(OptionError,"UnrecognizedStyleType",
2598 value);
2599 draw_info->style=(StyleType) option;
2600 break;
2601 }
2602 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2603 keyword);
2604 break;
2605 }
2606 case 'T':
2607 case 't':
2608 {
2609 if (LocaleCompare(keyword,"text") == 0)
2610 {
2611 CloneString(&draw_info->text,value);
2612 break;
2613 }
2614 if (LocaleCompare(keyword,"translate") == 0)
2615 {
2616 flags=ParseGeometry(value,&geometry_info);
2617 if ((flags & SigmaValue) == 0)
2618 geometry_info.sigma=1.0;
2619 affine.tx=geometry_info.rho;
2620 affine.ty=geometry_info.sigma;
2621 break;
2622 }
2623 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2624 keyword);
2625 break;
2626 }
2627 case 'U':
2628 case 'u':
2629 {
2630 if (LocaleCompare(keyword, "undercolor") == 0)
2631 {
2632 (void) QueryColorDatabase(value,&draw_info->undercolor,
2633 &exception);
2634 break;
2635 }
2636 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2637 keyword);
2638 break;
2639 }
2640 case 'W':
2641 case 'w':
2642 {
2643 if (LocaleCompare(keyword,"weight") == 0)
2644 {
cristyf2f27272009-12-17 14:48:46 +00002645 draw_info->weight=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002646 break;
2647 }
2648 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2649 keyword);
2650 break;
2651 }
2652 case 'X':
2653 case 'x':
2654 {
2655 if (LocaleCompare(keyword,"x") == 0)
2656 {
cristyf2f27272009-12-17 14:48:46 +00002657 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002658 break;
2659 }
2660 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2661 keyword);
2662 break;
2663 }
2664 case 'Y':
2665 case 'y':
2666 {
2667 if (LocaleCompare(keyword,"y") == 0)
2668 {
cristyf2f27272009-12-17 14:48:46 +00002669 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002670 break;
2671 }
2672 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2673 keyword);
2674 break;
2675 }
2676 default:
2677 {
2678 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2679 keyword);
2680 break;
2681 }
2682 }
2683 }
cristyb51dff52011-05-19 16:55:47 +00002684 (void) FormatLocaleString(text,MaxTextExtent,
cristye8c25f92010-06-03 00:53:06 +00002685 "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,(double)
2686 geometry.height,(double) geometry.x,(double) geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00002687 CloneString(&draw_info->geometry,text);
cristyef7c8a52010-10-10 13:46:51 +00002688 draw_info->affine.sx=affine.sx*current.sx+affine.ry*current.rx;
2689 draw_info->affine.rx=affine.rx*current.sx+affine.sy*current.rx;
2690 draw_info->affine.ry=affine.sx*current.ry+affine.ry*current.sy;
2691 draw_info->affine.sy=affine.rx*current.ry+affine.sy*current.sy;
2692 draw_info->affine.tx=affine.sx*current.tx+affine.ry*current.ty+
2693 affine.tx;
2694 draw_info->affine.ty=affine.rx*current.tx+affine.sy*current.ty+
2695 affine.ty;
cristy018f07f2011-09-04 21:15:19 +00002696 (void) DrawImage(msl_info->image[n],draw_info,&exception);
cristy3ed852e2009-09-05 21:47:34 +00002697 draw_info=DestroyDrawInfo(draw_info);
2698 break;
2699 }
2700 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
2701 }
2702 case 'E':
2703 case 'e':
2704 {
cristyb988fe72009-09-16 01:01:10 +00002705 if (LocaleCompare((const char *) tag,"edge") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002706 {
2707 Image
2708 *edge_image;
2709
2710 /*
2711 Edge image.
2712 */
2713 if (msl_info->image[n] == (Image *) NULL)
2714 {
cristyb988fe72009-09-16 01:01:10 +00002715 ThrowMSLException(OptionError,"NoImagesDefined",
2716 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002717 break;
2718 }
2719 if (attributes != (const xmlChar **) NULL)
2720 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2721 {
2722 keyword=(const char *) attributes[i++];
2723 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002724 msl_info->attributes[n],(const char *) attributes[i],
2725 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002726 CloneString(&value,attribute);
2727 switch (*keyword)
2728 {
2729 case 'G':
2730 case 'g':
2731 {
2732 if (LocaleCompare(keyword,"geometry") == 0)
2733 {
2734 flags=ParseGeometry(value,&geometry_info);
2735 if ((flags & SigmaValue) == 0)
2736 geometry_info.sigma=1.0;
2737 break;
2738 }
2739 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2740 keyword);
2741 break;
2742 }
2743 case 'R':
2744 case 'r':
2745 {
2746 if (LocaleCompare(keyword,"radius") == 0)
2747 {
cristyc1acd842011-05-19 23:05:47 +00002748 geometry_info.rho=InterpretLocaleValue(value,
2749 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002750 break;
2751 }
2752 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2753 keyword);
2754 break;
2755 }
2756 default:
2757 {
2758 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2759 keyword);
2760 break;
2761 }
2762 }
2763 }
2764 edge_image=EdgeImage(msl_info->image[n],geometry_info.rho,
2765 &msl_info->image[n]->exception);
2766 if (edge_image == (Image *) NULL)
2767 break;
2768 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2769 msl_info->image[n]=edge_image;
2770 break;
2771 }
cristyb988fe72009-09-16 01:01:10 +00002772 if (LocaleCompare((const char *) tag,"emboss") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002773 {
2774 Image
2775 *emboss_image;
2776
2777 /*
2778 Emboss image.
2779 */
2780 if (msl_info->image[n] == (Image *) NULL)
2781 {
cristyb988fe72009-09-16 01:01:10 +00002782 ThrowMSLException(OptionError,"NoImagesDefined",
2783 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002784 break;
2785 }
2786 if (attributes != (const xmlChar **) NULL)
2787 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2788 {
2789 keyword=(const char *) attributes[i++];
2790 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002791 msl_info->attributes[n],(const char *) attributes[i],
2792 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002793 CloneString(&value,attribute);
2794 switch (*keyword)
2795 {
2796 case 'G':
2797 case 'g':
2798 {
2799 if (LocaleCompare(keyword,"geometry") == 0)
2800 {
2801 flags=ParseGeometry(value,&geometry_info);
2802 if ((flags & SigmaValue) == 0)
2803 geometry_info.sigma=1.0;
2804 break;
2805 }
2806 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2807 keyword);
2808 break;
2809 }
2810 case 'R':
2811 case 'r':
2812 {
2813 if (LocaleCompare(keyword,"radius") == 0)
2814 {
cristyc1acd842011-05-19 23:05:47 +00002815 geometry_info.rho=InterpretLocaleValue(value,
2816 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002817 break;
2818 }
2819 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2820 keyword);
2821 break;
2822 }
2823 case 'S':
2824 case 's':
2825 {
2826 if (LocaleCompare(keyword,"sigma") == 0)
2827 {
cristyf2f27272009-12-17 14:48:46 +00002828 geometry_info.sigma=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002829 break;
2830 }
2831 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2832 keyword);
2833 break;
2834 }
2835 default:
2836 {
2837 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2838 keyword);
2839 break;
2840 }
2841 }
2842 }
2843 emboss_image=EmbossImage(msl_info->image[n],geometry_info.rho,
2844 geometry_info.sigma,&msl_info->image[n]->exception);
2845 if (emboss_image == (Image *) NULL)
2846 break;
2847 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2848 msl_info->image[n]=emboss_image;
2849 break;
2850 }
cristyb988fe72009-09-16 01:01:10 +00002851 if (LocaleCompare((const char *) tag,"enhance") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002852 {
2853 Image
2854 *enhance_image;
2855
2856 /*
2857 Enhance image.
2858 */
2859 if (msl_info->image[n] == (Image *) NULL)
2860 {
cristyb988fe72009-09-16 01:01:10 +00002861 ThrowMSLException(OptionError,"NoImagesDefined",
2862 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002863 break;
2864 }
2865 if (attributes != (const xmlChar **) NULL)
2866 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2867 {
2868 keyword=(const char *) attributes[i++];
2869 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002870 msl_info->attributes[n],(const char *) attributes[i],
2871 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002872 CloneString(&value,attribute);
2873 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
2874 }
2875 enhance_image=EnhanceImage(msl_info->image[n],
2876 &msl_info->image[n]->exception);
2877 if (enhance_image == (Image *) NULL)
2878 break;
2879 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2880 msl_info->image[n]=enhance_image;
2881 break;
2882 }
cristyb988fe72009-09-16 01:01:10 +00002883 if (LocaleCompare((const char *) tag,"equalize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002884 {
2885 /*
2886 Equalize image.
2887 */
2888 if (msl_info->image[n] == (Image *) NULL)
2889 {
cristyb988fe72009-09-16 01:01:10 +00002890 ThrowMSLException(OptionError,"NoImagesDefined",
2891 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002892 break;
2893 }
2894 if (attributes != (const xmlChar **) NULL)
2895 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2896 {
2897 keyword=(const char *) attributes[i++];
2898 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002899 msl_info->attributes[n],(const char *) attributes[i],
2900 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002901 CloneString(&value,attribute);
2902 switch (*keyword)
2903 {
2904 default:
2905 {
2906 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2907 keyword);
2908 break;
2909 }
2910 }
2911 }
cristy6d8c3d72011-08-22 01:20:01 +00002912 (void) EqualizeImage(msl_info->image[n],
2913 &msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00002914 break;
2915 }
2916 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
2917 }
2918 case 'F':
2919 case 'f':
2920 {
cristyb988fe72009-09-16 01:01:10 +00002921 if (LocaleCompare((const char *) tag, "flatten") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002922 {
2923 if (msl_info->image[n] == (Image *) NULL)
2924 {
cristyb988fe72009-09-16 01:01:10 +00002925 ThrowMSLException(OptionError,"NoImagesDefined",
2926 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002927 break;
2928 }
2929
2930 /* no attributes here */
2931
2932 /* process the image */
2933 {
2934 Image
2935 *newImage;
2936
2937 newImage=MergeImageLayers(msl_info->image[n],FlattenLayer,
2938 &msl_info->image[n]->exception);
2939 if (newImage == (Image *) NULL)
2940 break;
2941 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2942 msl_info->image[n]=newImage;
2943 break;
2944 }
2945 }
cristyb988fe72009-09-16 01:01:10 +00002946 if (LocaleCompare((const char *) tag,"flip") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002947 {
2948 Image
2949 *flip_image;
2950
2951 /*
2952 Flip image.
2953 */
2954 if (msl_info->image[n] == (Image *) NULL)
2955 {
cristyb988fe72009-09-16 01:01:10 +00002956 ThrowMSLException(OptionError,"NoImagesDefined",
2957 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002958 break;
2959 }
2960 if (attributes != (const xmlChar **) NULL)
2961 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2962 {
2963 keyword=(const char *) attributes[i++];
2964 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002965 msl_info->attributes[n],(const char *) attributes[i],
2966 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002967 CloneString(&value,attribute);
2968 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
2969 }
2970 flip_image=FlipImage(msl_info->image[n],
2971 &msl_info->image[n]->exception);
2972 if (flip_image == (Image *) NULL)
2973 break;
2974 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2975 msl_info->image[n]=flip_image;
2976 break;
2977 }
cristyb988fe72009-09-16 01:01:10 +00002978 if (LocaleCompare((const char *) tag,"flop") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002979 {
2980 Image
2981 *flop_image;
2982
2983 /*
2984 Flop image.
2985 */
2986 if (msl_info->image[n] == (Image *) NULL)
2987 {
cristyb988fe72009-09-16 01:01:10 +00002988 ThrowMSLException(OptionError,"NoImagesDefined",
2989 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002990 break;
2991 }
2992 if (attributes != (const xmlChar **) NULL)
2993 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2994 {
2995 keyword=(const char *) attributes[i++];
2996 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002997 msl_info->attributes[n],(const char *) attributes[i],
2998 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002999 CloneString(&value,attribute);
3000 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3001 }
3002 flop_image=FlopImage(msl_info->image[n],
3003 &msl_info->image[n]->exception);
3004 if (flop_image == (Image *) NULL)
3005 break;
3006 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3007 msl_info->image[n]=flop_image;
3008 break;
3009 }
cristyb988fe72009-09-16 01:01:10 +00003010 if (LocaleCompare((const char *) tag,"frame") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003011 {
3012 FrameInfo
3013 frame_info;
3014
3015 Image
3016 *frame_image;
3017
3018 /*
3019 Frame image.
3020 */
3021 if (msl_info->image[n] == (Image *) NULL)
3022 {
cristyb988fe72009-09-16 01:01:10 +00003023 ThrowMSLException(OptionError,"NoImagesDefined",
3024 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003025 break;
3026 }
3027 SetGeometry(msl_info->image[n],&geometry);
3028 if (attributes != (const xmlChar **) NULL)
3029 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3030 {
3031 keyword=(const char *) attributes[i++];
3032 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003033 msl_info->attributes[n],(const char *) attributes[i],
3034 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003035 CloneString(&value,attribute);
3036 switch (*keyword)
3037 {
3038 case 'C':
3039 case 'c':
3040 {
3041 if (LocaleCompare(keyword,"compose") == 0)
3042 {
cristy042ee782011-04-22 18:48:30 +00003043 option=ParseCommandOption(MagickComposeOptions,
cristy3ed852e2009-09-05 21:47:34 +00003044 MagickFalse,value);
3045 if (option < 0)
3046 ThrowMSLException(OptionError,"UnrecognizedComposeType",
3047 value);
3048 msl_info->image[n]->compose=(CompositeOperator) option;
3049 break;
3050 }
3051 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3052 keyword);
3053 break;
3054 }
3055 case 'F':
3056 case 'f':
3057 {
3058 if (LocaleCompare(keyword, "fill") == 0)
3059 {
3060 (void) QueryColorDatabase(value,
3061 &msl_info->image[n]->matte_color,&exception);
3062 break;
3063 }
3064 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3065 keyword);
3066 break;
3067 }
3068 case 'G':
3069 case 'g':
3070 {
3071 if (LocaleCompare(keyword,"geometry") == 0)
3072 {
3073 flags=ParsePageGeometry(msl_info->image[n],value,
3074 &geometry,&exception);
3075 if ((flags & HeightValue) == 0)
3076 geometry.height=geometry.width;
3077 frame_info.width=geometry.width;
3078 frame_info.height=geometry.height;
3079 frame_info.outer_bevel=geometry.x;
3080 frame_info.inner_bevel=geometry.y;
3081 break;
3082 }
3083 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3084 keyword);
3085 break;
3086 }
3087 case 'H':
3088 case 'h':
3089 {
3090 if (LocaleCompare(keyword,"height") == 0)
3091 {
cristyf2f27272009-12-17 14:48:46 +00003092 frame_info.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003093 break;
3094 }
3095 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3096 keyword);
3097 break;
3098 }
3099 case 'I':
3100 case 'i':
3101 {
3102 if (LocaleCompare(keyword,"inner") == 0)
3103 {
cristyf2f27272009-12-17 14:48:46 +00003104 frame_info.inner_bevel=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003105 break;
3106 }
3107 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3108 keyword);
3109 break;
3110 }
3111 case 'O':
3112 case 'o':
3113 {
3114 if (LocaleCompare(keyword,"outer") == 0)
3115 {
cristyf2f27272009-12-17 14:48:46 +00003116 frame_info.outer_bevel=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003117 break;
3118 }
3119 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3120 keyword);
3121 break;
3122 }
3123 case 'W':
3124 case 'w':
3125 {
3126 if (LocaleCompare(keyword,"width") == 0)
3127 {
cristyf2f27272009-12-17 14:48:46 +00003128 frame_info.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003129 break;
3130 }
3131 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3132 keyword);
3133 break;
3134 }
3135 default:
3136 {
3137 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3138 keyword);
3139 break;
3140 }
3141 }
3142 }
cristybb503372010-05-27 20:51:26 +00003143 frame_info.x=(ssize_t) frame_info.width;
3144 frame_info.y=(ssize_t) frame_info.height;
cristy3ed852e2009-09-05 21:47:34 +00003145 frame_info.width=msl_info->image[n]->columns+2*frame_info.x;
3146 frame_info.height=msl_info->image[n]->rows+2*frame_info.y;
3147 frame_image=FrameImage(msl_info->image[n],&frame_info,
3148 &msl_info->image[n]->exception);
3149 if (frame_image == (Image *) NULL)
3150 break;
3151 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3152 msl_info->image[n]=frame_image;
3153 break;
3154 }
3155 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3156 }
3157 case 'G':
3158 case 'g':
3159 {
cristyb988fe72009-09-16 01:01:10 +00003160 if (LocaleCompare((const char *) tag,"gamma") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003161 {
3162 char
3163 gamma[MaxTextExtent];
3164
cristy4c08aed2011-07-01 19:47:50 +00003165 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00003166 pixel;
3167
3168 /*
3169 Gamma image.
3170 */
3171 if (msl_info->image[n] == (Image *) NULL)
3172 {
cristyb988fe72009-09-16 01:01:10 +00003173 ThrowMSLException(OptionError,"NoImagesDefined",
3174 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003175 break;
3176 }
3177 channel=UndefinedChannel;
3178 pixel.red=0.0;
3179 pixel.green=0.0;
3180 pixel.blue=0.0;
3181 *gamma='\0';
3182 if (attributes != (const xmlChar **) NULL)
3183 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3184 {
3185 keyword=(const char *) attributes[i++];
3186 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003187 msl_info->attributes[n],(const char *) attributes[i],
3188 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003189 CloneString(&value,attribute);
3190 switch (*keyword)
3191 {
3192 case 'B':
3193 case 'b':
3194 {
3195 if (LocaleCompare(keyword,"blue") == 0)
3196 {
cristyc1acd842011-05-19 23:05:47 +00003197 pixel.blue=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003198 break;
3199 }
3200 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3201 keyword);
3202 break;
3203 }
3204 case 'C':
3205 case 'c':
3206 {
3207 if (LocaleCompare(keyword,"channel") == 0)
3208 {
3209 option=ParseChannelOption(value);
3210 if (option < 0)
3211 ThrowMSLException(OptionError,"UnrecognizedChannelType",
3212 value);
3213 channel=(ChannelType) option;
3214 break;
3215 }
3216 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3217 keyword);
3218 break;
3219 }
3220 case 'G':
3221 case 'g':
3222 {
3223 if (LocaleCompare(keyword,"gamma") == 0)
3224 {
3225 (void) CopyMagickString(gamma,value,MaxTextExtent);
3226 break;
3227 }
3228 if (LocaleCompare(keyword,"green") == 0)
3229 {
cristyc1acd842011-05-19 23:05:47 +00003230 pixel.green=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003231 break;
3232 }
3233 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3234 keyword);
3235 break;
3236 }
3237 case 'R':
3238 case 'r':
3239 {
3240 if (LocaleCompare(keyword,"red") == 0)
3241 {
cristyc1acd842011-05-19 23:05:47 +00003242 pixel.red=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003243 break;
3244 }
3245 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3246 keyword);
3247 break;
3248 }
3249 default:
3250 {
3251 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3252 keyword);
3253 break;
3254 }
3255 }
3256 }
3257 if (*gamma == '\0')
cristyb51dff52011-05-19 16:55:47 +00003258 (void) FormatLocaleString(gamma,MaxTextExtent,"%g,%g,%g",
cristy3ed852e2009-09-05 21:47:34 +00003259 (double) pixel.red,(double) pixel.green,(double) pixel.blue);
cristyb3e7c6c2011-07-24 01:43:55 +00003260 (void) GammaImage(msl_info->image[n],atof(gamma),
3261 &msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00003262 break;
3263 }
cristyb988fe72009-09-16 01:01:10 +00003264 else if (LocaleCompare((const char *) tag,"get") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003265 {
3266 if (msl_info->image[n] == (Image *) NULL)
3267 {
cristyb988fe72009-09-16 01:01:10 +00003268 ThrowMSLException(OptionError,"NoImagesDefined",
3269 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003270 break;
3271 }
3272 if (attributes == (const xmlChar **) NULL)
3273 break;
3274 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3275 {
3276 keyword=(const char *) attributes[i++];
cristyb988fe72009-09-16 01:01:10 +00003277 CloneString(&value,(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003278 (void) CopyMagickString(key,value,MaxTextExtent);
3279 switch (*keyword)
3280 {
3281 case 'H':
3282 case 'h':
3283 {
3284 if (LocaleCompare(keyword,"height") == 0)
3285 {
cristyb51dff52011-05-19 16:55:47 +00003286 (void) FormatLocaleString(value,MaxTextExtent,"%.20g",
cristye8c25f92010-06-03 00:53:06 +00003287 (double) msl_info->image[n]->rows);
cristy3ed852e2009-09-05 21:47:34 +00003288 (void) SetImageProperty(msl_info->attributes[n],key,value);
3289 break;
3290 }
3291 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3292 }
3293 case 'W':
3294 case 'w':
3295 {
3296 if (LocaleCompare(keyword,"width") == 0)
3297 {
cristyb51dff52011-05-19 16:55:47 +00003298 (void) FormatLocaleString(value,MaxTextExtent,"%.20g",
cristye8c25f92010-06-03 00:53:06 +00003299 (double) msl_info->image[n]->columns);
cristy3ed852e2009-09-05 21:47:34 +00003300 (void) SetImageProperty(msl_info->attributes[n],key,value);
3301 break;
3302 }
3303 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3304 }
3305 default:
3306 {
3307 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3308 break;
3309 }
3310 }
3311 }
3312 break;
3313 }
cristyb988fe72009-09-16 01:01:10 +00003314 else if (LocaleCompare((const char *) tag, "group") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003315 {
3316 msl_info->number_groups++;
3317 msl_info->group_info=(MSLGroupInfo *) ResizeQuantumMemory(
3318 msl_info->group_info,msl_info->number_groups+1UL,
3319 sizeof(*msl_info->group_info));
3320 break;
3321 }
3322 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3323 }
3324 case 'I':
3325 case 'i':
3326 {
cristyb988fe72009-09-16 01:01:10 +00003327 if (LocaleCompare((const char *) tag,"image") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003328 {
cristy3ed852e2009-09-05 21:47:34 +00003329 MSLPushImage(msl_info,(Image *) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003330 if (attributes == (const xmlChar **) NULL)
3331 break;
3332 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3333 {
3334 keyword=(const char *) attributes[i++];
3335 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003336 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00003337 switch (*keyword)
3338 {
cristyb988fe72009-09-16 01:01:10 +00003339 case 'C':
3340 case 'c':
cristy3ed852e2009-09-05 21:47:34 +00003341 {
cristyb988fe72009-09-16 01:01:10 +00003342 if (LocaleCompare(keyword,"color") == 0)
3343 {
3344 Image
3345 *next_image;
cristy3ed852e2009-09-05 21:47:34 +00003346
cristyb988fe72009-09-16 01:01:10 +00003347 (void) CopyMagickString(msl_info->image_info[n]->filename,
3348 "xc:",MaxTextExtent);
3349 (void) ConcatenateMagickString(msl_info->image_info[n]->
3350 filename,value,MaxTextExtent);
3351 next_image=ReadImage(msl_info->image_info[n],&exception);
3352 CatchException(&exception);
3353 if (next_image == (Image *) NULL)
3354 continue;
3355 if (msl_info->image[n] == (Image *) NULL)
3356 msl_info->image[n]=next_image;
3357 else
3358 {
3359 register Image
3360 *p;
cristy3ed852e2009-09-05 21:47:34 +00003361
cristyb988fe72009-09-16 01:01:10 +00003362 /*
3363 Link image into image list.
3364 */
3365 p=msl_info->image[n];
3366 while (p->next != (Image *) NULL)
3367 p=GetNextImageInList(p);
3368 next_image->previous=p;
3369 p->next=next_image;
3370 }
3371 break;
3372 }
cristyb20775d2009-09-16 01:51:41 +00003373 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00003374 break;
3375 }
3376 default:
3377 {
cristyb20775d2009-09-16 01:51:41 +00003378 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00003379 break;
3380 }
3381 }
3382 }
3383 break;
3384 }
cristyb988fe72009-09-16 01:01:10 +00003385 if (LocaleCompare((const char *) tag,"implode") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003386 {
3387 Image
3388 *implode_image;
3389
3390 /*
3391 Implode image.
3392 */
3393 if (msl_info->image[n] == (Image *) NULL)
3394 {
cristyb988fe72009-09-16 01:01:10 +00003395 ThrowMSLException(OptionError,"NoImagesDefined",
3396 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003397 break;
3398 }
3399 if (attributes != (const xmlChar **) NULL)
3400 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3401 {
3402 keyword=(const char *) attributes[i++];
3403 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003404 msl_info->attributes[n],(const char *) attributes[i],
3405 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003406 CloneString(&value,attribute);
3407 switch (*keyword)
3408 {
3409 case 'A':
3410 case 'a':
3411 {
3412 if (LocaleCompare(keyword,"amount") == 0)
3413 {
cristyc1acd842011-05-19 23:05:47 +00003414 geometry_info.rho=InterpretLocaleValue(value,
3415 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003416 break;
3417 }
3418 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3419 keyword);
3420 break;
3421 }
3422 case 'G':
3423 case 'g':
3424 {
3425 if (LocaleCompare(keyword,"geometry") == 0)
3426 {
3427 flags=ParseGeometry(value,&geometry_info);
3428 if ((flags & SigmaValue) == 0)
3429 geometry_info.sigma=1.0;
3430 break;
3431 }
3432 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3433 keyword);
3434 break;
3435 }
3436 default:
3437 {
3438 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3439 keyword);
3440 break;
3441 }
3442 }
3443 }
3444 implode_image=ImplodeImage(msl_info->image[n],geometry_info.rho,
3445 &msl_info->image[n]->exception);
3446 if (implode_image == (Image *) NULL)
3447 break;
3448 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3449 msl_info->image[n]=implode_image;
3450 break;
3451 }
3452 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3453 }
3454 case 'L':
3455 case 'l':
3456 {
cristyb988fe72009-09-16 01:01:10 +00003457 if (LocaleCompare((const char *) tag,"label") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003458 break;
cristyb988fe72009-09-16 01:01:10 +00003459 if (LocaleCompare((const char *) tag, "level") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003460 {
3461 double
3462 levelBlack = 0, levelGamma = 1, levelWhite = QuantumRange;
3463
3464 if (msl_info->image[n] == (Image *) NULL)
3465 {
cristyb988fe72009-09-16 01:01:10 +00003466 ThrowMSLException(OptionError,"NoImagesDefined",
3467 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003468 break;
3469 }
3470 if (attributes == (const xmlChar **) NULL)
3471 break;
3472 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3473 {
3474 keyword=(const char *) attributes[i++];
cristyb988fe72009-09-16 01:01:10 +00003475 CloneString(&value,(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003476 (void) CopyMagickString(key,value,MaxTextExtent);
3477 switch (*keyword)
3478 {
3479 case 'B':
3480 case 'b':
3481 {
3482 if (LocaleCompare(keyword,"black") == 0)
3483 {
cristyc1acd842011-05-19 23:05:47 +00003484 levelBlack = InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003485 break;
3486 }
3487 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3488 break;
3489 }
3490 case 'G':
3491 case 'g':
3492 {
3493 if (LocaleCompare(keyword,"gamma") == 0)
3494 {
cristyc1acd842011-05-19 23:05:47 +00003495 levelGamma = InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003496 break;
3497 }
3498 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3499 break;
3500 }
3501 case 'W':
3502 case 'w':
3503 {
3504 if (LocaleCompare(keyword,"white") == 0)
3505 {
cristyc1acd842011-05-19 23:05:47 +00003506 levelWhite = InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003507 break;
3508 }
3509 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3510 break;
3511 }
3512 default:
3513 {
3514 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3515 break;
3516 }
3517 }
3518 }
3519
3520 /* process image */
cristy01e9afd2011-08-10 17:38:41 +00003521 LevelImage(msl_info->image[n],levelBlack,levelWhite,levelGamma,
3522 &msl_info->image[n]->exception);
cristyf89cb1d2011-07-07 01:24:37 +00003523 break;
cristy3ed852e2009-09-05 21:47:34 +00003524 }
3525 }
3526 case 'M':
3527 case 'm':
3528 {
cristyb988fe72009-09-16 01:01:10 +00003529 if (LocaleCompare((const char *) tag,"magnify") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003530 {
3531 Image
3532 *magnify_image;
3533
3534 /*
3535 Magnify image.
3536 */
3537 if (msl_info->image[n] == (Image *) NULL)
3538 {
cristyb988fe72009-09-16 01:01:10 +00003539 ThrowMSLException(OptionError,"NoImagesDefined",
3540 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003541 break;
3542 }
3543 if (attributes != (const xmlChar **) NULL)
3544 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3545 {
3546 keyword=(const char *) attributes[i++];
3547 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003548 msl_info->attributes[n],(const char *) attributes[i],
3549 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003550 CloneString(&value,attribute);
3551 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3552 }
3553 magnify_image=MagnifyImage(msl_info->image[n],
3554 &msl_info->image[n]->exception);
3555 if (magnify_image == (Image *) NULL)
3556 break;
3557 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3558 msl_info->image[n]=magnify_image;
3559 break;
3560 }
cristyb988fe72009-09-16 01:01:10 +00003561 if (LocaleCompare((const char *) tag,"map") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003562 {
3563 Image
3564 *affinity_image;
3565
3566 MagickBooleanType
3567 dither;
3568
3569 QuantizeInfo
3570 *quantize_info;
3571
3572 /*
3573 Map image.
3574 */
3575 if (msl_info->image[n] == (Image *) NULL)
3576 {
cristyb988fe72009-09-16 01:01:10 +00003577 ThrowMSLException(OptionError,"NoImagesDefined",
3578 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003579 break;
3580 }
3581 affinity_image=NewImageList();
3582 dither=MagickFalse;
3583 if (attributes != (const xmlChar **) NULL)
3584 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3585 {
3586 keyword=(const char *) attributes[i++];
3587 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003588 msl_info->attributes[n],(const char *) attributes[i],
3589 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003590 CloneString(&value,attribute);
3591 switch (*keyword)
3592 {
3593 case 'D':
3594 case 'd':
3595 {
3596 if (LocaleCompare(keyword,"dither") == 0)
3597 {
cristy042ee782011-04-22 18:48:30 +00003598 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00003599 value);
3600 if (option < 0)
3601 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
3602 value);
3603 dither=(MagickBooleanType) option;
3604 break;
3605 }
3606 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3607 keyword);
3608 break;
3609 }
3610 case 'I':
3611 case 'i':
3612 {
3613 if (LocaleCompare(keyword,"image") == 0)
3614 for (j=0; j < msl_info->n; j++)
3615 {
3616 const char
3617 *attribute;
cristyb988fe72009-09-16 01:01:10 +00003618
cristy3ed852e2009-09-05 21:47:34 +00003619 attribute=GetImageProperty(msl_info->attributes[j],"id");
3620 if ((attribute != (const char *) NULL) &&
3621 (LocaleCompare(attribute,value) == 0))
3622 {
3623 affinity_image=CloneImage(msl_info->image[j],0,0,
3624 MagickFalse,&exception);
3625 break;
3626 }
3627 }
3628 break;
3629 }
3630 default:
3631 {
3632 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3633 keyword);
3634 break;
3635 }
3636 }
3637 }
3638 quantize_info=AcquireQuantizeInfo(msl_info->image_info[n]);
3639 quantize_info->dither=dither;
3640 (void) RemapImages(quantize_info,msl_info->image[n],
cristy018f07f2011-09-04 21:15:19 +00003641 affinity_image,&exception);
cristy3ed852e2009-09-05 21:47:34 +00003642 quantize_info=DestroyQuantizeInfo(quantize_info);
3643 affinity_image=DestroyImage(affinity_image);
3644 break;
3645 }
cristyb988fe72009-09-16 01:01:10 +00003646 if (LocaleCompare((const char *) tag,"matte-floodfill") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003647 {
3648 double
3649 opacity;
3650
cristy4c08aed2011-07-01 19:47:50 +00003651 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00003652 target;
3653
3654 PaintMethod
3655 paint_method;
3656
3657 /*
3658 Matte floodfill image.
3659 */
3660 opacity=0.0;
3661 if (msl_info->image[n] == (Image *) NULL)
3662 {
cristyb988fe72009-09-16 01:01:10 +00003663 ThrowMSLException(OptionError,"NoImagesDefined",
3664 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003665 break;
3666 }
3667 SetGeometry(msl_info->image[n],&geometry);
3668 paint_method=FloodfillMethod;
3669 if (attributes != (const xmlChar **) NULL)
3670 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3671 {
3672 keyword=(const char *) attributes[i++];
3673 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003674 msl_info->attributes[n],(const char *) attributes[i],
3675 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003676 CloneString(&value,attribute);
3677 switch (*keyword)
3678 {
3679 case 'B':
3680 case 'b':
3681 {
3682 if (LocaleCompare(keyword,"bordercolor") == 0)
3683 {
3684 (void) QueryMagickColor(value,&target,&exception);
3685 paint_method=FillToBorderMethod;
3686 break;
3687 }
3688 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3689 keyword);
3690 break;
3691 }
3692 case 'F':
3693 case 'f':
3694 {
3695 if (LocaleCompare(keyword,"fuzz") == 0)
3696 {
cristyc1acd842011-05-19 23:05:47 +00003697 msl_info->image[n]->fuzz=InterpretLocaleValue(value,
3698 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003699 break;
3700 }
3701 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3702 keyword);
3703 break;
3704 }
3705 case 'G':
3706 case 'g':
3707 {
3708 if (LocaleCompare(keyword,"geometry") == 0)
3709 {
3710 flags=ParsePageGeometry(msl_info->image[n],value,
3711 &geometry,&exception);
3712 if ((flags & HeightValue) == 0)
3713 geometry.height=geometry.width;
3714 (void) GetOneVirtualMagickPixel(msl_info->image[n],
3715 geometry.x,geometry.y,&target,&exception);
3716 break;
3717 }
3718 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3719 keyword);
3720 break;
3721 }
3722 case 'O':
3723 case 'o':
3724 {
3725 if (LocaleCompare(keyword,"opacity") == 0)
3726 {
cristyc1acd842011-05-19 23:05:47 +00003727 opacity=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003728 break;
3729 }
3730 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3731 keyword);
3732 break;
3733 }
3734 case 'X':
3735 case 'x':
3736 {
3737 if (LocaleCompare(keyword,"x") == 0)
3738 {
cristyf2f27272009-12-17 14:48:46 +00003739 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003740 (void) GetOneVirtualMagickPixel(msl_info->image[n],
3741 geometry.x,geometry.y,&target,&exception);
3742 break;
3743 }
3744 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3745 keyword);
3746 break;
3747 }
3748 case 'Y':
3749 case 'y':
3750 {
3751 if (LocaleCompare(keyword,"y") == 0)
3752 {
cristyf2f27272009-12-17 14:48:46 +00003753 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003754 (void) GetOneVirtualMagickPixel(msl_info->image[n],
3755 geometry.x,geometry.y,&target,&exception);
3756 break;
3757 }
3758 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3759 keyword);
3760 break;
3761 }
3762 default:
3763 {
3764 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3765 keyword);
3766 break;
3767 }
3768 }
3769 }
3770 draw_info=CloneDrawInfo(msl_info->image_info[n],
3771 msl_info->draw_info[n]);
cristy4c08aed2011-07-01 19:47:50 +00003772 draw_info->fill.alpha=ClampToQuantum(opacity);
cristybd5a96c2011-08-21 00:04:26 +00003773 channel_mask=SetPixelChannelMask(msl_info->image[n],AlphaChannel);
cristyd42d9952011-07-08 14:21:50 +00003774 (void) FloodfillPaintImage(msl_info->image[n],draw_info,&target,
3775 geometry.x,geometry.y,paint_method == FloodfillMethod ?
cristy189e84c2011-08-27 18:08:53 +00003776 MagickFalse : MagickTrue,&msl_info->image[n]->exception);
cristybd5a96c2011-08-21 00:04:26 +00003777 (void) SetPixelChannelMap(msl_info->image[n],channel_mask);
cristy3ed852e2009-09-05 21:47:34 +00003778 draw_info=DestroyDrawInfo(draw_info);
3779 break;
3780 }
cristyb988fe72009-09-16 01:01:10 +00003781 if (LocaleCompare((const char *) tag,"median-filter") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003782 {
3783 Image
3784 *median_image;
3785
3786 /*
3787 Median-filter image.
3788 */
3789 if (msl_info->image[n] == (Image *) NULL)
3790 {
cristyb988fe72009-09-16 01:01:10 +00003791 ThrowMSLException(OptionError,"NoImagesDefined",
3792 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003793 break;
3794 }
3795 if (attributes != (const xmlChar **) NULL)
3796 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3797 {
3798 keyword=(const char *) attributes[i++];
3799 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003800 msl_info->attributes[n],(const char *) attributes[i],
3801 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003802 CloneString(&value,attribute);
3803 switch (*keyword)
3804 {
3805 case 'G':
3806 case 'g':
3807 {
3808 if (LocaleCompare(keyword,"geometry") == 0)
3809 {
3810 flags=ParseGeometry(value,&geometry_info);
3811 if ((flags & SigmaValue) == 0)
3812 geometry_info.sigma=1.0;
3813 break;
3814 }
3815 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3816 keyword);
3817 break;
3818 }
3819 case 'R':
3820 case 'r':
3821 {
3822 if (LocaleCompare(keyword,"radius") == 0)
3823 {
cristyc1acd842011-05-19 23:05:47 +00003824 geometry_info.rho=InterpretLocaleValue(value,
3825 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003826 break;
3827 }
3828 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3829 keyword);
3830 break;
3831 }
3832 default:
3833 {
3834 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3835 keyword);
3836 break;
3837 }
3838 }
3839 }
cristy733678d2011-03-18 21:29:28 +00003840 median_image=StatisticImage(msl_info->image[n],MedianStatistic,
cristy95c38342011-03-18 22:39:51 +00003841 (size_t) geometry_info.rho,(size_t) geometry_info.sigma,
3842 &msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00003843 if (median_image == (Image *) NULL)
3844 break;
3845 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3846 msl_info->image[n]=median_image;
3847 break;
3848 }
cristyb988fe72009-09-16 01:01:10 +00003849 if (LocaleCompare((const char *) tag,"minify") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003850 {
3851 Image
3852 *minify_image;
3853
3854 /*
3855 Minify image.
3856 */
3857 if (msl_info->image[n] == (Image *) NULL)
3858 {
cristyb988fe72009-09-16 01:01:10 +00003859 ThrowMSLException(OptionError,"NoImagesDefined",
3860 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003861 break;
3862 }
3863 if (attributes != (const xmlChar **) NULL)
3864 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3865 {
3866 keyword=(const char *) attributes[i++];
3867 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003868 msl_info->attributes[n],(const char *) attributes[i],
3869 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003870 CloneString(&value,attribute);
3871 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3872 }
3873 minify_image=MinifyImage(msl_info->image[n],
3874 &msl_info->image[n]->exception);
3875 if (minify_image == (Image *) NULL)
3876 break;
3877 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3878 msl_info->image[n]=minify_image;
3879 break;
3880 }
cristyb988fe72009-09-16 01:01:10 +00003881 if (LocaleCompare((const char *) tag,"msl") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00003882 break;
cristyb988fe72009-09-16 01:01:10 +00003883 if (LocaleCompare((const char *) tag,"modulate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003884 {
3885 char
3886 modulate[MaxTextExtent];
3887
3888 /*
3889 Modulate image.
3890 */
3891 if (msl_info->image[n] == (Image *) NULL)
3892 {
cristyb988fe72009-09-16 01:01:10 +00003893 ThrowMSLException(OptionError,"NoImagesDefined",
3894 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003895 break;
3896 }
3897 geometry_info.rho=100.0;
3898 geometry_info.sigma=100.0;
3899 geometry_info.xi=100.0;
3900 if (attributes != (const xmlChar **) NULL)
3901 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3902 {
3903 keyword=(const char *) attributes[i++];
3904 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003905 msl_info->attributes[n],(const char *) attributes[i],
3906 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003907 CloneString(&value,attribute);
3908 switch (*keyword)
3909 {
3910 case 'B':
3911 case 'b':
3912 {
3913 if (LocaleCompare(keyword,"blackness") == 0)
3914 {
cristyc1acd842011-05-19 23:05:47 +00003915 geometry_info.rho=InterpretLocaleValue(value,
3916 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003917 break;
3918 }
3919 if (LocaleCompare(keyword,"brightness") == 0)
3920 {
cristyc1acd842011-05-19 23:05:47 +00003921 geometry_info.rho=InterpretLocaleValue(value,
3922 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003923 break;
3924 }
3925 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3926 keyword);
3927 break;
3928 }
3929 case 'F':
3930 case 'f':
3931 {
3932 if (LocaleCompare(keyword,"factor") == 0)
3933 {
3934 flags=ParseGeometry(value,&geometry_info);
3935 break;
3936 }
3937 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3938 keyword);
3939 break;
3940 }
3941 case 'H':
3942 case 'h':
3943 {
3944 if (LocaleCompare(keyword,"hue") == 0)
3945 {
cristyc1acd842011-05-19 23:05:47 +00003946 geometry_info.xi=InterpretLocaleValue(value,
3947 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003948 break;
3949 }
3950 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3951 keyword);
3952 break;
3953 }
3954 case 'L':
3955 case 'l':
3956 {
3957 if (LocaleCompare(keyword,"lightness") == 0)
3958 {
cristyc1acd842011-05-19 23:05:47 +00003959 geometry_info.rho=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 'S':
3968 case 's':
3969 {
3970 if (LocaleCompare(keyword,"saturation") == 0)
3971 {
cristyc1acd842011-05-19 23:05:47 +00003972 geometry_info.sigma=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 'W':
3981 case 'w':
3982 {
3983 if (LocaleCompare(keyword,"whiteness") == 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 default:
3994 {
3995 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3996 keyword);
3997 break;
3998 }
3999 }
4000 }
cristyb51dff52011-05-19 16:55:47 +00004001 (void) FormatLocaleString(modulate,MaxTextExtent,"%g,%g,%g",
cristy3ed852e2009-09-05 21:47:34 +00004002 geometry_info.rho,geometry_info.sigma,geometry_info.xi);
cristy33bd5152011-08-24 01:42:24 +00004003 (void) ModulateImage(msl_info->image[n],modulate,
4004 &msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00004005 break;
4006 }
4007 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4008 }
4009 case 'N':
4010 case 'n':
4011 {
cristyb988fe72009-09-16 01:01:10 +00004012 if (LocaleCompare((const char *) tag,"negate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004013 {
4014 MagickBooleanType
4015 gray;
4016
4017 /*
4018 Negate image.
4019 */
4020 if (msl_info->image[n] == (Image *) NULL)
4021 {
cristyb988fe72009-09-16 01:01:10 +00004022 ThrowMSLException(OptionError,"NoImagesDefined",
4023 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004024 break;
4025 }
4026 gray=MagickFalse;
4027 if (attributes != (const xmlChar **) NULL)
4028 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4029 {
4030 keyword=(const char *) attributes[i++];
4031 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004032 msl_info->attributes[n],(const char *) attributes[i],
4033 &exception);
cristy3ed852e2009-09-05 21:47:34 +00004034 CloneString(&value,attribute);
4035 switch (*keyword)
4036 {
4037 case 'C':
4038 case 'c':
4039 {
4040 if (LocaleCompare(keyword,"channel") == 0)
4041 {
4042 option=ParseChannelOption(value);
4043 if (option < 0)
4044 ThrowMSLException(OptionError,"UnrecognizedChannelType",
4045 value);
4046 channel=(ChannelType) option;
4047 break;
4048 }
4049 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4050 keyword);
4051 break;
4052 }
4053 case 'G':
4054 case 'g':
4055 {
4056 if (LocaleCompare(keyword,"gray") == 0)
4057 {
cristy042ee782011-04-22 18:48:30 +00004058 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004059 value);
4060 if (option < 0)
4061 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4062 value);
4063 gray=(MagickBooleanType) option;
4064 break;
4065 }
4066 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4067 keyword);
4068 break;
4069 }
4070 default:
4071 {
4072 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4073 keyword);
4074 break;
4075 }
4076 }
4077 }
cristybd5a96c2011-08-21 00:04:26 +00004078 channel_mask=SetPixelChannelMask(msl_info->image[n],channel);
cristyb3e7c6c2011-07-24 01:43:55 +00004079 (void) NegateImage(msl_info->image[n],gray,
4080 &msl_info->image[n]->exception);
cristybd5a96c2011-08-21 00:04:26 +00004081 (void) SetPixelChannelMap(msl_info->image[n],channel_mask);
cristy3ed852e2009-09-05 21:47:34 +00004082 break;
4083 }
cristyb988fe72009-09-16 01:01:10 +00004084 if (LocaleCompare((const char *) tag,"normalize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004085 {
4086 /*
4087 Normalize image.
4088 */
4089 if (msl_info->image[n] == (Image *) NULL)
4090 {
cristyb988fe72009-09-16 01:01:10 +00004091 ThrowMSLException(OptionError,"NoImagesDefined",
4092 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004093 break;
4094 }
4095 if (attributes != (const xmlChar **) NULL)
4096 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4097 {
4098 keyword=(const char *) attributes[i++];
4099 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004100 msl_info->attributes[n],(const char *) attributes[i],
4101 &exception);
cristy3ed852e2009-09-05 21:47:34 +00004102 CloneString(&value,attribute);
4103 switch (*keyword)
4104 {
4105 case 'C':
4106 case 'c':
4107 {
4108 if (LocaleCompare(keyword,"channel") == 0)
4109 {
4110 option=ParseChannelOption(value);
4111 if (option < 0)
4112 ThrowMSLException(OptionError,"UnrecognizedChannelType",
4113 value);
4114 channel=(ChannelType) option;
4115 break;
4116 }
4117 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4118 keyword);
4119 break;
4120 }
4121 default:
4122 {
4123 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4124 keyword);
4125 break;
4126 }
4127 }
4128 }
cristye23ec9d2011-08-16 18:15:40 +00004129 (void) NormalizeImage(msl_info->image[n],
4130 &msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00004131 break;
4132 }
4133 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4134 }
4135 case 'O':
4136 case 'o':
4137 {
cristyb988fe72009-09-16 01:01:10 +00004138 if (LocaleCompare((const char *) tag,"oil-paint") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004139 {
4140 Image
4141 *paint_image;
4142
4143 /*
4144 Oil-paint image.
4145 */
4146 if (msl_info->image[n] == (Image *) NULL)
4147 {
cristyb988fe72009-09-16 01:01:10 +00004148 ThrowMSLException(OptionError,"NoImagesDefined",
4149 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004150 break;
4151 }
4152 if (attributes != (const xmlChar **) NULL)
4153 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4154 {
4155 keyword=(const char *) attributes[i++];
4156 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004157 msl_info->attributes[n],(const char *) attributes[i],
4158 &exception);
cristy3ed852e2009-09-05 21:47:34 +00004159 CloneString(&value,attribute);
4160 switch (*keyword)
4161 {
4162 case 'G':
4163 case 'g':
4164 {
4165 if (LocaleCompare(keyword,"geometry") == 0)
4166 {
4167 flags=ParseGeometry(value,&geometry_info);
4168 if ((flags & SigmaValue) == 0)
4169 geometry_info.sigma=1.0;
4170 break;
4171 }
4172 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4173 keyword);
4174 break;
4175 }
4176 case 'R':
4177 case 'r':
4178 {
4179 if (LocaleCompare(keyword,"radius") == 0)
4180 {
cristyc1acd842011-05-19 23:05:47 +00004181 geometry_info.rho=InterpretLocaleValue(value,
4182 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004183 break;
4184 }
4185 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4186 keyword);
4187 break;
4188 }
4189 default:
4190 {
4191 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4192 keyword);
4193 break;
4194 }
4195 }
4196 }
4197 paint_image=OilPaintImage(msl_info->image[n],geometry_info.rho,
cristy14973ba2011-08-27 23:48:07 +00004198 geometry_info.sigma,&msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00004199 if (paint_image == (Image *) NULL)
4200 break;
4201 msl_info->image[n]=DestroyImage(msl_info->image[n]);
4202 msl_info->image[n]=paint_image;
4203 break;
4204 }
cristyb988fe72009-09-16 01:01:10 +00004205 if (LocaleCompare((const char *) tag,"opaque") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004206 {
cristy4c08aed2011-07-01 19:47:50 +00004207 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00004208 fill_color,
4209 target;
4210
4211 /*
4212 Opaque image.
4213 */
4214 if (msl_info->image[n] == (Image *) NULL)
4215 {
cristyb988fe72009-09-16 01:01:10 +00004216 ThrowMSLException(OptionError,"NoImagesDefined",
4217 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004218 break;
4219 }
4220 (void) QueryMagickColor("none",&target,&exception);
4221 (void) QueryMagickColor("none",&fill_color,&exception);
4222 if (attributes != (const xmlChar **) NULL)
4223 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4224 {
4225 keyword=(const char *) attributes[i++];
4226 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004227 msl_info->attributes[n],(const char *) attributes[i],
4228 &exception);
cristy3ed852e2009-09-05 21:47:34 +00004229 CloneString(&value,attribute);
4230 switch (*keyword)
4231 {
4232 case 'C':
4233 case 'c':
4234 {
4235 if (LocaleCompare(keyword,"channel") == 0)
4236 {
4237 option=ParseChannelOption(value);
4238 if (option < 0)
4239 ThrowMSLException(OptionError,"UnrecognizedChannelType",
4240 value);
4241 channel=(ChannelType) option;
4242 break;
4243 }
4244 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4245 keyword);
4246 break;
4247 }
4248 case 'F':
4249 case 'f':
4250 {
4251 if (LocaleCompare(keyword,"fill") == 0)
4252 {
4253 (void) QueryMagickColor(value,&fill_color,&exception);
4254 break;
4255 }
4256 if (LocaleCompare(keyword,"fuzz") == 0)
4257 {
cristyc1acd842011-05-19 23:05:47 +00004258 msl_info->image[n]->fuzz=InterpretLocaleValue(value,
4259 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004260 break;
4261 }
4262 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4263 keyword);
4264 break;
4265 }
4266 default:
4267 {
4268 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4269 keyword);
4270 break;
4271 }
4272 }
4273 }
cristybd5a96c2011-08-21 00:04:26 +00004274 channel_mask=SetPixelChannelMask(msl_info->image[n],channel);
cristyd42d9952011-07-08 14:21:50 +00004275 (void) OpaquePaintImage(msl_info->image[n],&target,&fill_color,
cristy189e84c2011-08-27 18:08:53 +00004276 MagickFalse,&msl_info->image[n]->exception);
cristybd5a96c2011-08-21 00:04:26 +00004277 (void) SetPixelChannelMap(msl_info->image[n],channel_mask);
cristy3ed852e2009-09-05 21:47:34 +00004278 break;
4279 }
4280 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4281 }
4282 case 'P':
4283 case 'p':
4284 {
cristyb988fe72009-09-16 01:01:10 +00004285 if (LocaleCompare((const char *) tag,"print") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004286 {
4287 if (attributes == (const xmlChar **) NULL)
4288 break;
4289 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4290 {
4291 keyword=(const char *) attributes[i++];
4292 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004293 msl_info->attributes[n],(const char *) attributes[i],
4294 &exception);
cristy3ed852e2009-09-05 21:47:34 +00004295 CloneString(&value,attribute);
4296 switch (*keyword)
4297 {
4298 case 'O':
4299 case 'o':
4300 {
4301 if (LocaleCompare(keyword,"output") == 0)
4302 {
cristyb51dff52011-05-19 16:55:47 +00004303 (void) FormatLocaleFile(stdout,"%s",value);
cristy3ed852e2009-09-05 21:47:34 +00004304 break;
4305 }
4306 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
4307 break;
4308 }
4309 default:
4310 {
4311 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
4312 break;
4313 }
4314 }
4315 }
4316 break;
4317 }
cristy4fa36e42009-09-18 14:24:06 +00004318 if (LocaleCompare((const char *) tag, "profile") == 0)
4319 {
cristy4fa36e42009-09-18 14:24:06 +00004320 if (msl_info->image[n] == (Image *) NULL)
4321 {
4322 ThrowMSLException(OptionError,"NoImagesDefined",
4323 (const char *) tag);
4324 break;
4325 }
4326 if (attributes == (const xmlChar **) NULL)
4327 break;
4328 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4329 {
4330 const char
4331 *name;
4332
4333 const StringInfo
4334 *profile;
4335
4336 Image
4337 *profile_image;
4338
4339 ImageInfo
4340 *profile_info;
4341
4342 keyword=(const char *) attributes[i++];
4343 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004344 msl_info->attributes[n],(const char *) attributes[i],
4345 &exception);
cristy4fa36e42009-09-18 14:24:06 +00004346 CloneString(&value,attribute);
4347 if (*keyword == '+')
4348 {
4349 /*
4350 Remove a profile from the image.
4351 */
4352 (void) ProfileImage(msl_info->image[n],keyword,
4353 (const unsigned char *) NULL,0,MagickTrue);
4354 continue;
4355 }
4356 /*
4357 Associate a profile with the image.
4358 */
4359 profile_info=CloneImageInfo(msl_info->image_info[n]);
4360 profile=GetImageProfile(msl_info->image[n],"iptc");
4361 if (profile != (StringInfo *) NULL)
4362 profile_info->profile=(void *) CloneStringInfo(profile);
4363 profile_image=GetImageCache(profile_info,keyword,&exception);
4364 profile_info=DestroyImageInfo(profile_info);
4365 if (profile_image == (Image *) NULL)
4366 {
4367 char
4368 name[MaxTextExtent],
4369 filename[MaxTextExtent];
4370
4371 register char
4372 *p;
4373
4374 StringInfo
4375 *profile;
4376
4377 (void) CopyMagickString(filename,keyword,MaxTextExtent);
4378 (void) CopyMagickString(name,keyword,MaxTextExtent);
4379 for (p=filename; *p != '\0'; p++)
4380 if ((*p == ':') && (IsPathDirectory(keyword) < 0) &&
4381 (IsPathAccessible(keyword) == MagickFalse))
4382 {
4383 register char
4384 *q;
4385
4386 /*
4387 Look for profile name (e.g. name:profile).
4388 */
4389 (void) CopyMagickString(name,filename,(size_t)
4390 (p-filename+1));
4391 for (q=filename; *q != '\0'; q++)
4392 *q=(*++p);
4393 break;
4394 }
4395 profile=FileToStringInfo(filename,~0UL,&exception);
4396 if (profile != (StringInfo *) NULL)
4397 {
4398 (void) ProfileImage(msl_info->image[n],name,
cristybb503372010-05-27 20:51:26 +00004399 GetStringInfoDatum(profile),(size_t)
cristy4fa36e42009-09-18 14:24:06 +00004400 GetStringInfoLength(profile),MagickFalse);
4401 profile=DestroyStringInfo(profile);
4402 }
4403 continue;
4404 }
4405 ResetImageProfileIterator(profile_image);
4406 name=GetNextImageProfile(profile_image);
4407 while (name != (const char *) NULL)
4408 {
4409 profile=GetImageProfile(profile_image,name);
4410 if (profile != (StringInfo *) NULL)
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 name=GetNextImageProfile(profile_image);
4415 }
4416 profile_image=DestroyImage(profile_image);
4417 }
4418 break;
4419 }
cristy3ed852e2009-09-05 21:47:34 +00004420 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4421 }
4422 case 'Q':
4423 case 'q':
4424 {
cristyb988fe72009-09-16 01:01:10 +00004425 if (LocaleCompare((const char *) tag,"quantize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004426 {
4427 QuantizeInfo
4428 quantize_info;
4429
4430 /*
4431 Quantize image.
4432 */
4433 if (msl_info->image[n] == (Image *) NULL)
4434 {
cristyb988fe72009-09-16 01:01:10 +00004435 ThrowMSLException(OptionError,"NoImagesDefined",
4436 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004437 break;
4438 }
4439 GetQuantizeInfo(&quantize_info);
4440 if (attributes != (const xmlChar **) NULL)
4441 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4442 {
4443 keyword=(const char *) attributes[i++];
4444 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004445 msl_info->attributes[n],(const char *) attributes[i],
4446 &exception);
cristy3ed852e2009-09-05 21:47:34 +00004447 CloneString(&value,attribute);
4448 switch (*keyword)
4449 {
4450 case 'C':
4451 case 'c':
4452 {
4453 if (LocaleCompare(keyword,"colors") == 0)
4454 {
cristyf2f27272009-12-17 14:48:46 +00004455 quantize_info.number_colors=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004456 break;
4457 }
4458 if (LocaleCompare(keyword,"colorspace") == 0)
4459 {
cristy042ee782011-04-22 18:48:30 +00004460 option=ParseCommandOption(MagickColorspaceOptions,
cristy3ed852e2009-09-05 21:47:34 +00004461 MagickFalse,value);
4462 if (option < 0)
4463 ThrowMSLException(OptionError,
4464 "UnrecognizedColorspaceType",value);
4465 quantize_info.colorspace=(ColorspaceType) option;
4466 break;
4467 }
4468 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4469 keyword);
4470 break;
4471 }
4472 case 'D':
4473 case 'd':
4474 {
4475 if (LocaleCompare(keyword,"dither") == 0)
4476 {
cristy042ee782011-04-22 18:48:30 +00004477 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004478 value);
4479 if (option < 0)
4480 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4481 value);
4482 quantize_info.dither=(MagickBooleanType) option;
4483 break;
4484 }
4485 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4486 keyword);
4487 break;
4488 }
4489 case 'M':
4490 case 'm':
4491 {
4492 if (LocaleCompare(keyword,"measure") == 0)
4493 {
cristy042ee782011-04-22 18:48:30 +00004494 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004495 value);
4496 if (option < 0)
4497 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4498 value);
4499 quantize_info.measure_error=(MagickBooleanType) option;
4500 break;
4501 }
4502 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4503 keyword);
4504 break;
4505 }
4506 case 'T':
4507 case 't':
4508 {
4509 if (LocaleCompare(keyword,"treedepth") == 0)
4510 {
cristyf2f27272009-12-17 14:48:46 +00004511 quantize_info.tree_depth=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004512 break;
4513 }
4514 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4515 keyword);
4516 break;
4517 }
4518 default:
4519 {
4520 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4521 keyword);
4522 break;
4523 }
4524 }
4525 }
cristy018f07f2011-09-04 21:15:19 +00004526 (void) QuantizeImage(&quantize_info,msl_info->image[n],&exception);
cristy3ed852e2009-09-05 21:47:34 +00004527 break;
4528 }
cristyb988fe72009-09-16 01:01:10 +00004529 if (LocaleCompare((const char *) tag,"query-font-metrics") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004530 {
4531 char
4532 text[MaxTextExtent];
4533
4534 MagickBooleanType
4535 status;
4536
4537 TypeMetric
4538 metrics;
4539
4540 /*
4541 Query font metrics.
4542 */
4543 draw_info=CloneDrawInfo(msl_info->image_info[n],
4544 msl_info->draw_info[n]);
4545 angle=0.0;
4546 current=draw_info->affine;
4547 GetAffineMatrix(&affine);
4548 if (attributes != (const xmlChar **) NULL)
4549 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4550 {
4551 keyword=(const char *) attributes[i++];
4552 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004553 msl_info->attributes[n],(const char *) attributes[i],
4554 &exception);
cristy3ed852e2009-09-05 21:47:34 +00004555 CloneString(&value,attribute);
4556 switch (*keyword)
4557 {
4558 case 'A':
4559 case 'a':
4560 {
4561 if (LocaleCompare(keyword,"affine") == 0)
4562 {
4563 char
4564 *p;
4565
4566 p=value;
cristyc1acd842011-05-19 23:05:47 +00004567 draw_info->affine.sx=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004568 if (*p ==',')
4569 p++;
cristyc1acd842011-05-19 23:05:47 +00004570 draw_info->affine.rx=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004571 if (*p ==',')
4572 p++;
cristyc1acd842011-05-19 23:05:47 +00004573 draw_info->affine.ry=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004574 if (*p ==',')
4575 p++;
cristyc1acd842011-05-19 23:05:47 +00004576 draw_info->affine.sy=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004577 if (*p ==',')
4578 p++;
cristyc1acd842011-05-19 23:05:47 +00004579 draw_info->affine.tx=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004580 if (*p ==',')
4581 p++;
cristyc1acd842011-05-19 23:05:47 +00004582 draw_info->affine.ty=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004583 break;
4584 }
4585 if (LocaleCompare(keyword,"align") == 0)
4586 {
cristy042ee782011-04-22 18:48:30 +00004587 option=ParseCommandOption(MagickAlignOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004588 value);
4589 if (option < 0)
4590 ThrowMSLException(OptionError,"UnrecognizedAlignType",
4591 value);
4592 draw_info->align=(AlignType) option;
4593 break;
4594 }
4595 if (LocaleCompare(keyword,"antialias") == 0)
4596 {
cristy042ee782011-04-22 18:48:30 +00004597 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004598 value);
4599 if (option < 0)
4600 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4601 value);
4602 draw_info->stroke_antialias=(MagickBooleanType) option;
4603 draw_info->text_antialias=(MagickBooleanType) option;
4604 break;
4605 }
4606 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4607 keyword);
4608 break;
4609 }
4610 case 'D':
4611 case 'd':
4612 {
4613 if (LocaleCompare(keyword,"density") == 0)
4614 {
4615 CloneString(&draw_info->density,value);
4616 break;
4617 }
4618 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4619 keyword);
4620 break;
4621 }
4622 case 'E':
4623 case 'e':
4624 {
4625 if (LocaleCompare(keyword,"encoding") == 0)
4626 {
4627 CloneString(&draw_info->encoding,value);
4628 break;
4629 }
4630 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4631 keyword);
4632 break;
4633 }
4634 case 'F':
4635 case 'f':
4636 {
4637 if (LocaleCompare(keyword, "fill") == 0)
4638 {
4639 (void) QueryColorDatabase(value,&draw_info->fill,
4640 &exception);
4641 break;
4642 }
4643 if (LocaleCompare(keyword,"family") == 0)
4644 {
4645 CloneString(&draw_info->family,value);
4646 break;
4647 }
4648 if (LocaleCompare(keyword,"font") == 0)
4649 {
4650 CloneString(&draw_info->font,value);
4651 break;
4652 }
4653 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4654 keyword);
4655 break;
4656 }
4657 case 'G':
4658 case 'g':
4659 {
4660 if (LocaleCompare(keyword,"geometry") == 0)
4661 {
4662 flags=ParsePageGeometry(msl_info->image[n],value,
4663 &geometry,&exception);
4664 if ((flags & HeightValue) == 0)
4665 geometry.height=geometry.width;
4666 break;
4667 }
4668 if (LocaleCompare(keyword,"gravity") == 0)
4669 {
cristy042ee782011-04-22 18:48:30 +00004670 option=ParseCommandOption(MagickGravityOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004671 value);
4672 if (option < 0)
4673 ThrowMSLException(OptionError,"UnrecognizedGravityType",
4674 value);
4675 draw_info->gravity=(GravityType) option;
4676 break;
4677 }
4678 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4679 keyword);
4680 break;
4681 }
4682 case 'P':
4683 case 'p':
4684 {
4685 if (LocaleCompare(keyword,"pointsize") == 0)
4686 {
cristyc1acd842011-05-19 23:05:47 +00004687 draw_info->pointsize=InterpretLocaleValue(value,
4688 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004689 break;
4690 }
4691 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4692 keyword);
4693 break;
4694 }
4695 case 'R':
4696 case 'r':
4697 {
4698 if (LocaleCompare(keyword,"rotate") == 0)
4699 {
cristyc1acd842011-05-19 23:05:47 +00004700 angle=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004701 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
4702 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
4703 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
4704 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
4705 break;
4706 }
4707 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4708 keyword);
4709 break;
4710 }
4711 case 'S':
4712 case 's':
4713 {
4714 if (LocaleCompare(keyword,"scale") == 0)
4715 {
4716 flags=ParseGeometry(value,&geometry_info);
4717 if ((flags & SigmaValue) == 0)
4718 geometry_info.sigma=1.0;
4719 affine.sx=geometry_info.rho;
4720 affine.sy=geometry_info.sigma;
4721 break;
4722 }
4723 if (LocaleCompare(keyword,"skewX") == 0)
4724 {
cristyc1acd842011-05-19 23:05:47 +00004725 angle=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004726 affine.ry=cos(DegreesToRadians(fmod(angle,360.0)));
4727 break;
4728 }
4729 if (LocaleCompare(keyword,"skewY") == 0)
4730 {
cristyc1acd842011-05-19 23:05:47 +00004731 angle=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004732 affine.rx=cos(DegreesToRadians(fmod(angle,360.0)));
4733 break;
4734 }
4735 if (LocaleCompare(keyword,"stretch") == 0)
4736 {
cristy042ee782011-04-22 18:48:30 +00004737 option=ParseCommandOption(MagickStretchOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004738 value);
4739 if (option < 0)
4740 ThrowMSLException(OptionError,"UnrecognizedStretchType",
4741 value);
4742 draw_info->stretch=(StretchType) option;
4743 break;
4744 }
4745 if (LocaleCompare(keyword, "stroke") == 0)
4746 {
4747 (void) QueryColorDatabase(value,&draw_info->stroke,
4748 &exception);
4749 break;
4750 }
4751 if (LocaleCompare(keyword,"strokewidth") == 0)
4752 {
cristyf2f27272009-12-17 14:48:46 +00004753 draw_info->stroke_width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004754 break;
4755 }
4756 if (LocaleCompare(keyword,"style") == 0)
4757 {
cristy042ee782011-04-22 18:48:30 +00004758 option=ParseCommandOption(MagickStyleOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004759 value);
4760 if (option < 0)
4761 ThrowMSLException(OptionError,"UnrecognizedStyleType",
4762 value);
4763 draw_info->style=(StyleType) option;
4764 break;
4765 }
4766 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4767 keyword);
4768 break;
4769 }
4770 case 'T':
4771 case 't':
4772 {
4773 if (LocaleCompare(keyword,"text") == 0)
4774 {
4775 CloneString(&draw_info->text,value);
4776 break;
4777 }
4778 if (LocaleCompare(keyword,"translate") == 0)
4779 {
4780 flags=ParseGeometry(value,&geometry_info);
4781 if ((flags & SigmaValue) == 0)
4782 geometry_info.sigma=1.0;
4783 affine.tx=geometry_info.rho;
4784 affine.ty=geometry_info.sigma;
4785 break;
4786 }
4787 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4788 keyword);
4789 break;
4790 }
4791 case 'U':
4792 case 'u':
4793 {
4794 if (LocaleCompare(keyword, "undercolor") == 0)
4795 {
4796 (void) QueryColorDatabase(value,&draw_info->undercolor,
4797 &exception);
4798 break;
4799 }
4800 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4801 keyword);
4802 break;
4803 }
4804 case 'W':
4805 case 'w':
4806 {
4807 if (LocaleCompare(keyword,"weight") == 0)
4808 {
cristyf2f27272009-12-17 14:48:46 +00004809 draw_info->weight=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004810 break;
4811 }
4812 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4813 keyword);
4814 break;
4815 }
4816 case 'X':
4817 case 'x':
4818 {
4819 if (LocaleCompare(keyword,"x") == 0)
4820 {
cristyf2f27272009-12-17 14:48:46 +00004821 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004822 break;
4823 }
4824 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4825 keyword);
4826 break;
4827 }
4828 case 'Y':
4829 case 'y':
4830 {
4831 if (LocaleCompare(keyword,"y") == 0)
4832 {
cristyf2f27272009-12-17 14:48:46 +00004833 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004834 break;
4835 }
4836 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4837 keyword);
4838 break;
4839 }
4840 default:
4841 {
4842 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4843 keyword);
4844 break;
4845 }
4846 }
4847 }
cristyb51dff52011-05-19 16:55:47 +00004848 (void) FormatLocaleString(text,MaxTextExtent,
cristye8c25f92010-06-03 00:53:06 +00004849 "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,(double)
4850 geometry.height,(double) geometry.x,(double) geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00004851 CloneString(&draw_info->geometry,text);
cristyef7c8a52010-10-10 13:46:51 +00004852 draw_info->affine.sx=affine.sx*current.sx+affine.ry*current.rx;
4853 draw_info->affine.rx=affine.rx*current.sx+affine.sy*current.rx;
4854 draw_info->affine.ry=affine.sx*current.ry+affine.ry*current.sy;
4855 draw_info->affine.sy=affine.rx*current.ry+affine.sy*current.sy;
4856 draw_info->affine.tx=affine.sx*current.tx+affine.ry*current.ty+
4857 affine.tx;
4858 draw_info->affine.ty=affine.rx*current.tx+affine.sy*current.ty+
4859 affine.ty;
cristy5cbc0162011-08-29 00:36:28 +00004860 status=GetTypeMetrics(msl_info->attributes[n],draw_info,&metrics,
4861 &msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00004862 if (status != MagickFalse)
4863 {
4864 Image
4865 *image;
4866
4867 image=msl_info->attributes[n];
cristy8cd5b312010-01-07 01:10:24 +00004868 FormatImageProperty(image,"msl:font-metrics.pixels_per_em.x",
cristye7f51092010-01-17 00:39:37 +00004869 "%g",metrics.pixels_per_em.x);
cristy8cd5b312010-01-07 01:10:24 +00004870 FormatImageProperty(image,"msl:font-metrics.pixels_per_em.y",
cristye7f51092010-01-17 00:39:37 +00004871 "%g",metrics.pixels_per_em.y);
4872 FormatImageProperty(image,"msl:font-metrics.ascent","%g",
cristy3ed852e2009-09-05 21:47:34 +00004873 metrics.ascent);
cristye7f51092010-01-17 00:39:37 +00004874 FormatImageProperty(image,"msl:font-metrics.descent","%g",
cristy3ed852e2009-09-05 21:47:34 +00004875 metrics.descent);
cristye7f51092010-01-17 00:39:37 +00004876 FormatImageProperty(image,"msl:font-metrics.width","%g",
cristy3ed852e2009-09-05 21:47:34 +00004877 metrics.width);
cristye7f51092010-01-17 00:39:37 +00004878 FormatImageProperty(image,"msl:font-metrics.height","%g",
cristy3ed852e2009-09-05 21:47:34 +00004879 metrics.height);
cristye7f51092010-01-17 00:39:37 +00004880 FormatImageProperty(image,"msl:font-metrics.max_advance","%g",
cristy3ed852e2009-09-05 21:47:34 +00004881 metrics.max_advance);
cristye7f51092010-01-17 00:39:37 +00004882 FormatImageProperty(image,"msl:font-metrics.bounds.x1","%g",
cristy3ed852e2009-09-05 21:47:34 +00004883 metrics.bounds.x1);
cristye7f51092010-01-17 00:39:37 +00004884 FormatImageProperty(image,"msl:font-metrics.bounds.y1","%g",
cristy3ed852e2009-09-05 21:47:34 +00004885 metrics.bounds.y1);
cristye7f51092010-01-17 00:39:37 +00004886 FormatImageProperty(image,"msl:font-metrics.bounds.x2","%g",
cristy3ed852e2009-09-05 21:47:34 +00004887 metrics.bounds.x2);
cristye7f51092010-01-17 00:39:37 +00004888 FormatImageProperty(image,"msl:font-metrics.bounds.y2","%g",
cristy3ed852e2009-09-05 21:47:34 +00004889 metrics.bounds.y2);
cristye7f51092010-01-17 00:39:37 +00004890 FormatImageProperty(image,"msl:font-metrics.origin.x","%g",
cristy3ed852e2009-09-05 21:47:34 +00004891 metrics.origin.x);
cristye7f51092010-01-17 00:39:37 +00004892 FormatImageProperty(image,"msl:font-metrics.origin.y","%g",
cristy3ed852e2009-09-05 21:47:34 +00004893 metrics.origin.y);
4894 }
4895 draw_info=DestroyDrawInfo(draw_info);
4896 break;
4897 }
4898 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4899 }
4900 case 'R':
4901 case 'r':
4902 {
cristyb988fe72009-09-16 01:01:10 +00004903 if (LocaleCompare((const char *) tag,"raise") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004904 {
4905 MagickBooleanType
4906 raise;
4907
4908 /*
4909 Raise image.
4910 */
4911 if (msl_info->image[n] == (Image *) NULL)
4912 {
cristyb988fe72009-09-16 01:01:10 +00004913 ThrowMSLException(OptionError,"NoImagesDefined",
4914 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004915 break;
4916 }
4917 raise=MagickFalse;
4918 SetGeometry(msl_info->image[n],&geometry);
4919 if (attributes != (const xmlChar **) NULL)
4920 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4921 {
4922 keyword=(const char *) attributes[i++];
4923 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004924 msl_info->attributes[n],(const char *) attributes[i],
4925 &exception);
cristy3ed852e2009-09-05 21:47:34 +00004926 CloneString(&value,attribute);
4927 switch (*keyword)
4928 {
4929 case 'G':
4930 case 'g':
4931 {
4932 if (LocaleCompare(keyword,"geometry") == 0)
4933 {
4934 flags=ParsePageGeometry(msl_info->image[n],value,
4935 &geometry,&exception);
4936 if ((flags & HeightValue) == 0)
4937 geometry.height=geometry.width;
4938 break;
4939 }
4940 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4941 keyword);
4942 break;
4943 }
4944 case 'H':
4945 case 'h':
4946 {
4947 if (LocaleCompare(keyword,"height") == 0)
4948 {
cristyf2f27272009-12-17 14:48:46 +00004949 geometry.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004950 break;
4951 }
4952 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4953 keyword);
4954 break;
4955 }
4956 case 'R':
4957 case 'r':
4958 {
4959 if (LocaleCompare(keyword,"raise") == 0)
4960 {
cristy042ee782011-04-22 18:48:30 +00004961 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004962 value);
4963 if (option < 0)
4964 ThrowMSLException(OptionError,"UnrecognizedNoiseType",
4965 value);
4966 raise=(MagickBooleanType) option;
4967 break;
4968 }
4969 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4970 keyword);
4971 break;
4972 }
4973 case 'W':
4974 case 'w':
4975 {
4976 if (LocaleCompare(keyword,"width") == 0)
4977 {
cristyf2f27272009-12-17 14:48:46 +00004978 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004979 break;
4980 }
4981 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4982 keyword);
4983 break;
4984 }
4985 default:
4986 {
4987 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4988 keyword);
4989 break;
4990 }
4991 }
4992 }
cristy6170ac32011-08-28 14:15:37 +00004993 (void) RaiseImage(msl_info->image[n],&geometry,raise,
4994 &msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00004995 break;
4996 }
cristyb988fe72009-09-16 01:01:10 +00004997 if (LocaleCompare((const char *) tag,"read") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004998 {
4999 if (attributes == (const xmlChar **) NULL)
5000 break;
5001 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5002 {
5003 keyword=(const char *) attributes[i++];
5004 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005005 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00005006 switch (*keyword)
5007 {
5008 case 'F':
5009 case 'f':
5010 {
5011 if (LocaleCompare(keyword,"filename") == 0)
5012 {
5013 Image
5014 *image;
5015
5016 (void) CopyMagickString(msl_info->image_info[n]->filename,
5017 value,MaxTextExtent);
5018 image=ReadImage(msl_info->image_info[n],&exception);
5019 CatchException(&exception);
5020 if (image == (Image *) NULL)
5021 continue;
5022 AppendImageToList(&msl_info->image[n],image);
5023 break;
5024 }
cristy4582cbb2009-09-23 00:35:43 +00005025 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00005026 break;
5027 }
5028 default:
5029 {
cristy4582cbb2009-09-23 00:35:43 +00005030 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00005031 break;
5032 }
5033 }
5034 }
5035 break;
5036 }
cristyb988fe72009-09-16 01:01:10 +00005037 if (LocaleCompare((const char *) tag,"reduce-noise") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005038 {
5039 Image
5040 *paint_image;
5041
5042 /*
5043 Reduce-noise image.
5044 */
5045 if (msl_info->image[n] == (Image *) NULL)
5046 {
cristyb988fe72009-09-16 01:01:10 +00005047 ThrowMSLException(OptionError,"NoImagesDefined",
5048 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005049 break;
5050 }
5051 if (attributes != (const xmlChar **) NULL)
5052 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5053 {
5054 keyword=(const char *) attributes[i++];
5055 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005056 msl_info->attributes[n],(const char *) attributes[i],
5057 &exception);
cristy3ed852e2009-09-05 21:47:34 +00005058 CloneString(&value,attribute);
5059 switch (*keyword)
5060 {
5061 case 'G':
5062 case 'g':
5063 {
5064 if (LocaleCompare(keyword,"geometry") == 0)
5065 {
5066 flags=ParseGeometry(value,&geometry_info);
5067 if ((flags & SigmaValue) == 0)
5068 geometry_info.sigma=1.0;
5069 break;
5070 }
5071 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5072 keyword);
5073 break;
5074 }
5075 case 'R':
5076 case 'r':
5077 {
5078 if (LocaleCompare(keyword,"radius") == 0)
5079 {
cristyc1acd842011-05-19 23:05:47 +00005080 geometry_info.rho=InterpretLocaleValue(value,
5081 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005082 break;
5083 }
5084 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5085 keyword);
5086 break;
5087 }
5088 default:
5089 {
5090 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5091 keyword);
5092 break;
5093 }
5094 }
5095 }
cristy733678d2011-03-18 21:29:28 +00005096 paint_image=StatisticImage(msl_info->image[n],NonpeakStatistic,
cristy95c38342011-03-18 22:39:51 +00005097 (size_t) geometry_info.rho,(size_t) geometry_info.sigma,
5098 &msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00005099 if (paint_image == (Image *) NULL)
5100 break;
5101 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5102 msl_info->image[n]=paint_image;
5103 break;
5104 }
cristyb988fe72009-09-16 01:01:10 +00005105 else if (LocaleCompare((const char *) tag,"repage") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005106 {
5107 /* init the values */
5108 width=msl_info->image[n]->page.width;
5109 height=msl_info->image[n]->page.height;
5110 x=msl_info->image[n]->page.x;
5111 y=msl_info->image[n]->page.y;
5112
5113 if (msl_info->image[n] == (Image *) NULL)
5114 {
cristyb988fe72009-09-16 01:01:10 +00005115 ThrowMSLException(OptionError,"NoImagesDefined",
5116 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005117 break;
5118 }
5119 if (attributes == (const xmlChar **) NULL)
5120 break;
5121 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5122 {
5123 keyword=(const char *) attributes[i++];
5124 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005125 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00005126 switch (*keyword)
5127 {
5128 case 'G':
5129 case 'g':
5130 {
5131 if (LocaleCompare(keyword,"geometry") == 0)
5132 {
5133 int
5134 flags;
5135
5136 RectangleInfo
5137 geometry;
5138
5139 flags=ParseAbsoluteGeometry(value,&geometry);
5140 if ((flags & WidthValue) != 0)
5141 {
5142 if ((flags & HeightValue) == 0)
5143 geometry.height=geometry.width;
5144 width=geometry.width;
5145 height=geometry.height;
5146 }
5147 if ((flags & AspectValue) != 0)
5148 {
5149 if ((flags & XValue) != 0)
5150 x+=geometry.x;
5151 if ((flags & YValue) != 0)
5152 y+=geometry.y;
5153 }
5154 else
5155 {
5156 if ((flags & XValue) != 0)
5157 {
5158 x=geometry.x;
5159 if ((width == 0) && (geometry.x > 0))
5160 width=msl_info->image[n]->columns+geometry.x;
5161 }
5162 if ((flags & YValue) != 0)
5163 {
5164 y=geometry.y;
5165 if ((height == 0) && (geometry.y > 0))
5166 height=msl_info->image[n]->rows+geometry.y;
5167 }
5168 }
5169 break;
5170 }
5171 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5172 break;
5173 }
5174 case 'H':
5175 case 'h':
5176 {
5177 if (LocaleCompare(keyword,"height") == 0)
5178 {
cristyf2f27272009-12-17 14:48:46 +00005179 height = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005180 break;
5181 }
5182 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5183 break;
5184 }
5185 case 'W':
5186 case 'w':
5187 {
5188 if (LocaleCompare(keyword,"width") == 0)
5189 {
cristyf2f27272009-12-17 14:48:46 +00005190 width = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005191 break;
5192 }
5193 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5194 break;
5195 }
5196 case 'X':
5197 case 'x':
5198 {
5199 if (LocaleCompare(keyword,"x") == 0)
5200 {
cristyf2f27272009-12-17 14:48:46 +00005201 x = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005202 break;
5203 }
5204 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5205 break;
5206 }
5207 case 'Y':
5208 case 'y':
5209 {
5210 if (LocaleCompare(keyword,"y") == 0)
5211 {
cristyf2f27272009-12-17 14:48:46 +00005212 y = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005213 break;
5214 }
5215 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5216 break;
5217 }
5218 default:
5219 {
5220 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5221 break;
5222 }
5223 }
5224 }
5225
cristyb988fe72009-09-16 01:01:10 +00005226 msl_info->image[n]->page.width=width;
5227 msl_info->image[n]->page.height=height;
5228 msl_info->image[n]->page.x=x;
5229 msl_info->image[n]->page.y=y;
cristy3ed852e2009-09-05 21:47:34 +00005230 break;
5231 }
cristyb988fe72009-09-16 01:01:10 +00005232 else if (LocaleCompare((const char *) tag,"resample") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005233 {
5234 double
5235 x_resolution,
5236 y_resolution;
5237
5238 if (msl_info->image[n] == (Image *) NULL)
5239 {
cristyb988fe72009-09-16 01:01:10 +00005240 ThrowMSLException(OptionError,"NoImagesDefined",
5241 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005242 break;
5243 }
5244 if (attributes == (const xmlChar **) NULL)
5245 break;
5246 x_resolution=DefaultResolution;
5247 y_resolution=DefaultResolution;
5248 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5249 {
5250 keyword=(const char *) attributes[i++];
5251 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005252 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00005253 switch (*keyword)
5254 {
5255 case 'b':
5256 {
5257 if (LocaleCompare(keyword,"blur") == 0)
5258 {
cristyc1acd842011-05-19 23:05:47 +00005259 msl_info->image[n]->blur=InterpretLocaleValue(value,
5260 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005261 break;
5262 }
5263 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5264 break;
5265 }
5266 case 'G':
5267 case 'g':
5268 {
5269 if (LocaleCompare(keyword,"geometry") == 0)
5270 {
cristybb503372010-05-27 20:51:26 +00005271 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00005272 flags;
5273
5274 flags=ParseGeometry(value,&geometry_info);
5275 if ((flags & SigmaValue) == 0)
5276 geometry_info.sigma*=geometry_info.rho;
5277 x_resolution=geometry_info.rho;
5278 y_resolution=geometry_info.sigma;
5279 break;
5280 }
5281 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5282 break;
5283 }
5284 case 'X':
5285 case 'x':
5286 {
5287 if (LocaleCompare(keyword,"x-resolution") == 0)
5288 {
cristyc1acd842011-05-19 23:05:47 +00005289 x_resolution=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005290 break;
5291 }
5292 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5293 break;
5294 }
5295 case 'Y':
5296 case 'y':
5297 {
5298 if (LocaleCompare(keyword,"y-resolution") == 0)
5299 {
cristyc1acd842011-05-19 23:05:47 +00005300 y_resolution=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005301 break;
5302 }
5303 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5304 break;
5305 }
5306 default:
5307 {
5308 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5309 break;
5310 }
5311 }
5312 }
5313 /*
5314 Resample image.
5315 */
5316 {
5317 double
5318 factor;
5319
5320 Image
5321 *resample_image;
5322
5323 factor=1.0;
5324 if (msl_info->image[n]->units == PixelsPerCentimeterResolution)
5325 factor=2.54;
cristybb503372010-05-27 20:51:26 +00005326 width=(size_t) (x_resolution*msl_info->image[n]->columns/
cristy3ed852e2009-09-05 21:47:34 +00005327 (factor*(msl_info->image[n]->x_resolution == 0.0 ? DefaultResolution :
5328 msl_info->image[n]->x_resolution))+0.5);
cristybb503372010-05-27 20:51:26 +00005329 height=(size_t) (y_resolution*msl_info->image[n]->rows/
cristy3ed852e2009-09-05 21:47:34 +00005330 (factor*(msl_info->image[n]->y_resolution == 0.0 ? DefaultResolution :
5331 msl_info->image[n]->y_resolution))+0.5);
5332 resample_image=ResizeImage(msl_info->image[n],width,height,
5333 msl_info->image[n]->filter,msl_info->image[n]->blur,
5334 &msl_info->image[n]->exception);
5335 if (resample_image == (Image *) NULL)
5336 break;
5337 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5338 msl_info->image[n]=resample_image;
5339 }
5340 break;
5341 }
cristyb988fe72009-09-16 01:01:10 +00005342 if (LocaleCompare((const char *) tag,"resize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005343 {
5344 double
5345 blur;
5346
5347 FilterTypes
5348 filter;
5349
5350 Image
5351 *resize_image;
5352
5353 /*
5354 Resize image.
5355 */
5356 if (msl_info->image[n] == (Image *) NULL)
5357 {
cristyb988fe72009-09-16 01:01:10 +00005358 ThrowMSLException(OptionError,"NoImagesDefined",
5359 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005360 break;
5361 }
5362 filter=UndefinedFilter;
5363 blur=1.0;
5364 if (attributes != (const xmlChar **) NULL)
5365 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5366 {
5367 keyword=(const char *) attributes[i++];
5368 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005369 msl_info->attributes[n],(const char *) attributes[i],
5370 &exception);
cristy3ed852e2009-09-05 21:47:34 +00005371 CloneString(&value,attribute);
5372 switch (*keyword)
5373 {
5374 case 'F':
5375 case 'f':
5376 {
5377 if (LocaleCompare(keyword,"filter") == 0)
5378 {
cristy042ee782011-04-22 18:48:30 +00005379 option=ParseCommandOption(MagickFilterOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00005380 value);
5381 if (option < 0)
5382 ThrowMSLException(OptionError,"UnrecognizedNoiseType",
5383 value);
5384 filter=(FilterTypes) option;
5385 break;
5386 }
5387 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5388 keyword);
5389 break;
5390 }
5391 case 'G':
5392 case 'g':
5393 {
5394 if (LocaleCompare(keyword,"geometry") == 0)
5395 {
5396 flags=ParseRegionGeometry(msl_info->image[n],value,
5397 &geometry,&exception);
5398 break;
5399 }
5400 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5401 keyword);
5402 break;
5403 }
5404 case 'H':
5405 case 'h':
5406 {
5407 if (LocaleCompare(keyword,"height") == 0)
5408 {
cristye27293e2009-12-18 02:53:20 +00005409 geometry.height=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005410 break;
5411 }
5412 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5413 keyword);
5414 break;
5415 }
5416 case 'S':
5417 case 's':
5418 {
5419 if (LocaleCompare(keyword,"support") == 0)
5420 {
cristyc1acd842011-05-19 23:05:47 +00005421 blur=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005422 break;
5423 }
5424 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5425 keyword);
5426 break;
5427 }
5428 case 'W':
5429 case 'w':
5430 {
5431 if (LocaleCompare(keyword,"width") == 0)
5432 {
cristyf2f27272009-12-17 14:48:46 +00005433 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005434 break;
5435 }
5436 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5437 keyword);
5438 break;
5439 }
5440 default:
5441 {
5442 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5443 keyword);
5444 break;
5445 }
5446 }
5447 }
5448 resize_image=ResizeImage(msl_info->image[n],geometry.width,
5449 geometry.height,filter,blur,&msl_info->image[n]->exception);
5450 if (resize_image == (Image *) NULL)
5451 break;
5452 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5453 msl_info->image[n]=resize_image;
5454 break;
5455 }
cristyb988fe72009-09-16 01:01:10 +00005456 if (LocaleCompare((const char *) tag,"roll") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005457 {
5458 Image
5459 *roll_image;
5460
5461 /*
5462 Roll image.
5463 */
5464 if (msl_info->image[n] == (Image *) NULL)
5465 {
cristyb988fe72009-09-16 01:01:10 +00005466 ThrowMSLException(OptionError,"NoImagesDefined",
5467 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005468 break;
5469 }
5470 SetGeometry(msl_info->image[n],&geometry);
5471 if (attributes != (const xmlChar **) NULL)
5472 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5473 {
5474 keyword=(const char *) attributes[i++];
5475 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005476 msl_info->attributes[n],(const char *) attributes[i],
5477 &exception);
cristy3ed852e2009-09-05 21:47:34 +00005478 CloneString(&value,attribute);
5479 switch (*keyword)
5480 {
5481 case 'G':
5482 case 'g':
5483 {
5484 if (LocaleCompare(keyword,"geometry") == 0)
5485 {
5486 flags=ParsePageGeometry(msl_info->image[n],value,
5487 &geometry,&exception);
5488 if ((flags & HeightValue) == 0)
5489 geometry.height=geometry.width;
5490 break;
5491 }
5492 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5493 keyword);
5494 break;
5495 }
5496 case 'X':
5497 case 'x':
5498 {
5499 if (LocaleCompare(keyword,"x") == 0)
5500 {
cristyf2f27272009-12-17 14:48:46 +00005501 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005502 break;
5503 }
5504 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5505 keyword);
5506 break;
5507 }
5508 case 'Y':
5509 case 'y':
5510 {
5511 if (LocaleCompare(keyword,"y") == 0)
5512 {
cristyf2f27272009-12-17 14:48:46 +00005513 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005514 break;
5515 }
5516 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5517 keyword);
5518 break;
5519 }
5520 default:
5521 {
5522 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5523 keyword);
5524 break;
5525 }
5526 }
5527 }
5528 roll_image=RollImage(msl_info->image[n],geometry.x,geometry.y,
5529 &msl_info->image[n]->exception);
5530 if (roll_image == (Image *) NULL)
5531 break;
5532 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5533 msl_info->image[n]=roll_image;
5534 break;
5535 }
cristyb988fe72009-09-16 01:01:10 +00005536 else if (LocaleCompare((const char *) tag,"roll") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005537 {
5538 /* init the values */
5539 width=msl_info->image[n]->columns;
5540 height=msl_info->image[n]->rows;
5541 x = y = 0;
5542
5543 if (msl_info->image[n] == (Image *) NULL)
5544 {
cristyb988fe72009-09-16 01:01:10 +00005545 ThrowMSLException(OptionError,"NoImagesDefined",
5546 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005547 break;
5548 }
5549 if (attributes == (const xmlChar **) NULL)
5550 break;
5551 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5552 {
5553 keyword=(const char *) attributes[i++];
5554 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005555 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00005556 switch (*keyword)
5557 {
5558 case 'G':
5559 case 'g':
5560 {
5561 if (LocaleCompare(keyword,"geometry") == 0)
5562 {
5563 (void) ParseMetaGeometry(value,&x,&y,&width,&height);
5564 break;
5565 }
5566 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5567 break;
5568 }
5569 case 'X':
5570 case 'x':
5571 {
5572 if (LocaleCompare(keyword,"x") == 0)
5573 {
cristyf2f27272009-12-17 14:48:46 +00005574 x = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005575 break;
5576 }
5577 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5578 break;
5579 }
5580 case 'Y':
5581 case 'y':
5582 {
5583 if (LocaleCompare(keyword,"y") == 0)
5584 {
cristyf2f27272009-12-17 14:48:46 +00005585 y = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005586 break;
5587 }
5588 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5589 break;
5590 }
5591 default:
5592 {
5593 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5594 break;
5595 }
5596 }
5597 }
5598
5599 /*
5600 process image.
5601 */
5602 {
5603 Image
5604 *newImage;
5605
5606 newImage=RollImage(msl_info->image[n], x, y, &msl_info->image[n]->exception);
5607 if (newImage == (Image *) NULL)
5608 break;
5609 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5610 msl_info->image[n]=newImage;
5611 }
5612
5613 break;
5614 }
cristyb988fe72009-09-16 01:01:10 +00005615 if (LocaleCompare((const char *) tag,"rotate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005616 {
5617 Image
5618 *rotate_image;
5619
5620 /*
5621 Rotate image.
5622 */
5623 if (msl_info->image[n] == (Image *) NULL)
5624 {
cristyb988fe72009-09-16 01:01:10 +00005625 ThrowMSLException(OptionError,"NoImagesDefined",
5626 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005627 break;
5628 }
5629 if (attributes != (const xmlChar **) NULL)
5630 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5631 {
5632 keyword=(const char *) attributes[i++];
5633 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005634 msl_info->attributes[n],(const char *) attributes[i],
5635 &exception);
cristy3ed852e2009-09-05 21:47:34 +00005636 CloneString(&value,attribute);
5637 switch (*keyword)
5638 {
5639 case 'D':
5640 case 'd':
5641 {
5642 if (LocaleCompare(keyword,"degrees") == 0)
5643 {
cristyc1acd842011-05-19 23:05:47 +00005644 geometry_info.rho=InterpretLocaleValue(value,
5645 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005646 break;
5647 }
5648 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5649 keyword);
5650 break;
5651 }
5652 case 'G':
5653 case 'g':
5654 {
5655 if (LocaleCompare(keyword,"geometry") == 0)
5656 {
5657 flags=ParseGeometry(value,&geometry_info);
5658 if ((flags & SigmaValue) == 0)
5659 geometry_info.sigma=1.0;
5660 break;
5661 }
5662 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5663 keyword);
5664 break;
5665 }
5666 default:
5667 {
5668 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5669 keyword);
5670 break;
5671 }
5672 }
5673 }
5674 rotate_image=RotateImage(msl_info->image[n],geometry_info.rho,
5675 &msl_info->image[n]->exception);
5676 if (rotate_image == (Image *) NULL)
5677 break;
5678 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5679 msl_info->image[n]=rotate_image;
5680 break;
5681 }
cristyb988fe72009-09-16 01:01:10 +00005682 else if (LocaleCompare((const char *) tag,"rotate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005683 {
5684 /* init the values */
5685 double degrees = 0;
5686
5687 if (msl_info->image[n] == (Image *) NULL)
5688 {
cristyb988fe72009-09-16 01:01:10 +00005689 ThrowMSLException(OptionError,"NoImagesDefined",
5690 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005691 break;
5692 }
5693 if (attributes == (const xmlChar **) NULL)
cristy31939262009-09-15 00:23:11 +00005694 break;
cristy3ed852e2009-09-05 21:47:34 +00005695 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5696 {
5697 keyword=(const char *) attributes[i++];
5698 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005699 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00005700 switch (*keyword)
5701 {
5702 case 'D':
5703 case 'd':
5704 {
5705 if (LocaleCompare(keyword,"degrees") == 0)
5706 {
cristyc1acd842011-05-19 23:05:47 +00005707 degrees = InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005708 break;
5709 }
5710 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5711 break;
5712 }
5713 default:
5714 {
5715 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5716 break;
5717 }
5718 }
5719 }
5720
5721 /*
5722 process image.
5723 */
5724 {
5725 Image
5726 *newImage;
5727
5728 newImage=RotateImage(msl_info->image[n], degrees, &msl_info->image[n]->exception);
5729 if (newImage == (Image *) NULL)
5730 break;
5731 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5732 msl_info->image[n]=newImage;
5733 }
5734
5735 break;
5736 }
5737 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
5738 }
5739 case 'S':
5740 case 's':
5741 {
cristyb988fe72009-09-16 01:01:10 +00005742 if (LocaleCompare((const char *) tag,"sample") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005743 {
5744 Image
5745 *sample_image;
5746
5747 /*
5748 Sample image.
5749 */
5750 if (msl_info->image[n] == (Image *) NULL)
5751 {
cristyb988fe72009-09-16 01:01:10 +00005752 ThrowMSLException(OptionError,"NoImagesDefined",
5753 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005754 break;
5755 }
5756 if (attributes != (const xmlChar **) NULL)
5757 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5758 {
5759 keyword=(const char *) attributes[i++];
5760 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005761 msl_info->attributes[n],(const char *) attributes[i],
5762 &exception);
cristy3ed852e2009-09-05 21:47:34 +00005763 CloneString(&value,attribute);
5764 switch (*keyword)
5765 {
5766 case 'G':
5767 case 'g':
5768 {
5769 if (LocaleCompare(keyword,"geometry") == 0)
5770 {
5771 flags=ParseRegionGeometry(msl_info->image[n],value,
5772 &geometry,&exception);
5773 break;
5774 }
5775 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5776 keyword);
5777 break;
5778 }
5779 case 'H':
5780 case 'h':
5781 {
5782 if (LocaleCompare(keyword,"height") == 0)
5783 {
cristye27293e2009-12-18 02:53:20 +00005784 geometry.height=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005785 break;
5786 }
5787 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5788 keyword);
5789 break;
5790 }
5791 case 'W':
5792 case 'w':
5793 {
5794 if (LocaleCompare(keyword,"width") == 0)
5795 {
cristyf2f27272009-12-17 14:48:46 +00005796 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005797 break;
5798 }
5799 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5800 keyword);
5801 break;
5802 }
5803 default:
5804 {
5805 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5806 keyword);
5807 break;
5808 }
5809 }
5810 }
5811 sample_image=SampleImage(msl_info->image[n],geometry.width,
5812 geometry.height,&msl_info->image[n]->exception);
5813 if (sample_image == (Image *) NULL)
5814 break;
5815 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5816 msl_info->image[n]=sample_image;
5817 break;
5818 }
cristyb988fe72009-09-16 01:01:10 +00005819 if (LocaleCompare((const char *) tag,"scale") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005820 {
5821 Image
5822 *scale_image;
5823
5824 /*
5825 Scale image.
5826 */
5827 if (msl_info->image[n] == (Image *) NULL)
5828 {
cristyb988fe72009-09-16 01:01:10 +00005829 ThrowMSLException(OptionError,"NoImagesDefined",
5830 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005831 break;
5832 }
5833 if (attributes != (const xmlChar **) NULL)
5834 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5835 {
5836 keyword=(const char *) attributes[i++];
5837 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005838 msl_info->attributes[n],(const char *) attributes[i],
5839 &exception);
cristy3ed852e2009-09-05 21:47:34 +00005840 CloneString(&value,attribute);
5841 switch (*keyword)
5842 {
5843 case 'G':
5844 case 'g':
5845 {
5846 if (LocaleCompare(keyword,"geometry") == 0)
5847 {
5848 flags=ParseRegionGeometry(msl_info->image[n],value,
5849 &geometry,&exception);
5850 break;
5851 }
5852 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5853 keyword);
5854 break;
5855 }
5856 case 'H':
5857 case 'h':
5858 {
5859 if (LocaleCompare(keyword,"height") == 0)
5860 {
cristye27293e2009-12-18 02:53:20 +00005861 geometry.height=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005862 break;
5863 }
5864 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5865 keyword);
5866 break;
5867 }
5868 case 'W':
5869 case 'w':
5870 {
5871 if (LocaleCompare(keyword,"width") == 0)
5872 {
cristyf2f27272009-12-17 14:48:46 +00005873 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005874 break;
5875 }
5876 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5877 keyword);
5878 break;
5879 }
5880 default:
5881 {
5882 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5883 keyword);
5884 break;
5885 }
5886 }
5887 }
5888 scale_image=ScaleImage(msl_info->image[n],geometry.width,
5889 geometry.height,&msl_info->image[n]->exception);
5890 if (scale_image == (Image *) NULL)
5891 break;
5892 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5893 msl_info->image[n]=scale_image;
5894 break;
5895 }
cristyb988fe72009-09-16 01:01:10 +00005896 if (LocaleCompare((const char *) tag,"segment") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005897 {
5898 ColorspaceType
5899 colorspace;
5900
5901 MagickBooleanType
5902 verbose;
cristyb988fe72009-09-16 01:01:10 +00005903
cristy3ed852e2009-09-05 21:47:34 +00005904 /*
5905 Segment image.
5906 */
5907 if (msl_info->image[n] == (Image *) NULL)
5908 {
cristyb988fe72009-09-16 01:01:10 +00005909 ThrowMSLException(OptionError,"NoImagesDefined",
5910 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005911 break;
5912 }
5913 geometry_info.rho=1.0;
5914 geometry_info.sigma=1.5;
5915 colorspace=RGBColorspace;
5916 verbose=MagickFalse;
5917 if (attributes != (const xmlChar **) NULL)
5918 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5919 {
5920 keyword=(const char *) attributes[i++];
5921 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005922 msl_info->attributes[n],(const char *) attributes[i],
5923 &exception);
cristy3ed852e2009-09-05 21:47:34 +00005924 CloneString(&value,attribute);
5925 switch (*keyword)
5926 {
5927 case 'C':
5928 case 'c':
5929 {
5930 if (LocaleCompare(keyword,"cluster-threshold") == 0)
5931 {
cristyc1acd842011-05-19 23:05:47 +00005932 geometry_info.rho=InterpretLocaleValue(value,
5933 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005934 break;
5935 }
5936 if (LocaleCompare(keyword,"colorspace") == 0)
5937 {
cristy042ee782011-04-22 18:48:30 +00005938 option=ParseCommandOption(MagickColorspaceOptions,
cristy3ed852e2009-09-05 21:47:34 +00005939 MagickFalse,value);
5940 if (option < 0)
5941 ThrowMSLException(OptionError,
5942 "UnrecognizedColorspaceType",value);
5943 colorspace=(ColorspaceType) option;
5944 break;
5945 }
5946 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5947 keyword);
5948 break;
5949 }
5950 case 'G':
5951 case 'g':
5952 {
5953 if (LocaleCompare(keyword,"geometry") == 0)
5954 {
5955 flags=ParseGeometry(value,&geometry_info);
5956 if ((flags & SigmaValue) == 0)
5957 geometry_info.sigma=1.5;
5958 break;
5959 }
5960 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5961 keyword);
5962 break;
5963 }
5964 case 'S':
5965 case 's':
5966 {
5967 if (LocaleCompare(keyword,"smoothing-threshold") == 0)
5968 {
cristyc1acd842011-05-19 23:05:47 +00005969 geometry_info.sigma=InterpretLocaleValue(value,
5970 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005971 break;
5972 }
5973 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5974 keyword);
5975 break;
5976 }
5977 default:
5978 {
5979 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5980 keyword);
5981 break;
5982 }
5983 }
5984 }
5985 (void) SegmentImage(msl_info->image[n],colorspace,verbose,
cristy018f07f2011-09-04 21:15:19 +00005986 geometry_info.rho,geometry_info.sigma,&exception);
cristy3ed852e2009-09-05 21:47:34 +00005987 break;
5988 }
cristyb988fe72009-09-16 01:01:10 +00005989 else if (LocaleCompare((const char *) tag, "set") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005990 {
5991 if (msl_info->image[n] == (Image *) NULL)
5992 {
cristy0b6d0052011-07-27 23:54:16 +00005993 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005994 break;
5995 }
5996
5997 if (attributes == (const xmlChar **) NULL)
5998 break;
5999 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6000 {
6001 keyword=(const char *) attributes[i++];
6002 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006003 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00006004 switch (*keyword)
6005 {
cristy3ed852e2009-09-05 21:47:34 +00006006 case 'C':
6007 case 'c':
6008 {
6009 if (LocaleCompare(keyword,"clip-mask") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006010 {
cristy2c8b6312009-09-16 02:37:23 +00006011 for (j=0; j < msl_info->n; j++)
cristy3ed852e2009-09-05 21:47:34 +00006012 {
cristy2c8b6312009-09-16 02:37:23 +00006013 const char
6014 *property;
6015
6016 property=GetImageProperty(msl_info->attributes[j],"id");
6017 if (LocaleCompare(property,value) == 0)
6018 {
cristy018f07f2011-09-04 21:15:19 +00006019 SetImageMask(msl_info->image[n],msl_info->image[j],
6020 &exception);
cristy2c8b6312009-09-16 02:37:23 +00006021 break;
6022 }
cristy3ed852e2009-09-05 21:47:34 +00006023 }
cristy2c8b6312009-09-16 02:37:23 +00006024 break;
cristy3ed852e2009-09-05 21:47:34 +00006025 }
cristy3ed852e2009-09-05 21:47:34 +00006026 if (LocaleCompare(keyword,"clip-path") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006027 {
cristy2c8b6312009-09-16 02:37:23 +00006028 for (j=0; j < msl_info->n; j++)
cristy3ed852e2009-09-05 21:47:34 +00006029 {
cristy2c8b6312009-09-16 02:37:23 +00006030 const char
6031 *property;
6032
6033 property=GetImageProperty(msl_info->attributes[j],"id");
6034 if (LocaleCompare(property,value) == 0)
6035 {
cristy018f07f2011-09-04 21:15:19 +00006036 SetImageClipMask(msl_info->image[n],msl_info->image[j],
6037 &exception);
cristy2c8b6312009-09-16 02:37:23 +00006038 break;
6039 }
cristy3ed852e2009-09-05 21:47:34 +00006040 }
cristy2c8b6312009-09-16 02:37:23 +00006041 break;
cristy3ed852e2009-09-05 21:47:34 +00006042 }
cristy2c8b6312009-09-16 02:37:23 +00006043 if (LocaleCompare(keyword,"colorspace") == 0)
6044 {
cristybb503372010-05-27 20:51:26 +00006045 ssize_t
cristy2c8b6312009-09-16 02:37:23 +00006046 colorspace;
6047
cristy042ee782011-04-22 18:48:30 +00006048 colorspace=(ColorspaceType) ParseCommandOption(
cristy7e9e6fa2010-11-21 17:06:24 +00006049 MagickColorspaceOptions,MagickFalse,value);
cristy2c8b6312009-09-16 02:37:23 +00006050 if (colorspace < 0)
cristyfb758a52009-09-16 14:36:08 +00006051 ThrowMSLException(OptionError,"UnrecognizedColorspace",
cristy2c8b6312009-09-16 02:37:23 +00006052 value);
6053 (void) TransformImageColorspace(msl_info->image[n],
6054 (ColorspaceType) colorspace);
6055 break;
6056 }
6057 (void) SetMSLAttributes(msl_info,keyword,value);
cristy0b6d0052011-07-27 23:54:16 +00006058 (void) SetImageProperty(msl_info->image[n],keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00006059 break;
6060 }
6061 case 'D':
6062 case 'd':
6063 {
cristy2c8b6312009-09-16 02:37:23 +00006064 if (LocaleCompare(keyword,"density") == 0)
6065 {
6066 flags=ParseGeometry(value,&geometry_info);
6067 msl_info->image[n]->x_resolution=geometry_info.rho;
6068 msl_info->image[n]->y_resolution=geometry_info.sigma;
6069 if ((flags & SigmaValue) == 0)
6070 msl_info->image[n]->y_resolution=
6071 msl_info->image[n]->x_resolution;
6072 break;
6073 }
6074 (void) SetMSLAttributes(msl_info,keyword,value);
cristy0b6d0052011-07-27 23:54:16 +00006075 (void) SetImageProperty(msl_info->image[n],keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00006076 break;
6077 }
6078 case 'O':
6079 case 'o':
6080 {
6081 if (LocaleCompare(keyword, "opacity") == 0)
cristy2c8b6312009-09-16 02:37:23 +00006082 {
cristy4c08aed2011-07-01 19:47:50 +00006083 ssize_t opac = OpaqueAlpha,
cristybb503372010-05-27 20:51:26 +00006084 len = (ssize_t) strlen( value );
cristy3ed852e2009-09-05 21:47:34 +00006085
cristy2c8b6312009-09-16 02:37:23 +00006086 if (value[len-1] == '%') {
6087 char tmp[100];
6088 (void) CopyMagickString(tmp,value,len);
cristyf2f27272009-12-17 14:48:46 +00006089 opac = StringToLong( tmp );
cristy2c8b6312009-09-16 02:37:23 +00006090 opac = (int)(QuantumRange * ((float)opac/100));
6091 } else
cristyf2f27272009-12-17 14:48:46 +00006092 opac = StringToLong( value );
cristy2c8b6312009-09-16 02:37:23 +00006093 (void) SetImageOpacity( msl_info->image[n], (Quantum) opac );
6094 break;
cristy3ed852e2009-09-05 21:47:34 +00006095 }
cristy2c8b6312009-09-16 02:37:23 +00006096 (void) SetMSLAttributes(msl_info,keyword,value);
cristy0b6d0052011-07-27 23:54:16 +00006097 (void) SetImageProperty(msl_info->image[n],keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00006098 break;
6099 }
6100 case 'P':
6101 case 'p':
6102 {
6103 if (LocaleCompare(keyword, "page") == 0)
6104 {
6105 char
6106 page[MaxTextExtent];
6107
6108 const char
6109 *image_option;
6110
6111 MagickStatusType
6112 flags;
6113
6114 RectangleInfo
6115 geometry;
6116
6117 (void) ResetMagickMemory(&geometry,0,sizeof(geometry));
6118 image_option=GetImageOption(msl_info->image_info[n],"page");
6119 if (image_option != (const char *) NULL)
6120 flags=ParseAbsoluteGeometry(image_option,&geometry);
6121 flags=ParseAbsoluteGeometry(value,&geometry);
cristyb51dff52011-05-19 16:55:47 +00006122 (void) FormatLocaleString(page,MaxTextExtent,"%.20gx%.20g",
cristye8c25f92010-06-03 00:53:06 +00006123 (double) geometry.width,(double) geometry.height);
cristy3ed852e2009-09-05 21:47:34 +00006124 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
cristyb51dff52011-05-19 16:55:47 +00006125 (void) FormatLocaleString(page,MaxTextExtent,
cristye8c25f92010-06-03 00:53:06 +00006126 "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,
6127 (double) geometry.height,(double) geometry.x,(double)
cristyf2faecf2010-05-28 19:19:36 +00006128 geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00006129 (void) SetImageOption(msl_info->image_info[n],keyword,page);
6130 msl_info->image_info[n]->page=GetPageGeometry(page);
6131 break;
6132 }
cristy2c8b6312009-09-16 02:37:23 +00006133 (void) SetMSLAttributes(msl_info,keyword,value);
cristy0b6d0052011-07-27 23:54:16 +00006134 (void) SetImageProperty(msl_info->image[n],keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00006135 break;
6136 }
6137 default:
6138 {
cristy2c8b6312009-09-16 02:37:23 +00006139 (void) SetMSLAttributes(msl_info,keyword,value);
cristy0b6d0052011-07-27 23:54:16 +00006140 (void) SetImageProperty(msl_info->image[n],keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00006141 break;
6142 }
6143 }
6144 }
6145 break;
6146 }
cristyb988fe72009-09-16 01:01:10 +00006147 if (LocaleCompare((const char *) tag,"shade") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006148 {
6149 Image
6150 *shade_image;
6151
6152 MagickBooleanType
6153 gray;
6154
6155 /*
6156 Shade image.
6157 */
6158 if (msl_info->image[n] == (Image *) NULL)
6159 {
cristyb988fe72009-09-16 01:01:10 +00006160 ThrowMSLException(OptionError,"NoImagesDefined",
6161 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006162 break;
6163 }
6164 gray=MagickFalse;
6165 if (attributes != (const xmlChar **) NULL)
6166 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6167 {
6168 keyword=(const char *) attributes[i++];
6169 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006170 msl_info->attributes[n],(const char *) attributes[i],
6171 &exception);
cristy3ed852e2009-09-05 21:47:34 +00006172 CloneString(&value,attribute);
6173 switch (*keyword)
6174 {
6175 case 'A':
6176 case 'a':
6177 {
6178 if (LocaleCompare(keyword,"azimuth") == 0)
6179 {
cristyc1acd842011-05-19 23:05:47 +00006180 geometry_info.rho=InterpretLocaleValue(value,
6181 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006182 break;
6183 }
6184 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6185 keyword);
6186 break;
6187 }
6188 case 'E':
6189 case 'e':
6190 {
6191 if (LocaleCompare(keyword,"elevation") == 0)
6192 {
cristyc1acd842011-05-19 23:05:47 +00006193 geometry_info.sigma=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 'G':
6202 case 'g':
6203 {
6204 if (LocaleCompare(keyword,"geometry") == 0)
6205 {
6206 flags=ParseGeometry(value,&geometry_info);
6207 if ((flags & SigmaValue) == 0)
6208 geometry_info.sigma=1.0;
6209 break;
6210 }
6211 if (LocaleCompare(keyword,"gray") == 0)
6212 {
cristy042ee782011-04-22 18:48:30 +00006213 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00006214 value);
6215 if (option < 0)
6216 ThrowMSLException(OptionError,"UnrecognizedNoiseType",
6217 value);
6218 gray=(MagickBooleanType) option;
6219 break;
6220 }
6221 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6222 keyword);
6223 break;
6224 }
6225 default:
6226 {
6227 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6228 keyword);
6229 break;
6230 }
6231 }
6232 }
6233 shade_image=ShadeImage(msl_info->image[n],gray,geometry_info.rho,
6234 geometry_info.sigma,&msl_info->image[n]->exception);
6235 if (shade_image == (Image *) NULL)
6236 break;
6237 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6238 msl_info->image[n]=shade_image;
6239 break;
6240 }
cristyb988fe72009-09-16 01:01:10 +00006241 if (LocaleCompare((const char *) tag,"shadow") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006242 {
6243 Image
6244 *shadow_image;
6245
6246 /*
6247 Shear image.
6248 */
6249 if (msl_info->image[n] == (Image *) NULL)
6250 {
cristyb988fe72009-09-16 01:01:10 +00006251 ThrowMSLException(OptionError,"NoImagesDefined",
6252 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006253 break;
6254 }
6255 if (attributes != (const xmlChar **) NULL)
6256 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6257 {
6258 keyword=(const char *) attributes[i++];
6259 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006260 msl_info->attributes[n],(const char *) attributes[i],
6261 &exception);
cristy3ed852e2009-09-05 21:47:34 +00006262 CloneString(&value,attribute);
6263 switch (*keyword)
6264 {
6265 case 'G':
6266 case 'g':
6267 {
6268 if (LocaleCompare(keyword,"geometry") == 0)
6269 {
6270 flags=ParseGeometry(value,&geometry_info);
6271 if ((flags & SigmaValue) == 0)
6272 geometry_info.sigma=1.0;
6273 break;
6274 }
6275 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6276 keyword);
6277 break;
6278 }
6279 case 'O':
6280 case 'o':
6281 {
6282 if (LocaleCompare(keyword,"opacity") == 0)
6283 {
cristyf2f27272009-12-17 14:48:46 +00006284 geometry_info.rho=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006285 break;
6286 }
6287 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6288 keyword);
6289 break;
6290 }
6291 case 'S':
6292 case 's':
6293 {
6294 if (LocaleCompare(keyword,"sigma") == 0)
6295 {
cristyf2f27272009-12-17 14:48:46 +00006296 geometry_info.sigma=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006297 break;
6298 }
6299 break;
6300 }
6301 case 'X':
6302 case 'x':
6303 {
6304 if (LocaleCompare(keyword,"x") == 0)
6305 {
cristyc1acd842011-05-19 23:05:47 +00006306 geometry_info.xi=InterpretLocaleValue(value,
6307 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006308 break;
6309 }
6310 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6311 keyword);
6312 break;
6313 }
6314 case 'Y':
6315 case 'y':
6316 {
6317 if (LocaleCompare(keyword,"y") == 0)
6318 {
cristyf2f27272009-12-17 14:48:46 +00006319 geometry_info.psi=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006320 break;
6321 }
6322 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6323 keyword);
6324 break;
6325 }
6326 default:
6327 {
6328 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6329 keyword);
6330 break;
6331 }
6332 }
6333 }
6334 shadow_image=ShadowImage(msl_info->image[n],geometry_info.rho,
cristybb503372010-05-27 20:51:26 +00006335 geometry_info.sigma,(ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
cristy0534a6b2010-03-18 01:19:38 +00006336 ceil(geometry_info.psi-0.5),&msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00006337 if (shadow_image == (Image *) NULL)
6338 break;
6339 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6340 msl_info->image[n]=shadow_image;
6341 break;
6342 }
cristyb988fe72009-09-16 01:01:10 +00006343 if (LocaleCompare((const char *) tag,"sharpen") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006344 {
6345 double radius = 0.0,
6346 sigma = 1.0;
6347
6348 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00006349 {
6350 ThrowMSLException(OptionError,"NoImagesDefined",
6351 (const char *) tag);
6352 break;
6353 }
cristy3ed852e2009-09-05 21:47:34 +00006354 /*
6355 NOTE: sharpen can have no attributes, since we use all the defaults!
6356 */
6357 if (attributes != (const xmlChar **) NULL)
6358 {
6359 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6360 {
6361 keyword=(const char *) attributes[i++];
6362 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006363 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00006364 switch (*keyword)
6365 {
6366 case 'R':
6367 case 'r':
6368 {
6369 if (LocaleCompare(keyword, "radius") == 0)
6370 {
cristyc1acd842011-05-19 23:05:47 +00006371 radius = InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006372 break;
6373 }
6374 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6375 break;
6376 }
6377 case 'S':
6378 case 's':
6379 {
6380 if (LocaleCompare(keyword,"sigma") == 0)
6381 {
cristyf2f27272009-12-17 14:48:46 +00006382 sigma = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00006383 break;
6384 }
6385 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6386 break;
6387 }
6388 default:
6389 {
6390 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6391 break;
6392 }
6393 }
6394 }
6395 }
6396
6397 /*
6398 sharpen image.
6399 */
6400 {
6401 Image
6402 *newImage;
6403
6404 newImage=SharpenImage(msl_info->image[n],radius,sigma,&msl_info->image[n]->exception);
6405 if (newImage == (Image *) NULL)
6406 break;
6407 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6408 msl_info->image[n]=newImage;
6409 break;
6410 }
6411 }
cristyb988fe72009-09-16 01:01:10 +00006412 else if (LocaleCompare((const char *) tag,"shave") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006413 {
6414 /* init the values */
6415 width = height = 0;
6416 x = y = 0;
6417
6418 if (msl_info->image[n] == (Image *) NULL)
6419 {
cristyb988fe72009-09-16 01:01:10 +00006420 ThrowMSLException(OptionError,"NoImagesDefined",
6421 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006422 break;
6423 }
6424 if (attributes == (const xmlChar **) NULL)
6425 break;
6426 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6427 {
6428 keyword=(const char *) attributes[i++];
6429 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006430 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00006431 switch (*keyword)
6432 {
6433 case 'G':
6434 case 'g':
6435 {
6436 if (LocaleCompare(keyword,"geometry") == 0)
6437 {
6438 (void) ParseMetaGeometry(value,&x,&y,&width,&height);
6439 break;
6440 }
6441 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6442 break;
6443 }
6444 case 'H':
6445 case 'h':
6446 {
6447 if (LocaleCompare(keyword,"height") == 0)
6448 {
cristyf2f27272009-12-17 14:48:46 +00006449 height = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00006450 break;
6451 }
6452 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6453 break;
6454 }
6455 case 'W':
6456 case 'w':
6457 {
6458 if (LocaleCompare(keyword,"width") == 0)
6459 {
cristyf2f27272009-12-17 14:48:46 +00006460 width = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00006461 break;
6462 }
6463 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6464 break;
6465 }
6466 default:
6467 {
6468 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6469 break;
6470 }
6471 }
6472 }
6473
6474 /*
6475 process image.
6476 */
6477 {
6478 Image
6479 *newImage;
6480 RectangleInfo
6481 rectInfo;
6482
6483 rectInfo.height = height;
6484 rectInfo.width = width;
6485 rectInfo.x = x;
6486 rectInfo.y = y;
6487
6488
6489 newImage=ShaveImage(msl_info->image[n], &rectInfo,
6490 &msl_info->image[n]->exception);
6491 if (newImage == (Image *) NULL)
6492 break;
6493 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6494 msl_info->image[n]=newImage;
6495 }
6496
6497 break;
6498 }
cristyb988fe72009-09-16 01:01:10 +00006499 if (LocaleCompare((const char *) tag,"shear") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006500 {
6501 Image
6502 *shear_image;
6503
6504 /*
6505 Shear image.
6506 */
6507 if (msl_info->image[n] == (Image *) NULL)
6508 {
cristyb988fe72009-09-16 01:01:10 +00006509 ThrowMSLException(OptionError,"NoImagesDefined",
6510 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006511 break;
6512 }
6513 if (attributes != (const xmlChar **) NULL)
6514 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6515 {
6516 keyword=(const char *) attributes[i++];
6517 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006518 msl_info->attributes[n],(const char *) attributes[i],
6519 &exception);
cristy3ed852e2009-09-05 21:47:34 +00006520 CloneString(&value,attribute);
6521 switch (*keyword)
6522 {
6523 case 'F':
6524 case 'f':
6525 {
6526 if (LocaleCompare(keyword, "fill") == 0)
6527 {
6528 (void) QueryColorDatabase(value,
6529 &msl_info->image[n]->background_color,&exception);
6530 break;
6531 }
6532 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6533 keyword);
6534 break;
6535 }
6536 case 'G':
6537 case 'g':
6538 {
6539 if (LocaleCompare(keyword,"geometry") == 0)
6540 {
6541 flags=ParseGeometry(value,&geometry_info);
6542 if ((flags & SigmaValue) == 0)
6543 geometry_info.sigma=1.0;
6544 break;
6545 }
6546 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6547 keyword);
6548 break;
6549 }
6550 case 'X':
6551 case 'x':
6552 {
6553 if (LocaleCompare(keyword,"x") == 0)
6554 {
cristyc1acd842011-05-19 23:05:47 +00006555 geometry_info.rho=InterpretLocaleValue(value,
6556 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006557 break;
6558 }
6559 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6560 keyword);
6561 break;
6562 }
6563 case 'Y':
6564 case 'y':
6565 {
6566 if (LocaleCompare(keyword,"y") == 0)
6567 {
cristyf2f27272009-12-17 14:48:46 +00006568 geometry_info.sigma=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006569 break;
6570 }
6571 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6572 keyword);
6573 break;
6574 }
6575 default:
6576 {
6577 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6578 keyword);
6579 break;
6580 }
6581 }
6582 }
6583 shear_image=ShearImage(msl_info->image[n],geometry_info.rho,
6584 geometry_info.sigma,&msl_info->image[n]->exception);
6585 if (shear_image == (Image *) NULL)
6586 break;
6587 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6588 msl_info->image[n]=shear_image;
6589 break;
6590 }
cristyb988fe72009-09-16 01:01:10 +00006591 if (LocaleCompare((const char *) tag,"signature") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006592 {
6593 /*
6594 Signature image.
6595 */
6596 if (msl_info->image[n] == (Image *) NULL)
6597 {
cristyb988fe72009-09-16 01:01:10 +00006598 ThrowMSLException(OptionError,"NoImagesDefined",
6599 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006600 break;
6601 }
6602 if (attributes != (const xmlChar **) NULL)
6603 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6604 {
6605 keyword=(const char *) attributes[i++];
6606 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006607 msl_info->attributes[n],(const char *) attributes[i],
6608 &exception);
cristy3ed852e2009-09-05 21:47:34 +00006609 CloneString(&value,attribute);
6610 switch (*keyword)
6611 {
6612 default:
6613 {
6614 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6615 keyword);
6616 break;
6617 }
6618 }
6619 }
cristy018f07f2011-09-04 21:15:19 +00006620 (void) SignatureImage(msl_info->image[n],&exception);
cristy3ed852e2009-09-05 21:47:34 +00006621 break;
6622 }
cristyb988fe72009-09-16 01:01:10 +00006623 if (LocaleCompare((const char *) tag,"solarize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006624 {
6625 /*
6626 Solarize image.
6627 */
6628 if (msl_info->image[n] == (Image *) NULL)
6629 {
cristyb988fe72009-09-16 01:01:10 +00006630 ThrowMSLException(OptionError,"NoImagesDefined",
6631 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006632 break;
6633 }
6634 geometry_info.rho=QuantumRange/2.0;
6635 if (attributes != (const xmlChar **) NULL)
6636 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6637 {
6638 keyword=(const char *) attributes[i++];
6639 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006640 msl_info->attributes[n],(const char *) attributes[i],
6641 &exception);
cristy3ed852e2009-09-05 21:47:34 +00006642 CloneString(&value,attribute);
6643 switch (*keyword)
6644 {
6645 case 'G':
6646 case 'g':
6647 {
6648 if (LocaleCompare(keyword,"geometry") == 0)
6649 {
6650 flags=ParseGeometry(value,&geometry_info);
6651 break;
6652 }
6653 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6654 keyword);
6655 break;
6656 }
6657 case 'T':
6658 case 't':
6659 {
6660 if (LocaleCompare(keyword,"threshold") == 0)
6661 {
cristyc1acd842011-05-19 23:05:47 +00006662 geometry_info.rho=InterpretLocaleValue(value,
6663 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006664 break;
6665 }
6666 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6667 keyword);
6668 break;
6669 }
6670 default:
6671 {
6672 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6673 keyword);
6674 break;
6675 }
6676 }
6677 }
cristy5cbc0162011-08-29 00:36:28 +00006678 (void) SolarizeImage(msl_info->image[n],geometry_info.rho,
6679 &msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00006680 break;
6681 }
cristyb988fe72009-09-16 01:01:10 +00006682 if (LocaleCompare((const char *) tag,"spread") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006683 {
6684 Image
6685 *spread_image;
6686
6687 /*
6688 Spread image.
6689 */
6690 if (msl_info->image[n] == (Image *) NULL)
6691 {
cristyb988fe72009-09-16 01:01:10 +00006692 ThrowMSLException(OptionError,"NoImagesDefined",
6693 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006694 break;
6695 }
6696 if (attributes != (const xmlChar **) NULL)
6697 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6698 {
6699 keyword=(const char *) attributes[i++];
6700 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006701 msl_info->attributes[n],(const char *) attributes[i],
6702 &exception);
cristy3ed852e2009-09-05 21:47:34 +00006703 CloneString(&value,attribute);
6704 switch (*keyword)
6705 {
6706 case 'G':
6707 case 'g':
6708 {
6709 if (LocaleCompare(keyword,"geometry") == 0)
6710 {
6711 flags=ParseGeometry(value,&geometry_info);
6712 if ((flags & SigmaValue) == 0)
6713 geometry_info.sigma=1.0;
6714 break;
6715 }
6716 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6717 keyword);
6718 break;
6719 }
6720 case 'R':
6721 case 'r':
6722 {
6723 if (LocaleCompare(keyword,"radius") == 0)
6724 {
cristyc1acd842011-05-19 23:05:47 +00006725 geometry_info.rho=InterpretLocaleValue(value,
6726 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006727 break;
6728 }
6729 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6730 keyword);
6731 break;
6732 }
6733 default:
6734 {
6735 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6736 keyword);
6737 break;
6738 }
6739 }
6740 }
6741 spread_image=SpreadImage(msl_info->image[n],geometry_info.rho,
6742 &msl_info->image[n]->exception);
6743 if (spread_image == (Image *) NULL)
6744 break;
6745 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6746 msl_info->image[n]=spread_image;
6747 break;
6748 }
cristyb988fe72009-09-16 01:01:10 +00006749 else if (LocaleCompare((const char *) tag,"stegano") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006750 {
6751 Image *
6752 watermark = (Image*)NULL;
6753
6754 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00006755 {
6756 ThrowMSLException(OptionError,"NoImagesDefined",
6757 (const char *) tag);
6758 break;
6759 }
cristy3ed852e2009-09-05 21:47:34 +00006760 if (attributes == (const xmlChar **) NULL)
6761 break;
6762 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6763 {
6764 keyword=(const char *) attributes[i++];
6765 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006766 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00006767 switch (*keyword)
6768 {
6769 case 'I':
6770 case 'i':
6771 {
6772 if (LocaleCompare(keyword,"image") == 0)
6773 {
6774 for (j=0; j<msl_info->n;j++)
6775 {
6776 const char *
6777 theAttr = GetImageProperty(msl_info->attributes[j], "id");
6778 if (theAttr && LocaleCompare(theAttr, value) == 0)
6779 {
6780 watermark = msl_info->image[j];
6781 break;
6782 }
6783 }
6784 break;
6785 }
6786 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6787 break;
6788 }
6789 default:
6790 {
6791 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6792 break;
6793 }
6794 }
6795 }
6796
6797 /*
6798 process image.
6799 */
6800 if ( watermark != (Image*) NULL )
6801 {
6802 Image
6803 *newImage;
6804
6805 newImage=SteganoImage(msl_info->image[n], watermark, &msl_info->image[n]->exception);
6806 if (newImage == (Image *) NULL)
6807 break;
6808 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6809 msl_info->image[n]=newImage;
6810 break;
6811 } else
6812 ThrowMSLException(OptionError,"MissingWatermarkImage",keyword);
6813 }
cristyb988fe72009-09-16 01:01:10 +00006814 else if (LocaleCompare((const char *) tag,"stereo") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006815 {
6816 Image *
6817 stereoImage = (Image*)NULL;
6818
6819 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00006820 {
6821 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
6822 break;
6823 }
cristy3ed852e2009-09-05 21:47:34 +00006824 if (attributes == (const xmlChar **) NULL)
6825 break;
6826 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6827 {
6828 keyword=(const char *) attributes[i++];
6829 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006830 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00006831 switch (*keyword)
6832 {
6833 case 'I':
6834 case 'i':
6835 {
6836 if (LocaleCompare(keyword,"image") == 0)
6837 {
6838 for (j=0; j<msl_info->n;j++)
6839 {
6840 const char *
6841 theAttr = GetImageProperty(msl_info->attributes[j], "id");
6842 if (theAttr && LocaleCompare(theAttr, value) == 0)
6843 {
6844 stereoImage = msl_info->image[j];
6845 break;
6846 }
6847 }
6848 break;
6849 }
6850 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6851 break;
6852 }
6853 default:
6854 {
6855 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6856 break;
6857 }
6858 }
6859 }
6860
6861 /*
6862 process image.
6863 */
6864 if ( stereoImage != (Image*) NULL )
6865 {
6866 Image
6867 *newImage;
6868
6869 newImage=StereoImage(msl_info->image[n], stereoImage, &msl_info->image[n]->exception);
6870 if (newImage == (Image *) NULL)
6871 break;
6872 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6873 msl_info->image[n]=newImage;
6874 break;
6875 } else
6876 ThrowMSLException(OptionError,"Missing stereo image",keyword);
6877 }
cristyb988fe72009-09-16 01:01:10 +00006878 if (LocaleCompare((const char *) tag,"swap") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006879 {
6880 Image
6881 *p,
6882 *q,
6883 *swap;
6884
cristybb503372010-05-27 20:51:26 +00006885 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00006886 index,
6887 swap_index;
6888
6889 if (msl_info->image[n] == (Image *) NULL)
6890 {
cristyb988fe72009-09-16 01:01:10 +00006891 ThrowMSLException(OptionError,"NoImagesDefined",
6892 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006893 break;
6894 }
6895 index=(-1);
6896 swap_index=(-2);
6897 if (attributes != (const xmlChar **) NULL)
6898 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6899 {
6900 keyword=(const char *) attributes[i++];
6901 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006902 msl_info->attributes[n],(const char *) attributes[i],
6903 &exception);
cristy3ed852e2009-09-05 21:47:34 +00006904 CloneString(&value,attribute);
6905 switch (*keyword)
6906 {
6907 case 'G':
6908 case 'g':
6909 {
6910 if (LocaleCompare(keyword,"indexes") == 0)
6911 {
6912 flags=ParseGeometry(value,&geometry_info);
cristybb503372010-05-27 20:51:26 +00006913 index=(ssize_t) geometry_info.rho;
cristy3ed852e2009-09-05 21:47:34 +00006914 if ((flags & SigmaValue) == 0)
cristybb503372010-05-27 20:51:26 +00006915 swap_index=(ssize_t) geometry_info.sigma;
cristy3ed852e2009-09-05 21:47:34 +00006916 break;
6917 }
6918 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6919 keyword);
6920 break;
6921 }
6922 default:
6923 {
6924 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6925 keyword);
6926 break;
6927 }
6928 }
6929 }
6930 /*
6931 Swap images.
6932 */
6933 p=GetImageFromList(msl_info->image[n],index);
6934 q=GetImageFromList(msl_info->image[n],swap_index);
6935 if ((p == (Image *) NULL) || (q == (Image *) NULL))
6936 {
cristyb988fe72009-09-16 01:01:10 +00006937 ThrowMSLException(OptionError,"NoSuchImage",(const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006938 break;
6939 }
6940 swap=CloneImage(p,0,0,MagickTrue,&p->exception);
6941 ReplaceImageInList(&p,CloneImage(q,0,0,MagickTrue,&q->exception));
6942 ReplaceImageInList(&q,swap);
6943 msl_info->image[n]=GetFirstImageInList(q);
6944 break;
6945 }
cristyb988fe72009-09-16 01:01:10 +00006946 if (LocaleCompare((const char *) tag,"swirl") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006947 {
6948 Image
6949 *swirl_image;
6950
6951 /*
6952 Swirl image.
6953 */
6954 if (msl_info->image[n] == (Image *) NULL)
6955 {
cristyb988fe72009-09-16 01:01:10 +00006956 ThrowMSLException(OptionError,"NoImagesDefined",
6957 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006958 break;
6959 }
6960 if (attributes != (const xmlChar **) NULL)
6961 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6962 {
6963 keyword=(const char *) attributes[i++];
6964 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006965 msl_info->attributes[n],(const char *) attributes[i],
6966 &exception);
cristy3ed852e2009-09-05 21:47:34 +00006967 CloneString(&value,attribute);
6968 switch (*keyword)
6969 {
6970 case 'D':
6971 case 'd':
6972 {
6973 if (LocaleCompare(keyword,"degrees") == 0)
6974 {
cristyc1acd842011-05-19 23:05:47 +00006975 geometry_info.rho=InterpretLocaleValue(value,
6976 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006977 break;
6978 }
6979 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6980 keyword);
6981 break;
6982 }
6983 case 'G':
6984 case 'g':
6985 {
6986 if (LocaleCompare(keyword,"geometry") == 0)
6987 {
6988 flags=ParseGeometry(value,&geometry_info);
6989 if ((flags & SigmaValue) == 0)
6990 geometry_info.sigma=1.0;
6991 break;
6992 }
6993 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6994 keyword);
6995 break;
6996 }
6997 default:
6998 {
6999 ThrowMSLException(OptionError,"UnrecognizedAttribute",
7000 keyword);
7001 break;
7002 }
7003 }
7004 }
7005 swirl_image=SwirlImage(msl_info->image[n],geometry_info.rho,
7006 &msl_info->image[n]->exception);
7007 if (swirl_image == (Image *) NULL)
7008 break;
7009 msl_info->image[n]=DestroyImage(msl_info->image[n]);
7010 msl_info->image[n]=swirl_image;
7011 break;
7012 }
cristyb988fe72009-09-16 01:01:10 +00007013 if (LocaleCompare((const char *) tag,"sync") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007014 {
7015 /*
7016 Sync image.
7017 */
7018 if (msl_info->image[n] == (Image *) NULL)
7019 {
cristyb988fe72009-09-16 01:01:10 +00007020 ThrowMSLException(OptionError,"NoImagesDefined",
7021 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00007022 break;
7023 }
7024 if (attributes != (const xmlChar **) NULL)
7025 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7026 {
7027 keyword=(const char *) attributes[i++];
7028 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00007029 msl_info->attributes[n],(const char *) attributes[i],
7030 &exception);
cristy3ed852e2009-09-05 21:47:34 +00007031 CloneString(&value,attribute);
7032 switch (*keyword)
7033 {
7034 default:
7035 {
7036 ThrowMSLException(OptionError,"UnrecognizedAttribute",
7037 keyword);
7038 break;
7039 }
7040 }
7041 }
7042 (void) SyncImage(msl_info->image[n]);
7043 break;
7044 }
7045 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7046 }
7047 case 'T':
7048 case 't':
7049 {
cristyb988fe72009-09-16 01:01:10 +00007050 if (LocaleCompare((const char *) tag,"map") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007051 {
7052 Image
7053 *texture_image;
7054
7055 /*
7056 Texture image.
7057 */
7058 if (msl_info->image[n] == (Image *) NULL)
7059 {
cristyb988fe72009-09-16 01:01:10 +00007060 ThrowMSLException(OptionError,"NoImagesDefined",
7061 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00007062 break;
7063 }
7064 texture_image=NewImageList();
7065 if (attributes != (const xmlChar **) NULL)
7066 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7067 {
7068 keyword=(const char *) attributes[i++];
7069 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00007070 msl_info->attributes[n],(const char *) attributes[i],
7071 &exception);
cristy3ed852e2009-09-05 21:47:34 +00007072 CloneString(&value,attribute);
7073 switch (*keyword)
7074 {
7075 case 'I':
7076 case 'i':
7077 {
7078 if (LocaleCompare(keyword,"image") == 0)
7079 for (j=0; j < msl_info->n; j++)
7080 {
7081 const char
7082 *attribute;
cristyb988fe72009-09-16 01:01:10 +00007083
cristy3ed852e2009-09-05 21:47:34 +00007084 attribute=GetImageProperty(msl_info->attributes[j],"id");
7085 if ((attribute != (const char *) NULL) &&
7086 (LocaleCompare(attribute,value) == 0))
7087 {
7088 texture_image=CloneImage(msl_info->image[j],0,0,
7089 MagickFalse,&exception);
7090 break;
7091 }
7092 }
7093 break;
7094 }
7095 default:
7096 {
7097 ThrowMSLException(OptionError,"UnrecognizedAttribute",
7098 keyword);
7099 break;
7100 }
7101 }
7102 }
7103 (void) TextureImage(msl_info->image[n],texture_image);
7104 texture_image=DestroyImage(texture_image);
7105 break;
7106 }
cristyb988fe72009-09-16 01:01:10 +00007107 else if (LocaleCompare((const char *) tag,"threshold") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007108 {
7109 /* init the values */
7110 double threshold = 0;
7111
7112 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007113 {
7114 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7115 break;
7116 }
cristy3ed852e2009-09-05 21:47:34 +00007117 if (attributes == (const xmlChar **) NULL)
7118 break;
7119 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7120 {
7121 keyword=(const char *) attributes[i++];
7122 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00007123 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00007124 switch (*keyword)
7125 {
7126 case 'T':
7127 case 't':
7128 {
7129 if (LocaleCompare(keyword,"threshold") == 0)
7130 {
cristyc1acd842011-05-19 23:05:47 +00007131 threshold = InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00007132 break;
7133 }
7134 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7135 break;
7136 }
7137 default:
7138 {
7139 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7140 break;
7141 }
7142 }
7143 }
7144
7145 /*
7146 process image.
7147 */
7148 {
cristyf4ad9df2011-07-08 16:49:03 +00007149 BilevelImage(msl_info->image[n],threshold);
cristy3ed852e2009-09-05 21:47:34 +00007150 break;
7151 }
7152 }
cristyb988fe72009-09-16 01:01:10 +00007153 else if (LocaleCompare((const char *) tag, "transparent") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007154 {
7155 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007156 {
7157 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7158 break;
7159 }
cristy3ed852e2009-09-05 21:47:34 +00007160 if (attributes == (const xmlChar **) NULL)
7161 break;
7162 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7163 {
7164 keyword=(const char *) attributes[i++];
7165 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00007166 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00007167 switch (*keyword)
7168 {
7169 case 'C':
7170 case 'c':
7171 {
7172 if (LocaleCompare(keyword,"color") == 0)
7173 {
cristy4c08aed2011-07-01 19:47:50 +00007174 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00007175 target;
7176
7177 (void) QueryMagickColor(value,&target,&exception);
7178 (void) TransparentPaintImage(msl_info->image[n],&target,
cristy189e84c2011-08-27 18:08:53 +00007179 TransparentAlpha,MagickFalse,&msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00007180 break;
7181 }
7182 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7183 break;
7184 }
7185 default:
7186 {
7187 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7188 break;
7189 }
7190 }
7191 }
7192 break;
7193 }
cristyb988fe72009-09-16 01:01:10 +00007194 else if (LocaleCompare((const char *) tag, "trim") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007195 {
7196 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007197 {
7198 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7199 break;
7200 }
cristy3ed852e2009-09-05 21:47:34 +00007201
7202 /* no attributes here */
7203
7204 /* process the image */
7205 {
7206 Image
7207 *newImage;
7208 RectangleInfo
7209 rectInfo;
7210
7211 /* all zeros on a crop == trim edges! */
7212 rectInfo.height = rectInfo.width = 0;
7213 rectInfo.x = rectInfo.y = 0;
7214
7215 newImage=CropImage(msl_info->image[n],&rectInfo, &msl_info->image[n]->exception);
7216 if (newImage == (Image *) NULL)
7217 break;
7218 msl_info->image[n]=DestroyImage(msl_info->image[n]);
7219 msl_info->image[n]=newImage;
7220 break;
7221 }
7222 }
7223 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7224 }
7225 case 'W':
7226 case 'w':
7227 {
cristyb988fe72009-09-16 01:01:10 +00007228 if (LocaleCompare((const char *) tag,"write") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007229 {
7230 if (msl_info->image[n] == (Image *) NULL)
7231 {
cristyb988fe72009-09-16 01:01:10 +00007232 ThrowMSLException(OptionError,"NoImagesDefined",
7233 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00007234 break;
7235 }
7236 if (attributes == (const xmlChar **) NULL)
7237 break;
7238 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7239 {
7240 keyword=(const char *) attributes[i++];
7241 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00007242 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00007243 switch (*keyword)
7244 {
7245 case 'F':
7246 case 'f':
7247 {
7248 if (LocaleCompare(keyword,"filename") == 0)
7249 {
7250 (void) CopyMagickString(msl_info->image[n]->filename,value,
7251 MaxTextExtent);
7252 break;
7253 }
cristy4582cbb2009-09-23 00:35:43 +00007254 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00007255 }
7256 default:
7257 {
cristy4582cbb2009-09-23 00:35:43 +00007258 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00007259 break;
7260 }
7261 }
7262 }
7263
7264 /* process */
7265 {
cristy6f9e0d32011-08-28 16:32:09 +00007266 (void) WriteImage(msl_info->image_info[n], msl_info->image[n],
7267 &msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00007268 break;
7269 }
7270 }
7271 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7272 }
7273 default:
7274 {
7275 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7276 break;
7277 }
7278 }
7279 if ( value != NULL )
7280 value=DestroyString(value);
7281 (void) LogMagickEvent(CoderEvent,GetMagickModule()," )");
7282}
7283
7284static void MSLEndElement(void *context,const xmlChar *tag)
7285{
cristybb503372010-05-27 20:51:26 +00007286 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00007287 n;
7288
7289 MSLInfo
7290 *msl_info;
7291
7292 /*
7293 Called when the end of an element has been detected.
7294 */
7295 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.endElement(%s)",
7296 tag);
7297 msl_info=(MSLInfo *) context;
7298 n=msl_info->n;
7299 switch (*tag)
7300 {
7301 case 'C':
7302 case 'c':
7303 {
cristyb988fe72009-09-16 01:01:10 +00007304 if (LocaleCompare((const char *) tag,"comment") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007305 {
7306 (void) DeleteImageProperty(msl_info->image[n],"comment");
7307 if (msl_info->content == (char *) NULL)
7308 break;
7309 StripString(msl_info->content);
7310 (void) SetImageProperty(msl_info->image[n],"comment",
7311 msl_info->content);
7312 break;
7313 }
7314 break;
7315 }
7316 case 'G':
7317 case 'g':
7318 {
cristyb988fe72009-09-16 01:01:10 +00007319 if (LocaleCompare((const char *) tag, "group") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007320 {
7321 if (msl_info->group_info[msl_info->number_groups-1].numImages > 0 )
7322 {
cristybb503372010-05-27 20:51:26 +00007323 ssize_t i = (ssize_t)
cristy3ed852e2009-09-05 21:47:34 +00007324 (msl_info->group_info[msl_info->number_groups-1].numImages);
7325 while ( i-- )
7326 {
7327 if (msl_info->image[msl_info->n] != (Image *) NULL)
7328 msl_info->image[msl_info->n]=DestroyImage(msl_info->image[msl_info->n]);
7329 msl_info->attributes[msl_info->n]=DestroyImage(msl_info->attributes[msl_info->n]);
7330 msl_info->image_info[msl_info->n]=DestroyImageInfo(msl_info->image_info[msl_info->n]);
7331 msl_info->n--;
7332 }
7333 }
7334 msl_info->number_groups--;
7335 }
7336 break;
7337 }
7338 case 'I':
7339 case 'i':
7340 {
cristyb988fe72009-09-16 01:01:10 +00007341 if (LocaleCompare((const char *) tag, "image") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007342 MSLPopImage(msl_info);
7343 break;
7344 }
7345 case 'L':
7346 case 'l':
7347 {
cristyb988fe72009-09-16 01:01:10 +00007348 if (LocaleCompare((const char *) tag,"label") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007349 {
7350 (void) DeleteImageProperty(msl_info->image[n],"label");
7351 if (msl_info->content == (char *) NULL)
7352 break;
7353 StripString(msl_info->content);
7354 (void) SetImageProperty(msl_info->image[n],"label",
7355 msl_info->content);
7356 break;
7357 }
7358 break;
7359 }
7360 case 'M':
7361 case 'm':
7362 {
cristyb988fe72009-09-16 01:01:10 +00007363 if (LocaleCompare((const char *) tag, "msl") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007364 {
7365 /*
7366 This our base element.
7367 at the moment we don't do anything special
7368 but someday we might!
7369 */
7370 }
7371 break;
7372 }
7373 default:
7374 break;
7375 }
7376 if (msl_info->content != (char *) NULL)
7377 msl_info->content=DestroyString(msl_info->content);
7378}
7379
7380static void MSLCharacters(void *context,const xmlChar *c,int length)
7381{
7382 MSLInfo
7383 *msl_info;
7384
7385 register char
7386 *p;
7387
cristybb503372010-05-27 20:51:26 +00007388 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00007389 i;
7390
7391 /*
7392 Receiving some characters from the parser.
7393 */
7394 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7395 " SAX.characters(%s,%d)",c,length);
7396 msl_info=(MSLInfo *) context;
7397 if (msl_info->content != (char *) NULL)
7398 msl_info->content=(char *) ResizeQuantumMemory(msl_info->content,
7399 strlen(msl_info->content)+length+MaxTextExtent,
7400 sizeof(*msl_info->content));
7401 else
7402 {
7403 msl_info->content=(char *) NULL;
cristy37e0b382011-06-07 13:31:21 +00007404 if (~length >= (MaxTextExtent-1))
cristy3ed852e2009-09-05 21:47:34 +00007405 msl_info->content=(char *) AcquireQuantumMemory(length+MaxTextExtent,
7406 sizeof(*msl_info->content));
7407 if (msl_info->content != (char *) NULL)
7408 *msl_info->content='\0';
7409 }
7410 if (msl_info->content == (char *) NULL)
7411 return;
7412 p=msl_info->content+strlen(msl_info->content);
7413 for (i=0; i < length; i++)
7414 *p++=c[i];
7415 *p='\0';
7416}
7417
7418static void MSLReference(void *context,const xmlChar *name)
7419{
7420 MSLInfo
7421 *msl_info;
7422
7423 xmlParserCtxtPtr
7424 parser;
7425
7426 /*
7427 Called when an entity reference is detected.
7428 */
7429 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7430 " SAX.reference(%s)",name);
7431 msl_info=(MSLInfo *) context;
7432 parser=msl_info->parser;
7433 if (*name == '#')
7434 (void) xmlAddChild(parser->node,xmlNewCharRef(msl_info->document,name));
7435 else
7436 (void) xmlAddChild(parser->node,xmlNewReference(msl_info->document,name));
7437}
7438
7439static void MSLIgnorableWhitespace(void *context,const xmlChar *c,int length)
7440{
7441 MSLInfo
7442 *msl_info;
7443
7444 /*
7445 Receiving some ignorable whitespaces from the parser.
7446 */
7447 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7448 " SAX.ignorableWhitespace(%.30s, %d)",c,length);
7449 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007450 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007451}
7452
7453static void MSLProcessingInstructions(void *context,const xmlChar *target,
7454 const xmlChar *data)
7455{
7456 MSLInfo
7457 *msl_info;
7458
7459 /*
7460 A processing instruction has been parsed.
7461 */
7462 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7463 " SAX.processingInstruction(%s, %s)",
7464 target,data);
7465 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007466 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007467}
7468
7469static void MSLComment(void *context,const xmlChar *value)
7470{
7471 MSLInfo
7472 *msl_info;
7473
7474 /*
7475 A comment has been parsed.
7476 */
7477 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7478 " SAX.comment(%s)",value);
7479 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007480 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007481}
7482
7483static void MSLWarning(void *context,const char *format,...)
7484{
7485 char
7486 *message,
7487 reason[MaxTextExtent];
7488
7489 MSLInfo
7490 *msl_info;
7491
7492 va_list
7493 operands;
7494
7495 /**
7496 Display and format a warning messages, gives file, line, position and
7497 extra parameters.
7498 */
7499 va_start(operands,format);
7500 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.warning: ");
7501 (void) LogMagickEvent(CoderEvent,GetMagickModule(),format,operands);
7502 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007503 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007504#if !defined(MAGICKCORE_HAVE_VSNPRINTF)
7505 (void) vsprintf(reason,format,operands);
7506#else
7507 (void) vsnprintf(reason,MaxTextExtent,format,operands);
7508#endif
7509 message=GetExceptionMessage(errno);
7510 ThrowMSLException(CoderError,reason,message);
7511 message=DestroyString(message);
7512 va_end(operands);
7513}
7514
7515static void MSLError(void *context,const char *format,...)
7516{
7517 char
7518 reason[MaxTextExtent];
7519
7520 MSLInfo
7521 *msl_info;
7522
7523 va_list
7524 operands;
7525
7526 /*
7527 Display and format a error formats, gives file, line, position and
7528 extra parameters.
7529 */
7530 va_start(operands,format);
7531 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.error: ");
7532 (void) LogMagickEvent(CoderEvent,GetMagickModule(),format,operands);
7533 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007534 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007535#if !defined(MAGICKCORE_HAVE_VSNPRINTF)
7536 (void) vsprintf(reason,format,operands);
7537#else
7538 (void) vsnprintf(reason,MaxTextExtent,format,operands);
7539#endif
7540 ThrowMSLException(DelegateFatalError,reason,"SAX error");
7541 va_end(operands);
7542}
7543
7544static void MSLCDataBlock(void *context,const xmlChar *value,int length)
7545{
7546 MSLInfo
7547 *msl_info;
7548
7549 xmlNodePtr
7550 child;
7551
7552 xmlParserCtxtPtr
7553 parser;
7554
7555 /*
7556 Called when a pcdata block has been parsed.
7557 */
7558 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7559 " SAX.pcdata(%s, %d)",value,length);
7560 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007561 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007562 parser=msl_info->parser;
7563 child=xmlGetLastChild(parser->node);
7564 if ((child != (xmlNodePtr) NULL) && (child->type == XML_CDATA_SECTION_NODE))
7565 {
7566 xmlTextConcat(child,value,length);
7567 return;
7568 }
7569 (void) xmlAddChild(parser->node,xmlNewCDataBlock(parser->myDoc,value,length));
7570}
7571
7572static void MSLExternalSubset(void *context,const xmlChar *name,
7573 const xmlChar *external_id,const xmlChar *system_id)
7574{
7575 MSLInfo
7576 *msl_info;
7577
7578 xmlParserCtxt
7579 parser_context;
7580
7581 xmlParserCtxtPtr
7582 parser;
7583
7584 xmlParserInputPtr
7585 input;
7586
7587 /*
7588 Does this document has an external subset?
7589 */
7590 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7591 " SAX.externalSubset(%s %s %s)",name,
cristyb988fe72009-09-16 01:01:10 +00007592 (external_id != (const xmlChar *) NULL ? (const char *) external_id : " "),
7593 (system_id != (const xmlChar *) NULL ? (const char *) system_id : " "));
cristy3ed852e2009-09-05 21:47:34 +00007594 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007595 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007596 parser=msl_info->parser;
7597 if (((external_id == NULL) && (system_id == NULL)) ||
7598 ((parser->validate == 0) || (parser->wellFormed == 0) ||
7599 (msl_info->document == 0)))
7600 return;
7601 input=MSLResolveEntity(context,external_id,system_id);
7602 if (input == NULL)
7603 return;
7604 (void) xmlNewDtd(msl_info->document,name,external_id,system_id);
7605 parser_context=(*parser);
7606 parser->inputTab=(xmlParserInputPtr *) xmlMalloc(5*sizeof(*parser->inputTab));
7607 if (parser->inputTab == (xmlParserInputPtr *) NULL)
7608 {
7609 parser->errNo=XML_ERR_NO_MEMORY;
7610 parser->input=parser_context.input;
7611 parser->inputNr=parser_context.inputNr;
7612 parser->inputMax=parser_context.inputMax;
7613 parser->inputTab=parser_context.inputTab;
7614 return;
7615 }
7616 parser->inputNr=0;
7617 parser->inputMax=5;
7618 parser->input=NULL;
7619 xmlPushInput(parser,input);
7620 (void) xmlSwitchEncoding(parser,xmlDetectCharEncoding(parser->input->cur,4));
7621 if (input->filename == (char *) NULL)
7622 input->filename=(char *) xmlStrdup(system_id);
7623 input->line=1;
7624 input->col=1;
7625 input->base=parser->input->cur;
7626 input->cur=parser->input->cur;
7627 input->free=NULL;
7628 xmlParseExternalSubset(parser,external_id,system_id);
7629 while (parser->inputNr > 1)
7630 (void) xmlPopInput(parser);
7631 xmlFreeInputStream(parser->input);
7632 xmlFree(parser->inputTab);
7633 parser->input=parser_context.input;
7634 parser->inputNr=parser_context.inputNr;
7635 parser->inputMax=parser_context.inputMax;
7636 parser->inputTab=parser_context.inputTab;
7637}
7638
7639#if defined(__cplusplus) || defined(c_plusplus)
7640}
7641#endif
7642
7643static MagickBooleanType ProcessMSLScript(const ImageInfo *image_info,Image **image,
7644 ExceptionInfo *exception)
7645{
cristy3ed852e2009-09-05 21:47:34 +00007646 char
7647 message[MaxTextExtent];
7648
7649 Image
7650 *msl_image;
7651
7652 int
7653 status;
7654
cristybb503372010-05-27 20:51:26 +00007655 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00007656 n;
7657
7658 MSLInfo
7659 msl_info;
7660
cristy5f6f01c2009-11-19 19:36:42 +00007661 xmlSAXHandler
7662 sax_modules;
7663
cristy3ed852e2009-09-05 21:47:34 +00007664 xmlSAXHandlerPtr
cristy5f6f01c2009-11-19 19:36:42 +00007665 sax_handler;
cristy3ed852e2009-09-05 21:47:34 +00007666
7667 /*
7668 Open image file.
7669 */
7670 assert(image_info != (const ImageInfo *) NULL);
7671 assert(image_info->signature == MagickSignature);
7672 if (image_info->debug != MagickFalse)
cristy5f6f01c2009-11-19 19:36:42 +00007673 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
7674 image_info->filename);
cristy3ed852e2009-09-05 21:47:34 +00007675 assert(image != (Image **) NULL);
7676 msl_image=AcquireImage(image_info);
7677 status=OpenBlob(image_info,msl_image,ReadBinaryBlobMode,exception);
7678 if (status == MagickFalse)
7679 {
7680 ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
7681 msl_image->filename);
7682 msl_image=DestroyImageList(msl_image);
7683 return(MagickFalse);
7684 }
7685 msl_image->columns=1;
7686 msl_image->rows=1;
7687 /*
7688 Parse MSL file.
7689 */
7690 (void) ResetMagickMemory(&msl_info,0,sizeof(msl_info));
7691 msl_info.exception=exception;
7692 msl_info.image_info=(ImageInfo **) AcquireMagickMemory(
7693 sizeof(*msl_info.image_info));
7694 msl_info.draw_info=(DrawInfo **) AcquireMagickMemory(
7695 sizeof(*msl_info.draw_info));
7696 /* top of the stack is the MSL file itself */
cristy73bd4a52010-10-05 11:24:23 +00007697 msl_info.image=(Image **) AcquireMagickMemory(sizeof(*msl_info.image));
cristy3ed852e2009-09-05 21:47:34 +00007698 msl_info.attributes=(Image **) AcquireMagickMemory(
7699 sizeof(*msl_info.attributes));
7700 msl_info.group_info=(MSLGroupInfo *) AcquireMagickMemory(
7701 sizeof(*msl_info.group_info));
7702 if ((msl_info.image_info == (ImageInfo **) NULL) ||
7703 (msl_info.image == (Image **) NULL) ||
7704 (msl_info.attributes == (Image **) NULL) ||
7705 (msl_info.group_info == (MSLGroupInfo *) NULL))
7706 ThrowFatalException(ResourceLimitFatalError,
7707 "UnableToInterpretMSLImage");
7708 *msl_info.image_info=CloneImageInfo(image_info);
7709 *msl_info.draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL);
7710 *msl_info.attributes=AcquireImage(image_info);
7711 msl_info.group_info[0].numImages=0;
7712 /* the first slot is used to point to the MSL file image */
7713 *msl_info.image=msl_image;
7714 if (*image != (Image *) NULL)
7715 MSLPushImage(&msl_info,*image);
7716 (void) xmlSubstituteEntitiesDefault(1);
cristy5f6f01c2009-11-19 19:36:42 +00007717 (void) ResetMagickMemory(&sax_modules,0,sizeof(sax_modules));
7718 sax_modules.internalSubset=MSLInternalSubset;
7719 sax_modules.isStandalone=MSLIsStandalone;
7720 sax_modules.hasInternalSubset=MSLHasInternalSubset;
7721 sax_modules.hasExternalSubset=MSLHasExternalSubset;
7722 sax_modules.resolveEntity=MSLResolveEntity;
7723 sax_modules.getEntity=MSLGetEntity;
7724 sax_modules.entityDecl=MSLEntityDeclaration;
7725 sax_modules.notationDecl=MSLNotationDeclaration;
7726 sax_modules.attributeDecl=MSLAttributeDeclaration;
7727 sax_modules.elementDecl=MSLElementDeclaration;
7728 sax_modules.unparsedEntityDecl=MSLUnparsedEntityDeclaration;
7729 sax_modules.setDocumentLocator=MSLSetDocumentLocator;
7730 sax_modules.startDocument=MSLStartDocument;
7731 sax_modules.endDocument=MSLEndDocument;
7732 sax_modules.startElement=MSLStartElement;
7733 sax_modules.endElement=MSLEndElement;
7734 sax_modules.reference=MSLReference;
7735 sax_modules.characters=MSLCharacters;
7736 sax_modules.ignorableWhitespace=MSLIgnorableWhitespace;
7737 sax_modules.processingInstruction=MSLProcessingInstructions;
7738 sax_modules.comment=MSLComment;
7739 sax_modules.warning=MSLWarning;
7740 sax_modules.error=MSLError;
7741 sax_modules.fatalError=MSLError;
7742 sax_modules.getParameterEntity=MSLGetParameterEntity;
7743 sax_modules.cdataBlock=MSLCDataBlock;
7744 sax_modules.externalSubset=MSLExternalSubset;
7745 sax_handler=(&sax_modules);
7746 msl_info.parser=xmlCreatePushParserCtxt(sax_handler,&msl_info,(char *) NULL,0,
cristy3ed852e2009-09-05 21:47:34 +00007747 msl_image->filename);
7748 while (ReadBlobString(msl_image,message) != (char *) NULL)
7749 {
cristybb503372010-05-27 20:51:26 +00007750 n=(ssize_t) strlen(message);
cristy3ed852e2009-09-05 21:47:34 +00007751 if (n == 0)
7752 continue;
7753 status=xmlParseChunk(msl_info.parser,message,(int) n,MagickFalse);
7754 if (status != 0)
7755 break;
7756 (void) xmlParseChunk(msl_info.parser," ",1,MagickFalse);
7757 if (msl_info.exception->severity >= ErrorException)
7758 break;
7759 }
7760 if (msl_info.exception->severity == UndefinedException)
7761 (void) xmlParseChunk(msl_info.parser," ",1,MagickTrue);
7762 xmlFreeParserCtxt(msl_info.parser);
7763 (void) LogMagickEvent(CoderEvent,GetMagickModule(),"end SAX");
7764 xmlCleanupParser();
7765 msl_info.group_info=(MSLGroupInfo *) RelinquishMagickMemory(
7766 msl_info.group_info);
7767 if (*image == (Image *) NULL)
7768 *image=(*msl_info.image);
cristy5f6f01c2009-11-19 19:36:42 +00007769 if ((*msl_info.image)->exception.severity != UndefinedException)
7770 return(MagickFalse);
7771 return(MagickTrue);
cristy3ed852e2009-09-05 21:47:34 +00007772}
7773
7774static Image *ReadMSLImage(const ImageInfo *image_info,ExceptionInfo *exception)
7775{
7776 Image
7777 *image;
7778
7779 /*
7780 Open image file.
7781 */
7782 assert(image_info != (const ImageInfo *) NULL);
7783 assert(image_info->signature == MagickSignature);
7784 if (image_info->debug != MagickFalse)
7785 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
7786 image_info->filename);
7787 assert(exception != (ExceptionInfo *) NULL);
7788 assert(exception->signature == MagickSignature);
7789 image=(Image *) NULL;
7790 (void) ProcessMSLScript(image_info,&image,exception);
7791 return(GetFirstImageInList(image));
7792}
7793#endif
7794
7795/*
7796%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7797% %
7798% %
7799% %
7800% R e g i s t e r M S L I m a g e %
7801% %
7802% %
7803% %
7804%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7805%
7806% RegisterMSLImage() adds attributes for the MSL image format to
7807% the list of supported formats. The attributes include the image format
7808% tag, a method to read and/or write the format, whether the format
7809% supports the saving of more than one frame to the same file or blob,
7810% whether the format supports native in-memory I/O, and a brief
7811% description of the format.
7812%
7813% The format of the RegisterMSLImage method is:
7814%
cristybb503372010-05-27 20:51:26 +00007815% size_t RegisterMSLImage(void)
cristy3ed852e2009-09-05 21:47:34 +00007816%
7817*/
cristybb503372010-05-27 20:51:26 +00007818ModuleExport size_t RegisterMSLImage(void)
cristy3ed852e2009-09-05 21:47:34 +00007819{
7820 MagickInfo
7821 *entry;
7822
7823 entry=SetMagickInfo("MSL");
7824#if defined(MAGICKCORE_XML_DELEGATE)
7825 entry->decoder=(DecodeImageHandler *) ReadMSLImage;
7826 entry->encoder=(EncodeImageHandler *) WriteMSLImage;
7827#endif
7828 entry->description=ConstantString("Magick Scripting Language");
7829 entry->module=ConstantString("MSL");
7830 (void) RegisterMagickInfo(entry);
7831 return(MagickImageCoderSignature);
7832}
7833
cristy6b9f7ed2010-04-24 01:08:02 +00007834#if defined(MAGICKCORE_XML_DELEGATE)
cristy3ed852e2009-09-05 21:47:34 +00007835/*
7836%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7837% %
7838% %
7839% %
cristyb988fe72009-09-16 01:01:10 +00007840% S e t M S L A t t r i b u t e s %
7841% %
7842% %
7843% %
7844%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7845%
7846% SetMSLAttributes() ...
7847%
7848% The format of the SetMSLAttributes method is:
7849%
7850% MagickBooleanType SetMSLAttributes(MSLInfo *msl_info,
cristyb20775d2009-09-16 01:51:41 +00007851% const char *keyword,const char *value)
cristyb988fe72009-09-16 01:01:10 +00007852%
7853% A description of each parameter follows:
7854%
7855% o msl_info: the MSL info.
7856%
cristyb20775d2009-09-16 01:51:41 +00007857% o keyword: the keyword.
7858%
7859% o value: the value.
cristyb988fe72009-09-16 01:01:10 +00007860%
7861*/
cristyb20775d2009-09-16 01:51:41 +00007862static MagickBooleanType SetMSLAttributes(MSLInfo *msl_info,const char *keyword,
7863 const char *value)
cristyb988fe72009-09-16 01:01:10 +00007864{
cristy4582cbb2009-09-23 00:35:43 +00007865 Image
7866 *attributes;
7867
cristyb20775d2009-09-16 01:51:41 +00007868 DrawInfo
7869 *draw_info;
cristyb988fe72009-09-16 01:01:10 +00007870
7871 ExceptionInfo
7872 *exception;
7873
cristy4582cbb2009-09-23 00:35:43 +00007874 GeometryInfo
7875 geometry_info;
7876
cristy4fa36e42009-09-18 14:24:06 +00007877 Image
7878 *image;
7879
cristyb20775d2009-09-16 01:51:41 +00007880 ImageInfo
7881 *image_info;
7882
cristy4582cbb2009-09-23 00:35:43 +00007883 int
7884 flags;
7885
cristybb503372010-05-27 20:51:26 +00007886 ssize_t
cristyb988fe72009-09-16 01:01:10 +00007887 n;
7888
cristyb988fe72009-09-16 01:01:10 +00007889 assert(msl_info != (MSLInfo *) NULL);
cristyb20775d2009-09-16 01:51:41 +00007890 if (keyword == (const char *) NULL)
7891 return(MagickTrue);
7892 if (value == (const char *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007893 return(MagickTrue);
7894 exception=msl_info->exception;
7895 n=msl_info->n;
cristy4582cbb2009-09-23 00:35:43 +00007896 attributes=msl_info->attributes[n];
cristyb20775d2009-09-16 01:51:41 +00007897 image_info=msl_info->image_info[n];
7898 draw_info=msl_info->draw_info[n];
cristy4fa36e42009-09-18 14:24:06 +00007899 image=msl_info->image[n];
cristyb20775d2009-09-16 01:51:41 +00007900 switch (*keyword)
cristyb988fe72009-09-16 01:01:10 +00007901 {
cristyfb758a52009-09-16 14:36:08 +00007902 case 'A':
7903 case 'a':
7904 {
7905 if (LocaleCompare(keyword,"adjoin") == 0)
7906 {
cristybb503372010-05-27 20:51:26 +00007907 ssize_t
cristyfb758a52009-09-16 14:36:08 +00007908 adjoin;
7909
cristy042ee782011-04-22 18:48:30 +00007910 adjoin=ParseCommandOption(MagickBooleanOptions,MagickFalse,value);
cristyfb758a52009-09-16 14:36:08 +00007911 if (adjoin < 0)
7912 ThrowMSLException(OptionError,"UnrecognizedType",value);
7913 image_info->adjoin=(MagickBooleanType) adjoin;
7914 break;
7915 }
cristy4fa36e42009-09-18 14:24:06 +00007916 if (LocaleCompare(keyword,"alpha") == 0)
7917 {
cristybb503372010-05-27 20:51:26 +00007918 ssize_t
cristy4fa36e42009-09-18 14:24:06 +00007919 alpha;
7920
cristy042ee782011-04-22 18:48:30 +00007921 alpha=ParseCommandOption(MagickAlphaOptions,MagickFalse,value);
cristy4fa36e42009-09-18 14:24:06 +00007922 if (alpha < 0)
7923 ThrowMSLException(OptionError,"UnrecognizedType",value);
cristy4582cbb2009-09-23 00:35:43 +00007924 if (image != (Image *) NULL)
cristy63240882011-08-05 19:05:27 +00007925 (void) SetImageAlphaChannel(image,(AlphaChannelType) alpha,
7926 exception);
cristy4582cbb2009-09-23 00:35:43 +00007927 break;
7928 }
7929 if (LocaleCompare(keyword,"antialias") == 0)
7930 {
cristybb503372010-05-27 20:51:26 +00007931 ssize_t
cristy4582cbb2009-09-23 00:35:43 +00007932 antialias;
7933
cristy042ee782011-04-22 18:48:30 +00007934 antialias=ParseCommandOption(MagickBooleanOptions,MagickFalse,value);
cristy4582cbb2009-09-23 00:35:43 +00007935 if (antialias < 0)
7936 ThrowMSLException(OptionError,"UnrecognizedGravityType",value);
7937 image_info->antialias=(MagickBooleanType) antialias;
7938 break;
7939 }
7940 if (LocaleCompare(keyword,"area-limit") == 0)
7941 {
7942 MagickSizeType
7943 limit;
7944
7945 limit=MagickResourceInfinity;
7946 if (LocaleCompare(value,"unlimited") != 0)
cristyf2f27272009-12-17 14:48:46 +00007947 limit=(MagickSizeType) SiPrefixToDouble(value,100.0);
cristy4582cbb2009-09-23 00:35:43 +00007948 (void) SetMagickResourceLimit(AreaResource,limit);
7949 break;
7950 }
7951 if (LocaleCompare(keyword,"attenuate") == 0)
7952 {
7953 (void) SetImageOption(image_info,keyword,value);
7954 break;
7955 }
7956 if (LocaleCompare(keyword,"authenticate") == 0)
7957 {
7958 (void) CloneString(&image_info->density,value);
cristy4fa36e42009-09-18 14:24:06 +00007959 break;
7960 }
cristyfb758a52009-09-16 14:36:08 +00007961 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7962 break;
7963 }
cristyb20775d2009-09-16 01:51:41 +00007964 case 'B':
7965 case 'b':
cristyb988fe72009-09-16 01:01:10 +00007966 {
cristyb20775d2009-09-16 01:51:41 +00007967 if (LocaleCompare(keyword,"background") == 0)
7968 {
cristy2c8b6312009-09-16 02:37:23 +00007969 (void) QueryColorDatabase(value,&image_info->background_color,
cristyb20775d2009-09-16 01:51:41 +00007970 exception);
7971 break;
7972 }
cristy4582cbb2009-09-23 00:35:43 +00007973 if (LocaleCompare(keyword,"bias") == 0)
7974 {
7975 if (image == (Image *) NULL)
7976 break;
cristyf2f27272009-12-17 14:48:46 +00007977 image->bias=SiPrefixToDouble(value,QuantumRange);
cristy4582cbb2009-09-23 00:35:43 +00007978 break;
7979 }
7980 if (LocaleCompare(keyword,"blue-primary") == 0)
7981 {
7982 if (image == (Image *) NULL)
7983 break;
7984 flags=ParseGeometry(value,&geometry_info);
7985 image->chromaticity.blue_primary.x=geometry_info.rho;
7986 image->chromaticity.blue_primary.y=geometry_info.sigma;
7987 if ((flags & SigmaValue) == 0)
7988 image->chromaticity.blue_primary.y=
7989 image->chromaticity.blue_primary.x;
7990 break;
7991 }
cristy2c8b6312009-09-16 02:37:23 +00007992 if (LocaleCompare(keyword,"bordercolor") == 0)
7993 {
7994 (void) QueryColorDatabase(value,&image_info->border_color,
7995 exception);
7996 break;
7997 }
7998 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7999 break;
8000 }
8001 case 'D':
8002 case 'd':
8003 {
8004 if (LocaleCompare(keyword,"density") == 0)
8005 {
8006 (void) CloneString(&image_info->density,value);
8007 (void) CloneString(&draw_info->density,value);
8008 break;
8009 }
cristyb20775d2009-09-16 01:51:41 +00008010 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8011 break;
8012 }
8013 case 'F':
8014 case 'f':
8015 {
8016 if (LocaleCompare(keyword,"fill") == 0)
8017 {
cristy2c8b6312009-09-16 02:37:23 +00008018 (void) QueryColorDatabase(value,&draw_info->fill,exception);
cristya30afaf2009-09-22 13:42:12 +00008019 (void) SetImageOption(image_info,keyword,value);
cristyb20775d2009-09-16 01:51:41 +00008020 break;
8021 }
cristy4582cbb2009-09-23 00:35:43 +00008022 if (LocaleCompare(keyword,"filename") == 0)
8023 {
8024 (void) CopyMagickString(image_info->filename,value,MaxTextExtent);
8025 break;
8026 }
8027 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8028 break;
8029 }
8030 case 'G':
8031 case 'g':
8032 {
8033 if (LocaleCompare(keyword,"gravity") == 0)
8034 {
cristybb503372010-05-27 20:51:26 +00008035 ssize_t
cristy4582cbb2009-09-23 00:35:43 +00008036 gravity;
8037
cristy042ee782011-04-22 18:48:30 +00008038 gravity=ParseCommandOption(MagickGravityOptions,MagickFalse,value);
cristy4582cbb2009-09-23 00:35:43 +00008039 if (gravity < 0)
8040 ThrowMSLException(OptionError,"UnrecognizedGravityType",value);
8041 (void) SetImageOption(image_info,keyword,value);
8042 break;
8043 }
cristyb20775d2009-09-16 01:51:41 +00008044 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8045 break;
8046 }
8047 case 'I':
8048 case 'i':
8049 {
8050 if (LocaleCompare(keyword,"id") == 0)
8051 {
cristy4582cbb2009-09-23 00:35:43 +00008052 (void) SetImageProperty(attributes,keyword,value);
cristy2c8b6312009-09-16 02:37:23 +00008053 break;
8054 }
8055 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8056 break;
8057 }
8058 case 'M':
8059 case 'm':
8060 {
8061 if (LocaleCompare(keyword,"magick") == 0)
8062 {
8063 (void) CopyMagickString(image_info->magick,value,MaxTextExtent);
8064 break;
8065 }
cristy2c8b6312009-09-16 02:37:23 +00008066 if (LocaleCompare(keyword,"mattecolor") == 0)
8067 {
8068 (void) QueryColorDatabase(value,&image_info->matte_color,
8069 exception);
cristyb20775d2009-09-16 01:51:41 +00008070 break;
8071 }
8072 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8073 break;
8074 }
8075 case 'P':
8076 case 'p':
8077 {
8078 if (LocaleCompare(keyword,"pointsize") == 0)
8079 {
cristyc1acd842011-05-19 23:05:47 +00008080 image_info->pointsize=InterpretLocaleValue(value,(char **) NULL);
8081 draw_info->pointsize=InterpretLocaleValue(value,(char **) NULL);
cristyb20775d2009-09-16 01:51:41 +00008082 break;
8083 }
8084 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8085 break;
8086 }
cristy4582cbb2009-09-23 00:35:43 +00008087 case 'Q':
8088 case 'q':
8089 {
8090 if (LocaleCompare(keyword,"quality") == 0)
8091 {
cristyf2f27272009-12-17 14:48:46 +00008092 image_info->quality=StringToLong(value);
cristy4582cbb2009-09-23 00:35:43 +00008093 if (image == (Image *) NULL)
8094 break;
cristyf2f27272009-12-17 14:48:46 +00008095 image->quality=StringToLong(value);
cristy4582cbb2009-09-23 00:35:43 +00008096 break;
8097 }
8098 break;
8099 }
cristyb20775d2009-09-16 01:51:41 +00008100 case 'S':
8101 case 's':
8102 {
8103 if (LocaleCompare(keyword,"size") == 0)
8104 {
cristy2c8b6312009-09-16 02:37:23 +00008105 (void) CloneString(&image_info->size,value);
cristyb20775d2009-09-16 01:51:41 +00008106 break;
8107 }
8108 if (LocaleCompare(keyword,"stroke") == 0)
8109 {
cristy2c8b6312009-09-16 02:37:23 +00008110 (void) QueryColorDatabase(value,&draw_info->stroke,exception);
cristya30afaf2009-09-22 13:42:12 +00008111 (void) SetImageOption(image_info,keyword,value);
cristyb20775d2009-09-16 01:51:41 +00008112 break;
8113 }
8114 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8115 break;
8116 }
8117 default:
8118 {
8119 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8120 break;
cristyb988fe72009-09-16 01:01:10 +00008121 }
8122 }
8123 return(MagickTrue);
8124}
cristy6b9f7ed2010-04-24 01:08:02 +00008125#endif
cristyb988fe72009-09-16 01:01:10 +00008126
8127/*
8128%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8129% %
8130% %
8131% %
cristy3ed852e2009-09-05 21:47:34 +00008132% U n r e g i s t e r M S L I m a g e %
8133% %
8134% %
8135% %
8136%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8137%
8138% UnregisterMSLImage() removes format registrations made by the
8139% MSL module from the list of supported formats.
8140%
8141% The format of the UnregisterMSLImage method is:
8142%
8143% UnregisterMSLImage(void)
8144%
8145*/
8146ModuleExport void UnregisterMSLImage(void)
8147{
8148 (void) UnregisterMagickInfo("MSL");
8149}
8150
8151#if defined(MAGICKCORE_XML_DELEGATE)
8152/*
8153%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8154% %
8155% %
8156% %
8157% W r i t e M S L I m a g e %
8158% %
8159% %
8160% %
8161%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8162%
8163% WriteMSLImage() writes an image to a file in MVG image format.
8164%
8165% The format of the WriteMSLImage method is:
8166%
cristy1e178e72011-08-28 19:44:34 +00008167% MagickBooleanType WriteMSLImage(const ImageInfo *image_info,
8168% Image *image,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00008169%
8170% A description of each parameter follows.
8171%
8172% o image_info: the image info.
8173%
8174% o image: The image.
8175%
cristy1e178e72011-08-28 19:44:34 +00008176% o exception: return any errors or warnings in this structure.
8177%
cristy3ed852e2009-09-05 21:47:34 +00008178*/
cristy1e178e72011-08-28 19:44:34 +00008179static MagickBooleanType WriteMSLImage(const ImageInfo *image_info,Image *image,
8180 ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00008181{
8182 assert(image_info != (const ImageInfo *) NULL);
8183 assert(image_info->signature == MagickSignature);
8184 assert(image != (Image *) NULL);
8185 assert(image->signature == MagickSignature);
8186 if (image->debug != MagickFalse)
8187 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
8188 (void) ReferenceImage(image);
cristy1e178e72011-08-28 19:44:34 +00008189 (void) ProcessMSLScript(image_info,&image,exception);
cristy3ed852e2009-09-05 21:47:34 +00008190 return(MagickTrue);
8191}
8192#endif