blob: 5488e8b2d9d9dfd2dc3077c82732bf92c0b5e58f [file] [log] [blame]
anthony805a2d42011-09-25 08:25:12 +00001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% %
anthony8b10b462012-02-08 12:32:44 +00006% OOO PPPP EEEE RRRR AA TTTTT III OOO N N %
7% O O P P E R R A A T I O O NN N %
8% O O PPPP EEE RRRR AAAA T I O O N N N %
9% O O P E R R A A T I O O N NN %
10% OOO P EEEE R RR A A T III OOO N N %
anthony805a2d42011-09-25 08:25:12 +000011% %
12% %
anthony8b10b462012-02-08 12:32:44 +000013% CLI Magick Option Methods %
anthony805a2d42011-09-25 08:25:12 +000014% %
anthony8b10b462012-02-08 12:32:44 +000015% Dragon Computing %
cristy9e58efd2012-01-30 14:27:34 +000016% Anthony Thyssen %
cristy0a0ca4f2011-09-28 01:15:28 +000017% September 2011 %
anthony805a2d42011-09-25 08:25:12 +000018% %
19% %
cristy1454be72011-12-19 01:52:48 +000020% Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization %
anthony805a2d42011-09-25 08:25:12 +000021% dedicated to making software imaging solutions freely available. %
22% %
23% You may not use this file except in compliance with the License. You may %
24% obtain a copy of the License at %
25% %
26% http://www.imagemagick.org/script/license.php %
27% %
28% Unless required by applicable law or agreed to in writing, software %
29% distributed under the License is distributed on an "AS IS" BASIS, %
30% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31% See the License for the specific language governing permissions and %
32% limitations under the License. %
33% %
34%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35%
36% Apply the given options (settings, and simple, or sequence operations) to
anthony8b10b462012-02-08 12:32:44 +000037% the given image(s) according to the current "image_info", "draw_info", and
38% "quantize_info" settings, stored in a special CLI Image Wand.
anthony805a2d42011-09-25 08:25:12 +000039%
40% The final goal is to allow the execution in a strict one option at a time
41% manner that is needed for 'pipelining and file scripting' of options in
42% IMv7.
43%
anthony8b10b462012-02-08 12:32:44 +000044% Anthony Thyssen, September 2011
anthony805a2d42011-09-25 08:25:12 +000045*/
46
47/*
48 Include declarations.
49*/
50#include "MagickWand/studio.h"
51#include "MagickWand/MagickWand.h"
anthony72feaa62012-01-17 06:46:23 +000052#include "MagickWand/magick-wand-private.h"
anthony43f425d2012-02-26 12:58:58 +000053#include "MagickWand/wand.h"
anthony756cd0d2012-04-08 12:41:44 +000054#include "MagickWand/wandcli.h"
55#include "MagickWand/wandcli-private.h"
56#include "MagickWand/operation.h"
anthony805a2d42011-09-25 08:25:12 +000057#include "MagickCore/monitor-private.h"
58#include "MagickCore/thread-private.h"
59#include "MagickCore/string-private.h"
60
61/*
62 Define declarations.
63*/
anthonyafa3dfc2012-03-03 11:31:30 +000064#define USE_WAND_METHODS 0
65#define MAX_STACK_DEPTH 32
66#define UNDEFINED_COMPRESSION_QUALITY 0UL
67
anthonyb1d483a2012-04-14 12:53:56 +000068/* FUTURE: why is this default so specific? */
69#define DEFAULT_DISSIMILARITY_THRESHOLD "0.31830988618379067154"
70
anthony805a2d42011-09-25 08:25:12 +000071/*
72 Constant declaration. (temporary exports)
73*/
74static const char
75 BackgroundColor[] = "#fff", /* white */
anthony72feaa62012-01-17 06:46:23 +000076 BorderColor[] = "#dfdfdf", /* sRGB gray */
77 MatteColor[] = "#bdbdbd"; /* slightly darker gray */
anthony22de2722012-04-19 14:43:00 +000078
79/* For Debugging Geometry Input */
80#define ReportGeometry(flags,info) \
81 (void) FormatLocaleFile(stderr, "Geometry = 0x%04X : %lg x %lg %+lg %+lg\n", \
82 flags, info.rho, info.sigma, info.xi, info.psi )
anthony805a2d42011-09-25 08:25:12 +000083
84/*
85** Function to report on the progress of image operations
86*/
87static MagickBooleanType MonitorProgress(const char *text,
88 const MagickOffsetType offset,const MagickSizeType extent,
anthony43f425d2012-02-26 12:58:58 +000089 void *wand_unused(cli_wandent_data))
anthony805a2d42011-09-25 08:25:12 +000090{
91 char
92 message[MaxTextExtent],
93 tag[MaxTextExtent];
94
95 const char
96 *locale_message;
97
98 register char
99 *p;
100
101 if (extent < 2)
102 return(MagickTrue);
103 (void) CopyMagickMemory(tag,text,MaxTextExtent);
104 p=strrchr(tag,'/');
105 if (p != (char *) NULL)
106 *p='\0';
107 (void) FormatLocaleString(message,MaxTextExtent,"Monitor/%s",tag);
108 locale_message=GetLocaleMessage(message);
109 if (locale_message == message)
110 locale_message=tag;
111 if (p == (char *) NULL)
112 (void) FormatLocaleFile(stderr,"%s: %ld of %lu, %02ld%% complete\r",
113 locale_message,(long) offset,(unsigned long) extent,(long)
114 (100L*offset/(extent-1)));
115 else
116 (void) FormatLocaleFile(stderr,"%s[%s]: %ld of %lu, %02ld%% complete\r",
117 locale_message,p+1,(long) offset,(unsigned long) extent,(long)
118 (100L*offset/(extent-1)));
119 if (offset == (MagickOffsetType) (extent-1))
120 (void) FormatLocaleFile(stderr,"\n");
121 (void) fflush(stderr);
122 return(MagickTrue);
123}
124
125/*
126** GetImageCache() will read an image into a image cache if not already
127** present then return the image that is in the cache under that filename.
128*/
129static inline Image *GetImageCache(const ImageInfo *image_info,const char *path,
130 ExceptionInfo *exception)
131{
132 char
133 key[MaxTextExtent];
134
135 ExceptionInfo
136 *sans_exception;
137
138 Image
139 *image;
140
141 ImageInfo
142 *read_info;
143
144 (void) FormatLocaleString(key,MaxTextExtent,"cache:%s",path);
145 sans_exception=AcquireExceptionInfo();
146 image=(Image *) GetImageRegistry(ImageRegistryType,key,sans_exception);
147 sans_exception=DestroyExceptionInfo(sans_exception);
148 if (image != (Image *) NULL)
149 return(image);
150 read_info=CloneImageInfo(image_info);
151 (void) CopyMagickString(read_info->filename,path,MaxTextExtent);
152 image=ReadImage(read_info,exception);
153 read_info=DestroyImageInfo(read_info);
154 if (image != (Image *) NULL)
155 (void) SetImageRegistry(ImageRegistryType,key,image,exception);
156 return(image);
157}
158
anthony756cd0d2012-04-08 12:41:44 +0000159/*
anthonya89dd172011-10-04 13:29:35 +0000160 SparseColorOption() parse the complex -sparse-color argument into an
161 an array of floating point values than call SparseColorImage().
162 Argument is a complex mix of floating-point pixel coodinates, and color
163 specifications (or direct floating point numbers). The number of floats
164 needed to represent a color varies depending on teh current channel
165 setting.
anthony43f425d2012-02-26 12:58:58 +0000166
167 This really should be in MagickCore, so that other API's can make use of it.
anthony805a2d42011-09-25 08:25:12 +0000168*/
169static Image *SparseColorOption(const Image *image,
170 const SparseColorMethod method,const char *arguments,
anthony31f1bf72012-01-30 12:37:22 +0000171 ExceptionInfo *exception)
anthony805a2d42011-09-25 08:25:12 +0000172{
173 char
174 token[MaxTextExtent];
175
176 const char
177 *p;
178
179 double
180 *sparse_arguments;
181
182 Image
183 *sparse_image;
184
185 PixelInfo
186 color;
187
188 MagickBooleanType
189 error;
190
191 register size_t
192 x;
193
194 size_t
195 number_arguments,
196 number_colors;
197
198 assert(image != (Image *) NULL);
199 assert(image->signature == MagickSignature);
anthony7bcfe7f2012-03-30 14:01:22 +0000200 if (IfMagickTrue(image->debug))
anthony805a2d42011-09-25 08:25:12 +0000201 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
202 assert(exception != (ExceptionInfo *) NULL);
203 assert(exception->signature == MagickSignature);
204 /*
anthonyb1d483a2012-04-14 12:53:56 +0000205 Limit channels according to image
206 add up number of values needed per color.
anthony805a2d42011-09-25 08:25:12 +0000207 */
208 number_colors=0;
209 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
210 number_colors++;
211 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
212 number_colors++;
213 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
214 number_colors++;
215 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
216 (image->colorspace == CMYKColorspace))
217 number_colors++;
218 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
anthony7bcfe7f2012-03-30 14:01:22 +0000219 IfMagickTrue(image->matte))
anthony805a2d42011-09-25 08:25:12 +0000220 number_colors++;
221
222 /*
223 Read string, to determine number of arguments needed,
224 */
225 p=arguments;
226 x=0;
227 while( *p != '\0' )
228 {
229 GetMagickToken(p,&p,token);
230 if ( token[0] == ',' ) continue;
anthony31f1bf72012-01-30 12:37:22 +0000231 if ( isalpha((int) token[0]) || token[0] == '#' )
232 x += number_colors; /* color argument found */
anthonyce8dcb32012-03-21 13:20:31 +0000233 else
anthony805a2d42011-09-25 08:25:12 +0000234 x++; /* floating point argument */
anthony805a2d42011-09-25 08:25:12 +0000235 }
anthony31f1bf72012-01-30 12:37:22 +0000236 /* control points and color values */
anthony7bcfe7f2012-03-30 14:01:22 +0000237 error = IsMagickTrue( x % (2+number_colors) );
anthony31f1bf72012-01-30 12:37:22 +0000238 number_arguments=x;
anthony7bcfe7f2012-03-30 14:01:22 +0000239 if ( IfMagickTrue(error) ) {
anthony805a2d42011-09-25 08:25:12 +0000240 (void) ThrowMagickException(exception,GetMagickModule(),
anthony43f425d2012-02-26 12:58:58 +0000241 OptionError, "InvalidArgument", "'%s': %s", "sparse-color",
anthony805a2d42011-09-25 08:25:12 +0000242 "Invalid number of Arguments");
243 return( (Image *)NULL);
244 }
245
246 /* Allocate and fill in the floating point arguments */
247 sparse_arguments=(double *) AcquireQuantumMemory(number_arguments,
248 sizeof(*sparse_arguments));
249 if (sparse_arguments == (double *) NULL) {
250 (void) ThrowMagickException(exception,GetMagickModule(),ResourceLimitError,
251 "MemoryAllocationFailed","%s","SparseColorOption");
252 return( (Image *)NULL);
253 }
254 (void) ResetMagickMemory(sparse_arguments,0,number_arguments*
255 sizeof(*sparse_arguments));
256 p=arguments;
257 x=0;
258 while( *p != '\0' && x < number_arguments ) {
259 /* X coordinate */
260 token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token);
261 if ( token[0] == '\0' ) break;
262 if ( isalpha((int) token[0]) || token[0] == '#' ) {
263 (void) ThrowMagickException(exception,GetMagickModule(),
anthony43f425d2012-02-26 12:58:58 +0000264 OptionError, "InvalidArgument", "'%s': %s", "sparse-color",
anthony805a2d42011-09-25 08:25:12 +0000265 "Color found, instead of X-coord");
266 error = MagickTrue;
267 break;
268 }
cristydbdd0e32011-11-04 23:29:40 +0000269 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +0000270 /* Y coordinate */
271 token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token);
272 if ( token[0] == '\0' ) break;
273 if ( isalpha((int) token[0]) || token[0] == '#' ) {
274 (void) ThrowMagickException(exception,GetMagickModule(),
anthony43f425d2012-02-26 12:58:58 +0000275 OptionError, "InvalidArgument", "'%s': %s", "sparse-color",
anthony805a2d42011-09-25 08:25:12 +0000276 "Color found, instead of Y-coord");
277 error = MagickTrue;
278 break;
279 }
cristydbdd0e32011-11-04 23:29:40 +0000280 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
anthony31f1bf72012-01-30 12:37:22 +0000281 /* color name or function given in string argument */
282 token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token);
283 if ( token[0] == '\0' ) break;
284 if ( isalpha((int) token[0]) || token[0] == '#' ) {
285 /* Color string given */
286 (void) QueryColorCompliance(token,AllCompliance,&color,
287 exception);
288 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
289 sparse_arguments[x++] = QuantumScale*color.red;
290 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
291 sparse_arguments[x++] = QuantumScale*color.green;
292 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
293 sparse_arguments[x++] = QuantumScale*color.blue;
294 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
295 (image->colorspace == CMYKColorspace))
296 sparse_arguments[x++] = QuantumScale*color.black;
297 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
anthony7bcfe7f2012-03-30 14:01:22 +0000298 IfMagickTrue(image->matte))
anthony31f1bf72012-01-30 12:37:22 +0000299 sparse_arguments[x++] = QuantumScale*color.alpha;
anthony805a2d42011-09-25 08:25:12 +0000300 }
anthony31f1bf72012-01-30 12:37:22 +0000301 else {
302 /* Colors given as a set of floating point values - experimental */
303 /* NB: token contains the first floating point value to use! */
304 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
305 {
306 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
307 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
308 break;
309 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
310 token[0] = ','; /* used this token - get another */
anthony805a2d42011-09-25 08:25:12 +0000311 }
anthony31f1bf72012-01-30 12:37:22 +0000312 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
313 {
314 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
315 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
316 break;
317 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
318 token[0] = ','; /* used this token - get another */
319 }
320 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
321 {
322 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
323 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
324 break;
325 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
326 token[0] = ','; /* used this token - get another */
327 }
328 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
329 (image->colorspace == CMYKColorspace))
330 {
331 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
332 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
333 break;
334 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
335 token[0] = ','; /* used this token - get another */
336 }
337 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
anthony7bcfe7f2012-03-30 14:01:22 +0000338 IfMagickTrue(image->matte))
anthony31f1bf72012-01-30 12:37:22 +0000339 {
340 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
341 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
342 break;
343 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
344 token[0] = ','; /* used this token - get another */
anthony805a2d42011-09-25 08:25:12 +0000345 }
346 }
347 }
348 if ( number_arguments != x && !error ) {
349 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
anthony43f425d2012-02-26 12:58:58 +0000350 "InvalidArgument","'%s': %s","sparse-color","Argument Parsing Error");
anthony805a2d42011-09-25 08:25:12 +0000351 sparse_arguments=(double *) RelinquishMagickMemory(sparse_arguments);
352 return( (Image *)NULL);
353 }
354 if ( error )
355 return( (Image *)NULL);
356
anthony31f1bf72012-01-30 12:37:22 +0000357 /* Call the Sparse Color Interpolation function with the parsed arguments */
anthony805a2d42011-09-25 08:25:12 +0000358 sparse_image=SparseColorImage(image,method,number_arguments,sparse_arguments,
359 exception);
360 sparse_arguments=(double *) RelinquishMagickMemory(sparse_arguments);
361 return( sparse_image );
362}
363
364/*
365%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
366% %
367% %
368% %
anthony43f425d2012-02-26 12:58:58 +0000369+ C L I S e t t i n g O p t i o n I n f o %
370% %
371% %
372% %
373%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
374%
375% CLISettingOptionInfo() applies a single settings option into a CLI wand
376% holding the image_info, draw_info, quantize_info structures that will be
377% used when processing the images.
378%
379% These options do no require images to be present in the CLI wand for them
380% to be able to be set, in which case they will generally be applied to image
381% that are read in later
anthony80c37752012-01-16 01:03:11 +0000382%
383% Options handled by this function are listed in CommandOptions[] of
anthonyfd706f92012-01-19 04:22:02 +0000384% "option.c" that is one of "SettingOptionFlags" option flags.
anthony805a2d42011-09-25 08:25:12 +0000385%
anthony2052d272012-02-28 12:48:29 +0000386% The format of the CLISettingOptionInfo method is:
anthony1afdc7a2011-10-05 11:54:28 +0000387%
anthonyafa3dfc2012-03-03 11:31:30 +0000388% void CLISettingOptionInfo(MagickCLI *cli_wand,
anthonye5fcd362012-04-09 04:02:09 +0000389% const char *option, const char *arg1, const char *arg2)
anthony805a2d42011-09-25 08:25:12 +0000390%
391% A description of each parameter follows:
392%
anthony43f425d2012-02-26 12:58:58 +0000393% o cli_wand: structure holding settings to be applied
anthony805a2d42011-09-25 08:25:12 +0000394%
anthonydcf510d2011-10-30 13:51:40 +0000395% o option: The option string to be set
anthony805a2d42011-09-25 08:25:12 +0000396%
anthonye5fcd362012-04-09 04:02:09 +0000397% o arg1, arg2: optional argument strings to the operation
398% arg2 is currently only used by "-limit"
anthonydcf510d2011-10-30 13:51:40 +0000399%
anthony72feaa62012-01-17 06:46:23 +0000400% Example usage...
401%
anthonye5fcd362012-04-09 04:02:09 +0000402% CLISettingOptionInfo(cli_wand, "-background", "Red", NULL); // set value
403% CLISettingOptionInfo(cli_wand, "-adjoin", NULL, NULL); // set boolean
404% CLISettingOptionInfo(cli_wand, "+adjoin", NULL, NULL); // unset
anthony72feaa62012-01-17 06:46:23 +0000405%
anthony24aa8822012-03-11 00:56:06 +0000406% Or for handling command line arguments EG: +/-option ["arg1"]
anthonydcf510d2011-10-30 13:51:40 +0000407%
408% argc,argv
409% i=index in argv
410%
anthony2052d272012-02-28 12:48:29 +0000411% option_info = GetCommandOptionInfo(argv[i]);
412% count=option_info->type;
413% option_type=option_info->flags;
414%
415% if ( (option_type & SettingOperatorOptionFlags) != 0 )
anthonyafa3dfc2012-03-03 11:31:30 +0000416% CLISettingOptionInfo(cli_wand, argv[i],
anthonye5fcd362012-04-09 04:02:09 +0000417% (count>=1) ? argv[i+1] : (char *)NULL,
418% (count>=2) ? argv[i+2] : (char *)NULL);
anthonydcf510d2011-10-30 13:51:40 +0000419% i += count+1;
420%
anthony805a2d42011-09-25 08:25:12 +0000421*/
anthonyafa3dfc2012-03-03 11:31:30 +0000422WandExport void CLISettingOptionInfo(MagickCLI *cli_wand,
anthonye5fcd362012-04-09 04:02:09 +0000423 const char *option,const char *arg1, const char *arg2)
anthony805a2d42011-09-25 08:25:12 +0000424{
anthony30b912a2012-03-22 01:20:28 +0000425 ssize_t
426 parse; /* option argument parsing (string to value table lookup) */
427
anthony43f425d2012-02-26 12:58:58 +0000428 assert(cli_wand != (MagickCLI *) NULL);
429 assert(cli_wand->signature == WandSignature);
430 assert(cli_wand->wand.signature == WandSignature);
anthony7bcfe7f2012-03-30 14:01:22 +0000431 if (IfMagickTrue(cli_wand->wand.debug))
anthony43f425d2012-02-26 12:58:58 +0000432 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
anthony1afdc7a2011-10-05 11:54:28 +0000433
anthony2e4501b2012-03-30 04:41:54 +0000434#define _image_info (cli_wand->wand.image_info)
435#define _exception (cli_wand->wand.exception)
436#define _draw_info (cli_wand->draw_info)
437#define _quantize_info (cli_wand->quantize_info)
anthony24aa8822012-03-11 00:56:06 +0000438#define IfSetOption (*option=='-')
anthony7bcfe7f2012-03-30 14:01:22 +0000439#define ArgBoolean IsMagickTrue(IfSetOption)
440#define ArgBooleanNot IsMagickFalse(IfSetOption)
anthony24aa8822012-03-11 00:56:06 +0000441#define ArgBooleanString (IfSetOption?"true":"false")
442#define ArgOption(def) (IfSetOption?arg1:(const char *)(def))
anthony74b1cfc2011-10-06 12:44:16 +0000443
anthonyafa3dfc2012-03-03 11:31:30 +0000444 switch (*(option+1))
anthony805a2d42011-09-25 08:25:12 +0000445 {
446 case 'a':
447 {
anthonyafa3dfc2012-03-03 11:31:30 +0000448 if (LocaleCompare("adjoin",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000449 {
anthony92c93bd2012-03-19 14:02:47 +0000450 _image_info->adjoin = ArgBoolean;
anthony805a2d42011-09-25 08:25:12 +0000451 break;
452 }
anthonyafa3dfc2012-03-03 11:31:30 +0000453 if (LocaleCompare("affine",option+1) == 0)
anthony1afdc7a2011-10-05 11:54:28 +0000454 {
anthony975a8d72012-04-12 13:54:36 +0000455 CLIWandWarnDepreciated("-draw 'affine ...'");
anthony74b1cfc2011-10-06 12:44:16 +0000456 if (IfSetOption)
anthony92c93bd2012-03-19 14:02:47 +0000457 (void) ParseAffineGeometry(arg1,&_draw_info->affine,_exception);
anthony74b1cfc2011-10-06 12:44:16 +0000458 else
anthony92c93bd2012-03-19 14:02:47 +0000459 GetAffineMatrix(&_draw_info->affine);
anthony1afdc7a2011-10-05 11:54:28 +0000460 break;
461 }
anthonyafa3dfc2012-03-03 11:31:30 +0000462 if (LocaleCompare("antialias",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000463 {
anthony92c93bd2012-03-19 14:02:47 +0000464 _image_info->antialias =
465 _draw_info->stroke_antialias =
466 _draw_info->text_antialias = ArgBoolean;
anthony805a2d42011-09-25 08:25:12 +0000467 break;
468 }
anthony31f1bf72012-01-30 12:37:22 +0000469 if (LocaleCompare("attenuate",option+1) == 0)
470 {
anthony7bcfe7f2012-03-30 14:01:22 +0000471 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthony92c93bd2012-03-19 14:02:47 +0000472 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
473 (void) SetImageOption(_image_info,option+1,ArgOption("1.0"));
anthony31f1bf72012-01-30 12:37:22 +0000474 break;
475 }
anthonyafa3dfc2012-03-03 11:31:30 +0000476 if (LocaleCompare("authenticate",option+1) == 0)
anthonydcf510d2011-10-30 13:51:40 +0000477 {
anthony92c93bd2012-03-19 14:02:47 +0000478 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +0000479 break;
480 }
anthonyebb73a22012-03-22 14:25:52 +0000481 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +0000482 }
483 case 'b':
484 {
anthonyafa3dfc2012-03-03 11:31:30 +0000485 if (LocaleCompare("background",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000486 {
anthony92c93bd2012-03-19 14:02:47 +0000487 /* FUTURE: both _image_info attribute & ImageOption in use!
488 _image_info only used directly for generating new images.
anthony72feaa62012-01-17 06:46:23 +0000489 SyncImageSettings() used to set per-image attribute.
490
anthony92c93bd2012-03-19 14:02:47 +0000491 FUTURE: if _image_info->background_color is not set then
anthony30b912a2012-03-22 01:20:28 +0000492 we should fall back to per-image background_color
493
494 At this time -background will 'wipe out' the per-image
495 background color!
496
497 Better error handling of QueryColorCompliance() needed.
anthony74b1cfc2011-10-06 12:44:16 +0000498 */
anthony92c93bd2012-03-19 14:02:47 +0000499 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony72feaa62012-01-17 06:46:23 +0000500 (void) QueryColorCompliance(ArgOption(BackgroundColor),AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +0000501 &_image_info->background_color,_exception);
anthony805a2d42011-09-25 08:25:12 +0000502 break;
503 }
anthonyafa3dfc2012-03-03 11:31:30 +0000504 if (LocaleCompare("bias",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000505 {
anthony52bef752012-03-27 13:54:47 +0000506 /* FUTURE: bias OBSOLETED, replaced by Artifact "convolve:bias"
anthony31f1bf72012-01-30 12:37:22 +0000507 as it is actually rarely used except in direct convolve operations
508 Usage outside a direct convolve operation is actally non-sensible!
anthony72feaa62012-01-17 06:46:23 +0000509
510 SyncImageSettings() used to set per-image attribute.
anthony74b1cfc2011-10-06 12:44:16 +0000511 */
anthony7bcfe7f2012-03-30 14:01:22 +0000512 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthony5330ae02012-03-20 14:17:01 +0000513 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyf46d4262012-03-26 03:30:34 +0000514 (void) SetImageOption(_image_info,"convolve:bias",ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +0000515 break;
516 }
anthonyafa3dfc2012-03-03 11:31:30 +0000517 if (LocaleCompare("black-point-compensation",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000518 {
anthony72feaa62012-01-17 06:46:23 +0000519 /* Used as a image chromaticity setting
520 SyncImageSettings() used to set per-image attribute.
521 */
anthony92c93bd2012-03-19 14:02:47 +0000522 (void) SetImageOption(_image_info,option+1,ArgBooleanString);
anthony805a2d42011-09-25 08:25:12 +0000523 break;
524 }
anthonyafa3dfc2012-03-03 11:31:30 +0000525 if (LocaleCompare("blue-primary",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000526 {
anthonyafbaed72011-10-26 12:05:04 +0000527 /* Image chromaticity X,Y NB: Y=X if Y not defined
528 Used by many coders including PNG
anthony72feaa62012-01-17 06:46:23 +0000529 SyncImageSettings() used to set per-image attribute.
anthonyafbaed72011-10-26 12:05:04 +0000530 */
anthonyf42014d2012-03-25 09:53:06 +0000531 arg1=ArgOption("0.0");
anthony7bcfe7f2012-03-30 14:01:22 +0000532 if (IfMagickFalse(IsGeometry(arg1)))
anthony5330ae02012-03-20 14:17:01 +0000533 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyf42014d2012-03-25 09:53:06 +0000534 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000535 break;
536 }
anthonyafa3dfc2012-03-03 11:31:30 +0000537 if (LocaleCompare("bordercolor",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000538 {
anthony92c93bd2012-03-19 14:02:47 +0000539 /* FUTURE: both _image_info attribute & ImageOption in use!
anthony72feaa62012-01-17 06:46:23 +0000540 SyncImageSettings() used to set per-image attribute.
anthony30b912a2012-03-22 01:20:28 +0000541 Better error checking of QueryColorCompliance().
anthony72feaa62012-01-17 06:46:23 +0000542 */
anthony74b1cfc2011-10-06 12:44:16 +0000543 if (IfSetOption)
anthony805a2d42011-09-25 08:25:12 +0000544 {
anthony92c93bd2012-03-19 14:02:47 +0000545 (void) SetImageOption(_image_info,option+1,arg1);
anthony24aa8822012-03-11 00:56:06 +0000546 (void) QueryColorCompliance(arg1,AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +0000547 &_image_info->border_color,_exception);
anthony24aa8822012-03-11 00:56:06 +0000548 (void) QueryColorCompliance(arg1,AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +0000549 &_draw_info->border_color,_exception);
anthony805a2d42011-09-25 08:25:12 +0000550 break;
551 }
anthony92c93bd2012-03-19 14:02:47 +0000552 (void) DeleteImageOption(_image_info,option+1);
anthony74b1cfc2011-10-06 12:44:16 +0000553 (void) QueryColorCompliance(BorderColor,AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +0000554 &_image_info->border_color,_exception);
anthony74b1cfc2011-10-06 12:44:16 +0000555 (void) QueryColorCompliance(BorderColor,AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +0000556 &_draw_info->border_color,_exception);
anthony805a2d42011-09-25 08:25:12 +0000557 break;
558 }
anthonyafa3dfc2012-03-03 11:31:30 +0000559 if (LocaleCompare("box",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000560 {
anthony975a8d72012-04-12 13:54:36 +0000561 CLIWandWarnDepreciated("-undercolor");
562 CLISettingOptionInfo(cli_wand,"-undercolor",arg1, arg2);
anthonyfd706f92012-01-19 04:22:02 +0000563 break;
anthony805a2d42011-09-25 08:25:12 +0000564 }
anthonyebb73a22012-03-22 14:25:52 +0000565 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +0000566 }
567 case 'c':
568 {
anthonyafa3dfc2012-03-03 11:31:30 +0000569 if (LocaleCompare("cache",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000570 {
571 MagickSizeType
572 limit;
573
anthony7bcfe7f2012-03-30 14:01:22 +0000574 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthony5330ae02012-03-20 14:17:01 +0000575 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +0000576 limit=MagickResourceInfinity;
anthony24aa8822012-03-11 00:56:06 +0000577 if (LocaleCompare("unlimited",arg1) != 0)
578 limit=(MagickSizeType) SiPrefixToDoubleInterval(arg1,100.0);
anthony805a2d42011-09-25 08:25:12 +0000579 (void) SetMagickResourceLimit(MemoryResource,limit);
580 (void) SetMagickResourceLimit(MapResource,2*limit);
581 break;
582 }
anthonyafa3dfc2012-03-03 11:31:30 +0000583 if (LocaleCompare("caption",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000584 {
anthony92c93bd2012-03-19 14:02:47 +0000585 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +0000586 break;
587 }
anthonyafa3dfc2012-03-03 11:31:30 +0000588 if (LocaleCompare("channel",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000589 {
anthony30b912a2012-03-22 01:20:28 +0000590 arg1=ArgOption("default");
591 parse=ParseChannelOption(arg1);
592 if (parse < 0)
593 CLIWandExceptArgBreak(OptionError,"UnrecognizedChannelType",
594 option,arg1);
595 _image_info->channel=(ChannelType) parse;
596 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000597 break;
598 }
anthonyafa3dfc2012-03-03 11:31:30 +0000599 if (LocaleCompare("colorspace",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000600 {
anthonyafbaed72011-10-26 12:05:04 +0000601 /* Setting used for new images via AquireImage()
602 But also used as a SimpleImageOperator
603 Undefined colorspace means don't modify images on
604 read or as a operation */
anthony30b912a2012-03-22 01:20:28 +0000605 parse = ParseCommandOption(MagickColorspaceOptions,MagickFalse,
606 ArgOption("undefined"));
607 if (parse < 0)
anthony5330ae02012-03-20 14:17:01 +0000608 CLIWandExceptArgBreak(OptionError,"UnrecognizedColorspace",
609 option,arg1);
anthony30b912a2012-03-22 01:20:28 +0000610 _image_info->colorspace=(ColorspaceType) parse;
anthony805a2d42011-09-25 08:25:12 +0000611 break;
612 }
anthonyafa3dfc2012-03-03 11:31:30 +0000613 if (LocaleCompare("comment",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000614 {
anthony92c93bd2012-03-19 14:02:47 +0000615 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +0000616 break;
617 }
anthonyafa3dfc2012-03-03 11:31:30 +0000618 if (LocaleCompare("compose",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000619 {
anthony92c93bd2012-03-19 14:02:47 +0000620 /* FUTURE: _image_info should be used,
anthony72feaa62012-01-17 06:46:23 +0000621 SyncImageSettings() used to set per-image attribute. - REMOVE
622
anthonyafbaed72011-10-26 12:05:04 +0000623 This setting should NOT be used to set image 'compose'
anthony92c93bd2012-03-19 14:02:47 +0000624 "-layer" operators shoud use _image_info if defined otherwise
anthony72feaa62012-01-17 06:46:23 +0000625 they should use a per-image compose setting.
anthony965524b2011-10-07 12:34:14 +0000626 */
anthonyebb73a22012-03-22 14:25:52 +0000627 parse = ParseCommandOption(MagickComposeOptions,MagickFalse,
628 ArgOption("undefined"));
629 if (parse < 0)
630 CLIWandExceptArgBreak(OptionError,"UnrecognizedComposeOperator",
631 option,arg1);
632 _image_info->compose=(CompositeOperator) parse;
anthony92c93bd2012-03-19 14:02:47 +0000633 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +0000634 break;
635 }
anthonyafa3dfc2012-03-03 11:31:30 +0000636 if (LocaleCompare("compress",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000637 {
anthony92c93bd2012-03-19 14:02:47 +0000638 /* FUTURE: What should be used? _image_info or ImageOption ???
anthony5f867ae2011-10-09 10:28:34 +0000639 The former is more efficent, but Crisy prefers the latter!
anthony72feaa62012-01-17 06:46:23 +0000640 SyncImageSettings() used to set per-image attribute.
anthony5f867ae2011-10-09 10:28:34 +0000641
anthony92c93bd2012-03-19 14:02:47 +0000642 The coders appears to use _image_info, not Image_Option
anthony5f867ae2011-10-09 10:28:34 +0000643 however the image attribute (for save) is set from the
644 ImageOption!
anthony72feaa62012-01-17 06:46:23 +0000645
646 Note that "undefined" is a different setting to "none".
anthony5f867ae2011-10-09 10:28:34 +0000647 */
anthonyebb73a22012-03-22 14:25:52 +0000648 parse = ParseCommandOption(MagickCompressOptions,MagickFalse,
649 ArgOption("undefined"));
650 if (parse < 0)
651 CLIWandExceptArgBreak(OptionError,"UnrecognizedImageCompression",
652 option,arg1);
653 _image_info->compression=(CompressionType) parse;
anthony92c93bd2012-03-19 14:02:47 +0000654 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +0000655 break;
656 }
anthonyebb73a22012-03-22 14:25:52 +0000657 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +0000658 }
659 case 'd':
660 {
anthonyafa3dfc2012-03-03 11:31:30 +0000661 if (LocaleCompare("debug",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000662 {
anthony72feaa62012-01-17 06:46:23 +0000663 /* SyncImageSettings() used to set per-image attribute. */
anthonyebb73a22012-03-22 14:25:52 +0000664 arg1=ArgOption("none");
665 parse = ParseCommandOption(MagickLogEventOptions,MagickFalse,arg1);
666 if (parse < 0)
667 CLIWandExceptArgBreak(OptionError,"UnrecognizedEventType",
668 option,arg1);
669 (void) SetLogEventMask(arg1);
670 _image_info->debug=IsEventLogging(); /* extract logging*/
anthony43f425d2012-02-26 12:58:58 +0000671 cli_wand->wand.debug=IsEventLogging();
anthony805a2d42011-09-25 08:25:12 +0000672 break;
673 }
anthonyafa3dfc2012-03-03 11:31:30 +0000674 if (LocaleCompare("define",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000675 {
anthony24aa8822012-03-11 00:56:06 +0000676 if (LocaleNCompare(arg1,"registry:",9) == 0)
anthony805a2d42011-09-25 08:25:12 +0000677 {
anthony5f867ae2011-10-09 10:28:34 +0000678 if (IfSetOption)
anthony92c93bd2012-03-19 14:02:47 +0000679 (void) DefineImageRegistry(StringRegistryType,arg1+9,_exception);
anthony5f867ae2011-10-09 10:28:34 +0000680 else
anthony24aa8822012-03-11 00:56:06 +0000681 (void) DeleteImageRegistry(arg1+9);
anthony805a2d42011-09-25 08:25:12 +0000682 break;
683 }
anthony24aa8822012-03-11 00:56:06 +0000684 /* DefineImageOption() equals SetImageOption() but with '=' */
anthony5f867ae2011-10-09 10:28:34 +0000685 if (IfSetOption)
anthony92c93bd2012-03-19 14:02:47 +0000686 (void) DefineImageOption(_image_info,arg1);
anthony7bcfe7f2012-03-30 14:01:22 +0000687 else if (IsMagickFalse(DeleteImageOption(_image_info,arg1)))
anthonyebb73a22012-03-22 14:25:52 +0000688 CLIWandExceptArgBreak(OptionError,"NoSuchOption",option,arg1);
anthony805a2d42011-09-25 08:25:12 +0000689 break;
690 }
anthonyafa3dfc2012-03-03 11:31:30 +0000691 if (LocaleCompare("delay",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000692 {
anthonyafbaed72011-10-26 12:05:04 +0000693 /* Only used for new images via AcquireImage()
694 FUTURE: Option should also be used for "-morph" (color morphing)
anthony5f867ae2011-10-09 10:28:34 +0000695 */
anthonyebb73a22012-03-22 14:25:52 +0000696 arg1=ArgOption("0");
anthony7bcfe7f2012-03-30 14:01:22 +0000697 if (IfMagickFalse(IsGeometry(arg1)))
anthonyebb73a22012-03-22 14:25:52 +0000698 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
699 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000700 break;
701 }
anthonyafa3dfc2012-03-03 11:31:30 +0000702 if (LocaleCompare("density",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000703 {
anthony92c93bd2012-03-19 14:02:47 +0000704 /* FUTURE: strings used in _image_info attr and _draw_info!
anthony72feaa62012-01-17 06:46:23 +0000705 Basically as density can be in a XxY form!
706
707 SyncImageSettings() used to set per-image attribute.
708 */
anthony7bcfe7f2012-03-30 14:01:22 +0000709 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthonyebb73a22012-03-22 14:25:52 +0000710 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +0000711 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
712 (void) CloneString(&_image_info->density,ArgOption(NULL));
713 (void) CloneString(&_draw_info->density,_image_info->density);
anthony805a2d42011-09-25 08:25:12 +0000714 break;
715 }
anthonyafa3dfc2012-03-03 11:31:30 +0000716 if (LocaleCompare("depth",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000717 {
anthony72feaa62012-01-17 06:46:23 +0000718 /* This is also a SimpleImageOperator! for 8->16 vaule trunc !!!!
719 SyncImageSettings() used to set per-image attribute.
720 */
anthony7bcfe7f2012-03-30 14:01:22 +0000721 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthonyebb73a22012-03-22 14:25:52 +0000722 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +0000723 _image_info->depth=IfSetOption?StringToUnsignedLong(arg1)
anthony5f867ae2011-10-09 10:28:34 +0000724 :MAGICKCORE_QUANTUM_DEPTH;
anthony805a2d42011-09-25 08:25:12 +0000725 break;
726 }
anthonyafa3dfc2012-03-03 11:31:30 +0000727 if (LocaleCompare("direction",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000728 {
anthony92c93bd2012-03-19 14:02:47 +0000729 /* Image Option is only used to set _draw_info */
anthonyebb73a22012-03-22 14:25:52 +0000730 arg1=ArgOption("undefined");
731 parse = ParseCommandOption(MagickDirectionOptions,MagickFalse,arg1);
732 if (parse < 0)
733 CLIWandExceptArgBreak(OptionError,"UnrecognizedDirectionType",
734 option,arg1);
735 _draw_info->direction=(DirectionType) parse;
736 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000737 break;
738 }
anthonyafa3dfc2012-03-03 11:31:30 +0000739 if (LocaleCompare("display",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000740 {
anthony92c93bd2012-03-19 14:02:47 +0000741 (void) CloneString(&_image_info->server_name,ArgOption(NULL));
742 (void) CloneString(&_draw_info->server_name,_image_info->server_name);
anthony805a2d42011-09-25 08:25:12 +0000743 break;
744 }
anthonyafa3dfc2012-03-03 11:31:30 +0000745 if (LocaleCompare("dispose",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000746 {
anthony72feaa62012-01-17 06:46:23 +0000747 /* only used in setting new images */
anthonyebb73a22012-03-22 14:25:52 +0000748 arg1=ArgOption("undefined");
749 parse = ParseCommandOption(MagickDisposeOptions,MagickFalse,arg1);
750 if (parse < 0)
751 CLIWandExceptArgBreak(OptionError,"UnrecognizedDisposeMethod",
752 option,arg1);
anthony92c93bd2012-03-19 14:02:47 +0000753 (void) SetImageOption(_image_info,option+1,ArgOption("undefined"));
anthony805a2d42011-09-25 08:25:12 +0000754 break;
755 }
anthonyb1d483a2012-04-14 12:53:56 +0000756 if (LocaleCompare("dissimilarity-threshold",option+1) == 0)
757 {
758 /* FUTURE: this is only used by CompareImages() which is used
759 only by the "compare" CLI program at this time. */
760 arg1=ArgOption(DEFAULT_DISSIMILARITY_THRESHOLD);
761 if (IfMagickFalse(IsGeometry(arg1)))
762 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
763 (void) SetImageOption(_image_info,option+1,arg1);
764 break;
765 }
anthonyafa3dfc2012-03-03 11:31:30 +0000766 if (LocaleCompare("dither",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000767 {
anthony92c93bd2012-03-19 14:02:47 +0000768 /* _image_info attr (on/off), _quantize_info attr (on/off)
769 but also ImageInfo and _quantize_info method!
anthony72feaa62012-01-17 06:46:23 +0000770 FUTURE: merge the duality of the dithering options
771 */
anthony92c93bd2012-03-19 14:02:47 +0000772 _image_info->dither = _quantize_info->dither = ArgBoolean;
773 (void) SetImageOption(_image_info,option+1,ArgOption("none"));
774 _quantize_info->dither_method=(DitherMethod) ParseCommandOption(
anthony72feaa62012-01-17 06:46:23 +0000775 MagickDitherOptions,MagickFalse,ArgOption("none"));
anthony92c93bd2012-03-19 14:02:47 +0000776 if (_quantize_info->dither_method == NoDitherMethod)
777 _image_info->dither = _quantize_info->dither = MagickFalse;
anthony805a2d42011-09-25 08:25:12 +0000778 break;
779 }
anthonyebb73a22012-03-22 14:25:52 +0000780 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +0000781 }
782 case 'e':
783 {
anthonyafa3dfc2012-03-03 11:31:30 +0000784 if (LocaleCompare("encoding",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000785 {
anthony92c93bd2012-03-19 14:02:47 +0000786 (void) CloneString(&_draw_info->encoding,ArgOption("undefined"));
787 (void) SetImageOption(_image_info,option+1,_draw_info->encoding);
anthony805a2d42011-09-25 08:25:12 +0000788 break;
789 }
anthonyafa3dfc2012-03-03 11:31:30 +0000790 if (LocaleCompare("endian",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000791 {
anthony92c93bd2012-03-19 14:02:47 +0000792 /* Both _image_info attr and ImageInfo */
anthony2a0ec8c2012-03-24 04:35:56 +0000793 arg1 = ArgOption("undefined");
794 parse = ParseCommandOption(MagickEndianOptions,MagickFalse,arg1);
795 if (parse < 0)
796 CLIWandExceptArgBreak(OptionError,"UnrecognizedEndianType",
797 option,arg1);
anthonyf46d4262012-03-26 03:30:34 +0000798 /* FUTURE: check alloc/free of endian string! - remove? */
cristyaa2c16c2012-03-25 22:21:35 +0000799 _image_info->endian=(EndianType) (*arg1);
anthony2a0ec8c2012-03-24 04:35:56 +0000800 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000801 break;
802 }
anthonyafa3dfc2012-03-03 11:31:30 +0000803 if (LocaleCompare("extract",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000804 {
anthony92c93bd2012-03-19 14:02:47 +0000805 (void) CloneString(&_image_info->extract,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +0000806 break;
807 }
anthonyebb73a22012-03-22 14:25:52 +0000808 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +0000809 }
810 case 'f':
811 {
anthonyafa3dfc2012-03-03 11:31:30 +0000812 if (LocaleCompare("family",option+1) == 0)
anthony6dc09cd2011-10-12 08:56:49 +0000813 {
anthony92c93bd2012-03-19 14:02:47 +0000814 (void) CloneString(&_draw_info->family,ArgOption(NULL));
anthony6dc09cd2011-10-12 08:56:49 +0000815 break;
816 }
anthonyafa3dfc2012-03-03 11:31:30 +0000817 if (LocaleCompare("fill",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000818 {
anthony92c93bd2012-03-19 14:02:47 +0000819 /* Set "fill" OR "fill-pattern" in _draw_info
anthonyfd706f92012-01-19 04:22:02 +0000820 The original fill color is preserved if a fill-pattern is given.
821 That way it does not effect other operations that directly using
822 the fill color and, can be retored using "+tile".
anthonyafbaed72011-10-26 12:05:04 +0000823 */
anthony72feaa62012-01-17 06:46:23 +0000824 MagickBooleanType
825 status;
anthony6dc09cd2011-10-12 08:56:49 +0000826
827 ExceptionInfo
828 *sans;
829
anthonyfd706f92012-01-19 04:22:02 +0000830 PixelInfo
831 color;
832
anthony2a0ec8c2012-03-24 04:35:56 +0000833 arg1 = ArgOption("none"); /* +fill turns it off! */
834 (void) SetImageOption(_image_info,option+1,arg1);
anthony92c93bd2012-03-19 14:02:47 +0000835 if (_draw_info->fill_pattern != (Image *) NULL)
836 _draw_info->fill_pattern=DestroyImage(_draw_info->fill_pattern);
anthony72feaa62012-01-17 06:46:23 +0000837
838 /* is it a color or a image? -- ignore exceptions */
839 sans=AcquireExceptionInfo();
anthony2a0ec8c2012-03-24 04:35:56 +0000840 status=QueryColorCompliance(arg1,AllCompliance,&color,sans);
anthony72feaa62012-01-17 06:46:23 +0000841 sans=DestroyExceptionInfo(sans);
anthonyfd706f92012-01-19 04:22:02 +0000842
anthony7bcfe7f2012-03-30 14:01:22 +0000843 if (IfMagickFalse(status))
anthony2a0ec8c2012-03-24 04:35:56 +0000844 _draw_info->fill_pattern=GetImageCache(_image_info,arg1,_exception);
anthonyfd706f92012-01-19 04:22:02 +0000845 else
anthony92c93bd2012-03-19 14:02:47 +0000846 _draw_info->fill=color;
anthony805a2d42011-09-25 08:25:12 +0000847 break;
848 }
anthonyafa3dfc2012-03-03 11:31:30 +0000849 if (LocaleCompare("filter",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000850 {
anthony72feaa62012-01-17 06:46:23 +0000851 /* SyncImageSettings() used to set per-image attribute. */
anthony2a0ec8c2012-03-24 04:35:56 +0000852 arg1 = ArgOption("undefined");
853 parse = ParseCommandOption(MagickFilterOptions,MagickFalse,arg1);
854 if (parse < 0)
855 CLIWandExceptArgBreak(OptionError,"UnrecognizedImageFilter",
856 option,arg1);
857 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000858 break;
859 }
anthonyafa3dfc2012-03-03 11:31:30 +0000860 if (LocaleCompare("font",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000861 {
anthony92c93bd2012-03-19 14:02:47 +0000862 (void) CloneString(&_draw_info->font,ArgOption(NULL));
863 (void) CloneString(&_image_info->font,_draw_info->font);
anthony805a2d42011-09-25 08:25:12 +0000864 break;
865 }
anthonyafa3dfc2012-03-03 11:31:30 +0000866 if (LocaleCompare("format",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000867 {
anthonydcf510d2011-10-30 13:51:40 +0000868 /* FUTURE: why the ping test, you could set ping after this! */
869 /*
anthony805a2d42011-09-25 08:25:12 +0000870 register const char
871 *q;
872
anthony24aa8822012-03-11 00:56:06 +0000873 for (q=strchr(arg1,'%'); q != (char *) NULL; q=strchr(q+1,'%'))
anthony805a2d42011-09-25 08:25:12 +0000874 if (strchr("Agkrz@[#",*(q+1)) != (char *) NULL)
anthony92c93bd2012-03-19 14:02:47 +0000875 _image_info->ping=MagickFalse;
anthonydcf510d2011-10-30 13:51:40 +0000876 */
anthony92c93bd2012-03-19 14:02:47 +0000877 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +0000878 break;
879 }
anthonyafa3dfc2012-03-03 11:31:30 +0000880 if (LocaleCompare("fuzz",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000881 {
anthony72feaa62012-01-17 06:46:23 +0000882 /* Option used to set image fuzz! unless blank canvas (from color)
anthonydcf510d2011-10-30 13:51:40 +0000883 Image attribute used for color compare operations
anthony72feaa62012-01-17 06:46:23 +0000884 SyncImageSettings() used to set per-image attribute.
885
anthony2a0ec8c2012-03-24 04:35:56 +0000886 FUTURE: Can't find anything else using _image_info->fuzz directly!
887 remove direct sttribute from image_info
anthony6613bf32011-10-15 07:24:44 +0000888 */
anthony2a0ec8c2012-03-24 04:35:56 +0000889 arg1=ArgOption("0");
anthony7bcfe7f2012-03-30 14:01:22 +0000890 if (IfMagickFalse(IsGeometry(arg1)))
anthony2a0ec8c2012-03-24 04:35:56 +0000891 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
892 _image_info->fuzz=StringToDoubleInterval(arg1,(double)
anthony80c37752012-01-16 01:03:11 +0000893 QuantumRange+1.0);
anthony2a0ec8c2012-03-24 04:35:56 +0000894 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000895 break;
896 }
anthonyebb73a22012-03-22 14:25:52 +0000897 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +0000898 }
899 case 'g':
900 {
anthonyafa3dfc2012-03-03 11:31:30 +0000901 if (LocaleCompare("gravity",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000902 {
anthony72feaa62012-01-17 06:46:23 +0000903 /* SyncImageSettings() used to set per-image attribute. */
anthonyfe1aa782012-03-24 13:43:04 +0000904 arg1 = ArgOption("none");
905 parse = ParseCommandOption(MagickGravityOptions,MagickFalse,arg1);
906 if (parse < 0)
907 CLIWandExceptArgBreak(OptionError,"UnrecognizedGravityType",
908 option,arg1);
anthonyfe1aa782012-03-24 13:43:04 +0000909 _draw_info->gravity=(GravityType) parse;
anthonye8490972012-04-03 13:16:01 +0000910 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000911 break;
912 }
anthonyafa3dfc2012-03-03 11:31:30 +0000913 if (LocaleCompare("green-primary",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000914 {
anthonydcf510d2011-10-30 13:51:40 +0000915 /* Image chromaticity X,Y NB: Y=X if Y not defined
anthony72feaa62012-01-17 06:46:23 +0000916 SyncImageSettings() used to set per-image attribute.
917 Used directly by many coders
anthonydcf510d2011-10-30 13:51:40 +0000918 */
anthonyf42014d2012-03-25 09:53:06 +0000919 arg1=ArgOption("0.0");
anthony7bcfe7f2012-03-30 14:01:22 +0000920 if (IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +0000921 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyf42014d2012-03-25 09:53:06 +0000922 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000923 break;
924 }
anthonyebb73a22012-03-22 14:25:52 +0000925 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +0000926 }
anthonyb1d483a2012-04-14 12:53:56 +0000927 case 'h':
928 {
929 if (LocaleCompare("highlight-color",option+1) == 0)
930 {
931 /* FUTURE: this is only used by CompareImages() which is used
932 only by the "compare" CLI program at this time. */
933 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
934 break;
935 }
936 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
937 }
anthony805a2d42011-09-25 08:25:12 +0000938 case 'i':
939 {
anthonyafa3dfc2012-03-03 11:31:30 +0000940 if (LocaleCompare("intent",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000941 {
anthony72feaa62012-01-17 06:46:23 +0000942 /* Only used by coders: MIFF, MPC, BMP, PNG
anthonydcf510d2011-10-30 13:51:40 +0000943 and for image profile call to AcquireTransformThreadSet()
anthony72feaa62012-01-17 06:46:23 +0000944 SyncImageSettings() used to set per-image attribute.
anthonydcf510d2011-10-30 13:51:40 +0000945 */
anthonyfe1aa782012-03-24 13:43:04 +0000946 arg1 = ArgOption("indefined");
947 parse = ParseCommandOption(MagickIntentOptions,MagickFalse,arg1);
948 if (parse < 0)
949 CLIWandExceptArgBreak(OptionError,"UnrecognizedIntentType",
950 option,arg1);
951 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000952 break;
953 }
anthonyafa3dfc2012-03-03 11:31:30 +0000954 if (LocaleCompare("interlace",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000955 {
anthony92c93bd2012-03-19 14:02:47 +0000956 /* _image_info is directly used by coders (so why an image setting?)
anthony72feaa62012-01-17 06:46:23 +0000957 SyncImageSettings() used to set per-image attribute.
anthonydcf510d2011-10-30 13:51:40 +0000958 */
anthonyfe1aa782012-03-24 13:43:04 +0000959 arg1 = ArgOption("undefined");
960 parse = ParseCommandOption(MagickInterlaceOptions,MagickFalse,arg1);
961 if (parse < 0)
962 CLIWandExceptArgBreak(OptionError,"UnrecognizedInterlaceType",
963 option,arg1);
964 _image_info->interlace=(InterlaceType) parse;
965 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000966 break;
967 }
anthonyafa3dfc2012-03-03 11:31:30 +0000968 if (LocaleCompare("interline-spacing",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000969 {
anthony7bcfe7f2012-03-30 14:01:22 +0000970 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +0000971 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +0000972 (void) SetImageOption(_image_info,option+1, ArgOption(NULL));
973 _draw_info->interline_spacing=StringToDouble(ArgOption("0"),
anthony72feaa62012-01-17 06:46:23 +0000974 (char **) NULL);
anthony805a2d42011-09-25 08:25:12 +0000975 break;
976 }
anthonyafa3dfc2012-03-03 11:31:30 +0000977 if (LocaleCompare("interpolate",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000978 {
anthonyfd706f92012-01-19 04:22:02 +0000979 /* SyncImageSettings() used to set per-image attribute. */
anthonyfe1aa782012-03-24 13:43:04 +0000980 arg1 = ArgOption("undefined");
981 parse = ParseCommandOption(MagickInterpolateOptions,MagickFalse,arg1);
982 if (parse < 0)
983 CLIWandExceptArgBreak(OptionError,"UnrecognizedInterpolateMethod",
984 option,arg1);
985 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000986 break;
987 }
anthonyafa3dfc2012-03-03 11:31:30 +0000988 if (LocaleCompare("interword-spacing",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000989 {
anthony7bcfe7f2012-03-30 14:01:22 +0000990 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +0000991 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +0000992 (void) SetImageOption(_image_info,option+1, ArgOption(NULL));
993 _draw_info->interword_spacing=StringToDouble(ArgOption("0"),(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +0000994 break;
995 }
anthonyebb73a22012-03-22 14:25:52 +0000996 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +0000997 }
998 case 'k':
999 {
anthonyafa3dfc2012-03-03 11:31:30 +00001000 if (LocaleCompare("kerning",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001001 {
anthony7bcfe7f2012-03-30 14:01:22 +00001002 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00001003 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001004 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1005 _draw_info->kerning=StringToDouble(ArgOption("0"),(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +00001006 break;
1007 }
anthonyebb73a22012-03-22 14:25:52 +00001008 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001009 }
1010 case 'l':
1011 {
anthonyafa3dfc2012-03-03 11:31:30 +00001012 if (LocaleCompare("label",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001013 {
anthony72feaa62012-01-17 06:46:23 +00001014 /* only used for new images - not in SyncImageOptions() */
anthony92c93bd2012-03-19 14:02:47 +00001015 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +00001016 break;
1017 }
anthony756cd0d2012-04-08 12:41:44 +00001018 if (LocaleCompare("limit",option+1) == 0)
1019 {
1020 MagickSizeType
1021 limit;
1022
1023 limit=MagickResourceInfinity;
1024 parse= ParseCommandOption(MagickResourceOptions,MagickFalse,arg1);
1025 if ( parse < 0 )
1026 CLIWandExceptArgBreak(OptionError,"UnrecognizedResourceType",
1027 option,arg1);
1028 if (LocaleCompare("unlimited",arg2) != 0)
1029 limit=(MagickSizeType) SiPrefixToDoubleInterval(arg2,100.0);
1030 (void) SetMagickResourceLimit((ResourceType)parse,limit);
1031 break;
1032 }
anthonyafa3dfc2012-03-03 11:31:30 +00001033 if (LocaleCompare("log",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001034 {
anthonyfe1aa782012-03-24 13:43:04 +00001035 if (IfSetOption) {
1036 if ((strchr(arg1,'%') == (char *) NULL))
1037 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony24aa8822012-03-11 00:56:06 +00001038 (void) SetLogFormat(arg1);
anthonyfe1aa782012-03-24 13:43:04 +00001039 }
anthony805a2d42011-09-25 08:25:12 +00001040 break;
1041 }
anthony975a8d72012-04-12 13:54:36 +00001042 if (LocaleCompare("lowlight-color",option+1) == 0)
1043 {
anthonyb1d483a2012-04-14 12:53:56 +00001044 /* FUTURE: this is only used by CompareImages() which is used
1045 only by the "compare" CLI program at this time. */
anthony975a8d72012-04-12 13:54:36 +00001046 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1047 break;
1048 }
anthonyafa3dfc2012-03-03 11:31:30 +00001049 if (LocaleCompare("loop",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001050 {
anthony72feaa62012-01-17 06:46:23 +00001051 /* SyncImageSettings() used to set per-image attribute. */
anthonyfe1aa782012-03-24 13:43:04 +00001052 arg1=ArgOption("0");
anthony7bcfe7f2012-03-30 14:01:22 +00001053 if (IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00001054 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1055 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +00001056 break;
1057 }
anthonyebb73a22012-03-22 14:25:52 +00001058 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001059 }
1060 case 'm':
1061 {
anthonyafa3dfc2012-03-03 11:31:30 +00001062 if (LocaleCompare("mattecolor",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001063 {
anthony72feaa62012-01-17 06:46:23 +00001064 /* SyncImageSettings() used to set per-image attribute. */
anthony92c93bd2012-03-19 14:02:47 +00001065 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony72feaa62012-01-17 06:46:23 +00001066 (void) QueryColorCompliance(ArgOption(MatteColor),AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +00001067 &_image_info->matte_color,_exception);
anthony805a2d42011-09-25 08:25:12 +00001068 break;
anthonycd358fc2012-04-16 13:59:03 +00001069 }
anthonyb1d483a2012-04-14 12:53:56 +00001070 if (LocaleCompare("metric",option+1) == 0)
1071 {
1072 /* FUTURE: this is only used by CompareImages() which is used
1073 only by the "compare" CLI program at this time. */
1074 parse=ParseCommandOption(MagickMetricOptions,MagickFalse,arg1);
1075 if ( parse < 0 )
1076 CLIWandExceptArgBreak(OptionError,"UnrecognizedMetricType",
1077 option,arg1);
1078 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthonycd358fc2012-04-16 13:59:03 +00001079 break;
anthony805a2d42011-09-25 08:25:12 +00001080 }
anthonyafa3dfc2012-03-03 11:31:30 +00001081 if (LocaleCompare("monitor",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001082 {
anthony92c93bd2012-03-19 14:02:47 +00001083 (void) SetImageInfoProgressMonitor(_image_info, IfSetOption?
anthony31f1bf72012-01-30 12:37:22 +00001084 MonitorProgress: (MagickProgressMonitor) NULL, (void *) NULL);
anthony805a2d42011-09-25 08:25:12 +00001085 break;
1086 }
anthonyafa3dfc2012-03-03 11:31:30 +00001087 if (LocaleCompare("monochrome",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001088 {
anthony24aa8822012-03-11 00:56:06 +00001089 /* Setting (used by some input coders!) -- why?
1090 Warning: This is also Special '-type' SimpleOperator
anthony72feaa62012-01-17 06:46:23 +00001091 */
anthony92c93bd2012-03-19 14:02:47 +00001092 _image_info->monochrome= ArgBoolean;
anthony805a2d42011-09-25 08:25:12 +00001093 break;
1094 }
anthonyebb73a22012-03-22 14:25:52 +00001095 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001096 }
1097 case 'o':
1098 {
anthonyafa3dfc2012-03-03 11:31:30 +00001099 if (LocaleCompare("orient",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001100 {
anthony72feaa62012-01-17 06:46:23 +00001101 /* Is not used when defining for new images.
anthonydcf510d2011-10-30 13:51:40 +00001102 This makes it more of a 'operation' than a setting
anthony72feaa62012-01-17 06:46:23 +00001103 FUTURE: make set meta-data operator instead.
1104 SyncImageSettings() used to set per-image attribute.
anthonydcf510d2011-10-30 13:51:40 +00001105 */
anthony7bc87992012-03-25 02:32:51 +00001106 parse=ParseCommandOption(MagickOrientationOptions,MagickFalse,
1107 ArgOption("undefined"));
1108 if (parse < 0)
1109 CLIWandExceptArgBreak(OptionError,"UnrecognizedImageOrientation",
1110 option,arg1);
1111 _image_info->orientation=(OrientationType)parse;
anthony92c93bd2012-03-19 14:02:47 +00001112 (void) SetImageOption(_image_info,option+1, ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +00001113 break;
1114 }
anthonyebb73a22012-03-22 14:25:52 +00001115 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001116 }
1117 case 'p':
1118 {
anthonyafa3dfc2012-03-03 11:31:30 +00001119 if (LocaleCompare("page",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001120 {
anthony7bc87992012-03-25 02:32:51 +00001121 /* Only used for new images and image generators.
anthony72feaa62012-01-17 06:46:23 +00001122 SyncImageSettings() used to set per-image attribute. ?????
1123 That last is WRONG!!!!
anthony7bc87992012-03-25 02:32:51 +00001124 FUTURE: adjust named 'page' sizes according density
anthony72feaa62012-01-17 06:46:23 +00001125 */
anthony805a2d42011-09-25 08:25:12 +00001126 char
1127 *canonical_page,
1128 page[MaxTextExtent];
1129
1130 const char
1131 *image_option;
1132
1133 MagickStatusType
1134 flags;
1135
1136 RectangleInfo
1137 geometry;
1138
anthonydcf510d2011-10-30 13:51:40 +00001139 if (!IfSetOption)
anthony805a2d42011-09-25 08:25:12 +00001140 {
anthony92c93bd2012-03-19 14:02:47 +00001141 (void) DeleteImageOption(_image_info,option+1);
1142 (void) CloneString(&_image_info->page,(char *) NULL);
anthony805a2d42011-09-25 08:25:12 +00001143 break;
1144 }
1145 (void) ResetMagickMemory(&geometry,0,sizeof(geometry));
anthony92c93bd2012-03-19 14:02:47 +00001146 image_option=GetImageOption(_image_info,"page");
anthony805a2d42011-09-25 08:25:12 +00001147 if (image_option != (const char *) NULL)
1148 flags=ParseAbsoluteGeometry(image_option,&geometry);
anthony24aa8822012-03-11 00:56:06 +00001149 canonical_page=GetPageGeometry(arg1);
anthony805a2d42011-09-25 08:25:12 +00001150 flags=ParseAbsoluteGeometry(canonical_page,&geometry);
1151 canonical_page=DestroyString(canonical_page);
1152 (void) FormatLocaleString(page,MaxTextExtent,"%lux%lu",
1153 (unsigned long) geometry.width,(unsigned long) geometry.height);
1154 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
1155 (void) FormatLocaleString(page,MaxTextExtent,"%lux%lu%+ld%+ld",
1156 (unsigned long) geometry.width,(unsigned long) geometry.height,
1157 (long) geometry.x,(long) geometry.y);
anthony92c93bd2012-03-19 14:02:47 +00001158 (void) SetImageOption(_image_info,option+1,page);
1159 (void) CloneString(&_image_info->page,page);
anthony805a2d42011-09-25 08:25:12 +00001160 break;
1161 }
anthonyafa3dfc2012-03-03 11:31:30 +00001162 if (LocaleCompare("ping",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001163 {
anthony92c93bd2012-03-19 14:02:47 +00001164 _image_info->ping = ArgBoolean;
anthony805a2d42011-09-25 08:25:12 +00001165 break;
1166 }
anthonyafa3dfc2012-03-03 11:31:30 +00001167 if (LocaleCompare("pointsize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001168 {
anthonyf42014d2012-03-25 09:53:06 +00001169 if (IfSetOption) {
anthony7bcfe7f2012-03-30 14:01:22 +00001170 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00001171 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1172 _image_info->pointsize =
1173 _draw_info->pointsize =
1174 StringToDouble(arg1,(char **) NULL);
1175 }
1176 else {
1177 _image_info->pointsize=0.0; /* unset pointsize */
1178 _draw_info->pointsize=12.0;
1179 }
anthony805a2d42011-09-25 08:25:12 +00001180 break;
1181 }
anthonyafa3dfc2012-03-03 11:31:30 +00001182 if (LocaleCompare("precision",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001183 {
anthonyf42014d2012-03-25 09:53:06 +00001184 arg1=ArgOption("-1");
anthony7bcfe7f2012-03-30 14:01:22 +00001185 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00001186 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1187 (void) SetMagickPrecision(StringToInteger(arg1));
anthony805a2d42011-09-25 08:25:12 +00001188 break;
1189 }
anthonydcf510d2011-10-30 13:51:40 +00001190 /* FUTURE: Only the 'preview' coder appears to use this
anthonya3ef4ed2012-03-17 06:52:53 +00001191 * DEPRECIATE the coder? Leaving only the 'preview' operator.
anthonyafa3dfc2012-03-03 11:31:30 +00001192 if (LocaleCompare("preview",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001193 {
anthony92c93bd2012-03-19 14:02:47 +00001194 _image_info->preview_type=UndefinedPreview;
anthonydcf510d2011-10-30 13:51:40 +00001195 if (IfSetOption)
anthony92c93bd2012-03-19 14:02:47 +00001196 _image_info->preview_type=(PreviewType) ParseCommandOption(
anthony24aa8822012-03-11 00:56:06 +00001197 MagickPreviewOptions,MagickFalse,arg1);
anthony805a2d42011-09-25 08:25:12 +00001198 break;
1199 }
anthonydcf510d2011-10-30 13:51:40 +00001200 */
anthonyebb73a22012-03-22 14:25:52 +00001201 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001202 }
1203 case 'q':
1204 {
anthonyafa3dfc2012-03-03 11:31:30 +00001205 if (LocaleCompare("quality",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001206 {
anthony7bcfe7f2012-03-30 14:01:22 +00001207 if (IfMagickFalse(IsGeometry(arg1)))
anthony7bc87992012-03-25 02:32:51 +00001208 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyf42014d2012-03-25 09:53:06 +00001209 _image_info->quality= IfSetOption ? StringToUnsignedLong(arg1)
1210 : UNDEFINED_COMPRESSION_QUALITY;
anthony92c93bd2012-03-19 14:02:47 +00001211 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +00001212 break;
1213 }
anthonyafa3dfc2012-03-03 11:31:30 +00001214 if (LocaleCompare("quantize",option+1) == 0)
anthonyafbaed72011-10-26 12:05:04 +00001215 {
anthony92c93bd2012-03-19 14:02:47 +00001216 /* Just a set direct in _quantize_info */
anthony7bc87992012-03-25 02:32:51 +00001217 arg1=ArgOption("undefined");
1218 parse=ParseCommandOption(MagickColorspaceOptions,MagickFalse,arg1);
1219 if (parse < 0)
1220 CLIWandExceptArgBreak(OptionError,"UnrecognizedColorspace",
1221 option,arg1);
1222 _quantize_info->colorspace=(ColorspaceType)parse;
anthonyafbaed72011-10-26 12:05:04 +00001223 break;
1224 }
anthonyafa3dfc2012-03-03 11:31:30 +00001225 if (LocaleCompare("quiet",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001226 {
anthonyf42014d2012-03-25 09:53:06 +00001227 /* FUTURE: if two -quiet is performed you can not do +quiet!
1228 This needs to be checked over thoughly.
1229 */
anthony805a2d42011-09-25 08:25:12 +00001230 static WarningHandler
1231 warning_handler = (WarningHandler) NULL;
anthony72feaa62012-01-17 06:46:23 +00001232
anthonyafbaed72011-10-26 12:05:04 +00001233 WarningHandler
1234 tmp = SetWarningHandler((WarningHandler) NULL);
anthony805a2d42011-09-25 08:25:12 +00001235
anthonyafbaed72011-10-26 12:05:04 +00001236 if ( tmp != (WarningHandler) NULL)
1237 warning_handler = tmp; /* remember the old handler */
1238 if (!IfSetOption) /* set the old handler */
1239 warning_handler=SetWarningHandler(warning_handler);
anthony805a2d42011-09-25 08:25:12 +00001240 break;
1241 }
anthonyebb73a22012-03-22 14:25:52 +00001242 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001243 }
1244 case 'r':
1245 {
anthonyafa3dfc2012-03-03 11:31:30 +00001246 if (LocaleCompare("red-primary",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001247 {
anthonydcf510d2011-10-30 13:51:40 +00001248 /* Image chromaticity X,Y NB: Y=X if Y not defined
1249 Used by many coders
anthony72feaa62012-01-17 06:46:23 +00001250 SyncImageSettings() used to set per-image attribute.
anthonydcf510d2011-10-30 13:51:40 +00001251 */
anthonyf42014d2012-03-25 09:53:06 +00001252 arg1=ArgOption("0.0");
anthony7bcfe7f2012-03-30 14:01:22 +00001253 if (IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00001254 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyf42014d2012-03-25 09:53:06 +00001255 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +00001256 break;
1257 }
cristyb0f7a182012-04-06 23:33:11 +00001258 if (LocaleCompare("regard-warnings",option+1) == 0)
anthonye5fcd362012-04-09 04:02:09 +00001259 /* FUTURE: to be replaced by a 'fatal-level' type setting */
cristyb0f7a182012-04-06 23:33:11 +00001260 break;
anthonyafa3dfc2012-03-03 11:31:30 +00001261 if (LocaleCompare("render",option+1) == 0)
anthonyafbaed72011-10-26 12:05:04 +00001262 {
anthony92c93bd2012-03-19 14:02:47 +00001263 /* _draw_info only setting */
1264 _draw_info->render= ArgBooleanNot;
anthonyafbaed72011-10-26 12:05:04 +00001265 break;
1266 }
anthony756cd0d2012-04-08 12:41:44 +00001267 if (LocaleCompare("respect-parenthesis",option+1) == 0)
1268 {
1269 /* link image and setting stacks - option is itself saved on stack! */
1270 (void) SetImageOption(_image_info,option+1,ArgBooleanString);
1271 break;
1272 }
anthonyebb73a22012-03-22 14:25:52 +00001273 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001274 }
1275 case 's':
1276 {
anthonyafa3dfc2012-03-03 11:31:30 +00001277 if (LocaleCompare("sampling-factor",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001278 {
anthonyafbaed72011-10-26 12:05:04 +00001279 /* FUTURE: should be converted to jpeg:sampling_factor */
anthony7bcfe7f2012-03-30 14:01:22 +00001280 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00001281 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001282 (void) CloneString(&_image_info->sampling_factor,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +00001283 break;
1284 }
anthonyafa3dfc2012-03-03 11:31:30 +00001285 if (LocaleCompare("scene",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001286 {
anthonyf42014d2012-03-25 09:53:06 +00001287 /* SyncImageSettings() used to set this as a per-image attribute.
anthony72feaa62012-01-17 06:46:23 +00001288 What ??? Why ????
1289 */
anthony7bcfe7f2012-03-30 14:01:22 +00001290 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00001291 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001292 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1293 _image_info->scene=StringToUnsignedLong(ArgOption("0"));
anthony805a2d42011-09-25 08:25:12 +00001294 break;
1295 }
anthonyafa3dfc2012-03-03 11:31:30 +00001296 if (LocaleCompare("seed",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001297 {
anthony7bcfe7f2012-03-30 14:01:22 +00001298 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00001299 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
cristyd7761bb2012-04-14 01:42:05 +00001300 SetRandomSecretKey(
anthony24aa8822012-03-11 00:56:06 +00001301 IfSetOption ? (size_t) StringToUnsignedLong(arg1)
anthonyafbaed72011-10-26 12:05:04 +00001302 : (size_t) time((time_t *) NULL) );
anthony805a2d42011-09-25 08:25:12 +00001303 break;
1304 }
anthonyafa3dfc2012-03-03 11:31:30 +00001305 if (LocaleCompare("size",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001306 {
anthony92c93bd2012-03-19 14:02:47 +00001307 /* FUTURE: string in _image_info -- convert to Option ???
anthonyafbaed72011-10-26 12:05:04 +00001308 Look at the special handling for "size" in SetImageOption()
anthony74b1cfc2011-10-06 12:44:16 +00001309 */
anthony92c93bd2012-03-19 14:02:47 +00001310 (void) CloneString(&_image_info->size,ArgOption(NULL));
anthonyafbaed72011-10-26 12:05:04 +00001311 break;
1312 }
anthonyafa3dfc2012-03-03 11:31:30 +00001313 if (LocaleCompare("stretch",option+1) == 0)
anthonyafbaed72011-10-26 12:05:04 +00001314 {
anthonyf42014d2012-03-25 09:53:06 +00001315 arg1=ArgOption("undefined");
1316 parse = ParseCommandOption(MagickStretchOptions,MagickFalse,arg1);
1317 if (parse < 0)
1318 CLIWandExceptArgBreak(OptionError,"UnrecognizedStretchType",
1319 option,arg1);
1320 _draw_info->stretch=(StretchType) parse;
anthony805a2d42011-09-25 08:25:12 +00001321 break;
1322 }
anthonyafa3dfc2012-03-03 11:31:30 +00001323 if (LocaleCompare("stroke",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001324 {
anthonyafbaed72011-10-26 12:05:04 +00001325 /* set stroke color OR stroke-pattern
anthonyfd706f92012-01-19 04:22:02 +00001326 UPDATE: ensure stroke color is not destroyed is a pattern
1327 is given. Just in case the color is also used for other purposes.
anthonyafbaed72011-10-26 12:05:04 +00001328 */
anthony72feaa62012-01-17 06:46:23 +00001329 MagickBooleanType
1330 status;
anthonyafbaed72011-10-26 12:05:04 +00001331
1332 ExceptionInfo
1333 *sans;
1334
anthonyfd706f92012-01-19 04:22:02 +00001335 PixelInfo
1336 color;
1337
anthony2a0ec8c2012-03-24 04:35:56 +00001338 arg1 = ArgOption("none"); /* +fill turns it off! */
1339 (void) SetImageOption(_image_info,option+1,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001340 if (_draw_info->stroke_pattern != (Image *) NULL)
1341 _draw_info->stroke_pattern=DestroyImage(_draw_info->stroke_pattern);
anthony72feaa62012-01-17 06:46:23 +00001342
1343 /* is it a color or a image? -- ignore exceptions */
anthonyafbaed72011-10-26 12:05:04 +00001344 sans=AcquireExceptionInfo();
anthony2a0ec8c2012-03-24 04:35:56 +00001345 status=QueryColorCompliance(arg1,AllCompliance,&color,sans);
anthonyafbaed72011-10-26 12:05:04 +00001346 sans=DestroyExceptionInfo(sans);
anthonyfd706f92012-01-19 04:22:02 +00001347
anthony7bcfe7f2012-03-30 14:01:22 +00001348 if (IfMagickFalse(status))
anthony2a0ec8c2012-03-24 04:35:56 +00001349 _draw_info->stroke_pattern=GetImageCache(_image_info,arg1,_exception);
anthonyfd706f92012-01-19 04:22:02 +00001350 else
anthony92c93bd2012-03-19 14:02:47 +00001351 _draw_info->stroke=color;
anthony805a2d42011-09-25 08:25:12 +00001352 break;
1353 }
anthonyafa3dfc2012-03-03 11:31:30 +00001354 if (LocaleCompare("strokewidth",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001355 {
anthony7bcfe7f2012-03-30 14:01:22 +00001356 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00001357 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001358 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1359 _draw_info->stroke_width=StringToDouble(ArgOption("1.0"),
anthony72feaa62012-01-17 06:46:23 +00001360 (char **) NULL);
anthonyafbaed72011-10-26 12:05:04 +00001361 break;
1362 }
anthonyafa3dfc2012-03-03 11:31:30 +00001363 if (LocaleCompare("style",option+1) == 0)
anthonyafbaed72011-10-26 12:05:04 +00001364 {
anthonyf42014d2012-03-25 09:53:06 +00001365 arg1=ArgOption("undefined");
1366 parse = ParseCommandOption(MagickStyleOptions,MagickFalse,arg1);
1367 if (parse < 0)
1368 CLIWandExceptArgBreak(OptionError,"UnrecognizedStyleType",
1369 option,arg1);
1370 _draw_info->style=(StyleType) parse;
anthony805a2d42011-09-25 08:25:12 +00001371 break;
1372 }
anthonycd358fc2012-04-16 13:59:03 +00001373#if 0
anthonyb1d483a2012-04-14 12:53:56 +00001374 if (LocaleCompare("subimage-search",option+1) == 0)
1375 {
1376 /* FUTURE: this is only used by CompareImages() which is used
1377 only by the "compare" CLI program at this time. */
1378 (void) SetImageOption(_image_info,option+1,ArgBooleanString);
1379 break;
1380 }
anthonycd358fc2012-04-16 13:59:03 +00001381#endif
anthonyafa3dfc2012-03-03 11:31:30 +00001382 if (LocaleCompare("synchronize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001383 {
anthonyf42014d2012-03-25 09:53:06 +00001384 /* FUTURE: syncronize to storage - but what does that mean? */
anthony92c93bd2012-03-19 14:02:47 +00001385 _image_info->synchronize = ArgBoolean;
anthony805a2d42011-09-25 08:25:12 +00001386 break;
1387 }
anthonyebb73a22012-03-22 14:25:52 +00001388 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001389 }
1390 case 't':
1391 {
anthonyafa3dfc2012-03-03 11:31:30 +00001392 if (LocaleCompare("taint",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001393 {
anthony72feaa62012-01-17 06:46:23 +00001394 /* SyncImageSettings() used to set per-image attribute. */
anthony92c93bd2012-03-19 14:02:47 +00001395 (void) SetImageOption(_image_info,option+1,ArgBooleanString);
anthony805a2d42011-09-25 08:25:12 +00001396 break;
1397 }
anthonyafa3dfc2012-03-03 11:31:30 +00001398 if (LocaleCompare("texture",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001399 {
anthony52bef752012-03-27 13:54:47 +00001400 /* FUTURE: move _image_info string to option splay-tree
1401 Other than "montage" what uses "texture" ????
1402 */
anthony92c93bd2012-03-19 14:02:47 +00001403 (void) CloneString(&_image_info->texture,ArgOption(NULL));
anthonyafbaed72011-10-26 12:05:04 +00001404 break;
1405 }
anthonyafa3dfc2012-03-03 11:31:30 +00001406 if (LocaleCompare("tile",option+1) == 0)
anthonyafbaed72011-10-26 12:05:04 +00001407 {
anthony92c93bd2012-03-19 14:02:47 +00001408 _draw_info->fill_pattern=IfSetOption
1409 ?GetImageCache(_image_info,arg1,_exception)
1410 :DestroyImage(_draw_info->fill_pattern);
anthony805a2d42011-09-25 08:25:12 +00001411 break;
1412 }
anthonyafa3dfc2012-03-03 11:31:30 +00001413 if (LocaleCompare("tile-offset",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001414 {
anthony72feaa62012-01-17 06:46:23 +00001415 /* SyncImageSettings() used to set per-image attribute. ??? */
anthony52bef752012-03-27 13:54:47 +00001416 arg1=ArgOption("0");
anthony7bcfe7f2012-03-30 14:01:22 +00001417 if (IfMagickFalse(IsGeometry(arg1)))
anthony52bef752012-03-27 13:54:47 +00001418 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1419 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +00001420 break;
1421 }
anthonyafa3dfc2012-03-03 11:31:30 +00001422 if (LocaleCompare("transparent-color",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001423 {
anthony92c93bd2012-03-19 14:02:47 +00001424 /* FUTURE: both _image_info attribute & ImageOption in use!
1425 _image_info only used for generating new images.
anthony72feaa62012-01-17 06:46:23 +00001426 SyncImageSettings() used to set per-image attribute.
1427
anthonyafbaed72011-10-26 12:05:04 +00001428 Note that +transparent-color, means fall-back to image
1429 attribute so ImageOption is deleted, not set to a default.
1430 */
anthony7bcfe7f2012-03-30 14:01:22 +00001431 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthony52bef752012-03-27 13:54:47 +00001432 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001433 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony72feaa62012-01-17 06:46:23 +00001434 (void) QueryColorCompliance(ArgOption("none"),AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +00001435 &_image_info->transparent_color,_exception);
anthony805a2d42011-09-25 08:25:12 +00001436 break;
1437 }
anthonyafa3dfc2012-03-03 11:31:30 +00001438 if (LocaleCompare("treedepth",option+1) == 0)
anthony31f1bf72012-01-30 12:37:22 +00001439 {
anthony92c93bd2012-03-19 14:02:47 +00001440 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1441 _quantize_info->tree_depth=StringToUnsignedLong(ArgOption("0"));
anthony31f1bf72012-01-30 12:37:22 +00001442 break;
1443 }
anthonyafa3dfc2012-03-03 11:31:30 +00001444 if (LocaleCompare("type",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001445 {
anthony72feaa62012-01-17 06:46:23 +00001446 /* SyncImageSettings() used to set per-image attribute. */
anthony52bef752012-03-27 13:54:47 +00001447 parse=ParseCommandOption(MagickTypeOptions,MagickFalse,
1448 ArgOption("undefined"));
1449 if (parse < 0)
1450 CLIWandExceptArgBreak(OptionError,"UnrecognizedImageType",
1451 option,arg1);
1452 _image_info->type=(ImageType) parse;
anthony92c93bd2012-03-19 14:02:47 +00001453 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +00001454 break;
1455 }
anthonyebb73a22012-03-22 14:25:52 +00001456 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001457 }
1458 case 'u':
1459 {
anthonyafa3dfc2012-03-03 11:31:30 +00001460 if (LocaleCompare("undercolor",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001461 {
anthony92c93bd2012-03-19 14:02:47 +00001462 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony72feaa62012-01-17 06:46:23 +00001463 (void) QueryColorCompliance(ArgOption("none"),AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +00001464 &_draw_info->undercolor,_exception);
anthony805a2d42011-09-25 08:25:12 +00001465 break;
1466 }
anthonyafa3dfc2012-03-03 11:31:30 +00001467 if (LocaleCompare("units",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001468 {
anthony72feaa62012-01-17 06:46:23 +00001469 /* SyncImageSettings() used to set per-image attribute.
anthony92c93bd2012-03-19 14:02:47 +00001470 Should this effect _draw_info X and Y resolution?
anthony72feaa62012-01-17 06:46:23 +00001471 FUTURE: this probably should be part of the density setting
1472 */
anthony52bef752012-03-27 13:54:47 +00001473 parse=ParseCommandOption(MagickResolutionOptions,MagickFalse,
1474 ArgOption("undefined"));
1475 if (parse < 0)
1476 CLIWandExceptArgBreak(OptionError,"UnrecognizedUnitsType",
1477 option,arg1);
1478 _image_info->units=(ResolutionType) parse;
anthony92c93bd2012-03-19 14:02:47 +00001479 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +00001480 break;
1481 }
anthonyebb73a22012-03-22 14:25:52 +00001482 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001483 }
1484 case 'v':
1485 {
anthonyafa3dfc2012-03-03 11:31:30 +00001486 if (LocaleCompare("verbose",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001487 {
anthony24aa8822012-03-11 00:56:06 +00001488 /* FUTURE: Remember all options become image artifacts
anthony92c93bd2012-03-19 14:02:47 +00001489 _image_info->verbose is only used by coders.
anthonyab3a50c2011-10-27 11:48:57 +00001490 */
anthony92c93bd2012-03-19 14:02:47 +00001491 (void) SetImageOption(_image_info,option+1,ArgBooleanString);
1492 _image_info->verbose= ArgBoolean;
1493 _image_info->ping=MagickFalse; /* verbose can't be a ping */
anthony805a2d42011-09-25 08:25:12 +00001494 break;
1495 }
anthonyafa3dfc2012-03-03 11:31:30 +00001496 if (LocaleCompare("view",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001497 {
anthony92c93bd2012-03-19 14:02:47 +00001498 /* FUTURE: Convert from _image_info to ImageOption
anthonyab3a50c2011-10-27 11:48:57 +00001499 Only used by coder FPX
anthony52bef752012-03-27 13:54:47 +00001500 And it only tests existance, not its content!
anthonyab3a50c2011-10-27 11:48:57 +00001501 */
anthony92c93bd2012-03-19 14:02:47 +00001502 (void) CloneString(&_image_info->view,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +00001503 break;
1504 }
anthonyafa3dfc2012-03-03 11:31:30 +00001505 if (LocaleCompare("virtual-pixel",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001506 {
anthonyfd706f92012-01-19 04:22:02 +00001507 /* SyncImageSettings() used to set per-image attribute.
1508 This is VERY deep in the image caching structure.
1509 */
anthony52bef752012-03-27 13:54:47 +00001510 parse=ParseCommandOption(MagickVirtualPixelOptions,MagickFalse,
1511 ArgOption("undefined"));
1512 if (parse < 0)
1513 CLIWandExceptArgBreak(OptionError,"UnrecognizedVirtualPixelMethod",
1514 option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001515 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +00001516 break;
1517 }
anthonyebb73a22012-03-22 14:25:52 +00001518 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001519 }
1520 case 'w':
1521 {
anthonyafa3dfc2012-03-03 11:31:30 +00001522 if (LocaleCompare("weight",option+1) == 0)
anthonyab3a50c2011-10-27 11:48:57 +00001523 {
anthony72feaa62012-01-17 06:46:23 +00001524 /* Just what does using a font 'weight' do ???
anthonydcf510d2011-10-30 13:51:40 +00001525 There is no "-list weight" output (reference manual says there is)
anthonyab3a50c2011-10-27 11:48:57 +00001526 */
anthony52bef752012-03-27 13:54:47 +00001527 arg1=ArgOption("all");
anthony92c93bd2012-03-19 14:02:47 +00001528 _draw_info->weight=StringToUnsignedLong(arg1);
anthony24aa8822012-03-11 00:56:06 +00001529 if (LocaleCompare(arg1,"all") == 0)
anthony92c93bd2012-03-19 14:02:47 +00001530 _draw_info->weight=0;
anthony24aa8822012-03-11 00:56:06 +00001531 if (LocaleCompare(arg1,"bold") == 0)
anthony92c93bd2012-03-19 14:02:47 +00001532 _draw_info->weight=700;
anthony24aa8822012-03-11 00:56:06 +00001533 if (LocaleCompare(arg1,"bolder") == 0)
anthony92c93bd2012-03-19 14:02:47 +00001534 if (_draw_info->weight <= 800)
1535 _draw_info->weight+=100;
anthony24aa8822012-03-11 00:56:06 +00001536 if (LocaleCompare(arg1,"lighter") == 0)
anthony92c93bd2012-03-19 14:02:47 +00001537 if (_draw_info->weight >= 100)
1538 _draw_info->weight-=100;
anthony24aa8822012-03-11 00:56:06 +00001539 if (LocaleCompare(arg1,"normal") == 0)
anthony92c93bd2012-03-19 14:02:47 +00001540 _draw_info->weight=400;
anthonyab3a50c2011-10-27 11:48:57 +00001541 break;
1542 }
anthonyafa3dfc2012-03-03 11:31:30 +00001543 if (LocaleCompare("white-point",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001544 {
anthony72feaa62012-01-17 06:46:23 +00001545 /* Used as a image chromaticity setting
1546 SyncImageSettings() used to set per-image attribute.
1547 */
anthony52bef752012-03-27 13:54:47 +00001548 arg1=ArgOption("0.0");
anthony7bcfe7f2012-03-30 14:01:22 +00001549 if (IfMagickFalse(IsGeometry(arg1)))
anthony52bef752012-03-27 13:54:47 +00001550 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1551 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +00001552 break;
1553 }
anthonyebb73a22012-03-22 14:25:52 +00001554 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001555 }
1556 default:
anthonyebb73a22012-03-22 14:25:52 +00001557 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001558 }
anthony24aa8822012-03-11 00:56:06 +00001559
anthony92c93bd2012-03-19 14:02:47 +00001560#undef _image_info
1561#undef _exception
1562#undef _draw_info
1563#undef _quantize_info
anthonyfd706f92012-01-19 04:22:02 +00001564#undef IfSetOption
anthonyfd706f92012-01-19 04:22:02 +00001565#undef ArgBoolean
anthony24aa8822012-03-11 00:56:06 +00001566#undef ArgBooleanNot
1567#undef ArgBooleanString
1568#undef ArgOption
anthonyfd706f92012-01-19 04:22:02 +00001569
anthony31f1bf72012-01-30 12:37:22 +00001570 return;
anthony805a2d42011-09-25 08:25:12 +00001571}
1572
1573/*
1574%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1575% %
1576% %
1577% %
anthony43f425d2012-02-26 12:58:58 +00001578+ 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 +00001579% %
1580% %
1581% %
1582%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1583%
anthony31f1bf72012-01-30 12:37:22 +00001584% WandSimpleOperatorImages() applys one simple image operation given to all
anthony43f425d2012-02-26 12:58:58 +00001585% the images in the CLI wand, with the settings that was previously saved in
1586% the CLI wand.
anthonydcf510d2011-10-30 13:51:40 +00001587%
1588% It is assumed that any per-image settings are up-to-date with respect to
anthony43f425d2012-02-26 12:58:58 +00001589% extra settings that were already saved in the wand.
anthony805a2d42011-09-25 08:25:12 +00001590%
anthonyd1447672012-01-19 05:33:53 +00001591% The format of the WandSimpleOperatorImage method is:
anthony805a2d42011-09-25 08:25:12 +00001592%
anthony43f425d2012-02-26 12:58:58 +00001593% void CLISimpleOperatorImages(MagickCLI *cli_wand,
anthonyafa3dfc2012-03-03 11:31:30 +00001594% const char *option, const char *arg1, const char *arg2)
anthony805a2d42011-09-25 08:25:12 +00001595%
1596% A description of each parameter follows:
1597%
anthony43f425d2012-02-26 12:58:58 +00001598% o cli_wand: structure holding settings and images to be operated on
anthony805a2d42011-09-25 08:25:12 +00001599%
anthonyfd706f92012-01-19 04:22:02 +00001600% o option: The option string for the operation
anthonydcf510d2011-10-30 13:51:40 +00001601%
anthonyfd706f92012-01-19 04:22:02 +00001602% o arg1, arg2: optional argument strings to the operation
anthony805a2d42011-09-25 08:25:12 +00001603%
anthony31f1bf72012-01-30 12:37:22 +00001604% Any problems will be added to the 'exception' entry of the given wand.
anthony805a2d42011-09-25 08:25:12 +00001605%
anthony31f1bf72012-01-30 12:37:22 +00001606% Example usage...
anthonydcf510d2011-10-30 13:51:40 +00001607%
anthonyafa3dfc2012-03-03 11:31:30 +00001608% CLISimpleOperatorImages(cli_wand, "-crop","100x100+20+30",NULL);
1609% CLISimpleOperatorImages(cli_wand, "+repage",NULL,NULL);
1610% CLISimpleOperatorImages(cli_wand, "+distort","SRT","45");
anthonyfd706f92012-01-19 04:22:02 +00001611%
anthony24aa8822012-03-11 00:56:06 +00001612% Or for handling command line arguments EG: +/-option ["arg1"]
anthonydcf510d2011-10-30 13:51:40 +00001613%
anthony43f425d2012-02-26 12:58:58 +00001614% cli_wand
anthonydcf510d2011-10-30 13:51:40 +00001615% argc,argv
1616% i=index in argv
1617%
anthony2052d272012-02-28 12:48:29 +00001618% option_info = GetCommandOptionInfo(argv[i]);
1619% count=option_info->type;
1620% option_type=option_info->flags;
1621%
1622% if ( (option_type & SimpleOperatorOptionFlag) != 0 )
anthonyafa3dfc2012-03-03 11:31:30 +00001623% CLISimpleOperatorImages(cli_wand, argv[i],
anthonyfd706f92012-01-19 04:22:02 +00001624% count>=1 ? argv[i+1] : (char *)NULL,
1625% count>=2 ? argv[i+2] : (char *)NULL );
anthonydcf510d2011-10-30 13:51:40 +00001626% i += count+1;
1627%
anthony805a2d42011-09-25 08:25:12 +00001628*/
anthony31f1bf72012-01-30 12:37:22 +00001629
1630/*
1631 Internal subrountine to apply one simple image operation to the current
anthony43f425d2012-02-26 12:58:58 +00001632 image pointed to by the CLI wand.
anthony31f1bf72012-01-30 12:37:22 +00001633
1634 The image in the list may be modified in three different ways...
1635 * directly modified (EG: -negate, -gamma, -level, -annotate, -draw),
1636 * replaced by a new image (EG: -spread, -resize, -rotate, -morphology)
1637 * one image replace by a list of images (-separate and -crop only!)
1638
anthonyafa3dfc2012-03-03 11:31:30 +00001639 In each case the result replaces the single original image in the list, as
1640 well as the pointer to the modified image (last image added if replaced by a
1641 list of images) is returned.
anthony31f1bf72012-01-30 12:37:22 +00001642
1643 As the image pointed to may be replaced, the first image in the list may
1644 also change. GetFirstImageInList() should be used by caller if they wish
1645 return the Image pointer to the first image in list.
1646*/
anthony43f425d2012-02-26 12:58:58 +00001647static void CLISimpleOperatorImage(MagickCLI *cli_wand,
anthonyafa3dfc2012-03-03 11:31:30 +00001648 const char *option, const char *arg1, const char *arg2)
anthony805a2d42011-09-25 08:25:12 +00001649{
1650 Image *
1651 new_image;
1652
anthony805a2d42011-09-25 08:25:12 +00001653 GeometryInfo
1654 geometry_info;
1655
1656 RectangleInfo
1657 geometry;
1658
1659 MagickStatusType
anthony805a2d42011-09-25 08:25:12 +00001660 flags;
1661
anthony92c93bd2012-03-19 14:02:47 +00001662 ssize_t
anthony2a0ec8c2012-03-24 04:35:56 +00001663 parse;
anthony92c93bd2012-03-19 14:02:47 +00001664
anthony2e4501b2012-03-30 04:41:54 +00001665#define _image_info (cli_wand->wand.image_info)
1666#define _image (cli_wand->wand.images)
1667#define _exception (cli_wand->wand.exception)
1668#define _draw_info (cli_wand->draw_info)
1669#define _quantize_info (cli_wand->quantize_info)
anthonyafa3dfc2012-03-03 11:31:30 +00001670#define IfNormalOp (*option=='-')
1671#define IfPlusOp (*option!='-')
anthony7bcfe7f2012-03-30 14:01:22 +00001672#define normal_op IsMagickTrue(IfNormalOp)
1673#define plus_alt_op IsMagickFalse(IfNormalOp)
anthonyfd706f92012-01-19 04:22:02 +00001674
anthony43f425d2012-02-26 12:58:58 +00001675 assert(cli_wand != (MagickCLI *) NULL);
1676 assert(cli_wand->signature == WandSignature);
1677 assert(cli_wand->wand.signature == WandSignature);
anthony5330ae02012-03-20 14:17:01 +00001678 assert(_image != (Image *) NULL); /* an image must be present */
anthony7bcfe7f2012-03-30 14:01:22 +00001679 if (IfMagickTrue(cli_wand->wand.debug))
anthony43f425d2012-02-26 12:58:58 +00001680 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
anthonydcf510d2011-10-30 13:51:40 +00001681
anthony92c93bd2012-03-19 14:02:47 +00001682 (void) SyncImageSettings(_image_info,_image,_exception);
anthony24aa8822012-03-11 00:56:06 +00001683
anthony805a2d42011-09-25 08:25:12 +00001684 SetGeometryInfo(&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00001685
anthony5330ae02012-03-20 14:17:01 +00001686 new_image = (Image *)NULL; /* the replacement image, if not null at end */
anthony805a2d42011-09-25 08:25:12 +00001687
anthonyfd706f92012-01-19 04:22:02 +00001688 /* FUTURE: We may need somthing a little more optimized than this!
1689 Perhaps, do the 'sync' if 'settings tainted' before next operator.
1690 */
anthonyafa3dfc2012-03-03 11:31:30 +00001691 switch (*(option+1))
anthony805a2d42011-09-25 08:25:12 +00001692 {
1693 case 'a':
1694 {
anthonyafa3dfc2012-03-03 11:31:30 +00001695 if (LocaleCompare("adaptive-blur",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001696 {
anthonyfd706f92012-01-19 04:22:02 +00001697 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00001698 if ((flags & (RhoValue|SigmaValue)) == 0)
1699 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00001700 if ((flags & SigmaValue) == 0)
1701 geometry_info.sigma=1.0;
anthony92c93bd2012-03-19 14:02:47 +00001702 new_image=AdaptiveBlurImage(_image,geometry_info.rho,
cristyaa2c16c2012-03-25 22:21:35 +00001703 geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00001704 break;
1705 }
anthonyafa3dfc2012-03-03 11:31:30 +00001706 if (LocaleCompare("adaptive-resize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001707 {
anthonyfe1aa782012-03-24 13:43:04 +00001708 /* FUTURE: Roll into a resize special operator */
anthony7bcfe7f2012-03-30 14:01:22 +00001709 if (IfMagickFalse(IsGeometry(arg1)))
anthony92c93bd2012-03-19 14:02:47 +00001710 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1711 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
1712 new_image=AdaptiveResizeImage(_image,geometry.width,geometry.height,
cristyaa2c16c2012-03-25 22:21:35 +00001713 _exception);
anthony805a2d42011-09-25 08:25:12 +00001714 break;
1715 }
anthonyafa3dfc2012-03-03 11:31:30 +00001716 if (LocaleCompare("adaptive-sharpen",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001717 {
anthonyfd706f92012-01-19 04:22:02 +00001718 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00001719 if ((flags & (RhoValue|SigmaValue)) == 0)
1720 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00001721 if ((flags & SigmaValue) == 0)
1722 geometry_info.sigma=1.0;
anthony92c93bd2012-03-19 14:02:47 +00001723 new_image=AdaptiveSharpenImage(_image,geometry_info.rho,
cristyaa2c16c2012-03-25 22:21:35 +00001724 geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00001725 break;
1726 }
anthonyafa3dfc2012-03-03 11:31:30 +00001727 if (LocaleCompare("alpha",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001728 {
anthony2a0ec8c2012-03-24 04:35:56 +00001729 parse=ParseCommandOption(MagickAlphaOptions,MagickFalse,arg1);
1730 if (parse < 0)
anthony92c93bd2012-03-19 14:02:47 +00001731 CLIWandExceptArgBreak(OptionError,"UnrecognizedAlphaChannelType",
1732 option,arg1);
anthony2a0ec8c2012-03-24 04:35:56 +00001733 (void) SetImageAlphaChannel(_image,(AlphaChannelType)parse,
1734 _exception);
anthony805a2d42011-09-25 08:25:12 +00001735 break;
1736 }
anthonyafa3dfc2012-03-03 11:31:30 +00001737 if (LocaleCompare("annotate",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001738 {
1739 char
1740 *text,
1741 geometry[MaxTextExtent];
1742
anthony805a2d42011-09-25 08:25:12 +00001743 SetGeometryInfo(&geometry_info);
anthonyfd706f92012-01-19 04:22:02 +00001744 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00001745 if ((flags & RhoValue) == 0)
1746 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00001747 if ((flags & SigmaValue) == 0)
1748 geometry_info.sigma=geometry_info.rho;
anthony92c93bd2012-03-19 14:02:47 +00001749 text=InterpretImageProperties(_image_info,_image,arg2,
1750 _exception);
anthony805a2d42011-09-25 08:25:12 +00001751 if (text == (char *) NULL)
1752 break;
anthony92c93bd2012-03-19 14:02:47 +00001753 (void) CloneString(&_draw_info->text,text);
anthony805a2d42011-09-25 08:25:12 +00001754 text=DestroyString(text);
1755 (void) FormatLocaleString(geometry,MaxTextExtent,"%+f%+f",
1756 geometry_info.xi,geometry_info.psi);
anthony92c93bd2012-03-19 14:02:47 +00001757 (void) CloneString(&_draw_info->geometry,geometry);
1758 _draw_info->affine.sx=cos(DegreesToRadians(
anthony805a2d42011-09-25 08:25:12 +00001759 fmod(geometry_info.rho,360.0)));
anthony92c93bd2012-03-19 14:02:47 +00001760 _draw_info->affine.rx=sin(DegreesToRadians(
anthony805a2d42011-09-25 08:25:12 +00001761 fmod(geometry_info.rho,360.0)));
anthony92c93bd2012-03-19 14:02:47 +00001762 _draw_info->affine.ry=(-sin(DegreesToRadians(
anthony805a2d42011-09-25 08:25:12 +00001763 fmod(geometry_info.sigma,360.0))));
anthony92c93bd2012-03-19 14:02:47 +00001764 _draw_info->affine.sy=cos(DegreesToRadians(
anthony805a2d42011-09-25 08:25:12 +00001765 fmod(geometry_info.sigma,360.0)));
anthony92c93bd2012-03-19 14:02:47 +00001766 (void) AnnotateImage(_image,_draw_info,_exception);
1767 GetAffineMatrix(&_draw_info->affine);
anthony805a2d42011-09-25 08:25:12 +00001768 break;
1769 }
anthonyafa3dfc2012-03-03 11:31:30 +00001770 if (LocaleCompare("auto-gamma",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001771 {
anthony92c93bd2012-03-19 14:02:47 +00001772 (void) AutoGammaImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00001773 break;
1774 }
anthonyafa3dfc2012-03-03 11:31:30 +00001775 if (LocaleCompare("auto-level",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001776 {
anthony92c93bd2012-03-19 14:02:47 +00001777 (void) AutoLevelImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00001778 break;
1779 }
anthonyafa3dfc2012-03-03 11:31:30 +00001780 if (LocaleCompare("auto-orient",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001781 {
anthony5330ae02012-03-20 14:17:01 +00001782 /* This should probably be a MagickCore function */
anthony92c93bd2012-03-19 14:02:47 +00001783 switch (_image->orientation)
anthony805a2d42011-09-25 08:25:12 +00001784 {
1785 case TopRightOrientation:
1786 {
anthony92c93bd2012-03-19 14:02:47 +00001787 new_image=FlopImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00001788 break;
1789 }
1790 case BottomRightOrientation:
1791 {
anthony92c93bd2012-03-19 14:02:47 +00001792 new_image=RotateImage(_image,180.0,_exception);
anthony805a2d42011-09-25 08:25:12 +00001793 break;
1794 }
1795 case BottomLeftOrientation:
1796 {
anthony92c93bd2012-03-19 14:02:47 +00001797 new_image=FlipImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00001798 break;
1799 }
1800 case LeftTopOrientation:
1801 {
anthony92c93bd2012-03-19 14:02:47 +00001802 new_image=TransposeImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00001803 break;
1804 }
1805 case RightTopOrientation:
1806 {
anthony92c93bd2012-03-19 14:02:47 +00001807 new_image=RotateImage(_image,90.0,_exception);
anthony805a2d42011-09-25 08:25:12 +00001808 break;
1809 }
1810 case RightBottomOrientation:
1811 {
anthony92c93bd2012-03-19 14:02:47 +00001812 new_image=TransverseImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00001813 break;
1814 }
1815 case LeftBottomOrientation:
1816 {
anthony92c93bd2012-03-19 14:02:47 +00001817 new_image=RotateImage(_image,270.0,_exception);
anthony805a2d42011-09-25 08:25:12 +00001818 break;
1819 }
1820 default:
1821 break;
1822 }
1823 if (new_image != (Image *) NULL)
1824 new_image->orientation=TopLeftOrientation;
1825 break;
1826 }
anthonyebb73a22012-03-22 14:25:52 +00001827 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001828 }
1829 case 'b':
1830 {
anthonyafa3dfc2012-03-03 11:31:30 +00001831 if (LocaleCompare("black-threshold",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001832 {
anthony7bcfe7f2012-03-30 14:01:22 +00001833 if (IfMagickFalse(IsGeometry(arg1)))
anthony5330ae02012-03-20 14:17:01 +00001834 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001835 (void) BlackThresholdImage(_image,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00001836 break;
1837 }
anthonyafa3dfc2012-03-03 11:31:30 +00001838 if (LocaleCompare("blue-shift",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001839 {
anthony805a2d42011-09-25 08:25:12 +00001840 geometry_info.rho=1.5;
anthony5330ae02012-03-20 14:17:01 +00001841 if (IfNormalOp) {
anthonyfd706f92012-01-19 04:22:02 +00001842 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00001843 if ((flags & RhoValue) == 0)
1844 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony5330ae02012-03-20 14:17:01 +00001845 }
anthony92c93bd2012-03-19 14:02:47 +00001846 new_image=BlueShiftImage(_image,geometry_info.rho,_exception);
anthony805a2d42011-09-25 08:25:12 +00001847 break;
1848 }
anthonyafa3dfc2012-03-03 11:31:30 +00001849 if (LocaleCompare("blur",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001850 {
anthonyfd706f92012-01-19 04:22:02 +00001851 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00001852 if ((flags & (RhoValue|SigmaValue)) == 0)
1853 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00001854 if ((flags & SigmaValue) == 0)
1855 geometry_info.sigma=1.0;
cristyaa2c16c2012-03-25 22:21:35 +00001856 new_image=BlurImage(_image,geometry_info.rho,geometry_info.sigma,
1857 _exception);
anthony805a2d42011-09-25 08:25:12 +00001858 break;
1859 }
anthonyafa3dfc2012-03-03 11:31:30 +00001860 if (LocaleCompare("border",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001861 {
anthony31f1bf72012-01-30 12:37:22 +00001862 CompositeOperator
anthony5f867ae2011-10-09 10:28:34 +00001863 compose;
1864
1865 const char*
anthony5f867ae2011-10-09 10:28:34 +00001866 value;
1867
anthony22de2722012-04-19 14:43:00 +00001868 flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
1869 if ((flags & RhoValue) == 0)
anthony5330ae02012-03-20 14:17:01 +00001870 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony22de2722012-04-19 14:43:00 +00001871 if ((flags & SigmaValue) == 0)
1872 geometry.height=geometry.width;
anthony5330ae02012-03-20 14:17:01 +00001873
anthony92c93bd2012-03-19 14:02:47 +00001874 value=GetImageOption(_image_info,"compose");
anthony5f867ae2011-10-09 10:28:34 +00001875 if (value != (const char *) NULL)
1876 compose=(CompositeOperator) ParseCommandOption(
1877 MagickComposeOptions,MagickFalse,value);
1878 else
anthony92c93bd2012-03-19 14:02:47 +00001879 compose=OverCompositeOp; /* use Over not _image->compose */
anthony5f867ae2011-10-09 10:28:34 +00001880
anthony92c93bd2012-03-19 14:02:47 +00001881 new_image=BorderImage(_image,&geometry,compose,_exception);
anthony805a2d42011-09-25 08:25:12 +00001882 break;
1883 }
anthonyafa3dfc2012-03-03 11:31:30 +00001884 if (LocaleCompare("brightness-contrast",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001885 {
1886 double
1887 brightness,
1888 contrast;
1889
1890 GeometryInfo
1891 geometry_info;
1892
1893 MagickStatusType
1894 flags;
1895
anthonyfd706f92012-01-19 04:22:02 +00001896 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00001897 if ((flags & RhoValue) == 0)
1898 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00001899 brightness=geometry_info.rho;
1900 contrast=0.0;
1901 if ((flags & SigmaValue) != 0)
1902 contrast=geometry_info.sigma;
anthony92c93bd2012-03-19 14:02:47 +00001903 (void) BrightnessContrastImage(_image,brightness,contrast,
1904 _exception);
anthony805a2d42011-09-25 08:25:12 +00001905 break;
1906 }
anthonyebb73a22012-03-22 14:25:52 +00001907 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001908 }
1909 case 'c':
1910 {
anthonyafa3dfc2012-03-03 11:31:30 +00001911 if (LocaleCompare("cdl",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001912 {
1913 char
1914 *color_correction_collection;
1915
1916 /*
1917 Color correct with a color decision list.
1918 */
anthony92c93bd2012-03-19 14:02:47 +00001919 color_correction_collection=FileToString(arg1,~0,_exception);
anthony805a2d42011-09-25 08:25:12 +00001920 if (color_correction_collection == (char *) NULL)
1921 break;
anthony92c93bd2012-03-19 14:02:47 +00001922 (void) ColorDecisionListImage(_image,color_correction_collection,
1923 _exception);
anthony805a2d42011-09-25 08:25:12 +00001924 break;
1925 }
anthonyafa3dfc2012-03-03 11:31:30 +00001926 if (LocaleCompare("charcoal",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001927 {
anthonyfd706f92012-01-19 04:22:02 +00001928 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00001929 if ((flags & (RhoValue|SigmaValue)) == 0)
1930 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00001931 if ((flags & SigmaValue) == 0)
1932 geometry_info.sigma=1.0;
1933 if ((flags & XiValue) == 0)
1934 geometry_info.xi=1.0;
anthony92c93bd2012-03-19 14:02:47 +00001935 new_image=CharcoalImage(_image,geometry_info.rho,
cristyaa2c16c2012-03-25 22:21:35 +00001936 geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00001937 break;
1938 }
anthonyafa3dfc2012-03-03 11:31:30 +00001939 if (LocaleCompare("chop",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001940 {
anthony7bcfe7f2012-03-30 14:01:22 +00001941 if (IfMagickFalse(IsGeometry(arg1)))
anthony5330ae02012-03-20 14:17:01 +00001942 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001943 (void) ParseGravityGeometry(_image,arg1,&geometry,_exception);
1944 new_image=ChopImage(_image,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00001945 break;
1946 }
anthonyafa3dfc2012-03-03 11:31:30 +00001947 if (LocaleCompare("clamp",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001948 {
anthony92c93bd2012-03-19 14:02:47 +00001949 (void) ClampImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00001950 break;
1951 }
anthonyafa3dfc2012-03-03 11:31:30 +00001952 if (LocaleCompare("clip",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001953 {
anthonyafa3dfc2012-03-03 11:31:30 +00001954 if (IfNormalOp)
anthony92c93bd2012-03-19 14:02:47 +00001955 (void) ClipImage(_image,_exception);
anthony43f425d2012-02-26 12:58:58 +00001956 else /* "+mask" remove the write mask */
anthony92c93bd2012-03-19 14:02:47 +00001957 (void) SetImageMask(_image,(Image *) NULL,_exception);
anthony805a2d42011-09-25 08:25:12 +00001958 break;
1959 }
anthonyafa3dfc2012-03-03 11:31:30 +00001960 if (LocaleCompare("clip-mask",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001961 {
1962 CacheView
1963 *mask_view;
1964
1965 Image
1966 *mask_image;
1967
1968 register Quantum
1969 *restrict q;
1970
1971 register ssize_t
1972 x;
1973
1974 ssize_t
1975 y;
1976
anthonyafa3dfc2012-03-03 11:31:30 +00001977 if (IfPlusOp) {
1978 /* "+clip-mask" Remove the write mask */
anthony92c93bd2012-03-19 14:02:47 +00001979 (void) SetImageMask(_image,(Image *) NULL,_exception);
anthonyafa3dfc2012-03-03 11:31:30 +00001980 break;
1981 }
anthony92c93bd2012-03-19 14:02:47 +00001982 mask_image=GetImageCache(_image_info,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00001983 if (mask_image == (Image *) NULL)
1984 break;
anthony7bcfe7f2012-03-30 14:01:22 +00001985 if (IfMagickFalse(SetImageStorageClass(mask_image,DirectClass,_exception)))
anthony31f1bf72012-01-30 12:37:22 +00001986 break;
anthony5330ae02012-03-20 14:17:01 +00001987 /* Create a write mask from cli_wand mask image */
anthonyfd706f92012-01-19 04:22:02 +00001988 /* FUTURE: use Alpha operations instead and create a Grey Image */
cristydb070952012-04-20 14:33:00 +00001989 mask_view=AcquireAuthenticCacheView(mask_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00001990 for (y=0; y < (ssize_t) mask_image->rows; y++)
1991 {
1992 q=GetCacheViewAuthenticPixels(mask_view,0,y,mask_image->columns,1,
anthony92c93bd2012-03-19 14:02:47 +00001993 _exception);
anthony805a2d42011-09-25 08:25:12 +00001994 if (q == (Quantum *) NULL)
1995 break;
1996 for (x=0; x < (ssize_t) mask_image->columns; x++)
1997 {
anthony7bcfe7f2012-03-30 14:01:22 +00001998 if (IfMagickFalse(mask_image->matte))
anthony805a2d42011-09-25 08:25:12 +00001999 SetPixelAlpha(mask_image,GetPixelIntensity(mask_image,q),q);
2000 SetPixelRed(mask_image,GetPixelAlpha(mask_image,q),q);
2001 SetPixelGreen(mask_image,GetPixelAlpha(mask_image,q),q);
2002 SetPixelBlue(mask_image,GetPixelAlpha(mask_image,q),q);
2003 q+=GetPixelChannels(mask_image);
2004 }
anthony7bcfe7f2012-03-30 14:01:22 +00002005 if (IfMagickFalse(SyncCacheViewAuthenticPixels(mask_view,_exception)))
anthony805a2d42011-09-25 08:25:12 +00002006 break;
2007 }
anthonyfd706f92012-01-19 04:22:02 +00002008 /* clean up and set the write mask */
anthony805a2d42011-09-25 08:25:12 +00002009 mask_view=DestroyCacheView(mask_view);
2010 mask_image->matte=MagickTrue;
anthony92c93bd2012-03-19 14:02:47 +00002011 (void) SetImageMask(_image,mask_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002012 mask_image=DestroyImage(mask_image);
anthony805a2d42011-09-25 08:25:12 +00002013 break;
2014 }
anthonyafa3dfc2012-03-03 11:31:30 +00002015 if (LocaleCompare("clip-path",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002016 {
anthony92c93bd2012-03-19 14:02:47 +00002017 (void) ClipImagePath(_image,arg1,normal_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00002018 break;
2019 }
anthonyafa3dfc2012-03-03 11:31:30 +00002020 if (LocaleCompare("colorize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002021 {
anthony7bcfe7f2012-03-30 14:01:22 +00002022 if (IfMagickFalse(IsGeometry(arg1)))
anthony5330ae02012-03-20 14:17:01 +00002023 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002024 new_image=ColorizeImage(_image,arg1,&_draw_info->fill,_exception);
anthony805a2d42011-09-25 08:25:12 +00002025 break;
2026 }
anthonyafa3dfc2012-03-03 11:31:30 +00002027 if (LocaleCompare("color-matrix",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002028 {
2029 KernelInfo
2030 *kernel;
2031
anthonyfd706f92012-01-19 04:22:02 +00002032 kernel=AcquireKernelInfo(arg1);
anthony805a2d42011-09-25 08:25:12 +00002033 if (kernel == (KernelInfo *) NULL)
anthony5330ae02012-03-20 14:17:01 +00002034 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002035 new_image=ColorMatrixImage(_image,kernel,_exception);
anthony805a2d42011-09-25 08:25:12 +00002036 kernel=DestroyKernelInfo(kernel);
2037 break;
2038 }
anthonyafa3dfc2012-03-03 11:31:30 +00002039 if (LocaleCompare("colors",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002040 {
anthony5330ae02012-03-20 14:17:01 +00002041 /* Reduce the number of colors in the image.
2042 FUTURE: also provide 'plus version with image 'color counts'
anthonyfd706f92012-01-19 04:22:02 +00002043 */
anthony92c93bd2012-03-19 14:02:47 +00002044 _quantize_info->number_colors=StringToUnsignedLong(arg1);
2045 if (_quantize_info->number_colors == 0)
anthony5330ae02012-03-20 14:17:01 +00002046 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002047 if ((_image->storage_class == DirectClass) ||
2048 _image->colors > _quantize_info->number_colors)
2049 (void) QuantizeImage(_quantize_info,_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002050 else
anthony92c93bd2012-03-19 14:02:47 +00002051 (void) CompressImageColormap(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002052 break;
2053 }
anthonyafa3dfc2012-03-03 11:31:30 +00002054 if (LocaleCompare("colorspace",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002055 {
anthony5330ae02012-03-20 14:17:01 +00002056 /* WARNING: this is both a image_info setting (already done)
2057 and a operator to change image colorspace.
anthony31f1bf72012-01-30 12:37:22 +00002058
2059 FUTURE: default colorspace should be sRGB!
anthonyd2cdc862011-10-07 14:07:17 +00002060 Unless some type of 'linear colorspace' mode is set.
anthony31f1bf72012-01-30 12:37:22 +00002061
anthonyd2cdc862011-10-07 14:07:17 +00002062 Note that +colorspace sets "undefined" or no effect on
2063 new images, but forces images already in memory back to RGB!
anthony31f1bf72012-01-30 12:37:22 +00002064 That seems to be a little strange!
anthonyd2cdc862011-10-07 14:07:17 +00002065 */
anthony92c93bd2012-03-19 14:02:47 +00002066 (void) TransformImageColorspace(_image,
2067 IfNormalOp ? _image_info->colorspace : RGBColorspace,
2068 _exception);
anthony805a2d42011-09-25 08:25:12 +00002069 break;
2070 }
anthonyafa3dfc2012-03-03 11:31:30 +00002071 if (LocaleCompare("contrast",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002072 {
anthony975a8d72012-04-12 13:54:36 +00002073 CLIWandWarnDepreciated(normal_op?"-level":"+level");
anthony92c93bd2012-03-19 14:02:47 +00002074 (void) ContrastImage(_image,normal_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00002075 break;
2076 }
anthonyafa3dfc2012-03-03 11:31:30 +00002077 if (LocaleCompare("contrast-stretch",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002078 {
2079 double
2080 black_point,
2081 white_point;
2082
2083 MagickStatusType
2084 flags;
2085
anthonyfd706f92012-01-19 04:22:02 +00002086 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00002087 if ((flags & RhoValue) == 0)
2088 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00002089 black_point=geometry_info.rho;
2090 white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
2091 black_point;
anthonyebb73a22012-03-22 14:25:52 +00002092 if ((flags & PercentValue) != 0) {
anthony92c93bd2012-03-19 14:02:47 +00002093 black_point*=(double) _image->columns*_image->rows/100.0;
2094 white_point*=(double) _image->columns*_image->rows/100.0;
anthony805a2d42011-09-25 08:25:12 +00002095 }
anthony92c93bd2012-03-19 14:02:47 +00002096 white_point=(MagickRealType) _image->columns*_image->rows-
anthony805a2d42011-09-25 08:25:12 +00002097 white_point;
anthony92c93bd2012-03-19 14:02:47 +00002098 (void) ContrastStretchImage(_image,black_point,white_point,
2099 _exception);
anthony805a2d42011-09-25 08:25:12 +00002100 break;
2101 }
anthonyafa3dfc2012-03-03 11:31:30 +00002102 if (LocaleCompare("convolve",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002103 {
2104 KernelInfo
2105 *kernel_info;
2106
anthonyfd706f92012-01-19 04:22:02 +00002107 kernel_info=AcquireKernelInfo(arg1);
anthony805a2d42011-09-25 08:25:12 +00002108 if (kernel_info == (KernelInfo *) NULL)
anthonyebb73a22012-03-22 14:25:52 +00002109 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony22de2722012-04-19 14:43:00 +00002110 new_image=MorphologyImage(_image,ConvolveMorphology,1,kernel_info,
2111 _exception);
anthony805a2d42011-09-25 08:25:12 +00002112 kernel_info=DestroyKernelInfo(kernel_info);
2113 break;
2114 }
anthonyafa3dfc2012-03-03 11:31:30 +00002115 if (LocaleCompare("crop",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002116 {
anthony31f1bf72012-01-30 12:37:22 +00002117 /* WARNING: This can generate multiple images! */
anthony7bcfe7f2012-03-30 14:01:22 +00002118 if (IfMagickFalse(IsGeometry(arg1)))
anthonyebb73a22012-03-22 14:25:52 +00002119 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002120 new_image=CropImageToTiles(_image,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00002121 break;
2122 }
anthonyafa3dfc2012-03-03 11:31:30 +00002123 if (LocaleCompare("cycle",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002124 {
anthony7bcfe7f2012-03-30 14:01:22 +00002125 if (IfMagickFalse(IsGeometry(arg1)))
anthonyebb73a22012-03-22 14:25:52 +00002126 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002127 (void) CycleColormapImage(_image,(ssize_t) StringToLong(arg1),
2128 _exception);
anthony805a2d42011-09-25 08:25:12 +00002129 break;
2130 }
anthonyebb73a22012-03-22 14:25:52 +00002131 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002132 }
2133 case 'd':
2134 {
anthonyafa3dfc2012-03-03 11:31:30 +00002135 if (LocaleCompare("decipher",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002136 {
2137 StringInfo
2138 *passkey;
2139
anthony92c93bd2012-03-19 14:02:47 +00002140 passkey=FileToStringInfo(arg1,~0,_exception);
anthonyebb73a22012-03-22 14:25:52 +00002141 if (passkey == (StringInfo *) NULL)
2142 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2143
2144 (void) PasskeyDecipherImage(_image,passkey,_exception);
2145 passkey=DestroyStringInfo(passkey);
anthony805a2d42011-09-25 08:25:12 +00002146 break;
2147 }
anthonyafa3dfc2012-03-03 11:31:30 +00002148 if (LocaleCompare("depth",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002149 {
anthony92c93bd2012-03-19 14:02:47 +00002150 /* The _image_info->depth setting has already been set
anthonydcf510d2011-10-30 13:51:40 +00002151 We just need to apply it to all images in current sequence
anthony31f1bf72012-01-30 12:37:22 +00002152
anthonydcf510d2011-10-30 13:51:40 +00002153 WARNING: Depth from 8 to 16 causes 'quantum rounding to images!
2154 That is it really is an operation, not a setting! Arrgghhh
anthony31f1bf72012-01-30 12:37:22 +00002155
anthonyfd706f92012-01-19 04:22:02 +00002156 FUTURE: this should not be an operator!!!
anthonydcf510d2011-10-30 13:51:40 +00002157 */
anthony92c93bd2012-03-19 14:02:47 +00002158 (void) SetImageDepth(_image,_image_info->depth,_exception);
anthony805a2d42011-09-25 08:25:12 +00002159 break;
2160 }
anthonyafa3dfc2012-03-03 11:31:30 +00002161 if (LocaleCompare("deskew",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002162 {
2163 double
2164 threshold;
2165
anthonyebb73a22012-03-22 14:25:52 +00002166 if (IfNormalOp) {
anthony7bcfe7f2012-03-30 14:01:22 +00002167 if (IfMagickFalse(IsGeometry(arg1)))
anthonyebb73a22012-03-22 14:25:52 +00002168 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00002169 threshold=StringToDoubleInterval(arg1,(double) QuantumRange+1.0);
anthonyebb73a22012-03-22 14:25:52 +00002170 }
anthonyafa3dfc2012-03-03 11:31:30 +00002171 else
2172 threshold=40.0*QuantumRange/100.0;
anthony92c93bd2012-03-19 14:02:47 +00002173 new_image=DeskewImage(_image,threshold,_exception);
anthony805a2d42011-09-25 08:25:12 +00002174 break;
2175 }
anthonyafa3dfc2012-03-03 11:31:30 +00002176 if (LocaleCompare("despeckle",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002177 {
anthony92c93bd2012-03-19 14:02:47 +00002178 new_image=DespeckleImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002179 break;
2180 }
anthonyafa3dfc2012-03-03 11:31:30 +00002181 if (LocaleCompare("distort",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002182 {
2183 char
anthonyb1d483a2012-04-14 12:53:56 +00002184 *arg;
anthony805a2d42011-09-25 08:25:12 +00002185
anthony805a2d42011-09-25 08:25:12 +00002186 double
anthonyb1d483a2012-04-14 12:53:56 +00002187 *args;
anthony805a2d42011-09-25 08:25:12 +00002188
anthonyb1d483a2012-04-14 12:53:56 +00002189 ssize_t
2190 count;
anthony805a2d42011-09-25 08:25:12 +00002191
anthony2a0ec8c2012-03-24 04:35:56 +00002192 parse = ParseCommandOption(MagickDistortOptions,MagickFalse,arg1);
2193 if ( parse < 0 )
anthonyebb73a22012-03-22 14:25:52 +00002194 CLIWandExceptArgBreak(OptionError,"UnrecognizedDistortMethod",
2195 option,arg1);
anthony2a0ec8c2012-03-24 04:35:56 +00002196 if ((DistortImageMethod) parse == ResizeDistortion)
anthony805a2d42011-09-25 08:25:12 +00002197 {
anthony80c37752012-01-16 01:03:11 +00002198 double
2199 resize_args[2];
anthony805a2d42011-09-25 08:25:12 +00002200 /* Special Case - Argument is actually a resize geometry!
2201 ** Convert that to an appropriate distortion argument array.
anthonyfd706f92012-01-19 04:22:02 +00002202 ** FUTURE: make a separate special resize operator
anthonyfe1aa782012-03-24 13:43:04 +00002203 Roll into a resize special operator */
anthony7bcfe7f2012-03-30 14:01:22 +00002204 if (IfMagickFalse(IsGeometry(arg2)))
anthonyebb73a22012-03-22 14:25:52 +00002205 CLIWandExceptArgBreak(OptionError,"InvalidGeometry",
2206 option,arg2);
2207 (void) ParseRegionGeometry(_image,arg2,&geometry,_exception);
anthony80c37752012-01-16 01:03:11 +00002208 resize_args[0]=(double) geometry.width;
2209 resize_args[1]=(double) geometry.height;
anthony2a0ec8c2012-03-24 04:35:56 +00002210 new_image=DistortImage(_image,(DistortImageMethod) parse,
2211 (size_t)2,resize_args,MagickTrue,_exception);
anthony805a2d42011-09-25 08:25:12 +00002212 break;
2213 }
anthonyb1d483a2012-04-14 12:53:56 +00002214 /* allow percent escapes in argument string */
2215 arg=InterpretImageProperties(_image_info,_image,arg2,_exception);
2216 if (arg == (char *) NULL)
anthony805a2d42011-09-25 08:25:12 +00002217 break;
anthonyb1d483a2012-04-14 12:53:56 +00002218 /* convert argument string into an array of doubles */
2219 args = StringToArrayOfDoubles(arg,&count,_exception);
2220 arg=DestroyString(arg);
2221 if (args == (double *)NULL )
2222 CLIWandExceptArgBreak(OptionError,"InvalidNumberList",option,arg2);
2223
2224 new_image=DistortImage(_image,(DistortImageMethod) parse,count,args,
2225 plus_alt_op,_exception);
2226 args=(double *) RelinquishMagickMemory(args);
anthony805a2d42011-09-25 08:25:12 +00002227 break;
2228 }
anthonyafa3dfc2012-03-03 11:31:30 +00002229 if (LocaleCompare("draw",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002230 {
anthony92c93bd2012-03-19 14:02:47 +00002231 (void) CloneString(&_draw_info->primitive,arg1);
2232 (void) DrawImage(_image,_draw_info,_exception);
2233 (void) CloneString(&_draw_info->primitive,(char *)NULL);
anthony805a2d42011-09-25 08:25:12 +00002234 break;
2235 }
anthonyebb73a22012-03-22 14:25:52 +00002236 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002237 }
2238 case 'e':
2239 {
anthonyafa3dfc2012-03-03 11:31:30 +00002240 if (LocaleCompare("edge",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002241 {
anthonyfd706f92012-01-19 04:22:02 +00002242 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00002243 if ((flags & (RhoValue|SigmaValue)) == 0)
2244 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00002245 if ((flags & SigmaValue) == 0)
2246 geometry_info.sigma=1.0;
anthony2a0ec8c2012-03-24 04:35:56 +00002247 new_image=EdgeImage(_image,geometry_info.rho,geometry_info.sigma,
2248 _exception);
anthony805a2d42011-09-25 08:25:12 +00002249 break;
2250 }
anthonyafa3dfc2012-03-03 11:31:30 +00002251 if (LocaleCompare("emboss",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002252 {
anthonyfd706f92012-01-19 04:22:02 +00002253 flags=ParseGeometry(arg1,&geometry_info);
anthonyb1e21ed2012-04-20 12:43:12 +00002254 if ((flags & (RhoValue|SigmaValue)) == 0)
2255 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00002256 if ((flags & SigmaValue) == 0)
2257 geometry_info.sigma=1.0;
anthony92c93bd2012-03-19 14:02:47 +00002258 new_image=EmbossImage(_image,geometry_info.rho,
2259 geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00002260 break;
2261 }
anthonyafa3dfc2012-03-03 11:31:30 +00002262 if (LocaleCompare("encipher",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002263 {
2264 StringInfo
2265 *passkey;
2266
anthony92c93bd2012-03-19 14:02:47 +00002267 passkey=FileToStringInfo(arg1,~0,_exception);
anthony805a2d42011-09-25 08:25:12 +00002268 if (passkey != (StringInfo *) NULL)
2269 {
anthony92c93bd2012-03-19 14:02:47 +00002270 (void) PasskeyEncipherImage(_image,passkey,_exception);
anthony805a2d42011-09-25 08:25:12 +00002271 passkey=DestroyStringInfo(passkey);
2272 }
2273 break;
2274 }
anthonyafa3dfc2012-03-03 11:31:30 +00002275 if (LocaleCompare("enhance",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002276 {
anthony92c93bd2012-03-19 14:02:47 +00002277 new_image=EnhanceImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002278 break;
2279 }
anthonyafa3dfc2012-03-03 11:31:30 +00002280 if (LocaleCompare("equalize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002281 {
anthony92c93bd2012-03-19 14:02:47 +00002282 (void) EqualizeImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002283 break;
2284 }
anthonyafa3dfc2012-03-03 11:31:30 +00002285 if (LocaleCompare("evaluate",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002286 {
2287 double
2288 constant;
2289
anthony2a0ec8c2012-03-24 04:35:56 +00002290 parse = ParseCommandOption(MagickEvaluateOptions,MagickFalse,arg1);
2291 if ( parse < 0 )
2292 CLIWandExceptArgBreak(OptionError,"UnrecognizedEvaluateOperator",
2293 option,arg1);
anthony7bcfe7f2012-03-30 14:01:22 +00002294 if (IfMagickFalse(IsGeometry(arg2)))
anthony2a0ec8c2012-03-24 04:35:56 +00002295 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
anthonyfd706f92012-01-19 04:22:02 +00002296 constant=StringToDoubleInterval(arg2,(double) QuantumRange+1.0);
anthony2a0ec8c2012-03-24 04:35:56 +00002297 (void) EvaluateImage(_image,(MagickEvaluateOperator)parse,constant,
2298 _exception);
anthony805a2d42011-09-25 08:25:12 +00002299 break;
2300 }
anthonyafa3dfc2012-03-03 11:31:30 +00002301 if (LocaleCompare("extent",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002302 {
anthony7bcfe7f2012-03-30 14:01:22 +00002303 if (IfMagickFalse(IsGeometry(arg1)))
anthony2a0ec8c2012-03-24 04:35:56 +00002304 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002305 flags=ParseGravityGeometry(_image,arg1,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00002306 if (geometry.width == 0)
anthony92c93bd2012-03-19 14:02:47 +00002307 geometry.width=_image->columns;
anthony805a2d42011-09-25 08:25:12 +00002308 if (geometry.height == 0)
anthony92c93bd2012-03-19 14:02:47 +00002309 geometry.height=_image->rows;
2310 new_image=ExtentImage(_image,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00002311 break;
2312 }
anthonyebb73a22012-03-22 14:25:52 +00002313 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002314 }
2315 case 'f':
2316 {
anthonyafa3dfc2012-03-03 11:31:30 +00002317 if (LocaleCompare("features",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002318 {
anthony31f1bf72012-01-30 12:37:22 +00002319 /* FUTURE: move to SyncImageSettings() and AcqireImage()??? */
anthonyafa3dfc2012-03-03 11:31:30 +00002320 if (IfPlusOp) {
anthony92c93bd2012-03-19 14:02:47 +00002321 (void) DeleteImageArtifact(_image,"identify:features");
anthony31f1bf72012-01-30 12:37:22 +00002322 break;
2323 }
anthony92c93bd2012-03-19 14:02:47 +00002324 (void) SetImageArtifact(_image,"identify:features","true");
2325 (void) SetImageArtifact(_image,"verbose","true");
anthony805a2d42011-09-25 08:25:12 +00002326 break;
2327 }
anthonyafa3dfc2012-03-03 11:31:30 +00002328 if (LocaleCompare("flip",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002329 {
anthony92c93bd2012-03-19 14:02:47 +00002330 new_image=FlipImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002331 break;
2332 }
anthonyafa3dfc2012-03-03 11:31:30 +00002333 if (LocaleCompare("flop",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002334 {
anthony92c93bd2012-03-19 14:02:47 +00002335 new_image=FlopImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002336 break;
2337 }
anthonyafa3dfc2012-03-03 11:31:30 +00002338 if (LocaleCompare("floodfill",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002339 {
2340 PixelInfo
2341 target;
2342
anthony7bcfe7f2012-03-30 14:01:22 +00002343 if (IfMagickFalse(IsGeometry(arg1)))
anthony2a0ec8c2012-03-24 04:35:56 +00002344 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002345 (void) ParsePageGeometry(_image,arg1,&geometry,_exception);
2346 (void) QueryColorCompliance(arg2,AllCompliance,&target,_exception);
2347 (void) FloodfillPaintImage(_image,_draw_info,&target,geometry.x,
2348 geometry.y,plus_alt_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00002349 break;
2350 }
anthonyafa3dfc2012-03-03 11:31:30 +00002351 if (LocaleCompare("frame",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002352 {
2353 FrameInfo
2354 frame_info;
2355
anthony31f1bf72012-01-30 12:37:22 +00002356 CompositeOperator
anthonyfd706f92012-01-19 04:22:02 +00002357 compose;
2358
2359 const char*
2360 value;
2361
anthony92c93bd2012-03-19 14:02:47 +00002362 value=GetImageOption(_image_info,"compose");
anthonyfd706f92012-01-19 04:22:02 +00002363 if (value != (const char *) NULL)
2364 compose=(CompositeOperator) ParseCommandOption(
2365 MagickComposeOptions,MagickFalse,value);
2366 else
anthony92c93bd2012-03-19 14:02:47 +00002367 compose=OverCompositeOp; /* use Over not _image->compose */
anthonyfd706f92012-01-19 04:22:02 +00002368
anthony7bcfe7f2012-03-30 14:01:22 +00002369 if (IfMagickFalse(IsGeometry(arg1)))
anthony2a0ec8c2012-03-24 04:35:56 +00002370 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002371 flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00002372 frame_info.width=geometry.width;
2373 frame_info.height=geometry.height;
2374 if ((flags & HeightValue) == 0)
2375 frame_info.height=geometry.width;
2376 frame_info.outer_bevel=geometry.x;
2377 frame_info.inner_bevel=geometry.y;
2378 frame_info.x=(ssize_t) frame_info.width;
2379 frame_info.y=(ssize_t) frame_info.height;
anthony92c93bd2012-03-19 14:02:47 +00002380 frame_info.width=_image->columns+2*frame_info.width;
2381 frame_info.height=_image->rows+2*frame_info.height;
2382 new_image=FrameImage(_image,&frame_info,compose,_exception);
anthony805a2d42011-09-25 08:25:12 +00002383 break;
2384 }
anthonyafa3dfc2012-03-03 11:31:30 +00002385 if (LocaleCompare("function",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002386 {
2387 char
anthonyb1d483a2012-04-14 12:53:56 +00002388 *arg;
anthony805a2d42011-09-25 08:25:12 +00002389
2390 double
anthonyb1d483a2012-04-14 12:53:56 +00002391 *args;
anthony805a2d42011-09-25 08:25:12 +00002392
anthonyb1d483a2012-04-14 12:53:56 +00002393 ssize_t
2394 count;
anthony805a2d42011-09-25 08:25:12 +00002395
anthony2a0ec8c2012-03-24 04:35:56 +00002396 parse=ParseCommandOption(MagickFunctionOptions,MagickFalse,arg1);
2397 if ( parse < 0 )
2398 CLIWandExceptArgBreak(OptionError,"UnrecognizedFunction",
2399 option,arg1);
anthonyb1d483a2012-04-14 12:53:56 +00002400 /* allow percent escapes in argument string */
2401 arg=InterpretImageProperties(_image_info,_image,arg2,_exception);
2402 if (arg == (char *) NULL)
2403 break;
2404 /* convert argument string into an array of doubles */
2405 args = StringToArrayOfDoubles(arg,&count,_exception);
2406 arg=DestroyString(arg);
2407 if (args == (double *)NULL )
2408 CLIWandExceptArgBreak(OptionError,"InvalidNumberList",option,arg2);
2409
2410 (void) FunctionImage(_image,(MagickFunction)parse,count,args,
2411 _exception);
2412 args=(double *) RelinquishMagickMemory(args);
anthony805a2d42011-09-25 08:25:12 +00002413 break;
2414 }
anthonyebb73a22012-03-22 14:25:52 +00002415 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002416 }
2417 case 'g':
2418 {
anthonyafa3dfc2012-03-03 11:31:30 +00002419 if (LocaleCompare("gamma",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002420 {
anthony7bcfe7f2012-03-30 14:01:22 +00002421 if (IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00002422 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyafa3dfc2012-03-03 11:31:30 +00002423 if (IfNormalOp)
anthony92c93bd2012-03-19 14:02:47 +00002424 (void) GammaImage(_image,StringToDouble(arg1,(char **) NULL),
2425 _exception);
anthonyafa3dfc2012-03-03 11:31:30 +00002426 else
anthony92c93bd2012-03-19 14:02:47 +00002427 _image->gamma=StringToDouble(arg1,(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +00002428 break;
2429 }
anthony975a8d72012-04-12 13:54:36 +00002430 if (LocaleCompare("gaussian-blur",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002431 {
anthonyfd706f92012-01-19 04:22:02 +00002432 flags=ParseGeometry(arg1,&geometry_info);
anthonyb1e21ed2012-04-20 12:43:12 +00002433 if ((flags & (RhoValue|SigmaValue)) == 0)
2434 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00002435 if ((flags & SigmaValue) == 0)
2436 geometry_info.sigma=1.0;
anthony92c93bd2012-03-19 14:02:47 +00002437 new_image=GaussianBlurImage(_image,geometry_info.rho,
2438 geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00002439 break;
2440 }
anthony975a8d72012-04-12 13:54:36 +00002441 if (LocaleCompare("gaussian",option+1) == 0)
2442 {
2443 CLIWandWarnDepreciated("-gaussian-blur");
2444 CLISimpleOperatorImage(cli_wand,"-gaussian-blur",arg1,NULL);
2445 }
anthonyafa3dfc2012-03-03 11:31:30 +00002446 if (LocaleCompare("geometry",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002447 {
anthonyfd706f92012-01-19 04:22:02 +00002448 /*
anthony31f1bf72012-01-30 12:37:22 +00002449 Record Image offset for composition. (A Setting)
anthonyfe1aa782012-03-24 13:43:04 +00002450 Resize last _image. (ListOperator) -- DEPRECIATE
anthony31f1bf72012-01-30 12:37:22 +00002451 FUTURE: Why if no 'offset' does this resize ALL images?
2452 Also why is the setting recorded in the IMAGE non-sense!
anthonyfd706f92012-01-19 04:22:02 +00002453 */
anthonyafa3dfc2012-03-03 11:31:30 +00002454 if (IfPlusOp)
anthonyfd706f92012-01-19 04:22:02 +00002455 { /* remove the previous composition geometry offset! */
anthony92c93bd2012-03-19 14:02:47 +00002456 if (_image->geometry != (char *) NULL)
2457 _image->geometry=DestroyString(_image->geometry);
anthony805a2d42011-09-25 08:25:12 +00002458 break;
2459 }
anthony7bcfe7f2012-03-30 14:01:22 +00002460 if (IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00002461 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002462 flags=ParseRegionGeometry(_image,arg1,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00002463 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
anthony92c93bd2012-03-19 14:02:47 +00002464 (void) CloneString(&_image->geometry,arg1);
anthony805a2d42011-09-25 08:25:12 +00002465 else
anthony92c93bd2012-03-19 14:02:47 +00002466 new_image=ResizeImage(_image,geometry.width,geometry.height,
cristyaa2c16c2012-03-25 22:21:35 +00002467 _image->filter,_exception);
anthony805a2d42011-09-25 08:25:12 +00002468 break;
2469 }
anthonyebb73a22012-03-22 14:25:52 +00002470 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002471 }
anthony805a2d42011-09-25 08:25:12 +00002472 case 'i':
2473 {
anthonyafa3dfc2012-03-03 11:31:30 +00002474 if (LocaleCompare("identify",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002475 {
anthony31f1bf72012-01-30 12:37:22 +00002476 const char
2477 *format,
anthony805a2d42011-09-25 08:25:12 +00002478 *text;
2479
anthony92c93bd2012-03-19 14:02:47 +00002480 format=GetImageOption(_image_info,"format");
anthony805a2d42011-09-25 08:25:12 +00002481 if (format == (char *) NULL)
2482 {
anthony92c93bd2012-03-19 14:02:47 +00002483 (void) IdentifyImage(_image,stdout,_image_info->verbose,
2484 _exception);
anthony805a2d42011-09-25 08:25:12 +00002485 break;
2486 }
anthony92c93bd2012-03-19 14:02:47 +00002487 text=InterpretImageProperties(_image_info,_image,format,_exception);
anthony805a2d42011-09-25 08:25:12 +00002488 if (text == (char *) NULL)
2489 break;
2490 (void) fputs(text,stdout);
2491 (void) fputc('\n',stdout);
anthony31f1bf72012-01-30 12:37:22 +00002492 text=DestroyString((char *)text);
anthony805a2d42011-09-25 08:25:12 +00002493 break;
2494 }
anthonyafa3dfc2012-03-03 11:31:30 +00002495 if (LocaleCompare("implode",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002496 {
anthonyb1e21ed2012-04-20 12:43:12 +00002497 flags=ParseGeometry(arg1,&geometry_info);
2498 if ((flags & RhoValue) == 0)
anthonyfe1aa782012-03-24 13:43:04 +00002499 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyb1e21ed2012-04-20 12:43:12 +00002500 new_image=ImplodeImage(_image,geometry_info.rho,_image->interpolate,
2501 _exception);
anthony805a2d42011-09-25 08:25:12 +00002502 break;
2503 }
anthonyafa3dfc2012-03-03 11:31:30 +00002504 if (LocaleCompare("interpolative-resize",option+1) == 0)
cristy947cb4c2011-10-20 18:41:46 +00002505 {
anthonyfe1aa782012-03-24 13:43:04 +00002506 /* FUTURE: New to IMv7
2507 Roll into a resize special operator */
anthony7bcfe7f2012-03-30 14:01:22 +00002508 if (IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00002509 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002510 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
2511 new_image=InterpolativeResizeImage(_image,geometry.width,
2512 geometry.height,_image->interpolate,_exception);
cristy947cb4c2011-10-20 18:41:46 +00002513 break;
2514 }
anthonyebb73a22012-03-22 14:25:52 +00002515 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002516 }
2517 case 'l':
2518 {
anthonyafa3dfc2012-03-03 11:31:30 +00002519 if (LocaleCompare("lat",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002520 {
anthonyfd706f92012-01-19 04:22:02 +00002521 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00002522 if ((flags & (RhoValue|SigmaValue)) == 0)
2523 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00002524 if ((flags & PercentValue) != 0)
2525 geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
anthony92c93bd2012-03-19 14:02:47 +00002526 new_image=AdaptiveThresholdImage(_image,(size_t) geometry_info.rho,
anthony31f1bf72012-01-30 12:37:22 +00002527 (size_t) geometry_info.sigma,(double) geometry_info.xi,
anthony92c93bd2012-03-19 14:02:47 +00002528 _exception);
anthony805a2d42011-09-25 08:25:12 +00002529 break;
2530 }
anthonyafa3dfc2012-03-03 11:31:30 +00002531 if (LocaleCompare("level",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002532 {
2533 MagickRealType
2534 black_point,
2535 gamma,
2536 white_point;
2537
2538 MagickStatusType
2539 flags;
2540
anthonyfd706f92012-01-19 04:22:02 +00002541 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00002542 if ((flags & RhoValue) == 0)
2543 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00002544 black_point=geometry_info.rho;
2545 white_point=(MagickRealType) QuantumRange;
2546 if ((flags & SigmaValue) != 0)
2547 white_point=geometry_info.sigma;
2548 gamma=1.0;
2549 if ((flags & XiValue) != 0)
2550 gamma=geometry_info.xi;
2551 if ((flags & PercentValue) != 0)
2552 {
2553 black_point*=(MagickRealType) (QuantumRange/100.0);
2554 white_point*=(MagickRealType) (QuantumRange/100.0);
2555 }
2556 if ((flags & SigmaValue) == 0)
2557 white_point=(MagickRealType) QuantumRange-black_point;
anthonyafa3dfc2012-03-03 11:31:30 +00002558 if (IfPlusOp || ((flags & AspectValue) != 0))
anthony92c93bd2012-03-19 14:02:47 +00002559 (void) LevelizeImage(_image,black_point,white_point,gamma,_exception);
anthony805a2d42011-09-25 08:25:12 +00002560 else
anthony92c93bd2012-03-19 14:02:47 +00002561 (void) LevelImage(_image,black_point,white_point,gamma,_exception);
anthony805a2d42011-09-25 08:25:12 +00002562 break;
2563 }
anthonyafa3dfc2012-03-03 11:31:30 +00002564 if (LocaleCompare("level-colors",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002565 {
2566 char
2567 token[MaxTextExtent];
2568
2569 const char
2570 *p;
2571
2572 PixelInfo
2573 black_point,
2574 white_point;
2575
anthonyfd706f92012-01-19 04:22:02 +00002576 p=(const char *) arg1;
anthony805a2d42011-09-25 08:25:12 +00002577 GetMagickToken(p,&p,token); /* get black point color */
2578 if ((isalpha((int) *token) != 0) || ((*token == '#') != 0))
cristy269c9412011-10-13 23:41:15 +00002579 (void) QueryColorCompliance(token,AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +00002580 &black_point,_exception);
anthony805a2d42011-09-25 08:25:12 +00002581 else
cristy269c9412011-10-13 23:41:15 +00002582 (void) QueryColorCompliance("#000000",AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +00002583 &black_point,_exception);
anthony805a2d42011-09-25 08:25:12 +00002584 if (isalpha((int) token[0]) || (token[0] == '#'))
2585 GetMagickToken(p,&p,token);
2586 if (*token == '\0')
2587 white_point=black_point; /* set everything to that color */
2588 else
2589 {
2590 if ((isalpha((int) *token) == 0) && ((*token == '#') == 0))
2591 GetMagickToken(p,&p,token); /* Get white point color. */
2592 if ((isalpha((int) *token) != 0) || ((*token == '#') != 0))
cristy269c9412011-10-13 23:41:15 +00002593 (void) QueryColorCompliance(token,AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +00002594 &white_point,_exception);
anthony805a2d42011-09-25 08:25:12 +00002595 else
cristy269c9412011-10-13 23:41:15 +00002596 (void) QueryColorCompliance("#ffffff",AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +00002597 &white_point,_exception);
anthony805a2d42011-09-25 08:25:12 +00002598 }
anthony92c93bd2012-03-19 14:02:47 +00002599 (void) LevelImageColors(_image,&black_point,&white_point,
2600 plus_alt_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00002601 break;
2602 }
anthonyafa3dfc2012-03-03 11:31:30 +00002603 if (LocaleCompare("linear-stretch",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002604 {
2605 double
2606 black_point,
2607 white_point;
2608
2609 MagickStatusType
2610 flags;
2611
anthonyfd706f92012-01-19 04:22:02 +00002612 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00002613 if ((flags & RhoValue) == 0)
2614 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00002615 black_point=geometry_info.rho;
anthony92c93bd2012-03-19 14:02:47 +00002616 white_point=(MagickRealType) _image->columns*_image->rows;
anthony805a2d42011-09-25 08:25:12 +00002617 if ((flags & SigmaValue) != 0)
2618 white_point=geometry_info.sigma;
2619 if ((flags & PercentValue) != 0)
2620 {
anthony92c93bd2012-03-19 14:02:47 +00002621 black_point*=(double) _image->columns*_image->rows/100.0;
2622 white_point*=(double) _image->columns*_image->rows/100.0;
anthony805a2d42011-09-25 08:25:12 +00002623 }
2624 if ((flags & SigmaValue) == 0)
anthony92c93bd2012-03-19 14:02:47 +00002625 white_point=(MagickRealType) _image->columns*_image->rows-
anthony805a2d42011-09-25 08:25:12 +00002626 black_point;
anthony92c93bd2012-03-19 14:02:47 +00002627 (void) LinearStretchImage(_image,black_point,white_point,_exception);
anthony805a2d42011-09-25 08:25:12 +00002628 break;
2629 }
anthonyafa3dfc2012-03-03 11:31:30 +00002630 if (LocaleCompare("liquid-rescale",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002631 {
anthonyfe1aa782012-03-24 13:43:04 +00002632 /* FUTURE: Roll into a resize special operator */
anthony7bcfe7f2012-03-30 14:01:22 +00002633 if (IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00002634 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002635 flags=ParseRegionGeometry(_image,arg1,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00002636 if ((flags & XValue) == 0)
2637 geometry.x=1;
2638 if ((flags & YValue) == 0)
2639 geometry.y=0;
anthony92c93bd2012-03-19 14:02:47 +00002640 new_image=LiquidRescaleImage(_image,geometry.width,
2641 geometry.height,1.0*geometry.x,1.0*geometry.y,_exception);
anthony805a2d42011-09-25 08:25:12 +00002642 break;
2643 }
anthonyebb73a22012-03-22 14:25:52 +00002644 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002645 }
2646 case 'm':
2647 {
anthonyafa3dfc2012-03-03 11:31:30 +00002648 if (LocaleCompare("map",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002649 {
anthony975a8d72012-04-12 13:54:36 +00002650 CLIWandWarnDepreciated("-remap");
2651 CLISimpleOperatorImage(cli_wand,"-remap",NULL,NULL);
anthony805a2d42011-09-25 08:25:12 +00002652 break;
2653 }
anthonyafa3dfc2012-03-03 11:31:30 +00002654 if (LocaleCompare("mask",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002655 {
2656 Image
2657 *mask;
2658
anthonyafa3dfc2012-03-03 11:31:30 +00002659 if (IfPlusOp)
anthony31f1bf72012-01-30 12:37:22 +00002660 { /* Remove a mask. */
anthony92c93bd2012-03-19 14:02:47 +00002661 (void) SetImageMask(_image,(Image *) NULL,_exception);
anthony805a2d42011-09-25 08:25:12 +00002662 break;
2663 }
anthony5330ae02012-03-20 14:17:01 +00002664 /* Set the image mask. */
anthony92c93bd2012-03-19 14:02:47 +00002665 mask=GetImageCache(_image_info,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00002666 if (mask == (Image *) NULL)
2667 break;
anthony92c93bd2012-03-19 14:02:47 +00002668 (void) SetImageMask(_image,mask,_exception);
anthony805a2d42011-09-25 08:25:12 +00002669 mask=DestroyImage(mask);
2670 break;
2671 }
anthonyafa3dfc2012-03-03 11:31:30 +00002672 if (LocaleCompare("matte",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002673 {
anthony975a8d72012-04-12 13:54:36 +00002674 CLIWandWarnDepreciated(IfNormalOp?"-alpha Set":"-alpha Off");
anthony92c93bd2012-03-19 14:02:47 +00002675 (void) SetImageAlphaChannel(_image,IfNormalOp ? SetAlphaChannel :
2676 DeactivateAlphaChannel, _exception);
anthony805a2d42011-09-25 08:25:12 +00002677 break;
2678 }
anthonya3ef4ed2012-03-17 06:52:53 +00002679 if (LocaleCompare("median",option+1) == 0)
2680 {
anthony975a8d72012-04-12 13:54:36 +00002681 CLIWandWarnDepreciated("-statistic Median");
anthonya3ef4ed2012-03-17 06:52:53 +00002682 CLISimpleOperatorImage(cli_wand,"-statistic","Median",arg1);
2683 break;
2684 }
anthonyafa3dfc2012-03-03 11:31:30 +00002685 if (LocaleCompare("mode",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002686 {
anthony975a8d72012-04-12 13:54:36 +00002687 /* FUTURE: note this is also a special "montage" option */
2688 CLIWandWarnDepreciated("-statistic Mode");
2689 CLISimpleOperatorImage(cli_wand,"-statistic","Mode",arg1);
anthony805a2d42011-09-25 08:25:12 +00002690 break;
2691 }
anthonyafa3dfc2012-03-03 11:31:30 +00002692 if (LocaleCompare("modulate",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002693 {
anthony7bcfe7f2012-03-30 14:01:22 +00002694 if (IfMagickFalse(IsGeometry(arg1)))
anthony7bc87992012-03-25 02:32:51 +00002695 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002696 (void) ModulateImage(_image,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00002697 break;
2698 }
anthonyafa3dfc2012-03-03 11:31:30 +00002699 if (LocaleCompare("monitor",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002700 {
anthony92c93bd2012-03-19 14:02:47 +00002701 (void) SetImageProgressMonitor(_image, IfNormalOp ? MonitorProgress :
anthonyafa3dfc2012-03-03 11:31:30 +00002702 (MagickProgressMonitor) NULL,(void *) NULL);
anthony805a2d42011-09-25 08:25:12 +00002703 break;
2704 }
anthonyafa3dfc2012-03-03 11:31:30 +00002705 if (LocaleCompare("monochrome",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002706 {
anthony92c93bd2012-03-19 14:02:47 +00002707 (void) SetImageType(_image,BilevelType,_exception);
anthony805a2d42011-09-25 08:25:12 +00002708 break;
2709 }
anthonyafa3dfc2012-03-03 11:31:30 +00002710 if (LocaleCompare("morphology",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002711 {
2712 char
2713 token[MaxTextExtent];
2714
2715 const char
2716 *p;
2717
2718 KernelInfo
2719 *kernel;
2720
anthony805a2d42011-09-25 08:25:12 +00002721 ssize_t
2722 iterations;
2723
anthonyfd706f92012-01-19 04:22:02 +00002724 p=arg1;
anthony805a2d42011-09-25 08:25:12 +00002725 GetMagickToken(p,&p,token);
anthony7bc87992012-03-25 02:32:51 +00002726 parse=ParseCommandOption(MagickMorphologyOptions,MagickFalse,token);
2727 if ( parse < 0 )
2728 CLIWandExceptArgBreak(OptionError,"UnrecognizedFunction",
2729 option,arg1);
anthony805a2d42011-09-25 08:25:12 +00002730 iterations=1L;
2731 GetMagickToken(p,&p,token);
2732 if ((*p == ':') || (*p == ','))
2733 GetMagickToken(p,&p,token);
2734 if ((*p != '\0'))
2735 iterations=(ssize_t) StringToLong(p);
anthonyfd706f92012-01-19 04:22:02 +00002736 kernel=AcquireKernelInfo(arg2);
anthony805a2d42011-09-25 08:25:12 +00002737 if (kernel == (KernelInfo *) NULL)
anthony7bc87992012-03-25 02:32:51 +00002738 CLIWandExceptArgBreak(OptionError,"UnabletoParseKernel",
2739 option,arg2);
2740 new_image=MorphologyImage(_image,(MorphologyMethod)parse,
2741 iterations,kernel,_exception);
anthony805a2d42011-09-25 08:25:12 +00002742 kernel=DestroyKernelInfo(kernel);
2743 break;
2744 }
anthonyafa3dfc2012-03-03 11:31:30 +00002745 if (LocaleCompare("motion-blur",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002746 {
anthonyfd706f92012-01-19 04:22:02 +00002747 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00002748 if ((flags & (RhoValue|SigmaValue)) == 0)
2749 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00002750 if ((flags & SigmaValue) == 0)
2751 geometry_info.sigma=1.0;
anthony92c93bd2012-03-19 14:02:47 +00002752 new_image=MotionBlurImage(_image,geometry_info.rho,
cristyaa2c16c2012-03-25 22:21:35 +00002753 geometry_info.sigma,geometry_info.xi,_exception);
anthony805a2d42011-09-25 08:25:12 +00002754 break;
2755 }
anthonyebb73a22012-03-22 14:25:52 +00002756 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002757 }
2758 case 'n':
2759 {
anthonyafa3dfc2012-03-03 11:31:30 +00002760 if (LocaleCompare("negate",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002761 {
anthony92c93bd2012-03-19 14:02:47 +00002762 (void) NegateImage(_image, plus_alt_op, _exception);
anthony805a2d42011-09-25 08:25:12 +00002763 break;
2764 }
anthonyafa3dfc2012-03-03 11:31:30 +00002765 if (LocaleCompare("noise",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002766 {
anthony975a8d72012-04-12 13:54:36 +00002767 double
2768 attenuate;
2769
2770 const char*
2771 value;
2772
anthonyafa3dfc2012-03-03 11:31:30 +00002773 if (IfNormalOp)
anthony805a2d42011-09-25 08:25:12 +00002774 {
anthony975a8d72012-04-12 13:54:36 +00002775 CLIWandWarnDepreciated("-statistic NonPeak");
2776 CLISimpleOperatorImage(cli_wand,"-statistic","NonPeak",arg1);
2777 break;
anthony805a2d42011-09-25 08:25:12 +00002778 }
anthony975a8d72012-04-12 13:54:36 +00002779 parse=ParseCommandOption(MagickNoiseOptions,MagickFalse,arg1);
2780 if ( parse < 0 )
2781 CLIWandExceptArgBreak(OptionError,"UnrecognizedNoiseType",
2782 option,arg1);
2783 attenuate=1.0;
2784 value=GetImageOption(_image_info,"attenuate");
2785 if (value != (const char *) NULL)
2786 attenuate=StringToDouble(value,(char **) NULL);
2787 new_image=AddNoiseImage(_image,(NoiseType)parse,attenuate,
2788 _exception);
anthony805a2d42011-09-25 08:25:12 +00002789 break;
2790 }
anthonyafa3dfc2012-03-03 11:31:30 +00002791 if (LocaleCompare("normalize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002792 {
anthony92c93bd2012-03-19 14:02:47 +00002793 (void) NormalizeImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002794 break;
2795 }
anthonyebb73a22012-03-22 14:25:52 +00002796 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002797 }
2798 case 'o':
2799 {
anthonyafa3dfc2012-03-03 11:31:30 +00002800 if (LocaleCompare("opaque",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002801 {
2802 PixelInfo
2803 target;
2804
anthony92c93bd2012-03-19 14:02:47 +00002805 (void) QueryColorCompliance(arg1,AllCompliance,&target,_exception);
2806 (void) OpaquePaintImage(_image,&target,&_draw_info->fill,plus_alt_op,
2807 _exception);
anthony805a2d42011-09-25 08:25:12 +00002808 break;
2809 }
anthonyafa3dfc2012-03-03 11:31:30 +00002810 if (LocaleCompare("ordered-dither",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002811 {
anthony92c93bd2012-03-19 14:02:47 +00002812 (void) OrderedPosterizeImage(_image,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00002813 break;
2814 }
anthonyebb73a22012-03-22 14:25:52 +00002815 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002816 }
2817 case 'p':
2818 {
anthonyafa3dfc2012-03-03 11:31:30 +00002819 if (LocaleCompare("paint",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002820 {
anthony22de2722012-04-19 14:43:00 +00002821 flags=ParseGeometry(arg1,&geometry_info);
2822 if ((flags & (RhoValue|SigmaValue)) == 0)
2823 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002824 new_image=OilPaintImage(_image,geometry_info.rho,geometry_info.sigma,
2825 _exception);
anthony805a2d42011-09-25 08:25:12 +00002826 break;
2827 }
anthonyafa3dfc2012-03-03 11:31:30 +00002828 if (LocaleCompare("polaroid",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002829 {
cristye9e3d382011-12-14 01:50:13 +00002830 const char
2831 *caption;
2832
anthony805a2d42011-09-25 08:25:12 +00002833 double
2834 angle;
2835
anthony7bc87992012-03-25 02:32:51 +00002836 if (IfPlusOp) {
anthonyf42014d2012-03-25 09:53:06 +00002837 RandomInfo
2838 *random_info;
anthony805a2d42011-09-25 08:25:12 +00002839
anthonyf42014d2012-03-25 09:53:06 +00002840 random_info=AcquireRandomInfo();
2841 angle=22.5*(GetPseudoRandomValue(random_info)-0.5);
2842 random_info=DestroyRandomInfo(random_info);
2843 }
anthony7bc87992012-03-25 02:32:51 +00002844 else {
anthonyf42014d2012-03-25 09:53:06 +00002845 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00002846 if ((flags & RhoValue) == 0)
2847 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyf42014d2012-03-25 09:53:06 +00002848 angle=geometry_info.rho;
2849 }
anthony92c93bd2012-03-19 14:02:47 +00002850 caption=GetImageProperty(_image,"caption",_exception);
2851 new_image=PolaroidImage(_image,_draw_info,caption,angle,
2852 _image->interpolate,_exception);
anthony805a2d42011-09-25 08:25:12 +00002853 break;
2854 }
anthonyafa3dfc2012-03-03 11:31:30 +00002855 if (LocaleCompare("posterize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002856 {
anthony22de2722012-04-19 14:43:00 +00002857 flags=ParseGeometry(arg1,&geometry_info);
2858 if ((flags & RhoValue) == 0)
anthony7bc87992012-03-25 02:32:51 +00002859 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002860 (void) PosterizeImage(_image,(size_t) geometry_info.rho,
2861 _quantize_info->dither,_exception);
anthony805a2d42011-09-25 08:25:12 +00002862 break;
2863 }
anthonyafa3dfc2012-03-03 11:31:30 +00002864 if (LocaleCompare("preview",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002865 {
anthony31f1bf72012-01-30 12:37:22 +00002866 /* FUTURE: should be a 'Genesis' option?
2867 Option however is also in WandSettingOptionInfo()
anthony7bc87992012-03-25 02:32:51 +00002868 Why???
cristy947cb4c2011-10-20 18:41:46 +00002869 */
anthony7bc87992012-03-25 02:32:51 +00002870 parse=ParseCommandOption(MagickPreviewOptions, MagickFalse,arg1);
2871 if ( parse < 0 )
2872 CLIWandExceptArgBreak(OptionError,"UnrecognizedPreviewType",
2873 option,arg1);
2874 new_image=PreviewImage(_image,(PreviewType)parse,_exception);
anthony805a2d42011-09-25 08:25:12 +00002875 break;
2876 }
anthonyafa3dfc2012-03-03 11:31:30 +00002877 if (LocaleCompare("profile",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002878 {
2879 const char
2880 *name;
2881
2882 const StringInfo
2883 *profile;
2884
2885 Image
2886 *profile_image;
2887
2888 ImageInfo
2889 *profile_info;
2890
anthonyafa3dfc2012-03-03 11:31:30 +00002891 if (IfPlusOp)
anthony92c93bd2012-03-19 14:02:47 +00002892 { /* Remove a profile from the _image. */
2893 (void) ProfileImage(_image,arg1,(const unsigned char *)
2894 NULL,0,_exception);
anthony805a2d42011-09-25 08:25:12 +00002895 break;
2896 }
anthony92c93bd2012-03-19 14:02:47 +00002897 /* Associate a profile with the _image. */
2898 profile_info=CloneImageInfo(_image_info);
2899 profile=GetImageProfile(_image,"iptc");
anthony805a2d42011-09-25 08:25:12 +00002900 if (profile != (StringInfo *) NULL)
2901 profile_info->profile=(void *) CloneStringInfo(profile);
anthony92c93bd2012-03-19 14:02:47 +00002902 profile_image=GetImageCache(profile_info,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00002903 profile_info=DestroyImageInfo(profile_info);
2904 if (profile_image == (Image *) NULL)
2905 {
2906 StringInfo
2907 *profile;
2908
anthony92c93bd2012-03-19 14:02:47 +00002909 profile_info=CloneImageInfo(_image_info);
anthonyfd706f92012-01-19 04:22:02 +00002910 (void) CopyMagickString(profile_info->filename,arg1,
anthony805a2d42011-09-25 08:25:12 +00002911 MaxTextExtent);
anthony92c93bd2012-03-19 14:02:47 +00002912 profile=FileToStringInfo(profile_info->filename,~0UL,_exception);
anthony805a2d42011-09-25 08:25:12 +00002913 if (profile != (StringInfo *) NULL)
2914 {
anthony92c93bd2012-03-19 14:02:47 +00002915 (void) ProfileImage(_image,profile_info->magick,
anthony805a2d42011-09-25 08:25:12 +00002916 GetStringInfoDatum(profile),(size_t)
anthony92c93bd2012-03-19 14:02:47 +00002917 GetStringInfoLength(profile),_exception);
anthony805a2d42011-09-25 08:25:12 +00002918 profile=DestroyStringInfo(profile);
2919 }
2920 profile_info=DestroyImageInfo(profile_info);
2921 break;
2922 }
2923 ResetImageProfileIterator(profile_image);
2924 name=GetNextImageProfile(profile_image);
2925 while (name != (const char *) NULL)
2926 {
2927 profile=GetImageProfile(profile_image,name);
2928 if (profile != (StringInfo *) NULL)
anthony92c93bd2012-03-19 14:02:47 +00002929 (void) ProfileImage(_image,name,GetStringInfoDatum(profile),
2930 (size_t) GetStringInfoLength(profile),_exception);
anthony805a2d42011-09-25 08:25:12 +00002931 name=GetNextImageProfile(profile_image);
2932 }
2933 profile_image=DestroyImage(profile_image);
2934 break;
2935 }
anthonyebb73a22012-03-22 14:25:52 +00002936 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002937 }
anthony805a2d42011-09-25 08:25:12 +00002938 case 'r':
2939 {
anthonyafa3dfc2012-03-03 11:31:30 +00002940 if (LocaleCompare("radial-blur",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002941 {
anthonyfd706f92012-01-19 04:22:02 +00002942 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00002943 if ((flags & RhoValue) == 0)
2944 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
cristyaa2c16c2012-03-25 22:21:35 +00002945 new_image=RadialBlurImage(_image,geometry_info.rho,_exception);
anthony805a2d42011-09-25 08:25:12 +00002946 break;
2947 }
anthonyafa3dfc2012-03-03 11:31:30 +00002948 if (LocaleCompare("raise",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002949 {
anthony7bcfe7f2012-03-30 14:01:22 +00002950 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00002951 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002952 flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00002953 if ((flags & SigmaValue) == 0)
2954 geometry.height=geometry.width;
anthony92c93bd2012-03-19 14:02:47 +00002955 (void) RaiseImage(_image,&geometry,normal_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00002956 break;
2957 }
anthonyafa3dfc2012-03-03 11:31:30 +00002958 if (LocaleCompare("random-threshold",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002959 {
anthony7bcfe7f2012-03-30 14:01:22 +00002960 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00002961 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002962 (void) RandomThresholdImage(_image,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00002963 break;
2964 }
anthony975a8d72012-04-12 13:54:36 +00002965 if (LocaleCompare("recolor",option+1) == 0)
2966 {
2967 CLIWandWarnDepreciated("-color-matrix");
2968 CLISimpleOperatorImage(cli_wand,"-color-matrix",arg1,NULL);
2969 }
anthonyafa3dfc2012-03-03 11:31:30 +00002970 if (LocaleCompare("remap",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002971 {
2972 Image
2973 *remap_image;
2974
anthony92c93bd2012-03-19 14:02:47 +00002975 remap_image=GetImageCache(_image_info,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00002976 if (remap_image == (Image *) NULL)
2977 break;
anthony92c93bd2012-03-19 14:02:47 +00002978 (void) RemapImage(_quantize_info,_image,remap_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002979 remap_image=DestroyImage(remap_image);
2980 break;
2981 }
anthonyafa3dfc2012-03-03 11:31:30 +00002982 if (LocaleCompare("repage",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002983 {
anthonyafa3dfc2012-03-03 11:31:30 +00002984 if (IfNormalOp)
cristy0d0de742012-03-25 19:32:48 +00002985 {
anthony7bcfe7f2012-03-30 14:01:22 +00002986 if (IfMagickFalse(IsGeometry(arg1)))
cristy0d0de742012-03-25 19:32:48 +00002987 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,
2988 arg1);
2989 (void) ResetImagePage(_image,arg1);
2990 }
anthony31f1bf72012-01-30 12:37:22 +00002991 else
anthony92c93bd2012-03-19 14:02:47 +00002992 (void) ParseAbsoluteGeometry("0x0+0+0",&_image->page);
anthony805a2d42011-09-25 08:25:12 +00002993 break;
2994 }
anthonyafa3dfc2012-03-03 11:31:30 +00002995 if (LocaleCompare("resample",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002996 {
anthonyf46d4262012-03-26 03:30:34 +00002997 /* FUTURE: Roll into a resize special operation */
anthonyfd706f92012-01-19 04:22:02 +00002998 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00002999 if ((flags & (RhoValue|SigmaValue)) == 0)
3000 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00003001 if ((flags & SigmaValue) == 0)
3002 geometry_info.sigma=geometry_info.rho;
anthony92c93bd2012-03-19 14:02:47 +00003003 new_image=ResampleImage(_image,geometry_info.rho,
cristyaa2c16c2012-03-25 22:21:35 +00003004 geometry_info.sigma,_image->filter,_exception);
anthony805a2d42011-09-25 08:25:12 +00003005 break;
3006 }
anthonyafa3dfc2012-03-03 11:31:30 +00003007 if (LocaleCompare("resize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003008 {
anthony7bcfe7f2012-03-30 14:01:22 +00003009 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003010 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003011 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
3012 new_image=ResizeImage(_image,geometry.width,geometry.height,
cristyaa2c16c2012-03-25 22:21:35 +00003013 _image->filter,_exception);
anthony805a2d42011-09-25 08:25:12 +00003014 break;
3015 }
anthonyafa3dfc2012-03-03 11:31:30 +00003016 if (LocaleCompare("roll",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003017 {
anthony7bcfe7f2012-03-30 14:01:22 +00003018 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003019 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003020 (void) ParsePageGeometry(_image,arg1,&geometry,_exception);
3021 new_image=RollImage(_image,geometry.x,geometry.y,_exception);
anthony805a2d42011-09-25 08:25:12 +00003022 break;
3023 }
anthonyafa3dfc2012-03-03 11:31:30 +00003024 if (LocaleCompare("rotate",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003025 {
anthony22de2722012-04-19 14:43:00 +00003026 flags=ParseGeometry(arg1,&geometry_info);
3027 if ((flags & RhoValue) == 0)
anthonyf42014d2012-03-25 09:53:06 +00003028 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyad255a02012-04-19 15:02:01 +00003029 if ((flags & GreaterValue) != 0 && (_image->columns <= _image->rows))
anthony22de2722012-04-19 14:43:00 +00003030 break;
3031 if ((flags & LessValue) != 0 && (_image->columns >= _image->rows))
3032 break;
anthony92c93bd2012-03-19 14:02:47 +00003033 new_image=RotateImage(_image,geometry_info.rho,_exception);
anthony805a2d42011-09-25 08:25:12 +00003034 break;
3035 }
anthonyebb73a22012-03-22 14:25:52 +00003036 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003037 }
3038 case 's':
3039 {
anthonyafa3dfc2012-03-03 11:31:30 +00003040 if (LocaleCompare("sample",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003041 {
anthonyfe1aa782012-03-24 13:43:04 +00003042 /* FUTURE: Roll into a resize special operator */
anthony7bcfe7f2012-03-30 14:01:22 +00003043 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003044 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003045 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
3046 new_image=SampleImage(_image,geometry.width,geometry.height,
3047 _exception);
anthony805a2d42011-09-25 08:25:12 +00003048 break;
3049 }
anthonyafa3dfc2012-03-03 11:31:30 +00003050 if (LocaleCompare("scale",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003051 {
anthonyfe1aa782012-03-24 13:43:04 +00003052 /* FUTURE: Roll into a resize special operator */
anthony7bcfe7f2012-03-30 14:01:22 +00003053 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003054 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003055 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
3056 new_image=ScaleImage(_image,geometry.width,geometry.height,
3057 _exception);
anthony805a2d42011-09-25 08:25:12 +00003058 break;
3059 }
anthonyf42014d2012-03-25 09:53:06 +00003060 if (LocaleCompare("segment",option+1) == 0)
3061 {
anthonyf42014d2012-03-25 09:53:06 +00003062 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00003063 if ((flags & (RhoValue|SigmaValue)) == 0)
3064 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyf42014d2012-03-25 09:53:06 +00003065 if ((flags & SigmaValue) == 0)
3066 geometry_info.sigma=1.0;
3067 (void) SegmentImage(_image,_image->colorspace,
3068 _image_info->verbose,geometry_info.rho,geometry_info.sigma,
3069 _exception);
3070 break;
3071 }
anthonyafa3dfc2012-03-03 11:31:30 +00003072 if (LocaleCompare("selective-blur",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003073 {
anthonyfd706f92012-01-19 04:22:02 +00003074 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00003075 if ((flags & (RhoValue|SigmaValue)) == 0)
3076 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3077 if ((flags & SigmaValue) == 0)
3078 geometry_info.sigma=1.0;
anthony805a2d42011-09-25 08:25:12 +00003079 if ((flags & PercentValue) != 0)
3080 geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
anthony92c93bd2012-03-19 14:02:47 +00003081 new_image=SelectiveBlurImage(_image,geometry_info.rho,
cristyaa2c16c2012-03-25 22:21:35 +00003082 geometry_info.sigma,geometry_info.xi,_exception);
anthony805a2d42011-09-25 08:25:12 +00003083 break;
3084 }
anthonyafa3dfc2012-03-03 11:31:30 +00003085 if (LocaleCompare("separate",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003086 {
anthony31f1bf72012-01-30 12:37:22 +00003087 /* WARNING: This can generate multiple images! */
anthony43f425d2012-02-26 12:58:58 +00003088 /* FUTURE - this may be replaced by a "-channel" method */
cristydfdb19e2012-03-21 22:22:24 +00003089 new_image=SeparateImages(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00003090 break;
3091 }
anthonyafa3dfc2012-03-03 11:31:30 +00003092 if (LocaleCompare("sepia-tone",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003093 {
anthony7bcfe7f2012-03-30 14:01:22 +00003094 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003095 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3096 new_image=SepiaToneImage(_image,StringToDoubleInterval(arg1,
3097 (double) QuantumRange+1.0),_exception);
anthony805a2d42011-09-25 08:25:12 +00003098 break;
3099 }
anthonyafa3dfc2012-03-03 11:31:30 +00003100 if (LocaleCompare("set",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003101 {
3102 char
3103 *value;
3104
anthonyf42014d2012-03-25 09:53:06 +00003105 if (IfPlusOp) {
anthonyfd706f92012-01-19 04:22:02 +00003106 if (LocaleNCompare(arg1,"registry:",9) == 0)
3107 (void) DeleteImageRegistry(arg1+9);
anthony805a2d42011-09-25 08:25:12 +00003108 else
anthony31f1bf72012-01-30 12:37:22 +00003109 if (LocaleNCompare(arg1,"option:",7) == 0)
anthony805a2d42011-09-25 08:25:12 +00003110 {
anthony92c93bd2012-03-19 14:02:47 +00003111 (void) DeleteImageOption(_image_info,arg1+7);
3112 (void) DeleteImageArtifact(_image,arg1+7);
anthony805a2d42011-09-25 08:25:12 +00003113 }
3114 else
anthony92c93bd2012-03-19 14:02:47 +00003115 (void) DeleteImageProperty(_image,arg1);
anthony805a2d42011-09-25 08:25:12 +00003116 break;
3117 }
anthonyf42014d2012-03-25 09:53:06 +00003118 value=InterpretImageProperties(_image_info,_image,arg2,_exception);
anthony805a2d42011-09-25 08:25:12 +00003119 if (value == (char *) NULL)
3120 break;
anthonyfd706f92012-01-19 04:22:02 +00003121 if (LocaleNCompare(arg1,"registry:",9) == 0)
anthonyf42014d2012-03-25 09:53:06 +00003122 (void) SetImageRegistry(StringRegistryType,arg1+9,value,_exception);
anthony805a2d42011-09-25 08:25:12 +00003123 else
anthonyfd706f92012-01-19 04:22:02 +00003124 if (LocaleNCompare(arg1,"option:",7) == 0)
anthony805a2d42011-09-25 08:25:12 +00003125 {
anthony92c93bd2012-03-19 14:02:47 +00003126 (void) SetImageOption(_image_info,arg1+7,value);
3127 (void) SetImageArtifact(_image,arg1+7,value);
anthony805a2d42011-09-25 08:25:12 +00003128 }
3129 else
anthony92c93bd2012-03-19 14:02:47 +00003130 (void) SetImageProperty(_image,arg1,value,_exception);
anthony805a2d42011-09-25 08:25:12 +00003131 value=DestroyString(value);
3132 break;
3133 }
anthonyafa3dfc2012-03-03 11:31:30 +00003134 if (LocaleCompare("shade",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003135 {
anthonyfd706f92012-01-19 04:22:02 +00003136 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00003137 if (((flags & RhoValue) == 0) || ((flags & SigmaValue) == 0))
3138 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003139 new_image=ShadeImage(_image,normal_op,geometry_info.rho,
3140 geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00003141 break;
3142 }
anthonyafa3dfc2012-03-03 11:31:30 +00003143 if (LocaleCompare("shadow",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003144 {
anthonyfd706f92012-01-19 04:22:02 +00003145 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00003146 if ((flags & (RhoValue|SigmaValue)) == 0)
3147 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00003148 if ((flags & SigmaValue) == 0)
3149 geometry_info.sigma=1.0;
3150 if ((flags & XiValue) == 0)
3151 geometry_info.xi=4.0;
3152 if ((flags & PsiValue) == 0)
3153 geometry_info.psi=4.0;
cristyaa2c16c2012-03-25 22:21:35 +00003154 new_image=ShadowImage(_image,geometry_info.rho,geometry_info.sigma,
3155 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
3156 ceil(geometry_info.psi-0.5),_exception);
anthony805a2d42011-09-25 08:25:12 +00003157 break;
3158 }
anthonyafa3dfc2012-03-03 11:31:30 +00003159 if (LocaleCompare("sharpen",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003160 {
anthonyfd706f92012-01-19 04:22:02 +00003161 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00003162 if ((flags & (RhoValue|SigmaValue)) == 0)
3163 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00003164 if ((flags & SigmaValue) == 0)
3165 geometry_info.sigma=1.0;
3166 if ((flags & XiValue) == 0)
3167 geometry_info.xi=0.0;
cristyaa2c16c2012-03-25 22:21:35 +00003168 new_image=SharpenImage(_image,geometry_info.rho,geometry_info.sigma,
3169 _exception);
anthony805a2d42011-09-25 08:25:12 +00003170 break;
3171 }
anthonyafa3dfc2012-03-03 11:31:30 +00003172 if (LocaleCompare("shave",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003173 {
anthony7bcfe7f2012-03-30 14:01:22 +00003174 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003175 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003176 flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
3177 new_image=ShaveImage(_image,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00003178 break;
3179 }
anthonyafa3dfc2012-03-03 11:31:30 +00003180 if (LocaleCompare("shear",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003181 {
anthonyfd706f92012-01-19 04:22:02 +00003182 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00003183 if ((flags & RhoValue) == 0)
3184 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00003185 if ((flags & SigmaValue) == 0)
3186 geometry_info.sigma=geometry_info.rho;
anthony92c93bd2012-03-19 14:02:47 +00003187 new_image=ShearImage(_image,geometry_info.rho,
3188 geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00003189 break;
3190 }
anthonyafa3dfc2012-03-03 11:31:30 +00003191 if (LocaleCompare("sigmoidal-contrast",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003192 {
anthonyfd706f92012-01-19 04:22:02 +00003193 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00003194 if ((flags & RhoValue) == 0)
3195 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00003196 if ((flags & SigmaValue) == 0)
3197 geometry_info.sigma=(double) QuantumRange/2.0;
3198 if ((flags & PercentValue) != 0)
3199 geometry_info.sigma=(double) QuantumRange*geometry_info.sigma/
3200 100.0;
anthony92c93bd2012-03-19 14:02:47 +00003201 (void) SigmoidalContrastImage(_image,normal_op,geometry_info.rho,
anthonyb1d483a2012-04-14 12:53:56 +00003202 geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00003203 break;
3204 }
anthonyafa3dfc2012-03-03 11:31:30 +00003205 if (LocaleCompare("sketch",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003206 {
anthonyfd706f92012-01-19 04:22:02 +00003207 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00003208 if ((flags & (RhoValue|SigmaValue)) == 0)
3209 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00003210 if ((flags & SigmaValue) == 0)
3211 geometry_info.sigma=1.0;
anthony92c93bd2012-03-19 14:02:47 +00003212 new_image=SketchImage(_image,geometry_info.rho,
cristyaa2c16c2012-03-25 22:21:35 +00003213 geometry_info.sigma,geometry_info.xi,_exception);
anthony805a2d42011-09-25 08:25:12 +00003214 break;
3215 }
anthonyafa3dfc2012-03-03 11:31:30 +00003216 if (LocaleCompare("solarize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003217 {
anthony7bcfe7f2012-03-30 14:01:22 +00003218 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003219 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003220 (void) SolarizeImage(_image,StringToDoubleInterval(arg1,(double)
3221 QuantumRange+1.0),_exception);
anthony805a2d42011-09-25 08:25:12 +00003222 break;
3223 }
anthonyafa3dfc2012-03-03 11:31:30 +00003224 if (LocaleCompare("sparse-color",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003225 {
anthony805a2d42011-09-25 08:25:12 +00003226 char
3227 *arguments;
3228
anthonyf42014d2012-03-25 09:53:06 +00003229 parse= ParseCommandOption(MagickSparseColorOptions,MagickFalse,arg1);
3230 if ( parse < 0 )
3231 CLIWandExceptArgBreak(OptionError,"UnrecognizedSparseColorMethod",
3232 option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003233 arguments=InterpretImageProperties(_image_info,_image,arg2,_exception);
anthony805a2d42011-09-25 08:25:12 +00003234 if (arguments == (char *) NULL)
anthonyf42014d2012-03-25 09:53:06 +00003235 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
3236 new_image=SparseColorOption(_image,(SparseColorMethod)parse,
3237 arguments,_exception);
anthony805a2d42011-09-25 08:25:12 +00003238 arguments=DestroyString(arguments);
3239 break;
3240 }
anthonyafa3dfc2012-03-03 11:31:30 +00003241 if (LocaleCompare("splice",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003242 {
anthony7bcfe7f2012-03-30 14:01:22 +00003243 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003244 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyb1e21ed2012-04-20 12:43:12 +00003245 flags=ParseGravityGeometry(_image,arg1,&geometry,_exception);
anthony92c93bd2012-03-19 14:02:47 +00003246 new_image=SpliceImage(_image,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00003247 break;
3248 }
anthonyafa3dfc2012-03-03 11:31:30 +00003249 if (LocaleCompare("spread",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003250 {
anthonyb1e21ed2012-04-20 12:43:12 +00003251 flags=ParseGeometry(arg1,&geometry_info);
3252 if ((flags & RhoValue) == 0)
3253 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
anthony92c93bd2012-03-19 14:02:47 +00003254 new_image=SpreadImage(_image,geometry_info.rho,_image->interpolate,
3255 _exception);
anthony805a2d42011-09-25 08:25:12 +00003256 break;
3257 }
anthonyafa3dfc2012-03-03 11:31:30 +00003258 if (LocaleCompare("statistic",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003259 {
anthony7bc87992012-03-25 02:32:51 +00003260 parse=ParseCommandOption(MagickStatisticOptions,MagickFalse,arg1);
3261 if ( parse < 0 )
anthonyf42014d2012-03-25 09:53:06 +00003262 CLIWandExceptArgBreak(OptionError,"UnrecognizedStatisticType",
anthony7bc87992012-03-25 02:32:51 +00003263 option,arg1);
anthony975a8d72012-04-12 13:54:36 +00003264 flags=ParseGeometry(arg2,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00003265 if ((flags & RhoValue) == 0)
3266 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
anthony975a8d72012-04-12 13:54:36 +00003267 if ((flags & SigmaValue) == 0)
3268 geometry_info.sigma=geometry_info.rho;
anthony7bc87992012-03-25 02:32:51 +00003269 new_image=StatisticImage(_image,(StatisticType)parse,
3270 (size_t) geometry_info.rho,(size_t) geometry_info.sigma,
3271 _exception);
anthony805a2d42011-09-25 08:25:12 +00003272 break;
3273 }
anthonyafa3dfc2012-03-03 11:31:30 +00003274 if (LocaleCompare("strip",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003275 {
anthony92c93bd2012-03-19 14:02:47 +00003276 (void) StripImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00003277 break;
3278 }
anthonyafa3dfc2012-03-03 11:31:30 +00003279 if (LocaleCompare("swirl",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003280 {
anthonyb1e21ed2012-04-20 12:43:12 +00003281 flags=ParseGeometry(arg2,&geometry_info);
3282 if ((flags & RhoValue) == 0)
3283 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
anthony92c93bd2012-03-19 14:02:47 +00003284 new_image=SwirlImage(_image,geometry_info.rho,
3285 _image->interpolate,_exception);
anthony805a2d42011-09-25 08:25:12 +00003286 break;
3287 }
anthonyebb73a22012-03-22 14:25:52 +00003288 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003289 }
3290 case 't':
3291 {
anthonyafa3dfc2012-03-03 11:31:30 +00003292 if (LocaleCompare("threshold",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003293 {
3294 double
3295 threshold;
3296
anthony52bef752012-03-27 13:54:47 +00003297 threshold=(double) QuantumRange/2;
3298 if (normal_op) {
anthony7bcfe7f2012-03-30 14:01:22 +00003299 if (IfMagickFalse(IsGeometry(arg1)))
anthony52bef752012-03-27 13:54:47 +00003300 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00003301 threshold=StringToDoubleInterval(arg1,(double) QuantumRange+1.0);
anthony52bef752012-03-27 13:54:47 +00003302 }
anthony92c93bd2012-03-19 14:02:47 +00003303 (void) BilevelImage(_image,threshold,_exception);
anthony805a2d42011-09-25 08:25:12 +00003304 break;
3305 }
anthonyafa3dfc2012-03-03 11:31:30 +00003306 if (LocaleCompare("thumbnail",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003307 {
anthony7bcfe7f2012-03-30 14:01:22 +00003308 if (IfMagickFalse(IsGeometry(arg1)))
anthony52bef752012-03-27 13:54:47 +00003309 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003310 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
3311 new_image=ThumbnailImage(_image,geometry.width,geometry.height,
3312 _exception);
anthony805a2d42011-09-25 08:25:12 +00003313 break;
3314 }
anthonyafa3dfc2012-03-03 11:31:30 +00003315 if (LocaleCompare("tint",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003316 {
anthony7bcfe7f2012-03-30 14:01:22 +00003317 if (IfMagickFalse(IsGeometry(arg1)))
anthony52bef752012-03-27 13:54:47 +00003318 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003319 new_image=TintImage(_image,arg1,&_draw_info->fill,_exception);
anthony805a2d42011-09-25 08:25:12 +00003320 break;
3321 }
anthonyafa3dfc2012-03-03 11:31:30 +00003322 if (LocaleCompare("transform",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003323 {
anthony975a8d72012-04-12 13:54:36 +00003324 CLIWandWarnDepreciated("+distort AffineProjection");
anthony52bef752012-03-27 13:54:47 +00003325 new_image=AffineTransformImage(_image,&_draw_info->affine,_exception);
anthony805a2d42011-09-25 08:25:12 +00003326 break;
3327 }
anthonyafa3dfc2012-03-03 11:31:30 +00003328 if (LocaleCompare("transparent",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003329 {
3330 PixelInfo
3331 target;
3332
anthony92c93bd2012-03-19 14:02:47 +00003333 (void) QueryColorCompliance(arg1,AllCompliance,&target,_exception);
3334 (void) TransparentPaintImage(_image,&target,(Quantum)
3335 TransparentAlpha,plus_alt_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00003336 break;
3337 }
anthonyafa3dfc2012-03-03 11:31:30 +00003338 if (LocaleCompare("transpose",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003339 {
anthony92c93bd2012-03-19 14:02:47 +00003340 new_image=TransposeImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00003341 break;
3342 }
anthonyafa3dfc2012-03-03 11:31:30 +00003343 if (LocaleCompare("transverse",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003344 {
anthony92c93bd2012-03-19 14:02:47 +00003345 new_image=TransverseImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00003346 break;
3347 }
anthonyafa3dfc2012-03-03 11:31:30 +00003348 if (LocaleCompare("trim",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003349 {
anthony92c93bd2012-03-19 14:02:47 +00003350 new_image=TrimImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00003351 break;
3352 }
anthonyafa3dfc2012-03-03 11:31:30 +00003353 if (LocaleCompare("type",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003354 {
anthonyab3a50c2011-10-27 11:48:57 +00003355 /* Note that "type" setting should have already been defined */
anthony92c93bd2012-03-19 14:02:47 +00003356 (void) SetImageType(_image,_image_info->type,_exception);
anthony805a2d42011-09-25 08:25:12 +00003357 break;
3358 }
anthonyebb73a22012-03-22 14:25:52 +00003359 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003360 }
3361 case 'u':
3362 {
anthonyafa3dfc2012-03-03 11:31:30 +00003363 if (LocaleCompare("unique",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003364 {
anthony52bef752012-03-27 13:54:47 +00003365 /* FUTURE: move to SyncImageSettings() and AcqireImage()???
3366 Option is not documented, bt appears to be for "identify".
3367 We may need a identify specific verbose!
3368 */
3369 if (plus_alt_op) {
anthony92c93bd2012-03-19 14:02:47 +00003370 (void) DeleteImageArtifact(_image,"identify:unique-colors");
anthony805a2d42011-09-25 08:25:12 +00003371 break;
3372 }
anthony92c93bd2012-03-19 14:02:47 +00003373 (void) SetImageArtifact(_image,"identify:unique-colors","true");
3374 (void) SetImageArtifact(_image,"verbose","true");
anthony805a2d42011-09-25 08:25:12 +00003375 break;
3376 }
anthonyafa3dfc2012-03-03 11:31:30 +00003377 if (LocaleCompare("unique-colors",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003378 {
anthony92c93bd2012-03-19 14:02:47 +00003379 new_image=UniqueImageColors(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00003380 break;
3381 }
anthonyafa3dfc2012-03-03 11:31:30 +00003382 if (LocaleCompare("unsharp",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003383 {
anthonyfd706f92012-01-19 04:22:02 +00003384 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00003385 if ((flags & (RhoValue|SigmaValue)) == 0)
3386 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00003387 if ((flags & SigmaValue) == 0)
3388 geometry_info.sigma=1.0;
3389 if ((flags & XiValue) == 0)
3390 geometry_info.xi=1.0;
3391 if ((flags & PsiValue) == 0)
3392 geometry_info.psi=0.05;
anthony92c93bd2012-03-19 14:02:47 +00003393 new_image=UnsharpMaskImage(_image,geometry_info.rho,
3394 geometry_info.sigma,geometry_info.xi,geometry_info.psi,_exception);
anthony805a2d42011-09-25 08:25:12 +00003395 break;
3396 }
anthonyebb73a22012-03-22 14:25:52 +00003397 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003398 }
3399 case 'v':
3400 {
anthonyafa3dfc2012-03-03 11:31:30 +00003401 if (LocaleCompare("verbose",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003402 {
anthonyafa3dfc2012-03-03 11:31:30 +00003403 /* FUTURE: move to SyncImageSettings() and AcquireImage()???
anthony92c93bd2012-03-19 14:02:47 +00003404 three places! ImageArtifact ImageOption _image_info->verbose
anthony5330ae02012-03-20 14:17:01 +00003405 Some how new images also get this artifact!
anthony31f1bf72012-01-30 12:37:22 +00003406 */
anthony92c93bd2012-03-19 14:02:47 +00003407 (void) SetImageArtifact(_image,option+1,
anthonyafa3dfc2012-03-03 11:31:30 +00003408 IfNormalOp ? "true" : "false" );
anthony805a2d42011-09-25 08:25:12 +00003409 break;
3410 }
anthonyafa3dfc2012-03-03 11:31:30 +00003411 if (LocaleCompare("vignette",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003412 {
anthonyfd706f92012-01-19 04:22:02 +00003413 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00003414 if ((flags & (RhoValue|SigmaValue)) == 0)
3415 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00003416 if ((flags & SigmaValue) == 0)
3417 geometry_info.sigma=1.0;
3418 if ((flags & XiValue) == 0)
anthony92c93bd2012-03-19 14:02:47 +00003419 geometry_info.xi=0.1*_image->columns;
anthony805a2d42011-09-25 08:25:12 +00003420 if ((flags & PsiValue) == 0)
anthony92c93bd2012-03-19 14:02:47 +00003421 geometry_info.psi=0.1*_image->rows;
3422 new_image=VignetteImage(_image,geometry_info.rho,geometry_info.sigma,
cristyaa2c16c2012-03-25 22:21:35 +00003423 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
3424 ceil(geometry_info.psi-0.5),_exception);
anthony805a2d42011-09-25 08:25:12 +00003425 break;
3426 }
anthonyebb73a22012-03-22 14:25:52 +00003427 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003428 }
3429 case 'w':
3430 {
anthonyafa3dfc2012-03-03 11:31:30 +00003431 if (LocaleCompare("wave",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003432 {
anthonyfd706f92012-01-19 04:22:02 +00003433 flags=ParseGeometry(arg1,&geometry_info);
anthony22de2722012-04-19 14:43:00 +00003434 if ((flags & (RhoValue|SigmaValue)) == 0)
3435 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00003436 if ((flags & SigmaValue) == 0)
3437 geometry_info.sigma=1.0;
anthony92c93bd2012-03-19 14:02:47 +00003438 new_image=WaveImage(_image,geometry_info.rho,geometry_info.sigma,
3439 _image->interpolate,_exception);
anthony805a2d42011-09-25 08:25:12 +00003440 break;
3441 }
anthonyafa3dfc2012-03-03 11:31:30 +00003442 if (LocaleCompare("white-threshold",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003443 {
anthony7bcfe7f2012-03-30 14:01:22 +00003444 if (IfMagickFalse(IsGeometry(arg1)))
anthony52bef752012-03-27 13:54:47 +00003445 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003446 (void) WhiteThresholdImage(_image,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00003447 break;
3448 }
anthonyebb73a22012-03-22 14:25:52 +00003449 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003450 }
3451 default:
anthonyebb73a22012-03-22 14:25:52 +00003452 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003453 }
3454 /*
3455 Replace current image with any image that was generated
anthony31f1bf72012-01-30 12:37:22 +00003456 and set image point to last image (so image->next is correct)
anthony805a2d42011-09-25 08:25:12 +00003457 */
3458 if (new_image != (Image *) NULL)
anthony92c93bd2012-03-19 14:02:47 +00003459 ReplaceImageInListReturnLast(&_image,new_image);
anthony805a2d42011-09-25 08:25:12 +00003460
anthony31f1bf72012-01-30 12:37:22 +00003461 return;
anthony92c93bd2012-03-19 14:02:47 +00003462#undef _image_info
3463#undef _draw_info
3464#undef _quantize_info
3465#undef _image
3466#undef _exception
anthonyafa3dfc2012-03-03 11:31:30 +00003467#undef IfNormalOp
3468#undef IfPlusOp
anthony31f1bf72012-01-30 12:37:22 +00003469#undef normal_op
anthonyafa3dfc2012-03-03 11:31:30 +00003470#undef plus_alt_op
anthony31f1bf72012-01-30 12:37:22 +00003471}
anthonyfd706f92012-01-19 04:22:02 +00003472
anthony43f425d2012-02-26 12:58:58 +00003473WandExport void CLISimpleOperatorImages(MagickCLI *cli_wand,
anthonyafa3dfc2012-03-03 11:31:30 +00003474 const char *option, const char *arg1, const char *arg2)
anthony31f1bf72012-01-30 12:37:22 +00003475{
3476 size_t
anthony43f425d2012-02-26 12:58:58 +00003477 n,
anthony31f1bf72012-01-30 12:37:22 +00003478 i;
3479
anthony43f425d2012-02-26 12:58:58 +00003480 assert(cli_wand != (MagickCLI *) NULL);
3481 assert(cli_wand->signature == WandSignature);
3482 assert(cli_wand->wand.signature == WandSignature);
3483 assert(cli_wand->wand.images != (Image *) NULL); /* images must be present */
anthony7bcfe7f2012-03-30 14:01:22 +00003484 if (IfMagickTrue(cli_wand->wand.debug))
anthony43f425d2012-02-26 12:58:58 +00003485 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
anthony31f1bf72012-01-30 12:37:22 +00003486
anthonyafa3dfc2012-03-03 11:31:30 +00003487#if !USE_WAND_METHODS
3488 /* FUTURE add appropriate tracing */
anthony31f1bf72012-01-30 12:37:22 +00003489 i=0;
anthony43f425d2012-02-26 12:58:58 +00003490 n=GetImageListLength(cli_wand->wand.images);
3491 cli_wand->wand.images=GetFirstImageInList(cli_wand->wand.images);
anthonyafa3dfc2012-03-03 11:31:30 +00003492 while (1) {
anthony31f1bf72012-01-30 12:37:22 +00003493 i++;
anthonyafa3dfc2012-03-03 11:31:30 +00003494 CLISimpleOperatorImage(cli_wand, option, arg1, arg2);
anthony43f425d2012-02-26 12:58:58 +00003495 if ( cli_wand->wand.images->next == (Image *) NULL )
3496 break;
3497 cli_wand->wand.images=cli_wand->wand.images->next;
anthony31f1bf72012-01-30 12:37:22 +00003498 }
anthony43f425d2012-02-26 12:58:58 +00003499 assert( i == n );
3500 cli_wand->wand.images=GetFirstImageInList(cli_wand->wand.images);
anthonyafa3dfc2012-03-03 11:31:30 +00003501#else
3502 MagickResetIterator(&cli_wand->wand);
anthony7bcfe7f2012-03-30 14:01:22 +00003503 while ( IfMagickTrue(MagickNextImage(&cli_wand->wand)) )
anthonyafa3dfc2012-03-03 11:31:30 +00003504 CLISimpleOperatorImage(cli_wand, option, arg1, arg2);
3505 MagickResetIterator(&cli_wand->wand);
3506#endif
anthony31f1bf72012-01-30 12:37:22 +00003507 return;
anthony805a2d42011-09-25 08:25:12 +00003508}
3509
3510/*
3511%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3512% %
3513% %
3514% %
anthony43f425d2012-02-26 12:58:58 +00003515+ 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 +00003516% %
3517% %
3518% %
3519%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3520%
anthony43f425d2012-02-26 12:58:58 +00003521% CLIListOperatorImages() applies a single operation that is apply to the
anthony31f1bf72012-01-30 12:37:22 +00003522% entire image list as a whole. The result is often a complete replacment
3523% of the image list with a completely new list, or just a single image.
anthony805a2d42011-09-25 08:25:12 +00003524%
3525% The format of the MogrifyImage method is:
3526%
anthony43f425d2012-02-26 12:58:58 +00003527% void CLIListOperatorImages(MagickCLI *cli_wand,
anthonyafa3dfc2012-03-03 11:31:30 +00003528% const char *option, const char *arg1, const char *arg2)
anthony805a2d42011-09-25 08:25:12 +00003529%
3530% A description of each parameter follows:
3531%
anthony43f425d2012-02-26 12:58:58 +00003532% o cli_wand: structure holding settings to be applied
anthony805a2d42011-09-25 08:25:12 +00003533%
anthony36a8c2c2012-02-10 00:08:44 +00003534% o option: The option string for the operation
3535%
anthony31f1bf72012-01-30 12:37:22 +00003536% o arg1, arg2: optional argument strings to the operation
anthonye5fcd362012-04-09 04:02:09 +00003537% arg2 is currently not used
anthony8b10b462012-02-08 12:32:44 +00003538%
3539% Example usage...
3540%
anthonyafa3dfc2012-03-03 11:31:30 +00003541% CLIListOperatorImages(cli_wand,MagickFalse,"-duplicate", "3", NULL);
3542% CLIListOperatorImages(cli_wand,MagickTrue, "+append", NULL, NULL);
anthony8b10b462012-02-08 12:32:44 +00003543%
anthony24aa8822012-03-11 00:56:06 +00003544% Or for handling command line arguments EG: +/-option ["arg1"]
anthony8b10b462012-02-08 12:32:44 +00003545%
anthony43f425d2012-02-26 12:58:58 +00003546% cli_wand
anthony8b10b462012-02-08 12:32:44 +00003547% argc,argv
3548% i=index in argv
3549%
anthony2052d272012-02-28 12:48:29 +00003550% option_info = GetCommandOptionInfo(argv[i]);
3551% count=option_info->type;
3552% option_type=option_info->flags;
3553%
3554% if ( (option_type & ListOperatorOptionFlag) != 0 )
anthonyafa3dfc2012-03-03 11:31:30 +00003555% CLIListOperatorImages(cli_wand,argv[i],
anthony8b10b462012-02-08 12:32:44 +00003556% count>=1 ? argv[i+1] : (char *)NULL,
3557% count>=2 ? argv[i+2] : (char *)NULL );
3558% i += count+1;
3559%
anthony805a2d42011-09-25 08:25:12 +00003560*/
anthony43f425d2012-02-26 12:58:58 +00003561WandExport void CLIListOperatorImages(MagickCLI *cli_wand,
anthonye5fcd362012-04-09 04:02:09 +00003562 const char *option,const char *arg1, const char *magick_unused(arg2))
anthony805a2d42011-09-25 08:25:12 +00003563{
anthony2a0ec8c2012-03-24 04:35:56 +00003564 ssize_t
3565 parse;
3566
anthony31f1bf72012-01-30 12:37:22 +00003567 Image
3568 *new_images;
anthony805a2d42011-09-25 08:25:12 +00003569
anthony2e4501b2012-03-30 04:41:54 +00003570#define _image_info (cli_wand->wand.image_info)
3571#define _images (cli_wand->wand.images)
3572#define _exception (cli_wand->wand.exception)
3573#define _draw_info (cli_wand->draw_info)
3574#define _quantize_info (cli_wand->quantize_info)
anthonyafa3dfc2012-03-03 11:31:30 +00003575#define IfNormalOp (*option=='-')
3576#define IfPlusOp (*option!='-')
anthony7bcfe7f2012-03-30 14:01:22 +00003577#define normal_op IsMagickTrue(IfNormalOp)
anthony805a2d42011-09-25 08:25:12 +00003578
anthony43f425d2012-02-26 12:58:58 +00003579 assert(cli_wand != (MagickCLI *) NULL);
3580 assert(cli_wand->signature == WandSignature);
3581 assert(cli_wand->wand.signature == WandSignature);
anthony92c93bd2012-03-19 14:02:47 +00003582 assert(_images != (Image *) NULL); /* _images must be present */
anthony7bcfe7f2012-03-30 14:01:22 +00003583 if (IfMagickTrue(cli_wand->wand.debug))
anthony43f425d2012-02-26 12:58:58 +00003584 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
anthony31f1bf72012-01-30 12:37:22 +00003585
anthony92c93bd2012-03-19 14:02:47 +00003586 (void) SyncImagesSettings(_image_info,_images,_exception);
anthony31f1bf72012-01-30 12:37:22 +00003587
3588 new_images=NewImageList();
3589
anthonyafa3dfc2012-03-03 11:31:30 +00003590 switch (*(option+1))
anthony805a2d42011-09-25 08:25:12 +00003591 {
3592 case 'a':
3593 {
anthonyafa3dfc2012-03-03 11:31:30 +00003594 if (LocaleCompare("append",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003595 {
anthony92c93bd2012-03-19 14:02:47 +00003596 new_images=AppendImages(_images,normal_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00003597 break;
3598 }
anthonyafa3dfc2012-03-03 11:31:30 +00003599 if (LocaleCompare("average",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003600 {
anthony975a8d72012-04-12 13:54:36 +00003601 CLIWandWarnDepreciated("-evaluate-sequence Mean");
anthonyafa3dfc2012-03-03 11:31:30 +00003602 CLIListOperatorImages(cli_wand,"-evaluate-sequence","Mean",NULL);
anthony805a2d42011-09-25 08:25:12 +00003603 break;
3604 }
anthonyebb73a22012-03-22 14:25:52 +00003605 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003606 }
3607 case 'c':
3608 {
cristy5f257b22012-03-07 00:27:29 +00003609 if (LocaleCompare("channel-fx",option+1) == 0)
cristy87c02f42012-02-24 00:19:10 +00003610 {
anthony92c93bd2012-03-19 14:02:47 +00003611 new_images=ChannelFxImage(_images,arg1,_exception);
cristy87c02f42012-02-24 00:19:10 +00003612 break;
3613 }
anthonyafa3dfc2012-03-03 11:31:30 +00003614 if (LocaleCompare("clut",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003615 {
anthony805a2d42011-09-25 08:25:12 +00003616 Image
anthony31f1bf72012-01-30 12:37:22 +00003617 *clut_image;
anthony805a2d42011-09-25 08:25:12 +00003618
anthonyafa3dfc2012-03-03 11:31:30 +00003619 /* FUTURE - make this a compose option, and thus can be used
3620 with layers compose or even compose last image over all other
anthony92c93bd2012-03-19 14:02:47 +00003621 _images.
cristy87c02f42012-02-24 00:19:10 +00003622 */
anthony92c93bd2012-03-19 14:02:47 +00003623 new_images=RemoveFirstImageFromList(&_images);
3624 clut_image=RemoveLastImageFromList(&_images);
anthonye8f56492012-02-12 12:39:02 +00003625 /* FUTURE - produce Exception, rather than silent fail */
anthony805a2d42011-09-25 08:25:12 +00003626 if (clut_image == (Image *) NULL)
cristy87c02f42012-02-24 00:19:10 +00003627 break;
cristye52fb5e2012-04-06 23:30:20 +00003628 (void) ClutImage(new_images,clut_image,new_images->interpolate,_exception);
anthony805a2d42011-09-25 08:25:12 +00003629 clut_image=DestroyImage(clut_image);
anthony805a2d42011-09-25 08:25:12 +00003630 break;
3631 }
anthonyafa3dfc2012-03-03 11:31:30 +00003632 if (LocaleCompare("coalesce",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003633 {
anthony92c93bd2012-03-19 14:02:47 +00003634 new_images=CoalesceImages(_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003635 break;
3636 }
anthonyafa3dfc2012-03-03 11:31:30 +00003637 if (LocaleCompare("combine",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003638 {
anthony43f425d2012-02-26 12:58:58 +00003639 /* FUTURE - this may be replaced by a 'channel' method */
anthony92c93bd2012-03-19 14:02:47 +00003640 new_images=CombineImages(_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003641 break;
3642 }
anthonyafa3dfc2012-03-03 11:31:30 +00003643 if (LocaleCompare("composite",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003644 {
cristyfeb3e962012-03-29 17:25:55 +00003645 CompositeOperator
3646 compose;
3647
3648 const char*
3649 value;
3650
3651 MagickBooleanType
3652 clip_to_self;
3653
anthony805a2d42011-09-25 08:25:12 +00003654 Image
3655 *mask_image,
anthony31f1bf72012-01-30 12:37:22 +00003656 *source_image;
anthony805a2d42011-09-25 08:25:12 +00003657
3658 RectangleInfo
3659 geometry;
3660
anthony7bcfe7f2012-03-30 14:01:22 +00003661 /* Compose value from "-compose" option only */
anthony92c93bd2012-03-19 14:02:47 +00003662 value=GetImageOption(_image_info,"compose");
cristy542a95b2012-04-03 19:30:58 +00003663 if (value == (const char *) NULL)
anthony31f1bf72012-01-30 12:37:22 +00003664 compose=OverCompositeOp; /* use Over not source_image->compose */
cristy542a95b2012-04-03 19:30:58 +00003665 else
3666 compose=(CompositeOperator) ParseCommandOption(MagickComposeOptions,
3667 MagickFalse,value);
anthony5f867ae2011-10-09 10:28:34 +00003668
anthony7bcfe7f2012-03-30 14:01:22 +00003669 /* Get "clip-to-self" expert setting (false is normal) */
cristyca0e82c2012-04-10 11:53:24 +00003670 value=GetImageOption(_image_info,"compose:clip-to-self");
3671 if (value == (const char *) NULL)
3672 clip_to_self=MagickTrue;
3673 else
3674 clip_to_self=IsStringTrue(GetImageOption(_image_info,
3675 "compose:clip-to-self")); /* if this is true */
anthony2e4501b2012-03-30 04:41:54 +00003676 value=GetImageOption(_image_info,"compose:outside-overlay");
anthony7bcfe7f2012-03-30 14:01:22 +00003677 if (value != (const char *) NULL) { /* or this false */
anthony2e4501b2012-03-30 04:41:54 +00003678 /* FUTURE: depreciate warning for "compose:outside-overlay"*/
anthony7bcfe7f2012-03-30 14:01:22 +00003679 clip_to_self= IsMagickFalse(IsStringNotFalse(value));
anthony2e4501b2012-03-30 04:41:54 +00003680 }
3681
anthony92c93bd2012-03-19 14:02:47 +00003682 new_images=RemoveFirstImageFromList(&_images);
3683 source_image=RemoveFirstImageFromList(&_images);
anthony31f1bf72012-01-30 12:37:22 +00003684 if (source_image == (Image *) NULL)
anthony7bcfe7f2012-03-30 14:01:22 +00003685 break; /* FUTURE - produce Exception, rather than silent fail */
anthonye8f56492012-02-12 12:39:02 +00003686
anthony31f1bf72012-01-30 12:37:22 +00003687 /* FUTURE - this should not be here! - should be part of -geometry */
3688 (void) TransformImage(&source_image,(char *) NULL,
anthony92c93bd2012-03-19 14:02:47 +00003689 source_image->geometry,_exception);
anthony5f867ae2011-10-09 10:28:34 +00003690
anthony31f1bf72012-01-30 12:37:22 +00003691 SetGeometry(source_image,&geometry);
3692 (void) ParseAbsoluteGeometry(source_image->geometry,&geometry);
3693 GravityAdjustGeometry(new_images->columns,new_images->rows,
3694 new_images->gravity, &geometry);
anthony5f867ae2011-10-09 10:28:34 +00003695
anthony92c93bd2012-03-19 14:02:47 +00003696 mask_image=RemoveFirstImageFromList(&_images);
anthony805a2d42011-09-25 08:25:12 +00003697 if (mask_image != (Image *) NULL)
anthony31f1bf72012-01-30 12:37:22 +00003698 { /* handle a third write mask image */
anthony5f867ae2011-10-09 10:28:34 +00003699 if ((compose == DisplaceCompositeOp) ||
anthony7bcfe7f2012-03-30 14:01:22 +00003700 (compose == DistortCompositeOp)) {
3701 /* Merge Y displacement into X displace/distort map. */
3702 (void) CompositeImage(source_image,mask_image,
3703 CopyGreenCompositeOp,MagickTrue,0,0,_exception);
3704 mask_image=DestroyImage(mask_image);
3705 }
3706 else {
3707 /* Set a blending mask for the composition. */
3708 (void) NegateImage(mask_image,MagickFalse,_exception);
3709 (void) SetImageMask(new_images,mask_image,_exception);
3710 mask_image=DestroyImage(mask_image);
3711 }
anthony805a2d42011-09-25 08:25:12 +00003712 }
cristyfeb3e962012-03-29 17:25:55 +00003713 (void) CompositeImage(new_images,source_image,compose,clip_to_self,
3714 geometry.x,geometry.y,_exception);
anthony92c93bd2012-03-19 14:02:47 +00003715 (void) SetImageMask(new_images,(Image *) NULL,_exception);
anthony31f1bf72012-01-30 12:37:22 +00003716 source_image=DestroyImage(source_image);
anthony805a2d42011-09-25 08:25:12 +00003717 break;
3718 }
anthonyebb73a22012-03-22 14:25:52 +00003719 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003720 }
3721 case 'd':
3722 {
anthonyafa3dfc2012-03-03 11:31:30 +00003723 if (LocaleCompare("deconstruct",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003724 {
anthony975a8d72012-04-12 13:54:36 +00003725 CLIWandWarnDepreciated("-layer CompareAny");
anthonyafa3dfc2012-03-03 11:31:30 +00003726 CLIListOperatorImages(cli_wand,"-layer","CompareAny",NULL);
anthony805a2d42011-09-25 08:25:12 +00003727 break;
3728 }
anthonyafa3dfc2012-03-03 11:31:30 +00003729 if (LocaleCompare("delete",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003730 {
anthonyafa3dfc2012-03-03 11:31:30 +00003731 if (IfNormalOp)
anthony92c93bd2012-03-19 14:02:47 +00003732 DeleteImages(&_images,arg1,_exception);
anthonyafa3dfc2012-03-03 11:31:30 +00003733 else
anthony92c93bd2012-03-19 14:02:47 +00003734 DeleteImages(&_images,"-1",_exception);
anthony805a2d42011-09-25 08:25:12 +00003735 break;
3736 }
anthonyafa3dfc2012-03-03 11:31:30 +00003737 if (LocaleCompare("duplicate",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003738 {
anthonyafa3dfc2012-03-03 11:31:30 +00003739 if (IfNormalOp)
anthony805a2d42011-09-25 08:25:12 +00003740 {
3741 const char
3742 *p;
3743
3744 size_t
3745 number_duplicates;
3746
anthony7bcfe7f2012-03-30 14:01:22 +00003747 if (IfMagickFalse(IsGeometry(arg1)))
anthonyebb73a22012-03-22 14:25:52 +00003748 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,
3749 arg1);
anthony31f1bf72012-01-30 12:37:22 +00003750 number_duplicates=(size_t) StringToLong(arg1);
3751 p=strchr(arg1,',');
anthony805a2d42011-09-25 08:25:12 +00003752 if (p == (const char *) NULL)
anthonyebb73a22012-03-22 14:25:52 +00003753 new_images=DuplicateImages(_images,number_duplicates,"-1",
3754 _exception);
anthony805a2d42011-09-25 08:25:12 +00003755 else
anthony92c93bd2012-03-19 14:02:47 +00003756 new_images=DuplicateImages(_images,number_duplicates,p,
3757 _exception);
anthony805a2d42011-09-25 08:25:12 +00003758 }
anthonyafa3dfc2012-03-03 11:31:30 +00003759 else
anthony92c93bd2012-03-19 14:02:47 +00003760 new_images=DuplicateImages(_images,1,"-1",_exception);
3761 AppendImageToList(&_images, new_images);
anthony36a8c2c2012-02-10 00:08:44 +00003762 new_images=(Image *)NULL;
anthony805a2d42011-09-25 08:25:12 +00003763 break;
3764 }
anthonyebb73a22012-03-22 14:25:52 +00003765 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003766 }
3767 case 'e':
3768 {
anthonyafa3dfc2012-03-03 11:31:30 +00003769 if (LocaleCompare("evaluate-sequence",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003770 {
anthony2a0ec8c2012-03-24 04:35:56 +00003771 parse = ParseCommandOption(MagickEvaluateOptions,MagickFalse,arg1);
3772 if ( parse < 0 )
3773 CLIWandExceptArgBreak(OptionError,"UnrecognizedEvaluateOperator",
3774 option,arg1);
3775 new_images=EvaluateImages(_images,(MagickEvaluateOperator)parse,
3776 _exception);
anthony805a2d42011-09-25 08:25:12 +00003777 break;
3778 }
anthonyebb73a22012-03-22 14:25:52 +00003779 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003780 }
3781 case 'f':
3782 {
anthonyafa3dfc2012-03-03 11:31:30 +00003783 if (LocaleCompare("fft",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003784 {
anthony92c93bd2012-03-19 14:02:47 +00003785 new_images=ForwardFourierTransformImage(_images,normal_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00003786 break;
3787 }
anthonyafa3dfc2012-03-03 11:31:30 +00003788 if (LocaleCompare("flatten",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003789 {
anthony319dac62012-03-06 04:12:44 +00003790 /* REDIRECTED to use -layers flatten instead */
anthony2e4501b2012-03-30 04:41:54 +00003791 CLIListOperatorImages(cli_wand,"-layers",option+1,NULL);
anthony805a2d42011-09-25 08:25:12 +00003792 break;
3793 }
anthonyafa3dfc2012-03-03 11:31:30 +00003794 if (LocaleCompare("fx",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003795 {
anthony92c93bd2012-03-19 14:02:47 +00003796 new_images=FxImage(_images,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00003797 break;
3798 }
anthonyebb73a22012-03-22 14:25:52 +00003799 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003800 }
3801 case 'h':
3802 {
anthonyafa3dfc2012-03-03 11:31:30 +00003803 if (LocaleCompare("hald-clut",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003804 {
anthony31f1bf72012-01-30 12:37:22 +00003805 /* FUTURE - make this a compose option (and thus layers compose )
anthony92c93bd2012-03-19 14:02:47 +00003806 or perhaps compose last image over all other _images.
anthony31f1bf72012-01-30 12:37:22 +00003807 */
anthony805a2d42011-09-25 08:25:12 +00003808 Image
anthony31f1bf72012-01-30 12:37:22 +00003809 *hald_image;
anthony805a2d42011-09-25 08:25:12 +00003810
anthony92c93bd2012-03-19 14:02:47 +00003811 new_images=RemoveFirstImageFromList(&_images);
3812 hald_image=RemoveLastImageFromList(&_images);
anthony805a2d42011-09-25 08:25:12 +00003813 if (hald_image == (Image *) NULL)
anthony31f1bf72012-01-30 12:37:22 +00003814 break;
anthony92c93bd2012-03-19 14:02:47 +00003815 (void) HaldClutImage(new_images,hald_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00003816 hald_image=DestroyImage(hald_image);
anthony805a2d42011-09-25 08:25:12 +00003817 break;
3818 }
anthonyebb73a22012-03-22 14:25:52 +00003819 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003820 }
3821 case 'i':
3822 {
anthonyafa3dfc2012-03-03 11:31:30 +00003823 if (LocaleCompare("ift",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003824 {
3825 Image
anthony805a2d42011-09-25 08:25:12 +00003826 *magnitude_image,
3827 *phase_image;
3828
anthony92c93bd2012-03-19 14:02:47 +00003829 magnitude_image=RemoveFirstImageFromList(&_images);
3830 phase_image=RemoveFirstImageFromList(&_images);
anthonye8f56492012-02-12 12:39:02 +00003831 /* FUTURE - produce Exception, rather than silent fail */
anthony31f1bf72012-01-30 12:37:22 +00003832 if (phase_image == (Image *) NULL)
3833 break;
3834 new_images=InverseFourierTransformImage(magnitude_image,phase_image,
anthony92c93bd2012-03-19 14:02:47 +00003835 normal_op,_exception);
anthony31f1bf72012-01-30 12:37:22 +00003836 magnitude_image=DestroyImage(magnitude_image);
3837 phase_image=DestroyImage(phase_image);
anthony805a2d42011-09-25 08:25:12 +00003838 break;
3839 }
anthonyafa3dfc2012-03-03 11:31:30 +00003840 if (LocaleCompare("insert",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003841 {
3842 Image
anthony31f1bf72012-01-30 12:37:22 +00003843 *insert_image,
3844 *index_image;
3845
3846 ssize_t
3847 index;
anthony805a2d42011-09-25 08:25:12 +00003848
anthony7bcfe7f2012-03-30 14:01:22 +00003849 if (IfNormalOp && IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00003850 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00003851 index=0;
anthony92c93bd2012-03-19 14:02:47 +00003852 insert_image=RemoveLastImageFromList(&_images);
anthonyafa3dfc2012-03-03 11:31:30 +00003853 if (IfNormalOp)
anthony31f1bf72012-01-30 12:37:22 +00003854 index=(ssize_t) StringToLong(arg1);
anthony43f425d2012-02-26 12:58:58 +00003855 index_image=insert_image;
anthony805a2d42011-09-25 08:25:12 +00003856 if (index == 0)
anthony92c93bd2012-03-19 14:02:47 +00003857 PrependImageToList(&_images,insert_image);
3858 else if (index == (ssize_t) GetImageListLength(_images))
3859 AppendImageToList(&_images,insert_image);
anthony805a2d42011-09-25 08:25:12 +00003860 else
anthony43f425d2012-02-26 12:58:58 +00003861 {
anthony92c93bd2012-03-19 14:02:47 +00003862 index_image=GetImageFromList(_images,index-1);
anthony43f425d2012-02-26 12:58:58 +00003863 if (index_image == (Image *) NULL)
anthonyfe1aa782012-03-24 13:43:04 +00003864 CLIWandExceptArgBreak(OptionError,"NoSuchImage",option,arg1);
anthony43f425d2012-02-26 12:58:58 +00003865 InsertImageInList(&index_image,insert_image);
3866 }
anthony92c93bd2012-03-19 14:02:47 +00003867 _images=GetFirstImageInList(index_image);
anthony805a2d42011-09-25 08:25:12 +00003868 break;
3869 }
anthonyebb73a22012-03-22 14:25:52 +00003870 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003871 }
3872 case 'l':
3873 {
anthonyafa3dfc2012-03-03 11:31:30 +00003874 if (LocaleCompare("layers",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003875 {
anthonyfe1aa782012-03-24 13:43:04 +00003876 parse=ParseCommandOption(MagickLayerOptions,MagickFalse,arg1);
3877 if ( parse < 0 )
3878 CLIWandExceptArgBreak(OptionError,"UnrecognizedLayerMethod",
3879 option,arg1);
3880 switch ((ImageLayerMethod) parse)
anthony805a2d42011-09-25 08:25:12 +00003881 {
3882 case CoalesceLayer:
3883 {
anthony92c93bd2012-03-19 14:02:47 +00003884 new_images=CoalesceImages(_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003885 break;
3886 }
3887 case CompareAnyLayer:
3888 case CompareClearLayer:
3889 case CompareOverlayLayer:
3890 default:
3891 {
anthonyfe1aa782012-03-24 13:43:04 +00003892 new_images=CompareImagesLayers(_images,(ImageLayerMethod) parse,
3893 _exception);
anthony805a2d42011-09-25 08:25:12 +00003894 break;
3895 }
3896 case MergeLayer:
3897 case FlattenLayer:
3898 case MosaicLayer:
3899 case TrimBoundsLayer:
3900 {
anthonyfe1aa782012-03-24 13:43:04 +00003901 new_images=MergeImageLayers(_images,(ImageLayerMethod) parse,
3902 _exception);
anthony805a2d42011-09-25 08:25:12 +00003903 break;
3904 }
3905 case DisposeLayer:
3906 {
anthony92c93bd2012-03-19 14:02:47 +00003907 new_images=DisposeImages(_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003908 break;
3909 }
3910 case OptimizeImageLayer:
3911 {
anthony92c93bd2012-03-19 14:02:47 +00003912 new_images=OptimizeImageLayers(_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003913 break;
3914 }
3915 case OptimizePlusLayer:
3916 {
anthony92c93bd2012-03-19 14:02:47 +00003917 new_images=OptimizePlusImageLayers(_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003918 break;
3919 }
3920 case OptimizeTransLayer:
3921 {
anthony92c93bd2012-03-19 14:02:47 +00003922 OptimizeImageTransparency(_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003923 break;
3924 }
3925 case RemoveDupsLayer:
3926 {
anthony92c93bd2012-03-19 14:02:47 +00003927 RemoveDuplicateLayers(&_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003928 break;
3929 }
3930 case RemoveZeroLayer:
3931 {
anthony92c93bd2012-03-19 14:02:47 +00003932 RemoveZeroDelayLayers(&_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003933 break;
3934 }
3935 case OptimizeLayer:
anthony31f1bf72012-01-30 12:37:22 +00003936 { /* General Purpose, GIF Animation Optimizer. */
anthony92c93bd2012-03-19 14:02:47 +00003937 new_images=CoalesceImages(_images,_exception);
anthony31f1bf72012-01-30 12:37:22 +00003938 if (new_images == (Image *) NULL)
3939 break;
anthony92c93bd2012-03-19 14:02:47 +00003940 _images=DestroyImageList(_images);
3941 _images=OptimizeImageLayers(new_images,_exception);
3942 if (_images == (Image *) NULL)
anthony31f1bf72012-01-30 12:37:22 +00003943 break;
3944 new_images=DestroyImageList(new_images);
anthony92c93bd2012-03-19 14:02:47 +00003945 OptimizeImageTransparency(_images,_exception);
3946 (void) RemapImages(_quantize_info,_images,(Image *) NULL,
3947 _exception);
anthony805a2d42011-09-25 08:25:12 +00003948 break;
3949 }
3950 case CompositeLayer:
3951 {
anthony805a2d42011-09-25 08:25:12 +00003952 Image
3953 *source;
3954
3955 RectangleInfo
3956 geometry;
3957
anthony31f1bf72012-01-30 12:37:22 +00003958 CompositeOperator
anthony5f867ae2011-10-09 10:28:34 +00003959 compose;
3960
3961 const char*
3962 value;
3963
anthony92c93bd2012-03-19 14:02:47 +00003964 value=GetImageOption(_image_info,"compose");
anthony31f1bf72012-01-30 12:37:22 +00003965 compose=OverCompositeOp; /* Default to Over */
anthony5f867ae2011-10-09 10:28:34 +00003966 if (value != (const char *) NULL)
3967 compose=(CompositeOperator) ParseCommandOption(
3968 MagickComposeOptions,MagickFalse,value);
anthony5f867ae2011-10-09 10:28:34 +00003969
anthony31f1bf72012-01-30 12:37:22 +00003970 /* Split image sequence at the first 'NULL:' image. */
anthony92c93bd2012-03-19 14:02:47 +00003971 source=_images;
anthony805a2d42011-09-25 08:25:12 +00003972 while (source != (Image *) NULL)
3973 {
3974 source=GetNextImageInList(source);
3975 if ((source != (Image *) NULL) &&
3976 (LocaleCompare(source->magick,"NULL") == 0))
3977 break;
3978 }
3979 if (source != (Image *) NULL)
3980 {
3981 if ((GetPreviousImageInList(source) == (Image *) NULL) ||
3982 (GetNextImageInList(source) == (Image *) NULL))
3983 source=(Image *) NULL;
3984 else
anthony31f1bf72012-01-30 12:37:22 +00003985 { /* Separate the two lists, junk the null: image. */
anthony805a2d42011-09-25 08:25:12 +00003986 source=SplitImageList(source->previous);
3987 DeleteImageFromList(&source);
3988 }
3989 }
3990 if (source == (Image *) NULL)
3991 {
anthony92c93bd2012-03-19 14:02:47 +00003992 (void) ThrowMagickException(_exception,GetMagickModule(),
anthony805a2d42011-09-25 08:25:12 +00003993 OptionError,"MissingNullSeparator","layers Composite");
anthony805a2d42011-09-25 08:25:12 +00003994 break;
3995 }
anthony31f1bf72012-01-30 12:37:22 +00003996 /* Adjust offset with gravity and virtual canvas. */
anthony92c93bd2012-03-19 14:02:47 +00003997 SetGeometry(_images,&geometry);
3998 (void) ParseAbsoluteGeometry(_images->geometry,&geometry);
anthony805a2d42011-09-25 08:25:12 +00003999 geometry.width=source->page.width != 0 ?
4000 source->page.width : source->columns;
4001 geometry.height=source->page.height != 0 ?
4002 source->page.height : source->rows;
anthony92c93bd2012-03-19 14:02:47 +00004003 GravityAdjustGeometry(_images->page.width != 0 ?
4004 _images->page.width : _images->columns,
4005 _images->page.height != 0 ? _images->page.height :
4006 _images->rows,_images->gravity,&geometry);
anthony5f867ae2011-10-09 10:28:34 +00004007
anthony31f1bf72012-01-30 12:37:22 +00004008 /* Compose the two image sequences together */
anthony92c93bd2012-03-19 14:02:47 +00004009 CompositeLayers(_images,compose,source,geometry.x,geometry.y,
4010 _exception);
anthony805a2d42011-09-25 08:25:12 +00004011 source=DestroyImageList(source);
4012 break;
4013 }
4014 }
anthony805a2d42011-09-25 08:25:12 +00004015 break;
4016 }
anthonyebb73a22012-03-22 14:25:52 +00004017 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00004018 }
4019 case 'm':
4020 {
anthonyafa3dfc2012-03-03 11:31:30 +00004021 if (LocaleCompare("map",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00004022 {
anthony975a8d72012-04-12 13:54:36 +00004023 CLIWandWarnDepreciated("+remap");
anthony92c93bd2012-03-19 14:02:47 +00004024 (void) RemapImages(_quantize_info,_images,(Image *) NULL,_exception);
anthony805a2d42011-09-25 08:25:12 +00004025 break;
4026 }
anthonyafa3dfc2012-03-03 11:31:30 +00004027 if (LocaleCompare("morph",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00004028 {
4029 Image
4030 *morph_image;
4031
anthony7bcfe7f2012-03-30 14:01:22 +00004032 if (IfMagickFalse(IsGeometry(arg1)))
anthony7bc87992012-03-25 02:32:51 +00004033 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00004034 morph_image=MorphImages(_images,StringToUnsignedLong(arg1),
4035 _exception);
anthony805a2d42011-09-25 08:25:12 +00004036 if (morph_image == (Image *) NULL)
anthony31f1bf72012-01-30 12:37:22 +00004037 break;
anthony92c93bd2012-03-19 14:02:47 +00004038 _images=DestroyImageList(_images);
4039 _images=morph_image;
anthony805a2d42011-09-25 08:25:12 +00004040 break;
4041 }
anthonyafa3dfc2012-03-03 11:31:30 +00004042 if (LocaleCompare("mosaic",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00004043 {
anthony319dac62012-03-06 04:12:44 +00004044 /* REDIRECTED to use -layers mosaic instead */
anthony2e4501b2012-03-30 04:41:54 +00004045 CLIListOperatorImages(cli_wand,"-layers",option+1,NULL);
anthony805a2d42011-09-25 08:25:12 +00004046 break;
4047 }
anthonyebb73a22012-03-22 14:25:52 +00004048 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00004049 }
4050 case 'p':
4051 {
anthonyafa3dfc2012-03-03 11:31:30 +00004052 if (LocaleCompare("print",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00004053 {
4054 char
4055 *string;
4056
anthony92c93bd2012-03-19 14:02:47 +00004057 string=InterpretImageProperties(_image_info,_images,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00004058 if (string == (char *) NULL)
4059 break;
4060 (void) FormatLocaleFile(stdout,"%s",string);
4061 string=DestroyString(string);
anthony24aa8822012-03-11 00:56:06 +00004062 break;
anthony805a2d42011-09-25 08:25:12 +00004063 }
anthonyafa3dfc2012-03-03 11:31:30 +00004064 if (LocaleCompare("process",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00004065 {
anthonyb1d483a2012-04-14 12:53:56 +00004066 /* FUTURE: better parsing using ScriptToken() from string ??? */
anthony805a2d42011-09-25 08:25:12 +00004067 char
4068 **arguments;
4069
4070 int
4071 j,
4072 number_arguments;
4073
anthony31f1bf72012-01-30 12:37:22 +00004074 arguments=StringToArgv(arg1,&number_arguments);
anthony805a2d42011-09-25 08:25:12 +00004075 if (arguments == (char **) NULL)
4076 break;
anthony31f1bf72012-01-30 12:37:22 +00004077 if (strchr(arguments[1],'=') != (char *) NULL)
anthony805a2d42011-09-25 08:25:12 +00004078 {
4079 char
4080 breaker,
4081 quote,
4082 *token;
4083
4084 const char
4085 *arguments;
4086
4087 int
4088 next,
4089 status;
4090
4091 size_t
4092 length;
4093
4094 TokenInfo
4095 *token_info;
4096
4097 /*
anthony24aa8822012-03-11 00:56:06 +00004098 Support old style syntax, filter="-option arg1".
anthony805a2d42011-09-25 08:25:12 +00004099 */
anthony31f1bf72012-01-30 12:37:22 +00004100 length=strlen(arg1);
anthony805a2d42011-09-25 08:25:12 +00004101 token=(char *) NULL;
4102 if (~length >= (MaxTextExtent-1))
4103 token=(char *) AcquireQuantumMemory(length+MaxTextExtent,
4104 sizeof(*token));
4105 if (token == (char *) NULL)
4106 break;
4107 next=0;
anthony31f1bf72012-01-30 12:37:22 +00004108 arguments=arg1;
anthony805a2d42011-09-25 08:25:12 +00004109 token_info=AcquireTokenInfo();
4110 status=Tokenizer(token_info,0,token,length,arguments,"","=",
4111 "\"",'\0',&breaker,&next,&quote);
4112 token_info=DestroyTokenInfo(token_info);
4113 if (status == 0)
4114 {
4115 const char
4116 *argv;
4117
4118 argv=(&(arguments[next]));
anthony92c93bd2012-03-19 14:02:47 +00004119 (void) InvokeDynamicImageFilter(token,&_images,1,&argv,
4120 _exception);
anthony805a2d42011-09-25 08:25:12 +00004121 }
4122 token=DestroyString(token);
4123 break;
4124 }
4125 (void) SubstituteString(&arguments[1],"-","");
anthony92c93bd2012-03-19 14:02:47 +00004126 (void) InvokeDynamicImageFilter(arguments[1],&_images,
4127 number_arguments-2,(const char **) arguments+2,_exception);
anthony805a2d42011-09-25 08:25:12 +00004128 for (j=0; j < number_arguments; j++)
4129 arguments[j]=DestroyString(arguments[j]);
4130 arguments=(char **) RelinquishMagickMemory(arguments);
4131 break;
4132 }
anthonyebb73a22012-03-22 14:25:52 +00004133 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00004134 }
4135 case 'r':
4136 {
anthonyafa3dfc2012-03-03 11:31:30 +00004137 if (LocaleCompare("remap",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00004138 {
anthony92c93bd2012-03-19 14:02:47 +00004139 (void) RemapImages(_quantize_info,_images,(Image *) NULL,_exception);
anthony31f1bf72012-01-30 12:37:22 +00004140 break;
4141 }
anthonyafa3dfc2012-03-03 11:31:30 +00004142 if (LocaleCompare("reverse",option+1) == 0)
anthony31f1bf72012-01-30 12:37:22 +00004143 {
anthony92c93bd2012-03-19 14:02:47 +00004144 ReverseImageList(&_images);
anthony805a2d42011-09-25 08:25:12 +00004145 break;
4146 }
anthonyebb73a22012-03-22 14:25:52 +00004147 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00004148 }
4149 case 's':
4150 {
anthonyafa3dfc2012-03-03 11:31:30 +00004151 if (LocaleCompare("smush",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00004152 {
anthonycd358fc2012-04-16 13:59:03 +00004153 /* FUTURE: this option needs more work to make better */
anthony805a2d42011-09-25 08:25:12 +00004154 ssize_t
4155 offset;
4156
anthony7bcfe7f2012-03-30 14:01:22 +00004157 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00004158 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony31f1bf72012-01-30 12:37:22 +00004159 offset=(ssize_t) StringToLong(arg1);
anthonycd358fc2012-04-16 13:59:03 +00004160 new_images=SmushImages(_images,normal_op,offset,_exception);
4161 break;
4162 }
4163 if (LocaleCompare("subimage",option+1) == 0)
4164 {
4165 Image
4166 *base_image,
4167 *compare_image;
4168
4169 const char *
4170 value;
4171
4172 MetricType
4173 metric;
4174
4175 double
4176 similarity;
4177
4178 RectangleInfo
4179 offset;
4180
4181 base_image=GetImageFromList(_images,0);
4182 compare_image=GetImageFromList(_images,1);
4183
4184 /* Comparision Metric */
4185 metric=UndefinedMetric;
4186 value=GetImageOption(_image_info,"metric");
4187 if (value != (const char *) NULL)
4188 metric=(MetricType) ParseCommandOption(MagickMetricOptions,
4189 MagickFalse,value);
4190
4191 new_images=SimilarityImage(base_image,compare_image,metric,
4192 &offset,&similarity,_exception);
4193
4194 if ( new_images != (Image *)NULL ) {
4195 char
4196 result[MaxTextExtent];
4197
4198 (void) FormatLocaleString(result,MaxTextExtent,"%lf",similarity);
4199 (void) SetImageProperty(new_images,"subimage:similarity",result,
4200 _exception);
4201 (void) FormatLocaleString(result,MaxTextExtent,"%+ld",
4202 (long) offset.x);
4203 (void) SetImageProperty(new_images,"subimage:x",result,
4204 _exception);
4205 (void) FormatLocaleString(result,MaxTextExtent,"%+ld",
4206 (long) offset.y);
4207 (void) SetImageProperty(new_images,"subimage:y",result,
4208 _exception);
4209 (void) FormatLocaleString(result,MaxTextExtent,"%lux%lu%+ld%+ld",
4210 (unsigned long) offset.width,(unsigned long) offset.height,
4211 (long) offset.x,(long) offset.y);
4212 (void) SetImageProperty(new_images,"subimage:offset",result,
4213 _exception);
4214 }
anthony805a2d42011-09-25 08:25:12 +00004215 break;
4216 }
anthony0ea037a2012-04-03 12:14:39 +00004217 if (LocaleCompare("swap",option+1) == 0) {
4218 Image
4219 *p,
4220 *q,
4221 *swap;
anthony805a2d42011-09-25 08:25:12 +00004222
anthony0ea037a2012-04-03 12:14:39 +00004223 ssize_t
4224 index,
4225 swap_index;
anthony805a2d42011-09-25 08:25:12 +00004226
anthony0ea037a2012-04-03 12:14:39 +00004227 index=-1;
4228 swap_index=-2;
4229 if (IfNormalOp) {
4230 GeometryInfo
4231 geometry_info;
4232
4233 MagickStatusType
4234 flags;
4235
4236 swap_index=(-1);
anthony0ea037a2012-04-03 12:14:39 +00004237 flags=ParseGeometry(arg1,&geometry_info);
anthonyb1e21ed2012-04-20 12:43:12 +00004238 if ((flags & RhoValue) != 0)
4239 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony0ea037a2012-04-03 12:14:39 +00004240 index=(ssize_t) geometry_info.rho;
4241 if ((flags & SigmaValue) != 0)
4242 swap_index=(ssize_t) geometry_info.sigma;
anthony805a2d42011-09-25 08:25:12 +00004243 }
anthony0ea037a2012-04-03 12:14:39 +00004244 p=GetImageFromList(_images,index);
4245 q=GetImageFromList(_images,swap_index);
anthony8226e722012-04-05 14:25:46 +00004246 if ((p == (Image *) NULL) || (q == (Image *) NULL)) {
4247 if (IfNormalOp)
4248 CLIWandExceptArgBreak(OptionError,"InvalidImageIndex",option,arg1)
4249 else
4250 CLIWandExceptionBreak(OptionError,"TwoOrMoreImagesRequired",option);
4251 }
anthony0ea037a2012-04-03 12:14:39 +00004252 if (p == q)
anthony8226e722012-04-05 14:25:46 +00004253 CLIWandExceptArgBreak(OptionError,"InvalidImageIndex",option,arg1);
anthony0ea037a2012-04-03 12:14:39 +00004254 swap=CloneImage(p,0,0,MagickTrue,_exception);
4255 ReplaceImageInList(&p,CloneImage(q,0,0,MagickTrue,_exception));
4256 ReplaceImageInList(&q,swap);
4257 _images=GetFirstImageInList(q);
4258 break;
4259 }
anthonyebb73a22012-03-22 14:25:52 +00004260 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00004261 }
anthony805a2d42011-09-25 08:25:12 +00004262 default:
anthonyebb73a22012-03-22 14:25:52 +00004263 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00004264 }
anthony31f1bf72012-01-30 12:37:22 +00004265 if (new_images == (Image *) NULL)
4266 return;
anthony805a2d42011-09-25 08:25:12 +00004267
anthony92c93bd2012-03-19 14:02:47 +00004268 if (_images != (Image *) NULL)
4269 _images=DestroyImageList(_images);
4270 _images=GetFirstImageInList(new_images);
anthony31f1bf72012-01-30 12:37:22 +00004271 return;
4272
anthony92c93bd2012-03-19 14:02:47 +00004273#undef _image_info
4274#undef _images
4275#undef _exception
4276#undef _draw_info
4277#undef _quantize_info
anthonyafa3dfc2012-03-03 11:31:30 +00004278#undef IfNormalOp
4279#undef IfPlusOp
anthony31f1bf72012-01-30 12:37:22 +00004280#undef normal_op
anthony805a2d42011-09-25 08:25:12 +00004281}
anthony43f425d2012-02-26 12:58:58 +00004282
4283/*
4284%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4285% %
4286% %
4287% %
4288+ C L I S p e c i a l O p e r a t i o n s %
4289% %
4290% %
4291% %
4292%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4293%
anthony756cd0d2012-04-08 12:41:44 +00004294% CLISpecialOperator() Applies operations that may not actually need images
4295% in an image list wen it is applied.
anthony43f425d2012-02-26 12:58:58 +00004296%
anthony756cd0d2012-04-08 12:41:44 +00004297% The classic operators of this type is -read, which actually creates images
4298% even when no images are present. Or image stack operators, which can be
4299% applied to empty image lists.
anthonyafa3dfc2012-03-03 11:31:30 +00004300%
4301% Note: unlike other Operators, these may involve other special 'option'
4302% character prefixes, other than simply '-' or '+'.
anthony43f425d2012-02-26 12:58:58 +00004303%
4304% The format of the CLISpecialOption method is:
4305%
4306% void CLISpecialOption(MagickCLI *cli_wand,const char *option,
anthony24aa8822012-03-11 00:56:06 +00004307% const char *arg1)
anthony43f425d2012-02-26 12:58:58 +00004308%
4309% A description of each parameter follows:
4310%
4311% o cli_wand: the main CLI Wand to use.
4312%
4313% o option: The special option (with any switch char) to process
4314%
anthony24aa8822012-03-11 00:56:06 +00004315% o arg1: Argument for option, if required
anthonyafa3dfc2012-03-03 11:31:30 +00004316%
anthony2052d272012-02-28 12:48:29 +00004317% Example Usage...
4318%
anthonyce8dcb32012-03-21 13:20:31 +00004319% CLISpecialOperator(cli_wand,"-read","rose:");
anthony2052d272012-02-28 12:48:29 +00004320%
anthony24aa8822012-03-11 00:56:06 +00004321% Or for handling command line arguments EG: +/-option ["arg1"]
anthony2052d272012-02-28 12:48:29 +00004322%
4323% cli_wand
4324% argc,argv
4325% i=index in argv
4326%
4327% option_info = GetCommandOptionInfo(argv[i]);
4328% count=option_info->type;
4329% option_type=option_info->flags;
4330%
4331% if ( (option_type & SpecialOptionFlag) != 0 )
4332% CLISpecialOperator(cli_wand,argv[i],
4333% count>=1 ? argv[i+1] : (char *)NULL);
4334% i += count+1;
anthony43f425d2012-02-26 12:58:58 +00004335%
4336*/
4337
anthony43f425d2012-02-26 12:58:58 +00004338WandExport void CLISpecialOperator(MagickCLI *cli_wand,
anthony24aa8822012-03-11 00:56:06 +00004339 const char *option, const char *arg1)
anthony43f425d2012-02-26 12:58:58 +00004340{
anthony8226e722012-04-05 14:25:46 +00004341#define _image_info (cli_wand->wand.image_info)
4342#define _images (cli_wand->wand.images)
4343#define _exception (cli_wand->wand.exception)
4344#define IfNormalOp (*option=='-')
4345#define IfPlusOp (*option!='-')
anthony43f425d2012-02-26 12:58:58 +00004346
4347 assert(cli_wand != (MagickCLI *) NULL);
4348 assert(cli_wand->signature == WandSignature);
4349 assert(cli_wand->wand.signature == WandSignature);
anthony7bcfe7f2012-03-30 14:01:22 +00004350 if (IfMagickTrue(cli_wand->wand.debug))
anthony43f425d2012-02-26 12:58:58 +00004351 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
4352
anthony8226e722012-04-05 14:25:46 +00004353 if(_images != (Image *)NULL)
4354 (void) SyncImagesSettings(cli_wand->wand.image_info,_images,_exception);
anthony24aa8822012-03-11 00:56:06 +00004355
anthony52bef752012-03-27 13:54:47 +00004356 /*
anthony756cd0d2012-04-08 12:41:44 +00004357 No-op options (ignore these)
anthony52bef752012-03-27 13:54:47 +00004358 */
anthony756cd0d2012-04-08 12:41:44 +00004359 if (LocaleCompare("noop",option+1) == 0) /* no argument */
anthony52bef752012-03-27 13:54:47 +00004360 return;
anthony756cd0d2012-04-08 12:41:44 +00004361 if (LocaleCompare("sans",option+1) == 0) /* one argument */
anthony52bef752012-03-27 13:54:47 +00004362 return;
anthony756cd0d2012-04-08 12:41:44 +00004363 if (LocaleCompare("sans0",option+1) == 0) /* no argument */
anthony52bef752012-03-27 13:54:47 +00004364 return;
anthony756cd0d2012-04-08 12:41:44 +00004365 if (LocaleCompare("sans2",option+1) == 0) /* two arguments */
anthony52bef752012-03-27 13:54:47 +00004366 return;
4367 /*
4368 Image Reading
4369 */
4370 if ( ( LocaleCompare("read",option+1) == 0 ) ||
anthony0ea037a2012-04-03 12:14:39 +00004371 ( LocaleCompare("--",option) == 0 ) ) {
4372 int
4373 argc;
4374 char
4375 **argv;
anthony52bef752012-03-27 13:54:47 +00004376
anthony0ea037a2012-04-03 12:14:39 +00004377 ssize_t
4378 i;
4379
4380 /* Expand the filename argument (meta-characters or "@filelist" ) */
4381 argc = 1;
cristye71f2942012-04-04 11:07:05 +00004382 argv = (char **) &arg1;
anthony0ea037a2012-04-03 12:14:39 +00004383 MagickBooleanType
4384 status=ExpandFilenames(&argc,&argv);
4385
4386 if (IfMagickFalse(status))
4387 CLIWandExceptArgReturn(ResourceLimitError,"MemoryAllocationFailed",
4388 option,GetExceptionMessage(errno));
4389
4390 /* loop over expanded list reading images */
4391 for (i=0; i<argc; i++) {
anthony52bef752012-03-27 13:54:47 +00004392#if !USE_WAND_METHODS
4393 Image *
4394 new_images;
anthony8226e722012-04-05 14:25:46 +00004395 if (IfMagickTrue(_image_info->ping))
4396 new_images=PingImages(_image_info,argv[i],_exception);
anthony52bef752012-03-27 13:54:47 +00004397 else
anthony8226e722012-04-05 14:25:46 +00004398 new_images=ReadImages(_image_info,argv[i],_exception);
4399 AppendImageToList(&_images, new_images);
anthony52bef752012-03-27 13:54:47 +00004400#else
4401 /* read images using MagickWand method - no ping */
4402 /* This is not working! - it locks up in a CPU loop! */
4403 MagickSetLastIterator(&cli_wand->wand);
4404 MagickReadImage(&cli_wand->wand,arg1);
4405 MagickSetFirstIterator(&cli_wand->wand);
4406#endif
anthony52bef752012-03-27 13:54:47 +00004407 }
anthony0ea037a2012-04-03 12:14:39 +00004408 /* FUTURE: how do I free the expanded filename arguments??? */
4409
4410 return;
4411 }
anthony52bef752012-03-27 13:54:47 +00004412 /*
anthony756cd0d2012-04-08 12:41:44 +00004413 Image Writing (no-images present is valid in specific cases)
anthony8226e722012-04-05 14:25:46 +00004414 */
4415 if (LocaleCompare("write",option+1) == 0) {
4416 char
4417 key[MaxTextExtent];
4418
4419 Image
4420 *write_images;
4421
4422 ImageInfo
4423 *write_info;
4424
4425 /* Need images, unless a "null:" output coder is used */
4426 if ( cli_wand->wand.images == (Image *) NULL ) {
anthonya9e4f5d2012-04-12 06:44:02 +00004427 if ( LocaleCompare(arg1,"null:") == 0 )
anthony8226e722012-04-05 14:25:46 +00004428 return;
4429 CLIWandExceptArgReturn(OptionError,"NoImagesForWrite",option,arg1);
4430 }
4431
4432 (void) FormatLocaleString(key,MaxTextExtent,"cache:%s",arg1);
4433 (void) DeleteImageRegistry(key);
4434 write_images=_images;
4435 if (IfPlusOp)
4436 write_images=CloneImageList(_images,_exception);
4437 write_info=CloneImageInfo(_image_info);
4438 (void) WriteImages(write_info,write_images,arg1,_exception);
4439 write_info=DestroyImageInfo(write_info);
4440 if (IfPlusOp)
4441 write_images=DestroyImageList(write_images);
4442 return;
4443 }
4444 /*
anthony52bef752012-03-27 13:54:47 +00004445 Parenthesis and Brace operations
4446 */
anthonyce8dcb32012-03-21 13:20:31 +00004447 if (LocaleCompare("(",option) == 0) {
anthony8226e722012-04-05 14:25:46 +00004448 /* stack 'push' images */
4449 Stack
4450 *node;
anthony43f425d2012-02-26 12:58:58 +00004451
anthony8226e722012-04-05 14:25:46 +00004452 size_t
4453 size;
anthony43f425d2012-02-26 12:58:58 +00004454
anthony8226e722012-04-05 14:25:46 +00004455 size=0;
4456 node=cli_wand->image_list_stack;
4457 for ( ; node != (Stack *)NULL; node=node->next)
4458 size++;
4459 if ( size >= MAX_STACK_DEPTH )
4460 CLIWandExceptionReturn(OptionError,"ParenthesisNestedTooDeeply",option);
4461 node=(Stack *) AcquireMagickMemory(sizeof(*node));
4462 if (node == (Stack *) NULL)
4463 CLIWandExceptionReturn(ResourceLimitFatalError,
4464 "MemoryAllocationFailed",option);
4465 node->data = (void *)cli_wand->wand.images;
4466 cli_wand->wand.images = NewImageList();
4467 node->next = cli_wand->image_list_stack;
4468 cli_wand->image_list_stack = node;
anthony43f425d2012-02-26 12:58:58 +00004469
anthony8226e722012-04-05 14:25:46 +00004470 /* handle respect-parenthesis */
4471 if (IfMagickTrue(IsStringTrue(GetImageOption(cli_wand->wand.image_info,
4472 "respect-parenthesis"))))
4473 option="{"; /* fall-thru so as to push image settings too */
4474 else
anthony43f425d2012-02-26 12:58:58 +00004475 return;
anthony8226e722012-04-05 14:25:46 +00004476 }
4477 if (LocaleCompare("{",option) == 0) {
4478 /* stack 'push' of image_info settings */
4479 Stack
4480 *node;
anthony43f425d2012-02-26 12:58:58 +00004481
anthony8226e722012-04-05 14:25:46 +00004482 size_t
4483 size;
anthony43f425d2012-02-26 12:58:58 +00004484
anthony8226e722012-04-05 14:25:46 +00004485 size=0;
4486 node=cli_wand->image_info_stack;
4487 for ( ; node != (Stack *)NULL; node=node->next)
4488 size++;
4489 if ( size >= MAX_STACK_DEPTH )
4490 CLIWandExceptionReturn(OptionError,"CurlyBracesNestedTooDeeply",option);
4491 node=(Stack *) AcquireMagickMemory(sizeof(*node));
4492 if (node == (Stack *) NULL)
4493 CLIWandExceptionReturn(ResourceLimitFatalError,
4494 "MemoryAllocationFailed",option);
anthony43f425d2012-02-26 12:58:58 +00004495
anthony8226e722012-04-05 14:25:46 +00004496 node->data = (void *)cli_wand->wand.image_info;
4497 cli_wand->wand.image_info = CloneImageInfo(cli_wand->wand.image_info);
4498 if (cli_wand->wand.image_info == (ImageInfo *)NULL) {
4499 CLIWandException(ResourceLimitFatalError,"MemoryAllocationFailed",
4500 option);
anthony43f425d2012-02-26 12:58:58 +00004501 cli_wand->wand.image_info = (ImageInfo *)node->data;
4502 node = (Stack *)RelinquishMagickMemory(node);
anthony43f425d2012-02-26 12:58:58 +00004503 return;
4504 }
anthony8226e722012-04-05 14:25:46 +00004505
4506 node->next = cli_wand->image_info_stack;
4507 cli_wand->image_info_stack = node;
4508
4509 return;
4510 }
4511 if (LocaleCompare(")",option) == 0) {
4512 /* pop images from stack */
4513 Stack
4514 *node;
4515
4516 node = (Stack *)cli_wand->image_list_stack;
4517 if ( node == (Stack *)NULL)
4518 CLIWandExceptionReturn(OptionError,"UnbalancedParenthesis",option);
4519 cli_wand->image_list_stack = node->next;
4520
4521 AppendImageToList((Image **)&node->data,cli_wand->wand.images);
4522 cli_wand->wand.images= (Image *)node->data;
4523 node = (Stack *)RelinquishMagickMemory(node);
4524
4525 /* handle respect-parenthesis - of the previous 'pushed' settings */
4526 node = cli_wand->image_info_stack;
4527 if ( node != (Stack *)NULL)
4528 {
4529 if (IfMagickTrue(IsStringTrue(GetImageOption(
4530 cli_wand->wand.image_info,"respect-parenthesis"))))
4531 option="}"; /* fall-thru so as to pop image settings too */
4532 else
4533 return;
4534 }
4535 else
4536 return;
4537 }
4538 if (LocaleCompare("}",option) == 0) {
4539 /* pop image_info settings from stack */
4540 Stack
4541 *node;
4542
4543 node = (Stack *)cli_wand->image_info_stack;
4544 if ( node == (Stack *)NULL)
4545 CLIWandExceptionReturn(OptionError,"UnbalancedCurlyBraces",option);
4546 cli_wand->image_info_stack = node->next;
4547
4548 (void) DestroyImageInfo(cli_wand->wand.image_info);
4549 cli_wand->wand.image_info = (ImageInfo *)node->data;
4550 node = (Stack *)RelinquishMagickMemory(node);
4551
4552 GetDrawInfo(cli_wand->wand.image_info, cli_wand->draw_info);
4553 cli_wand->quantize_info=DestroyQuantizeInfo(cli_wand->quantize_info);
4554 cli_wand->quantize_info=AcquireQuantizeInfo(cli_wand->wand.image_info);
4555
4556 return;
4557 }
anthonyce8dcb32012-03-21 13:20:31 +00004558 if (LocaleCompare("clone",option+1) == 0) {
anthony43f425d2012-02-26 12:58:58 +00004559 Image
4560 *new_images;
4561
4562 if (*option == '+')
anthony24aa8822012-03-11 00:56:06 +00004563 arg1="-1";
anthony7bcfe7f2012-03-30 14:01:22 +00004564 if (IfMagickFalse(IsSceneGeometry(arg1,MagickFalse)))
anthony92c93bd2012-03-19 14:02:47 +00004565 CLIWandExceptionReturn(OptionError,"InvalidArgument",option);
anthony43f425d2012-02-26 12:58:58 +00004566 if ( cli_wand->image_list_stack == (Stack *)NULL)
anthony92c93bd2012-03-19 14:02:47 +00004567 CLIWandExceptionReturn(OptionError,"UnableToCloneImage",option);
anthony43f425d2012-02-26 12:58:58 +00004568 new_images = (Image *)cli_wand->image_list_stack->data;
4569 if (new_images == (Image *) NULL)
anthony92c93bd2012-03-19 14:02:47 +00004570 CLIWandExceptionReturn(OptionError,"UnableToCloneImage",option);
4571 new_images=CloneImages(new_images,arg1,_exception);
anthony43f425d2012-02-26 12:58:58 +00004572 if (new_images == (Image *) NULL)
anthony92c93bd2012-03-19 14:02:47 +00004573 CLIWandExceptionReturn(OptionError,"NoSuchImage",option);
anthony8226e722012-04-05 14:25:46 +00004574 AppendImageToList(&_images,new_images);
anthony43f425d2012-02-26 12:58:58 +00004575 return;
4576 }
anthony52bef752012-03-27 13:54:47 +00004577 /*
4578 Informational Operations
4579 */
anthony0ea037a2012-04-03 12:14:39 +00004580 if (LocaleCompare("version",option+1) == 0) {
anthony8226e722012-04-05 14:25:46 +00004581 (void) FormatLocaleFile(stdout,"Version: %s\n",
4582 GetMagickVersion((size_t *) NULL));
4583 (void) FormatLocaleFile(stdout,"Copyright: %s\n",
4584 GetMagickCopyright());
4585 (void) FormatLocaleFile(stdout,"Features: %s\n\n",
4586 GetMagickFeatures());
4587 return;
4588 }
anthonyce8dcb32012-03-21 13:20:31 +00004589 if (LocaleCompare("list",option+1) == 0) {
anthony8226e722012-04-05 14:25:46 +00004590 /* FUTURE: This should really be built into the MagickCore
4591 It does not actually require a cli-wand or and images!
4592 */
4593 ssize_t
4594 list;
anthony43f425d2012-02-26 12:58:58 +00004595
anthony8226e722012-04-05 14:25:46 +00004596 list=ParseCommandOption(MagickListOptions,MagickFalse,arg1);
4597 if ( list < 0 ) {
4598 CLIWandExceptionArg(OptionError,"UnrecognizedListType",option,arg1);
anthony43f425d2012-02-26 12:58:58 +00004599 return;
4600 }
anthony8226e722012-04-05 14:25:46 +00004601 switch (list)
4602 {
4603 case MagickCoderOptions:
4604 {
4605 (void) ListCoderInfo((FILE *) NULL,_exception);
4606 break;
4607 }
4608 case MagickColorOptions:
4609 {
4610 (void) ListColorInfo((FILE *) NULL,_exception);
4611 break;
4612 }
4613 case MagickConfigureOptions:
4614 {
4615 (void) ListConfigureInfo((FILE *) NULL,_exception);
4616 break;
4617 }
4618 case MagickDelegateOptions:
4619 {
4620 (void) ListDelegateInfo((FILE *) NULL,_exception);
4621 break;
4622 }
4623 case MagickFontOptions:
4624 {
4625 (void) ListTypeInfo((FILE *) NULL,_exception);
4626 break;
4627 }
4628 case MagickFormatOptions:
4629 (void) ListMagickInfo((FILE *) NULL,_exception);
4630 break;
4631 case MagickLocaleOptions:
4632 (void) ListLocaleInfo((FILE *) NULL,_exception);
4633 break;
4634 case MagickLogOptions:
4635 (void) ListLogInfo((FILE *) NULL,_exception);
4636 break;
4637 case MagickMagicOptions:
4638 (void) ListMagicInfo((FILE *) NULL,_exception);
4639 break;
4640 case MagickMimeOptions:
4641 (void) ListMimeInfo((FILE *) NULL,_exception);
4642 break;
4643 case MagickModuleOptions:
4644 (void) ListModuleInfo((FILE *) NULL,_exception);
4645 break;
4646 case MagickPolicyOptions:
4647 (void) ListPolicyInfo((FILE *) NULL,_exception);
4648 break;
4649 case MagickResourceOptions:
4650 (void) ListMagickResourceInfo((FILE *) NULL,_exception);
4651 break;
4652 case MagickThresholdOptions:
4653 (void) ListThresholdMaps((FILE *) NULL,_exception);
4654 break;
4655 default:
4656 (void) ListCommandOptions((FILE *) NULL,(CommandOption) list,
4657 _exception);
4658 break;
4659 }
4660 return;
4661 }
anthony43f425d2012-02-26 12:58:58 +00004662
4663#if 0
anthony43f425d2012-02-26 12:58:58 +00004664 // Other 'special' options this should handle
anthony5216f822012-04-10 13:02:37 +00004665 // "region" "reset" "arg"
anthony43f425d2012-02-26 12:58:58 +00004666 if ( ( process_flags & ProcessUnknownOptionError ) != 0 )
anthony43f425d2012-02-26 12:58:58 +00004667#endif
anthonyebb73a22012-03-22 14:25:52 +00004668 CLIWandException(OptionError,"UnrecognizedOption",option);
anthony43f425d2012-02-26 12:58:58 +00004669
anthony8226e722012-04-05 14:25:46 +00004670#undef _image_info
4671#undef _images
anthony92c93bd2012-03-19 14:02:47 +00004672#undef _exception
anthony8226e722012-04-05 14:25:46 +00004673#undef IfNormalOp
4674#undef IfPlusOp
anthony43f425d2012-02-26 12:58:58 +00004675}