blob: e59ac6523c167090a45f15b0e377d2784bad6172 [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 {
anthony92c93bd2012-03-19 14:02:47 +0000469 /* DEPRECIATED: _draw_info setting only: for -draw and -transform */
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 {
anthonyfd706f92012-01-19 04:22:02 +0000575 /* DEPRECIATED - now "undercolor" */
anthonye5fcd362012-04-09 04:02:09 +0000576 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 }
anthonyafa3dfc2012-03-03 11:31:30 +00001035 if (LocaleCompare("loop",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001036 {
anthony72feaa62012-01-17 06:46:23 +00001037 /* SyncImageSettings() used to set per-image attribute. */
anthonyfe1aa782012-03-24 13:43:04 +00001038 arg1=ArgOption("0");
anthony7bcfe7f2012-03-30 14:01:22 +00001039 if (IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00001040 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1041 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +00001042 break;
1043 }
anthonyebb73a22012-03-22 14:25:52 +00001044 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001045 }
1046 case 'm':
1047 {
anthonyafa3dfc2012-03-03 11:31:30 +00001048 if (LocaleCompare("mattecolor",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001049 {
anthony72feaa62012-01-17 06:46:23 +00001050 /* SyncImageSettings() used to set per-image attribute. */
anthony92c93bd2012-03-19 14:02:47 +00001051 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony72feaa62012-01-17 06:46:23 +00001052 (void) QueryColorCompliance(ArgOption(MatteColor),AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +00001053 &_image_info->matte_color,_exception);
anthony805a2d42011-09-25 08:25:12 +00001054 break;
1055 }
anthonyafa3dfc2012-03-03 11:31:30 +00001056 if (LocaleCompare("monitor",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001057 {
anthony92c93bd2012-03-19 14:02:47 +00001058 (void) SetImageInfoProgressMonitor(_image_info, IfSetOption?
anthony31f1bf72012-01-30 12:37:22 +00001059 MonitorProgress: (MagickProgressMonitor) NULL, (void *) NULL);
anthony805a2d42011-09-25 08:25:12 +00001060 break;
1061 }
anthonyafa3dfc2012-03-03 11:31:30 +00001062 if (LocaleCompare("monochrome",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001063 {
anthony24aa8822012-03-11 00:56:06 +00001064 /* Setting (used by some input coders!) -- why?
1065 Warning: This is also Special '-type' SimpleOperator
anthony72feaa62012-01-17 06:46:23 +00001066 */
anthony92c93bd2012-03-19 14:02:47 +00001067 _image_info->monochrome= ArgBoolean;
anthony805a2d42011-09-25 08:25:12 +00001068 break;
1069 }
anthonyebb73a22012-03-22 14:25:52 +00001070 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001071 }
1072 case 'o':
1073 {
anthonyafa3dfc2012-03-03 11:31:30 +00001074 if (LocaleCompare("orient",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001075 {
anthony72feaa62012-01-17 06:46:23 +00001076 /* Is not used when defining for new images.
anthonydcf510d2011-10-30 13:51:40 +00001077 This makes it more of a 'operation' than a setting
anthony72feaa62012-01-17 06:46:23 +00001078 FUTURE: make set meta-data operator instead.
1079 SyncImageSettings() used to set per-image attribute.
anthonydcf510d2011-10-30 13:51:40 +00001080 */
anthony7bc87992012-03-25 02:32:51 +00001081 parse=ParseCommandOption(MagickOrientationOptions,MagickFalse,
1082 ArgOption("undefined"));
1083 if (parse < 0)
1084 CLIWandExceptArgBreak(OptionError,"UnrecognizedImageOrientation",
1085 option,arg1);
1086 _image_info->orientation=(OrientationType)parse;
anthony92c93bd2012-03-19 14:02:47 +00001087 (void) SetImageOption(_image_info,option+1, ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +00001088 break;
1089 }
anthonyebb73a22012-03-22 14:25:52 +00001090 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001091 }
1092 case 'p':
1093 {
anthonyafa3dfc2012-03-03 11:31:30 +00001094 if (LocaleCompare("page",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001095 {
anthony7bc87992012-03-25 02:32:51 +00001096 /* Only used for new images and image generators.
anthony72feaa62012-01-17 06:46:23 +00001097 SyncImageSettings() used to set per-image attribute. ?????
1098 That last is WRONG!!!!
anthony7bc87992012-03-25 02:32:51 +00001099 FUTURE: adjust named 'page' sizes according density
anthony72feaa62012-01-17 06:46:23 +00001100 */
anthony805a2d42011-09-25 08:25:12 +00001101 char
1102 *canonical_page,
1103 page[MaxTextExtent];
1104
1105 const char
1106 *image_option;
1107
1108 MagickStatusType
1109 flags;
1110
1111 RectangleInfo
1112 geometry;
1113
anthonydcf510d2011-10-30 13:51:40 +00001114 if (!IfSetOption)
anthony805a2d42011-09-25 08:25:12 +00001115 {
anthony92c93bd2012-03-19 14:02:47 +00001116 (void) DeleteImageOption(_image_info,option+1);
1117 (void) CloneString(&_image_info->page,(char *) NULL);
anthony805a2d42011-09-25 08:25:12 +00001118 break;
1119 }
1120 (void) ResetMagickMemory(&geometry,0,sizeof(geometry));
anthony92c93bd2012-03-19 14:02:47 +00001121 image_option=GetImageOption(_image_info,"page");
anthony805a2d42011-09-25 08:25:12 +00001122 if (image_option != (const char *) NULL)
1123 flags=ParseAbsoluteGeometry(image_option,&geometry);
anthony24aa8822012-03-11 00:56:06 +00001124 canonical_page=GetPageGeometry(arg1);
anthony805a2d42011-09-25 08:25:12 +00001125 flags=ParseAbsoluteGeometry(canonical_page,&geometry);
1126 canonical_page=DestroyString(canonical_page);
1127 (void) FormatLocaleString(page,MaxTextExtent,"%lux%lu",
1128 (unsigned long) geometry.width,(unsigned long) geometry.height);
1129 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
1130 (void) FormatLocaleString(page,MaxTextExtent,"%lux%lu%+ld%+ld",
1131 (unsigned long) geometry.width,(unsigned long) geometry.height,
1132 (long) geometry.x,(long) geometry.y);
anthony92c93bd2012-03-19 14:02:47 +00001133 (void) SetImageOption(_image_info,option+1,page);
1134 (void) CloneString(&_image_info->page,page);
anthony805a2d42011-09-25 08:25:12 +00001135 break;
1136 }
anthonyafa3dfc2012-03-03 11:31:30 +00001137 if (LocaleCompare("ping",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001138 {
anthony92c93bd2012-03-19 14:02:47 +00001139 _image_info->ping = ArgBoolean;
anthony805a2d42011-09-25 08:25:12 +00001140 break;
1141 }
anthonyafa3dfc2012-03-03 11:31:30 +00001142 if (LocaleCompare("pointsize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001143 {
anthonyf42014d2012-03-25 09:53:06 +00001144 if (IfSetOption) {
anthony7bcfe7f2012-03-30 14:01:22 +00001145 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00001146 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1147 _image_info->pointsize =
1148 _draw_info->pointsize =
1149 StringToDouble(arg1,(char **) NULL);
1150 }
1151 else {
1152 _image_info->pointsize=0.0; /* unset pointsize */
1153 _draw_info->pointsize=12.0;
1154 }
anthony805a2d42011-09-25 08:25:12 +00001155 break;
1156 }
anthonyafa3dfc2012-03-03 11:31:30 +00001157 if (LocaleCompare("precision",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001158 {
anthonyf42014d2012-03-25 09:53:06 +00001159 arg1=ArgOption("-1");
anthony7bcfe7f2012-03-30 14:01:22 +00001160 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00001161 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1162 (void) SetMagickPrecision(StringToInteger(arg1));
anthony805a2d42011-09-25 08:25:12 +00001163 break;
1164 }
anthonydcf510d2011-10-30 13:51:40 +00001165 /* FUTURE: Only the 'preview' coder appears to use this
anthonya3ef4ed2012-03-17 06:52:53 +00001166 * DEPRECIATE the coder? Leaving only the 'preview' operator.
anthonyafa3dfc2012-03-03 11:31:30 +00001167 if (LocaleCompare("preview",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001168 {
anthony92c93bd2012-03-19 14:02:47 +00001169 _image_info->preview_type=UndefinedPreview;
anthonydcf510d2011-10-30 13:51:40 +00001170 if (IfSetOption)
anthony92c93bd2012-03-19 14:02:47 +00001171 _image_info->preview_type=(PreviewType) ParseCommandOption(
anthony24aa8822012-03-11 00:56:06 +00001172 MagickPreviewOptions,MagickFalse,arg1);
anthony805a2d42011-09-25 08:25:12 +00001173 break;
1174 }
anthonydcf510d2011-10-30 13:51:40 +00001175 */
anthonyebb73a22012-03-22 14:25:52 +00001176 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001177 }
1178 case 'q':
1179 {
anthonyafa3dfc2012-03-03 11:31:30 +00001180 if (LocaleCompare("quality",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001181 {
anthony7bcfe7f2012-03-30 14:01:22 +00001182 if (IfMagickFalse(IsGeometry(arg1)))
anthony7bc87992012-03-25 02:32:51 +00001183 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyf42014d2012-03-25 09:53:06 +00001184 _image_info->quality= IfSetOption ? StringToUnsignedLong(arg1)
1185 : UNDEFINED_COMPRESSION_QUALITY;
anthony92c93bd2012-03-19 14:02:47 +00001186 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +00001187 break;
1188 }
anthonyafa3dfc2012-03-03 11:31:30 +00001189 if (LocaleCompare("quantize",option+1) == 0)
anthonyafbaed72011-10-26 12:05:04 +00001190 {
anthony92c93bd2012-03-19 14:02:47 +00001191 /* Just a set direct in _quantize_info */
anthony7bc87992012-03-25 02:32:51 +00001192 arg1=ArgOption("undefined");
1193 parse=ParseCommandOption(MagickColorspaceOptions,MagickFalse,arg1);
1194 if (parse < 0)
1195 CLIWandExceptArgBreak(OptionError,"UnrecognizedColorspace",
1196 option,arg1);
1197 _quantize_info->colorspace=(ColorspaceType)parse;
anthonyafbaed72011-10-26 12:05:04 +00001198 break;
1199 }
anthonyafa3dfc2012-03-03 11:31:30 +00001200 if (LocaleCompare("quiet",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001201 {
anthonyf42014d2012-03-25 09:53:06 +00001202 /* FUTURE: if two -quiet is performed you can not do +quiet!
1203 This needs to be checked over thoughly.
1204 */
anthony805a2d42011-09-25 08:25:12 +00001205 static WarningHandler
1206 warning_handler = (WarningHandler) NULL;
anthony72feaa62012-01-17 06:46:23 +00001207
anthonyafbaed72011-10-26 12:05:04 +00001208 WarningHandler
1209 tmp = SetWarningHandler((WarningHandler) NULL);
anthony805a2d42011-09-25 08:25:12 +00001210
anthonyafbaed72011-10-26 12:05:04 +00001211 if ( tmp != (WarningHandler) NULL)
1212 warning_handler = tmp; /* remember the old handler */
1213 if (!IfSetOption) /* set the old handler */
1214 warning_handler=SetWarningHandler(warning_handler);
anthony805a2d42011-09-25 08:25:12 +00001215 break;
1216 }
anthonyebb73a22012-03-22 14:25:52 +00001217 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001218 }
1219 case 'r':
1220 {
anthonyafa3dfc2012-03-03 11:31:30 +00001221 if (LocaleCompare("red-primary",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001222 {
anthonydcf510d2011-10-30 13:51:40 +00001223 /* Image chromaticity X,Y NB: Y=X if Y not defined
1224 Used by many coders
anthony72feaa62012-01-17 06:46:23 +00001225 SyncImageSettings() used to set per-image attribute.
anthonydcf510d2011-10-30 13:51:40 +00001226 */
anthonyf42014d2012-03-25 09:53:06 +00001227 arg1=ArgOption("0.0");
anthony7bcfe7f2012-03-30 14:01:22 +00001228 if (IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00001229 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyf42014d2012-03-25 09:53:06 +00001230 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +00001231 break;
1232 }
cristyb0f7a182012-04-06 23:33:11 +00001233 if (LocaleCompare("regard-warnings",option+1) == 0)
anthonye5fcd362012-04-09 04:02:09 +00001234 /* FUTURE: to be replaced by a 'fatal-level' type setting */
cristyb0f7a182012-04-06 23:33:11 +00001235 break;
anthonyafa3dfc2012-03-03 11:31:30 +00001236 if (LocaleCompare("render",option+1) == 0)
anthonyafbaed72011-10-26 12:05:04 +00001237 {
anthony92c93bd2012-03-19 14:02:47 +00001238 /* _draw_info only setting */
1239 _draw_info->render= ArgBooleanNot;
anthonyafbaed72011-10-26 12:05:04 +00001240 break;
1241 }
anthony756cd0d2012-04-08 12:41:44 +00001242 if (LocaleCompare("respect-parenthesis",option+1) == 0)
1243 {
1244 /* link image and setting stacks - option is itself saved on stack! */
1245 (void) SetImageOption(_image_info,option+1,ArgBooleanString);
1246 break;
1247 }
anthonyebb73a22012-03-22 14:25:52 +00001248 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001249 }
1250 case 's':
1251 {
anthonyafa3dfc2012-03-03 11:31:30 +00001252 if (LocaleCompare("sampling-factor",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001253 {
anthonyafbaed72011-10-26 12:05:04 +00001254 /* FUTURE: should be converted to jpeg:sampling_factor */
anthony7bcfe7f2012-03-30 14:01:22 +00001255 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00001256 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001257 (void) CloneString(&_image_info->sampling_factor,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +00001258 break;
1259 }
anthonyafa3dfc2012-03-03 11:31:30 +00001260 if (LocaleCompare("scene",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001261 {
anthonyf42014d2012-03-25 09:53:06 +00001262 /* SyncImageSettings() used to set this as a per-image attribute.
anthony72feaa62012-01-17 06:46:23 +00001263 What ??? Why ????
1264 */
anthony7bcfe7f2012-03-30 14:01:22 +00001265 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00001266 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001267 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1268 _image_info->scene=StringToUnsignedLong(ArgOption("0"));
anthony805a2d42011-09-25 08:25:12 +00001269 break;
1270 }
anthonyafa3dfc2012-03-03 11:31:30 +00001271 if (LocaleCompare("seed",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001272 {
anthony7bcfe7f2012-03-30 14:01:22 +00001273 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00001274 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyafbaed72011-10-26 12:05:04 +00001275 SeedPseudoRandomGenerator(
anthony24aa8822012-03-11 00:56:06 +00001276 IfSetOption ? (size_t) StringToUnsignedLong(arg1)
anthonyafbaed72011-10-26 12:05:04 +00001277 : (size_t) time((time_t *) NULL) );
anthony805a2d42011-09-25 08:25:12 +00001278 break;
1279 }
anthonyafa3dfc2012-03-03 11:31:30 +00001280 if (LocaleCompare("size",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001281 {
anthony92c93bd2012-03-19 14:02:47 +00001282 /* FUTURE: string in _image_info -- convert to Option ???
anthonyafbaed72011-10-26 12:05:04 +00001283 Look at the special handling for "size" in SetImageOption()
anthony74b1cfc2011-10-06 12:44:16 +00001284 */
anthony92c93bd2012-03-19 14:02:47 +00001285 (void) CloneString(&_image_info->size,ArgOption(NULL));
anthonyafbaed72011-10-26 12:05:04 +00001286 break;
1287 }
anthonyafa3dfc2012-03-03 11:31:30 +00001288 if (LocaleCompare("stretch",option+1) == 0)
anthonyafbaed72011-10-26 12:05:04 +00001289 {
anthonyf42014d2012-03-25 09:53:06 +00001290 arg1=ArgOption("undefined");
1291 parse = ParseCommandOption(MagickStretchOptions,MagickFalse,arg1);
1292 if (parse < 0)
1293 CLIWandExceptArgBreak(OptionError,"UnrecognizedStretchType",
1294 option,arg1);
1295 _draw_info->stretch=(StretchType) parse;
anthony805a2d42011-09-25 08:25:12 +00001296 break;
1297 }
anthonyafa3dfc2012-03-03 11:31:30 +00001298 if (LocaleCompare("stroke",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001299 {
anthonyafbaed72011-10-26 12:05:04 +00001300 /* set stroke color OR stroke-pattern
anthonyfd706f92012-01-19 04:22:02 +00001301 UPDATE: ensure stroke color is not destroyed is a pattern
1302 is given. Just in case the color is also used for other purposes.
anthonyafbaed72011-10-26 12:05:04 +00001303 */
anthony72feaa62012-01-17 06:46:23 +00001304 MagickBooleanType
1305 status;
anthonyafbaed72011-10-26 12:05:04 +00001306
1307 ExceptionInfo
1308 *sans;
1309
anthonyfd706f92012-01-19 04:22:02 +00001310 PixelInfo
1311 color;
1312
anthony2a0ec8c2012-03-24 04:35:56 +00001313 arg1 = ArgOption("none"); /* +fill turns it off! */
1314 (void) SetImageOption(_image_info,option+1,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001315 if (_draw_info->stroke_pattern != (Image *) NULL)
1316 _draw_info->stroke_pattern=DestroyImage(_draw_info->stroke_pattern);
anthony72feaa62012-01-17 06:46:23 +00001317
1318 /* is it a color or a image? -- ignore exceptions */
anthonyafbaed72011-10-26 12:05:04 +00001319 sans=AcquireExceptionInfo();
anthony2a0ec8c2012-03-24 04:35:56 +00001320 status=QueryColorCompliance(arg1,AllCompliance,&color,sans);
anthonyafbaed72011-10-26 12:05:04 +00001321 sans=DestroyExceptionInfo(sans);
anthonyfd706f92012-01-19 04:22:02 +00001322
anthony7bcfe7f2012-03-30 14:01:22 +00001323 if (IfMagickFalse(status))
anthony2a0ec8c2012-03-24 04:35:56 +00001324 _draw_info->stroke_pattern=GetImageCache(_image_info,arg1,_exception);
anthonyfd706f92012-01-19 04:22:02 +00001325 else
anthony92c93bd2012-03-19 14:02:47 +00001326 _draw_info->stroke=color;
anthony805a2d42011-09-25 08:25:12 +00001327 break;
1328 }
anthonyafa3dfc2012-03-03 11:31:30 +00001329 if (LocaleCompare("strokewidth",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001330 {
anthony7bcfe7f2012-03-30 14:01:22 +00001331 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00001332 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001333 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1334 _draw_info->stroke_width=StringToDouble(ArgOption("1.0"),
anthony72feaa62012-01-17 06:46:23 +00001335 (char **) NULL);
anthonyafbaed72011-10-26 12:05:04 +00001336 break;
1337 }
anthonyafa3dfc2012-03-03 11:31:30 +00001338 if (LocaleCompare("style",option+1) == 0)
anthonyafbaed72011-10-26 12:05:04 +00001339 {
anthonyf42014d2012-03-25 09:53:06 +00001340 arg1=ArgOption("undefined");
1341 parse = ParseCommandOption(MagickStyleOptions,MagickFalse,arg1);
1342 if (parse < 0)
1343 CLIWandExceptArgBreak(OptionError,"UnrecognizedStyleType",
1344 option,arg1);
1345 _draw_info->style=(StyleType) parse;
anthony805a2d42011-09-25 08:25:12 +00001346 break;
1347 }
anthonyafa3dfc2012-03-03 11:31:30 +00001348 if (LocaleCompare("synchronize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001349 {
anthonyf42014d2012-03-25 09:53:06 +00001350 /* FUTURE: syncronize to storage - but what does that mean? */
anthony92c93bd2012-03-19 14:02:47 +00001351 _image_info->synchronize = ArgBoolean;
anthony805a2d42011-09-25 08:25:12 +00001352 break;
1353 }
anthonyebb73a22012-03-22 14:25:52 +00001354 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001355 }
1356 case 't':
1357 {
anthonyafa3dfc2012-03-03 11:31:30 +00001358 if (LocaleCompare("taint",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001359 {
anthony72feaa62012-01-17 06:46:23 +00001360 /* SyncImageSettings() used to set per-image attribute. */
anthony92c93bd2012-03-19 14:02:47 +00001361 (void) SetImageOption(_image_info,option+1,ArgBooleanString);
anthony805a2d42011-09-25 08:25:12 +00001362 break;
1363 }
anthonyafa3dfc2012-03-03 11:31:30 +00001364 if (LocaleCompare("texture",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001365 {
anthony52bef752012-03-27 13:54:47 +00001366 /* FUTURE: move _image_info string to option splay-tree
1367 Other than "montage" what uses "texture" ????
1368 */
anthony92c93bd2012-03-19 14:02:47 +00001369 (void) CloneString(&_image_info->texture,ArgOption(NULL));
anthonyafbaed72011-10-26 12:05:04 +00001370 break;
1371 }
anthonyafa3dfc2012-03-03 11:31:30 +00001372 if (LocaleCompare("tile",option+1) == 0)
anthonyafbaed72011-10-26 12:05:04 +00001373 {
anthony92c93bd2012-03-19 14:02:47 +00001374 _draw_info->fill_pattern=IfSetOption
1375 ?GetImageCache(_image_info,arg1,_exception)
1376 :DestroyImage(_draw_info->fill_pattern);
anthony805a2d42011-09-25 08:25:12 +00001377 break;
1378 }
anthonyafa3dfc2012-03-03 11:31:30 +00001379 if (LocaleCompare("tile-offset",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001380 {
anthony72feaa62012-01-17 06:46:23 +00001381 /* SyncImageSettings() used to set per-image attribute. ??? */
anthony52bef752012-03-27 13:54:47 +00001382 arg1=ArgOption("0");
anthony7bcfe7f2012-03-30 14:01:22 +00001383 if (IfMagickFalse(IsGeometry(arg1)))
anthony52bef752012-03-27 13:54:47 +00001384 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1385 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +00001386 break;
1387 }
anthonyafa3dfc2012-03-03 11:31:30 +00001388 if (LocaleCompare("transparent-color",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001389 {
anthony92c93bd2012-03-19 14:02:47 +00001390 /* FUTURE: both _image_info attribute & ImageOption in use!
1391 _image_info only used for generating new images.
anthony72feaa62012-01-17 06:46:23 +00001392 SyncImageSettings() used to set per-image attribute.
1393
anthonyafbaed72011-10-26 12:05:04 +00001394 Note that +transparent-color, means fall-back to image
1395 attribute so ImageOption is deleted, not set to a default.
1396 */
anthony7bcfe7f2012-03-30 14:01:22 +00001397 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthony52bef752012-03-27 13:54:47 +00001398 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001399 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony72feaa62012-01-17 06:46:23 +00001400 (void) QueryColorCompliance(ArgOption("none"),AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +00001401 &_image_info->transparent_color,_exception);
anthony805a2d42011-09-25 08:25:12 +00001402 break;
1403 }
anthonyafa3dfc2012-03-03 11:31:30 +00001404 if (LocaleCompare("treedepth",option+1) == 0)
anthony31f1bf72012-01-30 12:37:22 +00001405 {
anthony92c93bd2012-03-19 14:02:47 +00001406 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1407 _quantize_info->tree_depth=StringToUnsignedLong(ArgOption("0"));
anthony31f1bf72012-01-30 12:37:22 +00001408 break;
1409 }
anthonyafa3dfc2012-03-03 11:31:30 +00001410 if (LocaleCompare("type",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001411 {
anthony72feaa62012-01-17 06:46:23 +00001412 /* SyncImageSettings() used to set per-image attribute. */
anthony52bef752012-03-27 13:54:47 +00001413 parse=ParseCommandOption(MagickTypeOptions,MagickFalse,
1414 ArgOption("undefined"));
1415 if (parse < 0)
1416 CLIWandExceptArgBreak(OptionError,"UnrecognizedImageType",
1417 option,arg1);
1418 _image_info->type=(ImageType) parse;
anthony92c93bd2012-03-19 14:02:47 +00001419 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +00001420 break;
1421 }
anthonyebb73a22012-03-22 14:25:52 +00001422 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001423 }
1424 case 'u':
1425 {
anthonyafa3dfc2012-03-03 11:31:30 +00001426 if (LocaleCompare("undercolor",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001427 {
anthony92c93bd2012-03-19 14:02:47 +00001428 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony72feaa62012-01-17 06:46:23 +00001429 (void) QueryColorCompliance(ArgOption("none"),AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +00001430 &_draw_info->undercolor,_exception);
anthony805a2d42011-09-25 08:25:12 +00001431 break;
1432 }
anthonyafa3dfc2012-03-03 11:31:30 +00001433 if (LocaleCompare("units",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001434 {
anthony72feaa62012-01-17 06:46:23 +00001435 /* SyncImageSettings() used to set per-image attribute.
anthony92c93bd2012-03-19 14:02:47 +00001436 Should this effect _draw_info X and Y resolution?
anthony72feaa62012-01-17 06:46:23 +00001437 FUTURE: this probably should be part of the density setting
1438 */
anthony52bef752012-03-27 13:54:47 +00001439 parse=ParseCommandOption(MagickResolutionOptions,MagickFalse,
1440 ArgOption("undefined"));
1441 if (parse < 0)
1442 CLIWandExceptArgBreak(OptionError,"UnrecognizedUnitsType",
1443 option,arg1);
1444 _image_info->units=(ResolutionType) parse;
anthony92c93bd2012-03-19 14:02:47 +00001445 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +00001446 break;
1447 }
anthonyebb73a22012-03-22 14:25:52 +00001448 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001449 }
1450 case 'v':
1451 {
anthonyafa3dfc2012-03-03 11:31:30 +00001452 if (LocaleCompare("verbose",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001453 {
anthony24aa8822012-03-11 00:56:06 +00001454 /* FUTURE: Remember all options become image artifacts
anthony92c93bd2012-03-19 14:02:47 +00001455 _image_info->verbose is only used by coders.
anthonyab3a50c2011-10-27 11:48:57 +00001456 */
anthony92c93bd2012-03-19 14:02:47 +00001457 (void) SetImageOption(_image_info,option+1,ArgBooleanString);
1458 _image_info->verbose= ArgBoolean;
1459 _image_info->ping=MagickFalse; /* verbose can't be a ping */
anthony805a2d42011-09-25 08:25:12 +00001460 break;
1461 }
anthonyafa3dfc2012-03-03 11:31:30 +00001462 if (LocaleCompare("view",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001463 {
anthony92c93bd2012-03-19 14:02:47 +00001464 /* FUTURE: Convert from _image_info to ImageOption
anthonyab3a50c2011-10-27 11:48:57 +00001465 Only used by coder FPX
anthony52bef752012-03-27 13:54:47 +00001466 And it only tests existance, not its content!
anthonyab3a50c2011-10-27 11:48:57 +00001467 */
anthony92c93bd2012-03-19 14:02:47 +00001468 (void) CloneString(&_image_info->view,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +00001469 break;
1470 }
anthonyafa3dfc2012-03-03 11:31:30 +00001471 if (LocaleCompare("virtual-pixel",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001472 {
anthonyfd706f92012-01-19 04:22:02 +00001473 /* SyncImageSettings() used to set per-image attribute.
1474 This is VERY deep in the image caching structure.
1475 */
anthony52bef752012-03-27 13:54:47 +00001476 parse=ParseCommandOption(MagickVirtualPixelOptions,MagickFalse,
1477 ArgOption("undefined"));
1478 if (parse < 0)
1479 CLIWandExceptArgBreak(OptionError,"UnrecognizedVirtualPixelMethod",
1480 option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001481 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +00001482 break;
1483 }
anthonyebb73a22012-03-22 14:25:52 +00001484 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001485 }
1486 case 'w':
1487 {
anthonyafa3dfc2012-03-03 11:31:30 +00001488 if (LocaleCompare("weight",option+1) == 0)
anthonyab3a50c2011-10-27 11:48:57 +00001489 {
anthony72feaa62012-01-17 06:46:23 +00001490 /* Just what does using a font 'weight' do ???
anthonydcf510d2011-10-30 13:51:40 +00001491 There is no "-list weight" output (reference manual says there is)
anthonyab3a50c2011-10-27 11:48:57 +00001492 */
anthony52bef752012-03-27 13:54:47 +00001493 arg1=ArgOption("all");
anthony92c93bd2012-03-19 14:02:47 +00001494 _draw_info->weight=StringToUnsignedLong(arg1);
anthony24aa8822012-03-11 00:56:06 +00001495 if (LocaleCompare(arg1,"all") == 0)
anthony92c93bd2012-03-19 14:02:47 +00001496 _draw_info->weight=0;
anthony24aa8822012-03-11 00:56:06 +00001497 if (LocaleCompare(arg1,"bold") == 0)
anthony92c93bd2012-03-19 14:02:47 +00001498 _draw_info->weight=700;
anthony24aa8822012-03-11 00:56:06 +00001499 if (LocaleCompare(arg1,"bolder") == 0)
anthony92c93bd2012-03-19 14:02:47 +00001500 if (_draw_info->weight <= 800)
1501 _draw_info->weight+=100;
anthony24aa8822012-03-11 00:56:06 +00001502 if (LocaleCompare(arg1,"lighter") == 0)
anthony92c93bd2012-03-19 14:02:47 +00001503 if (_draw_info->weight >= 100)
1504 _draw_info->weight-=100;
anthony24aa8822012-03-11 00:56:06 +00001505 if (LocaleCompare(arg1,"normal") == 0)
anthony92c93bd2012-03-19 14:02:47 +00001506 _draw_info->weight=400;
anthonyab3a50c2011-10-27 11:48:57 +00001507 break;
1508 }
anthonyafa3dfc2012-03-03 11:31:30 +00001509 if (LocaleCompare("white-point",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001510 {
anthony72feaa62012-01-17 06:46:23 +00001511 /* Used as a image chromaticity setting
1512 SyncImageSettings() used to set per-image attribute.
1513 */
anthony52bef752012-03-27 13:54:47 +00001514 arg1=ArgOption("0.0");
anthony7bcfe7f2012-03-30 14:01:22 +00001515 if (IfMagickFalse(IsGeometry(arg1)))
anthony52bef752012-03-27 13:54:47 +00001516 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1517 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +00001518 break;
1519 }
anthonyebb73a22012-03-22 14:25:52 +00001520 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001521 }
1522 default:
anthonyebb73a22012-03-22 14:25:52 +00001523 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001524 }
anthony24aa8822012-03-11 00:56:06 +00001525
anthony92c93bd2012-03-19 14:02:47 +00001526#undef _image_info
1527#undef _exception
1528#undef _draw_info
1529#undef _quantize_info
anthonyfd706f92012-01-19 04:22:02 +00001530#undef IfSetOption
anthonyfd706f92012-01-19 04:22:02 +00001531#undef ArgBoolean
anthony24aa8822012-03-11 00:56:06 +00001532#undef ArgBooleanNot
1533#undef ArgBooleanString
1534#undef ArgOption
anthonyfd706f92012-01-19 04:22:02 +00001535
anthony31f1bf72012-01-30 12:37:22 +00001536 return;
anthony805a2d42011-09-25 08:25:12 +00001537}
1538
1539/*
1540%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1541% %
1542% %
1543% %
anthony43f425d2012-02-26 12:58:58 +00001544+ 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 +00001545% %
1546% %
1547% %
1548%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1549%
anthony31f1bf72012-01-30 12:37:22 +00001550% WandSimpleOperatorImages() applys one simple image operation given to all
anthony43f425d2012-02-26 12:58:58 +00001551% the images in the CLI wand, with the settings that was previously saved in
1552% the CLI wand.
anthonydcf510d2011-10-30 13:51:40 +00001553%
1554% It is assumed that any per-image settings are up-to-date with respect to
anthony43f425d2012-02-26 12:58:58 +00001555% extra settings that were already saved in the wand.
anthony805a2d42011-09-25 08:25:12 +00001556%
anthonyd1447672012-01-19 05:33:53 +00001557% The format of the WandSimpleOperatorImage method is:
anthony805a2d42011-09-25 08:25:12 +00001558%
anthony43f425d2012-02-26 12:58:58 +00001559% void CLISimpleOperatorImages(MagickCLI *cli_wand,
anthonyafa3dfc2012-03-03 11:31:30 +00001560% const char *option, const char *arg1, const char *arg2)
anthony805a2d42011-09-25 08:25:12 +00001561%
1562% A description of each parameter follows:
1563%
anthony43f425d2012-02-26 12:58:58 +00001564% o cli_wand: structure holding settings and images to be operated on
anthony805a2d42011-09-25 08:25:12 +00001565%
anthonyfd706f92012-01-19 04:22:02 +00001566% o option: The option string for the operation
anthonydcf510d2011-10-30 13:51:40 +00001567%
anthonyfd706f92012-01-19 04:22:02 +00001568% o arg1, arg2: optional argument strings to the operation
anthony805a2d42011-09-25 08:25:12 +00001569%
anthony31f1bf72012-01-30 12:37:22 +00001570% Any problems will be added to the 'exception' entry of the given wand.
anthony805a2d42011-09-25 08:25:12 +00001571%
anthony31f1bf72012-01-30 12:37:22 +00001572% Example usage...
anthonydcf510d2011-10-30 13:51:40 +00001573%
anthonyafa3dfc2012-03-03 11:31:30 +00001574% CLISimpleOperatorImages(cli_wand, "-crop","100x100+20+30",NULL);
1575% CLISimpleOperatorImages(cli_wand, "+repage",NULL,NULL);
1576% CLISimpleOperatorImages(cli_wand, "+distort","SRT","45");
anthonyfd706f92012-01-19 04:22:02 +00001577%
anthony24aa8822012-03-11 00:56:06 +00001578% Or for handling command line arguments EG: +/-option ["arg1"]
anthonydcf510d2011-10-30 13:51:40 +00001579%
anthony43f425d2012-02-26 12:58:58 +00001580% cli_wand
anthonydcf510d2011-10-30 13:51:40 +00001581% argc,argv
1582% i=index in argv
1583%
anthony2052d272012-02-28 12:48:29 +00001584% option_info = GetCommandOptionInfo(argv[i]);
1585% count=option_info->type;
1586% option_type=option_info->flags;
1587%
1588% if ( (option_type & SimpleOperatorOptionFlag) != 0 )
anthonyafa3dfc2012-03-03 11:31:30 +00001589% CLISimpleOperatorImages(cli_wand, argv[i],
anthonyfd706f92012-01-19 04:22:02 +00001590% count>=1 ? argv[i+1] : (char *)NULL,
1591% count>=2 ? argv[i+2] : (char *)NULL );
anthonydcf510d2011-10-30 13:51:40 +00001592% i += count+1;
1593%
anthony805a2d42011-09-25 08:25:12 +00001594*/
anthony31f1bf72012-01-30 12:37:22 +00001595
1596/*
1597 Internal subrountine to apply one simple image operation to the current
anthony43f425d2012-02-26 12:58:58 +00001598 image pointed to by the CLI wand.
anthony31f1bf72012-01-30 12:37:22 +00001599
1600 The image in the list may be modified in three different ways...
1601 * directly modified (EG: -negate, -gamma, -level, -annotate, -draw),
1602 * replaced by a new image (EG: -spread, -resize, -rotate, -morphology)
1603 * one image replace by a list of images (-separate and -crop only!)
1604
anthonyafa3dfc2012-03-03 11:31:30 +00001605 In each case the result replaces the single original image in the list, as
1606 well as the pointer to the modified image (last image added if replaced by a
1607 list of images) is returned.
anthony31f1bf72012-01-30 12:37:22 +00001608
1609 As the image pointed to may be replaced, the first image in the list may
1610 also change. GetFirstImageInList() should be used by caller if they wish
1611 return the Image pointer to the first image in list.
1612*/
anthony43f425d2012-02-26 12:58:58 +00001613static void CLISimpleOperatorImage(MagickCLI *cli_wand,
anthonyafa3dfc2012-03-03 11:31:30 +00001614 const char *option, const char *arg1, const char *arg2)
anthony805a2d42011-09-25 08:25:12 +00001615{
1616 Image *
1617 new_image;
1618
anthony805a2d42011-09-25 08:25:12 +00001619 GeometryInfo
1620 geometry_info;
1621
1622 RectangleInfo
1623 geometry;
1624
1625 MagickStatusType
anthony805a2d42011-09-25 08:25:12 +00001626 flags;
1627
anthony92c93bd2012-03-19 14:02:47 +00001628 ssize_t
anthony2a0ec8c2012-03-24 04:35:56 +00001629 parse;
anthony92c93bd2012-03-19 14:02:47 +00001630
anthony2e4501b2012-03-30 04:41:54 +00001631#define _image_info (cli_wand->wand.image_info)
1632#define _image (cli_wand->wand.images)
1633#define _exception (cli_wand->wand.exception)
1634#define _draw_info (cli_wand->draw_info)
1635#define _quantize_info (cli_wand->quantize_info)
anthonyafa3dfc2012-03-03 11:31:30 +00001636#define IfNormalOp (*option=='-')
1637#define IfPlusOp (*option!='-')
anthony7bcfe7f2012-03-30 14:01:22 +00001638#define normal_op IsMagickTrue(IfNormalOp)
1639#define plus_alt_op IsMagickFalse(IfNormalOp)
anthonyfd706f92012-01-19 04:22:02 +00001640
anthony43f425d2012-02-26 12:58:58 +00001641 assert(cli_wand != (MagickCLI *) NULL);
1642 assert(cli_wand->signature == WandSignature);
1643 assert(cli_wand->wand.signature == WandSignature);
anthony5330ae02012-03-20 14:17:01 +00001644 assert(_image != (Image *) NULL); /* an image must be present */
anthony7bcfe7f2012-03-30 14:01:22 +00001645 if (IfMagickTrue(cli_wand->wand.debug))
anthony43f425d2012-02-26 12:58:58 +00001646 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
anthonydcf510d2011-10-30 13:51:40 +00001647
anthony92c93bd2012-03-19 14:02:47 +00001648 (void) SyncImageSettings(_image_info,_image,_exception);
anthony24aa8822012-03-11 00:56:06 +00001649
anthony805a2d42011-09-25 08:25:12 +00001650 SetGeometryInfo(&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00001651
anthony5330ae02012-03-20 14:17:01 +00001652 new_image = (Image *)NULL; /* the replacement image, if not null at end */
anthony805a2d42011-09-25 08:25:12 +00001653
anthonyfd706f92012-01-19 04:22:02 +00001654 /* FUTURE: We may need somthing a little more optimized than this!
1655 Perhaps, do the 'sync' if 'settings tainted' before next operator.
1656 */
anthonyafa3dfc2012-03-03 11:31:30 +00001657 switch (*(option+1))
anthony805a2d42011-09-25 08:25:12 +00001658 {
1659 case 'a':
1660 {
anthonyafa3dfc2012-03-03 11:31:30 +00001661 if (LocaleCompare("adaptive-blur",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001662 {
anthony7bcfe7f2012-03-30 14:01:22 +00001663 if (IfMagickFalse(IsGeometry(arg1)))
anthony92c93bd2012-03-19 14:02:47 +00001664 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00001665 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00001666 if ((flags & SigmaValue) == 0)
1667 geometry_info.sigma=1.0;
anthony92c93bd2012-03-19 14:02:47 +00001668 new_image=AdaptiveBlurImage(_image,geometry_info.rho,
cristyaa2c16c2012-03-25 22:21:35 +00001669 geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00001670 break;
1671 }
anthonyafa3dfc2012-03-03 11:31:30 +00001672 if (LocaleCompare("adaptive-resize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001673 {
anthonyfe1aa782012-03-24 13:43:04 +00001674 /* FUTURE: Roll into a resize special operator */
anthony7bcfe7f2012-03-30 14:01:22 +00001675 if (IfMagickFalse(IsGeometry(arg1)))
anthony92c93bd2012-03-19 14:02:47 +00001676 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1677 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
1678 new_image=AdaptiveResizeImage(_image,geometry.width,geometry.height,
cristyaa2c16c2012-03-25 22:21:35 +00001679 _exception);
anthony805a2d42011-09-25 08:25:12 +00001680 break;
1681 }
anthonyafa3dfc2012-03-03 11:31:30 +00001682 if (LocaleCompare("adaptive-sharpen",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001683 {
anthony7bcfe7f2012-03-30 14:01:22 +00001684 if (IfMagickFalse(IsGeometry(arg1)))
anthony92c93bd2012-03-19 14:02:47 +00001685 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00001686 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00001687 if ((flags & SigmaValue) == 0)
1688 geometry_info.sigma=1.0;
anthony92c93bd2012-03-19 14:02:47 +00001689 new_image=AdaptiveSharpenImage(_image,geometry_info.rho,
cristyaa2c16c2012-03-25 22:21:35 +00001690 geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00001691 break;
1692 }
anthonyafa3dfc2012-03-03 11:31:30 +00001693 if (LocaleCompare("alpha",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001694 {
anthony2a0ec8c2012-03-24 04:35:56 +00001695 parse=ParseCommandOption(MagickAlphaOptions,MagickFalse,arg1);
1696 if (parse < 0)
anthony92c93bd2012-03-19 14:02:47 +00001697 CLIWandExceptArgBreak(OptionError,"UnrecognizedAlphaChannelType",
1698 option,arg1);
anthony2a0ec8c2012-03-24 04:35:56 +00001699 (void) SetImageAlphaChannel(_image,(AlphaChannelType)parse,
1700 _exception);
anthony805a2d42011-09-25 08:25:12 +00001701 break;
1702 }
anthonyafa3dfc2012-03-03 11:31:30 +00001703 if (LocaleCompare("annotate",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001704 {
1705 char
1706 *text,
1707 geometry[MaxTextExtent];
1708
anthony7bcfe7f2012-03-30 14:01:22 +00001709 if (IfMagickFalse(IsGeometry(arg1)))
anthony92c93bd2012-03-19 14:02:47 +00001710 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00001711 SetGeometryInfo(&geometry_info);
anthonyfd706f92012-01-19 04:22:02 +00001712 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00001713 if ((flags & SigmaValue) == 0)
1714 geometry_info.sigma=geometry_info.rho;
anthony92c93bd2012-03-19 14:02:47 +00001715 text=InterpretImageProperties(_image_info,_image,arg2,
1716 _exception);
anthony805a2d42011-09-25 08:25:12 +00001717 if (text == (char *) NULL)
1718 break;
anthony92c93bd2012-03-19 14:02:47 +00001719 (void) CloneString(&_draw_info->text,text);
anthony805a2d42011-09-25 08:25:12 +00001720 text=DestroyString(text);
1721 (void) FormatLocaleString(geometry,MaxTextExtent,"%+f%+f",
1722 geometry_info.xi,geometry_info.psi);
anthony92c93bd2012-03-19 14:02:47 +00001723 (void) CloneString(&_draw_info->geometry,geometry);
1724 _draw_info->affine.sx=cos(DegreesToRadians(
anthony805a2d42011-09-25 08:25:12 +00001725 fmod(geometry_info.rho,360.0)));
anthony92c93bd2012-03-19 14:02:47 +00001726 _draw_info->affine.rx=sin(DegreesToRadians(
anthony805a2d42011-09-25 08:25:12 +00001727 fmod(geometry_info.rho,360.0)));
anthony92c93bd2012-03-19 14:02:47 +00001728 _draw_info->affine.ry=(-sin(DegreesToRadians(
anthony805a2d42011-09-25 08:25:12 +00001729 fmod(geometry_info.sigma,360.0))));
anthony92c93bd2012-03-19 14:02:47 +00001730 _draw_info->affine.sy=cos(DegreesToRadians(
anthony805a2d42011-09-25 08:25:12 +00001731 fmod(geometry_info.sigma,360.0)));
anthony92c93bd2012-03-19 14:02:47 +00001732 (void) AnnotateImage(_image,_draw_info,_exception);
1733 GetAffineMatrix(&_draw_info->affine);
anthony805a2d42011-09-25 08:25:12 +00001734 break;
1735 }
anthonyafa3dfc2012-03-03 11:31:30 +00001736 if (LocaleCompare("auto-gamma",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001737 {
anthony92c93bd2012-03-19 14:02:47 +00001738 (void) AutoGammaImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00001739 break;
1740 }
anthonyafa3dfc2012-03-03 11:31:30 +00001741 if (LocaleCompare("auto-level",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001742 {
anthony92c93bd2012-03-19 14:02:47 +00001743 (void) AutoLevelImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00001744 break;
1745 }
anthonyafa3dfc2012-03-03 11:31:30 +00001746 if (LocaleCompare("auto-orient",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001747 {
anthony5330ae02012-03-20 14:17:01 +00001748 /* This should probably be a MagickCore function */
anthony92c93bd2012-03-19 14:02:47 +00001749 switch (_image->orientation)
anthony805a2d42011-09-25 08:25:12 +00001750 {
1751 case TopRightOrientation:
1752 {
anthony92c93bd2012-03-19 14:02:47 +00001753 new_image=FlopImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00001754 break;
1755 }
1756 case BottomRightOrientation:
1757 {
anthony92c93bd2012-03-19 14:02:47 +00001758 new_image=RotateImage(_image,180.0,_exception);
anthony805a2d42011-09-25 08:25:12 +00001759 break;
1760 }
1761 case BottomLeftOrientation:
1762 {
anthony92c93bd2012-03-19 14:02:47 +00001763 new_image=FlipImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00001764 break;
1765 }
1766 case LeftTopOrientation:
1767 {
anthony92c93bd2012-03-19 14:02:47 +00001768 new_image=TransposeImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00001769 break;
1770 }
1771 case RightTopOrientation:
1772 {
anthony92c93bd2012-03-19 14:02:47 +00001773 new_image=RotateImage(_image,90.0,_exception);
anthony805a2d42011-09-25 08:25:12 +00001774 break;
1775 }
1776 case RightBottomOrientation:
1777 {
anthony92c93bd2012-03-19 14:02:47 +00001778 new_image=TransverseImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00001779 break;
1780 }
1781 case LeftBottomOrientation:
1782 {
anthony92c93bd2012-03-19 14:02:47 +00001783 new_image=RotateImage(_image,270.0,_exception);
anthony805a2d42011-09-25 08:25:12 +00001784 break;
1785 }
1786 default:
1787 break;
1788 }
1789 if (new_image != (Image *) NULL)
1790 new_image->orientation=TopLeftOrientation;
1791 break;
1792 }
anthonyebb73a22012-03-22 14:25:52 +00001793 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001794 }
1795 case 'b':
1796 {
anthonyafa3dfc2012-03-03 11:31:30 +00001797 if (LocaleCompare("black-threshold",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001798 {
anthony7bcfe7f2012-03-30 14:01:22 +00001799 if (IfMagickFalse(IsGeometry(arg1)))
anthony5330ae02012-03-20 14:17:01 +00001800 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001801 (void) BlackThresholdImage(_image,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00001802 break;
1803 }
anthonyafa3dfc2012-03-03 11:31:30 +00001804 if (LocaleCompare("blue-shift",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001805 {
anthony805a2d42011-09-25 08:25:12 +00001806 geometry_info.rho=1.5;
anthony5330ae02012-03-20 14:17:01 +00001807 if (IfNormalOp) {
anthony7bcfe7f2012-03-30 14:01:22 +00001808 if (IfMagickFalse(IsGeometry(arg1)))
anthony5330ae02012-03-20 14:17:01 +00001809 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00001810 flags=ParseGeometry(arg1,&geometry_info);
anthony5330ae02012-03-20 14:17:01 +00001811 }
anthony92c93bd2012-03-19 14:02:47 +00001812 new_image=BlueShiftImage(_image,geometry_info.rho,_exception);
anthony805a2d42011-09-25 08:25:12 +00001813 break;
1814 }
anthonyafa3dfc2012-03-03 11:31:30 +00001815 if (LocaleCompare("blur",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001816 {
anthony7bcfe7f2012-03-30 14:01:22 +00001817 if (IfMagickFalse(IsGeometry(arg1)))
anthony5330ae02012-03-20 14:17:01 +00001818 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00001819 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00001820 if ((flags & SigmaValue) == 0)
1821 geometry_info.sigma=1.0;
cristyaa2c16c2012-03-25 22:21:35 +00001822 new_image=BlurImage(_image,geometry_info.rho,geometry_info.sigma,
1823 _exception);
anthony805a2d42011-09-25 08:25:12 +00001824 break;
1825 }
anthonyafa3dfc2012-03-03 11:31:30 +00001826 if (LocaleCompare("border",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001827 {
anthony31f1bf72012-01-30 12:37:22 +00001828 CompositeOperator
anthony5f867ae2011-10-09 10:28:34 +00001829 compose;
1830
1831 const char*
anthony5f867ae2011-10-09 10:28:34 +00001832 value;
1833
anthony7bcfe7f2012-03-30 14:01:22 +00001834 if (IfMagickFalse(IsGeometry(arg1)))
anthony5330ae02012-03-20 14:17:01 +00001835 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1836
anthony92c93bd2012-03-19 14:02:47 +00001837 value=GetImageOption(_image_info,"compose");
anthony5f867ae2011-10-09 10:28:34 +00001838 if (value != (const char *) NULL)
1839 compose=(CompositeOperator) ParseCommandOption(
1840 MagickComposeOptions,MagickFalse,value);
1841 else
anthony92c93bd2012-03-19 14:02:47 +00001842 compose=OverCompositeOp; /* use Over not _image->compose */
anthony5f867ae2011-10-09 10:28:34 +00001843
anthony92c93bd2012-03-19 14:02:47 +00001844 flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00001845 if ((flags & SigmaValue) == 0)
1846 geometry.height=geometry.width;
anthony92c93bd2012-03-19 14:02:47 +00001847 new_image=BorderImage(_image,&geometry,compose,_exception);
anthony805a2d42011-09-25 08:25:12 +00001848 break;
1849 }
anthonyafa3dfc2012-03-03 11:31:30 +00001850 if (LocaleCompare("brightness-contrast",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001851 {
1852 double
1853 brightness,
1854 contrast;
1855
1856 GeometryInfo
1857 geometry_info;
1858
1859 MagickStatusType
1860 flags;
1861
anthony7bcfe7f2012-03-30 14:01:22 +00001862 if (IfMagickFalse(IsGeometry(arg1)))
anthony5330ae02012-03-20 14:17:01 +00001863 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00001864 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00001865 brightness=geometry_info.rho;
1866 contrast=0.0;
1867 if ((flags & SigmaValue) != 0)
1868 contrast=geometry_info.sigma;
anthony92c93bd2012-03-19 14:02:47 +00001869 (void) BrightnessContrastImage(_image,brightness,contrast,
1870 _exception);
anthony805a2d42011-09-25 08:25:12 +00001871 break;
1872 }
anthonyebb73a22012-03-22 14:25:52 +00001873 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001874 }
1875 case 'c':
1876 {
anthonyafa3dfc2012-03-03 11:31:30 +00001877 if (LocaleCompare("cdl",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001878 {
1879 char
1880 *color_correction_collection;
1881
1882 /*
1883 Color correct with a color decision list.
1884 */
anthony92c93bd2012-03-19 14:02:47 +00001885 color_correction_collection=FileToString(arg1,~0,_exception);
anthony805a2d42011-09-25 08:25:12 +00001886 if (color_correction_collection == (char *) NULL)
1887 break;
anthony92c93bd2012-03-19 14:02:47 +00001888 (void) ColorDecisionListImage(_image,color_correction_collection,
1889 _exception);
anthony805a2d42011-09-25 08:25:12 +00001890 break;
1891 }
anthonyafa3dfc2012-03-03 11:31:30 +00001892 if (LocaleCompare("charcoal",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001893 {
anthony7bcfe7f2012-03-30 14:01:22 +00001894 if (IfMagickFalse(IsGeometry(arg1)))
anthony5330ae02012-03-20 14:17:01 +00001895 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00001896 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00001897 if ((flags & SigmaValue) == 0)
1898 geometry_info.sigma=1.0;
1899 if ((flags & XiValue) == 0)
1900 geometry_info.xi=1.0;
anthony92c93bd2012-03-19 14:02:47 +00001901 new_image=CharcoalImage(_image,geometry_info.rho,
cristyaa2c16c2012-03-25 22:21:35 +00001902 geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00001903 break;
1904 }
anthonyafa3dfc2012-03-03 11:31:30 +00001905 if (LocaleCompare("chop",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001906 {
anthony7bcfe7f2012-03-30 14:01:22 +00001907 if (IfMagickFalse(IsGeometry(arg1)))
anthony5330ae02012-03-20 14:17:01 +00001908 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001909 (void) ParseGravityGeometry(_image,arg1,&geometry,_exception);
1910 new_image=ChopImage(_image,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00001911 break;
1912 }
anthonyafa3dfc2012-03-03 11:31:30 +00001913 if (LocaleCompare("clamp",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001914 {
anthony92c93bd2012-03-19 14:02:47 +00001915 (void) ClampImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00001916 break;
1917 }
anthonyafa3dfc2012-03-03 11:31:30 +00001918 if (LocaleCompare("clip",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001919 {
anthonyafa3dfc2012-03-03 11:31:30 +00001920 if (IfNormalOp)
anthony92c93bd2012-03-19 14:02:47 +00001921 (void) ClipImage(_image,_exception);
anthony43f425d2012-02-26 12:58:58 +00001922 else /* "+mask" remove the write mask */
anthony92c93bd2012-03-19 14:02:47 +00001923 (void) SetImageMask(_image,(Image *) NULL,_exception);
anthony805a2d42011-09-25 08:25:12 +00001924 break;
1925 }
anthonyafa3dfc2012-03-03 11:31:30 +00001926 if (LocaleCompare("clip-mask",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001927 {
1928 CacheView
1929 *mask_view;
1930
1931 Image
1932 *mask_image;
1933
1934 register Quantum
1935 *restrict q;
1936
1937 register ssize_t
1938 x;
1939
1940 ssize_t
1941 y;
1942
anthonyafa3dfc2012-03-03 11:31:30 +00001943 if (IfPlusOp) {
1944 /* "+clip-mask" Remove the write mask */
anthony92c93bd2012-03-19 14:02:47 +00001945 (void) SetImageMask(_image,(Image *) NULL,_exception);
anthonyafa3dfc2012-03-03 11:31:30 +00001946 break;
1947 }
anthony92c93bd2012-03-19 14:02:47 +00001948 mask_image=GetImageCache(_image_info,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00001949 if (mask_image == (Image *) NULL)
1950 break;
anthony7bcfe7f2012-03-30 14:01:22 +00001951 if (IfMagickFalse(SetImageStorageClass(mask_image,DirectClass,_exception)))
anthony31f1bf72012-01-30 12:37:22 +00001952 break;
anthony5330ae02012-03-20 14:17:01 +00001953 /* Create a write mask from cli_wand mask image */
anthonyfd706f92012-01-19 04:22:02 +00001954 /* FUTURE: use Alpha operations instead and create a Grey Image */
anthony805a2d42011-09-25 08:25:12 +00001955 mask_view=AcquireCacheView(mask_image);
1956 for (y=0; y < (ssize_t) mask_image->rows; y++)
1957 {
1958 q=GetCacheViewAuthenticPixels(mask_view,0,y,mask_image->columns,1,
anthony92c93bd2012-03-19 14:02:47 +00001959 _exception);
anthony805a2d42011-09-25 08:25:12 +00001960 if (q == (Quantum *) NULL)
1961 break;
1962 for (x=0; x < (ssize_t) mask_image->columns; x++)
1963 {
anthony7bcfe7f2012-03-30 14:01:22 +00001964 if (IfMagickFalse(mask_image->matte))
anthony805a2d42011-09-25 08:25:12 +00001965 SetPixelAlpha(mask_image,GetPixelIntensity(mask_image,q),q);
1966 SetPixelRed(mask_image,GetPixelAlpha(mask_image,q),q);
1967 SetPixelGreen(mask_image,GetPixelAlpha(mask_image,q),q);
1968 SetPixelBlue(mask_image,GetPixelAlpha(mask_image,q),q);
1969 q+=GetPixelChannels(mask_image);
1970 }
anthony7bcfe7f2012-03-30 14:01:22 +00001971 if (IfMagickFalse(SyncCacheViewAuthenticPixels(mask_view,_exception)))
anthony805a2d42011-09-25 08:25:12 +00001972 break;
1973 }
anthonyfd706f92012-01-19 04:22:02 +00001974 /* clean up and set the write mask */
anthony805a2d42011-09-25 08:25:12 +00001975 mask_view=DestroyCacheView(mask_view);
1976 mask_image->matte=MagickTrue;
anthony92c93bd2012-03-19 14:02:47 +00001977 (void) SetImageMask(_image,mask_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00001978 mask_image=DestroyImage(mask_image);
anthony805a2d42011-09-25 08:25:12 +00001979 break;
1980 }
anthonyafa3dfc2012-03-03 11:31:30 +00001981 if (LocaleCompare("clip-path",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001982 {
anthony92c93bd2012-03-19 14:02:47 +00001983 (void) ClipImagePath(_image,arg1,normal_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00001984 break;
1985 }
anthonyafa3dfc2012-03-03 11:31:30 +00001986 if (LocaleCompare("colorize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001987 {
anthony7bcfe7f2012-03-30 14:01:22 +00001988 if (IfMagickFalse(IsGeometry(arg1)))
anthony5330ae02012-03-20 14:17:01 +00001989 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001990 new_image=ColorizeImage(_image,arg1,&_draw_info->fill,_exception);
anthony805a2d42011-09-25 08:25:12 +00001991 break;
1992 }
anthonyafa3dfc2012-03-03 11:31:30 +00001993 if (LocaleCompare("color-matrix",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001994 {
1995 KernelInfo
1996 *kernel;
1997
anthonyfd706f92012-01-19 04:22:02 +00001998 kernel=AcquireKernelInfo(arg1);
anthony805a2d42011-09-25 08:25:12 +00001999 if (kernel == (KernelInfo *) NULL)
anthony5330ae02012-03-20 14:17:01 +00002000 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002001 new_image=ColorMatrixImage(_image,kernel,_exception);
anthony805a2d42011-09-25 08:25:12 +00002002 kernel=DestroyKernelInfo(kernel);
2003 break;
2004 }
anthonyafa3dfc2012-03-03 11:31:30 +00002005 if (LocaleCompare("colors",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002006 {
anthony5330ae02012-03-20 14:17:01 +00002007 /* Reduce the number of colors in the image.
2008 FUTURE: also provide 'plus version with image 'color counts'
anthonyfd706f92012-01-19 04:22:02 +00002009 */
anthony92c93bd2012-03-19 14:02:47 +00002010 _quantize_info->number_colors=StringToUnsignedLong(arg1);
2011 if (_quantize_info->number_colors == 0)
anthony5330ae02012-03-20 14:17:01 +00002012 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002013 if ((_image->storage_class == DirectClass) ||
2014 _image->colors > _quantize_info->number_colors)
2015 (void) QuantizeImage(_quantize_info,_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002016 else
anthony92c93bd2012-03-19 14:02:47 +00002017 (void) CompressImageColormap(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002018 break;
2019 }
anthonyafa3dfc2012-03-03 11:31:30 +00002020 if (LocaleCompare("colorspace",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002021 {
anthony5330ae02012-03-20 14:17:01 +00002022 /* WARNING: this is both a image_info setting (already done)
2023 and a operator to change image colorspace.
anthony31f1bf72012-01-30 12:37:22 +00002024
2025 FUTURE: default colorspace should be sRGB!
anthonyd2cdc862011-10-07 14:07:17 +00002026 Unless some type of 'linear colorspace' mode is set.
anthony31f1bf72012-01-30 12:37:22 +00002027
anthonyd2cdc862011-10-07 14:07:17 +00002028 Note that +colorspace sets "undefined" or no effect on
2029 new images, but forces images already in memory back to RGB!
anthony31f1bf72012-01-30 12:37:22 +00002030 That seems to be a little strange!
anthonyd2cdc862011-10-07 14:07:17 +00002031 */
anthony92c93bd2012-03-19 14:02:47 +00002032 (void) TransformImageColorspace(_image,
2033 IfNormalOp ? _image_info->colorspace : RGBColorspace,
2034 _exception);
anthony805a2d42011-09-25 08:25:12 +00002035 break;
2036 }
anthonyafa3dfc2012-03-03 11:31:30 +00002037 if (LocaleCompare("contrast",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002038 {
anthonydcf3a912012-03-22 14:33:17 +00002039 /* DEPRECIATED: The -/+level provides far more controlled form */
anthony92c93bd2012-03-19 14:02:47 +00002040 (void) ContrastImage(_image,normal_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00002041 break;
2042 }
anthonyafa3dfc2012-03-03 11:31:30 +00002043 if (LocaleCompare("contrast-stretch",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002044 {
2045 double
2046 black_point,
2047 white_point;
2048
2049 MagickStatusType
2050 flags;
2051
anthony7bcfe7f2012-03-30 14:01:22 +00002052 if (IfMagickFalse(IsGeometry(arg1)))
anthonyebb73a22012-03-22 14:25:52 +00002053 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00002054 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002055 black_point=geometry_info.rho;
2056 white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
2057 black_point;
anthonyebb73a22012-03-22 14:25:52 +00002058 if ((flags & PercentValue) != 0) {
anthony92c93bd2012-03-19 14:02:47 +00002059 black_point*=(double) _image->columns*_image->rows/100.0;
2060 white_point*=(double) _image->columns*_image->rows/100.0;
anthony805a2d42011-09-25 08:25:12 +00002061 }
anthony92c93bd2012-03-19 14:02:47 +00002062 white_point=(MagickRealType) _image->columns*_image->rows-
anthony805a2d42011-09-25 08:25:12 +00002063 white_point;
anthony92c93bd2012-03-19 14:02:47 +00002064 (void) ContrastStretchImage(_image,black_point,white_point,
2065 _exception);
anthony805a2d42011-09-25 08:25:12 +00002066 break;
2067 }
anthonyafa3dfc2012-03-03 11:31:30 +00002068 if (LocaleCompare("convolve",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002069 {
2070 KernelInfo
2071 *kernel_info;
2072
anthonyfd706f92012-01-19 04:22:02 +00002073 kernel_info=AcquireKernelInfo(arg1);
anthony805a2d42011-09-25 08:25:12 +00002074 if (kernel_info == (KernelInfo *) NULL)
anthonyebb73a22012-03-22 14:25:52 +00002075 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyf46d4262012-03-26 03:30:34 +00002076 /* kernel_info->bias=_image->bias; -- FUTURE: check this path! */
cristy38419ba2012-04-05 23:47:05 +00002077 ScaleKernelInfo(kernel_info,1.0,NormalizeValue); /* normalize */
anthony92c93bd2012-03-19 14:02:47 +00002078 new_image=ConvolveImage(_image,kernel_info,_exception);
anthony805a2d42011-09-25 08:25:12 +00002079 kernel_info=DestroyKernelInfo(kernel_info);
2080 break;
2081 }
anthonyafa3dfc2012-03-03 11:31:30 +00002082 if (LocaleCompare("crop",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002083 {
anthony31f1bf72012-01-30 12:37:22 +00002084 /* WARNING: This can generate multiple images! */
anthony7bcfe7f2012-03-30 14:01:22 +00002085 if (IfMagickFalse(IsGeometry(arg1)))
anthonyebb73a22012-03-22 14:25:52 +00002086 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002087 new_image=CropImageToTiles(_image,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00002088 break;
2089 }
anthonyafa3dfc2012-03-03 11:31:30 +00002090 if (LocaleCompare("cycle",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002091 {
anthony7bcfe7f2012-03-30 14:01:22 +00002092 if (IfMagickFalse(IsGeometry(arg1)))
anthonyebb73a22012-03-22 14:25:52 +00002093 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002094 (void) CycleColormapImage(_image,(ssize_t) StringToLong(arg1),
2095 _exception);
anthony805a2d42011-09-25 08:25:12 +00002096 break;
2097 }
anthonyebb73a22012-03-22 14:25:52 +00002098 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002099 }
2100 case 'd':
2101 {
anthonyafa3dfc2012-03-03 11:31:30 +00002102 if (LocaleCompare("decipher",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002103 {
2104 StringInfo
2105 *passkey;
2106
anthony92c93bd2012-03-19 14:02:47 +00002107 passkey=FileToStringInfo(arg1,~0,_exception);
anthonyebb73a22012-03-22 14:25:52 +00002108 if (passkey == (StringInfo *) NULL)
2109 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2110
2111 (void) PasskeyDecipherImage(_image,passkey,_exception);
2112 passkey=DestroyStringInfo(passkey);
anthony805a2d42011-09-25 08:25:12 +00002113 break;
2114 }
anthonyafa3dfc2012-03-03 11:31:30 +00002115 if (LocaleCompare("depth",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002116 {
anthony92c93bd2012-03-19 14:02:47 +00002117 /* The _image_info->depth setting has already been set
anthonydcf510d2011-10-30 13:51:40 +00002118 We just need to apply it to all images in current sequence
anthony31f1bf72012-01-30 12:37:22 +00002119
anthonydcf510d2011-10-30 13:51:40 +00002120 WARNING: Depth from 8 to 16 causes 'quantum rounding to images!
2121 That is it really is an operation, not a setting! Arrgghhh
anthony31f1bf72012-01-30 12:37:22 +00002122
anthonyfd706f92012-01-19 04:22:02 +00002123 FUTURE: this should not be an operator!!!
anthonydcf510d2011-10-30 13:51:40 +00002124 */
anthony92c93bd2012-03-19 14:02:47 +00002125 (void) SetImageDepth(_image,_image_info->depth,_exception);
anthony805a2d42011-09-25 08:25:12 +00002126 break;
2127 }
anthonyafa3dfc2012-03-03 11:31:30 +00002128 if (LocaleCompare("deskew",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002129 {
2130 double
2131 threshold;
2132
anthonyebb73a22012-03-22 14:25:52 +00002133 if (IfNormalOp) {
anthony7bcfe7f2012-03-30 14:01:22 +00002134 if (IfMagickFalse(IsGeometry(arg1)))
anthonyebb73a22012-03-22 14:25:52 +00002135 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00002136 threshold=StringToDoubleInterval(arg1,(double) QuantumRange+1.0);
anthonyebb73a22012-03-22 14:25:52 +00002137 }
anthonyafa3dfc2012-03-03 11:31:30 +00002138 else
2139 threshold=40.0*QuantumRange/100.0;
anthony92c93bd2012-03-19 14:02:47 +00002140 new_image=DeskewImage(_image,threshold,_exception);
anthony805a2d42011-09-25 08:25:12 +00002141 break;
2142 }
anthonyafa3dfc2012-03-03 11:31:30 +00002143 if (LocaleCompare("despeckle",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002144 {
anthony92c93bd2012-03-19 14:02:47 +00002145 new_image=DespeckleImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002146 break;
2147 }
anthonyafa3dfc2012-03-03 11:31:30 +00002148 if (LocaleCompare("distort",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002149 {
2150 char
2151 *args,
2152 token[MaxTextExtent];
2153
2154 const char
2155 *p;
2156
anthony805a2d42011-09-25 08:25:12 +00002157 double
2158 *arguments;
2159
2160 register ssize_t
2161 x;
2162
2163 size_t
2164 number_arguments;
2165
anthony2a0ec8c2012-03-24 04:35:56 +00002166 parse = ParseCommandOption(MagickDistortOptions,MagickFalse,arg1);
2167 if ( parse < 0 )
anthonyebb73a22012-03-22 14:25:52 +00002168 CLIWandExceptArgBreak(OptionError,"UnrecognizedDistortMethod",
2169 option,arg1);
anthony2a0ec8c2012-03-24 04:35:56 +00002170 if ((DistortImageMethod) parse == ResizeDistortion)
anthony805a2d42011-09-25 08:25:12 +00002171 {
anthony80c37752012-01-16 01:03:11 +00002172 double
2173 resize_args[2];
anthony805a2d42011-09-25 08:25:12 +00002174 /* Special Case - Argument is actually a resize geometry!
2175 ** Convert that to an appropriate distortion argument array.
anthonyfd706f92012-01-19 04:22:02 +00002176 ** FUTURE: make a separate special resize operator
anthonyfe1aa782012-03-24 13:43:04 +00002177 Roll into a resize special operator */
anthony7bcfe7f2012-03-30 14:01:22 +00002178 if (IfMagickFalse(IsGeometry(arg2)))
anthonyebb73a22012-03-22 14:25:52 +00002179 CLIWandExceptArgBreak(OptionError,"InvalidGeometry",
2180 option,arg2);
2181 (void) ParseRegionGeometry(_image,arg2,&geometry,_exception);
anthony80c37752012-01-16 01:03:11 +00002182 resize_args[0]=(double) geometry.width;
2183 resize_args[1]=(double) geometry.height;
anthony2a0ec8c2012-03-24 04:35:56 +00002184 new_image=DistortImage(_image,(DistortImageMethod) parse,
2185 (size_t)2,resize_args,MagickTrue,_exception);
anthony805a2d42011-09-25 08:25:12 +00002186 break;
2187 }
anthonyfd706f92012-01-19 04:22:02 +00002188 /* handle percent arguments */
anthonyebb73a22012-03-22 14:25:52 +00002189 args=InterpretImageProperties(_image_info,_image,arg2,_exception);
anthony805a2d42011-09-25 08:25:12 +00002190 if (args == (char *) NULL)
2191 break;
anthonyfd706f92012-01-19 04:22:02 +00002192 /* convert arguments into an array of doubles
2193 FUTURE: make this a separate function.
2194 Also make use of new 'sentinal' feature to avoid need for
2195 tokenization.
2196 */
anthony805a2d42011-09-25 08:25:12 +00002197 p=(char *) args;
2198 for (x=0; *p != '\0'; x++)
2199 {
2200 GetMagickToken(p,&p,token);
2201 if (*token == ',')
2202 GetMagickToken(p,&p,token);
2203 }
2204 number_arguments=(size_t) x;
2205 arguments=(double *) AcquireQuantumMemory(number_arguments,
2206 sizeof(*arguments));
2207 if (arguments == (double *) NULL)
anthonyebb73a22012-03-22 14:25:52 +00002208 CLIWandExceptionBreak(ResourceLimitFatalError,
2209 "MemoryAllocationFailed",option);
anthony805a2d42011-09-25 08:25:12 +00002210 (void) ResetMagickMemory(arguments,0,number_arguments*
anthonyebb73a22012-03-22 14:25:52 +00002211 sizeof(*arguments));
anthony805a2d42011-09-25 08:25:12 +00002212 p=(char *) args;
2213 for (x=0; (x < (ssize_t) number_arguments) && (*p != '\0'); x++)
2214 {
2215 GetMagickToken(p,&p,token);
2216 if (*token == ',')
2217 GetMagickToken(p,&p,token);
cristydbdd0e32011-11-04 23:29:40 +00002218 arguments[x]=StringToDouble(token,(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +00002219 }
2220 args=DestroyString(args);
anthony2a0ec8c2012-03-24 04:35:56 +00002221 new_image=DistortImage(_image,(DistortImageMethod) parse,
2222 number_arguments,arguments,plus_alt_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00002223 arguments=(double *) RelinquishMagickMemory(arguments);
2224 break;
2225 }
anthonyafa3dfc2012-03-03 11:31:30 +00002226 if (LocaleCompare("draw",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002227 {
anthony92c93bd2012-03-19 14:02:47 +00002228 (void) CloneString(&_draw_info->primitive,arg1);
2229 (void) DrawImage(_image,_draw_info,_exception);
2230 (void) CloneString(&_draw_info->primitive,(char *)NULL);
anthony805a2d42011-09-25 08:25:12 +00002231 break;
2232 }
anthonyebb73a22012-03-22 14:25:52 +00002233 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002234 }
2235 case 'e':
2236 {
anthonyafa3dfc2012-03-03 11:31:30 +00002237 if (LocaleCompare("edge",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002238 {
anthony7bcfe7f2012-03-30 14:01:22 +00002239 if (IfMagickFalse(IsGeometry(arg1)))
anthony2a0ec8c2012-03-24 04:35:56 +00002240 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00002241 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002242 if ((flags & SigmaValue) == 0)
2243 geometry_info.sigma=1.0;
anthony2a0ec8c2012-03-24 04:35:56 +00002244 new_image=EdgeImage(_image,geometry_info.rho,geometry_info.sigma,
2245 _exception);
anthony805a2d42011-09-25 08:25:12 +00002246 break;
2247 }
anthonyafa3dfc2012-03-03 11:31:30 +00002248 if (LocaleCompare("emboss",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002249 {
anthony7bcfe7f2012-03-30 14:01:22 +00002250 if (IfMagickFalse(IsGeometry(arg1)))
anthony2a0ec8c2012-03-24 04:35:56 +00002251 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00002252 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002253 if ((flags & SigmaValue) == 0)
2254 geometry_info.sigma=1.0;
anthony92c93bd2012-03-19 14:02:47 +00002255 new_image=EmbossImage(_image,geometry_info.rho,
2256 geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00002257 break;
2258 }
anthonyafa3dfc2012-03-03 11:31:30 +00002259 if (LocaleCompare("encipher",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002260 {
2261 StringInfo
2262 *passkey;
2263
anthony92c93bd2012-03-19 14:02:47 +00002264 passkey=FileToStringInfo(arg1,~0,_exception);
anthony805a2d42011-09-25 08:25:12 +00002265 if (passkey != (StringInfo *) NULL)
2266 {
anthony92c93bd2012-03-19 14:02:47 +00002267 (void) PasskeyEncipherImage(_image,passkey,_exception);
anthony805a2d42011-09-25 08:25:12 +00002268 passkey=DestroyStringInfo(passkey);
2269 }
2270 break;
2271 }
anthonyafa3dfc2012-03-03 11:31:30 +00002272 if (LocaleCompare("enhance",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002273 {
anthony92c93bd2012-03-19 14:02:47 +00002274 new_image=EnhanceImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002275 break;
2276 }
anthonyafa3dfc2012-03-03 11:31:30 +00002277 if (LocaleCompare("equalize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002278 {
anthony92c93bd2012-03-19 14:02:47 +00002279 (void) EqualizeImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002280 break;
2281 }
anthonyafa3dfc2012-03-03 11:31:30 +00002282 if (LocaleCompare("evaluate",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002283 {
2284 double
2285 constant;
2286
anthony2a0ec8c2012-03-24 04:35:56 +00002287 parse = ParseCommandOption(MagickEvaluateOptions,MagickFalse,arg1);
2288 if ( parse < 0 )
2289 CLIWandExceptArgBreak(OptionError,"UnrecognizedEvaluateOperator",
2290 option,arg1);
anthony7bcfe7f2012-03-30 14:01:22 +00002291 if (IfMagickFalse(IsGeometry(arg2)))
anthony2a0ec8c2012-03-24 04:35:56 +00002292 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
anthonyfd706f92012-01-19 04:22:02 +00002293 constant=StringToDoubleInterval(arg2,(double) QuantumRange+1.0);
anthony2a0ec8c2012-03-24 04:35:56 +00002294 (void) EvaluateImage(_image,(MagickEvaluateOperator)parse,constant,
2295 _exception);
anthony805a2d42011-09-25 08:25:12 +00002296 break;
2297 }
anthonyafa3dfc2012-03-03 11:31:30 +00002298 if (LocaleCompare("extent",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002299 {
anthony7bcfe7f2012-03-30 14:01:22 +00002300 if (IfMagickFalse(IsGeometry(arg1)))
anthony2a0ec8c2012-03-24 04:35:56 +00002301 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002302 flags=ParseGravityGeometry(_image,arg1,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00002303 if (geometry.width == 0)
anthony92c93bd2012-03-19 14:02:47 +00002304 geometry.width=_image->columns;
anthony805a2d42011-09-25 08:25:12 +00002305 if (geometry.height == 0)
anthony92c93bd2012-03-19 14:02:47 +00002306 geometry.height=_image->rows;
2307 new_image=ExtentImage(_image,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00002308 break;
2309 }
anthonyebb73a22012-03-22 14:25:52 +00002310 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002311 }
2312 case 'f':
2313 {
anthonyafa3dfc2012-03-03 11:31:30 +00002314 if (LocaleCompare("features",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002315 {
anthony31f1bf72012-01-30 12:37:22 +00002316 /* FUTURE: move to SyncImageSettings() and AcqireImage()??? */
anthonyafa3dfc2012-03-03 11:31:30 +00002317 if (IfPlusOp) {
anthony92c93bd2012-03-19 14:02:47 +00002318 (void) DeleteImageArtifact(_image,"identify:features");
anthony31f1bf72012-01-30 12:37:22 +00002319 break;
2320 }
anthony92c93bd2012-03-19 14:02:47 +00002321 (void) SetImageArtifact(_image,"identify:features","true");
2322 (void) SetImageArtifact(_image,"verbose","true");
anthony805a2d42011-09-25 08:25:12 +00002323 break;
2324 }
anthonyafa3dfc2012-03-03 11:31:30 +00002325 if (LocaleCompare("flip",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002326 {
anthony92c93bd2012-03-19 14:02:47 +00002327 new_image=FlipImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002328 break;
2329 }
anthonyafa3dfc2012-03-03 11:31:30 +00002330 if (LocaleCompare("flop",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002331 {
anthony92c93bd2012-03-19 14:02:47 +00002332 new_image=FlopImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002333 break;
2334 }
anthonyafa3dfc2012-03-03 11:31:30 +00002335 if (LocaleCompare("floodfill",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002336 {
2337 PixelInfo
2338 target;
2339
anthony7bcfe7f2012-03-30 14:01:22 +00002340 if (IfMagickFalse(IsGeometry(arg1)))
anthony2a0ec8c2012-03-24 04:35:56 +00002341 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002342 (void) ParsePageGeometry(_image,arg1,&geometry,_exception);
2343 (void) QueryColorCompliance(arg2,AllCompliance,&target,_exception);
2344 (void) FloodfillPaintImage(_image,_draw_info,&target,geometry.x,
2345 geometry.y,plus_alt_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00002346 break;
2347 }
anthonyafa3dfc2012-03-03 11:31:30 +00002348 if (LocaleCompare("frame",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002349 {
2350 FrameInfo
2351 frame_info;
2352
anthony31f1bf72012-01-30 12:37:22 +00002353 CompositeOperator
anthonyfd706f92012-01-19 04:22:02 +00002354 compose;
2355
2356 const char*
2357 value;
2358
anthony92c93bd2012-03-19 14:02:47 +00002359 value=GetImageOption(_image_info,"compose");
anthonyfd706f92012-01-19 04:22:02 +00002360 if (value != (const char *) NULL)
2361 compose=(CompositeOperator) ParseCommandOption(
2362 MagickComposeOptions,MagickFalse,value);
2363 else
anthony92c93bd2012-03-19 14:02:47 +00002364 compose=OverCompositeOp; /* use Over not _image->compose */
anthonyfd706f92012-01-19 04:22:02 +00002365
anthony7bcfe7f2012-03-30 14:01:22 +00002366 if (IfMagickFalse(IsGeometry(arg1)))
anthony2a0ec8c2012-03-24 04:35:56 +00002367 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002368 flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00002369 frame_info.width=geometry.width;
2370 frame_info.height=geometry.height;
2371 if ((flags & HeightValue) == 0)
2372 frame_info.height=geometry.width;
2373 frame_info.outer_bevel=geometry.x;
2374 frame_info.inner_bevel=geometry.y;
2375 frame_info.x=(ssize_t) frame_info.width;
2376 frame_info.y=(ssize_t) frame_info.height;
anthony92c93bd2012-03-19 14:02:47 +00002377 frame_info.width=_image->columns+2*frame_info.width;
2378 frame_info.height=_image->rows+2*frame_info.height;
2379 new_image=FrameImage(_image,&frame_info,compose,_exception);
anthony805a2d42011-09-25 08:25:12 +00002380 break;
2381 }
anthonyafa3dfc2012-03-03 11:31:30 +00002382 if (LocaleCompare("function",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002383 {
2384 char
2385 *arguments,
2386 token[MaxTextExtent];
2387
2388 const char
2389 *p;
2390
2391 double
2392 *parameters;
2393
anthony805a2d42011-09-25 08:25:12 +00002394 register ssize_t
2395 x;
2396
2397 size_t
2398 number_parameters;
2399
cristy947cb4c2011-10-20 18:41:46 +00002400 /*
2401 Function Modify Image Values
anthonyfd706f92012-01-19 04:22:02 +00002402 FUTURE: code should be almost a duplicate of that is "distort"
cristy947cb4c2011-10-20 18:41:46 +00002403 */
anthony2a0ec8c2012-03-24 04:35:56 +00002404 parse=ParseCommandOption(MagickFunctionOptions,MagickFalse,arg1);
2405 if ( parse < 0 )
2406 CLIWandExceptArgBreak(OptionError,"UnrecognizedFunction",
2407 option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002408 arguments=InterpretImageProperties(_image_info,_image,arg2,
2409 _exception);
anthony805a2d42011-09-25 08:25:12 +00002410 if (arguments == (char *) NULL)
anthony2a0ec8c2012-03-24 04:35:56 +00002411 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
anthony805a2d42011-09-25 08:25:12 +00002412 p=(char *) arguments;
2413 for (x=0; *p != '\0'; x++)
2414 {
2415 GetMagickToken(p,&p,token);
2416 if (*token == ',')
2417 GetMagickToken(p,&p,token);
2418 }
2419 number_parameters=(size_t) x;
2420 parameters=(double *) AcquireQuantumMemory(number_parameters,
2421 sizeof(*parameters));
2422 if (parameters == (double *) NULL)
2423 ThrowWandFatalException(ResourceLimitFatalError,
anthony92c93bd2012-03-19 14:02:47 +00002424 "MemoryAllocationFailed",_image->filename);
anthony805a2d42011-09-25 08:25:12 +00002425 (void) ResetMagickMemory(parameters,0,number_parameters*
2426 sizeof(*parameters));
2427 p=(char *) arguments;
anthony2a0ec8c2012-03-24 04:35:56 +00002428 for (x=0; (x < (ssize_t) number_parameters) && (*p != '\0'); x++) {
anthony805a2d42011-09-25 08:25:12 +00002429 GetMagickToken(p,&p,token);
2430 if (*token == ',')
2431 GetMagickToken(p,&p,token);
cristydbdd0e32011-11-04 23:29:40 +00002432 parameters[x]=StringToDouble(token,(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +00002433 }
2434 arguments=DestroyString(arguments);
anthony2a0ec8c2012-03-24 04:35:56 +00002435 (void) FunctionImage(_image,(MagickFunction)parse,number_parameters,
2436 parameters,_exception);
anthony805a2d42011-09-25 08:25:12 +00002437 parameters=(double *) RelinquishMagickMemory(parameters);
2438 break;
2439 }
anthonyebb73a22012-03-22 14:25:52 +00002440 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002441 }
2442 case 'g':
2443 {
anthonyafa3dfc2012-03-03 11:31:30 +00002444 if (LocaleCompare("gamma",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002445 {
anthony7bcfe7f2012-03-30 14:01:22 +00002446 if (IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00002447 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyafa3dfc2012-03-03 11:31:30 +00002448 if (IfNormalOp)
anthony92c93bd2012-03-19 14:02:47 +00002449 (void) GammaImage(_image,StringToDouble(arg1,(char **) NULL),
2450 _exception);
anthonyafa3dfc2012-03-03 11:31:30 +00002451 else
anthony92c93bd2012-03-19 14:02:47 +00002452 _image->gamma=StringToDouble(arg1,(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +00002453 break;
2454 }
anthonyafa3dfc2012-03-03 11:31:30 +00002455 if ((LocaleCompare("gaussian-blur",option+1) == 0) ||
2456 (LocaleCompare("gaussian",option+1) == 0))
anthony805a2d42011-09-25 08:25:12 +00002457 {
anthony7bcfe7f2012-03-30 14:01:22 +00002458 if (IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00002459 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00002460 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002461 if ((flags & SigmaValue) == 0)
2462 geometry_info.sigma=1.0;
anthony92c93bd2012-03-19 14:02:47 +00002463 new_image=GaussianBlurImage(_image,geometry_info.rho,
2464 geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00002465 break;
2466 }
anthonyafa3dfc2012-03-03 11:31:30 +00002467 if (LocaleCompare("geometry",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002468 {
anthonyfd706f92012-01-19 04:22:02 +00002469 /*
anthony31f1bf72012-01-30 12:37:22 +00002470 Record Image offset for composition. (A Setting)
anthonyfe1aa782012-03-24 13:43:04 +00002471 Resize last _image. (ListOperator) -- DEPRECIATE
anthony31f1bf72012-01-30 12:37:22 +00002472 FUTURE: Why if no 'offset' does this resize ALL images?
2473 Also why is the setting recorded in the IMAGE non-sense!
anthonyfd706f92012-01-19 04:22:02 +00002474 */
anthonyafa3dfc2012-03-03 11:31:30 +00002475 if (IfPlusOp)
anthonyfd706f92012-01-19 04:22:02 +00002476 { /* remove the previous composition geometry offset! */
anthony92c93bd2012-03-19 14:02:47 +00002477 if (_image->geometry != (char *) NULL)
2478 _image->geometry=DestroyString(_image->geometry);
anthony805a2d42011-09-25 08:25:12 +00002479 break;
2480 }
anthony7bcfe7f2012-03-30 14:01:22 +00002481 if (IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00002482 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002483 flags=ParseRegionGeometry(_image,arg1,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00002484 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
anthony92c93bd2012-03-19 14:02:47 +00002485 (void) CloneString(&_image->geometry,arg1);
anthony805a2d42011-09-25 08:25:12 +00002486 else
anthony92c93bd2012-03-19 14:02:47 +00002487 new_image=ResizeImage(_image,geometry.width,geometry.height,
cristyaa2c16c2012-03-25 22:21:35 +00002488 _image->filter,_exception);
anthony805a2d42011-09-25 08:25:12 +00002489 break;
2490 }
anthonyebb73a22012-03-22 14:25:52 +00002491 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002492 }
2493 case 'h':
2494 {
anthonyafa3dfc2012-03-03 11:31:30 +00002495 if (LocaleCompare("highlight-color",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002496 {
anthony92c93bd2012-03-19 14:02:47 +00002497 (void) SetImageArtifact(_image,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +00002498 break;
2499 }
anthonyebb73a22012-03-22 14:25:52 +00002500 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002501 }
2502 case 'i':
2503 {
anthonyafa3dfc2012-03-03 11:31:30 +00002504 if (LocaleCompare("identify",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002505 {
anthony31f1bf72012-01-30 12:37:22 +00002506 const char
2507 *format,
anthony805a2d42011-09-25 08:25:12 +00002508 *text;
2509
anthony92c93bd2012-03-19 14:02:47 +00002510 format=GetImageOption(_image_info,"format");
anthony805a2d42011-09-25 08:25:12 +00002511 if (format == (char *) NULL)
2512 {
anthony92c93bd2012-03-19 14:02:47 +00002513 (void) IdentifyImage(_image,stdout,_image_info->verbose,
2514 _exception);
anthony805a2d42011-09-25 08:25:12 +00002515 break;
2516 }
anthony92c93bd2012-03-19 14:02:47 +00002517 text=InterpretImageProperties(_image_info,_image,format,_exception);
anthony805a2d42011-09-25 08:25:12 +00002518 if (text == (char *) NULL)
2519 break;
2520 (void) fputs(text,stdout);
2521 (void) fputc('\n',stdout);
anthony31f1bf72012-01-30 12:37:22 +00002522 text=DestroyString((char *)text);
anthony805a2d42011-09-25 08:25:12 +00002523 break;
2524 }
anthonyafa3dfc2012-03-03 11:31:30 +00002525 if (LocaleCompare("implode",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002526 {
anthony7bcfe7f2012-03-30 14:01:22 +00002527 if (IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00002528 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00002529 (void) ParseGeometry(arg1,&geometry_info);
anthony92c93bd2012-03-19 14:02:47 +00002530 new_image=ImplodeImage(_image,geometry_info.rho,
2531 _image->interpolate,_exception);
anthony805a2d42011-09-25 08:25:12 +00002532 break;
2533 }
anthonyafa3dfc2012-03-03 11:31:30 +00002534 if (LocaleCompare("interpolative-resize",option+1) == 0)
cristy947cb4c2011-10-20 18:41:46 +00002535 {
anthonyfe1aa782012-03-24 13:43:04 +00002536 /* FUTURE: New to IMv7
2537 Roll into a resize special operator */
anthony7bcfe7f2012-03-30 14:01:22 +00002538 if (IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00002539 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002540 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
2541 new_image=InterpolativeResizeImage(_image,geometry.width,
2542 geometry.height,_image->interpolate,_exception);
cristy947cb4c2011-10-20 18:41:46 +00002543 break;
2544 }
anthonyebb73a22012-03-22 14:25:52 +00002545 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002546 }
2547 case 'l':
2548 {
anthonyafa3dfc2012-03-03 11:31:30 +00002549 if (LocaleCompare("lat",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002550 {
anthony7bcfe7f2012-03-30 14:01:22 +00002551 if (IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00002552 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00002553 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002554 if ((flags & PercentValue) != 0)
2555 geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
anthony92c93bd2012-03-19 14:02:47 +00002556 new_image=AdaptiveThresholdImage(_image,(size_t) geometry_info.rho,
anthony31f1bf72012-01-30 12:37:22 +00002557 (size_t) geometry_info.sigma,(double) geometry_info.xi,
anthony92c93bd2012-03-19 14:02:47 +00002558 _exception);
anthony805a2d42011-09-25 08:25:12 +00002559 break;
2560 }
anthonyafa3dfc2012-03-03 11:31:30 +00002561 if (LocaleCompare("level",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002562 {
2563 MagickRealType
2564 black_point,
2565 gamma,
2566 white_point;
2567
2568 MagickStatusType
2569 flags;
2570
anthony7bcfe7f2012-03-30 14:01:22 +00002571 if (IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00002572 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00002573 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002574 black_point=geometry_info.rho;
2575 white_point=(MagickRealType) QuantumRange;
2576 if ((flags & SigmaValue) != 0)
2577 white_point=geometry_info.sigma;
2578 gamma=1.0;
2579 if ((flags & XiValue) != 0)
2580 gamma=geometry_info.xi;
2581 if ((flags & PercentValue) != 0)
2582 {
2583 black_point*=(MagickRealType) (QuantumRange/100.0);
2584 white_point*=(MagickRealType) (QuantumRange/100.0);
2585 }
2586 if ((flags & SigmaValue) == 0)
2587 white_point=(MagickRealType) QuantumRange-black_point;
anthonyafa3dfc2012-03-03 11:31:30 +00002588 if (IfPlusOp || ((flags & AspectValue) != 0))
anthony92c93bd2012-03-19 14:02:47 +00002589 (void) LevelizeImage(_image,black_point,white_point,gamma,_exception);
anthony805a2d42011-09-25 08:25:12 +00002590 else
anthony92c93bd2012-03-19 14:02:47 +00002591 (void) LevelImage(_image,black_point,white_point,gamma,_exception);
anthony805a2d42011-09-25 08:25:12 +00002592 break;
2593 }
anthonyafa3dfc2012-03-03 11:31:30 +00002594 if (LocaleCompare("level-colors",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002595 {
2596 char
2597 token[MaxTextExtent];
2598
2599 const char
2600 *p;
2601
2602 PixelInfo
2603 black_point,
2604 white_point;
2605
anthonyfd706f92012-01-19 04:22:02 +00002606 p=(const char *) arg1;
anthony805a2d42011-09-25 08:25:12 +00002607 GetMagickToken(p,&p,token); /* get black point color */
2608 if ((isalpha((int) *token) != 0) || ((*token == '#') != 0))
cristy269c9412011-10-13 23:41:15 +00002609 (void) QueryColorCompliance(token,AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +00002610 &black_point,_exception);
anthony805a2d42011-09-25 08:25:12 +00002611 else
cristy269c9412011-10-13 23:41:15 +00002612 (void) QueryColorCompliance("#000000",AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +00002613 &black_point,_exception);
anthony805a2d42011-09-25 08:25:12 +00002614 if (isalpha((int) token[0]) || (token[0] == '#'))
2615 GetMagickToken(p,&p,token);
2616 if (*token == '\0')
2617 white_point=black_point; /* set everything to that color */
2618 else
2619 {
2620 if ((isalpha((int) *token) == 0) && ((*token == '#') == 0))
2621 GetMagickToken(p,&p,token); /* Get white point color. */
2622 if ((isalpha((int) *token) != 0) || ((*token == '#') != 0))
cristy269c9412011-10-13 23:41:15 +00002623 (void) QueryColorCompliance(token,AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +00002624 &white_point,_exception);
anthony805a2d42011-09-25 08:25:12 +00002625 else
cristy269c9412011-10-13 23:41:15 +00002626 (void) QueryColorCompliance("#ffffff",AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +00002627 &white_point,_exception);
anthony805a2d42011-09-25 08:25:12 +00002628 }
anthony92c93bd2012-03-19 14:02:47 +00002629 (void) LevelImageColors(_image,&black_point,&white_point,
2630 plus_alt_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00002631 break;
2632 }
anthonyafa3dfc2012-03-03 11:31:30 +00002633 if (LocaleCompare("linear-stretch",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002634 {
2635 double
2636 black_point,
2637 white_point;
2638
2639 MagickStatusType
2640 flags;
2641
anthony7bcfe7f2012-03-30 14:01:22 +00002642 if (IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00002643 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00002644 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002645 black_point=geometry_info.rho;
anthony92c93bd2012-03-19 14:02:47 +00002646 white_point=(MagickRealType) _image->columns*_image->rows;
anthony805a2d42011-09-25 08:25:12 +00002647 if ((flags & SigmaValue) != 0)
2648 white_point=geometry_info.sigma;
2649 if ((flags & PercentValue) != 0)
2650 {
anthony92c93bd2012-03-19 14:02:47 +00002651 black_point*=(double) _image->columns*_image->rows/100.0;
2652 white_point*=(double) _image->columns*_image->rows/100.0;
anthony805a2d42011-09-25 08:25:12 +00002653 }
2654 if ((flags & SigmaValue) == 0)
anthony92c93bd2012-03-19 14:02:47 +00002655 white_point=(MagickRealType) _image->columns*_image->rows-
anthony805a2d42011-09-25 08:25:12 +00002656 black_point;
anthony92c93bd2012-03-19 14:02:47 +00002657 (void) LinearStretchImage(_image,black_point,white_point,_exception);
anthony805a2d42011-09-25 08:25:12 +00002658 break;
2659 }
anthonyafa3dfc2012-03-03 11:31:30 +00002660 if (LocaleCompare("liquid-rescale",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002661 {
anthonyfe1aa782012-03-24 13:43:04 +00002662 /* FUTURE: Roll into a resize special operator */
anthony7bcfe7f2012-03-30 14:01:22 +00002663 if (IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00002664 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002665 flags=ParseRegionGeometry(_image,arg1,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00002666 if ((flags & XValue) == 0)
2667 geometry.x=1;
2668 if ((flags & YValue) == 0)
2669 geometry.y=0;
anthony92c93bd2012-03-19 14:02:47 +00002670 new_image=LiquidRescaleImage(_image,geometry.width,
2671 geometry.height,1.0*geometry.x,1.0*geometry.y,_exception);
anthony805a2d42011-09-25 08:25:12 +00002672 break;
2673 }
anthonyafa3dfc2012-03-03 11:31:30 +00002674 if (LocaleCompare("lowlight-color",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002675 {
anthony92c93bd2012-03-19 14:02:47 +00002676 (void) SetImageArtifact(_image,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +00002677 break;
2678 }
anthonyebb73a22012-03-22 14:25:52 +00002679 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002680 }
2681 case 'm':
2682 {
anthonyafa3dfc2012-03-03 11:31:30 +00002683 if (LocaleCompare("map",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002684 {
2685 Image
2686 *remap_image;
2687
anthony31f1bf72012-01-30 12:37:22 +00002688 /* DEPRECIATED use -remap */
anthony92c93bd2012-03-19 14:02:47 +00002689 remap_image=GetImageCache(_image_info,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00002690 if (remap_image == (Image *) NULL)
2691 break;
anthony92c93bd2012-03-19 14:02:47 +00002692 (void) RemapImage(_quantize_info,_image,remap_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002693 remap_image=DestroyImage(remap_image);
2694 break;
2695 }
anthonyafa3dfc2012-03-03 11:31:30 +00002696 if (LocaleCompare("mask",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002697 {
2698 Image
2699 *mask;
2700
anthonyafa3dfc2012-03-03 11:31:30 +00002701 if (IfPlusOp)
anthony31f1bf72012-01-30 12:37:22 +00002702 { /* Remove a mask. */
anthony92c93bd2012-03-19 14:02:47 +00002703 (void) SetImageMask(_image,(Image *) NULL,_exception);
anthony805a2d42011-09-25 08:25:12 +00002704 break;
2705 }
anthony5330ae02012-03-20 14:17:01 +00002706 /* Set the image mask. */
anthony92c93bd2012-03-19 14:02:47 +00002707 mask=GetImageCache(_image_info,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00002708 if (mask == (Image *) NULL)
2709 break;
anthony92c93bd2012-03-19 14:02:47 +00002710 (void) SetImageMask(_image,mask,_exception);
anthony805a2d42011-09-25 08:25:12 +00002711 mask=DestroyImage(mask);
2712 break;
2713 }
anthonyafa3dfc2012-03-03 11:31:30 +00002714 if (LocaleCompare("matte",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002715 {
anthony31f1bf72012-01-30 12:37:22 +00002716 /* DEPRECIATED */
anthony92c93bd2012-03-19 14:02:47 +00002717 (void) SetImageAlphaChannel(_image,IfNormalOp ? SetAlphaChannel :
2718 DeactivateAlphaChannel, _exception);
anthony805a2d42011-09-25 08:25:12 +00002719 break;
2720 }
anthonya3ef4ed2012-03-17 06:52:53 +00002721 if (LocaleCompare("median",option+1) == 0)
2722 {
2723 /* DEPRECIATED - use -statistic Median */
anthony7bcfe7f2012-03-30 14:01:22 +00002724 if (IfMagickFalse(IsGeometry(arg1)))
anthony7bc87992012-03-25 02:32:51 +00002725 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonya3ef4ed2012-03-17 06:52:53 +00002726 CLISimpleOperatorImage(cli_wand,"-statistic","Median",arg1);
2727 break;
2728 }
anthonyafa3dfc2012-03-03 11:31:30 +00002729 if (LocaleCompare("mode",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002730 {
anthony7bcfe7f2012-03-30 14:01:22 +00002731 if (IfMagickFalse(IsGeometry(arg1)))
anthony7bc87992012-03-25 02:32:51 +00002732 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00002733 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002734 if ((flags & SigmaValue) == 0)
2735 geometry_info.sigma=geometry_info.rho;
anthony92c93bd2012-03-19 14:02:47 +00002736 new_image=StatisticImage(_image,ModeStatistic,(size_t)
2737 geometry_info.rho,(size_t) geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00002738 break;
2739 }
anthonyafa3dfc2012-03-03 11:31:30 +00002740 if (LocaleCompare("modulate",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002741 {
anthony7bcfe7f2012-03-30 14:01:22 +00002742 if (IfMagickFalse(IsGeometry(arg1)))
anthony7bc87992012-03-25 02:32:51 +00002743 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002744 (void) ModulateImage(_image,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00002745 break;
2746 }
anthonyafa3dfc2012-03-03 11:31:30 +00002747 if (LocaleCompare("monitor",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002748 {
anthony92c93bd2012-03-19 14:02:47 +00002749 (void) SetImageProgressMonitor(_image, IfNormalOp ? MonitorProgress :
anthonyafa3dfc2012-03-03 11:31:30 +00002750 (MagickProgressMonitor) NULL,(void *) NULL);
anthony805a2d42011-09-25 08:25:12 +00002751 break;
2752 }
anthonyafa3dfc2012-03-03 11:31:30 +00002753 if (LocaleCompare("monochrome",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002754 {
anthony92c93bd2012-03-19 14:02:47 +00002755 (void) SetImageType(_image,BilevelType,_exception);
anthony805a2d42011-09-25 08:25:12 +00002756 break;
2757 }
anthonyafa3dfc2012-03-03 11:31:30 +00002758 if (LocaleCompare("morphology",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002759 {
2760 char
2761 token[MaxTextExtent];
2762
2763 const char
2764 *p;
2765
2766 KernelInfo
2767 *kernel;
2768
anthony805a2d42011-09-25 08:25:12 +00002769 ssize_t
2770 iterations;
2771
anthonyfd706f92012-01-19 04:22:02 +00002772 p=arg1;
anthony805a2d42011-09-25 08:25:12 +00002773 GetMagickToken(p,&p,token);
anthony7bc87992012-03-25 02:32:51 +00002774 parse=ParseCommandOption(MagickMorphologyOptions,MagickFalse,token);
2775 if ( parse < 0 )
2776 CLIWandExceptArgBreak(OptionError,"UnrecognizedFunction",
2777 option,arg1);
anthony805a2d42011-09-25 08:25:12 +00002778 iterations=1L;
2779 GetMagickToken(p,&p,token);
2780 if ((*p == ':') || (*p == ','))
2781 GetMagickToken(p,&p,token);
2782 if ((*p != '\0'))
2783 iterations=(ssize_t) StringToLong(p);
anthonyfd706f92012-01-19 04:22:02 +00002784 kernel=AcquireKernelInfo(arg2);
anthony805a2d42011-09-25 08:25:12 +00002785 if (kernel == (KernelInfo *) NULL)
anthony7bc87992012-03-25 02:32:51 +00002786 CLIWandExceptArgBreak(OptionError,"UnabletoParseKernel",
2787 option,arg2);
2788 new_image=MorphologyImage(_image,(MorphologyMethod)parse,
2789 iterations,kernel,_exception);
anthony805a2d42011-09-25 08:25:12 +00002790 kernel=DestroyKernelInfo(kernel);
2791 break;
2792 }
anthonyafa3dfc2012-03-03 11:31:30 +00002793 if (LocaleCompare("motion-blur",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002794 {
anthony7bcfe7f2012-03-30 14:01:22 +00002795 if (IfMagickFalse(IsGeometry(arg1)))
anthony7bc87992012-03-25 02:32:51 +00002796 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00002797 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002798 if ((flags & SigmaValue) == 0)
2799 geometry_info.sigma=1.0;
anthony92c93bd2012-03-19 14:02:47 +00002800 new_image=MotionBlurImage(_image,geometry_info.rho,
cristyaa2c16c2012-03-25 22:21:35 +00002801 geometry_info.sigma,geometry_info.xi,_exception);
anthony805a2d42011-09-25 08:25:12 +00002802 break;
2803 }
anthonyebb73a22012-03-22 14:25:52 +00002804 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002805 }
2806 case 'n':
2807 {
anthonyafa3dfc2012-03-03 11:31:30 +00002808 if (LocaleCompare("negate",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002809 {
anthony92c93bd2012-03-19 14:02:47 +00002810 (void) NegateImage(_image, plus_alt_op, _exception);
anthony805a2d42011-09-25 08:25:12 +00002811 break;
2812 }
anthonyafa3dfc2012-03-03 11:31:30 +00002813 if (LocaleCompare("noise",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002814 {
anthonyafa3dfc2012-03-03 11:31:30 +00002815 if (IfNormalOp)
anthony805a2d42011-09-25 08:25:12 +00002816 {
anthony7bcfe7f2012-03-30 14:01:22 +00002817 if (IfMagickFalse(IsGeometry(arg1)))
anthony7bc87992012-03-25 02:32:51 +00002818 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00002819 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002820 if ((flags & SigmaValue) == 0)
2821 geometry_info.sigma=geometry_info.rho;
anthony92c93bd2012-03-19 14:02:47 +00002822 new_image=StatisticImage(_image,NonpeakStatistic,(size_t)
2823 geometry_info.rho,(size_t) geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00002824 }
2825 else
2826 {
anthony31f1bf72012-01-30 12:37:22 +00002827 double
2828 attenuate;
2829
2830 const char*
2831 value;
2832
anthony7bc87992012-03-25 02:32:51 +00002833 parse=ParseCommandOption(MagickNoiseOptions,MagickFalse,arg1);
2834 if ( parse < 0 )
2835 CLIWandExceptArgBreak(OptionError,"UnrecognizedNoiseType",
2836 option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002837 value=GetImageOption(_image_info,"attenuate");
anthony31f1bf72012-01-30 12:37:22 +00002838 if (value != (const char *) NULL)
2839 attenuate=StringToDouble(value,(char **) NULL);
2840 else
2841 attenuate=1.0;
2842
anthony7bc87992012-03-25 02:32:51 +00002843 new_image=AddNoiseImage(_image,(NoiseType)parse,attenuate,
2844 _exception);
anthony805a2d42011-09-25 08:25:12 +00002845 }
2846 break;
2847 }
anthonyafa3dfc2012-03-03 11:31:30 +00002848 if (LocaleCompare("normalize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002849 {
anthony92c93bd2012-03-19 14:02:47 +00002850 (void) NormalizeImage(_image,_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 'o':
2856 {
anthonyafa3dfc2012-03-03 11:31:30 +00002857 if (LocaleCompare("opaque",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002858 {
2859 PixelInfo
2860 target;
2861
anthony92c93bd2012-03-19 14:02:47 +00002862 (void) QueryColorCompliance(arg1,AllCompliance,&target,_exception);
2863 (void) OpaquePaintImage(_image,&target,&_draw_info->fill,plus_alt_op,
2864 _exception);
anthony805a2d42011-09-25 08:25:12 +00002865 break;
2866 }
anthonyafa3dfc2012-03-03 11:31:30 +00002867 if (LocaleCompare("ordered-dither",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002868 {
anthony92c93bd2012-03-19 14:02:47 +00002869 (void) OrderedPosterizeImage(_image,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00002870 break;
2871 }
anthonyebb73a22012-03-22 14:25:52 +00002872 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002873 }
2874 case 'p':
2875 {
anthonyafa3dfc2012-03-03 11:31:30 +00002876 if (LocaleCompare("paint",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002877 {
anthonyfd706f92012-01-19 04:22:02 +00002878 (void) ParseGeometry(arg1,&geometry_info);
anthony92c93bd2012-03-19 14:02:47 +00002879 new_image=OilPaintImage(_image,geometry_info.rho,geometry_info.sigma,
2880 _exception);
anthony805a2d42011-09-25 08:25:12 +00002881 break;
2882 }
anthonyafa3dfc2012-03-03 11:31:30 +00002883 if (LocaleCompare("polaroid",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002884 {
cristye9e3d382011-12-14 01:50:13 +00002885 const char
2886 *caption;
2887
anthony805a2d42011-09-25 08:25:12 +00002888 double
2889 angle;
2890
anthony7bc87992012-03-25 02:32:51 +00002891 if (IfPlusOp) {
anthonyf42014d2012-03-25 09:53:06 +00002892 RandomInfo
2893 *random_info;
anthony805a2d42011-09-25 08:25:12 +00002894
anthonyf42014d2012-03-25 09:53:06 +00002895 random_info=AcquireRandomInfo();
2896 angle=22.5*(GetPseudoRandomValue(random_info)-0.5);
2897 random_info=DestroyRandomInfo(random_info);
2898 }
anthony7bc87992012-03-25 02:32:51 +00002899 else {
anthony7bcfe7f2012-03-30 14:01:22 +00002900 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00002901 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2902 flags=ParseGeometry(arg1,&geometry_info);
2903 angle=geometry_info.rho;
2904 }
anthony92c93bd2012-03-19 14:02:47 +00002905 caption=GetImageProperty(_image,"caption",_exception);
2906 new_image=PolaroidImage(_image,_draw_info,caption,angle,
2907 _image->interpolate,_exception);
anthony805a2d42011-09-25 08:25:12 +00002908 break;
2909 }
anthonyafa3dfc2012-03-03 11:31:30 +00002910 if (LocaleCompare("posterize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002911 {
anthony7bcfe7f2012-03-30 14:01:22 +00002912 if (IfMagickFalse(IsGeometry(arg1)))
anthony7bc87992012-03-25 02:32:51 +00002913 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony31f1bf72012-01-30 12:37:22 +00002914 (void) ParseGeometry(arg1,&geometry_info);
anthony92c93bd2012-03-19 14:02:47 +00002915 (void) PosterizeImage(_image,(size_t) geometry_info.rho,
2916 _quantize_info->dither,_exception);
anthony805a2d42011-09-25 08:25:12 +00002917 break;
2918 }
anthonyafa3dfc2012-03-03 11:31:30 +00002919 if (LocaleCompare("preview",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002920 {
anthony31f1bf72012-01-30 12:37:22 +00002921 /* FUTURE: should be a 'Genesis' option?
2922 Option however is also in WandSettingOptionInfo()
anthony7bc87992012-03-25 02:32:51 +00002923 Why???
cristy947cb4c2011-10-20 18:41:46 +00002924 */
anthony7bc87992012-03-25 02:32:51 +00002925 parse=ParseCommandOption(MagickPreviewOptions, MagickFalse,arg1);
2926 if ( parse < 0 )
2927 CLIWandExceptArgBreak(OptionError,"UnrecognizedPreviewType",
2928 option,arg1);
2929 new_image=PreviewImage(_image,(PreviewType)parse,_exception);
anthony805a2d42011-09-25 08:25:12 +00002930 break;
2931 }
anthonyafa3dfc2012-03-03 11:31:30 +00002932 if (LocaleCompare("profile",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002933 {
2934 const char
2935 *name;
2936
2937 const StringInfo
2938 *profile;
2939
2940 Image
2941 *profile_image;
2942
2943 ImageInfo
2944 *profile_info;
2945
anthonyafa3dfc2012-03-03 11:31:30 +00002946 if (IfPlusOp)
anthony92c93bd2012-03-19 14:02:47 +00002947 { /* Remove a profile from the _image. */
2948 (void) ProfileImage(_image,arg1,(const unsigned char *)
2949 NULL,0,_exception);
anthony805a2d42011-09-25 08:25:12 +00002950 break;
2951 }
anthony92c93bd2012-03-19 14:02:47 +00002952 /* Associate a profile with the _image. */
2953 profile_info=CloneImageInfo(_image_info);
2954 profile=GetImageProfile(_image,"iptc");
anthony805a2d42011-09-25 08:25:12 +00002955 if (profile != (StringInfo *) NULL)
2956 profile_info->profile=(void *) CloneStringInfo(profile);
anthony92c93bd2012-03-19 14:02:47 +00002957 profile_image=GetImageCache(profile_info,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00002958 profile_info=DestroyImageInfo(profile_info);
2959 if (profile_image == (Image *) NULL)
2960 {
2961 StringInfo
2962 *profile;
2963
anthony92c93bd2012-03-19 14:02:47 +00002964 profile_info=CloneImageInfo(_image_info);
anthonyfd706f92012-01-19 04:22:02 +00002965 (void) CopyMagickString(profile_info->filename,arg1,
anthony805a2d42011-09-25 08:25:12 +00002966 MaxTextExtent);
anthony92c93bd2012-03-19 14:02:47 +00002967 profile=FileToStringInfo(profile_info->filename,~0UL,_exception);
anthony805a2d42011-09-25 08:25:12 +00002968 if (profile != (StringInfo *) NULL)
2969 {
anthony92c93bd2012-03-19 14:02:47 +00002970 (void) ProfileImage(_image,profile_info->magick,
anthony805a2d42011-09-25 08:25:12 +00002971 GetStringInfoDatum(profile),(size_t)
anthony92c93bd2012-03-19 14:02:47 +00002972 GetStringInfoLength(profile),_exception);
anthony805a2d42011-09-25 08:25:12 +00002973 profile=DestroyStringInfo(profile);
2974 }
2975 profile_info=DestroyImageInfo(profile_info);
2976 break;
2977 }
2978 ResetImageProfileIterator(profile_image);
2979 name=GetNextImageProfile(profile_image);
2980 while (name != (const char *) NULL)
2981 {
2982 profile=GetImageProfile(profile_image,name);
2983 if (profile != (StringInfo *) NULL)
anthony92c93bd2012-03-19 14:02:47 +00002984 (void) ProfileImage(_image,name,GetStringInfoDatum(profile),
2985 (size_t) GetStringInfoLength(profile),_exception);
anthony805a2d42011-09-25 08:25:12 +00002986 name=GetNextImageProfile(profile_image);
2987 }
2988 profile_image=DestroyImage(profile_image);
2989 break;
2990 }
anthonyebb73a22012-03-22 14:25:52 +00002991 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002992 }
anthony805a2d42011-09-25 08:25:12 +00002993 case 'r':
2994 {
anthonyafa3dfc2012-03-03 11:31:30 +00002995 if (LocaleCompare("radial-blur",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002996 {
anthony7bcfe7f2012-03-30 14:01:22 +00002997 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00002998 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00002999 flags=ParseGeometry(arg1,&geometry_info);
cristyaa2c16c2012-03-25 22:21:35 +00003000 new_image=RadialBlurImage(_image,geometry_info.rho,_exception);
anthony805a2d42011-09-25 08:25:12 +00003001 break;
3002 }
anthonyafa3dfc2012-03-03 11:31:30 +00003003 if (LocaleCompare("raise",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003004 {
anthony7bcfe7f2012-03-30 14:01:22 +00003005 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003006 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003007 flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00003008 if ((flags & SigmaValue) == 0)
3009 geometry.height=geometry.width;
anthony92c93bd2012-03-19 14:02:47 +00003010 (void) RaiseImage(_image,&geometry,normal_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00003011 break;
3012 }
anthonyafa3dfc2012-03-03 11:31:30 +00003013 if (LocaleCompare("random-threshold",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003014 {
anthony7bcfe7f2012-03-30 14:01:22 +00003015 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003016 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003017 (void) RandomThresholdImage(_image,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00003018 break;
3019 }
anthonyafa3dfc2012-03-03 11:31:30 +00003020 if (LocaleCompare("remap",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003021 {
3022 Image
3023 *remap_image;
3024
anthony92c93bd2012-03-19 14:02:47 +00003025 remap_image=GetImageCache(_image_info,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00003026 if (remap_image == (Image *) NULL)
3027 break;
anthony92c93bd2012-03-19 14:02:47 +00003028 (void) RemapImage(_quantize_info,_image,remap_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00003029 remap_image=DestroyImage(remap_image);
3030 break;
3031 }
anthonyafa3dfc2012-03-03 11:31:30 +00003032 if (LocaleCompare("repage",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003033 {
anthonyafa3dfc2012-03-03 11:31:30 +00003034 if (IfNormalOp)
cristy0d0de742012-03-25 19:32:48 +00003035 {
anthony7bcfe7f2012-03-30 14:01:22 +00003036 if (IfMagickFalse(IsGeometry(arg1)))
cristy0d0de742012-03-25 19:32:48 +00003037 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,
3038 arg1);
3039 (void) ResetImagePage(_image,arg1);
3040 }
anthony31f1bf72012-01-30 12:37:22 +00003041 else
anthony92c93bd2012-03-19 14:02:47 +00003042 (void) ParseAbsoluteGeometry("0x0+0+0",&_image->page);
anthony805a2d42011-09-25 08:25:12 +00003043 break;
3044 }
anthonyafa3dfc2012-03-03 11:31:30 +00003045 if (LocaleCompare("resample",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003046 {
anthonyf46d4262012-03-26 03:30:34 +00003047 /* FUTURE: Roll into a resize special operation */
anthony7bcfe7f2012-03-30 14:01:22 +00003048 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003049 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00003050 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003051 if ((flags & SigmaValue) == 0)
3052 geometry_info.sigma=geometry_info.rho;
anthony92c93bd2012-03-19 14:02:47 +00003053 new_image=ResampleImage(_image,geometry_info.rho,
cristyaa2c16c2012-03-25 22:21:35 +00003054 geometry_info.sigma,_image->filter,_exception);
anthony805a2d42011-09-25 08:25:12 +00003055 break;
3056 }
anthonyafa3dfc2012-03-03 11:31:30 +00003057 if (LocaleCompare("resize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003058 {
anthony7bcfe7f2012-03-30 14:01:22 +00003059 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003060 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003061 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
3062 new_image=ResizeImage(_image,geometry.width,geometry.height,
cristyaa2c16c2012-03-25 22:21:35 +00003063 _image->filter,_exception);
anthony805a2d42011-09-25 08:25:12 +00003064 break;
3065 }
anthonyafa3dfc2012-03-03 11:31:30 +00003066 if (LocaleCompare("roll",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003067 {
anthony7bcfe7f2012-03-30 14:01:22 +00003068 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003069 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003070 (void) ParsePageGeometry(_image,arg1,&geometry,_exception);
3071 new_image=RollImage(_image,geometry.x,geometry.y,_exception);
anthony805a2d42011-09-25 08:25:12 +00003072 break;
3073 }
anthonyafa3dfc2012-03-03 11:31:30 +00003074 if (LocaleCompare("rotate",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003075 {
anthony7bcfe7f2012-03-30 14:01:22 +00003076 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003077 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00003078 if (strchr(arg1,'>') != (char *) NULL)
anthony92c93bd2012-03-19 14:02:47 +00003079 if (_image->columns <= _image->rows)
anthony805a2d42011-09-25 08:25:12 +00003080 break;
anthonyfd706f92012-01-19 04:22:02 +00003081 if (strchr(arg1,'<') != (char *) NULL)
anthony92c93bd2012-03-19 14:02:47 +00003082 if (_image->columns >= _image->rows)
anthony805a2d42011-09-25 08:25:12 +00003083 break;
anthonyfd706f92012-01-19 04:22:02 +00003084 (void) ParseGeometry(arg1,&geometry_info);
anthony92c93bd2012-03-19 14:02:47 +00003085 new_image=RotateImage(_image,geometry_info.rho,_exception);
anthony805a2d42011-09-25 08:25:12 +00003086 break;
3087 }
anthonyebb73a22012-03-22 14:25:52 +00003088 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003089 }
3090 case 's':
3091 {
anthonyafa3dfc2012-03-03 11:31:30 +00003092 if (LocaleCompare("sample",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003093 {
anthonyfe1aa782012-03-24 13:43:04 +00003094 /* FUTURE: Roll into a resize special operator */
anthony7bcfe7f2012-03-30 14:01:22 +00003095 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003096 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003097 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
3098 new_image=SampleImage(_image,geometry.width,geometry.height,
3099 _exception);
anthony805a2d42011-09-25 08:25:12 +00003100 break;
3101 }
anthonyafa3dfc2012-03-03 11:31:30 +00003102 if (LocaleCompare("scale",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003103 {
anthonyfe1aa782012-03-24 13:43:04 +00003104 /* FUTURE: Roll into a resize special operator */
anthony7bcfe7f2012-03-30 14:01:22 +00003105 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003106 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003107 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
3108 new_image=ScaleImage(_image,geometry.width,geometry.height,
3109 _exception);
anthony805a2d42011-09-25 08:25:12 +00003110 break;
3111 }
anthonyf42014d2012-03-25 09:53:06 +00003112 if (LocaleCompare("segment",option+1) == 0)
3113 {
anthony7bcfe7f2012-03-30 14:01:22 +00003114 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003115 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3116 flags=ParseGeometry(arg1,&geometry_info);
3117 if ((flags & SigmaValue) == 0)
3118 geometry_info.sigma=1.0;
3119 (void) SegmentImage(_image,_image->colorspace,
3120 _image_info->verbose,geometry_info.rho,geometry_info.sigma,
3121 _exception);
3122 break;
3123 }
anthonyafa3dfc2012-03-03 11:31:30 +00003124 if (LocaleCompare("selective-blur",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003125 {
anthony7bcfe7f2012-03-30 14:01:22 +00003126 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003127 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00003128 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003129 if ((flags & PercentValue) != 0)
3130 geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
anthony92c93bd2012-03-19 14:02:47 +00003131 new_image=SelectiveBlurImage(_image,geometry_info.rho,
cristyaa2c16c2012-03-25 22:21:35 +00003132 geometry_info.sigma,geometry_info.xi,_exception);
anthony805a2d42011-09-25 08:25:12 +00003133 break;
3134 }
anthonyafa3dfc2012-03-03 11:31:30 +00003135 if (LocaleCompare("separate",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003136 {
anthony31f1bf72012-01-30 12:37:22 +00003137 /* WARNING: This can generate multiple images! */
anthony43f425d2012-02-26 12:58:58 +00003138 /* FUTURE - this may be replaced by a "-channel" method */
cristydfdb19e2012-03-21 22:22:24 +00003139 new_image=SeparateImages(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00003140 break;
3141 }
anthonyafa3dfc2012-03-03 11:31:30 +00003142 if (LocaleCompare("sepia-tone",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003143 {
anthony7bcfe7f2012-03-30 14:01:22 +00003144 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003145 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3146 new_image=SepiaToneImage(_image,StringToDoubleInterval(arg1,
3147 (double) QuantumRange+1.0),_exception);
anthony805a2d42011-09-25 08:25:12 +00003148 break;
3149 }
anthonyafa3dfc2012-03-03 11:31:30 +00003150 if (LocaleCompare("set",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003151 {
3152 char
3153 *value;
3154
anthonyf42014d2012-03-25 09:53:06 +00003155 if (IfPlusOp) {
anthonyfd706f92012-01-19 04:22:02 +00003156 if (LocaleNCompare(arg1,"registry:",9) == 0)
3157 (void) DeleteImageRegistry(arg1+9);
anthony805a2d42011-09-25 08:25:12 +00003158 else
anthony31f1bf72012-01-30 12:37:22 +00003159 if (LocaleNCompare(arg1,"option:",7) == 0)
anthony805a2d42011-09-25 08:25:12 +00003160 {
anthony92c93bd2012-03-19 14:02:47 +00003161 (void) DeleteImageOption(_image_info,arg1+7);
3162 (void) DeleteImageArtifact(_image,arg1+7);
anthony805a2d42011-09-25 08:25:12 +00003163 }
3164 else
anthony92c93bd2012-03-19 14:02:47 +00003165 (void) DeleteImageProperty(_image,arg1);
anthony805a2d42011-09-25 08:25:12 +00003166 break;
3167 }
anthonyf42014d2012-03-25 09:53:06 +00003168 value=InterpretImageProperties(_image_info,_image,arg2,_exception);
anthony805a2d42011-09-25 08:25:12 +00003169 if (value == (char *) NULL)
3170 break;
anthonyfd706f92012-01-19 04:22:02 +00003171 if (LocaleNCompare(arg1,"registry:",9) == 0)
anthonyf42014d2012-03-25 09:53:06 +00003172 (void) SetImageRegistry(StringRegistryType,arg1+9,value,_exception);
anthony805a2d42011-09-25 08:25:12 +00003173 else
anthonyfd706f92012-01-19 04:22:02 +00003174 if (LocaleNCompare(arg1,"option:",7) == 0)
anthony805a2d42011-09-25 08:25:12 +00003175 {
anthony92c93bd2012-03-19 14:02:47 +00003176 (void) SetImageOption(_image_info,arg1+7,value);
3177 (void) SetImageArtifact(_image,arg1+7,value);
anthony805a2d42011-09-25 08:25:12 +00003178 }
3179 else
anthony92c93bd2012-03-19 14:02:47 +00003180 (void) SetImageProperty(_image,arg1,value,_exception);
anthony805a2d42011-09-25 08:25:12 +00003181 value=DestroyString(value);
3182 break;
3183 }
anthonyafa3dfc2012-03-03 11:31:30 +00003184 if (LocaleCompare("shade",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003185 {
anthony7bcfe7f2012-03-30 14:01:22 +00003186 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003187 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00003188 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003189 if ((flags & SigmaValue) == 0)
3190 geometry_info.sigma=1.0;
anthony92c93bd2012-03-19 14:02:47 +00003191 new_image=ShadeImage(_image,normal_op,geometry_info.rho,
3192 geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00003193 break;
3194 }
anthonyafa3dfc2012-03-03 11:31:30 +00003195 if (LocaleCompare("shadow",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003196 {
anthony7bcfe7f2012-03-30 14:01:22 +00003197 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003198 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00003199 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003200 if ((flags & SigmaValue) == 0)
3201 geometry_info.sigma=1.0;
3202 if ((flags & XiValue) == 0)
3203 geometry_info.xi=4.0;
3204 if ((flags & PsiValue) == 0)
3205 geometry_info.psi=4.0;
cristyaa2c16c2012-03-25 22:21:35 +00003206 new_image=ShadowImage(_image,geometry_info.rho,geometry_info.sigma,
3207 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
3208 ceil(geometry_info.psi-0.5),_exception);
anthony805a2d42011-09-25 08:25:12 +00003209 break;
3210 }
anthonyafa3dfc2012-03-03 11:31:30 +00003211 if (LocaleCompare("sharpen",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003212 {
anthony7bcfe7f2012-03-30 14:01:22 +00003213 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003214 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00003215 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003216 if ((flags & SigmaValue) == 0)
3217 geometry_info.sigma=1.0;
3218 if ((flags & XiValue) == 0)
3219 geometry_info.xi=0.0;
cristyaa2c16c2012-03-25 22:21:35 +00003220 new_image=SharpenImage(_image,geometry_info.rho,geometry_info.sigma,
3221 _exception);
anthony805a2d42011-09-25 08:25:12 +00003222 break;
3223 }
anthonyafa3dfc2012-03-03 11:31:30 +00003224 if (LocaleCompare("shave",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003225 {
anthony7bcfe7f2012-03-30 14:01:22 +00003226 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003227 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003228 flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
3229 new_image=ShaveImage(_image,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00003230 break;
3231 }
anthonyafa3dfc2012-03-03 11:31:30 +00003232 if (LocaleCompare("shear",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003233 {
anthony7bcfe7f2012-03-30 14:01:22 +00003234 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003235 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00003236 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003237 if ((flags & SigmaValue) == 0)
3238 geometry_info.sigma=geometry_info.rho;
anthony92c93bd2012-03-19 14:02:47 +00003239 new_image=ShearImage(_image,geometry_info.rho,
3240 geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00003241 break;
3242 }
anthonyafa3dfc2012-03-03 11:31:30 +00003243 if (LocaleCompare("sigmoidal-contrast",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003244 {
anthony7bcfe7f2012-03-30 14:01:22 +00003245 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003246 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00003247 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003248 if ((flags & SigmaValue) == 0)
3249 geometry_info.sigma=(double) QuantumRange/2.0;
3250 if ((flags & PercentValue) != 0)
3251 geometry_info.sigma=(double) QuantumRange*geometry_info.sigma/
3252 100.0;
anthony92c93bd2012-03-19 14:02:47 +00003253 (void) SigmoidalContrastImage(_image,normal_op,geometry_info.rho,
anthony31f1bf72012-01-30 12:37:22 +00003254 geometry_info.sigma,
anthony92c93bd2012-03-19 14:02:47 +00003255 _exception);
anthony805a2d42011-09-25 08:25:12 +00003256 break;
3257 }
anthonyafa3dfc2012-03-03 11:31:30 +00003258 if (LocaleCompare("sketch",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003259 {
anthony7bcfe7f2012-03-30 14:01:22 +00003260 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003261 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00003262 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003263 if ((flags & SigmaValue) == 0)
3264 geometry_info.sigma=1.0;
anthony92c93bd2012-03-19 14:02:47 +00003265 new_image=SketchImage(_image,geometry_info.rho,
cristyaa2c16c2012-03-25 22:21:35 +00003266 geometry_info.sigma,geometry_info.xi,_exception);
anthony805a2d42011-09-25 08:25:12 +00003267 break;
3268 }
anthonyafa3dfc2012-03-03 11:31:30 +00003269 if (LocaleCompare("solarize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003270 {
anthony7bcfe7f2012-03-30 14:01:22 +00003271 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003272 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003273 (void) SolarizeImage(_image,StringToDoubleInterval(arg1,(double)
3274 QuantumRange+1.0),_exception);
anthony805a2d42011-09-25 08:25:12 +00003275 break;
3276 }
anthonyafa3dfc2012-03-03 11:31:30 +00003277 if (LocaleCompare("sparse-color",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003278 {
anthony805a2d42011-09-25 08:25:12 +00003279 char
3280 *arguments;
3281
anthonyf42014d2012-03-25 09:53:06 +00003282 parse= ParseCommandOption(MagickSparseColorOptions,MagickFalse,arg1);
3283 if ( parse < 0 )
3284 CLIWandExceptArgBreak(OptionError,"UnrecognizedSparseColorMethod",
3285 option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003286 arguments=InterpretImageProperties(_image_info,_image,arg2,_exception);
anthony805a2d42011-09-25 08:25:12 +00003287 if (arguments == (char *) NULL)
anthonyf42014d2012-03-25 09:53:06 +00003288 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
3289 new_image=SparseColorOption(_image,(SparseColorMethod)parse,
3290 arguments,_exception);
anthony805a2d42011-09-25 08:25:12 +00003291 arguments=DestroyString(arguments);
3292 break;
3293 }
anthonyafa3dfc2012-03-03 11:31:30 +00003294 if (LocaleCompare("splice",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003295 {
anthony7bcfe7f2012-03-30 14:01:22 +00003296 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003297 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003298 (void) ParseGravityGeometry(_image,arg1,&geometry,_exception);
3299 new_image=SpliceImage(_image,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00003300 break;
3301 }
anthonyafa3dfc2012-03-03 11:31:30 +00003302 if (LocaleCompare("spread",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003303 {
anthony7bcfe7f2012-03-30 14:01:22 +00003304 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003305 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00003306 (void) ParseGeometry(arg1,&geometry_info);
anthony92c93bd2012-03-19 14:02:47 +00003307 new_image=SpreadImage(_image,geometry_info.rho,_image->interpolate,
3308 _exception);
anthony805a2d42011-09-25 08:25:12 +00003309 break;
3310 }
anthonyafa3dfc2012-03-03 11:31:30 +00003311 if (LocaleCompare("statistic",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003312 {
anthony7bc87992012-03-25 02:32:51 +00003313 parse=ParseCommandOption(MagickStatisticOptions,MagickFalse,arg1);
3314 if ( parse < 0 )
anthonyf42014d2012-03-25 09:53:06 +00003315 CLIWandExceptArgBreak(OptionError,"UnrecognizedStatisticType",
anthony7bc87992012-03-25 02:32:51 +00003316 option,arg1);
anthony7bcfe7f2012-03-30 14:01:22 +00003317 if (IfMagickFalse(IsGeometry(arg2)))
anthony7bc87992012-03-25 02:32:51 +00003318 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
anthonyfd706f92012-01-19 04:22:02 +00003319 (void) ParseGeometry(arg2,&geometry_info);
anthony7bc87992012-03-25 02:32:51 +00003320 new_image=StatisticImage(_image,(StatisticType)parse,
3321 (size_t) geometry_info.rho,(size_t) geometry_info.sigma,
3322 _exception);
anthony805a2d42011-09-25 08:25:12 +00003323 break;
3324 }
anthonyafa3dfc2012-03-03 11:31:30 +00003325 if (LocaleCompare("strip",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003326 {
anthony92c93bd2012-03-19 14:02:47 +00003327 (void) StripImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00003328 break;
3329 }
anthonyafa3dfc2012-03-03 11:31:30 +00003330 if (LocaleCompare("swirl",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003331 {
anthony7bcfe7f2012-03-30 14:01:22 +00003332 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003333 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00003334 (void) ParseGeometry(arg1,&geometry_info);
anthony92c93bd2012-03-19 14:02:47 +00003335 new_image=SwirlImage(_image,geometry_info.rho,
3336 _image->interpolate,_exception);
anthony805a2d42011-09-25 08:25:12 +00003337 break;
3338 }
anthonyebb73a22012-03-22 14:25:52 +00003339 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003340 }
3341 case 't':
3342 {
anthonyafa3dfc2012-03-03 11:31:30 +00003343 if (LocaleCompare("threshold",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003344 {
3345 double
3346 threshold;
3347
anthony52bef752012-03-27 13:54:47 +00003348 threshold=(double) QuantumRange/2;
3349 if (normal_op) {
anthony7bcfe7f2012-03-30 14:01:22 +00003350 if (IfMagickFalse(IsGeometry(arg1)))
anthony52bef752012-03-27 13:54:47 +00003351 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00003352 threshold=StringToDoubleInterval(arg1,(double) QuantumRange+1.0);
anthony52bef752012-03-27 13:54:47 +00003353 }
anthony92c93bd2012-03-19 14:02:47 +00003354 (void) BilevelImage(_image,threshold,_exception);
anthony805a2d42011-09-25 08:25:12 +00003355 break;
3356 }
anthonyafa3dfc2012-03-03 11:31:30 +00003357 if (LocaleCompare("thumbnail",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003358 {
anthony7bcfe7f2012-03-30 14:01:22 +00003359 if (IfMagickFalse(IsGeometry(arg1)))
anthony52bef752012-03-27 13:54:47 +00003360 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003361 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
3362 new_image=ThumbnailImage(_image,geometry.width,geometry.height,
3363 _exception);
anthony805a2d42011-09-25 08:25:12 +00003364 break;
3365 }
anthonyafa3dfc2012-03-03 11:31:30 +00003366 if (LocaleCompare("tint",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003367 {
anthony7bcfe7f2012-03-30 14:01:22 +00003368 if (IfMagickFalse(IsGeometry(arg1)))
anthony52bef752012-03-27 13:54:47 +00003369 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003370 new_image=TintImage(_image,arg1,&_draw_info->fill,_exception);
anthony805a2d42011-09-25 08:25:12 +00003371 break;
3372 }
anthonyafa3dfc2012-03-03 11:31:30 +00003373 if (LocaleCompare("transform",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003374 {
anthonya3ef4ed2012-03-17 06:52:53 +00003375 /* DEPRECIATED -- should really use Distort AffineProjection */
anthony52bef752012-03-27 13:54:47 +00003376 new_image=AffineTransformImage(_image,&_draw_info->affine,_exception);
anthony805a2d42011-09-25 08:25:12 +00003377 break;
3378 }
anthonyafa3dfc2012-03-03 11:31:30 +00003379 if (LocaleCompare("transparent",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003380 {
3381 PixelInfo
3382 target;
3383
anthony92c93bd2012-03-19 14:02:47 +00003384 (void) QueryColorCompliance(arg1,AllCompliance,&target,_exception);
3385 (void) TransparentPaintImage(_image,&target,(Quantum)
3386 TransparentAlpha,plus_alt_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00003387 break;
3388 }
anthonyafa3dfc2012-03-03 11:31:30 +00003389 if (LocaleCompare("transpose",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003390 {
anthony92c93bd2012-03-19 14:02:47 +00003391 new_image=TransposeImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00003392 break;
3393 }
anthonyafa3dfc2012-03-03 11:31:30 +00003394 if (LocaleCompare("transverse",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003395 {
anthony92c93bd2012-03-19 14:02:47 +00003396 new_image=TransverseImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00003397 break;
3398 }
anthonyafa3dfc2012-03-03 11:31:30 +00003399 if (LocaleCompare("trim",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003400 {
anthony92c93bd2012-03-19 14:02:47 +00003401 new_image=TrimImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00003402 break;
3403 }
anthonyafa3dfc2012-03-03 11:31:30 +00003404 if (LocaleCompare("type",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003405 {
anthonyab3a50c2011-10-27 11:48:57 +00003406 /* Note that "type" setting should have already been defined */
anthony92c93bd2012-03-19 14:02:47 +00003407 (void) SetImageType(_image,_image_info->type,_exception);
anthony805a2d42011-09-25 08:25:12 +00003408 break;
3409 }
anthonyebb73a22012-03-22 14:25:52 +00003410 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003411 }
3412 case 'u':
3413 {
anthonyafa3dfc2012-03-03 11:31:30 +00003414 if (LocaleCompare("unique",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003415 {
anthony52bef752012-03-27 13:54:47 +00003416 /* FUTURE: move to SyncImageSettings() and AcqireImage()???
3417 Option is not documented, bt appears to be for "identify".
3418 We may need a identify specific verbose!
3419 */
3420 if (plus_alt_op) {
anthony92c93bd2012-03-19 14:02:47 +00003421 (void) DeleteImageArtifact(_image,"identify:unique-colors");
anthony805a2d42011-09-25 08:25:12 +00003422 break;
3423 }
anthony92c93bd2012-03-19 14:02:47 +00003424 (void) SetImageArtifact(_image,"identify:unique-colors","true");
3425 (void) SetImageArtifact(_image,"verbose","true");
anthony805a2d42011-09-25 08:25:12 +00003426 break;
3427 }
anthonyafa3dfc2012-03-03 11:31:30 +00003428 if (LocaleCompare("unique-colors",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003429 {
anthony92c93bd2012-03-19 14:02:47 +00003430 new_image=UniqueImageColors(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00003431 break;
3432 }
anthonyafa3dfc2012-03-03 11:31:30 +00003433 if (LocaleCompare("unsharp",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003434 {
anthony7bcfe7f2012-03-30 14:01:22 +00003435 if (IfMagickFalse(IsGeometry(arg1)))
anthony52bef752012-03-27 13:54:47 +00003436 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00003437 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003438 if ((flags & SigmaValue) == 0)
3439 geometry_info.sigma=1.0;
3440 if ((flags & XiValue) == 0)
3441 geometry_info.xi=1.0;
3442 if ((flags & PsiValue) == 0)
3443 geometry_info.psi=0.05;
anthony92c93bd2012-03-19 14:02:47 +00003444 new_image=UnsharpMaskImage(_image,geometry_info.rho,
3445 geometry_info.sigma,geometry_info.xi,geometry_info.psi,_exception);
anthony805a2d42011-09-25 08:25:12 +00003446 break;
3447 }
anthonyebb73a22012-03-22 14:25:52 +00003448 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003449 }
3450 case 'v':
3451 {
anthonyafa3dfc2012-03-03 11:31:30 +00003452 if (LocaleCompare("verbose",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003453 {
anthonyafa3dfc2012-03-03 11:31:30 +00003454 /* FUTURE: move to SyncImageSettings() and AcquireImage()???
anthony92c93bd2012-03-19 14:02:47 +00003455 three places! ImageArtifact ImageOption _image_info->verbose
anthony5330ae02012-03-20 14:17:01 +00003456 Some how new images also get this artifact!
anthony31f1bf72012-01-30 12:37:22 +00003457 */
anthony92c93bd2012-03-19 14:02:47 +00003458 (void) SetImageArtifact(_image,option+1,
anthonyafa3dfc2012-03-03 11:31:30 +00003459 IfNormalOp ? "true" : "false" );
anthony805a2d42011-09-25 08:25:12 +00003460 break;
3461 }
anthonyafa3dfc2012-03-03 11:31:30 +00003462 if (LocaleCompare("vignette",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003463 {
anthony7bcfe7f2012-03-30 14:01:22 +00003464 if (IfMagickFalse(IsGeometry(arg1)))
anthony52bef752012-03-27 13:54:47 +00003465 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00003466 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003467 if ((flags & SigmaValue) == 0)
3468 geometry_info.sigma=1.0;
3469 if ((flags & XiValue) == 0)
anthony92c93bd2012-03-19 14:02:47 +00003470 geometry_info.xi=0.1*_image->columns;
anthony805a2d42011-09-25 08:25:12 +00003471 if ((flags & PsiValue) == 0)
anthony92c93bd2012-03-19 14:02:47 +00003472 geometry_info.psi=0.1*_image->rows;
3473 new_image=VignetteImage(_image,geometry_info.rho,geometry_info.sigma,
cristyaa2c16c2012-03-25 22:21:35 +00003474 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
3475 ceil(geometry_info.psi-0.5),_exception);
anthony805a2d42011-09-25 08:25:12 +00003476 break;
3477 }
anthonyebb73a22012-03-22 14:25:52 +00003478 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003479 }
3480 case 'w':
3481 {
anthonyafa3dfc2012-03-03 11:31:30 +00003482 if (LocaleCompare("wave",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003483 {
anthony7bcfe7f2012-03-30 14:01:22 +00003484 if (IfMagickFalse(IsGeometry(arg1)))
anthony52bef752012-03-27 13:54:47 +00003485 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00003486 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003487 if ((flags & SigmaValue) == 0)
3488 geometry_info.sigma=1.0;
anthony92c93bd2012-03-19 14:02:47 +00003489 new_image=WaveImage(_image,geometry_info.rho,geometry_info.sigma,
3490 _image->interpolate,_exception);
anthony805a2d42011-09-25 08:25:12 +00003491 break;
3492 }
anthonyafa3dfc2012-03-03 11:31:30 +00003493 if (LocaleCompare("white-threshold",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003494 {
anthony7bcfe7f2012-03-30 14:01:22 +00003495 if (IfMagickFalse(IsGeometry(arg1)))
anthony52bef752012-03-27 13:54:47 +00003496 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003497 (void) WhiteThresholdImage(_image,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00003498 break;
3499 }
anthonyebb73a22012-03-22 14:25:52 +00003500 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003501 }
3502 default:
anthonyebb73a22012-03-22 14:25:52 +00003503 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003504 }
3505 /*
3506 Replace current image with any image that was generated
anthony31f1bf72012-01-30 12:37:22 +00003507 and set image point to last image (so image->next is correct)
anthony805a2d42011-09-25 08:25:12 +00003508 */
3509 if (new_image != (Image *) NULL)
anthony92c93bd2012-03-19 14:02:47 +00003510 ReplaceImageInListReturnLast(&_image,new_image);
anthony805a2d42011-09-25 08:25:12 +00003511
anthony31f1bf72012-01-30 12:37:22 +00003512 return;
anthony92c93bd2012-03-19 14:02:47 +00003513#undef _image_info
3514#undef _draw_info
3515#undef _quantize_info
3516#undef _image
3517#undef _exception
anthonyafa3dfc2012-03-03 11:31:30 +00003518#undef IfNormalOp
3519#undef IfPlusOp
anthony31f1bf72012-01-30 12:37:22 +00003520#undef normal_op
anthonyafa3dfc2012-03-03 11:31:30 +00003521#undef plus_alt_op
anthony31f1bf72012-01-30 12:37:22 +00003522}
anthonyfd706f92012-01-19 04:22:02 +00003523
anthony43f425d2012-02-26 12:58:58 +00003524WandExport void CLISimpleOperatorImages(MagickCLI *cli_wand,
anthonyafa3dfc2012-03-03 11:31:30 +00003525 const char *option, const char *arg1, const char *arg2)
anthony31f1bf72012-01-30 12:37:22 +00003526{
3527 size_t
anthony43f425d2012-02-26 12:58:58 +00003528 n,
anthony31f1bf72012-01-30 12:37:22 +00003529 i;
3530
anthony43f425d2012-02-26 12:58:58 +00003531 assert(cli_wand != (MagickCLI *) NULL);
3532 assert(cli_wand->signature == WandSignature);
3533 assert(cli_wand->wand.signature == WandSignature);
3534 assert(cli_wand->wand.images != (Image *) NULL); /* images must be present */
anthony7bcfe7f2012-03-30 14:01:22 +00003535 if (IfMagickTrue(cli_wand->wand.debug))
anthony43f425d2012-02-26 12:58:58 +00003536 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
anthony31f1bf72012-01-30 12:37:22 +00003537
anthonyafa3dfc2012-03-03 11:31:30 +00003538#if !USE_WAND_METHODS
3539 /* FUTURE add appropriate tracing */
anthony31f1bf72012-01-30 12:37:22 +00003540 i=0;
anthony43f425d2012-02-26 12:58:58 +00003541 n=GetImageListLength(cli_wand->wand.images);
3542 cli_wand->wand.images=GetFirstImageInList(cli_wand->wand.images);
anthonyafa3dfc2012-03-03 11:31:30 +00003543 while (1) {
anthony31f1bf72012-01-30 12:37:22 +00003544 i++;
anthonyafa3dfc2012-03-03 11:31:30 +00003545 CLISimpleOperatorImage(cli_wand, option, arg1, arg2);
anthony43f425d2012-02-26 12:58:58 +00003546 if ( cli_wand->wand.images->next == (Image *) NULL )
3547 break;
3548 cli_wand->wand.images=cli_wand->wand.images->next;
anthony31f1bf72012-01-30 12:37:22 +00003549 }
anthony43f425d2012-02-26 12:58:58 +00003550 assert( i == n );
3551 cli_wand->wand.images=GetFirstImageInList(cli_wand->wand.images);
anthonyafa3dfc2012-03-03 11:31:30 +00003552#else
3553 MagickResetIterator(&cli_wand->wand);
anthony7bcfe7f2012-03-30 14:01:22 +00003554 while ( IfMagickTrue(MagickNextImage(&cli_wand->wand)) )
anthonyafa3dfc2012-03-03 11:31:30 +00003555 CLISimpleOperatorImage(cli_wand, option, arg1, arg2);
3556 MagickResetIterator(&cli_wand->wand);
3557#endif
anthony31f1bf72012-01-30 12:37:22 +00003558 return;
anthony805a2d42011-09-25 08:25:12 +00003559}
3560
3561/*
3562%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3563% %
3564% %
3565% %
anthony43f425d2012-02-26 12:58:58 +00003566+ 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 +00003567% %
3568% %
3569% %
3570%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3571%
anthony43f425d2012-02-26 12:58:58 +00003572% CLIListOperatorImages() applies a single operation that is apply to the
anthony31f1bf72012-01-30 12:37:22 +00003573% entire image list as a whole. The result is often a complete replacment
3574% of the image list with a completely new list, or just a single image.
anthony805a2d42011-09-25 08:25:12 +00003575%
3576% The format of the MogrifyImage method is:
3577%
anthony43f425d2012-02-26 12:58:58 +00003578% void CLIListOperatorImages(MagickCLI *cli_wand,
anthonyafa3dfc2012-03-03 11:31:30 +00003579% const char *option, const char *arg1, const char *arg2)
anthony805a2d42011-09-25 08:25:12 +00003580%
3581% A description of each parameter follows:
3582%
anthony43f425d2012-02-26 12:58:58 +00003583% o cli_wand: structure holding settings to be applied
anthony805a2d42011-09-25 08:25:12 +00003584%
anthony36a8c2c2012-02-10 00:08:44 +00003585% o option: The option string for the operation
3586%
anthony31f1bf72012-01-30 12:37:22 +00003587% o arg1, arg2: optional argument strings to the operation
anthonye5fcd362012-04-09 04:02:09 +00003588% arg2 is currently not used
anthony8b10b462012-02-08 12:32:44 +00003589%
3590% Example usage...
3591%
anthonyafa3dfc2012-03-03 11:31:30 +00003592% CLIListOperatorImages(cli_wand,MagickFalse,"-duplicate", "3", NULL);
3593% CLIListOperatorImages(cli_wand,MagickTrue, "+append", NULL, NULL);
anthony8b10b462012-02-08 12:32:44 +00003594%
anthony24aa8822012-03-11 00:56:06 +00003595% Or for handling command line arguments EG: +/-option ["arg1"]
anthony8b10b462012-02-08 12:32:44 +00003596%
anthony43f425d2012-02-26 12:58:58 +00003597% cli_wand
anthony8b10b462012-02-08 12:32:44 +00003598% argc,argv
3599% i=index in argv
3600%
anthony2052d272012-02-28 12:48:29 +00003601% option_info = GetCommandOptionInfo(argv[i]);
3602% count=option_info->type;
3603% option_type=option_info->flags;
3604%
3605% if ( (option_type & ListOperatorOptionFlag) != 0 )
anthonyafa3dfc2012-03-03 11:31:30 +00003606% CLIListOperatorImages(cli_wand,argv[i],
anthony8b10b462012-02-08 12:32:44 +00003607% count>=1 ? argv[i+1] : (char *)NULL,
3608% count>=2 ? argv[i+2] : (char *)NULL );
3609% i += count+1;
3610%
anthony805a2d42011-09-25 08:25:12 +00003611*/
anthony43f425d2012-02-26 12:58:58 +00003612WandExport void CLIListOperatorImages(MagickCLI *cli_wand,
anthonye5fcd362012-04-09 04:02:09 +00003613 const char *option,const char *arg1, const char *magick_unused(arg2))
anthony805a2d42011-09-25 08:25:12 +00003614{
anthony2a0ec8c2012-03-24 04:35:56 +00003615 ssize_t
3616 parse;
3617
anthony31f1bf72012-01-30 12:37:22 +00003618 Image
3619 *new_images;
anthony805a2d42011-09-25 08:25:12 +00003620
anthony2e4501b2012-03-30 04:41:54 +00003621#define _image_info (cli_wand->wand.image_info)
3622#define _images (cli_wand->wand.images)
3623#define _exception (cli_wand->wand.exception)
3624#define _draw_info (cli_wand->draw_info)
3625#define _quantize_info (cli_wand->quantize_info)
anthonyafa3dfc2012-03-03 11:31:30 +00003626#define IfNormalOp (*option=='-')
3627#define IfPlusOp (*option!='-')
anthony7bcfe7f2012-03-30 14:01:22 +00003628#define normal_op IsMagickTrue(IfNormalOp)
anthony805a2d42011-09-25 08:25:12 +00003629
anthony43f425d2012-02-26 12:58:58 +00003630 assert(cli_wand != (MagickCLI *) NULL);
3631 assert(cli_wand->signature == WandSignature);
3632 assert(cli_wand->wand.signature == WandSignature);
anthony92c93bd2012-03-19 14:02:47 +00003633 assert(_images != (Image *) NULL); /* _images must be present */
anthony7bcfe7f2012-03-30 14:01:22 +00003634 if (IfMagickTrue(cli_wand->wand.debug))
anthony43f425d2012-02-26 12:58:58 +00003635 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
anthony31f1bf72012-01-30 12:37:22 +00003636
anthony92c93bd2012-03-19 14:02:47 +00003637 (void) SyncImagesSettings(_image_info,_images,_exception);
anthony31f1bf72012-01-30 12:37:22 +00003638
3639 new_images=NewImageList();
3640
anthonyafa3dfc2012-03-03 11:31:30 +00003641 switch (*(option+1))
anthony805a2d42011-09-25 08:25:12 +00003642 {
3643 case 'a':
3644 {
anthonyafa3dfc2012-03-03 11:31:30 +00003645 if (LocaleCompare("append",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003646 {
anthony92c93bd2012-03-19 14:02:47 +00003647 new_images=AppendImages(_images,normal_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00003648 break;
3649 }
anthonyafa3dfc2012-03-03 11:31:30 +00003650 if (LocaleCompare("average",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003651 {
anthony31f1bf72012-01-30 12:37:22 +00003652 /* DEPRECIATED - use -evaluate-sequence Mean */
anthonyafa3dfc2012-03-03 11:31:30 +00003653 CLIListOperatorImages(cli_wand,"-evaluate-sequence","Mean",NULL);
anthony805a2d42011-09-25 08:25:12 +00003654 break;
3655 }
anthonyebb73a22012-03-22 14:25:52 +00003656 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003657 }
3658 case 'c':
3659 {
cristy5f257b22012-03-07 00:27:29 +00003660 if (LocaleCompare("channel-fx",option+1) == 0)
cristy87c02f42012-02-24 00:19:10 +00003661 {
anthony92c93bd2012-03-19 14:02:47 +00003662 new_images=ChannelFxImage(_images,arg1,_exception);
cristy87c02f42012-02-24 00:19:10 +00003663 break;
3664 }
anthonyafa3dfc2012-03-03 11:31:30 +00003665 if (LocaleCompare("clut",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003666 {
anthony805a2d42011-09-25 08:25:12 +00003667 Image
anthony31f1bf72012-01-30 12:37:22 +00003668 *clut_image;
anthony805a2d42011-09-25 08:25:12 +00003669
anthonyafa3dfc2012-03-03 11:31:30 +00003670 /* FUTURE - make this a compose option, and thus can be used
3671 with layers compose or even compose last image over all other
anthony92c93bd2012-03-19 14:02:47 +00003672 _images.
cristy87c02f42012-02-24 00:19:10 +00003673 */
anthony92c93bd2012-03-19 14:02:47 +00003674 new_images=RemoveFirstImageFromList(&_images);
3675 clut_image=RemoveLastImageFromList(&_images);
anthonye8f56492012-02-12 12:39:02 +00003676 /* FUTURE - produce Exception, rather than silent fail */
anthony805a2d42011-09-25 08:25:12 +00003677 if (clut_image == (Image *) NULL)
cristy87c02f42012-02-24 00:19:10 +00003678 break;
cristye52fb5e2012-04-06 23:30:20 +00003679 (void) ClutImage(new_images,clut_image,new_images->interpolate,_exception);
anthony805a2d42011-09-25 08:25:12 +00003680 clut_image=DestroyImage(clut_image);
anthony805a2d42011-09-25 08:25:12 +00003681 break;
3682 }
anthonyafa3dfc2012-03-03 11:31:30 +00003683 if (LocaleCompare("coalesce",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003684 {
anthony92c93bd2012-03-19 14:02:47 +00003685 new_images=CoalesceImages(_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003686 break;
3687 }
anthonyafa3dfc2012-03-03 11:31:30 +00003688 if (LocaleCompare("combine",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003689 {
anthony43f425d2012-02-26 12:58:58 +00003690 /* FUTURE - this may be replaced by a 'channel' method */
anthony92c93bd2012-03-19 14:02:47 +00003691 new_images=CombineImages(_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003692 break;
3693 }
anthonyafa3dfc2012-03-03 11:31:30 +00003694 if (LocaleCompare("composite",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003695 {
cristyfeb3e962012-03-29 17:25:55 +00003696 CompositeOperator
3697 compose;
3698
3699 const char*
3700 value;
3701
3702 MagickBooleanType
3703 clip_to_self;
3704
anthony805a2d42011-09-25 08:25:12 +00003705 Image
3706 *mask_image,
anthony31f1bf72012-01-30 12:37:22 +00003707 *source_image;
anthony805a2d42011-09-25 08:25:12 +00003708
3709 RectangleInfo
3710 geometry;
3711
anthony7bcfe7f2012-03-30 14:01:22 +00003712 /* Compose value from "-compose" option only */
anthony92c93bd2012-03-19 14:02:47 +00003713 value=GetImageOption(_image_info,"compose");
cristy542a95b2012-04-03 19:30:58 +00003714 if (value == (const char *) NULL)
anthony31f1bf72012-01-30 12:37:22 +00003715 compose=OverCompositeOp; /* use Over not source_image->compose */
cristy542a95b2012-04-03 19:30:58 +00003716 else
3717 compose=(CompositeOperator) ParseCommandOption(MagickComposeOptions,
3718 MagickFalse,value);
anthony5f867ae2011-10-09 10:28:34 +00003719
anthony7bcfe7f2012-03-30 14:01:22 +00003720 /* Get "clip-to-self" expert setting (false is normal) */
anthonye5fcd362012-04-09 04:02:09 +00003721 clip_to_self=IsStringTrue(GetImageOption(_image_info,
3722 "compose:clip-to-self")); /* if this is true */
anthony2e4501b2012-03-30 04:41:54 +00003723 value=GetImageOption(_image_info,"compose:outside-overlay");
anthony7bcfe7f2012-03-30 14:01:22 +00003724 if (value != (const char *) NULL) { /* or this false */
anthony2e4501b2012-03-30 04:41:54 +00003725 /* FUTURE: depreciate warning for "compose:outside-overlay"*/
anthony7bcfe7f2012-03-30 14:01:22 +00003726 clip_to_self= IsMagickFalse(IsStringNotFalse(value));
anthony2e4501b2012-03-30 04:41:54 +00003727 }
3728
anthony92c93bd2012-03-19 14:02:47 +00003729 new_images=RemoveFirstImageFromList(&_images);
3730 source_image=RemoveFirstImageFromList(&_images);
anthony31f1bf72012-01-30 12:37:22 +00003731 if (source_image == (Image *) NULL)
anthony7bcfe7f2012-03-30 14:01:22 +00003732 break; /* FUTURE - produce Exception, rather than silent fail */
anthonye8f56492012-02-12 12:39:02 +00003733
anthony31f1bf72012-01-30 12:37:22 +00003734 /* FUTURE - this should not be here! - should be part of -geometry */
3735 (void) TransformImage(&source_image,(char *) NULL,
anthony92c93bd2012-03-19 14:02:47 +00003736 source_image->geometry,_exception);
anthony5f867ae2011-10-09 10:28:34 +00003737
anthony31f1bf72012-01-30 12:37:22 +00003738 SetGeometry(source_image,&geometry);
3739 (void) ParseAbsoluteGeometry(source_image->geometry,&geometry);
3740 GravityAdjustGeometry(new_images->columns,new_images->rows,
3741 new_images->gravity, &geometry);
anthony5f867ae2011-10-09 10:28:34 +00003742
anthony92c93bd2012-03-19 14:02:47 +00003743 mask_image=RemoveFirstImageFromList(&_images);
anthony805a2d42011-09-25 08:25:12 +00003744 if (mask_image != (Image *) NULL)
anthony31f1bf72012-01-30 12:37:22 +00003745 { /* handle a third write mask image */
anthony5f867ae2011-10-09 10:28:34 +00003746 if ((compose == DisplaceCompositeOp) ||
anthony7bcfe7f2012-03-30 14:01:22 +00003747 (compose == DistortCompositeOp)) {
3748 /* Merge Y displacement into X displace/distort map. */
3749 (void) CompositeImage(source_image,mask_image,
3750 CopyGreenCompositeOp,MagickTrue,0,0,_exception);
3751 mask_image=DestroyImage(mask_image);
3752 }
3753 else {
3754 /* Set a blending mask for the composition. */
3755 (void) NegateImage(mask_image,MagickFalse,_exception);
3756 (void) SetImageMask(new_images,mask_image,_exception);
3757 mask_image=DestroyImage(mask_image);
3758 }
anthony805a2d42011-09-25 08:25:12 +00003759 }
cristyfeb3e962012-03-29 17:25:55 +00003760 (void) CompositeImage(new_images,source_image,compose,clip_to_self,
3761 geometry.x,geometry.y,_exception);
anthony92c93bd2012-03-19 14:02:47 +00003762 (void) SetImageMask(new_images,(Image *) NULL,_exception);
anthony31f1bf72012-01-30 12:37:22 +00003763 source_image=DestroyImage(source_image);
anthony805a2d42011-09-25 08:25:12 +00003764 break;
3765 }
anthonyebb73a22012-03-22 14:25:52 +00003766 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003767 }
3768 case 'd':
3769 {
anthonyafa3dfc2012-03-03 11:31:30 +00003770 if (LocaleCompare("deconstruct",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003771 {
anthony31f1bf72012-01-30 12:37:22 +00003772 /* DEPRECIATED - use -layers CompareAny */
anthonyafa3dfc2012-03-03 11:31:30 +00003773 CLIListOperatorImages(cli_wand,"-layer","CompareAny",NULL);
anthony805a2d42011-09-25 08:25:12 +00003774 break;
3775 }
anthonyafa3dfc2012-03-03 11:31:30 +00003776 if (LocaleCompare("delete",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003777 {
anthonyafa3dfc2012-03-03 11:31:30 +00003778 if (IfNormalOp)
anthony92c93bd2012-03-19 14:02:47 +00003779 DeleteImages(&_images,arg1,_exception);
anthonyafa3dfc2012-03-03 11:31:30 +00003780 else
anthony92c93bd2012-03-19 14:02:47 +00003781 DeleteImages(&_images,"-1",_exception);
anthony805a2d42011-09-25 08:25:12 +00003782 break;
3783 }
anthonyafa3dfc2012-03-03 11:31:30 +00003784 if (LocaleCompare("duplicate",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003785 {
anthonyafa3dfc2012-03-03 11:31:30 +00003786 if (IfNormalOp)
anthony805a2d42011-09-25 08:25:12 +00003787 {
3788 const char
3789 *p;
3790
3791 size_t
3792 number_duplicates;
3793
anthony7bcfe7f2012-03-30 14:01:22 +00003794 if (IfMagickFalse(IsGeometry(arg1)))
anthonyebb73a22012-03-22 14:25:52 +00003795 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,
3796 arg1);
anthony31f1bf72012-01-30 12:37:22 +00003797 number_duplicates=(size_t) StringToLong(arg1);
3798 p=strchr(arg1,',');
anthony805a2d42011-09-25 08:25:12 +00003799 if (p == (const char *) NULL)
anthonyebb73a22012-03-22 14:25:52 +00003800 new_images=DuplicateImages(_images,number_duplicates,"-1",
3801 _exception);
anthony805a2d42011-09-25 08:25:12 +00003802 else
anthony92c93bd2012-03-19 14:02:47 +00003803 new_images=DuplicateImages(_images,number_duplicates,p,
3804 _exception);
anthony805a2d42011-09-25 08:25:12 +00003805 }
anthonyafa3dfc2012-03-03 11:31:30 +00003806 else
anthony92c93bd2012-03-19 14:02:47 +00003807 new_images=DuplicateImages(_images,1,"-1",_exception);
3808 AppendImageToList(&_images, new_images);
anthony36a8c2c2012-02-10 00:08:44 +00003809 new_images=(Image *)NULL;
anthony805a2d42011-09-25 08:25:12 +00003810 break;
3811 }
anthonyebb73a22012-03-22 14:25:52 +00003812 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003813 }
3814 case 'e':
3815 {
anthonyafa3dfc2012-03-03 11:31:30 +00003816 if (LocaleCompare("evaluate-sequence",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003817 {
anthony2a0ec8c2012-03-24 04:35:56 +00003818 parse = ParseCommandOption(MagickEvaluateOptions,MagickFalse,arg1);
3819 if ( parse < 0 )
3820 CLIWandExceptArgBreak(OptionError,"UnrecognizedEvaluateOperator",
3821 option,arg1);
3822 new_images=EvaluateImages(_images,(MagickEvaluateOperator)parse,
3823 _exception);
anthony805a2d42011-09-25 08:25:12 +00003824 break;
3825 }
anthonyebb73a22012-03-22 14:25:52 +00003826 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003827 }
3828 case 'f':
3829 {
anthonyafa3dfc2012-03-03 11:31:30 +00003830 if (LocaleCompare("fft",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003831 {
anthony92c93bd2012-03-19 14:02:47 +00003832 new_images=ForwardFourierTransformImage(_images,normal_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00003833 break;
3834 }
anthonyafa3dfc2012-03-03 11:31:30 +00003835 if (LocaleCompare("flatten",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003836 {
anthony319dac62012-03-06 04:12:44 +00003837 /* REDIRECTED to use -layers flatten instead */
anthony2e4501b2012-03-30 04:41:54 +00003838 CLIListOperatorImages(cli_wand,"-layers",option+1,NULL);
anthony805a2d42011-09-25 08:25:12 +00003839 break;
3840 }
anthonyafa3dfc2012-03-03 11:31:30 +00003841 if (LocaleCompare("fx",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003842 {
anthony92c93bd2012-03-19 14:02:47 +00003843 new_images=FxImage(_images,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00003844 break;
3845 }
anthonyebb73a22012-03-22 14:25:52 +00003846 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003847 }
3848 case 'h':
3849 {
anthonyafa3dfc2012-03-03 11:31:30 +00003850 if (LocaleCompare("hald-clut",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003851 {
anthony31f1bf72012-01-30 12:37:22 +00003852 /* FUTURE - make this a compose option (and thus layers compose )
anthony92c93bd2012-03-19 14:02:47 +00003853 or perhaps compose last image over all other _images.
anthony31f1bf72012-01-30 12:37:22 +00003854 */
anthony805a2d42011-09-25 08:25:12 +00003855 Image
anthony31f1bf72012-01-30 12:37:22 +00003856 *hald_image;
anthony805a2d42011-09-25 08:25:12 +00003857
anthony92c93bd2012-03-19 14:02:47 +00003858 new_images=RemoveFirstImageFromList(&_images);
3859 hald_image=RemoveLastImageFromList(&_images);
anthony805a2d42011-09-25 08:25:12 +00003860 if (hald_image == (Image *) NULL)
anthony31f1bf72012-01-30 12:37:22 +00003861 break;
anthony92c93bd2012-03-19 14:02:47 +00003862 (void) HaldClutImage(new_images,hald_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00003863 hald_image=DestroyImage(hald_image);
anthony805a2d42011-09-25 08:25:12 +00003864 break;
3865 }
anthonyebb73a22012-03-22 14:25:52 +00003866 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003867 }
3868 case 'i':
3869 {
anthonyafa3dfc2012-03-03 11:31:30 +00003870 if (LocaleCompare("ift",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003871 {
3872 Image
anthony805a2d42011-09-25 08:25:12 +00003873 *magnitude_image,
3874 *phase_image;
3875
anthony92c93bd2012-03-19 14:02:47 +00003876 magnitude_image=RemoveFirstImageFromList(&_images);
3877 phase_image=RemoveFirstImageFromList(&_images);
anthonye8f56492012-02-12 12:39:02 +00003878 /* FUTURE - produce Exception, rather than silent fail */
anthony31f1bf72012-01-30 12:37:22 +00003879 if (phase_image == (Image *) NULL)
3880 break;
3881 new_images=InverseFourierTransformImage(magnitude_image,phase_image,
anthony92c93bd2012-03-19 14:02:47 +00003882 normal_op,_exception);
anthony31f1bf72012-01-30 12:37:22 +00003883 magnitude_image=DestroyImage(magnitude_image);
3884 phase_image=DestroyImage(phase_image);
anthony805a2d42011-09-25 08:25:12 +00003885 break;
3886 }
anthonyafa3dfc2012-03-03 11:31:30 +00003887 if (LocaleCompare("insert",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003888 {
3889 Image
anthony31f1bf72012-01-30 12:37:22 +00003890 *insert_image,
3891 *index_image;
3892
3893 ssize_t
3894 index;
anthony805a2d42011-09-25 08:25:12 +00003895
anthony7bcfe7f2012-03-30 14:01:22 +00003896 if (IfNormalOp && IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00003897 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00003898 index=0;
anthony92c93bd2012-03-19 14:02:47 +00003899 insert_image=RemoveLastImageFromList(&_images);
anthonyafa3dfc2012-03-03 11:31:30 +00003900 if (IfNormalOp)
anthony31f1bf72012-01-30 12:37:22 +00003901 index=(ssize_t) StringToLong(arg1);
anthony43f425d2012-02-26 12:58:58 +00003902 index_image=insert_image;
anthony805a2d42011-09-25 08:25:12 +00003903 if (index == 0)
anthony92c93bd2012-03-19 14:02:47 +00003904 PrependImageToList(&_images,insert_image);
3905 else if (index == (ssize_t) GetImageListLength(_images))
3906 AppendImageToList(&_images,insert_image);
anthony805a2d42011-09-25 08:25:12 +00003907 else
anthony43f425d2012-02-26 12:58:58 +00003908 {
anthony92c93bd2012-03-19 14:02:47 +00003909 index_image=GetImageFromList(_images,index-1);
anthony43f425d2012-02-26 12:58:58 +00003910 if (index_image == (Image *) NULL)
anthonyfe1aa782012-03-24 13:43:04 +00003911 CLIWandExceptArgBreak(OptionError,"NoSuchImage",option,arg1);
anthony43f425d2012-02-26 12:58:58 +00003912 InsertImageInList(&index_image,insert_image);
3913 }
anthony92c93bd2012-03-19 14:02:47 +00003914 _images=GetFirstImageInList(index_image);
anthony805a2d42011-09-25 08:25:12 +00003915 break;
3916 }
anthonyebb73a22012-03-22 14:25:52 +00003917 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003918 }
3919 case 'l':
3920 {
anthonyafa3dfc2012-03-03 11:31:30 +00003921 if (LocaleCompare("layers",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003922 {
anthonyfe1aa782012-03-24 13:43:04 +00003923 parse=ParseCommandOption(MagickLayerOptions,MagickFalse,arg1);
3924 if ( parse < 0 )
3925 CLIWandExceptArgBreak(OptionError,"UnrecognizedLayerMethod",
3926 option,arg1);
3927 switch ((ImageLayerMethod) parse)
anthony805a2d42011-09-25 08:25:12 +00003928 {
3929 case CoalesceLayer:
3930 {
anthony92c93bd2012-03-19 14:02:47 +00003931 new_images=CoalesceImages(_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003932 break;
3933 }
3934 case CompareAnyLayer:
3935 case CompareClearLayer:
3936 case CompareOverlayLayer:
3937 default:
3938 {
anthonyfe1aa782012-03-24 13:43:04 +00003939 new_images=CompareImagesLayers(_images,(ImageLayerMethod) parse,
3940 _exception);
anthony805a2d42011-09-25 08:25:12 +00003941 break;
3942 }
3943 case MergeLayer:
3944 case FlattenLayer:
3945 case MosaicLayer:
3946 case TrimBoundsLayer:
3947 {
anthonyfe1aa782012-03-24 13:43:04 +00003948 new_images=MergeImageLayers(_images,(ImageLayerMethod) parse,
3949 _exception);
anthony805a2d42011-09-25 08:25:12 +00003950 break;
3951 }
3952 case DisposeLayer:
3953 {
anthony92c93bd2012-03-19 14:02:47 +00003954 new_images=DisposeImages(_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003955 break;
3956 }
3957 case OptimizeImageLayer:
3958 {
anthony92c93bd2012-03-19 14:02:47 +00003959 new_images=OptimizeImageLayers(_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003960 break;
3961 }
3962 case OptimizePlusLayer:
3963 {
anthony92c93bd2012-03-19 14:02:47 +00003964 new_images=OptimizePlusImageLayers(_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003965 break;
3966 }
3967 case OptimizeTransLayer:
3968 {
anthony92c93bd2012-03-19 14:02:47 +00003969 OptimizeImageTransparency(_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003970 break;
3971 }
3972 case RemoveDupsLayer:
3973 {
anthony92c93bd2012-03-19 14:02:47 +00003974 RemoveDuplicateLayers(&_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003975 break;
3976 }
3977 case RemoveZeroLayer:
3978 {
anthony92c93bd2012-03-19 14:02:47 +00003979 RemoveZeroDelayLayers(&_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003980 break;
3981 }
3982 case OptimizeLayer:
anthony31f1bf72012-01-30 12:37:22 +00003983 { /* General Purpose, GIF Animation Optimizer. */
anthony92c93bd2012-03-19 14:02:47 +00003984 new_images=CoalesceImages(_images,_exception);
anthony31f1bf72012-01-30 12:37:22 +00003985 if (new_images == (Image *) NULL)
3986 break;
anthony92c93bd2012-03-19 14:02:47 +00003987 _images=DestroyImageList(_images);
3988 _images=OptimizeImageLayers(new_images,_exception);
3989 if (_images == (Image *) NULL)
anthony31f1bf72012-01-30 12:37:22 +00003990 break;
3991 new_images=DestroyImageList(new_images);
anthony92c93bd2012-03-19 14:02:47 +00003992 OptimizeImageTransparency(_images,_exception);
3993 (void) RemapImages(_quantize_info,_images,(Image *) NULL,
3994 _exception);
anthony805a2d42011-09-25 08:25:12 +00003995 break;
3996 }
3997 case CompositeLayer:
3998 {
anthony805a2d42011-09-25 08:25:12 +00003999 Image
4000 *source;
4001
4002 RectangleInfo
4003 geometry;
4004
anthony31f1bf72012-01-30 12:37:22 +00004005 CompositeOperator
anthony5f867ae2011-10-09 10:28:34 +00004006 compose;
4007
4008 const char*
4009 value;
4010
anthony92c93bd2012-03-19 14:02:47 +00004011 value=GetImageOption(_image_info,"compose");
anthony31f1bf72012-01-30 12:37:22 +00004012 compose=OverCompositeOp; /* Default to Over */
anthony5f867ae2011-10-09 10:28:34 +00004013 if (value != (const char *) NULL)
4014 compose=(CompositeOperator) ParseCommandOption(
4015 MagickComposeOptions,MagickFalse,value);
anthony5f867ae2011-10-09 10:28:34 +00004016
anthony31f1bf72012-01-30 12:37:22 +00004017 /* Split image sequence at the first 'NULL:' image. */
anthony92c93bd2012-03-19 14:02:47 +00004018 source=_images;
anthony805a2d42011-09-25 08:25:12 +00004019 while (source != (Image *) NULL)
4020 {
4021 source=GetNextImageInList(source);
4022 if ((source != (Image *) NULL) &&
4023 (LocaleCompare(source->magick,"NULL") == 0))
4024 break;
4025 }
4026 if (source != (Image *) NULL)
4027 {
4028 if ((GetPreviousImageInList(source) == (Image *) NULL) ||
4029 (GetNextImageInList(source) == (Image *) NULL))
4030 source=(Image *) NULL;
4031 else
anthony31f1bf72012-01-30 12:37:22 +00004032 { /* Separate the two lists, junk the null: image. */
anthony805a2d42011-09-25 08:25:12 +00004033 source=SplitImageList(source->previous);
4034 DeleteImageFromList(&source);
4035 }
4036 }
4037 if (source == (Image *) NULL)
4038 {
anthony92c93bd2012-03-19 14:02:47 +00004039 (void) ThrowMagickException(_exception,GetMagickModule(),
anthony805a2d42011-09-25 08:25:12 +00004040 OptionError,"MissingNullSeparator","layers Composite");
anthony805a2d42011-09-25 08:25:12 +00004041 break;
4042 }
anthony31f1bf72012-01-30 12:37:22 +00004043 /* Adjust offset with gravity and virtual canvas. */
anthony92c93bd2012-03-19 14:02:47 +00004044 SetGeometry(_images,&geometry);
4045 (void) ParseAbsoluteGeometry(_images->geometry,&geometry);
anthony805a2d42011-09-25 08:25:12 +00004046 geometry.width=source->page.width != 0 ?
4047 source->page.width : source->columns;
4048 geometry.height=source->page.height != 0 ?
4049 source->page.height : source->rows;
anthony92c93bd2012-03-19 14:02:47 +00004050 GravityAdjustGeometry(_images->page.width != 0 ?
4051 _images->page.width : _images->columns,
4052 _images->page.height != 0 ? _images->page.height :
4053 _images->rows,_images->gravity,&geometry);
anthony5f867ae2011-10-09 10:28:34 +00004054
anthony31f1bf72012-01-30 12:37:22 +00004055 /* Compose the two image sequences together */
anthony92c93bd2012-03-19 14:02:47 +00004056 CompositeLayers(_images,compose,source,geometry.x,geometry.y,
4057 _exception);
anthony805a2d42011-09-25 08:25:12 +00004058 source=DestroyImageList(source);
4059 break;
4060 }
4061 }
anthony805a2d42011-09-25 08:25:12 +00004062 break;
4063 }
anthonyebb73a22012-03-22 14:25:52 +00004064 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00004065 }
4066 case 'm':
4067 {
anthonyafa3dfc2012-03-03 11:31:30 +00004068 if (LocaleCompare("map",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00004069 {
anthony31f1bf72012-01-30 12:37:22 +00004070 /* DEPRECIATED use +remap */
anthony92c93bd2012-03-19 14:02:47 +00004071 (void) RemapImages(_quantize_info,_images,(Image *) NULL,_exception);
anthony805a2d42011-09-25 08:25:12 +00004072 break;
4073 }
anthonyafa3dfc2012-03-03 11:31:30 +00004074 if (LocaleCompare("morph",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00004075 {
4076 Image
4077 *morph_image;
4078
anthony7bcfe7f2012-03-30 14:01:22 +00004079 if (IfMagickFalse(IsGeometry(arg1)))
anthony7bc87992012-03-25 02:32:51 +00004080 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00004081 morph_image=MorphImages(_images,StringToUnsignedLong(arg1),
4082 _exception);
anthony805a2d42011-09-25 08:25:12 +00004083 if (morph_image == (Image *) NULL)
anthony31f1bf72012-01-30 12:37:22 +00004084 break;
anthony92c93bd2012-03-19 14:02:47 +00004085 _images=DestroyImageList(_images);
4086 _images=morph_image;
anthony805a2d42011-09-25 08:25:12 +00004087 break;
4088 }
anthonyafa3dfc2012-03-03 11:31:30 +00004089 if (LocaleCompare("mosaic",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00004090 {
anthony319dac62012-03-06 04:12:44 +00004091 /* REDIRECTED to use -layers mosaic instead */
anthony2e4501b2012-03-30 04:41:54 +00004092 CLIListOperatorImages(cli_wand,"-layers",option+1,NULL);
anthony805a2d42011-09-25 08:25:12 +00004093 break;
4094 }
anthonyebb73a22012-03-22 14:25:52 +00004095 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00004096 }
4097 case 'p':
4098 {
anthonyafa3dfc2012-03-03 11:31:30 +00004099 if (LocaleCompare("print",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00004100 {
4101 char
4102 *string;
4103
anthony92c93bd2012-03-19 14:02:47 +00004104 string=InterpretImageProperties(_image_info,_images,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00004105 if (string == (char *) NULL)
4106 break;
4107 (void) FormatLocaleFile(stdout,"%s",string);
4108 string=DestroyString(string);
anthony24aa8822012-03-11 00:56:06 +00004109 break;
anthony805a2d42011-09-25 08:25:12 +00004110 }
anthonyafa3dfc2012-03-03 11:31:30 +00004111 if (LocaleCompare("process",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00004112 {
4113 char
4114 **arguments;
4115
4116 int
4117 j,
4118 number_arguments;
4119
anthony31f1bf72012-01-30 12:37:22 +00004120 arguments=StringToArgv(arg1,&number_arguments);
anthony805a2d42011-09-25 08:25:12 +00004121 if (arguments == (char **) NULL)
4122 break;
anthony31f1bf72012-01-30 12:37:22 +00004123 if (strchr(arguments[1],'=') != (char *) NULL)
anthony805a2d42011-09-25 08:25:12 +00004124 {
4125 char
4126 breaker,
4127 quote,
4128 *token;
4129
4130 const char
4131 *arguments;
4132
4133 int
4134 next,
4135 status;
4136
4137 size_t
4138 length;
4139
4140 TokenInfo
4141 *token_info;
4142
4143 /*
anthony24aa8822012-03-11 00:56:06 +00004144 Support old style syntax, filter="-option arg1".
anthony805a2d42011-09-25 08:25:12 +00004145 */
anthony31f1bf72012-01-30 12:37:22 +00004146 length=strlen(arg1);
anthony805a2d42011-09-25 08:25:12 +00004147 token=(char *) NULL;
4148 if (~length >= (MaxTextExtent-1))
4149 token=(char *) AcquireQuantumMemory(length+MaxTextExtent,
4150 sizeof(*token));
4151 if (token == (char *) NULL)
4152 break;
4153 next=0;
anthony31f1bf72012-01-30 12:37:22 +00004154 arguments=arg1;
anthony805a2d42011-09-25 08:25:12 +00004155 token_info=AcquireTokenInfo();
4156 status=Tokenizer(token_info,0,token,length,arguments,"","=",
4157 "\"",'\0',&breaker,&next,&quote);
4158 token_info=DestroyTokenInfo(token_info);
4159 if (status == 0)
4160 {
4161 const char
4162 *argv;
4163
4164 argv=(&(arguments[next]));
anthony92c93bd2012-03-19 14:02:47 +00004165 (void) InvokeDynamicImageFilter(token,&_images,1,&argv,
4166 _exception);
anthony805a2d42011-09-25 08:25:12 +00004167 }
4168 token=DestroyString(token);
4169 break;
4170 }
4171 (void) SubstituteString(&arguments[1],"-","");
anthony92c93bd2012-03-19 14:02:47 +00004172 (void) InvokeDynamicImageFilter(arguments[1],&_images,
4173 number_arguments-2,(const char **) arguments+2,_exception);
anthony805a2d42011-09-25 08:25:12 +00004174 for (j=0; j < number_arguments; j++)
4175 arguments[j]=DestroyString(arguments[j]);
4176 arguments=(char **) RelinquishMagickMemory(arguments);
4177 break;
4178 }
anthonyebb73a22012-03-22 14:25:52 +00004179 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00004180 }
4181 case 'r':
4182 {
anthonyafa3dfc2012-03-03 11:31:30 +00004183 if (LocaleCompare("remap",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00004184 {
anthony92c93bd2012-03-19 14:02:47 +00004185 (void) RemapImages(_quantize_info,_images,(Image *) NULL,_exception);
anthony31f1bf72012-01-30 12:37:22 +00004186 break;
4187 }
anthonyafa3dfc2012-03-03 11:31:30 +00004188 if (LocaleCompare("reverse",option+1) == 0)
anthony31f1bf72012-01-30 12:37:22 +00004189 {
anthony92c93bd2012-03-19 14:02:47 +00004190 ReverseImageList(&_images);
anthony805a2d42011-09-25 08:25:12 +00004191 break;
4192 }
anthonyebb73a22012-03-22 14:25:52 +00004193 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00004194 }
4195 case 's':
4196 {
anthonyafa3dfc2012-03-03 11:31:30 +00004197 if (LocaleCompare("smush",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00004198 {
4199 Image
4200 *smush_image;
4201
4202 ssize_t
4203 offset;
4204
anthony7bcfe7f2012-03-30 14:01:22 +00004205 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00004206 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony31f1bf72012-01-30 12:37:22 +00004207 offset=(ssize_t) StringToLong(arg1);
anthony92c93bd2012-03-19 14:02:47 +00004208 smush_image=SmushImages(_images,normal_op,offset,_exception);
anthony805a2d42011-09-25 08:25:12 +00004209 if (smush_image == (Image *) NULL)
anthony31f1bf72012-01-30 12:37:22 +00004210 break;
anthony92c93bd2012-03-19 14:02:47 +00004211 _images=DestroyImageList(_images);
4212 _images=smush_image;
anthony805a2d42011-09-25 08:25:12 +00004213 break;
4214 }
anthony0ea037a2012-04-03 12:14:39 +00004215 if (LocaleCompare("swap",option+1) == 0) {
4216 Image
4217 *p,
4218 *q,
4219 *swap;
anthony805a2d42011-09-25 08:25:12 +00004220
anthony0ea037a2012-04-03 12:14:39 +00004221 ssize_t
4222 index,
4223 swap_index;
anthony805a2d42011-09-25 08:25:12 +00004224
anthony0ea037a2012-04-03 12:14:39 +00004225 index=-1;
4226 swap_index=-2;
4227 if (IfNormalOp) {
4228 GeometryInfo
4229 geometry_info;
4230
4231 MagickStatusType
4232 flags;
4233
4234 swap_index=(-1);
anthony7bcfe7f2012-03-30 14:01:22 +00004235 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00004236 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony0ea037a2012-04-03 12:14:39 +00004237 flags=ParseGeometry(arg1,&geometry_info);
4238 index=(ssize_t) geometry_info.rho;
4239 if ((flags & SigmaValue) != 0)
4240 swap_index=(ssize_t) geometry_info.sigma;
anthony805a2d42011-09-25 08:25:12 +00004241 }
anthony0ea037a2012-04-03 12:14:39 +00004242 p=GetImageFromList(_images,index);
4243 q=GetImageFromList(_images,swap_index);
anthony8226e722012-04-05 14:25:46 +00004244 if ((p == (Image *) NULL) || (q == (Image *) NULL)) {
4245 if (IfNormalOp)
4246 CLIWandExceptArgBreak(OptionError,"InvalidImageIndex",option,arg1)
4247 else
4248 CLIWandExceptionBreak(OptionError,"TwoOrMoreImagesRequired",option);
4249 }
anthony0ea037a2012-04-03 12:14:39 +00004250 if (p == q)
anthony8226e722012-04-05 14:25:46 +00004251 CLIWandExceptArgBreak(OptionError,"InvalidImageIndex",option,arg1);
anthony0ea037a2012-04-03 12:14:39 +00004252 swap=CloneImage(p,0,0,MagickTrue,_exception);
4253 ReplaceImageInList(&p,CloneImage(q,0,0,MagickTrue,_exception));
4254 ReplaceImageInList(&q,swap);
4255 _images=GetFirstImageInList(q);
4256 break;
4257 }
anthonyebb73a22012-03-22 14:25:52 +00004258 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00004259 }
anthony805a2d42011-09-25 08:25:12 +00004260 default:
anthonyebb73a22012-03-22 14:25:52 +00004261 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00004262 }
anthony31f1bf72012-01-30 12:37:22 +00004263 if (new_images == (Image *) NULL)
4264 return;
anthony805a2d42011-09-25 08:25:12 +00004265
anthony92c93bd2012-03-19 14:02:47 +00004266 if (_images != (Image *) NULL)
4267 _images=DestroyImageList(_images);
4268 _images=GetFirstImageInList(new_images);
anthony31f1bf72012-01-30 12:37:22 +00004269 return;
4270
anthony92c93bd2012-03-19 14:02:47 +00004271#undef _image_info
4272#undef _images
4273#undef _exception
4274#undef _draw_info
4275#undef _quantize_info
anthonyafa3dfc2012-03-03 11:31:30 +00004276#undef IfNormalOp
4277#undef IfPlusOp
anthony31f1bf72012-01-30 12:37:22 +00004278#undef normal_op
anthony805a2d42011-09-25 08:25:12 +00004279}
anthony43f425d2012-02-26 12:58:58 +00004280
4281/*
4282%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4283% %
4284% %
4285% %
4286+ C L I S p e c i a l O p e r a t i o n s %
4287% %
4288% %
4289% %
4290%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4291%
anthony756cd0d2012-04-08 12:41:44 +00004292% CLISpecialOperator() Applies operations that may not actually need images
4293% in an image list wen it is applied.
anthony43f425d2012-02-26 12:58:58 +00004294%
anthony756cd0d2012-04-08 12:41:44 +00004295% The classic operators of this type is -read, which actually creates images
4296% even when no images are present. Or image stack operators, which can be
4297% applied to empty image lists.
anthonyafa3dfc2012-03-03 11:31:30 +00004298%
4299% Note: unlike other Operators, these may involve other special 'option'
4300% character prefixes, other than simply '-' or '+'.
anthony43f425d2012-02-26 12:58:58 +00004301%
4302% The format of the CLISpecialOption method is:
4303%
4304% void CLISpecialOption(MagickCLI *cli_wand,const char *option,
anthony24aa8822012-03-11 00:56:06 +00004305% const char *arg1)
anthony43f425d2012-02-26 12:58:58 +00004306%
4307% A description of each parameter follows:
4308%
4309% o cli_wand: the main CLI Wand to use.
4310%
4311% o option: The special option (with any switch char) to process
4312%
anthony24aa8822012-03-11 00:56:06 +00004313% o arg1: Argument for option, if required
anthonyafa3dfc2012-03-03 11:31:30 +00004314%
anthony2052d272012-02-28 12:48:29 +00004315% Example Usage...
4316%
anthonyce8dcb32012-03-21 13:20:31 +00004317% CLISpecialOperator(cli_wand,"-read","rose:");
anthony2052d272012-02-28 12:48:29 +00004318%
anthony24aa8822012-03-11 00:56:06 +00004319% Or for handling command line arguments EG: +/-option ["arg1"]
anthony2052d272012-02-28 12:48:29 +00004320%
4321% cli_wand
4322% argc,argv
4323% i=index in argv
4324%
4325% option_info = GetCommandOptionInfo(argv[i]);
4326% count=option_info->type;
4327% option_type=option_info->flags;
4328%
4329% if ( (option_type & SpecialOptionFlag) != 0 )
4330% CLISpecialOperator(cli_wand,argv[i],
4331% count>=1 ? argv[i+1] : (char *)NULL);
4332% i += count+1;
anthony43f425d2012-02-26 12:58:58 +00004333%
4334*/
4335
anthony43f425d2012-02-26 12:58:58 +00004336WandExport void CLISpecialOperator(MagickCLI *cli_wand,
anthony24aa8822012-03-11 00:56:06 +00004337 const char *option, const char *arg1)
anthony43f425d2012-02-26 12:58:58 +00004338{
anthony8226e722012-04-05 14:25:46 +00004339#define _image_info (cli_wand->wand.image_info)
4340#define _images (cli_wand->wand.images)
4341#define _exception (cli_wand->wand.exception)
4342#define IfNormalOp (*option=='-')
4343#define IfPlusOp (*option!='-')
anthony43f425d2012-02-26 12:58:58 +00004344
4345 assert(cli_wand != (MagickCLI *) NULL);
4346 assert(cli_wand->signature == WandSignature);
4347 assert(cli_wand->wand.signature == WandSignature);
anthony7bcfe7f2012-03-30 14:01:22 +00004348 if (IfMagickTrue(cli_wand->wand.debug))
anthony43f425d2012-02-26 12:58:58 +00004349 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
4350
anthony8226e722012-04-05 14:25:46 +00004351 if(_images != (Image *)NULL)
4352 (void) SyncImagesSettings(cli_wand->wand.image_info,_images,_exception);
anthony24aa8822012-03-11 00:56:06 +00004353
anthony52bef752012-03-27 13:54:47 +00004354 /*
anthony756cd0d2012-04-08 12:41:44 +00004355 No-op options (ignore these)
anthony52bef752012-03-27 13:54:47 +00004356 */
anthony756cd0d2012-04-08 12:41:44 +00004357 if (LocaleCompare("noop",option+1) == 0) /* no argument */
anthony52bef752012-03-27 13:54:47 +00004358 return;
anthony756cd0d2012-04-08 12:41:44 +00004359 if (LocaleCompare("sans",option+1) == 0) /* one argument */
anthony52bef752012-03-27 13:54:47 +00004360 return;
anthony756cd0d2012-04-08 12:41:44 +00004361 if (LocaleCompare("sans0",option+1) == 0) /* no argument */
anthony52bef752012-03-27 13:54:47 +00004362 return;
anthony756cd0d2012-04-08 12:41:44 +00004363 if (LocaleCompare("sans2",option+1) == 0) /* two arguments */
anthony52bef752012-03-27 13:54:47 +00004364 return;
4365 /*
4366 Image Reading
4367 */
4368 if ( ( LocaleCompare("read",option+1) == 0 ) ||
anthony0ea037a2012-04-03 12:14:39 +00004369 ( LocaleCompare("--",option) == 0 ) ) {
4370 int
4371 argc;
4372 char
4373 **argv;
anthony52bef752012-03-27 13:54:47 +00004374
anthony0ea037a2012-04-03 12:14:39 +00004375 ssize_t
4376 i;
4377
4378 /* Expand the filename argument (meta-characters or "@filelist" ) */
4379 argc = 1;
cristye71f2942012-04-04 11:07:05 +00004380 argv = (char **) &arg1;
anthony0ea037a2012-04-03 12:14:39 +00004381 MagickBooleanType
4382 status=ExpandFilenames(&argc,&argv);
4383
4384 if (IfMagickFalse(status))
4385 CLIWandExceptArgReturn(ResourceLimitError,"MemoryAllocationFailed",
4386 option,GetExceptionMessage(errno));
4387
4388 /* loop over expanded list reading images */
4389 for (i=0; i<argc; i++) {
anthony52bef752012-03-27 13:54:47 +00004390#if !USE_WAND_METHODS
4391 Image *
4392 new_images;
anthony8226e722012-04-05 14:25:46 +00004393 if (IfMagickTrue(_image_info->ping))
4394 new_images=PingImages(_image_info,argv[i],_exception);
anthony52bef752012-03-27 13:54:47 +00004395 else
anthony8226e722012-04-05 14:25:46 +00004396 new_images=ReadImages(_image_info,argv[i],_exception);
4397 AppendImageToList(&_images, new_images);
anthony52bef752012-03-27 13:54:47 +00004398#else
4399 /* read images using MagickWand method - no ping */
4400 /* This is not working! - it locks up in a CPU loop! */
4401 MagickSetLastIterator(&cli_wand->wand);
4402 MagickReadImage(&cli_wand->wand,arg1);
4403 MagickSetFirstIterator(&cli_wand->wand);
4404#endif
anthony52bef752012-03-27 13:54:47 +00004405 }
anthony0ea037a2012-04-03 12:14:39 +00004406 /* FUTURE: how do I free the expanded filename arguments??? */
4407
4408 return;
4409 }
anthony52bef752012-03-27 13:54:47 +00004410 /*
anthony756cd0d2012-04-08 12:41:44 +00004411 Image Writing (no-images present is valid in specific cases)
anthony8226e722012-04-05 14:25:46 +00004412 */
4413 if (LocaleCompare("write",option+1) == 0) {
4414 char
4415 key[MaxTextExtent];
4416
4417 Image
4418 *write_images;
4419
4420 ImageInfo
4421 *write_info;
4422
4423 /* Need images, unless a "null:" output coder is used */
4424 if ( cli_wand->wand.images == (Image *) NULL ) {
4425 if ( LocaleCompare(option,"null:") == 0 )
4426 return;
4427 CLIWandExceptArgReturn(OptionError,"NoImagesForWrite",option,arg1);
4428 }
4429
4430 (void) FormatLocaleString(key,MaxTextExtent,"cache:%s",arg1);
4431 (void) DeleteImageRegistry(key);
4432 write_images=_images;
4433 if (IfPlusOp)
4434 write_images=CloneImageList(_images,_exception);
4435 write_info=CloneImageInfo(_image_info);
4436 (void) WriteImages(write_info,write_images,arg1,_exception);
4437 write_info=DestroyImageInfo(write_info);
4438 if (IfPlusOp)
4439 write_images=DestroyImageList(write_images);
4440 return;
4441 }
4442 /*
anthony52bef752012-03-27 13:54:47 +00004443 Parenthesis and Brace operations
4444 */
anthonyce8dcb32012-03-21 13:20:31 +00004445 if (LocaleCompare("(",option) == 0) {
anthony8226e722012-04-05 14:25:46 +00004446 /* stack 'push' images */
4447 Stack
4448 *node;
anthony43f425d2012-02-26 12:58:58 +00004449
anthony8226e722012-04-05 14:25:46 +00004450 size_t
4451 size;
anthony43f425d2012-02-26 12:58:58 +00004452
anthony8226e722012-04-05 14:25:46 +00004453 size=0;
4454 node=cli_wand->image_list_stack;
4455 for ( ; node != (Stack *)NULL; node=node->next)
4456 size++;
4457 if ( size >= MAX_STACK_DEPTH )
4458 CLIWandExceptionReturn(OptionError,"ParenthesisNestedTooDeeply",option);
4459 node=(Stack *) AcquireMagickMemory(sizeof(*node));
4460 if (node == (Stack *) NULL)
4461 CLIWandExceptionReturn(ResourceLimitFatalError,
4462 "MemoryAllocationFailed",option);
4463 node->data = (void *)cli_wand->wand.images;
4464 cli_wand->wand.images = NewImageList();
4465 node->next = cli_wand->image_list_stack;
4466 cli_wand->image_list_stack = node;
anthony43f425d2012-02-26 12:58:58 +00004467
anthony8226e722012-04-05 14:25:46 +00004468 /* handle respect-parenthesis */
4469 if (IfMagickTrue(IsStringTrue(GetImageOption(cli_wand->wand.image_info,
4470 "respect-parenthesis"))))
4471 option="{"; /* fall-thru so as to push image settings too */
4472 else
anthony43f425d2012-02-26 12:58:58 +00004473 return;
anthony8226e722012-04-05 14:25:46 +00004474 }
4475 if (LocaleCompare("{",option) == 0) {
4476 /* stack 'push' of image_info settings */
4477 Stack
4478 *node;
anthony43f425d2012-02-26 12:58:58 +00004479
anthony8226e722012-04-05 14:25:46 +00004480 size_t
4481 size;
anthony43f425d2012-02-26 12:58:58 +00004482
anthony8226e722012-04-05 14:25:46 +00004483 size=0;
4484 node=cli_wand->image_info_stack;
4485 for ( ; node != (Stack *)NULL; node=node->next)
4486 size++;
4487 if ( size >= MAX_STACK_DEPTH )
4488 CLIWandExceptionReturn(OptionError,"CurlyBracesNestedTooDeeply",option);
4489 node=(Stack *) AcquireMagickMemory(sizeof(*node));
4490 if (node == (Stack *) NULL)
4491 CLIWandExceptionReturn(ResourceLimitFatalError,
4492 "MemoryAllocationFailed",option);
anthony43f425d2012-02-26 12:58:58 +00004493
anthony8226e722012-04-05 14:25:46 +00004494 node->data = (void *)cli_wand->wand.image_info;
4495 cli_wand->wand.image_info = CloneImageInfo(cli_wand->wand.image_info);
4496 if (cli_wand->wand.image_info == (ImageInfo *)NULL) {
4497 CLIWandException(ResourceLimitFatalError,"MemoryAllocationFailed",
4498 option);
anthony43f425d2012-02-26 12:58:58 +00004499 cli_wand->wand.image_info = (ImageInfo *)node->data;
4500 node = (Stack *)RelinquishMagickMemory(node);
anthony43f425d2012-02-26 12:58:58 +00004501 return;
4502 }
anthony8226e722012-04-05 14:25:46 +00004503
4504 node->next = cli_wand->image_info_stack;
4505 cli_wand->image_info_stack = node;
4506
4507 return;
4508 }
4509 if (LocaleCompare(")",option) == 0) {
4510 /* pop images from stack */
4511 Stack
4512 *node;
4513
4514 node = (Stack *)cli_wand->image_list_stack;
4515 if ( node == (Stack *)NULL)
4516 CLIWandExceptionReturn(OptionError,"UnbalancedParenthesis",option);
4517 cli_wand->image_list_stack = node->next;
4518
4519 AppendImageToList((Image **)&node->data,cli_wand->wand.images);
4520 cli_wand->wand.images= (Image *)node->data;
4521 node = (Stack *)RelinquishMagickMemory(node);
4522
4523 /* handle respect-parenthesis - of the previous 'pushed' settings */
4524 node = cli_wand->image_info_stack;
4525 if ( node != (Stack *)NULL)
4526 {
4527 if (IfMagickTrue(IsStringTrue(GetImageOption(
4528 cli_wand->wand.image_info,"respect-parenthesis"))))
4529 option="}"; /* fall-thru so as to pop image settings too */
4530 else
4531 return;
4532 }
4533 else
4534 return;
4535 }
4536 if (LocaleCompare("}",option) == 0) {
4537 /* pop image_info settings from stack */
4538 Stack
4539 *node;
4540
4541 node = (Stack *)cli_wand->image_info_stack;
4542 if ( node == (Stack *)NULL)
4543 CLIWandExceptionReturn(OptionError,"UnbalancedCurlyBraces",option);
4544 cli_wand->image_info_stack = node->next;
4545
4546 (void) DestroyImageInfo(cli_wand->wand.image_info);
4547 cli_wand->wand.image_info = (ImageInfo *)node->data;
4548 node = (Stack *)RelinquishMagickMemory(node);
4549
4550 GetDrawInfo(cli_wand->wand.image_info, cli_wand->draw_info);
4551 cli_wand->quantize_info=DestroyQuantizeInfo(cli_wand->quantize_info);
4552 cli_wand->quantize_info=AcquireQuantizeInfo(cli_wand->wand.image_info);
4553
4554 return;
4555 }
anthonyce8dcb32012-03-21 13:20:31 +00004556 if (LocaleCompare("clone",option+1) == 0) {
anthony43f425d2012-02-26 12:58:58 +00004557 Image
4558 *new_images;
4559
4560 if (*option == '+')
anthony24aa8822012-03-11 00:56:06 +00004561 arg1="-1";
anthony7bcfe7f2012-03-30 14:01:22 +00004562 if (IfMagickFalse(IsSceneGeometry(arg1,MagickFalse)))
anthony92c93bd2012-03-19 14:02:47 +00004563 CLIWandExceptionReturn(OptionError,"InvalidArgument",option);
anthony43f425d2012-02-26 12:58:58 +00004564 if ( cli_wand->image_list_stack == (Stack *)NULL)
anthony92c93bd2012-03-19 14:02:47 +00004565 CLIWandExceptionReturn(OptionError,"UnableToCloneImage",option);
anthony43f425d2012-02-26 12:58:58 +00004566 new_images = (Image *)cli_wand->image_list_stack->data;
4567 if (new_images == (Image *) NULL)
anthony92c93bd2012-03-19 14:02:47 +00004568 CLIWandExceptionReturn(OptionError,"UnableToCloneImage",option);
4569 new_images=CloneImages(new_images,arg1,_exception);
anthony43f425d2012-02-26 12:58:58 +00004570 if (new_images == (Image *) NULL)
anthony92c93bd2012-03-19 14:02:47 +00004571 CLIWandExceptionReturn(OptionError,"NoSuchImage",option);
anthony8226e722012-04-05 14:25:46 +00004572 AppendImageToList(&_images,new_images);
anthony43f425d2012-02-26 12:58:58 +00004573 return;
4574 }
anthony52bef752012-03-27 13:54:47 +00004575 /*
4576 Informational Operations
4577 */
anthony0ea037a2012-04-03 12:14:39 +00004578 if (LocaleCompare("version",option+1) == 0) {
anthony8226e722012-04-05 14:25:46 +00004579 (void) FormatLocaleFile(stdout,"Version: %s\n",
4580 GetMagickVersion((size_t *) NULL));
4581 (void) FormatLocaleFile(stdout,"Copyright: %s\n",
4582 GetMagickCopyright());
4583 (void) FormatLocaleFile(stdout,"Features: %s\n\n",
4584 GetMagickFeatures());
4585 return;
4586 }
anthonyce8dcb32012-03-21 13:20:31 +00004587 if (LocaleCompare("list",option+1) == 0) {
anthony8226e722012-04-05 14:25:46 +00004588 /* FUTURE: This should really be built into the MagickCore
4589 It does not actually require a cli-wand or and images!
4590 */
4591 ssize_t
4592 list;
anthony43f425d2012-02-26 12:58:58 +00004593
anthony8226e722012-04-05 14:25:46 +00004594 list=ParseCommandOption(MagickListOptions,MagickFalse,arg1);
4595 if ( list < 0 ) {
4596 CLIWandExceptionArg(OptionError,"UnrecognizedListType",option,arg1);
anthony43f425d2012-02-26 12:58:58 +00004597 return;
4598 }
anthony8226e722012-04-05 14:25:46 +00004599 switch (list)
4600 {
4601 case MagickCoderOptions:
4602 {
4603 (void) ListCoderInfo((FILE *) NULL,_exception);
4604 break;
4605 }
4606 case MagickColorOptions:
4607 {
4608 (void) ListColorInfo((FILE *) NULL,_exception);
4609 break;
4610 }
4611 case MagickConfigureOptions:
4612 {
4613 (void) ListConfigureInfo((FILE *) NULL,_exception);
4614 break;
4615 }
4616 case MagickDelegateOptions:
4617 {
4618 (void) ListDelegateInfo((FILE *) NULL,_exception);
4619 break;
4620 }
4621 case MagickFontOptions:
4622 {
4623 (void) ListTypeInfo((FILE *) NULL,_exception);
4624 break;
4625 }
4626 case MagickFormatOptions:
4627 (void) ListMagickInfo((FILE *) NULL,_exception);
4628 break;
4629 case MagickLocaleOptions:
4630 (void) ListLocaleInfo((FILE *) NULL,_exception);
4631 break;
4632 case MagickLogOptions:
4633 (void) ListLogInfo((FILE *) NULL,_exception);
4634 break;
4635 case MagickMagicOptions:
4636 (void) ListMagicInfo((FILE *) NULL,_exception);
4637 break;
4638 case MagickMimeOptions:
4639 (void) ListMimeInfo((FILE *) NULL,_exception);
4640 break;
4641 case MagickModuleOptions:
4642 (void) ListModuleInfo((FILE *) NULL,_exception);
4643 break;
4644 case MagickPolicyOptions:
4645 (void) ListPolicyInfo((FILE *) NULL,_exception);
4646 break;
4647 case MagickResourceOptions:
4648 (void) ListMagickResourceInfo((FILE *) NULL,_exception);
4649 break;
4650 case MagickThresholdOptions:
4651 (void) ListThresholdMaps((FILE *) NULL,_exception);
4652 break;
4653 default:
4654 (void) ListCommandOptions((FILE *) NULL,(CommandOption) list,
4655 _exception);
4656 break;
4657 }
4658 return;
4659 }
anthony43f425d2012-02-26 12:58:58 +00004660
4661#if 0
anthony43f425d2012-02-26 12:58:58 +00004662 // Other 'special' options this should handle
anthony8226e722012-04-05 14:25:46 +00004663 // "region"
anthony43f425d2012-02-26 12:58:58 +00004664 if ( ( process_flags & ProcessUnknownOptionError ) != 0 )
anthony43f425d2012-02-26 12:58:58 +00004665#endif
anthonyebb73a22012-03-22 14:25:52 +00004666 CLIWandException(OptionError,"UnrecognizedOption",option);
anthony43f425d2012-02-26 12:58:58 +00004667
anthony8226e722012-04-05 14:25:46 +00004668#undef _image_info
4669#undef _images
anthony92c93bd2012-03-19 14:02:47 +00004670#undef _exception
anthony8226e722012-04-05 14:25:46 +00004671#undef IfNormalOp
4672#undef IfPlusOp
anthony43f425d2012-02-26 12:58:58 +00004673}