blob: 9f531542cba0d8ad8cd83688487adcc933e3835b [file] [log] [blame]
anthony805a2d42011-09-25 08:25:12 +00001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% %
anthony8b10b462012-02-08 12:32:44 +00006% 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 %
anthony805a2d42011-09-25 08:25:12 +000011% %
12% %
anthony8b10b462012-02-08 12:32:44 +000013% CLI Magick Option Methods %
anthony805a2d42011-09-25 08:25:12 +000014% %
anthony8b10b462012-02-08 12:32:44 +000015% Dragon Computing %
cristy9e58efd2012-01-30 14:27:34 +000016% Anthony Thyssen %
cristy0a0ca4f2011-09-28 01:15:28 +000017% September 2011 %
anthony805a2d42011-09-25 08:25:12 +000018% %
19% %
cristy1454be72011-12-19 01:52:48 +000020% Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization %
anthony805a2d42011-09-25 08:25:12 +000021% dedicated to making software imaging solutions freely available. %
22% %
23% You may not use this file except in compliance with the License. You may %
24% obtain a copy of the License at %
25% %
26% http://www.imagemagick.org/script/license.php %
27% %
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. %
33% %
34%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35%
36% Apply the given options (settings, and simple, or sequence operations) to
anthony8b10b462012-02-08 12:32:44 +000037% the given image(s) according to the current "image_info", "draw_info", and
38% "quantize_info" settings, stored in a special CLI Image Wand.
anthony805a2d42011-09-25 08:25:12 +000039%
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
42% IMv7.
43%
anthony8b10b462012-02-08 12:32:44 +000044% Anthony Thyssen, September 2011
anthony805a2d42011-09-25 08:25:12 +000045*/
46
47/*
48 Include declarations.
49*/
50#include "MagickWand/studio.h"
51#include "MagickWand/MagickWand.h"
anthony72feaa62012-01-17 06:46:23 +000052#include "MagickWand/magick-wand-private.h"
anthony43f425d2012-02-26 12:58:58 +000053#include "MagickWand/wand.h"
anthony756cd0d2012-04-08 12:41:44 +000054#include "MagickWand/wandcli.h"
55#include "MagickWand/wandcli-private.h"
56#include "MagickWand/operation.h"
anthony805a2d42011-09-25 08:25:12 +000057#include "MagickCore/monitor-private.h"
58#include "MagickCore/thread-private.h"
59#include "MagickCore/string-private.h"
60
61/*
62 Define declarations.
63*/
anthonyafa3dfc2012-03-03 11:31:30 +000064#define USE_WAND_METHODS 0
65#define MAX_STACK_DEPTH 32
66#define UNDEFINED_COMPRESSION_QUALITY 0UL
67
anthonyb1d483a2012-04-14 12:53:56 +000068/* FUTURE: why is this default so specific? */
69#define DEFAULT_DISSIMILARITY_THRESHOLD "0.31830988618379067154"
70
anthony805a2d42011-09-25 08:25:12 +000071/*
72 Constant declaration. (temporary exports)
73*/
74static const char
75 BackgroundColor[] = "#fff", /* white */
anthony72feaa62012-01-17 06:46:23 +000076 BorderColor[] = "#dfdfdf", /* sRGB gray */
77 MatteColor[] = "#bdbdbd"; /* slightly darker gray */
anthony22de2722012-04-19 14:43:00 +000078
79/* For Debugging Geometry Input */
80#define ReportGeometry(flags,info) \
81 (void) FormatLocaleFile(stderr, "Geometry = 0x%04X : %lg x %lg %+lg %+lg\n", \
82 flags, info.rho, info.sigma, info.xi, info.psi )
anthony805a2d42011-09-25 08:25:12 +000083
84/*
85** Function to report on the progress of image operations
86*/
87static MagickBooleanType MonitorProgress(const char *text,
88 const MagickOffsetType offset,const MagickSizeType extent,
anthony43f425d2012-02-26 12:58:58 +000089 void *wand_unused(cli_wandent_data))
anthony805a2d42011-09-25 08:25:12 +000090{
91 char
92 message[MaxTextExtent],
93 tag[MaxTextExtent];
94
95 const char
96 *locale_message;
97
98 register char
99 *p;
100
101 if (extent < 2)
102 return(MagickTrue);
103 (void) CopyMagickMemory(tag,text,MaxTextExtent);
104 p=strrchr(tag,'/');
105 if (p != (char *) NULL)
106 *p='\0';
107 (void) FormatLocaleString(message,MaxTextExtent,"Monitor/%s",tag);
108 locale_message=GetLocaleMessage(message);
109 if (locale_message == message)
110 locale_message=tag;
111 if (p == (char *) NULL)
112 (void) FormatLocaleFile(stderr,"%s: %ld of %lu, %02ld%% complete\r",
113 locale_message,(long) offset,(unsigned long) extent,(long)
114 (100L*offset/(extent-1)));
115 else
116 (void) FormatLocaleFile(stderr,"%s[%s]: %ld of %lu, %02ld%% complete\r",
117 locale_message,p+1,(long) offset,(unsigned long) extent,(long)
118 (100L*offset/(extent-1)));
119 if (offset == (MagickOffsetType) (extent-1))
120 (void) FormatLocaleFile(stderr,"\n");
121 (void) fflush(stderr);
122 return(MagickTrue);
123}
124
125/*
126** GetImageCache() will read an image into a image cache if not already
127** present then return the image that is in the cache under that filename.
128*/
129static inline Image *GetImageCache(const ImageInfo *image_info,const char *path,
130 ExceptionInfo *exception)
131{
132 char
133 key[MaxTextExtent];
134
135 ExceptionInfo
136 *sans_exception;
137
138 Image
139 *image;
140
141 ImageInfo
142 *read_info;
143
144 (void) FormatLocaleString(key,MaxTextExtent,"cache:%s",path);
145 sans_exception=AcquireExceptionInfo();
146 image=(Image *) GetImageRegistry(ImageRegistryType,key,sans_exception);
147 sans_exception=DestroyExceptionInfo(sans_exception);
148 if (image != (Image *) NULL)
149 return(image);
150 read_info=CloneImageInfo(image_info);
151 (void) CopyMagickString(read_info->filename,path,MaxTextExtent);
152 image=ReadImage(read_info,exception);
153 read_info=DestroyImageInfo(read_info);
154 if (image != (Image *) NULL)
155 (void) SetImageRegistry(ImageRegistryType,key,image,exception);
156 return(image);
157}
158
anthony756cd0d2012-04-08 12:41:44 +0000159/*
anthonya89dd172011-10-04 13:29:35 +0000160 SparseColorOption() parse the complex -sparse-color argument into an
161 an array of floating point values than call SparseColorImage().
162 Argument is a complex mix of floating-point pixel coodinates, and color
163 specifications (or direct floating point numbers). The number of floats
164 needed to represent a color varies depending on teh current channel
165 setting.
anthony43f425d2012-02-26 12:58:58 +0000166
167 This really should be in MagickCore, so that other API's can make use of it.
anthony805a2d42011-09-25 08:25:12 +0000168*/
169static Image *SparseColorOption(const Image *image,
170 const SparseColorMethod method,const char *arguments,
anthony31f1bf72012-01-30 12:37:22 +0000171 ExceptionInfo *exception)
anthony805a2d42011-09-25 08:25:12 +0000172{
173 char
174 token[MaxTextExtent];
175
176 const char
177 *p;
178
179 double
180 *sparse_arguments;
181
182 Image
183 *sparse_image;
184
185 PixelInfo
186 color;
187
188 MagickBooleanType
189 error;
190
191 register size_t
192 x;
193
194 size_t
195 number_arguments,
196 number_colors;
197
198 assert(image != (Image *) NULL);
199 assert(image->signature == MagickSignature);
anthony7bcfe7f2012-03-30 14:01:22 +0000200 if (IfMagickTrue(image->debug))
anthony805a2d42011-09-25 08:25:12 +0000201 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
202 assert(exception != (ExceptionInfo *) NULL);
203 assert(exception->signature == MagickSignature);
204 /*
anthonyb1d483a2012-04-14 12:53:56 +0000205 Limit channels according to image
206 add up number of values needed per color.
anthony805a2d42011-09-25 08:25:12 +0000207 */
208 number_colors=0;
209 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
210 number_colors++;
211 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
212 number_colors++;
213 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
214 number_colors++;
215 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
216 (image->colorspace == CMYKColorspace))
217 number_colors++;
218 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
anthony7bcfe7f2012-03-30 14:01:22 +0000219 IfMagickTrue(image->matte))
anthony805a2d42011-09-25 08:25:12 +0000220 number_colors++;
221
222 /*
223 Read string, to determine number of arguments needed,
224 */
225 p=arguments;
226 x=0;
227 while( *p != '\0' )
228 {
229 GetMagickToken(p,&p,token);
230 if ( token[0] == ',' ) continue;
anthony31f1bf72012-01-30 12:37:22 +0000231 if ( isalpha((int) token[0]) || token[0] == '#' )
232 x += number_colors; /* color argument found */
anthonyce8dcb32012-03-21 13:20:31 +0000233 else
anthony805a2d42011-09-25 08:25:12 +0000234 x++; /* floating point argument */
anthony805a2d42011-09-25 08:25:12 +0000235 }
anthony31f1bf72012-01-30 12:37:22 +0000236 /* control points and color values */
anthony7bcfe7f2012-03-30 14:01:22 +0000237 error = IsMagickTrue( x % (2+number_colors) );
anthony31f1bf72012-01-30 12:37:22 +0000238 number_arguments=x;
anthony7bcfe7f2012-03-30 14:01:22 +0000239 if ( IfMagickTrue(error) ) {
anthony805a2d42011-09-25 08:25:12 +0000240 (void) ThrowMagickException(exception,GetMagickModule(),
anthony43f425d2012-02-26 12:58:58 +0000241 OptionError, "InvalidArgument", "'%s': %s", "sparse-color",
anthony805a2d42011-09-25 08:25:12 +0000242 "Invalid number of Arguments");
243 return( (Image *)NULL);
244 }
245
246 /* Allocate and fill in the floating point arguments */
247 sparse_arguments=(double *) AcquireQuantumMemory(number_arguments,
248 sizeof(*sparse_arguments));
249 if (sparse_arguments == (double *) NULL) {
250 (void) ThrowMagickException(exception,GetMagickModule(),ResourceLimitError,
251 "MemoryAllocationFailed","%s","SparseColorOption");
252 return( (Image *)NULL);
253 }
254 (void) ResetMagickMemory(sparse_arguments,0,number_arguments*
255 sizeof(*sparse_arguments));
256 p=arguments;
257 x=0;
258 while( *p != '\0' && x < number_arguments ) {
259 /* X coordinate */
260 token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token);
261 if ( token[0] == '\0' ) break;
262 if ( isalpha((int) token[0]) || token[0] == '#' ) {
263 (void) ThrowMagickException(exception,GetMagickModule(),
anthony43f425d2012-02-26 12:58:58 +0000264 OptionError, "InvalidArgument", "'%s': %s", "sparse-color",
anthony805a2d42011-09-25 08:25:12 +0000265 "Color found, instead of X-coord");
266 error = MagickTrue;
267 break;
268 }
cristydbdd0e32011-11-04 23:29:40 +0000269 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +0000270 /* Y coordinate */
271 token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token);
272 if ( token[0] == '\0' ) break;
273 if ( isalpha((int) token[0]) || token[0] == '#' ) {
274 (void) ThrowMagickException(exception,GetMagickModule(),
anthony43f425d2012-02-26 12:58:58 +0000275 OptionError, "InvalidArgument", "'%s': %s", "sparse-color",
anthony805a2d42011-09-25 08:25:12 +0000276 "Color found, instead of Y-coord");
277 error = MagickTrue;
278 break;
279 }
cristydbdd0e32011-11-04 23:29:40 +0000280 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
anthony31f1bf72012-01-30 12:37:22 +0000281 /* color name or function given in string argument */
282 token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token);
283 if ( token[0] == '\0' ) break;
284 if ( isalpha((int) token[0]) || token[0] == '#' ) {
285 /* Color string given */
286 (void) QueryColorCompliance(token,AllCompliance,&color,
287 exception);
288 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
289 sparse_arguments[x++] = QuantumScale*color.red;
290 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
291 sparse_arguments[x++] = QuantumScale*color.green;
292 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
293 sparse_arguments[x++] = QuantumScale*color.blue;
294 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
295 (image->colorspace == CMYKColorspace))
296 sparse_arguments[x++] = QuantumScale*color.black;
297 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
anthony7bcfe7f2012-03-30 14:01:22 +0000298 IfMagickTrue(image->matte))
anthony31f1bf72012-01-30 12:37:22 +0000299 sparse_arguments[x++] = QuantumScale*color.alpha;
anthony805a2d42011-09-25 08:25:12 +0000300 }
anthony31f1bf72012-01-30 12:37:22 +0000301 else {
302 /* Colors given as a set of floating point values - experimental */
303 /* NB: token contains the first floating point value to use! */
304 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
305 {
306 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
307 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
308 break;
309 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
310 token[0] = ','; /* used this token - get another */
anthony805a2d42011-09-25 08:25:12 +0000311 }
anthony31f1bf72012-01-30 12:37:22 +0000312 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
313 {
314 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
315 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
316 break;
317 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
318 token[0] = ','; /* used this token - get another */
319 }
320 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
321 {
322 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
323 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
324 break;
325 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
326 token[0] = ','; /* used this token - get another */
327 }
328 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
329 (image->colorspace == CMYKColorspace))
330 {
331 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
332 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
333 break;
334 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
335 token[0] = ','; /* used this token - get another */
336 }
337 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
anthony7bcfe7f2012-03-30 14:01:22 +0000338 IfMagickTrue(image->matte))
anthony31f1bf72012-01-30 12:37:22 +0000339 {
340 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
341 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
342 break;
343 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
344 token[0] = ','; /* used this token - get another */
anthony805a2d42011-09-25 08:25:12 +0000345 }
346 }
347 }
348 if ( number_arguments != x && !error ) {
349 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
anthony43f425d2012-02-26 12:58:58 +0000350 "InvalidArgument","'%s': %s","sparse-color","Argument Parsing Error");
anthony805a2d42011-09-25 08:25:12 +0000351 sparse_arguments=(double *) RelinquishMagickMemory(sparse_arguments);
352 return( (Image *)NULL);
353 }
354 if ( error )
355 return( (Image *)NULL);
356
anthony31f1bf72012-01-30 12:37:22 +0000357 /* Call the Sparse Color Interpolation function with the parsed arguments */
anthony805a2d42011-09-25 08:25:12 +0000358 sparse_image=SparseColorImage(image,method,number_arguments,sparse_arguments,
359 exception);
360 sparse_arguments=(double *) RelinquishMagickMemory(sparse_arguments);
361 return( sparse_image );
362}
363
364/*
365%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
366% %
367% %
368% %
anthony464f1c42012-04-22 08:51:01 +0000369% C L I S e t t i n g O p t i o n I n f o %
anthony43f425d2012-02-26 12:58:58 +0000370% %
371% %
372% %
373%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
374%
375% CLISettingOptionInfo() applies a single settings option into a CLI wand
376% holding the image_info, draw_info, quantize_info structures that will be
377% used when processing the images.
378%
379% These options do no require images to be present in the CLI wand for them
380% to be able to be set, in which case they will generally be applied to image
381% that are read in later
anthony80c37752012-01-16 01:03:11 +0000382%
383% Options handled by this function are listed in CommandOptions[] of
anthonyfd706f92012-01-19 04:22:02 +0000384% "option.c" that is one of "SettingOptionFlags" option flags.
anthony805a2d42011-09-25 08:25:12 +0000385%
anthony2052d272012-02-28 12:48:29 +0000386% The format of the CLISettingOptionInfo method is:
anthony1afdc7a2011-10-05 11:54:28 +0000387%
anthonyafa3dfc2012-03-03 11:31:30 +0000388% void CLISettingOptionInfo(MagickCLI *cli_wand,
anthonye5fcd362012-04-09 04:02:09 +0000389% const char *option, const char *arg1, const char *arg2)
anthony805a2d42011-09-25 08:25:12 +0000390%
391% A description of each parameter follows:
392%
anthony43f425d2012-02-26 12:58:58 +0000393% o cli_wand: structure holding settings to be applied
anthony805a2d42011-09-25 08:25:12 +0000394%
anthonydcf510d2011-10-30 13:51:40 +0000395% o option: The option string to be set
anthony805a2d42011-09-25 08:25:12 +0000396%
anthonye5fcd362012-04-09 04:02:09 +0000397% o arg1, arg2: optional argument strings to the operation
398% arg2 is currently only used by "-limit"
anthonydcf510d2011-10-30 13:51:40 +0000399%
anthony805a2d42011-09-25 08:25:12 +0000400*/
anthonyafa3dfc2012-03-03 11:31:30 +0000401WandExport void CLISettingOptionInfo(MagickCLI *cli_wand,
anthonye5fcd362012-04-09 04:02:09 +0000402 const char *option,const char *arg1, const char *arg2)
anthony805a2d42011-09-25 08:25:12 +0000403{
anthony30b912a2012-03-22 01:20:28 +0000404 ssize_t
405 parse; /* option argument parsing (string to value table lookup) */
406
anthony43f425d2012-02-26 12:58:58 +0000407 assert(cli_wand != (MagickCLI *) NULL);
408 assert(cli_wand->signature == WandSignature);
409 assert(cli_wand->wand.signature == WandSignature);
anthony7bcfe7f2012-03-30 14:01:22 +0000410 if (IfMagickTrue(cli_wand->wand.debug))
anthony43f425d2012-02-26 12:58:58 +0000411 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
anthony1afdc7a2011-10-05 11:54:28 +0000412
anthony2e4501b2012-03-30 04:41:54 +0000413#define _image_info (cli_wand->wand.image_info)
414#define _exception (cli_wand->wand.exception)
415#define _draw_info (cli_wand->draw_info)
416#define _quantize_info (cli_wand->quantize_info)
anthony24aa8822012-03-11 00:56:06 +0000417#define IfSetOption (*option=='-')
anthony7bcfe7f2012-03-30 14:01:22 +0000418#define ArgBoolean IsMagickTrue(IfSetOption)
419#define ArgBooleanNot IsMagickFalse(IfSetOption)
anthony24aa8822012-03-11 00:56:06 +0000420#define ArgBooleanString (IfSetOption?"true":"false")
421#define ArgOption(def) (IfSetOption?arg1:(const char *)(def))
anthony74b1cfc2011-10-06 12:44:16 +0000422
anthonyafa3dfc2012-03-03 11:31:30 +0000423 switch (*(option+1))
anthony805a2d42011-09-25 08:25:12 +0000424 {
425 case 'a':
426 {
anthonyafa3dfc2012-03-03 11:31:30 +0000427 if (LocaleCompare("adjoin",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000428 {
anthony92c93bd2012-03-19 14:02:47 +0000429 _image_info->adjoin = ArgBoolean;
anthony805a2d42011-09-25 08:25:12 +0000430 break;
431 }
anthonyafa3dfc2012-03-03 11:31:30 +0000432 if (LocaleCompare("affine",option+1) == 0)
anthony1afdc7a2011-10-05 11:54:28 +0000433 {
anthony464f1c42012-04-22 08:51:01 +0000434 CLIWandWarnReplaced("-draw 'affine ...'");
anthony74b1cfc2011-10-06 12:44:16 +0000435 if (IfSetOption)
anthony92c93bd2012-03-19 14:02:47 +0000436 (void) ParseAffineGeometry(arg1,&_draw_info->affine,_exception);
anthony74b1cfc2011-10-06 12:44:16 +0000437 else
anthony92c93bd2012-03-19 14:02:47 +0000438 GetAffineMatrix(&_draw_info->affine);
anthony1afdc7a2011-10-05 11:54:28 +0000439 break;
440 }
anthonyafa3dfc2012-03-03 11:31:30 +0000441 if (LocaleCompare("antialias",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000442 {
anthony92c93bd2012-03-19 14:02:47 +0000443 _image_info->antialias =
444 _draw_info->stroke_antialias =
445 _draw_info->text_antialias = ArgBoolean;
anthony805a2d42011-09-25 08:25:12 +0000446 break;
447 }
anthony31f1bf72012-01-30 12:37:22 +0000448 if (LocaleCompare("attenuate",option+1) == 0)
449 {
anthony7bcfe7f2012-03-30 14:01:22 +0000450 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthony92c93bd2012-03-19 14:02:47 +0000451 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
452 (void) SetImageOption(_image_info,option+1,ArgOption("1.0"));
anthony31f1bf72012-01-30 12:37:22 +0000453 break;
454 }
anthonyafa3dfc2012-03-03 11:31:30 +0000455 if (LocaleCompare("authenticate",option+1) == 0)
anthonydcf510d2011-10-30 13:51:40 +0000456 {
anthony92c93bd2012-03-19 14:02:47 +0000457 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +0000458 break;
459 }
anthonyebb73a22012-03-22 14:25:52 +0000460 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +0000461 }
462 case 'b':
463 {
anthonyafa3dfc2012-03-03 11:31:30 +0000464 if (LocaleCompare("background",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000465 {
anthony92c93bd2012-03-19 14:02:47 +0000466 /* FUTURE: both _image_info attribute & ImageOption in use!
467 _image_info only used directly for generating new images.
anthony72feaa62012-01-17 06:46:23 +0000468 SyncImageSettings() used to set per-image attribute.
469
anthony92c93bd2012-03-19 14:02:47 +0000470 FUTURE: if _image_info->background_color is not set then
anthony30b912a2012-03-22 01:20:28 +0000471 we should fall back to per-image background_color
472
473 At this time -background will 'wipe out' the per-image
474 background color!
475
476 Better error handling of QueryColorCompliance() needed.
anthony74b1cfc2011-10-06 12:44:16 +0000477 */
anthony92c93bd2012-03-19 14:02:47 +0000478 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony72feaa62012-01-17 06:46:23 +0000479 (void) QueryColorCompliance(ArgOption(BackgroundColor),AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +0000480 &_image_info->background_color,_exception);
anthony805a2d42011-09-25 08:25:12 +0000481 break;
482 }
anthonyafa3dfc2012-03-03 11:31:30 +0000483 if (LocaleCompare("bias",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000484 {
anthony52bef752012-03-27 13:54:47 +0000485 /* FUTURE: bias OBSOLETED, replaced by Artifact "convolve:bias"
anthony31f1bf72012-01-30 12:37:22 +0000486 as it is actually rarely used except in direct convolve operations
487 Usage outside a direct convolve operation is actally non-sensible!
anthony72feaa62012-01-17 06:46:23 +0000488
489 SyncImageSettings() used to set per-image attribute.
anthony74b1cfc2011-10-06 12:44:16 +0000490 */
anthony7bcfe7f2012-03-30 14:01:22 +0000491 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthony5330ae02012-03-20 14:17:01 +0000492 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyf46d4262012-03-26 03:30:34 +0000493 (void) SetImageOption(_image_info,"convolve:bias",ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +0000494 break;
495 }
anthonyafa3dfc2012-03-03 11:31:30 +0000496 if (LocaleCompare("black-point-compensation",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000497 {
anthony72feaa62012-01-17 06:46:23 +0000498 /* Used as a image chromaticity setting
499 SyncImageSettings() used to set per-image attribute.
500 */
anthony92c93bd2012-03-19 14:02:47 +0000501 (void) SetImageOption(_image_info,option+1,ArgBooleanString);
anthony805a2d42011-09-25 08:25:12 +0000502 break;
503 }
anthonyafa3dfc2012-03-03 11:31:30 +0000504 if (LocaleCompare("blue-primary",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000505 {
anthonyafbaed72011-10-26 12:05:04 +0000506 /* Image chromaticity X,Y NB: Y=X if Y not defined
507 Used by many coders including PNG
anthony72feaa62012-01-17 06:46:23 +0000508 SyncImageSettings() used to set per-image attribute.
anthonyafbaed72011-10-26 12:05:04 +0000509 */
anthonyf42014d2012-03-25 09:53:06 +0000510 arg1=ArgOption("0.0");
anthony7bcfe7f2012-03-30 14:01:22 +0000511 if (IfMagickFalse(IsGeometry(arg1)))
anthony5330ae02012-03-20 14:17:01 +0000512 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyf42014d2012-03-25 09:53:06 +0000513 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000514 break;
515 }
anthonyafa3dfc2012-03-03 11:31:30 +0000516 if (LocaleCompare("bordercolor",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000517 {
anthony92c93bd2012-03-19 14:02:47 +0000518 /* FUTURE: both _image_info attribute & ImageOption in use!
anthony72feaa62012-01-17 06:46:23 +0000519 SyncImageSettings() used to set per-image attribute.
anthony30b912a2012-03-22 01:20:28 +0000520 Better error checking of QueryColorCompliance().
anthony72feaa62012-01-17 06:46:23 +0000521 */
anthony74b1cfc2011-10-06 12:44:16 +0000522 if (IfSetOption)
anthony805a2d42011-09-25 08:25:12 +0000523 {
anthony92c93bd2012-03-19 14:02:47 +0000524 (void) SetImageOption(_image_info,option+1,arg1);
anthony24aa8822012-03-11 00:56:06 +0000525 (void) QueryColorCompliance(arg1,AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +0000526 &_image_info->border_color,_exception);
anthony24aa8822012-03-11 00:56:06 +0000527 (void) QueryColorCompliance(arg1,AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +0000528 &_draw_info->border_color,_exception);
anthony805a2d42011-09-25 08:25:12 +0000529 break;
530 }
anthony92c93bd2012-03-19 14:02:47 +0000531 (void) DeleteImageOption(_image_info,option+1);
anthony74b1cfc2011-10-06 12:44:16 +0000532 (void) QueryColorCompliance(BorderColor,AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +0000533 &_image_info->border_color,_exception);
anthony74b1cfc2011-10-06 12:44:16 +0000534 (void) QueryColorCompliance(BorderColor,AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +0000535 &_draw_info->border_color,_exception);
anthony805a2d42011-09-25 08:25:12 +0000536 break;
537 }
anthonyafa3dfc2012-03-03 11:31:30 +0000538 if (LocaleCompare("box",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000539 {
anthony464f1c42012-04-22 08:51:01 +0000540 CLIWandWarnReplaced("-undercolor");
anthony975a8d72012-04-12 13:54:36 +0000541 CLISettingOptionInfo(cli_wand,"-undercolor",arg1, arg2);
anthonyfd706f92012-01-19 04:22:02 +0000542 break;
anthony805a2d42011-09-25 08:25:12 +0000543 }
anthonyebb73a22012-03-22 14:25:52 +0000544 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +0000545 }
546 case 'c':
547 {
anthonyafa3dfc2012-03-03 11:31:30 +0000548 if (LocaleCompare("cache",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000549 {
550 MagickSizeType
551 limit;
552
anthony7bcfe7f2012-03-30 14:01:22 +0000553 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthony5330ae02012-03-20 14:17:01 +0000554 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +0000555 limit=MagickResourceInfinity;
anthony24aa8822012-03-11 00:56:06 +0000556 if (LocaleCompare("unlimited",arg1) != 0)
557 limit=(MagickSizeType) SiPrefixToDoubleInterval(arg1,100.0);
anthony805a2d42011-09-25 08:25:12 +0000558 (void) SetMagickResourceLimit(MemoryResource,limit);
559 (void) SetMagickResourceLimit(MapResource,2*limit);
560 break;
561 }
anthonyafa3dfc2012-03-03 11:31:30 +0000562 if (LocaleCompare("caption",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000563 {
anthony92c93bd2012-03-19 14:02:47 +0000564 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +0000565 break;
566 }
anthonyafa3dfc2012-03-03 11:31:30 +0000567 if (LocaleCompare("channel",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000568 {
anthony30b912a2012-03-22 01:20:28 +0000569 arg1=ArgOption("default");
570 parse=ParseChannelOption(arg1);
571 if (parse < 0)
572 CLIWandExceptArgBreak(OptionError,"UnrecognizedChannelType",
573 option,arg1);
574 _image_info->channel=(ChannelType) parse;
575 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000576 break;
577 }
anthonyafa3dfc2012-03-03 11:31:30 +0000578 if (LocaleCompare("colorspace",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000579 {
anthonyafbaed72011-10-26 12:05:04 +0000580 /* Setting used for new images via AquireImage()
581 But also used as a SimpleImageOperator
582 Undefined colorspace means don't modify images on
583 read or as a operation */
anthony30b912a2012-03-22 01:20:28 +0000584 parse = ParseCommandOption(MagickColorspaceOptions,MagickFalse,
585 ArgOption("undefined"));
586 if (parse < 0)
anthony5330ae02012-03-20 14:17:01 +0000587 CLIWandExceptArgBreak(OptionError,"UnrecognizedColorspace",
588 option,arg1);
anthony30b912a2012-03-22 01:20:28 +0000589 _image_info->colorspace=(ColorspaceType) parse;
anthony805a2d42011-09-25 08:25:12 +0000590 break;
591 }
anthonyafa3dfc2012-03-03 11:31:30 +0000592 if (LocaleCompare("comment",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000593 {
anthony92c93bd2012-03-19 14:02:47 +0000594 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +0000595 break;
596 }
anthonyafa3dfc2012-03-03 11:31:30 +0000597 if (LocaleCompare("compose",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000598 {
anthony92c93bd2012-03-19 14:02:47 +0000599 /* FUTURE: _image_info should be used,
anthony72feaa62012-01-17 06:46:23 +0000600 SyncImageSettings() used to set per-image attribute. - REMOVE
601
anthonyafbaed72011-10-26 12:05:04 +0000602 This setting should NOT be used to set image 'compose'
anthony92c93bd2012-03-19 14:02:47 +0000603 "-layer" operators shoud use _image_info if defined otherwise
anthony72feaa62012-01-17 06:46:23 +0000604 they should use a per-image compose setting.
anthony965524b2011-10-07 12:34:14 +0000605 */
anthonyebb73a22012-03-22 14:25:52 +0000606 parse = ParseCommandOption(MagickComposeOptions,MagickFalse,
607 ArgOption("undefined"));
608 if (parse < 0)
609 CLIWandExceptArgBreak(OptionError,"UnrecognizedComposeOperator",
610 option,arg1);
611 _image_info->compose=(CompositeOperator) parse;
anthony92c93bd2012-03-19 14:02:47 +0000612 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +0000613 break;
614 }
anthonyafa3dfc2012-03-03 11:31:30 +0000615 if (LocaleCompare("compress",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000616 {
anthony92c93bd2012-03-19 14:02:47 +0000617 /* FUTURE: What should be used? _image_info or ImageOption ???
anthony5f867ae2011-10-09 10:28:34 +0000618 The former is more efficent, but Crisy prefers the latter!
anthony72feaa62012-01-17 06:46:23 +0000619 SyncImageSettings() used to set per-image attribute.
anthony5f867ae2011-10-09 10:28:34 +0000620
anthony92c93bd2012-03-19 14:02:47 +0000621 The coders appears to use _image_info, not Image_Option
anthony5f867ae2011-10-09 10:28:34 +0000622 however the image attribute (for save) is set from the
623 ImageOption!
anthony72feaa62012-01-17 06:46:23 +0000624
625 Note that "undefined" is a different setting to "none".
anthony5f867ae2011-10-09 10:28:34 +0000626 */
anthonyebb73a22012-03-22 14:25:52 +0000627 parse = ParseCommandOption(MagickCompressOptions,MagickFalse,
628 ArgOption("undefined"));
629 if (parse < 0)
630 CLIWandExceptArgBreak(OptionError,"UnrecognizedImageCompression",
631 option,arg1);
632 _image_info->compression=(CompressionType) parse;
anthony92c93bd2012-03-19 14:02:47 +0000633 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +0000634 break;
635 }
anthonyebb73a22012-03-22 14:25:52 +0000636 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +0000637 }
638 case 'd':
639 {
anthonyafa3dfc2012-03-03 11:31:30 +0000640 if (LocaleCompare("debug",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000641 {
anthony72feaa62012-01-17 06:46:23 +0000642 /* SyncImageSettings() used to set per-image attribute. */
anthonyebb73a22012-03-22 14:25:52 +0000643 arg1=ArgOption("none");
644 parse = ParseCommandOption(MagickLogEventOptions,MagickFalse,arg1);
645 if (parse < 0)
646 CLIWandExceptArgBreak(OptionError,"UnrecognizedEventType",
647 option,arg1);
648 (void) SetLogEventMask(arg1);
649 _image_info->debug=IsEventLogging(); /* extract logging*/
anthony43f425d2012-02-26 12:58:58 +0000650 cli_wand->wand.debug=IsEventLogging();
anthony805a2d42011-09-25 08:25:12 +0000651 break;
652 }
anthonyafa3dfc2012-03-03 11:31:30 +0000653 if (LocaleCompare("define",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000654 {
anthony24aa8822012-03-11 00:56:06 +0000655 if (LocaleNCompare(arg1,"registry:",9) == 0)
anthony805a2d42011-09-25 08:25:12 +0000656 {
anthony5f867ae2011-10-09 10:28:34 +0000657 if (IfSetOption)
anthony92c93bd2012-03-19 14:02:47 +0000658 (void) DefineImageRegistry(StringRegistryType,arg1+9,_exception);
anthony5f867ae2011-10-09 10:28:34 +0000659 else
anthony24aa8822012-03-11 00:56:06 +0000660 (void) DeleteImageRegistry(arg1+9);
anthony805a2d42011-09-25 08:25:12 +0000661 break;
662 }
anthony24aa8822012-03-11 00:56:06 +0000663 /* DefineImageOption() equals SetImageOption() but with '=' */
anthony5f867ae2011-10-09 10:28:34 +0000664 if (IfSetOption)
anthony92c93bd2012-03-19 14:02:47 +0000665 (void) DefineImageOption(_image_info,arg1);
anthony7bcfe7f2012-03-30 14:01:22 +0000666 else if (IsMagickFalse(DeleteImageOption(_image_info,arg1)))
anthonyebb73a22012-03-22 14:25:52 +0000667 CLIWandExceptArgBreak(OptionError,"NoSuchOption",option,arg1);
anthony805a2d42011-09-25 08:25:12 +0000668 break;
669 }
anthonyafa3dfc2012-03-03 11:31:30 +0000670 if (LocaleCompare("delay",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000671 {
anthonyafbaed72011-10-26 12:05:04 +0000672 /* Only used for new images via AcquireImage()
673 FUTURE: Option should also be used for "-morph" (color morphing)
anthony5f867ae2011-10-09 10:28:34 +0000674 */
anthonyebb73a22012-03-22 14:25:52 +0000675 arg1=ArgOption("0");
anthony7bcfe7f2012-03-30 14:01:22 +0000676 if (IfMagickFalse(IsGeometry(arg1)))
anthonyebb73a22012-03-22 14:25:52 +0000677 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
678 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000679 break;
680 }
anthonyafa3dfc2012-03-03 11:31:30 +0000681 if (LocaleCompare("density",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000682 {
anthony92c93bd2012-03-19 14:02:47 +0000683 /* FUTURE: strings used in _image_info attr and _draw_info!
anthony72feaa62012-01-17 06:46:23 +0000684 Basically as density can be in a XxY form!
685
686 SyncImageSettings() used to set per-image attribute.
687 */
anthony7bcfe7f2012-03-30 14:01:22 +0000688 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthonyebb73a22012-03-22 14:25:52 +0000689 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +0000690 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
691 (void) CloneString(&_image_info->density,ArgOption(NULL));
692 (void) CloneString(&_draw_info->density,_image_info->density);
anthony805a2d42011-09-25 08:25:12 +0000693 break;
694 }
anthonyafa3dfc2012-03-03 11:31:30 +0000695 if (LocaleCompare("depth",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000696 {
anthony72feaa62012-01-17 06:46:23 +0000697 /* This is also a SimpleImageOperator! for 8->16 vaule trunc !!!!
698 SyncImageSettings() used to set per-image attribute.
699 */
anthony7bcfe7f2012-03-30 14:01:22 +0000700 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthonyebb73a22012-03-22 14:25:52 +0000701 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +0000702 _image_info->depth=IfSetOption?StringToUnsignedLong(arg1)
anthony5f867ae2011-10-09 10:28:34 +0000703 :MAGICKCORE_QUANTUM_DEPTH;
anthony805a2d42011-09-25 08:25:12 +0000704 break;
705 }
anthonyafa3dfc2012-03-03 11:31:30 +0000706 if (LocaleCompare("direction",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000707 {
anthony92c93bd2012-03-19 14:02:47 +0000708 /* Image Option is only used to set _draw_info */
anthonyebb73a22012-03-22 14:25:52 +0000709 arg1=ArgOption("undefined");
710 parse = ParseCommandOption(MagickDirectionOptions,MagickFalse,arg1);
711 if (parse < 0)
712 CLIWandExceptArgBreak(OptionError,"UnrecognizedDirectionType",
713 option,arg1);
714 _draw_info->direction=(DirectionType) parse;
715 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000716 break;
717 }
anthonyafa3dfc2012-03-03 11:31:30 +0000718 if (LocaleCompare("display",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000719 {
anthony92c93bd2012-03-19 14:02:47 +0000720 (void) CloneString(&_image_info->server_name,ArgOption(NULL));
721 (void) CloneString(&_draw_info->server_name,_image_info->server_name);
anthony805a2d42011-09-25 08:25:12 +0000722 break;
723 }
anthonyafa3dfc2012-03-03 11:31:30 +0000724 if (LocaleCompare("dispose",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000725 {
anthony72feaa62012-01-17 06:46:23 +0000726 /* only used in setting new images */
anthonyebb73a22012-03-22 14:25:52 +0000727 arg1=ArgOption("undefined");
728 parse = ParseCommandOption(MagickDisposeOptions,MagickFalse,arg1);
729 if (parse < 0)
730 CLIWandExceptArgBreak(OptionError,"UnrecognizedDisposeMethod",
731 option,arg1);
anthony92c93bd2012-03-19 14:02:47 +0000732 (void) SetImageOption(_image_info,option+1,ArgOption("undefined"));
anthony805a2d42011-09-25 08:25:12 +0000733 break;
734 }
anthonyb1d483a2012-04-14 12:53:56 +0000735 if (LocaleCompare("dissimilarity-threshold",option+1) == 0)
736 {
737 /* FUTURE: this is only used by CompareImages() which is used
738 only by the "compare" CLI program at this time. */
739 arg1=ArgOption(DEFAULT_DISSIMILARITY_THRESHOLD);
740 if (IfMagickFalse(IsGeometry(arg1)))
741 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
742 (void) SetImageOption(_image_info,option+1,arg1);
743 break;
744 }
anthonyafa3dfc2012-03-03 11:31:30 +0000745 if (LocaleCompare("dither",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000746 {
anthony92c93bd2012-03-19 14:02:47 +0000747 /* _image_info attr (on/off), _quantize_info attr (on/off)
748 but also ImageInfo and _quantize_info method!
anthony72feaa62012-01-17 06:46:23 +0000749 FUTURE: merge the duality of the dithering options
750 */
anthony92c93bd2012-03-19 14:02:47 +0000751 _image_info->dither = _quantize_info->dither = ArgBoolean;
752 (void) SetImageOption(_image_info,option+1,ArgOption("none"));
753 _quantize_info->dither_method=(DitherMethod) ParseCommandOption(
anthony72feaa62012-01-17 06:46:23 +0000754 MagickDitherOptions,MagickFalse,ArgOption("none"));
anthony92c93bd2012-03-19 14:02:47 +0000755 if (_quantize_info->dither_method == NoDitherMethod)
756 _image_info->dither = _quantize_info->dither = MagickFalse;
anthony805a2d42011-09-25 08:25:12 +0000757 break;
758 }
anthonyebb73a22012-03-22 14:25:52 +0000759 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +0000760 }
761 case 'e':
762 {
anthonyafa3dfc2012-03-03 11:31:30 +0000763 if (LocaleCompare("encoding",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000764 {
anthony92c93bd2012-03-19 14:02:47 +0000765 (void) CloneString(&_draw_info->encoding,ArgOption("undefined"));
766 (void) SetImageOption(_image_info,option+1,_draw_info->encoding);
anthony805a2d42011-09-25 08:25:12 +0000767 break;
768 }
anthonyafa3dfc2012-03-03 11:31:30 +0000769 if (LocaleCompare("endian",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000770 {
anthony92c93bd2012-03-19 14:02:47 +0000771 /* Both _image_info attr and ImageInfo */
anthony2a0ec8c2012-03-24 04:35:56 +0000772 arg1 = ArgOption("undefined");
773 parse = ParseCommandOption(MagickEndianOptions,MagickFalse,arg1);
774 if (parse < 0)
775 CLIWandExceptArgBreak(OptionError,"UnrecognizedEndianType",
776 option,arg1);
anthonyf46d4262012-03-26 03:30:34 +0000777 /* FUTURE: check alloc/free of endian string! - remove? */
cristyaa2c16c2012-03-25 22:21:35 +0000778 _image_info->endian=(EndianType) (*arg1);
anthony2a0ec8c2012-03-24 04:35:56 +0000779 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000780 break;
781 }
anthonyafa3dfc2012-03-03 11:31:30 +0000782 if (LocaleCompare("extract",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000783 {
anthony92c93bd2012-03-19 14:02:47 +0000784 (void) CloneString(&_image_info->extract,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +0000785 break;
786 }
anthonyebb73a22012-03-22 14:25:52 +0000787 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +0000788 }
789 case 'f':
790 {
anthonyafa3dfc2012-03-03 11:31:30 +0000791 if (LocaleCompare("family",option+1) == 0)
anthony6dc09cd2011-10-12 08:56:49 +0000792 {
anthony92c93bd2012-03-19 14:02:47 +0000793 (void) CloneString(&_draw_info->family,ArgOption(NULL));
anthony6dc09cd2011-10-12 08:56:49 +0000794 break;
795 }
anthonyafa3dfc2012-03-03 11:31:30 +0000796 if (LocaleCompare("fill",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000797 {
anthony92c93bd2012-03-19 14:02:47 +0000798 /* Set "fill" OR "fill-pattern" in _draw_info
anthonyfd706f92012-01-19 04:22:02 +0000799 The original fill color is preserved if a fill-pattern is given.
800 That way it does not effect other operations that directly using
801 the fill color and, can be retored using "+tile".
anthonyafbaed72011-10-26 12:05:04 +0000802 */
anthony72feaa62012-01-17 06:46:23 +0000803 MagickBooleanType
804 status;
anthony6dc09cd2011-10-12 08:56:49 +0000805
806 ExceptionInfo
807 *sans;
808
anthonyfd706f92012-01-19 04:22:02 +0000809 PixelInfo
810 color;
811
anthony2a0ec8c2012-03-24 04:35:56 +0000812 arg1 = ArgOption("none"); /* +fill turns it off! */
813 (void) SetImageOption(_image_info,option+1,arg1);
anthony92c93bd2012-03-19 14:02:47 +0000814 if (_draw_info->fill_pattern != (Image *) NULL)
815 _draw_info->fill_pattern=DestroyImage(_draw_info->fill_pattern);
anthony72feaa62012-01-17 06:46:23 +0000816
817 /* is it a color or a image? -- ignore exceptions */
818 sans=AcquireExceptionInfo();
anthony2a0ec8c2012-03-24 04:35:56 +0000819 status=QueryColorCompliance(arg1,AllCompliance,&color,sans);
anthony72feaa62012-01-17 06:46:23 +0000820 sans=DestroyExceptionInfo(sans);
anthonyfd706f92012-01-19 04:22:02 +0000821
anthony7bcfe7f2012-03-30 14:01:22 +0000822 if (IfMagickFalse(status))
anthony2a0ec8c2012-03-24 04:35:56 +0000823 _draw_info->fill_pattern=GetImageCache(_image_info,arg1,_exception);
anthonyfd706f92012-01-19 04:22:02 +0000824 else
anthony92c93bd2012-03-19 14:02:47 +0000825 _draw_info->fill=color;
anthony805a2d42011-09-25 08:25:12 +0000826 break;
827 }
anthonyafa3dfc2012-03-03 11:31:30 +0000828 if (LocaleCompare("filter",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000829 {
anthony72feaa62012-01-17 06:46:23 +0000830 /* SyncImageSettings() used to set per-image attribute. */
anthony2a0ec8c2012-03-24 04:35:56 +0000831 arg1 = ArgOption("undefined");
832 parse = ParseCommandOption(MagickFilterOptions,MagickFalse,arg1);
833 if (parse < 0)
834 CLIWandExceptArgBreak(OptionError,"UnrecognizedImageFilter",
835 option,arg1);
836 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000837 break;
838 }
anthonyafa3dfc2012-03-03 11:31:30 +0000839 if (LocaleCompare("font",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000840 {
anthony92c93bd2012-03-19 14:02:47 +0000841 (void) CloneString(&_draw_info->font,ArgOption(NULL));
842 (void) CloneString(&_image_info->font,_draw_info->font);
anthony805a2d42011-09-25 08:25:12 +0000843 break;
844 }
anthonyafa3dfc2012-03-03 11:31:30 +0000845 if (LocaleCompare("format",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000846 {
anthonydcf510d2011-10-30 13:51:40 +0000847 /* FUTURE: why the ping test, you could set ping after this! */
848 /*
anthony805a2d42011-09-25 08:25:12 +0000849 register const char
850 *q;
851
anthony24aa8822012-03-11 00:56:06 +0000852 for (q=strchr(arg1,'%'); q != (char *) NULL; q=strchr(q+1,'%'))
anthony805a2d42011-09-25 08:25:12 +0000853 if (strchr("Agkrz@[#",*(q+1)) != (char *) NULL)
anthony92c93bd2012-03-19 14:02:47 +0000854 _image_info->ping=MagickFalse;
anthonydcf510d2011-10-30 13:51:40 +0000855 */
anthony92c93bd2012-03-19 14:02:47 +0000856 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +0000857 break;
858 }
anthonyafa3dfc2012-03-03 11:31:30 +0000859 if (LocaleCompare("fuzz",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000860 {
anthony72feaa62012-01-17 06:46:23 +0000861 /* Option used to set image fuzz! unless blank canvas (from color)
anthonydcf510d2011-10-30 13:51:40 +0000862 Image attribute used for color compare operations
anthony72feaa62012-01-17 06:46:23 +0000863 SyncImageSettings() used to set per-image attribute.
864
anthony2a0ec8c2012-03-24 04:35:56 +0000865 FUTURE: Can't find anything else using _image_info->fuzz directly!
866 remove direct sttribute from image_info
anthony6613bf32011-10-15 07:24:44 +0000867 */
anthony2a0ec8c2012-03-24 04:35:56 +0000868 arg1=ArgOption("0");
anthony7bcfe7f2012-03-30 14:01:22 +0000869 if (IfMagickFalse(IsGeometry(arg1)))
anthony2a0ec8c2012-03-24 04:35:56 +0000870 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
871 _image_info->fuzz=StringToDoubleInterval(arg1,(double)
anthony80c37752012-01-16 01:03:11 +0000872 QuantumRange+1.0);
anthony2a0ec8c2012-03-24 04:35:56 +0000873 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000874 break;
875 }
anthonyebb73a22012-03-22 14:25:52 +0000876 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +0000877 }
878 case 'g':
879 {
anthonyafa3dfc2012-03-03 11:31:30 +0000880 if (LocaleCompare("gravity",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000881 {
anthony72feaa62012-01-17 06:46:23 +0000882 /* SyncImageSettings() used to set per-image attribute. */
anthonyfe1aa782012-03-24 13:43:04 +0000883 arg1 = ArgOption("none");
884 parse = ParseCommandOption(MagickGravityOptions,MagickFalse,arg1);
885 if (parse < 0)
886 CLIWandExceptArgBreak(OptionError,"UnrecognizedGravityType",
887 option,arg1);
anthonyfe1aa782012-03-24 13:43:04 +0000888 _draw_info->gravity=(GravityType) parse;
anthonye8490972012-04-03 13:16:01 +0000889 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000890 break;
891 }
anthonyafa3dfc2012-03-03 11:31:30 +0000892 if (LocaleCompare("green-primary",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000893 {
anthonydcf510d2011-10-30 13:51:40 +0000894 /* Image chromaticity X,Y NB: Y=X if Y not defined
anthony72feaa62012-01-17 06:46:23 +0000895 SyncImageSettings() used to set per-image attribute.
896 Used directly by many coders
anthonydcf510d2011-10-30 13:51:40 +0000897 */
anthonyf42014d2012-03-25 09:53:06 +0000898 arg1=ArgOption("0.0");
anthony7bcfe7f2012-03-30 14:01:22 +0000899 if (IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +0000900 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyf42014d2012-03-25 09:53:06 +0000901 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000902 break;
903 }
anthonyebb73a22012-03-22 14:25:52 +0000904 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +0000905 }
anthonyb1d483a2012-04-14 12:53:56 +0000906 case 'h':
907 {
908 if (LocaleCompare("highlight-color",option+1) == 0)
909 {
910 /* FUTURE: this is only used by CompareImages() which is used
911 only by the "compare" CLI program at this time. */
912 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
913 break;
914 }
915 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
916 }
anthony805a2d42011-09-25 08:25:12 +0000917 case 'i':
918 {
anthonyafa3dfc2012-03-03 11:31:30 +0000919 if (LocaleCompare("intent",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000920 {
anthony72feaa62012-01-17 06:46:23 +0000921 /* Only used by coders: MIFF, MPC, BMP, PNG
anthonydcf510d2011-10-30 13:51:40 +0000922 and for image profile call to AcquireTransformThreadSet()
anthony72feaa62012-01-17 06:46:23 +0000923 SyncImageSettings() used to set per-image attribute.
anthonydcf510d2011-10-30 13:51:40 +0000924 */
anthonyfe1aa782012-03-24 13:43:04 +0000925 arg1 = ArgOption("indefined");
926 parse = ParseCommandOption(MagickIntentOptions,MagickFalse,arg1);
927 if (parse < 0)
928 CLIWandExceptArgBreak(OptionError,"UnrecognizedIntentType",
929 option,arg1);
930 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000931 break;
932 }
anthonyafa3dfc2012-03-03 11:31:30 +0000933 if (LocaleCompare("interlace",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000934 {
anthony92c93bd2012-03-19 14:02:47 +0000935 /* _image_info is directly used by coders (so why an image setting?)
anthony72feaa62012-01-17 06:46:23 +0000936 SyncImageSettings() used to set per-image attribute.
anthonydcf510d2011-10-30 13:51:40 +0000937 */
anthonyfe1aa782012-03-24 13:43:04 +0000938 arg1 = ArgOption("undefined");
939 parse = ParseCommandOption(MagickInterlaceOptions,MagickFalse,arg1);
940 if (parse < 0)
941 CLIWandExceptArgBreak(OptionError,"UnrecognizedInterlaceType",
942 option,arg1);
943 _image_info->interlace=(InterlaceType) parse;
944 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000945 break;
946 }
anthonyafa3dfc2012-03-03 11:31:30 +0000947 if (LocaleCompare("interline-spacing",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000948 {
anthony7bcfe7f2012-03-30 14:01:22 +0000949 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +0000950 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +0000951 (void) SetImageOption(_image_info,option+1, ArgOption(NULL));
952 _draw_info->interline_spacing=StringToDouble(ArgOption("0"),
anthony72feaa62012-01-17 06:46:23 +0000953 (char **) NULL);
anthony805a2d42011-09-25 08:25:12 +0000954 break;
955 }
anthonyafa3dfc2012-03-03 11:31:30 +0000956 if (LocaleCompare("interpolate",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000957 {
anthonyfd706f92012-01-19 04:22:02 +0000958 /* SyncImageSettings() used to set per-image attribute. */
anthonyfe1aa782012-03-24 13:43:04 +0000959 arg1 = ArgOption("undefined");
960 parse = ParseCommandOption(MagickInterpolateOptions,MagickFalse,arg1);
961 if (parse < 0)
962 CLIWandExceptArgBreak(OptionError,"UnrecognizedInterpolateMethod",
963 option,arg1);
964 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000965 break;
966 }
anthonyafa3dfc2012-03-03 11:31:30 +0000967 if (LocaleCompare("interword-spacing",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000968 {
anthony7bcfe7f2012-03-30 14:01:22 +0000969 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +0000970 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +0000971 (void) SetImageOption(_image_info,option+1, ArgOption(NULL));
972 _draw_info->interword_spacing=StringToDouble(ArgOption("0"),(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +0000973 break;
974 }
anthonyebb73a22012-03-22 14:25:52 +0000975 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +0000976 }
977 case 'k':
978 {
anthonyafa3dfc2012-03-03 11:31:30 +0000979 if (LocaleCompare("kerning",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000980 {
anthony7bcfe7f2012-03-30 14:01:22 +0000981 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +0000982 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +0000983 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
984 _draw_info->kerning=StringToDouble(ArgOption("0"),(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +0000985 break;
986 }
anthonyebb73a22012-03-22 14:25:52 +0000987 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +0000988 }
989 case 'l':
990 {
anthonyafa3dfc2012-03-03 11:31:30 +0000991 if (LocaleCompare("label",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000992 {
anthony72feaa62012-01-17 06:46:23 +0000993 /* only used for new images - not in SyncImageOptions() */
anthony92c93bd2012-03-19 14:02:47 +0000994 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +0000995 break;
996 }
anthony756cd0d2012-04-08 12:41:44 +0000997 if (LocaleCompare("limit",option+1) == 0)
998 {
999 MagickSizeType
1000 limit;
1001
1002 limit=MagickResourceInfinity;
1003 parse= ParseCommandOption(MagickResourceOptions,MagickFalse,arg1);
1004 if ( parse < 0 )
1005 CLIWandExceptArgBreak(OptionError,"UnrecognizedResourceType",
1006 option,arg1);
1007 if (LocaleCompare("unlimited",arg2) != 0)
1008 limit=(MagickSizeType) SiPrefixToDoubleInterval(arg2,100.0);
1009 (void) SetMagickResourceLimit((ResourceType)parse,limit);
1010 break;
1011 }
anthonyafa3dfc2012-03-03 11:31:30 +00001012 if (LocaleCompare("log",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001013 {
anthonyfe1aa782012-03-24 13:43:04 +00001014 if (IfSetOption) {
1015 if ((strchr(arg1,'%') == (char *) NULL))
1016 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony24aa8822012-03-11 00:56:06 +00001017 (void) SetLogFormat(arg1);
anthonyfe1aa782012-03-24 13:43:04 +00001018 }
anthony805a2d42011-09-25 08:25:12 +00001019 break;
1020 }
anthony975a8d72012-04-12 13:54:36 +00001021 if (LocaleCompare("lowlight-color",option+1) == 0)
1022 {
anthonyb1d483a2012-04-14 12:53:56 +00001023 /* FUTURE: this is only used by CompareImages() which is used
1024 only by the "compare" CLI program at this time. */
anthony975a8d72012-04-12 13:54:36 +00001025 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1026 break;
1027 }
anthonyafa3dfc2012-03-03 11:31:30 +00001028 if (LocaleCompare("loop",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001029 {
anthony72feaa62012-01-17 06:46:23 +00001030 /* SyncImageSettings() used to set per-image attribute. */
anthonyfe1aa782012-03-24 13:43:04 +00001031 arg1=ArgOption("0");
anthony7bcfe7f2012-03-30 14:01:22 +00001032 if (IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00001033 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1034 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +00001035 break;
1036 }
anthonyebb73a22012-03-22 14:25:52 +00001037 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001038 }
1039 case 'm':
1040 {
anthonyafa3dfc2012-03-03 11:31:30 +00001041 if (LocaleCompare("mattecolor",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001042 {
anthony72feaa62012-01-17 06:46:23 +00001043 /* SyncImageSettings() used to set per-image attribute. */
anthony92c93bd2012-03-19 14:02:47 +00001044 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony72feaa62012-01-17 06:46:23 +00001045 (void) QueryColorCompliance(ArgOption(MatteColor),AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +00001046 &_image_info->matte_color,_exception);
anthony805a2d42011-09-25 08:25:12 +00001047 break;
anthonycd358fc2012-04-16 13:59:03 +00001048 }
anthonyb1d483a2012-04-14 12:53:56 +00001049 if (LocaleCompare("metric",option+1) == 0)
1050 {
1051 /* FUTURE: this is only used by CompareImages() which is used
1052 only by the "compare" CLI program at this time. */
1053 parse=ParseCommandOption(MagickMetricOptions,MagickFalse,arg1);
1054 if ( parse < 0 )
1055 CLIWandExceptArgBreak(OptionError,"UnrecognizedMetricType",
1056 option,arg1);
1057 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthonycd358fc2012-04-16 13:59:03 +00001058 break;
anthony805a2d42011-09-25 08:25:12 +00001059 }
anthonyafa3dfc2012-03-03 11:31:30 +00001060 if (LocaleCompare("monitor",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001061 {
anthony92c93bd2012-03-19 14:02:47 +00001062 (void) SetImageInfoProgressMonitor(_image_info, IfSetOption?
anthony31f1bf72012-01-30 12:37:22 +00001063 MonitorProgress: (MagickProgressMonitor) NULL, (void *) NULL);
anthony805a2d42011-09-25 08:25:12 +00001064 break;
1065 }
anthonyafa3dfc2012-03-03 11:31:30 +00001066 if (LocaleCompare("monochrome",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001067 {
anthony24aa8822012-03-11 00:56:06 +00001068 /* Setting (used by some input coders!) -- why?
1069 Warning: This is also Special '-type' SimpleOperator
anthony72feaa62012-01-17 06:46:23 +00001070 */
anthony92c93bd2012-03-19 14:02:47 +00001071 _image_info->monochrome= ArgBoolean;
anthony805a2d42011-09-25 08:25:12 +00001072 break;
1073 }
anthonyebb73a22012-03-22 14:25:52 +00001074 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001075 }
1076 case 'o':
1077 {
anthonyafa3dfc2012-03-03 11:31:30 +00001078 if (LocaleCompare("orient",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001079 {
anthony72feaa62012-01-17 06:46:23 +00001080 /* Is not used when defining for new images.
anthonydcf510d2011-10-30 13:51:40 +00001081 This makes it more of a 'operation' than a setting
anthony72feaa62012-01-17 06:46:23 +00001082 FUTURE: make set meta-data operator instead.
1083 SyncImageSettings() used to set per-image attribute.
anthonydcf510d2011-10-30 13:51:40 +00001084 */
anthony7bc87992012-03-25 02:32:51 +00001085 parse=ParseCommandOption(MagickOrientationOptions,MagickFalse,
1086 ArgOption("undefined"));
1087 if (parse < 0)
1088 CLIWandExceptArgBreak(OptionError,"UnrecognizedImageOrientation",
1089 option,arg1);
1090 _image_info->orientation=(OrientationType)parse;
anthony92c93bd2012-03-19 14:02:47 +00001091 (void) SetImageOption(_image_info,option+1, ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +00001092 break;
1093 }
anthonyebb73a22012-03-22 14:25:52 +00001094 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001095 }
1096 case 'p':
1097 {
anthonyafa3dfc2012-03-03 11:31:30 +00001098 if (LocaleCompare("page",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001099 {
anthony7bc87992012-03-25 02:32:51 +00001100 /* Only used for new images and image generators.
anthony72feaa62012-01-17 06:46:23 +00001101 SyncImageSettings() used to set per-image attribute. ?????
1102 That last is WRONG!!!!
anthony7bc87992012-03-25 02:32:51 +00001103 FUTURE: adjust named 'page' sizes according density
anthony72feaa62012-01-17 06:46:23 +00001104 */
anthony805a2d42011-09-25 08:25:12 +00001105 char
1106 *canonical_page,
1107 page[MaxTextExtent];
1108
1109 const char
1110 *image_option;
1111
1112 MagickStatusType
1113 flags;
1114
1115 RectangleInfo
1116 geometry;
1117
anthonydcf510d2011-10-30 13:51:40 +00001118 if (!IfSetOption)
anthony805a2d42011-09-25 08:25:12 +00001119 {
anthony92c93bd2012-03-19 14:02:47 +00001120 (void) DeleteImageOption(_image_info,option+1);
1121 (void) CloneString(&_image_info->page,(char *) NULL);
anthony805a2d42011-09-25 08:25:12 +00001122 break;
1123 }
1124 (void) ResetMagickMemory(&geometry,0,sizeof(geometry));
anthony92c93bd2012-03-19 14:02:47 +00001125 image_option=GetImageOption(_image_info,"page");
anthony805a2d42011-09-25 08:25:12 +00001126 if (image_option != (const char *) NULL)
1127 flags=ParseAbsoluteGeometry(image_option,&geometry);
anthony24aa8822012-03-11 00:56:06 +00001128 canonical_page=GetPageGeometry(arg1);
anthony805a2d42011-09-25 08:25:12 +00001129 flags=ParseAbsoluteGeometry(canonical_page,&geometry);
1130 canonical_page=DestroyString(canonical_page);
1131 (void) FormatLocaleString(page,MaxTextExtent,"%lux%lu",
1132 (unsigned long) geometry.width,(unsigned long) geometry.height);
1133 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
1134 (void) FormatLocaleString(page,MaxTextExtent,"%lux%lu%+ld%+ld",
1135 (unsigned long) geometry.width,(unsigned long) geometry.height,
1136 (long) geometry.x,(long) geometry.y);
anthony92c93bd2012-03-19 14:02:47 +00001137 (void) SetImageOption(_image_info,option+1,page);
1138 (void) CloneString(&_image_info->page,page);
anthony805a2d42011-09-25 08:25:12 +00001139 break;
1140 }
anthonyafa3dfc2012-03-03 11:31:30 +00001141 if (LocaleCompare("ping",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001142 {
anthony92c93bd2012-03-19 14:02:47 +00001143 _image_info->ping = ArgBoolean;
anthony805a2d42011-09-25 08:25:12 +00001144 break;
1145 }
anthonyafa3dfc2012-03-03 11:31:30 +00001146 if (LocaleCompare("pointsize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001147 {
anthonyf42014d2012-03-25 09:53:06 +00001148 if (IfSetOption) {
anthony7bcfe7f2012-03-30 14:01:22 +00001149 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00001150 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1151 _image_info->pointsize =
1152 _draw_info->pointsize =
1153 StringToDouble(arg1,(char **) NULL);
1154 }
1155 else {
1156 _image_info->pointsize=0.0; /* unset pointsize */
1157 _draw_info->pointsize=12.0;
1158 }
anthony805a2d42011-09-25 08:25:12 +00001159 break;
1160 }
anthonyafa3dfc2012-03-03 11:31:30 +00001161 if (LocaleCompare("precision",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001162 {
anthonyf42014d2012-03-25 09:53:06 +00001163 arg1=ArgOption("-1");
anthony7bcfe7f2012-03-30 14:01:22 +00001164 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00001165 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1166 (void) SetMagickPrecision(StringToInteger(arg1));
anthony805a2d42011-09-25 08:25:12 +00001167 break;
1168 }
anthonydcf510d2011-10-30 13:51:40 +00001169 /* FUTURE: Only the 'preview' coder appears to use this
anthonya3ef4ed2012-03-17 06:52:53 +00001170 * DEPRECIATE the coder? Leaving only the 'preview' operator.
anthonyafa3dfc2012-03-03 11:31:30 +00001171 if (LocaleCompare("preview",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001172 {
anthony92c93bd2012-03-19 14:02:47 +00001173 _image_info->preview_type=UndefinedPreview;
anthonydcf510d2011-10-30 13:51:40 +00001174 if (IfSetOption)
anthony92c93bd2012-03-19 14:02:47 +00001175 _image_info->preview_type=(PreviewType) ParseCommandOption(
anthony24aa8822012-03-11 00:56:06 +00001176 MagickPreviewOptions,MagickFalse,arg1);
anthony805a2d42011-09-25 08:25:12 +00001177 break;
1178 }
anthonydcf510d2011-10-30 13:51:40 +00001179 */
anthonyebb73a22012-03-22 14:25:52 +00001180 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001181 }
1182 case 'q':
1183 {
anthonyafa3dfc2012-03-03 11:31:30 +00001184 if (LocaleCompare("quality",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001185 {
anthony7bcfe7f2012-03-30 14:01:22 +00001186 if (IfMagickFalse(IsGeometry(arg1)))
anthony7bc87992012-03-25 02:32:51 +00001187 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyf42014d2012-03-25 09:53:06 +00001188 _image_info->quality= IfSetOption ? StringToUnsignedLong(arg1)
1189 : UNDEFINED_COMPRESSION_QUALITY;
anthony92c93bd2012-03-19 14:02:47 +00001190 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +00001191 break;
1192 }
anthonyafa3dfc2012-03-03 11:31:30 +00001193 if (LocaleCompare("quantize",option+1) == 0)
anthonyafbaed72011-10-26 12:05:04 +00001194 {
anthony92c93bd2012-03-19 14:02:47 +00001195 /* Just a set direct in _quantize_info */
anthony7bc87992012-03-25 02:32:51 +00001196 arg1=ArgOption("undefined");
1197 parse=ParseCommandOption(MagickColorspaceOptions,MagickFalse,arg1);
1198 if (parse < 0)
1199 CLIWandExceptArgBreak(OptionError,"UnrecognizedColorspace",
1200 option,arg1);
1201 _quantize_info->colorspace=(ColorspaceType)parse;
anthonyafbaed72011-10-26 12:05:04 +00001202 break;
1203 }
anthonyafa3dfc2012-03-03 11:31:30 +00001204 if (LocaleCompare("quiet",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001205 {
anthonyf42014d2012-03-25 09:53:06 +00001206 /* FUTURE: if two -quiet is performed you can not do +quiet!
1207 This needs to be checked over thoughly.
1208 */
anthony805a2d42011-09-25 08:25:12 +00001209 static WarningHandler
1210 warning_handler = (WarningHandler) NULL;
anthony72feaa62012-01-17 06:46:23 +00001211
anthonyafbaed72011-10-26 12:05:04 +00001212 WarningHandler
1213 tmp = SetWarningHandler((WarningHandler) NULL);
anthony805a2d42011-09-25 08:25:12 +00001214
anthonyafbaed72011-10-26 12:05:04 +00001215 if ( tmp != (WarningHandler) NULL)
1216 warning_handler = tmp; /* remember the old handler */
1217 if (!IfSetOption) /* set the old handler */
1218 warning_handler=SetWarningHandler(warning_handler);
anthony805a2d42011-09-25 08:25:12 +00001219 break;
1220 }
anthonyebb73a22012-03-22 14:25:52 +00001221 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001222 }
1223 case 'r':
1224 {
anthonyafa3dfc2012-03-03 11:31:30 +00001225 if (LocaleCompare("red-primary",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001226 {
anthonydcf510d2011-10-30 13:51:40 +00001227 /* Image chromaticity X,Y NB: Y=X if Y not defined
1228 Used by many coders
anthony72feaa62012-01-17 06:46:23 +00001229 SyncImageSettings() used to set per-image attribute.
anthonydcf510d2011-10-30 13:51:40 +00001230 */
anthonyf42014d2012-03-25 09:53:06 +00001231 arg1=ArgOption("0.0");
anthony7bcfe7f2012-03-30 14:01:22 +00001232 if (IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00001233 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyf42014d2012-03-25 09:53:06 +00001234 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +00001235 break;
1236 }
cristyb0f7a182012-04-06 23:33:11 +00001237 if (LocaleCompare("regard-warnings",option+1) == 0)
anthonye5fcd362012-04-09 04:02:09 +00001238 /* FUTURE: to be replaced by a 'fatal-level' type setting */
cristyb0f7a182012-04-06 23:33:11 +00001239 break;
anthonyafa3dfc2012-03-03 11:31:30 +00001240 if (LocaleCompare("render",option+1) == 0)
anthonyafbaed72011-10-26 12:05:04 +00001241 {
anthony92c93bd2012-03-19 14:02:47 +00001242 /* _draw_info only setting */
1243 _draw_info->render= ArgBooleanNot;
anthonyafbaed72011-10-26 12:05:04 +00001244 break;
1245 }
anthony756cd0d2012-04-08 12:41:44 +00001246 if (LocaleCompare("respect-parenthesis",option+1) == 0)
1247 {
1248 /* link image and setting stacks - option is itself saved on stack! */
1249 (void) SetImageOption(_image_info,option+1,ArgBooleanString);
1250 break;
1251 }
anthonyebb73a22012-03-22 14:25:52 +00001252 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001253 }
1254 case 's':
1255 {
anthonyafa3dfc2012-03-03 11:31:30 +00001256 if (LocaleCompare("sampling-factor",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001257 {
anthonyafbaed72011-10-26 12:05:04 +00001258 /* FUTURE: should be converted to jpeg:sampling_factor */
anthony7bcfe7f2012-03-30 14:01:22 +00001259 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00001260 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001261 (void) CloneString(&_image_info->sampling_factor,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +00001262 break;
1263 }
anthonyafa3dfc2012-03-03 11:31:30 +00001264 if (LocaleCompare("scene",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001265 {
anthonyf42014d2012-03-25 09:53:06 +00001266 /* SyncImageSettings() used to set this as a per-image attribute.
anthony72feaa62012-01-17 06:46:23 +00001267 What ??? Why ????
1268 */
anthony7bcfe7f2012-03-30 14:01:22 +00001269 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00001270 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001271 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1272 _image_info->scene=StringToUnsignedLong(ArgOption("0"));
anthony805a2d42011-09-25 08:25:12 +00001273 break;
1274 }
anthonyafa3dfc2012-03-03 11:31:30 +00001275 if (LocaleCompare("seed",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001276 {
anthony7bcfe7f2012-03-30 14:01:22 +00001277 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00001278 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
cristyd7761bb2012-04-14 01:42:05 +00001279 SetRandomSecretKey(
anthony24aa8822012-03-11 00:56:06 +00001280 IfSetOption ? (size_t) StringToUnsignedLong(arg1)
anthonyafbaed72011-10-26 12:05:04 +00001281 : (size_t) time((time_t *) NULL) );
anthony805a2d42011-09-25 08:25:12 +00001282 break;
1283 }
anthonyafa3dfc2012-03-03 11:31:30 +00001284 if (LocaleCompare("size",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001285 {
anthony92c93bd2012-03-19 14:02:47 +00001286 /* FUTURE: string in _image_info -- convert to Option ???
anthonyafbaed72011-10-26 12:05:04 +00001287 Look at the special handling for "size" in SetImageOption()
anthony74b1cfc2011-10-06 12:44:16 +00001288 */
anthony92c93bd2012-03-19 14:02:47 +00001289 (void) CloneString(&_image_info->size,ArgOption(NULL));
anthonyafbaed72011-10-26 12:05:04 +00001290 break;
1291 }
anthonyafa3dfc2012-03-03 11:31:30 +00001292 if (LocaleCompare("stretch",option+1) == 0)
anthonyafbaed72011-10-26 12:05:04 +00001293 {
anthonyf42014d2012-03-25 09:53:06 +00001294 arg1=ArgOption("undefined");
1295 parse = ParseCommandOption(MagickStretchOptions,MagickFalse,arg1);
1296 if (parse < 0)
1297 CLIWandExceptArgBreak(OptionError,"UnrecognizedStretchType",
1298 option,arg1);
1299 _draw_info->stretch=(StretchType) parse;
anthony805a2d42011-09-25 08:25:12 +00001300 break;
1301 }
anthonyafa3dfc2012-03-03 11:31:30 +00001302 if (LocaleCompare("stroke",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001303 {
anthonyafbaed72011-10-26 12:05:04 +00001304 /* set stroke color OR stroke-pattern
anthonyfd706f92012-01-19 04:22:02 +00001305 UPDATE: ensure stroke color is not destroyed is a pattern
1306 is given. Just in case the color is also used for other purposes.
anthonyafbaed72011-10-26 12:05:04 +00001307 */
anthony72feaa62012-01-17 06:46:23 +00001308 MagickBooleanType
1309 status;
anthonyafbaed72011-10-26 12:05:04 +00001310
1311 ExceptionInfo
1312 *sans;
1313
anthonyfd706f92012-01-19 04:22:02 +00001314 PixelInfo
1315 color;
1316
anthony2a0ec8c2012-03-24 04:35:56 +00001317 arg1 = ArgOption("none"); /* +fill turns it off! */
1318 (void) SetImageOption(_image_info,option+1,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001319 if (_draw_info->stroke_pattern != (Image *) NULL)
1320 _draw_info->stroke_pattern=DestroyImage(_draw_info->stroke_pattern);
anthony72feaa62012-01-17 06:46:23 +00001321
1322 /* is it a color or a image? -- ignore exceptions */
anthonyafbaed72011-10-26 12:05:04 +00001323 sans=AcquireExceptionInfo();
anthony2a0ec8c2012-03-24 04:35:56 +00001324 status=QueryColorCompliance(arg1,AllCompliance,&color,sans);
anthonyafbaed72011-10-26 12:05:04 +00001325 sans=DestroyExceptionInfo(sans);
anthonyfd706f92012-01-19 04:22:02 +00001326
anthony7bcfe7f2012-03-30 14:01:22 +00001327 if (IfMagickFalse(status))
anthony2a0ec8c2012-03-24 04:35:56 +00001328 _draw_info->stroke_pattern=GetImageCache(_image_info,arg1,_exception);
anthonyfd706f92012-01-19 04:22:02 +00001329 else
anthony92c93bd2012-03-19 14:02:47 +00001330 _draw_info->stroke=color;
anthony805a2d42011-09-25 08:25:12 +00001331 break;
1332 }
anthonyafa3dfc2012-03-03 11:31:30 +00001333 if (LocaleCompare("strokewidth",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001334 {
anthony7bcfe7f2012-03-30 14:01:22 +00001335 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00001336 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001337 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1338 _draw_info->stroke_width=StringToDouble(ArgOption("1.0"),
anthony72feaa62012-01-17 06:46:23 +00001339 (char **) NULL);
anthonyafbaed72011-10-26 12:05:04 +00001340 break;
1341 }
anthonyafa3dfc2012-03-03 11:31:30 +00001342 if (LocaleCompare("style",option+1) == 0)
anthonyafbaed72011-10-26 12:05:04 +00001343 {
anthonyf42014d2012-03-25 09:53:06 +00001344 arg1=ArgOption("undefined");
1345 parse = ParseCommandOption(MagickStyleOptions,MagickFalse,arg1);
1346 if (parse < 0)
1347 CLIWandExceptArgBreak(OptionError,"UnrecognizedStyleType",
1348 option,arg1);
1349 _draw_info->style=(StyleType) parse;
anthony805a2d42011-09-25 08:25:12 +00001350 break;
1351 }
anthonycd358fc2012-04-16 13:59:03 +00001352#if 0
anthonyb1d483a2012-04-14 12:53:56 +00001353 if (LocaleCompare("subimage-search",option+1) == 0)
1354 {
1355 /* FUTURE: this is only used by CompareImages() which is used
1356 only by the "compare" CLI program at this time. */
1357 (void) SetImageOption(_image_info,option+1,ArgBooleanString);
1358 break;
1359 }
anthonycd358fc2012-04-16 13:59:03 +00001360#endif
anthonyafa3dfc2012-03-03 11:31:30 +00001361 if (LocaleCompare("synchronize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001362 {
anthonyf42014d2012-03-25 09:53:06 +00001363 /* FUTURE: syncronize to storage - but what does that mean? */
anthony92c93bd2012-03-19 14:02:47 +00001364 _image_info->synchronize = ArgBoolean;
anthony805a2d42011-09-25 08:25:12 +00001365 break;
1366 }
anthonyebb73a22012-03-22 14:25:52 +00001367 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001368 }
1369 case 't':
1370 {
anthonyafa3dfc2012-03-03 11:31:30 +00001371 if (LocaleCompare("taint",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001372 {
anthony72feaa62012-01-17 06:46:23 +00001373 /* SyncImageSettings() used to set per-image attribute. */
anthony92c93bd2012-03-19 14:02:47 +00001374 (void) SetImageOption(_image_info,option+1,ArgBooleanString);
anthony805a2d42011-09-25 08:25:12 +00001375 break;
1376 }
anthonyafa3dfc2012-03-03 11:31:30 +00001377 if (LocaleCompare("texture",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001378 {
anthony52bef752012-03-27 13:54:47 +00001379 /* FUTURE: move _image_info string to option splay-tree
1380 Other than "montage" what uses "texture" ????
1381 */
anthony92c93bd2012-03-19 14:02:47 +00001382 (void) CloneString(&_image_info->texture,ArgOption(NULL));
anthonyafbaed72011-10-26 12:05:04 +00001383 break;
1384 }
anthonyafa3dfc2012-03-03 11:31:30 +00001385 if (LocaleCompare("tile",option+1) == 0)
anthonyafbaed72011-10-26 12:05:04 +00001386 {
anthony92c93bd2012-03-19 14:02:47 +00001387 _draw_info->fill_pattern=IfSetOption
1388 ?GetImageCache(_image_info,arg1,_exception)
1389 :DestroyImage(_draw_info->fill_pattern);
anthony805a2d42011-09-25 08:25:12 +00001390 break;
1391 }
anthonyafa3dfc2012-03-03 11:31:30 +00001392 if (LocaleCompare("tile-offset",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001393 {
anthony72feaa62012-01-17 06:46:23 +00001394 /* SyncImageSettings() used to set per-image attribute. ??? */
anthony52bef752012-03-27 13:54:47 +00001395 arg1=ArgOption("0");
anthony7bcfe7f2012-03-30 14:01:22 +00001396 if (IfMagickFalse(IsGeometry(arg1)))
anthony52bef752012-03-27 13:54:47 +00001397 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1398 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +00001399 break;
1400 }
anthonyafa3dfc2012-03-03 11:31:30 +00001401 if (LocaleCompare("transparent-color",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001402 {
anthony92c93bd2012-03-19 14:02:47 +00001403 /* FUTURE: both _image_info attribute & ImageOption in use!
1404 _image_info only used for generating new images.
anthony72feaa62012-01-17 06:46:23 +00001405 SyncImageSettings() used to set per-image attribute.
1406
anthonyafbaed72011-10-26 12:05:04 +00001407 Note that +transparent-color, means fall-back to image
1408 attribute so ImageOption is deleted, not set to a default.
1409 */
anthony7bcfe7f2012-03-30 14:01:22 +00001410 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthony52bef752012-03-27 13:54:47 +00001411 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001412 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony72feaa62012-01-17 06:46:23 +00001413 (void) QueryColorCompliance(ArgOption("none"),AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +00001414 &_image_info->transparent_color,_exception);
anthony805a2d42011-09-25 08:25:12 +00001415 break;
1416 }
anthonyafa3dfc2012-03-03 11:31:30 +00001417 if (LocaleCompare("treedepth",option+1) == 0)
anthony31f1bf72012-01-30 12:37:22 +00001418 {
anthony92c93bd2012-03-19 14:02:47 +00001419 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1420 _quantize_info->tree_depth=StringToUnsignedLong(ArgOption("0"));
anthony31f1bf72012-01-30 12:37:22 +00001421 break;
1422 }
anthonyafa3dfc2012-03-03 11:31:30 +00001423 if (LocaleCompare("type",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001424 {
anthony72feaa62012-01-17 06:46:23 +00001425 /* SyncImageSettings() used to set per-image attribute. */
anthony52bef752012-03-27 13:54:47 +00001426 parse=ParseCommandOption(MagickTypeOptions,MagickFalse,
1427 ArgOption("undefined"));
1428 if (parse < 0)
1429 CLIWandExceptArgBreak(OptionError,"UnrecognizedImageType",
1430 option,arg1);
1431 _image_info->type=(ImageType) parse;
anthony92c93bd2012-03-19 14:02:47 +00001432 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +00001433 break;
1434 }
anthonyebb73a22012-03-22 14:25:52 +00001435 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001436 }
1437 case 'u':
1438 {
anthonyafa3dfc2012-03-03 11:31:30 +00001439 if (LocaleCompare("undercolor",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001440 {
anthony92c93bd2012-03-19 14:02:47 +00001441 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony72feaa62012-01-17 06:46:23 +00001442 (void) QueryColorCompliance(ArgOption("none"),AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +00001443 &_draw_info->undercolor,_exception);
anthony805a2d42011-09-25 08:25:12 +00001444 break;
1445 }
anthonyafa3dfc2012-03-03 11:31:30 +00001446 if (LocaleCompare("units",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001447 {
anthony72feaa62012-01-17 06:46:23 +00001448 /* SyncImageSettings() used to set per-image attribute.
anthony92c93bd2012-03-19 14:02:47 +00001449 Should this effect _draw_info X and Y resolution?
anthony72feaa62012-01-17 06:46:23 +00001450 FUTURE: this probably should be part of the density setting
1451 */
anthony52bef752012-03-27 13:54:47 +00001452 parse=ParseCommandOption(MagickResolutionOptions,MagickFalse,
1453 ArgOption("undefined"));
1454 if (parse < 0)
1455 CLIWandExceptArgBreak(OptionError,"UnrecognizedUnitsType",
1456 option,arg1);
1457 _image_info->units=(ResolutionType) parse;
anthony92c93bd2012-03-19 14:02:47 +00001458 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +00001459 break;
1460 }
anthonyebb73a22012-03-22 14:25:52 +00001461 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001462 }
1463 case 'v':
1464 {
anthonyafa3dfc2012-03-03 11:31:30 +00001465 if (LocaleCompare("verbose",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001466 {
anthony24aa8822012-03-11 00:56:06 +00001467 /* FUTURE: Remember all options become image artifacts
anthony92c93bd2012-03-19 14:02:47 +00001468 _image_info->verbose is only used by coders.
anthonyab3a50c2011-10-27 11:48:57 +00001469 */
anthony92c93bd2012-03-19 14:02:47 +00001470 (void) SetImageOption(_image_info,option+1,ArgBooleanString);
1471 _image_info->verbose= ArgBoolean;
1472 _image_info->ping=MagickFalse; /* verbose can't be a ping */
anthony805a2d42011-09-25 08:25:12 +00001473 break;
1474 }
anthonyafa3dfc2012-03-03 11:31:30 +00001475 if (LocaleCompare("view",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001476 {
anthony92c93bd2012-03-19 14:02:47 +00001477 /* FUTURE: Convert from _image_info to ImageOption
anthonyab3a50c2011-10-27 11:48:57 +00001478 Only used by coder FPX
anthony52bef752012-03-27 13:54:47 +00001479 And it only tests existance, not its content!
anthonyab3a50c2011-10-27 11:48:57 +00001480 */
anthony92c93bd2012-03-19 14:02:47 +00001481 (void) CloneString(&_image_info->view,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +00001482 break;
1483 }
anthonyafa3dfc2012-03-03 11:31:30 +00001484 if (LocaleCompare("virtual-pixel",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001485 {
anthonyfd706f92012-01-19 04:22:02 +00001486 /* SyncImageSettings() used to set per-image attribute.
1487 This is VERY deep in the image caching structure.
1488 */
anthony52bef752012-03-27 13:54:47 +00001489 parse=ParseCommandOption(MagickVirtualPixelOptions,MagickFalse,
1490 ArgOption("undefined"));
1491 if (parse < 0)
1492 CLIWandExceptArgBreak(OptionError,"UnrecognizedVirtualPixelMethod",
1493 option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001494 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +00001495 break;
1496 }
anthonyebb73a22012-03-22 14:25:52 +00001497 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001498 }
1499 case 'w':
1500 {
anthonyafa3dfc2012-03-03 11:31:30 +00001501 if (LocaleCompare("weight",option+1) == 0)
anthonyab3a50c2011-10-27 11:48:57 +00001502 {
anthony72feaa62012-01-17 06:46:23 +00001503 /* Just what does using a font 'weight' do ???
anthonydcf510d2011-10-30 13:51:40 +00001504 There is no "-list weight" output (reference manual says there is)
anthonyab3a50c2011-10-27 11:48:57 +00001505 */
anthony52bef752012-03-27 13:54:47 +00001506 arg1=ArgOption("all");
anthony92c93bd2012-03-19 14:02:47 +00001507 _draw_info->weight=StringToUnsignedLong(arg1);
anthony24aa8822012-03-11 00:56:06 +00001508 if (LocaleCompare(arg1,"all") == 0)
anthony92c93bd2012-03-19 14:02:47 +00001509 _draw_info->weight=0;
anthony24aa8822012-03-11 00:56:06 +00001510 if (LocaleCompare(arg1,"bold") == 0)
anthony92c93bd2012-03-19 14:02:47 +00001511 _draw_info->weight=700;
anthony24aa8822012-03-11 00:56:06 +00001512 if (LocaleCompare(arg1,"bolder") == 0)
anthony92c93bd2012-03-19 14:02:47 +00001513 if (_draw_info->weight <= 800)
1514 _draw_info->weight+=100;
anthony24aa8822012-03-11 00:56:06 +00001515 if (LocaleCompare(arg1,"lighter") == 0)
anthony92c93bd2012-03-19 14:02:47 +00001516 if (_draw_info->weight >= 100)
1517 _draw_info->weight-=100;
anthony24aa8822012-03-11 00:56:06 +00001518 if (LocaleCompare(arg1,"normal") == 0)
anthony92c93bd2012-03-19 14:02:47 +00001519 _draw_info->weight=400;
anthonyab3a50c2011-10-27 11:48:57 +00001520 break;
1521 }
anthonyafa3dfc2012-03-03 11:31:30 +00001522 if (LocaleCompare("white-point",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001523 {
anthony72feaa62012-01-17 06:46:23 +00001524 /* Used as a image chromaticity setting
1525 SyncImageSettings() used to set per-image attribute.
1526 */
anthony52bef752012-03-27 13:54:47 +00001527 arg1=ArgOption("0.0");
anthony7bcfe7f2012-03-30 14:01:22 +00001528 if (IfMagickFalse(IsGeometry(arg1)))
anthony52bef752012-03-27 13:54:47 +00001529 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1530 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +00001531 break;
1532 }
anthonyebb73a22012-03-22 14:25:52 +00001533 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001534 }
1535 default:
anthonyebb73a22012-03-22 14:25:52 +00001536 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001537 }
anthony24aa8822012-03-11 00:56:06 +00001538
anthony92c93bd2012-03-19 14:02:47 +00001539#undef _image_info
1540#undef _exception
1541#undef _draw_info
1542#undef _quantize_info
anthonyfd706f92012-01-19 04:22:02 +00001543#undef IfSetOption
anthonyfd706f92012-01-19 04:22:02 +00001544#undef ArgBoolean
anthony24aa8822012-03-11 00:56:06 +00001545#undef ArgBooleanNot
1546#undef ArgBooleanString
1547#undef ArgOption
anthonyfd706f92012-01-19 04:22:02 +00001548
anthony31f1bf72012-01-30 12:37:22 +00001549 return;
anthony805a2d42011-09-25 08:25:12 +00001550}
1551
1552/*
1553%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1554% %
1555% %
1556% %
anthony43f425d2012-02-26 12:58:58 +00001557+ C L I S i m p l e O p e r a t o r I m a g e s %
anthony805a2d42011-09-25 08:25:12 +00001558% %
1559% %
1560% %
1561%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1562%
anthony31f1bf72012-01-30 12:37:22 +00001563% WandSimpleOperatorImages() applys one simple image operation given to all
anthony43f425d2012-02-26 12:58:58 +00001564% the images in the CLI wand, with the settings that was previously saved in
1565% the CLI wand.
anthonydcf510d2011-10-30 13:51:40 +00001566%
1567% It is assumed that any per-image settings are up-to-date with respect to
anthony43f425d2012-02-26 12:58:58 +00001568% extra settings that were already saved in the wand.
anthony805a2d42011-09-25 08:25:12 +00001569%
anthonyd1447672012-01-19 05:33:53 +00001570% The format of the WandSimpleOperatorImage method is:
anthony805a2d42011-09-25 08:25:12 +00001571%
anthony43f425d2012-02-26 12:58:58 +00001572% void CLISimpleOperatorImages(MagickCLI *cli_wand,
anthonyafa3dfc2012-03-03 11:31:30 +00001573% const char *option, const char *arg1, const char *arg2)
anthony805a2d42011-09-25 08:25:12 +00001574%
1575% A description of each parameter follows:
1576%
anthony43f425d2012-02-26 12:58:58 +00001577% o cli_wand: structure holding settings and images to be operated on
anthony805a2d42011-09-25 08:25:12 +00001578%
anthonyfd706f92012-01-19 04:22:02 +00001579% o option: The option string for the operation
anthonydcf510d2011-10-30 13:51:40 +00001580%
anthonyfd706f92012-01-19 04:22:02 +00001581% o arg1, arg2: optional argument strings to the operation
anthony805a2d42011-09-25 08:25:12 +00001582%
anthony805a2d42011-09-25 08:25:12 +00001583*/
anthony31f1bf72012-01-30 12:37:22 +00001584
1585/*
1586 Internal subrountine to apply one simple image operation to the current
anthony43f425d2012-02-26 12:58:58 +00001587 image pointed to by the CLI wand.
anthony31f1bf72012-01-30 12:37:22 +00001588
1589 The image in the list may be modified in three different ways...
1590 * directly modified (EG: -negate, -gamma, -level, -annotate, -draw),
1591 * replaced by a new image (EG: -spread, -resize, -rotate, -morphology)
1592 * one image replace by a list of images (-separate and -crop only!)
1593
anthonyafa3dfc2012-03-03 11:31:30 +00001594 In each case the result replaces the single original image in the list, as
1595 well as the pointer to the modified image (last image added if replaced by a
1596 list of images) is returned.
anthony31f1bf72012-01-30 12:37:22 +00001597
1598 As the image pointed to may be replaced, the first image in the list may
1599 also change. GetFirstImageInList() should be used by caller if they wish
1600 return the Image pointer to the first image in list.
1601*/
anthony43f425d2012-02-26 12:58:58 +00001602static void CLISimpleOperatorImage(MagickCLI *cli_wand,
anthony964d28e2012-05-17 23:39:46 +00001603 const char *option, const char *arg1n, const char *arg2n)
anthony805a2d42011-09-25 08:25:12 +00001604{
1605 Image *
1606 new_image;
1607
anthony805a2d42011-09-25 08:25:12 +00001608 GeometryInfo
1609 geometry_info;
1610
1611 RectangleInfo
1612 geometry;
1613
1614 MagickStatusType
anthony805a2d42011-09-25 08:25:12 +00001615 flags;
1616
anthony92c93bd2012-03-19 14:02:47 +00001617 ssize_t
anthony2a0ec8c2012-03-24 04:35:56 +00001618 parse;
anthony92c93bd2012-03-19 14:02:47 +00001619
anthony964d28e2012-05-17 23:39:46 +00001620 const char /* For percent escape interpretImageProperties() */
1621 *arg1,
1622 *arg2;
1623
anthony2e4501b2012-03-30 04:41:54 +00001624#define _image_info (cli_wand->wand.image_info)
1625#define _image (cli_wand->wand.images)
1626#define _exception (cli_wand->wand.exception)
1627#define _draw_info (cli_wand->draw_info)
1628#define _quantize_info (cli_wand->quantize_info)
anthony964d28e2012-05-17 23:39:46 +00001629#define _process_flags (cli_wand->process_flags)
1630#define _option_type ((CommandOptionFlags) cli_wand->command->flags)
anthonyafa3dfc2012-03-03 11:31:30 +00001631#define IfNormalOp (*option=='-')
1632#define IfPlusOp (*option!='-')
anthony7bcfe7f2012-03-30 14:01:22 +00001633#define normal_op IsMagickTrue(IfNormalOp)
1634#define plus_alt_op IsMagickFalse(IfNormalOp)
anthonyfd706f92012-01-19 04:22:02 +00001635
anthony43f425d2012-02-26 12:58:58 +00001636 assert(cli_wand != (MagickCLI *) NULL);
1637 assert(cli_wand->signature == WandSignature);
1638 assert(cli_wand->wand.signature == WandSignature);
anthony5330ae02012-03-20 14:17:01 +00001639 assert(_image != (Image *) NULL); /* an image must be present */
anthony7bcfe7f2012-03-30 14:01:22 +00001640 if (IfMagickTrue(cli_wand->wand.debug))
anthony43f425d2012-02-26 12:58:58 +00001641 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
anthonydcf510d2011-10-30 13:51:40 +00001642
anthony964d28e2012-05-17 23:39:46 +00001643 /* Interpret Percent Escapes in Arguments - using first image */
1644 arg1 = arg1n,
1645 arg2 = arg2n;
1646 if ( (((_process_flags & ProcessInterpretProperities) != 0 )
1647 || ((_option_type & AlwaysInterpretArgsFlag) != 0)
1648 ) && ((_option_type & NeverInterpretArgsFlag) == 0) ) {
1649 /* Interpret Percent escapes in argument 1 */
1650 if (arg1n != (char *) NULL) {
1651 arg1=InterpretImageProperties(_image_info,_image,arg1n,_exception);
1652 if (arg1 == (char *) NULL) {
1653 CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
1654 arg1=arg1n; /* use the given argument as is */
1655 }
1656 }
1657 if (arg2n != (char *) NULL) {
1658 arg2=InterpretImageProperties(_image_info,_image,arg2n,_exception);
1659 if (arg2 == (char *) NULL) {
1660 CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
1661 arg2=arg2n; /* use the given argument as is */
1662 }
1663 }
1664 }
1665#undef _option_type
1666
1667#if 0
1668 (void) FormatLocaleFile(stderr,
1669 "CLISimpleOperatorImage: \"%s\" \"%s\" \"%s\"\n",option,arg1,arg2);
1670#endif
anthony805a2d42011-09-25 08:25:12 +00001671
anthony5330ae02012-03-20 14:17:01 +00001672 new_image = (Image *)NULL; /* the replacement image, if not null at end */
anthony964d28e2012-05-17 23:39:46 +00001673 SetGeometryInfo(&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00001674
anthonyafa3dfc2012-03-03 11:31:30 +00001675 switch (*(option+1))
anthony805a2d42011-09-25 08:25:12 +00001676 {
1677 case 'a':
1678 {
anthonyafa3dfc2012-03-03 11:31:30 +00001679 if (LocaleCompare("adaptive-blur",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001680 {
anthonyfd706f92012-01-19 04:22:02 +00001681 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00001682 if ((flags & (RhoValue|SigmaValue)) == 0)
1683 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00001684 if ((flags & SigmaValue) == 0)
1685 geometry_info.sigma=1.0;
anthony92c93bd2012-03-19 14:02:47 +00001686 new_image=AdaptiveBlurImage(_image,geometry_info.rho,
cristyaa2c16c2012-03-25 22:21:35 +00001687 geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00001688 break;
1689 }
anthonyafa3dfc2012-03-03 11:31:30 +00001690 if (LocaleCompare("adaptive-resize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001691 {
anthonyfe1aa782012-03-24 13:43:04 +00001692 /* FUTURE: Roll into a resize special operator */
anthony7bcfe7f2012-03-30 14:01:22 +00001693 if (IfMagickFalse(IsGeometry(arg1)))
anthony92c93bd2012-03-19 14:02:47 +00001694 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1695 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
1696 new_image=AdaptiveResizeImage(_image,geometry.width,geometry.height,
cristyaa2c16c2012-03-25 22:21:35 +00001697 _exception);
anthony805a2d42011-09-25 08:25:12 +00001698 break;
1699 }
anthonyafa3dfc2012-03-03 11:31:30 +00001700 if (LocaleCompare("adaptive-sharpen",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001701 {
anthonyfd706f92012-01-19 04:22:02 +00001702 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00001703 if ((flags & (RhoValue|SigmaValue)) == 0)
1704 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00001705 if ((flags & SigmaValue) == 0)
1706 geometry_info.sigma=1.0;
anthony92c93bd2012-03-19 14:02:47 +00001707 new_image=AdaptiveSharpenImage(_image,geometry_info.rho,
cristyaa2c16c2012-03-25 22:21:35 +00001708 geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00001709 break;
1710 }
anthonyafa3dfc2012-03-03 11:31:30 +00001711 if (LocaleCompare("alpha",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001712 {
anthony2a0ec8c2012-03-24 04:35:56 +00001713 parse=ParseCommandOption(MagickAlphaOptions,MagickFalse,arg1);
1714 if (parse < 0)
anthony92c93bd2012-03-19 14:02:47 +00001715 CLIWandExceptArgBreak(OptionError,"UnrecognizedAlphaChannelType",
1716 option,arg1);
anthony2a0ec8c2012-03-24 04:35:56 +00001717 (void) SetImageAlphaChannel(_image,(AlphaChannelType)parse,
1718 _exception);
anthony805a2d42011-09-25 08:25:12 +00001719 break;
1720 }
anthonyafa3dfc2012-03-03 11:31:30 +00001721 if (LocaleCompare("annotate",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001722 {
1723 char
anthony805a2d42011-09-25 08:25:12 +00001724 geometry[MaxTextExtent];
1725
anthony805a2d42011-09-25 08:25:12 +00001726 SetGeometryInfo(&geometry_info);
anthonyfd706f92012-01-19 04:22:02 +00001727 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00001728 if ((flags & RhoValue) == 0)
1729 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00001730 if ((flags & SigmaValue) == 0)
1731 geometry_info.sigma=geometry_info.rho;
anthony964d28e2012-05-17 23:39:46 +00001732 (void) CloneString(&_draw_info->text,arg2);
anthony805a2d42011-09-25 08:25:12 +00001733 (void) FormatLocaleString(geometry,MaxTextExtent,"%+f%+f",
1734 geometry_info.xi,geometry_info.psi);
anthony92c93bd2012-03-19 14:02:47 +00001735 (void) CloneString(&_draw_info->geometry,geometry);
1736 _draw_info->affine.sx=cos(DegreesToRadians(
anthony805a2d42011-09-25 08:25:12 +00001737 fmod(geometry_info.rho,360.0)));
anthony92c93bd2012-03-19 14:02:47 +00001738 _draw_info->affine.rx=sin(DegreesToRadians(
anthony805a2d42011-09-25 08:25:12 +00001739 fmod(geometry_info.rho,360.0)));
anthony92c93bd2012-03-19 14:02:47 +00001740 _draw_info->affine.ry=(-sin(DegreesToRadians(
anthony805a2d42011-09-25 08:25:12 +00001741 fmod(geometry_info.sigma,360.0))));
anthony92c93bd2012-03-19 14:02:47 +00001742 _draw_info->affine.sy=cos(DegreesToRadians(
anthony805a2d42011-09-25 08:25:12 +00001743 fmod(geometry_info.sigma,360.0)));
anthony92c93bd2012-03-19 14:02:47 +00001744 (void) AnnotateImage(_image,_draw_info,_exception);
1745 GetAffineMatrix(&_draw_info->affine);
anthony805a2d42011-09-25 08:25:12 +00001746 break;
1747 }
anthonyafa3dfc2012-03-03 11:31:30 +00001748 if (LocaleCompare("auto-gamma",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001749 {
anthony92c93bd2012-03-19 14:02:47 +00001750 (void) AutoGammaImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00001751 break;
1752 }
anthonyafa3dfc2012-03-03 11:31:30 +00001753 if (LocaleCompare("auto-level",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001754 {
anthony92c93bd2012-03-19 14:02:47 +00001755 (void) AutoLevelImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00001756 break;
1757 }
anthonyafa3dfc2012-03-03 11:31:30 +00001758 if (LocaleCompare("auto-orient",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001759 {
anthony5330ae02012-03-20 14:17:01 +00001760 /* This should probably be a MagickCore function */
anthony92c93bd2012-03-19 14:02:47 +00001761 switch (_image->orientation)
anthony805a2d42011-09-25 08:25:12 +00001762 {
1763 case TopRightOrientation:
1764 {
anthony92c93bd2012-03-19 14:02:47 +00001765 new_image=FlopImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00001766 break;
1767 }
1768 case BottomRightOrientation:
1769 {
anthony92c93bd2012-03-19 14:02:47 +00001770 new_image=RotateImage(_image,180.0,_exception);
anthony805a2d42011-09-25 08:25:12 +00001771 break;
1772 }
1773 case BottomLeftOrientation:
1774 {
anthony92c93bd2012-03-19 14:02:47 +00001775 new_image=FlipImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00001776 break;
1777 }
1778 case LeftTopOrientation:
1779 {
anthony92c93bd2012-03-19 14:02:47 +00001780 new_image=TransposeImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00001781 break;
1782 }
1783 case RightTopOrientation:
1784 {
anthony92c93bd2012-03-19 14:02:47 +00001785 new_image=RotateImage(_image,90.0,_exception);
anthony805a2d42011-09-25 08:25:12 +00001786 break;
1787 }
1788 case RightBottomOrientation:
1789 {
anthony92c93bd2012-03-19 14:02:47 +00001790 new_image=TransverseImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00001791 break;
1792 }
1793 case LeftBottomOrientation:
1794 {
anthony92c93bd2012-03-19 14:02:47 +00001795 new_image=RotateImage(_image,270.0,_exception);
anthony805a2d42011-09-25 08:25:12 +00001796 break;
1797 }
1798 default:
1799 break;
1800 }
1801 if (new_image != (Image *) NULL)
1802 new_image->orientation=TopLeftOrientation;
1803 break;
1804 }
anthonyebb73a22012-03-22 14:25:52 +00001805 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001806 }
1807 case 'b':
1808 {
anthonyafa3dfc2012-03-03 11:31:30 +00001809 if (LocaleCompare("black-threshold",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001810 {
anthony7bcfe7f2012-03-30 14:01:22 +00001811 if (IfMagickFalse(IsGeometry(arg1)))
anthony5330ae02012-03-20 14:17:01 +00001812 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001813 (void) BlackThresholdImage(_image,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00001814 break;
1815 }
anthonyafa3dfc2012-03-03 11:31:30 +00001816 if (LocaleCompare("blue-shift",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001817 {
anthony805a2d42011-09-25 08:25:12 +00001818 geometry_info.rho=1.5;
anthony5330ae02012-03-20 14:17:01 +00001819 if (IfNormalOp) {
anthonyfd706f92012-01-19 04:22:02 +00001820 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00001821 if ((flags & RhoValue) == 0)
1822 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony5330ae02012-03-20 14:17:01 +00001823 }
anthony92c93bd2012-03-19 14:02:47 +00001824 new_image=BlueShiftImage(_image,geometry_info.rho,_exception);
anthony805a2d42011-09-25 08:25:12 +00001825 break;
1826 }
anthonyafa3dfc2012-03-03 11:31:30 +00001827 if (LocaleCompare("blur",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001828 {
anthonyfd706f92012-01-19 04:22:02 +00001829 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00001830 if ((flags & (RhoValue|SigmaValue)) == 0)
1831 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00001832 if ((flags & SigmaValue) == 0)
1833 geometry_info.sigma=1.0;
cristyaa2c16c2012-03-25 22:21:35 +00001834 new_image=BlurImage(_image,geometry_info.rho,geometry_info.sigma,
1835 _exception);
anthony805a2d42011-09-25 08:25:12 +00001836 break;
1837 }
anthonyafa3dfc2012-03-03 11:31:30 +00001838 if (LocaleCompare("border",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001839 {
anthony31f1bf72012-01-30 12:37:22 +00001840 CompositeOperator
anthony5f867ae2011-10-09 10:28:34 +00001841 compose;
1842
1843 const char*
anthony5f867ae2011-10-09 10:28:34 +00001844 value;
1845
anthony22de2722012-04-19 14:43:00 +00001846 flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
1847 if ((flags & RhoValue) == 0)
anthony5330ae02012-03-20 14:17:01 +00001848 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony22de2722012-04-19 14:43:00 +00001849 if ((flags & SigmaValue) == 0)
1850 geometry.height=geometry.width;
anthony5330ae02012-03-20 14:17:01 +00001851
anthony92c93bd2012-03-19 14:02:47 +00001852 value=GetImageOption(_image_info,"compose");
anthony5f867ae2011-10-09 10:28:34 +00001853 if (value != (const char *) NULL)
1854 compose=(CompositeOperator) ParseCommandOption(
1855 MagickComposeOptions,MagickFalse,value);
1856 else
anthony92c93bd2012-03-19 14:02:47 +00001857 compose=OverCompositeOp; /* use Over not _image->compose */
anthony5f867ae2011-10-09 10:28:34 +00001858
anthony92c93bd2012-03-19 14:02:47 +00001859 new_image=BorderImage(_image,&geometry,compose,_exception);
anthony805a2d42011-09-25 08:25:12 +00001860 break;
1861 }
anthonyafa3dfc2012-03-03 11:31:30 +00001862 if (LocaleCompare("brightness-contrast",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001863 {
1864 double
1865 brightness,
1866 contrast;
1867
1868 GeometryInfo
1869 geometry_info;
1870
1871 MagickStatusType
1872 flags;
1873
anthonyfd706f92012-01-19 04:22:02 +00001874 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00001875 if ((flags & RhoValue) == 0)
1876 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00001877 brightness=geometry_info.rho;
1878 contrast=0.0;
1879 if ((flags & SigmaValue) != 0)
1880 contrast=geometry_info.sigma;
anthony92c93bd2012-03-19 14:02:47 +00001881 (void) BrightnessContrastImage(_image,brightness,contrast,
1882 _exception);
anthony805a2d42011-09-25 08:25:12 +00001883 break;
1884 }
anthonyebb73a22012-03-22 14:25:52 +00001885 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001886 }
1887 case 'c':
1888 {
anthonyafa3dfc2012-03-03 11:31:30 +00001889 if (LocaleCompare("cdl",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001890 {
1891 char
1892 *color_correction_collection;
1893
1894 /*
1895 Color correct with a color decision list.
1896 */
anthony92c93bd2012-03-19 14:02:47 +00001897 color_correction_collection=FileToString(arg1,~0,_exception);
anthony805a2d42011-09-25 08:25:12 +00001898 if (color_correction_collection == (char *) NULL)
1899 break;
anthony92c93bd2012-03-19 14:02:47 +00001900 (void) ColorDecisionListImage(_image,color_correction_collection,
1901 _exception);
anthony805a2d42011-09-25 08:25:12 +00001902 break;
1903 }
anthonyafa3dfc2012-03-03 11:31:30 +00001904 if (LocaleCompare("charcoal",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001905 {
anthonyfd706f92012-01-19 04:22:02 +00001906 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00001907 if ((flags & (RhoValue|SigmaValue)) == 0)
1908 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00001909 if ((flags & SigmaValue) == 0)
1910 geometry_info.sigma=1.0;
1911 if ((flags & XiValue) == 0)
1912 geometry_info.xi=1.0;
anthony92c93bd2012-03-19 14:02:47 +00001913 new_image=CharcoalImage(_image,geometry_info.rho,
cristyaa2c16c2012-03-25 22:21:35 +00001914 geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00001915 break;
1916 }
anthonyafa3dfc2012-03-03 11:31:30 +00001917 if (LocaleCompare("chop",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001918 {
anthony7bcfe7f2012-03-30 14:01:22 +00001919 if (IfMagickFalse(IsGeometry(arg1)))
anthony5330ae02012-03-20 14:17:01 +00001920 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001921 (void) ParseGravityGeometry(_image,arg1,&geometry,_exception);
1922 new_image=ChopImage(_image,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00001923 break;
1924 }
anthonyafa3dfc2012-03-03 11:31:30 +00001925 if (LocaleCompare("clamp",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001926 {
anthony92c93bd2012-03-19 14:02:47 +00001927 (void) ClampImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00001928 break;
1929 }
anthonyafa3dfc2012-03-03 11:31:30 +00001930 if (LocaleCompare("clip",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001931 {
anthonyafa3dfc2012-03-03 11:31:30 +00001932 if (IfNormalOp)
anthony92c93bd2012-03-19 14:02:47 +00001933 (void) ClipImage(_image,_exception);
anthony43f425d2012-02-26 12:58:58 +00001934 else /* "+mask" remove the write mask */
anthony92c93bd2012-03-19 14:02:47 +00001935 (void) SetImageMask(_image,(Image *) NULL,_exception);
anthony805a2d42011-09-25 08:25:12 +00001936 break;
1937 }
anthonyafa3dfc2012-03-03 11:31:30 +00001938 if (LocaleCompare("clip-mask",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001939 {
1940 CacheView
1941 *mask_view;
1942
1943 Image
1944 *mask_image;
1945
1946 register Quantum
1947 *restrict q;
1948
1949 register ssize_t
1950 x;
1951
1952 ssize_t
1953 y;
1954
anthonyafa3dfc2012-03-03 11:31:30 +00001955 if (IfPlusOp) {
1956 /* "+clip-mask" Remove the write mask */
anthony92c93bd2012-03-19 14:02:47 +00001957 (void) SetImageMask(_image,(Image *) NULL,_exception);
anthonyafa3dfc2012-03-03 11:31:30 +00001958 break;
1959 }
anthony92c93bd2012-03-19 14:02:47 +00001960 mask_image=GetImageCache(_image_info,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00001961 if (mask_image == (Image *) NULL)
1962 break;
anthony7bcfe7f2012-03-30 14:01:22 +00001963 if (IfMagickFalse(SetImageStorageClass(mask_image,DirectClass,_exception)))
anthony31f1bf72012-01-30 12:37:22 +00001964 break;
anthony5330ae02012-03-20 14:17:01 +00001965 /* Create a write mask from cli_wand mask image */
anthonyfd706f92012-01-19 04:22:02 +00001966 /* FUTURE: use Alpha operations instead and create a Grey Image */
cristydb070952012-04-20 14:33:00 +00001967 mask_view=AcquireAuthenticCacheView(mask_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00001968 for (y=0; y < (ssize_t) mask_image->rows; y++)
1969 {
1970 q=GetCacheViewAuthenticPixels(mask_view,0,y,mask_image->columns,1,
anthony92c93bd2012-03-19 14:02:47 +00001971 _exception);
anthony805a2d42011-09-25 08:25:12 +00001972 if (q == (Quantum *) NULL)
1973 break;
1974 for (x=0; x < (ssize_t) mask_image->columns; x++)
1975 {
anthony7bcfe7f2012-03-30 14:01:22 +00001976 if (IfMagickFalse(mask_image->matte))
anthony805a2d42011-09-25 08:25:12 +00001977 SetPixelAlpha(mask_image,GetPixelIntensity(mask_image,q),q);
1978 SetPixelRed(mask_image,GetPixelAlpha(mask_image,q),q);
1979 SetPixelGreen(mask_image,GetPixelAlpha(mask_image,q),q);
1980 SetPixelBlue(mask_image,GetPixelAlpha(mask_image,q),q);
1981 q+=GetPixelChannels(mask_image);
1982 }
anthony7bcfe7f2012-03-30 14:01:22 +00001983 if (IfMagickFalse(SyncCacheViewAuthenticPixels(mask_view,_exception)))
anthony805a2d42011-09-25 08:25:12 +00001984 break;
1985 }
anthonyfd706f92012-01-19 04:22:02 +00001986 /* clean up and set the write mask */
anthony805a2d42011-09-25 08:25:12 +00001987 mask_view=DestroyCacheView(mask_view);
1988 mask_image->matte=MagickTrue;
anthony92c93bd2012-03-19 14:02:47 +00001989 (void) SetImageMask(_image,mask_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00001990 mask_image=DestroyImage(mask_image);
anthony805a2d42011-09-25 08:25:12 +00001991 break;
1992 }
anthonyafa3dfc2012-03-03 11:31:30 +00001993 if (LocaleCompare("clip-path",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001994 {
anthony92c93bd2012-03-19 14:02:47 +00001995 (void) ClipImagePath(_image,arg1,normal_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00001996 break;
1997 }
anthonyafa3dfc2012-03-03 11:31:30 +00001998 if (LocaleCompare("colorize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001999 {
anthony7bcfe7f2012-03-30 14:01:22 +00002000 if (IfMagickFalse(IsGeometry(arg1)))
anthony5330ae02012-03-20 14:17:01 +00002001 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002002 new_image=ColorizeImage(_image,arg1,&_draw_info->fill,_exception);
anthony805a2d42011-09-25 08:25:12 +00002003 break;
2004 }
anthonyafa3dfc2012-03-03 11:31:30 +00002005 if (LocaleCompare("color-matrix",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002006 {
2007 KernelInfo
2008 *kernel;
2009
anthonyfd706f92012-01-19 04:22:02 +00002010 kernel=AcquireKernelInfo(arg1);
anthony805a2d42011-09-25 08:25:12 +00002011 if (kernel == (KernelInfo *) NULL)
anthony5330ae02012-03-20 14:17:01 +00002012 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002013 new_image=ColorMatrixImage(_image,kernel,_exception);
anthony805a2d42011-09-25 08:25:12 +00002014 kernel=DestroyKernelInfo(kernel);
2015 break;
2016 }
anthonyafa3dfc2012-03-03 11:31:30 +00002017 if (LocaleCompare("colors",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002018 {
anthony5330ae02012-03-20 14:17:01 +00002019 /* Reduce the number of colors in the image.
2020 FUTURE: also provide 'plus version with image 'color counts'
anthonyfd706f92012-01-19 04:22:02 +00002021 */
anthony92c93bd2012-03-19 14:02:47 +00002022 _quantize_info->number_colors=StringToUnsignedLong(arg1);
2023 if (_quantize_info->number_colors == 0)
anthony5330ae02012-03-20 14:17:01 +00002024 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002025 if ((_image->storage_class == DirectClass) ||
2026 _image->colors > _quantize_info->number_colors)
2027 (void) QuantizeImage(_quantize_info,_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002028 else
anthony92c93bd2012-03-19 14:02:47 +00002029 (void) CompressImageColormap(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002030 break;
2031 }
anthonyafa3dfc2012-03-03 11:31:30 +00002032 if (LocaleCompare("colorspace",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002033 {
anthony5330ae02012-03-20 14:17:01 +00002034 /* WARNING: this is both a image_info setting (already done)
2035 and a operator to change image colorspace.
anthony31f1bf72012-01-30 12:37:22 +00002036
2037 FUTURE: default colorspace should be sRGB!
anthonyd2cdc862011-10-07 14:07:17 +00002038 Unless some type of 'linear colorspace' mode is set.
anthony31f1bf72012-01-30 12:37:22 +00002039
anthonyd2cdc862011-10-07 14:07:17 +00002040 Note that +colorspace sets "undefined" or no effect on
2041 new images, but forces images already in memory back to RGB!
anthony31f1bf72012-01-30 12:37:22 +00002042 That seems to be a little strange!
anthonyd2cdc862011-10-07 14:07:17 +00002043 */
anthony92c93bd2012-03-19 14:02:47 +00002044 (void) TransformImageColorspace(_image,
2045 IfNormalOp ? _image_info->colorspace : RGBColorspace,
2046 _exception);
anthony805a2d42011-09-25 08:25:12 +00002047 break;
2048 }
anthonyafa3dfc2012-03-03 11:31:30 +00002049 if (LocaleCompare("contrast",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002050 {
anthony464f1c42012-04-22 08:51:01 +00002051 CLIWandWarnReplaced(normal_op?"-level":"+level");
anthony92c93bd2012-03-19 14:02:47 +00002052 (void) ContrastImage(_image,normal_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00002053 break;
2054 }
anthonyafa3dfc2012-03-03 11:31:30 +00002055 if (LocaleCompare("contrast-stretch",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002056 {
2057 double
2058 black_point,
2059 white_point;
2060
2061 MagickStatusType
2062 flags;
2063
anthonyfd706f92012-01-19 04:22:02 +00002064 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00002065 if ((flags & RhoValue) == 0)
2066 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00002067 black_point=geometry_info.rho;
2068 white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
2069 black_point;
anthonyebb73a22012-03-22 14:25:52 +00002070 if ((flags & PercentValue) != 0) {
anthony92c93bd2012-03-19 14:02:47 +00002071 black_point*=(double) _image->columns*_image->rows/100.0;
2072 white_point*=(double) _image->columns*_image->rows/100.0;
anthony805a2d42011-09-25 08:25:12 +00002073 }
anthony92c93bd2012-03-19 14:02:47 +00002074 white_point=(MagickRealType) _image->columns*_image->rows-
anthony805a2d42011-09-25 08:25:12 +00002075 white_point;
anthony92c93bd2012-03-19 14:02:47 +00002076 (void) ContrastStretchImage(_image,black_point,white_point,
2077 _exception);
anthony805a2d42011-09-25 08:25:12 +00002078 break;
2079 }
anthonyafa3dfc2012-03-03 11:31:30 +00002080 if (LocaleCompare("convolve",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002081 {
2082 KernelInfo
2083 *kernel_info;
2084
anthonyfd706f92012-01-19 04:22:02 +00002085 kernel_info=AcquireKernelInfo(arg1);
anthony805a2d42011-09-25 08:25:12 +00002086 if (kernel_info == (KernelInfo *) NULL)
anthonyebb73a22012-03-22 14:25:52 +00002087 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
cristya12d8ba2012-04-29 16:33:41 +00002088 new_image=MorphologyImage(_image,CorrelateMorphology,1,kernel_info,
2089 _exception);
anthony805a2d42011-09-25 08:25:12 +00002090 kernel_info=DestroyKernelInfo(kernel_info);
2091 break;
2092 }
anthonyafa3dfc2012-03-03 11:31:30 +00002093 if (LocaleCompare("crop",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002094 {
anthony31f1bf72012-01-30 12:37:22 +00002095 /* WARNING: This can generate multiple images! */
anthony7bcfe7f2012-03-30 14:01:22 +00002096 if (IfMagickFalse(IsGeometry(arg1)))
anthonyebb73a22012-03-22 14:25:52 +00002097 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002098 new_image=CropImageToTiles(_image,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00002099 break;
2100 }
anthonyafa3dfc2012-03-03 11:31:30 +00002101 if (LocaleCompare("cycle",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002102 {
anthony7bcfe7f2012-03-30 14:01:22 +00002103 if (IfMagickFalse(IsGeometry(arg1)))
anthonyebb73a22012-03-22 14:25:52 +00002104 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002105 (void) CycleColormapImage(_image,(ssize_t) StringToLong(arg1),
2106 _exception);
anthony805a2d42011-09-25 08:25:12 +00002107 break;
2108 }
anthonyebb73a22012-03-22 14:25:52 +00002109 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002110 }
2111 case 'd':
2112 {
anthonyafa3dfc2012-03-03 11:31:30 +00002113 if (LocaleCompare("decipher",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002114 {
2115 StringInfo
2116 *passkey;
2117
anthony92c93bd2012-03-19 14:02:47 +00002118 passkey=FileToStringInfo(arg1,~0,_exception);
anthonyebb73a22012-03-22 14:25:52 +00002119 if (passkey == (StringInfo *) NULL)
2120 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2121
2122 (void) PasskeyDecipherImage(_image,passkey,_exception);
2123 passkey=DestroyStringInfo(passkey);
anthony805a2d42011-09-25 08:25:12 +00002124 break;
2125 }
anthonyafa3dfc2012-03-03 11:31:30 +00002126 if (LocaleCompare("depth",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002127 {
anthony92c93bd2012-03-19 14:02:47 +00002128 /* The _image_info->depth setting has already been set
anthonydcf510d2011-10-30 13:51:40 +00002129 We just need to apply it to all images in current sequence
anthony31f1bf72012-01-30 12:37:22 +00002130
anthonydcf510d2011-10-30 13:51:40 +00002131 WARNING: Depth from 8 to 16 causes 'quantum rounding to images!
2132 That is it really is an operation, not a setting! Arrgghhh
anthony31f1bf72012-01-30 12:37:22 +00002133
anthonyfd706f92012-01-19 04:22:02 +00002134 FUTURE: this should not be an operator!!!
anthonydcf510d2011-10-30 13:51:40 +00002135 */
anthony92c93bd2012-03-19 14:02:47 +00002136 (void) SetImageDepth(_image,_image_info->depth,_exception);
anthony805a2d42011-09-25 08:25:12 +00002137 break;
2138 }
anthonyafa3dfc2012-03-03 11:31:30 +00002139 if (LocaleCompare("deskew",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002140 {
2141 double
2142 threshold;
2143
anthonyebb73a22012-03-22 14:25:52 +00002144 if (IfNormalOp) {
anthony7bcfe7f2012-03-30 14:01:22 +00002145 if (IfMagickFalse(IsGeometry(arg1)))
anthonyebb73a22012-03-22 14:25:52 +00002146 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00002147 threshold=StringToDoubleInterval(arg1,(double) QuantumRange+1.0);
anthonyebb73a22012-03-22 14:25:52 +00002148 }
anthonyafa3dfc2012-03-03 11:31:30 +00002149 else
2150 threshold=40.0*QuantumRange/100.0;
anthony92c93bd2012-03-19 14:02:47 +00002151 new_image=DeskewImage(_image,threshold,_exception);
anthony805a2d42011-09-25 08:25:12 +00002152 break;
2153 }
anthonyafa3dfc2012-03-03 11:31:30 +00002154 if (LocaleCompare("despeckle",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002155 {
anthony92c93bd2012-03-19 14:02:47 +00002156 new_image=DespeckleImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002157 break;
2158 }
anthonyafa3dfc2012-03-03 11:31:30 +00002159 if (LocaleCompare("distort",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002160 {
anthony805a2d42011-09-25 08:25:12 +00002161 double
anthonyb1d483a2012-04-14 12:53:56 +00002162 *args;
anthony805a2d42011-09-25 08:25:12 +00002163
anthonyb1d483a2012-04-14 12:53:56 +00002164 ssize_t
2165 count;
anthony805a2d42011-09-25 08:25:12 +00002166
anthony2a0ec8c2012-03-24 04:35:56 +00002167 parse = ParseCommandOption(MagickDistortOptions,MagickFalse,arg1);
2168 if ( parse < 0 )
anthonyebb73a22012-03-22 14:25:52 +00002169 CLIWandExceptArgBreak(OptionError,"UnrecognizedDistortMethod",
2170 option,arg1);
anthony2a0ec8c2012-03-24 04:35:56 +00002171 if ((DistortImageMethod) parse == ResizeDistortion)
anthony805a2d42011-09-25 08:25:12 +00002172 {
anthony80c37752012-01-16 01:03:11 +00002173 double
2174 resize_args[2];
anthony805a2d42011-09-25 08:25:12 +00002175 /* Special Case - Argument is actually a resize geometry!
2176 ** Convert that to an appropriate distortion argument array.
anthonyfd706f92012-01-19 04:22:02 +00002177 ** FUTURE: make a separate special resize operator
anthonyfe1aa782012-03-24 13:43:04 +00002178 Roll into a resize special operator */
anthony7bcfe7f2012-03-30 14:01:22 +00002179 if (IfMagickFalse(IsGeometry(arg2)))
anthonyebb73a22012-03-22 14:25:52 +00002180 CLIWandExceptArgBreak(OptionError,"InvalidGeometry",
2181 option,arg2);
2182 (void) ParseRegionGeometry(_image,arg2,&geometry,_exception);
anthony80c37752012-01-16 01:03:11 +00002183 resize_args[0]=(double) geometry.width;
2184 resize_args[1]=(double) geometry.height;
anthony2a0ec8c2012-03-24 04:35:56 +00002185 new_image=DistortImage(_image,(DistortImageMethod) parse,
2186 (size_t)2,resize_args,MagickTrue,_exception);
anthony805a2d42011-09-25 08:25:12 +00002187 break;
2188 }
anthonyb1d483a2012-04-14 12:53:56 +00002189 /* convert argument string into an array of doubles */
anthony964d28e2012-05-17 23:39:46 +00002190 args = StringToArrayOfDoubles(arg2,&count,_exception);
anthonyb1d483a2012-04-14 12:53:56 +00002191 if (args == (double *)NULL )
2192 CLIWandExceptArgBreak(OptionError,"InvalidNumberList",option,arg2);
2193
2194 new_image=DistortImage(_image,(DistortImageMethod) parse,count,args,
2195 plus_alt_op,_exception);
2196 args=(double *) RelinquishMagickMemory(args);
anthony805a2d42011-09-25 08:25:12 +00002197 break;
2198 }
anthonyafa3dfc2012-03-03 11:31:30 +00002199 if (LocaleCompare("draw",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002200 {
anthony92c93bd2012-03-19 14:02:47 +00002201 (void) CloneString(&_draw_info->primitive,arg1);
2202 (void) DrawImage(_image,_draw_info,_exception);
2203 (void) CloneString(&_draw_info->primitive,(char *)NULL);
anthony805a2d42011-09-25 08:25:12 +00002204 break;
2205 }
anthonyebb73a22012-03-22 14:25:52 +00002206 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002207 }
2208 case 'e':
2209 {
anthonyafa3dfc2012-03-03 11:31:30 +00002210 if (LocaleCompare("edge",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002211 {
anthonyfd706f92012-01-19 04:22:02 +00002212 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00002213 if ((flags & (RhoValue|SigmaValue)) == 0)
2214 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00002215 if ((flags & SigmaValue) == 0)
2216 geometry_info.sigma=1.0;
anthony2a0ec8c2012-03-24 04:35:56 +00002217 new_image=EdgeImage(_image,geometry_info.rho,geometry_info.sigma,
2218 _exception);
anthony805a2d42011-09-25 08:25:12 +00002219 break;
2220 }
anthonyafa3dfc2012-03-03 11:31:30 +00002221 if (LocaleCompare("emboss",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002222 {
anthonyfd706f92012-01-19 04:22:02 +00002223 flags=ParseGeometry(arg1,&geometry_info);
anthonyb1e21ed2012-04-20 12:43:12 +00002224 if ((flags & (RhoValue|SigmaValue)) == 0)
2225 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00002226 if ((flags & SigmaValue) == 0)
2227 geometry_info.sigma=1.0;
anthony92c93bd2012-03-19 14:02:47 +00002228 new_image=EmbossImage(_image,geometry_info.rho,
2229 geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00002230 break;
2231 }
anthonyafa3dfc2012-03-03 11:31:30 +00002232 if (LocaleCompare("encipher",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002233 {
2234 StringInfo
2235 *passkey;
2236
anthony92c93bd2012-03-19 14:02:47 +00002237 passkey=FileToStringInfo(arg1,~0,_exception);
anthony805a2d42011-09-25 08:25:12 +00002238 if (passkey != (StringInfo *) NULL)
2239 {
anthony92c93bd2012-03-19 14:02:47 +00002240 (void) PasskeyEncipherImage(_image,passkey,_exception);
anthony805a2d42011-09-25 08:25:12 +00002241 passkey=DestroyStringInfo(passkey);
2242 }
2243 break;
2244 }
anthonyafa3dfc2012-03-03 11:31:30 +00002245 if (LocaleCompare("enhance",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002246 {
anthony92c93bd2012-03-19 14:02:47 +00002247 new_image=EnhanceImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002248 break;
2249 }
anthonyafa3dfc2012-03-03 11:31:30 +00002250 if (LocaleCompare("equalize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002251 {
anthony92c93bd2012-03-19 14:02:47 +00002252 (void) EqualizeImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002253 break;
2254 }
anthonyafa3dfc2012-03-03 11:31:30 +00002255 if (LocaleCompare("evaluate",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002256 {
2257 double
2258 constant;
2259
anthony2a0ec8c2012-03-24 04:35:56 +00002260 parse = ParseCommandOption(MagickEvaluateOptions,MagickFalse,arg1);
2261 if ( parse < 0 )
2262 CLIWandExceptArgBreak(OptionError,"UnrecognizedEvaluateOperator",
2263 option,arg1);
anthony7bcfe7f2012-03-30 14:01:22 +00002264 if (IfMagickFalse(IsGeometry(arg2)))
anthony2a0ec8c2012-03-24 04:35:56 +00002265 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
anthonyfd706f92012-01-19 04:22:02 +00002266 constant=StringToDoubleInterval(arg2,(double) QuantumRange+1.0);
anthony2a0ec8c2012-03-24 04:35:56 +00002267 (void) EvaluateImage(_image,(MagickEvaluateOperator)parse,constant,
2268 _exception);
anthony805a2d42011-09-25 08:25:12 +00002269 break;
2270 }
anthonyafa3dfc2012-03-03 11:31:30 +00002271 if (LocaleCompare("extent",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002272 {
anthony7bcfe7f2012-03-30 14:01:22 +00002273 if (IfMagickFalse(IsGeometry(arg1)))
anthony2a0ec8c2012-03-24 04:35:56 +00002274 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002275 flags=ParseGravityGeometry(_image,arg1,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00002276 if (geometry.width == 0)
anthony92c93bd2012-03-19 14:02:47 +00002277 geometry.width=_image->columns;
anthony805a2d42011-09-25 08:25:12 +00002278 if (geometry.height == 0)
anthony92c93bd2012-03-19 14:02:47 +00002279 geometry.height=_image->rows;
2280 new_image=ExtentImage(_image,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00002281 break;
2282 }
anthonyebb73a22012-03-22 14:25:52 +00002283 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002284 }
2285 case 'f':
2286 {
anthonyafa3dfc2012-03-03 11:31:30 +00002287 if (LocaleCompare("features",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002288 {
anthony31f1bf72012-01-30 12:37:22 +00002289 /* FUTURE: move to SyncImageSettings() and AcqireImage()??? */
anthonyafa3dfc2012-03-03 11:31:30 +00002290 if (IfPlusOp) {
anthony92c93bd2012-03-19 14:02:47 +00002291 (void) DeleteImageArtifact(_image,"identify:features");
anthony31f1bf72012-01-30 12:37:22 +00002292 break;
2293 }
anthony92c93bd2012-03-19 14:02:47 +00002294 (void) SetImageArtifact(_image,"identify:features","true");
2295 (void) SetImageArtifact(_image,"verbose","true");
anthony805a2d42011-09-25 08:25:12 +00002296 break;
2297 }
anthonyafa3dfc2012-03-03 11:31:30 +00002298 if (LocaleCompare("flip",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002299 {
anthony92c93bd2012-03-19 14:02:47 +00002300 new_image=FlipImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002301 break;
2302 }
anthonyafa3dfc2012-03-03 11:31:30 +00002303 if (LocaleCompare("flop",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002304 {
anthony92c93bd2012-03-19 14:02:47 +00002305 new_image=FlopImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002306 break;
2307 }
anthonyafa3dfc2012-03-03 11:31:30 +00002308 if (LocaleCompare("floodfill",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002309 {
2310 PixelInfo
2311 target;
2312
anthony7bcfe7f2012-03-30 14:01:22 +00002313 if (IfMagickFalse(IsGeometry(arg1)))
anthony2a0ec8c2012-03-24 04:35:56 +00002314 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002315 (void) ParsePageGeometry(_image,arg1,&geometry,_exception);
2316 (void) QueryColorCompliance(arg2,AllCompliance,&target,_exception);
2317 (void) FloodfillPaintImage(_image,_draw_info,&target,geometry.x,
2318 geometry.y,plus_alt_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00002319 break;
2320 }
anthonyafa3dfc2012-03-03 11:31:30 +00002321 if (LocaleCompare("frame",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002322 {
2323 FrameInfo
2324 frame_info;
2325
anthony31f1bf72012-01-30 12:37:22 +00002326 CompositeOperator
anthonyfd706f92012-01-19 04:22:02 +00002327 compose;
2328
2329 const char*
2330 value;
2331
anthony92c93bd2012-03-19 14:02:47 +00002332 value=GetImageOption(_image_info,"compose");
anthonyfd706f92012-01-19 04:22:02 +00002333 if (value != (const char *) NULL)
2334 compose=(CompositeOperator) ParseCommandOption(
2335 MagickComposeOptions,MagickFalse,value);
2336 else
anthony92c93bd2012-03-19 14:02:47 +00002337 compose=OverCompositeOp; /* use Over not _image->compose */
anthonyfd706f92012-01-19 04:22:02 +00002338
anthony7bcfe7f2012-03-30 14:01:22 +00002339 if (IfMagickFalse(IsGeometry(arg1)))
anthony2a0ec8c2012-03-24 04:35:56 +00002340 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002341 flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00002342 frame_info.width=geometry.width;
2343 frame_info.height=geometry.height;
2344 if ((flags & HeightValue) == 0)
2345 frame_info.height=geometry.width;
2346 frame_info.outer_bevel=geometry.x;
2347 frame_info.inner_bevel=geometry.y;
2348 frame_info.x=(ssize_t) frame_info.width;
2349 frame_info.y=(ssize_t) frame_info.height;
anthony92c93bd2012-03-19 14:02:47 +00002350 frame_info.width=_image->columns+2*frame_info.width;
2351 frame_info.height=_image->rows+2*frame_info.height;
2352 new_image=FrameImage(_image,&frame_info,compose,_exception);
anthony805a2d42011-09-25 08:25:12 +00002353 break;
2354 }
anthonyafa3dfc2012-03-03 11:31:30 +00002355 if (LocaleCompare("function",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002356 {
anthony805a2d42011-09-25 08:25:12 +00002357 double
anthonyb1d483a2012-04-14 12:53:56 +00002358 *args;
anthony805a2d42011-09-25 08:25:12 +00002359
anthonyb1d483a2012-04-14 12:53:56 +00002360 ssize_t
2361 count;
anthony805a2d42011-09-25 08:25:12 +00002362
anthony2a0ec8c2012-03-24 04:35:56 +00002363 parse=ParseCommandOption(MagickFunctionOptions,MagickFalse,arg1);
2364 if ( parse < 0 )
2365 CLIWandExceptArgBreak(OptionError,"UnrecognizedFunction",
2366 option,arg1);
anthonyb1d483a2012-04-14 12:53:56 +00002367 /* convert argument string into an array of doubles */
anthony964d28e2012-05-17 23:39:46 +00002368 args = StringToArrayOfDoubles(arg2,&count,_exception);
anthonyb1d483a2012-04-14 12:53:56 +00002369 if (args == (double *)NULL )
2370 CLIWandExceptArgBreak(OptionError,"InvalidNumberList",option,arg2);
2371
2372 (void) FunctionImage(_image,(MagickFunction)parse,count,args,
2373 _exception);
2374 args=(double *) RelinquishMagickMemory(args);
anthony805a2d42011-09-25 08:25:12 +00002375 break;
2376 }
anthonyebb73a22012-03-22 14:25:52 +00002377 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002378 }
2379 case 'g':
2380 {
anthonyafa3dfc2012-03-03 11:31:30 +00002381 if (LocaleCompare("gamma",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002382 {
anthony7bcfe7f2012-03-30 14:01:22 +00002383 if (IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00002384 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyafa3dfc2012-03-03 11:31:30 +00002385 if (IfNormalOp)
anthony92c93bd2012-03-19 14:02:47 +00002386 (void) GammaImage(_image,StringToDouble(arg1,(char **) NULL),
2387 _exception);
anthonyafa3dfc2012-03-03 11:31:30 +00002388 else
anthony92c93bd2012-03-19 14:02:47 +00002389 _image->gamma=StringToDouble(arg1,(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +00002390 break;
2391 }
anthony975a8d72012-04-12 13:54:36 +00002392 if (LocaleCompare("gaussian-blur",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002393 {
anthonyfd706f92012-01-19 04:22:02 +00002394 flags=ParseGeometry(arg1,&geometry_info);
anthonyb1e21ed2012-04-20 12:43:12 +00002395 if ((flags & (RhoValue|SigmaValue)) == 0)
2396 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00002397 if ((flags & SigmaValue) == 0)
2398 geometry_info.sigma=1.0;
anthony92c93bd2012-03-19 14:02:47 +00002399 new_image=GaussianBlurImage(_image,geometry_info.rho,
2400 geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00002401 break;
2402 }
anthony975a8d72012-04-12 13:54:36 +00002403 if (LocaleCompare("gaussian",option+1) == 0)
2404 {
anthony464f1c42012-04-22 08:51:01 +00002405 CLIWandWarnReplaced("-gaussian-blur");
anthony975a8d72012-04-12 13:54:36 +00002406 CLISimpleOperatorImage(cli_wand,"-gaussian-blur",arg1,NULL);
2407 }
anthonyafa3dfc2012-03-03 11:31:30 +00002408 if (LocaleCompare("geometry",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002409 {
anthonyfd706f92012-01-19 04:22:02 +00002410 /*
anthony31f1bf72012-01-30 12:37:22 +00002411 Record Image offset for composition. (A Setting)
anthonyfe1aa782012-03-24 13:43:04 +00002412 Resize last _image. (ListOperator) -- DEPRECIATE
anthony31f1bf72012-01-30 12:37:22 +00002413 FUTURE: Why if no 'offset' does this resize ALL images?
2414 Also why is the setting recorded in the IMAGE non-sense!
anthonyfd706f92012-01-19 04:22:02 +00002415 */
anthonyafa3dfc2012-03-03 11:31:30 +00002416 if (IfPlusOp)
anthonyfd706f92012-01-19 04:22:02 +00002417 { /* remove the previous composition geometry offset! */
anthony92c93bd2012-03-19 14:02:47 +00002418 if (_image->geometry != (char *) NULL)
2419 _image->geometry=DestroyString(_image->geometry);
anthony805a2d42011-09-25 08:25:12 +00002420 break;
2421 }
anthony7bcfe7f2012-03-30 14:01:22 +00002422 if (IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00002423 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002424 flags=ParseRegionGeometry(_image,arg1,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00002425 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
anthony92c93bd2012-03-19 14:02:47 +00002426 (void) CloneString(&_image->geometry,arg1);
anthony805a2d42011-09-25 08:25:12 +00002427 else
anthony92c93bd2012-03-19 14:02:47 +00002428 new_image=ResizeImage(_image,geometry.width,geometry.height,
cristyaa2c16c2012-03-25 22:21:35 +00002429 _image->filter,_exception);
anthony805a2d42011-09-25 08:25:12 +00002430 break;
2431 }
anthonyebb73a22012-03-22 14:25:52 +00002432 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002433 }
anthony805a2d42011-09-25 08:25:12 +00002434 case 'i':
2435 {
anthonyafa3dfc2012-03-03 11:31:30 +00002436 if (LocaleCompare("identify",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002437 {
anthony31f1bf72012-01-30 12:37:22 +00002438 const char
2439 *format,
anthony805a2d42011-09-25 08:25:12 +00002440 *text;
2441
anthony92c93bd2012-03-19 14:02:47 +00002442 format=GetImageOption(_image_info,"format");
anthony964d28e2012-05-17 23:39:46 +00002443 if (format == (char *) NULL) {
2444 (void) IdentifyImage(_image,stdout,_image_info->verbose,_exception);
2445 break;
2446 }
anthony92c93bd2012-03-19 14:02:47 +00002447 text=InterpretImageProperties(_image_info,_image,format,_exception);
anthony805a2d42011-09-25 08:25:12 +00002448 if (text == (char *) NULL)
anthony964d28e2012-05-17 23:39:46 +00002449 CLIWandExceptionBreak(OptionWarning,"InterpretPropertyFailure",
2450 option);
anthony805a2d42011-09-25 08:25:12 +00002451 (void) fputs(text,stdout);
2452 (void) fputc('\n',stdout);
anthony31f1bf72012-01-30 12:37:22 +00002453 text=DestroyString((char *)text);
anthony805a2d42011-09-25 08:25:12 +00002454 break;
2455 }
anthonyafa3dfc2012-03-03 11:31:30 +00002456 if (LocaleCompare("implode",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002457 {
anthonyb1e21ed2012-04-20 12:43:12 +00002458 flags=ParseGeometry(arg1,&geometry_info);
2459 if ((flags & RhoValue) == 0)
anthonyfe1aa782012-03-24 13:43:04 +00002460 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyb1e21ed2012-04-20 12:43:12 +00002461 new_image=ImplodeImage(_image,geometry_info.rho,_image->interpolate,
2462 _exception);
anthony805a2d42011-09-25 08:25:12 +00002463 break;
2464 }
anthonyafa3dfc2012-03-03 11:31:30 +00002465 if (LocaleCompare("interpolative-resize",option+1) == 0)
cristy947cb4c2011-10-20 18:41:46 +00002466 {
anthonyfe1aa782012-03-24 13:43:04 +00002467 /* FUTURE: New to IMv7
2468 Roll into a resize special operator */
anthony7bcfe7f2012-03-30 14:01:22 +00002469 if (IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00002470 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002471 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
2472 new_image=InterpolativeResizeImage(_image,geometry.width,
2473 geometry.height,_image->interpolate,_exception);
cristy947cb4c2011-10-20 18:41:46 +00002474 break;
2475 }
anthonyebb73a22012-03-22 14:25:52 +00002476 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002477 }
2478 case 'l':
2479 {
anthonyafa3dfc2012-03-03 11:31:30 +00002480 if (LocaleCompare("lat",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002481 {
anthonyfd706f92012-01-19 04:22:02 +00002482 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00002483 if ((flags & (RhoValue|SigmaValue)) == 0)
2484 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00002485 if ((flags & PercentValue) != 0)
2486 geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
anthony92c93bd2012-03-19 14:02:47 +00002487 new_image=AdaptiveThresholdImage(_image,(size_t) geometry_info.rho,
anthony31f1bf72012-01-30 12:37:22 +00002488 (size_t) geometry_info.sigma,(double) geometry_info.xi,
anthony92c93bd2012-03-19 14:02:47 +00002489 _exception);
anthony805a2d42011-09-25 08:25:12 +00002490 break;
2491 }
anthonyafa3dfc2012-03-03 11:31:30 +00002492 if (LocaleCompare("level",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002493 {
2494 MagickRealType
2495 black_point,
2496 gamma,
2497 white_point;
2498
2499 MagickStatusType
2500 flags;
2501
anthonyfd706f92012-01-19 04:22:02 +00002502 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00002503 if ((flags & RhoValue) == 0)
2504 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00002505 black_point=geometry_info.rho;
2506 white_point=(MagickRealType) QuantumRange;
2507 if ((flags & SigmaValue) != 0)
2508 white_point=geometry_info.sigma;
2509 gamma=1.0;
2510 if ((flags & XiValue) != 0)
2511 gamma=geometry_info.xi;
2512 if ((flags & PercentValue) != 0)
2513 {
2514 black_point*=(MagickRealType) (QuantumRange/100.0);
2515 white_point*=(MagickRealType) (QuantumRange/100.0);
2516 }
2517 if ((flags & SigmaValue) == 0)
2518 white_point=(MagickRealType) QuantumRange-black_point;
anthonyafa3dfc2012-03-03 11:31:30 +00002519 if (IfPlusOp || ((flags & AspectValue) != 0))
anthony92c93bd2012-03-19 14:02:47 +00002520 (void) LevelizeImage(_image,black_point,white_point,gamma,_exception);
anthony805a2d42011-09-25 08:25:12 +00002521 else
anthony92c93bd2012-03-19 14:02:47 +00002522 (void) LevelImage(_image,black_point,white_point,gamma,_exception);
anthony805a2d42011-09-25 08:25:12 +00002523 break;
2524 }
anthonyafa3dfc2012-03-03 11:31:30 +00002525 if (LocaleCompare("level-colors",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002526 {
2527 char
2528 token[MaxTextExtent];
2529
2530 const char
2531 *p;
2532
2533 PixelInfo
2534 black_point,
2535 white_point;
2536
anthonyfd706f92012-01-19 04:22:02 +00002537 p=(const char *) arg1;
anthony805a2d42011-09-25 08:25:12 +00002538 GetMagickToken(p,&p,token); /* get black point color */
2539 if ((isalpha((int) *token) != 0) || ((*token == '#') != 0))
cristy269c9412011-10-13 23:41:15 +00002540 (void) QueryColorCompliance(token,AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +00002541 &black_point,_exception);
anthony805a2d42011-09-25 08:25:12 +00002542 else
cristy269c9412011-10-13 23:41:15 +00002543 (void) QueryColorCompliance("#000000",AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +00002544 &black_point,_exception);
anthony805a2d42011-09-25 08:25:12 +00002545 if (isalpha((int) token[0]) || (token[0] == '#'))
2546 GetMagickToken(p,&p,token);
2547 if (*token == '\0')
2548 white_point=black_point; /* set everything to that color */
2549 else
2550 {
2551 if ((isalpha((int) *token) == 0) && ((*token == '#') == 0))
2552 GetMagickToken(p,&p,token); /* Get white point color. */
2553 if ((isalpha((int) *token) != 0) || ((*token == '#') != 0))
cristy269c9412011-10-13 23:41:15 +00002554 (void) QueryColorCompliance(token,AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +00002555 &white_point,_exception);
anthony805a2d42011-09-25 08:25:12 +00002556 else
cristy269c9412011-10-13 23:41:15 +00002557 (void) QueryColorCompliance("#ffffff",AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +00002558 &white_point,_exception);
anthony805a2d42011-09-25 08:25:12 +00002559 }
anthony92c93bd2012-03-19 14:02:47 +00002560 (void) LevelImageColors(_image,&black_point,&white_point,
2561 plus_alt_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00002562 break;
2563 }
anthonyafa3dfc2012-03-03 11:31:30 +00002564 if (LocaleCompare("linear-stretch",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002565 {
2566 double
2567 black_point,
2568 white_point;
2569
2570 MagickStatusType
2571 flags;
2572
anthonyfd706f92012-01-19 04:22:02 +00002573 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00002574 if ((flags & RhoValue) == 0)
2575 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00002576 black_point=geometry_info.rho;
anthony92c93bd2012-03-19 14:02:47 +00002577 white_point=(MagickRealType) _image->columns*_image->rows;
anthony805a2d42011-09-25 08:25:12 +00002578 if ((flags & SigmaValue) != 0)
2579 white_point=geometry_info.sigma;
2580 if ((flags & PercentValue) != 0)
2581 {
anthony92c93bd2012-03-19 14:02:47 +00002582 black_point*=(double) _image->columns*_image->rows/100.0;
2583 white_point*=(double) _image->columns*_image->rows/100.0;
anthony805a2d42011-09-25 08:25:12 +00002584 }
2585 if ((flags & SigmaValue) == 0)
anthony92c93bd2012-03-19 14:02:47 +00002586 white_point=(MagickRealType) _image->columns*_image->rows-
anthony805a2d42011-09-25 08:25:12 +00002587 black_point;
anthony92c93bd2012-03-19 14:02:47 +00002588 (void) LinearStretchImage(_image,black_point,white_point,_exception);
anthony805a2d42011-09-25 08:25:12 +00002589 break;
2590 }
anthonyafa3dfc2012-03-03 11:31:30 +00002591 if (LocaleCompare("liquid-rescale",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002592 {
anthonyfe1aa782012-03-24 13:43:04 +00002593 /* FUTURE: Roll into a resize special operator */
anthony7bcfe7f2012-03-30 14:01:22 +00002594 if (IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00002595 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002596 flags=ParseRegionGeometry(_image,arg1,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00002597 if ((flags & XValue) == 0)
2598 geometry.x=1;
2599 if ((flags & YValue) == 0)
2600 geometry.y=0;
anthony92c93bd2012-03-19 14:02:47 +00002601 new_image=LiquidRescaleImage(_image,geometry.width,
2602 geometry.height,1.0*geometry.x,1.0*geometry.y,_exception);
anthony805a2d42011-09-25 08:25:12 +00002603 break;
2604 }
anthonyebb73a22012-03-22 14:25:52 +00002605 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002606 }
2607 case 'm':
2608 {
anthonyafa3dfc2012-03-03 11:31:30 +00002609 if (LocaleCompare("map",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002610 {
anthony464f1c42012-04-22 08:51:01 +00002611 CLIWandWarnReplaced("-remap");
anthony975a8d72012-04-12 13:54:36 +00002612 CLISimpleOperatorImage(cli_wand,"-remap",NULL,NULL);
anthony805a2d42011-09-25 08:25:12 +00002613 break;
2614 }
anthonyafa3dfc2012-03-03 11:31:30 +00002615 if (LocaleCompare("mask",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002616 {
2617 Image
2618 *mask;
2619
anthonyafa3dfc2012-03-03 11:31:30 +00002620 if (IfPlusOp)
anthony31f1bf72012-01-30 12:37:22 +00002621 { /* Remove a mask. */
anthony92c93bd2012-03-19 14:02:47 +00002622 (void) SetImageMask(_image,(Image *) NULL,_exception);
anthony805a2d42011-09-25 08:25:12 +00002623 break;
2624 }
anthony5330ae02012-03-20 14:17:01 +00002625 /* Set the image mask. */
anthony92c93bd2012-03-19 14:02:47 +00002626 mask=GetImageCache(_image_info,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00002627 if (mask == (Image *) NULL)
2628 break;
anthony92c93bd2012-03-19 14:02:47 +00002629 (void) SetImageMask(_image,mask,_exception);
anthony805a2d42011-09-25 08:25:12 +00002630 mask=DestroyImage(mask);
2631 break;
2632 }
anthonyafa3dfc2012-03-03 11:31:30 +00002633 if (LocaleCompare("matte",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002634 {
anthony464f1c42012-04-22 08:51:01 +00002635 CLIWandWarnReplaced(IfNormalOp?"-alpha Set":"-alpha Off");
anthony92c93bd2012-03-19 14:02:47 +00002636 (void) SetImageAlphaChannel(_image,IfNormalOp ? SetAlphaChannel :
2637 DeactivateAlphaChannel, _exception);
anthony805a2d42011-09-25 08:25:12 +00002638 break;
2639 }
anthonya3ef4ed2012-03-17 06:52:53 +00002640 if (LocaleCompare("median",option+1) == 0)
2641 {
anthony464f1c42012-04-22 08:51:01 +00002642 CLIWandWarnReplaced("-statistic Median");
anthonya3ef4ed2012-03-17 06:52:53 +00002643 CLISimpleOperatorImage(cli_wand,"-statistic","Median",arg1);
2644 break;
2645 }
anthonyafa3dfc2012-03-03 11:31:30 +00002646 if (LocaleCompare("mode",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002647 {
anthony975a8d72012-04-12 13:54:36 +00002648 /* FUTURE: note this is also a special "montage" option */
anthony464f1c42012-04-22 08:51:01 +00002649 CLIWandWarnReplaced("-statistic Mode");
anthony975a8d72012-04-12 13:54:36 +00002650 CLISimpleOperatorImage(cli_wand,"-statistic","Mode",arg1);
anthony805a2d42011-09-25 08:25:12 +00002651 break;
2652 }
anthonyafa3dfc2012-03-03 11:31:30 +00002653 if (LocaleCompare("modulate",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002654 {
anthony7bcfe7f2012-03-30 14:01:22 +00002655 if (IfMagickFalse(IsGeometry(arg1)))
anthony7bc87992012-03-25 02:32:51 +00002656 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002657 (void) ModulateImage(_image,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00002658 break;
2659 }
anthonyafa3dfc2012-03-03 11:31:30 +00002660 if (LocaleCompare("monitor",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002661 {
anthony92c93bd2012-03-19 14:02:47 +00002662 (void) SetImageProgressMonitor(_image, IfNormalOp ? MonitorProgress :
anthonyafa3dfc2012-03-03 11:31:30 +00002663 (MagickProgressMonitor) NULL,(void *) NULL);
anthony805a2d42011-09-25 08:25:12 +00002664 break;
2665 }
anthonyafa3dfc2012-03-03 11:31:30 +00002666 if (LocaleCompare("monochrome",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002667 {
anthony92c93bd2012-03-19 14:02:47 +00002668 (void) SetImageType(_image,BilevelType,_exception);
anthony805a2d42011-09-25 08:25:12 +00002669 break;
2670 }
anthonyafa3dfc2012-03-03 11:31:30 +00002671 if (LocaleCompare("morphology",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002672 {
2673 char
2674 token[MaxTextExtent];
2675
2676 const char
2677 *p;
2678
2679 KernelInfo
2680 *kernel;
2681
anthony805a2d42011-09-25 08:25:12 +00002682 ssize_t
2683 iterations;
2684
anthonyfd706f92012-01-19 04:22:02 +00002685 p=arg1;
anthony805a2d42011-09-25 08:25:12 +00002686 GetMagickToken(p,&p,token);
anthony7bc87992012-03-25 02:32:51 +00002687 parse=ParseCommandOption(MagickMorphologyOptions,MagickFalse,token);
2688 if ( parse < 0 )
2689 CLIWandExceptArgBreak(OptionError,"UnrecognizedFunction",
2690 option,arg1);
anthony805a2d42011-09-25 08:25:12 +00002691 iterations=1L;
2692 GetMagickToken(p,&p,token);
2693 if ((*p == ':') || (*p == ','))
2694 GetMagickToken(p,&p,token);
2695 if ((*p != '\0'))
2696 iterations=(ssize_t) StringToLong(p);
anthonyfd706f92012-01-19 04:22:02 +00002697 kernel=AcquireKernelInfo(arg2);
anthony805a2d42011-09-25 08:25:12 +00002698 if (kernel == (KernelInfo *) NULL)
anthony7bc87992012-03-25 02:32:51 +00002699 CLIWandExceptArgBreak(OptionError,"UnabletoParseKernel",
2700 option,arg2);
2701 new_image=MorphologyImage(_image,(MorphologyMethod)parse,
2702 iterations,kernel,_exception);
anthony805a2d42011-09-25 08:25:12 +00002703 kernel=DestroyKernelInfo(kernel);
2704 break;
2705 }
anthonyafa3dfc2012-03-03 11:31:30 +00002706 if (LocaleCompare("motion-blur",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002707 {
anthonyfd706f92012-01-19 04:22:02 +00002708 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00002709 if ((flags & (RhoValue|SigmaValue)) == 0)
2710 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00002711 if ((flags & SigmaValue) == 0)
2712 geometry_info.sigma=1.0;
anthony92c93bd2012-03-19 14:02:47 +00002713 new_image=MotionBlurImage(_image,geometry_info.rho,
cristyaa2c16c2012-03-25 22:21:35 +00002714 geometry_info.sigma,geometry_info.xi,_exception);
anthony805a2d42011-09-25 08:25:12 +00002715 break;
2716 }
anthonyebb73a22012-03-22 14:25:52 +00002717 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002718 }
2719 case 'n':
2720 {
anthonyafa3dfc2012-03-03 11:31:30 +00002721 if (LocaleCompare("negate",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002722 {
anthony92c93bd2012-03-19 14:02:47 +00002723 (void) NegateImage(_image, plus_alt_op, _exception);
anthony805a2d42011-09-25 08:25:12 +00002724 break;
2725 }
anthonyafa3dfc2012-03-03 11:31:30 +00002726 if (LocaleCompare("noise",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002727 {
anthony975a8d72012-04-12 13:54:36 +00002728 double
2729 attenuate;
2730
2731 const char*
2732 value;
2733
anthonyafa3dfc2012-03-03 11:31:30 +00002734 if (IfNormalOp)
anthony805a2d42011-09-25 08:25:12 +00002735 {
anthony464f1c42012-04-22 08:51:01 +00002736 CLIWandWarnReplaced("-statistic NonPeak");
anthony975a8d72012-04-12 13:54:36 +00002737 CLISimpleOperatorImage(cli_wand,"-statistic","NonPeak",arg1);
2738 break;
anthony805a2d42011-09-25 08:25:12 +00002739 }
anthony975a8d72012-04-12 13:54:36 +00002740 parse=ParseCommandOption(MagickNoiseOptions,MagickFalse,arg1);
2741 if ( parse < 0 )
2742 CLIWandExceptArgBreak(OptionError,"UnrecognizedNoiseType",
2743 option,arg1);
2744 attenuate=1.0;
2745 value=GetImageOption(_image_info,"attenuate");
2746 if (value != (const char *) NULL)
2747 attenuate=StringToDouble(value,(char **) NULL);
2748 new_image=AddNoiseImage(_image,(NoiseType)parse,attenuate,
2749 _exception);
anthony805a2d42011-09-25 08:25:12 +00002750 break;
2751 }
anthonyafa3dfc2012-03-03 11:31:30 +00002752 if (LocaleCompare("normalize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002753 {
anthony92c93bd2012-03-19 14:02:47 +00002754 (void) NormalizeImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002755 break;
2756 }
anthonyebb73a22012-03-22 14:25:52 +00002757 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002758 }
2759 case 'o':
2760 {
anthonyafa3dfc2012-03-03 11:31:30 +00002761 if (LocaleCompare("opaque",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002762 {
2763 PixelInfo
2764 target;
2765
anthony92c93bd2012-03-19 14:02:47 +00002766 (void) QueryColorCompliance(arg1,AllCompliance,&target,_exception);
2767 (void) OpaquePaintImage(_image,&target,&_draw_info->fill,plus_alt_op,
2768 _exception);
anthony805a2d42011-09-25 08:25:12 +00002769 break;
2770 }
anthonyafa3dfc2012-03-03 11:31:30 +00002771 if (LocaleCompare("ordered-dither",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002772 {
anthony92c93bd2012-03-19 14:02:47 +00002773 (void) OrderedPosterizeImage(_image,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00002774 break;
2775 }
anthonyebb73a22012-03-22 14:25:52 +00002776 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002777 }
2778 case 'p':
2779 {
anthonyafa3dfc2012-03-03 11:31:30 +00002780 if (LocaleCompare("paint",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002781 {
anthony22de2722012-04-19 14:43:00 +00002782 flags=ParseGeometry(arg1,&geometry_info);
2783 if ((flags & (RhoValue|SigmaValue)) == 0)
2784 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002785 new_image=OilPaintImage(_image,geometry_info.rho,geometry_info.sigma,
2786 _exception);
anthony805a2d42011-09-25 08:25:12 +00002787 break;
2788 }
anthonyafa3dfc2012-03-03 11:31:30 +00002789 if (LocaleCompare("polaroid",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002790 {
cristye9e3d382011-12-14 01:50:13 +00002791 const char
2792 *caption;
2793
anthony805a2d42011-09-25 08:25:12 +00002794 double
2795 angle;
2796
anthony7bc87992012-03-25 02:32:51 +00002797 if (IfPlusOp) {
anthonyf42014d2012-03-25 09:53:06 +00002798 RandomInfo
2799 *random_info;
anthony805a2d42011-09-25 08:25:12 +00002800
anthonyf42014d2012-03-25 09:53:06 +00002801 random_info=AcquireRandomInfo();
2802 angle=22.5*(GetPseudoRandomValue(random_info)-0.5);
2803 random_info=DestroyRandomInfo(random_info);
2804 }
anthony7bc87992012-03-25 02:32:51 +00002805 else {
anthonyf42014d2012-03-25 09:53:06 +00002806 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00002807 if ((flags & RhoValue) == 0)
2808 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyf42014d2012-03-25 09:53:06 +00002809 angle=geometry_info.rho;
2810 }
anthony92c93bd2012-03-19 14:02:47 +00002811 caption=GetImageProperty(_image,"caption",_exception);
2812 new_image=PolaroidImage(_image,_draw_info,caption,angle,
2813 _image->interpolate,_exception);
anthony805a2d42011-09-25 08:25:12 +00002814 break;
2815 }
anthonyafa3dfc2012-03-03 11:31:30 +00002816 if (LocaleCompare("posterize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002817 {
anthony22de2722012-04-19 14:43:00 +00002818 flags=ParseGeometry(arg1,&geometry_info);
2819 if ((flags & RhoValue) == 0)
anthony7bc87992012-03-25 02:32:51 +00002820 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002821 (void) PosterizeImage(_image,(size_t) geometry_info.rho,
2822 _quantize_info->dither,_exception);
anthony805a2d42011-09-25 08:25:12 +00002823 break;
2824 }
anthonyafa3dfc2012-03-03 11:31:30 +00002825 if (LocaleCompare("preview",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002826 {
anthony31f1bf72012-01-30 12:37:22 +00002827 /* FUTURE: should be a 'Genesis' option?
2828 Option however is also in WandSettingOptionInfo()
anthony7bc87992012-03-25 02:32:51 +00002829 Why???
cristy947cb4c2011-10-20 18:41:46 +00002830 */
anthony7bc87992012-03-25 02:32:51 +00002831 parse=ParseCommandOption(MagickPreviewOptions, MagickFalse,arg1);
2832 if ( parse < 0 )
2833 CLIWandExceptArgBreak(OptionError,"UnrecognizedPreviewType",
2834 option,arg1);
2835 new_image=PreviewImage(_image,(PreviewType)parse,_exception);
anthony805a2d42011-09-25 08:25:12 +00002836 break;
2837 }
anthonyafa3dfc2012-03-03 11:31:30 +00002838 if (LocaleCompare("profile",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002839 {
2840 const char
2841 *name;
2842
2843 const StringInfo
2844 *profile;
2845
2846 Image
2847 *profile_image;
2848
2849 ImageInfo
2850 *profile_info;
2851
anthonyafa3dfc2012-03-03 11:31:30 +00002852 if (IfPlusOp)
anthony92c93bd2012-03-19 14:02:47 +00002853 { /* Remove a profile from the _image. */
2854 (void) ProfileImage(_image,arg1,(const unsigned char *)
2855 NULL,0,_exception);
anthony805a2d42011-09-25 08:25:12 +00002856 break;
2857 }
anthony92c93bd2012-03-19 14:02:47 +00002858 /* Associate a profile with the _image. */
2859 profile_info=CloneImageInfo(_image_info);
2860 profile=GetImageProfile(_image,"iptc");
anthony805a2d42011-09-25 08:25:12 +00002861 if (profile != (StringInfo *) NULL)
2862 profile_info->profile=(void *) CloneStringInfo(profile);
anthony92c93bd2012-03-19 14:02:47 +00002863 profile_image=GetImageCache(profile_info,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00002864 profile_info=DestroyImageInfo(profile_info);
2865 if (profile_image == (Image *) NULL)
2866 {
2867 StringInfo
2868 *profile;
2869
anthony92c93bd2012-03-19 14:02:47 +00002870 profile_info=CloneImageInfo(_image_info);
anthonyfd706f92012-01-19 04:22:02 +00002871 (void) CopyMagickString(profile_info->filename,arg1,
anthony805a2d42011-09-25 08:25:12 +00002872 MaxTextExtent);
anthony92c93bd2012-03-19 14:02:47 +00002873 profile=FileToStringInfo(profile_info->filename,~0UL,_exception);
anthony805a2d42011-09-25 08:25:12 +00002874 if (profile != (StringInfo *) NULL)
2875 {
anthony92c93bd2012-03-19 14:02:47 +00002876 (void) ProfileImage(_image,profile_info->magick,
anthony805a2d42011-09-25 08:25:12 +00002877 GetStringInfoDatum(profile),(size_t)
anthony92c93bd2012-03-19 14:02:47 +00002878 GetStringInfoLength(profile),_exception);
anthony805a2d42011-09-25 08:25:12 +00002879 profile=DestroyStringInfo(profile);
2880 }
2881 profile_info=DestroyImageInfo(profile_info);
2882 break;
2883 }
2884 ResetImageProfileIterator(profile_image);
2885 name=GetNextImageProfile(profile_image);
2886 while (name != (const char *) NULL)
2887 {
2888 profile=GetImageProfile(profile_image,name);
2889 if (profile != (StringInfo *) NULL)
anthony92c93bd2012-03-19 14:02:47 +00002890 (void) ProfileImage(_image,name,GetStringInfoDatum(profile),
2891 (size_t) GetStringInfoLength(profile),_exception);
anthony805a2d42011-09-25 08:25:12 +00002892 name=GetNextImageProfile(profile_image);
2893 }
2894 profile_image=DestroyImage(profile_image);
2895 break;
2896 }
anthonyebb73a22012-03-22 14:25:52 +00002897 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002898 }
anthony805a2d42011-09-25 08:25:12 +00002899 case 'r':
2900 {
anthonyafa3dfc2012-03-03 11:31:30 +00002901 if (LocaleCompare("radial-blur",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002902 {
anthonyfd706f92012-01-19 04:22:02 +00002903 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00002904 if ((flags & RhoValue) == 0)
2905 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
cristyaa2c16c2012-03-25 22:21:35 +00002906 new_image=RadialBlurImage(_image,geometry_info.rho,_exception);
anthony805a2d42011-09-25 08:25:12 +00002907 break;
2908 }
anthonyafa3dfc2012-03-03 11:31:30 +00002909 if (LocaleCompare("raise",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002910 {
anthony7bcfe7f2012-03-30 14:01:22 +00002911 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00002912 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002913 flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00002914 if ((flags & SigmaValue) == 0)
2915 geometry.height=geometry.width;
anthony92c93bd2012-03-19 14:02:47 +00002916 (void) RaiseImage(_image,&geometry,normal_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00002917 break;
2918 }
anthonyafa3dfc2012-03-03 11:31:30 +00002919 if (LocaleCompare("random-threshold",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002920 {
anthony7bcfe7f2012-03-30 14:01:22 +00002921 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00002922 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002923 (void) RandomThresholdImage(_image,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00002924 break;
2925 }
anthony975a8d72012-04-12 13:54:36 +00002926 if (LocaleCompare("recolor",option+1) == 0)
2927 {
anthony464f1c42012-04-22 08:51:01 +00002928 CLIWandWarnReplaced("-color-matrix");
anthony975a8d72012-04-12 13:54:36 +00002929 CLISimpleOperatorImage(cli_wand,"-color-matrix",arg1,NULL);
2930 }
anthonyafa3dfc2012-03-03 11:31:30 +00002931 if (LocaleCompare("remap",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002932 {
2933 Image
2934 *remap_image;
2935
anthony92c93bd2012-03-19 14:02:47 +00002936 remap_image=GetImageCache(_image_info,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00002937 if (remap_image == (Image *) NULL)
2938 break;
anthony92c93bd2012-03-19 14:02:47 +00002939 (void) RemapImage(_quantize_info,_image,remap_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002940 remap_image=DestroyImage(remap_image);
2941 break;
2942 }
anthonyafa3dfc2012-03-03 11:31:30 +00002943 if (LocaleCompare("repage",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002944 {
anthonyafa3dfc2012-03-03 11:31:30 +00002945 if (IfNormalOp)
cristy0d0de742012-03-25 19:32:48 +00002946 {
anthony7bcfe7f2012-03-30 14:01:22 +00002947 if (IfMagickFalse(IsGeometry(arg1)))
cristy0d0de742012-03-25 19:32:48 +00002948 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,
2949 arg1);
2950 (void) ResetImagePage(_image,arg1);
2951 }
anthony31f1bf72012-01-30 12:37:22 +00002952 else
anthony92c93bd2012-03-19 14:02:47 +00002953 (void) ParseAbsoluteGeometry("0x0+0+0",&_image->page);
anthony805a2d42011-09-25 08:25:12 +00002954 break;
2955 }
anthonyafa3dfc2012-03-03 11:31:30 +00002956 if (LocaleCompare("resample",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002957 {
anthonyf46d4262012-03-26 03:30:34 +00002958 /* FUTURE: Roll into a resize special operation */
anthonyfd706f92012-01-19 04:22:02 +00002959 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00002960 if ((flags & (RhoValue|SigmaValue)) == 0)
2961 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00002962 if ((flags & SigmaValue) == 0)
2963 geometry_info.sigma=geometry_info.rho;
anthony92c93bd2012-03-19 14:02:47 +00002964 new_image=ResampleImage(_image,geometry_info.rho,
cristyaa2c16c2012-03-25 22:21:35 +00002965 geometry_info.sigma,_image->filter,_exception);
anthony805a2d42011-09-25 08:25:12 +00002966 break;
2967 }
anthonyafa3dfc2012-03-03 11:31:30 +00002968 if (LocaleCompare("resize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002969 {
anthony7bcfe7f2012-03-30 14:01:22 +00002970 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00002971 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002972 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
2973 new_image=ResizeImage(_image,geometry.width,geometry.height,
cristyaa2c16c2012-03-25 22:21:35 +00002974 _image->filter,_exception);
anthony805a2d42011-09-25 08:25:12 +00002975 break;
2976 }
anthonyafa3dfc2012-03-03 11:31:30 +00002977 if (LocaleCompare("roll",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002978 {
anthony7bcfe7f2012-03-30 14:01:22 +00002979 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00002980 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002981 (void) ParsePageGeometry(_image,arg1,&geometry,_exception);
2982 new_image=RollImage(_image,geometry.x,geometry.y,_exception);
anthony805a2d42011-09-25 08:25:12 +00002983 break;
2984 }
anthonyafa3dfc2012-03-03 11:31:30 +00002985 if (LocaleCompare("rotate",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002986 {
anthony22de2722012-04-19 14:43:00 +00002987 flags=ParseGeometry(arg1,&geometry_info);
2988 if ((flags & RhoValue) == 0)
anthonyf42014d2012-03-25 09:53:06 +00002989 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyad255a02012-04-19 15:02:01 +00002990 if ((flags & GreaterValue) != 0 && (_image->columns <= _image->rows))
anthony22de2722012-04-19 14:43:00 +00002991 break;
2992 if ((flags & LessValue) != 0 && (_image->columns >= _image->rows))
2993 break;
anthony92c93bd2012-03-19 14:02:47 +00002994 new_image=RotateImage(_image,geometry_info.rho,_exception);
anthony805a2d42011-09-25 08:25:12 +00002995 break;
2996 }
anthonyebb73a22012-03-22 14:25:52 +00002997 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002998 }
2999 case 's':
3000 {
anthonyafa3dfc2012-03-03 11:31:30 +00003001 if (LocaleCompare("sample",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003002 {
anthonyfe1aa782012-03-24 13:43:04 +00003003 /* FUTURE: Roll into a resize special operator */
anthony7bcfe7f2012-03-30 14:01:22 +00003004 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003005 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003006 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
3007 new_image=SampleImage(_image,geometry.width,geometry.height,
3008 _exception);
anthony805a2d42011-09-25 08:25:12 +00003009 break;
3010 }
anthonyafa3dfc2012-03-03 11:31:30 +00003011 if (LocaleCompare("scale",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003012 {
anthonyfe1aa782012-03-24 13:43:04 +00003013 /* FUTURE: Roll into a resize special operator */
anthony7bcfe7f2012-03-30 14:01:22 +00003014 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003015 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003016 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
3017 new_image=ScaleImage(_image,geometry.width,geometry.height,
3018 _exception);
anthony805a2d42011-09-25 08:25:12 +00003019 break;
3020 }
anthonyf42014d2012-03-25 09:53:06 +00003021 if (LocaleCompare("segment",option+1) == 0)
3022 {
anthonyf42014d2012-03-25 09:53:06 +00003023 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00003024 if ((flags & (RhoValue|SigmaValue)) == 0)
3025 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyf42014d2012-03-25 09:53:06 +00003026 if ((flags & SigmaValue) == 0)
3027 geometry_info.sigma=1.0;
3028 (void) SegmentImage(_image,_image->colorspace,
3029 _image_info->verbose,geometry_info.rho,geometry_info.sigma,
3030 _exception);
3031 break;
3032 }
anthonyafa3dfc2012-03-03 11:31:30 +00003033 if (LocaleCompare("selective-blur",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003034 {
anthonyfd706f92012-01-19 04:22:02 +00003035 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00003036 if ((flags & (RhoValue|SigmaValue)) == 0)
3037 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3038 if ((flags & SigmaValue) == 0)
3039 geometry_info.sigma=1.0;
anthony805a2d42011-09-25 08:25:12 +00003040 if ((flags & PercentValue) != 0)
3041 geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
anthony92c93bd2012-03-19 14:02:47 +00003042 new_image=SelectiveBlurImage(_image,geometry_info.rho,
cristyaa2c16c2012-03-25 22:21:35 +00003043 geometry_info.sigma,geometry_info.xi,_exception);
anthony805a2d42011-09-25 08:25:12 +00003044 break;
3045 }
anthonyafa3dfc2012-03-03 11:31:30 +00003046 if (LocaleCompare("separate",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003047 {
anthony31f1bf72012-01-30 12:37:22 +00003048 /* WARNING: This can generate multiple images! */
anthony43f425d2012-02-26 12:58:58 +00003049 /* FUTURE - this may be replaced by a "-channel" method */
cristydfdb19e2012-03-21 22:22:24 +00003050 new_image=SeparateImages(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00003051 break;
3052 }
anthonyafa3dfc2012-03-03 11:31:30 +00003053 if (LocaleCompare("sepia-tone",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003054 {
anthony7bcfe7f2012-03-30 14:01:22 +00003055 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003056 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3057 new_image=SepiaToneImage(_image,StringToDoubleInterval(arg1,
3058 (double) QuantumRange+1.0),_exception);
anthony805a2d42011-09-25 08:25:12 +00003059 break;
3060 }
anthonyafa3dfc2012-03-03 11:31:30 +00003061 if (LocaleCompare("set",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003062 {
3063 char
3064 *value;
3065
anthonyf42014d2012-03-25 09:53:06 +00003066 if (IfPlusOp) {
anthonyfd706f92012-01-19 04:22:02 +00003067 if (LocaleNCompare(arg1,"registry:",9) == 0)
3068 (void) DeleteImageRegistry(arg1+9);
anthony805a2d42011-09-25 08:25:12 +00003069 else
anthony31f1bf72012-01-30 12:37:22 +00003070 if (LocaleNCompare(arg1,"option:",7) == 0)
anthony805a2d42011-09-25 08:25:12 +00003071 {
anthony92c93bd2012-03-19 14:02:47 +00003072 (void) DeleteImageOption(_image_info,arg1+7);
3073 (void) DeleteImageArtifact(_image,arg1+7);
anthony805a2d42011-09-25 08:25:12 +00003074 }
3075 else
anthony92c93bd2012-03-19 14:02:47 +00003076 (void) DeleteImageProperty(_image,arg1);
anthony805a2d42011-09-25 08:25:12 +00003077 break;
3078 }
anthonyf42014d2012-03-25 09:53:06 +00003079 value=InterpretImageProperties(_image_info,_image,arg2,_exception);
anthony805a2d42011-09-25 08:25:12 +00003080 if (value == (char *) NULL)
anthony964d28e2012-05-17 23:39:46 +00003081 CLIWandExceptionBreak(OptionWarning,"InterpretPropertyFailure",
3082 option);
anthonyfd706f92012-01-19 04:22:02 +00003083 if (LocaleNCompare(arg1,"registry:",9) == 0)
anthonyf42014d2012-03-25 09:53:06 +00003084 (void) SetImageRegistry(StringRegistryType,arg1+9,value,_exception);
anthony805a2d42011-09-25 08:25:12 +00003085 else
anthonyfd706f92012-01-19 04:22:02 +00003086 if (LocaleNCompare(arg1,"option:",7) == 0)
anthony805a2d42011-09-25 08:25:12 +00003087 {
anthony92c93bd2012-03-19 14:02:47 +00003088 (void) SetImageOption(_image_info,arg1+7,value);
3089 (void) SetImageArtifact(_image,arg1+7,value);
anthony805a2d42011-09-25 08:25:12 +00003090 }
3091 else
anthony92c93bd2012-03-19 14:02:47 +00003092 (void) SetImageProperty(_image,arg1,value,_exception);
anthony805a2d42011-09-25 08:25:12 +00003093 value=DestroyString(value);
3094 break;
3095 }
anthonyafa3dfc2012-03-03 11:31:30 +00003096 if (LocaleCompare("shade",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003097 {
anthonyfd706f92012-01-19 04:22:02 +00003098 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00003099 if (((flags & RhoValue) == 0) || ((flags & SigmaValue) == 0))
3100 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003101 new_image=ShadeImage(_image,normal_op,geometry_info.rho,
3102 geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00003103 break;
3104 }
anthonyafa3dfc2012-03-03 11:31:30 +00003105 if (LocaleCompare("shadow",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003106 {
anthonyfd706f92012-01-19 04:22:02 +00003107 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00003108 if ((flags & (RhoValue|SigmaValue)) == 0)
3109 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00003110 if ((flags & SigmaValue) == 0)
3111 geometry_info.sigma=1.0;
3112 if ((flags & XiValue) == 0)
3113 geometry_info.xi=4.0;
3114 if ((flags & PsiValue) == 0)
3115 geometry_info.psi=4.0;
cristyaa2c16c2012-03-25 22:21:35 +00003116 new_image=ShadowImage(_image,geometry_info.rho,geometry_info.sigma,
3117 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
3118 ceil(geometry_info.psi-0.5),_exception);
anthony805a2d42011-09-25 08:25:12 +00003119 break;
3120 }
anthonyafa3dfc2012-03-03 11:31:30 +00003121 if (LocaleCompare("sharpen",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003122 {
anthonyfd706f92012-01-19 04:22:02 +00003123 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00003124 if ((flags & (RhoValue|SigmaValue)) == 0)
3125 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00003126 if ((flags & SigmaValue) == 0)
3127 geometry_info.sigma=1.0;
3128 if ((flags & XiValue) == 0)
3129 geometry_info.xi=0.0;
cristyaa2c16c2012-03-25 22:21:35 +00003130 new_image=SharpenImage(_image,geometry_info.rho,geometry_info.sigma,
3131 _exception);
anthony805a2d42011-09-25 08:25:12 +00003132 break;
3133 }
anthonyafa3dfc2012-03-03 11:31:30 +00003134 if (LocaleCompare("shave",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003135 {
anthony7bcfe7f2012-03-30 14:01:22 +00003136 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003137 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003138 flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
3139 new_image=ShaveImage(_image,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00003140 break;
3141 }
anthonyafa3dfc2012-03-03 11:31:30 +00003142 if (LocaleCompare("shear",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003143 {
anthonyfd706f92012-01-19 04:22:02 +00003144 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00003145 if ((flags & RhoValue) == 0)
3146 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00003147 if ((flags & SigmaValue) == 0)
3148 geometry_info.sigma=geometry_info.rho;
anthony92c93bd2012-03-19 14:02:47 +00003149 new_image=ShearImage(_image,geometry_info.rho,
3150 geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00003151 break;
3152 }
anthonyafa3dfc2012-03-03 11:31:30 +00003153 if (LocaleCompare("sigmoidal-contrast",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003154 {
anthonyfd706f92012-01-19 04:22:02 +00003155 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00003156 if ((flags & RhoValue) == 0)
3157 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00003158 if ((flags & SigmaValue) == 0)
3159 geometry_info.sigma=(double) QuantumRange/2.0;
3160 if ((flags & PercentValue) != 0)
3161 geometry_info.sigma=(double) QuantumRange*geometry_info.sigma/
3162 100.0;
anthony92c93bd2012-03-19 14:02:47 +00003163 (void) SigmoidalContrastImage(_image,normal_op,geometry_info.rho,
anthonyb1d483a2012-04-14 12:53:56 +00003164 geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00003165 break;
3166 }
anthonyafa3dfc2012-03-03 11:31:30 +00003167 if (LocaleCompare("sketch",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003168 {
anthonyfd706f92012-01-19 04:22:02 +00003169 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00003170 if ((flags & (RhoValue|SigmaValue)) == 0)
3171 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00003172 if ((flags & SigmaValue) == 0)
3173 geometry_info.sigma=1.0;
anthony92c93bd2012-03-19 14:02:47 +00003174 new_image=SketchImage(_image,geometry_info.rho,
cristyaa2c16c2012-03-25 22:21:35 +00003175 geometry_info.sigma,geometry_info.xi,_exception);
anthony805a2d42011-09-25 08:25:12 +00003176 break;
3177 }
anthonyafa3dfc2012-03-03 11:31:30 +00003178 if (LocaleCompare("solarize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003179 {
anthony7bcfe7f2012-03-30 14:01:22 +00003180 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003181 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003182 (void) SolarizeImage(_image,StringToDoubleInterval(arg1,(double)
3183 QuantumRange+1.0),_exception);
anthony805a2d42011-09-25 08:25:12 +00003184 break;
3185 }
anthonyafa3dfc2012-03-03 11:31:30 +00003186 if (LocaleCompare("sparse-color",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003187 {
anthonyf42014d2012-03-25 09:53:06 +00003188 parse= ParseCommandOption(MagickSparseColorOptions,MagickFalse,arg1);
3189 if ( parse < 0 )
3190 CLIWandExceptArgBreak(OptionError,"UnrecognizedSparseColorMethod",
3191 option,arg1);
anthony964d28e2012-05-17 23:39:46 +00003192 new_image=SparseColorOption(_image,(SparseColorMethod)parse,arg2,
3193 _exception);
anthony805a2d42011-09-25 08:25:12 +00003194 break;
3195 }
anthonyafa3dfc2012-03-03 11:31:30 +00003196 if (LocaleCompare("splice",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003197 {
anthony7bcfe7f2012-03-30 14:01:22 +00003198 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003199 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyb1e21ed2012-04-20 12:43:12 +00003200 flags=ParseGravityGeometry(_image,arg1,&geometry,_exception);
anthony92c93bd2012-03-19 14:02:47 +00003201 new_image=SpliceImage(_image,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00003202 break;
3203 }
anthonyafa3dfc2012-03-03 11:31:30 +00003204 if (LocaleCompare("spread",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003205 {
anthonyb1e21ed2012-04-20 12:43:12 +00003206 flags=ParseGeometry(arg1,&geometry_info);
3207 if ((flags & RhoValue) == 0)
3208 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
anthony92c93bd2012-03-19 14:02:47 +00003209 new_image=SpreadImage(_image,geometry_info.rho,_image->interpolate,
3210 _exception);
anthony805a2d42011-09-25 08:25:12 +00003211 break;
3212 }
anthonyafa3dfc2012-03-03 11:31:30 +00003213 if (LocaleCompare("statistic",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003214 {
anthony7bc87992012-03-25 02:32:51 +00003215 parse=ParseCommandOption(MagickStatisticOptions,MagickFalse,arg1);
3216 if ( parse < 0 )
anthonyf42014d2012-03-25 09:53:06 +00003217 CLIWandExceptArgBreak(OptionError,"UnrecognizedStatisticType",
anthony7bc87992012-03-25 02:32:51 +00003218 option,arg1);
anthony975a8d72012-04-12 13:54:36 +00003219 flags=ParseGeometry(arg2,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00003220 if ((flags & RhoValue) == 0)
3221 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
anthony975a8d72012-04-12 13:54:36 +00003222 if ((flags & SigmaValue) == 0)
3223 geometry_info.sigma=geometry_info.rho;
anthony7bc87992012-03-25 02:32:51 +00003224 new_image=StatisticImage(_image,(StatisticType)parse,
3225 (size_t) geometry_info.rho,(size_t) geometry_info.sigma,
3226 _exception);
anthony805a2d42011-09-25 08:25:12 +00003227 break;
3228 }
anthonyafa3dfc2012-03-03 11:31:30 +00003229 if (LocaleCompare("strip",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003230 {
anthony92c93bd2012-03-19 14:02:47 +00003231 (void) StripImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00003232 break;
3233 }
anthonyafa3dfc2012-03-03 11:31:30 +00003234 if (LocaleCompare("swirl",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003235 {
anthonyb1e21ed2012-04-20 12:43:12 +00003236 flags=ParseGeometry(arg2,&geometry_info);
3237 if ((flags & RhoValue) == 0)
3238 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
anthony92c93bd2012-03-19 14:02:47 +00003239 new_image=SwirlImage(_image,geometry_info.rho,
3240 _image->interpolate,_exception);
anthony805a2d42011-09-25 08:25:12 +00003241 break;
3242 }
anthonyebb73a22012-03-22 14:25:52 +00003243 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003244 }
3245 case 't':
3246 {
anthonyafa3dfc2012-03-03 11:31:30 +00003247 if (LocaleCompare("threshold",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003248 {
3249 double
3250 threshold;
3251
anthony52bef752012-03-27 13:54:47 +00003252 threshold=(double) QuantumRange/2;
3253 if (normal_op) {
anthony7bcfe7f2012-03-30 14:01:22 +00003254 if (IfMagickFalse(IsGeometry(arg1)))
anthony52bef752012-03-27 13:54:47 +00003255 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00003256 threshold=StringToDoubleInterval(arg1,(double) QuantumRange+1.0);
anthony52bef752012-03-27 13:54:47 +00003257 }
anthony92c93bd2012-03-19 14:02:47 +00003258 (void) BilevelImage(_image,threshold,_exception);
anthony805a2d42011-09-25 08:25:12 +00003259 break;
3260 }
anthonyafa3dfc2012-03-03 11:31:30 +00003261 if (LocaleCompare("thumbnail",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003262 {
anthony7bcfe7f2012-03-30 14:01:22 +00003263 if (IfMagickFalse(IsGeometry(arg1)))
anthony52bef752012-03-27 13:54:47 +00003264 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003265 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
3266 new_image=ThumbnailImage(_image,geometry.width,geometry.height,
3267 _exception);
anthony805a2d42011-09-25 08:25:12 +00003268 break;
3269 }
anthonyafa3dfc2012-03-03 11:31:30 +00003270 if (LocaleCompare("tint",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003271 {
anthony7bcfe7f2012-03-30 14:01:22 +00003272 if (IfMagickFalse(IsGeometry(arg1)))
anthony52bef752012-03-27 13:54:47 +00003273 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003274 new_image=TintImage(_image,arg1,&_draw_info->fill,_exception);
anthony805a2d42011-09-25 08:25:12 +00003275 break;
3276 }
anthonyafa3dfc2012-03-03 11:31:30 +00003277 if (LocaleCompare("transform",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003278 {
anthony464f1c42012-04-22 08:51:01 +00003279 CLIWandWarnReplaced("+distort AffineProjection");
anthony52bef752012-03-27 13:54:47 +00003280 new_image=AffineTransformImage(_image,&_draw_info->affine,_exception);
anthony805a2d42011-09-25 08:25:12 +00003281 break;
3282 }
anthonyafa3dfc2012-03-03 11:31:30 +00003283 if (LocaleCompare("transparent",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003284 {
3285 PixelInfo
3286 target;
3287
anthony92c93bd2012-03-19 14:02:47 +00003288 (void) QueryColorCompliance(arg1,AllCompliance,&target,_exception);
3289 (void) TransparentPaintImage(_image,&target,(Quantum)
3290 TransparentAlpha,plus_alt_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00003291 break;
3292 }
anthonyafa3dfc2012-03-03 11:31:30 +00003293 if (LocaleCompare("transpose",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003294 {
anthony92c93bd2012-03-19 14:02:47 +00003295 new_image=TransposeImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00003296 break;
3297 }
anthonyafa3dfc2012-03-03 11:31:30 +00003298 if (LocaleCompare("transverse",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003299 {
anthony92c93bd2012-03-19 14:02:47 +00003300 new_image=TransverseImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00003301 break;
3302 }
anthonyafa3dfc2012-03-03 11:31:30 +00003303 if (LocaleCompare("trim",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003304 {
anthony92c93bd2012-03-19 14:02:47 +00003305 new_image=TrimImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00003306 break;
3307 }
anthonyafa3dfc2012-03-03 11:31:30 +00003308 if (LocaleCompare("type",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003309 {
anthonyab3a50c2011-10-27 11:48:57 +00003310 /* Note that "type" setting should have already been defined */
anthony92c93bd2012-03-19 14:02:47 +00003311 (void) SetImageType(_image,_image_info->type,_exception);
anthony805a2d42011-09-25 08:25:12 +00003312 break;
3313 }
anthonyebb73a22012-03-22 14:25:52 +00003314 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003315 }
3316 case 'u':
3317 {
anthonyafa3dfc2012-03-03 11:31:30 +00003318 if (LocaleCompare("unique",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003319 {
anthony52bef752012-03-27 13:54:47 +00003320 /* FUTURE: move to SyncImageSettings() and AcqireImage()???
3321 Option is not documented, bt appears to be for "identify".
3322 We may need a identify specific verbose!
3323 */
3324 if (plus_alt_op) {
anthony92c93bd2012-03-19 14:02:47 +00003325 (void) DeleteImageArtifact(_image,"identify:unique-colors");
anthony805a2d42011-09-25 08:25:12 +00003326 break;
3327 }
anthony92c93bd2012-03-19 14:02:47 +00003328 (void) SetImageArtifact(_image,"identify:unique-colors","true");
3329 (void) SetImageArtifact(_image,"verbose","true");
anthony805a2d42011-09-25 08:25:12 +00003330 break;
3331 }
anthonyafa3dfc2012-03-03 11:31:30 +00003332 if (LocaleCompare("unique-colors",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003333 {
anthony92c93bd2012-03-19 14:02:47 +00003334 new_image=UniqueImageColors(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00003335 break;
3336 }
anthonyafa3dfc2012-03-03 11:31:30 +00003337 if (LocaleCompare("unsharp",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003338 {
anthonyfd706f92012-01-19 04:22:02 +00003339 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00003340 if ((flags & (RhoValue|SigmaValue)) == 0)
3341 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00003342 if ((flags & SigmaValue) == 0)
3343 geometry_info.sigma=1.0;
3344 if ((flags & XiValue) == 0)
3345 geometry_info.xi=1.0;
3346 if ((flags & PsiValue) == 0)
3347 geometry_info.psi=0.05;
anthony92c93bd2012-03-19 14:02:47 +00003348 new_image=UnsharpMaskImage(_image,geometry_info.rho,
3349 geometry_info.sigma,geometry_info.xi,geometry_info.psi,_exception);
anthony805a2d42011-09-25 08:25:12 +00003350 break;
3351 }
anthonyebb73a22012-03-22 14:25:52 +00003352 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003353 }
3354 case 'v':
3355 {
anthonyafa3dfc2012-03-03 11:31:30 +00003356 if (LocaleCompare("verbose",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003357 {
anthonyafa3dfc2012-03-03 11:31:30 +00003358 /* FUTURE: move to SyncImageSettings() and AcquireImage()???
anthony92c93bd2012-03-19 14:02:47 +00003359 three places! ImageArtifact ImageOption _image_info->verbose
anthony5330ae02012-03-20 14:17:01 +00003360 Some how new images also get this artifact!
anthony31f1bf72012-01-30 12:37:22 +00003361 */
anthony92c93bd2012-03-19 14:02:47 +00003362 (void) SetImageArtifact(_image,option+1,
anthonyafa3dfc2012-03-03 11:31:30 +00003363 IfNormalOp ? "true" : "false" );
anthony805a2d42011-09-25 08:25:12 +00003364 break;
3365 }
anthonyafa3dfc2012-03-03 11:31:30 +00003366 if (LocaleCompare("vignette",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003367 {
anthonyfd706f92012-01-19 04:22:02 +00003368 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00003369 if ((flags & (RhoValue|SigmaValue)) == 0)
3370 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00003371 if ((flags & SigmaValue) == 0)
3372 geometry_info.sigma=1.0;
3373 if ((flags & XiValue) == 0)
anthony92c93bd2012-03-19 14:02:47 +00003374 geometry_info.xi=0.1*_image->columns;
anthony805a2d42011-09-25 08:25:12 +00003375 if ((flags & PsiValue) == 0)
anthony92c93bd2012-03-19 14:02:47 +00003376 geometry_info.psi=0.1*_image->rows;
3377 new_image=VignetteImage(_image,geometry_info.rho,geometry_info.sigma,
cristyaa2c16c2012-03-25 22:21:35 +00003378 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
3379 ceil(geometry_info.psi-0.5),_exception);
anthony805a2d42011-09-25 08:25:12 +00003380 break;
3381 }
anthonyebb73a22012-03-22 14:25:52 +00003382 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003383 }
3384 case 'w':
3385 {
anthonyafa3dfc2012-03-03 11:31:30 +00003386 if (LocaleCompare("wave",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003387 {
anthonyfd706f92012-01-19 04:22:02 +00003388 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00003389 if ((flags & (RhoValue|SigmaValue)) == 0)
3390 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00003391 if ((flags & SigmaValue) == 0)
3392 geometry_info.sigma=1.0;
anthony92c93bd2012-03-19 14:02:47 +00003393 new_image=WaveImage(_image,geometry_info.rho,geometry_info.sigma,
3394 _image->interpolate,_exception);
anthony805a2d42011-09-25 08:25:12 +00003395 break;
3396 }
anthonyafa3dfc2012-03-03 11:31:30 +00003397 if (LocaleCompare("white-threshold",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003398 {
anthony7bcfe7f2012-03-30 14:01:22 +00003399 if (IfMagickFalse(IsGeometry(arg1)))
anthony52bef752012-03-27 13:54:47 +00003400 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003401 (void) WhiteThresholdImage(_image,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00003402 break;
3403 }
anthonyebb73a22012-03-22 14:25:52 +00003404 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003405 }
3406 default:
anthonyebb73a22012-03-22 14:25:52 +00003407 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003408 }
anthony964d28e2012-05-17 23:39:46 +00003409 /* clean up percent escape interpreted strings */
3410 if (arg1 != arg1n )
3411 arg1=DestroyString((char *)arg1);
3412 if (arg2 != arg2n )
3413 arg2=DestroyString((char *)arg2);
3414
3415 /* Replace current image with any image that was generated
3416 and set image point to last image (so image->next is correct) */
anthony805a2d42011-09-25 08:25:12 +00003417 if (new_image != (Image *) NULL)
anthony92c93bd2012-03-19 14:02:47 +00003418 ReplaceImageInListReturnLast(&_image,new_image);
anthony805a2d42011-09-25 08:25:12 +00003419
anthony31f1bf72012-01-30 12:37:22 +00003420 return;
anthony92c93bd2012-03-19 14:02:47 +00003421#undef _image_info
3422#undef _draw_info
3423#undef _quantize_info
3424#undef _image
3425#undef _exception
anthonyafa3dfc2012-03-03 11:31:30 +00003426#undef IfNormalOp
3427#undef IfPlusOp
anthony31f1bf72012-01-30 12:37:22 +00003428#undef normal_op
anthonyafa3dfc2012-03-03 11:31:30 +00003429#undef plus_alt_op
anthony31f1bf72012-01-30 12:37:22 +00003430}
anthonyfd706f92012-01-19 04:22:02 +00003431
anthony43f425d2012-02-26 12:58:58 +00003432WandExport void CLISimpleOperatorImages(MagickCLI *cli_wand,
anthonyafa3dfc2012-03-03 11:31:30 +00003433 const char *option, const char *arg1, const char *arg2)
anthony31f1bf72012-01-30 12:37:22 +00003434{
3435 size_t
anthony43f425d2012-02-26 12:58:58 +00003436 n,
anthony31f1bf72012-01-30 12:37:22 +00003437 i;
3438
anthony43f425d2012-02-26 12:58:58 +00003439 assert(cli_wand != (MagickCLI *) NULL);
3440 assert(cli_wand->signature == WandSignature);
3441 assert(cli_wand->wand.signature == WandSignature);
3442 assert(cli_wand->wand.images != (Image *) NULL); /* images must be present */
anthony7bcfe7f2012-03-30 14:01:22 +00003443 if (IfMagickTrue(cli_wand->wand.debug))
anthony43f425d2012-02-26 12:58:58 +00003444 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
anthony31f1bf72012-01-30 12:37:22 +00003445
anthonyafa3dfc2012-03-03 11:31:30 +00003446#if !USE_WAND_METHODS
3447 /* FUTURE add appropriate tracing */
anthony31f1bf72012-01-30 12:37:22 +00003448 i=0;
anthony43f425d2012-02-26 12:58:58 +00003449 n=GetImageListLength(cli_wand->wand.images);
3450 cli_wand->wand.images=GetFirstImageInList(cli_wand->wand.images);
anthonyafa3dfc2012-03-03 11:31:30 +00003451 while (1) {
anthony31f1bf72012-01-30 12:37:22 +00003452 i++;
anthonyafa3dfc2012-03-03 11:31:30 +00003453 CLISimpleOperatorImage(cli_wand, option, arg1, arg2);
anthony43f425d2012-02-26 12:58:58 +00003454 if ( cli_wand->wand.images->next == (Image *) NULL )
3455 break;
3456 cli_wand->wand.images=cli_wand->wand.images->next;
anthony31f1bf72012-01-30 12:37:22 +00003457 }
anthony43f425d2012-02-26 12:58:58 +00003458 assert( i == n );
3459 cli_wand->wand.images=GetFirstImageInList(cli_wand->wand.images);
anthonyafa3dfc2012-03-03 11:31:30 +00003460#else
3461 MagickResetIterator(&cli_wand->wand);
anthony7bcfe7f2012-03-30 14:01:22 +00003462 while ( IfMagickTrue(MagickNextImage(&cli_wand->wand)) )
anthonyafa3dfc2012-03-03 11:31:30 +00003463 CLISimpleOperatorImage(cli_wand, option, arg1, arg2);
3464 MagickResetIterator(&cli_wand->wand);
3465#endif
anthony31f1bf72012-01-30 12:37:22 +00003466 return;
anthony805a2d42011-09-25 08:25:12 +00003467}
3468
3469/*
3470%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3471% %
3472% %
3473% %
anthony43f425d2012-02-26 12:58:58 +00003474+ C L I L i s t O p e r a t o r I m a g e s %
anthony805a2d42011-09-25 08:25:12 +00003475% %
3476% %
3477% %
3478%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3479%
anthony43f425d2012-02-26 12:58:58 +00003480% CLIListOperatorImages() applies a single operation that is apply to the
anthony31f1bf72012-01-30 12:37:22 +00003481% entire image list as a whole. The result is often a complete replacment
3482% of the image list with a completely new list, or just a single image.
anthony805a2d42011-09-25 08:25:12 +00003483%
3484% The format of the MogrifyImage method is:
3485%
anthony43f425d2012-02-26 12:58:58 +00003486% void CLIListOperatorImages(MagickCLI *cli_wand,
anthonyafa3dfc2012-03-03 11:31:30 +00003487% const char *option, const char *arg1, const char *arg2)
anthony805a2d42011-09-25 08:25:12 +00003488%
3489% A description of each parameter follows:
3490%
anthony43f425d2012-02-26 12:58:58 +00003491% o cli_wand: structure holding settings to be applied
anthony805a2d42011-09-25 08:25:12 +00003492%
anthony36a8c2c2012-02-10 00:08:44 +00003493% o option: The option string for the operation
3494%
anthony31f1bf72012-01-30 12:37:22 +00003495% o arg1, arg2: optional argument strings to the operation
anthonye5fcd362012-04-09 04:02:09 +00003496% arg2 is currently not used
anthony8b10b462012-02-08 12:32:44 +00003497%
anthony805a2d42011-09-25 08:25:12 +00003498*/
anthony43f425d2012-02-26 12:58:58 +00003499WandExport void CLIListOperatorImages(MagickCLI *cli_wand,
anthony964d28e2012-05-17 23:39:46 +00003500 const char *option,const char *arg1n, const char *arg2n)
anthony805a2d42011-09-25 08:25:12 +00003501{
anthony2a0ec8c2012-03-24 04:35:56 +00003502 ssize_t
3503 parse;
3504
anthony31f1bf72012-01-30 12:37:22 +00003505 Image
3506 *new_images;
anthony805a2d42011-09-25 08:25:12 +00003507
anthony964d28e2012-05-17 23:39:46 +00003508 const char /* For percent escape interpretImageProperties() */
3509 *arg1,
3510 *arg2;
3511
anthony2e4501b2012-03-30 04:41:54 +00003512#define _image_info (cli_wand->wand.image_info)
3513#define _images (cli_wand->wand.images)
3514#define _exception (cli_wand->wand.exception)
3515#define _draw_info (cli_wand->draw_info)
3516#define _quantize_info (cli_wand->quantize_info)
anthony964d28e2012-05-17 23:39:46 +00003517#define _process_flags (cli_wand->process_flags)
3518#define _option_type ((CommandOptionFlags) cli_wand->command->flags)
anthonyafa3dfc2012-03-03 11:31:30 +00003519#define IfNormalOp (*option=='-')
3520#define IfPlusOp (*option!='-')
anthony7bcfe7f2012-03-30 14:01:22 +00003521#define normal_op IsMagickTrue(IfNormalOp)
anthony805a2d42011-09-25 08:25:12 +00003522
anthony43f425d2012-02-26 12:58:58 +00003523 assert(cli_wand != (MagickCLI *) NULL);
3524 assert(cli_wand->signature == WandSignature);
3525 assert(cli_wand->wand.signature == WandSignature);
anthony92c93bd2012-03-19 14:02:47 +00003526 assert(_images != (Image *) NULL); /* _images must be present */
anthony7bcfe7f2012-03-30 14:01:22 +00003527 if (IfMagickTrue(cli_wand->wand.debug))
anthony43f425d2012-02-26 12:58:58 +00003528 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
anthony31f1bf72012-01-30 12:37:22 +00003529
anthony964d28e2012-05-17 23:39:46 +00003530 /* Interpret Percent Escapes in Arguments - using first image */
3531 arg1 = arg1n;
3532 arg2 = arg2n;
3533 if ( (((_process_flags & ProcessInterpretProperities) != 0 )
3534 || ((_option_type & AlwaysInterpretArgsFlag) != 0)
3535 ) && ((_option_type & NeverInterpretArgsFlag) == 0) ) {
3536 /* Interpret Percent escapes in argument 1 */
3537 if (arg1n != (char *) NULL) {
3538 arg1=InterpretImageProperties(_image_info,_images,arg1n,_exception);
3539 if (arg1 == (char *) NULL) {
3540 CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
3541 arg1=arg1n; /* use the given argument as is */
3542 }
3543 }
3544 if (arg2n != (char *) NULL) {
3545 arg2=InterpretImageProperties(_image_info,_images,arg2n,_exception);
3546 if (arg2 == (char *) NULL) {
3547 CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
3548 arg2=arg2n; /* use the given argument as is */
3549 }
3550 }
3551 }
3552#undef _option_type
3553
3554#if 0
3555 (void) FormatLocaleFile(stderr,
3556 "CLIListOperatorImages: \"%s\" \"%s\" \"%s\"\n",option,arg1,arg2);
3557#endif
3558
3559
anthony31f1bf72012-01-30 12:37:22 +00003560 new_images=NewImageList();
3561
anthonyafa3dfc2012-03-03 11:31:30 +00003562 switch (*(option+1))
anthony805a2d42011-09-25 08:25:12 +00003563 {
3564 case 'a':
3565 {
anthonyafa3dfc2012-03-03 11:31:30 +00003566 if (LocaleCompare("append",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003567 {
anthony92c93bd2012-03-19 14:02:47 +00003568 new_images=AppendImages(_images,normal_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00003569 break;
3570 }
anthonyafa3dfc2012-03-03 11:31:30 +00003571 if (LocaleCompare("average",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003572 {
anthony464f1c42012-04-22 08:51:01 +00003573 CLIWandWarnReplaced("-evaluate-sequence Mean");
anthonyafa3dfc2012-03-03 11:31:30 +00003574 CLIListOperatorImages(cli_wand,"-evaluate-sequence","Mean",NULL);
anthony805a2d42011-09-25 08:25:12 +00003575 break;
3576 }
anthonyebb73a22012-03-22 14:25:52 +00003577 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003578 }
3579 case 'c':
3580 {
cristy5f257b22012-03-07 00:27:29 +00003581 if (LocaleCompare("channel-fx",option+1) == 0)
cristy87c02f42012-02-24 00:19:10 +00003582 {
anthony92c93bd2012-03-19 14:02:47 +00003583 new_images=ChannelFxImage(_images,arg1,_exception);
cristy87c02f42012-02-24 00:19:10 +00003584 break;
3585 }
anthonyafa3dfc2012-03-03 11:31:30 +00003586 if (LocaleCompare("clut",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003587 {
anthony805a2d42011-09-25 08:25:12 +00003588 Image
anthony31f1bf72012-01-30 12:37:22 +00003589 *clut_image;
anthony805a2d42011-09-25 08:25:12 +00003590
anthonyafa3dfc2012-03-03 11:31:30 +00003591 /* FUTURE - make this a compose option, and thus can be used
3592 with layers compose or even compose last image over all other
anthony92c93bd2012-03-19 14:02:47 +00003593 _images.
cristy87c02f42012-02-24 00:19:10 +00003594 */
anthony92c93bd2012-03-19 14:02:47 +00003595 new_images=RemoveFirstImageFromList(&_images);
3596 clut_image=RemoveLastImageFromList(&_images);
anthonye8f56492012-02-12 12:39:02 +00003597 /* FUTURE - produce Exception, rather than silent fail */
anthony805a2d42011-09-25 08:25:12 +00003598 if (clut_image == (Image *) NULL)
cristy87c02f42012-02-24 00:19:10 +00003599 break;
cristye52fb5e2012-04-06 23:30:20 +00003600 (void) ClutImage(new_images,clut_image,new_images->interpolate,_exception);
anthony805a2d42011-09-25 08:25:12 +00003601 clut_image=DestroyImage(clut_image);
anthony805a2d42011-09-25 08:25:12 +00003602 break;
3603 }
anthonyafa3dfc2012-03-03 11:31:30 +00003604 if (LocaleCompare("coalesce",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003605 {
anthony92c93bd2012-03-19 14:02:47 +00003606 new_images=CoalesceImages(_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003607 break;
3608 }
anthonyafa3dfc2012-03-03 11:31:30 +00003609 if (LocaleCompare("combine",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003610 {
anthony43f425d2012-02-26 12:58:58 +00003611 /* FUTURE - this may be replaced by a 'channel' method */
anthony92c93bd2012-03-19 14:02:47 +00003612 new_images=CombineImages(_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003613 break;
3614 }
anthonyafa3dfc2012-03-03 11:31:30 +00003615 if (LocaleCompare("composite",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003616 {
cristyfeb3e962012-03-29 17:25:55 +00003617 CompositeOperator
3618 compose;
3619
3620 const char*
3621 value;
3622
3623 MagickBooleanType
3624 clip_to_self;
3625
anthony805a2d42011-09-25 08:25:12 +00003626 Image
3627 *mask_image,
anthony31f1bf72012-01-30 12:37:22 +00003628 *source_image;
anthony805a2d42011-09-25 08:25:12 +00003629
3630 RectangleInfo
3631 geometry;
3632
anthony7bcfe7f2012-03-30 14:01:22 +00003633 /* Compose value from "-compose" option only */
anthony92c93bd2012-03-19 14:02:47 +00003634 value=GetImageOption(_image_info,"compose");
cristy542a95b2012-04-03 19:30:58 +00003635 if (value == (const char *) NULL)
anthony31f1bf72012-01-30 12:37:22 +00003636 compose=OverCompositeOp; /* use Over not source_image->compose */
cristy542a95b2012-04-03 19:30:58 +00003637 else
3638 compose=(CompositeOperator) ParseCommandOption(MagickComposeOptions,
3639 MagickFalse,value);
anthony5f867ae2011-10-09 10:28:34 +00003640
anthony7bcfe7f2012-03-30 14:01:22 +00003641 /* Get "clip-to-self" expert setting (false is normal) */
cristyca0e82c2012-04-10 11:53:24 +00003642 value=GetImageOption(_image_info,"compose:clip-to-self");
3643 if (value == (const char *) NULL)
3644 clip_to_self=MagickTrue;
3645 else
3646 clip_to_self=IsStringTrue(GetImageOption(_image_info,
3647 "compose:clip-to-self")); /* if this is true */
anthony2e4501b2012-03-30 04:41:54 +00003648 value=GetImageOption(_image_info,"compose:outside-overlay");
anthony7bcfe7f2012-03-30 14:01:22 +00003649 if (value != (const char *) NULL) { /* or this false */
anthony2e4501b2012-03-30 04:41:54 +00003650 /* FUTURE: depreciate warning for "compose:outside-overlay"*/
anthony7bcfe7f2012-03-30 14:01:22 +00003651 clip_to_self= IsMagickFalse(IsStringNotFalse(value));
anthony2e4501b2012-03-30 04:41:54 +00003652 }
3653
anthony92c93bd2012-03-19 14:02:47 +00003654 new_images=RemoveFirstImageFromList(&_images);
3655 source_image=RemoveFirstImageFromList(&_images);
anthony31f1bf72012-01-30 12:37:22 +00003656 if (source_image == (Image *) NULL)
anthony7bcfe7f2012-03-30 14:01:22 +00003657 break; /* FUTURE - produce Exception, rather than silent fail */
anthonye8f56492012-02-12 12:39:02 +00003658
anthony31f1bf72012-01-30 12:37:22 +00003659 /* FUTURE - this should not be here! - should be part of -geometry */
3660 (void) TransformImage(&source_image,(char *) NULL,
anthony92c93bd2012-03-19 14:02:47 +00003661 source_image->geometry,_exception);
anthony5f867ae2011-10-09 10:28:34 +00003662
anthony31f1bf72012-01-30 12:37:22 +00003663 SetGeometry(source_image,&geometry);
3664 (void) ParseAbsoluteGeometry(source_image->geometry,&geometry);
3665 GravityAdjustGeometry(new_images->columns,new_images->rows,
3666 new_images->gravity, &geometry);
anthony5f867ae2011-10-09 10:28:34 +00003667
anthony92c93bd2012-03-19 14:02:47 +00003668 mask_image=RemoveFirstImageFromList(&_images);
anthony805a2d42011-09-25 08:25:12 +00003669 if (mask_image != (Image *) NULL)
anthony31f1bf72012-01-30 12:37:22 +00003670 { /* handle a third write mask image */
anthony5f867ae2011-10-09 10:28:34 +00003671 if ((compose == DisplaceCompositeOp) ||
anthony7bcfe7f2012-03-30 14:01:22 +00003672 (compose == DistortCompositeOp)) {
3673 /* Merge Y displacement into X displace/distort map. */
3674 (void) CompositeImage(source_image,mask_image,
3675 CopyGreenCompositeOp,MagickTrue,0,0,_exception);
3676 mask_image=DestroyImage(mask_image);
3677 }
3678 else {
3679 /* Set a blending mask for the composition. */
3680 (void) NegateImage(mask_image,MagickFalse,_exception);
cristy665e18f2012-05-17 12:39:54 +00003681 (void) SetImageMask(source_image,mask_image,_exception);
anthony7bcfe7f2012-03-30 14:01:22 +00003682 mask_image=DestroyImage(mask_image);
3683 }
anthony805a2d42011-09-25 08:25:12 +00003684 }
cristyfeb3e962012-03-29 17:25:55 +00003685 (void) CompositeImage(new_images,source_image,compose,clip_to_self,
3686 geometry.x,geometry.y,_exception);
anthony92c93bd2012-03-19 14:02:47 +00003687 (void) SetImageMask(new_images,(Image *) NULL,_exception);
anthony31f1bf72012-01-30 12:37:22 +00003688 source_image=DestroyImage(source_image);
anthony805a2d42011-09-25 08:25:12 +00003689 break;
3690 }
anthonyebb73a22012-03-22 14:25:52 +00003691 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003692 }
3693 case 'd':
3694 {
anthonyafa3dfc2012-03-03 11:31:30 +00003695 if (LocaleCompare("deconstruct",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003696 {
anthony464f1c42012-04-22 08:51:01 +00003697 CLIWandWarnReplaced("-layer CompareAny");
anthonyafa3dfc2012-03-03 11:31:30 +00003698 CLIListOperatorImages(cli_wand,"-layer","CompareAny",NULL);
anthony805a2d42011-09-25 08:25:12 +00003699 break;
3700 }
anthonyafa3dfc2012-03-03 11:31:30 +00003701 if (LocaleCompare("delete",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003702 {
anthonyafa3dfc2012-03-03 11:31:30 +00003703 if (IfNormalOp)
anthony92c93bd2012-03-19 14:02:47 +00003704 DeleteImages(&_images,arg1,_exception);
anthonyafa3dfc2012-03-03 11:31:30 +00003705 else
anthony92c93bd2012-03-19 14:02:47 +00003706 DeleteImages(&_images,"-1",_exception);
anthony805a2d42011-09-25 08:25:12 +00003707 break;
3708 }
anthonyafa3dfc2012-03-03 11:31:30 +00003709 if (LocaleCompare("duplicate",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003710 {
anthonyafa3dfc2012-03-03 11:31:30 +00003711 if (IfNormalOp)
anthony805a2d42011-09-25 08:25:12 +00003712 {
3713 const char
3714 *p;
3715
3716 size_t
3717 number_duplicates;
3718
anthony7bcfe7f2012-03-30 14:01:22 +00003719 if (IfMagickFalse(IsGeometry(arg1)))
anthonyebb73a22012-03-22 14:25:52 +00003720 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,
3721 arg1);
anthony31f1bf72012-01-30 12:37:22 +00003722 number_duplicates=(size_t) StringToLong(arg1);
3723 p=strchr(arg1,',');
anthony805a2d42011-09-25 08:25:12 +00003724 if (p == (const char *) NULL)
anthonyebb73a22012-03-22 14:25:52 +00003725 new_images=DuplicateImages(_images,number_duplicates,"-1",
3726 _exception);
anthony805a2d42011-09-25 08:25:12 +00003727 else
anthony92c93bd2012-03-19 14:02:47 +00003728 new_images=DuplicateImages(_images,number_duplicates,p,
3729 _exception);
anthony805a2d42011-09-25 08:25:12 +00003730 }
anthonyafa3dfc2012-03-03 11:31:30 +00003731 else
anthony92c93bd2012-03-19 14:02:47 +00003732 new_images=DuplicateImages(_images,1,"-1",_exception);
3733 AppendImageToList(&_images, new_images);
anthony36a8c2c2012-02-10 00:08:44 +00003734 new_images=(Image *)NULL;
anthony805a2d42011-09-25 08:25:12 +00003735 break;
3736 }
anthonyebb73a22012-03-22 14:25:52 +00003737 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003738 }
3739 case 'e':
3740 {
anthonyafa3dfc2012-03-03 11:31:30 +00003741 if (LocaleCompare("evaluate-sequence",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003742 {
anthony2a0ec8c2012-03-24 04:35:56 +00003743 parse = ParseCommandOption(MagickEvaluateOptions,MagickFalse,arg1);
3744 if ( parse < 0 )
3745 CLIWandExceptArgBreak(OptionError,"UnrecognizedEvaluateOperator",
3746 option,arg1);
3747 new_images=EvaluateImages(_images,(MagickEvaluateOperator)parse,
3748 _exception);
anthony805a2d42011-09-25 08:25:12 +00003749 break;
3750 }
anthonyebb73a22012-03-22 14:25:52 +00003751 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003752 }
3753 case 'f':
3754 {
anthonyafa3dfc2012-03-03 11:31:30 +00003755 if (LocaleCompare("fft",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003756 {
anthony92c93bd2012-03-19 14:02:47 +00003757 new_images=ForwardFourierTransformImage(_images,normal_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00003758 break;
3759 }
anthonyafa3dfc2012-03-03 11:31:30 +00003760 if (LocaleCompare("flatten",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003761 {
anthony319dac62012-03-06 04:12:44 +00003762 /* REDIRECTED to use -layers flatten instead */
anthony2e4501b2012-03-30 04:41:54 +00003763 CLIListOperatorImages(cli_wand,"-layers",option+1,NULL);
anthony805a2d42011-09-25 08:25:12 +00003764 break;
3765 }
anthonyafa3dfc2012-03-03 11:31:30 +00003766 if (LocaleCompare("fx",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003767 {
anthony92c93bd2012-03-19 14:02:47 +00003768 new_images=FxImage(_images,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00003769 break;
3770 }
anthonyebb73a22012-03-22 14:25:52 +00003771 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003772 }
3773 case 'h':
3774 {
anthonyafa3dfc2012-03-03 11:31:30 +00003775 if (LocaleCompare("hald-clut",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003776 {
anthony31f1bf72012-01-30 12:37:22 +00003777 /* FUTURE - make this a compose option (and thus layers compose )
anthony92c93bd2012-03-19 14:02:47 +00003778 or perhaps compose last image over all other _images.
anthony31f1bf72012-01-30 12:37:22 +00003779 */
anthony805a2d42011-09-25 08:25:12 +00003780 Image
anthony31f1bf72012-01-30 12:37:22 +00003781 *hald_image;
anthony805a2d42011-09-25 08:25:12 +00003782
anthony92c93bd2012-03-19 14:02:47 +00003783 new_images=RemoveFirstImageFromList(&_images);
3784 hald_image=RemoveLastImageFromList(&_images);
anthony805a2d42011-09-25 08:25:12 +00003785 if (hald_image == (Image *) NULL)
anthony31f1bf72012-01-30 12:37:22 +00003786 break;
anthony92c93bd2012-03-19 14:02:47 +00003787 (void) HaldClutImage(new_images,hald_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00003788 hald_image=DestroyImage(hald_image);
anthony805a2d42011-09-25 08:25:12 +00003789 break;
3790 }
anthonyebb73a22012-03-22 14:25:52 +00003791 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003792 }
3793 case 'i':
3794 {
anthonyafa3dfc2012-03-03 11:31:30 +00003795 if (LocaleCompare("ift",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003796 {
3797 Image
anthony805a2d42011-09-25 08:25:12 +00003798 *magnitude_image,
3799 *phase_image;
3800
anthony92c93bd2012-03-19 14:02:47 +00003801 magnitude_image=RemoveFirstImageFromList(&_images);
3802 phase_image=RemoveFirstImageFromList(&_images);
anthonye8f56492012-02-12 12:39:02 +00003803 /* FUTURE - produce Exception, rather than silent fail */
anthony31f1bf72012-01-30 12:37:22 +00003804 if (phase_image == (Image *) NULL)
3805 break;
3806 new_images=InverseFourierTransformImage(magnitude_image,phase_image,
anthony92c93bd2012-03-19 14:02:47 +00003807 normal_op,_exception);
anthony31f1bf72012-01-30 12:37:22 +00003808 magnitude_image=DestroyImage(magnitude_image);
3809 phase_image=DestroyImage(phase_image);
anthony805a2d42011-09-25 08:25:12 +00003810 break;
3811 }
anthonyafa3dfc2012-03-03 11:31:30 +00003812 if (LocaleCompare("insert",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003813 {
3814 Image
anthony31f1bf72012-01-30 12:37:22 +00003815 *insert_image,
3816 *index_image;
3817
3818 ssize_t
3819 index;
anthony805a2d42011-09-25 08:25:12 +00003820
anthony7bcfe7f2012-03-30 14:01:22 +00003821 if (IfNormalOp && IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00003822 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00003823 index=0;
anthony92c93bd2012-03-19 14:02:47 +00003824 insert_image=RemoveLastImageFromList(&_images);
anthonyafa3dfc2012-03-03 11:31:30 +00003825 if (IfNormalOp)
anthony31f1bf72012-01-30 12:37:22 +00003826 index=(ssize_t) StringToLong(arg1);
anthony43f425d2012-02-26 12:58:58 +00003827 index_image=insert_image;
anthony805a2d42011-09-25 08:25:12 +00003828 if (index == 0)
anthony92c93bd2012-03-19 14:02:47 +00003829 PrependImageToList(&_images,insert_image);
3830 else if (index == (ssize_t) GetImageListLength(_images))
3831 AppendImageToList(&_images,insert_image);
anthony805a2d42011-09-25 08:25:12 +00003832 else
anthony43f425d2012-02-26 12:58:58 +00003833 {
anthony92c93bd2012-03-19 14:02:47 +00003834 index_image=GetImageFromList(_images,index-1);
anthony43f425d2012-02-26 12:58:58 +00003835 if (index_image == (Image *) NULL)
anthonyfe1aa782012-03-24 13:43:04 +00003836 CLIWandExceptArgBreak(OptionError,"NoSuchImage",option,arg1);
anthony43f425d2012-02-26 12:58:58 +00003837 InsertImageInList(&index_image,insert_image);
3838 }
anthony92c93bd2012-03-19 14:02:47 +00003839 _images=GetFirstImageInList(index_image);
anthony805a2d42011-09-25 08:25:12 +00003840 break;
3841 }
anthonyebb73a22012-03-22 14:25:52 +00003842 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003843 }
3844 case 'l':
3845 {
anthonyafa3dfc2012-03-03 11:31:30 +00003846 if (LocaleCompare("layers",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003847 {
anthonyfe1aa782012-03-24 13:43:04 +00003848 parse=ParseCommandOption(MagickLayerOptions,MagickFalse,arg1);
3849 if ( parse < 0 )
3850 CLIWandExceptArgBreak(OptionError,"UnrecognizedLayerMethod",
3851 option,arg1);
3852 switch ((ImageLayerMethod) parse)
anthony805a2d42011-09-25 08:25:12 +00003853 {
3854 case CoalesceLayer:
3855 {
anthony92c93bd2012-03-19 14:02:47 +00003856 new_images=CoalesceImages(_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003857 break;
3858 }
3859 case CompareAnyLayer:
3860 case CompareClearLayer:
3861 case CompareOverlayLayer:
3862 default:
3863 {
anthonyfe1aa782012-03-24 13:43:04 +00003864 new_images=CompareImagesLayers(_images,(ImageLayerMethod) parse,
3865 _exception);
anthony805a2d42011-09-25 08:25:12 +00003866 break;
3867 }
3868 case MergeLayer:
3869 case FlattenLayer:
3870 case MosaicLayer:
3871 case TrimBoundsLayer:
3872 {
anthonyfe1aa782012-03-24 13:43:04 +00003873 new_images=MergeImageLayers(_images,(ImageLayerMethod) parse,
3874 _exception);
anthony805a2d42011-09-25 08:25:12 +00003875 break;
3876 }
3877 case DisposeLayer:
3878 {
anthony92c93bd2012-03-19 14:02:47 +00003879 new_images=DisposeImages(_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003880 break;
3881 }
3882 case OptimizeImageLayer:
3883 {
anthony92c93bd2012-03-19 14:02:47 +00003884 new_images=OptimizeImageLayers(_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003885 break;
3886 }
3887 case OptimizePlusLayer:
3888 {
anthony92c93bd2012-03-19 14:02:47 +00003889 new_images=OptimizePlusImageLayers(_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003890 break;
3891 }
3892 case OptimizeTransLayer:
3893 {
anthony92c93bd2012-03-19 14:02:47 +00003894 OptimizeImageTransparency(_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003895 break;
3896 }
3897 case RemoveDupsLayer:
3898 {
anthony92c93bd2012-03-19 14:02:47 +00003899 RemoveDuplicateLayers(&_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003900 break;
3901 }
3902 case RemoveZeroLayer:
3903 {
anthony92c93bd2012-03-19 14:02:47 +00003904 RemoveZeroDelayLayers(&_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003905 break;
3906 }
3907 case OptimizeLayer:
anthony31f1bf72012-01-30 12:37:22 +00003908 { /* General Purpose, GIF Animation Optimizer. */
anthony92c93bd2012-03-19 14:02:47 +00003909 new_images=CoalesceImages(_images,_exception);
anthony31f1bf72012-01-30 12:37:22 +00003910 if (new_images == (Image *) NULL)
3911 break;
anthony92c93bd2012-03-19 14:02:47 +00003912 _images=DestroyImageList(_images);
3913 _images=OptimizeImageLayers(new_images,_exception);
3914 if (_images == (Image *) NULL)
anthony31f1bf72012-01-30 12:37:22 +00003915 break;
3916 new_images=DestroyImageList(new_images);
anthony92c93bd2012-03-19 14:02:47 +00003917 OptimizeImageTransparency(_images,_exception);
3918 (void) RemapImages(_quantize_info,_images,(Image *) NULL,
3919 _exception);
anthony805a2d42011-09-25 08:25:12 +00003920 break;
3921 }
3922 case CompositeLayer:
3923 {
anthony805a2d42011-09-25 08:25:12 +00003924 Image
3925 *source;
3926
3927 RectangleInfo
3928 geometry;
3929
anthony31f1bf72012-01-30 12:37:22 +00003930 CompositeOperator
anthony5f867ae2011-10-09 10:28:34 +00003931 compose;
3932
3933 const char*
3934 value;
3935
anthony92c93bd2012-03-19 14:02:47 +00003936 value=GetImageOption(_image_info,"compose");
anthony31f1bf72012-01-30 12:37:22 +00003937 compose=OverCompositeOp; /* Default to Over */
anthony5f867ae2011-10-09 10:28:34 +00003938 if (value != (const char *) NULL)
3939 compose=(CompositeOperator) ParseCommandOption(
3940 MagickComposeOptions,MagickFalse,value);
anthony5f867ae2011-10-09 10:28:34 +00003941
anthony31f1bf72012-01-30 12:37:22 +00003942 /* Split image sequence at the first 'NULL:' image. */
anthony92c93bd2012-03-19 14:02:47 +00003943 source=_images;
anthony805a2d42011-09-25 08:25:12 +00003944 while (source != (Image *) NULL)
3945 {
3946 source=GetNextImageInList(source);
3947 if ((source != (Image *) NULL) &&
3948 (LocaleCompare(source->magick,"NULL") == 0))
3949 break;
3950 }
3951 if (source != (Image *) NULL)
3952 {
3953 if ((GetPreviousImageInList(source) == (Image *) NULL) ||
3954 (GetNextImageInList(source) == (Image *) NULL))
3955 source=(Image *) NULL;
3956 else
anthony31f1bf72012-01-30 12:37:22 +00003957 { /* Separate the two lists, junk the null: image. */
anthony805a2d42011-09-25 08:25:12 +00003958 source=SplitImageList(source->previous);
3959 DeleteImageFromList(&source);
3960 }
3961 }
3962 if (source == (Image *) NULL)
3963 {
anthony92c93bd2012-03-19 14:02:47 +00003964 (void) ThrowMagickException(_exception,GetMagickModule(),
anthony805a2d42011-09-25 08:25:12 +00003965 OptionError,"MissingNullSeparator","layers Composite");
anthony805a2d42011-09-25 08:25:12 +00003966 break;
3967 }
anthony31f1bf72012-01-30 12:37:22 +00003968 /* Adjust offset with gravity and virtual canvas. */
anthony92c93bd2012-03-19 14:02:47 +00003969 SetGeometry(_images,&geometry);
3970 (void) ParseAbsoluteGeometry(_images->geometry,&geometry);
anthony805a2d42011-09-25 08:25:12 +00003971 geometry.width=source->page.width != 0 ?
3972 source->page.width : source->columns;
3973 geometry.height=source->page.height != 0 ?
3974 source->page.height : source->rows;
anthony92c93bd2012-03-19 14:02:47 +00003975 GravityAdjustGeometry(_images->page.width != 0 ?
3976 _images->page.width : _images->columns,
3977 _images->page.height != 0 ? _images->page.height :
3978 _images->rows,_images->gravity,&geometry);
anthony5f867ae2011-10-09 10:28:34 +00003979
anthony31f1bf72012-01-30 12:37:22 +00003980 /* Compose the two image sequences together */
anthony92c93bd2012-03-19 14:02:47 +00003981 CompositeLayers(_images,compose,source,geometry.x,geometry.y,
3982 _exception);
anthony805a2d42011-09-25 08:25:12 +00003983 source=DestroyImageList(source);
3984 break;
3985 }
3986 }
anthony805a2d42011-09-25 08:25:12 +00003987 break;
3988 }
anthonyebb73a22012-03-22 14:25:52 +00003989 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003990 }
3991 case 'm':
3992 {
anthonyafa3dfc2012-03-03 11:31:30 +00003993 if (LocaleCompare("map",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003994 {
anthony464f1c42012-04-22 08:51:01 +00003995 CLIWandWarnReplaced("+remap");
anthony92c93bd2012-03-19 14:02:47 +00003996 (void) RemapImages(_quantize_info,_images,(Image *) NULL,_exception);
anthony805a2d42011-09-25 08:25:12 +00003997 break;
3998 }
anthonyafa3dfc2012-03-03 11:31:30 +00003999 if (LocaleCompare("morph",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00004000 {
4001 Image
4002 *morph_image;
4003
anthony7bcfe7f2012-03-30 14:01:22 +00004004 if (IfMagickFalse(IsGeometry(arg1)))
anthony7bc87992012-03-25 02:32:51 +00004005 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00004006 morph_image=MorphImages(_images,StringToUnsignedLong(arg1),
4007 _exception);
anthony805a2d42011-09-25 08:25:12 +00004008 if (morph_image == (Image *) NULL)
anthony31f1bf72012-01-30 12:37:22 +00004009 break;
anthony92c93bd2012-03-19 14:02:47 +00004010 _images=DestroyImageList(_images);
4011 _images=morph_image;
anthony805a2d42011-09-25 08:25:12 +00004012 break;
4013 }
anthonyafa3dfc2012-03-03 11:31:30 +00004014 if (LocaleCompare("mosaic",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00004015 {
anthony319dac62012-03-06 04:12:44 +00004016 /* REDIRECTED to use -layers mosaic instead */
anthony2e4501b2012-03-30 04:41:54 +00004017 CLIListOperatorImages(cli_wand,"-layers",option+1,NULL);
anthony805a2d42011-09-25 08:25:12 +00004018 break;
4019 }
anthonyebb73a22012-03-22 14:25:52 +00004020 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00004021 }
4022 case 'p':
4023 {
anthonyafa3dfc2012-03-03 11:31:30 +00004024 if (LocaleCompare("print",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00004025 {
anthony964d28e2012-05-17 23:39:46 +00004026 (void) FormatLocaleFile(stdout,"%s",arg1);
anthony24aa8822012-03-11 00:56:06 +00004027 break;
anthony805a2d42011-09-25 08:25:12 +00004028 }
anthonyafa3dfc2012-03-03 11:31:30 +00004029 if (LocaleCompare("process",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00004030 {
anthonyb1d483a2012-04-14 12:53:56 +00004031 /* FUTURE: better parsing using ScriptToken() from string ??? */
anthony805a2d42011-09-25 08:25:12 +00004032 char
4033 **arguments;
4034
4035 int
4036 j,
4037 number_arguments;
4038
anthony31f1bf72012-01-30 12:37:22 +00004039 arguments=StringToArgv(arg1,&number_arguments);
anthony805a2d42011-09-25 08:25:12 +00004040 if (arguments == (char **) NULL)
4041 break;
anthony31f1bf72012-01-30 12:37:22 +00004042 if (strchr(arguments[1],'=') != (char *) NULL)
anthony805a2d42011-09-25 08:25:12 +00004043 {
4044 char
4045 breaker,
4046 quote,
4047 *token;
4048
4049 const char
4050 *arguments;
4051
4052 int
4053 next,
4054 status;
4055
4056 size_t
4057 length;
4058
4059 TokenInfo
4060 *token_info;
4061
4062 /*
anthony24aa8822012-03-11 00:56:06 +00004063 Support old style syntax, filter="-option arg1".
anthony805a2d42011-09-25 08:25:12 +00004064 */
anthony31f1bf72012-01-30 12:37:22 +00004065 length=strlen(arg1);
anthony805a2d42011-09-25 08:25:12 +00004066 token=(char *) NULL;
4067 if (~length >= (MaxTextExtent-1))
4068 token=(char *) AcquireQuantumMemory(length+MaxTextExtent,
4069 sizeof(*token));
4070 if (token == (char *) NULL)
4071 break;
4072 next=0;
anthony31f1bf72012-01-30 12:37:22 +00004073 arguments=arg1;
anthony805a2d42011-09-25 08:25:12 +00004074 token_info=AcquireTokenInfo();
4075 status=Tokenizer(token_info,0,token,length,arguments,"","=",
4076 "\"",'\0',&breaker,&next,&quote);
4077 token_info=DestroyTokenInfo(token_info);
4078 if (status == 0)
4079 {
4080 const char
4081 *argv;
4082
4083 argv=(&(arguments[next]));
anthony92c93bd2012-03-19 14:02:47 +00004084 (void) InvokeDynamicImageFilter(token,&_images,1,&argv,
4085 _exception);
anthony805a2d42011-09-25 08:25:12 +00004086 }
4087 token=DestroyString(token);
4088 break;
4089 }
4090 (void) SubstituteString(&arguments[1],"-","");
anthony92c93bd2012-03-19 14:02:47 +00004091 (void) InvokeDynamicImageFilter(arguments[1],&_images,
4092 number_arguments-2,(const char **) arguments+2,_exception);
anthony805a2d42011-09-25 08:25:12 +00004093 for (j=0; j < number_arguments; j++)
4094 arguments[j]=DestroyString(arguments[j]);
4095 arguments=(char **) RelinquishMagickMemory(arguments);
4096 break;
4097 }
anthonyebb73a22012-03-22 14:25:52 +00004098 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00004099 }
4100 case 'r':
4101 {
anthonyafa3dfc2012-03-03 11:31:30 +00004102 if (LocaleCompare("remap",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00004103 {
anthony92c93bd2012-03-19 14:02:47 +00004104 (void) RemapImages(_quantize_info,_images,(Image *) NULL,_exception);
anthony31f1bf72012-01-30 12:37:22 +00004105 break;
4106 }
anthonyafa3dfc2012-03-03 11:31:30 +00004107 if (LocaleCompare("reverse",option+1) == 0)
anthony31f1bf72012-01-30 12:37:22 +00004108 {
anthony92c93bd2012-03-19 14:02:47 +00004109 ReverseImageList(&_images);
anthony805a2d42011-09-25 08:25:12 +00004110 break;
4111 }
anthonyebb73a22012-03-22 14:25:52 +00004112 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00004113 }
4114 case 's':
4115 {
anthonyafa3dfc2012-03-03 11:31:30 +00004116 if (LocaleCompare("smush",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00004117 {
anthonycd358fc2012-04-16 13:59:03 +00004118 /* FUTURE: this option needs more work to make better */
anthony805a2d42011-09-25 08:25:12 +00004119 ssize_t
4120 offset;
4121
anthony7bcfe7f2012-03-30 14:01:22 +00004122 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00004123 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony31f1bf72012-01-30 12:37:22 +00004124 offset=(ssize_t) StringToLong(arg1);
anthonycd358fc2012-04-16 13:59:03 +00004125 new_images=SmushImages(_images,normal_op,offset,_exception);
4126 break;
4127 }
4128 if (LocaleCompare("subimage",option+1) == 0)
4129 {
4130 Image
4131 *base_image,
4132 *compare_image;
4133
4134 const char *
4135 value;
4136
4137 MetricType
4138 metric;
4139
4140 double
4141 similarity;
4142
4143 RectangleInfo
4144 offset;
4145
4146 base_image=GetImageFromList(_images,0);
4147 compare_image=GetImageFromList(_images,1);
4148
4149 /* Comparision Metric */
4150 metric=UndefinedMetric;
4151 value=GetImageOption(_image_info,"metric");
4152 if (value != (const char *) NULL)
4153 metric=(MetricType) ParseCommandOption(MagickMetricOptions,
4154 MagickFalse,value);
4155
4156 new_images=SimilarityImage(base_image,compare_image,metric,
4157 &offset,&similarity,_exception);
4158
4159 if ( new_images != (Image *)NULL ) {
4160 char
4161 result[MaxTextExtent];
4162
4163 (void) FormatLocaleString(result,MaxTextExtent,"%lf",similarity);
4164 (void) SetImageProperty(new_images,"subimage:similarity",result,
4165 _exception);
4166 (void) FormatLocaleString(result,MaxTextExtent,"%+ld",
4167 (long) offset.x);
4168 (void) SetImageProperty(new_images,"subimage:x",result,
4169 _exception);
4170 (void) FormatLocaleString(result,MaxTextExtent,"%+ld",
4171 (long) offset.y);
4172 (void) SetImageProperty(new_images,"subimage:y",result,
4173 _exception);
4174 (void) FormatLocaleString(result,MaxTextExtent,"%lux%lu%+ld%+ld",
4175 (unsigned long) offset.width,(unsigned long) offset.height,
4176 (long) offset.x,(long) offset.y);
4177 (void) SetImageProperty(new_images,"subimage:offset",result,
4178 _exception);
4179 }
anthony805a2d42011-09-25 08:25:12 +00004180 break;
4181 }
anthony0ea037a2012-04-03 12:14:39 +00004182 if (LocaleCompare("swap",option+1) == 0) {
4183 Image
4184 *p,
4185 *q,
4186 *swap;
anthony805a2d42011-09-25 08:25:12 +00004187
anthony0ea037a2012-04-03 12:14:39 +00004188 ssize_t
4189 index,
4190 swap_index;
anthony805a2d42011-09-25 08:25:12 +00004191
anthony0ea037a2012-04-03 12:14:39 +00004192 index=-1;
4193 swap_index=-2;
4194 if (IfNormalOp) {
4195 GeometryInfo
4196 geometry_info;
4197
4198 MagickStatusType
4199 flags;
4200
4201 swap_index=(-1);
anthony0ea037a2012-04-03 12:14:39 +00004202 flags=ParseGeometry(arg1,&geometry_info);
anthonyb1e21ed2012-04-20 12:43:12 +00004203 if ((flags & RhoValue) != 0)
4204 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony0ea037a2012-04-03 12:14:39 +00004205 index=(ssize_t) geometry_info.rho;
4206 if ((flags & SigmaValue) != 0)
4207 swap_index=(ssize_t) geometry_info.sigma;
anthony805a2d42011-09-25 08:25:12 +00004208 }
anthony0ea037a2012-04-03 12:14:39 +00004209 p=GetImageFromList(_images,index);
4210 q=GetImageFromList(_images,swap_index);
anthony8226e722012-04-05 14:25:46 +00004211 if ((p == (Image *) NULL) || (q == (Image *) NULL)) {
4212 if (IfNormalOp)
4213 CLIWandExceptArgBreak(OptionError,"InvalidImageIndex",option,arg1)
4214 else
4215 CLIWandExceptionBreak(OptionError,"TwoOrMoreImagesRequired",option);
4216 }
anthony0ea037a2012-04-03 12:14:39 +00004217 if (p == q)
anthony8226e722012-04-05 14:25:46 +00004218 CLIWandExceptArgBreak(OptionError,"InvalidImageIndex",option,arg1);
anthony0ea037a2012-04-03 12:14:39 +00004219 swap=CloneImage(p,0,0,MagickTrue,_exception);
4220 ReplaceImageInList(&p,CloneImage(q,0,0,MagickTrue,_exception));
4221 ReplaceImageInList(&q,swap);
4222 _images=GetFirstImageInList(q);
4223 break;
4224 }
anthonyebb73a22012-03-22 14:25:52 +00004225 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00004226 }
anthony805a2d42011-09-25 08:25:12 +00004227 default:
anthonyebb73a22012-03-22 14:25:52 +00004228 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00004229 }
anthony964d28e2012-05-17 23:39:46 +00004230
4231 /* clean up percent escape interpreted strings */
4232 if (arg1 != arg1n )
4233 arg1=DestroyString((char *)arg1);
4234 if (arg2 != arg2n )
4235 arg2=DestroyString((char *)arg2);
4236
4237 /* if new image list generated, replace existing image list */
anthony31f1bf72012-01-30 12:37:22 +00004238 if (new_images == (Image *) NULL)
4239 return;
anthony964d28e2012-05-17 23:39:46 +00004240 _images=DestroyImageList(_images);
anthony92c93bd2012-03-19 14:02:47 +00004241 _images=GetFirstImageInList(new_images);
anthony31f1bf72012-01-30 12:37:22 +00004242 return;
4243
anthony92c93bd2012-03-19 14:02:47 +00004244#undef _image_info
4245#undef _images
4246#undef _exception
4247#undef _draw_info
4248#undef _quantize_info
anthonyafa3dfc2012-03-03 11:31:30 +00004249#undef IfNormalOp
4250#undef IfPlusOp
anthony31f1bf72012-01-30 12:37:22 +00004251#undef normal_op
anthony805a2d42011-09-25 08:25:12 +00004252}
anthony43f425d2012-02-26 12:58:58 +00004253
4254/*
4255%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4256% %
4257% %
4258% %
anthony964d28e2012-05-17 23:39:46 +00004259+ C L I N o I m a g e O p e r a t i o n s %
anthony43f425d2012-02-26 12:58:58 +00004260% %
4261% %
4262% %
4263%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4264%
anthony464f1c42012-04-22 08:51:01 +00004265% CLINoImageOperator() Applies operations that may not actually need images
anthony964d28e2012-05-17 23:39:46 +00004266% in an image list.
anthony43f425d2012-02-26 12:58:58 +00004267%
anthony756cd0d2012-04-08 12:41:44 +00004268% The classic operators of this type is -read, which actually creates images
4269% even when no images are present. Or image stack operators, which can be
anthony964d28e2012-05-17 23:39:46 +00004270% applied (push or pop) to an empty image list.
anthonyafa3dfc2012-03-03 11:31:30 +00004271%
4272% Note: unlike other Operators, these may involve other special 'option'
anthony964d28e2012-05-17 23:39:46 +00004273% characters other than '-' or '+', namely parenthesis and braces.
anthony43f425d2012-02-26 12:58:58 +00004274%
anthony464f1c42012-04-22 08:51:01 +00004275% The format of the CLINoImageOption method is:
anthony43f425d2012-02-26 12:58:58 +00004276%
anthony464f1c42012-04-22 08:51:01 +00004277% void CLINoImageOption(MagickCLI *cli_wand,const char *option,
4278% const char *arg1, const char *arg2)
anthony43f425d2012-02-26 12:58:58 +00004279%
4280% A description of each parameter follows:
4281%
4282% o cli_wand: the main CLI Wand to use.
4283%
4284% o option: The special option (with any switch char) to process
4285%
anthony464f1c42012-04-22 08:51:01 +00004286% o arg1 & arg2: Argument for option, if required
4287% Currently arg2 is not used.
anthony43f425d2012-02-26 12:58:58 +00004288%
4289*/
anthony464f1c42012-04-22 08:51:01 +00004290WandExport void CLINoImageOperator(MagickCLI *cli_wand,
4291 const char *option, const char *arg1, const char *magick_unused(arg2))
anthony43f425d2012-02-26 12:58:58 +00004292{
anthony8226e722012-04-05 14:25:46 +00004293#define _image_info (cli_wand->wand.image_info)
4294#define _images (cli_wand->wand.images)
4295#define _exception (cli_wand->wand.exception)
4296#define IfNormalOp (*option=='-')
4297#define IfPlusOp (*option!='-')
anthony43f425d2012-02-26 12:58:58 +00004298
4299 assert(cli_wand != (MagickCLI *) NULL);
4300 assert(cli_wand->signature == WandSignature);
4301 assert(cli_wand->wand.signature == WandSignature);
anthony7bcfe7f2012-03-30 14:01:22 +00004302 if (IfMagickTrue(cli_wand->wand.debug))
anthony43f425d2012-02-26 12:58:58 +00004303 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
4304
anthony52bef752012-03-27 13:54:47 +00004305 /*
anthony756cd0d2012-04-08 12:41:44 +00004306 No-op options (ignore these)
anthony52bef752012-03-27 13:54:47 +00004307 */
anthony756cd0d2012-04-08 12:41:44 +00004308 if (LocaleCompare("noop",option+1) == 0) /* no argument */
anthony52bef752012-03-27 13:54:47 +00004309 return;
anthony756cd0d2012-04-08 12:41:44 +00004310 if (LocaleCompare("sans",option+1) == 0) /* one argument */
anthony52bef752012-03-27 13:54:47 +00004311 return;
anthony756cd0d2012-04-08 12:41:44 +00004312 if (LocaleCompare("sans0",option+1) == 0) /* no argument */
anthony52bef752012-03-27 13:54:47 +00004313 return;
anthony756cd0d2012-04-08 12:41:44 +00004314 if (LocaleCompare("sans2",option+1) == 0) /* two arguments */
anthony52bef752012-03-27 13:54:47 +00004315 return;
4316 /*
4317 Image Reading
4318 */
4319 if ( ( LocaleCompare("read",option+1) == 0 ) ||
anthony0ea037a2012-04-03 12:14:39 +00004320 ( LocaleCompare("--",option) == 0 ) ) {
anthonyde897b72012-04-27 00:16:17 +00004321#if 0
4322 /* Directly read 'arg1' without filename expansion handling (see below).
anthonyde897b72012-04-27 00:16:17 +00004323 */
anthony9b33b252012-04-29 12:29:31 +00004324# if !USE_WAND_METHODS
anthonyde897b72012-04-27 00:16:17 +00004325 Image *new_images;
anthony52bef752012-03-27 13:54:47 +00004326
anthonyde897b72012-04-27 00:16:17 +00004327 if (IfMagickTrue(_image_info->ping))
4328 new_images=PingImages(_image_info,arg1,_exception);
4329 else
4330 new_images=ReadImages(_image_info,arg1,_exception);
4331 AppendImageToList(&_images, new_images);
anthony9b33b252012-04-29 12:29:31 +00004332# else
anthonyde897b72012-04-27 00:16:17 +00004333 /* read images using MagickWand method - no ping */
4334 /* This is not working! - it locks up in a CPU loop! */
4335 MagickSetLastIterator(&cli_wand->wand);
4336 MagickReadImage(&cli_wand->wand,arg1);
4337 MagickSetFirstIterator(&cli_wand->wand);
anthony9b33b252012-04-29 12:29:31 +00004338# endif
anthonyde897b72012-04-27 00:16:17 +00004339#else
4340 /* Do Filename Expansion for 'arg1' then read all images.
4341 *
4342 * Expansion handles '@', '~', '*', and '?' meta-characters while ignoring
4343 * (but attaching to generated argument list) any [...] read modifiers
4344 * that may be present.
4345 *
4346 * For example: correctly expand '*.gif[20x20]' into a list such as
4347 * 'abc.gif[20x20', 'foobar.gif[20x20]', 'xyzzy.gif[20x20]'
4348 *
4349 * NOTE: In IMv6 this was done globally across all images. This
4350 * meant you could include IM options in '@filename' lists, but you
4351 * could not include comments. Doing it only for image read makes
4352 * it far more secure.
4353 */
4354 int argc;
4355 char **argv;
4356 ssize_t i;
anthony0ea037a2012-04-03 12:14:39 +00004357
anthony0ea037a2012-04-03 12:14:39 +00004358 argc = 1;
cristye71f2942012-04-04 11:07:05 +00004359 argv = (char **) &arg1;
anthony0ea037a2012-04-03 12:14:39 +00004360
anthony451f9092012-05-11 01:56:24 +00004361 /* Expand 'glob' expressions in the given filename.
4362 Expansion handles any 'coder:' prefix, or read modifiers attached
4363 to the filename, including them in the resulting expanded list.
4364 */
4365 if (IfMagickFalse( ExpandFilenames(&argc,&argv) ))
anthony0ea037a2012-04-03 12:14:39 +00004366 CLIWandExceptArgReturn(ResourceLimitError,"MemoryAllocationFailed",
4367 option,GetExceptionMessage(errno));
4368
anthonyde897b72012-04-27 00:16:17 +00004369 /* loop over expanded filename list, and read then all in */
anthony0ea037a2012-04-03 12:14:39 +00004370 for (i=0; i<argc; i++) {
anthony52bef752012-03-27 13:54:47 +00004371 Image *
4372 new_images;
anthonyff134e62012-04-30 04:25:09 +00004373#if 0
anthony964d28e2012-05-17 23:39:46 +00004374 fprintf(stderr, "DEBUG: Reading image: \"%s\"\n", argv[i]);
anthonyde897b72012-04-27 00:16:17 +00004375#endif
anthony8226e722012-04-05 14:25:46 +00004376 if (IfMagickTrue(_image_info->ping))
4377 new_images=PingImages(_image_info,argv[i],_exception);
anthony52bef752012-03-27 13:54:47 +00004378 else
anthony8226e722012-04-05 14:25:46 +00004379 new_images=ReadImages(_image_info,argv[i],_exception);
4380 AppendImageToList(&_images, new_images);
anthony52bef752012-03-27 13:54:47 +00004381 }
anthony451f9092012-05-11 01:56:24 +00004382 argv=DestroyStringList(argv); /* Destroy the Expanded Filename list */
anthonyde897b72012-04-27 00:16:17 +00004383#endif
anthony0ea037a2012-04-03 12:14:39 +00004384 return;
4385 }
anthony52bef752012-03-27 13:54:47 +00004386 /*
anthonyde897b72012-04-27 00:16:17 +00004387 Image Writing
4388 Note: Writing a empty image list is valid in specific cases
anthony8226e722012-04-05 14:25:46 +00004389 */
4390 if (LocaleCompare("write",option+1) == 0) {
4391 char
4392 key[MaxTextExtent];
4393
4394 Image
4395 *write_images;
4396
4397 ImageInfo
4398 *write_info;
4399
4400 /* Need images, unless a "null:" output coder is used */
4401 if ( cli_wand->wand.images == (Image *) NULL ) {
anthonya9e4f5d2012-04-12 06:44:02 +00004402 if ( LocaleCompare(arg1,"null:") == 0 )
anthony8226e722012-04-05 14:25:46 +00004403 return;
4404 CLIWandExceptArgReturn(OptionError,"NoImagesForWrite",option,arg1);
4405 }
4406
4407 (void) FormatLocaleString(key,MaxTextExtent,"cache:%s",arg1);
4408 (void) DeleteImageRegistry(key);
4409 write_images=_images;
4410 if (IfPlusOp)
4411 write_images=CloneImageList(_images,_exception);
4412 write_info=CloneImageInfo(_image_info);
4413 (void) WriteImages(write_info,write_images,arg1,_exception);
4414 write_info=DestroyImageInfo(write_info);
4415 if (IfPlusOp)
4416 write_images=DestroyImageList(write_images);
4417 return;
4418 }
4419 /*
anthony52bef752012-03-27 13:54:47 +00004420 Parenthesis and Brace operations
4421 */
anthonyce8dcb32012-03-21 13:20:31 +00004422 if (LocaleCompare("(",option) == 0) {
anthony8226e722012-04-05 14:25:46 +00004423 /* stack 'push' images */
4424 Stack
4425 *node;
anthony43f425d2012-02-26 12:58:58 +00004426
anthony8226e722012-04-05 14:25:46 +00004427 size_t
4428 size;
anthony43f425d2012-02-26 12:58:58 +00004429
anthony8226e722012-04-05 14:25:46 +00004430 size=0;
4431 node=cli_wand->image_list_stack;
4432 for ( ; node != (Stack *)NULL; node=node->next)
4433 size++;
4434 if ( size >= MAX_STACK_DEPTH )
4435 CLIWandExceptionReturn(OptionError,"ParenthesisNestedTooDeeply",option);
4436 node=(Stack *) AcquireMagickMemory(sizeof(*node));
4437 if (node == (Stack *) NULL)
4438 CLIWandExceptionReturn(ResourceLimitFatalError,
4439 "MemoryAllocationFailed",option);
4440 node->data = (void *)cli_wand->wand.images;
4441 cli_wand->wand.images = NewImageList();
4442 node->next = cli_wand->image_list_stack;
4443 cli_wand->image_list_stack = node;
anthony43f425d2012-02-26 12:58:58 +00004444
anthony8226e722012-04-05 14:25:46 +00004445 /* handle respect-parenthesis */
4446 if (IfMagickTrue(IsStringTrue(GetImageOption(cli_wand->wand.image_info,
4447 "respect-parenthesis"))))
4448 option="{"; /* fall-thru so as to push image settings too */
4449 else
anthony43f425d2012-02-26 12:58:58 +00004450 return;
anthony8226e722012-04-05 14:25:46 +00004451 }
4452 if (LocaleCompare("{",option) == 0) {
4453 /* stack 'push' of image_info settings */
4454 Stack
4455 *node;
anthony43f425d2012-02-26 12:58:58 +00004456
anthony8226e722012-04-05 14:25:46 +00004457 size_t
4458 size;
anthony43f425d2012-02-26 12:58:58 +00004459
anthony8226e722012-04-05 14:25:46 +00004460 size=0;
4461 node=cli_wand->image_info_stack;
4462 for ( ; node != (Stack *)NULL; node=node->next)
4463 size++;
4464 if ( size >= MAX_STACK_DEPTH )
4465 CLIWandExceptionReturn(OptionError,"CurlyBracesNestedTooDeeply",option);
4466 node=(Stack *) AcquireMagickMemory(sizeof(*node));
4467 if (node == (Stack *) NULL)
4468 CLIWandExceptionReturn(ResourceLimitFatalError,
4469 "MemoryAllocationFailed",option);
anthony43f425d2012-02-26 12:58:58 +00004470
anthony8226e722012-04-05 14:25:46 +00004471 node->data = (void *)cli_wand->wand.image_info;
4472 cli_wand->wand.image_info = CloneImageInfo(cli_wand->wand.image_info);
4473 if (cli_wand->wand.image_info == (ImageInfo *)NULL) {
4474 CLIWandException(ResourceLimitFatalError,"MemoryAllocationFailed",
4475 option);
anthony43f425d2012-02-26 12:58:58 +00004476 cli_wand->wand.image_info = (ImageInfo *)node->data;
4477 node = (Stack *)RelinquishMagickMemory(node);
anthony43f425d2012-02-26 12:58:58 +00004478 return;
4479 }
anthony8226e722012-04-05 14:25:46 +00004480
4481 node->next = cli_wand->image_info_stack;
4482 cli_wand->image_info_stack = node;
4483
4484 return;
4485 }
4486 if (LocaleCompare(")",option) == 0) {
4487 /* pop images from stack */
4488 Stack
4489 *node;
4490
4491 node = (Stack *)cli_wand->image_list_stack;
4492 if ( node == (Stack *)NULL)
4493 CLIWandExceptionReturn(OptionError,"UnbalancedParenthesis",option);
4494 cli_wand->image_list_stack = node->next;
4495
4496 AppendImageToList((Image **)&node->data,cli_wand->wand.images);
4497 cli_wand->wand.images= (Image *)node->data;
4498 node = (Stack *)RelinquishMagickMemory(node);
4499
4500 /* handle respect-parenthesis - of the previous 'pushed' settings */
4501 node = cli_wand->image_info_stack;
4502 if ( node != (Stack *)NULL)
4503 {
4504 if (IfMagickTrue(IsStringTrue(GetImageOption(
4505 cli_wand->wand.image_info,"respect-parenthesis"))))
4506 option="}"; /* fall-thru so as to pop image settings too */
4507 else
4508 return;
4509 }
4510 else
4511 return;
4512 }
4513 if (LocaleCompare("}",option) == 0) {
4514 /* pop image_info settings from stack */
4515 Stack
4516 *node;
4517
4518 node = (Stack *)cli_wand->image_info_stack;
4519 if ( node == (Stack *)NULL)
4520 CLIWandExceptionReturn(OptionError,"UnbalancedCurlyBraces",option);
4521 cli_wand->image_info_stack = node->next;
4522
4523 (void) DestroyImageInfo(cli_wand->wand.image_info);
4524 cli_wand->wand.image_info = (ImageInfo *)node->data;
4525 node = (Stack *)RelinquishMagickMemory(node);
4526
4527 GetDrawInfo(cli_wand->wand.image_info, cli_wand->draw_info);
4528 cli_wand->quantize_info=DestroyQuantizeInfo(cli_wand->quantize_info);
4529 cli_wand->quantize_info=AcquireQuantizeInfo(cli_wand->wand.image_info);
4530
4531 return;
4532 }
anthonyce8dcb32012-03-21 13:20:31 +00004533 if (LocaleCompare("clone",option+1) == 0) {
anthony43f425d2012-02-26 12:58:58 +00004534 Image
4535 *new_images;
4536
4537 if (*option == '+')
anthony24aa8822012-03-11 00:56:06 +00004538 arg1="-1";
anthony7bcfe7f2012-03-30 14:01:22 +00004539 if (IfMagickFalse(IsSceneGeometry(arg1,MagickFalse)))
anthony92c93bd2012-03-19 14:02:47 +00004540 CLIWandExceptionReturn(OptionError,"InvalidArgument",option);
anthony43f425d2012-02-26 12:58:58 +00004541 if ( cli_wand->image_list_stack == (Stack *)NULL)
anthony92c93bd2012-03-19 14:02:47 +00004542 CLIWandExceptionReturn(OptionError,"UnableToCloneImage",option);
anthony43f425d2012-02-26 12:58:58 +00004543 new_images = (Image *)cli_wand->image_list_stack->data;
4544 if (new_images == (Image *) NULL)
anthony92c93bd2012-03-19 14:02:47 +00004545 CLIWandExceptionReturn(OptionError,"UnableToCloneImage",option);
4546 new_images=CloneImages(new_images,arg1,_exception);
anthony43f425d2012-02-26 12:58:58 +00004547 if (new_images == (Image *) NULL)
anthony92c93bd2012-03-19 14:02:47 +00004548 CLIWandExceptionReturn(OptionError,"NoSuchImage",option);
anthony8226e722012-04-05 14:25:46 +00004549 AppendImageToList(&_images,new_images);
anthony43f425d2012-02-26 12:58:58 +00004550 return;
4551 }
anthony52bef752012-03-27 13:54:47 +00004552 /*
4553 Informational Operations
4554 */
anthony0ea037a2012-04-03 12:14:39 +00004555 if (LocaleCompare("version",option+1) == 0) {
anthony8226e722012-04-05 14:25:46 +00004556 (void) FormatLocaleFile(stdout,"Version: %s\n",
4557 GetMagickVersion((size_t *) NULL));
4558 (void) FormatLocaleFile(stdout,"Copyright: %s\n",
4559 GetMagickCopyright());
4560 (void) FormatLocaleFile(stdout,"Features: %s\n\n",
4561 GetMagickFeatures());
4562 return;
4563 }
anthonyce8dcb32012-03-21 13:20:31 +00004564 if (LocaleCompare("list",option+1) == 0) {
anthony8226e722012-04-05 14:25:46 +00004565 /* FUTURE: This should really be built into the MagickCore
4566 It does not actually require a cli-wand or and images!
4567 */
4568 ssize_t
4569 list;
anthony43f425d2012-02-26 12:58:58 +00004570
anthony8226e722012-04-05 14:25:46 +00004571 list=ParseCommandOption(MagickListOptions,MagickFalse,arg1);
4572 if ( list < 0 ) {
4573 CLIWandExceptionArg(OptionError,"UnrecognizedListType",option,arg1);
anthony43f425d2012-02-26 12:58:58 +00004574 return;
4575 }
anthony8226e722012-04-05 14:25:46 +00004576 switch (list)
4577 {
4578 case MagickCoderOptions:
4579 {
4580 (void) ListCoderInfo((FILE *) NULL,_exception);
4581 break;
4582 }
4583 case MagickColorOptions:
4584 {
4585 (void) ListColorInfo((FILE *) NULL,_exception);
4586 break;
4587 }
4588 case MagickConfigureOptions:
4589 {
4590 (void) ListConfigureInfo((FILE *) NULL,_exception);
4591 break;
4592 }
4593 case MagickDelegateOptions:
4594 {
4595 (void) ListDelegateInfo((FILE *) NULL,_exception);
4596 break;
4597 }
4598 case MagickFontOptions:
4599 {
4600 (void) ListTypeInfo((FILE *) NULL,_exception);
4601 break;
4602 }
4603 case MagickFormatOptions:
4604 (void) ListMagickInfo((FILE *) NULL,_exception);
4605 break;
4606 case MagickLocaleOptions:
4607 (void) ListLocaleInfo((FILE *) NULL,_exception);
4608 break;
4609 case MagickLogOptions:
4610 (void) ListLogInfo((FILE *) NULL,_exception);
4611 break;
4612 case MagickMagicOptions:
4613 (void) ListMagicInfo((FILE *) NULL,_exception);
4614 break;
4615 case MagickMimeOptions:
4616 (void) ListMimeInfo((FILE *) NULL,_exception);
4617 break;
4618 case MagickModuleOptions:
4619 (void) ListModuleInfo((FILE *) NULL,_exception);
4620 break;
4621 case MagickPolicyOptions:
4622 (void) ListPolicyInfo((FILE *) NULL,_exception);
4623 break;
4624 case MagickResourceOptions:
4625 (void) ListMagickResourceInfo((FILE *) NULL,_exception);
4626 break;
4627 case MagickThresholdOptions:
4628 (void) ListThresholdMaps((FILE *) NULL,_exception);
4629 break;
4630 default:
4631 (void) ListCommandOptions((FILE *) NULL,(CommandOption) list,
4632 _exception);
4633 break;
4634 }
4635 return;
4636 }
anthony43f425d2012-02-26 12:58:58 +00004637
4638#if 0
anthony43f425d2012-02-26 12:58:58 +00004639 // Other 'special' options this should handle
anthony5216f822012-04-10 13:02:37 +00004640 // "region" "reset" "arg"
anthony43f425d2012-02-26 12:58:58 +00004641 if ( ( process_flags & ProcessUnknownOptionError ) != 0 )
anthony43f425d2012-02-26 12:58:58 +00004642#endif
anthonyebb73a22012-03-22 14:25:52 +00004643 CLIWandException(OptionError,"UnrecognizedOption",option);
anthony43f425d2012-02-26 12:58:58 +00004644
anthony8226e722012-04-05 14:25:46 +00004645#undef _image_info
4646#undef _images
anthony92c93bd2012-03-19 14:02:47 +00004647#undef _exception
anthony8226e722012-04-05 14:25:46 +00004648#undef IfNormalOp
4649#undef IfPlusOp
anthony43f425d2012-02-26 12:58:58 +00004650}
anthony464f1c42012-04-22 08:51:01 +00004651
4652/*
4653%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4654% %
4655% %
4656% %
anthony964d28e2012-05-17 23:39:46 +00004657+ C L I O p t i o n %
anthony464f1c42012-04-22 08:51:01 +00004658% %
4659% %
4660% %
4661%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4662%
4663% CLIOption() Processes the given option using the given CLI Magick Wand.
anthony964d28e2012-05-17 23:39:46 +00004664% The option arguments can be variable in number, though at this time no more
4665% that two is actually used by any option (this may change). Excess options
4666% are simply ignored.
anthony464f1c42012-04-22 08:51:01 +00004667%
4668% If the cli_wand->command pointer is non-null, then it is assumed that the
4669% option has already been search for up from the CommandOptions[] table in
anthony964d28e2012-05-17 23:39:46 +00004670% "MagickCore/options.c" using GetCommandOptionInfo(). If not set this
4671% routine will do the lookup instead. The pointer is reset afterward.
4672%
4673% This action allows the caller to lookup and pre-handle any 'special'
4674% options, (such as implicit reads) before calling this general option
4675% handler to deal with 'standard' command line options.
anthony464f1c42012-04-22 08:51:01 +00004676%
4677% The format of the CLIOption method is:
4678%
4679% void CLIOption(MagickCLI *cli_wand,const char *option, ...)
4680%
4681% A description of each parameter follows:
4682%
4683% o cli_wand: the main CLI Wand to use.
4684%
4685% o option: The special option (with any switch char) to process
4686%
anthony964d28e2012-05-17 23:39:46 +00004687% o args: any required arguments for an option (variable number)
anthony464f1c42012-04-22 08:51:01 +00004688%
4689% Example Usage...
4690%
4691% CLIoption(cli_wand,"-read","rose:");
4692% CLIoption(cli_wand,"-virtual-pixel","transparent");
4693% CLIoption(cli_wand,"-distort","SRT:","30");
4694% CLIoption(cli_wand,"-write","rotated_rose.png");
4695%
4696*/
4697WandExport void CLIOption(MagickCLI *cli_wand,const char *option,...)
4698{
4699 const char
4700 *arg1,
4701 *arg2;
4702
4703 CommandOptionFlags
4704 option_type;
4705
4706 assert(cli_wand != (MagickCLI *) NULL);
4707 assert(cli_wand->signature == WandSignature);
4708 assert(cli_wand->wand.signature == WandSignature);
4709 if (IfMagickTrue(cli_wand->wand.debug))
4710 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
4711
anthony964d28e2012-05-17 23:39:46 +00004712 do { /* Break Code Block for error handling */
4713
4714 /* get information about option */
4715 if ( cli_wand->command == (const OptionInfo *) NULL )
4716 cli_wand->command = GetCommandOptionInfo(option);
anthony464f1c42012-04-22 08:51:01 +00004717#if 0
anthony964d28e2012-05-17 23:39:46 +00004718 (void) FormatLocaleFile(stderr, "CLIOption \"%s\" matched \"%s\"\n",
4719 option, cli_wand->command->mnemonic );
anthony464f1c42012-04-22 08:51:01 +00004720#endif
anthony964d28e2012-05-17 23:39:46 +00004721 option_type=(CommandOptionFlags) cli_wand->command->flags;
anthony464f1c42012-04-22 08:51:01 +00004722
anthony964d28e2012-05-17 23:39:46 +00004723 if ( option_type == UndefinedOptionFlag )
4724 CLIWandExceptionReturn(OptionFatalError,"UnrecognizedOption",option);
anthony464f1c42012-04-22 08:51:01 +00004725
anthony964d28e2012-05-17 23:39:46 +00004726 assert( LocaleCompare(cli_wand->command->mnemonic,option) == 0 );
anthony464f1c42012-04-22 08:51:01 +00004727
anthony964d28e2012-05-17 23:39:46 +00004728 /* depreciated options */
4729 if ( (option_type & DeprecateOptionFlag) != 0 )
4730 CLIWandExceptionBreak(OptionError,"DeprecatedOptionNoCode",option);
anthony464f1c42012-04-22 08:51:01 +00004731
anthony964d28e2012-05-17 23:39:46 +00004732 /* options that this module does not handle */
4733 if ((option_type & (SpecialOptionFlag|GenesisOptionFlag)) != 0 )
4734 CLIWandExceptionBreak(OptionFatalError,"InvalidUseOfOption",option);
anthony464f1c42012-04-22 08:51:01 +00004735
anthony964d28e2012-05-17 23:39:46 +00004736 /* Get argument strings from VarArgs
4737 How can you determine arguments is enough was supplied? */
4738 { size_t
4739 count = cli_wand->command->type;
anthony464f1c42012-04-22 08:51:01 +00004740
anthony964d28e2012-05-17 23:39:46 +00004741 va_list
4742 operands;
anthony464f1c42012-04-22 08:51:01 +00004743
anthony964d28e2012-05-17 23:39:46 +00004744 va_start(operands,option);
anthony464f1c42012-04-22 08:51:01 +00004745
anthony964d28e2012-05-17 23:39:46 +00004746 arg1=arg2=NULL;
4747 if ( count >= 1 )
4748 arg1=(const char *) va_arg(operands, const char *);
4749 if ( count >= 2 )
4750 arg2=(const char *) va_arg(operands, const char *);
anthony464f1c42012-04-22 08:51:01 +00004751
anthony964d28e2012-05-17 23:39:46 +00004752 va_end(operands);
anthony464f1c42012-04-22 08:51:01 +00004753
anthony52cb3df2012-04-24 03:29:32 +00004754#if 0
anthony964d28e2012-05-17 23:39:46 +00004755 (void) FormatLocaleFile(stderr,
4756 "CLIOption: \"%s\" Count: %ld Flags: %04x Args: \"%s\" \"%s\"\n",
4757 option,(long) count,option_type,arg1,arg2);
anthony464f1c42012-04-22 08:51:01 +00004758#endif
anthony964d28e2012-05-17 23:39:46 +00004759 }
4760
4761 /*
4762 Call the appropriate option handler
4763 */
4764
4765 /* FUTURE: this is temporary - get 'settings' to handle distribution of
4766 settings to images attributes,proprieties,artifacts */
4767 if ( cli_wand->wand.images != (Image *)NULL )
4768 SyncImagesSettings(cli_wand->wand.image_info,cli_wand->wand.images,
4769 cli_wand->wand.exception);
4770
4771 if ( (option_type & SettingOptionFlags) != 0 ) {
4772 CLISettingOptionInfo(cli_wand, option, arg1, arg2);
4773 // FUTURE: Sync Specific Settings into Image Properities (not global)
4774 }
4775
4776 /* Operators that do not need images - read, write, stack, clone */
4777 if ( (option_type & NoImageOperatorFlag) != 0)
4778 CLINoImageOperator(cli_wand, option, arg1, arg2);
4779
4780 /* FUTURE: The not a setting part below is a temporary hack due to
4781 * some options being both a Setting and a Simple operator.
4782 * Specifically -monitor, -depth, and -colorspace */
4783 if ( cli_wand->wand.images == (Image *)NULL )
4784 if ( ((option_type & (SimpleOperatorFlag|ListOperatorFlag)) != 0 ) &&
4785 ((option_type & SettingOptionFlags) == 0 )) /* temp hack */
4786 CLIWandExceptionBreak(OptionError,"NoImagesFound",option);
4787
4788 /* Operators work on single images, and needs a loop over the images */
4789 if ( (option_type & SimpleOperatorFlag) != 0)
4790 CLISimpleOperatorImages(cli_wand, option, arg1, arg2);
4791
4792 /* Operators that work on the image list as a whole */
4793 if ( (option_type & ListOperatorFlag) != 0 )
4794 CLIListOperatorImages(cli_wand, option, arg1, arg2);
4795
4796 } while (0); /* end Break code block */
anthony464f1c42012-04-22 08:51:01 +00004797
4798 cli_wand->command = (const OptionInfo *) NULL; /* prevent re-use later */
anthony464f1c42012-04-22 08:51:01 +00004799}