blob: 28aba9bed0c11bd15c14b32b42a9b230281f17d2 [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"
anthony7a4d6102012-07-01 09:48:25 +000060#include "MagickCore/pixel-private.h"
anthony805a2d42011-09-25 08:25:12 +000061
62/*
63 Define declarations.
64*/
anthonyafa3dfc2012-03-03 11:31:30 +000065#define USE_WAND_METHODS 0
66#define MAX_STACK_DEPTH 32
67#define UNDEFINED_COMPRESSION_QUALITY 0UL
68
anthonyb1d483a2012-04-14 12:53:56 +000069/* FUTURE: why is this default so specific? */
70#define DEFAULT_DISSIMILARITY_THRESHOLD "0.31830988618379067154"
71
anthony805a2d42011-09-25 08:25:12 +000072/*
73 Constant declaration. (temporary exports)
74*/
75static const char
76 BackgroundColor[] = "#fff", /* white */
anthony72feaa62012-01-17 06:46:23 +000077 BorderColor[] = "#dfdfdf", /* sRGB gray */
78 MatteColor[] = "#bdbdbd"; /* slightly darker gray */
anthony22de2722012-04-19 14:43:00 +000079
80/* For Debugging Geometry Input */
81#define ReportGeometry(flags,info) \
82 (void) FormatLocaleFile(stderr, "Geometry = 0x%04X : %lg x %lg %+lg %+lg\n", \
83 flags, info.rho, info.sigma, info.xi, info.psi )
anthony805a2d42011-09-25 08:25:12 +000084
85/*
86** Function to report on the progress of image operations
87*/
88static MagickBooleanType MonitorProgress(const char *text,
89 const MagickOffsetType offset,const MagickSizeType extent,
anthony43f425d2012-02-26 12:58:58 +000090 void *wand_unused(cli_wandent_data))
anthony805a2d42011-09-25 08:25:12 +000091{
92 char
93 message[MaxTextExtent],
94 tag[MaxTextExtent];
95
96 const char
97 *locale_message;
98
99 register char
100 *p;
101
102 if (extent < 2)
103 return(MagickTrue);
104 (void) CopyMagickMemory(tag,text,MaxTextExtent);
105 p=strrchr(tag,'/');
106 if (p != (char *) NULL)
107 *p='\0';
108 (void) FormatLocaleString(message,MaxTextExtent,"Monitor/%s",tag);
109 locale_message=GetLocaleMessage(message);
110 if (locale_message == message)
111 locale_message=tag;
112 if (p == (char *) NULL)
113 (void) FormatLocaleFile(stderr,"%s: %ld of %lu, %02ld%% complete\r",
114 locale_message,(long) offset,(unsigned long) extent,(long)
115 (100L*offset/(extent-1)));
116 else
117 (void) FormatLocaleFile(stderr,"%s[%s]: %ld of %lu, %02ld%% complete\r",
118 locale_message,p+1,(long) offset,(unsigned long) extent,(long)
119 (100L*offset/(extent-1)));
120 if (offset == (MagickOffsetType) (extent-1))
121 (void) FormatLocaleFile(stderr,"\n");
122 (void) fflush(stderr);
123 return(MagickTrue);
124}
125
126/*
127** GetImageCache() will read an image into a image cache if not already
128** present then return the image that is in the cache under that filename.
129*/
130static inline Image *GetImageCache(const ImageInfo *image_info,const char *path,
131 ExceptionInfo *exception)
132{
133 char
134 key[MaxTextExtent];
135
136 ExceptionInfo
137 *sans_exception;
138
139 Image
140 *image;
141
142 ImageInfo
143 *read_info;
144
145 (void) FormatLocaleString(key,MaxTextExtent,"cache:%s",path);
146 sans_exception=AcquireExceptionInfo();
147 image=(Image *) GetImageRegistry(ImageRegistryType,key,sans_exception);
148 sans_exception=DestroyExceptionInfo(sans_exception);
149 if (image != (Image *) NULL)
150 return(image);
151 read_info=CloneImageInfo(image_info);
152 (void) CopyMagickString(read_info->filename,path,MaxTextExtent);
153 image=ReadImage(read_info,exception);
154 read_info=DestroyImageInfo(read_info);
155 if (image != (Image *) NULL)
156 (void) SetImageRegistry(ImageRegistryType,key,image,exception);
157 return(image);
158}
159
anthony756cd0d2012-04-08 12:41:44 +0000160/*
anthonya89dd172011-10-04 13:29:35 +0000161 SparseColorOption() parse the complex -sparse-color argument into an
162 an array of floating point values than call SparseColorImage().
163 Argument is a complex mix of floating-point pixel coodinates, and color
164 specifications (or direct floating point numbers). The number of floats
165 needed to represent a color varies depending on teh current channel
166 setting.
anthony43f425d2012-02-26 12:58:58 +0000167
168 This really should be in MagickCore, so that other API's can make use of it.
anthony805a2d42011-09-25 08:25:12 +0000169*/
170static Image *SparseColorOption(const Image *image,
171 const SparseColorMethod method,const char *arguments,
anthony31f1bf72012-01-30 12:37:22 +0000172 ExceptionInfo *exception)
anthony805a2d42011-09-25 08:25:12 +0000173{
174 char
175 token[MaxTextExtent];
176
177 const char
178 *p;
179
180 double
181 *sparse_arguments;
182
183 Image
184 *sparse_image;
185
186 PixelInfo
187 color;
188
189 MagickBooleanType
190 error;
191
192 register size_t
193 x;
194
195 size_t
196 number_arguments,
197 number_colors;
198
199 assert(image != (Image *) NULL);
200 assert(image->signature == MagickSignature);
anthony7bcfe7f2012-03-30 14:01:22 +0000201 if (IfMagickTrue(image->debug))
anthony805a2d42011-09-25 08:25:12 +0000202 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
203 assert(exception != (ExceptionInfo *) NULL);
204 assert(exception->signature == MagickSignature);
205 /*
anthonyb1d483a2012-04-14 12:53:56 +0000206 Limit channels according to image
207 add up number of values needed per color.
anthony805a2d42011-09-25 08:25:12 +0000208 */
209 number_colors=0;
210 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
211 number_colors++;
212 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
213 number_colors++;
214 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
215 number_colors++;
216 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
217 (image->colorspace == CMYKColorspace))
218 number_colors++;
219 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
anthony7bcfe7f2012-03-30 14:01:22 +0000220 IfMagickTrue(image->matte))
anthony805a2d42011-09-25 08:25:12 +0000221 number_colors++;
222
223 /*
224 Read string, to determine number of arguments needed,
225 */
226 p=arguments;
227 x=0;
228 while( *p != '\0' )
229 {
230 GetMagickToken(p,&p,token);
231 if ( token[0] == ',' ) continue;
anthony31f1bf72012-01-30 12:37:22 +0000232 if ( isalpha((int) token[0]) || token[0] == '#' )
233 x += number_colors; /* color argument found */
anthonyce8dcb32012-03-21 13:20:31 +0000234 else
anthony805a2d42011-09-25 08:25:12 +0000235 x++; /* floating point argument */
anthony805a2d42011-09-25 08:25:12 +0000236 }
anthony31f1bf72012-01-30 12:37:22 +0000237 /* control points and color values */
anthony7bcfe7f2012-03-30 14:01:22 +0000238 error = IsMagickTrue( x % (2+number_colors) );
anthony31f1bf72012-01-30 12:37:22 +0000239 number_arguments=x;
anthony7bcfe7f2012-03-30 14:01:22 +0000240 if ( IfMagickTrue(error) ) {
anthony805a2d42011-09-25 08:25:12 +0000241 (void) ThrowMagickException(exception,GetMagickModule(),
anthony43f425d2012-02-26 12:58:58 +0000242 OptionError, "InvalidArgument", "'%s': %s", "sparse-color",
anthony805a2d42011-09-25 08:25:12 +0000243 "Invalid number of Arguments");
244 return( (Image *)NULL);
245 }
246
247 /* Allocate and fill in the floating point arguments */
248 sparse_arguments=(double *) AcquireQuantumMemory(number_arguments,
249 sizeof(*sparse_arguments));
250 if (sparse_arguments == (double *) NULL) {
251 (void) ThrowMagickException(exception,GetMagickModule(),ResourceLimitError,
252 "MemoryAllocationFailed","%s","SparseColorOption");
253 return( (Image *)NULL);
254 }
255 (void) ResetMagickMemory(sparse_arguments,0,number_arguments*
256 sizeof(*sparse_arguments));
257 p=arguments;
258 x=0;
259 while( *p != '\0' && x < number_arguments ) {
260 /* X coordinate */
261 token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token);
262 if ( token[0] == '\0' ) break;
263 if ( isalpha((int) token[0]) || token[0] == '#' ) {
264 (void) ThrowMagickException(exception,GetMagickModule(),
anthony43f425d2012-02-26 12:58:58 +0000265 OptionError, "InvalidArgument", "'%s': %s", "sparse-color",
anthony805a2d42011-09-25 08:25:12 +0000266 "Color found, instead of X-coord");
267 error = MagickTrue;
268 break;
269 }
cristydbdd0e32011-11-04 23:29:40 +0000270 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +0000271 /* Y coordinate */
272 token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token);
273 if ( token[0] == '\0' ) break;
274 if ( isalpha((int) token[0]) || token[0] == '#' ) {
275 (void) ThrowMagickException(exception,GetMagickModule(),
anthony43f425d2012-02-26 12:58:58 +0000276 OptionError, "InvalidArgument", "'%s': %s", "sparse-color",
anthony805a2d42011-09-25 08:25:12 +0000277 "Color found, instead of Y-coord");
278 error = MagickTrue;
279 break;
280 }
cristydbdd0e32011-11-04 23:29:40 +0000281 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
anthony31f1bf72012-01-30 12:37:22 +0000282 /* color name or function given in string argument */
283 token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token);
284 if ( token[0] == '\0' ) break;
285 if ( isalpha((int) token[0]) || token[0] == '#' ) {
286 /* Color string given */
287 (void) QueryColorCompliance(token,AllCompliance,&color,
288 exception);
289 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
290 sparse_arguments[x++] = QuantumScale*color.red;
291 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
292 sparse_arguments[x++] = QuantumScale*color.green;
293 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
294 sparse_arguments[x++] = QuantumScale*color.blue;
295 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
296 (image->colorspace == CMYKColorspace))
297 sparse_arguments[x++] = QuantumScale*color.black;
298 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
anthony7bcfe7f2012-03-30 14:01:22 +0000299 IfMagickTrue(image->matte))
anthony31f1bf72012-01-30 12:37:22 +0000300 sparse_arguments[x++] = QuantumScale*color.alpha;
anthony805a2d42011-09-25 08:25:12 +0000301 }
anthony31f1bf72012-01-30 12:37:22 +0000302 else {
303 /* Colors given as a set of floating point values - experimental */
304 /* NB: token contains the first floating point value to use! */
305 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
306 {
307 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
308 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
309 break;
310 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
311 token[0] = ','; /* used this token - get another */
anthony805a2d42011-09-25 08:25:12 +0000312 }
anthony31f1bf72012-01-30 12:37:22 +0000313 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
314 {
315 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
316 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
317 break;
318 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
319 token[0] = ','; /* used this token - get another */
320 }
321 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
322 {
323 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
324 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
325 break;
326 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
327 token[0] = ','; /* used this token - get another */
328 }
329 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
330 (image->colorspace == CMYKColorspace))
331 {
332 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
333 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
334 break;
335 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
336 token[0] = ','; /* used this token - get another */
337 }
338 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
anthony7bcfe7f2012-03-30 14:01:22 +0000339 IfMagickTrue(image->matte))
anthony31f1bf72012-01-30 12:37:22 +0000340 {
341 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
342 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
343 break;
344 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
345 token[0] = ','; /* used this token - get another */
anthony805a2d42011-09-25 08:25:12 +0000346 }
347 }
348 }
349 if ( number_arguments != x && !error ) {
350 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
anthony43f425d2012-02-26 12:58:58 +0000351 "InvalidArgument","'%s': %s","sparse-color","Argument Parsing Error");
anthony805a2d42011-09-25 08:25:12 +0000352 sparse_arguments=(double *) RelinquishMagickMemory(sparse_arguments);
353 return( (Image *)NULL);
354 }
355 if ( error )
356 return( (Image *)NULL);
357
anthony31f1bf72012-01-30 12:37:22 +0000358 /* Call the Sparse Color Interpolation function with the parsed arguments */
anthony805a2d42011-09-25 08:25:12 +0000359 sparse_image=SparseColorImage(image,method,number_arguments,sparse_arguments,
360 exception);
361 sparse_arguments=(double *) RelinquishMagickMemory(sparse_arguments);
362 return( sparse_image );
363}
364
365/*
366%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
367% %
368% %
369% %
anthony464f1c42012-04-22 08:51:01 +0000370% 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 +0000371% %
372% %
373% %
374%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
375%
376% CLISettingOptionInfo() applies a single settings option into a CLI wand
377% holding the image_info, draw_info, quantize_info structures that will be
378% used when processing the images.
379%
380% These options do no require images to be present in the CLI wand for them
381% to be able to be set, in which case they will generally be applied to image
382% that are read in later
anthony80c37752012-01-16 01:03:11 +0000383%
384% Options handled by this function are listed in CommandOptions[] of
anthonyfd706f92012-01-19 04:22:02 +0000385% "option.c" that is one of "SettingOptionFlags" option flags.
anthony805a2d42011-09-25 08:25:12 +0000386%
anthony2052d272012-02-28 12:48:29 +0000387% The format of the CLISettingOptionInfo method is:
anthony1afdc7a2011-10-05 11:54:28 +0000388%
anthonyafa3dfc2012-03-03 11:31:30 +0000389% void CLISettingOptionInfo(MagickCLI *cli_wand,
anthonye5fcd362012-04-09 04:02:09 +0000390% const char *option, const char *arg1, const char *arg2)
anthony805a2d42011-09-25 08:25:12 +0000391%
392% A description of each parameter follows:
393%
anthony43f425d2012-02-26 12:58:58 +0000394% o cli_wand: structure holding settings to be applied
anthony805a2d42011-09-25 08:25:12 +0000395%
anthonydcf510d2011-10-30 13:51:40 +0000396% o option: The option string to be set
anthony805a2d42011-09-25 08:25:12 +0000397%
anthonye5fcd362012-04-09 04:02:09 +0000398% o arg1, arg2: optional argument strings to the operation
399% arg2 is currently only used by "-limit"
anthonydcf510d2011-10-30 13:51:40 +0000400%
anthony805a2d42011-09-25 08:25:12 +0000401*/
anthonyafa3dfc2012-03-03 11:31:30 +0000402WandExport void CLISettingOptionInfo(MagickCLI *cli_wand,
anthonye5fcd362012-04-09 04:02:09 +0000403 const char *option,const char *arg1, const char *arg2)
anthony805a2d42011-09-25 08:25:12 +0000404{
anthony30b912a2012-03-22 01:20:28 +0000405 ssize_t
406 parse; /* option argument parsing (string to value table lookup) */
407
anthony43f425d2012-02-26 12:58:58 +0000408 assert(cli_wand != (MagickCLI *) NULL);
409 assert(cli_wand->signature == WandSignature);
410 assert(cli_wand->wand.signature == WandSignature);
anthony7bcfe7f2012-03-30 14:01:22 +0000411 if (IfMagickTrue(cli_wand->wand.debug))
anthony43f425d2012-02-26 12:58:58 +0000412 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
anthony1afdc7a2011-10-05 11:54:28 +0000413
anthony2e4501b2012-03-30 04:41:54 +0000414#define _image_info (cli_wand->wand.image_info)
415#define _exception (cli_wand->wand.exception)
416#define _draw_info (cli_wand->draw_info)
417#define _quantize_info (cli_wand->quantize_info)
anthony24aa8822012-03-11 00:56:06 +0000418#define IfSetOption (*option=='-')
anthony7bcfe7f2012-03-30 14:01:22 +0000419#define ArgBoolean IsMagickTrue(IfSetOption)
420#define ArgBooleanNot IsMagickFalse(IfSetOption)
anthony24aa8822012-03-11 00:56:06 +0000421#define ArgBooleanString (IfSetOption?"true":"false")
422#define ArgOption(def) (IfSetOption?arg1:(const char *)(def))
anthony74b1cfc2011-10-06 12:44:16 +0000423
anthony4837ac22012-05-18 23:39:48 +0000424#if 0
425Setting are not directly involved with images, so can not
426interpret Percent Escapes in Arguments, At least not yet */
427
428#define _process_flags (cli_wand->process_flags)
429#define _option_type ((CommandOptionFlags) cli_wand->command->flags)
430 /* Interpret Percent Escapes in Arguments - using first image */
431 arg1 = arg1n,
432 arg2 = arg2n;
433 if ( (((_process_flags & ProcessInterpretProperities) != 0 )
434 || ((_option_type & AlwaysInterpretArgsFlag) != 0)
435 ) && ((_option_type & NeverInterpretArgsFlag) == 0) ) {
436 /* Interpret Percent escapes in argument 1 */
437 if (arg1n != (char *) NULL) {
438 arg1=InterpretImageProperties(_image_info,_image,arg1n,_exception);
439 if (arg1 == (char *) NULL) {
440 CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
441 arg1=arg1n; /* use the given argument as is */
442 }
443 }
444 if (arg2n != (char *) NULL) {
445 arg2=InterpretImageProperties(_image_info,_image,arg2n,_exception);
446 if (arg2 == (char *) NULL) {
447 CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
448 arg2=arg2n; /* use the given argument as is */
449 }
450 }
451 }
452#undef _process_flags
453#undef _option_type
454#endif
455
anthonyafa3dfc2012-03-03 11:31:30 +0000456 switch (*(option+1))
anthony805a2d42011-09-25 08:25:12 +0000457 {
458 case 'a':
459 {
anthonyafa3dfc2012-03-03 11:31:30 +0000460 if (LocaleCompare("adjoin",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000461 {
anthony92c93bd2012-03-19 14:02:47 +0000462 _image_info->adjoin = ArgBoolean;
anthony805a2d42011-09-25 08:25:12 +0000463 break;
464 }
anthonyafa3dfc2012-03-03 11:31:30 +0000465 if (LocaleCompare("affine",option+1) == 0)
anthony1afdc7a2011-10-05 11:54:28 +0000466 {
anthony464f1c42012-04-22 08:51:01 +0000467 CLIWandWarnReplaced("-draw 'affine ...'");
anthony74b1cfc2011-10-06 12:44:16 +0000468 if (IfSetOption)
anthony92c93bd2012-03-19 14:02:47 +0000469 (void) ParseAffineGeometry(arg1,&_draw_info->affine,_exception);
anthony74b1cfc2011-10-06 12:44:16 +0000470 else
anthony92c93bd2012-03-19 14:02:47 +0000471 GetAffineMatrix(&_draw_info->affine);
anthony1afdc7a2011-10-05 11:54:28 +0000472 break;
473 }
anthonyafa3dfc2012-03-03 11:31:30 +0000474 if (LocaleCompare("antialias",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000475 {
anthony92c93bd2012-03-19 14:02:47 +0000476 _image_info->antialias =
477 _draw_info->stroke_antialias =
478 _draw_info->text_antialias = ArgBoolean;
anthony805a2d42011-09-25 08:25:12 +0000479 break;
480 }
anthony31f1bf72012-01-30 12:37:22 +0000481 if (LocaleCompare("attenuate",option+1) == 0)
482 {
anthony7bcfe7f2012-03-30 14:01:22 +0000483 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthony92c93bd2012-03-19 14:02:47 +0000484 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
485 (void) SetImageOption(_image_info,option+1,ArgOption("1.0"));
anthony31f1bf72012-01-30 12:37:22 +0000486 break;
487 }
anthonyafa3dfc2012-03-03 11:31:30 +0000488 if (LocaleCompare("authenticate",option+1) == 0)
anthonydcf510d2011-10-30 13:51:40 +0000489 {
anthony92c93bd2012-03-19 14:02:47 +0000490 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +0000491 break;
492 }
anthonyebb73a22012-03-22 14:25:52 +0000493 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +0000494 }
495 case 'b':
496 {
anthonyafa3dfc2012-03-03 11:31:30 +0000497 if (LocaleCompare("background",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000498 {
anthony92c93bd2012-03-19 14:02:47 +0000499 /* FUTURE: both _image_info attribute & ImageOption in use!
500 _image_info only used directly for generating new images.
anthony72feaa62012-01-17 06:46:23 +0000501 SyncImageSettings() used to set per-image attribute.
502
anthony92c93bd2012-03-19 14:02:47 +0000503 FUTURE: if _image_info->background_color is not set then
anthony30b912a2012-03-22 01:20:28 +0000504 we should fall back to per-image background_color
505
506 At this time -background will 'wipe out' the per-image
507 background color!
508
509 Better error handling of QueryColorCompliance() needed.
anthony74b1cfc2011-10-06 12:44:16 +0000510 */
anthony92c93bd2012-03-19 14:02:47 +0000511 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony72feaa62012-01-17 06:46:23 +0000512 (void) QueryColorCompliance(ArgOption(BackgroundColor),AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +0000513 &_image_info->background_color,_exception);
anthony805a2d42011-09-25 08:25:12 +0000514 break;
515 }
anthonyafa3dfc2012-03-03 11:31:30 +0000516 if (LocaleCompare("bias",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000517 {
anthony52bef752012-03-27 13:54:47 +0000518 /* FUTURE: bias OBSOLETED, replaced by Artifact "convolve:bias"
anthony31f1bf72012-01-30 12:37:22 +0000519 as it is actually rarely used except in direct convolve operations
520 Usage outside a direct convolve operation is actally non-sensible!
anthony72feaa62012-01-17 06:46:23 +0000521
522 SyncImageSettings() used to set per-image attribute.
anthony74b1cfc2011-10-06 12:44:16 +0000523 */
anthony7bcfe7f2012-03-30 14:01:22 +0000524 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthony5330ae02012-03-20 14:17:01 +0000525 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyf46d4262012-03-26 03:30:34 +0000526 (void) SetImageOption(_image_info,"convolve:bias",ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +0000527 break;
528 }
anthonyafa3dfc2012-03-03 11:31:30 +0000529 if (LocaleCompare("black-point-compensation",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000530 {
anthony72feaa62012-01-17 06:46:23 +0000531 /* Used as a image chromaticity setting
532 SyncImageSettings() used to set per-image attribute.
533 */
anthony92c93bd2012-03-19 14:02:47 +0000534 (void) SetImageOption(_image_info,option+1,ArgBooleanString);
anthony805a2d42011-09-25 08:25:12 +0000535 break;
536 }
anthonyafa3dfc2012-03-03 11:31:30 +0000537 if (LocaleCompare("blue-primary",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000538 {
anthonyafbaed72011-10-26 12:05:04 +0000539 /* Image chromaticity X,Y NB: Y=X if Y not defined
540 Used by many coders including PNG
anthony72feaa62012-01-17 06:46:23 +0000541 SyncImageSettings() used to set per-image attribute.
anthonyafbaed72011-10-26 12:05:04 +0000542 */
anthonyf42014d2012-03-25 09:53:06 +0000543 arg1=ArgOption("0.0");
anthony7bcfe7f2012-03-30 14:01:22 +0000544 if (IfMagickFalse(IsGeometry(arg1)))
anthony5330ae02012-03-20 14:17:01 +0000545 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyf42014d2012-03-25 09:53:06 +0000546 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000547 break;
548 }
anthonyafa3dfc2012-03-03 11:31:30 +0000549 if (LocaleCompare("bordercolor",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000550 {
anthony92c93bd2012-03-19 14:02:47 +0000551 /* FUTURE: both _image_info attribute & ImageOption in use!
anthony72feaa62012-01-17 06:46:23 +0000552 SyncImageSettings() used to set per-image attribute.
anthony30b912a2012-03-22 01:20:28 +0000553 Better error checking of QueryColorCompliance().
anthony72feaa62012-01-17 06:46:23 +0000554 */
anthony74b1cfc2011-10-06 12:44:16 +0000555 if (IfSetOption)
anthony805a2d42011-09-25 08:25:12 +0000556 {
anthony92c93bd2012-03-19 14:02:47 +0000557 (void) SetImageOption(_image_info,option+1,arg1);
anthony24aa8822012-03-11 00:56:06 +0000558 (void) QueryColorCompliance(arg1,AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +0000559 &_image_info->border_color,_exception);
anthony24aa8822012-03-11 00:56:06 +0000560 (void) QueryColorCompliance(arg1,AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +0000561 &_draw_info->border_color,_exception);
anthony805a2d42011-09-25 08:25:12 +0000562 break;
563 }
anthony92c93bd2012-03-19 14:02:47 +0000564 (void) DeleteImageOption(_image_info,option+1);
anthony74b1cfc2011-10-06 12:44:16 +0000565 (void) QueryColorCompliance(BorderColor,AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +0000566 &_image_info->border_color,_exception);
anthony74b1cfc2011-10-06 12:44:16 +0000567 (void) QueryColorCompliance(BorderColor,AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +0000568 &_draw_info->border_color,_exception);
anthony805a2d42011-09-25 08:25:12 +0000569 break;
570 }
anthonyafa3dfc2012-03-03 11:31:30 +0000571 if (LocaleCompare("box",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000572 {
anthony464f1c42012-04-22 08:51:01 +0000573 CLIWandWarnReplaced("-undercolor");
anthony975a8d72012-04-12 13:54:36 +0000574 CLISettingOptionInfo(cli_wand,"-undercolor",arg1, arg2);
anthonyfd706f92012-01-19 04:22:02 +0000575 break;
anthony805a2d42011-09-25 08:25:12 +0000576 }
anthonyebb73a22012-03-22 14:25:52 +0000577 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +0000578 }
579 case 'c':
580 {
anthonyafa3dfc2012-03-03 11:31:30 +0000581 if (LocaleCompare("cache",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000582 {
583 MagickSizeType
584 limit;
585
anthony7bcfe7f2012-03-30 14:01:22 +0000586 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthony5330ae02012-03-20 14:17:01 +0000587 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +0000588 limit=MagickResourceInfinity;
anthony24aa8822012-03-11 00:56:06 +0000589 if (LocaleCompare("unlimited",arg1) != 0)
590 limit=(MagickSizeType) SiPrefixToDoubleInterval(arg1,100.0);
anthony805a2d42011-09-25 08:25:12 +0000591 (void) SetMagickResourceLimit(MemoryResource,limit);
592 (void) SetMagickResourceLimit(MapResource,2*limit);
593 break;
594 }
anthonyafa3dfc2012-03-03 11:31:30 +0000595 if (LocaleCompare("caption",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000596 {
anthony92c93bd2012-03-19 14:02:47 +0000597 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +0000598 break;
599 }
anthonyafa3dfc2012-03-03 11:31:30 +0000600 if (LocaleCompare("channel",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000601 {
anthony30b912a2012-03-22 01:20:28 +0000602 arg1=ArgOption("default");
603 parse=ParseChannelOption(arg1);
604 if (parse < 0)
605 CLIWandExceptArgBreak(OptionError,"UnrecognizedChannelType",
606 option,arg1);
607 _image_info->channel=(ChannelType) parse;
608 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000609 break;
610 }
anthonyafa3dfc2012-03-03 11:31:30 +0000611 if (LocaleCompare("colorspace",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000612 {
anthonyafbaed72011-10-26 12:05:04 +0000613 /* Setting used for new images via AquireImage()
614 But also used as a SimpleImageOperator
615 Undefined colorspace means don't modify images on
616 read or as a operation */
anthony30b912a2012-03-22 01:20:28 +0000617 parse = ParseCommandOption(MagickColorspaceOptions,MagickFalse,
618 ArgOption("undefined"));
619 if (parse < 0)
anthony5330ae02012-03-20 14:17:01 +0000620 CLIWandExceptArgBreak(OptionError,"UnrecognizedColorspace",
621 option,arg1);
anthony30b912a2012-03-22 01:20:28 +0000622 _image_info->colorspace=(ColorspaceType) parse;
anthony805a2d42011-09-25 08:25:12 +0000623 break;
624 }
anthonyafa3dfc2012-03-03 11:31:30 +0000625 if (LocaleCompare("comment",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000626 {
anthony92c93bd2012-03-19 14:02:47 +0000627 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +0000628 break;
629 }
anthonyafa3dfc2012-03-03 11:31:30 +0000630 if (LocaleCompare("compose",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000631 {
anthony92c93bd2012-03-19 14:02:47 +0000632 /* FUTURE: _image_info should be used,
anthony72feaa62012-01-17 06:46:23 +0000633 SyncImageSettings() used to set per-image attribute. - REMOVE
634
anthonyafbaed72011-10-26 12:05:04 +0000635 This setting should NOT be used to set image 'compose'
anthony92c93bd2012-03-19 14:02:47 +0000636 "-layer" operators shoud use _image_info if defined otherwise
anthony72feaa62012-01-17 06:46:23 +0000637 they should use a per-image compose setting.
anthony965524b2011-10-07 12:34:14 +0000638 */
anthonyebb73a22012-03-22 14:25:52 +0000639 parse = ParseCommandOption(MagickComposeOptions,MagickFalse,
640 ArgOption("undefined"));
641 if (parse < 0)
642 CLIWandExceptArgBreak(OptionError,"UnrecognizedComposeOperator",
643 option,arg1);
644 _image_info->compose=(CompositeOperator) parse;
anthony92c93bd2012-03-19 14:02:47 +0000645 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +0000646 break;
647 }
anthonyafa3dfc2012-03-03 11:31:30 +0000648 if (LocaleCompare("compress",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000649 {
anthony92c93bd2012-03-19 14:02:47 +0000650 /* FUTURE: What should be used? _image_info or ImageOption ???
anthony5f867ae2011-10-09 10:28:34 +0000651 The former is more efficent, but Crisy prefers the latter!
anthony72feaa62012-01-17 06:46:23 +0000652 SyncImageSettings() used to set per-image attribute.
anthony5f867ae2011-10-09 10:28:34 +0000653
anthony92c93bd2012-03-19 14:02:47 +0000654 The coders appears to use _image_info, not Image_Option
anthony5f867ae2011-10-09 10:28:34 +0000655 however the image attribute (for save) is set from the
656 ImageOption!
anthony72feaa62012-01-17 06:46:23 +0000657
658 Note that "undefined" is a different setting to "none".
anthony5f867ae2011-10-09 10:28:34 +0000659 */
anthonyebb73a22012-03-22 14:25:52 +0000660 parse = ParseCommandOption(MagickCompressOptions,MagickFalse,
661 ArgOption("undefined"));
662 if (parse < 0)
663 CLIWandExceptArgBreak(OptionError,"UnrecognizedImageCompression",
664 option,arg1);
665 _image_info->compression=(CompressionType) parse;
anthony92c93bd2012-03-19 14:02:47 +0000666 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +0000667 break;
668 }
anthonyebb73a22012-03-22 14:25:52 +0000669 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +0000670 }
671 case 'd':
672 {
anthonyafa3dfc2012-03-03 11:31:30 +0000673 if (LocaleCompare("debug",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000674 {
anthony72feaa62012-01-17 06:46:23 +0000675 /* SyncImageSettings() used to set per-image attribute. */
anthonyebb73a22012-03-22 14:25:52 +0000676 arg1=ArgOption("none");
677 parse = ParseCommandOption(MagickLogEventOptions,MagickFalse,arg1);
678 if (parse < 0)
679 CLIWandExceptArgBreak(OptionError,"UnrecognizedEventType",
680 option,arg1);
681 (void) SetLogEventMask(arg1);
682 _image_info->debug=IsEventLogging(); /* extract logging*/
anthony43f425d2012-02-26 12:58:58 +0000683 cli_wand->wand.debug=IsEventLogging();
anthony805a2d42011-09-25 08:25:12 +0000684 break;
685 }
anthonyafa3dfc2012-03-03 11:31:30 +0000686 if (LocaleCompare("define",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000687 {
anthony24aa8822012-03-11 00:56:06 +0000688 if (LocaleNCompare(arg1,"registry:",9) == 0)
anthony805a2d42011-09-25 08:25:12 +0000689 {
anthony5f867ae2011-10-09 10:28:34 +0000690 if (IfSetOption)
anthony92c93bd2012-03-19 14:02:47 +0000691 (void) DefineImageRegistry(StringRegistryType,arg1+9,_exception);
anthony5f867ae2011-10-09 10:28:34 +0000692 else
anthony24aa8822012-03-11 00:56:06 +0000693 (void) DeleteImageRegistry(arg1+9);
anthony805a2d42011-09-25 08:25:12 +0000694 break;
695 }
anthony24aa8822012-03-11 00:56:06 +0000696 /* DefineImageOption() equals SetImageOption() but with '=' */
anthony5f867ae2011-10-09 10:28:34 +0000697 if (IfSetOption)
anthony92c93bd2012-03-19 14:02:47 +0000698 (void) DefineImageOption(_image_info,arg1);
anthony7bcfe7f2012-03-30 14:01:22 +0000699 else if (IsMagickFalse(DeleteImageOption(_image_info,arg1)))
anthonyebb73a22012-03-22 14:25:52 +0000700 CLIWandExceptArgBreak(OptionError,"NoSuchOption",option,arg1);
anthony805a2d42011-09-25 08:25:12 +0000701 break;
702 }
anthonyafa3dfc2012-03-03 11:31:30 +0000703 if (LocaleCompare("delay",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000704 {
anthonyafbaed72011-10-26 12:05:04 +0000705 /* Only used for new images via AcquireImage()
706 FUTURE: Option should also be used for "-morph" (color morphing)
anthony5f867ae2011-10-09 10:28:34 +0000707 */
anthonyebb73a22012-03-22 14:25:52 +0000708 arg1=ArgOption("0");
anthony7bcfe7f2012-03-30 14:01:22 +0000709 if (IfMagickFalse(IsGeometry(arg1)))
anthonyebb73a22012-03-22 14:25:52 +0000710 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
711 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000712 break;
713 }
anthonyafa3dfc2012-03-03 11:31:30 +0000714 if (LocaleCompare("density",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000715 {
anthony92c93bd2012-03-19 14:02:47 +0000716 /* FUTURE: strings used in _image_info attr and _draw_info!
anthony72feaa62012-01-17 06:46:23 +0000717 Basically as density can be in a XxY form!
718
719 SyncImageSettings() used to set per-image attribute.
720 */
anthony7bcfe7f2012-03-30 14:01:22 +0000721 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthonyebb73a22012-03-22 14:25:52 +0000722 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +0000723 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
724 (void) CloneString(&_image_info->density,ArgOption(NULL));
725 (void) CloneString(&_draw_info->density,_image_info->density);
anthony805a2d42011-09-25 08:25:12 +0000726 break;
727 }
anthonyafa3dfc2012-03-03 11:31:30 +0000728 if (LocaleCompare("depth",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000729 {
anthony72feaa62012-01-17 06:46:23 +0000730 /* This is also a SimpleImageOperator! for 8->16 vaule trunc !!!!
731 SyncImageSettings() used to set per-image attribute.
732 */
anthony7bcfe7f2012-03-30 14:01:22 +0000733 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthonyebb73a22012-03-22 14:25:52 +0000734 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +0000735 _image_info->depth=IfSetOption?StringToUnsignedLong(arg1)
anthony5f867ae2011-10-09 10:28:34 +0000736 :MAGICKCORE_QUANTUM_DEPTH;
anthony805a2d42011-09-25 08:25:12 +0000737 break;
738 }
anthonyafa3dfc2012-03-03 11:31:30 +0000739 if (LocaleCompare("direction",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000740 {
anthony92c93bd2012-03-19 14:02:47 +0000741 /* Image Option is only used to set _draw_info */
anthonyebb73a22012-03-22 14:25:52 +0000742 arg1=ArgOption("undefined");
743 parse = ParseCommandOption(MagickDirectionOptions,MagickFalse,arg1);
744 if (parse < 0)
745 CLIWandExceptArgBreak(OptionError,"UnrecognizedDirectionType",
746 option,arg1);
747 _draw_info->direction=(DirectionType) parse;
748 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000749 break;
750 }
anthonyafa3dfc2012-03-03 11:31:30 +0000751 if (LocaleCompare("display",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000752 {
anthony92c93bd2012-03-19 14:02:47 +0000753 (void) CloneString(&_image_info->server_name,ArgOption(NULL));
754 (void) CloneString(&_draw_info->server_name,_image_info->server_name);
anthony805a2d42011-09-25 08:25:12 +0000755 break;
756 }
anthonyafa3dfc2012-03-03 11:31:30 +0000757 if (LocaleCompare("dispose",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000758 {
anthony72feaa62012-01-17 06:46:23 +0000759 /* only used in setting new images */
anthonyebb73a22012-03-22 14:25:52 +0000760 arg1=ArgOption("undefined");
761 parse = ParseCommandOption(MagickDisposeOptions,MagickFalse,arg1);
762 if (parse < 0)
763 CLIWandExceptArgBreak(OptionError,"UnrecognizedDisposeMethod",
764 option,arg1);
anthony92c93bd2012-03-19 14:02:47 +0000765 (void) SetImageOption(_image_info,option+1,ArgOption("undefined"));
anthony805a2d42011-09-25 08:25:12 +0000766 break;
767 }
anthonyb1d483a2012-04-14 12:53:56 +0000768 if (LocaleCompare("dissimilarity-threshold",option+1) == 0)
769 {
770 /* FUTURE: this is only used by CompareImages() which is used
771 only by the "compare" CLI program at this time. */
772 arg1=ArgOption(DEFAULT_DISSIMILARITY_THRESHOLD);
773 if (IfMagickFalse(IsGeometry(arg1)))
774 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
775 (void) SetImageOption(_image_info,option+1,arg1);
776 break;
777 }
anthonyafa3dfc2012-03-03 11:31:30 +0000778 if (LocaleCompare("dither",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000779 {
anthony92c93bd2012-03-19 14:02:47 +0000780 /* _image_info attr (on/off), _quantize_info attr (on/off)
781 but also ImageInfo and _quantize_info method!
anthony72feaa62012-01-17 06:46:23 +0000782 FUTURE: merge the duality of the dithering options
783 */
cristycbda6112012-05-27 20:57:16 +0000784 _image_info->dither = ArgBoolean;
anthony92c93bd2012-03-19 14:02:47 +0000785 (void) SetImageOption(_image_info,option+1,ArgOption("none"));
786 _quantize_info->dither_method=(DitherMethod) ParseCommandOption(
cristycbda6112012-05-27 20:57:16 +0000787 MagickDitherOptions,MagickFalse,ArgOption("none"));
anthony92c93bd2012-03-19 14:02:47 +0000788 if (_quantize_info->dither_method == NoDitherMethod)
cristycbda6112012-05-27 20:57:16 +0000789 _image_info->dither = MagickFalse;
anthony805a2d42011-09-25 08:25:12 +0000790 break;
791 }
anthonyebb73a22012-03-22 14:25:52 +0000792 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +0000793 }
794 case 'e':
795 {
anthonyafa3dfc2012-03-03 11:31:30 +0000796 if (LocaleCompare("encoding",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000797 {
anthony92c93bd2012-03-19 14:02:47 +0000798 (void) CloneString(&_draw_info->encoding,ArgOption("undefined"));
799 (void) SetImageOption(_image_info,option+1,_draw_info->encoding);
anthony805a2d42011-09-25 08:25:12 +0000800 break;
801 }
anthonyafa3dfc2012-03-03 11:31:30 +0000802 if (LocaleCompare("endian",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000803 {
anthony92c93bd2012-03-19 14:02:47 +0000804 /* Both _image_info attr and ImageInfo */
anthony2a0ec8c2012-03-24 04:35:56 +0000805 arg1 = ArgOption("undefined");
806 parse = ParseCommandOption(MagickEndianOptions,MagickFalse,arg1);
807 if (parse < 0)
808 CLIWandExceptArgBreak(OptionError,"UnrecognizedEndianType",
809 option,arg1);
anthonyf46d4262012-03-26 03:30:34 +0000810 /* FUTURE: check alloc/free of endian string! - remove? */
cristyaa2c16c2012-03-25 22:21:35 +0000811 _image_info->endian=(EndianType) (*arg1);
anthony2a0ec8c2012-03-24 04:35:56 +0000812 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000813 break;
814 }
anthonyafa3dfc2012-03-03 11:31:30 +0000815 if (LocaleCompare("extract",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000816 {
anthony92c93bd2012-03-19 14:02:47 +0000817 (void) CloneString(&_image_info->extract,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +0000818 break;
819 }
anthonyebb73a22012-03-22 14:25:52 +0000820 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +0000821 }
822 case 'f':
823 {
anthonyafa3dfc2012-03-03 11:31:30 +0000824 if (LocaleCompare("family",option+1) == 0)
anthony6dc09cd2011-10-12 08:56:49 +0000825 {
anthony92c93bd2012-03-19 14:02:47 +0000826 (void) CloneString(&_draw_info->family,ArgOption(NULL));
anthony6dc09cd2011-10-12 08:56:49 +0000827 break;
828 }
anthonyafa3dfc2012-03-03 11:31:30 +0000829 if (LocaleCompare("fill",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000830 {
anthony92c93bd2012-03-19 14:02:47 +0000831 /* Set "fill" OR "fill-pattern" in _draw_info
anthonyfd706f92012-01-19 04:22:02 +0000832 The original fill color is preserved if a fill-pattern is given.
833 That way it does not effect other operations that directly using
834 the fill color and, can be retored using "+tile".
anthonyafbaed72011-10-26 12:05:04 +0000835 */
anthony72feaa62012-01-17 06:46:23 +0000836 MagickBooleanType
837 status;
anthony6dc09cd2011-10-12 08:56:49 +0000838
839 ExceptionInfo
840 *sans;
841
anthonyfd706f92012-01-19 04:22:02 +0000842 PixelInfo
843 color;
844
anthony2a0ec8c2012-03-24 04:35:56 +0000845 arg1 = ArgOption("none"); /* +fill turns it off! */
846 (void) SetImageOption(_image_info,option+1,arg1);
anthony92c93bd2012-03-19 14:02:47 +0000847 if (_draw_info->fill_pattern != (Image *) NULL)
848 _draw_info->fill_pattern=DestroyImage(_draw_info->fill_pattern);
anthony72feaa62012-01-17 06:46:23 +0000849
850 /* is it a color or a image? -- ignore exceptions */
851 sans=AcquireExceptionInfo();
anthony2a0ec8c2012-03-24 04:35:56 +0000852 status=QueryColorCompliance(arg1,AllCompliance,&color,sans);
anthony72feaa62012-01-17 06:46:23 +0000853 sans=DestroyExceptionInfo(sans);
anthonyfd706f92012-01-19 04:22:02 +0000854
anthony7bcfe7f2012-03-30 14:01:22 +0000855 if (IfMagickFalse(status))
anthony2a0ec8c2012-03-24 04:35:56 +0000856 _draw_info->fill_pattern=GetImageCache(_image_info,arg1,_exception);
anthonyfd706f92012-01-19 04:22:02 +0000857 else
anthony92c93bd2012-03-19 14:02:47 +0000858 _draw_info->fill=color;
anthony805a2d42011-09-25 08:25:12 +0000859 break;
860 }
anthonyafa3dfc2012-03-03 11:31:30 +0000861 if (LocaleCompare("filter",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000862 {
anthony72feaa62012-01-17 06:46:23 +0000863 /* SyncImageSettings() used to set per-image attribute. */
anthony2a0ec8c2012-03-24 04:35:56 +0000864 arg1 = ArgOption("undefined");
865 parse = ParseCommandOption(MagickFilterOptions,MagickFalse,arg1);
866 if (parse < 0)
867 CLIWandExceptArgBreak(OptionError,"UnrecognizedImageFilter",
868 option,arg1);
869 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000870 break;
871 }
anthonyafa3dfc2012-03-03 11:31:30 +0000872 if (LocaleCompare("font",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000873 {
anthony92c93bd2012-03-19 14:02:47 +0000874 (void) CloneString(&_draw_info->font,ArgOption(NULL));
875 (void) CloneString(&_image_info->font,_draw_info->font);
anthony805a2d42011-09-25 08:25:12 +0000876 break;
877 }
anthonyafa3dfc2012-03-03 11:31:30 +0000878 if (LocaleCompare("format",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000879 {
anthonydcf510d2011-10-30 13:51:40 +0000880 /* FUTURE: why the ping test, you could set ping after this! */
881 /*
anthony805a2d42011-09-25 08:25:12 +0000882 register const char
883 *q;
884
anthony24aa8822012-03-11 00:56:06 +0000885 for (q=strchr(arg1,'%'); q != (char *) NULL; q=strchr(q+1,'%'))
anthony805a2d42011-09-25 08:25:12 +0000886 if (strchr("Agkrz@[#",*(q+1)) != (char *) NULL)
anthony92c93bd2012-03-19 14:02:47 +0000887 _image_info->ping=MagickFalse;
anthonydcf510d2011-10-30 13:51:40 +0000888 */
anthony92c93bd2012-03-19 14:02:47 +0000889 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +0000890 break;
891 }
anthonyafa3dfc2012-03-03 11:31:30 +0000892 if (LocaleCompare("fuzz",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000893 {
anthony72feaa62012-01-17 06:46:23 +0000894 /* Option used to set image fuzz! unless blank canvas (from color)
anthonydcf510d2011-10-30 13:51:40 +0000895 Image attribute used for color compare operations
anthony72feaa62012-01-17 06:46:23 +0000896 SyncImageSettings() used to set per-image attribute.
897
anthony2a0ec8c2012-03-24 04:35:56 +0000898 FUTURE: Can't find anything else using _image_info->fuzz directly!
899 remove direct sttribute from image_info
anthony6613bf32011-10-15 07:24:44 +0000900 */
anthony2a0ec8c2012-03-24 04:35:56 +0000901 arg1=ArgOption("0");
anthony7bcfe7f2012-03-30 14:01:22 +0000902 if (IfMagickFalse(IsGeometry(arg1)))
anthony2a0ec8c2012-03-24 04:35:56 +0000903 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
904 _image_info->fuzz=StringToDoubleInterval(arg1,(double)
anthony80c37752012-01-16 01:03:11 +0000905 QuantumRange+1.0);
anthony2a0ec8c2012-03-24 04:35:56 +0000906 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000907 break;
908 }
anthonyebb73a22012-03-22 14:25:52 +0000909 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +0000910 }
911 case 'g':
912 {
anthonyafa3dfc2012-03-03 11:31:30 +0000913 if (LocaleCompare("gravity",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000914 {
anthony72feaa62012-01-17 06:46:23 +0000915 /* SyncImageSettings() used to set per-image attribute. */
anthonyfe1aa782012-03-24 13:43:04 +0000916 arg1 = ArgOption("none");
917 parse = ParseCommandOption(MagickGravityOptions,MagickFalse,arg1);
918 if (parse < 0)
919 CLIWandExceptArgBreak(OptionError,"UnrecognizedGravityType",
920 option,arg1);
anthonyfe1aa782012-03-24 13:43:04 +0000921 _draw_info->gravity=(GravityType) parse;
anthonye8490972012-04-03 13:16:01 +0000922 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000923 break;
924 }
anthonyafa3dfc2012-03-03 11:31:30 +0000925 if (LocaleCompare("green-primary",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000926 {
anthonydcf510d2011-10-30 13:51:40 +0000927 /* Image chromaticity X,Y NB: Y=X if Y not defined
anthony72feaa62012-01-17 06:46:23 +0000928 SyncImageSettings() used to set per-image attribute.
929 Used directly by many coders
anthonydcf510d2011-10-30 13:51:40 +0000930 */
anthonyf42014d2012-03-25 09:53:06 +0000931 arg1=ArgOption("0.0");
anthony7bcfe7f2012-03-30 14:01:22 +0000932 if (IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +0000933 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyf42014d2012-03-25 09:53:06 +0000934 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000935 break;
936 }
anthonyebb73a22012-03-22 14:25:52 +0000937 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +0000938 }
anthonyb1d483a2012-04-14 12:53:56 +0000939 case 'h':
940 {
941 if (LocaleCompare("highlight-color",option+1) == 0)
942 {
943 /* FUTURE: this is only used by CompareImages() which is used
944 only by the "compare" CLI program at this time. */
945 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
946 break;
947 }
948 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
949 }
anthony805a2d42011-09-25 08:25:12 +0000950 case 'i':
951 {
anthonyafa3dfc2012-03-03 11:31:30 +0000952 if (LocaleCompare("intent",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000953 {
anthony72feaa62012-01-17 06:46:23 +0000954 /* Only used by coders: MIFF, MPC, BMP, PNG
anthonydcf510d2011-10-30 13:51:40 +0000955 and for image profile call to AcquireTransformThreadSet()
anthony72feaa62012-01-17 06:46:23 +0000956 SyncImageSettings() used to set per-image attribute.
anthonydcf510d2011-10-30 13:51:40 +0000957 */
anthonyfe1aa782012-03-24 13:43:04 +0000958 arg1 = ArgOption("indefined");
959 parse = ParseCommandOption(MagickIntentOptions,MagickFalse,arg1);
960 if (parse < 0)
961 CLIWandExceptArgBreak(OptionError,"UnrecognizedIntentType",
962 option,arg1);
963 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000964 break;
965 }
anthonyafa3dfc2012-03-03 11:31:30 +0000966 if (LocaleCompare("interlace",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000967 {
anthony92c93bd2012-03-19 14:02:47 +0000968 /* _image_info is directly used by coders (so why an image setting?)
anthony72feaa62012-01-17 06:46:23 +0000969 SyncImageSettings() used to set per-image attribute.
anthonydcf510d2011-10-30 13:51:40 +0000970 */
anthonyfe1aa782012-03-24 13:43:04 +0000971 arg1 = ArgOption("undefined");
972 parse = ParseCommandOption(MagickInterlaceOptions,MagickFalse,arg1);
973 if (parse < 0)
974 CLIWandExceptArgBreak(OptionError,"UnrecognizedInterlaceType",
975 option,arg1);
976 _image_info->interlace=(InterlaceType) parse;
977 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000978 break;
979 }
anthonyafa3dfc2012-03-03 11:31:30 +0000980 if (LocaleCompare("interline-spacing",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000981 {
anthony7bcfe7f2012-03-30 14:01:22 +0000982 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +0000983 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +0000984 (void) SetImageOption(_image_info,option+1, ArgOption(NULL));
985 _draw_info->interline_spacing=StringToDouble(ArgOption("0"),
anthony72feaa62012-01-17 06:46:23 +0000986 (char **) NULL);
anthony805a2d42011-09-25 08:25:12 +0000987 break;
988 }
anthonyafa3dfc2012-03-03 11:31:30 +0000989 if (LocaleCompare("interpolate",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000990 {
anthonyfd706f92012-01-19 04:22:02 +0000991 /* SyncImageSettings() used to set per-image attribute. */
anthonyfe1aa782012-03-24 13:43:04 +0000992 arg1 = ArgOption("undefined");
993 parse = ParseCommandOption(MagickInterpolateOptions,MagickFalse,arg1);
994 if (parse < 0)
995 CLIWandExceptArgBreak(OptionError,"UnrecognizedInterpolateMethod",
996 option,arg1);
997 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000998 break;
999 }
anthonyafa3dfc2012-03-03 11:31:30 +00001000 if (LocaleCompare("interword-spacing",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001001 {
anthony7bcfe7f2012-03-30 14:01:22 +00001002 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00001003 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001004 (void) SetImageOption(_image_info,option+1, ArgOption(NULL));
1005 _draw_info->interword_spacing=StringToDouble(ArgOption("0"),(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +00001006 break;
1007 }
anthonyebb73a22012-03-22 14:25:52 +00001008 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001009 }
1010 case 'k':
1011 {
anthonyafa3dfc2012-03-03 11:31:30 +00001012 if (LocaleCompare("kerning",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001013 {
anthony7bcfe7f2012-03-30 14:01:22 +00001014 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00001015 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001016 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1017 _draw_info->kerning=StringToDouble(ArgOption("0"),(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +00001018 break;
1019 }
anthonyebb73a22012-03-22 14:25:52 +00001020 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001021 }
1022 case 'l':
1023 {
anthonyafa3dfc2012-03-03 11:31:30 +00001024 if (LocaleCompare("label",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001025 {
anthony72feaa62012-01-17 06:46:23 +00001026 /* only used for new images - not in SyncImageOptions() */
anthony92c93bd2012-03-19 14:02:47 +00001027 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +00001028 break;
1029 }
anthony756cd0d2012-04-08 12:41:44 +00001030 if (LocaleCompare("limit",option+1) == 0)
1031 {
1032 MagickSizeType
1033 limit;
1034
1035 limit=MagickResourceInfinity;
1036 parse= ParseCommandOption(MagickResourceOptions,MagickFalse,arg1);
1037 if ( parse < 0 )
1038 CLIWandExceptArgBreak(OptionError,"UnrecognizedResourceType",
1039 option,arg1);
1040 if (LocaleCompare("unlimited",arg2) != 0)
1041 limit=(MagickSizeType) SiPrefixToDoubleInterval(arg2,100.0);
1042 (void) SetMagickResourceLimit((ResourceType)parse,limit);
1043 break;
1044 }
anthonyafa3dfc2012-03-03 11:31:30 +00001045 if (LocaleCompare("log",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001046 {
anthonyfe1aa782012-03-24 13:43:04 +00001047 if (IfSetOption) {
1048 if ((strchr(arg1,'%') == (char *) NULL))
1049 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony24aa8822012-03-11 00:56:06 +00001050 (void) SetLogFormat(arg1);
anthonyfe1aa782012-03-24 13:43:04 +00001051 }
anthony805a2d42011-09-25 08:25:12 +00001052 break;
1053 }
anthony975a8d72012-04-12 13:54:36 +00001054 if (LocaleCompare("lowlight-color",option+1) == 0)
1055 {
anthonyb1d483a2012-04-14 12:53:56 +00001056 /* FUTURE: this is only used by CompareImages() which is used
1057 only by the "compare" CLI program at this time. */
anthony975a8d72012-04-12 13:54:36 +00001058 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1059 break;
1060 }
anthonyafa3dfc2012-03-03 11:31:30 +00001061 if (LocaleCompare("loop",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001062 {
anthony72feaa62012-01-17 06:46:23 +00001063 /* SyncImageSettings() used to set per-image attribute. */
anthonyfe1aa782012-03-24 13:43:04 +00001064 arg1=ArgOption("0");
anthony7bcfe7f2012-03-30 14:01:22 +00001065 if (IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00001066 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1067 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +00001068 break;
1069 }
anthonyebb73a22012-03-22 14:25:52 +00001070 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001071 }
1072 case 'm':
1073 {
anthonyafa3dfc2012-03-03 11:31:30 +00001074 if (LocaleCompare("mattecolor",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001075 {
anthony72feaa62012-01-17 06:46:23 +00001076 /* SyncImageSettings() used to set per-image attribute. */
anthony92c93bd2012-03-19 14:02:47 +00001077 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony72feaa62012-01-17 06:46:23 +00001078 (void) QueryColorCompliance(ArgOption(MatteColor),AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +00001079 &_image_info->matte_color,_exception);
anthony805a2d42011-09-25 08:25:12 +00001080 break;
anthonycd358fc2012-04-16 13:59:03 +00001081 }
anthonyb1d483a2012-04-14 12:53:56 +00001082 if (LocaleCompare("metric",option+1) == 0)
1083 {
1084 /* FUTURE: this is only used by CompareImages() which is used
1085 only by the "compare" CLI program at this time. */
1086 parse=ParseCommandOption(MagickMetricOptions,MagickFalse,arg1);
1087 if ( parse < 0 )
1088 CLIWandExceptArgBreak(OptionError,"UnrecognizedMetricType",
1089 option,arg1);
1090 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthonycd358fc2012-04-16 13:59:03 +00001091 break;
anthony805a2d42011-09-25 08:25:12 +00001092 }
anthonyafa3dfc2012-03-03 11:31:30 +00001093 if (LocaleCompare("monitor",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001094 {
anthony92c93bd2012-03-19 14:02:47 +00001095 (void) SetImageInfoProgressMonitor(_image_info, IfSetOption?
anthony31f1bf72012-01-30 12:37:22 +00001096 MonitorProgress: (MagickProgressMonitor) NULL, (void *) NULL);
anthony805a2d42011-09-25 08:25:12 +00001097 break;
1098 }
anthonyafa3dfc2012-03-03 11:31:30 +00001099 if (LocaleCompare("monochrome",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001100 {
anthony24aa8822012-03-11 00:56:06 +00001101 /* Setting (used by some input coders!) -- why?
1102 Warning: This is also Special '-type' SimpleOperator
anthony72feaa62012-01-17 06:46:23 +00001103 */
anthony92c93bd2012-03-19 14:02:47 +00001104 _image_info->monochrome= ArgBoolean;
anthony805a2d42011-09-25 08:25:12 +00001105 break;
1106 }
anthonyebb73a22012-03-22 14:25:52 +00001107 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001108 }
1109 case 'o':
1110 {
anthonyafa3dfc2012-03-03 11:31:30 +00001111 if (LocaleCompare("orient",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001112 {
anthony72feaa62012-01-17 06:46:23 +00001113 /* Is not used when defining for new images.
anthonydcf510d2011-10-30 13:51:40 +00001114 This makes it more of a 'operation' than a setting
anthony72feaa62012-01-17 06:46:23 +00001115 FUTURE: make set meta-data operator instead.
1116 SyncImageSettings() used to set per-image attribute.
anthonydcf510d2011-10-30 13:51:40 +00001117 */
anthony7bc87992012-03-25 02:32:51 +00001118 parse=ParseCommandOption(MagickOrientationOptions,MagickFalse,
1119 ArgOption("undefined"));
1120 if (parse < 0)
1121 CLIWandExceptArgBreak(OptionError,"UnrecognizedImageOrientation",
1122 option,arg1);
1123 _image_info->orientation=(OrientationType)parse;
anthony92c93bd2012-03-19 14:02:47 +00001124 (void) SetImageOption(_image_info,option+1, ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +00001125 break;
1126 }
anthonyebb73a22012-03-22 14:25:52 +00001127 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001128 }
1129 case 'p':
1130 {
anthonyafa3dfc2012-03-03 11:31:30 +00001131 if (LocaleCompare("page",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001132 {
anthony7bc87992012-03-25 02:32:51 +00001133 /* Only used for new images and image generators.
anthony72feaa62012-01-17 06:46:23 +00001134 SyncImageSettings() used to set per-image attribute. ?????
1135 That last is WRONG!!!!
anthony7bc87992012-03-25 02:32:51 +00001136 FUTURE: adjust named 'page' sizes according density
anthony72feaa62012-01-17 06:46:23 +00001137 */
anthony805a2d42011-09-25 08:25:12 +00001138 char
1139 *canonical_page,
1140 page[MaxTextExtent];
1141
1142 const char
1143 *image_option;
1144
1145 MagickStatusType
1146 flags;
1147
1148 RectangleInfo
1149 geometry;
1150
anthonydcf510d2011-10-30 13:51:40 +00001151 if (!IfSetOption)
anthony805a2d42011-09-25 08:25:12 +00001152 {
anthony92c93bd2012-03-19 14:02:47 +00001153 (void) DeleteImageOption(_image_info,option+1);
1154 (void) CloneString(&_image_info->page,(char *) NULL);
anthony805a2d42011-09-25 08:25:12 +00001155 break;
1156 }
1157 (void) ResetMagickMemory(&geometry,0,sizeof(geometry));
anthony92c93bd2012-03-19 14:02:47 +00001158 image_option=GetImageOption(_image_info,"page");
anthony805a2d42011-09-25 08:25:12 +00001159 if (image_option != (const char *) NULL)
1160 flags=ParseAbsoluteGeometry(image_option,&geometry);
anthony24aa8822012-03-11 00:56:06 +00001161 canonical_page=GetPageGeometry(arg1);
anthony805a2d42011-09-25 08:25:12 +00001162 flags=ParseAbsoluteGeometry(canonical_page,&geometry);
1163 canonical_page=DestroyString(canonical_page);
1164 (void) FormatLocaleString(page,MaxTextExtent,"%lux%lu",
1165 (unsigned long) geometry.width,(unsigned long) geometry.height);
1166 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
1167 (void) FormatLocaleString(page,MaxTextExtent,"%lux%lu%+ld%+ld",
1168 (unsigned long) geometry.width,(unsigned long) geometry.height,
1169 (long) geometry.x,(long) geometry.y);
anthony92c93bd2012-03-19 14:02:47 +00001170 (void) SetImageOption(_image_info,option+1,page);
1171 (void) CloneString(&_image_info->page,page);
anthony805a2d42011-09-25 08:25:12 +00001172 break;
1173 }
anthonyafa3dfc2012-03-03 11:31:30 +00001174 if (LocaleCompare("ping",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001175 {
anthony92c93bd2012-03-19 14:02:47 +00001176 _image_info->ping = ArgBoolean;
anthony805a2d42011-09-25 08:25:12 +00001177 break;
1178 }
anthonyafa3dfc2012-03-03 11:31:30 +00001179 if (LocaleCompare("pointsize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001180 {
anthonyf42014d2012-03-25 09:53:06 +00001181 if (IfSetOption) {
anthony7bcfe7f2012-03-30 14:01:22 +00001182 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00001183 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1184 _image_info->pointsize =
1185 _draw_info->pointsize =
1186 StringToDouble(arg1,(char **) NULL);
1187 }
1188 else {
1189 _image_info->pointsize=0.0; /* unset pointsize */
1190 _draw_info->pointsize=12.0;
1191 }
anthony805a2d42011-09-25 08:25:12 +00001192 break;
1193 }
anthonyafa3dfc2012-03-03 11:31:30 +00001194 if (LocaleCompare("precision",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001195 {
anthonyf42014d2012-03-25 09:53:06 +00001196 arg1=ArgOption("-1");
anthony7bcfe7f2012-03-30 14:01:22 +00001197 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00001198 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1199 (void) SetMagickPrecision(StringToInteger(arg1));
anthony805a2d42011-09-25 08:25:12 +00001200 break;
1201 }
anthonydcf510d2011-10-30 13:51:40 +00001202 /* FUTURE: Only the 'preview' coder appears to use this
anthonya3ef4ed2012-03-17 06:52:53 +00001203 * DEPRECIATE the coder? Leaving only the 'preview' operator.
anthonyafa3dfc2012-03-03 11:31:30 +00001204 if (LocaleCompare("preview",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001205 {
anthony92c93bd2012-03-19 14:02:47 +00001206 _image_info->preview_type=UndefinedPreview;
anthonydcf510d2011-10-30 13:51:40 +00001207 if (IfSetOption)
anthony92c93bd2012-03-19 14:02:47 +00001208 _image_info->preview_type=(PreviewType) ParseCommandOption(
anthony24aa8822012-03-11 00:56:06 +00001209 MagickPreviewOptions,MagickFalse,arg1);
anthony805a2d42011-09-25 08:25:12 +00001210 break;
1211 }
anthonydcf510d2011-10-30 13:51:40 +00001212 */
anthonyebb73a22012-03-22 14:25:52 +00001213 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001214 }
1215 case 'q':
1216 {
anthonyafa3dfc2012-03-03 11:31:30 +00001217 if (LocaleCompare("quality",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001218 {
anthony7bcfe7f2012-03-30 14:01:22 +00001219 if (IfMagickFalse(IsGeometry(arg1)))
anthony7bc87992012-03-25 02:32:51 +00001220 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyf42014d2012-03-25 09:53:06 +00001221 _image_info->quality= IfSetOption ? StringToUnsignedLong(arg1)
1222 : UNDEFINED_COMPRESSION_QUALITY;
anthony92c93bd2012-03-19 14:02:47 +00001223 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +00001224 break;
1225 }
anthonyafa3dfc2012-03-03 11:31:30 +00001226 if (LocaleCompare("quantize",option+1) == 0)
anthonyafbaed72011-10-26 12:05:04 +00001227 {
anthony92c93bd2012-03-19 14:02:47 +00001228 /* Just a set direct in _quantize_info */
anthony7bc87992012-03-25 02:32:51 +00001229 arg1=ArgOption("undefined");
1230 parse=ParseCommandOption(MagickColorspaceOptions,MagickFalse,arg1);
1231 if (parse < 0)
1232 CLIWandExceptArgBreak(OptionError,"UnrecognizedColorspace",
1233 option,arg1);
1234 _quantize_info->colorspace=(ColorspaceType)parse;
anthonyafbaed72011-10-26 12:05:04 +00001235 break;
1236 }
anthonyafa3dfc2012-03-03 11:31:30 +00001237 if (LocaleCompare("quiet",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001238 {
anthonyf42014d2012-03-25 09:53:06 +00001239 /* FUTURE: if two -quiet is performed you can not do +quiet!
1240 This needs to be checked over thoughly.
1241 */
anthony805a2d42011-09-25 08:25:12 +00001242 static WarningHandler
1243 warning_handler = (WarningHandler) NULL;
anthony72feaa62012-01-17 06:46:23 +00001244
anthonyafbaed72011-10-26 12:05:04 +00001245 WarningHandler
1246 tmp = SetWarningHandler((WarningHandler) NULL);
anthony805a2d42011-09-25 08:25:12 +00001247
anthonyafbaed72011-10-26 12:05:04 +00001248 if ( tmp != (WarningHandler) NULL)
1249 warning_handler = tmp; /* remember the old handler */
1250 if (!IfSetOption) /* set the old handler */
1251 warning_handler=SetWarningHandler(warning_handler);
anthony805a2d42011-09-25 08:25:12 +00001252 break;
1253 }
anthonyebb73a22012-03-22 14:25:52 +00001254 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001255 }
1256 case 'r':
1257 {
anthonyafa3dfc2012-03-03 11:31:30 +00001258 if (LocaleCompare("red-primary",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001259 {
anthonydcf510d2011-10-30 13:51:40 +00001260 /* Image chromaticity X,Y NB: Y=X if Y not defined
1261 Used by many coders
anthony72feaa62012-01-17 06:46:23 +00001262 SyncImageSettings() used to set per-image attribute.
anthonydcf510d2011-10-30 13:51:40 +00001263 */
anthonyf42014d2012-03-25 09:53:06 +00001264 arg1=ArgOption("0.0");
anthony7bcfe7f2012-03-30 14:01:22 +00001265 if (IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00001266 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyf42014d2012-03-25 09:53:06 +00001267 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +00001268 break;
1269 }
cristyb0f7a182012-04-06 23:33:11 +00001270 if (LocaleCompare("regard-warnings",option+1) == 0)
anthonye5fcd362012-04-09 04:02:09 +00001271 /* FUTURE: to be replaced by a 'fatal-level' type setting */
cristyb0f7a182012-04-06 23:33:11 +00001272 break;
anthonyafa3dfc2012-03-03 11:31:30 +00001273 if (LocaleCompare("render",option+1) == 0)
anthonyafbaed72011-10-26 12:05:04 +00001274 {
anthony92c93bd2012-03-19 14:02:47 +00001275 /* _draw_info only setting */
1276 _draw_info->render= ArgBooleanNot;
anthonyafbaed72011-10-26 12:05:04 +00001277 break;
1278 }
anthony756cd0d2012-04-08 12:41:44 +00001279 if (LocaleCompare("respect-parenthesis",option+1) == 0)
1280 {
1281 /* link image and setting stacks - option is itself saved on stack! */
1282 (void) SetImageOption(_image_info,option+1,ArgBooleanString);
1283 break;
1284 }
anthonyebb73a22012-03-22 14:25:52 +00001285 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001286 }
1287 case 's':
1288 {
anthonyafa3dfc2012-03-03 11:31:30 +00001289 if (LocaleCompare("sampling-factor",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001290 {
anthonyafbaed72011-10-26 12:05:04 +00001291 /* FUTURE: should be converted to jpeg:sampling_factor */
anthony7bcfe7f2012-03-30 14:01:22 +00001292 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00001293 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001294 (void) CloneString(&_image_info->sampling_factor,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +00001295 break;
1296 }
anthonyafa3dfc2012-03-03 11:31:30 +00001297 if (LocaleCompare("scene",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001298 {
anthonyf42014d2012-03-25 09:53:06 +00001299 /* SyncImageSettings() used to set this as a per-image attribute.
anthony72feaa62012-01-17 06:46:23 +00001300 What ??? Why ????
1301 */
anthony7bcfe7f2012-03-30 14:01:22 +00001302 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00001303 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001304 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1305 _image_info->scene=StringToUnsignedLong(ArgOption("0"));
anthony805a2d42011-09-25 08:25:12 +00001306 break;
1307 }
anthonyafa3dfc2012-03-03 11:31:30 +00001308 if (LocaleCompare("seed",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001309 {
anthony7bcfe7f2012-03-30 14:01:22 +00001310 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00001311 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
cristyd7761bb2012-04-14 01:42:05 +00001312 SetRandomSecretKey(
anthony24aa8822012-03-11 00:56:06 +00001313 IfSetOption ? (size_t) StringToUnsignedLong(arg1)
anthonyafbaed72011-10-26 12:05:04 +00001314 : (size_t) time((time_t *) NULL) );
anthony805a2d42011-09-25 08:25:12 +00001315 break;
1316 }
anthonyafa3dfc2012-03-03 11:31:30 +00001317 if (LocaleCompare("size",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001318 {
anthony92c93bd2012-03-19 14:02:47 +00001319 /* FUTURE: string in _image_info -- convert to Option ???
anthonyafbaed72011-10-26 12:05:04 +00001320 Look at the special handling for "size" in SetImageOption()
anthony74b1cfc2011-10-06 12:44:16 +00001321 */
anthony92c93bd2012-03-19 14:02:47 +00001322 (void) CloneString(&_image_info->size,ArgOption(NULL));
anthonyafbaed72011-10-26 12:05:04 +00001323 break;
1324 }
anthonyafa3dfc2012-03-03 11:31:30 +00001325 if (LocaleCompare("stretch",option+1) == 0)
anthonyafbaed72011-10-26 12:05:04 +00001326 {
anthonyf42014d2012-03-25 09:53:06 +00001327 arg1=ArgOption("undefined");
1328 parse = ParseCommandOption(MagickStretchOptions,MagickFalse,arg1);
1329 if (parse < 0)
1330 CLIWandExceptArgBreak(OptionError,"UnrecognizedStretchType",
1331 option,arg1);
1332 _draw_info->stretch=(StretchType) parse;
anthony805a2d42011-09-25 08:25:12 +00001333 break;
1334 }
anthonyafa3dfc2012-03-03 11:31:30 +00001335 if (LocaleCompare("stroke",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001336 {
anthonyafbaed72011-10-26 12:05:04 +00001337 /* set stroke color OR stroke-pattern
anthonyfd706f92012-01-19 04:22:02 +00001338 UPDATE: ensure stroke color is not destroyed is a pattern
1339 is given. Just in case the color is also used for other purposes.
anthonyafbaed72011-10-26 12:05:04 +00001340 */
anthony72feaa62012-01-17 06:46:23 +00001341 MagickBooleanType
1342 status;
anthonyafbaed72011-10-26 12:05:04 +00001343
1344 ExceptionInfo
1345 *sans;
1346
anthonyfd706f92012-01-19 04:22:02 +00001347 PixelInfo
1348 color;
1349
anthony2a0ec8c2012-03-24 04:35:56 +00001350 arg1 = ArgOption("none"); /* +fill turns it off! */
1351 (void) SetImageOption(_image_info,option+1,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001352 if (_draw_info->stroke_pattern != (Image *) NULL)
1353 _draw_info->stroke_pattern=DestroyImage(_draw_info->stroke_pattern);
anthony72feaa62012-01-17 06:46:23 +00001354
1355 /* is it a color or a image? -- ignore exceptions */
anthonyafbaed72011-10-26 12:05:04 +00001356 sans=AcquireExceptionInfo();
anthony2a0ec8c2012-03-24 04:35:56 +00001357 status=QueryColorCompliance(arg1,AllCompliance,&color,sans);
anthonyafbaed72011-10-26 12:05:04 +00001358 sans=DestroyExceptionInfo(sans);
anthonyfd706f92012-01-19 04:22:02 +00001359
anthony7bcfe7f2012-03-30 14:01:22 +00001360 if (IfMagickFalse(status))
anthony2a0ec8c2012-03-24 04:35:56 +00001361 _draw_info->stroke_pattern=GetImageCache(_image_info,arg1,_exception);
anthonyfd706f92012-01-19 04:22:02 +00001362 else
anthony92c93bd2012-03-19 14:02:47 +00001363 _draw_info->stroke=color;
anthony805a2d42011-09-25 08:25:12 +00001364 break;
1365 }
anthonyafa3dfc2012-03-03 11:31:30 +00001366 if (LocaleCompare("strokewidth",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001367 {
anthony7bcfe7f2012-03-30 14:01:22 +00001368 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00001369 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001370 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1371 _draw_info->stroke_width=StringToDouble(ArgOption("1.0"),
anthony72feaa62012-01-17 06:46:23 +00001372 (char **) NULL);
anthonyafbaed72011-10-26 12:05:04 +00001373 break;
1374 }
anthonyafa3dfc2012-03-03 11:31:30 +00001375 if (LocaleCompare("style",option+1) == 0)
anthonyafbaed72011-10-26 12:05:04 +00001376 {
anthonyf42014d2012-03-25 09:53:06 +00001377 arg1=ArgOption("undefined");
1378 parse = ParseCommandOption(MagickStyleOptions,MagickFalse,arg1);
1379 if (parse < 0)
1380 CLIWandExceptArgBreak(OptionError,"UnrecognizedStyleType",
1381 option,arg1);
1382 _draw_info->style=(StyleType) parse;
anthony805a2d42011-09-25 08:25:12 +00001383 break;
1384 }
anthonycd358fc2012-04-16 13:59:03 +00001385#if 0
anthonyb1d483a2012-04-14 12:53:56 +00001386 if (LocaleCompare("subimage-search",option+1) == 0)
1387 {
1388 /* FUTURE: this is only used by CompareImages() which is used
1389 only by the "compare" CLI program at this time. */
1390 (void) SetImageOption(_image_info,option+1,ArgBooleanString);
1391 break;
1392 }
anthonycd358fc2012-04-16 13:59:03 +00001393#endif
anthonyafa3dfc2012-03-03 11:31:30 +00001394 if (LocaleCompare("synchronize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001395 {
anthonyf42014d2012-03-25 09:53:06 +00001396 /* FUTURE: syncronize to storage - but what does that mean? */
anthony92c93bd2012-03-19 14:02:47 +00001397 _image_info->synchronize = ArgBoolean;
anthony805a2d42011-09-25 08:25:12 +00001398 break;
1399 }
anthonyebb73a22012-03-22 14:25:52 +00001400 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001401 }
1402 case 't':
1403 {
anthonyafa3dfc2012-03-03 11:31:30 +00001404 if (LocaleCompare("taint",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001405 {
anthony72feaa62012-01-17 06:46:23 +00001406 /* SyncImageSettings() used to set per-image attribute. */
anthony92c93bd2012-03-19 14:02:47 +00001407 (void) SetImageOption(_image_info,option+1,ArgBooleanString);
anthony805a2d42011-09-25 08:25:12 +00001408 break;
1409 }
anthonyafa3dfc2012-03-03 11:31:30 +00001410 if (LocaleCompare("texture",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001411 {
anthony4837ac22012-05-18 23:39:48 +00001412 /* Note: arguments do not have percent escapes expanded */
anthony52bef752012-03-27 13:54:47 +00001413 /* FUTURE: move _image_info string to option splay-tree
1414 Other than "montage" what uses "texture" ????
1415 */
anthony92c93bd2012-03-19 14:02:47 +00001416 (void) CloneString(&_image_info->texture,ArgOption(NULL));
anthonyafbaed72011-10-26 12:05:04 +00001417 break;
1418 }
anthonyafa3dfc2012-03-03 11:31:30 +00001419 if (LocaleCompare("tile",option+1) == 0)
anthonyafbaed72011-10-26 12:05:04 +00001420 {
anthony4837ac22012-05-18 23:39:48 +00001421 /* Note: arguments do not have percent escapes expanded */
anthony92c93bd2012-03-19 14:02:47 +00001422 _draw_info->fill_pattern=IfSetOption
1423 ?GetImageCache(_image_info,arg1,_exception)
1424 :DestroyImage(_draw_info->fill_pattern);
anthony805a2d42011-09-25 08:25:12 +00001425 break;
1426 }
anthonyafa3dfc2012-03-03 11:31:30 +00001427 if (LocaleCompare("tile-offset",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001428 {
anthony72feaa62012-01-17 06:46:23 +00001429 /* SyncImageSettings() used to set per-image attribute. ??? */
anthony52bef752012-03-27 13:54:47 +00001430 arg1=ArgOption("0");
anthony7bcfe7f2012-03-30 14:01:22 +00001431 if (IfMagickFalse(IsGeometry(arg1)))
anthony52bef752012-03-27 13:54:47 +00001432 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1433 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +00001434 break;
1435 }
anthonyafa3dfc2012-03-03 11:31:30 +00001436 if (LocaleCompare("transparent-color",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001437 {
anthony92c93bd2012-03-19 14:02:47 +00001438 /* FUTURE: both _image_info attribute & ImageOption in use!
1439 _image_info only used for generating new images.
anthony72feaa62012-01-17 06:46:23 +00001440 SyncImageSettings() used to set per-image attribute.
1441
anthonyafbaed72011-10-26 12:05:04 +00001442 Note that +transparent-color, means fall-back to image
1443 attribute so ImageOption is deleted, not set to a default.
1444 */
anthony7bcfe7f2012-03-30 14:01:22 +00001445 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthony52bef752012-03-27 13:54:47 +00001446 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001447 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony72feaa62012-01-17 06:46:23 +00001448 (void) QueryColorCompliance(ArgOption("none"),AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +00001449 &_image_info->transparent_color,_exception);
anthony805a2d42011-09-25 08:25:12 +00001450 break;
1451 }
anthonyafa3dfc2012-03-03 11:31:30 +00001452 if (LocaleCompare("treedepth",option+1) == 0)
anthony31f1bf72012-01-30 12:37:22 +00001453 {
anthony92c93bd2012-03-19 14:02:47 +00001454 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1455 _quantize_info->tree_depth=StringToUnsignedLong(ArgOption("0"));
anthony31f1bf72012-01-30 12:37:22 +00001456 break;
1457 }
anthonyafa3dfc2012-03-03 11:31:30 +00001458 if (LocaleCompare("type",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001459 {
anthony72feaa62012-01-17 06:46:23 +00001460 /* SyncImageSettings() used to set per-image attribute. */
anthony52bef752012-03-27 13:54:47 +00001461 parse=ParseCommandOption(MagickTypeOptions,MagickFalse,
1462 ArgOption("undefined"));
1463 if (parse < 0)
1464 CLIWandExceptArgBreak(OptionError,"UnrecognizedImageType",
1465 option,arg1);
1466 _image_info->type=(ImageType) parse;
anthony92c93bd2012-03-19 14:02:47 +00001467 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +00001468 break;
1469 }
anthonyebb73a22012-03-22 14:25:52 +00001470 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001471 }
1472 case 'u':
1473 {
anthonyafa3dfc2012-03-03 11:31:30 +00001474 if (LocaleCompare("undercolor",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001475 {
anthony92c93bd2012-03-19 14:02:47 +00001476 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony72feaa62012-01-17 06:46:23 +00001477 (void) QueryColorCompliance(ArgOption("none"),AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +00001478 &_draw_info->undercolor,_exception);
anthony805a2d42011-09-25 08:25:12 +00001479 break;
1480 }
anthonyafa3dfc2012-03-03 11:31:30 +00001481 if (LocaleCompare("units",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001482 {
anthony72feaa62012-01-17 06:46:23 +00001483 /* SyncImageSettings() used to set per-image attribute.
anthony92c93bd2012-03-19 14:02:47 +00001484 Should this effect _draw_info X and Y resolution?
anthony72feaa62012-01-17 06:46:23 +00001485 FUTURE: this probably should be part of the density setting
1486 */
anthony52bef752012-03-27 13:54:47 +00001487 parse=ParseCommandOption(MagickResolutionOptions,MagickFalse,
1488 ArgOption("undefined"));
1489 if (parse < 0)
1490 CLIWandExceptArgBreak(OptionError,"UnrecognizedUnitsType",
1491 option,arg1);
1492 _image_info->units=(ResolutionType) parse;
anthony92c93bd2012-03-19 14:02:47 +00001493 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +00001494 break;
1495 }
anthonyebb73a22012-03-22 14:25:52 +00001496 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001497 }
1498 case 'v':
1499 {
anthonyafa3dfc2012-03-03 11:31:30 +00001500 if (LocaleCompare("verbose",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001501 {
anthony24aa8822012-03-11 00:56:06 +00001502 /* FUTURE: Remember all options become image artifacts
anthony92c93bd2012-03-19 14:02:47 +00001503 _image_info->verbose is only used by coders.
anthonyab3a50c2011-10-27 11:48:57 +00001504 */
anthony92c93bd2012-03-19 14:02:47 +00001505 (void) SetImageOption(_image_info,option+1,ArgBooleanString);
1506 _image_info->verbose= ArgBoolean;
1507 _image_info->ping=MagickFalse; /* verbose can't be a ping */
anthony805a2d42011-09-25 08:25:12 +00001508 break;
1509 }
anthonyafa3dfc2012-03-03 11:31:30 +00001510 if (LocaleCompare("view",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001511 {
anthony92c93bd2012-03-19 14:02:47 +00001512 /* FUTURE: Convert from _image_info to ImageOption
anthonyab3a50c2011-10-27 11:48:57 +00001513 Only used by coder FPX
anthony52bef752012-03-27 13:54:47 +00001514 And it only tests existance, not its content!
anthonyab3a50c2011-10-27 11:48:57 +00001515 */
anthony92c93bd2012-03-19 14:02:47 +00001516 (void) CloneString(&_image_info->view,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +00001517 break;
1518 }
anthonyafa3dfc2012-03-03 11:31:30 +00001519 if (LocaleCompare("virtual-pixel",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001520 {
anthonyfd706f92012-01-19 04:22:02 +00001521 /* SyncImageSettings() used to set per-image attribute.
1522 This is VERY deep in the image caching structure.
1523 */
anthony52bef752012-03-27 13:54:47 +00001524 parse=ParseCommandOption(MagickVirtualPixelOptions,MagickFalse,
1525 ArgOption("undefined"));
1526 if (parse < 0)
1527 CLIWandExceptArgBreak(OptionError,"UnrecognizedVirtualPixelMethod",
1528 option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001529 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +00001530 break;
1531 }
anthonyebb73a22012-03-22 14:25:52 +00001532 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001533 }
1534 case 'w':
1535 {
anthonyafa3dfc2012-03-03 11:31:30 +00001536 if (LocaleCompare("weight",option+1) == 0)
anthonyab3a50c2011-10-27 11:48:57 +00001537 {
anthony72feaa62012-01-17 06:46:23 +00001538 /* Just what does using a font 'weight' do ???
anthonydcf510d2011-10-30 13:51:40 +00001539 There is no "-list weight" output (reference manual says there is)
anthonyab3a50c2011-10-27 11:48:57 +00001540 */
anthony52bef752012-03-27 13:54:47 +00001541 arg1=ArgOption("all");
anthony92c93bd2012-03-19 14:02:47 +00001542 _draw_info->weight=StringToUnsignedLong(arg1);
anthony24aa8822012-03-11 00:56:06 +00001543 if (LocaleCompare(arg1,"all") == 0)
anthony92c93bd2012-03-19 14:02:47 +00001544 _draw_info->weight=0;
anthony24aa8822012-03-11 00:56:06 +00001545 if (LocaleCompare(arg1,"bold") == 0)
anthony92c93bd2012-03-19 14:02:47 +00001546 _draw_info->weight=700;
anthony24aa8822012-03-11 00:56:06 +00001547 if (LocaleCompare(arg1,"bolder") == 0)
anthony92c93bd2012-03-19 14:02:47 +00001548 if (_draw_info->weight <= 800)
1549 _draw_info->weight+=100;
anthony24aa8822012-03-11 00:56:06 +00001550 if (LocaleCompare(arg1,"lighter") == 0)
anthony92c93bd2012-03-19 14:02:47 +00001551 if (_draw_info->weight >= 100)
1552 _draw_info->weight-=100;
anthony24aa8822012-03-11 00:56:06 +00001553 if (LocaleCompare(arg1,"normal") == 0)
anthony92c93bd2012-03-19 14:02:47 +00001554 _draw_info->weight=400;
anthonyab3a50c2011-10-27 11:48:57 +00001555 break;
1556 }
anthonyafa3dfc2012-03-03 11:31:30 +00001557 if (LocaleCompare("white-point",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001558 {
anthony72feaa62012-01-17 06:46:23 +00001559 /* Used as a image chromaticity setting
1560 SyncImageSettings() used to set per-image attribute.
1561 */
anthony52bef752012-03-27 13:54:47 +00001562 arg1=ArgOption("0.0");
anthony7bcfe7f2012-03-30 14:01:22 +00001563 if (IfMagickFalse(IsGeometry(arg1)))
anthony52bef752012-03-27 13:54:47 +00001564 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1565 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +00001566 break;
1567 }
anthonyebb73a22012-03-22 14:25:52 +00001568 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001569 }
1570 default:
anthonyebb73a22012-03-22 14:25:52 +00001571 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001572 }
anthony24aa8822012-03-11 00:56:06 +00001573
anthony4837ac22012-05-18 23:39:48 +00001574#if 0
1575 /* clean up percent escape interpreted strings */
1576 if (arg1 != arg1n )
1577 arg1=DestroyString((char *)arg1);
1578 if (arg2 != arg2n )
1579 arg2=DestroyString((char *)arg2);
1580#endif
1581
anthony92c93bd2012-03-19 14:02:47 +00001582#undef _image_info
1583#undef _exception
1584#undef _draw_info
1585#undef _quantize_info
anthonyfd706f92012-01-19 04:22:02 +00001586#undef IfSetOption
anthonyfd706f92012-01-19 04:22:02 +00001587#undef ArgBoolean
anthony24aa8822012-03-11 00:56:06 +00001588#undef ArgBooleanNot
1589#undef ArgBooleanString
1590#undef ArgOption
anthonyfd706f92012-01-19 04:22:02 +00001591
anthony31f1bf72012-01-30 12:37:22 +00001592 return;
anthony805a2d42011-09-25 08:25:12 +00001593}
1594
1595/*
1596%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1597% %
1598% %
1599% %
anthony43f425d2012-02-26 12:58:58 +00001600+ 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 +00001601% %
1602% %
1603% %
1604%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1605%
anthony7a4d6102012-07-01 09:48:25 +00001606% WandSimpleOperatorImages() andSimpleOperatorImagespplys one simple image operation given to all
anthony43f425d2012-02-26 12:58:58 +00001607% the images in the CLI wand, with the settings that was previously saved in
1608% the CLI wand.
anthonydcf510d2011-10-30 13:51:40 +00001609%
1610% It is assumed that any per-image settings are up-to-date with respect to
anthony43f425d2012-02-26 12:58:58 +00001611% extra settings that were already saved in the wand.
anthony805a2d42011-09-25 08:25:12 +00001612%
anthony7a4d6102012-07-01 09:48:25 +00001613% The format of the WandSimpleOperatorImages method is:
anthony805a2d42011-09-25 08:25:12 +00001614%
anthony43f425d2012-02-26 12:58:58 +00001615% void CLISimpleOperatorImages(MagickCLI *cli_wand,
anthonyafa3dfc2012-03-03 11:31:30 +00001616% const char *option, const char *arg1, const char *arg2)
anthony805a2d42011-09-25 08:25:12 +00001617%
1618% A description of each parameter follows:
1619%
anthony43f425d2012-02-26 12:58:58 +00001620% o cli_wand: structure holding settings and images to be operated on
anthony805a2d42011-09-25 08:25:12 +00001621%
anthonyfd706f92012-01-19 04:22:02 +00001622% o option: The option string for the operation
anthonydcf510d2011-10-30 13:51:40 +00001623%
anthonyfd706f92012-01-19 04:22:02 +00001624% o arg1, arg2: optional argument strings to the operation
anthony805a2d42011-09-25 08:25:12 +00001625%
anthony805a2d42011-09-25 08:25:12 +00001626*/
anthony31f1bf72012-01-30 12:37:22 +00001627
1628/*
1629 Internal subrountine to apply one simple image operation to the current
anthony43f425d2012-02-26 12:58:58 +00001630 image pointed to by the CLI wand.
anthony31f1bf72012-01-30 12:37:22 +00001631
1632 The image in the list may be modified in three different ways...
1633 * directly modified (EG: -negate, -gamma, -level, -annotate, -draw),
1634 * replaced by a new image (EG: -spread, -resize, -rotate, -morphology)
1635 * one image replace by a list of images (-separate and -crop only!)
1636
anthonyafa3dfc2012-03-03 11:31:30 +00001637 In each case the result replaces the single original image in the list, as
1638 well as the pointer to the modified image (last image added if replaced by a
1639 list of images) is returned.
anthony31f1bf72012-01-30 12:37:22 +00001640
1641 As the image pointed to may be replaced, the first image in the list may
1642 also change. GetFirstImageInList() should be used by caller if they wish
1643 return the Image pointer to the first image in list.
1644*/
anthony43f425d2012-02-26 12:58:58 +00001645static void CLISimpleOperatorImage(MagickCLI *cli_wand,
anthony964d28e2012-05-17 23:39:46 +00001646 const char *option, const char *arg1n, const char *arg2n)
anthony805a2d42011-09-25 08:25:12 +00001647{
1648 Image *
1649 new_image;
1650
anthony805a2d42011-09-25 08:25:12 +00001651 GeometryInfo
1652 geometry_info;
1653
1654 RectangleInfo
1655 geometry;
1656
1657 MagickStatusType
anthony805a2d42011-09-25 08:25:12 +00001658 flags;
1659
anthony92c93bd2012-03-19 14:02:47 +00001660 ssize_t
anthony2a0ec8c2012-03-24 04:35:56 +00001661 parse;
anthony92c93bd2012-03-19 14:02:47 +00001662
anthony964d28e2012-05-17 23:39:46 +00001663 const char /* For percent escape interpretImageProperties() */
1664 *arg1,
1665 *arg2;
1666
anthony2e4501b2012-03-30 04:41:54 +00001667#define _image_info (cli_wand->wand.image_info)
1668#define _image (cli_wand->wand.images)
1669#define _exception (cli_wand->wand.exception)
1670#define _draw_info (cli_wand->draw_info)
1671#define _quantize_info (cli_wand->quantize_info)
anthony964d28e2012-05-17 23:39:46 +00001672#define _process_flags (cli_wand->process_flags)
1673#define _option_type ((CommandOptionFlags) cli_wand->command->flags)
anthonyafa3dfc2012-03-03 11:31:30 +00001674#define IfNormalOp (*option=='-')
1675#define IfPlusOp (*option!='-')
anthony7bcfe7f2012-03-30 14:01:22 +00001676#define normal_op IsMagickTrue(IfNormalOp)
1677#define plus_alt_op IsMagickFalse(IfNormalOp)
anthonyfd706f92012-01-19 04:22:02 +00001678
anthony43f425d2012-02-26 12:58:58 +00001679 assert(cli_wand != (MagickCLI *) NULL);
1680 assert(cli_wand->signature == WandSignature);
1681 assert(cli_wand->wand.signature == WandSignature);
anthony5330ae02012-03-20 14:17:01 +00001682 assert(_image != (Image *) NULL); /* an image must be present */
anthony7bcfe7f2012-03-30 14:01:22 +00001683 if (IfMagickTrue(cli_wand->wand.debug))
anthony43f425d2012-02-26 12:58:58 +00001684 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
anthonydcf510d2011-10-30 13:51:40 +00001685
anthony964d28e2012-05-17 23:39:46 +00001686 /* Interpret Percent Escapes in Arguments - using first image */
1687 arg1 = arg1n,
1688 arg2 = arg2n;
1689 if ( (((_process_flags & ProcessInterpretProperities) != 0 )
1690 || ((_option_type & AlwaysInterpretArgsFlag) != 0)
1691 ) && ((_option_type & NeverInterpretArgsFlag) == 0) ) {
1692 /* Interpret Percent escapes in argument 1 */
1693 if (arg1n != (char *) NULL) {
1694 arg1=InterpretImageProperties(_image_info,_image,arg1n,_exception);
1695 if (arg1 == (char *) NULL) {
1696 CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
1697 arg1=arg1n; /* use the given argument as is */
1698 }
1699 }
1700 if (arg2n != (char *) NULL) {
1701 arg2=InterpretImageProperties(_image_info,_image,arg2n,_exception);
1702 if (arg2 == (char *) NULL) {
1703 CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
1704 arg2=arg2n; /* use the given argument as is */
1705 }
1706 }
1707 }
anthony4837ac22012-05-18 23:39:48 +00001708#undef _process_flags
anthony964d28e2012-05-17 23:39:46 +00001709#undef _option_type
1710
1711#if 0
1712 (void) FormatLocaleFile(stderr,
1713 "CLISimpleOperatorImage: \"%s\" \"%s\" \"%s\"\n",option,arg1,arg2);
1714#endif
anthony805a2d42011-09-25 08:25:12 +00001715
anthony5330ae02012-03-20 14:17:01 +00001716 new_image = (Image *)NULL; /* the replacement image, if not null at end */
anthony964d28e2012-05-17 23:39:46 +00001717 SetGeometryInfo(&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00001718
anthonyafa3dfc2012-03-03 11:31:30 +00001719 switch (*(option+1))
anthony805a2d42011-09-25 08:25:12 +00001720 {
1721 case 'a':
1722 {
anthonyafa3dfc2012-03-03 11:31:30 +00001723 if (LocaleCompare("adaptive-blur",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001724 {
anthonyfd706f92012-01-19 04:22:02 +00001725 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00001726 if ((flags & (RhoValue|SigmaValue)) == 0)
1727 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00001728 if ((flags & SigmaValue) == 0)
1729 geometry_info.sigma=1.0;
anthony92c93bd2012-03-19 14:02:47 +00001730 new_image=AdaptiveBlurImage(_image,geometry_info.rho,
cristyaa2c16c2012-03-25 22:21:35 +00001731 geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00001732 break;
1733 }
anthonyafa3dfc2012-03-03 11:31:30 +00001734 if (LocaleCompare("adaptive-resize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001735 {
anthonyfe1aa782012-03-24 13:43:04 +00001736 /* FUTURE: Roll into a resize special operator */
anthony7bcfe7f2012-03-30 14:01:22 +00001737 if (IfMagickFalse(IsGeometry(arg1)))
anthony92c93bd2012-03-19 14:02:47 +00001738 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1739 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
1740 new_image=AdaptiveResizeImage(_image,geometry.width,geometry.height,
cristyaa2c16c2012-03-25 22:21:35 +00001741 _exception);
anthony805a2d42011-09-25 08:25:12 +00001742 break;
1743 }
anthonyafa3dfc2012-03-03 11:31:30 +00001744 if (LocaleCompare("adaptive-sharpen",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001745 {
anthonyfd706f92012-01-19 04:22:02 +00001746 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00001747 if ((flags & (RhoValue|SigmaValue)) == 0)
1748 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00001749 if ((flags & SigmaValue) == 0)
1750 geometry_info.sigma=1.0;
anthony92c93bd2012-03-19 14:02:47 +00001751 new_image=AdaptiveSharpenImage(_image,geometry_info.rho,
cristyaa2c16c2012-03-25 22:21:35 +00001752 geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00001753 break;
1754 }
anthonyafa3dfc2012-03-03 11:31:30 +00001755 if (LocaleCompare("alpha",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001756 {
anthony2a0ec8c2012-03-24 04:35:56 +00001757 parse=ParseCommandOption(MagickAlphaOptions,MagickFalse,arg1);
1758 if (parse < 0)
anthony92c93bd2012-03-19 14:02:47 +00001759 CLIWandExceptArgBreak(OptionError,"UnrecognizedAlphaChannelType",
1760 option,arg1);
anthony2a0ec8c2012-03-24 04:35:56 +00001761 (void) SetImageAlphaChannel(_image,(AlphaChannelType)parse,
1762 _exception);
anthony805a2d42011-09-25 08:25:12 +00001763 break;
1764 }
anthonyafa3dfc2012-03-03 11:31:30 +00001765 if (LocaleCompare("annotate",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001766 {
1767 char
anthony805a2d42011-09-25 08:25:12 +00001768 geometry[MaxTextExtent];
1769
anthony805a2d42011-09-25 08:25:12 +00001770 SetGeometryInfo(&geometry_info);
anthonyfd706f92012-01-19 04:22:02 +00001771 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00001772 if ((flags & RhoValue) == 0)
1773 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00001774 if ((flags & SigmaValue) == 0)
1775 geometry_info.sigma=geometry_info.rho;
anthony964d28e2012-05-17 23:39:46 +00001776 (void) CloneString(&_draw_info->text,arg2);
anthony805a2d42011-09-25 08:25:12 +00001777 (void) FormatLocaleString(geometry,MaxTextExtent,"%+f%+f",
1778 geometry_info.xi,geometry_info.psi);
anthony92c93bd2012-03-19 14:02:47 +00001779 (void) CloneString(&_draw_info->geometry,geometry);
1780 _draw_info->affine.sx=cos(DegreesToRadians(
anthony805a2d42011-09-25 08:25:12 +00001781 fmod(geometry_info.rho,360.0)));
anthony92c93bd2012-03-19 14:02:47 +00001782 _draw_info->affine.rx=sin(DegreesToRadians(
anthony805a2d42011-09-25 08:25:12 +00001783 fmod(geometry_info.rho,360.0)));
anthony92c93bd2012-03-19 14:02:47 +00001784 _draw_info->affine.ry=(-sin(DegreesToRadians(
anthony805a2d42011-09-25 08:25:12 +00001785 fmod(geometry_info.sigma,360.0))));
anthony92c93bd2012-03-19 14:02:47 +00001786 _draw_info->affine.sy=cos(DegreesToRadians(
anthony805a2d42011-09-25 08:25:12 +00001787 fmod(geometry_info.sigma,360.0)));
anthony92c93bd2012-03-19 14:02:47 +00001788 (void) AnnotateImage(_image,_draw_info,_exception);
1789 GetAffineMatrix(&_draw_info->affine);
anthony805a2d42011-09-25 08:25:12 +00001790 break;
1791 }
anthonyafa3dfc2012-03-03 11:31:30 +00001792 if (LocaleCompare("auto-gamma",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001793 {
anthony92c93bd2012-03-19 14:02:47 +00001794 (void) AutoGammaImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00001795 break;
1796 }
anthonyafa3dfc2012-03-03 11:31:30 +00001797 if (LocaleCompare("auto-level",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001798 {
anthony92c93bd2012-03-19 14:02:47 +00001799 (void) AutoLevelImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00001800 break;
1801 }
anthonyafa3dfc2012-03-03 11:31:30 +00001802 if (LocaleCompare("auto-orient",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001803 {
anthony5330ae02012-03-20 14:17:01 +00001804 /* This should probably be a MagickCore function */
anthony92c93bd2012-03-19 14:02:47 +00001805 switch (_image->orientation)
anthony805a2d42011-09-25 08:25:12 +00001806 {
1807 case TopRightOrientation:
1808 {
anthony92c93bd2012-03-19 14:02:47 +00001809 new_image=FlopImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00001810 break;
1811 }
1812 case BottomRightOrientation:
1813 {
anthony92c93bd2012-03-19 14:02:47 +00001814 new_image=RotateImage(_image,180.0,_exception);
anthony805a2d42011-09-25 08:25:12 +00001815 break;
1816 }
1817 case BottomLeftOrientation:
1818 {
anthony92c93bd2012-03-19 14:02:47 +00001819 new_image=FlipImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00001820 break;
1821 }
1822 case LeftTopOrientation:
1823 {
anthony92c93bd2012-03-19 14:02:47 +00001824 new_image=TransposeImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00001825 break;
1826 }
1827 case RightTopOrientation:
1828 {
anthony92c93bd2012-03-19 14:02:47 +00001829 new_image=RotateImage(_image,90.0,_exception);
anthony805a2d42011-09-25 08:25:12 +00001830 break;
1831 }
1832 case RightBottomOrientation:
1833 {
anthony92c93bd2012-03-19 14:02:47 +00001834 new_image=TransverseImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00001835 break;
1836 }
1837 case LeftBottomOrientation:
1838 {
anthony92c93bd2012-03-19 14:02:47 +00001839 new_image=RotateImage(_image,270.0,_exception);
anthony805a2d42011-09-25 08:25:12 +00001840 break;
1841 }
1842 default:
1843 break;
1844 }
1845 if (new_image != (Image *) NULL)
1846 new_image->orientation=TopLeftOrientation;
1847 break;
1848 }
anthonyebb73a22012-03-22 14:25:52 +00001849 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001850 }
1851 case 'b':
1852 {
anthonyafa3dfc2012-03-03 11:31:30 +00001853 if (LocaleCompare("black-threshold",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001854 {
anthony7bcfe7f2012-03-30 14:01:22 +00001855 if (IfMagickFalse(IsGeometry(arg1)))
anthony5330ae02012-03-20 14:17:01 +00001856 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001857 (void) BlackThresholdImage(_image,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00001858 break;
1859 }
anthonyafa3dfc2012-03-03 11:31:30 +00001860 if (LocaleCompare("blue-shift",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001861 {
anthony805a2d42011-09-25 08:25:12 +00001862 geometry_info.rho=1.5;
anthony5330ae02012-03-20 14:17:01 +00001863 if (IfNormalOp) {
anthonyfd706f92012-01-19 04:22:02 +00001864 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00001865 if ((flags & RhoValue) == 0)
1866 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony5330ae02012-03-20 14:17:01 +00001867 }
anthony92c93bd2012-03-19 14:02:47 +00001868 new_image=BlueShiftImage(_image,geometry_info.rho,_exception);
anthony805a2d42011-09-25 08:25:12 +00001869 break;
1870 }
anthonyafa3dfc2012-03-03 11:31:30 +00001871 if (LocaleCompare("blur",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001872 {
anthonyfd706f92012-01-19 04:22:02 +00001873 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00001874 if ((flags & (RhoValue|SigmaValue)) == 0)
1875 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00001876 if ((flags & SigmaValue) == 0)
1877 geometry_info.sigma=1.0;
cristyaa2c16c2012-03-25 22:21:35 +00001878 new_image=BlurImage(_image,geometry_info.rho,geometry_info.sigma,
1879 _exception);
anthony805a2d42011-09-25 08:25:12 +00001880 break;
1881 }
anthonyafa3dfc2012-03-03 11:31:30 +00001882 if (LocaleCompare("border",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001883 {
anthony31f1bf72012-01-30 12:37:22 +00001884 CompositeOperator
anthony5f867ae2011-10-09 10:28:34 +00001885 compose;
1886
1887 const char*
anthony5f867ae2011-10-09 10:28:34 +00001888 value;
1889
anthony22de2722012-04-19 14:43:00 +00001890 flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
1891 if ((flags & RhoValue) == 0)
anthony5330ae02012-03-20 14:17:01 +00001892 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony22de2722012-04-19 14:43:00 +00001893 if ((flags & SigmaValue) == 0)
1894 geometry.height=geometry.width;
anthony5330ae02012-03-20 14:17:01 +00001895
anthony92c93bd2012-03-19 14:02:47 +00001896 value=GetImageOption(_image_info,"compose");
anthony5f867ae2011-10-09 10:28:34 +00001897 if (value != (const char *) NULL)
1898 compose=(CompositeOperator) ParseCommandOption(
1899 MagickComposeOptions,MagickFalse,value);
1900 else
anthony92c93bd2012-03-19 14:02:47 +00001901 compose=OverCompositeOp; /* use Over not _image->compose */
anthony5f867ae2011-10-09 10:28:34 +00001902
anthony92c93bd2012-03-19 14:02:47 +00001903 new_image=BorderImage(_image,&geometry,compose,_exception);
anthony805a2d42011-09-25 08:25:12 +00001904 break;
1905 }
anthonyafa3dfc2012-03-03 11:31:30 +00001906 if (LocaleCompare("brightness-contrast",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001907 {
1908 double
1909 brightness,
1910 contrast;
1911
1912 GeometryInfo
1913 geometry_info;
1914
1915 MagickStatusType
1916 flags;
1917
anthonyfd706f92012-01-19 04:22:02 +00001918 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00001919 if ((flags & RhoValue) == 0)
1920 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00001921 brightness=geometry_info.rho;
1922 contrast=0.0;
1923 if ((flags & SigmaValue) != 0)
1924 contrast=geometry_info.sigma;
anthony92c93bd2012-03-19 14:02:47 +00001925 (void) BrightnessContrastImage(_image,brightness,contrast,
1926 _exception);
anthony805a2d42011-09-25 08:25:12 +00001927 break;
1928 }
anthonyebb73a22012-03-22 14:25:52 +00001929 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001930 }
1931 case 'c':
1932 {
anthonyafa3dfc2012-03-03 11:31:30 +00001933 if (LocaleCompare("cdl",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001934 {
anthony4837ac22012-05-18 23:39:48 +00001935 /* Note: arguments do not have percent escapes expanded */
anthony805a2d42011-09-25 08:25:12 +00001936 char
1937 *color_correction_collection;
1938
1939 /*
1940 Color correct with a color decision list.
1941 */
anthony92c93bd2012-03-19 14:02:47 +00001942 color_correction_collection=FileToString(arg1,~0,_exception);
anthony805a2d42011-09-25 08:25:12 +00001943 if (color_correction_collection == (char *) NULL)
1944 break;
anthony92c93bd2012-03-19 14:02:47 +00001945 (void) ColorDecisionListImage(_image,color_correction_collection,
1946 _exception);
anthony805a2d42011-09-25 08:25:12 +00001947 break;
1948 }
anthonyafa3dfc2012-03-03 11:31:30 +00001949 if (LocaleCompare("charcoal",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001950 {
anthonyfd706f92012-01-19 04:22:02 +00001951 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00001952 if ((flags & (RhoValue|SigmaValue)) == 0)
1953 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00001954 if ((flags & SigmaValue) == 0)
1955 geometry_info.sigma=1.0;
1956 if ((flags & XiValue) == 0)
1957 geometry_info.xi=1.0;
anthony92c93bd2012-03-19 14:02:47 +00001958 new_image=CharcoalImage(_image,geometry_info.rho,
cristyaa2c16c2012-03-25 22:21:35 +00001959 geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00001960 break;
1961 }
anthonyafa3dfc2012-03-03 11:31:30 +00001962 if (LocaleCompare("chop",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001963 {
anthony7bcfe7f2012-03-30 14:01:22 +00001964 if (IfMagickFalse(IsGeometry(arg1)))
anthony5330ae02012-03-20 14:17:01 +00001965 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001966 (void) ParseGravityGeometry(_image,arg1,&geometry,_exception);
1967 new_image=ChopImage(_image,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00001968 break;
1969 }
anthonyafa3dfc2012-03-03 11:31:30 +00001970 if (LocaleCompare("clamp",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001971 {
anthony92c93bd2012-03-19 14:02:47 +00001972 (void) ClampImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00001973 break;
1974 }
anthonyafa3dfc2012-03-03 11:31:30 +00001975 if (LocaleCompare("clip",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001976 {
anthonyafa3dfc2012-03-03 11:31:30 +00001977 if (IfNormalOp)
anthony92c93bd2012-03-19 14:02:47 +00001978 (void) ClipImage(_image,_exception);
anthony43f425d2012-02-26 12:58:58 +00001979 else /* "+mask" remove the write mask */
anthony92c93bd2012-03-19 14:02:47 +00001980 (void) SetImageMask(_image,(Image *) NULL,_exception);
anthony805a2d42011-09-25 08:25:12 +00001981 break;
1982 }
anthonyafa3dfc2012-03-03 11:31:30 +00001983 if (LocaleCompare("clip-mask",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001984 {
anthony4837ac22012-05-18 23:39:48 +00001985 /* Note: arguments do not have percent escapes expanded */
anthony805a2d42011-09-25 08:25:12 +00001986 CacheView
1987 *mask_view;
1988
1989 Image
1990 *mask_image;
1991
1992 register Quantum
1993 *restrict q;
1994
1995 register ssize_t
1996 x;
1997
1998 ssize_t
1999 y;
2000
anthonyafa3dfc2012-03-03 11:31:30 +00002001 if (IfPlusOp) {
anthony4837ac22012-05-18 23:39:48 +00002002 /* use "+clip-mask" Remove the write mask for -clip-path */
anthony92c93bd2012-03-19 14:02:47 +00002003 (void) SetImageMask(_image,(Image *) NULL,_exception);
anthonyafa3dfc2012-03-03 11:31:30 +00002004 break;
2005 }
anthony92c93bd2012-03-19 14:02:47 +00002006 mask_image=GetImageCache(_image_info,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00002007 if (mask_image == (Image *) NULL)
2008 break;
anthony7bcfe7f2012-03-30 14:01:22 +00002009 if (IfMagickFalse(SetImageStorageClass(mask_image,DirectClass,_exception)))
anthony31f1bf72012-01-30 12:37:22 +00002010 break;
anthony5330ae02012-03-20 14:17:01 +00002011 /* Create a write mask from cli_wand mask image */
anthonyfd706f92012-01-19 04:22:02 +00002012 /* FUTURE: use Alpha operations instead and create a Grey Image */
cristydb070952012-04-20 14:33:00 +00002013 mask_view=AcquireAuthenticCacheView(mask_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002014 for (y=0; y < (ssize_t) mask_image->rows; y++)
2015 {
2016 q=GetCacheViewAuthenticPixels(mask_view,0,y,mask_image->columns,1,
anthony92c93bd2012-03-19 14:02:47 +00002017 _exception);
anthony805a2d42011-09-25 08:25:12 +00002018 if (q == (Quantum *) NULL)
2019 break;
2020 for (x=0; x < (ssize_t) mask_image->columns; x++)
2021 {
anthony7bcfe7f2012-03-30 14:01:22 +00002022 if (IfMagickFalse(mask_image->matte))
anthony805a2d42011-09-25 08:25:12 +00002023 SetPixelAlpha(mask_image,GetPixelIntensity(mask_image,q),q);
2024 SetPixelRed(mask_image,GetPixelAlpha(mask_image,q),q);
2025 SetPixelGreen(mask_image,GetPixelAlpha(mask_image,q),q);
2026 SetPixelBlue(mask_image,GetPixelAlpha(mask_image,q),q);
2027 q+=GetPixelChannels(mask_image);
2028 }
anthony7bcfe7f2012-03-30 14:01:22 +00002029 if (IfMagickFalse(SyncCacheViewAuthenticPixels(mask_view,_exception)))
anthony805a2d42011-09-25 08:25:12 +00002030 break;
2031 }
anthonyfd706f92012-01-19 04:22:02 +00002032 /* clean up and set the write mask */
anthony805a2d42011-09-25 08:25:12 +00002033 mask_view=DestroyCacheView(mask_view);
2034 mask_image->matte=MagickTrue;
anthony92c93bd2012-03-19 14:02:47 +00002035 (void) SetImageMask(_image,mask_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002036 mask_image=DestroyImage(mask_image);
anthony805a2d42011-09-25 08:25:12 +00002037 break;
2038 }
anthonyafa3dfc2012-03-03 11:31:30 +00002039 if (LocaleCompare("clip-path",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002040 {
anthony92c93bd2012-03-19 14:02:47 +00002041 (void) ClipImagePath(_image,arg1,normal_op,_exception);
anthony4837ac22012-05-18 23:39:48 +00002042 /* Note: Use "+clip-mask" remove the write mask added */
anthony805a2d42011-09-25 08:25:12 +00002043 break;
2044 }
anthonyafa3dfc2012-03-03 11:31:30 +00002045 if (LocaleCompare("colorize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002046 {
anthony7bcfe7f2012-03-30 14:01:22 +00002047 if (IfMagickFalse(IsGeometry(arg1)))
anthony5330ae02012-03-20 14:17:01 +00002048 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002049 new_image=ColorizeImage(_image,arg1,&_draw_info->fill,_exception);
anthony805a2d42011-09-25 08:25:12 +00002050 break;
2051 }
anthonyafa3dfc2012-03-03 11:31:30 +00002052 if (LocaleCompare("color-matrix",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002053 {
2054 KernelInfo
2055 *kernel;
2056
anthonyfd706f92012-01-19 04:22:02 +00002057 kernel=AcquireKernelInfo(arg1);
anthony805a2d42011-09-25 08:25:12 +00002058 if (kernel == (KernelInfo *) NULL)
anthony5330ae02012-03-20 14:17:01 +00002059 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002060 new_image=ColorMatrixImage(_image,kernel,_exception);
anthony805a2d42011-09-25 08:25:12 +00002061 kernel=DestroyKernelInfo(kernel);
2062 break;
2063 }
anthonyafa3dfc2012-03-03 11:31:30 +00002064 if (LocaleCompare("colors",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002065 {
anthony5330ae02012-03-20 14:17:01 +00002066 /* Reduce the number of colors in the image.
2067 FUTURE: also provide 'plus version with image 'color counts'
anthonyfd706f92012-01-19 04:22:02 +00002068 */
anthony92c93bd2012-03-19 14:02:47 +00002069 _quantize_info->number_colors=StringToUnsignedLong(arg1);
2070 if (_quantize_info->number_colors == 0)
anthony5330ae02012-03-20 14:17:01 +00002071 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002072 if ((_image->storage_class == DirectClass) ||
2073 _image->colors > _quantize_info->number_colors)
2074 (void) QuantizeImage(_quantize_info,_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002075 else
anthony92c93bd2012-03-19 14:02:47 +00002076 (void) CompressImageColormap(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002077 break;
2078 }
anthonyafa3dfc2012-03-03 11:31:30 +00002079 if (LocaleCompare("colorspace",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002080 {
anthony5330ae02012-03-20 14:17:01 +00002081 /* WARNING: this is both a image_info setting (already done)
2082 and a operator to change image colorspace.
anthony31f1bf72012-01-30 12:37:22 +00002083
2084 FUTURE: default colorspace should be sRGB!
anthonyd2cdc862011-10-07 14:07:17 +00002085 Unless some type of 'linear colorspace' mode is set.
anthony31f1bf72012-01-30 12:37:22 +00002086
anthonyd2cdc862011-10-07 14:07:17 +00002087 Note that +colorspace sets "undefined" or no effect on
2088 new images, but forces images already in memory back to RGB!
anthony31f1bf72012-01-30 12:37:22 +00002089 That seems to be a little strange!
anthonyd2cdc862011-10-07 14:07:17 +00002090 */
anthony92c93bd2012-03-19 14:02:47 +00002091 (void) TransformImageColorspace(_image,
2092 IfNormalOp ? _image_info->colorspace : RGBColorspace,
2093 _exception);
anthony805a2d42011-09-25 08:25:12 +00002094 break;
2095 }
anthonyafa3dfc2012-03-03 11:31:30 +00002096 if (LocaleCompare("contrast",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002097 {
anthony464f1c42012-04-22 08:51:01 +00002098 CLIWandWarnReplaced(normal_op?"-level":"+level");
anthony92c93bd2012-03-19 14:02:47 +00002099 (void) ContrastImage(_image,normal_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00002100 break;
2101 }
anthonyafa3dfc2012-03-03 11:31:30 +00002102 if (LocaleCompare("contrast-stretch",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002103 {
2104 double
2105 black_point,
2106 white_point;
2107
2108 MagickStatusType
2109 flags;
2110
anthonyfd706f92012-01-19 04:22:02 +00002111 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00002112 if ((flags & RhoValue) == 0)
2113 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00002114 black_point=geometry_info.rho;
2115 white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
2116 black_point;
anthonyebb73a22012-03-22 14:25:52 +00002117 if ((flags & PercentValue) != 0) {
anthony92c93bd2012-03-19 14:02:47 +00002118 black_point*=(double) _image->columns*_image->rows/100.0;
2119 white_point*=(double) _image->columns*_image->rows/100.0;
anthony805a2d42011-09-25 08:25:12 +00002120 }
anthony92c93bd2012-03-19 14:02:47 +00002121 white_point=(MagickRealType) _image->columns*_image->rows-
anthony805a2d42011-09-25 08:25:12 +00002122 white_point;
anthony92c93bd2012-03-19 14:02:47 +00002123 (void) ContrastStretchImage(_image,black_point,white_point,
2124 _exception);
anthony805a2d42011-09-25 08:25:12 +00002125 break;
2126 }
anthonyafa3dfc2012-03-03 11:31:30 +00002127 if (LocaleCompare("convolve",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002128 {
2129 KernelInfo
2130 *kernel_info;
2131
anthonyfd706f92012-01-19 04:22:02 +00002132 kernel_info=AcquireKernelInfo(arg1);
anthony805a2d42011-09-25 08:25:12 +00002133 if (kernel_info == (KernelInfo *) NULL)
anthonyebb73a22012-03-22 14:25:52 +00002134 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
cristya12d8ba2012-04-29 16:33:41 +00002135 new_image=MorphologyImage(_image,CorrelateMorphology,1,kernel_info,
2136 _exception);
anthony805a2d42011-09-25 08:25:12 +00002137 kernel_info=DestroyKernelInfo(kernel_info);
2138 break;
2139 }
anthonyafa3dfc2012-03-03 11:31:30 +00002140 if (LocaleCompare("crop",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002141 {
anthony31f1bf72012-01-30 12:37:22 +00002142 /* WARNING: This can generate multiple images! */
anthony7bcfe7f2012-03-30 14:01:22 +00002143 if (IfMagickFalse(IsGeometry(arg1)))
anthonyebb73a22012-03-22 14:25:52 +00002144 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002145 new_image=CropImageToTiles(_image,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00002146 break;
2147 }
anthonyafa3dfc2012-03-03 11:31:30 +00002148 if (LocaleCompare("cycle",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002149 {
anthony7bcfe7f2012-03-30 14:01:22 +00002150 if (IfMagickFalse(IsGeometry(arg1)))
anthonyebb73a22012-03-22 14:25:52 +00002151 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002152 (void) CycleColormapImage(_image,(ssize_t) StringToLong(arg1),
2153 _exception);
anthony805a2d42011-09-25 08:25:12 +00002154 break;
2155 }
anthonyebb73a22012-03-22 14:25:52 +00002156 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002157 }
2158 case 'd':
2159 {
anthonyafa3dfc2012-03-03 11:31:30 +00002160 if (LocaleCompare("decipher",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002161 {
anthony4837ac22012-05-18 23:39:48 +00002162 /* Note: arguments do not have percent escapes expanded */
anthony805a2d42011-09-25 08:25:12 +00002163 StringInfo
2164 *passkey;
2165
anthony92c93bd2012-03-19 14:02:47 +00002166 passkey=FileToStringInfo(arg1,~0,_exception);
anthonyebb73a22012-03-22 14:25:52 +00002167 if (passkey == (StringInfo *) NULL)
2168 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2169
2170 (void) PasskeyDecipherImage(_image,passkey,_exception);
2171 passkey=DestroyStringInfo(passkey);
anthony805a2d42011-09-25 08:25:12 +00002172 break;
2173 }
anthonyafa3dfc2012-03-03 11:31:30 +00002174 if (LocaleCompare("depth",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002175 {
anthony92c93bd2012-03-19 14:02:47 +00002176 /* The _image_info->depth setting has already been set
anthonydcf510d2011-10-30 13:51:40 +00002177 We just need to apply it to all images in current sequence
anthony31f1bf72012-01-30 12:37:22 +00002178
anthonydcf510d2011-10-30 13:51:40 +00002179 WARNING: Depth from 8 to 16 causes 'quantum rounding to images!
2180 That is it really is an operation, not a setting! Arrgghhh
anthony31f1bf72012-01-30 12:37:22 +00002181
anthonyfd706f92012-01-19 04:22:02 +00002182 FUTURE: this should not be an operator!!!
anthonydcf510d2011-10-30 13:51:40 +00002183 */
anthony92c93bd2012-03-19 14:02:47 +00002184 (void) SetImageDepth(_image,_image_info->depth,_exception);
anthony805a2d42011-09-25 08:25:12 +00002185 break;
2186 }
anthonyafa3dfc2012-03-03 11:31:30 +00002187 if (LocaleCompare("deskew",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002188 {
2189 double
2190 threshold;
2191
anthonyebb73a22012-03-22 14:25:52 +00002192 if (IfNormalOp) {
anthony7bcfe7f2012-03-30 14:01:22 +00002193 if (IfMagickFalse(IsGeometry(arg1)))
anthonyebb73a22012-03-22 14:25:52 +00002194 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00002195 threshold=StringToDoubleInterval(arg1,(double) QuantumRange+1.0);
anthonyebb73a22012-03-22 14:25:52 +00002196 }
anthonyafa3dfc2012-03-03 11:31:30 +00002197 else
2198 threshold=40.0*QuantumRange/100.0;
anthony92c93bd2012-03-19 14:02:47 +00002199 new_image=DeskewImage(_image,threshold,_exception);
anthony805a2d42011-09-25 08:25:12 +00002200 break;
2201 }
anthonyafa3dfc2012-03-03 11:31:30 +00002202 if (LocaleCompare("despeckle",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002203 {
anthony92c93bd2012-03-19 14:02:47 +00002204 new_image=DespeckleImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002205 break;
2206 }
anthonyafa3dfc2012-03-03 11:31:30 +00002207 if (LocaleCompare("distort",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002208 {
anthony805a2d42011-09-25 08:25:12 +00002209 double
anthonyb1d483a2012-04-14 12:53:56 +00002210 *args;
anthony805a2d42011-09-25 08:25:12 +00002211
anthonyb1d483a2012-04-14 12:53:56 +00002212 ssize_t
2213 count;
anthony805a2d42011-09-25 08:25:12 +00002214
anthony2a0ec8c2012-03-24 04:35:56 +00002215 parse = ParseCommandOption(MagickDistortOptions,MagickFalse,arg1);
2216 if ( parse < 0 )
anthonyebb73a22012-03-22 14:25:52 +00002217 CLIWandExceptArgBreak(OptionError,"UnrecognizedDistortMethod",
2218 option,arg1);
anthony2a0ec8c2012-03-24 04:35:56 +00002219 if ((DistortImageMethod) parse == ResizeDistortion)
anthony805a2d42011-09-25 08:25:12 +00002220 {
anthony80c37752012-01-16 01:03:11 +00002221 double
2222 resize_args[2];
anthony805a2d42011-09-25 08:25:12 +00002223 /* Special Case - Argument is actually a resize geometry!
2224 ** Convert that to an appropriate distortion argument array.
anthonyfd706f92012-01-19 04:22:02 +00002225 ** FUTURE: make a separate special resize operator
anthonyfe1aa782012-03-24 13:43:04 +00002226 Roll into a resize special operator */
anthony7bcfe7f2012-03-30 14:01:22 +00002227 if (IfMagickFalse(IsGeometry(arg2)))
anthonyebb73a22012-03-22 14:25:52 +00002228 CLIWandExceptArgBreak(OptionError,"InvalidGeometry",
2229 option,arg2);
2230 (void) ParseRegionGeometry(_image,arg2,&geometry,_exception);
anthony80c37752012-01-16 01:03:11 +00002231 resize_args[0]=(double) geometry.width;
2232 resize_args[1]=(double) geometry.height;
anthony2a0ec8c2012-03-24 04:35:56 +00002233 new_image=DistortImage(_image,(DistortImageMethod) parse,
2234 (size_t)2,resize_args,MagickTrue,_exception);
anthony805a2d42011-09-25 08:25:12 +00002235 break;
2236 }
anthonyb1d483a2012-04-14 12:53:56 +00002237 /* convert argument string into an array of doubles */
anthony964d28e2012-05-17 23:39:46 +00002238 args = StringToArrayOfDoubles(arg2,&count,_exception);
anthonyb1d483a2012-04-14 12:53:56 +00002239 if (args == (double *)NULL )
2240 CLIWandExceptArgBreak(OptionError,"InvalidNumberList",option,arg2);
2241
2242 new_image=DistortImage(_image,(DistortImageMethod) parse,count,args,
2243 plus_alt_op,_exception);
2244 args=(double *) RelinquishMagickMemory(args);
anthony805a2d42011-09-25 08:25:12 +00002245 break;
2246 }
anthonyafa3dfc2012-03-03 11:31:30 +00002247 if (LocaleCompare("draw",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002248 {
anthony92c93bd2012-03-19 14:02:47 +00002249 (void) CloneString(&_draw_info->primitive,arg1);
2250 (void) DrawImage(_image,_draw_info,_exception);
2251 (void) CloneString(&_draw_info->primitive,(char *)NULL);
anthony805a2d42011-09-25 08:25:12 +00002252 break;
2253 }
anthonyebb73a22012-03-22 14:25:52 +00002254 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002255 }
2256 case 'e':
2257 {
anthonyafa3dfc2012-03-03 11:31:30 +00002258 if (LocaleCompare("edge",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002259 {
anthonyfd706f92012-01-19 04:22:02 +00002260 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00002261 if ((flags & (RhoValue|SigmaValue)) == 0)
2262 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00002263 if ((flags & SigmaValue) == 0)
2264 geometry_info.sigma=1.0;
anthony2a0ec8c2012-03-24 04:35:56 +00002265 new_image=EdgeImage(_image,geometry_info.rho,geometry_info.sigma,
2266 _exception);
anthony805a2d42011-09-25 08:25:12 +00002267 break;
2268 }
anthonyafa3dfc2012-03-03 11:31:30 +00002269 if (LocaleCompare("emboss",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002270 {
anthonyfd706f92012-01-19 04:22:02 +00002271 flags=ParseGeometry(arg1,&geometry_info);
anthonyb1e21ed2012-04-20 12:43:12 +00002272 if ((flags & (RhoValue|SigmaValue)) == 0)
2273 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00002274 if ((flags & SigmaValue) == 0)
2275 geometry_info.sigma=1.0;
anthony92c93bd2012-03-19 14:02:47 +00002276 new_image=EmbossImage(_image,geometry_info.rho,
2277 geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00002278 break;
2279 }
anthonyafa3dfc2012-03-03 11:31:30 +00002280 if (LocaleCompare("encipher",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002281 {
anthony4837ac22012-05-18 23:39:48 +00002282 /* Note: arguments do not have percent escapes expanded */
anthony805a2d42011-09-25 08:25:12 +00002283 StringInfo
2284 *passkey;
2285
anthony92c93bd2012-03-19 14:02:47 +00002286 passkey=FileToStringInfo(arg1,~0,_exception);
anthony805a2d42011-09-25 08:25:12 +00002287 if (passkey != (StringInfo *) NULL)
2288 {
anthony92c93bd2012-03-19 14:02:47 +00002289 (void) PasskeyEncipherImage(_image,passkey,_exception);
anthony805a2d42011-09-25 08:25:12 +00002290 passkey=DestroyStringInfo(passkey);
2291 }
2292 break;
2293 }
anthonyafa3dfc2012-03-03 11:31:30 +00002294 if (LocaleCompare("enhance",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002295 {
anthony92c93bd2012-03-19 14:02:47 +00002296 new_image=EnhanceImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002297 break;
2298 }
anthonyafa3dfc2012-03-03 11:31:30 +00002299 if (LocaleCompare("equalize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002300 {
anthony92c93bd2012-03-19 14:02:47 +00002301 (void) EqualizeImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002302 break;
2303 }
anthonyafa3dfc2012-03-03 11:31:30 +00002304 if (LocaleCompare("evaluate",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002305 {
2306 double
2307 constant;
2308
anthony2a0ec8c2012-03-24 04:35:56 +00002309 parse = ParseCommandOption(MagickEvaluateOptions,MagickFalse,arg1);
2310 if ( parse < 0 )
2311 CLIWandExceptArgBreak(OptionError,"UnrecognizedEvaluateOperator",
2312 option,arg1);
anthony7bcfe7f2012-03-30 14:01:22 +00002313 if (IfMagickFalse(IsGeometry(arg2)))
anthony2a0ec8c2012-03-24 04:35:56 +00002314 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
anthonyfd706f92012-01-19 04:22:02 +00002315 constant=StringToDoubleInterval(arg2,(double) QuantumRange+1.0);
anthony2a0ec8c2012-03-24 04:35:56 +00002316 (void) EvaluateImage(_image,(MagickEvaluateOperator)parse,constant,
2317 _exception);
anthony805a2d42011-09-25 08:25:12 +00002318 break;
2319 }
anthonyafa3dfc2012-03-03 11:31:30 +00002320 if (LocaleCompare("extent",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002321 {
anthony7bcfe7f2012-03-30 14:01:22 +00002322 if (IfMagickFalse(IsGeometry(arg1)))
anthony2a0ec8c2012-03-24 04:35:56 +00002323 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002324 flags=ParseGravityGeometry(_image,arg1,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00002325 if (geometry.width == 0)
anthony92c93bd2012-03-19 14:02:47 +00002326 geometry.width=_image->columns;
anthony805a2d42011-09-25 08:25:12 +00002327 if (geometry.height == 0)
anthony92c93bd2012-03-19 14:02:47 +00002328 geometry.height=_image->rows;
2329 new_image=ExtentImage(_image,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00002330 break;
2331 }
anthonyebb73a22012-03-22 14:25:52 +00002332 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002333 }
2334 case 'f':
2335 {
anthonyafa3dfc2012-03-03 11:31:30 +00002336 if (LocaleCompare("features",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002337 {
anthony31f1bf72012-01-30 12:37:22 +00002338 /* FUTURE: move to SyncImageSettings() and AcqireImage()??? */
anthonyafa3dfc2012-03-03 11:31:30 +00002339 if (IfPlusOp) {
anthony92c93bd2012-03-19 14:02:47 +00002340 (void) DeleteImageArtifact(_image,"identify:features");
anthony31f1bf72012-01-30 12:37:22 +00002341 break;
2342 }
anthony92c93bd2012-03-19 14:02:47 +00002343 (void) SetImageArtifact(_image,"identify:features","true");
2344 (void) SetImageArtifact(_image,"verbose","true");
anthony805a2d42011-09-25 08:25:12 +00002345 break;
2346 }
anthonyafa3dfc2012-03-03 11:31:30 +00002347 if (LocaleCompare("flip",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002348 {
anthony92c93bd2012-03-19 14:02:47 +00002349 new_image=FlipImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002350 break;
2351 }
anthonyafa3dfc2012-03-03 11:31:30 +00002352 if (LocaleCompare("flop",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002353 {
anthony92c93bd2012-03-19 14:02:47 +00002354 new_image=FlopImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002355 break;
2356 }
anthonyafa3dfc2012-03-03 11:31:30 +00002357 if (LocaleCompare("floodfill",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002358 {
2359 PixelInfo
2360 target;
2361
anthony7bcfe7f2012-03-30 14:01:22 +00002362 if (IfMagickFalse(IsGeometry(arg1)))
anthony2a0ec8c2012-03-24 04:35:56 +00002363 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002364 (void) ParsePageGeometry(_image,arg1,&geometry,_exception);
2365 (void) QueryColorCompliance(arg2,AllCompliance,&target,_exception);
2366 (void) FloodfillPaintImage(_image,_draw_info,&target,geometry.x,
2367 geometry.y,plus_alt_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00002368 break;
2369 }
anthonyafa3dfc2012-03-03 11:31:30 +00002370 if (LocaleCompare("frame",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002371 {
2372 FrameInfo
2373 frame_info;
2374
anthony31f1bf72012-01-30 12:37:22 +00002375 CompositeOperator
anthonyfd706f92012-01-19 04:22:02 +00002376 compose;
2377
2378 const char*
2379 value;
2380
anthony92c93bd2012-03-19 14:02:47 +00002381 value=GetImageOption(_image_info,"compose");
anthonyfd706f92012-01-19 04:22:02 +00002382 if (value != (const char *) NULL)
2383 compose=(CompositeOperator) ParseCommandOption(
2384 MagickComposeOptions,MagickFalse,value);
2385 else
anthony92c93bd2012-03-19 14:02:47 +00002386 compose=OverCompositeOp; /* use Over not _image->compose */
anthonyfd706f92012-01-19 04:22:02 +00002387
anthony7bcfe7f2012-03-30 14:01:22 +00002388 if (IfMagickFalse(IsGeometry(arg1)))
anthony2a0ec8c2012-03-24 04:35:56 +00002389 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002390 flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00002391 frame_info.width=geometry.width;
2392 frame_info.height=geometry.height;
2393 if ((flags & HeightValue) == 0)
2394 frame_info.height=geometry.width;
2395 frame_info.outer_bevel=geometry.x;
2396 frame_info.inner_bevel=geometry.y;
2397 frame_info.x=(ssize_t) frame_info.width;
2398 frame_info.y=(ssize_t) frame_info.height;
anthony92c93bd2012-03-19 14:02:47 +00002399 frame_info.width=_image->columns+2*frame_info.width;
2400 frame_info.height=_image->rows+2*frame_info.height;
2401 new_image=FrameImage(_image,&frame_info,compose,_exception);
anthony805a2d42011-09-25 08:25:12 +00002402 break;
2403 }
anthonyafa3dfc2012-03-03 11:31:30 +00002404 if (LocaleCompare("function",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002405 {
anthony805a2d42011-09-25 08:25:12 +00002406 double
anthonyb1d483a2012-04-14 12:53:56 +00002407 *args;
anthony805a2d42011-09-25 08:25:12 +00002408
anthonyb1d483a2012-04-14 12:53:56 +00002409 ssize_t
2410 count;
anthony805a2d42011-09-25 08:25:12 +00002411
anthony2a0ec8c2012-03-24 04:35:56 +00002412 parse=ParseCommandOption(MagickFunctionOptions,MagickFalse,arg1);
2413 if ( parse < 0 )
2414 CLIWandExceptArgBreak(OptionError,"UnrecognizedFunction",
2415 option,arg1);
anthonyb1d483a2012-04-14 12:53:56 +00002416 /* convert argument string into an array of doubles */
anthony964d28e2012-05-17 23:39:46 +00002417 args = StringToArrayOfDoubles(arg2,&count,_exception);
anthonyb1d483a2012-04-14 12:53:56 +00002418 if (args == (double *)NULL )
2419 CLIWandExceptArgBreak(OptionError,"InvalidNumberList",option,arg2);
2420
2421 (void) FunctionImage(_image,(MagickFunction)parse,count,args,
2422 _exception);
2423 args=(double *) RelinquishMagickMemory(args);
anthony805a2d42011-09-25 08:25:12 +00002424 break;
2425 }
anthonyebb73a22012-03-22 14:25:52 +00002426 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002427 }
2428 case 'g':
2429 {
anthonyafa3dfc2012-03-03 11:31:30 +00002430 if (LocaleCompare("gamma",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002431 {
anthony7a4d6102012-07-01 09:48:25 +00002432 double
2433 constant;
2434
anthony7bcfe7f2012-03-30 14:01:22 +00002435 if (IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00002436 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony7a4d6102012-07-01 09:48:25 +00002437 constant=StringToDouble(arg1,(char **) NULL);
2438#if 0
2439 /* Using Gamma, via a cache */
2440 if (IfPlusOp)
2441 constant=MagickEpsilonReciprocal(constant);
2442 (void) GammaImage(_image,constant,_exception);
2443#else
2444 /* Using Evaluate POW, direct update of values - more accurite */
anthonyafa3dfc2012-03-03 11:31:30 +00002445 if (IfNormalOp)
anthony7a4d6102012-07-01 09:48:25 +00002446 constant=MagickEpsilonReciprocal(constant);
2447 (void) EvaluateImage(_image,PowEvaluateOperator,constant,_exception);
2448#endif
2449 /* Set gamma setting -- Old meaning of "+gamma"
2450 * _image->gamma=StringToDouble(arg1,(char **) NULL);
2451 */
anthony805a2d42011-09-25 08:25:12 +00002452 break;
2453 }
anthony975a8d72012-04-12 13:54:36 +00002454 if (LocaleCompare("gaussian-blur",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002455 {
anthonyfd706f92012-01-19 04:22:02 +00002456 flags=ParseGeometry(arg1,&geometry_info);
anthonyb1e21ed2012-04-20 12:43:12 +00002457 if ((flags & (RhoValue|SigmaValue)) == 0)
2458 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00002459 if ((flags & SigmaValue) == 0)
2460 geometry_info.sigma=1.0;
anthony92c93bd2012-03-19 14:02:47 +00002461 new_image=GaussianBlurImage(_image,geometry_info.rho,
2462 geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00002463 break;
2464 }
anthony975a8d72012-04-12 13:54:36 +00002465 if (LocaleCompare("gaussian",option+1) == 0)
2466 {
anthony464f1c42012-04-22 08:51:01 +00002467 CLIWandWarnReplaced("-gaussian-blur");
anthony975a8d72012-04-12 13:54:36 +00002468 CLISimpleOperatorImage(cli_wand,"-gaussian-blur",arg1,NULL);
2469 }
anthonyafa3dfc2012-03-03 11:31:30 +00002470 if (LocaleCompare("geometry",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002471 {
anthonyfd706f92012-01-19 04:22:02 +00002472 /*
anthony31f1bf72012-01-30 12:37:22 +00002473 Record Image offset for composition. (A Setting)
anthonyfe1aa782012-03-24 13:43:04 +00002474 Resize last _image. (ListOperator) -- DEPRECIATE
anthony31f1bf72012-01-30 12:37:22 +00002475 FUTURE: Why if no 'offset' does this resize ALL images?
2476 Also why is the setting recorded in the IMAGE non-sense!
anthonyfd706f92012-01-19 04:22:02 +00002477 */
anthonyafa3dfc2012-03-03 11:31:30 +00002478 if (IfPlusOp)
anthonyfd706f92012-01-19 04:22:02 +00002479 { /* remove the previous composition geometry offset! */
anthony92c93bd2012-03-19 14:02:47 +00002480 if (_image->geometry != (char *) NULL)
2481 _image->geometry=DestroyString(_image->geometry);
anthony805a2d42011-09-25 08:25:12 +00002482 break;
2483 }
anthony7bcfe7f2012-03-30 14:01:22 +00002484 if (IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00002485 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002486 flags=ParseRegionGeometry(_image,arg1,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00002487 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
anthony92c93bd2012-03-19 14:02:47 +00002488 (void) CloneString(&_image->geometry,arg1);
anthony805a2d42011-09-25 08:25:12 +00002489 else
anthony92c93bd2012-03-19 14:02:47 +00002490 new_image=ResizeImage(_image,geometry.width,geometry.height,
cristyaa2c16c2012-03-25 22:21:35 +00002491 _image->filter,_exception);
anthony805a2d42011-09-25 08:25:12 +00002492 break;
2493 }
anthonyebb73a22012-03-22 14:25:52 +00002494 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002495 }
anthony805a2d42011-09-25 08:25:12 +00002496 case 'i':
2497 {
anthonyafa3dfc2012-03-03 11:31:30 +00002498 if (LocaleCompare("identify",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002499 {
anthony31f1bf72012-01-30 12:37:22 +00002500 const char
2501 *format,
anthony805a2d42011-09-25 08:25:12 +00002502 *text;
2503
anthony92c93bd2012-03-19 14:02:47 +00002504 format=GetImageOption(_image_info,"format");
anthony964d28e2012-05-17 23:39:46 +00002505 if (format == (char *) NULL) {
2506 (void) IdentifyImage(_image,stdout,_image_info->verbose,_exception);
2507 break;
2508 }
anthony92c93bd2012-03-19 14:02:47 +00002509 text=InterpretImageProperties(_image_info,_image,format,_exception);
anthony805a2d42011-09-25 08:25:12 +00002510 if (text == (char *) NULL)
anthony964d28e2012-05-17 23:39:46 +00002511 CLIWandExceptionBreak(OptionWarning,"InterpretPropertyFailure",
2512 option);
anthony805a2d42011-09-25 08:25:12 +00002513 (void) fputs(text,stdout);
2514 (void) fputc('\n',stdout);
anthony31f1bf72012-01-30 12:37:22 +00002515 text=DestroyString((char *)text);
anthony805a2d42011-09-25 08:25:12 +00002516 break;
2517 }
anthonyafa3dfc2012-03-03 11:31:30 +00002518 if (LocaleCompare("implode",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002519 {
anthonyb1e21ed2012-04-20 12:43:12 +00002520 flags=ParseGeometry(arg1,&geometry_info);
2521 if ((flags & RhoValue) == 0)
anthonyfe1aa782012-03-24 13:43:04 +00002522 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyb1e21ed2012-04-20 12:43:12 +00002523 new_image=ImplodeImage(_image,geometry_info.rho,_image->interpolate,
2524 _exception);
anthony805a2d42011-09-25 08:25:12 +00002525 break;
2526 }
anthonyafa3dfc2012-03-03 11:31:30 +00002527 if (LocaleCompare("interpolative-resize",option+1) == 0)
cristy947cb4c2011-10-20 18:41:46 +00002528 {
anthonyfe1aa782012-03-24 13:43:04 +00002529 /* FUTURE: New to IMv7
2530 Roll into a resize special operator */
anthony7bcfe7f2012-03-30 14:01:22 +00002531 if (IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00002532 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002533 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
2534 new_image=InterpolativeResizeImage(_image,geometry.width,
2535 geometry.height,_image->interpolate,_exception);
cristy947cb4c2011-10-20 18:41:46 +00002536 break;
2537 }
anthonyebb73a22012-03-22 14:25:52 +00002538 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002539 }
2540 case 'l':
2541 {
anthonyafa3dfc2012-03-03 11:31:30 +00002542 if (LocaleCompare("lat",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002543 {
anthonyfd706f92012-01-19 04:22:02 +00002544 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00002545 if ((flags & (RhoValue|SigmaValue)) == 0)
2546 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00002547 if ((flags & PercentValue) != 0)
2548 geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
anthony92c93bd2012-03-19 14:02:47 +00002549 new_image=AdaptiveThresholdImage(_image,(size_t) geometry_info.rho,
anthony31f1bf72012-01-30 12:37:22 +00002550 (size_t) geometry_info.sigma,(double) geometry_info.xi,
anthony92c93bd2012-03-19 14:02:47 +00002551 _exception);
anthony805a2d42011-09-25 08:25:12 +00002552 break;
2553 }
anthonyafa3dfc2012-03-03 11:31:30 +00002554 if (LocaleCompare("level",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002555 {
2556 MagickRealType
2557 black_point,
2558 gamma,
2559 white_point;
2560
2561 MagickStatusType
2562 flags;
2563
anthonyfd706f92012-01-19 04:22:02 +00002564 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00002565 if ((flags & RhoValue) == 0)
2566 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00002567 black_point=geometry_info.rho;
2568 white_point=(MagickRealType) QuantumRange;
2569 if ((flags & SigmaValue) != 0)
2570 white_point=geometry_info.sigma;
2571 gamma=1.0;
2572 if ((flags & XiValue) != 0)
2573 gamma=geometry_info.xi;
2574 if ((flags & PercentValue) != 0)
2575 {
2576 black_point*=(MagickRealType) (QuantumRange/100.0);
2577 white_point*=(MagickRealType) (QuantumRange/100.0);
2578 }
2579 if ((flags & SigmaValue) == 0)
2580 white_point=(MagickRealType) QuantumRange-black_point;
anthonyafa3dfc2012-03-03 11:31:30 +00002581 if (IfPlusOp || ((flags & AspectValue) != 0))
anthony92c93bd2012-03-19 14:02:47 +00002582 (void) LevelizeImage(_image,black_point,white_point,gamma,_exception);
anthony805a2d42011-09-25 08:25:12 +00002583 else
anthony92c93bd2012-03-19 14:02:47 +00002584 (void) LevelImage(_image,black_point,white_point,gamma,_exception);
anthony805a2d42011-09-25 08:25:12 +00002585 break;
2586 }
anthonyafa3dfc2012-03-03 11:31:30 +00002587 if (LocaleCompare("level-colors",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002588 {
2589 char
2590 token[MaxTextExtent];
2591
2592 const char
2593 *p;
2594
2595 PixelInfo
2596 black_point,
2597 white_point;
2598
anthonyfd706f92012-01-19 04:22:02 +00002599 p=(const char *) arg1;
anthony805a2d42011-09-25 08:25:12 +00002600 GetMagickToken(p,&p,token); /* get black point color */
2601 if ((isalpha((int) *token) != 0) || ((*token == '#') != 0))
cristy269c9412011-10-13 23:41:15 +00002602 (void) QueryColorCompliance(token,AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +00002603 &black_point,_exception);
anthony805a2d42011-09-25 08:25:12 +00002604 else
cristy269c9412011-10-13 23:41:15 +00002605 (void) QueryColorCompliance("#000000",AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +00002606 &black_point,_exception);
anthony805a2d42011-09-25 08:25:12 +00002607 if (isalpha((int) token[0]) || (token[0] == '#'))
2608 GetMagickToken(p,&p,token);
2609 if (*token == '\0')
2610 white_point=black_point; /* set everything to that color */
2611 else
2612 {
2613 if ((isalpha((int) *token) == 0) && ((*token == '#') == 0))
2614 GetMagickToken(p,&p,token); /* Get white point color. */
2615 if ((isalpha((int) *token) != 0) || ((*token == '#') != 0))
cristy269c9412011-10-13 23:41:15 +00002616 (void) QueryColorCompliance(token,AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +00002617 &white_point,_exception);
anthony805a2d42011-09-25 08:25:12 +00002618 else
cristy269c9412011-10-13 23:41:15 +00002619 (void) QueryColorCompliance("#ffffff",AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +00002620 &white_point,_exception);
anthony805a2d42011-09-25 08:25:12 +00002621 }
anthony92c93bd2012-03-19 14:02:47 +00002622 (void) LevelImageColors(_image,&black_point,&white_point,
2623 plus_alt_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00002624 break;
2625 }
anthonyafa3dfc2012-03-03 11:31:30 +00002626 if (LocaleCompare("linear-stretch",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002627 {
2628 double
2629 black_point,
2630 white_point;
2631
2632 MagickStatusType
2633 flags;
2634
anthonyfd706f92012-01-19 04:22:02 +00002635 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00002636 if ((flags & RhoValue) == 0)
2637 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00002638 black_point=geometry_info.rho;
anthony92c93bd2012-03-19 14:02:47 +00002639 white_point=(MagickRealType) _image->columns*_image->rows;
anthony805a2d42011-09-25 08:25:12 +00002640 if ((flags & SigmaValue) != 0)
2641 white_point=geometry_info.sigma;
2642 if ((flags & PercentValue) != 0)
2643 {
anthony92c93bd2012-03-19 14:02:47 +00002644 black_point*=(double) _image->columns*_image->rows/100.0;
2645 white_point*=(double) _image->columns*_image->rows/100.0;
anthony805a2d42011-09-25 08:25:12 +00002646 }
2647 if ((flags & SigmaValue) == 0)
anthony92c93bd2012-03-19 14:02:47 +00002648 white_point=(MagickRealType) _image->columns*_image->rows-
anthony805a2d42011-09-25 08:25:12 +00002649 black_point;
anthony92c93bd2012-03-19 14:02:47 +00002650 (void) LinearStretchImage(_image,black_point,white_point,_exception);
anthony805a2d42011-09-25 08:25:12 +00002651 break;
2652 }
anthonyafa3dfc2012-03-03 11:31:30 +00002653 if (LocaleCompare("liquid-rescale",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002654 {
anthonyfe1aa782012-03-24 13:43:04 +00002655 /* FUTURE: Roll into a resize special operator */
anthony7bcfe7f2012-03-30 14:01:22 +00002656 if (IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00002657 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002658 flags=ParseRegionGeometry(_image,arg1,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00002659 if ((flags & XValue) == 0)
2660 geometry.x=1;
2661 if ((flags & YValue) == 0)
2662 geometry.y=0;
anthony92c93bd2012-03-19 14:02:47 +00002663 new_image=LiquidRescaleImage(_image,geometry.width,
2664 geometry.height,1.0*geometry.x,1.0*geometry.y,_exception);
anthony805a2d42011-09-25 08:25:12 +00002665 break;
2666 }
anthonyebb73a22012-03-22 14:25:52 +00002667 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002668 }
2669 case 'm':
2670 {
anthonyafa3dfc2012-03-03 11:31:30 +00002671 if (LocaleCompare("map",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002672 {
anthony464f1c42012-04-22 08:51:01 +00002673 CLIWandWarnReplaced("-remap");
anthony975a8d72012-04-12 13:54:36 +00002674 CLISimpleOperatorImage(cli_wand,"-remap",NULL,NULL);
anthony805a2d42011-09-25 08:25:12 +00002675 break;
2676 }
anthonyafa3dfc2012-03-03 11:31:30 +00002677 if (LocaleCompare("mask",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002678 {
anthony4837ac22012-05-18 23:39:48 +00002679 /* Note: arguments do not have percent escapes expanded */
anthony805a2d42011-09-25 08:25:12 +00002680 Image
2681 *mask;
2682
anthonyafa3dfc2012-03-03 11:31:30 +00002683 if (IfPlusOp)
anthony31f1bf72012-01-30 12:37:22 +00002684 { /* Remove a mask. */
anthony92c93bd2012-03-19 14:02:47 +00002685 (void) SetImageMask(_image,(Image *) NULL,_exception);
anthony805a2d42011-09-25 08:25:12 +00002686 break;
2687 }
anthony5330ae02012-03-20 14:17:01 +00002688 /* Set the image mask. */
anthony92c93bd2012-03-19 14:02:47 +00002689 mask=GetImageCache(_image_info,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00002690 if (mask == (Image *) NULL)
2691 break;
anthony92c93bd2012-03-19 14:02:47 +00002692 (void) SetImageMask(_image,mask,_exception);
anthony805a2d42011-09-25 08:25:12 +00002693 mask=DestroyImage(mask);
2694 break;
2695 }
anthonyafa3dfc2012-03-03 11:31:30 +00002696 if (LocaleCompare("matte",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002697 {
anthony464f1c42012-04-22 08:51:01 +00002698 CLIWandWarnReplaced(IfNormalOp?"-alpha Set":"-alpha Off");
anthony92c93bd2012-03-19 14:02:47 +00002699 (void) SetImageAlphaChannel(_image,IfNormalOp ? SetAlphaChannel :
2700 DeactivateAlphaChannel, _exception);
anthony805a2d42011-09-25 08:25:12 +00002701 break;
2702 }
anthonya3ef4ed2012-03-17 06:52:53 +00002703 if (LocaleCompare("median",option+1) == 0)
2704 {
anthony464f1c42012-04-22 08:51:01 +00002705 CLIWandWarnReplaced("-statistic Median");
anthonya3ef4ed2012-03-17 06:52:53 +00002706 CLISimpleOperatorImage(cli_wand,"-statistic","Median",arg1);
2707 break;
2708 }
anthonyafa3dfc2012-03-03 11:31:30 +00002709 if (LocaleCompare("mode",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002710 {
anthony975a8d72012-04-12 13:54:36 +00002711 /* FUTURE: note this is also a special "montage" option */
anthony464f1c42012-04-22 08:51:01 +00002712 CLIWandWarnReplaced("-statistic Mode");
anthony975a8d72012-04-12 13:54:36 +00002713 CLISimpleOperatorImage(cli_wand,"-statistic","Mode",arg1);
anthony805a2d42011-09-25 08:25:12 +00002714 break;
2715 }
anthonyafa3dfc2012-03-03 11:31:30 +00002716 if (LocaleCompare("modulate",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002717 {
anthony7bcfe7f2012-03-30 14:01:22 +00002718 if (IfMagickFalse(IsGeometry(arg1)))
anthony7bc87992012-03-25 02:32:51 +00002719 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002720 (void) ModulateImage(_image,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00002721 break;
2722 }
anthonyafa3dfc2012-03-03 11:31:30 +00002723 if (LocaleCompare("monitor",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002724 {
anthony92c93bd2012-03-19 14:02:47 +00002725 (void) SetImageProgressMonitor(_image, IfNormalOp ? MonitorProgress :
anthonyafa3dfc2012-03-03 11:31:30 +00002726 (MagickProgressMonitor) NULL,(void *) NULL);
anthony805a2d42011-09-25 08:25:12 +00002727 break;
2728 }
anthonyafa3dfc2012-03-03 11:31:30 +00002729 if (LocaleCompare("monochrome",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002730 {
anthony92c93bd2012-03-19 14:02:47 +00002731 (void) SetImageType(_image,BilevelType,_exception);
anthony805a2d42011-09-25 08:25:12 +00002732 break;
2733 }
anthonyafa3dfc2012-03-03 11:31:30 +00002734 if (LocaleCompare("morphology",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002735 {
2736 char
2737 token[MaxTextExtent];
2738
2739 const char
2740 *p;
2741
2742 KernelInfo
2743 *kernel;
2744
anthony805a2d42011-09-25 08:25:12 +00002745 ssize_t
2746 iterations;
2747
anthonyfd706f92012-01-19 04:22:02 +00002748 p=arg1;
anthony805a2d42011-09-25 08:25:12 +00002749 GetMagickToken(p,&p,token);
anthony7bc87992012-03-25 02:32:51 +00002750 parse=ParseCommandOption(MagickMorphologyOptions,MagickFalse,token);
2751 if ( parse < 0 )
2752 CLIWandExceptArgBreak(OptionError,"UnrecognizedFunction",
2753 option,arg1);
anthony805a2d42011-09-25 08:25:12 +00002754 iterations=1L;
2755 GetMagickToken(p,&p,token);
2756 if ((*p == ':') || (*p == ','))
2757 GetMagickToken(p,&p,token);
2758 if ((*p != '\0'))
2759 iterations=(ssize_t) StringToLong(p);
anthonyfd706f92012-01-19 04:22:02 +00002760 kernel=AcquireKernelInfo(arg2);
anthony805a2d42011-09-25 08:25:12 +00002761 if (kernel == (KernelInfo *) NULL)
anthony7bc87992012-03-25 02:32:51 +00002762 CLIWandExceptArgBreak(OptionError,"UnabletoParseKernel",
2763 option,arg2);
2764 new_image=MorphologyImage(_image,(MorphologyMethod)parse,
2765 iterations,kernel,_exception);
anthony805a2d42011-09-25 08:25:12 +00002766 kernel=DestroyKernelInfo(kernel);
2767 break;
2768 }
anthonyafa3dfc2012-03-03 11:31:30 +00002769 if (LocaleCompare("motion-blur",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002770 {
anthonyfd706f92012-01-19 04:22:02 +00002771 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00002772 if ((flags & (RhoValue|SigmaValue)) == 0)
2773 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00002774 if ((flags & SigmaValue) == 0)
2775 geometry_info.sigma=1.0;
anthony92c93bd2012-03-19 14:02:47 +00002776 new_image=MotionBlurImage(_image,geometry_info.rho,
cristyaa2c16c2012-03-25 22:21:35 +00002777 geometry_info.sigma,geometry_info.xi,_exception);
anthony805a2d42011-09-25 08:25:12 +00002778 break;
2779 }
anthonyebb73a22012-03-22 14:25:52 +00002780 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002781 }
2782 case 'n':
2783 {
anthonyafa3dfc2012-03-03 11:31:30 +00002784 if (LocaleCompare("negate",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002785 {
anthony92c93bd2012-03-19 14:02:47 +00002786 (void) NegateImage(_image, plus_alt_op, _exception);
anthony805a2d42011-09-25 08:25:12 +00002787 break;
2788 }
anthonyafa3dfc2012-03-03 11:31:30 +00002789 if (LocaleCompare("noise",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002790 {
anthony975a8d72012-04-12 13:54:36 +00002791 double
2792 attenuate;
2793
2794 const char*
2795 value;
2796
anthonyafa3dfc2012-03-03 11:31:30 +00002797 if (IfNormalOp)
anthony805a2d42011-09-25 08:25:12 +00002798 {
anthony464f1c42012-04-22 08:51:01 +00002799 CLIWandWarnReplaced("-statistic NonPeak");
anthony975a8d72012-04-12 13:54:36 +00002800 CLISimpleOperatorImage(cli_wand,"-statistic","NonPeak",arg1);
2801 break;
anthony805a2d42011-09-25 08:25:12 +00002802 }
anthony975a8d72012-04-12 13:54:36 +00002803 parse=ParseCommandOption(MagickNoiseOptions,MagickFalse,arg1);
2804 if ( parse < 0 )
2805 CLIWandExceptArgBreak(OptionError,"UnrecognizedNoiseType",
2806 option,arg1);
2807 attenuate=1.0;
2808 value=GetImageOption(_image_info,"attenuate");
2809 if (value != (const char *) NULL)
2810 attenuate=StringToDouble(value,(char **) NULL);
2811 new_image=AddNoiseImage(_image,(NoiseType)parse,attenuate,
2812 _exception);
anthony805a2d42011-09-25 08:25:12 +00002813 break;
2814 }
anthonyafa3dfc2012-03-03 11:31:30 +00002815 if (LocaleCompare("normalize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002816 {
anthony92c93bd2012-03-19 14:02:47 +00002817 (void) NormalizeImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002818 break;
2819 }
anthonyebb73a22012-03-22 14:25:52 +00002820 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002821 }
2822 case 'o':
2823 {
anthonyafa3dfc2012-03-03 11:31:30 +00002824 if (LocaleCompare("opaque",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002825 {
2826 PixelInfo
2827 target;
2828
anthony92c93bd2012-03-19 14:02:47 +00002829 (void) QueryColorCompliance(arg1,AllCompliance,&target,_exception);
2830 (void) OpaquePaintImage(_image,&target,&_draw_info->fill,plus_alt_op,
2831 _exception);
anthony805a2d42011-09-25 08:25:12 +00002832 break;
2833 }
anthonyafa3dfc2012-03-03 11:31:30 +00002834 if (LocaleCompare("ordered-dither",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002835 {
anthony92c93bd2012-03-19 14:02:47 +00002836 (void) OrderedPosterizeImage(_image,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00002837 break;
2838 }
anthonyebb73a22012-03-22 14:25:52 +00002839 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002840 }
2841 case 'p':
2842 {
anthonyafa3dfc2012-03-03 11:31:30 +00002843 if (LocaleCompare("paint",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002844 {
anthony22de2722012-04-19 14:43:00 +00002845 flags=ParseGeometry(arg1,&geometry_info);
2846 if ((flags & (RhoValue|SigmaValue)) == 0)
2847 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002848 new_image=OilPaintImage(_image,geometry_info.rho,geometry_info.sigma,
2849 _exception);
anthony805a2d42011-09-25 08:25:12 +00002850 break;
2851 }
anthonyafa3dfc2012-03-03 11:31:30 +00002852 if (LocaleCompare("polaroid",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002853 {
cristye9e3d382011-12-14 01:50:13 +00002854 const char
2855 *caption;
2856
anthony805a2d42011-09-25 08:25:12 +00002857 double
2858 angle;
2859
anthony7bc87992012-03-25 02:32:51 +00002860 if (IfPlusOp) {
anthonyf42014d2012-03-25 09:53:06 +00002861 RandomInfo
2862 *random_info;
anthony805a2d42011-09-25 08:25:12 +00002863
anthonyf42014d2012-03-25 09:53:06 +00002864 random_info=AcquireRandomInfo();
2865 angle=22.5*(GetPseudoRandomValue(random_info)-0.5);
2866 random_info=DestroyRandomInfo(random_info);
2867 }
anthony7bc87992012-03-25 02:32:51 +00002868 else {
anthonyf42014d2012-03-25 09:53:06 +00002869 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00002870 if ((flags & RhoValue) == 0)
2871 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyf42014d2012-03-25 09:53:06 +00002872 angle=geometry_info.rho;
2873 }
anthony92c93bd2012-03-19 14:02:47 +00002874 caption=GetImageProperty(_image,"caption",_exception);
2875 new_image=PolaroidImage(_image,_draw_info,caption,angle,
2876 _image->interpolate,_exception);
anthony805a2d42011-09-25 08:25:12 +00002877 break;
2878 }
anthonyafa3dfc2012-03-03 11:31:30 +00002879 if (LocaleCompare("posterize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002880 {
anthony22de2722012-04-19 14:43:00 +00002881 flags=ParseGeometry(arg1,&geometry_info);
2882 if ((flags & RhoValue) == 0)
anthony7bc87992012-03-25 02:32:51 +00002883 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002884 (void) PosterizeImage(_image,(size_t) geometry_info.rho,
cristycbda6112012-05-27 20:57:16 +00002885 _quantize_info->dither_method,_exception);
anthony805a2d42011-09-25 08:25:12 +00002886 break;
2887 }
anthonyafa3dfc2012-03-03 11:31:30 +00002888 if (LocaleCompare("preview",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002889 {
anthony31f1bf72012-01-30 12:37:22 +00002890 /* FUTURE: should be a 'Genesis' option?
2891 Option however is also in WandSettingOptionInfo()
anthony7bc87992012-03-25 02:32:51 +00002892 Why???
cristy947cb4c2011-10-20 18:41:46 +00002893 */
anthony7bc87992012-03-25 02:32:51 +00002894 parse=ParseCommandOption(MagickPreviewOptions, MagickFalse,arg1);
2895 if ( parse < 0 )
2896 CLIWandExceptArgBreak(OptionError,"UnrecognizedPreviewType",
2897 option,arg1);
2898 new_image=PreviewImage(_image,(PreviewType)parse,_exception);
anthony805a2d42011-09-25 08:25:12 +00002899 break;
2900 }
anthonyafa3dfc2012-03-03 11:31:30 +00002901 if (LocaleCompare("profile",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002902 {
anthony4837ac22012-05-18 23:39:48 +00002903 /* Note: arguments do not have percent escapes expanded */
anthony805a2d42011-09-25 08:25:12 +00002904 const char
2905 *name;
2906
2907 const StringInfo
2908 *profile;
2909
2910 Image
2911 *profile_image;
2912
2913 ImageInfo
2914 *profile_info;
2915
anthonyafa3dfc2012-03-03 11:31:30 +00002916 if (IfPlusOp)
anthony92c93bd2012-03-19 14:02:47 +00002917 { /* Remove a profile from the _image. */
2918 (void) ProfileImage(_image,arg1,(const unsigned char *)
2919 NULL,0,_exception);
anthony805a2d42011-09-25 08:25:12 +00002920 break;
2921 }
anthony92c93bd2012-03-19 14:02:47 +00002922 /* Associate a profile with the _image. */
2923 profile_info=CloneImageInfo(_image_info);
2924 profile=GetImageProfile(_image,"iptc");
anthony805a2d42011-09-25 08:25:12 +00002925 if (profile != (StringInfo *) NULL)
2926 profile_info->profile=(void *) CloneStringInfo(profile);
anthony92c93bd2012-03-19 14:02:47 +00002927 profile_image=GetImageCache(profile_info,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00002928 profile_info=DestroyImageInfo(profile_info);
2929 if (profile_image == (Image *) NULL)
2930 {
2931 StringInfo
2932 *profile;
2933
anthony92c93bd2012-03-19 14:02:47 +00002934 profile_info=CloneImageInfo(_image_info);
anthonyfd706f92012-01-19 04:22:02 +00002935 (void) CopyMagickString(profile_info->filename,arg1,
anthony805a2d42011-09-25 08:25:12 +00002936 MaxTextExtent);
anthony92c93bd2012-03-19 14:02:47 +00002937 profile=FileToStringInfo(profile_info->filename,~0UL,_exception);
anthony805a2d42011-09-25 08:25:12 +00002938 if (profile != (StringInfo *) NULL)
2939 {
anthony92c93bd2012-03-19 14:02:47 +00002940 (void) ProfileImage(_image,profile_info->magick,
anthony805a2d42011-09-25 08:25:12 +00002941 GetStringInfoDatum(profile),(size_t)
anthony92c93bd2012-03-19 14:02:47 +00002942 GetStringInfoLength(profile),_exception);
anthony805a2d42011-09-25 08:25:12 +00002943 profile=DestroyStringInfo(profile);
2944 }
2945 profile_info=DestroyImageInfo(profile_info);
2946 break;
2947 }
2948 ResetImageProfileIterator(profile_image);
2949 name=GetNextImageProfile(profile_image);
2950 while (name != (const char *) NULL)
2951 {
2952 profile=GetImageProfile(profile_image,name);
2953 if (profile != (StringInfo *) NULL)
anthony92c93bd2012-03-19 14:02:47 +00002954 (void) ProfileImage(_image,name,GetStringInfoDatum(profile),
2955 (size_t) GetStringInfoLength(profile),_exception);
anthony805a2d42011-09-25 08:25:12 +00002956 name=GetNextImageProfile(profile_image);
2957 }
2958 profile_image=DestroyImage(profile_image);
2959 break;
2960 }
anthonyebb73a22012-03-22 14:25:52 +00002961 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002962 }
anthony805a2d42011-09-25 08:25:12 +00002963 case 'r':
2964 {
anthonyafa3dfc2012-03-03 11:31:30 +00002965 if (LocaleCompare("radial-blur",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002966 {
anthonyfd706f92012-01-19 04:22:02 +00002967 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00002968 if ((flags & RhoValue) == 0)
2969 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
cristyaa2c16c2012-03-25 22:21:35 +00002970 new_image=RadialBlurImage(_image,geometry_info.rho,_exception);
anthony805a2d42011-09-25 08:25:12 +00002971 break;
2972 }
anthonyafa3dfc2012-03-03 11:31:30 +00002973 if (LocaleCompare("raise",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002974 {
anthony7bcfe7f2012-03-30 14:01:22 +00002975 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00002976 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002977 flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00002978 if ((flags & SigmaValue) == 0)
2979 geometry.height=geometry.width;
anthony92c93bd2012-03-19 14:02:47 +00002980 (void) RaiseImage(_image,&geometry,normal_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00002981 break;
2982 }
anthonyafa3dfc2012-03-03 11:31:30 +00002983 if (LocaleCompare("random-threshold",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002984 {
anthony7bcfe7f2012-03-30 14:01:22 +00002985 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00002986 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002987 (void) RandomThresholdImage(_image,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00002988 break;
2989 }
anthony975a8d72012-04-12 13:54:36 +00002990 if (LocaleCompare("recolor",option+1) == 0)
2991 {
anthony464f1c42012-04-22 08:51:01 +00002992 CLIWandWarnReplaced("-color-matrix");
anthony975a8d72012-04-12 13:54:36 +00002993 CLISimpleOperatorImage(cli_wand,"-color-matrix",arg1,NULL);
2994 }
anthonyafa3dfc2012-03-03 11:31:30 +00002995 if (LocaleCompare("remap",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002996 {
anthony4837ac22012-05-18 23:39:48 +00002997 /* Note: arguments do not have percent escapes expanded */
anthony805a2d42011-09-25 08:25:12 +00002998 Image
2999 *remap_image;
3000
anthony92c93bd2012-03-19 14:02:47 +00003001 remap_image=GetImageCache(_image_info,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00003002 if (remap_image == (Image *) NULL)
3003 break;
anthony92c93bd2012-03-19 14:02:47 +00003004 (void) RemapImage(_quantize_info,_image,remap_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00003005 remap_image=DestroyImage(remap_image);
3006 break;
3007 }
anthonyafa3dfc2012-03-03 11:31:30 +00003008 if (LocaleCompare("repage",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003009 {
anthonyafa3dfc2012-03-03 11:31:30 +00003010 if (IfNormalOp)
cristy0d0de742012-03-25 19:32:48 +00003011 {
anthony7bcfe7f2012-03-30 14:01:22 +00003012 if (IfMagickFalse(IsGeometry(arg1)))
cristy0d0de742012-03-25 19:32:48 +00003013 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,
3014 arg1);
3015 (void) ResetImagePage(_image,arg1);
3016 }
anthony31f1bf72012-01-30 12:37:22 +00003017 else
anthony92c93bd2012-03-19 14:02:47 +00003018 (void) ParseAbsoluteGeometry("0x0+0+0",&_image->page);
anthony805a2d42011-09-25 08:25:12 +00003019 break;
3020 }
anthonyafa3dfc2012-03-03 11:31:30 +00003021 if (LocaleCompare("resample",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003022 {
anthonyf46d4262012-03-26 03:30:34 +00003023 /* FUTURE: Roll into a resize special operation */
anthonyfd706f92012-01-19 04:22:02 +00003024 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00003025 if ((flags & (RhoValue|SigmaValue)) == 0)
3026 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00003027 if ((flags & SigmaValue) == 0)
3028 geometry_info.sigma=geometry_info.rho;
anthony92c93bd2012-03-19 14:02:47 +00003029 new_image=ResampleImage(_image,geometry_info.rho,
cristyaa2c16c2012-03-25 22:21:35 +00003030 geometry_info.sigma,_image->filter,_exception);
anthony805a2d42011-09-25 08:25:12 +00003031 break;
3032 }
anthonyafa3dfc2012-03-03 11:31:30 +00003033 if (LocaleCompare("resize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003034 {
anthony7bcfe7f2012-03-30 14:01:22 +00003035 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003036 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003037 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
3038 new_image=ResizeImage(_image,geometry.width,geometry.height,
cristyaa2c16c2012-03-25 22:21:35 +00003039 _image->filter,_exception);
anthony805a2d42011-09-25 08:25:12 +00003040 break;
3041 }
anthonyafa3dfc2012-03-03 11:31:30 +00003042 if (LocaleCompare("roll",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003043 {
anthony7bcfe7f2012-03-30 14:01:22 +00003044 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003045 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003046 (void) ParsePageGeometry(_image,arg1,&geometry,_exception);
3047 new_image=RollImage(_image,geometry.x,geometry.y,_exception);
anthony805a2d42011-09-25 08:25:12 +00003048 break;
3049 }
anthonyafa3dfc2012-03-03 11:31:30 +00003050 if (LocaleCompare("rotate",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003051 {
anthony22de2722012-04-19 14:43:00 +00003052 flags=ParseGeometry(arg1,&geometry_info);
3053 if ((flags & RhoValue) == 0)
anthonyf42014d2012-03-25 09:53:06 +00003054 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyad255a02012-04-19 15:02:01 +00003055 if ((flags & GreaterValue) != 0 && (_image->columns <= _image->rows))
anthony22de2722012-04-19 14:43:00 +00003056 break;
3057 if ((flags & LessValue) != 0 && (_image->columns >= _image->rows))
3058 break;
anthony92c93bd2012-03-19 14:02:47 +00003059 new_image=RotateImage(_image,geometry_info.rho,_exception);
anthony805a2d42011-09-25 08:25:12 +00003060 break;
3061 }
anthonyebb73a22012-03-22 14:25:52 +00003062 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003063 }
3064 case 's':
3065 {
anthonyafa3dfc2012-03-03 11:31:30 +00003066 if (LocaleCompare("sample",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003067 {
anthonyfe1aa782012-03-24 13:43:04 +00003068 /* FUTURE: Roll into a resize special operator */
anthony7bcfe7f2012-03-30 14:01:22 +00003069 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003070 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003071 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
3072 new_image=SampleImage(_image,geometry.width,geometry.height,
3073 _exception);
anthony805a2d42011-09-25 08:25:12 +00003074 break;
3075 }
anthonyafa3dfc2012-03-03 11:31:30 +00003076 if (LocaleCompare("scale",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003077 {
anthonyfe1aa782012-03-24 13:43:04 +00003078 /* FUTURE: Roll into a resize special operator */
anthony7bcfe7f2012-03-30 14:01:22 +00003079 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003080 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003081 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
3082 new_image=ScaleImage(_image,geometry.width,geometry.height,
3083 _exception);
anthony805a2d42011-09-25 08:25:12 +00003084 break;
3085 }
anthonyf42014d2012-03-25 09:53:06 +00003086 if (LocaleCompare("segment",option+1) == 0)
3087 {
anthonyf42014d2012-03-25 09:53:06 +00003088 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00003089 if ((flags & (RhoValue|SigmaValue)) == 0)
3090 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyf42014d2012-03-25 09:53:06 +00003091 if ((flags & SigmaValue) == 0)
3092 geometry_info.sigma=1.0;
3093 (void) SegmentImage(_image,_image->colorspace,
3094 _image_info->verbose,geometry_info.rho,geometry_info.sigma,
3095 _exception);
3096 break;
3097 }
anthonyafa3dfc2012-03-03 11:31:30 +00003098 if (LocaleCompare("selective-blur",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003099 {
anthonyfd706f92012-01-19 04:22:02 +00003100 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00003101 if ((flags & (RhoValue|SigmaValue)) == 0)
3102 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3103 if ((flags & SigmaValue) == 0)
3104 geometry_info.sigma=1.0;
anthony805a2d42011-09-25 08:25:12 +00003105 if ((flags & PercentValue) != 0)
3106 geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
anthony92c93bd2012-03-19 14:02:47 +00003107 new_image=SelectiveBlurImage(_image,geometry_info.rho,
cristyaa2c16c2012-03-25 22:21:35 +00003108 geometry_info.sigma,geometry_info.xi,_exception);
anthony805a2d42011-09-25 08:25:12 +00003109 break;
3110 }
anthonyafa3dfc2012-03-03 11:31:30 +00003111 if (LocaleCompare("separate",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003112 {
anthony31f1bf72012-01-30 12:37:22 +00003113 /* WARNING: This can generate multiple images! */
anthony43f425d2012-02-26 12:58:58 +00003114 /* FUTURE - this may be replaced by a "-channel" method */
cristydfdb19e2012-03-21 22:22:24 +00003115 new_image=SeparateImages(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00003116 break;
3117 }
anthonyafa3dfc2012-03-03 11:31:30 +00003118 if (LocaleCompare("sepia-tone",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003119 {
anthony7bcfe7f2012-03-30 14:01:22 +00003120 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003121 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3122 new_image=SepiaToneImage(_image,StringToDoubleInterval(arg1,
3123 (double) QuantumRange+1.0),_exception);
anthony805a2d42011-09-25 08:25:12 +00003124 break;
3125 }
anthonyafa3dfc2012-03-03 11:31:30 +00003126 if (LocaleCompare("set",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003127 {
anthony4837ac22012-05-18 23:39:48 +00003128 /* Note: arguments do not have percent escapes expanded */
anthony805a2d42011-09-25 08:25:12 +00003129 char
3130 *value;
3131
anthonyf42014d2012-03-25 09:53:06 +00003132 if (IfPlusOp) {
anthonyfd706f92012-01-19 04:22:02 +00003133 if (LocaleNCompare(arg1,"registry:",9) == 0)
3134 (void) DeleteImageRegistry(arg1+9);
anthony805a2d42011-09-25 08:25:12 +00003135 else
anthony31f1bf72012-01-30 12:37:22 +00003136 if (LocaleNCompare(arg1,"option:",7) == 0)
anthony805a2d42011-09-25 08:25:12 +00003137 {
anthony92c93bd2012-03-19 14:02:47 +00003138 (void) DeleteImageOption(_image_info,arg1+7);
3139 (void) DeleteImageArtifact(_image,arg1+7);
anthony805a2d42011-09-25 08:25:12 +00003140 }
3141 else
anthony92c93bd2012-03-19 14:02:47 +00003142 (void) DeleteImageProperty(_image,arg1);
anthony805a2d42011-09-25 08:25:12 +00003143 break;
3144 }
anthonyf42014d2012-03-25 09:53:06 +00003145 value=InterpretImageProperties(_image_info,_image,arg2,_exception);
anthony805a2d42011-09-25 08:25:12 +00003146 if (value == (char *) NULL)
anthony964d28e2012-05-17 23:39:46 +00003147 CLIWandExceptionBreak(OptionWarning,"InterpretPropertyFailure",
3148 option);
anthonyfd706f92012-01-19 04:22:02 +00003149 if (LocaleNCompare(arg1,"registry:",9) == 0)
anthonyf42014d2012-03-25 09:53:06 +00003150 (void) SetImageRegistry(StringRegistryType,arg1+9,value,_exception);
anthony805a2d42011-09-25 08:25:12 +00003151 else
anthonyfd706f92012-01-19 04:22:02 +00003152 if (LocaleNCompare(arg1,"option:",7) == 0)
anthony805a2d42011-09-25 08:25:12 +00003153 {
anthony92c93bd2012-03-19 14:02:47 +00003154 (void) SetImageOption(_image_info,arg1+7,value);
3155 (void) SetImageArtifact(_image,arg1+7,value);
anthony805a2d42011-09-25 08:25:12 +00003156 }
3157 else
anthony92c93bd2012-03-19 14:02:47 +00003158 (void) SetImageProperty(_image,arg1,value,_exception);
anthony805a2d42011-09-25 08:25:12 +00003159 value=DestroyString(value);
3160 break;
3161 }
anthonyafa3dfc2012-03-03 11:31:30 +00003162 if (LocaleCompare("shade",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003163 {
anthonyfd706f92012-01-19 04:22:02 +00003164 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00003165 if (((flags & RhoValue) == 0) || ((flags & SigmaValue) == 0))
3166 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003167 new_image=ShadeImage(_image,normal_op,geometry_info.rho,
3168 geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00003169 break;
3170 }
anthonyafa3dfc2012-03-03 11:31:30 +00003171 if (LocaleCompare("shadow",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003172 {
anthonyfd706f92012-01-19 04:22:02 +00003173 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00003174 if ((flags & (RhoValue|SigmaValue)) == 0)
3175 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00003176 if ((flags & SigmaValue) == 0)
3177 geometry_info.sigma=1.0;
3178 if ((flags & XiValue) == 0)
3179 geometry_info.xi=4.0;
3180 if ((flags & PsiValue) == 0)
3181 geometry_info.psi=4.0;
cristyaa2c16c2012-03-25 22:21:35 +00003182 new_image=ShadowImage(_image,geometry_info.rho,geometry_info.sigma,
3183 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
3184 ceil(geometry_info.psi-0.5),_exception);
anthony805a2d42011-09-25 08:25:12 +00003185 break;
3186 }
anthonyafa3dfc2012-03-03 11:31:30 +00003187 if (LocaleCompare("sharpen",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003188 {
anthonyfd706f92012-01-19 04:22:02 +00003189 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00003190 if ((flags & (RhoValue|SigmaValue)) == 0)
3191 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00003192 if ((flags & SigmaValue) == 0)
3193 geometry_info.sigma=1.0;
3194 if ((flags & XiValue) == 0)
3195 geometry_info.xi=0.0;
cristyaa2c16c2012-03-25 22:21:35 +00003196 new_image=SharpenImage(_image,geometry_info.rho,geometry_info.sigma,
3197 _exception);
anthony805a2d42011-09-25 08:25:12 +00003198 break;
3199 }
anthonyafa3dfc2012-03-03 11:31:30 +00003200 if (LocaleCompare("shave",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003201 {
anthony7bcfe7f2012-03-30 14:01:22 +00003202 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003203 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003204 flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
3205 new_image=ShaveImage(_image,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00003206 break;
3207 }
anthonyafa3dfc2012-03-03 11:31:30 +00003208 if (LocaleCompare("shear",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003209 {
anthonyfd706f92012-01-19 04:22:02 +00003210 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00003211 if ((flags & RhoValue) == 0)
3212 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00003213 if ((flags & SigmaValue) == 0)
3214 geometry_info.sigma=geometry_info.rho;
anthony92c93bd2012-03-19 14:02:47 +00003215 new_image=ShearImage(_image,geometry_info.rho,
3216 geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00003217 break;
3218 }
anthonyafa3dfc2012-03-03 11:31:30 +00003219 if (LocaleCompare("sigmoidal-contrast",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003220 {
anthonyfd706f92012-01-19 04:22:02 +00003221 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00003222 if ((flags & RhoValue) == 0)
3223 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00003224 if ((flags & SigmaValue) == 0)
3225 geometry_info.sigma=(double) QuantumRange/2.0;
3226 if ((flags & PercentValue) != 0)
3227 geometry_info.sigma=(double) QuantumRange*geometry_info.sigma/
3228 100.0;
anthony92c93bd2012-03-19 14:02:47 +00003229 (void) SigmoidalContrastImage(_image,normal_op,geometry_info.rho,
anthonyb1d483a2012-04-14 12:53:56 +00003230 geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00003231 break;
3232 }
anthonyafa3dfc2012-03-03 11:31:30 +00003233 if (LocaleCompare("sketch",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003234 {
anthonyfd706f92012-01-19 04:22:02 +00003235 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00003236 if ((flags & (RhoValue|SigmaValue)) == 0)
3237 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00003238 if ((flags & SigmaValue) == 0)
3239 geometry_info.sigma=1.0;
anthony92c93bd2012-03-19 14:02:47 +00003240 new_image=SketchImage(_image,geometry_info.rho,
cristyaa2c16c2012-03-25 22:21:35 +00003241 geometry_info.sigma,geometry_info.xi,_exception);
anthony805a2d42011-09-25 08:25:12 +00003242 break;
3243 }
anthonyafa3dfc2012-03-03 11:31:30 +00003244 if (LocaleCompare("solarize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003245 {
anthony7bcfe7f2012-03-30 14:01:22 +00003246 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003247 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003248 (void) SolarizeImage(_image,StringToDoubleInterval(arg1,(double)
3249 QuantumRange+1.0),_exception);
anthony805a2d42011-09-25 08:25:12 +00003250 break;
3251 }
anthonyafa3dfc2012-03-03 11:31:30 +00003252 if (LocaleCompare("sparse-color",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003253 {
anthonyf42014d2012-03-25 09:53:06 +00003254 parse= ParseCommandOption(MagickSparseColorOptions,MagickFalse,arg1);
3255 if ( parse < 0 )
3256 CLIWandExceptArgBreak(OptionError,"UnrecognizedSparseColorMethod",
3257 option,arg1);
anthony964d28e2012-05-17 23:39:46 +00003258 new_image=SparseColorOption(_image,(SparseColorMethod)parse,arg2,
3259 _exception);
anthony805a2d42011-09-25 08:25:12 +00003260 break;
3261 }
anthonyafa3dfc2012-03-03 11:31:30 +00003262 if (LocaleCompare("splice",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003263 {
anthony7bcfe7f2012-03-30 14:01:22 +00003264 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003265 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyb1e21ed2012-04-20 12:43:12 +00003266 flags=ParseGravityGeometry(_image,arg1,&geometry,_exception);
anthony92c93bd2012-03-19 14:02:47 +00003267 new_image=SpliceImage(_image,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00003268 break;
3269 }
anthonyafa3dfc2012-03-03 11:31:30 +00003270 if (LocaleCompare("spread",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003271 {
anthonyb1e21ed2012-04-20 12:43:12 +00003272 flags=ParseGeometry(arg1,&geometry_info);
3273 if ((flags & RhoValue) == 0)
3274 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
anthony92c93bd2012-03-19 14:02:47 +00003275 new_image=SpreadImage(_image,geometry_info.rho,_image->interpolate,
3276 _exception);
anthony805a2d42011-09-25 08:25:12 +00003277 break;
3278 }
anthonyafa3dfc2012-03-03 11:31:30 +00003279 if (LocaleCompare("statistic",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003280 {
anthony7bc87992012-03-25 02:32:51 +00003281 parse=ParseCommandOption(MagickStatisticOptions,MagickFalse,arg1);
3282 if ( parse < 0 )
anthonyf42014d2012-03-25 09:53:06 +00003283 CLIWandExceptArgBreak(OptionError,"UnrecognizedStatisticType",
anthony7bc87992012-03-25 02:32:51 +00003284 option,arg1);
anthony975a8d72012-04-12 13:54:36 +00003285 flags=ParseGeometry(arg2,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00003286 if ((flags & RhoValue) == 0)
3287 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
anthony975a8d72012-04-12 13:54:36 +00003288 if ((flags & SigmaValue) == 0)
3289 geometry_info.sigma=geometry_info.rho;
anthony7bc87992012-03-25 02:32:51 +00003290 new_image=StatisticImage(_image,(StatisticType)parse,
3291 (size_t) geometry_info.rho,(size_t) geometry_info.sigma,
3292 _exception);
anthony805a2d42011-09-25 08:25:12 +00003293 break;
3294 }
anthonyafa3dfc2012-03-03 11:31:30 +00003295 if (LocaleCompare("strip",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003296 {
anthony92c93bd2012-03-19 14:02:47 +00003297 (void) StripImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00003298 break;
3299 }
anthonyafa3dfc2012-03-03 11:31:30 +00003300 if (LocaleCompare("swirl",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003301 {
cristy898c6042012-06-24 00:36:34 +00003302 flags=ParseGeometry(arg1,&geometry_info);
anthonyb1e21ed2012-04-20 12:43:12 +00003303 if ((flags & RhoValue) == 0)
cristy898c6042012-06-24 00:36:34 +00003304 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003305 new_image=SwirlImage(_image,geometry_info.rho,
3306 _image->interpolate,_exception);
anthony805a2d42011-09-25 08:25:12 +00003307 break;
3308 }
anthonyebb73a22012-03-22 14:25:52 +00003309 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003310 }
3311 case 't':
3312 {
anthonyafa3dfc2012-03-03 11:31:30 +00003313 if (LocaleCompare("threshold",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003314 {
3315 double
3316 threshold;
3317
anthony52bef752012-03-27 13:54:47 +00003318 threshold=(double) QuantumRange/2;
3319 if (normal_op) {
anthony7bcfe7f2012-03-30 14:01:22 +00003320 if (IfMagickFalse(IsGeometry(arg1)))
anthony52bef752012-03-27 13:54:47 +00003321 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00003322 threshold=StringToDoubleInterval(arg1,(double) QuantumRange+1.0);
anthony52bef752012-03-27 13:54:47 +00003323 }
anthony92c93bd2012-03-19 14:02:47 +00003324 (void) BilevelImage(_image,threshold,_exception);
anthony805a2d42011-09-25 08:25:12 +00003325 break;
3326 }
anthonyafa3dfc2012-03-03 11:31:30 +00003327 if (LocaleCompare("thumbnail",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003328 {
anthony7bcfe7f2012-03-30 14:01:22 +00003329 if (IfMagickFalse(IsGeometry(arg1)))
anthony52bef752012-03-27 13:54:47 +00003330 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003331 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
3332 new_image=ThumbnailImage(_image,geometry.width,geometry.height,
3333 _exception);
anthony805a2d42011-09-25 08:25:12 +00003334 break;
3335 }
anthonyafa3dfc2012-03-03 11:31:30 +00003336 if (LocaleCompare("tint",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003337 {
anthony7bcfe7f2012-03-30 14:01:22 +00003338 if (IfMagickFalse(IsGeometry(arg1)))
anthony52bef752012-03-27 13:54:47 +00003339 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003340 new_image=TintImage(_image,arg1,&_draw_info->fill,_exception);
anthony805a2d42011-09-25 08:25:12 +00003341 break;
3342 }
anthonyafa3dfc2012-03-03 11:31:30 +00003343 if (LocaleCompare("transform",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003344 {
anthony464f1c42012-04-22 08:51:01 +00003345 CLIWandWarnReplaced("+distort AffineProjection");
anthony52bef752012-03-27 13:54:47 +00003346 new_image=AffineTransformImage(_image,&_draw_info->affine,_exception);
anthony805a2d42011-09-25 08:25:12 +00003347 break;
3348 }
anthonyafa3dfc2012-03-03 11:31:30 +00003349 if (LocaleCompare("transparent",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003350 {
3351 PixelInfo
3352 target;
3353
anthony92c93bd2012-03-19 14:02:47 +00003354 (void) QueryColorCompliance(arg1,AllCompliance,&target,_exception);
3355 (void) TransparentPaintImage(_image,&target,(Quantum)
3356 TransparentAlpha,plus_alt_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00003357 break;
3358 }
anthonyafa3dfc2012-03-03 11:31:30 +00003359 if (LocaleCompare("transpose",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003360 {
anthony92c93bd2012-03-19 14:02:47 +00003361 new_image=TransposeImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00003362 break;
3363 }
anthonyafa3dfc2012-03-03 11:31:30 +00003364 if (LocaleCompare("transverse",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003365 {
anthony92c93bd2012-03-19 14:02:47 +00003366 new_image=TransverseImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00003367 break;
3368 }
anthonyafa3dfc2012-03-03 11:31:30 +00003369 if (LocaleCompare("trim",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003370 {
anthony92c93bd2012-03-19 14:02:47 +00003371 new_image=TrimImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00003372 break;
3373 }
anthonyafa3dfc2012-03-03 11:31:30 +00003374 if (LocaleCompare("type",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003375 {
anthonyab3a50c2011-10-27 11:48:57 +00003376 /* Note that "type" setting should have already been defined */
anthony92c93bd2012-03-19 14:02:47 +00003377 (void) SetImageType(_image,_image_info->type,_exception);
anthony805a2d42011-09-25 08:25:12 +00003378 break;
3379 }
anthonyebb73a22012-03-22 14:25:52 +00003380 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003381 }
3382 case 'u':
3383 {
anthonyafa3dfc2012-03-03 11:31:30 +00003384 if (LocaleCompare("unique",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003385 {
anthony52bef752012-03-27 13:54:47 +00003386 /* FUTURE: move to SyncImageSettings() and AcqireImage()???
3387 Option is not documented, bt appears to be for "identify".
3388 We may need a identify specific verbose!
3389 */
3390 if (plus_alt_op) {
anthony92c93bd2012-03-19 14:02:47 +00003391 (void) DeleteImageArtifact(_image,"identify:unique-colors");
anthony805a2d42011-09-25 08:25:12 +00003392 break;
3393 }
anthony92c93bd2012-03-19 14:02:47 +00003394 (void) SetImageArtifact(_image,"identify:unique-colors","true");
3395 (void) SetImageArtifact(_image,"verbose","true");
anthony805a2d42011-09-25 08:25:12 +00003396 break;
3397 }
anthonyafa3dfc2012-03-03 11:31:30 +00003398 if (LocaleCompare("unique-colors",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003399 {
anthony92c93bd2012-03-19 14:02:47 +00003400 new_image=UniqueImageColors(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00003401 break;
3402 }
anthonyafa3dfc2012-03-03 11:31:30 +00003403 if (LocaleCompare("unsharp",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003404 {
anthonyfd706f92012-01-19 04:22:02 +00003405 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00003406 if ((flags & (RhoValue|SigmaValue)) == 0)
3407 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00003408 if ((flags & SigmaValue) == 0)
3409 geometry_info.sigma=1.0;
3410 if ((flags & XiValue) == 0)
3411 geometry_info.xi=1.0;
3412 if ((flags & PsiValue) == 0)
3413 geometry_info.psi=0.05;
anthony92c93bd2012-03-19 14:02:47 +00003414 new_image=UnsharpMaskImage(_image,geometry_info.rho,
3415 geometry_info.sigma,geometry_info.xi,geometry_info.psi,_exception);
anthony805a2d42011-09-25 08:25:12 +00003416 break;
3417 }
anthonyebb73a22012-03-22 14:25:52 +00003418 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003419 }
3420 case 'v':
3421 {
anthonyafa3dfc2012-03-03 11:31:30 +00003422 if (LocaleCompare("verbose",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003423 {
anthonyafa3dfc2012-03-03 11:31:30 +00003424 /* FUTURE: move to SyncImageSettings() and AcquireImage()???
anthony92c93bd2012-03-19 14:02:47 +00003425 three places! ImageArtifact ImageOption _image_info->verbose
anthony5330ae02012-03-20 14:17:01 +00003426 Some how new images also get this artifact!
anthony31f1bf72012-01-30 12:37:22 +00003427 */
anthony92c93bd2012-03-19 14:02:47 +00003428 (void) SetImageArtifact(_image,option+1,
anthonyafa3dfc2012-03-03 11:31:30 +00003429 IfNormalOp ? "true" : "false" );
anthony805a2d42011-09-25 08:25:12 +00003430 break;
3431 }
anthonyafa3dfc2012-03-03 11:31:30 +00003432 if (LocaleCompare("vignette",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003433 {
anthonyfd706f92012-01-19 04:22:02 +00003434 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00003435 if ((flags & (RhoValue|SigmaValue)) == 0)
3436 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00003437 if ((flags & SigmaValue) == 0)
3438 geometry_info.sigma=1.0;
3439 if ((flags & XiValue) == 0)
anthony92c93bd2012-03-19 14:02:47 +00003440 geometry_info.xi=0.1*_image->columns;
anthony805a2d42011-09-25 08:25:12 +00003441 if ((flags & PsiValue) == 0)
anthony92c93bd2012-03-19 14:02:47 +00003442 geometry_info.psi=0.1*_image->rows;
3443 new_image=VignetteImage(_image,geometry_info.rho,geometry_info.sigma,
cristyaa2c16c2012-03-25 22:21:35 +00003444 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
3445 ceil(geometry_info.psi-0.5),_exception);
anthony805a2d42011-09-25 08:25:12 +00003446 break;
3447 }
anthonyebb73a22012-03-22 14:25:52 +00003448 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003449 }
3450 case 'w':
3451 {
anthonyafa3dfc2012-03-03 11:31:30 +00003452 if (LocaleCompare("wave",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003453 {
anthonyfd706f92012-01-19 04:22:02 +00003454 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00003455 if ((flags & (RhoValue|SigmaValue)) == 0)
3456 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00003457 if ((flags & SigmaValue) == 0)
3458 geometry_info.sigma=1.0;
anthony92c93bd2012-03-19 14:02:47 +00003459 new_image=WaveImage(_image,geometry_info.rho,geometry_info.sigma,
3460 _image->interpolate,_exception);
anthony805a2d42011-09-25 08:25:12 +00003461 break;
3462 }
anthonyafa3dfc2012-03-03 11:31:30 +00003463 if (LocaleCompare("white-threshold",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003464 {
anthony7bcfe7f2012-03-30 14:01:22 +00003465 if (IfMagickFalse(IsGeometry(arg1)))
anthony52bef752012-03-27 13:54:47 +00003466 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003467 (void) WhiteThresholdImage(_image,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00003468 break;
3469 }
anthonyebb73a22012-03-22 14:25:52 +00003470 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003471 }
3472 default:
anthonyebb73a22012-03-22 14:25:52 +00003473 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003474 }
anthony964d28e2012-05-17 23:39:46 +00003475 /* clean up percent escape interpreted strings */
3476 if (arg1 != arg1n )
3477 arg1=DestroyString((char *)arg1);
3478 if (arg2 != arg2n )
3479 arg2=DestroyString((char *)arg2);
3480
3481 /* Replace current image with any image that was generated
3482 and set image point to last image (so image->next is correct) */
anthony805a2d42011-09-25 08:25:12 +00003483 if (new_image != (Image *) NULL)
anthony92c93bd2012-03-19 14:02:47 +00003484 ReplaceImageInListReturnLast(&_image,new_image);
anthony805a2d42011-09-25 08:25:12 +00003485
anthony31f1bf72012-01-30 12:37:22 +00003486 return;
anthony92c93bd2012-03-19 14:02:47 +00003487#undef _image_info
3488#undef _draw_info
3489#undef _quantize_info
3490#undef _image
3491#undef _exception
anthonyafa3dfc2012-03-03 11:31:30 +00003492#undef IfNormalOp
3493#undef IfPlusOp
anthony31f1bf72012-01-30 12:37:22 +00003494#undef normal_op
anthonyafa3dfc2012-03-03 11:31:30 +00003495#undef plus_alt_op
anthony31f1bf72012-01-30 12:37:22 +00003496}
anthonyfd706f92012-01-19 04:22:02 +00003497
anthony43f425d2012-02-26 12:58:58 +00003498WandExport void CLISimpleOperatorImages(MagickCLI *cli_wand,
anthonyafa3dfc2012-03-03 11:31:30 +00003499 const char *option, const char *arg1, const char *arg2)
anthony31f1bf72012-01-30 12:37:22 +00003500{
3501 size_t
anthony43f425d2012-02-26 12:58:58 +00003502 n,
anthony31f1bf72012-01-30 12:37:22 +00003503 i;
3504
anthony43f425d2012-02-26 12:58:58 +00003505 assert(cli_wand != (MagickCLI *) NULL);
3506 assert(cli_wand->signature == WandSignature);
3507 assert(cli_wand->wand.signature == WandSignature);
3508 assert(cli_wand->wand.images != (Image *) NULL); /* images must be present */
anthony7bcfe7f2012-03-30 14:01:22 +00003509 if (IfMagickTrue(cli_wand->wand.debug))
anthony43f425d2012-02-26 12:58:58 +00003510 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
anthony31f1bf72012-01-30 12:37:22 +00003511
anthonyafa3dfc2012-03-03 11:31:30 +00003512#if !USE_WAND_METHODS
3513 /* FUTURE add appropriate tracing */
anthony31f1bf72012-01-30 12:37:22 +00003514 i=0;
anthony43f425d2012-02-26 12:58:58 +00003515 n=GetImageListLength(cli_wand->wand.images);
3516 cli_wand->wand.images=GetFirstImageInList(cli_wand->wand.images);
anthonyafa3dfc2012-03-03 11:31:30 +00003517 while (1) {
anthony31f1bf72012-01-30 12:37:22 +00003518 i++;
anthonyafa3dfc2012-03-03 11:31:30 +00003519 CLISimpleOperatorImage(cli_wand, option, arg1, arg2);
anthony43f425d2012-02-26 12:58:58 +00003520 if ( cli_wand->wand.images->next == (Image *) NULL )
3521 break;
3522 cli_wand->wand.images=cli_wand->wand.images->next;
anthony31f1bf72012-01-30 12:37:22 +00003523 }
anthony43f425d2012-02-26 12:58:58 +00003524 assert( i == n );
3525 cli_wand->wand.images=GetFirstImageInList(cli_wand->wand.images);
anthonyafa3dfc2012-03-03 11:31:30 +00003526#else
3527 MagickResetIterator(&cli_wand->wand);
anthony7bcfe7f2012-03-30 14:01:22 +00003528 while ( IfMagickTrue(MagickNextImage(&cli_wand->wand)) )
anthonyafa3dfc2012-03-03 11:31:30 +00003529 CLISimpleOperatorImage(cli_wand, option, arg1, arg2);
3530 MagickResetIterator(&cli_wand->wand);
3531#endif
anthony31f1bf72012-01-30 12:37:22 +00003532 return;
anthony805a2d42011-09-25 08:25:12 +00003533}
3534
3535/*
3536%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3537% %
3538% %
3539% %
anthony43f425d2012-02-26 12:58:58 +00003540+ 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 +00003541% %
3542% %
3543% %
3544%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3545%
anthony43f425d2012-02-26 12:58:58 +00003546% CLIListOperatorImages() applies a single operation that is apply to the
anthony31f1bf72012-01-30 12:37:22 +00003547% entire image list as a whole. The result is often a complete replacment
3548% of the image list with a completely new list, or just a single image.
anthony805a2d42011-09-25 08:25:12 +00003549%
3550% The format of the MogrifyImage method is:
3551%
anthony43f425d2012-02-26 12:58:58 +00003552% void CLIListOperatorImages(MagickCLI *cli_wand,
anthonyafa3dfc2012-03-03 11:31:30 +00003553% const char *option, const char *arg1, const char *arg2)
anthony805a2d42011-09-25 08:25:12 +00003554%
3555% A description of each parameter follows:
3556%
anthony43f425d2012-02-26 12:58:58 +00003557% o cli_wand: structure holding settings to be applied
anthony805a2d42011-09-25 08:25:12 +00003558%
anthony36a8c2c2012-02-10 00:08:44 +00003559% o option: The option string for the operation
3560%
anthony31f1bf72012-01-30 12:37:22 +00003561% o arg1, arg2: optional argument strings to the operation
anthonye5fcd362012-04-09 04:02:09 +00003562% arg2 is currently not used
anthony8b10b462012-02-08 12:32:44 +00003563%
anthony805a2d42011-09-25 08:25:12 +00003564*/
anthony43f425d2012-02-26 12:58:58 +00003565WandExport void CLIListOperatorImages(MagickCLI *cli_wand,
anthony964d28e2012-05-17 23:39:46 +00003566 const char *option,const char *arg1n, const char *arg2n)
anthony805a2d42011-09-25 08:25:12 +00003567{
anthony2a0ec8c2012-03-24 04:35:56 +00003568 ssize_t
3569 parse;
3570
anthony31f1bf72012-01-30 12:37:22 +00003571 Image
3572 *new_images;
anthony805a2d42011-09-25 08:25:12 +00003573
anthony964d28e2012-05-17 23:39:46 +00003574 const char /* For percent escape interpretImageProperties() */
3575 *arg1,
3576 *arg2;
3577
anthony2e4501b2012-03-30 04:41:54 +00003578#define _image_info (cli_wand->wand.image_info)
3579#define _images (cli_wand->wand.images)
3580#define _exception (cli_wand->wand.exception)
3581#define _draw_info (cli_wand->draw_info)
3582#define _quantize_info (cli_wand->quantize_info)
anthony964d28e2012-05-17 23:39:46 +00003583#define _process_flags (cli_wand->process_flags)
3584#define _option_type ((CommandOptionFlags) cli_wand->command->flags)
anthonyafa3dfc2012-03-03 11:31:30 +00003585#define IfNormalOp (*option=='-')
3586#define IfPlusOp (*option!='-')
anthony7bcfe7f2012-03-30 14:01:22 +00003587#define normal_op IsMagickTrue(IfNormalOp)
anthony805a2d42011-09-25 08:25:12 +00003588
anthony43f425d2012-02-26 12:58:58 +00003589 assert(cli_wand != (MagickCLI *) NULL);
3590 assert(cli_wand->signature == WandSignature);
3591 assert(cli_wand->wand.signature == WandSignature);
anthony92c93bd2012-03-19 14:02:47 +00003592 assert(_images != (Image *) NULL); /* _images must be present */
anthony7bcfe7f2012-03-30 14:01:22 +00003593 if (IfMagickTrue(cli_wand->wand.debug))
anthony43f425d2012-02-26 12:58:58 +00003594 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
anthony31f1bf72012-01-30 12:37:22 +00003595
anthony964d28e2012-05-17 23:39:46 +00003596 /* Interpret Percent Escapes in Arguments - using first image */
3597 arg1 = arg1n;
3598 arg2 = arg2n;
3599 if ( (((_process_flags & ProcessInterpretProperities) != 0 )
3600 || ((_option_type & AlwaysInterpretArgsFlag) != 0)
3601 ) && ((_option_type & NeverInterpretArgsFlag) == 0) ) {
3602 /* Interpret Percent escapes in argument 1 */
3603 if (arg1n != (char *) NULL) {
3604 arg1=InterpretImageProperties(_image_info,_images,arg1n,_exception);
3605 if (arg1 == (char *) NULL) {
3606 CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
3607 arg1=arg1n; /* use the given argument as is */
3608 }
3609 }
3610 if (arg2n != (char *) NULL) {
3611 arg2=InterpretImageProperties(_image_info,_images,arg2n,_exception);
3612 if (arg2 == (char *) NULL) {
3613 CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
3614 arg2=arg2n; /* use the given argument as is */
3615 }
3616 }
3617 }
anthony4837ac22012-05-18 23:39:48 +00003618#undef _process_flags
anthony964d28e2012-05-17 23:39:46 +00003619#undef _option_type
3620
3621#if 0
3622 (void) FormatLocaleFile(stderr,
3623 "CLIListOperatorImages: \"%s\" \"%s\" \"%s\"\n",option,arg1,arg2);
3624#endif
3625
3626
anthony31f1bf72012-01-30 12:37:22 +00003627 new_images=NewImageList();
3628
anthonyafa3dfc2012-03-03 11:31:30 +00003629 switch (*(option+1))
anthony805a2d42011-09-25 08:25:12 +00003630 {
3631 case 'a':
3632 {
anthonyafa3dfc2012-03-03 11:31:30 +00003633 if (LocaleCompare("append",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003634 {
anthony92c93bd2012-03-19 14:02:47 +00003635 new_images=AppendImages(_images,normal_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00003636 break;
3637 }
anthonyafa3dfc2012-03-03 11:31:30 +00003638 if (LocaleCompare("average",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003639 {
anthony464f1c42012-04-22 08:51:01 +00003640 CLIWandWarnReplaced("-evaluate-sequence Mean");
anthonyafa3dfc2012-03-03 11:31:30 +00003641 CLIListOperatorImages(cli_wand,"-evaluate-sequence","Mean",NULL);
anthony805a2d42011-09-25 08:25:12 +00003642 break;
3643 }
anthonyebb73a22012-03-22 14:25:52 +00003644 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003645 }
3646 case 'c':
3647 {
cristy5f257b22012-03-07 00:27:29 +00003648 if (LocaleCompare("channel-fx",option+1) == 0)
cristy87c02f42012-02-24 00:19:10 +00003649 {
anthony92c93bd2012-03-19 14:02:47 +00003650 new_images=ChannelFxImage(_images,arg1,_exception);
cristy87c02f42012-02-24 00:19:10 +00003651 break;
3652 }
anthonyafa3dfc2012-03-03 11:31:30 +00003653 if (LocaleCompare("clut",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003654 {
anthony805a2d42011-09-25 08:25:12 +00003655 Image
anthony31f1bf72012-01-30 12:37:22 +00003656 *clut_image;
anthony805a2d42011-09-25 08:25:12 +00003657
anthonyafa3dfc2012-03-03 11:31:30 +00003658 /* FUTURE - make this a compose option, and thus can be used
3659 with layers compose or even compose last image over all other
anthony92c93bd2012-03-19 14:02:47 +00003660 _images.
cristy87c02f42012-02-24 00:19:10 +00003661 */
anthony92c93bd2012-03-19 14:02:47 +00003662 new_images=RemoveFirstImageFromList(&_images);
3663 clut_image=RemoveLastImageFromList(&_images);
anthonye8f56492012-02-12 12:39:02 +00003664 /* FUTURE - produce Exception, rather than silent fail */
anthony805a2d42011-09-25 08:25:12 +00003665 if (clut_image == (Image *) NULL)
cristy87c02f42012-02-24 00:19:10 +00003666 break;
cristye52fb5e2012-04-06 23:30:20 +00003667 (void) ClutImage(new_images,clut_image,new_images->interpolate,_exception);
anthony805a2d42011-09-25 08:25:12 +00003668 clut_image=DestroyImage(clut_image);
anthony805a2d42011-09-25 08:25:12 +00003669 break;
3670 }
anthonyafa3dfc2012-03-03 11:31:30 +00003671 if (LocaleCompare("coalesce",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003672 {
anthony92c93bd2012-03-19 14:02:47 +00003673 new_images=CoalesceImages(_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003674 break;
3675 }
anthonyafa3dfc2012-03-03 11:31:30 +00003676 if (LocaleCompare("combine",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003677 {
anthony43f425d2012-02-26 12:58:58 +00003678 /* FUTURE - this may be replaced by a 'channel' method */
cristy46f354c2012-07-04 13:31:29 +00003679 parse = ParseCommandOption(MagickColorspaceOptions,MagickFalse,arg1);
3680 new_images=CombineImages(_images,(ColorspaceType) parse,_exception);
anthony805a2d42011-09-25 08:25:12 +00003681 break;
3682 }
anthonyafa3dfc2012-03-03 11:31:30 +00003683 if (LocaleCompare("composite",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003684 {
cristyfeb3e962012-03-29 17:25:55 +00003685 CompositeOperator
3686 compose;
3687
3688 const char*
3689 value;
3690
3691 MagickBooleanType
3692 clip_to_self;
3693
anthony805a2d42011-09-25 08:25:12 +00003694 Image
3695 *mask_image,
anthony31f1bf72012-01-30 12:37:22 +00003696 *source_image;
anthony805a2d42011-09-25 08:25:12 +00003697
3698 RectangleInfo
3699 geometry;
3700
anthony7bcfe7f2012-03-30 14:01:22 +00003701 /* Compose value from "-compose" option only */
anthony92c93bd2012-03-19 14:02:47 +00003702 value=GetImageOption(_image_info,"compose");
cristy542a95b2012-04-03 19:30:58 +00003703 if (value == (const char *) NULL)
anthony31f1bf72012-01-30 12:37:22 +00003704 compose=OverCompositeOp; /* use Over not source_image->compose */
cristy542a95b2012-04-03 19:30:58 +00003705 else
3706 compose=(CompositeOperator) ParseCommandOption(MagickComposeOptions,
3707 MagickFalse,value);
anthony5f867ae2011-10-09 10:28:34 +00003708
anthony7bcfe7f2012-03-30 14:01:22 +00003709 /* Get "clip-to-self" expert setting (false is normal) */
cristyca0e82c2012-04-10 11:53:24 +00003710 value=GetImageOption(_image_info,"compose:clip-to-self");
3711 if (value == (const char *) NULL)
3712 clip_to_self=MagickTrue;
3713 else
3714 clip_to_self=IsStringTrue(GetImageOption(_image_info,
3715 "compose:clip-to-self")); /* if this is true */
anthony2e4501b2012-03-30 04:41:54 +00003716 value=GetImageOption(_image_info,"compose:outside-overlay");
anthony7bcfe7f2012-03-30 14:01:22 +00003717 if (value != (const char *) NULL) { /* or this false */
anthony2e4501b2012-03-30 04:41:54 +00003718 /* FUTURE: depreciate warning for "compose:outside-overlay"*/
anthony7bcfe7f2012-03-30 14:01:22 +00003719 clip_to_self= IsMagickFalse(IsStringNotFalse(value));
anthony2e4501b2012-03-30 04:41:54 +00003720 }
3721
anthony92c93bd2012-03-19 14:02:47 +00003722 new_images=RemoveFirstImageFromList(&_images);
3723 source_image=RemoveFirstImageFromList(&_images);
anthony31f1bf72012-01-30 12:37:22 +00003724 if (source_image == (Image *) NULL)
anthony7bcfe7f2012-03-30 14:01:22 +00003725 break; /* FUTURE - produce Exception, rather than silent fail */
anthonye8f56492012-02-12 12:39:02 +00003726
anthony31f1bf72012-01-30 12:37:22 +00003727 /* FUTURE - this should not be here! - should be part of -geometry */
3728 (void) TransformImage(&source_image,(char *) NULL,
anthony92c93bd2012-03-19 14:02:47 +00003729 source_image->geometry,_exception);
anthony5f867ae2011-10-09 10:28:34 +00003730
anthony31f1bf72012-01-30 12:37:22 +00003731 SetGeometry(source_image,&geometry);
3732 (void) ParseAbsoluteGeometry(source_image->geometry,&geometry);
3733 GravityAdjustGeometry(new_images->columns,new_images->rows,
3734 new_images->gravity, &geometry);
anthony5f867ae2011-10-09 10:28:34 +00003735
anthony92c93bd2012-03-19 14:02:47 +00003736 mask_image=RemoveFirstImageFromList(&_images);
anthony805a2d42011-09-25 08:25:12 +00003737 if (mask_image != (Image *) NULL)
anthony31f1bf72012-01-30 12:37:22 +00003738 { /* handle a third write mask image */
anthony5f867ae2011-10-09 10:28:34 +00003739 if ((compose == DisplaceCompositeOp) ||
anthony7bcfe7f2012-03-30 14:01:22 +00003740 (compose == DistortCompositeOp)) {
3741 /* Merge Y displacement into X displace/distort map. */
3742 (void) CompositeImage(source_image,mask_image,
3743 CopyGreenCompositeOp,MagickTrue,0,0,_exception);
3744 mask_image=DestroyImage(mask_image);
3745 }
3746 else {
3747 /* Set a blending mask for the composition. */
3748 (void) NegateImage(mask_image,MagickFalse,_exception);
cristy665e18f2012-05-17 12:39:54 +00003749 (void) SetImageMask(source_image,mask_image,_exception);
anthony7bcfe7f2012-03-30 14:01:22 +00003750 mask_image=DestroyImage(mask_image);
3751 }
anthony805a2d42011-09-25 08:25:12 +00003752 }
cristyfeb3e962012-03-29 17:25:55 +00003753 (void) CompositeImage(new_images,source_image,compose,clip_to_self,
3754 geometry.x,geometry.y,_exception);
anthony92c93bd2012-03-19 14:02:47 +00003755 (void) SetImageMask(new_images,(Image *) NULL,_exception);
anthony31f1bf72012-01-30 12:37:22 +00003756 source_image=DestroyImage(source_image);
anthony805a2d42011-09-25 08:25:12 +00003757 break;
3758 }
anthonyebb73a22012-03-22 14:25:52 +00003759 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003760 }
3761 case 'd':
3762 {
anthonyafa3dfc2012-03-03 11:31:30 +00003763 if (LocaleCompare("deconstruct",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003764 {
anthony464f1c42012-04-22 08:51:01 +00003765 CLIWandWarnReplaced("-layer CompareAny");
anthonyafa3dfc2012-03-03 11:31:30 +00003766 CLIListOperatorImages(cli_wand,"-layer","CompareAny",NULL);
anthony805a2d42011-09-25 08:25:12 +00003767 break;
3768 }
anthonyafa3dfc2012-03-03 11:31:30 +00003769 if (LocaleCompare("delete",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003770 {
anthonyafa3dfc2012-03-03 11:31:30 +00003771 if (IfNormalOp)
anthony92c93bd2012-03-19 14:02:47 +00003772 DeleteImages(&_images,arg1,_exception);
anthonyafa3dfc2012-03-03 11:31:30 +00003773 else
anthony92c93bd2012-03-19 14:02:47 +00003774 DeleteImages(&_images,"-1",_exception);
anthony805a2d42011-09-25 08:25:12 +00003775 break;
3776 }
anthonyafa3dfc2012-03-03 11:31:30 +00003777 if (LocaleCompare("duplicate",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003778 {
anthonyafa3dfc2012-03-03 11:31:30 +00003779 if (IfNormalOp)
anthony805a2d42011-09-25 08:25:12 +00003780 {
3781 const char
3782 *p;
3783
3784 size_t
3785 number_duplicates;
3786
anthony7bcfe7f2012-03-30 14:01:22 +00003787 if (IfMagickFalse(IsGeometry(arg1)))
anthonyebb73a22012-03-22 14:25:52 +00003788 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,
3789 arg1);
anthony31f1bf72012-01-30 12:37:22 +00003790 number_duplicates=(size_t) StringToLong(arg1);
3791 p=strchr(arg1,',');
anthony805a2d42011-09-25 08:25:12 +00003792 if (p == (const char *) NULL)
anthonyebb73a22012-03-22 14:25:52 +00003793 new_images=DuplicateImages(_images,number_duplicates,"-1",
3794 _exception);
anthony805a2d42011-09-25 08:25:12 +00003795 else
anthony92c93bd2012-03-19 14:02:47 +00003796 new_images=DuplicateImages(_images,number_duplicates,p,
3797 _exception);
anthony805a2d42011-09-25 08:25:12 +00003798 }
anthonyafa3dfc2012-03-03 11:31:30 +00003799 else
anthony92c93bd2012-03-19 14:02:47 +00003800 new_images=DuplicateImages(_images,1,"-1",_exception);
3801 AppendImageToList(&_images, new_images);
anthony36a8c2c2012-02-10 00:08:44 +00003802 new_images=(Image *)NULL;
anthony805a2d42011-09-25 08:25:12 +00003803 break;
3804 }
anthonyebb73a22012-03-22 14:25:52 +00003805 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003806 }
3807 case 'e':
3808 {
anthonyafa3dfc2012-03-03 11:31:30 +00003809 if (LocaleCompare("evaluate-sequence",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003810 {
anthony2a0ec8c2012-03-24 04:35:56 +00003811 parse = ParseCommandOption(MagickEvaluateOptions,MagickFalse,arg1);
3812 if ( parse < 0 )
3813 CLIWandExceptArgBreak(OptionError,"UnrecognizedEvaluateOperator",
3814 option,arg1);
3815 new_images=EvaluateImages(_images,(MagickEvaluateOperator)parse,
3816 _exception);
anthony805a2d42011-09-25 08:25:12 +00003817 break;
3818 }
anthonyebb73a22012-03-22 14:25:52 +00003819 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003820 }
3821 case 'f':
3822 {
anthonyafa3dfc2012-03-03 11:31:30 +00003823 if (LocaleCompare("fft",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003824 {
anthony92c93bd2012-03-19 14:02:47 +00003825 new_images=ForwardFourierTransformImage(_images,normal_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00003826 break;
3827 }
anthonyafa3dfc2012-03-03 11:31:30 +00003828 if (LocaleCompare("flatten",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003829 {
anthony319dac62012-03-06 04:12:44 +00003830 /* REDIRECTED to use -layers flatten instead */
anthony2e4501b2012-03-30 04:41:54 +00003831 CLIListOperatorImages(cli_wand,"-layers",option+1,NULL);
anthony805a2d42011-09-25 08:25:12 +00003832 break;
3833 }
anthonyafa3dfc2012-03-03 11:31:30 +00003834 if (LocaleCompare("fx",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003835 {
anthony92c93bd2012-03-19 14:02:47 +00003836 new_images=FxImage(_images,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00003837 break;
3838 }
anthonyebb73a22012-03-22 14:25:52 +00003839 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003840 }
3841 case 'h':
3842 {
anthonyafa3dfc2012-03-03 11:31:30 +00003843 if (LocaleCompare("hald-clut",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003844 {
anthony31f1bf72012-01-30 12:37:22 +00003845 /* FUTURE - make this a compose option (and thus layers compose )
anthony92c93bd2012-03-19 14:02:47 +00003846 or perhaps compose last image over all other _images.
anthony31f1bf72012-01-30 12:37:22 +00003847 */
anthony805a2d42011-09-25 08:25:12 +00003848 Image
anthony31f1bf72012-01-30 12:37:22 +00003849 *hald_image;
anthony805a2d42011-09-25 08:25:12 +00003850
anthony92c93bd2012-03-19 14:02:47 +00003851 new_images=RemoveFirstImageFromList(&_images);
3852 hald_image=RemoveLastImageFromList(&_images);
anthony805a2d42011-09-25 08:25:12 +00003853 if (hald_image == (Image *) NULL)
anthony31f1bf72012-01-30 12:37:22 +00003854 break;
anthony92c93bd2012-03-19 14:02:47 +00003855 (void) HaldClutImage(new_images,hald_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00003856 hald_image=DestroyImage(hald_image);
anthony805a2d42011-09-25 08:25:12 +00003857 break;
3858 }
anthonyebb73a22012-03-22 14:25:52 +00003859 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003860 }
3861 case 'i':
3862 {
anthonyafa3dfc2012-03-03 11:31:30 +00003863 if (LocaleCompare("ift",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003864 {
3865 Image
anthony805a2d42011-09-25 08:25:12 +00003866 *magnitude_image,
3867 *phase_image;
3868
anthony92c93bd2012-03-19 14:02:47 +00003869 magnitude_image=RemoveFirstImageFromList(&_images);
3870 phase_image=RemoveFirstImageFromList(&_images);
anthonye8f56492012-02-12 12:39:02 +00003871 /* FUTURE - produce Exception, rather than silent fail */
anthony31f1bf72012-01-30 12:37:22 +00003872 if (phase_image == (Image *) NULL)
3873 break;
3874 new_images=InverseFourierTransformImage(magnitude_image,phase_image,
anthony92c93bd2012-03-19 14:02:47 +00003875 normal_op,_exception);
anthony31f1bf72012-01-30 12:37:22 +00003876 magnitude_image=DestroyImage(magnitude_image);
3877 phase_image=DestroyImage(phase_image);
anthony805a2d42011-09-25 08:25:12 +00003878 break;
3879 }
anthonyafa3dfc2012-03-03 11:31:30 +00003880 if (LocaleCompare("insert",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003881 {
3882 Image
anthony31f1bf72012-01-30 12:37:22 +00003883 *insert_image,
3884 *index_image;
3885
3886 ssize_t
3887 index;
anthony805a2d42011-09-25 08:25:12 +00003888
anthony7bcfe7f2012-03-30 14:01:22 +00003889 if (IfNormalOp && IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00003890 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00003891 index=0;
anthony92c93bd2012-03-19 14:02:47 +00003892 insert_image=RemoveLastImageFromList(&_images);
anthonyafa3dfc2012-03-03 11:31:30 +00003893 if (IfNormalOp)
anthony31f1bf72012-01-30 12:37:22 +00003894 index=(ssize_t) StringToLong(arg1);
anthony43f425d2012-02-26 12:58:58 +00003895 index_image=insert_image;
anthony805a2d42011-09-25 08:25:12 +00003896 if (index == 0)
anthony92c93bd2012-03-19 14:02:47 +00003897 PrependImageToList(&_images,insert_image);
3898 else if (index == (ssize_t) GetImageListLength(_images))
3899 AppendImageToList(&_images,insert_image);
anthony805a2d42011-09-25 08:25:12 +00003900 else
anthony43f425d2012-02-26 12:58:58 +00003901 {
anthony92c93bd2012-03-19 14:02:47 +00003902 index_image=GetImageFromList(_images,index-1);
anthony43f425d2012-02-26 12:58:58 +00003903 if (index_image == (Image *) NULL)
anthonyfe1aa782012-03-24 13:43:04 +00003904 CLIWandExceptArgBreak(OptionError,"NoSuchImage",option,arg1);
anthony43f425d2012-02-26 12:58:58 +00003905 InsertImageInList(&index_image,insert_image);
3906 }
anthony92c93bd2012-03-19 14:02:47 +00003907 _images=GetFirstImageInList(index_image);
anthony805a2d42011-09-25 08:25:12 +00003908 break;
3909 }
anthonyebb73a22012-03-22 14:25:52 +00003910 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003911 }
3912 case 'l':
3913 {
anthonyafa3dfc2012-03-03 11:31:30 +00003914 if (LocaleCompare("layers",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003915 {
anthonyfe1aa782012-03-24 13:43:04 +00003916 parse=ParseCommandOption(MagickLayerOptions,MagickFalse,arg1);
3917 if ( parse < 0 )
3918 CLIWandExceptArgBreak(OptionError,"UnrecognizedLayerMethod",
3919 option,arg1);
3920 switch ((ImageLayerMethod) parse)
anthony805a2d42011-09-25 08:25:12 +00003921 {
3922 case CoalesceLayer:
3923 {
anthony92c93bd2012-03-19 14:02:47 +00003924 new_images=CoalesceImages(_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003925 break;
3926 }
3927 case CompareAnyLayer:
3928 case CompareClearLayer:
3929 case CompareOverlayLayer:
3930 default:
3931 {
anthonyfe1aa782012-03-24 13:43:04 +00003932 new_images=CompareImagesLayers(_images,(ImageLayerMethod) parse,
3933 _exception);
anthony805a2d42011-09-25 08:25:12 +00003934 break;
3935 }
3936 case MergeLayer:
3937 case FlattenLayer:
3938 case MosaicLayer:
3939 case TrimBoundsLayer:
3940 {
anthonyfe1aa782012-03-24 13:43:04 +00003941 new_images=MergeImageLayers(_images,(ImageLayerMethod) parse,
3942 _exception);
anthony805a2d42011-09-25 08:25:12 +00003943 break;
3944 }
3945 case DisposeLayer:
3946 {
anthony92c93bd2012-03-19 14:02:47 +00003947 new_images=DisposeImages(_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003948 break;
3949 }
3950 case OptimizeImageLayer:
3951 {
anthony92c93bd2012-03-19 14:02:47 +00003952 new_images=OptimizeImageLayers(_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003953 break;
3954 }
3955 case OptimizePlusLayer:
3956 {
anthony92c93bd2012-03-19 14:02:47 +00003957 new_images=OptimizePlusImageLayers(_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003958 break;
3959 }
3960 case OptimizeTransLayer:
3961 {
anthony92c93bd2012-03-19 14:02:47 +00003962 OptimizeImageTransparency(_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003963 break;
3964 }
3965 case RemoveDupsLayer:
3966 {
anthony92c93bd2012-03-19 14:02:47 +00003967 RemoveDuplicateLayers(&_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003968 break;
3969 }
3970 case RemoveZeroLayer:
3971 {
anthony92c93bd2012-03-19 14:02:47 +00003972 RemoveZeroDelayLayers(&_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003973 break;
3974 }
3975 case OptimizeLayer:
anthony31f1bf72012-01-30 12:37:22 +00003976 { /* General Purpose, GIF Animation Optimizer. */
anthony92c93bd2012-03-19 14:02:47 +00003977 new_images=CoalesceImages(_images,_exception);
anthony31f1bf72012-01-30 12:37:22 +00003978 if (new_images == (Image *) NULL)
3979 break;
anthony92c93bd2012-03-19 14:02:47 +00003980 _images=DestroyImageList(_images);
3981 _images=OptimizeImageLayers(new_images,_exception);
3982 if (_images == (Image *) NULL)
anthony31f1bf72012-01-30 12:37:22 +00003983 break;
3984 new_images=DestroyImageList(new_images);
anthony92c93bd2012-03-19 14:02:47 +00003985 OptimizeImageTransparency(_images,_exception);
3986 (void) RemapImages(_quantize_info,_images,(Image *) NULL,
3987 _exception);
anthony805a2d42011-09-25 08:25:12 +00003988 break;
3989 }
3990 case CompositeLayer:
3991 {
anthony805a2d42011-09-25 08:25:12 +00003992 Image
3993 *source;
3994
3995 RectangleInfo
3996 geometry;
3997
anthony31f1bf72012-01-30 12:37:22 +00003998 CompositeOperator
anthony5f867ae2011-10-09 10:28:34 +00003999 compose;
4000
4001 const char*
4002 value;
4003
anthony92c93bd2012-03-19 14:02:47 +00004004 value=GetImageOption(_image_info,"compose");
anthony31f1bf72012-01-30 12:37:22 +00004005 compose=OverCompositeOp; /* Default to Over */
anthony5f867ae2011-10-09 10:28:34 +00004006 if (value != (const char *) NULL)
4007 compose=(CompositeOperator) ParseCommandOption(
4008 MagickComposeOptions,MagickFalse,value);
anthony5f867ae2011-10-09 10:28:34 +00004009
anthony31f1bf72012-01-30 12:37:22 +00004010 /* Split image sequence at the first 'NULL:' image. */
anthony92c93bd2012-03-19 14:02:47 +00004011 source=_images;
anthony805a2d42011-09-25 08:25:12 +00004012 while (source != (Image *) NULL)
4013 {
4014 source=GetNextImageInList(source);
4015 if ((source != (Image *) NULL) &&
4016 (LocaleCompare(source->magick,"NULL") == 0))
4017 break;
4018 }
4019 if (source != (Image *) NULL)
4020 {
4021 if ((GetPreviousImageInList(source) == (Image *) NULL) ||
4022 (GetNextImageInList(source) == (Image *) NULL))
4023 source=(Image *) NULL;
4024 else
anthony31f1bf72012-01-30 12:37:22 +00004025 { /* Separate the two lists, junk the null: image. */
anthony805a2d42011-09-25 08:25:12 +00004026 source=SplitImageList(source->previous);
4027 DeleteImageFromList(&source);
4028 }
4029 }
4030 if (source == (Image *) NULL)
4031 {
anthony92c93bd2012-03-19 14:02:47 +00004032 (void) ThrowMagickException(_exception,GetMagickModule(),
anthony805a2d42011-09-25 08:25:12 +00004033 OptionError,"MissingNullSeparator","layers Composite");
anthony805a2d42011-09-25 08:25:12 +00004034 break;
4035 }
anthony31f1bf72012-01-30 12:37:22 +00004036 /* Adjust offset with gravity and virtual canvas. */
anthony92c93bd2012-03-19 14:02:47 +00004037 SetGeometry(_images,&geometry);
4038 (void) ParseAbsoluteGeometry(_images->geometry,&geometry);
anthony805a2d42011-09-25 08:25:12 +00004039 geometry.width=source->page.width != 0 ?
4040 source->page.width : source->columns;
4041 geometry.height=source->page.height != 0 ?
4042 source->page.height : source->rows;
anthony92c93bd2012-03-19 14:02:47 +00004043 GravityAdjustGeometry(_images->page.width != 0 ?
4044 _images->page.width : _images->columns,
4045 _images->page.height != 0 ? _images->page.height :
4046 _images->rows,_images->gravity,&geometry);
anthony5f867ae2011-10-09 10:28:34 +00004047
anthony31f1bf72012-01-30 12:37:22 +00004048 /* Compose the two image sequences together */
anthony92c93bd2012-03-19 14:02:47 +00004049 CompositeLayers(_images,compose,source,geometry.x,geometry.y,
4050 _exception);
anthony805a2d42011-09-25 08:25:12 +00004051 source=DestroyImageList(source);
4052 break;
4053 }
4054 }
anthony805a2d42011-09-25 08:25:12 +00004055 break;
4056 }
anthonyebb73a22012-03-22 14:25:52 +00004057 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00004058 }
4059 case 'm':
4060 {
anthonyafa3dfc2012-03-03 11:31:30 +00004061 if (LocaleCompare("map",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00004062 {
anthony464f1c42012-04-22 08:51:01 +00004063 CLIWandWarnReplaced("+remap");
anthony92c93bd2012-03-19 14:02:47 +00004064 (void) RemapImages(_quantize_info,_images,(Image *) NULL,_exception);
anthony805a2d42011-09-25 08:25:12 +00004065 break;
4066 }
anthonyafa3dfc2012-03-03 11:31:30 +00004067 if (LocaleCompare("morph",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00004068 {
4069 Image
4070 *morph_image;
4071
anthony7bcfe7f2012-03-30 14:01:22 +00004072 if (IfMagickFalse(IsGeometry(arg1)))
anthony7bc87992012-03-25 02:32:51 +00004073 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00004074 morph_image=MorphImages(_images,StringToUnsignedLong(arg1),
4075 _exception);
anthony805a2d42011-09-25 08:25:12 +00004076 if (morph_image == (Image *) NULL)
anthony31f1bf72012-01-30 12:37:22 +00004077 break;
anthony92c93bd2012-03-19 14:02:47 +00004078 _images=DestroyImageList(_images);
4079 _images=morph_image;
anthony805a2d42011-09-25 08:25:12 +00004080 break;
4081 }
anthonyafa3dfc2012-03-03 11:31:30 +00004082 if (LocaleCompare("mosaic",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00004083 {
anthony319dac62012-03-06 04:12:44 +00004084 /* REDIRECTED to use -layers mosaic instead */
anthony2e4501b2012-03-30 04:41:54 +00004085 CLIListOperatorImages(cli_wand,"-layers",option+1,NULL);
anthony805a2d42011-09-25 08:25:12 +00004086 break;
4087 }
anthonyebb73a22012-03-22 14:25:52 +00004088 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00004089 }
4090 case 'p':
4091 {
anthonyafa3dfc2012-03-03 11:31:30 +00004092 if (LocaleCompare("print",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00004093 {
anthony964d28e2012-05-17 23:39:46 +00004094 (void) FormatLocaleFile(stdout,"%s",arg1);
anthony24aa8822012-03-11 00:56:06 +00004095 break;
anthony805a2d42011-09-25 08:25:12 +00004096 }
anthonyafa3dfc2012-03-03 11:31:30 +00004097 if (LocaleCompare("process",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00004098 {
anthonyb1d483a2012-04-14 12:53:56 +00004099 /* FUTURE: better parsing using ScriptToken() from string ??? */
anthony805a2d42011-09-25 08:25:12 +00004100 char
4101 **arguments;
4102
4103 int
4104 j,
4105 number_arguments;
4106
anthony31f1bf72012-01-30 12:37:22 +00004107 arguments=StringToArgv(arg1,&number_arguments);
anthony805a2d42011-09-25 08:25:12 +00004108 if (arguments == (char **) NULL)
4109 break;
anthony31f1bf72012-01-30 12:37:22 +00004110 if (strchr(arguments[1],'=') != (char *) NULL)
anthony805a2d42011-09-25 08:25:12 +00004111 {
4112 char
4113 breaker,
4114 quote,
4115 *token;
4116
4117 const char
4118 *arguments;
4119
4120 int
4121 next,
4122 status;
4123
4124 size_t
4125 length;
4126
4127 TokenInfo
4128 *token_info;
4129
4130 /*
anthony24aa8822012-03-11 00:56:06 +00004131 Support old style syntax, filter="-option arg1".
anthony805a2d42011-09-25 08:25:12 +00004132 */
anthony31f1bf72012-01-30 12:37:22 +00004133 length=strlen(arg1);
anthony805a2d42011-09-25 08:25:12 +00004134 token=(char *) NULL;
4135 if (~length >= (MaxTextExtent-1))
4136 token=(char *) AcquireQuantumMemory(length+MaxTextExtent,
4137 sizeof(*token));
4138 if (token == (char *) NULL)
4139 break;
4140 next=0;
anthony31f1bf72012-01-30 12:37:22 +00004141 arguments=arg1;
anthony805a2d42011-09-25 08:25:12 +00004142 token_info=AcquireTokenInfo();
4143 status=Tokenizer(token_info,0,token,length,arguments,"","=",
4144 "\"",'\0',&breaker,&next,&quote);
4145 token_info=DestroyTokenInfo(token_info);
4146 if (status == 0)
4147 {
4148 const char
4149 *argv;
4150
4151 argv=(&(arguments[next]));
anthony92c93bd2012-03-19 14:02:47 +00004152 (void) InvokeDynamicImageFilter(token,&_images,1,&argv,
4153 _exception);
anthony805a2d42011-09-25 08:25:12 +00004154 }
4155 token=DestroyString(token);
4156 break;
4157 }
4158 (void) SubstituteString(&arguments[1],"-","");
anthony92c93bd2012-03-19 14:02:47 +00004159 (void) InvokeDynamicImageFilter(arguments[1],&_images,
4160 number_arguments-2,(const char **) arguments+2,_exception);
anthony805a2d42011-09-25 08:25:12 +00004161 for (j=0; j < number_arguments; j++)
4162 arguments[j]=DestroyString(arguments[j]);
4163 arguments=(char **) RelinquishMagickMemory(arguments);
4164 break;
4165 }
anthonyebb73a22012-03-22 14:25:52 +00004166 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00004167 }
4168 case 'r':
4169 {
anthonyafa3dfc2012-03-03 11:31:30 +00004170 if (LocaleCompare("remap",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00004171 {
anthony92c93bd2012-03-19 14:02:47 +00004172 (void) RemapImages(_quantize_info,_images,(Image *) NULL,_exception);
anthony31f1bf72012-01-30 12:37:22 +00004173 break;
4174 }
anthonyafa3dfc2012-03-03 11:31:30 +00004175 if (LocaleCompare("reverse",option+1) == 0)
anthony31f1bf72012-01-30 12:37:22 +00004176 {
anthony92c93bd2012-03-19 14:02:47 +00004177 ReverseImageList(&_images);
anthony805a2d42011-09-25 08:25:12 +00004178 break;
4179 }
anthonyebb73a22012-03-22 14:25:52 +00004180 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00004181 }
4182 case 's':
4183 {
anthonyafa3dfc2012-03-03 11:31:30 +00004184 if (LocaleCompare("smush",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00004185 {
anthonycd358fc2012-04-16 13:59:03 +00004186 /* FUTURE: this option needs more work to make better */
anthony805a2d42011-09-25 08:25:12 +00004187 ssize_t
4188 offset;
4189
anthony7bcfe7f2012-03-30 14:01:22 +00004190 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00004191 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony31f1bf72012-01-30 12:37:22 +00004192 offset=(ssize_t) StringToLong(arg1);
anthonycd358fc2012-04-16 13:59:03 +00004193 new_images=SmushImages(_images,normal_op,offset,_exception);
4194 break;
4195 }
4196 if (LocaleCompare("subimage",option+1) == 0)
4197 {
4198 Image
4199 *base_image,
4200 *compare_image;
4201
4202 const char *
4203 value;
4204
4205 MetricType
4206 metric;
4207
4208 double
4209 similarity;
4210
4211 RectangleInfo
4212 offset;
4213
4214 base_image=GetImageFromList(_images,0);
4215 compare_image=GetImageFromList(_images,1);
4216
4217 /* Comparision Metric */
4218 metric=UndefinedMetric;
4219 value=GetImageOption(_image_info,"metric");
4220 if (value != (const char *) NULL)
4221 metric=(MetricType) ParseCommandOption(MagickMetricOptions,
4222 MagickFalse,value);
4223
4224 new_images=SimilarityImage(base_image,compare_image,metric,
4225 &offset,&similarity,_exception);
4226
4227 if ( new_images != (Image *)NULL ) {
4228 char
4229 result[MaxTextExtent];
4230
4231 (void) FormatLocaleString(result,MaxTextExtent,"%lf",similarity);
4232 (void) SetImageProperty(new_images,"subimage:similarity",result,
4233 _exception);
4234 (void) FormatLocaleString(result,MaxTextExtent,"%+ld",
4235 (long) offset.x);
4236 (void) SetImageProperty(new_images,"subimage:x",result,
4237 _exception);
4238 (void) FormatLocaleString(result,MaxTextExtent,"%+ld",
4239 (long) offset.y);
4240 (void) SetImageProperty(new_images,"subimage:y",result,
4241 _exception);
4242 (void) FormatLocaleString(result,MaxTextExtent,"%lux%lu%+ld%+ld",
4243 (unsigned long) offset.width,(unsigned long) offset.height,
4244 (long) offset.x,(long) offset.y);
4245 (void) SetImageProperty(new_images,"subimage:offset",result,
4246 _exception);
4247 }
anthony805a2d42011-09-25 08:25:12 +00004248 break;
4249 }
anthony0ea037a2012-04-03 12:14:39 +00004250 if (LocaleCompare("swap",option+1) == 0) {
4251 Image
4252 *p,
4253 *q,
4254 *swap;
anthony805a2d42011-09-25 08:25:12 +00004255
anthony0ea037a2012-04-03 12:14:39 +00004256 ssize_t
4257 index,
4258 swap_index;
anthony805a2d42011-09-25 08:25:12 +00004259
anthony0ea037a2012-04-03 12:14:39 +00004260 index=-1;
4261 swap_index=-2;
4262 if (IfNormalOp) {
4263 GeometryInfo
4264 geometry_info;
4265
4266 MagickStatusType
4267 flags;
4268
4269 swap_index=(-1);
anthony0ea037a2012-04-03 12:14:39 +00004270 flags=ParseGeometry(arg1,&geometry_info);
anthonyb1e21ed2012-04-20 12:43:12 +00004271 if ((flags & RhoValue) != 0)
4272 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony0ea037a2012-04-03 12:14:39 +00004273 index=(ssize_t) geometry_info.rho;
4274 if ((flags & SigmaValue) != 0)
4275 swap_index=(ssize_t) geometry_info.sigma;
anthony805a2d42011-09-25 08:25:12 +00004276 }
anthony0ea037a2012-04-03 12:14:39 +00004277 p=GetImageFromList(_images,index);
4278 q=GetImageFromList(_images,swap_index);
anthony8226e722012-04-05 14:25:46 +00004279 if ((p == (Image *) NULL) || (q == (Image *) NULL)) {
4280 if (IfNormalOp)
4281 CLIWandExceptArgBreak(OptionError,"InvalidImageIndex",option,arg1)
4282 else
4283 CLIWandExceptionBreak(OptionError,"TwoOrMoreImagesRequired",option);
4284 }
anthony0ea037a2012-04-03 12:14:39 +00004285 if (p == q)
anthony8226e722012-04-05 14:25:46 +00004286 CLIWandExceptArgBreak(OptionError,"InvalidImageIndex",option,arg1);
anthony0ea037a2012-04-03 12:14:39 +00004287 swap=CloneImage(p,0,0,MagickTrue,_exception);
4288 ReplaceImageInList(&p,CloneImage(q,0,0,MagickTrue,_exception));
4289 ReplaceImageInList(&q,swap);
4290 _images=GetFirstImageInList(q);
4291 break;
4292 }
anthonyebb73a22012-03-22 14:25:52 +00004293 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00004294 }
anthony805a2d42011-09-25 08:25:12 +00004295 default:
anthonyebb73a22012-03-22 14:25:52 +00004296 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00004297 }
anthony964d28e2012-05-17 23:39:46 +00004298
4299 /* clean up percent escape interpreted strings */
4300 if (arg1 != arg1n )
4301 arg1=DestroyString((char *)arg1);
4302 if (arg2 != arg2n )
4303 arg2=DestroyString((char *)arg2);
4304
4305 /* if new image list generated, replace existing image list */
anthony31f1bf72012-01-30 12:37:22 +00004306 if (new_images == (Image *) NULL)
4307 return;
anthony964d28e2012-05-17 23:39:46 +00004308 _images=DestroyImageList(_images);
anthony92c93bd2012-03-19 14:02:47 +00004309 _images=GetFirstImageInList(new_images);
anthony31f1bf72012-01-30 12:37:22 +00004310 return;
4311
anthony92c93bd2012-03-19 14:02:47 +00004312#undef _image_info
4313#undef _images
4314#undef _exception
4315#undef _draw_info
4316#undef _quantize_info
anthonyafa3dfc2012-03-03 11:31:30 +00004317#undef IfNormalOp
4318#undef IfPlusOp
anthony31f1bf72012-01-30 12:37:22 +00004319#undef normal_op
anthony805a2d42011-09-25 08:25:12 +00004320}
anthony43f425d2012-02-26 12:58:58 +00004321
4322/*
4323%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4324% %
4325% %
4326% %
anthony964d28e2012-05-17 23:39:46 +00004327+ 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 +00004328% %
4329% %
4330% %
4331%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4332%
anthony464f1c42012-04-22 08:51:01 +00004333% CLINoImageOperator() Applies operations that may not actually need images
anthony964d28e2012-05-17 23:39:46 +00004334% in an image list.
anthony43f425d2012-02-26 12:58:58 +00004335%
anthony4837ac22012-05-18 23:39:48 +00004336% The classic operators of this type is "-read", which actually creates
4337% images even when no images are present. Or image stack operators, which
4338% can be applied (push or pop) to an empty image list.
anthonyafa3dfc2012-03-03 11:31:30 +00004339%
anthony4837ac22012-05-18 23:39:48 +00004340% Note that these operators may involve other special 'option' prefix
4341% characters other than '-' or '+', namely parenthesis and braces.
anthony43f425d2012-02-26 12:58:58 +00004342%
anthony464f1c42012-04-22 08:51:01 +00004343% The format of the CLINoImageOption method is:
anthony43f425d2012-02-26 12:58:58 +00004344%
anthony464f1c42012-04-22 08:51:01 +00004345% void CLINoImageOption(MagickCLI *cli_wand,const char *option,
4346% const char *arg1, const char *arg2)
anthony43f425d2012-02-26 12:58:58 +00004347%
4348% A description of each parameter follows:
4349%
4350% o cli_wand: the main CLI Wand to use.
4351%
4352% o option: The special option (with any switch char) to process
4353%
anthony464f1c42012-04-22 08:51:01 +00004354% o arg1 & arg2: Argument for option, if required
4355% Currently arg2 is not used.
anthony43f425d2012-02-26 12:58:58 +00004356%
4357*/
anthony464f1c42012-04-22 08:51:01 +00004358WandExport void CLINoImageOperator(MagickCLI *cli_wand,
4359 const char *option, const char *arg1, const char *magick_unused(arg2))
anthony43f425d2012-02-26 12:58:58 +00004360{
anthony4837ac22012-05-18 23:39:48 +00004361#if 0
4362 const char /* For percent escape interpretImageProperties() */
4363 *arg1,
4364 *arg2;
4365#endif
4366
anthony8226e722012-04-05 14:25:46 +00004367#define _image_info (cli_wand->wand.image_info)
4368#define _images (cli_wand->wand.images)
4369#define _exception (cli_wand->wand.exception)
4370#define IfNormalOp (*option=='-')
4371#define IfPlusOp (*option!='-')
anthony43f425d2012-02-26 12:58:58 +00004372
4373 assert(cli_wand != (MagickCLI *) NULL);
4374 assert(cli_wand->signature == WandSignature);
4375 assert(cli_wand->wand.signature == WandSignature);
anthony7bcfe7f2012-03-30 14:01:22 +00004376 if (IfMagickTrue(cli_wand->wand.debug))
anthony43f425d2012-02-26 12:58:58 +00004377 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
4378
anthonyde897b72012-04-27 00:16:17 +00004379#if 0
anthony4837ac22012-05-18 23:39:48 +00004380 Not able to be used as their may not be any images!
4381 Also the only option that may have arguments that can be percent escaped is
4382 "-clone".
anthony52bef752012-03-27 13:54:47 +00004383
anthony4837ac22012-05-18 23:39:48 +00004384#define _process_flags (cli_wand->process_flags)
4385#define _option_type ((CommandOptionFlags) cli_wand->command->flags)
4386 /* Interpret Percent Escapes in Arguments - using first image */
4387 arg1 = arg1n;
4388 arg2 = arg2n;
4389 if ( (((_process_flags & ProcessInterpretProperities) != 0 )
4390 || ((_option_type & AlwaysInterpretArgsFlag) != 0)
4391 ) && ((_option_type & NeverInterpretArgsFlag) == 0) ) {
4392 /* Interpret Percent escapes in argument 1 */
4393 if (arg1n != (char *) NULL) {
4394 arg1=InterpretImageProperties(_image_info,_images,arg1n,_exception);
4395 if (arg1 == (char *) NULL) {
4396 CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
4397 arg1=arg1n; /* use the given argument as is */
4398 }
4399 }
4400 if (arg2n != (char *) NULL) {
4401 arg2=InterpretImageProperties(_image_info,_images,arg2n,_exception);
4402 if (arg2 == (char *) NULL) {
4403 CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
4404 arg2=arg2n; /* use the given argument as is */
4405 }
4406 }
4407 }
4408#undef _process_flags
4409#undef _option_type
anthonyde897b72012-04-27 00:16:17 +00004410#endif
anthony4837ac22012-05-18 23:39:48 +00004411
4412 do { /* break to exit code */
4413 /*
4414 No-op options (ignore these)
4415 */
4416 if (LocaleCompare("noop",option+1) == 0) /* no argument */
4417 break;
4418 if (LocaleCompare("sans",option+1) == 0) /* one argument */
4419 break;
4420 if (LocaleCompare("sans0",option+1) == 0) /* no argument */
4421 break;
4422 if (LocaleCompare("sans2",option+1) == 0) /* two arguments */
4423 break;
4424 /*
4425 Image Reading
4426 */
4427 if ( ( LocaleCompare("read",option+1) == 0 ) ||
4428 ( LocaleCompare("--",option) == 0 ) ) {
4429 /* Do Glob filename Expansion for 'arg1' then read all images.
4430 *
4431 * Expansion handles '@', '~', '*', and '?' meta-characters while ignoring
4432 * (but attaching to the filenames in the generated argument list) any
4433 * [...] read modifiers that may be present.
4434 *
4435 * For example: It will expand '*.gif[20x20]' into a list such as
4436 * 'abc.gif[20x20]', 'foobar.gif[20x20]', 'xyzzy.gif[20x20]'
4437 *
4438 * NOTE: In IMv6 this was done globally across all images. This
4439 * meant you could include IM options in '@filename' lists, but you
4440 * could not include comments. Doing it only for image read makes
4441 * it far more secure.
4442 *
4443 * Note: arguments do not have percent escapes expanded for security
4444 * reasons.
4445 */
4446 int argc;
4447 char **argv;
4448 ssize_t i;
4449
4450 argc = 1;
4451 argv = (char **) &arg1;
4452
4453 /* Expand 'glob' expressions in the given filename.
4454 Expansion handles any 'coder:' prefix, or read modifiers attached
4455 to the filename, including them in the resulting expanded list.
4456 */
4457 if (IfMagickFalse( ExpandFilenames(&argc,&argv) ))
4458 CLIWandExceptArgBreak(ResourceLimitError,"MemoryAllocationFailed",
4459 option,GetExceptionMessage(errno));
4460
4461 /* loop over expanded filename list, and read then all in */
4462 for (i=0; i<argc; i++) {
4463 Image *
4464 new_images;
4465 if (IfMagickTrue(_image_info->ping))
4466 new_images=PingImages(_image_info,argv[i],_exception);
4467 else
4468 new_images=ReadImages(_image_info,argv[i],_exception);
4469 AppendImageToList(&_images, new_images);
4470 }
4471 argv=DestroyStringList(argv); /* Destroy the Expanded Filename list */
4472 break;
4473 }
4474 /*
4475 Image Writing
4476 Note: Writing a empty image list is valid in specific cases
4477 */
4478 if (LocaleCompare("write",option+1) == 0) {
4479 /* Note: arguments do not have percent escapes expanded */
4480 char
4481 key[MaxTextExtent];
4482
4483 Image
4484 *write_images;
4485
4486 ImageInfo
4487 *write_info;
4488
4489 /* Need images, unless a "null:" output coder is used */
4490 if ( cli_wand->wand.images == (Image *) NULL ) {
4491 if ( LocaleCompare(arg1,"null:") == 0 )
4492 break;
4493 CLIWandExceptArgBreak(OptionError,"NoImagesForWrite",option,arg1);
4494 }
4495
4496 (void) FormatLocaleString(key,MaxTextExtent,"cache:%s",arg1);
4497 (void) DeleteImageRegistry(key);
4498 write_images=_images;
4499 if (IfPlusOp)
4500 write_images=CloneImageList(_images,_exception);
4501 write_info=CloneImageInfo(_image_info);
4502 (void) WriteImages(write_info,write_images,arg1,_exception);
4503 write_info=DestroyImageInfo(write_info);
4504 if (IfPlusOp)
4505 write_images=DestroyImageList(write_images);
4506 break;
4507 }
4508 /*
4509 Parenthesis and Brace operations
4510 */
4511 if (LocaleCompare("(",option) == 0) {
4512 /* stack 'push' images */
4513 Stack
4514 *node;
4515
4516 size_t
4517 size;
4518
4519 size=0;
4520 node=cli_wand->image_list_stack;
4521 for ( ; node != (Stack *)NULL; node=node->next)
4522 size++;
4523 if ( size >= MAX_STACK_DEPTH )
4524 CLIWandExceptionBreak(OptionError,"ParenthesisNestedTooDeeply",option);
4525 node=(Stack *) AcquireMagickMemory(sizeof(*node));
4526 if (node == (Stack *) NULL)
4527 CLIWandExceptionBreak(ResourceLimitFatalError,
4528 "MemoryAllocationFailed",option);
4529 node->data = (void *)cli_wand->wand.images;
4530 cli_wand->wand.images = NewImageList();
4531 node->next = cli_wand->image_list_stack;
4532 cli_wand->image_list_stack = node;
4533
4534 /* handle respect-parenthesis */
4535 if (IfMagickTrue(IsStringTrue(GetImageOption(cli_wand->wand.image_info,
4536 "respect-parenthesis"))))
4537 option="{"; /* fall-thru so as to push image settings too */
anthony52bef752012-03-27 13:54:47 +00004538 else
anthony4837ac22012-05-18 23:39:48 +00004539 break;
4540 /* fall thru to next if */
anthony52bef752012-03-27 13:54:47 +00004541 }
anthony4837ac22012-05-18 23:39:48 +00004542 if (LocaleCompare("{",option) == 0) {
4543 /* stack 'push' of image_info settings */
4544 Stack
4545 *node;
anthony8226e722012-04-05 14:25:46 +00004546
anthony4837ac22012-05-18 23:39:48 +00004547 size_t
4548 size;
anthony8226e722012-04-05 14:25:46 +00004549
anthony4837ac22012-05-18 23:39:48 +00004550 size=0;
4551 node=cli_wand->image_info_stack;
4552 for ( ; node != (Stack *)NULL; node=node->next)
4553 size++;
4554 if ( size >= MAX_STACK_DEPTH )
4555 CLIWandExceptionBreak(OptionError,"CurlyBracesNestedTooDeeply",option);
4556 node=(Stack *) AcquireMagickMemory(sizeof(*node));
4557 if (node == (Stack *) NULL)
4558 CLIWandExceptionBreak(ResourceLimitFatalError,
4559 "MemoryAllocationFailed",option);
anthony8226e722012-04-05 14:25:46 +00004560
anthony4837ac22012-05-18 23:39:48 +00004561 node->data = (void *)cli_wand->wand.image_info;
4562 cli_wand->wand.image_info = CloneImageInfo(cli_wand->wand.image_info);
4563 if (cli_wand->wand.image_info == (ImageInfo *)NULL) {
4564 CLIWandException(ResourceLimitFatalError,"MemoryAllocationFailed",
4565 option);
4566 cli_wand->wand.image_info = (ImageInfo *)node->data;
4567 node = (Stack *)RelinquishMagickMemory(node);
4568 break;
4569 }
4570
4571 node->next = cli_wand->image_info_stack;
4572 cli_wand->image_info_stack = node;
4573
4574 break;
anthony8226e722012-04-05 14:25:46 +00004575 }
anthony4837ac22012-05-18 23:39:48 +00004576 if (LocaleCompare(")",option) == 0) {
4577 /* pop images from stack */
4578 Stack
4579 *node;
anthony8226e722012-04-05 14:25:46 +00004580
anthony4837ac22012-05-18 23:39:48 +00004581 node = (Stack *)cli_wand->image_list_stack;
4582 if ( node == (Stack *)NULL)
4583 CLIWandExceptionBreak(OptionError,"UnbalancedParenthesis",option);
4584 cli_wand->image_list_stack = node->next;
anthony43f425d2012-02-26 12:58:58 +00004585
anthony4837ac22012-05-18 23:39:48 +00004586 AppendImageToList((Image **)&node->data,cli_wand->wand.images);
4587 cli_wand->wand.images= (Image *)node->data;
4588 node = (Stack *)RelinquishMagickMemory(node);
anthony43f425d2012-02-26 12:58:58 +00004589
anthony4837ac22012-05-18 23:39:48 +00004590 /* handle respect-parenthesis - of the previous 'pushed' settings */
4591 node = cli_wand->image_info_stack;
4592 if ( node != (Stack *)NULL)
4593 {
4594 if (IfMagickTrue(IsStringTrue(GetImageOption(
4595 cli_wand->wand.image_info,"respect-parenthesis"))))
4596 option="}"; /* fall-thru so as to pop image settings too */
4597 else
4598 break;
4599 }
4600 else
4601 break;
4602 /* fall thru to next if */
4603 }
4604 if (LocaleCompare("}",option) == 0) {
4605 /* pop image_info settings from stack */
4606 Stack
4607 *node;
anthony43f425d2012-02-26 12:58:58 +00004608
anthony4837ac22012-05-18 23:39:48 +00004609 node = (Stack *)cli_wand->image_info_stack;
4610 if ( node == (Stack *)NULL)
4611 CLIWandExceptionBreak(OptionError,"UnbalancedCurlyBraces",option);
4612 cli_wand->image_info_stack = node->next;
anthony43f425d2012-02-26 12:58:58 +00004613
anthony4837ac22012-05-18 23:39:48 +00004614 (void) DestroyImageInfo(cli_wand->wand.image_info);
anthony43f425d2012-02-26 12:58:58 +00004615 cli_wand->wand.image_info = (ImageInfo *)node->data;
4616 node = (Stack *)RelinquishMagickMemory(node);
anthony4837ac22012-05-18 23:39:48 +00004617
4618 GetDrawInfo(cli_wand->wand.image_info, cli_wand->draw_info);
4619 cli_wand->quantize_info=DestroyQuantizeInfo(cli_wand->quantize_info);
4620 cli_wand->quantize_info=AcquireQuantizeInfo(cli_wand->wand.image_info);
4621
4622 break;
4623 }
4624 if (LocaleCompare("clone",option+1) == 0) {
4625 Image
4626 *new_images;
4627
4628 if (*option == '+')
4629 arg1="-1";
4630 if (IfMagickFalse(IsSceneGeometry(arg1,MagickFalse)))
4631 CLIWandExceptionBreak(OptionError,"InvalidArgument",option);
4632 if ( cli_wand->image_list_stack == (Stack *)NULL)
4633 CLIWandExceptionBreak(OptionError,"UnableToCloneImage",option);
4634 new_images = (Image *)cli_wand->image_list_stack->data;
4635 if (new_images == (Image *) NULL)
4636 CLIWandExceptionBreak(OptionError,"UnableToCloneImage",option);
4637 new_images=CloneImages(new_images,arg1,_exception);
4638 if (new_images == (Image *) NULL)
4639 CLIWandExceptionBreak(OptionError,"NoSuchImage",option);
4640 AppendImageToList(&_images,new_images);
4641 break;
4642 }
4643 /*
4644 Informational Operations
4645
4646 Note that these do not require either cli-wand or images!
4647 */
4648 if (LocaleCompare("version",option+1) == 0) {
4649 (void) FormatLocaleFile(stdout,"Version: %s\n",
4650 GetMagickVersion((size_t *) NULL));
4651 (void) FormatLocaleFile(stdout,"Copyright: %s\n",
4652 GetMagickCopyright());
4653 (void) FormatLocaleFile(stdout,"Features: %s\n\n",
4654 GetMagickFeatures());
4655 break;
4656 }
4657 if (LocaleCompare("list",option+1) == 0) {
4658 /*
4659 FUTURE: This 'switch' should really be built into the MagickCore
4660 */
4661 ssize_t
4662 list;
4663
4664 list=ParseCommandOption(MagickListOptions,MagickFalse,arg1);
4665 if ( list < 0 ) {
4666 CLIWandExceptionArg(OptionError,"UnrecognizedListType",option,arg1);
4667 break;
4668 }
4669 switch (list)
4670 {
4671 case MagickCoderOptions:
4672 {
4673 (void) ListCoderInfo((FILE *) NULL,_exception);
4674 break;
4675 }
4676 case MagickColorOptions:
4677 {
4678 (void) ListColorInfo((FILE *) NULL,_exception);
4679 break;
4680 }
4681 case MagickConfigureOptions:
4682 {
4683 (void) ListConfigureInfo((FILE *) NULL,_exception);
4684 break;
4685 }
4686 case MagickDelegateOptions:
4687 {
4688 (void) ListDelegateInfo((FILE *) NULL,_exception);
4689 break;
4690 }
4691 case MagickFontOptions:
4692 {
4693 (void) ListTypeInfo((FILE *) NULL,_exception);
4694 break;
4695 }
4696 case MagickFormatOptions:
4697 (void) ListMagickInfo((FILE *) NULL,_exception);
4698 break;
4699 case MagickLocaleOptions:
4700 (void) ListLocaleInfo((FILE *) NULL,_exception);
4701 break;
4702 case MagickLogOptions:
4703 (void) ListLogInfo((FILE *) NULL,_exception);
4704 break;
4705 case MagickMagicOptions:
4706 (void) ListMagicInfo((FILE *) NULL,_exception);
4707 break;
4708 case MagickMimeOptions:
4709 (void) ListMimeInfo((FILE *) NULL,_exception);
4710 break;
4711 case MagickModuleOptions:
4712 (void) ListModuleInfo((FILE *) NULL,_exception);
4713 break;
4714 case MagickPolicyOptions:
4715 (void) ListPolicyInfo((FILE *) NULL,_exception);
4716 break;
4717 case MagickResourceOptions:
4718 (void) ListMagickResourceInfo((FILE *) NULL,_exception);
4719 break;
4720 case MagickThresholdOptions:
4721 (void) ListThresholdMaps((FILE *) NULL,_exception);
4722 break;
4723 default:
4724 (void) ListCommandOptions((FILE *) NULL,(CommandOption) list,
4725 _exception);
4726 break;
4727 }
4728 break;
anthony43f425d2012-02-26 12:58:58 +00004729 }
anthony8226e722012-04-05 14:25:46 +00004730
anthony4837ac22012-05-18 23:39:48 +00004731 CLIWandException(OptionError,"UnrecognizedOption",option);
anthony8226e722012-04-05 14:25:46 +00004732
anthony4837ac22012-05-18 23:39:48 +00004733 } while (0); /* break to exit code. */
anthony43f425d2012-02-26 12:58:58 +00004734
4735#if 0
anthony4837ac22012-05-18 23:39:48 +00004736 /* clean up percent escape interpreted strings */
4737 if (arg1 != arg1n )
4738 arg1=DestroyString((char *)arg1);
4739 if (arg2 != arg2n )
4740 arg2=DestroyString((char *)arg2);
anthony43f425d2012-02-26 12:58:58 +00004741#endif
4742
anthony8226e722012-04-05 14:25:46 +00004743#undef _image_info
4744#undef _images
anthony92c93bd2012-03-19 14:02:47 +00004745#undef _exception
anthony8226e722012-04-05 14:25:46 +00004746#undef IfNormalOp
4747#undef IfPlusOp
anthony43f425d2012-02-26 12:58:58 +00004748}
anthony464f1c42012-04-22 08:51:01 +00004749
4750/*
4751%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4752% %
4753% %
4754% %
anthony964d28e2012-05-17 23:39:46 +00004755+ C L I O p t i o n %
anthony464f1c42012-04-22 08:51:01 +00004756% %
4757% %
4758% %
4759%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4760%
4761% CLIOption() Processes the given option using the given CLI Magick Wand.
anthony964d28e2012-05-17 23:39:46 +00004762% The option arguments can be variable in number, though at this time no more
4763% that two is actually used by any option (this may change). Excess options
4764% are simply ignored.
anthony464f1c42012-04-22 08:51:01 +00004765%
4766% If the cli_wand->command pointer is non-null, then it is assumed that the
4767% option has already been search for up from the CommandOptions[] table in
anthony964d28e2012-05-17 23:39:46 +00004768% "MagickCore/options.c" using GetCommandOptionInfo(). If not set this
4769% routine will do the lookup instead. The pointer is reset afterward.
4770%
4771% This action allows the caller to lookup and pre-handle any 'special'
4772% options, (such as implicit reads) before calling this general option
4773% handler to deal with 'standard' command line options.
anthony464f1c42012-04-22 08:51:01 +00004774%
4775% The format of the CLIOption method is:
4776%
4777% void CLIOption(MagickCLI *cli_wand,const char *option, ...)
4778%
4779% A description of each parameter follows:
4780%
4781% o cli_wand: the main CLI Wand to use.
4782%
4783% o option: The special option (with any switch char) to process
4784%
anthony964d28e2012-05-17 23:39:46 +00004785% o args: any required arguments for an option (variable number)
anthony464f1c42012-04-22 08:51:01 +00004786%
4787% Example Usage...
4788%
4789% CLIoption(cli_wand,"-read","rose:");
4790% CLIoption(cli_wand,"-virtual-pixel","transparent");
4791% CLIoption(cli_wand,"-distort","SRT:","30");
4792% CLIoption(cli_wand,"-write","rotated_rose.png");
4793%
4794*/
4795WandExport void CLIOption(MagickCLI *cli_wand,const char *option,...)
4796{
4797 const char
4798 *arg1,
4799 *arg2;
4800
4801 CommandOptionFlags
4802 option_type;
4803
4804 assert(cli_wand != (MagickCLI *) NULL);
4805 assert(cli_wand->signature == WandSignature);
4806 assert(cli_wand->wand.signature == WandSignature);
4807 if (IfMagickTrue(cli_wand->wand.debug))
4808 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
4809
anthony964d28e2012-05-17 23:39:46 +00004810 do { /* Break Code Block for error handling */
4811
4812 /* get information about option */
4813 if ( cli_wand->command == (const OptionInfo *) NULL )
4814 cli_wand->command = GetCommandOptionInfo(option);
anthony464f1c42012-04-22 08:51:01 +00004815#if 0
anthony964d28e2012-05-17 23:39:46 +00004816 (void) FormatLocaleFile(stderr, "CLIOption \"%s\" matched \"%s\"\n",
4817 option, cli_wand->command->mnemonic );
anthony464f1c42012-04-22 08:51:01 +00004818#endif
anthony964d28e2012-05-17 23:39:46 +00004819 option_type=(CommandOptionFlags) cli_wand->command->flags;
anthony464f1c42012-04-22 08:51:01 +00004820
anthony964d28e2012-05-17 23:39:46 +00004821 if ( option_type == UndefinedOptionFlag )
4822 CLIWandExceptionReturn(OptionFatalError,"UnrecognizedOption",option);
anthony464f1c42012-04-22 08:51:01 +00004823
anthony964d28e2012-05-17 23:39:46 +00004824 assert( LocaleCompare(cli_wand->command->mnemonic,option) == 0 );
anthony464f1c42012-04-22 08:51:01 +00004825
anthony964d28e2012-05-17 23:39:46 +00004826 /* depreciated options */
4827 if ( (option_type & DeprecateOptionFlag) != 0 )
4828 CLIWandExceptionBreak(OptionError,"DeprecatedOptionNoCode",option);
anthony464f1c42012-04-22 08:51:01 +00004829
anthony964d28e2012-05-17 23:39:46 +00004830 /* options that this module does not handle */
4831 if ((option_type & (SpecialOptionFlag|GenesisOptionFlag)) != 0 )
4832 CLIWandExceptionBreak(OptionFatalError,"InvalidUseOfOption",option);
anthony464f1c42012-04-22 08:51:01 +00004833
anthony964d28e2012-05-17 23:39:46 +00004834 /* Get argument strings from VarArgs
4835 How can you determine arguments is enough was supplied? */
4836 { size_t
4837 count = cli_wand->command->type;
anthony464f1c42012-04-22 08:51:01 +00004838
anthony964d28e2012-05-17 23:39:46 +00004839 va_list
4840 operands;
anthony464f1c42012-04-22 08:51:01 +00004841
anthony964d28e2012-05-17 23:39:46 +00004842 va_start(operands,option);
anthony464f1c42012-04-22 08:51:01 +00004843
anthony964d28e2012-05-17 23:39:46 +00004844 arg1=arg2=NULL;
4845 if ( count >= 1 )
4846 arg1=(const char *) va_arg(operands, const char *);
4847 if ( count >= 2 )
4848 arg2=(const char *) va_arg(operands, const char *);
anthony464f1c42012-04-22 08:51:01 +00004849
anthony964d28e2012-05-17 23:39:46 +00004850 va_end(operands);
anthony464f1c42012-04-22 08:51:01 +00004851
anthony52cb3df2012-04-24 03:29:32 +00004852#if 0
anthony964d28e2012-05-17 23:39:46 +00004853 (void) FormatLocaleFile(stderr,
4854 "CLIOption: \"%s\" Count: %ld Flags: %04x Args: \"%s\" \"%s\"\n",
4855 option,(long) count,option_type,arg1,arg2);
anthony464f1c42012-04-22 08:51:01 +00004856#endif
anthony964d28e2012-05-17 23:39:46 +00004857 }
4858
4859 /*
4860 Call the appropriate option handler
4861 */
4862
4863 /* FUTURE: this is temporary - get 'settings' to handle distribution of
4864 settings to images attributes,proprieties,artifacts */
4865 if ( cli_wand->wand.images != (Image *)NULL )
4866 SyncImagesSettings(cli_wand->wand.image_info,cli_wand->wand.images,
4867 cli_wand->wand.exception);
4868
4869 if ( (option_type & SettingOptionFlags) != 0 ) {
4870 CLISettingOptionInfo(cli_wand, option, arg1, arg2);
4871 // FUTURE: Sync Specific Settings into Image Properities (not global)
4872 }
4873
4874 /* Operators that do not need images - read, write, stack, clone */
4875 if ( (option_type & NoImageOperatorFlag) != 0)
4876 CLINoImageOperator(cli_wand, option, arg1, arg2);
4877
4878 /* FUTURE: The not a setting part below is a temporary hack due to
4879 * some options being both a Setting and a Simple operator.
4880 * Specifically -monitor, -depth, and -colorspace */
4881 if ( cli_wand->wand.images == (Image *)NULL )
4882 if ( ((option_type & (SimpleOperatorFlag|ListOperatorFlag)) != 0 ) &&
4883 ((option_type & SettingOptionFlags) == 0 )) /* temp hack */
4884 CLIWandExceptionBreak(OptionError,"NoImagesFound",option);
4885
4886 /* Operators work on single images, and needs a loop over the images */
4887 if ( (option_type & SimpleOperatorFlag) != 0)
4888 CLISimpleOperatorImages(cli_wand, option, arg1, arg2);
4889
4890 /* Operators that work on the image list as a whole */
4891 if ( (option_type & ListOperatorFlag) != 0 )
4892 CLIListOperatorImages(cli_wand, option, arg1, arg2);
4893
4894 } while (0); /* end Break code block */
anthony464f1c42012-04-22 08:51:01 +00004895
4896 cli_wand->command = (const OptionInfo *) NULL; /* prevent re-use later */
anthony464f1c42012-04-22 08:51:01 +00004897}