blob: 69c73480e3eef21a742d6e9fad0179829c751b00 [file] [log] [blame]
anthony805a2d42011-09-25 08:25:12 +00001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% %
anthony8b10b462012-02-08 12:32:44 +00006% OOO PPPP EEEE RRRR AA TTTTT III OOO N N %
7% O O P P E R R A A T I O O NN N %
8% O O PPPP EEE RRRR AAAA T I O O N N N %
9% O O P E R R A A T I O O N NN %
10% OOO P EEEE R RR A A T III OOO N N %
anthony805a2d42011-09-25 08:25:12 +000011% %
12% %
anthony8b10b462012-02-08 12:32:44 +000013% CLI Magick Option Methods %
anthony805a2d42011-09-25 08:25:12 +000014% %
anthony8b10b462012-02-08 12:32:44 +000015% Dragon Computing %
cristy9e58efd2012-01-30 14:27:34 +000016% Anthony Thyssen %
cristy0a0ca4f2011-09-28 01:15:28 +000017% September 2011 %
anthony805a2d42011-09-25 08:25:12 +000018% %
19% %
cristy1454be72011-12-19 01:52:48 +000020% Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization %
anthony805a2d42011-09-25 08:25:12 +000021% dedicated to making software imaging solutions freely available. %
22% %
23% You may not use this file except in compliance with the License. You may %
24% obtain a copy of the License at %
25% %
26% http://www.imagemagick.org/script/license.php %
27% %
28% Unless required by applicable law or agreed to in writing, software %
29% distributed under the License is distributed on an "AS IS" BASIS, %
30% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31% See the License for the specific language governing permissions and %
32% limitations under the License. %
33% %
34%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35%
36% Apply the given options (settings, and simple, or sequence operations) to
anthony8b10b462012-02-08 12:32:44 +000037% the given image(s) according to the current "image_info", "draw_info", and
38% "quantize_info" settings, stored in a special CLI Image Wand.
anthony805a2d42011-09-25 08:25:12 +000039%
40% The final goal is to allow the execution in a strict one option at a time
41% manner that is needed for 'pipelining and file scripting' of options in
42% IMv7.
43%
anthony8b10b462012-02-08 12:32:44 +000044% Anthony Thyssen, September 2011
anthony805a2d42011-09-25 08:25:12 +000045*/
46
47/*
48 Include declarations.
49*/
50#include "MagickWand/studio.h"
51#include "MagickWand/MagickWand.h"
anthony72feaa62012-01-17 06:46:23 +000052#include "MagickWand/magick-wand-private.h"
anthony43f425d2012-02-26 12:58:58 +000053#include "MagickWand/wand.h"
anthony756cd0d2012-04-08 12:41:44 +000054#include "MagickWand/wandcli.h"
55#include "MagickWand/wandcli-private.h"
56#include "MagickWand/operation.h"
anthony805a2d42011-09-25 08:25:12 +000057#include "MagickCore/monitor-private.h"
58#include "MagickCore/thread-private.h"
59#include "MagickCore/string-private.h"
60
61/*
62 Define declarations.
63*/
anthonyafa3dfc2012-03-03 11:31:30 +000064#define USE_WAND_METHODS 0
65#define MAX_STACK_DEPTH 32
66#define UNDEFINED_COMPRESSION_QUALITY 0UL
67
anthony805a2d42011-09-25 08:25:12 +000068/*
69 Constant declaration. (temporary exports)
70*/
71static const char
72 BackgroundColor[] = "#fff", /* white */
anthony72feaa62012-01-17 06:46:23 +000073 BorderColor[] = "#dfdfdf", /* sRGB gray */
74 MatteColor[] = "#bdbdbd"; /* slightly darker gray */
anthony805a2d42011-09-25 08:25:12 +000075
76/*
77** Function to report on the progress of image operations
78*/
79static MagickBooleanType MonitorProgress(const char *text,
80 const MagickOffsetType offset,const MagickSizeType extent,
anthony43f425d2012-02-26 12:58:58 +000081 void *wand_unused(cli_wandent_data))
anthony805a2d42011-09-25 08:25:12 +000082{
83 char
84 message[MaxTextExtent],
85 tag[MaxTextExtent];
86
87 const char
88 *locale_message;
89
90 register char
91 *p;
92
93 if (extent < 2)
94 return(MagickTrue);
95 (void) CopyMagickMemory(tag,text,MaxTextExtent);
96 p=strrchr(tag,'/');
97 if (p != (char *) NULL)
98 *p='\0';
99 (void) FormatLocaleString(message,MaxTextExtent,"Monitor/%s",tag);
100 locale_message=GetLocaleMessage(message);
101 if (locale_message == message)
102 locale_message=tag;
103 if (p == (char *) NULL)
104 (void) FormatLocaleFile(stderr,"%s: %ld of %lu, %02ld%% complete\r",
105 locale_message,(long) offset,(unsigned long) extent,(long)
106 (100L*offset/(extent-1)));
107 else
108 (void) FormatLocaleFile(stderr,"%s[%s]: %ld of %lu, %02ld%% complete\r",
109 locale_message,p+1,(long) offset,(unsigned long) extent,(long)
110 (100L*offset/(extent-1)));
111 if (offset == (MagickOffsetType) (extent-1))
112 (void) FormatLocaleFile(stderr,"\n");
113 (void) fflush(stderr);
114 return(MagickTrue);
115}
116
117/*
118** GetImageCache() will read an image into a image cache if not already
119** present then return the image that is in the cache under that filename.
120*/
121static inline Image *GetImageCache(const ImageInfo *image_info,const char *path,
122 ExceptionInfo *exception)
123{
124 char
125 key[MaxTextExtent];
126
127 ExceptionInfo
128 *sans_exception;
129
130 Image
131 *image;
132
133 ImageInfo
134 *read_info;
135
136 (void) FormatLocaleString(key,MaxTextExtent,"cache:%s",path);
137 sans_exception=AcquireExceptionInfo();
138 image=(Image *) GetImageRegistry(ImageRegistryType,key,sans_exception);
139 sans_exception=DestroyExceptionInfo(sans_exception);
140 if (image != (Image *) NULL)
141 return(image);
142 read_info=CloneImageInfo(image_info);
143 (void) CopyMagickString(read_info->filename,path,MaxTextExtent);
144 image=ReadImage(read_info,exception);
145 read_info=DestroyImageInfo(read_info);
146 if (image != (Image *) NULL)
147 (void) SetImageRegistry(ImageRegistryType,key,image,exception);
148 return(image);
149}
150
151/*
anthony756cd0d2012-04-08 12:41:44 +0000152 FloatListOption() converts a string option of space or comma seperated
153 numbers into a list of floating point numbers, required by some operations.
154*/
155static MagickBooleanType FloatListOption(const char *option,
156 size_t *number_arguments, double **arguments, ExceptionInfo *exception)
157{
158 char
159 token[MaxTextExtent];
160
161 const char
162 *p;
163
164 MagickBooleanType
165 error;
166
167 register size_t
168 x;
169
170}
171
172/*
anthonya89dd172011-10-04 13:29:35 +0000173 SparseColorOption() parse the complex -sparse-color argument into an
174 an array of floating point values than call SparseColorImage().
175 Argument is a complex mix of floating-point pixel coodinates, and color
176 specifications (or direct floating point numbers). The number of floats
177 needed to represent a color varies depending on teh current channel
178 setting.
anthony43f425d2012-02-26 12:58:58 +0000179
180 This really should be in MagickCore, so that other API's can make use of it.
anthony805a2d42011-09-25 08:25:12 +0000181*/
182static Image *SparseColorOption(const Image *image,
183 const SparseColorMethod method,const char *arguments,
anthony31f1bf72012-01-30 12:37:22 +0000184 ExceptionInfo *exception)
anthony805a2d42011-09-25 08:25:12 +0000185{
186 char
187 token[MaxTextExtent];
188
189 const char
190 *p;
191
192 double
193 *sparse_arguments;
194
195 Image
196 *sparse_image;
197
198 PixelInfo
199 color;
200
201 MagickBooleanType
202 error;
203
204 register size_t
205 x;
206
207 size_t
208 number_arguments,
209 number_colors;
210
211 assert(image != (Image *) NULL);
212 assert(image->signature == MagickSignature);
anthony7bcfe7f2012-03-30 14:01:22 +0000213 if (IfMagickTrue(image->debug))
anthony805a2d42011-09-25 08:25:12 +0000214 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
215 assert(exception != (ExceptionInfo *) NULL);
216 assert(exception->signature == MagickSignature);
217 /*
218 Limit channels according to image - and add up number of color channel.
219 */
220 number_colors=0;
221 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
222 number_colors++;
223 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
224 number_colors++;
225 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
226 number_colors++;
227 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
228 (image->colorspace == CMYKColorspace))
229 number_colors++;
230 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
anthony7bcfe7f2012-03-30 14:01:22 +0000231 IfMagickTrue(image->matte))
anthony805a2d42011-09-25 08:25:12 +0000232 number_colors++;
233
234 /*
235 Read string, to determine number of arguments needed,
236 */
237 p=arguments;
238 x=0;
239 while( *p != '\0' )
240 {
241 GetMagickToken(p,&p,token);
242 if ( token[0] == ',' ) continue;
anthony31f1bf72012-01-30 12:37:22 +0000243 if ( isalpha((int) token[0]) || token[0] == '#' )
244 x += number_colors; /* color argument found */
anthonyce8dcb32012-03-21 13:20:31 +0000245 else
anthony805a2d42011-09-25 08:25:12 +0000246 x++; /* floating point argument */
anthony805a2d42011-09-25 08:25:12 +0000247 }
anthony31f1bf72012-01-30 12:37:22 +0000248 /* control points and color values */
anthony7bcfe7f2012-03-30 14:01:22 +0000249 error = IsMagickTrue( x % (2+number_colors) );
anthony31f1bf72012-01-30 12:37:22 +0000250 number_arguments=x;
anthony7bcfe7f2012-03-30 14:01:22 +0000251 if ( IfMagickTrue(error) ) {
anthony805a2d42011-09-25 08:25:12 +0000252 (void) ThrowMagickException(exception,GetMagickModule(),
anthony43f425d2012-02-26 12:58:58 +0000253 OptionError, "InvalidArgument", "'%s': %s", "sparse-color",
anthony805a2d42011-09-25 08:25:12 +0000254 "Invalid number of Arguments");
255 return( (Image *)NULL);
256 }
257
258 /* Allocate and fill in the floating point arguments */
259 sparse_arguments=(double *) AcquireQuantumMemory(number_arguments,
260 sizeof(*sparse_arguments));
261 if (sparse_arguments == (double *) NULL) {
262 (void) ThrowMagickException(exception,GetMagickModule(),ResourceLimitError,
263 "MemoryAllocationFailed","%s","SparseColorOption");
264 return( (Image *)NULL);
265 }
266 (void) ResetMagickMemory(sparse_arguments,0,number_arguments*
267 sizeof(*sparse_arguments));
268 p=arguments;
269 x=0;
270 while( *p != '\0' && x < number_arguments ) {
271 /* X coordinate */
272 token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token);
273 if ( token[0] == '\0' ) break;
274 if ( isalpha((int) token[0]) || token[0] == '#' ) {
275 (void) ThrowMagickException(exception,GetMagickModule(),
anthony43f425d2012-02-26 12:58:58 +0000276 OptionError, "InvalidArgument", "'%s': %s", "sparse-color",
anthony805a2d42011-09-25 08:25:12 +0000277 "Color found, instead of X-coord");
278 error = MagickTrue;
279 break;
280 }
cristydbdd0e32011-11-04 23:29:40 +0000281 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +0000282 /* Y coordinate */
283 token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token);
284 if ( token[0] == '\0' ) break;
285 if ( isalpha((int) token[0]) || token[0] == '#' ) {
286 (void) ThrowMagickException(exception,GetMagickModule(),
anthony43f425d2012-02-26 12:58:58 +0000287 OptionError, "InvalidArgument", "'%s': %s", "sparse-color",
anthony805a2d42011-09-25 08:25:12 +0000288 "Color found, instead of Y-coord");
289 error = MagickTrue;
290 break;
291 }
cristydbdd0e32011-11-04 23:29:40 +0000292 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
anthony31f1bf72012-01-30 12:37:22 +0000293 /* color name or function given in string argument */
294 token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token);
295 if ( token[0] == '\0' ) break;
296 if ( isalpha((int) token[0]) || token[0] == '#' ) {
297 /* Color string given */
298 (void) QueryColorCompliance(token,AllCompliance,&color,
299 exception);
300 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
301 sparse_arguments[x++] = QuantumScale*color.red;
302 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
303 sparse_arguments[x++] = QuantumScale*color.green;
304 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
305 sparse_arguments[x++] = QuantumScale*color.blue;
306 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
307 (image->colorspace == CMYKColorspace))
308 sparse_arguments[x++] = QuantumScale*color.black;
309 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
anthony7bcfe7f2012-03-30 14:01:22 +0000310 IfMagickTrue(image->matte))
anthony31f1bf72012-01-30 12:37:22 +0000311 sparse_arguments[x++] = QuantumScale*color.alpha;
anthony805a2d42011-09-25 08:25:12 +0000312 }
anthony31f1bf72012-01-30 12:37:22 +0000313 else {
314 /* Colors given as a set of floating point values - experimental */
315 /* NB: token contains the first floating point value to use! */
316 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
317 {
318 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
319 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
320 break;
321 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
322 token[0] = ','; /* used this token - get another */
anthony805a2d42011-09-25 08:25:12 +0000323 }
anthony31f1bf72012-01-30 12:37:22 +0000324 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
325 {
326 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
327 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
328 break;
329 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
330 token[0] = ','; /* used this token - get another */
331 }
332 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
333 {
334 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
335 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
336 break;
337 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
338 token[0] = ','; /* used this token - get another */
339 }
340 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
341 (image->colorspace == CMYKColorspace))
342 {
343 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
344 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
345 break;
346 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
347 token[0] = ','; /* used this token - get another */
348 }
349 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
anthony7bcfe7f2012-03-30 14:01:22 +0000350 IfMagickTrue(image->matte))
anthony31f1bf72012-01-30 12:37:22 +0000351 {
352 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
353 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
354 break;
355 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
356 token[0] = ','; /* used this token - get another */
anthony805a2d42011-09-25 08:25:12 +0000357 }
358 }
359 }
360 if ( number_arguments != x && !error ) {
361 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
anthony43f425d2012-02-26 12:58:58 +0000362 "InvalidArgument","'%s': %s","sparse-color","Argument Parsing Error");
anthony805a2d42011-09-25 08:25:12 +0000363 sparse_arguments=(double *) RelinquishMagickMemory(sparse_arguments);
364 return( (Image *)NULL);
365 }
366 if ( error )
367 return( (Image *)NULL);
368
anthony31f1bf72012-01-30 12:37:22 +0000369 /* Call the Sparse Color Interpolation function with the parsed arguments */
anthony805a2d42011-09-25 08:25:12 +0000370 sparse_image=SparseColorImage(image,method,number_arguments,sparse_arguments,
371 exception);
372 sparse_arguments=(double *) RelinquishMagickMemory(sparse_arguments);
373 return( sparse_image );
374}
375
376/*
377%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
378% %
379% %
380% %
anthony43f425d2012-02-26 12:58:58 +0000381+ C L I S e t t i n g O p t i o n I n f o %
382% %
383% %
384% %
385%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
386%
387% CLISettingOptionInfo() applies a single settings option into a CLI wand
388% holding the image_info, draw_info, quantize_info structures that will be
389% used when processing the images.
390%
391% These options do no require images to be present in the CLI wand for them
392% to be able to be set, in which case they will generally be applied to image
393% that are read in later
anthony80c37752012-01-16 01:03:11 +0000394%
395% Options handled by this function are listed in CommandOptions[] of
anthonyfd706f92012-01-19 04:22:02 +0000396% "option.c" that is one of "SettingOptionFlags" option flags.
anthony805a2d42011-09-25 08:25:12 +0000397%
anthony2052d272012-02-28 12:48:29 +0000398% The format of the CLISettingOptionInfo method is:
anthony1afdc7a2011-10-05 11:54:28 +0000399%
anthonyafa3dfc2012-03-03 11:31:30 +0000400% void CLISettingOptionInfo(MagickCLI *cli_wand,
anthony24aa8822012-03-11 00:56:06 +0000401% const char *option, const char *arg1)
anthony805a2d42011-09-25 08:25:12 +0000402%
403% A description of each parameter follows:
404%
anthony43f425d2012-02-26 12:58:58 +0000405% o cli_wand: structure holding settings to be applied
anthony805a2d42011-09-25 08:25:12 +0000406%
anthonydcf510d2011-10-30 13:51:40 +0000407% o option: The option string to be set
anthony805a2d42011-09-25 08:25:12 +0000408%
anthony24aa8822012-03-11 00:56:06 +0000409% o arg1: The single argument used to set this option.
anthonydcf510d2011-10-30 13:51:40 +0000410%
anthony72feaa62012-01-17 06:46:23 +0000411% Example usage...
412%
anthonyafa3dfc2012-03-03 11:31:30 +0000413% CLISettingOptionInfo(cli_wand, "-background", "Red"); // set value
414% CLISettingOptionInfo(cli_wand, "-adjoin", NULL); // set boolean
415% CLISettingOptionInfo(cli_wand, "+adjoin", NULL); // unset
anthony72feaa62012-01-17 06:46:23 +0000416%
anthony24aa8822012-03-11 00:56:06 +0000417% Or for handling command line arguments EG: +/-option ["arg1"]
anthonydcf510d2011-10-30 13:51:40 +0000418%
419% argc,argv
420% i=index in argv
421%
anthony2052d272012-02-28 12:48:29 +0000422% option_info = GetCommandOptionInfo(argv[i]);
423% count=option_info->type;
424% option_type=option_info->flags;
425%
426% if ( (option_type & SettingOperatorOptionFlags) != 0 )
anthonyafa3dfc2012-03-03 11:31:30 +0000427% CLISettingOptionInfo(cli_wand, argv[i],
428% (count>0) ? argv[i+1] : (char *)NULL);
anthonydcf510d2011-10-30 13:51:40 +0000429% i += count+1;
430%
anthony805a2d42011-09-25 08:25:12 +0000431*/
anthonyafa3dfc2012-03-03 11:31:30 +0000432WandExport void CLISettingOptionInfo(MagickCLI *cli_wand,
anthony24aa8822012-03-11 00:56:06 +0000433 const char *option,const char *arg1)
anthony805a2d42011-09-25 08:25:12 +0000434{
anthony30b912a2012-03-22 01:20:28 +0000435 ssize_t
436 parse; /* option argument parsing (string to value table lookup) */
437
anthony43f425d2012-02-26 12:58:58 +0000438 assert(cli_wand != (MagickCLI *) NULL);
439 assert(cli_wand->signature == WandSignature);
440 assert(cli_wand->wand.signature == WandSignature);
anthony7bcfe7f2012-03-30 14:01:22 +0000441 if (IfMagickTrue(cli_wand->wand.debug))
anthony43f425d2012-02-26 12:58:58 +0000442 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
anthony1afdc7a2011-10-05 11:54:28 +0000443
anthony2e4501b2012-03-30 04:41:54 +0000444#define _image_info (cli_wand->wand.image_info)
445#define _exception (cli_wand->wand.exception)
446#define _draw_info (cli_wand->draw_info)
447#define _quantize_info (cli_wand->quantize_info)
anthony24aa8822012-03-11 00:56:06 +0000448#define IfSetOption (*option=='-')
anthony7bcfe7f2012-03-30 14:01:22 +0000449#define ArgBoolean IsMagickTrue(IfSetOption)
450#define ArgBooleanNot IsMagickFalse(IfSetOption)
anthony24aa8822012-03-11 00:56:06 +0000451#define ArgBooleanString (IfSetOption?"true":"false")
452#define ArgOption(def) (IfSetOption?arg1:(const char *)(def))
anthony74b1cfc2011-10-06 12:44:16 +0000453
anthonyafa3dfc2012-03-03 11:31:30 +0000454 switch (*(option+1))
anthony805a2d42011-09-25 08:25:12 +0000455 {
456 case 'a':
457 {
anthonyafa3dfc2012-03-03 11:31:30 +0000458 if (LocaleCompare("adjoin",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000459 {
anthony92c93bd2012-03-19 14:02:47 +0000460 _image_info->adjoin = ArgBoolean;
anthony805a2d42011-09-25 08:25:12 +0000461 break;
462 }
anthonyafa3dfc2012-03-03 11:31:30 +0000463 if (LocaleCompare("affine",option+1) == 0)
anthony1afdc7a2011-10-05 11:54:28 +0000464 {
anthony92c93bd2012-03-19 14:02:47 +0000465 /* DEPRECIATED: _draw_info setting only: for -draw and -transform */
anthony74b1cfc2011-10-06 12:44:16 +0000466 if (IfSetOption)
anthony92c93bd2012-03-19 14:02:47 +0000467 (void) ParseAffineGeometry(arg1,&_draw_info->affine,_exception);
anthony74b1cfc2011-10-06 12:44:16 +0000468 else
anthony92c93bd2012-03-19 14:02:47 +0000469 GetAffineMatrix(&_draw_info->affine);
anthony1afdc7a2011-10-05 11:54:28 +0000470 break;
471 }
anthonyafa3dfc2012-03-03 11:31:30 +0000472 if (LocaleCompare("antialias",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000473 {
anthony92c93bd2012-03-19 14:02:47 +0000474 _image_info->antialias =
475 _draw_info->stroke_antialias =
476 _draw_info->text_antialias = ArgBoolean;
anthony805a2d42011-09-25 08:25:12 +0000477 break;
478 }
anthony31f1bf72012-01-30 12:37:22 +0000479 if (LocaleCompare("attenuate",option+1) == 0)
480 {
anthony7bcfe7f2012-03-30 14:01:22 +0000481 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthony92c93bd2012-03-19 14:02:47 +0000482 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
483 (void) SetImageOption(_image_info,option+1,ArgOption("1.0"));
anthony31f1bf72012-01-30 12:37:22 +0000484 break;
485 }
anthonyafa3dfc2012-03-03 11:31:30 +0000486 if (LocaleCompare("authenticate",option+1) == 0)
anthonydcf510d2011-10-30 13:51:40 +0000487 {
anthony92c93bd2012-03-19 14:02:47 +0000488 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +0000489 break;
490 }
anthonyebb73a22012-03-22 14:25:52 +0000491 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +0000492 }
493 case 'b':
494 {
anthonyafa3dfc2012-03-03 11:31:30 +0000495 if (LocaleCompare("background",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000496 {
anthony92c93bd2012-03-19 14:02:47 +0000497 /* FUTURE: both _image_info attribute & ImageOption in use!
498 _image_info only used directly for generating new images.
anthony72feaa62012-01-17 06:46:23 +0000499 SyncImageSettings() used to set per-image attribute.
500
anthony92c93bd2012-03-19 14:02:47 +0000501 FUTURE: if _image_info->background_color is not set then
anthony30b912a2012-03-22 01:20:28 +0000502 we should fall back to per-image background_color
503
504 At this time -background will 'wipe out' the per-image
505 background color!
506
507 Better error handling of QueryColorCompliance() needed.
anthony74b1cfc2011-10-06 12:44:16 +0000508 */
anthony92c93bd2012-03-19 14:02:47 +0000509 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony72feaa62012-01-17 06:46:23 +0000510 (void) QueryColorCompliance(ArgOption(BackgroundColor),AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +0000511 &_image_info->background_color,_exception);
anthony805a2d42011-09-25 08:25:12 +0000512 break;
513 }
anthonyafa3dfc2012-03-03 11:31:30 +0000514 if (LocaleCompare("bias",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000515 {
anthony52bef752012-03-27 13:54:47 +0000516 /* FUTURE: bias OBSOLETED, replaced by Artifact "convolve:bias"
anthony31f1bf72012-01-30 12:37:22 +0000517 as it is actually rarely used except in direct convolve operations
518 Usage outside a direct convolve operation is actally non-sensible!
anthony72feaa62012-01-17 06:46:23 +0000519
520 SyncImageSettings() used to set per-image attribute.
anthony74b1cfc2011-10-06 12:44:16 +0000521 */
anthony7bcfe7f2012-03-30 14:01:22 +0000522 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthony5330ae02012-03-20 14:17:01 +0000523 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyf46d4262012-03-26 03:30:34 +0000524 (void) SetImageOption(_image_info,"convolve:bias",ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +0000525 break;
526 }
anthonyafa3dfc2012-03-03 11:31:30 +0000527 if (LocaleCompare("black-point-compensation",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000528 {
anthony72feaa62012-01-17 06:46:23 +0000529 /* Used as a image chromaticity setting
530 SyncImageSettings() used to set per-image attribute.
531 */
anthony92c93bd2012-03-19 14:02:47 +0000532 (void) SetImageOption(_image_info,option+1,ArgBooleanString);
anthony805a2d42011-09-25 08:25:12 +0000533 break;
534 }
anthonyafa3dfc2012-03-03 11:31:30 +0000535 if (LocaleCompare("blue-primary",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000536 {
anthonyafbaed72011-10-26 12:05:04 +0000537 /* Image chromaticity X,Y NB: Y=X if Y not defined
538 Used by many coders including PNG
anthony72feaa62012-01-17 06:46:23 +0000539 SyncImageSettings() used to set per-image attribute.
anthonyafbaed72011-10-26 12:05:04 +0000540 */
anthonyf42014d2012-03-25 09:53:06 +0000541 arg1=ArgOption("0.0");
anthony7bcfe7f2012-03-30 14:01:22 +0000542 if (IfMagickFalse(IsGeometry(arg1)))
anthony5330ae02012-03-20 14:17:01 +0000543 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyf42014d2012-03-25 09:53:06 +0000544 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000545 break;
546 }
anthonyafa3dfc2012-03-03 11:31:30 +0000547 if (LocaleCompare("bordercolor",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000548 {
anthony92c93bd2012-03-19 14:02:47 +0000549 /* FUTURE: both _image_info attribute & ImageOption in use!
anthony72feaa62012-01-17 06:46:23 +0000550 SyncImageSettings() used to set per-image attribute.
anthony30b912a2012-03-22 01:20:28 +0000551 Better error checking of QueryColorCompliance().
anthony72feaa62012-01-17 06:46:23 +0000552 */
anthony74b1cfc2011-10-06 12:44:16 +0000553 if (IfSetOption)
anthony805a2d42011-09-25 08:25:12 +0000554 {
anthony92c93bd2012-03-19 14:02:47 +0000555 (void) SetImageOption(_image_info,option+1,arg1);
anthony24aa8822012-03-11 00:56:06 +0000556 (void) QueryColorCompliance(arg1,AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +0000557 &_image_info->border_color,_exception);
anthony24aa8822012-03-11 00:56:06 +0000558 (void) QueryColorCompliance(arg1,AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +0000559 &_draw_info->border_color,_exception);
anthony805a2d42011-09-25 08:25:12 +0000560 break;
561 }
anthony92c93bd2012-03-19 14:02:47 +0000562 (void) DeleteImageOption(_image_info,option+1);
anthony74b1cfc2011-10-06 12:44:16 +0000563 (void) QueryColorCompliance(BorderColor,AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +0000564 &_image_info->border_color,_exception);
anthony74b1cfc2011-10-06 12:44:16 +0000565 (void) QueryColorCompliance(BorderColor,AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +0000566 &_draw_info->border_color,_exception);
anthony805a2d42011-09-25 08:25:12 +0000567 break;
568 }
anthonyafa3dfc2012-03-03 11:31:30 +0000569 if (LocaleCompare("box",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000570 {
anthonyfd706f92012-01-19 04:22:02 +0000571 /* DEPRECIATED - now "undercolor" */
anthony24aa8822012-03-11 00:56:06 +0000572 CLISettingOptionInfo(cli_wand,"undercolor",arg1);
anthonyfd706f92012-01-19 04:22:02 +0000573 break;
anthony805a2d42011-09-25 08:25:12 +0000574 }
anthonyebb73a22012-03-22 14:25:52 +0000575 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +0000576 }
577 case 'c':
578 {
anthonyafa3dfc2012-03-03 11:31:30 +0000579 if (LocaleCompare("cache",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000580 {
581 MagickSizeType
582 limit;
583
anthony7bcfe7f2012-03-30 14:01:22 +0000584 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthony5330ae02012-03-20 14:17:01 +0000585 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +0000586 limit=MagickResourceInfinity;
anthony24aa8822012-03-11 00:56:06 +0000587 if (LocaleCompare("unlimited",arg1) != 0)
588 limit=(MagickSizeType) SiPrefixToDoubleInterval(arg1,100.0);
anthony805a2d42011-09-25 08:25:12 +0000589 (void) SetMagickResourceLimit(MemoryResource,limit);
590 (void) SetMagickResourceLimit(MapResource,2*limit);
591 break;
592 }
anthonyafa3dfc2012-03-03 11:31:30 +0000593 if (LocaleCompare("caption",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000594 {
anthony92c93bd2012-03-19 14:02:47 +0000595 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +0000596 break;
597 }
anthonyafa3dfc2012-03-03 11:31:30 +0000598 if (LocaleCompare("channel",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000599 {
anthony30b912a2012-03-22 01:20:28 +0000600 arg1=ArgOption("default");
601 parse=ParseChannelOption(arg1);
602 if (parse < 0)
603 CLIWandExceptArgBreak(OptionError,"UnrecognizedChannelType",
604 option,arg1);
605 _image_info->channel=(ChannelType) parse;
606 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000607 break;
608 }
anthonyafa3dfc2012-03-03 11:31:30 +0000609 if (LocaleCompare("colorspace",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000610 {
anthonyafbaed72011-10-26 12:05:04 +0000611 /* Setting used for new images via AquireImage()
612 But also used as a SimpleImageOperator
613 Undefined colorspace means don't modify images on
614 read or as a operation */
anthony30b912a2012-03-22 01:20:28 +0000615 parse = ParseCommandOption(MagickColorspaceOptions,MagickFalse,
616 ArgOption("undefined"));
617 if (parse < 0)
anthony5330ae02012-03-20 14:17:01 +0000618 CLIWandExceptArgBreak(OptionError,"UnrecognizedColorspace",
619 option,arg1);
anthony30b912a2012-03-22 01:20:28 +0000620 _image_info->colorspace=(ColorspaceType) parse;
anthony805a2d42011-09-25 08:25:12 +0000621 break;
622 }
anthonyafa3dfc2012-03-03 11:31:30 +0000623 if (LocaleCompare("comment",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000624 {
anthony92c93bd2012-03-19 14:02:47 +0000625 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +0000626 break;
627 }
anthonyafa3dfc2012-03-03 11:31:30 +0000628 if (LocaleCompare("compose",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000629 {
anthony92c93bd2012-03-19 14:02:47 +0000630 /* FUTURE: _image_info should be used,
anthony72feaa62012-01-17 06:46:23 +0000631 SyncImageSettings() used to set per-image attribute. - REMOVE
632
anthonyafbaed72011-10-26 12:05:04 +0000633 This setting should NOT be used to set image 'compose'
anthony92c93bd2012-03-19 14:02:47 +0000634 "-layer" operators shoud use _image_info if defined otherwise
anthony72feaa62012-01-17 06:46:23 +0000635 they should use a per-image compose setting.
anthony965524b2011-10-07 12:34:14 +0000636 */
anthonyebb73a22012-03-22 14:25:52 +0000637 parse = ParseCommandOption(MagickComposeOptions,MagickFalse,
638 ArgOption("undefined"));
639 if (parse < 0)
640 CLIWandExceptArgBreak(OptionError,"UnrecognizedComposeOperator",
641 option,arg1);
642 _image_info->compose=(CompositeOperator) parse;
anthony92c93bd2012-03-19 14:02:47 +0000643 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +0000644 break;
645 }
anthonyafa3dfc2012-03-03 11:31:30 +0000646 if (LocaleCompare("compress",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000647 {
anthony92c93bd2012-03-19 14:02:47 +0000648 /* FUTURE: What should be used? _image_info or ImageOption ???
anthony5f867ae2011-10-09 10:28:34 +0000649 The former is more efficent, but Crisy prefers the latter!
anthony72feaa62012-01-17 06:46:23 +0000650 SyncImageSettings() used to set per-image attribute.
anthony5f867ae2011-10-09 10:28:34 +0000651
anthony92c93bd2012-03-19 14:02:47 +0000652 The coders appears to use _image_info, not Image_Option
anthony5f867ae2011-10-09 10:28:34 +0000653 however the image attribute (for save) is set from the
654 ImageOption!
anthony72feaa62012-01-17 06:46:23 +0000655
656 Note that "undefined" is a different setting to "none".
anthony5f867ae2011-10-09 10:28:34 +0000657 */
anthonyebb73a22012-03-22 14:25:52 +0000658 parse = ParseCommandOption(MagickCompressOptions,MagickFalse,
659 ArgOption("undefined"));
660 if (parse < 0)
661 CLIWandExceptArgBreak(OptionError,"UnrecognizedImageCompression",
662 option,arg1);
663 _image_info->compression=(CompressionType) parse;
anthony92c93bd2012-03-19 14:02:47 +0000664 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +0000665 break;
666 }
anthonyebb73a22012-03-22 14:25:52 +0000667 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +0000668 }
669 case 'd':
670 {
anthonyafa3dfc2012-03-03 11:31:30 +0000671 if (LocaleCompare("debug",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000672 {
anthony72feaa62012-01-17 06:46:23 +0000673 /* SyncImageSettings() used to set per-image attribute. */
anthonyebb73a22012-03-22 14:25:52 +0000674 arg1=ArgOption("none");
675 parse = ParseCommandOption(MagickLogEventOptions,MagickFalse,arg1);
676 if (parse < 0)
677 CLIWandExceptArgBreak(OptionError,"UnrecognizedEventType",
678 option,arg1);
679 (void) SetLogEventMask(arg1);
680 _image_info->debug=IsEventLogging(); /* extract logging*/
anthony43f425d2012-02-26 12:58:58 +0000681 cli_wand->wand.debug=IsEventLogging();
anthony805a2d42011-09-25 08:25:12 +0000682 break;
683 }
anthonyafa3dfc2012-03-03 11:31:30 +0000684 if (LocaleCompare("define",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000685 {
anthony24aa8822012-03-11 00:56:06 +0000686 if (LocaleNCompare(arg1,"registry:",9) == 0)
anthony805a2d42011-09-25 08:25:12 +0000687 {
anthony5f867ae2011-10-09 10:28:34 +0000688 if (IfSetOption)
anthony92c93bd2012-03-19 14:02:47 +0000689 (void) DefineImageRegistry(StringRegistryType,arg1+9,_exception);
anthony5f867ae2011-10-09 10:28:34 +0000690 else
anthony24aa8822012-03-11 00:56:06 +0000691 (void) DeleteImageRegistry(arg1+9);
anthony805a2d42011-09-25 08:25:12 +0000692 break;
693 }
anthony24aa8822012-03-11 00:56:06 +0000694 /* DefineImageOption() equals SetImageOption() but with '=' */
anthony5f867ae2011-10-09 10:28:34 +0000695 if (IfSetOption)
anthony92c93bd2012-03-19 14:02:47 +0000696 (void) DefineImageOption(_image_info,arg1);
anthony7bcfe7f2012-03-30 14:01:22 +0000697 else if (IsMagickFalse(DeleteImageOption(_image_info,arg1)))
anthonyebb73a22012-03-22 14:25:52 +0000698 CLIWandExceptArgBreak(OptionError,"NoSuchOption",option,arg1);
anthony805a2d42011-09-25 08:25:12 +0000699 break;
700 }
anthonyafa3dfc2012-03-03 11:31:30 +0000701 if (LocaleCompare("delay",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000702 {
anthonyafbaed72011-10-26 12:05:04 +0000703 /* Only used for new images via AcquireImage()
704 FUTURE: Option should also be used for "-morph" (color morphing)
anthony5f867ae2011-10-09 10:28:34 +0000705 */
anthonyebb73a22012-03-22 14:25:52 +0000706 arg1=ArgOption("0");
anthony7bcfe7f2012-03-30 14:01:22 +0000707 if (IfMagickFalse(IsGeometry(arg1)))
anthonyebb73a22012-03-22 14:25:52 +0000708 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
709 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000710 break;
711 }
anthonyafa3dfc2012-03-03 11:31:30 +0000712 if (LocaleCompare("density",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000713 {
anthony92c93bd2012-03-19 14:02:47 +0000714 /* FUTURE: strings used in _image_info attr and _draw_info!
anthony72feaa62012-01-17 06:46:23 +0000715 Basically as density can be in a XxY form!
716
717 SyncImageSettings() used to set per-image attribute.
718 */
anthony7bcfe7f2012-03-30 14:01:22 +0000719 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthonyebb73a22012-03-22 14:25:52 +0000720 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +0000721 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
722 (void) CloneString(&_image_info->density,ArgOption(NULL));
723 (void) CloneString(&_draw_info->density,_image_info->density);
anthony805a2d42011-09-25 08:25:12 +0000724 break;
725 }
anthonyafa3dfc2012-03-03 11:31:30 +0000726 if (LocaleCompare("depth",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000727 {
anthony72feaa62012-01-17 06:46:23 +0000728 /* This is also a SimpleImageOperator! for 8->16 vaule trunc !!!!
729 SyncImageSettings() used to set per-image attribute.
730 */
anthony7bcfe7f2012-03-30 14:01:22 +0000731 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthonyebb73a22012-03-22 14:25:52 +0000732 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +0000733 _image_info->depth=IfSetOption?StringToUnsignedLong(arg1)
anthony5f867ae2011-10-09 10:28:34 +0000734 :MAGICKCORE_QUANTUM_DEPTH;
anthony805a2d42011-09-25 08:25:12 +0000735 break;
736 }
anthonyafa3dfc2012-03-03 11:31:30 +0000737 if (LocaleCompare("direction",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000738 {
anthony92c93bd2012-03-19 14:02:47 +0000739 /* Image Option is only used to set _draw_info */
anthonyebb73a22012-03-22 14:25:52 +0000740 arg1=ArgOption("undefined");
741 parse = ParseCommandOption(MagickDirectionOptions,MagickFalse,arg1);
742 if (parse < 0)
743 CLIWandExceptArgBreak(OptionError,"UnrecognizedDirectionType",
744 option,arg1);
745 _draw_info->direction=(DirectionType) parse;
746 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000747 break;
748 }
anthonyafa3dfc2012-03-03 11:31:30 +0000749 if (LocaleCompare("display",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000750 {
anthony92c93bd2012-03-19 14:02:47 +0000751 (void) CloneString(&_image_info->server_name,ArgOption(NULL));
752 (void) CloneString(&_draw_info->server_name,_image_info->server_name);
anthony805a2d42011-09-25 08:25:12 +0000753 break;
754 }
anthonyafa3dfc2012-03-03 11:31:30 +0000755 if (LocaleCompare("dispose",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000756 {
anthony72feaa62012-01-17 06:46:23 +0000757 /* only used in setting new images */
anthonyebb73a22012-03-22 14:25:52 +0000758 arg1=ArgOption("undefined");
759 parse = ParseCommandOption(MagickDisposeOptions,MagickFalse,arg1);
760 if (parse < 0)
761 CLIWandExceptArgBreak(OptionError,"UnrecognizedDisposeMethod",
762 option,arg1);
anthony92c93bd2012-03-19 14:02:47 +0000763 (void) SetImageOption(_image_info,option+1,ArgOption("undefined"));
anthony805a2d42011-09-25 08:25:12 +0000764 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 }
927 case 'i':
928 {
anthonyafa3dfc2012-03-03 11:31:30 +0000929 if (LocaleCompare("intent",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000930 {
anthony72feaa62012-01-17 06:46:23 +0000931 /* Only used by coders: MIFF, MPC, BMP, PNG
anthonydcf510d2011-10-30 13:51:40 +0000932 and for image profile call to AcquireTransformThreadSet()
anthony72feaa62012-01-17 06:46:23 +0000933 SyncImageSettings() used to set per-image attribute.
anthonydcf510d2011-10-30 13:51:40 +0000934 */
anthonyfe1aa782012-03-24 13:43:04 +0000935 arg1 = ArgOption("indefined");
936 parse = ParseCommandOption(MagickIntentOptions,MagickFalse,arg1);
937 if (parse < 0)
938 CLIWandExceptArgBreak(OptionError,"UnrecognizedIntentType",
939 option,arg1);
940 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000941 break;
942 }
anthonyafa3dfc2012-03-03 11:31:30 +0000943 if (LocaleCompare("interlace",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000944 {
anthony92c93bd2012-03-19 14:02:47 +0000945 /* _image_info is directly used by coders (so why an image setting?)
anthony72feaa62012-01-17 06:46:23 +0000946 SyncImageSettings() used to set per-image attribute.
anthonydcf510d2011-10-30 13:51:40 +0000947 */
anthonyfe1aa782012-03-24 13:43:04 +0000948 arg1 = ArgOption("undefined");
949 parse = ParseCommandOption(MagickInterlaceOptions,MagickFalse,arg1);
950 if (parse < 0)
951 CLIWandExceptArgBreak(OptionError,"UnrecognizedInterlaceType",
952 option,arg1);
953 _image_info->interlace=(InterlaceType) parse;
954 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000955 break;
956 }
anthonyafa3dfc2012-03-03 11:31:30 +0000957 if (LocaleCompare("interline-spacing",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000958 {
anthony7bcfe7f2012-03-30 14:01:22 +0000959 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +0000960 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +0000961 (void) SetImageOption(_image_info,option+1, ArgOption(NULL));
962 _draw_info->interline_spacing=StringToDouble(ArgOption("0"),
anthony72feaa62012-01-17 06:46:23 +0000963 (char **) NULL);
anthony805a2d42011-09-25 08:25:12 +0000964 break;
965 }
anthonyafa3dfc2012-03-03 11:31:30 +0000966 if (LocaleCompare("interpolate",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000967 {
anthonyfd706f92012-01-19 04:22:02 +0000968 /* SyncImageSettings() used to set per-image attribute. */
anthonyfe1aa782012-03-24 13:43:04 +0000969 arg1 = ArgOption("undefined");
970 parse = ParseCommandOption(MagickInterpolateOptions,MagickFalse,arg1);
971 if (parse < 0)
972 CLIWandExceptArgBreak(OptionError,"UnrecognizedInterpolateMethod",
973 option,arg1);
974 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000975 break;
976 }
anthonyafa3dfc2012-03-03 11:31:30 +0000977 if (LocaleCompare("interword-spacing",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000978 {
anthony7bcfe7f2012-03-30 14:01:22 +0000979 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +0000980 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +0000981 (void) SetImageOption(_image_info,option+1, ArgOption(NULL));
982 _draw_info->interword_spacing=StringToDouble(ArgOption("0"),(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +0000983 break;
984 }
anthonyebb73a22012-03-22 14:25:52 +0000985 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +0000986 }
987 case 'k':
988 {
anthonyafa3dfc2012-03-03 11:31:30 +0000989 if (LocaleCompare("kerning",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000990 {
anthony7bcfe7f2012-03-30 14:01:22 +0000991 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +0000992 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +0000993 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
994 _draw_info->kerning=StringToDouble(ArgOption("0"),(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +0000995 break;
996 }
anthonyebb73a22012-03-22 14:25:52 +0000997 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +0000998 }
999 case 'l':
1000 {
anthonyafa3dfc2012-03-03 11:31:30 +00001001 if (LocaleCompare("label",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001002 {
anthony72feaa62012-01-17 06:46:23 +00001003 /* only used for new images - not in SyncImageOptions() */
anthony92c93bd2012-03-19 14:02:47 +00001004 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +00001005 break;
1006 }
anthony756cd0d2012-04-08 12:41:44 +00001007 if (LocaleCompare("limit",option+1) == 0)
1008 {
1009 MagickSizeType
1010 limit;
1011
1012 limit=MagickResourceInfinity;
1013 parse= ParseCommandOption(MagickResourceOptions,MagickFalse,arg1);
1014 if ( parse < 0 )
1015 CLIWandExceptArgBreak(OptionError,"UnrecognizedResourceType",
1016 option,arg1);
1017 if (LocaleCompare("unlimited",arg2) != 0)
1018 limit=(MagickSizeType) SiPrefixToDoubleInterval(arg2,100.0);
1019 (void) SetMagickResourceLimit((ResourceType)parse,limit);
1020 break;
1021 }
anthonyafa3dfc2012-03-03 11:31:30 +00001022 if (LocaleCompare("log",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001023 {
anthonyfe1aa782012-03-24 13:43:04 +00001024 if (IfSetOption) {
1025 if ((strchr(arg1,'%') == (char *) NULL))
1026 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony24aa8822012-03-11 00:56:06 +00001027 (void) SetLogFormat(arg1);
anthonyfe1aa782012-03-24 13:43:04 +00001028 }
anthony805a2d42011-09-25 08:25:12 +00001029 break;
1030 }
anthonyafa3dfc2012-03-03 11:31:30 +00001031 if (LocaleCompare("loop",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001032 {
anthony72feaa62012-01-17 06:46:23 +00001033 /* SyncImageSettings() used to set per-image attribute. */
anthonyfe1aa782012-03-24 13:43:04 +00001034 arg1=ArgOption("0");
anthony7bcfe7f2012-03-30 14:01:22 +00001035 if (IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00001036 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1037 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +00001038 break;
1039 }
anthonyebb73a22012-03-22 14:25:52 +00001040 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001041 }
1042 case 'm':
1043 {
anthonyafa3dfc2012-03-03 11:31:30 +00001044 if (LocaleCompare("mattecolor",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001045 {
anthony72feaa62012-01-17 06:46:23 +00001046 /* SyncImageSettings() used to set per-image attribute. */
anthony92c93bd2012-03-19 14:02:47 +00001047 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony72feaa62012-01-17 06:46:23 +00001048 (void) QueryColorCompliance(ArgOption(MatteColor),AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +00001049 &_image_info->matte_color,_exception);
anthony805a2d42011-09-25 08:25:12 +00001050 break;
1051 }
anthonyafa3dfc2012-03-03 11:31:30 +00001052 if (LocaleCompare("monitor",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001053 {
anthony92c93bd2012-03-19 14:02:47 +00001054 (void) SetImageInfoProgressMonitor(_image_info, IfSetOption?
anthony31f1bf72012-01-30 12:37:22 +00001055 MonitorProgress: (MagickProgressMonitor) NULL, (void *) NULL);
anthony805a2d42011-09-25 08:25:12 +00001056 break;
1057 }
anthonyafa3dfc2012-03-03 11:31:30 +00001058 if (LocaleCompare("monochrome",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001059 {
anthony24aa8822012-03-11 00:56:06 +00001060 /* Setting (used by some input coders!) -- why?
1061 Warning: This is also Special '-type' SimpleOperator
anthony72feaa62012-01-17 06:46:23 +00001062 */
anthony92c93bd2012-03-19 14:02:47 +00001063 _image_info->monochrome= ArgBoolean;
anthony805a2d42011-09-25 08:25:12 +00001064 break;
1065 }
anthonyebb73a22012-03-22 14:25:52 +00001066 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001067 }
1068 case 'o':
1069 {
anthonyafa3dfc2012-03-03 11:31:30 +00001070 if (LocaleCompare("orient",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001071 {
anthony72feaa62012-01-17 06:46:23 +00001072 /* Is not used when defining for new images.
anthonydcf510d2011-10-30 13:51:40 +00001073 This makes it more of a 'operation' than a setting
anthony72feaa62012-01-17 06:46:23 +00001074 FUTURE: make set meta-data operator instead.
1075 SyncImageSettings() used to set per-image attribute.
anthonydcf510d2011-10-30 13:51:40 +00001076 */
anthony7bc87992012-03-25 02:32:51 +00001077 parse=ParseCommandOption(MagickOrientationOptions,MagickFalse,
1078 ArgOption("undefined"));
1079 if (parse < 0)
1080 CLIWandExceptArgBreak(OptionError,"UnrecognizedImageOrientation",
1081 option,arg1);
1082 _image_info->orientation=(OrientationType)parse;
anthony92c93bd2012-03-19 14:02:47 +00001083 (void) SetImageOption(_image_info,option+1, ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +00001084 break;
1085 }
anthonyebb73a22012-03-22 14:25:52 +00001086 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001087 }
1088 case 'p':
1089 {
anthonyafa3dfc2012-03-03 11:31:30 +00001090 if (LocaleCompare("page",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001091 {
anthony7bc87992012-03-25 02:32:51 +00001092 /* Only used for new images and image generators.
anthony72feaa62012-01-17 06:46:23 +00001093 SyncImageSettings() used to set per-image attribute. ?????
1094 That last is WRONG!!!!
anthony7bc87992012-03-25 02:32:51 +00001095 FUTURE: adjust named 'page' sizes according density
anthony72feaa62012-01-17 06:46:23 +00001096 */
anthony805a2d42011-09-25 08:25:12 +00001097 char
1098 *canonical_page,
1099 page[MaxTextExtent];
1100
1101 const char
1102 *image_option;
1103
1104 MagickStatusType
1105 flags;
1106
1107 RectangleInfo
1108 geometry;
1109
anthonydcf510d2011-10-30 13:51:40 +00001110 if (!IfSetOption)
anthony805a2d42011-09-25 08:25:12 +00001111 {
anthony92c93bd2012-03-19 14:02:47 +00001112 (void) DeleteImageOption(_image_info,option+1);
1113 (void) CloneString(&_image_info->page,(char *) NULL);
anthony805a2d42011-09-25 08:25:12 +00001114 break;
1115 }
1116 (void) ResetMagickMemory(&geometry,0,sizeof(geometry));
anthony92c93bd2012-03-19 14:02:47 +00001117 image_option=GetImageOption(_image_info,"page");
anthony805a2d42011-09-25 08:25:12 +00001118 if (image_option != (const char *) NULL)
1119 flags=ParseAbsoluteGeometry(image_option,&geometry);
anthony24aa8822012-03-11 00:56:06 +00001120 canonical_page=GetPageGeometry(arg1);
anthony805a2d42011-09-25 08:25:12 +00001121 flags=ParseAbsoluteGeometry(canonical_page,&geometry);
1122 canonical_page=DestroyString(canonical_page);
1123 (void) FormatLocaleString(page,MaxTextExtent,"%lux%lu",
1124 (unsigned long) geometry.width,(unsigned long) geometry.height);
1125 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
1126 (void) FormatLocaleString(page,MaxTextExtent,"%lux%lu%+ld%+ld",
1127 (unsigned long) geometry.width,(unsigned long) geometry.height,
1128 (long) geometry.x,(long) geometry.y);
anthony92c93bd2012-03-19 14:02:47 +00001129 (void) SetImageOption(_image_info,option+1,page);
1130 (void) CloneString(&_image_info->page,page);
anthony805a2d42011-09-25 08:25:12 +00001131 break;
1132 }
anthonyafa3dfc2012-03-03 11:31:30 +00001133 if (LocaleCompare("ping",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001134 {
anthony92c93bd2012-03-19 14:02:47 +00001135 _image_info->ping = ArgBoolean;
anthony805a2d42011-09-25 08:25:12 +00001136 break;
1137 }
anthonyafa3dfc2012-03-03 11:31:30 +00001138 if (LocaleCompare("pointsize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001139 {
anthonyf42014d2012-03-25 09:53:06 +00001140 if (IfSetOption) {
anthony7bcfe7f2012-03-30 14:01:22 +00001141 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00001142 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1143 _image_info->pointsize =
1144 _draw_info->pointsize =
1145 StringToDouble(arg1,(char **) NULL);
1146 }
1147 else {
1148 _image_info->pointsize=0.0; /* unset pointsize */
1149 _draw_info->pointsize=12.0;
1150 }
anthony805a2d42011-09-25 08:25:12 +00001151 break;
1152 }
anthonyafa3dfc2012-03-03 11:31:30 +00001153 if (LocaleCompare("precision",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001154 {
anthonyf42014d2012-03-25 09:53:06 +00001155 arg1=ArgOption("-1");
anthony7bcfe7f2012-03-30 14:01:22 +00001156 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00001157 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1158 (void) SetMagickPrecision(StringToInteger(arg1));
anthony805a2d42011-09-25 08:25:12 +00001159 break;
1160 }
anthonydcf510d2011-10-30 13:51:40 +00001161 /* FUTURE: Only the 'preview' coder appears to use this
anthonya3ef4ed2012-03-17 06:52:53 +00001162 * DEPRECIATE the coder? Leaving only the 'preview' operator.
anthonyafa3dfc2012-03-03 11:31:30 +00001163 if (LocaleCompare("preview",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001164 {
anthony92c93bd2012-03-19 14:02:47 +00001165 _image_info->preview_type=UndefinedPreview;
anthonydcf510d2011-10-30 13:51:40 +00001166 if (IfSetOption)
anthony92c93bd2012-03-19 14:02:47 +00001167 _image_info->preview_type=(PreviewType) ParseCommandOption(
anthony24aa8822012-03-11 00:56:06 +00001168 MagickPreviewOptions,MagickFalse,arg1);
anthony805a2d42011-09-25 08:25:12 +00001169 break;
1170 }
anthonydcf510d2011-10-30 13:51:40 +00001171 */
anthonyebb73a22012-03-22 14:25:52 +00001172 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001173 }
1174 case 'q':
1175 {
anthonyafa3dfc2012-03-03 11:31:30 +00001176 if (LocaleCompare("quality",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001177 {
anthony7bcfe7f2012-03-30 14:01:22 +00001178 if (IfMagickFalse(IsGeometry(arg1)))
anthony7bc87992012-03-25 02:32:51 +00001179 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyf42014d2012-03-25 09:53:06 +00001180 _image_info->quality= IfSetOption ? StringToUnsignedLong(arg1)
1181 : UNDEFINED_COMPRESSION_QUALITY;
anthony92c93bd2012-03-19 14:02:47 +00001182 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +00001183 break;
1184 }
anthonyafa3dfc2012-03-03 11:31:30 +00001185 if (LocaleCompare("quantize",option+1) == 0)
anthonyafbaed72011-10-26 12:05:04 +00001186 {
anthony92c93bd2012-03-19 14:02:47 +00001187 /* Just a set direct in _quantize_info */
anthony7bc87992012-03-25 02:32:51 +00001188 arg1=ArgOption("undefined");
1189 parse=ParseCommandOption(MagickColorspaceOptions,MagickFalse,arg1);
1190 if (parse < 0)
1191 CLIWandExceptArgBreak(OptionError,"UnrecognizedColorspace",
1192 option,arg1);
1193 _quantize_info->colorspace=(ColorspaceType)parse;
anthonyafbaed72011-10-26 12:05:04 +00001194 break;
1195 }
anthonyafa3dfc2012-03-03 11:31:30 +00001196 if (LocaleCompare("quiet",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001197 {
anthonyf42014d2012-03-25 09:53:06 +00001198 /* FUTURE: if two -quiet is performed you can not do +quiet!
1199 This needs to be checked over thoughly.
1200 */
anthony805a2d42011-09-25 08:25:12 +00001201 static WarningHandler
1202 warning_handler = (WarningHandler) NULL;
anthony72feaa62012-01-17 06:46:23 +00001203
anthonyafbaed72011-10-26 12:05:04 +00001204 WarningHandler
1205 tmp = SetWarningHandler((WarningHandler) NULL);
anthony805a2d42011-09-25 08:25:12 +00001206
anthonyafbaed72011-10-26 12:05:04 +00001207 if ( tmp != (WarningHandler) NULL)
1208 warning_handler = tmp; /* remember the old handler */
1209 if (!IfSetOption) /* set the old handler */
1210 warning_handler=SetWarningHandler(warning_handler);
anthony805a2d42011-09-25 08:25:12 +00001211 break;
1212 }
anthonyebb73a22012-03-22 14:25:52 +00001213 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001214 }
1215 case 'r':
1216 {
anthonyafa3dfc2012-03-03 11:31:30 +00001217 if (LocaleCompare("red-primary",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001218 {
anthonydcf510d2011-10-30 13:51:40 +00001219 /* Image chromaticity X,Y NB: Y=X if Y not defined
1220 Used by many coders
anthony72feaa62012-01-17 06:46:23 +00001221 SyncImageSettings() used to set per-image attribute.
anthonydcf510d2011-10-30 13:51:40 +00001222 */
anthonyf42014d2012-03-25 09:53:06 +00001223 arg1=ArgOption("0.0");
anthony7bcfe7f2012-03-30 14:01:22 +00001224 if (IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00001225 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyf42014d2012-03-25 09:53:06 +00001226 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +00001227 break;
1228 }
cristyb0f7a182012-04-06 23:33:11 +00001229 if (LocaleCompare("regard-warnings",option+1) == 0)
1230 break;
anthonyafa3dfc2012-03-03 11:31:30 +00001231 if (LocaleCompare("render",option+1) == 0)
anthonyafbaed72011-10-26 12:05:04 +00001232 {
anthony92c93bd2012-03-19 14:02:47 +00001233 /* _draw_info only setting */
1234 _draw_info->render= ArgBooleanNot;
anthonyafbaed72011-10-26 12:05:04 +00001235 break;
1236 }
anthony756cd0d2012-04-08 12:41:44 +00001237 if (LocaleCompare("respect-parenthesis",option+1) == 0)
1238 {
1239 /* link image and setting stacks - option is itself saved on stack! */
1240 (void) SetImageOption(_image_info,option+1,ArgBooleanString);
1241 break;
1242 }
anthonyebb73a22012-03-22 14:25:52 +00001243 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001244 }
1245 case 's':
1246 {
anthonyafa3dfc2012-03-03 11:31:30 +00001247 if (LocaleCompare("sampling-factor",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001248 {
anthonyafbaed72011-10-26 12:05:04 +00001249 /* FUTURE: should be converted to jpeg:sampling_factor */
anthony7bcfe7f2012-03-30 14:01:22 +00001250 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00001251 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001252 (void) CloneString(&_image_info->sampling_factor,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +00001253 break;
1254 }
anthonyafa3dfc2012-03-03 11:31:30 +00001255 if (LocaleCompare("scene",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001256 {
anthonyf42014d2012-03-25 09:53:06 +00001257 /* SyncImageSettings() used to set this as a per-image attribute.
anthony72feaa62012-01-17 06:46:23 +00001258 What ??? Why ????
1259 */
anthony7bcfe7f2012-03-30 14:01:22 +00001260 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00001261 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001262 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1263 _image_info->scene=StringToUnsignedLong(ArgOption("0"));
anthony805a2d42011-09-25 08:25:12 +00001264 break;
1265 }
anthonyafa3dfc2012-03-03 11:31:30 +00001266 if (LocaleCompare("seed",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001267 {
anthony7bcfe7f2012-03-30 14:01:22 +00001268 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00001269 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyafbaed72011-10-26 12:05:04 +00001270 SeedPseudoRandomGenerator(
anthony24aa8822012-03-11 00:56:06 +00001271 IfSetOption ? (size_t) StringToUnsignedLong(arg1)
anthonyafbaed72011-10-26 12:05:04 +00001272 : (size_t) time((time_t *) NULL) );
anthony805a2d42011-09-25 08:25:12 +00001273 break;
1274 }
anthonyafa3dfc2012-03-03 11:31:30 +00001275 if (LocaleCompare("size",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001276 {
anthony92c93bd2012-03-19 14:02:47 +00001277 /* FUTURE: string in _image_info -- convert to Option ???
anthonyafbaed72011-10-26 12:05:04 +00001278 Look at the special handling for "size" in SetImageOption()
anthony74b1cfc2011-10-06 12:44:16 +00001279 */
anthony92c93bd2012-03-19 14:02:47 +00001280 (void) CloneString(&_image_info->size,ArgOption(NULL));
anthonyafbaed72011-10-26 12:05:04 +00001281 break;
1282 }
anthonyafa3dfc2012-03-03 11:31:30 +00001283 if (LocaleCompare("stretch",option+1) == 0)
anthonyafbaed72011-10-26 12:05:04 +00001284 {
anthonyf42014d2012-03-25 09:53:06 +00001285 arg1=ArgOption("undefined");
1286 parse = ParseCommandOption(MagickStretchOptions,MagickFalse,arg1);
1287 if (parse < 0)
1288 CLIWandExceptArgBreak(OptionError,"UnrecognizedStretchType",
1289 option,arg1);
1290 _draw_info->stretch=(StretchType) parse;
anthony805a2d42011-09-25 08:25:12 +00001291 break;
1292 }
anthonyafa3dfc2012-03-03 11:31:30 +00001293 if (LocaleCompare("stroke",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001294 {
anthonyafbaed72011-10-26 12:05:04 +00001295 /* set stroke color OR stroke-pattern
anthonyfd706f92012-01-19 04:22:02 +00001296 UPDATE: ensure stroke color is not destroyed is a pattern
1297 is given. Just in case the color is also used for other purposes.
anthonyafbaed72011-10-26 12:05:04 +00001298 */
anthony72feaa62012-01-17 06:46:23 +00001299 MagickBooleanType
1300 status;
anthonyafbaed72011-10-26 12:05:04 +00001301
1302 ExceptionInfo
1303 *sans;
1304
anthonyfd706f92012-01-19 04:22:02 +00001305 PixelInfo
1306 color;
1307
anthony2a0ec8c2012-03-24 04:35:56 +00001308 arg1 = ArgOption("none"); /* +fill turns it off! */
1309 (void) SetImageOption(_image_info,option+1,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001310 if (_draw_info->stroke_pattern != (Image *) NULL)
1311 _draw_info->stroke_pattern=DestroyImage(_draw_info->stroke_pattern);
anthony72feaa62012-01-17 06:46:23 +00001312
1313 /* is it a color or a image? -- ignore exceptions */
anthonyafbaed72011-10-26 12:05:04 +00001314 sans=AcquireExceptionInfo();
anthony2a0ec8c2012-03-24 04:35:56 +00001315 status=QueryColorCompliance(arg1,AllCompliance,&color,sans);
anthonyafbaed72011-10-26 12:05:04 +00001316 sans=DestroyExceptionInfo(sans);
anthonyfd706f92012-01-19 04:22:02 +00001317
anthony7bcfe7f2012-03-30 14:01:22 +00001318 if (IfMagickFalse(status))
anthony2a0ec8c2012-03-24 04:35:56 +00001319 _draw_info->stroke_pattern=GetImageCache(_image_info,arg1,_exception);
anthonyfd706f92012-01-19 04:22:02 +00001320 else
anthony92c93bd2012-03-19 14:02:47 +00001321 _draw_info->stroke=color;
anthony805a2d42011-09-25 08:25:12 +00001322 break;
1323 }
anthonyafa3dfc2012-03-03 11:31:30 +00001324 if (LocaleCompare("strokewidth",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001325 {
anthony7bcfe7f2012-03-30 14:01:22 +00001326 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00001327 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001328 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1329 _draw_info->stroke_width=StringToDouble(ArgOption("1.0"),
anthony72feaa62012-01-17 06:46:23 +00001330 (char **) NULL);
anthonyafbaed72011-10-26 12:05:04 +00001331 break;
1332 }
anthonyafa3dfc2012-03-03 11:31:30 +00001333 if (LocaleCompare("style",option+1) == 0)
anthonyafbaed72011-10-26 12:05:04 +00001334 {
anthonyf42014d2012-03-25 09:53:06 +00001335 arg1=ArgOption("undefined");
1336 parse = ParseCommandOption(MagickStyleOptions,MagickFalse,arg1);
1337 if (parse < 0)
1338 CLIWandExceptArgBreak(OptionError,"UnrecognizedStyleType",
1339 option,arg1);
1340 _draw_info->style=(StyleType) parse;
anthony805a2d42011-09-25 08:25:12 +00001341 break;
1342 }
anthonyafa3dfc2012-03-03 11:31:30 +00001343 if (LocaleCompare("synchronize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001344 {
anthonyf42014d2012-03-25 09:53:06 +00001345 /* FUTURE: syncronize to storage - but what does that mean? */
anthony92c93bd2012-03-19 14:02:47 +00001346 _image_info->synchronize = ArgBoolean;
anthony805a2d42011-09-25 08:25:12 +00001347 break;
1348 }
anthonyebb73a22012-03-22 14:25:52 +00001349 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001350 }
1351 case 't':
1352 {
anthonyafa3dfc2012-03-03 11:31:30 +00001353 if (LocaleCompare("taint",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001354 {
anthony72feaa62012-01-17 06:46:23 +00001355 /* SyncImageSettings() used to set per-image attribute. */
anthony92c93bd2012-03-19 14:02:47 +00001356 (void) SetImageOption(_image_info,option+1,ArgBooleanString);
anthony805a2d42011-09-25 08:25:12 +00001357 break;
1358 }
anthonyafa3dfc2012-03-03 11:31:30 +00001359 if (LocaleCompare("texture",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001360 {
anthony52bef752012-03-27 13:54:47 +00001361 /* FUTURE: move _image_info string to option splay-tree
1362 Other than "montage" what uses "texture" ????
1363 */
anthony92c93bd2012-03-19 14:02:47 +00001364 (void) CloneString(&_image_info->texture,ArgOption(NULL));
anthonyafbaed72011-10-26 12:05:04 +00001365 break;
1366 }
anthonyafa3dfc2012-03-03 11:31:30 +00001367 if (LocaleCompare("tile",option+1) == 0)
anthonyafbaed72011-10-26 12:05:04 +00001368 {
anthony92c93bd2012-03-19 14:02:47 +00001369 _draw_info->fill_pattern=IfSetOption
1370 ?GetImageCache(_image_info,arg1,_exception)
1371 :DestroyImage(_draw_info->fill_pattern);
anthony805a2d42011-09-25 08:25:12 +00001372 break;
1373 }
anthonyafa3dfc2012-03-03 11:31:30 +00001374 if (LocaleCompare("tile-offset",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001375 {
anthony72feaa62012-01-17 06:46:23 +00001376 /* SyncImageSettings() used to set per-image attribute. ??? */
anthony52bef752012-03-27 13:54:47 +00001377 arg1=ArgOption("0");
anthony7bcfe7f2012-03-30 14:01:22 +00001378 if (IfMagickFalse(IsGeometry(arg1)))
anthony52bef752012-03-27 13:54:47 +00001379 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1380 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +00001381 break;
1382 }
anthonyafa3dfc2012-03-03 11:31:30 +00001383 if (LocaleCompare("transparent-color",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001384 {
anthony92c93bd2012-03-19 14:02:47 +00001385 /* FUTURE: both _image_info attribute & ImageOption in use!
1386 _image_info only used for generating new images.
anthony72feaa62012-01-17 06:46:23 +00001387 SyncImageSettings() used to set per-image attribute.
1388
anthonyafbaed72011-10-26 12:05:04 +00001389 Note that +transparent-color, means fall-back to image
1390 attribute so ImageOption is deleted, not set to a default.
1391 */
anthony7bcfe7f2012-03-30 14:01:22 +00001392 if (IfSetOption && IfMagickFalse(IsGeometry(arg1)))
anthony52bef752012-03-27 13:54:47 +00001393 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001394 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony72feaa62012-01-17 06:46:23 +00001395 (void) QueryColorCompliance(ArgOption("none"),AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +00001396 &_image_info->transparent_color,_exception);
anthony805a2d42011-09-25 08:25:12 +00001397 break;
1398 }
anthonyafa3dfc2012-03-03 11:31:30 +00001399 if (LocaleCompare("treedepth",option+1) == 0)
anthony31f1bf72012-01-30 12:37:22 +00001400 {
anthony92c93bd2012-03-19 14:02:47 +00001401 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1402 _quantize_info->tree_depth=StringToUnsignedLong(ArgOption("0"));
anthony31f1bf72012-01-30 12:37:22 +00001403 break;
1404 }
anthonyafa3dfc2012-03-03 11:31:30 +00001405 if (LocaleCompare("type",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001406 {
anthony72feaa62012-01-17 06:46:23 +00001407 /* SyncImageSettings() used to set per-image attribute. */
anthony52bef752012-03-27 13:54:47 +00001408 parse=ParseCommandOption(MagickTypeOptions,MagickFalse,
1409 ArgOption("undefined"));
1410 if (parse < 0)
1411 CLIWandExceptArgBreak(OptionError,"UnrecognizedImageType",
1412 option,arg1);
1413 _image_info->type=(ImageType) parse;
anthony92c93bd2012-03-19 14:02:47 +00001414 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +00001415 break;
1416 }
anthonyebb73a22012-03-22 14:25:52 +00001417 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001418 }
1419 case 'u':
1420 {
anthonyafa3dfc2012-03-03 11:31:30 +00001421 if (LocaleCompare("undercolor",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001422 {
anthony92c93bd2012-03-19 14:02:47 +00001423 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony72feaa62012-01-17 06:46:23 +00001424 (void) QueryColorCompliance(ArgOption("none"),AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +00001425 &_draw_info->undercolor,_exception);
anthony805a2d42011-09-25 08:25:12 +00001426 break;
1427 }
anthonyafa3dfc2012-03-03 11:31:30 +00001428 if (LocaleCompare("units",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001429 {
anthony72feaa62012-01-17 06:46:23 +00001430 /* SyncImageSettings() used to set per-image attribute.
anthony92c93bd2012-03-19 14:02:47 +00001431 Should this effect _draw_info X and Y resolution?
anthony72feaa62012-01-17 06:46:23 +00001432 FUTURE: this probably should be part of the density setting
1433 */
anthony52bef752012-03-27 13:54:47 +00001434 parse=ParseCommandOption(MagickResolutionOptions,MagickFalse,
1435 ArgOption("undefined"));
1436 if (parse < 0)
1437 CLIWandExceptArgBreak(OptionError,"UnrecognizedUnitsType",
1438 option,arg1);
1439 _image_info->units=(ResolutionType) parse;
anthony92c93bd2012-03-19 14:02:47 +00001440 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +00001441 break;
1442 }
anthonyebb73a22012-03-22 14:25:52 +00001443 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001444 }
1445 case 'v':
1446 {
anthonyafa3dfc2012-03-03 11:31:30 +00001447 if (LocaleCompare("verbose",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001448 {
anthony24aa8822012-03-11 00:56:06 +00001449 /* FUTURE: Remember all options become image artifacts
anthony92c93bd2012-03-19 14:02:47 +00001450 _image_info->verbose is only used by coders.
anthonyab3a50c2011-10-27 11:48:57 +00001451 */
anthony92c93bd2012-03-19 14:02:47 +00001452 (void) SetImageOption(_image_info,option+1,ArgBooleanString);
1453 _image_info->verbose= ArgBoolean;
1454 _image_info->ping=MagickFalse; /* verbose can't be a ping */
anthony805a2d42011-09-25 08:25:12 +00001455 break;
1456 }
anthonyafa3dfc2012-03-03 11:31:30 +00001457 if (LocaleCompare("view",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001458 {
anthony92c93bd2012-03-19 14:02:47 +00001459 /* FUTURE: Convert from _image_info to ImageOption
anthonyab3a50c2011-10-27 11:48:57 +00001460 Only used by coder FPX
anthony52bef752012-03-27 13:54:47 +00001461 And it only tests existance, not its content!
anthonyab3a50c2011-10-27 11:48:57 +00001462 */
anthony92c93bd2012-03-19 14:02:47 +00001463 (void) CloneString(&_image_info->view,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +00001464 break;
1465 }
anthonyafa3dfc2012-03-03 11:31:30 +00001466 if (LocaleCompare("virtual-pixel",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001467 {
anthonyfd706f92012-01-19 04:22:02 +00001468 /* SyncImageSettings() used to set per-image attribute.
1469 This is VERY deep in the image caching structure.
1470 */
anthony52bef752012-03-27 13:54:47 +00001471 parse=ParseCommandOption(MagickVirtualPixelOptions,MagickFalse,
1472 ArgOption("undefined"));
1473 if (parse < 0)
1474 CLIWandExceptArgBreak(OptionError,"UnrecognizedVirtualPixelMethod",
1475 option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001476 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +00001477 break;
1478 }
anthonyebb73a22012-03-22 14:25:52 +00001479 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001480 }
1481 case 'w':
1482 {
anthonyafa3dfc2012-03-03 11:31:30 +00001483 if (LocaleCompare("weight",option+1) == 0)
anthonyab3a50c2011-10-27 11:48:57 +00001484 {
anthony72feaa62012-01-17 06:46:23 +00001485 /* Just what does using a font 'weight' do ???
anthonydcf510d2011-10-30 13:51:40 +00001486 There is no "-list weight" output (reference manual says there is)
anthonyab3a50c2011-10-27 11:48:57 +00001487 */
anthony52bef752012-03-27 13:54:47 +00001488 arg1=ArgOption("all");
anthony92c93bd2012-03-19 14:02:47 +00001489 _draw_info->weight=StringToUnsignedLong(arg1);
anthony24aa8822012-03-11 00:56:06 +00001490 if (LocaleCompare(arg1,"all") == 0)
anthony92c93bd2012-03-19 14:02:47 +00001491 _draw_info->weight=0;
anthony24aa8822012-03-11 00:56:06 +00001492 if (LocaleCompare(arg1,"bold") == 0)
anthony92c93bd2012-03-19 14:02:47 +00001493 _draw_info->weight=700;
anthony24aa8822012-03-11 00:56:06 +00001494 if (LocaleCompare(arg1,"bolder") == 0)
anthony92c93bd2012-03-19 14:02:47 +00001495 if (_draw_info->weight <= 800)
1496 _draw_info->weight+=100;
anthony24aa8822012-03-11 00:56:06 +00001497 if (LocaleCompare(arg1,"lighter") == 0)
anthony92c93bd2012-03-19 14:02:47 +00001498 if (_draw_info->weight >= 100)
1499 _draw_info->weight-=100;
anthony24aa8822012-03-11 00:56:06 +00001500 if (LocaleCompare(arg1,"normal") == 0)
anthony92c93bd2012-03-19 14:02:47 +00001501 _draw_info->weight=400;
anthonyab3a50c2011-10-27 11:48:57 +00001502 break;
1503 }
anthonyafa3dfc2012-03-03 11:31:30 +00001504 if (LocaleCompare("white-point",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001505 {
anthony72feaa62012-01-17 06:46:23 +00001506 /* Used as a image chromaticity setting
1507 SyncImageSettings() used to set per-image attribute.
1508 */
anthony52bef752012-03-27 13:54:47 +00001509 arg1=ArgOption("0.0");
anthony7bcfe7f2012-03-30 14:01:22 +00001510 if (IfMagickFalse(IsGeometry(arg1)))
anthony52bef752012-03-27 13:54:47 +00001511 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1512 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +00001513 break;
1514 }
anthonyebb73a22012-03-22 14:25:52 +00001515 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001516 }
1517 default:
anthonyebb73a22012-03-22 14:25:52 +00001518 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001519 }
anthony24aa8822012-03-11 00:56:06 +00001520
anthony92c93bd2012-03-19 14:02:47 +00001521#undef _image_info
1522#undef _exception
1523#undef _draw_info
1524#undef _quantize_info
anthonyfd706f92012-01-19 04:22:02 +00001525#undef IfSetOption
anthonyfd706f92012-01-19 04:22:02 +00001526#undef ArgBoolean
anthony24aa8822012-03-11 00:56:06 +00001527#undef ArgBooleanNot
1528#undef ArgBooleanString
1529#undef ArgOption
anthonyfd706f92012-01-19 04:22:02 +00001530
anthony31f1bf72012-01-30 12:37:22 +00001531 return;
anthony805a2d42011-09-25 08:25:12 +00001532}
1533
1534/*
1535%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1536% %
1537% %
1538% %
anthony43f425d2012-02-26 12:58:58 +00001539+ 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 +00001540% %
1541% %
1542% %
1543%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1544%
anthony31f1bf72012-01-30 12:37:22 +00001545% WandSimpleOperatorImages() applys one simple image operation given to all
anthony43f425d2012-02-26 12:58:58 +00001546% the images in the CLI wand, with the settings that was previously saved in
1547% the CLI wand.
anthonydcf510d2011-10-30 13:51:40 +00001548%
1549% It is assumed that any per-image settings are up-to-date with respect to
anthony43f425d2012-02-26 12:58:58 +00001550% extra settings that were already saved in the wand.
anthony805a2d42011-09-25 08:25:12 +00001551%
anthonyd1447672012-01-19 05:33:53 +00001552% The format of the WandSimpleOperatorImage method is:
anthony805a2d42011-09-25 08:25:12 +00001553%
anthony43f425d2012-02-26 12:58:58 +00001554% void CLISimpleOperatorImages(MagickCLI *cli_wand,
anthonyafa3dfc2012-03-03 11:31:30 +00001555% const char *option, const char *arg1, const char *arg2)
anthony805a2d42011-09-25 08:25:12 +00001556%
1557% A description of each parameter follows:
1558%
anthony43f425d2012-02-26 12:58:58 +00001559% o cli_wand: structure holding settings and images to be operated on
anthony805a2d42011-09-25 08:25:12 +00001560%
anthonyfd706f92012-01-19 04:22:02 +00001561% o option: The option string for the operation
anthonydcf510d2011-10-30 13:51:40 +00001562%
anthonyfd706f92012-01-19 04:22:02 +00001563% o arg1, arg2: optional argument strings to the operation
anthony805a2d42011-09-25 08:25:12 +00001564%
anthony31f1bf72012-01-30 12:37:22 +00001565% Any problems will be added to the 'exception' entry of the given wand.
anthony805a2d42011-09-25 08:25:12 +00001566%
anthony31f1bf72012-01-30 12:37:22 +00001567% Example usage...
anthonydcf510d2011-10-30 13:51:40 +00001568%
anthonyafa3dfc2012-03-03 11:31:30 +00001569% CLISimpleOperatorImages(cli_wand, "-crop","100x100+20+30",NULL);
1570% CLISimpleOperatorImages(cli_wand, "+repage",NULL,NULL);
1571% CLISimpleOperatorImages(cli_wand, "+distort","SRT","45");
anthonyfd706f92012-01-19 04:22:02 +00001572%
anthony24aa8822012-03-11 00:56:06 +00001573% Or for handling command line arguments EG: +/-option ["arg1"]
anthonydcf510d2011-10-30 13:51:40 +00001574%
anthony43f425d2012-02-26 12:58:58 +00001575% cli_wand
anthonydcf510d2011-10-30 13:51:40 +00001576% argc,argv
1577% i=index in argv
1578%
anthony2052d272012-02-28 12:48:29 +00001579% option_info = GetCommandOptionInfo(argv[i]);
1580% count=option_info->type;
1581% option_type=option_info->flags;
1582%
1583% if ( (option_type & SimpleOperatorOptionFlag) != 0 )
anthonyafa3dfc2012-03-03 11:31:30 +00001584% CLISimpleOperatorImages(cli_wand, argv[i],
anthonyfd706f92012-01-19 04:22:02 +00001585% count>=1 ? argv[i+1] : (char *)NULL,
1586% count>=2 ? argv[i+2] : (char *)NULL );
anthonydcf510d2011-10-30 13:51:40 +00001587% i += count+1;
1588%
anthony805a2d42011-09-25 08:25:12 +00001589*/
anthony31f1bf72012-01-30 12:37:22 +00001590
1591/*
1592 Internal subrountine to apply one simple image operation to the current
anthony43f425d2012-02-26 12:58:58 +00001593 image pointed to by the CLI wand.
anthony31f1bf72012-01-30 12:37:22 +00001594
1595 The image in the list may be modified in three different ways...
1596 * directly modified (EG: -negate, -gamma, -level, -annotate, -draw),
1597 * replaced by a new image (EG: -spread, -resize, -rotate, -morphology)
1598 * one image replace by a list of images (-separate and -crop only!)
1599
anthonyafa3dfc2012-03-03 11:31:30 +00001600 In each case the result replaces the single original image in the list, as
1601 well as the pointer to the modified image (last image added if replaced by a
1602 list of images) is returned.
anthony31f1bf72012-01-30 12:37:22 +00001603
1604 As the image pointed to may be replaced, the first image in the list may
1605 also change. GetFirstImageInList() should be used by caller if they wish
1606 return the Image pointer to the first image in list.
1607*/
anthony43f425d2012-02-26 12:58:58 +00001608static void CLISimpleOperatorImage(MagickCLI *cli_wand,
anthonyafa3dfc2012-03-03 11:31:30 +00001609 const char *option, const char *arg1, const char *arg2)
anthony805a2d42011-09-25 08:25:12 +00001610{
1611 Image *
1612 new_image;
1613
anthony805a2d42011-09-25 08:25:12 +00001614 GeometryInfo
1615 geometry_info;
1616
1617 RectangleInfo
1618 geometry;
1619
1620 MagickStatusType
anthony805a2d42011-09-25 08:25:12 +00001621 flags;
1622
anthony92c93bd2012-03-19 14:02:47 +00001623 ssize_t
anthony2a0ec8c2012-03-24 04:35:56 +00001624 parse;
anthony92c93bd2012-03-19 14:02:47 +00001625
anthony2e4501b2012-03-30 04:41:54 +00001626#define _image_info (cli_wand->wand.image_info)
1627#define _image (cli_wand->wand.images)
1628#define _exception (cli_wand->wand.exception)
1629#define _draw_info (cli_wand->draw_info)
1630#define _quantize_info (cli_wand->quantize_info)
anthonyafa3dfc2012-03-03 11:31:30 +00001631#define IfNormalOp (*option=='-')
1632#define IfPlusOp (*option!='-')
anthony7bcfe7f2012-03-30 14:01:22 +00001633#define normal_op IsMagickTrue(IfNormalOp)
1634#define plus_alt_op IsMagickFalse(IfNormalOp)
anthonyfd706f92012-01-19 04:22:02 +00001635
anthony43f425d2012-02-26 12:58:58 +00001636 assert(cli_wand != (MagickCLI *) NULL);
1637 assert(cli_wand->signature == WandSignature);
1638 assert(cli_wand->wand.signature == WandSignature);
anthony5330ae02012-03-20 14:17:01 +00001639 assert(_image != (Image *) NULL); /* an image must be present */
anthony7bcfe7f2012-03-30 14:01:22 +00001640 if (IfMagickTrue(cli_wand->wand.debug))
anthony43f425d2012-02-26 12:58:58 +00001641 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
anthonydcf510d2011-10-30 13:51:40 +00001642
anthony92c93bd2012-03-19 14:02:47 +00001643 (void) SyncImageSettings(_image_info,_image,_exception);
anthony24aa8822012-03-11 00:56:06 +00001644
anthony805a2d42011-09-25 08:25:12 +00001645 SetGeometryInfo(&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00001646
anthony5330ae02012-03-20 14:17:01 +00001647 new_image = (Image *)NULL; /* the replacement image, if not null at end */
anthony805a2d42011-09-25 08:25:12 +00001648
anthonyfd706f92012-01-19 04:22:02 +00001649 /* FUTURE: We may need somthing a little more optimized than this!
1650 Perhaps, do the 'sync' if 'settings tainted' before next operator.
1651 */
anthonyafa3dfc2012-03-03 11:31:30 +00001652 switch (*(option+1))
anthony805a2d42011-09-25 08:25:12 +00001653 {
1654 case 'a':
1655 {
anthonyafa3dfc2012-03-03 11:31:30 +00001656 if (LocaleCompare("adaptive-blur",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001657 {
anthony7bcfe7f2012-03-30 14:01:22 +00001658 if (IfMagickFalse(IsGeometry(arg1)))
anthony92c93bd2012-03-19 14:02:47 +00001659 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00001660 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00001661 if ((flags & SigmaValue) == 0)
1662 geometry_info.sigma=1.0;
anthony92c93bd2012-03-19 14:02:47 +00001663 new_image=AdaptiveBlurImage(_image,geometry_info.rho,
cristyaa2c16c2012-03-25 22:21:35 +00001664 geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00001665 break;
1666 }
anthonyafa3dfc2012-03-03 11:31:30 +00001667 if (LocaleCompare("adaptive-resize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001668 {
anthonyfe1aa782012-03-24 13:43:04 +00001669 /* FUTURE: Roll into a resize special operator */
anthony7bcfe7f2012-03-30 14:01:22 +00001670 if (IfMagickFalse(IsGeometry(arg1)))
anthony92c93bd2012-03-19 14:02:47 +00001671 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1672 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
1673 new_image=AdaptiveResizeImage(_image,geometry.width,geometry.height,
cristyaa2c16c2012-03-25 22:21:35 +00001674 _exception);
anthony805a2d42011-09-25 08:25:12 +00001675 break;
1676 }
anthonyafa3dfc2012-03-03 11:31:30 +00001677 if (LocaleCompare("adaptive-sharpen",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001678 {
anthony7bcfe7f2012-03-30 14:01:22 +00001679 if (IfMagickFalse(IsGeometry(arg1)))
anthony92c93bd2012-03-19 14:02:47 +00001680 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00001681 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00001682 if ((flags & SigmaValue) == 0)
1683 geometry_info.sigma=1.0;
anthony92c93bd2012-03-19 14:02:47 +00001684 new_image=AdaptiveSharpenImage(_image,geometry_info.rho,
cristyaa2c16c2012-03-25 22:21:35 +00001685 geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00001686 break;
1687 }
anthonyafa3dfc2012-03-03 11:31:30 +00001688 if (LocaleCompare("alpha",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001689 {
anthony2a0ec8c2012-03-24 04:35:56 +00001690 parse=ParseCommandOption(MagickAlphaOptions,MagickFalse,arg1);
1691 if (parse < 0)
anthony92c93bd2012-03-19 14:02:47 +00001692 CLIWandExceptArgBreak(OptionError,"UnrecognizedAlphaChannelType",
1693 option,arg1);
anthony2a0ec8c2012-03-24 04:35:56 +00001694 (void) SetImageAlphaChannel(_image,(AlphaChannelType)parse,
1695 _exception);
anthony805a2d42011-09-25 08:25:12 +00001696 break;
1697 }
anthonyafa3dfc2012-03-03 11:31:30 +00001698 if (LocaleCompare("annotate",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001699 {
1700 char
1701 *text,
1702 geometry[MaxTextExtent];
1703
anthony7bcfe7f2012-03-30 14:01:22 +00001704 if (IfMagickFalse(IsGeometry(arg1)))
anthony92c93bd2012-03-19 14:02:47 +00001705 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00001706 SetGeometryInfo(&geometry_info);
anthonyfd706f92012-01-19 04:22:02 +00001707 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00001708 if ((flags & SigmaValue) == 0)
1709 geometry_info.sigma=geometry_info.rho;
anthony92c93bd2012-03-19 14:02:47 +00001710 text=InterpretImageProperties(_image_info,_image,arg2,
1711 _exception);
anthony805a2d42011-09-25 08:25:12 +00001712 if (text == (char *) NULL)
1713 break;
anthony92c93bd2012-03-19 14:02:47 +00001714 (void) CloneString(&_draw_info->text,text);
anthony805a2d42011-09-25 08:25:12 +00001715 text=DestroyString(text);
1716 (void) FormatLocaleString(geometry,MaxTextExtent,"%+f%+f",
1717 geometry_info.xi,geometry_info.psi);
anthony92c93bd2012-03-19 14:02:47 +00001718 (void) CloneString(&_draw_info->geometry,geometry);
1719 _draw_info->affine.sx=cos(DegreesToRadians(
anthony805a2d42011-09-25 08:25:12 +00001720 fmod(geometry_info.rho,360.0)));
anthony92c93bd2012-03-19 14:02:47 +00001721 _draw_info->affine.rx=sin(DegreesToRadians(
anthony805a2d42011-09-25 08:25:12 +00001722 fmod(geometry_info.rho,360.0)));
anthony92c93bd2012-03-19 14:02:47 +00001723 _draw_info->affine.ry=(-sin(DegreesToRadians(
anthony805a2d42011-09-25 08:25:12 +00001724 fmod(geometry_info.sigma,360.0))));
anthony92c93bd2012-03-19 14:02:47 +00001725 _draw_info->affine.sy=cos(DegreesToRadians(
anthony805a2d42011-09-25 08:25:12 +00001726 fmod(geometry_info.sigma,360.0)));
anthony92c93bd2012-03-19 14:02:47 +00001727 (void) AnnotateImage(_image,_draw_info,_exception);
1728 GetAffineMatrix(&_draw_info->affine);
anthony805a2d42011-09-25 08:25:12 +00001729 break;
1730 }
anthonyafa3dfc2012-03-03 11:31:30 +00001731 if (LocaleCompare("auto-gamma",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001732 {
anthony92c93bd2012-03-19 14:02:47 +00001733 (void) AutoGammaImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00001734 break;
1735 }
anthonyafa3dfc2012-03-03 11:31:30 +00001736 if (LocaleCompare("auto-level",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001737 {
anthony92c93bd2012-03-19 14:02:47 +00001738 (void) AutoLevelImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00001739 break;
1740 }
anthonyafa3dfc2012-03-03 11:31:30 +00001741 if (LocaleCompare("auto-orient",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001742 {
anthony5330ae02012-03-20 14:17:01 +00001743 /* This should probably be a MagickCore function */
anthony92c93bd2012-03-19 14:02:47 +00001744 switch (_image->orientation)
anthony805a2d42011-09-25 08:25:12 +00001745 {
1746 case TopRightOrientation:
1747 {
anthony92c93bd2012-03-19 14:02:47 +00001748 new_image=FlopImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00001749 break;
1750 }
1751 case BottomRightOrientation:
1752 {
anthony92c93bd2012-03-19 14:02:47 +00001753 new_image=RotateImage(_image,180.0,_exception);
anthony805a2d42011-09-25 08:25:12 +00001754 break;
1755 }
1756 case BottomLeftOrientation:
1757 {
anthony92c93bd2012-03-19 14:02:47 +00001758 new_image=FlipImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00001759 break;
1760 }
1761 case LeftTopOrientation:
1762 {
anthony92c93bd2012-03-19 14:02:47 +00001763 new_image=TransposeImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00001764 break;
1765 }
1766 case RightTopOrientation:
1767 {
anthony92c93bd2012-03-19 14:02:47 +00001768 new_image=RotateImage(_image,90.0,_exception);
anthony805a2d42011-09-25 08:25:12 +00001769 break;
1770 }
1771 case RightBottomOrientation:
1772 {
anthony92c93bd2012-03-19 14:02:47 +00001773 new_image=TransverseImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00001774 break;
1775 }
1776 case LeftBottomOrientation:
1777 {
anthony92c93bd2012-03-19 14:02:47 +00001778 new_image=RotateImage(_image,270.0,_exception);
anthony805a2d42011-09-25 08:25:12 +00001779 break;
1780 }
1781 default:
1782 break;
1783 }
1784 if (new_image != (Image *) NULL)
1785 new_image->orientation=TopLeftOrientation;
1786 break;
1787 }
anthonyebb73a22012-03-22 14:25:52 +00001788 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001789 }
1790 case 'b':
1791 {
anthonyafa3dfc2012-03-03 11:31:30 +00001792 if (LocaleCompare("black-threshold",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001793 {
anthony7bcfe7f2012-03-30 14:01:22 +00001794 if (IfMagickFalse(IsGeometry(arg1)))
anthony5330ae02012-03-20 14:17:01 +00001795 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001796 (void) BlackThresholdImage(_image,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00001797 break;
1798 }
anthonyafa3dfc2012-03-03 11:31:30 +00001799 if (LocaleCompare("blue-shift",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001800 {
anthony805a2d42011-09-25 08:25:12 +00001801 geometry_info.rho=1.5;
anthony5330ae02012-03-20 14:17:01 +00001802 if (IfNormalOp) {
anthony7bcfe7f2012-03-30 14:01:22 +00001803 if (IfMagickFalse(IsGeometry(arg1)))
anthony5330ae02012-03-20 14:17:01 +00001804 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00001805 flags=ParseGeometry(arg1,&geometry_info);
anthony5330ae02012-03-20 14:17:01 +00001806 }
anthony92c93bd2012-03-19 14:02:47 +00001807 new_image=BlueShiftImage(_image,geometry_info.rho,_exception);
anthony805a2d42011-09-25 08:25:12 +00001808 break;
1809 }
anthonyafa3dfc2012-03-03 11:31:30 +00001810 if (LocaleCompare("blur",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001811 {
anthony7bcfe7f2012-03-30 14:01:22 +00001812 if (IfMagickFalse(IsGeometry(arg1)))
anthony5330ae02012-03-20 14:17:01 +00001813 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00001814 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00001815 if ((flags & SigmaValue) == 0)
1816 geometry_info.sigma=1.0;
cristyaa2c16c2012-03-25 22:21:35 +00001817 new_image=BlurImage(_image,geometry_info.rho,geometry_info.sigma,
1818 _exception);
anthony805a2d42011-09-25 08:25:12 +00001819 break;
1820 }
anthonyafa3dfc2012-03-03 11:31:30 +00001821 if (LocaleCompare("border",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001822 {
anthony31f1bf72012-01-30 12:37:22 +00001823 CompositeOperator
anthony5f867ae2011-10-09 10:28:34 +00001824 compose;
1825
1826 const char*
anthony5f867ae2011-10-09 10:28:34 +00001827 value;
1828
anthony7bcfe7f2012-03-30 14:01:22 +00001829 if (IfMagickFalse(IsGeometry(arg1)))
anthony5330ae02012-03-20 14:17:01 +00001830 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1831
anthony92c93bd2012-03-19 14:02:47 +00001832 value=GetImageOption(_image_info,"compose");
anthony5f867ae2011-10-09 10:28:34 +00001833 if (value != (const char *) NULL)
1834 compose=(CompositeOperator) ParseCommandOption(
1835 MagickComposeOptions,MagickFalse,value);
1836 else
anthony92c93bd2012-03-19 14:02:47 +00001837 compose=OverCompositeOp; /* use Over not _image->compose */
anthony5f867ae2011-10-09 10:28:34 +00001838
anthony92c93bd2012-03-19 14:02:47 +00001839 flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00001840 if ((flags & SigmaValue) == 0)
1841 geometry.height=geometry.width;
anthony92c93bd2012-03-19 14:02:47 +00001842 new_image=BorderImage(_image,&geometry,compose,_exception);
anthony805a2d42011-09-25 08:25:12 +00001843 break;
1844 }
anthonyafa3dfc2012-03-03 11:31:30 +00001845 if (LocaleCompare("brightness-contrast",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001846 {
1847 double
1848 brightness,
1849 contrast;
1850
1851 GeometryInfo
1852 geometry_info;
1853
1854 MagickStatusType
1855 flags;
1856
anthony7bcfe7f2012-03-30 14:01:22 +00001857 if (IfMagickFalse(IsGeometry(arg1)))
anthony5330ae02012-03-20 14:17:01 +00001858 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00001859 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00001860 brightness=geometry_info.rho;
1861 contrast=0.0;
1862 if ((flags & SigmaValue) != 0)
1863 contrast=geometry_info.sigma;
anthony92c93bd2012-03-19 14:02:47 +00001864 (void) BrightnessContrastImage(_image,brightness,contrast,
1865 _exception);
anthony805a2d42011-09-25 08:25:12 +00001866 break;
1867 }
anthonyebb73a22012-03-22 14:25:52 +00001868 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001869 }
1870 case 'c':
1871 {
anthonyafa3dfc2012-03-03 11:31:30 +00001872 if (LocaleCompare("cdl",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001873 {
1874 char
1875 *color_correction_collection;
1876
1877 /*
1878 Color correct with a color decision list.
1879 */
anthony92c93bd2012-03-19 14:02:47 +00001880 color_correction_collection=FileToString(arg1,~0,_exception);
anthony805a2d42011-09-25 08:25:12 +00001881 if (color_correction_collection == (char *) NULL)
1882 break;
anthony92c93bd2012-03-19 14:02:47 +00001883 (void) ColorDecisionListImage(_image,color_correction_collection,
1884 _exception);
anthony805a2d42011-09-25 08:25:12 +00001885 break;
1886 }
anthonyafa3dfc2012-03-03 11:31:30 +00001887 if (LocaleCompare("charcoal",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001888 {
anthony7bcfe7f2012-03-30 14:01:22 +00001889 if (IfMagickFalse(IsGeometry(arg1)))
anthony5330ae02012-03-20 14:17:01 +00001890 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00001891 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00001892 if ((flags & SigmaValue) == 0)
1893 geometry_info.sigma=1.0;
1894 if ((flags & XiValue) == 0)
1895 geometry_info.xi=1.0;
anthony92c93bd2012-03-19 14:02:47 +00001896 new_image=CharcoalImage(_image,geometry_info.rho,
cristyaa2c16c2012-03-25 22:21:35 +00001897 geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00001898 break;
1899 }
anthonyafa3dfc2012-03-03 11:31:30 +00001900 if (LocaleCompare("chop",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001901 {
anthony7bcfe7f2012-03-30 14:01:22 +00001902 if (IfMagickFalse(IsGeometry(arg1)))
anthony5330ae02012-03-20 14:17:01 +00001903 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001904 (void) ParseGravityGeometry(_image,arg1,&geometry,_exception);
1905 new_image=ChopImage(_image,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00001906 break;
1907 }
anthonyafa3dfc2012-03-03 11:31:30 +00001908 if (LocaleCompare("clamp",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001909 {
anthony92c93bd2012-03-19 14:02:47 +00001910 (void) ClampImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00001911 break;
1912 }
anthonyafa3dfc2012-03-03 11:31:30 +00001913 if (LocaleCompare("clip",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001914 {
anthonyafa3dfc2012-03-03 11:31:30 +00001915 if (IfNormalOp)
anthony92c93bd2012-03-19 14:02:47 +00001916 (void) ClipImage(_image,_exception);
anthony43f425d2012-02-26 12:58:58 +00001917 else /* "+mask" remove the write mask */
anthony92c93bd2012-03-19 14:02:47 +00001918 (void) SetImageMask(_image,(Image *) NULL,_exception);
anthony805a2d42011-09-25 08:25:12 +00001919 break;
1920 }
anthonyafa3dfc2012-03-03 11:31:30 +00001921 if (LocaleCompare("clip-mask",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001922 {
1923 CacheView
1924 *mask_view;
1925
1926 Image
1927 *mask_image;
1928
1929 register Quantum
1930 *restrict q;
1931
1932 register ssize_t
1933 x;
1934
1935 ssize_t
1936 y;
1937
anthonyafa3dfc2012-03-03 11:31:30 +00001938 if (IfPlusOp) {
1939 /* "+clip-mask" Remove the write mask */
anthony92c93bd2012-03-19 14:02:47 +00001940 (void) SetImageMask(_image,(Image *) NULL,_exception);
anthonyafa3dfc2012-03-03 11:31:30 +00001941 break;
1942 }
anthony92c93bd2012-03-19 14:02:47 +00001943 mask_image=GetImageCache(_image_info,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00001944 if (mask_image == (Image *) NULL)
1945 break;
anthony7bcfe7f2012-03-30 14:01:22 +00001946 if (IfMagickFalse(SetImageStorageClass(mask_image,DirectClass,_exception)))
anthony31f1bf72012-01-30 12:37:22 +00001947 break;
anthony5330ae02012-03-20 14:17:01 +00001948 /* Create a write mask from cli_wand mask image */
anthonyfd706f92012-01-19 04:22:02 +00001949 /* FUTURE: use Alpha operations instead and create a Grey Image */
anthony805a2d42011-09-25 08:25:12 +00001950 mask_view=AcquireCacheView(mask_image);
1951 for (y=0; y < (ssize_t) mask_image->rows; y++)
1952 {
1953 q=GetCacheViewAuthenticPixels(mask_view,0,y,mask_image->columns,1,
anthony92c93bd2012-03-19 14:02:47 +00001954 _exception);
anthony805a2d42011-09-25 08:25:12 +00001955 if (q == (Quantum *) NULL)
1956 break;
1957 for (x=0; x < (ssize_t) mask_image->columns; x++)
1958 {
anthony7bcfe7f2012-03-30 14:01:22 +00001959 if (IfMagickFalse(mask_image->matte))
anthony805a2d42011-09-25 08:25:12 +00001960 SetPixelAlpha(mask_image,GetPixelIntensity(mask_image,q),q);
1961 SetPixelRed(mask_image,GetPixelAlpha(mask_image,q),q);
1962 SetPixelGreen(mask_image,GetPixelAlpha(mask_image,q),q);
1963 SetPixelBlue(mask_image,GetPixelAlpha(mask_image,q),q);
1964 q+=GetPixelChannels(mask_image);
1965 }
anthony7bcfe7f2012-03-30 14:01:22 +00001966 if (IfMagickFalse(SyncCacheViewAuthenticPixels(mask_view,_exception)))
anthony805a2d42011-09-25 08:25:12 +00001967 break;
1968 }
anthonyfd706f92012-01-19 04:22:02 +00001969 /* clean up and set the write mask */
anthony805a2d42011-09-25 08:25:12 +00001970 mask_view=DestroyCacheView(mask_view);
1971 mask_image->matte=MagickTrue;
anthony92c93bd2012-03-19 14:02:47 +00001972 (void) SetImageMask(_image,mask_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00001973 mask_image=DestroyImage(mask_image);
anthony805a2d42011-09-25 08:25:12 +00001974 break;
1975 }
anthonyafa3dfc2012-03-03 11:31:30 +00001976 if (LocaleCompare("clip-path",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001977 {
anthony92c93bd2012-03-19 14:02:47 +00001978 (void) ClipImagePath(_image,arg1,normal_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00001979 break;
1980 }
anthonyafa3dfc2012-03-03 11:31:30 +00001981 if (LocaleCompare("colorize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001982 {
anthony7bcfe7f2012-03-30 14:01:22 +00001983 if (IfMagickFalse(IsGeometry(arg1)))
anthony5330ae02012-03-20 14:17:01 +00001984 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001985 new_image=ColorizeImage(_image,arg1,&_draw_info->fill,_exception);
anthony805a2d42011-09-25 08:25:12 +00001986 break;
1987 }
anthonyafa3dfc2012-03-03 11:31:30 +00001988 if (LocaleCompare("color-matrix",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001989 {
1990 KernelInfo
1991 *kernel;
1992
anthonyfd706f92012-01-19 04:22:02 +00001993 kernel=AcquireKernelInfo(arg1);
anthony805a2d42011-09-25 08:25:12 +00001994 if (kernel == (KernelInfo *) NULL)
anthony5330ae02012-03-20 14:17:01 +00001995 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001996 new_image=ColorMatrixImage(_image,kernel,_exception);
anthony805a2d42011-09-25 08:25:12 +00001997 kernel=DestroyKernelInfo(kernel);
1998 break;
1999 }
anthonyafa3dfc2012-03-03 11:31:30 +00002000 if (LocaleCompare("colors",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002001 {
anthony5330ae02012-03-20 14:17:01 +00002002 /* Reduce the number of colors in the image.
2003 FUTURE: also provide 'plus version with image 'color counts'
anthonyfd706f92012-01-19 04:22:02 +00002004 */
anthony92c93bd2012-03-19 14:02:47 +00002005 _quantize_info->number_colors=StringToUnsignedLong(arg1);
2006 if (_quantize_info->number_colors == 0)
anthony5330ae02012-03-20 14:17:01 +00002007 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002008 if ((_image->storage_class == DirectClass) ||
2009 _image->colors > _quantize_info->number_colors)
2010 (void) QuantizeImage(_quantize_info,_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002011 else
anthony92c93bd2012-03-19 14:02:47 +00002012 (void) CompressImageColormap(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002013 break;
2014 }
anthonyafa3dfc2012-03-03 11:31:30 +00002015 if (LocaleCompare("colorspace",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002016 {
anthony5330ae02012-03-20 14:17:01 +00002017 /* WARNING: this is both a image_info setting (already done)
2018 and a operator to change image colorspace.
anthony31f1bf72012-01-30 12:37:22 +00002019
2020 FUTURE: default colorspace should be sRGB!
anthonyd2cdc862011-10-07 14:07:17 +00002021 Unless some type of 'linear colorspace' mode is set.
anthony31f1bf72012-01-30 12:37:22 +00002022
anthonyd2cdc862011-10-07 14:07:17 +00002023 Note that +colorspace sets "undefined" or no effect on
2024 new images, but forces images already in memory back to RGB!
anthony31f1bf72012-01-30 12:37:22 +00002025 That seems to be a little strange!
anthonyd2cdc862011-10-07 14:07:17 +00002026 */
anthony92c93bd2012-03-19 14:02:47 +00002027 (void) TransformImageColorspace(_image,
2028 IfNormalOp ? _image_info->colorspace : RGBColorspace,
2029 _exception);
anthony805a2d42011-09-25 08:25:12 +00002030 break;
2031 }
anthonyafa3dfc2012-03-03 11:31:30 +00002032 if (LocaleCompare("contrast",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002033 {
anthonydcf3a912012-03-22 14:33:17 +00002034 /* DEPRECIATED: The -/+level provides far more controlled form */
anthony92c93bd2012-03-19 14:02:47 +00002035 (void) ContrastImage(_image,normal_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00002036 break;
2037 }
anthonyafa3dfc2012-03-03 11:31:30 +00002038 if (LocaleCompare("contrast-stretch",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002039 {
2040 double
2041 black_point,
2042 white_point;
2043
2044 MagickStatusType
2045 flags;
2046
anthony7bcfe7f2012-03-30 14:01:22 +00002047 if (IfMagickFalse(IsGeometry(arg1)))
anthonyebb73a22012-03-22 14:25:52 +00002048 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00002049 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002050 black_point=geometry_info.rho;
2051 white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
2052 black_point;
anthonyebb73a22012-03-22 14:25:52 +00002053 if ((flags & PercentValue) != 0) {
anthony92c93bd2012-03-19 14:02:47 +00002054 black_point*=(double) _image->columns*_image->rows/100.0;
2055 white_point*=(double) _image->columns*_image->rows/100.0;
anthony805a2d42011-09-25 08:25:12 +00002056 }
anthony92c93bd2012-03-19 14:02:47 +00002057 white_point=(MagickRealType) _image->columns*_image->rows-
anthony805a2d42011-09-25 08:25:12 +00002058 white_point;
anthony92c93bd2012-03-19 14:02:47 +00002059 (void) ContrastStretchImage(_image,black_point,white_point,
2060 _exception);
anthony805a2d42011-09-25 08:25:12 +00002061 break;
2062 }
anthonyafa3dfc2012-03-03 11:31:30 +00002063 if (LocaleCompare("convolve",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002064 {
2065 KernelInfo
2066 *kernel_info;
2067
anthonyfd706f92012-01-19 04:22:02 +00002068 kernel_info=AcquireKernelInfo(arg1);
anthony805a2d42011-09-25 08:25:12 +00002069 if (kernel_info == (KernelInfo *) NULL)
anthonyebb73a22012-03-22 14:25:52 +00002070 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyf46d4262012-03-26 03:30:34 +00002071 /* kernel_info->bias=_image->bias; -- FUTURE: check this path! */
cristy38419ba2012-04-05 23:47:05 +00002072 ScaleKernelInfo(kernel_info,1.0,NormalizeValue); /* normalize */
anthony92c93bd2012-03-19 14:02:47 +00002073 new_image=ConvolveImage(_image,kernel_info,_exception);
anthony805a2d42011-09-25 08:25:12 +00002074 kernel_info=DestroyKernelInfo(kernel_info);
2075 break;
2076 }
anthonyafa3dfc2012-03-03 11:31:30 +00002077 if (LocaleCompare("crop",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002078 {
anthony31f1bf72012-01-30 12:37:22 +00002079 /* WARNING: This can generate multiple images! */
anthony7bcfe7f2012-03-30 14:01:22 +00002080 if (IfMagickFalse(IsGeometry(arg1)))
anthonyebb73a22012-03-22 14:25:52 +00002081 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002082 new_image=CropImageToTiles(_image,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00002083 break;
2084 }
anthonyafa3dfc2012-03-03 11:31:30 +00002085 if (LocaleCompare("cycle",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002086 {
anthony7bcfe7f2012-03-30 14:01:22 +00002087 if (IfMagickFalse(IsGeometry(arg1)))
anthonyebb73a22012-03-22 14:25:52 +00002088 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002089 (void) CycleColormapImage(_image,(ssize_t) StringToLong(arg1),
2090 _exception);
anthony805a2d42011-09-25 08:25:12 +00002091 break;
2092 }
anthonyebb73a22012-03-22 14:25:52 +00002093 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002094 }
2095 case 'd':
2096 {
anthonyafa3dfc2012-03-03 11:31:30 +00002097 if (LocaleCompare("decipher",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002098 {
2099 StringInfo
2100 *passkey;
2101
anthony92c93bd2012-03-19 14:02:47 +00002102 passkey=FileToStringInfo(arg1,~0,_exception);
anthonyebb73a22012-03-22 14:25:52 +00002103 if (passkey == (StringInfo *) NULL)
2104 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2105
2106 (void) PasskeyDecipherImage(_image,passkey,_exception);
2107 passkey=DestroyStringInfo(passkey);
anthony805a2d42011-09-25 08:25:12 +00002108 break;
2109 }
anthonyafa3dfc2012-03-03 11:31:30 +00002110 if (LocaleCompare("depth",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002111 {
anthony92c93bd2012-03-19 14:02:47 +00002112 /* The _image_info->depth setting has already been set
anthonydcf510d2011-10-30 13:51:40 +00002113 We just need to apply it to all images in current sequence
anthony31f1bf72012-01-30 12:37:22 +00002114
anthonydcf510d2011-10-30 13:51:40 +00002115 WARNING: Depth from 8 to 16 causes 'quantum rounding to images!
2116 That is it really is an operation, not a setting! Arrgghhh
anthony31f1bf72012-01-30 12:37:22 +00002117
anthonyfd706f92012-01-19 04:22:02 +00002118 FUTURE: this should not be an operator!!!
anthonydcf510d2011-10-30 13:51:40 +00002119 */
anthony92c93bd2012-03-19 14:02:47 +00002120 (void) SetImageDepth(_image,_image_info->depth,_exception);
anthony805a2d42011-09-25 08:25:12 +00002121 break;
2122 }
anthonyafa3dfc2012-03-03 11:31:30 +00002123 if (LocaleCompare("deskew",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002124 {
2125 double
2126 threshold;
2127
anthonyebb73a22012-03-22 14:25:52 +00002128 if (IfNormalOp) {
anthony7bcfe7f2012-03-30 14:01:22 +00002129 if (IfMagickFalse(IsGeometry(arg1)))
anthonyebb73a22012-03-22 14:25:52 +00002130 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00002131 threshold=StringToDoubleInterval(arg1,(double) QuantumRange+1.0);
anthonyebb73a22012-03-22 14:25:52 +00002132 }
anthonyafa3dfc2012-03-03 11:31:30 +00002133 else
2134 threshold=40.0*QuantumRange/100.0;
anthony92c93bd2012-03-19 14:02:47 +00002135 new_image=DeskewImage(_image,threshold,_exception);
anthony805a2d42011-09-25 08:25:12 +00002136 break;
2137 }
anthonyafa3dfc2012-03-03 11:31:30 +00002138 if (LocaleCompare("despeckle",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002139 {
anthony92c93bd2012-03-19 14:02:47 +00002140 new_image=DespeckleImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002141 break;
2142 }
anthonyafa3dfc2012-03-03 11:31:30 +00002143 if (LocaleCompare("distort",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002144 {
2145 char
2146 *args,
2147 token[MaxTextExtent];
2148
2149 const char
2150 *p;
2151
anthony805a2d42011-09-25 08:25:12 +00002152 double
2153 *arguments;
2154
2155 register ssize_t
2156 x;
2157
2158 size_t
2159 number_arguments;
2160
anthony2a0ec8c2012-03-24 04:35:56 +00002161 parse = ParseCommandOption(MagickDistortOptions,MagickFalse,arg1);
2162 if ( parse < 0 )
anthonyebb73a22012-03-22 14:25:52 +00002163 CLIWandExceptArgBreak(OptionError,"UnrecognizedDistortMethod",
2164 option,arg1);
anthony2a0ec8c2012-03-24 04:35:56 +00002165 if ((DistortImageMethod) parse == ResizeDistortion)
anthony805a2d42011-09-25 08:25:12 +00002166 {
anthony80c37752012-01-16 01:03:11 +00002167 double
2168 resize_args[2];
anthony805a2d42011-09-25 08:25:12 +00002169 /* Special Case - Argument is actually a resize geometry!
2170 ** Convert that to an appropriate distortion argument array.
anthonyfd706f92012-01-19 04:22:02 +00002171 ** FUTURE: make a separate special resize operator
anthonyfe1aa782012-03-24 13:43:04 +00002172 Roll into a resize special operator */
anthony7bcfe7f2012-03-30 14:01:22 +00002173 if (IfMagickFalse(IsGeometry(arg2)))
anthonyebb73a22012-03-22 14:25:52 +00002174 CLIWandExceptArgBreak(OptionError,"InvalidGeometry",
2175 option,arg2);
2176 (void) ParseRegionGeometry(_image,arg2,&geometry,_exception);
anthony80c37752012-01-16 01:03:11 +00002177 resize_args[0]=(double) geometry.width;
2178 resize_args[1]=(double) geometry.height;
anthony2a0ec8c2012-03-24 04:35:56 +00002179 new_image=DistortImage(_image,(DistortImageMethod) parse,
2180 (size_t)2,resize_args,MagickTrue,_exception);
anthony805a2d42011-09-25 08:25:12 +00002181 break;
2182 }
anthonyfd706f92012-01-19 04:22:02 +00002183 /* handle percent arguments */
anthonyebb73a22012-03-22 14:25:52 +00002184 args=InterpretImageProperties(_image_info,_image,arg2,_exception);
anthony805a2d42011-09-25 08:25:12 +00002185 if (args == (char *) NULL)
2186 break;
anthonyfd706f92012-01-19 04:22:02 +00002187 /* convert arguments into an array of doubles
2188 FUTURE: make this a separate function.
2189 Also make use of new 'sentinal' feature to avoid need for
2190 tokenization.
2191 */
anthony805a2d42011-09-25 08:25:12 +00002192 p=(char *) args;
2193 for (x=0; *p != '\0'; x++)
2194 {
2195 GetMagickToken(p,&p,token);
2196 if (*token == ',')
2197 GetMagickToken(p,&p,token);
2198 }
2199 number_arguments=(size_t) x;
2200 arguments=(double *) AcquireQuantumMemory(number_arguments,
2201 sizeof(*arguments));
2202 if (arguments == (double *) NULL)
anthonyebb73a22012-03-22 14:25:52 +00002203 CLIWandExceptionBreak(ResourceLimitFatalError,
2204 "MemoryAllocationFailed",option);
anthony805a2d42011-09-25 08:25:12 +00002205 (void) ResetMagickMemory(arguments,0,number_arguments*
anthonyebb73a22012-03-22 14:25:52 +00002206 sizeof(*arguments));
anthony805a2d42011-09-25 08:25:12 +00002207 p=(char *) args;
2208 for (x=0; (x < (ssize_t) number_arguments) && (*p != '\0'); x++)
2209 {
2210 GetMagickToken(p,&p,token);
2211 if (*token == ',')
2212 GetMagickToken(p,&p,token);
cristydbdd0e32011-11-04 23:29:40 +00002213 arguments[x]=StringToDouble(token,(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +00002214 }
2215 args=DestroyString(args);
anthony2a0ec8c2012-03-24 04:35:56 +00002216 new_image=DistortImage(_image,(DistortImageMethod) parse,
2217 number_arguments,arguments,plus_alt_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00002218 arguments=(double *) RelinquishMagickMemory(arguments);
2219 break;
2220 }
anthonyafa3dfc2012-03-03 11:31:30 +00002221 if (LocaleCompare("draw",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002222 {
anthony92c93bd2012-03-19 14:02:47 +00002223 (void) CloneString(&_draw_info->primitive,arg1);
2224 (void) DrawImage(_image,_draw_info,_exception);
2225 (void) CloneString(&_draw_info->primitive,(char *)NULL);
anthony805a2d42011-09-25 08:25:12 +00002226 break;
2227 }
anthonyebb73a22012-03-22 14:25:52 +00002228 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002229 }
2230 case 'e':
2231 {
anthonyafa3dfc2012-03-03 11:31:30 +00002232 if (LocaleCompare("edge",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002233 {
anthony7bcfe7f2012-03-30 14:01:22 +00002234 if (IfMagickFalse(IsGeometry(arg1)))
anthony2a0ec8c2012-03-24 04:35:56 +00002235 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00002236 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002237 if ((flags & SigmaValue) == 0)
2238 geometry_info.sigma=1.0;
anthony2a0ec8c2012-03-24 04:35:56 +00002239 new_image=EdgeImage(_image,geometry_info.rho,geometry_info.sigma,
2240 _exception);
anthony805a2d42011-09-25 08:25:12 +00002241 break;
2242 }
anthonyafa3dfc2012-03-03 11:31:30 +00002243 if (LocaleCompare("emboss",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002244 {
anthony7bcfe7f2012-03-30 14:01:22 +00002245 if (IfMagickFalse(IsGeometry(arg1)))
anthony2a0ec8c2012-03-24 04:35:56 +00002246 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00002247 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002248 if ((flags & SigmaValue) == 0)
2249 geometry_info.sigma=1.0;
anthony92c93bd2012-03-19 14:02:47 +00002250 new_image=EmbossImage(_image,geometry_info.rho,
2251 geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00002252 break;
2253 }
anthonyafa3dfc2012-03-03 11:31:30 +00002254 if (LocaleCompare("encipher",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002255 {
2256 StringInfo
2257 *passkey;
2258
anthony92c93bd2012-03-19 14:02:47 +00002259 passkey=FileToStringInfo(arg1,~0,_exception);
anthony805a2d42011-09-25 08:25:12 +00002260 if (passkey != (StringInfo *) NULL)
2261 {
anthony92c93bd2012-03-19 14:02:47 +00002262 (void) PasskeyEncipherImage(_image,passkey,_exception);
anthony805a2d42011-09-25 08:25:12 +00002263 passkey=DestroyStringInfo(passkey);
2264 }
2265 break;
2266 }
anthonyafa3dfc2012-03-03 11:31:30 +00002267 if (LocaleCompare("enhance",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002268 {
anthony92c93bd2012-03-19 14:02:47 +00002269 new_image=EnhanceImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002270 break;
2271 }
anthonyafa3dfc2012-03-03 11:31:30 +00002272 if (LocaleCompare("equalize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002273 {
anthony92c93bd2012-03-19 14:02:47 +00002274 (void) EqualizeImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002275 break;
2276 }
anthonyafa3dfc2012-03-03 11:31:30 +00002277 if (LocaleCompare("evaluate",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002278 {
2279 double
2280 constant;
2281
anthony2a0ec8c2012-03-24 04:35:56 +00002282 parse = ParseCommandOption(MagickEvaluateOptions,MagickFalse,arg1);
2283 if ( parse < 0 )
2284 CLIWandExceptArgBreak(OptionError,"UnrecognizedEvaluateOperator",
2285 option,arg1);
anthony7bcfe7f2012-03-30 14:01:22 +00002286 if (IfMagickFalse(IsGeometry(arg2)))
anthony2a0ec8c2012-03-24 04:35:56 +00002287 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
anthonyfd706f92012-01-19 04:22:02 +00002288 constant=StringToDoubleInterval(arg2,(double) QuantumRange+1.0);
anthony2a0ec8c2012-03-24 04:35:56 +00002289 (void) EvaluateImage(_image,(MagickEvaluateOperator)parse,constant,
2290 _exception);
anthony805a2d42011-09-25 08:25:12 +00002291 break;
2292 }
anthonyafa3dfc2012-03-03 11:31:30 +00002293 if (LocaleCompare("extent",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002294 {
anthony7bcfe7f2012-03-30 14:01:22 +00002295 if (IfMagickFalse(IsGeometry(arg1)))
anthony2a0ec8c2012-03-24 04:35:56 +00002296 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002297 flags=ParseGravityGeometry(_image,arg1,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00002298 if (geometry.width == 0)
anthony92c93bd2012-03-19 14:02:47 +00002299 geometry.width=_image->columns;
anthony805a2d42011-09-25 08:25:12 +00002300 if (geometry.height == 0)
anthony92c93bd2012-03-19 14:02:47 +00002301 geometry.height=_image->rows;
2302 new_image=ExtentImage(_image,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00002303 break;
2304 }
anthonyebb73a22012-03-22 14:25:52 +00002305 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002306 }
2307 case 'f':
2308 {
anthonyafa3dfc2012-03-03 11:31:30 +00002309 if (LocaleCompare("features",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002310 {
anthony31f1bf72012-01-30 12:37:22 +00002311 /* FUTURE: move to SyncImageSettings() and AcqireImage()??? */
anthonyafa3dfc2012-03-03 11:31:30 +00002312 if (IfPlusOp) {
anthony92c93bd2012-03-19 14:02:47 +00002313 (void) DeleteImageArtifact(_image,"identify:features");
anthony31f1bf72012-01-30 12:37:22 +00002314 break;
2315 }
anthony92c93bd2012-03-19 14:02:47 +00002316 (void) SetImageArtifact(_image,"identify:features","true");
2317 (void) SetImageArtifact(_image,"verbose","true");
anthony805a2d42011-09-25 08:25:12 +00002318 break;
2319 }
anthonyafa3dfc2012-03-03 11:31:30 +00002320 if (LocaleCompare("flip",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002321 {
anthony92c93bd2012-03-19 14:02:47 +00002322 new_image=FlipImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002323 break;
2324 }
anthonyafa3dfc2012-03-03 11:31:30 +00002325 if (LocaleCompare("flop",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002326 {
anthony92c93bd2012-03-19 14:02:47 +00002327 new_image=FlopImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002328 break;
2329 }
anthonyafa3dfc2012-03-03 11:31:30 +00002330 if (LocaleCompare("floodfill",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002331 {
2332 PixelInfo
2333 target;
2334
anthony7bcfe7f2012-03-30 14:01:22 +00002335 if (IfMagickFalse(IsGeometry(arg1)))
anthony2a0ec8c2012-03-24 04:35:56 +00002336 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002337 (void) ParsePageGeometry(_image,arg1,&geometry,_exception);
2338 (void) QueryColorCompliance(arg2,AllCompliance,&target,_exception);
2339 (void) FloodfillPaintImage(_image,_draw_info,&target,geometry.x,
2340 geometry.y,plus_alt_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00002341 break;
2342 }
anthonyafa3dfc2012-03-03 11:31:30 +00002343 if (LocaleCompare("frame",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002344 {
2345 FrameInfo
2346 frame_info;
2347
anthony31f1bf72012-01-30 12:37:22 +00002348 CompositeOperator
anthonyfd706f92012-01-19 04:22:02 +00002349 compose;
2350
2351 const char*
2352 value;
2353
anthony92c93bd2012-03-19 14:02:47 +00002354 value=GetImageOption(_image_info,"compose");
anthonyfd706f92012-01-19 04:22:02 +00002355 if (value != (const char *) NULL)
2356 compose=(CompositeOperator) ParseCommandOption(
2357 MagickComposeOptions,MagickFalse,value);
2358 else
anthony92c93bd2012-03-19 14:02:47 +00002359 compose=OverCompositeOp; /* use Over not _image->compose */
anthonyfd706f92012-01-19 04:22:02 +00002360
anthony7bcfe7f2012-03-30 14:01:22 +00002361 if (IfMagickFalse(IsGeometry(arg1)))
anthony2a0ec8c2012-03-24 04:35:56 +00002362 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002363 flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00002364 frame_info.width=geometry.width;
2365 frame_info.height=geometry.height;
2366 if ((flags & HeightValue) == 0)
2367 frame_info.height=geometry.width;
2368 frame_info.outer_bevel=geometry.x;
2369 frame_info.inner_bevel=geometry.y;
2370 frame_info.x=(ssize_t) frame_info.width;
2371 frame_info.y=(ssize_t) frame_info.height;
anthony92c93bd2012-03-19 14:02:47 +00002372 frame_info.width=_image->columns+2*frame_info.width;
2373 frame_info.height=_image->rows+2*frame_info.height;
2374 new_image=FrameImage(_image,&frame_info,compose,_exception);
anthony805a2d42011-09-25 08:25:12 +00002375 break;
2376 }
anthonyafa3dfc2012-03-03 11:31:30 +00002377 if (LocaleCompare("function",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002378 {
2379 char
2380 *arguments,
2381 token[MaxTextExtent];
2382
2383 const char
2384 *p;
2385
2386 double
2387 *parameters;
2388
anthony805a2d42011-09-25 08:25:12 +00002389 register ssize_t
2390 x;
2391
2392 size_t
2393 number_parameters;
2394
cristy947cb4c2011-10-20 18:41:46 +00002395 /*
2396 Function Modify Image Values
anthonyfd706f92012-01-19 04:22:02 +00002397 FUTURE: code should be almost a duplicate of that is "distort"
cristy947cb4c2011-10-20 18:41:46 +00002398 */
anthony2a0ec8c2012-03-24 04:35:56 +00002399 parse=ParseCommandOption(MagickFunctionOptions,MagickFalse,arg1);
2400 if ( parse < 0 )
2401 CLIWandExceptArgBreak(OptionError,"UnrecognizedFunction",
2402 option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002403 arguments=InterpretImageProperties(_image_info,_image,arg2,
2404 _exception);
anthony805a2d42011-09-25 08:25:12 +00002405 if (arguments == (char *) NULL)
anthony2a0ec8c2012-03-24 04:35:56 +00002406 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
anthony805a2d42011-09-25 08:25:12 +00002407 p=(char *) arguments;
2408 for (x=0; *p != '\0'; x++)
2409 {
2410 GetMagickToken(p,&p,token);
2411 if (*token == ',')
2412 GetMagickToken(p,&p,token);
2413 }
2414 number_parameters=(size_t) x;
2415 parameters=(double *) AcquireQuantumMemory(number_parameters,
2416 sizeof(*parameters));
2417 if (parameters == (double *) NULL)
2418 ThrowWandFatalException(ResourceLimitFatalError,
anthony92c93bd2012-03-19 14:02:47 +00002419 "MemoryAllocationFailed",_image->filename);
anthony805a2d42011-09-25 08:25:12 +00002420 (void) ResetMagickMemory(parameters,0,number_parameters*
2421 sizeof(*parameters));
2422 p=(char *) arguments;
anthony2a0ec8c2012-03-24 04:35:56 +00002423 for (x=0; (x < (ssize_t) number_parameters) && (*p != '\0'); x++) {
anthony805a2d42011-09-25 08:25:12 +00002424 GetMagickToken(p,&p,token);
2425 if (*token == ',')
2426 GetMagickToken(p,&p,token);
cristydbdd0e32011-11-04 23:29:40 +00002427 parameters[x]=StringToDouble(token,(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +00002428 }
2429 arguments=DestroyString(arguments);
anthony2a0ec8c2012-03-24 04:35:56 +00002430 (void) FunctionImage(_image,(MagickFunction)parse,number_parameters,
2431 parameters,_exception);
anthony805a2d42011-09-25 08:25:12 +00002432 parameters=(double *) RelinquishMagickMemory(parameters);
2433 break;
2434 }
anthonyebb73a22012-03-22 14:25:52 +00002435 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002436 }
2437 case 'g':
2438 {
anthonyafa3dfc2012-03-03 11:31:30 +00002439 if (LocaleCompare("gamma",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002440 {
anthony7bcfe7f2012-03-30 14:01:22 +00002441 if (IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00002442 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyafa3dfc2012-03-03 11:31:30 +00002443 if (IfNormalOp)
anthony92c93bd2012-03-19 14:02:47 +00002444 (void) GammaImage(_image,StringToDouble(arg1,(char **) NULL),
2445 _exception);
anthonyafa3dfc2012-03-03 11:31:30 +00002446 else
anthony92c93bd2012-03-19 14:02:47 +00002447 _image->gamma=StringToDouble(arg1,(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +00002448 break;
2449 }
anthonyafa3dfc2012-03-03 11:31:30 +00002450 if ((LocaleCompare("gaussian-blur",option+1) == 0) ||
2451 (LocaleCompare("gaussian",option+1) == 0))
anthony805a2d42011-09-25 08:25:12 +00002452 {
anthony7bcfe7f2012-03-30 14:01:22 +00002453 if (IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00002454 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00002455 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002456 if ((flags & SigmaValue) == 0)
2457 geometry_info.sigma=1.0;
anthony92c93bd2012-03-19 14:02:47 +00002458 new_image=GaussianBlurImage(_image,geometry_info.rho,
2459 geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00002460 break;
2461 }
anthonyafa3dfc2012-03-03 11:31:30 +00002462 if (LocaleCompare("geometry",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002463 {
anthonyfd706f92012-01-19 04:22:02 +00002464 /*
anthony31f1bf72012-01-30 12:37:22 +00002465 Record Image offset for composition. (A Setting)
anthonyfe1aa782012-03-24 13:43:04 +00002466 Resize last _image. (ListOperator) -- DEPRECIATE
anthony31f1bf72012-01-30 12:37:22 +00002467 FUTURE: Why if no 'offset' does this resize ALL images?
2468 Also why is the setting recorded in the IMAGE non-sense!
anthonyfd706f92012-01-19 04:22:02 +00002469 */
anthonyafa3dfc2012-03-03 11:31:30 +00002470 if (IfPlusOp)
anthonyfd706f92012-01-19 04:22:02 +00002471 { /* remove the previous composition geometry offset! */
anthony92c93bd2012-03-19 14:02:47 +00002472 if (_image->geometry != (char *) NULL)
2473 _image->geometry=DestroyString(_image->geometry);
anthony805a2d42011-09-25 08:25:12 +00002474 break;
2475 }
anthony7bcfe7f2012-03-30 14:01:22 +00002476 if (IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00002477 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002478 flags=ParseRegionGeometry(_image,arg1,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00002479 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
anthony92c93bd2012-03-19 14:02:47 +00002480 (void) CloneString(&_image->geometry,arg1);
anthony805a2d42011-09-25 08:25:12 +00002481 else
anthony92c93bd2012-03-19 14:02:47 +00002482 new_image=ResizeImage(_image,geometry.width,geometry.height,
cristyaa2c16c2012-03-25 22:21:35 +00002483 _image->filter,_exception);
anthony805a2d42011-09-25 08:25:12 +00002484 break;
2485 }
anthonyebb73a22012-03-22 14:25:52 +00002486 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002487 }
2488 case 'h':
2489 {
anthonyafa3dfc2012-03-03 11:31:30 +00002490 if (LocaleCompare("highlight-color",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002491 {
anthony92c93bd2012-03-19 14:02:47 +00002492 (void) SetImageArtifact(_image,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +00002493 break;
2494 }
anthonyebb73a22012-03-22 14:25:52 +00002495 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002496 }
2497 case 'i':
2498 {
anthonyafa3dfc2012-03-03 11:31:30 +00002499 if (LocaleCompare("identify",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002500 {
anthony31f1bf72012-01-30 12:37:22 +00002501 const char
2502 *format,
anthony805a2d42011-09-25 08:25:12 +00002503 *text;
2504
anthony92c93bd2012-03-19 14:02:47 +00002505 format=GetImageOption(_image_info,"format");
anthony805a2d42011-09-25 08:25:12 +00002506 if (format == (char *) NULL)
2507 {
anthony92c93bd2012-03-19 14:02:47 +00002508 (void) IdentifyImage(_image,stdout,_image_info->verbose,
2509 _exception);
anthony805a2d42011-09-25 08:25:12 +00002510 break;
2511 }
anthony92c93bd2012-03-19 14:02:47 +00002512 text=InterpretImageProperties(_image_info,_image,format,_exception);
anthony805a2d42011-09-25 08:25:12 +00002513 if (text == (char *) NULL)
2514 break;
2515 (void) fputs(text,stdout);
2516 (void) fputc('\n',stdout);
anthony31f1bf72012-01-30 12:37:22 +00002517 text=DestroyString((char *)text);
anthony805a2d42011-09-25 08:25:12 +00002518 break;
2519 }
anthonyafa3dfc2012-03-03 11:31:30 +00002520 if (LocaleCompare("implode",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002521 {
anthony7bcfe7f2012-03-30 14:01:22 +00002522 if (IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00002523 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00002524 (void) ParseGeometry(arg1,&geometry_info);
anthony92c93bd2012-03-19 14:02:47 +00002525 new_image=ImplodeImage(_image,geometry_info.rho,
2526 _image->interpolate,_exception);
anthony805a2d42011-09-25 08:25:12 +00002527 break;
2528 }
anthonyafa3dfc2012-03-03 11:31:30 +00002529 if (LocaleCompare("interpolative-resize",option+1) == 0)
cristy947cb4c2011-10-20 18:41:46 +00002530 {
anthonyfe1aa782012-03-24 13:43:04 +00002531 /* FUTURE: New to IMv7
2532 Roll into a resize special operator */
anthony7bcfe7f2012-03-30 14:01:22 +00002533 if (IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00002534 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002535 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
2536 new_image=InterpolativeResizeImage(_image,geometry.width,
2537 geometry.height,_image->interpolate,_exception);
cristy947cb4c2011-10-20 18:41:46 +00002538 break;
2539 }
anthonyebb73a22012-03-22 14:25:52 +00002540 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002541 }
2542 case 'l':
2543 {
anthonyafa3dfc2012-03-03 11:31:30 +00002544 if (LocaleCompare("lat",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002545 {
anthony7bcfe7f2012-03-30 14:01:22 +00002546 if (IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00002547 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00002548 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002549 if ((flags & PercentValue) != 0)
2550 geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
anthony92c93bd2012-03-19 14:02:47 +00002551 new_image=AdaptiveThresholdImage(_image,(size_t) geometry_info.rho,
anthony31f1bf72012-01-30 12:37:22 +00002552 (size_t) geometry_info.sigma,(double) geometry_info.xi,
anthony92c93bd2012-03-19 14:02:47 +00002553 _exception);
anthony805a2d42011-09-25 08:25:12 +00002554 break;
2555 }
anthonyafa3dfc2012-03-03 11:31:30 +00002556 if (LocaleCompare("level",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002557 {
2558 MagickRealType
2559 black_point,
2560 gamma,
2561 white_point;
2562
2563 MagickStatusType
2564 flags;
2565
anthony7bcfe7f2012-03-30 14:01:22 +00002566 if (IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00002567 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00002568 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002569 black_point=geometry_info.rho;
2570 white_point=(MagickRealType) QuantumRange;
2571 if ((flags & SigmaValue) != 0)
2572 white_point=geometry_info.sigma;
2573 gamma=1.0;
2574 if ((flags & XiValue) != 0)
2575 gamma=geometry_info.xi;
2576 if ((flags & PercentValue) != 0)
2577 {
2578 black_point*=(MagickRealType) (QuantumRange/100.0);
2579 white_point*=(MagickRealType) (QuantumRange/100.0);
2580 }
2581 if ((flags & SigmaValue) == 0)
2582 white_point=(MagickRealType) QuantumRange-black_point;
anthonyafa3dfc2012-03-03 11:31:30 +00002583 if (IfPlusOp || ((flags & AspectValue) != 0))
anthony92c93bd2012-03-19 14:02:47 +00002584 (void) LevelizeImage(_image,black_point,white_point,gamma,_exception);
anthony805a2d42011-09-25 08:25:12 +00002585 else
anthony92c93bd2012-03-19 14:02:47 +00002586 (void) LevelImage(_image,black_point,white_point,gamma,_exception);
anthony805a2d42011-09-25 08:25:12 +00002587 break;
2588 }
anthonyafa3dfc2012-03-03 11:31:30 +00002589 if (LocaleCompare("level-colors",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002590 {
2591 char
2592 token[MaxTextExtent];
2593
2594 const char
2595 *p;
2596
2597 PixelInfo
2598 black_point,
2599 white_point;
2600
anthonyfd706f92012-01-19 04:22:02 +00002601 p=(const char *) arg1;
anthony805a2d42011-09-25 08:25:12 +00002602 GetMagickToken(p,&p,token); /* get black point color */
2603 if ((isalpha((int) *token) != 0) || ((*token == '#') != 0))
cristy269c9412011-10-13 23:41:15 +00002604 (void) QueryColorCompliance(token,AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +00002605 &black_point,_exception);
anthony805a2d42011-09-25 08:25:12 +00002606 else
cristy269c9412011-10-13 23:41:15 +00002607 (void) QueryColorCompliance("#000000",AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +00002608 &black_point,_exception);
anthony805a2d42011-09-25 08:25:12 +00002609 if (isalpha((int) token[0]) || (token[0] == '#'))
2610 GetMagickToken(p,&p,token);
2611 if (*token == '\0')
2612 white_point=black_point; /* set everything to that color */
2613 else
2614 {
2615 if ((isalpha((int) *token) == 0) && ((*token == '#') == 0))
2616 GetMagickToken(p,&p,token); /* Get white point color. */
2617 if ((isalpha((int) *token) != 0) || ((*token == '#') != 0))
cristy269c9412011-10-13 23:41:15 +00002618 (void) QueryColorCompliance(token,AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +00002619 &white_point,_exception);
anthony805a2d42011-09-25 08:25:12 +00002620 else
cristy269c9412011-10-13 23:41:15 +00002621 (void) QueryColorCompliance("#ffffff",AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +00002622 &white_point,_exception);
anthony805a2d42011-09-25 08:25:12 +00002623 }
anthony92c93bd2012-03-19 14:02:47 +00002624 (void) LevelImageColors(_image,&black_point,&white_point,
2625 plus_alt_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00002626 break;
2627 }
anthonyafa3dfc2012-03-03 11:31:30 +00002628 if (LocaleCompare("linear-stretch",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002629 {
2630 double
2631 black_point,
2632 white_point;
2633
2634 MagickStatusType
2635 flags;
2636
anthony7bcfe7f2012-03-30 14:01:22 +00002637 if (IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00002638 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00002639 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002640 black_point=geometry_info.rho;
anthony92c93bd2012-03-19 14:02:47 +00002641 white_point=(MagickRealType) _image->columns*_image->rows;
anthony805a2d42011-09-25 08:25:12 +00002642 if ((flags & SigmaValue) != 0)
2643 white_point=geometry_info.sigma;
2644 if ((flags & PercentValue) != 0)
2645 {
anthony92c93bd2012-03-19 14:02:47 +00002646 black_point*=(double) _image->columns*_image->rows/100.0;
2647 white_point*=(double) _image->columns*_image->rows/100.0;
anthony805a2d42011-09-25 08:25:12 +00002648 }
2649 if ((flags & SigmaValue) == 0)
anthony92c93bd2012-03-19 14:02:47 +00002650 white_point=(MagickRealType) _image->columns*_image->rows-
anthony805a2d42011-09-25 08:25:12 +00002651 black_point;
anthony92c93bd2012-03-19 14:02:47 +00002652 (void) LinearStretchImage(_image,black_point,white_point,_exception);
anthony805a2d42011-09-25 08:25:12 +00002653 break;
2654 }
anthonyafa3dfc2012-03-03 11:31:30 +00002655 if (LocaleCompare("liquid-rescale",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002656 {
anthonyfe1aa782012-03-24 13:43:04 +00002657 /* FUTURE: Roll into a resize special operator */
anthony7bcfe7f2012-03-30 14:01:22 +00002658 if (IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00002659 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002660 flags=ParseRegionGeometry(_image,arg1,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00002661 if ((flags & XValue) == 0)
2662 geometry.x=1;
2663 if ((flags & YValue) == 0)
2664 geometry.y=0;
anthony92c93bd2012-03-19 14:02:47 +00002665 new_image=LiquidRescaleImage(_image,geometry.width,
2666 geometry.height,1.0*geometry.x,1.0*geometry.y,_exception);
anthony805a2d42011-09-25 08:25:12 +00002667 break;
2668 }
anthonyafa3dfc2012-03-03 11:31:30 +00002669 if (LocaleCompare("lowlight-color",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002670 {
anthony92c93bd2012-03-19 14:02:47 +00002671 (void) SetImageArtifact(_image,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +00002672 break;
2673 }
anthonyebb73a22012-03-22 14:25:52 +00002674 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002675 }
2676 case 'm':
2677 {
anthonyafa3dfc2012-03-03 11:31:30 +00002678 if (LocaleCompare("map",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002679 {
2680 Image
2681 *remap_image;
2682
anthony31f1bf72012-01-30 12:37:22 +00002683 /* DEPRECIATED use -remap */
anthony92c93bd2012-03-19 14:02:47 +00002684 remap_image=GetImageCache(_image_info,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00002685 if (remap_image == (Image *) NULL)
2686 break;
anthony92c93bd2012-03-19 14:02:47 +00002687 (void) RemapImage(_quantize_info,_image,remap_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002688 remap_image=DestroyImage(remap_image);
2689 break;
2690 }
anthonyafa3dfc2012-03-03 11:31:30 +00002691 if (LocaleCompare("mask",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002692 {
2693 Image
2694 *mask;
2695
anthonyafa3dfc2012-03-03 11:31:30 +00002696 if (IfPlusOp)
anthony31f1bf72012-01-30 12:37:22 +00002697 { /* Remove a mask. */
anthony92c93bd2012-03-19 14:02:47 +00002698 (void) SetImageMask(_image,(Image *) NULL,_exception);
anthony805a2d42011-09-25 08:25:12 +00002699 break;
2700 }
anthony5330ae02012-03-20 14:17:01 +00002701 /* Set the image mask. */
anthony92c93bd2012-03-19 14:02:47 +00002702 mask=GetImageCache(_image_info,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00002703 if (mask == (Image *) NULL)
2704 break;
anthony92c93bd2012-03-19 14:02:47 +00002705 (void) SetImageMask(_image,mask,_exception);
anthony805a2d42011-09-25 08:25:12 +00002706 mask=DestroyImage(mask);
2707 break;
2708 }
anthonyafa3dfc2012-03-03 11:31:30 +00002709 if (LocaleCompare("matte",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002710 {
anthony31f1bf72012-01-30 12:37:22 +00002711 /* DEPRECIATED */
anthony92c93bd2012-03-19 14:02:47 +00002712 (void) SetImageAlphaChannel(_image,IfNormalOp ? SetAlphaChannel :
2713 DeactivateAlphaChannel, _exception);
anthony805a2d42011-09-25 08:25:12 +00002714 break;
2715 }
anthonya3ef4ed2012-03-17 06:52:53 +00002716 if (LocaleCompare("median",option+1) == 0)
2717 {
2718 /* DEPRECIATED - use -statistic Median */
anthony7bcfe7f2012-03-30 14:01:22 +00002719 if (IfMagickFalse(IsGeometry(arg1)))
anthony7bc87992012-03-25 02:32:51 +00002720 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonya3ef4ed2012-03-17 06:52:53 +00002721 CLISimpleOperatorImage(cli_wand,"-statistic","Median",arg1);
2722 break;
2723 }
anthonyafa3dfc2012-03-03 11:31:30 +00002724 if (LocaleCompare("mode",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002725 {
anthony7bcfe7f2012-03-30 14:01:22 +00002726 if (IfMagickFalse(IsGeometry(arg1)))
anthony7bc87992012-03-25 02:32:51 +00002727 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00002728 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002729 if ((flags & SigmaValue) == 0)
2730 geometry_info.sigma=geometry_info.rho;
anthony92c93bd2012-03-19 14:02:47 +00002731 new_image=StatisticImage(_image,ModeStatistic,(size_t)
2732 geometry_info.rho,(size_t) geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00002733 break;
2734 }
anthonyafa3dfc2012-03-03 11:31:30 +00002735 if (LocaleCompare("modulate",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002736 {
anthony7bcfe7f2012-03-30 14:01:22 +00002737 if (IfMagickFalse(IsGeometry(arg1)))
anthony7bc87992012-03-25 02:32:51 +00002738 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002739 (void) ModulateImage(_image,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00002740 break;
2741 }
anthonyafa3dfc2012-03-03 11:31:30 +00002742 if (LocaleCompare("monitor",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002743 {
anthony92c93bd2012-03-19 14:02:47 +00002744 (void) SetImageProgressMonitor(_image, IfNormalOp ? MonitorProgress :
anthonyafa3dfc2012-03-03 11:31:30 +00002745 (MagickProgressMonitor) NULL,(void *) NULL);
anthony805a2d42011-09-25 08:25:12 +00002746 break;
2747 }
anthonyafa3dfc2012-03-03 11:31:30 +00002748 if (LocaleCompare("monochrome",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002749 {
anthony92c93bd2012-03-19 14:02:47 +00002750 (void) SetImageType(_image,BilevelType,_exception);
anthony805a2d42011-09-25 08:25:12 +00002751 break;
2752 }
anthonyafa3dfc2012-03-03 11:31:30 +00002753 if (LocaleCompare("morphology",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002754 {
2755 char
2756 token[MaxTextExtent];
2757
2758 const char
2759 *p;
2760
2761 KernelInfo
2762 *kernel;
2763
anthony805a2d42011-09-25 08:25:12 +00002764 ssize_t
2765 iterations;
2766
anthonyfd706f92012-01-19 04:22:02 +00002767 p=arg1;
anthony805a2d42011-09-25 08:25:12 +00002768 GetMagickToken(p,&p,token);
anthony7bc87992012-03-25 02:32:51 +00002769 parse=ParseCommandOption(MagickMorphologyOptions,MagickFalse,token);
2770 if ( parse < 0 )
2771 CLIWandExceptArgBreak(OptionError,"UnrecognizedFunction",
2772 option,arg1);
anthony805a2d42011-09-25 08:25:12 +00002773 iterations=1L;
2774 GetMagickToken(p,&p,token);
2775 if ((*p == ':') || (*p == ','))
2776 GetMagickToken(p,&p,token);
2777 if ((*p != '\0'))
2778 iterations=(ssize_t) StringToLong(p);
anthonyfd706f92012-01-19 04:22:02 +00002779 kernel=AcquireKernelInfo(arg2);
anthony805a2d42011-09-25 08:25:12 +00002780 if (kernel == (KernelInfo *) NULL)
anthony7bc87992012-03-25 02:32:51 +00002781 CLIWandExceptArgBreak(OptionError,"UnabletoParseKernel",
2782 option,arg2);
2783 new_image=MorphologyImage(_image,(MorphologyMethod)parse,
2784 iterations,kernel,_exception);
anthony805a2d42011-09-25 08:25:12 +00002785 kernel=DestroyKernelInfo(kernel);
2786 break;
2787 }
anthonyafa3dfc2012-03-03 11:31:30 +00002788 if (LocaleCompare("motion-blur",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002789 {
anthony7bcfe7f2012-03-30 14:01:22 +00002790 if (IfMagickFalse(IsGeometry(arg1)))
anthony7bc87992012-03-25 02:32:51 +00002791 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00002792 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002793 if ((flags & SigmaValue) == 0)
2794 geometry_info.sigma=1.0;
anthony92c93bd2012-03-19 14:02:47 +00002795 new_image=MotionBlurImage(_image,geometry_info.rho,
cristyaa2c16c2012-03-25 22:21:35 +00002796 geometry_info.sigma,geometry_info.xi,_exception);
anthony805a2d42011-09-25 08:25:12 +00002797 break;
2798 }
anthonyebb73a22012-03-22 14:25:52 +00002799 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002800 }
2801 case 'n':
2802 {
anthonyafa3dfc2012-03-03 11:31:30 +00002803 if (LocaleCompare("negate",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002804 {
anthony92c93bd2012-03-19 14:02:47 +00002805 (void) NegateImage(_image, plus_alt_op, _exception);
anthony805a2d42011-09-25 08:25:12 +00002806 break;
2807 }
anthonyafa3dfc2012-03-03 11:31:30 +00002808 if (LocaleCompare("noise",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002809 {
anthonyafa3dfc2012-03-03 11:31:30 +00002810 if (IfNormalOp)
anthony805a2d42011-09-25 08:25:12 +00002811 {
anthony7bcfe7f2012-03-30 14:01:22 +00002812 if (IfMagickFalse(IsGeometry(arg1)))
anthony7bc87992012-03-25 02:32:51 +00002813 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00002814 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002815 if ((flags & SigmaValue) == 0)
2816 geometry_info.sigma=geometry_info.rho;
anthony92c93bd2012-03-19 14:02:47 +00002817 new_image=StatisticImage(_image,NonpeakStatistic,(size_t)
2818 geometry_info.rho,(size_t) geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00002819 }
2820 else
2821 {
anthony31f1bf72012-01-30 12:37:22 +00002822 double
2823 attenuate;
2824
2825 const char*
2826 value;
2827
anthony7bc87992012-03-25 02:32:51 +00002828 parse=ParseCommandOption(MagickNoiseOptions,MagickFalse,arg1);
2829 if ( parse < 0 )
2830 CLIWandExceptArgBreak(OptionError,"UnrecognizedNoiseType",
2831 option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002832 value=GetImageOption(_image_info,"attenuate");
anthony31f1bf72012-01-30 12:37:22 +00002833 if (value != (const char *) NULL)
2834 attenuate=StringToDouble(value,(char **) NULL);
2835 else
2836 attenuate=1.0;
2837
anthony7bc87992012-03-25 02:32:51 +00002838 new_image=AddNoiseImage(_image,(NoiseType)parse,attenuate,
2839 _exception);
anthony805a2d42011-09-25 08:25:12 +00002840 }
2841 break;
2842 }
anthonyafa3dfc2012-03-03 11:31:30 +00002843 if (LocaleCompare("normalize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002844 {
anthony92c93bd2012-03-19 14:02:47 +00002845 (void) NormalizeImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002846 break;
2847 }
anthonyebb73a22012-03-22 14:25:52 +00002848 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002849 }
2850 case 'o':
2851 {
anthonyafa3dfc2012-03-03 11:31:30 +00002852 if (LocaleCompare("opaque",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002853 {
2854 PixelInfo
2855 target;
2856
anthony92c93bd2012-03-19 14:02:47 +00002857 (void) QueryColorCompliance(arg1,AllCompliance,&target,_exception);
2858 (void) OpaquePaintImage(_image,&target,&_draw_info->fill,plus_alt_op,
2859 _exception);
anthony805a2d42011-09-25 08:25:12 +00002860 break;
2861 }
anthonyafa3dfc2012-03-03 11:31:30 +00002862 if (LocaleCompare("ordered-dither",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002863 {
anthony92c93bd2012-03-19 14:02:47 +00002864 (void) OrderedPosterizeImage(_image,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00002865 break;
2866 }
anthonyebb73a22012-03-22 14:25:52 +00002867 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002868 }
2869 case 'p':
2870 {
anthonyafa3dfc2012-03-03 11:31:30 +00002871 if (LocaleCompare("paint",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002872 {
anthonyfd706f92012-01-19 04:22:02 +00002873 (void) ParseGeometry(arg1,&geometry_info);
anthony92c93bd2012-03-19 14:02:47 +00002874 new_image=OilPaintImage(_image,geometry_info.rho,geometry_info.sigma,
2875 _exception);
anthony805a2d42011-09-25 08:25:12 +00002876 break;
2877 }
anthonyafa3dfc2012-03-03 11:31:30 +00002878 if (LocaleCompare("polaroid",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002879 {
cristye9e3d382011-12-14 01:50:13 +00002880 const char
2881 *caption;
2882
anthony805a2d42011-09-25 08:25:12 +00002883 double
2884 angle;
2885
anthony7bc87992012-03-25 02:32:51 +00002886 if (IfPlusOp) {
anthonyf42014d2012-03-25 09:53:06 +00002887 RandomInfo
2888 *random_info;
anthony805a2d42011-09-25 08:25:12 +00002889
anthonyf42014d2012-03-25 09:53:06 +00002890 random_info=AcquireRandomInfo();
2891 angle=22.5*(GetPseudoRandomValue(random_info)-0.5);
2892 random_info=DestroyRandomInfo(random_info);
2893 }
anthony7bc87992012-03-25 02:32:51 +00002894 else {
anthony7bcfe7f2012-03-30 14:01:22 +00002895 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00002896 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2897 flags=ParseGeometry(arg1,&geometry_info);
2898 angle=geometry_info.rho;
2899 }
anthony92c93bd2012-03-19 14:02:47 +00002900 caption=GetImageProperty(_image,"caption",_exception);
2901 new_image=PolaroidImage(_image,_draw_info,caption,angle,
2902 _image->interpolate,_exception);
anthony805a2d42011-09-25 08:25:12 +00002903 break;
2904 }
anthonyafa3dfc2012-03-03 11:31:30 +00002905 if (LocaleCompare("posterize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002906 {
anthony7bcfe7f2012-03-30 14:01:22 +00002907 if (IfMagickFalse(IsGeometry(arg1)))
anthony7bc87992012-03-25 02:32:51 +00002908 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony31f1bf72012-01-30 12:37:22 +00002909 (void) ParseGeometry(arg1,&geometry_info);
anthony92c93bd2012-03-19 14:02:47 +00002910 (void) PosterizeImage(_image,(size_t) geometry_info.rho,
2911 _quantize_info->dither,_exception);
anthony805a2d42011-09-25 08:25:12 +00002912 break;
2913 }
anthonyafa3dfc2012-03-03 11:31:30 +00002914 if (LocaleCompare("preview",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002915 {
anthony31f1bf72012-01-30 12:37:22 +00002916 /* FUTURE: should be a 'Genesis' option?
2917 Option however is also in WandSettingOptionInfo()
anthony7bc87992012-03-25 02:32:51 +00002918 Why???
cristy947cb4c2011-10-20 18:41:46 +00002919 */
anthony7bc87992012-03-25 02:32:51 +00002920 parse=ParseCommandOption(MagickPreviewOptions, MagickFalse,arg1);
2921 if ( parse < 0 )
2922 CLIWandExceptArgBreak(OptionError,"UnrecognizedPreviewType",
2923 option,arg1);
2924 new_image=PreviewImage(_image,(PreviewType)parse,_exception);
anthony805a2d42011-09-25 08:25:12 +00002925 break;
2926 }
anthonyafa3dfc2012-03-03 11:31:30 +00002927 if (LocaleCompare("profile",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002928 {
2929 const char
2930 *name;
2931
2932 const StringInfo
2933 *profile;
2934
2935 Image
2936 *profile_image;
2937
2938 ImageInfo
2939 *profile_info;
2940
anthonyafa3dfc2012-03-03 11:31:30 +00002941 if (IfPlusOp)
anthony92c93bd2012-03-19 14:02:47 +00002942 { /* Remove a profile from the _image. */
2943 (void) ProfileImage(_image,arg1,(const unsigned char *)
2944 NULL,0,_exception);
anthony805a2d42011-09-25 08:25:12 +00002945 break;
2946 }
anthony92c93bd2012-03-19 14:02:47 +00002947 /* Associate a profile with the _image. */
2948 profile_info=CloneImageInfo(_image_info);
2949 profile=GetImageProfile(_image,"iptc");
anthony805a2d42011-09-25 08:25:12 +00002950 if (profile != (StringInfo *) NULL)
2951 profile_info->profile=(void *) CloneStringInfo(profile);
anthony92c93bd2012-03-19 14:02:47 +00002952 profile_image=GetImageCache(profile_info,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00002953 profile_info=DestroyImageInfo(profile_info);
2954 if (profile_image == (Image *) NULL)
2955 {
2956 StringInfo
2957 *profile;
2958
anthony92c93bd2012-03-19 14:02:47 +00002959 profile_info=CloneImageInfo(_image_info);
anthonyfd706f92012-01-19 04:22:02 +00002960 (void) CopyMagickString(profile_info->filename,arg1,
anthony805a2d42011-09-25 08:25:12 +00002961 MaxTextExtent);
anthony92c93bd2012-03-19 14:02:47 +00002962 profile=FileToStringInfo(profile_info->filename,~0UL,_exception);
anthony805a2d42011-09-25 08:25:12 +00002963 if (profile != (StringInfo *) NULL)
2964 {
anthony92c93bd2012-03-19 14:02:47 +00002965 (void) ProfileImage(_image,profile_info->magick,
anthony805a2d42011-09-25 08:25:12 +00002966 GetStringInfoDatum(profile),(size_t)
anthony92c93bd2012-03-19 14:02:47 +00002967 GetStringInfoLength(profile),_exception);
anthony805a2d42011-09-25 08:25:12 +00002968 profile=DestroyStringInfo(profile);
2969 }
2970 profile_info=DestroyImageInfo(profile_info);
2971 break;
2972 }
2973 ResetImageProfileIterator(profile_image);
2974 name=GetNextImageProfile(profile_image);
2975 while (name != (const char *) NULL)
2976 {
2977 profile=GetImageProfile(profile_image,name);
2978 if (profile != (StringInfo *) NULL)
anthony92c93bd2012-03-19 14:02:47 +00002979 (void) ProfileImage(_image,name,GetStringInfoDatum(profile),
2980 (size_t) GetStringInfoLength(profile),_exception);
anthony805a2d42011-09-25 08:25:12 +00002981 name=GetNextImageProfile(profile_image);
2982 }
2983 profile_image=DestroyImage(profile_image);
2984 break;
2985 }
anthonyebb73a22012-03-22 14:25:52 +00002986 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002987 }
anthony805a2d42011-09-25 08:25:12 +00002988 case 'r':
2989 {
anthonyafa3dfc2012-03-03 11:31:30 +00002990 if (LocaleCompare("radial-blur",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002991 {
anthony7bcfe7f2012-03-30 14:01:22 +00002992 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00002993 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00002994 flags=ParseGeometry(arg1,&geometry_info);
cristyaa2c16c2012-03-25 22:21:35 +00002995 new_image=RadialBlurImage(_image,geometry_info.rho,_exception);
anthony805a2d42011-09-25 08:25:12 +00002996 break;
2997 }
anthonyafa3dfc2012-03-03 11:31:30 +00002998 if (LocaleCompare("raise",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002999 {
anthony7bcfe7f2012-03-30 14:01:22 +00003000 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003001 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003002 flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00003003 if ((flags & SigmaValue) == 0)
3004 geometry.height=geometry.width;
anthony92c93bd2012-03-19 14:02:47 +00003005 (void) RaiseImage(_image,&geometry,normal_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00003006 break;
3007 }
anthonyafa3dfc2012-03-03 11:31:30 +00003008 if (LocaleCompare("random-threshold",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003009 {
anthony7bcfe7f2012-03-30 14:01:22 +00003010 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003011 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003012 (void) RandomThresholdImage(_image,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00003013 break;
3014 }
anthonyafa3dfc2012-03-03 11:31:30 +00003015 if (LocaleCompare("remap",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003016 {
3017 Image
3018 *remap_image;
3019
anthony92c93bd2012-03-19 14:02:47 +00003020 remap_image=GetImageCache(_image_info,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00003021 if (remap_image == (Image *) NULL)
3022 break;
anthony92c93bd2012-03-19 14:02:47 +00003023 (void) RemapImage(_quantize_info,_image,remap_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00003024 remap_image=DestroyImage(remap_image);
3025 break;
3026 }
anthonyafa3dfc2012-03-03 11:31:30 +00003027 if (LocaleCompare("repage",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003028 {
anthonyafa3dfc2012-03-03 11:31:30 +00003029 if (IfNormalOp)
cristy0d0de742012-03-25 19:32:48 +00003030 {
anthony7bcfe7f2012-03-30 14:01:22 +00003031 if (IfMagickFalse(IsGeometry(arg1)))
cristy0d0de742012-03-25 19:32:48 +00003032 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,
3033 arg1);
3034 (void) ResetImagePage(_image,arg1);
3035 }
anthony31f1bf72012-01-30 12:37:22 +00003036 else
anthony92c93bd2012-03-19 14:02:47 +00003037 (void) ParseAbsoluteGeometry("0x0+0+0",&_image->page);
anthony805a2d42011-09-25 08:25:12 +00003038 break;
3039 }
anthonyafa3dfc2012-03-03 11:31:30 +00003040 if (LocaleCompare("resample",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003041 {
anthonyf46d4262012-03-26 03:30:34 +00003042 /* FUTURE: Roll into a resize special operation */
anthony7bcfe7f2012-03-30 14:01:22 +00003043 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003044 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00003045 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003046 if ((flags & SigmaValue) == 0)
3047 geometry_info.sigma=geometry_info.rho;
anthony92c93bd2012-03-19 14:02:47 +00003048 new_image=ResampleImage(_image,geometry_info.rho,
cristyaa2c16c2012-03-25 22:21:35 +00003049 geometry_info.sigma,_image->filter,_exception);
anthony805a2d42011-09-25 08:25:12 +00003050 break;
3051 }
anthonyafa3dfc2012-03-03 11:31:30 +00003052 if (LocaleCompare("resize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003053 {
anthony7bcfe7f2012-03-30 14:01:22 +00003054 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003055 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003056 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
3057 new_image=ResizeImage(_image,geometry.width,geometry.height,
cristyaa2c16c2012-03-25 22:21:35 +00003058 _image->filter,_exception);
anthony805a2d42011-09-25 08:25:12 +00003059 break;
3060 }
anthonyafa3dfc2012-03-03 11:31:30 +00003061 if (LocaleCompare("roll",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003062 {
anthony7bcfe7f2012-03-30 14:01:22 +00003063 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003064 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003065 (void) ParsePageGeometry(_image,arg1,&geometry,_exception);
3066 new_image=RollImage(_image,geometry.x,geometry.y,_exception);
anthony805a2d42011-09-25 08:25:12 +00003067 break;
3068 }
anthonyafa3dfc2012-03-03 11:31:30 +00003069 if (LocaleCompare("rotate",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003070 {
anthony7bcfe7f2012-03-30 14:01:22 +00003071 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003072 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00003073 if (strchr(arg1,'>') != (char *) NULL)
anthony92c93bd2012-03-19 14:02:47 +00003074 if (_image->columns <= _image->rows)
anthony805a2d42011-09-25 08:25:12 +00003075 break;
anthonyfd706f92012-01-19 04:22:02 +00003076 if (strchr(arg1,'<') != (char *) NULL)
anthony92c93bd2012-03-19 14:02:47 +00003077 if (_image->columns >= _image->rows)
anthony805a2d42011-09-25 08:25:12 +00003078 break;
anthonyfd706f92012-01-19 04:22:02 +00003079 (void) ParseGeometry(arg1,&geometry_info);
anthony92c93bd2012-03-19 14:02:47 +00003080 new_image=RotateImage(_image,geometry_info.rho,_exception);
anthony805a2d42011-09-25 08:25:12 +00003081 break;
3082 }
anthonyebb73a22012-03-22 14:25:52 +00003083 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003084 }
3085 case 's':
3086 {
anthonyafa3dfc2012-03-03 11:31:30 +00003087 if (LocaleCompare("sample",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003088 {
anthonyfe1aa782012-03-24 13:43:04 +00003089 /* FUTURE: Roll into a resize special operator */
anthony7bcfe7f2012-03-30 14:01:22 +00003090 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003091 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003092 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
3093 new_image=SampleImage(_image,geometry.width,geometry.height,
3094 _exception);
anthony805a2d42011-09-25 08:25:12 +00003095 break;
3096 }
anthonyafa3dfc2012-03-03 11:31:30 +00003097 if (LocaleCompare("scale",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003098 {
anthonyfe1aa782012-03-24 13:43:04 +00003099 /* FUTURE: Roll into a resize special operator */
anthony7bcfe7f2012-03-30 14:01:22 +00003100 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003101 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003102 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
3103 new_image=ScaleImage(_image,geometry.width,geometry.height,
3104 _exception);
anthony805a2d42011-09-25 08:25:12 +00003105 break;
3106 }
anthonyf42014d2012-03-25 09:53:06 +00003107 if (LocaleCompare("segment",option+1) == 0)
3108 {
anthony7bcfe7f2012-03-30 14:01:22 +00003109 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003110 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3111 flags=ParseGeometry(arg1,&geometry_info);
3112 if ((flags & SigmaValue) == 0)
3113 geometry_info.sigma=1.0;
3114 (void) SegmentImage(_image,_image->colorspace,
3115 _image_info->verbose,geometry_info.rho,geometry_info.sigma,
3116 _exception);
3117 break;
3118 }
anthonyafa3dfc2012-03-03 11:31:30 +00003119 if (LocaleCompare("selective-blur",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003120 {
anthony7bcfe7f2012-03-30 14:01:22 +00003121 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003122 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00003123 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003124 if ((flags & PercentValue) != 0)
3125 geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
anthony92c93bd2012-03-19 14:02:47 +00003126 new_image=SelectiveBlurImage(_image,geometry_info.rho,
cristyaa2c16c2012-03-25 22:21:35 +00003127 geometry_info.sigma,geometry_info.xi,_exception);
anthony805a2d42011-09-25 08:25:12 +00003128 break;
3129 }
anthonyafa3dfc2012-03-03 11:31:30 +00003130 if (LocaleCompare("separate",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003131 {
anthony31f1bf72012-01-30 12:37:22 +00003132 /* WARNING: This can generate multiple images! */
anthony43f425d2012-02-26 12:58:58 +00003133 /* FUTURE - this may be replaced by a "-channel" method */
cristydfdb19e2012-03-21 22:22:24 +00003134 new_image=SeparateImages(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00003135 break;
3136 }
anthonyafa3dfc2012-03-03 11:31:30 +00003137 if (LocaleCompare("sepia-tone",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003138 {
anthony7bcfe7f2012-03-30 14:01:22 +00003139 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003140 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
3141 new_image=SepiaToneImage(_image,StringToDoubleInterval(arg1,
3142 (double) QuantumRange+1.0),_exception);
anthony805a2d42011-09-25 08:25:12 +00003143 break;
3144 }
anthonyafa3dfc2012-03-03 11:31:30 +00003145 if (LocaleCompare("set",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003146 {
3147 char
3148 *value;
3149
anthonyf42014d2012-03-25 09:53:06 +00003150 if (IfPlusOp) {
anthonyfd706f92012-01-19 04:22:02 +00003151 if (LocaleNCompare(arg1,"registry:",9) == 0)
3152 (void) DeleteImageRegistry(arg1+9);
anthony805a2d42011-09-25 08:25:12 +00003153 else
anthony31f1bf72012-01-30 12:37:22 +00003154 if (LocaleNCompare(arg1,"option:",7) == 0)
anthony805a2d42011-09-25 08:25:12 +00003155 {
anthony92c93bd2012-03-19 14:02:47 +00003156 (void) DeleteImageOption(_image_info,arg1+7);
3157 (void) DeleteImageArtifact(_image,arg1+7);
anthony805a2d42011-09-25 08:25:12 +00003158 }
3159 else
anthony92c93bd2012-03-19 14:02:47 +00003160 (void) DeleteImageProperty(_image,arg1);
anthony805a2d42011-09-25 08:25:12 +00003161 break;
3162 }
anthonyf42014d2012-03-25 09:53:06 +00003163 value=InterpretImageProperties(_image_info,_image,arg2,_exception);
anthony805a2d42011-09-25 08:25:12 +00003164 if (value == (char *) NULL)
3165 break;
anthonyfd706f92012-01-19 04:22:02 +00003166 if (LocaleNCompare(arg1,"registry:",9) == 0)
anthonyf42014d2012-03-25 09:53:06 +00003167 (void) SetImageRegistry(StringRegistryType,arg1+9,value,_exception);
anthony805a2d42011-09-25 08:25:12 +00003168 else
anthonyfd706f92012-01-19 04:22:02 +00003169 if (LocaleNCompare(arg1,"option:",7) == 0)
anthony805a2d42011-09-25 08:25:12 +00003170 {
anthony92c93bd2012-03-19 14:02:47 +00003171 (void) SetImageOption(_image_info,arg1+7,value);
3172 (void) SetImageArtifact(_image,arg1+7,value);
anthony805a2d42011-09-25 08:25:12 +00003173 }
3174 else
anthony92c93bd2012-03-19 14:02:47 +00003175 (void) SetImageProperty(_image,arg1,value,_exception);
anthony805a2d42011-09-25 08:25:12 +00003176 value=DestroyString(value);
3177 break;
3178 }
anthonyafa3dfc2012-03-03 11:31:30 +00003179 if (LocaleCompare("shade",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003180 {
anthony7bcfe7f2012-03-30 14:01:22 +00003181 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003182 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00003183 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003184 if ((flags & SigmaValue) == 0)
3185 geometry_info.sigma=1.0;
anthony92c93bd2012-03-19 14:02:47 +00003186 new_image=ShadeImage(_image,normal_op,geometry_info.rho,
3187 geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00003188 break;
3189 }
anthonyafa3dfc2012-03-03 11:31:30 +00003190 if (LocaleCompare("shadow",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003191 {
anthony7bcfe7f2012-03-30 14:01:22 +00003192 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003193 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00003194 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003195 if ((flags & SigmaValue) == 0)
3196 geometry_info.sigma=1.0;
3197 if ((flags & XiValue) == 0)
3198 geometry_info.xi=4.0;
3199 if ((flags & PsiValue) == 0)
3200 geometry_info.psi=4.0;
cristyaa2c16c2012-03-25 22:21:35 +00003201 new_image=ShadowImage(_image,geometry_info.rho,geometry_info.sigma,
3202 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
3203 ceil(geometry_info.psi-0.5),_exception);
anthony805a2d42011-09-25 08:25:12 +00003204 break;
3205 }
anthonyafa3dfc2012-03-03 11:31:30 +00003206 if (LocaleCompare("sharpen",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003207 {
anthony7bcfe7f2012-03-30 14:01:22 +00003208 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003209 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00003210 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003211 if ((flags & SigmaValue) == 0)
3212 geometry_info.sigma=1.0;
3213 if ((flags & XiValue) == 0)
3214 geometry_info.xi=0.0;
cristyaa2c16c2012-03-25 22:21:35 +00003215 new_image=SharpenImage(_image,geometry_info.rho,geometry_info.sigma,
3216 _exception);
anthony805a2d42011-09-25 08:25:12 +00003217 break;
3218 }
anthonyafa3dfc2012-03-03 11:31:30 +00003219 if (LocaleCompare("shave",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003220 {
anthony7bcfe7f2012-03-30 14:01:22 +00003221 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003222 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003223 flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
3224 new_image=ShaveImage(_image,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00003225 break;
3226 }
anthonyafa3dfc2012-03-03 11:31:30 +00003227 if (LocaleCompare("shear",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003228 {
anthony7bcfe7f2012-03-30 14:01:22 +00003229 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003230 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00003231 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003232 if ((flags & SigmaValue) == 0)
3233 geometry_info.sigma=geometry_info.rho;
anthony92c93bd2012-03-19 14:02:47 +00003234 new_image=ShearImage(_image,geometry_info.rho,
3235 geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00003236 break;
3237 }
anthonyafa3dfc2012-03-03 11:31:30 +00003238 if (LocaleCompare("sigmoidal-contrast",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003239 {
anthony7bcfe7f2012-03-30 14:01:22 +00003240 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003241 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00003242 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003243 if ((flags & SigmaValue) == 0)
3244 geometry_info.sigma=(double) QuantumRange/2.0;
3245 if ((flags & PercentValue) != 0)
3246 geometry_info.sigma=(double) QuantumRange*geometry_info.sigma/
3247 100.0;
anthony92c93bd2012-03-19 14:02:47 +00003248 (void) SigmoidalContrastImage(_image,normal_op,geometry_info.rho,
anthony31f1bf72012-01-30 12:37:22 +00003249 geometry_info.sigma,
anthony92c93bd2012-03-19 14:02:47 +00003250 _exception);
anthony805a2d42011-09-25 08:25:12 +00003251 break;
3252 }
anthonyafa3dfc2012-03-03 11:31:30 +00003253 if (LocaleCompare("sketch",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003254 {
anthony7bcfe7f2012-03-30 14:01:22 +00003255 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003256 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00003257 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003258 if ((flags & SigmaValue) == 0)
3259 geometry_info.sigma=1.0;
anthony92c93bd2012-03-19 14:02:47 +00003260 new_image=SketchImage(_image,geometry_info.rho,
cristyaa2c16c2012-03-25 22:21:35 +00003261 geometry_info.sigma,geometry_info.xi,_exception);
anthony805a2d42011-09-25 08:25:12 +00003262 break;
3263 }
anthonyafa3dfc2012-03-03 11:31:30 +00003264 if (LocaleCompare("solarize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003265 {
anthony7bcfe7f2012-03-30 14:01:22 +00003266 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003267 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003268 (void) SolarizeImage(_image,StringToDoubleInterval(arg1,(double)
3269 QuantumRange+1.0),_exception);
anthony805a2d42011-09-25 08:25:12 +00003270 break;
3271 }
anthonyafa3dfc2012-03-03 11:31:30 +00003272 if (LocaleCompare("sparse-color",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003273 {
anthony805a2d42011-09-25 08:25:12 +00003274 char
3275 *arguments;
3276
anthonyf42014d2012-03-25 09:53:06 +00003277 parse= ParseCommandOption(MagickSparseColorOptions,MagickFalse,arg1);
3278 if ( parse < 0 )
3279 CLIWandExceptArgBreak(OptionError,"UnrecognizedSparseColorMethod",
3280 option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003281 arguments=InterpretImageProperties(_image_info,_image,arg2,_exception);
anthony805a2d42011-09-25 08:25:12 +00003282 if (arguments == (char *) NULL)
anthonyf42014d2012-03-25 09:53:06 +00003283 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
3284 new_image=SparseColorOption(_image,(SparseColorMethod)parse,
3285 arguments,_exception);
anthony805a2d42011-09-25 08:25:12 +00003286 arguments=DestroyString(arguments);
3287 break;
3288 }
anthonyafa3dfc2012-03-03 11:31:30 +00003289 if (LocaleCompare("splice",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003290 {
anthony7bcfe7f2012-03-30 14:01:22 +00003291 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003292 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003293 (void) ParseGravityGeometry(_image,arg1,&geometry,_exception);
3294 new_image=SpliceImage(_image,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00003295 break;
3296 }
anthonyafa3dfc2012-03-03 11:31:30 +00003297 if (LocaleCompare("spread",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003298 {
anthony7bcfe7f2012-03-30 14:01:22 +00003299 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003300 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00003301 (void) ParseGeometry(arg1,&geometry_info);
anthony92c93bd2012-03-19 14:02:47 +00003302 new_image=SpreadImage(_image,geometry_info.rho,_image->interpolate,
3303 _exception);
anthony805a2d42011-09-25 08:25:12 +00003304 break;
3305 }
anthonyafa3dfc2012-03-03 11:31:30 +00003306 if (LocaleCompare("statistic",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003307 {
anthony7bc87992012-03-25 02:32:51 +00003308 parse=ParseCommandOption(MagickStatisticOptions,MagickFalse,arg1);
3309 if ( parse < 0 )
anthonyf42014d2012-03-25 09:53:06 +00003310 CLIWandExceptArgBreak(OptionError,"UnrecognizedStatisticType",
anthony7bc87992012-03-25 02:32:51 +00003311 option,arg1);
anthony7bcfe7f2012-03-30 14:01:22 +00003312 if (IfMagickFalse(IsGeometry(arg2)))
anthony7bc87992012-03-25 02:32:51 +00003313 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
anthonyfd706f92012-01-19 04:22:02 +00003314 (void) ParseGeometry(arg2,&geometry_info);
anthony7bc87992012-03-25 02:32:51 +00003315 new_image=StatisticImage(_image,(StatisticType)parse,
3316 (size_t) geometry_info.rho,(size_t) geometry_info.sigma,
3317 _exception);
anthony805a2d42011-09-25 08:25:12 +00003318 break;
3319 }
anthonyafa3dfc2012-03-03 11:31:30 +00003320 if (LocaleCompare("strip",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003321 {
anthony92c93bd2012-03-19 14:02:47 +00003322 (void) StripImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00003323 break;
3324 }
anthonyafa3dfc2012-03-03 11:31:30 +00003325 if (LocaleCompare("swirl",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003326 {
anthony7bcfe7f2012-03-30 14:01:22 +00003327 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00003328 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00003329 (void) ParseGeometry(arg1,&geometry_info);
anthony92c93bd2012-03-19 14:02:47 +00003330 new_image=SwirlImage(_image,geometry_info.rho,
3331 _image->interpolate,_exception);
anthony805a2d42011-09-25 08:25:12 +00003332 break;
3333 }
anthonyebb73a22012-03-22 14:25:52 +00003334 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003335 }
3336 case 't':
3337 {
anthonyafa3dfc2012-03-03 11:31:30 +00003338 if (LocaleCompare("threshold",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003339 {
3340 double
3341 threshold;
3342
anthony52bef752012-03-27 13:54:47 +00003343 threshold=(double) QuantumRange/2;
3344 if (normal_op) {
anthony7bcfe7f2012-03-30 14:01:22 +00003345 if (IfMagickFalse(IsGeometry(arg1)))
anthony52bef752012-03-27 13:54:47 +00003346 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00003347 threshold=StringToDoubleInterval(arg1,(double) QuantumRange+1.0);
anthony52bef752012-03-27 13:54:47 +00003348 }
anthony92c93bd2012-03-19 14:02:47 +00003349 (void) BilevelImage(_image,threshold,_exception);
anthony805a2d42011-09-25 08:25:12 +00003350 break;
3351 }
anthonyafa3dfc2012-03-03 11:31:30 +00003352 if (LocaleCompare("thumbnail",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003353 {
anthony7bcfe7f2012-03-30 14:01:22 +00003354 if (IfMagickFalse(IsGeometry(arg1)))
anthony52bef752012-03-27 13:54:47 +00003355 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003356 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
3357 new_image=ThumbnailImage(_image,geometry.width,geometry.height,
3358 _exception);
anthony805a2d42011-09-25 08:25:12 +00003359 break;
3360 }
anthonyafa3dfc2012-03-03 11:31:30 +00003361 if (LocaleCompare("tint",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003362 {
anthony7bcfe7f2012-03-30 14:01:22 +00003363 if (IfMagickFalse(IsGeometry(arg1)))
anthony52bef752012-03-27 13:54:47 +00003364 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003365 new_image=TintImage(_image,arg1,&_draw_info->fill,_exception);
anthony805a2d42011-09-25 08:25:12 +00003366 break;
3367 }
anthonyafa3dfc2012-03-03 11:31:30 +00003368 if (LocaleCompare("transform",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003369 {
anthonya3ef4ed2012-03-17 06:52:53 +00003370 /* DEPRECIATED -- should really use Distort AffineProjection */
anthony52bef752012-03-27 13:54:47 +00003371 new_image=AffineTransformImage(_image,&_draw_info->affine,_exception);
anthony805a2d42011-09-25 08:25:12 +00003372 break;
3373 }
anthonyafa3dfc2012-03-03 11:31:30 +00003374 if (LocaleCompare("transparent",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003375 {
3376 PixelInfo
3377 target;
3378
anthony92c93bd2012-03-19 14:02:47 +00003379 (void) QueryColorCompliance(arg1,AllCompliance,&target,_exception);
3380 (void) TransparentPaintImage(_image,&target,(Quantum)
3381 TransparentAlpha,plus_alt_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00003382 break;
3383 }
anthonyafa3dfc2012-03-03 11:31:30 +00003384 if (LocaleCompare("transpose",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003385 {
anthony92c93bd2012-03-19 14:02:47 +00003386 new_image=TransposeImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00003387 break;
3388 }
anthonyafa3dfc2012-03-03 11:31:30 +00003389 if (LocaleCompare("transverse",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003390 {
anthony92c93bd2012-03-19 14:02:47 +00003391 new_image=TransverseImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00003392 break;
3393 }
anthonyafa3dfc2012-03-03 11:31:30 +00003394 if (LocaleCompare("trim",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003395 {
anthony92c93bd2012-03-19 14:02:47 +00003396 new_image=TrimImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00003397 break;
3398 }
anthonyafa3dfc2012-03-03 11:31:30 +00003399 if (LocaleCompare("type",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003400 {
anthonyab3a50c2011-10-27 11:48:57 +00003401 /* Note that "type" setting should have already been defined */
anthony92c93bd2012-03-19 14:02:47 +00003402 (void) SetImageType(_image,_image_info->type,_exception);
anthony805a2d42011-09-25 08:25:12 +00003403 break;
3404 }
anthonyebb73a22012-03-22 14:25:52 +00003405 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003406 }
3407 case 'u':
3408 {
anthonyafa3dfc2012-03-03 11:31:30 +00003409 if (LocaleCompare("unique",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003410 {
anthony52bef752012-03-27 13:54:47 +00003411 /* FUTURE: move to SyncImageSettings() and AcqireImage()???
3412 Option is not documented, bt appears to be for "identify".
3413 We may need a identify specific verbose!
3414 */
3415 if (plus_alt_op) {
anthony92c93bd2012-03-19 14:02:47 +00003416 (void) DeleteImageArtifact(_image,"identify:unique-colors");
anthony805a2d42011-09-25 08:25:12 +00003417 break;
3418 }
anthony92c93bd2012-03-19 14:02:47 +00003419 (void) SetImageArtifact(_image,"identify:unique-colors","true");
3420 (void) SetImageArtifact(_image,"verbose","true");
anthony805a2d42011-09-25 08:25:12 +00003421 break;
3422 }
anthonyafa3dfc2012-03-03 11:31:30 +00003423 if (LocaleCompare("unique-colors",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003424 {
anthony92c93bd2012-03-19 14:02:47 +00003425 new_image=UniqueImageColors(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00003426 break;
3427 }
anthonyafa3dfc2012-03-03 11:31:30 +00003428 if (LocaleCompare("unsharp",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003429 {
anthony7bcfe7f2012-03-30 14:01:22 +00003430 if (IfMagickFalse(IsGeometry(arg1)))
anthony52bef752012-03-27 13:54:47 +00003431 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00003432 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003433 if ((flags & SigmaValue) == 0)
3434 geometry_info.sigma=1.0;
3435 if ((flags & XiValue) == 0)
3436 geometry_info.xi=1.0;
3437 if ((flags & PsiValue) == 0)
3438 geometry_info.psi=0.05;
anthony92c93bd2012-03-19 14:02:47 +00003439 new_image=UnsharpMaskImage(_image,geometry_info.rho,
3440 geometry_info.sigma,geometry_info.xi,geometry_info.psi,_exception);
anthony805a2d42011-09-25 08:25:12 +00003441 break;
3442 }
anthonyebb73a22012-03-22 14:25:52 +00003443 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003444 }
3445 case 'v':
3446 {
anthonyafa3dfc2012-03-03 11:31:30 +00003447 if (LocaleCompare("verbose",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003448 {
anthonyafa3dfc2012-03-03 11:31:30 +00003449 /* FUTURE: move to SyncImageSettings() and AcquireImage()???
anthony92c93bd2012-03-19 14:02:47 +00003450 three places! ImageArtifact ImageOption _image_info->verbose
anthony5330ae02012-03-20 14:17:01 +00003451 Some how new images also get this artifact!
anthony31f1bf72012-01-30 12:37:22 +00003452 */
anthony92c93bd2012-03-19 14:02:47 +00003453 (void) SetImageArtifact(_image,option+1,
anthonyafa3dfc2012-03-03 11:31:30 +00003454 IfNormalOp ? "true" : "false" );
anthony805a2d42011-09-25 08:25:12 +00003455 break;
3456 }
anthonyafa3dfc2012-03-03 11:31:30 +00003457 if (LocaleCompare("vignette",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003458 {
anthony7bcfe7f2012-03-30 14:01:22 +00003459 if (IfMagickFalse(IsGeometry(arg1)))
anthony52bef752012-03-27 13:54:47 +00003460 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00003461 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003462 if ((flags & SigmaValue) == 0)
3463 geometry_info.sigma=1.0;
3464 if ((flags & XiValue) == 0)
anthony92c93bd2012-03-19 14:02:47 +00003465 geometry_info.xi=0.1*_image->columns;
anthony805a2d42011-09-25 08:25:12 +00003466 if ((flags & PsiValue) == 0)
anthony92c93bd2012-03-19 14:02:47 +00003467 geometry_info.psi=0.1*_image->rows;
3468 new_image=VignetteImage(_image,geometry_info.rho,geometry_info.sigma,
cristyaa2c16c2012-03-25 22:21:35 +00003469 (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
3470 ceil(geometry_info.psi-0.5),_exception);
anthony805a2d42011-09-25 08:25:12 +00003471 break;
3472 }
anthonyebb73a22012-03-22 14:25:52 +00003473 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003474 }
3475 case 'w':
3476 {
anthonyafa3dfc2012-03-03 11:31:30 +00003477 if (LocaleCompare("wave",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003478 {
anthony7bcfe7f2012-03-30 14:01:22 +00003479 if (IfMagickFalse(IsGeometry(arg1)))
anthony52bef752012-03-27 13:54:47 +00003480 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00003481 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003482 if ((flags & SigmaValue) == 0)
3483 geometry_info.sigma=1.0;
anthony92c93bd2012-03-19 14:02:47 +00003484 new_image=WaveImage(_image,geometry_info.rho,geometry_info.sigma,
3485 _image->interpolate,_exception);
anthony805a2d42011-09-25 08:25:12 +00003486 break;
3487 }
anthonyafa3dfc2012-03-03 11:31:30 +00003488 if (LocaleCompare("white-threshold",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003489 {
anthony7bcfe7f2012-03-30 14:01:22 +00003490 if (IfMagickFalse(IsGeometry(arg1)))
anthony52bef752012-03-27 13:54:47 +00003491 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003492 (void) WhiteThresholdImage(_image,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00003493 break;
3494 }
anthonyebb73a22012-03-22 14:25:52 +00003495 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003496 }
3497 default:
anthonyebb73a22012-03-22 14:25:52 +00003498 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003499 }
3500 /*
3501 Replace current image with any image that was generated
anthony31f1bf72012-01-30 12:37:22 +00003502 and set image point to last image (so image->next is correct)
anthony805a2d42011-09-25 08:25:12 +00003503 */
3504 if (new_image != (Image *) NULL)
anthony92c93bd2012-03-19 14:02:47 +00003505 ReplaceImageInListReturnLast(&_image,new_image);
anthony805a2d42011-09-25 08:25:12 +00003506
anthony31f1bf72012-01-30 12:37:22 +00003507 return;
anthony92c93bd2012-03-19 14:02:47 +00003508#undef _image_info
3509#undef _draw_info
3510#undef _quantize_info
3511#undef _image
3512#undef _exception
anthonyafa3dfc2012-03-03 11:31:30 +00003513#undef IfNormalOp
3514#undef IfPlusOp
anthony31f1bf72012-01-30 12:37:22 +00003515#undef normal_op
anthonyafa3dfc2012-03-03 11:31:30 +00003516#undef plus_alt_op
anthony31f1bf72012-01-30 12:37:22 +00003517}
anthonyfd706f92012-01-19 04:22:02 +00003518
anthony43f425d2012-02-26 12:58:58 +00003519WandExport void CLISimpleOperatorImages(MagickCLI *cli_wand,
anthonyafa3dfc2012-03-03 11:31:30 +00003520 const char *option, const char *arg1, const char *arg2)
anthony31f1bf72012-01-30 12:37:22 +00003521{
3522 size_t
anthony43f425d2012-02-26 12:58:58 +00003523 n,
anthony31f1bf72012-01-30 12:37:22 +00003524 i;
3525
anthony43f425d2012-02-26 12:58:58 +00003526 assert(cli_wand != (MagickCLI *) NULL);
3527 assert(cli_wand->signature == WandSignature);
3528 assert(cli_wand->wand.signature == WandSignature);
3529 assert(cli_wand->wand.images != (Image *) NULL); /* images must be present */
anthony7bcfe7f2012-03-30 14:01:22 +00003530 if (IfMagickTrue(cli_wand->wand.debug))
anthony43f425d2012-02-26 12:58:58 +00003531 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
anthony31f1bf72012-01-30 12:37:22 +00003532
anthonyafa3dfc2012-03-03 11:31:30 +00003533#if !USE_WAND_METHODS
3534 /* FUTURE add appropriate tracing */
anthony31f1bf72012-01-30 12:37:22 +00003535 i=0;
anthony43f425d2012-02-26 12:58:58 +00003536 n=GetImageListLength(cli_wand->wand.images);
3537 cli_wand->wand.images=GetFirstImageInList(cli_wand->wand.images);
anthonyafa3dfc2012-03-03 11:31:30 +00003538 while (1) {
anthony31f1bf72012-01-30 12:37:22 +00003539 i++;
anthonyafa3dfc2012-03-03 11:31:30 +00003540 CLISimpleOperatorImage(cli_wand, option, arg1, arg2);
anthony43f425d2012-02-26 12:58:58 +00003541 if ( cli_wand->wand.images->next == (Image *) NULL )
3542 break;
3543 cli_wand->wand.images=cli_wand->wand.images->next;
anthony31f1bf72012-01-30 12:37:22 +00003544 }
anthony43f425d2012-02-26 12:58:58 +00003545 assert( i == n );
3546 cli_wand->wand.images=GetFirstImageInList(cli_wand->wand.images);
anthonyafa3dfc2012-03-03 11:31:30 +00003547#else
3548 MagickResetIterator(&cli_wand->wand);
anthony7bcfe7f2012-03-30 14:01:22 +00003549 while ( IfMagickTrue(MagickNextImage(&cli_wand->wand)) )
anthonyafa3dfc2012-03-03 11:31:30 +00003550 CLISimpleOperatorImage(cli_wand, option, arg1, arg2);
3551 MagickResetIterator(&cli_wand->wand);
3552#endif
anthony31f1bf72012-01-30 12:37:22 +00003553 return;
anthony805a2d42011-09-25 08:25:12 +00003554}
3555
3556/*
3557%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3558% %
3559% %
3560% %
anthony43f425d2012-02-26 12:58:58 +00003561+ 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 +00003562% %
3563% %
3564% %
3565%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3566%
anthony43f425d2012-02-26 12:58:58 +00003567% CLIListOperatorImages() applies a single operation that is apply to the
anthony31f1bf72012-01-30 12:37:22 +00003568% entire image list as a whole. The result is often a complete replacment
3569% of the image list with a completely new list, or just a single image.
anthony805a2d42011-09-25 08:25:12 +00003570%
3571% The format of the MogrifyImage method is:
3572%
anthony43f425d2012-02-26 12:58:58 +00003573% void CLIListOperatorImages(MagickCLI *cli_wand,
anthonyafa3dfc2012-03-03 11:31:30 +00003574% const char *option, const char *arg1, const char *arg2)
anthony805a2d42011-09-25 08:25:12 +00003575%
3576% A description of each parameter follows:
3577%
anthony43f425d2012-02-26 12:58:58 +00003578% o cli_wand: structure holding settings to be applied
anthony805a2d42011-09-25 08:25:12 +00003579%
anthony36a8c2c2012-02-10 00:08:44 +00003580% o option: The option string for the operation
3581%
anthony31f1bf72012-01-30 12:37:22 +00003582% o arg1, arg2: optional argument strings to the operation
anthony805a2d42011-09-25 08:25:12 +00003583%
anthonyfe1aa782012-03-24 13:43:04 +00003584% NOTE: only "limit" uses two arguments.
anthony8b10b462012-02-08 12:32:44 +00003585%
3586% Example usage...
3587%
anthonyafa3dfc2012-03-03 11:31:30 +00003588% CLIListOperatorImages(cli_wand,MagickFalse,"-duplicate", "3", NULL);
3589% CLIListOperatorImages(cli_wand,MagickTrue, "+append", NULL, NULL);
anthony8b10b462012-02-08 12:32:44 +00003590%
anthony24aa8822012-03-11 00:56:06 +00003591% Or for handling command line arguments EG: +/-option ["arg1"]
anthony8b10b462012-02-08 12:32:44 +00003592%
anthony43f425d2012-02-26 12:58:58 +00003593% cli_wand
anthony8b10b462012-02-08 12:32:44 +00003594% argc,argv
3595% i=index in argv
3596%
anthony2052d272012-02-28 12:48:29 +00003597% option_info = GetCommandOptionInfo(argv[i]);
3598% count=option_info->type;
3599% option_type=option_info->flags;
3600%
3601% if ( (option_type & ListOperatorOptionFlag) != 0 )
anthonyafa3dfc2012-03-03 11:31:30 +00003602% CLIListOperatorImages(cli_wand,argv[i],
anthony8b10b462012-02-08 12:32:44 +00003603% count>=1 ? argv[i+1] : (char *)NULL,
3604% count>=2 ? argv[i+2] : (char *)NULL );
3605% i += count+1;
3606%
anthony805a2d42011-09-25 08:25:12 +00003607*/
anthony43f425d2012-02-26 12:58:58 +00003608WandExport void CLIListOperatorImages(MagickCLI *cli_wand,
anthonyafa3dfc2012-03-03 11:31:30 +00003609 const char *option,const char *arg1, const char *arg2)
anthony805a2d42011-09-25 08:25:12 +00003610{
anthony2a0ec8c2012-03-24 04:35:56 +00003611 ssize_t
3612 parse;
3613
anthony31f1bf72012-01-30 12:37:22 +00003614 Image
3615 *new_images;
anthony805a2d42011-09-25 08:25:12 +00003616
anthony2e4501b2012-03-30 04:41:54 +00003617#define _image_info (cli_wand->wand.image_info)
3618#define _images (cli_wand->wand.images)
3619#define _exception (cli_wand->wand.exception)
3620#define _draw_info (cli_wand->draw_info)
3621#define _quantize_info (cli_wand->quantize_info)
anthonyafa3dfc2012-03-03 11:31:30 +00003622#define IfNormalOp (*option=='-')
3623#define IfPlusOp (*option!='-')
anthony7bcfe7f2012-03-30 14:01:22 +00003624#define normal_op IsMagickTrue(IfNormalOp)
anthony805a2d42011-09-25 08:25:12 +00003625
anthony43f425d2012-02-26 12:58:58 +00003626 assert(cli_wand != (MagickCLI *) NULL);
3627 assert(cli_wand->signature == WandSignature);
3628 assert(cli_wand->wand.signature == WandSignature);
anthony92c93bd2012-03-19 14:02:47 +00003629 assert(_images != (Image *) NULL); /* _images must be present */
anthony7bcfe7f2012-03-30 14:01:22 +00003630 if (IfMagickTrue(cli_wand->wand.debug))
anthony43f425d2012-02-26 12:58:58 +00003631 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
anthony31f1bf72012-01-30 12:37:22 +00003632
anthony92c93bd2012-03-19 14:02:47 +00003633 (void) SyncImagesSettings(_image_info,_images,_exception);
anthony31f1bf72012-01-30 12:37:22 +00003634
3635 new_images=NewImageList();
3636
anthonyafa3dfc2012-03-03 11:31:30 +00003637 switch (*(option+1))
anthony805a2d42011-09-25 08:25:12 +00003638 {
3639 case 'a':
3640 {
anthonyafa3dfc2012-03-03 11:31:30 +00003641 if (LocaleCompare("append",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003642 {
anthony92c93bd2012-03-19 14:02:47 +00003643 new_images=AppendImages(_images,normal_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00003644 break;
3645 }
anthonyafa3dfc2012-03-03 11:31:30 +00003646 if (LocaleCompare("average",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003647 {
anthony31f1bf72012-01-30 12:37:22 +00003648 /* DEPRECIATED - use -evaluate-sequence Mean */
anthonyafa3dfc2012-03-03 11:31:30 +00003649 CLIListOperatorImages(cli_wand,"-evaluate-sequence","Mean",NULL);
anthony805a2d42011-09-25 08:25:12 +00003650 break;
3651 }
anthonyebb73a22012-03-22 14:25:52 +00003652 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003653 }
3654 case 'c':
3655 {
cristy5f257b22012-03-07 00:27:29 +00003656 if (LocaleCompare("channel-fx",option+1) == 0)
cristy87c02f42012-02-24 00:19:10 +00003657 {
anthony92c93bd2012-03-19 14:02:47 +00003658 new_images=ChannelFxImage(_images,arg1,_exception);
cristy87c02f42012-02-24 00:19:10 +00003659 break;
3660 }
anthonyafa3dfc2012-03-03 11:31:30 +00003661 if (LocaleCompare("clut",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003662 {
anthony805a2d42011-09-25 08:25:12 +00003663 Image
anthony31f1bf72012-01-30 12:37:22 +00003664 *clut_image;
anthony805a2d42011-09-25 08:25:12 +00003665
anthonyafa3dfc2012-03-03 11:31:30 +00003666 /* FUTURE - make this a compose option, and thus can be used
3667 with layers compose or even compose last image over all other
anthony92c93bd2012-03-19 14:02:47 +00003668 _images.
cristy87c02f42012-02-24 00:19:10 +00003669 */
anthony92c93bd2012-03-19 14:02:47 +00003670 new_images=RemoveFirstImageFromList(&_images);
3671 clut_image=RemoveLastImageFromList(&_images);
anthonye8f56492012-02-12 12:39:02 +00003672 /* FUTURE - produce Exception, rather than silent fail */
anthony805a2d42011-09-25 08:25:12 +00003673 if (clut_image == (Image *) NULL)
cristy87c02f42012-02-24 00:19:10 +00003674 break;
cristye52fb5e2012-04-06 23:30:20 +00003675 (void) ClutImage(new_images,clut_image,new_images->interpolate,_exception);
anthony805a2d42011-09-25 08:25:12 +00003676 clut_image=DestroyImage(clut_image);
anthony805a2d42011-09-25 08:25:12 +00003677 break;
3678 }
anthonyafa3dfc2012-03-03 11:31:30 +00003679 if (LocaleCompare("coalesce",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003680 {
anthony92c93bd2012-03-19 14:02:47 +00003681 new_images=CoalesceImages(_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003682 break;
3683 }
anthonyafa3dfc2012-03-03 11:31:30 +00003684 if (LocaleCompare("combine",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003685 {
anthony43f425d2012-02-26 12:58:58 +00003686 /* FUTURE - this may be replaced by a 'channel' method */
anthony92c93bd2012-03-19 14:02:47 +00003687 new_images=CombineImages(_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003688 break;
3689 }
anthonyafa3dfc2012-03-03 11:31:30 +00003690 if (LocaleCompare("composite",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003691 {
cristyfeb3e962012-03-29 17:25:55 +00003692 CompositeOperator
3693 compose;
3694
3695 const char*
3696 value;
3697
3698 MagickBooleanType
3699 clip_to_self;
3700
anthony805a2d42011-09-25 08:25:12 +00003701 Image
3702 *mask_image,
anthony31f1bf72012-01-30 12:37:22 +00003703 *source_image;
anthony805a2d42011-09-25 08:25:12 +00003704
3705 RectangleInfo
3706 geometry;
3707
anthony7bcfe7f2012-03-30 14:01:22 +00003708 /* Compose value from "-compose" option only */
anthony92c93bd2012-03-19 14:02:47 +00003709 value=GetImageOption(_image_info,"compose");
cristy542a95b2012-04-03 19:30:58 +00003710 if (value == (const char *) NULL)
anthony31f1bf72012-01-30 12:37:22 +00003711 compose=OverCompositeOp; /* use Over not source_image->compose */
cristy542a95b2012-04-03 19:30:58 +00003712 else
3713 compose=(CompositeOperator) ParseCommandOption(MagickComposeOptions,
3714 MagickFalse,value);
anthony5f867ae2011-10-09 10:28:34 +00003715
anthony7bcfe7f2012-03-30 14:01:22 +00003716 /* Get "clip-to-self" expert setting (false is normal) */
cristy542a95b2012-04-03 19:30:58 +00003717 value=GetImageOption(_image_info,"compose:clip-to-self");
3718 if (value == (const char *) NULL)
3719 clip_to_self=MagickTrue;
3720 else
3721 clip_to_self=IsStringTrue(GetImageOption(_image_info,
3722 "compose:clip-to-self")); /* if this is true */
anthony2e4501b2012-03-30 04:41:54 +00003723 value=GetImageOption(_image_info,"compose:outside-overlay");
anthony7bcfe7f2012-03-30 14:01:22 +00003724 if (value != (const char *) NULL) { /* or this false */
anthony2e4501b2012-03-30 04:41:54 +00003725 /* FUTURE: depreciate warning for "compose:outside-overlay"*/
anthony7bcfe7f2012-03-30 14:01:22 +00003726 clip_to_self= IsMagickFalse(IsStringNotFalse(value));
anthony2e4501b2012-03-30 04:41:54 +00003727 }
3728
anthony92c93bd2012-03-19 14:02:47 +00003729 new_images=RemoveFirstImageFromList(&_images);
3730 source_image=RemoveFirstImageFromList(&_images);
anthony31f1bf72012-01-30 12:37:22 +00003731 if (source_image == (Image *) NULL)
anthony7bcfe7f2012-03-30 14:01:22 +00003732 break; /* FUTURE - produce Exception, rather than silent fail */
anthonye8f56492012-02-12 12:39:02 +00003733
anthony31f1bf72012-01-30 12:37:22 +00003734 /* FUTURE - this should not be here! - should be part of -geometry */
3735 (void) TransformImage(&source_image,(char *) NULL,
anthony92c93bd2012-03-19 14:02:47 +00003736 source_image->geometry,_exception);
anthony5f867ae2011-10-09 10:28:34 +00003737
anthony31f1bf72012-01-30 12:37:22 +00003738 SetGeometry(source_image,&geometry);
3739 (void) ParseAbsoluteGeometry(source_image->geometry,&geometry);
3740 GravityAdjustGeometry(new_images->columns,new_images->rows,
3741 new_images->gravity, &geometry);
anthony5f867ae2011-10-09 10:28:34 +00003742
anthony92c93bd2012-03-19 14:02:47 +00003743 mask_image=RemoveFirstImageFromList(&_images);
anthony805a2d42011-09-25 08:25:12 +00003744 if (mask_image != (Image *) NULL)
anthony31f1bf72012-01-30 12:37:22 +00003745 { /* handle a third write mask image */
anthony5f867ae2011-10-09 10:28:34 +00003746 if ((compose == DisplaceCompositeOp) ||
anthony7bcfe7f2012-03-30 14:01:22 +00003747 (compose == DistortCompositeOp)) {
3748 /* Merge Y displacement into X displace/distort map. */
3749 (void) CompositeImage(source_image,mask_image,
3750 CopyGreenCompositeOp,MagickTrue,0,0,_exception);
3751 mask_image=DestroyImage(mask_image);
3752 }
3753 else {
3754 /* Set a blending mask for the composition. */
3755 (void) NegateImage(mask_image,MagickFalse,_exception);
3756 (void) SetImageMask(new_images,mask_image,_exception);
3757 mask_image=DestroyImage(mask_image);
3758 }
anthony805a2d42011-09-25 08:25:12 +00003759 }
cristyfeb3e962012-03-29 17:25:55 +00003760 (void) CompositeImage(new_images,source_image,compose,clip_to_self,
3761 geometry.x,geometry.y,_exception);
anthony92c93bd2012-03-19 14:02:47 +00003762 (void) SetImageMask(new_images,(Image *) NULL,_exception);
anthony31f1bf72012-01-30 12:37:22 +00003763 source_image=DestroyImage(source_image);
anthony805a2d42011-09-25 08:25:12 +00003764 break;
3765 }
anthonyebb73a22012-03-22 14:25:52 +00003766 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003767 }
3768 case 'd':
3769 {
anthonyafa3dfc2012-03-03 11:31:30 +00003770 if (LocaleCompare("deconstruct",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003771 {
anthony31f1bf72012-01-30 12:37:22 +00003772 /* DEPRECIATED - use -layers CompareAny */
anthonyafa3dfc2012-03-03 11:31:30 +00003773 CLIListOperatorImages(cli_wand,"-layer","CompareAny",NULL);
anthony805a2d42011-09-25 08:25:12 +00003774 break;
3775 }
anthonyafa3dfc2012-03-03 11:31:30 +00003776 if (LocaleCompare("delete",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003777 {
anthonyafa3dfc2012-03-03 11:31:30 +00003778 if (IfNormalOp)
anthony92c93bd2012-03-19 14:02:47 +00003779 DeleteImages(&_images,arg1,_exception);
anthonyafa3dfc2012-03-03 11:31:30 +00003780 else
anthony92c93bd2012-03-19 14:02:47 +00003781 DeleteImages(&_images,"-1",_exception);
anthony805a2d42011-09-25 08:25:12 +00003782 break;
3783 }
anthonyafa3dfc2012-03-03 11:31:30 +00003784 if (LocaleCompare("duplicate",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003785 {
anthonyafa3dfc2012-03-03 11:31:30 +00003786 if (IfNormalOp)
anthony805a2d42011-09-25 08:25:12 +00003787 {
3788 const char
3789 *p;
3790
3791 size_t
3792 number_duplicates;
3793
anthony7bcfe7f2012-03-30 14:01:22 +00003794 if (IfMagickFalse(IsGeometry(arg1)))
anthonyebb73a22012-03-22 14:25:52 +00003795 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,
3796 arg1);
anthony31f1bf72012-01-30 12:37:22 +00003797 number_duplicates=(size_t) StringToLong(arg1);
3798 p=strchr(arg1,',');
anthony805a2d42011-09-25 08:25:12 +00003799 if (p == (const char *) NULL)
anthonyebb73a22012-03-22 14:25:52 +00003800 new_images=DuplicateImages(_images,number_duplicates,"-1",
3801 _exception);
anthony805a2d42011-09-25 08:25:12 +00003802 else
anthony92c93bd2012-03-19 14:02:47 +00003803 new_images=DuplicateImages(_images,number_duplicates,p,
3804 _exception);
anthony805a2d42011-09-25 08:25:12 +00003805 }
anthonyafa3dfc2012-03-03 11:31:30 +00003806 else
anthony92c93bd2012-03-19 14:02:47 +00003807 new_images=DuplicateImages(_images,1,"-1",_exception);
3808 AppendImageToList(&_images, new_images);
anthony36a8c2c2012-02-10 00:08:44 +00003809 new_images=(Image *)NULL;
anthony805a2d42011-09-25 08:25:12 +00003810 break;
3811 }
anthonyebb73a22012-03-22 14:25:52 +00003812 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003813 }
3814 case 'e':
3815 {
anthonyafa3dfc2012-03-03 11:31:30 +00003816 if (LocaleCompare("evaluate-sequence",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003817 {
anthony2a0ec8c2012-03-24 04:35:56 +00003818 parse = ParseCommandOption(MagickEvaluateOptions,MagickFalse,arg1);
3819 if ( parse < 0 )
3820 CLIWandExceptArgBreak(OptionError,"UnrecognizedEvaluateOperator",
3821 option,arg1);
3822 new_images=EvaluateImages(_images,(MagickEvaluateOperator)parse,
3823 _exception);
anthony805a2d42011-09-25 08:25:12 +00003824 break;
3825 }
anthonyebb73a22012-03-22 14:25:52 +00003826 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003827 }
3828 case 'f':
3829 {
anthonyafa3dfc2012-03-03 11:31:30 +00003830 if (LocaleCompare("fft",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003831 {
anthony92c93bd2012-03-19 14:02:47 +00003832 new_images=ForwardFourierTransformImage(_images,normal_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00003833 break;
3834 }
anthonyafa3dfc2012-03-03 11:31:30 +00003835 if (LocaleCompare("flatten",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003836 {
anthony319dac62012-03-06 04:12:44 +00003837 /* REDIRECTED to use -layers flatten instead */
anthony2e4501b2012-03-30 04:41:54 +00003838 CLIListOperatorImages(cli_wand,"-layers",option+1,NULL);
anthony805a2d42011-09-25 08:25:12 +00003839 break;
3840 }
anthonyafa3dfc2012-03-03 11:31:30 +00003841 if (LocaleCompare("fx",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003842 {
anthony92c93bd2012-03-19 14:02:47 +00003843 new_images=FxImage(_images,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00003844 break;
3845 }
anthonyebb73a22012-03-22 14:25:52 +00003846 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003847 }
3848 case 'h':
3849 {
anthonyafa3dfc2012-03-03 11:31:30 +00003850 if (LocaleCompare("hald-clut",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003851 {
anthony31f1bf72012-01-30 12:37:22 +00003852 /* FUTURE - make this a compose option (and thus layers compose )
anthony92c93bd2012-03-19 14:02:47 +00003853 or perhaps compose last image over all other _images.
anthony31f1bf72012-01-30 12:37:22 +00003854 */
anthony805a2d42011-09-25 08:25:12 +00003855 Image
anthony31f1bf72012-01-30 12:37:22 +00003856 *hald_image;
anthony805a2d42011-09-25 08:25:12 +00003857
anthony92c93bd2012-03-19 14:02:47 +00003858 new_images=RemoveFirstImageFromList(&_images);
3859 hald_image=RemoveLastImageFromList(&_images);
anthony805a2d42011-09-25 08:25:12 +00003860 if (hald_image == (Image *) NULL)
anthony31f1bf72012-01-30 12:37:22 +00003861 break;
anthony92c93bd2012-03-19 14:02:47 +00003862 (void) HaldClutImage(new_images,hald_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00003863 hald_image=DestroyImage(hald_image);
anthony805a2d42011-09-25 08:25:12 +00003864 break;
3865 }
anthonyebb73a22012-03-22 14:25:52 +00003866 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003867 }
3868 case 'i':
3869 {
anthonyafa3dfc2012-03-03 11:31:30 +00003870 if (LocaleCompare("ift",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003871 {
3872 Image
anthony805a2d42011-09-25 08:25:12 +00003873 *magnitude_image,
3874 *phase_image;
3875
anthony92c93bd2012-03-19 14:02:47 +00003876 magnitude_image=RemoveFirstImageFromList(&_images);
3877 phase_image=RemoveFirstImageFromList(&_images);
anthonye8f56492012-02-12 12:39:02 +00003878 /* FUTURE - produce Exception, rather than silent fail */
anthony31f1bf72012-01-30 12:37:22 +00003879 if (phase_image == (Image *) NULL)
3880 break;
3881 new_images=InverseFourierTransformImage(magnitude_image,phase_image,
anthony92c93bd2012-03-19 14:02:47 +00003882 normal_op,_exception);
anthony31f1bf72012-01-30 12:37:22 +00003883 magnitude_image=DestroyImage(magnitude_image);
3884 phase_image=DestroyImage(phase_image);
anthony805a2d42011-09-25 08:25:12 +00003885 break;
3886 }
anthonyafa3dfc2012-03-03 11:31:30 +00003887 if (LocaleCompare("insert",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003888 {
3889 Image
anthony31f1bf72012-01-30 12:37:22 +00003890 *insert_image,
3891 *index_image;
3892
3893 ssize_t
3894 index;
anthony805a2d42011-09-25 08:25:12 +00003895
anthony7bcfe7f2012-03-30 14:01:22 +00003896 if (IfNormalOp && IfMagickFalse(IsGeometry(arg1)))
anthonyfe1aa782012-03-24 13:43:04 +00003897 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00003898 index=0;
anthony92c93bd2012-03-19 14:02:47 +00003899 insert_image=RemoveLastImageFromList(&_images);
anthonyafa3dfc2012-03-03 11:31:30 +00003900 if (IfNormalOp)
anthony31f1bf72012-01-30 12:37:22 +00003901 index=(ssize_t) StringToLong(arg1);
anthony43f425d2012-02-26 12:58:58 +00003902 index_image=insert_image;
anthony805a2d42011-09-25 08:25:12 +00003903 if (index == 0)
anthony92c93bd2012-03-19 14:02:47 +00003904 PrependImageToList(&_images,insert_image);
3905 else if (index == (ssize_t) GetImageListLength(_images))
3906 AppendImageToList(&_images,insert_image);
anthony805a2d42011-09-25 08:25:12 +00003907 else
anthony43f425d2012-02-26 12:58:58 +00003908 {
anthony92c93bd2012-03-19 14:02:47 +00003909 index_image=GetImageFromList(_images,index-1);
anthony43f425d2012-02-26 12:58:58 +00003910 if (index_image == (Image *) NULL)
anthonyfe1aa782012-03-24 13:43:04 +00003911 CLIWandExceptArgBreak(OptionError,"NoSuchImage",option,arg1);
anthony43f425d2012-02-26 12:58:58 +00003912 InsertImageInList(&index_image,insert_image);
3913 }
anthony92c93bd2012-03-19 14:02:47 +00003914 _images=GetFirstImageInList(index_image);
anthony805a2d42011-09-25 08:25:12 +00003915 break;
3916 }
anthonyebb73a22012-03-22 14:25:52 +00003917 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003918 }
3919 case 'l':
3920 {
anthonyafa3dfc2012-03-03 11:31:30 +00003921 if (LocaleCompare("layers",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003922 {
anthonyfe1aa782012-03-24 13:43:04 +00003923 parse=ParseCommandOption(MagickLayerOptions,MagickFalse,arg1);
3924 if ( parse < 0 )
3925 CLIWandExceptArgBreak(OptionError,"UnrecognizedLayerMethod",
3926 option,arg1);
3927 switch ((ImageLayerMethod) parse)
anthony805a2d42011-09-25 08:25:12 +00003928 {
3929 case CoalesceLayer:
3930 {
anthony92c93bd2012-03-19 14:02:47 +00003931 new_images=CoalesceImages(_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003932 break;
3933 }
3934 case CompareAnyLayer:
3935 case CompareClearLayer:
3936 case CompareOverlayLayer:
3937 default:
3938 {
anthonyfe1aa782012-03-24 13:43:04 +00003939 new_images=CompareImagesLayers(_images,(ImageLayerMethod) parse,
3940 _exception);
anthony805a2d42011-09-25 08:25:12 +00003941 break;
3942 }
3943 case MergeLayer:
3944 case FlattenLayer:
3945 case MosaicLayer:
3946 case TrimBoundsLayer:
3947 {
anthonyfe1aa782012-03-24 13:43:04 +00003948 new_images=MergeImageLayers(_images,(ImageLayerMethod) parse,
3949 _exception);
anthony805a2d42011-09-25 08:25:12 +00003950 break;
3951 }
3952 case DisposeLayer:
3953 {
anthony92c93bd2012-03-19 14:02:47 +00003954 new_images=DisposeImages(_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003955 break;
3956 }
3957 case OptimizeImageLayer:
3958 {
anthony92c93bd2012-03-19 14:02:47 +00003959 new_images=OptimizeImageLayers(_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003960 break;
3961 }
3962 case OptimizePlusLayer:
3963 {
anthony92c93bd2012-03-19 14:02:47 +00003964 new_images=OptimizePlusImageLayers(_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003965 break;
3966 }
3967 case OptimizeTransLayer:
3968 {
anthony92c93bd2012-03-19 14:02:47 +00003969 OptimizeImageTransparency(_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003970 break;
3971 }
3972 case RemoveDupsLayer:
3973 {
anthony92c93bd2012-03-19 14:02:47 +00003974 RemoveDuplicateLayers(&_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003975 break;
3976 }
3977 case RemoveZeroLayer:
3978 {
anthony92c93bd2012-03-19 14:02:47 +00003979 RemoveZeroDelayLayers(&_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003980 break;
3981 }
3982 case OptimizeLayer:
anthony31f1bf72012-01-30 12:37:22 +00003983 { /* General Purpose, GIF Animation Optimizer. */
anthony92c93bd2012-03-19 14:02:47 +00003984 new_images=CoalesceImages(_images,_exception);
anthony31f1bf72012-01-30 12:37:22 +00003985 if (new_images == (Image *) NULL)
3986 break;
anthony92c93bd2012-03-19 14:02:47 +00003987 _images=DestroyImageList(_images);
3988 _images=OptimizeImageLayers(new_images,_exception);
3989 if (_images == (Image *) NULL)
anthony31f1bf72012-01-30 12:37:22 +00003990 break;
3991 new_images=DestroyImageList(new_images);
anthony92c93bd2012-03-19 14:02:47 +00003992 OptimizeImageTransparency(_images,_exception);
3993 (void) RemapImages(_quantize_info,_images,(Image *) NULL,
3994 _exception);
anthony805a2d42011-09-25 08:25:12 +00003995 break;
3996 }
3997 case CompositeLayer:
3998 {
anthony805a2d42011-09-25 08:25:12 +00003999 Image
4000 *source;
4001
4002 RectangleInfo
4003 geometry;
4004
anthony31f1bf72012-01-30 12:37:22 +00004005 CompositeOperator
anthony5f867ae2011-10-09 10:28:34 +00004006 compose;
4007
4008 const char*
4009 value;
4010
anthony92c93bd2012-03-19 14:02:47 +00004011 value=GetImageOption(_image_info,"compose");
anthony31f1bf72012-01-30 12:37:22 +00004012 compose=OverCompositeOp; /* Default to Over */
anthony5f867ae2011-10-09 10:28:34 +00004013 if (value != (const char *) NULL)
4014 compose=(CompositeOperator) ParseCommandOption(
4015 MagickComposeOptions,MagickFalse,value);
anthony5f867ae2011-10-09 10:28:34 +00004016
anthony31f1bf72012-01-30 12:37:22 +00004017 /* Split image sequence at the first 'NULL:' image. */
anthony92c93bd2012-03-19 14:02:47 +00004018 source=_images;
anthony805a2d42011-09-25 08:25:12 +00004019 while (source != (Image *) NULL)
4020 {
4021 source=GetNextImageInList(source);
4022 if ((source != (Image *) NULL) &&
4023 (LocaleCompare(source->magick,"NULL") == 0))
4024 break;
4025 }
4026 if (source != (Image *) NULL)
4027 {
4028 if ((GetPreviousImageInList(source) == (Image *) NULL) ||
4029 (GetNextImageInList(source) == (Image *) NULL))
4030 source=(Image *) NULL;
4031 else
anthony31f1bf72012-01-30 12:37:22 +00004032 { /* Separate the two lists, junk the null: image. */
anthony805a2d42011-09-25 08:25:12 +00004033 source=SplitImageList(source->previous);
4034 DeleteImageFromList(&source);
4035 }
4036 }
4037 if (source == (Image *) NULL)
4038 {
anthony92c93bd2012-03-19 14:02:47 +00004039 (void) ThrowMagickException(_exception,GetMagickModule(),
anthony805a2d42011-09-25 08:25:12 +00004040 OptionError,"MissingNullSeparator","layers Composite");
anthony805a2d42011-09-25 08:25:12 +00004041 break;
4042 }
anthony31f1bf72012-01-30 12:37:22 +00004043 /* Adjust offset with gravity and virtual canvas. */
anthony92c93bd2012-03-19 14:02:47 +00004044 SetGeometry(_images,&geometry);
4045 (void) ParseAbsoluteGeometry(_images->geometry,&geometry);
anthony805a2d42011-09-25 08:25:12 +00004046 geometry.width=source->page.width != 0 ?
4047 source->page.width : source->columns;
4048 geometry.height=source->page.height != 0 ?
4049 source->page.height : source->rows;
anthony92c93bd2012-03-19 14:02:47 +00004050 GravityAdjustGeometry(_images->page.width != 0 ?
4051 _images->page.width : _images->columns,
4052 _images->page.height != 0 ? _images->page.height :
4053 _images->rows,_images->gravity,&geometry);
anthony5f867ae2011-10-09 10:28:34 +00004054
anthony31f1bf72012-01-30 12:37:22 +00004055 /* Compose the two image sequences together */
anthony92c93bd2012-03-19 14:02:47 +00004056 CompositeLayers(_images,compose,source,geometry.x,geometry.y,
4057 _exception);
anthony805a2d42011-09-25 08:25:12 +00004058 source=DestroyImageList(source);
4059 break;
4060 }
4061 }
anthony805a2d42011-09-25 08:25:12 +00004062 break;
4063 }
anthonyebb73a22012-03-22 14:25:52 +00004064 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00004065 }
4066 case 'm':
4067 {
anthonyafa3dfc2012-03-03 11:31:30 +00004068 if (LocaleCompare("map",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00004069 {
anthony31f1bf72012-01-30 12:37:22 +00004070 /* DEPRECIATED use +remap */
anthony92c93bd2012-03-19 14:02:47 +00004071 (void) RemapImages(_quantize_info,_images,(Image *) NULL,_exception);
anthony805a2d42011-09-25 08:25:12 +00004072 break;
4073 }
anthonyafa3dfc2012-03-03 11:31:30 +00004074 if (LocaleCompare("morph",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00004075 {
4076 Image
4077 *morph_image;
4078
anthony7bcfe7f2012-03-30 14:01:22 +00004079 if (IfMagickFalse(IsGeometry(arg1)))
anthony7bc87992012-03-25 02:32:51 +00004080 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00004081 morph_image=MorphImages(_images,StringToUnsignedLong(arg1),
4082 _exception);
anthony805a2d42011-09-25 08:25:12 +00004083 if (morph_image == (Image *) NULL)
anthony31f1bf72012-01-30 12:37:22 +00004084 break;
anthony92c93bd2012-03-19 14:02:47 +00004085 _images=DestroyImageList(_images);
4086 _images=morph_image;
anthony805a2d42011-09-25 08:25:12 +00004087 break;
4088 }
anthonyafa3dfc2012-03-03 11:31:30 +00004089 if (LocaleCompare("mosaic",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00004090 {
anthony319dac62012-03-06 04:12:44 +00004091 /* REDIRECTED to use -layers mosaic instead */
anthony2e4501b2012-03-30 04:41:54 +00004092 CLIListOperatorImages(cli_wand,"-layers",option+1,NULL);
anthony805a2d42011-09-25 08:25:12 +00004093 break;
4094 }
anthonyebb73a22012-03-22 14:25:52 +00004095 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00004096 }
4097 case 'p':
4098 {
anthonyafa3dfc2012-03-03 11:31:30 +00004099 if (LocaleCompare("print",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00004100 {
4101 char
4102 *string;
4103
anthony92c93bd2012-03-19 14:02:47 +00004104 string=InterpretImageProperties(_image_info,_images,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00004105 if (string == (char *) NULL)
4106 break;
4107 (void) FormatLocaleFile(stdout,"%s",string);
4108 string=DestroyString(string);
anthony24aa8822012-03-11 00:56:06 +00004109 break;
anthony805a2d42011-09-25 08:25:12 +00004110 }
anthonyafa3dfc2012-03-03 11:31:30 +00004111 if (LocaleCompare("process",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00004112 {
4113 char
4114 **arguments;
4115
4116 int
4117 j,
4118 number_arguments;
4119
anthony31f1bf72012-01-30 12:37:22 +00004120 arguments=StringToArgv(arg1,&number_arguments);
anthony805a2d42011-09-25 08:25:12 +00004121 if (arguments == (char **) NULL)
4122 break;
anthony31f1bf72012-01-30 12:37:22 +00004123 if (strchr(arguments[1],'=') != (char *) NULL)
anthony805a2d42011-09-25 08:25:12 +00004124 {
4125 char
4126 breaker,
4127 quote,
4128 *token;
4129
4130 const char
4131 *arguments;
4132
4133 int
4134 next,
4135 status;
4136
4137 size_t
4138 length;
4139
4140 TokenInfo
4141 *token_info;
4142
4143 /*
anthony24aa8822012-03-11 00:56:06 +00004144 Support old style syntax, filter="-option arg1".
anthony805a2d42011-09-25 08:25:12 +00004145 */
anthony31f1bf72012-01-30 12:37:22 +00004146 length=strlen(arg1);
anthony805a2d42011-09-25 08:25:12 +00004147 token=(char *) NULL;
4148 if (~length >= (MaxTextExtent-1))
4149 token=(char *) AcquireQuantumMemory(length+MaxTextExtent,
4150 sizeof(*token));
4151 if (token == (char *) NULL)
4152 break;
4153 next=0;
anthony31f1bf72012-01-30 12:37:22 +00004154 arguments=arg1;
anthony805a2d42011-09-25 08:25:12 +00004155 token_info=AcquireTokenInfo();
4156 status=Tokenizer(token_info,0,token,length,arguments,"","=",
4157 "\"",'\0',&breaker,&next,&quote);
4158 token_info=DestroyTokenInfo(token_info);
4159 if (status == 0)
4160 {
4161 const char
4162 *argv;
4163
4164 argv=(&(arguments[next]));
anthony92c93bd2012-03-19 14:02:47 +00004165 (void) InvokeDynamicImageFilter(token,&_images,1,&argv,
4166 _exception);
anthony805a2d42011-09-25 08:25:12 +00004167 }
4168 token=DestroyString(token);
4169 break;
4170 }
4171 (void) SubstituteString(&arguments[1],"-","");
anthony92c93bd2012-03-19 14:02:47 +00004172 (void) InvokeDynamicImageFilter(arguments[1],&_images,
4173 number_arguments-2,(const char **) arguments+2,_exception);
anthony805a2d42011-09-25 08:25:12 +00004174 for (j=0; j < number_arguments; j++)
4175 arguments[j]=DestroyString(arguments[j]);
4176 arguments=(char **) RelinquishMagickMemory(arguments);
4177 break;
4178 }
anthonyebb73a22012-03-22 14:25:52 +00004179 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00004180 }
4181 case 'r':
4182 {
anthonyafa3dfc2012-03-03 11:31:30 +00004183 if (LocaleCompare("remap",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00004184 {
anthony92c93bd2012-03-19 14:02:47 +00004185 (void) RemapImages(_quantize_info,_images,(Image *) NULL,_exception);
anthony31f1bf72012-01-30 12:37:22 +00004186 break;
4187 }
anthonyafa3dfc2012-03-03 11:31:30 +00004188 if (LocaleCompare("reverse",option+1) == 0)
anthony31f1bf72012-01-30 12:37:22 +00004189 {
anthony92c93bd2012-03-19 14:02:47 +00004190 ReverseImageList(&_images);
anthony805a2d42011-09-25 08:25:12 +00004191 break;
4192 }
anthonyebb73a22012-03-22 14:25:52 +00004193 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00004194 }
4195 case 's':
4196 {
anthonyafa3dfc2012-03-03 11:31:30 +00004197 if (LocaleCompare("smush",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00004198 {
4199 Image
4200 *smush_image;
4201
4202 ssize_t
4203 offset;
4204
anthony7bcfe7f2012-03-30 14:01:22 +00004205 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00004206 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony31f1bf72012-01-30 12:37:22 +00004207 offset=(ssize_t) StringToLong(arg1);
anthony92c93bd2012-03-19 14:02:47 +00004208 smush_image=SmushImages(_images,normal_op,offset,_exception);
anthony805a2d42011-09-25 08:25:12 +00004209 if (smush_image == (Image *) NULL)
anthony31f1bf72012-01-30 12:37:22 +00004210 break;
anthony92c93bd2012-03-19 14:02:47 +00004211 _images=DestroyImageList(_images);
4212 _images=smush_image;
anthony805a2d42011-09-25 08:25:12 +00004213 break;
4214 }
anthony0ea037a2012-04-03 12:14:39 +00004215 if (LocaleCompare("swap",option+1) == 0) {
4216 Image
4217 *p,
4218 *q,
4219 *swap;
anthony805a2d42011-09-25 08:25:12 +00004220
anthony0ea037a2012-04-03 12:14:39 +00004221 ssize_t
4222 index,
4223 swap_index;
anthony805a2d42011-09-25 08:25:12 +00004224
anthony0ea037a2012-04-03 12:14:39 +00004225 index=-1;
4226 swap_index=-2;
4227 if (IfNormalOp) {
4228 GeometryInfo
4229 geometry_info;
4230
4231 MagickStatusType
4232 flags;
4233
4234 swap_index=(-1);
anthony7bcfe7f2012-03-30 14:01:22 +00004235 if (IfMagickFalse(IsGeometry(arg1)))
anthonyf42014d2012-03-25 09:53:06 +00004236 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony0ea037a2012-04-03 12:14:39 +00004237 flags=ParseGeometry(arg1,&geometry_info);
4238 index=(ssize_t) geometry_info.rho;
4239 if ((flags & SigmaValue) != 0)
4240 swap_index=(ssize_t) geometry_info.sigma;
anthony805a2d42011-09-25 08:25:12 +00004241 }
anthony0ea037a2012-04-03 12:14:39 +00004242 p=GetImageFromList(_images,index);
4243 q=GetImageFromList(_images,swap_index);
anthony8226e722012-04-05 14:25:46 +00004244 if ((p == (Image *) NULL) || (q == (Image *) NULL)) {
4245 if (IfNormalOp)
4246 CLIWandExceptArgBreak(OptionError,"InvalidImageIndex",option,arg1)
4247 else
4248 CLIWandExceptionBreak(OptionError,"TwoOrMoreImagesRequired",option);
4249 }
anthony0ea037a2012-04-03 12:14:39 +00004250 if (p == q)
anthony8226e722012-04-05 14:25:46 +00004251 CLIWandExceptArgBreak(OptionError,"InvalidImageIndex",option,arg1);
anthony0ea037a2012-04-03 12:14:39 +00004252 swap=CloneImage(p,0,0,MagickTrue,_exception);
4253 ReplaceImageInList(&p,CloneImage(q,0,0,MagickTrue,_exception));
4254 ReplaceImageInList(&q,swap);
4255 _images=GetFirstImageInList(q);
4256 break;
4257 }
anthonyebb73a22012-03-22 14:25:52 +00004258 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00004259 }
anthony805a2d42011-09-25 08:25:12 +00004260 default:
anthonyebb73a22012-03-22 14:25:52 +00004261 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00004262 }
anthony31f1bf72012-01-30 12:37:22 +00004263 if (new_images == (Image *) NULL)
4264 return;
anthony805a2d42011-09-25 08:25:12 +00004265
anthony92c93bd2012-03-19 14:02:47 +00004266 if (_images != (Image *) NULL)
4267 _images=DestroyImageList(_images);
4268 _images=GetFirstImageInList(new_images);
anthony31f1bf72012-01-30 12:37:22 +00004269 return;
4270
anthony92c93bd2012-03-19 14:02:47 +00004271#undef _image_info
4272#undef _images
4273#undef _exception
4274#undef _draw_info
4275#undef _quantize_info
anthonyafa3dfc2012-03-03 11:31:30 +00004276#undef IfNormalOp
4277#undef IfPlusOp
anthony31f1bf72012-01-30 12:37:22 +00004278#undef normal_op
anthony805a2d42011-09-25 08:25:12 +00004279}
anthony43f425d2012-02-26 12:58:58 +00004280
4281/*
4282%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4283% %
4284% %
4285% %
4286+ C L I S p e c i a l O p e r a t i o n s %
4287% %
4288% %
4289% %
4290%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4291%
anthony756cd0d2012-04-08 12:41:44 +00004292% CLISpecialOperator() Applies operations that may not actually need images
4293% in an image list wen it is applied.
anthony43f425d2012-02-26 12:58:58 +00004294%
anthony756cd0d2012-04-08 12:41:44 +00004295% The classic operators of this type is -read, which actually creates images
4296% even when no images are present. Or image stack operators, which can be
4297% applied to empty image lists.
anthonyafa3dfc2012-03-03 11:31:30 +00004298%
4299% Note: unlike other Operators, these may involve other special 'option'
4300% character prefixes, other than simply '-' or '+'.
anthony43f425d2012-02-26 12:58:58 +00004301%
4302% The format of the CLISpecialOption method is:
4303%
4304% void CLISpecialOption(MagickCLI *cli_wand,const char *option,
anthony24aa8822012-03-11 00:56:06 +00004305% const char *arg1)
anthony43f425d2012-02-26 12:58:58 +00004306%
4307% A description of each parameter follows:
4308%
4309% o cli_wand: the main CLI Wand to use.
4310%
4311% o option: The special option (with any switch char) to process
4312%
anthony24aa8822012-03-11 00:56:06 +00004313% o arg1: Argument for option, if required
anthonyafa3dfc2012-03-03 11:31:30 +00004314%
anthony2052d272012-02-28 12:48:29 +00004315% Example Usage...
4316%
anthonyce8dcb32012-03-21 13:20:31 +00004317% CLISpecialOperator(cli_wand,"-read","rose:");
anthony2052d272012-02-28 12:48:29 +00004318%
anthony24aa8822012-03-11 00:56:06 +00004319% Or for handling command line arguments EG: +/-option ["arg1"]
anthony2052d272012-02-28 12:48:29 +00004320%
4321% cli_wand
4322% argc,argv
4323% i=index in argv
4324%
4325% option_info = GetCommandOptionInfo(argv[i]);
4326% count=option_info->type;
4327% option_type=option_info->flags;
4328%
4329% if ( (option_type & SpecialOptionFlag) != 0 )
4330% CLISpecialOperator(cli_wand,argv[i],
4331% count>=1 ? argv[i+1] : (char *)NULL);
4332% i += count+1;
anthony43f425d2012-02-26 12:58:58 +00004333%
4334*/
4335
anthony43f425d2012-02-26 12:58:58 +00004336WandExport void CLISpecialOperator(MagickCLI *cli_wand,
anthony24aa8822012-03-11 00:56:06 +00004337 const char *option, const char *arg1)
anthony43f425d2012-02-26 12:58:58 +00004338{
anthony8226e722012-04-05 14:25:46 +00004339#define _image_info (cli_wand->wand.image_info)
4340#define _images (cli_wand->wand.images)
4341#define _exception (cli_wand->wand.exception)
4342#define IfNormalOp (*option=='-')
4343#define IfPlusOp (*option!='-')
anthony43f425d2012-02-26 12:58:58 +00004344
4345 assert(cli_wand != (MagickCLI *) NULL);
4346 assert(cli_wand->signature == WandSignature);
4347 assert(cli_wand->wand.signature == WandSignature);
anthony7bcfe7f2012-03-30 14:01:22 +00004348 if (IfMagickTrue(cli_wand->wand.debug))
anthony43f425d2012-02-26 12:58:58 +00004349 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
4350
anthony8226e722012-04-05 14:25:46 +00004351 if(_images != (Image *)NULL)
4352 (void) SyncImagesSettings(cli_wand->wand.image_info,_images,_exception);
anthony24aa8822012-03-11 00:56:06 +00004353
anthony52bef752012-03-27 13:54:47 +00004354 /*
anthony756cd0d2012-04-08 12:41:44 +00004355 No-op options (ignore these)
anthony52bef752012-03-27 13:54:47 +00004356 */
anthony756cd0d2012-04-08 12:41:44 +00004357 if (LocaleCompare("noop",option+1) == 0) /* no argument */
anthony52bef752012-03-27 13:54:47 +00004358 return;
anthony756cd0d2012-04-08 12:41:44 +00004359 if (LocaleCompare("sans",option+1) == 0) /* one argument */
anthony52bef752012-03-27 13:54:47 +00004360 return;
anthony756cd0d2012-04-08 12:41:44 +00004361 if (LocaleCompare("sans0",option+1) == 0) /* no argument */
anthony52bef752012-03-27 13:54:47 +00004362 return;
anthony756cd0d2012-04-08 12:41:44 +00004363 if (LocaleCompare("sans2",option+1) == 0) /* two arguments */
anthony52bef752012-03-27 13:54:47 +00004364 return;
4365 /*
4366 Image Reading
4367 */
4368 if ( ( LocaleCompare("read",option+1) == 0 ) ||
anthony0ea037a2012-04-03 12:14:39 +00004369 ( LocaleCompare("--",option) == 0 ) ) {
4370 int
4371 argc;
4372 char
4373 **argv;
anthony52bef752012-03-27 13:54:47 +00004374
anthony0ea037a2012-04-03 12:14:39 +00004375 ssize_t
4376 i;
4377
4378 /* Expand the filename argument (meta-characters or "@filelist" ) */
4379 argc = 1;
cristye71f2942012-04-04 11:07:05 +00004380 argv = (char **) &arg1;
anthony0ea037a2012-04-03 12:14:39 +00004381 MagickBooleanType
4382 status=ExpandFilenames(&argc,&argv);
4383
4384 if (IfMagickFalse(status))
4385 CLIWandExceptArgReturn(ResourceLimitError,"MemoryAllocationFailed",
4386 option,GetExceptionMessage(errno));
4387
4388 /* loop over expanded list reading images */
4389 for (i=0; i<argc; i++) {
anthony52bef752012-03-27 13:54:47 +00004390#if !USE_WAND_METHODS
4391 Image *
4392 new_images;
anthony8226e722012-04-05 14:25:46 +00004393 if (IfMagickTrue(_image_info->ping))
4394 new_images=PingImages(_image_info,argv[i],_exception);
anthony52bef752012-03-27 13:54:47 +00004395 else
anthony8226e722012-04-05 14:25:46 +00004396 new_images=ReadImages(_image_info,argv[i],_exception);
4397 AppendImageToList(&_images, new_images);
anthony52bef752012-03-27 13:54:47 +00004398#else
4399 /* read images using MagickWand method - no ping */
4400 /* This is not working! - it locks up in a CPU loop! */
4401 MagickSetLastIterator(&cli_wand->wand);
4402 MagickReadImage(&cli_wand->wand,arg1);
4403 MagickSetFirstIterator(&cli_wand->wand);
4404#endif
anthony52bef752012-03-27 13:54:47 +00004405 }
anthony0ea037a2012-04-03 12:14:39 +00004406 /* FUTURE: how do I free the expanded filename arguments??? */
4407
4408 return;
4409 }
anthony52bef752012-03-27 13:54:47 +00004410 /*
anthony756cd0d2012-04-08 12:41:44 +00004411 Image Writing (no-images present is valid in specific cases)
anthony8226e722012-04-05 14:25:46 +00004412 */
4413 if (LocaleCompare("write",option+1) == 0) {
4414 char
4415 key[MaxTextExtent];
4416
4417 Image
4418 *write_images;
4419
4420 ImageInfo
4421 *write_info;
4422
4423 /* Need images, unless a "null:" output coder is used */
4424 if ( cli_wand->wand.images == (Image *) NULL ) {
4425 if ( LocaleCompare(option,"null:") == 0 )
4426 return;
4427 CLIWandExceptArgReturn(OptionError,"NoImagesForWrite",option,arg1);
4428 }
4429
4430 (void) FormatLocaleString(key,MaxTextExtent,"cache:%s",arg1);
4431 (void) DeleteImageRegistry(key);
4432 write_images=_images;
4433 if (IfPlusOp)
4434 write_images=CloneImageList(_images,_exception);
4435 write_info=CloneImageInfo(_image_info);
4436 (void) WriteImages(write_info,write_images,arg1,_exception);
4437 write_info=DestroyImageInfo(write_info);
4438 if (IfPlusOp)
4439 write_images=DestroyImageList(write_images);
4440 return;
4441 }
4442 /*
anthony52bef752012-03-27 13:54:47 +00004443 Parenthesis and Brace operations
4444 */
anthonyce8dcb32012-03-21 13:20:31 +00004445 if (LocaleCompare("(",option) == 0) {
anthony8226e722012-04-05 14:25:46 +00004446 /* stack 'push' images */
4447 Stack
4448 *node;
anthony43f425d2012-02-26 12:58:58 +00004449
anthony8226e722012-04-05 14:25:46 +00004450 size_t
4451 size;
anthony43f425d2012-02-26 12:58:58 +00004452
anthony8226e722012-04-05 14:25:46 +00004453 size=0;
4454 node=cli_wand->image_list_stack;
4455 for ( ; node != (Stack *)NULL; node=node->next)
4456 size++;
4457 if ( size >= MAX_STACK_DEPTH )
4458 CLIWandExceptionReturn(OptionError,"ParenthesisNestedTooDeeply",option);
4459 node=(Stack *) AcquireMagickMemory(sizeof(*node));
4460 if (node == (Stack *) NULL)
4461 CLIWandExceptionReturn(ResourceLimitFatalError,
4462 "MemoryAllocationFailed",option);
4463 node->data = (void *)cli_wand->wand.images;
4464 cli_wand->wand.images = NewImageList();
4465 node->next = cli_wand->image_list_stack;
4466 cli_wand->image_list_stack = node;
anthony43f425d2012-02-26 12:58:58 +00004467
anthony8226e722012-04-05 14:25:46 +00004468 /* handle respect-parenthesis */
4469 if (IfMagickTrue(IsStringTrue(GetImageOption(cli_wand->wand.image_info,
4470 "respect-parenthesis"))))
4471 option="{"; /* fall-thru so as to push image settings too */
4472 else
anthony43f425d2012-02-26 12:58:58 +00004473 return;
anthony8226e722012-04-05 14:25:46 +00004474 }
4475 if (LocaleCompare("{",option) == 0) {
4476 /* stack 'push' of image_info settings */
4477 Stack
4478 *node;
anthony43f425d2012-02-26 12:58:58 +00004479
anthony8226e722012-04-05 14:25:46 +00004480 size_t
4481 size;
anthony43f425d2012-02-26 12:58:58 +00004482
anthony8226e722012-04-05 14:25:46 +00004483 size=0;
4484 node=cli_wand->image_info_stack;
4485 for ( ; node != (Stack *)NULL; node=node->next)
4486 size++;
4487 if ( size >= MAX_STACK_DEPTH )
4488 CLIWandExceptionReturn(OptionError,"CurlyBracesNestedTooDeeply",option);
4489 node=(Stack *) AcquireMagickMemory(sizeof(*node));
4490 if (node == (Stack *) NULL)
4491 CLIWandExceptionReturn(ResourceLimitFatalError,
4492 "MemoryAllocationFailed",option);
anthony43f425d2012-02-26 12:58:58 +00004493
anthony8226e722012-04-05 14:25:46 +00004494 node->data = (void *)cli_wand->wand.image_info;
4495 cli_wand->wand.image_info = CloneImageInfo(cli_wand->wand.image_info);
4496 if (cli_wand->wand.image_info == (ImageInfo *)NULL) {
4497 CLIWandException(ResourceLimitFatalError,"MemoryAllocationFailed",
4498 option);
anthony43f425d2012-02-26 12:58:58 +00004499 cli_wand->wand.image_info = (ImageInfo *)node->data;
4500 node = (Stack *)RelinquishMagickMemory(node);
anthony43f425d2012-02-26 12:58:58 +00004501 return;
4502 }
anthony8226e722012-04-05 14:25:46 +00004503
4504 node->next = cli_wand->image_info_stack;
4505 cli_wand->image_info_stack = node;
4506
4507 return;
4508 }
4509 if (LocaleCompare(")",option) == 0) {
4510 /* pop images from stack */
4511 Stack
4512 *node;
4513
4514 node = (Stack *)cli_wand->image_list_stack;
4515 if ( node == (Stack *)NULL)
4516 CLIWandExceptionReturn(OptionError,"UnbalancedParenthesis",option);
4517 cli_wand->image_list_stack = node->next;
4518
4519 AppendImageToList((Image **)&node->data,cli_wand->wand.images);
4520 cli_wand->wand.images= (Image *)node->data;
4521 node = (Stack *)RelinquishMagickMemory(node);
4522
4523 /* handle respect-parenthesis - of the previous 'pushed' settings */
4524 node = cli_wand->image_info_stack;
4525 if ( node != (Stack *)NULL)
4526 {
4527 if (IfMagickTrue(IsStringTrue(GetImageOption(
4528 cli_wand->wand.image_info,"respect-parenthesis"))))
4529 option="}"; /* fall-thru so as to pop image settings too */
4530 else
4531 return;
4532 }
4533 else
4534 return;
4535 }
4536 if (LocaleCompare("}",option) == 0) {
4537 /* pop image_info settings from stack */
4538 Stack
4539 *node;
4540
4541 node = (Stack *)cli_wand->image_info_stack;
4542 if ( node == (Stack *)NULL)
4543 CLIWandExceptionReturn(OptionError,"UnbalancedCurlyBraces",option);
4544 cli_wand->image_info_stack = node->next;
4545
4546 (void) DestroyImageInfo(cli_wand->wand.image_info);
4547 cli_wand->wand.image_info = (ImageInfo *)node->data;
4548 node = (Stack *)RelinquishMagickMemory(node);
4549
4550 GetDrawInfo(cli_wand->wand.image_info, cli_wand->draw_info);
4551 cli_wand->quantize_info=DestroyQuantizeInfo(cli_wand->quantize_info);
4552 cli_wand->quantize_info=AcquireQuantizeInfo(cli_wand->wand.image_info);
4553
4554 return;
4555 }
anthonyce8dcb32012-03-21 13:20:31 +00004556 if (LocaleCompare("clone",option+1) == 0) {
anthony43f425d2012-02-26 12:58:58 +00004557 Image
4558 *new_images;
4559
4560 if (*option == '+')
anthony24aa8822012-03-11 00:56:06 +00004561 arg1="-1";
anthony7bcfe7f2012-03-30 14:01:22 +00004562 if (IfMagickFalse(IsSceneGeometry(arg1,MagickFalse)))
anthony92c93bd2012-03-19 14:02:47 +00004563 CLIWandExceptionReturn(OptionError,"InvalidArgument",option);
anthony43f425d2012-02-26 12:58:58 +00004564 if ( cli_wand->image_list_stack == (Stack *)NULL)
anthony92c93bd2012-03-19 14:02:47 +00004565 CLIWandExceptionReturn(OptionError,"UnableToCloneImage",option);
anthony43f425d2012-02-26 12:58:58 +00004566 new_images = (Image *)cli_wand->image_list_stack->data;
4567 if (new_images == (Image *) NULL)
anthony92c93bd2012-03-19 14:02:47 +00004568 CLIWandExceptionReturn(OptionError,"UnableToCloneImage",option);
4569 new_images=CloneImages(new_images,arg1,_exception);
anthony43f425d2012-02-26 12:58:58 +00004570 if (new_images == (Image *) NULL)
anthony92c93bd2012-03-19 14:02:47 +00004571 CLIWandExceptionReturn(OptionError,"NoSuchImage",option);
anthony8226e722012-04-05 14:25:46 +00004572 AppendImageToList(&_images,new_images);
anthony43f425d2012-02-26 12:58:58 +00004573 return;
4574 }
anthony52bef752012-03-27 13:54:47 +00004575 /*
4576 Informational Operations
4577 */
anthony0ea037a2012-04-03 12:14:39 +00004578 if (LocaleCompare("version",option+1) == 0) {
anthony8226e722012-04-05 14:25:46 +00004579 (void) FormatLocaleFile(stdout,"Version: %s\n",
4580 GetMagickVersion((size_t *) NULL));
4581 (void) FormatLocaleFile(stdout,"Copyright: %s\n",
4582 GetMagickCopyright());
4583 (void) FormatLocaleFile(stdout,"Features: %s\n\n",
4584 GetMagickFeatures());
4585 return;
4586 }
anthonyce8dcb32012-03-21 13:20:31 +00004587 if (LocaleCompare("list",option+1) == 0) {
anthony8226e722012-04-05 14:25:46 +00004588 /* FUTURE: This should really be built into the MagickCore
4589 It does not actually require a cli-wand or and images!
4590 */
4591 ssize_t
4592 list;
anthony43f425d2012-02-26 12:58:58 +00004593
anthony8226e722012-04-05 14:25:46 +00004594 list=ParseCommandOption(MagickListOptions,MagickFalse,arg1);
4595 if ( list < 0 ) {
4596 CLIWandExceptionArg(OptionError,"UnrecognizedListType",option,arg1);
anthony43f425d2012-02-26 12:58:58 +00004597 return;
4598 }
anthony8226e722012-04-05 14:25:46 +00004599 switch (list)
4600 {
4601 case MagickCoderOptions:
4602 {
4603 (void) ListCoderInfo((FILE *) NULL,_exception);
4604 break;
4605 }
4606 case MagickColorOptions:
4607 {
4608 (void) ListColorInfo((FILE *) NULL,_exception);
4609 break;
4610 }
4611 case MagickConfigureOptions:
4612 {
4613 (void) ListConfigureInfo((FILE *) NULL,_exception);
4614 break;
4615 }
4616 case MagickDelegateOptions:
4617 {
4618 (void) ListDelegateInfo((FILE *) NULL,_exception);
4619 break;
4620 }
4621 case MagickFontOptions:
4622 {
4623 (void) ListTypeInfo((FILE *) NULL,_exception);
4624 break;
4625 }
4626 case MagickFormatOptions:
4627 (void) ListMagickInfo((FILE *) NULL,_exception);
4628 break;
4629 case MagickLocaleOptions:
4630 (void) ListLocaleInfo((FILE *) NULL,_exception);
4631 break;
4632 case MagickLogOptions:
4633 (void) ListLogInfo((FILE *) NULL,_exception);
4634 break;
4635 case MagickMagicOptions:
4636 (void) ListMagicInfo((FILE *) NULL,_exception);
4637 break;
4638 case MagickMimeOptions:
4639 (void) ListMimeInfo((FILE *) NULL,_exception);
4640 break;
4641 case MagickModuleOptions:
4642 (void) ListModuleInfo((FILE *) NULL,_exception);
4643 break;
4644 case MagickPolicyOptions:
4645 (void) ListPolicyInfo((FILE *) NULL,_exception);
4646 break;
4647 case MagickResourceOptions:
4648 (void) ListMagickResourceInfo((FILE *) NULL,_exception);
4649 break;
4650 case MagickThresholdOptions:
4651 (void) ListThresholdMaps((FILE *) NULL,_exception);
4652 break;
4653 default:
4654 (void) ListCommandOptions((FILE *) NULL,(CommandOption) list,
4655 _exception);
4656 break;
4657 }
4658 return;
4659 }
anthony43f425d2012-02-26 12:58:58 +00004660
4661#if 0
anthony43f425d2012-02-26 12:58:58 +00004662 // Other 'special' options this should handle
anthony8226e722012-04-05 14:25:46 +00004663 // "region"
anthony43f425d2012-02-26 12:58:58 +00004664 if ( ( process_flags & ProcessUnknownOptionError ) != 0 )
anthony43f425d2012-02-26 12:58:58 +00004665#endif
anthonyebb73a22012-03-22 14:25:52 +00004666 CLIWandException(OptionError,"UnrecognizedOption",option);
anthony43f425d2012-02-26 12:58:58 +00004667
anthony8226e722012-04-05 14:25:46 +00004668#undef _image_info
4669#undef _images
anthony92c93bd2012-03-19 14:02:47 +00004670#undef _exception
anthony8226e722012-04-05 14:25:46 +00004671#undef IfNormalOp
4672#undef IfPlusOp
anthony43f425d2012-02-26 12:58:58 +00004673}