blob: 33abebde0bf28ae792ab455b8a7a7859f4626442 [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 %
cristyde984cd2013-12-01 14:49:27 +000016% Cristy %
cristy3ed852e2009-09-05 21:47:34 +000017% Leonard Rosenthol %
18% William Radcliffe %
19% December 2001 %
20% %
21% %
cristyb56bb242014-11-25 17:12:48 +000022% Copyright 1999-2015 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"
cristy6a2180c2013-05-27 10:28:36 +000052#include "MagickCore/channel.h"
cristy4c08aed2011-07-01 19:47:50 +000053#include "MagickCore/color.h"
cristy4c08aed2011-07-01 19:47:50 +000054#include "MagickCore/color-private.h"
cristy9950d572011-10-01 18:22:35 +000055#include "MagickCore/colormap.h"
cristy4c08aed2011-07-01 19:47:50 +000056#include "MagickCore/composite.h"
57#include "MagickCore/constitute.h"
58#include "MagickCore/decorate.h"
59#include "MagickCore/display.h"
cristyc53413d2011-11-17 13:04:26 +000060#include "MagickCore/distort.h"
cristy4c08aed2011-07-01 19:47:50 +000061#include "MagickCore/draw.h"
62#include "MagickCore/effect.h"
63#include "MagickCore/enhance.h"
64#include "MagickCore/exception.h"
65#include "MagickCore/exception-private.h"
66#include "MagickCore/fx.h"
67#include "MagickCore/geometry.h"
68#include "MagickCore/image.h"
69#include "MagickCore/image-private.h"
70#include "MagickCore/list.h"
71#include "MagickCore/log.h"
72#include "MagickCore/magick.h"
73#include "MagickCore/memory_.h"
74#include "MagickCore/module.h"
75#include "MagickCore/option.h"
76#include "MagickCore/paint.h"
77#include "MagickCore/pixel-accessor.h"
78#include "MagickCore/profile.h"
79#include "MagickCore/property.h"
80#include "MagickCore/quantize.h"
81#include "MagickCore/quantum-private.h"
82#include "MagickCore/registry.h"
83#include "MagickCore/resize.h"
84#include "MagickCore/resource_.h"
85#include "MagickCore/segment.h"
cristy28039352011-11-17 13:15:46 +000086#include "MagickCore/shear.h"
cristy4c08aed2011-07-01 19:47:50 +000087#include "MagickCore/signature.h"
cristy7497f482011-12-08 01:57:31 +000088#include "MagickCore/statistic.h"
cristy4c08aed2011-07-01 19:47:50 +000089#include "MagickCore/static.h"
90#include "MagickCore/string_.h"
91#include "MagickCore/string-private.h"
92#include "MagickCore/transform.h"
93#include "MagickCore/threshold.h"
94#include "MagickCore/utility.h"
cristy3ed852e2009-09-05 21:47:34 +000095#if defined(MAGICKCORE_XML_DELEGATE)
cristy0157aea2010-04-24 21:12:18 +000096# if defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy14e6cc72014-10-05 19:31:31 +000097# if !defined(__MINGW32__) && !defined(__MINGW64__)
cristy3ed852e2009-09-05 21:47:34 +000098# include <win32config.h>
99# endif
100# endif
101# include <libxml/parser.h>
102# include <libxml/xmlmemory.h>
103# include <libxml/parserInternals.h>
104# include <libxml/xmlerror.h>
105#endif
106
107/*
108 Define Declatations.
109*/
110#define ThrowMSLException(severity,tag,reason) \
111 (void) ThrowMagickException(msl_info->exception,GetMagickModule(),severity, \
112 tag,"`%s'",reason);
113
114/*
115 Typedef declaractions.
116*/
117typedef struct _MSLGroupInfo
118{
cristybb503372010-05-27 20:51:26 +0000119 size_t
cristy3ed852e2009-09-05 21:47:34 +0000120 numImages; /* how many images are in this group */
121} MSLGroupInfo;
122
123typedef struct _MSLInfo
124{
125 ExceptionInfo
126 *exception;
127
cristybb503372010-05-27 20:51:26 +0000128 ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000129 n,
130 number_groups;
131
132 ImageInfo
133 **image_info;
134
135 DrawInfo
136 **draw_info;
137
138 Image
139 **attributes,
140 **image;
141
142 char
143 *content;
144
145 MSLGroupInfo
146 *group_info;
147
148#if defined(MAGICKCORE_XML_DELEGATE)
149 xmlParserCtxtPtr
150 parser;
151
152 xmlDocPtr
153 document;
154#endif
155} MSLInfo;
156
157/*
158 Forward declarations.
159*/
160#if defined(MAGICKCORE_XML_DELEGATE)
161static MagickBooleanType
cristy1e178e72011-08-28 19:44:34 +0000162 WriteMSLImage(const ImageInfo *,Image *,ExceptionInfo *);
cristyb988fe72009-09-16 01:01:10 +0000163
164static MagickBooleanType
cristyb20775d2009-09-16 01:51:41 +0000165 SetMSLAttributes(MSLInfo *,const char *,const char *);
cristy3ed852e2009-09-05 21:47:34 +0000166#endif
167
168#if defined(MAGICKCORE_XML_DELEGATE)
cristyb988fe72009-09-16 01:01:10 +0000169
cristy3ed852e2009-09-05 21:47:34 +0000170/*
171%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
172% %
173% %
174% %
175% R e a d M S L I m a g e %
176% %
177% %
178% %
179%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
180%
181% ReadMSLImage() reads a Magick Scripting Language file and returns it.
182% It allocates the memory necessary for the new Image structure and returns a
183% pointer to the new image.
184%
185% The format of the ReadMSLImage method is:
186%
187% Image *ReadMSLImage(const ImageInfo *image_info,ExceptionInfo *exception)
188%
189% A description of each parameter follows:
190%
191% o image_info: the image info.
192%
193% o exception: return any errors or warnings in this structure.
194%
cristy3ed852e2009-09-05 21:47:34 +0000195*/
196
197#if defined(__cplusplus) || defined(c_plusplus)
198extern "C" {
199#endif
200
cristy4fa36e42009-09-18 14:24:06 +0000201static inline Image *GetImageCache(const ImageInfo *image_info,const char *path,
202 ExceptionInfo *exception)
203{
204 char
cristy151b66d2015-04-15 10:50:31 +0000205 key[MagickPathExtent];
cristy4fa36e42009-09-18 14:24:06 +0000206
207 ExceptionInfo
208 *sans_exception;
209
210 Image
211 *image;
212
213 ImageInfo
214 *read_info;
215
cristy151b66d2015-04-15 10:50:31 +0000216 (void) FormatLocaleString(key,MagickPathExtent,"cache:%s",path);
cristy4fa36e42009-09-18 14:24:06 +0000217 sans_exception=AcquireExceptionInfo();
218 image=(Image *) GetImageRegistry(ImageRegistryType,key,sans_exception);
219 sans_exception=DestroyExceptionInfo(sans_exception);
220 if (image != (Image *) NULL)
221 return(image);
222 read_info=CloneImageInfo(image_info);
cristy151b66d2015-04-15 10:50:31 +0000223 (void) CopyMagickString(read_info->filename,path,MagickPathExtent);
cristy4fa36e42009-09-18 14:24:06 +0000224 image=ReadImage(read_info,exception);
225 read_info=DestroyImageInfo(read_info);
226 if (image != (Image *) NULL)
227 (void) SetImageRegistry(ImageRegistryType,key,image,exception);
228 return(image);
229}
230
231static int IsPathDirectory(const char *path)
232{
233 MagickBooleanType
234 status;
235
236 struct stat
237 attributes;
238
239 if ((path == (const char *) NULL) || (*path == '\0'))
240 return(MagickFalse);
241 status=GetPathAttributes(path,&attributes);
242 if (status == MagickFalse)
243 return(-1);
244 if (S_ISDIR(attributes.st_mode) == 0)
245 return(0);
246 return(1);
247}
248
cristy3ed852e2009-09-05 21:47:34 +0000249static int MSLIsStandalone(void *context)
250{
251 MSLInfo
252 *msl_info;
253
254 /*
255 Is this document tagged standalone?
256 */
257 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.MSLIsStandalone()");
258 msl_info=(MSLInfo *) context;
259 return(msl_info->document->standalone == 1);
260}
261
262static int MSLHasInternalSubset(void *context)
263{
264 MSLInfo
265 *msl_info;
266
267 /*
268 Does this document has an internal subset?
269 */
270 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
271 " SAX.MSLHasInternalSubset()");
272 msl_info=(MSLInfo *) context;
273 return(msl_info->document->intSubset != NULL);
274}
275
276static int MSLHasExternalSubset(void *context)
277{
278 MSLInfo
279 *msl_info;
280
281 /*
282 Does this document has an external subset?
283 */
284 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
285 " SAX.MSLHasExternalSubset()");
286 msl_info=(MSLInfo *) context;
287 return(msl_info->document->extSubset != NULL);
288}
289
290static void MSLInternalSubset(void *context,const xmlChar *name,
291 const xmlChar *external_id,const xmlChar *system_id)
292{
293 MSLInfo
294 *msl_info;
295
296 /*
297 Does this document has an internal subset?
298 */
299 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
300 " SAX.internalSubset(%s %s %s)",name,
cristyb988fe72009-09-16 01:01:10 +0000301 (external_id != (const xmlChar *) NULL ? (const char *) external_id : " "),
302 (system_id != (const xmlChar *) NULL ? (const char *) system_id : " "));
cristy3ed852e2009-09-05 21:47:34 +0000303 msl_info=(MSLInfo *) context;
304 (void) xmlCreateIntSubset(msl_info->document,name,external_id,system_id);
305}
306
307static xmlParserInputPtr MSLResolveEntity(void *context,
308 const xmlChar *public_id,const xmlChar *system_id)
309{
310 MSLInfo
311 *msl_info;
312
313 xmlParserInputPtr
314 stream;
315
316 /*
317 Special entity resolver, better left to the parser, it has more
318 context than the application layer. The default behaviour is to
319 not resolve the entities, in that case the ENTITY_REF nodes are
320 built in the structure (and the parameter values).
321 */
322 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
323 " SAX.resolveEntity(%s, %s)",
cristyb988fe72009-09-16 01:01:10 +0000324 (public_id != (const xmlChar *) NULL ? (const char *) public_id : "none"),
325 (system_id != (const xmlChar *) NULL ? (const char *) system_id : "none"));
cristy3ed852e2009-09-05 21:47:34 +0000326 msl_info=(MSLInfo *) context;
327 stream=xmlLoadExternalEntity((const char *) system_id,(const char *)
328 public_id,msl_info->parser);
329 return(stream);
330}
331
332static xmlEntityPtr MSLGetEntity(void *context,const xmlChar *name)
333{
334 MSLInfo
335 *msl_info;
336
337 /*
338 Get an entity by name.
339 */
340 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
cristyb988fe72009-09-16 01:01:10 +0000341 " SAX.MSLGetEntity(%s)",(const char *) name);
cristy3ed852e2009-09-05 21:47:34 +0000342 msl_info=(MSLInfo *) context;
343 return(xmlGetDocEntity(msl_info->document,name));
344}
345
346static xmlEntityPtr MSLGetParameterEntity(void *context,const xmlChar *name)
347{
348 MSLInfo
349 *msl_info;
350
351 /*
352 Get a parameter entity by name.
353 */
354 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
cristyb988fe72009-09-16 01:01:10 +0000355 " SAX.getParameterEntity(%s)",(const char *) name);
cristy3ed852e2009-09-05 21:47:34 +0000356 msl_info=(MSLInfo *) context;
357 return(xmlGetParameterEntity(msl_info->document,name));
358}
359
360static void MSLEntityDeclaration(void *context,const xmlChar *name,int type,
361 const xmlChar *public_id,const xmlChar *system_id,xmlChar *content)
362{
363 MSLInfo
364 *msl_info;
365
366 /*
367 An entity definition has been parsed.
368 */
369 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
370 " SAX.entityDecl(%s, %d, %s, %s, %s)",name,type,
cristyb988fe72009-09-16 01:01:10 +0000371 public_id != (const xmlChar *) NULL ? (const char *) public_id : "none",
372 system_id != (const xmlChar *) NULL ? (const char *) system_id : "none",
373 content);
cristy3ed852e2009-09-05 21:47:34 +0000374 msl_info=(MSLInfo *) context;
375 if (msl_info->parser->inSubset == 1)
376 (void) xmlAddDocEntity(msl_info->document,name,type,public_id,system_id,
377 content);
378 else
379 if (msl_info->parser->inSubset == 2)
380 (void) xmlAddDtdEntity(msl_info->document,name,type,public_id,system_id,
381 content);
382}
383
384static void MSLAttributeDeclaration(void *context,const xmlChar *element,
385 const xmlChar *name,int type,int value,const xmlChar *default_value,
386 xmlEnumerationPtr tree)
387{
388 MSLInfo
389 *msl_info;
390
391 xmlChar
392 *fullname,
393 *prefix;
394
395 xmlParserCtxtPtr
396 parser;
397
398 /*
399 An attribute definition has been parsed.
400 */
401 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
402 " SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",element,name,type,value,
403 default_value);
404 msl_info=(MSLInfo *) context;
405 fullname=(xmlChar *) NULL;
406 prefix=(xmlChar *) NULL;
407 parser=msl_info->parser;
408 fullname=(xmlChar *) xmlSplitQName(parser,name,&prefix);
409 if (parser->inSubset == 1)
410 (void) xmlAddAttributeDecl(&parser->vctxt,msl_info->document->intSubset,
411 element,fullname,prefix,(xmlAttributeType) type,
412 (xmlAttributeDefault) value,default_value,tree);
413 else
414 if (parser->inSubset == 2)
415 (void) xmlAddAttributeDecl(&parser->vctxt,msl_info->document->extSubset,
416 element,fullname,prefix,(xmlAttributeType) type,
417 (xmlAttributeDefault) value,default_value,tree);
418 if (prefix != (xmlChar *) NULL)
419 xmlFree(prefix);
420 if (fullname != (xmlChar *) NULL)
421 xmlFree(fullname);
422}
423
424static void MSLElementDeclaration(void *context,const xmlChar *name,int type,
425 xmlElementContentPtr content)
426{
427 MSLInfo
428 *msl_info;
429
430 xmlParserCtxtPtr
431 parser;
432
433 /*
434 An element definition has been parsed.
435 */
436 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
437 " SAX.elementDecl(%s, %d, ...)",name,type);
438 msl_info=(MSLInfo *) context;
439 parser=msl_info->parser;
440 if (parser->inSubset == 1)
441 (void) xmlAddElementDecl(&parser->vctxt,msl_info->document->intSubset,
442 name,(xmlElementTypeVal) type,content);
443 else
444 if (parser->inSubset == 2)
445 (void) xmlAddElementDecl(&parser->vctxt,msl_info->document->extSubset,
446 name,(xmlElementTypeVal) type,content);
447}
448
449static void MSLNotationDeclaration(void *context,const xmlChar *name,
450 const xmlChar *public_id,const xmlChar *system_id)
451{
452 MSLInfo
453 *msl_info;
454
455 xmlParserCtxtPtr
456 parser;
457
458 /*
459 What to do when a notation declaration has been parsed.
460 */
461 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
462 " SAX.notationDecl(%s, %s, %s)",name,
cristyb988fe72009-09-16 01:01:10 +0000463 public_id != (const xmlChar *) NULL ? (const char *) public_id : "none",
464 system_id != (const xmlChar *) NULL ? (const char *) system_id : "none");
cristy3ed852e2009-09-05 21:47:34 +0000465 msl_info=(MSLInfo *) context;
466 parser=msl_info->parser;
467 if (parser->inSubset == 1)
468 (void) xmlAddNotationDecl(&parser->vctxt,msl_info->document->intSubset,
469 name,public_id,system_id);
470 else
471 if (parser->inSubset == 2)
472 (void) xmlAddNotationDecl(&parser->vctxt,msl_info->document->intSubset,
473 name,public_id,system_id);
474}
475
476static void MSLUnparsedEntityDeclaration(void *context,const xmlChar *name,
477 const xmlChar *public_id,const xmlChar *system_id,const xmlChar *notation)
478{
479 MSLInfo
480 *msl_info;
481
482 /*
483 What to do when an unparsed entity declaration is parsed.
484 */
485 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
486 " SAX.unparsedEntityDecl(%s, %s, %s, %s)",name,
cristyb988fe72009-09-16 01:01:10 +0000487 public_id != (const xmlChar *) NULL ? (const char *) public_id : "none",
488 system_id != (const xmlChar *) NULL ? (const char *) system_id : "none",
489 notation);
cristy3ed852e2009-09-05 21:47:34 +0000490 msl_info=(MSLInfo *) context;
491 (void) xmlAddDocEntity(msl_info->document,name,
492 XML_EXTERNAL_GENERAL_UNPARSED_ENTITY,public_id,system_id,notation);
493
494}
495
496static void MSLSetDocumentLocator(void *context,xmlSAXLocatorPtr location)
497{
498 MSLInfo
499 *msl_info;
500
501 /*
502 Receive the document locator at startup, actually xmlDefaultSAXLocator.
503 */
504 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
505 " SAX.setDocumentLocator()\n");
506 (void) location;
507 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +0000508 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +0000509}
510
511static void MSLStartDocument(void *context)
512{
513 MSLInfo
514 *msl_info;
515
516 xmlParserCtxtPtr
517 parser;
518
519 /*
520 Called when the document start being processed.
521 */
522 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
523 " SAX.startDocument()");
524 msl_info=(MSLInfo *) context;
525 parser=msl_info->parser;
526 msl_info->document=xmlNewDoc(parser->version);
527 if (msl_info->document == (xmlDocPtr) NULL)
528 return;
529 if (parser->encoding == NULL)
530 msl_info->document->encoding=NULL;
531 else
532 msl_info->document->encoding=xmlStrdup(parser->encoding);
533 msl_info->document->standalone=parser->standalone;
534}
535
536static void MSLEndDocument(void *context)
537{
538 MSLInfo
539 *msl_info;
540
541 /*
542 Called when the document end has been detected.
543 */
544 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.endDocument()");
545 msl_info=(MSLInfo *) context;
546 if (msl_info->content != (char *) NULL)
547 msl_info->content=DestroyString(msl_info->content);
548}
549
550static void MSLPushImage(MSLInfo *msl_info,Image *image)
551{
cristybb503372010-05-27 20:51:26 +0000552 ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000553 n;
554
555 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
556 assert(msl_info != (MSLInfo *) NULL);
557 msl_info->n++;
558 n=msl_info->n;
559 msl_info->image_info=(ImageInfo **) ResizeQuantumMemory(msl_info->image_info,
560 (n+1),sizeof(*msl_info->image_info));
561 msl_info->draw_info=(DrawInfo **) ResizeQuantumMemory(msl_info->draw_info,
562 (n+1),sizeof(*msl_info->draw_info));
563 msl_info->attributes=(Image **) ResizeQuantumMemory(msl_info->attributes,
564 (n+1),sizeof(*msl_info->attributes));
565 msl_info->image=(Image **) ResizeQuantumMemory(msl_info->image,(n+1),
566 sizeof(*msl_info->image));
567 if ((msl_info->image_info == (ImageInfo **) NULL) ||
cristyca890a32014-01-16 01:39:02 +0000568 (msl_info->draw_info == (DrawInfo **) NULL) ||
569 (msl_info->attributes == (Image **) NULL) ||
570 (msl_info->image == (Image **) NULL))
cristy9c5171c2014-05-25 21:26:39 +0000571 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed")
cristy3ed852e2009-09-05 21:47:34 +0000572 msl_info->image_info[n]=CloneImageInfo(msl_info->image_info[n-1]);
573 msl_info->draw_info[n]=CloneDrawInfo(msl_info->image_info[n-1],
574 msl_info->draw_info[n-1]);
575 if (image == (Image *) NULL)
cristy9950d572011-10-01 18:22:35 +0000576 msl_info->attributes[n]=AcquireImage(msl_info->image_info[n],
cristyc82a27b2011-10-21 01:07:16 +0000577 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +0000578 else
cristyc82a27b2011-10-21 01:07:16 +0000579 msl_info->attributes[n]=CloneImage(image,0,0,MagickTrue,
580 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +0000581 msl_info->image[n]=(Image *) image;
582 if ((msl_info->image_info[n] == (ImageInfo *) NULL) ||
cristyca890a32014-01-16 01:39:02 +0000583 (msl_info->attributes[n] == (Image *) NULL))
cristy9c5171c2014-05-25 21:26:39 +0000584 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed")
cristy3ed852e2009-09-05 21:47:34 +0000585 if (msl_info->number_groups != 0)
586 msl_info->group_info[msl_info->number_groups-1].numImages++;
587}
588
589static void MSLPopImage(MSLInfo *msl_info)
590{
591 if (msl_info->number_groups != 0)
592 return;
593 if (msl_info->image[msl_info->n] != (Image *) NULL)
594 msl_info->image[msl_info->n]=DestroyImage(msl_info->image[msl_info->n]);
595 msl_info->attributes[msl_info->n]=DestroyImage(
596 msl_info->attributes[msl_info->n]);
597 msl_info->image_info[msl_info->n]=DestroyImageInfo(
598 msl_info->image_info[msl_info->n]);
599 msl_info->n--;
600}
601
602static void MSLStartElement(void *context,const xmlChar *tag,
603 const xmlChar **attributes)
604{
605 AffineMatrix
606 affine,
607 current;
608
609 ChannelType
610 channel;
611
cristybd5a96c2011-08-21 00:04:26 +0000612 ChannelType
613 channel_mask;
614
cristy3ed852e2009-09-05 21:47:34 +0000615 char
cristy151b66d2015-04-15 10:50:31 +0000616 key[MagickPathExtent],
cristy3ed852e2009-09-05 21:47:34 +0000617 *value;
618
619 const char
620 *attribute,
621 *keyword;
622
623 double
624 angle;
625
626 DrawInfo
627 *draw_info;
628
629 ExceptionInfo
dirke31feb82014-06-20 11:03:07 +0000630 *exception;
cristy3ed852e2009-09-05 21:47:34 +0000631
632 GeometryInfo
633 geometry_info;
634
635 Image
636 *image;
637
638 int
639 flags;
640
cristybb503372010-05-27 20:51:26 +0000641 ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000642 option,
643 j,
644 n,
645 x,
646 y;
647
648 MSLInfo
649 *msl_info;
650
651 RectangleInfo
652 geometry;
653
cristybb503372010-05-27 20:51:26 +0000654 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000655 i;
656
cristybb503372010-05-27 20:51:26 +0000657 size_t
cristy3ed852e2009-09-05 21:47:34 +0000658 height,
659 width;
660
661 /*
662 Called when an opening tag has been processed.
663 */
664 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
665 " SAX.startElement(%s",tag);
dirke31feb82014-06-20 11:03:07 +0000666 exception=AcquireExceptionInfo();
cristy3ed852e2009-09-05 21:47:34 +0000667 msl_info=(MSLInfo *) context;
668 n=msl_info->n;
669 keyword=(const char *) NULL;
670 value=(char *) NULL;
671 SetGeometryInfo(&geometry_info);
dirk93b02b72013-11-16 16:03:36 +0000672 (void) ResetMagickMemory(&geometry,0,sizeof(geometry));
cristy3ed852e2009-09-05 21:47:34 +0000673 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],
dirk6d6d5f22014-06-20 11:48:54 +0000703 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
cristy151b66d2015-04-15 10:50:31 +0000761 text[MagickPathExtent];
cristy3ed852e2009-09-05 21:47:34 +0000762
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],
dirk6d6d5f22014-06-20 11:48:54 +0000783 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,
dirk6d6d5f22014-06-20 11:48:54 +0000869 &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,
dirk6d6d5f22014-06-20 11:48:54 +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,
dirk6d6d5f22014-06-20 11:48:54 +0000976 &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,
dirk6d6d5f22014-06-20 11:48:54 +00001025 &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 }
cristy151b66d2015-04-15 10:50:31 +00001076 (void) FormatLocaleString(text,MagickPathExtent,
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],
dirk6d6d5f22014-06-20 11:48:54 +00001114 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],
dirk6d6d5f22014-06-20 11:48:54 +00001177 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],
dirk6d6d5f22014-06-20 11:48:54 +00001274 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,
dirk6d6d5f22014-06-20 11:48:54 +00001301 &msl_info->image[n]->border_color,exception);
cristy3ed852e2009-09-05 21:47:34 +00001302 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,
dirk6d6d5f22014-06-20 11:48:54 +00001314 &geometry,exception);
cristy3ed852e2009-09-05 21:47:34 +00001315 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
cristy151b66d2015-04-15 10:50:31 +00001371 blend[MagickPathExtent];
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);
cristy151b66d2015-04-15 10:50:31 +00001389 (void) CopyMagickString(blend,"100",MagickPathExtent);
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],
dirk6d6d5f22014-06-20 11:48:54 +00001396 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 {
cristy151b66d2015-04-15 10:50:31 +00001405 (void) CopyMagickString(blend,value,MagickPathExtent);
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],
dirk6d6d5f22014-06-20 11:48:54 +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],
dirk6d6d5f22014-06-20 11:48:54 +00001533 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,
dirk6d6d5f22014-06-20 11:48:54 +00001543 &geometry,exception);
cristy3ed852e2009-09-05 21:47:34 +00001544 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],
dirk6d6d5f22014-06-20 11:48:54 +00001643 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,
dirk6d6d5f22014-06-20 11:48:54 +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,
dirk6d6d5f22014-06-20 11:48:54 +00001667 &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,
dirk6d6d5f22014-06-20 11:48:54 +00001686 &geometry,exception);
cristy3ed852e2009-09-05 21:47:34 +00001687 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,
dirk6d6d5f22014-06-20 11:48:54 +00001691 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,
dirk6d6d5f22014-06-20 11:48:54 +00001706 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,
dirk6d6d5f22014-06-20 11:48:54 +00001721 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
cristy151b66d2015-04-15 10:50:31 +00001747 composite_geometry[MagickPathExtent];
cristy3ed852e2009-09-05 21:47:34 +00001748
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],
dirk6d6d5f22014-06-20 11:48:54 +00001773 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",
dirk6d6d5f22014-06-20 11:48:54 +00001802 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,
dirk6d6d5f22014-06-20 11:48:54 +00001807 MagickFalse,exception);
cristy3ed852e2009-09-05 21:47:34 +00001808 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],
dirk6d6d5f22014-06-20 11:48:54 +00001827 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,
dirk6d6d5f22014-06-20 11:48:54 +00001859 &composite_image->background_color,exception);
cristy3ed852e2009-09-05 21:47:34 +00001860 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,
dirk6d6d5f22014-06-20 11:48:54 +00001874 &geometry,exception);
cristy3ed852e2009-09-05 21:47:34 +00001875 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",
dirk6d6d5f22014-06-20 11:48:54 +00001912 exception);
cristy3ed852e2009-09-05 21:47:34 +00001913 if ((attribute != (const char *) NULL) &&
1914 (LocaleCompare(value,value) == 0))
1915 {
cristydef23e52015-01-22 11:52:01 +00001916 SetImageType(composite_image,TrueColorAlphaType,
dirk6d6d5f22014-06-20 11:48:54 +00001917 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,
dirk6d6d5f22014-06-20 11:48:54 +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)
dirk6d6d5f22014-06-20 11:48:54 +00001950 opacity,exception);
cristy3ed852e2009-09-05 21:47:34 +00001951 break;
1952 }
1953 (void) SetImageArtifact(msl_info->image[n],
1954 "compose:args",value);
cristy17f11b02014-12-20 19:37:04 +00001955 if (composite_image->alpha_trait == UndefinedPixelTrait)
cristye941a752011-10-15 01:52:48 +00001956 (void) SetImageAlpha(composite_image,OpaqueAlpha,
dirk6d6d5f22014-06-20 11:48:54 +00001957 exception);
1958 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,
dirk6d6d5f22014-06-20 11:48:54 +00001962 (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 }
dirk6d6d5f22014-06-20 11:48:54 +00001970 if (SyncCacheViewAuthenticPixels(composite_view,exception) == MagickFalse)
cristy3ed852e2009-09-05 21:47:34 +00001971 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,
dirk6d6d5f22014-06-20 11:48:54 +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,
dirk6d6d5f22014-06-20 11:48:54 +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,
dirk6d6d5f22014-06-20 11:48:54 +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];
cristy151b66d2015-04-15 10:50:31 +00002068 (void) FormatLocaleString(composite_geometry,MagickPathExtent,
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,
dirk6d6d5f22014-06-20 11:48:54 +00002073 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,
dirk6d6d5f22014-06-20 11:48:54 +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,
dirk6d6d5f22014-06-20 11:48:54 +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],
dirk6d6d5f22014-06-20 11:48:54 +00002116 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],
dirk6d6d5f22014-06-20 11:48:54 +00002170 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,
dirk6d6d5f22014-06-20 11:48:54 +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],
dirk6d6d5f22014-06-20 11:48:54 +00002272 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 }
dirk6d6d5f22014-06-20 11:48:54 +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],
dirk6d6d5f22014-06-20 11:48:54 +00002324 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],
dirk6d6d5f22014-06-20 11:48:54 +00002350 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
cristy151b66d2015-04-15 10:50:31 +00002369 text[MagickPathExtent];
cristy3ed852e2009-09-05 21:47:34 +00002370
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],
dirk6d6d5f22014-06-20 11:48:54 +00002391 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,
dirk6d6d5f22014-06-20 11:48:54 +00002477 &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,
dirk6d6d5f22014-06-20 11:48:54 +00002500 &geometry,exception);
cristy3ed852e2009-09-05 21:47:34 +00002501 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 {
cristy22890922013-12-27 14:08:49 +00002522 if (LocaleCompare(keyword,"points") == 0)
cristyb988fe72009-09-16 01:01:10 +00002523 {
cristy22890922013-12-27 14:08:49 +00002524 if (LocaleCompare(draw_info->primitive,"path") == 0)
2525 {
2526 (void) ConcatenateString(&draw_info->primitive," '");
2527 ConcatenateString(&draw_info->primitive,value);
2528 (void) ConcatenateString(&draw_info->primitive,"'");
2529 }
2530 else
2531 {
2532 (void) ConcatenateString(&draw_info->primitive," ");
2533 ConcatenateString(&draw_info->primitive,value);
2534 }
cristy3f891212013-12-27 14:17:27 +00002535 break;
cristy3ed852e2009-09-05 21:47:34 +00002536 }
2537 if (LocaleCompare(keyword,"pointsize") == 0)
2538 {
cristydbdd0e32011-11-04 23:29:40 +00002539 draw_info->pointsize=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00002540 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002541 break;
2542 }
cristy22890922013-12-27 14:08:49 +00002543 if (LocaleCompare(keyword,"primitive") == 0)
2544 {
2545 CloneString(&draw_info->primitive,value);
2546 break;
2547 }
cristy3ed852e2009-09-05 21:47:34 +00002548 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2549 keyword);
2550 break;
2551 }
2552 case 'R':
2553 case 'r':
2554 {
2555 if (LocaleCompare(keyword,"rotate") == 0)
2556 {
cristydbdd0e32011-11-04 23:29:40 +00002557 angle=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002558 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
2559 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
2560 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
2561 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
2562 break;
2563 }
2564 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2565 keyword);
2566 break;
2567 }
2568 case 'S':
2569 case 's':
2570 {
2571 if (LocaleCompare(keyword,"scale") == 0)
2572 {
2573 flags=ParseGeometry(value,&geometry_info);
2574 if ((flags & SigmaValue) == 0)
2575 geometry_info.sigma=1.0;
2576 affine.sx=geometry_info.rho;
2577 affine.sy=geometry_info.sigma;
2578 break;
2579 }
2580 if (LocaleCompare(keyword,"skewX") == 0)
2581 {
cristydbdd0e32011-11-04 23:29:40 +00002582 angle=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002583 affine.ry=cos(DegreesToRadians(fmod(angle,360.0)));
2584 break;
2585 }
2586 if (LocaleCompare(keyword,"skewY") == 0)
2587 {
cristydbdd0e32011-11-04 23:29:40 +00002588 angle=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002589 affine.rx=cos(DegreesToRadians(fmod(angle,360.0)));
2590 break;
2591 }
2592 if (LocaleCompare(keyword,"stretch") == 0)
2593 {
cristy9950d572011-10-01 18:22:35 +00002594 option=ParseCommandOption(MagickStretchOptions,
2595 MagickFalse,value);
cristy3ed852e2009-09-05 21:47:34 +00002596 if (option < 0)
2597 ThrowMSLException(OptionError,"UnrecognizedStretchType",
2598 value);
2599 draw_info->stretch=(StretchType) option;
2600 break;
2601 }
2602 if (LocaleCompare(keyword, "stroke") == 0)
2603 {
cristy9950d572011-10-01 18:22:35 +00002604 (void) QueryColorCompliance(value,AllCompliance,
dirk6d6d5f22014-06-20 11:48:54 +00002605 &draw_info->stroke,exception);
cristy3ed852e2009-09-05 21:47:34 +00002606 break;
2607 }
2608 if (LocaleCompare(keyword,"strokewidth") == 0)
2609 {
cristyf2f27272009-12-17 14:48:46 +00002610 draw_info->stroke_width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002611 break;
2612 }
2613 if (LocaleCompare(keyword,"style") == 0)
2614 {
cristy042ee782011-04-22 18:48:30 +00002615 option=ParseCommandOption(MagickStyleOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002616 value);
2617 if (option < 0)
2618 ThrowMSLException(OptionError,"UnrecognizedStyleType",
2619 value);
2620 draw_info->style=(StyleType) option;
2621 break;
2622 }
2623 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2624 keyword);
2625 break;
2626 }
2627 case 'T':
2628 case 't':
2629 {
2630 if (LocaleCompare(keyword,"text") == 0)
2631 {
cristye4fa22b2015-07-28 18:12:35 +00002632 (void) ConcatenateString(&draw_info->primitive," '");
2633 (void) ConcatenateString(&draw_info->primitive,value);
2634 (void) ConcatenateString(&draw_info->primitive,"'");
cristy3ed852e2009-09-05 21:47:34 +00002635 break;
2636 }
2637 if (LocaleCompare(keyword,"translate") == 0)
2638 {
2639 flags=ParseGeometry(value,&geometry_info);
2640 if ((flags & SigmaValue) == 0)
2641 geometry_info.sigma=1.0;
2642 affine.tx=geometry_info.rho;
2643 affine.ty=geometry_info.sigma;
2644 break;
2645 }
2646 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2647 keyword);
2648 break;
2649 }
2650 case 'U':
2651 case 'u':
2652 {
2653 if (LocaleCompare(keyword, "undercolor") == 0)
2654 {
cristy9950d572011-10-01 18:22:35 +00002655 (void) QueryColorCompliance(value,AllCompliance,
dirk6d6d5f22014-06-20 11:48:54 +00002656 &draw_info->undercolor,exception);
cristy3ed852e2009-09-05 21:47:34 +00002657 break;
2658 }
2659 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2660 keyword);
2661 break;
2662 }
2663 case 'W':
2664 case 'w':
2665 {
2666 if (LocaleCompare(keyword,"weight") == 0)
2667 {
cristyf2f27272009-12-17 14:48:46 +00002668 draw_info->weight=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002669 break;
2670 }
2671 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2672 keyword);
2673 break;
2674 }
2675 case 'X':
2676 case 'x':
2677 {
2678 if (LocaleCompare(keyword,"x") == 0)
2679 {
cristyf2f27272009-12-17 14:48:46 +00002680 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002681 break;
2682 }
2683 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2684 keyword);
2685 break;
2686 }
2687 case 'Y':
2688 case 'y':
2689 {
2690 if (LocaleCompare(keyword,"y") == 0)
2691 {
cristyf2f27272009-12-17 14:48:46 +00002692 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002693 break;
2694 }
2695 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2696 keyword);
2697 break;
2698 }
2699 default:
2700 {
2701 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2702 keyword);
2703 break;
2704 }
2705 }
2706 }
cristy151b66d2015-04-15 10:50:31 +00002707 (void) FormatLocaleString(text,MagickPathExtent,
cristye8c25f92010-06-03 00:53:06 +00002708 "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,(double)
2709 geometry.height,(double) geometry.x,(double) geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00002710 CloneString(&draw_info->geometry,text);
cristyef7c8a52010-10-10 13:46:51 +00002711 draw_info->affine.sx=affine.sx*current.sx+affine.ry*current.rx;
2712 draw_info->affine.rx=affine.rx*current.sx+affine.sy*current.rx;
2713 draw_info->affine.ry=affine.sx*current.ry+affine.ry*current.sy;
2714 draw_info->affine.sy=affine.rx*current.ry+affine.sy*current.sy;
2715 draw_info->affine.tx=affine.sx*current.tx+affine.ry*current.ty+
2716 affine.tx;
2717 draw_info->affine.ty=affine.rx*current.tx+affine.sy*current.ty+
2718 affine.ty;
dirk6d6d5f22014-06-20 11:48:54 +00002719 (void) DrawImage(msl_info->image[n],draw_info,exception);
cristy3ed852e2009-09-05 21:47:34 +00002720 draw_info=DestroyDrawInfo(draw_info);
2721 break;
2722 }
2723 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
2724 }
2725 case 'E':
2726 case 'e':
2727 {
cristyb988fe72009-09-16 01:01:10 +00002728 if (LocaleCompare((const char *) tag,"edge") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002729 {
2730 Image
2731 *edge_image;
2732
2733 /*
2734 Edge image.
2735 */
2736 if (msl_info->image[n] == (Image *) NULL)
2737 {
cristyb988fe72009-09-16 01:01:10 +00002738 ThrowMSLException(OptionError,"NoImagesDefined",
2739 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002740 break;
2741 }
2742 if (attributes != (const xmlChar **) NULL)
2743 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2744 {
2745 keyword=(const char *) attributes[i++];
2746 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002747 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00002748 exception);
cristy3ed852e2009-09-05 21:47:34 +00002749 CloneString(&value,attribute);
2750 switch (*keyword)
2751 {
2752 case 'G':
2753 case 'g':
2754 {
2755 if (LocaleCompare(keyword,"geometry") == 0)
2756 {
2757 flags=ParseGeometry(value,&geometry_info);
2758 if ((flags & SigmaValue) == 0)
2759 geometry_info.sigma=1.0;
2760 break;
2761 }
2762 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2763 keyword);
2764 break;
2765 }
2766 case 'R':
2767 case 'r':
2768 {
2769 if (LocaleCompare(keyword,"radius") == 0)
2770 {
cristy9b34e302011-11-05 02:15:45 +00002771 geometry_info.rho=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002772 break;
2773 }
2774 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2775 keyword);
2776 break;
2777 }
2778 default:
2779 {
2780 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2781 keyword);
2782 break;
2783 }
2784 }
2785 }
2786 edge_image=EdgeImage(msl_info->image[n],geometry_info.rho,
cristy9dc4c512013-03-24 01:38:00 +00002787 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00002788 if (edge_image == (Image *) NULL)
2789 break;
2790 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2791 msl_info->image[n]=edge_image;
2792 break;
2793 }
cristyb988fe72009-09-16 01:01:10 +00002794 if (LocaleCompare((const char *) tag,"emboss") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002795 {
2796 Image
2797 *emboss_image;
2798
2799 /*
2800 Emboss image.
2801 */
2802 if (msl_info->image[n] == (Image *) NULL)
2803 {
cristyb988fe72009-09-16 01:01:10 +00002804 ThrowMSLException(OptionError,"NoImagesDefined",
2805 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002806 break;
2807 }
2808 if (attributes != (const xmlChar **) NULL)
2809 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2810 {
2811 keyword=(const char *) attributes[i++];
2812 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002813 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00002814 exception);
cristy3ed852e2009-09-05 21:47:34 +00002815 CloneString(&value,attribute);
2816 switch (*keyword)
2817 {
2818 case 'G':
2819 case 'g':
2820 {
2821 if (LocaleCompare(keyword,"geometry") == 0)
2822 {
2823 flags=ParseGeometry(value,&geometry_info);
2824 if ((flags & SigmaValue) == 0)
2825 geometry_info.sigma=1.0;
2826 break;
2827 }
2828 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2829 keyword);
2830 break;
2831 }
2832 case 'R':
2833 case 'r':
2834 {
2835 if (LocaleCompare(keyword,"radius") == 0)
2836 {
cristydbdd0e32011-11-04 23:29:40 +00002837 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00002838 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002839 break;
2840 }
2841 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2842 keyword);
2843 break;
2844 }
2845 case 'S':
2846 case 's':
2847 {
2848 if (LocaleCompare(keyword,"sigma") == 0)
2849 {
cristyf2f27272009-12-17 14:48:46 +00002850 geometry_info.sigma=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002851 break;
2852 }
2853 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2854 keyword);
2855 break;
2856 }
2857 default:
2858 {
2859 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2860 keyword);
2861 break;
2862 }
2863 }
2864 }
2865 emboss_image=EmbossImage(msl_info->image[n],geometry_info.rho,
cristyc82a27b2011-10-21 01:07:16 +00002866 geometry_info.sigma,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00002867 if (emboss_image == (Image *) NULL)
2868 break;
2869 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2870 msl_info->image[n]=emboss_image;
2871 break;
2872 }
cristyb988fe72009-09-16 01:01:10 +00002873 if (LocaleCompare((const char *) tag,"enhance") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002874 {
2875 Image
2876 *enhance_image;
2877
2878 /*
2879 Enhance image.
2880 */
2881 if (msl_info->image[n] == (Image *) NULL)
2882 {
cristyb988fe72009-09-16 01:01:10 +00002883 ThrowMSLException(OptionError,"NoImagesDefined",
2884 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002885 break;
2886 }
2887 if (attributes != (const xmlChar **) NULL)
2888 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2889 {
2890 keyword=(const char *) attributes[i++];
2891 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002892 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00002893 exception);
cristy3ed852e2009-09-05 21:47:34 +00002894 CloneString(&value,attribute);
2895 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
2896 }
2897 enhance_image=EnhanceImage(msl_info->image[n],
cristyc82a27b2011-10-21 01:07:16 +00002898 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00002899 if (enhance_image == (Image *) NULL)
2900 break;
2901 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2902 msl_info->image[n]=enhance_image;
2903 break;
2904 }
cristyb988fe72009-09-16 01:01:10 +00002905 if (LocaleCompare((const char *) tag,"equalize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002906 {
2907 /*
2908 Equalize image.
2909 */
2910 if (msl_info->image[n] == (Image *) NULL)
2911 {
cristyb988fe72009-09-16 01:01:10 +00002912 ThrowMSLException(OptionError,"NoImagesDefined",
2913 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002914 break;
2915 }
2916 if (attributes != (const xmlChar **) NULL)
2917 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2918 {
2919 keyword=(const char *) attributes[i++];
2920 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002921 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00002922 exception);
cristy3ed852e2009-09-05 21:47:34 +00002923 CloneString(&value,attribute);
2924 switch (*keyword)
2925 {
2926 default:
2927 {
2928 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2929 keyword);
2930 break;
2931 }
2932 }
2933 }
cristy6d8c3d72011-08-22 01:20:01 +00002934 (void) EqualizeImage(msl_info->image[n],
cristyc82a27b2011-10-21 01:07:16 +00002935 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00002936 break;
2937 }
2938 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
2939 }
2940 case 'F':
2941 case 'f':
2942 {
cristyb988fe72009-09-16 01:01:10 +00002943 if (LocaleCompare((const char *) tag, "flatten") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002944 {
2945 if (msl_info->image[n] == (Image *) NULL)
2946 {
cristyb988fe72009-09-16 01:01:10 +00002947 ThrowMSLException(OptionError,"NoImagesDefined",
2948 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002949 break;
2950 }
2951
2952 /* no attributes here */
2953
2954 /* process the image */
2955 {
2956 Image
2957 *newImage;
2958
2959 newImage=MergeImageLayers(msl_info->image[n],FlattenLayer,
cristyc82a27b2011-10-21 01:07:16 +00002960 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00002961 if (newImage == (Image *) NULL)
2962 break;
2963 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2964 msl_info->image[n]=newImage;
2965 break;
2966 }
2967 }
cristyb988fe72009-09-16 01:01:10 +00002968 if (LocaleCompare((const char *) tag,"flip") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002969 {
2970 Image
2971 *flip_image;
2972
2973 /*
2974 Flip image.
2975 */
2976 if (msl_info->image[n] == (Image *) NULL)
2977 {
cristyb988fe72009-09-16 01:01:10 +00002978 ThrowMSLException(OptionError,"NoImagesDefined",
2979 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002980 break;
2981 }
2982 if (attributes != (const xmlChar **) NULL)
2983 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2984 {
2985 keyword=(const char *) attributes[i++];
2986 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002987 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00002988 exception);
cristy3ed852e2009-09-05 21:47:34 +00002989 CloneString(&value,attribute);
2990 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
2991 }
2992 flip_image=FlipImage(msl_info->image[n],
cristyc82a27b2011-10-21 01:07:16 +00002993 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00002994 if (flip_image == (Image *) NULL)
2995 break;
2996 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2997 msl_info->image[n]=flip_image;
2998 break;
2999 }
cristyb988fe72009-09-16 01:01:10 +00003000 if (LocaleCompare((const char *) tag,"flop") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003001 {
3002 Image
3003 *flop_image;
3004
3005 /*
3006 Flop image.
3007 */
3008 if (msl_info->image[n] == (Image *) NULL)
3009 {
cristyb988fe72009-09-16 01:01:10 +00003010 ThrowMSLException(OptionError,"NoImagesDefined",
3011 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003012 break;
3013 }
3014 if (attributes != (const xmlChar **) NULL)
3015 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3016 {
3017 keyword=(const char *) attributes[i++];
3018 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003019 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00003020 exception);
cristy3ed852e2009-09-05 21:47:34 +00003021 CloneString(&value,attribute);
3022 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3023 }
3024 flop_image=FlopImage(msl_info->image[n],
cristyc82a27b2011-10-21 01:07:16 +00003025 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00003026 if (flop_image == (Image *) NULL)
3027 break;
3028 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3029 msl_info->image[n]=flop_image;
3030 break;
3031 }
cristyb988fe72009-09-16 01:01:10 +00003032 if (LocaleCompare((const char *) tag,"frame") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003033 {
3034 FrameInfo
3035 frame_info;
3036
3037 Image
3038 *frame_image;
3039
3040 /*
3041 Frame image.
3042 */
3043 if (msl_info->image[n] == (Image *) NULL)
3044 {
cristyb988fe72009-09-16 01:01:10 +00003045 ThrowMSLException(OptionError,"NoImagesDefined",
3046 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003047 break;
3048 }
cristy3e410e22014-07-25 16:24:50 +00003049 (void) ResetMagickMemory(&frame_info,0,sizeof(frame_info));
cristy3ed852e2009-09-05 21:47:34 +00003050 SetGeometry(msl_info->image[n],&geometry);
3051 if (attributes != (const xmlChar **) NULL)
3052 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3053 {
3054 keyword=(const char *) attributes[i++];
3055 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003056 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00003057 exception);
cristy3ed852e2009-09-05 21:47:34 +00003058 CloneString(&value,attribute);
3059 switch (*keyword)
3060 {
3061 case 'C':
3062 case 'c':
3063 {
3064 if (LocaleCompare(keyword,"compose") == 0)
3065 {
cristy042ee782011-04-22 18:48:30 +00003066 option=ParseCommandOption(MagickComposeOptions,
cristy3ed852e2009-09-05 21:47:34 +00003067 MagickFalse,value);
3068 if (option < 0)
3069 ThrowMSLException(OptionError,"UnrecognizedComposeType",
3070 value);
3071 msl_info->image[n]->compose=(CompositeOperator) option;
3072 break;
3073 }
3074 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3075 keyword);
3076 break;
3077 }
3078 case 'F':
3079 case 'f':
3080 {
3081 if (LocaleCompare(keyword, "fill") == 0)
3082 {
cristy9950d572011-10-01 18:22:35 +00003083 (void) QueryColorCompliance(value,AllCompliance,
dirk6d6d5f22014-06-20 11:48:54 +00003084 &msl_info->image[n]->matte_color,exception);
cristy3ed852e2009-09-05 21:47:34 +00003085 break;
3086 }
3087 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3088 keyword);
3089 break;
3090 }
3091 case 'G':
3092 case 'g':
3093 {
3094 if (LocaleCompare(keyword,"geometry") == 0)
3095 {
3096 flags=ParsePageGeometry(msl_info->image[n],value,
dirk6d6d5f22014-06-20 11:48:54 +00003097 &geometry,exception);
cristy3ed852e2009-09-05 21:47:34 +00003098 if ((flags & HeightValue) == 0)
3099 geometry.height=geometry.width;
3100 frame_info.width=geometry.width;
3101 frame_info.height=geometry.height;
3102 frame_info.outer_bevel=geometry.x;
3103 frame_info.inner_bevel=geometry.y;
3104 break;
3105 }
3106 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3107 keyword);
3108 break;
3109 }
3110 case 'H':
3111 case 'h':
3112 {
3113 if (LocaleCompare(keyword,"height") == 0)
3114 {
cristyf2f27272009-12-17 14:48:46 +00003115 frame_info.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003116 break;
3117 }
3118 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3119 keyword);
3120 break;
3121 }
3122 case 'I':
3123 case 'i':
3124 {
3125 if (LocaleCompare(keyword,"inner") == 0)
3126 {
cristyf2f27272009-12-17 14:48:46 +00003127 frame_info.inner_bevel=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003128 break;
3129 }
3130 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3131 keyword);
3132 break;
3133 }
3134 case 'O':
3135 case 'o':
3136 {
3137 if (LocaleCompare(keyword,"outer") == 0)
3138 {
cristyf2f27272009-12-17 14:48:46 +00003139 frame_info.outer_bevel=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003140 break;
3141 }
3142 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3143 keyword);
3144 break;
3145 }
3146 case 'W':
3147 case 'w':
3148 {
3149 if (LocaleCompare(keyword,"width") == 0)
3150 {
cristyf2f27272009-12-17 14:48:46 +00003151 frame_info.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003152 break;
3153 }
3154 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3155 keyword);
3156 break;
3157 }
3158 default:
3159 {
3160 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3161 keyword);
3162 break;
3163 }
3164 }
3165 }
cristybb503372010-05-27 20:51:26 +00003166 frame_info.x=(ssize_t) frame_info.width;
3167 frame_info.y=(ssize_t) frame_info.height;
cristy3ed852e2009-09-05 21:47:34 +00003168 frame_info.width=msl_info->image[n]->columns+2*frame_info.x;
3169 frame_info.height=msl_info->image[n]->rows+2*frame_info.y;
3170 frame_image=FrameImage(msl_info->image[n],&frame_info,
cristyc82a27b2011-10-21 01:07:16 +00003171 msl_info->image[n]->compose,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00003172 if (frame_image == (Image *) NULL)
3173 break;
3174 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3175 msl_info->image[n]=frame_image;
3176 break;
3177 }
3178 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3179 }
3180 case 'G':
3181 case 'g':
3182 {
cristyb988fe72009-09-16 01:01:10 +00003183 if (LocaleCompare((const char *) tag,"gamma") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003184 {
3185 char
cristy151b66d2015-04-15 10:50:31 +00003186 gamma[MagickPathExtent];
cristy3ed852e2009-09-05 21:47:34 +00003187
cristy4c08aed2011-07-01 19:47:50 +00003188 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00003189 pixel;
3190
3191 /*
3192 Gamma image.
3193 */
3194 if (msl_info->image[n] == (Image *) NULL)
3195 {
cristyb988fe72009-09-16 01:01:10 +00003196 ThrowMSLException(OptionError,"NoImagesDefined",
3197 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003198 break;
3199 }
3200 channel=UndefinedChannel;
3201 pixel.red=0.0;
3202 pixel.green=0.0;
3203 pixel.blue=0.0;
3204 *gamma='\0';
3205 if (attributes != (const xmlChar **) NULL)
3206 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3207 {
3208 keyword=(const char *) attributes[i++];
3209 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003210 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00003211 exception);
cristy3ed852e2009-09-05 21:47:34 +00003212 CloneString(&value,attribute);
3213 switch (*keyword)
3214 {
3215 case 'B':
3216 case 'b':
3217 {
3218 if (LocaleCompare(keyword,"blue") == 0)
3219 {
cristydbdd0e32011-11-04 23:29:40 +00003220 pixel.blue=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003221 break;
3222 }
3223 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3224 keyword);
3225 break;
3226 }
3227 case 'C':
3228 case 'c':
3229 {
3230 if (LocaleCompare(keyword,"channel") == 0)
3231 {
3232 option=ParseChannelOption(value);
3233 if (option < 0)
3234 ThrowMSLException(OptionError,"UnrecognizedChannelType",
3235 value);
3236 channel=(ChannelType) option;
3237 break;
3238 }
3239 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3240 keyword);
3241 break;
3242 }
3243 case 'G':
3244 case 'g':
3245 {
3246 if (LocaleCompare(keyword,"gamma") == 0)
3247 {
cristy151b66d2015-04-15 10:50:31 +00003248 (void) CopyMagickString(gamma,value,MagickPathExtent);
cristy3ed852e2009-09-05 21:47:34 +00003249 break;
3250 }
3251 if (LocaleCompare(keyword,"green") == 0)
3252 {
cristydbdd0e32011-11-04 23:29:40 +00003253 pixel.green=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003254 break;
3255 }
3256 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3257 keyword);
3258 break;
3259 }
3260 case 'R':
3261 case 'r':
3262 {
3263 if (LocaleCompare(keyword,"red") == 0)
3264 {
cristydbdd0e32011-11-04 23:29:40 +00003265 pixel.red=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003266 break;
3267 }
3268 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3269 keyword);
3270 break;
3271 }
3272 default:
3273 {
3274 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3275 keyword);
3276 break;
3277 }
3278 }
3279 }
3280 if (*gamma == '\0')
cristy151b66d2015-04-15 10:50:31 +00003281 (void) FormatLocaleString(gamma,MagickPathExtent,"%g,%g,%g",
cristy3ed852e2009-09-05 21:47:34 +00003282 (double) pixel.red,(double) pixel.green,(double) pixel.blue);
cristy79d05312014-12-25 18:13:29 +00003283 (void) GammaImage(msl_info->image[n],strtod(gamma,(char **) NULL),
cristyc82a27b2011-10-21 01:07:16 +00003284 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00003285 break;
3286 }
cristyb988fe72009-09-16 01:01:10 +00003287 else if (LocaleCompare((const char *) tag,"get") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003288 {
3289 if (msl_info->image[n] == (Image *) NULL)
3290 {
cristyb988fe72009-09-16 01:01:10 +00003291 ThrowMSLException(OptionError,"NoImagesDefined",
3292 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003293 break;
3294 }
3295 if (attributes == (const xmlChar **) NULL)
3296 break;
3297 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3298 {
3299 keyword=(const char *) attributes[i++];
cristyb988fe72009-09-16 01:01:10 +00003300 CloneString(&value,(const char *) attributes[i]);
cristy151b66d2015-04-15 10:50:31 +00003301 (void) CopyMagickString(key,value,MagickPathExtent);
cristy3ed852e2009-09-05 21:47:34 +00003302 switch (*keyword)
3303 {
3304 case 'H':
3305 case 'h':
3306 {
3307 if (LocaleCompare(keyword,"height") == 0)
3308 {
cristy151b66d2015-04-15 10:50:31 +00003309 (void) FormatLocaleString(value,MagickPathExtent,"%.20g",
cristye8c25f92010-06-03 00:53:06 +00003310 (double) msl_info->image[n]->rows);
cristyd15e6592011-10-15 00:13:06 +00003311 (void) SetImageProperty(msl_info->attributes[n],key,value,
dirk6d6d5f22014-06-20 11:48:54 +00003312 exception);
cristy3ed852e2009-09-05 21:47:34 +00003313 break;
3314 }
3315 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3316 }
3317 case 'W':
3318 case 'w':
3319 {
3320 if (LocaleCompare(keyword,"width") == 0)
3321 {
cristy151b66d2015-04-15 10:50:31 +00003322 (void) FormatLocaleString(value,MagickPathExtent,"%.20g",
cristye8c25f92010-06-03 00:53:06 +00003323 (double) msl_info->image[n]->columns);
cristyd15e6592011-10-15 00:13:06 +00003324 (void) SetImageProperty(msl_info->attributes[n],key,value,
dirk6d6d5f22014-06-20 11:48:54 +00003325 exception);
cristy3ed852e2009-09-05 21:47:34 +00003326 break;
3327 }
3328 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3329 }
3330 default:
3331 {
3332 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3333 break;
3334 }
3335 }
3336 }
3337 break;
3338 }
cristyb988fe72009-09-16 01:01:10 +00003339 else if (LocaleCompare((const char *) tag, "group") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003340 {
3341 msl_info->number_groups++;
3342 msl_info->group_info=(MSLGroupInfo *) ResizeQuantumMemory(
3343 msl_info->group_info,msl_info->number_groups+1UL,
3344 sizeof(*msl_info->group_info));
3345 break;
3346 }
3347 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3348 }
3349 case 'I':
3350 case 'i':
3351 {
cristyb988fe72009-09-16 01:01:10 +00003352 if (LocaleCompare((const char *) tag,"image") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003353 {
cristy3ed852e2009-09-05 21:47:34 +00003354 MSLPushImage(msl_info,(Image *) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003355 if (attributes == (const xmlChar **) NULL)
3356 break;
3357 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3358 {
3359 keyword=(const char *) attributes[i++];
3360 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
dirk6d6d5f22014-06-20 11:48:54 +00003361 msl_info->attributes[n],(const char *) attributes[i],exception));
cristy3ed852e2009-09-05 21:47:34 +00003362 switch (*keyword)
3363 {
cristyb988fe72009-09-16 01:01:10 +00003364 case 'C':
3365 case 'c':
cristy3ed852e2009-09-05 21:47:34 +00003366 {
cristyb988fe72009-09-16 01:01:10 +00003367 if (LocaleCompare(keyword,"color") == 0)
3368 {
3369 Image
3370 *next_image;
cristy3ed852e2009-09-05 21:47:34 +00003371
cristyb988fe72009-09-16 01:01:10 +00003372 (void) CopyMagickString(msl_info->image_info[n]->filename,
cristy151b66d2015-04-15 10:50:31 +00003373 "xc:",MagickPathExtent);
cristyb988fe72009-09-16 01:01:10 +00003374 (void) ConcatenateMagickString(msl_info->image_info[n]->
cristy151b66d2015-04-15 10:50:31 +00003375 filename,value,MagickPathExtent);
dirk6d6d5f22014-06-20 11:48:54 +00003376 next_image=ReadImage(msl_info->image_info[n],exception);
3377 CatchException(exception);
cristyb988fe72009-09-16 01:01:10 +00003378 if (next_image == (Image *) NULL)
3379 continue;
3380 if (msl_info->image[n] == (Image *) NULL)
3381 msl_info->image[n]=next_image;
3382 else
3383 {
3384 register Image
3385 *p;
cristy3ed852e2009-09-05 21:47:34 +00003386
cristyb988fe72009-09-16 01:01:10 +00003387 /*
3388 Link image into image list.
3389 */
3390 p=msl_info->image[n];
3391 while (p->next != (Image *) NULL)
3392 p=GetNextImageInList(p);
3393 next_image->previous=p;
3394 p->next=next_image;
3395 }
3396 break;
3397 }
cristyb20775d2009-09-16 01:51:41 +00003398 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00003399 break;
3400 }
3401 default:
3402 {
cristyb20775d2009-09-16 01:51:41 +00003403 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00003404 break;
3405 }
3406 }
3407 }
3408 break;
3409 }
cristyb988fe72009-09-16 01:01:10 +00003410 if (LocaleCompare((const char *) tag,"implode") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003411 {
3412 Image
3413 *implode_image;
3414
3415 /*
3416 Implode image.
3417 */
3418 if (msl_info->image[n] == (Image *) NULL)
3419 {
cristyb988fe72009-09-16 01:01:10 +00003420 ThrowMSLException(OptionError,"NoImagesDefined",
3421 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003422 break;
3423 }
3424 if (attributes != (const xmlChar **) NULL)
3425 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3426 {
3427 keyword=(const char *) attributes[i++];
3428 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003429 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00003430 exception);
cristy3ed852e2009-09-05 21:47:34 +00003431 CloneString(&value,attribute);
3432 switch (*keyword)
3433 {
3434 case 'A':
3435 case 'a':
3436 {
3437 if (LocaleCompare(keyword,"amount") == 0)
3438 {
cristydbdd0e32011-11-04 23:29:40 +00003439 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00003440 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003441 break;
3442 }
3443 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3444 keyword);
3445 break;
3446 }
3447 case 'G':
3448 case 'g':
3449 {
3450 if (LocaleCompare(keyword,"geometry") == 0)
3451 {
3452 flags=ParseGeometry(value,&geometry_info);
3453 if ((flags & SigmaValue) == 0)
3454 geometry_info.sigma=1.0;
3455 break;
3456 }
3457 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3458 keyword);
3459 break;
3460 }
3461 default:
3462 {
3463 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3464 keyword);
3465 break;
3466 }
3467 }
3468 }
3469 implode_image=ImplodeImage(msl_info->image[n],geometry_info.rho,
cristyc82a27b2011-10-21 01:07:16 +00003470 msl_info->image[n]->interpolate,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00003471 if (implode_image == (Image *) NULL)
3472 break;
3473 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3474 msl_info->image[n]=implode_image;
3475 break;
3476 }
3477 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3478 }
3479 case 'L':
3480 case 'l':
3481 {
cristyb988fe72009-09-16 01:01:10 +00003482 if (LocaleCompare((const char *) tag,"label") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003483 break;
cristyb988fe72009-09-16 01:01:10 +00003484 if (LocaleCompare((const char *) tag, "level") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003485 {
3486 double
3487 levelBlack = 0, levelGamma = 1, levelWhite = QuantumRange;
3488
3489 if (msl_info->image[n] == (Image *) NULL)
3490 {
cristyb988fe72009-09-16 01:01:10 +00003491 ThrowMSLException(OptionError,"NoImagesDefined",
3492 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003493 break;
3494 }
3495 if (attributes == (const xmlChar **) NULL)
3496 break;
3497 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3498 {
3499 keyword=(const char *) attributes[i++];
cristyb988fe72009-09-16 01:01:10 +00003500 CloneString(&value,(const char *) attributes[i]);
cristy151b66d2015-04-15 10:50:31 +00003501 (void) CopyMagickString(key,value,MagickPathExtent);
cristy3ed852e2009-09-05 21:47:34 +00003502 switch (*keyword)
3503 {
3504 case 'B':
3505 case 'b':
3506 {
3507 if (LocaleCompare(keyword,"black") == 0)
3508 {
cristydbdd0e32011-11-04 23:29:40 +00003509 levelBlack = StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003510 break;
3511 }
3512 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3513 break;
3514 }
3515 case 'G':
3516 case 'g':
3517 {
3518 if (LocaleCompare(keyword,"gamma") == 0)
3519 {
cristydbdd0e32011-11-04 23:29:40 +00003520 levelGamma = StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003521 break;
3522 }
3523 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3524 break;
3525 }
3526 case 'W':
3527 case 'w':
3528 {
3529 if (LocaleCompare(keyword,"white") == 0)
3530 {
cristydbdd0e32011-11-04 23:29:40 +00003531 levelWhite = StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003532 break;
3533 }
3534 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3535 break;
3536 }
3537 default:
3538 {
3539 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3540 break;
3541 }
3542 }
3543 }
3544
3545 /* process image */
cristy01e9afd2011-08-10 17:38:41 +00003546 LevelImage(msl_info->image[n],levelBlack,levelWhite,levelGamma,
cristyc82a27b2011-10-21 01:07:16 +00003547 msl_info->exception);
cristyf89cb1d2011-07-07 01:24:37 +00003548 break;
cristy3ed852e2009-09-05 21:47:34 +00003549 }
3550 }
3551 case 'M':
3552 case 'm':
3553 {
cristyb988fe72009-09-16 01:01:10 +00003554 if (LocaleCompare((const char *) tag,"magnify") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003555 {
3556 Image
3557 *magnify_image;
3558
3559 /*
3560 Magnify image.
3561 */
3562 if (msl_info->image[n] == (Image *) NULL)
3563 {
cristyb988fe72009-09-16 01:01:10 +00003564 ThrowMSLException(OptionError,"NoImagesDefined",
3565 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003566 break;
3567 }
3568 if (attributes != (const xmlChar **) NULL)
3569 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3570 {
3571 keyword=(const char *) attributes[i++];
3572 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003573 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00003574 exception);
cristy3ed852e2009-09-05 21:47:34 +00003575 CloneString(&value,attribute);
3576 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3577 }
3578 magnify_image=MagnifyImage(msl_info->image[n],
cristyc82a27b2011-10-21 01:07:16 +00003579 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00003580 if (magnify_image == (Image *) NULL)
3581 break;
3582 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3583 msl_info->image[n]=magnify_image;
3584 break;
3585 }
cristyb988fe72009-09-16 01:01:10 +00003586 if (LocaleCompare((const char *) tag,"map") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003587 {
3588 Image
3589 *affinity_image;
3590
3591 MagickBooleanType
3592 dither;
3593
3594 QuantizeInfo
3595 *quantize_info;
3596
3597 /*
3598 Map image.
3599 */
3600 if (msl_info->image[n] == (Image *) NULL)
3601 {
cristyb988fe72009-09-16 01:01:10 +00003602 ThrowMSLException(OptionError,"NoImagesDefined",
3603 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003604 break;
3605 }
3606 affinity_image=NewImageList();
3607 dither=MagickFalse;
3608 if (attributes != (const xmlChar **) NULL)
3609 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3610 {
3611 keyword=(const char *) attributes[i++];
3612 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003613 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00003614 exception);
cristy3ed852e2009-09-05 21:47:34 +00003615 CloneString(&value,attribute);
3616 switch (*keyword)
3617 {
3618 case 'D':
3619 case 'd':
3620 {
3621 if (LocaleCompare(keyword,"dither") == 0)
3622 {
cristy042ee782011-04-22 18:48:30 +00003623 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00003624 value);
3625 if (option < 0)
3626 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
3627 value);
3628 dither=(MagickBooleanType) option;
3629 break;
3630 }
3631 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3632 keyword);
3633 break;
3634 }
3635 case 'I':
3636 case 'i':
3637 {
3638 if (LocaleCompare(keyword,"image") == 0)
3639 for (j=0; j < msl_info->n; j++)
3640 {
3641 const char
3642 *attribute;
cristyb988fe72009-09-16 01:01:10 +00003643
cristyd15e6592011-10-15 00:13:06 +00003644 attribute=GetImageProperty(msl_info->attributes[j],"id",
dirk6d6d5f22014-06-20 11:48:54 +00003645 exception);
cristy3ed852e2009-09-05 21:47:34 +00003646 if ((attribute != (const char *) NULL) &&
3647 (LocaleCompare(attribute,value) == 0))
3648 {
3649 affinity_image=CloneImage(msl_info->image[j],0,0,
dirk6d6d5f22014-06-20 11:48:54 +00003650 MagickFalse,exception);
cristy3ed852e2009-09-05 21:47:34 +00003651 break;
3652 }
3653 }
3654 break;
3655 }
3656 default:
3657 {
3658 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3659 keyword);
3660 break;
3661 }
3662 }
3663 }
3664 quantize_info=AcquireQuantizeInfo(msl_info->image_info[n]);
cristycbda6112012-05-27 20:57:16 +00003665 quantize_info->dither_method=dither != MagickFalse ?
3666 RiemersmaDitherMethod : NoDitherMethod;
cristy3ed852e2009-09-05 21:47:34 +00003667 (void) RemapImages(quantize_info,msl_info->image[n],
dirk6d6d5f22014-06-20 11:48:54 +00003668 affinity_image,exception);
cristy3ed852e2009-09-05 21:47:34 +00003669 quantize_info=DestroyQuantizeInfo(quantize_info);
3670 affinity_image=DestroyImage(affinity_image);
3671 break;
3672 }
cristyb988fe72009-09-16 01:01:10 +00003673 if (LocaleCompare((const char *) tag,"matte-floodfill") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003674 {
3675 double
3676 opacity;
3677
cristy4c08aed2011-07-01 19:47:50 +00003678 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00003679 target;
3680
3681 PaintMethod
3682 paint_method;
3683
3684 /*
3685 Matte floodfill image.
3686 */
3687 opacity=0.0;
3688 if (msl_info->image[n] == (Image *) NULL)
3689 {
cristyb988fe72009-09-16 01:01:10 +00003690 ThrowMSLException(OptionError,"NoImagesDefined",
3691 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003692 break;
3693 }
3694 SetGeometry(msl_info->image[n],&geometry);
3695 paint_method=FloodfillMethod;
3696 if (attributes != (const xmlChar **) NULL)
3697 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3698 {
3699 keyword=(const char *) attributes[i++];
3700 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003701 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00003702 exception);
cristy3ed852e2009-09-05 21:47:34 +00003703 CloneString(&value,attribute);
3704 switch (*keyword)
3705 {
3706 case 'B':
3707 case 'b':
3708 {
3709 if (LocaleCompare(keyword,"bordercolor") == 0)
3710 {
cristy269c9412011-10-13 23:41:15 +00003711 (void) QueryColorCompliance(value,AllCompliance,
dirk6d6d5f22014-06-20 11:48:54 +00003712 &target,exception);
cristy3ed852e2009-09-05 21:47:34 +00003713 paint_method=FillToBorderMethod;
3714 break;
3715 }
3716 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3717 keyword);
3718 break;
3719 }
3720 case 'F':
3721 case 'f':
3722 {
3723 if (LocaleCompare(keyword,"fuzz") == 0)
3724 {
cristydbdd0e32011-11-04 23:29:40 +00003725 msl_info->image[n]->fuzz=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00003726 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003727 break;
3728 }
3729 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3730 keyword);
3731 break;
3732 }
3733 case 'G':
3734 case 'g':
3735 {
3736 if (LocaleCompare(keyword,"geometry") == 0)
3737 {
3738 flags=ParsePageGeometry(msl_info->image[n],value,
dirk6d6d5f22014-06-20 11:48:54 +00003739 &geometry,exception);
cristy3ed852e2009-09-05 21:47:34 +00003740 if ((flags & HeightValue) == 0)
3741 geometry.height=geometry.width;
cristy3aa93752011-12-18 15:54:24 +00003742 (void) GetOneVirtualPixelInfo(msl_info->image[n],
cristy33e9da62011-10-21 19:08:58 +00003743 TileVirtualPixelMethod,geometry.x,geometry.y,&target,
dirk6d6d5f22014-06-20 11:48:54 +00003744 exception);
cristy3ed852e2009-09-05 21:47:34 +00003745 break;
3746 }
3747 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3748 keyword);
3749 break;
3750 }
3751 case 'O':
3752 case 'o':
3753 {
3754 if (LocaleCompare(keyword,"opacity") == 0)
3755 {
cristydbdd0e32011-11-04 23:29:40 +00003756 opacity=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003757 break;
3758 }
3759 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3760 keyword);
3761 break;
3762 }
3763 case 'X':
3764 case 'x':
3765 {
3766 if (LocaleCompare(keyword,"x") == 0)
3767 {
cristyf2f27272009-12-17 14:48:46 +00003768 geometry.x=StringToLong(value);
cristy3aa93752011-12-18 15:54:24 +00003769 (void) GetOneVirtualPixelInfo(msl_info->image[n],
cristy33e9da62011-10-21 19:08:58 +00003770 TileVirtualPixelMethod,geometry.x,geometry.y,&target,
dirk6d6d5f22014-06-20 11:48:54 +00003771 exception);
cristy3ed852e2009-09-05 21:47:34 +00003772 break;
3773 }
3774 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3775 keyword);
3776 break;
3777 }
3778 case 'Y':
3779 case 'y':
3780 {
3781 if (LocaleCompare(keyword,"y") == 0)
3782 {
cristyf2f27272009-12-17 14:48:46 +00003783 geometry.y=StringToLong(value);
cristy3aa93752011-12-18 15:54:24 +00003784 (void) GetOneVirtualPixelInfo(msl_info->image[n],
cristy33e9da62011-10-21 19:08:58 +00003785 TileVirtualPixelMethod,geometry.x,geometry.y,&target,
dirk6d6d5f22014-06-20 11:48:54 +00003786 exception);
cristy3ed852e2009-09-05 21:47:34 +00003787 break;
3788 }
3789 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3790 keyword);
3791 break;
3792 }
3793 default:
3794 {
3795 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3796 keyword);
3797 break;
3798 }
3799 }
3800 }
3801 draw_info=CloneDrawInfo(msl_info->image_info[n],
3802 msl_info->draw_info[n]);
cristy4c08aed2011-07-01 19:47:50 +00003803 draw_info->fill.alpha=ClampToQuantum(opacity);
cristycf1296e2012-08-26 23:40:49 +00003804 channel_mask=SetImageChannelMask(msl_info->image[n],AlphaChannel);
cristyd42d9952011-07-08 14:21:50 +00003805 (void) FloodfillPaintImage(msl_info->image[n],draw_info,&target,
3806 geometry.x,geometry.y,paint_method == FloodfillMethod ?
cristyc82a27b2011-10-21 01:07:16 +00003807 MagickFalse : MagickTrue,msl_info->exception);
cristycf1296e2012-08-26 23:40:49 +00003808 (void) SetPixelChannelMask(msl_info->image[n],channel_mask);
cristy3ed852e2009-09-05 21:47:34 +00003809 draw_info=DestroyDrawInfo(draw_info);
3810 break;
3811 }
cristyb988fe72009-09-16 01:01:10 +00003812 if (LocaleCompare((const char *) tag,"median-filter") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003813 {
3814 Image
3815 *median_image;
3816
3817 /*
3818 Median-filter image.
3819 */
3820 if (msl_info->image[n] == (Image *) NULL)
3821 {
cristyb988fe72009-09-16 01:01:10 +00003822 ThrowMSLException(OptionError,"NoImagesDefined",
3823 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003824 break;
3825 }
3826 if (attributes != (const xmlChar **) NULL)
3827 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3828 {
3829 keyword=(const char *) attributes[i++];
3830 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003831 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00003832 exception);
cristy3ed852e2009-09-05 21:47:34 +00003833 CloneString(&value,attribute);
3834 switch (*keyword)
3835 {
3836 case 'G':
3837 case 'g':
3838 {
3839 if (LocaleCompare(keyword,"geometry") == 0)
3840 {
3841 flags=ParseGeometry(value,&geometry_info);
3842 if ((flags & SigmaValue) == 0)
3843 geometry_info.sigma=1.0;
3844 break;
3845 }
3846 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3847 keyword);
3848 break;
3849 }
3850 case 'R':
3851 case 'r':
3852 {
3853 if (LocaleCompare(keyword,"radius") == 0)
3854 {
cristydbdd0e32011-11-04 23:29:40 +00003855 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00003856 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003857 break;
3858 }
3859 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3860 keyword);
3861 break;
3862 }
3863 default:
3864 {
3865 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3866 keyword);
3867 break;
3868 }
3869 }
3870 }
cristy733678d2011-03-18 21:29:28 +00003871 median_image=StatisticImage(msl_info->image[n],MedianStatistic,
cristy95c38342011-03-18 22:39:51 +00003872 (size_t) geometry_info.rho,(size_t) geometry_info.sigma,
cristyc82a27b2011-10-21 01:07:16 +00003873 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00003874 if (median_image == (Image *) NULL)
3875 break;
3876 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3877 msl_info->image[n]=median_image;
3878 break;
3879 }
cristyb988fe72009-09-16 01:01:10 +00003880 if (LocaleCompare((const char *) tag,"minify") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003881 {
3882 Image
3883 *minify_image;
3884
3885 /*
3886 Minify image.
3887 */
3888 if (msl_info->image[n] == (Image *) NULL)
3889 {
cristyb988fe72009-09-16 01:01:10 +00003890 ThrowMSLException(OptionError,"NoImagesDefined",
3891 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003892 break;
3893 }
3894 if (attributes != (const xmlChar **) NULL)
3895 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3896 {
3897 keyword=(const char *) attributes[i++];
3898 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003899 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00003900 exception);
cristy3ed852e2009-09-05 21:47:34 +00003901 CloneString(&value,attribute);
3902 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3903 }
3904 minify_image=MinifyImage(msl_info->image[n],
cristyc82a27b2011-10-21 01:07:16 +00003905 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00003906 if (minify_image == (Image *) NULL)
3907 break;
3908 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3909 msl_info->image[n]=minify_image;
3910 break;
3911 }
cristyb988fe72009-09-16 01:01:10 +00003912 if (LocaleCompare((const char *) tag,"msl") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00003913 break;
cristyb988fe72009-09-16 01:01:10 +00003914 if (LocaleCompare((const char *) tag,"modulate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003915 {
3916 char
cristy151b66d2015-04-15 10:50:31 +00003917 modulate[MagickPathExtent];
cristy3ed852e2009-09-05 21:47:34 +00003918
3919 /*
3920 Modulate image.
3921 */
3922 if (msl_info->image[n] == (Image *) NULL)
3923 {
cristyb988fe72009-09-16 01:01:10 +00003924 ThrowMSLException(OptionError,"NoImagesDefined",
3925 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003926 break;
3927 }
3928 geometry_info.rho=100.0;
3929 geometry_info.sigma=100.0;
3930 geometry_info.xi=100.0;
3931 if (attributes != (const xmlChar **) NULL)
3932 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3933 {
3934 keyword=(const char *) attributes[i++];
3935 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003936 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00003937 exception);
cristy3ed852e2009-09-05 21:47:34 +00003938 CloneString(&value,attribute);
3939 switch (*keyword)
3940 {
3941 case 'B':
3942 case 'b':
3943 {
3944 if (LocaleCompare(keyword,"blackness") == 0)
3945 {
cristydbdd0e32011-11-04 23:29:40 +00003946 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00003947 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003948 break;
3949 }
3950 if (LocaleCompare(keyword,"brightness") == 0)
3951 {
cristydbdd0e32011-11-04 23:29:40 +00003952 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00003953 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003954 break;
3955 }
3956 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3957 keyword);
3958 break;
3959 }
3960 case 'F':
3961 case 'f':
3962 {
3963 if (LocaleCompare(keyword,"factor") == 0)
3964 {
3965 flags=ParseGeometry(value,&geometry_info);
3966 break;
3967 }
3968 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3969 keyword);
3970 break;
3971 }
3972 case 'H':
3973 case 'h':
3974 {
3975 if (LocaleCompare(keyword,"hue") == 0)
3976 {
cristydbdd0e32011-11-04 23:29:40 +00003977 geometry_info.xi=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00003978 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003979 break;
3980 }
3981 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3982 keyword);
3983 break;
3984 }
3985 case 'L':
3986 case 'l':
3987 {
3988 if (LocaleCompare(keyword,"lightness") == 0)
3989 {
cristydbdd0e32011-11-04 23:29:40 +00003990 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00003991 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003992 break;
3993 }
3994 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3995 keyword);
3996 break;
3997 }
3998 case 'S':
3999 case 's':
4000 {
4001 if (LocaleCompare(keyword,"saturation") == 0)
4002 {
cristydbdd0e32011-11-04 23:29:40 +00004003 geometry_info.sigma=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00004004 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004005 break;
4006 }
4007 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4008 keyword);
4009 break;
4010 }
4011 case 'W':
4012 case 'w':
4013 {
4014 if (LocaleCompare(keyword,"whiteness") == 0)
4015 {
cristydbdd0e32011-11-04 23:29:40 +00004016 geometry_info.sigma=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00004017 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004018 break;
4019 }
4020 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4021 keyword);
4022 break;
4023 }
4024 default:
4025 {
4026 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4027 keyword);
4028 break;
4029 }
4030 }
4031 }
cristy151b66d2015-04-15 10:50:31 +00004032 (void) FormatLocaleString(modulate,MagickPathExtent,"%g,%g,%g",
cristy3ed852e2009-09-05 21:47:34 +00004033 geometry_info.rho,geometry_info.sigma,geometry_info.xi);
cristy33bd5152011-08-24 01:42:24 +00004034 (void) ModulateImage(msl_info->image[n],modulate,
cristyc82a27b2011-10-21 01:07:16 +00004035 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00004036 break;
4037 }
4038 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4039 }
4040 case 'N':
4041 case 'n':
4042 {
cristyb988fe72009-09-16 01:01:10 +00004043 if (LocaleCompare((const char *) tag,"negate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004044 {
4045 MagickBooleanType
4046 gray;
4047
4048 /*
4049 Negate image.
4050 */
4051 if (msl_info->image[n] == (Image *) NULL)
4052 {
cristyb988fe72009-09-16 01:01:10 +00004053 ThrowMSLException(OptionError,"NoImagesDefined",
4054 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004055 break;
4056 }
4057 gray=MagickFalse;
4058 if (attributes != (const xmlChar **) NULL)
4059 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4060 {
4061 keyword=(const char *) attributes[i++];
4062 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004063 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00004064 exception);
cristy3ed852e2009-09-05 21:47:34 +00004065 CloneString(&value,attribute);
4066 switch (*keyword)
4067 {
4068 case 'C':
4069 case 'c':
4070 {
4071 if (LocaleCompare(keyword,"channel") == 0)
4072 {
4073 option=ParseChannelOption(value);
4074 if (option < 0)
4075 ThrowMSLException(OptionError,"UnrecognizedChannelType",
4076 value);
4077 channel=(ChannelType) option;
4078 break;
4079 }
4080 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4081 keyword);
4082 break;
4083 }
4084 case 'G':
4085 case 'g':
4086 {
4087 if (LocaleCompare(keyword,"gray") == 0)
4088 {
cristy042ee782011-04-22 18:48:30 +00004089 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004090 value);
4091 if (option < 0)
4092 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4093 value);
4094 gray=(MagickBooleanType) option;
4095 break;
4096 }
4097 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4098 keyword);
4099 break;
4100 }
4101 default:
4102 {
4103 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4104 keyword);
4105 break;
4106 }
4107 }
4108 }
cristycf1296e2012-08-26 23:40:49 +00004109 channel_mask=SetImageChannelMask(msl_info->image[n],channel);
cristyb3e7c6c2011-07-24 01:43:55 +00004110 (void) NegateImage(msl_info->image[n],gray,
cristyc82a27b2011-10-21 01:07:16 +00004111 msl_info->exception);
cristycf1296e2012-08-26 23:40:49 +00004112 (void) SetPixelChannelMask(msl_info->image[n],channel_mask);
cristy3ed852e2009-09-05 21:47:34 +00004113 break;
4114 }
cristyb988fe72009-09-16 01:01:10 +00004115 if (LocaleCompare((const char *) tag,"normalize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004116 {
4117 /*
4118 Normalize image.
4119 */
4120 if (msl_info->image[n] == (Image *) NULL)
4121 {
cristyb988fe72009-09-16 01:01:10 +00004122 ThrowMSLException(OptionError,"NoImagesDefined",
4123 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004124 break;
4125 }
4126 if (attributes != (const xmlChar **) NULL)
4127 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4128 {
4129 keyword=(const char *) attributes[i++];
4130 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004131 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00004132 exception);
cristy3ed852e2009-09-05 21:47:34 +00004133 CloneString(&value,attribute);
4134 switch (*keyword)
4135 {
4136 case 'C':
4137 case 'c':
4138 {
4139 if (LocaleCompare(keyword,"channel") == 0)
4140 {
4141 option=ParseChannelOption(value);
4142 if (option < 0)
4143 ThrowMSLException(OptionError,"UnrecognizedChannelType",
4144 value);
4145 channel=(ChannelType) option;
4146 break;
4147 }
4148 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4149 keyword);
4150 break;
4151 }
4152 default:
4153 {
4154 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4155 keyword);
4156 break;
4157 }
4158 }
4159 }
cristye23ec9d2011-08-16 18:15:40 +00004160 (void) NormalizeImage(msl_info->image[n],
cristyc82a27b2011-10-21 01:07:16 +00004161 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00004162 break;
4163 }
4164 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4165 }
4166 case 'O':
4167 case 'o':
4168 {
cristyb988fe72009-09-16 01:01:10 +00004169 if (LocaleCompare((const char *) tag,"oil-paint") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004170 {
4171 Image
4172 *paint_image;
4173
4174 /*
4175 Oil-paint image.
4176 */
4177 if (msl_info->image[n] == (Image *) NULL)
4178 {
cristyb988fe72009-09-16 01:01:10 +00004179 ThrowMSLException(OptionError,"NoImagesDefined",
4180 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004181 break;
4182 }
4183 if (attributes != (const xmlChar **) NULL)
4184 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4185 {
4186 keyword=(const char *) attributes[i++];
4187 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004188 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00004189 exception);
cristy3ed852e2009-09-05 21:47:34 +00004190 CloneString(&value,attribute);
4191 switch (*keyword)
4192 {
4193 case 'G':
4194 case 'g':
4195 {
4196 if (LocaleCompare(keyword,"geometry") == 0)
4197 {
4198 flags=ParseGeometry(value,&geometry_info);
4199 if ((flags & SigmaValue) == 0)
4200 geometry_info.sigma=1.0;
4201 break;
4202 }
4203 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4204 keyword);
4205 break;
4206 }
4207 case 'R':
4208 case 'r':
4209 {
4210 if (LocaleCompare(keyword,"radius") == 0)
4211 {
cristydbdd0e32011-11-04 23:29:40 +00004212 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00004213 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004214 break;
4215 }
4216 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4217 keyword);
4218 break;
4219 }
4220 default:
4221 {
4222 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4223 keyword);
4224 break;
4225 }
4226 }
4227 }
4228 paint_image=OilPaintImage(msl_info->image[n],geometry_info.rho,
cristyc82a27b2011-10-21 01:07:16 +00004229 geometry_info.sigma,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00004230 if (paint_image == (Image *) NULL)
4231 break;
4232 msl_info->image[n]=DestroyImage(msl_info->image[n]);
4233 msl_info->image[n]=paint_image;
4234 break;
4235 }
cristyb988fe72009-09-16 01:01:10 +00004236 if (LocaleCompare((const char *) tag,"opaque") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004237 {
cristy4c08aed2011-07-01 19:47:50 +00004238 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00004239 fill_color,
4240 target;
4241
4242 /*
4243 Opaque image.
4244 */
4245 if (msl_info->image[n] == (Image *) NULL)
4246 {
cristyb988fe72009-09-16 01:01:10 +00004247 ThrowMSLException(OptionError,"NoImagesDefined",
4248 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004249 break;
4250 }
cristy269c9412011-10-13 23:41:15 +00004251 (void) QueryColorCompliance("none",AllCompliance,&target,
dirk6d6d5f22014-06-20 11:48:54 +00004252 exception);
cristy269c9412011-10-13 23:41:15 +00004253 (void) QueryColorCompliance("none",AllCompliance,&fill_color,
dirk6d6d5f22014-06-20 11:48:54 +00004254 exception);
cristy3ed852e2009-09-05 21:47:34 +00004255 if (attributes != (const xmlChar **) NULL)
4256 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4257 {
4258 keyword=(const char *) attributes[i++];
4259 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004260 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00004261 exception);
cristy3ed852e2009-09-05 21:47:34 +00004262 CloneString(&value,attribute);
4263 switch (*keyword)
4264 {
4265 case 'C':
4266 case 'c':
4267 {
4268 if (LocaleCompare(keyword,"channel") == 0)
4269 {
4270 option=ParseChannelOption(value);
4271 if (option < 0)
4272 ThrowMSLException(OptionError,"UnrecognizedChannelType",
4273 value);
4274 channel=(ChannelType) option;
4275 break;
4276 }
4277 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4278 keyword);
4279 break;
4280 }
4281 case 'F':
4282 case 'f':
4283 {
4284 if (LocaleCompare(keyword,"fill") == 0)
4285 {
cristy269c9412011-10-13 23:41:15 +00004286 (void) QueryColorCompliance(value,AllCompliance,
dirk6d6d5f22014-06-20 11:48:54 +00004287 &fill_color,exception);
cristy3ed852e2009-09-05 21:47:34 +00004288 break;
4289 }
4290 if (LocaleCompare(keyword,"fuzz") == 0)
4291 {
cristydbdd0e32011-11-04 23:29:40 +00004292 msl_info->image[n]->fuzz=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00004293 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004294 break;
4295 }
4296 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4297 keyword);
4298 break;
4299 }
4300 default:
4301 {
4302 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4303 keyword);
4304 break;
4305 }
4306 }
4307 }
cristycf1296e2012-08-26 23:40:49 +00004308 channel_mask=SetImageChannelMask(msl_info->image[n],channel);
cristyd42d9952011-07-08 14:21:50 +00004309 (void) OpaquePaintImage(msl_info->image[n],&target,&fill_color,
cristyc82a27b2011-10-21 01:07:16 +00004310 MagickFalse,msl_info->exception);
cristycf1296e2012-08-26 23:40:49 +00004311 (void) SetPixelChannelMask(msl_info->image[n],channel_mask);
cristy3ed852e2009-09-05 21:47:34 +00004312 break;
4313 }
4314 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4315 }
4316 case 'P':
4317 case 'p':
4318 {
cristyb988fe72009-09-16 01:01:10 +00004319 if (LocaleCompare((const char *) tag,"print") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004320 {
4321 if (attributes == (const xmlChar **) NULL)
4322 break;
4323 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4324 {
4325 keyword=(const char *) attributes[i++];
4326 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004327 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00004328 exception);
cristy3ed852e2009-09-05 21:47:34 +00004329 CloneString(&value,attribute);
4330 switch (*keyword)
4331 {
4332 case 'O':
4333 case 'o':
4334 {
4335 if (LocaleCompare(keyword,"output") == 0)
4336 {
cristyb51dff52011-05-19 16:55:47 +00004337 (void) FormatLocaleFile(stdout,"%s",value);
cristy3ed852e2009-09-05 21:47:34 +00004338 break;
4339 }
4340 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
4341 break;
4342 }
4343 default:
4344 {
4345 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
4346 break;
4347 }
4348 }
4349 }
4350 break;
4351 }
cristy4fa36e42009-09-18 14:24:06 +00004352 if (LocaleCompare((const char *) tag, "profile") == 0)
4353 {
cristy4fa36e42009-09-18 14:24:06 +00004354 if (msl_info->image[n] == (Image *) NULL)
4355 {
4356 ThrowMSLException(OptionError,"NoImagesDefined",
4357 (const char *) tag);
4358 break;
4359 }
4360 if (attributes == (const xmlChar **) NULL)
4361 break;
4362 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4363 {
4364 const char
4365 *name;
4366
4367 const StringInfo
4368 *profile;
4369
4370 Image
4371 *profile_image;
4372
4373 ImageInfo
4374 *profile_info;
4375
4376 keyword=(const char *) attributes[i++];
4377 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004378 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00004379 exception);
cristy4fa36e42009-09-18 14:24:06 +00004380 CloneString(&value,attribute);
cristy8b2b4e52012-06-27 01:01:10 +00004381 if (*keyword == '!')
cristy4fa36e42009-09-18 14:24:06 +00004382 {
4383 /*
4384 Remove a profile from the image.
4385 */
4386 (void) ProfileImage(msl_info->image[n],keyword,
dirk6d6d5f22014-06-20 11:48:54 +00004387 (const unsigned char *) NULL,0,exception);
cristy4fa36e42009-09-18 14:24:06 +00004388 continue;
4389 }
4390 /*
4391 Associate a profile with the image.
4392 */
4393 profile_info=CloneImageInfo(msl_info->image_info[n]);
4394 profile=GetImageProfile(msl_info->image[n],"iptc");
4395 if (profile != (StringInfo *) NULL)
4396 profile_info->profile=(void *) CloneStringInfo(profile);
dirk6d6d5f22014-06-20 11:48:54 +00004397 profile_image=GetImageCache(profile_info,keyword,exception);
cristy4fa36e42009-09-18 14:24:06 +00004398 profile_info=DestroyImageInfo(profile_info);
4399 if (profile_image == (Image *) NULL)
4400 {
4401 char
cristy151b66d2015-04-15 10:50:31 +00004402 name[MagickPathExtent],
4403 filename[MagickPathExtent];
cristy4fa36e42009-09-18 14:24:06 +00004404
4405 register char
4406 *p;
4407
4408 StringInfo
4409 *profile;
4410
cristy151b66d2015-04-15 10:50:31 +00004411 (void) CopyMagickString(filename,keyword,MagickPathExtent);
4412 (void) CopyMagickString(name,keyword,MagickPathExtent);
cristy4fa36e42009-09-18 14:24:06 +00004413 for (p=filename; *p != '\0'; p++)
4414 if ((*p == ':') && (IsPathDirectory(keyword) < 0) &&
4415 (IsPathAccessible(keyword) == MagickFalse))
4416 {
4417 register char
4418 *q;
4419
4420 /*
4421 Look for profile name (e.g. name:profile).
4422 */
4423 (void) CopyMagickString(name,filename,(size_t)
4424 (p-filename+1));
4425 for (q=filename; *q != '\0'; q++)
4426 *q=(*++p);
4427 break;
4428 }
dirk6d6d5f22014-06-20 11:48:54 +00004429 profile=FileToStringInfo(filename,~0UL,exception);
cristy4fa36e42009-09-18 14:24:06 +00004430 if (profile != (StringInfo *) NULL)
4431 {
4432 (void) ProfileImage(msl_info->image[n],name,
cristybb503372010-05-27 20:51:26 +00004433 GetStringInfoDatum(profile),(size_t)
dirk6d6d5f22014-06-20 11:48:54 +00004434 GetStringInfoLength(profile),exception);
cristy4fa36e42009-09-18 14:24:06 +00004435 profile=DestroyStringInfo(profile);
4436 }
4437 continue;
4438 }
4439 ResetImageProfileIterator(profile_image);
4440 name=GetNextImageProfile(profile_image);
4441 while (name != (const char *) NULL)
4442 {
4443 profile=GetImageProfile(profile_image,name);
4444 if (profile != (StringInfo *) NULL)
4445 (void) ProfileImage(msl_info->image[n],name,
cristybb503372010-05-27 20:51:26 +00004446 GetStringInfoDatum(profile),(size_t)
dirk6d6d5f22014-06-20 11:48:54 +00004447 GetStringInfoLength(profile),exception);
cristy4fa36e42009-09-18 14:24:06 +00004448 name=GetNextImageProfile(profile_image);
4449 }
4450 profile_image=DestroyImage(profile_image);
4451 }
4452 break;
4453 }
cristy3ed852e2009-09-05 21:47:34 +00004454 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4455 }
4456 case 'Q':
4457 case 'q':
4458 {
cristyb988fe72009-09-16 01:01:10 +00004459 if (LocaleCompare((const char *) tag,"quantize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004460 {
4461 QuantizeInfo
4462 quantize_info;
4463
4464 /*
4465 Quantize image.
4466 */
4467 if (msl_info->image[n] == (Image *) NULL)
4468 {
cristyb988fe72009-09-16 01:01:10 +00004469 ThrowMSLException(OptionError,"NoImagesDefined",
4470 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004471 break;
4472 }
4473 GetQuantizeInfo(&quantize_info);
4474 if (attributes != (const xmlChar **) NULL)
4475 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4476 {
4477 keyword=(const char *) attributes[i++];
4478 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004479 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00004480 exception);
cristy3ed852e2009-09-05 21:47:34 +00004481 CloneString(&value,attribute);
4482 switch (*keyword)
4483 {
4484 case 'C':
4485 case 'c':
4486 {
4487 if (LocaleCompare(keyword,"colors") == 0)
4488 {
cristyf2f27272009-12-17 14:48:46 +00004489 quantize_info.number_colors=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004490 break;
4491 }
4492 if (LocaleCompare(keyword,"colorspace") == 0)
4493 {
cristy042ee782011-04-22 18:48:30 +00004494 option=ParseCommandOption(MagickColorspaceOptions,
cristy3ed852e2009-09-05 21:47:34 +00004495 MagickFalse,value);
4496 if (option < 0)
4497 ThrowMSLException(OptionError,
4498 "UnrecognizedColorspaceType",value);
4499 quantize_info.colorspace=(ColorspaceType) option;
4500 break;
4501 }
4502 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4503 keyword);
4504 break;
4505 }
4506 case 'D':
4507 case 'd':
4508 {
4509 if (LocaleCompare(keyword,"dither") == 0)
4510 {
cristycbda6112012-05-27 20:57:16 +00004511 option=ParseCommandOption(MagickDitherOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004512 value);
4513 if (option < 0)
4514 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4515 value);
cristycbda6112012-05-27 20:57:16 +00004516 quantize_info.dither_method=(DitherMethod) option;
cristy3ed852e2009-09-05 21:47:34 +00004517 break;
4518 }
4519 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4520 keyword);
4521 break;
4522 }
4523 case 'M':
4524 case 'm':
4525 {
4526 if (LocaleCompare(keyword,"measure") == 0)
4527 {
cristy042ee782011-04-22 18:48:30 +00004528 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004529 value);
4530 if (option < 0)
4531 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4532 value);
4533 quantize_info.measure_error=(MagickBooleanType) option;
4534 break;
4535 }
4536 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4537 keyword);
4538 break;
4539 }
4540 case 'T':
4541 case 't':
4542 {
4543 if (LocaleCompare(keyword,"treedepth") == 0)
4544 {
cristyf2f27272009-12-17 14:48:46 +00004545 quantize_info.tree_depth=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004546 break;
4547 }
4548 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4549 keyword);
4550 break;
4551 }
4552 default:
4553 {
4554 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4555 keyword);
4556 break;
4557 }
4558 }
4559 }
dirk6d6d5f22014-06-20 11:48:54 +00004560 (void) QuantizeImage(&quantize_info,msl_info->image[n],exception);
cristy3ed852e2009-09-05 21:47:34 +00004561 break;
4562 }
cristyb988fe72009-09-16 01:01:10 +00004563 if (LocaleCompare((const char *) tag,"query-font-metrics") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004564 {
4565 char
cristy151b66d2015-04-15 10:50:31 +00004566 text[MagickPathExtent];
cristy3ed852e2009-09-05 21:47:34 +00004567
4568 MagickBooleanType
4569 status;
4570
4571 TypeMetric
4572 metrics;
4573
4574 /*
4575 Query font metrics.
4576 */
4577 draw_info=CloneDrawInfo(msl_info->image_info[n],
4578 msl_info->draw_info[n]);
4579 angle=0.0;
4580 current=draw_info->affine;
4581 GetAffineMatrix(&affine);
4582 if (attributes != (const xmlChar **) NULL)
4583 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4584 {
4585 keyword=(const char *) attributes[i++];
4586 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004587 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00004588 exception);
cristy3ed852e2009-09-05 21:47:34 +00004589 CloneString(&value,attribute);
4590 switch (*keyword)
4591 {
4592 case 'A':
4593 case 'a':
4594 {
4595 if (LocaleCompare(keyword,"affine") == 0)
4596 {
4597 char
4598 *p;
4599
4600 p=value;
cristydbdd0e32011-11-04 23:29:40 +00004601 draw_info->affine.sx=StringToDouble(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004602 if (*p ==',')
4603 p++;
cristydbdd0e32011-11-04 23:29:40 +00004604 draw_info->affine.rx=StringToDouble(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004605 if (*p ==',')
4606 p++;
cristydbdd0e32011-11-04 23:29:40 +00004607 draw_info->affine.ry=StringToDouble(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004608 if (*p ==',')
4609 p++;
cristydbdd0e32011-11-04 23:29:40 +00004610 draw_info->affine.sy=StringToDouble(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004611 if (*p ==',')
4612 p++;
cristydbdd0e32011-11-04 23:29:40 +00004613 draw_info->affine.tx=StringToDouble(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004614 if (*p ==',')
4615 p++;
cristydbdd0e32011-11-04 23:29:40 +00004616 draw_info->affine.ty=StringToDouble(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004617 break;
4618 }
4619 if (LocaleCompare(keyword,"align") == 0)
4620 {
cristy042ee782011-04-22 18:48:30 +00004621 option=ParseCommandOption(MagickAlignOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004622 value);
4623 if (option < 0)
4624 ThrowMSLException(OptionError,"UnrecognizedAlignType",
4625 value);
4626 draw_info->align=(AlignType) option;
4627 break;
4628 }
4629 if (LocaleCompare(keyword,"antialias") == 0)
4630 {
cristy042ee782011-04-22 18:48:30 +00004631 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004632 value);
4633 if (option < 0)
4634 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4635 value);
4636 draw_info->stroke_antialias=(MagickBooleanType) option;
4637 draw_info->text_antialias=(MagickBooleanType) option;
4638 break;
4639 }
4640 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4641 keyword);
4642 break;
4643 }
4644 case 'D':
4645 case 'd':
4646 {
4647 if (LocaleCompare(keyword,"density") == 0)
4648 {
4649 CloneString(&draw_info->density,value);
4650 break;
4651 }
4652 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4653 keyword);
4654 break;
4655 }
4656 case 'E':
4657 case 'e':
4658 {
4659 if (LocaleCompare(keyword,"encoding") == 0)
4660 {
4661 CloneString(&draw_info->encoding,value);
4662 break;
4663 }
4664 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4665 keyword);
4666 break;
4667 }
4668 case 'F':
4669 case 'f':
4670 {
4671 if (LocaleCompare(keyword, "fill") == 0)
4672 {
cristy9950d572011-10-01 18:22:35 +00004673 (void) QueryColorCompliance(value,AllCompliance,
dirk6d6d5f22014-06-20 11:48:54 +00004674 &draw_info->fill,exception);
cristy3ed852e2009-09-05 21:47:34 +00004675 break;
4676 }
4677 if (LocaleCompare(keyword,"family") == 0)
4678 {
4679 CloneString(&draw_info->family,value);
4680 break;
4681 }
4682 if (LocaleCompare(keyword,"font") == 0)
4683 {
4684 CloneString(&draw_info->font,value);
4685 break;
4686 }
4687 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4688 keyword);
4689 break;
4690 }
4691 case 'G':
4692 case 'g':
4693 {
4694 if (LocaleCompare(keyword,"geometry") == 0)
4695 {
4696 flags=ParsePageGeometry(msl_info->image[n],value,
dirk6d6d5f22014-06-20 11:48:54 +00004697 &geometry,exception);
cristy3ed852e2009-09-05 21:47:34 +00004698 if ((flags & HeightValue) == 0)
4699 geometry.height=geometry.width;
4700 break;
4701 }
4702 if (LocaleCompare(keyword,"gravity") == 0)
4703 {
cristy042ee782011-04-22 18:48:30 +00004704 option=ParseCommandOption(MagickGravityOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004705 value);
4706 if (option < 0)
4707 ThrowMSLException(OptionError,"UnrecognizedGravityType",
4708 value);
4709 draw_info->gravity=(GravityType) option;
4710 break;
4711 }
4712 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4713 keyword);
4714 break;
4715 }
4716 case 'P':
4717 case 'p':
4718 {
4719 if (LocaleCompare(keyword,"pointsize") == 0)
4720 {
cristydbdd0e32011-11-04 23:29:40 +00004721 draw_info->pointsize=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00004722 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004723 break;
4724 }
4725 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4726 keyword);
4727 break;
4728 }
4729 case 'R':
4730 case 'r':
4731 {
4732 if (LocaleCompare(keyword,"rotate") == 0)
4733 {
cristydbdd0e32011-11-04 23:29:40 +00004734 angle=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004735 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
4736 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
4737 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
4738 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
4739 break;
4740 }
4741 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4742 keyword);
4743 break;
4744 }
4745 case 'S':
4746 case 's':
4747 {
4748 if (LocaleCompare(keyword,"scale") == 0)
4749 {
4750 flags=ParseGeometry(value,&geometry_info);
4751 if ((flags & SigmaValue) == 0)
4752 geometry_info.sigma=1.0;
4753 affine.sx=geometry_info.rho;
4754 affine.sy=geometry_info.sigma;
4755 break;
4756 }
4757 if (LocaleCompare(keyword,"skewX") == 0)
4758 {
cristydbdd0e32011-11-04 23:29:40 +00004759 angle=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004760 affine.ry=cos(DegreesToRadians(fmod(angle,360.0)));
4761 break;
4762 }
4763 if (LocaleCompare(keyword,"skewY") == 0)
4764 {
cristydbdd0e32011-11-04 23:29:40 +00004765 angle=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004766 affine.rx=cos(DegreesToRadians(fmod(angle,360.0)));
4767 break;
4768 }
4769 if (LocaleCompare(keyword,"stretch") == 0)
4770 {
cristy9950d572011-10-01 18:22:35 +00004771 option=ParseCommandOption(MagickStretchOptions,
4772 MagickFalse,value);
cristy3ed852e2009-09-05 21:47:34 +00004773 if (option < 0)
4774 ThrowMSLException(OptionError,"UnrecognizedStretchType",
4775 value);
4776 draw_info->stretch=(StretchType) option;
4777 break;
4778 }
4779 if (LocaleCompare(keyword, "stroke") == 0)
4780 {
cristy9950d572011-10-01 18:22:35 +00004781 (void) QueryColorCompliance(value,AllCompliance,
dirk6d6d5f22014-06-20 11:48:54 +00004782 &draw_info->stroke,exception);
cristy3ed852e2009-09-05 21:47:34 +00004783 break;
4784 }
4785 if (LocaleCompare(keyword,"strokewidth") == 0)
4786 {
cristyf2f27272009-12-17 14:48:46 +00004787 draw_info->stroke_width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004788 break;
4789 }
4790 if (LocaleCompare(keyword,"style") == 0)
4791 {
cristy042ee782011-04-22 18:48:30 +00004792 option=ParseCommandOption(MagickStyleOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004793 value);
4794 if (option < 0)
4795 ThrowMSLException(OptionError,"UnrecognizedStyleType",
4796 value);
4797 draw_info->style=(StyleType) option;
4798 break;
4799 }
4800 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4801 keyword);
4802 break;
4803 }
4804 case 'T':
4805 case 't':
4806 {
4807 if (LocaleCompare(keyword,"text") == 0)
4808 {
4809 CloneString(&draw_info->text,value);
4810 break;
4811 }
4812 if (LocaleCompare(keyword,"translate") == 0)
4813 {
4814 flags=ParseGeometry(value,&geometry_info);
4815 if ((flags & SigmaValue) == 0)
4816 geometry_info.sigma=1.0;
4817 affine.tx=geometry_info.rho;
4818 affine.ty=geometry_info.sigma;
4819 break;
4820 }
4821 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4822 keyword);
4823 break;
4824 }
4825 case 'U':
4826 case 'u':
4827 {
4828 if (LocaleCompare(keyword, "undercolor") == 0)
4829 {
cristy9950d572011-10-01 18:22:35 +00004830 (void) QueryColorCompliance(value,AllCompliance,
dirk6d6d5f22014-06-20 11:48:54 +00004831 &draw_info->undercolor,exception);
cristy3ed852e2009-09-05 21:47:34 +00004832 break;
4833 }
4834 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4835 keyword);
4836 break;
4837 }
4838 case 'W':
4839 case 'w':
4840 {
4841 if (LocaleCompare(keyword,"weight") == 0)
4842 {
cristyf2f27272009-12-17 14:48:46 +00004843 draw_info->weight=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004844 break;
4845 }
4846 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4847 keyword);
4848 break;
4849 }
4850 case 'X':
4851 case 'x':
4852 {
4853 if (LocaleCompare(keyword,"x") == 0)
4854 {
cristyf2f27272009-12-17 14:48:46 +00004855 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004856 break;
4857 }
4858 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4859 keyword);
4860 break;
4861 }
4862 case 'Y':
4863 case 'y':
4864 {
4865 if (LocaleCompare(keyword,"y") == 0)
4866 {
cristyf2f27272009-12-17 14:48:46 +00004867 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004868 break;
4869 }
4870 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4871 keyword);
4872 break;
4873 }
4874 default:
4875 {
4876 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4877 keyword);
4878 break;
4879 }
4880 }
4881 }
cristy151b66d2015-04-15 10:50:31 +00004882 (void) FormatLocaleString(text,MagickPathExtent,
cristye8c25f92010-06-03 00:53:06 +00004883 "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,(double)
4884 geometry.height,(double) geometry.x,(double) geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00004885 CloneString(&draw_info->geometry,text);
cristyef7c8a52010-10-10 13:46:51 +00004886 draw_info->affine.sx=affine.sx*current.sx+affine.ry*current.rx;
4887 draw_info->affine.rx=affine.rx*current.sx+affine.sy*current.rx;
4888 draw_info->affine.ry=affine.sx*current.ry+affine.ry*current.sy;
4889 draw_info->affine.sy=affine.rx*current.ry+affine.sy*current.sy;
4890 draw_info->affine.tx=affine.sx*current.tx+affine.ry*current.ty+
4891 affine.tx;
4892 draw_info->affine.ty=affine.rx*current.tx+affine.sy*current.ty+
4893 affine.ty;
cristy5cbc0162011-08-29 00:36:28 +00004894 status=GetTypeMetrics(msl_info->attributes[n],draw_info,&metrics,
cristyc82a27b2011-10-21 01:07:16 +00004895 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00004896 if (status != MagickFalse)
4897 {
4898 Image
4899 *image;
4900
4901 image=msl_info->attributes[n];
cristy8cd5b312010-01-07 01:10:24 +00004902 FormatImageProperty(image,"msl:font-metrics.pixels_per_em.x",
cristye7f51092010-01-17 00:39:37 +00004903 "%g",metrics.pixels_per_em.x);
cristy8cd5b312010-01-07 01:10:24 +00004904 FormatImageProperty(image,"msl:font-metrics.pixels_per_em.y",
cristye7f51092010-01-17 00:39:37 +00004905 "%g",metrics.pixels_per_em.y);
4906 FormatImageProperty(image,"msl:font-metrics.ascent","%g",
cristy3ed852e2009-09-05 21:47:34 +00004907 metrics.ascent);
cristye7f51092010-01-17 00:39:37 +00004908 FormatImageProperty(image,"msl:font-metrics.descent","%g",
cristy3ed852e2009-09-05 21:47:34 +00004909 metrics.descent);
cristye7f51092010-01-17 00:39:37 +00004910 FormatImageProperty(image,"msl:font-metrics.width","%g",
cristy3ed852e2009-09-05 21:47:34 +00004911 metrics.width);
cristye7f51092010-01-17 00:39:37 +00004912 FormatImageProperty(image,"msl:font-metrics.height","%g",
cristy3ed852e2009-09-05 21:47:34 +00004913 metrics.height);
cristye7f51092010-01-17 00:39:37 +00004914 FormatImageProperty(image,"msl:font-metrics.max_advance","%g",
cristy3ed852e2009-09-05 21:47:34 +00004915 metrics.max_advance);
cristye7f51092010-01-17 00:39:37 +00004916 FormatImageProperty(image,"msl:font-metrics.bounds.x1","%g",
cristy3ed852e2009-09-05 21:47:34 +00004917 metrics.bounds.x1);
cristye7f51092010-01-17 00:39:37 +00004918 FormatImageProperty(image,"msl:font-metrics.bounds.y1","%g",
cristy3ed852e2009-09-05 21:47:34 +00004919 metrics.bounds.y1);
cristye7f51092010-01-17 00:39:37 +00004920 FormatImageProperty(image,"msl:font-metrics.bounds.x2","%g",
cristy3ed852e2009-09-05 21:47:34 +00004921 metrics.bounds.x2);
cristye7f51092010-01-17 00:39:37 +00004922 FormatImageProperty(image,"msl:font-metrics.bounds.y2","%g",
cristy3ed852e2009-09-05 21:47:34 +00004923 metrics.bounds.y2);
cristye7f51092010-01-17 00:39:37 +00004924 FormatImageProperty(image,"msl:font-metrics.origin.x","%g",
cristy3ed852e2009-09-05 21:47:34 +00004925 metrics.origin.x);
cristye7f51092010-01-17 00:39:37 +00004926 FormatImageProperty(image,"msl:font-metrics.origin.y","%g",
cristy3ed852e2009-09-05 21:47:34 +00004927 metrics.origin.y);
4928 }
4929 draw_info=DestroyDrawInfo(draw_info);
4930 break;
4931 }
4932 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4933 }
4934 case 'R':
4935 case 'r':
4936 {
cristyb988fe72009-09-16 01:01:10 +00004937 if (LocaleCompare((const char *) tag,"raise") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004938 {
4939 MagickBooleanType
4940 raise;
4941
4942 /*
4943 Raise image.
4944 */
4945 if (msl_info->image[n] == (Image *) NULL)
4946 {
cristyb988fe72009-09-16 01:01:10 +00004947 ThrowMSLException(OptionError,"NoImagesDefined",
4948 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004949 break;
4950 }
4951 raise=MagickFalse;
4952 SetGeometry(msl_info->image[n],&geometry);
4953 if (attributes != (const xmlChar **) NULL)
4954 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4955 {
4956 keyword=(const char *) attributes[i++];
4957 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004958 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00004959 exception);
cristy3ed852e2009-09-05 21:47:34 +00004960 CloneString(&value,attribute);
4961 switch (*keyword)
4962 {
4963 case 'G':
4964 case 'g':
4965 {
4966 if (LocaleCompare(keyword,"geometry") == 0)
4967 {
4968 flags=ParsePageGeometry(msl_info->image[n],value,
dirk6d6d5f22014-06-20 11:48:54 +00004969 &geometry,exception);
cristy3ed852e2009-09-05 21:47:34 +00004970 if ((flags & HeightValue) == 0)
4971 geometry.height=geometry.width;
4972 break;
4973 }
4974 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4975 keyword);
4976 break;
4977 }
4978 case 'H':
4979 case 'h':
4980 {
4981 if (LocaleCompare(keyword,"height") == 0)
4982 {
cristyf2f27272009-12-17 14:48:46 +00004983 geometry.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004984 break;
4985 }
4986 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4987 keyword);
4988 break;
4989 }
4990 case 'R':
4991 case 'r':
4992 {
4993 if (LocaleCompare(keyword,"raise") == 0)
4994 {
cristy042ee782011-04-22 18:48:30 +00004995 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004996 value);
4997 if (option < 0)
4998 ThrowMSLException(OptionError,"UnrecognizedNoiseType",
4999 value);
5000 raise=(MagickBooleanType) option;
5001 break;
5002 }
5003 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5004 keyword);
5005 break;
5006 }
5007 case 'W':
5008 case 'w':
5009 {
5010 if (LocaleCompare(keyword,"width") == 0)
5011 {
cristyf2f27272009-12-17 14:48:46 +00005012 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005013 break;
5014 }
5015 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5016 keyword);
5017 break;
5018 }
5019 default:
5020 {
5021 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5022 keyword);
5023 break;
5024 }
5025 }
5026 }
cristy6170ac32011-08-28 14:15:37 +00005027 (void) RaiseImage(msl_info->image[n],&geometry,raise,
cristyc82a27b2011-10-21 01:07:16 +00005028 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00005029 break;
5030 }
cristyb988fe72009-09-16 01:01:10 +00005031 if (LocaleCompare((const char *) tag,"read") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005032 {
5033 if (attributes == (const xmlChar **) NULL)
5034 break;
5035 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5036 {
5037 keyword=(const char *) attributes[i++];
5038 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
dirk6d6d5f22014-06-20 11:48:54 +00005039 msl_info->attributes[n],(const char *) attributes[i],exception));
cristy3ed852e2009-09-05 21:47:34 +00005040 switch (*keyword)
5041 {
5042 case 'F':
5043 case 'f':
5044 {
5045 if (LocaleCompare(keyword,"filename") == 0)
5046 {
5047 Image
5048 *image;
5049
5050 (void) CopyMagickString(msl_info->image_info[n]->filename,
cristy151b66d2015-04-15 10:50:31 +00005051 value,MagickPathExtent);
dirk6d6d5f22014-06-20 11:48:54 +00005052 image=ReadImage(msl_info->image_info[n],exception);
5053 CatchException(exception);
cristy3ed852e2009-09-05 21:47:34 +00005054 if (image == (Image *) NULL)
5055 continue;
5056 AppendImageToList(&msl_info->image[n],image);
5057 break;
5058 }
cristy4582cbb2009-09-23 00:35:43 +00005059 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00005060 break;
5061 }
5062 default:
5063 {
cristy4582cbb2009-09-23 00:35:43 +00005064 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00005065 break;
5066 }
5067 }
5068 }
5069 break;
5070 }
cristyb988fe72009-09-16 01:01:10 +00005071 if (LocaleCompare((const char *) tag,"reduce-noise") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005072 {
5073 Image
5074 *paint_image;
5075
5076 /*
5077 Reduce-noise image.
5078 */
5079 if (msl_info->image[n] == (Image *) NULL)
5080 {
cristyb988fe72009-09-16 01:01:10 +00005081 ThrowMSLException(OptionError,"NoImagesDefined",
5082 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005083 break;
5084 }
5085 if (attributes != (const xmlChar **) NULL)
5086 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5087 {
5088 keyword=(const char *) attributes[i++];
5089 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005090 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00005091 exception);
cristy3ed852e2009-09-05 21:47:34 +00005092 CloneString(&value,attribute);
5093 switch (*keyword)
5094 {
5095 case 'G':
5096 case 'g':
5097 {
5098 if (LocaleCompare(keyword,"geometry") == 0)
5099 {
5100 flags=ParseGeometry(value,&geometry_info);
5101 if ((flags & SigmaValue) == 0)
5102 geometry_info.sigma=1.0;
5103 break;
5104 }
5105 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5106 keyword);
5107 break;
5108 }
5109 case 'R':
5110 case 'r':
5111 {
5112 if (LocaleCompare(keyword,"radius") == 0)
5113 {
cristydbdd0e32011-11-04 23:29:40 +00005114 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00005115 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005116 break;
5117 }
5118 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5119 keyword);
5120 break;
5121 }
5122 default:
5123 {
5124 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5125 keyword);
5126 break;
5127 }
5128 }
5129 }
cristy733678d2011-03-18 21:29:28 +00005130 paint_image=StatisticImage(msl_info->image[n],NonpeakStatistic,
cristy95c38342011-03-18 22:39:51 +00005131 (size_t) geometry_info.rho,(size_t) geometry_info.sigma,
cristyc82a27b2011-10-21 01:07:16 +00005132 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00005133 if (paint_image == (Image *) NULL)
5134 break;
5135 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5136 msl_info->image[n]=paint_image;
5137 break;
5138 }
cristyb988fe72009-09-16 01:01:10 +00005139 else if (LocaleCompare((const char *) tag,"repage") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005140 {
5141 /* init the values */
5142 width=msl_info->image[n]->page.width;
5143 height=msl_info->image[n]->page.height;
5144 x=msl_info->image[n]->page.x;
5145 y=msl_info->image[n]->page.y;
5146
5147 if (msl_info->image[n] == (Image *) NULL)
5148 {
cristyb988fe72009-09-16 01:01:10 +00005149 ThrowMSLException(OptionError,"NoImagesDefined",
5150 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005151 break;
5152 }
5153 if (attributes == (const xmlChar **) NULL)
5154 break;
5155 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5156 {
5157 keyword=(const char *) attributes[i++];
5158 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
dirk6d6d5f22014-06-20 11:48:54 +00005159 msl_info->attributes[n],(const char *) attributes[i],exception));
cristy3ed852e2009-09-05 21:47:34 +00005160 switch (*keyword)
5161 {
5162 case 'G':
5163 case 'g':
5164 {
5165 if (LocaleCompare(keyword,"geometry") == 0)
5166 {
5167 int
5168 flags;
5169
5170 RectangleInfo
5171 geometry;
5172
5173 flags=ParseAbsoluteGeometry(value,&geometry);
5174 if ((flags & WidthValue) != 0)
5175 {
5176 if ((flags & HeightValue) == 0)
5177 geometry.height=geometry.width;
5178 width=geometry.width;
5179 height=geometry.height;
5180 }
5181 if ((flags & AspectValue) != 0)
5182 {
5183 if ((flags & XValue) != 0)
5184 x+=geometry.x;
5185 if ((flags & YValue) != 0)
5186 y+=geometry.y;
5187 }
5188 else
5189 {
5190 if ((flags & XValue) != 0)
5191 {
5192 x=geometry.x;
5193 if ((width == 0) && (geometry.x > 0))
5194 width=msl_info->image[n]->columns+geometry.x;
5195 }
5196 if ((flags & YValue) != 0)
5197 {
5198 y=geometry.y;
5199 if ((height == 0) && (geometry.y > 0))
5200 height=msl_info->image[n]->rows+geometry.y;
5201 }
5202 }
5203 break;
5204 }
5205 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5206 break;
5207 }
5208 case 'H':
5209 case 'h':
5210 {
5211 if (LocaleCompare(keyword,"height") == 0)
5212 {
cristyf2f27272009-12-17 14:48:46 +00005213 height = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005214 break;
5215 }
5216 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5217 break;
5218 }
5219 case 'W':
5220 case 'w':
5221 {
5222 if (LocaleCompare(keyword,"width") == 0)
5223 {
cristyf2f27272009-12-17 14:48:46 +00005224 width = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005225 break;
5226 }
5227 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5228 break;
5229 }
5230 case 'X':
5231 case 'x':
5232 {
5233 if (LocaleCompare(keyword,"x") == 0)
5234 {
cristyf2f27272009-12-17 14:48:46 +00005235 x = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005236 break;
5237 }
5238 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5239 break;
5240 }
5241 case 'Y':
5242 case 'y':
5243 {
5244 if (LocaleCompare(keyword,"y") == 0)
5245 {
cristyf2f27272009-12-17 14:48:46 +00005246 y = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005247 break;
5248 }
5249 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5250 break;
5251 }
5252 default:
5253 {
5254 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5255 break;
5256 }
5257 }
5258 }
5259
cristyb988fe72009-09-16 01:01:10 +00005260 msl_info->image[n]->page.width=width;
5261 msl_info->image[n]->page.height=height;
5262 msl_info->image[n]->page.x=x;
5263 msl_info->image[n]->page.y=y;
cristy3ed852e2009-09-05 21:47:34 +00005264 break;
5265 }
cristyb988fe72009-09-16 01:01:10 +00005266 else if (LocaleCompare((const char *) tag,"resample") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005267 {
5268 double
5269 x_resolution,
5270 y_resolution;
5271
5272 if (msl_info->image[n] == (Image *) NULL)
5273 {
cristyb988fe72009-09-16 01:01:10 +00005274 ThrowMSLException(OptionError,"NoImagesDefined",
5275 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005276 break;
5277 }
5278 if (attributes == (const xmlChar **) NULL)
5279 break;
5280 x_resolution=DefaultResolution;
5281 y_resolution=DefaultResolution;
5282 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5283 {
5284 keyword=(const char *) attributes[i++];
5285 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
dirk6d6d5f22014-06-20 11:48:54 +00005286 msl_info->attributes[n],(const char *) attributes[i],exception));
cristy3ed852e2009-09-05 21:47:34 +00005287 switch (*keyword)
5288 {
cristy3ed852e2009-09-05 21:47:34 +00005289 case 'G':
5290 case 'g':
5291 {
5292 if (LocaleCompare(keyword,"geometry") == 0)
5293 {
cristybb503372010-05-27 20:51:26 +00005294 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00005295 flags;
5296
5297 flags=ParseGeometry(value,&geometry_info);
5298 if ((flags & SigmaValue) == 0)
5299 geometry_info.sigma*=geometry_info.rho;
5300 x_resolution=geometry_info.rho;
5301 y_resolution=geometry_info.sigma;
5302 break;
5303 }
5304 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5305 break;
5306 }
5307 case 'X':
5308 case 'x':
5309 {
5310 if (LocaleCompare(keyword,"x-resolution") == 0)
5311 {
cristydbdd0e32011-11-04 23:29:40 +00005312 x_resolution=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005313 break;
5314 }
5315 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5316 break;
5317 }
5318 case 'Y':
5319 case 'y':
5320 {
5321 if (LocaleCompare(keyword,"y-resolution") == 0)
5322 {
cristydbdd0e32011-11-04 23:29:40 +00005323 y_resolution=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005324 break;
5325 }
5326 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5327 break;
5328 }
5329 default:
5330 {
5331 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5332 break;
5333 }
5334 }
5335 }
5336 /*
5337 Resample image.
5338 */
5339 {
5340 double
5341 factor;
5342
5343 Image
5344 *resample_image;
5345
5346 factor=1.0;
5347 if (msl_info->image[n]->units == PixelsPerCentimeterResolution)
5348 factor=2.54;
cristybb503372010-05-27 20:51:26 +00005349 width=(size_t) (x_resolution*msl_info->image[n]->columns/
cristy2a11bef2011-10-28 18:33:11 +00005350 (factor*(msl_info->image[n]->resolution.x == 0.0 ? DefaultResolution :
5351 msl_info->image[n]->resolution.x))+0.5);
cristybb503372010-05-27 20:51:26 +00005352 height=(size_t) (y_resolution*msl_info->image[n]->rows/
cristy2a11bef2011-10-28 18:33:11 +00005353 (factor*(msl_info->image[n]->resolution.y == 0.0 ? DefaultResolution :
5354 msl_info->image[n]->resolution.y))+0.5);
cristy3ed852e2009-09-05 21:47:34 +00005355 resample_image=ResizeImage(msl_info->image[n],width,height,
cristyaa2c16c2012-03-25 22:21:35 +00005356 msl_info->image[n]->filter,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00005357 if (resample_image == (Image *) NULL)
5358 break;
5359 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5360 msl_info->image[n]=resample_image;
5361 }
5362 break;
5363 }
cristyb988fe72009-09-16 01:01:10 +00005364 if (LocaleCompare((const char *) tag,"resize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005365 {
cristy3ed852e2009-09-05 21:47:34 +00005366 FilterTypes
5367 filter;
5368
5369 Image
5370 *resize_image;
5371
5372 /*
5373 Resize image.
5374 */
5375 if (msl_info->image[n] == (Image *) NULL)
5376 {
cristyb988fe72009-09-16 01:01:10 +00005377 ThrowMSLException(OptionError,"NoImagesDefined",
5378 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005379 break;
5380 }
5381 filter=UndefinedFilter;
cristy3ed852e2009-09-05 21:47:34 +00005382 if (attributes != (const xmlChar **) NULL)
5383 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5384 {
5385 keyword=(const char *) attributes[i++];
5386 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005387 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00005388 exception);
cristy3ed852e2009-09-05 21:47:34 +00005389 CloneString(&value,attribute);
5390 switch (*keyword)
5391 {
5392 case 'F':
5393 case 'f':
5394 {
5395 if (LocaleCompare(keyword,"filter") == 0)
5396 {
cristy042ee782011-04-22 18:48:30 +00005397 option=ParseCommandOption(MagickFilterOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00005398 value);
5399 if (option < 0)
5400 ThrowMSLException(OptionError,"UnrecognizedNoiseType",
5401 value);
5402 filter=(FilterTypes) option;
5403 break;
5404 }
5405 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5406 keyword);
5407 break;
5408 }
5409 case 'G':
5410 case 'g':
5411 {
5412 if (LocaleCompare(keyword,"geometry") == 0)
5413 {
5414 flags=ParseRegionGeometry(msl_info->image[n],value,
dirk6d6d5f22014-06-20 11:48:54 +00005415 &geometry,exception);
cristy3ed852e2009-09-05 21:47:34 +00005416 break;
5417 }
5418 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5419 keyword);
5420 break;
5421 }
5422 case 'H':
5423 case 'h':
5424 {
5425 if (LocaleCompare(keyword,"height") == 0)
5426 {
cristye27293e2009-12-18 02:53:20 +00005427 geometry.height=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005428 break;
5429 }
5430 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5431 keyword);
5432 break;
5433 }
cristy3ed852e2009-09-05 21:47:34 +00005434 case 'W':
5435 case 'w':
5436 {
5437 if (LocaleCompare(keyword,"width") == 0)
5438 {
cristyf2f27272009-12-17 14:48:46 +00005439 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005440 break;
5441 }
5442 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5443 keyword);
5444 break;
5445 }
5446 default:
5447 {
5448 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5449 keyword);
5450 break;
5451 }
5452 }
5453 }
5454 resize_image=ResizeImage(msl_info->image[n],geometry.width,
cristyaa2c16c2012-03-25 22:21:35 +00005455 geometry.height,filter,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00005456 if (resize_image == (Image *) NULL)
5457 break;
5458 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5459 msl_info->image[n]=resize_image;
5460 break;
5461 }
cristyb988fe72009-09-16 01:01:10 +00005462 if (LocaleCompare((const char *) tag,"roll") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005463 {
5464 Image
5465 *roll_image;
5466
5467 /*
5468 Roll image.
5469 */
5470 if (msl_info->image[n] == (Image *) NULL)
5471 {
cristyb988fe72009-09-16 01:01:10 +00005472 ThrowMSLException(OptionError,"NoImagesDefined",
5473 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005474 break;
5475 }
5476 SetGeometry(msl_info->image[n],&geometry);
5477 if (attributes != (const xmlChar **) NULL)
5478 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5479 {
5480 keyword=(const char *) attributes[i++];
5481 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005482 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00005483 exception);
cristy3ed852e2009-09-05 21:47:34 +00005484 CloneString(&value,attribute);
5485 switch (*keyword)
5486 {
5487 case 'G':
5488 case 'g':
5489 {
5490 if (LocaleCompare(keyword,"geometry") == 0)
5491 {
5492 flags=ParsePageGeometry(msl_info->image[n],value,
dirk6d6d5f22014-06-20 11:48:54 +00005493 &geometry,exception);
cristy3ed852e2009-09-05 21:47:34 +00005494 if ((flags & HeightValue) == 0)
5495 geometry.height=geometry.width;
5496 break;
5497 }
5498 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5499 keyword);
5500 break;
5501 }
5502 case 'X':
5503 case 'x':
5504 {
5505 if (LocaleCompare(keyword,"x") == 0)
5506 {
cristyf2f27272009-12-17 14:48:46 +00005507 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005508 break;
5509 }
5510 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5511 keyword);
5512 break;
5513 }
5514 case 'Y':
5515 case 'y':
5516 {
5517 if (LocaleCompare(keyword,"y") == 0)
5518 {
cristyf2f27272009-12-17 14:48:46 +00005519 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005520 break;
5521 }
5522 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5523 keyword);
5524 break;
5525 }
5526 default:
5527 {
5528 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5529 keyword);
5530 break;
5531 }
5532 }
5533 }
5534 roll_image=RollImage(msl_info->image[n],geometry.x,geometry.y,
cristyc82a27b2011-10-21 01:07:16 +00005535 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00005536 if (roll_image == (Image *) NULL)
5537 break;
5538 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5539 msl_info->image[n]=roll_image;
5540 break;
5541 }
cristyb988fe72009-09-16 01:01:10 +00005542 else if (LocaleCompare((const char *) tag,"roll") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005543 {
5544 /* init the values */
5545 width=msl_info->image[n]->columns;
5546 height=msl_info->image[n]->rows;
5547 x = y = 0;
5548
5549 if (msl_info->image[n] == (Image *) NULL)
5550 {
cristyb988fe72009-09-16 01:01:10 +00005551 ThrowMSLException(OptionError,"NoImagesDefined",
5552 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005553 break;
5554 }
5555 if (attributes == (const xmlChar **) NULL)
5556 break;
5557 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5558 {
5559 keyword=(const char *) attributes[i++];
5560 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
dirk6d6d5f22014-06-20 11:48:54 +00005561 msl_info->attributes[n],(const char *) attributes[i],exception));
cristy3ed852e2009-09-05 21:47:34 +00005562 switch (*keyword)
5563 {
5564 case 'G':
5565 case 'g':
5566 {
5567 if (LocaleCompare(keyword,"geometry") == 0)
5568 {
5569 (void) ParseMetaGeometry(value,&x,&y,&width,&height);
5570 break;
5571 }
5572 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5573 break;
5574 }
5575 case 'X':
5576 case 'x':
5577 {
5578 if (LocaleCompare(keyword,"x") == 0)
5579 {
cristyf2f27272009-12-17 14:48:46 +00005580 x = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005581 break;
5582 }
5583 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5584 break;
5585 }
5586 case 'Y':
5587 case 'y':
5588 {
5589 if (LocaleCompare(keyword,"y") == 0)
5590 {
cristyf2f27272009-12-17 14:48:46 +00005591 y = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005592 break;
5593 }
5594 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5595 break;
5596 }
5597 default:
5598 {
5599 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5600 break;
5601 }
5602 }
5603 }
5604
5605 /*
5606 process image.
5607 */
5608 {
5609 Image
5610 *newImage;
5611
cristyc82a27b2011-10-21 01:07:16 +00005612 newImage=RollImage(msl_info->image[n], x, y, msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00005613 if (newImage == (Image *) NULL)
5614 break;
5615 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5616 msl_info->image[n]=newImage;
5617 }
5618
5619 break;
5620 }
cristyb988fe72009-09-16 01:01:10 +00005621 if (LocaleCompare((const char *) tag,"rotate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005622 {
5623 Image
5624 *rotate_image;
5625
5626 /*
5627 Rotate image.
5628 */
5629 if (msl_info->image[n] == (Image *) NULL)
5630 {
cristyb988fe72009-09-16 01:01:10 +00005631 ThrowMSLException(OptionError,"NoImagesDefined",
5632 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005633 break;
5634 }
5635 if (attributes != (const xmlChar **) NULL)
5636 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5637 {
5638 keyword=(const char *) attributes[i++];
5639 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005640 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00005641 exception);
cristy3ed852e2009-09-05 21:47:34 +00005642 CloneString(&value,attribute);
5643 switch (*keyword)
5644 {
5645 case 'D':
5646 case 'd':
5647 {
5648 if (LocaleCompare(keyword,"degrees") == 0)
5649 {
cristydbdd0e32011-11-04 23:29:40 +00005650 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00005651 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005652 break;
5653 }
5654 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5655 keyword);
5656 break;
5657 }
5658 case 'G':
5659 case 'g':
5660 {
5661 if (LocaleCompare(keyword,"geometry") == 0)
5662 {
5663 flags=ParseGeometry(value,&geometry_info);
5664 if ((flags & SigmaValue) == 0)
5665 geometry_info.sigma=1.0;
5666 break;
5667 }
5668 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5669 keyword);
5670 break;
5671 }
5672 default:
5673 {
5674 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5675 keyword);
5676 break;
5677 }
5678 }
5679 }
5680 rotate_image=RotateImage(msl_info->image[n],geometry_info.rho,
cristyc82a27b2011-10-21 01:07:16 +00005681 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00005682 if (rotate_image == (Image *) NULL)
5683 break;
5684 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5685 msl_info->image[n]=rotate_image;
5686 break;
5687 }
cristyb988fe72009-09-16 01:01:10 +00005688 else if (LocaleCompare((const char *) tag,"rotate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005689 {
5690 /* init the values */
5691 double degrees = 0;
5692
5693 if (msl_info->image[n] == (Image *) NULL)
5694 {
cristyb988fe72009-09-16 01:01:10 +00005695 ThrowMSLException(OptionError,"NoImagesDefined",
5696 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005697 break;
5698 }
5699 if (attributes == (const xmlChar **) NULL)
cristy31939262009-09-15 00:23:11 +00005700 break;
cristy3ed852e2009-09-05 21:47:34 +00005701 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5702 {
5703 keyword=(const char *) attributes[i++];
5704 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
dirk6d6d5f22014-06-20 11:48:54 +00005705 msl_info->attributes[n],(const char *) attributes[i],exception));
cristy3ed852e2009-09-05 21:47:34 +00005706 switch (*keyword)
5707 {
5708 case 'D':
5709 case 'd':
5710 {
5711 if (LocaleCompare(keyword,"degrees") == 0)
5712 {
cristydbdd0e32011-11-04 23:29:40 +00005713 degrees = StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005714 break;
5715 }
5716 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5717 break;
5718 }
5719 default:
5720 {
5721 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5722 break;
5723 }
5724 }
5725 }
5726
5727 /*
5728 process image.
5729 */
5730 {
5731 Image
5732 *newImage;
5733
cristyc82a27b2011-10-21 01:07:16 +00005734 newImage=RotateImage(msl_info->image[n], degrees, msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00005735 if (newImage == (Image *) NULL)
5736 break;
5737 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5738 msl_info->image[n]=newImage;
5739 }
5740
5741 break;
5742 }
5743 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
5744 }
5745 case 'S':
5746 case 's':
5747 {
cristyb988fe72009-09-16 01:01:10 +00005748 if (LocaleCompare((const char *) tag,"sample") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005749 {
5750 Image
5751 *sample_image;
5752
5753 /*
5754 Sample image.
5755 */
5756 if (msl_info->image[n] == (Image *) NULL)
5757 {
cristyb988fe72009-09-16 01:01:10 +00005758 ThrowMSLException(OptionError,"NoImagesDefined",
5759 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005760 break;
5761 }
5762 if (attributes != (const xmlChar **) NULL)
5763 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5764 {
5765 keyword=(const char *) attributes[i++];
5766 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005767 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00005768 exception);
cristy3ed852e2009-09-05 21:47:34 +00005769 CloneString(&value,attribute);
5770 switch (*keyword)
5771 {
5772 case 'G':
5773 case 'g':
5774 {
5775 if (LocaleCompare(keyword,"geometry") == 0)
5776 {
5777 flags=ParseRegionGeometry(msl_info->image[n],value,
dirk6d6d5f22014-06-20 11:48:54 +00005778 &geometry,exception);
cristy3ed852e2009-09-05 21:47:34 +00005779 break;
5780 }
5781 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5782 keyword);
5783 break;
5784 }
5785 case 'H':
5786 case 'h':
5787 {
5788 if (LocaleCompare(keyword,"height") == 0)
5789 {
cristye27293e2009-12-18 02:53:20 +00005790 geometry.height=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005791 break;
5792 }
5793 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5794 keyword);
5795 break;
5796 }
5797 case 'W':
5798 case 'w':
5799 {
5800 if (LocaleCompare(keyword,"width") == 0)
5801 {
cristyf2f27272009-12-17 14:48:46 +00005802 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005803 break;
5804 }
5805 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5806 keyword);
5807 break;
5808 }
5809 default:
5810 {
5811 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5812 keyword);
5813 break;
5814 }
5815 }
5816 }
5817 sample_image=SampleImage(msl_info->image[n],geometry.width,
cristyc82a27b2011-10-21 01:07:16 +00005818 geometry.height,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00005819 if (sample_image == (Image *) NULL)
5820 break;
5821 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5822 msl_info->image[n]=sample_image;
5823 break;
5824 }
cristyb988fe72009-09-16 01:01:10 +00005825 if (LocaleCompare((const char *) tag,"scale") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005826 {
5827 Image
5828 *scale_image;
5829
5830 /*
5831 Scale image.
5832 */
5833 if (msl_info->image[n] == (Image *) NULL)
5834 {
cristyb988fe72009-09-16 01:01:10 +00005835 ThrowMSLException(OptionError,"NoImagesDefined",
5836 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005837 break;
5838 }
5839 if (attributes != (const xmlChar **) NULL)
5840 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5841 {
5842 keyword=(const char *) attributes[i++];
5843 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005844 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00005845 exception);
cristy3ed852e2009-09-05 21:47:34 +00005846 CloneString(&value,attribute);
5847 switch (*keyword)
5848 {
5849 case 'G':
5850 case 'g':
5851 {
5852 if (LocaleCompare(keyword,"geometry") == 0)
5853 {
5854 flags=ParseRegionGeometry(msl_info->image[n],value,
dirk6d6d5f22014-06-20 11:48:54 +00005855 &geometry,exception);
cristy3ed852e2009-09-05 21:47:34 +00005856 break;
5857 }
5858 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5859 keyword);
5860 break;
5861 }
5862 case 'H':
5863 case 'h':
5864 {
5865 if (LocaleCompare(keyword,"height") == 0)
5866 {
cristye27293e2009-12-18 02:53:20 +00005867 geometry.height=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005868 break;
5869 }
5870 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5871 keyword);
5872 break;
5873 }
5874 case 'W':
5875 case 'w':
5876 {
5877 if (LocaleCompare(keyword,"width") == 0)
5878 {
cristyf2f27272009-12-17 14:48:46 +00005879 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005880 break;
5881 }
5882 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5883 keyword);
5884 break;
5885 }
5886 default:
5887 {
5888 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5889 keyword);
5890 break;
5891 }
5892 }
5893 }
5894 scale_image=ScaleImage(msl_info->image[n],geometry.width,
cristyc82a27b2011-10-21 01:07:16 +00005895 geometry.height,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00005896 if (scale_image == (Image *) NULL)
5897 break;
5898 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5899 msl_info->image[n]=scale_image;
5900 break;
5901 }
cristyb988fe72009-09-16 01:01:10 +00005902 if (LocaleCompare((const char *) tag,"segment") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005903 {
5904 ColorspaceType
5905 colorspace;
5906
5907 MagickBooleanType
5908 verbose;
cristyb988fe72009-09-16 01:01:10 +00005909
cristy3ed852e2009-09-05 21:47:34 +00005910 /*
5911 Segment image.
5912 */
5913 if (msl_info->image[n] == (Image *) NULL)
5914 {
cristyb988fe72009-09-16 01:01:10 +00005915 ThrowMSLException(OptionError,"NoImagesDefined",
5916 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005917 break;
5918 }
5919 geometry_info.rho=1.0;
5920 geometry_info.sigma=1.5;
cristy7020ae62012-04-18 12:58:34 +00005921 colorspace=sRGBColorspace;
cristy3ed852e2009-09-05 21:47:34 +00005922 verbose=MagickFalse;
5923 if (attributes != (const xmlChar **) NULL)
5924 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5925 {
5926 keyword=(const char *) attributes[i++];
5927 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005928 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00005929 exception);
cristy3ed852e2009-09-05 21:47:34 +00005930 CloneString(&value,attribute);
5931 switch (*keyword)
5932 {
5933 case 'C':
5934 case 'c':
5935 {
5936 if (LocaleCompare(keyword,"cluster-threshold") == 0)
5937 {
cristydbdd0e32011-11-04 23:29:40 +00005938 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00005939 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005940 break;
5941 }
5942 if (LocaleCompare(keyword,"colorspace") == 0)
5943 {
cristy042ee782011-04-22 18:48:30 +00005944 option=ParseCommandOption(MagickColorspaceOptions,
cristy3ed852e2009-09-05 21:47:34 +00005945 MagickFalse,value);
5946 if (option < 0)
5947 ThrowMSLException(OptionError,
5948 "UnrecognizedColorspaceType",value);
5949 colorspace=(ColorspaceType) option;
5950 break;
5951 }
5952 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5953 keyword);
5954 break;
5955 }
5956 case 'G':
5957 case 'g':
5958 {
5959 if (LocaleCompare(keyword,"geometry") == 0)
5960 {
5961 flags=ParseGeometry(value,&geometry_info);
5962 if ((flags & SigmaValue) == 0)
5963 geometry_info.sigma=1.5;
5964 break;
5965 }
5966 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5967 keyword);
5968 break;
5969 }
5970 case 'S':
5971 case 's':
5972 {
5973 if (LocaleCompare(keyword,"smoothing-threshold") == 0)
5974 {
cristydbdd0e32011-11-04 23:29:40 +00005975 geometry_info.sigma=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00005976 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005977 break;
5978 }
5979 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5980 keyword);
5981 break;
5982 }
5983 default:
5984 {
5985 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5986 keyword);
5987 break;
5988 }
5989 }
5990 }
5991 (void) SegmentImage(msl_info->image[n],colorspace,verbose,
dirk6d6d5f22014-06-20 11:48:54 +00005992 geometry_info.rho,geometry_info.sigma,exception);
cristy3ed852e2009-09-05 21:47:34 +00005993 break;
5994 }
cristyb988fe72009-09-16 01:01:10 +00005995 else if (LocaleCompare((const char *) tag, "set") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005996 {
5997 if (msl_info->image[n] == (Image *) NULL)
5998 {
cristy0b6d0052011-07-27 23:54:16 +00005999 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006000 break;
6001 }
6002
6003 if (attributes == (const xmlChar **) NULL)
6004 break;
6005 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6006 {
6007 keyword=(const char *) attributes[i++];
6008 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
dirk6d6d5f22014-06-20 11:48:54 +00006009 msl_info->attributes[n],(const char *) attributes[i],exception));
cristy3ed852e2009-09-05 21:47:34 +00006010 switch (*keyword)
6011 {
cristy3ed852e2009-09-05 21:47:34 +00006012 case 'C':
6013 case 'c':
6014 {
6015 if (LocaleCompare(keyword,"clip-mask") == 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",
dirk6d6d5f22014-06-20 11:48:54 +00006023 exception);
cristy2c8b6312009-09-16 02:37:23 +00006024 if (LocaleCompare(property,value) == 0)
6025 {
cristyacd0d4c2015-07-25 16:12:33 +00006026 SetImageMask(msl_info->image[n],ReadPixelMask,
6027 msl_info->image[j],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 }
cristy3ed852e2009-09-05 21:47:34 +00006033 if (LocaleCompare(keyword,"clip-path") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006034 {
cristy2c8b6312009-09-16 02:37:23 +00006035 for (j=0; j < msl_info->n; j++)
cristy3ed852e2009-09-05 21:47:34 +00006036 {
cristy2c8b6312009-09-16 02:37:23 +00006037 const char
6038 *property;
6039
cristyd15e6592011-10-15 00:13:06 +00006040 property=GetImageProperty(msl_info->attributes[j],"id",
dirk6d6d5f22014-06-20 11:48:54 +00006041 exception);
cristy2c8b6312009-09-16 02:37:23 +00006042 if (LocaleCompare(property,value) == 0)
6043 {
cristyacd0d4c2015-07-25 16:12:33 +00006044 SetImageMask(msl_info->image[n],ReadPixelMask,
6045 msl_info->image[j],exception);
cristy2c8b6312009-09-16 02:37:23 +00006046 break;
6047 }
cristy3ed852e2009-09-05 21:47:34 +00006048 }
cristy2c8b6312009-09-16 02:37:23 +00006049 break;
cristy3ed852e2009-09-05 21:47:34 +00006050 }
cristy2c8b6312009-09-16 02:37:23 +00006051 if (LocaleCompare(keyword,"colorspace") == 0)
6052 {
cristybb503372010-05-27 20:51:26 +00006053 ssize_t
cristy2c8b6312009-09-16 02:37:23 +00006054 colorspace;
6055
cristy042ee782011-04-22 18:48:30 +00006056 colorspace=(ColorspaceType) ParseCommandOption(
cristy7e9e6fa2010-11-21 17:06:24 +00006057 MagickColorspaceOptions,MagickFalse,value);
cristy2c8b6312009-09-16 02:37:23 +00006058 if (colorspace < 0)
cristyfb758a52009-09-16 14:36:08 +00006059 ThrowMSLException(OptionError,"UnrecognizedColorspace",
cristy2c8b6312009-09-16 02:37:23 +00006060 value);
6061 (void) TransformImageColorspace(msl_info->image[n],
dirk6d6d5f22014-06-20 11:48:54 +00006062 (ColorspaceType) colorspace,exception);
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,
dirk6d6d5f22014-06-20 11:48:54 +00006067 exception);
cristy3ed852e2009-09-05 21:47:34 +00006068 break;
6069 }
6070 case 'D':
6071 case 'd':
6072 {
cristy2c8b6312009-09-16 02:37:23 +00006073 if (LocaleCompare(keyword,"density") == 0)
6074 {
6075 flags=ParseGeometry(value,&geometry_info);
cristy2a11bef2011-10-28 18:33:11 +00006076 msl_info->image[n]->resolution.x=geometry_info.rho;
6077 msl_info->image[n]->resolution.y=geometry_info.sigma;
cristy2c8b6312009-09-16 02:37:23 +00006078 if ((flags & SigmaValue) == 0)
cristy2a11bef2011-10-28 18:33:11 +00006079 msl_info->image[n]->resolution.y=
6080 msl_info->image[n]->resolution.x;
cristy2c8b6312009-09-16 02:37:23 +00006081 break;
6082 }
6083 (void) SetMSLAttributes(msl_info,keyword,value);
cristyd15e6592011-10-15 00:13:06 +00006084 (void) SetImageProperty(msl_info->image[n],keyword,value,
dirk6d6d5f22014-06-20 11:48:54 +00006085 exception);
cristy3ed852e2009-09-05 21:47:34 +00006086 break;
6087 }
6088 case 'O':
6089 case 'o':
6090 {
6091 if (LocaleCompare(keyword, "opacity") == 0)
cristy2c8b6312009-09-16 02:37:23 +00006092 {
cristy4c08aed2011-07-01 19:47:50 +00006093 ssize_t opac = OpaqueAlpha,
cristybb503372010-05-27 20:51:26 +00006094 len = (ssize_t) strlen( value );
cristy3ed852e2009-09-05 21:47:34 +00006095
cristy2c8b6312009-09-16 02:37:23 +00006096 if (value[len-1] == '%') {
6097 char tmp[100];
6098 (void) CopyMagickString(tmp,value,len);
cristyf2f27272009-12-17 14:48:46 +00006099 opac = StringToLong( tmp );
cristy2c8b6312009-09-16 02:37:23 +00006100 opac = (int)(QuantumRange * ((float)opac/100));
6101 } else
cristyf2f27272009-12-17 14:48:46 +00006102 opac = StringToLong( value );
cristye941a752011-10-15 01:52:48 +00006103 (void) SetImageAlpha( msl_info->image[n], (Quantum) opac,
dirk6d6d5f22014-06-20 11:48:54 +00006104 exception);
cristy2c8b6312009-09-16 02:37:23 +00006105 break;
cristy3ed852e2009-09-05 21:47:34 +00006106 }
cristy2c8b6312009-09-16 02:37:23 +00006107 (void) SetMSLAttributes(msl_info,keyword,value);
cristyd15e6592011-10-15 00:13:06 +00006108 (void) SetImageProperty(msl_info->image[n],keyword,value,
6109 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00006110 break;
6111 }
6112 case 'P':
6113 case 'p':
6114 {
6115 if (LocaleCompare(keyword, "page") == 0)
6116 {
6117 char
cristy151b66d2015-04-15 10:50:31 +00006118 page[MagickPathExtent];
cristy3ed852e2009-09-05 21:47:34 +00006119
6120 const char
6121 *image_option;
6122
6123 MagickStatusType
6124 flags;
6125
6126 RectangleInfo
6127 geometry;
6128
6129 (void) ResetMagickMemory(&geometry,0,sizeof(geometry));
cristy8b206ba2013-04-05 01:11:15 +00006130 image_option=GetImageArtifact(msl_info->image[n],"page");
cristy3ed852e2009-09-05 21:47:34 +00006131 if (image_option != (const char *) NULL)
6132 flags=ParseAbsoluteGeometry(image_option,&geometry);
6133 flags=ParseAbsoluteGeometry(value,&geometry);
cristy151b66d2015-04-15 10:50:31 +00006134 (void) FormatLocaleString(page,MagickPathExtent,"%.20gx%.20g",
cristye8c25f92010-06-03 00:53:06 +00006135 (double) geometry.width,(double) geometry.height);
cristy3ed852e2009-09-05 21:47:34 +00006136 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
cristy151b66d2015-04-15 10:50:31 +00006137 (void) FormatLocaleString(page,MagickPathExtent,
cristye8c25f92010-06-03 00:53:06 +00006138 "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,
6139 (double) geometry.height,(double) geometry.x,(double)
cristyf2faecf2010-05-28 19:19:36 +00006140 geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00006141 (void) SetImageOption(msl_info->image_info[n],keyword,page);
6142 msl_info->image_info[n]->page=GetPageGeometry(page);
6143 break;
6144 }
cristy2c8b6312009-09-16 02:37:23 +00006145 (void) SetMSLAttributes(msl_info,keyword,value);
cristyd15e6592011-10-15 00:13:06 +00006146 (void) SetImageProperty(msl_info->image[n],keyword,value,
6147 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00006148 break;
6149 }
6150 default:
6151 {
cristy2c8b6312009-09-16 02:37:23 +00006152 (void) SetMSLAttributes(msl_info,keyword,value);
cristyd15e6592011-10-15 00:13:06 +00006153 (void) SetImageProperty(msl_info->image[n],keyword,value,
6154 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00006155 break;
6156 }
6157 }
6158 }
6159 break;
6160 }
cristyb988fe72009-09-16 01:01:10 +00006161 if (LocaleCompare((const char *) tag,"shade") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006162 {
6163 Image
6164 *shade_image;
6165
6166 MagickBooleanType
6167 gray;
6168
6169 /*
6170 Shade image.
6171 */
6172 if (msl_info->image[n] == (Image *) NULL)
6173 {
cristyb988fe72009-09-16 01:01:10 +00006174 ThrowMSLException(OptionError,"NoImagesDefined",
6175 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006176 break;
6177 }
6178 gray=MagickFalse;
6179 if (attributes != (const xmlChar **) NULL)
6180 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6181 {
6182 keyword=(const char *) attributes[i++];
6183 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006184 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00006185 exception);
cristy3ed852e2009-09-05 21:47:34 +00006186 CloneString(&value,attribute);
6187 switch (*keyword)
6188 {
6189 case 'A':
6190 case 'a':
6191 {
6192 if (LocaleCompare(keyword,"azimuth") == 0)
6193 {
cristydbdd0e32011-11-04 23:29:40 +00006194 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00006195 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006196 break;
6197 }
6198 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6199 keyword);
6200 break;
6201 }
6202 case 'E':
6203 case 'e':
6204 {
6205 if (LocaleCompare(keyword,"elevation") == 0)
6206 {
cristydbdd0e32011-11-04 23:29:40 +00006207 geometry_info.sigma=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00006208 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006209 break;
6210 }
6211 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6212 keyword);
6213 break;
6214 }
6215 case 'G':
6216 case 'g':
6217 {
6218 if (LocaleCompare(keyword,"geometry") == 0)
6219 {
6220 flags=ParseGeometry(value,&geometry_info);
6221 if ((flags & SigmaValue) == 0)
6222 geometry_info.sigma=1.0;
6223 break;
6224 }
6225 if (LocaleCompare(keyword,"gray") == 0)
6226 {
cristy042ee782011-04-22 18:48:30 +00006227 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00006228 value);
6229 if (option < 0)
6230 ThrowMSLException(OptionError,"UnrecognizedNoiseType",
6231 value);
6232 gray=(MagickBooleanType) option;
6233 break;
6234 }
6235 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6236 keyword);
6237 break;
6238 }
6239 default:
6240 {
6241 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6242 keyword);
6243 break;
6244 }
6245 }
6246 }
6247 shade_image=ShadeImage(msl_info->image[n],gray,geometry_info.rho,
cristyc82a27b2011-10-21 01:07:16 +00006248 geometry_info.sigma,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00006249 if (shade_image == (Image *) NULL)
6250 break;
6251 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6252 msl_info->image[n]=shade_image;
6253 break;
6254 }
cristyb988fe72009-09-16 01:01:10 +00006255 if (LocaleCompare((const char *) tag,"shadow") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006256 {
6257 Image
6258 *shadow_image;
6259
6260 /*
6261 Shear image.
6262 */
6263 if (msl_info->image[n] == (Image *) NULL)
6264 {
cristyb988fe72009-09-16 01:01:10 +00006265 ThrowMSLException(OptionError,"NoImagesDefined",
6266 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006267 break;
6268 }
6269 if (attributes != (const xmlChar **) NULL)
6270 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6271 {
6272 keyword=(const char *) attributes[i++];
6273 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006274 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00006275 exception);
cristy3ed852e2009-09-05 21:47:34 +00006276 CloneString(&value,attribute);
6277 switch (*keyword)
6278 {
6279 case 'G':
6280 case 'g':
6281 {
6282 if (LocaleCompare(keyword,"geometry") == 0)
6283 {
6284 flags=ParseGeometry(value,&geometry_info);
6285 if ((flags & SigmaValue) == 0)
6286 geometry_info.sigma=1.0;
6287 break;
6288 }
6289 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6290 keyword);
6291 break;
6292 }
6293 case 'O':
6294 case 'o':
6295 {
6296 if (LocaleCompare(keyword,"opacity") == 0)
6297 {
cristyf2f27272009-12-17 14:48:46 +00006298 geometry_info.rho=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006299 break;
6300 }
6301 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6302 keyword);
6303 break;
6304 }
6305 case 'S':
6306 case 's':
6307 {
6308 if (LocaleCompare(keyword,"sigma") == 0)
6309 {
cristyf2f27272009-12-17 14:48:46 +00006310 geometry_info.sigma=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006311 break;
6312 }
6313 break;
6314 }
6315 case 'X':
6316 case 'x':
6317 {
6318 if (LocaleCompare(keyword,"x") == 0)
6319 {
cristydbdd0e32011-11-04 23:29:40 +00006320 geometry_info.xi=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00006321 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006322 break;
6323 }
6324 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6325 keyword);
6326 break;
6327 }
6328 case 'Y':
6329 case 'y':
6330 {
6331 if (LocaleCompare(keyword,"y") == 0)
6332 {
cristyf2f27272009-12-17 14:48:46 +00006333 geometry_info.psi=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006334 break;
6335 }
6336 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6337 keyword);
6338 break;
6339 }
6340 default:
6341 {
6342 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6343 keyword);
6344 break;
6345 }
6346 }
6347 }
6348 shadow_image=ShadowImage(msl_info->image[n],geometry_info.rho,
cristyaa2c16c2012-03-25 22:21:35 +00006349 geometry_info.sigma,(ssize_t) ceil(geometry_info.xi-0.5),
cristyeb6e6582011-12-09 09:14:23 +00006350 (ssize_t) ceil(geometry_info.psi-0.5),msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00006351 if (shadow_image == (Image *) NULL)
6352 break;
6353 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6354 msl_info->image[n]=shadow_image;
6355 break;
6356 }
cristyb988fe72009-09-16 01:01:10 +00006357 if (LocaleCompare((const char *) tag,"sharpen") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006358 {
cristyaa2c16c2012-03-25 22:21:35 +00006359 double
cristy05c0c9a2011-09-05 23:16:13 +00006360 radius = 0.0,
cristy3ed852e2009-09-05 21:47:34 +00006361 sigma = 1.0;
6362
6363 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00006364 {
6365 ThrowMSLException(OptionError,"NoImagesDefined",
6366 (const char *) tag);
6367 break;
6368 }
cristy3ed852e2009-09-05 21:47:34 +00006369 /*
6370 NOTE: sharpen can have no attributes, since we use all the defaults!
6371 */
6372 if (attributes != (const xmlChar **) NULL)
6373 {
6374 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6375 {
6376 keyword=(const char *) attributes[i++];
6377 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
dirk6d6d5f22014-06-20 11:48:54 +00006378 msl_info->attributes[n],(const char *) attributes[i],exception));
cristy3ed852e2009-09-05 21:47:34 +00006379 switch (*keyword)
6380 {
6381 case 'R':
6382 case 'r':
6383 {
6384 if (LocaleCompare(keyword, "radius") == 0)
6385 {
cristydbdd0e32011-11-04 23:29:40 +00006386 radius = StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006387 break;
6388 }
6389 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6390 break;
6391 }
6392 case 'S':
6393 case 's':
6394 {
6395 if (LocaleCompare(keyword,"sigma") == 0)
6396 {
cristyf2f27272009-12-17 14:48:46 +00006397 sigma = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00006398 break;
6399 }
6400 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6401 break;
6402 }
6403 default:
6404 {
6405 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6406 break;
6407 }
6408 }
6409 }
6410 }
6411
6412 /*
6413 sharpen image.
6414 */
6415 {
6416 Image
6417 *newImage;
6418
cristyaa2c16c2012-03-25 22:21:35 +00006419 newImage=SharpenImage(msl_info->image[n],radius,sigma,
cristyc82a27b2011-10-21 01:07:16 +00006420 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00006421 if (newImage == (Image *) NULL)
6422 break;
6423 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6424 msl_info->image[n]=newImage;
6425 break;
6426 }
6427 }
cristyb988fe72009-09-16 01:01:10 +00006428 else if (LocaleCompare((const char *) tag,"shave") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006429 {
6430 /* init the values */
6431 width = height = 0;
6432 x = y = 0;
6433
6434 if (msl_info->image[n] == (Image *) NULL)
6435 {
cristyb988fe72009-09-16 01:01:10 +00006436 ThrowMSLException(OptionError,"NoImagesDefined",
6437 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006438 break;
6439 }
6440 if (attributes == (const xmlChar **) NULL)
6441 break;
6442 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6443 {
6444 keyword=(const char *) attributes[i++];
6445 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
dirk6d6d5f22014-06-20 11:48:54 +00006446 msl_info->attributes[n],(const char *) attributes[i],exception));
cristy3ed852e2009-09-05 21:47:34 +00006447 switch (*keyword)
6448 {
6449 case 'G':
6450 case 'g':
6451 {
6452 if (LocaleCompare(keyword,"geometry") == 0)
6453 {
6454 (void) ParseMetaGeometry(value,&x,&y,&width,&height);
6455 break;
6456 }
6457 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6458 break;
6459 }
6460 case 'H':
6461 case 'h':
6462 {
6463 if (LocaleCompare(keyword,"height") == 0)
6464 {
cristyf2f27272009-12-17 14:48:46 +00006465 height = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00006466 break;
6467 }
6468 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6469 break;
6470 }
6471 case 'W':
6472 case 'w':
6473 {
6474 if (LocaleCompare(keyword,"width") == 0)
6475 {
cristyf2f27272009-12-17 14:48:46 +00006476 width = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00006477 break;
6478 }
6479 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6480 break;
6481 }
6482 default:
6483 {
6484 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6485 break;
6486 }
6487 }
6488 }
6489
6490 /*
6491 process image.
6492 */
6493 {
6494 Image
6495 *newImage;
6496 RectangleInfo
6497 rectInfo;
6498
6499 rectInfo.height = height;
6500 rectInfo.width = width;
6501 rectInfo.x = x;
6502 rectInfo.y = y;
6503
6504
6505 newImage=ShaveImage(msl_info->image[n], &rectInfo,
cristyc82a27b2011-10-21 01:07:16 +00006506 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00006507 if (newImage == (Image *) NULL)
6508 break;
6509 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6510 msl_info->image[n]=newImage;
6511 }
6512
6513 break;
6514 }
cristyb988fe72009-09-16 01:01:10 +00006515 if (LocaleCompare((const char *) tag,"shear") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006516 {
6517 Image
6518 *shear_image;
6519
6520 /*
6521 Shear image.
6522 */
6523 if (msl_info->image[n] == (Image *) NULL)
6524 {
cristyb988fe72009-09-16 01:01:10 +00006525 ThrowMSLException(OptionError,"NoImagesDefined",
6526 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006527 break;
6528 }
6529 if (attributes != (const xmlChar **) NULL)
6530 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6531 {
6532 keyword=(const char *) attributes[i++];
6533 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006534 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00006535 exception);
cristy3ed852e2009-09-05 21:47:34 +00006536 CloneString(&value,attribute);
6537 switch (*keyword)
6538 {
6539 case 'F':
6540 case 'f':
6541 {
6542 if (LocaleCompare(keyword, "fill") == 0)
6543 {
cristy9950d572011-10-01 18:22:35 +00006544 (void) QueryColorCompliance(value,AllCompliance,
dirk6d6d5f22014-06-20 11:48:54 +00006545 &msl_info->image[n]->background_color,exception);
cristy3ed852e2009-09-05 21:47:34 +00006546 break;
6547 }
6548 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6549 keyword);
6550 break;
6551 }
6552 case 'G':
6553 case 'g':
6554 {
6555 if (LocaleCompare(keyword,"geometry") == 0)
6556 {
6557 flags=ParseGeometry(value,&geometry_info);
6558 if ((flags & SigmaValue) == 0)
6559 geometry_info.sigma=1.0;
6560 break;
6561 }
6562 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6563 keyword);
6564 break;
6565 }
6566 case 'X':
6567 case 'x':
6568 {
6569 if (LocaleCompare(keyword,"x") == 0)
6570 {
cristydbdd0e32011-11-04 23:29:40 +00006571 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00006572 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006573 break;
6574 }
6575 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6576 keyword);
6577 break;
6578 }
6579 case 'Y':
6580 case 'y':
6581 {
6582 if (LocaleCompare(keyword,"y") == 0)
6583 {
cristyf2f27272009-12-17 14:48:46 +00006584 geometry_info.sigma=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006585 break;
6586 }
6587 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6588 keyword);
6589 break;
6590 }
6591 default:
6592 {
6593 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6594 keyword);
6595 break;
6596 }
6597 }
6598 }
6599 shear_image=ShearImage(msl_info->image[n],geometry_info.rho,
cristyc82a27b2011-10-21 01:07:16 +00006600 geometry_info.sigma,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00006601 if (shear_image == (Image *) NULL)
6602 break;
6603 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6604 msl_info->image[n]=shear_image;
6605 break;
6606 }
cristyb988fe72009-09-16 01:01:10 +00006607 if (LocaleCompare((const char *) tag,"signature") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006608 {
6609 /*
6610 Signature image.
6611 */
6612 if (msl_info->image[n] == (Image *) NULL)
6613 {
cristyb988fe72009-09-16 01:01:10 +00006614 ThrowMSLException(OptionError,"NoImagesDefined",
6615 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006616 break;
6617 }
6618 if (attributes != (const xmlChar **) NULL)
6619 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6620 {
6621 keyword=(const char *) attributes[i++];
6622 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006623 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00006624 exception);
cristy3ed852e2009-09-05 21:47:34 +00006625 CloneString(&value,attribute);
6626 switch (*keyword)
6627 {
6628 default:
6629 {
6630 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6631 keyword);
6632 break;
6633 }
6634 }
6635 }
dirk6d6d5f22014-06-20 11:48:54 +00006636 (void) SignatureImage(msl_info->image[n],exception);
cristy3ed852e2009-09-05 21:47:34 +00006637 break;
6638 }
cristyb988fe72009-09-16 01:01:10 +00006639 if (LocaleCompare((const char *) tag,"solarize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006640 {
6641 /*
6642 Solarize image.
6643 */
6644 if (msl_info->image[n] == (Image *) NULL)
6645 {
cristyb988fe72009-09-16 01:01:10 +00006646 ThrowMSLException(OptionError,"NoImagesDefined",
6647 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006648 break;
6649 }
6650 geometry_info.rho=QuantumRange/2.0;
6651 if (attributes != (const xmlChar **) NULL)
6652 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6653 {
6654 keyword=(const char *) attributes[i++];
6655 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006656 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00006657 exception);
cristy3ed852e2009-09-05 21:47:34 +00006658 CloneString(&value,attribute);
6659 switch (*keyword)
6660 {
6661 case 'G':
6662 case 'g':
6663 {
6664 if (LocaleCompare(keyword,"geometry") == 0)
6665 {
6666 flags=ParseGeometry(value,&geometry_info);
6667 break;
6668 }
6669 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6670 keyword);
6671 break;
6672 }
6673 case 'T':
6674 case 't':
6675 {
6676 if (LocaleCompare(keyword,"threshold") == 0)
6677 {
cristydbdd0e32011-11-04 23:29:40 +00006678 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00006679 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006680 break;
6681 }
6682 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6683 keyword);
6684 break;
6685 }
6686 default:
6687 {
6688 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6689 keyword);
6690 break;
6691 }
6692 }
6693 }
cristy5cbc0162011-08-29 00:36:28 +00006694 (void) SolarizeImage(msl_info->image[n],geometry_info.rho,
cristyc82a27b2011-10-21 01:07:16 +00006695 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00006696 break;
6697 }
cristyb988fe72009-09-16 01:01:10 +00006698 if (LocaleCompare((const char *) tag,"spread") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006699 {
6700 Image
6701 *spread_image;
6702
6703 /*
6704 Spread image.
6705 */
6706 if (msl_info->image[n] == (Image *) NULL)
6707 {
cristyb988fe72009-09-16 01:01:10 +00006708 ThrowMSLException(OptionError,"NoImagesDefined",
6709 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006710 break;
6711 }
6712 if (attributes != (const xmlChar **) NULL)
6713 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6714 {
6715 keyword=(const char *) attributes[i++];
6716 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006717 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00006718 exception);
cristy3ed852e2009-09-05 21:47:34 +00006719 CloneString(&value,attribute);
6720 switch (*keyword)
6721 {
6722 case 'G':
6723 case 'g':
6724 {
6725 if (LocaleCompare(keyword,"geometry") == 0)
6726 {
6727 flags=ParseGeometry(value,&geometry_info);
6728 if ((flags & SigmaValue) == 0)
6729 geometry_info.sigma=1.0;
6730 break;
6731 }
6732 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6733 keyword);
6734 break;
6735 }
6736 case 'R':
6737 case 'r':
6738 {
6739 if (LocaleCompare(keyword,"radius") == 0)
6740 {
cristydbdd0e32011-11-04 23:29:40 +00006741 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00006742 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006743 break;
6744 }
6745 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6746 keyword);
6747 break;
6748 }
6749 default:
6750 {
6751 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6752 keyword);
6753 break;
6754 }
6755 }
6756 }
6757 spread_image=SpreadImage(msl_info->image[n],geometry_info.rho,
cristyc82a27b2011-10-21 01:07:16 +00006758 msl_info->image[n]->interpolate,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00006759 if (spread_image == (Image *) NULL)
6760 break;
6761 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6762 msl_info->image[n]=spread_image;
6763 break;
6764 }
cristyb988fe72009-09-16 01:01:10 +00006765 else if (LocaleCompare((const char *) tag,"stegano") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006766 {
6767 Image *
cristyf432c632014-12-07 15:11:28 +00006768 watermark = (Image*) NULL;
cristy3ed852e2009-09-05 21:47:34 +00006769
6770 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00006771 {
6772 ThrowMSLException(OptionError,"NoImagesDefined",
6773 (const char *) tag);
6774 break;
6775 }
cristy3ed852e2009-09-05 21:47:34 +00006776 if (attributes == (const xmlChar **) NULL)
6777 break;
6778 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6779 {
6780 keyword=(const char *) attributes[i++];
6781 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
dirk6d6d5f22014-06-20 11:48:54 +00006782 msl_info->attributes[n],(const char *) attributes[i],exception));
cristy3ed852e2009-09-05 21:47:34 +00006783 switch (*keyword)
6784 {
6785 case 'I':
6786 case 'i':
6787 {
6788 if (LocaleCompare(keyword,"image") == 0)
6789 {
6790 for (j=0; j<msl_info->n;j++)
6791 {
6792 const char *
cristyd15e6592011-10-15 00:13:06 +00006793 theAttr = GetImageProperty(msl_info->attributes[j], "id",
dirk6d6d5f22014-06-20 11:48:54 +00006794 exception);
cristy3ed852e2009-09-05 21:47:34 +00006795 if (theAttr && LocaleCompare(theAttr, value) == 0)
6796 {
6797 watermark = msl_info->image[j];
6798 break;
6799 }
6800 }
6801 break;
6802 }
6803 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6804 break;
6805 }
6806 default:
6807 {
6808 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6809 break;
6810 }
6811 }
6812 }
6813
6814 /*
6815 process image.
6816 */
6817 if ( watermark != (Image*) NULL )
6818 {
6819 Image
6820 *newImage;
6821
cristyc82a27b2011-10-21 01:07:16 +00006822 newImage=SteganoImage(msl_info->image[n], watermark, msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00006823 if (newImage == (Image *) NULL)
6824 break;
6825 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6826 msl_info->image[n]=newImage;
6827 break;
6828 } else
6829 ThrowMSLException(OptionError,"MissingWatermarkImage",keyword);
6830 }
cristyb988fe72009-09-16 01:01:10 +00006831 else if (LocaleCompare((const char *) tag,"stereo") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006832 {
6833 Image *
cristyf432c632014-12-07 15:11:28 +00006834 stereoImage = (Image*) NULL;
cristy3ed852e2009-09-05 21:47:34 +00006835
6836 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00006837 {
6838 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
6839 break;
6840 }
cristy3ed852e2009-09-05 21:47:34 +00006841 if (attributes == (const xmlChar **) NULL)
6842 break;
6843 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6844 {
6845 keyword=(const char *) attributes[i++];
6846 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
dirk6d6d5f22014-06-20 11:48:54 +00006847 msl_info->attributes[n],(const char *) attributes[i],exception));
cristy3ed852e2009-09-05 21:47:34 +00006848 switch (*keyword)
6849 {
6850 case 'I':
6851 case 'i':
6852 {
6853 if (LocaleCompare(keyword,"image") == 0)
6854 {
6855 for (j=0; j<msl_info->n;j++)
6856 {
6857 const char *
cristyd15e6592011-10-15 00:13:06 +00006858 theAttr = GetImageProperty(msl_info->attributes[j], "id",
dirk6d6d5f22014-06-20 11:48:54 +00006859 exception);
cristy3ed852e2009-09-05 21:47:34 +00006860 if (theAttr && LocaleCompare(theAttr, value) == 0)
6861 {
6862 stereoImage = msl_info->image[j];
6863 break;
6864 }
6865 }
6866 break;
6867 }
6868 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6869 break;
6870 }
6871 default:
6872 {
6873 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6874 break;
6875 }
6876 }
6877 }
6878
6879 /*
6880 process image.
6881 */
6882 if ( stereoImage != (Image*) NULL )
6883 {
6884 Image
6885 *newImage;
6886
cristyc82a27b2011-10-21 01:07:16 +00006887 newImage=StereoImage(msl_info->image[n], stereoImage, msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00006888 if (newImage == (Image *) NULL)
6889 break;
6890 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6891 msl_info->image[n]=newImage;
6892 break;
6893 } else
6894 ThrowMSLException(OptionError,"Missing stereo image",keyword);
6895 }
cristy8b2b4e52012-06-27 01:01:10 +00006896 if (LocaleCompare((const char *) tag,"strip") == 0)
6897 {
cristy8b2b4e52012-06-27 01:01:10 +00006898 /*
cristyae497ba2012-06-27 01:01:51 +00006899 Strip image.
cristy8b2b4e52012-06-27 01:01:10 +00006900 */
6901 if (msl_info->image[n] == (Image *) NULL)
6902 {
6903 ThrowMSLException(OptionError,"NoImagesDefined",
6904 (const char *) tag);
6905 break;
6906 }
6907 if (attributes != (const xmlChar **) NULL)
6908 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6909 {
6910 keyword=(const char *) attributes[i++];
6911 attribute=InterpretImageProperties(msl_info->image_info[n],
6912 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00006913 exception);
cristy8b2b4e52012-06-27 01:01:10 +00006914 CloneString(&value,attribute);
6915 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6916 }
6917 (void) StripImage(msl_info->image[n],msl_info->exception);
6918 break;
6919 }
cristyb988fe72009-09-16 01:01:10 +00006920 if (LocaleCompare((const char *) tag,"swap") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006921 {
6922 Image
6923 *p,
6924 *q,
6925 *swap;
6926
cristybb503372010-05-27 20:51:26 +00006927 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00006928 index,
6929 swap_index;
6930
6931 if (msl_info->image[n] == (Image *) NULL)
6932 {
cristyb988fe72009-09-16 01:01:10 +00006933 ThrowMSLException(OptionError,"NoImagesDefined",
6934 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006935 break;
6936 }
6937 index=(-1);
6938 swap_index=(-2);
6939 if (attributes != (const xmlChar **) NULL)
6940 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6941 {
6942 keyword=(const char *) attributes[i++];
6943 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006944 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00006945 exception);
cristy3ed852e2009-09-05 21:47:34 +00006946 CloneString(&value,attribute);
6947 switch (*keyword)
6948 {
6949 case 'G':
6950 case 'g':
6951 {
6952 if (LocaleCompare(keyword,"indexes") == 0)
6953 {
6954 flags=ParseGeometry(value,&geometry_info);
cristybb503372010-05-27 20:51:26 +00006955 index=(ssize_t) geometry_info.rho;
cristy3ed852e2009-09-05 21:47:34 +00006956 if ((flags & SigmaValue) == 0)
cristybb503372010-05-27 20:51:26 +00006957 swap_index=(ssize_t) geometry_info.sigma;
cristy3ed852e2009-09-05 21:47:34 +00006958 break;
6959 }
6960 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6961 keyword);
6962 break;
6963 }
6964 default:
6965 {
6966 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6967 keyword);
6968 break;
6969 }
6970 }
6971 }
6972 /*
6973 Swap images.
6974 */
6975 p=GetImageFromList(msl_info->image[n],index);
6976 q=GetImageFromList(msl_info->image[n],swap_index);
6977 if ((p == (Image *) NULL) || (q == (Image *) NULL))
6978 {
cristyb988fe72009-09-16 01:01:10 +00006979 ThrowMSLException(OptionError,"NoSuchImage",(const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006980 break;
6981 }
cristyc82a27b2011-10-21 01:07:16 +00006982 swap=CloneImage(p,0,0,MagickTrue,msl_info->exception);
6983 ReplaceImageInList(&p,CloneImage(q,0,0,MagickTrue,
6984 msl_info->exception));
cristy3ed852e2009-09-05 21:47:34 +00006985 ReplaceImageInList(&q,swap);
6986 msl_info->image[n]=GetFirstImageInList(q);
6987 break;
6988 }
cristyb988fe72009-09-16 01:01:10 +00006989 if (LocaleCompare((const char *) tag,"swirl") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006990 {
6991 Image
6992 *swirl_image;
6993
6994 /*
6995 Swirl image.
6996 */
6997 if (msl_info->image[n] == (Image *) NULL)
6998 {
cristyb988fe72009-09-16 01:01:10 +00006999 ThrowMSLException(OptionError,"NoImagesDefined",
7000 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00007001 break;
7002 }
7003 if (attributes != (const xmlChar **) NULL)
7004 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7005 {
7006 keyword=(const char *) attributes[i++];
7007 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00007008 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00007009 exception);
cristy3ed852e2009-09-05 21:47:34 +00007010 CloneString(&value,attribute);
7011 switch (*keyword)
7012 {
7013 case 'D':
7014 case 'd':
7015 {
7016 if (LocaleCompare(keyword,"degrees") == 0)
7017 {
cristydbdd0e32011-11-04 23:29:40 +00007018 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00007019 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00007020 break;
7021 }
7022 ThrowMSLException(OptionError,"UnrecognizedAttribute",
7023 keyword);
7024 break;
7025 }
7026 case 'G':
7027 case 'g':
7028 {
7029 if (LocaleCompare(keyword,"geometry") == 0)
7030 {
7031 flags=ParseGeometry(value,&geometry_info);
7032 if ((flags & SigmaValue) == 0)
7033 geometry_info.sigma=1.0;
7034 break;
7035 }
7036 ThrowMSLException(OptionError,"UnrecognizedAttribute",
7037 keyword);
7038 break;
7039 }
7040 default:
7041 {
7042 ThrowMSLException(OptionError,"UnrecognizedAttribute",
7043 keyword);
7044 break;
7045 }
7046 }
7047 }
7048 swirl_image=SwirlImage(msl_info->image[n],geometry_info.rho,
cristyc82a27b2011-10-21 01:07:16 +00007049 msl_info->image[n]->interpolate,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00007050 if (swirl_image == (Image *) NULL)
7051 break;
7052 msl_info->image[n]=DestroyImage(msl_info->image[n]);
7053 msl_info->image[n]=swirl_image;
7054 break;
7055 }
cristyb988fe72009-09-16 01:01:10 +00007056 if (LocaleCompare((const char *) tag,"sync") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007057 {
7058 /*
7059 Sync image.
7060 */
7061 if (msl_info->image[n] == (Image *) NULL)
7062 {
cristyb988fe72009-09-16 01:01:10 +00007063 ThrowMSLException(OptionError,"NoImagesDefined",
7064 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00007065 break;
7066 }
7067 if (attributes != (const xmlChar **) NULL)
7068 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7069 {
7070 keyword=(const char *) attributes[i++];
7071 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00007072 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00007073 exception);
cristy3ed852e2009-09-05 21:47:34 +00007074 CloneString(&value,attribute);
7075 switch (*keyword)
7076 {
7077 default:
7078 {
7079 ThrowMSLException(OptionError,"UnrecognizedAttribute",
7080 keyword);
7081 break;
7082 }
7083 }
7084 }
dirk6d6d5f22014-06-20 11:48:54 +00007085 (void) SyncImage(msl_info->image[n],exception);
cristy3ed852e2009-09-05 21:47:34 +00007086 break;
7087 }
7088 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7089 }
7090 case 'T':
7091 case 't':
7092 {
cristyb988fe72009-09-16 01:01:10 +00007093 if (LocaleCompare((const char *) tag,"map") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007094 {
7095 Image
7096 *texture_image;
7097
7098 /*
7099 Texture image.
7100 */
7101 if (msl_info->image[n] == (Image *) NULL)
7102 {
cristyb988fe72009-09-16 01:01:10 +00007103 ThrowMSLException(OptionError,"NoImagesDefined",
7104 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00007105 break;
7106 }
7107 texture_image=NewImageList();
7108 if (attributes != (const xmlChar **) NULL)
7109 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7110 {
7111 keyword=(const char *) attributes[i++];
7112 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00007113 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00007114 exception);
cristy3ed852e2009-09-05 21:47:34 +00007115 CloneString(&value,attribute);
7116 switch (*keyword)
7117 {
7118 case 'I':
7119 case 'i':
7120 {
7121 if (LocaleCompare(keyword,"image") == 0)
7122 for (j=0; j < msl_info->n; j++)
7123 {
7124 const char
7125 *attribute;
cristyb988fe72009-09-16 01:01:10 +00007126
cristyd15e6592011-10-15 00:13:06 +00007127 attribute=GetImageProperty(msl_info->attributes[j],"id",
dirk6d6d5f22014-06-20 11:48:54 +00007128 exception);
cristy3ed852e2009-09-05 21:47:34 +00007129 if ((attribute != (const char *) NULL) &&
7130 (LocaleCompare(attribute,value) == 0))
7131 {
7132 texture_image=CloneImage(msl_info->image[j],0,0,
dirk6d6d5f22014-06-20 11:48:54 +00007133 MagickFalse,exception);
cristy3ed852e2009-09-05 21:47:34 +00007134 break;
7135 }
7136 }
7137 break;
7138 }
7139 default:
7140 {
7141 ThrowMSLException(OptionError,"UnrecognizedAttribute",
7142 keyword);
7143 break;
7144 }
7145 }
7146 }
dirk6d6d5f22014-06-20 11:48:54 +00007147 (void) TextureImage(msl_info->image[n],texture_image,exception);
cristy3ed852e2009-09-05 21:47:34 +00007148 texture_image=DestroyImage(texture_image);
7149 break;
7150 }
cristyb988fe72009-09-16 01:01:10 +00007151 else if (LocaleCompare((const char *) tag,"threshold") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007152 {
7153 /* init the values */
7154 double threshold = 0;
7155
7156 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007157 {
7158 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7159 break;
7160 }
cristy3ed852e2009-09-05 21:47:34 +00007161 if (attributes == (const xmlChar **) NULL)
7162 break;
7163 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7164 {
7165 keyword=(const char *) attributes[i++];
7166 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
dirk6d6d5f22014-06-20 11:48:54 +00007167 msl_info->attributes[n],(const char *) attributes[i],exception));
cristy3ed852e2009-09-05 21:47:34 +00007168 switch (*keyword)
7169 {
7170 case 'T':
7171 case 't':
7172 {
7173 if (LocaleCompare(keyword,"threshold") == 0)
7174 {
cristydbdd0e32011-11-04 23:29:40 +00007175 threshold = StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00007176 break;
7177 }
7178 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7179 break;
7180 }
7181 default:
7182 {
7183 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7184 break;
7185 }
7186 }
7187 }
7188
7189 /*
7190 process image.
7191 */
7192 {
dirk6d6d5f22014-06-20 11:48:54 +00007193 BilevelImage(msl_info->image[n],threshold,exception);
cristye941a752011-10-15 01:52:48 +00007194 break;
cristy3ed852e2009-09-05 21:47:34 +00007195 }
7196 }
cristyb988fe72009-09-16 01:01:10 +00007197 else if (LocaleCompare((const char *) tag, "transparent") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007198 {
7199 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007200 {
7201 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7202 break;
7203 }
cristy3ed852e2009-09-05 21:47:34 +00007204 if (attributes == (const xmlChar **) NULL)
7205 break;
7206 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7207 {
7208 keyword=(const char *) attributes[i++];
7209 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
dirk6d6d5f22014-06-20 11:48:54 +00007210 msl_info->attributes[n],(const char *) attributes[i],exception));
cristy3ed852e2009-09-05 21:47:34 +00007211 switch (*keyword)
7212 {
7213 case 'C':
7214 case 'c':
7215 {
7216 if (LocaleCompare(keyword,"color") == 0)
7217 {
cristy4c08aed2011-07-01 19:47:50 +00007218 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00007219 target;
7220
cristy269c9412011-10-13 23:41:15 +00007221 (void) QueryColorCompliance(value,AllCompliance,&target,
dirk6d6d5f22014-06-20 11:48:54 +00007222 exception);
cristy3ed852e2009-09-05 21:47:34 +00007223 (void) TransparentPaintImage(msl_info->image[n],&target,
cristyc82a27b2011-10-21 01:07:16 +00007224 TransparentAlpha,MagickFalse,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00007225 break;
7226 }
7227 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7228 break;
7229 }
7230 default:
7231 {
7232 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7233 break;
7234 }
7235 }
7236 }
7237 break;
7238 }
cristyb988fe72009-09-16 01:01:10 +00007239 else if (LocaleCompare((const char *) tag, "trim") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007240 {
7241 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007242 {
7243 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7244 break;
7245 }
cristy3ed852e2009-09-05 21:47:34 +00007246
7247 /* no attributes here */
7248
7249 /* process the image */
7250 {
7251 Image
7252 *newImage;
7253 RectangleInfo
7254 rectInfo;
7255
7256 /* all zeros on a crop == trim edges! */
7257 rectInfo.height = rectInfo.width = 0;
7258 rectInfo.x = rectInfo.y = 0;
7259
cristyc82a27b2011-10-21 01:07:16 +00007260 newImage=CropImage(msl_info->image[n],&rectInfo, msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00007261 if (newImage == (Image *) NULL)
7262 break;
7263 msl_info->image[n]=DestroyImage(msl_info->image[n]);
7264 msl_info->image[n]=newImage;
7265 break;
7266 }
7267 }
7268 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7269 }
7270 case 'W':
7271 case 'w':
7272 {
cristyb988fe72009-09-16 01:01:10 +00007273 if (LocaleCompare((const char *) tag,"write") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007274 {
7275 if (msl_info->image[n] == (Image *) NULL)
7276 {
cristyb988fe72009-09-16 01:01:10 +00007277 ThrowMSLException(OptionError,"NoImagesDefined",
7278 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00007279 break;
7280 }
7281 if (attributes == (const xmlChar **) NULL)
7282 break;
7283 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7284 {
7285 keyword=(const char *) attributes[i++];
7286 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
dirk6d6d5f22014-06-20 11:48:54 +00007287 msl_info->attributes[n],(const char *) attributes[i],exception));
cristy3ed852e2009-09-05 21:47:34 +00007288 switch (*keyword)
7289 {
7290 case 'F':
7291 case 'f':
7292 {
7293 if (LocaleCompare(keyword,"filename") == 0)
7294 {
7295 (void) CopyMagickString(msl_info->image[n]->filename,value,
cristy151b66d2015-04-15 10:50:31 +00007296 MagickPathExtent);
cristy3ed852e2009-09-05 21:47:34 +00007297 break;
7298 }
cristy4582cbb2009-09-23 00:35:43 +00007299 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00007300 }
7301 default:
7302 {
cristy4582cbb2009-09-23 00:35:43 +00007303 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00007304 break;
7305 }
7306 }
7307 }
7308
7309 /* process */
7310 {
cristyb1fcb2b2015-02-12 00:17:34 +00007311 *msl_info->image_info[n]->magick='\0';
cristy6f9e0d32011-08-28 16:32:09 +00007312 (void) WriteImage(msl_info->image_info[n], msl_info->image[n],
cristyc82a27b2011-10-21 01:07:16 +00007313 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00007314 break;
7315 }
7316 }
7317 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7318 }
7319 default:
7320 {
7321 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7322 break;
7323 }
7324 }
7325 if ( value != NULL )
7326 value=DestroyString(value);
dirke31feb82014-06-20 11:03:07 +00007327 (void) DestroyExceptionInfo(exception);
cristy3ed852e2009-09-05 21:47:34 +00007328 (void) LogMagickEvent(CoderEvent,GetMagickModule()," )");
7329}
7330
7331static void MSLEndElement(void *context,const xmlChar *tag)
7332{
cristybb503372010-05-27 20:51:26 +00007333 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00007334 n;
7335
7336 MSLInfo
7337 *msl_info;
7338
7339 /*
7340 Called when the end of an element has been detected.
7341 */
7342 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.endElement(%s)",
7343 tag);
7344 msl_info=(MSLInfo *) context;
7345 n=msl_info->n;
7346 switch (*tag)
7347 {
7348 case 'C':
7349 case 'c':
7350 {
cristyb988fe72009-09-16 01:01:10 +00007351 if (LocaleCompare((const char *) tag,"comment") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007352 {
7353 (void) DeleteImageProperty(msl_info->image[n],"comment");
7354 if (msl_info->content == (char *) NULL)
7355 break;
7356 StripString(msl_info->content);
7357 (void) SetImageProperty(msl_info->image[n],"comment",
cristyd15e6592011-10-15 00:13:06 +00007358 msl_info->content,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00007359 break;
7360 }
7361 break;
7362 }
7363 case 'G':
7364 case 'g':
7365 {
cristyb988fe72009-09-16 01:01:10 +00007366 if (LocaleCompare((const char *) tag, "group") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007367 {
7368 if (msl_info->group_info[msl_info->number_groups-1].numImages > 0 )
7369 {
cristybb503372010-05-27 20:51:26 +00007370 ssize_t i = (ssize_t)
cristy3ed852e2009-09-05 21:47:34 +00007371 (msl_info->group_info[msl_info->number_groups-1].numImages);
7372 while ( i-- )
7373 {
7374 if (msl_info->image[msl_info->n] != (Image *) NULL)
cristyd15e6592011-10-15 00:13:06 +00007375 msl_info->image[msl_info->n]=DestroyImage(
7376 msl_info->image[msl_info->n]);
7377 msl_info->attributes[msl_info->n]=DestroyImage(
7378 msl_info->attributes[msl_info->n]);
7379 msl_info->image_info[msl_info->n]=DestroyImageInfo(
7380 msl_info->image_info[msl_info->n]);
cristy3ed852e2009-09-05 21:47:34 +00007381 msl_info->n--;
7382 }
7383 }
7384 msl_info->number_groups--;
7385 }
7386 break;
7387 }
7388 case 'I':
7389 case 'i':
7390 {
cristyb988fe72009-09-16 01:01:10 +00007391 if (LocaleCompare((const char *) tag, "image") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007392 MSLPopImage(msl_info);
7393 break;
7394 }
7395 case 'L':
7396 case 'l':
7397 {
cristyb988fe72009-09-16 01:01:10 +00007398 if (LocaleCompare((const char *) tag,"label") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007399 {
7400 (void) DeleteImageProperty(msl_info->image[n],"label");
7401 if (msl_info->content == (char *) NULL)
7402 break;
7403 StripString(msl_info->content);
7404 (void) SetImageProperty(msl_info->image[n],"label",
cristyd15e6592011-10-15 00:13:06 +00007405 msl_info->content,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00007406 break;
7407 }
7408 break;
7409 }
7410 case 'M':
7411 case 'm':
7412 {
cristyb988fe72009-09-16 01:01:10 +00007413 if (LocaleCompare((const char *) tag, "msl") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007414 {
7415 /*
7416 This our base element.
7417 at the moment we don't do anything special
7418 but someday we might!
7419 */
7420 }
7421 break;
7422 }
7423 default:
7424 break;
7425 }
7426 if (msl_info->content != (char *) NULL)
7427 msl_info->content=DestroyString(msl_info->content);
7428}
7429
7430static void MSLCharacters(void *context,const xmlChar *c,int length)
7431{
7432 MSLInfo
7433 *msl_info;
7434
7435 register char
7436 *p;
7437
cristybb503372010-05-27 20:51:26 +00007438 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00007439 i;
7440
7441 /*
7442 Receiving some characters from the parser.
7443 */
7444 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7445 " SAX.characters(%s,%d)",c,length);
7446 msl_info=(MSLInfo *) context;
7447 if (msl_info->content != (char *) NULL)
7448 msl_info->content=(char *) ResizeQuantumMemory(msl_info->content,
cristy151b66d2015-04-15 10:50:31 +00007449 strlen(msl_info->content)+length+MagickPathExtent,
cristy3ed852e2009-09-05 21:47:34 +00007450 sizeof(*msl_info->content));
7451 else
7452 {
7453 msl_info->content=(char *) NULL;
cristy151b66d2015-04-15 10:50:31 +00007454 if (~length >= (MagickPathExtent-1))
7455 msl_info->content=(char *) AcquireQuantumMemory(length+MagickPathExtent,
cristy3ed852e2009-09-05 21:47:34 +00007456 sizeof(*msl_info->content));
7457 if (msl_info->content != (char *) NULL)
7458 *msl_info->content='\0';
7459 }
7460 if (msl_info->content == (char *) NULL)
7461 return;
7462 p=msl_info->content+strlen(msl_info->content);
7463 for (i=0; i < length; i++)
7464 *p++=c[i];
7465 *p='\0';
7466}
7467
7468static void MSLReference(void *context,const xmlChar *name)
7469{
7470 MSLInfo
7471 *msl_info;
7472
7473 xmlParserCtxtPtr
7474 parser;
7475
7476 /*
7477 Called when an entity reference is detected.
7478 */
7479 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7480 " SAX.reference(%s)",name);
7481 msl_info=(MSLInfo *) context;
7482 parser=msl_info->parser;
7483 if (*name == '#')
7484 (void) xmlAddChild(parser->node,xmlNewCharRef(msl_info->document,name));
7485 else
7486 (void) xmlAddChild(parser->node,xmlNewReference(msl_info->document,name));
7487}
7488
7489static void MSLIgnorableWhitespace(void *context,const xmlChar *c,int length)
7490{
7491 MSLInfo
7492 *msl_info;
7493
7494 /*
7495 Receiving some ignorable whitespaces from the parser.
7496 */
7497 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7498 " SAX.ignorableWhitespace(%.30s, %d)",c,length);
7499 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007500 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007501}
7502
7503static void MSLProcessingInstructions(void *context,const xmlChar *target,
7504 const xmlChar *data)
7505{
7506 MSLInfo
7507 *msl_info;
7508
7509 /*
7510 A processing instruction has been parsed.
7511 */
7512 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7513 " SAX.processingInstruction(%s, %s)",
7514 target,data);
7515 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007516 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007517}
7518
7519static void MSLComment(void *context,const xmlChar *value)
7520{
7521 MSLInfo
7522 *msl_info;
7523
7524 /*
7525 A comment has been parsed.
7526 */
7527 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7528 " SAX.comment(%s)",value);
7529 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007530 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007531}
7532
7533static void MSLWarning(void *context,const char *format,...)
7534{
7535 char
7536 *message,
cristy151b66d2015-04-15 10:50:31 +00007537 reason[MagickPathExtent];
cristy3ed852e2009-09-05 21:47:34 +00007538
7539 MSLInfo
7540 *msl_info;
7541
7542 va_list
7543 operands;
7544
7545 /**
7546 Display and format a warning messages, gives file, line, position and
7547 extra parameters.
7548 */
7549 va_start(operands,format);
7550 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.warning: ");
7551 (void) LogMagickEvent(CoderEvent,GetMagickModule(),format,operands);
7552 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007553 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007554#if !defined(MAGICKCORE_HAVE_VSNPRINTF)
7555 (void) vsprintf(reason,format,operands);
7556#else
cristy151b66d2015-04-15 10:50:31 +00007557 (void) vsnprintf(reason,MagickPathExtent,format,operands);
cristy3ed852e2009-09-05 21:47:34 +00007558#endif
7559 message=GetExceptionMessage(errno);
7560 ThrowMSLException(CoderError,reason,message);
7561 message=DestroyString(message);
7562 va_end(operands);
7563}
7564
7565static void MSLError(void *context,const char *format,...)
7566{
7567 char
cristy151b66d2015-04-15 10:50:31 +00007568 reason[MagickPathExtent];
cristy3ed852e2009-09-05 21:47:34 +00007569
7570 MSLInfo
7571 *msl_info;
7572
7573 va_list
7574 operands;
7575
7576 /*
7577 Display and format a error formats, gives file, line, position and
7578 extra parameters.
7579 */
7580 va_start(operands,format);
7581 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.error: ");
7582 (void) LogMagickEvent(CoderEvent,GetMagickModule(),format,operands);
7583 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007584 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007585#if !defined(MAGICKCORE_HAVE_VSNPRINTF)
7586 (void) vsprintf(reason,format,operands);
7587#else
cristy151b66d2015-04-15 10:50:31 +00007588 (void) vsnprintf(reason,MagickPathExtent,format,operands);
cristy3ed852e2009-09-05 21:47:34 +00007589#endif
7590 ThrowMSLException(DelegateFatalError,reason,"SAX error");
7591 va_end(operands);
7592}
7593
7594static void MSLCDataBlock(void *context,const xmlChar *value,int length)
7595{
7596 MSLInfo
7597 *msl_info;
7598
7599 xmlNodePtr
7600 child;
7601
7602 xmlParserCtxtPtr
7603 parser;
7604
7605 /*
7606 Called when a pcdata block has been parsed.
7607 */
7608 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7609 " SAX.pcdata(%s, %d)",value,length);
7610 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007611 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007612 parser=msl_info->parser;
7613 child=xmlGetLastChild(parser->node);
7614 if ((child != (xmlNodePtr) NULL) && (child->type == XML_CDATA_SECTION_NODE))
7615 {
7616 xmlTextConcat(child,value,length);
7617 return;
7618 }
7619 (void) xmlAddChild(parser->node,xmlNewCDataBlock(parser->myDoc,value,length));
7620}
7621
7622static void MSLExternalSubset(void *context,const xmlChar *name,
7623 const xmlChar *external_id,const xmlChar *system_id)
7624{
7625 MSLInfo
7626 *msl_info;
7627
7628 xmlParserCtxt
7629 parser_context;
7630
7631 xmlParserCtxtPtr
7632 parser;
7633
7634 xmlParserInputPtr
7635 input;
7636
7637 /*
7638 Does this document has an external subset?
7639 */
7640 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7641 " SAX.externalSubset(%s %s %s)",name,
cristyb988fe72009-09-16 01:01:10 +00007642 (external_id != (const xmlChar *) NULL ? (const char *) external_id : " "),
7643 (system_id != (const xmlChar *) NULL ? (const char *) system_id : " "));
cristy3ed852e2009-09-05 21:47:34 +00007644 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007645 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007646 parser=msl_info->parser;
7647 if (((external_id == NULL) && (system_id == NULL)) ||
7648 ((parser->validate == 0) || (parser->wellFormed == 0) ||
7649 (msl_info->document == 0)))
7650 return;
7651 input=MSLResolveEntity(context,external_id,system_id);
7652 if (input == NULL)
7653 return;
7654 (void) xmlNewDtd(msl_info->document,name,external_id,system_id);
7655 parser_context=(*parser);
7656 parser->inputTab=(xmlParserInputPtr *) xmlMalloc(5*sizeof(*parser->inputTab));
7657 if (parser->inputTab == (xmlParserInputPtr *) NULL)
7658 {
7659 parser->errNo=XML_ERR_NO_MEMORY;
7660 parser->input=parser_context.input;
7661 parser->inputNr=parser_context.inputNr;
7662 parser->inputMax=parser_context.inputMax;
7663 parser->inputTab=parser_context.inputTab;
7664 return;
7665 }
7666 parser->inputNr=0;
7667 parser->inputMax=5;
7668 parser->input=NULL;
7669 xmlPushInput(parser,input);
7670 (void) xmlSwitchEncoding(parser,xmlDetectCharEncoding(parser->input->cur,4));
7671 if (input->filename == (char *) NULL)
7672 input->filename=(char *) xmlStrdup(system_id);
7673 input->line=1;
7674 input->col=1;
7675 input->base=parser->input->cur;
7676 input->cur=parser->input->cur;
7677 input->free=NULL;
7678 xmlParseExternalSubset(parser,external_id,system_id);
7679 while (parser->inputNr > 1)
7680 (void) xmlPopInput(parser);
7681 xmlFreeInputStream(parser->input);
7682 xmlFree(parser->inputTab);
7683 parser->input=parser_context.input;
7684 parser->inputNr=parser_context.inputNr;
7685 parser->inputMax=parser_context.inputMax;
7686 parser->inputTab=parser_context.inputTab;
7687}
7688
7689#if defined(__cplusplus) || defined(c_plusplus)
7690}
7691#endif
7692
cristy8b2b4e52012-06-27 01:01:10 +00007693static MagickBooleanType ProcessMSLScript(const ImageInfo *image_info,
7694 Image **image,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00007695{
cristy3ed852e2009-09-05 21:47:34 +00007696 char
cristy151b66d2015-04-15 10:50:31 +00007697 message[MagickPathExtent];
cristy3ed852e2009-09-05 21:47:34 +00007698
7699 Image
7700 *msl_image;
7701
7702 int
7703 status;
7704
cristybb503372010-05-27 20:51:26 +00007705 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00007706 n;
7707
7708 MSLInfo
7709 msl_info;
7710
cristy5f6f01c2009-11-19 19:36:42 +00007711 xmlSAXHandler
7712 sax_modules;
7713
cristy3ed852e2009-09-05 21:47:34 +00007714 xmlSAXHandlerPtr
cristy5f6f01c2009-11-19 19:36:42 +00007715 sax_handler;
cristy3ed852e2009-09-05 21:47:34 +00007716
7717 /*
7718 Open image file.
7719 */
7720 assert(image_info != (const ImageInfo *) NULL);
cristye1c94d92015-06-28 12:16:33 +00007721 assert(image_info->signature == MagickCoreSignature);
cristy3ed852e2009-09-05 21:47:34 +00007722 if (image_info->debug != MagickFalse)
cristy5f6f01c2009-11-19 19:36:42 +00007723 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
7724 image_info->filename);
cristy3ed852e2009-09-05 21:47:34 +00007725 assert(image != (Image **) NULL);
cristy9950d572011-10-01 18:22:35 +00007726 msl_image=AcquireImage(image_info,exception);
cristy3ed852e2009-09-05 21:47:34 +00007727 status=OpenBlob(image_info,msl_image,ReadBinaryBlobMode,exception);
7728 if (status == MagickFalse)
7729 {
7730 ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
7731 msl_image->filename);
7732 msl_image=DestroyImageList(msl_image);
7733 return(MagickFalse);
7734 }
7735 msl_image->columns=1;
7736 msl_image->rows=1;
7737 /*
7738 Parse MSL file.
7739 */
7740 (void) ResetMagickMemory(&msl_info,0,sizeof(msl_info));
7741 msl_info.exception=exception;
7742 msl_info.image_info=(ImageInfo **) AcquireMagickMemory(
7743 sizeof(*msl_info.image_info));
7744 msl_info.draw_info=(DrawInfo **) AcquireMagickMemory(
7745 sizeof(*msl_info.draw_info));
7746 /* top of the stack is the MSL file itself */
cristy73bd4a52010-10-05 11:24:23 +00007747 msl_info.image=(Image **) AcquireMagickMemory(sizeof(*msl_info.image));
cristy3ed852e2009-09-05 21:47:34 +00007748 msl_info.attributes=(Image **) AcquireMagickMemory(
7749 sizeof(*msl_info.attributes));
7750 msl_info.group_info=(MSLGroupInfo *) AcquireMagickMemory(
7751 sizeof(*msl_info.group_info));
7752 if ((msl_info.image_info == (ImageInfo **) NULL) ||
7753 (msl_info.image == (Image **) NULL) ||
7754 (msl_info.attributes == (Image **) NULL) ||
7755 (msl_info.group_info == (MSLGroupInfo *) NULL))
7756 ThrowFatalException(ResourceLimitFatalError,
7757 "UnableToInterpretMSLImage");
7758 *msl_info.image_info=CloneImageInfo(image_info);
7759 *msl_info.draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL);
cristy9950d572011-10-01 18:22:35 +00007760 *msl_info.attributes=AcquireImage(image_info,exception);
cristy3ed852e2009-09-05 21:47:34 +00007761 msl_info.group_info[0].numImages=0;
7762 /* the first slot is used to point to the MSL file image */
7763 *msl_info.image=msl_image;
7764 if (*image != (Image *) NULL)
7765 MSLPushImage(&msl_info,*image);
7766 (void) xmlSubstituteEntitiesDefault(1);
cristy5f6f01c2009-11-19 19:36:42 +00007767 (void) ResetMagickMemory(&sax_modules,0,sizeof(sax_modules));
7768 sax_modules.internalSubset=MSLInternalSubset;
7769 sax_modules.isStandalone=MSLIsStandalone;
7770 sax_modules.hasInternalSubset=MSLHasInternalSubset;
7771 sax_modules.hasExternalSubset=MSLHasExternalSubset;
7772 sax_modules.resolveEntity=MSLResolveEntity;
7773 sax_modules.getEntity=MSLGetEntity;
7774 sax_modules.entityDecl=MSLEntityDeclaration;
7775 sax_modules.notationDecl=MSLNotationDeclaration;
7776 sax_modules.attributeDecl=MSLAttributeDeclaration;
7777 sax_modules.elementDecl=MSLElementDeclaration;
7778 sax_modules.unparsedEntityDecl=MSLUnparsedEntityDeclaration;
7779 sax_modules.setDocumentLocator=MSLSetDocumentLocator;
7780 sax_modules.startDocument=MSLStartDocument;
7781 sax_modules.endDocument=MSLEndDocument;
7782 sax_modules.startElement=MSLStartElement;
7783 sax_modules.endElement=MSLEndElement;
7784 sax_modules.reference=MSLReference;
7785 sax_modules.characters=MSLCharacters;
7786 sax_modules.ignorableWhitespace=MSLIgnorableWhitespace;
7787 sax_modules.processingInstruction=MSLProcessingInstructions;
7788 sax_modules.comment=MSLComment;
7789 sax_modules.warning=MSLWarning;
7790 sax_modules.error=MSLError;
7791 sax_modules.fatalError=MSLError;
7792 sax_modules.getParameterEntity=MSLGetParameterEntity;
7793 sax_modules.cdataBlock=MSLCDataBlock;
7794 sax_modules.externalSubset=MSLExternalSubset;
7795 sax_handler=(&sax_modules);
7796 msl_info.parser=xmlCreatePushParserCtxt(sax_handler,&msl_info,(char *) NULL,0,
cristy3ed852e2009-09-05 21:47:34 +00007797 msl_image->filename);
7798 while (ReadBlobString(msl_image,message) != (char *) NULL)
7799 {
cristybb503372010-05-27 20:51:26 +00007800 n=(ssize_t) strlen(message);
cristy3ed852e2009-09-05 21:47:34 +00007801 if (n == 0)
7802 continue;
7803 status=xmlParseChunk(msl_info.parser,message,(int) n,MagickFalse);
7804 if (status != 0)
7805 break;
7806 (void) xmlParseChunk(msl_info.parser," ",1,MagickFalse);
7807 if (msl_info.exception->severity >= ErrorException)
7808 break;
7809 }
7810 if (msl_info.exception->severity == UndefinedException)
7811 (void) xmlParseChunk(msl_info.parser," ",1,MagickTrue);
7812 xmlFreeParserCtxt(msl_info.parser);
7813 (void) LogMagickEvent(CoderEvent,GetMagickModule(),"end SAX");
cristy3ed852e2009-09-05 21:47:34 +00007814 msl_info.group_info=(MSLGroupInfo *) RelinquishMagickMemory(
7815 msl_info.group_info);
7816 if (*image == (Image *) NULL)
7817 *image=(*msl_info.image);
cristyc82a27b2011-10-21 01:07:16 +00007818 if (msl_info.exception->severity != UndefinedException)
cristy5f6f01c2009-11-19 19:36:42 +00007819 return(MagickFalse);
7820 return(MagickTrue);
cristy3ed852e2009-09-05 21:47:34 +00007821}
7822
7823static Image *ReadMSLImage(const ImageInfo *image_info,ExceptionInfo *exception)
7824{
7825 Image
7826 *image;
7827
7828 /*
7829 Open image file.
7830 */
7831 assert(image_info != (const ImageInfo *) NULL);
cristye1c94d92015-06-28 12:16:33 +00007832 assert(image_info->signature == MagickCoreSignature);
cristy3ed852e2009-09-05 21:47:34 +00007833 if (image_info->debug != MagickFalse)
7834 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
7835 image_info->filename);
7836 assert(exception != (ExceptionInfo *) NULL);
cristye1c94d92015-06-28 12:16:33 +00007837 assert(exception->signature == MagickCoreSignature);
cristy3ed852e2009-09-05 21:47:34 +00007838 image=(Image *) NULL;
7839 (void) ProcessMSLScript(image_info,&image,exception);
7840 return(GetFirstImageInList(image));
7841}
7842#endif
7843
7844/*
7845%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7846% %
7847% %
7848% %
7849% R e g i s t e r M S L I m a g e %
7850% %
7851% %
7852% %
7853%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7854%
7855% RegisterMSLImage() adds attributes for the MSL image format to
7856% the list of supported formats. The attributes include the image format
7857% tag, a method to read and/or write the format, whether the format
7858% supports the saving of more than one frame to the same file or blob,
7859% whether the format supports native in-memory I/O, and a brief
7860% description of the format.
7861%
7862% The format of the RegisterMSLImage method is:
7863%
cristybb503372010-05-27 20:51:26 +00007864% size_t RegisterMSLImage(void)
cristy3ed852e2009-09-05 21:47:34 +00007865%
7866*/
cristybb503372010-05-27 20:51:26 +00007867ModuleExport size_t RegisterMSLImage(void)
cristy3ed852e2009-09-05 21:47:34 +00007868{
7869 MagickInfo
7870 *entry;
7871
cristyfbd03fe2013-08-29 13:47:42 +00007872#if defined(MAGICKCORE_XML_DELEGATE)
7873 xmlInitParser();
7874#endif
dirk06b627a2015-04-06 18:59:17 +00007875 entry=AcquireMagickInfo("MSL","MSL","Magick Scripting Language");
cristy3ed852e2009-09-05 21:47:34 +00007876#if defined(MAGICKCORE_XML_DELEGATE)
7877 entry->decoder=(DecodeImageHandler *) ReadMSLImage;
7878 entry->encoder=(EncodeImageHandler *) WriteMSLImage;
7879#endif
cristy3ed852e2009-09-05 21:47:34 +00007880 (void) RegisterMagickInfo(entry);
7881 return(MagickImageCoderSignature);
7882}
7883
cristy6b9f7ed2010-04-24 01:08:02 +00007884#if defined(MAGICKCORE_XML_DELEGATE)
cristy3ed852e2009-09-05 21:47:34 +00007885/*
7886%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7887% %
7888% %
7889% %
cristyb988fe72009-09-16 01:01:10 +00007890% S e t M S L A t t r i b u t e s %
7891% %
7892% %
7893% %
7894%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7895%
7896% SetMSLAttributes() ...
7897%
7898% The format of the SetMSLAttributes method is:
7899%
7900% MagickBooleanType SetMSLAttributes(MSLInfo *msl_info,
cristyb20775d2009-09-16 01:51:41 +00007901% const char *keyword,const char *value)
cristyb988fe72009-09-16 01:01:10 +00007902%
7903% A description of each parameter follows:
7904%
7905% o msl_info: the MSL info.
7906%
cristyb20775d2009-09-16 01:51:41 +00007907% o keyword: the keyword.
7908%
7909% o value: the value.
cristyb988fe72009-09-16 01:01:10 +00007910%
7911*/
cristyb20775d2009-09-16 01:51:41 +00007912static MagickBooleanType SetMSLAttributes(MSLInfo *msl_info,const char *keyword,
7913 const char *value)
cristyb988fe72009-09-16 01:01:10 +00007914{
cristy4582cbb2009-09-23 00:35:43 +00007915 Image
7916 *attributes;
7917
cristyb20775d2009-09-16 01:51:41 +00007918 DrawInfo
7919 *draw_info;
cristyb988fe72009-09-16 01:01:10 +00007920
7921 ExceptionInfo
7922 *exception;
7923
cristy4582cbb2009-09-23 00:35:43 +00007924 GeometryInfo
7925 geometry_info;
7926
cristy4fa36e42009-09-18 14:24:06 +00007927 Image
7928 *image;
7929
cristyb20775d2009-09-16 01:51:41 +00007930 ImageInfo
7931 *image_info;
7932
cristy4582cbb2009-09-23 00:35:43 +00007933 int
7934 flags;
7935
cristybb503372010-05-27 20:51:26 +00007936 ssize_t
cristyb988fe72009-09-16 01:01:10 +00007937 n;
7938
cristyb988fe72009-09-16 01:01:10 +00007939 assert(msl_info != (MSLInfo *) NULL);
cristyb20775d2009-09-16 01:51:41 +00007940 if (keyword == (const char *) NULL)
7941 return(MagickTrue);
7942 if (value == (const char *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007943 return(MagickTrue);
7944 exception=msl_info->exception;
7945 n=msl_info->n;
cristy4582cbb2009-09-23 00:35:43 +00007946 attributes=msl_info->attributes[n];
cristyb20775d2009-09-16 01:51:41 +00007947 image_info=msl_info->image_info[n];
7948 draw_info=msl_info->draw_info[n];
cristy4fa36e42009-09-18 14:24:06 +00007949 image=msl_info->image[n];
cristyb20775d2009-09-16 01:51:41 +00007950 switch (*keyword)
cristyb988fe72009-09-16 01:01:10 +00007951 {
cristyfb758a52009-09-16 14:36:08 +00007952 case 'A':
7953 case 'a':
7954 {
7955 if (LocaleCompare(keyword,"adjoin") == 0)
7956 {
cristybb503372010-05-27 20:51:26 +00007957 ssize_t
cristyfb758a52009-09-16 14:36:08 +00007958 adjoin;
7959
cristy042ee782011-04-22 18:48:30 +00007960 adjoin=ParseCommandOption(MagickBooleanOptions,MagickFalse,value);
cristyfb758a52009-09-16 14:36:08 +00007961 if (adjoin < 0)
7962 ThrowMSLException(OptionError,"UnrecognizedType",value);
7963 image_info->adjoin=(MagickBooleanType) adjoin;
7964 break;
7965 }
cristy4fa36e42009-09-18 14:24:06 +00007966 if (LocaleCompare(keyword,"alpha") == 0)
7967 {
cristybb503372010-05-27 20:51:26 +00007968 ssize_t
cristy4fa36e42009-09-18 14:24:06 +00007969 alpha;
7970
cristy288a3532012-08-28 00:19:44 +00007971 alpha=ParseCommandOption(MagickAlphaChannelOptions,MagickFalse,value);
cristy4fa36e42009-09-18 14:24:06 +00007972 if (alpha < 0)
7973 ThrowMSLException(OptionError,"UnrecognizedType",value);
cristy4582cbb2009-09-23 00:35:43 +00007974 if (image != (Image *) NULL)
cristyb15b06c2012-08-28 11:36:48 +00007975 (void) SetImageAlphaChannel(image,(AlphaChannelOption) alpha,
cristy63240882011-08-05 19:05:27 +00007976 exception);
cristy4582cbb2009-09-23 00:35:43 +00007977 break;
7978 }
7979 if (LocaleCompare(keyword,"antialias") == 0)
7980 {
cristybb503372010-05-27 20:51:26 +00007981 ssize_t
cristy4582cbb2009-09-23 00:35:43 +00007982 antialias;
7983
cristy042ee782011-04-22 18:48:30 +00007984 antialias=ParseCommandOption(MagickBooleanOptions,MagickFalse,value);
cristy4582cbb2009-09-23 00:35:43 +00007985 if (antialias < 0)
7986 ThrowMSLException(OptionError,"UnrecognizedGravityType",value);
7987 image_info->antialias=(MagickBooleanType) antialias;
7988 break;
7989 }
7990 if (LocaleCompare(keyword,"area-limit") == 0)
7991 {
7992 MagickSizeType
7993 limit;
7994
7995 limit=MagickResourceInfinity;
7996 if (LocaleCompare(value,"unlimited") != 0)
cristydbdd0e32011-11-04 23:29:40 +00007997 limit=(MagickSizeType) StringToDoubleInterval(value,100.0);
cristy4582cbb2009-09-23 00:35:43 +00007998 (void) SetMagickResourceLimit(AreaResource,limit);
7999 break;
8000 }
8001 if (LocaleCompare(keyword,"attenuate") == 0)
8002 {
8003 (void) SetImageOption(image_info,keyword,value);
8004 break;
8005 }
8006 if (LocaleCompare(keyword,"authenticate") == 0)
8007 {
8008 (void) CloneString(&image_info->density,value);
cristy4fa36e42009-09-18 14:24:06 +00008009 break;
8010 }
cristyfb758a52009-09-16 14:36:08 +00008011 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8012 break;
8013 }
cristyb20775d2009-09-16 01:51:41 +00008014 case 'B':
8015 case 'b':
cristyb988fe72009-09-16 01:01:10 +00008016 {
cristyb20775d2009-09-16 01:51:41 +00008017 if (LocaleCompare(keyword,"background") == 0)
8018 {
cristy9950d572011-10-01 18:22:35 +00008019 (void) QueryColorCompliance(value,AllCompliance,
8020 &image_info->background_color,exception);
cristyb20775d2009-09-16 01:51:41 +00008021 break;
8022 }
cristy4582cbb2009-09-23 00:35:43 +00008023 if (LocaleCompare(keyword,"blue-primary") == 0)
8024 {
8025 if (image == (Image *) NULL)
8026 break;
8027 flags=ParseGeometry(value,&geometry_info);
8028 image->chromaticity.blue_primary.x=geometry_info.rho;
8029 image->chromaticity.blue_primary.y=geometry_info.sigma;
8030 if ((flags & SigmaValue) == 0)
8031 image->chromaticity.blue_primary.y=
8032 image->chromaticity.blue_primary.x;
8033 break;
8034 }
cristy2c8b6312009-09-16 02:37:23 +00008035 if (LocaleCompare(keyword,"bordercolor") == 0)
8036 {
cristy9950d572011-10-01 18:22:35 +00008037 (void) QueryColorCompliance(value,AllCompliance,
8038 &image_info->border_color,exception);
cristy2c8b6312009-09-16 02:37:23 +00008039 break;
8040 }
8041 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8042 break;
8043 }
8044 case 'D':
8045 case 'd':
8046 {
8047 if (LocaleCompare(keyword,"density") == 0)
8048 {
8049 (void) CloneString(&image_info->density,value);
8050 (void) CloneString(&draw_info->density,value);
8051 break;
8052 }
cristyb20775d2009-09-16 01:51:41 +00008053 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8054 break;
8055 }
8056 case 'F':
8057 case 'f':
8058 {
8059 if (LocaleCompare(keyword,"fill") == 0)
8060 {
cristy9950d572011-10-01 18:22:35 +00008061 (void) QueryColorCompliance(value,AllCompliance,&draw_info->fill,
8062 exception);
cristya30afaf2009-09-22 13:42:12 +00008063 (void) SetImageOption(image_info,keyword,value);
cristyb20775d2009-09-16 01:51:41 +00008064 break;
8065 }
cristy4582cbb2009-09-23 00:35:43 +00008066 if (LocaleCompare(keyword,"filename") == 0)
8067 {
cristy151b66d2015-04-15 10:50:31 +00008068 (void) CopyMagickString(image_info->filename,value,MagickPathExtent);
cristy4582cbb2009-09-23 00:35:43 +00008069 break;
8070 }
8071 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8072 break;
8073 }
8074 case 'G':
8075 case 'g':
8076 {
8077 if (LocaleCompare(keyword,"gravity") == 0)
8078 {
cristybb503372010-05-27 20:51:26 +00008079 ssize_t
cristy4582cbb2009-09-23 00:35:43 +00008080 gravity;
8081
cristy042ee782011-04-22 18:48:30 +00008082 gravity=ParseCommandOption(MagickGravityOptions,MagickFalse,value);
cristy4582cbb2009-09-23 00:35:43 +00008083 if (gravity < 0)
8084 ThrowMSLException(OptionError,"UnrecognizedGravityType",value);
8085 (void) SetImageOption(image_info,keyword,value);
8086 break;
8087 }
cristyb20775d2009-09-16 01:51:41 +00008088 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8089 break;
8090 }
8091 case 'I':
8092 case 'i':
8093 {
8094 if (LocaleCompare(keyword,"id") == 0)
8095 {
cristyd15e6592011-10-15 00:13:06 +00008096 (void) SetImageProperty(attributes,keyword,value,exception);
cristy2c8b6312009-09-16 02:37:23 +00008097 break;
8098 }
8099 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8100 break;
8101 }
8102 case 'M':
8103 case 'm':
8104 {
8105 if (LocaleCompare(keyword,"magick") == 0)
8106 {
cristy151b66d2015-04-15 10:50:31 +00008107 (void) CopyMagickString(image_info->magick,value,MagickPathExtent);
cristy2c8b6312009-09-16 02:37:23 +00008108 break;
8109 }
cristy2c8b6312009-09-16 02:37:23 +00008110 if (LocaleCompare(keyword,"mattecolor") == 0)
8111 {
cristy9950d572011-10-01 18:22:35 +00008112 (void) QueryColorCompliance(value,AllCompliance,
8113 &image_info->matte_color,exception);
cristyb20775d2009-09-16 01:51:41 +00008114 break;
8115 }
8116 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8117 break;
8118 }
8119 case 'P':
8120 case 'p':
8121 {
8122 if (LocaleCompare(keyword,"pointsize") == 0)
8123 {
cristydbdd0e32011-11-04 23:29:40 +00008124 image_info->pointsize=StringToDouble(value,(char **) NULL);
8125 draw_info->pointsize=StringToDouble(value,(char **) NULL);
cristyb20775d2009-09-16 01:51:41 +00008126 break;
8127 }
8128 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8129 break;
8130 }
cristy4582cbb2009-09-23 00:35:43 +00008131 case 'Q':
8132 case 'q':
8133 {
8134 if (LocaleCompare(keyword,"quality") == 0)
8135 {
cristyf2f27272009-12-17 14:48:46 +00008136 image_info->quality=StringToLong(value);
cristy4582cbb2009-09-23 00:35:43 +00008137 if (image == (Image *) NULL)
8138 break;
cristyf2f27272009-12-17 14:48:46 +00008139 image->quality=StringToLong(value);
cristy4582cbb2009-09-23 00:35:43 +00008140 break;
8141 }
8142 break;
8143 }
cristyb20775d2009-09-16 01:51:41 +00008144 case 'S':
8145 case 's':
8146 {
8147 if (LocaleCompare(keyword,"size") == 0)
8148 {
cristy2c8b6312009-09-16 02:37:23 +00008149 (void) CloneString(&image_info->size,value);
cristyb20775d2009-09-16 01:51:41 +00008150 break;
8151 }
8152 if (LocaleCompare(keyword,"stroke") == 0)
8153 {
cristy9950d572011-10-01 18:22:35 +00008154 (void) QueryColorCompliance(value,AllCompliance,&draw_info->stroke,
8155 exception);
cristya30afaf2009-09-22 13:42:12 +00008156 (void) SetImageOption(image_info,keyword,value);
cristyb20775d2009-09-16 01:51:41 +00008157 break;
8158 }
8159 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8160 break;
8161 }
8162 default:
8163 {
8164 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8165 break;
cristyb988fe72009-09-16 01:01:10 +00008166 }
8167 }
8168 return(MagickTrue);
8169}
cristy6b9f7ed2010-04-24 01:08:02 +00008170#endif
cristyb988fe72009-09-16 01:01:10 +00008171
8172/*
8173%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8174% %
8175% %
8176% %
cristy3ed852e2009-09-05 21:47:34 +00008177% U n r e g i s t e r M S L I m a g e %
8178% %
8179% %
8180% %
8181%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8182%
8183% UnregisterMSLImage() removes format registrations made by the
8184% MSL module from the list of supported formats.
8185%
8186% The format of the UnregisterMSLImage method is:
8187%
8188% UnregisterMSLImage(void)
8189%
8190*/
8191ModuleExport void UnregisterMSLImage(void)
8192{
8193 (void) UnregisterMagickInfo("MSL");
cristyfbd03fe2013-08-29 13:47:42 +00008194#if defined(MAGICKCORE_XML_DELEGATE)
8195 xmlCleanupParser();
8196#endif
cristy3ed852e2009-09-05 21:47:34 +00008197}
8198
8199#if defined(MAGICKCORE_XML_DELEGATE)
8200/*
8201%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8202% %
8203% %
8204% %
8205% W r i t e M S L I m a g e %
8206% %
8207% %
8208% %
8209%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8210%
8211% WriteMSLImage() writes an image to a file in MVG image format.
8212%
8213% The format of the WriteMSLImage method is:
8214%
cristy1e178e72011-08-28 19:44:34 +00008215% MagickBooleanType WriteMSLImage(const ImageInfo *image_info,
8216% Image *image,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00008217%
8218% A description of each parameter follows.
8219%
8220% o image_info: the image info.
8221%
8222% o image: The image.
8223%
cristy1e178e72011-08-28 19:44:34 +00008224% o exception: return any errors or warnings in this structure.
8225%
cristy3ed852e2009-09-05 21:47:34 +00008226*/
cristy1e178e72011-08-28 19:44:34 +00008227static MagickBooleanType WriteMSLImage(const ImageInfo *image_info,Image *image,
8228 ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00008229{
8230 assert(image_info != (const ImageInfo *) NULL);
cristye1c94d92015-06-28 12:16:33 +00008231 assert(image_info->signature == MagickCoreSignature);
cristy3ed852e2009-09-05 21:47:34 +00008232 assert(image != (Image *) NULL);
cristye1c94d92015-06-28 12:16:33 +00008233 assert(image->signature == MagickCoreSignature);
cristy3ed852e2009-09-05 21:47:34 +00008234 if (image->debug != MagickFalse)
8235 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
8236 (void) ReferenceImage(image);
cristy1e178e72011-08-28 19:44:34 +00008237 (void) ProcessMSLScript(image_info,&image,exception);
cristy3ed852e2009-09-05 21:47:34 +00008238 return(MagickTrue);
8239}
8240#endif