blob: 6e12e1421ff43b62d1d5a7edf1abefc2ba50186c [file] [log] [blame]
anthony805a2d42011-09-25 08:25:12 +00001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% %
anthony8b10b462012-02-08 12:32:44 +00006% OOO PPPP EEEE RRRR AA TTTTT III OOO N N %
7% O O P P E R R A A T I O O NN N %
8% O O PPPP EEE RRRR AAAA T I O O N N N %
9% O O P E R R A A T I O O N NN %
10% OOO P EEEE R RR A A T III OOO N N %
anthony805a2d42011-09-25 08:25:12 +000011% %
12% %
anthony8b10b462012-02-08 12:32:44 +000013% CLI Magick Option Methods %
anthony805a2d42011-09-25 08:25:12 +000014% %
anthony8b10b462012-02-08 12:32:44 +000015% Dragon Computing %
cristy9e58efd2012-01-30 14:27:34 +000016% Anthony Thyssen %
cristy0a0ca4f2011-09-28 01:15:28 +000017% September 2011 %
anthony805a2d42011-09-25 08:25:12 +000018% %
19% %
cristy1454be72011-12-19 01:52:48 +000020% Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization %
anthony805a2d42011-09-25 08:25:12 +000021% dedicated to making software imaging solutions freely available. %
22% %
23% You may not use this file except in compliance with the License. You may %
24% obtain a copy of the License at %
25% %
26% http://www.imagemagick.org/script/license.php %
27% %
28% Unless required by applicable law or agreed to in writing, software %
29% distributed under the License is distributed on an "AS IS" BASIS, %
30% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31% See the License for the specific language governing permissions and %
32% limitations under the License. %
33% %
34%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35%
36% Apply the given options (settings, and simple, or sequence operations) to
anthony8b10b462012-02-08 12:32:44 +000037% the given image(s) according to the current "image_info", "draw_info", and
38% "quantize_info" settings, stored in a special CLI Image Wand.
anthony805a2d42011-09-25 08:25:12 +000039%
40% The final goal is to allow the execution in a strict one option at a time
41% manner that is needed for 'pipelining and file scripting' of options in
42% IMv7.
43%
anthony8b10b462012-02-08 12:32:44 +000044% Anthony Thyssen, September 2011
anthony805a2d42011-09-25 08:25:12 +000045*/
46
47/*
48 Include declarations.
49*/
50#include "MagickWand/studio.h"
51#include "MagickWand/MagickWand.h"
anthony72feaa62012-01-17 06:46:23 +000052#include "MagickWand/magick-wand-private.h"
anthony43f425d2012-02-26 12:58:58 +000053#include "MagickWand/wand.h"
anthony756cd0d2012-04-08 12:41:44 +000054#include "MagickWand/wandcli.h"
55#include "MagickWand/wandcli-private.h"
56#include "MagickWand/operation.h"
anthony805a2d42011-09-25 08:25:12 +000057#include "MagickCore/monitor-private.h"
58#include "MagickCore/thread-private.h"
59#include "MagickCore/string-private.h"
60
61/*
62 Define declarations.
63*/
anthonyafa3dfc2012-03-03 11:31:30 +000064#define USE_WAND_METHODS 0
65#define MAX_STACK_DEPTH 32
66#define UNDEFINED_COMPRESSION_QUALITY 0UL
67
anthony805a2d42011-09-25 08:25:12 +000068/*
69 Constant declaration. (temporary exports)
70*/
71static const char
72 BackgroundColor[] = "#fff", /* white */
anthony72feaa62012-01-17 06:46:23 +000073 BorderColor[] = "#dfdfdf", /* sRGB gray */
74 MatteColor[] = "#bdbdbd"; /* slightly darker gray */
anthony805a2d42011-09-25 08:25:12 +000075
76/*
77** Function to report on the progress of image operations
78*/
79static MagickBooleanType MonitorProgress(const char *text,
80 const MagickOffsetType offset,const MagickSizeType extent,
anthony43f425d2012-02-26 12:58:58 +000081 void *wand_unused(cli_wandent_data))
anthony805a2d42011-09-25 08:25:12 +000082{
83 char
84 message[MaxTextExtent],
85 tag[MaxTextExtent];
86
87 const char
88 *locale_message;
89
90 register char
91 *p;
92
93 if (extent < 2)
94 return(MagickTrue);
95 (void) CopyMagickMemory(tag,text,MaxTextExtent);
96 p=strrchr(tag,'/');
97 if (p != (char *) NULL)
98 *p='\0';
99 (void) FormatLocaleString(message,MaxTextExtent,"Monitor/%s",tag);
100 locale_message=GetLocaleMessage(message);
101 if (locale_message == message)
102 locale_message=tag;
103 if (p == (char *) NULL)
104 (void) FormatLocaleFile(stderr,"%s: %ld of %lu, %02ld%% complete\r",
105 locale_message,(long) offset,(unsigned long) extent,(long)
106 (100L*offset/(extent-1)));
107 else
108 (void) FormatLocaleFile(stderr,"%s[%s]: %ld of %lu, %02ld%% complete\r",
109 locale_message,p+1,(long) offset,(unsigned long) extent,(long)
110 (100L*offset/(extent-1)));
111 if (offset == (MagickOffsetType) (extent-1))
112 (void) FormatLocaleFile(stderr,"\n");
113 (void) fflush(stderr);
114 return(MagickTrue);
115}
116
117/*
118** GetImageCache() will read an image into a image cache if not already
119** present then return the image that is in the cache under that filename.
120*/
121static inline Image *GetImageCache(const ImageInfo *image_info,const char *path,
122 ExceptionInfo *exception)
123{
124 char
125 key[MaxTextExtent];
126
127 ExceptionInfo
128 *sans_exception;
129
130 Image
131 *image;
132
133 ImageInfo
134 *read_info;
135
136 (void) FormatLocaleString(key,MaxTextExtent,"cache:%s",path);
137 sans_exception=AcquireExceptionInfo();
138 image=(Image *) GetImageRegistry(ImageRegistryType,key,sans_exception);
139 sans_exception=DestroyExceptionInfo(sans_exception);
140 if (image != (Image *) NULL)
141 return(image);
142 read_info=CloneImageInfo(image_info);
143 (void) CopyMagickString(read_info->filename,path,MaxTextExtent);
144 image=ReadImage(read_info,exception);
145 read_info=DestroyImageInfo(read_info);
146 if (image != (Image *) NULL)
147 (void) SetImageRegistry(ImageRegistryType,key,image,exception);
148 return(image);
149}
150
anthonye5fcd362012-04-09 04:02:09 +0000151#if 0
anthony805a2d42011-09-25 08:25:12 +0000152/*
anthony756cd0d2012-04-08 12:41:44 +0000153 FloatListOption() converts a string option of space or comma seperated
154 numbers into a list of floating point numbers, required by some operations.
155*/
156static MagickBooleanType FloatListOption(const char *option,
157 size_t *number_arguments, double **arguments, ExceptionInfo *exception)
158{
159 char
160 token[MaxTextExtent];
161
162 const char
163 *p;
164
165 MagickBooleanType
166 error;
167
168 register size_t
169 x;
170
171}
anthonye5fcd362012-04-09 04:02:09 +0000172#endif
anthony756cd0d2012-04-08 12:41:44 +0000173
174/*
anthonya89dd172011-10-04 13:29:35 +0000175 SparseColorOption() parse the complex -sparse-color argument into an
176 an array of floating point values than call SparseColorImage().
177 Argument is a complex mix of floating-point pixel coodinates, and color
178 specifications (or direct floating point numbers). The number of floats
179 needed to represent a color varies depending on teh current channel
180 setting.
anthony43f425d2012-02-26 12:58:58 +0000181
182 This really should be in MagickCore, so that other API's can make use of it.
anthony805a2d42011-09-25 08:25:12 +0000183*/
184static Image *SparseColorOption(const Image *image,
185 const SparseColorMethod method,const char *arguments,
anthony31f1bf72012-01-30 12:37:22 +0000186 ExceptionInfo *exception)
anthony805a2d42011-09-25 08:25:12 +0000187{
188 char
189 token[MaxTextExtent];
190
191 const char
192 *p;
193
194 double
195 *sparse_arguments;
196
197 Image
198 *sparse_image;
199
200 PixelInfo
201 color;
202
203 MagickBooleanType
204 error;
205
206 register size_t
207 x;
208
209 size_t
210 number_arguments,
211 number_colors;
212
213 assert(image != (Image *) NULL);
214 assert(image->signature == MagickSignature);
anthony7bcfe7f2012-03-30 14:01:22 +0000215 if (IfMagickTrue(image->debug))
anthony805a2d42011-09-25 08:25:12 +0000216 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
217 assert(exception != (ExceptionInfo *) NULL);
218 assert(exception->signature == MagickSignature);
219 /*
220 Limit channels according to image - and add up number of color channel.
221 */
222 number_colors=0;
223 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
224 number_colors++;
225 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
226 number_colors++;
227 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
228 number_colors++;
229 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
230 (image->colorspace == CMYKColorspace))
231 number_colors++;
232 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
anthony7bcfe7f2012-03-30 14:01:22 +0000233 IfMagickTrue(image->matte))
anthony805a2d42011-09-25 08:25:12 +0000234 number_colors++;
235
236 /*
237 Read string, to determine number of arguments needed,
238 */
239 p=arguments;
240 x=0;
241 while( *p != '\0' )
242 {
243 GetMagickToken(p,&p,token);
244 if ( token[0] == ',' ) continue;
anthony31f1bf72012-01-30 12:37:22 +0000245 if ( isalpha((int) token[0]) || token[0] == '#' )
246 x += number_colors; /* color argument found */
anthonyce8dcb32012-03-21 13:20:31 +0000247 else
anthony805a2d42011-09-25 08:25:12 +0000248 x++; /* floating point argument */
anthony805a2d42011-09-25 08:25:12 +0000249 }
anthony31f1bf72012-01-30 12:37:22 +0000250 /* control points and color values */
anthony7bcfe7f2012-03-30 14:01:22 +0000251 error = IsMagickTrue( x % (2+number_colors) );
anthony31f1bf72012-01-30 12:37:22 +0000252 number_arguments=x;
anthony7bcfe7f2012-03-30 14:01:22 +0000253 if ( IfMagickTrue(error) ) {
anthony805a2d42011-09-25 08:25:12 +0000254 (void) ThrowMagickException(exception,GetMagickModule(),
anthony43f425d2012-02-26 12:58:58 +0000255 OptionError, "InvalidArgument", "'%s': %s", "sparse-color",
anthony805a2d42011-09-25 08:25:12 +0000256 "Invalid number of Arguments");
257 return( (Image *)NULL);
258 }
259
260 /* Allocate and fill in the floating point arguments */
261 sparse_arguments=(double *) AcquireQuantumMemory(number_arguments,
262 sizeof(*sparse_arguments));
263 if (sparse_arguments == (double *) NULL) {
264 (void) ThrowMagickException(exception,GetMagickModule(),ResourceLimitError,
265 "MemoryAllocationFailed","%s","SparseColorOption");
266 return( (Image *)NULL);
267 }
268 (void) ResetMagickMemory(sparse_arguments,0,number_arguments*
269 sizeof(*sparse_arguments));
270 p=arguments;
271 x=0;
272 while( *p != '\0' && x < number_arguments ) {
273 /* X coordinate */
274 token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token);
275 if ( token[0] == '\0' ) break;
276 if ( isalpha((int) token[0]) || token[0] == '#' ) {
277 (void) ThrowMagickException(exception,GetMagickModule(),
anthony43f425d2012-02-26 12:58:58 +0000278 OptionError, "InvalidArgument", "'%s': %s", "sparse-color",
anthony805a2d42011-09-25 08:25:12 +0000279 "Color found, instead of X-coord");
280 error = MagickTrue;
281 break;
282 }
cristydbdd0e32011-11-04 23:29:40 +0000283 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +0000284 /* Y coordinate */
285 token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token);
286 if ( token[0] == '\0' ) break;
287 if ( isalpha((int) token[0]) || token[0] == '#' ) {
288 (void) ThrowMagickException(exception,GetMagickModule(),
anthony43f425d2012-02-26 12:58:58 +0000289 OptionError, "InvalidArgument", "'%s': %s", "sparse-color",
anthony805a2d42011-09-25 08:25:12 +0000290 "Color found, instead of Y-coord");
291 error = MagickTrue;
292 break;
293 }
cristydbdd0e32011-11-04 23:29:40 +0000294 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
anthony31f1bf72012-01-30 12:37:22 +0000295 /* color name or function given in string argument */
296 token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token);
297 if ( token[0] == '\0' ) break;
298 if ( isalpha((int) token[0]) || token[0] == '#' ) {
299 /* Color string given */
300 (void) QueryColorCompliance(token,AllCompliance,&color,
301 exception);
302 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
303 sparse_arguments[x++] = QuantumScale*color.red;
304 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
305 sparse_arguments[x++] = QuantumScale*color.green;
306 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
307 sparse_arguments[x++] = QuantumScale*color.blue;
308 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
309 (image->colorspace == CMYKColorspace))
310 sparse_arguments[x++] = QuantumScale*color.black;
311 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
anthony7bcfe7f2012-03-30 14:01:22 +0000312 IfMagickTrue(image->matte))
anthony31f1bf72012-01-30 12:37:22 +0000313 sparse_arguments[x++] = QuantumScale*color.alpha;
anthony805a2d42011-09-25 08:25:12 +0000314 }
anthony31f1bf72012-01-30 12:37:22 +0000315 else {
316 /* Colors given as a set of floating point values - experimental */
317 /* NB: token contains the first floating point value to use! */
318 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
319 {
320 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
321 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
322 break;
323 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
324 token[0] = ','; /* used this token - get another */
anthony805a2d42011-09-25 08:25:12 +0000325 }
anthony31f1bf72012-01-30 12:37:22 +0000326 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
327 {
328 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
329 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
330 break;
331 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
332 token[0] = ','; /* used this token - get another */
333 }
334 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
335 {
336 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
337 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
338 break;
339 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
340 token[0] = ','; /* used this token - get another */
341 }
342 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
343 (image->colorspace == CMYKColorspace))
344 {
345 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
346 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
347 break;
348 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
349 token[0] = ','; /* used this token - get another */
350 }
351 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
anthony7bcfe7f2012-03-30 14:01:22 +0000352 IfMagickTrue(image->matte))
anthony31f1bf72012-01-30 12:37:22 +0000353 {
354 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
355 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
356 break;
357 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
358 token[0] = ','; /* used this token - get another */
anthony805a2d42011-09-25 08:25:12 +0000359 }
360 }
361 }
362 if ( number_arguments != x && !error ) {
363 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
anthony43f425d2012-02-26 12:58:58 +0000364 "InvalidArgument","'%s': %s","sparse-color","Argument Parsing Error");
anthony805a2d42011-09-25 08:25:12 +0000365 sparse_arguments=(double *) RelinquishMagickMemory(sparse_arguments);
366 return( (Image *)NULL);
367 }
368 if ( error )
369 return( (Image *)NULL);
370
anthony31f1bf72012-01-30 12:37:22 +0000371 /* Call the Sparse Color Interpolation function with the parsed arguments */
anthony805a2d42011-09-25 08:25:12 +0000372 sparse_image=SparseColorImage(image,method,number_arguments,sparse_arguments,
373 exception);
374 sparse_arguments=(double *) RelinquishMagickMemory(sparse_arguments);
375 return( sparse_image );
376}
377
378/*
379%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
380% %
381% %
382% %
anthony43f425d2012-02-26 12:58:58 +0000383+ C L I S e t t i n g O p t i o n I n f o %
384% %
385% %
386% %
387%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
388%
389% CLISettingOptionInfo() applies a single settings option into a CLI wand
390% holding the image_info, draw_info, quantize_info structures that will be
391% used when processing the images.
392%
393% These options do no require images to be present in the CLI wand for them
394% to be able to be set, in which case they will generally be applied to image
395% that are read in later
anthony80c37752012-01-16 01:03:11 +0000396%
397% Options handled by this function are listed in CommandOptions[] of
anthonyfd706f92012-01-19 04:22:02 +0000398% "option.c" that is one of "SettingOptionFlags" option flags.
anthony805a2d42011-09-25 08:25:12 +0000399%
anthony2052d272012-02-28 12:48:29 +0000400% The format of the CLISettingOptionInfo method is:
anthony1afdc7a2011-10-05 11:54:28 +0000401%
anthonyafa3dfc2012-03-03 11:31:30 +0000402% 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%
405% A description of each parameter follows:
406%
anthony43f425d2012-02-26 12:58:58 +0000407% o cli_wand: structure holding settings to be applied
anthony805a2d42011-09-25 08:25:12 +0000408%
anthonydcf510d2011-10-30 13:51:40 +0000409% o option: The option string to be set
anthony805a2d42011-09-25 08:25:12 +0000410%
anthonye5fcd362012-04-09 04:02:09 +0000411% o arg1, arg2: optional argument strings to the operation
412% arg2 is currently only used by "-limit"
anthonydcf510d2011-10-30 13:51:40 +0000413%
anthony72feaa62012-01-17 06:46:23 +0000414% Example usage...
415%
anthonye5fcd362012-04-09 04:02:09 +0000416% CLISettingOptionInfo(cli_wand, "-background", "Red", NULL); // set value
417% CLISettingOptionInfo(cli_wand, "-adjoin", NULL, NULL); // set boolean
418% CLISettingOptionInfo(cli_wand, "+adjoin", NULL, NULL); // unset
anthony72feaa62012-01-17 06:46:23 +0000419%
anthony24aa8822012-03-11 00:56:06 +0000420% Or for handling command line arguments EG: +/-option ["arg1"]
anthonydcf510d2011-10-30 13:51:40 +0000421%
422% argc,argv
423% i=index in argv
424%
anthony2052d272012-02-28 12:48:29 +0000425% option_info = GetCommandOptionInfo(argv[i]);
426% count=option_info->type;
427% option_type=option_info->flags;
428%
429% if ( (option_type & SettingOperatorOptionFlags) != 0 )
anthonyafa3dfc2012-03-03 11:31:30 +0000430% CLISettingOptionInfo(cli_wand, argv[i],
anthonye5fcd362012-04-09 04:02:09 +0000431% (count>=1) ? argv[i+1] : (char *)NULL,
432% (count>=2) ? argv[i+2] : (char *)NULL);
anthonydcf510d2011-10-30 13:51:40 +0000433% i += count+1;
434%
anthony805a2d42011-09-25 08:25:12 +0000435*/
anthonyafa3dfc2012-03-03 11:31:30 +0000436WandExport void CLISettingOptionInfo(MagickCLI *cli_wand,
anthonye5fcd362012-04-09 04:02:09 +0000437 const char *option,const char *arg1, const char *arg2)
anthony805a2d42011-09-25 08:25:12 +0000438{
anthony30b912a2012-03-22 01:20:28 +0000439 ssize_t
440 parse; /* option argument parsing (string to value table lookup) */
441
anthony43f425d2012-02-26 12:58:58 +0000442 assert(cli_wand != (MagickCLI *) NULL);
443 assert(cli_wand->signature == WandSignature);
444 assert(cli_wand->wand.signature == WandSignature);
anthony7bcfe7f2012-03-30 14:01:22 +0000445 if (IfMagickTrue(cli_wand->wand.debug))
anthony43f425d2012-02-26 12:58:58 +0000446 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
anthony1afdc7a2011-10-05 11:54:28 +0000447
anthony2e4501b2012-03-30 04:41:54 +0000448#define _image_info (cli_wand->wand.image_info)
449#define _exception (cli_wand->wand.exception)
450#define _draw_info (cli_wand->draw_info)
451#define _quantize_info (cli_wand->quantize_info)
anthony24aa8822012-03-11 00:56:06 +0000452#define IfSetOption (*option=='-')
anthony7bcfe7f2012-03-30 14:01:22 +0000453#define ArgBoolean IsMagickTrue(IfSetOption)
454#define ArgBooleanNot IsMagickFalse(IfSetOption)
anthony24aa8822012-03-11 00:56:06 +0000455#define ArgBooleanString (IfSetOption?"true":"false")
456#define ArgOption(def) (IfSetOption?arg1:(const char *)(def))
anthony74b1cfc2011-10-06 12:44:16 +0000457
anthonyafa3dfc2012-03-03 11:31:30 +0000458 switch (*(option+1))
anthony805a2d42011-09-25 08:25:12 +0000459 {
460 case 'a':
461 {
anthonyafa3dfc2012-03-03 11:31:30 +0000462 if (LocaleCompare("adjoin",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000463 {
anthony92c93bd2012-03-19 14:02:47 +0000464 _image_info->adjoin = ArgBoolean;
anthony805a2d42011-09-25 08:25:12 +0000465 break;
466 }
anthonyafa3dfc2012-03-03 11:31:30 +0000467 if (LocaleCompare("affine",option+1) == 0)
anthony1afdc7a2011-10-05 11:54:28 +0000468 {
anthony975a8d72012-04-12 13:54:36 +0000469 CLIWandWarnDepreciated("-draw 'affine ...'");
anthony74b1cfc2011-10-06 12:44:16 +0000470 if (IfSetOption)
anthony92c93bd2012-03-19 14:02:47 +0000471 (void) ParseAffineGeometry(arg1,&_draw_info->affine,_exception);
anthony74b1cfc2011-10-06 12:44:16 +0000472 else
anthony92c93bd2012-03-19 14:02:47 +0000473 GetAffineMatrix(&_draw_info->affine);
anthony1afdc7a2011-10-05 11:54:28 +0000474 break;
475 }
anthonyafa3dfc2012-03-03 11:31:30 +0000476 if (LocaleCompare("antialias",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000477 {
anthony92c93bd2012-03-19 14:02:47 +0000478 _image_info->antialias =
479 _draw_info->stroke_antialias =
480 _draw_info->text_antialias = ArgBoolean;
anthony805a2d42011-09-25 08:25:12 +0000481 break;
482 }
anthony31f1bf72012-01-30 12:37:22 +0000483 if (LocaleCompare("attenuate",option+1) == 0)
484 {
anthony7bcfe7f2012-03-30 14:01:22 +0000485 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthony92c93bd2012-03-19 14:02:47 +0000486 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
487 (void) SetImageOption(_image_info,option+1,ArgOption("1.0"));
anthony31f1bf72012-01-30 12:37:22 +0000488 break;
489 }
anthonyafa3dfc2012-03-03 11:31:30 +0000490 if (LocaleCompare("authenticate",option+1) == 0)
anthonydcf510d2011-10-30 13:51:40 +0000491 {
anthony92c93bd2012-03-19 14:02:47 +0000492 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +0000493 break;
494 }
anthonyebb73a22012-03-22 14:25:52 +0000495 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +0000496 }
497 case 'b':
498 {
anthonyafa3dfc2012-03-03 11:31:30 +0000499 if (LocaleCompare("background",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000500 {
anthony92c93bd2012-03-19 14:02:47 +0000501 /* FUTURE: both _image_info attribute & ImageOption in use!
502 _image_info only used directly for generating new images.
anthony72feaa62012-01-17 06:46:23 +0000503 SyncImageSettings() used to set per-image attribute.
504
anthony92c93bd2012-03-19 14:02:47 +0000505 FUTURE: if _image_info->background_color is not set then
anthony30b912a2012-03-22 01:20:28 +0000506 we should fall back to per-image background_color
507
508 At this time -background will 'wipe out' the per-image
509 background color!
510
511 Better error handling of QueryColorCompliance() needed.
anthony74b1cfc2011-10-06 12:44:16 +0000512 */
anthony92c93bd2012-03-19 14:02:47 +0000513 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony72feaa62012-01-17 06:46:23 +0000514 (void) QueryColorCompliance(ArgOption(BackgroundColor),AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +0000515 &_image_info->background_color,_exception);
anthony805a2d42011-09-25 08:25:12 +0000516 break;
517 }
anthonyafa3dfc2012-03-03 11:31:30 +0000518 if (LocaleCompare("bias",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000519 {
anthony52bef752012-03-27 13:54:47 +0000520 /* FUTURE: bias OBSOLETED, replaced by Artifact "convolve:bias"
anthony31f1bf72012-01-30 12:37:22 +0000521 as it is actually rarely used except in direct convolve operations
522 Usage outside a direct convolve operation is actally non-sensible!
anthony72feaa62012-01-17 06:46:23 +0000523
524 SyncImageSettings() used to set per-image attribute.
anthony74b1cfc2011-10-06 12:44:16 +0000525 */
anthony7bcfe7f2012-03-30 14:01:22 +0000526 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthony5330ae02012-03-20 14:17:01 +0000527 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyf46d4262012-03-26 03:30:34 +0000528 (void) SetImageOption(_image_info,"convolve:bias",ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +0000529 break;
530 }
anthonyafa3dfc2012-03-03 11:31:30 +0000531 if (LocaleCompare("black-point-compensation",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000532 {
anthony72feaa62012-01-17 06:46:23 +0000533 /* Used as a image chromaticity setting
534 SyncImageSettings() used to set per-image attribute.
535 */
anthony92c93bd2012-03-19 14:02:47 +0000536 (void) SetImageOption(_image_info,option+1,ArgBooleanString);
anthony805a2d42011-09-25 08:25:12 +0000537 break;
538 }
anthonyafa3dfc2012-03-03 11:31:30 +0000539 if (LocaleCompare("blue-primary",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000540 {
anthonyafbaed72011-10-26 12:05:04 +0000541 /* Image chromaticity X,Y NB: Y=X if Y not defined
542 Used by many coders including PNG
anthony72feaa62012-01-17 06:46:23 +0000543 SyncImageSettings() used to set per-image attribute.
anthonyafbaed72011-10-26 12:05:04 +0000544 */
anthonyf42014d2012-03-25 09:53:06 +0000545 arg1=ArgOption("0.0");
anthony7bcfe7f2012-03-30 14:01:22 +0000546 if (IfMagickFalse(IsGeometry(arg1)))
anthony5330ae02012-03-20 14:17:01 +0000547 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyf42014d2012-03-25 09:53:06 +0000548 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000549 break;
550 }
anthonyafa3dfc2012-03-03 11:31:30 +0000551 if (LocaleCompare("bordercolor",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000552 {
anthony92c93bd2012-03-19 14:02:47 +0000553 /* FUTURE: both _image_info attribute & ImageOption in use!
anthony72feaa62012-01-17 06:46:23 +0000554 SyncImageSettings() used to set per-image attribute.
anthony30b912a2012-03-22 01:20:28 +0000555 Better error checking of QueryColorCompliance().
anthony72feaa62012-01-17 06:46:23 +0000556 */
anthony74b1cfc2011-10-06 12:44:16 +0000557 if (IfSetOption)
anthony805a2d42011-09-25 08:25:12 +0000558 {
anthony92c93bd2012-03-19 14:02:47 +0000559 (void) SetImageOption(_image_info,option+1,arg1);
anthony24aa8822012-03-11 00:56:06 +0000560 (void) QueryColorCompliance(arg1,AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +0000561 &_image_info->border_color,_exception);
anthony24aa8822012-03-11 00:56:06 +0000562 (void) QueryColorCompliance(arg1,AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +0000563 &_draw_info->border_color,_exception);
anthony805a2d42011-09-25 08:25:12 +0000564 break;
565 }
anthony92c93bd2012-03-19 14:02:47 +0000566 (void) DeleteImageOption(_image_info,option+1);
anthony74b1cfc2011-10-06 12:44:16 +0000567 (void) QueryColorCompliance(BorderColor,AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +0000568 &_image_info->border_color,_exception);
anthony74b1cfc2011-10-06 12:44:16 +0000569 (void) QueryColorCompliance(BorderColor,AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +0000570 &_draw_info->border_color,_exception);
anthony805a2d42011-09-25 08:25:12 +0000571 break;
572 }
anthonyafa3dfc2012-03-03 11:31:30 +0000573 if (LocaleCompare("box",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000574 {
anthony975a8d72012-04-12 13:54:36 +0000575 CLIWandWarnDepreciated("-undercolor");
576 CLISettingOptionInfo(cli_wand,"-undercolor",arg1, arg2);
anthonyfd706f92012-01-19 04:22:02 +0000577 break;
anthony805a2d42011-09-25 08:25:12 +0000578 }
anthonyebb73a22012-03-22 14:25:52 +0000579 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +0000580 }
581 case 'c':
582 {
anthonyafa3dfc2012-03-03 11:31:30 +0000583 if (LocaleCompare("cache",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000584 {
585 MagickSizeType
586 limit;
587
anthony7bcfe7f2012-03-30 14:01:22 +0000588 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthony5330ae02012-03-20 14:17:01 +0000589 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +0000590 limit=MagickResourceInfinity;
anthony24aa8822012-03-11 00:56:06 +0000591 if (LocaleCompare("unlimited",arg1) != 0)
592 limit=(MagickSizeType) SiPrefixToDoubleInterval(arg1,100.0);
anthony805a2d42011-09-25 08:25:12 +0000593 (void) SetMagickResourceLimit(MemoryResource,limit);
594 (void) SetMagickResourceLimit(MapResource,2*limit);
595 break;
596 }
anthonyafa3dfc2012-03-03 11:31:30 +0000597 if (LocaleCompare("caption",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000598 {
anthony92c93bd2012-03-19 14:02:47 +0000599 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +0000600 break;
601 }
anthonyafa3dfc2012-03-03 11:31:30 +0000602 if (LocaleCompare("channel",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000603 {
anthony30b912a2012-03-22 01:20:28 +0000604 arg1=ArgOption("default");
605 parse=ParseChannelOption(arg1);
606 if (parse < 0)
607 CLIWandExceptArgBreak(OptionError,"UnrecognizedChannelType",
608 option,arg1);
609 _image_info->channel=(ChannelType) parse;
610 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000611 break;
612 }
anthonyafa3dfc2012-03-03 11:31:30 +0000613 if (LocaleCompare("colorspace",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000614 {
anthonyafbaed72011-10-26 12:05:04 +0000615 /* Setting used for new images via AquireImage()
616 But also used as a SimpleImageOperator
617 Undefined colorspace means don't modify images on
618 read or as a operation */
anthony30b912a2012-03-22 01:20:28 +0000619 parse = ParseCommandOption(MagickColorspaceOptions,MagickFalse,
620 ArgOption("undefined"));
621 if (parse < 0)
anthony5330ae02012-03-20 14:17:01 +0000622 CLIWandExceptArgBreak(OptionError,"UnrecognizedColorspace",
623 option,arg1);
anthony30b912a2012-03-22 01:20:28 +0000624 _image_info->colorspace=(ColorspaceType) parse;
anthony805a2d42011-09-25 08:25:12 +0000625 break;
626 }
anthonyafa3dfc2012-03-03 11:31:30 +0000627 if (LocaleCompare("comment",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000628 {
anthony92c93bd2012-03-19 14:02:47 +0000629 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +0000630 break;
631 }
anthonyafa3dfc2012-03-03 11:31:30 +0000632 if (LocaleCompare("compose",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000633 {
anthony92c93bd2012-03-19 14:02:47 +0000634 /* FUTURE: _image_info should be used,
anthony72feaa62012-01-17 06:46:23 +0000635 SyncImageSettings() used to set per-image attribute. - REMOVE
636
anthonyafbaed72011-10-26 12:05:04 +0000637 This setting should NOT be used to set image 'compose'
anthony92c93bd2012-03-19 14:02:47 +0000638 "-layer" operators shoud use _image_info if defined otherwise
anthony72feaa62012-01-17 06:46:23 +0000639 they should use a per-image compose setting.
anthony965524b2011-10-07 12:34:14 +0000640 */
anthonyebb73a22012-03-22 14:25:52 +0000641 parse = ParseCommandOption(MagickComposeOptions,MagickFalse,
642 ArgOption("undefined"));
643 if (parse < 0)
644 CLIWandExceptArgBreak(OptionError,"UnrecognizedComposeOperator",
645 option,arg1);
646 _image_info->compose=(CompositeOperator) parse;
anthony92c93bd2012-03-19 14:02:47 +0000647 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +0000648 break;
649 }
anthonyafa3dfc2012-03-03 11:31:30 +0000650 if (LocaleCompare("compress",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000651 {
anthony92c93bd2012-03-19 14:02:47 +0000652 /* FUTURE: What should be used? _image_info or ImageOption ???
anthony5f867ae2011-10-09 10:28:34 +0000653 The former is more efficent, but Crisy prefers the latter!
anthony72feaa62012-01-17 06:46:23 +0000654 SyncImageSettings() used to set per-image attribute.
anthony5f867ae2011-10-09 10:28:34 +0000655
anthony92c93bd2012-03-19 14:02:47 +0000656 The coders appears to use _image_info, not Image_Option
anthony5f867ae2011-10-09 10:28:34 +0000657 however the image attribute (for save) is set from the
658 ImageOption!
anthony72feaa62012-01-17 06:46:23 +0000659
660 Note that "undefined" is a different setting to "none".
anthony5f867ae2011-10-09 10:28:34 +0000661 */
anthonyebb73a22012-03-22 14:25:52 +0000662 parse = ParseCommandOption(MagickCompressOptions,MagickFalse,
663 ArgOption("undefined"));
664 if (parse < 0)
665 CLIWandExceptArgBreak(OptionError,"UnrecognizedImageCompression",
666 option,arg1);
667 _image_info->compression=(CompressionType) parse;
anthony92c93bd2012-03-19 14:02:47 +0000668 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +0000669 break;
670 }
anthonyebb73a22012-03-22 14:25:52 +0000671 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +0000672 }
673 case 'd':
674 {
anthonyafa3dfc2012-03-03 11:31:30 +0000675 if (LocaleCompare("debug",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000676 {
anthony72feaa62012-01-17 06:46:23 +0000677 /* SyncImageSettings() used to set per-image attribute. */
anthonyebb73a22012-03-22 14:25:52 +0000678 arg1=ArgOption("none");
679 parse = ParseCommandOption(MagickLogEventOptions,MagickFalse,arg1);
680 if (parse < 0)
681 CLIWandExceptArgBreak(OptionError,"UnrecognizedEventType",
682 option,arg1);
683 (void) SetLogEventMask(arg1);
684 _image_info->debug=IsEventLogging(); /* extract logging*/
anthony43f425d2012-02-26 12:58:58 +0000685 cli_wand->wand.debug=IsEventLogging();
anthony805a2d42011-09-25 08:25:12 +0000686 break;
687 }
anthonyafa3dfc2012-03-03 11:31:30 +0000688 if (LocaleCompare("define",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000689 {
anthony24aa8822012-03-11 00:56:06 +0000690 if (LocaleNCompare(arg1,"registry:",9) == 0)
anthony805a2d42011-09-25 08:25:12 +0000691 {
anthony5f867ae2011-10-09 10:28:34 +0000692 if (IfSetOption)
anthony92c93bd2012-03-19 14:02:47 +0000693 (void) DefineImageRegistry(StringRegistryType,arg1+9,_exception);
anthony5f867ae2011-10-09 10:28:34 +0000694 else
anthony24aa8822012-03-11 00:56:06 +0000695 (void) DeleteImageRegistry(arg1+9);
anthony805a2d42011-09-25 08:25:12 +0000696 break;
697 }
anthony24aa8822012-03-11 00:56:06 +0000698 /* DefineImageOption() equals SetImageOption() but with '=' */
anthony5f867ae2011-10-09 10:28:34 +0000699 if (IfSetOption)
anthony92c93bd2012-03-19 14:02:47 +0000700 (void) DefineImageOption(_image_info,arg1);
anthony7bcfe7f2012-03-30 14:01:22 +0000701 else if (IsMagickFalse(DeleteImageOption(_image_info,arg1)))
anthonyebb73a22012-03-22 14:25:52 +0000702 CLIWandExceptArgBreak(OptionError,"NoSuchOption",option,arg1);
anthony805a2d42011-09-25 08:25:12 +0000703 break;
704 }
anthonyafa3dfc2012-03-03 11:31:30 +0000705 if (LocaleCompare("delay",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000706 {
anthonyafbaed72011-10-26 12:05:04 +0000707 /* Only used for new images via AcquireImage()
708 FUTURE: Option should also be used for "-morph" (color morphing)
anthony5f867ae2011-10-09 10:28:34 +0000709 */
anthonyebb73a22012-03-22 14:25:52 +0000710 arg1=ArgOption("0");
anthony7bcfe7f2012-03-30 14:01:22 +0000711 if (IfMagickFalse(IsGeometry(arg1)))
anthonyebb73a22012-03-22 14:25:52 +0000712 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
713 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000714 break;
715 }
anthonyafa3dfc2012-03-03 11:31:30 +0000716 if (LocaleCompare("density",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000717 {
anthony92c93bd2012-03-19 14:02:47 +0000718 /* FUTURE: strings used in _image_info attr and _draw_info!
anthony72feaa62012-01-17 06:46:23 +0000719 Basically as density can be in a XxY form!
720
721 SyncImageSettings() used to set per-image attribute.
722 */
anthony7bcfe7f2012-03-30 14:01:22 +0000723 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthonyebb73a22012-03-22 14:25:52 +0000724 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +0000725 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
726 (void) CloneString(&_image_info->density,ArgOption(NULL));
727 (void) CloneString(&_draw_info->density,_image_info->density);
anthony805a2d42011-09-25 08:25:12 +0000728 break;
729 }
anthonyafa3dfc2012-03-03 11:31:30 +0000730 if (LocaleCompare("depth",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000731 {
anthony72feaa62012-01-17 06:46:23 +0000732 /* This is also a SimpleImageOperator! for 8->16 vaule trunc !!!!
733 SyncImageSettings() used to set per-image attribute.
734 */
anthony7bcfe7f2012-03-30 14:01:22 +0000735 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthonyebb73a22012-03-22 14:25:52 +0000736 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +0000737 _image_info->depth=IfSetOption?StringToUnsignedLong(arg1)
anthony5f867ae2011-10-09 10:28:34 +0000738 :MAGICKCORE_QUANTUM_DEPTH;
anthony805a2d42011-09-25 08:25:12 +0000739 break;
740 }
anthonyafa3dfc2012-03-03 11:31:30 +0000741 if (LocaleCompare("direction",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000742 {
anthony92c93bd2012-03-19 14:02:47 +0000743 /* Image Option is only used to set _draw_info */
anthonyebb73a22012-03-22 14:25:52 +0000744 arg1=ArgOption("undefined");
745 parse = ParseCommandOption(MagickDirectionOptions,MagickFalse,arg1);
746 if (parse < 0)
747 CLIWandExceptArgBreak(OptionError,"UnrecognizedDirectionType",
748 option,arg1);
749 _draw_info->direction=(DirectionType) parse;
750 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000751 break;
752 }
anthonyafa3dfc2012-03-03 11:31:30 +0000753 if (LocaleCompare("display",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000754 {
anthony92c93bd2012-03-19 14:02:47 +0000755 (void) CloneString(&_image_info->server_name,ArgOption(NULL));
756 (void) CloneString(&_draw_info->server_name,_image_info->server_name);
anthony805a2d42011-09-25 08:25:12 +0000757 break;
758 }
anthonyafa3dfc2012-03-03 11:31:30 +0000759 if (LocaleCompare("dispose",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000760 {
anthony72feaa62012-01-17 06:46:23 +0000761 /* only used in setting new images */
anthonyebb73a22012-03-22 14:25:52 +0000762 arg1=ArgOption("undefined");
763 parse = ParseCommandOption(MagickDisposeOptions,MagickFalse,arg1);
764 if (parse < 0)
765 CLIWandExceptArgBreak(OptionError,"UnrecognizedDisposeMethod",
766 option,arg1);
anthony92c93bd2012-03-19 14:02:47 +0000767 (void) SetImageOption(_image_info,option+1,ArgOption("undefined"));
anthony805a2d42011-09-25 08:25:12 +0000768 break;
769 }
anthonyafa3dfc2012-03-03 11:31:30 +0000770 if (LocaleCompare("dither",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000771 {
anthony92c93bd2012-03-19 14:02:47 +0000772 /* _image_info attr (on/off), _quantize_info attr (on/off)
773 but also ImageInfo and _quantize_info method!
anthony72feaa62012-01-17 06:46:23 +0000774 FUTURE: merge the duality of the dithering options
775 */
anthony92c93bd2012-03-19 14:02:47 +0000776 _image_info->dither = _quantize_info->dither = ArgBoolean;
777 (void) SetImageOption(_image_info,option+1,ArgOption("none"));
778 _quantize_info->dither_method=(DitherMethod) ParseCommandOption(
anthony72feaa62012-01-17 06:46:23 +0000779 MagickDitherOptions,MagickFalse,ArgOption("none"));
anthony92c93bd2012-03-19 14:02:47 +0000780 if (_quantize_info->dither_method == NoDitherMethod)
781 _image_info->dither = _quantize_info->dither = MagickFalse;
anthony805a2d42011-09-25 08:25:12 +0000782 break;
783 }
anthonyebb73a22012-03-22 14:25:52 +0000784 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +0000785 }
786 case 'e':
787 {
anthonyafa3dfc2012-03-03 11:31:30 +0000788 if (LocaleCompare("encoding",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000789 {
anthony92c93bd2012-03-19 14:02:47 +0000790 (void) CloneString(&_draw_info->encoding,ArgOption("undefined"));
791 (void) SetImageOption(_image_info,option+1,_draw_info->encoding);
anthony805a2d42011-09-25 08:25:12 +0000792 break;
793 }
anthonyafa3dfc2012-03-03 11:31:30 +0000794 if (LocaleCompare("endian",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000795 {
anthony92c93bd2012-03-19 14:02:47 +0000796 /* Both _image_info attr and ImageInfo */
anthony2a0ec8c2012-03-24 04:35:56 +0000797 arg1 = ArgOption("undefined");
798 parse = ParseCommandOption(MagickEndianOptions,MagickFalse,arg1);
799 if (parse < 0)
800 CLIWandExceptArgBreak(OptionError,"UnrecognizedEndianType",
801 option,arg1);
anthonyf46d4262012-03-26 03:30:34 +0000802 /* FUTURE: check alloc/free of endian string! - remove? */
cristyaa2c16c2012-03-25 22:21:35 +0000803 _image_info->endian=(EndianType) (*arg1);
anthony2a0ec8c2012-03-24 04:35:56 +0000804 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000805 break;
806 }
anthonyafa3dfc2012-03-03 11:31:30 +0000807 if (LocaleCompare("extract",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000808 {
anthony92c93bd2012-03-19 14:02:47 +0000809 (void) CloneString(&_image_info->extract,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +0000810 break;
811 }
anthonyebb73a22012-03-22 14:25:52 +0000812 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +0000813 }
814 case 'f':
815 {
anthonyafa3dfc2012-03-03 11:31:30 +0000816 if (LocaleCompare("family",option+1) == 0)
anthony6dc09cd2011-10-12 08:56:49 +0000817 {
anthony92c93bd2012-03-19 14:02:47 +0000818 (void) CloneString(&_draw_info->family,ArgOption(NULL));
anthony6dc09cd2011-10-12 08:56:49 +0000819 break;
820 }
anthonyafa3dfc2012-03-03 11:31:30 +0000821 if (LocaleCompare("fill",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000822 {
anthony92c93bd2012-03-19 14:02:47 +0000823 /* Set "fill" OR "fill-pattern" in _draw_info
anthonyfd706f92012-01-19 04:22:02 +0000824 The original fill color is preserved if a fill-pattern is given.
825 That way it does not effect other operations that directly using
826 the fill color and, can be retored using "+tile".
anthonyafbaed72011-10-26 12:05:04 +0000827 */
anthony72feaa62012-01-17 06:46:23 +0000828 MagickBooleanType
829 status;
anthony6dc09cd2011-10-12 08:56:49 +0000830
831 ExceptionInfo
832 *sans;
833
anthonyfd706f92012-01-19 04:22:02 +0000834 PixelInfo
835 color;
836
anthony2a0ec8c2012-03-24 04:35:56 +0000837 arg1 = ArgOption("none"); /* +fill turns it off! */
838 (void) SetImageOption(_image_info,option+1,arg1);
anthony92c93bd2012-03-19 14:02:47 +0000839 if (_draw_info->fill_pattern != (Image *) NULL)
840 _draw_info->fill_pattern=DestroyImage(_draw_info->fill_pattern);
anthony72feaa62012-01-17 06:46:23 +0000841
842 /* is it a color or a image? -- ignore exceptions */
843 sans=AcquireExceptionInfo();
anthony2a0ec8c2012-03-24 04:35:56 +0000844 status=QueryColorCompliance(arg1,AllCompliance,&color,sans);
anthony72feaa62012-01-17 06:46:23 +0000845 sans=DestroyExceptionInfo(sans);
anthonyfd706f92012-01-19 04:22:02 +0000846
anthony7bcfe7f2012-03-30 14:01:22 +0000847 if (IfMagickFalse(status))
anthony2a0ec8c2012-03-24 04:35:56 +0000848 _draw_info->fill_pattern=GetImageCache(_image_info,arg1,_exception);
anthonyfd706f92012-01-19 04:22:02 +0000849 else
anthony92c93bd2012-03-19 14:02:47 +0000850 _draw_info->fill=color;
anthony805a2d42011-09-25 08:25:12 +0000851 break;
852 }
anthonyafa3dfc2012-03-03 11:31:30 +0000853 if (LocaleCompare("filter",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000854 {
anthony72feaa62012-01-17 06:46:23 +0000855 /* SyncImageSettings() used to set per-image attribute. */
anthony2a0ec8c2012-03-24 04:35:56 +0000856 arg1 = ArgOption("undefined");
857 parse = ParseCommandOption(MagickFilterOptions,MagickFalse,arg1);
858 if (parse < 0)
859 CLIWandExceptArgBreak(OptionError,"UnrecognizedImageFilter",
860 option,arg1);
861 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000862 break;
863 }
anthonyafa3dfc2012-03-03 11:31:30 +0000864 if (LocaleCompare("font",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000865 {
anthony92c93bd2012-03-19 14:02:47 +0000866 (void) CloneString(&_draw_info->font,ArgOption(NULL));
867 (void) CloneString(&_image_info->font,_draw_info->font);
anthony805a2d42011-09-25 08:25:12 +0000868 break;
869 }
anthonyafa3dfc2012-03-03 11:31:30 +0000870 if (LocaleCompare("format",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000871 {
anthonydcf510d2011-10-30 13:51:40 +0000872 /* FUTURE: why the ping test, you could set ping after this! */
873 /*
anthony805a2d42011-09-25 08:25:12 +0000874 register const char
875 *q;
876
anthony24aa8822012-03-11 00:56:06 +0000877 for (q=strchr(arg1,'%'); q != (char *) NULL; q=strchr(q+1,'%'))
anthony805a2d42011-09-25 08:25:12 +0000878 if (strchr("Agkrz@[#",*(q+1)) != (char *) NULL)
anthony92c93bd2012-03-19 14:02:47 +0000879 _image_info->ping=MagickFalse;
anthonydcf510d2011-10-30 13:51:40 +0000880 */
anthony92c93bd2012-03-19 14:02:47 +0000881 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +0000882 break;
883 }
anthonyafa3dfc2012-03-03 11:31:30 +0000884 if (LocaleCompare("fuzz",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000885 {
anthony72feaa62012-01-17 06:46:23 +0000886 /* Option used to set image fuzz! unless blank canvas (from color)
anthonydcf510d2011-10-30 13:51:40 +0000887 Image attribute used for color compare operations
anthony72feaa62012-01-17 06:46:23 +0000888 SyncImageSettings() used to set per-image attribute.
889
anthony2a0ec8c2012-03-24 04:35:56 +0000890 FUTURE: Can't find anything else using _image_info->fuzz directly!
891 remove direct sttribute from image_info
anthony6613bf32011-10-15 07:24:44 +0000892 */
anthony2a0ec8c2012-03-24 04:35:56 +0000893 arg1=ArgOption("0");
anthony7bcfe7f2012-03-30 14:01:22 +0000894 if (IfMagickFalse(IsGeometry(arg1)))
anthony2a0ec8c2012-03-24 04:35:56 +0000895 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
896 _image_info->fuzz=StringToDoubleInterval(arg1,(double)
anthony80c37752012-01-16 01:03:11 +0000897 QuantumRange+1.0);
anthony2a0ec8c2012-03-24 04:35:56 +0000898 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000899 break;
900 }
anthonyebb73a22012-03-22 14:25:52 +0000901 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +0000902 }
903 case 'g':
904 {
anthonyafa3dfc2012-03-03 11:31:30 +0000905 if (LocaleCompare("gravity",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000906 {
anthony72feaa62012-01-17 06:46:23 +0000907 /* SyncImageSettings() used to set per-image attribute. */
anthonyfe1aa782012-03-24 13:43:04 +0000908 arg1 = ArgOption("none");
909 parse = ParseCommandOption(MagickGravityOptions,MagickFalse,arg1);
910 if (parse < 0)
911 CLIWandExceptArgBreak(OptionError,"UnrecognizedGravityType",
912 option,arg1);
anthonyfe1aa782012-03-24 13:43:04 +0000913 _draw_info->gravity=(GravityType) parse;
anthonye8490972012-04-03 13:16:01 +0000914 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000915 break;
916 }
anthonyafa3dfc2012-03-03 11:31:30 +0000917 if (LocaleCompare("green-primary",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000918 {
anthonydcf510d2011-10-30 13:51:40 +0000919 /* Image chromaticity X,Y NB: Y=X if Y not defined
anthony72feaa62012-01-17 06:46:23 +0000920 SyncImageSettings() used to set per-image attribute.
921 Used directly by many coders
anthonydcf510d2011-10-30 13:51:40 +0000922 */
anthonyf42014d2012-03-25 09:53:06 +0000923 arg1=ArgOption("0.0");
anthony7bcfe7f2012-03-30 14:01:22 +0000924 if (IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +0000925 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyf42014d2012-03-25 09:53:06 +0000926 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000927 break;
928 }
anthonyebb73a22012-03-22 14:25:52 +0000929 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +0000930 }
931 case 'i':
932 {
anthonyafa3dfc2012-03-03 11:31:30 +0000933 if (LocaleCompare("intent",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000934 {
anthony72feaa62012-01-17 06:46:23 +0000935 /* Only used by coders: MIFF, MPC, BMP, PNG
anthonydcf510d2011-10-30 13:51:40 +0000936 and for image profile call to AcquireTransformThreadSet()
anthony72feaa62012-01-17 06:46:23 +0000937 SyncImageSettings() used to set per-image attribute.
anthonydcf510d2011-10-30 13:51:40 +0000938 */
anthonyfe1aa782012-03-24 13:43:04 +0000939 arg1 = ArgOption("indefined");
940 parse = ParseCommandOption(MagickIntentOptions,MagickFalse,arg1);
941 if (parse < 0)
942 CLIWandExceptArgBreak(OptionError,"UnrecognizedIntentType",
943 option,arg1);
944 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000945 break;
946 }
anthonyafa3dfc2012-03-03 11:31:30 +0000947 if (LocaleCompare("interlace",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000948 {
anthony92c93bd2012-03-19 14:02:47 +0000949 /* _image_info is directly used by coders (so why an image setting?)
anthony72feaa62012-01-17 06:46:23 +0000950 SyncImageSettings() used to set per-image attribute.
anthonydcf510d2011-10-30 13:51:40 +0000951 */
anthonyfe1aa782012-03-24 13:43:04 +0000952 arg1 = ArgOption("undefined");
953 parse = ParseCommandOption(MagickInterlaceOptions,MagickFalse,arg1);
954 if (parse < 0)
955 CLIWandExceptArgBreak(OptionError,"UnrecognizedInterlaceType",
956 option,arg1);
957 _image_info->interlace=(InterlaceType) parse;
958 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000959 break;
960 }
anthonyafa3dfc2012-03-03 11:31:30 +0000961 if (LocaleCompare("interline-spacing",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000962 {
anthony7bcfe7f2012-03-30 14:01:22 +0000963 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +0000964 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +0000965 (void) SetImageOption(_image_info,option+1, ArgOption(NULL));
966 _draw_info->interline_spacing=StringToDouble(ArgOption("0"),
anthony72feaa62012-01-17 06:46:23 +0000967 (char **) NULL);
anthony805a2d42011-09-25 08:25:12 +0000968 break;
969 }
anthonyafa3dfc2012-03-03 11:31:30 +0000970 if (LocaleCompare("interpolate",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000971 {
anthonyfd706f92012-01-19 04:22:02 +0000972 /* SyncImageSettings() used to set per-image attribute. */
anthonyfe1aa782012-03-24 13:43:04 +0000973 arg1 = ArgOption("undefined");
974 parse = ParseCommandOption(MagickInterpolateOptions,MagickFalse,arg1);
975 if (parse < 0)
976 CLIWandExceptArgBreak(OptionError,"UnrecognizedInterpolateMethod",
977 option,arg1);
978 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000979 break;
980 }
anthonyafa3dfc2012-03-03 11:31:30 +0000981 if (LocaleCompare("interword-spacing",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000982 {
anthony7bcfe7f2012-03-30 14:01:22 +0000983 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +0000984 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +0000985 (void) SetImageOption(_image_info,option+1, ArgOption(NULL));
986 _draw_info->interword_spacing=StringToDouble(ArgOption("0"),(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +0000987 break;
988 }
anthonyebb73a22012-03-22 14:25:52 +0000989 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +0000990 }
991 case 'k':
992 {
anthonyafa3dfc2012-03-03 11:31:30 +0000993 if (LocaleCompare("kerning",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000994 {
anthony7bcfe7f2012-03-30 14:01:22 +0000995 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +0000996 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +0000997 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
998 _draw_info->kerning=StringToDouble(ArgOption("0"),(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +0000999 break;
1000 }
anthonyebb73a22012-03-22 14:25:52 +00001001 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001002 }
1003 case 'l':
1004 {
anthonyafa3dfc2012-03-03 11:31:30 +00001005 if (LocaleCompare("label",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001006 {
anthony72feaa62012-01-17 06:46:23 +00001007 /* only used for new images - not in SyncImageOptions() */
anthony92c93bd2012-03-19 14:02:47 +00001008 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +00001009 break;
1010 }
anthony756cd0d2012-04-08 12:41:44 +00001011 if (LocaleCompare("limit",option+1) == 0)
1012 {
1013 MagickSizeType
1014 limit;
1015
1016 limit=MagickResourceInfinity;
1017 parse= ParseCommandOption(MagickResourceOptions,MagickFalse,arg1);
1018 if ( parse < 0 )
1019 CLIWandExceptArgBreak(OptionError,"UnrecognizedResourceType",
1020 option,arg1);
1021 if (LocaleCompare("unlimited",arg2) != 0)
1022 limit=(MagickSizeType) SiPrefixToDoubleInterval(arg2,100.0);
1023 (void) SetMagickResourceLimit((ResourceType)parse,limit);
1024 break;
1025 }
anthonyafa3dfc2012-03-03 11:31:30 +00001026 if (LocaleCompare("log",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001027 {
anthonyfe1aa782012-03-24 13:43:04 +00001028 if (IfSetOption) {
1029 if ((strchr(arg1,'%') == (char *) NULL))
1030 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony24aa8822012-03-11 00:56:06 +00001031 (void) SetLogFormat(arg1);
anthonyfe1aa782012-03-24 13:43:04 +00001032 }
anthony805a2d42011-09-25 08:25:12 +00001033 break;
1034 }
anthony975a8d72012-04-12 13:54:36 +00001035 if (LocaleCompare("lowlight-color",option+1) == 0)
1036 {
1037 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1038 break;
1039 }
anthonyafa3dfc2012-03-03 11:31:30 +00001040 if (LocaleCompare("loop",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001041 {
anthony72feaa62012-01-17 06:46:23 +00001042 /* SyncImageSettings() used to set per-image attribute. */
anthonyfe1aa782012-03-24 13:43:04 +00001043 arg1=ArgOption("0");
anthony7bcfe7f2012-03-30 14:01:22 +00001044 if (IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00001045 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1046 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +00001047 break;
1048 }
anthonyebb73a22012-03-22 14:25:52 +00001049 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001050 }
1051 case 'm':
1052 {
anthonyafa3dfc2012-03-03 11:31:30 +00001053 if (LocaleCompare("mattecolor",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001054 {
anthony72feaa62012-01-17 06:46:23 +00001055 /* SyncImageSettings() used to set per-image attribute. */
anthony92c93bd2012-03-19 14:02:47 +00001056 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony72feaa62012-01-17 06:46:23 +00001057 (void) QueryColorCompliance(ArgOption(MatteColor),AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +00001058 &_image_info->matte_color,_exception);
anthony805a2d42011-09-25 08:25:12 +00001059 break;
1060 }
anthonyafa3dfc2012-03-03 11:31:30 +00001061 if (LocaleCompare("monitor",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001062 {
anthony92c93bd2012-03-19 14:02:47 +00001063 (void) SetImageInfoProgressMonitor(_image_info, IfSetOption?
anthony31f1bf72012-01-30 12:37:22 +00001064 MonitorProgress: (MagickProgressMonitor) NULL, (void *) NULL);
anthony805a2d42011-09-25 08:25:12 +00001065 break;
1066 }
anthonyafa3dfc2012-03-03 11:31:30 +00001067 if (LocaleCompare("monochrome",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001068 {
anthony24aa8822012-03-11 00:56:06 +00001069 /* Setting (used by some input coders!) -- why?
1070 Warning: This is also Special '-type' SimpleOperator
anthony72feaa62012-01-17 06:46:23 +00001071 */
anthony92c93bd2012-03-19 14:02:47 +00001072 _image_info->monochrome= ArgBoolean;
anthony805a2d42011-09-25 08:25:12 +00001073 break;
1074 }
anthonyebb73a22012-03-22 14:25:52 +00001075 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001076 }
1077 case 'o':
1078 {
anthonyafa3dfc2012-03-03 11:31:30 +00001079 if (LocaleCompare("orient",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001080 {
anthony72feaa62012-01-17 06:46:23 +00001081 /* Is not used when defining for new images.
anthonydcf510d2011-10-30 13:51:40 +00001082 This makes it more of a 'operation' than a setting
anthony72feaa62012-01-17 06:46:23 +00001083 FUTURE: make set meta-data operator instead.
1084 SyncImageSettings() used to set per-image attribute.
anthonydcf510d2011-10-30 13:51:40 +00001085 */
anthony7bc87992012-03-25 02:32:51 +00001086 parse=ParseCommandOption(MagickOrientationOptions,MagickFalse,
1087 ArgOption("undefined"));
1088 if (parse < 0)
1089 CLIWandExceptArgBreak(OptionError,"UnrecognizedImageOrientation",
1090 option,arg1);
1091 _image_info->orientation=(OrientationType)parse;
anthony92c93bd2012-03-19 14:02:47 +00001092 (void) SetImageOption(_image_info,option+1, ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +00001093 break;
1094 }
anthonyebb73a22012-03-22 14:25:52 +00001095 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001096 }
1097 case 'p':
1098 {
anthonyafa3dfc2012-03-03 11:31:30 +00001099 if (LocaleCompare("page",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001100 {
anthony7bc87992012-03-25 02:32:51 +00001101 /* Only used for new images and image generators.
anthony72feaa62012-01-17 06:46:23 +00001102 SyncImageSettings() used to set per-image attribute. ?????
1103 That last is WRONG!!!!
anthony7bc87992012-03-25 02:32:51 +00001104 FUTURE: adjust named 'page' sizes according density
anthony72feaa62012-01-17 06:46:23 +00001105 */
anthony805a2d42011-09-25 08:25:12 +00001106 char
1107 *canonical_page,
1108 page[MaxTextExtent];
1109
1110 const char
1111 *image_option;
1112
1113 MagickStatusType
1114 flags;
1115
1116 RectangleInfo
1117 geometry;
1118
anthonydcf510d2011-10-30 13:51:40 +00001119 if (!IfSetOption)
anthony805a2d42011-09-25 08:25:12 +00001120 {
anthony92c93bd2012-03-19 14:02:47 +00001121 (void) DeleteImageOption(_image_info,option+1);
1122 (void) CloneString(&_image_info->page,(char *) NULL);
anthony805a2d42011-09-25 08:25:12 +00001123 break;
1124 }
1125 (void) ResetMagickMemory(&geometry,0,sizeof(geometry));
anthony92c93bd2012-03-19 14:02:47 +00001126 image_option=GetImageOption(_image_info,"page");
anthony805a2d42011-09-25 08:25:12 +00001127 if (image_option != (const char *) NULL)
1128 flags=ParseAbsoluteGeometry(image_option,&geometry);
anthony24aa8822012-03-11 00:56:06 +00001129 canonical_page=GetPageGeometry(arg1);
anthony805a2d42011-09-25 08:25:12 +00001130 flags=ParseAbsoluteGeometry(canonical_page,&geometry);
1131 canonical_page=DestroyString(canonical_page);
1132 (void) FormatLocaleString(page,MaxTextExtent,"%lux%lu",
1133 (unsigned long) geometry.width,(unsigned long) geometry.height);
1134 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
1135 (void) FormatLocaleString(page,MaxTextExtent,"%lux%lu%+ld%+ld",
1136 (unsigned long) geometry.width,(unsigned long) geometry.height,
1137 (long) geometry.x,(long) geometry.y);
anthony92c93bd2012-03-19 14:02:47 +00001138 (void) SetImageOption(_image_info,option+1,page);
1139 (void) CloneString(&_image_info->page,page);
anthony805a2d42011-09-25 08:25:12 +00001140 break;
1141 }
anthonyafa3dfc2012-03-03 11:31:30 +00001142 if (LocaleCompare("ping",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001143 {
anthony92c93bd2012-03-19 14:02:47 +00001144 _image_info->ping = ArgBoolean;
anthony805a2d42011-09-25 08:25:12 +00001145 break;
1146 }
anthonyafa3dfc2012-03-03 11:31:30 +00001147 if (LocaleCompare("pointsize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001148 {
anthonyf42014d2012-03-25 09:53:06 +00001149 if (IfSetOption) {
anthony7bcfe7f2012-03-30 14:01:22 +00001150 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00001151 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1152 _image_info->pointsize =
1153 _draw_info->pointsize =
1154 StringToDouble(arg1,(char **) NULL);
1155 }
1156 else {
1157 _image_info->pointsize=0.0; /* unset pointsize */
1158 _draw_info->pointsize=12.0;
1159 }
anthony805a2d42011-09-25 08:25:12 +00001160 break;
1161 }
anthonyafa3dfc2012-03-03 11:31:30 +00001162 if (LocaleCompare("precision",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001163 {
anthonyf42014d2012-03-25 09:53:06 +00001164 arg1=ArgOption("-1");
anthony7bcfe7f2012-03-30 14:01:22 +00001165 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00001166 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1167 (void) SetMagickPrecision(StringToInteger(arg1));
anthony805a2d42011-09-25 08:25:12 +00001168 break;
1169 }
anthonydcf510d2011-10-30 13:51:40 +00001170 /* FUTURE: Only the 'preview' coder appears to use this
anthonya3ef4ed2012-03-17 06:52:53 +00001171 * DEPRECIATE the coder? Leaving only the 'preview' operator.
anthonyafa3dfc2012-03-03 11:31:30 +00001172 if (LocaleCompare("preview",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001173 {
anthony92c93bd2012-03-19 14:02:47 +00001174 _image_info->preview_type=UndefinedPreview;
anthonydcf510d2011-10-30 13:51:40 +00001175 if (IfSetOption)
anthony92c93bd2012-03-19 14:02:47 +00001176 _image_info->preview_type=(PreviewType) ParseCommandOption(
anthony24aa8822012-03-11 00:56:06 +00001177 MagickPreviewOptions,MagickFalse,arg1);
anthony805a2d42011-09-25 08:25:12 +00001178 break;
1179 }
anthonydcf510d2011-10-30 13:51:40 +00001180 */
anthonyebb73a22012-03-22 14:25:52 +00001181 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001182 }
1183 case 'q':
1184 {
anthonyafa3dfc2012-03-03 11:31:30 +00001185 if (LocaleCompare("quality",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001186 {
anthony7bcfe7f2012-03-30 14:01:22 +00001187 if (IfMagickFalse(IsGeometry(arg1)))
anthony7bc87992012-03-25 02:32:51 +00001188 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyf42014d2012-03-25 09:53:06 +00001189 _image_info->quality= IfSetOption ? StringToUnsignedLong(arg1)
1190 : UNDEFINED_COMPRESSION_QUALITY;
anthony92c93bd2012-03-19 14:02:47 +00001191 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +00001192 break;
1193 }
anthonyafa3dfc2012-03-03 11:31:30 +00001194 if (LocaleCompare("quantize",option+1) == 0)
anthonyafbaed72011-10-26 12:05:04 +00001195 {
anthony92c93bd2012-03-19 14:02:47 +00001196 /* Just a set direct in _quantize_info */
anthony7bc87992012-03-25 02:32:51 +00001197 arg1=ArgOption("undefined");
1198 parse=ParseCommandOption(MagickColorspaceOptions,MagickFalse,arg1);
1199 if (parse < 0)
1200 CLIWandExceptArgBreak(OptionError,"UnrecognizedColorspace",
1201 option,arg1);
1202 _quantize_info->colorspace=(ColorspaceType)parse;
anthonyafbaed72011-10-26 12:05:04 +00001203 break;
1204 }
anthonyafa3dfc2012-03-03 11:31:30 +00001205 if (LocaleCompare("quiet",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001206 {
anthonyf42014d2012-03-25 09:53:06 +00001207 /* FUTURE: if two -quiet is performed you can not do +quiet!
1208 This needs to be checked over thoughly.
1209 */
anthony805a2d42011-09-25 08:25:12 +00001210 static WarningHandler
1211 warning_handler = (WarningHandler) NULL;
anthony72feaa62012-01-17 06:46:23 +00001212
anthonyafbaed72011-10-26 12:05:04 +00001213 WarningHandler
1214 tmp = SetWarningHandler((WarningHandler) NULL);
anthony805a2d42011-09-25 08:25:12 +00001215
anthonyafbaed72011-10-26 12:05:04 +00001216 if ( tmp != (WarningHandler) NULL)
1217 warning_handler = tmp; /* remember the old handler */
1218 if (!IfSetOption) /* set the old handler */
1219 warning_handler=SetWarningHandler(warning_handler);
anthony805a2d42011-09-25 08:25:12 +00001220 break;
1221 }
anthonyebb73a22012-03-22 14:25:52 +00001222 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001223 }
1224 case 'r':
1225 {
anthonyafa3dfc2012-03-03 11:31:30 +00001226 if (LocaleCompare("red-primary",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001227 {
anthonydcf510d2011-10-30 13:51:40 +00001228 /* Image chromaticity X,Y NB: Y=X if Y not defined
1229 Used by many coders
anthony72feaa62012-01-17 06:46:23 +00001230 SyncImageSettings() used to set per-image attribute.
anthonydcf510d2011-10-30 13:51:40 +00001231 */
anthonyf42014d2012-03-25 09:53:06 +00001232 arg1=ArgOption("0.0");
anthony7bcfe7f2012-03-30 14:01:22 +00001233 if (IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00001234 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyf42014d2012-03-25 09:53:06 +00001235 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +00001236 break;
1237 }
cristyb0f7a182012-04-06 23:33:11 +00001238 if (LocaleCompare("regard-warnings",option+1) == 0)
anthonye5fcd362012-04-09 04:02:09 +00001239 /* FUTURE: to be replaced by a 'fatal-level' type setting */
cristyb0f7a182012-04-06 23:33:11 +00001240 break;
anthonyafa3dfc2012-03-03 11:31:30 +00001241 if (LocaleCompare("render",option+1) == 0)
anthonyafbaed72011-10-26 12:05:04 +00001242 {
anthony92c93bd2012-03-19 14:02:47 +00001243 /* _draw_info only setting */
1244 _draw_info->render= ArgBooleanNot;
anthonyafbaed72011-10-26 12:05:04 +00001245 break;
1246 }
anthony756cd0d2012-04-08 12:41:44 +00001247 if (LocaleCompare("respect-parenthesis",option+1) == 0)
1248 {
1249 /* link image and setting stacks - option is itself saved on stack! */
1250 (void) SetImageOption(_image_info,option+1,ArgBooleanString);
1251 break;
1252 }
anthonyebb73a22012-03-22 14:25:52 +00001253 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001254 }
1255 case 's':
1256 {
anthonyafa3dfc2012-03-03 11:31:30 +00001257 if (LocaleCompare("sampling-factor",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001258 {
anthonyafbaed72011-10-26 12:05:04 +00001259 /* FUTURE: should be converted to jpeg:sampling_factor */
anthony7bcfe7f2012-03-30 14:01:22 +00001260 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00001261 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001262 (void) CloneString(&_image_info->sampling_factor,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +00001263 break;
1264 }
anthonyafa3dfc2012-03-03 11:31:30 +00001265 if (LocaleCompare("scene",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001266 {
anthonyf42014d2012-03-25 09:53:06 +00001267 /* SyncImageSettings() used to set this as a per-image attribute.
anthony72feaa62012-01-17 06:46:23 +00001268 What ??? Why ????
1269 */
anthony7bcfe7f2012-03-30 14:01:22 +00001270 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00001271 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001272 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1273 _image_info->scene=StringToUnsignedLong(ArgOption("0"));
anthony805a2d42011-09-25 08:25:12 +00001274 break;
1275 }
anthonyafa3dfc2012-03-03 11:31:30 +00001276 if (LocaleCompare("seed",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001277 {
anthony7bcfe7f2012-03-30 14:01:22 +00001278 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00001279 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
cristyd7761bb2012-04-14 01:42:05 +00001280 SetRandomSecretKey(
anthony24aa8822012-03-11 00:56:06 +00001281 IfSetOption ? (size_t) StringToUnsignedLong(arg1)
anthonyafbaed72011-10-26 12:05:04 +00001282 : (size_t) time((time_t *) NULL) );
anthony805a2d42011-09-25 08:25:12 +00001283 break;
1284 }
anthonyafa3dfc2012-03-03 11:31:30 +00001285 if (LocaleCompare("size",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001286 {
anthony92c93bd2012-03-19 14:02:47 +00001287 /* FUTURE: string in _image_info -- convert to Option ???
anthonyafbaed72011-10-26 12:05:04 +00001288 Look at the special handling for "size" in SetImageOption()
anthony74b1cfc2011-10-06 12:44:16 +00001289 */
anthony92c93bd2012-03-19 14:02:47 +00001290 (void) CloneString(&_image_info->size,ArgOption(NULL));
anthonyafbaed72011-10-26 12:05:04 +00001291 break;
1292 }
anthonyafa3dfc2012-03-03 11:31:30 +00001293 if (LocaleCompare("stretch",option+1) == 0)
anthonyafbaed72011-10-26 12:05:04 +00001294 {
anthonyf42014d2012-03-25 09:53:06 +00001295 arg1=ArgOption("undefined");
1296 parse = ParseCommandOption(MagickStretchOptions,MagickFalse,arg1);
1297 if (parse < 0)
1298 CLIWandExceptArgBreak(OptionError,"UnrecognizedStretchType",
1299 option,arg1);
1300 _draw_info->stretch=(StretchType) parse;
anthony805a2d42011-09-25 08:25:12 +00001301 break;
1302 }
anthonyafa3dfc2012-03-03 11:31:30 +00001303 if (LocaleCompare("stroke",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001304 {
anthonyafbaed72011-10-26 12:05:04 +00001305 /* set stroke color OR stroke-pattern
anthonyfd706f92012-01-19 04:22:02 +00001306 UPDATE: ensure stroke color is not destroyed is a pattern
1307 is given. Just in case the color is also used for other purposes.
anthonyafbaed72011-10-26 12:05:04 +00001308 */
anthony72feaa62012-01-17 06:46:23 +00001309 MagickBooleanType
1310 status;
anthonyafbaed72011-10-26 12:05:04 +00001311
1312 ExceptionInfo
1313 *sans;
1314
anthonyfd706f92012-01-19 04:22:02 +00001315 PixelInfo
1316 color;
1317
anthony2a0ec8c2012-03-24 04:35:56 +00001318 arg1 = ArgOption("none"); /* +fill turns it off! */
1319 (void) SetImageOption(_image_info,option+1,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001320 if (_draw_info->stroke_pattern != (Image *) NULL)
1321 _draw_info->stroke_pattern=DestroyImage(_draw_info->stroke_pattern);
anthony72feaa62012-01-17 06:46:23 +00001322
1323 /* is it a color or a image? -- ignore exceptions */
anthonyafbaed72011-10-26 12:05:04 +00001324 sans=AcquireExceptionInfo();
anthony2a0ec8c2012-03-24 04:35:56 +00001325 status=QueryColorCompliance(arg1,AllCompliance,&color,sans);
anthonyafbaed72011-10-26 12:05:04 +00001326 sans=DestroyExceptionInfo(sans);
anthonyfd706f92012-01-19 04:22:02 +00001327
anthony7bcfe7f2012-03-30 14:01:22 +00001328 if (IfMagickFalse(status))
anthony2a0ec8c2012-03-24 04:35:56 +00001329 _draw_info->stroke_pattern=GetImageCache(_image_info,arg1,_exception);
anthonyfd706f92012-01-19 04:22:02 +00001330 else
anthony92c93bd2012-03-19 14:02:47 +00001331 _draw_info->stroke=color;
anthony805a2d42011-09-25 08:25:12 +00001332 break;
1333 }
anthonyafa3dfc2012-03-03 11:31:30 +00001334 if (LocaleCompare("strokewidth",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001335 {
anthony7bcfe7f2012-03-30 14:01:22 +00001336 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00001337 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001338 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1339 _draw_info->stroke_width=StringToDouble(ArgOption("1.0"),
anthony72feaa62012-01-17 06:46:23 +00001340 (char **) NULL);
anthonyafbaed72011-10-26 12:05:04 +00001341 break;
1342 }
anthonyafa3dfc2012-03-03 11:31:30 +00001343 if (LocaleCompare("style",option+1) == 0)
anthonyafbaed72011-10-26 12:05:04 +00001344 {
anthonyf42014d2012-03-25 09:53:06 +00001345 arg1=ArgOption("undefined");
1346 parse = ParseCommandOption(MagickStyleOptions,MagickFalse,arg1);
1347 if (parse < 0)
1348 CLIWandExceptArgBreak(OptionError,"UnrecognizedStyleType",
1349 option,arg1);
1350 _draw_info->style=(StyleType) parse;
anthony805a2d42011-09-25 08:25:12 +00001351 break;
1352 }
anthonyafa3dfc2012-03-03 11:31:30 +00001353 if (LocaleCompare("synchronize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001354 {
anthonyf42014d2012-03-25 09:53:06 +00001355 /* FUTURE: syncronize to storage - but what does that mean? */
anthony92c93bd2012-03-19 14:02:47 +00001356 _image_info->synchronize = ArgBoolean;
anthony805a2d42011-09-25 08:25:12 +00001357 break;
1358 }
anthonyebb73a22012-03-22 14:25:52 +00001359 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001360 }
1361 case 't':
1362 {
anthonyafa3dfc2012-03-03 11:31:30 +00001363 if (LocaleCompare("taint",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001364 {
anthony72feaa62012-01-17 06:46:23 +00001365 /* SyncImageSettings() used to set per-image attribute. */
anthony92c93bd2012-03-19 14:02:47 +00001366 (void) SetImageOption(_image_info,option+1,ArgBooleanString);
anthony805a2d42011-09-25 08:25:12 +00001367 break;
1368 }
anthonyafa3dfc2012-03-03 11:31:30 +00001369 if (LocaleCompare("texture",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001370 {
anthony52bef752012-03-27 13:54:47 +00001371 /* FUTURE: move _image_info string to option splay-tree
1372 Other than "montage" what uses "texture" ????
1373 */
anthony92c93bd2012-03-19 14:02:47 +00001374 (void) CloneString(&_image_info->texture,ArgOption(NULL));
anthonyafbaed72011-10-26 12:05:04 +00001375 break;
1376 }
anthonyafa3dfc2012-03-03 11:31:30 +00001377 if (LocaleCompare("tile",option+1) == 0)
anthonyafbaed72011-10-26 12:05:04 +00001378 {
anthony92c93bd2012-03-19 14:02:47 +00001379 _draw_info->fill_pattern=IfSetOption
1380 ?GetImageCache(_image_info,arg1,_exception)
1381 :DestroyImage(_draw_info->fill_pattern);
anthony805a2d42011-09-25 08:25:12 +00001382 break;
1383 }
anthonyafa3dfc2012-03-03 11:31:30 +00001384 if (LocaleCompare("tile-offset",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001385 {
anthony72feaa62012-01-17 06:46:23 +00001386 /* SyncImageSettings() used to set per-image attribute. ??? */
anthony52bef752012-03-27 13:54:47 +00001387 arg1=ArgOption("0");
anthony7bcfe7f2012-03-30 14:01:22 +00001388 if (IfMagickFalse(IsGeometry(arg1)))
anthony52bef752012-03-27 13:54:47 +00001389 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1390 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +00001391 break;
1392 }
anthonyafa3dfc2012-03-03 11:31:30 +00001393 if (LocaleCompare("transparent-color",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001394 {
anthony92c93bd2012-03-19 14:02:47 +00001395 /* FUTURE: both _image_info attribute & ImageOption in use!
1396 _image_info only used for generating new images.
anthony72feaa62012-01-17 06:46:23 +00001397 SyncImageSettings() used to set per-image attribute.
1398
anthonyafbaed72011-10-26 12:05:04 +00001399 Note that +transparent-color, means fall-back to image
1400 attribute so ImageOption is deleted, not set to a default.
1401 */
anthony7bcfe7f2012-03-30 14:01:22 +00001402 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthony52bef752012-03-27 13:54:47 +00001403 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001404 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony72feaa62012-01-17 06:46:23 +00001405 (void) QueryColorCompliance(ArgOption("none"),AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +00001406 &_image_info->transparent_color,_exception);
anthony805a2d42011-09-25 08:25:12 +00001407 break;
1408 }
anthonyafa3dfc2012-03-03 11:31:30 +00001409 if (LocaleCompare("treedepth",option+1) == 0)
anthony31f1bf72012-01-30 12:37:22 +00001410 {
anthony92c93bd2012-03-19 14:02:47 +00001411 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1412 _quantize_info->tree_depth=StringToUnsignedLong(ArgOption("0"));
anthony31f1bf72012-01-30 12:37:22 +00001413 break;
1414 }
anthonyafa3dfc2012-03-03 11:31:30 +00001415 if (LocaleCompare("type",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001416 {
anthony72feaa62012-01-17 06:46:23 +00001417 /* SyncImageSettings() used to set per-image attribute. */
anthony52bef752012-03-27 13:54:47 +00001418 parse=ParseCommandOption(MagickTypeOptions,MagickFalse,
1419 ArgOption("undefined"));
1420 if (parse < 0)
1421 CLIWandExceptArgBreak(OptionError,"UnrecognizedImageType",
1422 option,arg1);
1423 _image_info->type=(ImageType) parse;
anthony92c93bd2012-03-19 14:02:47 +00001424 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +00001425 break;
1426 }
anthonyebb73a22012-03-22 14:25:52 +00001427 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001428 }
1429 case 'u':
1430 {
anthonyafa3dfc2012-03-03 11:31:30 +00001431 if (LocaleCompare("undercolor",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001432 {
anthony92c93bd2012-03-19 14:02:47 +00001433 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony72feaa62012-01-17 06:46:23 +00001434 (void) QueryColorCompliance(ArgOption("none"),AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +00001435 &_draw_info->undercolor,_exception);
anthony805a2d42011-09-25 08:25:12 +00001436 break;
1437 }
anthonyafa3dfc2012-03-03 11:31:30 +00001438 if (LocaleCompare("units",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001439 {
anthony72feaa62012-01-17 06:46:23 +00001440 /* SyncImageSettings() used to set per-image attribute.
anthony92c93bd2012-03-19 14:02:47 +00001441 Should this effect _draw_info X and Y resolution?
anthony72feaa62012-01-17 06:46:23 +00001442 FUTURE: this probably should be part of the density setting
1443 */
anthony52bef752012-03-27 13:54:47 +00001444 parse=ParseCommandOption(MagickResolutionOptions,MagickFalse,
1445 ArgOption("undefined"));
1446 if (parse < 0)
1447 CLIWandExceptArgBreak(OptionError,"UnrecognizedUnitsType",
1448 option,arg1);
1449 _image_info->units=(ResolutionType) parse;
anthony92c93bd2012-03-19 14:02:47 +00001450 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +00001451 break;
1452 }
anthonyebb73a22012-03-22 14:25:52 +00001453 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001454 }
1455 case 'v':
1456 {
anthonyafa3dfc2012-03-03 11:31:30 +00001457 if (LocaleCompare("verbose",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001458 {
anthony24aa8822012-03-11 00:56:06 +00001459 /* FUTURE: Remember all options become image artifacts
anthony92c93bd2012-03-19 14:02:47 +00001460 _image_info->verbose is only used by coders.
anthonyab3a50c2011-10-27 11:48:57 +00001461 */
anthony92c93bd2012-03-19 14:02:47 +00001462 (void) SetImageOption(_image_info,option+1,ArgBooleanString);
1463 _image_info->verbose= ArgBoolean;
1464 _image_info->ping=MagickFalse; /* verbose can't be a ping */
anthony805a2d42011-09-25 08:25:12 +00001465 break;
1466 }
anthonyafa3dfc2012-03-03 11:31:30 +00001467 if (LocaleCompare("view",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001468 {
anthony92c93bd2012-03-19 14:02:47 +00001469 /* FUTURE: Convert from _image_info to ImageOption
anthonyab3a50c2011-10-27 11:48:57 +00001470 Only used by coder FPX
anthony52bef752012-03-27 13:54:47 +00001471 And it only tests existance, not its content!
anthonyab3a50c2011-10-27 11:48:57 +00001472 */
anthony92c93bd2012-03-19 14:02:47 +00001473 (void) CloneString(&_image_info->view,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +00001474 break;
1475 }
anthonyafa3dfc2012-03-03 11:31:30 +00001476 if (LocaleCompare("virtual-pixel",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001477 {
anthonyfd706f92012-01-19 04:22:02 +00001478 /* SyncImageSettings() used to set per-image attribute.
1479 This is VERY deep in the image caching structure.
1480 */
anthony52bef752012-03-27 13:54:47 +00001481 parse=ParseCommandOption(MagickVirtualPixelOptions,MagickFalse,
1482 ArgOption("undefined"));
1483 if (parse < 0)
1484 CLIWandExceptArgBreak(OptionError,"UnrecognizedVirtualPixelMethod",
1485 option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001486 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +00001487 break;
1488 }
anthonyebb73a22012-03-22 14:25:52 +00001489 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001490 }
1491 case 'w':
1492 {
anthonyafa3dfc2012-03-03 11:31:30 +00001493 if (LocaleCompare("weight",option+1) == 0)
anthonyab3a50c2011-10-27 11:48:57 +00001494 {
anthony72feaa62012-01-17 06:46:23 +00001495 /* Just what does using a font 'weight' do ???
anthonydcf510d2011-10-30 13:51:40 +00001496 There is no "-list weight" output (reference manual says there is)
anthonyab3a50c2011-10-27 11:48:57 +00001497 */
anthony52bef752012-03-27 13:54:47 +00001498 arg1=ArgOption("all");
anthony92c93bd2012-03-19 14:02:47 +00001499 _draw_info->weight=StringToUnsignedLong(arg1);
anthony24aa8822012-03-11 00:56:06 +00001500 if (LocaleCompare(arg1,"all") == 0)
anthony92c93bd2012-03-19 14:02:47 +00001501 _draw_info->weight=0;
anthony24aa8822012-03-11 00:56:06 +00001502 if (LocaleCompare(arg1,"bold") == 0)
anthony92c93bd2012-03-19 14:02:47 +00001503 _draw_info->weight=700;
anthony24aa8822012-03-11 00:56:06 +00001504 if (LocaleCompare(arg1,"bolder") == 0)
anthony92c93bd2012-03-19 14:02:47 +00001505 if (_draw_info->weight <= 800)
1506 _draw_info->weight+=100;
anthony24aa8822012-03-11 00:56:06 +00001507 if (LocaleCompare(arg1,"lighter") == 0)
anthony92c93bd2012-03-19 14:02:47 +00001508 if (_draw_info->weight >= 100)
1509 _draw_info->weight-=100;
anthony24aa8822012-03-11 00:56:06 +00001510 if (LocaleCompare(arg1,"normal") == 0)
anthony92c93bd2012-03-19 14:02:47 +00001511 _draw_info->weight=400;
anthonyab3a50c2011-10-27 11:48:57 +00001512 break;
1513 }
anthonyafa3dfc2012-03-03 11:31:30 +00001514 if (LocaleCompare("white-point",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001515 {
anthony72feaa62012-01-17 06:46:23 +00001516 /* Used as a image chromaticity setting
1517 SyncImageSettings() used to set per-image attribute.
1518 */
anthony52bef752012-03-27 13:54:47 +00001519 arg1=ArgOption("0.0");
anthony7bcfe7f2012-03-30 14:01:22 +00001520 if (IfMagickFalse(IsGeometry(arg1)))
anthony52bef752012-03-27 13:54:47 +00001521 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1522 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +00001523 break;
1524 }
anthonyebb73a22012-03-22 14:25:52 +00001525 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001526 }
1527 default:
anthonyebb73a22012-03-22 14:25:52 +00001528 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001529 }
anthony24aa8822012-03-11 00:56:06 +00001530
anthony92c93bd2012-03-19 14:02:47 +00001531#undef _image_info
1532#undef _exception
1533#undef _draw_info
1534#undef _quantize_info
anthonyfd706f92012-01-19 04:22:02 +00001535#undef IfSetOption
anthonyfd706f92012-01-19 04:22:02 +00001536#undef ArgBoolean
anthony24aa8822012-03-11 00:56:06 +00001537#undef ArgBooleanNot
1538#undef ArgBooleanString
1539#undef ArgOption
anthonyfd706f92012-01-19 04:22:02 +00001540
anthony31f1bf72012-01-30 12:37:22 +00001541 return;
anthony805a2d42011-09-25 08:25:12 +00001542}
1543
1544/*
1545%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1546% %
1547% %
1548% %
anthony43f425d2012-02-26 12:58:58 +00001549+ 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 +00001550% %
1551% %
1552% %
1553%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1554%
anthony31f1bf72012-01-30 12:37:22 +00001555% WandSimpleOperatorImages() applys one simple image operation given to all
anthony43f425d2012-02-26 12:58:58 +00001556% the images in the CLI wand, with the settings that was previously saved in
1557% the CLI wand.
anthonydcf510d2011-10-30 13:51:40 +00001558%
1559% It is assumed that any per-image settings are up-to-date with respect to
anthony43f425d2012-02-26 12:58:58 +00001560% extra settings that were already saved in the wand.
anthony805a2d42011-09-25 08:25:12 +00001561%
anthonyd1447672012-01-19 05:33:53 +00001562% The format of the WandSimpleOperatorImage method is:
anthony805a2d42011-09-25 08:25:12 +00001563%
anthony43f425d2012-02-26 12:58:58 +00001564% void CLISimpleOperatorImages(MagickCLI *cli_wand,
anthonyafa3dfc2012-03-03 11:31:30 +00001565% const char *option, const char *arg1, const char *arg2)
anthony805a2d42011-09-25 08:25:12 +00001566%
1567% A description of each parameter follows:
1568%
anthony43f425d2012-02-26 12:58:58 +00001569% o cli_wand: structure holding settings and images to be operated on
anthony805a2d42011-09-25 08:25:12 +00001570%
anthonyfd706f92012-01-19 04:22:02 +00001571% o option: The option string for the operation
anthonydcf510d2011-10-30 13:51:40 +00001572%
anthonyfd706f92012-01-19 04:22:02 +00001573% o arg1, arg2: optional argument strings to the operation
anthony805a2d42011-09-25 08:25:12 +00001574%
anthony31f1bf72012-01-30 12:37:22 +00001575% Any problems will be added to the 'exception' entry of the given wand.
anthony805a2d42011-09-25 08:25:12 +00001576%
anthony31f1bf72012-01-30 12:37:22 +00001577% Example usage...
anthonydcf510d2011-10-30 13:51:40 +00001578%
anthonyafa3dfc2012-03-03 11:31:30 +00001579% CLISimpleOperatorImages(cli_wand, "-crop","100x100+20+30",NULL);
1580% CLISimpleOperatorImages(cli_wand, "+repage",NULL,NULL);
1581% CLISimpleOperatorImages(cli_wand, "+distort","SRT","45");
anthonyfd706f92012-01-19 04:22:02 +00001582%
anthony24aa8822012-03-11 00:56:06 +00001583% Or for handling command line arguments EG: +/-option ["arg1"]
anthonydcf510d2011-10-30 13:51:40 +00001584%
anthony43f425d2012-02-26 12:58:58 +00001585% cli_wand
anthonydcf510d2011-10-30 13:51:40 +00001586% argc,argv
1587% i=index in argv
1588%
anthony2052d272012-02-28 12:48:29 +00001589% option_info = GetCommandOptionInfo(argv[i]);
1590% count=option_info->type;
1591% option_type=option_info->flags;
1592%
1593% if ( (option_type & SimpleOperatorOptionFlag) != 0 )
anthonyafa3dfc2012-03-03 11:31:30 +00001594% CLISimpleOperatorImages(cli_wand, argv[i],
anthonyfd706f92012-01-19 04:22:02 +00001595% count>=1 ? argv[i+1] : (char *)NULL,
1596% count>=2 ? argv[i+2] : (char *)NULL );
anthonydcf510d2011-10-30 13:51:40 +00001597% i += count+1;
1598%
anthony805a2d42011-09-25 08:25:12 +00001599*/
anthony31f1bf72012-01-30 12:37:22 +00001600
1601/*
1602 Internal subrountine to apply one simple image operation to the current
anthony43f425d2012-02-26 12:58:58 +00001603 image pointed to by the CLI wand.
anthony31f1bf72012-01-30 12:37:22 +00001604
1605 The image in the list may be modified in three different ways...
1606 * directly modified (EG: -negate, -gamma, -level, -annotate, -draw),
1607 * replaced by a new image (EG: -spread, -resize, -rotate, -morphology)
1608 * one image replace by a list of images (-separate and -crop only!)
1609
anthonyafa3dfc2012-03-03 11:31:30 +00001610 In each case the result replaces the single original image in the list, as
1611 well as the pointer to the modified image (last image added if replaced by a
1612 list of images) is returned.
anthony31f1bf72012-01-30 12:37:22 +00001613
1614 As the image pointed to may be replaced, the first image in the list may
1615 also change. GetFirstImageInList() should be used by caller if they wish
1616 return the Image pointer to the first image in list.
1617*/
anthony43f425d2012-02-26 12:58:58 +00001618static void CLISimpleOperatorImage(MagickCLI *cli_wand,
anthonyafa3dfc2012-03-03 11:31:30 +00001619 const char *option, const char *arg1, const char *arg2)
anthony805a2d42011-09-25 08:25:12 +00001620{
1621 Image *
1622 new_image;
1623
anthony805a2d42011-09-25 08:25:12 +00001624 GeometryInfo
1625 geometry_info;
1626
1627 RectangleInfo
1628 geometry;
1629
1630 MagickStatusType
anthony805a2d42011-09-25 08:25:12 +00001631 flags;
1632
anthony92c93bd2012-03-19 14:02:47 +00001633 ssize_t
anthony2a0ec8c2012-03-24 04:35:56 +00001634 parse;
anthony92c93bd2012-03-19 14:02:47 +00001635
anthony2e4501b2012-03-30 04:41:54 +00001636#define _image_info (cli_wand->wand.image_info)
1637#define _image (cli_wand->wand.images)
1638#define _exception (cli_wand->wand.exception)
1639#define _draw_info (cli_wand->draw_info)
1640#define _quantize_info (cli_wand->quantize_info)
anthonyafa3dfc2012-03-03 11:31:30 +00001641#define IfNormalOp (*option=='-')
1642#define IfPlusOp (*option!='-')
anthony7bcfe7f2012-03-30 14:01:22 +00001643#define normal_op IsMagickTrue(IfNormalOp)
1644#define plus_alt_op IsMagickFalse(IfNormalOp)
anthonyfd706f92012-01-19 04:22:02 +00001645
anthony43f425d2012-02-26 12:58:58 +00001646 assert(cli_wand != (MagickCLI *) NULL);
1647 assert(cli_wand->signature == WandSignature);
1648 assert(cli_wand->wand.signature == WandSignature);
anthony5330ae02012-03-20 14:17:01 +00001649 assert(_image != (Image *) NULL); /* an image must be present */
anthony7bcfe7f2012-03-30 14:01:22 +00001650 if (IfMagickTrue(cli_wand->wand.debug))
anthony43f425d2012-02-26 12:58:58 +00001651 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
anthonydcf510d2011-10-30 13:51:40 +00001652
anthony92c93bd2012-03-19 14:02:47 +00001653 (void) SyncImageSettings(_image_info,_image,_exception);
anthony24aa8822012-03-11 00:56:06 +00001654
anthony805a2d42011-09-25 08:25:12 +00001655 SetGeometryInfo(&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00001656
anthony5330ae02012-03-20 14:17:01 +00001657 new_image = (Image *)NULL; /* the replacement image, if not null at end */
anthony805a2d42011-09-25 08:25:12 +00001658
anthonyfd706f92012-01-19 04:22:02 +00001659 /* FUTURE: We may need somthing a little more optimized than this!
1660 Perhaps, do the 'sync' if 'settings tainted' before next operator.
1661 */
anthonyafa3dfc2012-03-03 11:31:30 +00001662 switch (*(option+1))
anthony805a2d42011-09-25 08:25:12 +00001663 {
1664 case 'a':
1665 {
anthonyafa3dfc2012-03-03 11:31:30 +00001666 if (LocaleCompare("adaptive-blur",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001667 {
anthony7bcfe7f2012-03-30 14:01:22 +00001668 if (IfMagickFalse(IsGeometry(arg1)))
anthony92c93bd2012-03-19 14:02:47 +00001669 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00001670 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00001671 if ((flags & SigmaValue) == 0)
1672 geometry_info.sigma=1.0;
anthony92c93bd2012-03-19 14:02:47 +00001673 new_image=AdaptiveBlurImage(_image,geometry_info.rho,
cristyaa2c16c2012-03-25 22:21:35 +00001674 geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00001675 break;
1676 }
anthonyafa3dfc2012-03-03 11:31:30 +00001677 if (LocaleCompare("adaptive-resize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001678 {
anthonyfe1aa782012-03-24 13:43:04 +00001679 /* FUTURE: Roll into a resize special operator */
anthony7bcfe7f2012-03-30 14:01:22 +00001680 if (IfMagickFalse(IsGeometry(arg1)))
anthony92c93bd2012-03-19 14:02:47 +00001681 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1682 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
1683 new_image=AdaptiveResizeImage(_image,geometry.width,geometry.height,
cristyaa2c16c2012-03-25 22:21:35 +00001684 _exception);
anthony805a2d42011-09-25 08:25:12 +00001685 break;
1686 }
anthonyafa3dfc2012-03-03 11:31:30 +00001687 if (LocaleCompare("adaptive-sharpen",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001688 {
anthony7bcfe7f2012-03-30 14:01:22 +00001689 if (IfMagickFalse(IsGeometry(arg1)))
anthony92c93bd2012-03-19 14:02:47 +00001690 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00001691 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00001692 if ((flags & SigmaValue) == 0)
1693 geometry_info.sigma=1.0;
anthony92c93bd2012-03-19 14:02:47 +00001694 new_image=AdaptiveSharpenImage(_image,geometry_info.rho,
cristyaa2c16c2012-03-25 22:21:35 +00001695 geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00001696 break;
1697 }
anthonyafa3dfc2012-03-03 11:31:30 +00001698 if (LocaleCompare("alpha",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001699 {
anthony2a0ec8c2012-03-24 04:35:56 +00001700 parse=ParseCommandOption(MagickAlphaOptions,MagickFalse,arg1);
1701 if (parse < 0)
anthony92c93bd2012-03-19 14:02:47 +00001702 CLIWandExceptArgBreak(OptionError,"UnrecognizedAlphaChannelType",
1703 option,arg1);
anthony2a0ec8c2012-03-24 04:35:56 +00001704 (void) SetImageAlphaChannel(_image,(AlphaChannelType)parse,
1705 _exception);
anthony805a2d42011-09-25 08:25:12 +00001706 break;
1707 }
anthonyafa3dfc2012-03-03 11:31:30 +00001708 if (LocaleCompare("annotate",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001709 {
1710 char
1711 *text,
1712 geometry[MaxTextExtent];
1713
anthony7bcfe7f2012-03-30 14:01:22 +00001714 if (IfMagickFalse(IsGeometry(arg1)))
anthony92c93bd2012-03-19 14:02:47 +00001715 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00001716 SetGeometryInfo(&geometry_info);
anthonyfd706f92012-01-19 04:22:02 +00001717 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00001718 if ((flags & SigmaValue) == 0)
1719 geometry_info.sigma=geometry_info.rho;
anthony92c93bd2012-03-19 14:02:47 +00001720 text=InterpretImageProperties(_image_info,_image,arg2,
1721 _exception);
anthony805a2d42011-09-25 08:25:12 +00001722 if (text == (char *) NULL)
1723 break;
anthony92c93bd2012-03-19 14:02:47 +00001724 (void) CloneString(&_draw_info->text,text);
anthony805a2d42011-09-25 08:25:12 +00001725 text=DestroyString(text);
1726 (void) FormatLocaleString(geometry,MaxTextExtent,"%+f%+f",
1727 geometry_info.xi,geometry_info.psi);
anthony92c93bd2012-03-19 14:02:47 +00001728 (void) CloneString(&_draw_info->geometry,geometry);
1729 _draw_info->affine.sx=cos(DegreesToRadians(
anthony805a2d42011-09-25 08:25:12 +00001730 fmod(geometry_info.rho,360.0)));
anthony92c93bd2012-03-19 14:02:47 +00001731 _draw_info->affine.rx=sin(DegreesToRadians(
anthony805a2d42011-09-25 08:25:12 +00001732 fmod(geometry_info.rho,360.0)));
anthony92c93bd2012-03-19 14:02:47 +00001733 _draw_info->affine.ry=(-sin(DegreesToRadians(
anthony805a2d42011-09-25 08:25:12 +00001734 fmod(geometry_info.sigma,360.0))));
anthony92c93bd2012-03-19 14:02:47 +00001735 _draw_info->affine.sy=cos(DegreesToRadians(
anthony805a2d42011-09-25 08:25:12 +00001736 fmod(geometry_info.sigma,360.0)));
anthony92c93bd2012-03-19 14:02:47 +00001737 (void) AnnotateImage(_image,_draw_info,_exception);
1738 GetAffineMatrix(&_draw_info->affine);
anthony805a2d42011-09-25 08:25:12 +00001739 break;
1740 }
anthonyafa3dfc2012-03-03 11:31:30 +00001741 if (LocaleCompare("auto-gamma",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001742 {
anthony92c93bd2012-03-19 14:02:47 +00001743 (void) AutoGammaImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00001744 break;
1745 }
anthonyafa3dfc2012-03-03 11:31:30 +00001746 if (LocaleCompare("auto-level",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001747 {
anthony92c93bd2012-03-19 14:02:47 +00001748 (void) AutoLevelImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00001749 break;
1750 }
anthonyafa3dfc2012-03-03 11:31:30 +00001751 if (LocaleCompare("auto-orient",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001752 {
anthony5330ae02012-03-20 14:17:01 +00001753 /* This should probably be a MagickCore function */
anthony92c93bd2012-03-19 14:02:47 +00001754 switch (_image->orientation)
anthony805a2d42011-09-25 08:25:12 +00001755 {
1756 case TopRightOrientation:
1757 {
anthony92c93bd2012-03-19 14:02:47 +00001758 new_image=FlopImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00001759 break;
1760 }
1761 case BottomRightOrientation:
1762 {
anthony92c93bd2012-03-19 14:02:47 +00001763 new_image=RotateImage(_image,180.0,_exception);
anthony805a2d42011-09-25 08:25:12 +00001764 break;
1765 }
1766 case BottomLeftOrientation:
1767 {
anthony92c93bd2012-03-19 14:02:47 +00001768 new_image=FlipImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00001769 break;
1770 }
1771 case LeftTopOrientation:
1772 {
anthony92c93bd2012-03-19 14:02:47 +00001773 new_image=TransposeImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00001774 break;
1775 }
1776 case RightTopOrientation:
1777 {
anthony92c93bd2012-03-19 14:02:47 +00001778 new_image=RotateImage(_image,90.0,_exception);
anthony805a2d42011-09-25 08:25:12 +00001779 break;
1780 }
1781 case RightBottomOrientation:
1782 {
anthony92c93bd2012-03-19 14:02:47 +00001783 new_image=TransverseImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00001784 break;
1785 }
1786 case LeftBottomOrientation:
1787 {
anthony92c93bd2012-03-19 14:02:47 +00001788 new_image=RotateImage(_image,270.0,_exception);
anthony805a2d42011-09-25 08:25:12 +00001789 break;
1790 }
1791 default:
1792 break;
1793 }
1794 if (new_image != (Image *) NULL)
1795 new_image->orientation=TopLeftOrientation;
1796 break;
1797 }
anthonyebb73a22012-03-22 14:25:52 +00001798 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001799 }
1800 case 'b':
1801 {
anthonyafa3dfc2012-03-03 11:31:30 +00001802 if (LocaleCompare("black-threshold",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001803 {
anthony7bcfe7f2012-03-30 14:01:22 +00001804 if (IfMagickFalse(IsGeometry(arg1)))
anthony5330ae02012-03-20 14:17:01 +00001805 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001806 (void) BlackThresholdImage(_image,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00001807 break;
1808 }
anthonyafa3dfc2012-03-03 11:31:30 +00001809 if (LocaleCompare("blue-shift",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001810 {
anthony805a2d42011-09-25 08:25:12 +00001811 geometry_info.rho=1.5;
anthony5330ae02012-03-20 14:17:01 +00001812 if (IfNormalOp) {
anthony7bcfe7f2012-03-30 14:01:22 +00001813 if (IfMagickFalse(IsGeometry(arg1)))
anthony5330ae02012-03-20 14:17:01 +00001814 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00001815 flags=ParseGeometry(arg1,&geometry_info);
anthony5330ae02012-03-20 14:17:01 +00001816 }
anthony92c93bd2012-03-19 14:02:47 +00001817 new_image=BlueShiftImage(_image,geometry_info.rho,_exception);
anthony805a2d42011-09-25 08:25:12 +00001818 break;
1819 }
anthonyafa3dfc2012-03-03 11:31:30 +00001820 if (LocaleCompare("blur",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001821 {
anthony7bcfe7f2012-03-30 14:01:22 +00001822 if (IfMagickFalse(IsGeometry(arg1)))
anthony5330ae02012-03-20 14:17:01 +00001823 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00001824 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00001825 if ((flags & SigmaValue) == 0)
1826 geometry_info.sigma=1.0;
cristyaa2c16c2012-03-25 22:21:35 +00001827 new_image=BlurImage(_image,geometry_info.rho,geometry_info.sigma,
1828 _exception);
anthony805a2d42011-09-25 08:25:12 +00001829 break;
1830 }
anthonyafa3dfc2012-03-03 11:31:30 +00001831 if (LocaleCompare("border",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001832 {
anthony31f1bf72012-01-30 12:37:22 +00001833 CompositeOperator
anthony5f867ae2011-10-09 10:28:34 +00001834 compose;
1835
1836 const char*
anthony5f867ae2011-10-09 10:28:34 +00001837 value;
1838
anthony7bcfe7f2012-03-30 14:01:22 +00001839 if (IfMagickFalse(IsGeometry(arg1)))
anthony5330ae02012-03-20 14:17:01 +00001840 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1841
anthony92c93bd2012-03-19 14:02:47 +00001842 value=GetImageOption(_image_info,"compose");
anthony5f867ae2011-10-09 10:28:34 +00001843 if (value != (const char *) NULL)
1844 compose=(CompositeOperator) ParseCommandOption(
1845 MagickComposeOptions,MagickFalse,value);
1846 else
anthony92c93bd2012-03-19 14:02:47 +00001847 compose=OverCompositeOp; /* use Over not _image->compose */
anthony5f867ae2011-10-09 10:28:34 +00001848
anthony92c93bd2012-03-19 14:02:47 +00001849 flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00001850 if ((flags & SigmaValue) == 0)
1851 geometry.height=geometry.width;
anthony92c93bd2012-03-19 14:02:47 +00001852 new_image=BorderImage(_image,&geometry,compose,_exception);
anthony805a2d42011-09-25 08:25:12 +00001853 break;
1854 }
anthonyafa3dfc2012-03-03 11:31:30 +00001855 if (LocaleCompare("brightness-contrast",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001856 {
1857 double
1858 brightness,
1859 contrast;
1860
1861 GeometryInfo
1862 geometry_info;
1863
1864 MagickStatusType
1865 flags;
1866
anthony7bcfe7f2012-03-30 14:01:22 +00001867 if (IfMagickFalse(IsGeometry(arg1)))
anthony5330ae02012-03-20 14:17:01 +00001868 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00001869 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00001870 brightness=geometry_info.rho;
1871 contrast=0.0;
1872 if ((flags & SigmaValue) != 0)
1873 contrast=geometry_info.sigma;
anthony92c93bd2012-03-19 14:02:47 +00001874 (void) BrightnessContrastImage(_image,brightness,contrast,
1875 _exception);
anthony805a2d42011-09-25 08:25:12 +00001876 break;
1877 }
anthonyebb73a22012-03-22 14:25:52 +00001878 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001879 }
1880 case 'c':
1881 {
anthonyafa3dfc2012-03-03 11:31:30 +00001882 if (LocaleCompare("cdl",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001883 {
1884 char
1885 *color_correction_collection;
1886
1887 /*
1888 Color correct with a color decision list.
1889 */
anthony92c93bd2012-03-19 14:02:47 +00001890 color_correction_collection=FileToString(arg1,~0,_exception);
anthony805a2d42011-09-25 08:25:12 +00001891 if (color_correction_collection == (char *) NULL)
1892 break;
anthony92c93bd2012-03-19 14:02:47 +00001893 (void) ColorDecisionListImage(_image,color_correction_collection,
1894 _exception);
anthony805a2d42011-09-25 08:25:12 +00001895 break;
1896 }
anthonyafa3dfc2012-03-03 11:31:30 +00001897 if (LocaleCompare("charcoal",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001898 {
anthony7bcfe7f2012-03-30 14:01:22 +00001899 if (IfMagickFalse(IsGeometry(arg1)))
anthony5330ae02012-03-20 14:17:01 +00001900 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00001901 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00001902 if ((flags & SigmaValue) == 0)
1903 geometry_info.sigma=1.0;
1904 if ((flags & XiValue) == 0)
1905 geometry_info.xi=1.0;
anthony92c93bd2012-03-19 14:02:47 +00001906 new_image=CharcoalImage(_image,geometry_info.rho,
cristyaa2c16c2012-03-25 22:21:35 +00001907 geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00001908 break;
1909 }
anthonyafa3dfc2012-03-03 11:31:30 +00001910 if (LocaleCompare("chop",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001911 {
anthony7bcfe7f2012-03-30 14:01:22 +00001912 if (IfMagickFalse(IsGeometry(arg1)))
anthony5330ae02012-03-20 14:17:01 +00001913 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001914 (void) ParseGravityGeometry(_image,arg1,&geometry,_exception);
1915 new_image=ChopImage(_image,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00001916 break;
1917 }
anthonyafa3dfc2012-03-03 11:31:30 +00001918 if (LocaleCompare("clamp",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001919 {
anthony92c93bd2012-03-19 14:02:47 +00001920 (void) ClampImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00001921 break;
1922 }
anthonyafa3dfc2012-03-03 11:31:30 +00001923 if (LocaleCompare("clip",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001924 {
anthonyafa3dfc2012-03-03 11:31:30 +00001925 if (IfNormalOp)
anthony92c93bd2012-03-19 14:02:47 +00001926 (void) ClipImage(_image,_exception);
anthony43f425d2012-02-26 12:58:58 +00001927 else /* "+mask" remove the write mask */
anthony92c93bd2012-03-19 14:02:47 +00001928 (void) SetImageMask(_image,(Image *) NULL,_exception);
anthony805a2d42011-09-25 08:25:12 +00001929 break;
1930 }
anthonyafa3dfc2012-03-03 11:31:30 +00001931 if (LocaleCompare("clip-mask",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001932 {
1933 CacheView
1934 *mask_view;
1935
1936 Image
1937 *mask_image;
1938
1939 register Quantum
1940 *restrict q;
1941
1942 register ssize_t
1943 x;
1944
1945 ssize_t
1946 y;
1947
anthonyafa3dfc2012-03-03 11:31:30 +00001948 if (IfPlusOp) {
1949 /* "+clip-mask" Remove the write mask */
anthony92c93bd2012-03-19 14:02:47 +00001950 (void) SetImageMask(_image,(Image *) NULL,_exception);
anthonyafa3dfc2012-03-03 11:31:30 +00001951 break;
1952 }
anthony92c93bd2012-03-19 14:02:47 +00001953 mask_image=GetImageCache(_image_info,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00001954 if (mask_image == (Image *) NULL)
1955 break;
anthony7bcfe7f2012-03-30 14:01:22 +00001956 if (IfMagickFalse(SetImageStorageClass(mask_image,DirectClass,_exception)))
anthony31f1bf72012-01-30 12:37:22 +00001957 break;
anthony5330ae02012-03-20 14:17:01 +00001958 /* Create a write mask from cli_wand mask image */
anthonyfd706f92012-01-19 04:22:02 +00001959 /* FUTURE: use Alpha operations instead and create a Grey Image */
anthony805a2d42011-09-25 08:25:12 +00001960 mask_view=AcquireCacheView(mask_image);
1961 for (y=0; y < (ssize_t) mask_image->rows; y++)
1962 {
1963 q=GetCacheViewAuthenticPixels(mask_view,0,y,mask_image->columns,1,
anthony92c93bd2012-03-19 14:02:47 +00001964 _exception);
anthony805a2d42011-09-25 08:25:12 +00001965 if (q == (Quantum *) NULL)
1966 break;
1967 for (x=0; x < (ssize_t) mask_image->columns; x++)
1968 {
anthony7bcfe7f2012-03-30 14:01:22 +00001969 if (IfMagickFalse(mask_image->matte))
anthony805a2d42011-09-25 08:25:12 +00001970 SetPixelAlpha(mask_image,GetPixelIntensity(mask_image,q),q);
1971 SetPixelRed(mask_image,GetPixelAlpha(mask_image,q),q);
1972 SetPixelGreen(mask_image,GetPixelAlpha(mask_image,q),q);
1973 SetPixelBlue(mask_image,GetPixelAlpha(mask_image,q),q);
1974 q+=GetPixelChannels(mask_image);
1975 }
anthony7bcfe7f2012-03-30 14:01:22 +00001976 if (IfMagickFalse(SyncCacheViewAuthenticPixels(mask_view,_exception)))
anthony805a2d42011-09-25 08:25:12 +00001977 break;
1978 }
anthonyfd706f92012-01-19 04:22:02 +00001979 /* clean up and set the write mask */
anthony805a2d42011-09-25 08:25:12 +00001980 mask_view=DestroyCacheView(mask_view);
1981 mask_image->matte=MagickTrue;
anthony92c93bd2012-03-19 14:02:47 +00001982 (void) SetImageMask(_image,mask_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00001983 mask_image=DestroyImage(mask_image);
anthony805a2d42011-09-25 08:25:12 +00001984 break;
1985 }
anthonyafa3dfc2012-03-03 11:31:30 +00001986 if (LocaleCompare("clip-path",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001987 {
anthony92c93bd2012-03-19 14:02:47 +00001988 (void) ClipImagePath(_image,arg1,normal_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00001989 break;
1990 }
anthonyafa3dfc2012-03-03 11:31:30 +00001991 if (LocaleCompare("colorize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001992 {
anthony7bcfe7f2012-03-30 14:01:22 +00001993 if (IfMagickFalse(IsGeometry(arg1)))
anthony5330ae02012-03-20 14:17:01 +00001994 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001995 new_image=ColorizeImage(_image,arg1,&_draw_info->fill,_exception);
anthony805a2d42011-09-25 08:25:12 +00001996 break;
1997 }
anthonyafa3dfc2012-03-03 11:31:30 +00001998 if (LocaleCompare("color-matrix",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001999 {
2000 KernelInfo
2001 *kernel;
2002
anthonyfd706f92012-01-19 04:22:02 +00002003 kernel=AcquireKernelInfo(arg1);
anthony805a2d42011-09-25 08:25:12 +00002004 if (kernel == (KernelInfo *) NULL)
anthony5330ae02012-03-20 14:17:01 +00002005 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002006 new_image=ColorMatrixImage(_image,kernel,_exception);
anthony805a2d42011-09-25 08:25:12 +00002007 kernel=DestroyKernelInfo(kernel);
2008 break;
2009 }
anthonyafa3dfc2012-03-03 11:31:30 +00002010 if (LocaleCompare("colors",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002011 {
anthony5330ae02012-03-20 14:17:01 +00002012 /* Reduce the number of colors in the image.
2013 FUTURE: also provide 'plus version with image 'color counts'
anthonyfd706f92012-01-19 04:22:02 +00002014 */
anthony92c93bd2012-03-19 14:02:47 +00002015 _quantize_info->number_colors=StringToUnsignedLong(arg1);
2016 if (_quantize_info->number_colors == 0)
anthony5330ae02012-03-20 14:17:01 +00002017 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002018 if ((_image->storage_class == DirectClass) ||
2019 _image->colors > _quantize_info->number_colors)
2020 (void) QuantizeImage(_quantize_info,_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002021 else
anthony92c93bd2012-03-19 14:02:47 +00002022 (void) CompressImageColormap(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002023 break;
2024 }
anthonyafa3dfc2012-03-03 11:31:30 +00002025 if (LocaleCompare("colorspace",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002026 {
anthony5330ae02012-03-20 14:17:01 +00002027 /* WARNING: this is both a image_info setting (already done)
2028 and a operator to change image colorspace.
anthony31f1bf72012-01-30 12:37:22 +00002029
2030 FUTURE: default colorspace should be sRGB!
anthonyd2cdc862011-10-07 14:07:17 +00002031 Unless some type of 'linear colorspace' mode is set.
anthony31f1bf72012-01-30 12:37:22 +00002032
anthonyd2cdc862011-10-07 14:07:17 +00002033 Note that +colorspace sets "undefined" or no effect on
2034 new images, but forces images already in memory back to RGB!
anthony31f1bf72012-01-30 12:37:22 +00002035 That seems to be a little strange!
anthonyd2cdc862011-10-07 14:07:17 +00002036 */
anthony92c93bd2012-03-19 14:02:47 +00002037 (void) TransformImageColorspace(_image,
2038 IfNormalOp ? _image_info->colorspace : RGBColorspace,
2039 _exception);
anthony805a2d42011-09-25 08:25:12 +00002040 break;
2041 }
anthonyafa3dfc2012-03-03 11:31:30 +00002042 if (LocaleCompare("contrast",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002043 {
anthony975a8d72012-04-12 13:54:36 +00002044 CLIWandWarnDepreciated(normal_op?"-level":"+level");
anthony92c93bd2012-03-19 14:02:47 +00002045 (void) ContrastImage(_image,normal_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00002046 break;
2047 }
anthonyafa3dfc2012-03-03 11:31:30 +00002048 if (LocaleCompare("contrast-stretch",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002049 {
2050 double
2051 black_point,
2052 white_point;
2053
2054 MagickStatusType
2055 flags;
2056
anthony7bcfe7f2012-03-30 14:01:22 +00002057 if (IfMagickFalse(IsGeometry(arg1)))
anthonyebb73a22012-03-22 14:25:52 +00002058 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00002059 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002060 black_point=geometry_info.rho;
2061 white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
2062 black_point;
anthonyebb73a22012-03-22 14:25:52 +00002063 if ((flags & PercentValue) != 0) {
anthony92c93bd2012-03-19 14:02:47 +00002064 black_point*=(double) _image->columns*_image->rows/100.0;
2065 white_point*=(double) _image->columns*_image->rows/100.0;
anthony805a2d42011-09-25 08:25:12 +00002066 }
anthony92c93bd2012-03-19 14:02:47 +00002067 white_point=(MagickRealType) _image->columns*_image->rows-
anthony805a2d42011-09-25 08:25:12 +00002068 white_point;
anthony92c93bd2012-03-19 14:02:47 +00002069 (void) ContrastStretchImage(_image,black_point,white_point,
2070 _exception);
anthony805a2d42011-09-25 08:25:12 +00002071 break;
2072 }
anthonyafa3dfc2012-03-03 11:31:30 +00002073 if (LocaleCompare("convolve",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002074 {
2075 KernelInfo
2076 *kernel_info;
2077
anthonyfd706f92012-01-19 04:22:02 +00002078 kernel_info=AcquireKernelInfo(arg1);
anthony805a2d42011-09-25 08:25:12 +00002079 if (kernel_info == (KernelInfo *) NULL)
anthonyebb73a22012-03-22 14:25:52 +00002080 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyf46d4262012-03-26 03:30:34 +00002081 /* kernel_info->bias=_image->bias; -- FUTURE: check this path! */
anthony92c93bd2012-03-19 14:02:47 +00002082 new_image=ConvolveImage(_image,kernel_info,_exception);
anthony805a2d42011-09-25 08:25:12 +00002083 kernel_info=DestroyKernelInfo(kernel_info);
2084 break;
2085 }
anthonyafa3dfc2012-03-03 11:31:30 +00002086 if (LocaleCompare("crop",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002087 {
anthony31f1bf72012-01-30 12:37:22 +00002088 /* WARNING: This can generate multiple images! */
anthony7bcfe7f2012-03-30 14:01:22 +00002089 if (IfMagickFalse(IsGeometry(arg1)))
anthonyebb73a22012-03-22 14:25:52 +00002090 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002091 new_image=CropImageToTiles(_image,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00002092 break;
2093 }
anthonyafa3dfc2012-03-03 11:31:30 +00002094 if (LocaleCompare("cycle",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002095 {
anthony7bcfe7f2012-03-30 14:01:22 +00002096 if (IfMagickFalse(IsGeometry(arg1)))
anthonyebb73a22012-03-22 14:25:52 +00002097 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002098 (void) CycleColormapImage(_image,(ssize_t) StringToLong(arg1),
2099 _exception);
anthony805a2d42011-09-25 08:25:12 +00002100 break;
2101 }
anthonyebb73a22012-03-22 14:25:52 +00002102 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002103 }
2104 case 'd':
2105 {
anthonyafa3dfc2012-03-03 11:31:30 +00002106 if (LocaleCompare("decipher",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002107 {
2108 StringInfo
2109 *passkey;
2110
anthony92c93bd2012-03-19 14:02:47 +00002111 passkey=FileToStringInfo(arg1,~0,_exception);
anthonyebb73a22012-03-22 14:25:52 +00002112 if (passkey == (StringInfo *) NULL)
2113 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2114
2115 (void) PasskeyDecipherImage(_image,passkey,_exception);
2116 passkey=DestroyStringInfo(passkey);
anthony805a2d42011-09-25 08:25:12 +00002117 break;
2118 }
anthonyafa3dfc2012-03-03 11:31:30 +00002119 if (LocaleCompare("depth",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002120 {
anthony92c93bd2012-03-19 14:02:47 +00002121 /* The _image_info->depth setting has already been set
anthonydcf510d2011-10-30 13:51:40 +00002122 We just need to apply it to all images in current sequence
anthony31f1bf72012-01-30 12:37:22 +00002123
anthonydcf510d2011-10-30 13:51:40 +00002124 WARNING: Depth from 8 to 16 causes 'quantum rounding to images!
2125 That is it really is an operation, not a setting! Arrgghhh
anthony31f1bf72012-01-30 12:37:22 +00002126
anthonyfd706f92012-01-19 04:22:02 +00002127 FUTURE: this should not be an operator!!!
anthonydcf510d2011-10-30 13:51:40 +00002128 */
anthony92c93bd2012-03-19 14:02:47 +00002129 (void) SetImageDepth(_image,_image_info->depth,_exception);
anthony805a2d42011-09-25 08:25:12 +00002130 break;
2131 }
anthonyafa3dfc2012-03-03 11:31:30 +00002132 if (LocaleCompare("deskew",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002133 {
2134 double
2135 threshold;
2136
anthonyebb73a22012-03-22 14:25:52 +00002137 if (IfNormalOp) {
anthony7bcfe7f2012-03-30 14:01:22 +00002138 if (IfMagickFalse(IsGeometry(arg1)))
anthonyebb73a22012-03-22 14:25:52 +00002139 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00002140 threshold=StringToDoubleInterval(arg1,(double) QuantumRange+1.0);
anthonyebb73a22012-03-22 14:25:52 +00002141 }
anthonyafa3dfc2012-03-03 11:31:30 +00002142 else
2143 threshold=40.0*QuantumRange/100.0;
anthony92c93bd2012-03-19 14:02:47 +00002144 new_image=DeskewImage(_image,threshold,_exception);
anthony805a2d42011-09-25 08:25:12 +00002145 break;
2146 }
anthonyafa3dfc2012-03-03 11:31:30 +00002147 if (LocaleCompare("despeckle",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002148 {
anthony92c93bd2012-03-19 14:02:47 +00002149 new_image=DespeckleImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002150 break;
2151 }
anthonyafa3dfc2012-03-03 11:31:30 +00002152 if (LocaleCompare("distort",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002153 {
2154 char
2155 *args,
2156 token[MaxTextExtent];
2157
2158 const char
2159 *p;
2160
anthony805a2d42011-09-25 08:25:12 +00002161 double
2162 *arguments;
2163
2164 register ssize_t
2165 x;
2166
2167 size_t
2168 number_arguments;
2169
anthony2a0ec8c2012-03-24 04:35:56 +00002170 parse = ParseCommandOption(MagickDistortOptions,MagickFalse,arg1);
2171 if ( parse < 0 )
anthonyebb73a22012-03-22 14:25:52 +00002172 CLIWandExceptArgBreak(OptionError,"UnrecognizedDistortMethod",
2173 option,arg1);
anthony2a0ec8c2012-03-24 04:35:56 +00002174 if ((DistortImageMethod) parse == ResizeDistortion)
anthony805a2d42011-09-25 08:25:12 +00002175 {
anthony80c37752012-01-16 01:03:11 +00002176 double
2177 resize_args[2];
anthony805a2d42011-09-25 08:25:12 +00002178 /* Special Case - Argument is actually a resize geometry!
2179 ** Convert that to an appropriate distortion argument array.
anthonyfd706f92012-01-19 04:22:02 +00002180 ** FUTURE: make a separate special resize operator
anthonyfe1aa782012-03-24 13:43:04 +00002181 Roll into a resize special operator */
anthony7bcfe7f2012-03-30 14:01:22 +00002182 if (IfMagickFalse(IsGeometry(arg2)))
anthonyebb73a22012-03-22 14:25:52 +00002183 CLIWandExceptArgBreak(OptionError,"InvalidGeometry",
2184 option,arg2);
2185 (void) ParseRegionGeometry(_image,arg2,&geometry,_exception);
anthony80c37752012-01-16 01:03:11 +00002186 resize_args[0]=(double) geometry.width;
2187 resize_args[1]=(double) geometry.height;
anthony2a0ec8c2012-03-24 04:35:56 +00002188 new_image=DistortImage(_image,(DistortImageMethod) parse,
2189 (size_t)2,resize_args,MagickTrue,_exception);
anthony805a2d42011-09-25 08:25:12 +00002190 break;
2191 }
anthonyfd706f92012-01-19 04:22:02 +00002192 /* handle percent arguments */
anthonyebb73a22012-03-22 14:25:52 +00002193 args=InterpretImageProperties(_image_info,_image,arg2,_exception);
anthony805a2d42011-09-25 08:25:12 +00002194 if (args == (char *) NULL)
2195 break;
anthonyfd706f92012-01-19 04:22:02 +00002196 /* convert arguments into an array of doubles
2197 FUTURE: make this a separate function.
2198 Also make use of new 'sentinal' feature to avoid need for
2199 tokenization.
2200 */
anthony805a2d42011-09-25 08:25:12 +00002201 p=(char *) args;
2202 for (x=0; *p != '\0'; x++)
2203 {
2204 GetMagickToken(p,&p,token);
2205 if (*token == ',')
2206 GetMagickToken(p,&p,token);
2207 }
2208 number_arguments=(size_t) x;
2209 arguments=(double *) AcquireQuantumMemory(number_arguments,
2210 sizeof(*arguments));
2211 if (arguments == (double *) NULL)
anthonyebb73a22012-03-22 14:25:52 +00002212 CLIWandExceptionBreak(ResourceLimitFatalError,
2213 "MemoryAllocationFailed",option);
anthony805a2d42011-09-25 08:25:12 +00002214 (void) ResetMagickMemory(arguments,0,number_arguments*
anthonyebb73a22012-03-22 14:25:52 +00002215 sizeof(*arguments));
anthony805a2d42011-09-25 08:25:12 +00002216 p=(char *) args;
2217 for (x=0; (x < (ssize_t) number_arguments) && (*p != '\0'); x++)
2218 {
2219 GetMagickToken(p,&p,token);
2220 if (*token == ',')
2221 GetMagickToken(p,&p,token);
cristydbdd0e32011-11-04 23:29:40 +00002222 arguments[x]=StringToDouble(token,(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +00002223 }
2224 args=DestroyString(args);
anthony2a0ec8c2012-03-24 04:35:56 +00002225 new_image=DistortImage(_image,(DistortImageMethod) parse,
2226 number_arguments,arguments,plus_alt_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00002227 arguments=(double *) RelinquishMagickMemory(arguments);
2228 break;
2229 }
anthonyafa3dfc2012-03-03 11:31:30 +00002230 if (LocaleCompare("draw",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002231 {
anthony92c93bd2012-03-19 14:02:47 +00002232 (void) CloneString(&_draw_info->primitive,arg1);
2233 (void) DrawImage(_image,_draw_info,_exception);
2234 (void) CloneString(&_draw_info->primitive,(char *)NULL);
anthony805a2d42011-09-25 08:25:12 +00002235 break;
2236 }
anthonyebb73a22012-03-22 14:25:52 +00002237 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002238 }
2239 case 'e':
2240 {
anthonyafa3dfc2012-03-03 11:31:30 +00002241 if (LocaleCompare("edge",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002242 {
anthony7bcfe7f2012-03-30 14:01:22 +00002243 if (IfMagickFalse(IsGeometry(arg1)))
anthony2a0ec8c2012-03-24 04:35:56 +00002244 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00002245 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002246 if ((flags & SigmaValue) == 0)
2247 geometry_info.sigma=1.0;
anthony2a0ec8c2012-03-24 04:35:56 +00002248 new_image=EdgeImage(_image,geometry_info.rho,geometry_info.sigma,
2249 _exception);
anthony805a2d42011-09-25 08:25:12 +00002250 break;
2251 }
anthonyafa3dfc2012-03-03 11:31:30 +00002252 if (LocaleCompare("emboss",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002253 {
anthony7bcfe7f2012-03-30 14:01:22 +00002254 if (IfMagickFalse(IsGeometry(arg1)))
anthony2a0ec8c2012-03-24 04:35:56 +00002255 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00002256 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002257 if ((flags & SigmaValue) == 0)
2258 geometry_info.sigma=1.0;
anthony92c93bd2012-03-19 14:02:47 +00002259 new_image=EmbossImage(_image,geometry_info.rho,
2260 geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00002261 break;
2262 }
anthonyafa3dfc2012-03-03 11:31:30 +00002263 if (LocaleCompare("encipher",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002264 {
2265 StringInfo
2266 *passkey;
2267
anthony92c93bd2012-03-19 14:02:47 +00002268 passkey=FileToStringInfo(arg1,~0,_exception);
anthony805a2d42011-09-25 08:25:12 +00002269 if (passkey != (StringInfo *) NULL)
2270 {
anthony92c93bd2012-03-19 14:02:47 +00002271 (void) PasskeyEncipherImage(_image,passkey,_exception);
anthony805a2d42011-09-25 08:25:12 +00002272 passkey=DestroyStringInfo(passkey);
2273 }
2274 break;
2275 }
anthonyafa3dfc2012-03-03 11:31:30 +00002276 if (LocaleCompare("enhance",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002277 {
anthony92c93bd2012-03-19 14:02:47 +00002278 new_image=EnhanceImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002279 break;
2280 }
anthonyafa3dfc2012-03-03 11:31:30 +00002281 if (LocaleCompare("equalize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002282 {
anthony92c93bd2012-03-19 14:02:47 +00002283 (void) EqualizeImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002284 break;
2285 }
anthonyafa3dfc2012-03-03 11:31:30 +00002286 if (LocaleCompare("evaluate",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002287 {
2288 double
2289 constant;
2290
anthony2a0ec8c2012-03-24 04:35:56 +00002291 parse = ParseCommandOption(MagickEvaluateOptions,MagickFalse,arg1);
2292 if ( parse < 0 )
2293 CLIWandExceptArgBreak(OptionError,"UnrecognizedEvaluateOperator",
2294 option,arg1);
anthony7bcfe7f2012-03-30 14:01:22 +00002295 if (IfMagickFalse(IsGeometry(arg2)))
anthony2a0ec8c2012-03-24 04:35:56 +00002296 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
anthonyfd706f92012-01-19 04:22:02 +00002297 constant=StringToDoubleInterval(arg2,(double) QuantumRange+1.0);
anthony2a0ec8c2012-03-24 04:35:56 +00002298 (void) EvaluateImage(_image,(MagickEvaluateOperator)parse,constant,
2299 _exception);
anthony805a2d42011-09-25 08:25:12 +00002300 break;
2301 }
anthonyafa3dfc2012-03-03 11:31:30 +00002302 if (LocaleCompare("extent",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002303 {
anthony7bcfe7f2012-03-30 14:01:22 +00002304 if (IfMagickFalse(IsGeometry(arg1)))
anthony2a0ec8c2012-03-24 04:35:56 +00002305 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002306 flags=ParseGravityGeometry(_image,arg1,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00002307 if (geometry.width == 0)
anthony92c93bd2012-03-19 14:02:47 +00002308 geometry.width=_image->columns;
anthony805a2d42011-09-25 08:25:12 +00002309 if (geometry.height == 0)
anthony92c93bd2012-03-19 14:02:47 +00002310 geometry.height=_image->rows;
2311 new_image=ExtentImage(_image,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00002312 break;
2313 }
anthonyebb73a22012-03-22 14:25:52 +00002314 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002315 }
2316 case 'f':
2317 {
anthonyafa3dfc2012-03-03 11:31:30 +00002318 if (LocaleCompare("features",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002319 {
anthony31f1bf72012-01-30 12:37:22 +00002320 /* FUTURE: move to SyncImageSettings() and AcqireImage()??? */
anthonyafa3dfc2012-03-03 11:31:30 +00002321 if (IfPlusOp) {
anthony92c93bd2012-03-19 14:02:47 +00002322 (void) DeleteImageArtifact(_image,"identify:features");
anthony31f1bf72012-01-30 12:37:22 +00002323 break;
2324 }
anthony92c93bd2012-03-19 14:02:47 +00002325 (void) SetImageArtifact(_image,"identify:features","true");
2326 (void) SetImageArtifact(_image,"verbose","true");
anthony805a2d42011-09-25 08:25:12 +00002327 break;
2328 }
anthonyafa3dfc2012-03-03 11:31:30 +00002329 if (LocaleCompare("flip",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002330 {
anthony92c93bd2012-03-19 14:02:47 +00002331 new_image=FlipImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002332 break;
2333 }
anthonyafa3dfc2012-03-03 11:31:30 +00002334 if (LocaleCompare("flop",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002335 {
anthony92c93bd2012-03-19 14:02:47 +00002336 new_image=FlopImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002337 break;
2338 }
anthonyafa3dfc2012-03-03 11:31:30 +00002339 if (LocaleCompare("floodfill",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002340 {
2341 PixelInfo
2342 target;
2343
anthony7bcfe7f2012-03-30 14:01:22 +00002344 if (IfMagickFalse(IsGeometry(arg1)))
anthony2a0ec8c2012-03-24 04:35:56 +00002345 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002346 (void) ParsePageGeometry(_image,arg1,&geometry,_exception);
2347 (void) QueryColorCompliance(arg2,AllCompliance,&target,_exception);
2348 (void) FloodfillPaintImage(_image,_draw_info,&target,geometry.x,
2349 geometry.y,plus_alt_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00002350 break;
2351 }
anthonyafa3dfc2012-03-03 11:31:30 +00002352 if (LocaleCompare("frame",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002353 {
2354 FrameInfo
2355 frame_info;
2356
anthony31f1bf72012-01-30 12:37:22 +00002357 CompositeOperator
anthonyfd706f92012-01-19 04:22:02 +00002358 compose;
2359
2360 const char*
2361 value;
2362
anthony92c93bd2012-03-19 14:02:47 +00002363 value=GetImageOption(_image_info,"compose");
anthonyfd706f92012-01-19 04:22:02 +00002364 if (value != (const char *) NULL)
2365 compose=(CompositeOperator) ParseCommandOption(
2366 MagickComposeOptions,MagickFalse,value);
2367 else
anthony92c93bd2012-03-19 14:02:47 +00002368 compose=OverCompositeOp; /* use Over not _image->compose */
anthonyfd706f92012-01-19 04:22:02 +00002369
anthony7bcfe7f2012-03-30 14:01:22 +00002370 if (IfMagickFalse(IsGeometry(arg1)))
anthony2a0ec8c2012-03-24 04:35:56 +00002371 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002372 flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00002373 frame_info.width=geometry.width;
2374 frame_info.height=geometry.height;
2375 if ((flags & HeightValue) == 0)
2376 frame_info.height=geometry.width;
2377 frame_info.outer_bevel=geometry.x;
2378 frame_info.inner_bevel=geometry.y;
2379 frame_info.x=(ssize_t) frame_info.width;
2380 frame_info.y=(ssize_t) frame_info.height;
anthony92c93bd2012-03-19 14:02:47 +00002381 frame_info.width=_image->columns+2*frame_info.width;
2382 frame_info.height=_image->rows+2*frame_info.height;
2383 new_image=FrameImage(_image,&frame_info,compose,_exception);
anthony805a2d42011-09-25 08:25:12 +00002384 break;
2385 }
anthonyafa3dfc2012-03-03 11:31:30 +00002386 if (LocaleCompare("function",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002387 {
2388 char
2389 *arguments,
2390 token[MaxTextExtent];
2391
2392 const char
2393 *p;
2394
2395 double
2396 *parameters;
2397
anthony805a2d42011-09-25 08:25:12 +00002398 register ssize_t
2399 x;
2400
2401 size_t
2402 number_parameters;
2403
cristy947cb4c2011-10-20 18:41:46 +00002404 /*
2405 Function Modify Image Values
anthonyfd706f92012-01-19 04:22:02 +00002406 FUTURE: code should be almost a duplicate of that is "distort"
cristy947cb4c2011-10-20 18:41:46 +00002407 */
anthony2a0ec8c2012-03-24 04:35:56 +00002408 parse=ParseCommandOption(MagickFunctionOptions,MagickFalse,arg1);
2409 if ( parse < 0 )
2410 CLIWandExceptArgBreak(OptionError,"UnrecognizedFunction",
2411 option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002412 arguments=InterpretImageProperties(_image_info,_image,arg2,
2413 _exception);
anthony805a2d42011-09-25 08:25:12 +00002414 if (arguments == (char *) NULL)
anthony2a0ec8c2012-03-24 04:35:56 +00002415 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
anthony805a2d42011-09-25 08:25:12 +00002416 p=(char *) arguments;
2417 for (x=0; *p != '\0'; x++)
2418 {
2419 GetMagickToken(p,&p,token);
2420 if (*token == ',')
2421 GetMagickToken(p,&p,token);
2422 }
2423 number_parameters=(size_t) x;
2424 parameters=(double *) AcquireQuantumMemory(number_parameters,
2425 sizeof(*parameters));
2426 if (parameters == (double *) NULL)
2427 ThrowWandFatalException(ResourceLimitFatalError,
anthony92c93bd2012-03-19 14:02:47 +00002428 "MemoryAllocationFailed",_image->filename);
anthony805a2d42011-09-25 08:25:12 +00002429 (void) ResetMagickMemory(parameters,0,number_parameters*
2430 sizeof(*parameters));
2431 p=(char *) arguments;
anthony2a0ec8c2012-03-24 04:35:56 +00002432 for (x=0; (x < (ssize_t) number_parameters) && (*p != '\0'); x++) {
anthony805a2d42011-09-25 08:25:12 +00002433 GetMagickToken(p,&p,token);
2434 if (*token == ',')
2435 GetMagickToken(p,&p,token);
cristydbdd0e32011-11-04 23:29:40 +00002436 parameters[x]=StringToDouble(token,(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +00002437 }
2438 arguments=DestroyString(arguments);
anthony2a0ec8c2012-03-24 04:35:56 +00002439 (void) FunctionImage(_image,(MagickFunction)parse,number_parameters,
2440 parameters,_exception);
anthony805a2d42011-09-25 08:25:12 +00002441 parameters=(double *) RelinquishMagickMemory(parameters);
2442 break;
2443 }
anthonyebb73a22012-03-22 14:25:52 +00002444 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002445 }
2446 case 'g':
2447 {
anthonyafa3dfc2012-03-03 11:31:30 +00002448 if (LocaleCompare("gamma",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002449 {
anthony7bcfe7f2012-03-30 14:01:22 +00002450 if (IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00002451 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyafa3dfc2012-03-03 11:31:30 +00002452 if (IfNormalOp)
anthony92c93bd2012-03-19 14:02:47 +00002453 (void) GammaImage(_image,StringToDouble(arg1,(char **) NULL),
2454 _exception);
anthonyafa3dfc2012-03-03 11:31:30 +00002455 else
anthony92c93bd2012-03-19 14:02:47 +00002456 _image->gamma=StringToDouble(arg1,(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +00002457 break;
2458 }
anthony975a8d72012-04-12 13:54:36 +00002459 if (LocaleCompare("gaussian-blur",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002460 {
anthony7bcfe7f2012-03-30 14:01:22 +00002461 if (IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00002462 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00002463 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002464 if ((flags & SigmaValue) == 0)
2465 geometry_info.sigma=1.0;
anthony92c93bd2012-03-19 14:02:47 +00002466 new_image=GaussianBlurImage(_image,geometry_info.rho,
2467 geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00002468 break;
2469 }
anthony975a8d72012-04-12 13:54:36 +00002470 if (LocaleCompare("gaussian",option+1) == 0)
2471 {
2472 CLIWandWarnDepreciated("-gaussian-blur");
2473 CLISimpleOperatorImage(cli_wand,"-gaussian-blur",arg1,NULL);
2474 }
anthonyafa3dfc2012-03-03 11:31:30 +00002475 if (LocaleCompare("geometry",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002476 {
anthonyfd706f92012-01-19 04:22:02 +00002477 /*
anthony31f1bf72012-01-30 12:37:22 +00002478 Record Image offset for composition. (A Setting)
anthonyfe1aa782012-03-24 13:43:04 +00002479 Resize last _image. (ListOperator) -- DEPRECIATE
anthony31f1bf72012-01-30 12:37:22 +00002480 FUTURE: Why if no 'offset' does this resize ALL images?
2481 Also why is the setting recorded in the IMAGE non-sense!
anthonyfd706f92012-01-19 04:22:02 +00002482 */
anthonyafa3dfc2012-03-03 11:31:30 +00002483 if (IfPlusOp)
anthonyfd706f92012-01-19 04:22:02 +00002484 { /* remove the previous composition geometry offset! */
anthony92c93bd2012-03-19 14:02:47 +00002485 if (_image->geometry != (char *) NULL)
2486 _image->geometry=DestroyString(_image->geometry);
anthony805a2d42011-09-25 08:25:12 +00002487 break;
2488 }
anthony7bcfe7f2012-03-30 14:01:22 +00002489 if (IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00002490 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002491 flags=ParseRegionGeometry(_image,arg1,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00002492 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
anthony92c93bd2012-03-19 14:02:47 +00002493 (void) CloneString(&_image->geometry,arg1);
anthony805a2d42011-09-25 08:25:12 +00002494 else
anthony92c93bd2012-03-19 14:02:47 +00002495 new_image=ResizeImage(_image,geometry.width,geometry.height,
cristyaa2c16c2012-03-25 22:21:35 +00002496 _image->filter,_exception);
anthony805a2d42011-09-25 08:25:12 +00002497 break;
2498 }
anthonyebb73a22012-03-22 14:25:52 +00002499 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002500 }
2501 case 'h':
2502 {
anthonyafa3dfc2012-03-03 11:31:30 +00002503 if (LocaleCompare("highlight-color",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002504 {
anthony92c93bd2012-03-19 14:02:47 +00002505 (void) SetImageArtifact(_image,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +00002506 break;
2507 }
anthonyebb73a22012-03-22 14:25:52 +00002508 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002509 }
2510 case 'i':
2511 {
anthonyafa3dfc2012-03-03 11:31:30 +00002512 if (LocaleCompare("identify",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002513 {
anthony31f1bf72012-01-30 12:37:22 +00002514 const char
2515 *format,
anthony805a2d42011-09-25 08:25:12 +00002516 *text;
2517
anthony92c93bd2012-03-19 14:02:47 +00002518 format=GetImageOption(_image_info,"format");
anthony805a2d42011-09-25 08:25:12 +00002519 if (format == (char *) NULL)
2520 {
anthony92c93bd2012-03-19 14:02:47 +00002521 (void) IdentifyImage(_image,stdout,_image_info->verbose,
2522 _exception);
anthony805a2d42011-09-25 08:25:12 +00002523 break;
2524 }
anthony92c93bd2012-03-19 14:02:47 +00002525 text=InterpretImageProperties(_image_info,_image,format,_exception);
anthony805a2d42011-09-25 08:25:12 +00002526 if (text == (char *) NULL)
2527 break;
2528 (void) fputs(text,stdout);
2529 (void) fputc('\n',stdout);
anthony31f1bf72012-01-30 12:37:22 +00002530 text=DestroyString((char *)text);
anthony805a2d42011-09-25 08:25:12 +00002531 break;
2532 }
anthonyafa3dfc2012-03-03 11:31:30 +00002533 if (LocaleCompare("implode",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002534 {
anthony7bcfe7f2012-03-30 14:01:22 +00002535 if (IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00002536 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00002537 (void) ParseGeometry(arg1,&geometry_info);
anthony92c93bd2012-03-19 14:02:47 +00002538 new_image=ImplodeImage(_image,geometry_info.rho,
2539 _image->interpolate,_exception);
anthony805a2d42011-09-25 08:25:12 +00002540 break;
2541 }
anthonyafa3dfc2012-03-03 11:31:30 +00002542 if (LocaleCompare("interpolative-resize",option+1) == 0)
cristy947cb4c2011-10-20 18:41:46 +00002543 {
anthonyfe1aa782012-03-24 13:43:04 +00002544 /* FUTURE: New to IMv7
2545 Roll into a resize special operator */
anthony7bcfe7f2012-03-30 14:01:22 +00002546 if (IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00002547 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002548 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
2549 new_image=InterpolativeResizeImage(_image,geometry.width,
2550 geometry.height,_image->interpolate,_exception);
cristy947cb4c2011-10-20 18:41:46 +00002551 break;
2552 }
anthonyebb73a22012-03-22 14:25:52 +00002553 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002554 }
2555 case 'l':
2556 {
anthonyafa3dfc2012-03-03 11:31:30 +00002557 if (LocaleCompare("lat",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002558 {
anthony7bcfe7f2012-03-30 14:01:22 +00002559 if (IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00002560 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00002561 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002562 if ((flags & PercentValue) != 0)
2563 geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
anthony92c93bd2012-03-19 14:02:47 +00002564 new_image=AdaptiveThresholdImage(_image,(size_t) geometry_info.rho,
anthony31f1bf72012-01-30 12:37:22 +00002565 (size_t) geometry_info.sigma,(double) geometry_info.xi,
anthony92c93bd2012-03-19 14:02:47 +00002566 _exception);
anthony805a2d42011-09-25 08:25:12 +00002567 break;
2568 }
anthonyafa3dfc2012-03-03 11:31:30 +00002569 if (LocaleCompare("level",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002570 {
2571 MagickRealType
2572 black_point,
2573 gamma,
2574 white_point;
2575
2576 MagickStatusType
2577 flags;
2578
anthony7bcfe7f2012-03-30 14:01:22 +00002579 if (IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00002580 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00002581 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002582 black_point=geometry_info.rho;
2583 white_point=(MagickRealType) QuantumRange;
2584 if ((flags & SigmaValue) != 0)
2585 white_point=geometry_info.sigma;
2586 gamma=1.0;
2587 if ((flags & XiValue) != 0)
2588 gamma=geometry_info.xi;
2589 if ((flags & PercentValue) != 0)
2590 {
2591 black_point*=(MagickRealType) (QuantumRange/100.0);
2592 white_point*=(MagickRealType) (QuantumRange/100.0);
2593 }
2594 if ((flags & SigmaValue) == 0)
2595 white_point=(MagickRealType) QuantumRange-black_point;
anthonyafa3dfc2012-03-03 11:31:30 +00002596 if (IfPlusOp || ((flags & AspectValue) != 0))
anthony92c93bd2012-03-19 14:02:47 +00002597 (void) LevelizeImage(_image,black_point,white_point,gamma,_exception);
anthony805a2d42011-09-25 08:25:12 +00002598 else
anthony92c93bd2012-03-19 14:02:47 +00002599 (void) LevelImage(_image,black_point,white_point,gamma,_exception);
anthony805a2d42011-09-25 08:25:12 +00002600 break;
2601 }
anthonyafa3dfc2012-03-03 11:31:30 +00002602 if (LocaleCompare("level-colors",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002603 {
2604 char
2605 token[MaxTextExtent];
2606
2607 const char
2608 *p;
2609
2610 PixelInfo
2611 black_point,
2612 white_point;
2613
anthonyfd706f92012-01-19 04:22:02 +00002614 p=(const char *) arg1;
anthony805a2d42011-09-25 08:25:12 +00002615 GetMagickToken(p,&p,token); /* get black point color */
2616 if ((isalpha((int) *token) != 0) || ((*token == '#') != 0))
cristy269c9412011-10-13 23:41:15 +00002617 (void) QueryColorCompliance(token,AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +00002618 &black_point,_exception);
anthony805a2d42011-09-25 08:25:12 +00002619 else
cristy269c9412011-10-13 23:41:15 +00002620 (void) QueryColorCompliance("#000000",AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +00002621 &black_point,_exception);
anthony805a2d42011-09-25 08:25:12 +00002622 if (isalpha((int) token[0]) || (token[0] == '#'))
2623 GetMagickToken(p,&p,token);
2624 if (*token == '\0')
2625 white_point=black_point; /* set everything to that color */
2626 else
2627 {
2628 if ((isalpha((int) *token) == 0) && ((*token == '#') == 0))
2629 GetMagickToken(p,&p,token); /* Get white point color. */
2630 if ((isalpha((int) *token) != 0) || ((*token == '#') != 0))
cristy269c9412011-10-13 23:41:15 +00002631 (void) QueryColorCompliance(token,AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +00002632 &white_point,_exception);
anthony805a2d42011-09-25 08:25:12 +00002633 else
cristy269c9412011-10-13 23:41:15 +00002634 (void) QueryColorCompliance("#ffffff",AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +00002635 &white_point,_exception);
anthony805a2d42011-09-25 08:25:12 +00002636 }
anthony92c93bd2012-03-19 14:02:47 +00002637 (void) LevelImageColors(_image,&black_point,&white_point,
2638 plus_alt_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00002639 break;
2640 }
anthonyafa3dfc2012-03-03 11:31:30 +00002641 if (LocaleCompare("linear-stretch",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002642 {
2643 double
2644 black_point,
2645 white_point;
2646
2647 MagickStatusType
2648 flags;
2649
anthony7bcfe7f2012-03-30 14:01:22 +00002650 if (IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00002651 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00002652 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002653 black_point=geometry_info.rho;
anthony92c93bd2012-03-19 14:02:47 +00002654 white_point=(MagickRealType) _image->columns*_image->rows;
anthony805a2d42011-09-25 08:25:12 +00002655 if ((flags & SigmaValue) != 0)
2656 white_point=geometry_info.sigma;
2657 if ((flags & PercentValue) != 0)
2658 {
anthony92c93bd2012-03-19 14:02:47 +00002659 black_point*=(double) _image->columns*_image->rows/100.0;
2660 white_point*=(double) _image->columns*_image->rows/100.0;
anthony805a2d42011-09-25 08:25:12 +00002661 }
2662 if ((flags & SigmaValue) == 0)
anthony92c93bd2012-03-19 14:02:47 +00002663 white_point=(MagickRealType) _image->columns*_image->rows-
anthony805a2d42011-09-25 08:25:12 +00002664 black_point;
anthony92c93bd2012-03-19 14:02:47 +00002665 (void) LinearStretchImage(_image,black_point,white_point,_exception);
anthony805a2d42011-09-25 08:25:12 +00002666 break;
2667 }
anthonyafa3dfc2012-03-03 11:31:30 +00002668 if (LocaleCompare("liquid-rescale",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002669 {
anthonyfe1aa782012-03-24 13:43:04 +00002670 /* FUTURE: Roll into a resize special operator */
anthony7bcfe7f2012-03-30 14:01:22 +00002671 if (IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00002672 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002673 flags=ParseRegionGeometry(_image,arg1,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00002674 if ((flags & XValue) == 0)
2675 geometry.x=1;
2676 if ((flags & YValue) == 0)
2677 geometry.y=0;
anthony92c93bd2012-03-19 14:02:47 +00002678 new_image=LiquidRescaleImage(_image,geometry.width,
2679 geometry.height,1.0*geometry.x,1.0*geometry.y,_exception);
anthony805a2d42011-09-25 08:25:12 +00002680 break;
2681 }
anthonyebb73a22012-03-22 14:25:52 +00002682 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002683 }
2684 case 'm':
2685 {
anthonyafa3dfc2012-03-03 11:31:30 +00002686 if (LocaleCompare("map",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002687 {
anthony975a8d72012-04-12 13:54:36 +00002688 CLIWandWarnDepreciated("-remap");
2689 CLISimpleOperatorImage(cli_wand,"-remap",NULL,NULL);
anthony805a2d42011-09-25 08:25:12 +00002690 break;
2691 }
anthonyafa3dfc2012-03-03 11:31:30 +00002692 if (LocaleCompare("mask",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002693 {
2694 Image
2695 *mask;
2696
anthonyafa3dfc2012-03-03 11:31:30 +00002697 if (IfPlusOp)
anthony31f1bf72012-01-30 12:37:22 +00002698 { /* Remove a mask. */
anthony92c93bd2012-03-19 14:02:47 +00002699 (void) SetImageMask(_image,(Image *) NULL,_exception);
anthony805a2d42011-09-25 08:25:12 +00002700 break;
2701 }
anthony5330ae02012-03-20 14:17:01 +00002702 /* Set the image mask. */
anthony92c93bd2012-03-19 14:02:47 +00002703 mask=GetImageCache(_image_info,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00002704 if (mask == (Image *) NULL)
2705 break;
anthony92c93bd2012-03-19 14:02:47 +00002706 (void) SetImageMask(_image,mask,_exception);
anthony805a2d42011-09-25 08:25:12 +00002707 mask=DestroyImage(mask);
2708 break;
2709 }
anthonyafa3dfc2012-03-03 11:31:30 +00002710 if (LocaleCompare("matte",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002711 {
anthony975a8d72012-04-12 13:54:36 +00002712 CLIWandWarnDepreciated(IfNormalOp?"-alpha Set":"-alpha Off");
anthony92c93bd2012-03-19 14:02:47 +00002713 (void) SetImageAlphaChannel(_image,IfNormalOp ? SetAlphaChannel :
2714 DeactivateAlphaChannel, _exception);
anthony805a2d42011-09-25 08:25:12 +00002715 break;
2716 }
anthonya3ef4ed2012-03-17 06:52:53 +00002717 if (LocaleCompare("median",option+1) == 0)
2718 {
anthony975a8d72012-04-12 13:54:36 +00002719 CLIWandWarnDepreciated("-statistic Median");
anthonya3ef4ed2012-03-17 06:52:53 +00002720 CLISimpleOperatorImage(cli_wand,"-statistic","Median",arg1);
2721 break;
2722 }
anthonyafa3dfc2012-03-03 11:31:30 +00002723 if (LocaleCompare("mode",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002724 {
anthony975a8d72012-04-12 13:54:36 +00002725 /* FUTURE: note this is also a special "montage" option */
2726 CLIWandWarnDepreciated("-statistic Mode");
2727 CLISimpleOperatorImage(cli_wand,"-statistic","Mode",arg1);
anthony805a2d42011-09-25 08:25:12 +00002728 break;
2729 }
anthonyafa3dfc2012-03-03 11:31:30 +00002730 if (LocaleCompare("modulate",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002731 {
anthony7bcfe7f2012-03-30 14:01:22 +00002732 if (IfMagickFalse(IsGeometry(arg1)))
anthony7bc87992012-03-25 02:32:51 +00002733 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002734 (void) ModulateImage(_image,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00002735 break;
2736 }
anthonyafa3dfc2012-03-03 11:31:30 +00002737 if (LocaleCompare("monitor",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002738 {
anthony92c93bd2012-03-19 14:02:47 +00002739 (void) SetImageProgressMonitor(_image, IfNormalOp ? MonitorProgress :
anthonyafa3dfc2012-03-03 11:31:30 +00002740 (MagickProgressMonitor) NULL,(void *) NULL);
anthony805a2d42011-09-25 08:25:12 +00002741 break;
2742 }
anthonyafa3dfc2012-03-03 11:31:30 +00002743 if (LocaleCompare("monochrome",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002744 {
anthony92c93bd2012-03-19 14:02:47 +00002745 (void) SetImageType(_image,BilevelType,_exception);
anthony805a2d42011-09-25 08:25:12 +00002746 break;
2747 }
anthonyafa3dfc2012-03-03 11:31:30 +00002748 if (LocaleCompare("morphology",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002749 {
2750 char
2751 token[MaxTextExtent];
2752
2753 const char
2754 *p;
2755
2756 KernelInfo
2757 *kernel;
2758
anthony805a2d42011-09-25 08:25:12 +00002759 ssize_t
2760 iterations;
2761
anthonyfd706f92012-01-19 04:22:02 +00002762 p=arg1;
anthony805a2d42011-09-25 08:25:12 +00002763 GetMagickToken(p,&p,token);
anthony7bc87992012-03-25 02:32:51 +00002764 parse=ParseCommandOption(MagickMorphologyOptions,MagickFalse,token);
2765 if ( parse < 0 )
2766 CLIWandExceptArgBreak(OptionError,"UnrecognizedFunction",
2767 option,arg1);
anthony805a2d42011-09-25 08:25:12 +00002768 iterations=1L;
2769 GetMagickToken(p,&p,token);
2770 if ((*p == ':') || (*p == ','))
2771 GetMagickToken(p,&p,token);
2772 if ((*p != '\0'))
2773 iterations=(ssize_t) StringToLong(p);
anthonyfd706f92012-01-19 04:22:02 +00002774 kernel=AcquireKernelInfo(arg2);
anthony805a2d42011-09-25 08:25:12 +00002775 if (kernel == (KernelInfo *) NULL)
anthony7bc87992012-03-25 02:32:51 +00002776 CLIWandExceptArgBreak(OptionError,"UnabletoParseKernel",
2777 option,arg2);
2778 new_image=MorphologyImage(_image,(MorphologyMethod)parse,
2779 iterations,kernel,_exception);
anthony805a2d42011-09-25 08:25:12 +00002780 kernel=DestroyKernelInfo(kernel);
2781 break;
2782 }
anthonyafa3dfc2012-03-03 11:31:30 +00002783 if (LocaleCompare("motion-blur",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002784 {
anthony7bcfe7f2012-03-30 14:01:22 +00002785 if (IfMagickFalse(IsGeometry(arg1)))
anthony7bc87992012-03-25 02:32:51 +00002786 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00002787 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002788 if ((flags & SigmaValue) == 0)
2789 geometry_info.sigma=1.0;
anthony92c93bd2012-03-19 14:02:47 +00002790 new_image=MotionBlurImage(_image,geometry_info.rho,
cristyaa2c16c2012-03-25 22:21:35 +00002791 geometry_info.sigma,geometry_info.xi,_exception);
anthony805a2d42011-09-25 08:25:12 +00002792 break;
2793 }
anthonyebb73a22012-03-22 14:25:52 +00002794 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002795 }
2796 case 'n':
2797 {
anthonyafa3dfc2012-03-03 11:31:30 +00002798 if (LocaleCompare("negate",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002799 {
anthony92c93bd2012-03-19 14:02:47 +00002800 (void) NegateImage(_image, plus_alt_op, _exception);
anthony805a2d42011-09-25 08:25:12 +00002801 break;
2802 }
anthonyafa3dfc2012-03-03 11:31:30 +00002803 if (LocaleCompare("noise",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002804 {
anthony975a8d72012-04-12 13:54:36 +00002805 double
2806 attenuate;
2807
2808 const char*
2809 value;
2810
anthonyafa3dfc2012-03-03 11:31:30 +00002811 if (IfNormalOp)
anthony805a2d42011-09-25 08:25:12 +00002812 {
anthony975a8d72012-04-12 13:54:36 +00002813 CLIWandWarnDepreciated("-statistic NonPeak");
2814 CLISimpleOperatorImage(cli_wand,"-statistic","NonPeak",arg1);
2815 break;
anthony805a2d42011-09-25 08:25:12 +00002816 }
anthony975a8d72012-04-12 13:54:36 +00002817 parse=ParseCommandOption(MagickNoiseOptions,MagickFalse,arg1);
2818 if ( parse < 0 )
2819 CLIWandExceptArgBreak(OptionError,"UnrecognizedNoiseType",
2820 option,arg1);
2821 attenuate=1.0;
2822 value=GetImageOption(_image_info,"attenuate");
2823 if (value != (const char *) NULL)
2824 attenuate=StringToDouble(value,(char **) NULL);
2825 new_image=AddNoiseImage(_image,(NoiseType)parse,attenuate,
2826 _exception);
anthony805a2d42011-09-25 08:25:12 +00002827 break;
2828 }
anthonyafa3dfc2012-03-03 11:31:30 +00002829 if (LocaleCompare("normalize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002830 {
anthony92c93bd2012-03-19 14:02:47 +00002831 (void) NormalizeImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002832 break;
2833 }
anthonyebb73a22012-03-22 14:25:52 +00002834 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002835 }
2836 case 'o':
2837 {
anthonyafa3dfc2012-03-03 11:31:30 +00002838 if (LocaleCompare("opaque",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002839 {
2840 PixelInfo
2841 target;
2842
anthony92c93bd2012-03-19 14:02:47 +00002843 (void) QueryColorCompliance(arg1,AllCompliance,&target,_exception);
2844 (void) OpaquePaintImage(_image,&target,&_draw_info->fill,plus_alt_op,
2845 _exception);
anthony805a2d42011-09-25 08:25:12 +00002846 break;
2847 }
anthonyafa3dfc2012-03-03 11:31:30 +00002848 if (LocaleCompare("ordered-dither",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002849 {
anthony92c93bd2012-03-19 14:02:47 +00002850 (void) OrderedPosterizeImage(_image,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00002851 break;
2852 }
anthonyebb73a22012-03-22 14:25:52 +00002853 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002854 }
2855 case 'p':
2856 {
anthonyafa3dfc2012-03-03 11:31:30 +00002857 if (LocaleCompare("paint",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002858 {
anthonyfd706f92012-01-19 04:22:02 +00002859 (void) ParseGeometry(arg1,&geometry_info);
anthony92c93bd2012-03-19 14:02:47 +00002860 new_image=OilPaintImage(_image,geometry_info.rho,geometry_info.sigma,
2861 _exception);
anthony805a2d42011-09-25 08:25:12 +00002862 break;
2863 }
anthonyafa3dfc2012-03-03 11:31:30 +00002864 if (LocaleCompare("polaroid",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002865 {
cristye9e3d382011-12-14 01:50:13 +00002866 const char
2867 *caption;
2868
anthony805a2d42011-09-25 08:25:12 +00002869 double
2870 angle;
2871
anthony7bc87992012-03-25 02:32:51 +00002872 if (IfPlusOp) {
anthonyf42014d2012-03-25 09:53:06 +00002873 RandomInfo
2874 *random_info;
anthony805a2d42011-09-25 08:25:12 +00002875
anthonyf42014d2012-03-25 09:53:06 +00002876 random_info=AcquireRandomInfo();
2877 angle=22.5*(GetPseudoRandomValue(random_info)-0.5);
2878 random_info=DestroyRandomInfo(random_info);
2879 }
anthony7bc87992012-03-25 02:32:51 +00002880 else {
anthony7bcfe7f2012-03-30 14:01:22 +00002881 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00002882 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2883 flags=ParseGeometry(arg1,&geometry_info);
2884 angle=geometry_info.rho;
2885 }
anthony92c93bd2012-03-19 14:02:47 +00002886 caption=GetImageProperty(_image,"caption",_exception);
2887 new_image=PolaroidImage(_image,_draw_info,caption,angle,
2888 _image->interpolate,_exception);
anthony805a2d42011-09-25 08:25:12 +00002889 break;
2890 }
anthonyafa3dfc2012-03-03 11:31:30 +00002891 if (LocaleCompare("posterize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002892 {
anthony7bcfe7f2012-03-30 14:01:22 +00002893 if (IfMagickFalse(IsGeometry(arg1)))
anthony7bc87992012-03-25 02:32:51 +00002894 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony31f1bf72012-01-30 12:37:22 +00002895 (void) ParseGeometry(arg1,&geometry_info);
anthony92c93bd2012-03-19 14:02:47 +00002896 (void) PosterizeImage(_image,(size_t) geometry_info.rho,
2897 _quantize_info->dither,_exception);
anthony805a2d42011-09-25 08:25:12 +00002898 break;
2899 }
anthonyafa3dfc2012-03-03 11:31:30 +00002900 if (LocaleCompare("preview",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002901 {
anthony31f1bf72012-01-30 12:37:22 +00002902 /* FUTURE: should be a 'Genesis' option?
2903 Option however is also in WandSettingOptionInfo()
anthony7bc87992012-03-25 02:32:51 +00002904 Why???
cristy947cb4c2011-10-20 18:41:46 +00002905 */
anthony7bc87992012-03-25 02:32:51 +00002906 parse=ParseCommandOption(MagickPreviewOptions, MagickFalse,arg1);
2907 if ( parse < 0 )
2908 CLIWandExceptArgBreak(OptionError,"UnrecognizedPreviewType",
2909 option,arg1);
2910 new_image=PreviewImage(_image,(PreviewType)parse,_exception);
anthony805a2d42011-09-25 08:25:12 +00002911 break;
2912 }
anthonyafa3dfc2012-03-03 11:31:30 +00002913 if (LocaleCompare("profile",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002914 {
2915 const char
2916 *name;
2917
2918 const StringInfo
2919 *profile;
2920
2921 Image
2922 *profile_image;
2923
2924 ImageInfo
2925 *profile_info;
2926
anthonyafa3dfc2012-03-03 11:31:30 +00002927 if (IfPlusOp)
anthony92c93bd2012-03-19 14:02:47 +00002928 { /* Remove a profile from the _image. */
2929 (void) ProfileImage(_image,arg1,(const unsigned char *)
2930 NULL,0,_exception);
anthony805a2d42011-09-25 08:25:12 +00002931 break;
2932 }
anthony92c93bd2012-03-19 14:02:47 +00002933 /* Associate a profile with the _image. */
2934 profile_info=CloneImageInfo(_image_info);
2935 profile=GetImageProfile(_image,"iptc");
anthony805a2d42011-09-25 08:25:12 +00002936 if (profile != (StringInfo *) NULL)
2937 profile_info->profile=(void *) CloneStringInfo(profile);
anthony92c93bd2012-03-19 14:02:47 +00002938 profile_image=GetImageCache(profile_info,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00002939 profile_info=DestroyImageInfo(profile_info);
2940 if (profile_image == (Image *) NULL)
2941 {
2942 StringInfo
2943 *profile;
2944
anthony92c93bd2012-03-19 14:02:47 +00002945 profile_info=CloneImageInfo(_image_info);
anthonyfd706f92012-01-19 04:22:02 +00002946 (void) CopyMagickString(profile_info->filename,arg1,
anthony805a2d42011-09-25 08:25:12 +00002947 MaxTextExtent);
anthony92c93bd2012-03-19 14:02:47 +00002948 profile=FileToStringInfo(profile_info->filename,~0UL,_exception);
anthony805a2d42011-09-25 08:25:12 +00002949 if (profile != (StringInfo *) NULL)
2950 {
anthony92c93bd2012-03-19 14:02:47 +00002951 (void) ProfileImage(_image,profile_info->magick,
anthony805a2d42011-09-25 08:25:12 +00002952 GetStringInfoDatum(profile),(size_t)
anthony92c93bd2012-03-19 14:02:47 +00002953 GetStringInfoLength(profile),_exception);
anthony805a2d42011-09-25 08:25:12 +00002954 profile=DestroyStringInfo(profile);
2955 }
2956 profile_info=DestroyImageInfo(profile_info);
2957 break;
2958 }
2959 ResetImageProfileIterator(profile_image);
2960 name=GetNextImageProfile(profile_image);
2961 while (name != (const char *) NULL)
2962 {
2963 profile=GetImageProfile(profile_image,name);
2964 if (profile != (StringInfo *) NULL)
anthony92c93bd2012-03-19 14:02:47 +00002965 (void) ProfileImage(_image,name,GetStringInfoDatum(profile),
2966 (size_t) GetStringInfoLength(profile),_exception);
anthony805a2d42011-09-25 08:25:12 +00002967 name=GetNextImageProfile(profile_image);
2968 }
2969 profile_image=DestroyImage(profile_image);
2970 break;
2971 }
anthonyebb73a22012-03-22 14:25:52 +00002972 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002973 }
anthony805a2d42011-09-25 08:25:12 +00002974 case 'r':
2975 {
anthonyafa3dfc2012-03-03 11:31:30 +00002976 if (LocaleCompare("radial-blur",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002977 {
anthony7bcfe7f2012-03-30 14:01:22 +00002978 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00002979 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00002980 flags=ParseGeometry(arg1,&geometry_info);
cristyaa2c16c2012-03-25 22:21:35 +00002981 new_image=RadialBlurImage(_image,geometry_info.rho,_exception);
anthony805a2d42011-09-25 08:25:12 +00002982 break;
2983 }
anthonyafa3dfc2012-03-03 11:31:30 +00002984 if (LocaleCompare("raise",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002985 {
anthony7bcfe7f2012-03-30 14:01:22 +00002986 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00002987 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002988 flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00002989 if ((flags & SigmaValue) == 0)
2990 geometry.height=geometry.width;
anthony92c93bd2012-03-19 14:02:47 +00002991 (void) RaiseImage(_image,&geometry,normal_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00002992 break;
2993 }
anthonyafa3dfc2012-03-03 11:31:30 +00002994 if (LocaleCompare("random-threshold",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002995 {
anthony7bcfe7f2012-03-30 14:01:22 +00002996 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00002997 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002998 (void) RandomThresholdImage(_image,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00002999 break;
3000 }
anthony975a8d72012-04-12 13:54:36 +00003001 if (LocaleCompare("recolor",option+1) == 0)
3002 {
3003 CLIWandWarnDepreciated("-color-matrix");
3004 CLISimpleOperatorImage(cli_wand,"-color-matrix",arg1,NULL);
3005 }
anthonyafa3dfc2012-03-03 11:31:30 +00003006 if (LocaleCompare("remap",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003007 {
3008 Image
3009 *remap_image;
3010
anthony92c93bd2012-03-19 14:02:47 +00003011 remap_image=GetImageCache(_image_info,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00003012 if (remap_image == (Image *) NULL)
3013 break;
anthony92c93bd2012-03-19 14:02:47 +00003014 (void) RemapImage(_quantize_info,_image,remap_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00003015 remap_image=DestroyImage(remap_image);
3016 break;
3017 }
anthonyafa3dfc2012-03-03 11:31:30 +00003018 if (LocaleCompare("repage",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003019 {
anthonyafa3dfc2012-03-03 11:31:30 +00003020 if (IfNormalOp)
cristy0d0de742012-03-25 19:32:48 +00003021 {
anthony7bcfe7f2012-03-30 14:01:22 +00003022 if (IfMagickFalse(IsGeometry(arg1)))
cristy0d0de742012-03-25 19:32:48 +00003023 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,
3024 arg1);
3025 (void) ResetImagePage(_image,arg1);
3026 }
anthony31f1bf72012-01-30 12:37:22 +00003027 else
anthony92c93bd2012-03-19 14:02:47 +00003028 (void) ParseAbsoluteGeometry("0x0+0+0",&_image->page);
anthony805a2d42011-09-25 08:25:12 +00003029 break;
3030 }
anthonyafa3dfc2012-03-03 11:31:30 +00003031 if (LocaleCompare("resample",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003032 {
anthonyf46d4262012-03-26 03:30:34 +00003033 /* FUTURE: Roll into a resize special operation */
anthony7bcfe7f2012-03-30 14:01:22 +00003034 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003035 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00003036 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003037 if ((flags & SigmaValue) == 0)
3038 geometry_info.sigma=geometry_info.rho;
anthony92c93bd2012-03-19 14:02:47 +00003039 new_image=ResampleImage(_image,geometry_info.rho,
cristyaa2c16c2012-03-25 22:21:35 +00003040 geometry_info.sigma,_image->filter,_exception);
anthony805a2d42011-09-25 08:25:12 +00003041 break;
3042 }
anthonyafa3dfc2012-03-03 11:31:30 +00003043 if (LocaleCompare("resize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003044 {
anthony7bcfe7f2012-03-30 14:01:22 +00003045 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003046 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003047 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
3048 new_image=ResizeImage(_image,geometry.width,geometry.height,
cristyaa2c16c2012-03-25 22:21:35 +00003049 _image->filter,_exception);
anthony805a2d42011-09-25 08:25:12 +00003050 break;
3051 }
anthonyafa3dfc2012-03-03 11:31:30 +00003052 if (LocaleCompare("roll",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003053 {
anthony7bcfe7f2012-03-30 14:01:22 +00003054 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003055 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003056 (void) ParsePageGeometry(_image,arg1,&geometry,_exception);
3057 new_image=RollImage(_image,geometry.x,geometry.y,_exception);
anthony805a2d42011-09-25 08:25:12 +00003058 break;
3059 }
anthonyafa3dfc2012-03-03 11:31:30 +00003060 if (LocaleCompare("rotate",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003061 {
anthony7bcfe7f2012-03-30 14:01:22 +00003062 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003063 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00003064 if (strchr(arg1,'>') != (char *) NULL)
anthony92c93bd2012-03-19 14:02:47 +00003065 if (_image->columns <= _image->rows)
anthony805a2d42011-09-25 08:25:12 +00003066 break;
anthonyfd706f92012-01-19 04:22:02 +00003067 if (strchr(arg1,'<') != (char *) NULL)
anthony92c93bd2012-03-19 14:02:47 +00003068 if (_image->columns >= _image->rows)
anthony805a2d42011-09-25 08:25:12 +00003069 break;
anthonyfd706f92012-01-19 04:22:02 +00003070 (void) ParseGeometry(arg1,&geometry_info);
anthony92c93bd2012-03-19 14:02:47 +00003071 new_image=RotateImage(_image,geometry_info.rho,_exception);
anthony805a2d42011-09-25 08:25:12 +00003072 break;
3073 }
anthonyebb73a22012-03-22 14:25:52 +00003074 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003075 }
3076 case 's':
3077 {
anthonyafa3dfc2012-03-03 11:31:30 +00003078 if (LocaleCompare("sample",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003079 {
anthonyfe1aa782012-03-24 13:43:04 +00003080 /* FUTURE: Roll into a resize special operator */
anthony7bcfe7f2012-03-30 14:01:22 +00003081 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003082 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003083 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
3084 new_image=SampleImage(_image,geometry.width,geometry.height,
3085 _exception);
anthony805a2d42011-09-25 08:25:12 +00003086 break;
3087 }
anthonyafa3dfc2012-03-03 11:31:30 +00003088 if (LocaleCompare("scale",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003089 {
anthonyfe1aa782012-03-24 13:43:04 +00003090 /* FUTURE: Roll into a resize special operator */
anthony7bcfe7f2012-03-30 14:01:22 +00003091 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003092 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003093 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
3094 new_image=ScaleImage(_image,geometry.width,geometry.height,
3095 _exception);
anthony805a2d42011-09-25 08:25:12 +00003096 break;
3097 }
anthonyf42014d2012-03-25 09:53:06 +00003098 if (LocaleCompare("segment",option+1) == 0)
3099 {
anthony7bcfe7f2012-03-30 14:01:22 +00003100 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003101 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3102 flags=ParseGeometry(arg1,&geometry_info);
3103 if ((flags & SigmaValue) == 0)
3104 geometry_info.sigma=1.0;
3105 (void) SegmentImage(_image,_image->colorspace,
3106 _image_info->verbose,geometry_info.rho,geometry_info.sigma,
3107 _exception);
3108 break;
3109 }
anthonyafa3dfc2012-03-03 11:31:30 +00003110 if (LocaleCompare("selective-blur",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003111 {
anthony7bcfe7f2012-03-30 14:01:22 +00003112 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003113 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00003114 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003115 if ((flags & PercentValue) != 0)
3116 geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
anthony92c93bd2012-03-19 14:02:47 +00003117 new_image=SelectiveBlurImage(_image,geometry_info.rho,
cristyaa2c16c2012-03-25 22:21:35 +00003118 geometry_info.sigma,geometry_info.xi,_exception);
anthony805a2d42011-09-25 08:25:12 +00003119 break;
3120 }
anthonyafa3dfc2012-03-03 11:31:30 +00003121 if (LocaleCompare("separate",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003122 {
anthony31f1bf72012-01-30 12:37:22 +00003123 /* WARNING: This can generate multiple images! */
anthony43f425d2012-02-26 12:58:58 +00003124 /* FUTURE - this may be replaced by a "-channel" method */
cristydfdb19e2012-03-21 22:22:24 +00003125 new_image=SeparateImages(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00003126 break;
3127 }
anthonyafa3dfc2012-03-03 11:31:30 +00003128 if (LocaleCompare("sepia-tone",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003129 {
anthony7bcfe7f2012-03-30 14:01:22 +00003130 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003131 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3132 new_image=SepiaToneImage(_image,StringToDoubleInterval(arg1,
3133 (double) QuantumRange+1.0),_exception);
anthony805a2d42011-09-25 08:25:12 +00003134 break;
3135 }
anthonyafa3dfc2012-03-03 11:31:30 +00003136 if (LocaleCompare("set",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003137 {
3138 char
3139 *value;
3140
anthonyf42014d2012-03-25 09:53:06 +00003141 if (IfPlusOp) {
anthonyfd706f92012-01-19 04:22:02 +00003142 if (LocaleNCompare(arg1,"registry:",9) == 0)
3143 (void) DeleteImageRegistry(arg1+9);
anthony805a2d42011-09-25 08:25:12 +00003144 else
anthony31f1bf72012-01-30 12:37:22 +00003145 if (LocaleNCompare(arg1,"option:",7) == 0)
anthony805a2d42011-09-25 08:25:12 +00003146 {
anthony92c93bd2012-03-19 14:02:47 +00003147 (void) DeleteImageOption(_image_info,arg1+7);
3148 (void) DeleteImageArtifact(_image,arg1+7);
anthony805a2d42011-09-25 08:25:12 +00003149 }
3150 else
anthony92c93bd2012-03-19 14:02:47 +00003151 (void) DeleteImageProperty(_image,arg1);
anthony805a2d42011-09-25 08:25:12 +00003152 break;
3153 }
anthonyf42014d2012-03-25 09:53:06 +00003154 value=InterpretImageProperties(_image_info,_image,arg2,_exception);
anthony805a2d42011-09-25 08:25:12 +00003155 if (value == (char *) NULL)
3156 break;
anthonyfd706f92012-01-19 04:22:02 +00003157 if (LocaleNCompare(arg1,"registry:",9) == 0)
anthonyf42014d2012-03-25 09:53:06 +00003158 (void) SetImageRegistry(StringRegistryType,arg1+9,value,_exception);
anthony805a2d42011-09-25 08:25:12 +00003159 else
anthonyfd706f92012-01-19 04:22:02 +00003160 if (LocaleNCompare(arg1,"option:",7) == 0)
anthony805a2d42011-09-25 08:25:12 +00003161 {
anthony92c93bd2012-03-19 14:02:47 +00003162 (void) SetImageOption(_image_info,arg1+7,value);
3163 (void) SetImageArtifact(_image,arg1+7,value);
anthony805a2d42011-09-25 08:25:12 +00003164 }
3165 else
anthony92c93bd2012-03-19 14:02:47 +00003166 (void) SetImageProperty(_image,arg1,value,_exception);
anthony805a2d42011-09-25 08:25:12 +00003167 value=DestroyString(value);
3168 break;
3169 }
anthonyafa3dfc2012-03-03 11:31:30 +00003170 if (LocaleCompare("shade",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003171 {
anthony7bcfe7f2012-03-30 14:01:22 +00003172 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003173 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00003174 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003175 if ((flags & SigmaValue) == 0)
3176 geometry_info.sigma=1.0;
anthony92c93bd2012-03-19 14:02:47 +00003177 new_image=ShadeImage(_image,normal_op,geometry_info.rho,
3178 geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00003179 break;
3180 }
anthonyafa3dfc2012-03-03 11:31:30 +00003181 if (LocaleCompare("shadow",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003182 {
anthony7bcfe7f2012-03-30 14:01:22 +00003183 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003184 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00003185 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003186 if ((flags & SigmaValue) == 0)
3187 geometry_info.sigma=1.0;
3188 if ((flags & XiValue) == 0)
3189 geometry_info.xi=4.0;
3190 if ((flags & PsiValue) == 0)
3191 geometry_info.psi=4.0;
cristyaa2c16c2012-03-25 22:21:35 +00003192 new_image=ShadowImage(_image,geometry_info.rho,geometry_info.sigma,
3193 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
3194 ceil(geometry_info.psi-0.5),_exception);
anthony805a2d42011-09-25 08:25:12 +00003195 break;
3196 }
anthonyafa3dfc2012-03-03 11:31:30 +00003197 if (LocaleCompare("sharpen",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003198 {
anthony7bcfe7f2012-03-30 14:01:22 +00003199 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003200 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00003201 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003202 if ((flags & SigmaValue) == 0)
3203 geometry_info.sigma=1.0;
3204 if ((flags & XiValue) == 0)
3205 geometry_info.xi=0.0;
cristyaa2c16c2012-03-25 22:21:35 +00003206 new_image=SharpenImage(_image,geometry_info.rho,geometry_info.sigma,
3207 _exception);
anthony805a2d42011-09-25 08:25:12 +00003208 break;
3209 }
anthonyafa3dfc2012-03-03 11:31:30 +00003210 if (LocaleCompare("shave",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003211 {
anthony7bcfe7f2012-03-30 14:01:22 +00003212 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003213 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003214 flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
3215 new_image=ShaveImage(_image,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00003216 break;
3217 }
anthonyafa3dfc2012-03-03 11:31:30 +00003218 if (LocaleCompare("shear",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003219 {
anthony7bcfe7f2012-03-30 14:01:22 +00003220 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003221 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00003222 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003223 if ((flags & SigmaValue) == 0)
3224 geometry_info.sigma=geometry_info.rho;
anthony92c93bd2012-03-19 14:02:47 +00003225 new_image=ShearImage(_image,geometry_info.rho,
3226 geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00003227 break;
3228 }
anthonyafa3dfc2012-03-03 11:31:30 +00003229 if (LocaleCompare("sigmoidal-contrast",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003230 {
anthony7bcfe7f2012-03-30 14:01:22 +00003231 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003232 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00003233 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003234 if ((flags & SigmaValue) == 0)
3235 geometry_info.sigma=(double) QuantumRange/2.0;
3236 if ((flags & PercentValue) != 0)
3237 geometry_info.sigma=(double) QuantumRange*geometry_info.sigma/
3238 100.0;
anthony92c93bd2012-03-19 14:02:47 +00003239 (void) SigmoidalContrastImage(_image,normal_op,geometry_info.rho,
anthony31f1bf72012-01-30 12:37:22 +00003240 geometry_info.sigma,
anthony92c93bd2012-03-19 14:02:47 +00003241 _exception);
anthony805a2d42011-09-25 08:25:12 +00003242 break;
3243 }
anthonyafa3dfc2012-03-03 11:31:30 +00003244 if (LocaleCompare("sketch",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);
anthonyfd706f92012-01-19 04:22:02 +00003248 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003249 if ((flags & SigmaValue) == 0)
3250 geometry_info.sigma=1.0;
anthony92c93bd2012-03-19 14:02:47 +00003251 new_image=SketchImage(_image,geometry_info.rho,
cristyaa2c16c2012-03-25 22:21:35 +00003252 geometry_info.sigma,geometry_info.xi,_exception);
anthony805a2d42011-09-25 08:25:12 +00003253 break;
3254 }
anthonyafa3dfc2012-03-03 11:31:30 +00003255 if (LocaleCompare("solarize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003256 {
anthony7bcfe7f2012-03-30 14:01:22 +00003257 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003258 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003259 (void) SolarizeImage(_image,StringToDoubleInterval(arg1,(double)
3260 QuantumRange+1.0),_exception);
anthony805a2d42011-09-25 08:25:12 +00003261 break;
3262 }
anthonyafa3dfc2012-03-03 11:31:30 +00003263 if (LocaleCompare("sparse-color",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003264 {
anthony805a2d42011-09-25 08:25:12 +00003265 char
3266 *arguments;
3267
anthonyf42014d2012-03-25 09:53:06 +00003268 parse= ParseCommandOption(MagickSparseColorOptions,MagickFalse,arg1);
3269 if ( parse < 0 )
3270 CLIWandExceptArgBreak(OptionError,"UnrecognizedSparseColorMethod",
3271 option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003272 arguments=InterpretImageProperties(_image_info,_image,arg2,_exception);
anthony805a2d42011-09-25 08:25:12 +00003273 if (arguments == (char *) NULL)
anthonyf42014d2012-03-25 09:53:06 +00003274 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
3275 new_image=SparseColorOption(_image,(SparseColorMethod)parse,
3276 arguments,_exception);
anthony805a2d42011-09-25 08:25:12 +00003277 arguments=DestroyString(arguments);
3278 break;
3279 }
anthonyafa3dfc2012-03-03 11:31:30 +00003280 if (LocaleCompare("splice",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003281 {
anthony7bcfe7f2012-03-30 14:01:22 +00003282 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003283 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003284 (void) ParseGravityGeometry(_image,arg1,&geometry,_exception);
3285 new_image=SpliceImage(_image,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00003286 break;
3287 }
anthonyafa3dfc2012-03-03 11:31:30 +00003288 if (LocaleCompare("spread",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003289 {
anthony7bcfe7f2012-03-30 14:01:22 +00003290 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003291 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00003292 (void) ParseGeometry(arg1,&geometry_info);
anthony92c93bd2012-03-19 14:02:47 +00003293 new_image=SpreadImage(_image,geometry_info.rho,_image->interpolate,
3294 _exception);
anthony805a2d42011-09-25 08:25:12 +00003295 break;
3296 }
anthonyafa3dfc2012-03-03 11:31:30 +00003297 if (LocaleCompare("statistic",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003298 {
anthony7bc87992012-03-25 02:32:51 +00003299 parse=ParseCommandOption(MagickStatisticOptions,MagickFalse,arg1);
3300 if ( parse < 0 )
anthonyf42014d2012-03-25 09:53:06 +00003301 CLIWandExceptArgBreak(OptionError,"UnrecognizedStatisticType",
anthony7bc87992012-03-25 02:32:51 +00003302 option,arg1);
anthony7bcfe7f2012-03-30 14:01:22 +00003303 if (IfMagickFalse(IsGeometry(arg2)))
anthony7bc87992012-03-25 02:32:51 +00003304 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
anthony975a8d72012-04-12 13:54:36 +00003305 flags=ParseGeometry(arg2,&geometry_info);
3306 if ((flags & SigmaValue) == 0)
3307 geometry_info.sigma=geometry_info.rho;
anthony7bc87992012-03-25 02:32:51 +00003308 new_image=StatisticImage(_image,(StatisticType)parse,
3309 (size_t) geometry_info.rho,(size_t) geometry_info.sigma,
3310 _exception);
anthony805a2d42011-09-25 08:25:12 +00003311 break;
3312 }
anthonyafa3dfc2012-03-03 11:31:30 +00003313 if (LocaleCompare("strip",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003314 {
anthony92c93bd2012-03-19 14:02:47 +00003315 (void) StripImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00003316 break;
3317 }
anthonyafa3dfc2012-03-03 11:31:30 +00003318 if (LocaleCompare("swirl",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003319 {
anthony7bcfe7f2012-03-30 14:01:22 +00003320 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003321 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00003322 (void) ParseGeometry(arg1,&geometry_info);
anthony92c93bd2012-03-19 14:02:47 +00003323 new_image=SwirlImage(_image,geometry_info.rho,
3324 _image->interpolate,_exception);
anthony805a2d42011-09-25 08:25:12 +00003325 break;
3326 }
anthonyebb73a22012-03-22 14:25:52 +00003327 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003328 }
3329 case 't':
3330 {
anthonyafa3dfc2012-03-03 11:31:30 +00003331 if (LocaleCompare("threshold",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003332 {
3333 double
3334 threshold;
3335
anthony52bef752012-03-27 13:54:47 +00003336 threshold=(double) QuantumRange/2;
3337 if (normal_op) {
anthony7bcfe7f2012-03-30 14:01:22 +00003338 if (IfMagickFalse(IsGeometry(arg1)))
anthony52bef752012-03-27 13:54:47 +00003339 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00003340 threshold=StringToDoubleInterval(arg1,(double) QuantumRange+1.0);
anthony52bef752012-03-27 13:54:47 +00003341 }
anthony92c93bd2012-03-19 14:02:47 +00003342 (void) BilevelImage(_image,threshold,_exception);
anthony805a2d42011-09-25 08:25:12 +00003343 break;
3344 }
anthonyafa3dfc2012-03-03 11:31:30 +00003345 if (LocaleCompare("thumbnail",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003346 {
anthony7bcfe7f2012-03-30 14:01:22 +00003347 if (IfMagickFalse(IsGeometry(arg1)))
anthony52bef752012-03-27 13:54:47 +00003348 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003349 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
3350 new_image=ThumbnailImage(_image,geometry.width,geometry.height,
3351 _exception);
anthony805a2d42011-09-25 08:25:12 +00003352 break;
3353 }
anthonyafa3dfc2012-03-03 11:31:30 +00003354 if (LocaleCompare("tint",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003355 {
anthony7bcfe7f2012-03-30 14:01:22 +00003356 if (IfMagickFalse(IsGeometry(arg1)))
anthony52bef752012-03-27 13:54:47 +00003357 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003358 new_image=TintImage(_image,arg1,&_draw_info->fill,_exception);
anthony805a2d42011-09-25 08:25:12 +00003359 break;
3360 }
anthonyafa3dfc2012-03-03 11:31:30 +00003361 if (LocaleCompare("transform",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003362 {
anthony975a8d72012-04-12 13:54:36 +00003363 CLIWandWarnDepreciated("+distort AffineProjection");
anthony52bef752012-03-27 13:54:47 +00003364 new_image=AffineTransformImage(_image,&_draw_info->affine,_exception);
anthony805a2d42011-09-25 08:25:12 +00003365 break;
3366 }
anthonyafa3dfc2012-03-03 11:31:30 +00003367 if (LocaleCompare("transparent",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003368 {
3369 PixelInfo
3370 target;
3371
anthony92c93bd2012-03-19 14:02:47 +00003372 (void) QueryColorCompliance(arg1,AllCompliance,&target,_exception);
3373 (void) TransparentPaintImage(_image,&target,(Quantum)
3374 TransparentAlpha,plus_alt_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00003375 break;
3376 }
anthonyafa3dfc2012-03-03 11:31:30 +00003377 if (LocaleCompare("transpose",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003378 {
anthony92c93bd2012-03-19 14:02:47 +00003379 new_image=TransposeImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00003380 break;
3381 }
anthonyafa3dfc2012-03-03 11:31:30 +00003382 if (LocaleCompare("transverse",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003383 {
anthony92c93bd2012-03-19 14:02:47 +00003384 new_image=TransverseImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00003385 break;
3386 }
anthonyafa3dfc2012-03-03 11:31:30 +00003387 if (LocaleCompare("trim",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003388 {
anthony92c93bd2012-03-19 14:02:47 +00003389 new_image=TrimImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00003390 break;
3391 }
anthonyafa3dfc2012-03-03 11:31:30 +00003392 if (LocaleCompare("type",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003393 {
anthonyab3a50c2011-10-27 11:48:57 +00003394 /* Note that "type" setting should have already been defined */
anthony92c93bd2012-03-19 14:02:47 +00003395 (void) SetImageType(_image,_image_info->type,_exception);
anthony805a2d42011-09-25 08:25:12 +00003396 break;
3397 }
anthonyebb73a22012-03-22 14:25:52 +00003398 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003399 }
3400 case 'u':
3401 {
anthonyafa3dfc2012-03-03 11:31:30 +00003402 if (LocaleCompare("unique",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003403 {
anthony52bef752012-03-27 13:54:47 +00003404 /* FUTURE: move to SyncImageSettings() and AcqireImage()???
3405 Option is not documented, bt appears to be for "identify".
3406 We may need a identify specific verbose!
3407 */
3408 if (plus_alt_op) {
anthony92c93bd2012-03-19 14:02:47 +00003409 (void) DeleteImageArtifact(_image,"identify:unique-colors");
anthony805a2d42011-09-25 08:25:12 +00003410 break;
3411 }
anthony92c93bd2012-03-19 14:02:47 +00003412 (void) SetImageArtifact(_image,"identify:unique-colors","true");
3413 (void) SetImageArtifact(_image,"verbose","true");
anthony805a2d42011-09-25 08:25:12 +00003414 break;
3415 }
anthonyafa3dfc2012-03-03 11:31:30 +00003416 if (LocaleCompare("unique-colors",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003417 {
anthony92c93bd2012-03-19 14:02:47 +00003418 new_image=UniqueImageColors(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00003419 break;
3420 }
anthonyafa3dfc2012-03-03 11:31:30 +00003421 if (LocaleCompare("unsharp",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003422 {
anthony7bcfe7f2012-03-30 14:01:22 +00003423 if (IfMagickFalse(IsGeometry(arg1)))
anthony52bef752012-03-27 13:54:47 +00003424 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00003425 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003426 if ((flags & SigmaValue) == 0)
3427 geometry_info.sigma=1.0;
3428 if ((flags & XiValue) == 0)
3429 geometry_info.xi=1.0;
3430 if ((flags & PsiValue) == 0)
3431 geometry_info.psi=0.05;
anthony92c93bd2012-03-19 14:02:47 +00003432 new_image=UnsharpMaskImage(_image,geometry_info.rho,
3433 geometry_info.sigma,geometry_info.xi,geometry_info.psi,_exception);
anthony805a2d42011-09-25 08:25:12 +00003434 break;
3435 }
anthonyebb73a22012-03-22 14:25:52 +00003436 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003437 }
3438 case 'v':
3439 {
anthonyafa3dfc2012-03-03 11:31:30 +00003440 if (LocaleCompare("verbose",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003441 {
anthonyafa3dfc2012-03-03 11:31:30 +00003442 /* FUTURE: move to SyncImageSettings() and AcquireImage()???
anthony92c93bd2012-03-19 14:02:47 +00003443 three places! ImageArtifact ImageOption _image_info->verbose
anthony5330ae02012-03-20 14:17:01 +00003444 Some how new images also get this artifact!
anthony31f1bf72012-01-30 12:37:22 +00003445 */
anthony92c93bd2012-03-19 14:02:47 +00003446 (void) SetImageArtifact(_image,option+1,
anthonyafa3dfc2012-03-03 11:31:30 +00003447 IfNormalOp ? "true" : "false" );
anthony805a2d42011-09-25 08:25:12 +00003448 break;
3449 }
anthonyafa3dfc2012-03-03 11:31:30 +00003450 if (LocaleCompare("vignette",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003451 {
anthony7bcfe7f2012-03-30 14:01:22 +00003452 if (IfMagickFalse(IsGeometry(arg1)))
anthony52bef752012-03-27 13:54:47 +00003453 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00003454 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003455 if ((flags & SigmaValue) == 0)
3456 geometry_info.sigma=1.0;
3457 if ((flags & XiValue) == 0)
anthony92c93bd2012-03-19 14:02:47 +00003458 geometry_info.xi=0.1*_image->columns;
anthony805a2d42011-09-25 08:25:12 +00003459 if ((flags & PsiValue) == 0)
anthony92c93bd2012-03-19 14:02:47 +00003460 geometry_info.psi=0.1*_image->rows;
3461 new_image=VignetteImage(_image,geometry_info.rho,geometry_info.sigma,
cristyaa2c16c2012-03-25 22:21:35 +00003462 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
3463 ceil(geometry_info.psi-0.5),_exception);
anthony805a2d42011-09-25 08:25:12 +00003464 break;
3465 }
anthonyebb73a22012-03-22 14:25:52 +00003466 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003467 }
3468 case 'w':
3469 {
anthonyafa3dfc2012-03-03 11:31:30 +00003470 if (LocaleCompare("wave",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003471 {
anthony7bcfe7f2012-03-30 14:01:22 +00003472 if (IfMagickFalse(IsGeometry(arg1)))
anthony52bef752012-03-27 13:54:47 +00003473 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00003474 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003475 if ((flags & SigmaValue) == 0)
3476 geometry_info.sigma=1.0;
anthony92c93bd2012-03-19 14:02:47 +00003477 new_image=WaveImage(_image,geometry_info.rho,geometry_info.sigma,
3478 _image->interpolate,_exception);
anthony805a2d42011-09-25 08:25:12 +00003479 break;
3480 }
anthonyafa3dfc2012-03-03 11:31:30 +00003481 if (LocaleCompare("white-threshold",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003482 {
anthony7bcfe7f2012-03-30 14:01:22 +00003483 if (IfMagickFalse(IsGeometry(arg1)))
anthony52bef752012-03-27 13:54:47 +00003484 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003485 (void) WhiteThresholdImage(_image,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00003486 break;
3487 }
anthonyebb73a22012-03-22 14:25:52 +00003488 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003489 }
3490 default:
anthonyebb73a22012-03-22 14:25:52 +00003491 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003492 }
3493 /*
3494 Replace current image with any image that was generated
anthony31f1bf72012-01-30 12:37:22 +00003495 and set image point to last image (so image->next is correct)
anthony805a2d42011-09-25 08:25:12 +00003496 */
3497 if (new_image != (Image *) NULL)
anthony92c93bd2012-03-19 14:02:47 +00003498 ReplaceImageInListReturnLast(&_image,new_image);
anthony805a2d42011-09-25 08:25:12 +00003499
anthony31f1bf72012-01-30 12:37:22 +00003500 return;
anthony92c93bd2012-03-19 14:02:47 +00003501#undef _image_info
3502#undef _draw_info
3503#undef _quantize_info
3504#undef _image
3505#undef _exception
anthonyafa3dfc2012-03-03 11:31:30 +00003506#undef IfNormalOp
3507#undef IfPlusOp
anthony31f1bf72012-01-30 12:37:22 +00003508#undef normal_op
anthonyafa3dfc2012-03-03 11:31:30 +00003509#undef plus_alt_op
anthony31f1bf72012-01-30 12:37:22 +00003510}
anthonyfd706f92012-01-19 04:22:02 +00003511
anthony43f425d2012-02-26 12:58:58 +00003512WandExport void CLISimpleOperatorImages(MagickCLI *cli_wand,
anthonyafa3dfc2012-03-03 11:31:30 +00003513 const char *option, const char *arg1, const char *arg2)
anthony31f1bf72012-01-30 12:37:22 +00003514{
3515 size_t
anthony43f425d2012-02-26 12:58:58 +00003516 n,
anthony31f1bf72012-01-30 12:37:22 +00003517 i;
3518
anthony43f425d2012-02-26 12:58:58 +00003519 assert(cli_wand != (MagickCLI *) NULL);
3520 assert(cli_wand->signature == WandSignature);
3521 assert(cli_wand->wand.signature == WandSignature);
3522 assert(cli_wand->wand.images != (Image *) NULL); /* images must be present */
anthony7bcfe7f2012-03-30 14:01:22 +00003523 if (IfMagickTrue(cli_wand->wand.debug))
anthony43f425d2012-02-26 12:58:58 +00003524 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
anthony31f1bf72012-01-30 12:37:22 +00003525
anthonyafa3dfc2012-03-03 11:31:30 +00003526#if !USE_WAND_METHODS
3527 /* FUTURE add appropriate tracing */
anthony31f1bf72012-01-30 12:37:22 +00003528 i=0;
anthony43f425d2012-02-26 12:58:58 +00003529 n=GetImageListLength(cli_wand->wand.images);
3530 cli_wand->wand.images=GetFirstImageInList(cli_wand->wand.images);
anthonyafa3dfc2012-03-03 11:31:30 +00003531 while (1) {
anthony31f1bf72012-01-30 12:37:22 +00003532 i++;
anthonyafa3dfc2012-03-03 11:31:30 +00003533 CLISimpleOperatorImage(cli_wand, option, arg1, arg2);
anthony43f425d2012-02-26 12:58:58 +00003534 if ( cli_wand->wand.images->next == (Image *) NULL )
3535 break;
3536 cli_wand->wand.images=cli_wand->wand.images->next;
anthony31f1bf72012-01-30 12:37:22 +00003537 }
anthony43f425d2012-02-26 12:58:58 +00003538 assert( i == n );
3539 cli_wand->wand.images=GetFirstImageInList(cli_wand->wand.images);
anthonyafa3dfc2012-03-03 11:31:30 +00003540#else
3541 MagickResetIterator(&cli_wand->wand);
anthony7bcfe7f2012-03-30 14:01:22 +00003542 while ( IfMagickTrue(MagickNextImage(&cli_wand->wand)) )
anthonyafa3dfc2012-03-03 11:31:30 +00003543 CLISimpleOperatorImage(cli_wand, option, arg1, arg2);
3544 MagickResetIterator(&cli_wand->wand);
3545#endif
anthony31f1bf72012-01-30 12:37:22 +00003546 return;
anthony805a2d42011-09-25 08:25:12 +00003547}
3548
3549/*
3550%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3551% %
3552% %
3553% %
anthony43f425d2012-02-26 12:58:58 +00003554+ 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 +00003555% %
3556% %
3557% %
3558%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3559%
anthony43f425d2012-02-26 12:58:58 +00003560% CLIListOperatorImages() applies a single operation that is apply to the
anthony31f1bf72012-01-30 12:37:22 +00003561% entire image list as a whole. The result is often a complete replacment
3562% of the image list with a completely new list, or just a single image.
anthony805a2d42011-09-25 08:25:12 +00003563%
3564% The format of the MogrifyImage method is:
3565%
anthony43f425d2012-02-26 12:58:58 +00003566% void CLIListOperatorImages(MagickCLI *cli_wand,
anthonyafa3dfc2012-03-03 11:31:30 +00003567% const char *option, const char *arg1, const char *arg2)
anthony805a2d42011-09-25 08:25:12 +00003568%
3569% A description of each parameter follows:
3570%
anthony43f425d2012-02-26 12:58:58 +00003571% o cli_wand: structure holding settings to be applied
anthony805a2d42011-09-25 08:25:12 +00003572%
anthony36a8c2c2012-02-10 00:08:44 +00003573% o option: The option string for the operation
3574%
anthony31f1bf72012-01-30 12:37:22 +00003575% o arg1, arg2: optional argument strings to the operation
anthonye5fcd362012-04-09 04:02:09 +00003576% arg2 is currently not used
anthony8b10b462012-02-08 12:32:44 +00003577%
3578% Example usage...
3579%
anthonyafa3dfc2012-03-03 11:31:30 +00003580% CLIListOperatorImages(cli_wand,MagickFalse,"-duplicate", "3", NULL);
3581% CLIListOperatorImages(cli_wand,MagickTrue, "+append", NULL, NULL);
anthony8b10b462012-02-08 12:32:44 +00003582%
anthony24aa8822012-03-11 00:56:06 +00003583% Or for handling command line arguments EG: +/-option ["arg1"]
anthony8b10b462012-02-08 12:32:44 +00003584%
anthony43f425d2012-02-26 12:58:58 +00003585% cli_wand
anthony8b10b462012-02-08 12:32:44 +00003586% argc,argv
3587% i=index in argv
3588%
anthony2052d272012-02-28 12:48:29 +00003589% option_info = GetCommandOptionInfo(argv[i]);
3590% count=option_info->type;
3591% option_type=option_info->flags;
3592%
3593% if ( (option_type & ListOperatorOptionFlag) != 0 )
anthonyafa3dfc2012-03-03 11:31:30 +00003594% CLIListOperatorImages(cli_wand,argv[i],
anthony8b10b462012-02-08 12:32:44 +00003595% count>=1 ? argv[i+1] : (char *)NULL,
3596% count>=2 ? argv[i+2] : (char *)NULL );
3597% i += count+1;
3598%
anthony805a2d42011-09-25 08:25:12 +00003599*/
anthony43f425d2012-02-26 12:58:58 +00003600WandExport void CLIListOperatorImages(MagickCLI *cli_wand,
anthonye5fcd362012-04-09 04:02:09 +00003601 const char *option,const char *arg1, const char *magick_unused(arg2))
anthony805a2d42011-09-25 08:25:12 +00003602{
anthony2a0ec8c2012-03-24 04:35:56 +00003603 ssize_t
3604 parse;
3605
anthony31f1bf72012-01-30 12:37:22 +00003606 Image
3607 *new_images;
anthony805a2d42011-09-25 08:25:12 +00003608
anthony2e4501b2012-03-30 04:41:54 +00003609#define _image_info (cli_wand->wand.image_info)
3610#define _images (cli_wand->wand.images)
3611#define _exception (cli_wand->wand.exception)
3612#define _draw_info (cli_wand->draw_info)
3613#define _quantize_info (cli_wand->quantize_info)
anthonyafa3dfc2012-03-03 11:31:30 +00003614#define IfNormalOp (*option=='-')
3615#define IfPlusOp (*option!='-')
anthony7bcfe7f2012-03-30 14:01:22 +00003616#define normal_op IsMagickTrue(IfNormalOp)
anthony805a2d42011-09-25 08:25:12 +00003617
anthony43f425d2012-02-26 12:58:58 +00003618 assert(cli_wand != (MagickCLI *) NULL);
3619 assert(cli_wand->signature == WandSignature);
3620 assert(cli_wand->wand.signature == WandSignature);
anthony92c93bd2012-03-19 14:02:47 +00003621 assert(_images != (Image *) NULL); /* _images must be present */
anthony7bcfe7f2012-03-30 14:01:22 +00003622 if (IfMagickTrue(cli_wand->wand.debug))
anthony43f425d2012-02-26 12:58:58 +00003623 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
anthony31f1bf72012-01-30 12:37:22 +00003624
anthony92c93bd2012-03-19 14:02:47 +00003625 (void) SyncImagesSettings(_image_info,_images,_exception);
anthony31f1bf72012-01-30 12:37:22 +00003626
3627 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 {
anthony975a8d72012-04-12 13:54:36 +00003640 CLIWandWarnDepreciated("-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 */
anthony92c93bd2012-03-19 14:02:47 +00003679 new_images=CombineImages(_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003680 break;
3681 }
anthonyafa3dfc2012-03-03 11:31:30 +00003682 if (LocaleCompare("composite",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003683 {
cristyfeb3e962012-03-29 17:25:55 +00003684 CompositeOperator
3685 compose;
3686
3687 const char*
3688 value;
3689
3690 MagickBooleanType
3691 clip_to_self;
3692
anthony805a2d42011-09-25 08:25:12 +00003693 Image
3694 *mask_image,
anthony31f1bf72012-01-30 12:37:22 +00003695 *source_image;
anthony805a2d42011-09-25 08:25:12 +00003696
3697 RectangleInfo
3698 geometry;
3699
anthony7bcfe7f2012-03-30 14:01:22 +00003700 /* Compose value from "-compose" option only */
anthony92c93bd2012-03-19 14:02:47 +00003701 value=GetImageOption(_image_info,"compose");
cristy542a95b2012-04-03 19:30:58 +00003702 if (value == (const char *) NULL)
anthony31f1bf72012-01-30 12:37:22 +00003703 compose=OverCompositeOp; /* use Over not source_image->compose */
cristy542a95b2012-04-03 19:30:58 +00003704 else
3705 compose=(CompositeOperator) ParseCommandOption(MagickComposeOptions,
3706 MagickFalse,value);
anthony5f867ae2011-10-09 10:28:34 +00003707
anthony7bcfe7f2012-03-30 14:01:22 +00003708 /* Get "clip-to-self" expert setting (false is normal) */
cristyca0e82c2012-04-10 11:53:24 +00003709 value=GetImageOption(_image_info,"compose:clip-to-self");
3710 if (value == (const char *) NULL)
3711 clip_to_self=MagickTrue;
3712 else
3713 clip_to_self=IsStringTrue(GetImageOption(_image_info,
3714 "compose:clip-to-self")); /* if this is true */
anthony2e4501b2012-03-30 04:41:54 +00003715 value=GetImageOption(_image_info,"compose:outside-overlay");
anthony7bcfe7f2012-03-30 14:01:22 +00003716 if (value != (const char *) NULL) { /* or this false */
anthony2e4501b2012-03-30 04:41:54 +00003717 /* FUTURE: depreciate warning for "compose:outside-overlay"*/
anthony7bcfe7f2012-03-30 14:01:22 +00003718 clip_to_self= IsMagickFalse(IsStringNotFalse(value));
anthony2e4501b2012-03-30 04:41:54 +00003719 }
3720
anthony92c93bd2012-03-19 14:02:47 +00003721 new_images=RemoveFirstImageFromList(&_images);
3722 source_image=RemoveFirstImageFromList(&_images);
anthony31f1bf72012-01-30 12:37:22 +00003723 if (source_image == (Image *) NULL)
anthony7bcfe7f2012-03-30 14:01:22 +00003724 break; /* FUTURE - produce Exception, rather than silent fail */
anthonye8f56492012-02-12 12:39:02 +00003725
anthony31f1bf72012-01-30 12:37:22 +00003726 /* FUTURE - this should not be here! - should be part of -geometry */
3727 (void) TransformImage(&source_image,(char *) NULL,
anthony92c93bd2012-03-19 14:02:47 +00003728 source_image->geometry,_exception);
anthony5f867ae2011-10-09 10:28:34 +00003729
anthony31f1bf72012-01-30 12:37:22 +00003730 SetGeometry(source_image,&geometry);
3731 (void) ParseAbsoluteGeometry(source_image->geometry,&geometry);
3732 GravityAdjustGeometry(new_images->columns,new_images->rows,
3733 new_images->gravity, &geometry);
anthony5f867ae2011-10-09 10:28:34 +00003734
anthony92c93bd2012-03-19 14:02:47 +00003735 mask_image=RemoveFirstImageFromList(&_images);
anthony805a2d42011-09-25 08:25:12 +00003736 if (mask_image != (Image *) NULL)
anthony31f1bf72012-01-30 12:37:22 +00003737 { /* handle a third write mask image */
anthony5f867ae2011-10-09 10:28:34 +00003738 if ((compose == DisplaceCompositeOp) ||
anthony7bcfe7f2012-03-30 14:01:22 +00003739 (compose == DistortCompositeOp)) {
3740 /* Merge Y displacement into X displace/distort map. */
3741 (void) CompositeImage(source_image,mask_image,
3742 CopyGreenCompositeOp,MagickTrue,0,0,_exception);
3743 mask_image=DestroyImage(mask_image);
3744 }
3745 else {
3746 /* Set a blending mask for the composition. */
3747 (void) NegateImage(mask_image,MagickFalse,_exception);
3748 (void) SetImageMask(new_images,mask_image,_exception);
3749 mask_image=DestroyImage(mask_image);
3750 }
anthony805a2d42011-09-25 08:25:12 +00003751 }
cristyfeb3e962012-03-29 17:25:55 +00003752 (void) CompositeImage(new_images,source_image,compose,clip_to_self,
3753 geometry.x,geometry.y,_exception);
anthony92c93bd2012-03-19 14:02:47 +00003754 (void) SetImageMask(new_images,(Image *) NULL,_exception);
anthony31f1bf72012-01-30 12:37:22 +00003755 source_image=DestroyImage(source_image);
anthony805a2d42011-09-25 08:25:12 +00003756 break;
3757 }
anthonyebb73a22012-03-22 14:25:52 +00003758 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003759 }
3760 case 'd':
3761 {
anthonyafa3dfc2012-03-03 11:31:30 +00003762 if (LocaleCompare("deconstruct",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003763 {
anthony975a8d72012-04-12 13:54:36 +00003764 CLIWandWarnDepreciated("-layer CompareAny");
anthonyafa3dfc2012-03-03 11:31:30 +00003765 CLIListOperatorImages(cli_wand,"-layer","CompareAny",NULL);
anthony805a2d42011-09-25 08:25:12 +00003766 break;
3767 }
anthonyafa3dfc2012-03-03 11:31:30 +00003768 if (LocaleCompare("delete",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003769 {
anthonyafa3dfc2012-03-03 11:31:30 +00003770 if (IfNormalOp)
anthony92c93bd2012-03-19 14:02:47 +00003771 DeleteImages(&_images,arg1,_exception);
anthonyafa3dfc2012-03-03 11:31:30 +00003772 else
anthony92c93bd2012-03-19 14:02:47 +00003773 DeleteImages(&_images,"-1",_exception);
anthony805a2d42011-09-25 08:25:12 +00003774 break;
3775 }
anthonyafa3dfc2012-03-03 11:31:30 +00003776 if (LocaleCompare("duplicate",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003777 {
anthonyafa3dfc2012-03-03 11:31:30 +00003778 if (IfNormalOp)
anthony805a2d42011-09-25 08:25:12 +00003779 {
3780 const char
3781 *p;
3782
3783 size_t
3784 number_duplicates;
3785
anthony7bcfe7f2012-03-30 14:01:22 +00003786 if (IfMagickFalse(IsGeometry(arg1)))
anthonyebb73a22012-03-22 14:25:52 +00003787 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,
3788 arg1);
anthony31f1bf72012-01-30 12:37:22 +00003789 number_duplicates=(size_t) StringToLong(arg1);
3790 p=strchr(arg1,',');
anthony805a2d42011-09-25 08:25:12 +00003791 if (p == (const char *) NULL)
anthonyebb73a22012-03-22 14:25:52 +00003792 new_images=DuplicateImages(_images,number_duplicates,"-1",
3793 _exception);
anthony805a2d42011-09-25 08:25:12 +00003794 else
anthony92c93bd2012-03-19 14:02:47 +00003795 new_images=DuplicateImages(_images,number_duplicates,p,
3796 _exception);
anthony805a2d42011-09-25 08:25:12 +00003797 }
anthonyafa3dfc2012-03-03 11:31:30 +00003798 else
anthony92c93bd2012-03-19 14:02:47 +00003799 new_images=DuplicateImages(_images,1,"-1",_exception);
3800 AppendImageToList(&_images, new_images);
anthony36a8c2c2012-02-10 00:08:44 +00003801 new_images=(Image *)NULL;
anthony805a2d42011-09-25 08:25:12 +00003802 break;
3803 }
anthonyebb73a22012-03-22 14:25:52 +00003804 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003805 }
3806 case 'e':
3807 {
anthonyafa3dfc2012-03-03 11:31:30 +00003808 if (LocaleCompare("evaluate-sequence",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003809 {
anthony2a0ec8c2012-03-24 04:35:56 +00003810 parse = ParseCommandOption(MagickEvaluateOptions,MagickFalse,arg1);
3811 if ( parse < 0 )
3812 CLIWandExceptArgBreak(OptionError,"UnrecognizedEvaluateOperator",
3813 option,arg1);
3814 new_images=EvaluateImages(_images,(MagickEvaluateOperator)parse,
3815 _exception);
anthony805a2d42011-09-25 08:25:12 +00003816 break;
3817 }
anthonyebb73a22012-03-22 14:25:52 +00003818 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003819 }
3820 case 'f':
3821 {
anthonyafa3dfc2012-03-03 11:31:30 +00003822 if (LocaleCompare("fft",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003823 {
anthony92c93bd2012-03-19 14:02:47 +00003824 new_images=ForwardFourierTransformImage(_images,normal_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00003825 break;
3826 }
anthonyafa3dfc2012-03-03 11:31:30 +00003827 if (LocaleCompare("flatten",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003828 {
anthony319dac62012-03-06 04:12:44 +00003829 /* REDIRECTED to use -layers flatten instead */
anthony2e4501b2012-03-30 04:41:54 +00003830 CLIListOperatorImages(cli_wand,"-layers",option+1,NULL);
anthony805a2d42011-09-25 08:25:12 +00003831 break;
3832 }
anthonyafa3dfc2012-03-03 11:31:30 +00003833 if (LocaleCompare("fx",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003834 {
anthony92c93bd2012-03-19 14:02:47 +00003835 new_images=FxImage(_images,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00003836 break;
3837 }
anthonyebb73a22012-03-22 14:25:52 +00003838 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003839 }
3840 case 'h':
3841 {
anthonyafa3dfc2012-03-03 11:31:30 +00003842 if (LocaleCompare("hald-clut",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003843 {
anthony31f1bf72012-01-30 12:37:22 +00003844 /* FUTURE - make this a compose option (and thus layers compose )
anthony92c93bd2012-03-19 14:02:47 +00003845 or perhaps compose last image over all other _images.
anthony31f1bf72012-01-30 12:37:22 +00003846 */
anthony805a2d42011-09-25 08:25:12 +00003847 Image
anthony31f1bf72012-01-30 12:37:22 +00003848 *hald_image;
anthony805a2d42011-09-25 08:25:12 +00003849
anthony92c93bd2012-03-19 14:02:47 +00003850 new_images=RemoveFirstImageFromList(&_images);
3851 hald_image=RemoveLastImageFromList(&_images);
anthony805a2d42011-09-25 08:25:12 +00003852 if (hald_image == (Image *) NULL)
anthony31f1bf72012-01-30 12:37:22 +00003853 break;
anthony92c93bd2012-03-19 14:02:47 +00003854 (void) HaldClutImage(new_images,hald_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00003855 hald_image=DestroyImage(hald_image);
anthony805a2d42011-09-25 08:25:12 +00003856 break;
3857 }
anthonyebb73a22012-03-22 14:25:52 +00003858 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003859 }
3860 case 'i':
3861 {
anthonyafa3dfc2012-03-03 11:31:30 +00003862 if (LocaleCompare("ift",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003863 {
3864 Image
anthony805a2d42011-09-25 08:25:12 +00003865 *magnitude_image,
3866 *phase_image;
3867
anthony92c93bd2012-03-19 14:02:47 +00003868 magnitude_image=RemoveFirstImageFromList(&_images);
3869 phase_image=RemoveFirstImageFromList(&_images);
anthonye8f56492012-02-12 12:39:02 +00003870 /* FUTURE - produce Exception, rather than silent fail */
anthony31f1bf72012-01-30 12:37:22 +00003871 if (phase_image == (Image *) NULL)
3872 break;
3873 new_images=InverseFourierTransformImage(magnitude_image,phase_image,
anthony92c93bd2012-03-19 14:02:47 +00003874 normal_op,_exception);
anthony31f1bf72012-01-30 12:37:22 +00003875 magnitude_image=DestroyImage(magnitude_image);
3876 phase_image=DestroyImage(phase_image);
anthony805a2d42011-09-25 08:25:12 +00003877 break;
3878 }
anthonyafa3dfc2012-03-03 11:31:30 +00003879 if (LocaleCompare("insert",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003880 {
3881 Image
anthony31f1bf72012-01-30 12:37:22 +00003882 *insert_image,
3883 *index_image;
3884
3885 ssize_t
3886 index;
anthony805a2d42011-09-25 08:25:12 +00003887
anthony7bcfe7f2012-03-30 14:01:22 +00003888 if (IfNormalOp && IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00003889 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00003890 index=0;
anthony92c93bd2012-03-19 14:02:47 +00003891 insert_image=RemoveLastImageFromList(&_images);
anthonyafa3dfc2012-03-03 11:31:30 +00003892 if (IfNormalOp)
anthony31f1bf72012-01-30 12:37:22 +00003893 index=(ssize_t) StringToLong(arg1);
anthony43f425d2012-02-26 12:58:58 +00003894 index_image=insert_image;
anthony805a2d42011-09-25 08:25:12 +00003895 if (index == 0)
anthony92c93bd2012-03-19 14:02:47 +00003896 PrependImageToList(&_images,insert_image);
3897 else if (index == (ssize_t) GetImageListLength(_images))
3898 AppendImageToList(&_images,insert_image);
anthony805a2d42011-09-25 08:25:12 +00003899 else
anthony43f425d2012-02-26 12:58:58 +00003900 {
anthony92c93bd2012-03-19 14:02:47 +00003901 index_image=GetImageFromList(_images,index-1);
anthony43f425d2012-02-26 12:58:58 +00003902 if (index_image == (Image *) NULL)
anthonyfe1aa782012-03-24 13:43:04 +00003903 CLIWandExceptArgBreak(OptionError,"NoSuchImage",option,arg1);
anthony43f425d2012-02-26 12:58:58 +00003904 InsertImageInList(&index_image,insert_image);
3905 }
anthony92c93bd2012-03-19 14:02:47 +00003906 _images=GetFirstImageInList(index_image);
anthony805a2d42011-09-25 08:25:12 +00003907 break;
3908 }
anthonyebb73a22012-03-22 14:25:52 +00003909 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003910 }
3911 case 'l':
3912 {
anthonyafa3dfc2012-03-03 11:31:30 +00003913 if (LocaleCompare("layers",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003914 {
anthonyfe1aa782012-03-24 13:43:04 +00003915 parse=ParseCommandOption(MagickLayerOptions,MagickFalse,arg1);
3916 if ( parse < 0 )
3917 CLIWandExceptArgBreak(OptionError,"UnrecognizedLayerMethod",
3918 option,arg1);
3919 switch ((ImageLayerMethod) parse)
anthony805a2d42011-09-25 08:25:12 +00003920 {
3921 case CoalesceLayer:
3922 {
anthony92c93bd2012-03-19 14:02:47 +00003923 new_images=CoalesceImages(_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003924 break;
3925 }
3926 case CompareAnyLayer:
3927 case CompareClearLayer:
3928 case CompareOverlayLayer:
3929 default:
3930 {
anthonyfe1aa782012-03-24 13:43:04 +00003931 new_images=CompareImagesLayers(_images,(ImageLayerMethod) parse,
3932 _exception);
anthony805a2d42011-09-25 08:25:12 +00003933 break;
3934 }
3935 case MergeLayer:
3936 case FlattenLayer:
3937 case MosaicLayer:
3938 case TrimBoundsLayer:
3939 {
anthonyfe1aa782012-03-24 13:43:04 +00003940 new_images=MergeImageLayers(_images,(ImageLayerMethod) parse,
3941 _exception);
anthony805a2d42011-09-25 08:25:12 +00003942 break;
3943 }
3944 case DisposeLayer:
3945 {
anthony92c93bd2012-03-19 14:02:47 +00003946 new_images=DisposeImages(_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003947 break;
3948 }
3949 case OptimizeImageLayer:
3950 {
anthony92c93bd2012-03-19 14:02:47 +00003951 new_images=OptimizeImageLayers(_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003952 break;
3953 }
3954 case OptimizePlusLayer:
3955 {
anthony92c93bd2012-03-19 14:02:47 +00003956 new_images=OptimizePlusImageLayers(_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003957 break;
3958 }
3959 case OptimizeTransLayer:
3960 {
anthony92c93bd2012-03-19 14:02:47 +00003961 OptimizeImageTransparency(_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003962 break;
3963 }
3964 case RemoveDupsLayer:
3965 {
anthony92c93bd2012-03-19 14:02:47 +00003966 RemoveDuplicateLayers(&_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003967 break;
3968 }
3969 case RemoveZeroLayer:
3970 {
anthony92c93bd2012-03-19 14:02:47 +00003971 RemoveZeroDelayLayers(&_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003972 break;
3973 }
3974 case OptimizeLayer:
anthony31f1bf72012-01-30 12:37:22 +00003975 { /* General Purpose, GIF Animation Optimizer. */
anthony92c93bd2012-03-19 14:02:47 +00003976 new_images=CoalesceImages(_images,_exception);
anthony31f1bf72012-01-30 12:37:22 +00003977 if (new_images == (Image *) NULL)
3978 break;
anthony92c93bd2012-03-19 14:02:47 +00003979 _images=DestroyImageList(_images);
3980 _images=OptimizeImageLayers(new_images,_exception);
3981 if (_images == (Image *) NULL)
anthony31f1bf72012-01-30 12:37:22 +00003982 break;
3983 new_images=DestroyImageList(new_images);
anthony92c93bd2012-03-19 14:02:47 +00003984 OptimizeImageTransparency(_images,_exception);
3985 (void) RemapImages(_quantize_info,_images,(Image *) NULL,
3986 _exception);
anthony805a2d42011-09-25 08:25:12 +00003987 break;
3988 }
3989 case CompositeLayer:
3990 {
anthony805a2d42011-09-25 08:25:12 +00003991 Image
3992 *source;
3993
3994 RectangleInfo
3995 geometry;
3996
anthony31f1bf72012-01-30 12:37:22 +00003997 CompositeOperator
anthony5f867ae2011-10-09 10:28:34 +00003998 compose;
3999
4000 const char*
4001 value;
4002
anthony92c93bd2012-03-19 14:02:47 +00004003 value=GetImageOption(_image_info,"compose");
anthony31f1bf72012-01-30 12:37:22 +00004004 compose=OverCompositeOp; /* Default to Over */
anthony5f867ae2011-10-09 10:28:34 +00004005 if (value != (const char *) NULL)
4006 compose=(CompositeOperator) ParseCommandOption(
4007 MagickComposeOptions,MagickFalse,value);
anthony5f867ae2011-10-09 10:28:34 +00004008
anthony31f1bf72012-01-30 12:37:22 +00004009 /* Split image sequence at the first 'NULL:' image. */
anthony92c93bd2012-03-19 14:02:47 +00004010 source=_images;
anthony805a2d42011-09-25 08:25:12 +00004011 while (source != (Image *) NULL)
4012 {
4013 source=GetNextImageInList(source);
4014 if ((source != (Image *) NULL) &&
4015 (LocaleCompare(source->magick,"NULL") == 0))
4016 break;
4017 }
4018 if (source != (Image *) NULL)
4019 {
4020 if ((GetPreviousImageInList(source) == (Image *) NULL) ||
4021 (GetNextImageInList(source) == (Image *) NULL))
4022 source=(Image *) NULL;
4023 else
anthony31f1bf72012-01-30 12:37:22 +00004024 { /* Separate the two lists, junk the null: image. */
anthony805a2d42011-09-25 08:25:12 +00004025 source=SplitImageList(source->previous);
4026 DeleteImageFromList(&source);
4027 }
4028 }
4029 if (source == (Image *) NULL)
4030 {
anthony92c93bd2012-03-19 14:02:47 +00004031 (void) ThrowMagickException(_exception,GetMagickModule(),
anthony805a2d42011-09-25 08:25:12 +00004032 OptionError,"MissingNullSeparator","layers Composite");
anthony805a2d42011-09-25 08:25:12 +00004033 break;
4034 }
anthony31f1bf72012-01-30 12:37:22 +00004035 /* Adjust offset with gravity and virtual canvas. */
anthony92c93bd2012-03-19 14:02:47 +00004036 SetGeometry(_images,&geometry);
4037 (void) ParseAbsoluteGeometry(_images->geometry,&geometry);
anthony805a2d42011-09-25 08:25:12 +00004038 geometry.width=source->page.width != 0 ?
4039 source->page.width : source->columns;
4040 geometry.height=source->page.height != 0 ?
4041 source->page.height : source->rows;
anthony92c93bd2012-03-19 14:02:47 +00004042 GravityAdjustGeometry(_images->page.width != 0 ?
4043 _images->page.width : _images->columns,
4044 _images->page.height != 0 ? _images->page.height :
4045 _images->rows,_images->gravity,&geometry);
anthony5f867ae2011-10-09 10:28:34 +00004046
anthony31f1bf72012-01-30 12:37:22 +00004047 /* Compose the two image sequences together */
anthony92c93bd2012-03-19 14:02:47 +00004048 CompositeLayers(_images,compose,source,geometry.x,geometry.y,
4049 _exception);
anthony805a2d42011-09-25 08:25:12 +00004050 source=DestroyImageList(source);
4051 break;
4052 }
4053 }
anthony805a2d42011-09-25 08:25:12 +00004054 break;
4055 }
anthonyebb73a22012-03-22 14:25:52 +00004056 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00004057 }
4058 case 'm':
4059 {
anthonyafa3dfc2012-03-03 11:31:30 +00004060 if (LocaleCompare("map",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00004061 {
anthony975a8d72012-04-12 13:54:36 +00004062 CLIWandWarnDepreciated("+remap");
anthony92c93bd2012-03-19 14:02:47 +00004063 (void) RemapImages(_quantize_info,_images,(Image *) NULL,_exception);
anthony805a2d42011-09-25 08:25:12 +00004064 break;
4065 }
anthonyafa3dfc2012-03-03 11:31:30 +00004066 if (LocaleCompare("morph",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00004067 {
4068 Image
4069 *morph_image;
4070
anthony7bcfe7f2012-03-30 14:01:22 +00004071 if (IfMagickFalse(IsGeometry(arg1)))
anthony7bc87992012-03-25 02:32:51 +00004072 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00004073 morph_image=MorphImages(_images,StringToUnsignedLong(arg1),
4074 _exception);
anthony805a2d42011-09-25 08:25:12 +00004075 if (morph_image == (Image *) NULL)
anthony31f1bf72012-01-30 12:37:22 +00004076 break;
anthony92c93bd2012-03-19 14:02:47 +00004077 _images=DestroyImageList(_images);
4078 _images=morph_image;
anthony805a2d42011-09-25 08:25:12 +00004079 break;
4080 }
anthonyafa3dfc2012-03-03 11:31:30 +00004081 if (LocaleCompare("mosaic",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00004082 {
anthony319dac62012-03-06 04:12:44 +00004083 /* REDIRECTED to use -layers mosaic instead */
anthony2e4501b2012-03-30 04:41:54 +00004084 CLIListOperatorImages(cli_wand,"-layers",option+1,NULL);
anthony805a2d42011-09-25 08:25:12 +00004085 break;
4086 }
anthonyebb73a22012-03-22 14:25:52 +00004087 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00004088 }
4089 case 'p':
4090 {
anthonyafa3dfc2012-03-03 11:31:30 +00004091 if (LocaleCompare("print",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00004092 {
4093 char
4094 *string;
4095
anthony92c93bd2012-03-19 14:02:47 +00004096 string=InterpretImageProperties(_image_info,_images,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00004097 if (string == (char *) NULL)
4098 break;
4099 (void) FormatLocaleFile(stdout,"%s",string);
4100 string=DestroyString(string);
anthony24aa8822012-03-11 00:56:06 +00004101 break;
anthony805a2d42011-09-25 08:25:12 +00004102 }
anthonyafa3dfc2012-03-03 11:31:30 +00004103 if (LocaleCompare("process",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00004104 {
4105 char
4106 **arguments;
4107
4108 int
4109 j,
4110 number_arguments;
4111
anthony31f1bf72012-01-30 12:37:22 +00004112 arguments=StringToArgv(arg1,&number_arguments);
anthony805a2d42011-09-25 08:25:12 +00004113 if (arguments == (char **) NULL)
4114 break;
anthony31f1bf72012-01-30 12:37:22 +00004115 if (strchr(arguments[1],'=') != (char *) NULL)
anthony805a2d42011-09-25 08:25:12 +00004116 {
4117 char
4118 breaker,
4119 quote,
4120 *token;
4121
4122 const char
4123 *arguments;
4124
4125 int
4126 next,
4127 status;
4128
4129 size_t
4130 length;
4131
4132 TokenInfo
4133 *token_info;
4134
4135 /*
anthony24aa8822012-03-11 00:56:06 +00004136 Support old style syntax, filter="-option arg1".
anthony805a2d42011-09-25 08:25:12 +00004137 */
anthony31f1bf72012-01-30 12:37:22 +00004138 length=strlen(arg1);
anthony805a2d42011-09-25 08:25:12 +00004139 token=(char *) NULL;
4140 if (~length >= (MaxTextExtent-1))
4141 token=(char *) AcquireQuantumMemory(length+MaxTextExtent,
4142 sizeof(*token));
4143 if (token == (char *) NULL)
4144 break;
4145 next=0;
anthony31f1bf72012-01-30 12:37:22 +00004146 arguments=arg1;
anthony805a2d42011-09-25 08:25:12 +00004147 token_info=AcquireTokenInfo();
4148 status=Tokenizer(token_info,0,token,length,arguments,"","=",
4149 "\"",'\0',&breaker,&next,&quote);
4150 token_info=DestroyTokenInfo(token_info);
4151 if (status == 0)
4152 {
4153 const char
4154 *argv;
4155
4156 argv=(&(arguments[next]));
anthony92c93bd2012-03-19 14:02:47 +00004157 (void) InvokeDynamicImageFilter(token,&_images,1,&argv,
4158 _exception);
anthony805a2d42011-09-25 08:25:12 +00004159 }
4160 token=DestroyString(token);
4161 break;
4162 }
4163 (void) SubstituteString(&arguments[1],"-","");
anthony92c93bd2012-03-19 14:02:47 +00004164 (void) InvokeDynamicImageFilter(arguments[1],&_images,
4165 number_arguments-2,(const char **) arguments+2,_exception);
anthony805a2d42011-09-25 08:25:12 +00004166 for (j=0; j < number_arguments; j++)
4167 arguments[j]=DestroyString(arguments[j]);
4168 arguments=(char **) RelinquishMagickMemory(arguments);
4169 break;
4170 }
anthonyebb73a22012-03-22 14:25:52 +00004171 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00004172 }
4173 case 'r':
4174 {
anthonyafa3dfc2012-03-03 11:31:30 +00004175 if (LocaleCompare("remap",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00004176 {
anthony92c93bd2012-03-19 14:02:47 +00004177 (void) RemapImages(_quantize_info,_images,(Image *) NULL,_exception);
anthony31f1bf72012-01-30 12:37:22 +00004178 break;
4179 }
anthonyafa3dfc2012-03-03 11:31:30 +00004180 if (LocaleCompare("reverse",option+1) == 0)
anthony31f1bf72012-01-30 12:37:22 +00004181 {
anthony92c93bd2012-03-19 14:02:47 +00004182 ReverseImageList(&_images);
anthony805a2d42011-09-25 08:25:12 +00004183 break;
4184 }
anthonyebb73a22012-03-22 14:25:52 +00004185 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00004186 }
4187 case 's':
4188 {
anthonyafa3dfc2012-03-03 11:31:30 +00004189 if (LocaleCompare("smush",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00004190 {
4191 Image
4192 *smush_image;
4193
4194 ssize_t
4195 offset;
4196
anthony7bcfe7f2012-03-30 14:01:22 +00004197 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00004198 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony31f1bf72012-01-30 12:37:22 +00004199 offset=(ssize_t) StringToLong(arg1);
anthony92c93bd2012-03-19 14:02:47 +00004200 smush_image=SmushImages(_images,normal_op,offset,_exception);
anthony805a2d42011-09-25 08:25:12 +00004201 if (smush_image == (Image *) NULL)
anthony31f1bf72012-01-30 12:37:22 +00004202 break;
anthony92c93bd2012-03-19 14:02:47 +00004203 _images=DestroyImageList(_images);
4204 _images=smush_image;
anthony805a2d42011-09-25 08:25:12 +00004205 break;
4206 }
anthony0ea037a2012-04-03 12:14:39 +00004207 if (LocaleCompare("swap",option+1) == 0) {
4208 Image
4209 *p,
4210 *q,
4211 *swap;
anthony805a2d42011-09-25 08:25:12 +00004212
anthony0ea037a2012-04-03 12:14:39 +00004213 ssize_t
4214 index,
4215 swap_index;
anthony805a2d42011-09-25 08:25:12 +00004216
anthony0ea037a2012-04-03 12:14:39 +00004217 index=-1;
4218 swap_index=-2;
4219 if (IfNormalOp) {
4220 GeometryInfo
4221 geometry_info;
4222
4223 MagickStatusType
4224 flags;
4225
4226 swap_index=(-1);
anthony7bcfe7f2012-03-30 14:01:22 +00004227 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00004228 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony0ea037a2012-04-03 12:14:39 +00004229 flags=ParseGeometry(arg1,&geometry_info);
4230 index=(ssize_t) geometry_info.rho;
4231 if ((flags & SigmaValue) != 0)
4232 swap_index=(ssize_t) geometry_info.sigma;
anthony805a2d42011-09-25 08:25:12 +00004233 }
anthony0ea037a2012-04-03 12:14:39 +00004234 p=GetImageFromList(_images,index);
4235 q=GetImageFromList(_images,swap_index);
anthony8226e722012-04-05 14:25:46 +00004236 if ((p == (Image *) NULL) || (q == (Image *) NULL)) {
4237 if (IfNormalOp)
4238 CLIWandExceptArgBreak(OptionError,"InvalidImageIndex",option,arg1)
4239 else
4240 CLIWandExceptionBreak(OptionError,"TwoOrMoreImagesRequired",option);
4241 }
anthony0ea037a2012-04-03 12:14:39 +00004242 if (p == q)
anthony8226e722012-04-05 14:25:46 +00004243 CLIWandExceptArgBreak(OptionError,"InvalidImageIndex",option,arg1);
anthony0ea037a2012-04-03 12:14:39 +00004244 swap=CloneImage(p,0,0,MagickTrue,_exception);
4245 ReplaceImageInList(&p,CloneImage(q,0,0,MagickTrue,_exception));
4246 ReplaceImageInList(&q,swap);
4247 _images=GetFirstImageInList(q);
4248 break;
4249 }
anthonyebb73a22012-03-22 14:25:52 +00004250 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00004251 }
anthony805a2d42011-09-25 08:25:12 +00004252 default:
anthonyebb73a22012-03-22 14:25:52 +00004253 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00004254 }
anthony31f1bf72012-01-30 12:37:22 +00004255 if (new_images == (Image *) NULL)
4256 return;
anthony805a2d42011-09-25 08:25:12 +00004257
anthony92c93bd2012-03-19 14:02:47 +00004258 if (_images != (Image *) NULL)
4259 _images=DestroyImageList(_images);
4260 _images=GetFirstImageInList(new_images);
anthony31f1bf72012-01-30 12:37:22 +00004261 return;
4262
anthony92c93bd2012-03-19 14:02:47 +00004263#undef _image_info
4264#undef _images
4265#undef _exception
4266#undef _draw_info
4267#undef _quantize_info
anthonyafa3dfc2012-03-03 11:31:30 +00004268#undef IfNormalOp
4269#undef IfPlusOp
anthony31f1bf72012-01-30 12:37:22 +00004270#undef normal_op
anthony805a2d42011-09-25 08:25:12 +00004271}
anthony43f425d2012-02-26 12:58:58 +00004272
4273/*
4274%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4275% %
4276% %
4277% %
4278+ C L I S p e c i a l O p e r a t i o n s %
4279% %
4280% %
4281% %
4282%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4283%
anthony756cd0d2012-04-08 12:41:44 +00004284% CLISpecialOperator() Applies operations that may not actually need images
4285% in an image list wen it is applied.
anthony43f425d2012-02-26 12:58:58 +00004286%
anthony756cd0d2012-04-08 12:41:44 +00004287% The classic operators of this type is -read, which actually creates images
4288% even when no images are present. Or image stack operators, which can be
4289% applied to empty image lists.
anthonyafa3dfc2012-03-03 11:31:30 +00004290%
4291% Note: unlike other Operators, these may involve other special 'option'
4292% character prefixes, other than simply '-' or '+'.
anthony43f425d2012-02-26 12:58:58 +00004293%
4294% The format of the CLISpecialOption method is:
4295%
4296% void CLISpecialOption(MagickCLI *cli_wand,const char *option,
anthony24aa8822012-03-11 00:56:06 +00004297% const char *arg1)
anthony43f425d2012-02-26 12:58:58 +00004298%
4299% A description of each parameter follows:
4300%
4301% o cli_wand: the main CLI Wand to use.
4302%
4303% o option: The special option (with any switch char) to process
4304%
anthony24aa8822012-03-11 00:56:06 +00004305% o arg1: Argument for option, if required
anthonyafa3dfc2012-03-03 11:31:30 +00004306%
anthony2052d272012-02-28 12:48:29 +00004307% Example Usage...
4308%
anthonyce8dcb32012-03-21 13:20:31 +00004309% CLISpecialOperator(cli_wand,"-read","rose:");
anthony2052d272012-02-28 12:48:29 +00004310%
anthony24aa8822012-03-11 00:56:06 +00004311% Or for handling command line arguments EG: +/-option ["arg1"]
anthony2052d272012-02-28 12:48:29 +00004312%
4313% cli_wand
4314% argc,argv
4315% i=index in argv
4316%
4317% option_info = GetCommandOptionInfo(argv[i]);
4318% count=option_info->type;
4319% option_type=option_info->flags;
4320%
4321% if ( (option_type & SpecialOptionFlag) != 0 )
4322% CLISpecialOperator(cli_wand,argv[i],
4323% count>=1 ? argv[i+1] : (char *)NULL);
4324% i += count+1;
anthony43f425d2012-02-26 12:58:58 +00004325%
4326*/
4327
anthony43f425d2012-02-26 12:58:58 +00004328WandExport void CLISpecialOperator(MagickCLI *cli_wand,
anthony24aa8822012-03-11 00:56:06 +00004329 const char *option, const char *arg1)
anthony43f425d2012-02-26 12:58:58 +00004330{
anthony8226e722012-04-05 14:25:46 +00004331#define _image_info (cli_wand->wand.image_info)
4332#define _images (cli_wand->wand.images)
4333#define _exception (cli_wand->wand.exception)
4334#define IfNormalOp (*option=='-')
4335#define IfPlusOp (*option!='-')
anthony43f425d2012-02-26 12:58:58 +00004336
4337 assert(cli_wand != (MagickCLI *) NULL);
4338 assert(cli_wand->signature == WandSignature);
4339 assert(cli_wand->wand.signature == WandSignature);
anthony7bcfe7f2012-03-30 14:01:22 +00004340 if (IfMagickTrue(cli_wand->wand.debug))
anthony43f425d2012-02-26 12:58:58 +00004341 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
4342
anthony8226e722012-04-05 14:25:46 +00004343 if(_images != (Image *)NULL)
4344 (void) SyncImagesSettings(cli_wand->wand.image_info,_images,_exception);
anthony24aa8822012-03-11 00:56:06 +00004345
anthony52bef752012-03-27 13:54:47 +00004346 /*
anthony756cd0d2012-04-08 12:41:44 +00004347 No-op options (ignore these)
anthony52bef752012-03-27 13:54:47 +00004348 */
anthony756cd0d2012-04-08 12:41:44 +00004349 if (LocaleCompare("noop",option+1) == 0) /* no argument */
anthony52bef752012-03-27 13:54:47 +00004350 return;
anthony756cd0d2012-04-08 12:41:44 +00004351 if (LocaleCompare("sans",option+1) == 0) /* one argument */
anthony52bef752012-03-27 13:54:47 +00004352 return;
anthony756cd0d2012-04-08 12:41:44 +00004353 if (LocaleCompare("sans0",option+1) == 0) /* no argument */
anthony52bef752012-03-27 13:54:47 +00004354 return;
anthony756cd0d2012-04-08 12:41:44 +00004355 if (LocaleCompare("sans2",option+1) == 0) /* two arguments */
anthony52bef752012-03-27 13:54:47 +00004356 return;
4357 /*
4358 Image Reading
4359 */
4360 if ( ( LocaleCompare("read",option+1) == 0 ) ||
anthony0ea037a2012-04-03 12:14:39 +00004361 ( LocaleCompare("--",option) == 0 ) ) {
4362 int
4363 argc;
4364 char
4365 **argv;
anthony52bef752012-03-27 13:54:47 +00004366
anthony0ea037a2012-04-03 12:14:39 +00004367 ssize_t
4368 i;
4369
4370 /* Expand the filename argument (meta-characters or "@filelist" ) */
4371 argc = 1;
cristye71f2942012-04-04 11:07:05 +00004372 argv = (char **) &arg1;
anthony0ea037a2012-04-03 12:14:39 +00004373 MagickBooleanType
4374 status=ExpandFilenames(&argc,&argv);
4375
4376 if (IfMagickFalse(status))
4377 CLIWandExceptArgReturn(ResourceLimitError,"MemoryAllocationFailed",
4378 option,GetExceptionMessage(errno));
4379
4380 /* loop over expanded list reading images */
4381 for (i=0; i<argc; i++) {
anthony52bef752012-03-27 13:54:47 +00004382#if !USE_WAND_METHODS
4383 Image *
4384 new_images;
anthony8226e722012-04-05 14:25:46 +00004385 if (IfMagickTrue(_image_info->ping))
4386 new_images=PingImages(_image_info,argv[i],_exception);
anthony52bef752012-03-27 13:54:47 +00004387 else
anthony8226e722012-04-05 14:25:46 +00004388 new_images=ReadImages(_image_info,argv[i],_exception);
4389 AppendImageToList(&_images, new_images);
anthony52bef752012-03-27 13:54:47 +00004390#else
4391 /* read images using MagickWand method - no ping */
4392 /* This is not working! - it locks up in a CPU loop! */
4393 MagickSetLastIterator(&cli_wand->wand);
4394 MagickReadImage(&cli_wand->wand,arg1);
4395 MagickSetFirstIterator(&cli_wand->wand);
4396#endif
anthony52bef752012-03-27 13:54:47 +00004397 }
anthony0ea037a2012-04-03 12:14:39 +00004398 /* FUTURE: how do I free the expanded filename arguments??? */
4399
4400 return;
4401 }
anthony52bef752012-03-27 13:54:47 +00004402 /*
anthony756cd0d2012-04-08 12:41:44 +00004403 Image Writing (no-images present is valid in specific cases)
anthony8226e722012-04-05 14:25:46 +00004404 */
4405 if (LocaleCompare("write",option+1) == 0) {
4406 char
4407 key[MaxTextExtent];
4408
4409 Image
4410 *write_images;
4411
4412 ImageInfo
4413 *write_info;
4414
4415 /* Need images, unless a "null:" output coder is used */
4416 if ( cli_wand->wand.images == (Image *) NULL ) {
anthonya9e4f5d2012-04-12 06:44:02 +00004417 if ( LocaleCompare(arg1,"null:") == 0 )
anthony8226e722012-04-05 14:25:46 +00004418 return;
4419 CLIWandExceptArgReturn(OptionError,"NoImagesForWrite",option,arg1);
4420 }
4421
4422 (void) FormatLocaleString(key,MaxTextExtent,"cache:%s",arg1);
4423 (void) DeleteImageRegistry(key);
4424 write_images=_images;
4425 if (IfPlusOp)
4426 write_images=CloneImageList(_images,_exception);
4427 write_info=CloneImageInfo(_image_info);
4428 (void) WriteImages(write_info,write_images,arg1,_exception);
4429 write_info=DestroyImageInfo(write_info);
4430 if (IfPlusOp)
4431 write_images=DestroyImageList(write_images);
4432 return;
4433 }
4434 /*
anthony52bef752012-03-27 13:54:47 +00004435 Parenthesis and Brace operations
4436 */
anthonyce8dcb32012-03-21 13:20:31 +00004437 if (LocaleCompare("(",option) == 0) {
anthony8226e722012-04-05 14:25:46 +00004438 /* stack 'push' images */
4439 Stack
4440 *node;
anthony43f425d2012-02-26 12:58:58 +00004441
anthony8226e722012-04-05 14:25:46 +00004442 size_t
4443 size;
anthony43f425d2012-02-26 12:58:58 +00004444
anthony8226e722012-04-05 14:25:46 +00004445 size=0;
4446 node=cli_wand->image_list_stack;
4447 for ( ; node != (Stack *)NULL; node=node->next)
4448 size++;
4449 if ( size >= MAX_STACK_DEPTH )
4450 CLIWandExceptionReturn(OptionError,"ParenthesisNestedTooDeeply",option);
4451 node=(Stack *) AcquireMagickMemory(sizeof(*node));
4452 if (node == (Stack *) NULL)
4453 CLIWandExceptionReturn(ResourceLimitFatalError,
4454 "MemoryAllocationFailed",option);
4455 node->data = (void *)cli_wand->wand.images;
4456 cli_wand->wand.images = NewImageList();
4457 node->next = cli_wand->image_list_stack;
4458 cli_wand->image_list_stack = node;
anthony43f425d2012-02-26 12:58:58 +00004459
anthony8226e722012-04-05 14:25:46 +00004460 /* handle respect-parenthesis */
4461 if (IfMagickTrue(IsStringTrue(GetImageOption(cli_wand->wand.image_info,
4462 "respect-parenthesis"))))
4463 option="{"; /* fall-thru so as to push image settings too */
4464 else
anthony43f425d2012-02-26 12:58:58 +00004465 return;
anthony8226e722012-04-05 14:25:46 +00004466 }
4467 if (LocaleCompare("{",option) == 0) {
4468 /* stack 'push' of image_info settings */
4469 Stack
4470 *node;
anthony43f425d2012-02-26 12:58:58 +00004471
anthony8226e722012-04-05 14:25:46 +00004472 size_t
4473 size;
anthony43f425d2012-02-26 12:58:58 +00004474
anthony8226e722012-04-05 14:25:46 +00004475 size=0;
4476 node=cli_wand->image_info_stack;
4477 for ( ; node != (Stack *)NULL; node=node->next)
4478 size++;
4479 if ( size >= MAX_STACK_DEPTH )
4480 CLIWandExceptionReturn(OptionError,"CurlyBracesNestedTooDeeply",option);
4481 node=(Stack *) AcquireMagickMemory(sizeof(*node));
4482 if (node == (Stack *) NULL)
4483 CLIWandExceptionReturn(ResourceLimitFatalError,
4484 "MemoryAllocationFailed",option);
anthony43f425d2012-02-26 12:58:58 +00004485
anthony8226e722012-04-05 14:25:46 +00004486 node->data = (void *)cli_wand->wand.image_info;
4487 cli_wand->wand.image_info = CloneImageInfo(cli_wand->wand.image_info);
4488 if (cli_wand->wand.image_info == (ImageInfo *)NULL) {
4489 CLIWandException(ResourceLimitFatalError,"MemoryAllocationFailed",
4490 option);
anthony43f425d2012-02-26 12:58:58 +00004491 cli_wand->wand.image_info = (ImageInfo *)node->data;
4492 node = (Stack *)RelinquishMagickMemory(node);
anthony43f425d2012-02-26 12:58:58 +00004493 return;
4494 }
anthony8226e722012-04-05 14:25:46 +00004495
4496 node->next = cli_wand->image_info_stack;
4497 cli_wand->image_info_stack = node;
4498
4499 return;
4500 }
4501 if (LocaleCompare(")",option) == 0) {
4502 /* pop images from stack */
4503 Stack
4504 *node;
4505
4506 node = (Stack *)cli_wand->image_list_stack;
4507 if ( node == (Stack *)NULL)
4508 CLIWandExceptionReturn(OptionError,"UnbalancedParenthesis",option);
4509 cli_wand->image_list_stack = node->next;
4510
4511 AppendImageToList((Image **)&node->data,cli_wand->wand.images);
4512 cli_wand->wand.images= (Image *)node->data;
4513 node = (Stack *)RelinquishMagickMemory(node);
4514
4515 /* handle respect-parenthesis - of the previous 'pushed' settings */
4516 node = cli_wand->image_info_stack;
4517 if ( node != (Stack *)NULL)
4518 {
4519 if (IfMagickTrue(IsStringTrue(GetImageOption(
4520 cli_wand->wand.image_info,"respect-parenthesis"))))
4521 option="}"; /* fall-thru so as to pop image settings too */
4522 else
4523 return;
4524 }
4525 else
4526 return;
4527 }
4528 if (LocaleCompare("}",option) == 0) {
4529 /* pop image_info settings from stack */
4530 Stack
4531 *node;
4532
4533 node = (Stack *)cli_wand->image_info_stack;
4534 if ( node == (Stack *)NULL)
4535 CLIWandExceptionReturn(OptionError,"UnbalancedCurlyBraces",option);
4536 cli_wand->image_info_stack = node->next;
4537
4538 (void) DestroyImageInfo(cli_wand->wand.image_info);
4539 cli_wand->wand.image_info = (ImageInfo *)node->data;
4540 node = (Stack *)RelinquishMagickMemory(node);
4541
4542 GetDrawInfo(cli_wand->wand.image_info, cli_wand->draw_info);
4543 cli_wand->quantize_info=DestroyQuantizeInfo(cli_wand->quantize_info);
4544 cli_wand->quantize_info=AcquireQuantizeInfo(cli_wand->wand.image_info);
4545
4546 return;
4547 }
anthonyce8dcb32012-03-21 13:20:31 +00004548 if (LocaleCompare("clone",option+1) == 0) {
anthony43f425d2012-02-26 12:58:58 +00004549 Image
4550 *new_images;
4551
4552 if (*option == '+')
anthony24aa8822012-03-11 00:56:06 +00004553 arg1="-1";
anthony7bcfe7f2012-03-30 14:01:22 +00004554 if (IfMagickFalse(IsSceneGeometry(arg1,MagickFalse)))
anthony92c93bd2012-03-19 14:02:47 +00004555 CLIWandExceptionReturn(OptionError,"InvalidArgument",option);
anthony43f425d2012-02-26 12:58:58 +00004556 if ( cli_wand->image_list_stack == (Stack *)NULL)
anthony92c93bd2012-03-19 14:02:47 +00004557 CLIWandExceptionReturn(OptionError,"UnableToCloneImage",option);
anthony43f425d2012-02-26 12:58:58 +00004558 new_images = (Image *)cli_wand->image_list_stack->data;
4559 if (new_images == (Image *) NULL)
anthony92c93bd2012-03-19 14:02:47 +00004560 CLIWandExceptionReturn(OptionError,"UnableToCloneImage",option);
4561 new_images=CloneImages(new_images,arg1,_exception);
anthony43f425d2012-02-26 12:58:58 +00004562 if (new_images == (Image *) NULL)
anthony92c93bd2012-03-19 14:02:47 +00004563 CLIWandExceptionReturn(OptionError,"NoSuchImage",option);
anthony8226e722012-04-05 14:25:46 +00004564 AppendImageToList(&_images,new_images);
anthony43f425d2012-02-26 12:58:58 +00004565 return;
4566 }
anthony52bef752012-03-27 13:54:47 +00004567 /*
4568 Informational Operations
4569 */
anthony0ea037a2012-04-03 12:14:39 +00004570 if (LocaleCompare("version",option+1) == 0) {
anthony8226e722012-04-05 14:25:46 +00004571 (void) FormatLocaleFile(stdout,"Version: %s\n",
4572 GetMagickVersion((size_t *) NULL));
4573 (void) FormatLocaleFile(stdout,"Copyright: %s\n",
4574 GetMagickCopyright());
4575 (void) FormatLocaleFile(stdout,"Features: %s\n\n",
4576 GetMagickFeatures());
4577 return;
4578 }
anthonyce8dcb32012-03-21 13:20:31 +00004579 if (LocaleCompare("list",option+1) == 0) {
anthony8226e722012-04-05 14:25:46 +00004580 /* FUTURE: This should really be built into the MagickCore
4581 It does not actually require a cli-wand or and images!
4582 */
4583 ssize_t
4584 list;
anthony43f425d2012-02-26 12:58:58 +00004585
anthony8226e722012-04-05 14:25:46 +00004586 list=ParseCommandOption(MagickListOptions,MagickFalse,arg1);
4587 if ( list < 0 ) {
4588 CLIWandExceptionArg(OptionError,"UnrecognizedListType",option,arg1);
anthony43f425d2012-02-26 12:58:58 +00004589 return;
4590 }
anthony8226e722012-04-05 14:25:46 +00004591 switch (list)
4592 {
4593 case MagickCoderOptions:
4594 {
4595 (void) ListCoderInfo((FILE *) NULL,_exception);
4596 break;
4597 }
4598 case MagickColorOptions:
4599 {
4600 (void) ListColorInfo((FILE *) NULL,_exception);
4601 break;
4602 }
4603 case MagickConfigureOptions:
4604 {
4605 (void) ListConfigureInfo((FILE *) NULL,_exception);
4606 break;
4607 }
4608 case MagickDelegateOptions:
4609 {
4610 (void) ListDelegateInfo((FILE *) NULL,_exception);
4611 break;
4612 }
4613 case MagickFontOptions:
4614 {
4615 (void) ListTypeInfo((FILE *) NULL,_exception);
4616 break;
4617 }
4618 case MagickFormatOptions:
4619 (void) ListMagickInfo((FILE *) NULL,_exception);
4620 break;
4621 case MagickLocaleOptions:
4622 (void) ListLocaleInfo((FILE *) NULL,_exception);
4623 break;
4624 case MagickLogOptions:
4625 (void) ListLogInfo((FILE *) NULL,_exception);
4626 break;
4627 case MagickMagicOptions:
4628 (void) ListMagicInfo((FILE *) NULL,_exception);
4629 break;
4630 case MagickMimeOptions:
4631 (void) ListMimeInfo((FILE *) NULL,_exception);
4632 break;
4633 case MagickModuleOptions:
4634 (void) ListModuleInfo((FILE *) NULL,_exception);
4635 break;
4636 case MagickPolicyOptions:
4637 (void) ListPolicyInfo((FILE *) NULL,_exception);
4638 break;
4639 case MagickResourceOptions:
4640 (void) ListMagickResourceInfo((FILE *) NULL,_exception);
4641 break;
4642 case MagickThresholdOptions:
4643 (void) ListThresholdMaps((FILE *) NULL,_exception);
4644 break;
4645 default:
4646 (void) ListCommandOptions((FILE *) NULL,(CommandOption) list,
4647 _exception);
4648 break;
4649 }
4650 return;
4651 }
anthony43f425d2012-02-26 12:58:58 +00004652
4653#if 0
anthony43f425d2012-02-26 12:58:58 +00004654 // Other 'special' options this should handle
anthony5216f822012-04-10 13:02:37 +00004655 // "region" "reset" "arg"
anthony43f425d2012-02-26 12:58:58 +00004656 if ( ( process_flags & ProcessUnknownOptionError ) != 0 )
anthony43f425d2012-02-26 12:58:58 +00004657#endif
anthonyebb73a22012-03-22 14:25:52 +00004658 CLIWandException(OptionError,"UnrecognizedOption",option);
anthony43f425d2012-02-26 12:58:58 +00004659
anthony8226e722012-04-05 14:25:46 +00004660#undef _image_info
4661#undef _images
anthony92c93bd2012-03-19 14:02:47 +00004662#undef _exception
anthony8226e722012-04-05 14:25:46 +00004663#undef IfNormalOp
4664#undef IfPlusOp
anthony43f425d2012-02-26 12:58:58 +00004665}