blob: 6fea30ea078097737d5a65b18dd346839d439895 [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"
cristy4c08aed2011-07-01 19:47:50 +000052#include "MagickCore/color-private.h"
cristy9950d572011-10-01 18:22:35 +000053#include "MagickCore/colormap.h"
cristy4c08aed2011-07-01 19:47:50 +000054#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)
cristy9950d572011-10-01 18:22:35 +0000574 msl_info->attributes[n]=AcquireImage(msl_info->image_info[n],
575 &image->exception);
cristy3ed852e2009-09-05 21:47:34 +0000576 else
577 msl_info->attributes[n]=CloneImage(image,0,0,MagickTrue,&image->exception);
578 msl_info->image[n]=(Image *) image;
579 if ((msl_info->image_info[n] == (ImageInfo *) NULL) ||
580 (msl_info->attributes[n] == (Image *) NULL))
581 ThrowMSLException(ResourceLimitFatalError,"MemoryAllocationFailed","msl");
582 if (msl_info->number_groups != 0)
583 msl_info->group_info[msl_info->number_groups-1].numImages++;
584}
585
586static void MSLPopImage(MSLInfo *msl_info)
587{
588 if (msl_info->number_groups != 0)
589 return;
590 if (msl_info->image[msl_info->n] != (Image *) NULL)
591 msl_info->image[msl_info->n]=DestroyImage(msl_info->image[msl_info->n]);
592 msl_info->attributes[msl_info->n]=DestroyImage(
593 msl_info->attributes[msl_info->n]);
594 msl_info->image_info[msl_info->n]=DestroyImageInfo(
595 msl_info->image_info[msl_info->n]);
596 msl_info->n--;
597}
598
599static void MSLStartElement(void *context,const xmlChar *tag,
600 const xmlChar **attributes)
601{
602 AffineMatrix
603 affine,
604 current;
605
606 ChannelType
607 channel;
608
cristybd5a96c2011-08-21 00:04:26 +0000609 ChannelType
610 channel_mask;
611
cristy3ed852e2009-09-05 21:47:34 +0000612 char
613 key[MaxTextExtent],
614 *value;
615
616 const char
617 *attribute,
618 *keyword;
619
620 double
621 angle;
622
623 DrawInfo
624 *draw_info;
625
626 ExceptionInfo
627 exception;
628
629 GeometryInfo
630 geometry_info;
631
632 Image
633 *image;
634
635 int
636 flags;
637
cristybb503372010-05-27 20:51:26 +0000638 ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000639 option,
640 j,
641 n,
642 x,
643 y;
644
645 MSLInfo
646 *msl_info;
647
648 RectangleInfo
649 geometry;
650
cristybb503372010-05-27 20:51:26 +0000651 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000652 i;
653
cristybb503372010-05-27 20:51:26 +0000654 size_t
cristy3ed852e2009-09-05 21:47:34 +0000655 height,
656 width;
657
658 /*
659 Called when an opening tag has been processed.
660 */
661 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
662 " SAX.startElement(%s",tag);
663 GetExceptionInfo(&exception);
664 msl_info=(MSLInfo *) context;
665 n=msl_info->n;
666 keyword=(const char *) NULL;
667 value=(char *) NULL;
668 SetGeometryInfo(&geometry_info);
669 channel=DefaultChannels;
670 switch (*tag)
671 {
672 case 'A':
673 case 'a':
674 {
cristyb988fe72009-09-16 01:01:10 +0000675 if (LocaleCompare((const char *) tag,"add-noise") == 0)
cristy3ed852e2009-09-05 21:47:34 +0000676 {
677 Image
678 *noise_image;
679
680 NoiseType
681 noise;
682
683 /*
684 Add noise image.
685 */
686 if (msl_info->image[n] == (Image *) NULL)
687 {
cristyb988fe72009-09-16 01:01:10 +0000688 ThrowMSLException(OptionError,"NoImagesDefined",
689 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +0000690 break;
691 }
692 noise=UniformNoise;
693 if (attributes != (const xmlChar **) NULL)
694 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
695 {
696 keyword=(const char *) attributes[i++];
697 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +0000698 msl_info->attributes[n],(const char *) attributes[i],
699 &exception);
cristy3ed852e2009-09-05 21:47:34 +0000700 CloneString(&value,attribute);
701 switch (*keyword)
702 {
703 case 'C':
704 case 'c':
705 {
706 if (LocaleCompare(keyword,"channel") == 0)
707 {
708 option=ParseChannelOption(value);
709 if (option < 0)
710 ThrowMSLException(OptionError,"UnrecognizedChannelType",
711 value);
712 channel=(ChannelType) option;
713 break;
714 }
715 ThrowMSLException(OptionError,"UnrecognizedAttribute",
716 keyword);
717 break;
718 }
719 case 'N':
720 case 'n':
721 {
722 if (LocaleCompare(keyword,"noise") == 0)
723 {
cristy042ee782011-04-22 18:48:30 +0000724 option=ParseCommandOption(MagickNoiseOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +0000725 value);
726 if (option < 0)
727 ThrowMSLException(OptionError,"UnrecognizedNoiseType",
728 value);
729 noise=(NoiseType) option;
730 break;
731 }
732 ThrowMSLException(OptionError,"UnrecognizedAttribute",
733 keyword);
734 break;
735 }
736 default:
737 {
738 ThrowMSLException(OptionError,"UnrecognizedAttribute",
739 keyword);
740 break;
741 }
742 }
743 }
cristybd5a96c2011-08-21 00:04:26 +0000744 channel_mask=SetPixelChannelMask(msl_info->image[n],channel);
cristy490408a2011-07-07 14:42:05 +0000745 noise_image=AddNoiseImage(msl_info->image[n],noise,
cristy3ed852e2009-09-05 21:47:34 +0000746 &msl_info->image[n]->exception);
cristybd5a96c2011-08-21 00:04:26 +0000747 (void) SetPixelChannelMap(msl_info->image[n],channel_mask);
cristy3ed852e2009-09-05 21:47:34 +0000748 if (noise_image == (Image *) NULL)
749 break;
750 msl_info->image[n]=DestroyImage(msl_info->image[n]);
751 msl_info->image[n]=noise_image;
752 break;
753 }
cristyb988fe72009-09-16 01:01:10 +0000754 if (LocaleCompare((const char *) tag,"annotate") == 0)
cristy3ed852e2009-09-05 21:47:34 +0000755 {
756 char
757 text[MaxTextExtent];
758
759 /*
760 Annotate image.
761 */
762 if (msl_info->image[n] == (Image *) NULL)
763 {
cristyb988fe72009-09-16 01:01:10 +0000764 ThrowMSLException(OptionError,"NoImagesDefined",
765 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +0000766 break;
767 }
768 draw_info=CloneDrawInfo(msl_info->image_info[n],
769 msl_info->draw_info[n]);
770 angle=0.0;
771 current=draw_info->affine;
772 GetAffineMatrix(&affine);
773 if (attributes != (const xmlChar **) NULL)
774 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
775 {
776 keyword=(const char *) attributes[i++];
777 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +0000778 msl_info->attributes[n],(const char *) attributes[i],
779 &exception);
cristy3ed852e2009-09-05 21:47:34 +0000780 CloneString(&value,attribute);
781 switch (*keyword)
782 {
783 case 'A':
784 case 'a':
785 {
786 if (LocaleCompare(keyword,"affine") == 0)
787 {
788 char
789 *p;
790
791 p=value;
cristyc1acd842011-05-19 23:05:47 +0000792 draw_info->affine.sx=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +0000793 if (*p ==',')
794 p++;
cristyc1acd842011-05-19 23:05:47 +0000795 draw_info->affine.rx=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +0000796 if (*p ==',')
797 p++;
cristyc1acd842011-05-19 23:05:47 +0000798 draw_info->affine.ry=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +0000799 if (*p ==',')
800 p++;
cristyc1acd842011-05-19 23:05:47 +0000801 draw_info->affine.sy=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +0000802 if (*p ==',')
803 p++;
cristyc1acd842011-05-19 23:05:47 +0000804 draw_info->affine.tx=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +0000805 if (*p ==',')
806 p++;
cristyc1acd842011-05-19 23:05:47 +0000807 draw_info->affine.ty=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +0000808 break;
809 }
810 if (LocaleCompare(keyword,"align") == 0)
811 {
cristy042ee782011-04-22 18:48:30 +0000812 option=ParseCommandOption(MagickAlignOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +0000813 value);
814 if (option < 0)
815 ThrowMSLException(OptionError,"UnrecognizedAlignType",
816 value);
817 draw_info->align=(AlignType) option;
818 break;
819 }
820 if (LocaleCompare(keyword,"antialias") == 0)
821 {
cristy042ee782011-04-22 18:48:30 +0000822 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +0000823 value);
824 if (option < 0)
825 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
826 value);
827 draw_info->stroke_antialias=(MagickBooleanType) option;
828 draw_info->text_antialias=(MagickBooleanType) option;
829 break;
830 }
831 ThrowMSLException(OptionError,"UnrecognizedAttribute",
832 keyword);
833 break;
834 }
835 case 'D':
836 case 'd':
837 {
838 if (LocaleCompare(keyword,"density") == 0)
839 {
840 CloneString(&draw_info->density,value);
841 break;
842 }
843 ThrowMSLException(OptionError,"UnrecognizedAttribute",
844 keyword);
845 break;
846 }
847 case 'E':
848 case 'e':
849 {
850 if (LocaleCompare(keyword,"encoding") == 0)
851 {
852 CloneString(&draw_info->encoding,value);
853 break;
854 }
855 ThrowMSLException(OptionError,"UnrecognizedAttribute",
856 keyword);
857 break;
858 }
859 case 'F':
860 case 'f':
861 {
862 if (LocaleCompare(keyword, "fill") == 0)
863 {
cristy9950d572011-10-01 18:22:35 +0000864 (void) QueryColorCompliance(value,AllCompliance,
865 &draw_info->fill,&exception);
cristy3ed852e2009-09-05 21:47:34 +0000866 break;
867 }
868 if (LocaleCompare(keyword,"family") == 0)
869 {
870 CloneString(&draw_info->family,value);
871 break;
872 }
873 if (LocaleCompare(keyword,"font") == 0)
874 {
875 CloneString(&draw_info->font,value);
876 break;
877 }
878 ThrowMSLException(OptionError,"UnrecognizedAttribute",
879 keyword);
880 break;
881 }
882 case 'G':
883 case 'g':
884 {
885 if (LocaleCompare(keyword,"geometry") == 0)
886 {
cristy860f4e12011-07-28 19:00:28 +0000887 flags=ParseGravityGeometry(msl_info->image[n],value,
cristy3ed852e2009-09-05 21:47:34 +0000888 &geometry,&exception);
cristy3ed852e2009-09-05 21:47:34 +0000889 break;
890 }
891 if (LocaleCompare(keyword,"gravity") == 0)
892 {
cristy860f4e12011-07-28 19:00:28 +0000893 option=ParseCommandOption(MagickGravityOptions,
894 MagickFalse,value);
cristy3ed852e2009-09-05 21:47:34 +0000895 if (option < 0)
896 ThrowMSLException(OptionError,"UnrecognizedGravityType",
897 value);
898 draw_info->gravity=(GravityType) option;
899 break;
900 }
901 ThrowMSLException(OptionError,"UnrecognizedAttribute",
902 keyword);
903 break;
904 }
905 case 'P':
906 case 'p':
907 {
908 if (LocaleCompare(keyword,"pointsize") == 0)
909 {
cristyc1acd842011-05-19 23:05:47 +0000910 draw_info->pointsize=InterpretLocaleValue(value,
911 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000912 break;
913 }
914 ThrowMSLException(OptionError,"UnrecognizedAttribute",
915 keyword);
916 break;
917 }
918 case 'R':
919 case 'r':
920 {
921 if (LocaleCompare(keyword,"rotate") == 0)
922 {
cristyc1acd842011-05-19 23:05:47 +0000923 angle=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000924 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
925 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
926 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
927 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
928 break;
929 }
930 ThrowMSLException(OptionError,"UnrecognizedAttribute",
931 keyword);
932 break;
933 }
934 case 'S':
935 case 's':
936 {
937 if (LocaleCompare(keyword,"scale") == 0)
938 {
939 flags=ParseGeometry(value,&geometry_info);
940 if ((flags & SigmaValue) == 0)
941 geometry_info.sigma=1.0;
942 affine.sx=geometry_info.rho;
943 affine.sy=geometry_info.sigma;
944 break;
945 }
946 if (LocaleCompare(keyword,"skewX") == 0)
947 {
cristyc1acd842011-05-19 23:05:47 +0000948 angle=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000949 affine.ry=tan(DegreesToRadians(fmod((double) angle,
950 360.0)));
951 break;
952 }
953 if (LocaleCompare(keyword,"skewY") == 0)
954 {
cristyc1acd842011-05-19 23:05:47 +0000955 angle=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000956 affine.rx=tan(DegreesToRadians(fmod((double) angle,
957 360.0)));
958 break;
959 }
960 if (LocaleCompare(keyword,"stretch") == 0)
961 {
cristy9950d572011-10-01 18:22:35 +0000962 option=ParseCommandOption(MagickStretchOptions,
963 MagickFalse,value);
cristy3ed852e2009-09-05 21:47:34 +0000964 if (option < 0)
965 ThrowMSLException(OptionError,"UnrecognizedStretchType",
966 value);
967 draw_info->stretch=(StretchType) option;
968 break;
969 }
970 if (LocaleCompare(keyword, "stroke") == 0)
971 {
cristy9950d572011-10-01 18:22:35 +0000972 (void) QueryColorCompliance(value,AllCompliance,
973 &draw_info->stroke,&exception);
cristy3ed852e2009-09-05 21:47:34 +0000974 break;
975 }
976 if (LocaleCompare(keyword,"strokewidth") == 0)
977 {
cristyf2f27272009-12-17 14:48:46 +0000978 draw_info->stroke_width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +0000979 break;
980 }
981 if (LocaleCompare(keyword,"style") == 0)
982 {
cristy042ee782011-04-22 18:48:30 +0000983 option=ParseCommandOption(MagickStyleOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +0000984 value);
985 if (option < 0)
986 ThrowMSLException(OptionError,"UnrecognizedStyleType",
987 value);
988 draw_info->style=(StyleType) option;
989 break;
990 }
991 ThrowMSLException(OptionError,"UnrecognizedAttribute",
992 keyword);
993 break;
994 }
995 case 'T':
996 case 't':
997 {
998 if (LocaleCompare(keyword,"text") == 0)
999 {
1000 CloneString(&draw_info->text,value);
1001 break;
1002 }
1003 if (LocaleCompare(keyword,"translate") == 0)
1004 {
1005 flags=ParseGeometry(value,&geometry_info);
1006 if ((flags & SigmaValue) == 0)
1007 geometry_info.sigma=1.0;
1008 affine.tx=geometry_info.rho;
1009 affine.ty=geometry_info.sigma;
1010 break;
1011 }
1012 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1013 keyword);
1014 break;
1015 }
1016 case 'U':
1017 case 'u':
1018 {
1019 if (LocaleCompare(keyword, "undercolor") == 0)
1020 {
cristy9950d572011-10-01 18:22:35 +00001021 (void) QueryColorCompliance(value,AllCompliance,
1022 &draw_info->undercolor,&exception);
cristy3ed852e2009-09-05 21:47:34 +00001023 break;
1024 }
1025 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1026 keyword);
1027 break;
1028 }
1029 case 'W':
1030 case 'w':
1031 {
1032 if (LocaleCompare(keyword,"weight") == 0)
1033 {
cristyf2f27272009-12-17 14:48:46 +00001034 draw_info->weight=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001035 break;
1036 }
1037 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1038 keyword);
1039 break;
1040 }
1041 case 'X':
1042 case 'x':
1043 {
1044 if (LocaleCompare(keyword,"x") == 0)
1045 {
cristyf2f27272009-12-17 14:48:46 +00001046 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001047 break;
1048 }
1049 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1050 keyword);
1051 break;
1052 }
1053 case 'Y':
1054 case 'y':
1055 {
1056 if (LocaleCompare(keyword,"y") == 0)
1057 {
cristyf2f27272009-12-17 14:48:46 +00001058 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001059 break;
1060 }
1061 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1062 keyword);
1063 break;
1064 }
1065 default:
1066 {
1067 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1068 keyword);
1069 break;
1070 }
1071 }
1072 }
cristyb51dff52011-05-19 16:55:47 +00001073 (void) FormatLocaleString(text,MaxTextExtent,
cristye8c25f92010-06-03 00:53:06 +00001074 "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,(double)
1075 geometry.height,(double) geometry.x,(double) geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00001076 CloneString(&draw_info->geometry,text);
cristyef7c8a52010-10-10 13:46:51 +00001077 draw_info->affine.sx=affine.sx*current.sx+affine.ry*current.rx;
1078 draw_info->affine.rx=affine.rx*current.sx+affine.sy*current.rx;
1079 draw_info->affine.ry=affine.sx*current.ry+affine.ry*current.sy;
1080 draw_info->affine.sy=affine.rx*current.ry+affine.sy*current.sy;
1081 draw_info->affine.tx=affine.sx*current.tx+affine.ry*current.ty+
1082 affine.tx;
1083 draw_info->affine.ty=affine.rx*current.tx+affine.sy*current.ty+
1084 affine.ty;
cristy5cbc0162011-08-29 00:36:28 +00001085 (void) AnnotateImage(msl_info->image[n],draw_info,
1086 &msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00001087 draw_info=DestroyDrawInfo(draw_info);
1088 break;
1089 }
cristyb988fe72009-09-16 01:01:10 +00001090 if (LocaleCompare((const char *) tag,"append") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001091 {
1092 Image
1093 *append_image;
1094
1095 MagickBooleanType
1096 stack;
cristyb988fe72009-09-16 01:01:10 +00001097
cristy3ed852e2009-09-05 21:47:34 +00001098 if (msl_info->image[n] == (Image *) NULL)
1099 {
cristyb988fe72009-09-16 01:01:10 +00001100 ThrowMSLException(OptionError,"NoImagesDefined",
1101 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001102 break;
1103 }
1104 stack=MagickFalse;
1105 if (attributes != (const xmlChar **) NULL)
1106 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1107 {
1108 keyword=(const char *) attributes[i++];
1109 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00001110 msl_info->attributes[n],(const char *) attributes[i],
1111 &exception);
cristy3ed852e2009-09-05 21:47:34 +00001112 CloneString(&value,attribute);
1113 switch (*keyword)
1114 {
1115 case 'S':
1116 case 's':
1117 {
1118 if (LocaleCompare(keyword,"stack") == 0)
1119 {
cristy042ee782011-04-22 18:48:30 +00001120 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00001121 value);
1122 if (option < 0)
1123 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
1124 value);
1125 stack=(MagickBooleanType) option;
1126 break;
1127 }
1128 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1129 keyword);
1130 break;
1131 }
1132 default:
1133 {
1134 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1135 keyword);
1136 break;
1137 }
1138 }
1139 }
1140 append_image=AppendImages(msl_info->image[n],stack,
1141 &msl_info->image[n]->exception);
1142 if (append_image == (Image *) NULL)
1143 break;
1144 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1145 msl_info->image[n]=append_image;
1146 break;
1147 }
1148 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
1149 break;
1150 }
1151 case 'B':
1152 case 'b':
1153 {
cristyb988fe72009-09-16 01:01:10 +00001154 if (LocaleCompare((const char *) tag,"blur") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001155 {
1156 Image
1157 *blur_image;
1158
1159 /*
1160 Blur image.
1161 */
1162 if (msl_info->image[n] == (Image *) NULL)
1163 {
cristyb988fe72009-09-16 01:01:10 +00001164 ThrowMSLException(OptionError,"NoImagesDefined",
1165 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001166 break;
1167 }
1168 if (attributes != (const xmlChar **) NULL)
1169 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1170 {
1171 keyword=(const char *) attributes[i++];
1172 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00001173 msl_info->attributes[n],(const char *) attributes[i],
1174 &exception);
cristy3ed852e2009-09-05 21:47:34 +00001175 CloneString(&value,attribute);
1176 switch (*keyword)
1177 {
1178 case 'C':
1179 case 'c':
1180 {
1181 if (LocaleCompare(keyword,"channel") == 0)
1182 {
1183 option=ParseChannelOption(value);
1184 if (option < 0)
1185 ThrowMSLException(OptionError,"UnrecognizedChannelType",
1186 value);
1187 channel=(ChannelType) option;
1188 break;
1189 }
1190 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1191 keyword);
1192 break;
1193 }
1194 case 'G':
1195 case 'g':
1196 {
1197 if (LocaleCompare(keyword,"geometry") == 0)
1198 {
1199 flags=ParseGeometry(value,&geometry_info);
1200 if ((flags & SigmaValue) == 0)
1201 geometry_info.sigma=1.0;
1202 break;
1203 }
1204 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1205 keyword);
1206 break;
1207 }
1208 case 'R':
1209 case 'r':
1210 {
1211 if (LocaleCompare(keyword,"radius") == 0)
1212 {
cristyc1acd842011-05-19 23:05:47 +00001213 geometry_info.rho=InterpretLocaleValue(value,
1214 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00001215 break;
1216 }
1217 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1218 keyword);
1219 break;
1220 }
1221 case 'S':
1222 case 's':
1223 {
1224 if (LocaleCompare(keyword,"sigma") == 0)
1225 {
cristyf2f27272009-12-17 14:48:46 +00001226 geometry_info.sigma=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001227 break;
1228 }
1229 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1230 keyword);
1231 break;
1232 }
1233 default:
1234 {
1235 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1236 keyword);
1237 break;
1238 }
1239 }
1240 }
cristybd5a96c2011-08-21 00:04:26 +00001241 channel_mask=SetPixelChannelMask(msl_info->image[n],channel);
cristyf4ad9df2011-07-08 16:49:03 +00001242 blur_image=BlurImage(msl_info->image[n],geometry_info.rho,
cristy05c0c9a2011-09-05 23:16:13 +00001243 geometry_info.sigma,geometry_info.xi,
1244 &msl_info->image[n]->exception);
cristybd5a96c2011-08-21 00:04:26 +00001245 (void) SetPixelChannelMap(msl_info->image[n],channel_mask);
cristy3ed852e2009-09-05 21:47:34 +00001246 if (blur_image == (Image *) NULL)
1247 break;
1248 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1249 msl_info->image[n]=blur_image;
1250 break;
1251 }
cristyb988fe72009-09-16 01:01:10 +00001252 if (LocaleCompare((const char *) tag,"border") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001253 {
1254 Image
1255 *border_image;
1256
1257 /*
1258 Border image.
1259 */
1260 if (msl_info->image[n] == (Image *) NULL)
1261 {
cristyb988fe72009-09-16 01:01:10 +00001262 ThrowMSLException(OptionError,"NoImagesDefined",
1263 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001264 break;
1265 }
1266 SetGeometry(msl_info->image[n],&geometry);
1267 if (attributes != (const xmlChar **) NULL)
1268 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1269 {
1270 keyword=(const char *) attributes[i++];
1271 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00001272 msl_info->attributes[n],(const char *) attributes[i],
1273 &exception);
cristy3ed852e2009-09-05 21:47:34 +00001274 CloneString(&value,attribute);
1275 switch (*keyword)
1276 {
1277 case 'C':
1278 case 'c':
1279 {
1280 if (LocaleCompare(keyword,"compose") == 0)
1281 {
cristy042ee782011-04-22 18:48:30 +00001282 option=ParseCommandOption(MagickComposeOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00001283 value);
1284 if (option < 0)
1285 ThrowMSLException(OptionError,"UnrecognizedComposeType",
1286 value);
1287 msl_info->image[n]->compose=(CompositeOperator) option;
1288 break;
1289 }
1290 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1291 keyword);
1292 break;
1293 }
1294 case 'F':
1295 case 'f':
1296 {
1297 if (LocaleCompare(keyword, "fill") == 0)
1298 {
cristy9950d572011-10-01 18:22:35 +00001299 (void) QueryColorCompliance(value,AllCompliance,
cristy3ed852e2009-09-05 21:47:34 +00001300 &msl_info->image[n]->border_color,&exception);
1301 break;
1302 }
1303 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1304 keyword);
1305 break;
1306 }
1307 case 'G':
1308 case 'g':
1309 {
1310 if (LocaleCompare(keyword,"geometry") == 0)
1311 {
1312 flags=ParsePageGeometry(msl_info->image[n],value,
1313 &geometry,&exception);
1314 if ((flags & HeightValue) == 0)
1315 geometry.height=geometry.width;
1316 break;
1317 }
1318 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1319 keyword);
1320 break;
1321 }
1322 case 'H':
1323 case 'h':
1324 {
1325 if (LocaleCompare(keyword,"height") == 0)
1326 {
cristyf2f27272009-12-17 14:48:46 +00001327 geometry.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001328 break;
1329 }
1330 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1331 keyword);
1332 break;
1333 }
1334 case 'W':
1335 case 'w':
1336 {
1337 if (LocaleCompare(keyword,"width") == 0)
1338 {
cristyf2f27272009-12-17 14:48:46 +00001339 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001340 break;
1341 }
1342 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1343 keyword);
1344 break;
1345 }
1346 default:
1347 {
1348 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1349 keyword);
1350 break;
1351 }
1352 }
1353 }
1354 border_image=BorderImage(msl_info->image[n],&geometry,
cristy633f0c62011-09-15 13:27:36 +00001355 msl_info->image[n]->compose,&msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00001356 if (border_image == (Image *) NULL)
1357 break;
1358 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1359 msl_info->image[n]=border_image;
1360 break;
1361 }
1362 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
1363 }
1364 case 'C':
1365 case 'c':
1366 {
cristyb988fe72009-09-16 01:01:10 +00001367 if (LocaleCompare((const char *) tag,"colorize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001368 {
1369 char
cristyc7e6ff62011-10-03 13:46:11 +00001370 blend[MaxTextExtent];
cristy3ed852e2009-09-05 21:47:34 +00001371
1372 Image
1373 *colorize_image;
1374
cristyc7e6ff62011-10-03 13:46:11 +00001375 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00001376 target;
1377
1378 /*
1379 Add noise image.
1380 */
1381 if (msl_info->image[n] == (Image *) NULL)
1382 {
cristyb988fe72009-09-16 01:01:10 +00001383 ThrowMSLException(OptionError,"NoImagesDefined",
1384 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001385 break;
1386 }
cristyc7e6ff62011-10-03 13:46:11 +00001387 GetPixelInfo(msl_info->image[n],&target);
1388 (void) CopyMagickString(blend,"100",MaxTextExtent);
cristy3ed852e2009-09-05 21:47:34 +00001389 if (attributes != (const xmlChar **) NULL)
1390 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1391 {
1392 keyword=(const char *) attributes[i++];
1393 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00001394 msl_info->attributes[n],(const char *) attributes[i],
1395 &exception);
cristy3ed852e2009-09-05 21:47:34 +00001396 CloneString(&value,attribute);
1397 switch (*keyword)
1398 {
cristyc7e6ff62011-10-03 13:46:11 +00001399 case 'B':
1400 case 'b':
cristy3ed852e2009-09-05 21:47:34 +00001401 {
cristyc7e6ff62011-10-03 13:46:11 +00001402 if (LocaleCompare(keyword,"blend") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001403 {
cristyc7e6ff62011-10-03 13:46:11 +00001404 (void) CopyMagickString(blend,value,MaxTextExtent);
cristy3ed852e2009-09-05 21:47:34 +00001405 break;
1406 }
1407 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1408 keyword);
1409 break;
1410 }
cristyc7e6ff62011-10-03 13:46:11 +00001411 case 'F':
1412 case 'f':
cristy3ed852e2009-09-05 21:47:34 +00001413 {
cristyc7e6ff62011-10-03 13:46:11 +00001414 if (LocaleCompare(keyword,"fill") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001415 {
cristyc7e6ff62011-10-03 13:46:11 +00001416 (void) QueryMagickColorCompliance(value,AllCompliance,
1417 &target,&msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00001418 break;
1419 }
1420 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1421 keyword);
1422 break;
1423 }
1424 default:
1425 {
1426 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1427 keyword);
1428 break;
1429 }
1430 }
1431 }
cristyc7e6ff62011-10-03 13:46:11 +00001432 colorize_image=ColorizeImage(msl_info->image[n],blend,&target,
cristy3ed852e2009-09-05 21:47:34 +00001433 &msl_info->image[n]->exception);
1434 if (colorize_image == (Image *) NULL)
1435 break;
1436 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1437 msl_info->image[n]=colorize_image;
1438 break;
1439 }
cristyb988fe72009-09-16 01:01:10 +00001440 if (LocaleCompare((const char *) tag, "charcoal") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001441 {
cristy05c0c9a2011-09-05 23:16:13 +00001442 double bias = 0.0,
1443 radius = 0.0,
cristy3ed852e2009-09-05 21:47:34 +00001444 sigma = 1.0;
1445
1446 if (msl_info->image[n] == (Image *) NULL)
1447 {
cristyb988fe72009-09-16 01:01:10 +00001448 ThrowMSLException(OptionError,"NoImagesDefined",
1449 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001450 break;
1451 }
1452 /*
1453 NOTE: charcoal can have no attributes, since we use all the defaults!
1454 */
1455 if (attributes != (const xmlChar **) NULL)
1456 {
1457 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1458 {
1459 keyword=(const char *) attributes[i++];
1460 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00001461 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00001462 switch (*keyword)
1463 {
cristy05c0c9a2011-09-05 23:16:13 +00001464 case 'B':
1465 case 'b':
1466 {
1467 if (LocaleCompare(keyword, "bias") == 0)
1468 {
1469 bias = InterpretLocaleValue(value,(char **) NULL);
1470 break;
1471 }
1472 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
1473 break;
1474 }
cristy3ed852e2009-09-05 21:47:34 +00001475 case 'R':
1476 case 'r':
1477 {
1478 if (LocaleCompare(keyword, "radius") == 0)
1479 {
cristyc1acd842011-05-19 23:05:47 +00001480 radius = InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00001481 break;
1482 }
1483 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
1484 break;
1485 }
1486 case 'S':
1487 case 's':
1488 {
1489 if (LocaleCompare(keyword,"sigma") == 0)
1490 {
cristyf2f27272009-12-17 14:48:46 +00001491 sigma = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00001492 break;
1493 }
1494 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
1495 break;
1496 }
1497 default:
1498 {
1499 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
1500 break;
1501 }
1502 }
1503 }
1504 }
1505
1506 /*
1507 charcoal image.
1508 */
1509 {
1510 Image
1511 *newImage;
1512
cristy05c0c9a2011-09-05 23:16:13 +00001513 newImage=CharcoalImage(msl_info->image[n],radius,sigma,bias,
cristy3ed852e2009-09-05 21:47:34 +00001514 &msl_info->image[n]->exception);
1515 if (newImage == (Image *) NULL)
1516 break;
1517 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1518 msl_info->image[n]=newImage;
1519 break;
1520 }
1521 }
cristyb988fe72009-09-16 01:01:10 +00001522 if (LocaleCompare((const char *) tag,"chop") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001523 {
1524 Image
1525 *chop_image;
1526
1527 /*
1528 Chop image.
1529 */
1530 if (msl_info->image[n] == (Image *) NULL)
1531 {
cristyb988fe72009-09-16 01:01:10 +00001532 ThrowMSLException(OptionError,"NoImagesDefined",
1533 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001534 break;
1535 }
1536 SetGeometry(msl_info->image[n],&geometry);
1537 if (attributes != (const xmlChar **) NULL)
1538 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1539 {
1540 keyword=(const char *) attributes[i++];
1541 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00001542 msl_info->attributes[n],(const char *) attributes[i],
1543 &exception);
cristy3ed852e2009-09-05 21:47:34 +00001544 CloneString(&value,attribute);
1545 switch (*keyword)
1546 {
1547 case 'G':
1548 case 'g':
1549 {
1550 if (LocaleCompare(keyword,"geometry") == 0)
1551 {
1552 flags=ParsePageGeometry(msl_info->image[n],value,
1553 &geometry,&exception);
1554 if ((flags & HeightValue) == 0)
1555 geometry.height=geometry.width;
1556 break;
1557 }
1558 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1559 keyword);
1560 break;
1561 }
1562 case 'H':
1563 case 'h':
1564 {
1565 if (LocaleCompare(keyword,"height") == 0)
1566 {
cristyf2f27272009-12-17 14:48:46 +00001567 geometry.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001568 break;
1569 }
1570 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1571 keyword);
1572 break;
1573 }
1574 case 'W':
1575 case 'w':
1576 {
1577 if (LocaleCompare(keyword,"width") == 0)
1578 {
cristyf2f27272009-12-17 14:48:46 +00001579 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001580 break;
1581 }
1582 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1583 keyword);
1584 break;
1585 }
1586 case 'X':
1587 case 'x':
1588 {
1589 if (LocaleCompare(keyword,"x") == 0)
1590 {
cristyf2f27272009-12-17 14:48:46 +00001591 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001592 break;
1593 }
1594 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1595 keyword);
1596 break;
1597 }
1598 case 'Y':
1599 case 'y':
1600 {
1601 if (LocaleCompare(keyword,"y") == 0)
1602 {
cristyf2f27272009-12-17 14:48:46 +00001603 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001604 break;
1605 }
1606 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1607 keyword);
1608 break;
1609 }
1610 default:
1611 {
1612 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1613 keyword);
1614 break;
1615 }
1616 }
1617 }
1618 chop_image=ChopImage(msl_info->image[n],&geometry,
1619 &msl_info->image[n]->exception);
1620 if (chop_image == (Image *) NULL)
1621 break;
1622 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1623 msl_info->image[n]=chop_image;
1624 break;
1625 }
cristyb988fe72009-09-16 01:01:10 +00001626 if (LocaleCompare((const char *) tag,"color-floodfill") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001627 {
1628 PaintMethod
1629 paint_method;
1630
cristy4c08aed2011-07-01 19:47:50 +00001631 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00001632 target;
1633
1634 /*
1635 Color floodfill image.
1636 */
1637 if (msl_info->image[n] == (Image *) NULL)
1638 {
cristyb988fe72009-09-16 01:01:10 +00001639 ThrowMSLException(OptionError,"NoImagesDefined",
1640 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001641 break;
1642 }
1643 draw_info=CloneDrawInfo(msl_info->image_info[n],
1644 msl_info->draw_info[n]);
1645 SetGeometry(msl_info->image[n],&geometry);
1646 paint_method=FloodfillMethod;
1647 if (attributes != (const xmlChar **) NULL)
1648 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1649 {
1650 keyword=(const char *) attributes[i++];
1651 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00001652 msl_info->attributes[n],(const char *) attributes[i],
1653 &exception);
cristy3ed852e2009-09-05 21:47:34 +00001654 CloneString(&value,attribute);
1655 switch (*keyword)
1656 {
1657 case 'B':
1658 case 'b':
1659 {
1660 if (LocaleCompare(keyword,"bordercolor") == 0)
1661 {
cristy9950d572011-10-01 18:22:35 +00001662 (void) QueryMagickColorCompliance(value,AllCompliance,
1663 &target,&exception);
cristy3ed852e2009-09-05 21:47:34 +00001664 paint_method=FillToBorderMethod;
1665 break;
1666 }
1667 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1668 keyword);
1669 break;
1670 }
1671 case 'F':
1672 case 'f':
1673 {
1674 if (LocaleCompare(keyword,"fill") == 0)
1675 {
cristy9950d572011-10-01 18:22:35 +00001676 (void) QueryColorCompliance(value,AllCompliance,
1677 &draw_info->fill,&exception);
cristy3ed852e2009-09-05 21:47:34 +00001678 break;
1679 }
1680 if (LocaleCompare(keyword,"fuzz") == 0)
1681 {
cristyc1acd842011-05-19 23:05:47 +00001682 msl_info->image[n]->fuzz=InterpretLocaleValue(value,
1683 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00001684 break;
1685 }
1686 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1687 keyword);
1688 break;
1689 }
1690 case 'G':
1691 case 'g':
1692 {
1693 if (LocaleCompare(keyword,"geometry") == 0)
1694 {
1695 flags=ParsePageGeometry(msl_info->image[n],value,
1696 &geometry,&exception);
1697 if ((flags & HeightValue) == 0)
1698 geometry.height=geometry.width;
1699 (void) GetOneVirtualMagickPixel(msl_info->image[n],
1700 geometry.x,geometry.y,&target,&exception);
1701 break;
1702 }
1703 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1704 keyword);
1705 break;
1706 }
1707 case 'X':
1708 case 'x':
1709 {
1710 if (LocaleCompare(keyword,"x") == 0)
1711 {
cristyf2f27272009-12-17 14:48:46 +00001712 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001713 (void) GetOneVirtualMagickPixel(msl_info->image[n],
1714 geometry.x,geometry.y,&target,&exception);
1715 break;
1716 }
1717 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1718 keyword);
1719 break;
1720 }
1721 case 'Y':
1722 case 'y':
1723 {
1724 if (LocaleCompare(keyword,"y") == 0)
1725 {
cristyf2f27272009-12-17 14:48:46 +00001726 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001727 (void) GetOneVirtualMagickPixel(msl_info->image[n],
1728 geometry.x,geometry.y,&target,&exception);
1729 break;
1730 }
1731 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1732 keyword);
1733 break;
1734 }
1735 default:
1736 {
1737 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1738 keyword);
1739 break;
1740 }
1741 }
1742 }
cristyd42d9952011-07-08 14:21:50 +00001743 (void) FloodfillPaintImage(msl_info->image[n],draw_info,&target,
1744 geometry.x,geometry.y,paint_method == FloodfillMethod ?
cristy189e84c2011-08-27 18:08:53 +00001745 MagickFalse : MagickTrue,&msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00001746 draw_info=DestroyDrawInfo(draw_info);
1747 break;
1748 }
cristyb988fe72009-09-16 01:01:10 +00001749 if (LocaleCompare((const char *) tag,"comment") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001750 break;
cristyb988fe72009-09-16 01:01:10 +00001751 if (LocaleCompare((const char *) tag,"composite") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001752 {
1753 char
1754 composite_geometry[MaxTextExtent];
1755
1756 CompositeOperator
1757 compose;
1758
1759 Image
1760 *composite_image,
1761 *rotate_image;
1762
cristy3ed852e2009-09-05 21:47:34 +00001763 /*
1764 Composite image.
1765 */
1766 if (msl_info->image[n] == (Image *) NULL)
1767 {
cristyb988fe72009-09-16 01:01:10 +00001768 ThrowMSLException(OptionError,"NoImagesDefined",
1769 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001770 break;
1771 }
1772 composite_image=NewImageList();
1773 compose=OverCompositeOp;
1774 if (attributes != (const xmlChar **) NULL)
1775 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1776 {
1777 keyword=(const char *) attributes[i++];
1778 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00001779 msl_info->attributes[n],(const char *) attributes[i],
1780 &exception);
cristy3ed852e2009-09-05 21:47:34 +00001781 CloneString(&value,attribute);
1782 switch (*keyword)
1783 {
1784 case 'C':
1785 case 'c':
1786 {
1787 if (LocaleCompare(keyword,"compose") == 0)
1788 {
cristy2ed42f62011-10-02 19:49:57 +00001789 option=ParseCommandOption(MagickComposeOptions,
1790 MagickFalse,value);
cristy3ed852e2009-09-05 21:47:34 +00001791 if (option < 0)
1792 ThrowMSLException(OptionError,"UnrecognizedComposeType",
1793 value);
1794 compose=(CompositeOperator) option;
1795 break;
1796 }
1797 break;
1798 }
1799 case 'I':
1800 case 'i':
1801 {
1802 if (LocaleCompare(keyword,"image") == 0)
1803 for (j=0; j < msl_info->n; j++)
1804 {
1805 const char
1806 *attribute;
cristyb988fe72009-09-16 01:01:10 +00001807
cristy3ed852e2009-09-05 21:47:34 +00001808 attribute=GetImageProperty(msl_info->attributes[j],"id");
1809 if ((attribute != (const char *) NULL) &&
1810 (LocaleCompare(attribute,value) == 0))
1811 {
1812 composite_image=CloneImage(msl_info->image[j],0,0,
1813 MagickFalse,&exception);
1814 break;
1815 }
1816 }
1817 break;
1818 }
1819 default:
1820 break;
1821 }
1822 }
1823 if (composite_image == (Image *) NULL)
1824 break;
1825 rotate_image=NewImageList();
1826 SetGeometry(msl_info->image[n],&geometry);
1827 if (attributes != (const xmlChar **) NULL)
1828 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1829 {
1830 keyword=(const char *) attributes[i++];
1831 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00001832 msl_info->attributes[n],(const char *) attributes[i],
1833 &exception);
cristy3ed852e2009-09-05 21:47:34 +00001834 CloneString(&value,attribute);
1835 switch (*keyword)
1836 {
1837 case 'B':
1838 case 'b':
1839 {
1840 if (LocaleCompare(keyword,"blend") == 0)
1841 {
1842 (void) SetImageArtifact(composite_image,
1843 "compose:args",value);
1844 break;
1845 }
1846 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1847 keyword);
1848 break;
1849 }
1850 case 'C':
1851 case 'c':
1852 {
1853 if (LocaleCompare(keyword,"channel") == 0)
1854 {
1855 option=ParseChannelOption(value);
1856 if (option < 0)
1857 ThrowMSLException(OptionError,"UnrecognizedChannelType",
1858 value);
1859 channel=(ChannelType) option;
1860 break;
1861 }
1862 if (LocaleCompare(keyword, "color") == 0)
1863 {
cristy9950d572011-10-01 18:22:35 +00001864 (void) QueryColorCompliance(value,AllCompliance,
cristy3ed852e2009-09-05 21:47:34 +00001865 &composite_image->background_color,&exception);
1866 break;
1867 }
1868 if (LocaleCompare(keyword,"compose") == 0)
1869 break;
1870 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1871 keyword);
1872 break;
1873 }
1874 case 'G':
1875 case 'g':
1876 {
1877 if (LocaleCompare(keyword,"geometry") == 0)
1878 {
1879 flags=ParsePageGeometry(msl_info->image[n],value,
1880 &geometry,&exception);
1881 if ((flags & HeightValue) == 0)
1882 geometry.height=geometry.width;
cristy3ed852e2009-09-05 21:47:34 +00001883 break;
1884 }
1885 if (LocaleCompare(keyword,"gravity") == 0)
1886 {
cristy2ed42f62011-10-02 19:49:57 +00001887 option=ParseCommandOption(MagickGravityOptions,
1888 MagickFalse,value);
cristy3ed852e2009-09-05 21:47:34 +00001889 if (option < 0)
1890 ThrowMSLException(OptionError,"UnrecognizedGravityType",
1891 value);
1892 msl_info->image[n]->gravity=(GravityType) option;
1893 break;
1894 }
1895 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1896 keyword);
1897 break;
1898 }
1899 case 'I':
1900 case 'i':
1901 {
1902 if (LocaleCompare(keyword,"image") == 0)
1903 break;
1904 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1905 keyword);
1906 break;
1907 }
1908 case 'M':
1909 case 'm':
1910 {
1911 if (LocaleCompare(keyword,"mask") == 0)
1912 for (j=0; j < msl_info->n; j++)
1913 {
1914 const char
1915 *attribute;
1916
1917 attribute=GetImageProperty(msl_info->attributes[j],"id");
1918 if ((attribute != (const char *) NULL) &&
1919 (LocaleCompare(value,value) == 0))
1920 {
cristy018f07f2011-09-04 21:15:19 +00001921 SetImageType(composite_image,TrueColorMatteType,
1922 &exception);
cristy3ed852e2009-09-05 21:47:34 +00001923 (void) CompositeImage(composite_image,
1924 CopyOpacityCompositeOp,msl_info->image[j],0,0);
1925 break;
1926 }
1927 }
1928 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1929 keyword);
1930 break;
1931 }
1932 case 'O':
1933 case 'o':
1934 {
1935 if (LocaleCompare(keyword,"opacity") == 0)
1936 {
cristybb503372010-05-27 20:51:26 +00001937 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001938 opacity,
1939 y;
cristyb988fe72009-09-16 01:01:10 +00001940
cristybb503372010-05-27 20:51:26 +00001941 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001942 x;
cristyb988fe72009-09-16 01:01:10 +00001943
cristy4c08aed2011-07-01 19:47:50 +00001944 register Quantum
cristy3ed852e2009-09-05 21:47:34 +00001945 *q;
cristyb988fe72009-09-16 01:01:10 +00001946
cristy3ed852e2009-09-05 21:47:34 +00001947 CacheView
1948 *composite_view;
1949
cristy4c08aed2011-07-01 19:47:50 +00001950 opacity=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001951 if (compose != DissolveCompositeOp)
1952 {
cristyb6a294d2011-10-03 00:55:17 +00001953 (void) SetImageAlpha(composite_image,(Quantum)
cristyb988fe72009-09-16 01:01:10 +00001954 opacity);
cristy3ed852e2009-09-05 21:47:34 +00001955 break;
1956 }
1957 (void) SetImageArtifact(msl_info->image[n],
1958 "compose:args",value);
1959 if (composite_image->matte != MagickTrue)
cristyb6a294d2011-10-03 00:55:17 +00001960 (void) SetImageAlpha(composite_image,OpaqueAlpha);
cristy3ed852e2009-09-05 21:47:34 +00001961 composite_view=AcquireCacheView(composite_image);
cristybb503372010-05-27 20:51:26 +00001962 for (y=0; y < (ssize_t) composite_image->rows ; y++)
cristyb988fe72009-09-16 01:01:10 +00001963 {
cristy4c08aed2011-07-01 19:47:50 +00001964 q=GetCacheViewAuthenticPixels(composite_view,0,y,
1965 (ssize_t) composite_image->columns,1,&exception);
cristybb503372010-05-27 20:51:26 +00001966 for (x=0; x < (ssize_t) composite_image->columns; x++)
cristyb988fe72009-09-16 01:01:10 +00001967 {
cristy4c08aed2011-07-01 19:47:50 +00001968 if (GetPixelAlpha(composite_image,q) == OpaqueAlpha)
1969 SetPixelAlpha(composite_image,
1970 ClampToQuantum(opacity),q);
cristyed231572011-07-14 02:18:59 +00001971 q+=GetPixelChannels(composite_image);
cristy3ed852e2009-09-05 21:47:34 +00001972 }
1973 if (SyncCacheViewAuthenticPixels(composite_view,&exception) == MagickFalse)
1974 break;
1975 }
1976 composite_view=DestroyCacheView(composite_view);
1977 break;
1978 }
1979 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1980 keyword);
1981 break;
1982 }
1983 case 'R':
1984 case 'r':
1985 {
1986 if (LocaleCompare(keyword,"rotate") == 0)
1987 {
cristyc1acd842011-05-19 23:05:47 +00001988 rotate_image=RotateImage(composite_image,
1989 InterpretLocaleValue(value,(char **) NULL),&exception);
cristy3ed852e2009-09-05 21:47:34 +00001990 break;
1991 }
1992 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1993 keyword);
1994 break;
1995 }
1996 case 'T':
1997 case 't':
1998 {
1999 if (LocaleCompare(keyword,"tile") == 0)
2000 {
2001 MagickBooleanType
2002 tile;
2003
cristy042ee782011-04-22 18:48:30 +00002004 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002005 value);
2006 if (option < 0)
2007 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
2008 value);
2009 tile=(MagickBooleanType) option;
cristyda16f162011-02-19 23:52:17 +00002010 (void) tile;
cristy3ed852e2009-09-05 21:47:34 +00002011 if (rotate_image != (Image *) NULL)
2012 (void) SetImageArtifact(rotate_image,
2013 "compose:outside-overlay","false");
2014 else
2015 (void) SetImageArtifact(composite_image,
2016 "compose:outside-overlay","false");
2017 image=msl_info->image[n];
2018 height=composite_image->rows;
2019 width=composite_image->columns;
cristyeaedf062010-05-29 22:36:02 +00002020 for (y=0; y < (ssize_t) image->rows; y+=(ssize_t) height)
2021 for (x=0; x < (ssize_t) image->columns; x+=(ssize_t) width)
cristy3ed852e2009-09-05 21:47:34 +00002022 {
2023 if (rotate_image != (Image *) NULL)
2024 (void) CompositeImage(image,compose,rotate_image,
2025 x,y);
2026 else
2027 (void) CompositeImage(image,compose,
2028 composite_image,x,y);
2029 }
2030 if (rotate_image != (Image *) NULL)
2031 rotate_image=DestroyImage(rotate_image);
2032 break;
2033 }
2034 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2035 keyword);
2036 break;
2037 }
2038 case 'X':
2039 case 'x':
2040 {
2041 if (LocaleCompare(keyword,"x") == 0)
2042 {
cristyf2f27272009-12-17 14:48:46 +00002043 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002044 break;
2045 }
2046 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2047 keyword);
2048 break;
2049 }
2050 case 'Y':
2051 case 'y':
2052 {
2053 if (LocaleCompare(keyword,"y") == 0)
2054 {
cristyf2f27272009-12-17 14:48:46 +00002055 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002056 break;
2057 }
2058 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2059 keyword);
2060 break;
2061 }
2062 default:
2063 {
2064 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2065 keyword);
2066 break;
2067 }
2068 }
2069 }
2070 image=msl_info->image[n];
cristyb51dff52011-05-19 16:55:47 +00002071 (void) FormatLocaleString(composite_geometry,MaxTextExtent,
cristye8c25f92010-06-03 00:53:06 +00002072 "%.20gx%.20g%+.20g%+.20g",(double) composite_image->columns,
2073 (double) composite_image->rows,(double) geometry.x,(double)
cristyf2faecf2010-05-28 19:19:36 +00002074 geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00002075 flags=ParseGravityGeometry(image,composite_geometry,&geometry,
2076 &exception);
cristybd5a96c2011-08-21 00:04:26 +00002077 channel_mask=SetPixelChannelMask(image,channel);
cristy3ed852e2009-09-05 21:47:34 +00002078 if (rotate_image == (Image *) NULL)
cristyf4ad9df2011-07-08 16:49:03 +00002079 CompositeImage(image,compose,composite_image,geometry.x,geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00002080 else
2081 {
2082 /*
2083 Rotate image.
2084 */
cristybb503372010-05-27 20:51:26 +00002085 geometry.x-=(ssize_t) (rotate_image->columns-
cristy3ed852e2009-09-05 21:47:34 +00002086 composite_image->columns)/2;
cristy2ed42f62011-10-02 19:49:57 +00002087 geometry.y-=(ssize_t) (rotate_image->rows-
2088 composite_image->rows)/2;
cristyf4ad9df2011-07-08 16:49:03 +00002089 CompositeImage(image,compose,rotate_image,geometry.x,geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00002090 rotate_image=DestroyImage(rotate_image);
2091 }
cristybd5a96c2011-08-21 00:04:26 +00002092 (void) SetPixelChannelMask(image,channel_mask);
cristy3ed852e2009-09-05 21:47:34 +00002093 composite_image=DestroyImage(composite_image);
2094 break;
2095 }
cristyb988fe72009-09-16 01:01:10 +00002096 if (LocaleCompare((const char *) tag,"contrast") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002097 {
2098 MagickBooleanType
2099 sharpen;
2100
2101 /*
2102 Contrast image.
2103 */
2104 if (msl_info->image[n] == (Image *) NULL)
2105 {
cristyb988fe72009-09-16 01:01:10 +00002106 ThrowMSLException(OptionError,"NoImagesDefined",
2107 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002108 break;
2109 }
2110 sharpen=MagickFalse;
2111 if (attributes != (const xmlChar **) NULL)
2112 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2113 {
2114 keyword=(const char *) attributes[i++];
2115 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002116 msl_info->attributes[n],(const char *) attributes[i],
2117 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002118 CloneString(&value,attribute);
2119 switch (*keyword)
2120 {
2121 case 'S':
2122 case 's':
2123 {
2124 if (LocaleCompare(keyword,"sharpen") == 0)
2125 {
cristy042ee782011-04-22 18:48:30 +00002126 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002127 value);
2128 if (option < 0)
2129 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
2130 value);
2131 sharpen=(MagickBooleanType) option;
2132 break;
2133 }
2134 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2135 keyword);
2136 break;
2137 }
2138 default:
2139 {
2140 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2141 keyword);
2142 break;
2143 }
2144 }
2145 }
cristye23ec9d2011-08-16 18:15:40 +00002146 (void) ContrastImage(msl_info->image[n],sharpen,
2147 &msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00002148 break;
2149 }
cristyb988fe72009-09-16 01:01:10 +00002150 if (LocaleCompare((const char *) tag,"crop") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002151 {
2152 Image
2153 *crop_image;
2154
2155 /*
2156 Crop image.
2157 */
2158 if (msl_info->image[n] == (Image *) NULL)
2159 {
cristyb988fe72009-09-16 01:01:10 +00002160 ThrowMSLException(OptionError,"NoImagesDefined",
2161 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002162 break;
2163 }
2164 SetGeometry(msl_info->image[n],&geometry);
2165 if (attributes != (const xmlChar **) NULL)
2166 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2167 {
2168 keyword=(const char *) attributes[i++];
2169 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002170 msl_info->attributes[n],(const char *) attributes[i],
2171 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002172 CloneString(&value,attribute);
2173 switch (*keyword)
2174 {
2175 case 'G':
2176 case 'g':
2177 {
2178 if (LocaleCompare(keyword,"geometry") == 0)
2179 {
cristy860f4e12011-07-28 19:00:28 +00002180 flags=ParseGravityGeometry(msl_info->image[n],value,
cristy3ed852e2009-09-05 21:47:34 +00002181 &geometry,&exception);
cristy3ed852e2009-09-05 21:47:34 +00002182 break;
2183 }
2184 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2185 keyword);
2186 break;
2187 }
2188 case 'H':
2189 case 'h':
2190 {
2191 if (LocaleCompare(keyword,"height") == 0)
2192 {
cristyf2f27272009-12-17 14:48:46 +00002193 geometry.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002194 break;
2195 }
2196 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2197 keyword);
2198 break;
2199 }
2200 case 'W':
2201 case 'w':
2202 {
2203 if (LocaleCompare(keyword,"width") == 0)
2204 {
cristyf2f27272009-12-17 14:48:46 +00002205 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002206 break;
2207 }
2208 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2209 keyword);
2210 break;
2211 }
2212 case 'X':
2213 case 'x':
2214 {
2215 if (LocaleCompare(keyword,"x") == 0)
2216 {
cristyf2f27272009-12-17 14:48:46 +00002217 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002218 break;
2219 }
2220 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2221 keyword);
2222 break;
2223 }
2224 case 'Y':
2225 case 'y':
2226 {
2227 if (LocaleCompare(keyword,"y") == 0)
2228 {
cristyf2f27272009-12-17 14:48:46 +00002229 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002230 break;
2231 }
2232 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2233 keyword);
2234 break;
2235 }
2236 default:
2237 {
2238 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2239 keyword);
2240 break;
2241 }
2242 }
2243 }
2244 crop_image=CropImage(msl_info->image[n],&geometry,
2245 &msl_info->image[n]->exception);
2246 if (crop_image == (Image *) NULL)
2247 break;
2248 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2249 msl_info->image[n]=crop_image;
2250 break;
2251 }
cristyb988fe72009-09-16 01:01:10 +00002252 if (LocaleCompare((const char *) tag,"cycle-colormap") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002253 {
cristybb503372010-05-27 20:51:26 +00002254 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002255 display;
2256
2257 /*
2258 Cycle-colormap image.
2259 */
2260 if (msl_info->image[n] == (Image *) NULL)
2261 {
cristyb988fe72009-09-16 01:01:10 +00002262 ThrowMSLException(OptionError,"NoImagesDefined",
2263 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002264 break;
2265 }
2266 display=0;
2267 if (attributes != (const xmlChar **) NULL)
2268 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2269 {
2270 keyword=(const char *) attributes[i++];
2271 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002272 msl_info->attributes[n],(const char *) attributes[i],
2273 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002274 CloneString(&value,attribute);
2275 switch (*keyword)
2276 {
2277 case 'D':
2278 case 'd':
2279 {
2280 if (LocaleCompare(keyword,"display") == 0)
2281 {
cristyf2f27272009-12-17 14:48:46 +00002282 display=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002283 break;
2284 }
2285 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2286 keyword);
2287 break;
2288 }
2289 default:
2290 {
2291 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2292 keyword);
2293 break;
2294 }
2295 }
2296 }
cristy018f07f2011-09-04 21:15:19 +00002297 (void) CycleColormapImage(msl_info->image[n],display,&exception);
cristy3ed852e2009-09-05 21:47:34 +00002298 break;
2299 }
2300 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
2301 }
2302 case 'D':
2303 case 'd':
2304 {
cristyb988fe72009-09-16 01:01:10 +00002305 if (LocaleCompare((const char *) tag,"despeckle") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002306 {
2307 Image
2308 *despeckle_image;
2309
2310 /*
2311 Despeckle image.
2312 */
2313 if (msl_info->image[n] == (Image *) NULL)
2314 {
cristyb988fe72009-09-16 01:01:10 +00002315 ThrowMSLException(OptionError,"NoImagesDefined",
2316 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002317 break;
2318 }
2319 if (attributes != (const xmlChar **) NULL)
2320 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2321 {
2322 keyword=(const char *) attributes[i++];
2323 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002324 msl_info->attributes[n],(const char *) attributes[i],
2325 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002326 CloneString(&value,attribute);
2327 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
2328 }
2329 despeckle_image=DespeckleImage(msl_info->image[n],
2330 &msl_info->image[n]->exception);
2331 if (despeckle_image == (Image *) NULL)
2332 break;
2333 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2334 msl_info->image[n]=despeckle_image;
2335 break;
2336 }
cristyb988fe72009-09-16 01:01:10 +00002337 if (LocaleCompare((const char *) tag,"display") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002338 {
2339 if (msl_info->image[n] == (Image *) NULL)
2340 {
cristyb988fe72009-09-16 01:01:10 +00002341 ThrowMSLException(OptionError,"NoImagesDefined",
2342 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002343 break;
2344 }
2345 if (attributes != (const xmlChar **) NULL)
2346 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2347 {
2348 keyword=(const char *) attributes[i++];
2349 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002350 msl_info->attributes[n],(const char *) attributes[i],
2351 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002352 CloneString(&value,attribute);
2353 switch (*keyword)
2354 {
2355 default:
2356 {
2357 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2358 keyword);
2359 break;
2360 }
2361 }
2362 }
cristy051718b2011-08-28 22:49:25 +00002363 (void) DisplayImages(msl_info->image_info[n],msl_info->image[n],
2364 &msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00002365 break;
2366 }
cristyb988fe72009-09-16 01:01:10 +00002367 if (LocaleCompare((const char *) tag,"draw") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002368 {
2369 char
2370 text[MaxTextExtent];
2371
2372 /*
2373 Annotate image.
2374 */
2375 if (msl_info->image[n] == (Image *) NULL)
2376 {
cristyb988fe72009-09-16 01:01:10 +00002377 ThrowMSLException(OptionError,"NoImagesDefined",
2378 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002379 break;
2380 }
2381 draw_info=CloneDrawInfo(msl_info->image_info[n],
2382 msl_info->draw_info[n]);
2383 angle=0.0;
2384 current=draw_info->affine;
2385 GetAffineMatrix(&affine);
2386 if (attributes != (const xmlChar **) NULL)
2387 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2388 {
2389 keyword=(const char *) attributes[i++];
2390 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002391 msl_info->attributes[n],(const char *) attributes[i],
2392 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002393 CloneString(&value,attribute);
2394 switch (*keyword)
2395 {
2396 case 'A':
2397 case 'a':
2398 {
2399 if (LocaleCompare(keyword,"affine") == 0)
2400 {
2401 char
2402 *p;
2403
2404 p=value;
cristyc1acd842011-05-19 23:05:47 +00002405 draw_info->affine.sx=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00002406 if (*p ==',')
2407 p++;
cristyc1acd842011-05-19 23:05:47 +00002408 draw_info->affine.rx=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00002409 if (*p ==',')
2410 p++;
cristyc1acd842011-05-19 23:05:47 +00002411 draw_info->affine.ry=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00002412 if (*p ==',')
2413 p++;
cristyc1acd842011-05-19 23:05:47 +00002414 draw_info->affine.sy=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00002415 if (*p ==',')
2416 p++;
cristyc1acd842011-05-19 23:05:47 +00002417 draw_info->affine.tx=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00002418 if (*p ==',')
2419 p++;
cristyc1acd842011-05-19 23:05:47 +00002420 draw_info->affine.ty=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00002421 break;
2422 }
2423 if (LocaleCompare(keyword,"align") == 0)
2424 {
cristy042ee782011-04-22 18:48:30 +00002425 option=ParseCommandOption(MagickAlignOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002426 value);
2427 if (option < 0)
2428 ThrowMSLException(OptionError,"UnrecognizedAlignType",
2429 value);
2430 draw_info->align=(AlignType) option;
2431 break;
2432 }
2433 if (LocaleCompare(keyword,"antialias") == 0)
2434 {
cristy042ee782011-04-22 18:48:30 +00002435 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002436 value);
2437 if (option < 0)
2438 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
2439 value);
2440 draw_info->stroke_antialias=(MagickBooleanType) option;
2441 draw_info->text_antialias=(MagickBooleanType) option;
2442 break;
2443 }
2444 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2445 keyword);
2446 break;
2447 }
2448 case 'D':
2449 case 'd':
2450 {
2451 if (LocaleCompare(keyword,"density") == 0)
2452 {
2453 CloneString(&draw_info->density,value);
2454 break;
2455 }
2456 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2457 keyword);
2458 break;
2459 }
2460 case 'E':
2461 case 'e':
2462 {
2463 if (LocaleCompare(keyword,"encoding") == 0)
2464 {
2465 CloneString(&draw_info->encoding,value);
2466 break;
2467 }
2468 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2469 keyword);
2470 break;
2471 }
2472 case 'F':
2473 case 'f':
2474 {
2475 if (LocaleCompare(keyword, "fill") == 0)
2476 {
cristy9950d572011-10-01 18:22:35 +00002477 (void) QueryColorCompliance(value,AllCompliance,
2478 &draw_info->fill,&exception);
cristy3ed852e2009-09-05 21:47:34 +00002479 break;
2480 }
2481 if (LocaleCompare(keyword,"family") == 0)
2482 {
2483 CloneString(&draw_info->family,value);
2484 break;
2485 }
2486 if (LocaleCompare(keyword,"font") == 0)
2487 {
2488 CloneString(&draw_info->font,value);
2489 break;
2490 }
2491 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2492 keyword);
2493 break;
2494 }
2495 case 'G':
2496 case 'g':
2497 {
2498 if (LocaleCompare(keyword,"geometry") == 0)
2499 {
2500 flags=ParsePageGeometry(msl_info->image[n],value,
2501 &geometry,&exception);
2502 if ((flags & HeightValue) == 0)
2503 geometry.height=geometry.width;
2504 break;
2505 }
2506 if (LocaleCompare(keyword,"gravity") == 0)
2507 {
cristy042ee782011-04-22 18:48:30 +00002508 option=ParseCommandOption(MagickGravityOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002509 value);
2510 if (option < 0)
2511 ThrowMSLException(OptionError,"UnrecognizedGravityType",
2512 value);
2513 draw_info->gravity=(GravityType) option;
2514 break;
2515 }
2516 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2517 keyword);
2518 break;
2519 }
2520 case 'P':
2521 case 'p':
2522 {
2523 if (LocaleCompare(keyword,"primitive") == 0)
cristyb988fe72009-09-16 01:01:10 +00002524 {
cristy3ed852e2009-09-05 21:47:34 +00002525 CloneString(&draw_info->primitive,value);
2526 break;
2527 }
2528 if (LocaleCompare(keyword,"pointsize") == 0)
2529 {
cristyc1acd842011-05-19 23:05:47 +00002530 draw_info->pointsize=InterpretLocaleValue(value,
2531 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002532 break;
2533 }
2534 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2535 keyword);
2536 break;
2537 }
2538 case 'R':
2539 case 'r':
2540 {
2541 if (LocaleCompare(keyword,"rotate") == 0)
2542 {
cristyc1acd842011-05-19 23:05:47 +00002543 angle=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002544 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
2545 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
2546 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
2547 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
2548 break;
2549 }
2550 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2551 keyword);
2552 break;
2553 }
2554 case 'S':
2555 case 's':
2556 {
2557 if (LocaleCompare(keyword,"scale") == 0)
2558 {
2559 flags=ParseGeometry(value,&geometry_info);
2560 if ((flags & SigmaValue) == 0)
2561 geometry_info.sigma=1.0;
2562 affine.sx=geometry_info.rho;
2563 affine.sy=geometry_info.sigma;
2564 break;
2565 }
2566 if (LocaleCompare(keyword,"skewX") == 0)
2567 {
cristyc1acd842011-05-19 23:05:47 +00002568 angle=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002569 affine.ry=cos(DegreesToRadians(fmod(angle,360.0)));
2570 break;
2571 }
2572 if (LocaleCompare(keyword,"skewY") == 0)
2573 {
cristyc1acd842011-05-19 23:05:47 +00002574 angle=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002575 affine.rx=cos(DegreesToRadians(fmod(angle,360.0)));
2576 break;
2577 }
2578 if (LocaleCompare(keyword,"stretch") == 0)
2579 {
cristy9950d572011-10-01 18:22:35 +00002580 option=ParseCommandOption(MagickStretchOptions,
2581 MagickFalse,value);
cristy3ed852e2009-09-05 21:47:34 +00002582 if (option < 0)
2583 ThrowMSLException(OptionError,"UnrecognizedStretchType",
2584 value);
2585 draw_info->stretch=(StretchType) option;
2586 break;
2587 }
2588 if (LocaleCompare(keyword, "stroke") == 0)
2589 {
cristy9950d572011-10-01 18:22:35 +00002590 (void) QueryColorCompliance(value,AllCompliance,
2591 &draw_info->stroke,&exception);
cristy3ed852e2009-09-05 21:47:34 +00002592 break;
2593 }
2594 if (LocaleCompare(keyword,"strokewidth") == 0)
2595 {
cristyf2f27272009-12-17 14:48:46 +00002596 draw_info->stroke_width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002597 break;
2598 }
2599 if (LocaleCompare(keyword,"style") == 0)
2600 {
cristy042ee782011-04-22 18:48:30 +00002601 option=ParseCommandOption(MagickStyleOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002602 value);
2603 if (option < 0)
2604 ThrowMSLException(OptionError,"UnrecognizedStyleType",
2605 value);
2606 draw_info->style=(StyleType) option;
2607 break;
2608 }
2609 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2610 keyword);
2611 break;
2612 }
2613 case 'T':
2614 case 't':
2615 {
2616 if (LocaleCompare(keyword,"text") == 0)
2617 {
2618 CloneString(&draw_info->text,value);
2619 break;
2620 }
2621 if (LocaleCompare(keyword,"translate") == 0)
2622 {
2623 flags=ParseGeometry(value,&geometry_info);
2624 if ((flags & SigmaValue) == 0)
2625 geometry_info.sigma=1.0;
2626 affine.tx=geometry_info.rho;
2627 affine.ty=geometry_info.sigma;
2628 break;
2629 }
2630 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2631 keyword);
2632 break;
2633 }
2634 case 'U':
2635 case 'u':
2636 {
2637 if (LocaleCompare(keyword, "undercolor") == 0)
2638 {
cristy9950d572011-10-01 18:22:35 +00002639 (void) QueryColorCompliance(value,AllCompliance,
2640 &draw_info->undercolor,&exception);
cristy3ed852e2009-09-05 21:47:34 +00002641 break;
2642 }
2643 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2644 keyword);
2645 break;
2646 }
2647 case 'W':
2648 case 'w':
2649 {
2650 if (LocaleCompare(keyword,"weight") == 0)
2651 {
cristyf2f27272009-12-17 14:48:46 +00002652 draw_info->weight=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002653 break;
2654 }
2655 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2656 keyword);
2657 break;
2658 }
2659 case 'X':
2660 case 'x':
2661 {
2662 if (LocaleCompare(keyword,"x") == 0)
2663 {
cristyf2f27272009-12-17 14:48:46 +00002664 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002665 break;
2666 }
2667 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2668 keyword);
2669 break;
2670 }
2671 case 'Y':
2672 case 'y':
2673 {
2674 if (LocaleCompare(keyword,"y") == 0)
2675 {
cristyf2f27272009-12-17 14:48:46 +00002676 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002677 break;
2678 }
2679 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2680 keyword);
2681 break;
2682 }
2683 default:
2684 {
2685 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2686 keyword);
2687 break;
2688 }
2689 }
2690 }
cristyb51dff52011-05-19 16:55:47 +00002691 (void) FormatLocaleString(text,MaxTextExtent,
cristye8c25f92010-06-03 00:53:06 +00002692 "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,(double)
2693 geometry.height,(double) geometry.x,(double) geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00002694 CloneString(&draw_info->geometry,text);
cristyef7c8a52010-10-10 13:46:51 +00002695 draw_info->affine.sx=affine.sx*current.sx+affine.ry*current.rx;
2696 draw_info->affine.rx=affine.rx*current.sx+affine.sy*current.rx;
2697 draw_info->affine.ry=affine.sx*current.ry+affine.ry*current.sy;
2698 draw_info->affine.sy=affine.rx*current.ry+affine.sy*current.sy;
2699 draw_info->affine.tx=affine.sx*current.tx+affine.ry*current.ty+
2700 affine.tx;
2701 draw_info->affine.ty=affine.rx*current.tx+affine.sy*current.ty+
2702 affine.ty;
cristy018f07f2011-09-04 21:15:19 +00002703 (void) DrawImage(msl_info->image[n],draw_info,&exception);
cristy3ed852e2009-09-05 21:47:34 +00002704 draw_info=DestroyDrawInfo(draw_info);
2705 break;
2706 }
2707 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
2708 }
2709 case 'E':
2710 case 'e':
2711 {
cristyb988fe72009-09-16 01:01:10 +00002712 if (LocaleCompare((const char *) tag,"edge") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002713 {
2714 Image
2715 *edge_image;
2716
2717 /*
2718 Edge image.
2719 */
2720 if (msl_info->image[n] == (Image *) NULL)
2721 {
cristyb988fe72009-09-16 01:01:10 +00002722 ThrowMSLException(OptionError,"NoImagesDefined",
2723 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002724 break;
2725 }
2726 if (attributes != (const xmlChar **) NULL)
2727 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2728 {
2729 keyword=(const char *) attributes[i++];
2730 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002731 msl_info->attributes[n],(const char *) attributes[i],
2732 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002733 CloneString(&value,attribute);
2734 switch (*keyword)
2735 {
2736 case 'G':
2737 case 'g':
2738 {
2739 if (LocaleCompare(keyword,"geometry") == 0)
2740 {
2741 flags=ParseGeometry(value,&geometry_info);
2742 if ((flags & SigmaValue) == 0)
2743 geometry_info.sigma=1.0;
2744 break;
2745 }
2746 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2747 keyword);
2748 break;
2749 }
2750 case 'R':
2751 case 'r':
2752 {
2753 if (LocaleCompare(keyword,"radius") == 0)
2754 {
cristyc1acd842011-05-19 23:05:47 +00002755 geometry_info.rho=InterpretLocaleValue(value,
2756 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002757 break;
2758 }
2759 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2760 keyword);
2761 break;
2762 }
2763 default:
2764 {
2765 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2766 keyword);
2767 break;
2768 }
2769 }
2770 }
2771 edge_image=EdgeImage(msl_info->image[n],geometry_info.rho,
cristy8ae632d2011-09-05 17:29:53 +00002772 geometry_info.sigma,&msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00002773 if (edge_image == (Image *) NULL)
2774 break;
2775 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2776 msl_info->image[n]=edge_image;
2777 break;
2778 }
cristyb988fe72009-09-16 01:01:10 +00002779 if (LocaleCompare((const char *) tag,"emboss") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002780 {
2781 Image
2782 *emboss_image;
2783
2784 /*
2785 Emboss image.
2786 */
2787 if (msl_info->image[n] == (Image *) NULL)
2788 {
cristyb988fe72009-09-16 01:01:10 +00002789 ThrowMSLException(OptionError,"NoImagesDefined",
2790 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002791 break;
2792 }
2793 if (attributes != (const xmlChar **) NULL)
2794 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2795 {
2796 keyword=(const char *) attributes[i++];
2797 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002798 msl_info->attributes[n],(const char *) attributes[i],
2799 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002800 CloneString(&value,attribute);
2801 switch (*keyword)
2802 {
2803 case 'G':
2804 case 'g':
2805 {
2806 if (LocaleCompare(keyword,"geometry") == 0)
2807 {
2808 flags=ParseGeometry(value,&geometry_info);
2809 if ((flags & SigmaValue) == 0)
2810 geometry_info.sigma=1.0;
2811 break;
2812 }
2813 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2814 keyword);
2815 break;
2816 }
2817 case 'R':
2818 case 'r':
2819 {
2820 if (LocaleCompare(keyword,"radius") == 0)
2821 {
cristyc1acd842011-05-19 23:05:47 +00002822 geometry_info.rho=InterpretLocaleValue(value,
2823 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002824 break;
2825 }
2826 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2827 keyword);
2828 break;
2829 }
2830 case 'S':
2831 case 's':
2832 {
2833 if (LocaleCompare(keyword,"sigma") == 0)
2834 {
cristyf2f27272009-12-17 14:48:46 +00002835 geometry_info.sigma=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002836 break;
2837 }
2838 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2839 keyword);
2840 break;
2841 }
2842 default:
2843 {
2844 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2845 keyword);
2846 break;
2847 }
2848 }
2849 }
2850 emboss_image=EmbossImage(msl_info->image[n],geometry_info.rho,
2851 geometry_info.sigma,&msl_info->image[n]->exception);
2852 if (emboss_image == (Image *) NULL)
2853 break;
2854 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2855 msl_info->image[n]=emboss_image;
2856 break;
2857 }
cristyb988fe72009-09-16 01:01:10 +00002858 if (LocaleCompare((const char *) tag,"enhance") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002859 {
2860 Image
2861 *enhance_image;
2862
2863 /*
2864 Enhance image.
2865 */
2866 if (msl_info->image[n] == (Image *) NULL)
2867 {
cristyb988fe72009-09-16 01:01:10 +00002868 ThrowMSLException(OptionError,"NoImagesDefined",
2869 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002870 break;
2871 }
2872 if (attributes != (const xmlChar **) NULL)
2873 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2874 {
2875 keyword=(const char *) attributes[i++];
2876 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002877 msl_info->attributes[n],(const char *) attributes[i],
2878 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002879 CloneString(&value,attribute);
2880 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
2881 }
2882 enhance_image=EnhanceImage(msl_info->image[n],
2883 &msl_info->image[n]->exception);
2884 if (enhance_image == (Image *) NULL)
2885 break;
2886 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2887 msl_info->image[n]=enhance_image;
2888 break;
2889 }
cristyb988fe72009-09-16 01:01:10 +00002890 if (LocaleCompare((const char *) tag,"equalize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002891 {
2892 /*
2893 Equalize image.
2894 */
2895 if (msl_info->image[n] == (Image *) NULL)
2896 {
cristyb988fe72009-09-16 01:01:10 +00002897 ThrowMSLException(OptionError,"NoImagesDefined",
2898 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002899 break;
2900 }
2901 if (attributes != (const xmlChar **) NULL)
2902 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2903 {
2904 keyword=(const char *) attributes[i++];
2905 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002906 msl_info->attributes[n],(const char *) attributes[i],
2907 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002908 CloneString(&value,attribute);
2909 switch (*keyword)
2910 {
2911 default:
2912 {
2913 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2914 keyword);
2915 break;
2916 }
2917 }
2918 }
cristy6d8c3d72011-08-22 01:20:01 +00002919 (void) EqualizeImage(msl_info->image[n],
2920 &msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00002921 break;
2922 }
2923 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
2924 }
2925 case 'F':
2926 case 'f':
2927 {
cristyb988fe72009-09-16 01:01:10 +00002928 if (LocaleCompare((const char *) tag, "flatten") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002929 {
2930 if (msl_info->image[n] == (Image *) NULL)
2931 {
cristyb988fe72009-09-16 01:01:10 +00002932 ThrowMSLException(OptionError,"NoImagesDefined",
2933 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002934 break;
2935 }
2936
2937 /* no attributes here */
2938
2939 /* process the image */
2940 {
2941 Image
2942 *newImage;
2943
2944 newImage=MergeImageLayers(msl_info->image[n],FlattenLayer,
2945 &msl_info->image[n]->exception);
2946 if (newImage == (Image *) NULL)
2947 break;
2948 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2949 msl_info->image[n]=newImage;
2950 break;
2951 }
2952 }
cristyb988fe72009-09-16 01:01:10 +00002953 if (LocaleCompare((const char *) tag,"flip") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002954 {
2955 Image
2956 *flip_image;
2957
2958 /*
2959 Flip image.
2960 */
2961 if (msl_info->image[n] == (Image *) NULL)
2962 {
cristyb988fe72009-09-16 01:01:10 +00002963 ThrowMSLException(OptionError,"NoImagesDefined",
2964 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002965 break;
2966 }
2967 if (attributes != (const xmlChar **) NULL)
2968 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2969 {
2970 keyword=(const char *) attributes[i++];
2971 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002972 msl_info->attributes[n],(const char *) attributes[i],
2973 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002974 CloneString(&value,attribute);
2975 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
2976 }
2977 flip_image=FlipImage(msl_info->image[n],
2978 &msl_info->image[n]->exception);
2979 if (flip_image == (Image *) NULL)
2980 break;
2981 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2982 msl_info->image[n]=flip_image;
2983 break;
2984 }
cristyb988fe72009-09-16 01:01:10 +00002985 if (LocaleCompare((const char *) tag,"flop") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002986 {
2987 Image
2988 *flop_image;
2989
2990 /*
2991 Flop image.
2992 */
2993 if (msl_info->image[n] == (Image *) NULL)
2994 {
cristyb988fe72009-09-16 01:01:10 +00002995 ThrowMSLException(OptionError,"NoImagesDefined",
2996 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002997 break;
2998 }
2999 if (attributes != (const xmlChar **) NULL)
3000 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3001 {
3002 keyword=(const char *) attributes[i++];
3003 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003004 msl_info->attributes[n],(const char *) attributes[i],
3005 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003006 CloneString(&value,attribute);
3007 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3008 }
3009 flop_image=FlopImage(msl_info->image[n],
3010 &msl_info->image[n]->exception);
3011 if (flop_image == (Image *) NULL)
3012 break;
3013 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3014 msl_info->image[n]=flop_image;
3015 break;
3016 }
cristyb988fe72009-09-16 01:01:10 +00003017 if (LocaleCompare((const char *) tag,"frame") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003018 {
3019 FrameInfo
3020 frame_info;
3021
3022 Image
3023 *frame_image;
3024
3025 /*
3026 Frame image.
3027 */
3028 if (msl_info->image[n] == (Image *) NULL)
3029 {
cristyb988fe72009-09-16 01:01:10 +00003030 ThrowMSLException(OptionError,"NoImagesDefined",
3031 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003032 break;
3033 }
3034 SetGeometry(msl_info->image[n],&geometry);
3035 if (attributes != (const xmlChar **) NULL)
3036 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3037 {
3038 keyword=(const char *) attributes[i++];
3039 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003040 msl_info->attributes[n],(const char *) attributes[i],
3041 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003042 CloneString(&value,attribute);
3043 switch (*keyword)
3044 {
3045 case 'C':
3046 case 'c':
3047 {
3048 if (LocaleCompare(keyword,"compose") == 0)
3049 {
cristy042ee782011-04-22 18:48:30 +00003050 option=ParseCommandOption(MagickComposeOptions,
cristy3ed852e2009-09-05 21:47:34 +00003051 MagickFalse,value);
3052 if (option < 0)
3053 ThrowMSLException(OptionError,"UnrecognizedComposeType",
3054 value);
3055 msl_info->image[n]->compose=(CompositeOperator) option;
3056 break;
3057 }
3058 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3059 keyword);
3060 break;
3061 }
3062 case 'F':
3063 case 'f':
3064 {
3065 if (LocaleCompare(keyword, "fill") == 0)
3066 {
cristy9950d572011-10-01 18:22:35 +00003067 (void) QueryColorCompliance(value,AllCompliance,
cristy3ed852e2009-09-05 21:47:34 +00003068 &msl_info->image[n]->matte_color,&exception);
3069 break;
3070 }
3071 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3072 keyword);
3073 break;
3074 }
3075 case 'G':
3076 case 'g':
3077 {
3078 if (LocaleCompare(keyword,"geometry") == 0)
3079 {
3080 flags=ParsePageGeometry(msl_info->image[n],value,
3081 &geometry,&exception);
3082 if ((flags & HeightValue) == 0)
3083 geometry.height=geometry.width;
3084 frame_info.width=geometry.width;
3085 frame_info.height=geometry.height;
3086 frame_info.outer_bevel=geometry.x;
3087 frame_info.inner_bevel=geometry.y;
3088 break;
3089 }
3090 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3091 keyword);
3092 break;
3093 }
3094 case 'H':
3095 case 'h':
3096 {
3097 if (LocaleCompare(keyword,"height") == 0)
3098 {
cristyf2f27272009-12-17 14:48:46 +00003099 frame_info.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003100 break;
3101 }
3102 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3103 keyword);
3104 break;
3105 }
3106 case 'I':
3107 case 'i':
3108 {
3109 if (LocaleCompare(keyword,"inner") == 0)
3110 {
cristyf2f27272009-12-17 14:48:46 +00003111 frame_info.inner_bevel=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003112 break;
3113 }
3114 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3115 keyword);
3116 break;
3117 }
3118 case 'O':
3119 case 'o':
3120 {
3121 if (LocaleCompare(keyword,"outer") == 0)
3122 {
cristyf2f27272009-12-17 14:48:46 +00003123 frame_info.outer_bevel=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003124 break;
3125 }
3126 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3127 keyword);
3128 break;
3129 }
3130 case 'W':
3131 case 'w':
3132 {
3133 if (LocaleCompare(keyword,"width") == 0)
3134 {
cristyf2f27272009-12-17 14:48:46 +00003135 frame_info.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003136 break;
3137 }
3138 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3139 keyword);
3140 break;
3141 }
3142 default:
3143 {
3144 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3145 keyword);
3146 break;
3147 }
3148 }
3149 }
cristybb503372010-05-27 20:51:26 +00003150 frame_info.x=(ssize_t) frame_info.width;
3151 frame_info.y=(ssize_t) frame_info.height;
cristy3ed852e2009-09-05 21:47:34 +00003152 frame_info.width=msl_info->image[n]->columns+2*frame_info.x;
3153 frame_info.height=msl_info->image[n]->rows+2*frame_info.y;
3154 frame_image=FrameImage(msl_info->image[n],&frame_info,
cristy633f0c62011-09-15 13:27:36 +00003155 msl_info->image[n]->compose,&msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00003156 if (frame_image == (Image *) NULL)
3157 break;
3158 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3159 msl_info->image[n]=frame_image;
3160 break;
3161 }
3162 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3163 }
3164 case 'G':
3165 case 'g':
3166 {
cristyb988fe72009-09-16 01:01:10 +00003167 if (LocaleCompare((const char *) tag,"gamma") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003168 {
3169 char
3170 gamma[MaxTextExtent];
3171
cristy4c08aed2011-07-01 19:47:50 +00003172 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00003173 pixel;
3174
3175 /*
3176 Gamma image.
3177 */
3178 if (msl_info->image[n] == (Image *) NULL)
3179 {
cristyb988fe72009-09-16 01:01:10 +00003180 ThrowMSLException(OptionError,"NoImagesDefined",
3181 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003182 break;
3183 }
3184 channel=UndefinedChannel;
3185 pixel.red=0.0;
3186 pixel.green=0.0;
3187 pixel.blue=0.0;
3188 *gamma='\0';
3189 if (attributes != (const xmlChar **) NULL)
3190 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3191 {
3192 keyword=(const char *) attributes[i++];
3193 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003194 msl_info->attributes[n],(const char *) attributes[i],
3195 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003196 CloneString(&value,attribute);
3197 switch (*keyword)
3198 {
3199 case 'B':
3200 case 'b':
3201 {
3202 if (LocaleCompare(keyword,"blue") == 0)
3203 {
cristyc1acd842011-05-19 23:05:47 +00003204 pixel.blue=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003205 break;
3206 }
3207 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3208 keyword);
3209 break;
3210 }
3211 case 'C':
3212 case 'c':
3213 {
3214 if (LocaleCompare(keyword,"channel") == 0)
3215 {
3216 option=ParseChannelOption(value);
3217 if (option < 0)
3218 ThrowMSLException(OptionError,"UnrecognizedChannelType",
3219 value);
3220 channel=(ChannelType) option;
3221 break;
3222 }
3223 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3224 keyword);
3225 break;
3226 }
3227 case 'G':
3228 case 'g':
3229 {
3230 if (LocaleCompare(keyword,"gamma") == 0)
3231 {
3232 (void) CopyMagickString(gamma,value,MaxTextExtent);
3233 break;
3234 }
3235 if (LocaleCompare(keyword,"green") == 0)
3236 {
cristyc1acd842011-05-19 23:05:47 +00003237 pixel.green=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003238 break;
3239 }
3240 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3241 keyword);
3242 break;
3243 }
3244 case 'R':
3245 case 'r':
3246 {
3247 if (LocaleCompare(keyword,"red") == 0)
3248 {
cristyc1acd842011-05-19 23:05:47 +00003249 pixel.red=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003250 break;
3251 }
3252 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3253 keyword);
3254 break;
3255 }
3256 default:
3257 {
3258 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3259 keyword);
3260 break;
3261 }
3262 }
3263 }
3264 if (*gamma == '\0')
cristyb51dff52011-05-19 16:55:47 +00003265 (void) FormatLocaleString(gamma,MaxTextExtent,"%g,%g,%g",
cristy3ed852e2009-09-05 21:47:34 +00003266 (double) pixel.red,(double) pixel.green,(double) pixel.blue);
cristyb3e7c6c2011-07-24 01:43:55 +00003267 (void) GammaImage(msl_info->image[n],atof(gamma),
3268 &msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00003269 break;
3270 }
cristyb988fe72009-09-16 01:01:10 +00003271 else if (LocaleCompare((const char *) tag,"get") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003272 {
3273 if (msl_info->image[n] == (Image *) NULL)
3274 {
cristyb988fe72009-09-16 01:01:10 +00003275 ThrowMSLException(OptionError,"NoImagesDefined",
3276 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003277 break;
3278 }
3279 if (attributes == (const xmlChar **) NULL)
3280 break;
3281 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3282 {
3283 keyword=(const char *) attributes[i++];
cristyb988fe72009-09-16 01:01:10 +00003284 CloneString(&value,(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003285 (void) CopyMagickString(key,value,MaxTextExtent);
3286 switch (*keyword)
3287 {
3288 case 'H':
3289 case 'h':
3290 {
3291 if (LocaleCompare(keyword,"height") == 0)
3292 {
cristyb51dff52011-05-19 16:55:47 +00003293 (void) FormatLocaleString(value,MaxTextExtent,"%.20g",
cristye8c25f92010-06-03 00:53:06 +00003294 (double) msl_info->image[n]->rows);
cristy3ed852e2009-09-05 21:47:34 +00003295 (void) SetImageProperty(msl_info->attributes[n],key,value);
3296 break;
3297 }
3298 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3299 }
3300 case 'W':
3301 case 'w':
3302 {
3303 if (LocaleCompare(keyword,"width") == 0)
3304 {
cristyb51dff52011-05-19 16:55:47 +00003305 (void) FormatLocaleString(value,MaxTextExtent,"%.20g",
cristye8c25f92010-06-03 00:53:06 +00003306 (double) msl_info->image[n]->columns);
cristy3ed852e2009-09-05 21:47:34 +00003307 (void) SetImageProperty(msl_info->attributes[n],key,value);
3308 break;
3309 }
3310 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3311 }
3312 default:
3313 {
3314 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3315 break;
3316 }
3317 }
3318 }
3319 break;
3320 }
cristyb988fe72009-09-16 01:01:10 +00003321 else if (LocaleCompare((const char *) tag, "group") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003322 {
3323 msl_info->number_groups++;
3324 msl_info->group_info=(MSLGroupInfo *) ResizeQuantumMemory(
3325 msl_info->group_info,msl_info->number_groups+1UL,
3326 sizeof(*msl_info->group_info));
3327 break;
3328 }
3329 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3330 }
3331 case 'I':
3332 case 'i':
3333 {
cristyb988fe72009-09-16 01:01:10 +00003334 if (LocaleCompare((const char *) tag,"image") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003335 {
cristy3ed852e2009-09-05 21:47:34 +00003336 MSLPushImage(msl_info,(Image *) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003337 if (attributes == (const xmlChar **) NULL)
3338 break;
3339 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3340 {
3341 keyword=(const char *) attributes[i++];
3342 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003343 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00003344 switch (*keyword)
3345 {
cristyb988fe72009-09-16 01:01:10 +00003346 case 'C':
3347 case 'c':
cristy3ed852e2009-09-05 21:47:34 +00003348 {
cristyb988fe72009-09-16 01:01:10 +00003349 if (LocaleCompare(keyword,"color") == 0)
3350 {
3351 Image
3352 *next_image;
cristy3ed852e2009-09-05 21:47:34 +00003353
cristyb988fe72009-09-16 01:01:10 +00003354 (void) CopyMagickString(msl_info->image_info[n]->filename,
3355 "xc:",MaxTextExtent);
3356 (void) ConcatenateMagickString(msl_info->image_info[n]->
3357 filename,value,MaxTextExtent);
3358 next_image=ReadImage(msl_info->image_info[n],&exception);
3359 CatchException(&exception);
3360 if (next_image == (Image *) NULL)
3361 continue;
3362 if (msl_info->image[n] == (Image *) NULL)
3363 msl_info->image[n]=next_image;
3364 else
3365 {
3366 register Image
3367 *p;
cristy3ed852e2009-09-05 21:47:34 +00003368
cristyb988fe72009-09-16 01:01:10 +00003369 /*
3370 Link image into image list.
3371 */
3372 p=msl_info->image[n];
3373 while (p->next != (Image *) NULL)
3374 p=GetNextImageInList(p);
3375 next_image->previous=p;
3376 p->next=next_image;
3377 }
3378 break;
3379 }
cristyb20775d2009-09-16 01:51:41 +00003380 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00003381 break;
3382 }
3383 default:
3384 {
cristyb20775d2009-09-16 01:51:41 +00003385 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00003386 break;
3387 }
3388 }
3389 }
3390 break;
3391 }
cristyb988fe72009-09-16 01:01:10 +00003392 if (LocaleCompare((const char *) tag,"implode") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003393 {
3394 Image
3395 *implode_image;
3396
3397 /*
3398 Implode image.
3399 */
3400 if (msl_info->image[n] == (Image *) NULL)
3401 {
cristyb988fe72009-09-16 01:01:10 +00003402 ThrowMSLException(OptionError,"NoImagesDefined",
3403 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003404 break;
3405 }
3406 if (attributes != (const xmlChar **) NULL)
3407 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3408 {
3409 keyword=(const char *) attributes[i++];
3410 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003411 msl_info->attributes[n],(const char *) attributes[i],
3412 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003413 CloneString(&value,attribute);
3414 switch (*keyword)
3415 {
3416 case 'A':
3417 case 'a':
3418 {
3419 if (LocaleCompare(keyword,"amount") == 0)
3420 {
cristyc1acd842011-05-19 23:05:47 +00003421 geometry_info.rho=InterpretLocaleValue(value,
3422 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003423 break;
3424 }
3425 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3426 keyword);
3427 break;
3428 }
3429 case 'G':
3430 case 'g':
3431 {
3432 if (LocaleCompare(keyword,"geometry") == 0)
3433 {
3434 flags=ParseGeometry(value,&geometry_info);
3435 if ((flags & SigmaValue) == 0)
3436 geometry_info.sigma=1.0;
3437 break;
3438 }
3439 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3440 keyword);
3441 break;
3442 }
3443 default:
3444 {
3445 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3446 keyword);
3447 break;
3448 }
3449 }
3450 }
3451 implode_image=ImplodeImage(msl_info->image[n],geometry_info.rho,
cristy76f512e2011-09-12 01:26:56 +00003452 msl_info->image[n]->interpolate,&msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00003453 if (implode_image == (Image *) NULL)
3454 break;
3455 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3456 msl_info->image[n]=implode_image;
3457 break;
3458 }
3459 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3460 }
3461 case 'L':
3462 case 'l':
3463 {
cristyb988fe72009-09-16 01:01:10 +00003464 if (LocaleCompare((const char *) tag,"label") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003465 break;
cristyb988fe72009-09-16 01:01:10 +00003466 if (LocaleCompare((const char *) tag, "level") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003467 {
3468 double
3469 levelBlack = 0, levelGamma = 1, levelWhite = QuantumRange;
3470
3471 if (msl_info->image[n] == (Image *) NULL)
3472 {
cristyb988fe72009-09-16 01:01:10 +00003473 ThrowMSLException(OptionError,"NoImagesDefined",
3474 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003475 break;
3476 }
3477 if (attributes == (const xmlChar **) NULL)
3478 break;
3479 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3480 {
3481 keyword=(const char *) attributes[i++];
cristyb988fe72009-09-16 01:01:10 +00003482 CloneString(&value,(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003483 (void) CopyMagickString(key,value,MaxTextExtent);
3484 switch (*keyword)
3485 {
3486 case 'B':
3487 case 'b':
3488 {
3489 if (LocaleCompare(keyword,"black") == 0)
3490 {
cristyc1acd842011-05-19 23:05:47 +00003491 levelBlack = InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003492 break;
3493 }
3494 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3495 break;
3496 }
3497 case 'G':
3498 case 'g':
3499 {
3500 if (LocaleCompare(keyword,"gamma") == 0)
3501 {
cristyc1acd842011-05-19 23:05:47 +00003502 levelGamma = InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003503 break;
3504 }
3505 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3506 break;
3507 }
3508 case 'W':
3509 case 'w':
3510 {
3511 if (LocaleCompare(keyword,"white") == 0)
3512 {
cristyc1acd842011-05-19 23:05:47 +00003513 levelWhite = InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003514 break;
3515 }
3516 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3517 break;
3518 }
3519 default:
3520 {
3521 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3522 break;
3523 }
3524 }
3525 }
3526
3527 /* process image */
cristy01e9afd2011-08-10 17:38:41 +00003528 LevelImage(msl_info->image[n],levelBlack,levelWhite,levelGamma,
3529 &msl_info->image[n]->exception);
cristyf89cb1d2011-07-07 01:24:37 +00003530 break;
cristy3ed852e2009-09-05 21:47:34 +00003531 }
3532 }
3533 case 'M':
3534 case 'm':
3535 {
cristyb988fe72009-09-16 01:01:10 +00003536 if (LocaleCompare((const char *) tag,"magnify") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003537 {
3538 Image
3539 *magnify_image;
3540
3541 /*
3542 Magnify image.
3543 */
3544 if (msl_info->image[n] == (Image *) NULL)
3545 {
cristyb988fe72009-09-16 01:01:10 +00003546 ThrowMSLException(OptionError,"NoImagesDefined",
3547 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003548 break;
3549 }
3550 if (attributes != (const xmlChar **) NULL)
3551 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3552 {
3553 keyword=(const char *) attributes[i++];
3554 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003555 msl_info->attributes[n],(const char *) attributes[i],
3556 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003557 CloneString(&value,attribute);
3558 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3559 }
3560 magnify_image=MagnifyImage(msl_info->image[n],
3561 &msl_info->image[n]->exception);
3562 if (magnify_image == (Image *) NULL)
3563 break;
3564 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3565 msl_info->image[n]=magnify_image;
3566 break;
3567 }
cristyb988fe72009-09-16 01:01:10 +00003568 if (LocaleCompare((const char *) tag,"map") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003569 {
3570 Image
3571 *affinity_image;
3572
3573 MagickBooleanType
3574 dither;
3575
3576 QuantizeInfo
3577 *quantize_info;
3578
3579 /*
3580 Map image.
3581 */
3582 if (msl_info->image[n] == (Image *) NULL)
3583 {
cristyb988fe72009-09-16 01:01:10 +00003584 ThrowMSLException(OptionError,"NoImagesDefined",
3585 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003586 break;
3587 }
3588 affinity_image=NewImageList();
3589 dither=MagickFalse;
3590 if (attributes != (const xmlChar **) NULL)
3591 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3592 {
3593 keyword=(const char *) attributes[i++];
3594 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003595 msl_info->attributes[n],(const char *) attributes[i],
3596 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003597 CloneString(&value,attribute);
3598 switch (*keyword)
3599 {
3600 case 'D':
3601 case 'd':
3602 {
3603 if (LocaleCompare(keyword,"dither") == 0)
3604 {
cristy042ee782011-04-22 18:48:30 +00003605 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00003606 value);
3607 if (option < 0)
3608 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
3609 value);
3610 dither=(MagickBooleanType) option;
3611 break;
3612 }
3613 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3614 keyword);
3615 break;
3616 }
3617 case 'I':
3618 case 'i':
3619 {
3620 if (LocaleCompare(keyword,"image") == 0)
3621 for (j=0; j < msl_info->n; j++)
3622 {
3623 const char
3624 *attribute;
cristyb988fe72009-09-16 01:01:10 +00003625
cristy3ed852e2009-09-05 21:47:34 +00003626 attribute=GetImageProperty(msl_info->attributes[j],"id");
3627 if ((attribute != (const char *) NULL) &&
3628 (LocaleCompare(attribute,value) == 0))
3629 {
3630 affinity_image=CloneImage(msl_info->image[j],0,0,
3631 MagickFalse,&exception);
3632 break;
3633 }
3634 }
3635 break;
3636 }
3637 default:
3638 {
3639 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3640 keyword);
3641 break;
3642 }
3643 }
3644 }
3645 quantize_info=AcquireQuantizeInfo(msl_info->image_info[n]);
3646 quantize_info->dither=dither;
3647 (void) RemapImages(quantize_info,msl_info->image[n],
cristy018f07f2011-09-04 21:15:19 +00003648 affinity_image,&exception);
cristy3ed852e2009-09-05 21:47:34 +00003649 quantize_info=DestroyQuantizeInfo(quantize_info);
3650 affinity_image=DestroyImage(affinity_image);
3651 break;
3652 }
cristyb988fe72009-09-16 01:01:10 +00003653 if (LocaleCompare((const char *) tag,"matte-floodfill") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003654 {
3655 double
3656 opacity;
3657
cristy4c08aed2011-07-01 19:47:50 +00003658 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00003659 target;
3660
3661 PaintMethod
3662 paint_method;
3663
3664 /*
3665 Matte floodfill image.
3666 */
3667 opacity=0.0;
3668 if (msl_info->image[n] == (Image *) NULL)
3669 {
cristyb988fe72009-09-16 01:01:10 +00003670 ThrowMSLException(OptionError,"NoImagesDefined",
3671 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003672 break;
3673 }
3674 SetGeometry(msl_info->image[n],&geometry);
3675 paint_method=FloodfillMethod;
3676 if (attributes != (const xmlChar **) NULL)
3677 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3678 {
3679 keyword=(const char *) attributes[i++];
3680 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003681 msl_info->attributes[n],(const char *) attributes[i],
3682 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003683 CloneString(&value,attribute);
3684 switch (*keyword)
3685 {
3686 case 'B':
3687 case 'b':
3688 {
3689 if (LocaleCompare(keyword,"bordercolor") == 0)
3690 {
cristy9950d572011-10-01 18:22:35 +00003691 (void) QueryMagickColorCompliance(value,AllCompliance,
3692 &target,&exception);
cristy3ed852e2009-09-05 21:47:34 +00003693 paint_method=FillToBorderMethod;
3694 break;
3695 }
3696 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3697 keyword);
3698 break;
3699 }
3700 case 'F':
3701 case 'f':
3702 {
3703 if (LocaleCompare(keyword,"fuzz") == 0)
3704 {
cristyc1acd842011-05-19 23:05:47 +00003705 msl_info->image[n]->fuzz=InterpretLocaleValue(value,
3706 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003707 break;
3708 }
3709 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3710 keyword);
3711 break;
3712 }
3713 case 'G':
3714 case 'g':
3715 {
3716 if (LocaleCompare(keyword,"geometry") == 0)
3717 {
3718 flags=ParsePageGeometry(msl_info->image[n],value,
3719 &geometry,&exception);
3720 if ((flags & HeightValue) == 0)
3721 geometry.height=geometry.width;
3722 (void) GetOneVirtualMagickPixel(msl_info->image[n],
3723 geometry.x,geometry.y,&target,&exception);
3724 break;
3725 }
3726 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3727 keyword);
3728 break;
3729 }
3730 case 'O':
3731 case 'o':
3732 {
3733 if (LocaleCompare(keyword,"opacity") == 0)
3734 {
cristyc1acd842011-05-19 23:05:47 +00003735 opacity=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003736 break;
3737 }
3738 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3739 keyword);
3740 break;
3741 }
3742 case 'X':
3743 case 'x':
3744 {
3745 if (LocaleCompare(keyword,"x") == 0)
3746 {
cristyf2f27272009-12-17 14:48:46 +00003747 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003748 (void) GetOneVirtualMagickPixel(msl_info->image[n],
3749 geometry.x,geometry.y,&target,&exception);
3750 break;
3751 }
3752 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3753 keyword);
3754 break;
3755 }
3756 case 'Y':
3757 case 'y':
3758 {
3759 if (LocaleCompare(keyword,"y") == 0)
3760 {
cristyf2f27272009-12-17 14:48:46 +00003761 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003762 (void) GetOneVirtualMagickPixel(msl_info->image[n],
3763 geometry.x,geometry.y,&target,&exception);
3764 break;
3765 }
3766 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3767 keyword);
3768 break;
3769 }
3770 default:
3771 {
3772 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3773 keyword);
3774 break;
3775 }
3776 }
3777 }
3778 draw_info=CloneDrawInfo(msl_info->image_info[n],
3779 msl_info->draw_info[n]);
cristy4c08aed2011-07-01 19:47:50 +00003780 draw_info->fill.alpha=ClampToQuantum(opacity);
cristybd5a96c2011-08-21 00:04:26 +00003781 channel_mask=SetPixelChannelMask(msl_info->image[n],AlphaChannel);
cristyd42d9952011-07-08 14:21:50 +00003782 (void) FloodfillPaintImage(msl_info->image[n],draw_info,&target,
3783 geometry.x,geometry.y,paint_method == FloodfillMethod ?
cristy189e84c2011-08-27 18:08:53 +00003784 MagickFalse : MagickTrue,&msl_info->image[n]->exception);
cristybd5a96c2011-08-21 00:04:26 +00003785 (void) SetPixelChannelMap(msl_info->image[n],channel_mask);
cristy3ed852e2009-09-05 21:47:34 +00003786 draw_info=DestroyDrawInfo(draw_info);
3787 break;
3788 }
cristyb988fe72009-09-16 01:01:10 +00003789 if (LocaleCompare((const char *) tag,"median-filter") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003790 {
3791 Image
3792 *median_image;
3793
3794 /*
3795 Median-filter image.
3796 */
3797 if (msl_info->image[n] == (Image *) NULL)
3798 {
cristyb988fe72009-09-16 01:01:10 +00003799 ThrowMSLException(OptionError,"NoImagesDefined",
3800 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003801 break;
3802 }
3803 if (attributes != (const xmlChar **) NULL)
3804 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3805 {
3806 keyword=(const char *) attributes[i++];
3807 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003808 msl_info->attributes[n],(const char *) attributes[i],
3809 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003810 CloneString(&value,attribute);
3811 switch (*keyword)
3812 {
3813 case 'G':
3814 case 'g':
3815 {
3816 if (LocaleCompare(keyword,"geometry") == 0)
3817 {
3818 flags=ParseGeometry(value,&geometry_info);
3819 if ((flags & SigmaValue) == 0)
3820 geometry_info.sigma=1.0;
3821 break;
3822 }
3823 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3824 keyword);
3825 break;
3826 }
3827 case 'R':
3828 case 'r':
3829 {
3830 if (LocaleCompare(keyword,"radius") == 0)
3831 {
cristyc1acd842011-05-19 23:05:47 +00003832 geometry_info.rho=InterpretLocaleValue(value,
3833 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003834 break;
3835 }
3836 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3837 keyword);
3838 break;
3839 }
3840 default:
3841 {
3842 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3843 keyword);
3844 break;
3845 }
3846 }
3847 }
cristy733678d2011-03-18 21:29:28 +00003848 median_image=StatisticImage(msl_info->image[n],MedianStatistic,
cristy95c38342011-03-18 22:39:51 +00003849 (size_t) geometry_info.rho,(size_t) geometry_info.sigma,
3850 &msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00003851 if (median_image == (Image *) NULL)
3852 break;
3853 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3854 msl_info->image[n]=median_image;
3855 break;
3856 }
cristyb988fe72009-09-16 01:01:10 +00003857 if (LocaleCompare((const char *) tag,"minify") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003858 {
3859 Image
3860 *minify_image;
3861
3862 /*
3863 Minify image.
3864 */
3865 if (msl_info->image[n] == (Image *) NULL)
3866 {
cristyb988fe72009-09-16 01:01:10 +00003867 ThrowMSLException(OptionError,"NoImagesDefined",
3868 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003869 break;
3870 }
3871 if (attributes != (const xmlChar **) NULL)
3872 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3873 {
3874 keyword=(const char *) attributes[i++];
3875 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003876 msl_info->attributes[n],(const char *) attributes[i],
3877 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003878 CloneString(&value,attribute);
3879 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3880 }
3881 minify_image=MinifyImage(msl_info->image[n],
3882 &msl_info->image[n]->exception);
3883 if (minify_image == (Image *) NULL)
3884 break;
3885 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3886 msl_info->image[n]=minify_image;
3887 break;
3888 }
cristyb988fe72009-09-16 01:01:10 +00003889 if (LocaleCompare((const char *) tag,"msl") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00003890 break;
cristyb988fe72009-09-16 01:01:10 +00003891 if (LocaleCompare((const char *) tag,"modulate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003892 {
3893 char
3894 modulate[MaxTextExtent];
3895
3896 /*
3897 Modulate image.
3898 */
3899 if (msl_info->image[n] == (Image *) NULL)
3900 {
cristyb988fe72009-09-16 01:01:10 +00003901 ThrowMSLException(OptionError,"NoImagesDefined",
3902 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003903 break;
3904 }
3905 geometry_info.rho=100.0;
3906 geometry_info.sigma=100.0;
3907 geometry_info.xi=100.0;
3908 if (attributes != (const xmlChar **) NULL)
3909 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3910 {
3911 keyword=(const char *) attributes[i++];
3912 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003913 msl_info->attributes[n],(const char *) attributes[i],
3914 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003915 CloneString(&value,attribute);
3916 switch (*keyword)
3917 {
3918 case 'B':
3919 case 'b':
3920 {
3921 if (LocaleCompare(keyword,"blackness") == 0)
3922 {
cristyc1acd842011-05-19 23:05:47 +00003923 geometry_info.rho=InterpretLocaleValue(value,
3924 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003925 break;
3926 }
3927 if (LocaleCompare(keyword,"brightness") == 0)
3928 {
cristyc1acd842011-05-19 23:05:47 +00003929 geometry_info.rho=InterpretLocaleValue(value,
3930 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003931 break;
3932 }
3933 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3934 keyword);
3935 break;
3936 }
3937 case 'F':
3938 case 'f':
3939 {
3940 if (LocaleCompare(keyword,"factor") == 0)
3941 {
3942 flags=ParseGeometry(value,&geometry_info);
3943 break;
3944 }
3945 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3946 keyword);
3947 break;
3948 }
3949 case 'H':
3950 case 'h':
3951 {
3952 if (LocaleCompare(keyword,"hue") == 0)
3953 {
cristyc1acd842011-05-19 23:05:47 +00003954 geometry_info.xi=InterpretLocaleValue(value,
3955 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003956 break;
3957 }
3958 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3959 keyword);
3960 break;
3961 }
3962 case 'L':
3963 case 'l':
3964 {
3965 if (LocaleCompare(keyword,"lightness") == 0)
3966 {
cristyc1acd842011-05-19 23:05:47 +00003967 geometry_info.rho=InterpretLocaleValue(value,
3968 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003969 break;
3970 }
3971 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3972 keyword);
3973 break;
3974 }
3975 case 'S':
3976 case 's':
3977 {
3978 if (LocaleCompare(keyword,"saturation") == 0)
3979 {
cristyc1acd842011-05-19 23:05:47 +00003980 geometry_info.sigma=InterpretLocaleValue(value,
3981 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003982 break;
3983 }
3984 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3985 keyword);
3986 break;
3987 }
3988 case 'W':
3989 case 'w':
3990 {
3991 if (LocaleCompare(keyword,"whiteness") == 0)
3992 {
cristyc1acd842011-05-19 23:05:47 +00003993 geometry_info.sigma=InterpretLocaleValue(value,
3994 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003995 break;
3996 }
3997 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3998 keyword);
3999 break;
4000 }
4001 default:
4002 {
4003 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4004 keyword);
4005 break;
4006 }
4007 }
4008 }
cristyb51dff52011-05-19 16:55:47 +00004009 (void) FormatLocaleString(modulate,MaxTextExtent,"%g,%g,%g",
cristy3ed852e2009-09-05 21:47:34 +00004010 geometry_info.rho,geometry_info.sigma,geometry_info.xi);
cristy33bd5152011-08-24 01:42:24 +00004011 (void) ModulateImage(msl_info->image[n],modulate,
4012 &msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00004013 break;
4014 }
4015 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4016 }
4017 case 'N':
4018 case 'n':
4019 {
cristyb988fe72009-09-16 01:01:10 +00004020 if (LocaleCompare((const char *) tag,"negate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004021 {
4022 MagickBooleanType
4023 gray;
4024
4025 /*
4026 Negate image.
4027 */
4028 if (msl_info->image[n] == (Image *) NULL)
4029 {
cristyb988fe72009-09-16 01:01:10 +00004030 ThrowMSLException(OptionError,"NoImagesDefined",
4031 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004032 break;
4033 }
4034 gray=MagickFalse;
4035 if (attributes != (const xmlChar **) NULL)
4036 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4037 {
4038 keyword=(const char *) attributes[i++];
4039 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004040 msl_info->attributes[n],(const char *) attributes[i],
4041 &exception);
cristy3ed852e2009-09-05 21:47:34 +00004042 CloneString(&value,attribute);
4043 switch (*keyword)
4044 {
4045 case 'C':
4046 case 'c':
4047 {
4048 if (LocaleCompare(keyword,"channel") == 0)
4049 {
4050 option=ParseChannelOption(value);
4051 if (option < 0)
4052 ThrowMSLException(OptionError,"UnrecognizedChannelType",
4053 value);
4054 channel=(ChannelType) option;
4055 break;
4056 }
4057 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4058 keyword);
4059 break;
4060 }
4061 case 'G':
4062 case 'g':
4063 {
4064 if (LocaleCompare(keyword,"gray") == 0)
4065 {
cristy042ee782011-04-22 18:48:30 +00004066 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004067 value);
4068 if (option < 0)
4069 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4070 value);
4071 gray=(MagickBooleanType) option;
4072 break;
4073 }
4074 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4075 keyword);
4076 break;
4077 }
4078 default:
4079 {
4080 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4081 keyword);
4082 break;
4083 }
4084 }
4085 }
cristybd5a96c2011-08-21 00:04:26 +00004086 channel_mask=SetPixelChannelMask(msl_info->image[n],channel);
cristyb3e7c6c2011-07-24 01:43:55 +00004087 (void) NegateImage(msl_info->image[n],gray,
4088 &msl_info->image[n]->exception);
cristybd5a96c2011-08-21 00:04:26 +00004089 (void) SetPixelChannelMap(msl_info->image[n],channel_mask);
cristy3ed852e2009-09-05 21:47:34 +00004090 break;
4091 }
cristyb988fe72009-09-16 01:01:10 +00004092 if (LocaleCompare((const char *) tag,"normalize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004093 {
4094 /*
4095 Normalize image.
4096 */
4097 if (msl_info->image[n] == (Image *) NULL)
4098 {
cristyb988fe72009-09-16 01:01:10 +00004099 ThrowMSLException(OptionError,"NoImagesDefined",
4100 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004101 break;
4102 }
4103 if (attributes != (const xmlChar **) NULL)
4104 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4105 {
4106 keyword=(const char *) attributes[i++];
4107 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004108 msl_info->attributes[n],(const char *) attributes[i],
4109 &exception);
cristy3ed852e2009-09-05 21:47:34 +00004110 CloneString(&value,attribute);
4111 switch (*keyword)
4112 {
4113 case 'C':
4114 case 'c':
4115 {
4116 if (LocaleCompare(keyword,"channel") == 0)
4117 {
4118 option=ParseChannelOption(value);
4119 if (option < 0)
4120 ThrowMSLException(OptionError,"UnrecognizedChannelType",
4121 value);
4122 channel=(ChannelType) option;
4123 break;
4124 }
4125 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4126 keyword);
4127 break;
4128 }
4129 default:
4130 {
4131 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4132 keyword);
4133 break;
4134 }
4135 }
4136 }
cristye23ec9d2011-08-16 18:15:40 +00004137 (void) NormalizeImage(msl_info->image[n],
4138 &msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00004139 break;
4140 }
4141 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4142 }
4143 case 'O':
4144 case 'o':
4145 {
cristyb988fe72009-09-16 01:01:10 +00004146 if (LocaleCompare((const char *) tag,"oil-paint") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004147 {
4148 Image
4149 *paint_image;
4150
4151 /*
4152 Oil-paint image.
4153 */
4154 if (msl_info->image[n] == (Image *) NULL)
4155 {
cristyb988fe72009-09-16 01:01:10 +00004156 ThrowMSLException(OptionError,"NoImagesDefined",
4157 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004158 break;
4159 }
4160 if (attributes != (const xmlChar **) NULL)
4161 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4162 {
4163 keyword=(const char *) attributes[i++];
4164 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004165 msl_info->attributes[n],(const char *) attributes[i],
4166 &exception);
cristy3ed852e2009-09-05 21:47:34 +00004167 CloneString(&value,attribute);
4168 switch (*keyword)
4169 {
4170 case 'G':
4171 case 'g':
4172 {
4173 if (LocaleCompare(keyword,"geometry") == 0)
4174 {
4175 flags=ParseGeometry(value,&geometry_info);
4176 if ((flags & SigmaValue) == 0)
4177 geometry_info.sigma=1.0;
4178 break;
4179 }
4180 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4181 keyword);
4182 break;
4183 }
4184 case 'R':
4185 case 'r':
4186 {
4187 if (LocaleCompare(keyword,"radius") == 0)
4188 {
cristyc1acd842011-05-19 23:05:47 +00004189 geometry_info.rho=InterpretLocaleValue(value,
4190 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004191 break;
4192 }
4193 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4194 keyword);
4195 break;
4196 }
4197 default:
4198 {
4199 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4200 keyword);
4201 break;
4202 }
4203 }
4204 }
4205 paint_image=OilPaintImage(msl_info->image[n],geometry_info.rho,
cristy14973ba2011-08-27 23:48:07 +00004206 geometry_info.sigma,&msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00004207 if (paint_image == (Image *) NULL)
4208 break;
4209 msl_info->image[n]=DestroyImage(msl_info->image[n]);
4210 msl_info->image[n]=paint_image;
4211 break;
4212 }
cristyb988fe72009-09-16 01:01:10 +00004213 if (LocaleCompare((const char *) tag,"opaque") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004214 {
cristy4c08aed2011-07-01 19:47:50 +00004215 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00004216 fill_color,
4217 target;
4218
4219 /*
4220 Opaque image.
4221 */
4222 if (msl_info->image[n] == (Image *) NULL)
4223 {
cristyb988fe72009-09-16 01:01:10 +00004224 ThrowMSLException(OptionError,"NoImagesDefined",
4225 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004226 break;
4227 }
cristy9950d572011-10-01 18:22:35 +00004228 (void) QueryMagickColorCompliance("none",AllCompliance,&target,
4229 &exception);
4230 (void) QueryMagickColorCompliance("none",AllCompliance,&fill_color,
4231 &exception);
cristy3ed852e2009-09-05 21:47:34 +00004232 if (attributes != (const xmlChar **) NULL)
4233 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4234 {
4235 keyword=(const char *) attributes[i++];
4236 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004237 msl_info->attributes[n],(const char *) attributes[i],
4238 &exception);
cristy3ed852e2009-09-05 21:47:34 +00004239 CloneString(&value,attribute);
4240 switch (*keyword)
4241 {
4242 case 'C':
4243 case 'c':
4244 {
4245 if (LocaleCompare(keyword,"channel") == 0)
4246 {
4247 option=ParseChannelOption(value);
4248 if (option < 0)
4249 ThrowMSLException(OptionError,"UnrecognizedChannelType",
4250 value);
4251 channel=(ChannelType) option;
4252 break;
4253 }
4254 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4255 keyword);
4256 break;
4257 }
4258 case 'F':
4259 case 'f':
4260 {
4261 if (LocaleCompare(keyword,"fill") == 0)
4262 {
cristy9950d572011-10-01 18:22:35 +00004263 (void) QueryMagickColorCompliance(value,AllCompliance,
4264 &fill_color,&exception);
cristy3ed852e2009-09-05 21:47:34 +00004265 break;
4266 }
4267 if (LocaleCompare(keyword,"fuzz") == 0)
4268 {
cristyc1acd842011-05-19 23:05:47 +00004269 msl_info->image[n]->fuzz=InterpretLocaleValue(value,
4270 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004271 break;
4272 }
4273 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4274 keyword);
4275 break;
4276 }
4277 default:
4278 {
4279 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4280 keyword);
4281 break;
4282 }
4283 }
4284 }
cristybd5a96c2011-08-21 00:04:26 +00004285 channel_mask=SetPixelChannelMask(msl_info->image[n],channel);
cristyd42d9952011-07-08 14:21:50 +00004286 (void) OpaquePaintImage(msl_info->image[n],&target,&fill_color,
cristy189e84c2011-08-27 18:08:53 +00004287 MagickFalse,&msl_info->image[n]->exception);
cristybd5a96c2011-08-21 00:04:26 +00004288 (void) SetPixelChannelMap(msl_info->image[n],channel_mask);
cristy3ed852e2009-09-05 21:47:34 +00004289 break;
4290 }
4291 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4292 }
4293 case 'P':
4294 case 'p':
4295 {
cristyb988fe72009-09-16 01:01:10 +00004296 if (LocaleCompare((const char *) tag,"print") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004297 {
4298 if (attributes == (const xmlChar **) NULL)
4299 break;
4300 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4301 {
4302 keyword=(const char *) attributes[i++];
4303 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004304 msl_info->attributes[n],(const char *) attributes[i],
4305 &exception);
cristy3ed852e2009-09-05 21:47:34 +00004306 CloneString(&value,attribute);
4307 switch (*keyword)
4308 {
4309 case 'O':
4310 case 'o':
4311 {
4312 if (LocaleCompare(keyword,"output") == 0)
4313 {
cristyb51dff52011-05-19 16:55:47 +00004314 (void) FormatLocaleFile(stdout,"%s",value);
cristy3ed852e2009-09-05 21:47:34 +00004315 break;
4316 }
4317 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
4318 break;
4319 }
4320 default:
4321 {
4322 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
4323 break;
4324 }
4325 }
4326 }
4327 break;
4328 }
cristy4fa36e42009-09-18 14:24:06 +00004329 if (LocaleCompare((const char *) tag, "profile") == 0)
4330 {
cristy4fa36e42009-09-18 14:24:06 +00004331 if (msl_info->image[n] == (Image *) NULL)
4332 {
4333 ThrowMSLException(OptionError,"NoImagesDefined",
4334 (const char *) tag);
4335 break;
4336 }
4337 if (attributes == (const xmlChar **) NULL)
4338 break;
4339 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4340 {
4341 const char
4342 *name;
4343
4344 const StringInfo
4345 *profile;
4346
4347 Image
4348 *profile_image;
4349
4350 ImageInfo
4351 *profile_info;
4352
4353 keyword=(const char *) attributes[i++];
4354 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004355 msl_info->attributes[n],(const char *) attributes[i],
4356 &exception);
cristy4fa36e42009-09-18 14:24:06 +00004357 CloneString(&value,attribute);
4358 if (*keyword == '+')
4359 {
4360 /*
4361 Remove a profile from the image.
4362 */
4363 (void) ProfileImage(msl_info->image[n],keyword,
4364 (const unsigned char *) NULL,0,MagickTrue);
4365 continue;
4366 }
4367 /*
4368 Associate a profile with the image.
4369 */
4370 profile_info=CloneImageInfo(msl_info->image_info[n]);
4371 profile=GetImageProfile(msl_info->image[n],"iptc");
4372 if (profile != (StringInfo *) NULL)
4373 profile_info->profile=(void *) CloneStringInfo(profile);
4374 profile_image=GetImageCache(profile_info,keyword,&exception);
4375 profile_info=DestroyImageInfo(profile_info);
4376 if (profile_image == (Image *) NULL)
4377 {
4378 char
4379 name[MaxTextExtent],
4380 filename[MaxTextExtent];
4381
4382 register char
4383 *p;
4384
4385 StringInfo
4386 *profile;
4387
4388 (void) CopyMagickString(filename,keyword,MaxTextExtent);
4389 (void) CopyMagickString(name,keyword,MaxTextExtent);
4390 for (p=filename; *p != '\0'; p++)
4391 if ((*p == ':') && (IsPathDirectory(keyword) < 0) &&
4392 (IsPathAccessible(keyword) == MagickFalse))
4393 {
4394 register char
4395 *q;
4396
4397 /*
4398 Look for profile name (e.g. name:profile).
4399 */
4400 (void) CopyMagickString(name,filename,(size_t)
4401 (p-filename+1));
4402 for (q=filename; *q != '\0'; q++)
4403 *q=(*++p);
4404 break;
4405 }
4406 profile=FileToStringInfo(filename,~0UL,&exception);
4407 if (profile != (StringInfo *) NULL)
4408 {
4409 (void) ProfileImage(msl_info->image[n],name,
cristybb503372010-05-27 20:51:26 +00004410 GetStringInfoDatum(profile),(size_t)
cristy4fa36e42009-09-18 14:24:06 +00004411 GetStringInfoLength(profile),MagickFalse);
4412 profile=DestroyStringInfo(profile);
4413 }
4414 continue;
4415 }
4416 ResetImageProfileIterator(profile_image);
4417 name=GetNextImageProfile(profile_image);
4418 while (name != (const char *) NULL)
4419 {
4420 profile=GetImageProfile(profile_image,name);
4421 if (profile != (StringInfo *) NULL)
4422 (void) ProfileImage(msl_info->image[n],name,
cristybb503372010-05-27 20:51:26 +00004423 GetStringInfoDatum(profile),(size_t)
cristy4fa36e42009-09-18 14:24:06 +00004424 GetStringInfoLength(profile),MagickFalse);
4425 name=GetNextImageProfile(profile_image);
4426 }
4427 profile_image=DestroyImage(profile_image);
4428 }
4429 break;
4430 }
cristy3ed852e2009-09-05 21:47:34 +00004431 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4432 }
4433 case 'Q':
4434 case 'q':
4435 {
cristyb988fe72009-09-16 01:01:10 +00004436 if (LocaleCompare((const char *) tag,"quantize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004437 {
4438 QuantizeInfo
4439 quantize_info;
4440
4441 /*
4442 Quantize image.
4443 */
4444 if (msl_info->image[n] == (Image *) NULL)
4445 {
cristyb988fe72009-09-16 01:01:10 +00004446 ThrowMSLException(OptionError,"NoImagesDefined",
4447 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004448 break;
4449 }
4450 GetQuantizeInfo(&quantize_info);
4451 if (attributes != (const xmlChar **) NULL)
4452 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4453 {
4454 keyword=(const char *) attributes[i++];
4455 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004456 msl_info->attributes[n],(const char *) attributes[i],
4457 &exception);
cristy3ed852e2009-09-05 21:47:34 +00004458 CloneString(&value,attribute);
4459 switch (*keyword)
4460 {
4461 case 'C':
4462 case 'c':
4463 {
4464 if (LocaleCompare(keyword,"colors") == 0)
4465 {
cristyf2f27272009-12-17 14:48:46 +00004466 quantize_info.number_colors=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004467 break;
4468 }
4469 if (LocaleCompare(keyword,"colorspace") == 0)
4470 {
cristy042ee782011-04-22 18:48:30 +00004471 option=ParseCommandOption(MagickColorspaceOptions,
cristy3ed852e2009-09-05 21:47:34 +00004472 MagickFalse,value);
4473 if (option < 0)
4474 ThrowMSLException(OptionError,
4475 "UnrecognizedColorspaceType",value);
4476 quantize_info.colorspace=(ColorspaceType) option;
4477 break;
4478 }
4479 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4480 keyword);
4481 break;
4482 }
4483 case 'D':
4484 case 'd':
4485 {
4486 if (LocaleCompare(keyword,"dither") == 0)
4487 {
cristy042ee782011-04-22 18:48:30 +00004488 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004489 value);
4490 if (option < 0)
4491 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4492 value);
4493 quantize_info.dither=(MagickBooleanType) option;
4494 break;
4495 }
4496 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4497 keyword);
4498 break;
4499 }
4500 case 'M':
4501 case 'm':
4502 {
4503 if (LocaleCompare(keyword,"measure") == 0)
4504 {
cristy042ee782011-04-22 18:48:30 +00004505 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004506 value);
4507 if (option < 0)
4508 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4509 value);
4510 quantize_info.measure_error=(MagickBooleanType) option;
4511 break;
4512 }
4513 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4514 keyword);
4515 break;
4516 }
4517 case 'T':
4518 case 't':
4519 {
4520 if (LocaleCompare(keyword,"treedepth") == 0)
4521 {
cristyf2f27272009-12-17 14:48:46 +00004522 quantize_info.tree_depth=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004523 break;
4524 }
4525 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4526 keyword);
4527 break;
4528 }
4529 default:
4530 {
4531 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4532 keyword);
4533 break;
4534 }
4535 }
4536 }
cristy018f07f2011-09-04 21:15:19 +00004537 (void) QuantizeImage(&quantize_info,msl_info->image[n],&exception);
cristy3ed852e2009-09-05 21:47:34 +00004538 break;
4539 }
cristyb988fe72009-09-16 01:01:10 +00004540 if (LocaleCompare((const char *) tag,"query-font-metrics") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004541 {
4542 char
4543 text[MaxTextExtent];
4544
4545 MagickBooleanType
4546 status;
4547
4548 TypeMetric
4549 metrics;
4550
4551 /*
4552 Query font metrics.
4553 */
4554 draw_info=CloneDrawInfo(msl_info->image_info[n],
4555 msl_info->draw_info[n]);
4556 angle=0.0;
4557 current=draw_info->affine;
4558 GetAffineMatrix(&affine);
4559 if (attributes != (const xmlChar **) NULL)
4560 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4561 {
4562 keyword=(const char *) attributes[i++];
4563 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004564 msl_info->attributes[n],(const char *) attributes[i],
4565 &exception);
cristy3ed852e2009-09-05 21:47:34 +00004566 CloneString(&value,attribute);
4567 switch (*keyword)
4568 {
4569 case 'A':
4570 case 'a':
4571 {
4572 if (LocaleCompare(keyword,"affine") == 0)
4573 {
4574 char
4575 *p;
4576
4577 p=value;
cristyc1acd842011-05-19 23:05:47 +00004578 draw_info->affine.sx=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004579 if (*p ==',')
4580 p++;
cristyc1acd842011-05-19 23:05:47 +00004581 draw_info->affine.rx=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004582 if (*p ==',')
4583 p++;
cristyc1acd842011-05-19 23:05:47 +00004584 draw_info->affine.ry=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004585 if (*p ==',')
4586 p++;
cristyc1acd842011-05-19 23:05:47 +00004587 draw_info->affine.sy=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004588 if (*p ==',')
4589 p++;
cristyc1acd842011-05-19 23:05:47 +00004590 draw_info->affine.tx=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004591 if (*p ==',')
4592 p++;
cristyc1acd842011-05-19 23:05:47 +00004593 draw_info->affine.ty=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004594 break;
4595 }
4596 if (LocaleCompare(keyword,"align") == 0)
4597 {
cristy042ee782011-04-22 18:48:30 +00004598 option=ParseCommandOption(MagickAlignOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004599 value);
4600 if (option < 0)
4601 ThrowMSLException(OptionError,"UnrecognizedAlignType",
4602 value);
4603 draw_info->align=(AlignType) option;
4604 break;
4605 }
4606 if (LocaleCompare(keyword,"antialias") == 0)
4607 {
cristy042ee782011-04-22 18:48:30 +00004608 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004609 value);
4610 if (option < 0)
4611 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4612 value);
4613 draw_info->stroke_antialias=(MagickBooleanType) option;
4614 draw_info->text_antialias=(MagickBooleanType) option;
4615 break;
4616 }
4617 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4618 keyword);
4619 break;
4620 }
4621 case 'D':
4622 case 'd':
4623 {
4624 if (LocaleCompare(keyword,"density") == 0)
4625 {
4626 CloneString(&draw_info->density,value);
4627 break;
4628 }
4629 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4630 keyword);
4631 break;
4632 }
4633 case 'E':
4634 case 'e':
4635 {
4636 if (LocaleCompare(keyword,"encoding") == 0)
4637 {
4638 CloneString(&draw_info->encoding,value);
4639 break;
4640 }
4641 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4642 keyword);
4643 break;
4644 }
4645 case 'F':
4646 case 'f':
4647 {
4648 if (LocaleCompare(keyword, "fill") == 0)
4649 {
cristy9950d572011-10-01 18:22:35 +00004650 (void) QueryColorCompliance(value,AllCompliance,
4651 &draw_info->fill,&exception);
cristy3ed852e2009-09-05 21:47:34 +00004652 break;
4653 }
4654 if (LocaleCompare(keyword,"family") == 0)
4655 {
4656 CloneString(&draw_info->family,value);
4657 break;
4658 }
4659 if (LocaleCompare(keyword,"font") == 0)
4660 {
4661 CloneString(&draw_info->font,value);
4662 break;
4663 }
4664 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4665 keyword);
4666 break;
4667 }
4668 case 'G':
4669 case 'g':
4670 {
4671 if (LocaleCompare(keyword,"geometry") == 0)
4672 {
4673 flags=ParsePageGeometry(msl_info->image[n],value,
4674 &geometry,&exception);
4675 if ((flags & HeightValue) == 0)
4676 geometry.height=geometry.width;
4677 break;
4678 }
4679 if (LocaleCompare(keyword,"gravity") == 0)
4680 {
cristy042ee782011-04-22 18:48:30 +00004681 option=ParseCommandOption(MagickGravityOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004682 value);
4683 if (option < 0)
4684 ThrowMSLException(OptionError,"UnrecognizedGravityType",
4685 value);
4686 draw_info->gravity=(GravityType) option;
4687 break;
4688 }
4689 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4690 keyword);
4691 break;
4692 }
4693 case 'P':
4694 case 'p':
4695 {
4696 if (LocaleCompare(keyword,"pointsize") == 0)
4697 {
cristyc1acd842011-05-19 23:05:47 +00004698 draw_info->pointsize=InterpretLocaleValue(value,
4699 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004700 break;
4701 }
4702 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4703 keyword);
4704 break;
4705 }
4706 case 'R':
4707 case 'r':
4708 {
4709 if (LocaleCompare(keyword,"rotate") == 0)
4710 {
cristyc1acd842011-05-19 23:05:47 +00004711 angle=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004712 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
4713 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
4714 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
4715 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
4716 break;
4717 }
4718 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4719 keyword);
4720 break;
4721 }
4722 case 'S':
4723 case 's':
4724 {
4725 if (LocaleCompare(keyword,"scale") == 0)
4726 {
4727 flags=ParseGeometry(value,&geometry_info);
4728 if ((flags & SigmaValue) == 0)
4729 geometry_info.sigma=1.0;
4730 affine.sx=geometry_info.rho;
4731 affine.sy=geometry_info.sigma;
4732 break;
4733 }
4734 if (LocaleCompare(keyword,"skewX") == 0)
4735 {
cristyc1acd842011-05-19 23:05:47 +00004736 angle=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004737 affine.ry=cos(DegreesToRadians(fmod(angle,360.0)));
4738 break;
4739 }
4740 if (LocaleCompare(keyword,"skewY") == 0)
4741 {
cristyc1acd842011-05-19 23:05:47 +00004742 angle=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004743 affine.rx=cos(DegreesToRadians(fmod(angle,360.0)));
4744 break;
4745 }
4746 if (LocaleCompare(keyword,"stretch") == 0)
4747 {
cristy9950d572011-10-01 18:22:35 +00004748 option=ParseCommandOption(MagickStretchOptions,
4749 MagickFalse,value);
cristy3ed852e2009-09-05 21:47:34 +00004750 if (option < 0)
4751 ThrowMSLException(OptionError,"UnrecognizedStretchType",
4752 value);
4753 draw_info->stretch=(StretchType) option;
4754 break;
4755 }
4756 if (LocaleCompare(keyword, "stroke") == 0)
4757 {
cristy9950d572011-10-01 18:22:35 +00004758 (void) QueryColorCompliance(value,AllCompliance,
4759 &draw_info->stroke,&exception);
cristy3ed852e2009-09-05 21:47:34 +00004760 break;
4761 }
4762 if (LocaleCompare(keyword,"strokewidth") == 0)
4763 {
cristyf2f27272009-12-17 14:48:46 +00004764 draw_info->stroke_width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004765 break;
4766 }
4767 if (LocaleCompare(keyword,"style") == 0)
4768 {
cristy042ee782011-04-22 18:48:30 +00004769 option=ParseCommandOption(MagickStyleOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004770 value);
4771 if (option < 0)
4772 ThrowMSLException(OptionError,"UnrecognizedStyleType",
4773 value);
4774 draw_info->style=(StyleType) option;
4775 break;
4776 }
4777 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4778 keyword);
4779 break;
4780 }
4781 case 'T':
4782 case 't':
4783 {
4784 if (LocaleCompare(keyword,"text") == 0)
4785 {
4786 CloneString(&draw_info->text,value);
4787 break;
4788 }
4789 if (LocaleCompare(keyword,"translate") == 0)
4790 {
4791 flags=ParseGeometry(value,&geometry_info);
4792 if ((flags & SigmaValue) == 0)
4793 geometry_info.sigma=1.0;
4794 affine.tx=geometry_info.rho;
4795 affine.ty=geometry_info.sigma;
4796 break;
4797 }
4798 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4799 keyword);
4800 break;
4801 }
4802 case 'U':
4803 case 'u':
4804 {
4805 if (LocaleCompare(keyword, "undercolor") == 0)
4806 {
cristy9950d572011-10-01 18:22:35 +00004807 (void) QueryColorCompliance(value,AllCompliance,
4808 &draw_info->undercolor,&exception);
cristy3ed852e2009-09-05 21:47:34 +00004809 break;
4810 }
4811 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4812 keyword);
4813 break;
4814 }
4815 case 'W':
4816 case 'w':
4817 {
4818 if (LocaleCompare(keyword,"weight") == 0)
4819 {
cristyf2f27272009-12-17 14:48:46 +00004820 draw_info->weight=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004821 break;
4822 }
4823 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4824 keyword);
4825 break;
4826 }
4827 case 'X':
4828 case 'x':
4829 {
4830 if (LocaleCompare(keyword,"x") == 0)
4831 {
cristyf2f27272009-12-17 14:48:46 +00004832 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004833 break;
4834 }
4835 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4836 keyword);
4837 break;
4838 }
4839 case 'Y':
4840 case 'y':
4841 {
4842 if (LocaleCompare(keyword,"y") == 0)
4843 {
cristyf2f27272009-12-17 14:48:46 +00004844 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004845 break;
4846 }
4847 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4848 keyword);
4849 break;
4850 }
4851 default:
4852 {
4853 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4854 keyword);
4855 break;
4856 }
4857 }
4858 }
cristyb51dff52011-05-19 16:55:47 +00004859 (void) FormatLocaleString(text,MaxTextExtent,
cristye8c25f92010-06-03 00:53:06 +00004860 "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,(double)
4861 geometry.height,(double) geometry.x,(double) geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00004862 CloneString(&draw_info->geometry,text);
cristyef7c8a52010-10-10 13:46:51 +00004863 draw_info->affine.sx=affine.sx*current.sx+affine.ry*current.rx;
4864 draw_info->affine.rx=affine.rx*current.sx+affine.sy*current.rx;
4865 draw_info->affine.ry=affine.sx*current.ry+affine.ry*current.sy;
4866 draw_info->affine.sy=affine.rx*current.ry+affine.sy*current.sy;
4867 draw_info->affine.tx=affine.sx*current.tx+affine.ry*current.ty+
4868 affine.tx;
4869 draw_info->affine.ty=affine.rx*current.tx+affine.sy*current.ty+
4870 affine.ty;
cristy5cbc0162011-08-29 00:36:28 +00004871 status=GetTypeMetrics(msl_info->attributes[n],draw_info,&metrics,
4872 &msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00004873 if (status != MagickFalse)
4874 {
4875 Image
4876 *image;
4877
4878 image=msl_info->attributes[n];
cristy8cd5b312010-01-07 01:10:24 +00004879 FormatImageProperty(image,"msl:font-metrics.pixels_per_em.x",
cristye7f51092010-01-17 00:39:37 +00004880 "%g",metrics.pixels_per_em.x);
cristy8cd5b312010-01-07 01:10:24 +00004881 FormatImageProperty(image,"msl:font-metrics.pixels_per_em.y",
cristye7f51092010-01-17 00:39:37 +00004882 "%g",metrics.pixels_per_em.y);
4883 FormatImageProperty(image,"msl:font-metrics.ascent","%g",
cristy3ed852e2009-09-05 21:47:34 +00004884 metrics.ascent);
cristye7f51092010-01-17 00:39:37 +00004885 FormatImageProperty(image,"msl:font-metrics.descent","%g",
cristy3ed852e2009-09-05 21:47:34 +00004886 metrics.descent);
cristye7f51092010-01-17 00:39:37 +00004887 FormatImageProperty(image,"msl:font-metrics.width","%g",
cristy3ed852e2009-09-05 21:47:34 +00004888 metrics.width);
cristye7f51092010-01-17 00:39:37 +00004889 FormatImageProperty(image,"msl:font-metrics.height","%g",
cristy3ed852e2009-09-05 21:47:34 +00004890 metrics.height);
cristye7f51092010-01-17 00:39:37 +00004891 FormatImageProperty(image,"msl:font-metrics.max_advance","%g",
cristy3ed852e2009-09-05 21:47:34 +00004892 metrics.max_advance);
cristye7f51092010-01-17 00:39:37 +00004893 FormatImageProperty(image,"msl:font-metrics.bounds.x1","%g",
cristy3ed852e2009-09-05 21:47:34 +00004894 metrics.bounds.x1);
cristye7f51092010-01-17 00:39:37 +00004895 FormatImageProperty(image,"msl:font-metrics.bounds.y1","%g",
cristy3ed852e2009-09-05 21:47:34 +00004896 metrics.bounds.y1);
cristye7f51092010-01-17 00:39:37 +00004897 FormatImageProperty(image,"msl:font-metrics.bounds.x2","%g",
cristy3ed852e2009-09-05 21:47:34 +00004898 metrics.bounds.x2);
cristye7f51092010-01-17 00:39:37 +00004899 FormatImageProperty(image,"msl:font-metrics.bounds.y2","%g",
cristy3ed852e2009-09-05 21:47:34 +00004900 metrics.bounds.y2);
cristye7f51092010-01-17 00:39:37 +00004901 FormatImageProperty(image,"msl:font-metrics.origin.x","%g",
cristy3ed852e2009-09-05 21:47:34 +00004902 metrics.origin.x);
cristye7f51092010-01-17 00:39:37 +00004903 FormatImageProperty(image,"msl:font-metrics.origin.y","%g",
cristy3ed852e2009-09-05 21:47:34 +00004904 metrics.origin.y);
4905 }
4906 draw_info=DestroyDrawInfo(draw_info);
4907 break;
4908 }
4909 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4910 }
4911 case 'R':
4912 case 'r':
4913 {
cristyb988fe72009-09-16 01:01:10 +00004914 if (LocaleCompare((const char *) tag,"raise") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004915 {
4916 MagickBooleanType
4917 raise;
4918
4919 /*
4920 Raise image.
4921 */
4922 if (msl_info->image[n] == (Image *) NULL)
4923 {
cristyb988fe72009-09-16 01:01:10 +00004924 ThrowMSLException(OptionError,"NoImagesDefined",
4925 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004926 break;
4927 }
4928 raise=MagickFalse;
4929 SetGeometry(msl_info->image[n],&geometry);
4930 if (attributes != (const xmlChar **) NULL)
4931 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4932 {
4933 keyword=(const char *) attributes[i++];
4934 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004935 msl_info->attributes[n],(const char *) attributes[i],
4936 &exception);
cristy3ed852e2009-09-05 21:47:34 +00004937 CloneString(&value,attribute);
4938 switch (*keyword)
4939 {
4940 case 'G':
4941 case 'g':
4942 {
4943 if (LocaleCompare(keyword,"geometry") == 0)
4944 {
4945 flags=ParsePageGeometry(msl_info->image[n],value,
4946 &geometry,&exception);
4947 if ((flags & HeightValue) == 0)
4948 geometry.height=geometry.width;
4949 break;
4950 }
4951 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4952 keyword);
4953 break;
4954 }
4955 case 'H':
4956 case 'h':
4957 {
4958 if (LocaleCompare(keyword,"height") == 0)
4959 {
cristyf2f27272009-12-17 14:48:46 +00004960 geometry.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004961 break;
4962 }
4963 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4964 keyword);
4965 break;
4966 }
4967 case 'R':
4968 case 'r':
4969 {
4970 if (LocaleCompare(keyword,"raise") == 0)
4971 {
cristy042ee782011-04-22 18:48:30 +00004972 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004973 value);
4974 if (option < 0)
4975 ThrowMSLException(OptionError,"UnrecognizedNoiseType",
4976 value);
4977 raise=(MagickBooleanType) option;
4978 break;
4979 }
4980 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4981 keyword);
4982 break;
4983 }
4984 case 'W':
4985 case 'w':
4986 {
4987 if (LocaleCompare(keyword,"width") == 0)
4988 {
cristyf2f27272009-12-17 14:48:46 +00004989 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004990 break;
4991 }
4992 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4993 keyword);
4994 break;
4995 }
4996 default:
4997 {
4998 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4999 keyword);
5000 break;
5001 }
5002 }
5003 }
cristy6170ac32011-08-28 14:15:37 +00005004 (void) RaiseImage(msl_info->image[n],&geometry,raise,
5005 &msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00005006 break;
5007 }
cristyb988fe72009-09-16 01:01:10 +00005008 if (LocaleCompare((const char *) tag,"read") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005009 {
5010 if (attributes == (const xmlChar **) NULL)
5011 break;
5012 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5013 {
5014 keyword=(const char *) attributes[i++];
5015 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005016 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00005017 switch (*keyword)
5018 {
5019 case 'F':
5020 case 'f':
5021 {
5022 if (LocaleCompare(keyword,"filename") == 0)
5023 {
5024 Image
5025 *image;
5026
5027 (void) CopyMagickString(msl_info->image_info[n]->filename,
5028 value,MaxTextExtent);
5029 image=ReadImage(msl_info->image_info[n],&exception);
5030 CatchException(&exception);
5031 if (image == (Image *) NULL)
5032 continue;
5033 AppendImageToList(&msl_info->image[n],image);
5034 break;
5035 }
cristy4582cbb2009-09-23 00:35:43 +00005036 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00005037 break;
5038 }
5039 default:
5040 {
cristy4582cbb2009-09-23 00:35:43 +00005041 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00005042 break;
5043 }
5044 }
5045 }
5046 break;
5047 }
cristyb988fe72009-09-16 01:01:10 +00005048 if (LocaleCompare((const char *) tag,"reduce-noise") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005049 {
5050 Image
5051 *paint_image;
5052
5053 /*
5054 Reduce-noise image.
5055 */
5056 if (msl_info->image[n] == (Image *) NULL)
5057 {
cristyb988fe72009-09-16 01:01:10 +00005058 ThrowMSLException(OptionError,"NoImagesDefined",
5059 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005060 break;
5061 }
5062 if (attributes != (const xmlChar **) NULL)
5063 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5064 {
5065 keyword=(const char *) attributes[i++];
5066 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005067 msl_info->attributes[n],(const char *) attributes[i],
5068 &exception);
cristy3ed852e2009-09-05 21:47:34 +00005069 CloneString(&value,attribute);
5070 switch (*keyword)
5071 {
5072 case 'G':
5073 case 'g':
5074 {
5075 if (LocaleCompare(keyword,"geometry") == 0)
5076 {
5077 flags=ParseGeometry(value,&geometry_info);
5078 if ((flags & SigmaValue) == 0)
5079 geometry_info.sigma=1.0;
5080 break;
5081 }
5082 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5083 keyword);
5084 break;
5085 }
5086 case 'R':
5087 case 'r':
5088 {
5089 if (LocaleCompare(keyword,"radius") == 0)
5090 {
cristyc1acd842011-05-19 23:05:47 +00005091 geometry_info.rho=InterpretLocaleValue(value,
5092 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005093 break;
5094 }
5095 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5096 keyword);
5097 break;
5098 }
5099 default:
5100 {
5101 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5102 keyword);
5103 break;
5104 }
5105 }
5106 }
cristy733678d2011-03-18 21:29:28 +00005107 paint_image=StatisticImage(msl_info->image[n],NonpeakStatistic,
cristy95c38342011-03-18 22:39:51 +00005108 (size_t) geometry_info.rho,(size_t) geometry_info.sigma,
5109 &msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00005110 if (paint_image == (Image *) NULL)
5111 break;
5112 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5113 msl_info->image[n]=paint_image;
5114 break;
5115 }
cristyb988fe72009-09-16 01:01:10 +00005116 else if (LocaleCompare((const char *) tag,"repage") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005117 {
5118 /* init the values */
5119 width=msl_info->image[n]->page.width;
5120 height=msl_info->image[n]->page.height;
5121 x=msl_info->image[n]->page.x;
5122 y=msl_info->image[n]->page.y;
5123
5124 if (msl_info->image[n] == (Image *) NULL)
5125 {
cristyb988fe72009-09-16 01:01:10 +00005126 ThrowMSLException(OptionError,"NoImagesDefined",
5127 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005128 break;
5129 }
5130 if (attributes == (const xmlChar **) NULL)
5131 break;
5132 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5133 {
5134 keyword=(const char *) attributes[i++];
5135 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005136 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00005137 switch (*keyword)
5138 {
5139 case 'G':
5140 case 'g':
5141 {
5142 if (LocaleCompare(keyword,"geometry") == 0)
5143 {
5144 int
5145 flags;
5146
5147 RectangleInfo
5148 geometry;
5149
5150 flags=ParseAbsoluteGeometry(value,&geometry);
5151 if ((flags & WidthValue) != 0)
5152 {
5153 if ((flags & HeightValue) == 0)
5154 geometry.height=geometry.width;
5155 width=geometry.width;
5156 height=geometry.height;
5157 }
5158 if ((flags & AspectValue) != 0)
5159 {
5160 if ((flags & XValue) != 0)
5161 x+=geometry.x;
5162 if ((flags & YValue) != 0)
5163 y+=geometry.y;
5164 }
5165 else
5166 {
5167 if ((flags & XValue) != 0)
5168 {
5169 x=geometry.x;
5170 if ((width == 0) && (geometry.x > 0))
5171 width=msl_info->image[n]->columns+geometry.x;
5172 }
5173 if ((flags & YValue) != 0)
5174 {
5175 y=geometry.y;
5176 if ((height == 0) && (geometry.y > 0))
5177 height=msl_info->image[n]->rows+geometry.y;
5178 }
5179 }
5180 break;
5181 }
5182 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5183 break;
5184 }
5185 case 'H':
5186 case 'h':
5187 {
5188 if (LocaleCompare(keyword,"height") == 0)
5189 {
cristyf2f27272009-12-17 14:48:46 +00005190 height = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005191 break;
5192 }
5193 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5194 break;
5195 }
5196 case 'W':
5197 case 'w':
5198 {
5199 if (LocaleCompare(keyword,"width") == 0)
5200 {
cristyf2f27272009-12-17 14:48:46 +00005201 width = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005202 break;
5203 }
5204 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5205 break;
5206 }
5207 case 'X':
5208 case 'x':
5209 {
5210 if (LocaleCompare(keyword,"x") == 0)
5211 {
cristyf2f27272009-12-17 14:48:46 +00005212 x = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005213 break;
5214 }
5215 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5216 break;
5217 }
5218 case 'Y':
5219 case 'y':
5220 {
5221 if (LocaleCompare(keyword,"y") == 0)
5222 {
cristyf2f27272009-12-17 14:48:46 +00005223 y = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005224 break;
5225 }
5226 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5227 break;
5228 }
5229 default:
5230 {
5231 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5232 break;
5233 }
5234 }
5235 }
5236
cristyb988fe72009-09-16 01:01:10 +00005237 msl_info->image[n]->page.width=width;
5238 msl_info->image[n]->page.height=height;
5239 msl_info->image[n]->page.x=x;
5240 msl_info->image[n]->page.y=y;
cristy3ed852e2009-09-05 21:47:34 +00005241 break;
5242 }
cristyb988fe72009-09-16 01:01:10 +00005243 else if (LocaleCompare((const char *) tag,"resample") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005244 {
5245 double
5246 x_resolution,
5247 y_resolution;
5248
5249 if (msl_info->image[n] == (Image *) NULL)
5250 {
cristyb988fe72009-09-16 01:01:10 +00005251 ThrowMSLException(OptionError,"NoImagesDefined",
5252 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005253 break;
5254 }
5255 if (attributes == (const xmlChar **) NULL)
5256 break;
5257 x_resolution=DefaultResolution;
5258 y_resolution=DefaultResolution;
5259 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5260 {
5261 keyword=(const char *) attributes[i++];
5262 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005263 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00005264 switch (*keyword)
5265 {
5266 case 'b':
5267 {
5268 if (LocaleCompare(keyword,"blur") == 0)
5269 {
cristyc1acd842011-05-19 23:05:47 +00005270 msl_info->image[n]->blur=InterpretLocaleValue(value,
5271 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005272 break;
5273 }
5274 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5275 break;
5276 }
5277 case 'G':
5278 case 'g':
5279 {
5280 if (LocaleCompare(keyword,"geometry") == 0)
5281 {
cristybb503372010-05-27 20:51:26 +00005282 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00005283 flags;
5284
5285 flags=ParseGeometry(value,&geometry_info);
5286 if ((flags & SigmaValue) == 0)
5287 geometry_info.sigma*=geometry_info.rho;
5288 x_resolution=geometry_info.rho;
5289 y_resolution=geometry_info.sigma;
5290 break;
5291 }
5292 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5293 break;
5294 }
5295 case 'X':
5296 case 'x':
5297 {
5298 if (LocaleCompare(keyword,"x-resolution") == 0)
5299 {
cristyc1acd842011-05-19 23:05:47 +00005300 x_resolution=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005301 break;
5302 }
5303 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5304 break;
5305 }
5306 case 'Y':
5307 case 'y':
5308 {
5309 if (LocaleCompare(keyword,"y-resolution") == 0)
5310 {
cristyc1acd842011-05-19 23:05:47 +00005311 y_resolution=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005312 break;
5313 }
5314 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5315 break;
5316 }
5317 default:
5318 {
5319 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5320 break;
5321 }
5322 }
5323 }
5324 /*
5325 Resample image.
5326 */
5327 {
5328 double
5329 factor;
5330
5331 Image
5332 *resample_image;
5333
5334 factor=1.0;
5335 if (msl_info->image[n]->units == PixelsPerCentimeterResolution)
5336 factor=2.54;
cristybb503372010-05-27 20:51:26 +00005337 width=(size_t) (x_resolution*msl_info->image[n]->columns/
cristy3ed852e2009-09-05 21:47:34 +00005338 (factor*(msl_info->image[n]->x_resolution == 0.0 ? DefaultResolution :
5339 msl_info->image[n]->x_resolution))+0.5);
cristybb503372010-05-27 20:51:26 +00005340 height=(size_t) (y_resolution*msl_info->image[n]->rows/
cristy3ed852e2009-09-05 21:47:34 +00005341 (factor*(msl_info->image[n]->y_resolution == 0.0 ? DefaultResolution :
5342 msl_info->image[n]->y_resolution))+0.5);
5343 resample_image=ResizeImage(msl_info->image[n],width,height,
5344 msl_info->image[n]->filter,msl_info->image[n]->blur,
5345 &msl_info->image[n]->exception);
5346 if (resample_image == (Image *) NULL)
5347 break;
5348 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5349 msl_info->image[n]=resample_image;
5350 }
5351 break;
5352 }
cristyb988fe72009-09-16 01:01:10 +00005353 if (LocaleCompare((const char *) tag,"resize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005354 {
5355 double
5356 blur;
5357
5358 FilterTypes
5359 filter;
5360
5361 Image
5362 *resize_image;
5363
5364 /*
5365 Resize image.
5366 */
5367 if (msl_info->image[n] == (Image *) NULL)
5368 {
cristyb988fe72009-09-16 01:01:10 +00005369 ThrowMSLException(OptionError,"NoImagesDefined",
5370 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005371 break;
5372 }
5373 filter=UndefinedFilter;
5374 blur=1.0;
5375 if (attributes != (const xmlChar **) NULL)
5376 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5377 {
5378 keyword=(const char *) attributes[i++];
5379 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005380 msl_info->attributes[n],(const char *) attributes[i],
5381 &exception);
cristy3ed852e2009-09-05 21:47:34 +00005382 CloneString(&value,attribute);
5383 switch (*keyword)
5384 {
5385 case 'F':
5386 case 'f':
5387 {
5388 if (LocaleCompare(keyword,"filter") == 0)
5389 {
cristy042ee782011-04-22 18:48:30 +00005390 option=ParseCommandOption(MagickFilterOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00005391 value);
5392 if (option < 0)
5393 ThrowMSLException(OptionError,"UnrecognizedNoiseType",
5394 value);
5395 filter=(FilterTypes) option;
5396 break;
5397 }
5398 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5399 keyword);
5400 break;
5401 }
5402 case 'G':
5403 case 'g':
5404 {
5405 if (LocaleCompare(keyword,"geometry") == 0)
5406 {
5407 flags=ParseRegionGeometry(msl_info->image[n],value,
5408 &geometry,&exception);
5409 break;
5410 }
5411 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5412 keyword);
5413 break;
5414 }
5415 case 'H':
5416 case 'h':
5417 {
5418 if (LocaleCompare(keyword,"height") == 0)
5419 {
cristye27293e2009-12-18 02:53:20 +00005420 geometry.height=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005421 break;
5422 }
5423 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5424 keyword);
5425 break;
5426 }
5427 case 'S':
5428 case 's':
5429 {
5430 if (LocaleCompare(keyword,"support") == 0)
5431 {
cristyc1acd842011-05-19 23:05:47 +00005432 blur=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005433 break;
5434 }
5435 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5436 keyword);
5437 break;
5438 }
5439 case 'W':
5440 case 'w':
5441 {
5442 if (LocaleCompare(keyword,"width") == 0)
5443 {
cristyf2f27272009-12-17 14:48:46 +00005444 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005445 break;
5446 }
5447 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5448 keyword);
5449 break;
5450 }
5451 default:
5452 {
5453 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5454 keyword);
5455 break;
5456 }
5457 }
5458 }
5459 resize_image=ResizeImage(msl_info->image[n],geometry.width,
5460 geometry.height,filter,blur,&msl_info->image[n]->exception);
5461 if (resize_image == (Image *) NULL)
5462 break;
5463 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5464 msl_info->image[n]=resize_image;
5465 break;
5466 }
cristyb988fe72009-09-16 01:01:10 +00005467 if (LocaleCompare((const char *) tag,"roll") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005468 {
5469 Image
5470 *roll_image;
5471
5472 /*
5473 Roll image.
5474 */
5475 if (msl_info->image[n] == (Image *) NULL)
5476 {
cristyb988fe72009-09-16 01:01:10 +00005477 ThrowMSLException(OptionError,"NoImagesDefined",
5478 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005479 break;
5480 }
5481 SetGeometry(msl_info->image[n],&geometry);
5482 if (attributes != (const xmlChar **) NULL)
5483 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5484 {
5485 keyword=(const char *) attributes[i++];
5486 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005487 msl_info->attributes[n],(const char *) attributes[i],
5488 &exception);
cristy3ed852e2009-09-05 21:47:34 +00005489 CloneString(&value,attribute);
5490 switch (*keyword)
5491 {
5492 case 'G':
5493 case 'g':
5494 {
5495 if (LocaleCompare(keyword,"geometry") == 0)
5496 {
5497 flags=ParsePageGeometry(msl_info->image[n],value,
5498 &geometry,&exception);
5499 if ((flags & HeightValue) == 0)
5500 geometry.height=geometry.width;
5501 break;
5502 }
5503 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5504 keyword);
5505 break;
5506 }
5507 case 'X':
5508 case 'x':
5509 {
5510 if (LocaleCompare(keyword,"x") == 0)
5511 {
cristyf2f27272009-12-17 14:48:46 +00005512 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005513 break;
5514 }
5515 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5516 keyword);
5517 break;
5518 }
5519 case 'Y':
5520 case 'y':
5521 {
5522 if (LocaleCompare(keyword,"y") == 0)
5523 {
cristyf2f27272009-12-17 14:48:46 +00005524 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005525 break;
5526 }
5527 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5528 keyword);
5529 break;
5530 }
5531 default:
5532 {
5533 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5534 keyword);
5535 break;
5536 }
5537 }
5538 }
5539 roll_image=RollImage(msl_info->image[n],geometry.x,geometry.y,
5540 &msl_info->image[n]->exception);
5541 if (roll_image == (Image *) NULL)
5542 break;
5543 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5544 msl_info->image[n]=roll_image;
5545 break;
5546 }
cristyb988fe72009-09-16 01:01:10 +00005547 else if (LocaleCompare((const char *) tag,"roll") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005548 {
5549 /* init the values */
5550 width=msl_info->image[n]->columns;
5551 height=msl_info->image[n]->rows;
5552 x = y = 0;
5553
5554 if (msl_info->image[n] == (Image *) NULL)
5555 {
cristyb988fe72009-09-16 01:01:10 +00005556 ThrowMSLException(OptionError,"NoImagesDefined",
5557 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005558 break;
5559 }
5560 if (attributes == (const xmlChar **) NULL)
5561 break;
5562 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5563 {
5564 keyword=(const char *) attributes[i++];
5565 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005566 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00005567 switch (*keyword)
5568 {
5569 case 'G':
5570 case 'g':
5571 {
5572 if (LocaleCompare(keyword,"geometry") == 0)
5573 {
5574 (void) ParseMetaGeometry(value,&x,&y,&width,&height);
5575 break;
5576 }
5577 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5578 break;
5579 }
5580 case 'X':
5581 case 'x':
5582 {
5583 if (LocaleCompare(keyword,"x") == 0)
5584 {
cristyf2f27272009-12-17 14:48:46 +00005585 x = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005586 break;
5587 }
5588 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5589 break;
5590 }
5591 case 'Y':
5592 case 'y':
5593 {
5594 if (LocaleCompare(keyword,"y") == 0)
5595 {
cristyf2f27272009-12-17 14:48:46 +00005596 y = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005597 break;
5598 }
5599 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5600 break;
5601 }
5602 default:
5603 {
5604 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5605 break;
5606 }
5607 }
5608 }
5609
5610 /*
5611 process image.
5612 */
5613 {
5614 Image
5615 *newImage;
5616
5617 newImage=RollImage(msl_info->image[n], x, y, &msl_info->image[n]->exception);
5618 if (newImage == (Image *) NULL)
5619 break;
5620 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5621 msl_info->image[n]=newImage;
5622 }
5623
5624 break;
5625 }
cristyb988fe72009-09-16 01:01:10 +00005626 if (LocaleCompare((const char *) tag,"rotate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005627 {
5628 Image
5629 *rotate_image;
5630
5631 /*
5632 Rotate image.
5633 */
5634 if (msl_info->image[n] == (Image *) NULL)
5635 {
cristyb988fe72009-09-16 01:01:10 +00005636 ThrowMSLException(OptionError,"NoImagesDefined",
5637 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005638 break;
5639 }
5640 if (attributes != (const xmlChar **) NULL)
5641 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5642 {
5643 keyword=(const char *) attributes[i++];
5644 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005645 msl_info->attributes[n],(const char *) attributes[i],
5646 &exception);
cristy3ed852e2009-09-05 21:47:34 +00005647 CloneString(&value,attribute);
5648 switch (*keyword)
5649 {
5650 case 'D':
5651 case 'd':
5652 {
5653 if (LocaleCompare(keyword,"degrees") == 0)
5654 {
cristyc1acd842011-05-19 23:05:47 +00005655 geometry_info.rho=InterpretLocaleValue(value,
5656 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005657 break;
5658 }
5659 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5660 keyword);
5661 break;
5662 }
5663 case 'G':
5664 case 'g':
5665 {
5666 if (LocaleCompare(keyword,"geometry") == 0)
5667 {
5668 flags=ParseGeometry(value,&geometry_info);
5669 if ((flags & SigmaValue) == 0)
5670 geometry_info.sigma=1.0;
5671 break;
5672 }
5673 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5674 keyword);
5675 break;
5676 }
5677 default:
5678 {
5679 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5680 keyword);
5681 break;
5682 }
5683 }
5684 }
5685 rotate_image=RotateImage(msl_info->image[n],geometry_info.rho,
5686 &msl_info->image[n]->exception);
5687 if (rotate_image == (Image *) NULL)
5688 break;
5689 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5690 msl_info->image[n]=rotate_image;
5691 break;
5692 }
cristyb988fe72009-09-16 01:01:10 +00005693 else if (LocaleCompare((const char *) tag,"rotate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005694 {
5695 /* init the values */
5696 double degrees = 0;
5697
5698 if (msl_info->image[n] == (Image *) NULL)
5699 {
cristyb988fe72009-09-16 01:01:10 +00005700 ThrowMSLException(OptionError,"NoImagesDefined",
5701 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005702 break;
5703 }
5704 if (attributes == (const xmlChar **) NULL)
cristy31939262009-09-15 00:23:11 +00005705 break;
cristy3ed852e2009-09-05 21:47:34 +00005706 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5707 {
5708 keyword=(const char *) attributes[i++];
5709 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005710 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00005711 switch (*keyword)
5712 {
5713 case 'D':
5714 case 'd':
5715 {
5716 if (LocaleCompare(keyword,"degrees") == 0)
5717 {
cristyc1acd842011-05-19 23:05:47 +00005718 degrees = InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005719 break;
5720 }
5721 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5722 break;
5723 }
5724 default:
5725 {
5726 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5727 break;
5728 }
5729 }
5730 }
5731
5732 /*
5733 process image.
5734 */
5735 {
5736 Image
5737 *newImage;
5738
5739 newImage=RotateImage(msl_info->image[n], degrees, &msl_info->image[n]->exception);
5740 if (newImage == (Image *) NULL)
5741 break;
5742 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5743 msl_info->image[n]=newImage;
5744 }
5745
5746 break;
5747 }
5748 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
5749 }
5750 case 'S':
5751 case 's':
5752 {
cristyb988fe72009-09-16 01:01:10 +00005753 if (LocaleCompare((const char *) tag,"sample") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005754 {
5755 Image
5756 *sample_image;
5757
5758 /*
5759 Sample image.
5760 */
5761 if (msl_info->image[n] == (Image *) NULL)
5762 {
cristyb988fe72009-09-16 01:01:10 +00005763 ThrowMSLException(OptionError,"NoImagesDefined",
5764 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005765 break;
5766 }
5767 if (attributes != (const xmlChar **) NULL)
5768 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5769 {
5770 keyword=(const char *) attributes[i++];
5771 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005772 msl_info->attributes[n],(const char *) attributes[i],
5773 &exception);
cristy3ed852e2009-09-05 21:47:34 +00005774 CloneString(&value,attribute);
5775 switch (*keyword)
5776 {
5777 case 'G':
5778 case 'g':
5779 {
5780 if (LocaleCompare(keyword,"geometry") == 0)
5781 {
5782 flags=ParseRegionGeometry(msl_info->image[n],value,
5783 &geometry,&exception);
5784 break;
5785 }
5786 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5787 keyword);
5788 break;
5789 }
5790 case 'H':
5791 case 'h':
5792 {
5793 if (LocaleCompare(keyword,"height") == 0)
5794 {
cristye27293e2009-12-18 02:53:20 +00005795 geometry.height=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005796 break;
5797 }
5798 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5799 keyword);
5800 break;
5801 }
5802 case 'W':
5803 case 'w':
5804 {
5805 if (LocaleCompare(keyword,"width") == 0)
5806 {
cristyf2f27272009-12-17 14:48:46 +00005807 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005808 break;
5809 }
5810 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5811 keyword);
5812 break;
5813 }
5814 default:
5815 {
5816 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5817 keyword);
5818 break;
5819 }
5820 }
5821 }
5822 sample_image=SampleImage(msl_info->image[n],geometry.width,
5823 geometry.height,&msl_info->image[n]->exception);
5824 if (sample_image == (Image *) NULL)
5825 break;
5826 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5827 msl_info->image[n]=sample_image;
5828 break;
5829 }
cristyb988fe72009-09-16 01:01:10 +00005830 if (LocaleCompare((const char *) tag,"scale") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005831 {
5832 Image
5833 *scale_image;
5834
5835 /*
5836 Scale image.
5837 */
5838 if (msl_info->image[n] == (Image *) NULL)
5839 {
cristyb988fe72009-09-16 01:01:10 +00005840 ThrowMSLException(OptionError,"NoImagesDefined",
5841 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005842 break;
5843 }
5844 if (attributes != (const xmlChar **) NULL)
5845 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5846 {
5847 keyword=(const char *) attributes[i++];
5848 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005849 msl_info->attributes[n],(const char *) attributes[i],
5850 &exception);
cristy3ed852e2009-09-05 21:47:34 +00005851 CloneString(&value,attribute);
5852 switch (*keyword)
5853 {
5854 case 'G':
5855 case 'g':
5856 {
5857 if (LocaleCompare(keyword,"geometry") == 0)
5858 {
5859 flags=ParseRegionGeometry(msl_info->image[n],value,
5860 &geometry,&exception);
5861 break;
5862 }
5863 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5864 keyword);
5865 break;
5866 }
5867 case 'H':
5868 case 'h':
5869 {
5870 if (LocaleCompare(keyword,"height") == 0)
5871 {
cristye27293e2009-12-18 02:53:20 +00005872 geometry.height=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005873 break;
5874 }
5875 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5876 keyword);
5877 break;
5878 }
5879 case 'W':
5880 case 'w':
5881 {
5882 if (LocaleCompare(keyword,"width") == 0)
5883 {
cristyf2f27272009-12-17 14:48:46 +00005884 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005885 break;
5886 }
5887 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5888 keyword);
5889 break;
5890 }
5891 default:
5892 {
5893 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5894 keyword);
5895 break;
5896 }
5897 }
5898 }
5899 scale_image=ScaleImage(msl_info->image[n],geometry.width,
5900 geometry.height,&msl_info->image[n]->exception);
5901 if (scale_image == (Image *) NULL)
5902 break;
5903 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5904 msl_info->image[n]=scale_image;
5905 break;
5906 }
cristyb988fe72009-09-16 01:01:10 +00005907 if (LocaleCompare((const char *) tag,"segment") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005908 {
5909 ColorspaceType
5910 colorspace;
5911
5912 MagickBooleanType
5913 verbose;
cristyb988fe72009-09-16 01:01:10 +00005914
cristy3ed852e2009-09-05 21:47:34 +00005915 /*
5916 Segment image.
5917 */
5918 if (msl_info->image[n] == (Image *) NULL)
5919 {
cristyb988fe72009-09-16 01:01:10 +00005920 ThrowMSLException(OptionError,"NoImagesDefined",
5921 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005922 break;
5923 }
5924 geometry_info.rho=1.0;
5925 geometry_info.sigma=1.5;
5926 colorspace=RGBColorspace;
5927 verbose=MagickFalse;
5928 if (attributes != (const xmlChar **) NULL)
5929 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5930 {
5931 keyword=(const char *) attributes[i++];
5932 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005933 msl_info->attributes[n],(const char *) attributes[i],
5934 &exception);
cristy3ed852e2009-09-05 21:47:34 +00005935 CloneString(&value,attribute);
5936 switch (*keyword)
5937 {
5938 case 'C':
5939 case 'c':
5940 {
5941 if (LocaleCompare(keyword,"cluster-threshold") == 0)
5942 {
cristyc1acd842011-05-19 23:05:47 +00005943 geometry_info.rho=InterpretLocaleValue(value,
5944 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005945 break;
5946 }
5947 if (LocaleCompare(keyword,"colorspace") == 0)
5948 {
cristy042ee782011-04-22 18:48:30 +00005949 option=ParseCommandOption(MagickColorspaceOptions,
cristy3ed852e2009-09-05 21:47:34 +00005950 MagickFalse,value);
5951 if (option < 0)
5952 ThrowMSLException(OptionError,
5953 "UnrecognizedColorspaceType",value);
5954 colorspace=(ColorspaceType) option;
5955 break;
5956 }
5957 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5958 keyword);
5959 break;
5960 }
5961 case 'G':
5962 case 'g':
5963 {
5964 if (LocaleCompare(keyword,"geometry") == 0)
5965 {
5966 flags=ParseGeometry(value,&geometry_info);
5967 if ((flags & SigmaValue) == 0)
5968 geometry_info.sigma=1.5;
5969 break;
5970 }
5971 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5972 keyword);
5973 break;
5974 }
5975 case 'S':
5976 case 's':
5977 {
5978 if (LocaleCompare(keyword,"smoothing-threshold") == 0)
5979 {
cristyc1acd842011-05-19 23:05:47 +00005980 geometry_info.sigma=InterpretLocaleValue(value,
5981 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005982 break;
5983 }
5984 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5985 keyword);
5986 break;
5987 }
5988 default:
5989 {
5990 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5991 keyword);
5992 break;
5993 }
5994 }
5995 }
5996 (void) SegmentImage(msl_info->image[n],colorspace,verbose,
cristy018f07f2011-09-04 21:15:19 +00005997 geometry_info.rho,geometry_info.sigma,&exception);
cristy3ed852e2009-09-05 21:47:34 +00005998 break;
5999 }
cristyb988fe72009-09-16 01:01:10 +00006000 else if (LocaleCompare((const char *) tag, "set") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006001 {
6002 if (msl_info->image[n] == (Image *) NULL)
6003 {
cristy0b6d0052011-07-27 23:54:16 +00006004 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006005 break;
6006 }
6007
6008 if (attributes == (const xmlChar **) NULL)
6009 break;
6010 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6011 {
6012 keyword=(const char *) attributes[i++];
6013 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006014 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00006015 switch (*keyword)
6016 {
cristy3ed852e2009-09-05 21:47:34 +00006017 case 'C':
6018 case 'c':
6019 {
6020 if (LocaleCompare(keyword,"clip-mask") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006021 {
cristy2c8b6312009-09-16 02:37:23 +00006022 for (j=0; j < msl_info->n; j++)
cristy3ed852e2009-09-05 21:47:34 +00006023 {
cristy2c8b6312009-09-16 02:37:23 +00006024 const char
6025 *property;
6026
6027 property=GetImageProperty(msl_info->attributes[j],"id");
6028 if (LocaleCompare(property,value) == 0)
6029 {
cristy018f07f2011-09-04 21:15:19 +00006030 SetImageMask(msl_info->image[n],msl_info->image[j],
6031 &exception);
cristy2c8b6312009-09-16 02:37:23 +00006032 break;
6033 }
cristy3ed852e2009-09-05 21:47:34 +00006034 }
cristy2c8b6312009-09-16 02:37:23 +00006035 break;
cristy3ed852e2009-09-05 21:47:34 +00006036 }
cristy3ed852e2009-09-05 21:47:34 +00006037 if (LocaleCompare(keyword,"clip-path") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006038 {
cristy2c8b6312009-09-16 02:37:23 +00006039 for (j=0; j < msl_info->n; j++)
cristy3ed852e2009-09-05 21:47:34 +00006040 {
cristy2c8b6312009-09-16 02:37:23 +00006041 const char
6042 *property;
6043
6044 property=GetImageProperty(msl_info->attributes[j],"id");
6045 if (LocaleCompare(property,value) == 0)
6046 {
cristy018f07f2011-09-04 21:15:19 +00006047 SetImageClipMask(msl_info->image[n],msl_info->image[j],
6048 &exception);
cristy2c8b6312009-09-16 02:37:23 +00006049 break;
6050 }
cristy3ed852e2009-09-05 21:47:34 +00006051 }
cristy2c8b6312009-09-16 02:37:23 +00006052 break;
cristy3ed852e2009-09-05 21:47:34 +00006053 }
cristy2c8b6312009-09-16 02:37:23 +00006054 if (LocaleCompare(keyword,"colorspace") == 0)
6055 {
cristybb503372010-05-27 20:51:26 +00006056 ssize_t
cristy2c8b6312009-09-16 02:37:23 +00006057 colorspace;
6058
cristy042ee782011-04-22 18:48:30 +00006059 colorspace=(ColorspaceType) ParseCommandOption(
cristy7e9e6fa2010-11-21 17:06:24 +00006060 MagickColorspaceOptions,MagickFalse,value);
cristy2c8b6312009-09-16 02:37:23 +00006061 if (colorspace < 0)
cristyfb758a52009-09-16 14:36:08 +00006062 ThrowMSLException(OptionError,"UnrecognizedColorspace",
cristy2c8b6312009-09-16 02:37:23 +00006063 value);
6064 (void) TransformImageColorspace(msl_info->image[n],
6065 (ColorspaceType) colorspace);
6066 break;
6067 }
6068 (void) SetMSLAttributes(msl_info,keyword,value);
cristy0b6d0052011-07-27 23:54:16 +00006069 (void) SetImageProperty(msl_info->image[n],keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00006070 break;
6071 }
6072 case 'D':
6073 case 'd':
6074 {
cristy2c8b6312009-09-16 02:37:23 +00006075 if (LocaleCompare(keyword,"density") == 0)
6076 {
6077 flags=ParseGeometry(value,&geometry_info);
6078 msl_info->image[n]->x_resolution=geometry_info.rho;
6079 msl_info->image[n]->y_resolution=geometry_info.sigma;
6080 if ((flags & SigmaValue) == 0)
6081 msl_info->image[n]->y_resolution=
6082 msl_info->image[n]->x_resolution;
6083 break;
6084 }
6085 (void) SetMSLAttributes(msl_info,keyword,value);
cristy0b6d0052011-07-27 23:54:16 +00006086 (void) SetImageProperty(msl_info->image[n],keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00006087 break;
6088 }
6089 case 'O':
6090 case 'o':
6091 {
6092 if (LocaleCompare(keyword, "opacity") == 0)
cristy2c8b6312009-09-16 02:37:23 +00006093 {
cristy4c08aed2011-07-01 19:47:50 +00006094 ssize_t opac = OpaqueAlpha,
cristybb503372010-05-27 20:51:26 +00006095 len = (ssize_t) strlen( value );
cristy3ed852e2009-09-05 21:47:34 +00006096
cristy2c8b6312009-09-16 02:37:23 +00006097 if (value[len-1] == '%') {
6098 char tmp[100];
6099 (void) CopyMagickString(tmp,value,len);
cristyf2f27272009-12-17 14:48:46 +00006100 opac = StringToLong( tmp );
cristy2c8b6312009-09-16 02:37:23 +00006101 opac = (int)(QuantumRange * ((float)opac/100));
6102 } else
cristyf2f27272009-12-17 14:48:46 +00006103 opac = StringToLong( value );
cristyb6a294d2011-10-03 00:55:17 +00006104 (void) SetImageAlpha( msl_info->image[n], (Quantum) opac );
cristy2c8b6312009-09-16 02:37:23 +00006105 break;
cristy3ed852e2009-09-05 21:47:34 +00006106 }
cristy2c8b6312009-09-16 02:37:23 +00006107 (void) SetMSLAttributes(msl_info,keyword,value);
cristy0b6d0052011-07-27 23:54:16 +00006108 (void) SetImageProperty(msl_info->image[n],keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00006109 break;
6110 }
6111 case 'P':
6112 case 'p':
6113 {
6114 if (LocaleCompare(keyword, "page") == 0)
6115 {
6116 char
6117 page[MaxTextExtent];
6118
6119 const char
6120 *image_option;
6121
6122 MagickStatusType
6123 flags;
6124
6125 RectangleInfo
6126 geometry;
6127
6128 (void) ResetMagickMemory(&geometry,0,sizeof(geometry));
6129 image_option=GetImageOption(msl_info->image_info[n],"page");
6130 if (image_option != (const char *) NULL)
6131 flags=ParseAbsoluteGeometry(image_option,&geometry);
6132 flags=ParseAbsoluteGeometry(value,&geometry);
cristyb51dff52011-05-19 16:55:47 +00006133 (void) FormatLocaleString(page,MaxTextExtent,"%.20gx%.20g",
cristye8c25f92010-06-03 00:53:06 +00006134 (double) geometry.width,(double) geometry.height);
cristy3ed852e2009-09-05 21:47:34 +00006135 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
cristyb51dff52011-05-19 16:55:47 +00006136 (void) FormatLocaleString(page,MaxTextExtent,
cristye8c25f92010-06-03 00:53:06 +00006137 "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,
6138 (double) geometry.height,(double) geometry.x,(double)
cristyf2faecf2010-05-28 19:19:36 +00006139 geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00006140 (void) SetImageOption(msl_info->image_info[n],keyword,page);
6141 msl_info->image_info[n]->page=GetPageGeometry(page);
6142 break;
6143 }
cristy2c8b6312009-09-16 02:37:23 +00006144 (void) SetMSLAttributes(msl_info,keyword,value);
cristy0b6d0052011-07-27 23:54:16 +00006145 (void) SetImageProperty(msl_info->image[n],keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00006146 break;
6147 }
6148 default:
6149 {
cristy2c8b6312009-09-16 02:37:23 +00006150 (void) SetMSLAttributes(msl_info,keyword,value);
cristy0b6d0052011-07-27 23:54:16 +00006151 (void) SetImageProperty(msl_info->image[n],keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00006152 break;
6153 }
6154 }
6155 }
6156 break;
6157 }
cristyb988fe72009-09-16 01:01:10 +00006158 if (LocaleCompare((const char *) tag,"shade") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006159 {
6160 Image
6161 *shade_image;
6162
6163 MagickBooleanType
6164 gray;
6165
6166 /*
6167 Shade image.
6168 */
6169 if (msl_info->image[n] == (Image *) NULL)
6170 {
cristyb988fe72009-09-16 01:01:10 +00006171 ThrowMSLException(OptionError,"NoImagesDefined",
6172 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006173 break;
6174 }
6175 gray=MagickFalse;
6176 if (attributes != (const xmlChar **) NULL)
6177 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6178 {
6179 keyword=(const char *) attributes[i++];
6180 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006181 msl_info->attributes[n],(const char *) attributes[i],
6182 &exception);
cristy3ed852e2009-09-05 21:47:34 +00006183 CloneString(&value,attribute);
6184 switch (*keyword)
6185 {
6186 case 'A':
6187 case 'a':
6188 {
6189 if (LocaleCompare(keyword,"azimuth") == 0)
6190 {
cristyc1acd842011-05-19 23:05:47 +00006191 geometry_info.rho=InterpretLocaleValue(value,
6192 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006193 break;
6194 }
6195 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6196 keyword);
6197 break;
6198 }
6199 case 'E':
6200 case 'e':
6201 {
6202 if (LocaleCompare(keyword,"elevation") == 0)
6203 {
cristyc1acd842011-05-19 23:05:47 +00006204 geometry_info.sigma=InterpretLocaleValue(value,
6205 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006206 break;
6207 }
6208 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6209 keyword);
6210 break;
6211 }
6212 case 'G':
6213 case 'g':
6214 {
6215 if (LocaleCompare(keyword,"geometry") == 0)
6216 {
6217 flags=ParseGeometry(value,&geometry_info);
6218 if ((flags & SigmaValue) == 0)
6219 geometry_info.sigma=1.0;
6220 break;
6221 }
6222 if (LocaleCompare(keyword,"gray") == 0)
6223 {
cristy042ee782011-04-22 18:48:30 +00006224 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00006225 value);
6226 if (option < 0)
6227 ThrowMSLException(OptionError,"UnrecognizedNoiseType",
6228 value);
6229 gray=(MagickBooleanType) option;
6230 break;
6231 }
6232 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6233 keyword);
6234 break;
6235 }
6236 default:
6237 {
6238 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6239 keyword);
6240 break;
6241 }
6242 }
6243 }
6244 shade_image=ShadeImage(msl_info->image[n],gray,geometry_info.rho,
6245 geometry_info.sigma,&msl_info->image[n]->exception);
6246 if (shade_image == (Image *) NULL)
6247 break;
6248 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6249 msl_info->image[n]=shade_image;
6250 break;
6251 }
cristyb988fe72009-09-16 01:01:10 +00006252 if (LocaleCompare((const char *) tag,"shadow") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006253 {
6254 Image
6255 *shadow_image;
6256
6257 /*
6258 Shear image.
6259 */
6260 if (msl_info->image[n] == (Image *) NULL)
6261 {
cristyb988fe72009-09-16 01:01:10 +00006262 ThrowMSLException(OptionError,"NoImagesDefined",
6263 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006264 break;
6265 }
6266 if (attributes != (const xmlChar **) NULL)
6267 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6268 {
6269 keyword=(const char *) attributes[i++];
6270 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006271 msl_info->attributes[n],(const char *) attributes[i],
6272 &exception);
cristy3ed852e2009-09-05 21:47:34 +00006273 CloneString(&value,attribute);
6274 switch (*keyword)
6275 {
6276 case 'G':
6277 case 'g':
6278 {
6279 if (LocaleCompare(keyword,"geometry") == 0)
6280 {
6281 flags=ParseGeometry(value,&geometry_info);
6282 if ((flags & SigmaValue) == 0)
6283 geometry_info.sigma=1.0;
6284 break;
6285 }
6286 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6287 keyword);
6288 break;
6289 }
6290 case 'O':
6291 case 'o':
6292 {
6293 if (LocaleCompare(keyword,"opacity") == 0)
6294 {
cristyf2f27272009-12-17 14:48:46 +00006295 geometry_info.rho=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006296 break;
6297 }
6298 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6299 keyword);
6300 break;
6301 }
6302 case 'S':
6303 case 's':
6304 {
6305 if (LocaleCompare(keyword,"sigma") == 0)
6306 {
cristyf2f27272009-12-17 14:48:46 +00006307 geometry_info.sigma=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006308 break;
6309 }
6310 break;
6311 }
6312 case 'X':
6313 case 'x':
6314 {
6315 if (LocaleCompare(keyword,"x") == 0)
6316 {
cristyc1acd842011-05-19 23:05:47 +00006317 geometry_info.xi=InterpretLocaleValue(value,
6318 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006319 break;
6320 }
6321 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6322 keyword);
6323 break;
6324 }
6325 case 'Y':
6326 case 'y':
6327 {
6328 if (LocaleCompare(keyword,"y") == 0)
6329 {
cristyf2f27272009-12-17 14:48:46 +00006330 geometry_info.psi=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006331 break;
6332 }
6333 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6334 keyword);
6335 break;
6336 }
6337 default:
6338 {
6339 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6340 keyword);
6341 break;
6342 }
6343 }
6344 }
6345 shadow_image=ShadowImage(msl_info->image[n],geometry_info.rho,
cristybb503372010-05-27 20:51:26 +00006346 geometry_info.sigma,(ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
cristy0534a6b2010-03-18 01:19:38 +00006347 ceil(geometry_info.psi-0.5),&msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00006348 if (shadow_image == (Image *) NULL)
6349 break;
6350 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6351 msl_info->image[n]=shadow_image;
6352 break;
6353 }
cristyb988fe72009-09-16 01:01:10 +00006354 if (LocaleCompare((const char *) tag,"sharpen") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006355 {
cristy05c0c9a2011-09-05 23:16:13 +00006356 double bias = 0.0,
6357 radius = 0.0,
cristy3ed852e2009-09-05 21:47:34 +00006358 sigma = 1.0;
6359
6360 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00006361 {
6362 ThrowMSLException(OptionError,"NoImagesDefined",
6363 (const char *) tag);
6364 break;
6365 }
cristy3ed852e2009-09-05 21:47:34 +00006366 /*
6367 NOTE: sharpen can have no attributes, since we use all the defaults!
6368 */
6369 if (attributes != (const xmlChar **) NULL)
6370 {
6371 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6372 {
6373 keyword=(const char *) attributes[i++];
6374 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006375 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00006376 switch (*keyword)
6377 {
cristy05c0c9a2011-09-05 23:16:13 +00006378 case 'B':
6379 case 'b':
6380 {
6381 if (LocaleCompare(keyword, "bias") == 0)
6382 {
6383 bias = InterpretLocaleValue(value,(char **) NULL);
6384 break;
6385 }
6386 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6387 break;
6388 }
cristy3ed852e2009-09-05 21:47:34 +00006389 case 'R':
6390 case 'r':
6391 {
6392 if (LocaleCompare(keyword, "radius") == 0)
6393 {
cristyc1acd842011-05-19 23:05:47 +00006394 radius = InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006395 break;
6396 }
6397 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6398 break;
6399 }
6400 case 'S':
6401 case 's':
6402 {
6403 if (LocaleCompare(keyword,"sigma") == 0)
6404 {
cristyf2f27272009-12-17 14:48:46 +00006405 sigma = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00006406 break;
6407 }
6408 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6409 break;
6410 }
6411 default:
6412 {
6413 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6414 break;
6415 }
6416 }
6417 }
6418 }
6419
6420 /*
6421 sharpen image.
6422 */
6423 {
6424 Image
6425 *newImage;
6426
cristy05c0c9a2011-09-05 23:16:13 +00006427 newImage=SharpenImage(msl_info->image[n],radius,sigma,bias,
6428 &msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00006429 if (newImage == (Image *) NULL)
6430 break;
6431 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6432 msl_info->image[n]=newImage;
6433 break;
6434 }
6435 }
cristyb988fe72009-09-16 01:01:10 +00006436 else if (LocaleCompare((const char *) tag,"shave") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006437 {
6438 /* init the values */
6439 width = height = 0;
6440 x = y = 0;
6441
6442 if (msl_info->image[n] == (Image *) NULL)
6443 {
cristyb988fe72009-09-16 01:01:10 +00006444 ThrowMSLException(OptionError,"NoImagesDefined",
6445 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006446 break;
6447 }
6448 if (attributes == (const xmlChar **) NULL)
6449 break;
6450 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6451 {
6452 keyword=(const char *) attributes[i++];
6453 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006454 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00006455 switch (*keyword)
6456 {
6457 case 'G':
6458 case 'g':
6459 {
6460 if (LocaleCompare(keyword,"geometry") == 0)
6461 {
6462 (void) ParseMetaGeometry(value,&x,&y,&width,&height);
6463 break;
6464 }
6465 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6466 break;
6467 }
6468 case 'H':
6469 case 'h':
6470 {
6471 if (LocaleCompare(keyword,"height") == 0)
6472 {
cristyf2f27272009-12-17 14:48:46 +00006473 height = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00006474 break;
6475 }
6476 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6477 break;
6478 }
6479 case 'W':
6480 case 'w':
6481 {
6482 if (LocaleCompare(keyword,"width") == 0)
6483 {
cristyf2f27272009-12-17 14:48:46 +00006484 width = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00006485 break;
6486 }
6487 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6488 break;
6489 }
6490 default:
6491 {
6492 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6493 break;
6494 }
6495 }
6496 }
6497
6498 /*
6499 process image.
6500 */
6501 {
6502 Image
6503 *newImage;
6504 RectangleInfo
6505 rectInfo;
6506
6507 rectInfo.height = height;
6508 rectInfo.width = width;
6509 rectInfo.x = x;
6510 rectInfo.y = y;
6511
6512
6513 newImage=ShaveImage(msl_info->image[n], &rectInfo,
6514 &msl_info->image[n]->exception);
6515 if (newImage == (Image *) NULL)
6516 break;
6517 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6518 msl_info->image[n]=newImage;
6519 }
6520
6521 break;
6522 }
cristyb988fe72009-09-16 01:01:10 +00006523 if (LocaleCompare((const char *) tag,"shear") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006524 {
6525 Image
6526 *shear_image;
6527
6528 /*
6529 Shear image.
6530 */
6531 if (msl_info->image[n] == (Image *) NULL)
6532 {
cristyb988fe72009-09-16 01:01:10 +00006533 ThrowMSLException(OptionError,"NoImagesDefined",
6534 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006535 break;
6536 }
6537 if (attributes != (const xmlChar **) NULL)
6538 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6539 {
6540 keyword=(const char *) attributes[i++];
6541 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006542 msl_info->attributes[n],(const char *) attributes[i],
6543 &exception);
cristy3ed852e2009-09-05 21:47:34 +00006544 CloneString(&value,attribute);
6545 switch (*keyword)
6546 {
6547 case 'F':
6548 case 'f':
6549 {
6550 if (LocaleCompare(keyword, "fill") == 0)
6551 {
cristy9950d572011-10-01 18:22:35 +00006552 (void) QueryColorCompliance(value,AllCompliance,
cristy3ed852e2009-09-05 21:47:34 +00006553 &msl_info->image[n]->background_color,&exception);
6554 break;
6555 }
6556 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6557 keyword);
6558 break;
6559 }
6560 case 'G':
6561 case 'g':
6562 {
6563 if (LocaleCompare(keyword,"geometry") == 0)
6564 {
6565 flags=ParseGeometry(value,&geometry_info);
6566 if ((flags & SigmaValue) == 0)
6567 geometry_info.sigma=1.0;
6568 break;
6569 }
6570 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6571 keyword);
6572 break;
6573 }
6574 case 'X':
6575 case 'x':
6576 {
6577 if (LocaleCompare(keyword,"x") == 0)
6578 {
cristyc1acd842011-05-19 23:05:47 +00006579 geometry_info.rho=InterpretLocaleValue(value,
6580 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006581 break;
6582 }
6583 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6584 keyword);
6585 break;
6586 }
6587 case 'Y':
6588 case 'y':
6589 {
6590 if (LocaleCompare(keyword,"y") == 0)
6591 {
cristyf2f27272009-12-17 14:48:46 +00006592 geometry_info.sigma=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006593 break;
6594 }
6595 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6596 keyword);
6597 break;
6598 }
6599 default:
6600 {
6601 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6602 keyword);
6603 break;
6604 }
6605 }
6606 }
6607 shear_image=ShearImage(msl_info->image[n],geometry_info.rho,
6608 geometry_info.sigma,&msl_info->image[n]->exception);
6609 if (shear_image == (Image *) NULL)
6610 break;
6611 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6612 msl_info->image[n]=shear_image;
6613 break;
6614 }
cristyb988fe72009-09-16 01:01:10 +00006615 if (LocaleCompare((const char *) tag,"signature") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006616 {
6617 /*
6618 Signature image.
6619 */
6620 if (msl_info->image[n] == (Image *) NULL)
6621 {
cristyb988fe72009-09-16 01:01:10 +00006622 ThrowMSLException(OptionError,"NoImagesDefined",
6623 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006624 break;
6625 }
6626 if (attributes != (const xmlChar **) NULL)
6627 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6628 {
6629 keyword=(const char *) attributes[i++];
6630 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006631 msl_info->attributes[n],(const char *) attributes[i],
6632 &exception);
cristy3ed852e2009-09-05 21:47:34 +00006633 CloneString(&value,attribute);
6634 switch (*keyword)
6635 {
6636 default:
6637 {
6638 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6639 keyword);
6640 break;
6641 }
6642 }
6643 }
cristy018f07f2011-09-04 21:15:19 +00006644 (void) SignatureImage(msl_info->image[n],&exception);
cristy3ed852e2009-09-05 21:47:34 +00006645 break;
6646 }
cristyb988fe72009-09-16 01:01:10 +00006647 if (LocaleCompare((const char *) tag,"solarize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006648 {
6649 /*
6650 Solarize image.
6651 */
6652 if (msl_info->image[n] == (Image *) NULL)
6653 {
cristyb988fe72009-09-16 01:01:10 +00006654 ThrowMSLException(OptionError,"NoImagesDefined",
6655 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006656 break;
6657 }
6658 geometry_info.rho=QuantumRange/2.0;
6659 if (attributes != (const xmlChar **) NULL)
6660 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6661 {
6662 keyword=(const char *) attributes[i++];
6663 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006664 msl_info->attributes[n],(const char *) attributes[i],
6665 &exception);
cristy3ed852e2009-09-05 21:47:34 +00006666 CloneString(&value,attribute);
6667 switch (*keyword)
6668 {
6669 case 'G':
6670 case 'g':
6671 {
6672 if (LocaleCompare(keyword,"geometry") == 0)
6673 {
6674 flags=ParseGeometry(value,&geometry_info);
6675 break;
6676 }
6677 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6678 keyword);
6679 break;
6680 }
6681 case 'T':
6682 case 't':
6683 {
6684 if (LocaleCompare(keyword,"threshold") == 0)
6685 {
cristyc1acd842011-05-19 23:05:47 +00006686 geometry_info.rho=InterpretLocaleValue(value,
6687 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006688 break;
6689 }
6690 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6691 keyword);
6692 break;
6693 }
6694 default:
6695 {
6696 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6697 keyword);
6698 break;
6699 }
6700 }
6701 }
cristy5cbc0162011-08-29 00:36:28 +00006702 (void) SolarizeImage(msl_info->image[n],geometry_info.rho,
6703 &msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00006704 break;
6705 }
cristyb988fe72009-09-16 01:01:10 +00006706 if (LocaleCompare((const char *) tag,"spread") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006707 {
6708 Image
6709 *spread_image;
6710
6711 /*
6712 Spread image.
6713 */
6714 if (msl_info->image[n] == (Image *) NULL)
6715 {
cristyb988fe72009-09-16 01:01:10 +00006716 ThrowMSLException(OptionError,"NoImagesDefined",
6717 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006718 break;
6719 }
6720 if (attributes != (const xmlChar **) NULL)
6721 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6722 {
6723 keyword=(const char *) attributes[i++];
6724 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006725 msl_info->attributes[n],(const char *) attributes[i],
6726 &exception);
cristy3ed852e2009-09-05 21:47:34 +00006727 CloneString(&value,attribute);
6728 switch (*keyword)
6729 {
6730 case 'G':
6731 case 'g':
6732 {
6733 if (LocaleCompare(keyword,"geometry") == 0)
6734 {
6735 flags=ParseGeometry(value,&geometry_info);
6736 if ((flags & SigmaValue) == 0)
6737 geometry_info.sigma=1.0;
6738 break;
6739 }
6740 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6741 keyword);
6742 break;
6743 }
6744 case 'R':
6745 case 'r':
6746 {
6747 if (LocaleCompare(keyword,"radius") == 0)
6748 {
cristyc1acd842011-05-19 23:05:47 +00006749 geometry_info.rho=InterpretLocaleValue(value,
6750 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006751 break;
6752 }
6753 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6754 keyword);
6755 break;
6756 }
6757 default:
6758 {
6759 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6760 keyword);
6761 break;
6762 }
6763 }
6764 }
6765 spread_image=SpreadImage(msl_info->image[n],geometry_info.rho,
cristy5c4e2582011-09-11 19:21:03 +00006766 msl_info->image[n]->interpolate,&msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00006767 if (spread_image == (Image *) NULL)
6768 break;
6769 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6770 msl_info->image[n]=spread_image;
6771 break;
6772 }
cristyb988fe72009-09-16 01:01:10 +00006773 else if (LocaleCompare((const char *) tag,"stegano") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006774 {
6775 Image *
6776 watermark = (Image*)NULL;
6777
6778 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00006779 {
6780 ThrowMSLException(OptionError,"NoImagesDefined",
6781 (const char *) tag);
6782 break;
6783 }
cristy3ed852e2009-09-05 21:47:34 +00006784 if (attributes == (const xmlChar **) NULL)
6785 break;
6786 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6787 {
6788 keyword=(const char *) attributes[i++];
6789 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006790 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00006791 switch (*keyword)
6792 {
6793 case 'I':
6794 case 'i':
6795 {
6796 if (LocaleCompare(keyword,"image") == 0)
6797 {
6798 for (j=0; j<msl_info->n;j++)
6799 {
6800 const char *
6801 theAttr = GetImageProperty(msl_info->attributes[j], "id");
6802 if (theAttr && LocaleCompare(theAttr, value) == 0)
6803 {
6804 watermark = msl_info->image[j];
6805 break;
6806 }
6807 }
6808 break;
6809 }
6810 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6811 break;
6812 }
6813 default:
6814 {
6815 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6816 break;
6817 }
6818 }
6819 }
6820
6821 /*
6822 process image.
6823 */
6824 if ( watermark != (Image*) NULL )
6825 {
6826 Image
6827 *newImage;
6828
6829 newImage=SteganoImage(msl_info->image[n], watermark, &msl_info->image[n]->exception);
6830 if (newImage == (Image *) NULL)
6831 break;
6832 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6833 msl_info->image[n]=newImage;
6834 break;
6835 } else
6836 ThrowMSLException(OptionError,"MissingWatermarkImage",keyword);
6837 }
cristyb988fe72009-09-16 01:01:10 +00006838 else if (LocaleCompare((const char *) tag,"stereo") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006839 {
6840 Image *
6841 stereoImage = (Image*)NULL;
6842
6843 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00006844 {
6845 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
6846 break;
6847 }
cristy3ed852e2009-09-05 21:47:34 +00006848 if (attributes == (const xmlChar **) NULL)
6849 break;
6850 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6851 {
6852 keyword=(const char *) attributes[i++];
6853 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006854 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00006855 switch (*keyword)
6856 {
6857 case 'I':
6858 case 'i':
6859 {
6860 if (LocaleCompare(keyword,"image") == 0)
6861 {
6862 for (j=0; j<msl_info->n;j++)
6863 {
6864 const char *
6865 theAttr = GetImageProperty(msl_info->attributes[j], "id");
6866 if (theAttr && LocaleCompare(theAttr, value) == 0)
6867 {
6868 stereoImage = msl_info->image[j];
6869 break;
6870 }
6871 }
6872 break;
6873 }
6874 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6875 break;
6876 }
6877 default:
6878 {
6879 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6880 break;
6881 }
6882 }
6883 }
6884
6885 /*
6886 process image.
6887 */
6888 if ( stereoImage != (Image*) NULL )
6889 {
6890 Image
6891 *newImage;
6892
6893 newImage=StereoImage(msl_info->image[n], stereoImage, &msl_info->image[n]->exception);
6894 if (newImage == (Image *) NULL)
6895 break;
6896 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6897 msl_info->image[n]=newImage;
6898 break;
6899 } else
6900 ThrowMSLException(OptionError,"Missing stereo image",keyword);
6901 }
cristyb988fe72009-09-16 01:01:10 +00006902 if (LocaleCompare((const char *) tag,"swap") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006903 {
6904 Image
6905 *p,
6906 *q,
6907 *swap;
6908
cristybb503372010-05-27 20:51:26 +00006909 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00006910 index,
6911 swap_index;
6912
6913 if (msl_info->image[n] == (Image *) NULL)
6914 {
cristyb988fe72009-09-16 01:01:10 +00006915 ThrowMSLException(OptionError,"NoImagesDefined",
6916 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006917 break;
6918 }
6919 index=(-1);
6920 swap_index=(-2);
6921 if (attributes != (const xmlChar **) NULL)
6922 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6923 {
6924 keyword=(const char *) attributes[i++];
6925 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006926 msl_info->attributes[n],(const char *) attributes[i],
6927 &exception);
cristy3ed852e2009-09-05 21:47:34 +00006928 CloneString(&value,attribute);
6929 switch (*keyword)
6930 {
6931 case 'G':
6932 case 'g':
6933 {
6934 if (LocaleCompare(keyword,"indexes") == 0)
6935 {
6936 flags=ParseGeometry(value,&geometry_info);
cristybb503372010-05-27 20:51:26 +00006937 index=(ssize_t) geometry_info.rho;
cristy3ed852e2009-09-05 21:47:34 +00006938 if ((flags & SigmaValue) == 0)
cristybb503372010-05-27 20:51:26 +00006939 swap_index=(ssize_t) geometry_info.sigma;
cristy3ed852e2009-09-05 21:47:34 +00006940 break;
6941 }
6942 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6943 keyword);
6944 break;
6945 }
6946 default:
6947 {
6948 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6949 keyword);
6950 break;
6951 }
6952 }
6953 }
6954 /*
6955 Swap images.
6956 */
6957 p=GetImageFromList(msl_info->image[n],index);
6958 q=GetImageFromList(msl_info->image[n],swap_index);
6959 if ((p == (Image *) NULL) || (q == (Image *) NULL))
6960 {
cristyb988fe72009-09-16 01:01:10 +00006961 ThrowMSLException(OptionError,"NoSuchImage",(const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006962 break;
6963 }
6964 swap=CloneImage(p,0,0,MagickTrue,&p->exception);
6965 ReplaceImageInList(&p,CloneImage(q,0,0,MagickTrue,&q->exception));
6966 ReplaceImageInList(&q,swap);
6967 msl_info->image[n]=GetFirstImageInList(q);
6968 break;
6969 }
cristyb988fe72009-09-16 01:01:10 +00006970 if (LocaleCompare((const char *) tag,"swirl") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006971 {
6972 Image
6973 *swirl_image;
6974
6975 /*
6976 Swirl image.
6977 */
6978 if (msl_info->image[n] == (Image *) NULL)
6979 {
cristyb988fe72009-09-16 01:01:10 +00006980 ThrowMSLException(OptionError,"NoImagesDefined",
6981 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006982 break;
6983 }
6984 if (attributes != (const xmlChar **) NULL)
6985 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6986 {
6987 keyword=(const char *) attributes[i++];
6988 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006989 msl_info->attributes[n],(const char *) attributes[i],
6990 &exception);
cristy3ed852e2009-09-05 21:47:34 +00006991 CloneString(&value,attribute);
6992 switch (*keyword)
6993 {
6994 case 'D':
6995 case 'd':
6996 {
6997 if (LocaleCompare(keyword,"degrees") == 0)
6998 {
cristyc1acd842011-05-19 23:05:47 +00006999 geometry_info.rho=InterpretLocaleValue(value,
7000 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00007001 break;
7002 }
7003 ThrowMSLException(OptionError,"UnrecognizedAttribute",
7004 keyword);
7005 break;
7006 }
7007 case 'G':
7008 case 'g':
7009 {
7010 if (LocaleCompare(keyword,"geometry") == 0)
7011 {
7012 flags=ParseGeometry(value,&geometry_info);
7013 if ((flags & SigmaValue) == 0)
7014 geometry_info.sigma=1.0;
7015 break;
7016 }
7017 ThrowMSLException(OptionError,"UnrecognizedAttribute",
7018 keyword);
7019 break;
7020 }
7021 default:
7022 {
7023 ThrowMSLException(OptionError,"UnrecognizedAttribute",
7024 keyword);
7025 break;
7026 }
7027 }
7028 }
7029 swirl_image=SwirlImage(msl_info->image[n],geometry_info.rho,
cristy76f512e2011-09-12 01:26:56 +00007030 msl_info->image[n]->interpolate,&msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00007031 if (swirl_image == (Image *) NULL)
7032 break;
7033 msl_info->image[n]=DestroyImage(msl_info->image[n]);
7034 msl_info->image[n]=swirl_image;
7035 break;
7036 }
cristyb988fe72009-09-16 01:01:10 +00007037 if (LocaleCompare((const char *) tag,"sync") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007038 {
7039 /*
7040 Sync image.
7041 */
7042 if (msl_info->image[n] == (Image *) NULL)
7043 {
cristyb988fe72009-09-16 01:01:10 +00007044 ThrowMSLException(OptionError,"NoImagesDefined",
7045 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00007046 break;
7047 }
7048 if (attributes != (const xmlChar **) NULL)
7049 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7050 {
7051 keyword=(const char *) attributes[i++];
7052 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00007053 msl_info->attributes[n],(const char *) attributes[i],
7054 &exception);
cristy3ed852e2009-09-05 21:47:34 +00007055 CloneString(&value,attribute);
7056 switch (*keyword)
7057 {
7058 default:
7059 {
7060 ThrowMSLException(OptionError,"UnrecognizedAttribute",
7061 keyword);
7062 break;
7063 }
7064 }
7065 }
7066 (void) SyncImage(msl_info->image[n]);
7067 break;
7068 }
7069 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7070 }
7071 case 'T':
7072 case 't':
7073 {
cristyb988fe72009-09-16 01:01:10 +00007074 if (LocaleCompare((const char *) tag,"map") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007075 {
7076 Image
7077 *texture_image;
7078
7079 /*
7080 Texture image.
7081 */
7082 if (msl_info->image[n] == (Image *) NULL)
7083 {
cristyb988fe72009-09-16 01:01:10 +00007084 ThrowMSLException(OptionError,"NoImagesDefined",
7085 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00007086 break;
7087 }
7088 texture_image=NewImageList();
7089 if (attributes != (const xmlChar **) NULL)
7090 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7091 {
7092 keyword=(const char *) attributes[i++];
7093 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00007094 msl_info->attributes[n],(const char *) attributes[i],
7095 &exception);
cristy3ed852e2009-09-05 21:47:34 +00007096 CloneString(&value,attribute);
7097 switch (*keyword)
7098 {
7099 case 'I':
7100 case 'i':
7101 {
7102 if (LocaleCompare(keyword,"image") == 0)
7103 for (j=0; j < msl_info->n; j++)
7104 {
7105 const char
7106 *attribute;
cristyb988fe72009-09-16 01:01:10 +00007107
cristy3ed852e2009-09-05 21:47:34 +00007108 attribute=GetImageProperty(msl_info->attributes[j],"id");
7109 if ((attribute != (const char *) NULL) &&
7110 (LocaleCompare(attribute,value) == 0))
7111 {
7112 texture_image=CloneImage(msl_info->image[j],0,0,
7113 MagickFalse,&exception);
7114 break;
7115 }
7116 }
7117 break;
7118 }
7119 default:
7120 {
7121 ThrowMSLException(OptionError,"UnrecognizedAttribute",
7122 keyword);
7123 break;
7124 }
7125 }
7126 }
7127 (void) TextureImage(msl_info->image[n],texture_image);
7128 texture_image=DestroyImage(texture_image);
7129 break;
7130 }
cristyb988fe72009-09-16 01:01:10 +00007131 else if (LocaleCompare((const char *) tag,"threshold") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007132 {
7133 /* init the values */
7134 double threshold = 0;
7135
7136 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007137 {
7138 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7139 break;
7140 }
cristy3ed852e2009-09-05 21:47:34 +00007141 if (attributes == (const xmlChar **) NULL)
7142 break;
7143 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7144 {
7145 keyword=(const char *) attributes[i++];
7146 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00007147 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00007148 switch (*keyword)
7149 {
7150 case 'T':
7151 case 't':
7152 {
7153 if (LocaleCompare(keyword,"threshold") == 0)
7154 {
cristyc1acd842011-05-19 23:05:47 +00007155 threshold = InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00007156 break;
7157 }
7158 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7159 break;
7160 }
7161 default:
7162 {
7163 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7164 break;
7165 }
7166 }
7167 }
7168
7169 /*
7170 process image.
7171 */
7172 {
cristyf4ad9df2011-07-08 16:49:03 +00007173 BilevelImage(msl_info->image[n],threshold);
cristy3ed852e2009-09-05 21:47:34 +00007174 break;
7175 }
7176 }
cristyb988fe72009-09-16 01:01:10 +00007177 else if (LocaleCompare((const char *) tag, "transparent") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007178 {
7179 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007180 {
7181 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7182 break;
7183 }
cristy3ed852e2009-09-05 21:47:34 +00007184 if (attributes == (const xmlChar **) NULL)
7185 break;
7186 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7187 {
7188 keyword=(const char *) attributes[i++];
7189 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00007190 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00007191 switch (*keyword)
7192 {
7193 case 'C':
7194 case 'c':
7195 {
7196 if (LocaleCompare(keyword,"color") == 0)
7197 {
cristy4c08aed2011-07-01 19:47:50 +00007198 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00007199 target;
7200
cristy9950d572011-10-01 18:22:35 +00007201 (void) QueryMagickColorCompliance(value,AllCompliance,&target,
7202 &exception);
cristy3ed852e2009-09-05 21:47:34 +00007203 (void) TransparentPaintImage(msl_info->image[n],&target,
cristy189e84c2011-08-27 18:08:53 +00007204 TransparentAlpha,MagickFalse,&msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00007205 break;
7206 }
7207 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7208 break;
7209 }
7210 default:
7211 {
7212 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7213 break;
7214 }
7215 }
7216 }
7217 break;
7218 }
cristyb988fe72009-09-16 01:01:10 +00007219 else if (LocaleCompare((const char *) tag, "trim") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007220 {
7221 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007222 {
7223 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7224 break;
7225 }
cristy3ed852e2009-09-05 21:47:34 +00007226
7227 /* no attributes here */
7228
7229 /* process the image */
7230 {
7231 Image
7232 *newImage;
7233 RectangleInfo
7234 rectInfo;
7235
7236 /* all zeros on a crop == trim edges! */
7237 rectInfo.height = rectInfo.width = 0;
7238 rectInfo.x = rectInfo.y = 0;
7239
7240 newImage=CropImage(msl_info->image[n],&rectInfo, &msl_info->image[n]->exception);
7241 if (newImage == (Image *) NULL)
7242 break;
7243 msl_info->image[n]=DestroyImage(msl_info->image[n]);
7244 msl_info->image[n]=newImage;
7245 break;
7246 }
7247 }
7248 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7249 }
7250 case 'W':
7251 case 'w':
7252 {
cristyb988fe72009-09-16 01:01:10 +00007253 if (LocaleCompare((const char *) tag,"write") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007254 {
7255 if (msl_info->image[n] == (Image *) NULL)
7256 {
cristyb988fe72009-09-16 01:01:10 +00007257 ThrowMSLException(OptionError,"NoImagesDefined",
7258 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00007259 break;
7260 }
7261 if (attributes == (const xmlChar **) NULL)
7262 break;
7263 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7264 {
7265 keyword=(const char *) attributes[i++];
7266 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00007267 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00007268 switch (*keyword)
7269 {
7270 case 'F':
7271 case 'f':
7272 {
7273 if (LocaleCompare(keyword,"filename") == 0)
7274 {
7275 (void) CopyMagickString(msl_info->image[n]->filename,value,
7276 MaxTextExtent);
7277 break;
7278 }
cristy4582cbb2009-09-23 00:35:43 +00007279 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00007280 }
7281 default:
7282 {
cristy4582cbb2009-09-23 00:35:43 +00007283 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00007284 break;
7285 }
7286 }
7287 }
7288
7289 /* process */
7290 {
cristy6f9e0d32011-08-28 16:32:09 +00007291 (void) WriteImage(msl_info->image_info[n], msl_info->image[n],
7292 &msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00007293 break;
7294 }
7295 }
7296 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7297 }
7298 default:
7299 {
7300 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7301 break;
7302 }
7303 }
7304 if ( value != NULL )
7305 value=DestroyString(value);
7306 (void) LogMagickEvent(CoderEvent,GetMagickModule()," )");
7307}
7308
7309static void MSLEndElement(void *context,const xmlChar *tag)
7310{
cristybb503372010-05-27 20:51:26 +00007311 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00007312 n;
7313
7314 MSLInfo
7315 *msl_info;
7316
7317 /*
7318 Called when the end of an element has been detected.
7319 */
7320 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.endElement(%s)",
7321 tag);
7322 msl_info=(MSLInfo *) context;
7323 n=msl_info->n;
7324 switch (*tag)
7325 {
7326 case 'C':
7327 case 'c':
7328 {
cristyb988fe72009-09-16 01:01:10 +00007329 if (LocaleCompare((const char *) tag,"comment") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007330 {
7331 (void) DeleteImageProperty(msl_info->image[n],"comment");
7332 if (msl_info->content == (char *) NULL)
7333 break;
7334 StripString(msl_info->content);
7335 (void) SetImageProperty(msl_info->image[n],"comment",
7336 msl_info->content);
7337 break;
7338 }
7339 break;
7340 }
7341 case 'G':
7342 case 'g':
7343 {
cristyb988fe72009-09-16 01:01:10 +00007344 if (LocaleCompare((const char *) tag, "group") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007345 {
7346 if (msl_info->group_info[msl_info->number_groups-1].numImages > 0 )
7347 {
cristybb503372010-05-27 20:51:26 +00007348 ssize_t i = (ssize_t)
cristy3ed852e2009-09-05 21:47:34 +00007349 (msl_info->group_info[msl_info->number_groups-1].numImages);
7350 while ( i-- )
7351 {
7352 if (msl_info->image[msl_info->n] != (Image *) NULL)
7353 msl_info->image[msl_info->n]=DestroyImage(msl_info->image[msl_info->n]);
7354 msl_info->attributes[msl_info->n]=DestroyImage(msl_info->attributes[msl_info->n]);
7355 msl_info->image_info[msl_info->n]=DestroyImageInfo(msl_info->image_info[msl_info->n]);
7356 msl_info->n--;
7357 }
7358 }
7359 msl_info->number_groups--;
7360 }
7361 break;
7362 }
7363 case 'I':
7364 case 'i':
7365 {
cristyb988fe72009-09-16 01:01:10 +00007366 if (LocaleCompare((const char *) tag, "image") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007367 MSLPopImage(msl_info);
7368 break;
7369 }
7370 case 'L':
7371 case 'l':
7372 {
cristyb988fe72009-09-16 01:01:10 +00007373 if (LocaleCompare((const char *) tag,"label") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007374 {
7375 (void) DeleteImageProperty(msl_info->image[n],"label");
7376 if (msl_info->content == (char *) NULL)
7377 break;
7378 StripString(msl_info->content);
7379 (void) SetImageProperty(msl_info->image[n],"label",
7380 msl_info->content);
7381 break;
7382 }
7383 break;
7384 }
7385 case 'M':
7386 case 'm':
7387 {
cristyb988fe72009-09-16 01:01:10 +00007388 if (LocaleCompare((const char *) tag, "msl") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007389 {
7390 /*
7391 This our base element.
7392 at the moment we don't do anything special
7393 but someday we might!
7394 */
7395 }
7396 break;
7397 }
7398 default:
7399 break;
7400 }
7401 if (msl_info->content != (char *) NULL)
7402 msl_info->content=DestroyString(msl_info->content);
7403}
7404
7405static void MSLCharacters(void *context,const xmlChar *c,int length)
7406{
7407 MSLInfo
7408 *msl_info;
7409
7410 register char
7411 *p;
7412
cristybb503372010-05-27 20:51:26 +00007413 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00007414 i;
7415
7416 /*
7417 Receiving some characters from the parser.
7418 */
7419 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7420 " SAX.characters(%s,%d)",c,length);
7421 msl_info=(MSLInfo *) context;
7422 if (msl_info->content != (char *) NULL)
7423 msl_info->content=(char *) ResizeQuantumMemory(msl_info->content,
7424 strlen(msl_info->content)+length+MaxTextExtent,
7425 sizeof(*msl_info->content));
7426 else
7427 {
7428 msl_info->content=(char *) NULL;
cristy37e0b382011-06-07 13:31:21 +00007429 if (~length >= (MaxTextExtent-1))
cristy3ed852e2009-09-05 21:47:34 +00007430 msl_info->content=(char *) AcquireQuantumMemory(length+MaxTextExtent,
7431 sizeof(*msl_info->content));
7432 if (msl_info->content != (char *) NULL)
7433 *msl_info->content='\0';
7434 }
7435 if (msl_info->content == (char *) NULL)
7436 return;
7437 p=msl_info->content+strlen(msl_info->content);
7438 for (i=0; i < length; i++)
7439 *p++=c[i];
7440 *p='\0';
7441}
7442
7443static void MSLReference(void *context,const xmlChar *name)
7444{
7445 MSLInfo
7446 *msl_info;
7447
7448 xmlParserCtxtPtr
7449 parser;
7450
7451 /*
7452 Called when an entity reference is detected.
7453 */
7454 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7455 " SAX.reference(%s)",name);
7456 msl_info=(MSLInfo *) context;
7457 parser=msl_info->parser;
7458 if (*name == '#')
7459 (void) xmlAddChild(parser->node,xmlNewCharRef(msl_info->document,name));
7460 else
7461 (void) xmlAddChild(parser->node,xmlNewReference(msl_info->document,name));
7462}
7463
7464static void MSLIgnorableWhitespace(void *context,const xmlChar *c,int length)
7465{
7466 MSLInfo
7467 *msl_info;
7468
7469 /*
7470 Receiving some ignorable whitespaces from the parser.
7471 */
7472 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7473 " SAX.ignorableWhitespace(%.30s, %d)",c,length);
7474 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007475 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007476}
7477
7478static void MSLProcessingInstructions(void *context,const xmlChar *target,
7479 const xmlChar *data)
7480{
7481 MSLInfo
7482 *msl_info;
7483
7484 /*
7485 A processing instruction has been parsed.
7486 */
7487 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7488 " SAX.processingInstruction(%s, %s)",
7489 target,data);
7490 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007491 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007492}
7493
7494static void MSLComment(void *context,const xmlChar *value)
7495{
7496 MSLInfo
7497 *msl_info;
7498
7499 /*
7500 A comment has been parsed.
7501 */
7502 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7503 " SAX.comment(%s)",value);
7504 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007505 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007506}
7507
7508static void MSLWarning(void *context,const char *format,...)
7509{
7510 char
7511 *message,
7512 reason[MaxTextExtent];
7513
7514 MSLInfo
7515 *msl_info;
7516
7517 va_list
7518 operands;
7519
7520 /**
7521 Display and format a warning messages, gives file, line, position and
7522 extra parameters.
7523 */
7524 va_start(operands,format);
7525 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.warning: ");
7526 (void) LogMagickEvent(CoderEvent,GetMagickModule(),format,operands);
7527 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007528 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007529#if !defined(MAGICKCORE_HAVE_VSNPRINTF)
7530 (void) vsprintf(reason,format,operands);
7531#else
7532 (void) vsnprintf(reason,MaxTextExtent,format,operands);
7533#endif
7534 message=GetExceptionMessage(errno);
7535 ThrowMSLException(CoderError,reason,message);
7536 message=DestroyString(message);
7537 va_end(operands);
7538}
7539
7540static void MSLError(void *context,const char *format,...)
7541{
7542 char
7543 reason[MaxTextExtent];
7544
7545 MSLInfo
7546 *msl_info;
7547
7548 va_list
7549 operands;
7550
7551 /*
7552 Display and format a error formats, gives file, line, position and
7553 extra parameters.
7554 */
7555 va_start(operands,format);
7556 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.error: ");
7557 (void) LogMagickEvent(CoderEvent,GetMagickModule(),format,operands);
7558 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007559 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007560#if !defined(MAGICKCORE_HAVE_VSNPRINTF)
7561 (void) vsprintf(reason,format,operands);
7562#else
7563 (void) vsnprintf(reason,MaxTextExtent,format,operands);
7564#endif
7565 ThrowMSLException(DelegateFatalError,reason,"SAX error");
7566 va_end(operands);
7567}
7568
7569static void MSLCDataBlock(void *context,const xmlChar *value,int length)
7570{
7571 MSLInfo
7572 *msl_info;
7573
7574 xmlNodePtr
7575 child;
7576
7577 xmlParserCtxtPtr
7578 parser;
7579
7580 /*
7581 Called when a pcdata block has been parsed.
7582 */
7583 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7584 " SAX.pcdata(%s, %d)",value,length);
7585 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007586 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007587 parser=msl_info->parser;
7588 child=xmlGetLastChild(parser->node);
7589 if ((child != (xmlNodePtr) NULL) && (child->type == XML_CDATA_SECTION_NODE))
7590 {
7591 xmlTextConcat(child,value,length);
7592 return;
7593 }
7594 (void) xmlAddChild(parser->node,xmlNewCDataBlock(parser->myDoc,value,length));
7595}
7596
7597static void MSLExternalSubset(void *context,const xmlChar *name,
7598 const xmlChar *external_id,const xmlChar *system_id)
7599{
7600 MSLInfo
7601 *msl_info;
7602
7603 xmlParserCtxt
7604 parser_context;
7605
7606 xmlParserCtxtPtr
7607 parser;
7608
7609 xmlParserInputPtr
7610 input;
7611
7612 /*
7613 Does this document has an external subset?
7614 */
7615 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7616 " SAX.externalSubset(%s %s %s)",name,
cristyb988fe72009-09-16 01:01:10 +00007617 (external_id != (const xmlChar *) NULL ? (const char *) external_id : " "),
7618 (system_id != (const xmlChar *) NULL ? (const char *) system_id : " "));
cristy3ed852e2009-09-05 21:47:34 +00007619 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007620 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007621 parser=msl_info->parser;
7622 if (((external_id == NULL) && (system_id == NULL)) ||
7623 ((parser->validate == 0) || (parser->wellFormed == 0) ||
7624 (msl_info->document == 0)))
7625 return;
7626 input=MSLResolveEntity(context,external_id,system_id);
7627 if (input == NULL)
7628 return;
7629 (void) xmlNewDtd(msl_info->document,name,external_id,system_id);
7630 parser_context=(*parser);
7631 parser->inputTab=(xmlParserInputPtr *) xmlMalloc(5*sizeof(*parser->inputTab));
7632 if (parser->inputTab == (xmlParserInputPtr *) NULL)
7633 {
7634 parser->errNo=XML_ERR_NO_MEMORY;
7635 parser->input=parser_context.input;
7636 parser->inputNr=parser_context.inputNr;
7637 parser->inputMax=parser_context.inputMax;
7638 parser->inputTab=parser_context.inputTab;
7639 return;
7640 }
7641 parser->inputNr=0;
7642 parser->inputMax=5;
7643 parser->input=NULL;
7644 xmlPushInput(parser,input);
7645 (void) xmlSwitchEncoding(parser,xmlDetectCharEncoding(parser->input->cur,4));
7646 if (input->filename == (char *) NULL)
7647 input->filename=(char *) xmlStrdup(system_id);
7648 input->line=1;
7649 input->col=1;
7650 input->base=parser->input->cur;
7651 input->cur=parser->input->cur;
7652 input->free=NULL;
7653 xmlParseExternalSubset(parser,external_id,system_id);
7654 while (parser->inputNr > 1)
7655 (void) xmlPopInput(parser);
7656 xmlFreeInputStream(parser->input);
7657 xmlFree(parser->inputTab);
7658 parser->input=parser_context.input;
7659 parser->inputNr=parser_context.inputNr;
7660 parser->inputMax=parser_context.inputMax;
7661 parser->inputTab=parser_context.inputTab;
7662}
7663
7664#if defined(__cplusplus) || defined(c_plusplus)
7665}
7666#endif
7667
7668static MagickBooleanType ProcessMSLScript(const ImageInfo *image_info,Image **image,
7669 ExceptionInfo *exception)
7670{
cristy3ed852e2009-09-05 21:47:34 +00007671 char
7672 message[MaxTextExtent];
7673
7674 Image
7675 *msl_image;
7676
7677 int
7678 status;
7679
cristybb503372010-05-27 20:51:26 +00007680 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00007681 n;
7682
7683 MSLInfo
7684 msl_info;
7685
cristy5f6f01c2009-11-19 19:36:42 +00007686 xmlSAXHandler
7687 sax_modules;
7688
cristy3ed852e2009-09-05 21:47:34 +00007689 xmlSAXHandlerPtr
cristy5f6f01c2009-11-19 19:36:42 +00007690 sax_handler;
cristy3ed852e2009-09-05 21:47:34 +00007691
7692 /*
7693 Open image file.
7694 */
7695 assert(image_info != (const ImageInfo *) NULL);
7696 assert(image_info->signature == MagickSignature);
7697 if (image_info->debug != MagickFalse)
cristy5f6f01c2009-11-19 19:36:42 +00007698 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
7699 image_info->filename);
cristy3ed852e2009-09-05 21:47:34 +00007700 assert(image != (Image **) NULL);
cristy9950d572011-10-01 18:22:35 +00007701 msl_image=AcquireImage(image_info,exception);
cristy3ed852e2009-09-05 21:47:34 +00007702 status=OpenBlob(image_info,msl_image,ReadBinaryBlobMode,exception);
7703 if (status == MagickFalse)
7704 {
7705 ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
7706 msl_image->filename);
7707 msl_image=DestroyImageList(msl_image);
7708 return(MagickFalse);
7709 }
7710 msl_image->columns=1;
7711 msl_image->rows=1;
7712 /*
7713 Parse MSL file.
7714 */
7715 (void) ResetMagickMemory(&msl_info,0,sizeof(msl_info));
7716 msl_info.exception=exception;
7717 msl_info.image_info=(ImageInfo **) AcquireMagickMemory(
7718 sizeof(*msl_info.image_info));
7719 msl_info.draw_info=(DrawInfo **) AcquireMagickMemory(
7720 sizeof(*msl_info.draw_info));
7721 /* top of the stack is the MSL file itself */
cristy73bd4a52010-10-05 11:24:23 +00007722 msl_info.image=(Image **) AcquireMagickMemory(sizeof(*msl_info.image));
cristy3ed852e2009-09-05 21:47:34 +00007723 msl_info.attributes=(Image **) AcquireMagickMemory(
7724 sizeof(*msl_info.attributes));
7725 msl_info.group_info=(MSLGroupInfo *) AcquireMagickMemory(
7726 sizeof(*msl_info.group_info));
7727 if ((msl_info.image_info == (ImageInfo **) NULL) ||
7728 (msl_info.image == (Image **) NULL) ||
7729 (msl_info.attributes == (Image **) NULL) ||
7730 (msl_info.group_info == (MSLGroupInfo *) NULL))
7731 ThrowFatalException(ResourceLimitFatalError,
7732 "UnableToInterpretMSLImage");
7733 *msl_info.image_info=CloneImageInfo(image_info);
7734 *msl_info.draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL);
cristy9950d572011-10-01 18:22:35 +00007735 *msl_info.attributes=AcquireImage(image_info,exception);
cristy3ed852e2009-09-05 21:47:34 +00007736 msl_info.group_info[0].numImages=0;
7737 /* the first slot is used to point to the MSL file image */
7738 *msl_info.image=msl_image;
7739 if (*image != (Image *) NULL)
7740 MSLPushImage(&msl_info,*image);
7741 (void) xmlSubstituteEntitiesDefault(1);
cristy5f6f01c2009-11-19 19:36:42 +00007742 (void) ResetMagickMemory(&sax_modules,0,sizeof(sax_modules));
7743 sax_modules.internalSubset=MSLInternalSubset;
7744 sax_modules.isStandalone=MSLIsStandalone;
7745 sax_modules.hasInternalSubset=MSLHasInternalSubset;
7746 sax_modules.hasExternalSubset=MSLHasExternalSubset;
7747 sax_modules.resolveEntity=MSLResolveEntity;
7748 sax_modules.getEntity=MSLGetEntity;
7749 sax_modules.entityDecl=MSLEntityDeclaration;
7750 sax_modules.notationDecl=MSLNotationDeclaration;
7751 sax_modules.attributeDecl=MSLAttributeDeclaration;
7752 sax_modules.elementDecl=MSLElementDeclaration;
7753 sax_modules.unparsedEntityDecl=MSLUnparsedEntityDeclaration;
7754 sax_modules.setDocumentLocator=MSLSetDocumentLocator;
7755 sax_modules.startDocument=MSLStartDocument;
7756 sax_modules.endDocument=MSLEndDocument;
7757 sax_modules.startElement=MSLStartElement;
7758 sax_modules.endElement=MSLEndElement;
7759 sax_modules.reference=MSLReference;
7760 sax_modules.characters=MSLCharacters;
7761 sax_modules.ignorableWhitespace=MSLIgnorableWhitespace;
7762 sax_modules.processingInstruction=MSLProcessingInstructions;
7763 sax_modules.comment=MSLComment;
7764 sax_modules.warning=MSLWarning;
7765 sax_modules.error=MSLError;
7766 sax_modules.fatalError=MSLError;
7767 sax_modules.getParameterEntity=MSLGetParameterEntity;
7768 sax_modules.cdataBlock=MSLCDataBlock;
7769 sax_modules.externalSubset=MSLExternalSubset;
7770 sax_handler=(&sax_modules);
7771 msl_info.parser=xmlCreatePushParserCtxt(sax_handler,&msl_info,(char *) NULL,0,
cristy3ed852e2009-09-05 21:47:34 +00007772 msl_image->filename);
7773 while (ReadBlobString(msl_image,message) != (char *) NULL)
7774 {
cristybb503372010-05-27 20:51:26 +00007775 n=(ssize_t) strlen(message);
cristy3ed852e2009-09-05 21:47:34 +00007776 if (n == 0)
7777 continue;
7778 status=xmlParseChunk(msl_info.parser,message,(int) n,MagickFalse);
7779 if (status != 0)
7780 break;
7781 (void) xmlParseChunk(msl_info.parser," ",1,MagickFalse);
7782 if (msl_info.exception->severity >= ErrorException)
7783 break;
7784 }
7785 if (msl_info.exception->severity == UndefinedException)
7786 (void) xmlParseChunk(msl_info.parser," ",1,MagickTrue);
7787 xmlFreeParserCtxt(msl_info.parser);
7788 (void) LogMagickEvent(CoderEvent,GetMagickModule(),"end SAX");
7789 xmlCleanupParser();
7790 msl_info.group_info=(MSLGroupInfo *) RelinquishMagickMemory(
7791 msl_info.group_info);
7792 if (*image == (Image *) NULL)
7793 *image=(*msl_info.image);
cristy5f6f01c2009-11-19 19:36:42 +00007794 if ((*msl_info.image)->exception.severity != UndefinedException)
7795 return(MagickFalse);
7796 return(MagickTrue);
cristy3ed852e2009-09-05 21:47:34 +00007797}
7798
7799static Image *ReadMSLImage(const ImageInfo *image_info,ExceptionInfo *exception)
7800{
7801 Image
7802 *image;
7803
7804 /*
7805 Open image file.
7806 */
7807 assert(image_info != (const ImageInfo *) NULL);
7808 assert(image_info->signature == MagickSignature);
7809 if (image_info->debug != MagickFalse)
7810 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
7811 image_info->filename);
7812 assert(exception != (ExceptionInfo *) NULL);
7813 assert(exception->signature == MagickSignature);
7814 image=(Image *) NULL;
7815 (void) ProcessMSLScript(image_info,&image,exception);
7816 return(GetFirstImageInList(image));
7817}
7818#endif
7819
7820/*
7821%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7822% %
7823% %
7824% %
7825% R e g i s t e r M S L I m a g e %
7826% %
7827% %
7828% %
7829%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7830%
7831% RegisterMSLImage() adds attributes for the MSL image format to
7832% the list of supported formats. The attributes include the image format
7833% tag, a method to read and/or write the format, whether the format
7834% supports the saving of more than one frame to the same file or blob,
7835% whether the format supports native in-memory I/O, and a brief
7836% description of the format.
7837%
7838% The format of the RegisterMSLImage method is:
7839%
cristybb503372010-05-27 20:51:26 +00007840% size_t RegisterMSLImage(void)
cristy3ed852e2009-09-05 21:47:34 +00007841%
7842*/
cristybb503372010-05-27 20:51:26 +00007843ModuleExport size_t RegisterMSLImage(void)
cristy3ed852e2009-09-05 21:47:34 +00007844{
7845 MagickInfo
7846 *entry;
7847
7848 entry=SetMagickInfo("MSL");
7849#if defined(MAGICKCORE_XML_DELEGATE)
7850 entry->decoder=(DecodeImageHandler *) ReadMSLImage;
7851 entry->encoder=(EncodeImageHandler *) WriteMSLImage;
7852#endif
7853 entry->description=ConstantString("Magick Scripting Language");
7854 entry->module=ConstantString("MSL");
7855 (void) RegisterMagickInfo(entry);
7856 return(MagickImageCoderSignature);
7857}
7858
cristy6b9f7ed2010-04-24 01:08:02 +00007859#if defined(MAGICKCORE_XML_DELEGATE)
cristy3ed852e2009-09-05 21:47:34 +00007860/*
7861%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7862% %
7863% %
7864% %
cristyb988fe72009-09-16 01:01:10 +00007865% S e t M S L A t t r i b u t e s %
7866% %
7867% %
7868% %
7869%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7870%
7871% SetMSLAttributes() ...
7872%
7873% The format of the SetMSLAttributes method is:
7874%
7875% MagickBooleanType SetMSLAttributes(MSLInfo *msl_info,
cristyb20775d2009-09-16 01:51:41 +00007876% const char *keyword,const char *value)
cristyb988fe72009-09-16 01:01:10 +00007877%
7878% A description of each parameter follows:
7879%
7880% o msl_info: the MSL info.
7881%
cristyb20775d2009-09-16 01:51:41 +00007882% o keyword: the keyword.
7883%
7884% o value: the value.
cristyb988fe72009-09-16 01:01:10 +00007885%
7886*/
cristyb20775d2009-09-16 01:51:41 +00007887static MagickBooleanType SetMSLAttributes(MSLInfo *msl_info,const char *keyword,
7888 const char *value)
cristyb988fe72009-09-16 01:01:10 +00007889{
cristy4582cbb2009-09-23 00:35:43 +00007890 Image
7891 *attributes;
7892
cristyb20775d2009-09-16 01:51:41 +00007893 DrawInfo
7894 *draw_info;
cristyb988fe72009-09-16 01:01:10 +00007895
7896 ExceptionInfo
7897 *exception;
7898
cristy4582cbb2009-09-23 00:35:43 +00007899 GeometryInfo
7900 geometry_info;
7901
cristy4fa36e42009-09-18 14:24:06 +00007902 Image
7903 *image;
7904
cristyb20775d2009-09-16 01:51:41 +00007905 ImageInfo
7906 *image_info;
7907
cristy4582cbb2009-09-23 00:35:43 +00007908 int
7909 flags;
7910
cristybb503372010-05-27 20:51:26 +00007911 ssize_t
cristyb988fe72009-09-16 01:01:10 +00007912 n;
7913
cristyb988fe72009-09-16 01:01:10 +00007914 assert(msl_info != (MSLInfo *) NULL);
cristyb20775d2009-09-16 01:51:41 +00007915 if (keyword == (const char *) NULL)
7916 return(MagickTrue);
7917 if (value == (const char *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007918 return(MagickTrue);
7919 exception=msl_info->exception;
7920 n=msl_info->n;
cristy4582cbb2009-09-23 00:35:43 +00007921 attributes=msl_info->attributes[n];
cristyb20775d2009-09-16 01:51:41 +00007922 image_info=msl_info->image_info[n];
7923 draw_info=msl_info->draw_info[n];
cristy4fa36e42009-09-18 14:24:06 +00007924 image=msl_info->image[n];
cristyb20775d2009-09-16 01:51:41 +00007925 switch (*keyword)
cristyb988fe72009-09-16 01:01:10 +00007926 {
cristyfb758a52009-09-16 14:36:08 +00007927 case 'A':
7928 case 'a':
7929 {
7930 if (LocaleCompare(keyword,"adjoin") == 0)
7931 {
cristybb503372010-05-27 20:51:26 +00007932 ssize_t
cristyfb758a52009-09-16 14:36:08 +00007933 adjoin;
7934
cristy042ee782011-04-22 18:48:30 +00007935 adjoin=ParseCommandOption(MagickBooleanOptions,MagickFalse,value);
cristyfb758a52009-09-16 14:36:08 +00007936 if (adjoin < 0)
7937 ThrowMSLException(OptionError,"UnrecognizedType",value);
7938 image_info->adjoin=(MagickBooleanType) adjoin;
7939 break;
7940 }
cristy4fa36e42009-09-18 14:24:06 +00007941 if (LocaleCompare(keyword,"alpha") == 0)
7942 {
cristybb503372010-05-27 20:51:26 +00007943 ssize_t
cristy4fa36e42009-09-18 14:24:06 +00007944 alpha;
7945
cristy042ee782011-04-22 18:48:30 +00007946 alpha=ParseCommandOption(MagickAlphaOptions,MagickFalse,value);
cristy4fa36e42009-09-18 14:24:06 +00007947 if (alpha < 0)
7948 ThrowMSLException(OptionError,"UnrecognizedType",value);
cristy4582cbb2009-09-23 00:35:43 +00007949 if (image != (Image *) NULL)
cristy63240882011-08-05 19:05:27 +00007950 (void) SetImageAlphaChannel(image,(AlphaChannelType) alpha,
7951 exception);
cristy4582cbb2009-09-23 00:35:43 +00007952 break;
7953 }
7954 if (LocaleCompare(keyword,"antialias") == 0)
7955 {
cristybb503372010-05-27 20:51:26 +00007956 ssize_t
cristy4582cbb2009-09-23 00:35:43 +00007957 antialias;
7958
cristy042ee782011-04-22 18:48:30 +00007959 antialias=ParseCommandOption(MagickBooleanOptions,MagickFalse,value);
cristy4582cbb2009-09-23 00:35:43 +00007960 if (antialias < 0)
7961 ThrowMSLException(OptionError,"UnrecognizedGravityType",value);
7962 image_info->antialias=(MagickBooleanType) antialias;
7963 break;
7964 }
7965 if (LocaleCompare(keyword,"area-limit") == 0)
7966 {
7967 MagickSizeType
7968 limit;
7969
7970 limit=MagickResourceInfinity;
7971 if (LocaleCompare(value,"unlimited") != 0)
cristyf2f27272009-12-17 14:48:46 +00007972 limit=(MagickSizeType) SiPrefixToDouble(value,100.0);
cristy4582cbb2009-09-23 00:35:43 +00007973 (void) SetMagickResourceLimit(AreaResource,limit);
7974 break;
7975 }
7976 if (LocaleCompare(keyword,"attenuate") == 0)
7977 {
7978 (void) SetImageOption(image_info,keyword,value);
7979 break;
7980 }
7981 if (LocaleCompare(keyword,"authenticate") == 0)
7982 {
7983 (void) CloneString(&image_info->density,value);
cristy4fa36e42009-09-18 14:24:06 +00007984 break;
7985 }
cristyfb758a52009-09-16 14:36:08 +00007986 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7987 break;
7988 }
cristyb20775d2009-09-16 01:51:41 +00007989 case 'B':
7990 case 'b':
cristyb988fe72009-09-16 01:01:10 +00007991 {
cristyb20775d2009-09-16 01:51:41 +00007992 if (LocaleCompare(keyword,"background") == 0)
7993 {
cristy9950d572011-10-01 18:22:35 +00007994 (void) QueryColorCompliance(value,AllCompliance,
7995 &image_info->background_color,exception);
cristyb20775d2009-09-16 01:51:41 +00007996 break;
7997 }
cristy4582cbb2009-09-23 00:35:43 +00007998 if (LocaleCompare(keyword,"bias") == 0)
7999 {
8000 if (image == (Image *) NULL)
8001 break;
cristyf2f27272009-12-17 14:48:46 +00008002 image->bias=SiPrefixToDouble(value,QuantumRange);
cristy4582cbb2009-09-23 00:35:43 +00008003 break;
8004 }
8005 if (LocaleCompare(keyword,"blue-primary") == 0)
8006 {
8007 if (image == (Image *) NULL)
8008 break;
8009 flags=ParseGeometry(value,&geometry_info);
8010 image->chromaticity.blue_primary.x=geometry_info.rho;
8011 image->chromaticity.blue_primary.y=geometry_info.sigma;
8012 if ((flags & SigmaValue) == 0)
8013 image->chromaticity.blue_primary.y=
8014 image->chromaticity.blue_primary.x;
8015 break;
8016 }
cristy2c8b6312009-09-16 02:37:23 +00008017 if (LocaleCompare(keyword,"bordercolor") == 0)
8018 {
cristy9950d572011-10-01 18:22:35 +00008019 (void) QueryColorCompliance(value,AllCompliance,
8020 &image_info->border_color,exception);
cristy2c8b6312009-09-16 02:37:23 +00008021 break;
8022 }
8023 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8024 break;
8025 }
8026 case 'D':
8027 case 'd':
8028 {
8029 if (LocaleCompare(keyword,"density") == 0)
8030 {
8031 (void) CloneString(&image_info->density,value);
8032 (void) CloneString(&draw_info->density,value);
8033 break;
8034 }
cristyb20775d2009-09-16 01:51:41 +00008035 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8036 break;
8037 }
8038 case 'F':
8039 case 'f':
8040 {
8041 if (LocaleCompare(keyword,"fill") == 0)
8042 {
cristy9950d572011-10-01 18:22:35 +00008043 (void) QueryColorCompliance(value,AllCompliance,&draw_info->fill,
8044 exception);
cristya30afaf2009-09-22 13:42:12 +00008045 (void) SetImageOption(image_info,keyword,value);
cristyb20775d2009-09-16 01:51:41 +00008046 break;
8047 }
cristy4582cbb2009-09-23 00:35:43 +00008048 if (LocaleCompare(keyword,"filename") == 0)
8049 {
8050 (void) CopyMagickString(image_info->filename,value,MaxTextExtent);
8051 break;
8052 }
8053 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8054 break;
8055 }
8056 case 'G':
8057 case 'g':
8058 {
8059 if (LocaleCompare(keyword,"gravity") == 0)
8060 {
cristybb503372010-05-27 20:51:26 +00008061 ssize_t
cristy4582cbb2009-09-23 00:35:43 +00008062 gravity;
8063
cristy042ee782011-04-22 18:48:30 +00008064 gravity=ParseCommandOption(MagickGravityOptions,MagickFalse,value);
cristy4582cbb2009-09-23 00:35:43 +00008065 if (gravity < 0)
8066 ThrowMSLException(OptionError,"UnrecognizedGravityType",value);
8067 (void) SetImageOption(image_info,keyword,value);
8068 break;
8069 }
cristyb20775d2009-09-16 01:51:41 +00008070 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8071 break;
8072 }
8073 case 'I':
8074 case 'i':
8075 {
8076 if (LocaleCompare(keyword,"id") == 0)
8077 {
cristy4582cbb2009-09-23 00:35:43 +00008078 (void) SetImageProperty(attributes,keyword,value);
cristy2c8b6312009-09-16 02:37:23 +00008079 break;
8080 }
8081 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8082 break;
8083 }
8084 case 'M':
8085 case 'm':
8086 {
8087 if (LocaleCompare(keyword,"magick") == 0)
8088 {
8089 (void) CopyMagickString(image_info->magick,value,MaxTextExtent);
8090 break;
8091 }
cristy2c8b6312009-09-16 02:37:23 +00008092 if (LocaleCompare(keyword,"mattecolor") == 0)
8093 {
cristy9950d572011-10-01 18:22:35 +00008094 (void) QueryColorCompliance(value,AllCompliance,
8095 &image_info->matte_color,exception);
cristyb20775d2009-09-16 01:51:41 +00008096 break;
8097 }
8098 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8099 break;
8100 }
8101 case 'P':
8102 case 'p':
8103 {
8104 if (LocaleCompare(keyword,"pointsize") == 0)
8105 {
cristyc1acd842011-05-19 23:05:47 +00008106 image_info->pointsize=InterpretLocaleValue(value,(char **) NULL);
8107 draw_info->pointsize=InterpretLocaleValue(value,(char **) NULL);
cristyb20775d2009-09-16 01:51:41 +00008108 break;
8109 }
8110 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8111 break;
8112 }
cristy4582cbb2009-09-23 00:35:43 +00008113 case 'Q':
8114 case 'q':
8115 {
8116 if (LocaleCompare(keyword,"quality") == 0)
8117 {
cristyf2f27272009-12-17 14:48:46 +00008118 image_info->quality=StringToLong(value);
cristy4582cbb2009-09-23 00:35:43 +00008119 if (image == (Image *) NULL)
8120 break;
cristyf2f27272009-12-17 14:48:46 +00008121 image->quality=StringToLong(value);
cristy4582cbb2009-09-23 00:35:43 +00008122 break;
8123 }
8124 break;
8125 }
cristyb20775d2009-09-16 01:51:41 +00008126 case 'S':
8127 case 's':
8128 {
8129 if (LocaleCompare(keyword,"size") == 0)
8130 {
cristy2c8b6312009-09-16 02:37:23 +00008131 (void) CloneString(&image_info->size,value);
cristyb20775d2009-09-16 01:51:41 +00008132 break;
8133 }
8134 if (LocaleCompare(keyword,"stroke") == 0)
8135 {
cristy9950d572011-10-01 18:22:35 +00008136 (void) QueryColorCompliance(value,AllCompliance,&draw_info->stroke,
8137 exception);
cristya30afaf2009-09-22 13:42:12 +00008138 (void) SetImageOption(image_info,keyword,value);
cristyb20775d2009-09-16 01:51:41 +00008139 break;
8140 }
8141 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8142 break;
8143 }
8144 default:
8145 {
8146 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8147 break;
cristyb988fe72009-09-16 01:01:10 +00008148 }
8149 }
8150 return(MagickTrue);
8151}
cristy6b9f7ed2010-04-24 01:08:02 +00008152#endif
cristyb988fe72009-09-16 01:01:10 +00008153
8154/*
8155%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8156% %
8157% %
8158% %
cristy3ed852e2009-09-05 21:47:34 +00008159% U n r e g i s t e r M S L I m a g e %
8160% %
8161% %
8162% %
8163%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8164%
8165% UnregisterMSLImage() removes format registrations made by the
8166% MSL module from the list of supported formats.
8167%
8168% The format of the UnregisterMSLImage method is:
8169%
8170% UnregisterMSLImage(void)
8171%
8172*/
8173ModuleExport void UnregisterMSLImage(void)
8174{
8175 (void) UnregisterMagickInfo("MSL");
8176}
8177
8178#if defined(MAGICKCORE_XML_DELEGATE)
8179/*
8180%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8181% %
8182% %
8183% %
8184% W r i t e M S L I m a g e %
8185% %
8186% %
8187% %
8188%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8189%
8190% WriteMSLImage() writes an image to a file in MVG image format.
8191%
8192% The format of the WriteMSLImage method is:
8193%
cristy1e178e72011-08-28 19:44:34 +00008194% MagickBooleanType WriteMSLImage(const ImageInfo *image_info,
8195% Image *image,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00008196%
8197% A description of each parameter follows.
8198%
8199% o image_info: the image info.
8200%
8201% o image: The image.
8202%
cristy1e178e72011-08-28 19:44:34 +00008203% o exception: return any errors or warnings in this structure.
8204%
cristy3ed852e2009-09-05 21:47:34 +00008205*/
cristy1e178e72011-08-28 19:44:34 +00008206static MagickBooleanType WriteMSLImage(const ImageInfo *image_info,Image *image,
8207 ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00008208{
8209 assert(image_info != (const ImageInfo *) NULL);
8210 assert(image_info->signature == MagickSignature);
8211 assert(image != (Image *) NULL);
8212 assert(image->signature == MagickSignature);
8213 if (image->debug != MagickFalse)
8214 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
8215 (void) ReferenceImage(image);
cristy1e178e72011-08-28 19:44:34 +00008216 (void) ProcessMSLScript(image_info,&image,exception);
cristy3ed852e2009-09-05 21:47:34 +00008217 return(MagickTrue);
8218}
8219#endif