% September 2011 %
% %
% %
-% Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization %
+% Copyright 1999-2014 ImageMagick Studio LLC, a non-profit organization %
% dedicated to making software imaging solutions freely available. %
% %
% You may not use this file except in compliance with the License. You may %
#include "MagickWand/studio.h"
#include "MagickWand/MagickWand.h"
#include "MagickWand/magick-wand-private.h"
+#include "MagickWand/mogrify.h"
#include "MagickWand/wand.h"
#include "MagickWand/wandcli.h"
#include "MagickWand/wandcli-private.h"
-#include "MagickWand/operation.h"
+#include "MagickCore/image-private.h"
#include "MagickCore/monitor-private.h"
+#include "MagickWand/operation.h"
#include "MagickCore/thread-private.h"
#include "MagickCore/string-private.h"
+#include "MagickCore/pixel-private.h"
+\f
+/*
+ Constant declaration.
+*/
+static const char
+ MogrifyBackgroundColor[] = "#fff", /* white */
+ MogrifyBorderColor[] = "#dfdfdf", /* sRGB gray */
+ MogrifyMatteColor[] = "#bdbdbd"; /* slightly darker gray */
\f
/*
Define declarations.
*/
-#define USE_WAND_METHODS 0
+#define USE_WAND_METHODS 1
#define MAX_STACK_DEPTH 32
#define UNDEFINED_COMPRESSION_QUALITY 0UL
/* FUTURE: why is this default so specific? */
#define DEFAULT_DISSIMILARITY_THRESHOLD "0.31830988618379067154"
-/*
- Constant declaration. (temporary exports)
-*/
-static const char
- BackgroundColor[] = "#fff", /* white */
- BorderColor[] = "#dfdfdf", /* sRGB gray */
- MatteColor[] = "#bdbdbd"; /* slightly darker gray */
-
/* For Debugging Geometry Input */
#define ReportGeometry(flags,info) \
(void) FormatLocaleFile(stderr, "Geometry = 0x%04X : %lg x %lg %+lg %+lg\n", \
if (image != (Image *) NULL)
return(image);
read_info=CloneImageInfo(image_info);
- (void) CopyMagickString(read_info->filename,path,MaxTextExtent);
+ if (path != (const char *) NULL)
+ (void) CopyMagickString(read_info->filename,path,MaxTextExtent);
image=ReadImage(read_info,exception);
read_info=DestroyImageInfo(read_info);
if (image != (Image *) NULL)
an array of floating point values than call SparseColorImage().
Argument is a complex mix of floating-point pixel coodinates, and color
specifications (or direct floating point numbers). The number of floats
- needed to represent a color varies depending on teh current channel
+ needed to represent a color varies depending on the current channel
setting.
This really should be in MagickCore, so that other API's can make use of it.
*/
static Image *SparseColorOption(const Image *image,
- const SparseColorMethod method,const char *arguments,
- ExceptionInfo *exception)
+ const SparseColorMethod method,const char *arguments,ExceptionInfo *exception)
{
char
token[MaxTextExtent];
(image->colorspace == CMYKColorspace))
number_colors++;
if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
- IfMagickTrue(image->matte))
+ image->alpha_trait == BlendPixelTrait)
number_colors++;
/*
(image->colorspace == CMYKColorspace))
sparse_arguments[x++] = QuantumScale*color.black;
if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
- IfMagickTrue(image->matte))
+ image->alpha_trait == BlendPixelTrait)
sparse_arguments[x++] = QuantumScale*color.alpha;
}
else {
token[0] = ','; /* used this token - get another */
}
if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
- IfMagickTrue(image->matte))
+ image->alpha_trait == BlendPixelTrait)
{
while ( token[0] == ',' ) GetMagickToken(p,&p,token);
if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
% arg2 is currently only used by "-limit"
%
*/
-WandExport void CLISettingOptionInfo(MagickCLI *cli_wand,
- const char *option,const char *arg1, const char *arg2)
+WandPrivate void CLISettingOptionInfo(MagickCLI *cli_wand,
+ const char *option,const char *arg1n, const char *arg2n)
{
ssize_t
parse; /* option argument parsing (string to value table lookup) */
- assert(cli_wand != (MagickCLI *) NULL);
- assert(cli_wand->signature == WandSignature);
- assert(cli_wand->wand.signature == WandSignature);
- if (IfMagickTrue(cli_wand->wand.debug))
- (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
+ const char /* percent escaped versions of the args */
+ *arg1,
+ *arg2;
#define _image_info (cli_wand->wand.image_info)
+#define _image (cli_wand->wand.images)
#define _exception (cli_wand->wand.exception)
#define _draw_info (cli_wand->draw_info)
#define _quantize_info (cli_wand->quantize_info)
#define ArgBooleanString (IfSetOption?"true":"false")
#define ArgOption(def) (IfSetOption?arg1:(const char *)(def))
+ assert(cli_wand != (MagickCLI *) NULL);
+ assert(cli_wand->signature == WandSignature);
+ assert(cli_wand->wand.signature == WandSignature);
+
+ if (IfMagickTrue(cli_wand->wand.debug))
+ (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(),
+ "- Setting Option: %s \"%s\" \"%s\"", option,arg1n,arg2n);
+
+ arg1 = arg1n,
+ arg2 = arg2n;
+
+#if 1
+#define _process_flags (cli_wand->process_flags)
+#define _option_type ((CommandOptionFlags) cli_wand->command->flags)
+ /* Interpret Percent Escapes in Arguments - using first image */
+ if ( (((_process_flags & ProcessInterpretProperities) != 0 )
+ || ((_option_type & AlwaysInterpretArgsFlag) != 0)
+ ) && ((_option_type & NeverInterpretArgsFlag) == 0) ) {
+ /* Interpret Percent escapes in argument 1 */
+ if (arg1n != (char *) NULL) {
+ arg1=InterpretImageProperties(_image_info,_image,arg1n,_exception);
+ if (arg1 == (char *) NULL) {
+ CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
+ arg1=arg1n; /* use the given argument as is */
+ }
+ }
+ if (arg2n != (char *) NULL) {
+ arg2=InterpretImageProperties(_image_info,_image,arg2n,_exception);
+ if (arg2 == (char *) NULL) {
+ CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
+ arg2=arg2n; /* use the given argument as is */
+ }
+ }
+ }
+#undef _process_flags
+#undef _option_type
+#endif
+
switch (*(option+1))
{
case 'a':
Better error handling of QueryColorCompliance() needed.
*/
(void) SetImageOption(_image_info,option+1,ArgOption(NULL));
- (void) QueryColorCompliance(ArgOption(BackgroundColor),AllCompliance,
+ (void) QueryColorCompliance(ArgOption(MogrifyBackgroundColor),AllCompliance,
&_image_info->background_color,_exception);
break;
}
break;
}
(void) DeleteImageOption(_image_info,option+1);
- (void) QueryColorCompliance(BorderColor,AllCompliance,
+ (void) QueryColorCompliance(MogrifyBorderColor,AllCompliance,
&_image_info->border_color,_exception);
- (void) QueryColorCompliance(BorderColor,AllCompliance,
+ (void) QueryColorCompliance(MogrifyBorderColor,AllCompliance,
&_draw_info->border_color,_exception);
break;
}
}
if (LocaleCompare("channel",option+1) == 0)
{
- arg1=ArgOption("default");
- parse=ParseChannelOption(arg1);
+ parse=ParseChannelOption(ArgOption("Default"));
if (parse < 0)
CLIWandExceptArgBreak(OptionError,"UnrecognizedChannelType",
option,arg1);
but also ImageInfo and _quantize_info method!
FUTURE: merge the duality of the dithering options
*/
- _image_info->dither = _quantize_info->dither = ArgBoolean;
+ _image_info->dither = ArgBoolean;
(void) SetImageOption(_image_info,option+1,ArgOption("none"));
_quantize_info->dither_method=(DitherMethod) ParseCommandOption(
- MagickDitherOptions,MagickFalse,ArgOption("none"));
+ MagickDitherOptions,MagickFalse,ArgOption("none"));
if (_quantize_info->dither_method == NoDitherMethod)
- _image_info->dither = _quantize_info->dither = MagickFalse;
+ _image_info->dither = MagickFalse;
break;
}
CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
(void) CloneString(&_draw_info->family,ArgOption(NULL));
break;
}
+ if (LocaleCompare("features",option+1) == 0)
+ {
+ (void) SetImageOption(_image_info,"identify:features",
+ ArgBooleanString);
+ if (IfSetOption)
+ (void) SetImageArtifact(_image,"verbose","true");
+ break;
+ }
if (LocaleCompare("fill",option+1) == 0)
{
/* Set "fill" OR "fill-pattern" in _draw_info
SyncImageSettings() used to set per-image attribute.
FUTURE: Can't find anything else using _image_info->fuzz directly!
- remove direct sttribute from image_info
+ convert structure attribute to 'option' string
*/
arg1=ArgOption("0");
if (IfMagickFalse(IsGeometry(arg1)))
}
case 'i':
{
+ if (LocaleCompare("intensity",option+1) == 0)
+ {
+ arg1 = ArgOption("undefined");
+ parse = ParseCommandOption(MagickPixelIntensityOptions,MagickFalse,
+ arg1);
+ if (parse < 0)
+ CLIWandExceptArgBreak(OptionError,"UnrecognizedIntensityType",
+ option,arg1);
+ (void) SetImageOption(_image_info,option+1,arg1);
+ break;
+ }
if (LocaleCompare("intent",option+1) == 0)
{
/* Only used by coders: MIFF, MPC, BMP, PNG
and for image profile call to AcquireTransformThreadSet()
SyncImageSettings() used to set per-image attribute.
*/
- arg1 = ArgOption("indefined");
+ arg1 = ArgOption("undefined");
parse = ParseCommandOption(MagickIntentOptions,MagickFalse,arg1);
if (parse < 0)
CLIWandExceptArgBreak(OptionError,"UnrecognizedIntentType",
{
/* SyncImageSettings() used to set per-image attribute. */
(void) SetImageOption(_image_info,option+1,ArgOption(NULL));
- (void) QueryColorCompliance(ArgOption(MatteColor),AllCompliance,
+ (void) QueryColorCompliance(ArgOption(MogrifyMatteColor),AllCompliance,
&_image_info->matte_color,_exception);
break;
}
(void) SetImageOption(_image_info,option+1,ArgOption(NULL));
break;
}
+ if (LocaleCompare("moments",option+1) == 0)
+ {
+ (void) SetImageOption(_image_info,"identify:moments",
+ ArgBooleanString);
+ if (IfSetOption)
+ (void) SetImageArtifact(_image,"verbose","true");
+ break;
+ }
if (LocaleCompare("monitor",option+1) == 0)
{
(void) SetImageInfoProgressMonitor(_image_info, IfSetOption?
if (IfMagickFalse(IsGeometry(arg1)))
CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
SetRandomSecretKey(
- IfSetOption ? (size_t) StringToUnsignedLong(arg1)
- : (size_t) time((time_t *) NULL) );
+ IfSetOption ? (unsigned long) StringToUnsignedLong(arg1)
+ : (unsigned long) time((time_t *) NULL) );
break;
}
if (LocaleCompare("size",option+1) == 0)
}
if (LocaleCompare("texture",option+1) == 0)
{
+ /* Note: arguments do not have percent escapes expanded */
/* FUTURE: move _image_info string to option splay-tree
Other than "montage" what uses "texture" ????
*/
}
if (LocaleCompare("tile",option+1) == 0)
{
+ /* Note: arguments do not have percent escapes expanded */
_draw_info->fill_pattern=IfSetOption
?GetImageCache(_image_info,arg1,_exception)
:DestroyImage(_draw_info->fill_pattern);
CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
}
+ /* clean up percent escape interpreted strings */
+ if (arg1 != arg1n )
+ arg1=DestroyString((char *)arg1);
+ if (arg2 != arg2n )
+ arg2=DestroyString((char *)arg2);
+
#undef _image_info
#undef _exception
#undef _draw_info
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
-% WandSimpleOperatorImages() applys one simple image operation given to all
-% the images in the CLI wand, with the settings that was previously saved in
-% the CLI wand.
+% CLISimpleOperatorImages() applys one simple image operation given to all
+% the images in the CLI wand, using any per-image or global settings that was
+% previously saved in the CLI wand.
%
-% It is assumed that any per-image settings are up-to-date with respect to
-% extra settings that were already saved in the wand.
+% It is assumed that any such settings are up-to-date.
%
-% The format of the WandSimpleOperatorImage method is:
+% The format of the WandSimpleOperatorImages method is:
%
% void CLISimpleOperatorImages(MagickCLI *cli_wand,
% const char *option, const char *arg1, const char *arg2)
*/
/*
- Internal subrountine to apply one simple image operation to the current
- image pointed to by the CLI wand.
+ CLISimpleOperatorImage() is an Internal subrountine to apply one simple
+ image operation to the current image pointed to by the CLI wand.
The image in the list may be modified in three different ways...
* directly modified (EG: -negate, -gamma, -level, -annotate, -draw),
also change. GetFirstImageInList() should be used by caller if they wish
return the Image pointer to the first image in list.
*/
-static void CLISimpleOperatorImage(MagickCLI *cli_wand,
- const char *option, const char *arg1, const char *arg2)
+static MagickBooleanType CLISimpleOperatorImage(MagickCLI *cli_wand,
+ const char *option, const char *arg1n, const char *arg2n)
{
Image *
new_image;
ssize_t
parse;
-#define _image_info (cli_wand->wand.image_info)
-#define _image (cli_wand->wand.images)
-#define _exception (cli_wand->wand.exception)
-#define _draw_info (cli_wand->draw_info)
-#define _quantize_info (cli_wand->quantize_info)
-#define IfNormalOp (*option=='-')
-#define IfPlusOp (*option!='-')
-#define normal_op IsMagickTrue(IfNormalOp)
-#define plus_alt_op IsMagickFalse(IfNormalOp)
+ const char /* percent escaped versions of the args */
+ *arg1,
+ *arg2;
+
+#define _image_info (cli_wand->wand.image_info)
+#define _image (cli_wand->wand.images)
+#define _exception (cli_wand->wand.exception)
+#define _draw_info (cli_wand->draw_info)
+#define _quantize_info (cli_wand->quantize_info)
+#define _process_flags (cli_wand->process_flags)
+#define _option_type ((CommandOptionFlags) cli_wand->command->flags)
+#define IfNormalOp (*option=='-')
+#define IfPlusOp (*option!='-')
+#define IsNormalOp IsMagickTrue(IfNormalOp)
+#define IsPlusOp IsMagickFalse(IfNormalOp)
assert(cli_wand != (MagickCLI *) NULL);
assert(cli_wand->signature == WandSignature);
if (IfMagickTrue(cli_wand->wand.debug))
(void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
- SetGeometryInfo(&geometry_info);
+ arg1 = arg1n,
+ arg2 = arg2n;
+
+ /* Interpret Percent Escapes in Arguments - using first image */
+ if ( (((_process_flags & ProcessInterpretProperities) != 0 )
+ || ((_option_type & AlwaysInterpretArgsFlag) != 0)
+ ) && ((_option_type & NeverInterpretArgsFlag) == 0) ) {
+ /* Interpret Percent escapes in argument 1 */
+ if (arg1n != (char *) NULL) {
+ arg1=InterpretImageProperties(_image_info,_image,arg1n,_exception);
+ if (arg1 == (char *) NULL) {
+ CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
+ arg1=arg1n; /* use the given argument as is */
+ }
+ }
+ if (arg2n != (char *) NULL) {
+ arg2=InterpretImageProperties(_image_info,_image,arg2n,_exception);
+ if (arg2 == (char *) NULL) {
+ CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
+ arg2=arg2n; /* use the given argument as is */
+ }
+ }
+ }
+#undef _process_flags
+#undef _option_type
+
+#if 0
+ (void) FormatLocaleFile(stderr,
+ "CLISimpleOperatorImage: \"%s\" \"%s\" \"%s\"\n",option,arg1,arg2);
+#endif
new_image = (Image *)NULL; /* the replacement image, if not null at end */
+ SetGeometryInfo(&geometry_info);
- /* FUTURE: We may need somthing a little more optimized than this!
- Perhaps, do the 'sync' if 'settings tainted' before next operator.
- */
switch (*(option+1))
{
case 'a':
}
if (LocaleCompare("alpha",option+1) == 0)
{
- parse=ParseCommandOption(MagickAlphaOptions,MagickFalse,arg1);
+ parse=ParseCommandOption(MagickAlphaChannelOptions,MagickFalse,arg1);
if (parse < 0)
- CLIWandExceptArgBreak(OptionError,"UnrecognizedAlphaChannelType",
+ CLIWandExceptArgBreak(OptionError,"UnrecognizedAlphaChannelOption",
option,arg1);
- (void) SetImageAlphaChannel(_image,(AlphaChannelType)parse,
+ (void) SetImageAlphaChannel(_image,(AlphaChannelOption)parse,
_exception);
break;
}
if (LocaleCompare("annotate",option+1) == 0)
{
char
- *text,
geometry[MaxTextExtent];
SetGeometryInfo(&geometry_info);
flags=ParseGeometry(arg1,&geometry_info);
- if ((flags & RhoValue) == 0)
+ if (flags == 0)
CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
if ((flags & SigmaValue) == 0)
geometry_info.sigma=geometry_info.rho;
- text=InterpretImageProperties(_image_info,_image,arg2,
- _exception);
- if (text == (char *) NULL)
- break;
- (void) CloneString(&_draw_info->text,text);
- text=DestroyString(text);
+ (void) CloneString(&_draw_info->text,arg2);
(void) FormatLocaleString(geometry,MaxTextExtent,"%+f%+f",
geometry_info.xi,geometry_info.psi);
(void) CloneString(&_draw_info->geometry,geometry);
}
if (LocaleCompare("auto-orient",option+1) == 0)
{
- /* This should probably be a MagickCore function */
- switch (_image->orientation)
- {
- case TopRightOrientation:
- {
- new_image=FlopImage(_image,_exception);
- break;
- }
- case BottomRightOrientation:
- {
- new_image=RotateImage(_image,180.0,_exception);
- break;
- }
- case BottomLeftOrientation:
- {
- new_image=FlipImage(_image,_exception);
- break;
- }
- case LeftTopOrientation:
- {
- new_image=TransposeImage(_image,_exception);
- break;
- }
- case RightTopOrientation:
- {
- new_image=RotateImage(_image,90.0,_exception);
- break;
- }
- case RightBottomOrientation:
- {
- new_image=TransverseImage(_image,_exception);
- break;
- }
- case LeftBottomOrientation:
- {
- new_image=RotateImage(_image,270.0,_exception);
- break;
- }
- default:
- break;
- }
- if (new_image != (Image *) NULL)
- new_image->orientation=TopLeftOrientation;
+ new_image=AutoOrientImage(_image,_image->orientation,_exception);
break;
}
CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
value;
flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
- if ((flags & RhoValue) == 0)
+ if ((flags & (WidthValue | HeightValue)) == 0)
CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
- if ((flags & SigmaValue) == 0)
- geometry.height=geometry.width;
-
+ compose=OverCompositeOp;
value=GetImageOption(_image_info,"compose");
if (value != (const char *) NULL)
- compose=(CompositeOperator) ParseCommandOption(
- MagickComposeOptions,MagickFalse,value);
- else
- compose=OverCompositeOp; /* use Over not _image->compose */
-
+ compose=(CompositeOperator) ParseCommandOption(MagickComposeOptions,
+ MagickFalse,value);
new_image=BorderImage(_image,&geometry,compose,_exception);
break;
}
}
case 'c':
{
+ if (LocaleCompare("canny",option+1) == 0)
+ {
+ flags=ParseGeometry(arg1,&geometry_info);
+ if ((flags & (RhoValue|SigmaValue)) == 0)
+ CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+ if ((flags & SigmaValue) == 0)
+ geometry_info.sigma=1.0;
+ if ((flags & XiValue) == 0)
+ geometry_info.xi=10;
+ if ((flags & PsiValue) == 0)
+ geometry_info.psi=30;
+ if ((flags & PercentValue) != 0)
+ {
+ geometry_info.xi/=100.0;
+ geometry_info.psi/=100.0;
+ }
+ new_image=CannyEdgeImage(_image,geometry_info.rho,geometry_info.sigma,
+ geometry_info.xi,geometry_info.psi,_exception);
+ break;
+ }
if (LocaleCompare("cdl",option+1) == 0)
{
+ /* Note: arguments do not have percent escapes expanded */
char
*color_correction_collection;
/*
Color correct with a color decision list.
*/
- color_correction_collection=FileToString(arg1,~0,_exception);
+ color_correction_collection=FileToString(arg1,~0UL,_exception);
if (color_correction_collection == (char *) NULL)
break;
(void) ColorDecisionListImage(_image,color_correction_collection,
geometry_info.sigma=1.0;
if ((flags & XiValue) == 0)
geometry_info.xi=1.0;
- new_image=CharcoalImage(_image,geometry_info.rho,
- geometry_info.sigma,_exception);
+ new_image=CharcoalImage(_image,geometry_info.rho,geometry_info.sigma,
+ _exception);
break;
}
if (LocaleCompare("chop",option+1) == 0)
}
if (LocaleCompare("clip-mask",option+1) == 0)
{
+ /* Note: arguments do not have percent escapes expanded */
CacheView
*mask_view;
y;
if (IfPlusOp) {
- /* "+clip-mask" Remove the write mask */
+ /* use "+clip-mask" Remove the write mask for -clip-path */
(void) SetImageMask(_image,(Image *) NULL,_exception);
break;
}
break;
for (x=0; x < (ssize_t) mask_image->columns; x++)
{
- if (IfMagickFalse(mask_image->matte))
+ if (mask_image->alpha_trait != BlendPixelTrait)
SetPixelAlpha(mask_image,GetPixelIntensity(mask_image,q),q);
- SetPixelRed(mask_image,GetPixelAlpha(mask_image,q),q);
- SetPixelGreen(mask_image,GetPixelAlpha(mask_image,q),q);
- SetPixelBlue(mask_image,GetPixelAlpha(mask_image,q),q);
+ SetPixelGray(mask_image,GetPixelAlpha(mask_image,q),q);
q+=GetPixelChannels(mask_image);
}
if (IfMagickFalse(SyncCacheViewAuthenticPixels(mask_view,_exception)))
}
/* clean up and set the write mask */
mask_view=DestroyCacheView(mask_view);
- mask_image->matte=MagickTrue;
+ mask_image->alpha_trait=BlendPixelTrait;
+ (void) SetImageColorspace(_image,GRAYColorspace,_exception);
(void) SetImageMask(_image,mask_image,_exception);
mask_image=DestroyImage(mask_image);
break;
}
if (LocaleCompare("clip-path",option+1) == 0)
{
- (void) ClipImagePath(_image,arg1,normal_op,_exception);
+ (void) ClipImagePath(_image,arg1,IsNormalOp,_exception);
+ /* Note: Use "+clip-mask" remove the write mask added */
break;
}
if (LocaleCompare("colorize",option+1) == 0)
That seems to be a little strange!
*/
(void) TransformImageColorspace(_image,
- IfNormalOp ? _image_info->colorspace : RGBColorspace,
+ IfNormalOp ? _image_info->colorspace : sRGBColorspace,
_exception);
break;
}
if (LocaleCompare("contrast",option+1) == 0)
{
- CLIWandWarnReplaced(normal_op?"-level":"+level");
- (void) ContrastImage(_image,normal_op,_exception);
+ CLIWandWarnReplaced(IfNormalOp?"-level":"+level");
+ (void) ContrastImage(_image,IsNormalOp,_exception);
break;
}
if (LocaleCompare("contrast-stretch",option+1) == 0)
black_point*=(double) _image->columns*_image->rows/100.0;
white_point*=(double) _image->columns*_image->rows/100.0;
}
- white_point=(MagickRealType) _image->columns*_image->rows-
+ white_point=(double) _image->columns*_image->rows-
white_point;
(void) ContrastStretchImage(_image,black_point,white_point,
_exception);
{
if (LocaleCompare("decipher",option+1) == 0)
{
+ /* Note: arguments do not have percent escapes expanded */
StringInfo
*passkey;
- passkey=FileToStringInfo(arg1,~0,_exception);
+ passkey=FileToStringInfo(arg1,~0UL,_exception);
if (passkey == (StringInfo *) NULL)
CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
}
if (LocaleCompare("distort",option+1) == 0)
{
- char
- *arg;
-
double
*args;
(size_t)2,resize_args,MagickTrue,_exception);
break;
}
- /* allow percent escapes in argument string */
- arg=InterpretImageProperties(_image_info,_image,arg2,_exception);
- if (arg == (char *) NULL)
- break;
/* convert argument string into an array of doubles */
- args = StringToArrayOfDoubles(arg,&count,_exception);
- arg=DestroyString(arg);
+ args = StringToArrayOfDoubles(arg2,&count,_exception);
if (args == (double *)NULL )
CLIWandExceptArgBreak(OptionError,"InvalidNumberList",option,arg2);
new_image=DistortImage(_image,(DistortImageMethod) parse,count,args,
- plus_alt_op,_exception);
+ IsPlusOp,_exception);
args=(double *) RelinquishMagickMemory(args);
break;
}
flags=ParseGeometry(arg1,&geometry_info);
if ((flags & (RhoValue|SigmaValue)) == 0)
CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
- if ((flags & SigmaValue) == 0)
- geometry_info.sigma=1.0;
- new_image=EdgeImage(_image,geometry_info.rho,geometry_info.sigma,
- _exception);
+ new_image=EdgeImage(_image,geometry_info.rho,_exception);
break;
}
if (LocaleCompare("emboss",option+1) == 0)
}
if (LocaleCompare("encipher",option+1) == 0)
{
+ /* Note: arguments do not have percent escapes expanded */
StringInfo
*passkey;
- passkey=FileToStringInfo(arg1,~0,_exception);
+ passkey=FileToStringInfo(arg1,~0UL,_exception);
if (passkey != (StringInfo *) NULL)
{
(void) PasskeyEncipherImage(_image,passkey,_exception);
}
case 'f':
{
- if (LocaleCompare("features",option+1) == 0)
- {
- /* FUTURE: move to SyncImageSettings() and AcqireImage()??? */
- if (IfPlusOp) {
- (void) DeleteImageArtifact(_image,"identify:features");
- break;
- }
- (void) SetImageArtifact(_image,"identify:features","true");
- (void) SetImageArtifact(_image,"verbose","true");
- break;
- }
if (LocaleCompare("flip",option+1) == 0)
{
new_image=FlipImage(_image,_exception);
(void) ParsePageGeometry(_image,arg1,&geometry,_exception);
(void) QueryColorCompliance(arg2,AllCompliance,&target,_exception);
(void) FloodfillPaintImage(_image,_draw_info,&target,geometry.x,
- geometry.y,plus_alt_op,_exception);
+ geometry.y,IsPlusOp,_exception);
break;
}
if (LocaleCompare("frame",option+1) == 0)
value;
value=GetImageOption(_image_info,"compose");
- if (value != (const char *) NULL)
- compose=(CompositeOperator) ParseCommandOption(
- MagickComposeOptions,MagickFalse,value);
- else
compose=OverCompositeOp; /* use Over not _image->compose */
-
+ if (value != (const char *) NULL)
+ compose=(CompositeOperator) ParseCommandOption(MagickComposeOptions,
+ MagickFalse,value);
if (IfMagickFalse(IsGeometry(arg1)))
CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
frame_info.width=geometry.width;
frame_info.height=geometry.height;
- if ((flags & HeightValue) == 0)
- frame_info.height=geometry.width;
frame_info.outer_bevel=geometry.x;
frame_info.inner_bevel=geometry.y;
frame_info.x=(ssize_t) frame_info.width;
}
if (LocaleCompare("function",option+1) == 0)
{
- char
- *arg;
-
double
*args;
if ( parse < 0 )
CLIWandExceptArgBreak(OptionError,"UnrecognizedFunction",
option,arg1);
- /* allow percent escapes in argument string */
- arg=InterpretImageProperties(_image_info,_image,arg2,_exception);
- if (arg == (char *) NULL)
- break;
/* convert argument string into an array of doubles */
- args = StringToArrayOfDoubles(arg,&count,_exception);
- arg=DestroyString(arg);
+ args = StringToArrayOfDoubles(arg2,&count,_exception);
if (args == (double *)NULL )
CLIWandExceptArgBreak(OptionError,"InvalidNumberList",option,arg2);
{
if (LocaleCompare("gamma",option+1) == 0)
{
+ double
+ constant;
+
if (IfMagickFalse(IsGeometry(arg1)))
CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+ constant=StringToDouble(arg1,(char **) NULL);
+#if 0
+ /* Using Gamma, via a cache */
+ if (IfPlusOp)
+ constant=PerceptibleReciprocal(constant);
+ (void) GammaImage(_image,constant,_exception);
+#else
+ /* Using Evaluate POW, direct update of values - more accurite */
if (IfNormalOp)
- (void) GammaImage(_image,StringToDouble(arg1,(char **) NULL),
- _exception);
- else
- _image->gamma=StringToDouble(arg1,(char **) NULL);
+ constant=PerceptibleReciprocal(constant);
+ (void) EvaluateImage(_image,PowEvaluateOperator,constant,_exception);
+#endif
+ /* Set gamma setting -- Old meaning of "+gamma"
+ * _image->gamma=StringToDouble(arg1,(char **) NULL);
+ */
break;
}
if (LocaleCompare("gaussian-blur",option+1) == 0)
_image->filter,_exception);
break;
}
+ if (LocaleCompare("grayscale",option+1) == 0)
+ {
+ parse=ParseCommandOption(MagickPixelIntensityOptions,
+ MagickFalse,arg1);
+ if (parse < 0)
+ CLIWandExceptArgBreak(OptionError,"UnrecognizedIntensityMethod",
+ option,arg1);
+ (void) GrayscaleImage(_image,(PixelIntensityMethod) parse,_exception);
+ break;
+ }
+ CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
+ }
+ case 'h':
+ {
+ if (LocaleCompare("hough-lines",option+1) == 0)
+ {
+ flags=ParseGeometry(arg1,&geometry_info);
+ if ((flags & (RhoValue|SigmaValue)) == 0)
+ CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+ if ((flags & SigmaValue) == 0)
+ geometry_info.sigma=geometry_info.rho;
+ if ((flags & XiValue) == 0)
+ geometry_info.xi=40;
+ new_image=HoughLineImage(_image,(size_t) geometry_info.rho,
+ (size_t) geometry_info.sigma,(size_t) geometry_info.xi,_exception);
+ break;
+ }
CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
}
case 'i':
}
text=InterpretImageProperties(_image_info,_image,format,_exception);
if (text == (char *) NULL)
- break;
+ CLIWandExceptionBreak(OptionWarning,"InterpretPropertyFailure",
+ option);
(void) fputs(text,stdout);
- (void) fputc('\n',stdout);
text=DestroyString((char *)text);
break;
}
flags=ParseGeometry(arg1,&geometry_info);
if ((flags & (RhoValue|SigmaValue)) == 0)
CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+ if ((flags & SigmaValue) == 0)
+ geometry_info.sigma=1.0;
if ((flags & PercentValue) != 0)
geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
new_image=AdaptiveThresholdImage(_image,(size_t) geometry_info.rho,
}
if (LocaleCompare("level",option+1) == 0)
{
- MagickRealType
+ double
black_point,
gamma,
white_point;
if ((flags & RhoValue) == 0)
CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
black_point=geometry_info.rho;
- white_point=(MagickRealType) QuantumRange;
+ white_point=(double) QuantumRange;
if ((flags & SigmaValue) != 0)
white_point=geometry_info.sigma;
gamma=1.0;
gamma=geometry_info.xi;
if ((flags & PercentValue) != 0)
{
- black_point*=(MagickRealType) (QuantumRange/100.0);
- white_point*=(MagickRealType) (QuantumRange/100.0);
+ black_point*=(double) (QuantumRange/100.0);
+ white_point*=(double) (QuantumRange/100.0);
}
if ((flags & SigmaValue) == 0)
- white_point=(MagickRealType) QuantumRange-black_point;
+ white_point=(double) QuantumRange-black_point;
if (IfPlusOp || ((flags & AspectValue) != 0))
(void) LevelizeImage(_image,black_point,white_point,gamma,_exception);
else
&white_point,_exception);
}
(void) LevelImageColors(_image,&black_point,&white_point,
- plus_alt_op,_exception);
+ IsPlusOp,_exception);
break;
}
if (LocaleCompare("linear-stretch",option+1) == 0)
if ((flags & RhoValue) == 0)
CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
black_point=geometry_info.rho;
- white_point=(MagickRealType) _image->columns*_image->rows;
+ white_point=(double) _image->columns*_image->rows;
if ((flags & SigmaValue) != 0)
white_point=geometry_info.sigma;
if ((flags & PercentValue) != 0)
white_point*=(double) _image->columns*_image->rows/100.0;
}
if ((flags & SigmaValue) == 0)
- white_point=(MagickRealType) _image->columns*_image->rows-
+ white_point=(double) _image->columns*_image->rows-
black_point;
(void) LinearStretchImage(_image,black_point,white_point,_exception);
break;
}
case 'm':
{
+ if (LocaleCompare("magnify",option+1) == 0)
+ {
+ new_image=MagnifyImage(_image,_exception);
+ break;
+ }
if (LocaleCompare("map",option+1) == 0)
{
CLIWandWarnReplaced("-remap");
}
if (LocaleCompare("mask",option+1) == 0)
{
+ /* Note: arguments do not have percent escapes expanded */
Image
*mask;
{
CLIWandWarnReplaced(IfNormalOp?"-alpha Set":"-alpha Off");
(void) SetImageAlphaChannel(_image,IfNormalOp ? SetAlphaChannel :
- DeactivateAlphaChannel, _exception);
+ DeactivateAlphaChannel, _exception);
+ break;
+ }
+ if (LocaleCompare("mean-shift",option+1) == 0)
+ {
+ flags=ParseGeometry(arg1,&geometry_info);
+ if ((flags & (RhoValue|SigmaValue)) == 0)
+ CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
+ if ((flags & SigmaValue) == 0)
+ geometry_info.sigma=1.0;
+ if ((flags & XiValue) == 0)
+ geometry_info.xi=0.10*QuantumRange;
+ if ((flags & PercentValue) != 0)
+ geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
+ new_image=MeanShiftImage(_image,(size_t) geometry_info.rho,
+ (size_t) geometry_info.sigma,geometry_info.xi,_exception);
break;
}
if (LocaleCompare("median",option+1) == 0)
{
if (LocaleCompare("negate",option+1) == 0)
{
- (void) NegateImage(_image, plus_alt_op, _exception);
+ (void) NegateImage(_image, IsPlusOp, _exception);
break;
}
if (LocaleCompare("noise",option+1) == 0)
target;
(void) QueryColorCompliance(arg1,AllCompliance,&target,_exception);
- (void) OpaquePaintImage(_image,&target,&_draw_info->fill,plus_alt_op,
+ (void) OpaquePaintImage(_image,&target,&_draw_info->fill,IsPlusOp,
_exception);
break;
}
_exception);
break;
}
+ if (LocaleCompare("perceptible",option+1) == 0)
+ {
+ (void) PerceptibleImage(_image,StringToDouble(arg1,(char **) NULL),
+ _exception);
+ break;
+ }
if (LocaleCompare("polaroid",option+1) == 0)
{
const char
if ((flags & RhoValue) == 0)
CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
(void) PosterizeImage(_image,(size_t) geometry_info.rho,
- _quantize_info->dither,_exception);
+ _quantize_info->dither_method,_exception);
break;
}
if (LocaleCompare("preview",option+1) == 0)
}
if (LocaleCompare("profile",option+1) == 0)
{
+ /* Note: arguments do not have percent escapes expanded */
const char
*name;
}
case 'r':
{
- if (LocaleCompare("radial-blur",option+1) == 0)
+ if (LocaleCompare("rotational-blur",option+1) == 0)
{
flags=ParseGeometry(arg1,&geometry_info);
if ((flags & RhoValue) == 0)
CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
- new_image=RadialBlurImage(_image,geometry_info.rho,_exception);
+ new_image=RotationalBlurImage(_image,geometry_info.rho,_exception);
break;
}
if (LocaleCompare("raise",option+1) == 0)
if (IfMagickFalse(IsGeometry(arg1)))
CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
- if ((flags & SigmaValue) == 0)
- geometry.height=geometry.width;
- (void) RaiseImage(_image,&geometry,normal_op,_exception);
+ (void) RaiseImage(_image,&geometry,IsNormalOp,_exception);
break;
}
if (LocaleCompare("random-threshold",option+1) == 0)
}
if (LocaleCompare("remap",option+1) == 0)
{
+ /* Note: arguments do not have percent escapes expanded */
Image
*remap_image;
(double) QuantumRange+1.0),_exception);
break;
}
- if (LocaleCompare("set",option+1) == 0)
- {
- char
- *value;
-
- if (IfPlusOp) {
- if (LocaleNCompare(arg1,"registry:",9) == 0)
- (void) DeleteImageRegistry(arg1+9);
- else
- if (LocaleNCompare(arg1,"option:",7) == 0)
- {
- (void) DeleteImageOption(_image_info,arg1+7);
- (void) DeleteImageArtifact(_image,arg1+7);
- }
- else
- (void) DeleteImageProperty(_image,arg1);
- break;
- }
- value=InterpretImageProperties(_image_info,_image,arg2,_exception);
- if (value == (char *) NULL)
- break;
- if (LocaleNCompare(arg1,"registry:",9) == 0)
- (void) SetImageRegistry(StringRegistryType,arg1+9,value,_exception);
- else
- if (LocaleNCompare(arg1,"option:",7) == 0)
- {
- (void) SetImageOption(_image_info,arg1+7,value);
- (void) SetImageArtifact(_image,arg1+7,value);
- }
- else
- (void) SetImageProperty(_image,arg1,value,_exception);
- value=DestroyString(value);
- break;
- }
if (LocaleCompare("shade",option+1) == 0)
{
flags=ParseGeometry(arg1,&geometry_info);
if (((flags & RhoValue) == 0) || ((flags & SigmaValue) == 0))
CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
- new_image=ShadeImage(_image,normal_op,geometry_info.rho,
+ new_image=ShadeImage(_image,IsNormalOp,geometry_info.rho,
geometry_info.sigma,_exception);
break;
}
CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
if ((flags & SigmaValue) == 0)
geometry_info.sigma=geometry_info.rho;
- new_image=ShearImage(_image,geometry_info.rho,
- geometry_info.sigma,_exception);
+ new_image=ShearImage(_image,geometry_info.rho,geometry_info.sigma,
+ _exception);
break;
}
if (LocaleCompare("sigmoidal-contrast",option+1) == 0)
if ((flags & PercentValue) != 0)
geometry_info.sigma=(double) QuantumRange*geometry_info.sigma/
100.0;
- (void) SigmoidalContrastImage(_image,normal_op,geometry_info.rho,
+ (void) SigmoidalContrastImage(_image,IsNormalOp,geometry_info.rho,
geometry_info.sigma,_exception);
break;
}
}
if (LocaleCompare("sparse-color",option+1) == 0)
{
- char
- *arguments;
-
parse= ParseCommandOption(MagickSparseColorOptions,MagickFalse,arg1);
if ( parse < 0 )
CLIWandExceptArgBreak(OptionError,"UnrecognizedSparseColorMethod",
option,arg1);
- arguments=InterpretImageProperties(_image_info,_image,arg2,_exception);
- if (arguments == (char *) NULL)
- CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
- new_image=SparseColorOption(_image,(SparseColorMethod)parse,
- arguments,_exception);
- arguments=DestroyString(arguments);
+ new_image=SparseColorOption(_image,(SparseColorMethod)parse,arg2,
+ _exception);
break;
}
if (LocaleCompare("splice",option+1) == 0)
}
if (LocaleCompare("swirl",option+1) == 0)
{
- flags=ParseGeometry(arg2,&geometry_info);
+ flags=ParseGeometry(arg1,&geometry_info);
if ((flags & RhoValue) == 0)
- CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
+ CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
new_image=SwirlImage(_image,geometry_info.rho,
_image->interpolate,_exception);
break;
threshold;
threshold=(double) QuantumRange/2;
- if (normal_op) {
+ if (IfNormalOp) {
if (IfMagickFalse(IsGeometry(arg1)))
CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
threshold=StringToDoubleInterval(arg1,(double) QuantumRange+1.0);
(void) QueryColorCompliance(arg1,AllCompliance,&target,_exception);
(void) TransparentPaintImage(_image,&target,(Quantum)
- TransparentAlpha,plus_alt_op,_exception);
+ TransparentAlpha,IsPlusOp,_exception);
break;
}
if (LocaleCompare("transpose",option+1) == 0)
Option is not documented, bt appears to be for "identify".
We may need a identify specific verbose!
*/
- if (plus_alt_op) {
+ if (IsPlusOp) {
(void) DeleteImageArtifact(_image,"identify:unique-colors");
break;
}
geometry_info.xi=0.1*_image->columns;
if ((flags & PsiValue) == 0)
geometry_info.psi=0.1*_image->rows;
+ if ((flags & PercentValue) != 0)
+ {
+ geometry_info.xi*=(double) _image->columns/100.0;
+ geometry_info.psi*=(double) _image->rows/100.0;
+ }
new_image=VignetteImage(_image,geometry_info.rho,geometry_info.sigma,
(ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
ceil(geometry_info.psi-0.5),_exception);
default:
CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
}
- /*
- Replace current image with any image that was generated
- and set image point to last image (so image->next is correct)
- */
+ /* clean up percent escape interpreted strings */
+ if (arg1 != arg1n )
+ arg1=DestroyString((char *)arg1);
+ if (arg2 != arg2n )
+ arg2=DestroyString((char *)arg2);
+
+ /* Replace current image with any image that was generated
+ and set image point to last image (so image->next is correct) */
if (new_image != (Image *) NULL)
ReplaceImageInListReturnLast(&_image,new_image);
- return;
+ return(MagickTrue);
#undef _image_info
#undef _draw_info
#undef _quantize_info
#undef _exception
#undef IfNormalOp
#undef IfPlusOp
-#undef normal_op
-#undef plus_alt_op
+#undef IsNormalOp
+#undef IsPlusOp
}
-WandExport void CLISimpleOperatorImages(MagickCLI *cli_wand,
- const char *option, const char *arg1, const char *arg2)
+WandPrivate MagickBooleanType CLISimpleOperatorImages(MagickCLI *cli_wand,
+ const char *option,const char *arg1,const char *arg2)
{
+#if !USE_WAND_METHODS
size_t
n,
i;
+#endif
assert(cli_wand != (MagickCLI *) NULL);
assert(cli_wand->signature == WandSignature);
assert(cli_wand->wand.signature == WandSignature);
assert(cli_wand->wand.images != (Image *) NULL); /* images must be present */
+
if (IfMagickTrue(cli_wand->wand.debug))
- (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
+ (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(),
+ "- Simple Operator: %s \"%s\" \"%s\"", option,arg1,arg2);
#if !USE_WAND_METHODS
/* FUTURE add appropriate tracing */
CLISimpleOperatorImage(cli_wand, option, arg1, arg2);
MagickResetIterator(&cli_wand->wand);
#endif
- return;
+ return(MagickTrue);
}
\f
/*
%
% CLIListOperatorImages() applies a single operation that is apply to the
% entire image list as a whole. The result is often a complete replacment
-% of the image list with a completely new list, or just a single image.
+% of the image list with a completely new list, or with just a single image
+% result.
%
% The format of the MogrifyImage method is:
%
-% void CLIListOperatorImages(MagickCLI *cli_wand,
-% const char *option, const char *arg1, const char *arg2)
+% MagickBooleanType CLIListOperatorImages(MagickCLI *cli_wand,
+% const char *option,const char *arg1,const char *arg2)
%
% A description of each parameter follows:
%
% arg2 is currently not used
%
*/
-WandExport void CLIListOperatorImages(MagickCLI *cli_wand,
- const char *option,const char *arg1, const char *magick_unused(arg2))
+WandPrivate MagickBooleanType CLIListOperatorImages(MagickCLI *cli_wand,
+ const char *option,const char *arg1n,const char *arg2n)
{
- ssize_t
- parse;
+ const char /* percent escaped versions of the args */
+ *arg1,
+ *arg2;
Image
*new_images;
+ MagickStatusType
+ status;
+
+ ssize_t
+ parse;
+
#define _image_info (cli_wand->wand.image_info)
#define _images (cli_wand->wand.images)
#define _exception (cli_wand->wand.exception)
#define _draw_info (cli_wand->draw_info)
#define _quantize_info (cli_wand->quantize_info)
+#define _process_flags (cli_wand->process_flags)
+#define _option_type ((CommandOptionFlags) cli_wand->command->flags)
#define IfNormalOp (*option=='-')
#define IfPlusOp (*option!='-')
-#define normal_op IsMagickTrue(IfNormalOp)
+#define IsNormalOp IsMagickTrue(IfNormalOp)
assert(cli_wand != (MagickCLI *) NULL);
assert(cli_wand->signature == WandSignature);
assert(cli_wand->wand.signature == WandSignature);
assert(_images != (Image *) NULL); /* _images must be present */
+
if (IfMagickTrue(cli_wand->wand.debug))
- (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
+ (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(),
+ "- List Operator: %s \"%s\" \"%s\"", option,arg1n,arg2n);
+
+ arg1 = arg1n;
+ arg2 = arg2n;
+
+ /* Interpret Percent Escapes in Arguments - using first image */
+ if ( (((_process_flags & ProcessInterpretProperities) != 0 )
+ || ((_option_type & AlwaysInterpretArgsFlag) != 0)
+ ) && ((_option_type & NeverInterpretArgsFlag) == 0) ) {
+ /* Interpret Percent escapes in argument 1 */
+ if (arg1n != (char *) NULL) {
+ arg1=InterpretImageProperties(_image_info,_images,arg1n,_exception);
+ if (arg1 == (char *) NULL) {
+ CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
+ arg1=arg1n; /* use the given argument as is */
+ }
+ }
+ if (arg2n != (char *) NULL) {
+ arg2=InterpretImageProperties(_image_info,_images,arg2n,_exception);
+ if (arg2 == (char *) NULL) {
+ CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
+ arg2=arg2n; /* use the given argument as is */
+ }
+ }
+ }
+#undef _process_flags
+#undef _option_type
+ status=MagickTrue;
new_images=NewImageList();
switch (*(option+1))
{
if (LocaleCompare("append",option+1) == 0)
{
- new_images=AppendImages(_images,normal_op,_exception);
+ new_images=AppendImages(_images,IsNormalOp,_exception);
break;
}
if (LocaleCompare("average",option+1) == 0)
}
if (LocaleCompare("combine",option+1) == 0)
{
- /* FUTURE - this may be replaced by a 'channel' method */
- new_images=CombineImages(_images,_exception);
+ parse = (ssize_t) sRGBColorspace; /* default (backward compatible) */
+ if ( IfPlusOp )
+ parse = ParseCommandOption(MagickColorspaceOptions,MagickFalse,
+ arg1);
+ if (parse < 0)
+ CLIWandExceptArgBreak(OptionError,"UnrecognizedColorspace",option,
+ arg1);
+ new_images=CombineImages(_images,(ColorspaceType) parse,_exception);
+ break;
+ }
+ if (LocaleCompare("compare",option+1) == 0)
+ {
+ double
+ distortion;
+
+ Image
+ *image,
+ *reconstruct_image;
+
+ MetricType
+ metric;
+
+ /*
+ Mathematically and visually annotate the difference between an
+ image and its reconstruction.
+ */
+ image=RemoveFirstImageFromList(&_images);
+ reconstruct_image=RemoveFirstImageFromList(&_images);
+ /* FUTURE - produce Exception, rather than silent fail */
+ if (reconstruct_image == (Image *) NULL)
+ break;
+ metric=UndefinedErrorMetric;
+ option=GetImageOption(_image_info,"metric");
+ if (option != (const char *) NULL)
+ metric=(MetricType) ParseCommandOption(MagickMetricOptions,
+ MagickFalse,option);
+ new_images=CompareImages(image,reconstruct_image,metric,&distortion,
+ _exception);
+ (void) distortion;
+ reconstruct_image=DestroyImage(reconstruct_image);
+ image=DestroyImage(image);
+ break;
+ }
+ if (LocaleCompare("complex",option+1) == 0)
+ {
+ parse=ParseCommandOption(MagickComplexOptions,MagickFalse,arg1);
+ if (parse < 0)
+ CLIWandExceptArgBreak(OptionError,"UnrecognizedEvaluateOperator",
+ option,arg1);
+ new_images=ComplexImages(_images,(ComplexOperator) parse,_exception);
break;
}
if (LocaleCompare("composite",option+1) == 0)
/* FUTURE - this should not be here! - should be part of -geometry */
(void) TransformImage(&source_image,(char *) NULL,
source_image->geometry,_exception);
-
SetGeometry(source_image,&geometry);
(void) ParseAbsoluteGeometry(source_image->geometry,&geometry);
GravityAdjustGeometry(new_images->columns,new_images->rows,
- new_images->gravity, &geometry);
-
+ new_images->gravity, &geometry);
mask_image=RemoveFirstImageFromList(&_images);
if (mask_image != (Image *) NULL)
- { /* handle a third write mask image */
+ {
if ((compose == DisplaceCompositeOp) ||
- (compose == DistortCompositeOp)) {
- /* Merge Y displacement into X displace/distort map. */
- (void) CompositeImage(source_image,mask_image,
+ (compose == DistortCompositeOp))
+ status&=CompositeImage(source_image,mask_image,
CopyGreenCompositeOp,MagickTrue,0,0,_exception);
- mask_image=DestroyImage(mask_image);
- }
- else {
- /* Set a blending mask for the composition. */
- (void) NegateImage(mask_image,MagickFalse,_exception);
- (void) SetImageMask(new_images,mask_image,_exception);
- mask_image=DestroyImage(mask_image);
- }
+ else
+ {
+ Image
+ *image;
+
+ RectangleInfo
+ source_geometry;
+
+ source_geometry.width=mask_image->columns;
+ source_geometry.height=mask_image->rows;
+ source_geometry.x=(-geometry.x);
+ source_geometry.y=(-geometry.y);
+ geometry.x=0;
+ geometry.y=0;
+ image=ExtentImage(source_image,&source_geometry,_exception);
+ if (image != (Image *) NULL)
+ {
+ source_image=DestroyImage(source_image);
+ source_image=image;
+ }
+ status&=CompositeImage(source_image,mask_image,
+ IntensityCompositeOp,MagickTrue,0,0,_exception);
+ }
+ mask_image=DestroyImage(mask_image);
}
- (void) CompositeImage(new_images,source_image,compose,clip_to_self,
+ status&=CompositeImage(new_images,source_image,compose,clip_to_self,
geometry.x,geometry.y,_exception);
- (void) SetImageMask(new_images,(Image *) NULL,_exception);
source_image=DestroyImage(source_image);
break;
}
{
if (LocaleCompare("evaluate-sequence",option+1) == 0)
{
- parse = ParseCommandOption(MagickEvaluateOptions,MagickFalse,arg1);
- if ( parse < 0 )
+ parse=ParseCommandOption(MagickEvaluateOptions,MagickFalse,arg1);
+ if (parse < 0)
CLIWandExceptArgBreak(OptionError,"UnrecognizedEvaluateOperator",
- option,arg1);
+ option,arg1);
new_images=EvaluateImages(_images,(MagickEvaluateOperator)parse,
- _exception);
+ _exception);
break;
}
CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
{
if (LocaleCompare("fft",option+1) == 0)
{
- new_images=ForwardFourierTransformImage(_images,normal_op,_exception);
+ new_images=ForwardFourierTransformImage(_images,IsNormalOp,_exception);
break;
}
if (LocaleCompare("flatten",option+1) == 0)
if (phase_image == (Image *) NULL)
break;
new_images=InverseFourierTransformImage(magnitude_image,phase_image,
- normal_op,_exception);
+ IsNormalOp,_exception);
magnitude_image=DestroyImage(magnitude_image);
phase_image=DestroyImage(phase_image);
break;
if ( parse < 0 )
CLIWandExceptArgBreak(OptionError,"UnrecognizedLayerMethod",
option,arg1);
- switch ((ImageLayerMethod) parse)
+ switch ((LayerMethod) parse)
{
case CoalesceLayer:
{
case CompareOverlayLayer:
default:
{
- new_images=CompareImagesLayers(_images,(ImageLayerMethod) parse,
+ new_images=CompareImagesLayers(_images,(LayerMethod) parse,
_exception);
break;
}
case MosaicLayer:
case TrimBoundsLayer:
{
- new_images=MergeImageLayers(_images,(ImageLayerMethod) parse,
+ new_images=MergeImageLayers(_images,(LayerMethod) parse,
_exception);
break;
}
(void) RemapImages(_quantize_info,_images,(Image *) NULL,_exception);
break;
}
+ if (LocaleCompare("metric",option+1) == 0)
+ break;
if (LocaleCompare("morph",option+1) == 0)
{
Image
}
case 'p':
{
- if (LocaleCompare("print",option+1) == 0)
+ if (LocaleCompare("poly",option+1) == 0)
{
- char
- *string;
+ double
+ *args;
- string=InterpretImageProperties(_image_info,_images,arg1,_exception);
- if (string == (char *) NULL)
- break;
- (void) FormatLocaleFile(stdout,"%s",string);
- string=DestroyString(string);
+ ssize_t
+ count;
+
+ /* convert argument string into an array of doubles */
+ args = StringToArrayOfDoubles(arg2,&count,_exception);
+ if (args == (double *)NULL )
+ CLIWandExceptArgBreak(OptionError,"InvalidNumberList",option,arg2);
+ new_images=PolynomialImage(_images,count >> 1,args,_exception);
+ args=(double *) RelinquishMagickMemory(args);
break;
}
if (LocaleCompare("process",option+1) == 0)
/*
Support old style syntax, filter="-option arg1".
*/
+ assert(arg1 != (const char *) NULL);
length=strlen(arg1);
token=(char *) NULL;
if (~length >= (MaxTextExtent-1))
if (IfMagickFalse(IsGeometry(arg1)))
CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
offset=(ssize_t) StringToLong(arg1);
- new_images=SmushImages(_images,normal_op,offset,_exception);
+ new_images=SmushImages(_images,IsNormalOp,offset,_exception);
break;
}
if (LocaleCompare("subimage",option+1) == 0)
compare_image=GetImageFromList(_images,1);
/* Comparision Metric */
- metric=UndefinedMetric;
+ metric=UndefinedErrorMetric;
value=GetImageOption(_image_info,"metric");
if (value != (const char *) NULL)
metric=(MetricType) ParseCommandOption(MagickMetricOptions,
MagickFalse,value);
- new_images=SimilarityImage(base_image,compare_image,metric,
+ new_images=SimilarityImage(base_image,compare_image,metric,0.0,
&offset,&similarity,_exception);
if ( new_images != (Image *)NULL ) {
index,
swap_index;
- index=-1;
- swap_index=-2;
+ index=(-1);
+ swap_index=(-2);
if (IfNormalOp) {
GeometryInfo
geometry_info;
swap_index=(-1);
flags=ParseGeometry(arg1,&geometry_info);
- if ((flags & RhoValue) != 0)
+ if ((flags & RhoValue) == 0)
CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
index=(ssize_t) geometry_info.rho;
if ((flags & SigmaValue) != 0)
default:
CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
}
- if (new_images == (Image *) NULL)
- return;
- if (_images != (Image *) NULL)
- _images=DestroyImageList(_images);
+ /* clean up percent escape interpreted strings */
+ if (arg1 != arg1n )
+ arg1=DestroyString((char *)arg1);
+ if (arg2 != arg2n )
+ arg2=DestroyString((char *)arg2);
+
+ /* if new image list generated, replace existing image list */
+ if (new_images == (Image *) NULL)
+ return(status == 0 ? MagickFalse : MagickTrue);
+ _images=DestroyImageList(_images);
_images=GetFirstImageInList(new_images);
- return;
+ return(status == 0 ? MagickFalse : MagickTrue);
#undef _image_info
#undef _images
#undef _quantize_info
#undef IfNormalOp
#undef IfPlusOp
-#undef normal_op
+#undef IsNormalOp
}
\f
/*
% %
% %
% %
-+ C L I S p e c i a l O p e r a t i o n s %
++ C L I N o I m a g e O p e r a t i o n s %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% CLINoImageOperator() Applies operations that may not actually need images
-% in an image list wen it is applied.
+% in an image list.
%
-% The classic operators of this type is -read, which actually creates images
-% even when no images are present. Or image stack operators, which can be
-% applied to empty image lists.
+% The classic operators of this type is "-read", which actually creates
+% images even when no images are present. Or image stack operators, which
+% can be applied (push or pop) to an empty image list.
%
-% Note: unlike other Operators, these may involve other special 'option'
-% character prefixes, other than simply '-' or '+'.
+% Note that these operators may involve other special 'option' prefix
+% characters other than '-' or '+', namely parenthesis and braces.
%
% The format of the CLINoImageOption method is:
%
%
% A description of each parameter follows:
%
-% o cli_wand: the main CLI Wand to use.
+% o cli_wand: the main CLI Wand to use. (sometimes not required)
%
% o option: The special option (with any switch char) to process
%
% Currently arg2 is not used.
%
*/
-WandExport void CLINoImageOperator(MagickCLI *cli_wand,
- const char *option, const char *arg1, const char *magick_unused(arg2))
+WandPrivate void CLINoImageOperator(MagickCLI *cli_wand,
+ const char *option,const char *arg1n,const char *arg2n)
{
+ const char /* percent escaped versions of the args */
+ *arg1,
+ *arg2;
+
#define _image_info (cli_wand->wand.image_info)
#define _images (cli_wand->wand.images)
#define _exception (cli_wand->wand.exception)
+#define _process_flags (cli_wand->process_flags)
+#define _option_type ((CommandOptionFlags) cli_wand->command->flags)
#define IfNormalOp (*option=='-')
#define IfPlusOp (*option!='-')
assert(cli_wand != (MagickCLI *) NULL);
assert(cli_wand->signature == WandSignature);
assert(cli_wand->wand.signature == WandSignature);
+
if (IfMagickTrue(cli_wand->wand.debug))
- (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
+ (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(),
+ "- NoImage Operator: %s \"%s\" \"%s\"", option,arg1n,arg2n);
+
+ arg1 = arg1n;
+ arg2 = arg2n;
+
+ /* Interpret Percent Escapes in Arguments - using first image */
+ if ( (((_process_flags & ProcessInterpretProperities) != 0 )
+ || ((_option_type & AlwaysInterpretArgsFlag) != 0)
+ ) && ((_option_type & NeverInterpretArgsFlag) == 0) ) {
+ /* Interpret Percent escapes in argument 1 */
+ if (arg1n != (char *) NULL) {
+ arg1=InterpretImageProperties(_image_info,_images,arg1n,_exception);
+ if (arg1 == (char *) NULL) {
+ CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
+ arg1=arg1n; /* use the given argument as is */
+ }
+ }
+ if (arg2n != (char *) NULL) {
+ arg2=InterpretImageProperties(_image_info,_images,arg2n,_exception);
+ if (arg2 == (char *) NULL) {
+ CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
+ arg2=arg2n; /* use the given argument as is */
+ }
+ }
+ }
+#undef _process_flags
+#undef _option_type
- /*
- No-op options (ignore these)
- */
- if (LocaleCompare("noop",option+1) == 0) /* no argument */
- return;
- if (LocaleCompare("sans",option+1) == 0) /* one argument */
- return;
- if (LocaleCompare("sans0",option+1) == 0) /* no argument */
- return;
- if (LocaleCompare("sans2",option+1) == 0) /* two arguments */
- return;
- /*
- Image Reading
- */
- if ( ( LocaleCompare("read",option+1) == 0 ) ||
- ( LocaleCompare("--",option) == 0 ) ) {
-#if 0
- /* Directly read 'arg1' without filename expansion handling (see below).
- This does NOT turn off the 'coder:' prefix, or '[...]' read modifiers.
+ do { /* break to exit code */
+ /*
+ No-op options (ignore these)
*/
-# if !USE_WAND_METHODS
- Image *new_images;
+ if (LocaleCompare("noop",option+1) == 0) /* zero argument */
+ break;
+ if (LocaleCompare("sans",option+1) == 0) /* one argument */
+ break;
+ if (LocaleCompare("sans0",option+1) == 0) /* zero argument */
+ break;
+ if (LocaleCompare("sans1",option+1) == 0) /* one argument */
+ break;
+ if (LocaleCompare("sans2",option+1) == 0) /* two arguments */
+ break;
+ /*
+ Image Reading
+ */
+ if ( ( LocaleCompare("read",option+1) == 0 ) ||
+ ( LocaleCompare("--",option) == 0 ) ) {
+ /* Do Glob filename Expansion for 'arg1' then read all images.
+ *
+ * Expansion handles '@', '~', '*', and '?' meta-characters while ignoring
+ * (but attaching to the filenames in the generated argument list) any
+ * [...] read modifiers that may be present.
+ *
+ * For example: It will expand '*.gif[20x20]' into a list such as
+ * 'abc.gif[20x20]', 'foobar.gif[20x20]', 'xyzzy.gif[20x20]'
+ *
+ * NOTE: In IMv6 this was done globally across all images. This
+ * meant you could include IM options in '@filename' lists, but you
+ * could not include comments. Doing it only for image read makes
+ * it far more secure.
+ *
+ * Note: arguments do not have percent escapes expanded for security
+ * reasons.
+ */
+ int argc;
+ char **argv;
+ ssize_t i;
- if (IfMagickTrue(_image_info->ping))
- new_images=PingImages(_image_info,arg1,_exception);
- else
- new_images=ReadImages(_image_info,arg1,_exception);
- AppendImageToList(&_images, new_images);
-# else
- /* read images using MagickWand method - no ping */
- /* This is not working! - it locks up in a CPU loop! */
- MagickSetLastIterator(&cli_wand->wand);
- MagickReadImage(&cli_wand->wand,arg1);
- MagickSetFirstIterator(&cli_wand->wand);
-# endif
-#else
- /* Do Filename Expansion for 'arg1' then read all images.
- *
- * Expansion handles '@', '~', '*', and '?' meta-characters while ignoring
- * (but attaching to generated argument list) any [...] read modifiers
- * that may be present.
- *
- * For example: correctly expand '*.gif[20x20]' into a list such as
- * 'abc.gif[20x20', 'foobar.gif[20x20]', 'xyzzy.gif[20x20]'
- *
- * NOTE: In IMv6 this was done globally across all images. This
- * meant you could include IM options in '@filename' lists, but you
- * could not include comments. Doing it only for image read makes
- * it far more secure.
- */
- int argc;
- char **argv;
- ssize_t i;
-
- argc = 1;
- argv = (char **) &arg1;
-
- if (IfMagickFalse(ExpandFilenames(&argc,&argv)))
- CLIWandExceptArgReturn(ResourceLimitError,"MemoryAllocationFailed",
- option,GetExceptionMessage(errno));
-
- /* loop over expanded filename list, and read then all in */
- for (i=0; i<argc; i++) {
- Image *
- new_images;
-#if 0
-fprintf(stderr, "DEBUG: Reading image: \"%s\"\n", argv[i]);
-#endif
- if (IfMagickTrue(_image_info->ping))
- new_images=PingImages(_image_info,argv[i],_exception);
- else
- new_images=ReadImages(_image_info,argv[i],_exception);
- AppendImageToList(&_images, new_images);
+ argc = 1;
+ argv = (char **) &arg1;
+
+ /* Expand 'glob' expressions in the given filename.
+ Expansion handles any 'coder:' prefix, or read modifiers attached
+ to the filename, including them in the resulting expanded list.
+ */
+ if (IfMagickFalse( ExpandFilenames(&argc,&argv) ))
+ CLIWandExceptArgBreak(ResourceLimitError,"MemoryAllocationFailed",
+ option,GetExceptionMessage(errno));
+
+ /* loop over expanded filename list, and read then all in */
+ for (i=0; i<argc; i++) {
+ Image *
+ new_images;
+ if (IfMagickTrue(_image_info->ping))
+ new_images=PingImages(_image_info,argv[i],_exception);
+ else
+ new_images=ReadImages(_image_info,argv[i],_exception);
+ AppendImageToList(&_images, new_images);
+ }
+ argv=DestroyStringList(argv); /* Destroy the Expanded Filename list */
+ break;
}
- /* FUTURE: how do I free the expanded filename array memory ??? */
- //argv=DestroyStringList(argv); /* Is this correct? */
-#endif
- return;
- }
- /*
- Image Writing
- Note: Writing a empty image list is valid in specific cases
- */
- if (LocaleCompare("write",option+1) == 0) {
- char
- key[MaxTextExtent];
+ /*
+ Image Writing
+ Note: Writing a empty image list is valid in specific cases
+ */
+ if (LocaleCompare("write",option+1) == 0) {
+ /* Note: arguments do not have percent escapes expanded */
+ char
+ key[MaxTextExtent];
- Image
- *write_images;
+ Image
+ *write_images;
- ImageInfo
- *write_info;
+ ImageInfo
+ *write_info;
- /* Need images, unless a "null:" output coder is used */
- if ( cli_wand->wand.images == (Image *) NULL ) {
- if ( LocaleCompare(arg1,"null:") == 0 )
- return;
- CLIWandExceptArgReturn(OptionError,"NoImagesForWrite",option,arg1);
+ /* Need images, unless a "null:" output coder is used */
+ if ( _images == (Image *) NULL ) {
+ if ( LocaleCompare(arg1,"null:") == 0 )
+ break;
+ CLIWandExceptArgBreak(OptionError,"NoImagesForWrite",option,arg1);
+ }
+
+ (void) FormatLocaleString(key,MaxTextExtent,"cache:%s",arg1);
+ (void) DeleteImageRegistry(key);
+ write_images=_images;
+ if (IfPlusOp)
+ write_images=CloneImageList(_images,_exception);
+ write_info=CloneImageInfo(_image_info);
+ (void) WriteImages(write_info,write_images,arg1,_exception);
+ write_info=DestroyImageInfo(write_info);
+ if (IfPlusOp)
+ write_images=DestroyImageList(write_images);
+ break;
}
+ /*
+ Parenthesis and Brace operations
+ */
+ if (LocaleCompare("(",option) == 0) {
+ /* stack 'push' images */
+ Stack
+ *node;
+
+ size_t
+ size;
+
+ size=0;
+ node=cli_wand->image_list_stack;
+ for ( ; node != (Stack *)NULL; node=node->next)
+ size++;
+ if ( size >= MAX_STACK_DEPTH )
+ CLIWandExceptionBreak(OptionError,"ParenthesisNestedTooDeeply",option);
+ node=(Stack *) AcquireMagickMemory(sizeof(*node));
+ if (node == (Stack *) NULL)
+ CLIWandExceptionBreak(ResourceLimitFatalError,
+ "MemoryAllocationFailed",option);
+ node->data = (void *)cli_wand->wand.images;
+ node->next = cli_wand->image_list_stack;
+ cli_wand->image_list_stack = node;
+ cli_wand->wand.images = NewImageList();
+
+ /* handle respect-parenthesis */
+ if (IfMagickTrue(IsStringTrue(GetImageOption(cli_wand->wand.image_info,
+ "respect-parenthesis"))))
+ option="{"; /* fall-thru so as to push image settings too */
+ else
+ break;
+ /* fall thru to operation */
+ }
+ if (LocaleCompare("{",option) == 0) {
+ /* stack 'push' of image_info settings */
+ Stack
+ *node;
+
+ size_t
+ size;
+
+ size=0;
+ node=cli_wand->image_info_stack;
+ for ( ; node != (Stack *)NULL; node=node->next)
+ size++;
+ if ( size >= MAX_STACK_DEPTH )
+ CLIWandExceptionBreak(OptionError,"CurlyBracesNestedTooDeeply",option);
+ node=(Stack *) AcquireMagickMemory(sizeof(*node));
+ if (node == (Stack *) NULL)
+ CLIWandExceptionBreak(ResourceLimitFatalError,
+ "MemoryAllocationFailed",option);
+
+ node->data = (void *)cli_wand->wand.image_info;
+ node->next = cli_wand->image_info_stack;
+
+ cli_wand->image_info_stack = node;
+ cli_wand->wand.image_info = CloneImageInfo(cli_wand->wand.image_info);
+ if (cli_wand->wand.image_info == (ImageInfo *)NULL) {
+ CLIWandException(ResourceLimitFatalError,"MemoryAllocationFailed",
+ option);
+ cli_wand->wand.image_info = (ImageInfo *)node->data;
+ node = (Stack *)RelinquishMagickMemory(node);
+ break;
+ }
- (void) FormatLocaleString(key,MaxTextExtent,"cache:%s",arg1);
- (void) DeleteImageRegistry(key);
- write_images=_images;
- if (IfPlusOp)
- write_images=CloneImageList(_images,_exception);
- write_info=CloneImageInfo(_image_info);
- (void) WriteImages(write_info,write_images,arg1,_exception);
- write_info=DestroyImageInfo(write_info);
- if (IfPlusOp)
- write_images=DestroyImageList(write_images);
- return;
- }
- /*
- Parenthesis and Brace operations
- */
- if (LocaleCompare("(",option) == 0) {
- /* stack 'push' images */
- Stack
- *node;
-
- size_t
- size;
-
- size=0;
- node=cli_wand->image_list_stack;
- for ( ; node != (Stack *)NULL; node=node->next)
- size++;
- if ( size >= MAX_STACK_DEPTH )
- CLIWandExceptionReturn(OptionError,"ParenthesisNestedTooDeeply",option);
- node=(Stack *) AcquireMagickMemory(sizeof(*node));
- if (node == (Stack *) NULL)
- CLIWandExceptionReturn(ResourceLimitFatalError,
- "MemoryAllocationFailed",option);
- node->data = (void *)cli_wand->wand.images;
- cli_wand->wand.images = NewImageList();
- node->next = cli_wand->image_list_stack;
- cli_wand->image_list_stack = node;
-
- /* handle respect-parenthesis */
- if (IfMagickTrue(IsStringTrue(GetImageOption(cli_wand->wand.image_info,
- "respect-parenthesis"))))
- option="{"; /* fall-thru so as to push image settings too */
- else
- return;
- }
- if (LocaleCompare("{",option) == 0) {
- /* stack 'push' of image_info settings */
- Stack
- *node;
-
- size_t
- size;
-
- size=0;
- node=cli_wand->image_info_stack;
- for ( ; node != (Stack *)NULL; node=node->next)
- size++;
- if ( size >= MAX_STACK_DEPTH )
- CLIWandExceptionReturn(OptionError,"CurlyBracesNestedTooDeeply",option);
- node=(Stack *) AcquireMagickMemory(sizeof(*node));
- if (node == (Stack *) NULL)
- CLIWandExceptionReturn(ResourceLimitFatalError,
- "MemoryAllocationFailed",option);
-
- node->data = (void *)cli_wand->wand.image_info;
- cli_wand->wand.image_info = CloneImageInfo(cli_wand->wand.image_info);
- if (cli_wand->wand.image_info == (ImageInfo *)NULL) {
- CLIWandException(ResourceLimitFatalError,"MemoryAllocationFailed",
- option);
- cli_wand->wand.image_info = (ImageInfo *)node->data;
+ break;
+ }
+ if (LocaleCompare(")",option) == 0) {
+ /* pop images from stack */
+ Stack
+ *node;
+
+ node = (Stack *)cli_wand->image_list_stack;
+ if ( node == (Stack *)NULL)
+ CLIWandExceptionBreak(OptionError,"UnbalancedParenthesis",option);
+ cli_wand->image_list_stack = node->next;
+
+ AppendImageToList((Image **)&node->data,cli_wand->wand.images);
+ cli_wand->wand.images= (Image *)node->data;
node = (Stack *)RelinquishMagickMemory(node);
- return;
+
+ /* handle respect-parenthesis - of the previous 'pushed' settings */
+ node = cli_wand->image_info_stack;
+ if ( node != (Stack *)NULL)
+ {
+ if (IfMagickTrue(IsStringTrue(GetImageOption(
+ cli_wand->wand.image_info,"respect-parenthesis"))))
+ option="}"; /* fall-thru so as to pop image settings too */
+ else
+ break;
+ }
+ else
+ break;
+ /* fall thru to next if */
}
+ if (LocaleCompare("}",option) == 0) {
+ /* pop image_info settings from stack */
+ Stack
+ *node;
- node->next = cli_wand->image_info_stack;
- cli_wand->image_info_stack = node;
+ node = (Stack *)cli_wand->image_info_stack;
+ if ( node == (Stack *)NULL)
+ CLIWandExceptionBreak(OptionError,"UnbalancedCurlyBraces",option);
+ cli_wand->image_info_stack = node->next;
- return;
- }
- if (LocaleCompare(")",option) == 0) {
- /* pop images from stack */
- Stack
- *node;
-
- node = (Stack *)cli_wand->image_list_stack;
- if ( node == (Stack *)NULL)
- CLIWandExceptionReturn(OptionError,"UnbalancedParenthesis",option);
- cli_wand->image_list_stack = node->next;
-
- AppendImageToList((Image **)&node->data,cli_wand->wand.images);
- cli_wand->wand.images= (Image *)node->data;
- node = (Stack *)RelinquishMagickMemory(node);
-
- /* handle respect-parenthesis - of the previous 'pushed' settings */
- node = cli_wand->image_info_stack;
- if ( node != (Stack *)NULL)
+ (void) DestroyImageInfo(cli_wand->wand.image_info);
+ cli_wand->wand.image_info = (ImageInfo *)node->data;
+ node = (Stack *)RelinquishMagickMemory(node);
+
+ GetDrawInfo(cli_wand->wand.image_info, cli_wand->draw_info);
+ cli_wand->quantize_info=DestroyQuantizeInfo(cli_wand->quantize_info);
+ cli_wand->quantize_info=AcquireQuantizeInfo(cli_wand->wand.image_info);
+
+ break;
+ }
+ if (LocaleCompare("print",option+1) == 0)
+ {
+ (void) FormatLocaleFile(stdout,"%s",arg1);
+ break;
+ }
+ if (LocaleCompare("set",option+1) == 0)
{
- if (IfMagickTrue(IsStringTrue(GetImageOption(
- cli_wand->wand.image_info,"respect-parenthesis"))))
- option="}"; /* fall-thru so as to pop image settings too */
- else
- return;
- }
- else
- return;
- }
- if (LocaleCompare("}",option) == 0) {
- /* pop image_info settings from stack */
- Stack
- *node;
+ /* Settings are applied to each image in memory in turn (if any).
+ While a option: only need to be applied once globally.
- node = (Stack *)cli_wand->image_info_stack;
- if ( node == (Stack *)NULL)
- CLIWandExceptionReturn(OptionError,"UnbalancedCurlyBraces",option);
- cli_wand->image_info_stack = node->next;
+ NOTE: rguments have not been automatically percent expaneded
+ */
- (void) DestroyImageInfo(cli_wand->wand.image_info);
- cli_wand->wand.image_info = (ImageInfo *)node->data;
- node = (Stack *)RelinquishMagickMemory(node);
+ /* escape the 'key' once only, using first image. */
+ arg1=InterpretImageProperties(_image_info,_images,arg1n,_exception);
+ if (arg1 == (char *) NULL)
+ CLIWandExceptionBreak(OptionWarning,"InterpretPropertyFailure",
+ option);
- GetDrawInfo(cli_wand->wand.image_info, cli_wand->draw_info);
- cli_wand->quantize_info=DestroyQuantizeInfo(cli_wand->quantize_info);
- cli_wand->quantize_info=AcquireQuantizeInfo(cli_wand->wand.image_info);
+ if (LocaleNCompare(arg1,"registry:",9) == 0)
+ {
+ if (IfPlusOp)
+ {
+ (void) DeleteImageRegistry(arg1+9);
+ arg1=DestroyString((char *)arg1);
+ break;
+ }
+ arg2=InterpretImageProperties(_image_info,_images,arg2n,_exception);
+ if (arg2 == (char *) NULL) {
+ arg1=DestroyString((char *)arg1);
+ CLIWandExceptionBreak(OptionWarning,"InterpretPropertyFailure",
+ option);
+ }
+ (void) SetImageRegistry(StringRegistryType,arg1+9,arg2,_exception);
+ arg1=DestroyString((char *)arg1);
+ arg2=DestroyString((char *)arg2);
+ break;
+ }
+ if (LocaleNCompare(arg1,"option:",7) == 0)
+ {
+ /* delete equivelent artifact from all images (if any) */
+ if (_images != (Image *)NULL)
+ {
+ MagickResetIterator(&cli_wand->wand);
+ while ( IfMagickTrue(MagickNextImage(&cli_wand->wand)) )
+ (void) DeleteImageArtifact(_images,arg1+7);
+ MagickResetIterator(&cli_wand->wand);
+ }
+ /* now set/delete the global option as needed */
+ /* FUTURE: make escapes in a global 'option:' delayed */
+ arg2=(char *)NULL;
+ if (IfNormalOp)
+ {
+ arg2=InterpretImageProperties(_image_info,_images,arg2n,_exception);
+ if (arg2 == (char *) NULL)
+ CLIWandExceptionBreak(OptionWarning,
+ "InterpretPropertyFailure",option);
+ }
+ (void) SetImageOption(_image_info,arg1+7,arg2);
+ arg1=DestroyString((char *)arg1);
+ arg2=DestroyString((char *)arg2);
+ break;
+ }
+ /* Set Artifacts/Properties/Attributes all images (required) */
+ if ( _images == (Image *) NULL )
+ CLIWandExceptArgBreak(OptionWarning,"NoImageForProperty",option,arg1);
- return;
- }
- if (LocaleCompare("clone",option+1) == 0) {
- Image
- *new_images;
-
- if (*option == '+')
- arg1="-1";
- if (IfMagickFalse(IsSceneGeometry(arg1,MagickFalse)))
- CLIWandExceptionReturn(OptionError,"InvalidArgument",option);
- if ( cli_wand->image_list_stack == (Stack *)NULL)
- CLIWandExceptionReturn(OptionError,"UnableToCloneImage",option);
- new_images = (Image *)cli_wand->image_list_stack->data;
- if (new_images == (Image *) NULL)
- CLIWandExceptionReturn(OptionError,"UnableToCloneImage",option);
- new_images=CloneImages(new_images,arg1,_exception);
- if (new_images == (Image *) NULL)
- CLIWandExceptionReturn(OptionError,"NoSuchImage",option);
- AppendImageToList(&_images,new_images);
- return;
- }
- /*
- Informational Operations
- */
- if (LocaleCompare("version",option+1) == 0) {
- (void) FormatLocaleFile(stdout,"Version: %s\n",
- GetMagickVersion((size_t *) NULL));
- (void) FormatLocaleFile(stdout,"Copyright: %s\n",
- GetMagickCopyright());
- (void) FormatLocaleFile(stdout,"Features: %s\n\n",
- GetMagickFeatures());
- return;
- }
- if (LocaleCompare("list",option+1) == 0) {
- /* FUTURE: This should really be built into the MagickCore
- It does not actually require a cli-wand or and images!
- */
- ssize_t
- list;
-
- list=ParseCommandOption(MagickListOptions,MagickFalse,arg1);
- if ( list < 0 ) {
- CLIWandExceptionArg(OptionError,"UnrecognizedListType",option,arg1);
- return;
- }
- switch (list)
- {
- case MagickCoderOptions:
- {
- (void) ListCoderInfo((FILE *) NULL,_exception);
+ MagickResetIterator(&cli_wand->wand);
+ while ( IfMagickTrue(MagickNextImage(&cli_wand->wand)) )
+ {
+ arg2=(char *)NULL;
+ if (IfNormalOp)
+ {
+ arg2=InterpretImageProperties(_image_info,_images,arg2n,_exception);
+ if (arg2 == (char *) NULL)
+ CLIWandExceptionBreak(OptionWarning,
+ "InterpretPropertyFailure",option);
+ }
+ if (LocaleNCompare(arg1,"artifact:",9) == 0)
+ (void) SetImageArtifact(_images,arg1+9,arg2);
+ else if (LocaleNCompare(arg1,"property:",9) == 0)
+ (void) SetImageProperty(_images,arg1+9,arg2,_exception);
+ else
+ (void) SetImageProperty(_images,arg1,arg2,_exception);
+ arg2=DestroyString((char *)arg2);
+ }
+ MagickResetIterator(&cli_wand->wand);
+ arg1=DestroyString((char *)arg1);
break;
- }
- case MagickColorOptions:
- {
- (void) ListColorInfo((FILE *) NULL,_exception);
+ }
+ if (LocaleCompare("clone",option+1) == 0) {
+ Image
+ *new_images;
+
+ if (*option == '+')
+ arg1="-1";
+ if (IfMagickFalse(IsSceneGeometry(arg1,MagickFalse)))
+ CLIWandExceptionBreak(OptionError,"InvalidArgument",option);
+ if ( cli_wand->image_list_stack == (Stack *)NULL)
+ CLIWandExceptionBreak(OptionError,"UnableToCloneImage",option);
+ new_images = (Image *)cli_wand->image_list_stack->data;
+ if (new_images == (Image *) NULL)
+ CLIWandExceptionBreak(OptionError,"UnableToCloneImage",option);
+ new_images=CloneImages(new_images,arg1,_exception);
+ if (new_images == (Image *) NULL)
+ CLIWandExceptionBreak(OptionError,"NoSuchImage",option);
+ AppendImageToList(&_images,new_images);
break;
}
- case MagickConfigureOptions:
+ /*
+ Informational Operations.
+
+ Note that these do not require either a cli-wand or images!
+ Though currently a cli-wand much be provided regardless.
+ */
+ if (LocaleCompare("version",option+1) == 0)
{
- (void) ListConfigureInfo((FILE *) NULL,_exception);
+ ListMagickVersion(stdout);
break;
}
- case MagickDelegateOptions:
- {
- (void) ListDelegateInfo((FILE *) NULL,_exception);
+ if (LocaleCompare("list",option+1) == 0) {
+ /*
+ FUTURE: This 'switch' should really be part of MagickCore
+ */
+ ssize_t
+ list;
+
+ list=ParseCommandOption(MagickListOptions,MagickFalse,arg1);
+ if ( list < 0 ) {
+ CLIWandExceptionArg(OptionError,"UnrecognizedListType",option,arg1);
break;
}
- case MagickFontOptions:
+ switch (list)
{
- (void) ListTypeInfo((FILE *) NULL,_exception);
- break;
+ case MagickCoderOptions:
+ {
+ (void) ListCoderInfo((FILE *) NULL,_exception);
+ break;
+ }
+ case MagickColorOptions:
+ {
+ (void) ListColorInfo((FILE *) NULL,_exception);
+ break;
+ }
+ case MagickConfigureOptions:
+ {
+ (void) ListConfigureInfo((FILE *) NULL,_exception);
+ break;
+ }
+ case MagickDelegateOptions:
+ {
+ (void) ListDelegateInfo((FILE *) NULL,_exception);
+ break;
+ }
+ case MagickFontOptions:
+ {
+ (void) ListTypeInfo((FILE *) NULL,_exception);
+ break;
+ }
+ case MagickFormatOptions:
+ (void) ListMagickInfo((FILE *) NULL,_exception);
+ break;
+ case MagickLocaleOptions:
+ (void) ListLocaleInfo((FILE *) NULL,_exception);
+ break;
+ case MagickLogOptions:
+ (void) ListLogInfo((FILE *) NULL,_exception);
+ break;
+ case MagickMagicOptions:
+ (void) ListMagicInfo((FILE *) NULL,_exception);
+ break;
+ case MagickMimeOptions:
+ (void) ListMimeInfo((FILE *) NULL,_exception);
+ break;
+ case MagickModuleOptions:
+ (void) ListModuleInfo((FILE *) NULL,_exception);
+ break;
+ case MagickPolicyOptions:
+ (void) ListPolicyInfo((FILE *) NULL,_exception);
+ break;
+ case MagickResourceOptions:
+ (void) ListMagickResourceInfo((FILE *) NULL,_exception);
+ break;
+ case MagickThresholdOptions:
+ (void) ListThresholdMaps((FILE *) NULL,_exception);
+ break;
+ default:
+ (void) ListCommandOptions((FILE *) NULL,(CommandOption) list,
+ _exception);
+ break;
}
- case MagickFormatOptions:
- (void) ListMagickInfo((FILE *) NULL,_exception);
- break;
- case MagickLocaleOptions:
- (void) ListLocaleInfo((FILE *) NULL,_exception);
- break;
- case MagickLogOptions:
- (void) ListLogInfo((FILE *) NULL,_exception);
- break;
- case MagickMagicOptions:
- (void) ListMagicInfo((FILE *) NULL,_exception);
- break;
- case MagickMimeOptions:
- (void) ListMimeInfo((FILE *) NULL,_exception);
- break;
- case MagickModuleOptions:
- (void) ListModuleInfo((FILE *) NULL,_exception);
- break;
- case MagickPolicyOptions:
- (void) ListPolicyInfo((FILE *) NULL,_exception);
- break;
- case MagickResourceOptions:
- (void) ListMagickResourceInfo((FILE *) NULL,_exception);
- break;
- case MagickThresholdOptions:
- (void) ListThresholdMaps((FILE *) NULL,_exception);
- break;
- default:
- (void) ListCommandOptions((FILE *) NULL,(CommandOption) list,
- _exception);
- break;
+ break;
}
- return;
- }
-#if 0
- // Other 'special' options this should handle
- // "region" "reset" "arg"
- if ( ( process_flags & ProcessUnknownOptionError ) != 0 )
-#endif
CLIWandException(OptionError,"UnrecognizedOption",option);
+DisableMSCWarning(4127)
+ } while (0); /* break to exit code. */
+RestoreMSCWarning
+
+ /* clean up percent escape interpreted strings */
+ if (arg1 != arg1n )
+ arg1=DestroyString((char *)arg1);
+ if (arg2 != arg2n )
+ arg2=DestroyString((char *)arg2);
+
#undef _image_info
#undef _images
#undef _exception
% %
% %
% %
-+ C L I O p t i o n O p e r a t i o n s %
++ C L I O p t i o n %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% CLIOption() Processes the given option using the given CLI Magick Wand.
+% The option arguments can be variable in number, though at this time no more
+% that two is actually used by any option (this may change). Excess options
+% are simply ignored.
%
% If the cli_wand->command pointer is non-null, then it is assumed that the
% option has already been search for up from the CommandOptions[] table in
-% "MagickCore/options.c" using GetCommandOptionInfo(), so that any command
-% specific options (such as "magick" scripting options, or "display" settings)
-% can be handled separatally.
+% "MagickCore/options.c" using GetCommandOptionInfo(). If not set this
+% routine will do the lookup instead. The pointer is reset afterward.
+%
+% This action allows the caller to lookup and pre-handle any 'special'
+% options, (such as implicit reads) before calling this general option
+% handler to deal with 'standard' command line options.
%
% The format of the CLIOption method is:
%
%
% o option: The special option (with any switch char) to process
%
-% o args: any required arguments for an option
+% o args: any required arguments for an option (variable number)
%
% Example Usage...
%
*/
WandExport void CLIOption(MagickCLI *cli_wand,const char *option,...)
{
- const char
+ const char /* extracted option args from args */
*arg1,
*arg2;
assert(cli_wand != (MagickCLI *) NULL);
assert(cli_wand->signature == WandSignature);
assert(cli_wand->wand.signature == WandSignature);
- if (IfMagickTrue(cli_wand->wand.debug))
- (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
- if ( cli_wand->command == (const OptionInfo *) NULL )
- cli_wand->command = GetCommandOptionInfo(option);
+ do { /* Break Code Block for error handling */
+
+ /* get information about option */
+ if ( cli_wand->command == (const OptionInfo *) NULL )
+ cli_wand->command = GetCommandOptionInfo(option);
#if 0
- (void) FormatLocaleFile(stderr, "CLIOption \"%s\" matched \"%s\"\n",
- option, cli_wand->command->mnemonic );
+ (void) FormatLocaleFile(stderr, "CLIOption \"%s\" matched \"%s\"\n",
+ option, cli_wand->command->mnemonic );
#endif
+ option_type=(CommandOptionFlags) cli_wand->command->flags;
- option_type=(CommandOptionFlags) cli_wand->command->flags;
+ if ( option_type == UndefinedOptionFlag )
+ CLIWandExceptionReturn(OptionFatalError,"UnrecognizedOption",option);
- if ( option_type == UndefinedOptionFlag )
- CLIWandExceptionReturn(OptionFatalError,"UnrecognizedOption",option);
+ assert( LocaleCompare(cli_wand->command->mnemonic,option) == 0 );
- assert( LocaleCompare(cli_wand->command->mnemonic,option) == 0 );
+ /* depreciated options */
+ if ( (option_type & DeprecateOptionFlag) != 0 )
+ CLIWandExceptionBreak(OptionError,"DeprecatedOptionNoCode",option);
- if ((option_type & (SpecialOptionFlag|GenesisOptionFlag)) != 0 )
- CLIWandExceptionReturn(OptionFatalError,"InvalidUseOfOption",option);
+ /* options that this module does not handle */
+ if ((option_type & (SpecialOptionFlag|GenesisOptionFlag)) != 0 )
+ CLIWandExceptionBreak(OptionFatalError,"InvalidUseOfOption",option);
- if ( (option_type & DeprecateOptionFlag) != 0 )
- CLIWandExceptionReturn(OptionError,"DeprecatedOptionNoCode",option);
-
- if ( IfMagickTrue(CLICatchException(cli_wand, MagickFalse)) )
- return;
-
-
- { size_t
- count = cli_wand->command->type;
-
- va_list
- operands;
+ /* Get argument strings from VarArgs
+ How can you determine if enough arguments was supplied?
+ What happens if not enough arguments were supplied?
+ */
+ { size_t
+ count = cli_wand->command->type;
- va_start(operands,option);
+ va_list
+ operands;
- arg1=arg2=NULL;
- if ( count >= 1 )
- arg1=(const char *) va_arg(operands, const char *);
- if ( count >= 2 )
- arg2=(const char *) va_arg(operands, const char *);
+ va_start(operands,option);
- va_end(operands);
+ arg1=arg2=NULL;
+ if ( count >= 1 )
+ arg1=(const char *) va_arg(operands, const char *);
+ if ( count >= 2 )
+ arg2=(const char *) va_arg(operands, const char *);
+ va_end(operands);
#if 0
- (void) FormatLocaleFile(stderr,
- "CLIOption: \"%s\" Count: %ld Flags: %04x Args: \"%s\" \"%s\"\n",
- option,(long) count,option_type,arg1,arg2);
+ (void) FormatLocaleFile(stderr,
+ "CLIOption: \"%s\" Count: %ld Flags: %04x Args: \"%s\" \"%s\"\n",
+ option,(long) count,option_type,arg1,arg2);
#endif
- }
+ }
- cli_wand->command = (const OptionInfo *) NULL; /* prevent re-use later */
+ /*
+ Call the appropriate option handler
+ */
+ /* FUTURE: this is temporary - get 'settings' to handle distribution of
+ settings to images attributes,proprieties,artifacts */
+ if ( cli_wand->wand.images != (Image *)NULL )
+ SyncImagesSettings(cli_wand->wand.image_info,cli_wand->wand.images,
+ cli_wand->wand.exception);
- /*
- Call the appropriate option handler
- */
+ if ( (option_type & SettingOptionFlags) != 0 ) {
+ CLISettingOptionInfo(cli_wand, option, arg1, arg2);
+ // FUTURE: Sync Specific Settings into Image Properities (not global)
+ }
- /* FUTURE: this is temporary - get 'settings' to handle
- distribution of settings to images attributes,proprieties,artifacts */
- if ( cli_wand->wand.images != (Image *)NULL )
- SyncImagesSettings(cli_wand->wand.image_info,cli_wand->wand.images,
- cli_wand->wand.exception);
+ /* Operators that do not need images - read, write, stack, clone */
+ if ( (option_type & NoImageOperatorFlag) != 0)
+ CLINoImageOperator(cli_wand, option, arg1, arg2);
- if ( (option_type & SettingOptionFlags) != 0 ) {
- CLISettingOptionInfo(cli_wand, option, arg1, arg2);
- // FUTURE: Sync Specific Settings into Image Properities (not global)
- }
+ /* FUTURE: The not a setting part below is a temporary hack due to
+ * some options being both a Setting and a Simple operator.
+ * Specifically -monitor, -depth, and -colorspace */
+ if ( cli_wand->wand.images == (Image *)NULL )
+ if ( ((option_type & (SimpleOperatorFlag|ListOperatorFlag)) != 0 ) &&
+ ((option_type & SettingOptionFlags) == 0 )) /* temp hack */
+ CLIWandExceptionBreak(OptionError,"NoImagesFound",option);
- if ( (option_type & NoImageOperatorFlag) != 0)
- CLINoImageOperator(cli_wand, option, arg1, arg2);
-
- /* FUTURE: The not a setting part below is a temporary hack due to
- * some options being both a Setting and a Simple operator.
- * Specifically -monitor, -depth, and -colorspace */
- if ( cli_wand->wand.images == (Image *)NULL ) {
- if ( ((option_type & (SimpleOperatorFlag|ListOperatorFlag)) != 0 ) &&
- ((option_type & SettingOptionFlags) == 0 )) /* temp hack */
- CLIWandException(OptionError,"NoImagesFound",option);
- return; /* on its own this is not an error */
- }
+ /* Operators which loop of individual images, simply */
+ if ( (option_type & SimpleOperatorFlag) != 0 &&
+ cli_wand->wand.images != (Image *)NULL) /* temp hack */
+ CLISimpleOperatorImages(cli_wand, option, arg1, arg2);
- if ( (option_type & SimpleOperatorFlag) != 0)
- CLISimpleOperatorImages(cli_wand, option, arg1, arg2);
+ /* Operators that work on the image list as a whole */
+ if ( (option_type & ListOperatorFlag) != 0 )
+ CLIListOperatorImages(cli_wand, option, arg1, arg2);
- if ( (option_type & ListOperatorFlag) != 0 )
- CLIListOperatorImages(cli_wand, option, arg1, arg2);
+DisableMSCWarning(4127)
+ } while (0); /* end Break code block */
+RestoreMSCWarning
+ cli_wand->command = (const OptionInfo *) NULL; /* prevent re-use later */
}