blob: 94bfa2bd621dc0c35aa228c22a2df8849b7a63e1 [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 {
2632 CloneString(&draw_info->text,value);
2633 break;
2634 }
2635 if (LocaleCompare(keyword,"translate") == 0)
2636 {
2637 flags=ParseGeometry(value,&geometry_info);
2638 if ((flags & SigmaValue) == 0)
2639 geometry_info.sigma=1.0;
2640 affine.tx=geometry_info.rho;
2641 affine.ty=geometry_info.sigma;
2642 break;
2643 }
2644 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2645 keyword);
2646 break;
2647 }
2648 case 'U':
2649 case 'u':
2650 {
2651 if (LocaleCompare(keyword, "undercolor") == 0)
2652 {
cristy9950d572011-10-01 18:22:35 +00002653 (void) QueryColorCompliance(value,AllCompliance,
dirk6d6d5f22014-06-20 11:48:54 +00002654 &draw_info->undercolor,exception);
cristy3ed852e2009-09-05 21:47:34 +00002655 break;
2656 }
2657 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2658 keyword);
2659 break;
2660 }
2661 case 'W':
2662 case 'w':
2663 {
2664 if (LocaleCompare(keyword,"weight") == 0)
2665 {
cristyf2f27272009-12-17 14:48:46 +00002666 draw_info->weight=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002667 break;
2668 }
2669 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2670 keyword);
2671 break;
2672 }
2673 case 'X':
2674 case 'x':
2675 {
2676 if (LocaleCompare(keyword,"x") == 0)
2677 {
cristyf2f27272009-12-17 14:48:46 +00002678 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002679 break;
2680 }
2681 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2682 keyword);
2683 break;
2684 }
2685 case 'Y':
2686 case 'y':
2687 {
2688 if (LocaleCompare(keyword,"y") == 0)
2689 {
cristyf2f27272009-12-17 14:48:46 +00002690 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002691 break;
2692 }
2693 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2694 keyword);
2695 break;
2696 }
2697 default:
2698 {
2699 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2700 keyword);
2701 break;
2702 }
2703 }
2704 }
cristy151b66d2015-04-15 10:50:31 +00002705 (void) FormatLocaleString(text,MagickPathExtent,
cristye8c25f92010-06-03 00:53:06 +00002706 "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,(double)
2707 geometry.height,(double) geometry.x,(double) geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00002708 CloneString(&draw_info->geometry,text);
cristyef7c8a52010-10-10 13:46:51 +00002709 draw_info->affine.sx=affine.sx*current.sx+affine.ry*current.rx;
2710 draw_info->affine.rx=affine.rx*current.sx+affine.sy*current.rx;
2711 draw_info->affine.ry=affine.sx*current.ry+affine.ry*current.sy;
2712 draw_info->affine.sy=affine.rx*current.ry+affine.sy*current.sy;
2713 draw_info->affine.tx=affine.sx*current.tx+affine.ry*current.ty+
2714 affine.tx;
2715 draw_info->affine.ty=affine.rx*current.tx+affine.sy*current.ty+
2716 affine.ty;
dirk6d6d5f22014-06-20 11:48:54 +00002717 (void) DrawImage(msl_info->image[n],draw_info,exception);
cristy3ed852e2009-09-05 21:47:34 +00002718 draw_info=DestroyDrawInfo(draw_info);
2719 break;
2720 }
2721 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
2722 }
2723 case 'E':
2724 case 'e':
2725 {
cristyb988fe72009-09-16 01:01:10 +00002726 if (LocaleCompare((const char *) tag,"edge") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002727 {
2728 Image
2729 *edge_image;
2730
2731 /*
2732 Edge image.
2733 */
2734 if (msl_info->image[n] == (Image *) NULL)
2735 {
cristyb988fe72009-09-16 01:01:10 +00002736 ThrowMSLException(OptionError,"NoImagesDefined",
2737 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002738 break;
2739 }
2740 if (attributes != (const xmlChar **) NULL)
2741 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2742 {
2743 keyword=(const char *) attributes[i++];
2744 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002745 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00002746 exception);
cristy3ed852e2009-09-05 21:47:34 +00002747 CloneString(&value,attribute);
2748 switch (*keyword)
2749 {
2750 case 'G':
2751 case 'g':
2752 {
2753 if (LocaleCompare(keyword,"geometry") == 0)
2754 {
2755 flags=ParseGeometry(value,&geometry_info);
2756 if ((flags & SigmaValue) == 0)
2757 geometry_info.sigma=1.0;
2758 break;
2759 }
2760 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2761 keyword);
2762 break;
2763 }
2764 case 'R':
2765 case 'r':
2766 {
2767 if (LocaleCompare(keyword,"radius") == 0)
2768 {
cristy9b34e302011-11-05 02:15:45 +00002769 geometry_info.rho=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002770 break;
2771 }
2772 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2773 keyword);
2774 break;
2775 }
2776 default:
2777 {
2778 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2779 keyword);
2780 break;
2781 }
2782 }
2783 }
2784 edge_image=EdgeImage(msl_info->image[n],geometry_info.rho,
cristy9dc4c512013-03-24 01:38:00 +00002785 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00002786 if (edge_image == (Image *) NULL)
2787 break;
2788 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2789 msl_info->image[n]=edge_image;
2790 break;
2791 }
cristyb988fe72009-09-16 01:01:10 +00002792 if (LocaleCompare((const char *) tag,"emboss") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002793 {
2794 Image
2795 *emboss_image;
2796
2797 /*
2798 Emboss image.
2799 */
2800 if (msl_info->image[n] == (Image *) NULL)
2801 {
cristyb988fe72009-09-16 01:01:10 +00002802 ThrowMSLException(OptionError,"NoImagesDefined",
2803 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002804 break;
2805 }
2806 if (attributes != (const xmlChar **) NULL)
2807 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2808 {
2809 keyword=(const char *) attributes[i++];
2810 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002811 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00002812 exception);
cristy3ed852e2009-09-05 21:47:34 +00002813 CloneString(&value,attribute);
2814 switch (*keyword)
2815 {
2816 case 'G':
2817 case 'g':
2818 {
2819 if (LocaleCompare(keyword,"geometry") == 0)
2820 {
2821 flags=ParseGeometry(value,&geometry_info);
2822 if ((flags & SigmaValue) == 0)
2823 geometry_info.sigma=1.0;
2824 break;
2825 }
2826 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2827 keyword);
2828 break;
2829 }
2830 case 'R':
2831 case 'r':
2832 {
2833 if (LocaleCompare(keyword,"radius") == 0)
2834 {
cristydbdd0e32011-11-04 23:29:40 +00002835 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00002836 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00002837 break;
2838 }
2839 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2840 keyword);
2841 break;
2842 }
2843 case 'S':
2844 case 's':
2845 {
2846 if (LocaleCompare(keyword,"sigma") == 0)
2847 {
cristyf2f27272009-12-17 14:48:46 +00002848 geometry_info.sigma=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00002849 break;
2850 }
2851 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2852 keyword);
2853 break;
2854 }
2855 default:
2856 {
2857 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2858 keyword);
2859 break;
2860 }
2861 }
2862 }
2863 emboss_image=EmbossImage(msl_info->image[n],geometry_info.rho,
cristyc82a27b2011-10-21 01:07:16 +00002864 geometry_info.sigma,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00002865 if (emboss_image == (Image *) NULL)
2866 break;
2867 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2868 msl_info->image[n]=emboss_image;
2869 break;
2870 }
cristyb988fe72009-09-16 01:01:10 +00002871 if (LocaleCompare((const char *) tag,"enhance") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002872 {
2873 Image
2874 *enhance_image;
2875
2876 /*
2877 Enhance image.
2878 */
2879 if (msl_info->image[n] == (Image *) NULL)
2880 {
cristyb988fe72009-09-16 01:01:10 +00002881 ThrowMSLException(OptionError,"NoImagesDefined",
2882 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002883 break;
2884 }
2885 if (attributes != (const xmlChar **) NULL)
2886 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2887 {
2888 keyword=(const char *) attributes[i++];
2889 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002890 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00002891 exception);
cristy3ed852e2009-09-05 21:47:34 +00002892 CloneString(&value,attribute);
2893 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
2894 }
2895 enhance_image=EnhanceImage(msl_info->image[n],
cristyc82a27b2011-10-21 01:07:16 +00002896 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00002897 if (enhance_image == (Image *) NULL)
2898 break;
2899 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2900 msl_info->image[n]=enhance_image;
2901 break;
2902 }
cristyb988fe72009-09-16 01:01:10 +00002903 if (LocaleCompare((const char *) tag,"equalize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002904 {
2905 /*
2906 Equalize image.
2907 */
2908 if (msl_info->image[n] == (Image *) NULL)
2909 {
cristyb988fe72009-09-16 01:01:10 +00002910 ThrowMSLException(OptionError,"NoImagesDefined",
2911 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002912 break;
2913 }
2914 if (attributes != (const xmlChar **) NULL)
2915 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2916 {
2917 keyword=(const char *) attributes[i++];
2918 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002919 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00002920 exception);
cristy3ed852e2009-09-05 21:47:34 +00002921 CloneString(&value,attribute);
2922 switch (*keyword)
2923 {
2924 default:
2925 {
2926 ThrowMSLException(OptionError,"UnrecognizedAttribute",
2927 keyword);
2928 break;
2929 }
2930 }
2931 }
cristy6d8c3d72011-08-22 01:20:01 +00002932 (void) EqualizeImage(msl_info->image[n],
cristyc82a27b2011-10-21 01:07:16 +00002933 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00002934 break;
2935 }
2936 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
2937 }
2938 case 'F':
2939 case 'f':
2940 {
cristyb988fe72009-09-16 01:01:10 +00002941 if (LocaleCompare((const char *) tag, "flatten") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002942 {
2943 if (msl_info->image[n] == (Image *) NULL)
2944 {
cristyb988fe72009-09-16 01:01:10 +00002945 ThrowMSLException(OptionError,"NoImagesDefined",
2946 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002947 break;
2948 }
2949
2950 /* no attributes here */
2951
2952 /* process the image */
2953 {
2954 Image
2955 *newImage;
2956
2957 newImage=MergeImageLayers(msl_info->image[n],FlattenLayer,
cristyc82a27b2011-10-21 01:07:16 +00002958 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00002959 if (newImage == (Image *) NULL)
2960 break;
2961 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2962 msl_info->image[n]=newImage;
2963 break;
2964 }
2965 }
cristyb988fe72009-09-16 01:01:10 +00002966 if (LocaleCompare((const char *) tag,"flip") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002967 {
2968 Image
2969 *flip_image;
2970
2971 /*
2972 Flip image.
2973 */
2974 if (msl_info->image[n] == (Image *) NULL)
2975 {
cristyb988fe72009-09-16 01:01:10 +00002976 ThrowMSLException(OptionError,"NoImagesDefined",
2977 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00002978 break;
2979 }
2980 if (attributes != (const xmlChar **) NULL)
2981 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
2982 {
2983 keyword=(const char *) attributes[i++];
2984 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00002985 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00002986 exception);
cristy3ed852e2009-09-05 21:47:34 +00002987 CloneString(&value,attribute);
2988 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
2989 }
2990 flip_image=FlipImage(msl_info->image[n],
cristyc82a27b2011-10-21 01:07:16 +00002991 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00002992 if (flip_image == (Image *) NULL)
2993 break;
2994 msl_info->image[n]=DestroyImage(msl_info->image[n]);
2995 msl_info->image[n]=flip_image;
2996 break;
2997 }
cristyb988fe72009-09-16 01:01:10 +00002998 if (LocaleCompare((const char *) tag,"flop") == 0)
cristy3ed852e2009-09-05 21:47:34 +00002999 {
3000 Image
3001 *flop_image;
3002
3003 /*
3004 Flop image.
3005 */
3006 if (msl_info->image[n] == (Image *) NULL)
3007 {
cristyb988fe72009-09-16 01:01:10 +00003008 ThrowMSLException(OptionError,"NoImagesDefined",
3009 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003010 break;
3011 }
3012 if (attributes != (const xmlChar **) NULL)
3013 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3014 {
3015 keyword=(const char *) attributes[i++];
3016 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003017 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00003018 exception);
cristy3ed852e2009-09-05 21:47:34 +00003019 CloneString(&value,attribute);
3020 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3021 }
3022 flop_image=FlopImage(msl_info->image[n],
cristyc82a27b2011-10-21 01:07:16 +00003023 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00003024 if (flop_image == (Image *) NULL)
3025 break;
3026 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3027 msl_info->image[n]=flop_image;
3028 break;
3029 }
cristyb988fe72009-09-16 01:01:10 +00003030 if (LocaleCompare((const char *) tag,"frame") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003031 {
3032 FrameInfo
3033 frame_info;
3034
3035 Image
3036 *frame_image;
3037
3038 /*
3039 Frame image.
3040 */
3041 if (msl_info->image[n] == (Image *) NULL)
3042 {
cristyb988fe72009-09-16 01:01:10 +00003043 ThrowMSLException(OptionError,"NoImagesDefined",
3044 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003045 break;
3046 }
cristy3e410e22014-07-25 16:24:50 +00003047 (void) ResetMagickMemory(&frame_info,0,sizeof(frame_info));
cristy3ed852e2009-09-05 21:47:34 +00003048 SetGeometry(msl_info->image[n],&geometry);
3049 if (attributes != (const xmlChar **) NULL)
3050 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3051 {
3052 keyword=(const char *) attributes[i++];
3053 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003054 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00003055 exception);
cristy3ed852e2009-09-05 21:47:34 +00003056 CloneString(&value,attribute);
3057 switch (*keyword)
3058 {
3059 case 'C':
3060 case 'c':
3061 {
3062 if (LocaleCompare(keyword,"compose") == 0)
3063 {
cristy042ee782011-04-22 18:48:30 +00003064 option=ParseCommandOption(MagickComposeOptions,
cristy3ed852e2009-09-05 21:47:34 +00003065 MagickFalse,value);
3066 if (option < 0)
3067 ThrowMSLException(OptionError,"UnrecognizedComposeType",
3068 value);
3069 msl_info->image[n]->compose=(CompositeOperator) option;
3070 break;
3071 }
3072 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3073 keyword);
3074 break;
3075 }
3076 case 'F':
3077 case 'f':
3078 {
3079 if (LocaleCompare(keyword, "fill") == 0)
3080 {
cristy9950d572011-10-01 18:22:35 +00003081 (void) QueryColorCompliance(value,AllCompliance,
dirk6d6d5f22014-06-20 11:48:54 +00003082 &msl_info->image[n]->matte_color,exception);
cristy3ed852e2009-09-05 21:47:34 +00003083 break;
3084 }
3085 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3086 keyword);
3087 break;
3088 }
3089 case 'G':
3090 case 'g':
3091 {
3092 if (LocaleCompare(keyword,"geometry") == 0)
3093 {
3094 flags=ParsePageGeometry(msl_info->image[n],value,
dirk6d6d5f22014-06-20 11:48:54 +00003095 &geometry,exception);
cristy3ed852e2009-09-05 21:47:34 +00003096 if ((flags & HeightValue) == 0)
3097 geometry.height=geometry.width;
3098 frame_info.width=geometry.width;
3099 frame_info.height=geometry.height;
3100 frame_info.outer_bevel=geometry.x;
3101 frame_info.inner_bevel=geometry.y;
3102 break;
3103 }
3104 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3105 keyword);
3106 break;
3107 }
3108 case 'H':
3109 case 'h':
3110 {
3111 if (LocaleCompare(keyword,"height") == 0)
3112 {
cristyf2f27272009-12-17 14:48:46 +00003113 frame_info.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003114 break;
3115 }
3116 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3117 keyword);
3118 break;
3119 }
3120 case 'I':
3121 case 'i':
3122 {
3123 if (LocaleCompare(keyword,"inner") == 0)
3124 {
cristyf2f27272009-12-17 14:48:46 +00003125 frame_info.inner_bevel=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003126 break;
3127 }
3128 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3129 keyword);
3130 break;
3131 }
3132 case 'O':
3133 case 'o':
3134 {
3135 if (LocaleCompare(keyword,"outer") == 0)
3136 {
cristyf2f27272009-12-17 14:48:46 +00003137 frame_info.outer_bevel=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003138 break;
3139 }
3140 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3141 keyword);
3142 break;
3143 }
3144 case 'W':
3145 case 'w':
3146 {
3147 if (LocaleCompare(keyword,"width") == 0)
3148 {
cristyf2f27272009-12-17 14:48:46 +00003149 frame_info.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00003150 break;
3151 }
3152 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3153 keyword);
3154 break;
3155 }
3156 default:
3157 {
3158 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3159 keyword);
3160 break;
3161 }
3162 }
3163 }
cristybb503372010-05-27 20:51:26 +00003164 frame_info.x=(ssize_t) frame_info.width;
3165 frame_info.y=(ssize_t) frame_info.height;
cristy3ed852e2009-09-05 21:47:34 +00003166 frame_info.width=msl_info->image[n]->columns+2*frame_info.x;
3167 frame_info.height=msl_info->image[n]->rows+2*frame_info.y;
3168 frame_image=FrameImage(msl_info->image[n],&frame_info,
cristyc82a27b2011-10-21 01:07:16 +00003169 msl_info->image[n]->compose,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00003170 if (frame_image == (Image *) NULL)
3171 break;
3172 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3173 msl_info->image[n]=frame_image;
3174 break;
3175 }
3176 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3177 }
3178 case 'G':
3179 case 'g':
3180 {
cristyb988fe72009-09-16 01:01:10 +00003181 if (LocaleCompare((const char *) tag,"gamma") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003182 {
3183 char
cristy151b66d2015-04-15 10:50:31 +00003184 gamma[MagickPathExtent];
cristy3ed852e2009-09-05 21:47:34 +00003185
cristy4c08aed2011-07-01 19:47:50 +00003186 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00003187 pixel;
3188
3189 /*
3190 Gamma image.
3191 */
3192 if (msl_info->image[n] == (Image *) NULL)
3193 {
cristyb988fe72009-09-16 01:01:10 +00003194 ThrowMSLException(OptionError,"NoImagesDefined",
3195 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003196 break;
3197 }
3198 channel=UndefinedChannel;
3199 pixel.red=0.0;
3200 pixel.green=0.0;
3201 pixel.blue=0.0;
3202 *gamma='\0';
3203 if (attributes != (const xmlChar **) NULL)
3204 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3205 {
3206 keyword=(const char *) attributes[i++];
3207 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003208 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00003209 exception);
cristy3ed852e2009-09-05 21:47:34 +00003210 CloneString(&value,attribute);
3211 switch (*keyword)
3212 {
3213 case 'B':
3214 case 'b':
3215 {
3216 if (LocaleCompare(keyword,"blue") == 0)
3217 {
cristydbdd0e32011-11-04 23:29:40 +00003218 pixel.blue=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003219 break;
3220 }
3221 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3222 keyword);
3223 break;
3224 }
3225 case 'C':
3226 case 'c':
3227 {
3228 if (LocaleCompare(keyword,"channel") == 0)
3229 {
3230 option=ParseChannelOption(value);
3231 if (option < 0)
3232 ThrowMSLException(OptionError,"UnrecognizedChannelType",
3233 value);
3234 channel=(ChannelType) option;
3235 break;
3236 }
3237 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3238 keyword);
3239 break;
3240 }
3241 case 'G':
3242 case 'g':
3243 {
3244 if (LocaleCompare(keyword,"gamma") == 0)
3245 {
cristy151b66d2015-04-15 10:50:31 +00003246 (void) CopyMagickString(gamma,value,MagickPathExtent);
cristy3ed852e2009-09-05 21:47:34 +00003247 break;
3248 }
3249 if (LocaleCompare(keyword,"green") == 0)
3250 {
cristydbdd0e32011-11-04 23:29:40 +00003251 pixel.green=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003252 break;
3253 }
3254 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3255 keyword);
3256 break;
3257 }
3258 case 'R':
3259 case 'r':
3260 {
3261 if (LocaleCompare(keyword,"red") == 0)
3262 {
cristydbdd0e32011-11-04 23:29:40 +00003263 pixel.red=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003264 break;
3265 }
3266 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3267 keyword);
3268 break;
3269 }
3270 default:
3271 {
3272 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3273 keyword);
3274 break;
3275 }
3276 }
3277 }
3278 if (*gamma == '\0')
cristy151b66d2015-04-15 10:50:31 +00003279 (void) FormatLocaleString(gamma,MagickPathExtent,"%g,%g,%g",
cristy3ed852e2009-09-05 21:47:34 +00003280 (double) pixel.red,(double) pixel.green,(double) pixel.blue);
cristy79d05312014-12-25 18:13:29 +00003281 (void) GammaImage(msl_info->image[n],strtod(gamma,(char **) NULL),
cristyc82a27b2011-10-21 01:07:16 +00003282 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00003283 break;
3284 }
cristyb988fe72009-09-16 01:01:10 +00003285 else if (LocaleCompare((const char *) tag,"get") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003286 {
3287 if (msl_info->image[n] == (Image *) NULL)
3288 {
cristyb988fe72009-09-16 01:01:10 +00003289 ThrowMSLException(OptionError,"NoImagesDefined",
3290 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003291 break;
3292 }
3293 if (attributes == (const xmlChar **) NULL)
3294 break;
3295 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3296 {
3297 keyword=(const char *) attributes[i++];
cristyb988fe72009-09-16 01:01:10 +00003298 CloneString(&value,(const char *) attributes[i]);
cristy151b66d2015-04-15 10:50:31 +00003299 (void) CopyMagickString(key,value,MagickPathExtent);
cristy3ed852e2009-09-05 21:47:34 +00003300 switch (*keyword)
3301 {
3302 case 'H':
3303 case 'h':
3304 {
3305 if (LocaleCompare(keyword,"height") == 0)
3306 {
cristy151b66d2015-04-15 10:50:31 +00003307 (void) FormatLocaleString(value,MagickPathExtent,"%.20g",
cristye8c25f92010-06-03 00:53:06 +00003308 (double) msl_info->image[n]->rows);
cristyd15e6592011-10-15 00:13:06 +00003309 (void) SetImageProperty(msl_info->attributes[n],key,value,
dirk6d6d5f22014-06-20 11:48:54 +00003310 exception);
cristy3ed852e2009-09-05 21:47:34 +00003311 break;
3312 }
3313 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3314 }
3315 case 'W':
3316 case 'w':
3317 {
3318 if (LocaleCompare(keyword,"width") == 0)
3319 {
cristy151b66d2015-04-15 10:50:31 +00003320 (void) FormatLocaleString(value,MagickPathExtent,"%.20g",
cristye8c25f92010-06-03 00:53:06 +00003321 (double) msl_info->image[n]->columns);
cristyd15e6592011-10-15 00:13:06 +00003322 (void) SetImageProperty(msl_info->attributes[n],key,value,
dirk6d6d5f22014-06-20 11:48:54 +00003323 exception);
cristy3ed852e2009-09-05 21:47:34 +00003324 break;
3325 }
3326 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3327 }
3328 default:
3329 {
3330 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3331 break;
3332 }
3333 }
3334 }
3335 break;
3336 }
cristyb988fe72009-09-16 01:01:10 +00003337 else if (LocaleCompare((const char *) tag, "group") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003338 {
3339 msl_info->number_groups++;
3340 msl_info->group_info=(MSLGroupInfo *) ResizeQuantumMemory(
3341 msl_info->group_info,msl_info->number_groups+1UL,
3342 sizeof(*msl_info->group_info));
3343 break;
3344 }
3345 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3346 }
3347 case 'I':
3348 case 'i':
3349 {
cristyb988fe72009-09-16 01:01:10 +00003350 if (LocaleCompare((const char *) tag,"image") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003351 {
cristy3ed852e2009-09-05 21:47:34 +00003352 MSLPushImage(msl_info,(Image *) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003353 if (attributes == (const xmlChar **) NULL)
3354 break;
3355 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3356 {
3357 keyword=(const char *) attributes[i++];
3358 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
dirk6d6d5f22014-06-20 11:48:54 +00003359 msl_info->attributes[n],(const char *) attributes[i],exception));
cristy3ed852e2009-09-05 21:47:34 +00003360 switch (*keyword)
3361 {
cristyb988fe72009-09-16 01:01:10 +00003362 case 'C':
3363 case 'c':
cristy3ed852e2009-09-05 21:47:34 +00003364 {
cristyb988fe72009-09-16 01:01:10 +00003365 if (LocaleCompare(keyword,"color") == 0)
3366 {
3367 Image
3368 *next_image;
cristy3ed852e2009-09-05 21:47:34 +00003369
cristyb988fe72009-09-16 01:01:10 +00003370 (void) CopyMagickString(msl_info->image_info[n]->filename,
cristy151b66d2015-04-15 10:50:31 +00003371 "xc:",MagickPathExtent);
cristyb988fe72009-09-16 01:01:10 +00003372 (void) ConcatenateMagickString(msl_info->image_info[n]->
cristy151b66d2015-04-15 10:50:31 +00003373 filename,value,MagickPathExtent);
dirk6d6d5f22014-06-20 11:48:54 +00003374 next_image=ReadImage(msl_info->image_info[n],exception);
3375 CatchException(exception);
cristyb988fe72009-09-16 01:01:10 +00003376 if (next_image == (Image *) NULL)
3377 continue;
3378 if (msl_info->image[n] == (Image *) NULL)
3379 msl_info->image[n]=next_image;
3380 else
3381 {
3382 register Image
3383 *p;
cristy3ed852e2009-09-05 21:47:34 +00003384
cristyb988fe72009-09-16 01:01:10 +00003385 /*
3386 Link image into image list.
3387 */
3388 p=msl_info->image[n];
3389 while (p->next != (Image *) NULL)
3390 p=GetNextImageInList(p);
3391 next_image->previous=p;
3392 p->next=next_image;
3393 }
3394 break;
3395 }
cristyb20775d2009-09-16 01:51:41 +00003396 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00003397 break;
3398 }
3399 default:
3400 {
cristyb20775d2009-09-16 01:51:41 +00003401 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00003402 break;
3403 }
3404 }
3405 }
3406 break;
3407 }
cristyb988fe72009-09-16 01:01:10 +00003408 if (LocaleCompare((const char *) tag,"implode") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003409 {
3410 Image
3411 *implode_image;
3412
3413 /*
3414 Implode image.
3415 */
3416 if (msl_info->image[n] == (Image *) NULL)
3417 {
cristyb988fe72009-09-16 01:01:10 +00003418 ThrowMSLException(OptionError,"NoImagesDefined",
3419 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003420 break;
3421 }
3422 if (attributes != (const xmlChar **) NULL)
3423 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3424 {
3425 keyword=(const char *) attributes[i++];
3426 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003427 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00003428 exception);
cristy3ed852e2009-09-05 21:47:34 +00003429 CloneString(&value,attribute);
3430 switch (*keyword)
3431 {
3432 case 'A':
3433 case 'a':
3434 {
3435 if (LocaleCompare(keyword,"amount") == 0)
3436 {
cristydbdd0e32011-11-04 23:29:40 +00003437 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00003438 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003439 break;
3440 }
3441 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3442 keyword);
3443 break;
3444 }
3445 case 'G':
3446 case 'g':
3447 {
3448 if (LocaleCompare(keyword,"geometry") == 0)
3449 {
3450 flags=ParseGeometry(value,&geometry_info);
3451 if ((flags & SigmaValue) == 0)
3452 geometry_info.sigma=1.0;
3453 break;
3454 }
3455 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3456 keyword);
3457 break;
3458 }
3459 default:
3460 {
3461 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3462 keyword);
3463 break;
3464 }
3465 }
3466 }
3467 implode_image=ImplodeImage(msl_info->image[n],geometry_info.rho,
cristyc82a27b2011-10-21 01:07:16 +00003468 msl_info->image[n]->interpolate,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00003469 if (implode_image == (Image *) NULL)
3470 break;
3471 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3472 msl_info->image[n]=implode_image;
3473 break;
3474 }
3475 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
3476 }
3477 case 'L':
3478 case 'l':
3479 {
cristyb988fe72009-09-16 01:01:10 +00003480 if (LocaleCompare((const char *) tag,"label") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003481 break;
cristyb988fe72009-09-16 01:01:10 +00003482 if (LocaleCompare((const char *) tag, "level") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003483 {
3484 double
3485 levelBlack = 0, levelGamma = 1, levelWhite = QuantumRange;
3486
3487 if (msl_info->image[n] == (Image *) NULL)
3488 {
cristyb988fe72009-09-16 01:01:10 +00003489 ThrowMSLException(OptionError,"NoImagesDefined",
3490 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003491 break;
3492 }
3493 if (attributes == (const xmlChar **) NULL)
3494 break;
3495 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3496 {
3497 keyword=(const char *) attributes[i++];
cristyb988fe72009-09-16 01:01:10 +00003498 CloneString(&value,(const char *) attributes[i]);
cristy151b66d2015-04-15 10:50:31 +00003499 (void) CopyMagickString(key,value,MagickPathExtent);
cristy3ed852e2009-09-05 21:47:34 +00003500 switch (*keyword)
3501 {
3502 case 'B':
3503 case 'b':
3504 {
3505 if (LocaleCompare(keyword,"black") == 0)
3506 {
cristydbdd0e32011-11-04 23:29:40 +00003507 levelBlack = StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003508 break;
3509 }
3510 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3511 break;
3512 }
3513 case 'G':
3514 case 'g':
3515 {
3516 if (LocaleCompare(keyword,"gamma") == 0)
3517 {
cristydbdd0e32011-11-04 23:29:40 +00003518 levelGamma = StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003519 break;
3520 }
3521 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3522 break;
3523 }
3524 case 'W':
3525 case 'w':
3526 {
3527 if (LocaleCompare(keyword,"white") == 0)
3528 {
cristydbdd0e32011-11-04 23:29:40 +00003529 levelWhite = StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003530 break;
3531 }
3532 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3533 break;
3534 }
3535 default:
3536 {
3537 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3538 break;
3539 }
3540 }
3541 }
3542
3543 /* process image */
cristy01e9afd2011-08-10 17:38:41 +00003544 LevelImage(msl_info->image[n],levelBlack,levelWhite,levelGamma,
cristyc82a27b2011-10-21 01:07:16 +00003545 msl_info->exception);
cristyf89cb1d2011-07-07 01:24:37 +00003546 break;
cristy3ed852e2009-09-05 21:47:34 +00003547 }
3548 }
3549 case 'M':
3550 case 'm':
3551 {
cristyb988fe72009-09-16 01:01:10 +00003552 if (LocaleCompare((const char *) tag,"magnify") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003553 {
3554 Image
3555 *magnify_image;
3556
3557 /*
3558 Magnify image.
3559 */
3560 if (msl_info->image[n] == (Image *) NULL)
3561 {
cristyb988fe72009-09-16 01:01:10 +00003562 ThrowMSLException(OptionError,"NoImagesDefined",
3563 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003564 break;
3565 }
3566 if (attributes != (const xmlChar **) NULL)
3567 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3568 {
3569 keyword=(const char *) attributes[i++];
3570 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003571 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00003572 exception);
cristy3ed852e2009-09-05 21:47:34 +00003573 CloneString(&value,attribute);
3574 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3575 }
3576 magnify_image=MagnifyImage(msl_info->image[n],
cristyc82a27b2011-10-21 01:07:16 +00003577 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00003578 if (magnify_image == (Image *) NULL)
3579 break;
3580 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3581 msl_info->image[n]=magnify_image;
3582 break;
3583 }
cristyb988fe72009-09-16 01:01:10 +00003584 if (LocaleCompare((const char *) tag,"map") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003585 {
3586 Image
3587 *affinity_image;
3588
3589 MagickBooleanType
3590 dither;
3591
3592 QuantizeInfo
3593 *quantize_info;
3594
3595 /*
3596 Map image.
3597 */
3598 if (msl_info->image[n] == (Image *) NULL)
3599 {
cristyb988fe72009-09-16 01:01:10 +00003600 ThrowMSLException(OptionError,"NoImagesDefined",
3601 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003602 break;
3603 }
3604 affinity_image=NewImageList();
3605 dither=MagickFalse;
3606 if (attributes != (const xmlChar **) NULL)
3607 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3608 {
3609 keyword=(const char *) attributes[i++];
3610 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003611 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00003612 exception);
cristy3ed852e2009-09-05 21:47:34 +00003613 CloneString(&value,attribute);
3614 switch (*keyword)
3615 {
3616 case 'D':
3617 case 'd':
3618 {
3619 if (LocaleCompare(keyword,"dither") == 0)
3620 {
cristy042ee782011-04-22 18:48:30 +00003621 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00003622 value);
3623 if (option < 0)
3624 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
3625 value);
3626 dither=(MagickBooleanType) option;
3627 break;
3628 }
3629 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3630 keyword);
3631 break;
3632 }
3633 case 'I':
3634 case 'i':
3635 {
3636 if (LocaleCompare(keyword,"image") == 0)
3637 for (j=0; j < msl_info->n; j++)
3638 {
3639 const char
3640 *attribute;
cristyb988fe72009-09-16 01:01:10 +00003641
cristyd15e6592011-10-15 00:13:06 +00003642 attribute=GetImageProperty(msl_info->attributes[j],"id",
dirk6d6d5f22014-06-20 11:48:54 +00003643 exception);
cristy3ed852e2009-09-05 21:47:34 +00003644 if ((attribute != (const char *) NULL) &&
3645 (LocaleCompare(attribute,value) == 0))
3646 {
3647 affinity_image=CloneImage(msl_info->image[j],0,0,
dirk6d6d5f22014-06-20 11:48:54 +00003648 MagickFalse,exception);
cristy3ed852e2009-09-05 21:47:34 +00003649 break;
3650 }
3651 }
3652 break;
3653 }
3654 default:
3655 {
3656 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3657 keyword);
3658 break;
3659 }
3660 }
3661 }
3662 quantize_info=AcquireQuantizeInfo(msl_info->image_info[n]);
cristycbda6112012-05-27 20:57:16 +00003663 quantize_info->dither_method=dither != MagickFalse ?
3664 RiemersmaDitherMethod : NoDitherMethod;
cristy3ed852e2009-09-05 21:47:34 +00003665 (void) RemapImages(quantize_info,msl_info->image[n],
dirk6d6d5f22014-06-20 11:48:54 +00003666 affinity_image,exception);
cristy3ed852e2009-09-05 21:47:34 +00003667 quantize_info=DestroyQuantizeInfo(quantize_info);
3668 affinity_image=DestroyImage(affinity_image);
3669 break;
3670 }
cristyb988fe72009-09-16 01:01:10 +00003671 if (LocaleCompare((const char *) tag,"matte-floodfill") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003672 {
3673 double
3674 opacity;
3675
cristy4c08aed2011-07-01 19:47:50 +00003676 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00003677 target;
3678
3679 PaintMethod
3680 paint_method;
3681
3682 /*
3683 Matte floodfill image.
3684 */
3685 opacity=0.0;
3686 if (msl_info->image[n] == (Image *) NULL)
3687 {
cristyb988fe72009-09-16 01:01:10 +00003688 ThrowMSLException(OptionError,"NoImagesDefined",
3689 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003690 break;
3691 }
3692 SetGeometry(msl_info->image[n],&geometry);
3693 paint_method=FloodfillMethod;
3694 if (attributes != (const xmlChar **) NULL)
3695 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3696 {
3697 keyword=(const char *) attributes[i++];
3698 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003699 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00003700 exception);
cristy3ed852e2009-09-05 21:47:34 +00003701 CloneString(&value,attribute);
3702 switch (*keyword)
3703 {
3704 case 'B':
3705 case 'b':
3706 {
3707 if (LocaleCompare(keyword,"bordercolor") == 0)
3708 {
cristy269c9412011-10-13 23:41:15 +00003709 (void) QueryColorCompliance(value,AllCompliance,
dirk6d6d5f22014-06-20 11:48:54 +00003710 &target,exception);
cristy3ed852e2009-09-05 21:47:34 +00003711 paint_method=FillToBorderMethod;
3712 break;
3713 }
3714 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3715 keyword);
3716 break;
3717 }
3718 case 'F':
3719 case 'f':
3720 {
3721 if (LocaleCompare(keyword,"fuzz") == 0)
3722 {
cristydbdd0e32011-11-04 23:29:40 +00003723 msl_info->image[n]->fuzz=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00003724 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003725 break;
3726 }
3727 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3728 keyword);
3729 break;
3730 }
3731 case 'G':
3732 case 'g':
3733 {
3734 if (LocaleCompare(keyword,"geometry") == 0)
3735 {
3736 flags=ParsePageGeometry(msl_info->image[n],value,
dirk6d6d5f22014-06-20 11:48:54 +00003737 &geometry,exception);
cristy3ed852e2009-09-05 21:47:34 +00003738 if ((flags & HeightValue) == 0)
3739 geometry.height=geometry.width;
cristy3aa93752011-12-18 15:54:24 +00003740 (void) GetOneVirtualPixelInfo(msl_info->image[n],
cristy33e9da62011-10-21 19:08:58 +00003741 TileVirtualPixelMethod,geometry.x,geometry.y,&target,
dirk6d6d5f22014-06-20 11:48:54 +00003742 exception);
cristy3ed852e2009-09-05 21:47:34 +00003743 break;
3744 }
3745 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3746 keyword);
3747 break;
3748 }
3749 case 'O':
3750 case 'o':
3751 {
3752 if (LocaleCompare(keyword,"opacity") == 0)
3753 {
cristydbdd0e32011-11-04 23:29:40 +00003754 opacity=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003755 break;
3756 }
3757 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3758 keyword);
3759 break;
3760 }
3761 case 'X':
3762 case 'x':
3763 {
3764 if (LocaleCompare(keyword,"x") == 0)
3765 {
cristyf2f27272009-12-17 14:48:46 +00003766 geometry.x=StringToLong(value);
cristy3aa93752011-12-18 15:54:24 +00003767 (void) GetOneVirtualPixelInfo(msl_info->image[n],
cristy33e9da62011-10-21 19:08:58 +00003768 TileVirtualPixelMethod,geometry.x,geometry.y,&target,
dirk6d6d5f22014-06-20 11:48:54 +00003769 exception);
cristy3ed852e2009-09-05 21:47:34 +00003770 break;
3771 }
3772 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3773 keyword);
3774 break;
3775 }
3776 case 'Y':
3777 case 'y':
3778 {
3779 if (LocaleCompare(keyword,"y") == 0)
3780 {
cristyf2f27272009-12-17 14:48:46 +00003781 geometry.y=StringToLong(value);
cristy3aa93752011-12-18 15:54:24 +00003782 (void) GetOneVirtualPixelInfo(msl_info->image[n],
cristy33e9da62011-10-21 19:08:58 +00003783 TileVirtualPixelMethod,geometry.x,geometry.y,&target,
dirk6d6d5f22014-06-20 11:48:54 +00003784 exception);
cristy3ed852e2009-09-05 21:47:34 +00003785 break;
3786 }
3787 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3788 keyword);
3789 break;
3790 }
3791 default:
3792 {
3793 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3794 keyword);
3795 break;
3796 }
3797 }
3798 }
3799 draw_info=CloneDrawInfo(msl_info->image_info[n],
3800 msl_info->draw_info[n]);
cristy4c08aed2011-07-01 19:47:50 +00003801 draw_info->fill.alpha=ClampToQuantum(opacity);
cristycf1296e2012-08-26 23:40:49 +00003802 channel_mask=SetImageChannelMask(msl_info->image[n],AlphaChannel);
cristyd42d9952011-07-08 14:21:50 +00003803 (void) FloodfillPaintImage(msl_info->image[n],draw_info,&target,
3804 geometry.x,geometry.y,paint_method == FloodfillMethod ?
cristyc82a27b2011-10-21 01:07:16 +00003805 MagickFalse : MagickTrue,msl_info->exception);
cristycf1296e2012-08-26 23:40:49 +00003806 (void) SetPixelChannelMask(msl_info->image[n],channel_mask);
cristy3ed852e2009-09-05 21:47:34 +00003807 draw_info=DestroyDrawInfo(draw_info);
3808 break;
3809 }
cristyb988fe72009-09-16 01:01:10 +00003810 if (LocaleCompare((const char *) tag,"median-filter") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003811 {
3812 Image
3813 *median_image;
3814
3815 /*
3816 Median-filter image.
3817 */
3818 if (msl_info->image[n] == (Image *) NULL)
3819 {
cristyb988fe72009-09-16 01:01:10 +00003820 ThrowMSLException(OptionError,"NoImagesDefined",
3821 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003822 break;
3823 }
3824 if (attributes != (const xmlChar **) NULL)
3825 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3826 {
3827 keyword=(const char *) attributes[i++];
3828 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003829 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00003830 exception);
cristy3ed852e2009-09-05 21:47:34 +00003831 CloneString(&value,attribute);
3832 switch (*keyword)
3833 {
3834 case 'G':
3835 case 'g':
3836 {
3837 if (LocaleCompare(keyword,"geometry") == 0)
3838 {
3839 flags=ParseGeometry(value,&geometry_info);
3840 if ((flags & SigmaValue) == 0)
3841 geometry_info.sigma=1.0;
3842 break;
3843 }
3844 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3845 keyword);
3846 break;
3847 }
3848 case 'R':
3849 case 'r':
3850 {
3851 if (LocaleCompare(keyword,"radius") == 0)
3852 {
cristydbdd0e32011-11-04 23:29:40 +00003853 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00003854 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003855 break;
3856 }
3857 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3858 keyword);
3859 break;
3860 }
3861 default:
3862 {
3863 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3864 keyword);
3865 break;
3866 }
3867 }
3868 }
cristy733678d2011-03-18 21:29:28 +00003869 median_image=StatisticImage(msl_info->image[n],MedianStatistic,
cristy95c38342011-03-18 22:39:51 +00003870 (size_t) geometry_info.rho,(size_t) geometry_info.sigma,
cristyc82a27b2011-10-21 01:07:16 +00003871 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00003872 if (median_image == (Image *) NULL)
3873 break;
3874 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3875 msl_info->image[n]=median_image;
3876 break;
3877 }
cristyb988fe72009-09-16 01:01:10 +00003878 if (LocaleCompare((const char *) tag,"minify") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003879 {
3880 Image
3881 *minify_image;
3882
3883 /*
3884 Minify image.
3885 */
3886 if (msl_info->image[n] == (Image *) NULL)
3887 {
cristyb988fe72009-09-16 01:01:10 +00003888 ThrowMSLException(OptionError,"NoImagesDefined",
3889 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003890 break;
3891 }
3892 if (attributes != (const xmlChar **) NULL)
3893 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3894 {
3895 keyword=(const char *) attributes[i++];
3896 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003897 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00003898 exception);
cristy3ed852e2009-09-05 21:47:34 +00003899 CloneString(&value,attribute);
3900 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
3901 }
3902 minify_image=MinifyImage(msl_info->image[n],
cristyc82a27b2011-10-21 01:07:16 +00003903 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00003904 if (minify_image == (Image *) NULL)
3905 break;
3906 msl_info->image[n]=DestroyImage(msl_info->image[n]);
3907 msl_info->image[n]=minify_image;
3908 break;
3909 }
cristyb988fe72009-09-16 01:01:10 +00003910 if (LocaleCompare((const char *) tag,"msl") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00003911 break;
cristyb988fe72009-09-16 01:01:10 +00003912 if (LocaleCompare((const char *) tag,"modulate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00003913 {
3914 char
cristy151b66d2015-04-15 10:50:31 +00003915 modulate[MagickPathExtent];
cristy3ed852e2009-09-05 21:47:34 +00003916
3917 /*
3918 Modulate image.
3919 */
3920 if (msl_info->image[n] == (Image *) NULL)
3921 {
cristyb988fe72009-09-16 01:01:10 +00003922 ThrowMSLException(OptionError,"NoImagesDefined",
3923 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00003924 break;
3925 }
3926 geometry_info.rho=100.0;
3927 geometry_info.sigma=100.0;
3928 geometry_info.xi=100.0;
3929 if (attributes != (const xmlChar **) NULL)
3930 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
3931 {
3932 keyword=(const char *) attributes[i++];
3933 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00003934 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00003935 exception);
cristy3ed852e2009-09-05 21:47:34 +00003936 CloneString(&value,attribute);
3937 switch (*keyword)
3938 {
3939 case 'B':
3940 case 'b':
3941 {
3942 if (LocaleCompare(keyword,"blackness") == 0)
3943 {
cristydbdd0e32011-11-04 23:29:40 +00003944 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00003945 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003946 break;
3947 }
3948 if (LocaleCompare(keyword,"brightness") == 0)
3949 {
cristydbdd0e32011-11-04 23:29:40 +00003950 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00003951 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003952 break;
3953 }
3954 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3955 keyword);
3956 break;
3957 }
3958 case 'F':
3959 case 'f':
3960 {
3961 if (LocaleCompare(keyword,"factor") == 0)
3962 {
3963 flags=ParseGeometry(value,&geometry_info);
3964 break;
3965 }
3966 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3967 keyword);
3968 break;
3969 }
3970 case 'H':
3971 case 'h':
3972 {
3973 if (LocaleCompare(keyword,"hue") == 0)
3974 {
cristydbdd0e32011-11-04 23:29:40 +00003975 geometry_info.xi=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00003976 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003977 break;
3978 }
3979 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3980 keyword);
3981 break;
3982 }
3983 case 'L':
3984 case 'l':
3985 {
3986 if (LocaleCompare(keyword,"lightness") == 0)
3987 {
cristydbdd0e32011-11-04 23:29:40 +00003988 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00003989 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00003990 break;
3991 }
3992 ThrowMSLException(OptionError,"UnrecognizedAttribute",
3993 keyword);
3994 break;
3995 }
3996 case 'S':
3997 case 's':
3998 {
3999 if (LocaleCompare(keyword,"saturation") == 0)
4000 {
cristydbdd0e32011-11-04 23:29:40 +00004001 geometry_info.sigma=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00004002 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004003 break;
4004 }
4005 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4006 keyword);
4007 break;
4008 }
4009 case 'W':
4010 case 'w':
4011 {
4012 if (LocaleCompare(keyword,"whiteness") == 0)
4013 {
cristydbdd0e32011-11-04 23:29:40 +00004014 geometry_info.sigma=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00004015 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004016 break;
4017 }
4018 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4019 keyword);
4020 break;
4021 }
4022 default:
4023 {
4024 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4025 keyword);
4026 break;
4027 }
4028 }
4029 }
cristy151b66d2015-04-15 10:50:31 +00004030 (void) FormatLocaleString(modulate,MagickPathExtent,"%g,%g,%g",
cristy3ed852e2009-09-05 21:47:34 +00004031 geometry_info.rho,geometry_info.sigma,geometry_info.xi);
cristy33bd5152011-08-24 01:42:24 +00004032 (void) ModulateImage(msl_info->image[n],modulate,
cristyc82a27b2011-10-21 01:07:16 +00004033 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00004034 break;
4035 }
4036 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4037 }
4038 case 'N':
4039 case 'n':
4040 {
cristyb988fe72009-09-16 01:01:10 +00004041 if (LocaleCompare((const char *) tag,"negate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004042 {
4043 MagickBooleanType
4044 gray;
4045
4046 /*
4047 Negate image.
4048 */
4049 if (msl_info->image[n] == (Image *) NULL)
4050 {
cristyb988fe72009-09-16 01:01:10 +00004051 ThrowMSLException(OptionError,"NoImagesDefined",
4052 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004053 break;
4054 }
4055 gray=MagickFalse;
4056 if (attributes != (const xmlChar **) NULL)
4057 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4058 {
4059 keyword=(const char *) attributes[i++];
4060 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004061 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00004062 exception);
cristy3ed852e2009-09-05 21:47:34 +00004063 CloneString(&value,attribute);
4064 switch (*keyword)
4065 {
4066 case 'C':
4067 case 'c':
4068 {
4069 if (LocaleCompare(keyword,"channel") == 0)
4070 {
4071 option=ParseChannelOption(value);
4072 if (option < 0)
4073 ThrowMSLException(OptionError,"UnrecognizedChannelType",
4074 value);
4075 channel=(ChannelType) option;
4076 break;
4077 }
4078 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4079 keyword);
4080 break;
4081 }
4082 case 'G':
4083 case 'g':
4084 {
4085 if (LocaleCompare(keyword,"gray") == 0)
4086 {
cristy042ee782011-04-22 18:48:30 +00004087 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004088 value);
4089 if (option < 0)
4090 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4091 value);
4092 gray=(MagickBooleanType) option;
4093 break;
4094 }
4095 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4096 keyword);
4097 break;
4098 }
4099 default:
4100 {
4101 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4102 keyword);
4103 break;
4104 }
4105 }
4106 }
cristycf1296e2012-08-26 23:40:49 +00004107 channel_mask=SetImageChannelMask(msl_info->image[n],channel);
cristyb3e7c6c2011-07-24 01:43:55 +00004108 (void) NegateImage(msl_info->image[n],gray,
cristyc82a27b2011-10-21 01:07:16 +00004109 msl_info->exception);
cristycf1296e2012-08-26 23:40:49 +00004110 (void) SetPixelChannelMask(msl_info->image[n],channel_mask);
cristy3ed852e2009-09-05 21:47:34 +00004111 break;
4112 }
cristyb988fe72009-09-16 01:01:10 +00004113 if (LocaleCompare((const char *) tag,"normalize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004114 {
4115 /*
4116 Normalize image.
4117 */
4118 if (msl_info->image[n] == (Image *) NULL)
4119 {
cristyb988fe72009-09-16 01:01:10 +00004120 ThrowMSLException(OptionError,"NoImagesDefined",
4121 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004122 break;
4123 }
4124 if (attributes != (const xmlChar **) NULL)
4125 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4126 {
4127 keyword=(const char *) attributes[i++];
4128 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004129 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00004130 exception);
cristy3ed852e2009-09-05 21:47:34 +00004131 CloneString(&value,attribute);
4132 switch (*keyword)
4133 {
4134 case 'C':
4135 case 'c':
4136 {
4137 if (LocaleCompare(keyword,"channel") == 0)
4138 {
4139 option=ParseChannelOption(value);
4140 if (option < 0)
4141 ThrowMSLException(OptionError,"UnrecognizedChannelType",
4142 value);
4143 channel=(ChannelType) option;
4144 break;
4145 }
4146 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4147 keyword);
4148 break;
4149 }
4150 default:
4151 {
4152 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4153 keyword);
4154 break;
4155 }
4156 }
4157 }
cristye23ec9d2011-08-16 18:15:40 +00004158 (void) NormalizeImage(msl_info->image[n],
cristyc82a27b2011-10-21 01:07:16 +00004159 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00004160 break;
4161 }
4162 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4163 }
4164 case 'O':
4165 case 'o':
4166 {
cristyb988fe72009-09-16 01:01:10 +00004167 if (LocaleCompare((const char *) tag,"oil-paint") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004168 {
4169 Image
4170 *paint_image;
4171
4172 /*
4173 Oil-paint image.
4174 */
4175 if (msl_info->image[n] == (Image *) NULL)
4176 {
cristyb988fe72009-09-16 01:01:10 +00004177 ThrowMSLException(OptionError,"NoImagesDefined",
4178 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004179 break;
4180 }
4181 if (attributes != (const xmlChar **) NULL)
4182 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4183 {
4184 keyword=(const char *) attributes[i++];
4185 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004186 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00004187 exception);
cristy3ed852e2009-09-05 21:47:34 +00004188 CloneString(&value,attribute);
4189 switch (*keyword)
4190 {
4191 case 'G':
4192 case 'g':
4193 {
4194 if (LocaleCompare(keyword,"geometry") == 0)
4195 {
4196 flags=ParseGeometry(value,&geometry_info);
4197 if ((flags & SigmaValue) == 0)
4198 geometry_info.sigma=1.0;
4199 break;
4200 }
4201 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4202 keyword);
4203 break;
4204 }
4205 case 'R':
4206 case 'r':
4207 {
4208 if (LocaleCompare(keyword,"radius") == 0)
4209 {
cristydbdd0e32011-11-04 23:29:40 +00004210 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00004211 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004212 break;
4213 }
4214 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4215 keyword);
4216 break;
4217 }
4218 default:
4219 {
4220 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4221 keyword);
4222 break;
4223 }
4224 }
4225 }
4226 paint_image=OilPaintImage(msl_info->image[n],geometry_info.rho,
cristyc82a27b2011-10-21 01:07:16 +00004227 geometry_info.sigma,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00004228 if (paint_image == (Image *) NULL)
4229 break;
4230 msl_info->image[n]=DestroyImage(msl_info->image[n]);
4231 msl_info->image[n]=paint_image;
4232 break;
4233 }
cristyb988fe72009-09-16 01:01:10 +00004234 if (LocaleCompare((const char *) tag,"opaque") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004235 {
cristy4c08aed2011-07-01 19:47:50 +00004236 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00004237 fill_color,
4238 target;
4239
4240 /*
4241 Opaque image.
4242 */
4243 if (msl_info->image[n] == (Image *) NULL)
4244 {
cristyb988fe72009-09-16 01:01:10 +00004245 ThrowMSLException(OptionError,"NoImagesDefined",
4246 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004247 break;
4248 }
cristy269c9412011-10-13 23:41:15 +00004249 (void) QueryColorCompliance("none",AllCompliance,&target,
dirk6d6d5f22014-06-20 11:48:54 +00004250 exception);
cristy269c9412011-10-13 23:41:15 +00004251 (void) QueryColorCompliance("none",AllCompliance,&fill_color,
dirk6d6d5f22014-06-20 11:48:54 +00004252 exception);
cristy3ed852e2009-09-05 21:47:34 +00004253 if (attributes != (const xmlChar **) NULL)
4254 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4255 {
4256 keyword=(const char *) attributes[i++];
4257 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004258 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00004259 exception);
cristy3ed852e2009-09-05 21:47:34 +00004260 CloneString(&value,attribute);
4261 switch (*keyword)
4262 {
4263 case 'C':
4264 case 'c':
4265 {
4266 if (LocaleCompare(keyword,"channel") == 0)
4267 {
4268 option=ParseChannelOption(value);
4269 if (option < 0)
4270 ThrowMSLException(OptionError,"UnrecognizedChannelType",
4271 value);
4272 channel=(ChannelType) option;
4273 break;
4274 }
4275 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4276 keyword);
4277 break;
4278 }
4279 case 'F':
4280 case 'f':
4281 {
4282 if (LocaleCompare(keyword,"fill") == 0)
4283 {
cristy269c9412011-10-13 23:41:15 +00004284 (void) QueryColorCompliance(value,AllCompliance,
dirk6d6d5f22014-06-20 11:48:54 +00004285 &fill_color,exception);
cristy3ed852e2009-09-05 21:47:34 +00004286 break;
4287 }
4288 if (LocaleCompare(keyword,"fuzz") == 0)
4289 {
cristydbdd0e32011-11-04 23:29:40 +00004290 msl_info->image[n]->fuzz=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00004291 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004292 break;
4293 }
4294 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4295 keyword);
4296 break;
4297 }
4298 default:
4299 {
4300 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4301 keyword);
4302 break;
4303 }
4304 }
4305 }
cristycf1296e2012-08-26 23:40:49 +00004306 channel_mask=SetImageChannelMask(msl_info->image[n],channel);
cristyd42d9952011-07-08 14:21:50 +00004307 (void) OpaquePaintImage(msl_info->image[n],&target,&fill_color,
cristyc82a27b2011-10-21 01:07:16 +00004308 MagickFalse,msl_info->exception);
cristycf1296e2012-08-26 23:40:49 +00004309 (void) SetPixelChannelMask(msl_info->image[n],channel_mask);
cristy3ed852e2009-09-05 21:47:34 +00004310 break;
4311 }
4312 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4313 }
4314 case 'P':
4315 case 'p':
4316 {
cristyb988fe72009-09-16 01:01:10 +00004317 if (LocaleCompare((const char *) tag,"print") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004318 {
4319 if (attributes == (const xmlChar **) NULL)
4320 break;
4321 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4322 {
4323 keyword=(const char *) attributes[i++];
4324 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004325 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00004326 exception);
cristy3ed852e2009-09-05 21:47:34 +00004327 CloneString(&value,attribute);
4328 switch (*keyword)
4329 {
4330 case 'O':
4331 case 'o':
4332 {
4333 if (LocaleCompare(keyword,"output") == 0)
4334 {
cristyb51dff52011-05-19 16:55:47 +00004335 (void) FormatLocaleFile(stdout,"%s",value);
cristy3ed852e2009-09-05 21:47:34 +00004336 break;
4337 }
4338 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
4339 break;
4340 }
4341 default:
4342 {
4343 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
4344 break;
4345 }
4346 }
4347 }
4348 break;
4349 }
cristy4fa36e42009-09-18 14:24:06 +00004350 if (LocaleCompare((const char *) tag, "profile") == 0)
4351 {
cristy4fa36e42009-09-18 14:24:06 +00004352 if (msl_info->image[n] == (Image *) NULL)
4353 {
4354 ThrowMSLException(OptionError,"NoImagesDefined",
4355 (const char *) tag);
4356 break;
4357 }
4358 if (attributes == (const xmlChar **) NULL)
4359 break;
4360 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4361 {
4362 const char
4363 *name;
4364
4365 const StringInfo
4366 *profile;
4367
4368 Image
4369 *profile_image;
4370
4371 ImageInfo
4372 *profile_info;
4373
4374 keyword=(const char *) attributes[i++];
4375 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004376 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00004377 exception);
cristy4fa36e42009-09-18 14:24:06 +00004378 CloneString(&value,attribute);
cristy8b2b4e52012-06-27 01:01:10 +00004379 if (*keyword == '!')
cristy4fa36e42009-09-18 14:24:06 +00004380 {
4381 /*
4382 Remove a profile from the image.
4383 */
4384 (void) ProfileImage(msl_info->image[n],keyword,
dirk6d6d5f22014-06-20 11:48:54 +00004385 (const unsigned char *) NULL,0,exception);
cristy4fa36e42009-09-18 14:24:06 +00004386 continue;
4387 }
4388 /*
4389 Associate a profile with the image.
4390 */
4391 profile_info=CloneImageInfo(msl_info->image_info[n]);
4392 profile=GetImageProfile(msl_info->image[n],"iptc");
4393 if (profile != (StringInfo *) NULL)
4394 profile_info->profile=(void *) CloneStringInfo(profile);
dirk6d6d5f22014-06-20 11:48:54 +00004395 profile_image=GetImageCache(profile_info,keyword,exception);
cristy4fa36e42009-09-18 14:24:06 +00004396 profile_info=DestroyImageInfo(profile_info);
4397 if (profile_image == (Image *) NULL)
4398 {
4399 char
cristy151b66d2015-04-15 10:50:31 +00004400 name[MagickPathExtent],
4401 filename[MagickPathExtent];
cristy4fa36e42009-09-18 14:24:06 +00004402
4403 register char
4404 *p;
4405
4406 StringInfo
4407 *profile;
4408
cristy151b66d2015-04-15 10:50:31 +00004409 (void) CopyMagickString(filename,keyword,MagickPathExtent);
4410 (void) CopyMagickString(name,keyword,MagickPathExtent);
cristy4fa36e42009-09-18 14:24:06 +00004411 for (p=filename; *p != '\0'; p++)
4412 if ((*p == ':') && (IsPathDirectory(keyword) < 0) &&
4413 (IsPathAccessible(keyword) == MagickFalse))
4414 {
4415 register char
4416 *q;
4417
4418 /*
4419 Look for profile name (e.g. name:profile).
4420 */
4421 (void) CopyMagickString(name,filename,(size_t)
4422 (p-filename+1));
4423 for (q=filename; *q != '\0'; q++)
4424 *q=(*++p);
4425 break;
4426 }
dirk6d6d5f22014-06-20 11:48:54 +00004427 profile=FileToStringInfo(filename,~0UL,exception);
cristy4fa36e42009-09-18 14:24:06 +00004428 if (profile != (StringInfo *) NULL)
4429 {
4430 (void) ProfileImage(msl_info->image[n],name,
cristybb503372010-05-27 20:51:26 +00004431 GetStringInfoDatum(profile),(size_t)
dirk6d6d5f22014-06-20 11:48:54 +00004432 GetStringInfoLength(profile),exception);
cristy4fa36e42009-09-18 14:24:06 +00004433 profile=DestroyStringInfo(profile);
4434 }
4435 continue;
4436 }
4437 ResetImageProfileIterator(profile_image);
4438 name=GetNextImageProfile(profile_image);
4439 while (name != (const char *) NULL)
4440 {
4441 profile=GetImageProfile(profile_image,name);
4442 if (profile != (StringInfo *) NULL)
4443 (void) ProfileImage(msl_info->image[n],name,
cristybb503372010-05-27 20:51:26 +00004444 GetStringInfoDatum(profile),(size_t)
dirk6d6d5f22014-06-20 11:48:54 +00004445 GetStringInfoLength(profile),exception);
cristy4fa36e42009-09-18 14:24:06 +00004446 name=GetNextImageProfile(profile_image);
4447 }
4448 profile_image=DestroyImage(profile_image);
4449 }
4450 break;
4451 }
cristy3ed852e2009-09-05 21:47:34 +00004452 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4453 }
4454 case 'Q':
4455 case 'q':
4456 {
cristyb988fe72009-09-16 01:01:10 +00004457 if (LocaleCompare((const char *) tag,"quantize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004458 {
4459 QuantizeInfo
4460 quantize_info;
4461
4462 /*
4463 Quantize image.
4464 */
4465 if (msl_info->image[n] == (Image *) NULL)
4466 {
cristyb988fe72009-09-16 01:01:10 +00004467 ThrowMSLException(OptionError,"NoImagesDefined",
4468 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004469 break;
4470 }
4471 GetQuantizeInfo(&quantize_info);
4472 if (attributes != (const xmlChar **) NULL)
4473 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4474 {
4475 keyword=(const char *) attributes[i++];
4476 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004477 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00004478 exception);
cristy3ed852e2009-09-05 21:47:34 +00004479 CloneString(&value,attribute);
4480 switch (*keyword)
4481 {
4482 case 'C':
4483 case 'c':
4484 {
4485 if (LocaleCompare(keyword,"colors") == 0)
4486 {
cristyf2f27272009-12-17 14:48:46 +00004487 quantize_info.number_colors=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004488 break;
4489 }
4490 if (LocaleCompare(keyword,"colorspace") == 0)
4491 {
cristy042ee782011-04-22 18:48:30 +00004492 option=ParseCommandOption(MagickColorspaceOptions,
cristy3ed852e2009-09-05 21:47:34 +00004493 MagickFalse,value);
4494 if (option < 0)
4495 ThrowMSLException(OptionError,
4496 "UnrecognizedColorspaceType",value);
4497 quantize_info.colorspace=(ColorspaceType) option;
4498 break;
4499 }
4500 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4501 keyword);
4502 break;
4503 }
4504 case 'D':
4505 case 'd':
4506 {
4507 if (LocaleCompare(keyword,"dither") == 0)
4508 {
cristycbda6112012-05-27 20:57:16 +00004509 option=ParseCommandOption(MagickDitherOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004510 value);
4511 if (option < 0)
4512 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4513 value);
cristycbda6112012-05-27 20:57:16 +00004514 quantize_info.dither_method=(DitherMethod) option;
cristy3ed852e2009-09-05 21:47:34 +00004515 break;
4516 }
4517 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4518 keyword);
4519 break;
4520 }
4521 case 'M':
4522 case 'm':
4523 {
4524 if (LocaleCompare(keyword,"measure") == 0)
4525 {
cristy042ee782011-04-22 18:48:30 +00004526 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004527 value);
4528 if (option < 0)
4529 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4530 value);
4531 quantize_info.measure_error=(MagickBooleanType) option;
4532 break;
4533 }
4534 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4535 keyword);
4536 break;
4537 }
4538 case 'T':
4539 case 't':
4540 {
4541 if (LocaleCompare(keyword,"treedepth") == 0)
4542 {
cristyf2f27272009-12-17 14:48:46 +00004543 quantize_info.tree_depth=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004544 break;
4545 }
4546 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4547 keyword);
4548 break;
4549 }
4550 default:
4551 {
4552 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4553 keyword);
4554 break;
4555 }
4556 }
4557 }
dirk6d6d5f22014-06-20 11:48:54 +00004558 (void) QuantizeImage(&quantize_info,msl_info->image[n],exception);
cristy3ed852e2009-09-05 21:47:34 +00004559 break;
4560 }
cristyb988fe72009-09-16 01:01:10 +00004561 if (LocaleCompare((const char *) tag,"query-font-metrics") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004562 {
4563 char
cristy151b66d2015-04-15 10:50:31 +00004564 text[MagickPathExtent];
cristy3ed852e2009-09-05 21:47:34 +00004565
4566 MagickBooleanType
4567 status;
4568
4569 TypeMetric
4570 metrics;
4571
4572 /*
4573 Query font metrics.
4574 */
4575 draw_info=CloneDrawInfo(msl_info->image_info[n],
4576 msl_info->draw_info[n]);
4577 angle=0.0;
4578 current=draw_info->affine;
4579 GetAffineMatrix(&affine);
4580 if (attributes != (const xmlChar **) NULL)
4581 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4582 {
4583 keyword=(const char *) attributes[i++];
4584 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004585 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00004586 exception);
cristy3ed852e2009-09-05 21:47:34 +00004587 CloneString(&value,attribute);
4588 switch (*keyword)
4589 {
4590 case 'A':
4591 case 'a':
4592 {
4593 if (LocaleCompare(keyword,"affine") == 0)
4594 {
4595 char
4596 *p;
4597
4598 p=value;
cristydbdd0e32011-11-04 23:29:40 +00004599 draw_info->affine.sx=StringToDouble(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004600 if (*p ==',')
4601 p++;
cristydbdd0e32011-11-04 23:29:40 +00004602 draw_info->affine.rx=StringToDouble(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004603 if (*p ==',')
4604 p++;
cristydbdd0e32011-11-04 23:29:40 +00004605 draw_info->affine.ry=StringToDouble(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004606 if (*p ==',')
4607 p++;
cristydbdd0e32011-11-04 23:29:40 +00004608 draw_info->affine.sy=StringToDouble(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004609 if (*p ==',')
4610 p++;
cristydbdd0e32011-11-04 23:29:40 +00004611 draw_info->affine.tx=StringToDouble(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004612 if (*p ==',')
4613 p++;
cristydbdd0e32011-11-04 23:29:40 +00004614 draw_info->affine.ty=StringToDouble(p,&p);
cristy3ed852e2009-09-05 21:47:34 +00004615 break;
4616 }
4617 if (LocaleCompare(keyword,"align") == 0)
4618 {
cristy042ee782011-04-22 18:48:30 +00004619 option=ParseCommandOption(MagickAlignOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004620 value);
4621 if (option < 0)
4622 ThrowMSLException(OptionError,"UnrecognizedAlignType",
4623 value);
4624 draw_info->align=(AlignType) option;
4625 break;
4626 }
4627 if (LocaleCompare(keyword,"antialias") == 0)
4628 {
cristy042ee782011-04-22 18:48:30 +00004629 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004630 value);
4631 if (option < 0)
4632 ThrowMSLException(OptionError,"UnrecognizedBooleanType",
4633 value);
4634 draw_info->stroke_antialias=(MagickBooleanType) option;
4635 draw_info->text_antialias=(MagickBooleanType) option;
4636 break;
4637 }
4638 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4639 keyword);
4640 break;
4641 }
4642 case 'D':
4643 case 'd':
4644 {
4645 if (LocaleCompare(keyword,"density") == 0)
4646 {
4647 CloneString(&draw_info->density,value);
4648 break;
4649 }
4650 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4651 keyword);
4652 break;
4653 }
4654 case 'E':
4655 case 'e':
4656 {
4657 if (LocaleCompare(keyword,"encoding") == 0)
4658 {
4659 CloneString(&draw_info->encoding,value);
4660 break;
4661 }
4662 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4663 keyword);
4664 break;
4665 }
4666 case 'F':
4667 case 'f':
4668 {
4669 if (LocaleCompare(keyword, "fill") == 0)
4670 {
cristy9950d572011-10-01 18:22:35 +00004671 (void) QueryColorCompliance(value,AllCompliance,
dirk6d6d5f22014-06-20 11:48:54 +00004672 &draw_info->fill,exception);
cristy3ed852e2009-09-05 21:47:34 +00004673 break;
4674 }
4675 if (LocaleCompare(keyword,"family") == 0)
4676 {
4677 CloneString(&draw_info->family,value);
4678 break;
4679 }
4680 if (LocaleCompare(keyword,"font") == 0)
4681 {
4682 CloneString(&draw_info->font,value);
4683 break;
4684 }
4685 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4686 keyword);
4687 break;
4688 }
4689 case 'G':
4690 case 'g':
4691 {
4692 if (LocaleCompare(keyword,"geometry") == 0)
4693 {
4694 flags=ParsePageGeometry(msl_info->image[n],value,
dirk6d6d5f22014-06-20 11:48:54 +00004695 &geometry,exception);
cristy3ed852e2009-09-05 21:47:34 +00004696 if ((flags & HeightValue) == 0)
4697 geometry.height=geometry.width;
4698 break;
4699 }
4700 if (LocaleCompare(keyword,"gravity") == 0)
4701 {
cristy042ee782011-04-22 18:48:30 +00004702 option=ParseCommandOption(MagickGravityOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004703 value);
4704 if (option < 0)
4705 ThrowMSLException(OptionError,"UnrecognizedGravityType",
4706 value);
4707 draw_info->gravity=(GravityType) option;
4708 break;
4709 }
4710 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4711 keyword);
4712 break;
4713 }
4714 case 'P':
4715 case 'p':
4716 {
4717 if (LocaleCompare(keyword,"pointsize") == 0)
4718 {
cristydbdd0e32011-11-04 23:29:40 +00004719 draw_info->pointsize=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00004720 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004721 break;
4722 }
4723 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4724 keyword);
4725 break;
4726 }
4727 case 'R':
4728 case 'r':
4729 {
4730 if (LocaleCompare(keyword,"rotate") == 0)
4731 {
cristydbdd0e32011-11-04 23:29:40 +00004732 angle=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004733 affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
4734 affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
4735 affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
4736 affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
4737 break;
4738 }
4739 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4740 keyword);
4741 break;
4742 }
4743 case 'S':
4744 case 's':
4745 {
4746 if (LocaleCompare(keyword,"scale") == 0)
4747 {
4748 flags=ParseGeometry(value,&geometry_info);
4749 if ((flags & SigmaValue) == 0)
4750 geometry_info.sigma=1.0;
4751 affine.sx=geometry_info.rho;
4752 affine.sy=geometry_info.sigma;
4753 break;
4754 }
4755 if (LocaleCompare(keyword,"skewX") == 0)
4756 {
cristydbdd0e32011-11-04 23:29:40 +00004757 angle=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004758 affine.ry=cos(DegreesToRadians(fmod(angle,360.0)));
4759 break;
4760 }
4761 if (LocaleCompare(keyword,"skewY") == 0)
4762 {
cristydbdd0e32011-11-04 23:29:40 +00004763 angle=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00004764 affine.rx=cos(DegreesToRadians(fmod(angle,360.0)));
4765 break;
4766 }
4767 if (LocaleCompare(keyword,"stretch") == 0)
4768 {
cristy9950d572011-10-01 18:22:35 +00004769 option=ParseCommandOption(MagickStretchOptions,
4770 MagickFalse,value);
cristy3ed852e2009-09-05 21:47:34 +00004771 if (option < 0)
4772 ThrowMSLException(OptionError,"UnrecognizedStretchType",
4773 value);
4774 draw_info->stretch=(StretchType) option;
4775 break;
4776 }
4777 if (LocaleCompare(keyword, "stroke") == 0)
4778 {
cristy9950d572011-10-01 18:22:35 +00004779 (void) QueryColorCompliance(value,AllCompliance,
dirk6d6d5f22014-06-20 11:48:54 +00004780 &draw_info->stroke,exception);
cristy3ed852e2009-09-05 21:47:34 +00004781 break;
4782 }
4783 if (LocaleCompare(keyword,"strokewidth") == 0)
4784 {
cristyf2f27272009-12-17 14:48:46 +00004785 draw_info->stroke_width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004786 break;
4787 }
4788 if (LocaleCompare(keyword,"style") == 0)
4789 {
cristy042ee782011-04-22 18:48:30 +00004790 option=ParseCommandOption(MagickStyleOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004791 value);
4792 if (option < 0)
4793 ThrowMSLException(OptionError,"UnrecognizedStyleType",
4794 value);
4795 draw_info->style=(StyleType) option;
4796 break;
4797 }
4798 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4799 keyword);
4800 break;
4801 }
4802 case 'T':
4803 case 't':
4804 {
4805 if (LocaleCompare(keyword,"text") == 0)
4806 {
4807 CloneString(&draw_info->text,value);
4808 break;
4809 }
4810 if (LocaleCompare(keyword,"translate") == 0)
4811 {
4812 flags=ParseGeometry(value,&geometry_info);
4813 if ((flags & SigmaValue) == 0)
4814 geometry_info.sigma=1.0;
4815 affine.tx=geometry_info.rho;
4816 affine.ty=geometry_info.sigma;
4817 break;
4818 }
4819 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4820 keyword);
4821 break;
4822 }
4823 case 'U':
4824 case 'u':
4825 {
4826 if (LocaleCompare(keyword, "undercolor") == 0)
4827 {
cristy9950d572011-10-01 18:22:35 +00004828 (void) QueryColorCompliance(value,AllCompliance,
dirk6d6d5f22014-06-20 11:48:54 +00004829 &draw_info->undercolor,exception);
cristy3ed852e2009-09-05 21:47:34 +00004830 break;
4831 }
4832 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4833 keyword);
4834 break;
4835 }
4836 case 'W':
4837 case 'w':
4838 {
4839 if (LocaleCompare(keyword,"weight") == 0)
4840 {
cristyf2f27272009-12-17 14:48:46 +00004841 draw_info->weight=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004842 break;
4843 }
4844 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4845 keyword);
4846 break;
4847 }
4848 case 'X':
4849 case 'x':
4850 {
4851 if (LocaleCompare(keyword,"x") == 0)
4852 {
cristyf2f27272009-12-17 14:48:46 +00004853 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004854 break;
4855 }
4856 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4857 keyword);
4858 break;
4859 }
4860 case 'Y':
4861 case 'y':
4862 {
4863 if (LocaleCompare(keyword,"y") == 0)
4864 {
cristyf2f27272009-12-17 14:48:46 +00004865 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004866 break;
4867 }
4868 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4869 keyword);
4870 break;
4871 }
4872 default:
4873 {
4874 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4875 keyword);
4876 break;
4877 }
4878 }
4879 }
cristy151b66d2015-04-15 10:50:31 +00004880 (void) FormatLocaleString(text,MagickPathExtent,
cristye8c25f92010-06-03 00:53:06 +00004881 "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,(double)
4882 geometry.height,(double) geometry.x,(double) geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00004883 CloneString(&draw_info->geometry,text);
cristyef7c8a52010-10-10 13:46:51 +00004884 draw_info->affine.sx=affine.sx*current.sx+affine.ry*current.rx;
4885 draw_info->affine.rx=affine.rx*current.sx+affine.sy*current.rx;
4886 draw_info->affine.ry=affine.sx*current.ry+affine.ry*current.sy;
4887 draw_info->affine.sy=affine.rx*current.ry+affine.sy*current.sy;
4888 draw_info->affine.tx=affine.sx*current.tx+affine.ry*current.ty+
4889 affine.tx;
4890 draw_info->affine.ty=affine.rx*current.tx+affine.sy*current.ty+
4891 affine.ty;
cristy5cbc0162011-08-29 00:36:28 +00004892 status=GetTypeMetrics(msl_info->attributes[n],draw_info,&metrics,
cristyc82a27b2011-10-21 01:07:16 +00004893 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00004894 if (status != MagickFalse)
4895 {
4896 Image
4897 *image;
4898
4899 image=msl_info->attributes[n];
cristy8cd5b312010-01-07 01:10:24 +00004900 FormatImageProperty(image,"msl:font-metrics.pixels_per_em.x",
cristye7f51092010-01-17 00:39:37 +00004901 "%g",metrics.pixels_per_em.x);
cristy8cd5b312010-01-07 01:10:24 +00004902 FormatImageProperty(image,"msl:font-metrics.pixels_per_em.y",
cristye7f51092010-01-17 00:39:37 +00004903 "%g",metrics.pixels_per_em.y);
4904 FormatImageProperty(image,"msl:font-metrics.ascent","%g",
cristy3ed852e2009-09-05 21:47:34 +00004905 metrics.ascent);
cristye7f51092010-01-17 00:39:37 +00004906 FormatImageProperty(image,"msl:font-metrics.descent","%g",
cristy3ed852e2009-09-05 21:47:34 +00004907 metrics.descent);
cristye7f51092010-01-17 00:39:37 +00004908 FormatImageProperty(image,"msl:font-metrics.width","%g",
cristy3ed852e2009-09-05 21:47:34 +00004909 metrics.width);
cristye7f51092010-01-17 00:39:37 +00004910 FormatImageProperty(image,"msl:font-metrics.height","%g",
cristy3ed852e2009-09-05 21:47:34 +00004911 metrics.height);
cristye7f51092010-01-17 00:39:37 +00004912 FormatImageProperty(image,"msl:font-metrics.max_advance","%g",
cristy3ed852e2009-09-05 21:47:34 +00004913 metrics.max_advance);
cristye7f51092010-01-17 00:39:37 +00004914 FormatImageProperty(image,"msl:font-metrics.bounds.x1","%g",
cristy3ed852e2009-09-05 21:47:34 +00004915 metrics.bounds.x1);
cristye7f51092010-01-17 00:39:37 +00004916 FormatImageProperty(image,"msl:font-metrics.bounds.y1","%g",
cristy3ed852e2009-09-05 21:47:34 +00004917 metrics.bounds.y1);
cristye7f51092010-01-17 00:39:37 +00004918 FormatImageProperty(image,"msl:font-metrics.bounds.x2","%g",
cristy3ed852e2009-09-05 21:47:34 +00004919 metrics.bounds.x2);
cristye7f51092010-01-17 00:39:37 +00004920 FormatImageProperty(image,"msl:font-metrics.bounds.y2","%g",
cristy3ed852e2009-09-05 21:47:34 +00004921 metrics.bounds.y2);
cristye7f51092010-01-17 00:39:37 +00004922 FormatImageProperty(image,"msl:font-metrics.origin.x","%g",
cristy3ed852e2009-09-05 21:47:34 +00004923 metrics.origin.x);
cristye7f51092010-01-17 00:39:37 +00004924 FormatImageProperty(image,"msl:font-metrics.origin.y","%g",
cristy3ed852e2009-09-05 21:47:34 +00004925 metrics.origin.y);
4926 }
4927 draw_info=DestroyDrawInfo(draw_info);
4928 break;
4929 }
4930 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
4931 }
4932 case 'R':
4933 case 'r':
4934 {
cristyb988fe72009-09-16 01:01:10 +00004935 if (LocaleCompare((const char *) tag,"raise") == 0)
cristy3ed852e2009-09-05 21:47:34 +00004936 {
4937 MagickBooleanType
4938 raise;
4939
4940 /*
4941 Raise image.
4942 */
4943 if (msl_info->image[n] == (Image *) NULL)
4944 {
cristyb988fe72009-09-16 01:01:10 +00004945 ThrowMSLException(OptionError,"NoImagesDefined",
4946 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00004947 break;
4948 }
4949 raise=MagickFalse;
4950 SetGeometry(msl_info->image[n],&geometry);
4951 if (attributes != (const xmlChar **) NULL)
4952 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
4953 {
4954 keyword=(const char *) attributes[i++];
4955 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00004956 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00004957 exception);
cristy3ed852e2009-09-05 21:47:34 +00004958 CloneString(&value,attribute);
4959 switch (*keyword)
4960 {
4961 case 'G':
4962 case 'g':
4963 {
4964 if (LocaleCompare(keyword,"geometry") == 0)
4965 {
4966 flags=ParsePageGeometry(msl_info->image[n],value,
dirk6d6d5f22014-06-20 11:48:54 +00004967 &geometry,exception);
cristy3ed852e2009-09-05 21:47:34 +00004968 if ((flags & HeightValue) == 0)
4969 geometry.height=geometry.width;
4970 break;
4971 }
4972 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4973 keyword);
4974 break;
4975 }
4976 case 'H':
4977 case 'h':
4978 {
4979 if (LocaleCompare(keyword,"height") == 0)
4980 {
cristyf2f27272009-12-17 14:48:46 +00004981 geometry.height=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00004982 break;
4983 }
4984 ThrowMSLException(OptionError,"UnrecognizedAttribute",
4985 keyword);
4986 break;
4987 }
4988 case 'R':
4989 case 'r':
4990 {
4991 if (LocaleCompare(keyword,"raise") == 0)
4992 {
cristy042ee782011-04-22 18:48:30 +00004993 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00004994 value);
4995 if (option < 0)
4996 ThrowMSLException(OptionError,"UnrecognizedNoiseType",
4997 value);
4998 raise=(MagickBooleanType) option;
4999 break;
5000 }
5001 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5002 keyword);
5003 break;
5004 }
5005 case 'W':
5006 case 'w':
5007 {
5008 if (LocaleCompare(keyword,"width") == 0)
5009 {
cristyf2f27272009-12-17 14:48:46 +00005010 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005011 break;
5012 }
5013 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5014 keyword);
5015 break;
5016 }
5017 default:
5018 {
5019 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5020 keyword);
5021 break;
5022 }
5023 }
5024 }
cristy6170ac32011-08-28 14:15:37 +00005025 (void) RaiseImage(msl_info->image[n],&geometry,raise,
cristyc82a27b2011-10-21 01:07:16 +00005026 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00005027 break;
5028 }
cristyb988fe72009-09-16 01:01:10 +00005029 if (LocaleCompare((const char *) tag,"read") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005030 {
5031 if (attributes == (const xmlChar **) NULL)
5032 break;
5033 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5034 {
5035 keyword=(const char *) attributes[i++];
5036 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
dirk6d6d5f22014-06-20 11:48:54 +00005037 msl_info->attributes[n],(const char *) attributes[i],exception));
cristy3ed852e2009-09-05 21:47:34 +00005038 switch (*keyword)
5039 {
5040 case 'F':
5041 case 'f':
5042 {
5043 if (LocaleCompare(keyword,"filename") == 0)
5044 {
5045 Image
5046 *image;
5047
5048 (void) CopyMagickString(msl_info->image_info[n]->filename,
cristy151b66d2015-04-15 10:50:31 +00005049 value,MagickPathExtent);
dirk6d6d5f22014-06-20 11:48:54 +00005050 image=ReadImage(msl_info->image_info[n],exception);
5051 CatchException(exception);
cristy3ed852e2009-09-05 21:47:34 +00005052 if (image == (Image *) NULL)
5053 continue;
5054 AppendImageToList(&msl_info->image[n],image);
5055 break;
5056 }
cristy4582cbb2009-09-23 00:35:43 +00005057 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00005058 break;
5059 }
5060 default:
5061 {
cristy4582cbb2009-09-23 00:35:43 +00005062 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00005063 break;
5064 }
5065 }
5066 }
5067 break;
5068 }
cristyb988fe72009-09-16 01:01:10 +00005069 if (LocaleCompare((const char *) tag,"reduce-noise") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005070 {
5071 Image
5072 *paint_image;
5073
5074 /*
5075 Reduce-noise image.
5076 */
5077 if (msl_info->image[n] == (Image *) NULL)
5078 {
cristyb988fe72009-09-16 01:01:10 +00005079 ThrowMSLException(OptionError,"NoImagesDefined",
5080 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005081 break;
5082 }
5083 if (attributes != (const xmlChar **) NULL)
5084 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5085 {
5086 keyword=(const char *) attributes[i++];
5087 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005088 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00005089 exception);
cristy3ed852e2009-09-05 21:47:34 +00005090 CloneString(&value,attribute);
5091 switch (*keyword)
5092 {
5093 case 'G':
5094 case 'g':
5095 {
5096 if (LocaleCompare(keyword,"geometry") == 0)
5097 {
5098 flags=ParseGeometry(value,&geometry_info);
5099 if ((flags & SigmaValue) == 0)
5100 geometry_info.sigma=1.0;
5101 break;
5102 }
5103 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5104 keyword);
5105 break;
5106 }
5107 case 'R':
5108 case 'r':
5109 {
5110 if (LocaleCompare(keyword,"radius") == 0)
5111 {
cristydbdd0e32011-11-04 23:29:40 +00005112 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00005113 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005114 break;
5115 }
5116 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5117 keyword);
5118 break;
5119 }
5120 default:
5121 {
5122 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5123 keyword);
5124 break;
5125 }
5126 }
5127 }
cristy733678d2011-03-18 21:29:28 +00005128 paint_image=StatisticImage(msl_info->image[n],NonpeakStatistic,
cristy95c38342011-03-18 22:39:51 +00005129 (size_t) geometry_info.rho,(size_t) geometry_info.sigma,
cristyc82a27b2011-10-21 01:07:16 +00005130 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00005131 if (paint_image == (Image *) NULL)
5132 break;
5133 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5134 msl_info->image[n]=paint_image;
5135 break;
5136 }
cristyb988fe72009-09-16 01:01:10 +00005137 else if (LocaleCompare((const char *) tag,"repage") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005138 {
5139 /* init the values */
5140 width=msl_info->image[n]->page.width;
5141 height=msl_info->image[n]->page.height;
5142 x=msl_info->image[n]->page.x;
5143 y=msl_info->image[n]->page.y;
5144
5145 if (msl_info->image[n] == (Image *) NULL)
5146 {
cristyb988fe72009-09-16 01:01:10 +00005147 ThrowMSLException(OptionError,"NoImagesDefined",
5148 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005149 break;
5150 }
5151 if (attributes == (const xmlChar **) NULL)
5152 break;
5153 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5154 {
5155 keyword=(const char *) attributes[i++];
5156 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
dirk6d6d5f22014-06-20 11:48:54 +00005157 msl_info->attributes[n],(const char *) attributes[i],exception));
cristy3ed852e2009-09-05 21:47:34 +00005158 switch (*keyword)
5159 {
5160 case 'G':
5161 case 'g':
5162 {
5163 if (LocaleCompare(keyword,"geometry") == 0)
5164 {
5165 int
5166 flags;
5167
5168 RectangleInfo
5169 geometry;
5170
5171 flags=ParseAbsoluteGeometry(value,&geometry);
5172 if ((flags & WidthValue) != 0)
5173 {
5174 if ((flags & HeightValue) == 0)
5175 geometry.height=geometry.width;
5176 width=geometry.width;
5177 height=geometry.height;
5178 }
5179 if ((flags & AspectValue) != 0)
5180 {
5181 if ((flags & XValue) != 0)
5182 x+=geometry.x;
5183 if ((flags & YValue) != 0)
5184 y+=geometry.y;
5185 }
5186 else
5187 {
5188 if ((flags & XValue) != 0)
5189 {
5190 x=geometry.x;
5191 if ((width == 0) && (geometry.x > 0))
5192 width=msl_info->image[n]->columns+geometry.x;
5193 }
5194 if ((flags & YValue) != 0)
5195 {
5196 y=geometry.y;
5197 if ((height == 0) && (geometry.y > 0))
5198 height=msl_info->image[n]->rows+geometry.y;
5199 }
5200 }
5201 break;
5202 }
5203 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5204 break;
5205 }
5206 case 'H':
5207 case 'h':
5208 {
5209 if (LocaleCompare(keyword,"height") == 0)
5210 {
cristyf2f27272009-12-17 14:48:46 +00005211 height = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005212 break;
5213 }
5214 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5215 break;
5216 }
5217 case 'W':
5218 case 'w':
5219 {
5220 if (LocaleCompare(keyword,"width") == 0)
5221 {
cristyf2f27272009-12-17 14:48:46 +00005222 width = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005223 break;
5224 }
5225 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5226 break;
5227 }
5228 case 'X':
5229 case 'x':
5230 {
5231 if (LocaleCompare(keyword,"x") == 0)
5232 {
cristyf2f27272009-12-17 14:48:46 +00005233 x = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005234 break;
5235 }
5236 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5237 break;
5238 }
5239 case 'Y':
5240 case 'y':
5241 {
5242 if (LocaleCompare(keyword,"y") == 0)
5243 {
cristyf2f27272009-12-17 14:48:46 +00005244 y = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005245 break;
5246 }
5247 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5248 break;
5249 }
5250 default:
5251 {
5252 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5253 break;
5254 }
5255 }
5256 }
5257
cristyb988fe72009-09-16 01:01:10 +00005258 msl_info->image[n]->page.width=width;
5259 msl_info->image[n]->page.height=height;
5260 msl_info->image[n]->page.x=x;
5261 msl_info->image[n]->page.y=y;
cristy3ed852e2009-09-05 21:47:34 +00005262 break;
5263 }
cristyb988fe72009-09-16 01:01:10 +00005264 else if (LocaleCompare((const char *) tag,"resample") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005265 {
5266 double
5267 x_resolution,
5268 y_resolution;
5269
5270 if (msl_info->image[n] == (Image *) NULL)
5271 {
cristyb988fe72009-09-16 01:01:10 +00005272 ThrowMSLException(OptionError,"NoImagesDefined",
5273 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005274 break;
5275 }
5276 if (attributes == (const xmlChar **) NULL)
5277 break;
5278 x_resolution=DefaultResolution;
5279 y_resolution=DefaultResolution;
5280 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5281 {
5282 keyword=(const char *) attributes[i++];
5283 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
dirk6d6d5f22014-06-20 11:48:54 +00005284 msl_info->attributes[n],(const char *) attributes[i],exception));
cristy3ed852e2009-09-05 21:47:34 +00005285 switch (*keyword)
5286 {
cristy3ed852e2009-09-05 21:47:34 +00005287 case 'G':
5288 case 'g':
5289 {
5290 if (LocaleCompare(keyword,"geometry") == 0)
5291 {
cristybb503372010-05-27 20:51:26 +00005292 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00005293 flags;
5294
5295 flags=ParseGeometry(value,&geometry_info);
5296 if ((flags & SigmaValue) == 0)
5297 geometry_info.sigma*=geometry_info.rho;
5298 x_resolution=geometry_info.rho;
5299 y_resolution=geometry_info.sigma;
5300 break;
5301 }
5302 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5303 break;
5304 }
5305 case 'X':
5306 case 'x':
5307 {
5308 if (LocaleCompare(keyword,"x-resolution") == 0)
5309 {
cristydbdd0e32011-11-04 23:29:40 +00005310 x_resolution=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005311 break;
5312 }
5313 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5314 break;
5315 }
5316 case 'Y':
5317 case 'y':
5318 {
5319 if (LocaleCompare(keyword,"y-resolution") == 0)
5320 {
cristydbdd0e32011-11-04 23:29:40 +00005321 y_resolution=StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005322 break;
5323 }
5324 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5325 break;
5326 }
5327 default:
5328 {
5329 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5330 break;
5331 }
5332 }
5333 }
5334 /*
5335 Resample image.
5336 */
5337 {
5338 double
5339 factor;
5340
5341 Image
5342 *resample_image;
5343
5344 factor=1.0;
5345 if (msl_info->image[n]->units == PixelsPerCentimeterResolution)
5346 factor=2.54;
cristybb503372010-05-27 20:51:26 +00005347 width=(size_t) (x_resolution*msl_info->image[n]->columns/
cristy2a11bef2011-10-28 18:33:11 +00005348 (factor*(msl_info->image[n]->resolution.x == 0.0 ? DefaultResolution :
5349 msl_info->image[n]->resolution.x))+0.5);
cristybb503372010-05-27 20:51:26 +00005350 height=(size_t) (y_resolution*msl_info->image[n]->rows/
cristy2a11bef2011-10-28 18:33:11 +00005351 (factor*(msl_info->image[n]->resolution.y == 0.0 ? DefaultResolution :
5352 msl_info->image[n]->resolution.y))+0.5);
cristy3ed852e2009-09-05 21:47:34 +00005353 resample_image=ResizeImage(msl_info->image[n],width,height,
cristyaa2c16c2012-03-25 22:21:35 +00005354 msl_info->image[n]->filter,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00005355 if (resample_image == (Image *) NULL)
5356 break;
5357 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5358 msl_info->image[n]=resample_image;
5359 }
5360 break;
5361 }
cristyb988fe72009-09-16 01:01:10 +00005362 if (LocaleCompare((const char *) tag,"resize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005363 {
cristy3ed852e2009-09-05 21:47:34 +00005364 FilterTypes
5365 filter;
5366
5367 Image
5368 *resize_image;
5369
5370 /*
5371 Resize image.
5372 */
5373 if (msl_info->image[n] == (Image *) NULL)
5374 {
cristyb988fe72009-09-16 01:01:10 +00005375 ThrowMSLException(OptionError,"NoImagesDefined",
5376 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005377 break;
5378 }
5379 filter=UndefinedFilter;
cristy3ed852e2009-09-05 21:47:34 +00005380 if (attributes != (const xmlChar **) NULL)
5381 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5382 {
5383 keyword=(const char *) attributes[i++];
5384 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005385 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00005386 exception);
cristy3ed852e2009-09-05 21:47:34 +00005387 CloneString(&value,attribute);
5388 switch (*keyword)
5389 {
5390 case 'F':
5391 case 'f':
5392 {
5393 if (LocaleCompare(keyword,"filter") == 0)
5394 {
cristy042ee782011-04-22 18:48:30 +00005395 option=ParseCommandOption(MagickFilterOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00005396 value);
5397 if (option < 0)
5398 ThrowMSLException(OptionError,"UnrecognizedNoiseType",
5399 value);
5400 filter=(FilterTypes) option;
5401 break;
5402 }
5403 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5404 keyword);
5405 break;
5406 }
5407 case 'G':
5408 case 'g':
5409 {
5410 if (LocaleCompare(keyword,"geometry") == 0)
5411 {
5412 flags=ParseRegionGeometry(msl_info->image[n],value,
dirk6d6d5f22014-06-20 11:48:54 +00005413 &geometry,exception);
cristy3ed852e2009-09-05 21:47:34 +00005414 break;
5415 }
5416 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5417 keyword);
5418 break;
5419 }
5420 case 'H':
5421 case 'h':
5422 {
5423 if (LocaleCompare(keyword,"height") == 0)
5424 {
cristye27293e2009-12-18 02:53:20 +00005425 geometry.height=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005426 break;
5427 }
5428 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5429 keyword);
5430 break;
5431 }
cristy3ed852e2009-09-05 21:47:34 +00005432 case 'W':
5433 case 'w':
5434 {
5435 if (LocaleCompare(keyword,"width") == 0)
5436 {
cristyf2f27272009-12-17 14:48:46 +00005437 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005438 break;
5439 }
5440 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5441 keyword);
5442 break;
5443 }
5444 default:
5445 {
5446 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5447 keyword);
5448 break;
5449 }
5450 }
5451 }
5452 resize_image=ResizeImage(msl_info->image[n],geometry.width,
cristyaa2c16c2012-03-25 22:21:35 +00005453 geometry.height,filter,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00005454 if (resize_image == (Image *) NULL)
5455 break;
5456 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5457 msl_info->image[n]=resize_image;
5458 break;
5459 }
cristyb988fe72009-09-16 01:01:10 +00005460 if (LocaleCompare((const char *) tag,"roll") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005461 {
5462 Image
5463 *roll_image;
5464
5465 /*
5466 Roll image.
5467 */
5468 if (msl_info->image[n] == (Image *) NULL)
5469 {
cristyb988fe72009-09-16 01:01:10 +00005470 ThrowMSLException(OptionError,"NoImagesDefined",
5471 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005472 break;
5473 }
5474 SetGeometry(msl_info->image[n],&geometry);
5475 if (attributes != (const xmlChar **) NULL)
5476 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5477 {
5478 keyword=(const char *) attributes[i++];
5479 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005480 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00005481 exception);
cristy3ed852e2009-09-05 21:47:34 +00005482 CloneString(&value,attribute);
5483 switch (*keyword)
5484 {
5485 case 'G':
5486 case 'g':
5487 {
5488 if (LocaleCompare(keyword,"geometry") == 0)
5489 {
5490 flags=ParsePageGeometry(msl_info->image[n],value,
dirk6d6d5f22014-06-20 11:48:54 +00005491 &geometry,exception);
cristy3ed852e2009-09-05 21:47:34 +00005492 if ((flags & HeightValue) == 0)
5493 geometry.height=geometry.width;
5494 break;
5495 }
5496 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5497 keyword);
5498 break;
5499 }
5500 case 'X':
5501 case 'x':
5502 {
5503 if (LocaleCompare(keyword,"x") == 0)
5504 {
cristyf2f27272009-12-17 14:48:46 +00005505 geometry.x=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005506 break;
5507 }
5508 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5509 keyword);
5510 break;
5511 }
5512 case 'Y':
5513 case 'y':
5514 {
5515 if (LocaleCompare(keyword,"y") == 0)
5516 {
cristyf2f27272009-12-17 14:48:46 +00005517 geometry.y=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005518 break;
5519 }
5520 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5521 keyword);
5522 break;
5523 }
5524 default:
5525 {
5526 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5527 keyword);
5528 break;
5529 }
5530 }
5531 }
5532 roll_image=RollImage(msl_info->image[n],geometry.x,geometry.y,
cristyc82a27b2011-10-21 01:07:16 +00005533 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00005534 if (roll_image == (Image *) NULL)
5535 break;
5536 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5537 msl_info->image[n]=roll_image;
5538 break;
5539 }
cristyb988fe72009-09-16 01:01:10 +00005540 else if (LocaleCompare((const char *) tag,"roll") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005541 {
5542 /* init the values */
5543 width=msl_info->image[n]->columns;
5544 height=msl_info->image[n]->rows;
5545 x = y = 0;
5546
5547 if (msl_info->image[n] == (Image *) NULL)
5548 {
cristyb988fe72009-09-16 01:01:10 +00005549 ThrowMSLException(OptionError,"NoImagesDefined",
5550 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005551 break;
5552 }
5553 if (attributes == (const xmlChar **) NULL)
5554 break;
5555 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5556 {
5557 keyword=(const char *) attributes[i++];
5558 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
dirk6d6d5f22014-06-20 11:48:54 +00005559 msl_info->attributes[n],(const char *) attributes[i],exception));
cristy3ed852e2009-09-05 21:47:34 +00005560 switch (*keyword)
5561 {
5562 case 'G':
5563 case 'g':
5564 {
5565 if (LocaleCompare(keyword,"geometry") == 0)
5566 {
5567 (void) ParseMetaGeometry(value,&x,&y,&width,&height);
5568 break;
5569 }
5570 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5571 break;
5572 }
5573 case 'X':
5574 case 'x':
5575 {
5576 if (LocaleCompare(keyword,"x") == 0)
5577 {
cristyf2f27272009-12-17 14:48:46 +00005578 x = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005579 break;
5580 }
5581 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5582 break;
5583 }
5584 case 'Y':
5585 case 'y':
5586 {
5587 if (LocaleCompare(keyword,"y") == 0)
5588 {
cristyf2f27272009-12-17 14:48:46 +00005589 y = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00005590 break;
5591 }
5592 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5593 break;
5594 }
5595 default:
5596 {
5597 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5598 break;
5599 }
5600 }
5601 }
5602
5603 /*
5604 process image.
5605 */
5606 {
5607 Image
5608 *newImage;
5609
cristyc82a27b2011-10-21 01:07:16 +00005610 newImage=RollImage(msl_info->image[n], x, y, msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00005611 if (newImage == (Image *) NULL)
5612 break;
5613 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5614 msl_info->image[n]=newImage;
5615 }
5616
5617 break;
5618 }
cristyb988fe72009-09-16 01:01:10 +00005619 if (LocaleCompare((const char *) tag,"rotate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005620 {
5621 Image
5622 *rotate_image;
5623
5624 /*
5625 Rotate image.
5626 */
5627 if (msl_info->image[n] == (Image *) NULL)
5628 {
cristyb988fe72009-09-16 01:01:10 +00005629 ThrowMSLException(OptionError,"NoImagesDefined",
5630 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005631 break;
5632 }
5633 if (attributes != (const xmlChar **) NULL)
5634 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5635 {
5636 keyword=(const char *) attributes[i++];
5637 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005638 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00005639 exception);
cristy3ed852e2009-09-05 21:47:34 +00005640 CloneString(&value,attribute);
5641 switch (*keyword)
5642 {
5643 case 'D':
5644 case 'd':
5645 {
5646 if (LocaleCompare(keyword,"degrees") == 0)
5647 {
cristydbdd0e32011-11-04 23:29:40 +00005648 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00005649 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005650 break;
5651 }
5652 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5653 keyword);
5654 break;
5655 }
5656 case 'G':
5657 case 'g':
5658 {
5659 if (LocaleCompare(keyword,"geometry") == 0)
5660 {
5661 flags=ParseGeometry(value,&geometry_info);
5662 if ((flags & SigmaValue) == 0)
5663 geometry_info.sigma=1.0;
5664 break;
5665 }
5666 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5667 keyword);
5668 break;
5669 }
5670 default:
5671 {
5672 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5673 keyword);
5674 break;
5675 }
5676 }
5677 }
5678 rotate_image=RotateImage(msl_info->image[n],geometry_info.rho,
cristyc82a27b2011-10-21 01:07:16 +00005679 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00005680 if (rotate_image == (Image *) NULL)
5681 break;
5682 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5683 msl_info->image[n]=rotate_image;
5684 break;
5685 }
cristyb988fe72009-09-16 01:01:10 +00005686 else if (LocaleCompare((const char *) tag,"rotate") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005687 {
5688 /* init the values */
5689 double degrees = 0;
5690
5691 if (msl_info->image[n] == (Image *) NULL)
5692 {
cristyb988fe72009-09-16 01:01:10 +00005693 ThrowMSLException(OptionError,"NoImagesDefined",
5694 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005695 break;
5696 }
5697 if (attributes == (const xmlChar **) NULL)
cristy31939262009-09-15 00:23:11 +00005698 break;
cristy3ed852e2009-09-05 21:47:34 +00005699 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5700 {
5701 keyword=(const char *) attributes[i++];
5702 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
dirk6d6d5f22014-06-20 11:48:54 +00005703 msl_info->attributes[n],(const char *) attributes[i],exception));
cristy3ed852e2009-09-05 21:47:34 +00005704 switch (*keyword)
5705 {
5706 case 'D':
5707 case 'd':
5708 {
5709 if (LocaleCompare(keyword,"degrees") == 0)
5710 {
cristydbdd0e32011-11-04 23:29:40 +00005711 degrees = StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005712 break;
5713 }
5714 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5715 break;
5716 }
5717 default:
5718 {
5719 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
5720 break;
5721 }
5722 }
5723 }
5724
5725 /*
5726 process image.
5727 */
5728 {
5729 Image
5730 *newImage;
5731
cristyc82a27b2011-10-21 01:07:16 +00005732 newImage=RotateImage(msl_info->image[n], degrees, msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00005733 if (newImage == (Image *) NULL)
5734 break;
5735 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5736 msl_info->image[n]=newImage;
5737 }
5738
5739 break;
5740 }
5741 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
5742 }
5743 case 'S':
5744 case 's':
5745 {
cristyb988fe72009-09-16 01:01:10 +00005746 if (LocaleCompare((const char *) tag,"sample") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005747 {
5748 Image
5749 *sample_image;
5750
5751 /*
5752 Sample image.
5753 */
5754 if (msl_info->image[n] == (Image *) NULL)
5755 {
cristyb988fe72009-09-16 01:01:10 +00005756 ThrowMSLException(OptionError,"NoImagesDefined",
5757 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005758 break;
5759 }
5760 if (attributes != (const xmlChar **) NULL)
5761 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5762 {
5763 keyword=(const char *) attributes[i++];
5764 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005765 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00005766 exception);
cristy3ed852e2009-09-05 21:47:34 +00005767 CloneString(&value,attribute);
5768 switch (*keyword)
5769 {
5770 case 'G':
5771 case 'g':
5772 {
5773 if (LocaleCompare(keyword,"geometry") == 0)
5774 {
5775 flags=ParseRegionGeometry(msl_info->image[n],value,
dirk6d6d5f22014-06-20 11:48:54 +00005776 &geometry,exception);
cristy3ed852e2009-09-05 21:47:34 +00005777 break;
5778 }
5779 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5780 keyword);
5781 break;
5782 }
5783 case 'H':
5784 case 'h':
5785 {
5786 if (LocaleCompare(keyword,"height") == 0)
5787 {
cristye27293e2009-12-18 02:53:20 +00005788 geometry.height=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005789 break;
5790 }
5791 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5792 keyword);
5793 break;
5794 }
5795 case 'W':
5796 case 'w':
5797 {
5798 if (LocaleCompare(keyword,"width") == 0)
5799 {
cristyf2f27272009-12-17 14:48:46 +00005800 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005801 break;
5802 }
5803 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5804 keyword);
5805 break;
5806 }
5807 default:
5808 {
5809 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5810 keyword);
5811 break;
5812 }
5813 }
5814 }
5815 sample_image=SampleImage(msl_info->image[n],geometry.width,
cristyc82a27b2011-10-21 01:07:16 +00005816 geometry.height,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00005817 if (sample_image == (Image *) NULL)
5818 break;
5819 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5820 msl_info->image[n]=sample_image;
5821 break;
5822 }
cristyb988fe72009-09-16 01:01:10 +00005823 if (LocaleCompare((const char *) tag,"scale") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005824 {
5825 Image
5826 *scale_image;
5827
5828 /*
5829 Scale image.
5830 */
5831 if (msl_info->image[n] == (Image *) NULL)
5832 {
cristyb988fe72009-09-16 01:01:10 +00005833 ThrowMSLException(OptionError,"NoImagesDefined",
5834 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005835 break;
5836 }
5837 if (attributes != (const xmlChar **) NULL)
5838 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5839 {
5840 keyword=(const char *) attributes[i++];
5841 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005842 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00005843 exception);
cristy3ed852e2009-09-05 21:47:34 +00005844 CloneString(&value,attribute);
5845 switch (*keyword)
5846 {
5847 case 'G':
5848 case 'g':
5849 {
5850 if (LocaleCompare(keyword,"geometry") == 0)
5851 {
5852 flags=ParseRegionGeometry(msl_info->image[n],value,
dirk6d6d5f22014-06-20 11:48:54 +00005853 &geometry,exception);
cristy3ed852e2009-09-05 21:47:34 +00005854 break;
5855 }
5856 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5857 keyword);
5858 break;
5859 }
5860 case 'H':
5861 case 'h':
5862 {
5863 if (LocaleCompare(keyword,"height") == 0)
5864 {
cristye27293e2009-12-18 02:53:20 +00005865 geometry.height=StringToUnsignedLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005866 break;
5867 }
5868 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5869 keyword);
5870 break;
5871 }
5872 case 'W':
5873 case 'w':
5874 {
5875 if (LocaleCompare(keyword,"width") == 0)
5876 {
cristyf2f27272009-12-17 14:48:46 +00005877 geometry.width=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00005878 break;
5879 }
5880 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5881 keyword);
5882 break;
5883 }
5884 default:
5885 {
5886 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5887 keyword);
5888 break;
5889 }
5890 }
5891 }
5892 scale_image=ScaleImage(msl_info->image[n],geometry.width,
cristyc82a27b2011-10-21 01:07:16 +00005893 geometry.height,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00005894 if (scale_image == (Image *) NULL)
5895 break;
5896 msl_info->image[n]=DestroyImage(msl_info->image[n]);
5897 msl_info->image[n]=scale_image;
5898 break;
5899 }
cristyb988fe72009-09-16 01:01:10 +00005900 if (LocaleCompare((const char *) tag,"segment") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005901 {
5902 ColorspaceType
5903 colorspace;
5904
5905 MagickBooleanType
5906 verbose;
cristyb988fe72009-09-16 01:01:10 +00005907
cristy3ed852e2009-09-05 21:47:34 +00005908 /*
5909 Segment image.
5910 */
5911 if (msl_info->image[n] == (Image *) NULL)
5912 {
cristyb988fe72009-09-16 01:01:10 +00005913 ThrowMSLException(OptionError,"NoImagesDefined",
5914 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005915 break;
5916 }
5917 geometry_info.rho=1.0;
5918 geometry_info.sigma=1.5;
cristy7020ae62012-04-18 12:58:34 +00005919 colorspace=sRGBColorspace;
cristy3ed852e2009-09-05 21:47:34 +00005920 verbose=MagickFalse;
5921 if (attributes != (const xmlChar **) NULL)
5922 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
5923 {
5924 keyword=(const char *) attributes[i++];
5925 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00005926 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00005927 exception);
cristy3ed852e2009-09-05 21:47:34 +00005928 CloneString(&value,attribute);
5929 switch (*keyword)
5930 {
5931 case 'C':
5932 case 'c':
5933 {
5934 if (LocaleCompare(keyword,"cluster-threshold") == 0)
5935 {
cristydbdd0e32011-11-04 23:29:40 +00005936 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00005937 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005938 break;
5939 }
5940 if (LocaleCompare(keyword,"colorspace") == 0)
5941 {
cristy042ee782011-04-22 18:48:30 +00005942 option=ParseCommandOption(MagickColorspaceOptions,
cristy3ed852e2009-09-05 21:47:34 +00005943 MagickFalse,value);
5944 if (option < 0)
5945 ThrowMSLException(OptionError,
5946 "UnrecognizedColorspaceType",value);
5947 colorspace=(ColorspaceType) option;
5948 break;
5949 }
5950 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5951 keyword);
5952 break;
5953 }
5954 case 'G':
5955 case 'g':
5956 {
5957 if (LocaleCompare(keyword,"geometry") == 0)
5958 {
5959 flags=ParseGeometry(value,&geometry_info);
5960 if ((flags & SigmaValue) == 0)
5961 geometry_info.sigma=1.5;
5962 break;
5963 }
5964 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5965 keyword);
5966 break;
5967 }
5968 case 'S':
5969 case 's':
5970 {
5971 if (LocaleCompare(keyword,"smoothing-threshold") == 0)
5972 {
cristydbdd0e32011-11-04 23:29:40 +00005973 geometry_info.sigma=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00005974 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00005975 break;
5976 }
5977 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5978 keyword);
5979 break;
5980 }
5981 default:
5982 {
5983 ThrowMSLException(OptionError,"UnrecognizedAttribute",
5984 keyword);
5985 break;
5986 }
5987 }
5988 }
5989 (void) SegmentImage(msl_info->image[n],colorspace,verbose,
dirk6d6d5f22014-06-20 11:48:54 +00005990 geometry_info.rho,geometry_info.sigma,exception);
cristy3ed852e2009-09-05 21:47:34 +00005991 break;
5992 }
cristyb988fe72009-09-16 01:01:10 +00005993 else if (LocaleCompare((const char *) tag, "set") == 0)
cristy3ed852e2009-09-05 21:47:34 +00005994 {
5995 if (msl_info->image[n] == (Image *) NULL)
5996 {
cristy0b6d0052011-07-27 23:54:16 +00005997 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00005998 break;
5999 }
6000
6001 if (attributes == (const xmlChar **) NULL)
6002 break;
6003 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6004 {
6005 keyword=(const char *) attributes[i++];
6006 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
dirk6d6d5f22014-06-20 11:48:54 +00006007 msl_info->attributes[n],(const char *) attributes[i],exception));
cristy3ed852e2009-09-05 21:47:34 +00006008 switch (*keyword)
6009 {
cristy3ed852e2009-09-05 21:47:34 +00006010 case 'C':
6011 case 'c':
6012 {
6013 if (LocaleCompare(keyword,"clip-mask") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006014 {
cristy2c8b6312009-09-16 02:37:23 +00006015 for (j=0; j < msl_info->n; j++)
cristy3ed852e2009-09-05 21:47:34 +00006016 {
cristy2c8b6312009-09-16 02:37:23 +00006017 const char
6018 *property;
6019
cristyd15e6592011-10-15 00:13:06 +00006020 property=GetImageProperty(msl_info->attributes[j],"id",
dirk6d6d5f22014-06-20 11:48:54 +00006021 exception);
cristy2c8b6312009-09-16 02:37:23 +00006022 if (LocaleCompare(property,value) == 0)
6023 {
cristy018f07f2011-09-04 21:15:19 +00006024 SetImageMask(msl_info->image[n],msl_info->image[j],
dirk6d6d5f22014-06-20 11:48:54 +00006025 exception);
cristy2c8b6312009-09-16 02:37:23 +00006026 break;
6027 }
cristy3ed852e2009-09-05 21:47:34 +00006028 }
cristy2c8b6312009-09-16 02:37:23 +00006029 break;
cristy3ed852e2009-09-05 21:47:34 +00006030 }
cristy3ed852e2009-09-05 21:47:34 +00006031 if (LocaleCompare(keyword,"clip-path") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006032 {
cristy2c8b6312009-09-16 02:37:23 +00006033 for (j=0; j < msl_info->n; j++)
cristy3ed852e2009-09-05 21:47:34 +00006034 {
cristy2c8b6312009-09-16 02:37:23 +00006035 const char
6036 *property;
6037
cristyd15e6592011-10-15 00:13:06 +00006038 property=GetImageProperty(msl_info->attributes[j],"id",
dirk6d6d5f22014-06-20 11:48:54 +00006039 exception);
cristy2c8b6312009-09-16 02:37:23 +00006040 if (LocaleCompare(property,value) == 0)
6041 {
cristy10a6c612012-01-29 21:41:05 +00006042 SetImageMask(msl_info->image[n],msl_info->image[j],
dirk6d6d5f22014-06-20 11:48:54 +00006043 exception);
cristy2c8b6312009-09-16 02:37:23 +00006044 break;
6045 }
cristy3ed852e2009-09-05 21:47:34 +00006046 }
cristy2c8b6312009-09-16 02:37:23 +00006047 break;
cristy3ed852e2009-09-05 21:47:34 +00006048 }
cristy2c8b6312009-09-16 02:37:23 +00006049 if (LocaleCompare(keyword,"colorspace") == 0)
6050 {
cristybb503372010-05-27 20:51:26 +00006051 ssize_t
cristy2c8b6312009-09-16 02:37:23 +00006052 colorspace;
6053
cristy042ee782011-04-22 18:48:30 +00006054 colorspace=(ColorspaceType) ParseCommandOption(
cristy7e9e6fa2010-11-21 17:06:24 +00006055 MagickColorspaceOptions,MagickFalse,value);
cristy2c8b6312009-09-16 02:37:23 +00006056 if (colorspace < 0)
cristyfb758a52009-09-16 14:36:08 +00006057 ThrowMSLException(OptionError,"UnrecognizedColorspace",
cristy2c8b6312009-09-16 02:37:23 +00006058 value);
6059 (void) TransformImageColorspace(msl_info->image[n],
dirk6d6d5f22014-06-20 11:48:54 +00006060 (ColorspaceType) colorspace,exception);
cristy2c8b6312009-09-16 02:37:23 +00006061 break;
6062 }
6063 (void) SetMSLAttributes(msl_info,keyword,value);
cristyd15e6592011-10-15 00:13:06 +00006064 (void) SetImageProperty(msl_info->image[n],keyword,value,
dirk6d6d5f22014-06-20 11:48:54 +00006065 exception);
cristy3ed852e2009-09-05 21:47:34 +00006066 break;
6067 }
6068 case 'D':
6069 case 'd':
6070 {
cristy2c8b6312009-09-16 02:37:23 +00006071 if (LocaleCompare(keyword,"density") == 0)
6072 {
6073 flags=ParseGeometry(value,&geometry_info);
cristy2a11bef2011-10-28 18:33:11 +00006074 msl_info->image[n]->resolution.x=geometry_info.rho;
6075 msl_info->image[n]->resolution.y=geometry_info.sigma;
cristy2c8b6312009-09-16 02:37:23 +00006076 if ((flags & SigmaValue) == 0)
cristy2a11bef2011-10-28 18:33:11 +00006077 msl_info->image[n]->resolution.y=
6078 msl_info->image[n]->resolution.x;
cristy2c8b6312009-09-16 02:37:23 +00006079 break;
6080 }
6081 (void) SetMSLAttributes(msl_info,keyword,value);
cristyd15e6592011-10-15 00:13:06 +00006082 (void) SetImageProperty(msl_info->image[n],keyword,value,
dirk6d6d5f22014-06-20 11:48:54 +00006083 exception);
cristy3ed852e2009-09-05 21:47:34 +00006084 break;
6085 }
6086 case 'O':
6087 case 'o':
6088 {
6089 if (LocaleCompare(keyword, "opacity") == 0)
cristy2c8b6312009-09-16 02:37:23 +00006090 {
cristy4c08aed2011-07-01 19:47:50 +00006091 ssize_t opac = OpaqueAlpha,
cristybb503372010-05-27 20:51:26 +00006092 len = (ssize_t) strlen( value );
cristy3ed852e2009-09-05 21:47:34 +00006093
cristy2c8b6312009-09-16 02:37:23 +00006094 if (value[len-1] == '%') {
6095 char tmp[100];
6096 (void) CopyMagickString(tmp,value,len);
cristyf2f27272009-12-17 14:48:46 +00006097 opac = StringToLong( tmp );
cristy2c8b6312009-09-16 02:37:23 +00006098 opac = (int)(QuantumRange * ((float)opac/100));
6099 } else
cristyf2f27272009-12-17 14:48:46 +00006100 opac = StringToLong( value );
cristye941a752011-10-15 01:52:48 +00006101 (void) SetImageAlpha( msl_info->image[n], (Quantum) opac,
dirk6d6d5f22014-06-20 11:48:54 +00006102 exception);
cristy2c8b6312009-09-16 02:37:23 +00006103 break;
cristy3ed852e2009-09-05 21:47:34 +00006104 }
cristy2c8b6312009-09-16 02:37:23 +00006105 (void) SetMSLAttributes(msl_info,keyword,value);
cristyd15e6592011-10-15 00:13:06 +00006106 (void) SetImageProperty(msl_info->image[n],keyword,value,
6107 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00006108 break;
6109 }
6110 case 'P':
6111 case 'p':
6112 {
6113 if (LocaleCompare(keyword, "page") == 0)
6114 {
6115 char
cristy151b66d2015-04-15 10:50:31 +00006116 page[MagickPathExtent];
cristy3ed852e2009-09-05 21:47:34 +00006117
6118 const char
6119 *image_option;
6120
6121 MagickStatusType
6122 flags;
6123
6124 RectangleInfo
6125 geometry;
6126
6127 (void) ResetMagickMemory(&geometry,0,sizeof(geometry));
cristy8b206ba2013-04-05 01:11:15 +00006128 image_option=GetImageArtifact(msl_info->image[n],"page");
cristy3ed852e2009-09-05 21:47:34 +00006129 if (image_option != (const char *) NULL)
6130 flags=ParseAbsoluteGeometry(image_option,&geometry);
6131 flags=ParseAbsoluteGeometry(value,&geometry);
cristy151b66d2015-04-15 10:50:31 +00006132 (void) FormatLocaleString(page,MagickPathExtent,"%.20gx%.20g",
cristye8c25f92010-06-03 00:53:06 +00006133 (double) geometry.width,(double) geometry.height);
cristy3ed852e2009-09-05 21:47:34 +00006134 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
cristy151b66d2015-04-15 10:50:31 +00006135 (void) FormatLocaleString(page,MagickPathExtent,
cristye8c25f92010-06-03 00:53:06 +00006136 "%.20gx%.20g%+.20g%+.20g",(double) geometry.width,
6137 (double) geometry.height,(double) geometry.x,(double)
cristyf2faecf2010-05-28 19:19:36 +00006138 geometry.y);
cristy3ed852e2009-09-05 21:47:34 +00006139 (void) SetImageOption(msl_info->image_info[n],keyword,page);
6140 msl_info->image_info[n]->page=GetPageGeometry(page);
6141 break;
6142 }
cristy2c8b6312009-09-16 02:37:23 +00006143 (void) SetMSLAttributes(msl_info,keyword,value);
cristyd15e6592011-10-15 00:13:06 +00006144 (void) SetImageProperty(msl_info->image[n],keyword,value,
6145 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00006146 break;
6147 }
6148 default:
6149 {
cristy2c8b6312009-09-16 02:37:23 +00006150 (void) SetMSLAttributes(msl_info,keyword,value);
cristyd15e6592011-10-15 00:13:06 +00006151 (void) SetImageProperty(msl_info->image[n],keyword,value,
6152 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00006153 break;
6154 }
6155 }
6156 }
6157 break;
6158 }
cristyb988fe72009-09-16 01:01:10 +00006159 if (LocaleCompare((const char *) tag,"shade") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006160 {
6161 Image
6162 *shade_image;
6163
6164 MagickBooleanType
6165 gray;
6166
6167 /*
6168 Shade image.
6169 */
6170 if (msl_info->image[n] == (Image *) NULL)
6171 {
cristyb988fe72009-09-16 01:01:10 +00006172 ThrowMSLException(OptionError,"NoImagesDefined",
6173 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006174 break;
6175 }
6176 gray=MagickFalse;
6177 if (attributes != (const xmlChar **) NULL)
6178 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6179 {
6180 keyword=(const char *) attributes[i++];
6181 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006182 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00006183 exception);
cristy3ed852e2009-09-05 21:47:34 +00006184 CloneString(&value,attribute);
6185 switch (*keyword)
6186 {
6187 case 'A':
6188 case 'a':
6189 {
6190 if (LocaleCompare(keyword,"azimuth") == 0)
6191 {
cristydbdd0e32011-11-04 23:29:40 +00006192 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00006193 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006194 break;
6195 }
6196 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6197 keyword);
6198 break;
6199 }
6200 case 'E':
6201 case 'e':
6202 {
6203 if (LocaleCompare(keyword,"elevation") == 0)
6204 {
cristydbdd0e32011-11-04 23:29:40 +00006205 geometry_info.sigma=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00006206 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006207 break;
6208 }
6209 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6210 keyword);
6211 break;
6212 }
6213 case 'G':
6214 case 'g':
6215 {
6216 if (LocaleCompare(keyword,"geometry") == 0)
6217 {
6218 flags=ParseGeometry(value,&geometry_info);
6219 if ((flags & SigmaValue) == 0)
6220 geometry_info.sigma=1.0;
6221 break;
6222 }
6223 if (LocaleCompare(keyword,"gray") == 0)
6224 {
cristy042ee782011-04-22 18:48:30 +00006225 option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00006226 value);
6227 if (option < 0)
6228 ThrowMSLException(OptionError,"UnrecognizedNoiseType",
6229 value);
6230 gray=(MagickBooleanType) option;
6231 break;
6232 }
6233 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6234 keyword);
6235 break;
6236 }
6237 default:
6238 {
6239 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6240 keyword);
6241 break;
6242 }
6243 }
6244 }
6245 shade_image=ShadeImage(msl_info->image[n],gray,geometry_info.rho,
cristyc82a27b2011-10-21 01:07:16 +00006246 geometry_info.sigma,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00006247 if (shade_image == (Image *) NULL)
6248 break;
6249 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6250 msl_info->image[n]=shade_image;
6251 break;
6252 }
cristyb988fe72009-09-16 01:01:10 +00006253 if (LocaleCompare((const char *) tag,"shadow") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006254 {
6255 Image
6256 *shadow_image;
6257
6258 /*
6259 Shear image.
6260 */
6261 if (msl_info->image[n] == (Image *) NULL)
6262 {
cristyb988fe72009-09-16 01:01:10 +00006263 ThrowMSLException(OptionError,"NoImagesDefined",
6264 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006265 break;
6266 }
6267 if (attributes != (const xmlChar **) NULL)
6268 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6269 {
6270 keyword=(const char *) attributes[i++];
6271 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006272 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00006273 exception);
cristy3ed852e2009-09-05 21:47:34 +00006274 CloneString(&value,attribute);
6275 switch (*keyword)
6276 {
6277 case 'G':
6278 case 'g':
6279 {
6280 if (LocaleCompare(keyword,"geometry") == 0)
6281 {
6282 flags=ParseGeometry(value,&geometry_info);
6283 if ((flags & SigmaValue) == 0)
6284 geometry_info.sigma=1.0;
6285 break;
6286 }
6287 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6288 keyword);
6289 break;
6290 }
6291 case 'O':
6292 case 'o':
6293 {
6294 if (LocaleCompare(keyword,"opacity") == 0)
6295 {
cristyf2f27272009-12-17 14:48:46 +00006296 geometry_info.rho=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006297 break;
6298 }
6299 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6300 keyword);
6301 break;
6302 }
6303 case 'S':
6304 case 's':
6305 {
6306 if (LocaleCompare(keyword,"sigma") == 0)
6307 {
cristyf2f27272009-12-17 14:48:46 +00006308 geometry_info.sigma=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006309 break;
6310 }
6311 break;
6312 }
6313 case 'X':
6314 case 'x':
6315 {
6316 if (LocaleCompare(keyword,"x") == 0)
6317 {
cristydbdd0e32011-11-04 23:29:40 +00006318 geometry_info.xi=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00006319 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006320 break;
6321 }
6322 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6323 keyword);
6324 break;
6325 }
6326 case 'Y':
6327 case 'y':
6328 {
6329 if (LocaleCompare(keyword,"y") == 0)
6330 {
cristyf2f27272009-12-17 14:48:46 +00006331 geometry_info.psi=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006332 break;
6333 }
6334 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6335 keyword);
6336 break;
6337 }
6338 default:
6339 {
6340 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6341 keyword);
6342 break;
6343 }
6344 }
6345 }
6346 shadow_image=ShadowImage(msl_info->image[n],geometry_info.rho,
cristyaa2c16c2012-03-25 22:21:35 +00006347 geometry_info.sigma,(ssize_t) ceil(geometry_info.xi-0.5),
cristyeb6e6582011-12-09 09:14:23 +00006348 (ssize_t) ceil(geometry_info.psi-0.5),msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00006349 if (shadow_image == (Image *) NULL)
6350 break;
6351 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6352 msl_info->image[n]=shadow_image;
6353 break;
6354 }
cristyb988fe72009-09-16 01:01:10 +00006355 if (LocaleCompare((const char *) tag,"sharpen") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006356 {
cristyaa2c16c2012-03-25 22:21:35 +00006357 double
cristy05c0c9a2011-09-05 23:16:13 +00006358 radius = 0.0,
cristy3ed852e2009-09-05 21:47:34 +00006359 sigma = 1.0;
6360
6361 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00006362 {
6363 ThrowMSLException(OptionError,"NoImagesDefined",
6364 (const char *) tag);
6365 break;
6366 }
cristy3ed852e2009-09-05 21:47:34 +00006367 /*
6368 NOTE: sharpen can have no attributes, since we use all the defaults!
6369 */
6370 if (attributes != (const xmlChar **) NULL)
6371 {
6372 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6373 {
6374 keyword=(const char *) attributes[i++];
6375 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
dirk6d6d5f22014-06-20 11:48:54 +00006376 msl_info->attributes[n],(const char *) attributes[i],exception));
cristy3ed852e2009-09-05 21:47:34 +00006377 switch (*keyword)
6378 {
6379 case 'R':
6380 case 'r':
6381 {
6382 if (LocaleCompare(keyword, "radius") == 0)
6383 {
cristydbdd0e32011-11-04 23:29:40 +00006384 radius = StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006385 break;
6386 }
6387 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6388 break;
6389 }
6390 case 'S':
6391 case 's':
6392 {
6393 if (LocaleCompare(keyword,"sigma") == 0)
6394 {
cristyf2f27272009-12-17 14:48:46 +00006395 sigma = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00006396 break;
6397 }
6398 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6399 break;
6400 }
6401 default:
6402 {
6403 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6404 break;
6405 }
6406 }
6407 }
6408 }
6409
6410 /*
6411 sharpen image.
6412 */
6413 {
6414 Image
6415 *newImage;
6416
cristyaa2c16c2012-03-25 22:21:35 +00006417 newImage=SharpenImage(msl_info->image[n],radius,sigma,
cristyc82a27b2011-10-21 01:07:16 +00006418 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00006419 if (newImage == (Image *) NULL)
6420 break;
6421 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6422 msl_info->image[n]=newImage;
6423 break;
6424 }
6425 }
cristyb988fe72009-09-16 01:01:10 +00006426 else if (LocaleCompare((const char *) tag,"shave") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006427 {
6428 /* init the values */
6429 width = height = 0;
6430 x = y = 0;
6431
6432 if (msl_info->image[n] == (Image *) NULL)
6433 {
cristyb988fe72009-09-16 01:01:10 +00006434 ThrowMSLException(OptionError,"NoImagesDefined",
6435 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006436 break;
6437 }
6438 if (attributes == (const xmlChar **) NULL)
6439 break;
6440 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6441 {
6442 keyword=(const char *) attributes[i++];
6443 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
dirk6d6d5f22014-06-20 11:48:54 +00006444 msl_info->attributes[n],(const char *) attributes[i],exception));
cristy3ed852e2009-09-05 21:47:34 +00006445 switch (*keyword)
6446 {
6447 case 'G':
6448 case 'g':
6449 {
6450 if (LocaleCompare(keyword,"geometry") == 0)
6451 {
6452 (void) ParseMetaGeometry(value,&x,&y,&width,&height);
6453 break;
6454 }
6455 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6456 break;
6457 }
6458 case 'H':
6459 case 'h':
6460 {
6461 if (LocaleCompare(keyword,"height") == 0)
6462 {
cristyf2f27272009-12-17 14:48:46 +00006463 height = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00006464 break;
6465 }
6466 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6467 break;
6468 }
6469 case 'W':
6470 case 'w':
6471 {
6472 if (LocaleCompare(keyword,"width") == 0)
6473 {
cristyf2f27272009-12-17 14:48:46 +00006474 width = StringToLong( value );
cristy3ed852e2009-09-05 21:47:34 +00006475 break;
6476 }
6477 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6478 break;
6479 }
6480 default:
6481 {
6482 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6483 break;
6484 }
6485 }
6486 }
6487
6488 /*
6489 process image.
6490 */
6491 {
6492 Image
6493 *newImage;
6494 RectangleInfo
6495 rectInfo;
6496
6497 rectInfo.height = height;
6498 rectInfo.width = width;
6499 rectInfo.x = x;
6500 rectInfo.y = y;
6501
6502
6503 newImage=ShaveImage(msl_info->image[n], &rectInfo,
cristyc82a27b2011-10-21 01:07:16 +00006504 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00006505 if (newImage == (Image *) NULL)
6506 break;
6507 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6508 msl_info->image[n]=newImage;
6509 }
6510
6511 break;
6512 }
cristyb988fe72009-09-16 01:01:10 +00006513 if (LocaleCompare((const char *) tag,"shear") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006514 {
6515 Image
6516 *shear_image;
6517
6518 /*
6519 Shear image.
6520 */
6521 if (msl_info->image[n] == (Image *) NULL)
6522 {
cristyb988fe72009-09-16 01:01:10 +00006523 ThrowMSLException(OptionError,"NoImagesDefined",
6524 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006525 break;
6526 }
6527 if (attributes != (const xmlChar **) NULL)
6528 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6529 {
6530 keyword=(const char *) attributes[i++];
6531 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006532 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00006533 exception);
cristy3ed852e2009-09-05 21:47:34 +00006534 CloneString(&value,attribute);
6535 switch (*keyword)
6536 {
6537 case 'F':
6538 case 'f':
6539 {
6540 if (LocaleCompare(keyword, "fill") == 0)
6541 {
cristy9950d572011-10-01 18:22:35 +00006542 (void) QueryColorCompliance(value,AllCompliance,
dirk6d6d5f22014-06-20 11:48:54 +00006543 &msl_info->image[n]->background_color,exception);
cristy3ed852e2009-09-05 21:47:34 +00006544 break;
6545 }
6546 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6547 keyword);
6548 break;
6549 }
6550 case 'G':
6551 case 'g':
6552 {
6553 if (LocaleCompare(keyword,"geometry") == 0)
6554 {
6555 flags=ParseGeometry(value,&geometry_info);
6556 if ((flags & SigmaValue) == 0)
6557 geometry_info.sigma=1.0;
6558 break;
6559 }
6560 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6561 keyword);
6562 break;
6563 }
6564 case 'X':
6565 case 'x':
6566 {
6567 if (LocaleCompare(keyword,"x") == 0)
6568 {
cristydbdd0e32011-11-04 23:29:40 +00006569 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00006570 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006571 break;
6572 }
6573 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6574 keyword);
6575 break;
6576 }
6577 case 'Y':
6578 case 'y':
6579 {
6580 if (LocaleCompare(keyword,"y") == 0)
6581 {
cristyf2f27272009-12-17 14:48:46 +00006582 geometry_info.sigma=StringToLong(value);
cristy3ed852e2009-09-05 21:47:34 +00006583 break;
6584 }
6585 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6586 keyword);
6587 break;
6588 }
6589 default:
6590 {
6591 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6592 keyword);
6593 break;
6594 }
6595 }
6596 }
6597 shear_image=ShearImage(msl_info->image[n],geometry_info.rho,
cristyc82a27b2011-10-21 01:07:16 +00006598 geometry_info.sigma,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00006599 if (shear_image == (Image *) NULL)
6600 break;
6601 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6602 msl_info->image[n]=shear_image;
6603 break;
6604 }
cristyb988fe72009-09-16 01:01:10 +00006605 if (LocaleCompare((const char *) tag,"signature") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006606 {
6607 /*
6608 Signature image.
6609 */
6610 if (msl_info->image[n] == (Image *) NULL)
6611 {
cristyb988fe72009-09-16 01:01:10 +00006612 ThrowMSLException(OptionError,"NoImagesDefined",
6613 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006614 break;
6615 }
6616 if (attributes != (const xmlChar **) NULL)
6617 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6618 {
6619 keyword=(const char *) attributes[i++];
6620 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006621 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00006622 exception);
cristy3ed852e2009-09-05 21:47:34 +00006623 CloneString(&value,attribute);
6624 switch (*keyword)
6625 {
6626 default:
6627 {
6628 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6629 keyword);
6630 break;
6631 }
6632 }
6633 }
dirk6d6d5f22014-06-20 11:48:54 +00006634 (void) SignatureImage(msl_info->image[n],exception);
cristy3ed852e2009-09-05 21:47:34 +00006635 break;
6636 }
cristyb988fe72009-09-16 01:01:10 +00006637 if (LocaleCompare((const char *) tag,"solarize") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006638 {
6639 /*
6640 Solarize image.
6641 */
6642 if (msl_info->image[n] == (Image *) NULL)
6643 {
cristyb988fe72009-09-16 01:01:10 +00006644 ThrowMSLException(OptionError,"NoImagesDefined",
6645 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006646 break;
6647 }
6648 geometry_info.rho=QuantumRange/2.0;
6649 if (attributes != (const xmlChar **) NULL)
6650 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6651 {
6652 keyword=(const char *) attributes[i++];
6653 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006654 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00006655 exception);
cristy3ed852e2009-09-05 21:47:34 +00006656 CloneString(&value,attribute);
6657 switch (*keyword)
6658 {
6659 case 'G':
6660 case 'g':
6661 {
6662 if (LocaleCompare(keyword,"geometry") == 0)
6663 {
6664 flags=ParseGeometry(value,&geometry_info);
6665 break;
6666 }
6667 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6668 keyword);
6669 break;
6670 }
6671 case 'T':
6672 case 't':
6673 {
6674 if (LocaleCompare(keyword,"threshold") == 0)
6675 {
cristydbdd0e32011-11-04 23:29:40 +00006676 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00006677 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006678 break;
6679 }
6680 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6681 keyword);
6682 break;
6683 }
6684 default:
6685 {
6686 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6687 keyword);
6688 break;
6689 }
6690 }
6691 }
cristy5cbc0162011-08-29 00:36:28 +00006692 (void) SolarizeImage(msl_info->image[n],geometry_info.rho,
cristyc82a27b2011-10-21 01:07:16 +00006693 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00006694 break;
6695 }
cristyb988fe72009-09-16 01:01:10 +00006696 if (LocaleCompare((const char *) tag,"spread") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006697 {
6698 Image
6699 *spread_image;
6700
6701 /*
6702 Spread image.
6703 */
6704 if (msl_info->image[n] == (Image *) NULL)
6705 {
cristyb988fe72009-09-16 01:01:10 +00006706 ThrowMSLException(OptionError,"NoImagesDefined",
6707 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006708 break;
6709 }
6710 if (attributes != (const xmlChar **) NULL)
6711 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6712 {
6713 keyword=(const char *) attributes[i++];
6714 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006715 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00006716 exception);
cristy3ed852e2009-09-05 21:47:34 +00006717 CloneString(&value,attribute);
6718 switch (*keyword)
6719 {
6720 case 'G':
6721 case 'g':
6722 {
6723 if (LocaleCompare(keyword,"geometry") == 0)
6724 {
6725 flags=ParseGeometry(value,&geometry_info);
6726 if ((flags & SigmaValue) == 0)
6727 geometry_info.sigma=1.0;
6728 break;
6729 }
6730 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6731 keyword);
6732 break;
6733 }
6734 case 'R':
6735 case 'r':
6736 {
6737 if (LocaleCompare(keyword,"radius") == 0)
6738 {
cristydbdd0e32011-11-04 23:29:40 +00006739 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00006740 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00006741 break;
6742 }
6743 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6744 keyword);
6745 break;
6746 }
6747 default:
6748 {
6749 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6750 keyword);
6751 break;
6752 }
6753 }
6754 }
6755 spread_image=SpreadImage(msl_info->image[n],geometry_info.rho,
cristyc82a27b2011-10-21 01:07:16 +00006756 msl_info->image[n]->interpolate,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00006757 if (spread_image == (Image *) NULL)
6758 break;
6759 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6760 msl_info->image[n]=spread_image;
6761 break;
6762 }
cristyb988fe72009-09-16 01:01:10 +00006763 else if (LocaleCompare((const char *) tag,"stegano") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006764 {
6765 Image *
cristyf432c632014-12-07 15:11:28 +00006766 watermark = (Image*) NULL;
cristy3ed852e2009-09-05 21:47:34 +00006767
6768 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00006769 {
6770 ThrowMSLException(OptionError,"NoImagesDefined",
6771 (const char *) tag);
6772 break;
6773 }
cristy3ed852e2009-09-05 21:47:34 +00006774 if (attributes == (const xmlChar **) NULL)
6775 break;
6776 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6777 {
6778 keyword=(const char *) attributes[i++];
6779 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
dirk6d6d5f22014-06-20 11:48:54 +00006780 msl_info->attributes[n],(const char *) attributes[i],exception));
cristy3ed852e2009-09-05 21:47:34 +00006781 switch (*keyword)
6782 {
6783 case 'I':
6784 case 'i':
6785 {
6786 if (LocaleCompare(keyword,"image") == 0)
6787 {
6788 for (j=0; j<msl_info->n;j++)
6789 {
6790 const char *
cristyd15e6592011-10-15 00:13:06 +00006791 theAttr = GetImageProperty(msl_info->attributes[j], "id",
dirk6d6d5f22014-06-20 11:48:54 +00006792 exception);
cristy3ed852e2009-09-05 21:47:34 +00006793 if (theAttr && LocaleCompare(theAttr, value) == 0)
6794 {
6795 watermark = msl_info->image[j];
6796 break;
6797 }
6798 }
6799 break;
6800 }
6801 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6802 break;
6803 }
6804 default:
6805 {
6806 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6807 break;
6808 }
6809 }
6810 }
6811
6812 /*
6813 process image.
6814 */
6815 if ( watermark != (Image*) NULL )
6816 {
6817 Image
6818 *newImage;
6819
cristyc82a27b2011-10-21 01:07:16 +00006820 newImage=SteganoImage(msl_info->image[n], watermark, msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00006821 if (newImage == (Image *) NULL)
6822 break;
6823 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6824 msl_info->image[n]=newImage;
6825 break;
6826 } else
6827 ThrowMSLException(OptionError,"MissingWatermarkImage",keyword);
6828 }
cristyb988fe72009-09-16 01:01:10 +00006829 else if (LocaleCompare((const char *) tag,"stereo") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006830 {
6831 Image *
cristyf432c632014-12-07 15:11:28 +00006832 stereoImage = (Image*) NULL;
cristy3ed852e2009-09-05 21:47:34 +00006833
6834 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00006835 {
6836 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
6837 break;
6838 }
cristy3ed852e2009-09-05 21:47:34 +00006839 if (attributes == (const xmlChar **) NULL)
6840 break;
6841 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6842 {
6843 keyword=(const char *) attributes[i++];
6844 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
dirk6d6d5f22014-06-20 11:48:54 +00006845 msl_info->attributes[n],(const char *) attributes[i],exception));
cristy3ed852e2009-09-05 21:47:34 +00006846 switch (*keyword)
6847 {
6848 case 'I':
6849 case 'i':
6850 {
6851 if (LocaleCompare(keyword,"image") == 0)
6852 {
6853 for (j=0; j<msl_info->n;j++)
6854 {
6855 const char *
cristyd15e6592011-10-15 00:13:06 +00006856 theAttr = GetImageProperty(msl_info->attributes[j], "id",
dirk6d6d5f22014-06-20 11:48:54 +00006857 exception);
cristy3ed852e2009-09-05 21:47:34 +00006858 if (theAttr && LocaleCompare(theAttr, value) == 0)
6859 {
6860 stereoImage = msl_info->image[j];
6861 break;
6862 }
6863 }
6864 break;
6865 }
6866 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6867 break;
6868 }
6869 default:
6870 {
6871 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6872 break;
6873 }
6874 }
6875 }
6876
6877 /*
6878 process image.
6879 */
6880 if ( stereoImage != (Image*) NULL )
6881 {
6882 Image
6883 *newImage;
6884
cristyc82a27b2011-10-21 01:07:16 +00006885 newImage=StereoImage(msl_info->image[n], stereoImage, msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00006886 if (newImage == (Image *) NULL)
6887 break;
6888 msl_info->image[n]=DestroyImage(msl_info->image[n]);
6889 msl_info->image[n]=newImage;
6890 break;
6891 } else
6892 ThrowMSLException(OptionError,"Missing stereo image",keyword);
6893 }
cristy8b2b4e52012-06-27 01:01:10 +00006894 if (LocaleCompare((const char *) tag,"strip") == 0)
6895 {
cristy8b2b4e52012-06-27 01:01:10 +00006896 /*
cristyae497ba2012-06-27 01:01:51 +00006897 Strip image.
cristy8b2b4e52012-06-27 01:01:10 +00006898 */
6899 if (msl_info->image[n] == (Image *) NULL)
6900 {
6901 ThrowMSLException(OptionError,"NoImagesDefined",
6902 (const char *) tag);
6903 break;
6904 }
6905 if (attributes != (const xmlChar **) NULL)
6906 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6907 {
6908 keyword=(const char *) attributes[i++];
6909 attribute=InterpretImageProperties(msl_info->image_info[n],
6910 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00006911 exception);
cristy8b2b4e52012-06-27 01:01:10 +00006912 CloneString(&value,attribute);
6913 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
6914 }
6915 (void) StripImage(msl_info->image[n],msl_info->exception);
6916 break;
6917 }
cristyb988fe72009-09-16 01:01:10 +00006918 if (LocaleCompare((const char *) tag,"swap") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006919 {
6920 Image
6921 *p,
6922 *q,
6923 *swap;
6924
cristybb503372010-05-27 20:51:26 +00006925 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00006926 index,
6927 swap_index;
6928
6929 if (msl_info->image[n] == (Image *) NULL)
6930 {
cristyb988fe72009-09-16 01:01:10 +00006931 ThrowMSLException(OptionError,"NoImagesDefined",
6932 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006933 break;
6934 }
6935 index=(-1);
6936 swap_index=(-2);
6937 if (attributes != (const xmlChar **) NULL)
6938 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
6939 {
6940 keyword=(const char *) attributes[i++];
6941 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00006942 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00006943 exception);
cristy3ed852e2009-09-05 21:47:34 +00006944 CloneString(&value,attribute);
6945 switch (*keyword)
6946 {
6947 case 'G':
6948 case 'g':
6949 {
6950 if (LocaleCompare(keyword,"indexes") == 0)
6951 {
6952 flags=ParseGeometry(value,&geometry_info);
cristybb503372010-05-27 20:51:26 +00006953 index=(ssize_t) geometry_info.rho;
cristy3ed852e2009-09-05 21:47:34 +00006954 if ((flags & SigmaValue) == 0)
cristybb503372010-05-27 20:51:26 +00006955 swap_index=(ssize_t) geometry_info.sigma;
cristy3ed852e2009-09-05 21:47:34 +00006956 break;
6957 }
6958 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6959 keyword);
6960 break;
6961 }
6962 default:
6963 {
6964 ThrowMSLException(OptionError,"UnrecognizedAttribute",
6965 keyword);
6966 break;
6967 }
6968 }
6969 }
6970 /*
6971 Swap images.
6972 */
6973 p=GetImageFromList(msl_info->image[n],index);
6974 q=GetImageFromList(msl_info->image[n],swap_index);
6975 if ((p == (Image *) NULL) || (q == (Image *) NULL))
6976 {
cristyb988fe72009-09-16 01:01:10 +00006977 ThrowMSLException(OptionError,"NoSuchImage",(const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006978 break;
6979 }
cristyc82a27b2011-10-21 01:07:16 +00006980 swap=CloneImage(p,0,0,MagickTrue,msl_info->exception);
6981 ReplaceImageInList(&p,CloneImage(q,0,0,MagickTrue,
6982 msl_info->exception));
cristy3ed852e2009-09-05 21:47:34 +00006983 ReplaceImageInList(&q,swap);
6984 msl_info->image[n]=GetFirstImageInList(q);
6985 break;
6986 }
cristyb988fe72009-09-16 01:01:10 +00006987 if (LocaleCompare((const char *) tag,"swirl") == 0)
cristy3ed852e2009-09-05 21:47:34 +00006988 {
6989 Image
6990 *swirl_image;
6991
6992 /*
6993 Swirl image.
6994 */
6995 if (msl_info->image[n] == (Image *) NULL)
6996 {
cristyb988fe72009-09-16 01:01:10 +00006997 ThrowMSLException(OptionError,"NoImagesDefined",
6998 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00006999 break;
7000 }
7001 if (attributes != (const xmlChar **) NULL)
7002 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7003 {
7004 keyword=(const char *) attributes[i++];
7005 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00007006 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00007007 exception);
cristy3ed852e2009-09-05 21:47:34 +00007008 CloneString(&value,attribute);
7009 switch (*keyword)
7010 {
7011 case 'D':
7012 case 'd':
7013 {
7014 if (LocaleCompare(keyword,"degrees") == 0)
7015 {
cristydbdd0e32011-11-04 23:29:40 +00007016 geometry_info.rho=StringToDouble(value,
cristyc1acd842011-05-19 23:05:47 +00007017 (char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00007018 break;
7019 }
7020 ThrowMSLException(OptionError,"UnrecognizedAttribute",
7021 keyword);
7022 break;
7023 }
7024 case 'G':
7025 case 'g':
7026 {
7027 if (LocaleCompare(keyword,"geometry") == 0)
7028 {
7029 flags=ParseGeometry(value,&geometry_info);
7030 if ((flags & SigmaValue) == 0)
7031 geometry_info.sigma=1.0;
7032 break;
7033 }
7034 ThrowMSLException(OptionError,"UnrecognizedAttribute",
7035 keyword);
7036 break;
7037 }
7038 default:
7039 {
7040 ThrowMSLException(OptionError,"UnrecognizedAttribute",
7041 keyword);
7042 break;
7043 }
7044 }
7045 }
7046 swirl_image=SwirlImage(msl_info->image[n],geometry_info.rho,
cristyc82a27b2011-10-21 01:07:16 +00007047 msl_info->image[n]->interpolate,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00007048 if (swirl_image == (Image *) NULL)
7049 break;
7050 msl_info->image[n]=DestroyImage(msl_info->image[n]);
7051 msl_info->image[n]=swirl_image;
7052 break;
7053 }
cristyb988fe72009-09-16 01:01:10 +00007054 if (LocaleCompare((const char *) tag,"sync") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007055 {
7056 /*
7057 Sync image.
7058 */
7059 if (msl_info->image[n] == (Image *) NULL)
7060 {
cristyb988fe72009-09-16 01:01:10 +00007061 ThrowMSLException(OptionError,"NoImagesDefined",
7062 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00007063 break;
7064 }
7065 if (attributes != (const xmlChar **) NULL)
7066 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7067 {
7068 keyword=(const char *) attributes[i++];
7069 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00007070 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00007071 exception);
cristy3ed852e2009-09-05 21:47:34 +00007072 CloneString(&value,attribute);
7073 switch (*keyword)
7074 {
7075 default:
7076 {
7077 ThrowMSLException(OptionError,"UnrecognizedAttribute",
7078 keyword);
7079 break;
7080 }
7081 }
7082 }
dirk6d6d5f22014-06-20 11:48:54 +00007083 (void) SyncImage(msl_info->image[n],exception);
cristy3ed852e2009-09-05 21:47:34 +00007084 break;
7085 }
7086 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7087 }
7088 case 'T':
7089 case 't':
7090 {
cristyb988fe72009-09-16 01:01:10 +00007091 if (LocaleCompare((const char *) tag,"map") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007092 {
7093 Image
7094 *texture_image;
7095
7096 /*
7097 Texture image.
7098 */
7099 if (msl_info->image[n] == (Image *) NULL)
7100 {
cristyb988fe72009-09-16 01:01:10 +00007101 ThrowMSLException(OptionError,"NoImagesDefined",
7102 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00007103 break;
7104 }
7105 texture_image=NewImageList();
7106 if (attributes != (const xmlChar **) NULL)
7107 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7108 {
7109 keyword=(const char *) attributes[i++];
7110 attribute=InterpretImageProperties(msl_info->image_info[n],
cristy018f07f2011-09-04 21:15:19 +00007111 msl_info->attributes[n],(const char *) attributes[i],
dirk6d6d5f22014-06-20 11:48:54 +00007112 exception);
cristy3ed852e2009-09-05 21:47:34 +00007113 CloneString(&value,attribute);
7114 switch (*keyword)
7115 {
7116 case 'I':
7117 case 'i':
7118 {
7119 if (LocaleCompare(keyword,"image") == 0)
7120 for (j=0; j < msl_info->n; j++)
7121 {
7122 const char
7123 *attribute;
cristyb988fe72009-09-16 01:01:10 +00007124
cristyd15e6592011-10-15 00:13:06 +00007125 attribute=GetImageProperty(msl_info->attributes[j],"id",
dirk6d6d5f22014-06-20 11:48:54 +00007126 exception);
cristy3ed852e2009-09-05 21:47:34 +00007127 if ((attribute != (const char *) NULL) &&
7128 (LocaleCompare(attribute,value) == 0))
7129 {
7130 texture_image=CloneImage(msl_info->image[j],0,0,
dirk6d6d5f22014-06-20 11:48:54 +00007131 MagickFalse,exception);
cristy3ed852e2009-09-05 21:47:34 +00007132 break;
7133 }
7134 }
7135 break;
7136 }
7137 default:
7138 {
7139 ThrowMSLException(OptionError,"UnrecognizedAttribute",
7140 keyword);
7141 break;
7142 }
7143 }
7144 }
dirk6d6d5f22014-06-20 11:48:54 +00007145 (void) TextureImage(msl_info->image[n],texture_image,exception);
cristy3ed852e2009-09-05 21:47:34 +00007146 texture_image=DestroyImage(texture_image);
7147 break;
7148 }
cristyb988fe72009-09-16 01:01:10 +00007149 else if (LocaleCompare((const char *) tag,"threshold") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007150 {
7151 /* init the values */
7152 double threshold = 0;
7153
7154 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007155 {
7156 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7157 break;
7158 }
cristy3ed852e2009-09-05 21:47:34 +00007159 if (attributes == (const xmlChar **) NULL)
7160 break;
7161 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7162 {
7163 keyword=(const char *) attributes[i++];
7164 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
dirk6d6d5f22014-06-20 11:48:54 +00007165 msl_info->attributes[n],(const char *) attributes[i],exception));
cristy3ed852e2009-09-05 21:47:34 +00007166 switch (*keyword)
7167 {
7168 case 'T':
7169 case 't':
7170 {
7171 if (LocaleCompare(keyword,"threshold") == 0)
7172 {
cristydbdd0e32011-11-04 23:29:40 +00007173 threshold = StringToDouble(value,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +00007174 break;
7175 }
7176 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7177 break;
7178 }
7179 default:
7180 {
7181 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7182 break;
7183 }
7184 }
7185 }
7186
7187 /*
7188 process image.
7189 */
7190 {
dirk6d6d5f22014-06-20 11:48:54 +00007191 BilevelImage(msl_info->image[n],threshold,exception);
cristye941a752011-10-15 01:52:48 +00007192 break;
cristy3ed852e2009-09-05 21:47:34 +00007193 }
7194 }
cristyb988fe72009-09-16 01:01:10 +00007195 else if (LocaleCompare((const char *) tag, "transparent") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007196 {
7197 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007198 {
7199 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7200 break;
7201 }
cristy3ed852e2009-09-05 21:47:34 +00007202 if (attributes == (const xmlChar **) NULL)
7203 break;
7204 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7205 {
7206 keyword=(const char *) attributes[i++];
7207 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
dirk6d6d5f22014-06-20 11:48:54 +00007208 msl_info->attributes[n],(const char *) attributes[i],exception));
cristy3ed852e2009-09-05 21:47:34 +00007209 switch (*keyword)
7210 {
7211 case 'C':
7212 case 'c':
7213 {
7214 if (LocaleCompare(keyword,"color") == 0)
7215 {
cristy4c08aed2011-07-01 19:47:50 +00007216 PixelInfo
cristy3ed852e2009-09-05 21:47:34 +00007217 target;
7218
cristy269c9412011-10-13 23:41:15 +00007219 (void) QueryColorCompliance(value,AllCompliance,&target,
dirk6d6d5f22014-06-20 11:48:54 +00007220 exception);
cristy3ed852e2009-09-05 21:47:34 +00007221 (void) TransparentPaintImage(msl_info->image[n],&target,
cristyc82a27b2011-10-21 01:07:16 +00007222 TransparentAlpha,MagickFalse,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00007223 break;
7224 }
7225 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7226 break;
7227 }
7228 default:
7229 {
7230 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
7231 break;
7232 }
7233 }
7234 }
7235 break;
7236 }
cristyb988fe72009-09-16 01:01:10 +00007237 else if (LocaleCompare((const char *) tag, "trim") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007238 {
7239 if (msl_info->image[n] == (Image *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007240 {
7241 ThrowMSLException(OptionError,"NoImagesDefined",(const char *) tag);
7242 break;
7243 }
cristy3ed852e2009-09-05 21:47:34 +00007244
7245 /* no attributes here */
7246
7247 /* process the image */
7248 {
7249 Image
7250 *newImage;
7251 RectangleInfo
7252 rectInfo;
7253
7254 /* all zeros on a crop == trim edges! */
7255 rectInfo.height = rectInfo.width = 0;
7256 rectInfo.x = rectInfo.y = 0;
7257
cristyc82a27b2011-10-21 01:07:16 +00007258 newImage=CropImage(msl_info->image[n],&rectInfo, msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00007259 if (newImage == (Image *) NULL)
7260 break;
7261 msl_info->image[n]=DestroyImage(msl_info->image[n]);
7262 msl_info->image[n]=newImage;
7263 break;
7264 }
7265 }
7266 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7267 }
7268 case 'W':
7269 case 'w':
7270 {
cristyb988fe72009-09-16 01:01:10 +00007271 if (LocaleCompare((const char *) tag,"write") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007272 {
7273 if (msl_info->image[n] == (Image *) NULL)
7274 {
cristyb988fe72009-09-16 01:01:10 +00007275 ThrowMSLException(OptionError,"NoImagesDefined",
7276 (const char *) tag);
cristy3ed852e2009-09-05 21:47:34 +00007277 break;
7278 }
7279 if (attributes == (const xmlChar **) NULL)
7280 break;
7281 for (i=0; (attributes[i] != (const xmlChar *) NULL); i++)
7282 {
7283 keyword=(const char *) attributes[i++];
7284 CloneString(&value,InterpretImageProperties(msl_info->image_info[n],
dirk6d6d5f22014-06-20 11:48:54 +00007285 msl_info->attributes[n],(const char *) attributes[i],exception));
cristy3ed852e2009-09-05 21:47:34 +00007286 switch (*keyword)
7287 {
7288 case 'F':
7289 case 'f':
7290 {
7291 if (LocaleCompare(keyword,"filename") == 0)
7292 {
7293 (void) CopyMagickString(msl_info->image[n]->filename,value,
cristy151b66d2015-04-15 10:50:31 +00007294 MagickPathExtent);
cristy3ed852e2009-09-05 21:47:34 +00007295 break;
7296 }
cristy4582cbb2009-09-23 00:35:43 +00007297 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00007298 }
7299 default:
7300 {
cristy4582cbb2009-09-23 00:35:43 +00007301 (void) SetMSLAttributes(msl_info,keyword,value);
cristy3ed852e2009-09-05 21:47:34 +00007302 break;
7303 }
7304 }
7305 }
7306
7307 /* process */
7308 {
cristyb1fcb2b2015-02-12 00:17:34 +00007309 *msl_info->image_info[n]->magick='\0';
cristy6f9e0d32011-08-28 16:32:09 +00007310 (void) WriteImage(msl_info->image_info[n], msl_info->image[n],
cristyc82a27b2011-10-21 01:07:16 +00007311 msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00007312 break;
7313 }
7314 }
7315 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7316 }
7317 default:
7318 {
7319 ThrowMSLException(OptionError,"UnrecognizedElement",(const char *) tag);
7320 break;
7321 }
7322 }
7323 if ( value != NULL )
7324 value=DestroyString(value);
dirke31feb82014-06-20 11:03:07 +00007325 (void) DestroyExceptionInfo(exception);
cristy3ed852e2009-09-05 21:47:34 +00007326 (void) LogMagickEvent(CoderEvent,GetMagickModule()," )");
7327}
7328
7329static void MSLEndElement(void *context,const xmlChar *tag)
7330{
cristybb503372010-05-27 20:51:26 +00007331 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00007332 n;
7333
7334 MSLInfo
7335 *msl_info;
7336
7337 /*
7338 Called when the end of an element has been detected.
7339 */
7340 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.endElement(%s)",
7341 tag);
7342 msl_info=(MSLInfo *) context;
7343 n=msl_info->n;
7344 switch (*tag)
7345 {
7346 case 'C':
7347 case 'c':
7348 {
cristyb988fe72009-09-16 01:01:10 +00007349 if (LocaleCompare((const char *) tag,"comment") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007350 {
7351 (void) DeleteImageProperty(msl_info->image[n],"comment");
7352 if (msl_info->content == (char *) NULL)
7353 break;
7354 StripString(msl_info->content);
7355 (void) SetImageProperty(msl_info->image[n],"comment",
cristyd15e6592011-10-15 00:13:06 +00007356 msl_info->content,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00007357 break;
7358 }
7359 break;
7360 }
7361 case 'G':
7362 case 'g':
7363 {
cristyb988fe72009-09-16 01:01:10 +00007364 if (LocaleCompare((const char *) tag, "group") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007365 {
7366 if (msl_info->group_info[msl_info->number_groups-1].numImages > 0 )
7367 {
cristybb503372010-05-27 20:51:26 +00007368 ssize_t i = (ssize_t)
cristy3ed852e2009-09-05 21:47:34 +00007369 (msl_info->group_info[msl_info->number_groups-1].numImages);
7370 while ( i-- )
7371 {
7372 if (msl_info->image[msl_info->n] != (Image *) NULL)
cristyd15e6592011-10-15 00:13:06 +00007373 msl_info->image[msl_info->n]=DestroyImage(
7374 msl_info->image[msl_info->n]);
7375 msl_info->attributes[msl_info->n]=DestroyImage(
7376 msl_info->attributes[msl_info->n]);
7377 msl_info->image_info[msl_info->n]=DestroyImageInfo(
7378 msl_info->image_info[msl_info->n]);
cristy3ed852e2009-09-05 21:47:34 +00007379 msl_info->n--;
7380 }
7381 }
7382 msl_info->number_groups--;
7383 }
7384 break;
7385 }
7386 case 'I':
7387 case 'i':
7388 {
cristyb988fe72009-09-16 01:01:10 +00007389 if (LocaleCompare((const char *) tag, "image") == 0)
cristy3ed852e2009-09-05 21:47:34 +00007390 MSLPopImage(msl_info);
7391 break;
7392 }
7393 case 'L':
7394 case 'l':
7395 {
cristyb988fe72009-09-16 01:01:10 +00007396 if (LocaleCompare((const char *) tag,"label") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007397 {
7398 (void) DeleteImageProperty(msl_info->image[n],"label");
7399 if (msl_info->content == (char *) NULL)
7400 break;
7401 StripString(msl_info->content);
7402 (void) SetImageProperty(msl_info->image[n],"label",
cristyd15e6592011-10-15 00:13:06 +00007403 msl_info->content,msl_info->exception);
cristy3ed852e2009-09-05 21:47:34 +00007404 break;
7405 }
7406 break;
7407 }
7408 case 'M':
7409 case 'm':
7410 {
cristyb988fe72009-09-16 01:01:10 +00007411 if (LocaleCompare((const char *) tag, "msl") == 0 )
cristy3ed852e2009-09-05 21:47:34 +00007412 {
7413 /*
7414 This our base element.
7415 at the moment we don't do anything special
7416 but someday we might!
7417 */
7418 }
7419 break;
7420 }
7421 default:
7422 break;
7423 }
7424 if (msl_info->content != (char *) NULL)
7425 msl_info->content=DestroyString(msl_info->content);
7426}
7427
7428static void MSLCharacters(void *context,const xmlChar *c,int length)
7429{
7430 MSLInfo
7431 *msl_info;
7432
7433 register char
7434 *p;
7435
cristybb503372010-05-27 20:51:26 +00007436 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00007437 i;
7438
7439 /*
7440 Receiving some characters from the parser.
7441 */
7442 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7443 " SAX.characters(%s,%d)",c,length);
7444 msl_info=(MSLInfo *) context;
7445 if (msl_info->content != (char *) NULL)
7446 msl_info->content=(char *) ResizeQuantumMemory(msl_info->content,
cristy151b66d2015-04-15 10:50:31 +00007447 strlen(msl_info->content)+length+MagickPathExtent,
cristy3ed852e2009-09-05 21:47:34 +00007448 sizeof(*msl_info->content));
7449 else
7450 {
7451 msl_info->content=(char *) NULL;
cristy151b66d2015-04-15 10:50:31 +00007452 if (~length >= (MagickPathExtent-1))
7453 msl_info->content=(char *) AcquireQuantumMemory(length+MagickPathExtent,
cristy3ed852e2009-09-05 21:47:34 +00007454 sizeof(*msl_info->content));
7455 if (msl_info->content != (char *) NULL)
7456 *msl_info->content='\0';
7457 }
7458 if (msl_info->content == (char *) NULL)
7459 return;
7460 p=msl_info->content+strlen(msl_info->content);
7461 for (i=0; i < length; i++)
7462 *p++=c[i];
7463 *p='\0';
7464}
7465
7466static void MSLReference(void *context,const xmlChar *name)
7467{
7468 MSLInfo
7469 *msl_info;
7470
7471 xmlParserCtxtPtr
7472 parser;
7473
7474 /*
7475 Called when an entity reference is detected.
7476 */
7477 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7478 " SAX.reference(%s)",name);
7479 msl_info=(MSLInfo *) context;
7480 parser=msl_info->parser;
7481 if (*name == '#')
7482 (void) xmlAddChild(parser->node,xmlNewCharRef(msl_info->document,name));
7483 else
7484 (void) xmlAddChild(parser->node,xmlNewReference(msl_info->document,name));
7485}
7486
7487static void MSLIgnorableWhitespace(void *context,const xmlChar *c,int length)
7488{
7489 MSLInfo
7490 *msl_info;
7491
7492 /*
7493 Receiving some ignorable whitespaces from the parser.
7494 */
7495 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7496 " SAX.ignorableWhitespace(%.30s, %d)",c,length);
7497 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007498 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007499}
7500
7501static void MSLProcessingInstructions(void *context,const xmlChar *target,
7502 const xmlChar *data)
7503{
7504 MSLInfo
7505 *msl_info;
7506
7507 /*
7508 A processing instruction has been parsed.
7509 */
7510 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7511 " SAX.processingInstruction(%s, %s)",
7512 target,data);
7513 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007514 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007515}
7516
7517static void MSLComment(void *context,const xmlChar *value)
7518{
7519 MSLInfo
7520 *msl_info;
7521
7522 /*
7523 A comment has been parsed.
7524 */
7525 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7526 " SAX.comment(%s)",value);
7527 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007528 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007529}
7530
7531static void MSLWarning(void *context,const char *format,...)
7532{
7533 char
7534 *message,
cristy151b66d2015-04-15 10:50:31 +00007535 reason[MagickPathExtent];
cristy3ed852e2009-09-05 21:47:34 +00007536
7537 MSLInfo
7538 *msl_info;
7539
7540 va_list
7541 operands;
7542
7543 /**
7544 Display and format a warning messages, gives file, line, position and
7545 extra parameters.
7546 */
7547 va_start(operands,format);
7548 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.warning: ");
7549 (void) LogMagickEvent(CoderEvent,GetMagickModule(),format,operands);
7550 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007551 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007552#if !defined(MAGICKCORE_HAVE_VSNPRINTF)
7553 (void) vsprintf(reason,format,operands);
7554#else
cristy151b66d2015-04-15 10:50:31 +00007555 (void) vsnprintf(reason,MagickPathExtent,format,operands);
cristy3ed852e2009-09-05 21:47:34 +00007556#endif
7557 message=GetExceptionMessage(errno);
7558 ThrowMSLException(CoderError,reason,message);
7559 message=DestroyString(message);
7560 va_end(operands);
7561}
7562
7563static void MSLError(void *context,const char *format,...)
7564{
7565 char
cristy151b66d2015-04-15 10:50:31 +00007566 reason[MagickPathExtent];
cristy3ed852e2009-09-05 21:47:34 +00007567
7568 MSLInfo
7569 *msl_info;
7570
7571 va_list
7572 operands;
7573
7574 /*
7575 Display and format a error formats, gives file, line, position and
7576 extra parameters.
7577 */
7578 va_start(operands,format);
7579 (void) LogMagickEvent(CoderEvent,GetMagickModule()," SAX.error: ");
7580 (void) LogMagickEvent(CoderEvent,GetMagickModule(),format,operands);
7581 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007582 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007583#if !defined(MAGICKCORE_HAVE_VSNPRINTF)
7584 (void) vsprintf(reason,format,operands);
7585#else
cristy151b66d2015-04-15 10:50:31 +00007586 (void) vsnprintf(reason,MagickPathExtent,format,operands);
cristy3ed852e2009-09-05 21:47:34 +00007587#endif
7588 ThrowMSLException(DelegateFatalError,reason,"SAX error");
7589 va_end(operands);
7590}
7591
7592static void MSLCDataBlock(void *context,const xmlChar *value,int length)
7593{
7594 MSLInfo
7595 *msl_info;
7596
7597 xmlNodePtr
7598 child;
7599
7600 xmlParserCtxtPtr
7601 parser;
7602
7603 /*
7604 Called when a pcdata block has been parsed.
7605 */
7606 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7607 " SAX.pcdata(%s, %d)",value,length);
7608 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007609 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007610 parser=msl_info->parser;
7611 child=xmlGetLastChild(parser->node);
7612 if ((child != (xmlNodePtr) NULL) && (child->type == XML_CDATA_SECTION_NODE))
7613 {
7614 xmlTextConcat(child,value,length);
7615 return;
7616 }
7617 (void) xmlAddChild(parser->node,xmlNewCDataBlock(parser->myDoc,value,length));
7618}
7619
7620static void MSLExternalSubset(void *context,const xmlChar *name,
7621 const xmlChar *external_id,const xmlChar *system_id)
7622{
7623 MSLInfo
7624 *msl_info;
7625
7626 xmlParserCtxt
7627 parser_context;
7628
7629 xmlParserCtxtPtr
7630 parser;
7631
7632 xmlParserInputPtr
7633 input;
7634
7635 /*
7636 Does this document has an external subset?
7637 */
7638 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
7639 " SAX.externalSubset(%s %s %s)",name,
cristyb988fe72009-09-16 01:01:10 +00007640 (external_id != (const xmlChar *) NULL ? (const char *) external_id : " "),
7641 (system_id != (const xmlChar *) NULL ? (const char *) system_id : " "));
cristy3ed852e2009-09-05 21:47:34 +00007642 msl_info=(MSLInfo *) context;
cristyda16f162011-02-19 23:52:17 +00007643 (void) msl_info;
cristy3ed852e2009-09-05 21:47:34 +00007644 parser=msl_info->parser;
7645 if (((external_id == NULL) && (system_id == NULL)) ||
7646 ((parser->validate == 0) || (parser->wellFormed == 0) ||
7647 (msl_info->document == 0)))
7648 return;
7649 input=MSLResolveEntity(context,external_id,system_id);
7650 if (input == NULL)
7651 return;
7652 (void) xmlNewDtd(msl_info->document,name,external_id,system_id);
7653 parser_context=(*parser);
7654 parser->inputTab=(xmlParserInputPtr *) xmlMalloc(5*sizeof(*parser->inputTab));
7655 if (parser->inputTab == (xmlParserInputPtr *) NULL)
7656 {
7657 parser->errNo=XML_ERR_NO_MEMORY;
7658 parser->input=parser_context.input;
7659 parser->inputNr=parser_context.inputNr;
7660 parser->inputMax=parser_context.inputMax;
7661 parser->inputTab=parser_context.inputTab;
7662 return;
7663 }
7664 parser->inputNr=0;
7665 parser->inputMax=5;
7666 parser->input=NULL;
7667 xmlPushInput(parser,input);
7668 (void) xmlSwitchEncoding(parser,xmlDetectCharEncoding(parser->input->cur,4));
7669 if (input->filename == (char *) NULL)
7670 input->filename=(char *) xmlStrdup(system_id);
7671 input->line=1;
7672 input->col=1;
7673 input->base=parser->input->cur;
7674 input->cur=parser->input->cur;
7675 input->free=NULL;
7676 xmlParseExternalSubset(parser,external_id,system_id);
7677 while (parser->inputNr > 1)
7678 (void) xmlPopInput(parser);
7679 xmlFreeInputStream(parser->input);
7680 xmlFree(parser->inputTab);
7681 parser->input=parser_context.input;
7682 parser->inputNr=parser_context.inputNr;
7683 parser->inputMax=parser_context.inputMax;
7684 parser->inputTab=parser_context.inputTab;
7685}
7686
7687#if defined(__cplusplus) || defined(c_plusplus)
7688}
7689#endif
7690
cristy8b2b4e52012-06-27 01:01:10 +00007691static MagickBooleanType ProcessMSLScript(const ImageInfo *image_info,
7692 Image **image,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00007693{
cristy3ed852e2009-09-05 21:47:34 +00007694 char
cristy151b66d2015-04-15 10:50:31 +00007695 message[MagickPathExtent];
cristy3ed852e2009-09-05 21:47:34 +00007696
7697 Image
7698 *msl_image;
7699
7700 int
7701 status;
7702
cristybb503372010-05-27 20:51:26 +00007703 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00007704 n;
7705
7706 MSLInfo
7707 msl_info;
7708
cristy5f6f01c2009-11-19 19:36:42 +00007709 xmlSAXHandler
7710 sax_modules;
7711
cristy3ed852e2009-09-05 21:47:34 +00007712 xmlSAXHandlerPtr
cristy5f6f01c2009-11-19 19:36:42 +00007713 sax_handler;
cristy3ed852e2009-09-05 21:47:34 +00007714
7715 /*
7716 Open image file.
7717 */
7718 assert(image_info != (const ImageInfo *) NULL);
7719 assert(image_info->signature == MagickSignature);
7720 if (image_info->debug != MagickFalse)
cristy5f6f01c2009-11-19 19:36:42 +00007721 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
7722 image_info->filename);
cristy3ed852e2009-09-05 21:47:34 +00007723 assert(image != (Image **) NULL);
cristy9950d572011-10-01 18:22:35 +00007724 msl_image=AcquireImage(image_info,exception);
cristy3ed852e2009-09-05 21:47:34 +00007725 status=OpenBlob(image_info,msl_image,ReadBinaryBlobMode,exception);
7726 if (status == MagickFalse)
7727 {
7728 ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
7729 msl_image->filename);
7730 msl_image=DestroyImageList(msl_image);
7731 return(MagickFalse);
7732 }
7733 msl_image->columns=1;
7734 msl_image->rows=1;
7735 /*
7736 Parse MSL file.
7737 */
7738 (void) ResetMagickMemory(&msl_info,0,sizeof(msl_info));
7739 msl_info.exception=exception;
7740 msl_info.image_info=(ImageInfo **) AcquireMagickMemory(
7741 sizeof(*msl_info.image_info));
7742 msl_info.draw_info=(DrawInfo **) AcquireMagickMemory(
7743 sizeof(*msl_info.draw_info));
7744 /* top of the stack is the MSL file itself */
cristy73bd4a52010-10-05 11:24:23 +00007745 msl_info.image=(Image **) AcquireMagickMemory(sizeof(*msl_info.image));
cristy3ed852e2009-09-05 21:47:34 +00007746 msl_info.attributes=(Image **) AcquireMagickMemory(
7747 sizeof(*msl_info.attributes));
7748 msl_info.group_info=(MSLGroupInfo *) AcquireMagickMemory(
7749 sizeof(*msl_info.group_info));
7750 if ((msl_info.image_info == (ImageInfo **) NULL) ||
7751 (msl_info.image == (Image **) NULL) ||
7752 (msl_info.attributes == (Image **) NULL) ||
7753 (msl_info.group_info == (MSLGroupInfo *) NULL))
7754 ThrowFatalException(ResourceLimitFatalError,
7755 "UnableToInterpretMSLImage");
7756 *msl_info.image_info=CloneImageInfo(image_info);
7757 *msl_info.draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL);
cristy9950d572011-10-01 18:22:35 +00007758 *msl_info.attributes=AcquireImage(image_info,exception);
cristy3ed852e2009-09-05 21:47:34 +00007759 msl_info.group_info[0].numImages=0;
7760 /* the first slot is used to point to the MSL file image */
7761 *msl_info.image=msl_image;
7762 if (*image != (Image *) NULL)
7763 MSLPushImage(&msl_info,*image);
7764 (void) xmlSubstituteEntitiesDefault(1);
cristy5f6f01c2009-11-19 19:36:42 +00007765 (void) ResetMagickMemory(&sax_modules,0,sizeof(sax_modules));
7766 sax_modules.internalSubset=MSLInternalSubset;
7767 sax_modules.isStandalone=MSLIsStandalone;
7768 sax_modules.hasInternalSubset=MSLHasInternalSubset;
7769 sax_modules.hasExternalSubset=MSLHasExternalSubset;
7770 sax_modules.resolveEntity=MSLResolveEntity;
7771 sax_modules.getEntity=MSLGetEntity;
7772 sax_modules.entityDecl=MSLEntityDeclaration;
7773 sax_modules.notationDecl=MSLNotationDeclaration;
7774 sax_modules.attributeDecl=MSLAttributeDeclaration;
7775 sax_modules.elementDecl=MSLElementDeclaration;
7776 sax_modules.unparsedEntityDecl=MSLUnparsedEntityDeclaration;
7777 sax_modules.setDocumentLocator=MSLSetDocumentLocator;
7778 sax_modules.startDocument=MSLStartDocument;
7779 sax_modules.endDocument=MSLEndDocument;
7780 sax_modules.startElement=MSLStartElement;
7781 sax_modules.endElement=MSLEndElement;
7782 sax_modules.reference=MSLReference;
7783 sax_modules.characters=MSLCharacters;
7784 sax_modules.ignorableWhitespace=MSLIgnorableWhitespace;
7785 sax_modules.processingInstruction=MSLProcessingInstructions;
7786 sax_modules.comment=MSLComment;
7787 sax_modules.warning=MSLWarning;
7788 sax_modules.error=MSLError;
7789 sax_modules.fatalError=MSLError;
7790 sax_modules.getParameterEntity=MSLGetParameterEntity;
7791 sax_modules.cdataBlock=MSLCDataBlock;
7792 sax_modules.externalSubset=MSLExternalSubset;
7793 sax_handler=(&sax_modules);
7794 msl_info.parser=xmlCreatePushParserCtxt(sax_handler,&msl_info,(char *) NULL,0,
cristy3ed852e2009-09-05 21:47:34 +00007795 msl_image->filename);
7796 while (ReadBlobString(msl_image,message) != (char *) NULL)
7797 {
cristybb503372010-05-27 20:51:26 +00007798 n=(ssize_t) strlen(message);
cristy3ed852e2009-09-05 21:47:34 +00007799 if (n == 0)
7800 continue;
7801 status=xmlParseChunk(msl_info.parser,message,(int) n,MagickFalse);
7802 if (status != 0)
7803 break;
7804 (void) xmlParseChunk(msl_info.parser," ",1,MagickFalse);
7805 if (msl_info.exception->severity >= ErrorException)
7806 break;
7807 }
7808 if (msl_info.exception->severity == UndefinedException)
7809 (void) xmlParseChunk(msl_info.parser," ",1,MagickTrue);
7810 xmlFreeParserCtxt(msl_info.parser);
7811 (void) LogMagickEvent(CoderEvent,GetMagickModule(),"end SAX");
cristy3ed852e2009-09-05 21:47:34 +00007812 msl_info.group_info=(MSLGroupInfo *) RelinquishMagickMemory(
7813 msl_info.group_info);
7814 if (*image == (Image *) NULL)
7815 *image=(*msl_info.image);
cristyc82a27b2011-10-21 01:07:16 +00007816 if (msl_info.exception->severity != UndefinedException)
cristy5f6f01c2009-11-19 19:36:42 +00007817 return(MagickFalse);
7818 return(MagickTrue);
cristy3ed852e2009-09-05 21:47:34 +00007819}
7820
7821static Image *ReadMSLImage(const ImageInfo *image_info,ExceptionInfo *exception)
7822{
7823 Image
7824 *image;
7825
7826 /*
7827 Open image file.
7828 */
7829 assert(image_info != (const ImageInfo *) NULL);
7830 assert(image_info->signature == MagickSignature);
7831 if (image_info->debug != MagickFalse)
7832 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
7833 image_info->filename);
7834 assert(exception != (ExceptionInfo *) NULL);
7835 assert(exception->signature == MagickSignature);
7836 image=(Image *) NULL;
7837 (void) ProcessMSLScript(image_info,&image,exception);
7838 return(GetFirstImageInList(image));
7839}
7840#endif
7841
7842/*
7843%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7844% %
7845% %
7846% %
7847% R e g i s t e r M S L I m a g e %
7848% %
7849% %
7850% %
7851%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7852%
7853% RegisterMSLImage() adds attributes for the MSL image format to
7854% the list of supported formats. The attributes include the image format
7855% tag, a method to read and/or write the format, whether the format
7856% supports the saving of more than one frame to the same file or blob,
7857% whether the format supports native in-memory I/O, and a brief
7858% description of the format.
7859%
7860% The format of the RegisterMSLImage method is:
7861%
cristybb503372010-05-27 20:51:26 +00007862% size_t RegisterMSLImage(void)
cristy3ed852e2009-09-05 21:47:34 +00007863%
7864*/
cristybb503372010-05-27 20:51:26 +00007865ModuleExport size_t RegisterMSLImage(void)
cristy3ed852e2009-09-05 21:47:34 +00007866{
7867 MagickInfo
7868 *entry;
7869
cristyfbd03fe2013-08-29 13:47:42 +00007870#if defined(MAGICKCORE_XML_DELEGATE)
7871 xmlInitParser();
7872#endif
dirk06b627a2015-04-06 18:59:17 +00007873 entry=AcquireMagickInfo("MSL","MSL","Magick Scripting Language");
cristy3ed852e2009-09-05 21:47:34 +00007874#if defined(MAGICKCORE_XML_DELEGATE)
7875 entry->decoder=(DecodeImageHandler *) ReadMSLImage;
7876 entry->encoder=(EncodeImageHandler *) WriteMSLImage;
7877#endif
cristy3ed852e2009-09-05 21:47:34 +00007878 (void) RegisterMagickInfo(entry);
7879 return(MagickImageCoderSignature);
7880}
7881
cristy6b9f7ed2010-04-24 01:08:02 +00007882#if defined(MAGICKCORE_XML_DELEGATE)
cristy3ed852e2009-09-05 21:47:34 +00007883/*
7884%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7885% %
7886% %
7887% %
cristyb988fe72009-09-16 01:01:10 +00007888% S e t M S L A t t r i b u t e s %
7889% %
7890% %
7891% %
7892%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7893%
7894% SetMSLAttributes() ...
7895%
7896% The format of the SetMSLAttributes method is:
7897%
7898% MagickBooleanType SetMSLAttributes(MSLInfo *msl_info,
cristyb20775d2009-09-16 01:51:41 +00007899% const char *keyword,const char *value)
cristyb988fe72009-09-16 01:01:10 +00007900%
7901% A description of each parameter follows:
7902%
7903% o msl_info: the MSL info.
7904%
cristyb20775d2009-09-16 01:51:41 +00007905% o keyword: the keyword.
7906%
7907% o value: the value.
cristyb988fe72009-09-16 01:01:10 +00007908%
7909*/
cristyb20775d2009-09-16 01:51:41 +00007910static MagickBooleanType SetMSLAttributes(MSLInfo *msl_info,const char *keyword,
7911 const char *value)
cristyb988fe72009-09-16 01:01:10 +00007912{
cristy4582cbb2009-09-23 00:35:43 +00007913 Image
7914 *attributes;
7915
cristyb20775d2009-09-16 01:51:41 +00007916 DrawInfo
7917 *draw_info;
cristyb988fe72009-09-16 01:01:10 +00007918
7919 ExceptionInfo
7920 *exception;
7921
cristy4582cbb2009-09-23 00:35:43 +00007922 GeometryInfo
7923 geometry_info;
7924
cristy4fa36e42009-09-18 14:24:06 +00007925 Image
7926 *image;
7927
cristyb20775d2009-09-16 01:51:41 +00007928 ImageInfo
7929 *image_info;
7930
cristy4582cbb2009-09-23 00:35:43 +00007931 int
7932 flags;
7933
cristybb503372010-05-27 20:51:26 +00007934 ssize_t
cristyb988fe72009-09-16 01:01:10 +00007935 n;
7936
cristyb988fe72009-09-16 01:01:10 +00007937 assert(msl_info != (MSLInfo *) NULL);
cristyb20775d2009-09-16 01:51:41 +00007938 if (keyword == (const char *) NULL)
7939 return(MagickTrue);
7940 if (value == (const char *) NULL)
cristyb988fe72009-09-16 01:01:10 +00007941 return(MagickTrue);
7942 exception=msl_info->exception;
7943 n=msl_info->n;
cristy4582cbb2009-09-23 00:35:43 +00007944 attributes=msl_info->attributes[n];
cristyb20775d2009-09-16 01:51:41 +00007945 image_info=msl_info->image_info[n];
7946 draw_info=msl_info->draw_info[n];
cristy4fa36e42009-09-18 14:24:06 +00007947 image=msl_info->image[n];
cristyb20775d2009-09-16 01:51:41 +00007948 switch (*keyword)
cristyb988fe72009-09-16 01:01:10 +00007949 {
cristyfb758a52009-09-16 14:36:08 +00007950 case 'A':
7951 case 'a':
7952 {
7953 if (LocaleCompare(keyword,"adjoin") == 0)
7954 {
cristybb503372010-05-27 20:51:26 +00007955 ssize_t
cristyfb758a52009-09-16 14:36:08 +00007956 adjoin;
7957
cristy042ee782011-04-22 18:48:30 +00007958 adjoin=ParseCommandOption(MagickBooleanOptions,MagickFalse,value);
cristyfb758a52009-09-16 14:36:08 +00007959 if (adjoin < 0)
7960 ThrowMSLException(OptionError,"UnrecognizedType",value);
7961 image_info->adjoin=(MagickBooleanType) adjoin;
7962 break;
7963 }
cristy4fa36e42009-09-18 14:24:06 +00007964 if (LocaleCompare(keyword,"alpha") == 0)
7965 {
cristybb503372010-05-27 20:51:26 +00007966 ssize_t
cristy4fa36e42009-09-18 14:24:06 +00007967 alpha;
7968
cristy288a3532012-08-28 00:19:44 +00007969 alpha=ParseCommandOption(MagickAlphaChannelOptions,MagickFalse,value);
cristy4fa36e42009-09-18 14:24:06 +00007970 if (alpha < 0)
7971 ThrowMSLException(OptionError,"UnrecognizedType",value);
cristy4582cbb2009-09-23 00:35:43 +00007972 if (image != (Image *) NULL)
cristyb15b06c2012-08-28 11:36:48 +00007973 (void) SetImageAlphaChannel(image,(AlphaChannelOption) alpha,
cristy63240882011-08-05 19:05:27 +00007974 exception);
cristy4582cbb2009-09-23 00:35:43 +00007975 break;
7976 }
7977 if (LocaleCompare(keyword,"antialias") == 0)
7978 {
cristybb503372010-05-27 20:51:26 +00007979 ssize_t
cristy4582cbb2009-09-23 00:35:43 +00007980 antialias;
7981
cristy042ee782011-04-22 18:48:30 +00007982 antialias=ParseCommandOption(MagickBooleanOptions,MagickFalse,value);
cristy4582cbb2009-09-23 00:35:43 +00007983 if (antialias < 0)
7984 ThrowMSLException(OptionError,"UnrecognizedGravityType",value);
7985 image_info->antialias=(MagickBooleanType) antialias;
7986 break;
7987 }
7988 if (LocaleCompare(keyword,"area-limit") == 0)
7989 {
7990 MagickSizeType
7991 limit;
7992
7993 limit=MagickResourceInfinity;
7994 if (LocaleCompare(value,"unlimited") != 0)
cristydbdd0e32011-11-04 23:29:40 +00007995 limit=(MagickSizeType) StringToDoubleInterval(value,100.0);
cristy4582cbb2009-09-23 00:35:43 +00007996 (void) SetMagickResourceLimit(AreaResource,limit);
7997 break;
7998 }
7999 if (LocaleCompare(keyword,"attenuate") == 0)
8000 {
8001 (void) SetImageOption(image_info,keyword,value);
8002 break;
8003 }
8004 if (LocaleCompare(keyword,"authenticate") == 0)
8005 {
8006 (void) CloneString(&image_info->density,value);
cristy4fa36e42009-09-18 14:24:06 +00008007 break;
8008 }
cristyfb758a52009-09-16 14:36:08 +00008009 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8010 break;
8011 }
cristyb20775d2009-09-16 01:51:41 +00008012 case 'B':
8013 case 'b':
cristyb988fe72009-09-16 01:01:10 +00008014 {
cristyb20775d2009-09-16 01:51:41 +00008015 if (LocaleCompare(keyword,"background") == 0)
8016 {
cristy9950d572011-10-01 18:22:35 +00008017 (void) QueryColorCompliance(value,AllCompliance,
8018 &image_info->background_color,exception);
cristyb20775d2009-09-16 01:51:41 +00008019 break;
8020 }
cristy4582cbb2009-09-23 00:35:43 +00008021 if (LocaleCompare(keyword,"blue-primary") == 0)
8022 {
8023 if (image == (Image *) NULL)
8024 break;
8025 flags=ParseGeometry(value,&geometry_info);
8026 image->chromaticity.blue_primary.x=geometry_info.rho;
8027 image->chromaticity.blue_primary.y=geometry_info.sigma;
8028 if ((flags & SigmaValue) == 0)
8029 image->chromaticity.blue_primary.y=
8030 image->chromaticity.blue_primary.x;
8031 break;
8032 }
cristy2c8b6312009-09-16 02:37:23 +00008033 if (LocaleCompare(keyword,"bordercolor") == 0)
8034 {
cristy9950d572011-10-01 18:22:35 +00008035 (void) QueryColorCompliance(value,AllCompliance,
8036 &image_info->border_color,exception);
cristy2c8b6312009-09-16 02:37:23 +00008037 break;
8038 }
8039 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8040 break;
8041 }
8042 case 'D':
8043 case 'd':
8044 {
8045 if (LocaleCompare(keyword,"density") == 0)
8046 {
8047 (void) CloneString(&image_info->density,value);
8048 (void) CloneString(&draw_info->density,value);
8049 break;
8050 }
cristyb20775d2009-09-16 01:51:41 +00008051 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8052 break;
8053 }
8054 case 'F':
8055 case 'f':
8056 {
8057 if (LocaleCompare(keyword,"fill") == 0)
8058 {
cristy9950d572011-10-01 18:22:35 +00008059 (void) QueryColorCompliance(value,AllCompliance,&draw_info->fill,
8060 exception);
cristya30afaf2009-09-22 13:42:12 +00008061 (void) SetImageOption(image_info,keyword,value);
cristyb20775d2009-09-16 01:51:41 +00008062 break;
8063 }
cristy4582cbb2009-09-23 00:35:43 +00008064 if (LocaleCompare(keyword,"filename") == 0)
8065 {
cristy151b66d2015-04-15 10:50:31 +00008066 (void) CopyMagickString(image_info->filename,value,MagickPathExtent);
cristy4582cbb2009-09-23 00:35:43 +00008067 break;
8068 }
8069 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8070 break;
8071 }
8072 case 'G':
8073 case 'g':
8074 {
8075 if (LocaleCompare(keyword,"gravity") == 0)
8076 {
cristybb503372010-05-27 20:51:26 +00008077 ssize_t
cristy4582cbb2009-09-23 00:35:43 +00008078 gravity;
8079
cristy042ee782011-04-22 18:48:30 +00008080 gravity=ParseCommandOption(MagickGravityOptions,MagickFalse,value);
cristy4582cbb2009-09-23 00:35:43 +00008081 if (gravity < 0)
8082 ThrowMSLException(OptionError,"UnrecognizedGravityType",value);
8083 (void) SetImageOption(image_info,keyword,value);
8084 break;
8085 }
cristyb20775d2009-09-16 01:51:41 +00008086 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8087 break;
8088 }
8089 case 'I':
8090 case 'i':
8091 {
8092 if (LocaleCompare(keyword,"id") == 0)
8093 {
cristyd15e6592011-10-15 00:13:06 +00008094 (void) SetImageProperty(attributes,keyword,value,exception);
cristy2c8b6312009-09-16 02:37:23 +00008095 break;
8096 }
8097 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8098 break;
8099 }
8100 case 'M':
8101 case 'm':
8102 {
8103 if (LocaleCompare(keyword,"magick") == 0)
8104 {
cristy151b66d2015-04-15 10:50:31 +00008105 (void) CopyMagickString(image_info->magick,value,MagickPathExtent);
cristy2c8b6312009-09-16 02:37:23 +00008106 break;
8107 }
cristy2c8b6312009-09-16 02:37:23 +00008108 if (LocaleCompare(keyword,"mattecolor") == 0)
8109 {
cristy9950d572011-10-01 18:22:35 +00008110 (void) QueryColorCompliance(value,AllCompliance,
8111 &image_info->matte_color,exception);
cristyb20775d2009-09-16 01:51:41 +00008112 break;
8113 }
8114 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8115 break;
8116 }
8117 case 'P':
8118 case 'p':
8119 {
8120 if (LocaleCompare(keyword,"pointsize") == 0)
8121 {
cristydbdd0e32011-11-04 23:29:40 +00008122 image_info->pointsize=StringToDouble(value,(char **) NULL);
8123 draw_info->pointsize=StringToDouble(value,(char **) NULL);
cristyb20775d2009-09-16 01:51:41 +00008124 break;
8125 }
8126 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8127 break;
8128 }
cristy4582cbb2009-09-23 00:35:43 +00008129 case 'Q':
8130 case 'q':
8131 {
8132 if (LocaleCompare(keyword,"quality") == 0)
8133 {
cristyf2f27272009-12-17 14:48:46 +00008134 image_info->quality=StringToLong(value);
cristy4582cbb2009-09-23 00:35:43 +00008135 if (image == (Image *) NULL)
8136 break;
cristyf2f27272009-12-17 14:48:46 +00008137 image->quality=StringToLong(value);
cristy4582cbb2009-09-23 00:35:43 +00008138 break;
8139 }
8140 break;
8141 }
cristyb20775d2009-09-16 01:51:41 +00008142 case 'S':
8143 case 's':
8144 {
8145 if (LocaleCompare(keyword,"size") == 0)
8146 {
cristy2c8b6312009-09-16 02:37:23 +00008147 (void) CloneString(&image_info->size,value);
cristyb20775d2009-09-16 01:51:41 +00008148 break;
8149 }
8150 if (LocaleCompare(keyword,"stroke") == 0)
8151 {
cristy9950d572011-10-01 18:22:35 +00008152 (void) QueryColorCompliance(value,AllCompliance,&draw_info->stroke,
8153 exception);
cristya30afaf2009-09-22 13:42:12 +00008154 (void) SetImageOption(image_info,keyword,value);
cristyb20775d2009-09-16 01:51:41 +00008155 break;
8156 }
8157 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8158 break;
8159 }
8160 default:
8161 {
8162 ThrowMSLException(OptionError,"UnrecognizedAttribute",keyword);
8163 break;
cristyb988fe72009-09-16 01:01:10 +00008164 }
8165 }
8166 return(MagickTrue);
8167}
cristy6b9f7ed2010-04-24 01:08:02 +00008168#endif
cristyb988fe72009-09-16 01:01:10 +00008169
8170/*
8171%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8172% %
8173% %
8174% %
cristy3ed852e2009-09-05 21:47:34 +00008175% U n r e g i s t e r M S L I m a g e %
8176% %
8177% %
8178% %
8179%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8180%
8181% UnregisterMSLImage() removes format registrations made by the
8182% MSL module from the list of supported formats.
8183%
8184% The format of the UnregisterMSLImage method is:
8185%
8186% UnregisterMSLImage(void)
8187%
8188*/
8189ModuleExport void UnregisterMSLImage(void)
8190{
8191 (void) UnregisterMagickInfo("MSL");
cristyfbd03fe2013-08-29 13:47:42 +00008192#if defined(MAGICKCORE_XML_DELEGATE)
8193 xmlCleanupParser();
8194#endif
cristy3ed852e2009-09-05 21:47:34 +00008195}
8196
8197#if defined(MAGICKCORE_XML_DELEGATE)
8198/*
8199%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8200% %
8201% %
8202% %
8203% W r i t e M S L I m a g e %
8204% %
8205% %
8206% %
8207%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8208%
8209% WriteMSLImage() writes an image to a file in MVG image format.
8210%
8211% The format of the WriteMSLImage method is:
8212%
cristy1e178e72011-08-28 19:44:34 +00008213% MagickBooleanType WriteMSLImage(const ImageInfo *image_info,
8214% Image *image,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00008215%
8216% A description of each parameter follows.
8217%
8218% o image_info: the image info.
8219%
8220% o image: The image.
8221%
cristy1e178e72011-08-28 19:44:34 +00008222% o exception: return any errors or warnings in this structure.
8223%
cristy3ed852e2009-09-05 21:47:34 +00008224*/
cristy1e178e72011-08-28 19:44:34 +00008225static MagickBooleanType WriteMSLImage(const ImageInfo *image_info,Image *image,
8226 ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00008227{
8228 assert(image_info != (const ImageInfo *) NULL);
8229 assert(image_info->signature == MagickSignature);
8230 assert(image != (Image *) NULL);
8231 assert(image->signature == MagickSignature);
8232 if (image->debug != MagickFalse)
8233 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
8234 (void) ReferenceImage(image);
cristy1e178e72011-08-28 19:44:34 +00008235 (void) ProcessMSLScript(image_info,&image,exception);
cristy3ed852e2009-09-05 21:47:34 +00008236 return(MagickTrue);
8237}
8238#endif