2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6 % OOO PPPP EEEE RRRR AA TTTTT III OOO N N %
7 % O O P P E R R A A T I O O NN N %
8 % O O PPPP EEE RRRR AAAA T I O O N N N %
9 % O O P E R R A A T I O O N NN %
10 % OOO P EEEE R RR A A T III OOO N N %
13 % CLI Magick Option Methods %
20 % Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization %
21 % dedicated to making software imaging solutions freely available. %
23 % You may not use this file except in compliance with the License. You may %
24 % obtain a copy of the License at %
26 % http://www.imagemagick.org/script/license.php %
28 % Unless required by applicable law or agreed to in writing, software %
29 % distributed under the License is distributed on an "AS IS" BASIS, %
30 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31 % See the License for the specific language governing permissions and %
32 % limitations under the License. %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
36 % Apply the given options (settings, and simple, or sequence operations) to
37 % the given image(s) according to the current "image_info", "draw_info", and
38 % "quantize_info" settings, stored in a special CLI Image Wand.
40 % The final goal is to allow the execution in a strict one option at a time
41 % manner that is needed for 'pipelining and file scripting' of options in
44 % Anthony Thyssen, September 2011
50 #include "MagickWand/studio.h"
51 #include "MagickWand/MagickWand.h"
52 #include "MagickWand/magick-wand-private.h"
53 #include "MagickWand/mogrify.h"
54 #include "MagickWand/wand.h"
55 #include "MagickWand/wandcli.h"
56 #include "MagickWand/wandcli-private.h"
57 #include "MagickCore/image-private.h"
58 #include "MagickCore/monitor-private.h"
59 #include "MagickWand/operation.h"
60 #include "MagickCore/thread-private.h"
61 #include "MagickCore/string-private.h"
62 #include "MagickCore/pixel-private.h"
68 MogrifyBackgroundColor[] = "#fff", /* white */
69 MogrifyBorderColor[] = "#dfdfdf", /* sRGB gray */
70 MogrifyMatteColor[] = "#bdbdbd"; /* slightly darker gray */
75 #define USE_WAND_METHODS 1
76 #define MAX_STACK_DEPTH 32
77 #define UNDEFINED_COMPRESSION_QUALITY 0UL
79 /* FUTURE: why is this default so specific? */
80 #define DEFAULT_DISSIMILARITY_THRESHOLD "0.31830988618379067154"
82 /* For Debugging Geometry Input */
83 #define ReportGeometry(flags,info) \
84 (void) FormatLocaleFile(stderr, "Geometry = 0x%04X : %lg x %lg %+lg %+lg\n", \
85 flags, info.rho, info.sigma, info.xi, info.psi )
88 ** Function to report on the progress of image operations
90 static MagickBooleanType MonitorProgress(const char *text,
91 const MagickOffsetType offset,const MagickSizeType extent,
92 void *wand_unused(cli_wandent_data))
95 message[MagickPathExtent],
96 tag[MagickPathExtent];
104 if ((extent <= 1) || (offset < 0) || (offset >= (MagickOffsetType) extent))
106 if ((offset != (MagickOffsetType) (extent-1)) && ((offset % 50) != 0))
108 (void) CopyMagickMemory(tag,text,MagickPathExtent);
110 if (p != (char *) NULL)
112 (void) FormatLocaleString(message,MagickPathExtent,"Monitor/%s",tag);
113 locale_message=GetLocaleMessage(message);
114 if (locale_message == message)
116 if (p == (char *) NULL)
117 (void) FormatLocaleFile(stderr,"%s: %ld of %lu, %02ld%% complete\r",
118 locale_message,(long) offset,(unsigned long) extent,(long)
119 (100L*offset/(extent-1)));
121 (void) FormatLocaleFile(stderr,"%s[%s]: %ld of %lu, %02ld%% complete\r",
122 locale_message,p+1,(long) offset,(unsigned long) extent,(long)
123 (100L*offset/(extent-1)));
124 if (offset == (MagickOffsetType) (extent-1))
125 (void) FormatLocaleFile(stderr,"\n");
126 (void) fflush(stderr);
131 ** GetImageCache() will read an image into a image cache if not already
132 ** present then return the image that is in the cache under that filename.
134 static inline Image *GetImageCache(const ImageInfo *image_info,const char *path,
135 ExceptionInfo *exception)
138 key[MagickPathExtent];
149 (void) FormatLocaleString(key,MagickPathExtent,"cache:%s",path);
150 sans_exception=AcquireExceptionInfo();
151 image=(Image *) GetImageRegistry(ImageRegistryType,key,sans_exception);
152 sans_exception=DestroyExceptionInfo(sans_exception);
153 if (image != (Image *) NULL)
155 read_info=CloneImageInfo(image_info);
156 if (path != (const char *) NULL)
157 (void) CopyMagickString(read_info->filename,path,MagickPathExtent);
158 image=ReadImage(read_info,exception);
159 read_info=DestroyImageInfo(read_info);
160 if (image != (Image *) NULL)
161 (void) SetImageRegistry(ImageRegistryType,key,image,exception);
166 SparseColorOption() parse the complex -sparse-color argument into an
167 an array of floating point values than call SparseColorImage().
168 Argument is a complex mix of floating-point pixel coodinates, and color
169 specifications (or direct floating point numbers). The number of floats
170 needed to represent a color varies depending on the current channel
173 This really should be in MagickCore, so that other API's can make use of it.
175 static Image *SparseColorOption(const Image *image,
176 const SparseColorMethod method,const char *arguments,ExceptionInfo *exception)
179 token[MagickPathExtent];
203 assert(image != (Image *) NULL);
204 assert(image->signature == MagickCoreSignature);
205 if (IfMagickTrue(image->debug))
206 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
207 assert(exception != (ExceptionInfo *) NULL);
208 assert(exception->signature == MagickCoreSignature);
210 Limit channels according to image
211 add up number of values needed per color.
214 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
216 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
218 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
220 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
221 (image->colorspace == CMYKColorspace))
223 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
224 image->alpha_trait != UndefinedPixelTrait)
228 Read string, to determine number of arguments needed,
234 GetMagickToken(p,&p,token);
235 if ( token[0] == ',' ) continue;
236 if ( isalpha((int) token[0]) || token[0] == '#' )
237 x += number_colors; /* color argument found */
239 x++; /* floating point argument */
241 /* control points and color values */
242 if ((x % (2+number_colors)) != 0)
244 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
245 "InvalidArgument","'%s': %s", "sparse-color",
246 "Invalid number of Arguments");
247 return( (Image *) NULL);
252 /* Allocate and fill in the floating point arguments */
253 sparse_arguments=(double *) AcquireQuantumMemory(number_arguments,
254 sizeof(*sparse_arguments));
255 if (sparse_arguments == (double *) NULL) {
256 (void) ThrowMagickException(exception,GetMagickModule(),ResourceLimitError,
257 "MemoryAllocationFailed","%s","SparseColorOption");
258 return( (Image *) NULL);
260 (void) ResetMagickMemory(sparse_arguments,0,number_arguments*
261 sizeof(*sparse_arguments));
264 while( *p != '\0' && x < number_arguments ) {
266 token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token);
267 if ( token[0] == '\0' ) break;
268 if ( isalpha((int) token[0]) || token[0] == '#' ) {
269 (void) ThrowMagickException(exception,GetMagickModule(),
270 OptionError, "InvalidArgument", "'%s': %s", "sparse-color",
271 "Color found, instead of X-coord");
275 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
277 token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token);
278 if ( token[0] == '\0' ) break;
279 if ( isalpha((int) token[0]) || token[0] == '#' ) {
280 (void) ThrowMagickException(exception,GetMagickModule(),
281 OptionError, "InvalidArgument", "'%s': %s", "sparse-color",
282 "Color found, instead of Y-coord");
286 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
287 /* color name or function given in string argument */
288 token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token);
289 if ( token[0] == '\0' ) break;
290 if ( isalpha((int) token[0]) || token[0] == '#' ) {
291 /* Color string given */
292 (void) QueryColorCompliance(token,AllCompliance,&color,
294 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
295 sparse_arguments[x++] = QuantumScale*color.red;
296 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
297 sparse_arguments[x++] = QuantumScale*color.green;
298 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
299 sparse_arguments[x++] = QuantumScale*color.blue;
300 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
301 (image->colorspace == CMYKColorspace))
302 sparse_arguments[x++] = QuantumScale*color.black;
303 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
304 image->alpha_trait != UndefinedPixelTrait)
305 sparse_arguments[x++] = QuantumScale*color.alpha;
308 /* Colors given as a set of floating point values - experimental */
309 /* NB: token contains the first floating point value to use! */
310 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
312 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
313 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
315 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
316 token[0] = ','; /* used this token - get another */
318 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
320 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
321 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
323 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
324 token[0] = ','; /* used this token - get another */
326 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
328 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
329 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
331 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
332 token[0] = ','; /* used this token - get another */
334 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
335 (image->colorspace == CMYKColorspace))
337 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
338 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
340 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
341 token[0] = ','; /* used this token - get another */
343 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
344 image->alpha_trait != UndefinedPixelTrait)
346 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
347 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
349 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
350 token[0] = ','; /* used this token - get another */
354 if (error != MagickFalse)
356 sparse_arguments=(double *) RelinquishMagickMemory(sparse_arguments);
357 return((Image *) NULL);
359 if (number_arguments != x)
361 sparse_arguments=(double *) RelinquishMagickMemory(sparse_arguments);
362 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
363 "InvalidArgument","'%s': %s","sparse-color","Argument Parsing Error");
364 return((Image *) NULL);
366 /* Call the Sparse Color Interpolation function with the parsed arguments */
367 sparse_image=SparseColorImage(image,method,number_arguments,sparse_arguments,
369 sparse_arguments=(double *) RelinquishMagickMemory(sparse_arguments);
370 return( sparse_image );
374 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
378 % C L I S e t t i n g O p t i o n I n f o %
382 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
384 % CLISettingOptionInfo() applies a single settings option into a CLI wand
385 % holding the image_info, draw_info, quantize_info structures that will be
386 % used when processing the images.
388 % These options do no require images to be present in the CLI wand for them
389 % to be able to be set, in which case they will generally be applied to image
390 % that are read in later
392 % Options handled by this function are listed in CommandOptions[] of
393 % "option.c" that is one of "SettingOptionFlags" option flags.
395 % The format of the CLISettingOptionInfo method is:
397 % void CLISettingOptionInfo(MagickCLI *cli_wand,
398 % const char *option, const char *arg1, const char *arg2)
400 % A description of each parameter follows:
402 % o cli_wand: structure holding settings to be applied
404 % o option: The option string to be set
406 % o arg1, arg2: optional argument strings to the operation
407 % arg2 is currently only used by "-limit"
410 WandPrivate void CLISettingOptionInfo(MagickCLI *cli_wand,
411 const char *option,const char *arg1n, const char *arg2n)
414 parse; /* option argument parsing (string to value table lookup) */
416 const char /* percent escaped versions of the args */
420 #define _image_info (cli_wand->wand.image_info)
421 #define _image (cli_wand->wand.images)
422 #define _exception (cli_wand->wand.exception)
423 #define _draw_info (cli_wand->draw_info)
424 #define _quantize_info (cli_wand->quantize_info)
425 #define IfSetOption (*option=='-')
426 #define ArgBoolean IfSetOption ? MagickTrue : MagickFalse
427 #define ArgBooleanNot IfSetOption ? MagickFalse : MagickTrue
428 #define ArgBooleanString (IfSetOption?"true":"false")
429 #define ArgOption(def) (IfSetOption?arg1:(const char *)(def))
431 assert(cli_wand != (MagickCLI *) NULL);
432 assert(cli_wand->signature == MagickWandSignature);
433 assert(cli_wand->wand.signature == MagickWandSignature);
435 if (IfMagickTrue(cli_wand->wand.debug))
436 (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(),
437 "- Setting Option: %s \"%s\" \"%s\"", option,arg1n,arg2n);
443 #define _process_flags (cli_wand->process_flags)
444 #define _option_type ((CommandOptionFlags) cli_wand->command->flags)
445 /* Interpret Percent Escapes in Arguments - using first image */
446 if ( (((_process_flags & ProcessInterpretProperities) != 0 )
447 || ((_option_type & AlwaysInterpretArgsFlag) != 0)
448 ) && ((_option_type & NeverInterpretArgsFlag) == 0) ) {
449 /* Interpret Percent escapes in argument 1 */
450 if (arg1n != (char *) NULL) {
451 arg1=InterpretImageProperties(_image_info,_image,arg1n,_exception);
452 if (arg1 == (char *) NULL) {
453 CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
454 arg1=arg1n; /* use the given argument as is */
457 if (arg2n != (char *) NULL) {
458 arg2=InterpretImageProperties(_image_info,_image,arg2n,_exception);
459 if (arg2 == (char *) NULL) {
460 CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
461 arg2=arg2n; /* use the given argument as is */
465 #undef _process_flags
473 if (LocaleCompare("adjoin",option+1) == 0)
475 _image_info->adjoin = ArgBoolean;
478 if (LocaleCompare("affine",option+1) == 0)
480 CLIWandWarnReplaced("-draw 'affine ...'");
482 (void) ParseAffineGeometry(arg1,&_draw_info->affine,_exception);
484 GetAffineMatrix(&_draw_info->affine);
487 if (LocaleCompare("antialias",option+1) == 0)
489 _image_info->antialias =
490 _draw_info->stroke_antialias =
491 _draw_info->text_antialias = ArgBoolean;
494 if (LocaleCompare("attenuate",option+1) == 0)
496 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
497 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
498 (void) SetImageOption(_image_info,option+1,ArgOption("1.0"));
501 if (LocaleCompare("authenticate",option+1) == 0)
503 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
506 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
510 if (LocaleCompare("background",option+1) == 0)
512 /* FUTURE: both _image_info attribute & ImageOption in use!
513 _image_info only used directly for generating new images.
514 SyncImageSettings() used to set per-image attribute.
516 FUTURE: if _image_info->background_color is not set then
517 we should fall back to per-image background_color
519 At this time -background will 'wipe out' the per-image
522 Better error handling of QueryColorCompliance() needed.
524 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
525 (void) QueryColorCompliance(ArgOption(MogrifyBackgroundColor),AllCompliance,
526 &_image_info->background_color,_exception);
529 if (LocaleCompare("bias",option+1) == 0)
531 /* FUTURE: bias OBSOLETED, replaced by Artifact "convolve:bias"
532 as it is actually rarely used except in direct convolve operations
533 Usage outside a direct convolve operation is actally non-sensible!
535 SyncImageSettings() used to set per-image attribute.
537 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
538 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
539 (void) SetImageOption(_image_info,"convolve:bias",ArgOption(NULL));
542 if (LocaleCompare("black-point-compensation",option+1) == 0)
544 /* Used as a image chromaticity setting
545 SyncImageSettings() used to set per-image attribute.
547 (void) SetImageOption(_image_info,option+1,ArgBooleanString);
550 if (LocaleCompare("blue-primary",option+1) == 0)
552 /* Image chromaticity X,Y NB: Y=X if Y not defined
553 Used by many coders including PNG
554 SyncImageSettings() used to set per-image attribute.
556 arg1=ArgOption("0.0");
557 if (IfMagickFalse(IsGeometry(arg1)))
558 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
559 (void) SetImageOption(_image_info,option+1,arg1);
562 if (LocaleCompare("bordercolor",option+1) == 0)
564 /* FUTURE: both _image_info attribute & ImageOption in use!
565 SyncImageSettings() used to set per-image attribute.
566 Better error checking of QueryColorCompliance().
570 (void) SetImageOption(_image_info,option+1,arg1);
571 (void) QueryColorCompliance(arg1,AllCompliance,
572 &_image_info->border_color,_exception);
573 (void) QueryColorCompliance(arg1,AllCompliance,
574 &_draw_info->border_color,_exception);
577 (void) DeleteImageOption(_image_info,option+1);
578 (void) QueryColorCompliance(MogrifyBorderColor,AllCompliance,
579 &_image_info->border_color,_exception);
580 (void) QueryColorCompliance(MogrifyBorderColor,AllCompliance,
581 &_draw_info->border_color,_exception);
584 if (LocaleCompare("box",option+1) == 0)
586 CLIWandWarnReplaced("-undercolor");
587 CLISettingOptionInfo(cli_wand,"-undercolor",arg1, arg2);
590 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
594 if (LocaleCompare("cache",option+1) == 0)
599 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
600 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
601 limit=MagickResourceInfinity;
602 if (LocaleCompare("unlimited",arg1) != 0)
603 limit=(MagickSizeType) SiPrefixToDoubleInterval(arg1,100.0);
604 (void) SetMagickResourceLimit(MemoryResource,limit);
605 (void) SetMagickResourceLimit(MapResource,2*limit);
608 if (LocaleCompare("caption",option+1) == 0)
610 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
613 if (LocaleCompare("colorspace",option+1) == 0)
615 /* Setting used for new images via AquireImage()
616 But also used as a SimpleImageOperator
617 Undefined colorspace means don't modify images on
618 read or as a operation */
619 parse=ParseCommandOption(MagickColorspaceOptions,MagickFalse,
620 ArgOption("undefined"));
622 CLIWandExceptArgBreak(OptionError,"UnrecognizedColorspace",option,
624 _image_info->colorspace=(ColorspaceType) parse;
627 if (LocaleCompare("comment",option+1) == 0)
629 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
632 if (LocaleCompare("compose",option+1) == 0)
634 /* FUTURE: _image_info should be used,
635 SyncImageSettings() used to set per-image attribute. - REMOVE
637 This setting should NOT be used to set image 'compose'
638 "-layer" operators shoud use _image_info if defined otherwise
639 they should use a per-image compose setting.
641 parse = ParseCommandOption(MagickComposeOptions,MagickFalse,
642 ArgOption("undefined"));
644 CLIWandExceptArgBreak(OptionError,"UnrecognizedComposeOperator",
646 _image_info->compose=(CompositeOperator) parse;
647 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
650 if (LocaleCompare("compress",option+1) == 0)
652 /* FUTURE: What should be used? _image_info or ImageOption ???
653 The former is more efficent, but Crisy prefers the latter!
654 SyncImageSettings() used to set per-image attribute.
656 The coders appears to use _image_info, not Image_Option
657 however the image attribute (for save) is set from the
660 Note that "undefined" is a different setting to "none".
662 parse = ParseCommandOption(MagickCompressOptions,MagickFalse,
663 ArgOption("undefined"));
665 CLIWandExceptArgBreak(OptionError,"UnrecognizedImageCompression",
667 _image_info->compression=(CompressionType) parse;
668 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
671 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
675 if (LocaleCompare("debug",option+1) == 0)
677 /* SyncImageSettings() used to set per-image attribute. */
678 arg1=ArgOption("none");
679 parse = ParseCommandOption(MagickLogEventOptions,MagickFalse,arg1);
681 CLIWandExceptArgBreak(OptionError,"UnrecognizedEventType",
683 (void) SetLogEventMask(arg1);
684 _image_info->debug=IsEventLogging(); /* extract logging*/
685 cli_wand->wand.debug=IsEventLogging();
688 if (LocaleCompare("define",option+1) == 0)
690 if (LocaleNCompare(arg1,"registry:",9) == 0)
693 (void) DefineImageRegistry(StringRegistryType,arg1+9,_exception);
695 (void) DeleteImageRegistry(arg1+9);
698 /* DefineImageOption() equals SetImageOption() but with '=' */
700 (void) DefineImageOption(_image_info,arg1);
701 else if (DeleteImageOption(_image_info,arg1) == MagickFalse)
702 CLIWandExceptArgBreak(OptionError,"NoSuchOption",option,arg1);
705 if (LocaleCompare("delay",option+1) == 0)
707 /* Only used for new images via AcquireImage()
708 FUTURE: Option should also be used for "-morph" (color morphing)
711 if (IfMagickFalse(IsGeometry(arg1)))
712 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
713 (void) SetImageOption(_image_info,option+1,arg1);
716 if (LocaleCompare("density",option+1) == 0)
718 /* FUTURE: strings used in _image_info attr and _draw_info!
719 Basically as density can be in a XxY form!
721 SyncImageSettings() used to set per-image attribute.
723 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
724 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
725 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
726 (void) CloneString(&_image_info->density,ArgOption(NULL));
727 (void) CloneString(&_draw_info->density,_image_info->density);
730 if (LocaleCompare("depth",option+1) == 0)
732 /* This is also a SimpleImageOperator! for 8->16 vaule trunc !!!!
733 SyncImageSettings() used to set per-image attribute.
735 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
736 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
737 _image_info->depth=IfSetOption?StringToUnsignedLong(arg1)
738 :MAGICKCORE_QUANTUM_DEPTH;
741 if (LocaleCompare("direction",option+1) == 0)
743 /* Image Option is only used to set _draw_info */
744 arg1=ArgOption("undefined");
745 parse = ParseCommandOption(MagickDirectionOptions,MagickFalse,arg1);
747 CLIWandExceptArgBreak(OptionError,"UnrecognizedDirectionType",
749 _draw_info->direction=(DirectionType) parse;
750 (void) SetImageOption(_image_info,option+1,arg1);
753 if (LocaleCompare("display",option+1) == 0)
755 (void) CloneString(&_image_info->server_name,ArgOption(NULL));
756 (void) CloneString(&_draw_info->server_name,_image_info->server_name);
759 if (LocaleCompare("dispose",option+1) == 0)
761 /* only used in setting new images */
762 arg1=ArgOption("undefined");
763 parse = ParseCommandOption(MagickDisposeOptions,MagickFalse,arg1);
765 CLIWandExceptArgBreak(OptionError,"UnrecognizedDisposeMethod",
767 (void) SetImageOption(_image_info,option+1,ArgOption("undefined"));
770 if (LocaleCompare("dissimilarity-threshold",option+1) == 0)
772 /* FUTURE: this is only used by CompareImages() which is used
773 only by the "compare" CLI program at this time. */
774 arg1=ArgOption(DEFAULT_DISSIMILARITY_THRESHOLD);
775 if (IfMagickFalse(IsGeometry(arg1)))
776 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
777 (void) SetImageOption(_image_info,option+1,arg1);
780 if (LocaleCompare("dither",option+1) == 0)
782 /* _image_info attr (on/off), _quantize_info attr (on/off)
783 but also ImageInfo and _quantize_info method!
784 FUTURE: merge the duality of the dithering options
786 _image_info->dither = ArgBoolean;
787 (void) SetImageOption(_image_info,option+1,ArgOption("none"));
788 _quantize_info->dither_method=(DitherMethod) ParseCommandOption(
789 MagickDitherOptions,MagickFalse,ArgOption("none"));
790 if (_quantize_info->dither_method == NoDitherMethod)
791 _image_info->dither = MagickFalse;
794 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
798 if (LocaleCompare("encoding",option+1) == 0)
800 (void) CloneString(&_draw_info->encoding,ArgOption("undefined"));
801 (void) SetImageOption(_image_info,option+1,_draw_info->encoding);
804 if (LocaleCompare("endian",option+1) == 0)
806 /* Both _image_info attr and ImageInfo */
807 arg1 = ArgOption("undefined");
808 parse = ParseCommandOption(MagickEndianOptions,MagickFalse,arg1);
810 CLIWandExceptArgBreak(OptionError,"UnrecognizedEndianType",
812 /* FUTURE: check alloc/free of endian string! - remove? */
813 _image_info->endian=(EndianType) (*arg1);
814 (void) SetImageOption(_image_info,option+1,arg1);
817 if (LocaleCompare("extract",option+1) == 0)
819 (void) CloneString(&_image_info->extract,ArgOption(NULL));
822 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
826 if (LocaleCompare("family",option+1) == 0)
828 (void) CloneString(&_draw_info->family,ArgOption(NULL));
831 if (LocaleCompare("features",option+1) == 0)
833 (void) SetImageOption(_image_info,"identify:features",
836 (void) SetImageArtifact(_image,"verbose","true");
839 if (LocaleCompare("fill",option+1) == 0)
841 /* Set "fill" OR "fill-pattern" in _draw_info
842 The original fill color is preserved if a fill-pattern is given.
843 That way it does not effect other operations that directly using
844 the fill color and, can be retored using "+tile".
855 arg1 = ArgOption("none"); /* +fill turns it off! */
856 (void) SetImageOption(_image_info,option+1,arg1);
857 if (_draw_info->fill_pattern != (Image *) NULL)
858 _draw_info->fill_pattern=DestroyImage(_draw_info->fill_pattern);
860 /* is it a color or a image? -- ignore exceptions */
861 sans=AcquireExceptionInfo();
862 status=QueryColorCompliance(arg1,AllCompliance,&color,sans);
863 sans=DestroyExceptionInfo(sans);
865 if (IfMagickFalse(status))
866 _draw_info->fill_pattern=GetImageCache(_image_info,arg1,_exception);
868 _draw_info->fill=color;
871 if (LocaleCompare("filter",option+1) == 0)
873 /* SyncImageSettings() used to set per-image attribute. */
874 arg1 = ArgOption("undefined");
875 parse = ParseCommandOption(MagickFilterOptions,MagickFalse,arg1);
877 CLIWandExceptArgBreak(OptionError,"UnrecognizedImageFilter",
879 (void) SetImageOption(_image_info,option+1,arg1);
882 if (LocaleCompare("font",option+1) == 0)
884 (void) CloneString(&_draw_info->font,ArgOption(NULL));
885 (void) CloneString(&_image_info->font,_draw_info->font);
888 if (LocaleCompare("format",option+1) == 0)
890 /* FUTURE: why the ping test, you could set ping after this! */
895 for (q=strchr(arg1,'%'); q != (char *) NULL; q=strchr(q+1,'%'))
896 if (strchr("Agkrz@[#",*(q+1)) != (char *) NULL)
897 _image_info->ping=MagickFalse;
899 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
902 if (LocaleCompare("fuzz",option+1) == 0)
904 /* Option used to set image fuzz! unless blank canvas (from color)
905 Image attribute used for color compare operations
906 SyncImageSettings() used to set per-image attribute.
908 FUTURE: Can't find anything else using _image_info->fuzz directly!
909 convert structure attribute to 'option' string
912 if (IfMagickFalse(IsGeometry(arg1)))
913 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
914 _image_info->fuzz=StringToDoubleInterval(arg1,(double)
916 (void) SetImageOption(_image_info,option+1,arg1);
919 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
923 if (LocaleCompare("gravity",option+1) == 0)
925 /* SyncImageSettings() used to set per-image attribute. */
926 arg1 = ArgOption("none");
927 parse = ParseCommandOption(MagickGravityOptions,MagickFalse,arg1);
929 CLIWandExceptArgBreak(OptionError,"UnrecognizedGravityType",
931 _draw_info->gravity=(GravityType) parse;
932 (void) SetImageOption(_image_info,option+1,arg1);
935 if (LocaleCompare("green-primary",option+1) == 0)
937 /* Image chromaticity X,Y NB: Y=X if Y not defined
938 SyncImageSettings() used to set per-image attribute.
939 Used directly by many coders
941 arg1=ArgOption("0.0");
942 if (IfMagickFalse(IsGeometry(arg1)))
943 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
944 (void) SetImageOption(_image_info,option+1,arg1);
947 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
951 if (LocaleCompare("highlight-color",option+1) == 0)
953 /* FUTURE: this is only used by CompareImages() which is used
954 only by the "compare" CLI program at this time. */
955 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
958 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
962 if (LocaleCompare("intensity",option+1) == 0)
964 arg1 = ArgOption("undefined");
965 parse = ParseCommandOption(MagickPixelIntensityOptions,MagickFalse,
968 CLIWandExceptArgBreak(OptionError,"UnrecognizedIntensityType",
970 (void) SetImageOption(_image_info,option+1,arg1);
973 if (LocaleCompare("intent",option+1) == 0)
975 /* Only used by coders: MIFF, MPC, BMP, PNG
976 and for image profile call to AcquireTransformThreadSet()
977 SyncImageSettings() used to set per-image attribute.
979 arg1 = ArgOption("undefined");
980 parse = ParseCommandOption(MagickIntentOptions,MagickFalse,arg1);
982 CLIWandExceptArgBreak(OptionError,"UnrecognizedIntentType",
984 (void) SetImageOption(_image_info,option+1,arg1);
987 if (LocaleCompare("interlace",option+1) == 0)
989 /* _image_info is directly used by coders (so why an image setting?)
990 SyncImageSettings() used to set per-image attribute.
992 arg1 = ArgOption("undefined");
993 parse = ParseCommandOption(MagickInterlaceOptions,MagickFalse,arg1);
995 CLIWandExceptArgBreak(OptionError,"UnrecognizedInterlaceType",
997 _image_info->interlace=(InterlaceType) parse;
998 (void) SetImageOption(_image_info,option+1,arg1);
1001 if (LocaleCompare("interline-spacing",option+1) == 0)
1003 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
1004 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1005 (void) SetImageOption(_image_info,option+1, ArgOption(NULL));
1006 _draw_info->interline_spacing=StringToDouble(ArgOption("0"),
1010 if (LocaleCompare("interpolate",option+1) == 0)
1012 /* SyncImageSettings() used to set per-image attribute. */
1013 arg1 = ArgOption("undefined");
1014 parse = ParseCommandOption(MagickInterpolateOptions,MagickFalse,arg1);
1016 CLIWandExceptArgBreak(OptionError,"UnrecognizedInterpolateMethod",
1018 (void) SetImageOption(_image_info,option+1,arg1);
1021 if (LocaleCompare("interword-spacing",option+1) == 0)
1023 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
1024 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1025 (void) SetImageOption(_image_info,option+1, ArgOption(NULL));
1026 _draw_info->interword_spacing=StringToDouble(ArgOption("0"),(char **) NULL);
1029 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1033 if (LocaleCompare("kerning",option+1) == 0)
1035 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
1036 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1037 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1038 _draw_info->kerning=StringToDouble(ArgOption("0"),(char **) NULL);
1041 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1045 if (LocaleCompare("label",option+1) == 0)
1047 /* only used for new images - not in SyncImageOptions() */
1048 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1051 if (LocaleCompare("limit",option+1) == 0)
1056 limit=MagickResourceInfinity;
1057 parse= ParseCommandOption(MagickResourceOptions,MagickFalse,arg1);
1059 CLIWandExceptArgBreak(OptionError,"UnrecognizedResourceType",
1061 if (LocaleCompare("unlimited",arg2) != 0)
1062 limit=(MagickSizeType) SiPrefixToDoubleInterval(arg2,100.0);
1063 (void) SetMagickResourceLimit((ResourceType)parse,limit);
1066 if (LocaleCompare("log",option+1) == 0)
1069 if ((strchr(arg1,'%') == (char *) NULL))
1070 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1071 (void) SetLogFormat(arg1);
1075 if (LocaleCompare("lowlight-color",option+1) == 0)
1077 /* FUTURE: this is only used by CompareImages() which is used
1078 only by the "compare" CLI program at this time. */
1079 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1082 if (LocaleCompare("loop",option+1) == 0)
1084 /* SyncImageSettings() used to set per-image attribute. */
1085 arg1=ArgOption("0");
1086 if (IfMagickFalse(IsGeometry(arg1)))
1087 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1088 (void) SetImageOption(_image_info,option+1,arg1);
1091 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1095 if (LocaleCompare("mattecolor",option+1) == 0)
1097 /* SyncImageSettings() used to set per-image attribute. */
1098 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1099 (void) QueryColorCompliance(ArgOption(MogrifyMatteColor),AllCompliance,
1100 &_image_info->matte_color,_exception);
1103 if (LocaleCompare("metric",option+1) == 0)
1105 /* FUTURE: this is only used by CompareImages() which is used
1106 only by the "compare" CLI program at this time. */
1107 parse=ParseCommandOption(MagickMetricOptions,MagickFalse,arg1);
1109 CLIWandExceptArgBreak(OptionError,"UnrecognizedMetricType",
1111 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1114 if (LocaleCompare("moments",option+1) == 0)
1116 (void) SetImageOption(_image_info,"identify:moments",
1119 (void) SetImageArtifact(_image,"verbose","true");
1122 if (LocaleCompare("monitor",option+1) == 0)
1124 (void) SetImageInfoProgressMonitor(_image_info, IfSetOption?
1125 MonitorProgress: (MagickProgressMonitor) NULL, (void *) NULL);
1128 if (LocaleCompare("monochrome",option+1) == 0)
1130 /* Setting (used by some input coders!) -- why?
1131 Warning: This is also Special '-type' SimpleOperator
1133 _image_info->monochrome= ArgBoolean;
1136 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1140 if (LocaleCompare("orient",option+1) == 0)
1142 /* Is not used when defining for new images.
1143 This makes it more of a 'operation' than a setting
1144 FUTURE: make set meta-data operator instead.
1145 SyncImageSettings() used to set per-image attribute.
1147 parse=ParseCommandOption(MagickOrientationOptions,MagickFalse,
1148 ArgOption("undefined"));
1150 CLIWandExceptArgBreak(OptionError,"UnrecognizedImageOrientation",
1152 _image_info->orientation=(OrientationType)parse;
1153 (void) SetImageOption(_image_info,option+1, ArgOption(NULL));
1156 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1160 if (LocaleCompare("page",option+1) == 0)
1162 /* Only used for new images and image generators.
1163 SyncImageSettings() used to set per-image attribute. ?????
1164 That last is WRONG!!!!
1165 FUTURE: adjust named 'page' sizes according density
1169 page[MagickPathExtent];
1182 (void) DeleteImageOption(_image_info,option+1);
1183 (void) CloneString(&_image_info->page,(char *) NULL);
1186 (void) ResetMagickMemory(&geometry,0,sizeof(geometry));
1187 image_option=GetImageOption(_image_info,"page");
1188 if (image_option != (const char *) NULL)
1189 flags=ParseAbsoluteGeometry(image_option,&geometry);
1190 canonical_page=GetPageGeometry(arg1);
1191 flags=ParseAbsoluteGeometry(canonical_page,&geometry);
1192 canonical_page=DestroyString(canonical_page);
1193 (void) FormatLocaleString(page,MagickPathExtent,"%lux%lu",
1194 (unsigned long) geometry.width,(unsigned long) geometry.height);
1195 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
1196 (void) FormatLocaleString(page,MagickPathExtent,"%lux%lu%+ld%+ld",
1197 (unsigned long) geometry.width,(unsigned long) geometry.height,
1198 (long) geometry.x,(long) geometry.y);
1199 (void) SetImageOption(_image_info,option+1,page);
1200 (void) CloneString(&_image_info->page,page);
1203 if (LocaleCompare("ping",option+1) == 0)
1205 _image_info->ping = ArgBoolean;
1208 if (LocaleCompare("pointsize",option+1) == 0)
1211 if (IfMagickFalse(IsGeometry(arg1)))
1212 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1213 _image_info->pointsize =
1214 _draw_info->pointsize =
1215 StringToDouble(arg1,(char **) NULL);
1218 _image_info->pointsize=0.0; /* unset pointsize */
1219 _draw_info->pointsize=12.0;
1223 if (LocaleCompare("precision",option+1) == 0)
1225 arg1=ArgOption("-1");
1226 if (IfMagickFalse(IsGeometry(arg1)))
1227 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1228 (void) SetMagickPrecision(StringToInteger(arg1));
1231 /* FUTURE: Only the 'preview' coder appears to use this
1232 * DEPRECIATE the coder? Leaving only the 'preview' operator.
1233 if (LocaleCompare("preview",option+1) == 0)
1235 _image_info->preview_type=UndefinedPreview;
1237 _image_info->preview_type=(PreviewType) ParseCommandOption(
1238 MagickPreviewOptions,MagickFalse,arg1);
1242 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1246 if (LocaleCompare("quality",option+1) == 0)
1248 if (IfMagickFalse(IsGeometry(arg1)))
1249 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1250 _image_info->quality= IfSetOption ? StringToUnsignedLong(arg1)
1251 : UNDEFINED_COMPRESSION_QUALITY;
1252 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1255 if (LocaleCompare("quantize",option+1) == 0)
1257 /* Just a set direct in _quantize_info */
1258 arg1=ArgOption("undefined");
1259 parse=ParseCommandOption(MagickColorspaceOptions,MagickFalse,arg1);
1261 CLIWandExceptArgBreak(OptionError,"UnrecognizedColorspace",
1263 _quantize_info->colorspace=(ColorspaceType)parse;
1266 if (LocaleCompare("quiet",option+1) == 0)
1268 /* FUTURE: if two -quiet is performed you can not do +quiet!
1269 This needs to be checked over thoughly.
1271 static WarningHandler
1272 warning_handler = (WarningHandler) NULL;
1275 tmp = SetWarningHandler((WarningHandler) NULL);
1277 if ( tmp != (WarningHandler) NULL)
1278 warning_handler = tmp; /* remember the old handler */
1279 if (!IfSetOption) /* set the old handler */
1280 warning_handler=SetWarningHandler(warning_handler);
1283 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1287 if (LocaleCompare("red-primary",option+1) == 0)
1289 /* Image chromaticity X,Y NB: Y=X if Y not defined
1291 SyncImageSettings() used to set per-image attribute.
1293 arg1=ArgOption("0.0");
1294 if (IfMagickFalse(IsGeometry(arg1)))
1295 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1296 (void) SetImageOption(_image_info,option+1,arg1);
1299 if (LocaleCompare("regard-warnings",option+1) == 0)
1300 /* FUTURE: to be replaced by a 'fatal-level' type setting */
1302 if (LocaleCompare("render",option+1) == 0)
1304 /* _draw_info only setting */
1305 _draw_info->render= ArgBooleanNot;
1308 if (LocaleCompare("respect-parenthesis",option+1) == 0)
1310 /* link image and setting stacks - option is itself saved on stack! */
1311 (void) SetImageOption(_image_info,option+1,ArgBooleanString);
1314 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1318 if (LocaleCompare("sampling-factor",option+1) == 0)
1320 /* FUTURE: should be converted to jpeg:sampling_factor */
1321 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
1322 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1323 (void) CloneString(&_image_info->sampling_factor,ArgOption(NULL));
1326 if (LocaleCompare("scene",option+1) == 0)
1328 /* SyncImageSettings() used to set this as a per-image attribute.
1331 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
1332 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1333 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1334 _image_info->scene=StringToUnsignedLong(ArgOption("0"));
1337 if (LocaleCompare("seed",option+1) == 0)
1339 if (IfMagickFalse(IsGeometry(arg1)))
1340 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1342 IfSetOption ? (unsigned long) StringToUnsignedLong(arg1)
1343 : (unsigned long) time((time_t *) NULL) );
1346 if (LocaleCompare("size",option+1) == 0)
1348 /* FUTURE: string in _image_info -- convert to Option ???
1349 Look at the special handling for "size" in SetImageOption()
1351 (void) CloneString(&_image_info->size,ArgOption(NULL));
1354 if (LocaleCompare("stretch",option+1) == 0)
1356 arg1=ArgOption("undefined");
1357 parse = ParseCommandOption(MagickStretchOptions,MagickFalse,arg1);
1359 CLIWandExceptArgBreak(OptionError,"UnrecognizedStretchType",
1361 _draw_info->stretch=(StretchType) parse;
1364 if (LocaleCompare("stroke",option+1) == 0)
1366 /* set stroke color OR stroke-pattern
1367 UPDATE: ensure stroke color is not destroyed is a pattern
1368 is given. Just in case the color is also used for other purposes.
1379 arg1 = ArgOption("none"); /* +fill turns it off! */
1380 (void) SetImageOption(_image_info,option+1,arg1);
1381 if (_draw_info->stroke_pattern != (Image *) NULL)
1382 _draw_info->stroke_pattern=DestroyImage(_draw_info->stroke_pattern);
1384 /* is it a color or a image? -- ignore exceptions */
1385 sans=AcquireExceptionInfo();
1386 status=QueryColorCompliance(arg1,AllCompliance,&color,sans);
1387 sans=DestroyExceptionInfo(sans);
1389 if (IfMagickFalse(status))
1390 _draw_info->stroke_pattern=GetImageCache(_image_info,arg1,_exception);
1392 _draw_info->stroke=color;
1395 if (LocaleCompare("strokewidth",option+1) == 0)
1397 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
1398 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1399 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1400 _draw_info->stroke_width=StringToDouble(ArgOption("1.0"),
1404 if (LocaleCompare("style",option+1) == 0)
1406 arg1=ArgOption("undefined");
1407 parse = ParseCommandOption(MagickStyleOptions,MagickFalse,arg1);
1409 CLIWandExceptArgBreak(OptionError,"UnrecognizedStyleType",
1411 _draw_info->style=(StyleType) parse;
1415 if (LocaleCompare("subimage-search",option+1) == 0)
1417 /* FUTURE: this is only used by CompareImages() which is used
1418 only by the "compare" CLI program at this time. */
1419 (void) SetImageOption(_image_info,option+1,ArgBooleanString);
1423 if (LocaleCompare("synchronize",option+1) == 0)
1425 /* FUTURE: syncronize to storage - but what does that mean? */
1426 _image_info->synchronize = ArgBoolean;
1429 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1433 if (LocaleCompare("taint",option+1) == 0)
1435 /* SyncImageSettings() used to set per-image attribute. */
1436 (void) SetImageOption(_image_info,option+1,ArgBooleanString);
1439 if (LocaleCompare("texture",option+1) == 0)
1441 /* Note: arguments do not have percent escapes expanded */
1442 /* FUTURE: move _image_info string to option splay-tree
1443 Other than "montage" what uses "texture" ????
1445 (void) CloneString(&_image_info->texture,ArgOption(NULL));
1448 if (LocaleCompare("tile",option+1) == 0)
1450 /* Note: arguments do not have percent escapes expanded */
1451 _draw_info->fill_pattern=IfSetOption
1452 ?GetImageCache(_image_info,arg1,_exception)
1453 :DestroyImage(_draw_info->fill_pattern);
1456 if (LocaleCompare("tile-offset",option+1) == 0)
1458 /* SyncImageSettings() used to set per-image attribute. ??? */
1459 arg1=ArgOption("0");
1460 if (IfMagickFalse(IsGeometry(arg1)))
1461 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1462 (void) SetImageOption(_image_info,option+1,arg1);
1465 if (LocaleCompare("transparent-color",option+1) == 0)
1467 /* FUTURE: both _image_info attribute & ImageOption in use!
1468 _image_info only used for generating new images.
1469 SyncImageSettings() used to set per-image attribute.
1471 Note that +transparent-color, means fall-back to image
1472 attribute so ImageOption is deleted, not set to a default.
1474 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
1475 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1476 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1477 (void) QueryColorCompliance(ArgOption("none"),AllCompliance,
1478 &_image_info->transparent_color,_exception);
1481 if (LocaleCompare("treedepth",option+1) == 0)
1483 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1484 _quantize_info->tree_depth=StringToUnsignedLong(ArgOption("0"));
1487 if (LocaleCompare("type",option+1) == 0)
1489 /* SyncImageSettings() used to set per-image attribute. */
1490 parse=ParseCommandOption(MagickTypeOptions,MagickFalse,
1491 ArgOption("undefined"));
1493 CLIWandExceptArgBreak(OptionError,"UnrecognizedImageType",
1495 _image_info->type=(ImageType) parse;
1496 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1499 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1503 if (LocaleCompare("undercolor",option+1) == 0)
1505 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1506 (void) QueryColorCompliance(ArgOption("none"),AllCompliance,
1507 &_draw_info->undercolor,_exception);
1510 if (LocaleCompare("units",option+1) == 0)
1512 /* SyncImageSettings() used to set per-image attribute.
1513 Should this effect _draw_info X and Y resolution?
1514 FUTURE: this probably should be part of the density setting
1516 parse=ParseCommandOption(MagickResolutionOptions,MagickFalse,
1517 ArgOption("undefined"));
1519 CLIWandExceptArgBreak(OptionError,"UnrecognizedUnitsType",
1521 _image_info->units=(ResolutionType) parse;
1522 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1525 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1529 if (LocaleCompare("verbose",option+1) == 0)
1531 /* FUTURE: Remember all options become image artifacts
1532 _image_info->verbose is only used by coders.
1534 (void) SetImageOption(_image_info,option+1,ArgBooleanString);
1535 _image_info->verbose= ArgBoolean;
1536 _image_info->ping=MagickFalse; /* verbose can't be a ping */
1539 if (LocaleCompare("view",option+1) == 0)
1541 /* FUTURE: Convert from _image_info to ImageOption
1542 Only used by coder FPX
1543 And it only tests existance, not its content!
1545 (void) CloneString(&_image_info->view,ArgOption(NULL));
1548 if (LocaleCompare("virtual-pixel",option+1) == 0)
1550 /* SyncImageSettings() used to set per-image attribute.
1551 This is VERY deep in the image caching structure.
1553 parse=ParseCommandOption(MagickVirtualPixelOptions,MagickFalse,
1554 ArgOption("undefined"));
1556 CLIWandExceptArgBreak(OptionError,"UnrecognizedVirtualPixelMethod",
1558 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1561 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1565 if (LocaleCompare("weight",option+1) == 0)
1570 weight=ParseCommandOption(MagickWeightOptions,MagickFalse,arg1);
1572 weight=StringToUnsignedLong(arg1);
1573 _draw_info->weight=(size_t) weight;
1576 if (LocaleCompare("white-point",option+1) == 0)
1578 /* Used as a image chromaticity setting
1579 SyncImageSettings() used to set per-image attribute.
1581 arg1=ArgOption("0.0");
1582 if (IfMagickFalse(IsGeometry(arg1)))
1583 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1584 (void) SetImageOption(_image_info,option+1,arg1);
1587 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1590 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1593 /* clean up percent escape interpreted strings */
1594 if ((arg1 && arg1n) && (arg1 != arg1n ))
1595 arg1=DestroyString((char *) arg1);
1596 if ((arg2 && arg2n) && (arg2 != arg2n ))
1597 arg2=DestroyString((char *) arg2);
1602 #undef _quantize_info
1605 #undef ArgBooleanNot
1606 #undef ArgBooleanString
1613 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1617 + C L I S i m p l e O p e r a t o r I m a g e s %
1621 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1623 % CLISimpleOperatorImages() applys one simple image operation given to all
1624 % the images in the CLI wand, using any per-image or global settings that was
1625 % previously saved in the CLI wand.
1627 % It is assumed that any such settings are up-to-date.
1629 % The format of the WandSimpleOperatorImages method is:
1631 % MagickBooleanType CLISimpleOperatorImages(MagickCLI *cli_wand,const char *option,
1632 % const char *arg1, const char *arg2,ExceptionInfo *exception)
1634 % A description of each parameter follows:
1636 % o cli_wand: structure holding settings and images to be operated on
1638 % o option: The option string for the operation
1640 % o arg1, arg2: optional argument strings to the operation
1645 CLISimpleOperatorImage() is an Internal subrountine to apply one simple
1646 image operation to the current image pointed to by the CLI wand.
1648 The image in the list may be modified in three different ways...
1649 * directly modified (EG: -negate, -gamma, -level, -annotate, -draw),
1650 * replaced by a new image (EG: -spread, -resize, -rotate, -morphology)
1651 * one image replace by a list of images (-separate and -crop only!)
1653 In each case the result replaces the single original image in the list, as
1654 well as the pointer to the modified image (last image added if replaced by a
1655 list of images) is returned.
1657 As the image pointed to may be replaced, the first image in the list may
1658 also change. GetFirstImageInList() should be used by caller if they wish
1659 return the Image pointer to the first image in list.
1661 static MagickBooleanType CLISimpleOperatorImage(MagickCLI *cli_wand,
1662 const char *option, const char *arg1n, const char *arg2n,
1663 ExceptionInfo *exception)
1680 const char /* percent escaped versions of the args */
1684 #define _image_info (cli_wand->wand.image_info)
1685 #define _image (cli_wand->wand.images)
1686 #define _exception (cli_wand->wand.exception)
1687 #define _draw_info (cli_wand->draw_info)
1688 #define _quantize_info (cli_wand->quantize_info)
1689 #define _process_flags (cli_wand->process_flags)
1690 #define _option_type ((CommandOptionFlags) cli_wand->command->flags)
1691 #define IfNormalOp (*option=='-')
1692 #define IfPlusOp (*option!='-')
1693 #define IsNormalOp IfNormalOp ? MagickTrue : MagickFalse
1694 #define IsPlusOp IfNormalOp ? MagickFalse : MagickTrue
1696 assert(cli_wand != (MagickCLI *) NULL);
1697 assert(cli_wand->signature == MagickWandSignature);
1698 assert(cli_wand->wand.signature == MagickWandSignature);
1699 assert(_image != (Image *) NULL); /* an image must be present */
1700 if (IfMagickTrue(cli_wand->wand.debug))
1701 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
1706 /* Interpret Percent Escapes in Arguments - using first image */
1707 if ( (((_process_flags & ProcessInterpretProperities) != 0 )
1708 || ((_option_type & AlwaysInterpretArgsFlag) != 0)
1709 ) && ((_option_type & NeverInterpretArgsFlag) == 0) ) {
1710 /* Interpret Percent escapes in argument 1 */
1711 if (arg1n != (char *) NULL) {
1712 arg1=InterpretImageProperties(_image_info,_image,arg1n,_exception);
1713 if (arg1 == (char *) NULL) {
1714 CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
1715 arg1=arg1n; /* use the given argument as is */
1718 if (arg2n != (char *) NULL) {
1719 arg2=InterpretImageProperties(_image_info,_image,arg2n,_exception);
1720 if (arg2 == (char *) NULL) {
1721 CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
1722 arg2=arg2n; /* use the given argument as is */
1726 #undef _process_flags
1730 (void) FormatLocaleFile(stderr,
1731 "CLISimpleOperatorImage: \"%s\" \"%s\" \"%s\"\n",option,arg1,arg2);
1734 new_image = (Image *) NULL; /* the replacement image, if not null at end */
1735 SetGeometryInfo(&geometry_info);
1737 switch (*(option+1))
1741 if (LocaleCompare("adaptive-blur",option+1) == 0)
1743 flags=ParseGeometry(arg1,&geometry_info);
1744 if ((flags & (RhoValue|SigmaValue)) == 0)
1745 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1746 if ((flags & SigmaValue) == 0)
1747 geometry_info.sigma=1.0;
1748 new_image=AdaptiveBlurImage(_image,geometry_info.rho,
1749 geometry_info.sigma,_exception);
1752 if (LocaleCompare("adaptive-resize",option+1) == 0)
1754 /* FUTURE: Roll into a resize special operator */
1755 if (IfMagickFalse(IsGeometry(arg1)))
1756 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1757 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
1758 new_image=AdaptiveResizeImage(_image,geometry.width,geometry.height,
1762 if (LocaleCompare("adaptive-sharpen",option+1) == 0)
1764 flags=ParseGeometry(arg1,&geometry_info);
1765 if ((flags & (RhoValue|SigmaValue)) == 0)
1766 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1767 if ((flags & SigmaValue) == 0)
1768 geometry_info.sigma=1.0;
1769 new_image=AdaptiveSharpenImage(_image,geometry_info.rho,
1770 geometry_info.sigma,_exception);
1773 if (LocaleCompare("alpha",option+1) == 0)
1775 parse=ParseCommandOption(MagickAlphaChannelOptions,MagickFalse,arg1);
1777 CLIWandExceptArgBreak(OptionError,"UnrecognizedAlphaChannelOption",
1779 (void) SetImageAlphaChannel(_image,(AlphaChannelOption) parse,
1783 if (LocaleCompare("annotate",option+1) == 0)
1786 geometry[MagickPathExtent];
1788 SetGeometryInfo(&geometry_info);
1789 flags=ParseGeometry(arg1,&geometry_info);
1791 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1792 if ((flags & SigmaValue) == 0)
1793 geometry_info.sigma=geometry_info.rho;
1794 (void) CloneString(&_draw_info->text,arg2);
1795 (void) FormatLocaleString(geometry,MagickPathExtent,"%+f%+f",
1796 geometry_info.xi,geometry_info.psi);
1797 (void) CloneString(&_draw_info->geometry,geometry);
1798 _draw_info->affine.sx=cos(DegreesToRadians(
1799 fmod(geometry_info.rho,360.0)));
1800 _draw_info->affine.rx=sin(DegreesToRadians(
1801 fmod(geometry_info.rho,360.0)));
1802 _draw_info->affine.ry=(-sin(DegreesToRadians(
1803 fmod(geometry_info.sigma,360.0))));
1804 _draw_info->affine.sy=cos(DegreesToRadians(
1805 fmod(geometry_info.sigma,360.0)));
1806 (void) AnnotateImage(_image,_draw_info,_exception);
1807 GetAffineMatrix(&_draw_info->affine);
1810 if (LocaleCompare("auto-gamma",option+1) == 0)
1812 (void) AutoGammaImage(_image,_exception);
1815 if (LocaleCompare("auto-level",option+1) == 0)
1817 (void) AutoLevelImage(_image,_exception);
1820 if (LocaleCompare("auto-orient",option+1) == 0)
1822 new_image=AutoOrientImage(_image,_image->orientation,_exception);
1825 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1829 if (LocaleCompare("black-threshold",option+1) == 0)
1831 if (IfMagickFalse(IsGeometry(arg1)))
1832 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1833 (void) BlackThresholdImage(_image,arg1,_exception);
1836 if (LocaleCompare("blue-shift",option+1) == 0)
1838 geometry_info.rho=1.5;
1840 flags=ParseGeometry(arg1,&geometry_info);
1841 if ((flags & RhoValue) == 0)
1842 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1844 new_image=BlueShiftImage(_image,geometry_info.rho,_exception);
1847 if (LocaleCompare("blur",option+1) == 0)
1849 flags=ParseGeometry(arg1,&geometry_info);
1850 if ((flags & (RhoValue|SigmaValue)) == 0)
1851 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1852 if ((flags & SigmaValue) == 0)
1853 geometry_info.sigma=1.0;
1854 new_image=BlurImage(_image,geometry_info.rho,geometry_info.sigma,
1858 if (LocaleCompare("border",option+1) == 0)
1866 flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
1867 if ((flags & (WidthValue | HeightValue)) == 0)
1868 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1869 compose=OverCompositeOp;
1870 value=GetImageOption(_image_info,"compose");
1871 if (value != (const char *) NULL)
1872 compose=(CompositeOperator) ParseCommandOption(MagickComposeOptions,
1874 new_image=BorderImage(_image,&geometry,compose,_exception);
1877 if (LocaleCompare("brightness-contrast",option+1) == 0)
1889 flags=ParseGeometry(arg1,&geometry_info);
1890 if ((flags & RhoValue) == 0)
1891 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1892 brightness=geometry_info.rho;
1894 if ((flags & SigmaValue) != 0)
1895 contrast=geometry_info.sigma;
1896 (void) BrightnessContrastImage(_image,brightness,contrast,
1900 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1904 if (LocaleCompare("canny",option+1) == 0)
1906 flags=ParseGeometry(arg1,&geometry_info);
1907 if ((flags & (RhoValue|SigmaValue)) == 0)
1908 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1909 if ((flags & SigmaValue) == 0)
1910 geometry_info.sigma=1.0;
1911 if ((flags & XiValue) == 0)
1912 geometry_info.xi=10;
1913 if ((flags & PsiValue) == 0)
1914 geometry_info.psi=30;
1915 if ((flags & PercentValue) != 0)
1917 geometry_info.xi/=100.0;
1918 geometry_info.psi/=100.0;
1920 new_image=CannyEdgeImage(_image,geometry_info.rho,geometry_info.sigma,
1921 geometry_info.xi,geometry_info.psi,_exception);
1924 if (LocaleCompare("cdl",option+1) == 0)
1926 /* Note: arguments do not have percent escapes expanded */
1928 *color_correction_collection;
1931 Color correct with a color decision list.
1933 color_correction_collection=FileToString(arg1,~0UL,_exception);
1934 if (color_correction_collection == (char *) NULL)
1936 (void) ColorDecisionListImage(_image,color_correction_collection,
1940 if (LocaleCompare("channel",option+1) == 0)
1944 (void) SetPixelChannelMask(_image,DefaultChannels);
1947 parse=ParseChannelOption(arg1);
1949 CLIWandExceptArgBreak(OptionError,"UnrecognizedIntensityMethod",
1951 (void) SetPixelChannelMask(_image,(ChannelType) parse);
1954 if (LocaleCompare("charcoal",option+1) == 0)
1956 flags=ParseGeometry(arg1,&geometry_info);
1957 if ((flags & (RhoValue|SigmaValue)) == 0)
1958 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1959 if ((flags & SigmaValue) == 0)
1960 geometry_info.sigma=1.0;
1961 if ((flags & XiValue) == 0)
1962 geometry_info.xi=1.0;
1963 new_image=CharcoalImage(_image,geometry_info.rho,geometry_info.sigma,
1967 if (LocaleCompare("chop",option+1) == 0)
1969 if (IfMagickFalse(IsGeometry(arg1)))
1970 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1971 (void) ParseGravityGeometry(_image,arg1,&geometry,_exception);
1972 new_image=ChopImage(_image,&geometry,_exception);
1975 if (LocaleCompare("clamp",option+1) == 0)
1977 (void) ClampImage(_image,_exception);
1980 if (LocaleCompare("clip",option+1) == 0)
1983 (void) ClipImage(_image,_exception);
1984 else /* "+mask" remove the write mask */
1985 (void) SetImageMask(_image,ReadPixelMask,(Image *) NULL,_exception);
1988 if (LocaleCompare("clip-mask",option+1) == 0)
1990 /* Note: arguments do not have percent escapes expanded */
2007 /* use "+clip-mask" Remove the write mask for -clip-path */
2008 (void) SetImageMask(_image,ReadPixelMask,(Image *) NULL,_exception);
2011 mask_image=GetImageCache(_image_info,arg1,_exception);
2012 if (mask_image == (Image *) NULL)
2014 if (IfMagickFalse(SetImageStorageClass(mask_image,DirectClass,_exception)))
2016 /* Create a write mask from cli_wand mask image */
2017 /* FUTURE: use Alpha operations instead and create a Grey Image */
2018 mask_view=AcquireAuthenticCacheView(mask_image,_exception);
2019 for (y=0; y < (ssize_t) mask_image->rows; y++)
2021 q=GetCacheViewAuthenticPixels(mask_view,0,y,mask_image->columns,1,
2023 if (q == (Quantum *) NULL)
2025 for (x=0; x < (ssize_t) mask_image->columns; x++)
2027 if (mask_image->alpha_trait == UndefinedPixelTrait)
2028 SetPixelAlpha(mask_image,(Quantum)
2029 GetPixelIntensity(mask_image,q),q);
2030 SetPixelGray(mask_image,GetPixelAlpha(mask_image,q),q);
2031 q+=GetPixelChannels(mask_image);
2033 if (IfMagickFalse(SyncCacheViewAuthenticPixels(mask_view,_exception)))
2036 /* clean up and set the write mask */
2037 mask_view=DestroyCacheView(mask_view);
2038 mask_image->alpha_trait=BlendPixelTrait;
2039 (void) SetImageColorspace(_image,GRAYColorspace,_exception);
2040 (void) SetImageMask(_image,ReadPixelMask,mask_image,_exception);
2041 mask_image=DestroyImage(mask_image);
2044 if (LocaleCompare("clip-path",option+1) == 0)
2046 (void) ClipImagePath(_image,arg1,IsNormalOp,_exception);
2047 /* Note: Use "+clip-mask" remove the write mask added */
2050 if (LocaleCompare("colorize",option+1) == 0)
2052 if (IfMagickFalse(IsGeometry(arg1)))
2053 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2054 new_image=ColorizeImage(_image,arg1,&_draw_info->fill,_exception);
2057 if (LocaleCompare("color-matrix",option+1) == 0)
2062 kernel=AcquireKernelInfo(arg1,exception);
2063 if (kernel == (KernelInfo *) NULL)
2064 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2065 new_image=ColorMatrixImage(_image,kernel,_exception);
2066 kernel=DestroyKernelInfo(kernel);
2069 if (LocaleCompare("colors",option+1) == 0)
2071 /* Reduce the number of colors in the image.
2072 FUTURE: also provide 'plus version with image 'color counts'
2074 _quantize_info->number_colors=StringToUnsignedLong(arg1);
2075 if (_quantize_info->number_colors == 0)
2076 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2077 if ((_image->storage_class == DirectClass) ||
2078 _image->colors > _quantize_info->number_colors)
2079 (void) QuantizeImage(_quantize_info,_image,_exception);
2081 (void) CompressImageColormap(_image,_exception);
2084 if (LocaleCompare("colorspace",option+1) == 0)
2086 /* WARNING: this is both a image_info setting (already done)
2087 and a operator to change image colorspace.
2089 FUTURE: default colorspace should be sRGB!
2090 Unless some type of 'linear colorspace' mode is set.
2092 Note that +colorspace sets "undefined" or no effect on
2093 new images, but forces images already in memory back to RGB!
2094 That seems to be a little strange!
2096 (void) TransformImageColorspace(_image,
2097 IfNormalOp ? _image_info->colorspace : sRGBColorspace,
2101 if (LocaleCompare("connected-components",option+1) == 0)
2103 if (IfMagickFalse(IsGeometry(arg1)))
2104 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2105 new_image=ConnectedComponentsImage(_image,(size_t)
2106 StringToInteger(arg1),_exception);
2109 if (LocaleCompare("contrast",option+1) == 0)
2111 CLIWandWarnReplaced(IfNormalOp?"-level":"+level");
2112 (void) ContrastImage(_image,IsNormalOp,_exception);
2115 if (LocaleCompare("contrast-stretch",option+1) == 0)
2124 flags=ParseGeometry(arg1,&geometry_info);
2125 if ((flags & RhoValue) == 0)
2126 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2127 black_point=geometry_info.rho;
2128 white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
2130 if ((flags & PercentValue) != 0) {
2131 black_point*=(double) _image->columns*_image->rows/100.0;
2132 white_point*=(double) _image->columns*_image->rows/100.0;
2134 white_point=(double) _image->columns*_image->rows-white_point;
2135 (void) ContrastStretchImage(_image,black_point,white_point,
2139 if (LocaleCompare("convolve",option+1) == 0)
2150 kernel_info=AcquireKernelInfo(arg1,exception);
2151 if (kernel_info == (KernelInfo *) NULL)
2152 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2154 for (j=0; j < (ssize_t) (kernel_info->width*kernel_info->height); j++)
2155 gamma+=kernel_info->values[j];
2156 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
2157 for (j=0; j < (ssize_t) (kernel_info->width*kernel_info->height); j++)
2158 kernel_info->values[j]*=gamma;
2159 new_image=MorphologyImage(_image,CorrelateMorphology,1,kernel_info,
2161 kernel_info=DestroyKernelInfo(kernel_info);
2164 if (LocaleCompare("crop",option+1) == 0)
2166 /* WARNING: This can generate multiple images! */
2167 if (IfMagickFalse(IsGeometry(arg1)))
2168 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2169 new_image=CropImageToTiles(_image,arg1,_exception);
2172 if (LocaleCompare("cycle",option+1) == 0)
2174 if (IfMagickFalse(IsGeometry(arg1)))
2175 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2176 (void) CycleColormapImage(_image,(ssize_t) StringToLong(arg1),
2180 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2184 if (LocaleCompare("decipher",option+1) == 0)
2186 /* Note: arguments do not have percent escapes expanded */
2190 passkey=FileToStringInfo(arg1,~0UL,_exception);
2191 if (passkey == (StringInfo *) NULL)
2192 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2194 (void) PasskeyDecipherImage(_image,passkey,_exception);
2195 passkey=DestroyStringInfo(passkey);
2198 if (LocaleCompare("depth",option+1) == 0)
2200 /* The _image_info->depth setting has already been set
2201 We just need to apply it to all images in current sequence
2203 WARNING: Depth from 8 to 16 causes 'quantum rounding to images!
2204 That is it really is an operation, not a setting! Arrgghhh
2206 FUTURE: this should not be an operator!!!
2208 (void) SetImageDepth(_image,_image_info->depth,_exception);
2211 if (LocaleCompare("deskew",option+1) == 0)
2217 if (IfMagickFalse(IsGeometry(arg1)))
2218 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2219 threshold=StringToDoubleInterval(arg1,(double) QuantumRange+1.0);
2222 threshold=40.0*QuantumRange/100.0;
2223 new_image=DeskewImage(_image,threshold,_exception);
2226 if (LocaleCompare("despeckle",option+1) == 0)
2228 new_image=DespeckleImage(_image,_exception);
2231 if (LocaleCompare("distort",option+1) == 0)
2239 parse = ParseCommandOption(MagickDistortOptions,MagickFalse,arg1);
2241 CLIWandExceptArgBreak(OptionError,"UnrecognizedDistortMethod",
2243 if ((DistortImageMethod) parse == ResizeDistortion)
2247 /* Special Case - Argument is actually a resize geometry!
2248 ** Convert that to an appropriate distortion argument array.
2249 ** FUTURE: make a separate special resize operator
2250 Roll into a resize special operator */
2251 if (IfMagickFalse(IsGeometry(arg2)))
2252 CLIWandExceptArgBreak(OptionError,"InvalidGeometry",
2254 (void) ParseRegionGeometry(_image,arg2,&geometry,_exception);
2255 resize_args[0]=(double) geometry.width;
2256 resize_args[1]=(double) geometry.height;
2257 new_image=DistortImage(_image,(DistortImageMethod) parse,
2258 (size_t)2,resize_args,MagickTrue,_exception);
2261 /* convert argument string into an array of doubles */
2262 args = StringToArrayOfDoubles(arg2,&count,_exception);
2263 if (args == (double *) NULL )
2264 CLIWandExceptArgBreak(OptionError,"InvalidNumberList",option,arg2);
2266 new_image=DistortImage(_image,(DistortImageMethod) parse,(size_t)
2267 count,args,IsPlusOp,_exception);
2268 args=(double *) RelinquishMagickMemory(args);
2271 if (LocaleCompare("draw",option+1) == 0)
2273 (void) CloneString(&_draw_info->primitive,arg1);
2274 (void) DrawImage(_image,_draw_info,_exception);
2275 (void) CloneString(&_draw_info->primitive,(char *) NULL);
2278 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2282 if (LocaleCompare("edge",option+1) == 0)
2284 flags=ParseGeometry(arg1,&geometry_info);
2285 if ((flags & (RhoValue|SigmaValue)) == 0)
2286 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2287 new_image=EdgeImage(_image,geometry_info.rho,_exception);
2290 if (LocaleCompare("emboss",option+1) == 0)
2292 flags=ParseGeometry(arg1,&geometry_info);
2293 if ((flags & (RhoValue|SigmaValue)) == 0)
2294 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2295 if ((flags & SigmaValue) == 0)
2296 geometry_info.sigma=1.0;
2297 new_image=EmbossImage(_image,geometry_info.rho,
2298 geometry_info.sigma,_exception);
2301 if (LocaleCompare("encipher",option+1) == 0)
2303 /* Note: arguments do not have percent escapes expanded */
2307 passkey=FileToStringInfo(arg1,~0UL,_exception);
2308 if (passkey != (StringInfo *) NULL)
2310 (void) PasskeyEncipherImage(_image,passkey,_exception);
2311 passkey=DestroyStringInfo(passkey);
2315 if (LocaleCompare("enhance",option+1) == 0)
2317 new_image=EnhanceImage(_image,_exception);
2320 if (LocaleCompare("equalize",option+1) == 0)
2322 (void) EqualizeImage(_image,_exception);
2325 if (LocaleCompare("evaluate",option+1) == 0)
2330 parse = ParseCommandOption(MagickEvaluateOptions,MagickFalse,arg1);
2332 CLIWandExceptArgBreak(OptionError,"UnrecognizedEvaluateOperator",
2334 if (IfMagickFalse(IsGeometry(arg2)))
2335 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
2336 constant=StringToDoubleInterval(arg2,(double) QuantumRange+1.0);
2337 (void) EvaluateImage(_image,(MagickEvaluateOperator)parse,constant,
2341 if (LocaleCompare("extent",option+1) == 0)
2343 if (IfMagickFalse(IsGeometry(arg1)))
2344 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2345 flags=ParseGravityGeometry(_image,arg1,&geometry,_exception);
2346 if (geometry.width == 0)
2347 geometry.width=_image->columns;
2348 if (geometry.height == 0)
2349 geometry.height=_image->rows;
2350 new_image=ExtentImage(_image,&geometry,_exception);
2353 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2357 if (LocaleCompare("flip",option+1) == 0)
2359 new_image=FlipImage(_image,_exception);
2362 if (LocaleCompare("flop",option+1) == 0)
2364 new_image=FlopImage(_image,_exception);
2367 if (LocaleCompare("floodfill",option+1) == 0)
2372 if (IfMagickFalse(IsGeometry(arg1)))
2373 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2374 (void) ParsePageGeometry(_image,arg1,&geometry,_exception);
2375 (void) QueryColorCompliance(arg2,AllCompliance,&target,_exception);
2376 (void) FloodfillPaintImage(_image,_draw_info,&target,geometry.x,
2377 geometry.y,IsPlusOp,_exception);
2380 if (LocaleCompare("frame",option+1) == 0)
2391 value=GetImageOption(_image_info,"compose");
2392 compose=OverCompositeOp; /* use Over not _image->compose */
2393 if (value != (const char *) NULL)
2394 compose=(CompositeOperator) ParseCommandOption(MagickComposeOptions,
2396 if (IfMagickFalse(IsGeometry(arg1)))
2397 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2398 flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
2399 frame_info.width=geometry.width;
2400 frame_info.height=geometry.height;
2401 frame_info.outer_bevel=geometry.x;
2402 frame_info.inner_bevel=geometry.y;
2403 frame_info.x=(ssize_t) frame_info.width;
2404 frame_info.y=(ssize_t) frame_info.height;
2405 frame_info.width=_image->columns+2*frame_info.width;
2406 frame_info.height=_image->rows+2*frame_info.height;
2407 new_image=FrameImage(_image,&frame_info,compose,_exception);
2410 if (LocaleCompare("function",option+1) == 0)
2418 parse=ParseCommandOption(MagickFunctionOptions,MagickFalse,arg1);
2420 CLIWandExceptArgBreak(OptionError,"UnrecognizedFunction",
2422 /* convert argument string into an array of doubles */
2423 args = StringToArrayOfDoubles(arg2,&count,_exception);
2424 if (args == (double *) NULL )
2425 CLIWandExceptArgBreak(OptionError,"InvalidNumberList",option,arg2);
2427 (void) FunctionImage(_image,(MagickFunction)parse,(size_t) count,args,
2429 args=(double *) RelinquishMagickMemory(args);
2432 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2436 if (LocaleCompare("gamma",option+1) == 0)
2441 if (IfMagickFalse(IsGeometry(arg1)))
2442 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2443 constant=StringToDouble(arg1,(char **) NULL);
2445 /* Using Gamma, via a cache */
2447 constant=PerceptibleReciprocal(constant);
2448 (void) GammaImage(_image,constant,_exception);
2450 /* Using Evaluate POW, direct update of values - more accurite */
2452 constant=PerceptibleReciprocal(constant);
2453 (void) EvaluateImage(_image,PowEvaluateOperator,constant,_exception);
2454 _image->gamma*=StringToDouble(arg1,(char **) NULL);
2456 /* Set gamma setting -- Old meaning of "+gamma"
2457 * _image->gamma=StringToDouble(arg1,(char **) NULL);
2461 if (LocaleCompare("gaussian-blur",option+1) == 0)
2463 flags=ParseGeometry(arg1,&geometry_info);
2464 if ((flags & (RhoValue|SigmaValue)) == 0)
2465 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2466 if ((flags & SigmaValue) == 0)
2467 geometry_info.sigma=1.0;
2468 new_image=GaussianBlurImage(_image,geometry_info.rho,
2469 geometry_info.sigma,_exception);
2472 if (LocaleCompare("gaussian",option+1) == 0)
2474 CLIWandWarnReplaced("-gaussian-blur");
2475 (void) CLISimpleOperatorImage(cli_wand,"-gaussian-blur",arg1,NULL,exception);
2477 if (LocaleCompare("geometry",option+1) == 0)
2480 Record Image offset for composition. (A Setting)
2481 Resize last _image. (ListOperator) -- DEPRECIATE
2482 FUTURE: Why if no 'offset' does this resize ALL images?
2483 Also why is the setting recorded in the IMAGE non-sense!
2486 { /* remove the previous composition geometry offset! */
2487 if (_image->geometry != (char *) NULL)
2488 _image->geometry=DestroyString(_image->geometry);
2491 if (IfMagickFalse(IsGeometry(arg1)))
2492 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2493 flags=ParseRegionGeometry(_image,arg1,&geometry,_exception);
2494 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
2495 (void) CloneString(&_image->geometry,arg1);
2497 new_image=ResizeImage(_image,geometry.width,geometry.height,
2498 _image->filter,_exception);
2501 if (LocaleCompare("grayscale",option+1) == 0)
2503 parse=ParseCommandOption(MagickPixelIntensityOptions,
2506 CLIWandExceptArgBreak(OptionError,"UnrecognizedIntensityMethod",
2508 (void) GrayscaleImage(_image,(PixelIntensityMethod) parse,_exception);
2511 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2515 if (LocaleCompare("hough-lines",option+1) == 0)
2517 flags=ParseGeometry(arg1,&geometry_info);
2518 if ((flags & (RhoValue|SigmaValue)) == 0)
2519 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2520 if ((flags & SigmaValue) == 0)
2521 geometry_info.sigma=geometry_info.rho;
2522 if ((flags & XiValue) == 0)
2523 geometry_info.xi=40;
2524 new_image=HoughLineImage(_image,(size_t) geometry_info.rho,
2525 (size_t) geometry_info.sigma,(size_t) geometry_info.xi,_exception);
2528 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2532 if (LocaleCompare("identify",option+1) == 0)
2538 format=GetImageOption(_image_info,"format");
2539 if (format == (char *) NULL)
2541 (void) IdentifyImage(_image,stdout,_image_info->verbose,
2545 text=InterpretImageProperties(_image_info,_image,format,_exception);
2546 if (text == (char *) NULL)
2547 CLIWandExceptionBreak(OptionWarning,"InterpretPropertyFailure",
2549 (void) fputs(text,stdout);
2550 text=DestroyString((char *)text);
2553 if (LocaleCompare("implode",option+1) == 0)
2555 flags=ParseGeometry(arg1,&geometry_info);
2556 if ((flags & RhoValue) == 0)
2557 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2558 new_image=ImplodeImage(_image,geometry_info.rho,_image->interpolate,
2562 if (LocaleCompare("interpolative-resize",option+1) == 0)
2564 /* FUTURE: New to IMv7
2565 Roll into a resize special operator */
2566 if (IfMagickFalse(IsGeometry(arg1)))
2567 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2568 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
2569 new_image=InterpolativeResizeImage(_image,geometry.width,
2570 geometry.height,_image->interpolate,_exception);
2573 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2577 if (LocaleCompare("kuwahara",option+1) == 0)
2580 Edge preserving blur.
2582 flags=ParseGeometry(arg1,&geometry_info);
2583 if ((flags & (RhoValue|SigmaValue)) == 0)
2584 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2585 if ((flags & SigmaValue) == 0)
2586 geometry_info.sigma=geometry_info.rho-0.5;
2587 new_image=KuwaharaImage(_image,geometry_info.rho,geometry_info.sigma,
2591 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2595 if (LocaleCompare("lat",option+1) == 0)
2597 flags=ParseGeometry(arg1,&geometry_info);
2598 if ((flags & (RhoValue|SigmaValue)) == 0)
2599 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2600 if ((flags & SigmaValue) == 0)
2601 geometry_info.sigma=1.0;
2602 if ((flags & PercentValue) != 0)
2603 geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
2604 new_image=AdaptiveThresholdImage(_image,(size_t) geometry_info.rho,
2605 (size_t) geometry_info.sigma,(double) geometry_info.xi,
2609 if (LocaleCompare("level",option+1) == 0)
2619 flags=ParseGeometry(arg1,&geometry_info);
2620 if ((flags & RhoValue) == 0)
2621 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2622 black_point=geometry_info.rho;
2623 white_point=(double) QuantumRange;
2624 if ((flags & SigmaValue) != 0)
2625 white_point=geometry_info.sigma;
2627 if ((flags & XiValue) != 0)
2628 gamma=geometry_info.xi;
2629 if ((flags & PercentValue) != 0)
2631 black_point*=(double) (QuantumRange/100.0);
2632 white_point*=(double) (QuantumRange/100.0);
2634 if ((flags & SigmaValue) == 0)
2635 white_point=(double) QuantumRange-black_point;
2636 if (IfPlusOp || ((flags & AspectValue) != 0))
2637 (void) LevelizeImage(_image,black_point,white_point,gamma,_exception);
2639 (void) LevelImage(_image,black_point,white_point,gamma,_exception);
2642 if (LocaleCompare("level-colors",option+1) == 0)
2645 token[MagickPathExtent];
2654 p=(const char *) arg1;
2655 GetMagickToken(p,&p,token); /* get black point color */
2656 if ((isalpha((int) *token) != 0) || ((*token == '#') != 0))
2657 (void) QueryColorCompliance(token,AllCompliance,
2658 &black_point,_exception);
2660 (void) QueryColorCompliance("#000000",AllCompliance,
2661 &black_point,_exception);
2662 if (isalpha((int) token[0]) || (token[0] == '#'))
2663 GetMagickToken(p,&p,token);
2665 white_point=black_point; /* set everything to that color */
2668 if ((isalpha((int) *token) == 0) && ((*token == '#') == 0))
2669 GetMagickToken(p,&p,token); /* Get white point color. */
2670 if ((isalpha((int) *token) != 0) || ((*token == '#') != 0))
2671 (void) QueryColorCompliance(token,AllCompliance,
2672 &white_point,_exception);
2674 (void) QueryColorCompliance("#ffffff",AllCompliance,
2675 &white_point,_exception);
2677 (void) LevelImageColors(_image,&black_point,&white_point,
2678 IsPlusOp,_exception);
2681 if (LocaleCompare("linear-stretch",option+1) == 0)
2690 flags=ParseGeometry(arg1,&geometry_info);
2691 if ((flags & RhoValue) == 0)
2692 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2693 black_point=geometry_info.rho;
2694 white_point=(double) _image->columns*_image->rows;
2695 if ((flags & SigmaValue) != 0)
2696 white_point=geometry_info.sigma;
2697 if ((flags & PercentValue) != 0)
2699 black_point*=(double) _image->columns*_image->rows/100.0;
2700 white_point*=(double) _image->columns*_image->rows/100.0;
2702 if ((flags & SigmaValue) == 0)
2703 white_point=(double) _image->columns*_image->rows-
2705 (void) LinearStretchImage(_image,black_point,white_point,_exception);
2708 if (LocaleCompare("liquid-rescale",option+1) == 0)
2710 /* FUTURE: Roll into a resize special operator */
2711 if (IfMagickFalse(IsGeometry(arg1)))
2712 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2713 flags=ParseRegionGeometry(_image,arg1,&geometry,_exception);
2714 if ((flags & XValue) == 0)
2716 if ((flags & YValue) == 0)
2718 new_image=LiquidRescaleImage(_image,geometry.width,
2719 geometry.height,1.0*geometry.x,1.0*geometry.y,_exception);
2722 if (LocaleCompare("local-contrast",option+1) == 0)
2727 flags=ParseGeometry(arg1,&geometry_info);
2728 if ((flags & RhoValue) == 0)
2729 geometry_info.rho=10;
2730 if ((flags & SigmaValue) == 0)
2731 geometry_info.sigma=12.5;
2732 if (((flags & RhoValue) == 0) || ((flags & PercentValue) != 0))
2733 geometry_info.rho*=MagickMax(_image->columns,_image->rows)/100.0;
2734 new_image=LocalContrastImage(_image,geometry_info.rho,
2735 geometry_info.sigma,exception);
2738 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2742 if (LocaleCompare("magnify",option+1) == 0)
2744 new_image=MagnifyImage(_image,_exception);
2747 if (LocaleCompare("map",option+1) == 0)
2749 CLIWandWarnReplaced("-remap");
2750 (void) CLISimpleOperatorImage(cli_wand,"-remap",NULL,NULL,exception);
2753 if (LocaleCompare("mask",option+1) == 0)
2755 CLIWandWarnReplaced("-read-mask");
2756 (void) CLISimpleOperatorImage(cli_wand,"-read-mask",NULL,NULL,
2760 if (LocaleCompare("matte",option+1) == 0)
2762 CLIWandWarnReplaced(IfNormalOp?"-alpha Set":"-alpha Off");
2763 (void) SetImageAlphaChannel(_image,IfNormalOp ? SetAlphaChannel :
2764 DeactivateAlphaChannel, _exception);
2767 if (LocaleCompare("mean-shift",option+1) == 0)
2769 flags=ParseGeometry(arg1,&geometry_info);
2770 if ((flags & (RhoValue|SigmaValue)) == 0)
2771 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2772 if ((flags & SigmaValue) == 0)
2773 geometry_info.sigma=1.0;
2774 if ((flags & XiValue) == 0)
2775 geometry_info.xi=0.10*QuantumRange;
2776 if ((flags & PercentValue) != 0)
2777 geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
2778 new_image=MeanShiftImage(_image,(size_t) geometry_info.rho,
2779 (size_t) geometry_info.sigma,geometry_info.xi,_exception);
2782 if (LocaleCompare("median",option+1) == 0)
2784 CLIWandWarnReplaced("-statistic Median");
2785 (void) CLISimpleOperatorImage(cli_wand,"-statistic","Median",arg1,exception);
2788 if (LocaleCompare("mode",option+1) == 0)
2790 /* FUTURE: note this is also a special "montage" option */
2791 CLIWandWarnReplaced("-statistic Mode");
2792 (void) CLISimpleOperatorImage(cli_wand,"-statistic","Mode",arg1,exception);
2795 if (LocaleCompare("modulate",option+1) == 0)
2797 if (IfMagickFalse(IsGeometry(arg1)))
2798 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2799 (void) ModulateImage(_image,arg1,_exception);
2802 if (LocaleCompare("monitor",option+1) == 0)
2804 (void) SetImageProgressMonitor(_image, IfNormalOp ? MonitorProgress :
2805 (MagickProgressMonitor) NULL,(void *) NULL);
2808 if (LocaleCompare("monochrome",option+1) == 0)
2810 (void) SetImageType(_image,BilevelType,_exception);
2813 if (LocaleCompare("morphology",option+1) == 0)
2816 token[MagickPathExtent];
2828 GetMagickToken(p,&p,token);
2829 parse=ParseCommandOption(MagickMorphologyOptions,MagickFalse,token);
2831 CLIWandExceptArgBreak(OptionError,"UnrecognizedFunction",option,
2834 GetMagickToken(p,&p,token);
2835 if ((*p == ':') || (*p == ','))
2836 GetMagickToken(p,&p,token);
2838 iterations=(ssize_t) StringToLong(p);
2839 kernel=AcquireKernelInfo(arg2,exception);
2840 if (kernel == (KernelInfo *) NULL)
2841 CLIWandExceptArgBreak(OptionError,"UnabletoParseKernel",option,arg2);
2842 new_image=MorphologyImage(_image,(MorphologyMethod)parse,iterations,
2844 kernel=DestroyKernelInfo(kernel);
2847 if (LocaleCompare("motion-blur",option+1) == 0)
2849 flags=ParseGeometry(arg1,&geometry_info);
2850 if ((flags & (RhoValue|SigmaValue)) == 0)
2851 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2852 if ((flags & SigmaValue) == 0)
2853 geometry_info.sigma=1.0;
2854 new_image=MotionBlurImage(_image,geometry_info.rho,geometry_info.sigma,
2855 geometry_info.xi,_exception);
2858 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2862 if (LocaleCompare("negate",option+1) == 0)
2864 (void) NegateImage(_image, IsPlusOp, _exception);
2867 if (LocaleCompare("noise",option+1) == 0)
2877 CLIWandWarnReplaced("-statistic NonPeak");
2878 (void) CLISimpleOperatorImage(cli_wand,"-statistic","NonPeak",arg1,exception);
2881 parse=ParseCommandOption(MagickNoiseOptions,MagickFalse,arg1);
2883 CLIWandExceptArgBreak(OptionError,"UnrecognizedNoiseType",
2886 value=GetImageOption(_image_info,"attenuate");
2887 if (value != (const char *) NULL)
2888 attenuate=StringToDouble(value,(char **) NULL);
2889 new_image=AddNoiseImage(_image,(NoiseType)parse,attenuate,
2893 if (LocaleCompare("normalize",option+1) == 0)
2895 (void) NormalizeImage(_image,_exception);
2898 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2902 if (LocaleCompare("opaque",option+1) == 0)
2907 (void) QueryColorCompliance(arg1,AllCompliance,&target,_exception);
2908 (void) OpaquePaintImage(_image,&target,&_draw_info->fill,IsPlusOp,
2912 if (LocaleCompare("ordered-dither",option+1) == 0)
2914 (void) OrderedPosterizeImage(_image,arg1,_exception);
2917 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2921 if (LocaleCompare("paint",option+1) == 0)
2923 flags=ParseGeometry(arg1,&geometry_info);
2924 if ((flags & (RhoValue|SigmaValue)) == 0)
2925 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2926 new_image=OilPaintImage(_image,geometry_info.rho,geometry_info.sigma,
2930 if (LocaleCompare("perceptible",option+1) == 0)
2932 (void) PerceptibleImage(_image,StringToDouble(arg1,(char **) NULL),
2936 if (LocaleCompare("polaroid",option+1) == 0)
2948 random_info=AcquireRandomInfo();
2949 angle=22.5*(GetPseudoRandomValue(random_info)-0.5);
2950 random_info=DestroyRandomInfo(random_info);
2953 flags=ParseGeometry(arg1,&geometry_info);
2954 if ((flags & RhoValue) == 0)
2955 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2956 angle=geometry_info.rho;
2958 caption=GetImageProperty(_image,"caption",_exception);
2959 new_image=PolaroidImage(_image,_draw_info,caption,angle,
2960 _image->interpolate,_exception);
2963 if (LocaleCompare("posterize",option+1) == 0)
2965 flags=ParseGeometry(arg1,&geometry_info);
2966 if ((flags & RhoValue) == 0)
2967 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2968 (void) PosterizeImage(_image,(size_t) geometry_info.rho,
2969 _quantize_info->dither_method,_exception);
2972 if (LocaleCompare("preview",option+1) == 0)
2974 /* FUTURE: should be a 'Genesis' option?
2975 Option however is also in WandSettingOptionInfo()
2978 parse=ParseCommandOption(MagickPreviewOptions, MagickFalse,arg1);
2980 CLIWandExceptArgBreak(OptionError,"UnrecognizedPreviewType",
2982 new_image=PreviewImage(_image,(PreviewType)parse,_exception);
2985 if (LocaleCompare("profile",option+1) == 0)
2987 /* Note: arguments do not have percent escapes expanded */
3001 { /* Remove a profile from the _image. */
3002 (void) ProfileImage(_image,arg1,(const unsigned char *)
3006 /* Associate a profile with the _image. */
3007 profile_info=CloneImageInfo(_image_info);
3008 profile=GetImageProfile(_image,"iptc");
3009 if (profile != (StringInfo *) NULL)
3010 profile_info->profile=(void *) CloneStringInfo(profile);
3011 profile_image=GetImageCache(profile_info,arg1,_exception);
3012 profile_info=DestroyImageInfo(profile_info);
3013 if (profile_image == (Image *) NULL)
3018 profile_info=CloneImageInfo(_image_info);
3019 (void) CopyMagickString(profile_info->filename,arg1,
3021 profile=FileToStringInfo(profile_info->filename,~0UL,_exception);
3022 if (profile != (StringInfo *) NULL)
3024 (void) ProfileImage(_image,profile_info->magick,
3025 GetStringInfoDatum(profile),(size_t)
3026 GetStringInfoLength(profile),_exception);
3027 profile=DestroyStringInfo(profile);
3029 profile_info=DestroyImageInfo(profile_info);
3032 ResetImageProfileIterator(profile_image);
3033 name=GetNextImageProfile(profile_image);
3034 while (name != (const char *) NULL)
3036 profile=GetImageProfile(profile_image,name);
3037 if (profile != (StringInfo *) NULL)
3038 (void) ProfileImage(_image,name,GetStringInfoDatum(profile),
3039 (size_t) GetStringInfoLength(profile),_exception);
3040 name=GetNextImageProfile(profile_image);
3042 profile_image=DestroyImage(profile_image);
3045 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
3049 if (LocaleCompare("rotational-blur",option+1) == 0)
3051 flags=ParseGeometry(arg1,&geometry_info);
3052 if ((flags & RhoValue) == 0)
3053 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3054 new_image=RotationalBlurImage(_image,geometry_info.rho,_exception);
3057 if (LocaleCompare("raise",option+1) == 0)
3059 if (IfMagickFalse(IsGeometry(arg1)))
3060 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3061 flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
3062 (void) RaiseImage(_image,&geometry,IsNormalOp,_exception);
3065 if (LocaleCompare("random-threshold",option+1) == 0)
3067 if (IfMagickFalse(IsGeometry(arg1)))
3068 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3069 (void) RandomThresholdImage(_image,arg1,_exception);
3072 if (LocaleCompare("read-mask",option+1) == 0)
3074 /* Note: arguments do not have percent escapes expanded */
3079 { /* Remove a mask. */
3080 (void) SetImageMask(_image,ReadPixelMask,(Image *) NULL,
3084 /* Set the image mask. */
3085 mask=GetImageCache(_image_info,arg1,_exception);
3086 if (mask == (Image *) NULL)
3088 (void) SetImageMask(_image,ReadPixelMask,mask,_exception);
3089 mask=DestroyImage(mask);
3092 if (LocaleCompare("recolor",option+1) == 0)
3094 CLIWandWarnReplaced("-color-matrix");
3095 (void) CLISimpleOperatorImage(cli_wand,"-color-matrix",arg1,NULL,exception);
3097 if (LocaleCompare("remap",option+1) == 0)
3099 /* Note: arguments do not have percent escapes expanded */
3103 remap_image=GetImageCache(_image_info,arg1,_exception);
3104 if (remap_image == (Image *) NULL)
3106 (void) RemapImage(_quantize_info,_image,remap_image,_exception);
3107 remap_image=DestroyImage(remap_image);
3110 if (LocaleCompare("repage",option+1) == 0)
3114 if (IfMagickFalse(IsGeometry(arg1)))
3115 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,
3117 (void) ResetImagePage(_image,arg1);
3120 (void) ParseAbsoluteGeometry("0x0+0+0",&_image->page);
3123 if (LocaleCompare("resample",option+1) == 0)
3125 /* FUTURE: Roll into a resize special operation */
3126 flags=ParseGeometry(arg1,&geometry_info);
3127 if ((flags & (RhoValue|SigmaValue)) == 0)
3128 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3129 if ((flags & SigmaValue) == 0)
3130 geometry_info.sigma=geometry_info.rho;
3131 new_image=ResampleImage(_image,geometry_info.rho,
3132 geometry_info.sigma,_image->filter,_exception);
3135 if (LocaleCompare("resize",option+1) == 0)
3137 if (IfMagickFalse(IsGeometry(arg1)))
3138 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3139 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
3140 new_image=ResizeImage(_image,geometry.width,geometry.height,
3141 _image->filter,_exception);
3144 if (LocaleCompare("roll",option+1) == 0)
3146 if (IfMagickFalse(IsGeometry(arg1)))
3147 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3148 (void) ParsePageGeometry(_image,arg1,&geometry,_exception);
3149 new_image=RollImage(_image,geometry.x,geometry.y,_exception);
3152 if (LocaleCompare("rotate",option+1) == 0)
3154 flags=ParseGeometry(arg1,&geometry_info);
3155 if ((flags & RhoValue) == 0)
3156 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3157 if ((flags & GreaterValue) != 0 && (_image->columns <= _image->rows))
3159 if ((flags & LessValue) != 0 && (_image->columns >= _image->rows))
3161 new_image=RotateImage(_image,geometry_info.rho,_exception);
3164 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
3168 if (LocaleCompare("sample",option+1) == 0)
3170 /* FUTURE: Roll into a resize special operator */
3171 if (IfMagickFalse(IsGeometry(arg1)))
3172 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3173 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
3174 new_image=SampleImage(_image,geometry.width,geometry.height,
3178 if (LocaleCompare("scale",option+1) == 0)
3180 /* FUTURE: Roll into a resize special operator */
3181 if (IfMagickFalse(IsGeometry(arg1)))
3182 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3183 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
3184 new_image=ScaleImage(_image,geometry.width,geometry.height,
3188 if (LocaleCompare("segment",option+1) == 0)
3190 flags=ParseGeometry(arg1,&geometry_info);
3191 if ((flags & (RhoValue|SigmaValue)) == 0)
3192 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3193 if ((flags & SigmaValue) == 0)
3194 geometry_info.sigma=1.0;
3195 (void) SegmentImage(_image,_image->colorspace,
3196 _image_info->verbose,geometry_info.rho,geometry_info.sigma,
3200 if (LocaleCompare("selective-blur",option+1) == 0)
3202 flags=ParseGeometry(arg1,&geometry_info);
3203 if ((flags & (RhoValue|SigmaValue)) == 0)
3204 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3205 if ((flags & SigmaValue) == 0)
3206 geometry_info.sigma=1.0;
3207 if ((flags & PercentValue) != 0)
3208 geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
3209 new_image=SelectiveBlurImage(_image,geometry_info.rho,
3210 geometry_info.sigma,geometry_info.xi,_exception);
3213 if (LocaleCompare("separate",option+1) == 0)
3215 /* WARNING: This can generate multiple images! */
3216 /* FUTURE - this may be replaced by a "-channel" method */
3217 new_image=SeparateImages(_image,_exception);
3220 if (LocaleCompare("sepia-tone",option+1) == 0)
3222 if (IfMagickFalse(IsGeometry(arg1)))
3223 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3224 new_image=SepiaToneImage(_image,StringToDoubleInterval(arg1,
3225 (double) QuantumRange+1.0),_exception);
3228 if (LocaleCompare("shade",option+1) == 0)
3230 flags=ParseGeometry(arg1,&geometry_info);
3231 if (((flags & RhoValue) == 0) || ((flags & SigmaValue) == 0))
3232 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3233 new_image=ShadeImage(_image,IsNormalOp,geometry_info.rho,
3234 geometry_info.sigma,_exception);
3237 if (LocaleCompare("shadow",option+1) == 0)
3239 flags=ParseGeometry(arg1,&geometry_info);
3240 if ((flags & (RhoValue|SigmaValue)) == 0)
3241 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3242 if ((flags & SigmaValue) == 0)
3243 geometry_info.sigma=1.0;
3244 if ((flags & XiValue) == 0)
3245 geometry_info.xi=4.0;
3246 if ((flags & PsiValue) == 0)
3247 geometry_info.psi=4.0;
3248 new_image=ShadowImage(_image,geometry_info.rho,geometry_info.sigma,
3249 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
3250 ceil(geometry_info.psi-0.5),_exception);
3253 if (LocaleCompare("sharpen",option+1) == 0)
3255 flags=ParseGeometry(arg1,&geometry_info);
3256 if ((flags & (RhoValue|SigmaValue)) == 0)
3257 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3258 if ((flags & SigmaValue) == 0)
3259 geometry_info.sigma=1.0;
3260 if ((flags & XiValue) == 0)
3261 geometry_info.xi=0.0;
3262 new_image=SharpenImage(_image,geometry_info.rho,geometry_info.sigma,
3266 if (LocaleCompare("shave",option+1) == 0)
3268 if (IfMagickFalse(IsGeometry(arg1)))
3269 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3270 flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
3271 new_image=ShaveImage(_image,&geometry,_exception);
3274 if (LocaleCompare("shear",option+1) == 0)
3276 flags=ParseGeometry(arg1,&geometry_info);
3277 if ((flags & RhoValue) == 0)
3278 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3279 if ((flags & SigmaValue) == 0)
3280 geometry_info.sigma=geometry_info.rho;
3281 new_image=ShearImage(_image,geometry_info.rho,geometry_info.sigma,
3285 if (LocaleCompare("sigmoidal-contrast",option+1) == 0)
3287 flags=ParseGeometry(arg1,&geometry_info);
3288 if ((flags & RhoValue) == 0)
3289 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3290 if ((flags & SigmaValue) == 0)
3291 geometry_info.sigma=(double) QuantumRange/2.0;
3292 if ((flags & PercentValue) != 0)
3293 geometry_info.sigma=(double) QuantumRange*geometry_info.sigma/
3295 (void) SigmoidalContrastImage(_image,IsNormalOp,geometry_info.rho,
3296 geometry_info.sigma,_exception);
3299 if (LocaleCompare("sketch",option+1) == 0)
3301 flags=ParseGeometry(arg1,&geometry_info);
3302 if ((flags & (RhoValue|SigmaValue)) == 0)
3303 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3304 if ((flags & SigmaValue) == 0)
3305 geometry_info.sigma=1.0;
3306 new_image=SketchImage(_image,geometry_info.rho,
3307 geometry_info.sigma,geometry_info.xi,_exception);
3310 if (LocaleCompare("solarize",option+1) == 0)
3312 if (IfMagickFalse(IsGeometry(arg1)))
3313 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3314 (void) SolarizeImage(_image,StringToDoubleInterval(arg1,(double)
3315 QuantumRange+1.0),_exception);
3318 if (LocaleCompare("sparse-color",option+1) == 0)
3320 parse= ParseCommandOption(MagickSparseColorOptions,MagickFalse,arg1);
3322 CLIWandExceptArgBreak(OptionError,"UnrecognizedSparseColorMethod",
3324 new_image=SparseColorOption(_image,(SparseColorMethod)parse,arg2,
3328 if (LocaleCompare("splice",option+1) == 0)
3330 if (IfMagickFalse(IsGeometry(arg1)))
3331 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3332 flags=ParseGravityGeometry(_image,arg1,&geometry,_exception);
3333 new_image=SpliceImage(_image,&geometry,_exception);
3336 if (LocaleCompare("spread",option+1) == 0)
3338 flags=ParseGeometry(arg1,&geometry_info);
3339 if ((flags & RhoValue) == 0)
3340 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
3341 new_image=SpreadImage(_image,_image->interpolate,geometry_info.rho,
3345 if (LocaleCompare("statistic",option+1) == 0)
3347 parse=ParseCommandOption(MagickStatisticOptions,MagickFalse,arg1);
3349 CLIWandExceptArgBreak(OptionError,"UnrecognizedStatisticType",
3351 flags=ParseGeometry(arg2,&geometry_info);
3352 if ((flags & RhoValue) == 0)
3353 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
3354 if ((flags & SigmaValue) == 0)
3355 geometry_info.sigma=geometry_info.rho;
3356 new_image=StatisticImage(_image,(StatisticType)parse,
3357 (size_t) geometry_info.rho,(size_t) geometry_info.sigma,
3361 if (LocaleCompare("strip",option+1) == 0)
3363 (void) StripImage(_image,_exception);
3366 if (LocaleCompare("swirl",option+1) == 0)
3368 flags=ParseGeometry(arg1,&geometry_info);
3369 if ((flags & RhoValue) == 0)
3370 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3371 new_image=SwirlImage(_image,geometry_info.rho,
3372 _image->interpolate,_exception);
3375 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
3379 if (LocaleCompare("threshold",option+1) == 0)
3384 threshold=(double) QuantumRange/2;
3386 if (IfMagickFalse(IsGeometry(arg1)))
3387 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3388 threshold=StringToDoubleInterval(arg1,(double) QuantumRange+1.0);
3390 (void) BilevelImage(_image,threshold,_exception);
3393 if (LocaleCompare("thumbnail",option+1) == 0)
3395 if (IfMagickFalse(IsGeometry(arg1)))
3396 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3397 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
3398 new_image=ThumbnailImage(_image,geometry.width,geometry.height,
3402 if (LocaleCompare("tint",option+1) == 0)
3404 if (IfMagickFalse(IsGeometry(arg1)))
3405 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3406 new_image=TintImage(_image,arg1,&_draw_info->fill,_exception);
3409 if (LocaleCompare("transform",option+1) == 0)
3411 CLIWandWarnReplaced("+distort AffineProjection");
3412 new_image=AffineTransformImage(_image,&_draw_info->affine,_exception);
3415 if (LocaleCompare("transparent",option+1) == 0)
3420 (void) QueryColorCompliance(arg1,AllCompliance,&target,_exception);
3421 (void) TransparentPaintImage(_image,&target,(Quantum)
3422 TransparentAlpha,IsPlusOp,_exception);
3425 if (LocaleCompare("transpose",option+1) == 0)
3427 new_image=TransposeImage(_image,_exception);
3430 if (LocaleCompare("transverse",option+1) == 0)
3432 new_image=TransverseImage(_image,_exception);
3435 if (LocaleCompare("trim",option+1) == 0)
3437 new_image=TrimImage(_image,_exception);
3440 if (LocaleCompare("type",option+1) == 0)
3442 /* Note that "type" setting should have already been defined */
3443 (void) SetImageType(_image,_image_info->type,_exception);
3446 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
3450 if (LocaleCompare("unique",option+1) == 0)
3452 /* FUTURE: move to SyncImageSettings() and AcqireImage()???
3453 Option is not documented, bt appears to be for "identify".
3454 We may need a identify specific verbose!
3457 (void) DeleteImageArtifact(_image,"identify:unique-colors");
3460 (void) SetImageArtifact(_image,"identify:unique-colors","true");
3461 (void) SetImageArtifact(_image,"verbose","true");
3464 if (LocaleCompare("unique-colors",option+1) == 0)
3466 new_image=UniqueImageColors(_image,_exception);
3469 if (LocaleCompare("unsharp",option+1) == 0)
3471 flags=ParseGeometry(arg1,&geometry_info);
3472 if ((flags & (RhoValue|SigmaValue)) == 0)
3473 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3474 if ((flags & SigmaValue) == 0)
3475 geometry_info.sigma=1.0;
3476 if ((flags & XiValue) == 0)
3477 geometry_info.xi=1.0;
3478 if ((flags & PsiValue) == 0)
3479 geometry_info.psi=0.05;
3480 new_image=UnsharpMaskImage(_image,geometry_info.rho,
3481 geometry_info.sigma,geometry_info.xi,geometry_info.psi,_exception);
3484 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
3488 if (LocaleCompare("verbose",option+1) == 0)
3490 /* FUTURE: move to SyncImageSettings() and AcquireImage()???
3491 three places! ImageArtifact ImageOption _image_info->verbose
3492 Some how new images also get this artifact!
3494 (void) SetImageArtifact(_image,option+1,
3495 IfNormalOp ? "true" : "false" );
3498 if (LocaleCompare("vignette",option+1) == 0)
3500 flags=ParseGeometry(arg1,&geometry_info);
3501 if ((flags & (RhoValue|SigmaValue)) == 0)
3502 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3503 if ((flags & SigmaValue) == 0)
3504 geometry_info.sigma=1.0;
3505 if ((flags & XiValue) == 0)
3506 geometry_info.xi=0.1*_image->columns;
3507 if ((flags & PsiValue) == 0)
3508 geometry_info.psi=0.1*_image->rows;
3509 if ((flags & PercentValue) != 0)
3511 geometry_info.xi*=(double) _image->columns/100.0;
3512 geometry_info.psi*=(double) _image->rows/100.0;
3514 new_image=VignetteImage(_image,geometry_info.rho,geometry_info.sigma,
3515 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
3516 ceil(geometry_info.psi-0.5),_exception);
3519 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
3523 if (LocaleCompare("wave",option+1) == 0)
3525 flags=ParseGeometry(arg1,&geometry_info);
3526 if ((flags & (RhoValue|SigmaValue)) == 0)
3527 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3528 if ((flags & SigmaValue) == 0)
3529 geometry_info.sigma=1.0;
3530 new_image=WaveImage(_image,geometry_info.rho,geometry_info.sigma,
3531 _image->interpolate,_exception);
3534 if (LocaleCompare("white-threshold",option+1) == 0)
3536 if (IfMagickFalse(IsGeometry(arg1)))
3537 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3538 (void) WhiteThresholdImage(_image,arg1,_exception);
3541 if (LocaleCompare("write-mask",option+1) == 0)
3543 /* Note: arguments do not have percent escapes expanded */
3548 { /* Remove a mask. */
3549 (void) SetImageMask(_image,WritePixelMask,(Image *) NULL,
3553 /* Set the image mask. */
3554 mask=GetImageCache(_image_info,arg1,_exception);
3555 if (mask == (Image *) NULL)
3557 (void) SetImageMask(_image,WritePixelMask,mask,_exception);
3558 mask=DestroyImage(mask);
3561 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
3564 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
3566 /* clean up percent escape interpreted strings */
3568 arg1=DestroyString((char *)arg1);
3570 arg2=DestroyString((char *)arg2);
3572 /* Replace current image with any image that was generated
3573 and set image point to last image (so image->next is correct) */
3574 if (new_image != (Image *) NULL)
3575 ReplaceImageInListReturnLast(&_image,new_image);
3580 #undef _quantize_info
3589 WandPrivate MagickBooleanType CLISimpleOperatorImages(MagickCLI *cli_wand,
3590 const char *option,const char *arg1,const char *arg2,ExceptionInfo *exception)
3592 #if !USE_WAND_METHODS
3598 assert(cli_wand != (MagickCLI *) NULL);
3599 assert(cli_wand->signature == MagickWandSignature);
3600 assert(cli_wand->wand.signature == MagickWandSignature);
3601 assert(cli_wand->wand.images != (Image *) NULL); /* images must be present */
3603 if (IfMagickTrue(cli_wand->wand.debug))
3604 (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(),
3605 "- Simple Operator: %s \"%s\" \"%s\"", option,arg1,arg2);
3607 #if !USE_WAND_METHODS
3608 /* FUTURE add appropriate tracing */
3610 n=GetImageListLength(cli_wand->wand.images);
3611 cli_wand->wand.images=GetFirstImageInList(cli_wand->wand.images);
3614 CLISimpleOperatorImage(cli_wand, option, arg1, arg2,exception);
3615 if ( cli_wand->wand.images->next == (Image *) NULL )
3617 cli_wand->wand.images=cli_wand->wand.images->next;
3620 cli_wand->wand.images=GetFirstImageInList(cli_wand->wand.images);
3622 MagickResetIterator(&cli_wand->wand);
3623 while ( IfMagickTrue(MagickNextImage(&cli_wand->wand)) )
3624 (void) CLISimpleOperatorImage(cli_wand, option, arg1, arg2,exception);
3625 MagickResetIterator(&cli_wand->wand);
3631 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3635 + C L I L i s t O p e r a t o r I m a g e s %
3639 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3641 % CLIListOperatorImages() applies a single operation that is apply to the
3642 % entire image list as a whole. The result is often a complete replacment
3643 % of the image list with a completely new list, or with just a single image
3646 % The format of the MogrifyImage method is:
3648 % MagickBooleanType CLIListOperatorImages(MagickCLI *cli_wand,
3649 % const char *option,const char *arg1,const char *arg2)
3651 % A description of each parameter follows:
3653 % o cli_wand: structure holding settings to be applied
3655 % o option: The option string for the operation
3657 % o arg1, arg2: optional argument strings to the operation
3658 % arg2 is currently not used
3661 WandPrivate MagickBooleanType CLIListOperatorImages(MagickCLI *cli_wand,
3662 const char *option,const char *arg1n,const char *arg2n)
3664 const char /* percent escaped versions of the args */
3677 #define _image_info (cli_wand->wand.image_info)
3678 #define _images (cli_wand->wand.images)
3679 #define _exception (cli_wand->wand.exception)
3680 #define _draw_info (cli_wand->draw_info)
3681 #define _quantize_info (cli_wand->quantize_info)
3682 #define _process_flags (cli_wand->process_flags)
3683 #define _option_type ((CommandOptionFlags) cli_wand->command->flags)
3684 #define IfNormalOp (*option=='-')
3685 #define IfPlusOp (*option!='-')
3686 #define IsNormalOp IfNormalOp ? MagickTrue : MagickFalse
3688 assert(cli_wand != (MagickCLI *) NULL);
3689 assert(cli_wand->signature == MagickWandSignature);
3690 assert(cli_wand->wand.signature == MagickWandSignature);
3691 assert(_images != (Image *) NULL); /* _images must be present */
3693 if (IfMagickTrue(cli_wand->wand.debug))
3694 (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(),
3695 "- List Operator: %s \"%s\" \"%s\"", option,
3696 arg1n == (const char *) NULL ? "null" : arg1n,
3697 arg2n == (const char *) NULL ? "null" : arg2n);
3702 /* Interpret Percent Escapes in Arguments - using first image */
3703 if ( (((_process_flags & ProcessInterpretProperities) != 0 )
3704 || ((_option_type & AlwaysInterpretArgsFlag) != 0)
3705 ) && ((_option_type & NeverInterpretArgsFlag) == 0) ) {
3706 /* Interpret Percent escapes in argument 1 */
3707 if (arg1n != (char *) NULL) {
3708 arg1=InterpretImageProperties(_image_info,_images,arg1n,_exception);
3709 if (arg1 == (char *) NULL) {
3710 CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
3711 arg1=arg1n; /* use the given argument as is */
3714 if (arg2n != (char *) NULL) {
3715 arg2=InterpretImageProperties(_image_info,_images,arg2n,_exception);
3716 if (arg2 == (char *) NULL) {
3717 CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
3718 arg2=arg2n; /* use the given argument as is */
3722 #undef _process_flags
3726 new_images=NewImageList();
3728 switch (*(option+1))
3732 if (LocaleCompare("append",option+1) == 0)
3734 new_images=AppendImages(_images,IsNormalOp,_exception);
3737 if (LocaleCompare("average",option+1) == 0)
3739 CLIWandWarnReplaced("-evaluate-sequence Mean");
3740 (void) CLIListOperatorImages(cli_wand,"-evaluate-sequence","Mean",NULL);
3743 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
3747 if (LocaleCompare("channel-fx",option+1) == 0)
3749 new_images=ChannelFxImage(_images,arg1,_exception);
3752 if (LocaleCompare("clut",option+1) == 0)
3757 /* FUTURE - make this a compose option, and thus can be used
3758 with layers compose or even compose last image over all other
3761 new_images=RemoveFirstImageFromList(&_images);
3762 clut_image=RemoveLastImageFromList(&_images);
3763 /* FUTURE - produce Exception, rather than silent fail */
3764 if (clut_image == (Image *) NULL)
3766 (void) ClutImage(new_images,clut_image,new_images->interpolate,
3768 clut_image=DestroyImage(clut_image);
3771 if (LocaleCompare("coalesce",option+1) == 0)
3773 new_images=CoalesceImages(_images,_exception);
3776 if (LocaleCompare("combine",option+1) == 0)
3778 parse=(ssize_t) _images->colorspace;
3780 parse=ParseCommandOption(MagickColorspaceOptions,MagickFalse,arg1);
3782 CLIWandExceptArgBreak(OptionError,"UnrecognizedColorspace",option,
3784 new_images=CombineImages(_images,(ColorspaceType) parse,_exception);
3787 if (LocaleCompare("compare",option+1) == 0)
3800 Mathematically and visually annotate the difference between an
3801 image and its reconstruction.
3803 image=RemoveFirstImageFromList(&_images);
3804 reconstruct_image=RemoveFirstImageFromList(&_images);
3805 /* FUTURE - produce Exception, rather than silent fail */
3806 if (reconstruct_image == (Image *) NULL)
3808 metric=UndefinedErrorMetric;
3809 option=GetImageOption(_image_info,"metric");
3810 if (option != (const char *) NULL)
3811 metric=(MetricType) ParseCommandOption(MagickMetricOptions,
3812 MagickFalse,option);
3813 new_images=CompareImages(image,reconstruct_image,metric,&distortion,
3816 reconstruct_image=DestroyImage(reconstruct_image);
3817 image=DestroyImage(image);
3820 if (LocaleCompare("complex",option+1) == 0)
3822 parse=ParseCommandOption(MagickComplexOptions,MagickFalse,arg1);
3824 CLIWandExceptArgBreak(OptionError,"UnrecognizedEvaluateOperator",
3826 new_images=ComplexImages(_images,(ComplexOperator) parse,_exception);
3829 if (LocaleCompare("composite",option+1) == 0)
3847 /* Compose value from "-compose" option only */
3848 value=GetImageOption(_image_info,"compose");
3849 if (value == (const char *) NULL)
3850 compose=OverCompositeOp; /* use Over not source_image->compose */
3852 compose=(CompositeOperator) ParseCommandOption(MagickComposeOptions,
3855 /* Get "clip-to-self" expert setting (false is normal) */
3856 value=GetImageOption(_image_info,"compose:clip-to-self");
3857 if (value == (const char *) NULL)
3858 clip_to_self=MagickTrue;
3860 clip_to_self=IsStringTrue(GetImageOption(_image_info,
3861 "compose:clip-to-self")); /* if this is true */
3862 value=GetImageOption(_image_info,"compose:outside-overlay");
3863 if (value != (const char *) NULL) { /* or this false */
3864 /* FUTURE: depreciate warning for "compose:outside-overlay"*/
3865 clip_to_self=IsStringFalse(value);
3868 new_images=RemoveFirstImageFromList(&_images);
3869 source_image=RemoveFirstImageFromList(&_images);
3870 if (source_image == (Image *) NULL)
3871 break; /* FUTURE - produce Exception, rather than silent fail */
3873 /* FUTURE - this should not be here! - should be part of -geometry */
3874 (void) TransformImage(&source_image,(char *) NULL,
3875 source_image->geometry,_exception);
3876 SetGeometry(source_image,&geometry);
3877 (void) ParseAbsoluteGeometry(source_image->geometry,&geometry);
3878 GravityAdjustGeometry(new_images->columns,new_images->rows,
3879 new_images->gravity, &geometry);
3880 mask_image=RemoveFirstImageFromList(&_images);
3881 if (mask_image == (Image *) NULL)
3882 status&=CompositeImage(new_images,source_image,compose,clip_to_self,
3883 geometry.x,geometry.y,_exception);
3886 if ((compose == DisplaceCompositeOp) ||
3887 (compose == DistortCompositeOp))
3889 status&=CompositeImage(source_image,mask_image,
3890 CopyGreenCompositeOp,MagickTrue,0,0,_exception);
3891 status&=CompositeImage(new_images,source_image,compose,
3892 clip_to_self,geometry.x,geometry.y,_exception);
3899 clone_image=CloneImage(new_images,0,0,MagickTrue,_exception);
3900 if (clone_image == (Image *) NULL)
3902 status&=CompositeImage(new_images,source_image,compose,
3903 clip_to_self,geometry.x,geometry.y,_exception);
3904 status&=CompositeImage(new_images,mask_image,
3905 CopyAlphaCompositeOp,MagickTrue,0,0,_exception);
3906 status&=CompositeImage(clone_image,new_images,OverCompositeOp,
3907 clip_to_self,0,0,_exception);
3908 new_images=DestroyImage(new_images);
3909 new_images=clone_image;
3911 mask_image=DestroyImage(mask_image);
3913 source_image=DestroyImage(source_image);
3916 if (LocaleCompare("copy",option+1) == 0)
3930 if (IfMagickFalse(IsGeometry(arg1)))
3931 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3932 if (IfMagickFalse(IsGeometry(arg2)))
3933 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3934 (void) ParsePageGeometry(_images,arg2,&geometry,_exception);
3935 offset.x=geometry.x;
3936 offset.y=geometry.y;
3937 source_image=_images;
3938 if (source_image->next != (Image *) NULL)
3939 source_image=source_image->next;
3940 (void) ParsePageGeometry(source_image,arg1,&geometry,_exception);
3941 (void) CopyImagePixels(_images,source_image,&geometry,&offset,
3945 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
3949 if (LocaleCompare("deconstruct",option+1) == 0)
3951 CLIWandWarnReplaced("-layer CompareAny");
3952 (void) CLIListOperatorImages(cli_wand,"-layer","CompareAny",NULL);
3955 if (LocaleCompare("delete",option+1) == 0)
3958 DeleteImages(&_images,arg1,_exception);
3960 DeleteImages(&_images,"-1",_exception);
3963 if (LocaleCompare("duplicate",option+1) == 0)
3973 if (IfMagickFalse(IsGeometry(arg1)))
3974 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,
3976 number_duplicates=(size_t) StringToLong(arg1);
3978 if (p == (const char *) NULL)
3979 new_images=DuplicateImages(_images,number_duplicates,"-1",
3982 new_images=DuplicateImages(_images,number_duplicates,p,
3986 new_images=DuplicateImages(_images,1,"-1",_exception);
3987 AppendImageToList(&_images, new_images);
3988 new_images=(Image *) NULL;
3991 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
3995 if (LocaleCompare("evaluate-sequence",option+1) == 0)
3997 parse=ParseCommandOption(MagickEvaluateOptions,MagickFalse,arg1);
3999 CLIWandExceptArgBreak(OptionError,"UnrecognizedEvaluateOperator",
4001 new_images=EvaluateImages(_images,(MagickEvaluateOperator)parse,
4005 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4009 if (LocaleCompare("fft",option+1) == 0)
4011 new_images=ForwardFourierTransformImage(_images,IsNormalOp,
4015 if (LocaleCompare("flatten",option+1) == 0)
4017 /* REDIRECTED to use -layers flatten instead */
4018 (void) CLIListOperatorImages(cli_wand,"-layers",option+1,NULL);
4021 if (LocaleCompare("fx",option+1) == 0)
4023 new_images=FxImage(_images,arg1,_exception);
4026 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4030 if (LocaleCompare("hald-clut",option+1) == 0)
4032 /* FUTURE - make this a compose option (and thus layers compose )
4033 or perhaps compose last image over all other _images.
4038 new_images=RemoveFirstImageFromList(&_images);
4039 hald_image=RemoveLastImageFromList(&_images);
4040 if (hald_image == (Image *) NULL)
4042 (void) HaldClutImage(new_images,hald_image,_exception);
4043 hald_image=DestroyImage(hald_image);
4046 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4050 if (LocaleCompare("ift",option+1) == 0)
4056 magnitude_image=RemoveFirstImageFromList(&_images);
4057 phase_image=RemoveFirstImageFromList(&_images);
4058 /* FUTURE - produce Exception, rather than silent fail */
4059 if (phase_image == (Image *) NULL)
4061 new_images=InverseFourierTransformImage(magnitude_image,phase_image,
4062 IsNormalOp,_exception);
4063 magnitude_image=DestroyImage(magnitude_image);
4064 phase_image=DestroyImage(phase_image);
4067 if (LocaleCompare("insert",option+1) == 0)
4076 if (IfNormalOp && IfMagickFalse(IsGeometry(arg1)))
4077 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
4079 insert_image=RemoveLastImageFromList(&_images);
4081 index=(ssize_t) StringToLong(arg1);
4082 index_image=insert_image;
4084 PrependImageToList(&_images,insert_image);
4085 else if (index == (ssize_t) GetImageListLength(_images))
4086 AppendImageToList(&_images,insert_image);
4089 index_image=GetImageFromList(_images,index-1);
4090 if (index_image == (Image *) NULL)
4091 CLIWandExceptArgBreak(OptionError,"NoSuchImage",option,arg1);
4092 InsertImageInList(&index_image,insert_image);
4094 _images=GetFirstImageInList(index_image);
4097 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4101 if (LocaleCompare("layers",option+1) == 0)
4103 parse=ParseCommandOption(MagickLayerOptions,MagickFalse,arg1);
4105 CLIWandExceptArgBreak(OptionError,"UnrecognizedLayerMethod",
4107 switch ((LayerMethod) parse)
4111 new_images=CoalesceImages(_images,_exception);
4114 case CompareAnyLayer:
4115 case CompareClearLayer:
4116 case CompareOverlayLayer:
4119 new_images=CompareImagesLayers(_images,(LayerMethod) parse,
4126 case TrimBoundsLayer:
4128 new_images=MergeImageLayers(_images,(LayerMethod) parse,
4134 new_images=DisposeImages(_images,_exception);
4137 case OptimizeImageLayer:
4139 new_images=OptimizeImageLayers(_images,_exception);
4142 case OptimizePlusLayer:
4144 new_images=OptimizePlusImageLayers(_images,_exception);
4147 case OptimizeTransLayer:
4149 OptimizeImageTransparency(_images,_exception);
4152 case RemoveDupsLayer:
4154 RemoveDuplicateLayers(&_images,_exception);
4157 case RemoveZeroLayer:
4159 RemoveZeroDelayLayers(&_images,_exception);
4163 { /* General Purpose, GIF Animation Optimizer. */
4164 new_images=CoalesceImages(_images,_exception);
4165 if (new_images == (Image *) NULL)
4167 _images=DestroyImageList(_images);
4168 _images=OptimizeImageLayers(new_images,_exception);
4169 if (_images == (Image *) NULL)
4171 new_images=DestroyImageList(new_images);
4172 OptimizeImageTransparency(_images,_exception);
4173 (void) RemapImages(_quantize_info,_images,(Image *) NULL,
4177 case CompositeLayer:
4191 value=GetImageOption(_image_info,"compose");
4192 compose=OverCompositeOp; /* Default to Over */
4193 if (value != (const char *) NULL)
4194 compose=(CompositeOperator) ParseCommandOption(
4195 MagickComposeOptions,MagickFalse,value);
4197 /* Split image sequence at the first 'NULL:' image. */
4199 while (source != (Image *) NULL)
4201 source=GetNextImageInList(source);
4202 if ((source != (Image *) NULL) &&
4203 (LocaleCompare(source->magick,"NULL") == 0))
4206 if (source != (Image *) NULL)
4208 if ((GetPreviousImageInList(source) == (Image *) NULL) ||
4209 (GetNextImageInList(source) == (Image *) NULL))
4210 source=(Image *) NULL;
4212 { /* Separate the two lists, junk the null: image. */
4213 source=SplitImageList(source->previous);
4214 DeleteImageFromList(&source);
4217 if (source == (Image *) NULL)
4219 (void) ThrowMagickException(_exception,GetMagickModule(),
4220 OptionError,"MissingNullSeparator","layers Composite");
4223 /* Adjust offset with gravity and virtual canvas. */
4224 SetGeometry(_images,&geometry);
4225 (void) ParseAbsoluteGeometry(_images->geometry,&geometry);
4226 geometry.width=source->page.width != 0 ?
4227 source->page.width : source->columns;
4228 geometry.height=source->page.height != 0 ?
4229 source->page.height : source->rows;
4230 GravityAdjustGeometry(_images->page.width != 0 ?
4231 _images->page.width : _images->columns,
4232 _images->page.height != 0 ? _images->page.height :
4233 _images->rows,_images->gravity,&geometry);
4235 /* Compose the two image sequences together */
4236 CompositeLayers(_images,compose,source,geometry.x,geometry.y,
4238 source=DestroyImageList(source);
4244 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4248 if (LocaleCompare("map",option+1) == 0)
4250 CLIWandWarnReplaced("+remap");
4251 (void) RemapImages(_quantize_info,_images,(Image *) NULL,_exception);
4254 if (LocaleCompare("metric",option+1) == 0)
4256 if (LocaleCompare("morph",option+1) == 0)
4261 if (IfMagickFalse(IsGeometry(arg1)))
4262 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
4263 morph_image=MorphImages(_images,StringToUnsignedLong(arg1),
4265 if (morph_image == (Image *) NULL)
4267 _images=DestroyImageList(_images);
4268 _images=morph_image;
4271 if (LocaleCompare("mosaic",option+1) == 0)
4273 /* REDIRECTED to use -layers mosaic instead */
4274 (void) CLIListOperatorImages(cli_wand,"-layers",option+1,NULL);
4277 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4281 if (LocaleCompare("poly",option+1) == 0)
4289 /* convert argument string into an array of doubles */
4290 args = StringToArrayOfDoubles(arg1,&count,_exception);
4291 if (args == (double *) NULL )
4292 CLIWandExceptArgBreak(OptionError,"InvalidNumberList",option,arg1);
4293 new_images=PolynomialImage(_images,(size_t) (count >> 1),args,
4295 args=(double *) RelinquishMagickMemory(args);
4298 if (LocaleCompare("process",option+1) == 0)
4300 /* FUTURE: better parsing using ScriptToken() from string ??? */
4308 arguments=StringToArgv(arg1,&number_arguments);
4309 if (arguments == (char **) NULL)
4311 if (strchr(arguments[1],'=') != (char *) NULL)
4332 Support old style syntax, filter="-option arg1".
4334 assert(arg1 != (const char *) NULL);
4335 length=strlen(arg1);
4336 token=(char *) NULL;
4337 if (~length >= (MagickPathExtent-1))
4338 token=(char *) AcquireQuantumMemory(length+MagickPathExtent,
4340 if (token == (char *) NULL)
4344 token_info=AcquireTokenInfo();
4345 status=Tokenizer(token_info,0,token,length,arguments,"","=",
4346 "\"",'\0',&breaker,&next,"e);
4347 token_info=DestroyTokenInfo(token_info);
4353 argv=(&(arguments[next]));
4354 (void) InvokeDynamicImageFilter(token,&_images,1,&argv,
4357 token=DestroyString(token);
4360 (void) SubstituteString(&arguments[1],"-","");
4361 (void) InvokeDynamicImageFilter(arguments[1],&_images,
4362 number_arguments-2,(const char **) arguments+2,_exception);
4363 for (j=0; j < number_arguments; j++)
4364 arguments[j]=DestroyString(arguments[j]);
4365 arguments=(char **) RelinquishMagickMemory(arguments);
4368 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4372 if (LocaleCompare("remap",option+1) == 0)
4374 (void) RemapImages(_quantize_info,_images,(Image *) NULL,_exception);
4377 if (LocaleCompare("reverse",option+1) == 0)
4379 ReverseImageList(&_images);
4382 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4386 if (LocaleCompare("smush",option+1) == 0)
4388 /* FUTURE: this option needs more work to make better */
4392 if (IfMagickFalse(IsGeometry(arg1)))
4393 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
4394 offset=(ssize_t) StringToLong(arg1);
4395 new_images=SmushImages(_images,IsNormalOp,offset,_exception);
4398 if (LocaleCompare("subimage",option+1) == 0)
4416 base_image=GetImageFromList(_images,0);
4417 compare_image=GetImageFromList(_images,1);
4419 /* Comparision Metric */
4420 metric=UndefinedErrorMetric;
4421 value=GetImageOption(_image_info,"metric");
4422 if (value != (const char *) NULL)
4423 metric=(MetricType) ParseCommandOption(MagickMetricOptions,
4426 new_images=SimilarityImage(base_image,compare_image,metric,0.0,
4427 &offset,&similarity,_exception);
4429 if (new_images != (Image *) NULL)
4432 result[MagickPathExtent];
4434 (void) FormatLocaleString(result,MagickPathExtent,"%lf",
4436 (void) SetImageProperty(new_images,"subimage:similarity",result,
4438 (void) FormatLocaleString(result,MagickPathExtent,"%+ld",(long)
4440 (void) SetImageProperty(new_images,"subimage:x",result,
4442 (void) FormatLocaleString(result,MagickPathExtent,"%+ld",(long)
4444 (void) SetImageProperty(new_images,"subimage:y",result,
4446 (void) FormatLocaleString(result,MagickPathExtent,
4447 "%lux%lu%+ld%+ld",(unsigned long) offset.width,(unsigned long)
4448 offset.height,(long) offset.x,(long) offset.y);
4449 (void) SetImageProperty(new_images,"subimage:offset",result,
4454 if (LocaleCompare("swap",option+1) == 0)
4475 flags=ParseGeometry(arg1,&geometry_info);
4476 if ((flags & RhoValue) == 0)
4477 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
4478 index=(ssize_t) geometry_info.rho;
4479 if ((flags & SigmaValue) != 0)
4480 swap_index=(ssize_t) geometry_info.sigma;
4482 p=GetImageFromList(_images,index);
4483 q=GetImageFromList(_images,swap_index);
4484 if ((p == (Image *) NULL) || (q == (Image *) NULL)) {
4486 CLIWandExceptArgBreak(OptionError,"InvalidImageIndex",option,arg1)
4488 CLIWandExceptionBreak(OptionError,"TwoOrMoreImagesRequired",option);
4491 CLIWandExceptArgBreak(OptionError,"InvalidImageIndex",option,arg1);
4492 swap=CloneImage(p,0,0,MagickTrue,_exception);
4493 ReplaceImageInList(&p,CloneImage(q,0,0,MagickTrue,_exception));
4494 ReplaceImageInList(&q,swap);
4495 _images=GetFirstImageInList(q);
4498 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4501 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4504 /* clean up percent escape interpreted strings */
4506 arg1=DestroyString((char *)arg1);
4508 arg2=DestroyString((char *)arg2);
4510 /* if new image list generated, replace existing image list */
4511 if (new_images == (Image *) NULL)
4512 return(status == 0 ? MagickFalse : MagickTrue);
4513 _images=DestroyImageList(_images);
4514 _images=GetFirstImageInList(new_images);
4515 return(status == 0 ? MagickFalse : MagickTrue);
4521 #undef _quantize_info
4528 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4532 + C L I N o I m a g e O p e r a t i o n s %
4536 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4538 % CLINoImageOperator() Applies operations that may not actually need images
4541 % The classic operators of this type is "-read", which actually creates
4542 % images even when no images are present. Or image stack operators, which
4543 % can be applied (push or pop) to an empty image list.
4545 % Note that these operators may involve other special 'option' prefix
4546 % characters other than '-' or '+', namely parenthesis and braces.
4548 % The format of the CLINoImageOption method is:
4550 % void CLINoImageOption(MagickCLI *cli_wand,const char *option,
4551 % const char *arg1, const char *arg2)
4553 % A description of each parameter follows:
4555 % o cli_wand: the main CLI Wand to use. (sometimes not required)
4557 % o option: The special option (with any switch char) to process
4559 % o arg1 & arg2: Argument for option, if required
4560 % Currently arg2 is not used.
4563 WandPrivate void CLINoImageOperator(MagickCLI *cli_wand,
4564 const char *option,const char *arg1n,const char *arg2n)
4566 const char /* percent escaped versions of the args */
4570 #define _image_info (cli_wand->wand.image_info)
4571 #define _images (cli_wand->wand.images)
4572 #define _exception (cli_wand->wand.exception)
4573 #define _process_flags (cli_wand->process_flags)
4574 #define _option_type ((CommandOptionFlags) cli_wand->command->flags)
4575 #define IfNormalOp (*option=='-')
4576 #define IfPlusOp (*option!='-')
4578 assert(cli_wand != (MagickCLI *) NULL);
4579 assert(cli_wand->signature == MagickWandSignature);
4580 assert(cli_wand->wand.signature == MagickWandSignature);
4582 if (IfMagickTrue(cli_wand->wand.debug))
4583 (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(),
4584 "- NoImage Operator: %s \"%s\" \"%s\"", option,
4585 arg1n != (char *) NULL ? arg1n : "",
4586 arg2n != (char *) NULL ? arg2n : "");
4591 /* Interpret Percent Escapes in Arguments - using first image */
4592 if ( (((_process_flags & ProcessInterpretProperities) != 0 )
4593 || ((_option_type & AlwaysInterpretArgsFlag) != 0)
4594 ) && ((_option_type & NeverInterpretArgsFlag) == 0) ) {
4595 /* Interpret Percent escapes in argument 1 */
4596 if (arg1n != (char *) NULL) {
4597 arg1=InterpretImageProperties(_image_info,_images,arg1n,_exception);
4598 if (arg1 == (char *) NULL) {
4599 CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
4600 arg1=arg1n; /* use the given argument as is */
4603 if (arg2n != (char *) NULL) {
4604 arg2=InterpretImageProperties(_image_info,_images,arg2n,_exception);
4605 if (arg2 == (char *) NULL) {
4606 CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
4607 arg2=arg2n; /* use the given argument as is */
4611 #undef _process_flags
4614 do { /* break to exit code */
4616 No-op options (ignore these)
4618 if (LocaleCompare("noop",option+1) == 0) /* zero argument */
4620 if (LocaleCompare("sans",option+1) == 0) /* one argument */
4622 if (LocaleCompare("sans0",option+1) == 0) /* zero argument */
4624 if (LocaleCompare("sans1",option+1) == 0) /* one argument */
4626 if (LocaleCompare("sans2",option+1) == 0) /* two arguments */
4631 if ( ( LocaleCompare("read",option+1) == 0 ) ||
4632 ( LocaleCompare("--",option) == 0 ) ) {
4633 /* Do Glob filename Expansion for 'arg1' then read all images.
4635 * Expansion handles '@', '~', '*', and '?' meta-characters while ignoring
4636 * (but attaching to the filenames in the generated argument list) any
4637 * [...] read modifiers that may be present.
4639 * For example: It will expand '*.gif[20x20]' into a list such as
4640 * 'abc.gif[20x20]', 'foobar.gif[20x20]', 'xyzzy.gif[20x20]'
4642 * NOTE: In IMv6 this was done globally across all images. This
4643 * meant you could include IM options in '@filename' lists, but you
4644 * could not include comments. Doing it only for image read makes
4645 * it far more secure.
4647 * Note: arguments do not have percent escapes expanded for security
4655 argv = (char **) &arg1;
4657 /* Expand 'glob' expressions in the given filename.
4658 Expansion handles any 'coder:' prefix, or read modifiers attached
4659 to the filename, including them in the resulting expanded list.
4661 if (IfMagickFalse( ExpandFilenames(&argc,&argv) ))
4662 CLIWandExceptArgBreak(ResourceLimitError,"MemoryAllocationFailed",
4663 option,GetExceptionMessage(errno));
4665 /* loop over expanded filename list, and read then all in */
4666 for (i=0; i < (ssize_t) argc; i++) {
4669 if (IfMagickTrue(_image_info->ping))
4670 new_images=PingImages(_image_info,argv[i],_exception);
4672 new_images=ReadImages(_image_info,argv[i],_exception);
4673 AppendImageToList(&_images, new_images);
4675 argv=DestroyStringList(argv); /* Destroy the Expanded Filename list */
4680 Note: Writing a empty image list is valid in specific cases
4682 if (LocaleCompare("write",option+1) == 0) {
4683 /* Note: arguments do not have percent escapes expanded */
4685 key[MagickPathExtent];
4693 /* Need images, unless a "null:" output coder is used */
4694 if ( _images == (Image *) NULL ) {
4695 if ( LocaleCompare(arg1,"null:") == 0 )
4697 CLIWandExceptArgBreak(OptionError,"NoImagesForWrite",option,arg1);
4700 (void) FormatLocaleString(key,MagickPathExtent,"cache:%s",arg1);
4701 (void) DeleteImageRegistry(key);
4702 write_images=_images;
4704 write_images=CloneImageList(_images,_exception);
4705 write_info=CloneImageInfo(_image_info);
4706 (void) WriteImages(write_info,write_images,arg1,_exception);
4707 write_info=DestroyImageInfo(write_info);
4709 write_images=DestroyImageList(write_images);
4713 Parenthesis and Brace operations
4715 if (LocaleCompare("(",option) == 0) {
4716 /* stack 'push' images */
4724 node=cli_wand->image_list_stack;
4725 for ( ; node != (Stack *) NULL; node=node->next)
4727 if ( size >= MAX_STACK_DEPTH )
4728 CLIWandExceptionBreak(OptionError,"ParenthesisNestedTooDeeply",option);
4729 node=(Stack *) AcquireMagickMemory(sizeof(*node));
4730 if (node == (Stack *) NULL)
4731 CLIWandExceptionBreak(ResourceLimitFatalError,
4732 "MemoryAllocationFailed",option);
4733 node->data = (void *)cli_wand->wand.images;
4734 node->next = cli_wand->image_list_stack;
4735 cli_wand->image_list_stack = node;
4736 cli_wand->wand.images = NewImageList();
4738 /* handle respect-parenthesis */
4739 if (IfMagickTrue(IsStringTrue(GetImageOption(cli_wand->wand.image_info,
4740 "respect-parenthesis"))))
4741 option="{"; /* fall-thru so as to push image settings too */
4744 /* fall thru to operation */
4746 if (LocaleCompare("{",option) == 0) {
4747 /* stack 'push' of image_info settings */
4755 node=cli_wand->image_info_stack;
4756 for ( ; node != (Stack *) NULL; node=node->next)
4758 if ( size >= MAX_STACK_DEPTH )
4759 CLIWandExceptionBreak(OptionError,"CurlyBracesNestedTooDeeply",option);
4760 node=(Stack *) AcquireMagickMemory(sizeof(*node));
4761 if (node == (Stack *) NULL)
4762 CLIWandExceptionBreak(ResourceLimitFatalError,
4763 "MemoryAllocationFailed",option);
4765 node->data = (void *)cli_wand->wand.image_info;
4766 node->next = cli_wand->image_info_stack;
4768 cli_wand->image_info_stack = node;
4769 cli_wand->wand.image_info = CloneImageInfo(cli_wand->wand.image_info);
4770 if (cli_wand->wand.image_info == (ImageInfo *) NULL) {
4771 CLIWandException(ResourceLimitFatalError,"MemoryAllocationFailed",
4773 cli_wand->wand.image_info = (ImageInfo *)node->data;
4774 node = (Stack *)RelinquishMagickMemory(node);
4780 if (LocaleCompare(")",option) == 0) {
4781 /* pop images from stack */
4785 node = (Stack *)cli_wand->image_list_stack;
4786 if ( node == (Stack *) NULL)
4787 CLIWandExceptionBreak(OptionError,"UnbalancedParenthesis",option);
4788 cli_wand->image_list_stack = node->next;
4790 AppendImageToList((Image **)&node->data,cli_wand->wand.images);
4791 cli_wand->wand.images= (Image *)node->data;
4792 node = (Stack *)RelinquishMagickMemory(node);
4794 /* handle respect-parenthesis - of the previous 'pushed' settings */
4795 node = cli_wand->image_info_stack;
4796 if ( node != (Stack *) NULL)
4798 if (IfMagickTrue(IsStringTrue(GetImageOption(
4799 cli_wand->wand.image_info,"respect-parenthesis"))))
4800 option="}"; /* fall-thru so as to pop image settings too */
4806 /* fall thru to next if */
4808 if (LocaleCompare("}",option) == 0) {
4809 /* pop image_info settings from stack */
4813 node = (Stack *)cli_wand->image_info_stack;
4814 if ( node == (Stack *) NULL)
4815 CLIWandExceptionBreak(OptionError,"UnbalancedCurlyBraces",option);
4816 cli_wand->image_info_stack = node->next;
4818 (void) DestroyImageInfo(cli_wand->wand.image_info);
4819 cli_wand->wand.image_info = (ImageInfo *)node->data;
4820 node = (Stack *)RelinquishMagickMemory(node);
4822 GetDrawInfo(cli_wand->wand.image_info, cli_wand->draw_info);
4823 cli_wand->quantize_info=DestroyQuantizeInfo(cli_wand->quantize_info);
4824 cli_wand->quantize_info=AcquireQuantizeInfo(cli_wand->wand.image_info);
4828 if (LocaleCompare("print",option+1) == 0)
4830 (void) FormatLocaleFile(stdout,"%s",arg1);
4833 if (LocaleCompare("set",option+1) == 0)
4835 /* Settings are applied to each image in memory in turn (if any).
4836 While a option: only need to be applied once globally.
4838 NOTE: rguments have not been automatically percent expaneded
4841 /* escape the 'key' once only, using first image. */
4842 arg1=InterpretImageProperties(_image_info,_images,arg1n,_exception);
4843 if (arg1 == (char *) NULL)
4844 CLIWandExceptionBreak(OptionWarning,"InterpretPropertyFailure",
4847 if (LocaleNCompare(arg1,"registry:",9) == 0)
4851 (void) DeleteImageRegistry(arg1+9);
4852 arg1=DestroyString((char *)arg1);
4855 arg2=InterpretImageProperties(_image_info,_images,arg2n,_exception);
4856 if (arg2 == (char *) NULL) {
4857 arg1=DestroyString((char *)arg1);
4858 CLIWandExceptionBreak(OptionWarning,"InterpretPropertyFailure",
4861 (void) SetImageRegistry(StringRegistryType,arg1+9,arg2,_exception);
4862 arg1=DestroyString((char *)arg1);
4863 arg2=DestroyString((char *)arg2);
4866 if (LocaleNCompare(arg1,"option:",7) == 0)
4868 /* delete equivelent artifact from all images (if any) */
4869 if (_images != (Image *) NULL)
4871 MagickResetIterator(&cli_wand->wand);
4872 while ( IfMagickTrue(MagickNextImage(&cli_wand->wand)) )
4873 (void) DeleteImageArtifact(_images,arg1+7);
4874 MagickResetIterator(&cli_wand->wand);
4876 /* now set/delete the global option as needed */
4877 /* FUTURE: make escapes in a global 'option:' delayed */
4881 arg2=InterpretImageProperties(_image_info,_images,arg2n,_exception);
4882 if (arg2 == (char *) NULL)
4883 CLIWandExceptionBreak(OptionWarning,
4884 "InterpretPropertyFailure",option);
4886 (void) SetImageOption(_image_info,arg1+7,arg2);
4887 arg1=DestroyString((char *)arg1);
4888 arg2=DestroyString((char *)arg2);
4891 /* Set Artifacts/Properties/Attributes all images (required) */
4892 if ( _images == (Image *) NULL )
4893 CLIWandExceptArgBreak(OptionWarning,"NoImageForProperty",option,arg1);
4895 MagickResetIterator(&cli_wand->wand);
4896 while ( IfMagickTrue(MagickNextImage(&cli_wand->wand)) )
4901 arg2=InterpretImageProperties(_image_info,_images,arg2n,_exception);
4902 if (arg2 == (char *) NULL)
4903 CLIWandExceptionBreak(OptionWarning,
4904 "InterpretPropertyFailure",option);
4906 if (LocaleNCompare(arg1,"artifact:",9) == 0)
4907 (void) SetImageArtifact(_images,arg1+9,arg2);
4908 else if (LocaleNCompare(arg1,"property:",9) == 0)
4909 (void) SetImageProperty(_images,arg1+9,arg2,_exception);
4911 (void) SetImageProperty(_images,arg1,arg2,_exception);
4912 arg2=DestroyString((char *)arg2);
4914 MagickResetIterator(&cli_wand->wand);
4915 arg1=DestroyString((char *)arg1);
4918 if (LocaleCompare("clone",option+1) == 0) {
4923 arg1=AcquireString("-1");
4924 if (IfMagickFalse(IsSceneGeometry(arg1,MagickFalse)))
4925 CLIWandExceptionBreak(OptionError,"InvalidArgument",option);
4926 if ( cli_wand->image_list_stack == (Stack *) NULL)
4927 CLIWandExceptionBreak(OptionError,"UnableToCloneImage",option);
4928 new_images = (Image *)cli_wand->image_list_stack->data;
4929 if (new_images == (Image *) NULL)
4930 CLIWandExceptionBreak(OptionError,"UnableToCloneImage",option);
4931 new_images=CloneImages(new_images,arg1,_exception);
4932 if (new_images == (Image *) NULL)
4933 CLIWandExceptionBreak(OptionError,"NoSuchImage",option);
4934 AppendImageToList(&_images,new_images);
4938 Informational Operations.
4940 Note that these do not require either a cli-wand or images!
4941 Though currently a cli-wand much be provided regardless.
4943 if (LocaleCompare("version",option+1) == 0)
4945 ListMagickVersion(stdout);
4948 if (LocaleCompare("list",option+1) == 0) {
4950 FUTURE: This 'switch' should really be part of MagickCore
4955 list=ParseCommandOption(MagickListOptions,MagickFalse,arg1);
4957 CLIWandExceptionArg(OptionError,"UnrecognizedListType",option,arg1);
4962 case MagickCoderOptions:
4964 (void) ListCoderInfo((FILE *) NULL,_exception);
4967 case MagickColorOptions:
4969 (void) ListColorInfo((FILE *) NULL,_exception);
4972 case MagickConfigureOptions:
4974 (void) ListConfigureInfo((FILE *) NULL,_exception);
4977 case MagickDelegateOptions:
4979 (void) ListDelegateInfo((FILE *) NULL,_exception);
4982 case MagickFontOptions:
4984 (void) ListTypeInfo((FILE *) NULL,_exception);
4987 case MagickFormatOptions:
4988 (void) ListMagickInfo((FILE *) NULL,_exception);
4990 case MagickLocaleOptions:
4991 (void) ListLocaleInfo((FILE *) NULL,_exception);
4993 case MagickLogOptions:
4994 (void) ListLogInfo((FILE *) NULL,_exception);
4996 case MagickMagicOptions:
4997 (void) ListMagicInfo((FILE *) NULL,_exception);
4999 case MagickMimeOptions:
5000 (void) ListMimeInfo((FILE *) NULL,_exception);
5002 case MagickModuleOptions:
5003 (void) ListModuleInfo((FILE *) NULL,_exception);
5005 case MagickPolicyOptions:
5006 (void) ListPolicyInfo((FILE *) NULL,_exception);
5008 case MagickResourceOptions:
5009 (void) ListMagickResourceInfo((FILE *) NULL,_exception);
5011 case MagickThresholdOptions:
5012 (void) ListThresholdMaps((FILE *) NULL,_exception);
5015 (void) ListCommandOptions((FILE *) NULL,(CommandOption) list,
5022 CLIWandException(OptionError,"UnrecognizedOption",option);
5024 DisableMSCWarning(4127)
5025 } while (0); /* break to exit code. */
5028 /* clean up percent escape interpreted strings */
5030 arg1=DestroyString((char *)arg1);
5032 arg2=DestroyString((char *)arg2);
5042 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5046 + C L I O p t i o n %
5050 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5052 % CLIOption() Processes the given option using the given CLI Magick Wand.
5053 % The option arguments can be variable in number, though at this time no more
5054 % that two is actually used by any option (this may change). Excess options
5055 % are simply ignored.
5057 % If the cli_wand->command pointer is non-null, then it is assumed that the
5058 % option has already been search for up from the CommandOptions[] table in
5059 % "MagickCore/options.c" using GetCommandOptionInfo(). If not set this
5060 % routine will do the lookup instead. The pointer is reset afterward.
5062 % This action allows the caller to lookup and pre-handle any 'special'
5063 % options, (such as implicit reads) before calling this general option
5064 % handler to deal with 'standard' command line options.
5066 % The format of the CLIOption method is:
5068 % void CLIOption(MagickCLI *cli_wand,const char *option, ...)
5070 % A description of each parameter follows:
5072 % o cli_wand: the main CLI Wand to use.
5074 % o option: The special option (with any switch char) to process
5076 % o args: any required arguments for an option (variable number)
5080 % CLIoption(cli_wand,"-read","rose:");
5081 % CLIoption(cli_wand,"-virtual-pixel","transparent");
5082 % CLIoption(cli_wand,"-distort","SRT:","30");
5083 % CLIoption(cli_wand,"-write","rotated_rose.png");
5086 WandExport void CLIOption(MagickCLI *cli_wand,const char *option,...)
5088 const char /* extracted option args from args */
5095 assert(cli_wand != (MagickCLI *) NULL);
5096 assert(cli_wand->signature == MagickWandSignature);
5097 assert(cli_wand->wand.signature == MagickWandSignature);
5099 do { /* Break Code Block for error handling */
5101 /* get information about option */
5102 if ( cli_wand->command == (const OptionInfo *) NULL )
5103 cli_wand->command = GetCommandOptionInfo(option);
5105 (void) FormatLocaleFile(stderr, "CLIOption \"%s\" matched \"%s\"\n",
5106 option, cli_wand->command->mnemonic );
5108 option_type=(CommandOptionFlags) cli_wand->command->flags;
5110 if ( option_type == UndefinedOptionFlag )
5111 CLIWandExceptionReturn(OptionFatalError,"UnrecognizedOption",option);
5113 assert( LocaleCompare(cli_wand->command->mnemonic,option) == 0 );
5115 /* deprecated options */
5116 if ( (option_type & DeprecateOptionFlag) != 0 )
5117 CLIWandExceptionBreak(OptionError,"DeprecatedOptionNoCode",option);
5119 /* options that this module does not handle */
5120 if ((option_type & (SpecialOptionFlag|GenesisOptionFlag)) != 0 )
5121 CLIWandExceptionBreak(OptionFatalError,"InvalidUseOfOption",option);
5123 /* Get argument strings from VarArgs
5124 How can you determine if enough arguments was supplied?
5125 What happens if not enough arguments were supplied?
5128 count = (size_t) cli_wand->command->type;
5133 va_start(operands,option);
5137 arg1=(const char *) va_arg(operands, const char *);
5139 arg2=(const char *) va_arg(operands, const char *);
5143 (void) FormatLocaleFile(stderr,
5144 "CLIOption: \"%s\" Count: %ld Flags: %04x Args: \"%s\" \"%s\"\n",
5145 option,(long) count,option_type,arg1,arg2);
5150 Call the appropriate option handler
5153 /* FUTURE: this is temporary - get 'settings' to handle distribution of
5154 settings to images attributes,proprieties,artifacts */
5155 if ( cli_wand->wand.images != (Image *) NULL )
5156 (void) SyncImagesSettings(cli_wand->wand.image_info,cli_wand->wand.images,
5157 cli_wand->wand.exception);
5159 if ( (option_type & SettingOptionFlags) != 0 ) {
5160 CLISettingOptionInfo(cli_wand, option, arg1, arg2);
5161 // FUTURE: Sync Specific Settings into Image Properities (not global)
5164 /* Operators that do not need images - read, write, stack, clone */
5165 if ((option_type & NoImageOperatorFlag) != 0)
5166 CLINoImageOperator(cli_wand, option, arg1, arg2);
5168 /* FUTURE: The not a setting part below is a temporary hack due to
5169 * some options being both a Setting and a Simple operator.
5170 * Specifically -monitor, -depth, and -colorspace */
5171 if ( cli_wand->wand.images == (Image *) NULL )
5172 if ( ((option_type & (SimpleOperatorFlag|ListOperatorFlag)) != 0 ) &&
5173 ((option_type & SettingOptionFlags) == 0 )) /* temp hack */
5174 CLIWandExceptionBreak(OptionError,"NoImagesFound",option);
5176 /* Operators which loop of individual images, simply */
5177 if ( (option_type & SimpleOperatorFlag) != 0 &&
5178 cli_wand->wand.images != (Image *) NULL) /* temp hack */
5180 ExceptionInfo *exception=AcquireExceptionInfo();
5181 (void) CLISimpleOperatorImages(cli_wand, option, arg1, arg2,exception);
5182 exception=DestroyExceptionInfo(exception);
5185 /* Operators that work on the image list as a whole */
5186 if ( (option_type & ListOperatorFlag) != 0 )
5187 (void) CLIListOperatorImages(cli_wand, option, arg1, arg2);
5189 DisableMSCWarning(4127)
5190 } while (0); /* end Break code block */
5193 cli_wand->command = (const OptionInfo *) NULL; /* prevent re-use later */