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 (image->debug != MagickFalse)
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 (cli_wand->wand.debug != MagickFalse)
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 && (IsGeometry(arg1) == MagickFalse))
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 && (IsGeometry(arg1) == MagickFalse))
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 (IsGeometry(arg1) == MagickFalse)
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 && (IsGeometry(arg1) == MagickFalse))
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 (IsGeometry(arg1) == MagickFalse)
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 && (IsGeometry(arg1) == MagickFalse))
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 && (IsGeometry(arg1) == MagickFalse))
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 (IsGeometry(arg1) == MagickFalse)
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 (status == MagickFalse)
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 (IsGeometry(arg1) == MagickFalse)
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 (IsGeometry(arg1) == MagickFalse)
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 && (IsGeometry(arg1) == MagickFalse))
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 && (IsGeometry(arg1) == MagickFalse))
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 && (IsGeometry(arg1) == MagickFalse))
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 (IsGeometry(arg1) == MagickFalse)
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 (IsGeometry(arg1) == MagickFalse)
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 (IsGeometry(arg1) == MagickFalse)
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 (IsGeometry(arg1) == MagickFalse)
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 (IsGeometry(arg1) == MagickFalse)
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 && (IsGeometry(arg1) == MagickFalse))
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 && (IsGeometry(arg1) == MagickFalse))
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 (IsGeometry(arg1) == MagickFalse)
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 (status == MagickFalse)
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 && (IsGeometry(arg1) == MagickFalse))
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 (IsGeometry(arg1) == MagickFalse)
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 && (IsGeometry(arg1) == MagickFalse))
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("virtual-pixel",option+1) == 0)
1541 /* SyncImageSettings() used to set per-image attribute.
1542 This is VERY deep in the image caching structure.
1544 parse=ParseCommandOption(MagickVirtualPixelOptions,MagickFalse,
1545 ArgOption("undefined"));
1547 CLIWandExceptArgBreak(OptionError,"UnrecognizedVirtualPixelMethod",
1549 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1552 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1556 if (LocaleCompare("weight",option+1) == 0)
1561 weight=ParseCommandOption(MagickWeightOptions,MagickFalse,arg1);
1563 weight=StringToUnsignedLong(arg1);
1564 _draw_info->weight=(size_t) weight;
1567 if (LocaleCompare("white-point",option+1) == 0)
1569 /* Used as a image chromaticity setting
1570 SyncImageSettings() used to set per-image attribute.
1572 arg1=ArgOption("0.0");
1573 if (IsGeometry(arg1) == MagickFalse)
1574 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1575 (void) SetImageOption(_image_info,option+1,arg1);
1578 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1581 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1584 /* clean up percent escape interpreted strings */
1585 if ((arg1 && arg1n) && (arg1 != arg1n ))
1586 arg1=DestroyString((char *) arg1);
1587 if ((arg2 && arg2n) && (arg2 != arg2n ))
1588 arg2=DestroyString((char *) arg2);
1593 #undef _quantize_info
1596 #undef ArgBooleanNot
1597 #undef ArgBooleanString
1604 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1608 + C L I S i m p l e O p e r a t o r I m a g e s %
1612 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1614 % CLISimpleOperatorImages() applys one simple image operation given to all
1615 % the images in the CLI wand, using any per-image or global settings that was
1616 % previously saved in the CLI wand.
1618 % It is assumed that any such settings are up-to-date.
1620 % The format of the WandSimpleOperatorImages method is:
1622 % MagickBooleanType CLISimpleOperatorImages(MagickCLI *cli_wand,const char *option,
1623 % const char *arg1, const char *arg2,ExceptionInfo *exception)
1625 % A description of each parameter follows:
1627 % o cli_wand: structure holding settings and images to be operated on
1629 % o option: The option string for the operation
1631 % o arg1, arg2: optional argument strings to the operation
1636 CLISimpleOperatorImage() is an Internal subrountine to apply one simple
1637 image operation to the current image pointed to by the CLI wand.
1639 The image in the list may be modified in three different ways...
1640 * directly modified (EG: -negate, -gamma, -level, -annotate, -draw),
1641 * replaced by a new image (EG: -spread, -resize, -rotate, -morphology)
1642 * one image replace by a list of images (-separate and -crop only!)
1644 In each case the result replaces the single original image in the list, as
1645 well as the pointer to the modified image (last image added if replaced by a
1646 list of images) is returned.
1648 As the image pointed to may be replaced, the first image in the list may
1649 also change. GetFirstImageInList() should be used by caller if they wish
1650 return the Image pointer to the first image in list.
1652 static MagickBooleanType CLISimpleOperatorImage(MagickCLI *cli_wand,
1653 const char *option, const char *arg1n, const char *arg2n,
1654 ExceptionInfo *exception)
1671 const char /* percent escaped versions of the args */
1675 #define _image_info (cli_wand->wand.image_info)
1676 #define _image (cli_wand->wand.images)
1677 #define _exception (cli_wand->wand.exception)
1678 #define _draw_info (cli_wand->draw_info)
1679 #define _quantize_info (cli_wand->quantize_info)
1680 #define _process_flags (cli_wand->process_flags)
1681 #define _option_type ((CommandOptionFlags) cli_wand->command->flags)
1682 #define IfNormalOp (*option=='-')
1683 #define IfPlusOp (*option!='-')
1684 #define IsNormalOp IfNormalOp ? MagickTrue : MagickFalse
1685 #define IsPlusOp IfNormalOp ? MagickFalse : MagickTrue
1687 assert(cli_wand != (MagickCLI *) NULL);
1688 assert(cli_wand->signature == MagickWandSignature);
1689 assert(cli_wand->wand.signature == MagickWandSignature);
1690 assert(_image != (Image *) NULL); /* an image must be present */
1691 if (cli_wand->wand.debug != MagickFalse)
1692 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
1697 /* Interpret Percent Escapes in Arguments - using first image */
1698 if ( (((_process_flags & ProcessInterpretProperities) != 0 )
1699 || ((_option_type & AlwaysInterpretArgsFlag) != 0)
1700 ) && ((_option_type & NeverInterpretArgsFlag) == 0) ) {
1701 /* Interpret Percent escapes in argument 1 */
1702 if (arg1n != (char *) NULL) {
1703 arg1=InterpretImageProperties(_image_info,_image,arg1n,_exception);
1704 if (arg1 == (char *) NULL) {
1705 CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
1706 arg1=arg1n; /* use the given argument as is */
1709 if (arg2n != (char *) NULL) {
1710 arg2=InterpretImageProperties(_image_info,_image,arg2n,_exception);
1711 if (arg2 == (char *) NULL) {
1712 CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
1713 arg2=arg2n; /* use the given argument as is */
1717 #undef _process_flags
1721 (void) FormatLocaleFile(stderr,
1722 "CLISimpleOperatorImage: \"%s\" \"%s\" \"%s\"\n",option,arg1,arg2);
1725 new_image = (Image *) NULL; /* the replacement image, if not null at end */
1726 SetGeometryInfo(&geometry_info);
1728 switch (*(option+1))
1732 if (LocaleCompare("adaptive-blur",option+1) == 0)
1734 flags=ParseGeometry(arg1,&geometry_info);
1735 if ((flags & (RhoValue|SigmaValue)) == 0)
1736 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1737 if ((flags & SigmaValue) == 0)
1738 geometry_info.sigma=1.0;
1739 new_image=AdaptiveBlurImage(_image,geometry_info.rho,
1740 geometry_info.sigma,_exception);
1743 if (LocaleCompare("adaptive-resize",option+1) == 0)
1745 /* FUTURE: Roll into a resize special operator */
1746 if (IsGeometry(arg1) == MagickFalse)
1747 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1748 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
1749 new_image=AdaptiveResizeImage(_image,geometry.width,geometry.height,
1753 if (LocaleCompare("adaptive-sharpen",option+1) == 0)
1755 flags=ParseGeometry(arg1,&geometry_info);
1756 if ((flags & (RhoValue|SigmaValue)) == 0)
1757 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1758 if ((flags & SigmaValue) == 0)
1759 geometry_info.sigma=1.0;
1760 new_image=AdaptiveSharpenImage(_image,geometry_info.rho,
1761 geometry_info.sigma,_exception);
1764 if (LocaleCompare("alpha",option+1) == 0)
1766 parse=ParseCommandOption(MagickAlphaChannelOptions,MagickFalse,arg1);
1768 CLIWandExceptArgBreak(OptionError,"UnrecognizedAlphaChannelOption",
1770 (void) SetImageAlphaChannel(_image,(AlphaChannelOption) parse,
1774 if (LocaleCompare("annotate",option+1) == 0)
1777 geometry[MagickPathExtent];
1779 SetGeometryInfo(&geometry_info);
1780 flags=ParseGeometry(arg1,&geometry_info);
1782 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1783 if ((flags & SigmaValue) == 0)
1784 geometry_info.sigma=geometry_info.rho;
1785 (void) CloneString(&_draw_info->text,arg2);
1786 (void) FormatLocaleString(geometry,MagickPathExtent,"%+f%+f",
1787 geometry_info.xi,geometry_info.psi);
1788 (void) CloneString(&_draw_info->geometry,geometry);
1789 _draw_info->affine.sx=cos(DegreesToRadians(
1790 fmod(geometry_info.rho,360.0)));
1791 _draw_info->affine.rx=sin(DegreesToRadians(
1792 fmod(geometry_info.rho,360.0)));
1793 _draw_info->affine.ry=(-sin(DegreesToRadians(
1794 fmod(geometry_info.sigma,360.0))));
1795 _draw_info->affine.sy=cos(DegreesToRadians(
1796 fmod(geometry_info.sigma,360.0)));
1797 (void) AnnotateImage(_image,_draw_info,_exception);
1798 GetAffineMatrix(&_draw_info->affine);
1801 if (LocaleCompare("auto-gamma",option+1) == 0)
1803 (void) AutoGammaImage(_image,_exception);
1806 if (LocaleCompare("auto-level",option+1) == 0)
1808 (void) AutoLevelImage(_image,_exception);
1811 if (LocaleCompare("auto-orient",option+1) == 0)
1813 new_image=AutoOrientImage(_image,_image->orientation,_exception);
1816 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1820 if (LocaleCompare("black-threshold",option+1) == 0)
1822 if (IsGeometry(arg1) == MagickFalse)
1823 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1824 (void) BlackThresholdImage(_image,arg1,_exception);
1827 if (LocaleCompare("blue-shift",option+1) == 0)
1829 geometry_info.rho=1.5;
1831 flags=ParseGeometry(arg1,&geometry_info);
1832 if ((flags & RhoValue) == 0)
1833 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1835 new_image=BlueShiftImage(_image,geometry_info.rho,_exception);
1838 if (LocaleCompare("blur",option+1) == 0)
1840 flags=ParseGeometry(arg1,&geometry_info);
1841 if ((flags & (RhoValue|SigmaValue)) == 0)
1842 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1843 if ((flags & SigmaValue) == 0)
1844 geometry_info.sigma=1.0;
1845 new_image=BlurImage(_image,geometry_info.rho,geometry_info.sigma,
1849 if (LocaleCompare("border",option+1) == 0)
1857 flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
1858 if ((flags & (WidthValue | HeightValue)) == 0)
1859 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1860 compose=OverCompositeOp;
1861 value=GetImageOption(_image_info,"compose");
1862 if (value != (const char *) NULL)
1863 compose=(CompositeOperator) ParseCommandOption(MagickComposeOptions,
1865 new_image=BorderImage(_image,&geometry,compose,_exception);
1868 if (LocaleCompare("brightness-contrast",option+1) == 0)
1880 flags=ParseGeometry(arg1,&geometry_info);
1881 if ((flags & RhoValue) == 0)
1882 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1883 brightness=geometry_info.rho;
1885 if ((flags & SigmaValue) != 0)
1886 contrast=geometry_info.sigma;
1887 (void) BrightnessContrastImage(_image,brightness,contrast,
1891 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1895 if (LocaleCompare("canny",option+1) == 0)
1897 flags=ParseGeometry(arg1,&geometry_info);
1898 if ((flags & (RhoValue|SigmaValue)) == 0)
1899 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1900 if ((flags & SigmaValue) == 0)
1901 geometry_info.sigma=1.0;
1902 if ((flags & XiValue) == 0)
1903 geometry_info.xi=10;
1904 if ((flags & PsiValue) == 0)
1905 geometry_info.psi=30;
1906 if ((flags & PercentValue) != 0)
1908 geometry_info.xi/=100.0;
1909 geometry_info.psi/=100.0;
1911 new_image=CannyEdgeImage(_image,geometry_info.rho,geometry_info.sigma,
1912 geometry_info.xi,geometry_info.psi,_exception);
1915 if (LocaleCompare("cdl",option+1) == 0)
1917 /* Note: arguments do not have percent escapes expanded */
1919 *color_correction_collection;
1922 Color correct with a color decision list.
1924 color_correction_collection=FileToString(arg1,~0UL,_exception);
1925 if (color_correction_collection == (char *) NULL)
1927 (void) ColorDecisionListImage(_image,color_correction_collection,
1931 if (LocaleCompare("channel",option+1) == 0)
1935 (void) SetPixelChannelMask(_image,DefaultChannels);
1938 parse=ParseChannelOption(arg1);
1940 CLIWandExceptArgBreak(OptionError,"UnrecognizedIntensityMethod",
1942 (void) SetPixelChannelMask(_image,(ChannelType) parse);
1945 if (LocaleCompare("charcoal",option+1) == 0)
1947 flags=ParseGeometry(arg1,&geometry_info);
1948 if ((flags & (RhoValue|SigmaValue)) == 0)
1949 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1950 if ((flags & SigmaValue) == 0)
1951 geometry_info.sigma=1.0;
1952 if ((flags & XiValue) == 0)
1953 geometry_info.xi=1.0;
1954 new_image=CharcoalImage(_image,geometry_info.rho,geometry_info.sigma,
1958 if (LocaleCompare("chop",option+1) == 0)
1960 if (IsGeometry(arg1) == MagickFalse)
1961 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1962 (void) ParseGravityGeometry(_image,arg1,&geometry,_exception);
1963 new_image=ChopImage(_image,&geometry,_exception);
1966 if (LocaleCompare("clamp",option+1) == 0)
1968 (void) ClampImage(_image,_exception);
1971 if (LocaleCompare("clip",option+1) == 0)
1974 (void) ClipImage(_image,_exception);
1975 else /* "+mask" remove the write mask */
1976 (void) SetImageMask(_image,ReadPixelMask,(Image *) NULL,_exception);
1979 if (LocaleCompare("clip-mask",option+1) == 0)
1981 /* Note: arguments do not have percent escapes expanded */
1998 /* use "+clip-mask" Remove the write mask for -clip-path */
1999 (void) SetImageMask(_image,ReadPixelMask,(Image *) NULL,_exception);
2002 mask_image=GetImageCache(_image_info,arg1,_exception);
2003 if (mask_image == (Image *) NULL)
2005 if (SetImageStorageClass(mask_image,DirectClass,_exception) == MagickFalse)
2007 /* Create a write mask from cli_wand mask image */
2008 /* FUTURE: use Alpha operations instead and create a Grey Image */
2009 mask_view=AcquireAuthenticCacheView(mask_image,_exception);
2010 for (y=0; y < (ssize_t) mask_image->rows; y++)
2012 q=GetCacheViewAuthenticPixels(mask_view,0,y,mask_image->columns,1,
2014 if (q == (Quantum *) NULL)
2016 for (x=0; x < (ssize_t) mask_image->columns; x++)
2018 if (mask_image->alpha_trait == UndefinedPixelTrait)
2019 SetPixelAlpha(mask_image,(Quantum)
2020 GetPixelIntensity(mask_image,q),q);
2021 SetPixelGray(mask_image,GetPixelAlpha(mask_image,q),q);
2022 q+=GetPixelChannels(mask_image);
2024 if (SyncCacheViewAuthenticPixels(mask_view,_exception) == MagickFalse)
2027 /* clean up and set the write mask */
2028 mask_view=DestroyCacheView(mask_view);
2029 mask_image->alpha_trait=BlendPixelTrait;
2030 (void) SetImageColorspace(_image,GRAYColorspace,_exception);
2031 (void) SetImageMask(_image,ReadPixelMask,mask_image,_exception);
2032 mask_image=DestroyImage(mask_image);
2035 if (LocaleCompare("clip-path",option+1) == 0)
2037 (void) ClipImagePath(_image,arg1,IsNormalOp,_exception);
2038 /* Note: Use "+clip-mask" remove the write mask added */
2041 if (LocaleCompare("colorize",option+1) == 0)
2043 if (IsGeometry(arg1) == MagickFalse)
2044 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2045 new_image=ColorizeImage(_image,arg1,&_draw_info->fill,_exception);
2048 if (LocaleCompare("color-matrix",option+1) == 0)
2053 kernel=AcquireKernelInfo(arg1,exception);
2054 if (kernel == (KernelInfo *) NULL)
2055 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2056 new_image=ColorMatrixImage(_image,kernel,_exception);
2057 kernel=DestroyKernelInfo(kernel);
2060 if (LocaleCompare("colors",option+1) == 0)
2062 /* Reduce the number of colors in the image.
2063 FUTURE: also provide 'plus version with image 'color counts'
2065 _quantize_info->number_colors=StringToUnsignedLong(arg1);
2066 if (_quantize_info->number_colors == 0)
2067 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2068 if ((_image->storage_class == DirectClass) ||
2069 _image->colors > _quantize_info->number_colors)
2070 (void) QuantizeImage(_quantize_info,_image,_exception);
2072 (void) CompressImageColormap(_image,_exception);
2075 if (LocaleCompare("colorspace",option+1) == 0)
2077 /* WARNING: this is both a image_info setting (already done)
2078 and a operator to change image colorspace.
2080 FUTURE: default colorspace should be sRGB!
2081 Unless some type of 'linear colorspace' mode is set.
2083 Note that +colorspace sets "undefined" or no effect on
2084 new images, but forces images already in memory back to RGB!
2085 That seems to be a little strange!
2087 (void) TransformImageColorspace(_image,
2088 IfNormalOp ? _image_info->colorspace : sRGBColorspace,
2092 if (LocaleCompare("connected-components",option+1) == 0)
2094 if (IsGeometry(arg1) == MagickFalse)
2095 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2096 new_image=ConnectedComponentsImage(_image,(size_t)
2097 StringToInteger(arg1),(CCObjectInfo **) NULL,_exception);
2100 if (LocaleCompare("contrast",option+1) == 0)
2102 CLIWandWarnReplaced(IfNormalOp?"-level":"+level");
2103 (void) ContrastImage(_image,IsNormalOp,_exception);
2106 if (LocaleCompare("contrast-stretch",option+1) == 0)
2115 flags=ParseGeometry(arg1,&geometry_info);
2116 if ((flags & RhoValue) == 0)
2117 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2118 black_point=geometry_info.rho;
2119 white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
2121 if ((flags & PercentValue) != 0) {
2122 black_point*=(double) _image->columns*_image->rows/100.0;
2123 white_point*=(double) _image->columns*_image->rows/100.0;
2125 white_point=(double) _image->columns*_image->rows-white_point;
2126 (void) ContrastStretchImage(_image,black_point,white_point,
2130 if (LocaleCompare("convolve",option+1) == 0)
2141 kernel_info=AcquireKernelInfo(arg1,exception);
2142 if (kernel_info == (KernelInfo *) NULL)
2143 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2145 for (j=0; j < (ssize_t) (kernel_info->width*kernel_info->height); j++)
2146 gamma+=kernel_info->values[j];
2147 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
2148 for (j=0; j < (ssize_t) (kernel_info->width*kernel_info->height); j++)
2149 kernel_info->values[j]*=gamma;
2150 new_image=MorphologyImage(_image,CorrelateMorphology,1,kernel_info,
2152 kernel_info=DestroyKernelInfo(kernel_info);
2155 if (LocaleCompare("crop",option+1) == 0)
2157 /* WARNING: This can generate multiple images! */
2158 if (IsGeometry(arg1) == MagickFalse)
2159 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2160 new_image=CropImageToTiles(_image,arg1,_exception);
2163 if (LocaleCompare("cycle",option+1) == 0)
2165 if (IsGeometry(arg1) == MagickFalse)
2166 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2167 (void) CycleColormapImage(_image,(ssize_t) StringToLong(arg1),
2171 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2175 if (LocaleCompare("decipher",option+1) == 0)
2177 /* Note: arguments do not have percent escapes expanded */
2181 passkey=FileToStringInfo(arg1,~0UL,_exception);
2182 if (passkey == (StringInfo *) NULL)
2183 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2185 (void) PasskeyDecipherImage(_image,passkey,_exception);
2186 passkey=DestroyStringInfo(passkey);
2189 if (LocaleCompare("depth",option+1) == 0)
2191 /* The _image_info->depth setting has already been set
2192 We just need to apply it to all images in current sequence
2194 WARNING: Depth from 8 to 16 causes 'quantum rounding to images!
2195 That is it really is an operation, not a setting! Arrgghhh
2197 FUTURE: this should not be an operator!!!
2199 (void) SetImageDepth(_image,_image_info->depth,_exception);
2202 if (LocaleCompare("deskew",option+1) == 0)
2208 if (IsGeometry(arg1) == MagickFalse)
2209 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2210 threshold=StringToDoubleInterval(arg1,(double) QuantumRange+1.0);
2213 threshold=40.0*QuantumRange/100.0;
2214 new_image=DeskewImage(_image,threshold,_exception);
2217 if (LocaleCompare("despeckle",option+1) == 0)
2219 new_image=DespeckleImage(_image,_exception);
2222 if (LocaleCompare("distort",option+1) == 0)
2230 parse = ParseCommandOption(MagickDistortOptions,MagickFalse,arg1);
2232 CLIWandExceptArgBreak(OptionError,"UnrecognizedDistortMethod",
2234 if ((DistortImageMethod) parse == ResizeDistortion)
2238 /* Special Case - Argument is actually a resize geometry!
2239 ** Convert that to an appropriate distortion argument array.
2240 ** FUTURE: make a separate special resize operator
2241 Roll into a resize special operator */
2242 if (IsGeometry(arg2) == MagickFalse)
2243 CLIWandExceptArgBreak(OptionError,"InvalidGeometry",
2245 (void) ParseRegionGeometry(_image,arg2,&geometry,_exception);
2246 resize_args[0]=(double) geometry.width;
2247 resize_args[1]=(double) geometry.height;
2248 new_image=DistortImage(_image,(DistortImageMethod) parse,
2249 (size_t)2,resize_args,MagickTrue,_exception);
2252 /* convert argument string into an array of doubles */
2253 args = StringToArrayOfDoubles(arg2,&count,_exception);
2254 if (args == (double *) NULL )
2255 CLIWandExceptArgBreak(OptionError,"InvalidNumberList",option,arg2);
2257 new_image=DistortImage(_image,(DistortImageMethod) parse,(size_t)
2258 count,args,IsPlusOp,_exception);
2259 args=(double *) RelinquishMagickMemory(args);
2262 if (LocaleCompare("draw",option+1) == 0)
2264 (void) CloneString(&_draw_info->primitive,arg1);
2265 (void) DrawImage(_image,_draw_info,_exception);
2266 (void) CloneString(&_draw_info->primitive,(char *) NULL);
2269 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2273 if (LocaleCompare("edge",option+1) == 0)
2275 flags=ParseGeometry(arg1,&geometry_info);
2276 if ((flags & (RhoValue|SigmaValue)) == 0)
2277 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2278 new_image=EdgeImage(_image,geometry_info.rho,_exception);
2281 if (LocaleCompare("emboss",option+1) == 0)
2283 flags=ParseGeometry(arg1,&geometry_info);
2284 if ((flags & (RhoValue|SigmaValue)) == 0)
2285 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2286 if ((flags & SigmaValue) == 0)
2287 geometry_info.sigma=1.0;
2288 new_image=EmbossImage(_image,geometry_info.rho,
2289 geometry_info.sigma,_exception);
2292 if (LocaleCompare("encipher",option+1) == 0)
2294 /* Note: arguments do not have percent escapes expanded */
2298 passkey=FileToStringInfo(arg1,~0UL,_exception);
2299 if (passkey != (StringInfo *) NULL)
2301 (void) PasskeyEncipherImage(_image,passkey,_exception);
2302 passkey=DestroyStringInfo(passkey);
2306 if (LocaleCompare("enhance",option+1) == 0)
2308 new_image=EnhanceImage(_image,_exception);
2311 if (LocaleCompare("equalize",option+1) == 0)
2313 (void) EqualizeImage(_image,_exception);
2316 if (LocaleCompare("evaluate",option+1) == 0)
2321 parse = ParseCommandOption(MagickEvaluateOptions,MagickFalse,arg1);
2323 CLIWandExceptArgBreak(OptionError,"UnrecognizedEvaluateOperator",
2325 if (IsGeometry(arg2) == MagickFalse)
2326 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
2327 constant=StringToDoubleInterval(arg2,(double) QuantumRange+1.0);
2328 (void) EvaluateImage(_image,(MagickEvaluateOperator)parse,constant,
2332 if (LocaleCompare("extent",option+1) == 0)
2334 if (IsGeometry(arg1) == MagickFalse)
2335 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2336 flags=ParseGravityGeometry(_image,arg1,&geometry,_exception);
2337 if (geometry.width == 0)
2338 geometry.width=_image->columns;
2339 if (geometry.height == 0)
2340 geometry.height=_image->rows;
2341 new_image=ExtentImage(_image,&geometry,_exception);
2344 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2348 if (LocaleCompare("flip",option+1) == 0)
2350 new_image=FlipImage(_image,_exception);
2353 if (LocaleCompare("flop",option+1) == 0)
2355 new_image=FlopImage(_image,_exception);
2358 if (LocaleCompare("floodfill",option+1) == 0)
2363 if (IsGeometry(arg1) == MagickFalse)
2364 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2365 (void) ParsePageGeometry(_image,arg1,&geometry,_exception);
2366 (void) QueryColorCompliance(arg2,AllCompliance,&target,_exception);
2367 (void) FloodfillPaintImage(_image,_draw_info,&target,geometry.x,
2368 geometry.y,IsPlusOp,_exception);
2371 if (LocaleCompare("frame",option+1) == 0)
2382 value=GetImageOption(_image_info,"compose");
2383 compose=OverCompositeOp; /* use Over not _image->compose */
2384 if (value != (const char *) NULL)
2385 compose=(CompositeOperator) ParseCommandOption(MagickComposeOptions,
2387 if (IsGeometry(arg1) == MagickFalse)
2388 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2389 flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
2390 frame_info.width=geometry.width;
2391 frame_info.height=geometry.height;
2392 frame_info.outer_bevel=geometry.x;
2393 frame_info.inner_bevel=geometry.y;
2394 frame_info.x=(ssize_t) frame_info.width;
2395 frame_info.y=(ssize_t) frame_info.height;
2396 frame_info.width=_image->columns+2*frame_info.width;
2397 frame_info.height=_image->rows+2*frame_info.height;
2398 new_image=FrameImage(_image,&frame_info,compose,_exception);
2401 if (LocaleCompare("function",option+1) == 0)
2409 parse=ParseCommandOption(MagickFunctionOptions,MagickFalse,arg1);
2411 CLIWandExceptArgBreak(OptionError,"UnrecognizedFunction",
2413 /* convert argument string into an array of doubles */
2414 args = StringToArrayOfDoubles(arg2,&count,_exception);
2415 if (args == (double *) NULL )
2416 CLIWandExceptArgBreak(OptionError,"InvalidNumberList",option,arg2);
2418 (void) FunctionImage(_image,(MagickFunction)parse,(size_t) count,args,
2420 args=(double *) RelinquishMagickMemory(args);
2423 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2427 if (LocaleCompare("gamma",option+1) == 0)
2432 if (IsGeometry(arg1) == MagickFalse)
2433 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2434 constant=StringToDouble(arg1,(char **) NULL);
2436 /* Using Gamma, via a cache */
2438 constant=PerceptibleReciprocal(constant);
2439 (void) GammaImage(_image,constant,_exception);
2441 /* Using Evaluate POW, direct update of values - more accurite */
2443 constant=PerceptibleReciprocal(constant);
2444 (void) EvaluateImage(_image,PowEvaluateOperator,constant,_exception);
2445 _image->gamma*=StringToDouble(arg1,(char **) NULL);
2447 /* Set gamma setting -- Old meaning of "+gamma"
2448 * _image->gamma=StringToDouble(arg1,(char **) NULL);
2452 if (LocaleCompare("gaussian-blur",option+1) == 0)
2454 flags=ParseGeometry(arg1,&geometry_info);
2455 if ((flags & (RhoValue|SigmaValue)) == 0)
2456 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2457 if ((flags & SigmaValue) == 0)
2458 geometry_info.sigma=1.0;
2459 new_image=GaussianBlurImage(_image,geometry_info.rho,
2460 geometry_info.sigma,_exception);
2463 if (LocaleCompare("gaussian",option+1) == 0)
2465 CLIWandWarnReplaced("-gaussian-blur");
2466 (void) CLISimpleOperatorImage(cli_wand,"-gaussian-blur",arg1,NULL,exception);
2468 if (LocaleCompare("geometry",option+1) == 0)
2471 Record Image offset for composition. (A Setting)
2472 Resize last _image. (ListOperator) -- DEPRECIATE
2473 FUTURE: Why if no 'offset' does this resize ALL images?
2474 Also why is the setting recorded in the IMAGE non-sense!
2477 { /* remove the previous composition geometry offset! */
2478 if (_image->geometry != (char *) NULL)
2479 _image->geometry=DestroyString(_image->geometry);
2482 if (IsGeometry(arg1) == MagickFalse)
2483 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2484 flags=ParseRegionGeometry(_image,arg1,&geometry,_exception);
2485 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
2486 (void) CloneString(&_image->geometry,arg1);
2488 new_image=ResizeImage(_image,geometry.width,geometry.height,
2489 _image->filter,_exception);
2492 if (LocaleCompare("grayscale",option+1) == 0)
2494 parse=ParseCommandOption(MagickPixelIntensityOptions,
2497 CLIWandExceptArgBreak(OptionError,"UnrecognizedIntensityMethod",
2499 (void) GrayscaleImage(_image,(PixelIntensityMethod) parse,_exception);
2502 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2506 if (LocaleCompare("hough-lines",option+1) == 0)
2508 flags=ParseGeometry(arg1,&geometry_info);
2509 if ((flags & (RhoValue|SigmaValue)) == 0)
2510 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2511 if ((flags & SigmaValue) == 0)
2512 geometry_info.sigma=geometry_info.rho;
2513 if ((flags & XiValue) == 0)
2514 geometry_info.xi=40;
2515 new_image=HoughLineImage(_image,(size_t) geometry_info.rho,
2516 (size_t) geometry_info.sigma,(size_t) geometry_info.xi,_exception);
2519 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2523 if (LocaleCompare("identify",option+1) == 0)
2529 format=GetImageOption(_image_info,"format");
2530 if (format == (char *) NULL)
2532 (void) IdentifyImage(_image,stdout,_image_info->verbose,
2536 text=InterpretImageProperties(_image_info,_image,format,_exception);
2537 if (text == (char *) NULL)
2538 CLIWandExceptionBreak(OptionWarning,"InterpretPropertyFailure",
2540 (void) fputs(text,stdout);
2541 text=DestroyString((char *)text);
2544 if (LocaleCompare("implode",option+1) == 0)
2546 flags=ParseGeometry(arg1,&geometry_info);
2547 if ((flags & RhoValue) == 0)
2548 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2549 new_image=ImplodeImage(_image,geometry_info.rho,_image->interpolate,
2553 if (LocaleCompare("interpolative-resize",option+1) == 0)
2555 /* FUTURE: New to IMv7
2556 Roll into a resize special operator */
2557 if (IsGeometry(arg1) == MagickFalse)
2558 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2559 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
2560 new_image=InterpolativeResizeImage(_image,geometry.width,
2561 geometry.height,_image->interpolate,_exception);
2564 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2568 if (LocaleCompare("kuwahara",option+1) == 0)
2571 Edge preserving blur.
2573 flags=ParseGeometry(arg1,&geometry_info);
2574 if ((flags & (RhoValue|SigmaValue)) == 0)
2575 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2576 if ((flags & SigmaValue) == 0)
2577 geometry_info.sigma=geometry_info.rho-0.5;
2578 new_image=KuwaharaImage(_image,geometry_info.rho,geometry_info.sigma,
2582 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2586 if (LocaleCompare("lat",option+1) == 0)
2588 flags=ParseGeometry(arg1,&geometry_info);
2589 if ((flags & (RhoValue|SigmaValue)) == 0)
2590 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2591 if ((flags & SigmaValue) == 0)
2592 geometry_info.sigma=1.0;
2593 if ((flags & PercentValue) != 0)
2594 geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
2595 new_image=AdaptiveThresholdImage(_image,(size_t) geometry_info.rho,
2596 (size_t) geometry_info.sigma,(double) geometry_info.xi,
2600 if (LocaleCompare("level",option+1) == 0)
2610 flags=ParseGeometry(arg1,&geometry_info);
2611 if ((flags & RhoValue) == 0)
2612 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2613 black_point=geometry_info.rho;
2614 white_point=(double) QuantumRange;
2615 if ((flags & SigmaValue) != 0)
2616 white_point=geometry_info.sigma;
2618 if ((flags & XiValue) != 0)
2619 gamma=geometry_info.xi;
2620 if ((flags & PercentValue) != 0)
2622 black_point*=(double) (QuantumRange/100.0);
2623 white_point*=(double) (QuantumRange/100.0);
2625 if ((flags & SigmaValue) == 0)
2626 white_point=(double) QuantumRange-black_point;
2627 if (IfPlusOp || ((flags & AspectValue) != 0))
2628 (void) LevelizeImage(_image,black_point,white_point,gamma,_exception);
2630 (void) LevelImage(_image,black_point,white_point,gamma,_exception);
2633 if (LocaleCompare("level-colors",option+1) == 0)
2636 token[MagickPathExtent];
2645 p=(const char *) arg1;
2646 GetMagickToken(p,&p,token); /* get black point color */
2647 if ((isalpha((int) *token) != 0) || ((*token == '#') != 0))
2648 (void) QueryColorCompliance(token,AllCompliance,
2649 &black_point,_exception);
2651 (void) QueryColorCompliance("#000000",AllCompliance,
2652 &black_point,_exception);
2653 if (isalpha((int) token[0]) || (token[0] == '#'))
2654 GetMagickToken(p,&p,token);
2656 white_point=black_point; /* set everything to that color */
2659 if ((isalpha((int) *token) == 0) && ((*token == '#') == 0))
2660 GetMagickToken(p,&p,token); /* Get white point color. */
2661 if ((isalpha((int) *token) != 0) || ((*token == '#') != 0))
2662 (void) QueryColorCompliance(token,AllCompliance,
2663 &white_point,_exception);
2665 (void) QueryColorCompliance("#ffffff",AllCompliance,
2666 &white_point,_exception);
2668 (void) LevelImageColors(_image,&black_point,&white_point,
2669 IsPlusOp,_exception);
2672 if (LocaleCompare("linear-stretch",option+1) == 0)
2681 flags=ParseGeometry(arg1,&geometry_info);
2682 if ((flags & RhoValue) == 0)
2683 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2684 black_point=geometry_info.rho;
2685 white_point=(double) _image->columns*_image->rows;
2686 if ((flags & SigmaValue) != 0)
2687 white_point=geometry_info.sigma;
2688 if ((flags & PercentValue) != 0)
2690 black_point*=(double) _image->columns*_image->rows/100.0;
2691 white_point*=(double) _image->columns*_image->rows/100.0;
2693 if ((flags & SigmaValue) == 0)
2694 white_point=(double) _image->columns*_image->rows-
2696 (void) LinearStretchImage(_image,black_point,white_point,_exception);
2699 if (LocaleCompare("liquid-rescale",option+1) == 0)
2701 /* FUTURE: Roll into a resize special operator */
2702 if (IsGeometry(arg1) == MagickFalse)
2703 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2704 flags=ParseRegionGeometry(_image,arg1,&geometry,_exception);
2705 if ((flags & XValue) == 0)
2707 if ((flags & YValue) == 0)
2709 new_image=LiquidRescaleImage(_image,geometry.width,
2710 geometry.height,1.0*geometry.x,1.0*geometry.y,_exception);
2713 if (LocaleCompare("local-contrast",option+1) == 0)
2718 flags=ParseGeometry(arg1,&geometry_info);
2719 if ((flags & RhoValue) == 0)
2720 geometry_info.rho=10;
2721 if ((flags & SigmaValue) == 0)
2722 geometry_info.sigma=12.5;
2723 if (((flags & RhoValue) == 0) || ((flags & PercentValue) != 0))
2724 geometry_info.rho*=MagickMax(_image->columns,_image->rows)/100.0;
2725 new_image=LocalContrastImage(_image,geometry_info.rho,
2726 geometry_info.sigma,exception);
2729 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2733 if (LocaleCompare("magnify",option+1) == 0)
2735 new_image=MagnifyImage(_image,_exception);
2738 if (LocaleCompare("map",option+1) == 0)
2740 CLIWandWarnReplaced("-remap");
2741 (void) CLISimpleOperatorImage(cli_wand,"-remap",NULL,NULL,exception);
2744 if (LocaleCompare("mask",option+1) == 0)
2746 CLIWandWarnReplaced("-read-mask");
2747 (void) CLISimpleOperatorImage(cli_wand,"-read-mask",NULL,NULL,
2751 if (LocaleCompare("matte",option+1) == 0)
2753 CLIWandWarnReplaced(IfNormalOp?"-alpha Set":"-alpha Off");
2754 (void) SetImageAlphaChannel(_image,IfNormalOp ? SetAlphaChannel :
2755 DeactivateAlphaChannel, _exception);
2758 if (LocaleCompare("mean-shift",option+1) == 0)
2760 flags=ParseGeometry(arg1,&geometry_info);
2761 if ((flags & (RhoValue|SigmaValue)) == 0)
2762 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2763 if ((flags & SigmaValue) == 0)
2764 geometry_info.sigma=1.0;
2765 if ((flags & XiValue) == 0)
2766 geometry_info.xi=0.10*QuantumRange;
2767 if ((flags & PercentValue) != 0)
2768 geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
2769 new_image=MeanShiftImage(_image,(size_t) geometry_info.rho,
2770 (size_t) geometry_info.sigma,geometry_info.xi,_exception);
2773 if (LocaleCompare("median",option+1) == 0)
2775 CLIWandWarnReplaced("-statistic Median");
2776 (void) CLISimpleOperatorImage(cli_wand,"-statistic","Median",arg1,exception);
2779 if (LocaleCompare("mode",option+1) == 0)
2781 /* FUTURE: note this is also a special "montage" option */
2782 CLIWandWarnReplaced("-statistic Mode");
2783 (void) CLISimpleOperatorImage(cli_wand,"-statistic","Mode",arg1,exception);
2786 if (LocaleCompare("modulate",option+1) == 0)
2788 if (IsGeometry(arg1) == MagickFalse)
2789 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2790 (void) ModulateImage(_image,arg1,_exception);
2793 if (LocaleCompare("monitor",option+1) == 0)
2795 (void) SetImageProgressMonitor(_image, IfNormalOp ? MonitorProgress :
2796 (MagickProgressMonitor) NULL,(void *) NULL);
2799 if (LocaleCompare("monochrome",option+1) == 0)
2801 (void) SetImageType(_image,BilevelType,_exception);
2804 if (LocaleCompare("morphology",option+1) == 0)
2807 token[MagickPathExtent];
2819 GetMagickToken(p,&p,token);
2820 parse=ParseCommandOption(MagickMorphologyOptions,MagickFalse,token);
2822 CLIWandExceptArgBreak(OptionError,"UnrecognizedFunction",option,
2825 GetMagickToken(p,&p,token);
2826 if ((*p == ':') || (*p == ','))
2827 GetMagickToken(p,&p,token);
2829 iterations=(ssize_t) StringToLong(p);
2830 kernel=AcquireKernelInfo(arg2,exception);
2831 if (kernel == (KernelInfo *) NULL)
2832 CLIWandExceptArgBreak(OptionError,"UnabletoParseKernel",option,arg2);
2833 new_image=MorphologyImage(_image,(MorphologyMethod)parse,iterations,
2835 kernel=DestroyKernelInfo(kernel);
2838 if (LocaleCompare("motion-blur",option+1) == 0)
2840 flags=ParseGeometry(arg1,&geometry_info);
2841 if ((flags & (RhoValue|SigmaValue)) == 0)
2842 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2843 if ((flags & SigmaValue) == 0)
2844 geometry_info.sigma=1.0;
2845 new_image=MotionBlurImage(_image,geometry_info.rho,geometry_info.sigma,
2846 geometry_info.xi,_exception);
2849 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2853 if (LocaleCompare("negate",option+1) == 0)
2855 (void) NegateImage(_image, IsPlusOp, _exception);
2858 if (LocaleCompare("noise",option+1) == 0)
2868 CLIWandWarnReplaced("-statistic NonPeak");
2869 (void) CLISimpleOperatorImage(cli_wand,"-statistic","NonPeak",arg1,exception);
2872 parse=ParseCommandOption(MagickNoiseOptions,MagickFalse,arg1);
2874 CLIWandExceptArgBreak(OptionError,"UnrecognizedNoiseType",
2877 value=GetImageOption(_image_info,"attenuate");
2878 if (value != (const char *) NULL)
2879 attenuate=StringToDouble(value,(char **) NULL);
2880 new_image=AddNoiseImage(_image,(NoiseType)parse,attenuate,
2884 if (LocaleCompare("normalize",option+1) == 0)
2886 (void) NormalizeImage(_image,_exception);
2889 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2893 if (LocaleCompare("opaque",option+1) == 0)
2898 (void) QueryColorCompliance(arg1,AllCompliance,&target,_exception);
2899 (void) OpaquePaintImage(_image,&target,&_draw_info->fill,IsPlusOp,
2903 if (LocaleCompare("ordered-dither",option+1) == 0)
2905 (void) OrderedPosterizeImage(_image,arg1,_exception);
2908 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2912 if (LocaleCompare("paint",option+1) == 0)
2914 flags=ParseGeometry(arg1,&geometry_info);
2915 if ((flags & (RhoValue|SigmaValue)) == 0)
2916 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2917 new_image=OilPaintImage(_image,geometry_info.rho,geometry_info.sigma,
2921 if (LocaleCompare("perceptible",option+1) == 0)
2923 (void) PerceptibleImage(_image,StringToDouble(arg1,(char **) NULL),
2927 if (LocaleCompare("polaroid",option+1) == 0)
2939 random_info=AcquireRandomInfo();
2940 angle=22.5*(GetPseudoRandomValue(random_info)-0.5);
2941 random_info=DestroyRandomInfo(random_info);
2944 flags=ParseGeometry(arg1,&geometry_info);
2945 if ((flags & RhoValue) == 0)
2946 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2947 angle=geometry_info.rho;
2949 caption=GetImageProperty(_image,"caption",_exception);
2950 new_image=PolaroidImage(_image,_draw_info,caption,angle,
2951 _image->interpolate,_exception);
2954 if (LocaleCompare("posterize",option+1) == 0)
2956 flags=ParseGeometry(arg1,&geometry_info);
2957 if ((flags & RhoValue) == 0)
2958 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2959 (void) PosterizeImage(_image,(size_t) geometry_info.rho,
2960 _quantize_info->dither_method,_exception);
2963 if (LocaleCompare("preview",option+1) == 0)
2965 /* FUTURE: should be a 'Genesis' option?
2966 Option however is also in WandSettingOptionInfo()
2969 parse=ParseCommandOption(MagickPreviewOptions, MagickFalse,arg1);
2971 CLIWandExceptArgBreak(OptionError,"UnrecognizedPreviewType",
2973 new_image=PreviewImage(_image,(PreviewType)parse,_exception);
2976 if (LocaleCompare("profile",option+1) == 0)
2978 /* Note: arguments do not have percent escapes expanded */
2992 { /* Remove a profile from the _image. */
2993 (void) ProfileImage(_image,arg1,(const unsigned char *)
2997 /* Associate a profile with the _image. */
2998 profile_info=CloneImageInfo(_image_info);
2999 profile=GetImageProfile(_image,"iptc");
3000 if (profile != (StringInfo *) NULL)
3001 profile_info->profile=(void *) CloneStringInfo(profile);
3002 profile_image=GetImageCache(profile_info,arg1,_exception);
3003 profile_info=DestroyImageInfo(profile_info);
3004 if (profile_image == (Image *) NULL)
3009 profile_info=CloneImageInfo(_image_info);
3010 (void) CopyMagickString(profile_info->filename,arg1,
3012 profile=FileToStringInfo(profile_info->filename,~0UL,_exception);
3013 if (profile != (StringInfo *) NULL)
3015 (void) ProfileImage(_image,profile_info->magick,
3016 GetStringInfoDatum(profile),(size_t)
3017 GetStringInfoLength(profile),_exception);
3018 profile=DestroyStringInfo(profile);
3020 profile_info=DestroyImageInfo(profile_info);
3023 ResetImageProfileIterator(profile_image);
3024 name=GetNextImageProfile(profile_image);
3025 while (name != (const char *) NULL)
3027 profile=GetImageProfile(profile_image,name);
3028 if (profile != (StringInfo *) NULL)
3029 (void) ProfileImage(_image,name,GetStringInfoDatum(profile),
3030 (size_t) GetStringInfoLength(profile),_exception);
3031 name=GetNextImageProfile(profile_image);
3033 profile_image=DestroyImage(profile_image);
3036 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
3040 if (LocaleCompare("rotational-blur",option+1) == 0)
3042 flags=ParseGeometry(arg1,&geometry_info);
3043 if ((flags & RhoValue) == 0)
3044 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3045 new_image=RotationalBlurImage(_image,geometry_info.rho,_exception);
3048 if (LocaleCompare("raise",option+1) == 0)
3050 if (IsGeometry(arg1) == MagickFalse)
3051 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3052 flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
3053 (void) RaiseImage(_image,&geometry,IsNormalOp,_exception);
3056 if (LocaleCompare("random-threshold",option+1) == 0)
3058 if (IsGeometry(arg1) == MagickFalse)
3059 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3060 (void) RandomThresholdImage(_image,arg1,_exception);
3063 if (LocaleCompare("read-mask",option+1) == 0)
3065 /* Note: arguments do not have percent escapes expanded */
3070 { /* Remove a mask. */
3071 (void) SetImageMask(_image,ReadPixelMask,(Image *) NULL,
3075 /* Set the image mask. */
3076 mask=GetImageCache(_image_info,arg1,_exception);
3077 if (mask == (Image *) NULL)
3079 (void) SetImageMask(_image,ReadPixelMask,mask,_exception);
3080 mask=DestroyImage(mask);
3083 if (LocaleCompare("recolor",option+1) == 0)
3085 CLIWandWarnReplaced("-color-matrix");
3086 (void) CLISimpleOperatorImage(cli_wand,"-color-matrix",arg1,NULL,exception);
3088 if (LocaleCompare("remap",option+1) == 0)
3090 /* Note: arguments do not have percent escapes expanded */
3094 remap_image=GetImageCache(_image_info,arg1,_exception);
3095 if (remap_image == (Image *) NULL)
3097 (void) RemapImage(_quantize_info,_image,remap_image,_exception);
3098 remap_image=DestroyImage(remap_image);
3101 if (LocaleCompare("repage",option+1) == 0)
3105 if (IsGeometry(arg1) == MagickFalse)
3106 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,
3108 (void) ResetImagePage(_image,arg1);
3111 (void) ParseAbsoluteGeometry("0x0+0+0",&_image->page);
3114 if (LocaleCompare("resample",option+1) == 0)
3116 /* FUTURE: Roll into a resize special operation */
3117 flags=ParseGeometry(arg1,&geometry_info);
3118 if ((flags & (RhoValue|SigmaValue)) == 0)
3119 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3120 if ((flags & SigmaValue) == 0)
3121 geometry_info.sigma=geometry_info.rho;
3122 new_image=ResampleImage(_image,geometry_info.rho,
3123 geometry_info.sigma,_image->filter,_exception);
3126 if (LocaleCompare("resize",option+1) == 0)
3128 if (IsGeometry(arg1) == MagickFalse)
3129 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3130 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
3131 new_image=ResizeImage(_image,geometry.width,geometry.height,
3132 _image->filter,_exception);
3135 if (LocaleCompare("roll",option+1) == 0)
3137 if (IsGeometry(arg1) == MagickFalse)
3138 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3139 (void) ParsePageGeometry(_image,arg1,&geometry,_exception);
3140 new_image=RollImage(_image,geometry.x,geometry.y,_exception);
3143 if (LocaleCompare("rotate",option+1) == 0)
3145 flags=ParseGeometry(arg1,&geometry_info);
3146 if ((flags & RhoValue) == 0)
3147 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3148 if ((flags & GreaterValue) != 0 && (_image->columns <= _image->rows))
3150 if ((flags & LessValue) != 0 && (_image->columns >= _image->rows))
3152 new_image=RotateImage(_image,geometry_info.rho,_exception);
3155 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
3159 if (LocaleCompare("sample",option+1) == 0)
3161 /* FUTURE: Roll into a resize special operator */
3162 if (IsGeometry(arg1) == MagickFalse)
3163 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3164 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
3165 new_image=SampleImage(_image,geometry.width,geometry.height,
3169 if (LocaleCompare("scale",option+1) == 0)
3171 /* FUTURE: Roll into a resize special operator */
3172 if (IsGeometry(arg1) == MagickFalse)
3173 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3174 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
3175 new_image=ScaleImage(_image,geometry.width,geometry.height,
3179 if (LocaleCompare("segment",option+1) == 0)
3181 flags=ParseGeometry(arg1,&geometry_info);
3182 if ((flags & (RhoValue|SigmaValue)) == 0)
3183 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3184 if ((flags & SigmaValue) == 0)
3185 geometry_info.sigma=1.0;
3186 (void) SegmentImage(_image,_image->colorspace,
3187 _image_info->verbose,geometry_info.rho,geometry_info.sigma,
3191 if (LocaleCompare("selective-blur",option+1) == 0)
3193 flags=ParseGeometry(arg1,&geometry_info);
3194 if ((flags & (RhoValue|SigmaValue)) == 0)
3195 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3196 if ((flags & SigmaValue) == 0)
3197 geometry_info.sigma=1.0;
3198 if ((flags & PercentValue) != 0)
3199 geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
3200 new_image=SelectiveBlurImage(_image,geometry_info.rho,
3201 geometry_info.sigma,geometry_info.xi,_exception);
3204 if (LocaleCompare("separate",option+1) == 0)
3206 /* WARNING: This can generate multiple images! */
3207 /* FUTURE - this may be replaced by a "-channel" method */
3208 new_image=SeparateImages(_image,_exception);
3211 if (LocaleCompare("sepia-tone",option+1) == 0)
3213 if (IsGeometry(arg1) == MagickFalse)
3214 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3215 new_image=SepiaToneImage(_image,StringToDoubleInterval(arg1,
3216 (double) QuantumRange+1.0),_exception);
3219 if (LocaleCompare("shade",option+1) == 0)
3221 flags=ParseGeometry(arg1,&geometry_info);
3222 if (((flags & RhoValue) == 0) || ((flags & SigmaValue) == 0))
3223 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3224 new_image=ShadeImage(_image,IsNormalOp,geometry_info.rho,
3225 geometry_info.sigma,_exception);
3228 if (LocaleCompare("shadow",option+1) == 0)
3230 flags=ParseGeometry(arg1,&geometry_info);
3231 if ((flags & (RhoValue|SigmaValue)) == 0)
3232 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3233 if ((flags & SigmaValue) == 0)
3234 geometry_info.sigma=1.0;
3235 if ((flags & XiValue) == 0)
3236 geometry_info.xi=4.0;
3237 if ((flags & PsiValue) == 0)
3238 geometry_info.psi=4.0;
3239 new_image=ShadowImage(_image,geometry_info.rho,geometry_info.sigma,
3240 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
3241 ceil(geometry_info.psi-0.5),_exception);
3244 if (LocaleCompare("sharpen",option+1) == 0)
3246 flags=ParseGeometry(arg1,&geometry_info);
3247 if ((flags & (RhoValue|SigmaValue)) == 0)
3248 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3249 if ((flags & SigmaValue) == 0)
3250 geometry_info.sigma=1.0;
3251 if ((flags & XiValue) == 0)
3252 geometry_info.xi=0.0;
3253 new_image=SharpenImage(_image,geometry_info.rho,geometry_info.sigma,
3257 if (LocaleCompare("shave",option+1) == 0)
3259 if (IsGeometry(arg1) == MagickFalse)
3260 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3261 flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
3262 new_image=ShaveImage(_image,&geometry,_exception);
3265 if (LocaleCompare("shear",option+1) == 0)
3267 flags=ParseGeometry(arg1,&geometry_info);
3268 if ((flags & RhoValue) == 0)
3269 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3270 if ((flags & SigmaValue) == 0)
3271 geometry_info.sigma=geometry_info.rho;
3272 new_image=ShearImage(_image,geometry_info.rho,geometry_info.sigma,
3276 if (LocaleCompare("sigmoidal-contrast",option+1) == 0)
3278 flags=ParseGeometry(arg1,&geometry_info);
3279 if ((flags & RhoValue) == 0)
3280 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3281 if ((flags & SigmaValue) == 0)
3282 geometry_info.sigma=(double) QuantumRange/2.0;
3283 if ((flags & PercentValue) != 0)
3284 geometry_info.sigma=(double) QuantumRange*geometry_info.sigma/
3286 (void) SigmoidalContrastImage(_image,IsNormalOp,geometry_info.rho,
3287 geometry_info.sigma,_exception);
3290 if (LocaleCompare("sketch",option+1) == 0)
3292 flags=ParseGeometry(arg1,&geometry_info);
3293 if ((flags & (RhoValue|SigmaValue)) == 0)
3294 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3295 if ((flags & SigmaValue) == 0)
3296 geometry_info.sigma=1.0;
3297 new_image=SketchImage(_image,geometry_info.rho,
3298 geometry_info.sigma,geometry_info.xi,_exception);
3301 if (LocaleCompare("solarize",option+1) == 0)
3303 if (IsGeometry(arg1) == MagickFalse)
3304 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3305 (void) SolarizeImage(_image,StringToDoubleInterval(arg1,(double)
3306 QuantumRange+1.0),_exception);
3309 if (LocaleCompare("sparse-color",option+1) == 0)
3311 parse= ParseCommandOption(MagickSparseColorOptions,MagickFalse,arg1);
3313 CLIWandExceptArgBreak(OptionError,"UnrecognizedSparseColorMethod",
3315 new_image=SparseColorOption(_image,(SparseColorMethod)parse,arg2,
3319 if (LocaleCompare("splice",option+1) == 0)
3321 if (IsGeometry(arg1) == MagickFalse)
3322 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3323 flags=ParseGravityGeometry(_image,arg1,&geometry,_exception);
3324 new_image=SpliceImage(_image,&geometry,_exception);
3327 if (LocaleCompare("spread",option+1) == 0)
3329 flags=ParseGeometry(arg1,&geometry_info);
3330 if ((flags & RhoValue) == 0)
3331 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
3332 new_image=SpreadImage(_image,_image->interpolate,geometry_info.rho,
3336 if (LocaleCompare("statistic",option+1) == 0)
3338 parse=ParseCommandOption(MagickStatisticOptions,MagickFalse,arg1);
3340 CLIWandExceptArgBreak(OptionError,"UnrecognizedStatisticType",
3342 flags=ParseGeometry(arg2,&geometry_info);
3343 if ((flags & RhoValue) == 0)
3344 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
3345 if ((flags & SigmaValue) == 0)
3346 geometry_info.sigma=geometry_info.rho;
3347 new_image=StatisticImage(_image,(StatisticType)parse,
3348 (size_t) geometry_info.rho,(size_t) geometry_info.sigma,
3352 if (LocaleCompare("strip",option+1) == 0)
3354 (void) StripImage(_image,_exception);
3357 if (LocaleCompare("swirl",option+1) == 0)
3359 flags=ParseGeometry(arg1,&geometry_info);
3360 if ((flags & RhoValue) == 0)
3361 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3362 new_image=SwirlImage(_image,geometry_info.rho,
3363 _image->interpolate,_exception);
3366 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
3370 if (LocaleCompare("threshold",option+1) == 0)
3375 threshold=(double) QuantumRange/2;
3377 if (IsGeometry(arg1) == MagickFalse)
3378 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3379 threshold=StringToDoubleInterval(arg1,(double) QuantumRange+1.0);
3381 (void) BilevelImage(_image,threshold,_exception);
3384 if (LocaleCompare("thumbnail",option+1) == 0)
3386 if (IsGeometry(arg1) == MagickFalse)
3387 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3388 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
3389 new_image=ThumbnailImage(_image,geometry.width,geometry.height,
3393 if (LocaleCompare("tint",option+1) == 0)
3395 if (IsGeometry(arg1) == MagickFalse)
3396 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3397 new_image=TintImage(_image,arg1,&_draw_info->fill,_exception);
3400 if (LocaleCompare("transform",option+1) == 0)
3402 CLIWandWarnReplaced("+distort AffineProjection");
3403 new_image=AffineTransformImage(_image,&_draw_info->affine,_exception);
3406 if (LocaleCompare("transparent",option+1) == 0)
3411 (void) QueryColorCompliance(arg1,AllCompliance,&target,_exception);
3412 (void) TransparentPaintImage(_image,&target,(Quantum)
3413 TransparentAlpha,IsPlusOp,_exception);
3416 if (LocaleCompare("transpose",option+1) == 0)
3418 new_image=TransposeImage(_image,_exception);
3421 if (LocaleCompare("transverse",option+1) == 0)
3423 new_image=TransverseImage(_image,_exception);
3426 if (LocaleCompare("trim",option+1) == 0)
3428 new_image=TrimImage(_image,_exception);
3431 if (LocaleCompare("type",option+1) == 0)
3433 /* Note that "type" setting should have already been defined */
3434 (void) SetImageType(_image,_image_info->type,_exception);
3437 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
3441 if (LocaleCompare("unique",option+1) == 0)
3443 /* FUTURE: move to SyncImageSettings() and AcqireImage()???
3444 Option is not documented, bt appears to be for "identify".
3445 We may need a identify specific verbose!
3448 (void) DeleteImageArtifact(_image,"identify:unique-colors");
3451 (void) SetImageArtifact(_image,"identify:unique-colors","true");
3452 (void) SetImageArtifact(_image,"verbose","true");
3455 if (LocaleCompare("unique-colors",option+1) == 0)
3457 new_image=UniqueImageColors(_image,_exception);
3460 if (LocaleCompare("unsharp",option+1) == 0)
3462 flags=ParseGeometry(arg1,&geometry_info);
3463 if ((flags & (RhoValue|SigmaValue)) == 0)
3464 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3465 if ((flags & SigmaValue) == 0)
3466 geometry_info.sigma=1.0;
3467 if ((flags & XiValue) == 0)
3468 geometry_info.xi=1.0;
3469 if ((flags & PsiValue) == 0)
3470 geometry_info.psi=0.05;
3471 new_image=UnsharpMaskImage(_image,geometry_info.rho,
3472 geometry_info.sigma,geometry_info.xi,geometry_info.psi,_exception);
3475 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
3479 if (LocaleCompare("verbose",option+1) == 0)
3481 /* FUTURE: move to SyncImageSettings() and AcquireImage()???
3482 three places! ImageArtifact ImageOption _image_info->verbose
3483 Some how new images also get this artifact!
3485 (void) SetImageArtifact(_image,option+1,
3486 IfNormalOp ? "true" : "false" );
3489 if (LocaleCompare("vignette",option+1) == 0)
3491 flags=ParseGeometry(arg1,&geometry_info);
3492 if ((flags & (RhoValue|SigmaValue)) == 0)
3493 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3494 if ((flags & SigmaValue) == 0)
3495 geometry_info.sigma=1.0;
3496 if ((flags & XiValue) == 0)
3497 geometry_info.xi=0.1*_image->columns;
3498 if ((flags & PsiValue) == 0)
3499 geometry_info.psi=0.1*_image->rows;
3500 if ((flags & PercentValue) != 0)
3502 geometry_info.xi*=(double) _image->columns/100.0;
3503 geometry_info.psi*=(double) _image->rows/100.0;
3505 new_image=VignetteImage(_image,geometry_info.rho,geometry_info.sigma,
3506 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
3507 ceil(geometry_info.psi-0.5),_exception);
3510 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
3514 if (LocaleCompare("wave",option+1) == 0)
3516 flags=ParseGeometry(arg1,&geometry_info);
3517 if ((flags & (RhoValue|SigmaValue)) == 0)
3518 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3519 if ((flags & SigmaValue) == 0)
3520 geometry_info.sigma=1.0;
3521 new_image=WaveImage(_image,geometry_info.rho,geometry_info.sigma,
3522 _image->interpolate,_exception);
3525 if (LocaleCompare("white-threshold",option+1) == 0)
3527 if (IsGeometry(arg1) == MagickFalse)
3528 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3529 (void) WhiteThresholdImage(_image,arg1,_exception);
3532 if (LocaleCompare("write-mask",option+1) == 0)
3534 /* Note: arguments do not have percent escapes expanded */
3539 { /* Remove a mask. */
3540 (void) SetImageMask(_image,WritePixelMask,(Image *) NULL,
3544 /* Set the image mask. */
3545 mask=GetImageCache(_image_info,arg1,_exception);
3546 if (mask == (Image *) NULL)
3548 (void) SetImageMask(_image,WritePixelMask,mask,_exception);
3549 mask=DestroyImage(mask);
3552 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
3555 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
3557 /* clean up percent escape interpreted strings */
3559 arg1=DestroyString((char *)arg1);
3561 arg2=DestroyString((char *)arg2);
3563 /* Replace current image with any image that was generated
3564 and set image point to last image (so image->next is correct) */
3565 if (new_image != (Image *) NULL)
3566 ReplaceImageInListReturnLast(&_image,new_image);
3571 #undef _quantize_info
3580 WandPrivate MagickBooleanType CLISimpleOperatorImages(MagickCLI *cli_wand,
3581 const char *option,const char *arg1,const char *arg2,ExceptionInfo *exception)
3583 #if !USE_WAND_METHODS
3589 assert(cli_wand != (MagickCLI *) NULL);
3590 assert(cli_wand->signature == MagickWandSignature);
3591 assert(cli_wand->wand.signature == MagickWandSignature);
3592 assert(cli_wand->wand.images != (Image *) NULL); /* images must be present */
3594 if (cli_wand->wand.debug != MagickFalse)
3595 (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(),
3596 "- Simple Operator: %s \"%s\" \"%s\"", option,arg1,arg2);
3598 #if !USE_WAND_METHODS
3599 /* FUTURE add appropriate tracing */
3601 n=GetImageListLength(cli_wand->wand.images);
3602 cli_wand->wand.images=GetFirstImageInList(cli_wand->wand.images);
3605 CLISimpleOperatorImage(cli_wand, option, arg1, arg2,exception);
3606 if ( cli_wand->wand.images->next == (Image *) NULL )
3608 cli_wand->wand.images=cli_wand->wand.images->next;
3611 cli_wand->wand.images=GetFirstImageInList(cli_wand->wand.images);
3613 MagickResetIterator(&cli_wand->wand);
3614 while (MagickNextImage(&cli_wand->wand) != MagickFalse)
3615 (void) CLISimpleOperatorImage(cli_wand, option, arg1, arg2,exception);
3616 MagickResetIterator(&cli_wand->wand);
3622 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3626 + C L I L i s t O p e r a t o r I m a g e s %
3630 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3632 % CLIListOperatorImages() applies a single operation that is apply to the
3633 % entire image list as a whole. The result is often a complete replacment
3634 % of the image list with a completely new list, or with just a single image
3637 % The format of the MogrifyImage method is:
3639 % MagickBooleanType CLIListOperatorImages(MagickCLI *cli_wand,
3640 % const char *option,const char *arg1,const char *arg2)
3642 % A description of each parameter follows:
3644 % o cli_wand: structure holding settings to be applied
3646 % o option: The option string for the operation
3648 % o arg1, arg2: optional argument strings to the operation
3649 % arg2 is currently not used
3652 WandPrivate MagickBooleanType CLIListOperatorImages(MagickCLI *cli_wand,
3653 const char *option,const char *arg1n,const char *arg2n)
3655 const char /* percent escaped versions of the args */
3668 #define _image_info (cli_wand->wand.image_info)
3669 #define _images (cli_wand->wand.images)
3670 #define _exception (cli_wand->wand.exception)
3671 #define _draw_info (cli_wand->draw_info)
3672 #define _quantize_info (cli_wand->quantize_info)
3673 #define _process_flags (cli_wand->process_flags)
3674 #define _option_type ((CommandOptionFlags) cli_wand->command->flags)
3675 #define IfNormalOp (*option=='-')
3676 #define IfPlusOp (*option!='-')
3677 #define IsNormalOp IfNormalOp ? MagickTrue : MagickFalse
3679 assert(cli_wand != (MagickCLI *) NULL);
3680 assert(cli_wand->signature == MagickWandSignature);
3681 assert(cli_wand->wand.signature == MagickWandSignature);
3682 assert(_images != (Image *) NULL); /* _images must be present */
3684 if (cli_wand->wand.debug != MagickFalse)
3685 (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(),
3686 "- List Operator: %s \"%s\" \"%s\"", option,
3687 arg1n == (const char *) NULL ? "null" : arg1n,
3688 arg2n == (const char *) NULL ? "null" : arg2n);
3693 /* Interpret Percent Escapes in Arguments - using first image */
3694 if ( (((_process_flags & ProcessInterpretProperities) != 0 )
3695 || ((_option_type & AlwaysInterpretArgsFlag) != 0)
3696 ) && ((_option_type & NeverInterpretArgsFlag) == 0) ) {
3697 /* Interpret Percent escapes in argument 1 */
3698 if (arg1n != (char *) NULL) {
3699 arg1=InterpretImageProperties(_image_info,_images,arg1n,_exception);
3700 if (arg1 == (char *) NULL) {
3701 CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
3702 arg1=arg1n; /* use the given argument as is */
3705 if (arg2n != (char *) NULL) {
3706 arg2=InterpretImageProperties(_image_info,_images,arg2n,_exception);
3707 if (arg2 == (char *) NULL) {
3708 CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
3709 arg2=arg2n; /* use the given argument as is */
3713 #undef _process_flags
3717 new_images=NewImageList();
3719 switch (*(option+1))
3723 if (LocaleCompare("append",option+1) == 0)
3725 new_images=AppendImages(_images,IsNormalOp,_exception);
3728 if (LocaleCompare("average",option+1) == 0)
3730 CLIWandWarnReplaced("-evaluate-sequence Mean");
3731 (void) CLIListOperatorImages(cli_wand,"-evaluate-sequence","Mean",NULL);
3734 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
3738 if (LocaleCompare("channel-fx",option+1) == 0)
3740 new_images=ChannelFxImage(_images,arg1,_exception);
3743 if (LocaleCompare("clut",option+1) == 0)
3748 /* FUTURE - make this a compose option, and thus can be used
3749 with layers compose or even compose last image over all other
3752 new_images=RemoveFirstImageFromList(&_images);
3753 clut_image=RemoveLastImageFromList(&_images);
3754 /* FUTURE - produce Exception, rather than silent fail */
3755 if (clut_image == (Image *) NULL)
3757 (void) ClutImage(new_images,clut_image,new_images->interpolate,
3759 clut_image=DestroyImage(clut_image);
3762 if (LocaleCompare("coalesce",option+1) == 0)
3764 new_images=CoalesceImages(_images,_exception);
3767 if (LocaleCompare("combine",option+1) == 0)
3769 parse=(ssize_t) _images->colorspace;
3771 parse=ParseCommandOption(MagickColorspaceOptions,MagickFalse,arg1);
3773 CLIWandExceptArgBreak(OptionError,"UnrecognizedColorspace",option,
3775 new_images=CombineImages(_images,(ColorspaceType) parse,_exception);
3778 if (LocaleCompare("compare",option+1) == 0)
3791 Mathematically and visually annotate the difference between an
3792 image and its reconstruction.
3794 image=RemoveFirstImageFromList(&_images);
3795 reconstruct_image=RemoveFirstImageFromList(&_images);
3796 /* FUTURE - produce Exception, rather than silent fail */
3797 if (reconstruct_image == (Image *) NULL)
3799 metric=UndefinedErrorMetric;
3800 option=GetImageOption(_image_info,"metric");
3801 if (option != (const char *) NULL)
3802 metric=(MetricType) ParseCommandOption(MagickMetricOptions,
3803 MagickFalse,option);
3804 new_images=CompareImages(image,reconstruct_image,metric,&distortion,
3807 reconstruct_image=DestroyImage(reconstruct_image);
3808 image=DestroyImage(image);
3811 if (LocaleCompare("complex",option+1) == 0)
3813 parse=ParseCommandOption(MagickComplexOptions,MagickFalse,arg1);
3815 CLIWandExceptArgBreak(OptionError,"UnrecognizedEvaluateOperator",
3817 new_images=ComplexImages(_images,(ComplexOperator) parse,_exception);
3820 if (LocaleCompare("composite",option+1) == 0)
3838 /* Compose value from "-compose" option only */
3839 value=GetImageOption(_image_info,"compose");
3840 if (value == (const char *) NULL)
3841 compose=OverCompositeOp; /* use Over not source_image->compose */
3843 compose=(CompositeOperator) ParseCommandOption(MagickComposeOptions,
3846 /* Get "clip-to-self" expert setting (false is normal) */
3847 value=GetImageOption(_image_info,"compose:clip-to-self");
3848 if (value == (const char *) NULL)
3849 clip_to_self=MagickTrue;
3851 clip_to_self=IsStringTrue(GetImageOption(_image_info,
3852 "compose:clip-to-self")); /* if this is true */
3853 value=GetImageOption(_image_info,"compose:outside-overlay");
3854 if (value != (const char *) NULL) { /* or this false */
3855 /* FUTURE: depreciate warning for "compose:outside-overlay"*/
3856 clip_to_self=IsStringFalse(value);
3859 new_images=RemoveFirstImageFromList(&_images);
3860 source_image=RemoveFirstImageFromList(&_images);
3861 if (source_image == (Image *) NULL)
3862 break; /* FUTURE - produce Exception, rather than silent fail */
3864 /* FUTURE - this should not be here! - should be part of -geometry */
3865 (void) TransformImage(&source_image,(char *) NULL,
3866 source_image->geometry,_exception);
3867 SetGeometry(source_image,&geometry);
3868 (void) ParseAbsoluteGeometry(source_image->geometry,&geometry);
3869 GravityAdjustGeometry(new_images->columns,new_images->rows,
3870 new_images->gravity, &geometry);
3871 mask_image=RemoveFirstImageFromList(&_images);
3872 if (mask_image == (Image *) NULL)
3873 status&=CompositeImage(new_images,source_image,compose,clip_to_self,
3874 geometry.x,geometry.y,_exception);
3877 if ((compose == DisplaceCompositeOp) ||
3878 (compose == DistortCompositeOp))
3880 status&=CompositeImage(source_image,mask_image,
3881 CopyGreenCompositeOp,MagickTrue,0,0,_exception);
3882 status&=CompositeImage(new_images,source_image,compose,
3883 clip_to_self,geometry.x,geometry.y,_exception);
3890 clone_image=CloneImage(new_images,0,0,MagickTrue,_exception);
3891 if (clone_image == (Image *) NULL)
3893 status&=CompositeImage(new_images,source_image,compose,
3894 clip_to_self,geometry.x,geometry.y,_exception);
3895 status&=CompositeImage(new_images,mask_image,
3896 CopyAlphaCompositeOp,MagickTrue,0,0,_exception);
3897 status&=CompositeImage(clone_image,new_images,OverCompositeOp,
3898 clip_to_self,0,0,_exception);
3899 new_images=DestroyImage(new_images);
3900 new_images=clone_image;
3902 mask_image=DestroyImage(mask_image);
3904 source_image=DestroyImage(source_image);
3907 if (LocaleCompare("copy",option+1) == 0)
3921 if (IsGeometry(arg1) == MagickFalse)
3922 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3923 if (IsGeometry(arg2) == MagickFalse)
3924 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3925 (void) ParsePageGeometry(_images,arg2,&geometry,_exception);
3926 offset.x=geometry.x;
3927 offset.y=geometry.y;
3928 source_image=_images;
3929 if (source_image->next != (Image *) NULL)
3930 source_image=source_image->next;
3931 (void) ParsePageGeometry(source_image,arg1,&geometry,_exception);
3932 (void) CopyImagePixels(_images,source_image,&geometry,&offset,
3936 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
3940 if (LocaleCompare("deconstruct",option+1) == 0)
3942 CLIWandWarnReplaced("-layer CompareAny");
3943 (void) CLIListOperatorImages(cli_wand,"-layer","CompareAny",NULL);
3946 if (LocaleCompare("delete",option+1) == 0)
3949 DeleteImages(&_images,arg1,_exception);
3951 DeleteImages(&_images,"-1",_exception);
3954 if (LocaleCompare("duplicate",option+1) == 0)
3964 if (IsGeometry(arg1) == MagickFalse)
3965 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,
3967 number_duplicates=(size_t) StringToLong(arg1);
3969 if (p == (const char *) NULL)
3970 new_images=DuplicateImages(_images,number_duplicates,"-1",
3973 new_images=DuplicateImages(_images,number_duplicates,p,
3977 new_images=DuplicateImages(_images,1,"-1",_exception);
3978 AppendImageToList(&_images, new_images);
3979 new_images=(Image *) NULL;
3982 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
3986 if (LocaleCompare("evaluate-sequence",option+1) == 0)
3988 parse=ParseCommandOption(MagickEvaluateOptions,MagickFalse,arg1);
3990 CLIWandExceptArgBreak(OptionError,"UnrecognizedEvaluateOperator",
3992 new_images=EvaluateImages(_images,(MagickEvaluateOperator)parse,
3996 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4000 if (LocaleCompare("fft",option+1) == 0)
4002 new_images=ForwardFourierTransformImage(_images,IsNormalOp,
4006 if (LocaleCompare("flatten",option+1) == 0)
4008 /* REDIRECTED to use -layers flatten instead */
4009 (void) CLIListOperatorImages(cli_wand,"-layers",option+1,NULL);
4012 if (LocaleCompare("fx",option+1) == 0)
4014 new_images=FxImage(_images,arg1,_exception);
4017 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4021 if (LocaleCompare("hald-clut",option+1) == 0)
4023 /* FUTURE - make this a compose option (and thus layers compose )
4024 or perhaps compose last image over all other _images.
4029 new_images=RemoveFirstImageFromList(&_images);
4030 hald_image=RemoveLastImageFromList(&_images);
4031 if (hald_image == (Image *) NULL)
4033 (void) HaldClutImage(new_images,hald_image,_exception);
4034 hald_image=DestroyImage(hald_image);
4037 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4041 if (LocaleCompare("ift",option+1) == 0)
4047 magnitude_image=RemoveFirstImageFromList(&_images);
4048 phase_image=RemoveFirstImageFromList(&_images);
4049 /* FUTURE - produce Exception, rather than silent fail */
4050 if (phase_image == (Image *) NULL)
4052 new_images=InverseFourierTransformImage(magnitude_image,phase_image,
4053 IsNormalOp,_exception);
4054 magnitude_image=DestroyImage(magnitude_image);
4055 phase_image=DestroyImage(phase_image);
4058 if (LocaleCompare("insert",option+1) == 0)
4067 if (IfNormalOp && (IsGeometry(arg1) == MagickFalse))
4068 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
4070 insert_image=RemoveLastImageFromList(&_images);
4072 index=(ssize_t) StringToLong(arg1);
4073 index_image=insert_image;
4075 PrependImageToList(&_images,insert_image);
4076 else if (index == (ssize_t) GetImageListLength(_images))
4077 AppendImageToList(&_images,insert_image);
4080 index_image=GetImageFromList(_images,index-1);
4081 if (index_image == (Image *) NULL)
4082 CLIWandExceptArgBreak(OptionError,"NoSuchImage",option,arg1);
4083 InsertImageInList(&index_image,insert_image);
4085 _images=GetFirstImageInList(index_image);
4088 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4092 if (LocaleCompare("layers",option+1) == 0)
4094 parse=ParseCommandOption(MagickLayerOptions,MagickFalse,arg1);
4096 CLIWandExceptArgBreak(OptionError,"UnrecognizedLayerMethod",
4098 switch ((LayerMethod) parse)
4102 new_images=CoalesceImages(_images,_exception);
4105 case CompareAnyLayer:
4106 case CompareClearLayer:
4107 case CompareOverlayLayer:
4110 new_images=CompareImagesLayers(_images,(LayerMethod) parse,
4117 case TrimBoundsLayer:
4119 new_images=MergeImageLayers(_images,(LayerMethod) parse,
4125 new_images=DisposeImages(_images,_exception);
4128 case OptimizeImageLayer:
4130 new_images=OptimizeImageLayers(_images,_exception);
4133 case OptimizePlusLayer:
4135 new_images=OptimizePlusImageLayers(_images,_exception);
4138 case OptimizeTransLayer:
4140 OptimizeImageTransparency(_images,_exception);
4143 case RemoveDupsLayer:
4145 RemoveDuplicateLayers(&_images,_exception);
4148 case RemoveZeroLayer:
4150 RemoveZeroDelayLayers(&_images,_exception);
4154 { /* General Purpose, GIF Animation Optimizer. */
4155 new_images=CoalesceImages(_images,_exception);
4156 if (new_images == (Image *) NULL)
4158 _images=DestroyImageList(_images);
4159 _images=OptimizeImageLayers(new_images,_exception);
4160 if (_images == (Image *) NULL)
4162 new_images=DestroyImageList(new_images);
4163 OptimizeImageTransparency(_images,_exception);
4164 (void) RemapImages(_quantize_info,_images,(Image *) NULL,
4168 case CompositeLayer:
4182 value=GetImageOption(_image_info,"compose");
4183 compose=OverCompositeOp; /* Default to Over */
4184 if (value != (const char *) NULL)
4185 compose=(CompositeOperator) ParseCommandOption(
4186 MagickComposeOptions,MagickFalse,value);
4188 /* Split image sequence at the first 'NULL:' image. */
4190 while (source != (Image *) NULL)
4192 source=GetNextImageInList(source);
4193 if ((source != (Image *) NULL) &&
4194 (LocaleCompare(source->magick,"NULL") == 0))
4197 if (source != (Image *) NULL)
4199 if ((GetPreviousImageInList(source) == (Image *) NULL) ||
4200 (GetNextImageInList(source) == (Image *) NULL))
4201 source=(Image *) NULL;
4203 { /* Separate the two lists, junk the null: image. */
4204 source=SplitImageList(source->previous);
4205 DeleteImageFromList(&source);
4208 if (source == (Image *) NULL)
4210 (void) ThrowMagickException(_exception,GetMagickModule(),
4211 OptionError,"MissingNullSeparator","layers Composite");
4214 /* Adjust offset with gravity and virtual canvas. */
4215 SetGeometry(_images,&geometry);
4216 (void) ParseAbsoluteGeometry(_images->geometry,&geometry);
4217 geometry.width=source->page.width != 0 ?
4218 source->page.width : source->columns;
4219 geometry.height=source->page.height != 0 ?
4220 source->page.height : source->rows;
4221 GravityAdjustGeometry(_images->page.width != 0 ?
4222 _images->page.width : _images->columns,
4223 _images->page.height != 0 ? _images->page.height :
4224 _images->rows,_images->gravity,&geometry);
4226 /* Compose the two image sequences together */
4227 CompositeLayers(_images,compose,source,geometry.x,geometry.y,
4229 source=DestroyImageList(source);
4235 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4239 if (LocaleCompare("map",option+1) == 0)
4241 CLIWandWarnReplaced("+remap");
4242 (void) RemapImages(_quantize_info,_images,(Image *) NULL,_exception);
4245 if (LocaleCompare("metric",option+1) == 0)
4247 if (LocaleCompare("morph",option+1) == 0)
4252 if (IsGeometry(arg1) == MagickFalse)
4253 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
4254 morph_image=MorphImages(_images,StringToUnsignedLong(arg1),
4256 if (morph_image == (Image *) NULL)
4258 _images=DestroyImageList(_images);
4259 _images=morph_image;
4262 if (LocaleCompare("mosaic",option+1) == 0)
4264 /* REDIRECTED to use -layers mosaic instead */
4265 (void) CLIListOperatorImages(cli_wand,"-layers",option+1,NULL);
4268 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4272 if (LocaleCompare("poly",option+1) == 0)
4280 /* convert argument string into an array of doubles */
4281 args = StringToArrayOfDoubles(arg1,&count,_exception);
4282 if (args == (double *) NULL )
4283 CLIWandExceptArgBreak(OptionError,"InvalidNumberList",option,arg1);
4284 new_images=PolynomialImage(_images,(size_t) (count >> 1),args,
4286 args=(double *) RelinquishMagickMemory(args);
4289 if (LocaleCompare("process",option+1) == 0)
4291 /* FUTURE: better parsing using ScriptToken() from string ??? */
4299 arguments=StringToArgv(arg1,&number_arguments);
4300 if (arguments == (char **) NULL)
4302 if (strchr(arguments[1],'=') != (char *) NULL)
4323 Support old style syntax, filter="-option arg1".
4325 assert(arg1 != (const char *) NULL);
4326 length=strlen(arg1);
4327 token=(char *) NULL;
4328 if (~length >= (MagickPathExtent-1))
4329 token=(char *) AcquireQuantumMemory(length+MagickPathExtent,
4331 if (token == (char *) NULL)
4335 token_info=AcquireTokenInfo();
4336 status=Tokenizer(token_info,0,token,length,arguments,"","=",
4337 "\"",'\0',&breaker,&next,"e);
4338 token_info=DestroyTokenInfo(token_info);
4344 argv=(&(arguments[next]));
4345 (void) InvokeDynamicImageFilter(token,&_images,1,&argv,
4348 token=DestroyString(token);
4351 (void) SubstituteString(&arguments[1],"-","");
4352 (void) InvokeDynamicImageFilter(arguments[1],&_images,
4353 number_arguments-2,(const char **) arguments+2,_exception);
4354 for (j=0; j < number_arguments; j++)
4355 arguments[j]=DestroyString(arguments[j]);
4356 arguments=(char **) RelinquishMagickMemory(arguments);
4359 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4363 if (LocaleCompare("remap",option+1) == 0)
4365 (void) RemapImages(_quantize_info,_images,(Image *) NULL,_exception);
4368 if (LocaleCompare("reverse",option+1) == 0)
4370 ReverseImageList(&_images);
4373 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4377 if (LocaleCompare("smush",option+1) == 0)
4379 /* FUTURE: this option needs more work to make better */
4383 if (IsGeometry(arg1) == MagickFalse)
4384 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
4385 offset=(ssize_t) StringToLong(arg1);
4386 new_images=SmushImages(_images,IsNormalOp,offset,_exception);
4389 if (LocaleCompare("subimage",option+1) == 0)
4407 base_image=GetImageFromList(_images,0);
4408 compare_image=GetImageFromList(_images,1);
4410 /* Comparision Metric */
4411 metric=UndefinedErrorMetric;
4412 value=GetImageOption(_image_info,"metric");
4413 if (value != (const char *) NULL)
4414 metric=(MetricType) ParseCommandOption(MagickMetricOptions,
4417 new_images=SimilarityImage(base_image,compare_image,metric,0.0,
4418 &offset,&similarity,_exception);
4420 if (new_images != (Image *) NULL)
4423 result[MagickPathExtent];
4425 (void) FormatLocaleString(result,MagickPathExtent,"%lf",
4427 (void) SetImageProperty(new_images,"subimage:similarity",result,
4429 (void) FormatLocaleString(result,MagickPathExtent,"%+ld",(long)
4431 (void) SetImageProperty(new_images,"subimage:x",result,
4433 (void) FormatLocaleString(result,MagickPathExtent,"%+ld",(long)
4435 (void) SetImageProperty(new_images,"subimage:y",result,
4437 (void) FormatLocaleString(result,MagickPathExtent,
4438 "%lux%lu%+ld%+ld",(unsigned long) offset.width,(unsigned long)
4439 offset.height,(long) offset.x,(long) offset.y);
4440 (void) SetImageProperty(new_images,"subimage:offset",result,
4445 if (LocaleCompare("swap",option+1) == 0)
4466 flags=ParseGeometry(arg1,&geometry_info);
4467 if ((flags & RhoValue) == 0)
4468 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
4469 index=(ssize_t) geometry_info.rho;
4470 if ((flags & SigmaValue) != 0)
4471 swap_index=(ssize_t) geometry_info.sigma;
4473 p=GetImageFromList(_images,index);
4474 q=GetImageFromList(_images,swap_index);
4475 if ((p == (Image *) NULL) || (q == (Image *) NULL)) {
4477 CLIWandExceptArgBreak(OptionError,"InvalidImageIndex",option,arg1)
4479 CLIWandExceptionBreak(OptionError,"TwoOrMoreImagesRequired",option);
4482 CLIWandExceptArgBreak(OptionError,"InvalidImageIndex",option,arg1);
4483 swap=CloneImage(p,0,0,MagickTrue,_exception);
4484 ReplaceImageInList(&p,CloneImage(q,0,0,MagickTrue,_exception));
4485 ReplaceImageInList(&q,swap);
4486 _images=GetFirstImageInList(q);
4489 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4492 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4495 /* clean up percent escape interpreted strings */
4497 arg1=DestroyString((char *)arg1);
4499 arg2=DestroyString((char *)arg2);
4501 /* if new image list generated, replace existing image list */
4502 if (new_images == (Image *) NULL)
4503 return(status == 0 ? MagickFalse : MagickTrue);
4504 _images=DestroyImageList(_images);
4505 _images=GetFirstImageInList(new_images);
4506 return(status == 0 ? MagickFalse : MagickTrue);
4512 #undef _quantize_info
4519 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4523 + C L I N o I m a g e O p e r a t i o n s %
4527 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4529 % CLINoImageOperator() Applies operations that may not actually need images
4532 % The classic operators of this type is "-read", which actually creates
4533 % images even when no images are present. Or image stack operators, which
4534 % can be applied (push or pop) to an empty image list.
4536 % Note that these operators may involve other special 'option' prefix
4537 % characters other than '-' or '+', namely parenthesis and braces.
4539 % The format of the CLINoImageOption method is:
4541 % void CLINoImageOption(MagickCLI *cli_wand,const char *option,
4542 % const char *arg1, const char *arg2)
4544 % A description of each parameter follows:
4546 % o cli_wand: the main CLI Wand to use. (sometimes not required)
4548 % o option: The special option (with any switch char) to process
4550 % o arg1 & arg2: Argument for option, if required
4551 % Currently arg2 is not used.
4554 WandPrivate void CLINoImageOperator(MagickCLI *cli_wand,
4555 const char *option,const char *arg1n,const char *arg2n)
4557 const char /* percent escaped versions of the args */
4561 #define _image_info (cli_wand->wand.image_info)
4562 #define _images (cli_wand->wand.images)
4563 #define _exception (cli_wand->wand.exception)
4564 #define _process_flags (cli_wand->process_flags)
4565 #define _option_type ((CommandOptionFlags) cli_wand->command->flags)
4566 #define IfNormalOp (*option=='-')
4567 #define IfPlusOp (*option!='-')
4569 assert(cli_wand != (MagickCLI *) NULL);
4570 assert(cli_wand->signature == MagickWandSignature);
4571 assert(cli_wand->wand.signature == MagickWandSignature);
4573 if (cli_wand->wand.debug != MagickFalse)
4574 (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(),
4575 "- NoImage Operator: %s \"%s\" \"%s\"", option,
4576 arg1n != (char *) NULL ? arg1n : "",
4577 arg2n != (char *) NULL ? arg2n : "");
4582 /* Interpret Percent Escapes in Arguments - using first image */
4583 if ( (((_process_flags & ProcessInterpretProperities) != 0 )
4584 || ((_option_type & AlwaysInterpretArgsFlag) != 0)
4585 ) && ((_option_type & NeverInterpretArgsFlag) == 0) ) {
4586 /* Interpret Percent escapes in argument 1 */
4587 if (arg1n != (char *) NULL) {
4588 arg1=InterpretImageProperties(_image_info,_images,arg1n,_exception);
4589 if (arg1 == (char *) NULL) {
4590 CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
4591 arg1=arg1n; /* use the given argument as is */
4594 if (arg2n != (char *) NULL) {
4595 arg2=InterpretImageProperties(_image_info,_images,arg2n,_exception);
4596 if (arg2 == (char *) NULL) {
4597 CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
4598 arg2=arg2n; /* use the given argument as is */
4602 #undef _process_flags
4605 do { /* break to exit code */
4607 No-op options (ignore these)
4609 if (LocaleCompare("noop",option+1) == 0) /* zero argument */
4611 if (LocaleCompare("sans",option+1) == 0) /* one argument */
4613 if (LocaleCompare("sans0",option+1) == 0) /* zero argument */
4615 if (LocaleCompare("sans1",option+1) == 0) /* one argument */
4617 if (LocaleCompare("sans2",option+1) == 0) /* two arguments */
4622 if ( ( LocaleCompare("read",option+1) == 0 ) ||
4623 ( LocaleCompare("--",option) == 0 ) ) {
4624 /* Do Glob filename Expansion for 'arg1' then read all images.
4626 * Expansion handles '@', '~', '*', and '?' meta-characters while ignoring
4627 * (but attaching to the filenames in the generated argument list) any
4628 * [...] read modifiers that may be present.
4630 * For example: It will expand '*.gif[20x20]' into a list such as
4631 * 'abc.gif[20x20]', 'foobar.gif[20x20]', 'xyzzy.gif[20x20]'
4633 * NOTE: In IMv6 this was done globally across all images. This
4634 * meant you could include IM options in '@filename' lists, but you
4635 * could not include comments. Doing it only for image read makes
4636 * it far more secure.
4638 * Note: arguments do not have percent escapes expanded for security
4646 argv = (char **) &arg1;
4648 /* Expand 'glob' expressions in the given filename.
4649 Expansion handles any 'coder:' prefix, or read modifiers attached
4650 to the filename, including them in the resulting expanded list.
4652 if (ExpandFilenames(&argc,&argv) == MagickFalse)
4653 CLIWandExceptArgBreak(ResourceLimitError,"MemoryAllocationFailed",
4654 option,GetExceptionMessage(errno));
4656 /* loop over expanded filename list, and read then all in */
4657 for (i=0; i < (ssize_t) argc; i++) {
4660 if (_image_info->ping != MagickFalse)
4661 new_images=PingImages(_image_info,argv[i],_exception);
4663 new_images=ReadImages(_image_info,argv[i],_exception);
4664 AppendImageToList(&_images, new_images);
4666 argv=DestroyStringList(argv); /* Destroy the Expanded Filename list */
4671 Note: Writing a empty image list is valid in specific cases
4673 if (LocaleCompare("write",option+1) == 0) {
4674 /* Note: arguments do not have percent escapes expanded */
4676 key[MagickPathExtent];
4684 /* Need images, unless a "null:" output coder is used */
4685 if ( _images == (Image *) NULL ) {
4686 if ( LocaleCompare(arg1,"null:") == 0 )
4688 CLIWandExceptArgBreak(OptionError,"NoImagesForWrite",option,arg1);
4691 (void) FormatLocaleString(key,MagickPathExtent,"cache:%s",arg1);
4692 (void) DeleteImageRegistry(key);
4693 write_images=_images;
4695 write_images=CloneImageList(_images,_exception);
4696 write_info=CloneImageInfo(_image_info);
4697 (void) WriteImages(write_info,write_images,arg1,_exception);
4698 write_info=DestroyImageInfo(write_info);
4700 write_images=DestroyImageList(write_images);
4704 Parenthesis and Brace operations
4706 if (LocaleCompare("(",option) == 0) {
4707 /* stack 'push' images */
4715 node=cli_wand->image_list_stack;
4716 for ( ; node != (Stack *) NULL; node=node->next)
4718 if ( size >= MAX_STACK_DEPTH )
4719 CLIWandExceptionBreak(OptionError,"ParenthesisNestedTooDeeply",option);
4720 node=(Stack *) AcquireMagickMemory(sizeof(*node));
4721 if (node == (Stack *) NULL)
4722 CLIWandExceptionBreak(ResourceLimitFatalError,
4723 "MemoryAllocationFailed",option);
4724 node->data = (void *)cli_wand->wand.images;
4725 node->next = cli_wand->image_list_stack;
4726 cli_wand->image_list_stack = node;
4727 cli_wand->wand.images = NewImageList();
4729 /* handle respect-parenthesis */
4730 if (IsStringTrue(GetImageOption(cli_wand->wand.image_info,
4731 "respect-parenthesis")) != MagickFalse)
4732 option="{"; /* fall-thru so as to push image settings too */
4735 /* fall thru to operation */
4737 if (LocaleCompare("{",option) == 0) {
4738 /* stack 'push' of image_info settings */
4746 node=cli_wand->image_info_stack;
4747 for ( ; node != (Stack *) NULL; node=node->next)
4749 if ( size >= MAX_STACK_DEPTH )
4750 CLIWandExceptionBreak(OptionError,"CurlyBracesNestedTooDeeply",option);
4751 node=(Stack *) AcquireMagickMemory(sizeof(*node));
4752 if (node == (Stack *) NULL)
4753 CLIWandExceptionBreak(ResourceLimitFatalError,
4754 "MemoryAllocationFailed",option);
4756 node->data = (void *)cli_wand->wand.image_info;
4757 node->next = cli_wand->image_info_stack;
4759 cli_wand->image_info_stack = node;
4760 cli_wand->wand.image_info = CloneImageInfo(cli_wand->wand.image_info);
4761 if (cli_wand->wand.image_info == (ImageInfo *) NULL) {
4762 CLIWandException(ResourceLimitFatalError,"MemoryAllocationFailed",
4764 cli_wand->wand.image_info = (ImageInfo *)node->data;
4765 node = (Stack *)RelinquishMagickMemory(node);
4771 if (LocaleCompare(")",option) == 0) {
4772 /* pop images from stack */
4776 node = (Stack *)cli_wand->image_list_stack;
4777 if ( node == (Stack *) NULL)
4778 CLIWandExceptionBreak(OptionError,"UnbalancedParenthesis",option);
4779 cli_wand->image_list_stack = node->next;
4781 AppendImageToList((Image **)&node->data,cli_wand->wand.images);
4782 cli_wand->wand.images= (Image *)node->data;
4783 node = (Stack *)RelinquishMagickMemory(node);
4785 /* handle respect-parenthesis - of the previous 'pushed' settings */
4786 node = cli_wand->image_info_stack;
4787 if ( node != (Stack *) NULL)
4789 if (IsStringTrue(GetImageOption(
4790 cli_wand->wand.image_info,"respect-parenthesis")) != MagickFalse)
4791 option="}"; /* fall-thru so as to pop image settings too */
4797 /* fall thru to next if */
4799 if (LocaleCompare("}",option) == 0) {
4800 /* pop image_info settings from stack */
4804 node = (Stack *)cli_wand->image_info_stack;
4805 if ( node == (Stack *) NULL)
4806 CLIWandExceptionBreak(OptionError,"UnbalancedCurlyBraces",option);
4807 cli_wand->image_info_stack = node->next;
4809 (void) DestroyImageInfo(cli_wand->wand.image_info);
4810 cli_wand->wand.image_info = (ImageInfo *)node->data;
4811 node = (Stack *)RelinquishMagickMemory(node);
4813 GetDrawInfo(cli_wand->wand.image_info, cli_wand->draw_info);
4814 cli_wand->quantize_info=DestroyQuantizeInfo(cli_wand->quantize_info);
4815 cli_wand->quantize_info=AcquireQuantizeInfo(cli_wand->wand.image_info);
4819 if (LocaleCompare("print",option+1) == 0)
4821 (void) FormatLocaleFile(stdout,"%s",arg1);
4824 if (LocaleCompare("set",option+1) == 0)
4826 /* Settings are applied to each image in memory in turn (if any).
4827 While a option: only need to be applied once globally.
4829 NOTE: rguments have not been automatically percent expaneded
4832 /* escape the 'key' once only, using first image. */
4833 arg1=InterpretImageProperties(_image_info,_images,arg1n,_exception);
4834 if (arg1 == (char *) NULL)
4835 CLIWandExceptionBreak(OptionWarning,"InterpretPropertyFailure",
4838 if (LocaleNCompare(arg1,"registry:",9) == 0)
4842 (void) DeleteImageRegistry(arg1+9);
4843 arg1=DestroyString((char *)arg1);
4846 arg2=InterpretImageProperties(_image_info,_images,arg2n,_exception);
4847 if (arg2 == (char *) NULL) {
4848 arg1=DestroyString((char *)arg1);
4849 CLIWandExceptionBreak(OptionWarning,"InterpretPropertyFailure",
4852 (void) SetImageRegistry(StringRegistryType,arg1+9,arg2,_exception);
4853 arg1=DestroyString((char *)arg1);
4854 arg2=DestroyString((char *)arg2);
4857 if (LocaleNCompare(arg1,"option:",7) == 0)
4859 /* delete equivelent artifact from all images (if any) */
4860 if (_images != (Image *) NULL)
4862 MagickResetIterator(&cli_wand->wand);
4863 while (MagickNextImage(&cli_wand->wand) != MagickFalse)
4864 (void) DeleteImageArtifact(_images,arg1+7);
4865 MagickResetIterator(&cli_wand->wand);
4867 /* now set/delete the global option as needed */
4868 /* FUTURE: make escapes in a global 'option:' delayed */
4872 arg2=InterpretImageProperties(_image_info,_images,arg2n,_exception);
4873 if (arg2 == (char *) NULL)
4874 CLIWandExceptionBreak(OptionWarning,
4875 "InterpretPropertyFailure",option);
4877 (void) SetImageOption(_image_info,arg1+7,arg2);
4878 arg1=DestroyString((char *)arg1);
4879 arg2=DestroyString((char *)arg2);
4882 /* Set Artifacts/Properties/Attributes all images (required) */
4883 if ( _images == (Image *) NULL )
4884 CLIWandExceptArgBreak(OptionWarning,"NoImageForProperty",option,arg1);
4886 MagickResetIterator(&cli_wand->wand);
4887 while (MagickNextImage(&cli_wand->wand) != MagickFalse)
4892 arg2=InterpretImageProperties(_image_info,_images,arg2n,_exception);
4893 if (arg2 == (char *) NULL)
4894 CLIWandExceptionBreak(OptionWarning,
4895 "InterpretPropertyFailure",option);
4897 if (LocaleNCompare(arg1,"artifact:",9) == 0)
4898 (void) SetImageArtifact(_images,arg1+9,arg2);
4899 else if (LocaleNCompare(arg1,"property:",9) == 0)
4900 (void) SetImageProperty(_images,arg1+9,arg2,_exception);
4902 (void) SetImageProperty(_images,arg1,arg2,_exception);
4903 arg2=DestroyString((char *)arg2);
4905 MagickResetIterator(&cli_wand->wand);
4906 arg1=DestroyString((char *)arg1);
4909 if (LocaleCompare("clone",option+1) == 0) {
4914 arg1=AcquireString("-1");
4915 if (IsSceneGeometry(arg1,MagickFalse) == MagickFalse)
4916 CLIWandExceptionBreak(OptionError,"InvalidArgument",option);
4917 if ( cli_wand->image_list_stack == (Stack *) NULL)
4918 CLIWandExceptionBreak(OptionError,"UnableToCloneImage",option);
4919 new_images = (Image *)cli_wand->image_list_stack->data;
4920 if (new_images == (Image *) NULL)
4921 CLIWandExceptionBreak(OptionError,"UnableToCloneImage",option);
4922 new_images=CloneImages(new_images,arg1,_exception);
4923 if (new_images == (Image *) NULL)
4924 CLIWandExceptionBreak(OptionError,"NoSuchImage",option);
4925 AppendImageToList(&_images,new_images);
4929 Informational Operations.
4931 Note that these do not require either a cli-wand or images!
4932 Though currently a cli-wand much be provided regardless.
4934 if (LocaleCompare("version",option+1) == 0)
4936 ListMagickVersion(stdout);
4939 if (LocaleCompare("list",option+1) == 0) {
4941 FUTURE: This 'switch' should really be part of MagickCore
4946 list=ParseCommandOption(MagickListOptions,MagickFalse,arg1);
4948 CLIWandExceptionArg(OptionError,"UnrecognizedListType",option,arg1);
4953 case MagickCoderOptions:
4955 (void) ListCoderInfo((FILE *) NULL,_exception);
4958 case MagickColorOptions:
4960 (void) ListColorInfo((FILE *) NULL,_exception);
4963 case MagickConfigureOptions:
4965 (void) ListConfigureInfo((FILE *) NULL,_exception);
4968 case MagickDelegateOptions:
4970 (void) ListDelegateInfo((FILE *) NULL,_exception);
4973 case MagickFontOptions:
4975 (void) ListTypeInfo((FILE *) NULL,_exception);
4978 case MagickFormatOptions:
4979 (void) ListMagickInfo((FILE *) NULL,_exception);
4981 case MagickLocaleOptions:
4982 (void) ListLocaleInfo((FILE *) NULL,_exception);
4984 case MagickLogOptions:
4985 (void) ListLogInfo((FILE *) NULL,_exception);
4987 case MagickMagicOptions:
4988 (void) ListMagicInfo((FILE *) NULL,_exception);
4990 case MagickMimeOptions:
4991 (void) ListMimeInfo((FILE *) NULL,_exception);
4993 case MagickModuleOptions:
4994 (void) ListModuleInfo((FILE *) NULL,_exception);
4996 case MagickPolicyOptions:
4997 (void) ListPolicyInfo((FILE *) NULL,_exception);
4999 case MagickResourceOptions:
5000 (void) ListMagickResourceInfo((FILE *) NULL,_exception);
5002 case MagickThresholdOptions:
5003 (void) ListThresholdMaps((FILE *) NULL,_exception);
5006 (void) ListCommandOptions((FILE *) NULL,(CommandOption) list,
5013 CLIWandException(OptionError,"UnrecognizedOption",option);
5015 DisableMSCWarning(4127)
5016 } while (0); /* break to exit code. */
5019 /* clean up percent escape interpreted strings */
5021 arg1=DestroyString((char *)arg1);
5023 arg2=DestroyString((char *)arg2);
5033 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5037 + C L I O p t i o n %
5041 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5043 % CLIOption() Processes the given option using the given CLI Magick Wand.
5044 % The option arguments can be variable in number, though at this time no more
5045 % that two is actually used by any option (this may change). Excess options
5046 % are simply ignored.
5048 % If the cli_wand->command pointer is non-null, then it is assumed that the
5049 % option has already been search for up from the CommandOptions[] table in
5050 % "MagickCore/options.c" using GetCommandOptionInfo(). If not set this
5051 % routine will do the lookup instead. The pointer is reset afterward.
5053 % This action allows the caller to lookup and pre-handle any 'special'
5054 % options, (such as implicit reads) before calling this general option
5055 % handler to deal with 'standard' command line options.
5057 % The format of the CLIOption method is:
5059 % void CLIOption(MagickCLI *cli_wand,const char *option, ...)
5061 % A description of each parameter follows:
5063 % o cli_wand: the main CLI Wand to use.
5065 % o option: The special option (with any switch char) to process
5067 % o args: any required arguments for an option (variable number)
5071 % CLIoption(cli_wand,"-read","rose:");
5072 % CLIoption(cli_wand,"-virtual-pixel","transparent");
5073 % CLIoption(cli_wand,"-distort","SRT:","30");
5074 % CLIoption(cli_wand,"-write","rotated_rose.png");
5077 WandExport void CLIOption(MagickCLI *cli_wand,const char *option,...)
5079 const char /* extracted option args from args */
5086 assert(cli_wand != (MagickCLI *) NULL);
5087 assert(cli_wand->signature == MagickWandSignature);
5088 assert(cli_wand->wand.signature == MagickWandSignature);
5090 do { /* Break Code Block for error handling */
5092 /* get information about option */
5093 if ( cli_wand->command == (const OptionInfo *) NULL )
5094 cli_wand->command = GetCommandOptionInfo(option);
5096 (void) FormatLocaleFile(stderr, "CLIOption \"%s\" matched \"%s\"\n",
5097 option, cli_wand->command->mnemonic );
5099 option_type=(CommandOptionFlags) cli_wand->command->flags;
5101 if ( option_type == UndefinedOptionFlag )
5102 CLIWandExceptionReturn(OptionFatalError,"UnrecognizedOption",option);
5104 assert( LocaleCompare(cli_wand->command->mnemonic,option) == 0 );
5106 /* deprecated options */
5107 if ( (option_type & DeprecateOptionFlag) != 0 )
5108 CLIWandExceptionBreak(OptionError,"DeprecatedOptionNoCode",option);
5110 /* options that this module does not handle */
5111 if ((option_type & (SpecialOptionFlag|GenesisOptionFlag)) != 0 )
5112 CLIWandExceptionBreak(OptionFatalError,"InvalidUseOfOption",option);
5114 /* Get argument strings from VarArgs
5115 How can you determine if enough arguments was supplied?
5116 What happens if not enough arguments were supplied?
5119 count = (size_t) cli_wand->command->type;
5124 va_start(operands,option);
5128 arg1=(const char *) va_arg(operands, const char *);
5130 arg2=(const char *) va_arg(operands, const char *);
5134 (void) FormatLocaleFile(stderr,
5135 "CLIOption: \"%s\" Count: %ld Flags: %04x Args: \"%s\" \"%s\"\n",
5136 option,(long) count,option_type,arg1,arg2);
5141 Call the appropriate option handler
5144 /* FUTURE: this is temporary - get 'settings' to handle distribution of
5145 settings to images attributes,proprieties,artifacts */
5146 if ( cli_wand->wand.images != (Image *) NULL )
5147 (void) SyncImagesSettings(cli_wand->wand.image_info,cli_wand->wand.images,
5148 cli_wand->wand.exception);
5150 if ( (option_type & SettingOptionFlags) != 0 ) {
5151 CLISettingOptionInfo(cli_wand, option, arg1, arg2);
5152 // FUTURE: Sync Specific Settings into Image Properities (not global)
5155 /* Operators that do not need images - read, write, stack, clone */
5156 if ((option_type & NoImageOperatorFlag) != 0)
5157 CLINoImageOperator(cli_wand, option, arg1, arg2);
5159 /* FUTURE: The not a setting part below is a temporary hack due to
5160 * some options being both a Setting and a Simple operator.
5161 * Specifically -monitor, -depth, and -colorspace */
5162 if ( cli_wand->wand.images == (Image *) NULL )
5163 if ( ((option_type & (SimpleOperatorFlag|ListOperatorFlag)) != 0 ) &&
5164 ((option_type & SettingOptionFlags) == 0 )) /* temp hack */
5165 CLIWandExceptionBreak(OptionError,"NoImagesFound",option);
5167 /* Operators which loop of individual images, simply */
5168 if ( (option_type & SimpleOperatorFlag) != 0 &&
5169 cli_wand->wand.images != (Image *) NULL) /* temp hack */
5171 ExceptionInfo *exception=AcquireExceptionInfo();
5172 (void) CLISimpleOperatorImages(cli_wand, option, arg1, arg2,exception);
5173 exception=DestroyExceptionInfo(exception);
5176 /* Operators that work on the image list as a whole */
5177 if ( (option_type & ListOperatorFlag) != 0 )
5178 (void) CLIListOperatorImages(cli_wand, option, arg1, arg2);
5180 DisableMSCWarning(4127)
5181 } while (0); /* end Break code block */
5184 cli_wand->command = (const OptionInfo *) NULL; /* prevent re-use later */