blob: 7d05cff70ac3581c27619003ab39ae32122d0598 [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% %
cristy1454be72011-12-19 01:52:48 +000022% Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization %
cristy3ed852e2009-09-05 21:47:34 +000023% dedicated to making software imaging solutions freely available. %
24% %
25% You may not use this file except in compliance with the License. You may %
26% obtain a copy of the License at %
27% %
28% http://www.imagemagick.org/script/license.php %
29% %
30% Unless required by applicable law or agreed to in writing, software %
31% distributed under the License is distributed on an "AS IS" BASIS, %
32% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
33% See the License for the specific language governing permissions and %
34% limitations under the License. %
35% %
36%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
37%
38%
39*/
40
41/*
42 Include declarations.
43*/
cristy4c08aed2011-07-01 19:47:50 +000044#include "MagickCore/studio.h"
45#include "MagickCore/annotate.h"
46#include "MagickCore/artifact.h"
47#include "MagickCore/blob.h"
48#include "MagickCore/blob-private.h"
49#include "MagickCore/cache.h"
50#include "MagickCore/cache-view.h"
51#include "MagickCore/color.h"
cristy4c08aed2011-07-01 19:47:50 +000052#include "MagickCore/color-private.h"
cristy9950d572011-10-01 18:22:35 +000053#include "MagickCore/colormap.h"
cristy4c08aed2011-07-01 19:47:50 +000054#include "MagickCore/composite.h"
55#include "MagickCore/constitute.h"
56#include "MagickCore/decorate.h"
57#include "MagickCore/display.h"
cristyc53413d2011-11-17 13:04:26 +000058#include "MagickCore/distort.h"
cristy4c08aed2011-07-01 19:47:50 +000059#include "MagickCore/draw.h"
60#include "MagickCore/effect.h"
61#include "MagickCore/enhance.h"
62#include "MagickCore/exception.h"
63#include "MagickCore/exception-private.h"
64#include "MagickCore/fx.h"
65#include "MagickCore/geometry.h"
66#include "MagickCore/image.h"
67#include "MagickCore/image-private.h"
68#include "MagickCore/list.h"
69#include "MagickCore/log.h"
70#include "MagickCore/magick.h"
71#include "MagickCore/memory_.h"
72#include "MagickCore/module.h"
73#include "MagickCore/option.h"
74#include "MagickCore/paint.h"
75#include "MagickCore/pixel-accessor.h"
76#include "MagickCore/profile.h"
77#include "MagickCore/property.h"
78#include "MagickCore/quantize.h"
79#include "MagickCore/quantum-private.h"
80#include "MagickCore/registry.h"
81#include "MagickCore/resize.h"
82#include "MagickCore/resource_.h"
83#include "MagickCore/segment.h"
cristy28039352011-11-17 13:15:46 +000084#include "MagickCore/shear.h"
cristy4c08aed2011-07-01 19:47:50 +000085#include "MagickCore/signature.h"
cristy7497f482011-12-08 01:57:31 +000086#include "MagickCore/statistic.h"
cristy4c08aed2011-07-01 19:47:50 +000087#include "MagickCore/static.h"
88#include "MagickCore/string_.h"
89#include "MagickCore/string-private.h"
90#include "MagickCore/transform.h"
91#include "MagickCore/threshold.h"
92#include "MagickCore/utility.h"
cristy3ed852e2009-09-05 21:47:34 +000093#if defined(MAGICKCORE_XML_DELEGATE)
cristy0157aea2010-04-24 21:12:18 +000094# if defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +000095# if defined(__MINGW32__)
96# define _MSC_VER
97# else
98# include <win32config.h>
99# endif
100# endif
101# include <libxml/parser.h>
102# include <libxml/xmlmemory.h>
103# include <libxml/parserInternals.h>
104# include <libxml/xmlerror.h>
105#endif
106
107/*
108 Define Declatations.
109*/
110#define ThrowMSLException(severity,tag,reason) \
111 (void) ThrowMagickException(msl_info->exception,GetMagickModule(),severity, \
112 tag,"`%s'",reason);
113
114/*
115 Typedef declaractions.
116*/
117typedef struct _MSLGroupInfo
118{
cristybb503372010-05-27 20:51:26 +0000119 size_t
cristy3ed852e2009-09-05 21:47:34 +0000120 numImages; /* how many images are in this group */
121} MSLGroupInfo;
122
123typedef struct _MSLInfo
124{
125 ExceptionInfo
126 *exception;
127
cristybb503372010-05-27 20:51:26 +0000128 ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000129 n,
130 number_groups;
131
132 ImageInfo
133 **image_info;
134
135 DrawInfo
136 **draw_info;
137
138 Image
139 **attributes,
140 **image;
141
142 char
143 *content;
144
145 MSLGroupInfo
146 *group_info;
147
148#if defined(MAGICKCORE_XML_DELEGATE)
149 xmlParserCtxtPtr
150 parser;
151
152 xmlDocPtr
153 document;
154#endif
155} MSLInfo;
156
157/*
158 Forward declarations.
159*/
160#if defined(MAGICKCORE_XML_DELEGATE)
161static MagickBooleanType
cristy1e178e72011-08-28 19:44:34 +0000162 WriteMSLImage(const ImageInfo *,Image *,ExceptionInfo *);
cristyb988fe72009-09-16 01:01:10 +0000163
164static MagickBooleanType
cristyb20775d2009-09-16 01:51:41 +0000165 SetMSLAttributes(MSLInfo *,const char *,const char *);
cristy3ed852e2009-09-05 21:47:34 +0000166#endif
167
168#if defined(MAGICKCORE_XML_DELEGATE)
cristyb988fe72009-09-16 01:01:10 +0000169
cristy3ed852e2009-09-05 21:47:34 +0000170/*
171%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
172% %
173% %
174% %
175% R e a d M S L I m a g e %
176% %
177% %
178% %
179%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
180%
181% ReadMSLImage() reads a Magick Scripting Language file and returns it.
182% It allocates the memory necessary for the new Image structure and returns a
183% pointer to the new image.
184%
185% The format of the ReadMSLImage method is:
186%
187% Image *ReadMSLImage(const ImageInfo *image_info,ExceptionInfo *exception)
188%
189% A description of each parameter follows:
190%
191% o image_info: the image info.
192%
193% o exception: return any errors or warnings in this structure.
194%
cristy3ed852e2009-09-05 21:47:34 +0000195*/
196
197#if defined(__cplusplus) || defined(c_plusplus)
198extern "C" {
199#endif
200
cristy4fa36e42009-09-18 14:24:06 +0000201static inline Image *GetImageCache(const ImageInfo *image_info,const char *path,
202 ExceptionInfo *exception)
203{
204 char
205 key[MaxTextExtent];
206
207 ExceptionInfo
208 *sans_exception;
209
210 Image
211 *image;
212
213 ImageInfo
214 *read_info;
215
cristyb51dff52011-05-19 16:55:47 +0000216 (void) FormatLocaleString(key,MaxTextExtent,"cache:%s",path);
cristy4fa36e42009-09-18 14:24:06 +0000217 sans_exception=AcquireExceptionInfo();
218 image=(Image *) GetImageRegistry(ImageRegistryType,key,sans_exception);
219 sans_exception=DestroyExceptionInfo(sans_exception);
220 if (image != (Image *) NULL)
221 return(image);
222 read_info=CloneImageInfo(image_info);
223 (void) CopyMagickString(read_info->filename,path,MaxTextExtent);
224 image=ReadImage(read_info,exception);
225 read_info=DestroyImageInfo(read_info);
226 if (image != (Image *) NULL)
227 (void) SetImageRegistry(ImageRegistryType,key,image,exception);
228 return(image);
229}
230
231static int IsPathDirectory(const char *path)
232{
233 MagickBooleanType
234 status;
235
236 struct stat
237 attributes;
238
239 if ((path == (const char *) NULL) || (*path == '\0'))
240 return(MagickFalse);
241 status=GetPathAttributes(path,&attributes);
242 if (status == MagickFalse)
243 return(-1);
244 if (S_ISDIR(attributes.st_mode) == 0)
245 return(0);
246 return(1);
247}
248
cristy3ed852e2009-09-05 21:47:34 +0000249static int MSLIsStandalone(void *context)
250{
251 MSLInfo
252 *msl_info;
253
254 /*
255 Is this document tagged standalone?
256 */
257 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.MSLIsStandalone()");
258 msl_info=(MSLInfo *) context;
259 return(msl_info->document->standalone == 1);
260}
261
262static int MSLHasInternalSubset(void *context)
263{
264 MSLInfo
265 *msl_info;
266
267 /*
268 Does this document has an internal subset?
269 */
270 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
271 " SAX.MSLHasInternalSubset()");
272 msl_info=(MSLInfo *) context;
273 return(msl_info->document->intSubset != NULL);
274}
275
276static int MSLHasExternalSubset(void *context)
277{
278 MSLInfo
279 *msl_info;
280
281 /*
282 Does this document has an external subset?
283 */
284 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
285 " SAX.MSLHasExternalSubset()");
286 msl_info=(MSLInfo *) context;
287 return(msl_info->document->extSubset != NULL);
288}
289
290static void MSLInternalSubset(void *context,const xmlChar *name,
291 const xmlChar *external_id,const xmlChar *system_id)
292{
293 MSLInfo
294 *msl_info;
295
296 /*
297 Does this document has an internal subset?
298 */
299 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
300 " SAX.internalSubset(%s %s %s)",name,
cristyb988fe72009-09-16 01:01:10 +0000301 (external_id != (const xmlChar *) NULL ? (const char *) external_id : " "),
302 (system_id != (const xmlChar *) NULL ? (const char *) system_id : " "));
cristy3ed852e2009-09-05 21:47:34 +0000303 msl_info=(MSLInfo *) context;
304 (void) xmlCreateIntSubset(msl_info->document,name,external_id,system_id);
305}
306
307static xmlParserInputPtr MSLResolveEntity(void *context,
308 const xmlChar *public_id,const xmlChar *system_id)
309{
310 MSLInfo
311 *msl_info;
312
313 xmlParserInputPtr
314 stream;
315
316 /*
317 Special entity resolver, better left to the parser, it has more
318 context than the application layer. The default behaviour is to
319 not resolve the entities, in that case the ENTITY_REF nodes are
320 built in the structure (and the parameter values).
321 */
322 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
323 " SAX.resolveEntity(%s, %s)",
cristyb988fe72009-09-16 01:01:10 +0000324 (public_id != (const xmlChar *) NULL ? (const char *) public_id : "none"),
325 (system_id != (const xmlChar *) NULL ? (const char *) system_id : "none"));
cristy3ed852e2009-09-05 21:47:34 +0000326 msl_info=(MSLInfo *) context;
327 stream=xmlLoadExternalEntity((const char *) system_id,(const char *)
328 public_id,msl_info->parser);
329 return(stream);
330}
331
332static xmlEntityPtr MSLGetEntity(void *context,const xmlChar *name)
333{
334 MSLInfo
335 *msl_info;
336
337 /*
338 Get an entity by name.
339 */
340 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
cristyb988fe72009-09-16 01:01:10 +0000341 " SAX.MSLGetEntity(%s)",(const char *) name);
cristy3ed852e2009-09-05 21:47:34 +0000342 msl_info=(MSLInfo *) context;
343 return(xmlGetDocEntity(msl_info->document,name));
344}
345
346static xmlEntityPtr MSLGetParameterEntity(void *context,const xmlChar *name)
347{
348 MSLInfo
349 *msl_info;
350
351 /*
352 Get a parameter entity by name.
353 */
354 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
cristyb988fe72009-09-16 01:01:10 +0000355 " SAX.getParameterEntity(%s)",(const char *) name);
cristy3ed852e2009-09-05 21:47:34 +0000356 msl_info=(MSLInfo *) context;
357 return(xmlGetParameterEntity(msl_info->document,name));
358}
359
360static void MSLEntityDeclaration(void *context,const xmlChar *name,int type,
361 const xmlChar *public_id,const xmlChar *system_id,xmlChar *content)
362{
363 MSLInfo
364 *msl_info;
365
366 /*
367 An entity definition has been parsed.
368 */
369 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
370 " SAX.entityDecl(%s, %d, %s, %s, %s)",name,type,
cristyb988fe72009-09-16 01:01:10 +0000371 public_id != (const xmlChar *) NULL ? (const char *) public_id : "none",
372 system_id != (const xmlChar *) NULL ? (const char *) system_id : "none",
373 content);
cristy3ed852e2009-09-05 21:47:34 +0000374 msl_info=(MSLInfo *) context;
375 if (msl_info->parser->inSubset == 1)
376 (void) xmlAddDocEntity(msl_info->document,name,type,public_id,system_id,
377 content);
378 else
379 if (msl_info->parser->inSubset == 2)
380 (void) xmlAddDtdEntity(msl_info->document,name,type,public_id,system_id,
381 content);
382}
383
384static void MSLAttributeDeclaration(void *context,const xmlChar *element,
385 const xmlChar *name,int type,int value,const xmlChar *default_value,
386 xmlEnumerationPtr tree)
387{
388 MSLInfo
389 *msl_info;
390
391 xmlChar
392 *fullname,
393 *prefix;
394
395 xmlParserCtxtPtr
396 parser;
397
398 /*
399 An attribute definition has been parsed.
400 */
401 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
402 " SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",element,name,type,value,
403 default_value);
404 msl_info=(MSLInfo *) context;
405 fullname=(xmlChar *) NULL;
406 prefix=(xmlChar *) NULL;
407 parser=msl_info->parser;
408 fullname=(xmlChar *) xmlSplitQName(parser,name,&prefix);
409 if (parser->inSubset == 1)
410 (void) xmlAddAttributeDecl(&parser->vctxt,msl_info->document->intSubset,
411 element,fullname,prefix,(xmlAttributeType) type,
412 (xmlAttributeDefault) value,default_value,tree);
413 else
414 if (parser->inSubset == 2)
415 (void) xmlAddAttributeDecl(&parser->vctxt,msl_info->document->extSubset,
416 element,fullname,prefix,(xmlAttributeType) type,
417 (xmlAttributeDefault) value,default_value,tree);
418 if (prefix != (xmlChar *) NULL)
419 xmlFree(prefix);
420 if (fullname != (xmlChar *) NULL)
421 xmlFree(fullname);
422}
423
424static void MSLElementDeclaration(void *context,const xmlChar *name,int type,
425 xmlElementContentPtr content)
426{
427 MSLInfo
428 *msl_info;
429
430 xmlParserCtxtPtr
431 parser;
432
433 /*
434 An element definition has been parsed.
435 */
436 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
437 " SAX.elementDecl(%s, %d, ...)",name,type);
438 msl_info=(MSLInfo *) context;
439 parser=msl_info->parser;
440 if (parser->inSubset == 1)
441 (void) xmlAddElementDecl(&parser->vctxt,msl_info->document->intSubset,
442 name,(xmlElementTypeVal) type,content);
443 else
444 if (parser->inSubset == 2)
445 (void) xmlAddElementDecl(&parser->vctxt,msl_info->document->extSubset,
446 name,(xmlElementTypeVal) type,content);
447}
448
449static void MSLNotationDeclaration(void *context,const xmlChar *name,
450 const xmlChar *public_id,const xmlChar *system_id)
451{
452 MSLInfo
453 *msl_info;
454
455 xmlParserCtxtPtr
456 parser;
457
458 /*
459 What to do when a notation declaration has been parsed.
460 */
461 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
462 " SAX.notationDecl(%s, %s, %s)",name,
cristyb988fe72009-09-16 01:01:10 +0000463 public_id != (const xmlChar *) NULL ? (const char *) public_id : "none",
464 system_id != (const xmlChar *) NULL ? (const char *) system_id : "none");
cristy3ed852e2009-09-05 21:47:34 +0000465 msl_info=(MSLInfo *) context;
466 parser=msl_info->parser;
467 if (parser->inSubset == 1)
468 (void) xmlAddNotationDecl(&parser->vctxt,msl_info->document->intSubset,
469 name,public_id,system_id);
470 else
471 if (parser->inSubset == 2)
472 (void) xmlAddNotationDecl(&parser->vctxt,msl_info->document->intSubset,
473 name,public_id,system_id);
474}
475
476static void MSLUnparsedEntityDeclaration(void *context,const xmlChar *name,
477 const xmlChar *public_id,const xmlChar *system_id,const xmlChar *notation)
478{
479 MSLInfo
480 *msl_info;
481
482 /*
483 What to do when an unparsed entity declaration is parsed.
484 */
485 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
486 " SAX.unparsedEntityDecl(%s, %s, %s, %s)",name,
cristyb988fe72009-09-16 01:01:10 +0000487 public_id != (const xmlChar *) NULL ? (const char *) public_id : "none",
488 system_id != (const xmlChar *) NULL ? (const char *) system_id : "none",
489 notation);
cristy3ed852e2009-09-05 21:47:34 +0000490 msl_info=(MSLInfo *) context;
491 (void) xmlAddDocEntity(msl_info->document,name,
492 XML_EXTERNAL_GENERAL_UNPARSED_ENTITY,public_id,system_id,notation);
493
494}
495
496static void MSLSetDocumentLocator(void *context,xmlSAXLocatorPtr location)
497{
498 MSLInfo
499 *msl_info;
500
501 /*
502 Receive the document locator at startup, actually xmlDefaultSAXLocator.
503 */
504 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
505 " SAX.setDocumentLocator()\n");
506 (void) location;
507 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +0000508 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +0000509}
510
511static void MSLStartDocument(void *context)
512{
513 MSLInfo
514 *msl_info;
515
516 xmlParserCtxtPtr
517 parser;
518
519 /*
520 Called when the document start being processed.
521 */
522 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
523 " SAX.startDocument()");
524 msl_info=(MSLInfo *) context;
525 parser=msl_info->parser;
526 msl_info->document=xmlNewDoc(parser->version);
527 if (msl_info->document == (xmlDocPtr) NULL)
528 return;
529 if (parser->encoding == NULL)
530 msl_info->document->encoding=NULL;
531 else
532 msl_info->document->encoding=xmlStrdup(parser->encoding);
533 msl_info->document->standalone=parser->standalone;
534}
535
536static void MSLEndDocument(void *context)
537{
538 MSLInfo
539 *msl_info;
540
541 /*
542 Called when the document end has been detected.
543 */
544 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.endDocument()");
545 msl_info=(MSLInfo *) context;
546 if (msl_info->content != (char *) NULL)
547 msl_info->content=DestroyString(msl_info->content);
548}
549
550static void MSLPushImage(MSLInfo *msl_info,Image *image)
551{
cristybb503372010-05-27 20:51:26 +0000552 ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000553 n;
554
555 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
556 assert(msl_info != (MSLInfo *) NULL);
557 msl_info->n++;
558 n=msl_info->n;
559 msl_info->image_info=(ImageInfo **) ResizeQuantumMemory(msl_info->image_info,
560 (n+1),sizeof(*msl_info->image_info));
561 msl_info->draw_info=(DrawInfo **) ResizeQuantumMemory(msl_info->draw_info,
562 (n+1),sizeof(*msl_info->draw_info));
563 msl_info->attributes=(Image **) ResizeQuantumMemory(msl_info->attributes,
564 (n+1),sizeof(*msl_info->attributes));
565 msl_info->image=(Image **) ResizeQuantumMemory(msl_info->image,(n+1),
566 sizeof(*msl_info->image));
567 if ((msl_info->image_info == (ImageInfo **) NULL) ||
568 (msl_info->draw_info == (DrawInfo **) NULL) ||
569 (msl_info->attributes == (Image **) NULL) ||
570 (msl_info->image == (Image **) NULL))
571 ThrowMSLException(ResourceLimitFatalError,"MemoryAllocationFailed","msl");
572 msl_info->image_info[n]=CloneImageInfo(msl_info->image_info[n-1]);
573 msl_info->draw_info[n]=CloneDrawInfo(msl_info->image_info[n-1],
574 msl_info->draw_info[n-1]);
575 if (image == (Image *) NULL)
cristy9950d572011-10-01 18:22:35 +0000576 msl_info->attributes[n]=AcquireImage(msl_info->image_info[n],
cristyc82a27b2011-10-21 01:07:16 +0000577 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +0000578 else
cristyc82a27b2011-10-21 01:07:16 +0000579 msl_info->attributes[n]=CloneImage(image,0,0,MagickTrue,
580 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +0000581 msl_info->image[n]=(Image *) image;
582 if ((msl_info->image_info[n] == (ImageInfo *) NULL) ||
583 (msl_info->attributes[n] == (Image *) NULL))
584 ThrowMSLException(ResourceLimitFatalError,"MemoryAllocationFailed","msl");
585 if (msl_info->number_groups != 0)
586 msl_info->group_info[msl_info->number_groups-1].numImages++;
587}
588
589static void MSLPopImage(MSLInfo *msl_info)
590{
591 if (msl_info->number_groups != 0)
592 return;
593 if (msl_info->image[msl_info->n] != (Image *) NULL)
594 msl_info->image[msl_info->n]=DestroyImage(msl_info->image[msl_info->n]);
595 msl_info->attributes[msl_info->n]=DestroyImage(
596 msl_info->attributes[msl_info->n]);
597 msl_info->image_info[msl_info->n]=DestroyImageInfo(
598 msl_info->image_info[msl_info->n]);
599 msl_info->n--;
600}
601
602static void MSLStartElement(void *context,const xmlChar *tag,
603 const xmlChar **attributes)
604{
605 AffineMatrix
606 affine,
607 current;
608
609 ChannelType
610 channel;
611
cristybd5a96c2011-08-21 00:04:26 +0000612 ChannelType
613 channel_mask;
614
cristy3ed852e2009-09-05 21:47:34 +0000615 char
616 key[MaxTextExtent],
617 *value;
618
619 const char
620 *attribute,
621 *keyword;
622
623 double
624 angle;
625
626 DrawInfo
627 *draw_info;
628
629 ExceptionInfo
630 exception;
631
632 GeometryInfo
633 geometry_info;
634
635 Image
636 *image;
637
638 int
639 flags;
640
cristybb503372010-05-27 20:51:26 +0000641 ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000642 option,
643 j,
644 n,
645 x,
646 y;
647
648 MSLInfo
649 *msl_info;
650
651 RectangleInfo
652 geometry;
653
cristybb503372010-05-27 20:51:26 +0000654 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000655 i;
656
cristybb503372010-05-27 20:51:26 +0000657 size_t
cristy3ed852e2009-09-05 21:47:34 +0000658 height,
659 width;
660
661 /*
662 Called when an opening tag has been processed.
663 */
664 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
665 " SAX.startElement(%s",tag);
666 GetExceptionInfo(&exception);
667 msl_info=(MSLInfo *) context;
668 n=msl_info->n;
669 keyword=(const char *) NULL;
670 value=(char *) NULL;
671 SetGeometryInfo(&geometry_info);
672 channel=DefaultChannels;
673 switch (*tag)
674 {
675 case 'A':
676 case 'a':
677 {
cristyb988fe72009-09-16 01:01:10 +0000678 if (LocaleCompare((const char *) tag,"add-noise") == 0)
cristy3ed852e2009-09-05 21:47:34 +0000679 {
680 Image
681 *noise_image;
682
683 NoiseType
684 noise;
685
686 /*
687 Add noise image.
688 */
689 if (msl_info->image[n] == (Image *) NULL)
690 {
cristyb988fe72009-09-16 01:01:10 +0000691 ThrowMSLException(OptionError,"NoImagesDefined",
692 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +0000693 break;
694 }
695 noise=UniformNoise;
696 if (attributes != (const xmlChar **) NULL)
697 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
698 {
699 keyword=(const char *) attributes[i++];
700 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +0000701 msl_info->attributes[n],(const char *) attributes[i],
702 &exception);
cristy3ed852e2009-09-05 21:47:34 +0000703 CloneString(&value,attribute);
704 switch (*keyword)
705 {
706 case 'C':
707 case 'c':
708 {
709 if (LocaleCompare(keyword,"channel") == 0)
710 {
711 option=ParseChannelOption(value);
712 if (option < 0)
713 ThrowMSLException(OptionError,"UnrecognizedChannelType",
714 value);
715 channel=(ChannelType) option;
716 break;
717 }
718 ThrowMSLException(OptionError,"UnrecognizedAttribute",
719 keyword);
720 break;
721 }
722 case 'N':
723 case 'n':
724 {
725 if (LocaleCompare(keyword,"noise") == 0)
726 {
cristy042ee782011-04-22 18:48:30 +0000727 option=ParseCommandOption(MagickNoiseOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +0000728 value);
729 if (option < 0)
730 ThrowMSLException(OptionError,"UnrecognizedNoiseType",
731 value);
732 noise=(NoiseType) option;
733 break;
734 }
735 ThrowMSLException(OptionError,"UnrecognizedAttribute",
736 keyword);
737 break;
738 }
739 default:
740 {
741 ThrowMSLException(OptionError,"UnrecognizedAttribute",
742 keyword);
743 break;
744 }
745 }
746 }
cristybd5a96c2011-08-21 00:04:26 +0000747 channel_mask=SetPixelChannelMask(msl_info->image[n],channel);
cristy9ed1f812011-10-08 02:00:08 +0000748 noise_image=AddNoiseImage(msl_info->image[n],noise,1.0,
cristyc82a27b2011-10-21 01:07:16 +0000749 msl_info->exception);
cristye2a912b2011-12-05 20:02:07 +0000750 (void) SetPixelChannelMapMask(msl_info->image[n],channel_mask);
cristy3ed852e2009-09-05 21:47:34 +0000751 if (noise_image == (Image *) NULL)
752 break;
753 msl_info->image[n]=DestroyImage(msl_info->image[n]);
754 msl_info->image[n]=noise_image;
755 break;
756 }
cristyb988fe72009-09-16 01:01:10 +0000757 if (LocaleCompare((const char *) tag,"annotate") == 0)
cristy3ed852e2009-09-05 21:47:34 +0000758 {
759 char
760 text[MaxTextExtent];
761
762 /*
763 Annotate image.
764 */
765 if (msl_info->image[n] == (Image *) NULL)
766 {
cristyb988fe72009-09-16 01:01:10 +0000767 ThrowMSLException(OptionError,"NoImagesDefined",
768 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +0000769 break;
770 }
771 draw_info=CloneDrawInfo(msl_info->image_info[n],
772 msl_info->draw_info[n]);
773 angle=0.0;
774 current=draw_info->affine;
775 GetAffineMatrix(&affine);
776 if (attributes != (const xmlChar **) NULL)
777 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
778 {
779 keyword=(const char *) attributes[i++];
780 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +0000781 msl_info->attributes[n],(const char *) attributes[i],
782 &exception);
cristy3ed852e2009-09-05 21:47:34 +0000783 CloneString(&value,attribute);
784 switch (*keyword)
785 {
786 case 'A':
787 case 'a':
788 {
789 if (LocaleCompare(keyword,"affine") == 0)
790 {
791 char
792 *p;
793
794 p=value;
cristydbdd0e32011-11-04 23:29:40 +0000795 draw_info->affine.sx=StringToDouble(p,&p);
cristy3ed852e2009-09-05 21:47:34 +0000796 if (*p ==',')
797 p++;
cristydbdd0e32011-11-04 23:29:40 +0000798 draw_info->affine.rx=StringToDouble(p,&p);
cristy3ed852e2009-09-05 21:47:34 +0000799 if (*p ==',')
800 p++;
cristydbdd0e32011-11-04 23:29:40 +0000801 draw_info->affine.ry=StringToDouble(p,&p);
cristy3ed852e2009-09-05 21:47:34 +0000802 if (*p ==',')
803 p++;
cristydbdd0e32011-11-04 23:29:40 +0000804 draw_info->affine.sy=StringToDouble(p,&p);
cristy3ed852e2009-09-05 21:47:34 +0000805 if (*p ==',')
806 p++;
cristydbdd0e32011-11-04 23:29:40 +0000807 draw_info->affine.tx=StringToDouble(p,&p);
cristy3ed852e2009-09-05 21:47:34 +0000808 if (*p ==',')
809 p++;
cristydbdd0e32011-11-04 23:29:40 +0000810 draw_info->affine.ty=StringToDouble(p,&p);
cristy3ed852e2009-09-05 21:47:34 +0000811 break;
812 }
813 if (LocaleCompare(keyword,"align") == 0)
814 {
cristy042ee782011-04-22 18:48:30 +0000815 option=ParseCommandOption(MagickAlignOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +0000816 value);
817 if (option < 0)
818 ThrowMSLException(OptionError,"UnrecognizedAlignType",
819 value);
820 draw_info->align=(AlignType) option;
821 break;
822 }
823 if (LocaleCompare(keyword,"antialias") == 0)
824 {
cristy9b34e302011-11-05 02:15:45 +0000825 option=ParseCommandOption(MagickBooleanOptions,
826 MagickFalse,value);
cristy3ed852e2009-09-05 21:47:34 +0000827 if (option < 0)
828 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
829 value);
830 draw_info->stroke_antialias=(MagickBooleanType) option;
831 draw_info->text_antialias=(MagickBooleanType) option;
832 break;
833 }
834 ThrowMSLException(OptionError,"UnrecognizedAttribute",
835 keyword);
836 break;
837 }
838 case 'D':
839 case 'd':
840 {
841 if (LocaleCompare(keyword,"density") == 0)
842 {
843 CloneString(&draw_info->density,value);
844 break;
845 }
846 ThrowMSLException(OptionError,"UnrecognizedAttribute",
847 keyword);
848 break;
849 }
850 case 'E':
851 case 'e':
852 {
853 if (LocaleCompare(keyword,"encoding") == 0)
854 {
855 CloneString(&draw_info->encoding,value);
856 break;
857 }
858 ThrowMSLException(OptionError,"UnrecognizedAttribute",
859 keyword);
860 break;
861 }
862 case 'F':
863 case 'f':
864 {
865 if (LocaleCompare(keyword, "fill") == 0)
866 {
cristy9950d572011-10-01 18:22:35 +0000867 (void) QueryColorCompliance(value,AllCompliance,
868 &draw_info->fill,&exception);
cristy3ed852e2009-09-05 21:47:34 +0000869 break;
870 }
871 if (LocaleCompare(keyword,"family") == 0)
872 {
873 CloneString(&draw_info->family,value);
874 break;
875 }
876 if (LocaleCompare(keyword,"font") == 0)
877 {
878 CloneString(&draw_info->font,value);
879 break;
880 }
881 ThrowMSLException(OptionError,"UnrecognizedAttribute",
882 keyword);
883 break;
884 }
885 case 'G':
886 case 'g':
887 {
888 if (LocaleCompare(keyword,"geometry") == 0)
889 {
cristy860f4e12011-07-28 19:00:28 +0000890 flags=ParseGravityGeometry(msl_info->image[n],value,
cristy3ed852e2009-09-05 21:47:34 +0000891 &geometry,&exception);
cristy3ed852e2009-09-05 21:47:34 +0000892 break;
893 }
894 if (LocaleCompare(keyword,"gravity") == 0)
895 {
cristy860f4e12011-07-28 19:00:28 +0000896 option=ParseCommandOption(MagickGravityOptions,
897 MagickFalse,value);
cristy3ed852e2009-09-05 21:47:34 +0000898 if (option < 0)
899 ThrowMSLException(OptionError,"UnrecognizedGravityType",
900 value);
901 draw_info->gravity=(GravityType) option;
902 break;
903 }
904 ThrowMSLException(OptionError,"UnrecognizedAttribute",
905 keyword);
906 break;
907 }
908 case 'P':
909 case 'p':
910 {
911 if (LocaleCompare(keyword,"pointsize") == 0)
912 {
cristy9b34e302011-11-05 02:15:45 +0000913 draw_info->pointsize=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000914 break;
915 }
916 ThrowMSLException(OptionError,"UnrecognizedAttribute",
917 keyword);
918 break;
919 }
920 case 'R':
921 case 'r':
922 {
923 if (LocaleCompare(keyword,"rotate") == 0)
924 {
cristydbdd0e32011-11-04 23:29:40 +0000925 angle=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000926 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
927 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
928 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
929 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
930 break;
931 }
932 ThrowMSLException(OptionError,"UnrecognizedAttribute",
933 keyword);
934 break;
935 }
936 case 'S':
937 case 's':
938 {
939 if (LocaleCompare(keyword,"scale") == 0)
940 {
941 flags=ParseGeometry(value,&geometry_info);
942 if ((flags & SigmaValue) == 0)
943 geometry_info.sigma=1.0;
944 affine.sx=geometry_info.rho;
945 affine.sy=geometry_info.sigma;
946 break;
947 }
948 if (LocaleCompare(keyword,"skewX") == 0)
949 {
cristydbdd0e32011-11-04 23:29:40 +0000950 angle=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000951 affine.ry=tan(DegreesToRadians(fmod((double) angle,
952 360.0)));
953 break;
954 }
955 if (LocaleCompare(keyword,"skewY") == 0)
956 {
cristydbdd0e32011-11-04 23:29:40 +0000957 angle=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000958 affine.rx=tan(DegreesToRadians(fmod((double) angle,
959 360.0)));
960 break;
961 }
962 if (LocaleCompare(keyword,"stretch") == 0)
963 {
cristy9950d572011-10-01 18:22:35 +0000964 option=ParseCommandOption(MagickStretchOptions,
965 MagickFalse,value);
cristy3ed852e2009-09-05 21:47:34 +0000966 if (option < 0)
967 ThrowMSLException(OptionError,"UnrecognizedStretchType",
968 value);
969 draw_info->stretch=(StretchType) option;
970 break;
971 }
972 if (LocaleCompare(keyword, "stroke") == 0)
973 {
cristy9950d572011-10-01 18:22:35 +0000974 (void) QueryColorCompliance(value,AllCompliance,
975 &draw_info->stroke,&exception);
cristy3ed852e2009-09-05 21:47:34 +0000976 break;
977 }
978 if (LocaleCompare(keyword,"strokewidth") == 0)
979 {
cristyf2f27272009-12-17 14:48:46 +0000980 draw_info->stroke_width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +0000981 break;
982 }
983 if (LocaleCompare(keyword,"style") == 0)
984 {
cristy042ee782011-04-22 18:48:30 +0000985 option=ParseCommandOption(MagickStyleOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +0000986 value);
987 if (option < 0)
988 ThrowMSLException(OptionError,"UnrecognizedStyleType",
989 value);
990 draw_info->style=(StyleType) option;
991 break;
992 }
993 ThrowMSLException(OptionError,"UnrecognizedAttribute",
994 keyword);
995 break;
996 }
997 case 'T':
998 case 't':
999 {
1000 if (LocaleCompare(keyword,"text") == 0)
1001 {
1002 CloneString(&draw_info->text,value);
1003 break;
1004 }
1005 if (LocaleCompare(keyword,"translate") == 0)
1006 {
1007 flags=ParseGeometry(value,&geometry_info);
1008 if ((flags & SigmaValue) == 0)
1009 geometry_info.sigma=1.0;
1010 affine.tx=geometry_info.rho;
1011 affine.ty=geometry_info.sigma;
1012 break;
1013 }
1014 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1015 keyword);
1016 break;
1017 }
1018 case 'U':
1019 case 'u':
1020 {
1021 if (LocaleCompare(keyword, "undercolor") == 0)
1022 {
cristy9950d572011-10-01 18:22:35 +00001023 (void) QueryColorCompliance(value,AllCompliance,
1024 &draw_info->undercolor,&exception);
cristy3ed852e2009-09-05 21:47:34 +00001025 break;
1026 }
1027 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1028 keyword);
1029 break;
1030 }
1031 case 'W':
1032 case 'w':
1033 {
1034 if (LocaleCompare(keyword,"weight") == 0)
1035 {
cristyf2f27272009-12-17 14:48:46 +00001036 draw_info->weight=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001037 break;
1038 }
1039 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1040 keyword);
1041 break;
1042 }
1043 case 'X':
1044 case 'x':
1045 {
1046 if (LocaleCompare(keyword,"x") == 0)
1047 {
cristyf2f27272009-12-17 14:48:46 +00001048 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001049 break;
1050 }
1051 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1052 keyword);
1053 break;
1054 }
1055 case 'Y':
1056 case 'y':
1057 {
1058 if (LocaleCompare(keyword,"y") == 0)
1059 {
cristyf2f27272009-12-17 14:48:46 +00001060 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001061 break;
1062 }
1063 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1064 keyword);
1065 break;
1066 }
1067 default:
1068 {
1069 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1070 keyword);
1071 break;
1072 }
1073 }
1074 }
cristyb51dff52011-05-19 16:55:47 +00001075 (void) FormatLocaleString(text,MaxTextExtent,
cristye8c25f92010-06-03 00:53:06 +00001076 "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,(double)
1077 geometry.height,(double) geometry.x,(double) geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00001078 CloneString(&draw_info->geometry,text);
cristyef7c8a52010-10-10 13:46:51 +00001079 draw_info->affine.sx=affine.sx*current.sx+affine.ry*current.rx;
1080 draw_info->affine.rx=affine.rx*current.sx+affine.sy*current.rx;
1081 draw_info->affine.ry=affine.sx*current.ry+affine.ry*current.sy;
1082 draw_info->affine.sy=affine.rx*current.ry+affine.sy*current.sy;
1083 draw_info->affine.tx=affine.sx*current.tx+affine.ry*current.ty+
1084 affine.tx;
1085 draw_info->affine.ty=affine.rx*current.tx+affine.sy*current.ty+
1086 affine.ty;
cristy5cbc0162011-08-29 00:36:28 +00001087 (void) AnnotateImage(msl_info->image[n],draw_info,
cristyc82a27b2011-10-21 01:07:16 +00001088 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00001089 draw_info=DestroyDrawInfo(draw_info);
1090 break;
1091 }
cristyb988fe72009-09-16 01:01:10 +00001092 if (LocaleCompare((const char *) tag,"append") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001093 {
1094 Image
1095 *append_image;
1096
1097 MagickBooleanType
1098 stack;
cristyb988fe72009-09-16 01:01:10 +00001099
cristy3ed852e2009-09-05 21:47:34 +00001100 if (msl_info->image[n] == (Image *) NULL)
1101 {
cristyb988fe72009-09-16 01:01:10 +00001102 ThrowMSLException(OptionError,"NoImagesDefined",
1103 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001104 break;
1105 }
1106 stack=MagickFalse;
1107 if (attributes != (const xmlChar **) NULL)
1108 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1109 {
1110 keyword=(const char *) attributes[i++];
1111 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00001112 msl_info->attributes[n],(const char *) attributes[i],
1113 &exception);
cristy3ed852e2009-09-05 21:47:34 +00001114 CloneString(&value,attribute);
1115 switch (*keyword)
1116 {
1117 case 'S':
1118 case 's':
1119 {
1120 if (LocaleCompare(keyword,"stack") == 0)
1121 {
cristy042ee782011-04-22 18:48:30 +00001122 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00001123 value);
1124 if (option < 0)
1125 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
1126 value);
1127 stack=(MagickBooleanType) option;
1128 break;
1129 }
1130 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1131 keyword);
1132 break;
1133 }
1134 default:
1135 {
1136 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1137 keyword);
1138 break;
1139 }
1140 }
1141 }
1142 append_image=AppendImages(msl_info->image[n],stack,
cristyc82a27b2011-10-21 01:07:16 +00001143 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00001144 if (append_image == (Image *) NULL)
1145 break;
1146 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1147 msl_info->image[n]=append_image;
1148 break;
1149 }
1150 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
1151 break;
1152 }
1153 case 'B':
1154 case 'b':
1155 {
cristyb988fe72009-09-16 01:01:10 +00001156 if (LocaleCompare((const char *) tag,"blur") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001157 {
1158 Image
1159 *blur_image;
1160
1161 /*
1162 Blur image.
1163 */
1164 if (msl_info->image[n] == (Image *) NULL)
1165 {
cristyb988fe72009-09-16 01:01:10 +00001166 ThrowMSLException(OptionError,"NoImagesDefined",
1167 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001168 break;
1169 }
1170 if (attributes != (const xmlChar **) NULL)
1171 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1172 {
1173 keyword=(const char *) attributes[i++];
1174 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00001175 msl_info->attributes[n],(const char *) attributes[i],
1176 &exception);
cristy3ed852e2009-09-05 21:47:34 +00001177 CloneString(&value,attribute);
1178 switch (*keyword)
1179 {
1180 case 'C':
1181 case 'c':
1182 {
1183 if (LocaleCompare(keyword,"channel") == 0)
1184 {
1185 option=ParseChannelOption(value);
1186 if (option < 0)
1187 ThrowMSLException(OptionError,"UnrecognizedChannelType",
1188 value);
1189 channel=(ChannelType) option;
1190 break;
1191 }
1192 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1193 keyword);
1194 break;
1195 }
1196 case 'G':
1197 case 'g':
1198 {
1199 if (LocaleCompare(keyword,"geometry") == 0)
1200 {
1201 flags=ParseGeometry(value,&geometry_info);
1202 if ((flags & SigmaValue) == 0)
1203 geometry_info.sigma=1.0;
1204 break;
1205 }
1206 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1207 keyword);
1208 break;
1209 }
1210 case 'R':
1211 case 'r':
1212 {
1213 if (LocaleCompare(keyword,"radius") == 0)
1214 {
cristy9b34e302011-11-05 02:15:45 +00001215 geometry_info.rho=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00001216 break;
1217 }
1218 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1219 keyword);
1220 break;
1221 }
1222 case 'S':
1223 case 's':
1224 {
1225 if (LocaleCompare(keyword,"sigma") == 0)
1226 {
cristyf2f27272009-12-17 14:48:46 +00001227 geometry_info.sigma=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001228 break;
1229 }
1230 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1231 keyword);
1232 break;
1233 }
1234 default:
1235 {
1236 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1237 keyword);
1238 break;
1239 }
1240 }
1241 }
cristybd5a96c2011-08-21 00:04:26 +00001242 channel_mask=SetPixelChannelMask(msl_info->image[n],channel);
cristyf4ad9df2011-07-08 16:49:03 +00001243 blur_image=BlurImage(msl_info->image[n],geometry_info.rho,
cristyaa2c16c2012-03-25 22:21:35 +00001244 geometry_info.sigma,msl_info->exception);
cristye2a912b2011-12-05 20:02:07 +00001245 (void) SetPixelChannelMapMask(msl_info->image[n],channel_mask);
cristy3ed852e2009-09-05 21:47:34 +00001246 if (blur_image == (Image *) NULL)
1247 break;
1248 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1249 msl_info->image[n]=blur_image;
1250 break;
1251 }
cristyb988fe72009-09-16 01:01:10 +00001252 if (LocaleCompare((const char *) tag,"border") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001253 {
1254 Image
1255 *border_image;
1256
1257 /*
1258 Border image.
1259 */
1260 if (msl_info->image[n] == (Image *) NULL)
1261 {
cristyb988fe72009-09-16 01:01:10 +00001262 ThrowMSLException(OptionError,"NoImagesDefined",
1263 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001264 break;
1265 }
1266 SetGeometry(msl_info->image[n],&geometry);
1267 if (attributes != (const xmlChar **) NULL)
1268 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1269 {
1270 keyword=(const char *) attributes[i++];
1271 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00001272 msl_info->attributes[n],(const char *) attributes[i],
1273 &exception);
cristy3ed852e2009-09-05 21:47:34 +00001274 CloneString(&value,attribute);
1275 switch (*keyword)
1276 {
1277 case 'C':
1278 case 'c':
1279 {
1280 if (LocaleCompare(keyword,"compose") == 0)
1281 {
cristy042ee782011-04-22 18:48:30 +00001282 option=ParseCommandOption(MagickComposeOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00001283 value);
1284 if (option < 0)
1285 ThrowMSLException(OptionError,"UnrecognizedComposeType",
1286 value);
1287 msl_info->image[n]->compose=(CompositeOperator) option;
1288 break;
1289 }
1290 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1291 keyword);
1292 break;
1293 }
1294 case 'F':
1295 case 'f':
1296 {
1297 if (LocaleCompare(keyword, "fill") == 0)
1298 {
cristy9950d572011-10-01 18:22:35 +00001299 (void) QueryColorCompliance(value,AllCompliance,
cristy3ed852e2009-09-05 21:47:34 +00001300 &msl_info->image[n]->border_color,&exception);
1301 break;
1302 }
1303 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1304 keyword);
1305 break;
1306 }
1307 case 'G':
1308 case 'g':
1309 {
1310 if (LocaleCompare(keyword,"geometry") == 0)
1311 {
1312 flags=ParsePageGeometry(msl_info->image[n],value,
1313 &geometry,&exception);
1314 if ((flags & HeightValue) == 0)
1315 geometry.height=geometry.width;
1316 break;
1317 }
1318 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1319 keyword);
1320 break;
1321 }
1322 case 'H':
1323 case 'h':
1324 {
1325 if (LocaleCompare(keyword,"height") == 0)
1326 {
cristyf2f27272009-12-17 14:48:46 +00001327 geometry.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001328 break;
1329 }
1330 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1331 keyword);
1332 break;
1333 }
1334 case 'W':
1335 case 'w':
1336 {
1337 if (LocaleCompare(keyword,"width") == 0)
1338 {
cristyf2f27272009-12-17 14:48:46 +00001339 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001340 break;
1341 }
1342 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1343 keyword);
1344 break;
1345 }
1346 default:
1347 {
1348 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1349 keyword);
1350 break;
1351 }
1352 }
1353 }
1354 border_image=BorderImage(msl_info->image[n],&geometry,
cristyc82a27b2011-10-21 01:07:16 +00001355 msl_info->image[n]->compose,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00001356 if (border_image == (Image *) NULL)
1357 break;
1358 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1359 msl_info->image[n]=border_image;
1360 break;
1361 }
1362 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
1363 }
1364 case 'C':
1365 case 'c':
1366 {
cristyb988fe72009-09-16 01:01:10 +00001367 if (LocaleCompare((const char *) tag,"colorize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001368 {
1369 char
cristyc7e6ff62011-10-03 13:46:11 +00001370 blend[MaxTextExtent];
cristy3ed852e2009-09-05 21:47:34 +00001371
1372 Image
1373 *colorize_image;
1374
cristyc7e6ff62011-10-03 13:46:11 +00001375 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00001376 target;
1377
1378 /*
1379 Add noise image.
1380 */
1381 if (msl_info->image[n] == (Image *) NULL)
1382 {
cristyb988fe72009-09-16 01:01:10 +00001383 ThrowMSLException(OptionError,"NoImagesDefined",
1384 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001385 break;
1386 }
cristyc7e6ff62011-10-03 13:46:11 +00001387 GetPixelInfo(msl_info->image[n],&target);
1388 (void) CopyMagickString(blend,"100",MaxTextExtent);
cristy3ed852e2009-09-05 21:47:34 +00001389 if (attributes != (const xmlChar **) NULL)
1390 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1391 {
1392 keyword=(const char *) attributes[i++];
1393 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00001394 msl_info->attributes[n],(const char *) attributes[i],
1395 &exception);
cristy3ed852e2009-09-05 21:47:34 +00001396 CloneString(&value,attribute);
1397 switch (*keyword)
1398 {
cristyc7e6ff62011-10-03 13:46:11 +00001399 case 'B':
1400 case 'b':
cristy3ed852e2009-09-05 21:47:34 +00001401 {
cristyc7e6ff62011-10-03 13:46:11 +00001402 if (LocaleCompare(keyword,"blend") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001403 {
cristyc7e6ff62011-10-03 13:46:11 +00001404 (void) CopyMagickString(blend,value,MaxTextExtent);
cristy3ed852e2009-09-05 21:47:34 +00001405 break;
1406 }
1407 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1408 keyword);
1409 break;
1410 }
cristyc7e6ff62011-10-03 13:46:11 +00001411 case 'F':
1412 case 'f':
cristy3ed852e2009-09-05 21:47:34 +00001413 {
cristyc7e6ff62011-10-03 13:46:11 +00001414 if (LocaleCompare(keyword,"fill") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001415 {
cristy269c9412011-10-13 23:41:15 +00001416 (void) QueryColorCompliance(value,AllCompliance,
cristyc82a27b2011-10-21 01:07:16 +00001417 &target,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00001418 break;
1419 }
1420 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1421 keyword);
1422 break;
1423 }
1424 default:
1425 {
1426 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1427 keyword);
1428 break;
1429 }
1430 }
1431 }
cristyc7e6ff62011-10-03 13:46:11 +00001432 colorize_image=ColorizeImage(msl_info->image[n],blend,&target,
cristyc82a27b2011-10-21 01:07:16 +00001433 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00001434 if (colorize_image == (Image *) NULL)
1435 break;
1436 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1437 msl_info->image[n]=colorize_image;
1438 break;
1439 }
cristyb988fe72009-09-16 01:01:10 +00001440 if (LocaleCompare((const char *) tag, "charcoal") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001441 {
cristyaa2c16c2012-03-25 22:21:35 +00001442 double
cristy05c0c9a2011-09-05 23:16:13 +00001443 radius = 0.0,
cristy3ed852e2009-09-05 21:47:34 +00001444 sigma = 1.0;
1445
1446 if (msl_info->image[n] == (Image *) NULL)
1447 {
cristyb988fe72009-09-16 01:01:10 +00001448 ThrowMSLException(OptionError,"NoImagesDefined",
1449 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001450 break;
1451 }
1452 /*
1453 NOTE: charcoal can have no attributes, since we use all the defaults!
1454 */
1455 if (attributes != (const xmlChar **) NULL)
1456 {
1457 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1458 {
1459 keyword=(const char *) attributes[i++];
1460 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00001461 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00001462 switch (*keyword)
1463 {
1464 case 'R':
1465 case 'r':
1466 {
cristy9b34e302011-11-05 02:15:45 +00001467 if (LocaleCompare(keyword,"radius") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001468 {
cristy9b34e302011-11-05 02:15:45 +00001469 radius=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00001470 break;
1471 }
1472 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
1473 break;
1474 }
1475 case 'S':
1476 case 's':
1477 {
1478 if (LocaleCompare(keyword,"sigma") == 0)
1479 {
cristyf2f27272009-12-17 14:48:46 +00001480 sigma = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00001481 break;
1482 }
1483 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
1484 break;
1485 }
1486 default:
1487 {
1488 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
1489 break;
1490 }
1491 }
1492 }
1493 }
1494
1495 /*
1496 charcoal image.
1497 */
1498 {
1499 Image
1500 *newImage;
1501
cristyaa2c16c2012-03-25 22:21:35 +00001502 newImage=CharcoalImage(msl_info->image[n],radius,sigma,
cristyc82a27b2011-10-21 01:07:16 +00001503 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00001504 if (newImage == (Image *) NULL)
1505 break;
1506 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1507 msl_info->image[n]=newImage;
1508 break;
1509 }
1510 }
cristyb988fe72009-09-16 01:01:10 +00001511 if (LocaleCompare((const char *) tag,"chop") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001512 {
1513 Image
1514 *chop_image;
1515
1516 /*
1517 Chop image.
1518 */
1519 if (msl_info->image[n] == (Image *) NULL)
1520 {
cristyb988fe72009-09-16 01:01:10 +00001521 ThrowMSLException(OptionError,"NoImagesDefined",
1522 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001523 break;
1524 }
1525 SetGeometry(msl_info->image[n],&geometry);
1526 if (attributes != (const xmlChar **) NULL)
1527 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1528 {
1529 keyword=(const char *) attributes[i++];
1530 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00001531 msl_info->attributes[n],(const char *) attributes[i],
1532 &exception);
cristy3ed852e2009-09-05 21:47:34 +00001533 CloneString(&value,attribute);
1534 switch (*keyword)
1535 {
1536 case 'G':
1537 case 'g':
1538 {
1539 if (LocaleCompare(keyword,"geometry") == 0)
1540 {
1541 flags=ParsePageGeometry(msl_info->image[n],value,
1542 &geometry,&exception);
1543 if ((flags & HeightValue) == 0)
1544 geometry.height=geometry.width;
1545 break;
1546 }
1547 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1548 keyword);
1549 break;
1550 }
1551 case 'H':
1552 case 'h':
1553 {
1554 if (LocaleCompare(keyword,"height") == 0)
1555 {
cristyf2f27272009-12-17 14:48:46 +00001556 geometry.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001557 break;
1558 }
1559 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1560 keyword);
1561 break;
1562 }
1563 case 'W':
1564 case 'w':
1565 {
1566 if (LocaleCompare(keyword,"width") == 0)
1567 {
cristyf2f27272009-12-17 14:48:46 +00001568 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001569 break;
1570 }
1571 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1572 keyword);
1573 break;
1574 }
1575 case 'X':
1576 case 'x':
1577 {
1578 if (LocaleCompare(keyword,"x") == 0)
1579 {
cristyf2f27272009-12-17 14:48:46 +00001580 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001581 break;
1582 }
1583 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1584 keyword);
1585 break;
1586 }
1587 case 'Y':
1588 case 'y':
1589 {
1590 if (LocaleCompare(keyword,"y") == 0)
1591 {
cristyf2f27272009-12-17 14:48:46 +00001592 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001593 break;
1594 }
1595 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1596 keyword);
1597 break;
1598 }
1599 default:
1600 {
1601 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1602 keyword);
1603 break;
1604 }
1605 }
1606 }
1607 chop_image=ChopImage(msl_info->image[n],&geometry,
cristyc82a27b2011-10-21 01:07:16 +00001608 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00001609 if (chop_image == (Image *) NULL)
1610 break;
1611 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1612 msl_info->image[n]=chop_image;
1613 break;
1614 }
cristyb988fe72009-09-16 01:01:10 +00001615 if (LocaleCompare((const char *) tag,"color-floodfill") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001616 {
1617 PaintMethod
1618 paint_method;
1619
cristy4c08aed2011-07-01 19:47:50 +00001620 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00001621 target;
1622
1623 /*
1624 Color floodfill image.
1625 */
1626 if (msl_info->image[n] == (Image *) NULL)
1627 {
cristyb988fe72009-09-16 01:01:10 +00001628 ThrowMSLException(OptionError,"NoImagesDefined",
1629 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001630 break;
1631 }
1632 draw_info=CloneDrawInfo(msl_info->image_info[n],
1633 msl_info->draw_info[n]);
1634 SetGeometry(msl_info->image[n],&geometry);
1635 paint_method=FloodfillMethod;
1636 if (attributes != (const xmlChar **) NULL)
1637 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1638 {
1639 keyword=(const char *) attributes[i++];
1640 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00001641 msl_info->attributes[n],(const char *) attributes[i],
1642 &exception);
cristy3ed852e2009-09-05 21:47:34 +00001643 CloneString(&value,attribute);
1644 switch (*keyword)
1645 {
1646 case 'B':
1647 case 'b':
1648 {
1649 if (LocaleCompare(keyword,"bordercolor") == 0)
1650 {
cristy269c9412011-10-13 23:41:15 +00001651 (void) QueryColorCompliance(value,AllCompliance,
cristy9950d572011-10-01 18:22:35 +00001652 &target,&exception);
cristy3ed852e2009-09-05 21:47:34 +00001653 paint_method=FillToBorderMethod;
1654 break;
1655 }
1656 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1657 keyword);
1658 break;
1659 }
1660 case 'F':
1661 case 'f':
1662 {
1663 if (LocaleCompare(keyword,"fill") == 0)
1664 {
cristy9950d572011-10-01 18:22:35 +00001665 (void) QueryColorCompliance(value,AllCompliance,
1666 &draw_info->fill,&exception);
cristy3ed852e2009-09-05 21:47:34 +00001667 break;
1668 }
1669 if (LocaleCompare(keyword,"fuzz") == 0)
1670 {
cristydbdd0e32011-11-04 23:29:40 +00001671 msl_info->image[n]->fuzz=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00001672 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00001673 break;
1674 }
1675 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1676 keyword);
1677 break;
1678 }
1679 case 'G':
1680 case 'g':
1681 {
1682 if (LocaleCompare(keyword,"geometry") == 0)
1683 {
1684 flags=ParsePageGeometry(msl_info->image[n],value,
1685 &geometry,&exception);
1686 if ((flags & HeightValue) == 0)
1687 geometry.height=geometry.width;
cristy3aa93752011-12-18 15:54:24 +00001688 (void) GetOneVirtualPixelInfo(msl_info->image[n],
cristy33e9da62011-10-21 19:08:58 +00001689 TileVirtualPixelMethod,geometry.x,geometry.y,&target,
1690 &exception);
cristy3ed852e2009-09-05 21:47:34 +00001691 break;
1692 }
1693 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1694 keyword);
1695 break;
1696 }
1697 case 'X':
1698 case 'x':
1699 {
1700 if (LocaleCompare(keyword,"x") == 0)
1701 {
cristyf2f27272009-12-17 14:48:46 +00001702 geometry.x=StringToLong(value);
cristy3aa93752011-12-18 15:54:24 +00001703 (void) GetOneVirtualPixelInfo(msl_info->image[n],
cristy33e9da62011-10-21 19:08:58 +00001704 TileVirtualPixelMethod,geometry.x,geometry.y,&target,
1705 &exception);
cristy3ed852e2009-09-05 21:47:34 +00001706 break;
1707 }
1708 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1709 keyword);
1710 break;
1711 }
1712 case 'Y':
1713 case 'y':
1714 {
1715 if (LocaleCompare(keyword,"y") == 0)
1716 {
cristyf2f27272009-12-17 14:48:46 +00001717 geometry.y=StringToLong(value);
cristy3aa93752011-12-18 15:54:24 +00001718 (void) GetOneVirtualPixelInfo(msl_info->image[n],
cristy33e9da62011-10-21 19:08:58 +00001719 TileVirtualPixelMethod,geometry.x,geometry.y,&target,
1720 &exception);
cristy3ed852e2009-09-05 21:47:34 +00001721 break;
1722 }
1723 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1724 keyword);
1725 break;
1726 }
1727 default:
1728 {
1729 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1730 keyword);
1731 break;
1732 }
1733 }
1734 }
cristyd42d9952011-07-08 14:21:50 +00001735 (void) FloodfillPaintImage(msl_info->image[n],draw_info,&target,
1736 geometry.x,geometry.y,paint_method == FloodfillMethod ?
cristyc82a27b2011-10-21 01:07:16 +00001737 MagickFalse : MagickTrue,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00001738 draw_info=DestroyDrawInfo(draw_info);
1739 break;
1740 }
cristyb988fe72009-09-16 01:01:10 +00001741 if (LocaleCompare((const char *) tag,"comment") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001742 break;
cristyb988fe72009-09-16 01:01:10 +00001743 if (LocaleCompare((const char *) tag,"composite") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001744 {
1745 char
1746 composite_geometry[MaxTextExtent];
1747
1748 CompositeOperator
1749 compose;
1750
1751 Image
1752 *composite_image,
1753 *rotate_image;
1754
cristy3ed852e2009-09-05 21:47:34 +00001755 /*
1756 Composite image.
1757 */
1758 if (msl_info->image[n] == (Image *) NULL)
1759 {
cristyb988fe72009-09-16 01:01:10 +00001760 ThrowMSLException(OptionError,"NoImagesDefined",
1761 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001762 break;
1763 }
1764 composite_image=NewImageList();
1765 compose=OverCompositeOp;
1766 if (attributes != (const xmlChar **) NULL)
1767 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1768 {
1769 keyword=(const char *) attributes[i++];
1770 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00001771 msl_info->attributes[n],(const char *) attributes[i],
1772 &exception);
cristy3ed852e2009-09-05 21:47:34 +00001773 CloneString(&value,attribute);
1774 switch (*keyword)
1775 {
1776 case 'C':
1777 case 'c':
1778 {
1779 if (LocaleCompare(keyword,"compose") == 0)
1780 {
cristy2ed42f62011-10-02 19:49:57 +00001781 option=ParseCommandOption(MagickComposeOptions,
1782 MagickFalse,value);
cristy3ed852e2009-09-05 21:47:34 +00001783 if (option < 0)
1784 ThrowMSLException(OptionError,"UnrecognizedComposeType",
1785 value);
1786 compose=(CompositeOperator) option;
1787 break;
1788 }
1789 break;
1790 }
1791 case 'I':
1792 case 'i':
1793 {
1794 if (LocaleCompare(keyword,"image") == 0)
1795 for (j=0; j < msl_info->n; j++)
1796 {
1797 const char
1798 *attribute;
cristyb988fe72009-09-16 01:01:10 +00001799
cristyd15e6592011-10-15 00:13:06 +00001800 attribute=GetImageProperty(msl_info->attributes[j],"id",
1801 &exception);
cristy3ed852e2009-09-05 21:47:34 +00001802 if ((attribute != (const char *) NULL) &&
1803 (LocaleCompare(attribute,value) == 0))
1804 {
1805 composite_image=CloneImage(msl_info->image[j],0,0,
1806 MagickFalse,&exception);
1807 break;
1808 }
1809 }
1810 break;
1811 }
1812 default:
1813 break;
1814 }
1815 }
1816 if (composite_image == (Image *) NULL)
1817 break;
1818 rotate_image=NewImageList();
1819 SetGeometry(msl_info->image[n],&geometry);
1820 if (attributes != (const xmlChar **) NULL)
1821 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1822 {
1823 keyword=(const char *) attributes[i++];
1824 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00001825 msl_info->attributes[n],(const char *) attributes[i],
1826 &exception);
cristy3ed852e2009-09-05 21:47:34 +00001827 CloneString(&value,attribute);
1828 switch (*keyword)
1829 {
1830 case 'B':
1831 case 'b':
1832 {
1833 if (LocaleCompare(keyword,"blend") == 0)
1834 {
1835 (void) SetImageArtifact(composite_image,
1836 "compose:args",value);
1837 break;
1838 }
1839 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1840 keyword);
1841 break;
1842 }
1843 case 'C':
1844 case 'c':
1845 {
1846 if (LocaleCompare(keyword,"channel") == 0)
1847 {
1848 option=ParseChannelOption(value);
1849 if (option < 0)
1850 ThrowMSLException(OptionError,"UnrecognizedChannelType",
1851 value);
1852 channel=(ChannelType) option;
1853 break;
1854 }
1855 if (LocaleCompare(keyword, "color") == 0)
1856 {
cristy9950d572011-10-01 18:22:35 +00001857 (void) QueryColorCompliance(value,AllCompliance,
cristy3ed852e2009-09-05 21:47:34 +00001858 &composite_image->background_color,&exception);
1859 break;
1860 }
1861 if (LocaleCompare(keyword,"compose") == 0)
1862 break;
1863 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1864 keyword);
1865 break;
1866 }
1867 case 'G':
1868 case 'g':
1869 {
1870 if (LocaleCompare(keyword,"geometry") == 0)
1871 {
1872 flags=ParsePageGeometry(msl_info->image[n],value,
1873 &geometry,&exception);
1874 if ((flags & HeightValue) == 0)
1875 geometry.height=geometry.width;
cristy3ed852e2009-09-05 21:47:34 +00001876 break;
1877 }
1878 if (LocaleCompare(keyword,"gravity") == 0)
1879 {
cristy2ed42f62011-10-02 19:49:57 +00001880 option=ParseCommandOption(MagickGravityOptions,
1881 MagickFalse,value);
cristy3ed852e2009-09-05 21:47:34 +00001882 if (option < 0)
1883 ThrowMSLException(OptionError,"UnrecognizedGravityType",
1884 value);
1885 msl_info->image[n]->gravity=(GravityType) option;
1886 break;
1887 }
1888 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1889 keyword);
1890 break;
1891 }
1892 case 'I':
1893 case 'i':
1894 {
1895 if (LocaleCompare(keyword,"image") == 0)
1896 break;
1897 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1898 keyword);
1899 break;
1900 }
1901 case 'M':
1902 case 'm':
1903 {
1904 if (LocaleCompare(keyword,"mask") == 0)
1905 for (j=0; j < msl_info->n; j++)
1906 {
1907 const char
1908 *attribute;
1909
cristyd15e6592011-10-15 00:13:06 +00001910 attribute=GetImageProperty(msl_info->attributes[j],"id",
1911 &exception);
cristy3ed852e2009-09-05 21:47:34 +00001912 if ((attribute != (const char *) NULL) &&
1913 (LocaleCompare(value,value) == 0))
1914 {
cristy018f07f2011-09-04 21:15:19 +00001915 SetImageType(composite_image,TrueColorMatteType,
1916 &exception);
cristy3ed852e2009-09-05 21:47:34 +00001917 (void) CompositeImage(composite_image,
cristy39172402012-03-30 13:04:39 +00001918 msl_info->image[j],CopyAlphaCompositeOp,MagickTrue,
cristyfeb3e962012-03-29 17:25:55 +00001919 0,0,&exception);
cristy3ed852e2009-09-05 21:47:34 +00001920 break;
1921 }
1922 }
1923 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1924 keyword);
1925 break;
1926 }
1927 case 'O':
1928 case 'o':
1929 {
1930 if (LocaleCompare(keyword,"opacity") == 0)
1931 {
cristybb503372010-05-27 20:51:26 +00001932 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001933 opacity,
1934 y;
cristyb988fe72009-09-16 01:01:10 +00001935
cristybb503372010-05-27 20:51:26 +00001936 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001937 x;
cristyb988fe72009-09-16 01:01:10 +00001938
cristy4c08aed2011-07-01 19:47:50 +00001939 register Quantum
cristy3ed852e2009-09-05 21:47:34 +00001940 *q;
cristyb988fe72009-09-16 01:01:10 +00001941
cristy3ed852e2009-09-05 21:47:34 +00001942 CacheView
1943 *composite_view;
1944
cristy4c08aed2011-07-01 19:47:50 +00001945 opacity=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001946 if (compose != DissolveCompositeOp)
1947 {
cristyb6a294d2011-10-03 00:55:17 +00001948 (void) SetImageAlpha(composite_image,(Quantum)
cristye941a752011-10-15 01:52:48 +00001949 opacity,&exception);
cristy3ed852e2009-09-05 21:47:34 +00001950 break;
1951 }
1952 (void) SetImageArtifact(msl_info->image[n],
1953 "compose:args",value);
1954 if (composite_image->matte != MagickTrue)
cristye941a752011-10-15 01:52:48 +00001955 (void) SetImageAlpha(composite_image,OpaqueAlpha,
1956 &exception);
cristydb070952012-04-20 14:33:00 +00001957 composite_view=AcquireAuthenticCacheView(composite_image,
1958 &exception);
cristybb503372010-05-27 20:51:26 +00001959 for (y=0; y < (ssize_t) composite_image->rows ; y++)
cristyb988fe72009-09-16 01:01:10 +00001960 {
cristy4c08aed2011-07-01 19:47:50 +00001961 q=GetCacheViewAuthenticPixels(composite_view,0,y,
1962 (ssize_t) composite_image->columns,1,&exception);
cristybb503372010-05-27 20:51:26 +00001963 for (x=0; x < (ssize_t) composite_image->columns; x++)
cristyb988fe72009-09-16 01:01:10 +00001964 {
cristy4c08aed2011-07-01 19:47:50 +00001965 if (GetPixelAlpha(composite_image,q) == OpaqueAlpha)
1966 SetPixelAlpha(composite_image,
1967 ClampToQuantum(opacity),q);
cristyed231572011-07-14 02:18:59 +00001968 q+=GetPixelChannels(composite_image);
cristy3ed852e2009-09-05 21:47:34 +00001969 }
1970 if (SyncCacheViewAuthenticPixels(composite_view,&exception) == MagickFalse)
1971 break;
1972 }
1973 composite_view=DestroyCacheView(composite_view);
1974 break;
1975 }
1976 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1977 keyword);
1978 break;
1979 }
1980 case 'R':
1981 case 'r':
1982 {
1983 if (LocaleCompare(keyword,"rotate") == 0)
1984 {
cristyc1acd842011-05-19 23:05:47 +00001985 rotate_image=RotateImage(composite_image,
cristydbdd0e32011-11-04 23:29:40 +00001986 StringToDouble(value,(char **) NULL),&exception);
cristy3ed852e2009-09-05 21:47:34 +00001987 break;
1988 }
1989 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1990 keyword);
1991 break;
1992 }
1993 case 'T':
1994 case 't':
1995 {
1996 if (LocaleCompare(keyword,"tile") == 0)
1997 {
1998 MagickBooleanType
1999 tile;
2000
cristy042ee782011-04-22 18:48:30 +00002001 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002002 value);
2003 if (option < 0)
2004 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
2005 value);
2006 tile=(MagickBooleanType) option;
cristyda16f162011-02-19 23:52:17 +00002007 (void) tile;
cristy3ed852e2009-09-05 21:47:34 +00002008 if (rotate_image != (Image *) NULL)
2009 (void) SetImageArtifact(rotate_image,
2010 "compose:outside-overlay","false");
2011 else
2012 (void) SetImageArtifact(composite_image,
2013 "compose:outside-overlay","false");
2014 image=msl_info->image[n];
2015 height=composite_image->rows;
2016 width=composite_image->columns;
cristyeaedf062010-05-29 22:36:02 +00002017 for (y=0; y < (ssize_t) image->rows; y+=(ssize_t) height)
2018 for (x=0; x < (ssize_t) image->columns; x+=(ssize_t) width)
cristy3ed852e2009-09-05 21:47:34 +00002019 {
2020 if (rotate_image != (Image *) NULL)
cristyfeb3e962012-03-29 17:25:55 +00002021 (void) CompositeImage(image,rotate_image,compose,
cristy39172402012-03-30 13:04:39 +00002022 MagickTrue,x,y,&exception);
cristy3ed852e2009-09-05 21:47:34 +00002023 else
cristyfeb3e962012-03-29 17:25:55 +00002024 (void) CompositeImage(image,composite_image,
cristy39172402012-03-30 13:04:39 +00002025 compose,MagickTrue,x,y,&exception);
cristy3ed852e2009-09-05 21:47:34 +00002026 }
2027 if (rotate_image != (Image *) NULL)
2028 rotate_image=DestroyImage(rotate_image);
2029 break;
2030 }
2031 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2032 keyword);
2033 break;
2034 }
2035 case 'X':
2036 case 'x':
2037 {
2038 if (LocaleCompare(keyword,"x") == 0)
2039 {
cristyf2f27272009-12-17 14:48:46 +00002040 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002041 break;
2042 }
2043 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2044 keyword);
2045 break;
2046 }
2047 case 'Y':
2048 case 'y':
2049 {
2050 if (LocaleCompare(keyword,"y") == 0)
2051 {
cristyf2f27272009-12-17 14:48:46 +00002052 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002053 break;
2054 }
2055 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2056 keyword);
2057 break;
2058 }
2059 default:
2060 {
2061 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2062 keyword);
2063 break;
2064 }
2065 }
2066 }
2067 image=msl_info->image[n];
cristyb51dff52011-05-19 16:55:47 +00002068 (void) FormatLocaleString(composite_geometry,MaxTextExtent,
cristye8c25f92010-06-03 00:53:06 +00002069 "%.20gx%.20g%+.20g%+.20g",(double) composite_image->columns,
2070 (double) composite_image->rows,(double) geometry.x,(double)
cristyf2faecf2010-05-28 19:19:36 +00002071 geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00002072 flags=ParseGravityGeometry(image,composite_geometry,&geometry,
2073 &exception);
cristybd5a96c2011-08-21 00:04:26 +00002074 channel_mask=SetPixelChannelMask(image,channel);
cristy3ed852e2009-09-05 21:47:34 +00002075 if (rotate_image == (Image *) NULL)
cristy39172402012-03-30 13:04:39 +00002076 CompositeImage(image,composite_image,compose,MagickTrue,geometry.x,
cristyfeb3e962012-03-29 17:25:55 +00002077 geometry.y,&exception);
cristy3ed852e2009-09-05 21:47:34 +00002078 else
2079 {
2080 /*
2081 Rotate image.
2082 */
cristybb503372010-05-27 20:51:26 +00002083 geometry.x-=(ssize_t) (rotate_image->columns-
cristy3ed852e2009-09-05 21:47:34 +00002084 composite_image->columns)/2;
cristy2ed42f62011-10-02 19:49:57 +00002085 geometry.y-=(ssize_t) (rotate_image->rows-
2086 composite_image->rows)/2;
cristy39172402012-03-30 13:04:39 +00002087 CompositeImage(image,rotate_image,compose,MagickTrue,geometry.x,
cristyfeb3e962012-03-29 17:25:55 +00002088 geometry.y,&exception);
cristy3ed852e2009-09-05 21:47:34 +00002089 rotate_image=DestroyImage(rotate_image);
2090 }
cristybd5a96c2011-08-21 00:04:26 +00002091 (void) SetPixelChannelMask(image,channel_mask);
cristy3ed852e2009-09-05 21:47:34 +00002092 composite_image=DestroyImage(composite_image);
2093 break;
2094 }
cristyb988fe72009-09-16 01:01:10 +00002095 if (LocaleCompare((const char *) tag,"contrast") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002096 {
2097 MagickBooleanType
2098 sharpen;
2099
2100 /*
2101 Contrast image.
2102 */
2103 if (msl_info->image[n] == (Image *) NULL)
2104 {
cristyb988fe72009-09-16 01:01:10 +00002105 ThrowMSLException(OptionError,"NoImagesDefined",
2106 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002107 break;
2108 }
2109 sharpen=MagickFalse;
2110 if (attributes != (const xmlChar **) NULL)
2111 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2112 {
2113 keyword=(const char *) attributes[i++];
2114 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002115 msl_info->attributes[n],(const char *) attributes[i],
2116 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002117 CloneString(&value,attribute);
2118 switch (*keyword)
2119 {
2120 case 'S':
2121 case 's':
2122 {
2123 if (LocaleCompare(keyword,"sharpen") == 0)
2124 {
cristy042ee782011-04-22 18:48:30 +00002125 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002126 value);
2127 if (option < 0)
2128 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
2129 value);
2130 sharpen=(MagickBooleanType) option;
2131 break;
2132 }
2133 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2134 keyword);
2135 break;
2136 }
2137 default:
2138 {
2139 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2140 keyword);
2141 break;
2142 }
2143 }
2144 }
cristye23ec9d2011-08-16 18:15:40 +00002145 (void) ContrastImage(msl_info->image[n],sharpen,
cristyc82a27b2011-10-21 01:07:16 +00002146 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00002147 break;
2148 }
cristyb988fe72009-09-16 01:01:10 +00002149 if (LocaleCompare((const char *) tag,"crop") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002150 {
2151 Image
2152 *crop_image;
2153
2154 /*
2155 Crop image.
2156 */
2157 if (msl_info->image[n] == (Image *) NULL)
2158 {
cristyb988fe72009-09-16 01:01:10 +00002159 ThrowMSLException(OptionError,"NoImagesDefined",
2160 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002161 break;
2162 }
2163 SetGeometry(msl_info->image[n],&geometry);
2164 if (attributes != (const xmlChar **) NULL)
2165 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2166 {
2167 keyword=(const char *) attributes[i++];
2168 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002169 msl_info->attributes[n],(const char *) attributes[i],
2170 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002171 CloneString(&value,attribute);
2172 switch (*keyword)
2173 {
2174 case 'G':
2175 case 'g':
2176 {
2177 if (LocaleCompare(keyword,"geometry") == 0)
2178 {
cristy860f4e12011-07-28 19:00:28 +00002179 flags=ParseGravityGeometry(msl_info->image[n],value,
cristy3ed852e2009-09-05 21:47:34 +00002180 &geometry,&exception);
cristy3ed852e2009-09-05 21:47:34 +00002181 break;
2182 }
2183 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2184 keyword);
2185 break;
2186 }
2187 case 'H':
2188 case 'h':
2189 {
2190 if (LocaleCompare(keyword,"height") == 0)
2191 {
cristyf2f27272009-12-17 14:48:46 +00002192 geometry.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002193 break;
2194 }
2195 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2196 keyword);
2197 break;
2198 }
2199 case 'W':
2200 case 'w':
2201 {
2202 if (LocaleCompare(keyword,"width") == 0)
2203 {
cristyf2f27272009-12-17 14:48:46 +00002204 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002205 break;
2206 }
2207 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2208 keyword);
2209 break;
2210 }
2211 case 'X':
2212 case 'x':
2213 {
2214 if (LocaleCompare(keyword,"x") == 0)
2215 {
cristyf2f27272009-12-17 14:48:46 +00002216 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002217 break;
2218 }
2219 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2220 keyword);
2221 break;
2222 }
2223 case 'Y':
2224 case 'y':
2225 {
2226 if (LocaleCompare(keyword,"y") == 0)
2227 {
cristyf2f27272009-12-17 14:48:46 +00002228 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002229 break;
2230 }
2231 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2232 keyword);
2233 break;
2234 }
2235 default:
2236 {
2237 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2238 keyword);
2239 break;
2240 }
2241 }
2242 }
2243 crop_image=CropImage(msl_info->image[n],&geometry,
cristyc82a27b2011-10-21 01:07:16 +00002244 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00002245 if (crop_image == (Image *) NULL)
2246 break;
2247 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2248 msl_info->image[n]=crop_image;
2249 break;
2250 }
cristyb988fe72009-09-16 01:01:10 +00002251 if (LocaleCompare((const char *) tag,"cycle-colormap") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002252 {
cristybb503372010-05-27 20:51:26 +00002253 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002254 display;
2255
2256 /*
2257 Cycle-colormap image.
2258 */
2259 if (msl_info->image[n] == (Image *) NULL)
2260 {
cristyb988fe72009-09-16 01:01:10 +00002261 ThrowMSLException(OptionError,"NoImagesDefined",
2262 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002263 break;
2264 }
2265 display=0;
2266 if (attributes != (const xmlChar **) NULL)
2267 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2268 {
2269 keyword=(const char *) attributes[i++];
2270 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002271 msl_info->attributes[n],(const char *) attributes[i],
2272 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002273 CloneString(&value,attribute);
2274 switch (*keyword)
2275 {
2276 case 'D':
2277 case 'd':
2278 {
2279 if (LocaleCompare(keyword,"display") == 0)
2280 {
cristyf2f27272009-12-17 14:48:46 +00002281 display=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002282 break;
2283 }
2284 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2285 keyword);
2286 break;
2287 }
2288 default:
2289 {
2290 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2291 keyword);
2292 break;
2293 }
2294 }
2295 }
cristy018f07f2011-09-04 21:15:19 +00002296 (void) CycleColormapImage(msl_info->image[n],display,&exception);
cristy3ed852e2009-09-05 21:47:34 +00002297 break;
2298 }
2299 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
2300 }
2301 case 'D':
2302 case 'd':
2303 {
cristyb988fe72009-09-16 01:01:10 +00002304 if (LocaleCompare((const char *) tag,"despeckle") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002305 {
2306 Image
2307 *despeckle_image;
2308
2309 /*
2310 Despeckle image.
2311 */
2312 if (msl_info->image[n] == (Image *) NULL)
2313 {
cristyb988fe72009-09-16 01:01:10 +00002314 ThrowMSLException(OptionError,"NoImagesDefined",
2315 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002316 break;
2317 }
2318 if (attributes != (const xmlChar **) NULL)
2319 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2320 {
2321 keyword=(const char *) attributes[i++];
2322 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002323 msl_info->attributes[n],(const char *) attributes[i],
2324 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002325 CloneString(&value,attribute);
2326 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
2327 }
2328 despeckle_image=DespeckleImage(msl_info->image[n],
cristyc82a27b2011-10-21 01:07:16 +00002329 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00002330 if (despeckle_image == (Image *) NULL)
2331 break;
2332 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2333 msl_info->image[n]=despeckle_image;
2334 break;
2335 }
cristyb988fe72009-09-16 01:01:10 +00002336 if (LocaleCompare((const char *) tag,"display") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002337 {
2338 if (msl_info->image[n] == (Image *) NULL)
2339 {
cristyb988fe72009-09-16 01:01:10 +00002340 ThrowMSLException(OptionError,"NoImagesDefined",
2341 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002342 break;
2343 }
2344 if (attributes != (const xmlChar **) NULL)
2345 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2346 {
2347 keyword=(const char *) attributes[i++];
2348 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002349 msl_info->attributes[n],(const char *) attributes[i],
2350 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002351 CloneString(&value,attribute);
2352 switch (*keyword)
2353 {
2354 default:
2355 {
2356 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2357 keyword);
2358 break;
2359 }
2360 }
2361 }
cristy051718b2011-08-28 22:49:25 +00002362 (void) DisplayImages(msl_info->image_info[n],msl_info->image[n],
cristyc82a27b2011-10-21 01:07:16 +00002363 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00002364 break;
2365 }
cristyb988fe72009-09-16 01:01:10 +00002366 if (LocaleCompare((const char *) tag,"draw") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002367 {
2368 char
2369 text[MaxTextExtent];
2370
2371 /*
2372 Annotate image.
2373 */
2374 if (msl_info->image[n] == (Image *) NULL)
2375 {
cristyb988fe72009-09-16 01:01:10 +00002376 ThrowMSLException(OptionError,"NoImagesDefined",
2377 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002378 break;
2379 }
2380 draw_info=CloneDrawInfo(msl_info->image_info[n],
2381 msl_info->draw_info[n]);
2382 angle=0.0;
2383 current=draw_info->affine;
2384 GetAffineMatrix(&affine);
2385 if (attributes != (const xmlChar **) NULL)
2386 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2387 {
2388 keyword=(const char *) attributes[i++];
2389 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002390 msl_info->attributes[n],(const char *) attributes[i],
2391 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002392 CloneString(&value,attribute);
2393 switch (*keyword)
2394 {
2395 case 'A':
2396 case 'a':
2397 {
2398 if (LocaleCompare(keyword,"affine") == 0)
2399 {
2400 char
2401 *p;
2402
2403 p=value;
cristydbdd0e32011-11-04 23:29:40 +00002404 draw_info->affine.sx=StringToDouble(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00002405 if (*p ==',')
2406 p++;
cristydbdd0e32011-11-04 23:29:40 +00002407 draw_info->affine.rx=StringToDouble(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00002408 if (*p ==',')
2409 p++;
cristydbdd0e32011-11-04 23:29:40 +00002410 draw_info->affine.ry=StringToDouble(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00002411 if (*p ==',')
2412 p++;
cristydbdd0e32011-11-04 23:29:40 +00002413 draw_info->affine.sy=StringToDouble(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00002414 if (*p ==',')
2415 p++;
cristydbdd0e32011-11-04 23:29:40 +00002416 draw_info->affine.tx=StringToDouble(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00002417 if (*p ==',')
2418 p++;
cristydbdd0e32011-11-04 23:29:40 +00002419 draw_info->affine.ty=StringToDouble(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00002420 break;
2421 }
2422 if (LocaleCompare(keyword,"align") == 0)
2423 {
cristy042ee782011-04-22 18:48:30 +00002424 option=ParseCommandOption(MagickAlignOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002425 value);
2426 if (option < 0)
2427 ThrowMSLException(OptionError,"UnrecognizedAlignType",
2428 value);
2429 draw_info->align=(AlignType) option;
2430 break;
2431 }
2432 if (LocaleCompare(keyword,"antialias") == 0)
2433 {
cristy042ee782011-04-22 18:48:30 +00002434 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002435 value);
2436 if (option < 0)
2437 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
2438 value);
2439 draw_info->stroke_antialias=(MagickBooleanType) option;
2440 draw_info->text_antialias=(MagickBooleanType) option;
2441 break;
2442 }
2443 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2444 keyword);
2445 break;
2446 }
2447 case 'D':
2448 case 'd':
2449 {
2450 if (LocaleCompare(keyword,"density") == 0)
2451 {
2452 CloneString(&draw_info->density,value);
2453 break;
2454 }
2455 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2456 keyword);
2457 break;
2458 }
2459 case 'E':
2460 case 'e':
2461 {
2462 if (LocaleCompare(keyword,"encoding") == 0)
2463 {
2464 CloneString(&draw_info->encoding,value);
2465 break;
2466 }
2467 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2468 keyword);
2469 break;
2470 }
2471 case 'F':
2472 case 'f':
2473 {
2474 if (LocaleCompare(keyword, "fill") == 0)
2475 {
cristy9950d572011-10-01 18:22:35 +00002476 (void) QueryColorCompliance(value,AllCompliance,
2477 &draw_info->fill,&exception);
cristy3ed852e2009-09-05 21:47:34 +00002478 break;
2479 }
2480 if (LocaleCompare(keyword,"family") == 0)
2481 {
2482 CloneString(&draw_info->family,value);
2483 break;
2484 }
2485 if (LocaleCompare(keyword,"font") == 0)
2486 {
2487 CloneString(&draw_info->font,value);
2488 break;
2489 }
2490 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2491 keyword);
2492 break;
2493 }
2494 case 'G':
2495 case 'g':
2496 {
2497 if (LocaleCompare(keyword,"geometry") == 0)
2498 {
2499 flags=ParsePageGeometry(msl_info->image[n],value,
2500 &geometry,&exception);
2501 if ((flags & HeightValue) == 0)
2502 geometry.height=geometry.width;
2503 break;
2504 }
2505 if (LocaleCompare(keyword,"gravity") == 0)
2506 {
cristy042ee782011-04-22 18:48:30 +00002507 option=ParseCommandOption(MagickGravityOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002508 value);
2509 if (option < 0)
2510 ThrowMSLException(OptionError,"UnrecognizedGravityType",
2511 value);
2512 draw_info->gravity=(GravityType) option;
2513 break;
2514 }
2515 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2516 keyword);
2517 break;
2518 }
2519 case 'P':
2520 case 'p':
2521 {
2522 if (LocaleCompare(keyword,"primitive") == 0)
cristyb988fe72009-09-16 01:01:10 +00002523 {
cristy3ed852e2009-09-05 21:47:34 +00002524 CloneString(&draw_info->primitive,value);
2525 break;
2526 }
2527 if (LocaleCompare(keyword,"pointsize") == 0)
2528 {
cristydbdd0e32011-11-04 23:29:40 +00002529 draw_info->pointsize=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00002530 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002531 break;
2532 }
2533 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2534 keyword);
2535 break;
2536 }
2537 case 'R':
2538 case 'r':
2539 {
2540 if (LocaleCompare(keyword,"rotate") == 0)
2541 {
cristydbdd0e32011-11-04 23:29:40 +00002542 angle=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002543 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
2544 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
2545 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
2546 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
2547 break;
2548 }
2549 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2550 keyword);
2551 break;
2552 }
2553 case 'S':
2554 case 's':
2555 {
2556 if (LocaleCompare(keyword,"scale") == 0)
2557 {
2558 flags=ParseGeometry(value,&geometry_info);
2559 if ((flags & SigmaValue) == 0)
2560 geometry_info.sigma=1.0;
2561 affine.sx=geometry_info.rho;
2562 affine.sy=geometry_info.sigma;
2563 break;
2564 }
2565 if (LocaleCompare(keyword,"skewX") == 0)
2566 {
cristydbdd0e32011-11-04 23:29:40 +00002567 angle=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002568 affine.ry=cos(DegreesToRadians(fmod(angle,360.0)));
2569 break;
2570 }
2571 if (LocaleCompare(keyword,"skewY") == 0)
2572 {
cristydbdd0e32011-11-04 23:29:40 +00002573 angle=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002574 affine.rx=cos(DegreesToRadians(fmod(angle,360.0)));
2575 break;
2576 }
2577 if (LocaleCompare(keyword,"stretch") == 0)
2578 {
cristy9950d572011-10-01 18:22:35 +00002579 option=ParseCommandOption(MagickStretchOptions,
2580 MagickFalse,value);
cristy3ed852e2009-09-05 21:47:34 +00002581 if (option < 0)
2582 ThrowMSLException(OptionError,"UnrecognizedStretchType",
2583 value);
2584 draw_info->stretch=(StretchType) option;
2585 break;
2586 }
2587 if (LocaleCompare(keyword, "stroke") == 0)
2588 {
cristy9950d572011-10-01 18:22:35 +00002589 (void) QueryColorCompliance(value,AllCompliance,
2590 &draw_info->stroke,&exception);
cristy3ed852e2009-09-05 21:47:34 +00002591 break;
2592 }
2593 if (LocaleCompare(keyword,"strokewidth") == 0)
2594 {
cristyf2f27272009-12-17 14:48:46 +00002595 draw_info->stroke_width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002596 break;
2597 }
2598 if (LocaleCompare(keyword,"style") == 0)
2599 {
cristy042ee782011-04-22 18:48:30 +00002600 option=ParseCommandOption(MagickStyleOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002601 value);
2602 if (option < 0)
2603 ThrowMSLException(OptionError,"UnrecognizedStyleType",
2604 value);
2605 draw_info->style=(StyleType) option;
2606 break;
2607 }
2608 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2609 keyword);
2610 break;
2611 }
2612 case 'T':
2613 case 't':
2614 {
2615 if (LocaleCompare(keyword,"text") == 0)
2616 {
2617 CloneString(&draw_info->text,value);
2618 break;
2619 }
2620 if (LocaleCompare(keyword,"translate") == 0)
2621 {
2622 flags=ParseGeometry(value,&geometry_info);
2623 if ((flags & SigmaValue) == 0)
2624 geometry_info.sigma=1.0;
2625 affine.tx=geometry_info.rho;
2626 affine.ty=geometry_info.sigma;
2627 break;
2628 }
2629 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2630 keyword);
2631 break;
2632 }
2633 case 'U':
2634 case 'u':
2635 {
2636 if (LocaleCompare(keyword, "undercolor") == 0)
2637 {
cristy9950d572011-10-01 18:22:35 +00002638 (void) QueryColorCompliance(value,AllCompliance,
2639 &draw_info->undercolor,&exception);
cristy3ed852e2009-09-05 21:47:34 +00002640 break;
2641 }
2642 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2643 keyword);
2644 break;
2645 }
2646 case 'W':
2647 case 'w':
2648 {
2649 if (LocaleCompare(keyword,"weight") == 0)
2650 {
cristyf2f27272009-12-17 14:48:46 +00002651 draw_info->weight=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002652 break;
2653 }
2654 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2655 keyword);
2656 break;
2657 }
2658 case 'X':
2659 case 'x':
2660 {
2661 if (LocaleCompare(keyword,"x") == 0)
2662 {
cristyf2f27272009-12-17 14:48:46 +00002663 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002664 break;
2665 }
2666 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2667 keyword);
2668 break;
2669 }
2670 case 'Y':
2671 case 'y':
2672 {
2673 if (LocaleCompare(keyword,"y") == 0)
2674 {
cristyf2f27272009-12-17 14:48:46 +00002675 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002676 break;
2677 }
2678 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2679 keyword);
2680 break;
2681 }
2682 default:
2683 {
2684 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2685 keyword);
2686 break;
2687 }
2688 }
2689 }
cristyb51dff52011-05-19 16:55:47 +00002690 (void) FormatLocaleString(text,MaxTextExtent,
cristye8c25f92010-06-03 00:53:06 +00002691 "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,(double)
2692 geometry.height,(double) geometry.x,(double) geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00002693 CloneString(&draw_info->geometry,text);
cristyef7c8a52010-10-10 13:46:51 +00002694 draw_info->affine.sx=affine.sx*current.sx+affine.ry*current.rx;
2695 draw_info->affine.rx=affine.rx*current.sx+affine.sy*current.rx;
2696 draw_info->affine.ry=affine.sx*current.ry+affine.ry*current.sy;
2697 draw_info->affine.sy=affine.rx*current.ry+affine.sy*current.sy;
2698 draw_info->affine.tx=affine.sx*current.tx+affine.ry*current.ty+
2699 affine.tx;
2700 draw_info->affine.ty=affine.rx*current.tx+affine.sy*current.ty+
2701 affine.ty;
cristy018f07f2011-09-04 21:15:19 +00002702 (void) DrawImage(msl_info->image[n],draw_info,&exception);
cristy3ed852e2009-09-05 21:47:34 +00002703 draw_info=DestroyDrawInfo(draw_info);
2704 break;
2705 }
2706 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
2707 }
2708 case 'E':
2709 case 'e':
2710 {
cristyb988fe72009-09-16 01:01:10 +00002711 if (LocaleCompare((const char *) tag,"edge") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002712 {
2713 Image
2714 *edge_image;
2715
2716 /*
2717 Edge image.
2718 */
2719 if (msl_info->image[n] == (Image *) NULL)
2720 {
cristyb988fe72009-09-16 01:01:10 +00002721 ThrowMSLException(OptionError,"NoImagesDefined",
2722 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002723 break;
2724 }
2725 if (attributes != (const xmlChar **) NULL)
2726 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2727 {
2728 keyword=(const char *) attributes[i++];
2729 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002730 msl_info->attributes[n],(const char *) attributes[i],
2731 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002732 CloneString(&value,attribute);
2733 switch (*keyword)
2734 {
2735 case 'G':
2736 case 'g':
2737 {
2738 if (LocaleCompare(keyword,"geometry") == 0)
2739 {
2740 flags=ParseGeometry(value,&geometry_info);
2741 if ((flags & SigmaValue) == 0)
2742 geometry_info.sigma=1.0;
2743 break;
2744 }
2745 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2746 keyword);
2747 break;
2748 }
2749 case 'R':
2750 case 'r':
2751 {
2752 if (LocaleCompare(keyword,"radius") == 0)
2753 {
cristy9b34e302011-11-05 02:15:45 +00002754 geometry_info.rho=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002755 break;
2756 }
2757 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2758 keyword);
2759 break;
2760 }
2761 default:
2762 {
2763 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2764 keyword);
2765 break;
2766 }
2767 }
2768 }
2769 edge_image=EdgeImage(msl_info->image[n],geometry_info.rho,
cristyc82a27b2011-10-21 01:07:16 +00002770 geometry_info.sigma,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00002771 if (edge_image == (Image *) NULL)
2772 break;
2773 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2774 msl_info->image[n]=edge_image;
2775 break;
2776 }
cristyb988fe72009-09-16 01:01:10 +00002777 if (LocaleCompare((const char *) tag,"emboss") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002778 {
2779 Image
2780 *emboss_image;
2781
2782 /*
2783 Emboss image.
2784 */
2785 if (msl_info->image[n] == (Image *) NULL)
2786 {
cristyb988fe72009-09-16 01:01:10 +00002787 ThrowMSLException(OptionError,"NoImagesDefined",
2788 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002789 break;
2790 }
2791 if (attributes != (const xmlChar **) NULL)
2792 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2793 {
2794 keyword=(const char *) attributes[i++];
2795 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002796 msl_info->attributes[n],(const char *) attributes[i],
2797 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002798 CloneString(&value,attribute);
2799 switch (*keyword)
2800 {
2801 case 'G':
2802 case 'g':
2803 {
2804 if (LocaleCompare(keyword,"geometry") == 0)
2805 {
2806 flags=ParseGeometry(value,&geometry_info);
2807 if ((flags & SigmaValue) == 0)
2808 geometry_info.sigma=1.0;
2809 break;
2810 }
2811 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2812 keyword);
2813 break;
2814 }
2815 case 'R':
2816 case 'r':
2817 {
2818 if (LocaleCompare(keyword,"radius") == 0)
2819 {
cristydbdd0e32011-11-04 23:29:40 +00002820 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00002821 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002822 break;
2823 }
2824 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2825 keyword);
2826 break;
2827 }
2828 case 'S':
2829 case 's':
2830 {
2831 if (LocaleCompare(keyword,"sigma") == 0)
2832 {
cristyf2f27272009-12-17 14:48:46 +00002833 geometry_info.sigma=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002834 break;
2835 }
2836 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2837 keyword);
2838 break;
2839 }
2840 default:
2841 {
2842 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2843 keyword);
2844 break;
2845 }
2846 }
2847 }
2848 emboss_image=EmbossImage(msl_info->image[n],geometry_info.rho,
cristyc82a27b2011-10-21 01:07:16 +00002849 geometry_info.sigma,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00002850 if (emboss_image == (Image *) NULL)
2851 break;
2852 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2853 msl_info->image[n]=emboss_image;
2854 break;
2855 }
cristyb988fe72009-09-16 01:01:10 +00002856 if (LocaleCompare((const char *) tag,"enhance") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002857 {
2858 Image
2859 *enhance_image;
2860
2861 /*
2862 Enhance image.
2863 */
2864 if (msl_info->image[n] == (Image *) NULL)
2865 {
cristyb988fe72009-09-16 01:01:10 +00002866 ThrowMSLException(OptionError,"NoImagesDefined",
2867 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002868 break;
2869 }
2870 if (attributes != (const xmlChar **) NULL)
2871 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2872 {
2873 keyword=(const char *) attributes[i++];
2874 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002875 msl_info->attributes[n],(const char *) attributes[i],
2876 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002877 CloneString(&value,attribute);
2878 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
2879 }
2880 enhance_image=EnhanceImage(msl_info->image[n],
cristyc82a27b2011-10-21 01:07:16 +00002881 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00002882 if (enhance_image == (Image *) NULL)
2883 break;
2884 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2885 msl_info->image[n]=enhance_image;
2886 break;
2887 }
cristyb988fe72009-09-16 01:01:10 +00002888 if (LocaleCompare((const char *) tag,"equalize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002889 {
2890 /*
2891 Equalize image.
2892 */
2893 if (msl_info->image[n] == (Image *) NULL)
2894 {
cristyb988fe72009-09-16 01:01:10 +00002895 ThrowMSLException(OptionError,"NoImagesDefined",
2896 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002897 break;
2898 }
2899 if (attributes != (const xmlChar **) NULL)
2900 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2901 {
2902 keyword=(const char *) attributes[i++];
2903 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002904 msl_info->attributes[n],(const char *) attributes[i],
2905 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002906 CloneString(&value,attribute);
2907 switch (*keyword)
2908 {
2909 default:
2910 {
2911 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2912 keyword);
2913 break;
2914 }
2915 }
2916 }
cristy6d8c3d72011-08-22 01:20:01 +00002917 (void) EqualizeImage(msl_info->image[n],
cristyc82a27b2011-10-21 01:07:16 +00002918 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00002919 break;
2920 }
2921 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
2922 }
2923 case 'F':
2924 case 'f':
2925 {
cristyb988fe72009-09-16 01:01:10 +00002926 if (LocaleCompare((const char *) tag, "flatten") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002927 {
2928 if (msl_info->image[n] == (Image *) NULL)
2929 {
cristyb988fe72009-09-16 01:01:10 +00002930 ThrowMSLException(OptionError,"NoImagesDefined",
2931 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002932 break;
2933 }
2934
2935 /* no attributes here */
2936
2937 /* process the image */
2938 {
2939 Image
2940 *newImage;
2941
2942 newImage=MergeImageLayers(msl_info->image[n],FlattenLayer,
cristyc82a27b2011-10-21 01:07:16 +00002943 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00002944 if (newImage == (Image *) NULL)
2945 break;
2946 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2947 msl_info->image[n]=newImage;
2948 break;
2949 }
2950 }
cristyb988fe72009-09-16 01:01:10 +00002951 if (LocaleCompare((const char *) tag,"flip") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002952 {
2953 Image
2954 *flip_image;
2955
2956 /*
2957 Flip image.
2958 */
2959 if (msl_info->image[n] == (Image *) NULL)
2960 {
cristyb988fe72009-09-16 01:01:10 +00002961 ThrowMSLException(OptionError,"NoImagesDefined",
2962 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002963 break;
2964 }
2965 if (attributes != (const xmlChar **) NULL)
2966 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2967 {
2968 keyword=(const char *) attributes[i++];
2969 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002970 msl_info->attributes[n],(const char *) attributes[i],
2971 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002972 CloneString(&value,attribute);
2973 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
2974 }
2975 flip_image=FlipImage(msl_info->image[n],
cristyc82a27b2011-10-21 01:07:16 +00002976 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00002977 if (flip_image == (Image *) NULL)
2978 break;
2979 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2980 msl_info->image[n]=flip_image;
2981 break;
2982 }
cristyb988fe72009-09-16 01:01:10 +00002983 if (LocaleCompare((const char *) tag,"flop") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002984 {
2985 Image
2986 *flop_image;
2987
2988 /*
2989 Flop image.
2990 */
2991 if (msl_info->image[n] == (Image *) NULL)
2992 {
cristyb988fe72009-09-16 01:01:10 +00002993 ThrowMSLException(OptionError,"NoImagesDefined",
2994 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002995 break;
2996 }
2997 if (attributes != (const xmlChar **) NULL)
2998 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2999 {
3000 keyword=(const char *) attributes[i++];
3001 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003002 msl_info->attributes[n],(const char *) attributes[i],
3003 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003004 CloneString(&value,attribute);
3005 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3006 }
3007 flop_image=FlopImage(msl_info->image[n],
cristyc82a27b2011-10-21 01:07:16 +00003008 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00003009 if (flop_image == (Image *) NULL)
3010 break;
3011 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3012 msl_info->image[n]=flop_image;
3013 break;
3014 }
cristyb988fe72009-09-16 01:01:10 +00003015 if (LocaleCompare((const char *) tag,"frame") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003016 {
3017 FrameInfo
3018 frame_info;
3019
3020 Image
3021 *frame_image;
3022
3023 /*
3024 Frame image.
3025 */
3026 if (msl_info->image[n] == (Image *) NULL)
3027 {
cristyb988fe72009-09-16 01:01:10 +00003028 ThrowMSLException(OptionError,"NoImagesDefined",
3029 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003030 break;
3031 }
3032 SetGeometry(msl_info->image[n],&geometry);
3033 if (attributes != (const xmlChar **) NULL)
3034 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3035 {
3036 keyword=(const char *) attributes[i++];
3037 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003038 msl_info->attributes[n],(const char *) attributes[i],
3039 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003040 CloneString(&value,attribute);
3041 switch (*keyword)
3042 {
3043 case 'C':
3044 case 'c':
3045 {
3046 if (LocaleCompare(keyword,"compose") == 0)
3047 {
cristy042ee782011-04-22 18:48:30 +00003048 option=ParseCommandOption(MagickComposeOptions,
cristy3ed852e2009-09-05 21:47:34 +00003049 MagickFalse,value);
3050 if (option < 0)
3051 ThrowMSLException(OptionError,"UnrecognizedComposeType",
3052 value);
3053 msl_info->image[n]->compose=(CompositeOperator) option;
3054 break;
3055 }
3056 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3057 keyword);
3058 break;
3059 }
3060 case 'F':
3061 case 'f':
3062 {
3063 if (LocaleCompare(keyword, "fill") == 0)
3064 {
cristy9950d572011-10-01 18:22:35 +00003065 (void) QueryColorCompliance(value,AllCompliance,
cristy3ed852e2009-09-05 21:47:34 +00003066 &msl_info->image[n]->matte_color,&exception);
3067 break;
3068 }
3069 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3070 keyword);
3071 break;
3072 }
3073 case 'G':
3074 case 'g':
3075 {
3076 if (LocaleCompare(keyword,"geometry") == 0)
3077 {
3078 flags=ParsePageGeometry(msl_info->image[n],value,
3079 &geometry,&exception);
3080 if ((flags & HeightValue) == 0)
3081 geometry.height=geometry.width;
3082 frame_info.width=geometry.width;
3083 frame_info.height=geometry.height;
3084 frame_info.outer_bevel=geometry.x;
3085 frame_info.inner_bevel=geometry.y;
3086 break;
3087 }
3088 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3089 keyword);
3090 break;
3091 }
3092 case 'H':
3093 case 'h':
3094 {
3095 if (LocaleCompare(keyword,"height") == 0)
3096 {
cristyf2f27272009-12-17 14:48:46 +00003097 frame_info.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003098 break;
3099 }
3100 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3101 keyword);
3102 break;
3103 }
3104 case 'I':
3105 case 'i':
3106 {
3107 if (LocaleCompare(keyword,"inner") == 0)
3108 {
cristyf2f27272009-12-17 14:48:46 +00003109 frame_info.inner_bevel=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003110 break;
3111 }
3112 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3113 keyword);
3114 break;
3115 }
3116 case 'O':
3117 case 'o':
3118 {
3119 if (LocaleCompare(keyword,"outer") == 0)
3120 {
cristyf2f27272009-12-17 14:48:46 +00003121 frame_info.outer_bevel=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003122 break;
3123 }
3124 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3125 keyword);
3126 break;
3127 }
3128 case 'W':
3129 case 'w':
3130 {
3131 if (LocaleCompare(keyword,"width") == 0)
3132 {
cristyf2f27272009-12-17 14:48:46 +00003133 frame_info.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003134 break;
3135 }
3136 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3137 keyword);
3138 break;
3139 }
3140 default:
3141 {
3142 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3143 keyword);
3144 break;
3145 }
3146 }
3147 }
cristybb503372010-05-27 20:51:26 +00003148 frame_info.x=(ssize_t) frame_info.width;
3149 frame_info.y=(ssize_t) frame_info.height;
cristy3ed852e2009-09-05 21:47:34 +00003150 frame_info.width=msl_info->image[n]->columns+2*frame_info.x;
3151 frame_info.height=msl_info->image[n]->rows+2*frame_info.y;
3152 frame_image=FrameImage(msl_info->image[n],&frame_info,
cristyc82a27b2011-10-21 01:07:16 +00003153 msl_info->image[n]->compose,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00003154 if (frame_image == (Image *) NULL)
3155 break;
3156 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3157 msl_info->image[n]=frame_image;
3158 break;
3159 }
3160 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3161 }
3162 case 'G':
3163 case 'g':
3164 {
cristyb988fe72009-09-16 01:01:10 +00003165 if (LocaleCompare((const char *) tag,"gamma") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003166 {
3167 char
3168 gamma[MaxTextExtent];
3169
cristy4c08aed2011-07-01 19:47:50 +00003170 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00003171 pixel;
3172
3173 /*
3174 Gamma image.
3175 */
3176 if (msl_info->image[n] == (Image *) NULL)
3177 {
cristyb988fe72009-09-16 01:01:10 +00003178 ThrowMSLException(OptionError,"NoImagesDefined",
3179 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003180 break;
3181 }
3182 channel=UndefinedChannel;
3183 pixel.red=0.0;
3184 pixel.green=0.0;
3185 pixel.blue=0.0;
3186 *gamma='\0';
3187 if (attributes != (const xmlChar **) NULL)
3188 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3189 {
3190 keyword=(const char *) attributes[i++];
3191 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003192 msl_info->attributes[n],(const char *) attributes[i],
3193 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003194 CloneString(&value,attribute);
3195 switch (*keyword)
3196 {
3197 case 'B':
3198 case 'b':
3199 {
3200 if (LocaleCompare(keyword,"blue") == 0)
3201 {
cristydbdd0e32011-11-04 23:29:40 +00003202 pixel.blue=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003203 break;
3204 }
3205 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3206 keyword);
3207 break;
3208 }
3209 case 'C':
3210 case 'c':
3211 {
3212 if (LocaleCompare(keyword,"channel") == 0)
3213 {
3214 option=ParseChannelOption(value);
3215 if (option < 0)
3216 ThrowMSLException(OptionError,"UnrecognizedChannelType",
3217 value);
3218 channel=(ChannelType) option;
3219 break;
3220 }
3221 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3222 keyword);
3223 break;
3224 }
3225 case 'G':
3226 case 'g':
3227 {
3228 if (LocaleCompare(keyword,"gamma") == 0)
3229 {
3230 (void) CopyMagickString(gamma,value,MaxTextExtent);
3231 break;
3232 }
3233 if (LocaleCompare(keyword,"green") == 0)
3234 {
cristydbdd0e32011-11-04 23:29:40 +00003235 pixel.green=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003236 break;
3237 }
3238 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3239 keyword);
3240 break;
3241 }
3242 case 'R':
3243 case 'r':
3244 {
3245 if (LocaleCompare(keyword,"red") == 0)
3246 {
cristydbdd0e32011-11-04 23:29:40 +00003247 pixel.red=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003248 break;
3249 }
3250 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3251 keyword);
3252 break;
3253 }
3254 default:
3255 {
3256 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3257 keyword);
3258 break;
3259 }
3260 }
3261 }
3262 if (*gamma == '\0')
cristyb51dff52011-05-19 16:55:47 +00003263 (void) FormatLocaleString(gamma,MaxTextExtent,"%g,%g,%g",
cristy3ed852e2009-09-05 21:47:34 +00003264 (double) pixel.red,(double) pixel.green,(double) pixel.blue);
cristyb3e7c6c2011-07-24 01:43:55 +00003265 (void) GammaImage(msl_info->image[n],atof(gamma),
cristyc82a27b2011-10-21 01:07:16 +00003266 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00003267 break;
3268 }
cristyb988fe72009-09-16 01:01:10 +00003269 else if (LocaleCompare((const char *) tag,"get") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003270 {
3271 if (msl_info->image[n] == (Image *) NULL)
3272 {
cristyb988fe72009-09-16 01:01:10 +00003273 ThrowMSLException(OptionError,"NoImagesDefined",
3274 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003275 break;
3276 }
3277 if (attributes == (const xmlChar **) NULL)
3278 break;
3279 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3280 {
3281 keyword=(const char *) attributes[i++];
cristyb988fe72009-09-16 01:01:10 +00003282 CloneString(&value,(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003283 (void) CopyMagickString(key,value,MaxTextExtent);
3284 switch (*keyword)
3285 {
3286 case 'H':
3287 case 'h':
3288 {
3289 if (LocaleCompare(keyword,"height") == 0)
3290 {
cristyb51dff52011-05-19 16:55:47 +00003291 (void) FormatLocaleString(value,MaxTextExtent,"%.20g",
cristye8c25f92010-06-03 00:53:06 +00003292 (double) msl_info->image[n]->rows);
cristyd15e6592011-10-15 00:13:06 +00003293 (void) SetImageProperty(msl_info->attributes[n],key,value,
3294 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003295 break;
3296 }
3297 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3298 }
3299 case 'W':
3300 case 'w':
3301 {
3302 if (LocaleCompare(keyword,"width") == 0)
3303 {
cristyb51dff52011-05-19 16:55:47 +00003304 (void) FormatLocaleString(value,MaxTextExtent,"%.20g",
cristye8c25f92010-06-03 00:53:06 +00003305 (double) msl_info->image[n]->columns);
cristyd15e6592011-10-15 00:13:06 +00003306 (void) SetImageProperty(msl_info->attributes[n],key,value,
3307 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003308 break;
3309 }
3310 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3311 }
3312 default:
3313 {
3314 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3315 break;
3316 }
3317 }
3318 }
3319 break;
3320 }
cristyb988fe72009-09-16 01:01:10 +00003321 else if (LocaleCompare((const char *) tag, "group") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003322 {
3323 msl_info->number_groups++;
3324 msl_info->group_info=(MSLGroupInfo *) ResizeQuantumMemory(
3325 msl_info->group_info,msl_info->number_groups+1UL,
3326 sizeof(*msl_info->group_info));
3327 break;
3328 }
3329 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3330 }
3331 case 'I':
3332 case 'i':
3333 {
cristyb988fe72009-09-16 01:01:10 +00003334 if (LocaleCompare((const char *) tag,"image") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003335 {
cristy3ed852e2009-09-05 21:47:34 +00003336 MSLPushImage(msl_info,(Image *) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003337 if (attributes == (const xmlChar **) NULL)
3338 break;
3339 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3340 {
3341 keyword=(const char *) attributes[i++];
3342 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003343 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00003344 switch (*keyword)
3345 {
cristyb988fe72009-09-16 01:01:10 +00003346 case 'C':
3347 case 'c':
cristy3ed852e2009-09-05 21:47:34 +00003348 {
cristyb988fe72009-09-16 01:01:10 +00003349 if (LocaleCompare(keyword,"color") == 0)
3350 {
3351 Image
3352 *next_image;
cristy3ed852e2009-09-05 21:47:34 +00003353
cristyb988fe72009-09-16 01:01:10 +00003354 (void) CopyMagickString(msl_info->image_info[n]->filename,
3355 "xc:",MaxTextExtent);
3356 (void) ConcatenateMagickString(msl_info->image_info[n]->
3357 filename,value,MaxTextExtent);
3358 next_image=ReadImage(msl_info->image_info[n],&exception);
3359 CatchException(&exception);
3360 if (next_image == (Image *) NULL)
3361 continue;
3362 if (msl_info->image[n] == (Image *) NULL)
3363 msl_info->image[n]=next_image;
3364 else
3365 {
3366 register Image
3367 *p;
cristy3ed852e2009-09-05 21:47:34 +00003368
cristyb988fe72009-09-16 01:01:10 +00003369 /*
3370 Link image into image list.
3371 */
3372 p=msl_info->image[n];
3373 while (p->next != (Image *) NULL)
3374 p=GetNextImageInList(p);
3375 next_image->previous=p;
3376 p->next=next_image;
3377 }
3378 break;
3379 }
cristyb20775d2009-09-16 01:51:41 +00003380 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00003381 break;
3382 }
3383 default:
3384 {
cristyb20775d2009-09-16 01:51:41 +00003385 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00003386 break;
3387 }
3388 }
3389 }
3390 break;
3391 }
cristyb988fe72009-09-16 01:01:10 +00003392 if (LocaleCompare((const char *) tag,"implode") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003393 {
3394 Image
3395 *implode_image;
3396
3397 /*
3398 Implode image.
3399 */
3400 if (msl_info->image[n] == (Image *) NULL)
3401 {
cristyb988fe72009-09-16 01:01:10 +00003402 ThrowMSLException(OptionError,"NoImagesDefined",
3403 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003404 break;
3405 }
3406 if (attributes != (const xmlChar **) NULL)
3407 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3408 {
3409 keyword=(const char *) attributes[i++];
3410 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003411 msl_info->attributes[n],(const char *) attributes[i],
3412 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003413 CloneString(&value,attribute);
3414 switch (*keyword)
3415 {
3416 case 'A':
3417 case 'a':
3418 {
3419 if (LocaleCompare(keyword,"amount") == 0)
3420 {
cristydbdd0e32011-11-04 23:29:40 +00003421 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00003422 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003423 break;
3424 }
3425 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3426 keyword);
3427 break;
3428 }
3429 case 'G':
3430 case 'g':
3431 {
3432 if (LocaleCompare(keyword,"geometry") == 0)
3433 {
3434 flags=ParseGeometry(value,&geometry_info);
3435 if ((flags & SigmaValue) == 0)
3436 geometry_info.sigma=1.0;
3437 break;
3438 }
3439 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3440 keyword);
3441 break;
3442 }
3443 default:
3444 {
3445 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3446 keyword);
3447 break;
3448 }
3449 }
3450 }
3451 implode_image=ImplodeImage(msl_info->image[n],geometry_info.rho,
cristyc82a27b2011-10-21 01:07:16 +00003452 msl_info->image[n]->interpolate,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00003453 if (implode_image == (Image *) NULL)
3454 break;
3455 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3456 msl_info->image[n]=implode_image;
3457 break;
3458 }
3459 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3460 }
3461 case 'L':
3462 case 'l':
3463 {
cristyb988fe72009-09-16 01:01:10 +00003464 if (LocaleCompare((const char *) tag,"label") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003465 break;
cristyb988fe72009-09-16 01:01:10 +00003466 if (LocaleCompare((const char *) tag, "level") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003467 {
3468 double
3469 levelBlack = 0, levelGamma = 1, levelWhite = QuantumRange;
3470
3471 if (msl_info->image[n] == (Image *) NULL)
3472 {
cristyb988fe72009-09-16 01:01:10 +00003473 ThrowMSLException(OptionError,"NoImagesDefined",
3474 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003475 break;
3476 }
3477 if (attributes == (const xmlChar **) NULL)
3478 break;
3479 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3480 {
3481 keyword=(const char *) attributes[i++];
cristyb988fe72009-09-16 01:01:10 +00003482 CloneString(&value,(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003483 (void) CopyMagickString(key,value,MaxTextExtent);
3484 switch (*keyword)
3485 {
3486 case 'B':
3487 case 'b':
3488 {
3489 if (LocaleCompare(keyword,"black") == 0)
3490 {
cristydbdd0e32011-11-04 23:29:40 +00003491 levelBlack = StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003492 break;
3493 }
3494 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3495 break;
3496 }
3497 case 'G':
3498 case 'g':
3499 {
3500 if (LocaleCompare(keyword,"gamma") == 0)
3501 {
cristydbdd0e32011-11-04 23:29:40 +00003502 levelGamma = StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003503 break;
3504 }
3505 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3506 break;
3507 }
3508 case 'W':
3509 case 'w':
3510 {
3511 if (LocaleCompare(keyword,"white") == 0)
3512 {
cristydbdd0e32011-11-04 23:29:40 +00003513 levelWhite = StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003514 break;
3515 }
3516 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3517 break;
3518 }
3519 default:
3520 {
3521 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3522 break;
3523 }
3524 }
3525 }
3526
3527 /* process image */
cristy01e9afd2011-08-10 17:38:41 +00003528 LevelImage(msl_info->image[n],levelBlack,levelWhite,levelGamma,
cristyc82a27b2011-10-21 01:07:16 +00003529 msl_info->exception);
cristyf89cb1d2011-07-07 01:24:37 +00003530 break;
cristy3ed852e2009-09-05 21:47:34 +00003531 }
3532 }
3533 case 'M':
3534 case 'm':
3535 {
cristyb988fe72009-09-16 01:01:10 +00003536 if (LocaleCompare((const char *) tag,"magnify") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003537 {
3538 Image
3539 *magnify_image;
3540
3541 /*
3542 Magnify image.
3543 */
3544 if (msl_info->image[n] == (Image *) NULL)
3545 {
cristyb988fe72009-09-16 01:01:10 +00003546 ThrowMSLException(OptionError,"NoImagesDefined",
3547 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003548 break;
3549 }
3550 if (attributes != (const xmlChar **) NULL)
3551 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3552 {
3553 keyword=(const char *) attributes[i++];
3554 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003555 msl_info->attributes[n],(const char *) attributes[i],
3556 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003557 CloneString(&value,attribute);
3558 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3559 }
3560 magnify_image=MagnifyImage(msl_info->image[n],
cristyc82a27b2011-10-21 01:07:16 +00003561 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00003562 if (magnify_image == (Image *) NULL)
3563 break;
3564 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3565 msl_info->image[n]=magnify_image;
3566 break;
3567 }
cristyb988fe72009-09-16 01:01:10 +00003568 if (LocaleCompare((const char *) tag,"map") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003569 {
3570 Image
3571 *affinity_image;
3572
3573 MagickBooleanType
3574 dither;
3575
3576 QuantizeInfo
3577 *quantize_info;
3578
3579 /*
3580 Map image.
3581 */
3582 if (msl_info->image[n] == (Image *) NULL)
3583 {
cristyb988fe72009-09-16 01:01:10 +00003584 ThrowMSLException(OptionError,"NoImagesDefined",
3585 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003586 break;
3587 }
3588 affinity_image=NewImageList();
3589 dither=MagickFalse;
3590 if (attributes != (const xmlChar **) NULL)
3591 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3592 {
3593 keyword=(const char *) attributes[i++];
3594 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003595 msl_info->attributes[n],(const char *) attributes[i],
3596 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003597 CloneString(&value,attribute);
3598 switch (*keyword)
3599 {
3600 case 'D':
3601 case 'd':
3602 {
3603 if (LocaleCompare(keyword,"dither") == 0)
3604 {
cristy042ee782011-04-22 18:48:30 +00003605 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00003606 value);
3607 if (option < 0)
3608 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
3609 value);
3610 dither=(MagickBooleanType) option;
3611 break;
3612 }
3613 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3614 keyword);
3615 break;
3616 }
3617 case 'I':
3618 case 'i':
3619 {
3620 if (LocaleCompare(keyword,"image") == 0)
3621 for (j=0; j < msl_info->n; j++)
3622 {
3623 const char
3624 *attribute;
cristyb988fe72009-09-16 01:01:10 +00003625
cristyd15e6592011-10-15 00:13:06 +00003626 attribute=GetImageProperty(msl_info->attributes[j],"id",
3627 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003628 if ((attribute != (const char *) NULL) &&
3629 (LocaleCompare(attribute,value) == 0))
3630 {
3631 affinity_image=CloneImage(msl_info->image[j],0,0,
3632 MagickFalse,&exception);
3633 break;
3634 }
3635 }
3636 break;
3637 }
3638 default:
3639 {
3640 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3641 keyword);
3642 break;
3643 }
3644 }
3645 }
3646 quantize_info=AcquireQuantizeInfo(msl_info->image_info[n]);
cristycbda6112012-05-27 20:57:16 +00003647 quantize_info->dither_method=dither != MagickFalse ?
3648 RiemersmaDitherMethod : NoDitherMethod;
cristy3ed852e2009-09-05 21:47:34 +00003649 (void) RemapImages(quantize_info,msl_info->image[n],
cristy018f07f2011-09-04 21:15:19 +00003650 affinity_image,&exception);
cristy3ed852e2009-09-05 21:47:34 +00003651 quantize_info=DestroyQuantizeInfo(quantize_info);
3652 affinity_image=DestroyImage(affinity_image);
3653 break;
3654 }
cristyb988fe72009-09-16 01:01:10 +00003655 if (LocaleCompare((const char *) tag,"matte-floodfill") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003656 {
3657 double
3658 opacity;
3659
cristy4c08aed2011-07-01 19:47:50 +00003660 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00003661 target;
3662
3663 PaintMethod
3664 paint_method;
3665
3666 /*
3667 Matte floodfill image.
3668 */
3669 opacity=0.0;
3670 if (msl_info->image[n] == (Image *) NULL)
3671 {
cristyb988fe72009-09-16 01:01:10 +00003672 ThrowMSLException(OptionError,"NoImagesDefined",
3673 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003674 break;
3675 }
3676 SetGeometry(msl_info->image[n],&geometry);
3677 paint_method=FloodfillMethod;
3678 if (attributes != (const xmlChar **) NULL)
3679 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3680 {
3681 keyword=(const char *) attributes[i++];
3682 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003683 msl_info->attributes[n],(const char *) attributes[i],
3684 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003685 CloneString(&value,attribute);
3686 switch (*keyword)
3687 {
3688 case 'B':
3689 case 'b':
3690 {
3691 if (LocaleCompare(keyword,"bordercolor") == 0)
3692 {
cristy269c9412011-10-13 23:41:15 +00003693 (void) QueryColorCompliance(value,AllCompliance,
cristy9950d572011-10-01 18:22:35 +00003694 &target,&exception);
cristy3ed852e2009-09-05 21:47:34 +00003695 paint_method=FillToBorderMethod;
3696 break;
3697 }
3698 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3699 keyword);
3700 break;
3701 }
3702 case 'F':
3703 case 'f':
3704 {
3705 if (LocaleCompare(keyword,"fuzz") == 0)
3706 {
cristydbdd0e32011-11-04 23:29:40 +00003707 msl_info->image[n]->fuzz=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00003708 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003709 break;
3710 }
3711 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3712 keyword);
3713 break;
3714 }
3715 case 'G':
3716 case 'g':
3717 {
3718 if (LocaleCompare(keyword,"geometry") == 0)
3719 {
3720 flags=ParsePageGeometry(msl_info->image[n],value,
3721 &geometry,&exception);
3722 if ((flags & HeightValue) == 0)
3723 geometry.height=geometry.width;
cristy3aa93752011-12-18 15:54:24 +00003724 (void) GetOneVirtualPixelInfo(msl_info->image[n],
cristy33e9da62011-10-21 19:08:58 +00003725 TileVirtualPixelMethod,geometry.x,geometry.y,&target,
3726 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003727 break;
3728 }
3729 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3730 keyword);
3731 break;
3732 }
3733 case 'O':
3734 case 'o':
3735 {
3736 if (LocaleCompare(keyword,"opacity") == 0)
3737 {
cristydbdd0e32011-11-04 23:29:40 +00003738 opacity=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003739 break;
3740 }
3741 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3742 keyword);
3743 break;
3744 }
3745 case 'X':
3746 case 'x':
3747 {
3748 if (LocaleCompare(keyword,"x") == 0)
3749 {
cristyf2f27272009-12-17 14:48:46 +00003750 geometry.x=StringToLong(value);
cristy3aa93752011-12-18 15:54:24 +00003751 (void) GetOneVirtualPixelInfo(msl_info->image[n],
cristy33e9da62011-10-21 19:08:58 +00003752 TileVirtualPixelMethod,geometry.x,geometry.y,&target,
3753 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003754 break;
3755 }
3756 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3757 keyword);
3758 break;
3759 }
3760 case 'Y':
3761 case 'y':
3762 {
3763 if (LocaleCompare(keyword,"y") == 0)
3764 {
cristyf2f27272009-12-17 14:48:46 +00003765 geometry.y=StringToLong(value);
cristy3aa93752011-12-18 15:54:24 +00003766 (void) GetOneVirtualPixelInfo(msl_info->image[n],
cristy33e9da62011-10-21 19:08:58 +00003767 TileVirtualPixelMethod,geometry.x,geometry.y,&target,
3768 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003769 break;
3770 }
3771 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3772 keyword);
3773 break;
3774 }
3775 default:
3776 {
3777 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3778 keyword);
3779 break;
3780 }
3781 }
3782 }
3783 draw_info=CloneDrawInfo(msl_info->image_info[n],
3784 msl_info->draw_info[n]);
cristy4c08aed2011-07-01 19:47:50 +00003785 draw_info->fill.alpha=ClampToQuantum(opacity);
cristybd5a96c2011-08-21 00:04:26 +00003786 channel_mask=SetPixelChannelMask(msl_info->image[n],AlphaChannel);
cristyd42d9952011-07-08 14:21:50 +00003787 (void) FloodfillPaintImage(msl_info->image[n],draw_info,&target,
3788 geometry.x,geometry.y,paint_method == FloodfillMethod ?
cristyc82a27b2011-10-21 01:07:16 +00003789 MagickFalse : MagickTrue,msl_info->exception);
cristye2a912b2011-12-05 20:02:07 +00003790 (void) SetPixelChannelMapMask(msl_info->image[n],channel_mask);
cristy3ed852e2009-09-05 21:47:34 +00003791 draw_info=DestroyDrawInfo(draw_info);
3792 break;
3793 }
cristyb988fe72009-09-16 01:01:10 +00003794 if (LocaleCompare((const char *) tag,"median-filter") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003795 {
3796 Image
3797 *median_image;
3798
3799 /*
3800 Median-filter image.
3801 */
3802 if (msl_info->image[n] == (Image *) NULL)
3803 {
cristyb988fe72009-09-16 01:01:10 +00003804 ThrowMSLException(OptionError,"NoImagesDefined",
3805 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003806 break;
3807 }
3808 if (attributes != (const xmlChar **) NULL)
3809 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3810 {
3811 keyword=(const char *) attributes[i++];
3812 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003813 msl_info->attributes[n],(const char *) attributes[i],
3814 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003815 CloneString(&value,attribute);
3816 switch (*keyword)
3817 {
3818 case 'G':
3819 case 'g':
3820 {
3821 if (LocaleCompare(keyword,"geometry") == 0)
3822 {
3823 flags=ParseGeometry(value,&geometry_info);
3824 if ((flags & SigmaValue) == 0)
3825 geometry_info.sigma=1.0;
3826 break;
3827 }
3828 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3829 keyword);
3830 break;
3831 }
3832 case 'R':
3833 case 'r':
3834 {
3835 if (LocaleCompare(keyword,"radius") == 0)
3836 {
cristydbdd0e32011-11-04 23:29:40 +00003837 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00003838 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003839 break;
3840 }
3841 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3842 keyword);
3843 break;
3844 }
3845 default:
3846 {
3847 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3848 keyword);
3849 break;
3850 }
3851 }
3852 }
cristy733678d2011-03-18 21:29:28 +00003853 median_image=StatisticImage(msl_info->image[n],MedianStatistic,
cristy95c38342011-03-18 22:39:51 +00003854 (size_t) geometry_info.rho,(size_t) geometry_info.sigma,
cristyc82a27b2011-10-21 01:07:16 +00003855 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00003856 if (median_image == (Image *) NULL)
3857 break;
3858 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3859 msl_info->image[n]=median_image;
3860 break;
3861 }
cristyb988fe72009-09-16 01:01:10 +00003862 if (LocaleCompare((const char *) tag,"minify") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003863 {
3864 Image
3865 *minify_image;
3866
3867 /*
3868 Minify image.
3869 */
3870 if (msl_info->image[n] == (Image *) NULL)
3871 {
cristyb988fe72009-09-16 01:01:10 +00003872 ThrowMSLException(OptionError,"NoImagesDefined",
3873 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003874 break;
3875 }
3876 if (attributes != (const xmlChar **) NULL)
3877 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3878 {
3879 keyword=(const char *) attributes[i++];
3880 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003881 msl_info->attributes[n],(const char *) attributes[i],
3882 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003883 CloneString(&value,attribute);
3884 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3885 }
3886 minify_image=MinifyImage(msl_info->image[n],
cristyc82a27b2011-10-21 01:07:16 +00003887 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00003888 if (minify_image == (Image *) NULL)
3889 break;
3890 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3891 msl_info->image[n]=minify_image;
3892 break;
3893 }
cristyb988fe72009-09-16 01:01:10 +00003894 if (LocaleCompare((const char *) tag,"msl") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00003895 break;
cristyb988fe72009-09-16 01:01:10 +00003896 if (LocaleCompare((const char *) tag,"modulate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003897 {
3898 char
3899 modulate[MaxTextExtent];
3900
3901 /*
3902 Modulate image.
3903 */
3904 if (msl_info->image[n] == (Image *) NULL)
3905 {
cristyb988fe72009-09-16 01:01:10 +00003906 ThrowMSLException(OptionError,"NoImagesDefined",
3907 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003908 break;
3909 }
3910 geometry_info.rho=100.0;
3911 geometry_info.sigma=100.0;
3912 geometry_info.xi=100.0;
3913 if (attributes != (const xmlChar **) NULL)
3914 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3915 {
3916 keyword=(const char *) attributes[i++];
3917 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003918 msl_info->attributes[n],(const char *) attributes[i],
3919 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003920 CloneString(&value,attribute);
3921 switch (*keyword)
3922 {
3923 case 'B':
3924 case 'b':
3925 {
3926 if (LocaleCompare(keyword,"blackness") == 0)
3927 {
cristydbdd0e32011-11-04 23:29:40 +00003928 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00003929 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003930 break;
3931 }
3932 if (LocaleCompare(keyword,"brightness") == 0)
3933 {
cristydbdd0e32011-11-04 23:29:40 +00003934 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00003935 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003936 break;
3937 }
3938 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3939 keyword);
3940 break;
3941 }
3942 case 'F':
3943 case 'f':
3944 {
3945 if (LocaleCompare(keyword,"factor") == 0)
3946 {
3947 flags=ParseGeometry(value,&geometry_info);
3948 break;
3949 }
3950 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3951 keyword);
3952 break;
3953 }
3954 case 'H':
3955 case 'h':
3956 {
3957 if (LocaleCompare(keyword,"hue") == 0)
3958 {
cristydbdd0e32011-11-04 23:29:40 +00003959 geometry_info.xi=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00003960 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003961 break;
3962 }
3963 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3964 keyword);
3965 break;
3966 }
3967 case 'L':
3968 case 'l':
3969 {
3970 if (LocaleCompare(keyword,"lightness") == 0)
3971 {
cristydbdd0e32011-11-04 23:29:40 +00003972 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00003973 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003974 break;
3975 }
3976 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3977 keyword);
3978 break;
3979 }
3980 case 'S':
3981 case 's':
3982 {
3983 if (LocaleCompare(keyword,"saturation") == 0)
3984 {
cristydbdd0e32011-11-04 23:29:40 +00003985 geometry_info.sigma=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00003986 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003987 break;
3988 }
3989 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3990 keyword);
3991 break;
3992 }
3993 case 'W':
3994 case 'w':
3995 {
3996 if (LocaleCompare(keyword,"whiteness") == 0)
3997 {
cristydbdd0e32011-11-04 23:29:40 +00003998 geometry_info.sigma=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00003999 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004000 break;
4001 }
4002 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4003 keyword);
4004 break;
4005 }
4006 default:
4007 {
4008 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4009 keyword);
4010 break;
4011 }
4012 }
4013 }
cristyb51dff52011-05-19 16:55:47 +00004014 (void) FormatLocaleString(modulate,MaxTextExtent,"%g,%g,%g",
cristy3ed852e2009-09-05 21:47:34 +00004015 geometry_info.rho,geometry_info.sigma,geometry_info.xi);
cristy33bd5152011-08-24 01:42:24 +00004016 (void) ModulateImage(msl_info->image[n],modulate,
cristyc82a27b2011-10-21 01:07:16 +00004017 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00004018 break;
4019 }
4020 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4021 }
4022 case 'N':
4023 case 'n':
4024 {
cristyb988fe72009-09-16 01:01:10 +00004025 if (LocaleCompare((const char *) tag,"negate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004026 {
4027 MagickBooleanType
4028 gray;
4029
4030 /*
4031 Negate image.
4032 */
4033 if (msl_info->image[n] == (Image *) NULL)
4034 {
cristyb988fe72009-09-16 01:01:10 +00004035 ThrowMSLException(OptionError,"NoImagesDefined",
4036 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004037 break;
4038 }
4039 gray=MagickFalse;
4040 if (attributes != (const xmlChar **) NULL)
4041 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4042 {
4043 keyword=(const char *) attributes[i++];
4044 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004045 msl_info->attributes[n],(const char *) attributes[i],
4046 &exception);
cristy3ed852e2009-09-05 21:47:34 +00004047 CloneString(&value,attribute);
4048 switch (*keyword)
4049 {
4050 case 'C':
4051 case 'c':
4052 {
4053 if (LocaleCompare(keyword,"channel") == 0)
4054 {
4055 option=ParseChannelOption(value);
4056 if (option < 0)
4057 ThrowMSLException(OptionError,"UnrecognizedChannelType",
4058 value);
4059 channel=(ChannelType) option;
4060 break;
4061 }
4062 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4063 keyword);
4064 break;
4065 }
4066 case 'G':
4067 case 'g':
4068 {
4069 if (LocaleCompare(keyword,"gray") == 0)
4070 {
cristy042ee782011-04-22 18:48:30 +00004071 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004072 value);
4073 if (option < 0)
4074 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4075 value);
4076 gray=(MagickBooleanType) option;
4077 break;
4078 }
4079 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4080 keyword);
4081 break;
4082 }
4083 default:
4084 {
4085 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4086 keyword);
4087 break;
4088 }
4089 }
4090 }
cristybd5a96c2011-08-21 00:04:26 +00004091 channel_mask=SetPixelChannelMask(msl_info->image[n],channel);
cristyb3e7c6c2011-07-24 01:43:55 +00004092 (void) NegateImage(msl_info->image[n],gray,
cristyc82a27b2011-10-21 01:07:16 +00004093 msl_info->exception);
cristye2a912b2011-12-05 20:02:07 +00004094 (void) SetPixelChannelMapMask(msl_info->image[n],channel_mask);
cristy3ed852e2009-09-05 21:47:34 +00004095 break;
4096 }
cristyb988fe72009-09-16 01:01:10 +00004097 if (LocaleCompare((const char *) tag,"normalize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004098 {
4099 /*
4100 Normalize image.
4101 */
4102 if (msl_info->image[n] == (Image *) NULL)
4103 {
cristyb988fe72009-09-16 01:01:10 +00004104 ThrowMSLException(OptionError,"NoImagesDefined",
4105 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004106 break;
4107 }
4108 if (attributes != (const xmlChar **) NULL)
4109 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4110 {
4111 keyword=(const char *) attributes[i++];
4112 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004113 msl_info->attributes[n],(const char *) attributes[i],
4114 &exception);
cristy3ed852e2009-09-05 21:47:34 +00004115 CloneString(&value,attribute);
4116 switch (*keyword)
4117 {
4118 case 'C':
4119 case 'c':
4120 {
4121 if (LocaleCompare(keyword,"channel") == 0)
4122 {
4123 option=ParseChannelOption(value);
4124 if (option < 0)
4125 ThrowMSLException(OptionError,"UnrecognizedChannelType",
4126 value);
4127 channel=(ChannelType) option;
4128 break;
4129 }
4130 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4131 keyword);
4132 break;
4133 }
4134 default:
4135 {
4136 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4137 keyword);
4138 break;
4139 }
4140 }
4141 }
cristye23ec9d2011-08-16 18:15:40 +00004142 (void) NormalizeImage(msl_info->image[n],
cristyc82a27b2011-10-21 01:07:16 +00004143 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00004144 break;
4145 }
4146 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4147 }
4148 case 'O':
4149 case 'o':
4150 {
cristyb988fe72009-09-16 01:01:10 +00004151 if (LocaleCompare((const char *) tag,"oil-paint") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004152 {
4153 Image
4154 *paint_image;
4155
4156 /*
4157 Oil-paint image.
4158 */
4159 if (msl_info->image[n] == (Image *) NULL)
4160 {
cristyb988fe72009-09-16 01:01:10 +00004161 ThrowMSLException(OptionError,"NoImagesDefined",
4162 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004163 break;
4164 }
4165 if (attributes != (const xmlChar **) NULL)
4166 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4167 {
4168 keyword=(const char *) attributes[i++];
4169 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004170 msl_info->attributes[n],(const char *) attributes[i],
4171 &exception);
cristy3ed852e2009-09-05 21:47:34 +00004172 CloneString(&value,attribute);
4173 switch (*keyword)
4174 {
4175 case 'G':
4176 case 'g':
4177 {
4178 if (LocaleCompare(keyword,"geometry") == 0)
4179 {
4180 flags=ParseGeometry(value,&geometry_info);
4181 if ((flags & SigmaValue) == 0)
4182 geometry_info.sigma=1.0;
4183 break;
4184 }
4185 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4186 keyword);
4187 break;
4188 }
4189 case 'R':
4190 case 'r':
4191 {
4192 if (LocaleCompare(keyword,"radius") == 0)
4193 {
cristydbdd0e32011-11-04 23:29:40 +00004194 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00004195 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004196 break;
4197 }
4198 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4199 keyword);
4200 break;
4201 }
4202 default:
4203 {
4204 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4205 keyword);
4206 break;
4207 }
4208 }
4209 }
4210 paint_image=OilPaintImage(msl_info->image[n],geometry_info.rho,
cristyc82a27b2011-10-21 01:07:16 +00004211 geometry_info.sigma,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00004212 if (paint_image == (Image *) NULL)
4213 break;
4214 msl_info->image[n]=DestroyImage(msl_info->image[n]);
4215 msl_info->image[n]=paint_image;
4216 break;
4217 }
cristyb988fe72009-09-16 01:01:10 +00004218 if (LocaleCompare((const char *) tag,"opaque") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004219 {
cristy4c08aed2011-07-01 19:47:50 +00004220 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00004221 fill_color,
4222 target;
4223
4224 /*
4225 Opaque image.
4226 */
4227 if (msl_info->image[n] == (Image *) NULL)
4228 {
cristyb988fe72009-09-16 01:01:10 +00004229 ThrowMSLException(OptionError,"NoImagesDefined",
4230 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004231 break;
4232 }
cristy269c9412011-10-13 23:41:15 +00004233 (void) QueryColorCompliance("none",AllCompliance,&target,
cristy9950d572011-10-01 18:22:35 +00004234 &exception);
cristy269c9412011-10-13 23:41:15 +00004235 (void) QueryColorCompliance("none",AllCompliance,&fill_color,
cristy9950d572011-10-01 18:22:35 +00004236 &exception);
cristy3ed852e2009-09-05 21:47:34 +00004237 if (attributes != (const xmlChar **) NULL)
4238 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4239 {
4240 keyword=(const char *) attributes[i++];
4241 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004242 msl_info->attributes[n],(const char *) attributes[i],
4243 &exception);
cristy3ed852e2009-09-05 21:47:34 +00004244 CloneString(&value,attribute);
4245 switch (*keyword)
4246 {
4247 case 'C':
4248 case 'c':
4249 {
4250 if (LocaleCompare(keyword,"channel") == 0)
4251 {
4252 option=ParseChannelOption(value);
4253 if (option < 0)
4254 ThrowMSLException(OptionError,"UnrecognizedChannelType",
4255 value);
4256 channel=(ChannelType) option;
4257 break;
4258 }
4259 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4260 keyword);
4261 break;
4262 }
4263 case 'F':
4264 case 'f':
4265 {
4266 if (LocaleCompare(keyword,"fill") == 0)
4267 {
cristy269c9412011-10-13 23:41:15 +00004268 (void) QueryColorCompliance(value,AllCompliance,
cristy9950d572011-10-01 18:22:35 +00004269 &fill_color,&exception);
cristy3ed852e2009-09-05 21:47:34 +00004270 break;
4271 }
4272 if (LocaleCompare(keyword,"fuzz") == 0)
4273 {
cristydbdd0e32011-11-04 23:29:40 +00004274 msl_info->image[n]->fuzz=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00004275 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004276 break;
4277 }
4278 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4279 keyword);
4280 break;
4281 }
4282 default:
4283 {
4284 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4285 keyword);
4286 break;
4287 }
4288 }
4289 }
cristybd5a96c2011-08-21 00:04:26 +00004290 channel_mask=SetPixelChannelMask(msl_info->image[n],channel);
cristyd42d9952011-07-08 14:21:50 +00004291 (void) OpaquePaintImage(msl_info->image[n],&target,&fill_color,
cristyc82a27b2011-10-21 01:07:16 +00004292 MagickFalse,msl_info->exception);
cristye2a912b2011-12-05 20:02:07 +00004293 (void) SetPixelChannelMapMask(msl_info->image[n],channel_mask);
cristy3ed852e2009-09-05 21:47:34 +00004294 break;
4295 }
4296 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4297 }
4298 case 'P':
4299 case 'p':
4300 {
cristyb988fe72009-09-16 01:01:10 +00004301 if (LocaleCompare((const char *) tag,"print") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004302 {
4303 if (attributes == (const xmlChar **) NULL)
4304 break;
4305 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4306 {
4307 keyword=(const char *) attributes[i++];
4308 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004309 msl_info->attributes[n],(const char *) attributes[i],
4310 &exception);
cristy3ed852e2009-09-05 21:47:34 +00004311 CloneString(&value,attribute);
4312 switch (*keyword)
4313 {
4314 case 'O':
4315 case 'o':
4316 {
4317 if (LocaleCompare(keyword,"output") == 0)
4318 {
cristyb51dff52011-05-19 16:55:47 +00004319 (void) FormatLocaleFile(stdout,"%s",value);
cristy3ed852e2009-09-05 21:47:34 +00004320 break;
4321 }
4322 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
4323 break;
4324 }
4325 default:
4326 {
4327 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
4328 break;
4329 }
4330 }
4331 }
4332 break;
4333 }
cristy4fa36e42009-09-18 14:24:06 +00004334 if (LocaleCompare((const char *) tag, "profile") == 0)
4335 {
cristy4fa36e42009-09-18 14:24:06 +00004336 if (msl_info->image[n] == (Image *) NULL)
4337 {
4338 ThrowMSLException(OptionError,"NoImagesDefined",
4339 (const char *) tag);
4340 break;
4341 }
4342 if (attributes == (const xmlChar **) NULL)
4343 break;
4344 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4345 {
4346 const char
4347 *name;
4348
4349 const StringInfo
4350 *profile;
4351
4352 Image
4353 *profile_image;
4354
4355 ImageInfo
4356 *profile_info;
4357
4358 keyword=(const char *) attributes[i++];
4359 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004360 msl_info->attributes[n],(const char *) attributes[i],
4361 &exception);
cristy4fa36e42009-09-18 14:24:06 +00004362 CloneString(&value,attribute);
4363 if (*keyword == '+')
4364 {
4365 /*
4366 Remove a profile from the image.
4367 */
4368 (void) ProfileImage(msl_info->image[n],keyword,
cristy092d71c2011-10-14 18:01:29 +00004369 (const unsigned char *) NULL,0,&exception);
cristy4fa36e42009-09-18 14:24:06 +00004370 continue;
4371 }
4372 /*
4373 Associate a profile with the image.
4374 */
4375 profile_info=CloneImageInfo(msl_info->image_info[n]);
4376 profile=GetImageProfile(msl_info->image[n],"iptc");
4377 if (profile != (StringInfo *) NULL)
4378 profile_info->profile=(void *) CloneStringInfo(profile);
4379 profile_image=GetImageCache(profile_info,keyword,&exception);
4380 profile_info=DestroyImageInfo(profile_info);
4381 if (profile_image == (Image *) NULL)
4382 {
4383 char
4384 name[MaxTextExtent],
4385 filename[MaxTextExtent];
4386
4387 register char
4388 *p;
4389
4390 StringInfo
4391 *profile;
4392
4393 (void) CopyMagickString(filename,keyword,MaxTextExtent);
4394 (void) CopyMagickString(name,keyword,MaxTextExtent);
4395 for (p=filename; *p != '\0'; p++)
4396 if ((*p == ':') && (IsPathDirectory(keyword) < 0) &&
4397 (IsPathAccessible(keyword) == MagickFalse))
4398 {
4399 register char
4400 *q;
4401
4402 /*
4403 Look for profile name (e.g. name:profile).
4404 */
4405 (void) CopyMagickString(name,filename,(size_t)
4406 (p-filename+1));
4407 for (q=filename; *q != '\0'; q++)
4408 *q=(*++p);
4409 break;
4410 }
4411 profile=FileToStringInfo(filename,~0UL,&exception);
4412 if (profile != (StringInfo *) NULL)
4413 {
4414 (void) ProfileImage(msl_info->image[n],name,
cristybb503372010-05-27 20:51:26 +00004415 GetStringInfoDatum(profile),(size_t)
cristy3fac9ec2011-11-17 18:04:39 +00004416 GetStringInfoLength(profile),&exception);
cristy4fa36e42009-09-18 14:24:06 +00004417 profile=DestroyStringInfo(profile);
4418 }
4419 continue;
4420 }
4421 ResetImageProfileIterator(profile_image);
4422 name=GetNextImageProfile(profile_image);
4423 while (name != (const char *) NULL)
4424 {
4425 profile=GetImageProfile(profile_image,name);
4426 if (profile != (StringInfo *) NULL)
4427 (void) ProfileImage(msl_info->image[n],name,
cristybb503372010-05-27 20:51:26 +00004428 GetStringInfoDatum(profile),(size_t)
cristy3fac9ec2011-11-17 18:04:39 +00004429 GetStringInfoLength(profile),&exception);
cristy4fa36e42009-09-18 14:24:06 +00004430 name=GetNextImageProfile(profile_image);
4431 }
4432 profile_image=DestroyImage(profile_image);
4433 }
4434 break;
4435 }
cristy3ed852e2009-09-05 21:47:34 +00004436 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4437 }
4438 case 'Q':
4439 case 'q':
4440 {
cristyb988fe72009-09-16 01:01:10 +00004441 if (LocaleCompare((const char *) tag,"quantize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004442 {
4443 QuantizeInfo
4444 quantize_info;
4445
4446 /*
4447 Quantize image.
4448 */
4449 if (msl_info->image[n] == (Image *) NULL)
4450 {
cristyb988fe72009-09-16 01:01:10 +00004451 ThrowMSLException(OptionError,"NoImagesDefined",
4452 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004453 break;
4454 }
4455 GetQuantizeInfo(&quantize_info);
4456 if (attributes != (const xmlChar **) NULL)
4457 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4458 {
4459 keyword=(const char *) attributes[i++];
4460 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004461 msl_info->attributes[n],(const char *) attributes[i],
4462 &exception);
cristy3ed852e2009-09-05 21:47:34 +00004463 CloneString(&value,attribute);
4464 switch (*keyword)
4465 {
4466 case 'C':
4467 case 'c':
4468 {
4469 if (LocaleCompare(keyword,"colors") == 0)
4470 {
cristyf2f27272009-12-17 14:48:46 +00004471 quantize_info.number_colors=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004472 break;
4473 }
4474 if (LocaleCompare(keyword,"colorspace") == 0)
4475 {
cristy042ee782011-04-22 18:48:30 +00004476 option=ParseCommandOption(MagickColorspaceOptions,
cristy3ed852e2009-09-05 21:47:34 +00004477 MagickFalse,value);
4478 if (option < 0)
4479 ThrowMSLException(OptionError,
4480 "UnrecognizedColorspaceType",value);
4481 quantize_info.colorspace=(ColorspaceType) option;
4482 break;
4483 }
4484 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4485 keyword);
4486 break;
4487 }
4488 case 'D':
4489 case 'd':
4490 {
4491 if (LocaleCompare(keyword,"dither") == 0)
4492 {
cristycbda6112012-05-27 20:57:16 +00004493 option=ParseCommandOption(MagickDitherOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004494 value);
4495 if (option < 0)
4496 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4497 value);
cristycbda6112012-05-27 20:57:16 +00004498 quantize_info.dither_method=(DitherMethod) option;
cristy3ed852e2009-09-05 21:47:34 +00004499 break;
4500 }
4501 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4502 keyword);
4503 break;
4504 }
4505 case 'M':
4506 case 'm':
4507 {
4508 if (LocaleCompare(keyword,"measure") == 0)
4509 {
cristy042ee782011-04-22 18:48:30 +00004510 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004511 value);
4512 if (option < 0)
4513 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4514 value);
4515 quantize_info.measure_error=(MagickBooleanType) option;
4516 break;
4517 }
4518 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4519 keyword);
4520 break;
4521 }
4522 case 'T':
4523 case 't':
4524 {
4525 if (LocaleCompare(keyword,"treedepth") == 0)
4526 {
cristyf2f27272009-12-17 14:48:46 +00004527 quantize_info.tree_depth=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004528 break;
4529 }
4530 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4531 keyword);
4532 break;
4533 }
4534 default:
4535 {
4536 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4537 keyword);
4538 break;
4539 }
4540 }
4541 }
cristy018f07f2011-09-04 21:15:19 +00004542 (void) QuantizeImage(&quantize_info,msl_info->image[n],&exception);
cristy3ed852e2009-09-05 21:47:34 +00004543 break;
4544 }
cristyb988fe72009-09-16 01:01:10 +00004545 if (LocaleCompare((const char *) tag,"query-font-metrics") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004546 {
4547 char
4548 text[MaxTextExtent];
4549
4550 MagickBooleanType
4551 status;
4552
4553 TypeMetric
4554 metrics;
4555
4556 /*
4557 Query font metrics.
4558 */
4559 draw_info=CloneDrawInfo(msl_info->image_info[n],
4560 msl_info->draw_info[n]);
4561 angle=0.0;
4562 current=draw_info->affine;
4563 GetAffineMatrix(&affine);
4564 if (attributes != (const xmlChar **) NULL)
4565 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4566 {
4567 keyword=(const char *) attributes[i++];
4568 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004569 msl_info->attributes[n],(const char *) attributes[i],
4570 &exception);
cristy3ed852e2009-09-05 21:47:34 +00004571 CloneString(&value,attribute);
4572 switch (*keyword)
4573 {
4574 case 'A':
4575 case 'a':
4576 {
4577 if (LocaleCompare(keyword,"affine") == 0)
4578 {
4579 char
4580 *p;
4581
4582 p=value;
cristydbdd0e32011-11-04 23:29:40 +00004583 draw_info->affine.sx=StringToDouble(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004584 if (*p ==',')
4585 p++;
cristydbdd0e32011-11-04 23:29:40 +00004586 draw_info->affine.rx=StringToDouble(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004587 if (*p ==',')
4588 p++;
cristydbdd0e32011-11-04 23:29:40 +00004589 draw_info->affine.ry=StringToDouble(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004590 if (*p ==',')
4591 p++;
cristydbdd0e32011-11-04 23:29:40 +00004592 draw_info->affine.sy=StringToDouble(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004593 if (*p ==',')
4594 p++;
cristydbdd0e32011-11-04 23:29:40 +00004595 draw_info->affine.tx=StringToDouble(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004596 if (*p ==',')
4597 p++;
cristydbdd0e32011-11-04 23:29:40 +00004598 draw_info->affine.ty=StringToDouble(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004599 break;
4600 }
4601 if (LocaleCompare(keyword,"align") == 0)
4602 {
cristy042ee782011-04-22 18:48:30 +00004603 option=ParseCommandOption(MagickAlignOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004604 value);
4605 if (option < 0)
4606 ThrowMSLException(OptionError,"UnrecognizedAlignType",
4607 value);
4608 draw_info->align=(AlignType) option;
4609 break;
4610 }
4611 if (LocaleCompare(keyword,"antialias") == 0)
4612 {
cristy042ee782011-04-22 18:48:30 +00004613 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004614 value);
4615 if (option < 0)
4616 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4617 value);
4618 draw_info->stroke_antialias=(MagickBooleanType) option;
4619 draw_info->text_antialias=(MagickBooleanType) option;
4620 break;
4621 }
4622 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4623 keyword);
4624 break;
4625 }
4626 case 'D':
4627 case 'd':
4628 {
4629 if (LocaleCompare(keyword,"density") == 0)
4630 {
4631 CloneString(&draw_info->density,value);
4632 break;
4633 }
4634 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4635 keyword);
4636 break;
4637 }
4638 case 'E':
4639 case 'e':
4640 {
4641 if (LocaleCompare(keyword,"encoding") == 0)
4642 {
4643 CloneString(&draw_info->encoding,value);
4644 break;
4645 }
4646 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4647 keyword);
4648 break;
4649 }
4650 case 'F':
4651 case 'f':
4652 {
4653 if (LocaleCompare(keyword, "fill") == 0)
4654 {
cristy9950d572011-10-01 18:22:35 +00004655 (void) QueryColorCompliance(value,AllCompliance,
4656 &draw_info->fill,&exception);
cristy3ed852e2009-09-05 21:47:34 +00004657 break;
4658 }
4659 if (LocaleCompare(keyword,"family") == 0)
4660 {
4661 CloneString(&draw_info->family,value);
4662 break;
4663 }
4664 if (LocaleCompare(keyword,"font") == 0)
4665 {
4666 CloneString(&draw_info->font,value);
4667 break;
4668 }
4669 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4670 keyword);
4671 break;
4672 }
4673 case 'G':
4674 case 'g':
4675 {
4676 if (LocaleCompare(keyword,"geometry") == 0)
4677 {
4678 flags=ParsePageGeometry(msl_info->image[n],value,
4679 &geometry,&exception);
4680 if ((flags & HeightValue) == 0)
4681 geometry.height=geometry.width;
4682 break;
4683 }
4684 if (LocaleCompare(keyword,"gravity") == 0)
4685 {
cristy042ee782011-04-22 18:48:30 +00004686 option=ParseCommandOption(MagickGravityOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004687 value);
4688 if (option < 0)
4689 ThrowMSLException(OptionError,"UnrecognizedGravityType",
4690 value);
4691 draw_info->gravity=(GravityType) option;
4692 break;
4693 }
4694 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4695 keyword);
4696 break;
4697 }
4698 case 'P':
4699 case 'p':
4700 {
4701 if (LocaleCompare(keyword,"pointsize") == 0)
4702 {
cristydbdd0e32011-11-04 23:29:40 +00004703 draw_info->pointsize=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00004704 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004705 break;
4706 }
4707 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4708 keyword);
4709 break;
4710 }
4711 case 'R':
4712 case 'r':
4713 {
4714 if (LocaleCompare(keyword,"rotate") == 0)
4715 {
cristydbdd0e32011-11-04 23:29:40 +00004716 angle=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004717 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
4718 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
4719 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
4720 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
4721 break;
4722 }
4723 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4724 keyword);
4725 break;
4726 }
4727 case 'S':
4728 case 's':
4729 {
4730 if (LocaleCompare(keyword,"scale") == 0)
4731 {
4732 flags=ParseGeometry(value,&geometry_info);
4733 if ((flags & SigmaValue) == 0)
4734 geometry_info.sigma=1.0;
4735 affine.sx=geometry_info.rho;
4736 affine.sy=geometry_info.sigma;
4737 break;
4738 }
4739 if (LocaleCompare(keyword,"skewX") == 0)
4740 {
cristydbdd0e32011-11-04 23:29:40 +00004741 angle=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004742 affine.ry=cos(DegreesToRadians(fmod(angle,360.0)));
4743 break;
4744 }
4745 if (LocaleCompare(keyword,"skewY") == 0)
4746 {
cristydbdd0e32011-11-04 23:29:40 +00004747 angle=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004748 affine.rx=cos(DegreesToRadians(fmod(angle,360.0)));
4749 break;
4750 }
4751 if (LocaleCompare(keyword,"stretch") == 0)
4752 {
cristy9950d572011-10-01 18:22:35 +00004753 option=ParseCommandOption(MagickStretchOptions,
4754 MagickFalse,value);
cristy3ed852e2009-09-05 21:47:34 +00004755 if (option < 0)
4756 ThrowMSLException(OptionError,"UnrecognizedStretchType",
4757 value);
4758 draw_info->stretch=(StretchType) option;
4759 break;
4760 }
4761 if (LocaleCompare(keyword, "stroke") == 0)
4762 {
cristy9950d572011-10-01 18:22:35 +00004763 (void) QueryColorCompliance(value,AllCompliance,
4764 &draw_info->stroke,&exception);
cristy3ed852e2009-09-05 21:47:34 +00004765 break;
4766 }
4767 if (LocaleCompare(keyword,"strokewidth") == 0)
4768 {
cristyf2f27272009-12-17 14:48:46 +00004769 draw_info->stroke_width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004770 break;
4771 }
4772 if (LocaleCompare(keyword,"style") == 0)
4773 {
cristy042ee782011-04-22 18:48:30 +00004774 option=ParseCommandOption(MagickStyleOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004775 value);
4776 if (option < 0)
4777 ThrowMSLException(OptionError,"UnrecognizedStyleType",
4778 value);
4779 draw_info->style=(StyleType) option;
4780 break;
4781 }
4782 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4783 keyword);
4784 break;
4785 }
4786 case 'T':
4787 case 't':
4788 {
4789 if (LocaleCompare(keyword,"text") == 0)
4790 {
4791 CloneString(&draw_info->text,value);
4792 break;
4793 }
4794 if (LocaleCompare(keyword,"translate") == 0)
4795 {
4796 flags=ParseGeometry(value,&geometry_info);
4797 if ((flags & SigmaValue) == 0)
4798 geometry_info.sigma=1.0;
4799 affine.tx=geometry_info.rho;
4800 affine.ty=geometry_info.sigma;
4801 break;
4802 }
4803 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4804 keyword);
4805 break;
4806 }
4807 case 'U':
4808 case 'u':
4809 {
4810 if (LocaleCompare(keyword, "undercolor") == 0)
4811 {
cristy9950d572011-10-01 18:22:35 +00004812 (void) QueryColorCompliance(value,AllCompliance,
4813 &draw_info->undercolor,&exception);
cristy3ed852e2009-09-05 21:47:34 +00004814 break;
4815 }
4816 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4817 keyword);
4818 break;
4819 }
4820 case 'W':
4821 case 'w':
4822 {
4823 if (LocaleCompare(keyword,"weight") == 0)
4824 {
cristyf2f27272009-12-17 14:48:46 +00004825 draw_info->weight=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004826 break;
4827 }
4828 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4829 keyword);
4830 break;
4831 }
4832 case 'X':
4833 case 'x':
4834 {
4835 if (LocaleCompare(keyword,"x") == 0)
4836 {
cristyf2f27272009-12-17 14:48:46 +00004837 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004838 break;
4839 }
4840 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4841 keyword);
4842 break;
4843 }
4844 case 'Y':
4845 case 'y':
4846 {
4847 if (LocaleCompare(keyword,"y") == 0)
4848 {
cristyf2f27272009-12-17 14:48:46 +00004849 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004850 break;
4851 }
4852 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4853 keyword);
4854 break;
4855 }
4856 default:
4857 {
4858 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4859 keyword);
4860 break;
4861 }
4862 }
4863 }
cristyb51dff52011-05-19 16:55:47 +00004864 (void) FormatLocaleString(text,MaxTextExtent,
cristye8c25f92010-06-03 00:53:06 +00004865 "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,(double)
4866 geometry.height,(double) geometry.x,(double) geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00004867 CloneString(&draw_info->geometry,text);
cristyef7c8a52010-10-10 13:46:51 +00004868 draw_info->affine.sx=affine.sx*current.sx+affine.ry*current.rx;
4869 draw_info->affine.rx=affine.rx*current.sx+affine.sy*current.rx;
4870 draw_info->affine.ry=affine.sx*current.ry+affine.ry*current.sy;
4871 draw_info->affine.sy=affine.rx*current.ry+affine.sy*current.sy;
4872 draw_info->affine.tx=affine.sx*current.tx+affine.ry*current.ty+
4873 affine.tx;
4874 draw_info->affine.ty=affine.rx*current.tx+affine.sy*current.ty+
4875 affine.ty;
cristy5cbc0162011-08-29 00:36:28 +00004876 status=GetTypeMetrics(msl_info->attributes[n],draw_info,&metrics,
cristyc82a27b2011-10-21 01:07:16 +00004877 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00004878 if (status != MagickFalse)
4879 {
4880 Image
4881 *image;
4882
4883 image=msl_info->attributes[n];
cristy8cd5b312010-01-07 01:10:24 +00004884 FormatImageProperty(image,"msl:font-metrics.pixels_per_em.x",
cristye7f51092010-01-17 00:39:37 +00004885 "%g",metrics.pixels_per_em.x);
cristy8cd5b312010-01-07 01:10:24 +00004886 FormatImageProperty(image,"msl:font-metrics.pixels_per_em.y",
cristye7f51092010-01-17 00:39:37 +00004887 "%g",metrics.pixels_per_em.y);
4888 FormatImageProperty(image,"msl:font-metrics.ascent","%g",
cristy3ed852e2009-09-05 21:47:34 +00004889 metrics.ascent);
cristye7f51092010-01-17 00:39:37 +00004890 FormatImageProperty(image,"msl:font-metrics.descent","%g",
cristy3ed852e2009-09-05 21:47:34 +00004891 metrics.descent);
cristye7f51092010-01-17 00:39:37 +00004892 FormatImageProperty(image,"msl:font-metrics.width","%g",
cristy3ed852e2009-09-05 21:47:34 +00004893 metrics.width);
cristye7f51092010-01-17 00:39:37 +00004894 FormatImageProperty(image,"msl:font-metrics.height","%g",
cristy3ed852e2009-09-05 21:47:34 +00004895 metrics.height);
cristye7f51092010-01-17 00:39:37 +00004896 FormatImageProperty(image,"msl:font-metrics.max_advance","%g",
cristy3ed852e2009-09-05 21:47:34 +00004897 metrics.max_advance);
cristye7f51092010-01-17 00:39:37 +00004898 FormatImageProperty(image,"msl:font-metrics.bounds.x1","%g",
cristy3ed852e2009-09-05 21:47:34 +00004899 metrics.bounds.x1);
cristye7f51092010-01-17 00:39:37 +00004900 FormatImageProperty(image,"msl:font-metrics.bounds.y1","%g",
cristy3ed852e2009-09-05 21:47:34 +00004901 metrics.bounds.y1);
cristye7f51092010-01-17 00:39:37 +00004902 FormatImageProperty(image,"msl:font-metrics.bounds.x2","%g",
cristy3ed852e2009-09-05 21:47:34 +00004903 metrics.bounds.x2);
cristye7f51092010-01-17 00:39:37 +00004904 FormatImageProperty(image,"msl:font-metrics.bounds.y2","%g",
cristy3ed852e2009-09-05 21:47:34 +00004905 metrics.bounds.y2);
cristye7f51092010-01-17 00:39:37 +00004906 FormatImageProperty(image,"msl:font-metrics.origin.x","%g",
cristy3ed852e2009-09-05 21:47:34 +00004907 metrics.origin.x);
cristye7f51092010-01-17 00:39:37 +00004908 FormatImageProperty(image,"msl:font-metrics.origin.y","%g",
cristy3ed852e2009-09-05 21:47:34 +00004909 metrics.origin.y);
4910 }
4911 draw_info=DestroyDrawInfo(draw_info);
4912 break;
4913 }
4914 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4915 }
4916 case 'R':
4917 case 'r':
4918 {
cristyb988fe72009-09-16 01:01:10 +00004919 if (LocaleCompare((const char *) tag,"raise") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004920 {
4921 MagickBooleanType
4922 raise;
4923
4924 /*
4925 Raise image.
4926 */
4927 if (msl_info->image[n] == (Image *) NULL)
4928 {
cristyb988fe72009-09-16 01:01:10 +00004929 ThrowMSLException(OptionError,"NoImagesDefined",
4930 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004931 break;
4932 }
4933 raise=MagickFalse;
4934 SetGeometry(msl_info->image[n],&geometry);
4935 if (attributes != (const xmlChar **) NULL)
4936 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4937 {
4938 keyword=(const char *) attributes[i++];
4939 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004940 msl_info->attributes[n],(const char *) attributes[i],
4941 &exception);
cristy3ed852e2009-09-05 21:47:34 +00004942 CloneString(&value,attribute);
4943 switch (*keyword)
4944 {
4945 case 'G':
4946 case 'g':
4947 {
4948 if (LocaleCompare(keyword,"geometry") == 0)
4949 {
4950 flags=ParsePageGeometry(msl_info->image[n],value,
4951 &geometry,&exception);
4952 if ((flags & HeightValue) == 0)
4953 geometry.height=geometry.width;
4954 break;
4955 }
4956 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4957 keyword);
4958 break;
4959 }
4960 case 'H':
4961 case 'h':
4962 {
4963 if (LocaleCompare(keyword,"height") == 0)
4964 {
cristyf2f27272009-12-17 14:48:46 +00004965 geometry.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004966 break;
4967 }
4968 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4969 keyword);
4970 break;
4971 }
4972 case 'R':
4973 case 'r':
4974 {
4975 if (LocaleCompare(keyword,"raise") == 0)
4976 {
cristy042ee782011-04-22 18:48:30 +00004977 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004978 value);
4979 if (option < 0)
4980 ThrowMSLException(OptionError,"UnrecognizedNoiseType",
4981 value);
4982 raise=(MagickBooleanType) option;
4983 break;
4984 }
4985 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4986 keyword);
4987 break;
4988 }
4989 case 'W':
4990 case 'w':
4991 {
4992 if (LocaleCompare(keyword,"width") == 0)
4993 {
cristyf2f27272009-12-17 14:48:46 +00004994 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004995 break;
4996 }
4997 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4998 keyword);
4999 break;
5000 }
5001 default:
5002 {
5003 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5004 keyword);
5005 break;
5006 }
5007 }
5008 }
cristy6170ac32011-08-28 14:15:37 +00005009 (void) RaiseImage(msl_info->image[n],&geometry,raise,
cristyc82a27b2011-10-21 01:07:16 +00005010 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00005011 break;
5012 }
cristyb988fe72009-09-16 01:01:10 +00005013 if (LocaleCompare((const char *) tag,"read") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005014 {
5015 if (attributes == (const xmlChar **) NULL)
5016 break;
5017 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5018 {
5019 keyword=(const char *) attributes[i++];
5020 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005021 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00005022 switch (*keyword)
5023 {
5024 case 'F':
5025 case 'f':
5026 {
5027 if (LocaleCompare(keyword,"filename") == 0)
5028 {
5029 Image
5030 *image;
5031
5032 (void) CopyMagickString(msl_info->image_info[n]->filename,
5033 value,MaxTextExtent);
5034 image=ReadImage(msl_info->image_info[n],&exception);
5035 CatchException(&exception);
5036 if (image == (Image *) NULL)
5037 continue;
5038 AppendImageToList(&msl_info->image[n],image);
5039 break;
5040 }
cristy4582cbb2009-09-23 00:35:43 +00005041 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00005042 break;
5043 }
5044 default:
5045 {
cristy4582cbb2009-09-23 00:35:43 +00005046 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00005047 break;
5048 }
5049 }
5050 }
5051 break;
5052 }
cristyb988fe72009-09-16 01:01:10 +00005053 if (LocaleCompare((const char *) tag,"reduce-noise") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005054 {
5055 Image
5056 *paint_image;
5057
5058 /*
5059 Reduce-noise image.
5060 */
5061 if (msl_info->image[n] == (Image *) NULL)
5062 {
cristyb988fe72009-09-16 01:01:10 +00005063 ThrowMSLException(OptionError,"NoImagesDefined",
5064 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005065 break;
5066 }
5067 if (attributes != (const xmlChar **) NULL)
5068 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5069 {
5070 keyword=(const char *) attributes[i++];
5071 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005072 msl_info->attributes[n],(const char *) attributes[i],
5073 &exception);
cristy3ed852e2009-09-05 21:47:34 +00005074 CloneString(&value,attribute);
5075 switch (*keyword)
5076 {
5077 case 'G':
5078 case 'g':
5079 {
5080 if (LocaleCompare(keyword,"geometry") == 0)
5081 {
5082 flags=ParseGeometry(value,&geometry_info);
5083 if ((flags & SigmaValue) == 0)
5084 geometry_info.sigma=1.0;
5085 break;
5086 }
5087 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5088 keyword);
5089 break;
5090 }
5091 case 'R':
5092 case 'r':
5093 {
5094 if (LocaleCompare(keyword,"radius") == 0)
5095 {
cristydbdd0e32011-11-04 23:29:40 +00005096 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00005097 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005098 break;
5099 }
5100 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5101 keyword);
5102 break;
5103 }
5104 default:
5105 {
5106 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5107 keyword);
5108 break;
5109 }
5110 }
5111 }
cristy733678d2011-03-18 21:29:28 +00005112 paint_image=StatisticImage(msl_info->image[n],NonpeakStatistic,
cristy95c38342011-03-18 22:39:51 +00005113 (size_t) geometry_info.rho,(size_t) geometry_info.sigma,
cristyc82a27b2011-10-21 01:07:16 +00005114 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00005115 if (paint_image == (Image *) NULL)
5116 break;
5117 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5118 msl_info->image[n]=paint_image;
5119 break;
5120 }
cristyb988fe72009-09-16 01:01:10 +00005121 else if (LocaleCompare((const char *) tag,"repage") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005122 {
5123 /* init the values */
5124 width=msl_info->image[n]->page.width;
5125 height=msl_info->image[n]->page.height;
5126 x=msl_info->image[n]->page.x;
5127 y=msl_info->image[n]->page.y;
5128
5129 if (msl_info->image[n] == (Image *) NULL)
5130 {
cristyb988fe72009-09-16 01:01:10 +00005131 ThrowMSLException(OptionError,"NoImagesDefined",
5132 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005133 break;
5134 }
5135 if (attributes == (const xmlChar **) NULL)
5136 break;
5137 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5138 {
5139 keyword=(const char *) attributes[i++];
5140 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005141 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00005142 switch (*keyword)
5143 {
5144 case 'G':
5145 case 'g':
5146 {
5147 if (LocaleCompare(keyword,"geometry") == 0)
5148 {
5149 int
5150 flags;
5151
5152 RectangleInfo
5153 geometry;
5154
5155 flags=ParseAbsoluteGeometry(value,&geometry);
5156 if ((flags & WidthValue) != 0)
5157 {
5158 if ((flags & HeightValue) == 0)
5159 geometry.height=geometry.width;
5160 width=geometry.width;
5161 height=geometry.height;
5162 }
5163 if ((flags & AspectValue) != 0)
5164 {
5165 if ((flags & XValue) != 0)
5166 x+=geometry.x;
5167 if ((flags & YValue) != 0)
5168 y+=geometry.y;
5169 }
5170 else
5171 {
5172 if ((flags & XValue) != 0)
5173 {
5174 x=geometry.x;
5175 if ((width == 0) && (geometry.x > 0))
5176 width=msl_info->image[n]->columns+geometry.x;
5177 }
5178 if ((flags & YValue) != 0)
5179 {
5180 y=geometry.y;
5181 if ((height == 0) && (geometry.y > 0))
5182 height=msl_info->image[n]->rows+geometry.y;
5183 }
5184 }
5185 break;
5186 }
5187 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5188 break;
5189 }
5190 case 'H':
5191 case 'h':
5192 {
5193 if (LocaleCompare(keyword,"height") == 0)
5194 {
cristyf2f27272009-12-17 14:48:46 +00005195 height = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005196 break;
5197 }
5198 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5199 break;
5200 }
5201 case 'W':
5202 case 'w':
5203 {
5204 if (LocaleCompare(keyword,"width") == 0)
5205 {
cristyf2f27272009-12-17 14:48:46 +00005206 width = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005207 break;
5208 }
5209 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5210 break;
5211 }
5212 case 'X':
5213 case 'x':
5214 {
5215 if (LocaleCompare(keyword,"x") == 0)
5216 {
cristyf2f27272009-12-17 14:48:46 +00005217 x = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005218 break;
5219 }
5220 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5221 break;
5222 }
5223 case 'Y':
5224 case 'y':
5225 {
5226 if (LocaleCompare(keyword,"y") == 0)
5227 {
cristyf2f27272009-12-17 14:48:46 +00005228 y = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005229 break;
5230 }
5231 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5232 break;
5233 }
5234 default:
5235 {
5236 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5237 break;
5238 }
5239 }
5240 }
5241
cristyb988fe72009-09-16 01:01:10 +00005242 msl_info->image[n]->page.width=width;
5243 msl_info->image[n]->page.height=height;
5244 msl_info->image[n]->page.x=x;
5245 msl_info->image[n]->page.y=y;
cristy3ed852e2009-09-05 21:47:34 +00005246 break;
5247 }
cristyb988fe72009-09-16 01:01:10 +00005248 else if (LocaleCompare((const char *) tag,"resample") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005249 {
5250 double
5251 x_resolution,
5252 y_resolution;
5253
5254 if (msl_info->image[n] == (Image *) NULL)
5255 {
cristyb988fe72009-09-16 01:01:10 +00005256 ThrowMSLException(OptionError,"NoImagesDefined",
5257 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005258 break;
5259 }
5260 if (attributes == (const xmlChar **) NULL)
5261 break;
5262 x_resolution=DefaultResolution;
5263 y_resolution=DefaultResolution;
5264 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5265 {
5266 keyword=(const char *) attributes[i++];
5267 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005268 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00005269 switch (*keyword)
5270 {
cristy3ed852e2009-09-05 21:47:34 +00005271 case 'G':
5272 case 'g':
5273 {
5274 if (LocaleCompare(keyword,"geometry") == 0)
5275 {
cristybb503372010-05-27 20:51:26 +00005276 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00005277 flags;
5278
5279 flags=ParseGeometry(value,&geometry_info);
5280 if ((flags & SigmaValue) == 0)
5281 geometry_info.sigma*=geometry_info.rho;
5282 x_resolution=geometry_info.rho;
5283 y_resolution=geometry_info.sigma;
5284 break;
5285 }
5286 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5287 break;
5288 }
5289 case 'X':
5290 case 'x':
5291 {
5292 if (LocaleCompare(keyword,"x-resolution") == 0)
5293 {
cristydbdd0e32011-11-04 23:29:40 +00005294 x_resolution=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005295 break;
5296 }
5297 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5298 break;
5299 }
5300 case 'Y':
5301 case 'y':
5302 {
5303 if (LocaleCompare(keyword,"y-resolution") == 0)
5304 {
cristydbdd0e32011-11-04 23:29:40 +00005305 y_resolution=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005306 break;
5307 }
5308 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5309 break;
5310 }
5311 default:
5312 {
5313 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5314 break;
5315 }
5316 }
5317 }
5318 /*
5319 Resample image.
5320 */
5321 {
5322 double
5323 factor;
5324
5325 Image
5326 *resample_image;
5327
5328 factor=1.0;
5329 if (msl_info->image[n]->units == PixelsPerCentimeterResolution)
5330 factor=2.54;
cristybb503372010-05-27 20:51:26 +00005331 width=(size_t) (x_resolution*msl_info->image[n]->columns/
cristy2a11bef2011-10-28 18:33:11 +00005332 (factor*(msl_info->image[n]->resolution.x == 0.0 ? DefaultResolution :
5333 msl_info->image[n]->resolution.x))+0.5);
cristybb503372010-05-27 20:51:26 +00005334 height=(size_t) (y_resolution*msl_info->image[n]->rows/
cristy2a11bef2011-10-28 18:33:11 +00005335 (factor*(msl_info->image[n]->resolution.y == 0.0 ? DefaultResolution :
5336 msl_info->image[n]->resolution.y))+0.5);
cristy3ed852e2009-09-05 21:47:34 +00005337 resample_image=ResizeImage(msl_info->image[n],width,height,
cristyaa2c16c2012-03-25 22:21:35 +00005338 msl_info->image[n]->filter,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00005339 if (resample_image == (Image *) NULL)
5340 break;
5341 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5342 msl_info->image[n]=resample_image;
5343 }
5344 break;
5345 }
cristyb988fe72009-09-16 01:01:10 +00005346 if (LocaleCompare((const char *) tag,"resize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005347 {
cristy3ed852e2009-09-05 21:47:34 +00005348 FilterTypes
5349 filter;
5350
5351 Image
5352 *resize_image;
5353
5354 /*
5355 Resize image.
5356 */
5357 if (msl_info->image[n] == (Image *) NULL)
5358 {
cristyb988fe72009-09-16 01:01:10 +00005359 ThrowMSLException(OptionError,"NoImagesDefined",
5360 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005361 break;
5362 }
5363 filter=UndefinedFilter;
cristy3ed852e2009-09-05 21:47:34 +00005364 if (attributes != (const xmlChar **) NULL)
5365 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5366 {
5367 keyword=(const char *) attributes[i++];
5368 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005369 msl_info->attributes[n],(const char *) attributes[i],
5370 &exception);
cristy3ed852e2009-09-05 21:47:34 +00005371 CloneString(&value,attribute);
5372 switch (*keyword)
5373 {
5374 case 'F':
5375 case 'f':
5376 {
5377 if (LocaleCompare(keyword,"filter") == 0)
5378 {
cristy042ee782011-04-22 18:48:30 +00005379 option=ParseCommandOption(MagickFilterOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00005380 value);
5381 if (option < 0)
5382 ThrowMSLException(OptionError,"UnrecognizedNoiseType",
5383 value);
5384 filter=(FilterTypes) option;
5385 break;
5386 }
5387 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5388 keyword);
5389 break;
5390 }
5391 case 'G':
5392 case 'g':
5393 {
5394 if (LocaleCompare(keyword,"geometry") == 0)
5395 {
5396 flags=ParseRegionGeometry(msl_info->image[n],value,
5397 &geometry,&exception);
5398 break;
5399 }
5400 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5401 keyword);
5402 break;
5403 }
5404 case 'H':
5405 case 'h':
5406 {
5407 if (LocaleCompare(keyword,"height") == 0)
5408 {
cristye27293e2009-12-18 02:53:20 +00005409 geometry.height=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005410 break;
5411 }
5412 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5413 keyword);
5414 break;
5415 }
cristy3ed852e2009-09-05 21:47:34 +00005416 case 'W':
5417 case 'w':
5418 {
5419 if (LocaleCompare(keyword,"width") == 0)
5420 {
cristyf2f27272009-12-17 14:48:46 +00005421 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005422 break;
5423 }
5424 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5425 keyword);
5426 break;
5427 }
5428 default:
5429 {
5430 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5431 keyword);
5432 break;
5433 }
5434 }
5435 }
5436 resize_image=ResizeImage(msl_info->image[n],geometry.width,
cristyaa2c16c2012-03-25 22:21:35 +00005437 geometry.height,filter,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00005438 if (resize_image == (Image *) NULL)
5439 break;
5440 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5441 msl_info->image[n]=resize_image;
5442 break;
5443 }
cristyb988fe72009-09-16 01:01:10 +00005444 if (LocaleCompare((const char *) tag,"roll") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005445 {
5446 Image
5447 *roll_image;
5448
5449 /*
5450 Roll image.
5451 */
5452 if (msl_info->image[n] == (Image *) NULL)
5453 {
cristyb988fe72009-09-16 01:01:10 +00005454 ThrowMSLException(OptionError,"NoImagesDefined",
5455 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005456 break;
5457 }
5458 SetGeometry(msl_info->image[n],&geometry);
5459 if (attributes != (const xmlChar **) NULL)
5460 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5461 {
5462 keyword=(const char *) attributes[i++];
5463 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005464 msl_info->attributes[n],(const char *) attributes[i],
5465 &exception);
cristy3ed852e2009-09-05 21:47:34 +00005466 CloneString(&value,attribute);
5467 switch (*keyword)
5468 {
5469 case 'G':
5470 case 'g':
5471 {
5472 if (LocaleCompare(keyword,"geometry") == 0)
5473 {
5474 flags=ParsePageGeometry(msl_info->image[n],value,
5475 &geometry,&exception);
5476 if ((flags & HeightValue) == 0)
5477 geometry.height=geometry.width;
5478 break;
5479 }
5480 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5481 keyword);
5482 break;
5483 }
5484 case 'X':
5485 case 'x':
5486 {
5487 if (LocaleCompare(keyword,"x") == 0)
5488 {
cristyf2f27272009-12-17 14:48:46 +00005489 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005490 break;
5491 }
5492 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5493 keyword);
5494 break;
5495 }
5496 case 'Y':
5497 case 'y':
5498 {
5499 if (LocaleCompare(keyword,"y") == 0)
5500 {
cristyf2f27272009-12-17 14:48:46 +00005501 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005502 break;
5503 }
5504 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5505 keyword);
5506 break;
5507 }
5508 default:
5509 {
5510 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5511 keyword);
5512 break;
5513 }
5514 }
5515 }
5516 roll_image=RollImage(msl_info->image[n],geometry.x,geometry.y,
cristyc82a27b2011-10-21 01:07:16 +00005517 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00005518 if (roll_image == (Image *) NULL)
5519 break;
5520 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5521 msl_info->image[n]=roll_image;
5522 break;
5523 }
cristyb988fe72009-09-16 01:01:10 +00005524 else if (LocaleCompare((const char *) tag,"roll") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005525 {
5526 /* init the values */
5527 width=msl_info->image[n]->columns;
5528 height=msl_info->image[n]->rows;
5529 x = y = 0;
5530
5531 if (msl_info->image[n] == (Image *) NULL)
5532 {
cristyb988fe72009-09-16 01:01:10 +00005533 ThrowMSLException(OptionError,"NoImagesDefined",
5534 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005535 break;
5536 }
5537 if (attributes == (const xmlChar **) NULL)
5538 break;
5539 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5540 {
5541 keyword=(const char *) attributes[i++];
5542 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005543 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00005544 switch (*keyword)
5545 {
5546 case 'G':
5547 case 'g':
5548 {
5549 if (LocaleCompare(keyword,"geometry") == 0)
5550 {
5551 (void) ParseMetaGeometry(value,&x,&y,&width,&height);
5552 break;
5553 }
5554 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5555 break;
5556 }
5557 case 'X':
5558 case 'x':
5559 {
5560 if (LocaleCompare(keyword,"x") == 0)
5561 {
cristyf2f27272009-12-17 14:48:46 +00005562 x = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005563 break;
5564 }
5565 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5566 break;
5567 }
5568 case 'Y':
5569 case 'y':
5570 {
5571 if (LocaleCompare(keyword,"y") == 0)
5572 {
cristyf2f27272009-12-17 14:48:46 +00005573 y = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005574 break;
5575 }
5576 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5577 break;
5578 }
5579 default:
5580 {
5581 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5582 break;
5583 }
5584 }
5585 }
5586
5587 /*
5588 process image.
5589 */
5590 {
5591 Image
5592 *newImage;
5593
cristyc82a27b2011-10-21 01:07:16 +00005594 newImage=RollImage(msl_info->image[n], x, y, msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00005595 if (newImage == (Image *) NULL)
5596 break;
5597 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5598 msl_info->image[n]=newImage;
5599 }
5600
5601 break;
5602 }
cristyb988fe72009-09-16 01:01:10 +00005603 if (LocaleCompare((const char *) tag,"rotate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005604 {
5605 Image
5606 *rotate_image;
5607
5608 /*
5609 Rotate image.
5610 */
5611 if (msl_info->image[n] == (Image *) NULL)
5612 {
cristyb988fe72009-09-16 01:01:10 +00005613 ThrowMSLException(OptionError,"NoImagesDefined",
5614 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005615 break;
5616 }
5617 if (attributes != (const xmlChar **) NULL)
5618 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5619 {
5620 keyword=(const char *) attributes[i++];
5621 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005622 msl_info->attributes[n],(const char *) attributes[i],
5623 &exception);
cristy3ed852e2009-09-05 21:47:34 +00005624 CloneString(&value,attribute);
5625 switch (*keyword)
5626 {
5627 case 'D':
5628 case 'd':
5629 {
5630 if (LocaleCompare(keyword,"degrees") == 0)
5631 {
cristydbdd0e32011-11-04 23:29:40 +00005632 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00005633 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005634 break;
5635 }
5636 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5637 keyword);
5638 break;
5639 }
5640 case 'G':
5641 case 'g':
5642 {
5643 if (LocaleCompare(keyword,"geometry") == 0)
5644 {
5645 flags=ParseGeometry(value,&geometry_info);
5646 if ((flags & SigmaValue) == 0)
5647 geometry_info.sigma=1.0;
5648 break;
5649 }
5650 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5651 keyword);
5652 break;
5653 }
5654 default:
5655 {
5656 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5657 keyword);
5658 break;
5659 }
5660 }
5661 }
5662 rotate_image=RotateImage(msl_info->image[n],geometry_info.rho,
cristyc82a27b2011-10-21 01:07:16 +00005663 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00005664 if (rotate_image == (Image *) NULL)
5665 break;
5666 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5667 msl_info->image[n]=rotate_image;
5668 break;
5669 }
cristyb988fe72009-09-16 01:01:10 +00005670 else if (LocaleCompare((const char *) tag,"rotate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005671 {
5672 /* init the values */
5673 double degrees = 0;
5674
5675 if (msl_info->image[n] == (Image *) NULL)
5676 {
cristyb988fe72009-09-16 01:01:10 +00005677 ThrowMSLException(OptionError,"NoImagesDefined",
5678 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005679 break;
5680 }
5681 if (attributes == (const xmlChar **) NULL)
cristy31939262009-09-15 00:23:11 +00005682 break;
cristy3ed852e2009-09-05 21:47:34 +00005683 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5684 {
5685 keyword=(const char *) attributes[i++];
5686 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005687 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00005688 switch (*keyword)
5689 {
5690 case 'D':
5691 case 'd':
5692 {
5693 if (LocaleCompare(keyword,"degrees") == 0)
5694 {
cristydbdd0e32011-11-04 23:29:40 +00005695 degrees = StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005696 break;
5697 }
5698 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5699 break;
5700 }
5701 default:
5702 {
5703 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5704 break;
5705 }
5706 }
5707 }
5708
5709 /*
5710 process image.
5711 */
5712 {
5713 Image
5714 *newImage;
5715
cristyc82a27b2011-10-21 01:07:16 +00005716 newImage=RotateImage(msl_info->image[n], degrees, msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00005717 if (newImage == (Image *) NULL)
5718 break;
5719 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5720 msl_info->image[n]=newImage;
5721 }
5722
5723 break;
5724 }
5725 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
5726 }
5727 case 'S':
5728 case 's':
5729 {
cristyb988fe72009-09-16 01:01:10 +00005730 if (LocaleCompare((const char *) tag,"sample") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005731 {
5732 Image
5733 *sample_image;
5734
5735 /*
5736 Sample image.
5737 */
5738 if (msl_info->image[n] == (Image *) NULL)
5739 {
cristyb988fe72009-09-16 01:01:10 +00005740 ThrowMSLException(OptionError,"NoImagesDefined",
5741 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005742 break;
5743 }
5744 if (attributes != (const xmlChar **) NULL)
5745 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5746 {
5747 keyword=(const char *) attributes[i++];
5748 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005749 msl_info->attributes[n],(const char *) attributes[i],
5750 &exception);
cristy3ed852e2009-09-05 21:47:34 +00005751 CloneString(&value,attribute);
5752 switch (*keyword)
5753 {
5754 case 'G':
5755 case 'g':
5756 {
5757 if (LocaleCompare(keyword,"geometry") == 0)
5758 {
5759 flags=ParseRegionGeometry(msl_info->image[n],value,
5760 &geometry,&exception);
5761 break;
5762 }
5763 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5764 keyword);
5765 break;
5766 }
5767 case 'H':
5768 case 'h':
5769 {
5770 if (LocaleCompare(keyword,"height") == 0)
5771 {
cristye27293e2009-12-18 02:53:20 +00005772 geometry.height=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005773 break;
5774 }
5775 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5776 keyword);
5777 break;
5778 }
5779 case 'W':
5780 case 'w':
5781 {
5782 if (LocaleCompare(keyword,"width") == 0)
5783 {
cristyf2f27272009-12-17 14:48:46 +00005784 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005785 break;
5786 }
5787 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5788 keyword);
5789 break;
5790 }
5791 default:
5792 {
5793 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5794 keyword);
5795 break;
5796 }
5797 }
5798 }
5799 sample_image=SampleImage(msl_info->image[n],geometry.width,
cristyc82a27b2011-10-21 01:07:16 +00005800 geometry.height,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00005801 if (sample_image == (Image *) NULL)
5802 break;
5803 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5804 msl_info->image[n]=sample_image;
5805 break;
5806 }
cristyb988fe72009-09-16 01:01:10 +00005807 if (LocaleCompare((const char *) tag,"scale") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005808 {
5809 Image
5810 *scale_image;
5811
5812 /*
5813 Scale image.
5814 */
5815 if (msl_info->image[n] == (Image *) NULL)
5816 {
cristyb988fe72009-09-16 01:01:10 +00005817 ThrowMSLException(OptionError,"NoImagesDefined",
5818 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005819 break;
5820 }
5821 if (attributes != (const xmlChar **) NULL)
5822 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5823 {
5824 keyword=(const char *) attributes[i++];
5825 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005826 msl_info->attributes[n],(const char *) attributes[i],
5827 &exception);
cristy3ed852e2009-09-05 21:47:34 +00005828 CloneString(&value,attribute);
5829 switch (*keyword)
5830 {
5831 case 'G':
5832 case 'g':
5833 {
5834 if (LocaleCompare(keyword,"geometry") == 0)
5835 {
5836 flags=ParseRegionGeometry(msl_info->image[n],value,
5837 &geometry,&exception);
5838 break;
5839 }
5840 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5841 keyword);
5842 break;
5843 }
5844 case 'H':
5845 case 'h':
5846 {
5847 if (LocaleCompare(keyword,"height") == 0)
5848 {
cristye27293e2009-12-18 02:53:20 +00005849 geometry.height=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005850 break;
5851 }
5852 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5853 keyword);
5854 break;
5855 }
5856 case 'W':
5857 case 'w':
5858 {
5859 if (LocaleCompare(keyword,"width") == 0)
5860 {
cristyf2f27272009-12-17 14:48:46 +00005861 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005862 break;
5863 }
5864 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5865 keyword);
5866 break;
5867 }
5868 default:
5869 {
5870 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5871 keyword);
5872 break;
5873 }
5874 }
5875 }
5876 scale_image=ScaleImage(msl_info->image[n],geometry.width,
cristyc82a27b2011-10-21 01:07:16 +00005877 geometry.height,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00005878 if (scale_image == (Image *) NULL)
5879 break;
5880 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5881 msl_info->image[n]=scale_image;
5882 break;
5883 }
cristyb988fe72009-09-16 01:01:10 +00005884 if (LocaleCompare((const char *) tag,"segment") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005885 {
5886 ColorspaceType
5887 colorspace;
5888
5889 MagickBooleanType
5890 verbose;
cristyb988fe72009-09-16 01:01:10 +00005891
cristy3ed852e2009-09-05 21:47:34 +00005892 /*
5893 Segment image.
5894 */
5895 if (msl_info->image[n] == (Image *) NULL)
5896 {
cristyb988fe72009-09-16 01:01:10 +00005897 ThrowMSLException(OptionError,"NoImagesDefined",
5898 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005899 break;
5900 }
5901 geometry_info.rho=1.0;
5902 geometry_info.sigma=1.5;
cristy7020ae62012-04-18 12:58:34 +00005903 colorspace=sRGBColorspace;
cristy3ed852e2009-09-05 21:47:34 +00005904 verbose=MagickFalse;
5905 if (attributes != (const xmlChar **) NULL)
5906 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5907 {
5908 keyword=(const char *) attributes[i++];
5909 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005910 msl_info->attributes[n],(const char *) attributes[i],
5911 &exception);
cristy3ed852e2009-09-05 21:47:34 +00005912 CloneString(&value,attribute);
5913 switch (*keyword)
5914 {
5915 case 'C':
5916 case 'c':
5917 {
5918 if (LocaleCompare(keyword,"cluster-threshold") == 0)
5919 {
cristydbdd0e32011-11-04 23:29:40 +00005920 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00005921 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005922 break;
5923 }
5924 if (LocaleCompare(keyword,"colorspace") == 0)
5925 {
cristy042ee782011-04-22 18:48:30 +00005926 option=ParseCommandOption(MagickColorspaceOptions,
cristy3ed852e2009-09-05 21:47:34 +00005927 MagickFalse,value);
5928 if (option < 0)
5929 ThrowMSLException(OptionError,
5930 "UnrecognizedColorspaceType",value);
5931 colorspace=(ColorspaceType) option;
5932 break;
5933 }
5934 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5935 keyword);
5936 break;
5937 }
5938 case 'G':
5939 case 'g':
5940 {
5941 if (LocaleCompare(keyword,"geometry") == 0)
5942 {
5943 flags=ParseGeometry(value,&geometry_info);
5944 if ((flags & SigmaValue) == 0)
5945 geometry_info.sigma=1.5;
5946 break;
5947 }
5948 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5949 keyword);
5950 break;
5951 }
5952 case 'S':
5953 case 's':
5954 {
5955 if (LocaleCompare(keyword,"smoothing-threshold") == 0)
5956 {
cristydbdd0e32011-11-04 23:29:40 +00005957 geometry_info.sigma=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00005958 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005959 break;
5960 }
5961 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5962 keyword);
5963 break;
5964 }
5965 default:
5966 {
5967 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5968 keyword);
5969 break;
5970 }
5971 }
5972 }
5973 (void) SegmentImage(msl_info->image[n],colorspace,verbose,
cristy018f07f2011-09-04 21:15:19 +00005974 geometry_info.rho,geometry_info.sigma,&exception);
cristy3ed852e2009-09-05 21:47:34 +00005975 break;
5976 }
cristyb988fe72009-09-16 01:01:10 +00005977 else if (LocaleCompare((const char *) tag, "set") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005978 {
5979 if (msl_info->image[n] == (Image *) NULL)
5980 {
cristy0b6d0052011-07-27 23:54:16 +00005981 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005982 break;
5983 }
5984
5985 if (attributes == (const xmlChar **) NULL)
5986 break;
5987 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5988 {
5989 keyword=(const char *) attributes[i++];
5990 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005991 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00005992 switch (*keyword)
5993 {
cristy3ed852e2009-09-05 21:47:34 +00005994 case 'C':
5995 case 'c':
5996 {
5997 if (LocaleCompare(keyword,"clip-mask") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005998 {
cristy2c8b6312009-09-16 02:37:23 +00005999 for (j=0; j < msl_info->n; j++)
cristy3ed852e2009-09-05 21:47:34 +00006000 {
cristy2c8b6312009-09-16 02:37:23 +00006001 const char
6002 *property;
6003
cristyd15e6592011-10-15 00:13:06 +00006004 property=GetImageProperty(msl_info->attributes[j],"id",
6005 &exception);
cristy2c8b6312009-09-16 02:37:23 +00006006 if (LocaleCompare(property,value) == 0)
6007 {
cristy018f07f2011-09-04 21:15:19 +00006008 SetImageMask(msl_info->image[n],msl_info->image[j],
6009 &exception);
cristy2c8b6312009-09-16 02:37:23 +00006010 break;
6011 }
cristy3ed852e2009-09-05 21:47:34 +00006012 }
cristy2c8b6312009-09-16 02:37:23 +00006013 break;
cristy3ed852e2009-09-05 21:47:34 +00006014 }
cristy3ed852e2009-09-05 21:47:34 +00006015 if (LocaleCompare(keyword,"clip-path") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006016 {
cristy2c8b6312009-09-16 02:37:23 +00006017 for (j=0; j < msl_info->n; j++)
cristy3ed852e2009-09-05 21:47:34 +00006018 {
cristy2c8b6312009-09-16 02:37:23 +00006019 const char
6020 *property;
6021
cristyd15e6592011-10-15 00:13:06 +00006022 property=GetImageProperty(msl_info->attributes[j],"id",
6023 &exception);
cristy2c8b6312009-09-16 02:37:23 +00006024 if (LocaleCompare(property,value) == 0)
6025 {
cristy10a6c612012-01-29 21:41:05 +00006026 SetImageMask(msl_info->image[n],msl_info->image[j],
cristy018f07f2011-09-04 21:15:19 +00006027 &exception);
cristy2c8b6312009-09-16 02:37:23 +00006028 break;
6029 }
cristy3ed852e2009-09-05 21:47:34 +00006030 }
cristy2c8b6312009-09-16 02:37:23 +00006031 break;
cristy3ed852e2009-09-05 21:47:34 +00006032 }
cristy2c8b6312009-09-16 02:37:23 +00006033 if (LocaleCompare(keyword,"colorspace") == 0)
6034 {
cristybb503372010-05-27 20:51:26 +00006035 ssize_t
cristy2c8b6312009-09-16 02:37:23 +00006036 colorspace;
6037
cristy042ee782011-04-22 18:48:30 +00006038 colorspace=(ColorspaceType) ParseCommandOption(
cristy7e9e6fa2010-11-21 17:06:24 +00006039 MagickColorspaceOptions,MagickFalse,value);
cristy2c8b6312009-09-16 02:37:23 +00006040 if (colorspace < 0)
cristyfb758a52009-09-16 14:36:08 +00006041 ThrowMSLException(OptionError,"UnrecognizedColorspace",
cristy2c8b6312009-09-16 02:37:23 +00006042 value);
6043 (void) TransformImageColorspace(msl_info->image[n],
cristye941a752011-10-15 01:52:48 +00006044 (ColorspaceType) colorspace,&exception);
cristy2c8b6312009-09-16 02:37:23 +00006045 break;
6046 }
6047 (void) SetMSLAttributes(msl_info,keyword,value);
cristyd15e6592011-10-15 00:13:06 +00006048 (void) SetImageProperty(msl_info->image[n],keyword,value,
6049 &exception);
cristy3ed852e2009-09-05 21:47:34 +00006050 break;
6051 }
6052 case 'D':
6053 case 'd':
6054 {
cristy2c8b6312009-09-16 02:37:23 +00006055 if (LocaleCompare(keyword,"density") == 0)
6056 {
6057 flags=ParseGeometry(value,&geometry_info);
cristy2a11bef2011-10-28 18:33:11 +00006058 msl_info->image[n]->resolution.x=geometry_info.rho;
6059 msl_info->image[n]->resolution.y=geometry_info.sigma;
cristy2c8b6312009-09-16 02:37:23 +00006060 if ((flags & SigmaValue) == 0)
cristy2a11bef2011-10-28 18:33:11 +00006061 msl_info->image[n]->resolution.y=
6062 msl_info->image[n]->resolution.x;
cristy2c8b6312009-09-16 02:37:23 +00006063 break;
6064 }
6065 (void) SetMSLAttributes(msl_info,keyword,value);
cristyd15e6592011-10-15 00:13:06 +00006066 (void) SetImageProperty(msl_info->image[n],keyword,value,
6067 &exception);
cristy3ed852e2009-09-05 21:47:34 +00006068 break;
6069 }
6070 case 'O':
6071 case 'o':
6072 {
6073 if (LocaleCompare(keyword, "opacity") == 0)
cristy2c8b6312009-09-16 02:37:23 +00006074 {
cristy4c08aed2011-07-01 19:47:50 +00006075 ssize_t opac = OpaqueAlpha,
cristybb503372010-05-27 20:51:26 +00006076 len = (ssize_t) strlen( value );
cristy3ed852e2009-09-05 21:47:34 +00006077
cristy2c8b6312009-09-16 02:37:23 +00006078 if (value[len-1] == '%') {
6079 char tmp[100];
6080 (void) CopyMagickString(tmp,value,len);
cristyf2f27272009-12-17 14:48:46 +00006081 opac = StringToLong( tmp );
cristy2c8b6312009-09-16 02:37:23 +00006082 opac = (int)(QuantumRange * ((float)opac/100));
6083 } else
cristyf2f27272009-12-17 14:48:46 +00006084 opac = StringToLong( value );
cristye941a752011-10-15 01:52:48 +00006085 (void) SetImageAlpha( msl_info->image[n], (Quantum) opac,
6086 &exception);
cristy2c8b6312009-09-16 02:37:23 +00006087 break;
cristy3ed852e2009-09-05 21:47:34 +00006088 }
cristy2c8b6312009-09-16 02:37:23 +00006089 (void) SetMSLAttributes(msl_info,keyword,value);
cristyd15e6592011-10-15 00:13:06 +00006090 (void) SetImageProperty(msl_info->image[n],keyword,value,
6091 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00006092 break;
6093 }
6094 case 'P':
6095 case 'p':
6096 {
6097 if (LocaleCompare(keyword, "page") == 0)
6098 {
6099 char
6100 page[MaxTextExtent];
6101
6102 const char
6103 *image_option;
6104
6105 MagickStatusType
6106 flags;
6107
6108 RectangleInfo
6109 geometry;
6110
6111 (void) ResetMagickMemory(&geometry,0,sizeof(geometry));
6112 image_option=GetImageOption(msl_info->image_info[n],"page");
6113 if (image_option != (const char *) NULL)
6114 flags=ParseAbsoluteGeometry(image_option,&geometry);
6115 flags=ParseAbsoluteGeometry(value,&geometry);
cristyb51dff52011-05-19 16:55:47 +00006116 (void) FormatLocaleString(page,MaxTextExtent,"%.20gx%.20g",
cristye8c25f92010-06-03 00:53:06 +00006117 (double) geometry.width,(double) geometry.height);
cristy3ed852e2009-09-05 21:47:34 +00006118 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
cristyb51dff52011-05-19 16:55:47 +00006119 (void) FormatLocaleString(page,MaxTextExtent,
cristye8c25f92010-06-03 00:53:06 +00006120 "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,
6121 (double) geometry.height,(double) geometry.x,(double)
cristyf2faecf2010-05-28 19:19:36 +00006122 geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00006123 (void) SetImageOption(msl_info->image_info[n],keyword,page);
6124 msl_info->image_info[n]->page=GetPageGeometry(page);
6125 break;
6126 }
cristy2c8b6312009-09-16 02:37:23 +00006127 (void) SetMSLAttributes(msl_info,keyword,value);
cristyd15e6592011-10-15 00:13:06 +00006128 (void) SetImageProperty(msl_info->image[n],keyword,value,
6129 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00006130 break;
6131 }
6132 default:
6133 {
cristy2c8b6312009-09-16 02:37:23 +00006134 (void) SetMSLAttributes(msl_info,keyword,value);
cristyd15e6592011-10-15 00:13:06 +00006135 (void) SetImageProperty(msl_info->image[n],keyword,value,
6136 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00006137 break;
6138 }
6139 }
6140 }
6141 break;
6142 }
cristyb988fe72009-09-16 01:01:10 +00006143 if (LocaleCompare((const char *) tag,"shade") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006144 {
6145 Image
6146 *shade_image;
6147
6148 MagickBooleanType
6149 gray;
6150
6151 /*
6152 Shade image.
6153 */
6154 if (msl_info->image[n] == (Image *) NULL)
6155 {
cristyb988fe72009-09-16 01:01:10 +00006156 ThrowMSLException(OptionError,"NoImagesDefined",
6157 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006158 break;
6159 }
6160 gray=MagickFalse;
6161 if (attributes != (const xmlChar **) NULL)
6162 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6163 {
6164 keyword=(const char *) attributes[i++];
6165 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006166 msl_info->attributes[n],(const char *) attributes[i],
6167 &exception);
cristy3ed852e2009-09-05 21:47:34 +00006168 CloneString(&value,attribute);
6169 switch (*keyword)
6170 {
6171 case 'A':
6172 case 'a':
6173 {
6174 if (LocaleCompare(keyword,"azimuth") == 0)
6175 {
cristydbdd0e32011-11-04 23:29:40 +00006176 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00006177 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006178 break;
6179 }
6180 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6181 keyword);
6182 break;
6183 }
6184 case 'E':
6185 case 'e':
6186 {
6187 if (LocaleCompare(keyword,"elevation") == 0)
6188 {
cristydbdd0e32011-11-04 23:29:40 +00006189 geometry_info.sigma=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00006190 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006191 break;
6192 }
6193 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6194 keyword);
6195 break;
6196 }
6197 case 'G':
6198 case 'g':
6199 {
6200 if (LocaleCompare(keyword,"geometry") == 0)
6201 {
6202 flags=ParseGeometry(value,&geometry_info);
6203 if ((flags & SigmaValue) == 0)
6204 geometry_info.sigma=1.0;
6205 break;
6206 }
6207 if (LocaleCompare(keyword,"gray") == 0)
6208 {
cristy042ee782011-04-22 18:48:30 +00006209 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00006210 value);
6211 if (option < 0)
6212 ThrowMSLException(OptionError,"UnrecognizedNoiseType",
6213 value);
6214 gray=(MagickBooleanType) option;
6215 break;
6216 }
6217 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6218 keyword);
6219 break;
6220 }
6221 default:
6222 {
6223 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6224 keyword);
6225 break;
6226 }
6227 }
6228 }
6229 shade_image=ShadeImage(msl_info->image[n],gray,geometry_info.rho,
cristyc82a27b2011-10-21 01:07:16 +00006230 geometry_info.sigma,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00006231 if (shade_image == (Image *) NULL)
6232 break;
6233 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6234 msl_info->image[n]=shade_image;
6235 break;
6236 }
cristyb988fe72009-09-16 01:01:10 +00006237 if (LocaleCompare((const char *) tag,"shadow") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006238 {
6239 Image
6240 *shadow_image;
6241
6242 /*
6243 Shear image.
6244 */
6245 if (msl_info->image[n] == (Image *) NULL)
6246 {
cristyb988fe72009-09-16 01:01:10 +00006247 ThrowMSLException(OptionError,"NoImagesDefined",
6248 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006249 break;
6250 }
6251 if (attributes != (const xmlChar **) NULL)
6252 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6253 {
6254 keyword=(const char *) attributes[i++];
6255 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006256 msl_info->attributes[n],(const char *) attributes[i],
6257 &exception);
cristy3ed852e2009-09-05 21:47:34 +00006258 CloneString(&value,attribute);
6259 switch (*keyword)
6260 {
6261 case 'G':
6262 case 'g':
6263 {
6264 if (LocaleCompare(keyword,"geometry") == 0)
6265 {
6266 flags=ParseGeometry(value,&geometry_info);
6267 if ((flags & SigmaValue) == 0)
6268 geometry_info.sigma=1.0;
6269 break;
6270 }
6271 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6272 keyword);
6273 break;
6274 }
6275 case 'O':
6276 case 'o':
6277 {
6278 if (LocaleCompare(keyword,"opacity") == 0)
6279 {
cristyf2f27272009-12-17 14:48:46 +00006280 geometry_info.rho=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006281 break;
6282 }
6283 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6284 keyword);
6285 break;
6286 }
6287 case 'S':
6288 case 's':
6289 {
6290 if (LocaleCompare(keyword,"sigma") == 0)
6291 {
cristyf2f27272009-12-17 14:48:46 +00006292 geometry_info.sigma=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006293 break;
6294 }
6295 break;
6296 }
6297 case 'X':
6298 case 'x':
6299 {
6300 if (LocaleCompare(keyword,"x") == 0)
6301 {
cristydbdd0e32011-11-04 23:29:40 +00006302 geometry_info.xi=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00006303 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006304 break;
6305 }
6306 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6307 keyword);
6308 break;
6309 }
6310 case 'Y':
6311 case 'y':
6312 {
6313 if (LocaleCompare(keyword,"y") == 0)
6314 {
cristyf2f27272009-12-17 14:48:46 +00006315 geometry_info.psi=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006316 break;
6317 }
6318 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6319 keyword);
6320 break;
6321 }
6322 default:
6323 {
6324 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6325 keyword);
6326 break;
6327 }
6328 }
6329 }
6330 shadow_image=ShadowImage(msl_info->image[n],geometry_info.rho,
cristyaa2c16c2012-03-25 22:21:35 +00006331 geometry_info.sigma,(ssize_t) ceil(geometry_info.xi-0.5),
cristyeb6e6582011-12-09 09:14:23 +00006332 (ssize_t) ceil(geometry_info.psi-0.5),msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00006333 if (shadow_image == (Image *) NULL)
6334 break;
6335 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6336 msl_info->image[n]=shadow_image;
6337 break;
6338 }
cristyb988fe72009-09-16 01:01:10 +00006339 if (LocaleCompare((const char *) tag,"sharpen") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006340 {
cristyaa2c16c2012-03-25 22:21:35 +00006341 double
cristy05c0c9a2011-09-05 23:16:13 +00006342 radius = 0.0,
cristy3ed852e2009-09-05 21:47:34 +00006343 sigma = 1.0;
6344
6345 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00006346 {
6347 ThrowMSLException(OptionError,"NoImagesDefined",
6348 (const char *) tag);
6349 break;
6350 }
cristy3ed852e2009-09-05 21:47:34 +00006351 /*
6352 NOTE: sharpen can have no attributes, since we use all the defaults!
6353 */
6354 if (attributes != (const xmlChar **) NULL)
6355 {
6356 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6357 {
6358 keyword=(const char *) attributes[i++];
6359 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006360 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00006361 switch (*keyword)
6362 {
6363 case 'R':
6364 case 'r':
6365 {
6366 if (LocaleCompare(keyword, "radius") == 0)
6367 {
cristydbdd0e32011-11-04 23:29:40 +00006368 radius = StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006369 break;
6370 }
6371 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6372 break;
6373 }
6374 case 'S':
6375 case 's':
6376 {
6377 if (LocaleCompare(keyword,"sigma") == 0)
6378 {
cristyf2f27272009-12-17 14:48:46 +00006379 sigma = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00006380 break;
6381 }
6382 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6383 break;
6384 }
6385 default:
6386 {
6387 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6388 break;
6389 }
6390 }
6391 }
6392 }
6393
6394 /*
6395 sharpen image.
6396 */
6397 {
6398 Image
6399 *newImage;
6400
cristyaa2c16c2012-03-25 22:21:35 +00006401 newImage=SharpenImage(msl_info->image[n],radius,sigma,
cristyc82a27b2011-10-21 01:07:16 +00006402 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00006403 if (newImage == (Image *) NULL)
6404 break;
6405 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6406 msl_info->image[n]=newImage;
6407 break;
6408 }
6409 }
cristyb988fe72009-09-16 01:01:10 +00006410 else if (LocaleCompare((const char *) tag,"shave") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006411 {
6412 /* init the values */
6413 width = height = 0;
6414 x = y = 0;
6415
6416 if (msl_info->image[n] == (Image *) NULL)
6417 {
cristyb988fe72009-09-16 01:01:10 +00006418 ThrowMSLException(OptionError,"NoImagesDefined",
6419 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006420 break;
6421 }
6422 if (attributes == (const xmlChar **) NULL)
6423 break;
6424 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6425 {
6426 keyword=(const char *) attributes[i++];
6427 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006428 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00006429 switch (*keyword)
6430 {
6431 case 'G':
6432 case 'g':
6433 {
6434 if (LocaleCompare(keyword,"geometry") == 0)
6435 {
6436 (void) ParseMetaGeometry(value,&x,&y,&width,&height);
6437 break;
6438 }
6439 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6440 break;
6441 }
6442 case 'H':
6443 case 'h':
6444 {
6445 if (LocaleCompare(keyword,"height") == 0)
6446 {
cristyf2f27272009-12-17 14:48:46 +00006447 height = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00006448 break;
6449 }
6450 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6451 break;
6452 }
6453 case 'W':
6454 case 'w':
6455 {
6456 if (LocaleCompare(keyword,"width") == 0)
6457 {
cristyf2f27272009-12-17 14:48:46 +00006458 width = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00006459 break;
6460 }
6461 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6462 break;
6463 }
6464 default:
6465 {
6466 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6467 break;
6468 }
6469 }
6470 }
6471
6472 /*
6473 process image.
6474 */
6475 {
6476 Image
6477 *newImage;
6478 RectangleInfo
6479 rectInfo;
6480
6481 rectInfo.height = height;
6482 rectInfo.width = width;
6483 rectInfo.x = x;
6484 rectInfo.y = y;
6485
6486
6487 newImage=ShaveImage(msl_info->image[n], &rectInfo,
cristyc82a27b2011-10-21 01:07:16 +00006488 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00006489 if (newImage == (Image *) NULL)
6490 break;
6491 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6492 msl_info->image[n]=newImage;
6493 }
6494
6495 break;
6496 }
cristyb988fe72009-09-16 01:01:10 +00006497 if (LocaleCompare((const char *) tag,"shear") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006498 {
6499 Image
6500 *shear_image;
6501
6502 /*
6503 Shear image.
6504 */
6505 if (msl_info->image[n] == (Image *) NULL)
6506 {
cristyb988fe72009-09-16 01:01:10 +00006507 ThrowMSLException(OptionError,"NoImagesDefined",
6508 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006509 break;
6510 }
6511 if (attributes != (const xmlChar **) NULL)
6512 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6513 {
6514 keyword=(const char *) attributes[i++];
6515 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006516 msl_info->attributes[n],(const char *) attributes[i],
6517 &exception);
cristy3ed852e2009-09-05 21:47:34 +00006518 CloneString(&value,attribute);
6519 switch (*keyword)
6520 {
6521 case 'F':
6522 case 'f':
6523 {
6524 if (LocaleCompare(keyword, "fill") == 0)
6525 {
cristy9950d572011-10-01 18:22:35 +00006526 (void) QueryColorCompliance(value,AllCompliance,
cristy3ed852e2009-09-05 21:47:34 +00006527 &msl_info->image[n]->background_color,&exception);
6528 break;
6529 }
6530 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6531 keyword);
6532 break;
6533 }
6534 case 'G':
6535 case 'g':
6536 {
6537 if (LocaleCompare(keyword,"geometry") == 0)
6538 {
6539 flags=ParseGeometry(value,&geometry_info);
6540 if ((flags & SigmaValue) == 0)
6541 geometry_info.sigma=1.0;
6542 break;
6543 }
6544 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6545 keyword);
6546 break;
6547 }
6548 case 'X':
6549 case 'x':
6550 {
6551 if (LocaleCompare(keyword,"x") == 0)
6552 {
cristydbdd0e32011-11-04 23:29:40 +00006553 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00006554 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006555 break;
6556 }
6557 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6558 keyword);
6559 break;
6560 }
6561 case 'Y':
6562 case 'y':
6563 {
6564 if (LocaleCompare(keyword,"y") == 0)
6565 {
cristyf2f27272009-12-17 14:48:46 +00006566 geometry_info.sigma=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006567 break;
6568 }
6569 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6570 keyword);
6571 break;
6572 }
6573 default:
6574 {
6575 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6576 keyword);
6577 break;
6578 }
6579 }
6580 }
6581 shear_image=ShearImage(msl_info->image[n],geometry_info.rho,
cristyc82a27b2011-10-21 01:07:16 +00006582 geometry_info.sigma,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00006583 if (shear_image == (Image *) NULL)
6584 break;
6585 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6586 msl_info->image[n]=shear_image;
6587 break;
6588 }
cristyb988fe72009-09-16 01:01:10 +00006589 if (LocaleCompare((const char *) tag,"signature") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006590 {
6591 /*
6592 Signature image.
6593 */
6594 if (msl_info->image[n] == (Image *) NULL)
6595 {
cristyb988fe72009-09-16 01:01:10 +00006596 ThrowMSLException(OptionError,"NoImagesDefined",
6597 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006598 break;
6599 }
6600 if (attributes != (const xmlChar **) NULL)
6601 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6602 {
6603 keyword=(const char *) attributes[i++];
6604 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006605 msl_info->attributes[n],(const char *) attributes[i],
6606 &exception);
cristy3ed852e2009-09-05 21:47:34 +00006607 CloneString(&value,attribute);
6608 switch (*keyword)
6609 {
6610 default:
6611 {
6612 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6613 keyword);
6614 break;
6615 }
6616 }
6617 }
cristy018f07f2011-09-04 21:15:19 +00006618 (void) SignatureImage(msl_info->image[n],&exception);
cristy3ed852e2009-09-05 21:47:34 +00006619 break;
6620 }
cristyb988fe72009-09-16 01:01:10 +00006621 if (LocaleCompare((const char *) tag,"solarize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006622 {
6623 /*
6624 Solarize image.
6625 */
6626 if (msl_info->image[n] == (Image *) NULL)
6627 {
cristyb988fe72009-09-16 01:01:10 +00006628 ThrowMSLException(OptionError,"NoImagesDefined",
6629 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006630 break;
6631 }
6632 geometry_info.rho=QuantumRange/2.0;
6633 if (attributes != (const xmlChar **) NULL)
6634 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6635 {
6636 keyword=(const char *) attributes[i++];
6637 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006638 msl_info->attributes[n],(const char *) attributes[i],
6639 &exception);
cristy3ed852e2009-09-05 21:47:34 +00006640 CloneString(&value,attribute);
6641 switch (*keyword)
6642 {
6643 case 'G':
6644 case 'g':
6645 {
6646 if (LocaleCompare(keyword,"geometry") == 0)
6647 {
6648 flags=ParseGeometry(value,&geometry_info);
6649 break;
6650 }
6651 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6652 keyword);
6653 break;
6654 }
6655 case 'T':
6656 case 't':
6657 {
6658 if (LocaleCompare(keyword,"threshold") == 0)
6659 {
cristydbdd0e32011-11-04 23:29:40 +00006660 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00006661 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006662 break;
6663 }
6664 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6665 keyword);
6666 break;
6667 }
6668 default:
6669 {
6670 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6671 keyword);
6672 break;
6673 }
6674 }
6675 }
cristy5cbc0162011-08-29 00:36:28 +00006676 (void) SolarizeImage(msl_info->image[n],geometry_info.rho,
cristyc82a27b2011-10-21 01:07:16 +00006677 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00006678 break;
6679 }
cristyb988fe72009-09-16 01:01:10 +00006680 if (LocaleCompare((const char *) tag,"spread") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006681 {
6682 Image
6683 *spread_image;
6684
6685 /*
6686 Spread image.
6687 */
6688 if (msl_info->image[n] == (Image *) NULL)
6689 {
cristyb988fe72009-09-16 01:01:10 +00006690 ThrowMSLException(OptionError,"NoImagesDefined",
6691 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006692 break;
6693 }
6694 if (attributes != (const xmlChar **) NULL)
6695 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6696 {
6697 keyword=(const char *) attributes[i++];
6698 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006699 msl_info->attributes[n],(const char *) attributes[i],
6700 &exception);
cristy3ed852e2009-09-05 21:47:34 +00006701 CloneString(&value,attribute);
6702 switch (*keyword)
6703 {
6704 case 'G':
6705 case 'g':
6706 {
6707 if (LocaleCompare(keyword,"geometry") == 0)
6708 {
6709 flags=ParseGeometry(value,&geometry_info);
6710 if ((flags & SigmaValue) == 0)
6711 geometry_info.sigma=1.0;
6712 break;
6713 }
6714 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6715 keyword);
6716 break;
6717 }
6718 case 'R':
6719 case 'r':
6720 {
6721 if (LocaleCompare(keyword,"radius") == 0)
6722 {
cristydbdd0e32011-11-04 23:29:40 +00006723 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00006724 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006725 break;
6726 }
6727 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6728 keyword);
6729 break;
6730 }
6731 default:
6732 {
6733 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6734 keyword);
6735 break;
6736 }
6737 }
6738 }
6739 spread_image=SpreadImage(msl_info->image[n],geometry_info.rho,
cristyc82a27b2011-10-21 01:07:16 +00006740 msl_info->image[n]->interpolate,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00006741 if (spread_image == (Image *) NULL)
6742 break;
6743 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6744 msl_info->image[n]=spread_image;
6745 break;
6746 }
cristyb988fe72009-09-16 01:01:10 +00006747 else if (LocaleCompare((const char *) tag,"stegano") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006748 {
6749 Image *
6750 watermark = (Image*)NULL;
6751
6752 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00006753 {
6754 ThrowMSLException(OptionError,"NoImagesDefined",
6755 (const char *) tag);
6756 break;
6757 }
cristy3ed852e2009-09-05 21:47:34 +00006758 if (attributes == (const xmlChar **) NULL)
6759 break;
6760 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6761 {
6762 keyword=(const char *) attributes[i++];
6763 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006764 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00006765 switch (*keyword)
6766 {
6767 case 'I':
6768 case 'i':
6769 {
6770 if (LocaleCompare(keyword,"image") == 0)
6771 {
6772 for (j=0; j<msl_info->n;j++)
6773 {
6774 const char *
cristyd15e6592011-10-15 00:13:06 +00006775 theAttr = GetImageProperty(msl_info->attributes[j], "id",
6776 &exception);
cristy3ed852e2009-09-05 21:47:34 +00006777 if (theAttr && LocaleCompare(theAttr, value) == 0)
6778 {
6779 watermark = msl_info->image[j];
6780 break;
6781 }
6782 }
6783 break;
6784 }
6785 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6786 break;
6787 }
6788 default:
6789 {
6790 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6791 break;
6792 }
6793 }
6794 }
6795
6796 /*
6797 process image.
6798 */
6799 if ( watermark != (Image*) NULL )
6800 {
6801 Image
6802 *newImage;
6803
cristyc82a27b2011-10-21 01:07:16 +00006804 newImage=SteganoImage(msl_info->image[n], watermark, msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00006805 if (newImage == (Image *) NULL)
6806 break;
6807 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6808 msl_info->image[n]=newImage;
6809 break;
6810 } else
6811 ThrowMSLException(OptionError,"MissingWatermarkImage",keyword);
6812 }
cristyb988fe72009-09-16 01:01:10 +00006813 else if (LocaleCompare((const char *) tag,"stereo") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006814 {
6815 Image *
6816 stereoImage = (Image*)NULL;
6817
6818 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00006819 {
6820 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
6821 break;
6822 }
cristy3ed852e2009-09-05 21:47:34 +00006823 if (attributes == (const xmlChar **) NULL)
6824 break;
6825 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6826 {
6827 keyword=(const char *) attributes[i++];
6828 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006829 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00006830 switch (*keyword)
6831 {
6832 case 'I':
6833 case 'i':
6834 {
6835 if (LocaleCompare(keyword,"image") == 0)
6836 {
6837 for (j=0; j<msl_info->n;j++)
6838 {
6839 const char *
cristyd15e6592011-10-15 00:13:06 +00006840 theAttr = GetImageProperty(msl_info->attributes[j], "id",
6841 &exception);
cristy3ed852e2009-09-05 21:47:34 +00006842 if (theAttr && LocaleCompare(theAttr, value) == 0)
6843 {
6844 stereoImage = msl_info->image[j];
6845 break;
6846 }
6847 }
6848 break;
6849 }
6850 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6851 break;
6852 }
6853 default:
6854 {
6855 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6856 break;
6857 }
6858 }
6859 }
6860
6861 /*
6862 process image.
6863 */
6864 if ( stereoImage != (Image*) NULL )
6865 {
6866 Image
6867 *newImage;
6868
cristyc82a27b2011-10-21 01:07:16 +00006869 newImage=StereoImage(msl_info->image[n], stereoImage, msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00006870 if (newImage == (Image *) NULL)
6871 break;
6872 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6873 msl_info->image[n]=newImage;
6874 break;
6875 } else
6876 ThrowMSLException(OptionError,"Missing stereo image",keyword);
6877 }
cristyb988fe72009-09-16 01:01:10 +00006878 if (LocaleCompare((const char *) tag,"swap") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006879 {
6880 Image
6881 *p,
6882 *q,
6883 *swap;
6884
cristybb503372010-05-27 20:51:26 +00006885 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00006886 index,
6887 swap_index;
6888
6889 if (msl_info->image[n] == (Image *) NULL)
6890 {
cristyb988fe72009-09-16 01:01:10 +00006891 ThrowMSLException(OptionError,"NoImagesDefined",
6892 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006893 break;
6894 }
6895 index=(-1);
6896 swap_index=(-2);
6897 if (attributes != (const xmlChar **) NULL)
6898 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6899 {
6900 keyword=(const char *) attributes[i++];
6901 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006902 msl_info->attributes[n],(const char *) attributes[i],
6903 &exception);
cristy3ed852e2009-09-05 21:47:34 +00006904 CloneString(&value,attribute);
6905 switch (*keyword)
6906 {
6907 case 'G':
6908 case 'g':
6909 {
6910 if (LocaleCompare(keyword,"indexes") == 0)
6911 {
6912 flags=ParseGeometry(value,&geometry_info);
cristybb503372010-05-27 20:51:26 +00006913 index=(ssize_t) geometry_info.rho;
cristy3ed852e2009-09-05 21:47:34 +00006914 if ((flags & SigmaValue) == 0)
cristybb503372010-05-27 20:51:26 +00006915 swap_index=(ssize_t) geometry_info.sigma;
cristy3ed852e2009-09-05 21:47:34 +00006916 break;
6917 }
6918 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6919 keyword);
6920 break;
6921 }
6922 default:
6923 {
6924 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6925 keyword);
6926 break;
6927 }
6928 }
6929 }
6930 /*
6931 Swap images.
6932 */
6933 p=GetImageFromList(msl_info->image[n],index);
6934 q=GetImageFromList(msl_info->image[n],swap_index);
6935 if ((p == (Image *) NULL) || (q == (Image *) NULL))
6936 {
cristyb988fe72009-09-16 01:01:10 +00006937 ThrowMSLException(OptionError,"NoSuchImage",(const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006938 break;
6939 }
cristyc82a27b2011-10-21 01:07:16 +00006940 swap=CloneImage(p,0,0,MagickTrue,msl_info->exception);
6941 ReplaceImageInList(&p,CloneImage(q,0,0,MagickTrue,
6942 msl_info->exception));
cristy3ed852e2009-09-05 21:47:34 +00006943 ReplaceImageInList(&q,swap);
6944 msl_info->image[n]=GetFirstImageInList(q);
6945 break;
6946 }
cristyb988fe72009-09-16 01:01:10 +00006947 if (LocaleCompare((const char *) tag,"swirl") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006948 {
6949 Image
6950 *swirl_image;
6951
6952 /*
6953 Swirl 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],
cristy018f07f2011-09-04 21:15:19 +00006966 msl_info->attributes[n],(const char *) attributes[i],
6967 &exception);
cristy3ed852e2009-09-05 21:47:34 +00006968 CloneString(&value,attribute);
6969 switch (*keyword)
6970 {
6971 case 'D':
6972 case 'd':
6973 {
6974 if (LocaleCompare(keyword,"degrees") == 0)
6975 {
cristydbdd0e32011-11-04 23:29:40 +00006976 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00006977 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006978 break;
6979 }
6980 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6981 keyword);
6982 break;
6983 }
6984 case 'G':
6985 case 'g':
6986 {
6987 if (LocaleCompare(keyword,"geometry") == 0)
6988 {
6989 flags=ParseGeometry(value,&geometry_info);
6990 if ((flags & SigmaValue) == 0)
6991 geometry_info.sigma=1.0;
6992 break;
6993 }
6994 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6995 keyword);
6996 break;
6997 }
6998 default:
6999 {
7000 ThrowMSLException(OptionError,"UnrecognizedAttribute",
7001 keyword);
7002 break;
7003 }
7004 }
7005 }
7006 swirl_image=SwirlImage(msl_info->image[n],geometry_info.rho,
cristyc82a27b2011-10-21 01:07:16 +00007007 msl_info->image[n]->interpolate,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00007008 if (swirl_image == (Image *) NULL)
7009 break;
7010 msl_info->image[n]=DestroyImage(msl_info->image[n]);
7011 msl_info->image[n]=swirl_image;
7012 break;
7013 }
cristyb988fe72009-09-16 01:01:10 +00007014 if (LocaleCompare((const char *) tag,"sync") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007015 {
7016 /*
7017 Sync image.
7018 */
7019 if (msl_info->image[n] == (Image *) NULL)
7020 {
cristyb988fe72009-09-16 01:01:10 +00007021 ThrowMSLException(OptionError,"NoImagesDefined",
7022 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00007023 break;
7024 }
7025 if (attributes != (const xmlChar **) NULL)
7026 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7027 {
7028 keyword=(const char *) attributes[i++];
7029 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00007030 msl_info->attributes[n],(const char *) attributes[i],
7031 &exception);
cristy3ed852e2009-09-05 21:47:34 +00007032 CloneString(&value,attribute);
7033 switch (*keyword)
7034 {
7035 default:
7036 {
7037 ThrowMSLException(OptionError,"UnrecognizedAttribute",
7038 keyword);
7039 break;
7040 }
7041 }
7042 }
cristyea1a8aa2011-10-20 13:24:06 +00007043 (void) SyncImage(msl_info->image[n],&exception);
cristy3ed852e2009-09-05 21:47:34 +00007044 break;
7045 }
7046 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7047 }
7048 case 'T':
7049 case 't':
7050 {
cristyb988fe72009-09-16 01:01:10 +00007051 if (LocaleCompare((const char *) tag,"map") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007052 {
7053 Image
7054 *texture_image;
7055
7056 /*
7057 Texture image.
7058 */
7059 if (msl_info->image[n] == (Image *) NULL)
7060 {
cristyb988fe72009-09-16 01:01:10 +00007061 ThrowMSLException(OptionError,"NoImagesDefined",
7062 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00007063 break;
7064 }
7065 texture_image=NewImageList();
7066 if (attributes != (const xmlChar **) NULL)
7067 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7068 {
7069 keyword=(const char *) attributes[i++];
7070 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00007071 msl_info->attributes[n],(const char *) attributes[i],
7072 &exception);
cristy3ed852e2009-09-05 21:47:34 +00007073 CloneString(&value,attribute);
7074 switch (*keyword)
7075 {
7076 case 'I':
7077 case 'i':
7078 {
7079 if (LocaleCompare(keyword,"image") == 0)
7080 for (j=0; j < msl_info->n; j++)
7081 {
7082 const char
7083 *attribute;
cristyb988fe72009-09-16 01:01:10 +00007084
cristyd15e6592011-10-15 00:13:06 +00007085 attribute=GetImageProperty(msl_info->attributes[j],"id",
7086 &exception);
cristy3ed852e2009-09-05 21:47:34 +00007087 if ((attribute != (const char *) NULL) &&
7088 (LocaleCompare(attribute,value) == 0))
7089 {
7090 texture_image=CloneImage(msl_info->image[j],0,0,
7091 MagickFalse,&exception);
7092 break;
7093 }
7094 }
7095 break;
7096 }
7097 default:
7098 {
7099 ThrowMSLException(OptionError,"UnrecognizedAttribute",
7100 keyword);
7101 break;
7102 }
7103 }
7104 }
cristye941a752011-10-15 01:52:48 +00007105 (void) TextureImage(msl_info->image[n],texture_image,&exception);
cristy3ed852e2009-09-05 21:47:34 +00007106 texture_image=DestroyImage(texture_image);
7107 break;
7108 }
cristyb988fe72009-09-16 01:01:10 +00007109 else if (LocaleCompare((const char *) tag,"threshold") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007110 {
7111 /* init the values */
7112 double threshold = 0;
7113
7114 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007115 {
7116 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7117 break;
7118 }
cristy3ed852e2009-09-05 21:47:34 +00007119 if (attributes == (const xmlChar **) NULL)
7120 break;
7121 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7122 {
7123 keyword=(const char *) attributes[i++];
7124 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00007125 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00007126 switch (*keyword)
7127 {
7128 case 'T':
7129 case 't':
7130 {
7131 if (LocaleCompare(keyword,"threshold") == 0)
7132 {
cristydbdd0e32011-11-04 23:29:40 +00007133 threshold = StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00007134 break;
7135 }
7136 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7137 break;
7138 }
7139 default:
7140 {
7141 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7142 break;
7143 }
7144 }
7145 }
7146
7147 /*
7148 process image.
7149 */
7150 {
cristye941a752011-10-15 01:52:48 +00007151 BilevelImage(msl_info->image[n],threshold,&exception);
7152 break;
cristy3ed852e2009-09-05 21:47:34 +00007153 }
7154 }
cristyb988fe72009-09-16 01:01:10 +00007155 else if (LocaleCompare((const char *) tag, "transparent") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007156 {
7157 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007158 {
7159 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7160 break;
7161 }
cristy3ed852e2009-09-05 21:47:34 +00007162 if (attributes == (const xmlChar **) NULL)
7163 break;
7164 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7165 {
7166 keyword=(const char *) attributes[i++];
7167 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00007168 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00007169 switch (*keyword)
7170 {
7171 case 'C':
7172 case 'c':
7173 {
7174 if (LocaleCompare(keyword,"color") == 0)
7175 {
cristy4c08aed2011-07-01 19:47:50 +00007176 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00007177 target;
7178
cristy269c9412011-10-13 23:41:15 +00007179 (void) QueryColorCompliance(value,AllCompliance,&target,
cristy9950d572011-10-01 18:22:35 +00007180 &exception);
cristy3ed852e2009-09-05 21:47:34 +00007181 (void) TransparentPaintImage(msl_info->image[n],&target,
cristyc82a27b2011-10-21 01:07:16 +00007182 TransparentAlpha,MagickFalse,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00007183 break;
7184 }
7185 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7186 break;
7187 }
7188 default:
7189 {
7190 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7191 break;
7192 }
7193 }
7194 }
7195 break;
7196 }
cristyb988fe72009-09-16 01:01:10 +00007197 else if (LocaleCompare((const char *) tag, "trim") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007198 {
7199 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007200 {
7201 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7202 break;
7203 }
cristy3ed852e2009-09-05 21:47:34 +00007204
7205 /* no attributes here */
7206
7207 /* process the image */
7208 {
7209 Image
7210 *newImage;
7211 RectangleInfo
7212 rectInfo;
7213
7214 /* all zeros on a crop == trim edges! */
7215 rectInfo.height = rectInfo.width = 0;
7216 rectInfo.x = rectInfo.y = 0;
7217
cristyc82a27b2011-10-21 01:07:16 +00007218 newImage=CropImage(msl_info->image[n],&rectInfo, msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00007219 if (newImage == (Image *) NULL)
7220 break;
7221 msl_info->image[n]=DestroyImage(msl_info->image[n]);
7222 msl_info->image[n]=newImage;
7223 break;
7224 }
7225 }
7226 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7227 }
7228 case 'W':
7229 case 'w':
7230 {
cristyb988fe72009-09-16 01:01:10 +00007231 if (LocaleCompare((const char *) tag,"write") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007232 {
7233 if (msl_info->image[n] == (Image *) NULL)
7234 {
cristyb988fe72009-09-16 01:01:10 +00007235 ThrowMSLException(OptionError,"NoImagesDefined",
7236 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00007237 break;
7238 }
7239 if (attributes == (const xmlChar **) NULL)
7240 break;
7241 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7242 {
7243 keyword=(const char *) attributes[i++];
7244 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00007245 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00007246 switch (*keyword)
7247 {
7248 case 'F':
7249 case 'f':
7250 {
7251 if (LocaleCompare(keyword,"filename") == 0)
7252 {
7253 (void) CopyMagickString(msl_info->image[n]->filename,value,
7254 MaxTextExtent);
7255 break;
7256 }
cristy4582cbb2009-09-23 00:35:43 +00007257 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00007258 }
7259 default:
7260 {
cristy4582cbb2009-09-23 00:35:43 +00007261 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00007262 break;
7263 }
7264 }
7265 }
7266
7267 /* process */
7268 {
cristy6f9e0d32011-08-28 16:32:09 +00007269 (void) WriteImage(msl_info->image_info[n], msl_info->image[n],
cristyc82a27b2011-10-21 01:07:16 +00007270 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00007271 break;
7272 }
7273 }
7274 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7275 }
7276 default:
7277 {
7278 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7279 break;
7280 }
7281 }
7282 if ( value != NULL )
7283 value=DestroyString(value);
7284 (void) LogMagickEvent(CoderEvent,GetMagickModule()," )");
7285}
7286
7287static void MSLEndElement(void *context,const xmlChar *tag)
7288{
cristybb503372010-05-27 20:51:26 +00007289 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00007290 n;
7291
7292 MSLInfo
7293 *msl_info;
7294
7295 /*
7296 Called when the end of an element has been detected.
7297 */
7298 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.endElement(%s)",
7299 tag);
7300 msl_info=(MSLInfo *) context;
7301 n=msl_info->n;
7302 switch (*tag)
7303 {
7304 case 'C':
7305 case 'c':
7306 {
cristyb988fe72009-09-16 01:01:10 +00007307 if (LocaleCompare((const char *) tag,"comment") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007308 {
7309 (void) DeleteImageProperty(msl_info->image[n],"comment");
7310 if (msl_info->content == (char *) NULL)
7311 break;
7312 StripString(msl_info->content);
7313 (void) SetImageProperty(msl_info->image[n],"comment",
cristyd15e6592011-10-15 00:13:06 +00007314 msl_info->content,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00007315 break;
7316 }
7317 break;
7318 }
7319 case 'G':
7320 case 'g':
7321 {
cristyb988fe72009-09-16 01:01:10 +00007322 if (LocaleCompare((const char *) tag, "group") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007323 {
7324 if (msl_info->group_info[msl_info->number_groups-1].numImages > 0 )
7325 {
cristybb503372010-05-27 20:51:26 +00007326 ssize_t i = (ssize_t)
cristy3ed852e2009-09-05 21:47:34 +00007327 (msl_info->group_info[msl_info->number_groups-1].numImages);
7328 while ( i-- )
7329 {
7330 if (msl_info->image[msl_info->n] != (Image *) NULL)
cristyd15e6592011-10-15 00:13:06 +00007331 msl_info->image[msl_info->n]=DestroyImage(
7332 msl_info->image[msl_info->n]);
7333 msl_info->attributes[msl_info->n]=DestroyImage(
7334 msl_info->attributes[msl_info->n]);
7335 msl_info->image_info[msl_info->n]=DestroyImageInfo(
7336 msl_info->image_info[msl_info->n]);
cristy3ed852e2009-09-05 21:47:34 +00007337 msl_info->n--;
7338 }
7339 }
7340 msl_info->number_groups--;
7341 }
7342 break;
7343 }
7344 case 'I':
7345 case 'i':
7346 {
cristyb988fe72009-09-16 01:01:10 +00007347 if (LocaleCompare((const char *) tag, "image") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007348 MSLPopImage(msl_info);
7349 break;
7350 }
7351 case 'L':
7352 case 'l':
7353 {
cristyb988fe72009-09-16 01:01:10 +00007354 if (LocaleCompare((const char *) tag,"label") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007355 {
7356 (void) DeleteImageProperty(msl_info->image[n],"label");
7357 if (msl_info->content == (char *) NULL)
7358 break;
7359 StripString(msl_info->content);
7360 (void) SetImageProperty(msl_info->image[n],"label",
cristyd15e6592011-10-15 00:13:06 +00007361 msl_info->content,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00007362 break;
7363 }
7364 break;
7365 }
7366 case 'M':
7367 case 'm':
7368 {
cristyb988fe72009-09-16 01:01:10 +00007369 if (LocaleCompare((const char *) tag, "msl") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007370 {
7371 /*
7372 This our base element.
7373 at the moment we don't do anything special
7374 but someday we might!
7375 */
7376 }
7377 break;
7378 }
7379 default:
7380 break;
7381 }
7382 if (msl_info->content != (char *) NULL)
7383 msl_info->content=DestroyString(msl_info->content);
7384}
7385
7386static void MSLCharacters(void *context,const xmlChar *c,int length)
7387{
7388 MSLInfo
7389 *msl_info;
7390
7391 register char
7392 *p;
7393
cristybb503372010-05-27 20:51:26 +00007394 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00007395 i;
7396
7397 /*
7398 Receiving some characters from the parser.
7399 */
7400 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7401 " SAX.characters(%s,%d)",c,length);
7402 msl_info=(MSLInfo *) context;
7403 if (msl_info->content != (char *) NULL)
7404 msl_info->content=(char *) ResizeQuantumMemory(msl_info->content,
7405 strlen(msl_info->content)+length+MaxTextExtent,
7406 sizeof(*msl_info->content));
7407 else
7408 {
7409 msl_info->content=(char *) NULL;
cristy37e0b382011-06-07 13:31:21 +00007410 if (~length >= (MaxTextExtent-1))
cristy3ed852e2009-09-05 21:47:34 +00007411 msl_info->content=(char *) AcquireQuantumMemory(length+MaxTextExtent,
7412 sizeof(*msl_info->content));
7413 if (msl_info->content != (char *) NULL)
7414 *msl_info->content='\0';
7415 }
7416 if (msl_info->content == (char *) NULL)
7417 return;
7418 p=msl_info->content+strlen(msl_info->content);
7419 for (i=0; i < length; i++)
7420 *p++=c[i];
7421 *p='\0';
7422}
7423
7424static void MSLReference(void *context,const xmlChar *name)
7425{
7426 MSLInfo
7427 *msl_info;
7428
7429 xmlParserCtxtPtr
7430 parser;
7431
7432 /*
7433 Called when an entity reference is detected.
7434 */
7435 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7436 " SAX.reference(%s)",name);
7437 msl_info=(MSLInfo *) context;
7438 parser=msl_info->parser;
7439 if (*name == '#')
7440 (void) xmlAddChild(parser->node,xmlNewCharRef(msl_info->document,name));
7441 else
7442 (void) xmlAddChild(parser->node,xmlNewReference(msl_info->document,name));
7443}
7444
7445static void MSLIgnorableWhitespace(void *context,const xmlChar *c,int length)
7446{
7447 MSLInfo
7448 *msl_info;
7449
7450 /*
7451 Receiving some ignorable whitespaces from the parser.
7452 */
7453 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7454 " SAX.ignorableWhitespace(%.30s, %d)",c,length);
7455 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007456 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007457}
7458
7459static void MSLProcessingInstructions(void *context,const xmlChar *target,
7460 const xmlChar *data)
7461{
7462 MSLInfo
7463 *msl_info;
7464
7465 /*
7466 A processing instruction has been parsed.
7467 */
7468 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7469 " SAX.processingInstruction(%s, %s)",
7470 target,data);
7471 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007472 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007473}
7474
7475static void MSLComment(void *context,const xmlChar *value)
7476{
7477 MSLInfo
7478 *msl_info;
7479
7480 /*
7481 A comment has been parsed.
7482 */
7483 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7484 " SAX.comment(%s)",value);
7485 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007486 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007487}
7488
7489static void MSLWarning(void *context,const char *format,...)
7490{
7491 char
7492 *message,
7493 reason[MaxTextExtent];
7494
7495 MSLInfo
7496 *msl_info;
7497
7498 va_list
7499 operands;
7500
7501 /**
7502 Display and format a warning messages, gives file, line, position and
7503 extra parameters.
7504 */
7505 va_start(operands,format);
7506 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.warning: ");
7507 (void) LogMagickEvent(CoderEvent,GetMagickModule(),format,operands);
7508 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007509 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007510#if !defined(MAGICKCORE_HAVE_VSNPRINTF)
7511 (void) vsprintf(reason,format,operands);
7512#else
7513 (void) vsnprintf(reason,MaxTextExtent,format,operands);
7514#endif
7515 message=GetExceptionMessage(errno);
7516 ThrowMSLException(CoderError,reason,message);
7517 message=DestroyString(message);
7518 va_end(operands);
7519}
7520
7521static void MSLError(void *context,const char *format,...)
7522{
7523 char
7524 reason[MaxTextExtent];
7525
7526 MSLInfo
7527 *msl_info;
7528
7529 va_list
7530 operands;
7531
7532 /*
7533 Display and format a error formats, gives file, line, position and
7534 extra parameters.
7535 */
7536 va_start(operands,format);
7537 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.error: ");
7538 (void) LogMagickEvent(CoderEvent,GetMagickModule(),format,operands);
7539 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007540 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007541#if !defined(MAGICKCORE_HAVE_VSNPRINTF)
7542 (void) vsprintf(reason,format,operands);
7543#else
7544 (void) vsnprintf(reason,MaxTextExtent,format,operands);
7545#endif
7546 ThrowMSLException(DelegateFatalError,reason,"SAX error");
7547 va_end(operands);
7548}
7549
7550static void MSLCDataBlock(void *context,const xmlChar *value,int length)
7551{
7552 MSLInfo
7553 *msl_info;
7554
7555 xmlNodePtr
7556 child;
7557
7558 xmlParserCtxtPtr
7559 parser;
7560
7561 /*
7562 Called when a pcdata block has been parsed.
7563 */
7564 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7565 " SAX.pcdata(%s, %d)",value,length);
7566 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007567 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007568 parser=msl_info->parser;
7569 child=xmlGetLastChild(parser->node);
7570 if ((child != (xmlNodePtr) NULL) && (child->type == XML_CDATA_SECTION_NODE))
7571 {
7572 xmlTextConcat(child,value,length);
7573 return;
7574 }
7575 (void) xmlAddChild(parser->node,xmlNewCDataBlock(parser->myDoc,value,length));
7576}
7577
7578static void MSLExternalSubset(void *context,const xmlChar *name,
7579 const xmlChar *external_id,const xmlChar *system_id)
7580{
7581 MSLInfo
7582 *msl_info;
7583
7584 xmlParserCtxt
7585 parser_context;
7586
7587 xmlParserCtxtPtr
7588 parser;
7589
7590 xmlParserInputPtr
7591 input;
7592
7593 /*
7594 Does this document has an external subset?
7595 */
7596 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7597 " SAX.externalSubset(%s %s %s)",name,
cristyb988fe72009-09-16 01:01:10 +00007598 (external_id != (const xmlChar *) NULL ? (const char *) external_id : " "),
7599 (system_id != (const xmlChar *) NULL ? (const char *) system_id : " "));
cristy3ed852e2009-09-05 21:47:34 +00007600 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007601 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007602 parser=msl_info->parser;
7603 if (((external_id == NULL) && (system_id == NULL)) ||
7604 ((parser->validate == 0) || (parser->wellFormed == 0) ||
7605 (msl_info->document == 0)))
7606 return;
7607 input=MSLResolveEntity(context,external_id,system_id);
7608 if (input == NULL)
7609 return;
7610 (void) xmlNewDtd(msl_info->document,name,external_id,system_id);
7611 parser_context=(*parser);
7612 parser->inputTab=(xmlParserInputPtr *) xmlMalloc(5*sizeof(*parser->inputTab));
7613 if (parser->inputTab == (xmlParserInputPtr *) NULL)
7614 {
7615 parser->errNo=XML_ERR_NO_MEMORY;
7616 parser->input=parser_context.input;
7617 parser->inputNr=parser_context.inputNr;
7618 parser->inputMax=parser_context.inputMax;
7619 parser->inputTab=parser_context.inputTab;
7620 return;
7621 }
7622 parser->inputNr=0;
7623 parser->inputMax=5;
7624 parser->input=NULL;
7625 xmlPushInput(parser,input);
7626 (void) xmlSwitchEncoding(parser,xmlDetectCharEncoding(parser->input->cur,4));
7627 if (input->filename == (char *) NULL)
7628 input->filename=(char *) xmlStrdup(system_id);
7629 input->line=1;
7630 input->col=1;
7631 input->base=parser->input->cur;
7632 input->cur=parser->input->cur;
7633 input->free=NULL;
7634 xmlParseExternalSubset(parser,external_id,system_id);
7635 while (parser->inputNr > 1)
7636 (void) xmlPopInput(parser);
7637 xmlFreeInputStream(parser->input);
7638 xmlFree(parser->inputTab);
7639 parser->input=parser_context.input;
7640 parser->inputNr=parser_context.inputNr;
7641 parser->inputMax=parser_context.inputMax;
7642 parser->inputTab=parser_context.inputTab;
7643}
7644
7645#if defined(__cplusplus) || defined(c_plusplus)
7646}
7647#endif
7648
7649static MagickBooleanType ProcessMSLScript(const ImageInfo *image_info,Image **image,
7650 ExceptionInfo *exception)
7651{
cristy3ed852e2009-09-05 21:47:34 +00007652 char
7653 message[MaxTextExtent];
7654
7655 Image
7656 *msl_image;
7657
7658 int
7659 status;
7660
cristybb503372010-05-27 20:51:26 +00007661 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00007662 n;
7663
7664 MSLInfo
7665 msl_info;
7666
cristy5f6f01c2009-11-19 19:36:42 +00007667 xmlSAXHandler
7668 sax_modules;
7669
cristy3ed852e2009-09-05 21:47:34 +00007670 xmlSAXHandlerPtr
cristy5f6f01c2009-11-19 19:36:42 +00007671 sax_handler;
cristy3ed852e2009-09-05 21:47:34 +00007672
7673 /*
7674 Open image file.
7675 */
7676 assert(image_info != (const ImageInfo *) NULL);
7677 assert(image_info->signature == MagickSignature);
7678 if (image_info->debug != MagickFalse)
cristy5f6f01c2009-11-19 19:36:42 +00007679 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
7680 image_info->filename);
cristy3ed852e2009-09-05 21:47:34 +00007681 assert(image != (Image **) NULL);
cristy9950d572011-10-01 18:22:35 +00007682 msl_image=AcquireImage(image_info,exception);
cristy3ed852e2009-09-05 21:47:34 +00007683 status=OpenBlob(image_info,msl_image,ReadBinaryBlobMode,exception);
7684 if (status == MagickFalse)
7685 {
7686 ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
7687 msl_image->filename);
7688 msl_image=DestroyImageList(msl_image);
7689 return(MagickFalse);
7690 }
7691 msl_image->columns=1;
7692 msl_image->rows=1;
7693 /*
7694 Parse MSL file.
7695 */
7696 (void) ResetMagickMemory(&msl_info,0,sizeof(msl_info));
7697 msl_info.exception=exception;
7698 msl_info.image_info=(ImageInfo **) AcquireMagickMemory(
7699 sizeof(*msl_info.image_info));
7700 msl_info.draw_info=(DrawInfo **) AcquireMagickMemory(
7701 sizeof(*msl_info.draw_info));
7702 /* top of the stack is the MSL file itself */
cristy73bd4a52010-10-05 11:24:23 +00007703 msl_info.image=(Image **) AcquireMagickMemory(sizeof(*msl_info.image));
cristy3ed852e2009-09-05 21:47:34 +00007704 msl_info.attributes=(Image **) AcquireMagickMemory(
7705 sizeof(*msl_info.attributes));
7706 msl_info.group_info=(MSLGroupInfo *) AcquireMagickMemory(
7707 sizeof(*msl_info.group_info));
7708 if ((msl_info.image_info == (ImageInfo **) NULL) ||
7709 (msl_info.image == (Image **) NULL) ||
7710 (msl_info.attributes == (Image **) NULL) ||
7711 (msl_info.group_info == (MSLGroupInfo *) NULL))
7712 ThrowFatalException(ResourceLimitFatalError,
7713 "UnableToInterpretMSLImage");
7714 *msl_info.image_info=CloneImageInfo(image_info);
7715 *msl_info.draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL);
cristy9950d572011-10-01 18:22:35 +00007716 *msl_info.attributes=AcquireImage(image_info,exception);
cristy3ed852e2009-09-05 21:47:34 +00007717 msl_info.group_info[0].numImages=0;
7718 /* the first slot is used to point to the MSL file image */
7719 *msl_info.image=msl_image;
7720 if (*image != (Image *) NULL)
7721 MSLPushImage(&msl_info,*image);
7722 (void) xmlSubstituteEntitiesDefault(1);
cristy5f6f01c2009-11-19 19:36:42 +00007723 (void) ResetMagickMemory(&sax_modules,0,sizeof(sax_modules));
7724 sax_modules.internalSubset=MSLInternalSubset;
7725 sax_modules.isStandalone=MSLIsStandalone;
7726 sax_modules.hasInternalSubset=MSLHasInternalSubset;
7727 sax_modules.hasExternalSubset=MSLHasExternalSubset;
7728 sax_modules.resolveEntity=MSLResolveEntity;
7729 sax_modules.getEntity=MSLGetEntity;
7730 sax_modules.entityDecl=MSLEntityDeclaration;
7731 sax_modules.notationDecl=MSLNotationDeclaration;
7732 sax_modules.attributeDecl=MSLAttributeDeclaration;
7733 sax_modules.elementDecl=MSLElementDeclaration;
7734 sax_modules.unparsedEntityDecl=MSLUnparsedEntityDeclaration;
7735 sax_modules.setDocumentLocator=MSLSetDocumentLocator;
7736 sax_modules.startDocument=MSLStartDocument;
7737 sax_modules.endDocument=MSLEndDocument;
7738 sax_modules.startElement=MSLStartElement;
7739 sax_modules.endElement=MSLEndElement;
7740 sax_modules.reference=MSLReference;
7741 sax_modules.characters=MSLCharacters;
7742 sax_modules.ignorableWhitespace=MSLIgnorableWhitespace;
7743 sax_modules.processingInstruction=MSLProcessingInstructions;
7744 sax_modules.comment=MSLComment;
7745 sax_modules.warning=MSLWarning;
7746 sax_modules.error=MSLError;
7747 sax_modules.fatalError=MSLError;
7748 sax_modules.getParameterEntity=MSLGetParameterEntity;
7749 sax_modules.cdataBlock=MSLCDataBlock;
7750 sax_modules.externalSubset=MSLExternalSubset;
7751 sax_handler=(&sax_modules);
7752 msl_info.parser=xmlCreatePushParserCtxt(sax_handler,&msl_info,(char *) NULL,0,
cristy3ed852e2009-09-05 21:47:34 +00007753 msl_image->filename);
7754 while (ReadBlobString(msl_image,message) != (char *) NULL)
7755 {
cristybb503372010-05-27 20:51:26 +00007756 n=(ssize_t) strlen(message);
cristy3ed852e2009-09-05 21:47:34 +00007757 if (n == 0)
7758 continue;
7759 status=xmlParseChunk(msl_info.parser,message,(int) n,MagickFalse);
7760 if (status != 0)
7761 break;
7762 (void) xmlParseChunk(msl_info.parser," ",1,MagickFalse);
7763 if (msl_info.exception->severity >= ErrorException)
7764 break;
7765 }
7766 if (msl_info.exception->severity == UndefinedException)
7767 (void) xmlParseChunk(msl_info.parser," ",1,MagickTrue);
7768 xmlFreeParserCtxt(msl_info.parser);
7769 (void) LogMagickEvent(CoderEvent,GetMagickModule(),"end SAX");
7770 xmlCleanupParser();
7771 msl_info.group_info=(MSLGroupInfo *) RelinquishMagickMemory(
7772 msl_info.group_info);
7773 if (*image == (Image *) NULL)
7774 *image=(*msl_info.image);
cristyc82a27b2011-10-21 01:07:16 +00007775 if (msl_info.exception->severity != UndefinedException)
cristy5f6f01c2009-11-19 19:36:42 +00007776 return(MagickFalse);
7777 return(MagickTrue);
cristy3ed852e2009-09-05 21:47:34 +00007778}
7779
7780static Image *ReadMSLImage(const ImageInfo *image_info,ExceptionInfo *exception)
7781{
7782 Image
7783 *image;
7784
7785 /*
7786 Open image file.
7787 */
7788 assert(image_info != (const ImageInfo *) NULL);
7789 assert(image_info->signature == MagickSignature);
7790 if (image_info->debug != MagickFalse)
7791 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
7792 image_info->filename);
7793 assert(exception != (ExceptionInfo *) NULL);
7794 assert(exception->signature == MagickSignature);
7795 image=(Image *) NULL;
7796 (void) ProcessMSLScript(image_info,&image,exception);
7797 return(GetFirstImageInList(image));
7798}
7799#endif
7800
7801/*
7802%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7803% %
7804% %
7805% %
7806% R e g i s t e r M S L I m a g e %
7807% %
7808% %
7809% %
7810%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7811%
7812% RegisterMSLImage() adds attributes for the MSL image format to
7813% the list of supported formats. The attributes include the image format
7814% tag, a method to read and/or write the format, whether the format
7815% supports the saving of more than one frame to the same file or blob,
7816% whether the format supports native in-memory I/O, and a brief
7817% description of the format.
7818%
7819% The format of the RegisterMSLImage method is:
7820%
cristybb503372010-05-27 20:51:26 +00007821% size_t RegisterMSLImage(void)
cristy3ed852e2009-09-05 21:47:34 +00007822%
7823*/
cristybb503372010-05-27 20:51:26 +00007824ModuleExport size_t RegisterMSLImage(void)
cristy3ed852e2009-09-05 21:47:34 +00007825{
7826 MagickInfo
7827 *entry;
7828
7829 entry=SetMagickInfo("MSL");
7830#if defined(MAGICKCORE_XML_DELEGATE)
7831 entry->decoder=(DecodeImageHandler *) ReadMSLImage;
7832 entry->encoder=(EncodeImageHandler *) WriteMSLImage;
7833#endif
7834 entry->description=ConstantString("Magick Scripting Language");
7835 entry->module=ConstantString("MSL");
7836 (void) RegisterMagickInfo(entry);
7837 return(MagickImageCoderSignature);
7838}
7839
cristy6b9f7ed2010-04-24 01:08:02 +00007840#if defined(MAGICKCORE_XML_DELEGATE)
cristy3ed852e2009-09-05 21:47:34 +00007841/*
7842%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7843% %
7844% %
7845% %
cristyb988fe72009-09-16 01:01:10 +00007846% S e t M S L A t t r i b u t e s %
7847% %
7848% %
7849% %
7850%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7851%
7852% SetMSLAttributes() ...
7853%
7854% The format of the SetMSLAttributes method is:
7855%
7856% MagickBooleanType SetMSLAttributes(MSLInfo *msl_info,
cristyb20775d2009-09-16 01:51:41 +00007857% const char *keyword,const char *value)
cristyb988fe72009-09-16 01:01:10 +00007858%
7859% A description of each parameter follows:
7860%
7861% o msl_info: the MSL info.
7862%
cristyb20775d2009-09-16 01:51:41 +00007863% o keyword: the keyword.
7864%
7865% o value: the value.
cristyb988fe72009-09-16 01:01:10 +00007866%
7867*/
cristyb20775d2009-09-16 01:51:41 +00007868static MagickBooleanType SetMSLAttributes(MSLInfo *msl_info,const char *keyword,
7869 const char *value)
cristyb988fe72009-09-16 01:01:10 +00007870{
cristy4582cbb2009-09-23 00:35:43 +00007871 Image
7872 *attributes;
7873
cristyb20775d2009-09-16 01:51:41 +00007874 DrawInfo
7875 *draw_info;
cristyb988fe72009-09-16 01:01:10 +00007876
7877 ExceptionInfo
7878 *exception;
7879
cristy4582cbb2009-09-23 00:35:43 +00007880 GeometryInfo
7881 geometry_info;
7882
cristy4fa36e42009-09-18 14:24:06 +00007883 Image
7884 *image;
7885
cristyb20775d2009-09-16 01:51:41 +00007886 ImageInfo
7887 *image_info;
7888
cristy4582cbb2009-09-23 00:35:43 +00007889 int
7890 flags;
7891
cristybb503372010-05-27 20:51:26 +00007892 ssize_t
cristyb988fe72009-09-16 01:01:10 +00007893 n;
7894
cristyb988fe72009-09-16 01:01:10 +00007895 assert(msl_info != (MSLInfo *) NULL);
cristyb20775d2009-09-16 01:51:41 +00007896 if (keyword == (const char *) NULL)
7897 return(MagickTrue);
7898 if (value == (const char *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007899 return(MagickTrue);
7900 exception=msl_info->exception;
7901 n=msl_info->n;
cristy4582cbb2009-09-23 00:35:43 +00007902 attributes=msl_info->attributes[n];
cristyb20775d2009-09-16 01:51:41 +00007903 image_info=msl_info->image_info[n];
7904 draw_info=msl_info->draw_info[n];
cristy4fa36e42009-09-18 14:24:06 +00007905 image=msl_info->image[n];
cristyb20775d2009-09-16 01:51:41 +00007906 switch (*keyword)
cristyb988fe72009-09-16 01:01:10 +00007907 {
cristyfb758a52009-09-16 14:36:08 +00007908 case 'A':
7909 case 'a':
7910 {
7911 if (LocaleCompare(keyword,"adjoin") == 0)
7912 {
cristybb503372010-05-27 20:51:26 +00007913 ssize_t
cristyfb758a52009-09-16 14:36:08 +00007914 adjoin;
7915
cristy042ee782011-04-22 18:48:30 +00007916 adjoin=ParseCommandOption(MagickBooleanOptions,MagickFalse,value);
cristyfb758a52009-09-16 14:36:08 +00007917 if (adjoin < 0)
7918 ThrowMSLException(OptionError,"UnrecognizedType",value);
7919 image_info->adjoin=(MagickBooleanType) adjoin;
7920 break;
7921 }
cristy4fa36e42009-09-18 14:24:06 +00007922 if (LocaleCompare(keyword,"alpha") == 0)
7923 {
cristybb503372010-05-27 20:51:26 +00007924 ssize_t
cristy4fa36e42009-09-18 14:24:06 +00007925 alpha;
7926
cristy042ee782011-04-22 18:48:30 +00007927 alpha=ParseCommandOption(MagickAlphaOptions,MagickFalse,value);
cristy4fa36e42009-09-18 14:24:06 +00007928 if (alpha < 0)
7929 ThrowMSLException(OptionError,"UnrecognizedType",value);
cristy4582cbb2009-09-23 00:35:43 +00007930 if (image != (Image *) NULL)
cristy63240882011-08-05 19:05:27 +00007931 (void) SetImageAlphaChannel(image,(AlphaChannelType) alpha,
7932 exception);
cristy4582cbb2009-09-23 00:35:43 +00007933 break;
7934 }
7935 if (LocaleCompare(keyword,"antialias") == 0)
7936 {
cristybb503372010-05-27 20:51:26 +00007937 ssize_t
cristy4582cbb2009-09-23 00:35:43 +00007938 antialias;
7939
cristy042ee782011-04-22 18:48:30 +00007940 antialias=ParseCommandOption(MagickBooleanOptions,MagickFalse,value);
cristy4582cbb2009-09-23 00:35:43 +00007941 if (antialias < 0)
7942 ThrowMSLException(OptionError,"UnrecognizedGravityType",value);
7943 image_info->antialias=(MagickBooleanType) antialias;
7944 break;
7945 }
7946 if (LocaleCompare(keyword,"area-limit") == 0)
7947 {
7948 MagickSizeType
7949 limit;
7950
7951 limit=MagickResourceInfinity;
7952 if (LocaleCompare(value,"unlimited") != 0)
cristydbdd0e32011-11-04 23:29:40 +00007953 limit=(MagickSizeType) StringToDoubleInterval(value,100.0);
cristy4582cbb2009-09-23 00:35:43 +00007954 (void) SetMagickResourceLimit(AreaResource,limit);
7955 break;
7956 }
7957 if (LocaleCompare(keyword,"attenuate") == 0)
7958 {
7959 (void) SetImageOption(image_info,keyword,value);
7960 break;
7961 }
7962 if (LocaleCompare(keyword,"authenticate") == 0)
7963 {
7964 (void) CloneString(&image_info->density,value);
cristy4fa36e42009-09-18 14:24:06 +00007965 break;
7966 }
cristyfb758a52009-09-16 14:36:08 +00007967 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7968 break;
7969 }
cristyb20775d2009-09-16 01:51:41 +00007970 case 'B':
7971 case 'b':
cristyb988fe72009-09-16 01:01:10 +00007972 {
cristyb20775d2009-09-16 01:51:41 +00007973 if (LocaleCompare(keyword,"background") == 0)
7974 {
cristy9950d572011-10-01 18:22:35 +00007975 (void) QueryColorCompliance(value,AllCompliance,
7976 &image_info->background_color,exception);
cristyb20775d2009-09-16 01:51:41 +00007977 break;
7978 }
cristy4582cbb2009-09-23 00:35:43 +00007979 if (LocaleCompare(keyword,"blue-primary") == 0)
7980 {
7981 if (image == (Image *) NULL)
7982 break;
7983 flags=ParseGeometry(value,&geometry_info);
7984 image->chromaticity.blue_primary.x=geometry_info.rho;
7985 image->chromaticity.blue_primary.y=geometry_info.sigma;
7986 if ((flags & SigmaValue) == 0)
7987 image->chromaticity.blue_primary.y=
7988 image->chromaticity.blue_primary.x;
7989 break;
7990 }
cristy2c8b6312009-09-16 02:37:23 +00007991 if (LocaleCompare(keyword,"bordercolor") == 0)
7992 {
cristy9950d572011-10-01 18:22:35 +00007993 (void) QueryColorCompliance(value,AllCompliance,
7994 &image_info->border_color,exception);
cristy2c8b6312009-09-16 02:37:23 +00007995 break;
7996 }
7997 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7998 break;
7999 }
8000 case 'D':
8001 case 'd':
8002 {
8003 if (LocaleCompare(keyword,"density") == 0)
8004 {
8005 (void) CloneString(&image_info->density,value);
8006 (void) CloneString(&draw_info->density,value);
8007 break;
8008 }
cristyb20775d2009-09-16 01:51:41 +00008009 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8010 break;
8011 }
8012 case 'F':
8013 case 'f':
8014 {
8015 if (LocaleCompare(keyword,"fill") == 0)
8016 {
cristy9950d572011-10-01 18:22:35 +00008017 (void) QueryColorCompliance(value,AllCompliance,&draw_info->fill,
8018 exception);
cristya30afaf2009-09-22 13:42:12 +00008019 (void) SetImageOption(image_info,keyword,value);
cristyb20775d2009-09-16 01:51:41 +00008020 break;
8021 }
cristy4582cbb2009-09-23 00:35:43 +00008022 if (LocaleCompare(keyword,"filename") == 0)
8023 {
8024 (void) CopyMagickString(image_info->filename,value,MaxTextExtent);
8025 break;
8026 }
8027 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8028 break;
8029 }
8030 case 'G':
8031 case 'g':
8032 {
8033 if (LocaleCompare(keyword,"gravity") == 0)
8034 {
cristybb503372010-05-27 20:51:26 +00008035 ssize_t
cristy4582cbb2009-09-23 00:35:43 +00008036 gravity;
8037
cristy042ee782011-04-22 18:48:30 +00008038 gravity=ParseCommandOption(MagickGravityOptions,MagickFalse,value);
cristy4582cbb2009-09-23 00:35:43 +00008039 if (gravity < 0)
8040 ThrowMSLException(OptionError,"UnrecognizedGravityType",value);
8041 (void) SetImageOption(image_info,keyword,value);
8042 break;
8043 }
cristyb20775d2009-09-16 01:51:41 +00008044 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8045 break;
8046 }
8047 case 'I':
8048 case 'i':
8049 {
8050 if (LocaleCompare(keyword,"id") == 0)
8051 {
cristyd15e6592011-10-15 00:13:06 +00008052 (void) SetImageProperty(attributes,keyword,value,exception);
cristy2c8b6312009-09-16 02:37:23 +00008053 break;
8054 }
8055 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8056 break;
8057 }
8058 case 'M':
8059 case 'm':
8060 {
8061 if (LocaleCompare(keyword,"magick") == 0)
8062 {
8063 (void) CopyMagickString(image_info->magick,value,MaxTextExtent);
8064 break;
8065 }
cristy2c8b6312009-09-16 02:37:23 +00008066 if (LocaleCompare(keyword,"mattecolor") == 0)
8067 {
cristy9950d572011-10-01 18:22:35 +00008068 (void) QueryColorCompliance(value,AllCompliance,
8069 &image_info->matte_color,exception);
cristyb20775d2009-09-16 01:51:41 +00008070 break;
8071 }
8072 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8073 break;
8074 }
8075 case 'P':
8076 case 'p':
8077 {
8078 if (LocaleCompare(keyword,"pointsize") == 0)
8079 {
cristydbdd0e32011-11-04 23:29:40 +00008080 image_info->pointsize=StringToDouble(value,(char **) NULL);
8081 draw_info->pointsize=StringToDouble(value,(char **) NULL);
cristyb20775d2009-09-16 01:51:41 +00008082 break;
8083 }
8084 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8085 break;
8086 }
cristy4582cbb2009-09-23 00:35:43 +00008087 case 'Q':
8088 case 'q':
8089 {
8090 if (LocaleCompare(keyword,"quality") == 0)
8091 {
cristyf2f27272009-12-17 14:48:46 +00008092 image_info->quality=StringToLong(value);
cristy4582cbb2009-09-23 00:35:43 +00008093 if (image == (Image *) NULL)
8094 break;
cristyf2f27272009-12-17 14:48:46 +00008095 image->quality=StringToLong(value);
cristy4582cbb2009-09-23 00:35:43 +00008096 break;
8097 }
8098 break;
8099 }
cristyb20775d2009-09-16 01:51:41 +00008100 case 'S':
8101 case 's':
8102 {
8103 if (LocaleCompare(keyword,"size") == 0)
8104 {
cristy2c8b6312009-09-16 02:37:23 +00008105 (void) CloneString(&image_info->size,value);
cristyb20775d2009-09-16 01:51:41 +00008106 break;
8107 }
8108 if (LocaleCompare(keyword,"stroke") == 0)
8109 {
cristy9950d572011-10-01 18:22:35 +00008110 (void) QueryColorCompliance(value,AllCompliance,&draw_info->stroke,
8111 exception);
cristya30afaf2009-09-22 13:42:12 +00008112 (void) SetImageOption(image_info,keyword,value);
cristyb20775d2009-09-16 01:51:41 +00008113 break;
8114 }
8115 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8116 break;
8117 }
8118 default:
8119 {
8120 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8121 break;
cristyb988fe72009-09-16 01:01:10 +00008122 }
8123 }
8124 return(MagickTrue);
8125}
cristy6b9f7ed2010-04-24 01:08:02 +00008126#endif
cristyb988fe72009-09-16 01:01:10 +00008127
8128/*
8129%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8130% %
8131% %
8132% %
cristy3ed852e2009-09-05 21:47:34 +00008133% U n r e g i s t e r M S L I m a g e %
8134% %
8135% %
8136% %
8137%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8138%
8139% UnregisterMSLImage() removes format registrations made by the
8140% MSL module from the list of supported formats.
8141%
8142% The format of the UnregisterMSLImage method is:
8143%
8144% UnregisterMSLImage(void)
8145%
8146*/
8147ModuleExport void UnregisterMSLImage(void)
8148{
8149 (void) UnregisterMagickInfo("MSL");
8150}
8151
8152#if defined(MAGICKCORE_XML_DELEGATE)
8153/*
8154%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8155% %
8156% %
8157% %
8158% W r i t e M S L I m a g e %
8159% %
8160% %
8161% %
8162%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8163%
8164% WriteMSLImage() writes an image to a file in MVG image format.
8165%
8166% The format of the WriteMSLImage method is:
8167%
cristy1e178e72011-08-28 19:44:34 +00008168% MagickBooleanType WriteMSLImage(const ImageInfo *image_info,
8169% Image *image,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00008170%
8171% A description of each parameter follows.
8172%
8173% o image_info: the image info.
8174%
8175% o image: The image.
8176%
cristy1e178e72011-08-28 19:44:34 +00008177% o exception: return any errors or warnings in this structure.
8178%
cristy3ed852e2009-09-05 21:47:34 +00008179*/
cristy1e178e72011-08-28 19:44:34 +00008180static MagickBooleanType WriteMSLImage(const ImageInfo *image_info,Image *image,
8181 ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00008182{
8183 assert(image_info != (const ImageInfo *) NULL);
8184 assert(image_info->signature == MagickSignature);
8185 assert(image != (Image *) NULL);
8186 assert(image->signature == MagickSignature);
8187 if (image->debug != MagickFalse)
8188 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
8189 (void) ReferenceImage(image);
cristy1e178e72011-08-28 19:44:34 +00008190 (void) ProcessMSLScript(image_info,&image,exception);
cristy3ed852e2009-09-05 21:47:34 +00008191 return(MagickTrue);
8192}
8193#endif