blob: 5e8f8af3054c558e89bfaa12467f6256e89a5a2a [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,
cristy05c0c9a2011-09-05 23:16:13 +00001244 geometry_info.sigma,geometry_info.xi,
cristyc82a27b2011-10-21 01:07:16 +00001245 msl_info->exception);
cristye2a912b2011-12-05 20:02:07 +00001246 (void) SetPixelChannelMapMask(msl_info->image[n],channel_mask);
cristy3ed852e2009-09-05 21:47:34 +00001247 if (blur_image == (Image *) NULL)
1248 break;
1249 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1250 msl_info->image[n]=blur_image;
1251 break;
1252 }
cristyb988fe72009-09-16 01:01:10 +00001253 if (LocaleCompare((const char *) tag,"border") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001254 {
1255 Image
1256 *border_image;
1257
1258 /*
1259 Border image.
1260 */
1261 if (msl_info->image[n] == (Image *) NULL)
1262 {
cristyb988fe72009-09-16 01:01:10 +00001263 ThrowMSLException(OptionError,"NoImagesDefined",
1264 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001265 break;
1266 }
1267 SetGeometry(msl_info->image[n],&geometry);
1268 if (attributes != (const xmlChar **) NULL)
1269 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1270 {
1271 keyword=(const char *) attributes[i++];
1272 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00001273 msl_info->attributes[n],(const char *) attributes[i],
1274 &exception);
cristy3ed852e2009-09-05 21:47:34 +00001275 CloneString(&value,attribute);
1276 switch (*keyword)
1277 {
1278 case 'C':
1279 case 'c':
1280 {
1281 if (LocaleCompare(keyword,"compose") == 0)
1282 {
cristy042ee782011-04-22 18:48:30 +00001283 option=ParseCommandOption(MagickComposeOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00001284 value);
1285 if (option < 0)
1286 ThrowMSLException(OptionError,"UnrecognizedComposeType",
1287 value);
1288 msl_info->image[n]->compose=(CompositeOperator) option;
1289 break;
1290 }
1291 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1292 keyword);
1293 break;
1294 }
1295 case 'F':
1296 case 'f':
1297 {
1298 if (LocaleCompare(keyword, "fill") == 0)
1299 {
cristy9950d572011-10-01 18:22:35 +00001300 (void) QueryColorCompliance(value,AllCompliance,
cristy3ed852e2009-09-05 21:47:34 +00001301 &msl_info->image[n]->border_color,&exception);
1302 break;
1303 }
1304 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1305 keyword);
1306 break;
1307 }
1308 case 'G':
1309 case 'g':
1310 {
1311 if (LocaleCompare(keyword,"geometry") == 0)
1312 {
1313 flags=ParsePageGeometry(msl_info->image[n],value,
1314 &geometry,&exception);
1315 if ((flags & HeightValue) == 0)
1316 geometry.height=geometry.width;
1317 break;
1318 }
1319 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1320 keyword);
1321 break;
1322 }
1323 case 'H':
1324 case 'h':
1325 {
1326 if (LocaleCompare(keyword,"height") == 0)
1327 {
cristyf2f27272009-12-17 14:48:46 +00001328 geometry.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001329 break;
1330 }
1331 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1332 keyword);
1333 break;
1334 }
1335 case 'W':
1336 case 'w':
1337 {
1338 if (LocaleCompare(keyword,"width") == 0)
1339 {
cristyf2f27272009-12-17 14:48:46 +00001340 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001341 break;
1342 }
1343 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1344 keyword);
1345 break;
1346 }
1347 default:
1348 {
1349 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1350 keyword);
1351 break;
1352 }
1353 }
1354 }
1355 border_image=BorderImage(msl_info->image[n],&geometry,
cristyc82a27b2011-10-21 01:07:16 +00001356 msl_info->image[n]->compose,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00001357 if (border_image == (Image *) NULL)
1358 break;
1359 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1360 msl_info->image[n]=border_image;
1361 break;
1362 }
1363 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
1364 }
1365 case 'C':
1366 case 'c':
1367 {
cristyb988fe72009-09-16 01:01:10 +00001368 if (LocaleCompare((const char *) tag,"colorize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001369 {
1370 char
cristyc7e6ff62011-10-03 13:46:11 +00001371 blend[MaxTextExtent];
cristy3ed852e2009-09-05 21:47:34 +00001372
1373 Image
1374 *colorize_image;
1375
cristyc7e6ff62011-10-03 13:46:11 +00001376 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00001377 target;
1378
1379 /*
1380 Add noise image.
1381 */
1382 if (msl_info->image[n] == (Image *) NULL)
1383 {
cristyb988fe72009-09-16 01:01:10 +00001384 ThrowMSLException(OptionError,"NoImagesDefined",
1385 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001386 break;
1387 }
cristyc7e6ff62011-10-03 13:46:11 +00001388 GetPixelInfo(msl_info->image[n],&target);
1389 (void) CopyMagickString(blend,"100",MaxTextExtent);
cristy3ed852e2009-09-05 21:47:34 +00001390 if (attributes != (const xmlChar **) NULL)
1391 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1392 {
1393 keyword=(const char *) attributes[i++];
1394 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00001395 msl_info->attributes[n],(const char *) attributes[i],
1396 &exception);
cristy3ed852e2009-09-05 21:47:34 +00001397 CloneString(&value,attribute);
1398 switch (*keyword)
1399 {
cristyc7e6ff62011-10-03 13:46:11 +00001400 case 'B':
1401 case 'b':
cristy3ed852e2009-09-05 21:47:34 +00001402 {
cristyc7e6ff62011-10-03 13:46:11 +00001403 if (LocaleCompare(keyword,"blend") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001404 {
cristyc7e6ff62011-10-03 13:46:11 +00001405 (void) CopyMagickString(blend,value,MaxTextExtent);
cristy3ed852e2009-09-05 21:47:34 +00001406 break;
1407 }
1408 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1409 keyword);
1410 break;
1411 }
cristyc7e6ff62011-10-03 13:46:11 +00001412 case 'F':
1413 case 'f':
cristy3ed852e2009-09-05 21:47:34 +00001414 {
cristyc7e6ff62011-10-03 13:46:11 +00001415 if (LocaleCompare(keyword,"fill") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001416 {
cristy269c9412011-10-13 23:41:15 +00001417 (void) QueryColorCompliance(value,AllCompliance,
cristyc82a27b2011-10-21 01:07:16 +00001418 &target,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00001419 break;
1420 }
1421 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1422 keyword);
1423 break;
1424 }
1425 default:
1426 {
1427 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1428 keyword);
1429 break;
1430 }
1431 }
1432 }
cristyc7e6ff62011-10-03 13:46:11 +00001433 colorize_image=ColorizeImage(msl_info->image[n],blend,&target,
cristyc82a27b2011-10-21 01:07:16 +00001434 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00001435 if (colorize_image == (Image *) NULL)
1436 break;
1437 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1438 msl_info->image[n]=colorize_image;
1439 break;
1440 }
cristyb988fe72009-09-16 01:01:10 +00001441 if (LocaleCompare((const char *) tag, "charcoal") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001442 {
cristy05c0c9a2011-09-05 23:16:13 +00001443 double bias = 0.0,
1444 radius = 0.0,
cristy3ed852e2009-09-05 21:47:34 +00001445 sigma = 1.0;
1446
1447 if (msl_info->image[n] == (Image *) NULL)
1448 {
cristyb988fe72009-09-16 01:01:10 +00001449 ThrowMSLException(OptionError,"NoImagesDefined",
1450 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001451 break;
1452 }
1453 /*
1454 NOTE: charcoal can have no attributes, since we use all the defaults!
1455 */
1456 if (attributes != (const xmlChar **) NULL)
1457 {
1458 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1459 {
1460 keyword=(const char *) attributes[i++];
1461 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00001462 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00001463 switch (*keyword)
1464 {
cristy05c0c9a2011-09-05 23:16:13 +00001465 case 'B':
1466 case 'b':
1467 {
1468 if (LocaleCompare(keyword, "bias") == 0)
cristy9b34e302011-11-05 02:15:45 +00001469 {
1470 bias=StringToDouble(value,(char **) NULL);
1471 break;
1472 }
cristy05c0c9a2011-09-05 23:16:13 +00001473 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
1474 break;
1475 }
cristy3ed852e2009-09-05 21:47:34 +00001476 case 'R':
1477 case 'r':
1478 {
cristy9b34e302011-11-05 02:15:45 +00001479 if (LocaleCompare(keyword,"radius") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001480 {
cristy9b34e302011-11-05 02:15:45 +00001481 radius=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00001482 break;
1483 }
1484 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
1485 break;
1486 }
1487 case 'S':
1488 case 's':
1489 {
1490 if (LocaleCompare(keyword,"sigma") == 0)
1491 {
cristyf2f27272009-12-17 14:48:46 +00001492 sigma = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00001493 break;
1494 }
1495 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
1496 break;
1497 }
1498 default:
1499 {
1500 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
1501 break;
1502 }
1503 }
1504 }
1505 }
1506
1507 /*
1508 charcoal image.
1509 */
1510 {
1511 Image
1512 *newImage;
1513
cristy05c0c9a2011-09-05 23:16:13 +00001514 newImage=CharcoalImage(msl_info->image[n],radius,sigma,bias,
cristyc82a27b2011-10-21 01:07:16 +00001515 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00001516 if (newImage == (Image *) NULL)
1517 break;
1518 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1519 msl_info->image[n]=newImage;
1520 break;
1521 }
1522 }
cristyb988fe72009-09-16 01:01:10 +00001523 if (LocaleCompare((const char *) tag,"chop") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001524 {
1525 Image
1526 *chop_image;
1527
1528 /*
1529 Chop image.
1530 */
1531 if (msl_info->image[n] == (Image *) NULL)
1532 {
cristyb988fe72009-09-16 01:01:10 +00001533 ThrowMSLException(OptionError,"NoImagesDefined",
1534 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001535 break;
1536 }
1537 SetGeometry(msl_info->image[n],&geometry);
1538 if (attributes != (const xmlChar **) NULL)
1539 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1540 {
1541 keyword=(const char *) attributes[i++];
1542 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00001543 msl_info->attributes[n],(const char *) attributes[i],
1544 &exception);
cristy3ed852e2009-09-05 21:47:34 +00001545 CloneString(&value,attribute);
1546 switch (*keyword)
1547 {
1548 case 'G':
1549 case 'g':
1550 {
1551 if (LocaleCompare(keyword,"geometry") == 0)
1552 {
1553 flags=ParsePageGeometry(msl_info->image[n],value,
1554 &geometry,&exception);
1555 if ((flags & HeightValue) == 0)
1556 geometry.height=geometry.width;
1557 break;
1558 }
1559 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1560 keyword);
1561 break;
1562 }
1563 case 'H':
1564 case 'h':
1565 {
1566 if (LocaleCompare(keyword,"height") == 0)
1567 {
cristyf2f27272009-12-17 14:48:46 +00001568 geometry.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001569 break;
1570 }
1571 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1572 keyword);
1573 break;
1574 }
1575 case 'W':
1576 case 'w':
1577 {
1578 if (LocaleCompare(keyword,"width") == 0)
1579 {
cristyf2f27272009-12-17 14:48:46 +00001580 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001581 break;
1582 }
1583 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1584 keyword);
1585 break;
1586 }
1587 case 'X':
1588 case 'x':
1589 {
1590 if (LocaleCompare(keyword,"x") == 0)
1591 {
cristyf2f27272009-12-17 14:48:46 +00001592 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001593 break;
1594 }
1595 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1596 keyword);
1597 break;
1598 }
1599 case 'Y':
1600 case 'y':
1601 {
1602 if (LocaleCompare(keyword,"y") == 0)
1603 {
cristyf2f27272009-12-17 14:48:46 +00001604 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001605 break;
1606 }
1607 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1608 keyword);
1609 break;
1610 }
1611 default:
1612 {
1613 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1614 keyword);
1615 break;
1616 }
1617 }
1618 }
1619 chop_image=ChopImage(msl_info->image[n],&geometry,
cristyc82a27b2011-10-21 01:07:16 +00001620 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00001621 if (chop_image == (Image *) NULL)
1622 break;
1623 msl_info->image[n]=DestroyImage(msl_info->image[n]);
1624 msl_info->image[n]=chop_image;
1625 break;
1626 }
cristyb988fe72009-09-16 01:01:10 +00001627 if (LocaleCompare((const char *) tag,"color-floodfill") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001628 {
1629 PaintMethod
1630 paint_method;
1631
cristy4c08aed2011-07-01 19:47:50 +00001632 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00001633 target;
1634
1635 /*
1636 Color floodfill image.
1637 */
1638 if (msl_info->image[n] == (Image *) NULL)
1639 {
cristyb988fe72009-09-16 01:01:10 +00001640 ThrowMSLException(OptionError,"NoImagesDefined",
1641 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001642 break;
1643 }
1644 draw_info=CloneDrawInfo(msl_info->image_info[n],
1645 msl_info->draw_info[n]);
1646 SetGeometry(msl_info->image[n],&geometry);
1647 paint_method=FloodfillMethod;
1648 if (attributes != (const xmlChar **) NULL)
1649 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1650 {
1651 keyword=(const char *) attributes[i++];
1652 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00001653 msl_info->attributes[n],(const char *) attributes[i],
1654 &exception);
cristy3ed852e2009-09-05 21:47:34 +00001655 CloneString(&value,attribute);
1656 switch (*keyword)
1657 {
1658 case 'B':
1659 case 'b':
1660 {
1661 if (LocaleCompare(keyword,"bordercolor") == 0)
1662 {
cristy269c9412011-10-13 23:41:15 +00001663 (void) QueryColorCompliance(value,AllCompliance,
cristy9950d572011-10-01 18:22:35 +00001664 &target,&exception);
cristy3ed852e2009-09-05 21:47:34 +00001665 paint_method=FillToBorderMethod;
1666 break;
1667 }
1668 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1669 keyword);
1670 break;
1671 }
1672 case 'F':
1673 case 'f':
1674 {
1675 if (LocaleCompare(keyword,"fill") == 0)
1676 {
cristy9950d572011-10-01 18:22:35 +00001677 (void) QueryColorCompliance(value,AllCompliance,
1678 &draw_info->fill,&exception);
cristy3ed852e2009-09-05 21:47:34 +00001679 break;
1680 }
1681 if (LocaleCompare(keyword,"fuzz") == 0)
1682 {
cristydbdd0e32011-11-04 23:29:40 +00001683 msl_info->image[n]->fuzz=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00001684 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00001685 break;
1686 }
1687 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1688 keyword);
1689 break;
1690 }
1691 case 'G':
1692 case 'g':
1693 {
1694 if (LocaleCompare(keyword,"geometry") == 0)
1695 {
1696 flags=ParsePageGeometry(msl_info->image[n],value,
1697 &geometry,&exception);
1698 if ((flags & HeightValue) == 0)
1699 geometry.height=geometry.width;
cristy3aa93752011-12-18 15:54:24 +00001700 (void) GetOneVirtualPixelInfo(msl_info->image[n],
cristy33e9da62011-10-21 19:08:58 +00001701 TileVirtualPixelMethod,geometry.x,geometry.y,&target,
1702 &exception);
cristy3ed852e2009-09-05 21:47:34 +00001703 break;
1704 }
1705 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1706 keyword);
1707 break;
1708 }
1709 case 'X':
1710 case 'x':
1711 {
1712 if (LocaleCompare(keyword,"x") == 0)
1713 {
cristyf2f27272009-12-17 14:48:46 +00001714 geometry.x=StringToLong(value);
cristy3aa93752011-12-18 15:54:24 +00001715 (void) GetOneVirtualPixelInfo(msl_info->image[n],
cristy33e9da62011-10-21 19:08:58 +00001716 TileVirtualPixelMethod,geometry.x,geometry.y,&target,
1717 &exception);
cristy3ed852e2009-09-05 21:47:34 +00001718 break;
1719 }
1720 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1721 keyword);
1722 break;
1723 }
1724 case 'Y':
1725 case 'y':
1726 {
1727 if (LocaleCompare(keyword,"y") == 0)
1728 {
cristyf2f27272009-12-17 14:48:46 +00001729 geometry.y=StringToLong(value);
cristy3aa93752011-12-18 15:54:24 +00001730 (void) GetOneVirtualPixelInfo(msl_info->image[n],
cristy33e9da62011-10-21 19:08:58 +00001731 TileVirtualPixelMethod,geometry.x,geometry.y,&target,
1732 &exception);
cristy3ed852e2009-09-05 21:47:34 +00001733 break;
1734 }
1735 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1736 keyword);
1737 break;
1738 }
1739 default:
1740 {
1741 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1742 keyword);
1743 break;
1744 }
1745 }
1746 }
cristyd42d9952011-07-08 14:21:50 +00001747 (void) FloodfillPaintImage(msl_info->image[n],draw_info,&target,
1748 geometry.x,geometry.y,paint_method == FloodfillMethod ?
cristyc82a27b2011-10-21 01:07:16 +00001749 MagickFalse : MagickTrue,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00001750 draw_info=DestroyDrawInfo(draw_info);
1751 break;
1752 }
cristyb988fe72009-09-16 01:01:10 +00001753 if (LocaleCompare((const char *) tag,"comment") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001754 break;
cristyb988fe72009-09-16 01:01:10 +00001755 if (LocaleCompare((const char *) tag,"composite") == 0)
cristy3ed852e2009-09-05 21:47:34 +00001756 {
1757 char
1758 composite_geometry[MaxTextExtent];
1759
1760 CompositeOperator
1761 compose;
1762
1763 Image
1764 *composite_image,
1765 *rotate_image;
1766
cristy3ed852e2009-09-05 21:47:34 +00001767 /*
1768 Composite image.
1769 */
1770 if (msl_info->image[n] == (Image *) NULL)
1771 {
cristyb988fe72009-09-16 01:01:10 +00001772 ThrowMSLException(OptionError,"NoImagesDefined",
1773 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00001774 break;
1775 }
1776 composite_image=NewImageList();
1777 compose=OverCompositeOp;
1778 if (attributes != (const xmlChar **) NULL)
1779 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1780 {
1781 keyword=(const char *) attributes[i++];
1782 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00001783 msl_info->attributes[n],(const char *) attributes[i],
1784 &exception);
cristy3ed852e2009-09-05 21:47:34 +00001785 CloneString(&value,attribute);
1786 switch (*keyword)
1787 {
1788 case 'C':
1789 case 'c':
1790 {
1791 if (LocaleCompare(keyword,"compose") == 0)
1792 {
cristy2ed42f62011-10-02 19:49:57 +00001793 option=ParseCommandOption(MagickComposeOptions,
1794 MagickFalse,value);
cristy3ed852e2009-09-05 21:47:34 +00001795 if (option < 0)
1796 ThrowMSLException(OptionError,"UnrecognizedComposeType",
1797 value);
1798 compose=(CompositeOperator) option;
1799 break;
1800 }
1801 break;
1802 }
1803 case 'I':
1804 case 'i':
1805 {
1806 if (LocaleCompare(keyword,"image") == 0)
1807 for (j=0; j < msl_info->n; j++)
1808 {
1809 const char
1810 *attribute;
cristyb988fe72009-09-16 01:01:10 +00001811
cristyd15e6592011-10-15 00:13:06 +00001812 attribute=GetImageProperty(msl_info->attributes[j],"id",
1813 &exception);
cristy3ed852e2009-09-05 21:47:34 +00001814 if ((attribute != (const char *) NULL) &&
1815 (LocaleCompare(attribute,value) == 0))
1816 {
1817 composite_image=CloneImage(msl_info->image[j],0,0,
1818 MagickFalse,&exception);
1819 break;
1820 }
1821 }
1822 break;
1823 }
1824 default:
1825 break;
1826 }
1827 }
1828 if (composite_image == (Image *) NULL)
1829 break;
1830 rotate_image=NewImageList();
1831 SetGeometry(msl_info->image[n],&geometry);
1832 if (attributes != (const xmlChar **) NULL)
1833 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
1834 {
1835 keyword=(const char *) attributes[i++];
1836 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00001837 msl_info->attributes[n],(const char *) attributes[i],
1838 &exception);
cristy3ed852e2009-09-05 21:47:34 +00001839 CloneString(&value,attribute);
1840 switch (*keyword)
1841 {
1842 case 'B':
1843 case 'b':
1844 {
1845 if (LocaleCompare(keyword,"blend") == 0)
1846 {
1847 (void) SetImageArtifact(composite_image,
1848 "compose:args",value);
1849 break;
1850 }
1851 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1852 keyword);
1853 break;
1854 }
1855 case 'C':
1856 case 'c':
1857 {
1858 if (LocaleCompare(keyword,"channel") == 0)
1859 {
1860 option=ParseChannelOption(value);
1861 if (option < 0)
1862 ThrowMSLException(OptionError,"UnrecognizedChannelType",
1863 value);
1864 channel=(ChannelType) option;
1865 break;
1866 }
1867 if (LocaleCompare(keyword, "color") == 0)
1868 {
cristy9950d572011-10-01 18:22:35 +00001869 (void) QueryColorCompliance(value,AllCompliance,
cristy3ed852e2009-09-05 21:47:34 +00001870 &composite_image->background_color,&exception);
1871 break;
1872 }
1873 if (LocaleCompare(keyword,"compose") == 0)
1874 break;
1875 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1876 keyword);
1877 break;
1878 }
1879 case 'G':
1880 case 'g':
1881 {
1882 if (LocaleCompare(keyword,"geometry") == 0)
1883 {
1884 flags=ParsePageGeometry(msl_info->image[n],value,
1885 &geometry,&exception);
1886 if ((flags & HeightValue) == 0)
1887 geometry.height=geometry.width;
cristy3ed852e2009-09-05 21:47:34 +00001888 break;
1889 }
1890 if (LocaleCompare(keyword,"gravity") == 0)
1891 {
cristy2ed42f62011-10-02 19:49:57 +00001892 option=ParseCommandOption(MagickGravityOptions,
1893 MagickFalse,value);
cristy3ed852e2009-09-05 21:47:34 +00001894 if (option < 0)
1895 ThrowMSLException(OptionError,"UnrecognizedGravityType",
1896 value);
1897 msl_info->image[n]->gravity=(GravityType) option;
1898 break;
1899 }
1900 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1901 keyword);
1902 break;
1903 }
1904 case 'I':
1905 case 'i':
1906 {
1907 if (LocaleCompare(keyword,"image") == 0)
1908 break;
1909 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1910 keyword);
1911 break;
1912 }
1913 case 'M':
1914 case 'm':
1915 {
1916 if (LocaleCompare(keyword,"mask") == 0)
1917 for (j=0; j < msl_info->n; j++)
1918 {
1919 const char
1920 *attribute;
1921
cristyd15e6592011-10-15 00:13:06 +00001922 attribute=GetImageProperty(msl_info->attributes[j],"id",
1923 &exception);
cristy3ed852e2009-09-05 21:47:34 +00001924 if ((attribute != (const char *) NULL) &&
1925 (LocaleCompare(value,value) == 0))
1926 {
cristy018f07f2011-09-04 21:15:19 +00001927 SetImageType(composite_image,TrueColorMatteType,
1928 &exception);
cristy3ed852e2009-09-05 21:47:34 +00001929 (void) CompositeImage(composite_image,
cristye4a40472011-12-22 02:56:19 +00001930 CopyAlphaCompositeOp,msl_info->image[j],0,0,
cristye941a752011-10-15 01:52:48 +00001931 &exception);
cristy3ed852e2009-09-05 21:47:34 +00001932 break;
1933 }
1934 }
1935 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1936 keyword);
1937 break;
1938 }
1939 case 'O':
1940 case 'o':
1941 {
1942 if (LocaleCompare(keyword,"opacity") == 0)
1943 {
cristybb503372010-05-27 20:51:26 +00001944 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001945 opacity,
1946 y;
cristyb988fe72009-09-16 01:01:10 +00001947
cristybb503372010-05-27 20:51:26 +00001948 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001949 x;
cristyb988fe72009-09-16 01:01:10 +00001950
cristy4c08aed2011-07-01 19:47:50 +00001951 register Quantum
cristy3ed852e2009-09-05 21:47:34 +00001952 *q;
cristyb988fe72009-09-16 01:01:10 +00001953
cristy3ed852e2009-09-05 21:47:34 +00001954 CacheView
1955 *composite_view;
1956
cristy4c08aed2011-07-01 19:47:50 +00001957 opacity=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00001958 if (compose != DissolveCompositeOp)
1959 {
cristyb6a294d2011-10-03 00:55:17 +00001960 (void) SetImageAlpha(composite_image,(Quantum)
cristye941a752011-10-15 01:52:48 +00001961 opacity,&exception);
cristy3ed852e2009-09-05 21:47:34 +00001962 break;
1963 }
1964 (void) SetImageArtifact(msl_info->image[n],
1965 "compose:args",value);
1966 if (composite_image->matte != MagickTrue)
cristye941a752011-10-15 01:52:48 +00001967 (void) SetImageAlpha(composite_image,OpaqueAlpha,
1968 &exception);
cristy3ed852e2009-09-05 21:47:34 +00001969 composite_view=AcquireCacheView(composite_image);
cristybb503372010-05-27 20:51:26 +00001970 for (y=0; y < (ssize_t) composite_image->rows ; y++)
cristyb988fe72009-09-16 01:01:10 +00001971 {
cristy4c08aed2011-07-01 19:47:50 +00001972 q=GetCacheViewAuthenticPixels(composite_view,0,y,
1973 (ssize_t) composite_image->columns,1,&exception);
cristybb503372010-05-27 20:51:26 +00001974 for (x=0; x < (ssize_t) composite_image->columns; x++)
cristyb988fe72009-09-16 01:01:10 +00001975 {
cristy4c08aed2011-07-01 19:47:50 +00001976 if (GetPixelAlpha(composite_image,q) == OpaqueAlpha)
1977 SetPixelAlpha(composite_image,
1978 ClampToQuantum(opacity),q);
cristyed231572011-07-14 02:18:59 +00001979 q+=GetPixelChannels(composite_image);
cristy3ed852e2009-09-05 21:47:34 +00001980 }
1981 if (SyncCacheViewAuthenticPixels(composite_view,&exception) == MagickFalse)
1982 break;
1983 }
1984 composite_view=DestroyCacheView(composite_view);
1985 break;
1986 }
1987 ThrowMSLException(OptionError,"UnrecognizedAttribute",
1988 keyword);
1989 break;
1990 }
1991 case 'R':
1992 case 'r':
1993 {
1994 if (LocaleCompare(keyword,"rotate") == 0)
1995 {
cristyc1acd842011-05-19 23:05:47 +00001996 rotate_image=RotateImage(composite_image,
cristydbdd0e32011-11-04 23:29:40 +00001997 StringToDouble(value,(char **) NULL),&exception);
cristy3ed852e2009-09-05 21:47:34 +00001998 break;
1999 }
2000 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2001 keyword);
2002 break;
2003 }
2004 case 'T':
2005 case 't':
2006 {
2007 if (LocaleCompare(keyword,"tile") == 0)
2008 {
2009 MagickBooleanType
2010 tile;
2011
cristy042ee782011-04-22 18:48:30 +00002012 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002013 value);
2014 if (option < 0)
2015 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
2016 value);
2017 tile=(MagickBooleanType) option;
cristyda16f162011-02-19 23:52:17 +00002018 (void) tile;
cristy3ed852e2009-09-05 21:47:34 +00002019 if (rotate_image != (Image *) NULL)
2020 (void) SetImageArtifact(rotate_image,
2021 "compose:outside-overlay","false");
2022 else
2023 (void) SetImageArtifact(composite_image,
2024 "compose:outside-overlay","false");
2025 image=msl_info->image[n];
2026 height=composite_image->rows;
2027 width=composite_image->columns;
cristyeaedf062010-05-29 22:36:02 +00002028 for (y=0; y < (ssize_t) image->rows; y+=(ssize_t) height)
2029 for (x=0; x < (ssize_t) image->columns; x+=(ssize_t) width)
cristy3ed852e2009-09-05 21:47:34 +00002030 {
2031 if (rotate_image != (Image *) NULL)
2032 (void) CompositeImage(image,compose,rotate_image,
cristye941a752011-10-15 01:52:48 +00002033 x,y,&exception);
cristy3ed852e2009-09-05 21:47:34 +00002034 else
2035 (void) CompositeImage(image,compose,
cristye941a752011-10-15 01:52:48 +00002036 composite_image,x,y,&exception);
cristy3ed852e2009-09-05 21:47:34 +00002037 }
2038 if (rotate_image != (Image *) NULL)
2039 rotate_image=DestroyImage(rotate_image);
2040 break;
2041 }
2042 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2043 keyword);
2044 break;
2045 }
2046 case 'X':
2047 case 'x':
2048 {
2049 if (LocaleCompare(keyword,"x") == 0)
2050 {
cristyf2f27272009-12-17 14:48:46 +00002051 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002052 break;
2053 }
2054 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2055 keyword);
2056 break;
2057 }
2058 case 'Y':
2059 case 'y':
2060 {
2061 if (LocaleCompare(keyword,"y") == 0)
2062 {
cristyf2f27272009-12-17 14:48:46 +00002063 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002064 break;
2065 }
2066 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2067 keyword);
2068 break;
2069 }
2070 default:
2071 {
2072 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2073 keyword);
2074 break;
2075 }
2076 }
2077 }
2078 image=msl_info->image[n];
cristyb51dff52011-05-19 16:55:47 +00002079 (void) FormatLocaleString(composite_geometry,MaxTextExtent,
cristye8c25f92010-06-03 00:53:06 +00002080 "%.20gx%.20g%+.20g%+.20g",(double) composite_image->columns,
2081 (double) composite_image->rows,(double) geometry.x,(double)
cristyf2faecf2010-05-28 19:19:36 +00002082 geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00002083 flags=ParseGravityGeometry(image,composite_geometry,&geometry,
2084 &exception);
cristybd5a96c2011-08-21 00:04:26 +00002085 channel_mask=SetPixelChannelMask(image,channel);
cristy3ed852e2009-09-05 21:47:34 +00002086 if (rotate_image == (Image *) NULL)
cristye941a752011-10-15 01:52:48 +00002087 CompositeImage(image,compose,composite_image,geometry.x,geometry.y,
2088 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002089 else
2090 {
2091 /*
2092 Rotate image.
2093 */
cristybb503372010-05-27 20:51:26 +00002094 geometry.x-=(ssize_t) (rotate_image->columns-
cristy3ed852e2009-09-05 21:47:34 +00002095 composite_image->columns)/2;
cristy2ed42f62011-10-02 19:49:57 +00002096 geometry.y-=(ssize_t) (rotate_image->rows-
2097 composite_image->rows)/2;
cristye941a752011-10-15 01:52:48 +00002098 CompositeImage(image,compose,rotate_image,geometry.x,geometry.y,
2099 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002100 rotate_image=DestroyImage(rotate_image);
2101 }
cristybd5a96c2011-08-21 00:04:26 +00002102 (void) SetPixelChannelMask(image,channel_mask);
cristy3ed852e2009-09-05 21:47:34 +00002103 composite_image=DestroyImage(composite_image);
2104 break;
2105 }
cristyb988fe72009-09-16 01:01:10 +00002106 if (LocaleCompare((const char *) tag,"contrast") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002107 {
2108 MagickBooleanType
2109 sharpen;
2110
2111 /*
2112 Contrast image.
2113 */
2114 if (msl_info->image[n] == (Image *) NULL)
2115 {
cristyb988fe72009-09-16 01:01:10 +00002116 ThrowMSLException(OptionError,"NoImagesDefined",
2117 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002118 break;
2119 }
2120 sharpen=MagickFalse;
2121 if (attributes != (const xmlChar **) NULL)
2122 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2123 {
2124 keyword=(const char *) attributes[i++];
2125 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002126 msl_info->attributes[n],(const char *) attributes[i],
2127 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002128 CloneString(&value,attribute);
2129 switch (*keyword)
2130 {
2131 case 'S':
2132 case 's':
2133 {
2134 if (LocaleCompare(keyword,"sharpen") == 0)
2135 {
cristy042ee782011-04-22 18:48:30 +00002136 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002137 value);
2138 if (option < 0)
2139 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
2140 value);
2141 sharpen=(MagickBooleanType) option;
2142 break;
2143 }
2144 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2145 keyword);
2146 break;
2147 }
2148 default:
2149 {
2150 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2151 keyword);
2152 break;
2153 }
2154 }
2155 }
cristye23ec9d2011-08-16 18:15:40 +00002156 (void) ContrastImage(msl_info->image[n],sharpen,
cristyc82a27b2011-10-21 01:07:16 +00002157 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00002158 break;
2159 }
cristyb988fe72009-09-16 01:01:10 +00002160 if (LocaleCompare((const char *) tag,"crop") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002161 {
2162 Image
2163 *crop_image;
2164
2165 /*
2166 Crop image.
2167 */
2168 if (msl_info->image[n] == (Image *) NULL)
2169 {
cristyb988fe72009-09-16 01:01:10 +00002170 ThrowMSLException(OptionError,"NoImagesDefined",
2171 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002172 break;
2173 }
2174 SetGeometry(msl_info->image[n],&geometry);
2175 if (attributes != (const xmlChar **) NULL)
2176 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2177 {
2178 keyword=(const char *) attributes[i++];
2179 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002180 msl_info->attributes[n],(const char *) attributes[i],
2181 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002182 CloneString(&value,attribute);
2183 switch (*keyword)
2184 {
2185 case 'G':
2186 case 'g':
2187 {
2188 if (LocaleCompare(keyword,"geometry") == 0)
2189 {
cristy860f4e12011-07-28 19:00:28 +00002190 flags=ParseGravityGeometry(msl_info->image[n],value,
cristy3ed852e2009-09-05 21:47:34 +00002191 &geometry,&exception);
cristy3ed852e2009-09-05 21:47:34 +00002192 break;
2193 }
2194 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2195 keyword);
2196 break;
2197 }
2198 case 'H':
2199 case 'h':
2200 {
2201 if (LocaleCompare(keyword,"height") == 0)
2202 {
cristyf2f27272009-12-17 14:48:46 +00002203 geometry.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002204 break;
2205 }
2206 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2207 keyword);
2208 break;
2209 }
2210 case 'W':
2211 case 'w':
2212 {
2213 if (LocaleCompare(keyword,"width") == 0)
2214 {
cristyf2f27272009-12-17 14:48:46 +00002215 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002216 break;
2217 }
2218 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2219 keyword);
2220 break;
2221 }
2222 case 'X':
2223 case 'x':
2224 {
2225 if (LocaleCompare(keyword,"x") == 0)
2226 {
cristyf2f27272009-12-17 14:48:46 +00002227 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002228 break;
2229 }
2230 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2231 keyword);
2232 break;
2233 }
2234 case 'Y':
2235 case 'y':
2236 {
2237 if (LocaleCompare(keyword,"y") == 0)
2238 {
cristyf2f27272009-12-17 14:48:46 +00002239 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002240 break;
2241 }
2242 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2243 keyword);
2244 break;
2245 }
2246 default:
2247 {
2248 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2249 keyword);
2250 break;
2251 }
2252 }
2253 }
2254 crop_image=CropImage(msl_info->image[n],&geometry,
cristyc82a27b2011-10-21 01:07:16 +00002255 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00002256 if (crop_image == (Image *) NULL)
2257 break;
2258 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2259 msl_info->image[n]=crop_image;
2260 break;
2261 }
cristyb988fe72009-09-16 01:01:10 +00002262 if (LocaleCompare((const char *) tag,"cycle-colormap") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002263 {
cristybb503372010-05-27 20:51:26 +00002264 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002265 display;
2266
2267 /*
2268 Cycle-colormap image.
2269 */
2270 if (msl_info->image[n] == (Image *) NULL)
2271 {
cristyb988fe72009-09-16 01:01:10 +00002272 ThrowMSLException(OptionError,"NoImagesDefined",
2273 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002274 break;
2275 }
2276 display=0;
2277 if (attributes != (const xmlChar **) NULL)
2278 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2279 {
2280 keyword=(const char *) attributes[i++];
2281 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002282 msl_info->attributes[n],(const char *) attributes[i],
2283 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002284 CloneString(&value,attribute);
2285 switch (*keyword)
2286 {
2287 case 'D':
2288 case 'd':
2289 {
2290 if (LocaleCompare(keyword,"display") == 0)
2291 {
cristyf2f27272009-12-17 14:48:46 +00002292 display=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002293 break;
2294 }
2295 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2296 keyword);
2297 break;
2298 }
2299 default:
2300 {
2301 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2302 keyword);
2303 break;
2304 }
2305 }
2306 }
cristy018f07f2011-09-04 21:15:19 +00002307 (void) CycleColormapImage(msl_info->image[n],display,&exception);
cristy3ed852e2009-09-05 21:47:34 +00002308 break;
2309 }
2310 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
2311 }
2312 case 'D':
2313 case 'd':
2314 {
cristyb988fe72009-09-16 01:01:10 +00002315 if (LocaleCompare((const char *) tag,"despeckle") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002316 {
2317 Image
2318 *despeckle_image;
2319
2320 /*
2321 Despeckle image.
2322 */
2323 if (msl_info->image[n] == (Image *) NULL)
2324 {
cristyb988fe72009-09-16 01:01:10 +00002325 ThrowMSLException(OptionError,"NoImagesDefined",
2326 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002327 break;
2328 }
2329 if (attributes != (const xmlChar **) NULL)
2330 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2331 {
2332 keyword=(const char *) attributes[i++];
2333 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002334 msl_info->attributes[n],(const char *) attributes[i],
2335 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002336 CloneString(&value,attribute);
2337 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
2338 }
2339 despeckle_image=DespeckleImage(msl_info->image[n],
cristyc82a27b2011-10-21 01:07:16 +00002340 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00002341 if (despeckle_image == (Image *) NULL)
2342 break;
2343 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2344 msl_info->image[n]=despeckle_image;
2345 break;
2346 }
cristyb988fe72009-09-16 01:01:10 +00002347 if (LocaleCompare((const char *) tag,"display") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002348 {
2349 if (msl_info->image[n] == (Image *) NULL)
2350 {
cristyb988fe72009-09-16 01:01:10 +00002351 ThrowMSLException(OptionError,"NoImagesDefined",
2352 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002353 break;
2354 }
2355 if (attributes != (const xmlChar **) NULL)
2356 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2357 {
2358 keyword=(const char *) attributes[i++];
2359 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002360 msl_info->attributes[n],(const char *) attributes[i],
2361 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002362 CloneString(&value,attribute);
2363 switch (*keyword)
2364 {
2365 default:
2366 {
2367 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2368 keyword);
2369 break;
2370 }
2371 }
2372 }
cristy051718b2011-08-28 22:49:25 +00002373 (void) DisplayImages(msl_info->image_info[n],msl_info->image[n],
cristyc82a27b2011-10-21 01:07:16 +00002374 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00002375 break;
2376 }
cristyb988fe72009-09-16 01:01:10 +00002377 if (LocaleCompare((const char *) tag,"draw") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002378 {
2379 char
2380 text[MaxTextExtent];
2381
2382 /*
2383 Annotate image.
2384 */
2385 if (msl_info->image[n] == (Image *) NULL)
2386 {
cristyb988fe72009-09-16 01:01:10 +00002387 ThrowMSLException(OptionError,"NoImagesDefined",
2388 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002389 break;
2390 }
2391 draw_info=CloneDrawInfo(msl_info->image_info[n],
2392 msl_info->draw_info[n]);
2393 angle=0.0;
2394 current=draw_info->affine;
2395 GetAffineMatrix(&affine);
2396 if (attributes != (const xmlChar **) NULL)
2397 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2398 {
2399 keyword=(const char *) attributes[i++];
2400 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002401 msl_info->attributes[n],(const char *) attributes[i],
2402 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002403 CloneString(&value,attribute);
2404 switch (*keyword)
2405 {
2406 case 'A':
2407 case 'a':
2408 {
2409 if (LocaleCompare(keyword,"affine") == 0)
2410 {
2411 char
2412 *p;
2413
2414 p=value;
cristydbdd0e32011-11-04 23:29:40 +00002415 draw_info->affine.sx=StringToDouble(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00002416 if (*p ==',')
2417 p++;
cristydbdd0e32011-11-04 23:29:40 +00002418 draw_info->affine.rx=StringToDouble(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00002419 if (*p ==',')
2420 p++;
cristydbdd0e32011-11-04 23:29:40 +00002421 draw_info->affine.ry=StringToDouble(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00002422 if (*p ==',')
2423 p++;
cristydbdd0e32011-11-04 23:29:40 +00002424 draw_info->affine.sy=StringToDouble(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00002425 if (*p ==',')
2426 p++;
cristydbdd0e32011-11-04 23:29:40 +00002427 draw_info->affine.tx=StringToDouble(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00002428 if (*p ==',')
2429 p++;
cristydbdd0e32011-11-04 23:29:40 +00002430 draw_info->affine.ty=StringToDouble(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00002431 break;
2432 }
2433 if (LocaleCompare(keyword,"align") == 0)
2434 {
cristy042ee782011-04-22 18:48:30 +00002435 option=ParseCommandOption(MagickAlignOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002436 value);
2437 if (option < 0)
2438 ThrowMSLException(OptionError,"UnrecognizedAlignType",
2439 value);
2440 draw_info->align=(AlignType) option;
2441 break;
2442 }
2443 if (LocaleCompare(keyword,"antialias") == 0)
2444 {
cristy042ee782011-04-22 18:48:30 +00002445 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002446 value);
2447 if (option < 0)
2448 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
2449 value);
2450 draw_info->stroke_antialias=(MagickBooleanType) option;
2451 draw_info->text_antialias=(MagickBooleanType) option;
2452 break;
2453 }
2454 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2455 keyword);
2456 break;
2457 }
2458 case 'D':
2459 case 'd':
2460 {
2461 if (LocaleCompare(keyword,"density") == 0)
2462 {
2463 CloneString(&draw_info->density,value);
2464 break;
2465 }
2466 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2467 keyword);
2468 break;
2469 }
2470 case 'E':
2471 case 'e':
2472 {
2473 if (LocaleCompare(keyword,"encoding") == 0)
2474 {
2475 CloneString(&draw_info->encoding,value);
2476 break;
2477 }
2478 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2479 keyword);
2480 break;
2481 }
2482 case 'F':
2483 case 'f':
2484 {
2485 if (LocaleCompare(keyword, "fill") == 0)
2486 {
cristy9950d572011-10-01 18:22:35 +00002487 (void) QueryColorCompliance(value,AllCompliance,
2488 &draw_info->fill,&exception);
cristy3ed852e2009-09-05 21:47:34 +00002489 break;
2490 }
2491 if (LocaleCompare(keyword,"family") == 0)
2492 {
2493 CloneString(&draw_info->family,value);
2494 break;
2495 }
2496 if (LocaleCompare(keyword,"font") == 0)
2497 {
2498 CloneString(&draw_info->font,value);
2499 break;
2500 }
2501 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2502 keyword);
2503 break;
2504 }
2505 case 'G':
2506 case 'g':
2507 {
2508 if (LocaleCompare(keyword,"geometry") == 0)
2509 {
2510 flags=ParsePageGeometry(msl_info->image[n],value,
2511 &geometry,&exception);
2512 if ((flags & HeightValue) == 0)
2513 geometry.height=geometry.width;
2514 break;
2515 }
2516 if (LocaleCompare(keyword,"gravity") == 0)
2517 {
cristy042ee782011-04-22 18:48:30 +00002518 option=ParseCommandOption(MagickGravityOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002519 value);
2520 if (option < 0)
2521 ThrowMSLException(OptionError,"UnrecognizedGravityType",
2522 value);
2523 draw_info->gravity=(GravityType) option;
2524 break;
2525 }
2526 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2527 keyword);
2528 break;
2529 }
2530 case 'P':
2531 case 'p':
2532 {
2533 if (LocaleCompare(keyword,"primitive") == 0)
cristyb988fe72009-09-16 01:01:10 +00002534 {
cristy3ed852e2009-09-05 21:47:34 +00002535 CloneString(&draw_info->primitive,value);
2536 break;
2537 }
2538 if (LocaleCompare(keyword,"pointsize") == 0)
2539 {
cristydbdd0e32011-11-04 23:29:40 +00002540 draw_info->pointsize=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00002541 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002542 break;
2543 }
2544 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2545 keyword);
2546 break;
2547 }
2548 case 'R':
2549 case 'r':
2550 {
2551 if (LocaleCompare(keyword,"rotate") == 0)
2552 {
cristydbdd0e32011-11-04 23:29:40 +00002553 angle=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002554 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
2555 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
2556 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
2557 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
2558 break;
2559 }
2560 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2561 keyword);
2562 break;
2563 }
2564 case 'S':
2565 case 's':
2566 {
2567 if (LocaleCompare(keyword,"scale") == 0)
2568 {
2569 flags=ParseGeometry(value,&geometry_info);
2570 if ((flags & SigmaValue) == 0)
2571 geometry_info.sigma=1.0;
2572 affine.sx=geometry_info.rho;
2573 affine.sy=geometry_info.sigma;
2574 break;
2575 }
2576 if (LocaleCompare(keyword,"skewX") == 0)
2577 {
cristydbdd0e32011-11-04 23:29:40 +00002578 angle=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002579 affine.ry=cos(DegreesToRadians(fmod(angle,360.0)));
2580 break;
2581 }
2582 if (LocaleCompare(keyword,"skewY") == 0)
2583 {
cristydbdd0e32011-11-04 23:29:40 +00002584 angle=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002585 affine.rx=cos(DegreesToRadians(fmod(angle,360.0)));
2586 break;
2587 }
2588 if (LocaleCompare(keyword,"stretch") == 0)
2589 {
cristy9950d572011-10-01 18:22:35 +00002590 option=ParseCommandOption(MagickStretchOptions,
2591 MagickFalse,value);
cristy3ed852e2009-09-05 21:47:34 +00002592 if (option < 0)
2593 ThrowMSLException(OptionError,"UnrecognizedStretchType",
2594 value);
2595 draw_info->stretch=(StretchType) option;
2596 break;
2597 }
2598 if (LocaleCompare(keyword, "stroke") == 0)
2599 {
cristy9950d572011-10-01 18:22:35 +00002600 (void) QueryColorCompliance(value,AllCompliance,
2601 &draw_info->stroke,&exception);
cristy3ed852e2009-09-05 21:47:34 +00002602 break;
2603 }
2604 if (LocaleCompare(keyword,"strokewidth") == 0)
2605 {
cristyf2f27272009-12-17 14:48:46 +00002606 draw_info->stroke_width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002607 break;
2608 }
2609 if (LocaleCompare(keyword,"style") == 0)
2610 {
cristy042ee782011-04-22 18:48:30 +00002611 option=ParseCommandOption(MagickStyleOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002612 value);
2613 if (option < 0)
2614 ThrowMSLException(OptionError,"UnrecognizedStyleType",
2615 value);
2616 draw_info->style=(StyleType) option;
2617 break;
2618 }
2619 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2620 keyword);
2621 break;
2622 }
2623 case 'T':
2624 case 't':
2625 {
2626 if (LocaleCompare(keyword,"text") == 0)
2627 {
2628 CloneString(&draw_info->text,value);
2629 break;
2630 }
2631 if (LocaleCompare(keyword,"translate") == 0)
2632 {
2633 flags=ParseGeometry(value,&geometry_info);
2634 if ((flags & SigmaValue) == 0)
2635 geometry_info.sigma=1.0;
2636 affine.tx=geometry_info.rho;
2637 affine.ty=geometry_info.sigma;
2638 break;
2639 }
2640 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2641 keyword);
2642 break;
2643 }
2644 case 'U':
2645 case 'u':
2646 {
2647 if (LocaleCompare(keyword, "undercolor") == 0)
2648 {
cristy9950d572011-10-01 18:22:35 +00002649 (void) QueryColorCompliance(value,AllCompliance,
2650 &draw_info->undercolor,&exception);
cristy3ed852e2009-09-05 21:47:34 +00002651 break;
2652 }
2653 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2654 keyword);
2655 break;
2656 }
2657 case 'W':
2658 case 'w':
2659 {
2660 if (LocaleCompare(keyword,"weight") == 0)
2661 {
cristyf2f27272009-12-17 14:48:46 +00002662 draw_info->weight=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002663 break;
2664 }
2665 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2666 keyword);
2667 break;
2668 }
2669 case 'X':
2670 case 'x':
2671 {
2672 if (LocaleCompare(keyword,"x") == 0)
2673 {
cristyf2f27272009-12-17 14:48:46 +00002674 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002675 break;
2676 }
2677 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2678 keyword);
2679 break;
2680 }
2681 case 'Y':
2682 case 'y':
2683 {
2684 if (LocaleCompare(keyword,"y") == 0)
2685 {
cristyf2f27272009-12-17 14:48:46 +00002686 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002687 break;
2688 }
2689 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2690 keyword);
2691 break;
2692 }
2693 default:
2694 {
2695 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2696 keyword);
2697 break;
2698 }
2699 }
2700 }
cristyb51dff52011-05-19 16:55:47 +00002701 (void) FormatLocaleString(text,MaxTextExtent,
cristye8c25f92010-06-03 00:53:06 +00002702 "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,(double)
2703 geometry.height,(double) geometry.x,(double) geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00002704 CloneString(&draw_info->geometry,text);
cristyef7c8a52010-10-10 13:46:51 +00002705 draw_info->affine.sx=affine.sx*current.sx+affine.ry*current.rx;
2706 draw_info->affine.rx=affine.rx*current.sx+affine.sy*current.rx;
2707 draw_info->affine.ry=affine.sx*current.ry+affine.ry*current.sy;
2708 draw_info->affine.sy=affine.rx*current.ry+affine.sy*current.sy;
2709 draw_info->affine.tx=affine.sx*current.tx+affine.ry*current.ty+
2710 affine.tx;
2711 draw_info->affine.ty=affine.rx*current.tx+affine.sy*current.ty+
2712 affine.ty;
cristy018f07f2011-09-04 21:15:19 +00002713 (void) DrawImage(msl_info->image[n],draw_info,&exception);
cristy3ed852e2009-09-05 21:47:34 +00002714 draw_info=DestroyDrawInfo(draw_info);
2715 break;
2716 }
2717 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
2718 }
2719 case 'E':
2720 case 'e':
2721 {
cristyb988fe72009-09-16 01:01:10 +00002722 if (LocaleCompare((const char *) tag,"edge") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002723 {
2724 Image
2725 *edge_image;
2726
2727 /*
2728 Edge image.
2729 */
2730 if (msl_info->image[n] == (Image *) NULL)
2731 {
cristyb988fe72009-09-16 01:01:10 +00002732 ThrowMSLException(OptionError,"NoImagesDefined",
2733 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002734 break;
2735 }
2736 if (attributes != (const xmlChar **) NULL)
2737 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2738 {
2739 keyword=(const char *) attributes[i++];
2740 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002741 msl_info->attributes[n],(const char *) attributes[i],
2742 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002743 CloneString(&value,attribute);
2744 switch (*keyword)
2745 {
2746 case 'G':
2747 case 'g':
2748 {
2749 if (LocaleCompare(keyword,"geometry") == 0)
2750 {
2751 flags=ParseGeometry(value,&geometry_info);
2752 if ((flags & SigmaValue) == 0)
2753 geometry_info.sigma=1.0;
2754 break;
2755 }
2756 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2757 keyword);
2758 break;
2759 }
2760 case 'R':
2761 case 'r':
2762 {
2763 if (LocaleCompare(keyword,"radius") == 0)
2764 {
cristy9b34e302011-11-05 02:15:45 +00002765 geometry_info.rho=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002766 break;
2767 }
2768 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2769 keyword);
2770 break;
2771 }
2772 default:
2773 {
2774 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2775 keyword);
2776 break;
2777 }
2778 }
2779 }
2780 edge_image=EdgeImage(msl_info->image[n],geometry_info.rho,
cristyc82a27b2011-10-21 01:07:16 +00002781 geometry_info.sigma,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00002782 if (edge_image == (Image *) NULL)
2783 break;
2784 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2785 msl_info->image[n]=edge_image;
2786 break;
2787 }
cristyb988fe72009-09-16 01:01:10 +00002788 if (LocaleCompare((const char *) tag,"emboss") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002789 {
2790 Image
2791 *emboss_image;
2792
2793 /*
2794 Emboss image.
2795 */
2796 if (msl_info->image[n] == (Image *) NULL)
2797 {
cristyb988fe72009-09-16 01:01:10 +00002798 ThrowMSLException(OptionError,"NoImagesDefined",
2799 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002800 break;
2801 }
2802 if (attributes != (const xmlChar **) NULL)
2803 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2804 {
2805 keyword=(const char *) attributes[i++];
2806 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002807 msl_info->attributes[n],(const char *) attributes[i],
2808 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002809 CloneString(&value,attribute);
2810 switch (*keyword)
2811 {
2812 case 'G':
2813 case 'g':
2814 {
2815 if (LocaleCompare(keyword,"geometry") == 0)
2816 {
2817 flags=ParseGeometry(value,&geometry_info);
2818 if ((flags & SigmaValue) == 0)
2819 geometry_info.sigma=1.0;
2820 break;
2821 }
2822 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2823 keyword);
2824 break;
2825 }
2826 case 'R':
2827 case 'r':
2828 {
2829 if (LocaleCompare(keyword,"radius") == 0)
2830 {
cristydbdd0e32011-11-04 23:29:40 +00002831 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00002832 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002833 break;
2834 }
2835 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2836 keyword);
2837 break;
2838 }
2839 case 'S':
2840 case 's':
2841 {
2842 if (LocaleCompare(keyword,"sigma") == 0)
2843 {
cristyf2f27272009-12-17 14:48:46 +00002844 geometry_info.sigma=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002845 break;
2846 }
2847 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2848 keyword);
2849 break;
2850 }
2851 default:
2852 {
2853 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2854 keyword);
2855 break;
2856 }
2857 }
2858 }
2859 emboss_image=EmbossImage(msl_info->image[n],geometry_info.rho,
cristyc82a27b2011-10-21 01:07:16 +00002860 geometry_info.sigma,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00002861 if (emboss_image == (Image *) NULL)
2862 break;
2863 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2864 msl_info->image[n]=emboss_image;
2865 break;
2866 }
cristyb988fe72009-09-16 01:01:10 +00002867 if (LocaleCompare((const char *) tag,"enhance") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002868 {
2869 Image
2870 *enhance_image;
2871
2872 /*
2873 Enhance image.
2874 */
2875 if (msl_info->image[n] == (Image *) NULL)
2876 {
cristyb988fe72009-09-16 01:01:10 +00002877 ThrowMSLException(OptionError,"NoImagesDefined",
2878 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002879 break;
2880 }
2881 if (attributes != (const xmlChar **) NULL)
2882 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2883 {
2884 keyword=(const char *) attributes[i++];
2885 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002886 msl_info->attributes[n],(const char *) attributes[i],
2887 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002888 CloneString(&value,attribute);
2889 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
2890 }
2891 enhance_image=EnhanceImage(msl_info->image[n],
cristyc82a27b2011-10-21 01:07:16 +00002892 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00002893 if (enhance_image == (Image *) NULL)
2894 break;
2895 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2896 msl_info->image[n]=enhance_image;
2897 break;
2898 }
cristyb988fe72009-09-16 01:01:10 +00002899 if (LocaleCompare((const char *) tag,"equalize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002900 {
2901 /*
2902 Equalize image.
2903 */
2904 if (msl_info->image[n] == (Image *) NULL)
2905 {
cristyb988fe72009-09-16 01:01:10 +00002906 ThrowMSLException(OptionError,"NoImagesDefined",
2907 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002908 break;
2909 }
2910 if (attributes != (const xmlChar **) NULL)
2911 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2912 {
2913 keyword=(const char *) attributes[i++];
2914 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002915 msl_info->attributes[n],(const char *) attributes[i],
2916 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002917 CloneString(&value,attribute);
2918 switch (*keyword)
2919 {
2920 default:
2921 {
2922 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2923 keyword);
2924 break;
2925 }
2926 }
2927 }
cristy6d8c3d72011-08-22 01:20:01 +00002928 (void) EqualizeImage(msl_info->image[n],
cristyc82a27b2011-10-21 01:07:16 +00002929 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00002930 break;
2931 }
2932 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
2933 }
2934 case 'F':
2935 case 'f':
2936 {
cristyb988fe72009-09-16 01:01:10 +00002937 if (LocaleCompare((const char *) tag, "flatten") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002938 {
2939 if (msl_info->image[n] == (Image *) NULL)
2940 {
cristyb988fe72009-09-16 01:01:10 +00002941 ThrowMSLException(OptionError,"NoImagesDefined",
2942 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002943 break;
2944 }
2945
2946 /* no attributes here */
2947
2948 /* process the image */
2949 {
2950 Image
2951 *newImage;
2952
2953 newImage=MergeImageLayers(msl_info->image[n],FlattenLayer,
cristyc82a27b2011-10-21 01:07:16 +00002954 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00002955 if (newImage == (Image *) NULL)
2956 break;
2957 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2958 msl_info->image[n]=newImage;
2959 break;
2960 }
2961 }
cristyb988fe72009-09-16 01:01:10 +00002962 if (LocaleCompare((const char *) tag,"flip") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002963 {
2964 Image
2965 *flip_image;
2966
2967 /*
2968 Flip image.
2969 */
2970 if (msl_info->image[n] == (Image *) NULL)
2971 {
cristyb988fe72009-09-16 01:01:10 +00002972 ThrowMSLException(OptionError,"NoImagesDefined",
2973 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002974 break;
2975 }
2976 if (attributes != (const xmlChar **) NULL)
2977 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2978 {
2979 keyword=(const char *) attributes[i++];
2980 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002981 msl_info->attributes[n],(const char *) attributes[i],
2982 &exception);
cristy3ed852e2009-09-05 21:47:34 +00002983 CloneString(&value,attribute);
2984 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
2985 }
2986 flip_image=FlipImage(msl_info->image[n],
cristyc82a27b2011-10-21 01:07:16 +00002987 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00002988 if (flip_image == (Image *) NULL)
2989 break;
2990 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2991 msl_info->image[n]=flip_image;
2992 break;
2993 }
cristyb988fe72009-09-16 01:01:10 +00002994 if (LocaleCompare((const char *) tag,"flop") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002995 {
2996 Image
2997 *flop_image;
2998
2999 /*
3000 Flop image.
3001 */
3002 if (msl_info->image[n] == (Image *) NULL)
3003 {
cristyb988fe72009-09-16 01:01:10 +00003004 ThrowMSLException(OptionError,"NoImagesDefined",
3005 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003006 break;
3007 }
3008 if (attributes != (const xmlChar **) NULL)
3009 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3010 {
3011 keyword=(const char *) attributes[i++];
3012 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003013 msl_info->attributes[n],(const char *) attributes[i],
3014 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003015 CloneString(&value,attribute);
3016 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3017 }
3018 flop_image=FlopImage(msl_info->image[n],
cristyc82a27b2011-10-21 01:07:16 +00003019 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00003020 if (flop_image == (Image *) NULL)
3021 break;
3022 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3023 msl_info->image[n]=flop_image;
3024 break;
3025 }
cristyb988fe72009-09-16 01:01:10 +00003026 if (LocaleCompare((const char *) tag,"frame") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003027 {
3028 FrameInfo
3029 frame_info;
3030
3031 Image
3032 *frame_image;
3033
3034 /*
3035 Frame image.
3036 */
3037 if (msl_info->image[n] == (Image *) NULL)
3038 {
cristyb988fe72009-09-16 01:01:10 +00003039 ThrowMSLException(OptionError,"NoImagesDefined",
3040 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003041 break;
3042 }
3043 SetGeometry(msl_info->image[n],&geometry);
3044 if (attributes != (const xmlChar **) NULL)
3045 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3046 {
3047 keyword=(const char *) attributes[i++];
3048 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003049 msl_info->attributes[n],(const char *) attributes[i],
3050 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003051 CloneString(&value,attribute);
3052 switch (*keyword)
3053 {
3054 case 'C':
3055 case 'c':
3056 {
3057 if (LocaleCompare(keyword,"compose") == 0)
3058 {
cristy042ee782011-04-22 18:48:30 +00003059 option=ParseCommandOption(MagickComposeOptions,
cristy3ed852e2009-09-05 21:47:34 +00003060 MagickFalse,value);
3061 if (option < 0)
3062 ThrowMSLException(OptionError,"UnrecognizedComposeType",
3063 value);
3064 msl_info->image[n]->compose=(CompositeOperator) option;
3065 break;
3066 }
3067 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3068 keyword);
3069 break;
3070 }
3071 case 'F':
3072 case 'f':
3073 {
3074 if (LocaleCompare(keyword, "fill") == 0)
3075 {
cristy9950d572011-10-01 18:22:35 +00003076 (void) QueryColorCompliance(value,AllCompliance,
cristy3ed852e2009-09-05 21:47:34 +00003077 &msl_info->image[n]->matte_color,&exception);
3078 break;
3079 }
3080 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3081 keyword);
3082 break;
3083 }
3084 case 'G':
3085 case 'g':
3086 {
3087 if (LocaleCompare(keyword,"geometry") == 0)
3088 {
3089 flags=ParsePageGeometry(msl_info->image[n],value,
3090 &geometry,&exception);
3091 if ((flags & HeightValue) == 0)
3092 geometry.height=geometry.width;
3093 frame_info.width=geometry.width;
3094 frame_info.height=geometry.height;
3095 frame_info.outer_bevel=geometry.x;
3096 frame_info.inner_bevel=geometry.y;
3097 break;
3098 }
3099 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3100 keyword);
3101 break;
3102 }
3103 case 'H':
3104 case 'h':
3105 {
3106 if (LocaleCompare(keyword,"height") == 0)
3107 {
cristyf2f27272009-12-17 14:48:46 +00003108 frame_info.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003109 break;
3110 }
3111 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3112 keyword);
3113 break;
3114 }
3115 case 'I':
3116 case 'i':
3117 {
3118 if (LocaleCompare(keyword,"inner") == 0)
3119 {
cristyf2f27272009-12-17 14:48:46 +00003120 frame_info.inner_bevel=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003121 break;
3122 }
3123 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3124 keyword);
3125 break;
3126 }
3127 case 'O':
3128 case 'o':
3129 {
3130 if (LocaleCompare(keyword,"outer") == 0)
3131 {
cristyf2f27272009-12-17 14:48:46 +00003132 frame_info.outer_bevel=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003133 break;
3134 }
3135 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3136 keyword);
3137 break;
3138 }
3139 case 'W':
3140 case 'w':
3141 {
3142 if (LocaleCompare(keyword,"width") == 0)
3143 {
cristyf2f27272009-12-17 14:48:46 +00003144 frame_info.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003145 break;
3146 }
3147 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3148 keyword);
3149 break;
3150 }
3151 default:
3152 {
3153 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3154 keyword);
3155 break;
3156 }
3157 }
3158 }
cristybb503372010-05-27 20:51:26 +00003159 frame_info.x=(ssize_t) frame_info.width;
3160 frame_info.y=(ssize_t) frame_info.height;
cristy3ed852e2009-09-05 21:47:34 +00003161 frame_info.width=msl_info->image[n]->columns+2*frame_info.x;
3162 frame_info.height=msl_info->image[n]->rows+2*frame_info.y;
3163 frame_image=FrameImage(msl_info->image[n],&frame_info,
cristyc82a27b2011-10-21 01:07:16 +00003164 msl_info->image[n]->compose,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00003165 if (frame_image == (Image *) NULL)
3166 break;
3167 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3168 msl_info->image[n]=frame_image;
3169 break;
3170 }
3171 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3172 }
3173 case 'G':
3174 case 'g':
3175 {
cristyb988fe72009-09-16 01:01:10 +00003176 if (LocaleCompare((const char *) tag,"gamma") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003177 {
3178 char
3179 gamma[MaxTextExtent];
3180
cristy4c08aed2011-07-01 19:47:50 +00003181 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00003182 pixel;
3183
3184 /*
3185 Gamma image.
3186 */
3187 if (msl_info->image[n] == (Image *) NULL)
3188 {
cristyb988fe72009-09-16 01:01:10 +00003189 ThrowMSLException(OptionError,"NoImagesDefined",
3190 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003191 break;
3192 }
3193 channel=UndefinedChannel;
3194 pixel.red=0.0;
3195 pixel.green=0.0;
3196 pixel.blue=0.0;
3197 *gamma='\0';
3198 if (attributes != (const xmlChar **) NULL)
3199 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3200 {
3201 keyword=(const char *) attributes[i++];
3202 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003203 msl_info->attributes[n],(const char *) attributes[i],
3204 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003205 CloneString(&value,attribute);
3206 switch (*keyword)
3207 {
3208 case 'B':
3209 case 'b':
3210 {
3211 if (LocaleCompare(keyword,"blue") == 0)
3212 {
cristydbdd0e32011-11-04 23:29:40 +00003213 pixel.blue=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003214 break;
3215 }
3216 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3217 keyword);
3218 break;
3219 }
3220 case 'C':
3221 case 'c':
3222 {
3223 if (LocaleCompare(keyword,"channel") == 0)
3224 {
3225 option=ParseChannelOption(value);
3226 if (option < 0)
3227 ThrowMSLException(OptionError,"UnrecognizedChannelType",
3228 value);
3229 channel=(ChannelType) option;
3230 break;
3231 }
3232 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3233 keyword);
3234 break;
3235 }
3236 case 'G':
3237 case 'g':
3238 {
3239 if (LocaleCompare(keyword,"gamma") == 0)
3240 {
3241 (void) CopyMagickString(gamma,value,MaxTextExtent);
3242 break;
3243 }
3244 if (LocaleCompare(keyword,"green") == 0)
3245 {
cristydbdd0e32011-11-04 23:29:40 +00003246 pixel.green=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003247 break;
3248 }
3249 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3250 keyword);
3251 break;
3252 }
3253 case 'R':
3254 case 'r':
3255 {
3256 if (LocaleCompare(keyword,"red") == 0)
3257 {
cristydbdd0e32011-11-04 23:29:40 +00003258 pixel.red=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003259 break;
3260 }
3261 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3262 keyword);
3263 break;
3264 }
3265 default:
3266 {
3267 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3268 keyword);
3269 break;
3270 }
3271 }
3272 }
3273 if (*gamma == '\0')
cristyb51dff52011-05-19 16:55:47 +00003274 (void) FormatLocaleString(gamma,MaxTextExtent,"%g,%g,%g",
cristy3ed852e2009-09-05 21:47:34 +00003275 (double) pixel.red,(double) pixel.green,(double) pixel.blue);
cristyb3e7c6c2011-07-24 01:43:55 +00003276 (void) GammaImage(msl_info->image[n],atof(gamma),
cristyc82a27b2011-10-21 01:07:16 +00003277 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00003278 break;
3279 }
cristyb988fe72009-09-16 01:01:10 +00003280 else if (LocaleCompare((const char *) tag,"get") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003281 {
3282 if (msl_info->image[n] == (Image *) NULL)
3283 {
cristyb988fe72009-09-16 01:01:10 +00003284 ThrowMSLException(OptionError,"NoImagesDefined",
3285 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003286 break;
3287 }
3288 if (attributes == (const xmlChar **) NULL)
3289 break;
3290 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3291 {
3292 keyword=(const char *) attributes[i++];
cristyb988fe72009-09-16 01:01:10 +00003293 CloneString(&value,(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003294 (void) CopyMagickString(key,value,MaxTextExtent);
3295 switch (*keyword)
3296 {
3297 case 'H':
3298 case 'h':
3299 {
3300 if (LocaleCompare(keyword,"height") == 0)
3301 {
cristyb51dff52011-05-19 16:55:47 +00003302 (void) FormatLocaleString(value,MaxTextExtent,"%.20g",
cristye8c25f92010-06-03 00:53:06 +00003303 (double) msl_info->image[n]->rows);
cristyd15e6592011-10-15 00:13:06 +00003304 (void) SetImageProperty(msl_info->attributes[n],key,value,
3305 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003306 break;
3307 }
3308 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3309 }
3310 case 'W':
3311 case 'w':
3312 {
3313 if (LocaleCompare(keyword,"width") == 0)
3314 {
cristyb51dff52011-05-19 16:55:47 +00003315 (void) FormatLocaleString(value,MaxTextExtent,"%.20g",
cristye8c25f92010-06-03 00:53:06 +00003316 (double) msl_info->image[n]->columns);
cristyd15e6592011-10-15 00:13:06 +00003317 (void) SetImageProperty(msl_info->attributes[n],key,value,
3318 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003319 break;
3320 }
3321 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3322 }
3323 default:
3324 {
3325 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3326 break;
3327 }
3328 }
3329 }
3330 break;
3331 }
cristyb988fe72009-09-16 01:01:10 +00003332 else if (LocaleCompare((const char *) tag, "group") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003333 {
3334 msl_info->number_groups++;
3335 msl_info->group_info=(MSLGroupInfo *) ResizeQuantumMemory(
3336 msl_info->group_info,msl_info->number_groups+1UL,
3337 sizeof(*msl_info->group_info));
3338 break;
3339 }
3340 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3341 }
3342 case 'I':
3343 case 'i':
3344 {
cristyb988fe72009-09-16 01:01:10 +00003345 if (LocaleCompare((const char *) tag,"image") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003346 {
cristy3ed852e2009-09-05 21:47:34 +00003347 MSLPushImage(msl_info,(Image *) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003348 if (attributes == (const xmlChar **) NULL)
3349 break;
3350 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3351 {
3352 keyword=(const char *) attributes[i++];
3353 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003354 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00003355 switch (*keyword)
3356 {
cristyb988fe72009-09-16 01:01:10 +00003357 case 'C':
3358 case 'c':
cristy3ed852e2009-09-05 21:47:34 +00003359 {
cristyb988fe72009-09-16 01:01:10 +00003360 if (LocaleCompare(keyword,"color") == 0)
3361 {
3362 Image
3363 *next_image;
cristy3ed852e2009-09-05 21:47:34 +00003364
cristyb988fe72009-09-16 01:01:10 +00003365 (void) CopyMagickString(msl_info->image_info[n]->filename,
3366 "xc:",MaxTextExtent);
3367 (void) ConcatenateMagickString(msl_info->image_info[n]->
3368 filename,value,MaxTextExtent);
3369 next_image=ReadImage(msl_info->image_info[n],&exception);
3370 CatchException(&exception);
3371 if (next_image == (Image *) NULL)
3372 continue;
3373 if (msl_info->image[n] == (Image *) NULL)
3374 msl_info->image[n]=next_image;
3375 else
3376 {
3377 register Image
3378 *p;
cristy3ed852e2009-09-05 21:47:34 +00003379
cristyb988fe72009-09-16 01:01:10 +00003380 /*
3381 Link image into image list.
3382 */
3383 p=msl_info->image[n];
3384 while (p->next != (Image *) NULL)
3385 p=GetNextImageInList(p);
3386 next_image->previous=p;
3387 p->next=next_image;
3388 }
3389 break;
3390 }
cristyb20775d2009-09-16 01:51:41 +00003391 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00003392 break;
3393 }
3394 default:
3395 {
cristyb20775d2009-09-16 01:51:41 +00003396 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00003397 break;
3398 }
3399 }
3400 }
3401 break;
3402 }
cristyb988fe72009-09-16 01:01:10 +00003403 if (LocaleCompare((const char *) tag,"implode") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003404 {
3405 Image
3406 *implode_image;
3407
3408 /*
3409 Implode image.
3410 */
3411 if (msl_info->image[n] == (Image *) NULL)
3412 {
cristyb988fe72009-09-16 01:01:10 +00003413 ThrowMSLException(OptionError,"NoImagesDefined",
3414 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003415 break;
3416 }
3417 if (attributes != (const xmlChar **) NULL)
3418 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3419 {
3420 keyword=(const char *) attributes[i++];
3421 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003422 msl_info->attributes[n],(const char *) attributes[i],
3423 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003424 CloneString(&value,attribute);
3425 switch (*keyword)
3426 {
3427 case 'A':
3428 case 'a':
3429 {
3430 if (LocaleCompare(keyword,"amount") == 0)
3431 {
cristydbdd0e32011-11-04 23:29:40 +00003432 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00003433 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003434 break;
3435 }
3436 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3437 keyword);
3438 break;
3439 }
3440 case 'G':
3441 case 'g':
3442 {
3443 if (LocaleCompare(keyword,"geometry") == 0)
3444 {
3445 flags=ParseGeometry(value,&geometry_info);
3446 if ((flags & SigmaValue) == 0)
3447 geometry_info.sigma=1.0;
3448 break;
3449 }
3450 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3451 keyword);
3452 break;
3453 }
3454 default:
3455 {
3456 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3457 keyword);
3458 break;
3459 }
3460 }
3461 }
3462 implode_image=ImplodeImage(msl_info->image[n],geometry_info.rho,
cristyc82a27b2011-10-21 01:07:16 +00003463 msl_info->image[n]->interpolate,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00003464 if (implode_image == (Image *) NULL)
3465 break;
3466 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3467 msl_info->image[n]=implode_image;
3468 break;
3469 }
3470 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3471 }
3472 case 'L':
3473 case 'l':
3474 {
cristyb988fe72009-09-16 01:01:10 +00003475 if (LocaleCompare((const char *) tag,"label") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003476 break;
cristyb988fe72009-09-16 01:01:10 +00003477 if (LocaleCompare((const char *) tag, "level") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003478 {
3479 double
3480 levelBlack = 0, levelGamma = 1, levelWhite = QuantumRange;
3481
3482 if (msl_info->image[n] == (Image *) NULL)
3483 {
cristyb988fe72009-09-16 01:01:10 +00003484 ThrowMSLException(OptionError,"NoImagesDefined",
3485 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003486 break;
3487 }
3488 if (attributes == (const xmlChar **) NULL)
3489 break;
3490 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3491 {
3492 keyword=(const char *) attributes[i++];
cristyb988fe72009-09-16 01:01:10 +00003493 CloneString(&value,(const char *) attributes[i]);
cristy3ed852e2009-09-05 21:47:34 +00003494 (void) CopyMagickString(key,value,MaxTextExtent);
3495 switch (*keyword)
3496 {
3497 case 'B':
3498 case 'b':
3499 {
3500 if (LocaleCompare(keyword,"black") == 0)
3501 {
cristydbdd0e32011-11-04 23:29:40 +00003502 levelBlack = StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003503 break;
3504 }
3505 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3506 break;
3507 }
3508 case 'G':
3509 case 'g':
3510 {
3511 if (LocaleCompare(keyword,"gamma") == 0)
3512 {
cristydbdd0e32011-11-04 23:29:40 +00003513 levelGamma = StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003514 break;
3515 }
3516 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3517 break;
3518 }
3519 case 'W':
3520 case 'w':
3521 {
3522 if (LocaleCompare(keyword,"white") == 0)
3523 {
cristydbdd0e32011-11-04 23:29:40 +00003524 levelWhite = StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003525 break;
3526 }
3527 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3528 break;
3529 }
3530 default:
3531 {
3532 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3533 break;
3534 }
3535 }
3536 }
3537
3538 /* process image */
cristy01e9afd2011-08-10 17:38:41 +00003539 LevelImage(msl_info->image[n],levelBlack,levelWhite,levelGamma,
cristyc82a27b2011-10-21 01:07:16 +00003540 msl_info->exception);
cristyf89cb1d2011-07-07 01:24:37 +00003541 break;
cristy3ed852e2009-09-05 21:47:34 +00003542 }
3543 }
3544 case 'M':
3545 case 'm':
3546 {
cristyb988fe72009-09-16 01:01:10 +00003547 if (LocaleCompare((const char *) tag,"magnify") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003548 {
3549 Image
3550 *magnify_image;
3551
3552 /*
3553 Magnify image.
3554 */
3555 if (msl_info->image[n] == (Image *) NULL)
3556 {
cristyb988fe72009-09-16 01:01:10 +00003557 ThrowMSLException(OptionError,"NoImagesDefined",
3558 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003559 break;
3560 }
3561 if (attributes != (const xmlChar **) NULL)
3562 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3563 {
3564 keyword=(const char *) attributes[i++];
3565 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003566 msl_info->attributes[n],(const char *) attributes[i],
3567 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003568 CloneString(&value,attribute);
3569 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3570 }
3571 magnify_image=MagnifyImage(msl_info->image[n],
cristyc82a27b2011-10-21 01:07:16 +00003572 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00003573 if (magnify_image == (Image *) NULL)
3574 break;
3575 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3576 msl_info->image[n]=magnify_image;
3577 break;
3578 }
cristyb988fe72009-09-16 01:01:10 +00003579 if (LocaleCompare((const char *) tag,"map") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003580 {
3581 Image
3582 *affinity_image;
3583
3584 MagickBooleanType
3585 dither;
3586
3587 QuantizeInfo
3588 *quantize_info;
3589
3590 /*
3591 Map image.
3592 */
3593 if (msl_info->image[n] == (Image *) NULL)
3594 {
cristyb988fe72009-09-16 01:01:10 +00003595 ThrowMSLException(OptionError,"NoImagesDefined",
3596 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003597 break;
3598 }
3599 affinity_image=NewImageList();
3600 dither=MagickFalse;
3601 if (attributes != (const xmlChar **) NULL)
3602 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3603 {
3604 keyword=(const char *) attributes[i++];
3605 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003606 msl_info->attributes[n],(const char *) attributes[i],
3607 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003608 CloneString(&value,attribute);
3609 switch (*keyword)
3610 {
3611 case 'D':
3612 case 'd':
3613 {
3614 if (LocaleCompare(keyword,"dither") == 0)
3615 {
cristy042ee782011-04-22 18:48:30 +00003616 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00003617 value);
3618 if (option < 0)
3619 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
3620 value);
3621 dither=(MagickBooleanType) option;
3622 break;
3623 }
3624 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3625 keyword);
3626 break;
3627 }
3628 case 'I':
3629 case 'i':
3630 {
3631 if (LocaleCompare(keyword,"image") == 0)
3632 for (j=0; j < msl_info->n; j++)
3633 {
3634 const char
3635 *attribute;
cristyb988fe72009-09-16 01:01:10 +00003636
cristyd15e6592011-10-15 00:13:06 +00003637 attribute=GetImageProperty(msl_info->attributes[j],"id",
3638 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003639 if ((attribute != (const char *) NULL) &&
3640 (LocaleCompare(attribute,value) == 0))
3641 {
3642 affinity_image=CloneImage(msl_info->image[j],0,0,
3643 MagickFalse,&exception);
3644 break;
3645 }
3646 }
3647 break;
3648 }
3649 default:
3650 {
3651 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3652 keyword);
3653 break;
3654 }
3655 }
3656 }
3657 quantize_info=AcquireQuantizeInfo(msl_info->image_info[n]);
3658 quantize_info->dither=dither;
3659 (void) RemapImages(quantize_info,msl_info->image[n],
cristy018f07f2011-09-04 21:15:19 +00003660 affinity_image,&exception);
cristy3ed852e2009-09-05 21:47:34 +00003661 quantize_info=DestroyQuantizeInfo(quantize_info);
3662 affinity_image=DestroyImage(affinity_image);
3663 break;
3664 }
cristyb988fe72009-09-16 01:01:10 +00003665 if (LocaleCompare((const char *) tag,"matte-floodfill") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003666 {
3667 double
3668 opacity;
3669
cristy4c08aed2011-07-01 19:47:50 +00003670 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00003671 target;
3672
3673 PaintMethod
3674 paint_method;
3675
3676 /*
3677 Matte floodfill image.
3678 */
3679 opacity=0.0;
3680 if (msl_info->image[n] == (Image *) NULL)
3681 {
cristyb988fe72009-09-16 01:01:10 +00003682 ThrowMSLException(OptionError,"NoImagesDefined",
3683 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003684 break;
3685 }
3686 SetGeometry(msl_info->image[n],&geometry);
3687 paint_method=FloodfillMethod;
3688 if (attributes != (const xmlChar **) NULL)
3689 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3690 {
3691 keyword=(const char *) attributes[i++];
3692 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003693 msl_info->attributes[n],(const char *) attributes[i],
3694 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003695 CloneString(&value,attribute);
3696 switch (*keyword)
3697 {
3698 case 'B':
3699 case 'b':
3700 {
3701 if (LocaleCompare(keyword,"bordercolor") == 0)
3702 {
cristy269c9412011-10-13 23:41:15 +00003703 (void) QueryColorCompliance(value,AllCompliance,
cristy9950d572011-10-01 18:22:35 +00003704 &target,&exception);
cristy3ed852e2009-09-05 21:47:34 +00003705 paint_method=FillToBorderMethod;
3706 break;
3707 }
3708 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3709 keyword);
3710 break;
3711 }
3712 case 'F':
3713 case 'f':
3714 {
3715 if (LocaleCompare(keyword,"fuzz") == 0)
3716 {
cristydbdd0e32011-11-04 23:29:40 +00003717 msl_info->image[n]->fuzz=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00003718 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003719 break;
3720 }
3721 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3722 keyword);
3723 break;
3724 }
3725 case 'G':
3726 case 'g':
3727 {
3728 if (LocaleCompare(keyword,"geometry") == 0)
3729 {
3730 flags=ParsePageGeometry(msl_info->image[n],value,
3731 &geometry,&exception);
3732 if ((flags & HeightValue) == 0)
3733 geometry.height=geometry.width;
cristy3aa93752011-12-18 15:54:24 +00003734 (void) GetOneVirtualPixelInfo(msl_info->image[n],
cristy33e9da62011-10-21 19:08:58 +00003735 TileVirtualPixelMethod,geometry.x,geometry.y,&target,
3736 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003737 break;
3738 }
3739 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3740 keyword);
3741 break;
3742 }
3743 case 'O':
3744 case 'o':
3745 {
3746 if (LocaleCompare(keyword,"opacity") == 0)
3747 {
cristydbdd0e32011-11-04 23:29:40 +00003748 opacity=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003749 break;
3750 }
3751 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3752 keyword);
3753 break;
3754 }
3755 case 'X':
3756 case 'x':
3757 {
3758 if (LocaleCompare(keyword,"x") == 0)
3759 {
cristyf2f27272009-12-17 14:48:46 +00003760 geometry.x=StringToLong(value);
cristy3aa93752011-12-18 15:54:24 +00003761 (void) GetOneVirtualPixelInfo(msl_info->image[n],
cristy33e9da62011-10-21 19:08:58 +00003762 TileVirtualPixelMethod,geometry.x,geometry.y,&target,
3763 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003764 break;
3765 }
3766 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3767 keyword);
3768 break;
3769 }
3770 case 'Y':
3771 case 'y':
3772 {
3773 if (LocaleCompare(keyword,"y") == 0)
3774 {
cristyf2f27272009-12-17 14:48:46 +00003775 geometry.y=StringToLong(value);
cristy3aa93752011-12-18 15:54:24 +00003776 (void) GetOneVirtualPixelInfo(msl_info->image[n],
cristy33e9da62011-10-21 19:08:58 +00003777 TileVirtualPixelMethod,geometry.x,geometry.y,&target,
3778 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003779 break;
3780 }
3781 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3782 keyword);
3783 break;
3784 }
3785 default:
3786 {
3787 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3788 keyword);
3789 break;
3790 }
3791 }
3792 }
3793 draw_info=CloneDrawInfo(msl_info->image_info[n],
3794 msl_info->draw_info[n]);
cristy4c08aed2011-07-01 19:47:50 +00003795 draw_info->fill.alpha=ClampToQuantum(opacity);
cristybd5a96c2011-08-21 00:04:26 +00003796 channel_mask=SetPixelChannelMask(msl_info->image[n],AlphaChannel);
cristyd42d9952011-07-08 14:21:50 +00003797 (void) FloodfillPaintImage(msl_info->image[n],draw_info,&target,
3798 geometry.x,geometry.y,paint_method == FloodfillMethod ?
cristyc82a27b2011-10-21 01:07:16 +00003799 MagickFalse : MagickTrue,msl_info->exception);
cristye2a912b2011-12-05 20:02:07 +00003800 (void) SetPixelChannelMapMask(msl_info->image[n],channel_mask);
cristy3ed852e2009-09-05 21:47:34 +00003801 draw_info=DestroyDrawInfo(draw_info);
3802 break;
3803 }
cristyb988fe72009-09-16 01:01:10 +00003804 if (LocaleCompare((const char *) tag,"median-filter") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003805 {
3806 Image
3807 *median_image;
3808
3809 /*
3810 Median-filter image.
3811 */
3812 if (msl_info->image[n] == (Image *) NULL)
3813 {
cristyb988fe72009-09-16 01:01:10 +00003814 ThrowMSLException(OptionError,"NoImagesDefined",
3815 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003816 break;
3817 }
3818 if (attributes != (const xmlChar **) NULL)
3819 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3820 {
3821 keyword=(const char *) attributes[i++];
3822 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003823 msl_info->attributes[n],(const char *) attributes[i],
3824 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003825 CloneString(&value,attribute);
3826 switch (*keyword)
3827 {
3828 case 'G':
3829 case 'g':
3830 {
3831 if (LocaleCompare(keyword,"geometry") == 0)
3832 {
3833 flags=ParseGeometry(value,&geometry_info);
3834 if ((flags & SigmaValue) == 0)
3835 geometry_info.sigma=1.0;
3836 break;
3837 }
3838 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3839 keyword);
3840 break;
3841 }
3842 case 'R':
3843 case 'r':
3844 {
3845 if (LocaleCompare(keyword,"radius") == 0)
3846 {
cristydbdd0e32011-11-04 23:29:40 +00003847 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00003848 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003849 break;
3850 }
3851 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3852 keyword);
3853 break;
3854 }
3855 default:
3856 {
3857 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3858 keyword);
3859 break;
3860 }
3861 }
3862 }
cristy733678d2011-03-18 21:29:28 +00003863 median_image=StatisticImage(msl_info->image[n],MedianStatistic,
cristy95c38342011-03-18 22:39:51 +00003864 (size_t) geometry_info.rho,(size_t) geometry_info.sigma,
cristyc82a27b2011-10-21 01:07:16 +00003865 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00003866 if (median_image == (Image *) NULL)
3867 break;
3868 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3869 msl_info->image[n]=median_image;
3870 break;
3871 }
cristyb988fe72009-09-16 01:01:10 +00003872 if (LocaleCompare((const char *) tag,"minify") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003873 {
3874 Image
3875 *minify_image;
3876
3877 /*
3878 Minify image.
3879 */
3880 if (msl_info->image[n] == (Image *) NULL)
3881 {
cristyb988fe72009-09-16 01:01:10 +00003882 ThrowMSLException(OptionError,"NoImagesDefined",
3883 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003884 break;
3885 }
3886 if (attributes != (const xmlChar **) NULL)
3887 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3888 {
3889 keyword=(const char *) attributes[i++];
3890 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003891 msl_info->attributes[n],(const char *) attributes[i],
3892 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003893 CloneString(&value,attribute);
3894 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3895 }
3896 minify_image=MinifyImage(msl_info->image[n],
cristyc82a27b2011-10-21 01:07:16 +00003897 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00003898 if (minify_image == (Image *) NULL)
3899 break;
3900 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3901 msl_info->image[n]=minify_image;
3902 break;
3903 }
cristyb988fe72009-09-16 01:01:10 +00003904 if (LocaleCompare((const char *) tag,"msl") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00003905 break;
cristyb988fe72009-09-16 01:01:10 +00003906 if (LocaleCompare((const char *) tag,"modulate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003907 {
3908 char
3909 modulate[MaxTextExtent];
3910
3911 /*
3912 Modulate image.
3913 */
3914 if (msl_info->image[n] == (Image *) NULL)
3915 {
cristyb988fe72009-09-16 01:01:10 +00003916 ThrowMSLException(OptionError,"NoImagesDefined",
3917 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003918 break;
3919 }
3920 geometry_info.rho=100.0;
3921 geometry_info.sigma=100.0;
3922 geometry_info.xi=100.0;
3923 if (attributes != (const xmlChar **) NULL)
3924 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3925 {
3926 keyword=(const char *) attributes[i++];
3927 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003928 msl_info->attributes[n],(const char *) attributes[i],
3929 &exception);
cristy3ed852e2009-09-05 21:47:34 +00003930 CloneString(&value,attribute);
3931 switch (*keyword)
3932 {
3933 case 'B':
3934 case 'b':
3935 {
3936 if (LocaleCompare(keyword,"blackness") == 0)
3937 {
cristydbdd0e32011-11-04 23:29:40 +00003938 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00003939 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003940 break;
3941 }
3942 if (LocaleCompare(keyword,"brightness") == 0)
3943 {
cristydbdd0e32011-11-04 23:29:40 +00003944 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00003945 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003946 break;
3947 }
3948 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3949 keyword);
3950 break;
3951 }
3952 case 'F':
3953 case 'f':
3954 {
3955 if (LocaleCompare(keyword,"factor") == 0)
3956 {
3957 flags=ParseGeometry(value,&geometry_info);
3958 break;
3959 }
3960 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3961 keyword);
3962 break;
3963 }
3964 case 'H':
3965 case 'h':
3966 {
3967 if (LocaleCompare(keyword,"hue") == 0)
3968 {
cristydbdd0e32011-11-04 23:29:40 +00003969 geometry_info.xi=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00003970 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003971 break;
3972 }
3973 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3974 keyword);
3975 break;
3976 }
3977 case 'L':
3978 case 'l':
3979 {
3980 if (LocaleCompare(keyword,"lightness") == 0)
3981 {
cristydbdd0e32011-11-04 23:29:40 +00003982 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00003983 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003984 break;
3985 }
3986 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3987 keyword);
3988 break;
3989 }
3990 case 'S':
3991 case 's':
3992 {
3993 if (LocaleCompare(keyword,"saturation") == 0)
3994 {
cristydbdd0e32011-11-04 23:29:40 +00003995 geometry_info.sigma=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00003996 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003997 break;
3998 }
3999 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4000 keyword);
4001 break;
4002 }
4003 case 'W':
4004 case 'w':
4005 {
4006 if (LocaleCompare(keyword,"whiteness") == 0)
4007 {
cristydbdd0e32011-11-04 23:29:40 +00004008 geometry_info.sigma=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00004009 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004010 break;
4011 }
4012 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4013 keyword);
4014 break;
4015 }
4016 default:
4017 {
4018 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4019 keyword);
4020 break;
4021 }
4022 }
4023 }
cristyb51dff52011-05-19 16:55:47 +00004024 (void) FormatLocaleString(modulate,MaxTextExtent,"%g,%g,%g",
cristy3ed852e2009-09-05 21:47:34 +00004025 geometry_info.rho,geometry_info.sigma,geometry_info.xi);
cristy33bd5152011-08-24 01:42:24 +00004026 (void) ModulateImage(msl_info->image[n],modulate,
cristyc82a27b2011-10-21 01:07:16 +00004027 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00004028 break;
4029 }
4030 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4031 }
4032 case 'N':
4033 case 'n':
4034 {
cristyb988fe72009-09-16 01:01:10 +00004035 if (LocaleCompare((const char *) tag,"negate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004036 {
4037 MagickBooleanType
4038 gray;
4039
4040 /*
4041 Negate image.
4042 */
4043 if (msl_info->image[n] == (Image *) NULL)
4044 {
cristyb988fe72009-09-16 01:01:10 +00004045 ThrowMSLException(OptionError,"NoImagesDefined",
4046 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004047 break;
4048 }
4049 gray=MagickFalse;
4050 if (attributes != (const xmlChar **) NULL)
4051 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4052 {
4053 keyword=(const char *) attributes[i++];
4054 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004055 msl_info->attributes[n],(const char *) attributes[i],
4056 &exception);
cristy3ed852e2009-09-05 21:47:34 +00004057 CloneString(&value,attribute);
4058 switch (*keyword)
4059 {
4060 case 'C':
4061 case 'c':
4062 {
4063 if (LocaleCompare(keyword,"channel") == 0)
4064 {
4065 option=ParseChannelOption(value);
4066 if (option < 0)
4067 ThrowMSLException(OptionError,"UnrecognizedChannelType",
4068 value);
4069 channel=(ChannelType) option;
4070 break;
4071 }
4072 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4073 keyword);
4074 break;
4075 }
4076 case 'G':
4077 case 'g':
4078 {
4079 if (LocaleCompare(keyword,"gray") == 0)
4080 {
cristy042ee782011-04-22 18:48:30 +00004081 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004082 value);
4083 if (option < 0)
4084 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4085 value);
4086 gray=(MagickBooleanType) option;
4087 break;
4088 }
4089 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4090 keyword);
4091 break;
4092 }
4093 default:
4094 {
4095 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4096 keyword);
4097 break;
4098 }
4099 }
4100 }
cristybd5a96c2011-08-21 00:04:26 +00004101 channel_mask=SetPixelChannelMask(msl_info->image[n],channel);
cristyb3e7c6c2011-07-24 01:43:55 +00004102 (void) NegateImage(msl_info->image[n],gray,
cristyc82a27b2011-10-21 01:07:16 +00004103 msl_info->exception);
cristye2a912b2011-12-05 20:02:07 +00004104 (void) SetPixelChannelMapMask(msl_info->image[n],channel_mask);
cristy3ed852e2009-09-05 21:47:34 +00004105 break;
4106 }
cristyb988fe72009-09-16 01:01:10 +00004107 if (LocaleCompare((const char *) tag,"normalize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004108 {
4109 /*
4110 Normalize image.
4111 */
4112 if (msl_info->image[n] == (Image *) NULL)
4113 {
cristyb988fe72009-09-16 01:01:10 +00004114 ThrowMSLException(OptionError,"NoImagesDefined",
4115 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004116 break;
4117 }
4118 if (attributes != (const xmlChar **) NULL)
4119 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4120 {
4121 keyword=(const char *) attributes[i++];
4122 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004123 msl_info->attributes[n],(const char *) attributes[i],
4124 &exception);
cristy3ed852e2009-09-05 21:47:34 +00004125 CloneString(&value,attribute);
4126 switch (*keyword)
4127 {
4128 case 'C':
4129 case 'c':
4130 {
4131 if (LocaleCompare(keyword,"channel") == 0)
4132 {
4133 option=ParseChannelOption(value);
4134 if (option < 0)
4135 ThrowMSLException(OptionError,"UnrecognizedChannelType",
4136 value);
4137 channel=(ChannelType) option;
4138 break;
4139 }
4140 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4141 keyword);
4142 break;
4143 }
4144 default:
4145 {
4146 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4147 keyword);
4148 break;
4149 }
4150 }
4151 }
cristye23ec9d2011-08-16 18:15:40 +00004152 (void) NormalizeImage(msl_info->image[n],
cristyc82a27b2011-10-21 01:07:16 +00004153 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00004154 break;
4155 }
4156 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4157 }
4158 case 'O':
4159 case 'o':
4160 {
cristyb988fe72009-09-16 01:01:10 +00004161 if (LocaleCompare((const char *) tag,"oil-paint") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004162 {
4163 Image
4164 *paint_image;
4165
4166 /*
4167 Oil-paint image.
4168 */
4169 if (msl_info->image[n] == (Image *) NULL)
4170 {
cristyb988fe72009-09-16 01:01:10 +00004171 ThrowMSLException(OptionError,"NoImagesDefined",
4172 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004173 break;
4174 }
4175 if (attributes != (const xmlChar **) NULL)
4176 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4177 {
4178 keyword=(const char *) attributes[i++];
4179 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004180 msl_info->attributes[n],(const char *) attributes[i],
4181 &exception);
cristy3ed852e2009-09-05 21:47:34 +00004182 CloneString(&value,attribute);
4183 switch (*keyword)
4184 {
4185 case 'G':
4186 case 'g':
4187 {
4188 if (LocaleCompare(keyword,"geometry") == 0)
4189 {
4190 flags=ParseGeometry(value,&geometry_info);
4191 if ((flags & SigmaValue) == 0)
4192 geometry_info.sigma=1.0;
4193 break;
4194 }
4195 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4196 keyword);
4197 break;
4198 }
4199 case 'R':
4200 case 'r':
4201 {
4202 if (LocaleCompare(keyword,"radius") == 0)
4203 {
cristydbdd0e32011-11-04 23:29:40 +00004204 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00004205 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004206 break;
4207 }
4208 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4209 keyword);
4210 break;
4211 }
4212 default:
4213 {
4214 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4215 keyword);
4216 break;
4217 }
4218 }
4219 }
4220 paint_image=OilPaintImage(msl_info->image[n],geometry_info.rho,
cristyc82a27b2011-10-21 01:07:16 +00004221 geometry_info.sigma,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00004222 if (paint_image == (Image *) NULL)
4223 break;
4224 msl_info->image[n]=DestroyImage(msl_info->image[n]);
4225 msl_info->image[n]=paint_image;
4226 break;
4227 }
cristyb988fe72009-09-16 01:01:10 +00004228 if (LocaleCompare((const char *) tag,"opaque") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004229 {
cristy4c08aed2011-07-01 19:47:50 +00004230 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00004231 fill_color,
4232 target;
4233
4234 /*
4235 Opaque image.
4236 */
4237 if (msl_info->image[n] == (Image *) NULL)
4238 {
cristyb988fe72009-09-16 01:01:10 +00004239 ThrowMSLException(OptionError,"NoImagesDefined",
4240 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004241 break;
4242 }
cristy269c9412011-10-13 23:41:15 +00004243 (void) QueryColorCompliance("none",AllCompliance,&target,
cristy9950d572011-10-01 18:22:35 +00004244 &exception);
cristy269c9412011-10-13 23:41:15 +00004245 (void) QueryColorCompliance("none",AllCompliance,&fill_color,
cristy9950d572011-10-01 18:22:35 +00004246 &exception);
cristy3ed852e2009-09-05 21:47:34 +00004247 if (attributes != (const xmlChar **) NULL)
4248 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4249 {
4250 keyword=(const char *) attributes[i++];
4251 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004252 msl_info->attributes[n],(const char *) attributes[i],
4253 &exception);
cristy3ed852e2009-09-05 21:47:34 +00004254 CloneString(&value,attribute);
4255 switch (*keyword)
4256 {
4257 case 'C':
4258 case 'c':
4259 {
4260 if (LocaleCompare(keyword,"channel") == 0)
4261 {
4262 option=ParseChannelOption(value);
4263 if (option < 0)
4264 ThrowMSLException(OptionError,"UnrecognizedChannelType",
4265 value);
4266 channel=(ChannelType) option;
4267 break;
4268 }
4269 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4270 keyword);
4271 break;
4272 }
4273 case 'F':
4274 case 'f':
4275 {
4276 if (LocaleCompare(keyword,"fill") == 0)
4277 {
cristy269c9412011-10-13 23:41:15 +00004278 (void) QueryColorCompliance(value,AllCompliance,
cristy9950d572011-10-01 18:22:35 +00004279 &fill_color,&exception);
cristy3ed852e2009-09-05 21:47:34 +00004280 break;
4281 }
4282 if (LocaleCompare(keyword,"fuzz") == 0)
4283 {
cristydbdd0e32011-11-04 23:29:40 +00004284 msl_info->image[n]->fuzz=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00004285 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004286 break;
4287 }
4288 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4289 keyword);
4290 break;
4291 }
4292 default:
4293 {
4294 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4295 keyword);
4296 break;
4297 }
4298 }
4299 }
cristybd5a96c2011-08-21 00:04:26 +00004300 channel_mask=SetPixelChannelMask(msl_info->image[n],channel);
cristyd42d9952011-07-08 14:21:50 +00004301 (void) OpaquePaintImage(msl_info->image[n],&target,&fill_color,
cristyc82a27b2011-10-21 01:07:16 +00004302 MagickFalse,msl_info->exception);
cristye2a912b2011-12-05 20:02:07 +00004303 (void) SetPixelChannelMapMask(msl_info->image[n],channel_mask);
cristy3ed852e2009-09-05 21:47:34 +00004304 break;
4305 }
4306 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4307 }
4308 case 'P':
4309 case 'p':
4310 {
cristyb988fe72009-09-16 01:01:10 +00004311 if (LocaleCompare((const char *) tag,"print") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004312 {
4313 if (attributes == (const xmlChar **) NULL)
4314 break;
4315 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4316 {
4317 keyword=(const char *) attributes[i++];
4318 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004319 msl_info->attributes[n],(const char *) attributes[i],
4320 &exception);
cristy3ed852e2009-09-05 21:47:34 +00004321 CloneString(&value,attribute);
4322 switch (*keyword)
4323 {
4324 case 'O':
4325 case 'o':
4326 {
4327 if (LocaleCompare(keyword,"output") == 0)
4328 {
cristyb51dff52011-05-19 16:55:47 +00004329 (void) FormatLocaleFile(stdout,"%s",value);
cristy3ed852e2009-09-05 21:47:34 +00004330 break;
4331 }
4332 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
4333 break;
4334 }
4335 default:
4336 {
4337 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
4338 break;
4339 }
4340 }
4341 }
4342 break;
4343 }
cristy4fa36e42009-09-18 14:24:06 +00004344 if (LocaleCompare((const char *) tag, "profile") == 0)
4345 {
cristy4fa36e42009-09-18 14:24:06 +00004346 if (msl_info->image[n] == (Image *) NULL)
4347 {
4348 ThrowMSLException(OptionError,"NoImagesDefined",
4349 (const char *) tag);
4350 break;
4351 }
4352 if (attributes == (const xmlChar **) NULL)
4353 break;
4354 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4355 {
4356 const char
4357 *name;
4358
4359 const StringInfo
4360 *profile;
4361
4362 Image
4363 *profile_image;
4364
4365 ImageInfo
4366 *profile_info;
4367
4368 keyword=(const char *) attributes[i++];
4369 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004370 msl_info->attributes[n],(const char *) attributes[i],
4371 &exception);
cristy4fa36e42009-09-18 14:24:06 +00004372 CloneString(&value,attribute);
4373 if (*keyword == '+')
4374 {
4375 /*
4376 Remove a profile from the image.
4377 */
4378 (void) ProfileImage(msl_info->image[n],keyword,
cristy092d71c2011-10-14 18:01:29 +00004379 (const unsigned char *) NULL,0,&exception);
cristy4fa36e42009-09-18 14:24:06 +00004380 continue;
4381 }
4382 /*
4383 Associate a profile with the image.
4384 */
4385 profile_info=CloneImageInfo(msl_info->image_info[n]);
4386 profile=GetImageProfile(msl_info->image[n],"iptc");
4387 if (profile != (StringInfo *) NULL)
4388 profile_info->profile=(void *) CloneStringInfo(profile);
4389 profile_image=GetImageCache(profile_info,keyword,&exception);
4390 profile_info=DestroyImageInfo(profile_info);
4391 if (profile_image == (Image *) NULL)
4392 {
4393 char
4394 name[MaxTextExtent],
4395 filename[MaxTextExtent];
4396
4397 register char
4398 *p;
4399
4400 StringInfo
4401 *profile;
4402
4403 (void) CopyMagickString(filename,keyword,MaxTextExtent);
4404 (void) CopyMagickString(name,keyword,MaxTextExtent);
4405 for (p=filename; *p != '\0'; p++)
4406 if ((*p == ':') && (IsPathDirectory(keyword) < 0) &&
4407 (IsPathAccessible(keyword) == MagickFalse))
4408 {
4409 register char
4410 *q;
4411
4412 /*
4413 Look for profile name (e.g. name:profile).
4414 */
4415 (void) CopyMagickString(name,filename,(size_t)
4416 (p-filename+1));
4417 for (q=filename; *q != '\0'; q++)
4418 *q=(*++p);
4419 break;
4420 }
4421 profile=FileToStringInfo(filename,~0UL,&exception);
4422 if (profile != (StringInfo *) NULL)
4423 {
4424 (void) ProfileImage(msl_info->image[n],name,
cristybb503372010-05-27 20:51:26 +00004425 GetStringInfoDatum(profile),(size_t)
cristy3fac9ec2011-11-17 18:04:39 +00004426 GetStringInfoLength(profile),&exception);
cristy4fa36e42009-09-18 14:24:06 +00004427 profile=DestroyStringInfo(profile);
4428 }
4429 continue;
4430 }
4431 ResetImageProfileIterator(profile_image);
4432 name=GetNextImageProfile(profile_image);
4433 while (name != (const char *) NULL)
4434 {
4435 profile=GetImageProfile(profile_image,name);
4436 if (profile != (StringInfo *) NULL)
4437 (void) ProfileImage(msl_info->image[n],name,
cristybb503372010-05-27 20:51:26 +00004438 GetStringInfoDatum(profile),(size_t)
cristy3fac9ec2011-11-17 18:04:39 +00004439 GetStringInfoLength(profile),&exception);
cristy4fa36e42009-09-18 14:24:06 +00004440 name=GetNextImageProfile(profile_image);
4441 }
4442 profile_image=DestroyImage(profile_image);
4443 }
4444 break;
4445 }
cristy3ed852e2009-09-05 21:47:34 +00004446 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4447 }
4448 case 'Q':
4449 case 'q':
4450 {
cristyb988fe72009-09-16 01:01:10 +00004451 if (LocaleCompare((const char *) tag,"quantize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004452 {
4453 QuantizeInfo
4454 quantize_info;
4455
4456 /*
4457 Quantize image.
4458 */
4459 if (msl_info->image[n] == (Image *) NULL)
4460 {
cristyb988fe72009-09-16 01:01:10 +00004461 ThrowMSLException(OptionError,"NoImagesDefined",
4462 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004463 break;
4464 }
4465 GetQuantizeInfo(&quantize_info);
4466 if (attributes != (const xmlChar **) NULL)
4467 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4468 {
4469 keyword=(const char *) attributes[i++];
4470 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004471 msl_info->attributes[n],(const char *) attributes[i],
4472 &exception);
cristy3ed852e2009-09-05 21:47:34 +00004473 CloneString(&value,attribute);
4474 switch (*keyword)
4475 {
4476 case 'C':
4477 case 'c':
4478 {
4479 if (LocaleCompare(keyword,"colors") == 0)
4480 {
cristyf2f27272009-12-17 14:48:46 +00004481 quantize_info.number_colors=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004482 break;
4483 }
4484 if (LocaleCompare(keyword,"colorspace") == 0)
4485 {
cristy042ee782011-04-22 18:48:30 +00004486 option=ParseCommandOption(MagickColorspaceOptions,
cristy3ed852e2009-09-05 21:47:34 +00004487 MagickFalse,value);
4488 if (option < 0)
4489 ThrowMSLException(OptionError,
4490 "UnrecognizedColorspaceType",value);
4491 quantize_info.colorspace=(ColorspaceType) option;
4492 break;
4493 }
4494 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4495 keyword);
4496 break;
4497 }
4498 case 'D':
4499 case 'd':
4500 {
4501 if (LocaleCompare(keyword,"dither") == 0)
4502 {
cristy042ee782011-04-22 18:48:30 +00004503 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004504 value);
4505 if (option < 0)
4506 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4507 value);
4508 quantize_info.dither=(MagickBooleanType) option;
4509 break;
4510 }
4511 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4512 keyword);
4513 break;
4514 }
4515 case 'M':
4516 case 'm':
4517 {
4518 if (LocaleCompare(keyword,"measure") == 0)
4519 {
cristy042ee782011-04-22 18:48:30 +00004520 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004521 value);
4522 if (option < 0)
4523 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4524 value);
4525 quantize_info.measure_error=(MagickBooleanType) option;
4526 break;
4527 }
4528 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4529 keyword);
4530 break;
4531 }
4532 case 'T':
4533 case 't':
4534 {
4535 if (LocaleCompare(keyword,"treedepth") == 0)
4536 {
cristyf2f27272009-12-17 14:48:46 +00004537 quantize_info.tree_depth=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004538 break;
4539 }
4540 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4541 keyword);
4542 break;
4543 }
4544 default:
4545 {
4546 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4547 keyword);
4548 break;
4549 }
4550 }
4551 }
cristy018f07f2011-09-04 21:15:19 +00004552 (void) QuantizeImage(&quantize_info,msl_info->image[n],&exception);
cristy3ed852e2009-09-05 21:47:34 +00004553 break;
4554 }
cristyb988fe72009-09-16 01:01:10 +00004555 if (LocaleCompare((const char *) tag,"query-font-metrics") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004556 {
4557 char
4558 text[MaxTextExtent];
4559
4560 MagickBooleanType
4561 status;
4562
4563 TypeMetric
4564 metrics;
4565
4566 /*
4567 Query font metrics.
4568 */
4569 draw_info=CloneDrawInfo(msl_info->image_info[n],
4570 msl_info->draw_info[n]);
4571 angle=0.0;
4572 current=draw_info->affine;
4573 GetAffineMatrix(&affine);
4574 if (attributes != (const xmlChar **) NULL)
4575 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4576 {
4577 keyword=(const char *) attributes[i++];
4578 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004579 msl_info->attributes[n],(const char *) attributes[i],
4580 &exception);
cristy3ed852e2009-09-05 21:47:34 +00004581 CloneString(&value,attribute);
4582 switch (*keyword)
4583 {
4584 case 'A':
4585 case 'a':
4586 {
4587 if (LocaleCompare(keyword,"affine") == 0)
4588 {
4589 char
4590 *p;
4591
4592 p=value;
cristydbdd0e32011-11-04 23:29:40 +00004593 draw_info->affine.sx=StringToDouble(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004594 if (*p ==',')
4595 p++;
cristydbdd0e32011-11-04 23:29:40 +00004596 draw_info->affine.rx=StringToDouble(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004597 if (*p ==',')
4598 p++;
cristydbdd0e32011-11-04 23:29:40 +00004599 draw_info->affine.ry=StringToDouble(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004600 if (*p ==',')
4601 p++;
cristydbdd0e32011-11-04 23:29:40 +00004602 draw_info->affine.sy=StringToDouble(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004603 if (*p ==',')
4604 p++;
cristydbdd0e32011-11-04 23:29:40 +00004605 draw_info->affine.tx=StringToDouble(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004606 if (*p ==',')
4607 p++;
cristydbdd0e32011-11-04 23:29:40 +00004608 draw_info->affine.ty=StringToDouble(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004609 break;
4610 }
4611 if (LocaleCompare(keyword,"align") == 0)
4612 {
cristy042ee782011-04-22 18:48:30 +00004613 option=ParseCommandOption(MagickAlignOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004614 value);
4615 if (option < 0)
4616 ThrowMSLException(OptionError,"UnrecognizedAlignType",
4617 value);
4618 draw_info->align=(AlignType) option;
4619 break;
4620 }
4621 if (LocaleCompare(keyword,"antialias") == 0)
4622 {
cristy042ee782011-04-22 18:48:30 +00004623 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004624 value);
4625 if (option < 0)
4626 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4627 value);
4628 draw_info->stroke_antialias=(MagickBooleanType) option;
4629 draw_info->text_antialias=(MagickBooleanType) option;
4630 break;
4631 }
4632 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4633 keyword);
4634 break;
4635 }
4636 case 'D':
4637 case 'd':
4638 {
4639 if (LocaleCompare(keyword,"density") == 0)
4640 {
4641 CloneString(&draw_info->density,value);
4642 break;
4643 }
4644 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4645 keyword);
4646 break;
4647 }
4648 case 'E':
4649 case 'e':
4650 {
4651 if (LocaleCompare(keyword,"encoding") == 0)
4652 {
4653 CloneString(&draw_info->encoding,value);
4654 break;
4655 }
4656 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4657 keyword);
4658 break;
4659 }
4660 case 'F':
4661 case 'f':
4662 {
4663 if (LocaleCompare(keyword, "fill") == 0)
4664 {
cristy9950d572011-10-01 18:22:35 +00004665 (void) QueryColorCompliance(value,AllCompliance,
4666 &draw_info->fill,&exception);
cristy3ed852e2009-09-05 21:47:34 +00004667 break;
4668 }
4669 if (LocaleCompare(keyword,"family") == 0)
4670 {
4671 CloneString(&draw_info->family,value);
4672 break;
4673 }
4674 if (LocaleCompare(keyword,"font") == 0)
4675 {
4676 CloneString(&draw_info->font,value);
4677 break;
4678 }
4679 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4680 keyword);
4681 break;
4682 }
4683 case 'G':
4684 case 'g':
4685 {
4686 if (LocaleCompare(keyword,"geometry") == 0)
4687 {
4688 flags=ParsePageGeometry(msl_info->image[n],value,
4689 &geometry,&exception);
4690 if ((flags & HeightValue) == 0)
4691 geometry.height=geometry.width;
4692 break;
4693 }
4694 if (LocaleCompare(keyword,"gravity") == 0)
4695 {
cristy042ee782011-04-22 18:48:30 +00004696 option=ParseCommandOption(MagickGravityOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004697 value);
4698 if (option < 0)
4699 ThrowMSLException(OptionError,"UnrecognizedGravityType",
4700 value);
4701 draw_info->gravity=(GravityType) option;
4702 break;
4703 }
4704 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4705 keyword);
4706 break;
4707 }
4708 case 'P':
4709 case 'p':
4710 {
4711 if (LocaleCompare(keyword,"pointsize") == 0)
4712 {
cristydbdd0e32011-11-04 23:29:40 +00004713 draw_info->pointsize=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00004714 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004715 break;
4716 }
4717 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4718 keyword);
4719 break;
4720 }
4721 case 'R':
4722 case 'r':
4723 {
4724 if (LocaleCompare(keyword,"rotate") == 0)
4725 {
cristydbdd0e32011-11-04 23:29:40 +00004726 angle=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004727 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
4728 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
4729 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
4730 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
4731 break;
4732 }
4733 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4734 keyword);
4735 break;
4736 }
4737 case 'S':
4738 case 's':
4739 {
4740 if (LocaleCompare(keyword,"scale") == 0)
4741 {
4742 flags=ParseGeometry(value,&geometry_info);
4743 if ((flags & SigmaValue) == 0)
4744 geometry_info.sigma=1.0;
4745 affine.sx=geometry_info.rho;
4746 affine.sy=geometry_info.sigma;
4747 break;
4748 }
4749 if (LocaleCompare(keyword,"skewX") == 0)
4750 {
cristydbdd0e32011-11-04 23:29:40 +00004751 angle=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004752 affine.ry=cos(DegreesToRadians(fmod(angle,360.0)));
4753 break;
4754 }
4755 if (LocaleCompare(keyword,"skewY") == 0)
4756 {
cristydbdd0e32011-11-04 23:29:40 +00004757 angle=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004758 affine.rx=cos(DegreesToRadians(fmod(angle,360.0)));
4759 break;
4760 }
4761 if (LocaleCompare(keyword,"stretch") == 0)
4762 {
cristy9950d572011-10-01 18:22:35 +00004763 option=ParseCommandOption(MagickStretchOptions,
4764 MagickFalse,value);
cristy3ed852e2009-09-05 21:47:34 +00004765 if (option < 0)
4766 ThrowMSLException(OptionError,"UnrecognizedStretchType",
4767 value);
4768 draw_info->stretch=(StretchType) option;
4769 break;
4770 }
4771 if (LocaleCompare(keyword, "stroke") == 0)
4772 {
cristy9950d572011-10-01 18:22:35 +00004773 (void) QueryColorCompliance(value,AllCompliance,
4774 &draw_info->stroke,&exception);
cristy3ed852e2009-09-05 21:47:34 +00004775 break;
4776 }
4777 if (LocaleCompare(keyword,"strokewidth") == 0)
4778 {
cristyf2f27272009-12-17 14:48:46 +00004779 draw_info->stroke_width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004780 break;
4781 }
4782 if (LocaleCompare(keyword,"style") == 0)
4783 {
cristy042ee782011-04-22 18:48:30 +00004784 option=ParseCommandOption(MagickStyleOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004785 value);
4786 if (option < 0)
4787 ThrowMSLException(OptionError,"UnrecognizedStyleType",
4788 value);
4789 draw_info->style=(StyleType) option;
4790 break;
4791 }
4792 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4793 keyword);
4794 break;
4795 }
4796 case 'T':
4797 case 't':
4798 {
4799 if (LocaleCompare(keyword,"text") == 0)
4800 {
4801 CloneString(&draw_info->text,value);
4802 break;
4803 }
4804 if (LocaleCompare(keyword,"translate") == 0)
4805 {
4806 flags=ParseGeometry(value,&geometry_info);
4807 if ((flags & SigmaValue) == 0)
4808 geometry_info.sigma=1.0;
4809 affine.tx=geometry_info.rho;
4810 affine.ty=geometry_info.sigma;
4811 break;
4812 }
4813 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4814 keyword);
4815 break;
4816 }
4817 case 'U':
4818 case 'u':
4819 {
4820 if (LocaleCompare(keyword, "undercolor") == 0)
4821 {
cristy9950d572011-10-01 18:22:35 +00004822 (void) QueryColorCompliance(value,AllCompliance,
4823 &draw_info->undercolor,&exception);
cristy3ed852e2009-09-05 21:47:34 +00004824 break;
4825 }
4826 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4827 keyword);
4828 break;
4829 }
4830 case 'W':
4831 case 'w':
4832 {
4833 if (LocaleCompare(keyword,"weight") == 0)
4834 {
cristyf2f27272009-12-17 14:48:46 +00004835 draw_info->weight=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004836 break;
4837 }
4838 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4839 keyword);
4840 break;
4841 }
4842 case 'X':
4843 case 'x':
4844 {
4845 if (LocaleCompare(keyword,"x") == 0)
4846 {
cristyf2f27272009-12-17 14:48:46 +00004847 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004848 break;
4849 }
4850 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4851 keyword);
4852 break;
4853 }
4854 case 'Y':
4855 case 'y':
4856 {
4857 if (LocaleCompare(keyword,"y") == 0)
4858 {
cristyf2f27272009-12-17 14:48:46 +00004859 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004860 break;
4861 }
4862 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4863 keyword);
4864 break;
4865 }
4866 default:
4867 {
4868 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4869 keyword);
4870 break;
4871 }
4872 }
4873 }
cristyb51dff52011-05-19 16:55:47 +00004874 (void) FormatLocaleString(text,MaxTextExtent,
cristye8c25f92010-06-03 00:53:06 +00004875 "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,(double)
4876 geometry.height,(double) geometry.x,(double) geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00004877 CloneString(&draw_info->geometry,text);
cristyef7c8a52010-10-10 13:46:51 +00004878 draw_info->affine.sx=affine.sx*current.sx+affine.ry*current.rx;
4879 draw_info->affine.rx=affine.rx*current.sx+affine.sy*current.rx;
4880 draw_info->affine.ry=affine.sx*current.ry+affine.ry*current.sy;
4881 draw_info->affine.sy=affine.rx*current.ry+affine.sy*current.sy;
4882 draw_info->affine.tx=affine.sx*current.tx+affine.ry*current.ty+
4883 affine.tx;
4884 draw_info->affine.ty=affine.rx*current.tx+affine.sy*current.ty+
4885 affine.ty;
cristy5cbc0162011-08-29 00:36:28 +00004886 status=GetTypeMetrics(msl_info->attributes[n],draw_info,&metrics,
cristyc82a27b2011-10-21 01:07:16 +00004887 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00004888 if (status != MagickFalse)
4889 {
4890 Image
4891 *image;
4892
4893 image=msl_info->attributes[n];
cristy8cd5b312010-01-07 01:10:24 +00004894 FormatImageProperty(image,"msl:font-metrics.pixels_per_em.x",
cristye7f51092010-01-17 00:39:37 +00004895 "%g",metrics.pixels_per_em.x);
cristy8cd5b312010-01-07 01:10:24 +00004896 FormatImageProperty(image,"msl:font-metrics.pixels_per_em.y",
cristye7f51092010-01-17 00:39:37 +00004897 "%g",metrics.pixels_per_em.y);
4898 FormatImageProperty(image,"msl:font-metrics.ascent","%g",
cristy3ed852e2009-09-05 21:47:34 +00004899 metrics.ascent);
cristye7f51092010-01-17 00:39:37 +00004900 FormatImageProperty(image,"msl:font-metrics.descent","%g",
cristy3ed852e2009-09-05 21:47:34 +00004901 metrics.descent);
cristye7f51092010-01-17 00:39:37 +00004902 FormatImageProperty(image,"msl:font-metrics.width","%g",
cristy3ed852e2009-09-05 21:47:34 +00004903 metrics.width);
cristye7f51092010-01-17 00:39:37 +00004904 FormatImageProperty(image,"msl:font-metrics.height","%g",
cristy3ed852e2009-09-05 21:47:34 +00004905 metrics.height);
cristye7f51092010-01-17 00:39:37 +00004906 FormatImageProperty(image,"msl:font-metrics.max_advance","%g",
cristy3ed852e2009-09-05 21:47:34 +00004907 metrics.max_advance);
cristye7f51092010-01-17 00:39:37 +00004908 FormatImageProperty(image,"msl:font-metrics.bounds.x1","%g",
cristy3ed852e2009-09-05 21:47:34 +00004909 metrics.bounds.x1);
cristye7f51092010-01-17 00:39:37 +00004910 FormatImageProperty(image,"msl:font-metrics.bounds.y1","%g",
cristy3ed852e2009-09-05 21:47:34 +00004911 metrics.bounds.y1);
cristye7f51092010-01-17 00:39:37 +00004912 FormatImageProperty(image,"msl:font-metrics.bounds.x2","%g",
cristy3ed852e2009-09-05 21:47:34 +00004913 metrics.bounds.x2);
cristye7f51092010-01-17 00:39:37 +00004914 FormatImageProperty(image,"msl:font-metrics.bounds.y2","%g",
cristy3ed852e2009-09-05 21:47:34 +00004915 metrics.bounds.y2);
cristye7f51092010-01-17 00:39:37 +00004916 FormatImageProperty(image,"msl:font-metrics.origin.x","%g",
cristy3ed852e2009-09-05 21:47:34 +00004917 metrics.origin.x);
cristye7f51092010-01-17 00:39:37 +00004918 FormatImageProperty(image,"msl:font-metrics.origin.y","%g",
cristy3ed852e2009-09-05 21:47:34 +00004919 metrics.origin.y);
4920 }
4921 draw_info=DestroyDrawInfo(draw_info);
4922 break;
4923 }
4924 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4925 }
4926 case 'R':
4927 case 'r':
4928 {
cristyb988fe72009-09-16 01:01:10 +00004929 if (LocaleCompare((const char *) tag,"raise") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004930 {
4931 MagickBooleanType
4932 raise;
4933
4934 /*
4935 Raise image.
4936 */
4937 if (msl_info->image[n] == (Image *) NULL)
4938 {
cristyb988fe72009-09-16 01:01:10 +00004939 ThrowMSLException(OptionError,"NoImagesDefined",
4940 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004941 break;
4942 }
4943 raise=MagickFalse;
4944 SetGeometry(msl_info->image[n],&geometry);
4945 if (attributes != (const xmlChar **) NULL)
4946 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4947 {
4948 keyword=(const char *) attributes[i++];
4949 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004950 msl_info->attributes[n],(const char *) attributes[i],
4951 &exception);
cristy3ed852e2009-09-05 21:47:34 +00004952 CloneString(&value,attribute);
4953 switch (*keyword)
4954 {
4955 case 'G':
4956 case 'g':
4957 {
4958 if (LocaleCompare(keyword,"geometry") == 0)
4959 {
4960 flags=ParsePageGeometry(msl_info->image[n],value,
4961 &geometry,&exception);
4962 if ((flags & HeightValue) == 0)
4963 geometry.height=geometry.width;
4964 break;
4965 }
4966 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4967 keyword);
4968 break;
4969 }
4970 case 'H':
4971 case 'h':
4972 {
4973 if (LocaleCompare(keyword,"height") == 0)
4974 {
cristyf2f27272009-12-17 14:48:46 +00004975 geometry.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004976 break;
4977 }
4978 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4979 keyword);
4980 break;
4981 }
4982 case 'R':
4983 case 'r':
4984 {
4985 if (LocaleCompare(keyword,"raise") == 0)
4986 {
cristy042ee782011-04-22 18:48:30 +00004987 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004988 value);
4989 if (option < 0)
4990 ThrowMSLException(OptionError,"UnrecognizedNoiseType",
4991 value);
4992 raise=(MagickBooleanType) option;
4993 break;
4994 }
4995 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4996 keyword);
4997 break;
4998 }
4999 case 'W':
5000 case 'w':
5001 {
5002 if (LocaleCompare(keyword,"width") == 0)
5003 {
cristyf2f27272009-12-17 14:48:46 +00005004 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005005 break;
5006 }
5007 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5008 keyword);
5009 break;
5010 }
5011 default:
5012 {
5013 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5014 keyword);
5015 break;
5016 }
5017 }
5018 }
cristy6170ac32011-08-28 14:15:37 +00005019 (void) RaiseImage(msl_info->image[n],&geometry,raise,
cristyc82a27b2011-10-21 01:07:16 +00005020 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00005021 break;
5022 }
cristyb988fe72009-09-16 01:01:10 +00005023 if (LocaleCompare((const char *) tag,"read") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005024 {
5025 if (attributes == (const xmlChar **) NULL)
5026 break;
5027 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5028 {
5029 keyword=(const char *) attributes[i++];
5030 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005031 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00005032 switch (*keyword)
5033 {
5034 case 'F':
5035 case 'f':
5036 {
5037 if (LocaleCompare(keyword,"filename") == 0)
5038 {
5039 Image
5040 *image;
5041
5042 (void) CopyMagickString(msl_info->image_info[n]->filename,
5043 value,MaxTextExtent);
5044 image=ReadImage(msl_info->image_info[n],&exception);
5045 CatchException(&exception);
5046 if (image == (Image *) NULL)
5047 continue;
5048 AppendImageToList(&msl_info->image[n],image);
5049 break;
5050 }
cristy4582cbb2009-09-23 00:35:43 +00005051 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00005052 break;
5053 }
5054 default:
5055 {
cristy4582cbb2009-09-23 00:35:43 +00005056 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00005057 break;
5058 }
5059 }
5060 }
5061 break;
5062 }
cristyb988fe72009-09-16 01:01:10 +00005063 if (LocaleCompare((const char *) tag,"reduce-noise") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005064 {
5065 Image
5066 *paint_image;
5067
5068 /*
5069 Reduce-noise image.
5070 */
5071 if (msl_info->image[n] == (Image *) NULL)
5072 {
cristyb988fe72009-09-16 01:01:10 +00005073 ThrowMSLException(OptionError,"NoImagesDefined",
5074 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005075 break;
5076 }
5077 if (attributes != (const xmlChar **) NULL)
5078 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5079 {
5080 keyword=(const char *) attributes[i++];
5081 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005082 msl_info->attributes[n],(const char *) attributes[i],
5083 &exception);
cristy3ed852e2009-09-05 21:47:34 +00005084 CloneString(&value,attribute);
5085 switch (*keyword)
5086 {
5087 case 'G':
5088 case 'g':
5089 {
5090 if (LocaleCompare(keyword,"geometry") == 0)
5091 {
5092 flags=ParseGeometry(value,&geometry_info);
5093 if ((flags & SigmaValue) == 0)
5094 geometry_info.sigma=1.0;
5095 break;
5096 }
5097 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5098 keyword);
5099 break;
5100 }
5101 case 'R':
5102 case 'r':
5103 {
5104 if (LocaleCompare(keyword,"radius") == 0)
5105 {
cristydbdd0e32011-11-04 23:29:40 +00005106 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00005107 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005108 break;
5109 }
5110 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5111 keyword);
5112 break;
5113 }
5114 default:
5115 {
5116 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5117 keyword);
5118 break;
5119 }
5120 }
5121 }
cristy733678d2011-03-18 21:29:28 +00005122 paint_image=StatisticImage(msl_info->image[n],NonpeakStatistic,
cristy95c38342011-03-18 22:39:51 +00005123 (size_t) geometry_info.rho,(size_t) geometry_info.sigma,
cristyc82a27b2011-10-21 01:07:16 +00005124 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00005125 if (paint_image == (Image *) NULL)
5126 break;
5127 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5128 msl_info->image[n]=paint_image;
5129 break;
5130 }
cristyb988fe72009-09-16 01:01:10 +00005131 else if (LocaleCompare((const char *) tag,"repage") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005132 {
5133 /* init the values */
5134 width=msl_info->image[n]->page.width;
5135 height=msl_info->image[n]->page.height;
5136 x=msl_info->image[n]->page.x;
5137 y=msl_info->image[n]->page.y;
5138
5139 if (msl_info->image[n] == (Image *) NULL)
5140 {
cristyb988fe72009-09-16 01:01:10 +00005141 ThrowMSLException(OptionError,"NoImagesDefined",
5142 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005143 break;
5144 }
5145 if (attributes == (const xmlChar **) NULL)
5146 break;
5147 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5148 {
5149 keyword=(const char *) attributes[i++];
5150 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005151 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00005152 switch (*keyword)
5153 {
5154 case 'G':
5155 case 'g':
5156 {
5157 if (LocaleCompare(keyword,"geometry") == 0)
5158 {
5159 int
5160 flags;
5161
5162 RectangleInfo
5163 geometry;
5164
5165 flags=ParseAbsoluteGeometry(value,&geometry);
5166 if ((flags & WidthValue) != 0)
5167 {
5168 if ((flags & HeightValue) == 0)
5169 geometry.height=geometry.width;
5170 width=geometry.width;
5171 height=geometry.height;
5172 }
5173 if ((flags & AspectValue) != 0)
5174 {
5175 if ((flags & XValue) != 0)
5176 x+=geometry.x;
5177 if ((flags & YValue) != 0)
5178 y+=geometry.y;
5179 }
5180 else
5181 {
5182 if ((flags & XValue) != 0)
5183 {
5184 x=geometry.x;
5185 if ((width == 0) && (geometry.x > 0))
5186 width=msl_info->image[n]->columns+geometry.x;
5187 }
5188 if ((flags & YValue) != 0)
5189 {
5190 y=geometry.y;
5191 if ((height == 0) && (geometry.y > 0))
5192 height=msl_info->image[n]->rows+geometry.y;
5193 }
5194 }
5195 break;
5196 }
5197 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5198 break;
5199 }
5200 case 'H':
5201 case 'h':
5202 {
5203 if (LocaleCompare(keyword,"height") == 0)
5204 {
cristyf2f27272009-12-17 14:48:46 +00005205 height = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005206 break;
5207 }
5208 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5209 break;
5210 }
5211 case 'W':
5212 case 'w':
5213 {
5214 if (LocaleCompare(keyword,"width") == 0)
5215 {
cristyf2f27272009-12-17 14:48:46 +00005216 width = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005217 break;
5218 }
5219 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5220 break;
5221 }
5222 case 'X':
5223 case 'x':
5224 {
5225 if (LocaleCompare(keyword,"x") == 0)
5226 {
cristyf2f27272009-12-17 14:48:46 +00005227 x = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005228 break;
5229 }
5230 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5231 break;
5232 }
5233 case 'Y':
5234 case 'y':
5235 {
5236 if (LocaleCompare(keyword,"y") == 0)
5237 {
cristyf2f27272009-12-17 14:48:46 +00005238 y = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005239 break;
5240 }
5241 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5242 break;
5243 }
5244 default:
5245 {
5246 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5247 break;
5248 }
5249 }
5250 }
5251
cristyb988fe72009-09-16 01:01:10 +00005252 msl_info->image[n]->page.width=width;
5253 msl_info->image[n]->page.height=height;
5254 msl_info->image[n]->page.x=x;
5255 msl_info->image[n]->page.y=y;
cristy3ed852e2009-09-05 21:47:34 +00005256 break;
5257 }
cristyb988fe72009-09-16 01:01:10 +00005258 else if (LocaleCompare((const char *) tag,"resample") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005259 {
5260 double
5261 x_resolution,
5262 y_resolution;
5263
5264 if (msl_info->image[n] == (Image *) NULL)
5265 {
cristyb988fe72009-09-16 01:01:10 +00005266 ThrowMSLException(OptionError,"NoImagesDefined",
5267 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005268 break;
5269 }
5270 if (attributes == (const xmlChar **) NULL)
5271 break;
5272 x_resolution=DefaultResolution;
5273 y_resolution=DefaultResolution;
5274 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5275 {
5276 keyword=(const char *) attributes[i++];
5277 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005278 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00005279 switch (*keyword)
5280 {
5281 case 'b':
5282 {
5283 if (LocaleCompare(keyword,"blur") == 0)
5284 {
cristydbdd0e32011-11-04 23:29:40 +00005285 msl_info->image[n]->blur=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00005286 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005287 break;
5288 }
5289 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5290 break;
5291 }
5292 case 'G':
5293 case 'g':
5294 {
5295 if (LocaleCompare(keyword,"geometry") == 0)
5296 {
cristybb503372010-05-27 20:51:26 +00005297 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00005298 flags;
5299
5300 flags=ParseGeometry(value,&geometry_info);
5301 if ((flags & SigmaValue) == 0)
5302 geometry_info.sigma*=geometry_info.rho;
5303 x_resolution=geometry_info.rho;
5304 y_resolution=geometry_info.sigma;
5305 break;
5306 }
5307 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5308 break;
5309 }
5310 case 'X':
5311 case 'x':
5312 {
5313 if (LocaleCompare(keyword,"x-resolution") == 0)
5314 {
cristydbdd0e32011-11-04 23:29:40 +00005315 x_resolution=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005316 break;
5317 }
5318 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5319 break;
5320 }
5321 case 'Y':
5322 case 'y':
5323 {
5324 if (LocaleCompare(keyword,"y-resolution") == 0)
5325 {
cristydbdd0e32011-11-04 23:29:40 +00005326 y_resolution=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005327 break;
5328 }
5329 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5330 break;
5331 }
5332 default:
5333 {
5334 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5335 break;
5336 }
5337 }
5338 }
5339 /*
5340 Resample image.
5341 */
5342 {
5343 double
5344 factor;
5345
5346 Image
5347 *resample_image;
5348
5349 factor=1.0;
5350 if (msl_info->image[n]->units == PixelsPerCentimeterResolution)
5351 factor=2.54;
cristybb503372010-05-27 20:51:26 +00005352 width=(size_t) (x_resolution*msl_info->image[n]->columns/
cristy2a11bef2011-10-28 18:33:11 +00005353 (factor*(msl_info->image[n]->resolution.x == 0.0 ? DefaultResolution :
5354 msl_info->image[n]->resolution.x))+0.5);
cristybb503372010-05-27 20:51:26 +00005355 height=(size_t) (y_resolution*msl_info->image[n]->rows/
cristy2a11bef2011-10-28 18:33:11 +00005356 (factor*(msl_info->image[n]->resolution.y == 0.0 ? DefaultResolution :
5357 msl_info->image[n]->resolution.y))+0.5);
cristy3ed852e2009-09-05 21:47:34 +00005358 resample_image=ResizeImage(msl_info->image[n],width,height,
5359 msl_info->image[n]->filter,msl_info->image[n]->blur,
cristyc82a27b2011-10-21 01:07:16 +00005360 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00005361 if (resample_image == (Image *) NULL)
5362 break;
5363 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5364 msl_info->image[n]=resample_image;
5365 }
5366 break;
5367 }
cristyb988fe72009-09-16 01:01:10 +00005368 if (LocaleCompare((const char *) tag,"resize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005369 {
5370 double
5371 blur;
5372
5373 FilterTypes
5374 filter;
5375
5376 Image
5377 *resize_image;
5378
5379 /*
5380 Resize image.
5381 */
5382 if (msl_info->image[n] == (Image *) NULL)
5383 {
cristyb988fe72009-09-16 01:01:10 +00005384 ThrowMSLException(OptionError,"NoImagesDefined",
5385 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005386 break;
5387 }
5388 filter=UndefinedFilter;
5389 blur=1.0;
5390 if (attributes != (const xmlChar **) NULL)
5391 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5392 {
5393 keyword=(const char *) attributes[i++];
5394 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005395 msl_info->attributes[n],(const char *) attributes[i],
5396 &exception);
cristy3ed852e2009-09-05 21:47:34 +00005397 CloneString(&value,attribute);
5398 switch (*keyword)
5399 {
5400 case 'F':
5401 case 'f':
5402 {
5403 if (LocaleCompare(keyword,"filter") == 0)
5404 {
cristy042ee782011-04-22 18:48:30 +00005405 option=ParseCommandOption(MagickFilterOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00005406 value);
5407 if (option < 0)
5408 ThrowMSLException(OptionError,"UnrecognizedNoiseType",
5409 value);
5410 filter=(FilterTypes) option;
5411 break;
5412 }
5413 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5414 keyword);
5415 break;
5416 }
5417 case 'G':
5418 case 'g':
5419 {
5420 if (LocaleCompare(keyword,"geometry") == 0)
5421 {
5422 flags=ParseRegionGeometry(msl_info->image[n],value,
5423 &geometry,&exception);
5424 break;
5425 }
5426 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5427 keyword);
5428 break;
5429 }
5430 case 'H':
5431 case 'h':
5432 {
5433 if (LocaleCompare(keyword,"height") == 0)
5434 {
cristye27293e2009-12-18 02:53:20 +00005435 geometry.height=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005436 break;
5437 }
5438 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5439 keyword);
5440 break;
5441 }
5442 case 'S':
5443 case 's':
5444 {
5445 if (LocaleCompare(keyword,"support") == 0)
5446 {
cristydbdd0e32011-11-04 23:29:40 +00005447 blur=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005448 break;
5449 }
5450 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5451 keyword);
5452 break;
5453 }
5454 case 'W':
5455 case 'w':
5456 {
5457 if (LocaleCompare(keyword,"width") == 0)
5458 {
cristyf2f27272009-12-17 14:48:46 +00005459 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005460 break;
5461 }
5462 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5463 keyword);
5464 break;
5465 }
5466 default:
5467 {
5468 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5469 keyword);
5470 break;
5471 }
5472 }
5473 }
5474 resize_image=ResizeImage(msl_info->image[n],geometry.width,
cristyc82a27b2011-10-21 01:07:16 +00005475 geometry.height,filter,blur,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00005476 if (resize_image == (Image *) NULL)
5477 break;
5478 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5479 msl_info->image[n]=resize_image;
5480 break;
5481 }
cristyb988fe72009-09-16 01:01:10 +00005482 if (LocaleCompare((const char *) tag,"roll") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005483 {
5484 Image
5485 *roll_image;
5486
5487 /*
5488 Roll image.
5489 */
5490 if (msl_info->image[n] == (Image *) NULL)
5491 {
cristyb988fe72009-09-16 01:01:10 +00005492 ThrowMSLException(OptionError,"NoImagesDefined",
5493 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005494 break;
5495 }
5496 SetGeometry(msl_info->image[n],&geometry);
5497 if (attributes != (const xmlChar **) NULL)
5498 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5499 {
5500 keyword=(const char *) attributes[i++];
5501 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005502 msl_info->attributes[n],(const char *) attributes[i],
5503 &exception);
cristy3ed852e2009-09-05 21:47:34 +00005504 CloneString(&value,attribute);
5505 switch (*keyword)
5506 {
5507 case 'G':
5508 case 'g':
5509 {
5510 if (LocaleCompare(keyword,"geometry") == 0)
5511 {
5512 flags=ParsePageGeometry(msl_info->image[n],value,
5513 &geometry,&exception);
5514 if ((flags & HeightValue) == 0)
5515 geometry.height=geometry.width;
5516 break;
5517 }
5518 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5519 keyword);
5520 break;
5521 }
5522 case 'X':
5523 case 'x':
5524 {
5525 if (LocaleCompare(keyword,"x") == 0)
5526 {
cristyf2f27272009-12-17 14:48:46 +00005527 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005528 break;
5529 }
5530 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5531 keyword);
5532 break;
5533 }
5534 case 'Y':
5535 case 'y':
5536 {
5537 if (LocaleCompare(keyword,"y") == 0)
5538 {
cristyf2f27272009-12-17 14:48:46 +00005539 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005540 break;
5541 }
5542 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5543 keyword);
5544 break;
5545 }
5546 default:
5547 {
5548 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5549 keyword);
5550 break;
5551 }
5552 }
5553 }
5554 roll_image=RollImage(msl_info->image[n],geometry.x,geometry.y,
cristyc82a27b2011-10-21 01:07:16 +00005555 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00005556 if (roll_image == (Image *) NULL)
5557 break;
5558 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5559 msl_info->image[n]=roll_image;
5560 break;
5561 }
cristyb988fe72009-09-16 01:01:10 +00005562 else if (LocaleCompare((const char *) tag,"roll") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005563 {
5564 /* init the values */
5565 width=msl_info->image[n]->columns;
5566 height=msl_info->image[n]->rows;
5567 x = y = 0;
5568
5569 if (msl_info->image[n] == (Image *) NULL)
5570 {
cristyb988fe72009-09-16 01:01:10 +00005571 ThrowMSLException(OptionError,"NoImagesDefined",
5572 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005573 break;
5574 }
5575 if (attributes == (const xmlChar **) NULL)
5576 break;
5577 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5578 {
5579 keyword=(const char *) attributes[i++];
5580 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005581 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00005582 switch (*keyword)
5583 {
5584 case 'G':
5585 case 'g':
5586 {
5587 if (LocaleCompare(keyword,"geometry") == 0)
5588 {
5589 (void) ParseMetaGeometry(value,&x,&y,&width,&height);
5590 break;
5591 }
5592 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5593 break;
5594 }
5595 case 'X':
5596 case 'x':
5597 {
5598 if (LocaleCompare(keyword,"x") == 0)
5599 {
cristyf2f27272009-12-17 14:48:46 +00005600 x = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005601 break;
5602 }
5603 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5604 break;
5605 }
5606 case 'Y':
5607 case 'y':
5608 {
5609 if (LocaleCompare(keyword,"y") == 0)
5610 {
cristyf2f27272009-12-17 14:48:46 +00005611 y = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005612 break;
5613 }
5614 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5615 break;
5616 }
5617 default:
5618 {
5619 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5620 break;
5621 }
5622 }
5623 }
5624
5625 /*
5626 process image.
5627 */
5628 {
5629 Image
5630 *newImage;
5631
cristyc82a27b2011-10-21 01:07:16 +00005632 newImage=RollImage(msl_info->image[n], x, y, msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00005633 if (newImage == (Image *) NULL)
5634 break;
5635 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5636 msl_info->image[n]=newImage;
5637 }
5638
5639 break;
5640 }
cristyb988fe72009-09-16 01:01:10 +00005641 if (LocaleCompare((const char *) tag,"rotate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005642 {
5643 Image
5644 *rotate_image;
5645
5646 /*
5647 Rotate image.
5648 */
5649 if (msl_info->image[n] == (Image *) NULL)
5650 {
cristyb988fe72009-09-16 01:01:10 +00005651 ThrowMSLException(OptionError,"NoImagesDefined",
5652 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005653 break;
5654 }
5655 if (attributes != (const xmlChar **) NULL)
5656 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5657 {
5658 keyword=(const char *) attributes[i++];
5659 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005660 msl_info->attributes[n],(const char *) attributes[i],
5661 &exception);
cristy3ed852e2009-09-05 21:47:34 +00005662 CloneString(&value,attribute);
5663 switch (*keyword)
5664 {
5665 case 'D':
5666 case 'd':
5667 {
5668 if (LocaleCompare(keyword,"degrees") == 0)
5669 {
cristydbdd0e32011-11-04 23:29:40 +00005670 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00005671 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005672 break;
5673 }
5674 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5675 keyword);
5676 break;
5677 }
5678 case 'G':
5679 case 'g':
5680 {
5681 if (LocaleCompare(keyword,"geometry") == 0)
5682 {
5683 flags=ParseGeometry(value,&geometry_info);
5684 if ((flags & SigmaValue) == 0)
5685 geometry_info.sigma=1.0;
5686 break;
5687 }
5688 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5689 keyword);
5690 break;
5691 }
5692 default:
5693 {
5694 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5695 keyword);
5696 break;
5697 }
5698 }
5699 }
5700 rotate_image=RotateImage(msl_info->image[n],geometry_info.rho,
cristyc82a27b2011-10-21 01:07:16 +00005701 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00005702 if (rotate_image == (Image *) NULL)
5703 break;
5704 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5705 msl_info->image[n]=rotate_image;
5706 break;
5707 }
cristyb988fe72009-09-16 01:01:10 +00005708 else if (LocaleCompare((const char *) tag,"rotate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005709 {
5710 /* init the values */
5711 double degrees = 0;
5712
5713 if (msl_info->image[n] == (Image *) NULL)
5714 {
cristyb988fe72009-09-16 01:01:10 +00005715 ThrowMSLException(OptionError,"NoImagesDefined",
5716 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005717 break;
5718 }
5719 if (attributes == (const xmlChar **) NULL)
cristy31939262009-09-15 00:23:11 +00005720 break;
cristy3ed852e2009-09-05 21:47:34 +00005721 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5722 {
5723 keyword=(const char *) attributes[i++];
5724 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005725 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00005726 switch (*keyword)
5727 {
5728 case 'D':
5729 case 'd':
5730 {
5731 if (LocaleCompare(keyword,"degrees") == 0)
5732 {
cristydbdd0e32011-11-04 23:29:40 +00005733 degrees = StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005734 break;
5735 }
5736 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5737 break;
5738 }
5739 default:
5740 {
5741 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5742 break;
5743 }
5744 }
5745 }
5746
5747 /*
5748 process image.
5749 */
5750 {
5751 Image
5752 *newImage;
5753
cristyc82a27b2011-10-21 01:07:16 +00005754 newImage=RotateImage(msl_info->image[n], degrees, msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00005755 if (newImage == (Image *) NULL)
5756 break;
5757 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5758 msl_info->image[n]=newImage;
5759 }
5760
5761 break;
5762 }
5763 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
5764 }
5765 case 'S':
5766 case 's':
5767 {
cristyb988fe72009-09-16 01:01:10 +00005768 if (LocaleCompare((const char *) tag,"sample") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005769 {
5770 Image
5771 *sample_image;
5772
5773 /*
5774 Sample image.
5775 */
5776 if (msl_info->image[n] == (Image *) NULL)
5777 {
cristyb988fe72009-09-16 01:01:10 +00005778 ThrowMSLException(OptionError,"NoImagesDefined",
5779 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005780 break;
5781 }
5782 if (attributes != (const xmlChar **) NULL)
5783 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5784 {
5785 keyword=(const char *) attributes[i++];
5786 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005787 msl_info->attributes[n],(const char *) attributes[i],
5788 &exception);
cristy3ed852e2009-09-05 21:47:34 +00005789 CloneString(&value,attribute);
5790 switch (*keyword)
5791 {
5792 case 'G':
5793 case 'g':
5794 {
5795 if (LocaleCompare(keyword,"geometry") == 0)
5796 {
5797 flags=ParseRegionGeometry(msl_info->image[n],value,
5798 &geometry,&exception);
5799 break;
5800 }
5801 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5802 keyword);
5803 break;
5804 }
5805 case 'H':
5806 case 'h':
5807 {
5808 if (LocaleCompare(keyword,"height") == 0)
5809 {
cristye27293e2009-12-18 02:53:20 +00005810 geometry.height=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005811 break;
5812 }
5813 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5814 keyword);
5815 break;
5816 }
5817 case 'W':
5818 case 'w':
5819 {
5820 if (LocaleCompare(keyword,"width") == 0)
5821 {
cristyf2f27272009-12-17 14:48:46 +00005822 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005823 break;
5824 }
5825 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5826 keyword);
5827 break;
5828 }
5829 default:
5830 {
5831 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5832 keyword);
5833 break;
5834 }
5835 }
5836 }
5837 sample_image=SampleImage(msl_info->image[n],geometry.width,
cristyc82a27b2011-10-21 01:07:16 +00005838 geometry.height,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00005839 if (sample_image == (Image *) NULL)
5840 break;
5841 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5842 msl_info->image[n]=sample_image;
5843 break;
5844 }
cristyb988fe72009-09-16 01:01:10 +00005845 if (LocaleCompare((const char *) tag,"scale") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005846 {
5847 Image
5848 *scale_image;
5849
5850 /*
5851 Scale image.
5852 */
5853 if (msl_info->image[n] == (Image *) NULL)
5854 {
cristyb988fe72009-09-16 01:01:10 +00005855 ThrowMSLException(OptionError,"NoImagesDefined",
5856 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005857 break;
5858 }
5859 if (attributes != (const xmlChar **) NULL)
5860 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5861 {
5862 keyword=(const char *) attributes[i++];
5863 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005864 msl_info->attributes[n],(const char *) attributes[i],
5865 &exception);
cristy3ed852e2009-09-05 21:47:34 +00005866 CloneString(&value,attribute);
5867 switch (*keyword)
5868 {
5869 case 'G':
5870 case 'g':
5871 {
5872 if (LocaleCompare(keyword,"geometry") == 0)
5873 {
5874 flags=ParseRegionGeometry(msl_info->image[n],value,
5875 &geometry,&exception);
5876 break;
5877 }
5878 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5879 keyword);
5880 break;
5881 }
5882 case 'H':
5883 case 'h':
5884 {
5885 if (LocaleCompare(keyword,"height") == 0)
5886 {
cristye27293e2009-12-18 02:53:20 +00005887 geometry.height=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005888 break;
5889 }
5890 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5891 keyword);
5892 break;
5893 }
5894 case 'W':
5895 case 'w':
5896 {
5897 if (LocaleCompare(keyword,"width") == 0)
5898 {
cristyf2f27272009-12-17 14:48:46 +00005899 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005900 break;
5901 }
5902 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5903 keyword);
5904 break;
5905 }
5906 default:
5907 {
5908 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5909 keyword);
5910 break;
5911 }
5912 }
5913 }
5914 scale_image=ScaleImage(msl_info->image[n],geometry.width,
cristyc82a27b2011-10-21 01:07:16 +00005915 geometry.height,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00005916 if (scale_image == (Image *) NULL)
5917 break;
5918 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5919 msl_info->image[n]=scale_image;
5920 break;
5921 }
cristyb988fe72009-09-16 01:01:10 +00005922 if (LocaleCompare((const char *) tag,"segment") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005923 {
5924 ColorspaceType
5925 colorspace;
5926
5927 MagickBooleanType
5928 verbose;
cristyb988fe72009-09-16 01:01:10 +00005929
cristy3ed852e2009-09-05 21:47:34 +00005930 /*
5931 Segment image.
5932 */
5933 if (msl_info->image[n] == (Image *) NULL)
5934 {
cristyb988fe72009-09-16 01:01:10 +00005935 ThrowMSLException(OptionError,"NoImagesDefined",
5936 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005937 break;
5938 }
5939 geometry_info.rho=1.0;
5940 geometry_info.sigma=1.5;
5941 colorspace=RGBColorspace;
5942 verbose=MagickFalse;
5943 if (attributes != (const xmlChar **) NULL)
5944 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5945 {
5946 keyword=(const char *) attributes[i++];
5947 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005948 msl_info->attributes[n],(const char *) attributes[i],
5949 &exception);
cristy3ed852e2009-09-05 21:47:34 +00005950 CloneString(&value,attribute);
5951 switch (*keyword)
5952 {
5953 case 'C':
5954 case 'c':
5955 {
5956 if (LocaleCompare(keyword,"cluster-threshold") == 0)
5957 {
cristydbdd0e32011-11-04 23:29:40 +00005958 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00005959 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005960 break;
5961 }
5962 if (LocaleCompare(keyword,"colorspace") == 0)
5963 {
cristy042ee782011-04-22 18:48:30 +00005964 option=ParseCommandOption(MagickColorspaceOptions,
cristy3ed852e2009-09-05 21:47:34 +00005965 MagickFalse,value);
5966 if (option < 0)
5967 ThrowMSLException(OptionError,
5968 "UnrecognizedColorspaceType",value);
5969 colorspace=(ColorspaceType) option;
5970 break;
5971 }
5972 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5973 keyword);
5974 break;
5975 }
5976 case 'G':
5977 case 'g':
5978 {
5979 if (LocaleCompare(keyword,"geometry") == 0)
5980 {
5981 flags=ParseGeometry(value,&geometry_info);
5982 if ((flags & SigmaValue) == 0)
5983 geometry_info.sigma=1.5;
5984 break;
5985 }
5986 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5987 keyword);
5988 break;
5989 }
5990 case 'S':
5991 case 's':
5992 {
5993 if (LocaleCompare(keyword,"smoothing-threshold") == 0)
5994 {
cristydbdd0e32011-11-04 23:29:40 +00005995 geometry_info.sigma=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00005996 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005997 break;
5998 }
5999 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6000 keyword);
6001 break;
6002 }
6003 default:
6004 {
6005 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6006 keyword);
6007 break;
6008 }
6009 }
6010 }
6011 (void) SegmentImage(msl_info->image[n],colorspace,verbose,
cristy018f07f2011-09-04 21:15:19 +00006012 geometry_info.rho,geometry_info.sigma,&exception);
cristy3ed852e2009-09-05 21:47:34 +00006013 break;
6014 }
cristyb988fe72009-09-16 01:01:10 +00006015 else if (LocaleCompare((const char *) tag, "set") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006016 {
6017 if (msl_info->image[n] == (Image *) NULL)
6018 {
cristy0b6d0052011-07-27 23:54:16 +00006019 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006020 break;
6021 }
6022
6023 if (attributes == (const xmlChar **) NULL)
6024 break;
6025 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6026 {
6027 keyword=(const char *) attributes[i++];
6028 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006029 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00006030 switch (*keyword)
6031 {
cristy3ed852e2009-09-05 21:47:34 +00006032 case 'C':
6033 case 'c':
6034 {
6035 if (LocaleCompare(keyword,"clip-mask") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006036 {
cristy2c8b6312009-09-16 02:37:23 +00006037 for (j=0; j < msl_info->n; j++)
cristy3ed852e2009-09-05 21:47:34 +00006038 {
cristy2c8b6312009-09-16 02:37:23 +00006039 const char
6040 *property;
6041
cristyd15e6592011-10-15 00:13:06 +00006042 property=GetImageProperty(msl_info->attributes[j],"id",
6043 &exception);
cristy2c8b6312009-09-16 02:37:23 +00006044 if (LocaleCompare(property,value) == 0)
6045 {
cristy018f07f2011-09-04 21:15:19 +00006046 SetImageMask(msl_info->image[n],msl_info->image[j],
6047 &exception);
cristy2c8b6312009-09-16 02:37:23 +00006048 break;
6049 }
cristy3ed852e2009-09-05 21:47:34 +00006050 }
cristy2c8b6312009-09-16 02:37:23 +00006051 break;
cristy3ed852e2009-09-05 21:47:34 +00006052 }
cristy3ed852e2009-09-05 21:47:34 +00006053 if (LocaleCompare(keyword,"clip-path") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006054 {
cristy2c8b6312009-09-16 02:37:23 +00006055 for (j=0; j < msl_info->n; j++)
cristy3ed852e2009-09-05 21:47:34 +00006056 {
cristy2c8b6312009-09-16 02:37:23 +00006057 const char
6058 *property;
6059
cristyd15e6592011-10-15 00:13:06 +00006060 property=GetImageProperty(msl_info->attributes[j],"id",
6061 &exception);
cristy2c8b6312009-09-16 02:37:23 +00006062 if (LocaleCompare(property,value) == 0)
6063 {
cristy10a6c612012-01-29 21:41:05 +00006064 SetImageMask(msl_info->image[n],msl_info->image[j],
cristy018f07f2011-09-04 21:15:19 +00006065 &exception);
cristy2c8b6312009-09-16 02:37:23 +00006066 break;
6067 }
cristy3ed852e2009-09-05 21:47:34 +00006068 }
cristy2c8b6312009-09-16 02:37:23 +00006069 break;
cristy3ed852e2009-09-05 21:47:34 +00006070 }
cristy2c8b6312009-09-16 02:37:23 +00006071 if (LocaleCompare(keyword,"colorspace") == 0)
6072 {
cristybb503372010-05-27 20:51:26 +00006073 ssize_t
cristy2c8b6312009-09-16 02:37:23 +00006074 colorspace;
6075
cristy042ee782011-04-22 18:48:30 +00006076 colorspace=(ColorspaceType) ParseCommandOption(
cristy7e9e6fa2010-11-21 17:06:24 +00006077 MagickColorspaceOptions,MagickFalse,value);
cristy2c8b6312009-09-16 02:37:23 +00006078 if (colorspace < 0)
cristyfb758a52009-09-16 14:36:08 +00006079 ThrowMSLException(OptionError,"UnrecognizedColorspace",
cristy2c8b6312009-09-16 02:37:23 +00006080 value);
6081 (void) TransformImageColorspace(msl_info->image[n],
cristye941a752011-10-15 01:52:48 +00006082 (ColorspaceType) colorspace,&exception);
cristy2c8b6312009-09-16 02:37:23 +00006083 break;
6084 }
6085 (void) SetMSLAttributes(msl_info,keyword,value);
cristyd15e6592011-10-15 00:13:06 +00006086 (void) SetImageProperty(msl_info->image[n],keyword,value,
6087 &exception);
cristy3ed852e2009-09-05 21:47:34 +00006088 break;
6089 }
6090 case 'D':
6091 case 'd':
6092 {
cristy2c8b6312009-09-16 02:37:23 +00006093 if (LocaleCompare(keyword,"density") == 0)
6094 {
6095 flags=ParseGeometry(value,&geometry_info);
cristy2a11bef2011-10-28 18:33:11 +00006096 msl_info->image[n]->resolution.x=geometry_info.rho;
6097 msl_info->image[n]->resolution.y=geometry_info.sigma;
cristy2c8b6312009-09-16 02:37:23 +00006098 if ((flags & SigmaValue) == 0)
cristy2a11bef2011-10-28 18:33:11 +00006099 msl_info->image[n]->resolution.y=
6100 msl_info->image[n]->resolution.x;
cristy2c8b6312009-09-16 02:37:23 +00006101 break;
6102 }
6103 (void) SetMSLAttributes(msl_info,keyword,value);
cristyd15e6592011-10-15 00:13:06 +00006104 (void) SetImageProperty(msl_info->image[n],keyword,value,
6105 &exception);
cristy3ed852e2009-09-05 21:47:34 +00006106 break;
6107 }
6108 case 'O':
6109 case 'o':
6110 {
6111 if (LocaleCompare(keyword, "opacity") == 0)
cristy2c8b6312009-09-16 02:37:23 +00006112 {
cristy4c08aed2011-07-01 19:47:50 +00006113 ssize_t opac = OpaqueAlpha,
cristybb503372010-05-27 20:51:26 +00006114 len = (ssize_t) strlen( value );
cristy3ed852e2009-09-05 21:47:34 +00006115
cristy2c8b6312009-09-16 02:37:23 +00006116 if (value[len-1] == '%') {
6117 char tmp[100];
6118 (void) CopyMagickString(tmp,value,len);
cristyf2f27272009-12-17 14:48:46 +00006119 opac = StringToLong( tmp );
cristy2c8b6312009-09-16 02:37:23 +00006120 opac = (int)(QuantumRange * ((float)opac/100));
6121 } else
cristyf2f27272009-12-17 14:48:46 +00006122 opac = StringToLong( value );
cristye941a752011-10-15 01:52:48 +00006123 (void) SetImageAlpha( msl_info->image[n], (Quantum) opac,
6124 &exception);
cristy2c8b6312009-09-16 02:37:23 +00006125 break;
cristy3ed852e2009-09-05 21:47:34 +00006126 }
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 case 'P':
6133 case 'p':
6134 {
6135 if (LocaleCompare(keyword, "page") == 0)
6136 {
6137 char
6138 page[MaxTextExtent];
6139
6140 const char
6141 *image_option;
6142
6143 MagickStatusType
6144 flags;
6145
6146 RectangleInfo
6147 geometry;
6148
6149 (void) ResetMagickMemory(&geometry,0,sizeof(geometry));
6150 image_option=GetImageOption(msl_info->image_info[n],"page");
6151 if (image_option != (const char *) NULL)
6152 flags=ParseAbsoluteGeometry(image_option,&geometry);
6153 flags=ParseAbsoluteGeometry(value,&geometry);
cristyb51dff52011-05-19 16:55:47 +00006154 (void) FormatLocaleString(page,MaxTextExtent,"%.20gx%.20g",
cristye8c25f92010-06-03 00:53:06 +00006155 (double) geometry.width,(double) geometry.height);
cristy3ed852e2009-09-05 21:47:34 +00006156 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
cristyb51dff52011-05-19 16:55:47 +00006157 (void) FormatLocaleString(page,MaxTextExtent,
cristye8c25f92010-06-03 00:53:06 +00006158 "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,
6159 (double) geometry.height,(double) geometry.x,(double)
cristyf2faecf2010-05-28 19:19:36 +00006160 geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00006161 (void) SetImageOption(msl_info->image_info[n],keyword,page);
6162 msl_info->image_info[n]->page=GetPageGeometry(page);
6163 break;
6164 }
cristy2c8b6312009-09-16 02:37:23 +00006165 (void) SetMSLAttributes(msl_info,keyword,value);
cristyd15e6592011-10-15 00:13:06 +00006166 (void) SetImageProperty(msl_info->image[n],keyword,value,
6167 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00006168 break;
6169 }
6170 default:
6171 {
cristy2c8b6312009-09-16 02:37:23 +00006172 (void) SetMSLAttributes(msl_info,keyword,value);
cristyd15e6592011-10-15 00:13:06 +00006173 (void) SetImageProperty(msl_info->image[n],keyword,value,
6174 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00006175 break;
6176 }
6177 }
6178 }
6179 break;
6180 }
cristyb988fe72009-09-16 01:01:10 +00006181 if (LocaleCompare((const char *) tag,"shade") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006182 {
6183 Image
6184 *shade_image;
6185
6186 MagickBooleanType
6187 gray;
6188
6189 /*
6190 Shade image.
6191 */
6192 if (msl_info->image[n] == (Image *) NULL)
6193 {
cristyb988fe72009-09-16 01:01:10 +00006194 ThrowMSLException(OptionError,"NoImagesDefined",
6195 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006196 break;
6197 }
6198 gray=MagickFalse;
6199 if (attributes != (const xmlChar **) NULL)
6200 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6201 {
6202 keyword=(const char *) attributes[i++];
6203 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006204 msl_info->attributes[n],(const char *) attributes[i],
6205 &exception);
cristy3ed852e2009-09-05 21:47:34 +00006206 CloneString(&value,attribute);
6207 switch (*keyword)
6208 {
6209 case 'A':
6210 case 'a':
6211 {
6212 if (LocaleCompare(keyword,"azimuth") == 0)
6213 {
cristydbdd0e32011-11-04 23:29:40 +00006214 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00006215 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006216 break;
6217 }
6218 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6219 keyword);
6220 break;
6221 }
6222 case 'E':
6223 case 'e':
6224 {
6225 if (LocaleCompare(keyword,"elevation") == 0)
6226 {
cristydbdd0e32011-11-04 23:29:40 +00006227 geometry_info.sigma=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00006228 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006229 break;
6230 }
6231 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6232 keyword);
6233 break;
6234 }
6235 case 'G':
6236 case 'g':
6237 {
6238 if (LocaleCompare(keyword,"geometry") == 0)
6239 {
6240 flags=ParseGeometry(value,&geometry_info);
6241 if ((flags & SigmaValue) == 0)
6242 geometry_info.sigma=1.0;
6243 break;
6244 }
6245 if (LocaleCompare(keyword,"gray") == 0)
6246 {
cristy042ee782011-04-22 18:48:30 +00006247 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00006248 value);
6249 if (option < 0)
6250 ThrowMSLException(OptionError,"UnrecognizedNoiseType",
6251 value);
6252 gray=(MagickBooleanType) option;
6253 break;
6254 }
6255 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6256 keyword);
6257 break;
6258 }
6259 default:
6260 {
6261 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6262 keyword);
6263 break;
6264 }
6265 }
6266 }
6267 shade_image=ShadeImage(msl_info->image[n],gray,geometry_info.rho,
cristyc82a27b2011-10-21 01:07:16 +00006268 geometry_info.sigma,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00006269 if (shade_image == (Image *) NULL)
6270 break;
6271 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6272 msl_info->image[n]=shade_image;
6273 break;
6274 }
cristyb988fe72009-09-16 01:01:10 +00006275 if (LocaleCompare((const char *) tag,"shadow") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006276 {
6277 Image
6278 *shadow_image;
6279
6280 /*
6281 Shear image.
6282 */
6283 if (msl_info->image[n] == (Image *) NULL)
6284 {
cristyb988fe72009-09-16 01:01:10 +00006285 ThrowMSLException(OptionError,"NoImagesDefined",
6286 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006287 break;
6288 }
6289 if (attributes != (const xmlChar **) NULL)
6290 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6291 {
6292 keyword=(const char *) attributes[i++];
6293 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006294 msl_info->attributes[n],(const char *) attributes[i],
6295 &exception);
cristy3ed852e2009-09-05 21:47:34 +00006296 CloneString(&value,attribute);
6297 switch (*keyword)
6298 {
6299 case 'G':
6300 case 'g':
6301 {
6302 if (LocaleCompare(keyword,"geometry") == 0)
6303 {
6304 flags=ParseGeometry(value,&geometry_info);
6305 if ((flags & SigmaValue) == 0)
6306 geometry_info.sigma=1.0;
6307 break;
6308 }
6309 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6310 keyword);
6311 break;
6312 }
6313 case 'O':
6314 case 'o':
6315 {
6316 if (LocaleCompare(keyword,"opacity") == 0)
6317 {
cristyf2f27272009-12-17 14:48:46 +00006318 geometry_info.rho=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006319 break;
6320 }
6321 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6322 keyword);
6323 break;
6324 }
6325 case 'S':
6326 case 's':
6327 {
6328 if (LocaleCompare(keyword,"sigma") == 0)
6329 {
cristyf2f27272009-12-17 14:48:46 +00006330 geometry_info.sigma=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006331 break;
6332 }
6333 break;
6334 }
6335 case 'X':
6336 case 'x':
6337 {
6338 if (LocaleCompare(keyword,"x") == 0)
6339 {
cristydbdd0e32011-11-04 23:29:40 +00006340 geometry_info.xi=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00006341 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006342 break;
6343 }
6344 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6345 keyword);
6346 break;
6347 }
6348 case 'Y':
6349 case 'y':
6350 {
6351 if (LocaleCompare(keyword,"y") == 0)
6352 {
cristyf2f27272009-12-17 14:48:46 +00006353 geometry_info.psi=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006354 break;
6355 }
6356 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6357 keyword);
6358 break;
6359 }
6360 default:
6361 {
6362 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6363 keyword);
6364 break;
6365 }
6366 }
6367 }
6368 shadow_image=ShadowImage(msl_info->image[n],geometry_info.rho,
cristyeb6e6582011-12-09 09:14:23 +00006369 geometry_info.sigma,0.0,(ssize_t) ceil(geometry_info.xi-0.5),
6370 (ssize_t) ceil(geometry_info.psi-0.5),msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00006371 if (shadow_image == (Image *) NULL)
6372 break;
6373 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6374 msl_info->image[n]=shadow_image;
6375 break;
6376 }
cristyb988fe72009-09-16 01:01:10 +00006377 if (LocaleCompare((const char *) tag,"sharpen") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006378 {
cristy05c0c9a2011-09-05 23:16:13 +00006379 double bias = 0.0,
6380 radius = 0.0,
cristy3ed852e2009-09-05 21:47:34 +00006381 sigma = 1.0;
6382
6383 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00006384 {
6385 ThrowMSLException(OptionError,"NoImagesDefined",
6386 (const char *) tag);
6387 break;
6388 }
cristy3ed852e2009-09-05 21:47:34 +00006389 /*
6390 NOTE: sharpen can have no attributes, since we use all the defaults!
6391 */
6392 if (attributes != (const xmlChar **) NULL)
6393 {
6394 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6395 {
6396 keyword=(const char *) attributes[i++];
6397 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006398 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00006399 switch (*keyword)
6400 {
cristy05c0c9a2011-09-05 23:16:13 +00006401 case 'B':
6402 case 'b':
6403 {
6404 if (LocaleCompare(keyword, "bias") == 0)
6405 {
cristydbdd0e32011-11-04 23:29:40 +00006406 bias = StringToDouble(value,(char **) NULL);
cristy05c0c9a2011-09-05 23:16:13 +00006407 break;
6408 }
6409 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6410 break;
6411 }
cristy3ed852e2009-09-05 21:47:34 +00006412 case 'R':
6413 case 'r':
6414 {
6415 if (LocaleCompare(keyword, "radius") == 0)
6416 {
cristydbdd0e32011-11-04 23:29:40 +00006417 radius = StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006418 break;
6419 }
6420 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6421 break;
6422 }
6423 case 'S':
6424 case 's':
6425 {
6426 if (LocaleCompare(keyword,"sigma") == 0)
6427 {
cristyf2f27272009-12-17 14:48:46 +00006428 sigma = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00006429 break;
6430 }
6431 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6432 break;
6433 }
6434 default:
6435 {
6436 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6437 break;
6438 }
6439 }
6440 }
6441 }
6442
6443 /*
6444 sharpen image.
6445 */
6446 {
6447 Image
6448 *newImage;
6449
cristy05c0c9a2011-09-05 23:16:13 +00006450 newImage=SharpenImage(msl_info->image[n],radius,sigma,bias,
cristyc82a27b2011-10-21 01:07:16 +00006451 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00006452 if (newImage == (Image *) NULL)
6453 break;
6454 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6455 msl_info->image[n]=newImage;
6456 break;
6457 }
6458 }
cristyb988fe72009-09-16 01:01:10 +00006459 else if (LocaleCompare((const char *) tag,"shave") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006460 {
6461 /* init the values */
6462 width = height = 0;
6463 x = y = 0;
6464
6465 if (msl_info->image[n] == (Image *) NULL)
6466 {
cristyb988fe72009-09-16 01:01:10 +00006467 ThrowMSLException(OptionError,"NoImagesDefined",
6468 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006469 break;
6470 }
6471 if (attributes == (const xmlChar **) NULL)
6472 break;
6473 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6474 {
6475 keyword=(const char *) attributes[i++];
6476 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006477 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00006478 switch (*keyword)
6479 {
6480 case 'G':
6481 case 'g':
6482 {
6483 if (LocaleCompare(keyword,"geometry") == 0)
6484 {
6485 (void) ParseMetaGeometry(value,&x,&y,&width,&height);
6486 break;
6487 }
6488 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6489 break;
6490 }
6491 case 'H':
6492 case 'h':
6493 {
6494 if (LocaleCompare(keyword,"height") == 0)
6495 {
cristyf2f27272009-12-17 14:48:46 +00006496 height = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00006497 break;
6498 }
6499 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6500 break;
6501 }
6502 case 'W':
6503 case 'w':
6504 {
6505 if (LocaleCompare(keyword,"width") == 0)
6506 {
cristyf2f27272009-12-17 14:48:46 +00006507 width = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00006508 break;
6509 }
6510 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6511 break;
6512 }
6513 default:
6514 {
6515 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6516 break;
6517 }
6518 }
6519 }
6520
6521 /*
6522 process image.
6523 */
6524 {
6525 Image
6526 *newImage;
6527 RectangleInfo
6528 rectInfo;
6529
6530 rectInfo.height = height;
6531 rectInfo.width = width;
6532 rectInfo.x = x;
6533 rectInfo.y = y;
6534
6535
6536 newImage=ShaveImage(msl_info->image[n], &rectInfo,
cristyc82a27b2011-10-21 01:07:16 +00006537 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00006538 if (newImage == (Image *) NULL)
6539 break;
6540 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6541 msl_info->image[n]=newImage;
6542 }
6543
6544 break;
6545 }
cristyb988fe72009-09-16 01:01:10 +00006546 if (LocaleCompare((const char *) tag,"shear") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006547 {
6548 Image
6549 *shear_image;
6550
6551 /*
6552 Shear image.
6553 */
6554 if (msl_info->image[n] == (Image *) NULL)
6555 {
cristyb988fe72009-09-16 01:01:10 +00006556 ThrowMSLException(OptionError,"NoImagesDefined",
6557 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006558 break;
6559 }
6560 if (attributes != (const xmlChar **) NULL)
6561 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6562 {
6563 keyword=(const char *) attributes[i++];
6564 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006565 msl_info->attributes[n],(const char *) attributes[i],
6566 &exception);
cristy3ed852e2009-09-05 21:47:34 +00006567 CloneString(&value,attribute);
6568 switch (*keyword)
6569 {
6570 case 'F':
6571 case 'f':
6572 {
6573 if (LocaleCompare(keyword, "fill") == 0)
6574 {
cristy9950d572011-10-01 18:22:35 +00006575 (void) QueryColorCompliance(value,AllCompliance,
cristy3ed852e2009-09-05 21:47:34 +00006576 &msl_info->image[n]->background_color,&exception);
6577 break;
6578 }
6579 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6580 keyword);
6581 break;
6582 }
6583 case 'G':
6584 case 'g':
6585 {
6586 if (LocaleCompare(keyword,"geometry") == 0)
6587 {
6588 flags=ParseGeometry(value,&geometry_info);
6589 if ((flags & SigmaValue) == 0)
6590 geometry_info.sigma=1.0;
6591 break;
6592 }
6593 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6594 keyword);
6595 break;
6596 }
6597 case 'X':
6598 case 'x':
6599 {
6600 if (LocaleCompare(keyword,"x") == 0)
6601 {
cristydbdd0e32011-11-04 23:29:40 +00006602 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00006603 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006604 break;
6605 }
6606 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6607 keyword);
6608 break;
6609 }
6610 case 'Y':
6611 case 'y':
6612 {
6613 if (LocaleCompare(keyword,"y") == 0)
6614 {
cristyf2f27272009-12-17 14:48:46 +00006615 geometry_info.sigma=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006616 break;
6617 }
6618 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6619 keyword);
6620 break;
6621 }
6622 default:
6623 {
6624 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6625 keyword);
6626 break;
6627 }
6628 }
6629 }
6630 shear_image=ShearImage(msl_info->image[n],geometry_info.rho,
cristyc82a27b2011-10-21 01:07:16 +00006631 geometry_info.sigma,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00006632 if (shear_image == (Image *) NULL)
6633 break;
6634 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6635 msl_info->image[n]=shear_image;
6636 break;
6637 }
cristyb988fe72009-09-16 01:01:10 +00006638 if (LocaleCompare((const char *) tag,"signature") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006639 {
6640 /*
6641 Signature image.
6642 */
6643 if (msl_info->image[n] == (Image *) NULL)
6644 {
cristyb988fe72009-09-16 01:01:10 +00006645 ThrowMSLException(OptionError,"NoImagesDefined",
6646 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006647 break;
6648 }
6649 if (attributes != (const xmlChar **) NULL)
6650 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6651 {
6652 keyword=(const char *) attributes[i++];
6653 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006654 msl_info->attributes[n],(const char *) attributes[i],
6655 &exception);
cristy3ed852e2009-09-05 21:47:34 +00006656 CloneString(&value,attribute);
6657 switch (*keyword)
6658 {
6659 default:
6660 {
6661 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6662 keyword);
6663 break;
6664 }
6665 }
6666 }
cristy018f07f2011-09-04 21:15:19 +00006667 (void) SignatureImage(msl_info->image[n],&exception);
cristy3ed852e2009-09-05 21:47:34 +00006668 break;
6669 }
cristyb988fe72009-09-16 01:01:10 +00006670 if (LocaleCompare((const char *) tag,"solarize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006671 {
6672 /*
6673 Solarize image.
6674 */
6675 if (msl_info->image[n] == (Image *) NULL)
6676 {
cristyb988fe72009-09-16 01:01:10 +00006677 ThrowMSLException(OptionError,"NoImagesDefined",
6678 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006679 break;
6680 }
6681 geometry_info.rho=QuantumRange/2.0;
6682 if (attributes != (const xmlChar **) NULL)
6683 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6684 {
6685 keyword=(const char *) attributes[i++];
6686 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006687 msl_info->attributes[n],(const char *) attributes[i],
6688 &exception);
cristy3ed852e2009-09-05 21:47:34 +00006689 CloneString(&value,attribute);
6690 switch (*keyword)
6691 {
6692 case 'G':
6693 case 'g':
6694 {
6695 if (LocaleCompare(keyword,"geometry") == 0)
6696 {
6697 flags=ParseGeometry(value,&geometry_info);
6698 break;
6699 }
6700 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6701 keyword);
6702 break;
6703 }
6704 case 'T':
6705 case 't':
6706 {
6707 if (LocaleCompare(keyword,"threshold") == 0)
6708 {
cristydbdd0e32011-11-04 23:29:40 +00006709 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00006710 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006711 break;
6712 }
6713 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6714 keyword);
6715 break;
6716 }
6717 default:
6718 {
6719 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6720 keyword);
6721 break;
6722 }
6723 }
6724 }
cristy5cbc0162011-08-29 00:36:28 +00006725 (void) SolarizeImage(msl_info->image[n],geometry_info.rho,
cristyc82a27b2011-10-21 01:07:16 +00006726 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00006727 break;
6728 }
cristyb988fe72009-09-16 01:01:10 +00006729 if (LocaleCompare((const char *) tag,"spread") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006730 {
6731 Image
6732 *spread_image;
6733
6734 /*
6735 Spread image.
6736 */
6737 if (msl_info->image[n] == (Image *) NULL)
6738 {
cristyb988fe72009-09-16 01:01:10 +00006739 ThrowMSLException(OptionError,"NoImagesDefined",
6740 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006741 break;
6742 }
6743 if (attributes != (const xmlChar **) NULL)
6744 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6745 {
6746 keyword=(const char *) attributes[i++];
6747 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006748 msl_info->attributes[n],(const char *) attributes[i],
6749 &exception);
cristy3ed852e2009-09-05 21:47:34 +00006750 CloneString(&value,attribute);
6751 switch (*keyword)
6752 {
6753 case 'G':
6754 case 'g':
6755 {
6756 if (LocaleCompare(keyword,"geometry") == 0)
6757 {
6758 flags=ParseGeometry(value,&geometry_info);
6759 if ((flags & SigmaValue) == 0)
6760 geometry_info.sigma=1.0;
6761 break;
6762 }
6763 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6764 keyword);
6765 break;
6766 }
6767 case 'R':
6768 case 'r':
6769 {
6770 if (LocaleCompare(keyword,"radius") == 0)
6771 {
cristydbdd0e32011-11-04 23:29:40 +00006772 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00006773 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006774 break;
6775 }
6776 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6777 keyword);
6778 break;
6779 }
6780 default:
6781 {
6782 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6783 keyword);
6784 break;
6785 }
6786 }
6787 }
6788 spread_image=SpreadImage(msl_info->image[n],geometry_info.rho,
cristyc82a27b2011-10-21 01:07:16 +00006789 msl_info->image[n]->interpolate,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00006790 if (spread_image == (Image *) NULL)
6791 break;
6792 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6793 msl_info->image[n]=spread_image;
6794 break;
6795 }
cristyb988fe72009-09-16 01:01:10 +00006796 else if (LocaleCompare((const char *) tag,"stegano") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006797 {
6798 Image *
6799 watermark = (Image*)NULL;
6800
6801 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00006802 {
6803 ThrowMSLException(OptionError,"NoImagesDefined",
6804 (const char *) tag);
6805 break;
6806 }
cristy3ed852e2009-09-05 21:47:34 +00006807 if (attributes == (const xmlChar **) NULL)
6808 break;
6809 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6810 {
6811 keyword=(const char *) attributes[i++];
6812 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006813 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00006814 switch (*keyword)
6815 {
6816 case 'I':
6817 case 'i':
6818 {
6819 if (LocaleCompare(keyword,"image") == 0)
6820 {
6821 for (j=0; j<msl_info->n;j++)
6822 {
6823 const char *
cristyd15e6592011-10-15 00:13:06 +00006824 theAttr = GetImageProperty(msl_info->attributes[j], "id",
6825 &exception);
cristy3ed852e2009-09-05 21:47:34 +00006826 if (theAttr && LocaleCompare(theAttr, value) == 0)
6827 {
6828 watermark = msl_info->image[j];
6829 break;
6830 }
6831 }
6832 break;
6833 }
6834 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6835 break;
6836 }
6837 default:
6838 {
6839 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6840 break;
6841 }
6842 }
6843 }
6844
6845 /*
6846 process image.
6847 */
6848 if ( watermark != (Image*) NULL )
6849 {
6850 Image
6851 *newImage;
6852
cristyc82a27b2011-10-21 01:07:16 +00006853 newImage=SteganoImage(msl_info->image[n], watermark, msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00006854 if (newImage == (Image *) NULL)
6855 break;
6856 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6857 msl_info->image[n]=newImage;
6858 break;
6859 } else
6860 ThrowMSLException(OptionError,"MissingWatermarkImage",keyword);
6861 }
cristyb988fe72009-09-16 01:01:10 +00006862 else if (LocaleCompare((const char *) tag,"stereo") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006863 {
6864 Image *
6865 stereoImage = (Image*)NULL;
6866
6867 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00006868 {
6869 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
6870 break;
6871 }
cristy3ed852e2009-09-05 21:47:34 +00006872 if (attributes == (const xmlChar **) NULL)
6873 break;
6874 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6875 {
6876 keyword=(const char *) attributes[i++];
6877 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006878 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00006879 switch (*keyword)
6880 {
6881 case 'I':
6882 case 'i':
6883 {
6884 if (LocaleCompare(keyword,"image") == 0)
6885 {
6886 for (j=0; j<msl_info->n;j++)
6887 {
6888 const char *
cristyd15e6592011-10-15 00:13:06 +00006889 theAttr = GetImageProperty(msl_info->attributes[j], "id",
6890 &exception);
cristy3ed852e2009-09-05 21:47:34 +00006891 if (theAttr && LocaleCompare(theAttr, value) == 0)
6892 {
6893 stereoImage = msl_info->image[j];
6894 break;
6895 }
6896 }
6897 break;
6898 }
6899 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6900 break;
6901 }
6902 default:
6903 {
6904 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6905 break;
6906 }
6907 }
6908 }
6909
6910 /*
6911 process image.
6912 */
6913 if ( stereoImage != (Image*) NULL )
6914 {
6915 Image
6916 *newImage;
6917
cristyc82a27b2011-10-21 01:07:16 +00006918 newImage=StereoImage(msl_info->image[n], stereoImage, msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00006919 if (newImage == (Image *) NULL)
6920 break;
6921 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6922 msl_info->image[n]=newImage;
6923 break;
6924 } else
6925 ThrowMSLException(OptionError,"Missing stereo image",keyword);
6926 }
cristyb988fe72009-09-16 01:01:10 +00006927 if (LocaleCompare((const char *) tag,"swap") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006928 {
6929 Image
6930 *p,
6931 *q,
6932 *swap;
6933
cristybb503372010-05-27 20:51:26 +00006934 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00006935 index,
6936 swap_index;
6937
6938 if (msl_info->image[n] == (Image *) NULL)
6939 {
cristyb988fe72009-09-16 01:01:10 +00006940 ThrowMSLException(OptionError,"NoImagesDefined",
6941 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006942 break;
6943 }
6944 index=(-1);
6945 swap_index=(-2);
6946 if (attributes != (const xmlChar **) NULL)
6947 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6948 {
6949 keyword=(const char *) attributes[i++];
6950 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006951 msl_info->attributes[n],(const char *) attributes[i],
6952 &exception);
cristy3ed852e2009-09-05 21:47:34 +00006953 CloneString(&value,attribute);
6954 switch (*keyword)
6955 {
6956 case 'G':
6957 case 'g':
6958 {
6959 if (LocaleCompare(keyword,"indexes") == 0)
6960 {
6961 flags=ParseGeometry(value,&geometry_info);
cristybb503372010-05-27 20:51:26 +00006962 index=(ssize_t) geometry_info.rho;
cristy3ed852e2009-09-05 21:47:34 +00006963 if ((flags & SigmaValue) == 0)
cristybb503372010-05-27 20:51:26 +00006964 swap_index=(ssize_t) geometry_info.sigma;
cristy3ed852e2009-09-05 21:47:34 +00006965 break;
6966 }
6967 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6968 keyword);
6969 break;
6970 }
6971 default:
6972 {
6973 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6974 keyword);
6975 break;
6976 }
6977 }
6978 }
6979 /*
6980 Swap images.
6981 */
6982 p=GetImageFromList(msl_info->image[n],index);
6983 q=GetImageFromList(msl_info->image[n],swap_index);
6984 if ((p == (Image *) NULL) || (q == (Image *) NULL))
6985 {
cristyb988fe72009-09-16 01:01:10 +00006986 ThrowMSLException(OptionError,"NoSuchImage",(const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006987 break;
6988 }
cristyc82a27b2011-10-21 01:07:16 +00006989 swap=CloneImage(p,0,0,MagickTrue,msl_info->exception);
6990 ReplaceImageInList(&p,CloneImage(q,0,0,MagickTrue,
6991 msl_info->exception));
cristy3ed852e2009-09-05 21:47:34 +00006992 ReplaceImageInList(&q,swap);
6993 msl_info->image[n]=GetFirstImageInList(q);
6994 break;
6995 }
cristyb988fe72009-09-16 01:01:10 +00006996 if (LocaleCompare((const char *) tag,"swirl") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006997 {
6998 Image
6999 *swirl_image;
7000
7001 /*
7002 Swirl image.
7003 */
7004 if (msl_info->image[n] == (Image *) NULL)
7005 {
cristyb988fe72009-09-16 01:01:10 +00007006 ThrowMSLException(OptionError,"NoImagesDefined",
7007 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00007008 break;
7009 }
7010 if (attributes != (const xmlChar **) NULL)
7011 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7012 {
7013 keyword=(const char *) attributes[i++];
7014 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00007015 msl_info->attributes[n],(const char *) attributes[i],
7016 &exception);
cristy3ed852e2009-09-05 21:47:34 +00007017 CloneString(&value,attribute);
7018 switch (*keyword)
7019 {
7020 case 'D':
7021 case 'd':
7022 {
7023 if (LocaleCompare(keyword,"degrees") == 0)
7024 {
cristydbdd0e32011-11-04 23:29:40 +00007025 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00007026 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00007027 break;
7028 }
7029 ThrowMSLException(OptionError,"UnrecognizedAttribute",
7030 keyword);
7031 break;
7032 }
7033 case 'G':
7034 case 'g':
7035 {
7036 if (LocaleCompare(keyword,"geometry") == 0)
7037 {
7038 flags=ParseGeometry(value,&geometry_info);
7039 if ((flags & SigmaValue) == 0)
7040 geometry_info.sigma=1.0;
7041 break;
7042 }
7043 ThrowMSLException(OptionError,"UnrecognizedAttribute",
7044 keyword);
7045 break;
7046 }
7047 default:
7048 {
7049 ThrowMSLException(OptionError,"UnrecognizedAttribute",
7050 keyword);
7051 break;
7052 }
7053 }
7054 }
7055 swirl_image=SwirlImage(msl_info->image[n],geometry_info.rho,
cristyc82a27b2011-10-21 01:07:16 +00007056 msl_info->image[n]->interpolate,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00007057 if (swirl_image == (Image *) NULL)
7058 break;
7059 msl_info->image[n]=DestroyImage(msl_info->image[n]);
7060 msl_info->image[n]=swirl_image;
7061 break;
7062 }
cristyb988fe72009-09-16 01:01:10 +00007063 if (LocaleCompare((const char *) tag,"sync") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007064 {
7065 /*
7066 Sync image.
7067 */
7068 if (msl_info->image[n] == (Image *) NULL)
7069 {
cristyb988fe72009-09-16 01:01:10 +00007070 ThrowMSLException(OptionError,"NoImagesDefined",
7071 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00007072 break;
7073 }
7074 if (attributes != (const xmlChar **) NULL)
7075 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7076 {
7077 keyword=(const char *) attributes[i++];
7078 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00007079 msl_info->attributes[n],(const char *) attributes[i],
7080 &exception);
cristy3ed852e2009-09-05 21:47:34 +00007081 CloneString(&value,attribute);
7082 switch (*keyword)
7083 {
7084 default:
7085 {
7086 ThrowMSLException(OptionError,"UnrecognizedAttribute",
7087 keyword);
7088 break;
7089 }
7090 }
7091 }
cristyea1a8aa2011-10-20 13:24:06 +00007092 (void) SyncImage(msl_info->image[n],&exception);
cristy3ed852e2009-09-05 21:47:34 +00007093 break;
7094 }
7095 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7096 }
7097 case 'T':
7098 case 't':
7099 {
cristyb988fe72009-09-16 01:01:10 +00007100 if (LocaleCompare((const char *) tag,"map") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007101 {
7102 Image
7103 *texture_image;
7104
7105 /*
7106 Texture image.
7107 */
7108 if (msl_info->image[n] == (Image *) NULL)
7109 {
cristyb988fe72009-09-16 01:01:10 +00007110 ThrowMSLException(OptionError,"NoImagesDefined",
7111 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00007112 break;
7113 }
7114 texture_image=NewImageList();
7115 if (attributes != (const xmlChar **) NULL)
7116 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7117 {
7118 keyword=(const char *) attributes[i++];
7119 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00007120 msl_info->attributes[n],(const char *) attributes[i],
7121 &exception);
cristy3ed852e2009-09-05 21:47:34 +00007122 CloneString(&value,attribute);
7123 switch (*keyword)
7124 {
7125 case 'I':
7126 case 'i':
7127 {
7128 if (LocaleCompare(keyword,"image") == 0)
7129 for (j=0; j < msl_info->n; j++)
7130 {
7131 const char
7132 *attribute;
cristyb988fe72009-09-16 01:01:10 +00007133
cristyd15e6592011-10-15 00:13:06 +00007134 attribute=GetImageProperty(msl_info->attributes[j],"id",
7135 &exception);
cristy3ed852e2009-09-05 21:47:34 +00007136 if ((attribute != (const char *) NULL) &&
7137 (LocaleCompare(attribute,value) == 0))
7138 {
7139 texture_image=CloneImage(msl_info->image[j],0,0,
7140 MagickFalse,&exception);
7141 break;
7142 }
7143 }
7144 break;
7145 }
7146 default:
7147 {
7148 ThrowMSLException(OptionError,"UnrecognizedAttribute",
7149 keyword);
7150 break;
7151 }
7152 }
7153 }
cristye941a752011-10-15 01:52:48 +00007154 (void) TextureImage(msl_info->image[n],texture_image,&exception);
cristy3ed852e2009-09-05 21:47:34 +00007155 texture_image=DestroyImage(texture_image);
7156 break;
7157 }
cristyb988fe72009-09-16 01:01:10 +00007158 else if (LocaleCompare((const char *) tag,"threshold") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007159 {
7160 /* init the values */
7161 double threshold = 0;
7162
7163 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007164 {
7165 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7166 break;
7167 }
cristy3ed852e2009-09-05 21:47:34 +00007168 if (attributes == (const xmlChar **) NULL)
7169 break;
7170 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7171 {
7172 keyword=(const char *) attributes[i++];
7173 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00007174 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00007175 switch (*keyword)
7176 {
7177 case 'T':
7178 case 't':
7179 {
7180 if (LocaleCompare(keyword,"threshold") == 0)
7181 {
cristydbdd0e32011-11-04 23:29:40 +00007182 threshold = StringToDouble(value,(char **) NULL);
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
7196 /*
7197 process image.
7198 */
7199 {
cristye941a752011-10-15 01:52:48 +00007200 BilevelImage(msl_info->image[n],threshold,&exception);
7201 break;
cristy3ed852e2009-09-05 21:47:34 +00007202 }
7203 }
cristyb988fe72009-09-16 01:01:10 +00007204 else if (LocaleCompare((const char *) tag, "transparent") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007205 {
7206 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007207 {
7208 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7209 break;
7210 }
cristy3ed852e2009-09-05 21:47:34 +00007211 if (attributes == (const xmlChar **) NULL)
7212 break;
7213 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7214 {
7215 keyword=(const char *) attributes[i++];
7216 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00007217 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00007218 switch (*keyword)
7219 {
7220 case 'C':
7221 case 'c':
7222 {
7223 if (LocaleCompare(keyword,"color") == 0)
7224 {
cristy4c08aed2011-07-01 19:47:50 +00007225 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00007226 target;
7227
cristy269c9412011-10-13 23:41:15 +00007228 (void) QueryColorCompliance(value,AllCompliance,&target,
cristy9950d572011-10-01 18:22:35 +00007229 &exception);
cristy3ed852e2009-09-05 21:47:34 +00007230 (void) TransparentPaintImage(msl_info->image[n],&target,
cristyc82a27b2011-10-21 01:07:16 +00007231 TransparentAlpha,MagickFalse,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00007232 break;
7233 }
7234 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7235 break;
7236 }
7237 default:
7238 {
7239 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7240 break;
7241 }
7242 }
7243 }
7244 break;
7245 }
cristyb988fe72009-09-16 01:01:10 +00007246 else if (LocaleCompare((const char *) tag, "trim") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007247 {
7248 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007249 {
7250 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7251 break;
7252 }
cristy3ed852e2009-09-05 21:47:34 +00007253
7254 /* no attributes here */
7255
7256 /* process the image */
7257 {
7258 Image
7259 *newImage;
7260 RectangleInfo
7261 rectInfo;
7262
7263 /* all zeros on a crop == trim edges! */
7264 rectInfo.height = rectInfo.width = 0;
7265 rectInfo.x = rectInfo.y = 0;
7266
cristyc82a27b2011-10-21 01:07:16 +00007267 newImage=CropImage(msl_info->image[n],&rectInfo, msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00007268 if (newImage == (Image *) NULL)
7269 break;
7270 msl_info->image[n]=DestroyImage(msl_info->image[n]);
7271 msl_info->image[n]=newImage;
7272 break;
7273 }
7274 }
7275 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7276 }
7277 case 'W':
7278 case 'w':
7279 {
cristyb988fe72009-09-16 01:01:10 +00007280 if (LocaleCompare((const char *) tag,"write") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007281 {
7282 if (msl_info->image[n] == (Image *) NULL)
7283 {
cristyb988fe72009-09-16 01:01:10 +00007284 ThrowMSLException(OptionError,"NoImagesDefined",
7285 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00007286 break;
7287 }
7288 if (attributes == (const xmlChar **) NULL)
7289 break;
7290 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7291 {
7292 keyword=(const char *) attributes[i++];
7293 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00007294 msl_info->attributes[n],(const char *) attributes[i],&exception));
cristy3ed852e2009-09-05 21:47:34 +00007295 switch (*keyword)
7296 {
7297 case 'F':
7298 case 'f':
7299 {
7300 if (LocaleCompare(keyword,"filename") == 0)
7301 {
7302 (void) CopyMagickString(msl_info->image[n]->filename,value,
7303 MaxTextExtent);
7304 break;
7305 }
cristy4582cbb2009-09-23 00:35:43 +00007306 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00007307 }
7308 default:
7309 {
cristy4582cbb2009-09-23 00:35:43 +00007310 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00007311 break;
7312 }
7313 }
7314 }
7315
7316 /* process */
7317 {
cristy6f9e0d32011-08-28 16:32:09 +00007318 (void) WriteImage(msl_info->image_info[n], msl_info->image[n],
cristyc82a27b2011-10-21 01:07:16 +00007319 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00007320 break;
7321 }
7322 }
7323 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7324 }
7325 default:
7326 {
7327 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7328 break;
7329 }
7330 }
7331 if ( value != NULL )
7332 value=DestroyString(value);
7333 (void) LogMagickEvent(CoderEvent,GetMagickModule()," )");
7334}
7335
7336static void MSLEndElement(void *context,const xmlChar *tag)
7337{
cristybb503372010-05-27 20:51:26 +00007338 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00007339 n;
7340
7341 MSLInfo
7342 *msl_info;
7343
7344 /*
7345 Called when the end of an element has been detected.
7346 */
7347 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.endElement(%s)",
7348 tag);
7349 msl_info=(MSLInfo *) context;
7350 n=msl_info->n;
7351 switch (*tag)
7352 {
7353 case 'C':
7354 case 'c':
7355 {
cristyb988fe72009-09-16 01:01:10 +00007356 if (LocaleCompare((const char *) tag,"comment") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007357 {
7358 (void) DeleteImageProperty(msl_info->image[n],"comment");
7359 if (msl_info->content == (char *) NULL)
7360 break;
7361 StripString(msl_info->content);
7362 (void) SetImageProperty(msl_info->image[n],"comment",
cristyd15e6592011-10-15 00:13:06 +00007363 msl_info->content,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00007364 break;
7365 }
7366 break;
7367 }
7368 case 'G':
7369 case 'g':
7370 {
cristyb988fe72009-09-16 01:01:10 +00007371 if (LocaleCompare((const char *) tag, "group") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007372 {
7373 if (msl_info->group_info[msl_info->number_groups-1].numImages > 0 )
7374 {
cristybb503372010-05-27 20:51:26 +00007375 ssize_t i = (ssize_t)
cristy3ed852e2009-09-05 21:47:34 +00007376 (msl_info->group_info[msl_info->number_groups-1].numImages);
7377 while ( i-- )
7378 {
7379 if (msl_info->image[msl_info->n] != (Image *) NULL)
cristyd15e6592011-10-15 00:13:06 +00007380 msl_info->image[msl_info->n]=DestroyImage(
7381 msl_info->image[msl_info->n]);
7382 msl_info->attributes[msl_info->n]=DestroyImage(
7383 msl_info->attributes[msl_info->n]);
7384 msl_info->image_info[msl_info->n]=DestroyImageInfo(
7385 msl_info->image_info[msl_info->n]);
cristy3ed852e2009-09-05 21:47:34 +00007386 msl_info->n--;
7387 }
7388 }
7389 msl_info->number_groups--;
7390 }
7391 break;
7392 }
7393 case 'I':
7394 case 'i':
7395 {
cristyb988fe72009-09-16 01:01:10 +00007396 if (LocaleCompare((const char *) tag, "image") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007397 MSLPopImage(msl_info);
7398 break;
7399 }
7400 case 'L':
7401 case 'l':
7402 {
cristyb988fe72009-09-16 01:01:10 +00007403 if (LocaleCompare((const char *) tag,"label") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007404 {
7405 (void) DeleteImageProperty(msl_info->image[n],"label");
7406 if (msl_info->content == (char *) NULL)
7407 break;
7408 StripString(msl_info->content);
7409 (void) SetImageProperty(msl_info->image[n],"label",
cristyd15e6592011-10-15 00:13:06 +00007410 msl_info->content,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00007411 break;
7412 }
7413 break;
7414 }
7415 case 'M':
7416 case 'm':
7417 {
cristyb988fe72009-09-16 01:01:10 +00007418 if (LocaleCompare((const char *) tag, "msl") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007419 {
7420 /*
7421 This our base element.
7422 at the moment we don't do anything special
7423 but someday we might!
7424 */
7425 }
7426 break;
7427 }
7428 default:
7429 break;
7430 }
7431 if (msl_info->content != (char *) NULL)
7432 msl_info->content=DestroyString(msl_info->content);
7433}
7434
7435static void MSLCharacters(void *context,const xmlChar *c,int length)
7436{
7437 MSLInfo
7438 *msl_info;
7439
7440 register char
7441 *p;
7442
cristybb503372010-05-27 20:51:26 +00007443 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00007444 i;
7445
7446 /*
7447 Receiving some characters from the parser.
7448 */
7449 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7450 " SAX.characters(%s,%d)",c,length);
7451 msl_info=(MSLInfo *) context;
7452 if (msl_info->content != (char *) NULL)
7453 msl_info->content=(char *) ResizeQuantumMemory(msl_info->content,
7454 strlen(msl_info->content)+length+MaxTextExtent,
7455 sizeof(*msl_info->content));
7456 else
7457 {
7458 msl_info->content=(char *) NULL;
cristy37e0b382011-06-07 13:31:21 +00007459 if (~length >= (MaxTextExtent-1))
cristy3ed852e2009-09-05 21:47:34 +00007460 msl_info->content=(char *) AcquireQuantumMemory(length+MaxTextExtent,
7461 sizeof(*msl_info->content));
7462 if (msl_info->content != (char *) NULL)
7463 *msl_info->content='\0';
7464 }
7465 if (msl_info->content == (char *) NULL)
7466 return;
7467 p=msl_info->content+strlen(msl_info->content);
7468 for (i=0; i < length; i++)
7469 *p++=c[i];
7470 *p='\0';
7471}
7472
7473static void MSLReference(void *context,const xmlChar *name)
7474{
7475 MSLInfo
7476 *msl_info;
7477
7478 xmlParserCtxtPtr
7479 parser;
7480
7481 /*
7482 Called when an entity reference is detected.
7483 */
7484 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7485 " SAX.reference(%s)",name);
7486 msl_info=(MSLInfo *) context;
7487 parser=msl_info->parser;
7488 if (*name == '#')
7489 (void) xmlAddChild(parser->node,xmlNewCharRef(msl_info->document,name));
7490 else
7491 (void) xmlAddChild(parser->node,xmlNewReference(msl_info->document,name));
7492}
7493
7494static void MSLIgnorableWhitespace(void *context,const xmlChar *c,int length)
7495{
7496 MSLInfo
7497 *msl_info;
7498
7499 /*
7500 Receiving some ignorable whitespaces from the parser.
7501 */
7502 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7503 " SAX.ignorableWhitespace(%.30s, %d)",c,length);
7504 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007505 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007506}
7507
7508static void MSLProcessingInstructions(void *context,const xmlChar *target,
7509 const xmlChar *data)
7510{
7511 MSLInfo
7512 *msl_info;
7513
7514 /*
7515 A processing instruction has been parsed.
7516 */
7517 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7518 " SAX.processingInstruction(%s, %s)",
7519 target,data);
7520 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007521 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007522}
7523
7524static void MSLComment(void *context,const xmlChar *value)
7525{
7526 MSLInfo
7527 *msl_info;
7528
7529 /*
7530 A comment has been parsed.
7531 */
7532 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7533 " SAX.comment(%s)",value);
7534 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007535 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007536}
7537
7538static void MSLWarning(void *context,const char *format,...)
7539{
7540 char
7541 *message,
7542 reason[MaxTextExtent];
7543
7544 MSLInfo
7545 *msl_info;
7546
7547 va_list
7548 operands;
7549
7550 /**
7551 Display and format a warning messages, gives file, line, position and
7552 extra parameters.
7553 */
7554 va_start(operands,format);
7555 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.warning: ");
7556 (void) LogMagickEvent(CoderEvent,GetMagickModule(),format,operands);
7557 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007558 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007559#if !defined(MAGICKCORE_HAVE_VSNPRINTF)
7560 (void) vsprintf(reason,format,operands);
7561#else
7562 (void) vsnprintf(reason,MaxTextExtent,format,operands);
7563#endif
7564 message=GetExceptionMessage(errno);
7565 ThrowMSLException(CoderError,reason,message);
7566 message=DestroyString(message);
7567 va_end(operands);
7568}
7569
7570static void MSLError(void *context,const char *format,...)
7571{
7572 char
7573 reason[MaxTextExtent];
7574
7575 MSLInfo
7576 *msl_info;
7577
7578 va_list
7579 operands;
7580
7581 /*
7582 Display and format a error formats, gives file, line, position and
7583 extra parameters.
7584 */
7585 va_start(operands,format);
7586 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.error: ");
7587 (void) LogMagickEvent(CoderEvent,GetMagickModule(),format,operands);
7588 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007589 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007590#if !defined(MAGICKCORE_HAVE_VSNPRINTF)
7591 (void) vsprintf(reason,format,operands);
7592#else
7593 (void) vsnprintf(reason,MaxTextExtent,format,operands);
7594#endif
7595 ThrowMSLException(DelegateFatalError,reason,"SAX error");
7596 va_end(operands);
7597}
7598
7599static void MSLCDataBlock(void *context,const xmlChar *value,int length)
7600{
7601 MSLInfo
7602 *msl_info;
7603
7604 xmlNodePtr
7605 child;
7606
7607 xmlParserCtxtPtr
7608 parser;
7609
7610 /*
7611 Called when a pcdata block has been parsed.
7612 */
7613 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7614 " SAX.pcdata(%s, %d)",value,length);
7615 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007616 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007617 parser=msl_info->parser;
7618 child=xmlGetLastChild(parser->node);
7619 if ((child != (xmlNodePtr) NULL) && (child->type == XML_CDATA_SECTION_NODE))
7620 {
7621 xmlTextConcat(child,value,length);
7622 return;
7623 }
7624 (void) xmlAddChild(parser->node,xmlNewCDataBlock(parser->myDoc,value,length));
7625}
7626
7627static void MSLExternalSubset(void *context,const xmlChar *name,
7628 const xmlChar *external_id,const xmlChar *system_id)
7629{
7630 MSLInfo
7631 *msl_info;
7632
7633 xmlParserCtxt
7634 parser_context;
7635
7636 xmlParserCtxtPtr
7637 parser;
7638
7639 xmlParserInputPtr
7640 input;
7641
7642 /*
7643 Does this document has an external subset?
7644 */
7645 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7646 " SAX.externalSubset(%s %s %s)",name,
cristyb988fe72009-09-16 01:01:10 +00007647 (external_id != (const xmlChar *) NULL ? (const char *) external_id : " "),
7648 (system_id != (const xmlChar *) NULL ? (const char *) system_id : " "));
cristy3ed852e2009-09-05 21:47:34 +00007649 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007650 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007651 parser=msl_info->parser;
7652 if (((external_id == NULL) && (system_id == NULL)) ||
7653 ((parser->validate == 0) || (parser->wellFormed == 0) ||
7654 (msl_info->document == 0)))
7655 return;
7656 input=MSLResolveEntity(context,external_id,system_id);
7657 if (input == NULL)
7658 return;
7659 (void) xmlNewDtd(msl_info->document,name,external_id,system_id);
7660 parser_context=(*parser);
7661 parser->inputTab=(xmlParserInputPtr *) xmlMalloc(5*sizeof(*parser->inputTab));
7662 if (parser->inputTab == (xmlParserInputPtr *) NULL)
7663 {
7664 parser->errNo=XML_ERR_NO_MEMORY;
7665 parser->input=parser_context.input;
7666 parser->inputNr=parser_context.inputNr;
7667 parser->inputMax=parser_context.inputMax;
7668 parser->inputTab=parser_context.inputTab;
7669 return;
7670 }
7671 parser->inputNr=0;
7672 parser->inputMax=5;
7673 parser->input=NULL;
7674 xmlPushInput(parser,input);
7675 (void) xmlSwitchEncoding(parser,xmlDetectCharEncoding(parser->input->cur,4));
7676 if (input->filename == (char *) NULL)
7677 input->filename=(char *) xmlStrdup(system_id);
7678 input->line=1;
7679 input->col=1;
7680 input->base=parser->input->cur;
7681 input->cur=parser->input->cur;
7682 input->free=NULL;
7683 xmlParseExternalSubset(parser,external_id,system_id);
7684 while (parser->inputNr > 1)
7685 (void) xmlPopInput(parser);
7686 xmlFreeInputStream(parser->input);
7687 xmlFree(parser->inputTab);
7688 parser->input=parser_context.input;
7689 parser->inputNr=parser_context.inputNr;
7690 parser->inputMax=parser_context.inputMax;
7691 parser->inputTab=parser_context.inputTab;
7692}
7693
7694#if defined(__cplusplus) || defined(c_plusplus)
7695}
7696#endif
7697
7698static MagickBooleanType ProcessMSLScript(const ImageInfo *image_info,Image **image,
7699 ExceptionInfo *exception)
7700{
cristy3ed852e2009-09-05 21:47:34 +00007701 char
7702 message[MaxTextExtent];
7703
7704 Image
7705 *msl_image;
7706
7707 int
7708 status;
7709
cristybb503372010-05-27 20:51:26 +00007710 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00007711 n;
7712
7713 MSLInfo
7714 msl_info;
7715
cristy5f6f01c2009-11-19 19:36:42 +00007716 xmlSAXHandler
7717 sax_modules;
7718
cristy3ed852e2009-09-05 21:47:34 +00007719 xmlSAXHandlerPtr
cristy5f6f01c2009-11-19 19:36:42 +00007720 sax_handler;
cristy3ed852e2009-09-05 21:47:34 +00007721
7722 /*
7723 Open image file.
7724 */
7725 assert(image_info != (const ImageInfo *) NULL);
7726 assert(image_info->signature == MagickSignature);
7727 if (image_info->debug != MagickFalse)
cristy5f6f01c2009-11-19 19:36:42 +00007728 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
7729 image_info->filename);
cristy3ed852e2009-09-05 21:47:34 +00007730 assert(image != (Image **) NULL);
cristy9950d572011-10-01 18:22:35 +00007731 msl_image=AcquireImage(image_info,exception);
cristy3ed852e2009-09-05 21:47:34 +00007732 status=OpenBlob(image_info,msl_image,ReadBinaryBlobMode,exception);
7733 if (status == MagickFalse)
7734 {
7735 ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
7736 msl_image->filename);
7737 msl_image=DestroyImageList(msl_image);
7738 return(MagickFalse);
7739 }
7740 msl_image->columns=1;
7741 msl_image->rows=1;
7742 /*
7743 Parse MSL file.
7744 */
7745 (void) ResetMagickMemory(&msl_info,0,sizeof(msl_info));
7746 msl_info.exception=exception;
7747 msl_info.image_info=(ImageInfo **) AcquireMagickMemory(
7748 sizeof(*msl_info.image_info));
7749 msl_info.draw_info=(DrawInfo **) AcquireMagickMemory(
7750 sizeof(*msl_info.draw_info));
7751 /* top of the stack is the MSL file itself */
cristy73bd4a52010-10-05 11:24:23 +00007752 msl_info.image=(Image **) AcquireMagickMemory(sizeof(*msl_info.image));
cristy3ed852e2009-09-05 21:47:34 +00007753 msl_info.attributes=(Image **) AcquireMagickMemory(
7754 sizeof(*msl_info.attributes));
7755 msl_info.group_info=(MSLGroupInfo *) AcquireMagickMemory(
7756 sizeof(*msl_info.group_info));
7757 if ((msl_info.image_info == (ImageInfo **) NULL) ||
7758 (msl_info.image == (Image **) NULL) ||
7759 (msl_info.attributes == (Image **) NULL) ||
7760 (msl_info.group_info == (MSLGroupInfo *) NULL))
7761 ThrowFatalException(ResourceLimitFatalError,
7762 "UnableToInterpretMSLImage");
7763 *msl_info.image_info=CloneImageInfo(image_info);
7764 *msl_info.draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL);
cristy9950d572011-10-01 18:22:35 +00007765 *msl_info.attributes=AcquireImage(image_info,exception);
cristy3ed852e2009-09-05 21:47:34 +00007766 msl_info.group_info[0].numImages=0;
7767 /* the first slot is used to point to the MSL file image */
7768 *msl_info.image=msl_image;
7769 if (*image != (Image *) NULL)
7770 MSLPushImage(&msl_info,*image);
7771 (void) xmlSubstituteEntitiesDefault(1);
cristy5f6f01c2009-11-19 19:36:42 +00007772 (void) ResetMagickMemory(&sax_modules,0,sizeof(sax_modules));
7773 sax_modules.internalSubset=MSLInternalSubset;
7774 sax_modules.isStandalone=MSLIsStandalone;
7775 sax_modules.hasInternalSubset=MSLHasInternalSubset;
7776 sax_modules.hasExternalSubset=MSLHasExternalSubset;
7777 sax_modules.resolveEntity=MSLResolveEntity;
7778 sax_modules.getEntity=MSLGetEntity;
7779 sax_modules.entityDecl=MSLEntityDeclaration;
7780 sax_modules.notationDecl=MSLNotationDeclaration;
7781 sax_modules.attributeDecl=MSLAttributeDeclaration;
7782 sax_modules.elementDecl=MSLElementDeclaration;
7783 sax_modules.unparsedEntityDecl=MSLUnparsedEntityDeclaration;
7784 sax_modules.setDocumentLocator=MSLSetDocumentLocator;
7785 sax_modules.startDocument=MSLStartDocument;
7786 sax_modules.endDocument=MSLEndDocument;
7787 sax_modules.startElement=MSLStartElement;
7788 sax_modules.endElement=MSLEndElement;
7789 sax_modules.reference=MSLReference;
7790 sax_modules.characters=MSLCharacters;
7791 sax_modules.ignorableWhitespace=MSLIgnorableWhitespace;
7792 sax_modules.processingInstruction=MSLProcessingInstructions;
7793 sax_modules.comment=MSLComment;
7794 sax_modules.warning=MSLWarning;
7795 sax_modules.error=MSLError;
7796 sax_modules.fatalError=MSLError;
7797 sax_modules.getParameterEntity=MSLGetParameterEntity;
7798 sax_modules.cdataBlock=MSLCDataBlock;
7799 sax_modules.externalSubset=MSLExternalSubset;
7800 sax_handler=(&sax_modules);
7801 msl_info.parser=xmlCreatePushParserCtxt(sax_handler,&msl_info,(char *) NULL,0,
cristy3ed852e2009-09-05 21:47:34 +00007802 msl_image->filename);
7803 while (ReadBlobString(msl_image,message) != (char *) NULL)
7804 {
cristybb503372010-05-27 20:51:26 +00007805 n=(ssize_t) strlen(message);
cristy3ed852e2009-09-05 21:47:34 +00007806 if (n == 0)
7807 continue;
7808 status=xmlParseChunk(msl_info.parser,message,(int) n,MagickFalse);
7809 if (status != 0)
7810 break;
7811 (void) xmlParseChunk(msl_info.parser," ",1,MagickFalse);
7812 if (msl_info.exception->severity >= ErrorException)
7813 break;
7814 }
7815 if (msl_info.exception->severity == UndefinedException)
7816 (void) xmlParseChunk(msl_info.parser," ",1,MagickTrue);
7817 xmlFreeParserCtxt(msl_info.parser);
7818 (void) LogMagickEvent(CoderEvent,GetMagickModule(),"end SAX");
7819 xmlCleanupParser();
7820 msl_info.group_info=(MSLGroupInfo *) RelinquishMagickMemory(
7821 msl_info.group_info);
7822 if (*image == (Image *) NULL)
7823 *image=(*msl_info.image);
cristyc82a27b2011-10-21 01:07:16 +00007824 if (msl_info.exception->severity != UndefinedException)
cristy5f6f01c2009-11-19 19:36:42 +00007825 return(MagickFalse);
7826 return(MagickTrue);
cristy3ed852e2009-09-05 21:47:34 +00007827}
7828
7829static Image *ReadMSLImage(const ImageInfo *image_info,ExceptionInfo *exception)
7830{
7831 Image
7832 *image;
7833
7834 /*
7835 Open image file.
7836 */
7837 assert(image_info != (const ImageInfo *) NULL);
7838 assert(image_info->signature == MagickSignature);
7839 if (image_info->debug != MagickFalse)
7840 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
7841 image_info->filename);
7842 assert(exception != (ExceptionInfo *) NULL);
7843 assert(exception->signature == MagickSignature);
7844 image=(Image *) NULL;
7845 (void) ProcessMSLScript(image_info,&image,exception);
7846 return(GetFirstImageInList(image));
7847}
7848#endif
7849
7850/*
7851%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7852% %
7853% %
7854% %
7855% R e g i s t e r M S L I m a g e %
7856% %
7857% %
7858% %
7859%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7860%
7861% RegisterMSLImage() adds attributes for the MSL image format to
7862% the list of supported formats. The attributes include the image format
7863% tag, a method to read and/or write the format, whether the format
7864% supports the saving of more than one frame to the same file or blob,
7865% whether the format supports native in-memory I/O, and a brief
7866% description of the format.
7867%
7868% The format of the RegisterMSLImage method is:
7869%
cristybb503372010-05-27 20:51:26 +00007870% size_t RegisterMSLImage(void)
cristy3ed852e2009-09-05 21:47:34 +00007871%
7872*/
cristybb503372010-05-27 20:51:26 +00007873ModuleExport size_t RegisterMSLImage(void)
cristy3ed852e2009-09-05 21:47:34 +00007874{
7875 MagickInfo
7876 *entry;
7877
7878 entry=SetMagickInfo("MSL");
7879#if defined(MAGICKCORE_XML_DELEGATE)
7880 entry->decoder=(DecodeImageHandler *) ReadMSLImage;
7881 entry->encoder=(EncodeImageHandler *) WriteMSLImage;
7882#endif
7883 entry->description=ConstantString("Magick Scripting Language");
7884 entry->module=ConstantString("MSL");
7885 (void) RegisterMagickInfo(entry);
7886 return(MagickImageCoderSignature);
7887}
7888
cristy6b9f7ed2010-04-24 01:08:02 +00007889#if defined(MAGICKCORE_XML_DELEGATE)
cristy3ed852e2009-09-05 21:47:34 +00007890/*
7891%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7892% %
7893% %
7894% %
cristyb988fe72009-09-16 01:01:10 +00007895% S e t M S L A t t r i b u t e s %
7896% %
7897% %
7898% %
7899%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7900%
7901% SetMSLAttributes() ...
7902%
7903% The format of the SetMSLAttributes method is:
7904%
7905% MagickBooleanType SetMSLAttributes(MSLInfo *msl_info,
cristyb20775d2009-09-16 01:51:41 +00007906% const char *keyword,const char *value)
cristyb988fe72009-09-16 01:01:10 +00007907%
7908% A description of each parameter follows:
7909%
7910% o msl_info: the MSL info.
7911%
cristyb20775d2009-09-16 01:51:41 +00007912% o keyword: the keyword.
7913%
7914% o value: the value.
cristyb988fe72009-09-16 01:01:10 +00007915%
7916*/
cristyb20775d2009-09-16 01:51:41 +00007917static MagickBooleanType SetMSLAttributes(MSLInfo *msl_info,const char *keyword,
7918 const char *value)
cristyb988fe72009-09-16 01:01:10 +00007919{
cristy4582cbb2009-09-23 00:35:43 +00007920 Image
7921 *attributes;
7922
cristyb20775d2009-09-16 01:51:41 +00007923 DrawInfo
7924 *draw_info;
cristyb988fe72009-09-16 01:01:10 +00007925
7926 ExceptionInfo
7927 *exception;
7928
cristy4582cbb2009-09-23 00:35:43 +00007929 GeometryInfo
7930 geometry_info;
7931
cristy4fa36e42009-09-18 14:24:06 +00007932 Image
7933 *image;
7934
cristyb20775d2009-09-16 01:51:41 +00007935 ImageInfo
7936 *image_info;
7937
cristy4582cbb2009-09-23 00:35:43 +00007938 int
7939 flags;
7940
cristybb503372010-05-27 20:51:26 +00007941 ssize_t
cristyb988fe72009-09-16 01:01:10 +00007942 n;
7943
cristyb988fe72009-09-16 01:01:10 +00007944 assert(msl_info != (MSLInfo *) NULL);
cristyb20775d2009-09-16 01:51:41 +00007945 if (keyword == (const char *) NULL)
7946 return(MagickTrue);
7947 if (value == (const char *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007948 return(MagickTrue);
7949 exception=msl_info->exception;
7950 n=msl_info->n;
cristy4582cbb2009-09-23 00:35:43 +00007951 attributes=msl_info->attributes[n];
cristyb20775d2009-09-16 01:51:41 +00007952 image_info=msl_info->image_info[n];
7953 draw_info=msl_info->draw_info[n];
cristy4fa36e42009-09-18 14:24:06 +00007954 image=msl_info->image[n];
cristyb20775d2009-09-16 01:51:41 +00007955 switch (*keyword)
cristyb988fe72009-09-16 01:01:10 +00007956 {
cristyfb758a52009-09-16 14:36:08 +00007957 case 'A':
7958 case 'a':
7959 {
7960 if (LocaleCompare(keyword,"adjoin") == 0)
7961 {
cristybb503372010-05-27 20:51:26 +00007962 ssize_t
cristyfb758a52009-09-16 14:36:08 +00007963 adjoin;
7964
cristy042ee782011-04-22 18:48:30 +00007965 adjoin=ParseCommandOption(MagickBooleanOptions,MagickFalse,value);
cristyfb758a52009-09-16 14:36:08 +00007966 if (adjoin < 0)
7967 ThrowMSLException(OptionError,"UnrecognizedType",value);
7968 image_info->adjoin=(MagickBooleanType) adjoin;
7969 break;
7970 }
cristy4fa36e42009-09-18 14:24:06 +00007971 if (LocaleCompare(keyword,"alpha") == 0)
7972 {
cristybb503372010-05-27 20:51:26 +00007973 ssize_t
cristy4fa36e42009-09-18 14:24:06 +00007974 alpha;
7975
cristy042ee782011-04-22 18:48:30 +00007976 alpha=ParseCommandOption(MagickAlphaOptions,MagickFalse,value);
cristy4fa36e42009-09-18 14:24:06 +00007977 if (alpha < 0)
7978 ThrowMSLException(OptionError,"UnrecognizedType",value);
cristy4582cbb2009-09-23 00:35:43 +00007979 if (image != (Image *) NULL)
cristy63240882011-08-05 19:05:27 +00007980 (void) SetImageAlphaChannel(image,(AlphaChannelType) alpha,
7981 exception);
cristy4582cbb2009-09-23 00:35:43 +00007982 break;
7983 }
7984 if (LocaleCompare(keyword,"antialias") == 0)
7985 {
cristybb503372010-05-27 20:51:26 +00007986 ssize_t
cristy4582cbb2009-09-23 00:35:43 +00007987 antialias;
7988
cristy042ee782011-04-22 18:48:30 +00007989 antialias=ParseCommandOption(MagickBooleanOptions,MagickFalse,value);
cristy4582cbb2009-09-23 00:35:43 +00007990 if (antialias < 0)
7991 ThrowMSLException(OptionError,"UnrecognizedGravityType",value);
7992 image_info->antialias=(MagickBooleanType) antialias;
7993 break;
7994 }
7995 if (LocaleCompare(keyword,"area-limit") == 0)
7996 {
7997 MagickSizeType
7998 limit;
7999
8000 limit=MagickResourceInfinity;
8001 if (LocaleCompare(value,"unlimited") != 0)
cristydbdd0e32011-11-04 23:29:40 +00008002 limit=(MagickSizeType) StringToDoubleInterval(value,100.0);
cristy4582cbb2009-09-23 00:35:43 +00008003 (void) SetMagickResourceLimit(AreaResource,limit);
8004 break;
8005 }
8006 if (LocaleCompare(keyword,"attenuate") == 0)
8007 {
8008 (void) SetImageOption(image_info,keyword,value);
8009 break;
8010 }
8011 if (LocaleCompare(keyword,"authenticate") == 0)
8012 {
8013 (void) CloneString(&image_info->density,value);
cristy4fa36e42009-09-18 14:24:06 +00008014 break;
8015 }
cristyfb758a52009-09-16 14:36:08 +00008016 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8017 break;
8018 }
cristyb20775d2009-09-16 01:51:41 +00008019 case 'B':
8020 case 'b':
cristyb988fe72009-09-16 01:01:10 +00008021 {
cristyb20775d2009-09-16 01:51:41 +00008022 if (LocaleCompare(keyword,"background") == 0)
8023 {
cristy9950d572011-10-01 18:22:35 +00008024 (void) QueryColorCompliance(value,AllCompliance,
8025 &image_info->background_color,exception);
cristyb20775d2009-09-16 01:51:41 +00008026 break;
8027 }
cristy4582cbb2009-09-23 00:35:43 +00008028 if (LocaleCompare(keyword,"bias") == 0)
8029 {
8030 if (image == (Image *) NULL)
8031 break;
cristydbdd0e32011-11-04 23:29:40 +00008032 image->bias=StringToDoubleInterval(value,QuantumRange);
cristy4582cbb2009-09-23 00:35:43 +00008033 break;
8034 }
8035 if (LocaleCompare(keyword,"blue-primary") == 0)
8036 {
8037 if (image == (Image *) NULL)
8038 break;
8039 flags=ParseGeometry(value,&geometry_info);
8040 image->chromaticity.blue_primary.x=geometry_info.rho;
8041 image->chromaticity.blue_primary.y=geometry_info.sigma;
8042 if ((flags & SigmaValue) == 0)
8043 image->chromaticity.blue_primary.y=
8044 image->chromaticity.blue_primary.x;
8045 break;
8046 }
cristy2c8b6312009-09-16 02:37:23 +00008047 if (LocaleCompare(keyword,"bordercolor") == 0)
8048 {
cristy9950d572011-10-01 18:22:35 +00008049 (void) QueryColorCompliance(value,AllCompliance,
8050 &image_info->border_color,exception);
cristy2c8b6312009-09-16 02:37:23 +00008051 break;
8052 }
8053 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8054 break;
8055 }
8056 case 'D':
8057 case 'd':
8058 {
8059 if (LocaleCompare(keyword,"density") == 0)
8060 {
8061 (void) CloneString(&image_info->density,value);
8062 (void) CloneString(&draw_info->density,value);
8063 break;
8064 }
cristyb20775d2009-09-16 01:51:41 +00008065 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8066 break;
8067 }
8068 case 'F':
8069 case 'f':
8070 {
8071 if (LocaleCompare(keyword,"fill") == 0)
8072 {
cristy9950d572011-10-01 18:22:35 +00008073 (void) QueryColorCompliance(value,AllCompliance,&draw_info->fill,
8074 exception);
cristya30afaf2009-09-22 13:42:12 +00008075 (void) SetImageOption(image_info,keyword,value);
cristyb20775d2009-09-16 01:51:41 +00008076 break;
8077 }
cristy4582cbb2009-09-23 00:35:43 +00008078 if (LocaleCompare(keyword,"filename") == 0)
8079 {
8080 (void) CopyMagickString(image_info->filename,value,MaxTextExtent);
8081 break;
8082 }
8083 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8084 break;
8085 }
8086 case 'G':
8087 case 'g':
8088 {
8089 if (LocaleCompare(keyword,"gravity") == 0)
8090 {
cristybb503372010-05-27 20:51:26 +00008091 ssize_t
cristy4582cbb2009-09-23 00:35:43 +00008092 gravity;
8093
cristy042ee782011-04-22 18:48:30 +00008094 gravity=ParseCommandOption(MagickGravityOptions,MagickFalse,value);
cristy4582cbb2009-09-23 00:35:43 +00008095 if (gravity < 0)
8096 ThrowMSLException(OptionError,"UnrecognizedGravityType",value);
8097 (void) SetImageOption(image_info,keyword,value);
8098 break;
8099 }
cristyb20775d2009-09-16 01:51:41 +00008100 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8101 break;
8102 }
8103 case 'I':
8104 case 'i':
8105 {
8106 if (LocaleCompare(keyword,"id") == 0)
8107 {
cristyd15e6592011-10-15 00:13:06 +00008108 (void) SetImageProperty(attributes,keyword,value,exception);
cristy2c8b6312009-09-16 02:37:23 +00008109 break;
8110 }
8111 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8112 break;
8113 }
8114 case 'M':
8115 case 'm':
8116 {
8117 if (LocaleCompare(keyword,"magick") == 0)
8118 {
8119 (void) CopyMagickString(image_info->magick,value,MaxTextExtent);
8120 break;
8121 }
cristy2c8b6312009-09-16 02:37:23 +00008122 if (LocaleCompare(keyword,"mattecolor") == 0)
8123 {
cristy9950d572011-10-01 18:22:35 +00008124 (void) QueryColorCompliance(value,AllCompliance,
8125 &image_info->matte_color,exception);
cristyb20775d2009-09-16 01:51:41 +00008126 break;
8127 }
8128 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8129 break;
8130 }
8131 case 'P':
8132 case 'p':
8133 {
8134 if (LocaleCompare(keyword,"pointsize") == 0)
8135 {
cristydbdd0e32011-11-04 23:29:40 +00008136 image_info->pointsize=StringToDouble(value,(char **) NULL);
8137 draw_info->pointsize=StringToDouble(value,(char **) NULL);
cristyb20775d2009-09-16 01:51:41 +00008138 break;
8139 }
8140 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8141 break;
8142 }
cristy4582cbb2009-09-23 00:35:43 +00008143 case 'Q':
8144 case 'q':
8145 {
8146 if (LocaleCompare(keyword,"quality") == 0)
8147 {
cristyf2f27272009-12-17 14:48:46 +00008148 image_info->quality=StringToLong(value);
cristy4582cbb2009-09-23 00:35:43 +00008149 if (image == (Image *) NULL)
8150 break;
cristyf2f27272009-12-17 14:48:46 +00008151 image->quality=StringToLong(value);
cristy4582cbb2009-09-23 00:35:43 +00008152 break;
8153 }
8154 break;
8155 }
cristyb20775d2009-09-16 01:51:41 +00008156 case 'S':
8157 case 's':
8158 {
8159 if (LocaleCompare(keyword,"size") == 0)
8160 {
cristy2c8b6312009-09-16 02:37:23 +00008161 (void) CloneString(&image_info->size,value);
cristyb20775d2009-09-16 01:51:41 +00008162 break;
8163 }
8164 if (LocaleCompare(keyword,"stroke") == 0)
8165 {
cristy9950d572011-10-01 18:22:35 +00008166 (void) QueryColorCompliance(value,AllCompliance,&draw_info->stroke,
8167 exception);
cristya30afaf2009-09-22 13:42:12 +00008168 (void) SetImageOption(image_info,keyword,value);
cristyb20775d2009-09-16 01:51:41 +00008169 break;
8170 }
8171 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8172 break;
8173 }
8174 default:
8175 {
8176 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8177 break;
cristyb988fe72009-09-16 01:01:10 +00008178 }
8179 }
8180 return(MagickTrue);
8181}
cristy6b9f7ed2010-04-24 01:08:02 +00008182#endif
cristyb988fe72009-09-16 01:01:10 +00008183
8184/*
8185%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8186% %
8187% %
8188% %
cristy3ed852e2009-09-05 21:47:34 +00008189% U n r e g i s t e r M S L I m a g e %
8190% %
8191% %
8192% %
8193%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8194%
8195% UnregisterMSLImage() removes format registrations made by the
8196% MSL module from the list of supported formats.
8197%
8198% The format of the UnregisterMSLImage method is:
8199%
8200% UnregisterMSLImage(void)
8201%
8202*/
8203ModuleExport void UnregisterMSLImage(void)
8204{
8205 (void) UnregisterMagickInfo("MSL");
8206}
8207
8208#if defined(MAGICKCORE_XML_DELEGATE)
8209/*
8210%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8211% %
8212% %
8213% %
8214% W r i t e M S L I m a g e %
8215% %
8216% %
8217% %
8218%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8219%
8220% WriteMSLImage() writes an image to a file in MVG image format.
8221%
8222% The format of the WriteMSLImage method is:
8223%
cristy1e178e72011-08-28 19:44:34 +00008224% MagickBooleanType WriteMSLImage(const ImageInfo *image_info,
8225% Image *image,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00008226%
8227% A description of each parameter follows.
8228%
8229% o image_info: the image info.
8230%
8231% o image: The image.
8232%
cristy1e178e72011-08-28 19:44:34 +00008233% o exception: return any errors or warnings in this structure.
8234%
cristy3ed852e2009-09-05 21:47:34 +00008235*/
cristy1e178e72011-08-28 19:44:34 +00008236static MagickBooleanType WriteMSLImage(const ImageInfo *image_info,Image *image,
8237 ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00008238{
8239 assert(image_info != (const ImageInfo *) NULL);
8240 assert(image_info->signature == MagickSignature);
8241 assert(image != (Image *) NULL);
8242 assert(image->signature == MagickSignature);
8243 if (image->debug != MagickFalse)
8244 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
8245 (void) ReferenceImage(image);
cristy1e178e72011-08-28 19:44:34 +00008246 (void) ProcessMSLScript(image_info,&image,exception);
cristy3ed852e2009-09-05 21:47:34 +00008247 return(MagickTrue);
8248}
8249#endif