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-2018 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 % https://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/operation.h"
55 #include "MagickWand/wand.h"
56 #include "MagickWand/wandcli.h"
57 #include "MagickWand/wandcli-private.h"
58 #include "MagickCore/composite-private.h"
59 #include "MagickCore/image-private.h"
60 #include "MagickCore/monitor-private.h"
61 #include "MagickCore/pixel-private.h"
62 #include "MagickCore/string-private.h"
63 #include "MagickCore/thread-private.h"
69 MogrifyAlphaColor[] = "#bdbdbd", /* slightly darker gray */
70 MogrifyBackgroundColor[] = "#fff", /* white */
71 MogrifyBorderColor[] = "#dfdfdf"; /* sRGB gray */
76 #define USE_WAND_METHODS 1
77 #define MAX_STACK_DEPTH 32
78 #define UNDEFINED_COMPRESSION_QUALITY 0UL
80 /* FUTURE: why is this default so specific? */
81 #define DEFAULT_DISSIMILARITY_THRESHOLD "0.31830988618379067154"
83 /* For Debugging Geometry Input */
84 #define ReportGeometry(flags,info) \
85 (void) FormatLocaleFile(stderr, "Geometry = 0x%04X : %lg x %lg %+lg %+lg\n", \
86 flags, info.rho, info.sigma, info.xi, info.psi )
89 ** Function to report on the progress of image operations
91 static MagickBooleanType MonitorProgress(const char *text,
92 const MagickOffsetType offset,const MagickSizeType extent,
93 void *wand_unused(client_data))
96 message[MagickPathExtent],
97 tag[MagickPathExtent];
105 magick_unreferenced(client_data);
107 if ((extent <= 1) || (offset < 0) || (offset >= (MagickOffsetType) extent))
109 if ((offset != (MagickOffsetType) (extent-1)) && ((offset % 50) != 0))
111 (void) CopyMagickString(tag,text,MagickPathExtent);
113 if (p != (char *) NULL)
115 (void) FormatLocaleString(message,MagickPathExtent,"Monitor/%s",tag);
116 locale_message=GetLocaleMessage(message);
117 if (locale_message == message)
119 if (p == (char *) NULL)
120 (void) FormatLocaleFile(stderr,"%s: %ld of %lu, %02ld%% complete\r",
121 locale_message,(long) offset,(unsigned long) extent,(long)
122 (100L*offset/(extent-1)));
124 (void) FormatLocaleFile(stderr,"%s[%s]: %ld of %lu, %02ld%% complete\r",
125 locale_message,p+1,(long) offset,(unsigned long) extent,(long)
126 (100L*offset/(extent-1)));
127 if (offset == (MagickOffsetType) (extent-1))
128 (void) FormatLocaleFile(stderr,"\n");
129 (void) fflush(stderr);
134 ** GetImageCache() will read an image into a image cache if not already
135 ** present then return the image that is in the cache under that filename.
137 static inline Image *GetImageCache(const ImageInfo *image_info,const char *path,
138 ExceptionInfo *exception)
141 key[MagickPathExtent];
152 (void) FormatLocaleString(key,MagickPathExtent,"cache:%s",path);
153 sans_exception=AcquireExceptionInfo();
154 image=(Image *) GetImageRegistry(ImageRegistryType,key,sans_exception);
155 sans_exception=DestroyExceptionInfo(sans_exception);
156 if (image != (Image *) NULL)
158 read_info=CloneImageInfo(image_info);
159 if (path != (const char *) NULL)
160 (void) CopyMagickString(read_info->filename,path,MagickPathExtent);
161 image=ReadImage(read_info,exception);
162 read_info=DestroyImageInfo(read_info);
163 if (image != (Image *) NULL)
164 (void) SetImageRegistry(ImageRegistryType,key,image,exception);
169 SparseColorOption() parse the complex -sparse-color argument into an
170 an array of floating point values than call SparseColorImage().
171 Argument is a complex mix of floating-point pixel coodinates, and color
172 specifications (or direct floating point numbers). The number of floats
173 needed to represent a color varies depending on the current channel
176 This really should be in MagickCore, so that other API's can make use of it.
178 static Image *SparseColorOption(const Image *image,
179 const SparseColorMethod method,const char *arguments,ExceptionInfo *exception)
182 token[MagickPathExtent];
206 assert(image != (Image *) NULL);
207 assert(image->signature == MagickCoreSignature);
208 if (image->debug != MagickFalse)
209 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
210 assert(exception != (ExceptionInfo *) NULL);
211 assert(exception->signature == MagickCoreSignature);
213 Limit channels according to image
214 add up number of values needed per color.
217 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
219 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
221 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
223 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
224 (image->colorspace == CMYKColorspace))
226 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
227 image->alpha_trait != UndefinedPixelTrait)
231 Read string, to determine number of arguments needed,
237 GetNextToken(p,&p,MagickPathExtent,token);
238 if ( token[0] == ',' ) continue;
239 if ( isalpha((int) token[0]) || token[0] == '#' )
240 x += number_colors; /* color argument found */
242 x++; /* floating point argument */
244 /* control points and color values */
245 if ((x % (2+number_colors)) != 0)
247 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
248 "InvalidArgument","'%s': %s", "sparse-color",
249 "Invalid number of Arguments");
250 return( (Image *) NULL);
255 /* Allocate and fill in the floating point arguments */
256 sparse_arguments=(double *) AcquireQuantumMemory(number_arguments,
257 sizeof(*sparse_arguments));
258 if (sparse_arguments == (double *) NULL) {
259 (void) ThrowMagickException(exception,GetMagickModule(),ResourceLimitError,
260 "MemoryAllocationFailed","%s","SparseColorOption");
261 return( (Image *) NULL);
263 (void) memset(sparse_arguments,0,number_arguments*
264 sizeof(*sparse_arguments));
267 while( *p != '\0' && x < number_arguments ) {
269 token[0]=','; while ( token[0] == ',' ) GetNextToken(p,&p,MagickPathExtent,token);
270 if ( token[0] == '\0' ) break;
271 if ( isalpha((int) token[0]) || token[0] == '#' ) {
272 (void) ThrowMagickException(exception,GetMagickModule(),
273 OptionError, "InvalidArgument", "'%s': %s", "sparse-color",
274 "Color found, instead of X-coord");
278 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
280 token[0]=','; while ( token[0] == ',' ) GetNextToken(p,&p,MagickPathExtent,token);
281 if ( token[0] == '\0' ) break;
282 if ( isalpha((int) token[0]) || token[0] == '#' ) {
283 (void) ThrowMagickException(exception,GetMagickModule(),
284 OptionError, "InvalidArgument", "'%s': %s", "sparse-color",
285 "Color found, instead of Y-coord");
289 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
290 /* color name or function given in string argument */
291 token[0]=','; while ( token[0] == ',' ) GetNextToken(p,&p,MagickPathExtent,token);
292 if ( token[0] == '\0' ) break;
293 if ( isalpha((int) token[0]) || token[0] == '#' ) {
294 /* Color string given */
295 (void) QueryColorCompliance(token,AllCompliance,&color,
297 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
298 sparse_arguments[x++] = QuantumScale*color.red;
299 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
300 sparse_arguments[x++] = QuantumScale*color.green;
301 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
302 sparse_arguments[x++] = QuantumScale*color.blue;
303 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
304 (image->colorspace == CMYKColorspace))
305 sparse_arguments[x++] = QuantumScale*color.black;
306 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
307 image->alpha_trait != UndefinedPixelTrait)
308 sparse_arguments[x++] = QuantumScale*color.alpha;
311 /* Colors given as a set of floating point values - experimental */
312 /* NB: token contains the first floating point value to use! */
313 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
315 while ( token[0] == ',' ) GetNextToken(p,&p,MagickPathExtent,token);
316 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
318 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
319 token[0] = ','; /* used this token - get another */
321 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
323 while ( token[0] == ',' ) GetNextToken(p,&p,MagickPathExtent,token);
324 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
326 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
327 token[0] = ','; /* used this token - get another */
329 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
331 while ( token[0] == ',' ) GetNextToken(p,&p,MagickPathExtent,token);
332 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
334 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
335 token[0] = ','; /* used this token - get another */
337 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
338 (image->colorspace == CMYKColorspace))
340 while ( token[0] == ',' ) GetNextToken(p,&p,MagickPathExtent,token);
341 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
343 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
344 token[0] = ','; /* used this token - get another */
346 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
347 image->alpha_trait != UndefinedPixelTrait)
349 while ( token[0] == ',' ) GetNextToken(p,&p,MagickPathExtent,token);
350 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
352 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
353 token[0] = ','; /* used this token - get another */
357 if (error != MagickFalse)
359 sparse_arguments=(double *) RelinquishMagickMemory(sparse_arguments);
360 return((Image *) NULL);
362 if (number_arguments != x)
364 sparse_arguments=(double *) RelinquishMagickMemory(sparse_arguments);
365 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
366 "InvalidArgument","'%s': %s","sparse-color","Argument Parsing Error");
367 return((Image *) NULL);
369 /* Call the Sparse Color Interpolation function with the parsed arguments */
370 sparse_image=SparseColorImage(image,method,number_arguments,sparse_arguments,
372 sparse_arguments=(double *) RelinquishMagickMemory(sparse_arguments);
373 return( sparse_image );
377 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
381 % C L I S e t t i n g O p t i o n I n f o %
385 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
387 % CLISettingOptionInfo() applies a single settings option into a CLI wand
388 % holding the image_info, draw_info, quantize_info structures that will be
389 % used when processing the images.
391 % These options do no require images to be present in the CLI wand for them
392 % to be able to be set, in which case they will generally be applied to image
393 % that are read in later
395 % Options handled by this function are listed in CommandOptions[] of
396 % "option.c" that is one of "SettingOptionFlags" option flags.
398 % The format of the CLISettingOptionInfo method is:
400 % void CLISettingOptionInfo(MagickCLI *cli_wand,
401 % const char *option, const char *arg1, const char *arg2)
403 % A description of each parameter follows:
405 % o cli_wand: structure holding settings to be applied
407 % o option: The option string to be set
409 % o arg1, arg2: optional argument strings to the operation
410 % arg2 is currently only used by "-limit"
413 WandPrivate void CLISettingOptionInfo(MagickCLI *cli_wand,
414 const char *option,const char *arg1n, const char *arg2n)
417 parse; /* option argument parsing (string to value table lookup) */
419 const char /* percent escaped versions of the args */
423 #define _image_info (cli_wand->wand.image_info)
424 #define _image (cli_wand->wand.images)
425 #define _exception (cli_wand->wand.exception)
426 #define _draw_info (cli_wand->draw_info)
427 #define _quantize_info (cli_wand->quantize_info)
428 #define IfSetOption (*option=='-')
429 #define ArgBoolean IfSetOption ? MagickTrue : MagickFalse
430 #define ArgBooleanNot IfSetOption ? MagickFalse : MagickTrue
431 #define ArgBooleanString (IfSetOption?"true":"false")
432 #define ArgOption(def) (IfSetOption?arg1:(const char *)(def))
434 assert(cli_wand != (MagickCLI *) NULL);
435 assert(cli_wand->signature == MagickWandSignature);
436 assert(cli_wand->wand.signature == MagickWandSignature);
438 if (cli_wand->wand.debug != MagickFalse)
439 (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(),
440 "- Setting Option: %s \"%s\" \"%s\"", option,arg1n,arg2n);
446 #define _process_flags (cli_wand->process_flags)
447 #define _option_type ((CommandOptionFlags) cli_wand->command->flags)
448 /* Interpret Percent Escapes in Arguments - using first image */
449 if ( (((_process_flags & ProcessInterpretProperities) != 0 )
450 || ((_option_type & AlwaysInterpretArgsFlag) != 0)
451 ) && ((_option_type & NeverInterpretArgsFlag) == 0) ) {
452 /* Interpret Percent escapes in argument 1 */
453 if (arg1n != (char *) NULL) {
454 arg1=InterpretImageProperties(_image_info,_image,arg1n,_exception);
455 if (arg1 == (char *) NULL) {
456 CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
457 arg1=arg1n; /* use the given argument as is */
460 if (arg2n != (char *) NULL) {
461 arg2=InterpretImageProperties(_image_info,_image,arg2n,_exception);
462 if (arg2 == (char *) NULL) {
463 CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
464 arg2=arg2n; /* use the given argument as is */
468 #undef _process_flags
476 if (LocaleCompare("adjoin",option+1) == 0)
478 _image_info->adjoin = ArgBoolean;
481 if (LocaleCompare("affine",option+1) == 0)
483 CLIWandWarnReplaced("-draw 'affine ...'");
485 (void) ParseAffineGeometry(arg1,&_draw_info->affine,_exception);
487 GetAffineMatrix(&_draw_info->affine);
490 if (LocaleCompare("antialias",option+1) == 0)
492 _image_info->antialias =
493 _draw_info->stroke_antialias =
494 _draw_info->text_antialias = ArgBoolean;
497 if (LocaleCompare("attenuate",option+1) == 0)
499 if (IfSetOption && (IsGeometry(arg1) == MagickFalse))
500 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
501 (void) SetImageOption(_image_info,option+1,ArgOption("1.0"));
504 if (LocaleCompare("authenticate",option+1) == 0)
506 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
509 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
513 if (LocaleCompare("background",option+1) == 0)
515 /* FUTURE: both _image_info attribute & ImageOption in use!
516 _image_info only used directly for generating new images.
517 SyncImageSettings() used to set per-image attribute.
519 FUTURE: if _image_info->background_color is not set then
520 we should fall back to per-image background_color
522 At this time -background will 'wipe out' the per-image
525 Better error handling of QueryColorCompliance() needed.
527 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
528 (void) QueryColorCompliance(ArgOption(MogrifyBackgroundColor),AllCompliance,
529 &_image_info->background_color,_exception);
532 if (LocaleCompare("bias",option+1) == 0)
534 /* FUTURE: bias OBSOLETED, replaced by Artifact "convolve:bias"
535 as it is actually rarely used except in direct convolve operations
536 Usage outside a direct convolve operation is actally non-sensible!
538 SyncImageSettings() used to set per-image attribute.
540 if (IfSetOption && (IsGeometry(arg1) == MagickFalse))
541 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
542 (void) SetImageOption(_image_info,"convolve:bias",ArgOption(NULL));
545 if (LocaleCompare("black-point-compensation",option+1) == 0)
547 /* Used as a image chromaticity setting
548 SyncImageSettings() used to set per-image attribute.
550 (void) SetImageOption(_image_info,option+1,ArgBooleanString);
553 if (LocaleCompare("blue-primary",option+1) == 0)
555 /* Image chromaticity X,Y NB: Y=X if Y not defined
556 Used by many coders including PNG
557 SyncImageSettings() used to set per-image attribute.
559 arg1=ArgOption("0.0");
560 if (IsGeometry(arg1) == MagickFalse)
561 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
562 (void) SetImageOption(_image_info,option+1,arg1);
565 if (LocaleCompare("bordercolor",option+1) == 0)
567 /* FUTURE: both _image_info attribute & ImageOption in use!
568 SyncImageSettings() used to set per-image attribute.
569 Better error checking of QueryColorCompliance().
573 (void) SetImageOption(_image_info,option+1,arg1);
574 (void) QueryColorCompliance(arg1,AllCompliance,
575 &_image_info->border_color,_exception);
576 (void) QueryColorCompliance(arg1,AllCompliance,
577 &_draw_info->border_color,_exception);
580 (void) DeleteImageOption(_image_info,option+1);
581 (void) QueryColorCompliance(MogrifyBorderColor,AllCompliance,
582 &_image_info->border_color,_exception);
583 (void) QueryColorCompliance(MogrifyBorderColor,AllCompliance,
584 &_draw_info->border_color,_exception);
587 if (LocaleCompare("box",option+1) == 0)
589 CLIWandWarnReplaced("-undercolor");
590 CLISettingOptionInfo(cli_wand,"-undercolor",arg1, arg2);
593 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
597 if (LocaleCompare("cache",option+1) == 0)
602 if (IfSetOption && (IsGeometry(arg1) == MagickFalse))
603 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
604 limit=MagickResourceInfinity;
605 if (LocaleCompare("unlimited",arg1) != 0)
606 limit=(MagickSizeType) SiPrefixToDoubleInterval(arg1,100.0);
607 (void) SetMagickResourceLimit(MemoryResource,limit);
608 (void) SetMagickResourceLimit(MapResource,2*limit);
611 if (LocaleCompare("caption",option+1) == 0)
613 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
616 if (LocaleCompare("colorspace",option+1) == 0)
618 /* Setting used for new images via AquireImage()
619 But also used as a SimpleImageOperator
620 Undefined colorspace means don't modify images on
621 read or as a operation */
622 parse=ParseCommandOption(MagickColorspaceOptions,MagickFalse,
623 ArgOption("undefined"));
625 CLIWandExceptArgBreak(OptionError,"UnrecognizedColorspace",option,
627 _image_info->colorspace=(ColorspaceType) parse;
630 if (LocaleCompare("comment",option+1) == 0)
632 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
635 if (LocaleCompare("compose",option+1) == 0)
637 /* FUTURE: _image_info should be used,
638 SyncImageSettings() used to set per-image attribute. - REMOVE
640 This setting should NOT be used to set image 'compose'
641 "-layer" operators shoud use _image_info if defined otherwise
642 they should use a per-image compose setting.
644 parse = ParseCommandOption(MagickComposeOptions,MagickFalse,
645 ArgOption("undefined"));
647 CLIWandExceptArgBreak(OptionError,"UnrecognizedComposeOperator",
649 _image_info->compose=(CompositeOperator) parse;
650 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
653 if (LocaleCompare("compress",option+1) == 0)
655 /* FUTURE: What should be used? _image_info or ImageOption ???
656 The former is more efficent, but Crisy prefers the latter!
657 SyncImageSettings() used to set per-image attribute.
659 The coders appears to use _image_info, not Image_Option
660 however the image attribute (for save) is set from the
663 Note that "undefined" is a different setting to "none".
665 parse = ParseCommandOption(MagickCompressOptions,MagickFalse,
666 ArgOption("undefined"));
668 CLIWandExceptArgBreak(OptionError,"UnrecognizedImageCompression",
670 _image_info->compression=(CompressionType) parse;
671 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
674 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
678 if (LocaleCompare("debug",option+1) == 0)
680 /* SyncImageSettings() used to set per-image attribute. */
681 arg1=ArgOption("none");
682 parse = ParseCommandOption(MagickLogEventOptions,MagickFalse,arg1);
684 CLIWandExceptArgBreak(OptionError,"UnrecognizedEventType",
686 (void) SetLogEventMask(arg1);
687 _image_info->debug=IsEventLogging(); /* extract logging*/
688 cli_wand->wand.debug=IsEventLogging();
691 if (LocaleCompare("define",option+1) == 0)
693 if (LocaleNCompare(arg1,"registry:",9) == 0)
696 (void) DefineImageRegistry(StringRegistryType,arg1+9,_exception);
698 (void) DeleteImageRegistry(arg1+9);
701 /* DefineImageOption() equals SetImageOption() but with '=' */
703 (void) DefineImageOption(_image_info,arg1);
704 else if (DeleteImageOption(_image_info,arg1) == MagickFalse)
705 CLIWandExceptArgBreak(OptionError,"NoSuchOption",option,arg1);
708 if (LocaleCompare("delay",option+1) == 0)
710 /* Only used for new images via AcquireImage()
711 FUTURE: Option should also be used for "-morph" (color morphing)
714 if (IsGeometry(arg1) == MagickFalse)
715 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
716 (void) SetImageOption(_image_info,option+1,arg1);
719 if (LocaleCompare("density",option+1) == 0)
721 /* FUTURE: strings used in _image_info attr and _draw_info!
722 Basically as density can be in a XxY form!
724 SyncImageSettings() used to set per-image attribute.
726 if (IfSetOption && (IsGeometry(arg1) == MagickFalse))
727 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
728 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
729 (void) CloneString(&_image_info->density,ArgOption(NULL));
730 (void) CloneString(&_draw_info->density,_image_info->density);
733 if (LocaleCompare("depth",option+1) == 0)
735 /* This is also a SimpleImageOperator! for 8->16 vaule trunc !!!!
736 SyncImageSettings() used to set per-image attribute.
738 if (IfSetOption && (IsGeometry(arg1) == MagickFalse))
739 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
740 _image_info->depth=IfSetOption?StringToUnsignedLong(arg1)
741 :MAGICKCORE_QUANTUM_DEPTH;
744 if (LocaleCompare("direction",option+1) == 0)
746 /* Image Option is only used to set _draw_info */
747 arg1=ArgOption("undefined");
748 parse = ParseCommandOption(MagickDirectionOptions,MagickFalse,arg1);
750 CLIWandExceptArgBreak(OptionError,"UnrecognizedDirectionType",
752 _draw_info->direction=(DirectionType) parse;
753 (void) SetImageOption(_image_info,option+1,arg1);
756 if (LocaleCompare("display",option+1) == 0)
758 (void) CloneString(&_image_info->server_name,ArgOption(NULL));
759 (void) CloneString(&_draw_info->server_name,_image_info->server_name);
762 if (LocaleCompare("dispose",option+1) == 0)
764 /* only used in setting new images */
765 arg1=ArgOption("undefined");
766 parse = ParseCommandOption(MagickDisposeOptions,MagickFalse,arg1);
768 CLIWandExceptArgBreak(OptionError,"UnrecognizedDisposeMethod",
770 (void) SetImageOption(_image_info,option+1,ArgOption("undefined"));
773 if (LocaleCompare("dissimilarity-threshold",option+1) == 0)
775 /* FUTURE: this is only used by CompareImages() which is used
776 only by the "compare" CLI program at this time. */
777 arg1=ArgOption(DEFAULT_DISSIMILARITY_THRESHOLD);
778 if (IsGeometry(arg1) == MagickFalse)
779 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
780 (void) SetImageOption(_image_info,option+1,arg1);
783 if (LocaleCompare("dither",option+1) == 0)
785 /* _image_info attr (on/off), _quantize_info attr (on/off)
786 but also ImageInfo and _quantize_info method!
787 FUTURE: merge the duality of the dithering options
789 _image_info->dither = ArgBoolean;
790 (void) SetImageOption(_image_info,option+1,ArgOption("none"));
791 _quantize_info->dither_method=(DitherMethod) ParseCommandOption(
792 MagickDitherOptions,MagickFalse,ArgOption("none"));
793 if (_quantize_info->dither_method == NoDitherMethod)
794 _image_info->dither = MagickFalse;
797 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
801 if (LocaleCompare("encoding",option+1) == 0)
803 (void) CloneString(&_draw_info->encoding,ArgOption("undefined"));
804 (void) SetImageOption(_image_info,option+1,_draw_info->encoding);
807 if (LocaleCompare("endian",option+1) == 0)
809 /* Both _image_info attr and ImageInfo */
810 arg1 = ArgOption("undefined");
811 parse = ParseCommandOption(MagickEndianOptions,MagickFalse,arg1);
813 CLIWandExceptArgBreak(OptionError,"UnrecognizedEndianType",
815 /* FUTURE: check alloc/free of endian string! - remove? */
816 _image_info->endian=(EndianType) (*arg1);
817 (void) SetImageOption(_image_info,option+1,arg1);
820 if (LocaleCompare("extract",option+1) == 0)
822 (void) CloneString(&_image_info->extract,ArgOption(NULL));
825 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
829 if (LocaleCompare("family",option+1) == 0)
831 (void) CloneString(&_draw_info->family,ArgOption(NULL));
834 if (LocaleCompare("features",option+1) == 0)
836 (void) SetImageOption(_image_info,"identify:features",
839 (void) SetImageArtifact(_image,"verbose","true");
842 if (LocaleCompare("fill",option+1) == 0)
844 /* Set "fill" OR "fill-pattern" in _draw_info
845 The original fill color is preserved if a fill-pattern is given.
846 That way it does not effect other operations that directly using
847 the fill color and, can be retored using "+tile".
858 arg1 = ArgOption("none"); /* +fill turns it off! */
859 (void) SetImageOption(_image_info,option+1,arg1);
860 if (_draw_info->fill_pattern != (Image *) NULL)
861 _draw_info->fill_pattern=DestroyImage(_draw_info->fill_pattern);
863 /* is it a color or a image? -- ignore exceptions */
864 sans=AcquireExceptionInfo();
865 status=QueryColorCompliance(arg1,AllCompliance,&color,sans);
866 sans=DestroyExceptionInfo(sans);
868 if (status == MagickFalse)
869 _draw_info->fill_pattern=GetImageCache(_image_info,arg1,_exception);
871 _draw_info->fill=color;
874 if (LocaleCompare("filter",option+1) == 0)
876 /* SyncImageSettings() used to set per-image attribute. */
877 arg1 = ArgOption("undefined");
878 parse = ParseCommandOption(MagickFilterOptions,MagickFalse,arg1);
880 CLIWandExceptArgBreak(OptionError,"UnrecognizedImageFilter",
882 (void) SetImageOption(_image_info,option+1,arg1);
885 if (LocaleCompare("font",option+1) == 0)
887 (void) CloneString(&_draw_info->font,ArgOption(NULL));
888 (void) CloneString(&_image_info->font,_draw_info->font);
891 if (LocaleCompare("format",option+1) == 0)
893 /* FUTURE: why the ping test, you could set ping after this! */
898 for (q=strchr(arg1,'%'); q != (char *) NULL; q=strchr(q+1,'%'))
899 if (strchr("Agkrz@[#",*(q+1)) != (char *) NULL)
900 _image_info->ping=MagickFalse;
902 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
905 if (LocaleCompare("fuzz",option+1) == 0)
907 /* Option used to set image fuzz! unless blank canvas (from color)
908 Image attribute used for color compare operations
909 SyncImageSettings() used to set per-image attribute.
911 FUTURE: Can't find anything else using _image_info->fuzz directly!
912 convert structure attribute to 'option' string
915 if (IsGeometry(arg1) == MagickFalse)
916 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
917 _image_info->fuzz=StringToDoubleInterval(arg1,(double)
919 (void) SetImageOption(_image_info,option+1,arg1);
922 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
926 if (LocaleCompare("gravity",option+1) == 0)
928 /* SyncImageSettings() used to set per-image attribute. */
929 arg1 = ArgOption("none");
930 parse = ParseCommandOption(MagickGravityOptions,MagickFalse,arg1);
932 CLIWandExceptArgBreak(OptionError,"UnrecognizedGravityType",
934 _draw_info->gravity=(GravityType) parse;
935 (void) SetImageOption(_image_info,option+1,arg1);
938 if (LocaleCompare("green-primary",option+1) == 0)
940 /* Image chromaticity X,Y NB: Y=X if Y not defined
941 SyncImageSettings() used to set per-image attribute.
942 Used directly by many coders
944 arg1=ArgOption("0.0");
945 if (IsGeometry(arg1) == MagickFalse)
946 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
947 (void) SetImageOption(_image_info,option+1,arg1);
950 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
954 if (LocaleCompare("highlight-color",option+1) == 0)
956 /* FUTURE: this is only used by CompareImages() which is used
957 only by the "compare" CLI program at this time. */
958 (void) SetImageOption(_image_info,"compare:highlight-color",
962 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
966 if (LocaleCompare("intensity",option+1) == 0)
968 arg1 = ArgOption("undefined");
969 parse = ParseCommandOption(MagickPixelIntensityOptions,MagickFalse,
972 CLIWandExceptArgBreak(OptionError,"UnrecognizedIntensityType",
974 (void) SetImageOption(_image_info,option+1,arg1);
977 if (LocaleCompare("intent",option+1) == 0)
979 /* Only used by coders: MIFF, MPC, BMP, PNG
980 and for image profile call to AcquireTransformThreadSet()
981 SyncImageSettings() used to set per-image attribute.
983 arg1 = ArgOption("undefined");
984 parse = ParseCommandOption(MagickIntentOptions,MagickFalse,arg1);
986 CLIWandExceptArgBreak(OptionError,"UnrecognizedIntentType",
988 (void) SetImageOption(_image_info,option+1,arg1);
991 if (LocaleCompare("interlace",option+1) == 0)
993 /* _image_info is directly used by coders (so why an image setting?)
994 SyncImageSettings() used to set per-image attribute.
996 arg1 = ArgOption("undefined");
997 parse = ParseCommandOption(MagickInterlaceOptions,MagickFalse,arg1);
999 CLIWandExceptArgBreak(OptionError,"UnrecognizedInterlaceType",
1001 _image_info->interlace=(InterlaceType) parse;
1002 (void) SetImageOption(_image_info,option+1,arg1);
1005 if (LocaleCompare("interline-spacing",option+1) == 0)
1007 if (IfSetOption && (IsGeometry(arg1) == MagickFalse))
1008 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1009 (void) SetImageOption(_image_info,option+1, ArgOption(NULL));
1010 _draw_info->interline_spacing=StringToDouble(ArgOption("0"),
1014 if (LocaleCompare("interpolate",option+1) == 0)
1016 /* SyncImageSettings() used to set per-image attribute. */
1017 arg1 = ArgOption("undefined");
1018 parse = ParseCommandOption(MagickInterpolateOptions,MagickFalse,arg1);
1020 CLIWandExceptArgBreak(OptionError,"UnrecognizedInterpolateMethod",
1022 (void) SetImageOption(_image_info,option+1,arg1);
1025 if (LocaleCompare("interword-spacing",option+1) == 0)
1027 if (IfSetOption && (IsGeometry(arg1) == MagickFalse))
1028 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1029 (void) SetImageOption(_image_info,option+1, ArgOption(NULL));
1030 _draw_info->interword_spacing=StringToDouble(ArgOption("0"),(char **) NULL);
1033 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1037 if (LocaleCompare("kerning",option+1) == 0)
1039 if (IfSetOption && (IsGeometry(arg1) == MagickFalse))
1040 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1041 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1042 _draw_info->kerning=StringToDouble(ArgOption("0"),(char **) NULL);
1045 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1049 if (LocaleCompare("label",option+1) == 0)
1051 /* only used for new images - not in SyncImageOptions() */
1052 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1055 if (LocaleCompare("limit",option+1) == 0)
1060 limit=MagickResourceInfinity;
1061 parse= ParseCommandOption(MagickResourceOptions,MagickFalse,arg1);
1063 CLIWandExceptArgBreak(OptionError,"UnrecognizedResourceType",
1065 if (LocaleCompare("unlimited",arg2) != 0)
1066 limit=(MagickSizeType) SiPrefixToDoubleInterval(arg2,100.0);
1067 (void) SetMagickResourceLimit((ResourceType)parse,limit);
1070 if (LocaleCompare("log",option+1) == 0)
1073 if ((strchr(arg1,'%') == (char *) NULL))
1074 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1075 (void) SetLogFormat(arg1);
1079 if (LocaleCompare("lowlight-color",option+1) == 0)
1081 /* FUTURE: this is only used by CompareImages() which is used
1082 only by the "compare" CLI program at this time. */
1083 (void) SetImageOption(_image_info,"compare:lowlight-color",
1087 if (LocaleCompare("loop",option+1) == 0)
1089 /* SyncImageSettings() used to set per-image attribute. */
1090 arg1=ArgOption("0");
1091 if (IsGeometry(arg1) == MagickFalse)
1092 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1093 (void) SetImageOption(_image_info,option+1,arg1);
1096 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1100 if (LocaleCompare("mattecolor",option+1) == 0)
1102 /* SyncImageSettings() used to set per-image attribute. */
1103 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1104 (void) QueryColorCompliance(ArgOption(MogrifyAlphaColor),
1105 AllCompliance,&_image_info->matte_color,_exception);
1108 if (LocaleCompare("metric",option+1) == 0)
1110 /* FUTURE: this is only used by CompareImages() which is used
1111 only by the "compare" CLI program at this time. */
1112 parse=ParseCommandOption(MagickMetricOptions,MagickFalse,arg1);
1114 CLIWandExceptArgBreak(OptionError,"UnrecognizedMetricType",
1116 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1119 if (LocaleCompare("moments",option+1) == 0)
1121 (void) SetImageOption(_image_info,"identify:moments",
1124 (void) SetImageArtifact(_image,"verbose","true");
1127 if (LocaleCompare("monitor",option+1) == 0)
1129 (void) SetImageInfoProgressMonitor(_image_info, IfSetOption?
1130 MonitorProgress: (MagickProgressMonitor) NULL, (void *) NULL);
1133 if (LocaleCompare("monochrome",option+1) == 0)
1135 /* Setting (used by some input coders!) -- why?
1136 Warning: This is also Special '-type' SimpleOperator
1138 _image_info->monochrome= ArgBoolean;
1141 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1145 if (LocaleCompare("orient",option+1) == 0)
1147 /* Is not used when defining for new images.
1148 This makes it more of a 'operation' than a setting
1149 FUTURE: make set meta-data operator instead.
1150 SyncImageSettings() used to set per-image attribute.
1152 parse=ParseCommandOption(MagickOrientationOptions,MagickFalse,
1153 ArgOption("undefined"));
1155 CLIWandExceptArgBreak(OptionError,"UnrecognizedImageOrientation",
1157 _image_info->orientation=(OrientationType)parse;
1158 (void) SetImageOption(_image_info,option+1, ArgOption(NULL));
1161 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1165 if (LocaleCompare("page",option+1) == 0)
1167 /* Only used for new images and image generators.
1168 SyncImageSettings() used to set per-image attribute. ?????
1169 That last is WRONG!!!!
1170 FUTURE: adjust named 'page' sizes according density
1174 page[MagickPathExtent];
1187 (void) DeleteImageOption(_image_info,option+1);
1188 (void) CloneString(&_image_info->page,(char *) NULL);
1191 (void) memset(&geometry,0,sizeof(geometry));
1192 image_option=GetImageOption(_image_info,"page");
1193 if (image_option != (const char *) NULL)
1194 flags=ParseAbsoluteGeometry(image_option,&geometry);
1195 canonical_page=GetPageGeometry(arg1);
1196 flags=ParseAbsoluteGeometry(canonical_page,&geometry);
1197 canonical_page=DestroyString(canonical_page);
1198 (void) FormatLocaleString(page,MagickPathExtent,"%lux%lu",
1199 (unsigned long) geometry.width,(unsigned long) geometry.height);
1200 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
1201 (void) FormatLocaleString(page,MagickPathExtent,"%lux%lu%+ld%+ld",
1202 (unsigned long) geometry.width,(unsigned long) geometry.height,
1203 (long) geometry.x,(long) geometry.y);
1204 (void) SetImageOption(_image_info,option+1,page);
1205 (void) CloneString(&_image_info->page,page);
1208 if (LocaleCompare("ping",option+1) == 0)
1210 _image_info->ping = ArgBoolean;
1213 if (LocaleCompare("pointsize",option+1) == 0)
1216 if (IsGeometry(arg1) == MagickFalse)
1217 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1218 _image_info->pointsize =
1219 _draw_info->pointsize =
1220 StringToDouble(arg1,(char **) NULL);
1223 _image_info->pointsize=0.0; /* unset pointsize */
1224 _draw_info->pointsize=12.0;
1228 if (LocaleCompare("precision",option+1) == 0)
1230 arg1=ArgOption("-1");
1231 if (IsGeometry(arg1) == MagickFalse)
1232 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1233 (void) SetMagickPrecision(StringToInteger(arg1));
1236 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1240 if (LocaleCompare("quality",option+1) == 0)
1242 if (IsGeometry(arg1) == MagickFalse)
1243 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1244 _image_info->quality= IfSetOption ? StringToUnsignedLong(arg1)
1245 : UNDEFINED_COMPRESSION_QUALITY;
1246 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1249 if (LocaleCompare("quantize",option+1) == 0)
1251 /* Just a set direct in _quantize_info */
1252 arg1=ArgOption("undefined");
1253 parse=ParseCommandOption(MagickColorspaceOptions,MagickFalse,arg1);
1255 CLIWandExceptArgBreak(OptionError,"UnrecognizedColorspace",
1257 _quantize_info->colorspace=(ColorspaceType)parse;
1260 if (LocaleCompare("quiet",option+1) == 0)
1262 /* FUTURE: if two -quiet is performed you can not do +quiet!
1263 This needs to be checked over thoughly.
1265 static WarningHandler
1266 warning_handler = (WarningHandler) NULL;
1269 tmp = SetWarningHandler((WarningHandler) NULL);
1271 if ( tmp != (WarningHandler) NULL)
1272 warning_handler = tmp; /* remember the old handler */
1273 if (!IfSetOption) /* set the old handler */
1274 warning_handler=SetWarningHandler(warning_handler);
1277 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1281 if (LocaleCompare("red-primary",option+1) == 0)
1283 /* Image chromaticity X,Y NB: Y=X if Y not defined
1285 SyncImageSettings() used to set per-image attribute.
1287 arg1=ArgOption("0.0");
1288 if (IsGeometry(arg1) == MagickFalse)
1289 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1290 (void) SetImageOption(_image_info,option+1,arg1);
1293 if (LocaleCompare("regard-warnings",option+1) == 0)
1294 /* FUTURE: to be replaced by a 'fatal-level' type setting */
1296 if (LocaleCompare("render",option+1) == 0)
1298 /* _draw_info only setting */
1299 _draw_info->render= ArgBooleanNot;
1302 if (LocaleCompare("respect-parenthesis",option+1) == 0)
1304 /* link image and setting stacks - option is itself saved on stack! */
1305 (void) SetImageOption(_image_info,option+1,ArgBooleanString);
1308 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1312 if (LocaleCompare("sampling-factor",option+1) == 0)
1314 /* FUTURE: should be converted to jpeg:sampling_factor */
1315 if (IfSetOption && (IsGeometry(arg1) == MagickFalse))
1316 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1317 (void) CloneString(&_image_info->sampling_factor,ArgOption(NULL));
1320 if (LocaleCompare("scene",option+1) == 0)
1322 /* SyncImageSettings() used to set this as a per-image attribute.
1325 if (IfSetOption && (IsGeometry(arg1) == MagickFalse))
1326 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1327 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1328 _image_info->scene=StringToUnsignedLong(ArgOption("0"));
1331 if (LocaleCompare("seed",option+1) == 0)
1333 if (IfSetOption && (IsGeometry(arg1) == MagickFalse))
1334 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1336 IfSetOption ? (unsigned long) StringToUnsignedLong(arg1)
1337 : (unsigned long) time((time_t *) NULL) );
1340 if (LocaleCompare("size",option+1) == 0)
1342 /* FUTURE: string in _image_info -- convert to Option ???
1343 Look at the special handling for "size" in SetImageOption()
1345 (void) CloneString(&_image_info->size,ArgOption(NULL));
1348 if (LocaleCompare("stretch",option+1) == 0)
1350 arg1=ArgOption("undefined");
1351 parse = ParseCommandOption(MagickStretchOptions,MagickFalse,arg1);
1353 CLIWandExceptArgBreak(OptionError,"UnrecognizedStretchType",
1355 _draw_info->stretch=(StretchType) parse;
1358 if (LocaleCompare("stroke",option+1) == 0)
1360 /* set stroke color OR stroke-pattern
1361 UPDATE: ensure stroke color is not destroyed is a pattern
1362 is given. Just in case the color is also used for other purposes.
1373 arg1 = ArgOption("none"); /* +fill turns it off! */
1374 (void) SetImageOption(_image_info,option+1,arg1);
1375 if (_draw_info->stroke_pattern != (Image *) NULL)
1376 _draw_info->stroke_pattern=DestroyImage(_draw_info->stroke_pattern);
1378 /* is it a color or a image? -- ignore exceptions */
1379 sans=AcquireExceptionInfo();
1380 status=QueryColorCompliance(arg1,AllCompliance,&color,sans);
1381 sans=DestroyExceptionInfo(sans);
1383 if (status == MagickFalse)
1384 _draw_info->stroke_pattern=GetImageCache(_image_info,arg1,_exception);
1386 _draw_info->stroke=color;
1389 if (LocaleCompare("strokewidth",option+1) == 0)
1391 if (IfSetOption && (IsGeometry(arg1) == MagickFalse))
1392 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1393 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1394 _draw_info->stroke_width=StringToDouble(ArgOption("1.0"),
1398 if (LocaleCompare("style",option+1) == 0)
1400 arg1=ArgOption("undefined");
1401 parse = ParseCommandOption(MagickStyleOptions,MagickFalse,arg1);
1403 CLIWandExceptArgBreak(OptionError,"UnrecognizedStyleType",
1405 _draw_info->style=(StyleType) parse;
1409 if (LocaleCompare("subimage-search",option+1) == 0)
1411 /* FUTURE: this is only used by CompareImages() which is used
1412 only by the "compare" CLI program at this time. */
1413 (void) SetImageOption(_image_info,option+1,ArgBooleanString);
1417 if (LocaleCompare("synchronize",option+1) == 0)
1419 /* FUTURE: syncronize to storage - but what does that mean? */
1420 _image_info->synchronize = ArgBoolean;
1423 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1427 if (LocaleCompare("taint",option+1) == 0)
1429 /* SyncImageSettings() used to set per-image attribute. */
1430 (void) SetImageOption(_image_info,option+1,ArgBooleanString);
1433 if (LocaleCompare("texture",option+1) == 0)
1435 /* Note: arguments do not have percent escapes expanded */
1436 /* FUTURE: move _image_info string to option splay-tree
1437 Other than "montage" what uses "texture" ????
1439 (void) CloneString(&_image_info->texture,ArgOption(NULL));
1442 if (LocaleCompare("tile",option+1) == 0)
1444 /* Note: arguments do not have percent escapes expanded */
1445 _draw_info->fill_pattern=IfSetOption
1446 ?GetImageCache(_image_info,arg1,_exception)
1447 :DestroyImage(_draw_info->fill_pattern);
1450 if (LocaleCompare("tile-offset",option+1) == 0)
1452 /* SyncImageSettings() used to set per-image attribute. ??? */
1453 arg1=ArgOption("0");
1454 if (IsGeometry(arg1) == MagickFalse)
1455 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1456 (void) SetImageOption(_image_info,option+1,arg1);
1459 if (LocaleCompare("transparent-color",option+1) == 0)
1461 /* FUTURE: both _image_info attribute & ImageOption in use!
1462 _image_info only used for generating new images.
1463 SyncImageSettings() used to set per-image attribute.
1465 Note that +transparent-color, means fall-back to image
1466 attribute so ImageOption is deleted, not set to a default.
1468 if (IfSetOption && (IsGeometry(arg1) == MagickFalse))
1469 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1470 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1471 (void) QueryColorCompliance(ArgOption("none"),AllCompliance,
1472 &_image_info->transparent_color,_exception);
1475 if (LocaleCompare("treedepth",option+1) == 0)
1477 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1478 _quantize_info->tree_depth=StringToUnsignedLong(ArgOption("0"));
1481 if (LocaleCompare("type",option+1) == 0)
1483 /* SyncImageSettings() used to set per-image attribute. */
1484 parse=ParseCommandOption(MagickTypeOptions,MagickFalse,
1485 ArgOption("undefined"));
1487 CLIWandExceptArgBreak(OptionError,"UnrecognizedImageType",
1489 _image_info->type=(ImageType) parse;
1490 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1493 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1497 if (LocaleCompare("undercolor",option+1) == 0)
1499 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1500 (void) QueryColorCompliance(ArgOption("none"),AllCompliance,
1501 &_draw_info->undercolor,_exception);
1504 if (LocaleCompare("units",option+1) == 0)
1506 /* SyncImageSettings() used to set per-image attribute.
1507 Should this effect _draw_info X and Y resolution?
1508 FUTURE: this probably should be part of the density setting
1510 parse=ParseCommandOption(MagickResolutionOptions,MagickFalse,
1511 ArgOption("undefined"));
1513 CLIWandExceptArgBreak(OptionError,"UnrecognizedUnitsType",
1515 _image_info->units=(ResolutionType) parse;
1516 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1519 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1523 if (LocaleCompare("verbose",option+1) == 0)
1525 /* FUTURE: Remember all options become image artifacts
1526 _image_info->verbose is only used by coders.
1528 (void) SetImageOption(_image_info,option+1,ArgBooleanString);
1529 _image_info->verbose= ArgBoolean;
1530 _image_info->ping=MagickFalse; /* verbose can't be a ping */
1533 if (LocaleCompare("virtual-pixel",option+1) == 0)
1535 /* SyncImageSettings() used to set per-image attribute.
1536 This is VERY deep in the image caching structure.
1538 parse=ParseCommandOption(MagickVirtualPixelOptions,MagickFalse,
1539 ArgOption("undefined"));
1541 CLIWandExceptArgBreak(OptionError,"UnrecognizedVirtualPixelMethod",
1543 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1546 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1550 if (LocaleCompare("weight",option+1) == 0)
1555 weight=ParseCommandOption(MagickWeightOptions,MagickFalse,arg1);
1557 weight=(ssize_t) StringToUnsignedLong(arg1);
1558 _draw_info->weight=(size_t) weight;
1561 if (LocaleCompare("white-point",option+1) == 0)
1563 /* Used as a image chromaticity setting
1564 SyncImageSettings() used to set per-image attribute.
1566 arg1=ArgOption("0.0");
1567 if (IsGeometry(arg1) == MagickFalse)
1568 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1569 (void) SetImageOption(_image_info,option+1,arg1);
1572 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1575 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1578 /* clean up percent escape interpreted strings */
1579 if ((arg1 && arg1n) && (arg1 != arg1n ))
1580 arg1=DestroyString((char *) arg1);
1581 if ((arg2 && arg2n) && (arg2 != arg2n ))
1582 arg2=DestroyString((char *) arg2);
1587 #undef _quantize_info
1590 #undef ArgBooleanNot
1591 #undef ArgBooleanString
1598 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1602 + C L I S i m p l e O p e r a t o r I m a g e s %
1606 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1608 % CLISimpleOperatorImages() applys one simple image operation given to all
1609 % the images in the CLI wand, using any per-image or global settings that was
1610 % previously saved in the CLI wand.
1612 % It is assumed that any such settings are up-to-date.
1614 % The format of the WandSimpleOperatorImages method is:
1616 % MagickBooleanType CLISimpleOperatorImages(MagickCLI *cli_wand,const char *option,
1617 % const char *arg1, const char *arg2,ExceptionInfo *exception)
1619 % A description of each parameter follows:
1621 % o cli_wand: structure holding settings and images to be operated on
1623 % o option: The option string for the operation
1625 % o arg1, arg2: optional argument strings to the operation
1630 CLISimpleOperatorImage() is an Internal subrountine to apply one simple
1631 image operation to the current image pointed to by the CLI wand.
1633 The image in the list may be modified in three different ways...
1634 * directly modified (EG: -negate, -gamma, -level, -annotate, -draw),
1635 * replaced by a new image (EG: -spread, -resize, -rotate, -morphology)
1636 * one image replace by a list of images (-separate and -crop only!)
1638 In each case the result replaces the single original image in the list, as
1639 well as the pointer to the modified image (last image added if replaced by a
1640 list of images) is returned.
1642 As the image pointed to may be replaced, the first image in the list may
1643 also change. GetFirstImageInList() should be used by caller if they wish
1644 return the Image pointer to the first image in list.
1646 static MagickBooleanType CLISimpleOperatorImage(MagickCLI *cli_wand,
1647 const char *option, const char *arg1n, const char *arg2n,
1648 ExceptionInfo *exception)
1665 const char /* percent escaped versions of the args */
1669 #define _image_info (cli_wand->wand.image_info)
1670 #define _image (cli_wand->wand.images)
1671 #define _exception (cli_wand->wand.exception)
1672 #define _draw_info (cli_wand->draw_info)
1673 #define _quantize_info (cli_wand->quantize_info)
1674 #define _process_flags (cli_wand->process_flags)
1675 #define _option_type ((CommandOptionFlags) cli_wand->command->flags)
1676 #define IfNormalOp (*option=='-')
1677 #define IfPlusOp (*option!='-')
1678 #define IsNormalOp IfNormalOp ? MagickTrue : MagickFalse
1679 #define IsPlusOp IfNormalOp ? MagickFalse : MagickTrue
1681 assert(cli_wand != (MagickCLI *) NULL);
1682 assert(cli_wand->signature == MagickWandSignature);
1683 assert(cli_wand->wand.signature == MagickWandSignature);
1684 assert(_image != (Image *) NULL); /* an image must be present */
1685 if (cli_wand->wand.debug != MagickFalse)
1686 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
1691 /* Interpret Percent Escapes in Arguments - using first image */
1692 if ( (((_process_flags & ProcessInterpretProperities) != 0 )
1693 || ((_option_type & AlwaysInterpretArgsFlag) != 0)
1694 ) && ((_option_type & NeverInterpretArgsFlag) == 0) ) {
1695 /* Interpret Percent escapes in argument 1 */
1696 if (arg1n != (char *) NULL) {
1697 arg1=InterpretImageProperties(_image_info,_image,arg1n,_exception);
1698 if (arg1 == (char *) NULL) {
1699 CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
1700 arg1=arg1n; /* use the given argument as is */
1703 if (arg2n != (char *) NULL) {
1704 arg2=InterpretImageProperties(_image_info,_image,arg2n,_exception);
1705 if (arg2 == (char *) NULL) {
1706 CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
1707 arg2=arg2n; /* use the given argument as is */
1711 #undef _process_flags
1715 (void) FormatLocaleFile(stderr,
1716 "CLISimpleOperatorImage: \"%s\" \"%s\" \"%s\"\n",option,arg1,arg2);
1719 new_image = (Image *) NULL; /* the replacement image, if not null at end */
1720 SetGeometryInfo(&geometry_info);
1722 switch (*(option+1))
1726 if (LocaleCompare("adaptive-blur",option+1) == 0)
1728 flags=ParseGeometry(arg1,&geometry_info);
1729 if ((flags & (RhoValue|SigmaValue)) == 0)
1730 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1731 if ((flags & SigmaValue) == 0)
1732 geometry_info.sigma=1.0;
1733 new_image=AdaptiveBlurImage(_image,geometry_info.rho,
1734 geometry_info.sigma,_exception);
1737 if (LocaleCompare("adaptive-resize",option+1) == 0)
1739 /* FUTURE: Roll into a resize special operator */
1740 if (IsGeometry(arg1) == MagickFalse)
1741 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1742 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
1743 new_image=AdaptiveResizeImage(_image,geometry.width,geometry.height,
1747 if (LocaleCompare("adaptive-sharpen",option+1) == 0)
1749 flags=ParseGeometry(arg1,&geometry_info);
1750 if ((flags & (RhoValue|SigmaValue)) == 0)
1751 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1752 if ((flags & SigmaValue) == 0)
1753 geometry_info.sigma=1.0;
1754 new_image=AdaptiveSharpenImage(_image,geometry_info.rho,
1755 geometry_info.sigma,_exception);
1758 if (LocaleCompare("alpha",option+1) == 0)
1760 parse=ParseCommandOption(MagickAlphaChannelOptions,MagickFalse,arg1);
1762 CLIWandExceptArgBreak(OptionError,"UnrecognizedAlphaChannelOption",
1764 (void) SetImageAlphaChannel(_image,(AlphaChannelOption) parse,
1768 if (LocaleCompare("annotate",option+1) == 0)
1771 geometry[MagickPathExtent];
1773 SetGeometryInfo(&geometry_info);
1774 flags=ParseGeometry(arg1,&geometry_info);
1776 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1777 if ((flags & SigmaValue) == 0)
1778 geometry_info.sigma=geometry_info.rho;
1779 (void) CloneString(&_draw_info->text,arg2);
1780 (void) FormatLocaleString(geometry,MagickPathExtent,"%+f%+f",
1781 geometry_info.xi,geometry_info.psi);
1782 (void) CloneString(&_draw_info->geometry,geometry);
1783 _draw_info->affine.sx=cos(DegreesToRadians(
1784 fmod(geometry_info.rho,360.0)));
1785 _draw_info->affine.rx=sin(DegreesToRadians(
1786 fmod(geometry_info.rho,360.0)));
1787 _draw_info->affine.ry=(-sin(DegreesToRadians(
1788 fmod(geometry_info.sigma,360.0))));
1789 _draw_info->affine.sy=cos(DegreesToRadians(
1790 fmod(geometry_info.sigma,360.0)));
1791 (void) AnnotateImage(_image,_draw_info,_exception);
1792 GetAffineMatrix(&_draw_info->affine);
1795 if (LocaleCompare("auto-gamma",option+1) == 0)
1797 (void) AutoGammaImage(_image,_exception);
1800 if (LocaleCompare("auto-level",option+1) == 0)
1802 (void) AutoLevelImage(_image,_exception);
1805 if (LocaleCompare("auto-orient",option+1) == 0)
1807 new_image=AutoOrientImage(_image,_image->orientation,_exception);
1810 if (LocaleCompare("auto-threshold",option+1) == 0)
1815 method=(AutoThresholdMethod) ParseCommandOption(
1816 MagickAutoThresholdOptions,MagickFalse,arg1);
1817 (void) AutoThresholdImage(_image,method,_exception);
1820 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1824 if (LocaleCompare("black-threshold",option+1) == 0)
1826 if (IsGeometry(arg1) == MagickFalse)
1827 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1828 (void) BlackThresholdImage(_image,arg1,_exception);
1831 if (LocaleCompare("blue-shift",option+1) == 0)
1833 geometry_info.rho=1.5;
1835 flags=ParseGeometry(arg1,&geometry_info);
1836 if ((flags & RhoValue) == 0)
1837 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1839 new_image=BlueShiftImage(_image,geometry_info.rho,_exception);
1842 if (LocaleCompare("blur",option+1) == 0)
1844 flags=ParseGeometry(arg1,&geometry_info);
1845 if ((flags & (RhoValue|SigmaValue)) == 0)
1846 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1847 if ((flags & SigmaValue) == 0)
1848 geometry_info.sigma=1.0;
1849 new_image=BlurImage(_image,geometry_info.rho,geometry_info.sigma,
1853 if (LocaleCompare("border",option+1) == 0)
1861 flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
1862 if ((flags & (WidthValue | HeightValue)) == 0)
1863 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1864 compose=OverCompositeOp;
1865 value=GetImageOption(_image_info,"compose");
1866 if (value != (const char *) NULL)
1867 compose=(CompositeOperator) ParseCommandOption(MagickComposeOptions,
1869 new_image=BorderImage(_image,&geometry,compose,_exception);
1872 if (LocaleCompare("brightness-contrast",option+1) == 0)
1884 flags=ParseGeometry(arg1,&geometry_info);
1885 if ((flags & RhoValue) == 0)
1886 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1887 brightness=geometry_info.rho;
1889 if ((flags & SigmaValue) != 0)
1890 contrast=geometry_info.sigma;
1891 (void) BrightnessContrastImage(_image,brightness,contrast,
1895 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
1899 if (LocaleCompare("canny",option+1) == 0)
1901 flags=ParseGeometry(arg1,&geometry_info);
1902 if ((flags & (RhoValue|SigmaValue)) == 0)
1903 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1904 if ((flags & SigmaValue) == 0)
1905 geometry_info.sigma=1.0;
1906 if ((flags & XiValue) == 0)
1907 geometry_info.xi=10;
1908 if ((flags & PsiValue) == 0)
1909 geometry_info.psi=30;
1910 if ((flags & PercentValue) != 0)
1912 geometry_info.xi/=100.0;
1913 geometry_info.psi/=100.0;
1915 new_image=CannyEdgeImage(_image,geometry_info.rho,geometry_info.sigma,
1916 geometry_info.xi,geometry_info.psi,_exception);
1919 if (LocaleCompare("cdl",option+1) == 0)
1922 *color_correction_collection; /* Note: arguments do not have percent escapes expanded */
1925 Color correct with a color decision list.
1927 color_correction_collection=FileToString(arg1,~0UL,_exception);
1928 if (color_correction_collection == (char *) NULL)
1930 (void) ColorDecisionListImage(_image,color_correction_collection,
1934 if (LocaleCompare("channel",option+1) == 0)
1938 (void) SetPixelChannelMask(_image,DefaultChannels);
1941 parse=ParseChannelOption(arg1);
1943 CLIWandExceptArgBreak(OptionError,"UnrecognizedChannelType",option,
1945 (void) SetPixelChannelMask(_image,(ChannelType) parse);
1948 if (LocaleCompare("charcoal",option+1) == 0)
1950 flags=ParseGeometry(arg1,&geometry_info);
1951 if ((flags & (RhoValue|SigmaValue)) == 0)
1952 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1953 if ((flags & SigmaValue) == 0)
1954 geometry_info.sigma=1.0;
1955 if ((flags & XiValue) == 0)
1956 geometry_info.xi=1.0;
1957 new_image=CharcoalImage(_image,geometry_info.rho,geometry_info.sigma,
1961 if (LocaleCompare("chop",option+1) == 0)
1963 if (IsGeometry(arg1) == MagickFalse)
1964 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1965 (void) ParseGravityGeometry(_image,arg1,&geometry,_exception);
1966 new_image=ChopImage(_image,&geometry,_exception);
1969 if (LocaleCompare("clamp",option+1) == 0)
1971 (void) ClampImage(_image,_exception);
1974 if (LocaleCompare("clip",option+1) == 0)
1977 (void) ClipImage(_image,_exception);
1978 else /* "+mask" remove the write mask */
1979 (void) SetImageMask(_image,WritePixelMask,(Image *) NULL,_exception);
1982 if (LocaleCompare("clip-mask",option+1) == 0)
1988 /* use "+clip-mask" Remove the write mask for -clip-path */
1989 (void) SetImageMask(_image,WritePixelMask,(Image *) NULL,_exception);
1992 clip_mask=GetImageCache(_image_info,arg1,_exception);
1993 if (clip_mask == (Image *) NULL)
1995 (void) SetImageMask(_image,WritePixelMask,clip_mask,_exception);
1996 clip_mask=DestroyImage(clip_mask);
1999 if (LocaleCompare("clip-path",option+1) == 0)
2001 (void) ClipImagePath(_image,arg1,IsNormalOp,_exception);
2002 /* Note: Use "+clip-mask" remove the write mask added */
2005 if (LocaleCompare("colorize",option+1) == 0)
2007 if (IsGeometry(arg1) == MagickFalse)
2008 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2009 new_image=ColorizeImage(_image,arg1,&_draw_info->fill,_exception);
2012 if (LocaleCompare("color-matrix",option+1) == 0)
2017 kernel=AcquireKernelInfo(arg1,exception);
2018 if (kernel == (KernelInfo *) NULL)
2019 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2020 new_image=ColorMatrixImage(_image,kernel,_exception);
2021 kernel=DestroyKernelInfo(kernel);
2024 if (LocaleCompare("colors",option+1) == 0)
2026 /* Reduce the number of colors in the image.
2027 FUTURE: also provide 'plus version with image 'color counts'
2029 _quantize_info->number_colors=StringToUnsignedLong(arg1);
2030 if (_quantize_info->number_colors == 0)
2031 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2032 if ((_image->storage_class == DirectClass) ||
2033 _image->colors > _quantize_info->number_colors)
2034 (void) QuantizeImage(_quantize_info,_image,_exception);
2036 (void) CompressImageColormap(_image,_exception);
2039 if (LocaleCompare("colorspace",option+1) == 0)
2041 /* WARNING: this is both a image_info setting (already done)
2042 and a operator to change image colorspace.
2044 FUTURE: default colorspace should be sRGB!
2045 Unless some type of 'linear colorspace' mode is set.
2047 Note that +colorspace sets "undefined" or no effect on
2048 new images, but forces images already in memory back to RGB!
2049 That seems to be a little strange!
2051 (void) TransformImageColorspace(_image,
2052 IfNormalOp ? _image_info->colorspace : sRGBColorspace,
2056 if (LocaleCompare("connected-components",option+1) == 0)
2058 if (IsGeometry(arg1) == MagickFalse)
2059 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2060 new_image=ConnectedComponentsImage(_image,(size_t)
2061 StringToInteger(arg1),(CCObjectInfo **) NULL,_exception);
2064 if (LocaleCompare("contrast",option+1) == 0)
2066 CLIWandWarnReplaced(IfNormalOp?"-level":"+level");
2067 (void) ContrastImage(_image,IsNormalOp,_exception);
2070 if (LocaleCompare("contrast-stretch",option+1) == 0)
2079 flags=ParseGeometry(arg1,&geometry_info);
2080 if ((flags & RhoValue) == 0)
2081 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2082 black_point=geometry_info.rho;
2083 white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
2085 if ((flags & PercentValue) != 0) {
2086 black_point*=(double) _image->columns*_image->rows/100.0;
2087 white_point*=(double) _image->columns*_image->rows/100.0;
2089 white_point=(double) _image->columns*_image->rows-white_point;
2090 (void) ContrastStretchImage(_image,black_point,white_point,
2094 if (LocaleCompare("convolve",option+1) == 0)
2105 kernel_info=AcquireKernelInfo(arg1,exception);
2106 if (kernel_info == (KernelInfo *) NULL)
2107 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2109 for (j=0; j < (ssize_t) (kernel_info->width*kernel_info->height); j++)
2110 gamma+=kernel_info->values[j];
2111 gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
2112 for (j=0; j < (ssize_t) (kernel_info->width*kernel_info->height); j++)
2113 kernel_info->values[j]*=gamma;
2114 new_image=MorphologyImage(_image,CorrelateMorphology,1,kernel_info,
2116 kernel_info=DestroyKernelInfo(kernel_info);
2119 if (LocaleCompare("crop",option+1) == 0)
2121 /* WARNING: This can generate multiple images! */
2122 if (IsGeometry(arg1) == MagickFalse)
2123 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2124 new_image=CropImageToTiles(_image,arg1,_exception);
2127 if (LocaleCompare("cycle",option+1) == 0)
2129 if (IsGeometry(arg1) == MagickFalse)
2130 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2131 (void) CycleColormapImage(_image,(ssize_t) StringToLong(arg1),
2135 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2139 if (LocaleCompare("decipher",option+1) == 0)
2141 /* Note: arguments do not have percent escapes expanded */
2145 passkey=FileToStringInfo(arg1,~0UL,_exception);
2146 if (passkey == (StringInfo *) NULL)
2147 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2149 (void) PasskeyDecipherImage(_image,passkey,_exception);
2150 passkey=DestroyStringInfo(passkey);
2153 if (LocaleCompare("depth",option+1) == 0)
2155 /* The _image_info->depth setting has already been set
2156 We just need to apply it to all images in current sequence
2158 WARNING: Depth from 8 to 16 causes 'quantum rounding to images!
2159 That is it really is an operation, not a setting! Arrgghhh
2161 FUTURE: this should not be an operator!!!
2163 (void) SetImageDepth(_image,_image_info->depth,_exception);
2166 if (LocaleCompare("deskew",option+1) == 0)
2172 if (IsGeometry(arg1) == MagickFalse)
2173 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2174 threshold=StringToDoubleInterval(arg1,(double) QuantumRange+1.0);
2177 threshold=40.0*QuantumRange/100.0;
2178 new_image=DeskewImage(_image,threshold,_exception);
2181 if (LocaleCompare("despeckle",option+1) == 0)
2183 new_image=DespeckleImage(_image,_exception);
2186 if (LocaleCompare("distort",option+1) == 0)
2194 parse = ParseCommandOption(MagickDistortOptions,MagickFalse,arg1);
2196 CLIWandExceptArgBreak(OptionError,"UnrecognizedDistortMethod",
2198 if ((DistortMethod) parse == ResizeDistortion)
2202 /* Special Case - Argument is actually a resize geometry!
2203 ** Convert that to an appropriate distortion argument array.
2204 ** FUTURE: make a separate special resize operator
2205 Roll into a resize special operator */
2206 if (IsGeometry(arg2) == MagickFalse)
2207 CLIWandExceptArgBreak(OptionError,"InvalidGeometry",
2209 (void) ParseRegionGeometry(_image,arg2,&geometry,_exception);
2210 resize_args[0]=(double) geometry.width;
2211 resize_args[1]=(double) geometry.height;
2212 new_image=DistortImage(_image,(DistortMethod) parse,
2213 (size_t)2,resize_args,MagickTrue,_exception);
2216 /* convert argument string into an array of doubles */
2217 args = StringToArrayOfDoubles(arg2,&count,_exception);
2218 if (args == (double *) NULL )
2219 CLIWandExceptArgBreak(OptionError,"InvalidNumberList",option,arg2);
2221 new_image=DistortImage(_image,(DistortMethod) parse,(size_t)
2222 count,args,IsPlusOp,_exception);
2223 args=(double *) RelinquishMagickMemory(args);
2226 if (LocaleCompare("draw",option+1) == 0)
2228 (void) CloneString(&_draw_info->primitive,arg1);
2229 (void) DrawImage(_image,_draw_info,_exception);
2230 (void) CloneString(&_draw_info->primitive,(char *) NULL);
2233 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2237 if (LocaleCompare("edge",option+1) == 0)
2239 flags=ParseGeometry(arg1,&geometry_info);
2240 if ((flags & (RhoValue|SigmaValue)) == 0)
2241 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2242 new_image=EdgeImage(_image,geometry_info.rho,_exception);
2245 if (LocaleCompare("emboss",option+1) == 0)
2247 flags=ParseGeometry(arg1,&geometry_info);
2248 if ((flags & (RhoValue|SigmaValue)) == 0)
2249 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2250 if ((flags & SigmaValue) == 0)
2251 geometry_info.sigma=1.0;
2252 new_image=EmbossImage(_image,geometry_info.rho,
2253 geometry_info.sigma,_exception);
2256 if (LocaleCompare("encipher",option+1) == 0)
2258 /* Note: arguments do not have percent escapes expanded */
2262 passkey=FileToStringInfo(arg1,~0UL,_exception);
2263 if (passkey != (StringInfo *) NULL)
2265 (void) PasskeyEncipherImage(_image,passkey,_exception);
2266 passkey=DestroyStringInfo(passkey);
2270 if (LocaleCompare("enhance",option+1) == 0)
2272 new_image=EnhanceImage(_image,_exception);
2275 if (LocaleCompare("equalize",option+1) == 0)
2277 (void) EqualizeImage(_image,_exception);
2280 if (LocaleCompare("evaluate",option+1) == 0)
2285 parse = ParseCommandOption(MagickEvaluateOptions,MagickFalse,arg1);
2287 CLIWandExceptArgBreak(OptionError,"UnrecognizedEvaluateOperator",
2289 if (IsGeometry(arg2) == MagickFalse)
2290 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
2291 constant=StringToDoubleInterval(arg2,(double) QuantumRange+1.0);
2292 (void) EvaluateImage(_image,(MagickEvaluateOperator)parse,constant,
2296 if (LocaleCompare("extent",option+1) == 0)
2298 if (IsGeometry(arg1) == MagickFalse)
2299 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2300 flags=ParseGravityGeometry(_image,arg1,&geometry,_exception);
2301 if (geometry.width == 0)
2302 geometry.width=_image->columns;
2303 if (geometry.height == 0)
2304 geometry.height=_image->rows;
2305 new_image=ExtentImage(_image,&geometry,_exception);
2308 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2312 if (LocaleCompare("flip",option+1) == 0)
2314 new_image=FlipImage(_image,_exception);
2317 if (LocaleCompare("flop",option+1) == 0)
2319 new_image=FlopImage(_image,_exception);
2322 if (LocaleCompare("floodfill",option+1) == 0)
2327 if (IsGeometry(arg1) == MagickFalse)
2328 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2329 (void) ParsePageGeometry(_image,arg1,&geometry,_exception);
2330 (void) GetOneVirtualPixelInfo(_image,TileVirtualPixelMethod,
2331 geometry.x,geometry.y,&target,exception);
2332 (void) QueryColorCompliance(arg2,AllCompliance,&_draw_info->fill,
2334 (void) FloodfillPaintImage(_image,_draw_info,&target,geometry.x,
2335 geometry.y,IsPlusOp,_exception);
2338 if (LocaleCompare("frame",option+1) == 0)
2349 value=GetImageOption(_image_info,"compose");
2350 compose=OverCompositeOp; /* use Over not _image->compose */
2351 if (value != (const char *) NULL)
2352 compose=(CompositeOperator) ParseCommandOption(MagickComposeOptions,
2354 if (IsGeometry(arg1) == MagickFalse)
2355 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2356 flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
2357 frame_info.width=geometry.width;
2358 frame_info.height=geometry.height;
2359 frame_info.outer_bevel=geometry.x;
2360 frame_info.inner_bevel=geometry.y;
2361 frame_info.x=(ssize_t) frame_info.width;
2362 frame_info.y=(ssize_t) frame_info.height;
2363 frame_info.width=_image->columns+2*frame_info.width;
2364 frame_info.height=_image->rows+2*frame_info.height;
2365 new_image=FrameImage(_image,&frame_info,compose,_exception);
2368 if (LocaleCompare("function",option+1) == 0)
2376 parse=ParseCommandOption(MagickFunctionOptions,MagickFalse,arg1);
2378 CLIWandExceptArgBreak(OptionError,"UnrecognizedFunction",
2380 /* convert argument string into an array of doubles */
2381 args = StringToArrayOfDoubles(arg2,&count,_exception);
2382 if (args == (double *) NULL )
2383 CLIWandExceptArgBreak(OptionError,"InvalidNumberList",option,arg2);
2385 (void) FunctionImage(_image,(MagickFunction)parse,(size_t) count,args,
2387 args=(double *) RelinquishMagickMemory(args);
2390 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2394 if (LocaleCompare("gamma",option+1) == 0)
2399 if (IsGeometry(arg1) == MagickFalse)
2400 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2401 constant=StringToDouble(arg1,(char **) NULL);
2403 /* Using Gamma, via a cache */
2405 constant=PerceptibleReciprocal(constant);
2406 (void) GammaImage(_image,constant,_exception);
2408 /* Using Evaluate POW, direct update of values - more accurite */
2410 constant=PerceptibleReciprocal(constant);
2411 (void) EvaluateImage(_image,PowEvaluateOperator,constant,_exception);
2412 _image->gamma*=StringToDouble(arg1,(char **) NULL);
2414 /* Set gamma setting -- Old meaning of "+gamma"
2415 * _image->gamma=StringToDouble(arg1,(char **) NULL);
2419 if (LocaleCompare("gaussian-blur",option+1) == 0)
2421 flags=ParseGeometry(arg1,&geometry_info);
2422 if ((flags & (RhoValue|SigmaValue)) == 0)
2423 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2424 if ((flags & SigmaValue) == 0)
2425 geometry_info.sigma=1.0;
2426 new_image=GaussianBlurImage(_image,geometry_info.rho,
2427 geometry_info.sigma,_exception);
2430 if (LocaleCompare("gaussian",option+1) == 0)
2432 CLIWandWarnReplaced("-gaussian-blur");
2433 (void) CLISimpleOperatorImage(cli_wand,"-gaussian-blur",arg1,NULL,exception);
2435 if (LocaleCompare("geometry",option+1) == 0)
2438 Record Image offset for composition. (A Setting)
2439 Resize last _image. (ListOperator) -- DEPRECIATE
2440 FUTURE: Why if no 'offset' does this resize ALL images?
2441 Also why is the setting recorded in the IMAGE non-sense!
2444 { /* remove the previous composition geometry offset! */
2445 if (_image->geometry != (char *) NULL)
2446 _image->geometry=DestroyString(_image->geometry);
2449 if (IsGeometry(arg1) == MagickFalse)
2450 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2451 flags=ParseRegionGeometry(_image,arg1,&geometry,_exception);
2452 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
2453 (void) CloneString(&_image->geometry,arg1);
2455 new_image=ResizeImage(_image,geometry.width,geometry.height,
2456 _image->filter,_exception);
2459 if (LocaleCompare("grayscale",option+1) == 0)
2461 parse=ParseCommandOption(MagickPixelIntensityOptions,
2464 CLIWandExceptArgBreak(OptionError,"UnrecognizedIntensityMethod",
2466 (void) GrayscaleImage(_image,(PixelIntensityMethod) parse,_exception);
2469 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2473 if (LocaleCompare("hough-lines",option+1) == 0)
2475 flags=ParseGeometry(arg1,&geometry_info);
2476 if ((flags & (RhoValue|SigmaValue)) == 0)
2477 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2478 if ((flags & SigmaValue) == 0)
2479 geometry_info.sigma=geometry_info.rho;
2480 if ((flags & XiValue) == 0)
2481 geometry_info.xi=40;
2482 new_image=HoughLineImage(_image,(size_t) geometry_info.rho,
2483 (size_t) geometry_info.sigma,(size_t) geometry_info.xi,_exception);
2486 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2490 if (LocaleCompare("identify",option+1) == 0)
2496 format=GetImageOption(_image_info,"format");
2497 if (format == (char *) NULL)
2499 (void) IdentifyImage(_image,stdout,_image_info->verbose,
2503 text=InterpretImageProperties(_image_info,_image,format,_exception);
2504 if (text == (char *) NULL)
2505 CLIWandExceptionBreak(OptionWarning,"InterpretPropertyFailure",
2507 (void) fputs(text,stdout);
2508 text=DestroyString((char *)text);
2511 if (LocaleCompare("implode",option+1) == 0)
2513 flags=ParseGeometry(arg1,&geometry_info);
2514 if ((flags & RhoValue) == 0)
2515 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2516 new_image=ImplodeImage(_image,geometry_info.rho,_image->interpolate,
2520 if (LocaleCompare("interpolative-resize",option+1) == 0)
2522 /* FUTURE: New to IMv7
2523 Roll into a resize special operator */
2524 if (IsGeometry(arg1) == MagickFalse)
2525 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2526 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
2527 new_image=InterpolativeResizeImage(_image,geometry.width,
2528 geometry.height,_image->interpolate,_exception);
2531 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2535 if (LocaleCompare("kuwahara",option+1) == 0)
2538 Edge preserving blur.
2540 flags=ParseGeometry(arg1,&geometry_info);
2541 if ((flags & (RhoValue|SigmaValue)) == 0)
2542 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2543 if ((flags & SigmaValue) == 0)
2544 geometry_info.sigma=geometry_info.rho-0.5;
2545 new_image=KuwaharaImage(_image,geometry_info.rho,geometry_info.sigma,
2549 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2553 if (LocaleCompare("lat",option+1) == 0)
2555 flags=ParseGeometry(arg1,&geometry_info);
2556 if ((flags & (RhoValue|SigmaValue)) == 0)
2557 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2558 if ((flags & SigmaValue) == 0)
2559 geometry_info.sigma=1.0;
2560 if ((flags & PercentValue) != 0)
2561 geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
2562 new_image=AdaptiveThresholdImage(_image,(size_t) geometry_info.rho,
2563 (size_t) geometry_info.sigma,(double) geometry_info.xi,
2567 if (LocaleCompare("level",option+1) == 0)
2577 flags=ParseGeometry(arg1,&geometry_info);
2578 if ((flags & RhoValue) == 0)
2579 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2580 black_point=geometry_info.rho;
2581 white_point=(double) QuantumRange;
2582 if ((flags & SigmaValue) != 0)
2583 white_point=geometry_info.sigma;
2585 if ((flags & XiValue) != 0)
2586 gamma=geometry_info.xi;
2587 if ((flags & PercentValue) != 0)
2589 black_point*=(double) (QuantumRange/100.0);
2590 white_point*=(double) (QuantumRange/100.0);
2592 if ((flags & SigmaValue) == 0)
2593 white_point=(double) QuantumRange-black_point;
2594 if (IfPlusOp || ((flags & AspectValue) != 0))
2595 (void) LevelizeImage(_image,black_point,white_point,gamma,_exception);
2597 (void) LevelImage(_image,black_point,white_point,gamma,_exception);
2600 if (LocaleCompare("level-colors",option+1) == 0)
2603 token[MagickPathExtent];
2612 p=(const char *) arg1;
2613 GetNextToken(p,&p,MagickPathExtent,token); /* get black point color */
2614 if ((isalpha((int) *token) != 0) || ((*token == '#') != 0))
2615 (void) QueryColorCompliance(token,AllCompliance,
2616 &black_point,_exception);
2618 (void) QueryColorCompliance("#000000",AllCompliance,
2619 &black_point,_exception);
2620 if (isalpha((int) token[0]) || (token[0] == '#'))
2621 GetNextToken(p,&p,MagickPathExtent,token);
2623 white_point=black_point; /* set everything to that color */
2626 if ((isalpha((int) *token) == 0) && ((*token == '#') == 0))
2627 GetNextToken(p,&p,MagickPathExtent,token); /* Get white point color. */
2628 if ((isalpha((int) *token) != 0) || ((*token == '#') != 0))
2629 (void) QueryColorCompliance(token,AllCompliance,
2630 &white_point,_exception);
2632 (void) QueryColorCompliance("#ffffff",AllCompliance,
2633 &white_point,_exception);
2635 (void) LevelImageColors(_image,&black_point,&white_point,
2636 IsPlusOp,_exception);
2639 if (LocaleCompare("linear-stretch",option+1) == 0)
2648 flags=ParseGeometry(arg1,&geometry_info);
2649 if ((flags & RhoValue) == 0)
2650 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2651 black_point=geometry_info.rho;
2652 white_point=(double) _image->columns*_image->rows;
2653 if ((flags & SigmaValue) != 0)
2654 white_point=geometry_info.sigma;
2655 if ((flags & PercentValue) != 0)
2657 black_point*=(double) _image->columns*_image->rows/100.0;
2658 white_point*=(double) _image->columns*_image->rows/100.0;
2660 if ((flags & SigmaValue) == 0)
2661 white_point=(double) _image->columns*_image->rows-
2663 (void) LinearStretchImage(_image,black_point,white_point,_exception);
2666 if (LocaleCompare("liquid-rescale",option+1) == 0)
2668 /* FUTURE: Roll into a resize special operator */
2669 if (IsGeometry(arg1) == MagickFalse)
2670 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2671 flags=ParseRegionGeometry(_image,arg1,&geometry,_exception);
2672 if ((flags & XValue) == 0)
2674 if ((flags & YValue) == 0)
2676 new_image=LiquidRescaleImage(_image,geometry.width,
2677 geometry.height,1.0*geometry.x,1.0*geometry.y,_exception);
2680 if (LocaleCompare("local-contrast",option+1) == 0)
2685 flags=ParseGeometry(arg1,&geometry_info);
2686 if ((flags & RhoValue) == 0)
2687 geometry_info.rho=10;
2688 if ((flags & SigmaValue) == 0)
2689 geometry_info.sigma=12.5;
2690 new_image=LocalContrastImage(_image,geometry_info.rho,
2691 geometry_info.sigma,exception);
2694 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2698 if (LocaleCompare("magnify",option+1) == 0)
2700 new_image=MagnifyImage(_image,_exception);
2703 if (LocaleCompare("map",option+1) == 0)
2705 CLIWandWarnReplaced("-remap");
2706 (void) CLISimpleOperatorImage(cli_wand,"-remap",NULL,NULL,exception);
2709 if (LocaleCompare("mask",option+1) == 0)
2719 (void) SetImageMask(_image,WritePixelMask,(Image *) NULL,
2726 mask=GetImageCache(_image_info,arg1,_exception);
2727 if (mask == (Image *) NULL)
2729 (void) SetImageMask(_image,WritePixelMask,mask,_exception);
2730 mask=DestroyImage(mask);
2733 if (LocaleCompare("matte",option+1) == 0)
2735 CLIWandWarnReplaced(IfNormalOp?"-alpha Set":"-alpha Off");
2736 (void) SetImageAlphaChannel(_image,IfNormalOp ? SetAlphaChannel :
2737 DeactivateAlphaChannel, _exception);
2740 if (LocaleCompare("mean-shift",option+1) == 0)
2742 flags=ParseGeometry(arg1,&geometry_info);
2743 if ((flags & (RhoValue|SigmaValue)) == 0)
2744 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2745 if ((flags & SigmaValue) == 0)
2746 geometry_info.sigma=1.0;
2747 if ((flags & XiValue) == 0)
2748 geometry_info.xi=0.10*QuantumRange;
2749 if ((flags & PercentValue) != 0)
2750 geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
2751 new_image=MeanShiftImage(_image,(size_t) geometry_info.rho,
2752 (size_t) geometry_info.sigma,geometry_info.xi,_exception);
2755 if (LocaleCompare("median",option+1) == 0)
2757 CLIWandWarnReplaced("-statistic Median");
2758 (void) CLISimpleOperatorImage(cli_wand,"-statistic","Median",arg1,exception);
2761 if (LocaleCompare("mode",option+1) == 0)
2763 /* FUTURE: note this is also a special "montage" option */
2764 CLIWandWarnReplaced("-statistic Mode");
2765 (void) CLISimpleOperatorImage(cli_wand,"-statistic","Mode",arg1,exception);
2768 if (LocaleCompare("modulate",option+1) == 0)
2770 if (IsGeometry(arg1) == MagickFalse)
2771 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2772 (void) ModulateImage(_image,arg1,_exception);
2775 if (LocaleCompare("monitor",option+1) == 0)
2777 (void) SetImageProgressMonitor(_image, IfNormalOp ? MonitorProgress :
2778 (MagickProgressMonitor) NULL,(void *) NULL);
2781 if (LocaleCompare("monochrome",option+1) == 0)
2783 (void) SetImageType(_image,BilevelType,_exception);
2786 if (LocaleCompare("morphology",option+1) == 0)
2789 token[MagickPathExtent];
2801 GetNextToken(p,&p,MagickPathExtent,token);
2802 parse=ParseCommandOption(MagickMorphologyOptions,MagickFalse,token);
2804 CLIWandExceptArgBreak(OptionError,"UnrecognizedFunction",option,
2807 GetNextToken(p,&p,MagickPathExtent,token);
2808 if ((*p == ':') || (*p == ','))
2809 GetNextToken(p,&p,MagickPathExtent,token);
2811 iterations=(ssize_t) StringToLong(p);
2812 kernel=AcquireKernelInfo(arg2,exception);
2813 if (kernel == (KernelInfo *) NULL)
2814 CLIWandExceptArgBreak(OptionError,"UnabletoParseKernel",option,arg2);
2815 new_image=MorphologyImage(_image,(MorphologyMethod)parse,iterations,
2817 kernel=DestroyKernelInfo(kernel);
2820 if (LocaleCompare("motion-blur",option+1) == 0)
2822 flags=ParseGeometry(arg1,&geometry_info);
2823 if ((flags & (RhoValue|SigmaValue)) == 0)
2824 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2825 if ((flags & SigmaValue) == 0)
2826 geometry_info.sigma=1.0;
2827 new_image=MotionBlurImage(_image,geometry_info.rho,geometry_info.sigma,
2828 geometry_info.xi,_exception);
2831 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2835 if (LocaleCompare("negate",option+1) == 0)
2837 (void) NegateImage(_image, IsPlusOp, _exception);
2840 if (LocaleCompare("noise",option+1) == 0)
2850 CLIWandWarnReplaced("-statistic NonPeak");
2851 (void) CLISimpleOperatorImage(cli_wand,"-statistic","NonPeak",arg1,exception);
2854 parse=ParseCommandOption(MagickNoiseOptions,MagickFalse,arg1);
2856 CLIWandExceptArgBreak(OptionError,"UnrecognizedNoiseType",
2859 value=GetImageOption(_image_info,"attenuate");
2860 if (value != (const char *) NULL)
2861 attenuate=StringToDouble(value,(char **) NULL);
2862 new_image=AddNoiseImage(_image,(NoiseType)parse,attenuate,
2866 if (LocaleCompare("normalize",option+1) == 0)
2868 (void) NormalizeImage(_image,_exception);
2871 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2875 if (LocaleCompare("opaque",option+1) == 0)
2880 (void) QueryColorCompliance(arg1,AllCompliance,&target,_exception);
2881 (void) OpaquePaintImage(_image,&target,&_draw_info->fill,IsPlusOp,
2885 if (LocaleCompare("ordered-dither",option+1) == 0)
2887 (void) OrderedDitherImage(_image,arg1,_exception);
2890 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
2894 if (LocaleCompare("paint",option+1) == 0)
2896 flags=ParseGeometry(arg1,&geometry_info);
2897 if ((flags & (RhoValue|SigmaValue)) == 0)
2898 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2899 new_image=OilPaintImage(_image,geometry_info.rho,geometry_info.sigma,
2903 if (LocaleCompare("perceptible",option+1) == 0)
2905 (void) PerceptibleImage(_image,StringToDouble(arg1,(char **) NULL),
2909 if (LocaleCompare("polaroid",option+1) == 0)
2921 random_info=AcquireRandomInfo();
2922 angle=22.5*(GetPseudoRandomValue(random_info)-0.5);
2923 random_info=DestroyRandomInfo(random_info);
2926 flags=ParseGeometry(arg1,&geometry_info);
2927 if ((flags & RhoValue) == 0)
2928 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2929 angle=geometry_info.rho;
2931 caption=GetImageProperty(_image,"caption",_exception);
2932 new_image=PolaroidImage(_image,_draw_info,caption,angle,
2933 _image->interpolate,_exception);
2936 if (LocaleCompare("posterize",option+1) == 0)
2938 flags=ParseGeometry(arg1,&geometry_info);
2939 if ((flags & RhoValue) == 0)
2940 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2941 (void) PosterizeImage(_image,(size_t) geometry_info.rho,
2942 _quantize_info->dither_method,_exception);
2945 if (LocaleCompare("preview",option+1) == 0)
2947 /* FUTURE: should be a 'Genesis' option?
2948 Option however is also in WandSettingOptionInfo()
2951 parse=ParseCommandOption(MagickPreviewOptions, MagickFalse,arg1);
2953 CLIWandExceptArgBreak(OptionError,"UnrecognizedPreviewType",
2955 new_image=PreviewImage(_image,(PreviewType)parse,_exception);
2958 if (LocaleCompare("profile",option+1) == 0)
2972 /* Note: arguments do not have percent escapes expanded */
2974 { /* Remove a profile from the _image. */
2975 (void) ProfileImage(_image,arg1,(const unsigned char *)
2979 /* Associate a profile with the _image. */
2980 profile_info=CloneImageInfo(_image_info);
2981 profile=GetImageProfile(_image,"iptc");
2982 if (profile != (StringInfo *) NULL)
2983 profile_info->profile=(void *) CloneStringInfo(profile);
2984 profile_image=GetImageCache(profile_info,arg1,_exception);
2985 profile_info=DestroyImageInfo(profile_info);
2986 if (profile_image == (Image *) NULL)
2991 profile_info=CloneImageInfo(_image_info);
2992 (void) CopyMagickString(profile_info->filename,arg1,
2994 profile=FileToStringInfo(profile_info->filename,~0UL,_exception);
2995 if (profile != (StringInfo *) NULL)
2997 (void) SetImageInfo(profile_info,0,_exception);
2998 (void) ProfileImage(_image,profile_info->magick,
2999 GetStringInfoDatum(profile),(size_t)
3000 GetStringInfoLength(profile),_exception);
3001 profile=DestroyStringInfo(profile);
3003 profile_info=DestroyImageInfo(profile_info);
3006 ResetImageProfileIterator(profile_image);
3007 name=GetNextImageProfile(profile_image);
3008 while (name != (const char *) NULL)
3010 profile=GetImageProfile(profile_image,name);
3011 if (profile != (StringInfo *) NULL)
3012 (void) ProfileImage(_image,name,GetStringInfoDatum(profile),
3013 (size_t) GetStringInfoLength(profile),_exception);
3014 name=GetNextImageProfile(profile_image);
3016 profile_image=DestroyImage(profile_image);
3019 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
3023 if (LocaleCompare("raise",option+1) == 0)
3025 if (IsGeometry(arg1) == MagickFalse)
3026 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3027 flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
3028 (void) RaiseImage(_image,&geometry,IsNormalOp,_exception);
3031 if (LocaleCompare("random-threshold",option+1) == 0)
3037 if (IsGeometry(arg1) == MagickFalse)
3038 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3040 max_threshold=(double) QuantumRange;
3041 flags=ParseGeometry(arg1,&geometry_info);
3042 min_threshold=geometry_info.rho;
3043 max_threshold=geometry_info.sigma;
3044 if ((flags & SigmaValue) == 0)
3045 max_threshold=min_threshold;
3046 if (strchr(arg1,'%') != (char *) NULL)
3048 max_threshold*=(double) (0.01*QuantumRange);
3049 min_threshold*=(double) (0.01*QuantumRange);
3051 (void) RandomThresholdImage(_image,min_threshold,max_threshold,
3055 if (LocaleCompare("range-threshold",option+1) == 0)
3058 Range threshold image.
3060 if (IsGeometry(arg1) == MagickFalse)
3061 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3062 flags=ParseGeometry(arg1,&geometry_info);
3063 if ((flags & SigmaValue) == 0)
3064 geometry_info.sigma=geometry_info.rho;
3065 if ((flags & XiValue) == 0)
3066 geometry_info.xi=geometry_info.sigma;
3067 if ((flags & PsiValue) == 0)
3068 geometry_info.psi=geometry_info.xi;
3069 if (strchr(arg1,'%') != (char *) NULL)
3071 geometry_info.rho*=(double) (0.01*QuantumRange);
3072 geometry_info.sigma*=(double) (0.01*QuantumRange);
3073 geometry_info.xi*=(double) (0.01*QuantumRange);
3074 geometry_info.psi*=(double) (0.01*QuantumRange);
3076 (void) RangeThresholdImage(_image,geometry_info.rho,
3077 geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception);
3080 if (LocaleCompare("read-mask",option+1) == 0)
3082 /* Note: arguments do not have percent escapes expanded */
3087 { /* Remove a mask. */
3088 (void) SetImageMask(_image,ReadPixelMask,(Image *) NULL,
3092 /* Set the image mask. */
3093 mask=GetImageCache(_image_info,arg1,_exception);
3094 if (mask == (Image *) NULL)
3096 (void) SetImageMask(_image,ReadPixelMask,mask,_exception);
3097 mask=DestroyImage(mask);
3100 if (LocaleCompare("recolor",option+1) == 0)
3102 CLIWandWarnReplaced("-color-matrix");
3103 (void) CLISimpleOperatorImage(cli_wand,"-color-matrix",arg1,NULL,
3106 if (LocaleCompare("region",option+1) == 0)
3110 (void) SetImageRegionMask(_image,WritePixelMask,
3111 (const RectangleInfo *) NULL,_exception);
3114 if (IsGeometry(arg1) == MagickFalse)
3115 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3116 (void) ParseGravityGeometry(_image,arg1,&geometry,_exception);
3117 (void) SetImageRegionMask(_image,WritePixelMask,&geometry,_exception);
3120 if (LocaleCompare("remap",option+1) == 0)
3122 /* Note: arguments do not have percent escapes expanded */
3126 remap_image=GetImageCache(_image_info,arg1,_exception);
3127 if (remap_image == (Image *) NULL)
3129 (void) RemapImage(_quantize_info,_image,remap_image,_exception);
3130 remap_image=DestroyImage(remap_image);
3133 if (LocaleCompare("repage",option+1) == 0)
3137 if (IsGeometry(arg1) == MagickFalse)
3138 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,
3140 (void) ResetImagePage(_image,arg1);
3143 (void) ParseAbsoluteGeometry("0x0+0+0",&_image->page);
3146 if (LocaleCompare("resample",option+1) == 0)
3148 /* FUTURE: Roll into a resize special operation */
3149 flags=ParseGeometry(arg1,&geometry_info);
3150 if ((flags & (RhoValue|SigmaValue)) == 0)
3151 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3152 if ((flags & SigmaValue) == 0)
3153 geometry_info.sigma=geometry_info.rho;
3154 new_image=ResampleImage(_image,geometry_info.rho,
3155 geometry_info.sigma,_image->filter,_exception);
3158 if (LocaleCompare("resize",option+1) == 0)
3160 if (IsGeometry(arg1) == MagickFalse)
3161 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3162 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
3163 new_image=ResizeImage(_image,geometry.width,geometry.height,
3164 _image->filter,_exception);
3167 if (LocaleCompare("roll",option+1) == 0)
3169 if (IsGeometry(arg1) == MagickFalse)
3170 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3171 flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
3172 if ((flags & PercentValue) != 0)
3174 geometry.x*=(double) _image->columns/100.0;
3175 geometry.y*=(double) _image->rows/100.0;
3177 new_image=RollImage(_image,geometry.x,geometry.y,_exception);
3180 if (LocaleCompare("rotate",option+1) == 0)
3182 flags=ParseGeometry(arg1,&geometry_info);
3183 if ((flags & RhoValue) == 0)
3184 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3185 if ((flags & GreaterValue) != 0 && (_image->columns <= _image->rows))
3187 if ((flags & LessValue) != 0 && (_image->columns >= _image->rows))
3189 new_image=RotateImage(_image,geometry_info.rho,_exception);
3192 if (LocaleCompare("rotational-blur",option+1) == 0)
3194 flags=ParseGeometry(arg1,&geometry_info);
3195 if ((flags & RhoValue) == 0)
3196 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3197 new_image=RotationalBlurImage(_image,geometry_info.rho,_exception);
3200 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
3204 if (LocaleCompare("sample",option+1) == 0)
3206 /* FUTURE: Roll into a resize special operator */
3207 if (IsGeometry(arg1) == MagickFalse)
3208 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3209 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
3210 new_image=SampleImage(_image,geometry.width,geometry.height,
3214 if (LocaleCompare("scale",option+1) == 0)
3216 /* FUTURE: Roll into a resize special operator */
3217 if (IsGeometry(arg1) == MagickFalse)
3218 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3219 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
3220 new_image=ScaleImage(_image,geometry.width,geometry.height,
3224 if (LocaleCompare("segment",option+1) == 0)
3226 flags=ParseGeometry(arg1,&geometry_info);
3227 if ((flags & (RhoValue|SigmaValue)) == 0)
3228 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3229 if ((flags & SigmaValue) == 0)
3230 geometry_info.sigma=1.0;
3231 (void) SegmentImage(_image,_image->colorspace,
3232 _image_info->verbose,geometry_info.rho,geometry_info.sigma,
3236 if (LocaleCompare("selective-blur",option+1) == 0)
3238 flags=ParseGeometry(arg1,&geometry_info);
3239 if ((flags & (RhoValue|SigmaValue)) == 0)
3240 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3241 if ((flags & SigmaValue) == 0)
3242 geometry_info.sigma=1.0;
3243 if ((flags & PercentValue) != 0)
3244 geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
3245 new_image=SelectiveBlurImage(_image,geometry_info.rho,
3246 geometry_info.sigma,geometry_info.xi,_exception);
3249 if (LocaleCompare("separate",option+1) == 0)
3251 /* WARNING: This can generate multiple images! */
3252 /* FUTURE - this may be replaced by a "-channel" method */
3253 new_image=SeparateImages(_image,_exception);
3256 if (LocaleCompare("sepia-tone",option+1) == 0)
3258 if (IsGeometry(arg1) == MagickFalse)
3259 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3260 new_image=SepiaToneImage(_image,StringToDoubleInterval(arg1,
3261 (double) QuantumRange+1.0),_exception);
3264 if (LocaleCompare("shade",option+1) == 0)
3266 flags=ParseGeometry(arg1,&geometry_info);
3267 if (((flags & RhoValue) == 0) || ((flags & SigmaValue) == 0))
3268 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3269 new_image=ShadeImage(_image,IsNormalOp,geometry_info.rho,
3270 geometry_info.sigma,_exception);
3273 if (LocaleCompare("shadow",option+1) == 0)
3275 flags=ParseGeometry(arg1,&geometry_info);
3276 if ((flags & (RhoValue|SigmaValue)) == 0)
3277 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3278 if ((flags & SigmaValue) == 0)
3279 geometry_info.sigma=1.0;
3280 if ((flags & XiValue) == 0)
3281 geometry_info.xi=4.0;
3282 if ((flags & PsiValue) == 0)
3283 geometry_info.psi=4.0;
3284 new_image=ShadowImage(_image,geometry_info.rho,geometry_info.sigma,
3285 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
3286 ceil(geometry_info.psi-0.5),_exception);
3289 if (LocaleCompare("sharpen",option+1) == 0)
3291 flags=ParseGeometry(arg1,&geometry_info);
3292 if ((flags & (RhoValue|SigmaValue)) == 0)
3293 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3294 if ((flags & SigmaValue) == 0)
3295 geometry_info.sigma=1.0;
3296 if ((flags & XiValue) == 0)
3297 geometry_info.xi=0.0;
3298 new_image=SharpenImage(_image,geometry_info.rho,geometry_info.sigma,
3302 if (LocaleCompare("shave",option+1) == 0)
3304 if (IsGeometry(arg1) == MagickFalse)
3305 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3306 flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
3307 new_image=ShaveImage(_image,&geometry,_exception);
3310 if (LocaleCompare("shear",option+1) == 0)
3312 flags=ParseGeometry(arg1,&geometry_info);
3313 if ((flags & RhoValue) == 0)
3314 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3315 if ((flags & SigmaValue) == 0)
3316 geometry_info.sigma=geometry_info.rho;
3317 new_image=ShearImage(_image,geometry_info.rho,geometry_info.sigma,
3321 if (LocaleCompare("sigmoidal-contrast",option+1) == 0)
3323 flags=ParseGeometry(arg1,&geometry_info);
3324 if ((flags & RhoValue) == 0)
3325 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3326 if ((flags & SigmaValue) == 0)
3327 geometry_info.sigma=(double) QuantumRange/2.0;
3328 if ((flags & PercentValue) != 0)
3329 geometry_info.sigma=(double) QuantumRange*geometry_info.sigma/
3331 (void) SigmoidalContrastImage(_image,IsNormalOp,geometry_info.rho,
3332 geometry_info.sigma,_exception);
3335 if (LocaleCompare("sketch",option+1) == 0)
3337 flags=ParseGeometry(arg1,&geometry_info);
3338 if ((flags & (RhoValue|SigmaValue)) == 0)
3339 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3340 if ((flags & SigmaValue) == 0)
3341 geometry_info.sigma=1.0;
3342 new_image=SketchImage(_image,geometry_info.rho,
3343 geometry_info.sigma,geometry_info.xi,_exception);
3346 if (LocaleCompare("solarize",option+1) == 0)
3348 if (IsGeometry(arg1) == MagickFalse)
3349 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3350 (void) SolarizeImage(_image,StringToDoubleInterval(arg1,(double)
3351 QuantumRange+1.0),_exception);
3354 if (LocaleCompare("sparse-color",option+1) == 0)
3356 parse= ParseCommandOption(MagickSparseColorOptions,MagickFalse,arg1);
3358 CLIWandExceptArgBreak(OptionError,"UnrecognizedSparseColorMethod",
3360 new_image=SparseColorOption(_image,(SparseColorMethod)parse,arg2,
3364 if (LocaleCompare("splice",option+1) == 0)
3366 if (IsGeometry(arg1) == MagickFalse)
3367 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3368 flags=ParseGravityGeometry(_image,arg1,&geometry,_exception);
3369 new_image=SpliceImage(_image,&geometry,_exception);
3372 if (LocaleCompare("spread",option+1) == 0)
3374 flags=ParseGeometry(arg1,&geometry_info);
3375 if ((flags & RhoValue) == 0)
3376 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
3377 new_image=SpreadImage(_image,_image->interpolate,geometry_info.rho,
3381 if (LocaleCompare("statistic",option+1) == 0)
3383 parse=ParseCommandOption(MagickStatisticOptions,MagickFalse,arg1);
3385 CLIWandExceptArgBreak(OptionError,"UnrecognizedStatisticType",
3387 flags=ParseGeometry(arg2,&geometry_info);
3388 if ((flags & RhoValue) == 0)
3389 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
3390 if ((flags & SigmaValue) == 0)
3391 geometry_info.sigma=geometry_info.rho;
3392 new_image=StatisticImage(_image,(StatisticType)parse,
3393 (size_t) geometry_info.rho,(size_t) geometry_info.sigma,
3397 if (LocaleCompare("strip",option+1) == 0)
3399 (void) StripImage(_image,_exception);
3402 if (LocaleCompare("swirl",option+1) == 0)
3404 flags=ParseGeometry(arg1,&geometry_info);
3405 if ((flags & RhoValue) == 0)
3406 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3407 new_image=SwirlImage(_image,geometry_info.rho,
3408 _image->interpolate,_exception);
3411 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
3415 if (LocaleCompare("threshold",option+1) == 0)
3420 threshold=(double) QuantumRange/2;
3422 if (IsGeometry(arg1) == MagickFalse)
3423 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3424 threshold=StringToDoubleInterval(arg1,(double) QuantumRange+1.0);
3426 (void) BilevelImage(_image,threshold,_exception);
3429 if (LocaleCompare("thumbnail",option+1) == 0)
3431 if (IsGeometry(arg1) == MagickFalse)
3432 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3433 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
3434 new_image=ThumbnailImage(_image,geometry.width,geometry.height,
3438 if (LocaleCompare("tint",option+1) == 0)
3440 if (IsGeometry(arg1) == MagickFalse)
3441 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3442 new_image=TintImage(_image,arg1,&_draw_info->fill,_exception);
3445 if (LocaleCompare("transform",option+1) == 0)
3447 CLIWandWarnReplaced("+distort AffineProjection");
3448 new_image=AffineTransformImage(_image,&_draw_info->affine,_exception);
3451 if (LocaleCompare("transparent",option+1) == 0)
3456 (void) QueryColorCompliance(arg1,AllCompliance,&target,_exception);
3457 (void) TransparentPaintImage(_image,&target,(Quantum)
3458 TransparentAlpha,IsPlusOp,_exception);
3461 if (LocaleCompare("transpose",option+1) == 0)
3463 new_image=TransposeImage(_image,_exception);
3466 if (LocaleCompare("transverse",option+1) == 0)
3468 new_image=TransverseImage(_image,_exception);
3471 if (LocaleCompare("trim",option+1) == 0)
3473 new_image=TrimImage(_image,_exception);
3476 if (LocaleCompare("type",option+1) == 0)
3478 /* Note that "type" setting should have already been defined */
3479 (void) SetImageType(_image,_image_info->type,_exception);
3482 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
3486 if (LocaleCompare("unique",option+1) == 0)
3488 /* FUTURE: move to SyncImageSettings() and AcqireImage()???
3489 Option is not documented, bt appears to be for "identify".
3490 We may need a identify specific verbose!
3493 (void) DeleteImageArtifact(_image,"identify:unique-colors");
3496 (void) SetImageArtifact(_image,"identify:unique-colors","true");
3497 (void) SetImageArtifact(_image,"verbose","true");
3500 if (LocaleCompare("unique-colors",option+1) == 0)
3502 new_image=UniqueImageColors(_image,_exception);
3505 if (LocaleCompare("unsharp",option+1) == 0)
3507 flags=ParseGeometry(arg1,&geometry_info);
3508 if ((flags & (RhoValue|SigmaValue)) == 0)
3509 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3510 if ((flags & SigmaValue) == 0)
3511 geometry_info.sigma=1.0;
3512 if ((flags & XiValue) == 0)
3513 geometry_info.xi=1.0;
3514 if ((flags & PsiValue) == 0)
3515 geometry_info.psi=0.05;
3516 new_image=UnsharpMaskImage(_image,geometry_info.rho,
3517 geometry_info.sigma,geometry_info.xi,geometry_info.psi,_exception);
3520 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
3524 if (LocaleCompare("verbose",option+1) == 0)
3526 /* FUTURE: move to SyncImageSettings() and AcquireImage()???
3527 three places! ImageArtifact ImageOption _image_info->verbose
3528 Some how new images also get this artifact!
3530 (void) SetImageArtifact(_image,option+1,
3531 IfNormalOp ? "true" : "false" );
3534 if (LocaleCompare("vignette",option+1) == 0)
3536 flags=ParseGeometry(arg1,&geometry_info);
3537 if ((flags & (RhoValue|SigmaValue)) == 0)
3538 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3539 if ((flags & SigmaValue) == 0)
3540 geometry_info.sigma=1.0;
3541 if ((flags & XiValue) == 0)
3542 geometry_info.xi=0.1*_image->columns;
3543 if ((flags & PsiValue) == 0)
3544 geometry_info.psi=0.1*_image->rows;
3545 if ((flags & PercentValue) != 0)
3547 geometry_info.xi*=(double) _image->columns/100.0;
3548 geometry_info.psi*=(double) _image->rows/100.0;
3550 new_image=VignetteImage(_image,geometry_info.rho,geometry_info.sigma,
3551 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
3552 ceil(geometry_info.psi-0.5),_exception);
3555 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
3559 if (LocaleCompare("wave",option+1) == 0)
3561 flags=ParseGeometry(arg1,&geometry_info);
3562 if ((flags & (RhoValue|SigmaValue)) == 0)
3563 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3564 if ((flags & SigmaValue) == 0)
3565 geometry_info.sigma=1.0;
3566 new_image=WaveImage(_image,geometry_info.rho,geometry_info.sigma,
3567 _image->interpolate,_exception);
3570 if (LocaleCompare("wavelet-denoise",option+1) == 0)
3572 flags=ParseGeometry(arg1,&geometry_info);
3573 if ((flags & RhoValue) == 0)
3574 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3575 if ((flags & PercentValue) != 0)
3577 geometry_info.rho=QuantumRange*geometry_info.rho/100.0;
3578 geometry_info.sigma=QuantumRange*geometry_info.sigma/100.0;
3580 if ((flags & SigmaValue) == 0)
3581 geometry_info.sigma=0.0;
3582 new_image=WaveletDenoiseImage(_image,geometry_info.rho,
3583 geometry_info.sigma,_exception);
3586 if (LocaleCompare("white-threshold",option+1) == 0)
3588 if (IsGeometry(arg1) == MagickFalse)
3589 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3590 (void) WhiteThresholdImage(_image,arg1,_exception);
3593 if (LocaleCompare("write-mask",option+1) == 0)
3595 /* Note: arguments do not have percent escapes expanded */
3600 { /* Remove a mask. */
3601 (void) SetImageMask(_image,WritePixelMask,(Image *) NULL,
3605 /* Set the image mask. */
3606 mask=GetImageCache(_image_info,arg1,_exception);
3607 if (mask == (Image *) NULL)
3609 (void) SetImageMask(_image,WritePixelMask,mask,_exception);
3610 mask=DestroyImage(mask);
3613 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
3616 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
3618 /* clean up percent escape interpreted strings */
3620 arg1=DestroyString((char *)arg1);
3622 arg2=DestroyString((char *)arg2);
3624 /* Replace current image with any image that was generated
3625 and set image point to last image (so image->next is correct) */
3626 if (new_image != (Image *) NULL)
3627 ReplaceImageInListReturnLast(&_image,new_image);
3632 #undef _quantize_info
3641 WandPrivate MagickBooleanType CLISimpleOperatorImages(MagickCLI *cli_wand,
3642 const char *option,const char *arg1,const char *arg2,ExceptionInfo *exception)
3644 #if !USE_WAND_METHODS
3650 assert(cli_wand != (MagickCLI *) NULL);
3651 assert(cli_wand->signature == MagickWandSignature);
3652 assert(cli_wand->wand.signature == MagickWandSignature);
3653 assert(cli_wand->wand.images != (Image *) NULL); /* images must be present */
3655 if (cli_wand->wand.debug != MagickFalse)
3656 (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(),
3657 "- Simple Operator: %s \"%s\" \"%s\"", option,arg1,arg2);
3659 #if !USE_WAND_METHODS
3660 /* FUTURE add appropriate tracing */
3662 n=GetImageListLength(cli_wand->wand.images);
3663 cli_wand->wand.images=GetFirstImageInList(cli_wand->wand.images);
3666 CLISimpleOperatorImage(cli_wand, option, arg1, arg2,exception);
3667 if ( cli_wand->wand.images->next == (Image *) NULL )
3669 cli_wand->wand.images=cli_wand->wand.images->next;
3672 cli_wand->wand.images=GetFirstImageInList(cli_wand->wand.images);
3674 MagickResetIterator(&cli_wand->wand);
3675 while (MagickNextImage(&cli_wand->wand) != MagickFalse)
3676 (void) CLISimpleOperatorImage(cli_wand, option, arg1, arg2,exception);
3677 MagickResetIterator(&cli_wand->wand);
3683 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3687 + C L I L i s t O p e r a t o r I m a g e s %
3691 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3693 % CLIListOperatorImages() applies a single operation that is apply to the
3694 % entire image list as a whole. The result is often a complete replacment
3695 % of the image list with a completely new list, or with just a single image
3698 % The format of the MogrifyImage method is:
3700 % MagickBooleanType CLIListOperatorImages(MagickCLI *cli_wand,
3701 % const char *option,const char *arg1,const char *arg2)
3703 % A description of each parameter follows:
3705 % o cli_wand: structure holding settings to be applied
3707 % o option: The option string for the operation
3709 % o arg1, arg2: optional argument strings to the operation
3710 % arg2 is currently not used
3713 WandPrivate MagickBooleanType CLIListOperatorImages(MagickCLI *cli_wand,
3714 const char *option,const char *arg1n,const char *arg2n)
3716 const char /* percent escaped versions of the args */
3729 #define _image_info (cli_wand->wand.image_info)
3730 #define _images (cli_wand->wand.images)
3731 #define _exception (cli_wand->wand.exception)
3732 #define _draw_info (cli_wand->draw_info)
3733 #define _quantize_info (cli_wand->quantize_info)
3734 #define _process_flags (cli_wand->process_flags)
3735 #define _option_type ((CommandOptionFlags) cli_wand->command->flags)
3736 #define IfNormalOp (*option=='-')
3737 #define IfPlusOp (*option!='-')
3738 #define IsNormalOp IfNormalOp ? MagickTrue : MagickFalse
3740 assert(cli_wand != (MagickCLI *) NULL);
3741 assert(cli_wand->signature == MagickWandSignature);
3742 assert(cli_wand->wand.signature == MagickWandSignature);
3743 assert(_images != (Image *) NULL); /* _images must be present */
3745 if (cli_wand->wand.debug != MagickFalse)
3746 (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(),
3747 "- List Operator: %s \"%s\" \"%s\"", option,
3748 arg1n == (const char *) NULL ? "null" : arg1n,
3749 arg2n == (const char *) NULL ? "null" : arg2n);
3754 /* Interpret Percent Escapes in Arguments - using first image */
3755 if ( (((_process_flags & ProcessInterpretProperities) != 0 )
3756 || ((_option_type & AlwaysInterpretArgsFlag) != 0)
3757 ) && ((_option_type & NeverInterpretArgsFlag) == 0) ) {
3758 /* Interpret Percent escapes in argument 1 */
3759 if (arg1n != (char *) NULL) {
3760 arg1=InterpretImageProperties(_image_info,_images,arg1n,_exception);
3761 if (arg1 == (char *) NULL) {
3762 CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
3763 arg1=arg1n; /* use the given argument as is */
3766 if (arg2n != (char *) NULL) {
3767 arg2=InterpretImageProperties(_image_info,_images,arg2n,_exception);
3768 if (arg2 == (char *) NULL) {
3769 CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
3770 arg2=arg2n; /* use the given argument as is */
3774 #undef _process_flags
3778 new_images=NewImageList();
3780 switch (*(option+1))
3784 if (LocaleCompare("append",option+1) == 0)
3786 new_images=AppendImages(_images,IsNormalOp,_exception);
3789 if (LocaleCompare("average",option+1) == 0)
3791 CLIWandWarnReplaced("-evaluate-sequence Mean");
3792 (void) CLIListOperatorImages(cli_wand,"-evaluate-sequence","Mean",
3796 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
3800 if (LocaleCompare("channel-fx",option+1) == 0)
3802 new_images=ChannelFxImage(_images,arg1,_exception);
3805 if (LocaleCompare("clut",option+1) == 0)
3810 /* FUTURE - make this a compose option, and thus can be used
3811 with layers compose or even compose last image over all other
3814 new_images=RemoveFirstImageFromList(&_images);
3815 clut_image=RemoveLastImageFromList(&_images);
3816 /* FUTURE - produce Exception, rather than silent fail */
3817 if (clut_image == (Image *) NULL)
3819 (void) ClutImage(new_images,clut_image,new_images->interpolate,
3821 clut_image=DestroyImage(clut_image);
3824 if (LocaleCompare("coalesce",option+1) == 0)
3826 new_images=CoalesceImages(_images,_exception);
3829 if (LocaleCompare("combine",option+1) == 0)
3831 parse=(ssize_t) _images->colorspace;
3832 if (_images->number_channels < GetImageListLength(_images))
3833 parse=sRGBColorspace;
3835 parse=ParseCommandOption(MagickColorspaceOptions,MagickFalse,arg1);
3837 CLIWandExceptArgBreak(OptionError,"UnrecognizedColorspace",option,
3839 new_images=CombineImages(_images,(ColorspaceType) parse,_exception);
3842 if (LocaleCompare("compare",option+1) == 0)
3855 Mathematically and visually annotate the difference between an
3856 image and its reconstruction.
3858 image=RemoveFirstImageFromList(&_images);
3859 reconstruct_image=RemoveFirstImageFromList(&_images);
3860 /* FUTURE - produce Exception, rather than silent fail */
3861 if (reconstruct_image == (Image *) NULL)
3863 metric=UndefinedErrorMetric;
3864 option=GetImageOption(_image_info,"metric");
3865 if (option != (const char *) NULL)
3866 metric=(MetricType) ParseCommandOption(MagickMetricOptions,
3867 MagickFalse,option);
3868 new_images=CompareImages(image,reconstruct_image,metric,&distortion,
3871 reconstruct_image=DestroyImage(reconstruct_image);
3872 image=DestroyImage(image);
3875 if (LocaleCompare("complex",option+1) == 0)
3877 parse=ParseCommandOption(MagickComplexOptions,MagickFalse,arg1);
3879 CLIWandExceptArgBreak(OptionError,"UnrecognizedEvaluateOperator",
3881 new_images=ComplexImages(_images,(ComplexOperator) parse,_exception);
3884 if (LocaleCompare("composite",option+1) == 0)
3902 /* Compose value from "-compose" option only */
3903 value=GetImageOption(_image_info,"compose");
3904 if (value == (const char *) NULL)
3905 compose=OverCompositeOp; /* use Over not source_image->compose */
3907 compose=(CompositeOperator) ParseCommandOption(MagickComposeOptions,
3910 /* Get "clip-to-self" expert setting (false is normal) */
3911 clip_to_self=GetCompositeClipToSelf(compose);
3912 value=GetImageOption(_image_info,"compose:clip-to-self");
3913 if (value != (const char *) NULL)
3914 clip_to_self=IsStringTrue(value);
3915 value=GetImageOption(_image_info,"compose:outside-overlay");
3916 if (value != (const char *) NULL)
3917 clip_to_self=IsStringFalse(value); /* deprecated */
3919 new_images=RemoveFirstImageFromList(&_images);
3920 source_image=RemoveFirstImageFromList(&_images);
3921 if (source_image == (Image *) NULL)
3922 break; /* FUTURE - produce Exception, rather than silent fail */
3924 /* FUTURE - this should not be here! - should be part of -geometry */
3925 if (source_image->geometry != (char *) NULL)
3930 (void) ParseRegionGeometry(source_image,source_image->geometry,
3931 &resize_geometry,_exception);
3932 if ((source_image->columns != resize_geometry.width) ||
3933 (source_image->rows != resize_geometry.height))
3938 resize_image=ResizeImage(source_image,resize_geometry.width,
3939 resize_geometry.height,source_image->filter,_exception);
3940 if (resize_image != (Image *) NULL)
3942 source_image=DestroyImage(source_image);
3943 source_image=resize_image;
3947 SetGeometry(source_image,&geometry);
3948 (void) ParseAbsoluteGeometry(source_image->geometry,&geometry);
3949 GravityAdjustGeometry(new_images->columns,new_images->rows,
3950 new_images->gravity, &geometry);
3951 mask_image=RemoveFirstImageFromList(&_images);
3952 if (mask_image == (Image *) NULL)
3953 status&=CompositeImage(new_images,source_image,compose,clip_to_self,
3954 geometry.x,geometry.y,_exception);
3957 if ((compose == DisplaceCompositeOp) ||
3958 (compose == DistortCompositeOp))
3960 status&=CompositeImage(source_image,mask_image,
3961 CopyGreenCompositeOp,MagickTrue,0,0,_exception);
3962 status&=CompositeImage(new_images,source_image,compose,
3963 clip_to_self,geometry.x,geometry.y,_exception);
3970 clone_image=CloneImage(new_images,0,0,MagickTrue,_exception);
3971 if (clone_image == (Image *) NULL)
3973 status&=CompositeImage(new_images,source_image,compose,
3974 clip_to_self,geometry.x,geometry.y,_exception);
3975 status&=CompositeImage(new_images,mask_image,
3976 CopyAlphaCompositeOp,MagickTrue,0,0,_exception);
3977 status&=CompositeImage(clone_image,new_images,OverCompositeOp,
3978 clip_to_self,0,0,_exception);
3979 new_images=DestroyImage(new_images);
3980 new_images=clone_image;
3982 mask_image=DestroyImage(mask_image);
3984 source_image=DestroyImage(source_image);
3987 if (LocaleCompare("copy",option+1) == 0)
4001 if (IsGeometry(arg1) == MagickFalse)
4002 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
4003 if (IsGeometry(arg2) == MagickFalse)
4004 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
4005 (void) ParsePageGeometry(_images,arg2,&geometry,_exception);
4006 offset.x=geometry.x;
4007 offset.y=geometry.y;
4008 source_image=_images;
4009 if (source_image->next != (Image *) NULL)
4010 source_image=source_image->next;
4011 (void) ParsePageGeometry(source_image,arg1,&geometry,_exception);
4012 (void) CopyImagePixels(_images,source_image,&geometry,&offset,
4016 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4020 if (LocaleCompare("deconstruct",option+1) == 0)
4022 CLIWandWarnReplaced("-layer CompareAny");
4023 (void) CLIListOperatorImages(cli_wand,"-layer","CompareAny",NULL);
4026 if (LocaleCompare("delete",option+1) == 0)
4029 DeleteImages(&_images,arg1,_exception);
4031 DeleteImages(&_images,"-1",_exception);
4034 if (LocaleCompare("duplicate",option+1) == 0)
4044 if (IsGeometry(arg1) == MagickFalse)
4045 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,
4047 number_duplicates=(size_t) StringToLong(arg1);
4049 if (p == (const char *) NULL)
4050 new_images=DuplicateImages(_images,number_duplicates,"-1",
4053 new_images=DuplicateImages(_images,number_duplicates,p,
4057 new_images=DuplicateImages(_images,1,"-1",_exception);
4058 AppendImageToList(&_images, new_images);
4059 new_images=(Image *) NULL;
4062 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4066 if (LocaleCompare("evaluate-sequence",option+1) == 0)
4068 parse=ParseCommandOption(MagickEvaluateOptions,MagickFalse,arg1);
4070 CLIWandExceptArgBreak(OptionError,"UnrecognizedEvaluateOperator",
4072 new_images=EvaluateImages(_images,(MagickEvaluateOperator)parse,
4076 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4080 if (LocaleCompare("fft",option+1) == 0)
4082 new_images=ForwardFourierTransformImage(_images,IsNormalOp,
4086 if (LocaleCompare("flatten",option+1) == 0)
4088 /* REDIRECTED to use -layers flatten instead */
4089 (void) CLIListOperatorImages(cli_wand,"-layers",option+1,NULL);
4092 if (LocaleCompare("fx",option+1) == 0)
4094 new_images=FxImage(_images,arg1,_exception);
4097 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4101 if (LocaleCompare("hald-clut",option+1) == 0)
4103 /* FUTURE - make this a compose option (and thus layers compose )
4104 or perhaps compose last image over all other _images.
4109 new_images=RemoveFirstImageFromList(&_images);
4110 hald_image=RemoveLastImageFromList(&_images);
4111 if (hald_image == (Image *) NULL)
4113 (void) HaldClutImage(new_images,hald_image,_exception);
4114 hald_image=DestroyImage(hald_image);
4117 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4121 if (LocaleCompare("ift",option+1) == 0)
4127 magnitude_image=RemoveFirstImageFromList(&_images);
4128 phase_image=RemoveFirstImageFromList(&_images);
4129 /* FUTURE - produce Exception, rather than silent fail */
4130 if (phase_image == (Image *) NULL)
4132 new_images=InverseFourierTransformImage(magnitude_image,phase_image,
4133 IsNormalOp,_exception);
4134 magnitude_image=DestroyImage(magnitude_image);
4135 phase_image=DestroyImage(phase_image);
4138 if (LocaleCompare("insert",option+1) == 0)
4147 if (IfNormalOp && (IsGeometry(arg1) == MagickFalse))
4148 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
4150 insert_image=RemoveLastImageFromList(&_images);
4152 index=(ssize_t) StringToLong(arg1);
4153 index_image=insert_image;
4155 PrependImageToList(&_images,insert_image);
4156 else if (index == (ssize_t) GetImageListLength(_images))
4157 AppendImageToList(&_images,insert_image);
4160 index_image=GetImageFromList(_images,index-1);
4161 if (index_image == (Image *) NULL)
4162 CLIWandExceptArgBreak(OptionError,"NoSuchImage",option,arg1);
4163 InsertImageInList(&index_image,insert_image);
4165 _images=GetFirstImageInList(index_image);
4168 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4172 if (LocaleCompare("layers",option+1) == 0)
4174 parse=ParseCommandOption(MagickLayerOptions,MagickFalse,arg1);
4176 CLIWandExceptArgBreak(OptionError,"UnrecognizedLayerMethod",
4178 switch ((LayerMethod) parse)
4182 new_images=CoalesceImages(_images,_exception);
4185 case CompareAnyLayer:
4186 case CompareClearLayer:
4187 case CompareOverlayLayer:
4190 new_images=CompareImagesLayers(_images,(LayerMethod) parse,
4197 case TrimBoundsLayer:
4199 new_images=MergeImageLayers(_images,(LayerMethod) parse,
4205 new_images=DisposeImages(_images,_exception);
4208 case OptimizeImageLayer:
4210 new_images=OptimizeImageLayers(_images,_exception);
4213 case OptimizePlusLayer:
4215 new_images=OptimizePlusImageLayers(_images,_exception);
4218 case OptimizeTransLayer:
4220 OptimizeImageTransparency(_images,_exception);
4223 case RemoveDupsLayer:
4225 RemoveDuplicateLayers(&_images,_exception);
4228 case RemoveZeroLayer:
4230 RemoveZeroDelayLayers(&_images,_exception);
4234 { /* General Purpose, GIF Animation Optimizer. */
4235 new_images=CoalesceImages(_images,_exception);
4236 if (new_images == (Image *) NULL)
4238 _images=DestroyImageList(_images);
4239 _images=OptimizeImageLayers(new_images,_exception);
4240 if (_images == (Image *) NULL)
4242 new_images=DestroyImageList(new_images);
4243 OptimizeImageTransparency(_images,_exception);
4244 (void) RemapImages(_quantize_info,_images,(Image *) NULL,
4248 case CompositeLayer:
4262 value=GetImageOption(_image_info,"compose");
4263 compose=OverCompositeOp; /* Default to Over */
4264 if (value != (const char *) NULL)
4265 compose=(CompositeOperator) ParseCommandOption(
4266 MagickComposeOptions,MagickFalse,value);
4268 /* Split image sequence at the first 'NULL:' image. */
4270 while (source != (Image *) NULL)
4272 source=GetNextImageInList(source);
4273 if ((source != (Image *) NULL) &&
4274 (LocaleCompare(source->magick,"NULL") == 0))
4277 if (source != (Image *) NULL)
4279 if ((GetPreviousImageInList(source) == (Image *) NULL) ||
4280 (GetNextImageInList(source) == (Image *) NULL))
4281 source=(Image *) NULL;
4283 { /* Separate the two lists, junk the null: image. */
4284 source=SplitImageList(source->previous);
4285 DeleteImageFromList(&source);
4288 if (source == (Image *) NULL)
4290 (void) ThrowMagickException(_exception,GetMagickModule(),
4291 OptionError,"MissingNullSeparator","layers Composite");
4294 /* Adjust offset with gravity and virtual canvas. */
4295 SetGeometry(_images,&geometry);
4296 (void) ParseAbsoluteGeometry(_images->geometry,&geometry);
4297 geometry.width=source->page.width != 0 ?
4298 source->page.width : source->columns;
4299 geometry.height=source->page.height != 0 ?
4300 source->page.height : source->rows;
4301 GravityAdjustGeometry(_images->page.width != 0 ?
4302 _images->page.width : _images->columns,
4303 _images->page.height != 0 ? _images->page.height :
4304 _images->rows,_images->gravity,&geometry);
4306 /* Compose the two image sequences together */
4307 CompositeLayers(_images,compose,source,geometry.x,geometry.y,
4309 source=DestroyImageList(source);
4315 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4319 if (LocaleCompare("map",option+1) == 0)
4321 CLIWandWarnReplaced("+remap");
4322 (void) RemapImages(_quantize_info,_images,(Image *) NULL,_exception);
4325 if (LocaleCompare("metric",option+1) == 0)
4327 (void) SetImageOption(_image_info,option+1,arg1);
4330 if (LocaleCompare("morph",option+1) == 0)
4335 if (IsGeometry(arg1) == MagickFalse)
4336 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
4337 morph_image=MorphImages(_images,StringToUnsignedLong(arg1),
4339 if (morph_image == (Image *) NULL)
4341 _images=DestroyImageList(_images);
4342 _images=morph_image;
4345 if (LocaleCompare("mosaic",option+1) == 0)
4347 /* REDIRECTED to use -layers mosaic instead */
4348 (void) CLIListOperatorImages(cli_wand,"-layers",option+1,NULL);
4351 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4355 if (LocaleCompare("poly",option+1) == 0)
4363 /* convert argument string into an array of doubles */
4364 args = StringToArrayOfDoubles(arg1,&count,_exception);
4365 if (args == (double *) NULL )
4366 CLIWandExceptArgBreak(OptionError,"InvalidNumberList",option,arg1);
4367 new_images=PolynomialImage(_images,(size_t) (count >> 1),args,
4369 args=(double *) RelinquishMagickMemory(args);
4372 if (LocaleCompare("process",option+1) == 0)
4374 /* FUTURE: better parsing using ScriptToken() from string ??? */
4382 arguments=StringToArgv(arg1,&number_arguments);
4383 if (arguments == (char **) NULL)
4385 if (strchr(arguments[1],'=') != (char *) NULL)
4406 Support old style syntax, filter="-option arg1".
4408 assert(arg1 != (const char *) NULL);
4409 length=strlen(arg1);
4410 token=(char *) NULL;
4411 if (~length >= (MagickPathExtent-1))
4412 token=(char *) AcquireQuantumMemory(length+MagickPathExtent,
4414 if (token == (char *) NULL)
4418 token_info=AcquireTokenInfo();
4419 status=Tokenizer(token_info,0,token,length,arguments,"","=",
4420 "\"",'\0',&breaker,&next,"e);
4421 token_info=DestroyTokenInfo(token_info);
4427 argv=(&(arguments[next]));
4428 (void) InvokeDynamicImageFilter(token,&_images,1,&argv,
4431 token=DestroyString(token);
4434 (void) SubstituteString(&arguments[1],"-","");
4435 (void) InvokeDynamicImageFilter(arguments[1],&_images,
4436 number_arguments-2,(const char **) arguments+2,_exception);
4437 for (j=0; j < number_arguments; j++)
4438 arguments[j]=DestroyString(arguments[j]);
4439 arguments=(char **) RelinquishMagickMemory(arguments);
4442 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4446 if (LocaleCompare("remap",option+1) == 0)
4448 (void) RemapImages(_quantize_info,_images,(Image *) NULL,_exception);
4451 if (LocaleCompare("reverse",option+1) == 0)
4453 ReverseImageList(&_images);
4456 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4460 if (LocaleCompare("smush",option+1) == 0)
4462 /* FUTURE: this option needs more work to make better */
4466 if (IsGeometry(arg1) == MagickFalse)
4467 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
4468 offset=(ssize_t) StringToLong(arg1);
4469 new_images=SmushImages(_images,IsNormalOp,offset,_exception);
4472 if (LocaleCompare("subimage",option+1) == 0)
4490 base_image=GetImageFromList(_images,0);
4491 compare_image=GetImageFromList(_images,1);
4493 /* Comparision Metric */
4494 metric=UndefinedErrorMetric;
4495 value=GetImageOption(_image_info,"metric");
4496 if (value != (const char *) NULL)
4497 metric=(MetricType) ParseCommandOption(MagickMetricOptions,
4500 new_images=SimilarityImage(base_image,compare_image,metric,0.0,
4501 &offset,&similarity,_exception);
4503 if (new_images != (Image *) NULL)
4506 result[MagickPathExtent];
4508 (void) FormatLocaleString(result,MagickPathExtent,"%lf",
4510 (void) SetImageProperty(new_images,"subimage:similarity",result,
4512 (void) FormatLocaleString(result,MagickPathExtent,"%+ld",(long)
4514 (void) SetImageProperty(new_images,"subimage:x",result,
4516 (void) FormatLocaleString(result,MagickPathExtent,"%+ld",(long)
4518 (void) SetImageProperty(new_images,"subimage:y",result,
4520 (void) FormatLocaleString(result,MagickPathExtent,
4521 "%lux%lu%+ld%+ld",(unsigned long) offset.width,(unsigned long)
4522 offset.height,(long) offset.x,(long) offset.y);
4523 (void) SetImageProperty(new_images,"subimage:offset",result,
4528 if (LocaleCompare("swap",option+1) == 0)
4549 flags=ParseGeometry(arg1,&geometry_info);
4550 if ((flags & RhoValue) == 0)
4551 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
4552 index=(ssize_t) geometry_info.rho;
4553 if ((flags & SigmaValue) != 0)
4554 swap_index=(ssize_t) geometry_info.sigma;
4556 p=GetImageFromList(_images,index);
4557 q=GetImageFromList(_images,swap_index);
4558 if ((p == (Image *) NULL) || (q == (Image *) NULL)) {
4560 CLIWandExceptArgBreak(OptionError,"InvalidImageIndex",option,arg1)
4562 CLIWandExceptionBreak(OptionError,"TwoOrMoreImagesRequired",option);
4565 CLIWandExceptArgBreak(OptionError,"InvalidImageIndex",option,arg1);
4566 swap=CloneImage(p,0,0,MagickTrue,_exception);
4567 if (swap == (Image *) NULL)
4568 CLIWandExceptArgBreak(ResourceLimitError,"MemoryAllocationFailed",
4569 option,GetExceptionMessage(errno));
4570 ReplaceImageInList(&p,CloneImage(q,0,0,MagickTrue,_exception));
4571 ReplaceImageInList(&q,swap);
4572 _images=GetFirstImageInList(q);
4575 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4578 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
4581 /* clean up percent escape interpreted strings */
4583 arg1=DestroyString((char *)arg1);
4585 arg2=DestroyString((char *)arg2);
4587 /* if new image list generated, replace existing image list */
4588 if (new_images == (Image *) NULL)
4589 return(status == 0 ? MagickFalse : MagickTrue);
4590 _images=DestroyImageList(_images);
4591 _images=GetFirstImageInList(new_images);
4592 return(status == 0 ? MagickFalse : MagickTrue);
4598 #undef _quantize_info
4605 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4609 + C L I N o I m a g e O p e r a t i o n s %
4613 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4615 % CLINoImageOperator() Applies operations that may not actually need images
4618 % The classic operators of this type is "-read", which actually creates
4619 % images even when no images are present. Or image stack operators, which
4620 % can be applied (push or pop) to an empty image list.
4622 % Note that these operators may involve other special 'option' prefix
4623 % characters other than '-' or '+', namely parenthesis and braces.
4625 % The format of the CLINoImageOption method is:
4627 % void CLINoImageOption(MagickCLI *cli_wand,const char *option,
4628 % const char *arg1, const char *arg2)
4630 % A description of each parameter follows:
4632 % o cli_wand: the main CLI Wand to use. (sometimes not required)
4634 % o option: The special option (with any switch char) to process
4636 % o arg1 & arg2: Argument for option, if required
4637 % Currently arg2 is not used.
4640 WandPrivate void CLINoImageOperator(MagickCLI *cli_wand,
4641 const char *option,const char *arg1n,const char *arg2n)
4643 const char /* percent escaped versions of the args */
4647 #define _image_info (cli_wand->wand.image_info)
4648 #define _images (cli_wand->wand.images)
4649 #define _exception (cli_wand->wand.exception)
4650 #define _process_flags (cli_wand->process_flags)
4651 #define _option_type ((CommandOptionFlags) cli_wand->command->flags)
4652 #define IfNormalOp (*option=='-')
4653 #define IfPlusOp (*option!='-')
4655 assert(cli_wand != (MagickCLI *) NULL);
4656 assert(cli_wand->signature == MagickWandSignature);
4657 assert(cli_wand->wand.signature == MagickWandSignature);
4659 if (cli_wand->wand.debug != MagickFalse)
4660 (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(),
4661 "- NoImage Operator: %s \"%s\" \"%s\"", option,
4662 arg1n != (char *) NULL ? arg1n : "",
4663 arg2n != (char *) NULL ? arg2n : "");
4668 /* Interpret Percent Escapes in Arguments - using first image */
4669 if ( (((_process_flags & ProcessInterpretProperities) != 0 )
4670 || ((_option_type & AlwaysInterpretArgsFlag) != 0)
4671 ) && ((_option_type & NeverInterpretArgsFlag) == 0) ) {
4672 /* Interpret Percent escapes in argument 1 */
4673 if (arg1n != (char *) NULL) {
4674 arg1=InterpretImageProperties(_image_info,_images,arg1n,_exception);
4675 if (arg1 == (char *) NULL) {
4676 CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
4677 arg1=arg1n; /* use the given argument as is */
4680 if (arg2n != (char *) NULL) {
4681 arg2=InterpretImageProperties(_image_info,_images,arg2n,_exception);
4682 if (arg2 == (char *) NULL) {
4683 CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
4684 arg2=arg2n; /* use the given argument as is */
4688 #undef _process_flags
4691 do { /* break to exit code */
4693 No-op options (ignore these)
4695 if (LocaleCompare("noop",option+1) == 0) /* zero argument */
4697 if (LocaleCompare("sans",option+1) == 0) /* one argument */
4699 if (LocaleCompare("sans0",option+1) == 0) /* zero argument */
4701 if (LocaleCompare("sans1",option+1) == 0) /* one argument */
4703 if (LocaleCompare("sans2",option+1) == 0) /* two arguments */
4708 if ( ( LocaleCompare("read",option+1) == 0 ) ||
4709 ( LocaleCompare("--",option) == 0 ) ) {
4710 /* Do Glob filename Expansion for 'arg1' then read all images.
4712 * Expansion handles '@', '~', '*', and '?' meta-characters while ignoring
4713 * (but attaching to the filenames in the generated argument list) any
4714 * [...] read modifiers that may be present.
4716 * For example: It will expand '*.gif[20x20]' into a list such as
4717 * 'abc.gif[20x20]', 'foobar.gif[20x20]', 'xyzzy.gif[20x20]'
4719 * NOTE: In IMv6 this was done globally across all images. This
4720 * meant you could include IM options in '@filename' lists, but you
4721 * could not include comments. Doing it only for image read makes
4722 * it far more secure.
4724 * Note: arguments do not have percent escapes expanded for security
4732 argv = (char **) &arg1;
4734 /* Expand 'glob' expressions in the given filename.
4735 Expansion handles any 'coder:' prefix, or read modifiers attached
4736 to the filename, including them in the resulting expanded list.
4738 if (ExpandFilenames(&argc,&argv) == MagickFalse)
4739 CLIWandExceptArgBreak(ResourceLimitError,"MemoryAllocationFailed",
4740 option,GetExceptionMessage(errno));
4742 /* loop over expanded filename list, and read then all in */
4743 for (i=0; i < (ssize_t) argc; i++) {
4746 if (_image_info->ping != MagickFalse)
4747 new_images=PingImages(_image_info,argv[i],_exception);
4749 new_images=ReadImages(_image_info,argv[i],_exception);
4750 AppendImageToList(&_images, new_images);
4751 argv[i]=DestroyString(argv[i]);
4753 argv=(char **) RelinquishMagickMemory(argv);
4758 Note: Writing a empty image list is valid in specific cases
4760 if (LocaleCompare("write",option+1) == 0) {
4761 /* Note: arguments do not have percent escapes expanded */
4763 key[MagickPathExtent];
4771 /* Need images, unless a "null:" output coder is used */
4772 if ( _images == (Image *) NULL ) {
4773 if ( LocaleCompare(arg1,"null:") == 0 )
4775 CLIWandExceptArgBreak(OptionError,"NoImagesForWrite",option,arg1);
4778 (void) FormatLocaleString(key,MagickPathExtent,"cache:%s",arg1);
4779 (void) DeleteImageRegistry(key);
4780 write_images=_images;
4782 write_images=CloneImageList(_images,_exception);
4783 write_info=CloneImageInfo(_image_info);
4784 (void) WriteImages(write_info,write_images,arg1,_exception);
4785 write_info=DestroyImageInfo(write_info);
4787 write_images=DestroyImageList(write_images);
4791 Parenthesis and Brace operations
4793 if (LocaleCompare("(",option) == 0) {
4794 /* stack 'push' images */
4802 node=cli_wand->image_list_stack;
4803 for ( ; node != (Stack *) NULL; node=node->next)
4805 if ( size >= MAX_STACK_DEPTH )
4806 CLIWandExceptionBreak(OptionError,"ParenthesisNestedTooDeeply",option);
4807 node=(Stack *) AcquireMagickMemory(sizeof(*node));
4808 if (node == (Stack *) NULL)
4809 CLIWandExceptionBreak(ResourceLimitFatalError,
4810 "MemoryAllocationFailed",option);
4811 node->data = (void *)cli_wand->wand.images;
4812 node->next = cli_wand->image_list_stack;
4813 cli_wand->image_list_stack = node;
4814 cli_wand->wand.images = NewImageList();
4816 /* handle respect-parenthesis */
4817 if (IsStringTrue(GetImageOption(cli_wand->wand.image_info,
4818 "respect-parenthesis")) != MagickFalse)
4819 option="{"; /* fall-thru so as to push image settings too */
4822 /* fall thru to operation */
4824 if (LocaleCompare("{",option) == 0) {
4825 /* stack 'push' of image_info settings */
4833 node=cli_wand->image_info_stack;
4834 for ( ; node != (Stack *) NULL; node=node->next)
4836 if ( size >= MAX_STACK_DEPTH )
4837 CLIWandExceptionBreak(OptionError,"CurlyBracesNestedTooDeeply",option);
4838 node=(Stack *) AcquireMagickMemory(sizeof(*node));
4839 if (node == (Stack *) NULL)
4840 CLIWandExceptionBreak(ResourceLimitFatalError,
4841 "MemoryAllocationFailed",option);
4843 node->data = (void *)cli_wand->wand.image_info;
4844 node->next = cli_wand->image_info_stack;
4846 cli_wand->image_info_stack = node;
4847 cli_wand->wand.image_info = CloneImageInfo(cli_wand->wand.image_info);
4848 if (cli_wand->wand.image_info == (ImageInfo *) NULL) {
4849 CLIWandException(ResourceLimitFatalError,"MemoryAllocationFailed",
4851 cli_wand->wand.image_info = (ImageInfo *)node->data;
4852 node = (Stack *)RelinquishMagickMemory(node);
4858 if (LocaleCompare(")",option) == 0) {
4859 /* pop images from stack */
4863 node = (Stack *)cli_wand->image_list_stack;
4864 if ( node == (Stack *) NULL)
4865 CLIWandExceptionBreak(OptionError,"UnbalancedParenthesis",option);
4866 cli_wand->image_list_stack = node->next;
4868 AppendImageToList((Image **)&node->data,cli_wand->wand.images);
4869 cli_wand->wand.images= (Image *)node->data;
4870 node = (Stack *)RelinquishMagickMemory(node);
4872 /* handle respect-parenthesis - of the previous 'pushed' settings */
4873 node = cli_wand->image_info_stack;
4874 if ( node != (Stack *) NULL)
4876 if (IsStringTrue(GetImageOption(
4877 cli_wand->wand.image_info,"respect-parenthesis")) != MagickFalse)
4878 option="}"; /* fall-thru so as to pop image settings too */
4884 /* fall thru to next if */
4886 if (LocaleCompare("}",option) == 0) {
4887 /* pop image_info settings from stack */
4891 node = (Stack *)cli_wand->image_info_stack;
4892 if ( node == (Stack *) NULL)
4893 CLIWandExceptionBreak(OptionError,"UnbalancedCurlyBraces",option);
4894 cli_wand->image_info_stack = node->next;
4896 (void) DestroyImageInfo(cli_wand->wand.image_info);
4897 cli_wand->wand.image_info = (ImageInfo *)node->data;
4898 node = (Stack *)RelinquishMagickMemory(node);
4900 GetDrawInfo(cli_wand->wand.image_info, cli_wand->draw_info);
4901 cli_wand->quantize_info=DestroyQuantizeInfo(cli_wand->quantize_info);
4902 cli_wand->quantize_info=AcquireQuantizeInfo(cli_wand->wand.image_info);
4906 if (LocaleCompare("print",option+1) == 0)
4908 (void) FormatLocaleFile(stdout,"%s",arg1);
4911 if (LocaleCompare("set",option+1) == 0)
4913 /* Settings are applied to each image in memory in turn (if any).
4914 While a option: only need to be applied once globally.
4916 NOTE: rguments have not been automatically percent expaneded
4919 /* escape the 'key' once only, using first image. */
4920 arg1=InterpretImageProperties(_image_info,_images,arg1n,_exception);
4921 if (arg1 == (char *) NULL)
4922 CLIWandExceptionBreak(OptionWarning,"InterpretPropertyFailure",
4925 if (LocaleNCompare(arg1,"registry:",9) == 0)
4929 (void) DeleteImageRegistry(arg1+9);
4930 arg1=DestroyString((char *)arg1);
4933 arg2=InterpretImageProperties(_image_info,_images,arg2n,_exception);
4934 if (arg2 == (char *) NULL) {
4935 arg1=DestroyString((char *)arg1);
4936 CLIWandExceptionBreak(OptionWarning,"InterpretPropertyFailure",
4939 (void) SetImageRegistry(StringRegistryType,arg1+9,arg2,_exception);
4940 arg1=DestroyString((char *)arg1);
4941 arg2=DestroyString((char *)arg2);
4944 if (LocaleNCompare(arg1,"option:",7) == 0)
4946 /* delete equivelent artifact from all images (if any) */
4947 if (_images != (Image *) NULL)
4949 MagickResetIterator(&cli_wand->wand);
4950 while (MagickNextImage(&cli_wand->wand) != MagickFalse)
4951 (void) DeleteImageArtifact(_images,arg1+7);
4952 MagickResetIterator(&cli_wand->wand);
4954 /* now set/delete the global option as needed */
4955 /* FUTURE: make escapes in a global 'option:' delayed */
4959 arg2=InterpretImageProperties(_image_info,_images,arg2n,_exception);
4960 if (arg2 == (char *) NULL)
4961 CLIWandExceptionBreak(OptionWarning,
4962 "InterpretPropertyFailure",option);
4964 (void) SetImageOption(_image_info,arg1+7,arg2);
4965 arg1=DestroyString((char *)arg1);
4966 arg2=DestroyString((char *)arg2);
4969 /* Set Artifacts/Properties/Attributes all images (required) */
4970 if ( _images == (Image *) NULL )
4971 CLIWandExceptArgBreak(OptionWarning,"NoImageForProperty",option,arg1);
4973 MagickResetIterator(&cli_wand->wand);
4974 while (MagickNextImage(&cli_wand->wand) != MagickFalse)
4979 arg2=InterpretImageProperties(_image_info,_images,arg2n,_exception);
4980 if (arg2 == (char *) NULL)
4981 CLIWandExceptionBreak(OptionWarning,
4982 "InterpretPropertyFailure",option);
4984 if (LocaleNCompare(arg1,"artifact:",9) == 0)
4985 (void) SetImageArtifact(_images,arg1+9,arg2);
4986 else if (LocaleNCompare(arg1,"property:",9) == 0)
4987 (void) SetImageProperty(_images,arg1+9,arg2,_exception);
4989 (void) SetImageProperty(_images,arg1,arg2,_exception);
4990 arg2=DestroyString((char *)arg2);
4992 MagickResetIterator(&cli_wand->wand);
4993 arg1=DestroyString((char *)arg1);
4996 if (LocaleCompare("clone",option+1) == 0) {
5001 arg1=AcquireString("-1");
5002 if (IsSceneGeometry(arg1,MagickFalse) == MagickFalse)
5003 CLIWandExceptionBreak(OptionError,"InvalidArgument",option);
5004 if ( cli_wand->image_list_stack == (Stack *) NULL)
5005 CLIWandExceptionBreak(OptionError,"UnableToCloneImage",option);
5006 new_images = (Image *)cli_wand->image_list_stack->data;
5007 if (new_images == (Image *) NULL)
5008 CLIWandExceptionBreak(OptionError,"UnableToCloneImage",option);
5009 new_images=CloneImages(new_images,arg1,_exception);
5010 if (new_images == (Image *) NULL)
5011 CLIWandExceptionBreak(OptionError,"NoSuchImage",option);
5012 AppendImageToList(&_images,new_images);
5016 Informational Operations.
5018 Note that these do not require either a cli-wand or images!
5019 Though currently a cli-wand much be provided regardless.
5021 if (LocaleCompare("version",option+1) == 0)
5023 ListMagickVersion(stdout);
5026 if (LocaleCompare("list",option+1) == 0) {
5028 FUTURE: This 'switch' should really be part of MagickCore
5033 list=ParseCommandOption(MagickListOptions,MagickFalse,arg1);
5035 CLIWandExceptionArg(OptionError,"UnrecognizedListType",option,arg1);
5040 case MagickCoderOptions:
5042 (void) ListCoderInfo((FILE *) NULL,_exception);
5045 case MagickColorOptions:
5047 (void) ListColorInfo((FILE *) NULL,_exception);
5050 case MagickConfigureOptions:
5052 (void) ListConfigureInfo((FILE *) NULL,_exception);
5055 case MagickDelegateOptions:
5057 (void) ListDelegateInfo((FILE *) NULL,_exception);
5060 case MagickFontOptions:
5062 (void) ListTypeInfo((FILE *) NULL,_exception);
5065 case MagickFormatOptions:
5066 (void) ListMagickInfo((FILE *) NULL,_exception);
5068 case MagickLocaleOptions:
5069 (void) ListLocaleInfo((FILE *) NULL,_exception);
5071 case MagickLogOptions:
5072 (void) ListLogInfo((FILE *) NULL,_exception);
5074 case MagickMagicOptions:
5075 (void) ListMagicInfo((FILE *) NULL,_exception);
5077 case MagickMimeOptions:
5078 (void) ListMimeInfo((FILE *) NULL,_exception);
5080 case MagickModuleOptions:
5081 (void) ListModuleInfo((FILE *) NULL,_exception);
5083 case MagickPolicyOptions:
5084 (void) ListPolicyInfo((FILE *) NULL,_exception);
5086 case MagickResourceOptions:
5087 (void) ListMagickResourceInfo((FILE *) NULL,_exception);
5089 case MagickThresholdOptions:
5090 (void) ListThresholdMaps((FILE *) NULL,_exception);
5093 (void) ListCommandOptions((FILE *) NULL,(CommandOption) list,
5100 CLIWandException(OptionError,"UnrecognizedOption",option);
5102 DisableMSCWarning(4127)
5103 } while (0); /* break to exit code. */
5106 /* clean up percent escape interpreted strings */
5108 arg1=DestroyString((char *)arg1);
5110 arg2=DestroyString((char *)arg2);
5120 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5124 + C L I O p t i o n %
5128 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5130 % CLIOption() Processes the given option using the given CLI Magick Wand.
5131 % The option arguments can be variable in number, though at this time no more
5132 % that two is actually used by any option (this may change). Excess options
5133 % are simply ignored.
5135 % If the cli_wand->command pointer is non-null, then it is assumed that the
5136 % option has already been search for up from the CommandOptions[] table in
5137 % "MagickCore/options.c" using GetCommandOptionInfo(). If not set this
5138 % routine will do the lookup instead. The pointer is reset afterward.
5140 % This action allows the caller to lookup and pre-handle any 'special'
5141 % options, (such as implicit reads) before calling this general option
5142 % handler to deal with 'standard' command line options.
5144 % The format of the CLIOption method is:
5146 % void CLIOption(MagickCLI *cli_wand,const char *option, ...)
5148 % A description of each parameter follows:
5150 % o cli_wand: the main CLI Wand to use.
5152 % o option: The special option (with any switch char) to process
5154 % o args: any required arguments for an option (variable number)
5158 % CLIoption(cli_wand,"-read","rose:");
5159 % CLIoption(cli_wand,"-virtual-pixel","transparent");
5160 % CLIoption(cli_wand,"-distort","SRT:","30");
5161 % CLIoption(cli_wand,"-write","rotated_rose.png");
5164 WandExport void CLIOption(MagickCLI *cli_wand,const char *option,...)
5166 const char /* extracted option args from args */
5173 assert(cli_wand != (MagickCLI *) NULL);
5174 assert(cli_wand->signature == MagickWandSignature);
5175 assert(cli_wand->wand.signature == MagickWandSignature);
5177 do { /* Break Code Block for error handling */
5179 /* get information about option */
5180 if ( cli_wand->command == (const OptionInfo *) NULL )
5181 cli_wand->command = GetCommandOptionInfo(option);
5183 (void) FormatLocaleFile(stderr, "CLIOption \"%s\" matched \"%s\"\n",
5184 option, cli_wand->command->mnemonic );
5186 option_type=(CommandOptionFlags) cli_wand->command->flags;
5188 if ( option_type == UndefinedOptionFlag )
5189 CLIWandExceptionReturn(OptionFatalError,"UnrecognizedOption",option);
5191 assert( LocaleCompare(cli_wand->command->mnemonic,option) == 0 );
5193 /* deprecated options */
5194 if ( (option_type & DeprecateOptionFlag) != 0 )
5195 CLIWandExceptionBreak(OptionError,"DeprecatedOptionNoCode",option);
5197 /* options that this module does not handle */
5198 if ((option_type & (SpecialOptionFlag|GenesisOptionFlag)) != 0 )
5199 CLIWandExceptionBreak(OptionFatalError,"InvalidUseOfOption",option);
5201 /* Get argument strings from VarArgs
5202 How can you determine if enough arguments was supplied?
5203 What happens if not enough arguments were supplied?
5206 count = (size_t) cli_wand->command->type;
5211 va_start(operands,option);
5215 arg1=(const char *) va_arg(operands, const char *);
5217 arg2=(const char *) va_arg(operands, const char *);
5221 (void) FormatLocaleFile(stderr,
5222 "CLIOption: \"%s\" Count: %ld Flags: %04x Args: \"%s\" \"%s\"\n",
5223 option,(long) count,option_type,arg1,arg2);
5228 Call the appropriate option handler
5231 /* FUTURE: this is temporary - get 'settings' to handle distribution of
5232 settings to images attributes,proprieties,artifacts */
5233 if ( cli_wand->wand.images != (Image *) NULL )
5234 (void) SyncImagesSettings(cli_wand->wand.image_info,cli_wand->wand.images,
5235 cli_wand->wand.exception);
5237 if ( (option_type & SettingOptionFlags) != 0 ) {
5238 CLISettingOptionInfo(cli_wand, option, arg1, arg2);
5240 FUTURE: Sync Specific Settings into Image Properities (not global)
5244 /* Operators that do not need images - read, write, stack, clone */
5245 if ((option_type & NoImageOperatorFlag) != 0)
5246 CLINoImageOperator(cli_wand, option, arg1, arg2);
5248 /* FUTURE: The not a setting part below is a temporary hack due to
5249 * some options being both a Setting and a Simple operator.
5250 * Specifically -monitor, -depth, and -colorspace */
5251 if ( cli_wand->wand.images == (Image *) NULL )
5252 if ( ((option_type & (SimpleOperatorFlag|ListOperatorFlag)) != 0 ) &&
5253 ((option_type & SettingOptionFlags) == 0 )) /* temp hack */
5254 CLIWandExceptionBreak(OptionError,"NoImagesFound",option);
5256 /* Operators which loop of individual images, simply */
5257 if ( (option_type & SimpleOperatorFlag) != 0 &&
5258 cli_wand->wand.images != (Image *) NULL) /* temp hack */
5260 ExceptionInfo *exception=AcquireExceptionInfo();
5261 (void) CLISimpleOperatorImages(cli_wand, option, arg1, arg2,exception);
5262 exception=DestroyExceptionInfo(exception);
5265 /* Operators that work on the image list as a whole */
5266 if ( (option_type & ListOperatorFlag) != 0 )
5267 (void) CLIListOperatorImages(cli_wand, option, arg1, arg2);
5269 DisableMSCWarning(4127)
5270 } while (0); /* end Break code block */
5273 cli_wand->command = (const OptionInfo *) NULL; /* prevent re-use later */