blob: e580e060c10c1fb291de71cc27eeaa702f77d851 [file] [log] [blame]
cristy3ed852e2009-09-05 21:47:34 +00001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% %
6% M M SSSSS L %
7% MM MM SS L %
8% M M M SSS L %
9% M M SS L %
10% M M SSSSS LLLLL %
11% %
12% %
13% Execute Magick Scripting Language Scripts. %
14% %
15% Software Design %
16% John Cristy %
17% Leonard Rosenthol %
18% William Radcliffe %
19% December 2001 %
20% %
21% %
cristy7e41fe82010-12-04 23:12:08 +000022% Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization %
cristy3ed852e2009-09-05 21:47:34 +000023% dedicated to making software imaging solutions freely available. %
24% %
25% You may not use this file except in compliance with the License. You may %
26% obtain a copy of the License at %
27% %
28% http://www.imagemagick.org/script/license.php %
29% %
30% Unless required by applicable law or agreed to in writing, software %
31% distributed under the License is distributed on an "AS IS" BASIS, %
32% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
33% See the License for the specific language governing permissions and %
34% limitations under the License. %
35% %
36%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
37%
38%
39*/
40
41/*
42 Include declarations.
43*/
cristy4c08aed2011-07-01 19:47:50 +000044#include "MagickCore/studio.h"
45#include "MagickCore/annotate.h"
46#include "MagickCore/artifact.h"
47#include "MagickCore/blob.h"
48#include "MagickCore/blob-private.h"
49#include "MagickCore/cache.h"
50#include "MagickCore/cache-view.h"
51#include "MagickCore/color.h"
52#include "MagickCore/colormap.h"
53#include "MagickCore/color-private.h"
54#include "MagickCore/composite.h"
55#include "MagickCore/constitute.h"
56#include "MagickCore/decorate.h"
57#include "MagickCore/display.h"
58#include "MagickCore/draw.h"
59#include "MagickCore/effect.h"
60#include "MagickCore/enhance.h"
61#include "MagickCore/exception.h"
62#include "MagickCore/exception-private.h"
63#include "MagickCore/fx.h"
64#include "MagickCore/geometry.h"
65#include "MagickCore/image.h"
66#include "MagickCore/image-private.h"
67#include "MagickCore/list.h"
68#include "MagickCore/log.h"
69#include "MagickCore/magick.h"
70#include "MagickCore/memory_.h"
71#include "MagickCore/module.h"
72#include "MagickCore/option.h"
73#include "MagickCore/paint.h"
74#include "MagickCore/pixel-accessor.h"
75#include "MagickCore/profile.h"
76#include "MagickCore/property.h"
77#include "MagickCore/quantize.h"
78#include "MagickCore/quantum-private.h"
79#include "MagickCore/registry.h"
80#include "MagickCore/resize.h"
81#include "MagickCore/resource_.h"
82#include "MagickCore/segment.h"
83#include "MagickCore/shear.h"
84#include "MagickCore/signature.h"
85#include "MagickCore/static.h"
86#include "MagickCore/string_.h"
87#include "MagickCore/string-private.h"
88#include "MagickCore/transform.h"
89#include "MagickCore/threshold.h"
90#include "MagickCore/utility.h"
cristy3ed852e2009-09-05 21:47:34 +000091#if defined(MAGICKCORE_XML_DELEGATE)
cristy0157aea2010-04-24 21:12:18 +000092# if defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +000093# if defined(__MINGW32__)
94# define _MSC_VER
95# else
96# include <win32config.h>
97# endif
98# endif
99# include <libxml/parser.h>
100# include <libxml/xmlmemory.h>
101# include <libxml/parserInternals.h>
102# include <libxml/xmlerror.h>
103#endif
104
105/*
106 Define Declatations.
107*/
108#define ThrowMSLException(severity,tag,reason) \
109 (void) ThrowMagickException(msl_info->exception,GetMagickModule(),severity, \
110 tag,"`%s'",reason);
111
112/*
113 Typedef declaractions.
114*/
115typedef struct _MSLGroupInfo
116{
cristybb503372010-05-27 20:51:26 +0000117 size_t
cristy3ed852e2009-09-05 21:47:34 +0000118 numImages; /* how many images are in this group */
119} MSLGroupInfo;
120
121typedef struct _MSLInfo
122{
123 ExceptionInfo
124 *exception;
125
cristybb503372010-05-27 20:51:26 +0000126 ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000127 n,
128 number_groups;
129
130 ImageInfo
131 **image_info;
132
133 DrawInfo
134 **draw_info;
135
136 Image
137 **attributes,
138 **image;
139
140 char
141 *content;
142
143 MSLGroupInfo
144 *group_info;
145
146#if defined(MAGICKCORE_XML_DELEGATE)
147 xmlParserCtxtPtr
148 parser;
149
150 xmlDocPtr
151 document;
152#endif
153} MSLInfo;
154
155/*
156 Forward declarations.
157*/
158#if defined(MAGICKCORE_XML_DELEGATE)
159static MagickBooleanType
160 WriteMSLImage(const ImageInfo *,Image *);
cristyb988fe72009-09-16 01:01:10 +0000161
162static MagickBooleanType
cristyb20775d2009-09-16 01:51:41 +0000163 SetMSLAttributes(MSLInfo *,const char *,const char *);
cristy3ed852e2009-09-05 21:47:34 +0000164#endif
165
166#if defined(MAGICKCORE_XML_DELEGATE)
cristyb988fe72009-09-16 01:01:10 +0000167
cristy3ed852e2009-09-05 21:47:34 +0000168/*
169%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
170% %
171% %
172% %
173% R e a d M S L I m a g e %
174% %
175% %
176% %
177%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
178%
179% ReadMSLImage() reads a Magick Scripting Language file and returns it.
180% It allocates the memory necessary for the new Image structure and returns a
181% pointer to the new image.
182%
183% The format of the ReadMSLImage method is:
184%
185% Image *ReadMSLImage(const ImageInfo *image_info,ExceptionInfo *exception)
186%
187% A description of each parameter follows:
188%
189% o image_info: the image info.
190%
191% o exception: return any errors or warnings in this structure.
192%
cristy3ed852e2009-09-05 21:47:34 +0000193*/
194
195#if defined(__cplusplus) || defined(c_plusplus)
196extern "C" {
197#endif
198
cristy4fa36e42009-09-18 14:24:06 +0000199static inline Image *GetImageCache(const ImageInfo *image_info,const char *path,
200 ExceptionInfo *exception)
201{
202 char
203 key[MaxTextExtent];
204
205 ExceptionInfo
206 *sans_exception;
207
208 Image
209 *image;
210
211 ImageInfo
212 *read_info;
213
cristyb51dff52011-05-19 16:55:47 +0000214 (void) FormatLocaleString(key,MaxTextExtent,"cache:%s",path);
cristy4fa36e42009-09-18 14:24:06 +0000215 sans_exception=AcquireExceptionInfo();
216 image=(Image *) GetImageRegistry(ImageRegistryType,key,sans_exception);
217 sans_exception=DestroyExceptionInfo(sans_exception);
218 if (image != (Image *) NULL)
219 return(image);
220 read_info=CloneImageInfo(image_info);
221 (void) CopyMagickString(read_info->filename,path,MaxTextExtent);
222 image=ReadImage(read_info,exception);
223 read_info=DestroyImageInfo(read_info);
224 if (image != (Image *) NULL)
225 (void) SetImageRegistry(ImageRegistryType,key,image,exception);
226 return(image);
227}
228
229static int IsPathDirectory(const char *path)
230{
231 MagickBooleanType
232 status;
233
234 struct stat
235 attributes;
236
237 if ((path == (const char *) NULL) || (*path == '\0'))
238 return(MagickFalse);
239 status=GetPathAttributes(path,&attributes);
240 if (status == MagickFalse)
241 return(-1);
242 if (S_ISDIR(attributes.st_mode) == 0)
243 return(0);
244 return(1);
245}
246
cristy3ed852e2009-09-05 21:47:34 +0000247static int MSLIsStandalone(void *context)
248{
249 MSLInfo
250 *msl_info;
251
252 /*
253 Is this document tagged standalone?
254 */
255 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.MSLIsStandalone()");
256 msl_info=(MSLInfo *) context;
257 return(msl_info->document->standalone == 1);
258}
259
260static int MSLHasInternalSubset(void *context)
261{
262 MSLInfo
263 *msl_info;
264
265 /*
266 Does this document has an internal subset?
267 */
268 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
269 " SAX.MSLHasInternalSubset()");
270 msl_info=(MSLInfo *) context;
271 return(msl_info->document->intSubset != NULL);
272}
273
274static int MSLHasExternalSubset(void *context)
275{
276 MSLInfo
277 *msl_info;
278
279 /*
280 Does this document has an external subset?
281 */
282 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
283 " SAX.MSLHasExternalSubset()");
284 msl_info=(MSLInfo *) context;
285 return(msl_info->document->extSubset != NULL);
286}
287
288static void MSLInternalSubset(void *context,const xmlChar *name,
289 const xmlChar *external_id,const xmlChar *system_id)
290{
291 MSLInfo
292 *msl_info;
293
294 /*
295 Does this document has an internal subset?
296 */
297 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
298 " SAX.internalSubset(%s %s %s)",name,
cristyb988fe72009-09-16 01:01:10 +0000299 (external_id != (const xmlChar *) NULL ? (const char *) external_id : " "),
300 (system_id != (const xmlChar *) NULL ? (const char *) system_id : " "));
cristy3ed852e2009-09-05 21:47:34 +0000301 msl_info=(MSLInfo *) context;
302 (void) xmlCreateIntSubset(msl_info->document,name,external_id,system_id);
303}
304
305static xmlParserInputPtr MSLResolveEntity(void *context,
306 const xmlChar *public_id,const xmlChar *system_id)
307{
308 MSLInfo
309 *msl_info;
310
311 xmlParserInputPtr
312 stream;
313
314 /*
315 Special entity resolver, better left to the parser, it has more
316 context than the application layer. The default behaviour is to
317 not resolve the entities, in that case the ENTITY_REF nodes are
318 built in the structure (and the parameter values).
319 */
320 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
321 " SAX.resolveEntity(%s, %s)",
cristyb988fe72009-09-16 01:01:10 +0000322 (public_id != (const xmlChar *) NULL ? (const char *) public_id : "none"),
323 (system_id != (const xmlChar *) NULL ? (const char *) system_id : "none"));
cristy3ed852e2009-09-05 21:47:34 +0000324 msl_info=(MSLInfo *) context;
325 stream=xmlLoadExternalEntity((const char *) system_id,(const char *)
326 public_id,msl_info->parser);
327 return(stream);
328}
329
330static xmlEntityPtr MSLGetEntity(void *context,const xmlChar *name)
331{
332 MSLInfo
333 *msl_info;
334
335 /*
336 Get an entity by name.
337 */
338 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
cristyb988fe72009-09-16 01:01:10 +0000339 " SAX.MSLGetEntity(%s)",(const char *) name);
cristy3ed852e2009-09-05 21:47:34 +0000340 msl_info=(MSLInfo *) context;
341 return(xmlGetDocEntity(msl_info->document,name));
342}
343
344static xmlEntityPtr MSLGetParameterEntity(void *context,const xmlChar *name)
345{
346 MSLInfo
347 *msl_info;
348
349 /*
350 Get a parameter entity by name.
351 */
352 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
cristyb988fe72009-09-16 01:01:10 +0000353 " SAX.getParameterEntity(%s)",(const char *) name);
cristy3ed852e2009-09-05 21:47:34 +0000354 msl_info=(MSLInfo *) context;
355 return(xmlGetParameterEntity(msl_info->document,name));
356}
357
358static void MSLEntityDeclaration(void *context,const xmlChar *name,int type,
359 const xmlChar *public_id,const xmlChar *system_id,xmlChar *content)
360{
361 MSLInfo
362 *msl_info;
363
364 /*
365 An entity definition has been parsed.
366 */
367 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
368 " SAX.entityDecl(%s, %d, %s, %s, %s)",name,type,
cristyb988fe72009-09-16 01:01:10 +0000369 public_id != (const xmlChar *) NULL ? (const char *) public_id : "none",
370 system_id != (const xmlChar *) NULL ? (const char *) system_id : "none",
371 content);
cristy3ed852e2009-09-05 21:47:34 +0000372 msl_info=(MSLInfo *) context;
373 if (msl_info->parser->inSubset == 1)
374 (void) xmlAddDocEntity(msl_info->document,name,type,public_id,system_id,
375 content);
376 else
377 if (msl_info->parser->inSubset == 2)
378 (void) xmlAddDtdEntity(msl_info->document,name,type,public_id,system_id,
379 content);
380}
381
382static void MSLAttributeDeclaration(void *context,const xmlChar *element,
383 const xmlChar *name,int type,int value,const xmlChar *default_value,
384 xmlEnumerationPtr tree)
385{
386 MSLInfo
387 *msl_info;
388
389 xmlChar
390 *fullname,
391 *prefix;
392
393 xmlParserCtxtPtr
394 parser;
395
396 /*
397 An attribute definition has been parsed.
398 */
399 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
400 " SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",element,name,type,value,
401 default_value);
402 msl_info=(MSLInfo *) context;
403 fullname=(xmlChar *) NULL;
404 prefix=(xmlChar *) NULL;
405 parser=msl_info->parser;
406 fullname=(xmlChar *) xmlSplitQName(parser,name,&prefix);
407 if (parser->inSubset == 1)
408 (void) xmlAddAttributeDecl(&parser->vctxt,msl_info->document->intSubset,
409 element,fullname,prefix,(xmlAttributeType) type,
410 (xmlAttributeDefault) value,default_value,tree);
411 else
412 if (parser->inSubset == 2)
413 (void) xmlAddAttributeDecl(&parser->vctxt,msl_info->document->extSubset,
414 element,fullname,prefix,(xmlAttributeType) type,
415 (xmlAttributeDefault) value,default_value,tree);
416 if (prefix != (xmlChar *) NULL)
417 xmlFree(prefix);
418 if (fullname != (xmlChar *) NULL)
419 xmlFree(fullname);
420}
421
422static void MSLElementDeclaration(void *context,const xmlChar *name,int type,
423 xmlElementContentPtr content)
424{
425 MSLInfo
426 *msl_info;
427
428 xmlParserCtxtPtr
429 parser;
430
431 /*
432 An element definition has been parsed.
433 */
434 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
435 " SAX.elementDecl(%s, %d, ...)",name,type);
436 msl_info=(MSLInfo *) context;
437 parser=msl_info->parser;
438 if (parser->inSubset == 1)
439 (void) xmlAddElementDecl(&parser->vctxt,msl_info->document->intSubset,
440 name,(xmlElementTypeVal) type,content);
441 else
442 if (parser->inSubset == 2)
443 (void) xmlAddElementDecl(&parser->vctxt,msl_info->document->extSubset,
444 name,(xmlElementTypeVal) type,content);
445}
446
447static void MSLNotationDeclaration(void *context,const xmlChar *name,
448 const xmlChar *public_id,const xmlChar *system_id)
449{
450 MSLInfo
451 *msl_info;
452
453 xmlParserCtxtPtr
454 parser;
455
456 /*
457 What to do when a notation declaration has been parsed.
458 */
459 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
460 " SAX.notationDecl(%s, %s, %s)",name,
cristyb988fe72009-09-16 01:01:10 +0000461 public_id != (const xmlChar *) NULL ? (const char *) public_id : "none",
462 system_id != (const xmlChar *) NULL ? (const char *) system_id : "none");
cristy3ed852e2009-09-05 21:47:34 +0000463 msl_info=(MSLInfo *) context;
464 parser=msl_info->parser;
465 if (parser->inSubset == 1)
466 (void) xmlAddNotationDecl(&parser->vctxt,msl_info->document->intSubset,
467 name,public_id,system_id);
468 else
469 if (parser->inSubset == 2)
470 (void) xmlAddNotationDecl(&parser->vctxt,msl_info->document->intSubset,
471 name,public_id,system_id);
472}
473
474static void MSLUnparsedEntityDeclaration(void *context,const xmlChar *name,
475 const xmlChar *public_id,const xmlChar *system_id,const xmlChar *notation)
476{
477 MSLInfo
478 *msl_info;
479
480 /*
481 What to do when an unparsed entity declaration is parsed.
482 */
483 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
484 " SAX.unparsedEntityDecl(%s, %s, %s, %s)",name,
cristyb988fe72009-09-16 01:01:10 +0000485 public_id != (const xmlChar *) NULL ? (const char *) public_id : "none",
486 system_id != (const xmlChar *) NULL ? (const char *) system_id : "none",
487 notation);
cristy3ed852e2009-09-05 21:47:34 +0000488 msl_info=(MSLInfo *) context;
489 (void) xmlAddDocEntity(msl_info->document,name,
490 XML_EXTERNAL_GENERAL_UNPARSED_ENTITY,public_id,system_id,notation);
491
492}
493
494static void MSLSetDocumentLocator(void *context,xmlSAXLocatorPtr location)
495{
496 MSLInfo
497 *msl_info;
498
499 /*
500 Receive the document locator at startup, actually xmlDefaultSAXLocator.
501 */
502 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
503 " SAX.setDocumentLocator()\n");
504 (void) location;
505 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +0000506 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +0000507}
508
509static void MSLStartDocument(void *context)
510{
511 MSLInfo
512 *msl_info;
513
514 xmlParserCtxtPtr
515 parser;
516
517 /*
518 Called when the document start being processed.
519 */
520 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
521 " SAX.startDocument()");
522 msl_info=(MSLInfo *) context;
523 parser=msl_info->parser;
524 msl_info->document=xmlNewDoc(parser->version);
525 if (msl_info->document == (xmlDocPtr) NULL)
526 return;
527 if (parser->encoding == NULL)
528 msl_info->document->encoding=NULL;
529 else
530 msl_info->document->encoding=xmlStrdup(parser->encoding);
531 msl_info->document->standalone=parser->standalone;
532}
533
534static void MSLEndDocument(void *context)
535{
536 MSLInfo
537 *msl_info;
538
539 /*
540 Called when the document end has been detected.
541 */
542 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.endDocument()");
543 msl_info=(MSLInfo *) context;
544 if (msl_info->content != (char *) NULL)
545 msl_info->content=DestroyString(msl_info->content);
546}
547
548static void MSLPushImage(MSLInfo *msl_info,Image *image)
549{
cristybb503372010-05-27 20:51:26 +0000550 ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000551 n;
552
553 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
554 assert(msl_info != (MSLInfo *) NULL);
555 msl_info->n++;
556 n=msl_info->n;
557 msl_info->image_info=(ImageInfo **) ResizeQuantumMemory(msl_info->image_info,
558 (n+1),sizeof(*msl_info->image_info));
559 msl_info->draw_info=(DrawInfo **) ResizeQuantumMemory(msl_info->draw_info,
560 (n+1),sizeof(*msl_info->draw_info));
561 msl_info->attributes=(Image **) ResizeQuantumMemory(msl_info->attributes,
562 (n+1),sizeof(*msl_info->attributes));
563 msl_info->image=(Image **) ResizeQuantumMemory(msl_info->image,(n+1),
564 sizeof(*msl_info->image));
565 if ((msl_info->image_info == (ImageInfo **) NULL) ||
566 (msl_info->draw_info == (DrawInfo **) NULL) ||
567 (msl_info->attributes == (Image **) NULL) ||
568 (msl_info->image == (Image **) NULL))
569 ThrowMSLException(ResourceLimitFatalError,"MemoryAllocationFailed","msl");
570 msl_info->image_info[n]=CloneImageInfo(msl_info->image_info[n-1]);
571 msl_info->draw_info[n]=CloneDrawInfo(msl_info->image_info[n-1],
572 msl_info->draw_info[n-1]);
573 if (image == (Image *) NULL)
574 msl_info->attributes[n]=AcquireImage(msl_info->image_info[n]);
575 else
576 msl_info->attributes[n]=CloneImage(image,0,0,MagickTrue,&image->exception);
577 msl_info->image[n]=(Image *) image;
578 if ((msl_info->image_info[n] == (ImageInfo *) NULL) ||
579 (msl_info->attributes[n] == (Image *) NULL))
580 ThrowMSLException(ResourceLimitFatalError,"MemoryAllocationFailed","msl");
581 if (msl_info->number_groups != 0)
582 msl_info->group_info[msl_info->number_groups-1].numImages++;
583}
584
585static void MSLPopImage(MSLInfo *msl_info)
586{
587 if (msl_info->number_groups != 0)
588 return;
589 if (msl_info->image[msl_info->n] != (Image *) NULL)
590 msl_info->image[msl_info->n]=DestroyImage(msl_info->image[msl_info->n]);
591 msl_info->attributes[msl_info->n]=DestroyImage(
592 msl_info->attributes[msl_info->n]);
593 msl_info->image_info[msl_info->n]=DestroyImageInfo(
594 msl_info->image_info[msl_info->n]);
595 msl_info->n--;
596}
597
598static void MSLStartElement(void *context,const xmlChar *tag,
599 const xmlChar **attributes)
600{
601 AffineMatrix
602 affine,
603 current;
604
605 ChannelType
606 channel;
607
cristybd5a96c2011-08-21 00:04:26 +0000608 ChannelType
609 channel_mask;
610
cristy3ed852e2009-09-05 21:47:34 +0000611 char
612 key[MaxTextExtent],
613 *value;
614
615 const char
616 *attribute,
617 *keyword;
618
619 double
620 angle;
621
622 DrawInfo
623 *draw_info;
624
625 ExceptionInfo
626 exception;
627
628 GeometryInfo
629 geometry_info;
630
631 Image
632 *image;
633
634 int
635 flags;
636
cristybb503372010-05-27 20:51:26 +0000637 ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000638 option,
639 j,
640 n,
641 x,
642 y;
643
644 MSLInfo
645 *msl_info;
646
647 RectangleInfo
648 geometry;
649
cristybb503372010-05-27 20:51:26 +0000650 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000651 i;
652
cristybb503372010-05-27 20:51:26 +0000653 size_t
cristy3ed852e2009-09-05 21:47:34 +0000654 height,
655 width;
656
657 /*
658 Called when an opening tag has been processed.
659 */
660 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
661 " SAX.startElement(%s",tag);
662 GetExceptionInfo(&exception);
663 msl_info=(MSLInfo *) context;
664 n=msl_info->n;
665 keyword=(const char *) NULL;
666 value=(char *) NULL;
667 SetGeometryInfo(&geometry_info);
668 channel=DefaultChannels;
669 switch (*tag)
670 {
671 case 'A':
672 case 'a':
673 {
cristyb988fe72009-09-16 01:01:10 +0000674 if (LocaleCompare((const char *) tag,"add-noise") == 0)
cristy3ed852e2009-09-05 21:47:34 +0000675 {
676 Image
677 *noise_image;
678
679 NoiseType
680 noise;
681
682 /*
683 Add noise image.
684 */
685 if (msl_info->image[n] == (Image *) NULL)
686 {
cristyb988fe72009-09-16 01:01:10 +0000687 ThrowMSLException(OptionError,"NoImagesDefined",
688 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +0000689 break;
690 }
691 noise=UniformNoise;
692 if (attributes != (const xmlChar **) NULL)
693 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
694 {
695 keyword=(const char *) attributes[i++];
696 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +0000697 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +0000698 CloneString(&value,attribute);
699 switch (*keyword)
700 {
701 case 'C':
702 case 'c':
703 {
704 if (LocaleCompare(keyword,"channel") == 0)
705 {
706 option=ParseChannelOption(value);
707 if (option < 0)
708 ThrowMSLException(OptionError,"UnrecognizedChannelType",
709 value);
710 channel=(ChannelType) option;
711 break;
712 }
713 ThrowMSLException(OptionError,"UnrecognizedAttribute",
714 keyword);
715 break;
716 }
717 case 'N':
718 case 'n':
719 {
720 if (LocaleCompare(keyword,"noise") == 0)
721 {
cristy042ee782011-04-22 18:48:30 +0000722 option=ParseCommandOption(MagickNoiseOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +0000723 value);
724 if (option < 0)
725 ThrowMSLException(OptionError,"UnrecognizedNoiseType",
726 value);
727 noise=(NoiseType) option;
728 break;
729 }
730 ThrowMSLException(OptionError,"UnrecognizedAttribute",
731 keyword);
732 break;
733 }
734 default:
735 {
736 ThrowMSLException(OptionError,"UnrecognizedAttribute",
737 keyword);
738 break;
739 }
740 }
741 }
cristybd5a96c2011-08-21 00:04:26 +0000742 channel_mask=SetPixelChannelMask(msl_info->image[n],channel);
cristy490408a2011-07-07 14:42:05 +0000743 noise_image=AddNoiseImage(msl_info->image[n],noise,
cristy3ed852e2009-09-05 21:47:34 +0000744 &msl_info->image[n]->exception);
cristybd5a96c2011-08-21 00:04:26 +0000745 (void) SetPixelChannelMap(msl_info->image[n],channel_mask);
cristy3ed852e2009-09-05 21:47:34 +0000746 if (noise_image == (Image *) NULL)
747 break;
748 msl_info->image[n]=DestroyImage(msl_info->image[n]);
749 msl_info->image[n]=noise_image;
750 break;
751 }
cristyb988fe72009-09-16 01:01:10 +0000752 if (LocaleCompare((const char *) tag,"annotate") == 0)
cristy3ed852e2009-09-05 21:47:34 +0000753 {
754 char
755 text[MaxTextExtent];
756
757 /*
758 Annotate image.
759 */
760 if (msl_info->image[n] == (Image *) NULL)
761 {
cristyb988fe72009-09-16 01:01:10 +0000762 ThrowMSLException(OptionError,"NoImagesDefined",
763 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +0000764 break;
765 }
766 draw_info=CloneDrawInfo(msl_info->image_info[n],
767 msl_info->draw_info[n]);
768 angle=0.0;
769 current=draw_info->affine;
770 GetAffineMatrix(&affine);
771 if (attributes != (const xmlChar **) NULL)
772 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
773 {
774 keyword=(const char *) attributes[i++];
775 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +0000776 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +0000777 CloneString(&value,attribute);
778 switch (*keyword)
779 {
780 case 'A':
781 case 'a':
782 {
783 if (LocaleCompare(keyword,"affine") == 0)
784 {
785 char
786 *p;
787
788 p=value;
cristyc1acd842011-05-19 23:05:47 +0000789 draw_info->affine.sx=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +0000790 if (*p ==',')
791 p++;
cristyc1acd842011-05-19 23:05:47 +0000792 draw_info->affine.rx=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +0000793 if (*p ==',')
794 p++;
cristyc1acd842011-05-19 23:05:47 +0000795 draw_info->affine.ry=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +0000796 if (*p ==',')
797 p++;
cristyc1acd842011-05-19 23:05:47 +0000798 draw_info->affine.sy=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +0000799 if (*p ==',')
800 p++;
cristyc1acd842011-05-19 23:05:47 +0000801 draw_info->affine.tx=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +0000802 if (*p ==',')
803 p++;
cristyc1acd842011-05-19 23:05:47 +0000804 draw_info->affine.ty=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +0000805 break;
806 }
807 if (LocaleCompare(keyword,"align") == 0)
808 {
cristy042ee782011-04-22 18:48:30 +0000809 option=ParseCommandOption(MagickAlignOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +0000810 value);
811 if (option < 0)
812 ThrowMSLException(OptionError,"UnrecognizedAlignType",
813 value);
814 draw_info->align=(AlignType) option;
815 break;
816 }
817 if (LocaleCompare(keyword,"antialias") == 0)
818 {
cristy042ee782011-04-22 18:48:30 +0000819 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +0000820 value);
821 if (option < 0)
822 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
823 value);
824 draw_info->stroke_antialias=(MagickBooleanType) option;
825 draw_info->text_antialias=(MagickBooleanType) option;
826 break;
827 }
828 ThrowMSLException(OptionError,"UnrecognizedAttribute",
829 keyword);
830 break;
831 }
832 case 'D':
833 case 'd':
834 {
835 if (LocaleCompare(keyword,"density") == 0)
836 {
837 CloneString(&draw_info->density,value);
838 break;
839 }
840 ThrowMSLException(OptionError,"UnrecognizedAttribute",
841 keyword);
842 break;
843 }
844 case 'E':
845 case 'e':
846 {
847 if (LocaleCompare(keyword,"encoding") == 0)
848 {
849 CloneString(&draw_info->encoding,value);
850 break;
851 }
852 ThrowMSLException(OptionError,"UnrecognizedAttribute",
853 keyword);
854 break;
855 }
856 case 'F':
857 case 'f':
858 {
859 if (LocaleCompare(keyword, "fill") == 0)
860 {
861 (void) QueryColorDatabase(value,&draw_info->fill,
862 &exception);
863 break;
864 }
865 if (LocaleCompare(keyword,"family") == 0)
866 {
867 CloneString(&draw_info->family,value);
868 break;
869 }
870 if (LocaleCompare(keyword,"font") == 0)
871 {
872 CloneString(&draw_info->font,value);
873 break;
874 }
875 ThrowMSLException(OptionError,"UnrecognizedAttribute",
876 keyword);
877 break;
878 }
879 case 'G':
880 case 'g':
881 {
882 if (LocaleCompare(keyword,"geometry") == 0)
883 {
cristy860f4e12011-07-28 19:00:28 +0000884 flags=ParseGravityGeometry(msl_info->image[n],value,
cristy3ed852e2009-09-05 21:47:34 +0000885 &geometry,&exception);
cristy3ed852e2009-09-05 21:47:34 +0000886 break;
887 }
888 if (LocaleCompare(keyword,"gravity") == 0)
889 {
cristy860f4e12011-07-28 19:00:28 +0000890 option=ParseCommandOption(MagickGravityOptions,
891 MagickFalse,value);
cristy3ed852e2009-09-05 21:47:34 +0000892 if (option < 0)
893 ThrowMSLException(OptionError,"UnrecognizedGravityType",
894 value);
895 draw_info->gravity=(GravityType) option;
896 break;
897 }
898 ThrowMSLException(OptionError,"UnrecognizedAttribute",
899 keyword);
900 break;
901 }
902 case 'P':
903 case 'p':
904 {
905 if (LocaleCompare(keyword,"pointsize") == 0)
906 {
cristyc1acd842011-05-19 23:05:47 +0000907 draw_info->pointsize=InterpretLocaleValue(value,
908 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000909 break;
910 }
911 ThrowMSLException(OptionError,"UnrecognizedAttribute",
912 keyword);
913 break;
914 }
915 case 'R':
916 case 'r':
917 {
918 if (LocaleCompare(keyword,"rotate") == 0)
919 {
cristyc1acd842011-05-19 23:05:47 +0000920 angle=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000921 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
922 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
923 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
924 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
925 break;
926 }
927 ThrowMSLException(OptionError,"UnrecognizedAttribute",
928 keyword);
929 break;
930 }
931 case 'S':
932 case 's':
933 {
934 if (LocaleCompare(keyword,"scale") == 0)
935 {
936 flags=ParseGeometry(value,&geometry_info);
937 if ((flags & SigmaValue) == 0)
938 geometry_info.sigma=1.0;
939 affine.sx=geometry_info.rho;
940 affine.sy=geometry_info.sigma;
941 break;
942 }
943 if (LocaleCompare(keyword,"skewX") == 0)
944 {
cristyc1acd842011-05-19 23:05:47 +0000945 angle=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000946 affine.ry=tan(DegreesToRadians(fmod((double) angle,
947 360.0)));
948 break;
949 }
950 if (LocaleCompare(keyword,"skewY") == 0)
951 {
cristyc1acd842011-05-19 23:05:47 +0000952 angle=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000953 affine.rx=tan(DegreesToRadians(fmod((double) angle,
954 360.0)));
955 break;
956 }
957 if (LocaleCompare(keyword,"stretch") == 0)
958 {
cristy042ee782011-04-22 18:48:30 +0000959 option=ParseCommandOption(MagickStretchOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +0000960 value);
961 if (option < 0)
962 ThrowMSLException(OptionError,"UnrecognizedStretchType",
963 value);
964 draw_info->stretch=(StretchType) option;
965 break;
966 }
967 if (LocaleCompare(keyword, "stroke") == 0)
968 {
969 (void) QueryColorDatabase(value,&draw_info->stroke,
970 &exception);
971 break;
972 }
973 if (LocaleCompare(keyword,"strokewidth") == 0)
974 {
cristyf2f27272009-12-17 14:48:46 +0000975 draw_info->stroke_width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +0000976 break;
977 }
978 if (LocaleCompare(keyword,"style") == 0)
979 {
cristy042ee782011-04-22 18:48:30 +0000980 option=ParseCommandOption(MagickStyleOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +0000981 value);
982 if (option < 0)
983 ThrowMSLException(OptionError,"UnrecognizedStyleType",
984 value);
985 draw_info->style=(StyleType) option;
986 break;
987 }
988 ThrowMSLException(OptionError,"UnrecognizedAttribute",
989 keyword);
990 break;
991 }
992 case 'T':
993 case 't':
994 {
995 if (LocaleCompare(keyword,"text") == 0)
996 {
997 CloneString(&draw_info->text,value);
998 break;
999 }
1000 if (LocaleCompare(keyword,"translate") == 0)
1001 {
1002 flags=ParseGeometry(value,&geometry_info);
1003 if ((flags & SigmaValue) == 0)
1004 geometry_info.sigma=1.0;
1005 affine.tx=geometry_info.rho;
1006 affine.ty=geometry_info.sigma;
1007 break;
1008 }
1009 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1010 keyword);
1011 break;
1012 }
1013 case 'U':
1014 case 'u':
1015 {
1016 if (LocaleCompare(keyword, "undercolor") == 0)
1017 {
1018 (void) QueryColorDatabase(value,&draw_info->undercolor,
1019 &exception);
1020 break;
1021 }
1022 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1023 keyword);
1024 break;
1025 }
1026 case 'W':
1027 case 'w':
1028 {
1029 if (LocaleCompare(keyword,"weight") == 0)
1030 {
cristyf2f27272009-12-17 14:48:46 +00001031 draw_info->weight=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001032 break;
1033 }
1034 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1035 keyword);
1036 break;
1037 }
1038 case 'X':
1039 case 'x':
1040 {
1041 if (LocaleCompare(keyword,"x") == 0)
1042 {
cristyf2f27272009-12-17 14:48:46 +00001043 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001044 break;
1045 }
1046 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1047 keyword);
1048 break;
1049 }
1050 case 'Y':
1051 case 'y':
1052 {
1053 if (LocaleCompare(keyword,"y") == 0)
1054 {
cristyf2f27272009-12-17 14:48:46 +00001055 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001056 break;
1057 }
1058 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1059 keyword);
1060 break;
1061 }
1062 default:
1063 {
1064 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1065 keyword);
1066 break;
1067 }
1068 }
1069 }
cristyb51dff52011-05-19 16:55:47 +00001070 (void) FormatLocaleString(text,MaxTextExtent,
cristye8c25f92010-06-03 00:53:06 +00001071 "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,(double)
1072 geometry.height,(double) geometry.x,(double) geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00001073 CloneString(&draw_info->geometry,text);
cristyef7c8a52010-10-10 13:46:51 +00001074 draw_info->affine.sx=affine.sx*current.sx+affine.ry*current.rx;
1075 draw_info->affine.rx=affine.rx*current.sx+affine.sy*current.rx;
1076 draw_info->affine.ry=affine.sx*current.ry+affine.ry*current.sy;
1077 draw_info->affine.sy=affine.rx*current.ry+affine.sy*current.sy;
1078 draw_info->affine.tx=affine.sx*current.tx+affine.ry*current.ty+
1079 affine.tx;
1080 draw_info->affine.ty=affine.rx*current.tx+affine.sy*current.ty+
1081 affine.ty;
cristy3ed852e2009-09-05 21:47:34 +00001082 (void) AnnotateImage(msl_info->image[n],draw_info);
1083 draw_info=DestroyDrawInfo(draw_info);
1084 break;
1085 }
cristyb988fe72009-09-16 01:01:10 +00001086 if (LocaleCompare((const char *) tag,"append") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001087 {
1088 Image
1089 *append_image;
1090
1091 MagickBooleanType
1092 stack;
cristyb988fe72009-09-16 01:01:10 +00001093
cristy3ed852e2009-09-05 21:47:34 +00001094 if (msl_info->image[n] == (Image *) NULL)
1095 {
cristyb988fe72009-09-16 01:01:10 +00001096 ThrowMSLException(OptionError,"NoImagesDefined",
1097 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001098 break;
1099 }
1100 stack=MagickFalse;
1101 if (attributes != (const xmlChar **) NULL)
1102 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1103 {
1104 keyword=(const char *) attributes[i++];
1105 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00001106 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00001107 CloneString(&value,attribute);
1108 switch (*keyword)
1109 {
1110 case 'S':
1111 case 's':
1112 {
1113 if (LocaleCompare(keyword,"stack") == 0)
1114 {
cristy042ee782011-04-22 18:48:30 +00001115 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00001116 value);
1117 if (option < 0)
1118 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
1119 value);
1120 stack=(MagickBooleanType) option;
1121 break;
1122 }
1123 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1124 keyword);
1125 break;
1126 }
1127 default:
1128 {
1129 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1130 keyword);
1131 break;
1132 }
1133 }
1134 }
1135 append_image=AppendImages(msl_info->image[n],stack,
1136 &msl_info->image[n]->exception);
1137 if (append_image == (Image *) NULL)
1138 break;
1139 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1140 msl_info->image[n]=append_image;
1141 break;
1142 }
1143 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
1144 break;
1145 }
1146 case 'B':
1147 case 'b':
1148 {
cristyb988fe72009-09-16 01:01:10 +00001149 if (LocaleCompare((const char *) tag,"blur") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001150 {
1151 Image
1152 *blur_image;
1153
1154 /*
1155 Blur image.
1156 */
1157 if (msl_info->image[n] == (Image *) NULL)
1158 {
cristyb988fe72009-09-16 01:01:10 +00001159 ThrowMSLException(OptionError,"NoImagesDefined",
1160 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001161 break;
1162 }
1163 if (attributes != (const xmlChar **) NULL)
1164 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1165 {
1166 keyword=(const char *) attributes[i++];
1167 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00001168 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00001169 CloneString(&value,attribute);
1170 switch (*keyword)
1171 {
1172 case 'C':
1173 case 'c':
1174 {
1175 if (LocaleCompare(keyword,"channel") == 0)
1176 {
1177 option=ParseChannelOption(value);
1178 if (option < 0)
1179 ThrowMSLException(OptionError,"UnrecognizedChannelType",
1180 value);
1181 channel=(ChannelType) option;
1182 break;
1183 }
1184 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1185 keyword);
1186 break;
1187 }
1188 case 'G':
1189 case 'g':
1190 {
1191 if (LocaleCompare(keyword,"geometry") == 0)
1192 {
1193 flags=ParseGeometry(value,&geometry_info);
1194 if ((flags & SigmaValue) == 0)
1195 geometry_info.sigma=1.0;
1196 break;
1197 }
1198 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1199 keyword);
1200 break;
1201 }
1202 case 'R':
1203 case 'r':
1204 {
1205 if (LocaleCompare(keyword,"radius") == 0)
1206 {
cristyc1acd842011-05-19 23:05:47 +00001207 geometry_info.rho=InterpretLocaleValue(value,
1208 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00001209 break;
1210 }
1211 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1212 keyword);
1213 break;
1214 }
1215 case 'S':
1216 case 's':
1217 {
1218 if (LocaleCompare(keyword,"sigma") == 0)
1219 {
cristyf2f27272009-12-17 14:48:46 +00001220 geometry_info.sigma=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001221 break;
1222 }
1223 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1224 keyword);
1225 break;
1226 }
1227 default:
1228 {
1229 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1230 keyword);
1231 break;
1232 }
1233 }
1234 }
cristybd5a96c2011-08-21 00:04:26 +00001235 channel_mask=SetPixelChannelMask(msl_info->image[n],channel);
cristyf4ad9df2011-07-08 16:49:03 +00001236 blur_image=BlurImage(msl_info->image[n],geometry_info.rho,
1237 geometry_info.sigma,&msl_info->image[n]->exception);
cristybd5a96c2011-08-21 00:04:26 +00001238 (void) SetPixelChannelMap(msl_info->image[n],channel_mask);
cristy3ed852e2009-09-05 21:47:34 +00001239 if (blur_image == (Image *) NULL)
1240 break;
1241 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1242 msl_info->image[n]=blur_image;
1243 break;
1244 }
cristyb988fe72009-09-16 01:01:10 +00001245 if (LocaleCompare((const char *) tag,"border") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001246 {
1247 Image
1248 *border_image;
1249
1250 /*
1251 Border image.
1252 */
1253 if (msl_info->image[n] == (Image *) NULL)
1254 {
cristyb988fe72009-09-16 01:01:10 +00001255 ThrowMSLException(OptionError,"NoImagesDefined",
1256 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001257 break;
1258 }
1259 SetGeometry(msl_info->image[n],&geometry);
1260 if (attributes != (const xmlChar **) NULL)
1261 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1262 {
1263 keyword=(const char *) attributes[i++];
1264 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00001265 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00001266 CloneString(&value,attribute);
1267 switch (*keyword)
1268 {
1269 case 'C':
1270 case 'c':
1271 {
1272 if (LocaleCompare(keyword,"compose") == 0)
1273 {
cristy042ee782011-04-22 18:48:30 +00001274 option=ParseCommandOption(MagickComposeOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00001275 value);
1276 if (option < 0)
1277 ThrowMSLException(OptionError,"UnrecognizedComposeType",
1278 value);
1279 msl_info->image[n]->compose=(CompositeOperator) option;
1280 break;
1281 }
1282 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1283 keyword);
1284 break;
1285 }
1286 case 'F':
1287 case 'f':
1288 {
1289 if (LocaleCompare(keyword, "fill") == 0)
1290 {
1291 (void) QueryColorDatabase(value,
1292 &msl_info->image[n]->border_color,&exception);
1293 break;
1294 }
1295 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1296 keyword);
1297 break;
1298 }
1299 case 'G':
1300 case 'g':
1301 {
1302 if (LocaleCompare(keyword,"geometry") == 0)
1303 {
1304 flags=ParsePageGeometry(msl_info->image[n],value,
1305 &geometry,&exception);
1306 if ((flags & HeightValue) == 0)
1307 geometry.height=geometry.width;
1308 break;
1309 }
1310 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1311 keyword);
1312 break;
1313 }
1314 case 'H':
1315 case 'h':
1316 {
1317 if (LocaleCompare(keyword,"height") == 0)
1318 {
cristyf2f27272009-12-17 14:48:46 +00001319 geometry.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001320 break;
1321 }
1322 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1323 keyword);
1324 break;
1325 }
1326 case 'W':
1327 case 'w':
1328 {
1329 if (LocaleCompare(keyword,"width") == 0)
1330 {
cristyf2f27272009-12-17 14:48:46 +00001331 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001332 break;
1333 }
1334 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1335 keyword);
1336 break;
1337 }
1338 default:
1339 {
1340 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1341 keyword);
1342 break;
1343 }
1344 }
1345 }
1346 border_image=BorderImage(msl_info->image[n],&geometry,
1347 &msl_info->image[n]->exception);
1348 if (border_image == (Image *) NULL)
1349 break;
1350 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1351 msl_info->image[n]=border_image;
1352 break;
1353 }
1354 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
1355 }
1356 case 'C':
1357 case 'c':
1358 {
cristyb988fe72009-09-16 01:01:10 +00001359 if (LocaleCompare((const char *) tag,"colorize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001360 {
1361 char
1362 opacity[MaxTextExtent];
1363
1364 Image
1365 *colorize_image;
1366
1367 PixelPacket
1368 target;
1369
1370 /*
1371 Add noise image.
1372 */
1373 if (msl_info->image[n] == (Image *) NULL)
1374 {
cristyb988fe72009-09-16 01:01:10 +00001375 ThrowMSLException(OptionError,"NoImagesDefined",
1376 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001377 break;
1378 }
1379 target=msl_info->image[n]->background_color;
1380 (void) CopyMagickString(opacity,"100",MaxTextExtent);
1381 if (attributes != (const xmlChar **) NULL)
1382 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1383 {
1384 keyword=(const char *) attributes[i++];
1385 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00001386 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00001387 CloneString(&value,attribute);
1388 switch (*keyword)
1389 {
1390 case 'F':
1391 case 'f':
1392 {
1393 if (LocaleCompare(keyword,"fill") == 0)
1394 {
1395 (void) QueryColorDatabase(value,&target,
1396 &msl_info->image[n]->exception);
1397 break;
1398 }
1399 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1400 keyword);
1401 break;
1402 }
1403 case 'O':
1404 case 'o':
1405 {
1406 if (LocaleCompare(keyword,"opacity") == 0)
1407 {
1408 (void) CopyMagickString(opacity,value,MaxTextExtent);
1409 break;
1410 }
1411 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1412 keyword);
1413 break;
1414 }
1415 default:
1416 {
1417 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1418 keyword);
1419 break;
1420 }
1421 }
1422 }
1423 colorize_image=ColorizeImage(msl_info->image[n],opacity,target,
1424 &msl_info->image[n]->exception);
1425 if (colorize_image == (Image *) NULL)
1426 break;
1427 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1428 msl_info->image[n]=colorize_image;
1429 break;
1430 }
cristyb988fe72009-09-16 01:01:10 +00001431 if (LocaleCompare((const char *) tag, "charcoal") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001432 {
1433 double radius = 0.0,
1434 sigma = 1.0;
1435
1436 if (msl_info->image[n] == (Image *) NULL)
1437 {
cristyb988fe72009-09-16 01:01:10 +00001438 ThrowMSLException(OptionError,"NoImagesDefined",
1439 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001440 break;
1441 }
1442 /*
1443 NOTE: charcoal can have no attributes, since we use all the defaults!
1444 */
1445 if (attributes != (const xmlChar **) NULL)
1446 {
1447 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1448 {
1449 keyword=(const char *) attributes[i++];
1450 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00001451 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00001452 switch (*keyword)
1453 {
1454 case 'R':
1455 case 'r':
1456 {
1457 if (LocaleCompare(keyword, "radius") == 0)
1458 {
cristyc1acd842011-05-19 23:05:47 +00001459 radius = InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00001460 break;
1461 }
1462 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
1463 break;
1464 }
1465 case 'S':
1466 case 's':
1467 {
1468 if (LocaleCompare(keyword,"sigma") == 0)
1469 {
cristyf2f27272009-12-17 14:48:46 +00001470 sigma = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00001471 break;
1472 }
1473 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
1474 break;
1475 }
1476 default:
1477 {
1478 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
1479 break;
1480 }
1481 }
1482 }
1483 }
1484
1485 /*
1486 charcoal image.
1487 */
1488 {
1489 Image
1490 *newImage;
1491
1492 newImage=CharcoalImage(msl_info->image[n],radius,sigma,
1493 &msl_info->image[n]->exception);
1494 if (newImage == (Image *) NULL)
1495 break;
1496 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1497 msl_info->image[n]=newImage;
1498 break;
1499 }
1500 }
cristyb988fe72009-09-16 01:01:10 +00001501 if (LocaleCompare((const char *) tag,"chop") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001502 {
1503 Image
1504 *chop_image;
1505
1506 /*
1507 Chop image.
1508 */
1509 if (msl_info->image[n] == (Image *) NULL)
1510 {
cristyb988fe72009-09-16 01:01:10 +00001511 ThrowMSLException(OptionError,"NoImagesDefined",
1512 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001513 break;
1514 }
1515 SetGeometry(msl_info->image[n],&geometry);
1516 if (attributes != (const xmlChar **) NULL)
1517 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1518 {
1519 keyword=(const char *) attributes[i++];
1520 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00001521 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00001522 CloneString(&value,attribute);
1523 switch (*keyword)
1524 {
1525 case 'G':
1526 case 'g':
1527 {
1528 if (LocaleCompare(keyword,"geometry") == 0)
1529 {
1530 flags=ParsePageGeometry(msl_info->image[n],value,
1531 &geometry,&exception);
1532 if ((flags & HeightValue) == 0)
1533 geometry.height=geometry.width;
1534 break;
1535 }
1536 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1537 keyword);
1538 break;
1539 }
1540 case 'H':
1541 case 'h':
1542 {
1543 if (LocaleCompare(keyword,"height") == 0)
1544 {
cristyf2f27272009-12-17 14:48:46 +00001545 geometry.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001546 break;
1547 }
1548 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1549 keyword);
1550 break;
1551 }
1552 case 'W':
1553 case 'w':
1554 {
1555 if (LocaleCompare(keyword,"width") == 0)
1556 {
cristyf2f27272009-12-17 14:48:46 +00001557 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001558 break;
1559 }
1560 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1561 keyword);
1562 break;
1563 }
1564 case 'X':
1565 case 'x':
1566 {
1567 if (LocaleCompare(keyword,"x") == 0)
1568 {
cristyf2f27272009-12-17 14:48:46 +00001569 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001570 break;
1571 }
1572 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1573 keyword);
1574 break;
1575 }
1576 case 'Y':
1577 case 'y':
1578 {
1579 if (LocaleCompare(keyword,"y") == 0)
1580 {
cristyf2f27272009-12-17 14:48:46 +00001581 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001582 break;
1583 }
1584 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1585 keyword);
1586 break;
1587 }
1588 default:
1589 {
1590 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1591 keyword);
1592 break;
1593 }
1594 }
1595 }
1596 chop_image=ChopImage(msl_info->image[n],&geometry,
1597 &msl_info->image[n]->exception);
1598 if (chop_image == (Image *) NULL)
1599 break;
1600 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1601 msl_info->image[n]=chop_image;
1602 break;
1603 }
cristyb988fe72009-09-16 01:01:10 +00001604 if (LocaleCompare((const char *) tag,"color-floodfill") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001605 {
1606 PaintMethod
1607 paint_method;
1608
cristy4c08aed2011-07-01 19:47:50 +00001609 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00001610 target;
1611
1612 /*
1613 Color floodfill image.
1614 */
1615 if (msl_info->image[n] == (Image *) NULL)
1616 {
cristyb988fe72009-09-16 01:01:10 +00001617 ThrowMSLException(OptionError,"NoImagesDefined",
1618 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001619 break;
1620 }
1621 draw_info=CloneDrawInfo(msl_info->image_info[n],
1622 msl_info->draw_info[n]);
1623 SetGeometry(msl_info->image[n],&geometry);
1624 paint_method=FloodfillMethod;
1625 if (attributes != (const xmlChar **) NULL)
1626 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1627 {
1628 keyword=(const char *) attributes[i++];
1629 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00001630 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00001631 CloneString(&value,attribute);
1632 switch (*keyword)
1633 {
1634 case 'B':
1635 case 'b':
1636 {
1637 if (LocaleCompare(keyword,"bordercolor") == 0)
1638 {
1639 (void) QueryMagickColor(value,&target,&exception);
1640 paint_method=FillToBorderMethod;
1641 break;
1642 }
1643 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1644 keyword);
1645 break;
1646 }
1647 case 'F':
1648 case 'f':
1649 {
1650 if (LocaleCompare(keyword,"fill") == 0)
1651 {
1652 (void) QueryColorDatabase(value,&draw_info->fill,
1653 &exception);
1654 break;
1655 }
1656 if (LocaleCompare(keyword,"fuzz") == 0)
1657 {
cristyc1acd842011-05-19 23:05:47 +00001658 msl_info->image[n]->fuzz=InterpretLocaleValue(value,
1659 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00001660 break;
1661 }
1662 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1663 keyword);
1664 break;
1665 }
1666 case 'G':
1667 case 'g':
1668 {
1669 if (LocaleCompare(keyword,"geometry") == 0)
1670 {
1671 flags=ParsePageGeometry(msl_info->image[n],value,
1672 &geometry,&exception);
1673 if ((flags & HeightValue) == 0)
1674 geometry.height=geometry.width;
1675 (void) GetOneVirtualMagickPixel(msl_info->image[n],
1676 geometry.x,geometry.y,&target,&exception);
1677 break;
1678 }
1679 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1680 keyword);
1681 break;
1682 }
1683 case 'X':
1684 case 'x':
1685 {
1686 if (LocaleCompare(keyword,"x") == 0)
1687 {
cristyf2f27272009-12-17 14:48:46 +00001688 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001689 (void) GetOneVirtualMagickPixel(msl_info->image[n],
1690 geometry.x,geometry.y,&target,&exception);
1691 break;
1692 }
1693 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1694 keyword);
1695 break;
1696 }
1697 case 'Y':
1698 case 'y':
1699 {
1700 if (LocaleCompare(keyword,"y") == 0)
1701 {
cristyf2f27272009-12-17 14:48:46 +00001702 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001703 (void) GetOneVirtualMagickPixel(msl_info->image[n],
1704 geometry.x,geometry.y,&target,&exception);
1705 break;
1706 }
1707 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1708 keyword);
1709 break;
1710 }
1711 default:
1712 {
1713 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1714 keyword);
1715 break;
1716 }
1717 }
1718 }
cristyd42d9952011-07-08 14:21:50 +00001719 (void) FloodfillPaintImage(msl_info->image[n],draw_info,&target,
1720 geometry.x,geometry.y,paint_method == FloodfillMethod ?
cristy189e84c2011-08-27 18:08:53 +00001721 MagickFalse : MagickTrue,&msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00001722 draw_info=DestroyDrawInfo(draw_info);
1723 break;
1724 }
cristyb988fe72009-09-16 01:01:10 +00001725 if (LocaleCompare((const char *) tag,"comment") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001726 break;
cristyb988fe72009-09-16 01:01:10 +00001727 if (LocaleCompare((const char *) tag,"composite") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001728 {
1729 char
1730 composite_geometry[MaxTextExtent];
1731
1732 CompositeOperator
1733 compose;
1734
1735 Image
1736 *composite_image,
1737 *rotate_image;
1738
1739 PixelPacket
1740 target;
1741
1742 /*
1743 Composite image.
1744 */
1745 if (msl_info->image[n] == (Image *) NULL)
1746 {
cristyb988fe72009-09-16 01:01:10 +00001747 ThrowMSLException(OptionError,"NoImagesDefined",
1748 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001749 break;
1750 }
1751 composite_image=NewImageList();
1752 compose=OverCompositeOp;
1753 if (attributes != (const xmlChar **) NULL)
1754 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1755 {
1756 keyword=(const char *) attributes[i++];
1757 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00001758 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00001759 CloneString(&value,attribute);
1760 switch (*keyword)
1761 {
1762 case 'C':
1763 case 'c':
1764 {
1765 if (LocaleCompare(keyword,"compose") == 0)
1766 {
cristy042ee782011-04-22 18:48:30 +00001767 option=ParseCommandOption(MagickComposeOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00001768 value);
1769 if (option < 0)
1770 ThrowMSLException(OptionError,"UnrecognizedComposeType",
1771 value);
1772 compose=(CompositeOperator) option;
1773 break;
1774 }
1775 break;
1776 }
1777 case 'I':
1778 case 'i':
1779 {
1780 if (LocaleCompare(keyword,"image") == 0)
1781 for (j=0; j < msl_info->n; j++)
1782 {
1783 const char
1784 *attribute;
cristyb988fe72009-09-16 01:01:10 +00001785
cristy3ed852e2009-09-05 21:47:34 +00001786 attribute=GetImageProperty(msl_info->attributes[j],"id");
1787 if ((attribute != (const char *) NULL) &&
1788 (LocaleCompare(attribute,value) == 0))
1789 {
1790 composite_image=CloneImage(msl_info->image[j],0,0,
1791 MagickFalse,&exception);
1792 break;
1793 }
1794 }
1795 break;
1796 }
1797 default:
1798 break;
1799 }
1800 }
1801 if (composite_image == (Image *) NULL)
1802 break;
1803 rotate_image=NewImageList();
1804 SetGeometry(msl_info->image[n],&geometry);
1805 if (attributes != (const xmlChar **) NULL)
1806 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1807 {
1808 keyword=(const char *) attributes[i++];
1809 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00001810 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00001811 CloneString(&value,attribute);
1812 switch (*keyword)
1813 {
1814 case 'B':
1815 case 'b':
1816 {
1817 if (LocaleCompare(keyword,"blend") == 0)
1818 {
1819 (void) SetImageArtifact(composite_image,
1820 "compose:args",value);
1821 break;
1822 }
1823 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1824 keyword);
1825 break;
1826 }
1827 case 'C':
1828 case 'c':
1829 {
1830 if (LocaleCompare(keyword,"channel") == 0)
1831 {
1832 option=ParseChannelOption(value);
1833 if (option < 0)
1834 ThrowMSLException(OptionError,"UnrecognizedChannelType",
1835 value);
1836 channel=(ChannelType) option;
1837 break;
1838 }
1839 if (LocaleCompare(keyword, "color") == 0)
1840 {
1841 (void) QueryColorDatabase(value,
1842 &composite_image->background_color,&exception);
1843 break;
1844 }
1845 if (LocaleCompare(keyword,"compose") == 0)
1846 break;
1847 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1848 keyword);
1849 break;
1850 }
1851 case 'G':
1852 case 'g':
1853 {
1854 if (LocaleCompare(keyword,"geometry") == 0)
1855 {
1856 flags=ParsePageGeometry(msl_info->image[n],value,
1857 &geometry,&exception);
1858 if ((flags & HeightValue) == 0)
1859 geometry.height=geometry.width;
1860 (void) GetOneVirtualPixel(msl_info->image[n],geometry.x,
1861 geometry.y,&target,&exception);
1862 break;
1863 }
1864 if (LocaleCompare(keyword,"gravity") == 0)
1865 {
cristy042ee782011-04-22 18:48:30 +00001866 option=ParseCommandOption(MagickGravityOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00001867 value);
1868 if (option < 0)
1869 ThrowMSLException(OptionError,"UnrecognizedGravityType",
1870 value);
1871 msl_info->image[n]->gravity=(GravityType) option;
1872 break;
1873 }
1874 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1875 keyword);
1876 break;
1877 }
1878 case 'I':
1879 case 'i':
1880 {
1881 if (LocaleCompare(keyword,"image") == 0)
1882 break;
1883 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1884 keyword);
1885 break;
1886 }
1887 case 'M':
1888 case 'm':
1889 {
1890 if (LocaleCompare(keyword,"mask") == 0)
1891 for (j=0; j < msl_info->n; j++)
1892 {
1893 const char
1894 *attribute;
1895
1896 attribute=GetImageProperty(msl_info->attributes[j],"id");
1897 if ((attribute != (const char *) NULL) &&
1898 (LocaleCompare(value,value) == 0))
1899 {
1900 SetImageType(composite_image,TrueColorMatteType);
1901 (void) CompositeImage(composite_image,
1902 CopyOpacityCompositeOp,msl_info->image[j],0,0);
1903 break;
1904 }
1905 }
1906 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1907 keyword);
1908 break;
1909 }
1910 case 'O':
1911 case 'o':
1912 {
1913 if (LocaleCompare(keyword,"opacity") == 0)
1914 {
cristybb503372010-05-27 20:51:26 +00001915 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001916 opacity,
1917 y;
cristyb988fe72009-09-16 01:01:10 +00001918
cristybb503372010-05-27 20:51:26 +00001919 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001920 x;
cristyb988fe72009-09-16 01:01:10 +00001921
cristy4c08aed2011-07-01 19:47:50 +00001922 register Quantum
cristy3ed852e2009-09-05 21:47:34 +00001923 *q;
cristyb988fe72009-09-16 01:01:10 +00001924
cristy3ed852e2009-09-05 21:47:34 +00001925 CacheView
1926 *composite_view;
1927
cristy4c08aed2011-07-01 19:47:50 +00001928 opacity=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001929 if (compose != DissolveCompositeOp)
1930 {
cristyb988fe72009-09-16 01:01:10 +00001931 (void) SetImageOpacity(composite_image,(Quantum)
1932 opacity);
cristy3ed852e2009-09-05 21:47:34 +00001933 break;
1934 }
1935 (void) SetImageArtifact(msl_info->image[n],
1936 "compose:args",value);
1937 if (composite_image->matte != MagickTrue)
cristy4c08aed2011-07-01 19:47:50 +00001938 (void) SetImageOpacity(composite_image,OpaqueAlpha);
cristy3ed852e2009-09-05 21:47:34 +00001939 composite_view=AcquireCacheView(composite_image);
cristybb503372010-05-27 20:51:26 +00001940 for (y=0; y < (ssize_t) composite_image->rows ; y++)
cristyb988fe72009-09-16 01:01:10 +00001941 {
cristy4c08aed2011-07-01 19:47:50 +00001942 q=GetCacheViewAuthenticPixels(composite_view,0,y,
1943 (ssize_t) composite_image->columns,1,&exception);
cristybb503372010-05-27 20:51:26 +00001944 for (x=0; x < (ssize_t) composite_image->columns; x++)
cristyb988fe72009-09-16 01:01:10 +00001945 {
cristy4c08aed2011-07-01 19:47:50 +00001946 if (GetPixelAlpha(composite_image,q) == OpaqueAlpha)
1947 SetPixelAlpha(composite_image,
1948 ClampToQuantum(opacity),q);
cristyed231572011-07-14 02:18:59 +00001949 q+=GetPixelChannels(composite_image);
cristy3ed852e2009-09-05 21:47:34 +00001950 }
1951 if (SyncCacheViewAuthenticPixels(composite_view,&exception) == MagickFalse)
1952 break;
1953 }
1954 composite_view=DestroyCacheView(composite_view);
1955 break;
1956 }
1957 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1958 keyword);
1959 break;
1960 }
1961 case 'R':
1962 case 'r':
1963 {
1964 if (LocaleCompare(keyword,"rotate") == 0)
1965 {
cristyc1acd842011-05-19 23:05:47 +00001966 rotate_image=RotateImage(composite_image,
1967 InterpretLocaleValue(value,(char **) NULL),&exception);
cristy3ed852e2009-09-05 21:47:34 +00001968 break;
1969 }
1970 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1971 keyword);
1972 break;
1973 }
1974 case 'T':
1975 case 't':
1976 {
1977 if (LocaleCompare(keyword,"tile") == 0)
1978 {
1979 MagickBooleanType
1980 tile;
1981
cristy042ee782011-04-22 18:48:30 +00001982 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00001983 value);
1984 if (option < 0)
1985 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
1986 value);
1987 tile=(MagickBooleanType) option;
cristyda16f162011-02-19 23:52:17 +00001988 (void) tile;
cristy3ed852e2009-09-05 21:47:34 +00001989 if (rotate_image != (Image *) NULL)
1990 (void) SetImageArtifact(rotate_image,
1991 "compose:outside-overlay","false");
1992 else
1993 (void) SetImageArtifact(composite_image,
1994 "compose:outside-overlay","false");
1995 image=msl_info->image[n];
1996 height=composite_image->rows;
1997 width=composite_image->columns;
cristyeaedf062010-05-29 22:36:02 +00001998 for (y=0; y < (ssize_t) image->rows; y+=(ssize_t) height)
1999 for (x=0; x < (ssize_t) image->columns; x+=(ssize_t) width)
cristy3ed852e2009-09-05 21:47:34 +00002000 {
2001 if (rotate_image != (Image *) NULL)
2002 (void) CompositeImage(image,compose,rotate_image,
2003 x,y);
2004 else
2005 (void) CompositeImage(image,compose,
2006 composite_image,x,y);
2007 }
2008 if (rotate_image != (Image *) NULL)
2009 rotate_image=DestroyImage(rotate_image);
2010 break;
2011 }
2012 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2013 keyword);
2014 break;
2015 }
2016 case 'X':
2017 case 'x':
2018 {
2019 if (LocaleCompare(keyword,"x") == 0)
2020 {
cristyf2f27272009-12-17 14:48:46 +00002021 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002022 (void) GetOneVirtualPixel(msl_info->image[n],geometry.x,
2023 geometry.y,&target,&exception);
2024 break;
2025 }
2026 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2027 keyword);
2028 break;
2029 }
2030 case 'Y':
2031 case 'y':
2032 {
2033 if (LocaleCompare(keyword,"y") == 0)
2034 {
cristyf2f27272009-12-17 14:48:46 +00002035 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002036 (void) GetOneVirtualPixel(msl_info->image[n],geometry.x,
2037 geometry.y,&target,&exception);
2038 break;
2039 }
2040 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2041 keyword);
2042 break;
2043 }
2044 default:
2045 {
2046 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2047 keyword);
2048 break;
2049 }
2050 }
2051 }
2052 image=msl_info->image[n];
cristyb51dff52011-05-19 16:55:47 +00002053 (void) FormatLocaleString(composite_geometry,MaxTextExtent,
cristye8c25f92010-06-03 00:53:06 +00002054 "%.20gx%.20g%+.20g%+.20g",(double) composite_image->columns,
2055 (double) composite_image->rows,(double) geometry.x,(double)
cristyf2faecf2010-05-28 19:19:36 +00002056 geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00002057 flags=ParseGravityGeometry(image,composite_geometry,&geometry,
2058 &exception);
cristybd5a96c2011-08-21 00:04:26 +00002059 channel_mask=SetPixelChannelMask(image,channel);
cristy3ed852e2009-09-05 21:47:34 +00002060 if (rotate_image == (Image *) NULL)
cristyf4ad9df2011-07-08 16:49:03 +00002061 CompositeImage(image,compose,composite_image,geometry.x,geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00002062 else
2063 {
2064 /*
2065 Rotate image.
2066 */
cristybb503372010-05-27 20:51:26 +00002067 geometry.x-=(ssize_t) (rotate_image->columns-
cristy3ed852e2009-09-05 21:47:34 +00002068 composite_image->columns)/2;
cristybb503372010-05-27 20:51:26 +00002069 geometry.y-=(ssize_t) (rotate_image->rows-composite_image->rows)/2;
cristyf4ad9df2011-07-08 16:49:03 +00002070 CompositeImage(image,compose,rotate_image,geometry.x,geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00002071 rotate_image=DestroyImage(rotate_image);
2072 }
cristybd5a96c2011-08-21 00:04:26 +00002073 (void) SetPixelChannelMask(image,channel_mask);
cristy3ed852e2009-09-05 21:47:34 +00002074 composite_image=DestroyImage(composite_image);
2075 break;
2076 }
cristyb988fe72009-09-16 01:01:10 +00002077 if (LocaleCompare((const char *) tag,"contrast") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002078 {
2079 MagickBooleanType
2080 sharpen;
2081
2082 /*
2083 Contrast image.
2084 */
2085 if (msl_info->image[n] == (Image *) NULL)
2086 {
cristyb988fe72009-09-16 01:01:10 +00002087 ThrowMSLException(OptionError,"NoImagesDefined",
2088 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002089 break;
2090 }
2091 sharpen=MagickFalse;
2092 if (attributes != (const xmlChar **) NULL)
2093 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2094 {
2095 keyword=(const char *) attributes[i++];
2096 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002097 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002098 CloneString(&value,attribute);
2099 switch (*keyword)
2100 {
2101 case 'S':
2102 case 's':
2103 {
2104 if (LocaleCompare(keyword,"sharpen") == 0)
2105 {
cristy042ee782011-04-22 18:48:30 +00002106 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002107 value);
2108 if (option < 0)
2109 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
2110 value);
2111 sharpen=(MagickBooleanType) option;
2112 break;
2113 }
2114 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2115 keyword);
2116 break;
2117 }
2118 default:
2119 {
2120 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2121 keyword);
2122 break;
2123 }
2124 }
2125 }
cristye23ec9d2011-08-16 18:15:40 +00002126 (void) ContrastImage(msl_info->image[n],sharpen,
2127 &msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00002128 break;
2129 }
cristyb988fe72009-09-16 01:01:10 +00002130 if (LocaleCompare((const char *) tag,"crop") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002131 {
2132 Image
2133 *crop_image;
2134
2135 /*
2136 Crop image.
2137 */
2138 if (msl_info->image[n] == (Image *) NULL)
2139 {
cristyb988fe72009-09-16 01:01:10 +00002140 ThrowMSLException(OptionError,"NoImagesDefined",
2141 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002142 break;
2143 }
2144 SetGeometry(msl_info->image[n],&geometry);
2145 if (attributes != (const xmlChar **) NULL)
2146 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2147 {
2148 keyword=(const char *) attributes[i++];
2149 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002150 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002151 CloneString(&value,attribute);
2152 switch (*keyword)
2153 {
2154 case 'G':
2155 case 'g':
2156 {
2157 if (LocaleCompare(keyword,"geometry") == 0)
2158 {
cristy860f4e12011-07-28 19:00:28 +00002159 flags=ParseGravityGeometry(msl_info->image[n],value,
cristy3ed852e2009-09-05 21:47:34 +00002160 &geometry,&exception);
cristy3ed852e2009-09-05 21:47:34 +00002161 break;
2162 }
2163 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2164 keyword);
2165 break;
2166 }
2167 case 'H':
2168 case 'h':
2169 {
2170 if (LocaleCompare(keyword,"height") == 0)
2171 {
cristyf2f27272009-12-17 14:48:46 +00002172 geometry.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002173 break;
2174 }
2175 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2176 keyword);
2177 break;
2178 }
2179 case 'W':
2180 case 'w':
2181 {
2182 if (LocaleCompare(keyword,"width") == 0)
2183 {
cristyf2f27272009-12-17 14:48:46 +00002184 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002185 break;
2186 }
2187 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2188 keyword);
2189 break;
2190 }
2191 case 'X':
2192 case 'x':
2193 {
2194 if (LocaleCompare(keyword,"x") == 0)
2195 {
cristyf2f27272009-12-17 14:48:46 +00002196 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002197 break;
2198 }
2199 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2200 keyword);
2201 break;
2202 }
2203 case 'Y':
2204 case 'y':
2205 {
2206 if (LocaleCompare(keyword,"y") == 0)
2207 {
cristyf2f27272009-12-17 14:48:46 +00002208 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002209 break;
2210 }
2211 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2212 keyword);
2213 break;
2214 }
2215 default:
2216 {
2217 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2218 keyword);
2219 break;
2220 }
2221 }
2222 }
2223 crop_image=CropImage(msl_info->image[n],&geometry,
2224 &msl_info->image[n]->exception);
2225 if (crop_image == (Image *) NULL)
2226 break;
2227 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2228 msl_info->image[n]=crop_image;
2229 break;
2230 }
cristyb988fe72009-09-16 01:01:10 +00002231 if (LocaleCompare((const char *) tag,"cycle-colormap") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002232 {
cristybb503372010-05-27 20:51:26 +00002233 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002234 display;
2235
2236 /*
2237 Cycle-colormap image.
2238 */
2239 if (msl_info->image[n] == (Image *) NULL)
2240 {
cristyb988fe72009-09-16 01:01:10 +00002241 ThrowMSLException(OptionError,"NoImagesDefined",
2242 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002243 break;
2244 }
2245 display=0;
2246 if (attributes != (const xmlChar **) NULL)
2247 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2248 {
2249 keyword=(const char *) attributes[i++];
2250 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002251 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002252 CloneString(&value,attribute);
2253 switch (*keyword)
2254 {
2255 case 'D':
2256 case 'd':
2257 {
2258 if (LocaleCompare(keyword,"display") == 0)
2259 {
cristyf2f27272009-12-17 14:48:46 +00002260 display=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002261 break;
2262 }
2263 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2264 keyword);
2265 break;
2266 }
2267 default:
2268 {
2269 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2270 keyword);
2271 break;
2272 }
2273 }
2274 }
2275 (void) CycleColormapImage(msl_info->image[n],display);
2276 break;
2277 }
2278 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
2279 }
2280 case 'D':
2281 case 'd':
2282 {
cristyb988fe72009-09-16 01:01:10 +00002283 if (LocaleCompare((const char *) tag,"despeckle") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002284 {
2285 Image
2286 *despeckle_image;
2287
2288 /*
2289 Despeckle image.
2290 */
2291 if (msl_info->image[n] == (Image *) NULL)
2292 {
cristyb988fe72009-09-16 01:01:10 +00002293 ThrowMSLException(OptionError,"NoImagesDefined",
2294 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002295 break;
2296 }
2297 if (attributes != (const xmlChar **) NULL)
2298 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2299 {
2300 keyword=(const char *) attributes[i++];
2301 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002302 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002303 CloneString(&value,attribute);
2304 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
2305 }
2306 despeckle_image=DespeckleImage(msl_info->image[n],
2307 &msl_info->image[n]->exception);
2308 if (despeckle_image == (Image *) NULL)
2309 break;
2310 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2311 msl_info->image[n]=despeckle_image;
2312 break;
2313 }
cristyb988fe72009-09-16 01:01:10 +00002314 if (LocaleCompare((const char *) tag,"display") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002315 {
2316 if (msl_info->image[n] == (Image *) NULL)
2317 {
cristyb988fe72009-09-16 01:01:10 +00002318 ThrowMSLException(OptionError,"NoImagesDefined",
2319 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002320 break;
2321 }
2322 if (attributes != (const xmlChar **) NULL)
2323 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2324 {
2325 keyword=(const char *) attributes[i++];
2326 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002327 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002328 CloneString(&value,attribute);
2329 switch (*keyword)
2330 {
2331 default:
2332 {
2333 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2334 keyword);
2335 break;
2336 }
2337 }
2338 }
2339 (void) DisplayImages(msl_info->image_info[n],msl_info->image[n]);
2340 break;
2341 }
cristyb988fe72009-09-16 01:01:10 +00002342 if (LocaleCompare((const char *) tag,"draw") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002343 {
2344 char
2345 text[MaxTextExtent];
2346
2347 /*
2348 Annotate image.
2349 */
2350 if (msl_info->image[n] == (Image *) NULL)
2351 {
cristyb988fe72009-09-16 01:01:10 +00002352 ThrowMSLException(OptionError,"NoImagesDefined",
2353 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002354 break;
2355 }
2356 draw_info=CloneDrawInfo(msl_info->image_info[n],
2357 msl_info->draw_info[n]);
2358 angle=0.0;
2359 current=draw_info->affine;
2360 GetAffineMatrix(&affine);
2361 if (attributes != (const xmlChar **) NULL)
2362 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2363 {
2364 keyword=(const char *) attributes[i++];
2365 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002366 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002367 CloneString(&value,attribute);
2368 switch (*keyword)
2369 {
2370 case 'A':
2371 case 'a':
2372 {
2373 if (LocaleCompare(keyword,"affine") == 0)
2374 {
2375 char
2376 *p;
2377
2378 p=value;
cristyc1acd842011-05-19 23:05:47 +00002379 draw_info->affine.sx=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00002380 if (*p ==',')
2381 p++;
cristyc1acd842011-05-19 23:05:47 +00002382 draw_info->affine.rx=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00002383 if (*p ==',')
2384 p++;
cristyc1acd842011-05-19 23:05:47 +00002385 draw_info->affine.ry=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00002386 if (*p ==',')
2387 p++;
cristyc1acd842011-05-19 23:05:47 +00002388 draw_info->affine.sy=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00002389 if (*p ==',')
2390 p++;
cristyc1acd842011-05-19 23:05:47 +00002391 draw_info->affine.tx=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00002392 if (*p ==',')
2393 p++;
cristyc1acd842011-05-19 23:05:47 +00002394 draw_info->affine.ty=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00002395 break;
2396 }
2397 if (LocaleCompare(keyword,"align") == 0)
2398 {
cristy042ee782011-04-22 18:48:30 +00002399 option=ParseCommandOption(MagickAlignOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002400 value);
2401 if (option < 0)
2402 ThrowMSLException(OptionError,"UnrecognizedAlignType",
2403 value);
2404 draw_info->align=(AlignType) option;
2405 break;
2406 }
2407 if (LocaleCompare(keyword,"antialias") == 0)
2408 {
cristy042ee782011-04-22 18:48:30 +00002409 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002410 value);
2411 if (option < 0)
2412 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
2413 value);
2414 draw_info->stroke_antialias=(MagickBooleanType) option;
2415 draw_info->text_antialias=(MagickBooleanType) option;
2416 break;
2417 }
2418 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2419 keyword);
2420 break;
2421 }
2422 case 'D':
2423 case 'd':
2424 {
2425 if (LocaleCompare(keyword,"density") == 0)
2426 {
2427 CloneString(&draw_info->density,value);
2428 break;
2429 }
2430 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2431 keyword);
2432 break;
2433 }
2434 case 'E':
2435 case 'e':
2436 {
2437 if (LocaleCompare(keyword,"encoding") == 0)
2438 {
2439 CloneString(&draw_info->encoding,value);
2440 break;
2441 }
2442 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2443 keyword);
2444 break;
2445 }
2446 case 'F':
2447 case 'f':
2448 {
2449 if (LocaleCompare(keyword, "fill") == 0)
2450 {
2451 (void) QueryColorDatabase(value,&draw_info->fill,
2452 &exception);
2453 break;
2454 }
2455 if (LocaleCompare(keyword,"family") == 0)
2456 {
2457 CloneString(&draw_info->family,value);
2458 break;
2459 }
2460 if (LocaleCompare(keyword,"font") == 0)
2461 {
2462 CloneString(&draw_info->font,value);
2463 break;
2464 }
2465 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2466 keyword);
2467 break;
2468 }
2469 case 'G':
2470 case 'g':
2471 {
2472 if (LocaleCompare(keyword,"geometry") == 0)
2473 {
2474 flags=ParsePageGeometry(msl_info->image[n],value,
2475 &geometry,&exception);
2476 if ((flags & HeightValue) == 0)
2477 geometry.height=geometry.width;
2478 break;
2479 }
2480 if (LocaleCompare(keyword,"gravity") == 0)
2481 {
cristy042ee782011-04-22 18:48:30 +00002482 option=ParseCommandOption(MagickGravityOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002483 value);
2484 if (option < 0)
2485 ThrowMSLException(OptionError,"UnrecognizedGravityType",
2486 value);
2487 draw_info->gravity=(GravityType) option;
2488 break;
2489 }
2490 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2491 keyword);
2492 break;
2493 }
2494 case 'P':
2495 case 'p':
2496 {
2497 if (LocaleCompare(keyword,"primitive") == 0)
cristyb988fe72009-09-16 01:01:10 +00002498 {
cristy3ed852e2009-09-05 21:47:34 +00002499 CloneString(&draw_info->primitive,value);
2500 break;
2501 }
2502 if (LocaleCompare(keyword,"pointsize") == 0)
2503 {
cristyc1acd842011-05-19 23:05:47 +00002504 draw_info->pointsize=InterpretLocaleValue(value,
2505 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002506 break;
2507 }
2508 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2509 keyword);
2510 break;
2511 }
2512 case 'R':
2513 case 'r':
2514 {
2515 if (LocaleCompare(keyword,"rotate") == 0)
2516 {
cristyc1acd842011-05-19 23:05:47 +00002517 angle=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002518 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
2519 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
2520 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
2521 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
2522 break;
2523 }
2524 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2525 keyword);
2526 break;
2527 }
2528 case 'S':
2529 case 's':
2530 {
2531 if (LocaleCompare(keyword,"scale") == 0)
2532 {
2533 flags=ParseGeometry(value,&geometry_info);
2534 if ((flags & SigmaValue) == 0)
2535 geometry_info.sigma=1.0;
2536 affine.sx=geometry_info.rho;
2537 affine.sy=geometry_info.sigma;
2538 break;
2539 }
2540 if (LocaleCompare(keyword,"skewX") == 0)
2541 {
cristyc1acd842011-05-19 23:05:47 +00002542 angle=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002543 affine.ry=cos(DegreesToRadians(fmod(angle,360.0)));
2544 break;
2545 }
2546 if (LocaleCompare(keyword,"skewY") == 0)
2547 {
cristyc1acd842011-05-19 23:05:47 +00002548 angle=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002549 affine.rx=cos(DegreesToRadians(fmod(angle,360.0)));
2550 break;
2551 }
2552 if (LocaleCompare(keyword,"stretch") == 0)
2553 {
cristy042ee782011-04-22 18:48:30 +00002554 option=ParseCommandOption(MagickStretchOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002555 value);
2556 if (option < 0)
2557 ThrowMSLException(OptionError,"UnrecognizedStretchType",
2558 value);
2559 draw_info->stretch=(StretchType) option;
2560 break;
2561 }
2562 if (LocaleCompare(keyword, "stroke") == 0)
2563 {
2564 (void) QueryColorDatabase(value,&draw_info->stroke,
2565 &exception);
2566 break;
2567 }
2568 if (LocaleCompare(keyword,"strokewidth") == 0)
2569 {
cristyf2f27272009-12-17 14:48:46 +00002570 draw_info->stroke_width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002571 break;
2572 }
2573 if (LocaleCompare(keyword,"style") == 0)
2574 {
cristy042ee782011-04-22 18:48:30 +00002575 option=ParseCommandOption(MagickStyleOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002576 value);
2577 if (option < 0)
2578 ThrowMSLException(OptionError,"UnrecognizedStyleType",
2579 value);
2580 draw_info->style=(StyleType) option;
2581 break;
2582 }
2583 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2584 keyword);
2585 break;
2586 }
2587 case 'T':
2588 case 't':
2589 {
2590 if (LocaleCompare(keyword,"text") == 0)
2591 {
2592 CloneString(&draw_info->text,value);
2593 break;
2594 }
2595 if (LocaleCompare(keyword,"translate") == 0)
2596 {
2597 flags=ParseGeometry(value,&geometry_info);
2598 if ((flags & SigmaValue) == 0)
2599 geometry_info.sigma=1.0;
2600 affine.tx=geometry_info.rho;
2601 affine.ty=geometry_info.sigma;
2602 break;
2603 }
2604 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2605 keyword);
2606 break;
2607 }
2608 case 'U':
2609 case 'u':
2610 {
2611 if (LocaleCompare(keyword, "undercolor") == 0)
2612 {
2613 (void) QueryColorDatabase(value,&draw_info->undercolor,
2614 &exception);
2615 break;
2616 }
2617 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2618 keyword);
2619 break;
2620 }
2621 case 'W':
2622 case 'w':
2623 {
2624 if (LocaleCompare(keyword,"weight") == 0)
2625 {
cristyf2f27272009-12-17 14:48:46 +00002626 draw_info->weight=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002627 break;
2628 }
2629 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2630 keyword);
2631 break;
2632 }
2633 case 'X':
2634 case 'x':
2635 {
2636 if (LocaleCompare(keyword,"x") == 0)
2637 {
cristyf2f27272009-12-17 14:48:46 +00002638 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002639 break;
2640 }
2641 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2642 keyword);
2643 break;
2644 }
2645 case 'Y':
2646 case 'y':
2647 {
2648 if (LocaleCompare(keyword,"y") == 0)
2649 {
cristyf2f27272009-12-17 14:48:46 +00002650 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002651 break;
2652 }
2653 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2654 keyword);
2655 break;
2656 }
2657 default:
2658 {
2659 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2660 keyword);
2661 break;
2662 }
2663 }
2664 }
cristyb51dff52011-05-19 16:55:47 +00002665 (void) FormatLocaleString(text,MaxTextExtent,
cristye8c25f92010-06-03 00:53:06 +00002666 "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,(double)
2667 geometry.height,(double) geometry.x,(double) geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00002668 CloneString(&draw_info->geometry,text);
cristyef7c8a52010-10-10 13:46:51 +00002669 draw_info->affine.sx=affine.sx*current.sx+affine.ry*current.rx;
2670 draw_info->affine.rx=affine.rx*current.sx+affine.sy*current.rx;
2671 draw_info->affine.ry=affine.sx*current.ry+affine.ry*current.sy;
2672 draw_info->affine.sy=affine.rx*current.ry+affine.sy*current.sy;
2673 draw_info->affine.tx=affine.sx*current.tx+affine.ry*current.ty+
2674 affine.tx;
2675 draw_info->affine.ty=affine.rx*current.tx+affine.sy*current.ty+
2676 affine.ty;
cristy3ed852e2009-09-05 21:47:34 +00002677 (void) DrawImage(msl_info->image[n],draw_info);
2678 draw_info=DestroyDrawInfo(draw_info);
2679 break;
2680 }
2681 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
2682 }
2683 case 'E':
2684 case 'e':
2685 {
cristyb988fe72009-09-16 01:01:10 +00002686 if (LocaleCompare((const char *) tag,"edge") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002687 {
2688 Image
2689 *edge_image;
2690
2691 /*
2692 Edge image.
2693 */
2694 if (msl_info->image[n] == (Image *) NULL)
2695 {
cristyb988fe72009-09-16 01:01:10 +00002696 ThrowMSLException(OptionError,"NoImagesDefined",
2697 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002698 break;
2699 }
2700 if (attributes != (const xmlChar **) NULL)
2701 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2702 {
2703 keyword=(const char *) attributes[i++];
2704 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002705 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002706 CloneString(&value,attribute);
2707 switch (*keyword)
2708 {
2709 case 'G':
2710 case 'g':
2711 {
2712 if (LocaleCompare(keyword,"geometry") == 0)
2713 {
2714 flags=ParseGeometry(value,&geometry_info);
2715 if ((flags & SigmaValue) == 0)
2716 geometry_info.sigma=1.0;
2717 break;
2718 }
2719 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2720 keyword);
2721 break;
2722 }
2723 case 'R':
2724 case 'r':
2725 {
2726 if (LocaleCompare(keyword,"radius") == 0)
2727 {
cristyc1acd842011-05-19 23:05:47 +00002728 geometry_info.rho=InterpretLocaleValue(value,
2729 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002730 break;
2731 }
2732 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2733 keyword);
2734 break;
2735 }
2736 default:
2737 {
2738 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2739 keyword);
2740 break;
2741 }
2742 }
2743 }
2744 edge_image=EdgeImage(msl_info->image[n],geometry_info.rho,
2745 &msl_info->image[n]->exception);
2746 if (edge_image == (Image *) NULL)
2747 break;
2748 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2749 msl_info->image[n]=edge_image;
2750 break;
2751 }
cristyb988fe72009-09-16 01:01:10 +00002752 if (LocaleCompare((const char *) tag,"emboss") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002753 {
2754 Image
2755 *emboss_image;
2756
2757 /*
2758 Emboss image.
2759 */
2760 if (msl_info->image[n] == (Image *) NULL)
2761 {
cristyb988fe72009-09-16 01:01:10 +00002762 ThrowMSLException(OptionError,"NoImagesDefined",
2763 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002764 break;
2765 }
2766 if (attributes != (const xmlChar **) NULL)
2767 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2768 {
2769 keyword=(const char *) attributes[i++];
2770 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002771 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002772 CloneString(&value,attribute);
2773 switch (*keyword)
2774 {
2775 case 'G':
2776 case 'g':
2777 {
2778 if (LocaleCompare(keyword,"geometry") == 0)
2779 {
2780 flags=ParseGeometry(value,&geometry_info);
2781 if ((flags & SigmaValue) == 0)
2782 geometry_info.sigma=1.0;
2783 break;
2784 }
2785 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2786 keyword);
2787 break;
2788 }
2789 case 'R':
2790 case 'r':
2791 {
2792 if (LocaleCompare(keyword,"radius") == 0)
2793 {
cristyc1acd842011-05-19 23:05:47 +00002794 geometry_info.rho=InterpretLocaleValue(value,
2795 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002796 break;
2797 }
2798 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2799 keyword);
2800 break;
2801 }
2802 case 'S':
2803 case 's':
2804 {
2805 if (LocaleCompare(keyword,"sigma") == 0)
2806 {
cristyf2f27272009-12-17 14:48:46 +00002807 geometry_info.sigma=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002808 break;
2809 }
2810 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2811 keyword);
2812 break;
2813 }
2814 default:
2815 {
2816 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2817 keyword);
2818 break;
2819 }
2820 }
2821 }
2822 emboss_image=EmbossImage(msl_info->image[n],geometry_info.rho,
2823 geometry_info.sigma,&msl_info->image[n]->exception);
2824 if (emboss_image == (Image *) NULL)
2825 break;
2826 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2827 msl_info->image[n]=emboss_image;
2828 break;
2829 }
cristyb988fe72009-09-16 01:01:10 +00002830 if (LocaleCompare((const char *) tag,"enhance") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002831 {
2832 Image
2833 *enhance_image;
2834
2835 /*
2836 Enhance image.
2837 */
2838 if (msl_info->image[n] == (Image *) NULL)
2839 {
cristyb988fe72009-09-16 01:01:10 +00002840 ThrowMSLException(OptionError,"NoImagesDefined",
2841 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002842 break;
2843 }
2844 if (attributes != (const xmlChar **) NULL)
2845 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2846 {
2847 keyword=(const char *) attributes[i++];
2848 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002849 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002850 CloneString(&value,attribute);
2851 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
2852 }
2853 enhance_image=EnhanceImage(msl_info->image[n],
2854 &msl_info->image[n]->exception);
2855 if (enhance_image == (Image *) NULL)
2856 break;
2857 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2858 msl_info->image[n]=enhance_image;
2859 break;
2860 }
cristyb988fe72009-09-16 01:01:10 +00002861 if (LocaleCompare((const char *) tag,"equalize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002862 {
2863 /*
2864 Equalize 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],
cristyb988fe72009-09-16 01:01:10 +00002877 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002878 CloneString(&value,attribute);
2879 switch (*keyword)
2880 {
2881 default:
2882 {
2883 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2884 keyword);
2885 break;
2886 }
2887 }
2888 }
cristy6d8c3d72011-08-22 01:20:01 +00002889 (void) EqualizeImage(msl_info->image[n],
2890 &msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00002891 break;
2892 }
2893 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
2894 }
2895 case 'F':
2896 case 'f':
2897 {
cristyb988fe72009-09-16 01:01:10 +00002898 if (LocaleCompare((const char *) tag, "flatten") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002899 {
2900 if (msl_info->image[n] == (Image *) NULL)
2901 {
cristyb988fe72009-09-16 01:01:10 +00002902 ThrowMSLException(OptionError,"NoImagesDefined",
2903 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002904 break;
2905 }
2906
2907 /* no attributes here */
2908
2909 /* process the image */
2910 {
2911 Image
2912 *newImage;
2913
2914 newImage=MergeImageLayers(msl_info->image[n],FlattenLayer,
2915 &msl_info->image[n]->exception);
2916 if (newImage == (Image *) NULL)
2917 break;
2918 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2919 msl_info->image[n]=newImage;
2920 break;
2921 }
2922 }
cristyb988fe72009-09-16 01:01:10 +00002923 if (LocaleCompare((const char *) tag,"flip") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002924 {
2925 Image
2926 *flip_image;
2927
2928 /*
2929 Flip image.
2930 */
2931 if (msl_info->image[n] == (Image *) NULL)
2932 {
cristyb988fe72009-09-16 01:01:10 +00002933 ThrowMSLException(OptionError,"NoImagesDefined",
2934 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002935 break;
2936 }
2937 if (attributes != (const xmlChar **) NULL)
2938 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2939 {
2940 keyword=(const char *) attributes[i++];
2941 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002942 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002943 CloneString(&value,attribute);
2944 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
2945 }
2946 flip_image=FlipImage(msl_info->image[n],
2947 &msl_info->image[n]->exception);
2948 if (flip_image == (Image *) NULL)
2949 break;
2950 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2951 msl_info->image[n]=flip_image;
2952 break;
2953 }
cristyb988fe72009-09-16 01:01:10 +00002954 if (LocaleCompare((const char *) tag,"flop") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002955 {
2956 Image
2957 *flop_image;
2958
2959 /*
2960 Flop image.
2961 */
2962 if (msl_info->image[n] == (Image *) NULL)
2963 {
cristyb988fe72009-09-16 01:01:10 +00002964 ThrowMSLException(OptionError,"NoImagesDefined",
2965 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002966 break;
2967 }
2968 if (attributes != (const xmlChar **) NULL)
2969 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2970 {
2971 keyword=(const char *) attributes[i++];
2972 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00002973 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00002974 CloneString(&value,attribute);
2975 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
2976 }
2977 flop_image=FlopImage(msl_info->image[n],
2978 &msl_info->image[n]->exception);
2979 if (flop_image == (Image *) NULL)
2980 break;
2981 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2982 msl_info->image[n]=flop_image;
2983 break;
2984 }
cristyb988fe72009-09-16 01:01:10 +00002985 if (LocaleCompare((const char *) tag,"frame") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002986 {
2987 FrameInfo
2988 frame_info;
2989
2990 Image
2991 *frame_image;
2992
2993 /*
2994 Frame image.
2995 */
2996 if (msl_info->image[n] == (Image *) NULL)
2997 {
cristyb988fe72009-09-16 01:01:10 +00002998 ThrowMSLException(OptionError,"NoImagesDefined",
2999 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003000 break;
3001 }
3002 SetGeometry(msl_info->image[n],&geometry);
3003 if (attributes != (const xmlChar **) NULL)
3004 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3005 {
3006 keyword=(const char *) attributes[i++];
3007 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003008 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003009 CloneString(&value,attribute);
3010 switch (*keyword)
3011 {
3012 case 'C':
3013 case 'c':
3014 {
3015 if (LocaleCompare(keyword,"compose") == 0)
3016 {
cristy042ee782011-04-22 18:48:30 +00003017 option=ParseCommandOption(MagickComposeOptions,
cristy3ed852e2009-09-05 21:47:34 +00003018 MagickFalse,value);
3019 if (option < 0)
3020 ThrowMSLException(OptionError,"UnrecognizedComposeType",
3021 value);
3022 msl_info->image[n]->compose=(CompositeOperator) option;
3023 break;
3024 }
3025 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3026 keyword);
3027 break;
3028 }
3029 case 'F':
3030 case 'f':
3031 {
3032 if (LocaleCompare(keyword, "fill") == 0)
3033 {
3034 (void) QueryColorDatabase(value,
3035 &msl_info->image[n]->matte_color,&exception);
3036 break;
3037 }
3038 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3039 keyword);
3040 break;
3041 }
3042 case 'G':
3043 case 'g':
3044 {
3045 if (LocaleCompare(keyword,"geometry") == 0)
3046 {
3047 flags=ParsePageGeometry(msl_info->image[n],value,
3048 &geometry,&exception);
3049 if ((flags & HeightValue) == 0)
3050 geometry.height=geometry.width;
3051 frame_info.width=geometry.width;
3052 frame_info.height=geometry.height;
3053 frame_info.outer_bevel=geometry.x;
3054 frame_info.inner_bevel=geometry.y;
3055 break;
3056 }
3057 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3058 keyword);
3059 break;
3060 }
3061 case 'H':
3062 case 'h':
3063 {
3064 if (LocaleCompare(keyword,"height") == 0)
3065 {
cristyf2f27272009-12-17 14:48:46 +00003066 frame_info.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003067 break;
3068 }
3069 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3070 keyword);
3071 break;
3072 }
3073 case 'I':
3074 case 'i':
3075 {
3076 if (LocaleCompare(keyword,"inner") == 0)
3077 {
cristyf2f27272009-12-17 14:48:46 +00003078 frame_info.inner_bevel=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003079 break;
3080 }
3081 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3082 keyword);
3083 break;
3084 }
3085 case 'O':
3086 case 'o':
3087 {
3088 if (LocaleCompare(keyword,"outer") == 0)
3089 {
cristyf2f27272009-12-17 14:48:46 +00003090 frame_info.outer_bevel=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003091 break;
3092 }
3093 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3094 keyword);
3095 break;
3096 }
3097 case 'W':
3098 case 'w':
3099 {
3100 if (LocaleCompare(keyword,"width") == 0)
3101 {
cristyf2f27272009-12-17 14:48:46 +00003102 frame_info.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003103 break;
3104 }
3105 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3106 keyword);
3107 break;
3108 }
3109 default:
3110 {
3111 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3112 keyword);
3113 break;
3114 }
3115 }
3116 }
cristybb503372010-05-27 20:51:26 +00003117 frame_info.x=(ssize_t) frame_info.width;
3118 frame_info.y=(ssize_t) frame_info.height;
cristy3ed852e2009-09-05 21:47:34 +00003119 frame_info.width=msl_info->image[n]->columns+2*frame_info.x;
3120 frame_info.height=msl_info->image[n]->rows+2*frame_info.y;
3121 frame_image=FrameImage(msl_info->image[n],&frame_info,
3122 &msl_info->image[n]->exception);
3123 if (frame_image == (Image *) NULL)
3124 break;
3125 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3126 msl_info->image[n]=frame_image;
3127 break;
3128 }
3129 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3130 }
3131 case 'G':
3132 case 'g':
3133 {
cristyb988fe72009-09-16 01:01:10 +00003134 if (LocaleCompare((const char *) tag,"gamma") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003135 {
3136 char
3137 gamma[MaxTextExtent];
3138
cristy4c08aed2011-07-01 19:47:50 +00003139 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00003140 pixel;
3141
3142 /*
3143 Gamma image.
3144 */
3145 if (msl_info->image[n] == (Image *) NULL)
3146 {
cristyb988fe72009-09-16 01:01:10 +00003147 ThrowMSLException(OptionError,"NoImagesDefined",
3148 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003149 break;
3150 }
3151 channel=UndefinedChannel;
3152 pixel.red=0.0;
3153 pixel.green=0.0;
3154 pixel.blue=0.0;
3155 *gamma='\0';
3156 if (attributes != (const xmlChar **) NULL)
3157 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3158 {
3159 keyword=(const char *) attributes[i++];
3160 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003161 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003162 CloneString(&value,attribute);
3163 switch (*keyword)
3164 {
3165 case 'B':
3166 case 'b':
3167 {
3168 if (LocaleCompare(keyword,"blue") == 0)
3169 {
cristyc1acd842011-05-19 23:05:47 +00003170 pixel.blue=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003171 break;
3172 }
3173 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3174 keyword);
3175 break;
3176 }
3177 case 'C':
3178 case 'c':
3179 {
3180 if (LocaleCompare(keyword,"channel") == 0)
3181 {
3182 option=ParseChannelOption(value);
3183 if (option < 0)
3184 ThrowMSLException(OptionError,"UnrecognizedChannelType",
3185 value);
3186 channel=(ChannelType) option;
3187 break;
3188 }
3189 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3190 keyword);
3191 break;
3192 }
3193 case 'G':
3194 case 'g':
3195 {
3196 if (LocaleCompare(keyword,"gamma") == 0)
3197 {
3198 (void) CopyMagickString(gamma,value,MaxTextExtent);
3199 break;
3200 }
3201 if (LocaleCompare(keyword,"green") == 0)
3202 {
cristyc1acd842011-05-19 23:05:47 +00003203 pixel.green=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003204 break;
3205 }
3206 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3207 keyword);
3208 break;
3209 }
3210 case 'R':
3211 case 'r':
3212 {
3213 if (LocaleCompare(keyword,"red") == 0)
3214 {
cristyc1acd842011-05-19 23:05:47 +00003215 pixel.red=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003216 break;
3217 }
3218 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3219 keyword);
3220 break;
3221 }
3222 default:
3223 {
3224 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3225 keyword);
3226 break;
3227 }
3228 }
3229 }
3230 if (*gamma == '\0')
cristyb51dff52011-05-19 16:55:47 +00003231 (void) FormatLocaleString(gamma,MaxTextExtent,"%g,%g,%g",
cristy3ed852e2009-09-05 21:47:34 +00003232 (double) pixel.red,(double) pixel.green,(double) pixel.blue);
cristyb3e7c6c2011-07-24 01:43:55 +00003233 (void) GammaImage(msl_info->image[n],atof(gamma),
3234 &msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00003235 break;
3236 }
cristyb988fe72009-09-16 01:01:10 +00003237 else if (LocaleCompare((const char *) tag,"get") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003238 {
3239 if (msl_info->image[n] == (Image *) NULL)
3240 {
cristyb988fe72009-09-16 01:01:10 +00003241 ThrowMSLException(OptionError,"NoImagesDefined",
3242 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003243 break;
3244 }
3245 if (attributes == (const xmlChar **) NULL)
3246 break;
3247 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3248 {
3249 keyword=(const char *) attributes[i++];
cristyb988fe72009-09-16 01:01:10 +00003250 CloneString(&value,(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003251 (void) CopyMagickString(key,value,MaxTextExtent);
3252 switch (*keyword)
3253 {
3254 case 'H':
3255 case 'h':
3256 {
3257 if (LocaleCompare(keyword,"height") == 0)
3258 {
cristyb51dff52011-05-19 16:55:47 +00003259 (void) FormatLocaleString(value,MaxTextExtent,"%.20g",
cristye8c25f92010-06-03 00:53:06 +00003260 (double) msl_info->image[n]->rows);
cristy3ed852e2009-09-05 21:47:34 +00003261 (void) SetImageProperty(msl_info->attributes[n],key,value);
3262 break;
3263 }
3264 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3265 }
3266 case 'W':
3267 case 'w':
3268 {
3269 if (LocaleCompare(keyword,"width") == 0)
3270 {
cristyb51dff52011-05-19 16:55:47 +00003271 (void) FormatLocaleString(value,MaxTextExtent,"%.20g",
cristye8c25f92010-06-03 00:53:06 +00003272 (double) msl_info->image[n]->columns);
cristy3ed852e2009-09-05 21:47:34 +00003273 (void) SetImageProperty(msl_info->attributes[n],key,value);
3274 break;
3275 }
3276 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3277 }
3278 default:
3279 {
3280 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3281 break;
3282 }
3283 }
3284 }
3285 break;
3286 }
cristyb988fe72009-09-16 01:01:10 +00003287 else if (LocaleCompare((const char *) tag, "group") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003288 {
3289 msl_info->number_groups++;
3290 msl_info->group_info=(MSLGroupInfo *) ResizeQuantumMemory(
3291 msl_info->group_info,msl_info->number_groups+1UL,
3292 sizeof(*msl_info->group_info));
3293 break;
3294 }
3295 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3296 }
3297 case 'I':
3298 case 'i':
3299 {
cristyb988fe72009-09-16 01:01:10 +00003300 if (LocaleCompare((const char *) tag,"image") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003301 {
cristy3ed852e2009-09-05 21:47:34 +00003302 MSLPushImage(msl_info,(Image *) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003303 if (attributes == (const xmlChar **) NULL)
3304 break;
3305 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3306 {
3307 keyword=(const char *) attributes[i++];
3308 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003309 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00003310 switch (*keyword)
3311 {
cristyb988fe72009-09-16 01:01:10 +00003312 case 'C':
3313 case 'c':
cristy3ed852e2009-09-05 21:47:34 +00003314 {
cristyb988fe72009-09-16 01:01:10 +00003315 if (LocaleCompare(keyword,"color") == 0)
3316 {
3317 Image
3318 *next_image;
cristy3ed852e2009-09-05 21:47:34 +00003319
cristyb988fe72009-09-16 01:01:10 +00003320 (void) CopyMagickString(msl_info->image_info[n]->filename,
3321 "xc:",MaxTextExtent);
3322 (void) ConcatenateMagickString(msl_info->image_info[n]->
3323 filename,value,MaxTextExtent);
3324 next_image=ReadImage(msl_info->image_info[n],&exception);
3325 CatchException(&exception);
3326 if (next_image == (Image *) NULL)
3327 continue;
3328 if (msl_info->image[n] == (Image *) NULL)
3329 msl_info->image[n]=next_image;
3330 else
3331 {
3332 register Image
3333 *p;
cristy3ed852e2009-09-05 21:47:34 +00003334
cristyb988fe72009-09-16 01:01:10 +00003335 /*
3336 Link image into image list.
3337 */
3338 p=msl_info->image[n];
3339 while (p->next != (Image *) NULL)
3340 p=GetNextImageInList(p);
3341 next_image->previous=p;
3342 p->next=next_image;
3343 }
3344 break;
3345 }
cristyb20775d2009-09-16 01:51:41 +00003346 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00003347 break;
3348 }
3349 default:
3350 {
cristyb20775d2009-09-16 01:51:41 +00003351 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00003352 break;
3353 }
3354 }
3355 }
3356 break;
3357 }
cristyb988fe72009-09-16 01:01:10 +00003358 if (LocaleCompare((const char *) tag,"implode") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003359 {
3360 Image
3361 *implode_image;
3362
3363 /*
3364 Implode image.
3365 */
3366 if (msl_info->image[n] == (Image *) NULL)
3367 {
cristyb988fe72009-09-16 01:01:10 +00003368 ThrowMSLException(OptionError,"NoImagesDefined",
3369 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003370 break;
3371 }
3372 if (attributes != (const xmlChar **) NULL)
3373 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3374 {
3375 keyword=(const char *) attributes[i++];
3376 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003377 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003378 CloneString(&value,attribute);
3379 switch (*keyword)
3380 {
3381 case 'A':
3382 case 'a':
3383 {
3384 if (LocaleCompare(keyword,"amount") == 0)
3385 {
cristyc1acd842011-05-19 23:05:47 +00003386 geometry_info.rho=InterpretLocaleValue(value,
3387 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003388 break;
3389 }
3390 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3391 keyword);
3392 break;
3393 }
3394 case 'G':
3395 case 'g':
3396 {
3397 if (LocaleCompare(keyword,"geometry") == 0)
3398 {
3399 flags=ParseGeometry(value,&geometry_info);
3400 if ((flags & SigmaValue) == 0)
3401 geometry_info.sigma=1.0;
3402 break;
3403 }
3404 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3405 keyword);
3406 break;
3407 }
3408 default:
3409 {
3410 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3411 keyword);
3412 break;
3413 }
3414 }
3415 }
3416 implode_image=ImplodeImage(msl_info->image[n],geometry_info.rho,
3417 &msl_info->image[n]->exception);
3418 if (implode_image == (Image *) NULL)
3419 break;
3420 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3421 msl_info->image[n]=implode_image;
3422 break;
3423 }
3424 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3425 }
3426 case 'L':
3427 case 'l':
3428 {
cristyb988fe72009-09-16 01:01:10 +00003429 if (LocaleCompare((const char *) tag,"label") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003430 break;
cristyb988fe72009-09-16 01:01:10 +00003431 if (LocaleCompare((const char *) tag, "level") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003432 {
3433 double
3434 levelBlack = 0, levelGamma = 1, levelWhite = QuantumRange;
3435
3436 if (msl_info->image[n] == (Image *) NULL)
3437 {
cristyb988fe72009-09-16 01:01:10 +00003438 ThrowMSLException(OptionError,"NoImagesDefined",
3439 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003440 break;
3441 }
3442 if (attributes == (const xmlChar **) NULL)
3443 break;
3444 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3445 {
3446 keyword=(const char *) attributes[i++];
cristyb988fe72009-09-16 01:01:10 +00003447 CloneString(&value,(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003448 (void) CopyMagickString(key,value,MaxTextExtent);
3449 switch (*keyword)
3450 {
3451 case 'B':
3452 case 'b':
3453 {
3454 if (LocaleCompare(keyword,"black") == 0)
3455 {
cristyc1acd842011-05-19 23:05:47 +00003456 levelBlack = InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003457 break;
3458 }
3459 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3460 break;
3461 }
3462 case 'G':
3463 case 'g':
3464 {
3465 if (LocaleCompare(keyword,"gamma") == 0)
3466 {
cristyc1acd842011-05-19 23:05:47 +00003467 levelGamma = InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003468 break;
3469 }
3470 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3471 break;
3472 }
3473 case 'W':
3474 case 'w':
3475 {
3476 if (LocaleCompare(keyword,"white") == 0)
3477 {
cristyc1acd842011-05-19 23:05:47 +00003478 levelWhite = InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003479 break;
3480 }
3481 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3482 break;
3483 }
3484 default:
3485 {
3486 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3487 break;
3488 }
3489 }
3490 }
3491
3492 /* process image */
cristy01e9afd2011-08-10 17:38:41 +00003493 LevelImage(msl_info->image[n],levelBlack,levelWhite,levelGamma,
3494 &msl_info->image[n]->exception);
cristyf89cb1d2011-07-07 01:24:37 +00003495 break;
cristy3ed852e2009-09-05 21:47:34 +00003496 }
3497 }
3498 case 'M':
3499 case 'm':
3500 {
cristyb988fe72009-09-16 01:01:10 +00003501 if (LocaleCompare((const char *) tag,"magnify") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003502 {
3503 Image
3504 *magnify_image;
3505
3506 /*
3507 Magnify image.
3508 */
3509 if (msl_info->image[n] == (Image *) NULL)
3510 {
cristyb988fe72009-09-16 01:01:10 +00003511 ThrowMSLException(OptionError,"NoImagesDefined",
3512 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003513 break;
3514 }
3515 if (attributes != (const xmlChar **) NULL)
3516 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3517 {
3518 keyword=(const char *) attributes[i++];
3519 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003520 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003521 CloneString(&value,attribute);
3522 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3523 }
3524 magnify_image=MagnifyImage(msl_info->image[n],
3525 &msl_info->image[n]->exception);
3526 if (magnify_image == (Image *) NULL)
3527 break;
3528 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3529 msl_info->image[n]=magnify_image;
3530 break;
3531 }
cristyb988fe72009-09-16 01:01:10 +00003532 if (LocaleCompare((const char *) tag,"map") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003533 {
3534 Image
3535 *affinity_image;
3536
3537 MagickBooleanType
3538 dither;
3539
3540 QuantizeInfo
3541 *quantize_info;
3542
3543 /*
3544 Map image.
3545 */
3546 if (msl_info->image[n] == (Image *) NULL)
3547 {
cristyb988fe72009-09-16 01:01:10 +00003548 ThrowMSLException(OptionError,"NoImagesDefined",
3549 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003550 break;
3551 }
3552 affinity_image=NewImageList();
3553 dither=MagickFalse;
3554 if (attributes != (const xmlChar **) NULL)
3555 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3556 {
3557 keyword=(const char *) attributes[i++];
3558 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003559 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003560 CloneString(&value,attribute);
3561 switch (*keyword)
3562 {
3563 case 'D':
3564 case 'd':
3565 {
3566 if (LocaleCompare(keyword,"dither") == 0)
3567 {
cristy042ee782011-04-22 18:48:30 +00003568 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00003569 value);
3570 if (option < 0)
3571 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
3572 value);
3573 dither=(MagickBooleanType) option;
3574 break;
3575 }
3576 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3577 keyword);
3578 break;
3579 }
3580 case 'I':
3581 case 'i':
3582 {
3583 if (LocaleCompare(keyword,"image") == 0)
3584 for (j=0; j < msl_info->n; j++)
3585 {
3586 const char
3587 *attribute;
cristyb988fe72009-09-16 01:01:10 +00003588
cristy3ed852e2009-09-05 21:47:34 +00003589 attribute=GetImageProperty(msl_info->attributes[j],"id");
3590 if ((attribute != (const char *) NULL) &&
3591 (LocaleCompare(attribute,value) == 0))
3592 {
3593 affinity_image=CloneImage(msl_info->image[j],0,0,
3594 MagickFalse,&exception);
3595 break;
3596 }
3597 }
3598 break;
3599 }
3600 default:
3601 {
3602 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3603 keyword);
3604 break;
3605 }
3606 }
3607 }
3608 quantize_info=AcquireQuantizeInfo(msl_info->image_info[n]);
3609 quantize_info->dither=dither;
3610 (void) RemapImages(quantize_info,msl_info->image[n],
3611 affinity_image);
3612 quantize_info=DestroyQuantizeInfo(quantize_info);
3613 affinity_image=DestroyImage(affinity_image);
3614 break;
3615 }
cristyb988fe72009-09-16 01:01:10 +00003616 if (LocaleCompare((const char *) tag,"matte-floodfill") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003617 {
3618 double
3619 opacity;
3620
cristy4c08aed2011-07-01 19:47:50 +00003621 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00003622 target;
3623
3624 PaintMethod
3625 paint_method;
3626
3627 /*
3628 Matte floodfill image.
3629 */
3630 opacity=0.0;
3631 if (msl_info->image[n] == (Image *) NULL)
3632 {
cristyb988fe72009-09-16 01:01:10 +00003633 ThrowMSLException(OptionError,"NoImagesDefined",
3634 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003635 break;
3636 }
3637 SetGeometry(msl_info->image[n],&geometry);
3638 paint_method=FloodfillMethod;
3639 if (attributes != (const xmlChar **) NULL)
3640 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3641 {
3642 keyword=(const char *) attributes[i++];
3643 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003644 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003645 CloneString(&value,attribute);
3646 switch (*keyword)
3647 {
3648 case 'B':
3649 case 'b':
3650 {
3651 if (LocaleCompare(keyword,"bordercolor") == 0)
3652 {
3653 (void) QueryMagickColor(value,&target,&exception);
3654 paint_method=FillToBorderMethod;
3655 break;
3656 }
3657 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3658 keyword);
3659 break;
3660 }
3661 case 'F':
3662 case 'f':
3663 {
3664 if (LocaleCompare(keyword,"fuzz") == 0)
3665 {
cristyc1acd842011-05-19 23:05:47 +00003666 msl_info->image[n]->fuzz=InterpretLocaleValue(value,
3667 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003668 break;
3669 }
3670 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3671 keyword);
3672 break;
3673 }
3674 case 'G':
3675 case 'g':
3676 {
3677 if (LocaleCompare(keyword,"geometry") == 0)
3678 {
3679 flags=ParsePageGeometry(msl_info->image[n],value,
3680 &geometry,&exception);
3681 if ((flags & HeightValue) == 0)
3682 geometry.height=geometry.width;
3683 (void) GetOneVirtualMagickPixel(msl_info->image[n],
3684 geometry.x,geometry.y,&target,&exception);
3685 break;
3686 }
3687 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3688 keyword);
3689 break;
3690 }
3691 case 'O':
3692 case 'o':
3693 {
3694 if (LocaleCompare(keyword,"opacity") == 0)
3695 {
cristyc1acd842011-05-19 23:05:47 +00003696 opacity=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003697 break;
3698 }
3699 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3700 keyword);
3701 break;
3702 }
3703 case 'X':
3704 case 'x':
3705 {
3706 if (LocaleCompare(keyword,"x") == 0)
3707 {
cristyf2f27272009-12-17 14:48:46 +00003708 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003709 (void) GetOneVirtualMagickPixel(msl_info->image[n],
3710 geometry.x,geometry.y,&target,&exception);
3711 break;
3712 }
3713 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3714 keyword);
3715 break;
3716 }
3717 case 'Y':
3718 case 'y':
3719 {
3720 if (LocaleCompare(keyword,"y") == 0)
3721 {
cristyf2f27272009-12-17 14:48:46 +00003722 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003723 (void) GetOneVirtualMagickPixel(msl_info->image[n],
3724 geometry.x,geometry.y,&target,&exception);
3725 break;
3726 }
3727 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3728 keyword);
3729 break;
3730 }
3731 default:
3732 {
3733 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3734 keyword);
3735 break;
3736 }
3737 }
3738 }
3739 draw_info=CloneDrawInfo(msl_info->image_info[n],
3740 msl_info->draw_info[n]);
cristy4c08aed2011-07-01 19:47:50 +00003741 draw_info->fill.alpha=ClampToQuantum(opacity);
cristybd5a96c2011-08-21 00:04:26 +00003742 channel_mask=SetPixelChannelMask(msl_info->image[n],AlphaChannel);
cristyd42d9952011-07-08 14:21:50 +00003743 (void) FloodfillPaintImage(msl_info->image[n],draw_info,&target,
3744 geometry.x,geometry.y,paint_method == FloodfillMethod ?
cristy189e84c2011-08-27 18:08:53 +00003745 MagickFalse : MagickTrue,&msl_info->image[n]->exception);
cristybd5a96c2011-08-21 00:04:26 +00003746 (void) SetPixelChannelMap(msl_info->image[n],channel_mask);
cristy3ed852e2009-09-05 21:47:34 +00003747 draw_info=DestroyDrawInfo(draw_info);
3748 break;
3749 }
cristyb988fe72009-09-16 01:01:10 +00003750 if (LocaleCompare((const char *) tag,"median-filter") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003751 {
3752 Image
3753 *median_image;
3754
3755 /*
3756 Median-filter image.
3757 */
3758 if (msl_info->image[n] == (Image *) NULL)
3759 {
cristyb988fe72009-09-16 01:01:10 +00003760 ThrowMSLException(OptionError,"NoImagesDefined",
3761 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003762 break;
3763 }
3764 if (attributes != (const xmlChar **) NULL)
3765 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3766 {
3767 keyword=(const char *) attributes[i++];
3768 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003769 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003770 CloneString(&value,attribute);
3771 switch (*keyword)
3772 {
3773 case 'G':
3774 case 'g':
3775 {
3776 if (LocaleCompare(keyword,"geometry") == 0)
3777 {
3778 flags=ParseGeometry(value,&geometry_info);
3779 if ((flags & SigmaValue) == 0)
3780 geometry_info.sigma=1.0;
3781 break;
3782 }
3783 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3784 keyword);
3785 break;
3786 }
3787 case 'R':
3788 case 'r':
3789 {
3790 if (LocaleCompare(keyword,"radius") == 0)
3791 {
cristyc1acd842011-05-19 23:05:47 +00003792 geometry_info.rho=InterpretLocaleValue(value,
3793 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003794 break;
3795 }
3796 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3797 keyword);
3798 break;
3799 }
3800 default:
3801 {
3802 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3803 keyword);
3804 break;
3805 }
3806 }
3807 }
cristy733678d2011-03-18 21:29:28 +00003808 median_image=StatisticImage(msl_info->image[n],MedianStatistic,
cristy95c38342011-03-18 22:39:51 +00003809 (size_t) geometry_info.rho,(size_t) geometry_info.sigma,
3810 &msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00003811 if (median_image == (Image *) NULL)
3812 break;
3813 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3814 msl_info->image[n]=median_image;
3815 break;
3816 }
cristyb988fe72009-09-16 01:01:10 +00003817 if (LocaleCompare((const char *) tag,"minify") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003818 {
3819 Image
3820 *minify_image;
3821
3822 /*
3823 Minify image.
3824 */
3825 if (msl_info->image[n] == (Image *) NULL)
3826 {
cristyb988fe72009-09-16 01:01:10 +00003827 ThrowMSLException(OptionError,"NoImagesDefined",
3828 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003829 break;
3830 }
3831 if (attributes != (const xmlChar **) NULL)
3832 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3833 {
3834 keyword=(const char *) attributes[i++];
3835 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003836 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003837 CloneString(&value,attribute);
3838 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3839 }
3840 minify_image=MinifyImage(msl_info->image[n],
3841 &msl_info->image[n]->exception);
3842 if (minify_image == (Image *) NULL)
3843 break;
3844 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3845 msl_info->image[n]=minify_image;
3846 break;
3847 }
cristyb988fe72009-09-16 01:01:10 +00003848 if (LocaleCompare((const char *) tag,"msl") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00003849 break;
cristyb988fe72009-09-16 01:01:10 +00003850 if (LocaleCompare((const char *) tag,"modulate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003851 {
3852 char
3853 modulate[MaxTextExtent];
3854
3855 /*
3856 Modulate image.
3857 */
3858 if (msl_info->image[n] == (Image *) NULL)
3859 {
cristyb988fe72009-09-16 01:01:10 +00003860 ThrowMSLException(OptionError,"NoImagesDefined",
3861 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003862 break;
3863 }
3864 geometry_info.rho=100.0;
3865 geometry_info.sigma=100.0;
3866 geometry_info.xi=100.0;
3867 if (attributes != (const xmlChar **) NULL)
3868 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3869 {
3870 keyword=(const char *) attributes[i++];
3871 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003872 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003873 CloneString(&value,attribute);
3874 switch (*keyword)
3875 {
3876 case 'B':
3877 case 'b':
3878 {
3879 if (LocaleCompare(keyword,"blackness") == 0)
3880 {
cristyc1acd842011-05-19 23:05:47 +00003881 geometry_info.rho=InterpretLocaleValue(value,
3882 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003883 break;
3884 }
3885 if (LocaleCompare(keyword,"brightness") == 0)
3886 {
cristyc1acd842011-05-19 23:05:47 +00003887 geometry_info.rho=InterpretLocaleValue(value,
3888 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003889 break;
3890 }
3891 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3892 keyword);
3893 break;
3894 }
3895 case 'F':
3896 case 'f':
3897 {
3898 if (LocaleCompare(keyword,"factor") == 0)
3899 {
3900 flags=ParseGeometry(value,&geometry_info);
3901 break;
3902 }
3903 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3904 keyword);
3905 break;
3906 }
3907 case 'H':
3908 case 'h':
3909 {
3910 if (LocaleCompare(keyword,"hue") == 0)
3911 {
cristyc1acd842011-05-19 23:05:47 +00003912 geometry_info.xi=InterpretLocaleValue(value,
3913 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003914 break;
3915 }
3916 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3917 keyword);
3918 break;
3919 }
3920 case 'L':
3921 case 'l':
3922 {
3923 if (LocaleCompare(keyword,"lightness") == 0)
3924 {
cristyc1acd842011-05-19 23:05:47 +00003925 geometry_info.rho=InterpretLocaleValue(value,
3926 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003927 break;
3928 }
3929 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3930 keyword);
3931 break;
3932 }
3933 case 'S':
3934 case 's':
3935 {
3936 if (LocaleCompare(keyword,"saturation") == 0)
3937 {
cristyc1acd842011-05-19 23:05:47 +00003938 geometry_info.sigma=InterpretLocaleValue(value,
3939 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003940 break;
3941 }
3942 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3943 keyword);
3944 break;
3945 }
3946 case 'W':
3947 case 'w':
3948 {
3949 if (LocaleCompare(keyword,"whiteness") == 0)
3950 {
cristyc1acd842011-05-19 23:05:47 +00003951 geometry_info.sigma=InterpretLocaleValue(value,
3952 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003953 break;
3954 }
3955 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3956 keyword);
3957 break;
3958 }
3959 default:
3960 {
3961 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3962 keyword);
3963 break;
3964 }
3965 }
3966 }
cristyb51dff52011-05-19 16:55:47 +00003967 (void) FormatLocaleString(modulate,MaxTextExtent,"%g,%g,%g",
cristy3ed852e2009-09-05 21:47:34 +00003968 geometry_info.rho,geometry_info.sigma,geometry_info.xi);
cristy33bd5152011-08-24 01:42:24 +00003969 (void) ModulateImage(msl_info->image[n],modulate,
3970 &msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00003971 break;
3972 }
3973 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3974 }
3975 case 'N':
3976 case 'n':
3977 {
cristyb988fe72009-09-16 01:01:10 +00003978 if (LocaleCompare((const char *) tag,"negate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003979 {
3980 MagickBooleanType
3981 gray;
3982
3983 /*
3984 Negate image.
3985 */
3986 if (msl_info->image[n] == (Image *) NULL)
3987 {
cristyb988fe72009-09-16 01:01:10 +00003988 ThrowMSLException(OptionError,"NoImagesDefined",
3989 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003990 break;
3991 }
3992 gray=MagickFalse;
3993 if (attributes != (const xmlChar **) NULL)
3994 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3995 {
3996 keyword=(const char *) attributes[i++];
3997 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00003998 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003999 CloneString(&value,attribute);
4000 switch (*keyword)
4001 {
4002 case 'C':
4003 case 'c':
4004 {
4005 if (LocaleCompare(keyword,"channel") == 0)
4006 {
4007 option=ParseChannelOption(value);
4008 if (option < 0)
4009 ThrowMSLException(OptionError,"UnrecognizedChannelType",
4010 value);
4011 channel=(ChannelType) option;
4012 break;
4013 }
4014 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4015 keyword);
4016 break;
4017 }
4018 case 'G':
4019 case 'g':
4020 {
4021 if (LocaleCompare(keyword,"gray") == 0)
4022 {
cristy042ee782011-04-22 18:48:30 +00004023 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004024 value);
4025 if (option < 0)
4026 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4027 value);
4028 gray=(MagickBooleanType) option;
4029 break;
4030 }
4031 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4032 keyword);
4033 break;
4034 }
4035 default:
4036 {
4037 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4038 keyword);
4039 break;
4040 }
4041 }
4042 }
cristybd5a96c2011-08-21 00:04:26 +00004043 channel_mask=SetPixelChannelMask(msl_info->image[n],channel);
cristyb3e7c6c2011-07-24 01:43:55 +00004044 (void) NegateImage(msl_info->image[n],gray,
4045 &msl_info->image[n]->exception);
cristybd5a96c2011-08-21 00:04:26 +00004046 (void) SetPixelChannelMap(msl_info->image[n],channel_mask);
cristy3ed852e2009-09-05 21:47:34 +00004047 break;
4048 }
cristyb988fe72009-09-16 01:01:10 +00004049 if (LocaleCompare((const char *) tag,"normalize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004050 {
4051 /*
4052 Normalize image.
4053 */
4054 if (msl_info->image[n] == (Image *) NULL)
4055 {
cristyb988fe72009-09-16 01:01:10 +00004056 ThrowMSLException(OptionError,"NoImagesDefined",
4057 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004058 break;
4059 }
4060 if (attributes != (const xmlChar **) NULL)
4061 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4062 {
4063 keyword=(const char *) attributes[i++];
4064 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004065 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004066 CloneString(&value,attribute);
4067 switch (*keyword)
4068 {
4069 case 'C':
4070 case 'c':
4071 {
4072 if (LocaleCompare(keyword,"channel") == 0)
4073 {
4074 option=ParseChannelOption(value);
4075 if (option < 0)
4076 ThrowMSLException(OptionError,"UnrecognizedChannelType",
4077 value);
4078 channel=(ChannelType) option;
4079 break;
4080 }
4081 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4082 keyword);
4083 break;
4084 }
4085 default:
4086 {
4087 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4088 keyword);
4089 break;
4090 }
4091 }
4092 }
cristye23ec9d2011-08-16 18:15:40 +00004093 (void) NormalizeImage(msl_info->image[n],
4094 &msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00004095 break;
4096 }
4097 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4098 }
4099 case 'O':
4100 case 'o':
4101 {
cristyb988fe72009-09-16 01:01:10 +00004102 if (LocaleCompare((const char *) tag,"oil-paint") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004103 {
4104 Image
4105 *paint_image;
4106
4107 /*
4108 Oil-paint image.
4109 */
4110 if (msl_info->image[n] == (Image *) NULL)
4111 {
cristyb988fe72009-09-16 01:01:10 +00004112 ThrowMSLException(OptionError,"NoImagesDefined",
4113 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004114 break;
4115 }
4116 if (attributes != (const xmlChar **) NULL)
4117 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4118 {
4119 keyword=(const char *) attributes[i++];
4120 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004121 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004122 CloneString(&value,attribute);
4123 switch (*keyword)
4124 {
4125 case 'G':
4126 case 'g':
4127 {
4128 if (LocaleCompare(keyword,"geometry") == 0)
4129 {
4130 flags=ParseGeometry(value,&geometry_info);
4131 if ((flags & SigmaValue) == 0)
4132 geometry_info.sigma=1.0;
4133 break;
4134 }
4135 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4136 keyword);
4137 break;
4138 }
4139 case 'R':
4140 case 'r':
4141 {
4142 if (LocaleCompare(keyword,"radius") == 0)
4143 {
cristyc1acd842011-05-19 23:05:47 +00004144 geometry_info.rho=InterpretLocaleValue(value,
4145 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004146 break;
4147 }
4148 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4149 keyword);
4150 break;
4151 }
4152 default:
4153 {
4154 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4155 keyword);
4156 break;
4157 }
4158 }
4159 }
4160 paint_image=OilPaintImage(msl_info->image[n],geometry_info.rho,
cristy14973ba2011-08-27 23:48:07 +00004161 geometry_info.sigma,&msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00004162 if (paint_image == (Image *) NULL)
4163 break;
4164 msl_info->image[n]=DestroyImage(msl_info->image[n]);
4165 msl_info->image[n]=paint_image;
4166 break;
4167 }
cristyb988fe72009-09-16 01:01:10 +00004168 if (LocaleCompare((const char *) tag,"opaque") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004169 {
cristy4c08aed2011-07-01 19:47:50 +00004170 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00004171 fill_color,
4172 target;
4173
4174 /*
4175 Opaque image.
4176 */
4177 if (msl_info->image[n] == (Image *) NULL)
4178 {
cristyb988fe72009-09-16 01:01:10 +00004179 ThrowMSLException(OptionError,"NoImagesDefined",
4180 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004181 break;
4182 }
4183 (void) QueryMagickColor("none",&target,&exception);
4184 (void) QueryMagickColor("none",&fill_color,&exception);
4185 if (attributes != (const xmlChar **) NULL)
4186 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4187 {
4188 keyword=(const char *) attributes[i++];
4189 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004190 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004191 CloneString(&value,attribute);
4192 switch (*keyword)
4193 {
4194 case 'C':
4195 case 'c':
4196 {
4197 if (LocaleCompare(keyword,"channel") == 0)
4198 {
4199 option=ParseChannelOption(value);
4200 if (option < 0)
4201 ThrowMSLException(OptionError,"UnrecognizedChannelType",
4202 value);
4203 channel=(ChannelType) option;
4204 break;
4205 }
4206 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4207 keyword);
4208 break;
4209 }
4210 case 'F':
4211 case 'f':
4212 {
4213 if (LocaleCompare(keyword,"fill") == 0)
4214 {
4215 (void) QueryMagickColor(value,&fill_color,&exception);
4216 break;
4217 }
4218 if (LocaleCompare(keyword,"fuzz") == 0)
4219 {
cristyc1acd842011-05-19 23:05:47 +00004220 msl_info->image[n]->fuzz=InterpretLocaleValue(value,
4221 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004222 break;
4223 }
4224 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4225 keyword);
4226 break;
4227 }
4228 default:
4229 {
4230 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4231 keyword);
4232 break;
4233 }
4234 }
4235 }
cristybd5a96c2011-08-21 00:04:26 +00004236 channel_mask=SetPixelChannelMask(msl_info->image[n],channel);
cristyd42d9952011-07-08 14:21:50 +00004237 (void) OpaquePaintImage(msl_info->image[n],&target,&fill_color,
cristy189e84c2011-08-27 18:08:53 +00004238 MagickFalse,&msl_info->image[n]->exception);
cristybd5a96c2011-08-21 00:04:26 +00004239 (void) SetPixelChannelMap(msl_info->image[n],channel_mask);
cristy3ed852e2009-09-05 21:47:34 +00004240 break;
4241 }
4242 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4243 }
4244 case 'P':
4245 case 'p':
4246 {
cristyb988fe72009-09-16 01:01:10 +00004247 if (LocaleCompare((const char *) tag,"print") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004248 {
4249 if (attributes == (const xmlChar **) NULL)
4250 break;
4251 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4252 {
4253 keyword=(const char *) attributes[i++];
4254 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004255 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004256 CloneString(&value,attribute);
4257 switch (*keyword)
4258 {
4259 case 'O':
4260 case 'o':
4261 {
4262 if (LocaleCompare(keyword,"output") == 0)
4263 {
cristyb51dff52011-05-19 16:55:47 +00004264 (void) FormatLocaleFile(stdout,"%s",value);
cristy3ed852e2009-09-05 21:47:34 +00004265 break;
4266 }
4267 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
4268 break;
4269 }
4270 default:
4271 {
4272 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
4273 break;
4274 }
4275 }
4276 }
4277 break;
4278 }
cristy4fa36e42009-09-18 14:24:06 +00004279 if (LocaleCompare((const char *) tag, "profile") == 0)
4280 {
cristy4fa36e42009-09-18 14:24:06 +00004281 if (msl_info->image[n] == (Image *) NULL)
4282 {
4283 ThrowMSLException(OptionError,"NoImagesDefined",
4284 (const char *) tag);
4285 break;
4286 }
4287 if (attributes == (const xmlChar **) NULL)
4288 break;
4289 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4290 {
4291 const char
4292 *name;
4293
4294 const StringInfo
4295 *profile;
4296
4297 Image
4298 *profile_image;
4299
4300 ImageInfo
4301 *profile_info;
4302
4303 keyword=(const char *) attributes[i++];
4304 attribute=InterpretImageProperties(msl_info->image_info[n],
4305 msl_info->attributes[n],(const char *) attributes[i]);
4306 CloneString(&value,attribute);
4307 if (*keyword == '+')
4308 {
4309 /*
4310 Remove a profile from the image.
4311 */
4312 (void) ProfileImage(msl_info->image[n],keyword,
4313 (const unsigned char *) NULL,0,MagickTrue);
4314 continue;
4315 }
4316 /*
4317 Associate a profile with the image.
4318 */
4319 profile_info=CloneImageInfo(msl_info->image_info[n]);
4320 profile=GetImageProfile(msl_info->image[n],"iptc");
4321 if (profile != (StringInfo *) NULL)
4322 profile_info->profile=(void *) CloneStringInfo(profile);
4323 profile_image=GetImageCache(profile_info,keyword,&exception);
4324 profile_info=DestroyImageInfo(profile_info);
4325 if (profile_image == (Image *) NULL)
4326 {
4327 char
4328 name[MaxTextExtent],
4329 filename[MaxTextExtent];
4330
4331 register char
4332 *p;
4333
4334 StringInfo
4335 *profile;
4336
4337 (void) CopyMagickString(filename,keyword,MaxTextExtent);
4338 (void) CopyMagickString(name,keyword,MaxTextExtent);
4339 for (p=filename; *p != '\0'; p++)
4340 if ((*p == ':') && (IsPathDirectory(keyword) < 0) &&
4341 (IsPathAccessible(keyword) == MagickFalse))
4342 {
4343 register char
4344 *q;
4345
4346 /*
4347 Look for profile name (e.g. name:profile).
4348 */
4349 (void) CopyMagickString(name,filename,(size_t)
4350 (p-filename+1));
4351 for (q=filename; *q != '\0'; q++)
4352 *q=(*++p);
4353 break;
4354 }
4355 profile=FileToStringInfo(filename,~0UL,&exception);
4356 if (profile != (StringInfo *) NULL)
4357 {
4358 (void) ProfileImage(msl_info->image[n],name,
cristybb503372010-05-27 20:51:26 +00004359 GetStringInfoDatum(profile),(size_t)
cristy4fa36e42009-09-18 14:24:06 +00004360 GetStringInfoLength(profile),MagickFalse);
4361 profile=DestroyStringInfo(profile);
4362 }
4363 continue;
4364 }
4365 ResetImageProfileIterator(profile_image);
4366 name=GetNextImageProfile(profile_image);
4367 while (name != (const char *) NULL)
4368 {
4369 profile=GetImageProfile(profile_image,name);
4370 if (profile != (StringInfo *) NULL)
4371 (void) ProfileImage(msl_info->image[n],name,
cristybb503372010-05-27 20:51:26 +00004372 GetStringInfoDatum(profile),(size_t)
cristy4fa36e42009-09-18 14:24:06 +00004373 GetStringInfoLength(profile),MagickFalse);
4374 name=GetNextImageProfile(profile_image);
4375 }
4376 profile_image=DestroyImage(profile_image);
4377 }
4378 break;
4379 }
cristy3ed852e2009-09-05 21:47:34 +00004380 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4381 }
4382 case 'Q':
4383 case 'q':
4384 {
cristyb988fe72009-09-16 01:01:10 +00004385 if (LocaleCompare((const char *) tag,"quantize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004386 {
4387 QuantizeInfo
4388 quantize_info;
4389
4390 /*
4391 Quantize image.
4392 */
4393 if (msl_info->image[n] == (Image *) NULL)
4394 {
cristyb988fe72009-09-16 01:01:10 +00004395 ThrowMSLException(OptionError,"NoImagesDefined",
4396 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004397 break;
4398 }
4399 GetQuantizeInfo(&quantize_info);
4400 if (attributes != (const xmlChar **) NULL)
4401 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4402 {
4403 keyword=(const char *) attributes[i++];
4404 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004405 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004406 CloneString(&value,attribute);
4407 switch (*keyword)
4408 {
4409 case 'C':
4410 case 'c':
4411 {
4412 if (LocaleCompare(keyword,"colors") == 0)
4413 {
cristyf2f27272009-12-17 14:48:46 +00004414 quantize_info.number_colors=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004415 break;
4416 }
4417 if (LocaleCompare(keyword,"colorspace") == 0)
4418 {
cristy042ee782011-04-22 18:48:30 +00004419 option=ParseCommandOption(MagickColorspaceOptions,
cristy3ed852e2009-09-05 21:47:34 +00004420 MagickFalse,value);
4421 if (option < 0)
4422 ThrowMSLException(OptionError,
4423 "UnrecognizedColorspaceType",value);
4424 quantize_info.colorspace=(ColorspaceType) option;
4425 break;
4426 }
4427 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4428 keyword);
4429 break;
4430 }
4431 case 'D':
4432 case 'd':
4433 {
4434 if (LocaleCompare(keyword,"dither") == 0)
4435 {
cristy042ee782011-04-22 18:48:30 +00004436 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004437 value);
4438 if (option < 0)
4439 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4440 value);
4441 quantize_info.dither=(MagickBooleanType) option;
4442 break;
4443 }
4444 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4445 keyword);
4446 break;
4447 }
4448 case 'M':
4449 case 'm':
4450 {
4451 if (LocaleCompare(keyword,"measure") == 0)
4452 {
cristy042ee782011-04-22 18:48:30 +00004453 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004454 value);
4455 if (option < 0)
4456 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4457 value);
4458 quantize_info.measure_error=(MagickBooleanType) option;
4459 break;
4460 }
4461 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4462 keyword);
4463 break;
4464 }
4465 case 'T':
4466 case 't':
4467 {
4468 if (LocaleCompare(keyword,"treedepth") == 0)
4469 {
cristyf2f27272009-12-17 14:48:46 +00004470 quantize_info.tree_depth=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004471 break;
4472 }
4473 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4474 keyword);
4475 break;
4476 }
4477 default:
4478 {
4479 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4480 keyword);
4481 break;
4482 }
4483 }
4484 }
4485 (void) QuantizeImage(&quantize_info,msl_info->image[n]);
4486 break;
4487 }
cristyb988fe72009-09-16 01:01:10 +00004488 if (LocaleCompare((const char *) tag,"query-font-metrics") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004489 {
4490 char
4491 text[MaxTextExtent];
4492
4493 MagickBooleanType
4494 status;
4495
4496 TypeMetric
4497 metrics;
4498
4499 /*
4500 Query font metrics.
4501 */
4502 draw_info=CloneDrawInfo(msl_info->image_info[n],
4503 msl_info->draw_info[n]);
4504 angle=0.0;
4505 current=draw_info->affine;
4506 GetAffineMatrix(&affine);
4507 if (attributes != (const xmlChar **) NULL)
4508 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4509 {
4510 keyword=(const char *) attributes[i++];
4511 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004512 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004513 CloneString(&value,attribute);
4514 switch (*keyword)
4515 {
4516 case 'A':
4517 case 'a':
4518 {
4519 if (LocaleCompare(keyword,"affine") == 0)
4520 {
4521 char
4522 *p;
4523
4524 p=value;
cristyc1acd842011-05-19 23:05:47 +00004525 draw_info->affine.sx=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004526 if (*p ==',')
4527 p++;
cristyc1acd842011-05-19 23:05:47 +00004528 draw_info->affine.rx=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004529 if (*p ==',')
4530 p++;
cristyc1acd842011-05-19 23:05:47 +00004531 draw_info->affine.ry=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004532 if (*p ==',')
4533 p++;
cristyc1acd842011-05-19 23:05:47 +00004534 draw_info->affine.sy=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004535 if (*p ==',')
4536 p++;
cristyc1acd842011-05-19 23:05:47 +00004537 draw_info->affine.tx=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004538 if (*p ==',')
4539 p++;
cristyc1acd842011-05-19 23:05:47 +00004540 draw_info->affine.ty=InterpretLocaleValue(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004541 break;
4542 }
4543 if (LocaleCompare(keyword,"align") == 0)
4544 {
cristy042ee782011-04-22 18:48:30 +00004545 option=ParseCommandOption(MagickAlignOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004546 value);
4547 if (option < 0)
4548 ThrowMSLException(OptionError,"UnrecognizedAlignType",
4549 value);
4550 draw_info->align=(AlignType) option;
4551 break;
4552 }
4553 if (LocaleCompare(keyword,"antialias") == 0)
4554 {
cristy042ee782011-04-22 18:48:30 +00004555 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004556 value);
4557 if (option < 0)
4558 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4559 value);
4560 draw_info->stroke_antialias=(MagickBooleanType) option;
4561 draw_info->text_antialias=(MagickBooleanType) option;
4562 break;
4563 }
4564 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4565 keyword);
4566 break;
4567 }
4568 case 'D':
4569 case 'd':
4570 {
4571 if (LocaleCompare(keyword,"density") == 0)
4572 {
4573 CloneString(&draw_info->density,value);
4574 break;
4575 }
4576 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4577 keyword);
4578 break;
4579 }
4580 case 'E':
4581 case 'e':
4582 {
4583 if (LocaleCompare(keyword,"encoding") == 0)
4584 {
4585 CloneString(&draw_info->encoding,value);
4586 break;
4587 }
4588 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4589 keyword);
4590 break;
4591 }
4592 case 'F':
4593 case 'f':
4594 {
4595 if (LocaleCompare(keyword, "fill") == 0)
4596 {
4597 (void) QueryColorDatabase(value,&draw_info->fill,
4598 &exception);
4599 break;
4600 }
4601 if (LocaleCompare(keyword,"family") == 0)
4602 {
4603 CloneString(&draw_info->family,value);
4604 break;
4605 }
4606 if (LocaleCompare(keyword,"font") == 0)
4607 {
4608 CloneString(&draw_info->font,value);
4609 break;
4610 }
4611 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4612 keyword);
4613 break;
4614 }
4615 case 'G':
4616 case 'g':
4617 {
4618 if (LocaleCompare(keyword,"geometry") == 0)
4619 {
4620 flags=ParsePageGeometry(msl_info->image[n],value,
4621 &geometry,&exception);
4622 if ((flags & HeightValue) == 0)
4623 geometry.height=geometry.width;
4624 break;
4625 }
4626 if (LocaleCompare(keyword,"gravity") == 0)
4627 {
cristy042ee782011-04-22 18:48:30 +00004628 option=ParseCommandOption(MagickGravityOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004629 value);
4630 if (option < 0)
4631 ThrowMSLException(OptionError,"UnrecognizedGravityType",
4632 value);
4633 draw_info->gravity=(GravityType) option;
4634 break;
4635 }
4636 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4637 keyword);
4638 break;
4639 }
4640 case 'P':
4641 case 'p':
4642 {
4643 if (LocaleCompare(keyword,"pointsize") == 0)
4644 {
cristyc1acd842011-05-19 23:05:47 +00004645 draw_info->pointsize=InterpretLocaleValue(value,
4646 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004647 break;
4648 }
4649 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4650 keyword);
4651 break;
4652 }
4653 case 'R':
4654 case 'r':
4655 {
4656 if (LocaleCompare(keyword,"rotate") == 0)
4657 {
cristyc1acd842011-05-19 23:05:47 +00004658 angle=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004659 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
4660 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
4661 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
4662 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
4663 break;
4664 }
4665 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4666 keyword);
4667 break;
4668 }
4669 case 'S':
4670 case 's':
4671 {
4672 if (LocaleCompare(keyword,"scale") == 0)
4673 {
4674 flags=ParseGeometry(value,&geometry_info);
4675 if ((flags & SigmaValue) == 0)
4676 geometry_info.sigma=1.0;
4677 affine.sx=geometry_info.rho;
4678 affine.sy=geometry_info.sigma;
4679 break;
4680 }
4681 if (LocaleCompare(keyword,"skewX") == 0)
4682 {
cristyc1acd842011-05-19 23:05:47 +00004683 angle=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004684 affine.ry=cos(DegreesToRadians(fmod(angle,360.0)));
4685 break;
4686 }
4687 if (LocaleCompare(keyword,"skewY") == 0)
4688 {
cristyc1acd842011-05-19 23:05:47 +00004689 angle=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004690 affine.rx=cos(DegreesToRadians(fmod(angle,360.0)));
4691 break;
4692 }
4693 if (LocaleCompare(keyword,"stretch") == 0)
4694 {
cristy042ee782011-04-22 18:48:30 +00004695 option=ParseCommandOption(MagickStretchOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004696 value);
4697 if (option < 0)
4698 ThrowMSLException(OptionError,"UnrecognizedStretchType",
4699 value);
4700 draw_info->stretch=(StretchType) option;
4701 break;
4702 }
4703 if (LocaleCompare(keyword, "stroke") == 0)
4704 {
4705 (void) QueryColorDatabase(value,&draw_info->stroke,
4706 &exception);
4707 break;
4708 }
4709 if (LocaleCompare(keyword,"strokewidth") == 0)
4710 {
cristyf2f27272009-12-17 14:48:46 +00004711 draw_info->stroke_width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004712 break;
4713 }
4714 if (LocaleCompare(keyword,"style") == 0)
4715 {
cristy042ee782011-04-22 18:48:30 +00004716 option=ParseCommandOption(MagickStyleOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004717 value);
4718 if (option < 0)
4719 ThrowMSLException(OptionError,"UnrecognizedStyleType",
4720 value);
4721 draw_info->style=(StyleType) option;
4722 break;
4723 }
4724 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4725 keyword);
4726 break;
4727 }
4728 case 'T':
4729 case 't':
4730 {
4731 if (LocaleCompare(keyword,"text") == 0)
4732 {
4733 CloneString(&draw_info->text,value);
4734 break;
4735 }
4736 if (LocaleCompare(keyword,"translate") == 0)
4737 {
4738 flags=ParseGeometry(value,&geometry_info);
4739 if ((flags & SigmaValue) == 0)
4740 geometry_info.sigma=1.0;
4741 affine.tx=geometry_info.rho;
4742 affine.ty=geometry_info.sigma;
4743 break;
4744 }
4745 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4746 keyword);
4747 break;
4748 }
4749 case 'U':
4750 case 'u':
4751 {
4752 if (LocaleCompare(keyword, "undercolor") == 0)
4753 {
4754 (void) QueryColorDatabase(value,&draw_info->undercolor,
4755 &exception);
4756 break;
4757 }
4758 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4759 keyword);
4760 break;
4761 }
4762 case 'W':
4763 case 'w':
4764 {
4765 if (LocaleCompare(keyword,"weight") == 0)
4766 {
cristyf2f27272009-12-17 14:48:46 +00004767 draw_info->weight=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004768 break;
4769 }
4770 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4771 keyword);
4772 break;
4773 }
4774 case 'X':
4775 case 'x':
4776 {
4777 if (LocaleCompare(keyword,"x") == 0)
4778 {
cristyf2f27272009-12-17 14:48:46 +00004779 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004780 break;
4781 }
4782 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4783 keyword);
4784 break;
4785 }
4786 case 'Y':
4787 case 'y':
4788 {
4789 if (LocaleCompare(keyword,"y") == 0)
4790 {
cristyf2f27272009-12-17 14:48:46 +00004791 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004792 break;
4793 }
4794 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4795 keyword);
4796 break;
4797 }
4798 default:
4799 {
4800 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4801 keyword);
4802 break;
4803 }
4804 }
4805 }
cristyb51dff52011-05-19 16:55:47 +00004806 (void) FormatLocaleString(text,MaxTextExtent,
cristye8c25f92010-06-03 00:53:06 +00004807 "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,(double)
4808 geometry.height,(double) geometry.x,(double) geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00004809 CloneString(&draw_info->geometry,text);
cristyef7c8a52010-10-10 13:46:51 +00004810 draw_info->affine.sx=affine.sx*current.sx+affine.ry*current.rx;
4811 draw_info->affine.rx=affine.rx*current.sx+affine.sy*current.rx;
4812 draw_info->affine.ry=affine.sx*current.ry+affine.ry*current.sy;
4813 draw_info->affine.sy=affine.rx*current.ry+affine.sy*current.sy;
4814 draw_info->affine.tx=affine.sx*current.tx+affine.ry*current.ty+
4815 affine.tx;
4816 draw_info->affine.ty=affine.rx*current.tx+affine.sy*current.ty+
4817 affine.ty;
cristy3ed852e2009-09-05 21:47:34 +00004818 status=GetTypeMetrics(msl_info->attributes[n],draw_info,&metrics);
4819 if (status != MagickFalse)
4820 {
4821 Image
4822 *image;
4823
4824 image=msl_info->attributes[n];
cristy8cd5b312010-01-07 01:10:24 +00004825 FormatImageProperty(image,"msl:font-metrics.pixels_per_em.x",
cristye7f51092010-01-17 00:39:37 +00004826 "%g",metrics.pixels_per_em.x);
cristy8cd5b312010-01-07 01:10:24 +00004827 FormatImageProperty(image,"msl:font-metrics.pixels_per_em.y",
cristye7f51092010-01-17 00:39:37 +00004828 "%g",metrics.pixels_per_em.y);
4829 FormatImageProperty(image,"msl:font-metrics.ascent","%g",
cristy3ed852e2009-09-05 21:47:34 +00004830 metrics.ascent);
cristye7f51092010-01-17 00:39:37 +00004831 FormatImageProperty(image,"msl:font-metrics.descent","%g",
cristy3ed852e2009-09-05 21:47:34 +00004832 metrics.descent);
cristye7f51092010-01-17 00:39:37 +00004833 FormatImageProperty(image,"msl:font-metrics.width","%g",
cristy3ed852e2009-09-05 21:47:34 +00004834 metrics.width);
cristye7f51092010-01-17 00:39:37 +00004835 FormatImageProperty(image,"msl:font-metrics.height","%g",
cristy3ed852e2009-09-05 21:47:34 +00004836 metrics.height);
cristye7f51092010-01-17 00:39:37 +00004837 FormatImageProperty(image,"msl:font-metrics.max_advance","%g",
cristy3ed852e2009-09-05 21:47:34 +00004838 metrics.max_advance);
cristye7f51092010-01-17 00:39:37 +00004839 FormatImageProperty(image,"msl:font-metrics.bounds.x1","%g",
cristy3ed852e2009-09-05 21:47:34 +00004840 metrics.bounds.x1);
cristye7f51092010-01-17 00:39:37 +00004841 FormatImageProperty(image,"msl:font-metrics.bounds.y1","%g",
cristy3ed852e2009-09-05 21:47:34 +00004842 metrics.bounds.y1);
cristye7f51092010-01-17 00:39:37 +00004843 FormatImageProperty(image,"msl:font-metrics.bounds.x2","%g",
cristy3ed852e2009-09-05 21:47:34 +00004844 metrics.bounds.x2);
cristye7f51092010-01-17 00:39:37 +00004845 FormatImageProperty(image,"msl:font-metrics.bounds.y2","%g",
cristy3ed852e2009-09-05 21:47:34 +00004846 metrics.bounds.y2);
cristye7f51092010-01-17 00:39:37 +00004847 FormatImageProperty(image,"msl:font-metrics.origin.x","%g",
cristy3ed852e2009-09-05 21:47:34 +00004848 metrics.origin.x);
cristye7f51092010-01-17 00:39:37 +00004849 FormatImageProperty(image,"msl:font-metrics.origin.y","%g",
cristy3ed852e2009-09-05 21:47:34 +00004850 metrics.origin.y);
4851 }
4852 draw_info=DestroyDrawInfo(draw_info);
4853 break;
4854 }
4855 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4856 }
4857 case 'R':
4858 case 'r':
4859 {
cristyb988fe72009-09-16 01:01:10 +00004860 if (LocaleCompare((const char *) tag,"raise") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004861 {
4862 MagickBooleanType
4863 raise;
4864
4865 /*
4866 Raise image.
4867 */
4868 if (msl_info->image[n] == (Image *) NULL)
4869 {
cristyb988fe72009-09-16 01:01:10 +00004870 ThrowMSLException(OptionError,"NoImagesDefined",
4871 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004872 break;
4873 }
4874 raise=MagickFalse;
4875 SetGeometry(msl_info->image[n],&geometry);
4876 if (attributes != (const xmlChar **) NULL)
4877 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4878 {
4879 keyword=(const char *) attributes[i++];
4880 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004881 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00004882 CloneString(&value,attribute);
4883 switch (*keyword)
4884 {
4885 case 'G':
4886 case 'g':
4887 {
4888 if (LocaleCompare(keyword,"geometry") == 0)
4889 {
4890 flags=ParsePageGeometry(msl_info->image[n],value,
4891 &geometry,&exception);
4892 if ((flags & HeightValue) == 0)
4893 geometry.height=geometry.width;
4894 break;
4895 }
4896 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4897 keyword);
4898 break;
4899 }
4900 case 'H':
4901 case 'h':
4902 {
4903 if (LocaleCompare(keyword,"height") == 0)
4904 {
cristyf2f27272009-12-17 14:48:46 +00004905 geometry.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004906 break;
4907 }
4908 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4909 keyword);
4910 break;
4911 }
4912 case 'R':
4913 case 'r':
4914 {
4915 if (LocaleCompare(keyword,"raise") == 0)
4916 {
cristy042ee782011-04-22 18:48:30 +00004917 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004918 value);
4919 if (option < 0)
4920 ThrowMSLException(OptionError,"UnrecognizedNoiseType",
4921 value);
4922 raise=(MagickBooleanType) option;
4923 break;
4924 }
4925 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4926 keyword);
4927 break;
4928 }
4929 case 'W':
4930 case 'w':
4931 {
4932 if (LocaleCompare(keyword,"width") == 0)
4933 {
cristyf2f27272009-12-17 14:48:46 +00004934 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004935 break;
4936 }
4937 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4938 keyword);
4939 break;
4940 }
4941 default:
4942 {
4943 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4944 keyword);
4945 break;
4946 }
4947 }
4948 }
4949 (void) RaiseImage(msl_info->image[n],&geometry,raise);
4950 break;
4951 }
cristyb988fe72009-09-16 01:01:10 +00004952 if (LocaleCompare((const char *) tag,"read") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004953 {
4954 if (attributes == (const xmlChar **) NULL)
4955 break;
4956 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4957 {
4958 keyword=(const char *) attributes[i++];
4959 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00004960 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00004961 switch (*keyword)
4962 {
4963 case 'F':
4964 case 'f':
4965 {
4966 if (LocaleCompare(keyword,"filename") == 0)
4967 {
4968 Image
4969 *image;
4970
4971 (void) CopyMagickString(msl_info->image_info[n]->filename,
4972 value,MaxTextExtent);
4973 image=ReadImage(msl_info->image_info[n],&exception);
4974 CatchException(&exception);
4975 if (image == (Image *) NULL)
4976 continue;
4977 AppendImageToList(&msl_info->image[n],image);
4978 break;
4979 }
cristy4582cbb2009-09-23 00:35:43 +00004980 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00004981 break;
4982 }
4983 default:
4984 {
cristy4582cbb2009-09-23 00:35:43 +00004985 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00004986 break;
4987 }
4988 }
4989 }
4990 break;
4991 }
cristyb988fe72009-09-16 01:01:10 +00004992 if (LocaleCompare((const char *) tag,"reduce-noise") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004993 {
4994 Image
4995 *paint_image;
4996
4997 /*
4998 Reduce-noise image.
4999 */
5000 if (msl_info->image[n] == (Image *) NULL)
5001 {
cristyb988fe72009-09-16 01:01:10 +00005002 ThrowMSLException(OptionError,"NoImagesDefined",
5003 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005004 break;
5005 }
5006 if (attributes != (const xmlChar **) NULL)
5007 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5008 {
5009 keyword=(const char *) attributes[i++];
5010 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005011 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00005012 CloneString(&value,attribute);
5013 switch (*keyword)
5014 {
5015 case 'G':
5016 case 'g':
5017 {
5018 if (LocaleCompare(keyword,"geometry") == 0)
5019 {
5020 flags=ParseGeometry(value,&geometry_info);
5021 if ((flags & SigmaValue) == 0)
5022 geometry_info.sigma=1.0;
5023 break;
5024 }
5025 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5026 keyword);
5027 break;
5028 }
5029 case 'R':
5030 case 'r':
5031 {
5032 if (LocaleCompare(keyword,"radius") == 0)
5033 {
cristyc1acd842011-05-19 23:05:47 +00005034 geometry_info.rho=InterpretLocaleValue(value,
5035 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005036 break;
5037 }
5038 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5039 keyword);
5040 break;
5041 }
5042 default:
5043 {
5044 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5045 keyword);
5046 break;
5047 }
5048 }
5049 }
cristy733678d2011-03-18 21:29:28 +00005050 paint_image=StatisticImage(msl_info->image[n],NonpeakStatistic,
cristy95c38342011-03-18 22:39:51 +00005051 (size_t) geometry_info.rho,(size_t) geometry_info.sigma,
5052 &msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00005053 if (paint_image == (Image *) NULL)
5054 break;
5055 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5056 msl_info->image[n]=paint_image;
5057 break;
5058 }
cristyb988fe72009-09-16 01:01:10 +00005059 else if (LocaleCompare((const char *) tag,"repage") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005060 {
5061 /* init the values */
5062 width=msl_info->image[n]->page.width;
5063 height=msl_info->image[n]->page.height;
5064 x=msl_info->image[n]->page.x;
5065 y=msl_info->image[n]->page.y;
5066
5067 if (msl_info->image[n] == (Image *) NULL)
5068 {
cristyb988fe72009-09-16 01:01:10 +00005069 ThrowMSLException(OptionError,"NoImagesDefined",
5070 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005071 break;
5072 }
5073 if (attributes == (const xmlChar **) NULL)
5074 break;
5075 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5076 {
5077 keyword=(const char *) attributes[i++];
5078 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005079 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00005080 switch (*keyword)
5081 {
5082 case 'G':
5083 case 'g':
5084 {
5085 if (LocaleCompare(keyword,"geometry") == 0)
5086 {
5087 int
5088 flags;
5089
5090 RectangleInfo
5091 geometry;
5092
5093 flags=ParseAbsoluteGeometry(value,&geometry);
5094 if ((flags & WidthValue) != 0)
5095 {
5096 if ((flags & HeightValue) == 0)
5097 geometry.height=geometry.width;
5098 width=geometry.width;
5099 height=geometry.height;
5100 }
5101 if ((flags & AspectValue) != 0)
5102 {
5103 if ((flags & XValue) != 0)
5104 x+=geometry.x;
5105 if ((flags & YValue) != 0)
5106 y+=geometry.y;
5107 }
5108 else
5109 {
5110 if ((flags & XValue) != 0)
5111 {
5112 x=geometry.x;
5113 if ((width == 0) && (geometry.x > 0))
5114 width=msl_info->image[n]->columns+geometry.x;
5115 }
5116 if ((flags & YValue) != 0)
5117 {
5118 y=geometry.y;
5119 if ((height == 0) && (geometry.y > 0))
5120 height=msl_info->image[n]->rows+geometry.y;
5121 }
5122 }
5123 break;
5124 }
5125 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5126 break;
5127 }
5128 case 'H':
5129 case 'h':
5130 {
5131 if (LocaleCompare(keyword,"height") == 0)
5132 {
cristyf2f27272009-12-17 14:48:46 +00005133 height = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005134 break;
5135 }
5136 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5137 break;
5138 }
5139 case 'W':
5140 case 'w':
5141 {
5142 if (LocaleCompare(keyword,"width") == 0)
5143 {
cristyf2f27272009-12-17 14:48:46 +00005144 width = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005145 break;
5146 }
5147 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5148 break;
5149 }
5150 case 'X':
5151 case 'x':
5152 {
5153 if (LocaleCompare(keyword,"x") == 0)
5154 {
cristyf2f27272009-12-17 14:48:46 +00005155 x = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005156 break;
5157 }
5158 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5159 break;
5160 }
5161 case 'Y':
5162 case 'y':
5163 {
5164 if (LocaleCompare(keyword,"y") == 0)
5165 {
cristyf2f27272009-12-17 14:48:46 +00005166 y = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005167 break;
5168 }
5169 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5170 break;
5171 }
5172 default:
5173 {
5174 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5175 break;
5176 }
5177 }
5178 }
5179
cristyb988fe72009-09-16 01:01:10 +00005180 msl_info->image[n]->page.width=width;
5181 msl_info->image[n]->page.height=height;
5182 msl_info->image[n]->page.x=x;
5183 msl_info->image[n]->page.y=y;
cristy3ed852e2009-09-05 21:47:34 +00005184 break;
5185 }
cristyb988fe72009-09-16 01:01:10 +00005186 else if (LocaleCompare((const char *) tag,"resample") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005187 {
5188 double
5189 x_resolution,
5190 y_resolution;
5191
5192 if (msl_info->image[n] == (Image *) NULL)
5193 {
cristyb988fe72009-09-16 01:01:10 +00005194 ThrowMSLException(OptionError,"NoImagesDefined",
5195 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005196 break;
5197 }
5198 if (attributes == (const xmlChar **) NULL)
5199 break;
5200 x_resolution=DefaultResolution;
5201 y_resolution=DefaultResolution;
5202 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5203 {
5204 keyword=(const char *) attributes[i++];
5205 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005206 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00005207 switch (*keyword)
5208 {
5209 case 'b':
5210 {
5211 if (LocaleCompare(keyword,"blur") == 0)
5212 {
cristyc1acd842011-05-19 23:05:47 +00005213 msl_info->image[n]->blur=InterpretLocaleValue(value,
5214 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005215 break;
5216 }
5217 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5218 break;
5219 }
5220 case 'G':
5221 case 'g':
5222 {
5223 if (LocaleCompare(keyword,"geometry") == 0)
5224 {
cristybb503372010-05-27 20:51:26 +00005225 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00005226 flags;
5227
5228 flags=ParseGeometry(value,&geometry_info);
5229 if ((flags & SigmaValue) == 0)
5230 geometry_info.sigma*=geometry_info.rho;
5231 x_resolution=geometry_info.rho;
5232 y_resolution=geometry_info.sigma;
5233 break;
5234 }
5235 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5236 break;
5237 }
5238 case 'X':
5239 case 'x':
5240 {
5241 if (LocaleCompare(keyword,"x-resolution") == 0)
5242 {
cristyc1acd842011-05-19 23:05:47 +00005243 x_resolution=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005244 break;
5245 }
5246 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5247 break;
5248 }
5249 case 'Y':
5250 case 'y':
5251 {
5252 if (LocaleCompare(keyword,"y-resolution") == 0)
5253 {
cristyc1acd842011-05-19 23:05:47 +00005254 y_resolution=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005255 break;
5256 }
5257 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5258 break;
5259 }
5260 default:
5261 {
5262 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5263 break;
5264 }
5265 }
5266 }
5267 /*
5268 Resample image.
5269 */
5270 {
5271 double
5272 factor;
5273
5274 Image
5275 *resample_image;
5276
5277 factor=1.0;
5278 if (msl_info->image[n]->units == PixelsPerCentimeterResolution)
5279 factor=2.54;
cristybb503372010-05-27 20:51:26 +00005280 width=(size_t) (x_resolution*msl_info->image[n]->columns/
cristy3ed852e2009-09-05 21:47:34 +00005281 (factor*(msl_info->image[n]->x_resolution == 0.0 ? DefaultResolution :
5282 msl_info->image[n]->x_resolution))+0.5);
cristybb503372010-05-27 20:51:26 +00005283 height=(size_t) (y_resolution*msl_info->image[n]->rows/
cristy3ed852e2009-09-05 21:47:34 +00005284 (factor*(msl_info->image[n]->y_resolution == 0.0 ? DefaultResolution :
5285 msl_info->image[n]->y_resolution))+0.5);
5286 resample_image=ResizeImage(msl_info->image[n],width,height,
5287 msl_info->image[n]->filter,msl_info->image[n]->blur,
5288 &msl_info->image[n]->exception);
5289 if (resample_image == (Image *) NULL)
5290 break;
5291 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5292 msl_info->image[n]=resample_image;
5293 }
5294 break;
5295 }
cristyb988fe72009-09-16 01:01:10 +00005296 if (LocaleCompare((const char *) tag,"resize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005297 {
5298 double
5299 blur;
5300
5301 FilterTypes
5302 filter;
5303
5304 Image
5305 *resize_image;
5306
5307 /*
5308 Resize image.
5309 */
5310 if (msl_info->image[n] == (Image *) NULL)
5311 {
cristyb988fe72009-09-16 01:01:10 +00005312 ThrowMSLException(OptionError,"NoImagesDefined",
5313 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005314 break;
5315 }
5316 filter=UndefinedFilter;
5317 blur=1.0;
5318 if (attributes != (const xmlChar **) NULL)
5319 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5320 {
5321 keyword=(const char *) attributes[i++];
5322 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005323 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00005324 CloneString(&value,attribute);
5325 switch (*keyword)
5326 {
5327 case 'F':
5328 case 'f':
5329 {
5330 if (LocaleCompare(keyword,"filter") == 0)
5331 {
cristy042ee782011-04-22 18:48:30 +00005332 option=ParseCommandOption(MagickFilterOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00005333 value);
5334 if (option < 0)
5335 ThrowMSLException(OptionError,"UnrecognizedNoiseType",
5336 value);
5337 filter=(FilterTypes) option;
5338 break;
5339 }
5340 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5341 keyword);
5342 break;
5343 }
5344 case 'G':
5345 case 'g':
5346 {
5347 if (LocaleCompare(keyword,"geometry") == 0)
5348 {
5349 flags=ParseRegionGeometry(msl_info->image[n],value,
5350 &geometry,&exception);
5351 break;
5352 }
5353 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5354 keyword);
5355 break;
5356 }
5357 case 'H':
5358 case 'h':
5359 {
5360 if (LocaleCompare(keyword,"height") == 0)
5361 {
cristye27293e2009-12-18 02:53:20 +00005362 geometry.height=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005363 break;
5364 }
5365 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5366 keyword);
5367 break;
5368 }
5369 case 'S':
5370 case 's':
5371 {
5372 if (LocaleCompare(keyword,"support") == 0)
5373 {
cristyc1acd842011-05-19 23:05:47 +00005374 blur=InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005375 break;
5376 }
5377 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5378 keyword);
5379 break;
5380 }
5381 case 'W':
5382 case 'w':
5383 {
5384 if (LocaleCompare(keyword,"width") == 0)
5385 {
cristyf2f27272009-12-17 14:48:46 +00005386 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005387 break;
5388 }
5389 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5390 keyword);
5391 break;
5392 }
5393 default:
5394 {
5395 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5396 keyword);
5397 break;
5398 }
5399 }
5400 }
5401 resize_image=ResizeImage(msl_info->image[n],geometry.width,
5402 geometry.height,filter,blur,&msl_info->image[n]->exception);
5403 if (resize_image == (Image *) NULL)
5404 break;
5405 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5406 msl_info->image[n]=resize_image;
5407 break;
5408 }
cristyb988fe72009-09-16 01:01:10 +00005409 if (LocaleCompare((const char *) tag,"roll") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005410 {
5411 Image
5412 *roll_image;
5413
5414 /*
5415 Roll image.
5416 */
5417 if (msl_info->image[n] == (Image *) NULL)
5418 {
cristyb988fe72009-09-16 01:01:10 +00005419 ThrowMSLException(OptionError,"NoImagesDefined",
5420 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005421 break;
5422 }
5423 SetGeometry(msl_info->image[n],&geometry);
5424 if (attributes != (const xmlChar **) NULL)
5425 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5426 {
5427 keyword=(const char *) attributes[i++];
5428 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005429 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00005430 CloneString(&value,attribute);
5431 switch (*keyword)
5432 {
5433 case 'G':
5434 case 'g':
5435 {
5436 if (LocaleCompare(keyword,"geometry") == 0)
5437 {
5438 flags=ParsePageGeometry(msl_info->image[n],value,
5439 &geometry,&exception);
5440 if ((flags & HeightValue) == 0)
5441 geometry.height=geometry.width;
5442 break;
5443 }
5444 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5445 keyword);
5446 break;
5447 }
5448 case 'X':
5449 case 'x':
5450 {
5451 if (LocaleCompare(keyword,"x") == 0)
5452 {
cristyf2f27272009-12-17 14:48:46 +00005453 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005454 break;
5455 }
5456 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5457 keyword);
5458 break;
5459 }
5460 case 'Y':
5461 case 'y':
5462 {
5463 if (LocaleCompare(keyword,"y") == 0)
5464 {
cristyf2f27272009-12-17 14:48:46 +00005465 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005466 break;
5467 }
5468 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5469 keyword);
5470 break;
5471 }
5472 default:
5473 {
5474 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5475 keyword);
5476 break;
5477 }
5478 }
5479 }
5480 roll_image=RollImage(msl_info->image[n],geometry.x,geometry.y,
5481 &msl_info->image[n]->exception);
5482 if (roll_image == (Image *) NULL)
5483 break;
5484 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5485 msl_info->image[n]=roll_image;
5486 break;
5487 }
cristyb988fe72009-09-16 01:01:10 +00005488 else if (LocaleCompare((const char *) tag,"roll") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005489 {
5490 /* init the values */
5491 width=msl_info->image[n]->columns;
5492 height=msl_info->image[n]->rows;
5493 x = y = 0;
5494
5495 if (msl_info->image[n] == (Image *) NULL)
5496 {
cristyb988fe72009-09-16 01:01:10 +00005497 ThrowMSLException(OptionError,"NoImagesDefined",
5498 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005499 break;
5500 }
5501 if (attributes == (const xmlChar **) NULL)
5502 break;
5503 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5504 {
5505 keyword=(const char *) attributes[i++];
5506 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005507 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00005508 switch (*keyword)
5509 {
5510 case 'G':
5511 case 'g':
5512 {
5513 if (LocaleCompare(keyword,"geometry") == 0)
5514 {
5515 (void) ParseMetaGeometry(value,&x,&y,&width,&height);
5516 break;
5517 }
5518 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5519 break;
5520 }
5521 case 'X':
5522 case 'x':
5523 {
5524 if (LocaleCompare(keyword,"x") == 0)
5525 {
cristyf2f27272009-12-17 14:48:46 +00005526 x = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005527 break;
5528 }
5529 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5530 break;
5531 }
5532 case 'Y':
5533 case 'y':
5534 {
5535 if (LocaleCompare(keyword,"y") == 0)
5536 {
cristyf2f27272009-12-17 14:48:46 +00005537 y = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005538 break;
5539 }
5540 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5541 break;
5542 }
5543 default:
5544 {
5545 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5546 break;
5547 }
5548 }
5549 }
5550
5551 /*
5552 process image.
5553 */
5554 {
5555 Image
5556 *newImage;
5557
5558 newImage=RollImage(msl_info->image[n], x, y, &msl_info->image[n]->exception);
5559 if (newImage == (Image *) NULL)
5560 break;
5561 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5562 msl_info->image[n]=newImage;
5563 }
5564
5565 break;
5566 }
cristyb988fe72009-09-16 01:01:10 +00005567 if (LocaleCompare((const char *) tag,"rotate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005568 {
5569 Image
5570 *rotate_image;
5571
5572 /*
5573 Rotate image.
5574 */
5575 if (msl_info->image[n] == (Image *) NULL)
5576 {
cristyb988fe72009-09-16 01:01:10 +00005577 ThrowMSLException(OptionError,"NoImagesDefined",
5578 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005579 break;
5580 }
5581 if (attributes != (const xmlChar **) NULL)
5582 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5583 {
5584 keyword=(const char *) attributes[i++];
5585 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005586 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00005587 CloneString(&value,attribute);
5588 switch (*keyword)
5589 {
5590 case 'D':
5591 case 'd':
5592 {
5593 if (LocaleCompare(keyword,"degrees") == 0)
5594 {
cristyc1acd842011-05-19 23:05:47 +00005595 geometry_info.rho=InterpretLocaleValue(value,
5596 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005597 break;
5598 }
5599 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5600 keyword);
5601 break;
5602 }
5603 case 'G':
5604 case 'g':
5605 {
5606 if (LocaleCompare(keyword,"geometry") == 0)
5607 {
5608 flags=ParseGeometry(value,&geometry_info);
5609 if ((flags & SigmaValue) == 0)
5610 geometry_info.sigma=1.0;
5611 break;
5612 }
5613 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5614 keyword);
5615 break;
5616 }
5617 default:
5618 {
5619 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5620 keyword);
5621 break;
5622 }
5623 }
5624 }
5625 rotate_image=RotateImage(msl_info->image[n],geometry_info.rho,
5626 &msl_info->image[n]->exception);
5627 if (rotate_image == (Image *) NULL)
5628 break;
5629 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5630 msl_info->image[n]=rotate_image;
5631 break;
5632 }
cristyb988fe72009-09-16 01:01:10 +00005633 else if (LocaleCompare((const char *) tag,"rotate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005634 {
5635 /* init the values */
5636 double degrees = 0;
5637
5638 if (msl_info->image[n] == (Image *) NULL)
5639 {
cristyb988fe72009-09-16 01:01:10 +00005640 ThrowMSLException(OptionError,"NoImagesDefined",
5641 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005642 break;
5643 }
5644 if (attributes == (const xmlChar **) NULL)
cristy31939262009-09-15 00:23:11 +00005645 break;
cristy3ed852e2009-09-05 21:47:34 +00005646 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5647 {
5648 keyword=(const char *) attributes[i++];
5649 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005650 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00005651 switch (*keyword)
5652 {
5653 case 'D':
5654 case 'd':
5655 {
5656 if (LocaleCompare(keyword,"degrees") == 0)
5657 {
cristyc1acd842011-05-19 23:05:47 +00005658 degrees = InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005659 break;
5660 }
5661 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5662 break;
5663 }
5664 default:
5665 {
5666 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5667 break;
5668 }
5669 }
5670 }
5671
5672 /*
5673 process image.
5674 */
5675 {
5676 Image
5677 *newImage;
5678
5679 newImage=RotateImage(msl_info->image[n], degrees, &msl_info->image[n]->exception);
5680 if (newImage == (Image *) NULL)
5681 break;
5682 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5683 msl_info->image[n]=newImage;
5684 }
5685
5686 break;
5687 }
5688 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
5689 }
5690 case 'S':
5691 case 's':
5692 {
cristyb988fe72009-09-16 01:01:10 +00005693 if (LocaleCompare((const char *) tag,"sample") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005694 {
5695 Image
5696 *sample_image;
5697
5698 /*
5699 Sample image.
5700 */
5701 if (msl_info->image[n] == (Image *) NULL)
5702 {
cristyb988fe72009-09-16 01:01:10 +00005703 ThrowMSLException(OptionError,"NoImagesDefined",
5704 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005705 break;
5706 }
5707 if (attributes != (const xmlChar **) NULL)
5708 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5709 {
5710 keyword=(const char *) attributes[i++];
5711 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005712 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00005713 CloneString(&value,attribute);
5714 switch (*keyword)
5715 {
5716 case 'G':
5717 case 'g':
5718 {
5719 if (LocaleCompare(keyword,"geometry") == 0)
5720 {
5721 flags=ParseRegionGeometry(msl_info->image[n],value,
5722 &geometry,&exception);
5723 break;
5724 }
5725 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5726 keyword);
5727 break;
5728 }
5729 case 'H':
5730 case 'h':
5731 {
5732 if (LocaleCompare(keyword,"height") == 0)
5733 {
cristye27293e2009-12-18 02:53:20 +00005734 geometry.height=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005735 break;
5736 }
5737 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5738 keyword);
5739 break;
5740 }
5741 case 'W':
5742 case 'w':
5743 {
5744 if (LocaleCompare(keyword,"width") == 0)
5745 {
cristyf2f27272009-12-17 14:48:46 +00005746 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005747 break;
5748 }
5749 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5750 keyword);
5751 break;
5752 }
5753 default:
5754 {
5755 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5756 keyword);
5757 break;
5758 }
5759 }
5760 }
5761 sample_image=SampleImage(msl_info->image[n],geometry.width,
5762 geometry.height,&msl_info->image[n]->exception);
5763 if (sample_image == (Image *) NULL)
5764 break;
5765 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5766 msl_info->image[n]=sample_image;
5767 break;
5768 }
cristyb988fe72009-09-16 01:01:10 +00005769 if (LocaleCompare((const char *) tag,"scale") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005770 {
5771 Image
5772 *scale_image;
5773
5774 /*
5775 Scale image.
5776 */
5777 if (msl_info->image[n] == (Image *) NULL)
5778 {
cristyb988fe72009-09-16 01:01:10 +00005779 ThrowMSLException(OptionError,"NoImagesDefined",
5780 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005781 break;
5782 }
5783 if (attributes != (const xmlChar **) NULL)
5784 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5785 {
5786 keyword=(const char *) attributes[i++];
5787 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005788 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00005789 CloneString(&value,attribute);
5790 switch (*keyword)
5791 {
5792 case 'G':
5793 case 'g':
5794 {
5795 if (LocaleCompare(keyword,"geometry") == 0)
5796 {
5797 flags=ParseRegionGeometry(msl_info->image[n],value,
5798 &geometry,&exception);
5799 break;
5800 }
5801 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5802 keyword);
5803 break;
5804 }
5805 case 'H':
5806 case 'h':
5807 {
5808 if (LocaleCompare(keyword,"height") == 0)
5809 {
cristye27293e2009-12-18 02:53:20 +00005810 geometry.height=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005811 break;
5812 }
5813 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5814 keyword);
5815 break;
5816 }
5817 case 'W':
5818 case 'w':
5819 {
5820 if (LocaleCompare(keyword,"width") == 0)
5821 {
cristyf2f27272009-12-17 14:48:46 +00005822 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005823 break;
5824 }
5825 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5826 keyword);
5827 break;
5828 }
5829 default:
5830 {
5831 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5832 keyword);
5833 break;
5834 }
5835 }
5836 }
5837 scale_image=ScaleImage(msl_info->image[n],geometry.width,
5838 geometry.height,&msl_info->image[n]->exception);
5839 if (scale_image == (Image *) NULL)
5840 break;
5841 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5842 msl_info->image[n]=scale_image;
5843 break;
5844 }
cristyb988fe72009-09-16 01:01:10 +00005845 if (LocaleCompare((const char *) tag,"segment") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005846 {
5847 ColorspaceType
5848 colorspace;
5849
5850 MagickBooleanType
5851 verbose;
cristyb988fe72009-09-16 01:01:10 +00005852
cristy3ed852e2009-09-05 21:47:34 +00005853 /*
5854 Segment image.
5855 */
5856 if (msl_info->image[n] == (Image *) NULL)
5857 {
cristyb988fe72009-09-16 01:01:10 +00005858 ThrowMSLException(OptionError,"NoImagesDefined",
5859 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005860 break;
5861 }
5862 geometry_info.rho=1.0;
5863 geometry_info.sigma=1.5;
5864 colorspace=RGBColorspace;
5865 verbose=MagickFalse;
5866 if (attributes != (const xmlChar **) NULL)
5867 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5868 {
5869 keyword=(const char *) attributes[i++];
5870 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005871 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00005872 CloneString(&value,attribute);
5873 switch (*keyword)
5874 {
5875 case 'C':
5876 case 'c':
5877 {
5878 if (LocaleCompare(keyword,"cluster-threshold") == 0)
5879 {
cristyc1acd842011-05-19 23:05:47 +00005880 geometry_info.rho=InterpretLocaleValue(value,
5881 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005882 break;
5883 }
5884 if (LocaleCompare(keyword,"colorspace") == 0)
5885 {
cristy042ee782011-04-22 18:48:30 +00005886 option=ParseCommandOption(MagickColorspaceOptions,
cristy3ed852e2009-09-05 21:47:34 +00005887 MagickFalse,value);
5888 if (option < 0)
5889 ThrowMSLException(OptionError,
5890 "UnrecognizedColorspaceType",value);
5891 colorspace=(ColorspaceType) option;
5892 break;
5893 }
5894 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5895 keyword);
5896 break;
5897 }
5898 case 'G':
5899 case 'g':
5900 {
5901 if (LocaleCompare(keyword,"geometry") == 0)
5902 {
5903 flags=ParseGeometry(value,&geometry_info);
5904 if ((flags & SigmaValue) == 0)
5905 geometry_info.sigma=1.5;
5906 break;
5907 }
5908 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5909 keyword);
5910 break;
5911 }
5912 case 'S':
5913 case 's':
5914 {
5915 if (LocaleCompare(keyword,"smoothing-threshold") == 0)
5916 {
cristyc1acd842011-05-19 23:05:47 +00005917 geometry_info.sigma=InterpretLocaleValue(value,
5918 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005919 break;
5920 }
5921 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5922 keyword);
5923 break;
5924 }
5925 default:
5926 {
5927 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5928 keyword);
5929 break;
5930 }
5931 }
5932 }
5933 (void) SegmentImage(msl_info->image[n],colorspace,verbose,
5934 geometry_info.rho,geometry_info.sigma);
5935 break;
5936 }
cristyb988fe72009-09-16 01:01:10 +00005937 else if (LocaleCompare((const char *) tag, "set") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005938 {
5939 if (msl_info->image[n] == (Image *) NULL)
5940 {
cristy0b6d0052011-07-27 23:54:16 +00005941 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005942 break;
5943 }
5944
5945 if (attributes == (const xmlChar **) NULL)
5946 break;
5947 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5948 {
5949 keyword=(const char *) attributes[i++];
5950 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00005951 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00005952 switch (*keyword)
5953 {
cristy3ed852e2009-09-05 21:47:34 +00005954 case 'C':
5955 case 'c':
5956 {
5957 if (LocaleCompare(keyword,"clip-mask") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005958 {
cristy2c8b6312009-09-16 02:37:23 +00005959 for (j=0; j < msl_info->n; j++)
cristy3ed852e2009-09-05 21:47:34 +00005960 {
cristy2c8b6312009-09-16 02:37:23 +00005961 const char
5962 *property;
5963
5964 property=GetImageProperty(msl_info->attributes[j],"id");
5965 if (LocaleCompare(property,value) == 0)
5966 {
5967 SetImageMask(msl_info->image[n],msl_info->image[j]);
5968 break;
5969 }
cristy3ed852e2009-09-05 21:47:34 +00005970 }
cristy2c8b6312009-09-16 02:37:23 +00005971 break;
cristy3ed852e2009-09-05 21:47:34 +00005972 }
cristy3ed852e2009-09-05 21:47:34 +00005973 if (LocaleCompare(keyword,"clip-path") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005974 {
cristy2c8b6312009-09-16 02:37:23 +00005975 for (j=0; j < msl_info->n; j++)
cristy3ed852e2009-09-05 21:47:34 +00005976 {
cristy2c8b6312009-09-16 02:37:23 +00005977 const char
5978 *property;
5979
5980 property=GetImageProperty(msl_info->attributes[j],"id");
5981 if (LocaleCompare(property,value) == 0)
5982 {
5983 SetImageClipMask(msl_info->image[n],msl_info->image[j]);
5984 break;
5985 }
cristy3ed852e2009-09-05 21:47:34 +00005986 }
cristy2c8b6312009-09-16 02:37:23 +00005987 break;
cristy3ed852e2009-09-05 21:47:34 +00005988 }
cristy2c8b6312009-09-16 02:37:23 +00005989 if (LocaleCompare(keyword,"colorspace") == 0)
5990 {
cristybb503372010-05-27 20:51:26 +00005991 ssize_t
cristy2c8b6312009-09-16 02:37:23 +00005992 colorspace;
5993
cristy042ee782011-04-22 18:48:30 +00005994 colorspace=(ColorspaceType) ParseCommandOption(
cristy7e9e6fa2010-11-21 17:06:24 +00005995 MagickColorspaceOptions,MagickFalse,value);
cristy2c8b6312009-09-16 02:37:23 +00005996 if (colorspace < 0)
cristyfb758a52009-09-16 14:36:08 +00005997 ThrowMSLException(OptionError,"UnrecognizedColorspace",
cristy2c8b6312009-09-16 02:37:23 +00005998 value);
5999 (void) TransformImageColorspace(msl_info->image[n],
6000 (ColorspaceType) colorspace);
6001 break;
6002 }
6003 (void) SetMSLAttributes(msl_info,keyword,value);
cristy0b6d0052011-07-27 23:54:16 +00006004 (void) SetImageProperty(msl_info->image[n],keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00006005 break;
6006 }
6007 case 'D':
6008 case 'd':
6009 {
cristy2c8b6312009-09-16 02:37:23 +00006010 if (LocaleCompare(keyword,"density") == 0)
6011 {
6012 flags=ParseGeometry(value,&geometry_info);
6013 msl_info->image[n]->x_resolution=geometry_info.rho;
6014 msl_info->image[n]->y_resolution=geometry_info.sigma;
6015 if ((flags & SigmaValue) == 0)
6016 msl_info->image[n]->y_resolution=
6017 msl_info->image[n]->x_resolution;
6018 break;
6019 }
6020 (void) SetMSLAttributes(msl_info,keyword,value);
cristy0b6d0052011-07-27 23:54:16 +00006021 (void) SetImageProperty(msl_info->image[n],keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00006022 break;
6023 }
6024 case 'O':
6025 case 'o':
6026 {
6027 if (LocaleCompare(keyword, "opacity") == 0)
cristy2c8b6312009-09-16 02:37:23 +00006028 {
cristy4c08aed2011-07-01 19:47:50 +00006029 ssize_t opac = OpaqueAlpha,
cristybb503372010-05-27 20:51:26 +00006030 len = (ssize_t) strlen( value );
cristy3ed852e2009-09-05 21:47:34 +00006031
cristy2c8b6312009-09-16 02:37:23 +00006032 if (value[len-1] == '%') {
6033 char tmp[100];
6034 (void) CopyMagickString(tmp,value,len);
cristyf2f27272009-12-17 14:48:46 +00006035 opac = StringToLong( tmp );
cristy2c8b6312009-09-16 02:37:23 +00006036 opac = (int)(QuantumRange * ((float)opac/100));
6037 } else
cristyf2f27272009-12-17 14:48:46 +00006038 opac = StringToLong( value );
cristy2c8b6312009-09-16 02:37:23 +00006039 (void) SetImageOpacity( msl_info->image[n], (Quantum) opac );
6040 break;
cristy3ed852e2009-09-05 21:47:34 +00006041 }
cristy2c8b6312009-09-16 02:37:23 +00006042 (void) SetMSLAttributes(msl_info,keyword,value);
cristy0b6d0052011-07-27 23:54:16 +00006043 (void) SetImageProperty(msl_info->image[n],keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00006044 break;
6045 }
6046 case 'P':
6047 case 'p':
6048 {
6049 if (LocaleCompare(keyword, "page") == 0)
6050 {
6051 char
6052 page[MaxTextExtent];
6053
6054 const char
6055 *image_option;
6056
6057 MagickStatusType
6058 flags;
6059
6060 RectangleInfo
6061 geometry;
6062
6063 (void) ResetMagickMemory(&geometry,0,sizeof(geometry));
6064 image_option=GetImageOption(msl_info->image_info[n],"page");
6065 if (image_option != (const char *) NULL)
6066 flags=ParseAbsoluteGeometry(image_option,&geometry);
6067 flags=ParseAbsoluteGeometry(value,&geometry);
cristyb51dff52011-05-19 16:55:47 +00006068 (void) FormatLocaleString(page,MaxTextExtent,"%.20gx%.20g",
cristye8c25f92010-06-03 00:53:06 +00006069 (double) geometry.width,(double) geometry.height);
cristy3ed852e2009-09-05 21:47:34 +00006070 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
cristyb51dff52011-05-19 16:55:47 +00006071 (void) FormatLocaleString(page,MaxTextExtent,
cristye8c25f92010-06-03 00:53:06 +00006072 "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,
6073 (double) geometry.height,(double) geometry.x,(double)
cristyf2faecf2010-05-28 19:19:36 +00006074 geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00006075 (void) SetImageOption(msl_info->image_info[n],keyword,page);
6076 msl_info->image_info[n]->page=GetPageGeometry(page);
6077 break;
6078 }
cristy2c8b6312009-09-16 02:37:23 +00006079 (void) SetMSLAttributes(msl_info,keyword,value);
cristy0b6d0052011-07-27 23:54:16 +00006080 (void) SetImageProperty(msl_info->image[n],keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00006081 break;
6082 }
6083 default:
6084 {
cristy2c8b6312009-09-16 02:37:23 +00006085 (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 }
6090 }
6091 break;
6092 }
cristyb988fe72009-09-16 01:01:10 +00006093 if (LocaleCompare((const char *) tag,"shade") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006094 {
6095 Image
6096 *shade_image;
6097
6098 MagickBooleanType
6099 gray;
6100
6101 /*
6102 Shade image.
6103 */
6104 if (msl_info->image[n] == (Image *) NULL)
6105 {
cristyb988fe72009-09-16 01:01:10 +00006106 ThrowMSLException(OptionError,"NoImagesDefined",
6107 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006108 break;
6109 }
6110 gray=MagickFalse;
6111 if (attributes != (const xmlChar **) NULL)
6112 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6113 {
6114 keyword=(const char *) attributes[i++];
6115 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006116 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006117 CloneString(&value,attribute);
6118 switch (*keyword)
6119 {
6120 case 'A':
6121 case 'a':
6122 {
6123 if (LocaleCompare(keyword,"azimuth") == 0)
6124 {
cristyc1acd842011-05-19 23:05:47 +00006125 geometry_info.rho=InterpretLocaleValue(value,
6126 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006127 break;
6128 }
6129 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6130 keyword);
6131 break;
6132 }
6133 case 'E':
6134 case 'e':
6135 {
6136 if (LocaleCompare(keyword,"elevation") == 0)
6137 {
cristyc1acd842011-05-19 23:05:47 +00006138 geometry_info.sigma=InterpretLocaleValue(value,
6139 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006140 break;
6141 }
6142 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6143 keyword);
6144 break;
6145 }
6146 case 'G':
6147 case 'g':
6148 {
6149 if (LocaleCompare(keyword,"geometry") == 0)
6150 {
6151 flags=ParseGeometry(value,&geometry_info);
6152 if ((flags & SigmaValue) == 0)
6153 geometry_info.sigma=1.0;
6154 break;
6155 }
6156 if (LocaleCompare(keyword,"gray") == 0)
6157 {
cristy042ee782011-04-22 18:48:30 +00006158 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00006159 value);
6160 if (option < 0)
6161 ThrowMSLException(OptionError,"UnrecognizedNoiseType",
6162 value);
6163 gray=(MagickBooleanType) option;
6164 break;
6165 }
6166 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6167 keyword);
6168 break;
6169 }
6170 default:
6171 {
6172 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6173 keyword);
6174 break;
6175 }
6176 }
6177 }
6178 shade_image=ShadeImage(msl_info->image[n],gray,geometry_info.rho,
6179 geometry_info.sigma,&msl_info->image[n]->exception);
6180 if (shade_image == (Image *) NULL)
6181 break;
6182 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6183 msl_info->image[n]=shade_image;
6184 break;
6185 }
cristyb988fe72009-09-16 01:01:10 +00006186 if (LocaleCompare((const char *) tag,"shadow") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006187 {
6188 Image
6189 *shadow_image;
6190
6191 /*
6192 Shear image.
6193 */
6194 if (msl_info->image[n] == (Image *) NULL)
6195 {
cristyb988fe72009-09-16 01:01:10 +00006196 ThrowMSLException(OptionError,"NoImagesDefined",
6197 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006198 break;
6199 }
6200 if (attributes != (const xmlChar **) NULL)
6201 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6202 {
6203 keyword=(const char *) attributes[i++];
6204 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006205 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006206 CloneString(&value,attribute);
6207 switch (*keyword)
6208 {
6209 case 'G':
6210 case 'g':
6211 {
6212 if (LocaleCompare(keyword,"geometry") == 0)
6213 {
6214 flags=ParseGeometry(value,&geometry_info);
6215 if ((flags & SigmaValue) == 0)
6216 geometry_info.sigma=1.0;
6217 break;
6218 }
6219 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6220 keyword);
6221 break;
6222 }
6223 case 'O':
6224 case 'o':
6225 {
6226 if (LocaleCompare(keyword,"opacity") == 0)
6227 {
cristyf2f27272009-12-17 14:48:46 +00006228 geometry_info.rho=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006229 break;
6230 }
6231 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6232 keyword);
6233 break;
6234 }
6235 case 'S':
6236 case 's':
6237 {
6238 if (LocaleCompare(keyword,"sigma") == 0)
6239 {
cristyf2f27272009-12-17 14:48:46 +00006240 geometry_info.sigma=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006241 break;
6242 }
6243 break;
6244 }
6245 case 'X':
6246 case 'x':
6247 {
6248 if (LocaleCompare(keyword,"x") == 0)
6249 {
cristyc1acd842011-05-19 23:05:47 +00006250 geometry_info.xi=InterpretLocaleValue(value,
6251 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006252 break;
6253 }
6254 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6255 keyword);
6256 break;
6257 }
6258 case 'Y':
6259 case 'y':
6260 {
6261 if (LocaleCompare(keyword,"y") == 0)
6262 {
cristyf2f27272009-12-17 14:48:46 +00006263 geometry_info.psi=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006264 break;
6265 }
6266 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6267 keyword);
6268 break;
6269 }
6270 default:
6271 {
6272 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6273 keyword);
6274 break;
6275 }
6276 }
6277 }
6278 shadow_image=ShadowImage(msl_info->image[n],geometry_info.rho,
cristybb503372010-05-27 20:51:26 +00006279 geometry_info.sigma,(ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
cristy0534a6b2010-03-18 01:19:38 +00006280 ceil(geometry_info.psi-0.5),&msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00006281 if (shadow_image == (Image *) NULL)
6282 break;
6283 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6284 msl_info->image[n]=shadow_image;
6285 break;
6286 }
cristyb988fe72009-09-16 01:01:10 +00006287 if (LocaleCompare((const char *) tag,"sharpen") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006288 {
6289 double radius = 0.0,
6290 sigma = 1.0;
6291
6292 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00006293 {
6294 ThrowMSLException(OptionError,"NoImagesDefined",
6295 (const char *) tag);
6296 break;
6297 }
cristy3ed852e2009-09-05 21:47:34 +00006298 /*
6299 NOTE: sharpen can have no attributes, since we use all the defaults!
6300 */
6301 if (attributes != (const xmlChar **) NULL)
6302 {
6303 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6304 {
6305 keyword=(const char *) attributes[i++];
6306 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006307 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00006308 switch (*keyword)
6309 {
6310 case 'R':
6311 case 'r':
6312 {
6313 if (LocaleCompare(keyword, "radius") == 0)
6314 {
cristyc1acd842011-05-19 23:05:47 +00006315 radius = InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006316 break;
6317 }
6318 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6319 break;
6320 }
6321 case 'S':
6322 case 's':
6323 {
6324 if (LocaleCompare(keyword,"sigma") == 0)
6325 {
cristyf2f27272009-12-17 14:48:46 +00006326 sigma = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00006327 break;
6328 }
6329 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6330 break;
6331 }
6332 default:
6333 {
6334 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6335 break;
6336 }
6337 }
6338 }
6339 }
6340
6341 /*
6342 sharpen image.
6343 */
6344 {
6345 Image
6346 *newImage;
6347
6348 newImage=SharpenImage(msl_info->image[n],radius,sigma,&msl_info->image[n]->exception);
6349 if (newImage == (Image *) NULL)
6350 break;
6351 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6352 msl_info->image[n]=newImage;
6353 break;
6354 }
6355 }
cristyb988fe72009-09-16 01:01:10 +00006356 else if (LocaleCompare((const char *) tag,"shave") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006357 {
6358 /* init the values */
6359 width = height = 0;
6360 x = y = 0;
6361
6362 if (msl_info->image[n] == (Image *) NULL)
6363 {
cristyb988fe72009-09-16 01:01:10 +00006364 ThrowMSLException(OptionError,"NoImagesDefined",
6365 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006366 break;
6367 }
6368 if (attributes == (const xmlChar **) NULL)
6369 break;
6370 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6371 {
6372 keyword=(const char *) attributes[i++];
6373 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006374 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00006375 switch (*keyword)
6376 {
6377 case 'G':
6378 case 'g':
6379 {
6380 if (LocaleCompare(keyword,"geometry") == 0)
6381 {
6382 (void) ParseMetaGeometry(value,&x,&y,&width,&height);
6383 break;
6384 }
6385 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6386 break;
6387 }
6388 case 'H':
6389 case 'h':
6390 {
6391 if (LocaleCompare(keyword,"height") == 0)
6392 {
cristyf2f27272009-12-17 14:48:46 +00006393 height = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00006394 break;
6395 }
6396 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6397 break;
6398 }
6399 case 'W':
6400 case 'w':
6401 {
6402 if (LocaleCompare(keyword,"width") == 0)
6403 {
cristyf2f27272009-12-17 14:48:46 +00006404 width = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00006405 break;
6406 }
6407 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6408 break;
6409 }
6410 default:
6411 {
6412 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6413 break;
6414 }
6415 }
6416 }
6417
6418 /*
6419 process image.
6420 */
6421 {
6422 Image
6423 *newImage;
6424 RectangleInfo
6425 rectInfo;
6426
6427 rectInfo.height = height;
6428 rectInfo.width = width;
6429 rectInfo.x = x;
6430 rectInfo.y = y;
6431
6432
6433 newImage=ShaveImage(msl_info->image[n], &rectInfo,
6434 &msl_info->image[n]->exception);
6435 if (newImage == (Image *) NULL)
6436 break;
6437 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6438 msl_info->image[n]=newImage;
6439 }
6440
6441 break;
6442 }
cristyb988fe72009-09-16 01:01:10 +00006443 if (LocaleCompare((const char *) tag,"shear") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006444 {
6445 Image
6446 *shear_image;
6447
6448 /*
6449 Shear image.
6450 */
6451 if (msl_info->image[n] == (Image *) NULL)
6452 {
cristyb988fe72009-09-16 01:01:10 +00006453 ThrowMSLException(OptionError,"NoImagesDefined",
6454 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006455 break;
6456 }
6457 if (attributes != (const xmlChar **) NULL)
6458 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6459 {
6460 keyword=(const char *) attributes[i++];
6461 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006462 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006463 CloneString(&value,attribute);
6464 switch (*keyword)
6465 {
6466 case 'F':
6467 case 'f':
6468 {
6469 if (LocaleCompare(keyword, "fill") == 0)
6470 {
6471 (void) QueryColorDatabase(value,
6472 &msl_info->image[n]->background_color,&exception);
6473 break;
6474 }
6475 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6476 keyword);
6477 break;
6478 }
6479 case 'G':
6480 case 'g':
6481 {
6482 if (LocaleCompare(keyword,"geometry") == 0)
6483 {
6484 flags=ParseGeometry(value,&geometry_info);
6485 if ((flags & SigmaValue) == 0)
6486 geometry_info.sigma=1.0;
6487 break;
6488 }
6489 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6490 keyword);
6491 break;
6492 }
6493 case 'X':
6494 case 'x':
6495 {
6496 if (LocaleCompare(keyword,"x") == 0)
6497 {
cristyc1acd842011-05-19 23:05:47 +00006498 geometry_info.rho=InterpretLocaleValue(value,
6499 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006500 break;
6501 }
6502 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6503 keyword);
6504 break;
6505 }
6506 case 'Y':
6507 case 'y':
6508 {
6509 if (LocaleCompare(keyword,"y") == 0)
6510 {
cristyf2f27272009-12-17 14:48:46 +00006511 geometry_info.sigma=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006512 break;
6513 }
6514 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6515 keyword);
6516 break;
6517 }
6518 default:
6519 {
6520 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6521 keyword);
6522 break;
6523 }
6524 }
6525 }
6526 shear_image=ShearImage(msl_info->image[n],geometry_info.rho,
6527 geometry_info.sigma,&msl_info->image[n]->exception);
6528 if (shear_image == (Image *) NULL)
6529 break;
6530 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6531 msl_info->image[n]=shear_image;
6532 break;
6533 }
cristyb988fe72009-09-16 01:01:10 +00006534 if (LocaleCompare((const char *) tag,"signature") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006535 {
6536 /*
6537 Signature image.
6538 */
6539 if (msl_info->image[n] == (Image *) NULL)
6540 {
cristyb988fe72009-09-16 01:01:10 +00006541 ThrowMSLException(OptionError,"NoImagesDefined",
6542 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006543 break;
6544 }
6545 if (attributes != (const xmlChar **) NULL)
6546 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6547 {
6548 keyword=(const char *) attributes[i++];
6549 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006550 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006551 CloneString(&value,attribute);
6552 switch (*keyword)
6553 {
6554 default:
6555 {
6556 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6557 keyword);
6558 break;
6559 }
6560 }
6561 }
6562 (void) SignatureImage(msl_info->image[n]);
6563 break;
6564 }
cristyb988fe72009-09-16 01:01:10 +00006565 if (LocaleCompare((const char *) tag,"solarize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006566 {
6567 /*
6568 Solarize image.
6569 */
6570 if (msl_info->image[n] == (Image *) NULL)
6571 {
cristyb988fe72009-09-16 01:01:10 +00006572 ThrowMSLException(OptionError,"NoImagesDefined",
6573 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006574 break;
6575 }
6576 geometry_info.rho=QuantumRange/2.0;
6577 if (attributes != (const xmlChar **) NULL)
6578 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6579 {
6580 keyword=(const char *) attributes[i++];
6581 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006582 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006583 CloneString(&value,attribute);
6584 switch (*keyword)
6585 {
6586 case 'G':
6587 case 'g':
6588 {
6589 if (LocaleCompare(keyword,"geometry") == 0)
6590 {
6591 flags=ParseGeometry(value,&geometry_info);
6592 break;
6593 }
6594 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6595 keyword);
6596 break;
6597 }
6598 case 'T':
6599 case 't':
6600 {
6601 if (LocaleCompare(keyword,"threshold") == 0)
6602 {
cristyc1acd842011-05-19 23:05:47 +00006603 geometry_info.rho=InterpretLocaleValue(value,
6604 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006605 break;
6606 }
6607 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6608 keyword);
6609 break;
6610 }
6611 default:
6612 {
6613 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6614 keyword);
6615 break;
6616 }
6617 }
6618 }
6619 (void) SolarizeImage(msl_info->image[n],geometry_info.rho);
6620 break;
6621 }
cristyb988fe72009-09-16 01:01:10 +00006622 if (LocaleCompare((const char *) tag,"spread") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006623 {
6624 Image
6625 *spread_image;
6626
6627 /*
6628 Spread image.
6629 */
6630 if (msl_info->image[n] == (Image *) NULL)
6631 {
cristyb988fe72009-09-16 01:01:10 +00006632 ThrowMSLException(OptionError,"NoImagesDefined",
6633 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006634 break;
6635 }
6636 if (attributes != (const xmlChar **) NULL)
6637 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6638 {
6639 keyword=(const char *) attributes[i++];
6640 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006641 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006642 CloneString(&value,attribute);
6643 switch (*keyword)
6644 {
6645 case 'G':
6646 case 'g':
6647 {
6648 if (LocaleCompare(keyword,"geometry") == 0)
6649 {
6650 flags=ParseGeometry(value,&geometry_info);
6651 if ((flags & SigmaValue) == 0)
6652 geometry_info.sigma=1.0;
6653 break;
6654 }
6655 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6656 keyword);
6657 break;
6658 }
6659 case 'R':
6660 case 'r':
6661 {
6662 if (LocaleCompare(keyword,"radius") == 0)
6663 {
cristyc1acd842011-05-19 23:05:47 +00006664 geometry_info.rho=InterpretLocaleValue(value,
6665 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006666 break;
6667 }
6668 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6669 keyword);
6670 break;
6671 }
6672 default:
6673 {
6674 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6675 keyword);
6676 break;
6677 }
6678 }
6679 }
6680 spread_image=SpreadImage(msl_info->image[n],geometry_info.rho,
6681 &msl_info->image[n]->exception);
6682 if (spread_image == (Image *) NULL)
6683 break;
6684 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6685 msl_info->image[n]=spread_image;
6686 break;
6687 }
cristyb988fe72009-09-16 01:01:10 +00006688 else if (LocaleCompare((const char *) tag,"stegano") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006689 {
6690 Image *
6691 watermark = (Image*)NULL;
6692
6693 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00006694 {
6695 ThrowMSLException(OptionError,"NoImagesDefined",
6696 (const char *) tag);
6697 break;
6698 }
cristy3ed852e2009-09-05 21:47:34 +00006699 if (attributes == (const xmlChar **) NULL)
6700 break;
6701 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6702 {
6703 keyword=(const char *) attributes[i++];
6704 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006705 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00006706 switch (*keyword)
6707 {
6708 case 'I':
6709 case 'i':
6710 {
6711 if (LocaleCompare(keyword,"image") == 0)
6712 {
6713 for (j=0; j<msl_info->n;j++)
6714 {
6715 const char *
6716 theAttr = GetImageProperty(msl_info->attributes[j], "id");
6717 if (theAttr && LocaleCompare(theAttr, value) == 0)
6718 {
6719 watermark = msl_info->image[j];
6720 break;
6721 }
6722 }
6723 break;
6724 }
6725 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6726 break;
6727 }
6728 default:
6729 {
6730 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6731 break;
6732 }
6733 }
6734 }
6735
6736 /*
6737 process image.
6738 */
6739 if ( watermark != (Image*) NULL )
6740 {
6741 Image
6742 *newImage;
6743
6744 newImage=SteganoImage(msl_info->image[n], watermark, &msl_info->image[n]->exception);
6745 if (newImage == (Image *) NULL)
6746 break;
6747 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6748 msl_info->image[n]=newImage;
6749 break;
6750 } else
6751 ThrowMSLException(OptionError,"MissingWatermarkImage",keyword);
6752 }
cristyb988fe72009-09-16 01:01:10 +00006753 else if (LocaleCompare((const char *) tag,"stereo") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006754 {
6755 Image *
6756 stereoImage = (Image*)NULL;
6757
6758 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00006759 {
6760 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
6761 break;
6762 }
cristy3ed852e2009-09-05 21:47:34 +00006763 if (attributes == (const xmlChar **) NULL)
6764 break;
6765 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6766 {
6767 keyword=(const char *) attributes[i++];
6768 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006769 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00006770 switch (*keyword)
6771 {
6772 case 'I':
6773 case 'i':
6774 {
6775 if (LocaleCompare(keyword,"image") == 0)
6776 {
6777 for (j=0; j<msl_info->n;j++)
6778 {
6779 const char *
6780 theAttr = GetImageProperty(msl_info->attributes[j], "id");
6781 if (theAttr && LocaleCompare(theAttr, value) == 0)
6782 {
6783 stereoImage = msl_info->image[j];
6784 break;
6785 }
6786 }
6787 break;
6788 }
6789 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6790 break;
6791 }
6792 default:
6793 {
6794 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6795 break;
6796 }
6797 }
6798 }
6799
6800 /*
6801 process image.
6802 */
6803 if ( stereoImage != (Image*) NULL )
6804 {
6805 Image
6806 *newImage;
6807
6808 newImage=StereoImage(msl_info->image[n], stereoImage, &msl_info->image[n]->exception);
6809 if (newImage == (Image *) NULL)
6810 break;
6811 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6812 msl_info->image[n]=newImage;
6813 break;
6814 } else
6815 ThrowMSLException(OptionError,"Missing stereo image",keyword);
6816 }
cristyb988fe72009-09-16 01:01:10 +00006817 if (LocaleCompare((const char *) tag,"swap") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006818 {
6819 Image
6820 *p,
6821 *q,
6822 *swap;
6823
cristybb503372010-05-27 20:51:26 +00006824 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00006825 index,
6826 swap_index;
6827
6828 if (msl_info->image[n] == (Image *) NULL)
6829 {
cristyb988fe72009-09-16 01:01:10 +00006830 ThrowMSLException(OptionError,"NoImagesDefined",
6831 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006832 break;
6833 }
6834 index=(-1);
6835 swap_index=(-2);
6836 if (attributes != (const xmlChar **) NULL)
6837 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6838 {
6839 keyword=(const char *) attributes[i++];
6840 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006841 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006842 CloneString(&value,attribute);
6843 switch (*keyword)
6844 {
6845 case 'G':
6846 case 'g':
6847 {
6848 if (LocaleCompare(keyword,"indexes") == 0)
6849 {
6850 flags=ParseGeometry(value,&geometry_info);
cristybb503372010-05-27 20:51:26 +00006851 index=(ssize_t) geometry_info.rho;
cristy3ed852e2009-09-05 21:47:34 +00006852 if ((flags & SigmaValue) == 0)
cristybb503372010-05-27 20:51:26 +00006853 swap_index=(ssize_t) geometry_info.sigma;
cristy3ed852e2009-09-05 21:47:34 +00006854 break;
6855 }
6856 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6857 keyword);
6858 break;
6859 }
6860 default:
6861 {
6862 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6863 keyword);
6864 break;
6865 }
6866 }
6867 }
6868 /*
6869 Swap images.
6870 */
6871 p=GetImageFromList(msl_info->image[n],index);
6872 q=GetImageFromList(msl_info->image[n],swap_index);
6873 if ((p == (Image *) NULL) || (q == (Image *) NULL))
6874 {
cristyb988fe72009-09-16 01:01:10 +00006875 ThrowMSLException(OptionError,"NoSuchImage",(const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006876 break;
6877 }
6878 swap=CloneImage(p,0,0,MagickTrue,&p->exception);
6879 ReplaceImageInList(&p,CloneImage(q,0,0,MagickTrue,&q->exception));
6880 ReplaceImageInList(&q,swap);
6881 msl_info->image[n]=GetFirstImageInList(q);
6882 break;
6883 }
cristyb988fe72009-09-16 01:01:10 +00006884 if (LocaleCompare((const char *) tag,"swirl") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006885 {
6886 Image
6887 *swirl_image;
6888
6889 /*
6890 Swirl image.
6891 */
6892 if (msl_info->image[n] == (Image *) NULL)
6893 {
cristyb988fe72009-09-16 01:01:10 +00006894 ThrowMSLException(OptionError,"NoImagesDefined",
6895 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006896 break;
6897 }
6898 if (attributes != (const xmlChar **) NULL)
6899 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6900 {
6901 keyword=(const char *) attributes[i++];
6902 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006903 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006904 CloneString(&value,attribute);
6905 switch (*keyword)
6906 {
6907 case 'D':
6908 case 'd':
6909 {
6910 if (LocaleCompare(keyword,"degrees") == 0)
6911 {
cristyc1acd842011-05-19 23:05:47 +00006912 geometry_info.rho=InterpretLocaleValue(value,
6913 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006914 break;
6915 }
6916 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6917 keyword);
6918 break;
6919 }
6920 case 'G':
6921 case 'g':
6922 {
6923 if (LocaleCompare(keyword,"geometry") == 0)
6924 {
6925 flags=ParseGeometry(value,&geometry_info);
6926 if ((flags & SigmaValue) == 0)
6927 geometry_info.sigma=1.0;
6928 break;
6929 }
6930 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6931 keyword);
6932 break;
6933 }
6934 default:
6935 {
6936 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6937 keyword);
6938 break;
6939 }
6940 }
6941 }
6942 swirl_image=SwirlImage(msl_info->image[n],geometry_info.rho,
6943 &msl_info->image[n]->exception);
6944 if (swirl_image == (Image *) NULL)
6945 break;
6946 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6947 msl_info->image[n]=swirl_image;
6948 break;
6949 }
cristyb988fe72009-09-16 01:01:10 +00006950 if (LocaleCompare((const char *) tag,"sync") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006951 {
6952 /*
6953 Sync image.
6954 */
6955 if (msl_info->image[n] == (Image *) NULL)
6956 {
cristyb988fe72009-09-16 01:01:10 +00006957 ThrowMSLException(OptionError,"NoImagesDefined",
6958 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006959 break;
6960 }
6961 if (attributes != (const xmlChar **) NULL)
6962 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6963 {
6964 keyword=(const char *) attributes[i++];
6965 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00006966 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00006967 CloneString(&value,attribute);
6968 switch (*keyword)
6969 {
6970 default:
6971 {
6972 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6973 keyword);
6974 break;
6975 }
6976 }
6977 }
6978 (void) SyncImage(msl_info->image[n]);
6979 break;
6980 }
6981 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
6982 }
6983 case 'T':
6984 case 't':
6985 {
cristyb988fe72009-09-16 01:01:10 +00006986 if (LocaleCompare((const char *) tag,"map") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006987 {
6988 Image
6989 *texture_image;
6990
6991 /*
6992 Texture image.
6993 */
6994 if (msl_info->image[n] == (Image *) NULL)
6995 {
cristyb988fe72009-09-16 01:01:10 +00006996 ThrowMSLException(OptionError,"NoImagesDefined",
6997 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006998 break;
6999 }
7000 texture_image=NewImageList();
7001 if (attributes != (const xmlChar **) NULL)
7002 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7003 {
7004 keyword=(const char *) attributes[i++];
7005 attribute=InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00007006 msl_info->attributes[n],(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00007007 CloneString(&value,attribute);
7008 switch (*keyword)
7009 {
7010 case 'I':
7011 case 'i':
7012 {
7013 if (LocaleCompare(keyword,"image") == 0)
7014 for (j=0; j < msl_info->n; j++)
7015 {
7016 const char
7017 *attribute;
cristyb988fe72009-09-16 01:01:10 +00007018
cristy3ed852e2009-09-05 21:47:34 +00007019 attribute=GetImageProperty(msl_info->attributes[j],"id");
7020 if ((attribute != (const char *) NULL) &&
7021 (LocaleCompare(attribute,value) == 0))
7022 {
7023 texture_image=CloneImage(msl_info->image[j],0,0,
7024 MagickFalse,&exception);
7025 break;
7026 }
7027 }
7028 break;
7029 }
7030 default:
7031 {
7032 ThrowMSLException(OptionError,"UnrecognizedAttribute",
7033 keyword);
7034 break;
7035 }
7036 }
7037 }
7038 (void) TextureImage(msl_info->image[n],texture_image);
7039 texture_image=DestroyImage(texture_image);
7040 break;
7041 }
cristyb988fe72009-09-16 01:01:10 +00007042 else if (LocaleCompare((const char *) tag,"threshold") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007043 {
7044 /* init the values */
7045 double threshold = 0;
7046
7047 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007048 {
7049 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7050 break;
7051 }
cristy3ed852e2009-09-05 21:47:34 +00007052 if (attributes == (const xmlChar **) NULL)
7053 break;
7054 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7055 {
7056 keyword=(const char *) attributes[i++];
7057 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00007058 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00007059 switch (*keyword)
7060 {
7061 case 'T':
7062 case 't':
7063 {
7064 if (LocaleCompare(keyword,"threshold") == 0)
7065 {
cristyc1acd842011-05-19 23:05:47 +00007066 threshold = InterpretLocaleValue(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00007067 break;
7068 }
7069 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7070 break;
7071 }
7072 default:
7073 {
7074 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7075 break;
7076 }
7077 }
7078 }
7079
7080 /*
7081 process image.
7082 */
7083 {
cristyf4ad9df2011-07-08 16:49:03 +00007084 BilevelImage(msl_info->image[n],threshold);
cristy3ed852e2009-09-05 21:47:34 +00007085 break;
7086 }
7087 }
cristyb988fe72009-09-16 01:01:10 +00007088 else if (LocaleCompare((const char *) tag, "transparent") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007089 {
7090 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007091 {
7092 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7093 break;
7094 }
cristy3ed852e2009-09-05 21:47:34 +00007095 if (attributes == (const xmlChar **) NULL)
7096 break;
7097 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7098 {
7099 keyword=(const char *) attributes[i++];
7100 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00007101 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00007102 switch (*keyword)
7103 {
7104 case 'C':
7105 case 'c':
7106 {
7107 if (LocaleCompare(keyword,"color") == 0)
7108 {
cristy4c08aed2011-07-01 19:47:50 +00007109 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00007110 target;
7111
7112 (void) QueryMagickColor(value,&target,&exception);
7113 (void) TransparentPaintImage(msl_info->image[n],&target,
cristy189e84c2011-08-27 18:08:53 +00007114 TransparentAlpha,MagickFalse,&msl_info->image[n]->exception);
cristy3ed852e2009-09-05 21:47:34 +00007115 break;
7116 }
7117 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7118 break;
7119 }
7120 default:
7121 {
7122 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7123 break;
7124 }
7125 }
7126 }
7127 break;
7128 }
cristyb988fe72009-09-16 01:01:10 +00007129 else if (LocaleCompare((const char *) tag, "trim") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007130 {
7131 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007132 {
7133 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7134 break;
7135 }
cristy3ed852e2009-09-05 21:47:34 +00007136
7137 /* no attributes here */
7138
7139 /* process the image */
7140 {
7141 Image
7142 *newImage;
7143 RectangleInfo
7144 rectInfo;
7145
7146 /* all zeros on a crop == trim edges! */
7147 rectInfo.height = rectInfo.width = 0;
7148 rectInfo.x = rectInfo.y = 0;
7149
7150 newImage=CropImage(msl_info->image[n],&rectInfo, &msl_info->image[n]->exception);
7151 if (newImage == (Image *) NULL)
7152 break;
7153 msl_info->image[n]=DestroyImage(msl_info->image[n]);
7154 msl_info->image[n]=newImage;
7155 break;
7156 }
7157 }
7158 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7159 }
7160 case 'W':
7161 case 'w':
7162 {
cristyb988fe72009-09-16 01:01:10 +00007163 if (LocaleCompare((const char *) tag,"write") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007164 {
7165 if (msl_info->image[n] == (Image *) NULL)
7166 {
cristyb988fe72009-09-16 01:01:10 +00007167 ThrowMSLException(OptionError,"NoImagesDefined",
7168 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00007169 break;
7170 }
7171 if (attributes == (const xmlChar **) NULL)
7172 break;
7173 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7174 {
7175 keyword=(const char *) attributes[i++];
7176 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristyb988fe72009-09-16 01:01:10 +00007177 msl_info->attributes[n],(const char *) attributes[i]));
cristy3ed852e2009-09-05 21:47:34 +00007178 switch (*keyword)
7179 {
7180 case 'F':
7181 case 'f':
7182 {
7183 if (LocaleCompare(keyword,"filename") == 0)
7184 {
7185 (void) CopyMagickString(msl_info->image[n]->filename,value,
7186 MaxTextExtent);
7187 break;
7188 }
cristy4582cbb2009-09-23 00:35:43 +00007189 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00007190 }
7191 default:
7192 {
cristy4582cbb2009-09-23 00:35:43 +00007193 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00007194 break;
7195 }
7196 }
7197 }
7198
7199 /* process */
7200 {
7201 (void) WriteImage(msl_info->image_info[n], msl_info->image[n]);
7202 break;
7203 }
7204 }
7205 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7206 }
7207 default:
7208 {
7209 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7210 break;
7211 }
7212 }
7213 if ( value != NULL )
7214 value=DestroyString(value);
7215 (void) LogMagickEvent(CoderEvent,GetMagickModule()," )");
7216}
7217
7218static void MSLEndElement(void *context,const xmlChar *tag)
7219{
cristybb503372010-05-27 20:51:26 +00007220 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00007221 n;
7222
7223 MSLInfo
7224 *msl_info;
7225
7226 /*
7227 Called when the end of an element has been detected.
7228 */
7229 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.endElement(%s)",
7230 tag);
7231 msl_info=(MSLInfo *) context;
7232 n=msl_info->n;
7233 switch (*tag)
7234 {
7235 case 'C':
7236 case 'c':
7237 {
cristyb988fe72009-09-16 01:01:10 +00007238 if (LocaleCompare((const char *) tag,"comment") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007239 {
7240 (void) DeleteImageProperty(msl_info->image[n],"comment");
7241 if (msl_info->content == (char *) NULL)
7242 break;
7243 StripString(msl_info->content);
7244 (void) SetImageProperty(msl_info->image[n],"comment",
7245 msl_info->content);
7246 break;
7247 }
7248 break;
7249 }
7250 case 'G':
7251 case 'g':
7252 {
cristyb988fe72009-09-16 01:01:10 +00007253 if (LocaleCompare((const char *) tag, "group") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007254 {
7255 if (msl_info->group_info[msl_info->number_groups-1].numImages > 0 )
7256 {
cristybb503372010-05-27 20:51:26 +00007257 ssize_t i = (ssize_t)
cristy3ed852e2009-09-05 21:47:34 +00007258 (msl_info->group_info[msl_info->number_groups-1].numImages);
7259 while ( i-- )
7260 {
7261 if (msl_info->image[msl_info->n] != (Image *) NULL)
7262 msl_info->image[msl_info->n]=DestroyImage(msl_info->image[msl_info->n]);
7263 msl_info->attributes[msl_info->n]=DestroyImage(msl_info->attributes[msl_info->n]);
7264 msl_info->image_info[msl_info->n]=DestroyImageInfo(msl_info->image_info[msl_info->n]);
7265 msl_info->n--;
7266 }
7267 }
7268 msl_info->number_groups--;
7269 }
7270 break;
7271 }
7272 case 'I':
7273 case 'i':
7274 {
cristyb988fe72009-09-16 01:01:10 +00007275 if (LocaleCompare((const char *) tag, "image") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007276 MSLPopImage(msl_info);
7277 break;
7278 }
7279 case 'L':
7280 case 'l':
7281 {
cristyb988fe72009-09-16 01:01:10 +00007282 if (LocaleCompare((const char *) tag,"label") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007283 {
7284 (void) DeleteImageProperty(msl_info->image[n],"label");
7285 if (msl_info->content == (char *) NULL)
7286 break;
7287 StripString(msl_info->content);
7288 (void) SetImageProperty(msl_info->image[n],"label",
7289 msl_info->content);
7290 break;
7291 }
7292 break;
7293 }
7294 case 'M':
7295 case 'm':
7296 {
cristyb988fe72009-09-16 01:01:10 +00007297 if (LocaleCompare((const char *) tag, "msl") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007298 {
7299 /*
7300 This our base element.
7301 at the moment we don't do anything special
7302 but someday we might!
7303 */
7304 }
7305 break;
7306 }
7307 default:
7308 break;
7309 }
7310 if (msl_info->content != (char *) NULL)
7311 msl_info->content=DestroyString(msl_info->content);
7312}
7313
7314static void MSLCharacters(void *context,const xmlChar *c,int length)
7315{
7316 MSLInfo
7317 *msl_info;
7318
7319 register char
7320 *p;
7321
cristybb503372010-05-27 20:51:26 +00007322 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00007323 i;
7324
7325 /*
7326 Receiving some characters from the parser.
7327 */
7328 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7329 " SAX.characters(%s,%d)",c,length);
7330 msl_info=(MSLInfo *) context;
7331 if (msl_info->content != (char *) NULL)
7332 msl_info->content=(char *) ResizeQuantumMemory(msl_info->content,
7333 strlen(msl_info->content)+length+MaxTextExtent,
7334 sizeof(*msl_info->content));
7335 else
7336 {
7337 msl_info->content=(char *) NULL;
cristy37e0b382011-06-07 13:31:21 +00007338 if (~length >= (MaxTextExtent-1))
cristy3ed852e2009-09-05 21:47:34 +00007339 msl_info->content=(char *) AcquireQuantumMemory(length+MaxTextExtent,
7340 sizeof(*msl_info->content));
7341 if (msl_info->content != (char *) NULL)
7342 *msl_info->content='\0';
7343 }
7344 if (msl_info->content == (char *) NULL)
7345 return;
7346 p=msl_info->content+strlen(msl_info->content);
7347 for (i=0; i < length; i++)
7348 *p++=c[i];
7349 *p='\0';
7350}
7351
7352static void MSLReference(void *context,const xmlChar *name)
7353{
7354 MSLInfo
7355 *msl_info;
7356
7357 xmlParserCtxtPtr
7358 parser;
7359
7360 /*
7361 Called when an entity reference is detected.
7362 */
7363 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7364 " SAX.reference(%s)",name);
7365 msl_info=(MSLInfo *) context;
7366 parser=msl_info->parser;
7367 if (*name == '#')
7368 (void) xmlAddChild(parser->node,xmlNewCharRef(msl_info->document,name));
7369 else
7370 (void) xmlAddChild(parser->node,xmlNewReference(msl_info->document,name));
7371}
7372
7373static void MSLIgnorableWhitespace(void *context,const xmlChar *c,int length)
7374{
7375 MSLInfo
7376 *msl_info;
7377
7378 /*
7379 Receiving some ignorable whitespaces from the parser.
7380 */
7381 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7382 " SAX.ignorableWhitespace(%.30s, %d)",c,length);
7383 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007384 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007385}
7386
7387static void MSLProcessingInstructions(void *context,const xmlChar *target,
7388 const xmlChar *data)
7389{
7390 MSLInfo
7391 *msl_info;
7392
7393 /*
7394 A processing instruction has been parsed.
7395 */
7396 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7397 " SAX.processingInstruction(%s, %s)",
7398 target,data);
7399 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007400 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007401}
7402
7403static void MSLComment(void *context,const xmlChar *value)
7404{
7405 MSLInfo
7406 *msl_info;
7407
7408 /*
7409 A comment has been parsed.
7410 */
7411 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7412 " SAX.comment(%s)",value);
7413 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007414 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007415}
7416
7417static void MSLWarning(void *context,const char *format,...)
7418{
7419 char
7420 *message,
7421 reason[MaxTextExtent];
7422
7423 MSLInfo
7424 *msl_info;
7425
7426 va_list
7427 operands;
7428
7429 /**
7430 Display and format a warning messages, gives file, line, position and
7431 extra parameters.
7432 */
7433 va_start(operands,format);
7434 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.warning: ");
7435 (void) LogMagickEvent(CoderEvent,GetMagickModule(),format,operands);
7436 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007437 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007438#if !defined(MAGICKCORE_HAVE_VSNPRINTF)
7439 (void) vsprintf(reason,format,operands);
7440#else
7441 (void) vsnprintf(reason,MaxTextExtent,format,operands);
7442#endif
7443 message=GetExceptionMessage(errno);
7444 ThrowMSLException(CoderError,reason,message);
7445 message=DestroyString(message);
7446 va_end(operands);
7447}
7448
7449static void MSLError(void *context,const char *format,...)
7450{
7451 char
7452 reason[MaxTextExtent];
7453
7454 MSLInfo
7455 *msl_info;
7456
7457 va_list
7458 operands;
7459
7460 /*
7461 Display and format a error formats, gives file, line, position and
7462 extra parameters.
7463 */
7464 va_start(operands,format);
7465 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.error: ");
7466 (void) LogMagickEvent(CoderEvent,GetMagickModule(),format,operands);
7467 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007468 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007469#if !defined(MAGICKCORE_HAVE_VSNPRINTF)
7470 (void) vsprintf(reason,format,operands);
7471#else
7472 (void) vsnprintf(reason,MaxTextExtent,format,operands);
7473#endif
7474 ThrowMSLException(DelegateFatalError,reason,"SAX error");
7475 va_end(operands);
7476}
7477
7478static void MSLCDataBlock(void *context,const xmlChar *value,int length)
7479{
7480 MSLInfo
7481 *msl_info;
7482
7483 xmlNodePtr
7484 child;
7485
7486 xmlParserCtxtPtr
7487 parser;
7488
7489 /*
7490 Called when a pcdata block has been parsed.
7491 */
7492 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7493 " SAX.pcdata(%s, %d)",value,length);
7494 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007495 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007496 parser=msl_info->parser;
7497 child=xmlGetLastChild(parser->node);
7498 if ((child != (xmlNodePtr) NULL) && (child->type == XML_CDATA_SECTION_NODE))
7499 {
7500 xmlTextConcat(child,value,length);
7501 return;
7502 }
7503 (void) xmlAddChild(parser->node,xmlNewCDataBlock(parser->myDoc,value,length));
7504}
7505
7506static void MSLExternalSubset(void *context,const xmlChar *name,
7507 const xmlChar *external_id,const xmlChar *system_id)
7508{
7509 MSLInfo
7510 *msl_info;
7511
7512 xmlParserCtxt
7513 parser_context;
7514
7515 xmlParserCtxtPtr
7516 parser;
7517
7518 xmlParserInputPtr
7519 input;
7520
7521 /*
7522 Does this document has an external subset?
7523 */
7524 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7525 " SAX.externalSubset(%s %s %s)",name,
cristyb988fe72009-09-16 01:01:10 +00007526 (external_id != (const xmlChar *) NULL ? (const char *) external_id : " "),
7527 (system_id != (const xmlChar *) NULL ? (const char *) system_id : " "));
cristy3ed852e2009-09-05 21:47:34 +00007528 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007529 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007530 parser=msl_info->parser;
7531 if (((external_id == NULL) && (system_id == NULL)) ||
7532 ((parser->validate == 0) || (parser->wellFormed == 0) ||
7533 (msl_info->document == 0)))
7534 return;
7535 input=MSLResolveEntity(context,external_id,system_id);
7536 if (input == NULL)
7537 return;
7538 (void) xmlNewDtd(msl_info->document,name,external_id,system_id);
7539 parser_context=(*parser);
7540 parser->inputTab=(xmlParserInputPtr *) xmlMalloc(5*sizeof(*parser->inputTab));
7541 if (parser->inputTab == (xmlParserInputPtr *) NULL)
7542 {
7543 parser->errNo=XML_ERR_NO_MEMORY;
7544 parser->input=parser_context.input;
7545 parser->inputNr=parser_context.inputNr;
7546 parser->inputMax=parser_context.inputMax;
7547 parser->inputTab=parser_context.inputTab;
7548 return;
7549 }
7550 parser->inputNr=0;
7551 parser->inputMax=5;
7552 parser->input=NULL;
7553 xmlPushInput(parser,input);
7554 (void) xmlSwitchEncoding(parser,xmlDetectCharEncoding(parser->input->cur,4));
7555 if (input->filename == (char *) NULL)
7556 input->filename=(char *) xmlStrdup(system_id);
7557 input->line=1;
7558 input->col=1;
7559 input->base=parser->input->cur;
7560 input->cur=parser->input->cur;
7561 input->free=NULL;
7562 xmlParseExternalSubset(parser,external_id,system_id);
7563 while (parser->inputNr > 1)
7564 (void) xmlPopInput(parser);
7565 xmlFreeInputStream(parser->input);
7566 xmlFree(parser->inputTab);
7567 parser->input=parser_context.input;
7568 parser->inputNr=parser_context.inputNr;
7569 parser->inputMax=parser_context.inputMax;
7570 parser->inputTab=parser_context.inputTab;
7571}
7572
7573#if defined(__cplusplus) || defined(c_plusplus)
7574}
7575#endif
7576
7577static MagickBooleanType ProcessMSLScript(const ImageInfo *image_info,Image **image,
7578 ExceptionInfo *exception)
7579{
cristy3ed852e2009-09-05 21:47:34 +00007580 char
7581 message[MaxTextExtent];
7582
7583 Image
7584 *msl_image;
7585
7586 int
7587 status;
7588
cristybb503372010-05-27 20:51:26 +00007589 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00007590 n;
7591
7592 MSLInfo
7593 msl_info;
7594
cristy5f6f01c2009-11-19 19:36:42 +00007595 xmlSAXHandler
7596 sax_modules;
7597
cristy3ed852e2009-09-05 21:47:34 +00007598 xmlSAXHandlerPtr
cristy5f6f01c2009-11-19 19:36:42 +00007599 sax_handler;
cristy3ed852e2009-09-05 21:47:34 +00007600
7601 /*
7602 Open image file.
7603 */
7604 assert(image_info != (const ImageInfo *) NULL);
7605 assert(image_info->signature == MagickSignature);
7606 if (image_info->debug != MagickFalse)
cristy5f6f01c2009-11-19 19:36:42 +00007607 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
7608 image_info->filename);
cristy3ed852e2009-09-05 21:47:34 +00007609 assert(image != (Image **) NULL);
7610 msl_image=AcquireImage(image_info);
7611 status=OpenBlob(image_info,msl_image,ReadBinaryBlobMode,exception);
7612 if (status == MagickFalse)
7613 {
7614 ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
7615 msl_image->filename);
7616 msl_image=DestroyImageList(msl_image);
7617 return(MagickFalse);
7618 }
7619 msl_image->columns=1;
7620 msl_image->rows=1;
7621 /*
7622 Parse MSL file.
7623 */
7624 (void) ResetMagickMemory(&msl_info,0,sizeof(msl_info));
7625 msl_info.exception=exception;
7626 msl_info.image_info=(ImageInfo **) AcquireMagickMemory(
7627 sizeof(*msl_info.image_info));
7628 msl_info.draw_info=(DrawInfo **) AcquireMagickMemory(
7629 sizeof(*msl_info.draw_info));
7630 /* top of the stack is the MSL file itself */
cristy73bd4a52010-10-05 11:24:23 +00007631 msl_info.image=(Image **) AcquireMagickMemory(sizeof(*msl_info.image));
cristy3ed852e2009-09-05 21:47:34 +00007632 msl_info.attributes=(Image **) AcquireMagickMemory(
7633 sizeof(*msl_info.attributes));
7634 msl_info.group_info=(MSLGroupInfo *) AcquireMagickMemory(
7635 sizeof(*msl_info.group_info));
7636 if ((msl_info.image_info == (ImageInfo **) NULL) ||
7637 (msl_info.image == (Image **) NULL) ||
7638 (msl_info.attributes == (Image **) NULL) ||
7639 (msl_info.group_info == (MSLGroupInfo *) NULL))
7640 ThrowFatalException(ResourceLimitFatalError,
7641 "UnableToInterpretMSLImage");
7642 *msl_info.image_info=CloneImageInfo(image_info);
7643 *msl_info.draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL);
7644 *msl_info.attributes=AcquireImage(image_info);
7645 msl_info.group_info[0].numImages=0;
7646 /* the first slot is used to point to the MSL file image */
7647 *msl_info.image=msl_image;
7648 if (*image != (Image *) NULL)
7649 MSLPushImage(&msl_info,*image);
7650 (void) xmlSubstituteEntitiesDefault(1);
cristy5f6f01c2009-11-19 19:36:42 +00007651 (void) ResetMagickMemory(&sax_modules,0,sizeof(sax_modules));
7652 sax_modules.internalSubset=MSLInternalSubset;
7653 sax_modules.isStandalone=MSLIsStandalone;
7654 sax_modules.hasInternalSubset=MSLHasInternalSubset;
7655 sax_modules.hasExternalSubset=MSLHasExternalSubset;
7656 sax_modules.resolveEntity=MSLResolveEntity;
7657 sax_modules.getEntity=MSLGetEntity;
7658 sax_modules.entityDecl=MSLEntityDeclaration;
7659 sax_modules.notationDecl=MSLNotationDeclaration;
7660 sax_modules.attributeDecl=MSLAttributeDeclaration;
7661 sax_modules.elementDecl=MSLElementDeclaration;
7662 sax_modules.unparsedEntityDecl=MSLUnparsedEntityDeclaration;
7663 sax_modules.setDocumentLocator=MSLSetDocumentLocator;
7664 sax_modules.startDocument=MSLStartDocument;
7665 sax_modules.endDocument=MSLEndDocument;
7666 sax_modules.startElement=MSLStartElement;
7667 sax_modules.endElement=MSLEndElement;
7668 sax_modules.reference=MSLReference;
7669 sax_modules.characters=MSLCharacters;
7670 sax_modules.ignorableWhitespace=MSLIgnorableWhitespace;
7671 sax_modules.processingInstruction=MSLProcessingInstructions;
7672 sax_modules.comment=MSLComment;
7673 sax_modules.warning=MSLWarning;
7674 sax_modules.error=MSLError;
7675 sax_modules.fatalError=MSLError;
7676 sax_modules.getParameterEntity=MSLGetParameterEntity;
7677 sax_modules.cdataBlock=MSLCDataBlock;
7678 sax_modules.externalSubset=MSLExternalSubset;
7679 sax_handler=(&sax_modules);
7680 msl_info.parser=xmlCreatePushParserCtxt(sax_handler,&msl_info,(char *) NULL,0,
cristy3ed852e2009-09-05 21:47:34 +00007681 msl_image->filename);
7682 while (ReadBlobString(msl_image,message) != (char *) NULL)
7683 {
cristybb503372010-05-27 20:51:26 +00007684 n=(ssize_t) strlen(message);
cristy3ed852e2009-09-05 21:47:34 +00007685 if (n == 0)
7686 continue;
7687 status=xmlParseChunk(msl_info.parser,message,(int) n,MagickFalse);
7688 if (status != 0)
7689 break;
7690 (void) xmlParseChunk(msl_info.parser," ",1,MagickFalse);
7691 if (msl_info.exception->severity >= ErrorException)
7692 break;
7693 }
7694 if (msl_info.exception->severity == UndefinedException)
7695 (void) xmlParseChunk(msl_info.parser," ",1,MagickTrue);
7696 xmlFreeParserCtxt(msl_info.parser);
7697 (void) LogMagickEvent(CoderEvent,GetMagickModule(),"end SAX");
7698 xmlCleanupParser();
7699 msl_info.group_info=(MSLGroupInfo *) RelinquishMagickMemory(
7700 msl_info.group_info);
7701 if (*image == (Image *) NULL)
7702 *image=(*msl_info.image);
cristy5f6f01c2009-11-19 19:36:42 +00007703 if ((*msl_info.image)->exception.severity != UndefinedException)
7704 return(MagickFalse);
7705 return(MagickTrue);
cristy3ed852e2009-09-05 21:47:34 +00007706}
7707
7708static Image *ReadMSLImage(const ImageInfo *image_info,ExceptionInfo *exception)
7709{
7710 Image
7711 *image;
7712
7713 /*
7714 Open image file.
7715 */
7716 assert(image_info != (const ImageInfo *) NULL);
7717 assert(image_info->signature == MagickSignature);
7718 if (image_info->debug != MagickFalse)
7719 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
7720 image_info->filename);
7721 assert(exception != (ExceptionInfo *) NULL);
7722 assert(exception->signature == MagickSignature);
7723 image=(Image *) NULL;
7724 (void) ProcessMSLScript(image_info,&image,exception);
7725 return(GetFirstImageInList(image));
7726}
7727#endif
7728
7729/*
7730%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7731% %
7732% %
7733% %
7734% R e g i s t e r M S L I m a g e %
7735% %
7736% %
7737% %
7738%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7739%
7740% RegisterMSLImage() adds attributes for the MSL image format to
7741% the list of supported formats. The attributes include the image format
7742% tag, a method to read and/or write the format, whether the format
7743% supports the saving of more than one frame to the same file or blob,
7744% whether the format supports native in-memory I/O, and a brief
7745% description of the format.
7746%
7747% The format of the RegisterMSLImage method is:
7748%
cristybb503372010-05-27 20:51:26 +00007749% size_t RegisterMSLImage(void)
cristy3ed852e2009-09-05 21:47:34 +00007750%
7751*/
cristybb503372010-05-27 20:51:26 +00007752ModuleExport size_t RegisterMSLImage(void)
cristy3ed852e2009-09-05 21:47:34 +00007753{
7754 MagickInfo
7755 *entry;
7756
7757 entry=SetMagickInfo("MSL");
7758#if defined(MAGICKCORE_XML_DELEGATE)
7759 entry->decoder=(DecodeImageHandler *) ReadMSLImage;
7760 entry->encoder=(EncodeImageHandler *) WriteMSLImage;
7761#endif
7762 entry->description=ConstantString("Magick Scripting Language");
7763 entry->module=ConstantString("MSL");
7764 (void) RegisterMagickInfo(entry);
7765 return(MagickImageCoderSignature);
7766}
7767
cristy6b9f7ed2010-04-24 01:08:02 +00007768#if defined(MAGICKCORE_XML_DELEGATE)
cristy3ed852e2009-09-05 21:47:34 +00007769/*
7770%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7771% %
7772% %
7773% %
cristyb988fe72009-09-16 01:01:10 +00007774% S e t M S L A t t r i b u t e s %
7775% %
7776% %
7777% %
7778%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7779%
7780% SetMSLAttributes() ...
7781%
7782% The format of the SetMSLAttributes method is:
7783%
7784% MagickBooleanType SetMSLAttributes(MSLInfo *msl_info,
cristyb20775d2009-09-16 01:51:41 +00007785% const char *keyword,const char *value)
cristyb988fe72009-09-16 01:01:10 +00007786%
7787% A description of each parameter follows:
7788%
7789% o msl_info: the MSL info.
7790%
cristyb20775d2009-09-16 01:51:41 +00007791% o keyword: the keyword.
7792%
7793% o value: the value.
cristyb988fe72009-09-16 01:01:10 +00007794%
7795*/
cristyb20775d2009-09-16 01:51:41 +00007796static MagickBooleanType SetMSLAttributes(MSLInfo *msl_info,const char *keyword,
7797 const char *value)
cristyb988fe72009-09-16 01:01:10 +00007798{
cristy4582cbb2009-09-23 00:35:43 +00007799 Image
7800 *attributes;
7801
cristyb20775d2009-09-16 01:51:41 +00007802 DrawInfo
7803 *draw_info;
cristyb988fe72009-09-16 01:01:10 +00007804
7805 ExceptionInfo
7806 *exception;
7807
cristy4582cbb2009-09-23 00:35:43 +00007808 GeometryInfo
7809 geometry_info;
7810
cristy4fa36e42009-09-18 14:24:06 +00007811 Image
7812 *image;
7813
cristyb20775d2009-09-16 01:51:41 +00007814 ImageInfo
7815 *image_info;
7816
cristy4582cbb2009-09-23 00:35:43 +00007817 int
7818 flags;
7819
cristybb503372010-05-27 20:51:26 +00007820 ssize_t
cristyb988fe72009-09-16 01:01:10 +00007821 n;
7822
cristyb988fe72009-09-16 01:01:10 +00007823 assert(msl_info != (MSLInfo *) NULL);
cristyb20775d2009-09-16 01:51:41 +00007824 if (keyword == (const char *) NULL)
7825 return(MagickTrue);
7826 if (value == (const char *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007827 return(MagickTrue);
7828 exception=msl_info->exception;
7829 n=msl_info->n;
cristy4582cbb2009-09-23 00:35:43 +00007830 attributes=msl_info->attributes[n];
cristyb20775d2009-09-16 01:51:41 +00007831 image_info=msl_info->image_info[n];
7832 draw_info=msl_info->draw_info[n];
cristy4fa36e42009-09-18 14:24:06 +00007833 image=msl_info->image[n];
cristyb20775d2009-09-16 01:51:41 +00007834 switch (*keyword)
cristyb988fe72009-09-16 01:01:10 +00007835 {
cristyfb758a52009-09-16 14:36:08 +00007836 case 'A':
7837 case 'a':
7838 {
7839 if (LocaleCompare(keyword,"adjoin") == 0)
7840 {
cristybb503372010-05-27 20:51:26 +00007841 ssize_t
cristyfb758a52009-09-16 14:36:08 +00007842 adjoin;
7843
cristy042ee782011-04-22 18:48:30 +00007844 adjoin=ParseCommandOption(MagickBooleanOptions,MagickFalse,value);
cristyfb758a52009-09-16 14:36:08 +00007845 if (adjoin < 0)
7846 ThrowMSLException(OptionError,"UnrecognizedType",value);
7847 image_info->adjoin=(MagickBooleanType) adjoin;
7848 break;
7849 }
cristy4fa36e42009-09-18 14:24:06 +00007850 if (LocaleCompare(keyword,"alpha") == 0)
7851 {
cristybb503372010-05-27 20:51:26 +00007852 ssize_t
cristy4fa36e42009-09-18 14:24:06 +00007853 alpha;
7854
cristy042ee782011-04-22 18:48:30 +00007855 alpha=ParseCommandOption(MagickAlphaOptions,MagickFalse,value);
cristy4fa36e42009-09-18 14:24:06 +00007856 if (alpha < 0)
7857 ThrowMSLException(OptionError,"UnrecognizedType",value);
cristy4582cbb2009-09-23 00:35:43 +00007858 if (image != (Image *) NULL)
cristy63240882011-08-05 19:05:27 +00007859 (void) SetImageAlphaChannel(image,(AlphaChannelType) alpha,
7860 exception);
cristy4582cbb2009-09-23 00:35:43 +00007861 break;
7862 }
7863 if (LocaleCompare(keyword,"antialias") == 0)
7864 {
cristybb503372010-05-27 20:51:26 +00007865 ssize_t
cristy4582cbb2009-09-23 00:35:43 +00007866 antialias;
7867
cristy042ee782011-04-22 18:48:30 +00007868 antialias=ParseCommandOption(MagickBooleanOptions,MagickFalse,value);
cristy4582cbb2009-09-23 00:35:43 +00007869 if (antialias < 0)
7870 ThrowMSLException(OptionError,"UnrecognizedGravityType",value);
7871 image_info->antialias=(MagickBooleanType) antialias;
7872 break;
7873 }
7874 if (LocaleCompare(keyword,"area-limit") == 0)
7875 {
7876 MagickSizeType
7877 limit;
7878
7879 limit=MagickResourceInfinity;
7880 if (LocaleCompare(value,"unlimited") != 0)
cristyf2f27272009-12-17 14:48:46 +00007881 limit=(MagickSizeType) SiPrefixToDouble(value,100.0);
cristy4582cbb2009-09-23 00:35:43 +00007882 (void) SetMagickResourceLimit(AreaResource,limit);
7883 break;
7884 }
7885 if (LocaleCompare(keyword,"attenuate") == 0)
7886 {
7887 (void) SetImageOption(image_info,keyword,value);
7888 break;
7889 }
7890 if (LocaleCompare(keyword,"authenticate") == 0)
7891 {
7892 (void) CloneString(&image_info->density,value);
cristy4fa36e42009-09-18 14:24:06 +00007893 break;
7894 }
cristyfb758a52009-09-16 14:36:08 +00007895 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7896 break;
7897 }
cristyb20775d2009-09-16 01:51:41 +00007898 case 'B':
7899 case 'b':
cristyb988fe72009-09-16 01:01:10 +00007900 {
cristyb20775d2009-09-16 01:51:41 +00007901 if (LocaleCompare(keyword,"background") == 0)
7902 {
cristy2c8b6312009-09-16 02:37:23 +00007903 (void) QueryColorDatabase(value,&image_info->background_color,
cristyb20775d2009-09-16 01:51:41 +00007904 exception);
7905 break;
7906 }
cristy4582cbb2009-09-23 00:35:43 +00007907 if (LocaleCompare(keyword,"bias") == 0)
7908 {
7909 if (image == (Image *) NULL)
7910 break;
cristyf2f27272009-12-17 14:48:46 +00007911 image->bias=SiPrefixToDouble(value,QuantumRange);
cristy4582cbb2009-09-23 00:35:43 +00007912 break;
7913 }
7914 if (LocaleCompare(keyword,"blue-primary") == 0)
7915 {
7916 if (image == (Image *) NULL)
7917 break;
7918 flags=ParseGeometry(value,&geometry_info);
7919 image->chromaticity.blue_primary.x=geometry_info.rho;
7920 image->chromaticity.blue_primary.y=geometry_info.sigma;
7921 if ((flags & SigmaValue) == 0)
7922 image->chromaticity.blue_primary.y=
7923 image->chromaticity.blue_primary.x;
7924 break;
7925 }
cristy2c8b6312009-09-16 02:37:23 +00007926 if (LocaleCompare(keyword,"bordercolor") == 0)
7927 {
7928 (void) QueryColorDatabase(value,&image_info->border_color,
7929 exception);
7930 break;
7931 }
7932 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7933 break;
7934 }
7935 case 'D':
7936 case 'd':
7937 {
7938 if (LocaleCompare(keyword,"density") == 0)
7939 {
7940 (void) CloneString(&image_info->density,value);
7941 (void) CloneString(&draw_info->density,value);
7942 break;
7943 }
cristyb20775d2009-09-16 01:51:41 +00007944 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7945 break;
7946 }
7947 case 'F':
7948 case 'f':
7949 {
7950 if (LocaleCompare(keyword,"fill") == 0)
7951 {
cristy2c8b6312009-09-16 02:37:23 +00007952 (void) QueryColorDatabase(value,&draw_info->fill,exception);
cristya30afaf2009-09-22 13:42:12 +00007953 (void) SetImageOption(image_info,keyword,value);
cristyb20775d2009-09-16 01:51:41 +00007954 break;
7955 }
cristy4582cbb2009-09-23 00:35:43 +00007956 if (LocaleCompare(keyword,"filename") == 0)
7957 {
7958 (void) CopyMagickString(image_info->filename,value,MaxTextExtent);
7959 break;
7960 }
7961 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7962 break;
7963 }
7964 case 'G':
7965 case 'g':
7966 {
7967 if (LocaleCompare(keyword,"gravity") == 0)
7968 {
cristybb503372010-05-27 20:51:26 +00007969 ssize_t
cristy4582cbb2009-09-23 00:35:43 +00007970 gravity;
7971
cristy042ee782011-04-22 18:48:30 +00007972 gravity=ParseCommandOption(MagickGravityOptions,MagickFalse,value);
cristy4582cbb2009-09-23 00:35:43 +00007973 if (gravity < 0)
7974 ThrowMSLException(OptionError,"UnrecognizedGravityType",value);
7975 (void) SetImageOption(image_info,keyword,value);
7976 break;
7977 }
cristyb20775d2009-09-16 01:51:41 +00007978 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7979 break;
7980 }
7981 case 'I':
7982 case 'i':
7983 {
7984 if (LocaleCompare(keyword,"id") == 0)
7985 {
cristy4582cbb2009-09-23 00:35:43 +00007986 (void) SetImageProperty(attributes,keyword,value);
cristy2c8b6312009-09-16 02:37:23 +00007987 break;
7988 }
7989 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7990 break;
7991 }
7992 case 'M':
7993 case 'm':
7994 {
7995 if (LocaleCompare(keyword,"magick") == 0)
7996 {
7997 (void) CopyMagickString(image_info->magick,value,MaxTextExtent);
7998 break;
7999 }
cristy2c8b6312009-09-16 02:37:23 +00008000 if (LocaleCompare(keyword,"mattecolor") == 0)
8001 {
8002 (void) QueryColorDatabase(value,&image_info->matte_color,
8003 exception);
cristyb20775d2009-09-16 01:51:41 +00008004 break;
8005 }
8006 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8007 break;
8008 }
8009 case 'P':
8010 case 'p':
8011 {
8012 if (LocaleCompare(keyword,"pointsize") == 0)
8013 {
cristyc1acd842011-05-19 23:05:47 +00008014 image_info->pointsize=InterpretLocaleValue(value,(char **) NULL);
8015 draw_info->pointsize=InterpretLocaleValue(value,(char **) NULL);
cristyb20775d2009-09-16 01:51:41 +00008016 break;
8017 }
8018 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8019 break;
8020 }
cristy4582cbb2009-09-23 00:35:43 +00008021 case 'Q':
8022 case 'q':
8023 {
8024 if (LocaleCompare(keyword,"quality") == 0)
8025 {
cristyf2f27272009-12-17 14:48:46 +00008026 image_info->quality=StringToLong(value);
cristy4582cbb2009-09-23 00:35:43 +00008027 if (image == (Image *) NULL)
8028 break;
cristyf2f27272009-12-17 14:48:46 +00008029 image->quality=StringToLong(value);
cristy4582cbb2009-09-23 00:35:43 +00008030 break;
8031 }
8032 break;
8033 }
cristyb20775d2009-09-16 01:51:41 +00008034 case 'S':
8035 case 's':
8036 {
8037 if (LocaleCompare(keyword,"size") == 0)
8038 {
cristy2c8b6312009-09-16 02:37:23 +00008039 (void) CloneString(&image_info->size,value);
cristyb20775d2009-09-16 01:51:41 +00008040 break;
8041 }
8042 if (LocaleCompare(keyword,"stroke") == 0)
8043 {
cristy2c8b6312009-09-16 02:37:23 +00008044 (void) QueryColorDatabase(value,&draw_info->stroke,exception);
cristya30afaf2009-09-22 13:42:12 +00008045 (void) SetImageOption(image_info,keyword,value);
cristyb20775d2009-09-16 01:51:41 +00008046 break;
8047 }
8048 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8049 break;
8050 }
8051 default:
8052 {
8053 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8054 break;
cristyb988fe72009-09-16 01:01:10 +00008055 }
8056 }
8057 return(MagickTrue);
8058}
cristy6b9f7ed2010-04-24 01:08:02 +00008059#endif
cristyb988fe72009-09-16 01:01:10 +00008060
8061/*
8062%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8063% %
8064% %
8065% %
cristy3ed852e2009-09-05 21:47:34 +00008066% U n r e g i s t e r M S L I m a g e %
8067% %
8068% %
8069% %
8070%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8071%
8072% UnregisterMSLImage() removes format registrations made by the
8073% MSL module from the list of supported formats.
8074%
8075% The format of the UnregisterMSLImage method is:
8076%
8077% UnregisterMSLImage(void)
8078%
8079*/
8080ModuleExport void UnregisterMSLImage(void)
8081{
8082 (void) UnregisterMagickInfo("MSL");
8083}
8084
8085#if defined(MAGICKCORE_XML_DELEGATE)
8086/*
8087%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8088% %
8089% %
8090% %
8091% W r i t e M S L I m a g e %
8092% %
8093% %
8094% %
8095%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8096%
8097% WriteMSLImage() writes an image to a file in MVG image format.
8098%
8099% The format of the WriteMSLImage method is:
8100%
8101% MagickBooleanType WriteMSLImage(const ImageInfo *image_info,Image *image)
8102%
8103% A description of each parameter follows.
8104%
8105% o image_info: the image info.
8106%
8107% o image: The image.
8108%
8109*/
8110static MagickBooleanType WriteMSLImage(const ImageInfo *image_info,Image *image)
8111{
8112 assert(image_info != (const ImageInfo *) NULL);
8113 assert(image_info->signature == MagickSignature);
8114 assert(image != (Image *) NULL);
8115 assert(image->signature == MagickSignature);
8116 if (image->debug != MagickFalse)
8117 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
8118 (void) ReferenceImage(image);
8119 (void) ProcessMSLScript(image_info,&image,&image->exception);
8120 return(MagickTrue);
8121}
8122#endif