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