blob: 9ceb4dc41351e367169d3281ca7209b62bfe0f6c [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"
anthonyfd706f92012-01-19 04:22:02 +000053#include "MagickWand/operation.h"
anthony2052d272012-02-28 12:48:29 +000054#include "MagickWand/operation-private.h"
anthony43f425d2012-02-26 12:58:58 +000055#include "MagickWand/wand.h"
anthony805a2d42011-09-25 08:25:12 +000056#include "MagickCore/monitor-private.h"
57#include "MagickCore/thread-private.h"
58#include "MagickCore/string-private.h"
59
60/*
61 Define declarations.
62*/
anthonyafa3dfc2012-03-03 11:31:30 +000063#define USE_WAND_METHODS 0
64#define MAX_STACK_DEPTH 32
65#define UNDEFINED_COMPRESSION_QUALITY 0UL
66
anthony805a2d42011-09-25 08:25:12 +000067/*
68 Constant declaration. (temporary exports)
69*/
70static const char
71 BackgroundColor[] = "#fff", /* white */
anthony72feaa62012-01-17 06:46:23 +000072 BorderColor[] = "#dfdfdf", /* sRGB gray */
73 MatteColor[] = "#bdbdbd"; /* slightly darker gray */
anthony805a2d42011-09-25 08:25:12 +000074
75/*
76** Function to report on the progress of image operations
77*/
78static MagickBooleanType MonitorProgress(const char *text,
79 const MagickOffsetType offset,const MagickSizeType extent,
anthony43f425d2012-02-26 12:58:58 +000080 void *wand_unused(cli_wandent_data))
anthony805a2d42011-09-25 08:25:12 +000081{
82 char
83 message[MaxTextExtent],
84 tag[MaxTextExtent];
85
86 const char
87 *locale_message;
88
89 register char
90 *p;
91
92 if (extent < 2)
93 return(MagickTrue);
94 (void) CopyMagickMemory(tag,text,MaxTextExtent);
95 p=strrchr(tag,'/');
96 if (p != (char *) NULL)
97 *p='\0';
98 (void) FormatLocaleString(message,MaxTextExtent,"Monitor/%s",tag);
99 locale_message=GetLocaleMessage(message);
100 if (locale_message == message)
101 locale_message=tag;
102 if (p == (char *) NULL)
103 (void) FormatLocaleFile(stderr,"%s: %ld of %lu, %02ld%% complete\r",
104 locale_message,(long) offset,(unsigned long) extent,(long)
105 (100L*offset/(extent-1)));
106 else
107 (void) FormatLocaleFile(stderr,"%s[%s]: %ld of %lu, %02ld%% complete\r",
108 locale_message,p+1,(long) offset,(unsigned long) extent,(long)
109 (100L*offset/(extent-1)));
110 if (offset == (MagickOffsetType) (extent-1))
111 (void) FormatLocaleFile(stderr,"\n");
112 (void) fflush(stderr);
113 return(MagickTrue);
114}
115
116/*
117** GetImageCache() will read an image into a image cache if not already
118** present then return the image that is in the cache under that filename.
119*/
120static inline Image *GetImageCache(const ImageInfo *image_info,const char *path,
121 ExceptionInfo *exception)
122{
123 char
124 key[MaxTextExtent];
125
126 ExceptionInfo
127 *sans_exception;
128
129 Image
130 *image;
131
132 ImageInfo
133 *read_info;
134
135 (void) FormatLocaleString(key,MaxTextExtent,"cache:%s",path);
136 sans_exception=AcquireExceptionInfo();
137 image=(Image *) GetImageRegistry(ImageRegistryType,key,sans_exception);
138 sans_exception=DestroyExceptionInfo(sans_exception);
139 if (image != (Image *) NULL)
140 return(image);
141 read_info=CloneImageInfo(image_info);
142 (void) CopyMagickString(read_info->filename,path,MaxTextExtent);
143 image=ReadImage(read_info,exception);
144 read_info=DestroyImageInfo(read_info);
145 if (image != (Image *) NULL)
146 (void) SetImageRegistry(ImageRegistryType,key,image,exception);
147 return(image);
148}
149
150/*
anthonya89dd172011-10-04 13:29:35 +0000151 SparseColorOption() parse the complex -sparse-color argument into an
152 an array of floating point values than call SparseColorImage().
153 Argument is a complex mix of floating-point pixel coodinates, and color
154 specifications (or direct floating point numbers). The number of floats
155 needed to represent a color varies depending on teh current channel
156 setting.
anthony43f425d2012-02-26 12:58:58 +0000157
158 This really should be in MagickCore, so that other API's can make use of it.
anthony805a2d42011-09-25 08:25:12 +0000159*/
160static Image *SparseColorOption(const Image *image,
161 const SparseColorMethod method,const char *arguments,
anthony31f1bf72012-01-30 12:37:22 +0000162 ExceptionInfo *exception)
anthony805a2d42011-09-25 08:25:12 +0000163{
164 char
165 token[MaxTextExtent];
166
167 const char
168 *p;
169
170 double
171 *sparse_arguments;
172
173 Image
174 *sparse_image;
175
176 PixelInfo
177 color;
178
179 MagickBooleanType
180 error;
181
182 register size_t
183 x;
184
185 size_t
186 number_arguments,
187 number_colors;
188
189 assert(image != (Image *) NULL);
190 assert(image->signature == MagickSignature);
191 if (image->debug != MagickFalse)
192 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
193 assert(exception != (ExceptionInfo *) NULL);
194 assert(exception->signature == MagickSignature);
195 /*
196 Limit channels according to image - and add up number of color channel.
197 */
198 number_colors=0;
199 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
200 number_colors++;
201 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
202 number_colors++;
203 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
204 number_colors++;
205 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
206 (image->colorspace == CMYKColorspace))
207 number_colors++;
208 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
209 (image->matte != MagickFalse))
210 number_colors++;
211
212 /*
213 Read string, to determine number of arguments needed,
214 */
215 p=arguments;
216 x=0;
217 while( *p != '\0' )
218 {
219 GetMagickToken(p,&p,token);
220 if ( token[0] == ',' ) continue;
anthony31f1bf72012-01-30 12:37:22 +0000221 if ( isalpha((int) token[0]) || token[0] == '#' )
222 x += number_colors; /* color argument found */
anthonyce8dcb32012-03-21 13:20:31 +0000223 else
anthony805a2d42011-09-25 08:25:12 +0000224 x++; /* floating point argument */
anthony805a2d42011-09-25 08:25:12 +0000225 }
226 error=MagickTrue;
anthony31f1bf72012-01-30 12:37:22 +0000227 /* control points and color values */
228 error = ( x % (2+number_colors) != 0 ) ? MagickTrue : MagickFalse;
229 number_arguments=x;
anthony805a2d42011-09-25 08:25:12 +0000230 if ( error ) {
231 (void) ThrowMagickException(exception,GetMagickModule(),
anthony43f425d2012-02-26 12:58:58 +0000232 OptionError, "InvalidArgument", "'%s': %s", "sparse-color",
anthony805a2d42011-09-25 08:25:12 +0000233 "Invalid number of Arguments");
234 return( (Image *)NULL);
235 }
236
237 /* Allocate and fill in the floating point arguments */
238 sparse_arguments=(double *) AcquireQuantumMemory(number_arguments,
239 sizeof(*sparse_arguments));
240 if (sparse_arguments == (double *) NULL) {
241 (void) ThrowMagickException(exception,GetMagickModule(),ResourceLimitError,
242 "MemoryAllocationFailed","%s","SparseColorOption");
243 return( (Image *)NULL);
244 }
245 (void) ResetMagickMemory(sparse_arguments,0,number_arguments*
246 sizeof(*sparse_arguments));
247 p=arguments;
248 x=0;
249 while( *p != '\0' && x < number_arguments ) {
250 /* X coordinate */
251 token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token);
252 if ( token[0] == '\0' ) break;
253 if ( isalpha((int) token[0]) || token[0] == '#' ) {
254 (void) ThrowMagickException(exception,GetMagickModule(),
anthony43f425d2012-02-26 12:58:58 +0000255 OptionError, "InvalidArgument", "'%s': %s", "sparse-color",
anthony805a2d42011-09-25 08:25:12 +0000256 "Color found, instead of X-coord");
257 error = MagickTrue;
258 break;
259 }
cristydbdd0e32011-11-04 23:29:40 +0000260 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +0000261 /* Y coordinate */
262 token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token);
263 if ( token[0] == '\0' ) break;
264 if ( isalpha((int) token[0]) || token[0] == '#' ) {
265 (void) ThrowMagickException(exception,GetMagickModule(),
anthony43f425d2012-02-26 12:58:58 +0000266 OptionError, "InvalidArgument", "'%s': %s", "sparse-color",
anthony805a2d42011-09-25 08:25:12 +0000267 "Color found, instead of Y-coord");
268 error = MagickTrue;
269 break;
270 }
cristydbdd0e32011-11-04 23:29:40 +0000271 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
anthony31f1bf72012-01-30 12:37:22 +0000272 /* color name or function given in string argument */
273 token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token);
274 if ( token[0] == '\0' ) break;
275 if ( isalpha((int) token[0]) || token[0] == '#' ) {
276 /* Color string given */
277 (void) QueryColorCompliance(token,AllCompliance,&color,
278 exception);
279 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
280 sparse_arguments[x++] = QuantumScale*color.red;
281 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
282 sparse_arguments[x++] = QuantumScale*color.green;
283 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
284 sparse_arguments[x++] = QuantumScale*color.blue;
285 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
286 (image->colorspace == CMYKColorspace))
287 sparse_arguments[x++] = QuantumScale*color.black;
288 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
289 (image->matte != MagickFalse))
290 sparse_arguments[x++] = QuantumScale*color.alpha;
anthony805a2d42011-09-25 08:25:12 +0000291 }
anthony31f1bf72012-01-30 12:37:22 +0000292 else {
293 /* Colors given as a set of floating point values - experimental */
294 /* NB: token contains the first floating point value to use! */
295 if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
296 {
297 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
298 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
299 break;
300 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
301 token[0] = ','; /* used this token - get another */
anthony805a2d42011-09-25 08:25:12 +0000302 }
anthony31f1bf72012-01-30 12:37:22 +0000303 if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
304 {
305 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
306 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
307 break;
308 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
309 token[0] = ','; /* used this token - get another */
310 }
311 if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
312 {
313 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
314 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
315 break;
316 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
317 token[0] = ','; /* used this token - get another */
318 }
319 if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
320 (image->colorspace == CMYKColorspace))
321 {
322 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
323 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
324 break;
325 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
326 token[0] = ','; /* used this token - get another */
327 }
328 if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
329 (image->matte != MagickFalse))
330 {
331 while ( token[0] == ',' ) GetMagickToken(p,&p,token);
332 if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
333 break;
334 sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
335 token[0] = ','; /* used this token - get another */
anthony805a2d42011-09-25 08:25:12 +0000336 }
337 }
338 }
339 if ( number_arguments != x && !error ) {
340 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
anthony43f425d2012-02-26 12:58:58 +0000341 "InvalidArgument","'%s': %s","sparse-color","Argument Parsing Error");
anthony805a2d42011-09-25 08:25:12 +0000342 sparse_arguments=(double *) RelinquishMagickMemory(sparse_arguments);
343 return( (Image *)NULL);
344 }
345 if ( error )
346 return( (Image *)NULL);
347
anthony31f1bf72012-01-30 12:37:22 +0000348 /* Call the Sparse Color Interpolation function with the parsed arguments */
anthony805a2d42011-09-25 08:25:12 +0000349 sparse_image=SparseColorImage(image,method,number_arguments,sparse_arguments,
350 exception);
351 sparse_arguments=(double *) RelinquishMagickMemory(sparse_arguments);
352 return( sparse_image );
353}
354
355/*
356%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
357% %
358% %
359% %
anthony43f425d2012-02-26 12:58:58 +0000360+ A c q u i r e W a n d C L I %
anthony805a2d42011-09-25 08:25:12 +0000361% %
362% %
363% %
364%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
365%
anthony43f425d2012-02-26 12:58:58 +0000366% AcquireMagickCLI() creates a new CLI wand (an expanded form of Magick
367% Wand). The given image_info and exception is included as is if provided.
anthony805a2d42011-09-25 08:25:12 +0000368%
anthony43f425d2012-02-26 12:58:58 +0000369% Use DestroyMagickCLI() to dispose of the CLI wand when it is no longer
370% needed.
371%
372% The format of the NewMagickWand method is:
anthonyafa3dfc2012-03-03 11:31:30 +0000373%
anthony43f425d2012-02-26 12:58:58 +0000374% MagickCLI *AcquireMagickCLI(ImageInfo *image_info,
375% ExceptionInfo *exception)
376%
377*/
378WandExport MagickCLI *AcquireMagickCLI(ImageInfo *image_info,
379 ExceptionInfo *exception)
380{
381 MagickCLI
382 *cli_wand;
383
384 /* precaution - as per NewMagickWand() */
385 {
386 size_t depth = MAGICKCORE_QUANTUM_DEPTH;
387 const char *quantum = GetMagickQuantumDepth(&depth);
388 if (depth != MAGICKCORE_QUANTUM_DEPTH)
389 ThrowWandFatalException(WandError,"QuantumDepthMismatch",quantum);
390 }
391
392 /* allocate memory for MgaickCLI */
393 cli_wand=(MagickCLI *) AcquireMagickMemory(sizeof(*cli_wand));
394 if (cli_wand == (MagickCLI *) NULL)
395 {
396 ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
397 GetExceptionMessage(errno));
398 return((MagickCLI *)NULL);
399 }
400
401 /* Initialize Wand Part of MagickCLI
402 FUTURE: this is a repeat of code from NewMagickWand()
403 However some parts may be given fro man external source!
404 */
405 cli_wand->wand.id=AcquireWandId();
406 (void) FormatLocaleString(cli_wand->wand.name,MaxTextExtent,
407 "%s-%.20g","MagickWandCLI", (double) cli_wand->wand.id);
408 cli_wand->wand.images=NewImageList();
409 if ( image_info == (ImageInfo *)NULL)
410 cli_wand->wand.image_info=AcquireImageInfo();
411 else
412 cli_wand->wand.image_info=image_info;
413 if ( exception == (ExceptionInfo *)NULL)
414 cli_wand->wand.exception=AcquireExceptionInfo();
415 else
416 cli_wand->wand.exception=exception;
417 cli_wand->wand.debug=IsEventLogging();
418 cli_wand->wand.signature=WandSignature;
419
420 /* Initialize CLI Part of MagickCLI */
421 cli_wand->draw_info=CloneDrawInfo(cli_wand->wand.image_info,(DrawInfo *) NULL);
422 cli_wand->quantize_info=AcquireQuantizeInfo(cli_wand->wand.image_info);
423 cli_wand->image_list_stack=(Stack *)NULL;
424 cli_wand->image_info_stack=(Stack *)NULL;
anthony5330ae02012-03-20 14:17:01 +0000425 cli_wand->location="'%s'"; /* option location not known by default */
426 cli_wand->location2="'%s' '%s'";
anthony319dac62012-03-06 04:12:44 +0000427 cli_wand->filename=cli_wand->wand.name;
anthony1cdc5b72012-03-03 02:31:18 +0000428 cli_wand->line=0;
429 cli_wand->column=0;
anthony43f425d2012-02-26 12:58:58 +0000430 cli_wand->signature=WandSignature;
431
432 if (cli_wand->wand.debug != MagickFalse)
433 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
434 return(cli_wand);
435}
436
437/*
438%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
439% %
440% %
441% %
442+ D e s t r o y W a n d C L I %
443% %
444% %
445% %
446%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
447%
448% DestroyMagickCLI() destorys everything in a CLI wand, including image_info
449% and any exceptions, if still present in the wand.
450%
451% The format of the NewMagickWand method is:
anthonyafa3dfc2012-03-03 11:31:30 +0000452%
anthony43f425d2012-02-26 12:58:58 +0000453% MagickWand *DestroyMagickCLI()
454% Exception *exception)
455%
456*/
457WandExport MagickCLI *DestroyMagickCLI(MagickCLI *cli_wand)
458{
459 Stack
460 *node;
461
462 assert(cli_wand != (MagickCLI *) NULL);
463 assert(cli_wand->signature == WandSignature);
464 assert(cli_wand->wand.signature == WandSignature);
465 if (cli_wand->wand.debug != MagickFalse)
466 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
467
468 /* Destroy CLI part of MagickCLI */
469 if (cli_wand->draw_info != (DrawInfo *) NULL )
470 cli_wand->draw_info=DestroyDrawInfo(cli_wand->draw_info);
471 if (cli_wand->quantize_info != (QuantizeInfo *) NULL )
472 cli_wand->quantize_info=DestroyQuantizeInfo(cli_wand->quantize_info);
473 while(cli_wand->image_list_stack != (Stack *)NULL)
474 {
475 node=cli_wand->image_list_stack;
476 cli_wand->image_list_stack=node->next;
477 (void) DestroyImageList((Image *)node->data);
478 (void) RelinquishMagickMemory(node);
479 }
480 while(cli_wand->image_info_stack != (Stack *)NULL)
481 {
482 node=cli_wand->image_info_stack;
483 cli_wand->image_info_stack=node->next;
484 (void) DestroyImageInfo((ImageInfo *)node->data);
485 (void) RelinquishMagickMemory(node);
486 }
487 cli_wand->signature=(~WandSignature);
488
489 /* Destroy Wand part MagickCLI */
490 cli_wand->wand.images=DestroyImageList(cli_wand->wand.images);
491 if (cli_wand->wand.image_info != (ImageInfo *) NULL )
492 cli_wand->wand.image_info=DestroyImageInfo(cli_wand->wand.image_info);
493 if (cli_wand->wand.exception != (ExceptionInfo *) NULL )
494 cli_wand->wand.exception=DestroyExceptionInfo(cli_wand->wand.exception);
495 RelinquishWandId(cli_wand->wand.id);
496 cli_wand->wand.signature=(~WandSignature);
497
498 return((MagickCLI *)NULL);
499}
500
501/*
502%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
503% %
504% %
505% %
anthony2052d272012-02-28 12:48:29 +0000506+ C L I C a t c h E x c e p t i o n %
507% %
508% %
509% %
510%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
511%
512% CLICatchException() will report exceptions, either just non-fatal warnings
513% only, or all errors, according to 'all_execeptions' boolean argument.
514%
515% The function returns true is errors are fatal, in which case the caller
516% should abort and re-call with an 'all_exceptions' argument of true before
517% quitting.
518%
519% The cut-off level between fatal and non-fatal may be controlled by options
520% (FUTURE), but defaults to 'Error' exceptions.
521%
522% The format of the CLICatchException method is:
523%
524% MagickBooleanType CLICatchException(MagickCLI *cli_wand,
525% const MagickBooleanType all_exceptions );
526%
527*/
528WandExport MagickBooleanType CLICatchException(MagickCLI *cli_wand,
529 const MagickBooleanType all_exceptions )
530{
531 MagickBooleanType
532 status;
533 assert(cli_wand != (MagickCLI *) NULL);
534 assert(cli_wand->signature == WandSignature);
535 assert(cli_wand->wand.signature == WandSignature);
536 if (cli_wand->wand.debug != MagickFalse)
537 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
538
539 // FUTURE: '-regard_warning' should make this more sensitive.
540 // Note pipelined options may like more control over this level
541
542 status = MagickFalse;
543 if (cli_wand->wand.exception->severity > ErrorException)
544 status = MagickTrue;
545
546 if ( status == MagickFalse || all_exceptions != MagickFalse )
547 CatchException(cli_wand->wand.exception); /* output and clear exceptions */
548
549 return(status);
550}
551
552/*
553%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
554% %
555% %
556% %
anthony43f425d2012-02-26 12:58:58 +0000557+ C L I S e t t i n g O p t i o n I n f o %
558% %
559% %
560% %
561%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
562%
563% CLISettingOptionInfo() applies a single settings option into a CLI wand
564% holding the image_info, draw_info, quantize_info structures that will be
565% used when processing the images.
566%
567% These options do no require images to be present in the CLI wand for them
568% to be able to be set, in which case they will generally be applied to image
569% that are read in later
anthony80c37752012-01-16 01:03:11 +0000570%
571% Options handled by this function are listed in CommandOptions[] of
anthonyfd706f92012-01-19 04:22:02 +0000572% "option.c" that is one of "SettingOptionFlags" option flags.
anthony805a2d42011-09-25 08:25:12 +0000573%
anthony2052d272012-02-28 12:48:29 +0000574% The format of the CLISettingOptionInfo method is:
anthony1afdc7a2011-10-05 11:54:28 +0000575%
anthonyafa3dfc2012-03-03 11:31:30 +0000576% void CLISettingOptionInfo(MagickCLI *cli_wand,
anthony24aa8822012-03-11 00:56:06 +0000577% const char *option, const char *arg1)
anthony805a2d42011-09-25 08:25:12 +0000578%
579% A description of each parameter follows:
580%
anthony43f425d2012-02-26 12:58:58 +0000581% o cli_wand: structure holding settings to be applied
anthony805a2d42011-09-25 08:25:12 +0000582%
anthonydcf510d2011-10-30 13:51:40 +0000583% o option: The option string to be set
anthony805a2d42011-09-25 08:25:12 +0000584%
anthony24aa8822012-03-11 00:56:06 +0000585% o arg1: The single argument used to set this option.
anthonydcf510d2011-10-30 13:51:40 +0000586%
anthony72feaa62012-01-17 06:46:23 +0000587% Example usage...
588%
anthonyafa3dfc2012-03-03 11:31:30 +0000589% CLISettingOptionInfo(cli_wand, "-background", "Red"); // set value
590% CLISettingOptionInfo(cli_wand, "-adjoin", NULL); // set boolean
591% CLISettingOptionInfo(cli_wand, "+adjoin", NULL); // unset
anthony72feaa62012-01-17 06:46:23 +0000592%
anthony24aa8822012-03-11 00:56:06 +0000593% Or for handling command line arguments EG: +/-option ["arg1"]
anthonydcf510d2011-10-30 13:51:40 +0000594%
595% argc,argv
596% i=index in argv
597%
anthony2052d272012-02-28 12:48:29 +0000598% option_info = GetCommandOptionInfo(argv[i]);
599% count=option_info->type;
600% option_type=option_info->flags;
601%
602% if ( (option_type & SettingOperatorOptionFlags) != 0 )
anthonyafa3dfc2012-03-03 11:31:30 +0000603% CLISettingOptionInfo(cli_wand, argv[i],
604% (count>0) ? argv[i+1] : (char *)NULL);
anthonydcf510d2011-10-30 13:51:40 +0000605% i += count+1;
606%
anthony805a2d42011-09-25 08:25:12 +0000607*/
anthonyafa3dfc2012-03-03 11:31:30 +0000608WandExport void CLISettingOptionInfo(MagickCLI *cli_wand,
anthony24aa8822012-03-11 00:56:06 +0000609 const char *option,const char *arg1)
anthony805a2d42011-09-25 08:25:12 +0000610{
anthony30b912a2012-03-22 01:20:28 +0000611 ssize_t
612 parse; /* option argument parsing (string to value table lookup) */
613
anthony43f425d2012-02-26 12:58:58 +0000614 assert(cli_wand != (MagickCLI *) NULL);
615 assert(cli_wand->signature == WandSignature);
616 assert(cli_wand->wand.signature == WandSignature);
617 if (cli_wand->wand.debug != MagickFalse)
618 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
anthony1afdc7a2011-10-05 11:54:28 +0000619
anthony92c93bd2012-03-19 14:02:47 +0000620#define _image_info (cli_wand->wand.image_info)
621#define _exception (cli_wand->wand.exception)
622#define _draw_info (cli_wand->draw_info)
623#define _quantize_info (cli_wand->quantize_info)
anthony24aa8822012-03-11 00:56:06 +0000624#define IfSetOption (*option=='-')
625#define ArgBoolean (IfSetOption?MagickTrue:MagickFalse)
626#define ArgBooleanNot (IfSetOption?MagickFalse:MagickTrue)
627#define ArgBooleanString (IfSetOption?"true":"false")
628#define ArgOption(def) (IfSetOption?arg1:(const char *)(def))
anthony74b1cfc2011-10-06 12:44:16 +0000629
anthonyafa3dfc2012-03-03 11:31:30 +0000630 switch (*(option+1))
anthony805a2d42011-09-25 08:25:12 +0000631 {
632 case 'a':
633 {
anthonyafa3dfc2012-03-03 11:31:30 +0000634 if (LocaleCompare("adjoin",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000635 {
anthony92c93bd2012-03-19 14:02:47 +0000636 _image_info->adjoin = ArgBoolean;
anthony805a2d42011-09-25 08:25:12 +0000637 break;
638 }
anthonyafa3dfc2012-03-03 11:31:30 +0000639 if (LocaleCompare("affine",option+1) == 0)
anthony1afdc7a2011-10-05 11:54:28 +0000640 {
anthony92c93bd2012-03-19 14:02:47 +0000641 /* DEPRECIATED: _draw_info setting only: for -draw and -transform */
anthony74b1cfc2011-10-06 12:44:16 +0000642 if (IfSetOption)
anthony92c93bd2012-03-19 14:02:47 +0000643 (void) ParseAffineGeometry(arg1,&_draw_info->affine,_exception);
anthony74b1cfc2011-10-06 12:44:16 +0000644 else
anthony92c93bd2012-03-19 14:02:47 +0000645 GetAffineMatrix(&_draw_info->affine);
anthony1afdc7a2011-10-05 11:54:28 +0000646 break;
647 }
anthonyafa3dfc2012-03-03 11:31:30 +0000648 if (LocaleCompare("antialias",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000649 {
anthony92c93bd2012-03-19 14:02:47 +0000650 _image_info->antialias =
651 _draw_info->stroke_antialias =
652 _draw_info->text_antialias = ArgBoolean;
anthony805a2d42011-09-25 08:25:12 +0000653 break;
654 }
anthony31f1bf72012-01-30 12:37:22 +0000655 if (LocaleCompare("attenuate",option+1) == 0)
656 {
anthony92c93bd2012-03-19 14:02:47 +0000657 if (IfSetOption && IsGeometry(arg1) == MagickFalse)
658 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
659 (void) SetImageOption(_image_info,option+1,ArgOption("1.0"));
anthony31f1bf72012-01-30 12:37:22 +0000660 break;
661 }
anthonyafa3dfc2012-03-03 11:31:30 +0000662 if (LocaleCompare("authenticate",option+1) == 0)
anthonydcf510d2011-10-30 13:51:40 +0000663 {
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 'b':
670 {
anthonyafa3dfc2012-03-03 11:31:30 +0000671 if (LocaleCompare("background",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000672 {
anthony92c93bd2012-03-19 14:02:47 +0000673 /* FUTURE: both _image_info attribute & ImageOption in use!
674 _image_info only used directly for generating new images.
anthony72feaa62012-01-17 06:46:23 +0000675 SyncImageSettings() used to set per-image attribute.
676
anthony92c93bd2012-03-19 14:02:47 +0000677 FUTURE: if _image_info->background_color is not set then
anthony30b912a2012-03-22 01:20:28 +0000678 we should fall back to per-image background_color
679
680 At this time -background will 'wipe out' the per-image
681 background color!
682
683 Better error handling of QueryColorCompliance() needed.
anthony74b1cfc2011-10-06 12:44:16 +0000684 */
anthony92c93bd2012-03-19 14:02:47 +0000685 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony72feaa62012-01-17 06:46:23 +0000686 (void) QueryColorCompliance(ArgOption(BackgroundColor),AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +0000687 &_image_info->background_color,_exception);
anthony805a2d42011-09-25 08:25:12 +0000688 break;
689 }
anthonyafa3dfc2012-03-03 11:31:30 +0000690 if (LocaleCompare("bias",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000691 {
anthony74b1cfc2011-10-06 12:44:16 +0000692 /* FUTURE: bias OBSOLETED, replaced by "convolve:bias"
anthony31f1bf72012-01-30 12:37:22 +0000693 as it is actually rarely used except in direct convolve operations
694 Usage outside a direct convolve operation is actally non-sensible!
anthony72feaa62012-01-17 06:46:23 +0000695
696 SyncImageSettings() used to set per-image attribute.
anthony74b1cfc2011-10-06 12:44:16 +0000697 */
anthony5330ae02012-03-20 14:17:01 +0000698 if (IfSetOption && IsGeometry(arg1) == MagickFalse)
699 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +0000700 (void) SetImageOption(_image_info,option+1,ArgOption("0"));
anthony805a2d42011-09-25 08:25:12 +0000701 break;
702 }
anthonyafa3dfc2012-03-03 11:31:30 +0000703 if (LocaleCompare("black-point-compensation",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000704 {
anthony72feaa62012-01-17 06:46:23 +0000705 /* Used as a image chromaticity setting
706 SyncImageSettings() used to set per-image attribute.
707 */
anthony92c93bd2012-03-19 14:02:47 +0000708 (void) SetImageOption(_image_info,option+1,ArgBooleanString);
anthony805a2d42011-09-25 08:25:12 +0000709 break;
710 }
anthonyafa3dfc2012-03-03 11:31:30 +0000711 if (LocaleCompare("blue-primary",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000712 {
anthonyafbaed72011-10-26 12:05:04 +0000713 /* Image chromaticity X,Y NB: Y=X if Y not defined
714 Used by many coders including PNG
anthony72feaa62012-01-17 06:46:23 +0000715 SyncImageSettings() used to set per-image attribute.
anthonyafbaed72011-10-26 12:05:04 +0000716 */
anthony5330ae02012-03-20 14:17:01 +0000717 if (IfSetOption && IsGeometry(arg1) == MagickFalse)
718 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +0000719 (void) SetImageOption(_image_info,option+1,ArgOption("0.0"));
anthony805a2d42011-09-25 08:25:12 +0000720 break;
721 }
anthonyafa3dfc2012-03-03 11:31:30 +0000722 if (LocaleCompare("bordercolor",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000723 {
anthony92c93bd2012-03-19 14:02:47 +0000724 /* FUTURE: both _image_info attribute & ImageOption in use!
anthony72feaa62012-01-17 06:46:23 +0000725 SyncImageSettings() used to set per-image attribute.
anthony30b912a2012-03-22 01:20:28 +0000726 Better error checking of QueryColorCompliance().
anthony72feaa62012-01-17 06:46:23 +0000727 */
anthony74b1cfc2011-10-06 12:44:16 +0000728 if (IfSetOption)
anthony805a2d42011-09-25 08:25:12 +0000729 {
anthony92c93bd2012-03-19 14:02:47 +0000730 (void) SetImageOption(_image_info,option+1,arg1);
anthony24aa8822012-03-11 00:56:06 +0000731 (void) QueryColorCompliance(arg1,AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +0000732 &_image_info->border_color,_exception);
anthony24aa8822012-03-11 00:56:06 +0000733 (void) QueryColorCompliance(arg1,AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +0000734 &_draw_info->border_color,_exception);
anthony805a2d42011-09-25 08:25:12 +0000735 break;
736 }
anthony92c93bd2012-03-19 14:02:47 +0000737 (void) DeleteImageOption(_image_info,option+1);
anthony74b1cfc2011-10-06 12:44:16 +0000738 (void) QueryColorCompliance(BorderColor,AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +0000739 &_image_info->border_color,_exception);
anthony74b1cfc2011-10-06 12:44:16 +0000740 (void) QueryColorCompliance(BorderColor,AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +0000741 &_draw_info->border_color,_exception);
anthony805a2d42011-09-25 08:25:12 +0000742 break;
743 }
anthonyafa3dfc2012-03-03 11:31:30 +0000744 if (LocaleCompare("box",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000745 {
anthonyfd706f92012-01-19 04:22:02 +0000746 /* DEPRECIATED - now "undercolor" */
anthony24aa8822012-03-11 00:56:06 +0000747 CLISettingOptionInfo(cli_wand,"undercolor",arg1);
anthonyfd706f92012-01-19 04:22:02 +0000748 break;
anthony805a2d42011-09-25 08:25:12 +0000749 }
anthonyebb73a22012-03-22 14:25:52 +0000750 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +0000751 }
752 case 'c':
753 {
anthonyafa3dfc2012-03-03 11:31:30 +0000754 if (LocaleCompare("cache",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000755 {
756 MagickSizeType
757 limit;
758
anthony5330ae02012-03-20 14:17:01 +0000759 if (IfSetOption && IsGeometry(arg1) == MagickFalse)
760 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +0000761 limit=MagickResourceInfinity;
anthony24aa8822012-03-11 00:56:06 +0000762 if (LocaleCompare("unlimited",arg1) != 0)
763 limit=(MagickSizeType) SiPrefixToDoubleInterval(arg1,100.0);
anthony805a2d42011-09-25 08:25:12 +0000764 (void) SetMagickResourceLimit(MemoryResource,limit);
765 (void) SetMagickResourceLimit(MapResource,2*limit);
766 break;
767 }
anthonyafa3dfc2012-03-03 11:31:30 +0000768 if (LocaleCompare("caption",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000769 {
anthony92c93bd2012-03-19 14:02:47 +0000770 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +0000771 break;
772 }
anthonyafa3dfc2012-03-03 11:31:30 +0000773 if (LocaleCompare("channel",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000774 {
anthony30b912a2012-03-22 01:20:28 +0000775 arg1=ArgOption("default");
776 parse=ParseChannelOption(arg1);
777 if (parse < 0)
778 CLIWandExceptArgBreak(OptionError,"UnrecognizedChannelType",
779 option,arg1);
780 _image_info->channel=(ChannelType) parse;
781 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000782 break;
783 }
anthonyafa3dfc2012-03-03 11:31:30 +0000784 if (LocaleCompare("colorspace",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000785 {
anthonyafbaed72011-10-26 12:05:04 +0000786 /* Setting used for new images via AquireImage()
787 But also used as a SimpleImageOperator
788 Undefined colorspace means don't modify images on
789 read or as a operation */
anthony30b912a2012-03-22 01:20:28 +0000790 parse = ParseCommandOption(MagickColorspaceOptions,MagickFalse,
791 ArgOption("undefined"));
792 if (parse < 0)
anthony5330ae02012-03-20 14:17:01 +0000793 CLIWandExceptArgBreak(OptionError,"UnrecognizedColorspace",
794 option,arg1);
anthony30b912a2012-03-22 01:20:28 +0000795 _image_info->colorspace=(ColorspaceType) parse;
anthony805a2d42011-09-25 08:25:12 +0000796 break;
797 }
anthonyafa3dfc2012-03-03 11:31:30 +0000798 if (LocaleCompare("comment",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000799 {
anthony92c93bd2012-03-19 14:02:47 +0000800 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +0000801 break;
802 }
anthonyafa3dfc2012-03-03 11:31:30 +0000803 if (LocaleCompare("compose",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000804 {
anthony92c93bd2012-03-19 14:02:47 +0000805 /* FUTURE: _image_info should be used,
anthony72feaa62012-01-17 06:46:23 +0000806 SyncImageSettings() used to set per-image attribute. - REMOVE
807
anthonyafbaed72011-10-26 12:05:04 +0000808 This setting should NOT be used to set image 'compose'
anthony92c93bd2012-03-19 14:02:47 +0000809 "-layer" operators shoud use _image_info if defined otherwise
anthony72feaa62012-01-17 06:46:23 +0000810 they should use a per-image compose setting.
anthony965524b2011-10-07 12:34:14 +0000811 */
anthonyebb73a22012-03-22 14:25:52 +0000812 parse = ParseCommandOption(MagickComposeOptions,MagickFalse,
813 ArgOption("undefined"));
814 if (parse < 0)
815 CLIWandExceptArgBreak(OptionError,"UnrecognizedComposeOperator",
816 option,arg1);
817 _image_info->compose=(CompositeOperator) parse;
anthony92c93bd2012-03-19 14:02:47 +0000818 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +0000819 break;
820 }
anthonyafa3dfc2012-03-03 11:31:30 +0000821 if (LocaleCompare("compress",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000822 {
anthony92c93bd2012-03-19 14:02:47 +0000823 /* FUTURE: What should be used? _image_info or ImageOption ???
anthony5f867ae2011-10-09 10:28:34 +0000824 The former is more efficent, but Crisy prefers the latter!
anthony72feaa62012-01-17 06:46:23 +0000825 SyncImageSettings() used to set per-image attribute.
anthony5f867ae2011-10-09 10:28:34 +0000826
anthony92c93bd2012-03-19 14:02:47 +0000827 The coders appears to use _image_info, not Image_Option
anthony5f867ae2011-10-09 10:28:34 +0000828 however the image attribute (for save) is set from the
829 ImageOption!
anthony72feaa62012-01-17 06:46:23 +0000830
831 Note that "undefined" is a different setting to "none".
anthony5f867ae2011-10-09 10:28:34 +0000832 */
anthonyebb73a22012-03-22 14:25:52 +0000833 parse = ParseCommandOption(MagickCompressOptions,MagickFalse,
834 ArgOption("undefined"));
835 if (parse < 0)
836 CLIWandExceptArgBreak(OptionError,"UnrecognizedImageCompression",
837 option,arg1);
838 _image_info->compression=(CompressionType) parse;
anthony92c93bd2012-03-19 14:02:47 +0000839 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +0000840 break;
841 }
anthonyebb73a22012-03-22 14:25:52 +0000842 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +0000843 }
844 case 'd':
845 {
anthonyafa3dfc2012-03-03 11:31:30 +0000846 if (LocaleCompare("debug",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000847 {
anthony72feaa62012-01-17 06:46:23 +0000848 /* SyncImageSettings() used to set per-image attribute. */
anthonyebb73a22012-03-22 14:25:52 +0000849 arg1=ArgOption("none");
850 parse = ParseCommandOption(MagickLogEventOptions,MagickFalse,arg1);
851 if (parse < 0)
852 CLIWandExceptArgBreak(OptionError,"UnrecognizedEventType",
853 option,arg1);
854 (void) SetLogEventMask(arg1);
855 _image_info->debug=IsEventLogging(); /* extract logging*/
anthony43f425d2012-02-26 12:58:58 +0000856 cli_wand->wand.debug=IsEventLogging();
anthony805a2d42011-09-25 08:25:12 +0000857 break;
858 }
anthonyafa3dfc2012-03-03 11:31:30 +0000859 if (LocaleCompare("define",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000860 {
anthony24aa8822012-03-11 00:56:06 +0000861 if (LocaleNCompare(arg1,"registry:",9) == 0)
anthony805a2d42011-09-25 08:25:12 +0000862 {
anthony5f867ae2011-10-09 10:28:34 +0000863 if (IfSetOption)
anthony92c93bd2012-03-19 14:02:47 +0000864 (void) DefineImageRegistry(StringRegistryType,arg1+9,_exception);
anthony5f867ae2011-10-09 10:28:34 +0000865 else
anthony24aa8822012-03-11 00:56:06 +0000866 (void) DeleteImageRegistry(arg1+9);
anthony805a2d42011-09-25 08:25:12 +0000867 break;
868 }
anthony24aa8822012-03-11 00:56:06 +0000869 /* DefineImageOption() equals SetImageOption() but with '=' */
anthony5f867ae2011-10-09 10:28:34 +0000870 if (IfSetOption)
anthony92c93bd2012-03-19 14:02:47 +0000871 (void) DefineImageOption(_image_info,arg1);
anthonyebb73a22012-03-22 14:25:52 +0000872 else if ( DeleteImageOption(_image_info,arg1) == MagickFalse )
873 CLIWandExceptArgBreak(OptionError,"NoSuchOption",option,arg1);
anthony805a2d42011-09-25 08:25:12 +0000874 break;
875 }
anthonyafa3dfc2012-03-03 11:31:30 +0000876 if (LocaleCompare("delay",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000877 {
anthonyafbaed72011-10-26 12:05:04 +0000878 /* Only used for new images via AcquireImage()
879 FUTURE: Option should also be used for "-morph" (color morphing)
anthony5f867ae2011-10-09 10:28:34 +0000880 */
anthonyebb73a22012-03-22 14:25:52 +0000881 arg1=ArgOption("0");
882 if (IsGeometry(arg1) == MagickFalse)
883 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
884 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000885 break;
886 }
anthonyafa3dfc2012-03-03 11:31:30 +0000887 if (LocaleCompare("density",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000888 {
anthony92c93bd2012-03-19 14:02:47 +0000889 /* FUTURE: strings used in _image_info attr and _draw_info!
anthony72feaa62012-01-17 06:46:23 +0000890 Basically as density can be in a XxY form!
891
892 SyncImageSettings() used to set per-image attribute.
893 */
anthonyebb73a22012-03-22 14:25:52 +0000894 if (IfSetOption && IsGeometry(arg1) == MagickFalse)
895 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +0000896 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
897 (void) CloneString(&_image_info->density,ArgOption(NULL));
898 (void) CloneString(&_draw_info->density,_image_info->density);
anthony805a2d42011-09-25 08:25:12 +0000899 break;
900 }
anthonyafa3dfc2012-03-03 11:31:30 +0000901 if (LocaleCompare("depth",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000902 {
anthony72feaa62012-01-17 06:46:23 +0000903 /* This is also a SimpleImageOperator! for 8->16 vaule trunc !!!!
904 SyncImageSettings() used to set per-image attribute.
905 */
anthonyebb73a22012-03-22 14:25:52 +0000906 if (IfSetOption && IsGeometry(arg1) == MagickFalse)
907 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +0000908 _image_info->depth=IfSetOption?StringToUnsignedLong(arg1)
anthony5f867ae2011-10-09 10:28:34 +0000909 :MAGICKCORE_QUANTUM_DEPTH;
anthony805a2d42011-09-25 08:25:12 +0000910 break;
911 }
anthonyafa3dfc2012-03-03 11:31:30 +0000912 if (LocaleCompare("direction",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000913 {
anthony92c93bd2012-03-19 14:02:47 +0000914 /* Image Option is only used to set _draw_info */
anthonyebb73a22012-03-22 14:25:52 +0000915 arg1=ArgOption("undefined");
916 parse = ParseCommandOption(MagickDirectionOptions,MagickFalse,arg1);
917 if (parse < 0)
918 CLIWandExceptArgBreak(OptionError,"UnrecognizedDirectionType",
919 option,arg1);
920 _draw_info->direction=(DirectionType) parse;
921 (void) SetImageOption(_image_info,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +0000922 break;
923 }
anthonyafa3dfc2012-03-03 11:31:30 +0000924 if (LocaleCompare("display",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000925 {
anthony92c93bd2012-03-19 14:02:47 +0000926 (void) CloneString(&_image_info->server_name,ArgOption(NULL));
927 (void) CloneString(&_draw_info->server_name,_image_info->server_name);
anthony805a2d42011-09-25 08:25:12 +0000928 break;
929 }
anthonyafa3dfc2012-03-03 11:31:30 +0000930 if (LocaleCompare("dispose",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000931 {
anthony72feaa62012-01-17 06:46:23 +0000932 /* only used in setting new images */
anthonyebb73a22012-03-22 14:25:52 +0000933 arg1=ArgOption("undefined");
934 parse = ParseCommandOption(MagickDisposeOptions,MagickFalse,arg1);
935 if (parse < 0)
936 CLIWandExceptArgBreak(OptionError,"UnrecognizedDisposeMethod",
937 option,arg1);
anthony92c93bd2012-03-19 14:02:47 +0000938 (void) SetImageOption(_image_info,option+1,ArgOption("undefined"));
anthony805a2d42011-09-25 08:25:12 +0000939 break;
940 }
anthonyafa3dfc2012-03-03 11:31:30 +0000941 if (LocaleCompare("dither",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000942 {
anthony92c93bd2012-03-19 14:02:47 +0000943 /* _image_info attr (on/off), _quantize_info attr (on/off)
944 but also ImageInfo and _quantize_info method!
anthony72feaa62012-01-17 06:46:23 +0000945 FUTURE: merge the duality of the dithering options
946 */
anthony92c93bd2012-03-19 14:02:47 +0000947 _image_info->dither = _quantize_info->dither = ArgBoolean;
948 (void) SetImageOption(_image_info,option+1,ArgOption("none"));
949 _quantize_info->dither_method=(DitherMethod) ParseCommandOption(
anthony72feaa62012-01-17 06:46:23 +0000950 MagickDitherOptions,MagickFalse,ArgOption("none"));
anthony92c93bd2012-03-19 14:02:47 +0000951 if (_quantize_info->dither_method == NoDitherMethod)
952 _image_info->dither = _quantize_info->dither = MagickFalse;
anthony805a2d42011-09-25 08:25:12 +0000953 break;
954 }
anthonyebb73a22012-03-22 14:25:52 +0000955 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +0000956 }
957 case 'e':
958 {
anthonyafa3dfc2012-03-03 11:31:30 +0000959 if (LocaleCompare("encoding",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000960 {
anthony92c93bd2012-03-19 14:02:47 +0000961 (void) CloneString(&_draw_info->encoding,ArgOption("undefined"));
962 (void) SetImageOption(_image_info,option+1,_draw_info->encoding);
anthony805a2d42011-09-25 08:25:12 +0000963 break;
964 }
anthonyafa3dfc2012-03-03 11:31:30 +0000965 if (LocaleCompare("endian",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000966 {
anthony92c93bd2012-03-19 14:02:47 +0000967 /* Both _image_info attr and ImageInfo */
968 (void) SetImageOption(_image_info,option+1,ArgOption("undefined"));
969 _image_info->endian=(EndianType) ParseCommandOption(
anthony72feaa62012-01-17 06:46:23 +0000970 MagickEndianOptions,MagickFalse,ArgOption("undefined"));
anthony805a2d42011-09-25 08:25:12 +0000971 break;
972 }
anthonyafa3dfc2012-03-03 11:31:30 +0000973 if (LocaleCompare("extract",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000974 {
anthony92c93bd2012-03-19 14:02:47 +0000975 (void) CloneString(&_image_info->extract,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +0000976 break;
977 }
anthonyebb73a22012-03-22 14:25:52 +0000978 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +0000979 }
980 case 'f':
981 {
anthonyafa3dfc2012-03-03 11:31:30 +0000982 if (LocaleCompare("family",option+1) == 0)
anthony6dc09cd2011-10-12 08:56:49 +0000983 {
anthony92c93bd2012-03-19 14:02:47 +0000984 (void) CloneString(&_draw_info->family,ArgOption(NULL));
anthony6dc09cd2011-10-12 08:56:49 +0000985 break;
986 }
anthonyafa3dfc2012-03-03 11:31:30 +0000987 if (LocaleCompare("fill",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +0000988 {
anthony92c93bd2012-03-19 14:02:47 +0000989 /* Set "fill" OR "fill-pattern" in _draw_info
anthonyfd706f92012-01-19 04:22:02 +0000990 The original fill color is preserved if a fill-pattern is given.
991 That way it does not effect other operations that directly using
992 the fill color and, can be retored using "+tile".
anthonyafbaed72011-10-26 12:05:04 +0000993 */
anthony6dc09cd2011-10-12 08:56:49 +0000994 const char
anthony72feaa62012-01-17 06:46:23 +0000995 *value;
996
997 MagickBooleanType
998 status;
anthony6dc09cd2011-10-12 08:56:49 +0000999
1000 ExceptionInfo
1001 *sans;
1002
anthonyfd706f92012-01-19 04:22:02 +00001003 PixelInfo
1004 color;
1005
anthony72feaa62012-01-17 06:46:23 +00001006 value = ArgOption("none");
anthony92c93bd2012-03-19 14:02:47 +00001007 (void) SetImageOption(_image_info,option+1,value);
1008 if (_draw_info->fill_pattern != (Image *) NULL)
1009 _draw_info->fill_pattern=DestroyImage(_draw_info->fill_pattern);
anthony72feaa62012-01-17 06:46:23 +00001010
1011 /* is it a color or a image? -- ignore exceptions */
1012 sans=AcquireExceptionInfo();
anthonyfd706f92012-01-19 04:22:02 +00001013 status=QueryColorCompliance(value,AllCompliance,&color,sans);
anthony72feaa62012-01-17 06:46:23 +00001014 sans=DestroyExceptionInfo(sans);
anthonyfd706f92012-01-19 04:22:02 +00001015
anthony6dc09cd2011-10-12 08:56:49 +00001016 if (status == MagickFalse)
anthony92c93bd2012-03-19 14:02:47 +00001017 _draw_info->fill_pattern=GetImageCache(_image_info,value,_exception);
anthonyfd706f92012-01-19 04:22:02 +00001018 else
anthony92c93bd2012-03-19 14:02:47 +00001019 _draw_info->fill=color;
anthony805a2d42011-09-25 08:25:12 +00001020 break;
1021 }
anthonyafa3dfc2012-03-03 11:31:30 +00001022 if (LocaleCompare("filter",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001023 {
anthony72feaa62012-01-17 06:46:23 +00001024 /* SyncImageSettings() used to set per-image attribute. */
anthony92c93bd2012-03-19 14:02:47 +00001025 (void) SetImageOption(_image_info,option+1,ArgOption("undefined"));
anthony805a2d42011-09-25 08:25:12 +00001026 break;
1027 }
anthonyafa3dfc2012-03-03 11:31:30 +00001028 if (LocaleCompare("font",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001029 {
anthony92c93bd2012-03-19 14:02:47 +00001030 (void) CloneString(&_draw_info->font,ArgOption(NULL));
1031 (void) CloneString(&_image_info->font,_draw_info->font);
anthony805a2d42011-09-25 08:25:12 +00001032 break;
1033 }
anthonyafa3dfc2012-03-03 11:31:30 +00001034 if (LocaleCompare("format",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001035 {
anthonydcf510d2011-10-30 13:51:40 +00001036 /* FUTURE: why the ping test, you could set ping after this! */
1037 /*
anthony805a2d42011-09-25 08:25:12 +00001038 register const char
1039 *q;
1040
anthony24aa8822012-03-11 00:56:06 +00001041 for (q=strchr(arg1,'%'); q != (char *) NULL; q=strchr(q+1,'%'))
anthony805a2d42011-09-25 08:25:12 +00001042 if (strchr("Agkrz@[#",*(q+1)) != (char *) NULL)
anthony92c93bd2012-03-19 14:02:47 +00001043 _image_info->ping=MagickFalse;
anthonydcf510d2011-10-30 13:51:40 +00001044 */
anthony92c93bd2012-03-19 14:02:47 +00001045 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +00001046 break;
1047 }
anthonyafa3dfc2012-03-03 11:31:30 +00001048 if (LocaleCompare("fuzz",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001049 {
anthony72feaa62012-01-17 06:46:23 +00001050 /* Option used to set image fuzz! unless blank canvas (from color)
anthonydcf510d2011-10-30 13:51:40 +00001051 Image attribute used for color compare operations
anthony72feaa62012-01-17 06:46:23 +00001052 SyncImageSettings() used to set per-image attribute.
1053
anthony92c93bd2012-03-19 14:02:47 +00001054 Can't find anything else using _image_info->fuzz directly!
anthony6613bf32011-10-15 07:24:44 +00001055 */
1056 if (IfSetOption)
cristy947cb4c2011-10-20 18:41:46 +00001057 {
anthony92c93bd2012-03-19 14:02:47 +00001058 _image_info->fuzz=StringToDoubleInterval(arg1,(double)
anthony80c37752012-01-16 01:03:11 +00001059 QuantumRange+1.0);
anthony92c93bd2012-03-19 14:02:47 +00001060 (void) SetImageOption(_image_info,option+1,arg1);
cristy947cb4c2011-10-20 18:41:46 +00001061 break;
1062 }
anthony92c93bd2012-03-19 14:02:47 +00001063 _image_info->fuzz=0.0;
1064 (void) SetImageOption(_image_info,option+1,"0");
anthony805a2d42011-09-25 08:25:12 +00001065 break;
1066 }
anthonyebb73a22012-03-22 14:25:52 +00001067 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001068 }
1069 case 'g':
1070 {
anthonyafa3dfc2012-03-03 11:31:30 +00001071 if (LocaleCompare("gravity",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001072 {
anthony72feaa62012-01-17 06:46:23 +00001073 /* SyncImageSettings() used to set per-image attribute. */
anthony92c93bd2012-03-19 14:02:47 +00001074 (void) SetImageOption(_image_info,option+1,ArgOption("none"));
1075 _draw_info->gravity=(GravityType) ParseCommandOption(
anthony72feaa62012-01-17 06:46:23 +00001076 MagickGravityOptions,MagickFalse,ArgOption("none"));
anthony805a2d42011-09-25 08:25:12 +00001077 break;
1078 }
anthonyafa3dfc2012-03-03 11:31:30 +00001079 if (LocaleCompare("green-primary",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001080 {
anthonydcf510d2011-10-30 13:51:40 +00001081 /* Image chromaticity X,Y NB: Y=X if Y not defined
anthony72feaa62012-01-17 06:46:23 +00001082 SyncImageSettings() used to set per-image attribute.
1083 Used directly by many coders
anthonydcf510d2011-10-30 13:51:40 +00001084 */
anthony92c93bd2012-03-19 14:02:47 +00001085 (void) SetImageOption(_image_info,option+1,ArgOption("0.0"));
anthony805a2d42011-09-25 08:25:12 +00001086 break;
1087 }
anthonyebb73a22012-03-22 14:25:52 +00001088 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001089 }
1090 case 'i':
1091 {
anthonyafa3dfc2012-03-03 11:31:30 +00001092 if (LocaleCompare("intent",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001093 {
anthony72feaa62012-01-17 06:46:23 +00001094 /* Only used by coders: MIFF, MPC, BMP, PNG
anthonydcf510d2011-10-30 13:51:40 +00001095 and for image profile call to AcquireTransformThreadSet()
anthony72feaa62012-01-17 06:46:23 +00001096 SyncImageSettings() used to set per-image attribute.
anthonydcf510d2011-10-30 13:51:40 +00001097 */
anthony92c93bd2012-03-19 14:02:47 +00001098 (void) SetImageOption(_image_info,option+1,ArgOption("undefined"));
anthony805a2d42011-09-25 08:25:12 +00001099 break;
1100 }
anthonyafa3dfc2012-03-03 11:31:30 +00001101 if (LocaleCompare("interlace",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001102 {
anthony92c93bd2012-03-19 14:02:47 +00001103 /* _image_info is directly used by coders (so why an image setting?)
anthony72feaa62012-01-17 06:46:23 +00001104 SyncImageSettings() used to set per-image attribute.
anthonydcf510d2011-10-30 13:51:40 +00001105 */
anthony92c93bd2012-03-19 14:02:47 +00001106 (void) SetImageOption(_image_info,option+1,ArgOption("undefined"));
1107 _image_info->interlace=(InterlaceType) ParseCommandOption(
anthony72feaa62012-01-17 06:46:23 +00001108 MagickInterlaceOptions,MagickFalse,ArgOption("undefined"));
anthony805a2d42011-09-25 08:25:12 +00001109 break;
1110 }
anthonyafa3dfc2012-03-03 11:31:30 +00001111 if (LocaleCompare("interline-spacing",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001112 {
anthony92c93bd2012-03-19 14:02:47 +00001113 (void) SetImageOption(_image_info,option+1, ArgOption(NULL));
1114 _draw_info->interline_spacing=StringToDouble(ArgOption("0"),
anthony72feaa62012-01-17 06:46:23 +00001115 (char **) NULL);
anthony805a2d42011-09-25 08:25:12 +00001116 break;
1117 }
anthonyafa3dfc2012-03-03 11:31:30 +00001118 if (LocaleCompare("interpolate",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001119 {
anthonyfd706f92012-01-19 04:22:02 +00001120 /* SyncImageSettings() used to set per-image attribute. */
anthony92c93bd2012-03-19 14:02:47 +00001121 (void) SetImageOption(_image_info,option+1,ArgOption("undefined"));
anthony805a2d42011-09-25 08:25:12 +00001122 break;
1123 }
anthonyafa3dfc2012-03-03 11:31:30 +00001124 if (LocaleCompare("interword-spacing",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001125 {
anthony92c93bd2012-03-19 14:02:47 +00001126 (void) SetImageOption(_image_info,option+1, ArgOption(NULL));
1127 _draw_info->interword_spacing=StringToDouble(ArgOption("0"),(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +00001128 break;
1129 }
anthonyebb73a22012-03-22 14:25:52 +00001130 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001131 }
1132 case 'k':
1133 {
anthonyafa3dfc2012-03-03 11:31:30 +00001134 if (LocaleCompare("kerning",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001135 {
anthony92c93bd2012-03-19 14:02:47 +00001136 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1137 _draw_info->kerning=StringToDouble(ArgOption("0"),(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +00001138 break;
1139 }
anthonyebb73a22012-03-22 14:25:52 +00001140 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001141 }
1142 case 'l':
1143 {
anthonyafa3dfc2012-03-03 11:31:30 +00001144 if (LocaleCompare("label",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001145 {
anthony72feaa62012-01-17 06:46:23 +00001146 /* only used for new images - not in SyncImageOptions() */
anthony92c93bd2012-03-19 14:02:47 +00001147 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +00001148 break;
1149 }
anthonyafa3dfc2012-03-03 11:31:30 +00001150 if (LocaleCompare("log",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001151 {
anthonydcf510d2011-10-30 13:51:40 +00001152 if (IfSetOption)
anthony24aa8822012-03-11 00:56:06 +00001153 (void) SetLogFormat(arg1);
anthony805a2d42011-09-25 08:25:12 +00001154 break;
1155 }
anthonyafa3dfc2012-03-03 11:31:30 +00001156 if (LocaleCompare("loop",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001157 {
anthony72feaa62012-01-17 06:46:23 +00001158 /* SyncImageSettings() used to set per-image attribute. */
anthony92c93bd2012-03-19 14:02:47 +00001159 (void) SetImageOption(_image_info,option+1,ArgOption("0"));
anthony805a2d42011-09-25 08:25:12 +00001160 break;
1161 }
anthonyebb73a22012-03-22 14:25:52 +00001162 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001163 }
1164 case 'm':
1165 {
anthonyafa3dfc2012-03-03 11:31:30 +00001166 if (LocaleCompare("mattecolor",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001167 {
anthony72feaa62012-01-17 06:46:23 +00001168 /* SyncImageSettings() used to set per-image attribute. */
anthony92c93bd2012-03-19 14:02:47 +00001169 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony72feaa62012-01-17 06:46:23 +00001170 (void) QueryColorCompliance(ArgOption(MatteColor),AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +00001171 &_image_info->matte_color,_exception);
anthony805a2d42011-09-25 08:25:12 +00001172 break;
1173 }
anthonyafa3dfc2012-03-03 11:31:30 +00001174 if (LocaleCompare("monitor",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001175 {
anthony92c93bd2012-03-19 14:02:47 +00001176 (void) SetImageInfoProgressMonitor(_image_info, IfSetOption?
anthony31f1bf72012-01-30 12:37:22 +00001177 MonitorProgress: (MagickProgressMonitor) NULL, (void *) NULL);
anthony805a2d42011-09-25 08:25:12 +00001178 break;
1179 }
anthonyafa3dfc2012-03-03 11:31:30 +00001180 if (LocaleCompare("monochrome",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001181 {
anthony24aa8822012-03-11 00:56:06 +00001182 /* Setting (used by some input coders!) -- why?
1183 Warning: This is also Special '-type' SimpleOperator
anthony72feaa62012-01-17 06:46:23 +00001184 */
anthony92c93bd2012-03-19 14:02:47 +00001185 _image_info->monochrome= ArgBoolean;
anthony805a2d42011-09-25 08:25:12 +00001186 break;
1187 }
anthonyebb73a22012-03-22 14:25:52 +00001188 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001189 }
1190 case 'o':
1191 {
anthonyafa3dfc2012-03-03 11:31:30 +00001192 if (LocaleCompare("orient",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001193 {
anthony72feaa62012-01-17 06:46:23 +00001194 /* Is not used when defining for new images.
anthonydcf510d2011-10-30 13:51:40 +00001195 This makes it more of a 'operation' than a setting
anthony72feaa62012-01-17 06:46:23 +00001196 FUTURE: make set meta-data operator instead.
1197 SyncImageSettings() used to set per-image attribute.
anthonydcf510d2011-10-30 13:51:40 +00001198 */
anthony92c93bd2012-03-19 14:02:47 +00001199 (void) SetImageOption(_image_info,option+1, ArgOption(NULL));
1200 _image_info->orientation=(InterlaceType) ParseCommandOption(
anthony72feaa62012-01-17 06:46:23 +00001201 MagickOrientationOptions,MagickFalse,ArgOption("undefined"));
anthony805a2d42011-09-25 08:25:12 +00001202 break;
1203 }
anthonyebb73a22012-03-22 14:25:52 +00001204 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001205 }
1206 case 'p':
1207 {
anthonyafa3dfc2012-03-03 11:31:30 +00001208 if (LocaleCompare("page",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001209 {
anthony72feaa62012-01-17 06:46:23 +00001210 /* Only used for new images and image generators
1211 SyncImageSettings() used to set per-image attribute. ?????
1212 That last is WRONG!!!!
1213 */
anthony805a2d42011-09-25 08:25:12 +00001214 char
1215 *canonical_page,
1216 page[MaxTextExtent];
1217
1218 const char
1219 *image_option;
1220
1221 MagickStatusType
1222 flags;
1223
1224 RectangleInfo
1225 geometry;
1226
anthonydcf510d2011-10-30 13:51:40 +00001227 if (!IfSetOption)
anthony805a2d42011-09-25 08:25:12 +00001228 {
anthony92c93bd2012-03-19 14:02:47 +00001229 (void) DeleteImageOption(_image_info,option+1);
1230 (void) CloneString(&_image_info->page,(char *) NULL);
anthony805a2d42011-09-25 08:25:12 +00001231 break;
1232 }
1233 (void) ResetMagickMemory(&geometry,0,sizeof(geometry));
anthony92c93bd2012-03-19 14:02:47 +00001234 image_option=GetImageOption(_image_info,"page");
anthony805a2d42011-09-25 08:25:12 +00001235 if (image_option != (const char *) NULL)
1236 flags=ParseAbsoluteGeometry(image_option,&geometry);
anthony24aa8822012-03-11 00:56:06 +00001237 canonical_page=GetPageGeometry(arg1);
anthony805a2d42011-09-25 08:25:12 +00001238 flags=ParseAbsoluteGeometry(canonical_page,&geometry);
1239 canonical_page=DestroyString(canonical_page);
1240 (void) FormatLocaleString(page,MaxTextExtent,"%lux%lu",
1241 (unsigned long) geometry.width,(unsigned long) geometry.height);
1242 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
1243 (void) FormatLocaleString(page,MaxTextExtent,"%lux%lu%+ld%+ld",
1244 (unsigned long) geometry.width,(unsigned long) geometry.height,
1245 (long) geometry.x,(long) geometry.y);
anthony92c93bd2012-03-19 14:02:47 +00001246 (void) SetImageOption(_image_info,option+1,page);
1247 (void) CloneString(&_image_info->page,page);
anthony805a2d42011-09-25 08:25:12 +00001248 break;
1249 }
anthonyafa3dfc2012-03-03 11:31:30 +00001250 if (LocaleCompare("ping",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001251 {
anthony92c93bd2012-03-19 14:02:47 +00001252 _image_info->ping = ArgBoolean;
anthony805a2d42011-09-25 08:25:12 +00001253 break;
1254 }
anthonyafa3dfc2012-03-03 11:31:30 +00001255 if (LocaleCompare("pointsize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001256 {
anthony92c93bd2012-03-19 14:02:47 +00001257 _image_info->pointsize=_draw_info->pointsize=
anthony72feaa62012-01-17 06:46:23 +00001258 StringToDouble(ArgOption("12"),(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +00001259 break;
1260 }
anthonyafa3dfc2012-03-03 11:31:30 +00001261 if (LocaleCompare("precision",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001262 {
anthony72feaa62012-01-17 06:46:23 +00001263 (void) SetMagickPrecision(StringToInteger(ArgOption("-1")));
anthony805a2d42011-09-25 08:25:12 +00001264 break;
1265 }
anthonydcf510d2011-10-30 13:51:40 +00001266 /* FUTURE: Only the 'preview' coder appears to use this
anthonya3ef4ed2012-03-17 06:52:53 +00001267 * DEPRECIATE the coder? Leaving only the 'preview' operator.
anthonyafa3dfc2012-03-03 11:31:30 +00001268 if (LocaleCompare("preview",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001269 {
anthony92c93bd2012-03-19 14:02:47 +00001270 _image_info->preview_type=UndefinedPreview;
anthonydcf510d2011-10-30 13:51:40 +00001271 if (IfSetOption)
anthony92c93bd2012-03-19 14:02:47 +00001272 _image_info->preview_type=(PreviewType) ParseCommandOption(
anthony24aa8822012-03-11 00:56:06 +00001273 MagickPreviewOptions,MagickFalse,arg1);
anthony805a2d42011-09-25 08:25:12 +00001274 break;
1275 }
anthonydcf510d2011-10-30 13:51:40 +00001276 */
anthonyebb73a22012-03-22 14:25:52 +00001277 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001278 }
1279 case 'q':
1280 {
anthonyafa3dfc2012-03-03 11:31:30 +00001281 if (LocaleCompare("quality",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001282 {
anthony92c93bd2012-03-19 14:02:47 +00001283 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1284 _image_info->quality=UNDEFINED_COMPRESSION_QUALITY;
anthony72feaa62012-01-17 06:46:23 +00001285 if (IfSetOption)
anthony92c93bd2012-03-19 14:02:47 +00001286 _image_info->quality=StringToUnsignedLong(arg1);
anthony805a2d42011-09-25 08:25:12 +00001287 break;
1288 }
anthonyafa3dfc2012-03-03 11:31:30 +00001289 if (LocaleCompare("quantize",option+1) == 0)
anthonyafbaed72011-10-26 12:05:04 +00001290 {
anthony92c93bd2012-03-19 14:02:47 +00001291 /* Just a set direct in _quantize_info */
1292 _quantize_info->colorspace=UndefinedColorspace;
anthonyafbaed72011-10-26 12:05:04 +00001293 if (IfSetOption)
anthony92c93bd2012-03-19 14:02:47 +00001294 _quantize_info->colorspace=(ColorspaceType) ParseCommandOption(
anthony24aa8822012-03-11 00:56:06 +00001295 MagickColorspaceOptions,MagickFalse,arg1);
anthonyafbaed72011-10-26 12:05:04 +00001296 break;
1297 }
anthonyafa3dfc2012-03-03 11:31:30 +00001298 if (LocaleCompare("quiet",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001299 {
anthonydcf510d2011-10-30 13:51:40 +00001300 /* FUTURE: if two -quiet is performed you can not do +quiet! */
anthony805a2d42011-09-25 08:25:12 +00001301 static WarningHandler
1302 warning_handler = (WarningHandler) NULL;
anthony72feaa62012-01-17 06:46:23 +00001303
anthonyafbaed72011-10-26 12:05:04 +00001304 WarningHandler
1305 tmp = SetWarningHandler((WarningHandler) NULL);
anthony805a2d42011-09-25 08:25:12 +00001306
anthonyafbaed72011-10-26 12:05:04 +00001307 if ( tmp != (WarningHandler) NULL)
1308 warning_handler = tmp; /* remember the old handler */
1309 if (!IfSetOption) /* set the old handler */
1310 warning_handler=SetWarningHandler(warning_handler);
anthony805a2d42011-09-25 08:25:12 +00001311 break;
1312 }
anthonyebb73a22012-03-22 14:25:52 +00001313 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001314 }
1315 case 'r':
1316 {
anthonyafa3dfc2012-03-03 11:31:30 +00001317 if (LocaleCompare("red-primary",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001318 {
anthonydcf510d2011-10-30 13:51:40 +00001319 /* Image chromaticity X,Y NB: Y=X if Y not defined
1320 Used by many coders
anthony72feaa62012-01-17 06:46:23 +00001321 SyncImageSettings() used to set per-image attribute.
anthonydcf510d2011-10-30 13:51:40 +00001322 */
anthony92c93bd2012-03-19 14:02:47 +00001323 (void) SetImageOption(_image_info,option+1,ArgOption("0.0"));
anthony805a2d42011-09-25 08:25:12 +00001324 break;
1325 }
anthonyafa3dfc2012-03-03 11:31:30 +00001326 if (LocaleCompare("render",option+1) == 0)
anthonyafbaed72011-10-26 12:05:04 +00001327 {
anthony92c93bd2012-03-19 14:02:47 +00001328 /* _draw_info only setting */
1329 _draw_info->render= ArgBooleanNot;
anthonyafbaed72011-10-26 12:05:04 +00001330 break;
1331 }
anthonyebb73a22012-03-22 14:25:52 +00001332 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001333 }
1334 case 's':
1335 {
anthonyafa3dfc2012-03-03 11:31:30 +00001336 if (LocaleCompare("sampling-factor",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001337 {
anthonyafbaed72011-10-26 12:05:04 +00001338 /* FUTURE: should be converted to jpeg:sampling_factor */
anthony92c93bd2012-03-19 14:02:47 +00001339 (void) CloneString(&_image_info->sampling_factor,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +00001340 break;
1341 }
anthonyafa3dfc2012-03-03 11:31:30 +00001342 if (LocaleCompare("scene",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001343 {
anthony72feaa62012-01-17 06:46:23 +00001344 /* SyncImageSettings() used to set per-image attribute.
1345 What ??? Why ????
1346 */
anthony92c93bd2012-03-19 14:02:47 +00001347 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1348 _image_info->scene=StringToUnsignedLong(ArgOption("0"));
anthony805a2d42011-09-25 08:25:12 +00001349 break;
1350 }
anthonyafa3dfc2012-03-03 11:31:30 +00001351 if (LocaleCompare("seed",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001352 {
anthonyafbaed72011-10-26 12:05:04 +00001353 SeedPseudoRandomGenerator(
anthony24aa8822012-03-11 00:56:06 +00001354 IfSetOption ? (size_t) StringToUnsignedLong(arg1)
anthonyafbaed72011-10-26 12:05:04 +00001355 : (size_t) time((time_t *) NULL) );
anthony805a2d42011-09-25 08:25:12 +00001356 break;
1357 }
anthonyafa3dfc2012-03-03 11:31:30 +00001358 if (LocaleCompare("size",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001359 {
anthony92c93bd2012-03-19 14:02:47 +00001360 /* FUTURE: string in _image_info -- convert to Option ???
anthonyafbaed72011-10-26 12:05:04 +00001361 Look at the special handling for "size" in SetImageOption()
anthony74b1cfc2011-10-06 12:44:16 +00001362 */
anthony92c93bd2012-03-19 14:02:47 +00001363 (void) CloneString(&_image_info->size,ArgOption(NULL));
anthonyafbaed72011-10-26 12:05:04 +00001364 break;
1365 }
anthonyafa3dfc2012-03-03 11:31:30 +00001366 if (LocaleCompare("stretch",option+1) == 0)
anthonyafbaed72011-10-26 12:05:04 +00001367 {
anthony92c93bd2012-03-19 14:02:47 +00001368 _draw_info->stretch=(StretchType) ParseCommandOption(
anthony72feaa62012-01-17 06:46:23 +00001369 MagickStretchOptions,MagickFalse,ArgOption("undefined"));
anthony805a2d42011-09-25 08:25:12 +00001370 break;
1371 }
anthonyafa3dfc2012-03-03 11:31:30 +00001372 if (LocaleCompare("stroke",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001373 {
anthonyafbaed72011-10-26 12:05:04 +00001374 /* set stroke color OR stroke-pattern
anthonyfd706f92012-01-19 04:22:02 +00001375 UPDATE: ensure stroke color is not destroyed is a pattern
1376 is given. Just in case the color is also used for other purposes.
anthonyafbaed72011-10-26 12:05:04 +00001377 */
1378 const char
anthony72feaa62012-01-17 06:46:23 +00001379 *value;
1380
1381 MagickBooleanType
1382 status;
anthonyafbaed72011-10-26 12:05:04 +00001383
1384 ExceptionInfo
1385 *sans;
1386
anthonyfd706f92012-01-19 04:22:02 +00001387 PixelInfo
1388 color;
1389
anthony72feaa62012-01-17 06:46:23 +00001390 value = ArgOption("none");
anthony92c93bd2012-03-19 14:02:47 +00001391 (void) SetImageOption(_image_info,option+1,value);
1392 if (_draw_info->stroke_pattern != (Image *) NULL)
1393 _draw_info->stroke_pattern=DestroyImage(_draw_info->stroke_pattern);
anthony72feaa62012-01-17 06:46:23 +00001394
1395 /* is it a color or a image? -- ignore exceptions */
anthonyafbaed72011-10-26 12:05:04 +00001396 sans=AcquireExceptionInfo();
anthonyfd706f92012-01-19 04:22:02 +00001397 status=QueryColorCompliance(value,AllCompliance,&color,sans);
anthonyafbaed72011-10-26 12:05:04 +00001398 sans=DestroyExceptionInfo(sans);
anthonyfd706f92012-01-19 04:22:02 +00001399
anthonyafbaed72011-10-26 12:05:04 +00001400 if (status == MagickFalse)
anthony92c93bd2012-03-19 14:02:47 +00001401 _draw_info->stroke_pattern=GetImageCache(_image_info,value,_exception);
anthonyfd706f92012-01-19 04:22:02 +00001402 else
anthony92c93bd2012-03-19 14:02:47 +00001403 _draw_info->stroke=color;
anthony805a2d42011-09-25 08:25:12 +00001404 break;
1405 }
anthonyafa3dfc2012-03-03 11:31:30 +00001406 if (LocaleCompare("strokewidth",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001407 {
anthony92c93bd2012-03-19 14:02:47 +00001408 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1409 _draw_info->stroke_width=StringToDouble(ArgOption("1.0"),
anthony72feaa62012-01-17 06:46:23 +00001410 (char **) NULL);
anthonyafbaed72011-10-26 12:05:04 +00001411 break;
1412 }
anthonyafa3dfc2012-03-03 11:31:30 +00001413 if (LocaleCompare("style",option+1) == 0)
anthonyafbaed72011-10-26 12:05:04 +00001414 {
anthony92c93bd2012-03-19 14:02:47 +00001415 _draw_info->style=(StyleType) ParseCommandOption(MagickStyleOptions,
anthony72feaa62012-01-17 06:46:23 +00001416 MagickFalse,ArgOption("undefined"));
anthony805a2d42011-09-25 08:25:12 +00001417 break;
1418 }
anthonyafa3dfc2012-03-03 11:31:30 +00001419 if (LocaleCompare("synchronize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001420 {
anthony92c93bd2012-03-19 14:02:47 +00001421 _image_info->synchronize = ArgBoolean;
anthony805a2d42011-09-25 08:25:12 +00001422 break;
1423 }
anthonyebb73a22012-03-22 14:25:52 +00001424 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001425 }
1426 case 't':
1427 {
anthonyafa3dfc2012-03-03 11:31:30 +00001428 if (LocaleCompare("taint",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 (void) SetImageOption(_image_info,option+1,ArgBooleanString);
anthony805a2d42011-09-25 08:25:12 +00001432 break;
1433 }
anthonyafa3dfc2012-03-03 11:31:30 +00001434 if (LocaleCompare("texture",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001435 {
anthony92c93bd2012-03-19 14:02:47 +00001436 /* FUTURE: move _image_info string to option splay-tree */
1437 (void) CloneString(&_image_info->texture,ArgOption(NULL));
anthonyafbaed72011-10-26 12:05:04 +00001438 break;
1439 }
anthonyafa3dfc2012-03-03 11:31:30 +00001440 if (LocaleCompare("tile",option+1) == 0)
anthonyafbaed72011-10-26 12:05:04 +00001441 {
anthony92c93bd2012-03-19 14:02:47 +00001442 _draw_info->fill_pattern=IfSetOption
1443 ?GetImageCache(_image_info,arg1,_exception)
1444 :DestroyImage(_draw_info->fill_pattern);
anthony805a2d42011-09-25 08:25:12 +00001445 break;
1446 }
anthonyafa3dfc2012-03-03 11:31:30 +00001447 if (LocaleCompare("tile-offset",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001448 {
anthony72feaa62012-01-17 06:46:23 +00001449 /* SyncImageSettings() used to set per-image attribute. ??? */
anthony92c93bd2012-03-19 14:02:47 +00001450 (void) SetImageOption(_image_info,option+1,ArgOption("0"));
anthony805a2d42011-09-25 08:25:12 +00001451 break;
1452 }
anthonyafa3dfc2012-03-03 11:31:30 +00001453 if (LocaleCompare("transparent-color",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001454 {
anthony92c93bd2012-03-19 14:02:47 +00001455 /* FUTURE: both _image_info attribute & ImageOption in use!
1456 _image_info only used for generating new images.
anthony72feaa62012-01-17 06:46:23 +00001457 SyncImageSettings() used to set per-image attribute.
1458
anthonyafbaed72011-10-26 12:05:04 +00001459 Note that +transparent-color, means fall-back to image
1460 attribute so ImageOption is deleted, not set to a default.
1461 */
anthony92c93bd2012-03-19 14:02:47 +00001462 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony72feaa62012-01-17 06:46:23 +00001463 (void) QueryColorCompliance(ArgOption("none"),AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +00001464 &_image_info->transparent_color,_exception);
anthony805a2d42011-09-25 08:25:12 +00001465 break;
1466 }
anthonyafa3dfc2012-03-03 11:31:30 +00001467 if (LocaleCompare("treedepth",option+1) == 0)
anthony31f1bf72012-01-30 12:37:22 +00001468 {
anthony92c93bd2012-03-19 14:02:47 +00001469 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1470 _quantize_info->tree_depth=StringToUnsignedLong(ArgOption("0"));
anthony31f1bf72012-01-30 12:37:22 +00001471 break;
1472 }
anthonyafa3dfc2012-03-03 11:31:30 +00001473 if (LocaleCompare("type",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001474 {
anthony72feaa62012-01-17 06:46:23 +00001475 /* SyncImageSettings() used to set per-image attribute. */
anthony92c93bd2012-03-19 14:02:47 +00001476 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1477 _image_info->type=(ImageType) ParseCommandOption(MagickTypeOptions,
anthony72feaa62012-01-17 06:46:23 +00001478 MagickFalse,ArgOption("undefined"));
anthony805a2d42011-09-25 08:25:12 +00001479 break;
1480 }
anthonyebb73a22012-03-22 14:25:52 +00001481 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001482 }
1483 case 'u':
1484 {
anthonyafa3dfc2012-03-03 11:31:30 +00001485 if (LocaleCompare("undercolor",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001486 {
anthony92c93bd2012-03-19 14:02:47 +00001487 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony72feaa62012-01-17 06:46:23 +00001488 (void) QueryColorCompliance(ArgOption("none"),AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +00001489 &_draw_info->undercolor,_exception);
anthony805a2d42011-09-25 08:25:12 +00001490 break;
1491 }
anthonyafa3dfc2012-03-03 11:31:30 +00001492 if (LocaleCompare("units",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001493 {
anthony72feaa62012-01-17 06:46:23 +00001494 /* SyncImageSettings() used to set per-image attribute.
anthony92c93bd2012-03-19 14:02:47 +00001495 Should this effect _draw_info X and Y resolution?
anthony72feaa62012-01-17 06:46:23 +00001496 FUTURE: this probably should be part of the density setting
1497 */
anthony92c93bd2012-03-19 14:02:47 +00001498 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
1499 _image_info->units=(ResolutionType) ParseCommandOption(
anthony72feaa62012-01-17 06:46:23 +00001500 MagickResolutionOptions,MagickFalse,ArgOption("undefined"));
anthony805a2d42011-09-25 08:25:12 +00001501 break;
1502 }
anthonyebb73a22012-03-22 14:25:52 +00001503 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001504 }
1505 case 'v':
1506 {
anthonyafa3dfc2012-03-03 11:31:30 +00001507 if (LocaleCompare("verbose",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001508 {
anthony24aa8822012-03-11 00:56:06 +00001509 /* FUTURE: Remember all options become image artifacts
anthony92c93bd2012-03-19 14:02:47 +00001510 _image_info->verbose is only used by coders.
anthonyab3a50c2011-10-27 11:48:57 +00001511 */
anthony92c93bd2012-03-19 14:02:47 +00001512 (void) SetImageOption(_image_info,option+1,ArgBooleanString);
1513 _image_info->verbose= ArgBoolean;
1514 _image_info->ping=MagickFalse; /* verbose can't be a ping */
anthony805a2d42011-09-25 08:25:12 +00001515 break;
1516 }
anthonyafa3dfc2012-03-03 11:31:30 +00001517 if (LocaleCompare("view",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001518 {
anthony92c93bd2012-03-19 14:02:47 +00001519 /* FUTURE: Convert from _image_info to ImageOption
anthonyab3a50c2011-10-27 11:48:57 +00001520 Only used by coder FPX
1521 */
anthony92c93bd2012-03-19 14:02:47 +00001522 (void) CloneString(&_image_info->view,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +00001523 break;
1524 }
anthonyafa3dfc2012-03-03 11:31:30 +00001525 if (LocaleCompare("virtual-pixel",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001526 {
anthonyfd706f92012-01-19 04:22:02 +00001527 /* SyncImageSettings() used to set per-image attribute.
1528 This is VERY deep in the image caching structure.
1529 */
anthony92c93bd2012-03-19 14:02:47 +00001530 (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
anthony805a2d42011-09-25 08:25:12 +00001531 break;
1532 }
anthonyebb73a22012-03-22 14:25:52 +00001533 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001534 }
1535 case 'w':
1536 {
anthonyafa3dfc2012-03-03 11:31:30 +00001537 if (LocaleCompare("weight",option+1) == 0)
anthonyab3a50c2011-10-27 11:48:57 +00001538 {
anthony72feaa62012-01-17 06:46:23 +00001539 /* Just what does using a font 'weight' do ???
anthonydcf510d2011-10-30 13:51:40 +00001540 There is no "-list weight" output (reference manual says there is)
anthonyab3a50c2011-10-27 11:48:57 +00001541 */
anthony72feaa62012-01-17 06:46:23 +00001542 if (!IfSetOption)
1543 break;
anthony92c93bd2012-03-19 14:02:47 +00001544 _draw_info->weight=StringToUnsignedLong(arg1);
anthony24aa8822012-03-11 00:56:06 +00001545 if (LocaleCompare(arg1,"all") == 0)
anthony92c93bd2012-03-19 14:02:47 +00001546 _draw_info->weight=0;
anthony24aa8822012-03-11 00:56:06 +00001547 if (LocaleCompare(arg1,"bold") == 0)
anthony92c93bd2012-03-19 14:02:47 +00001548 _draw_info->weight=700;
anthony24aa8822012-03-11 00:56:06 +00001549 if (LocaleCompare(arg1,"bolder") == 0)
anthony92c93bd2012-03-19 14:02:47 +00001550 if (_draw_info->weight <= 800)
1551 _draw_info->weight+=100;
anthony24aa8822012-03-11 00:56:06 +00001552 if (LocaleCompare(arg1,"lighter") == 0)
anthony92c93bd2012-03-19 14:02:47 +00001553 if (_draw_info->weight >= 100)
1554 _draw_info->weight-=100;
anthony24aa8822012-03-11 00:56:06 +00001555 if (LocaleCompare(arg1,"normal") == 0)
anthony92c93bd2012-03-19 14:02:47 +00001556 _draw_info->weight=400;
anthonyab3a50c2011-10-27 11:48:57 +00001557 break;
1558 }
anthonyafa3dfc2012-03-03 11:31:30 +00001559 if (LocaleCompare("white-point",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001560 {
anthony72feaa62012-01-17 06:46:23 +00001561 /* Used as a image chromaticity setting
1562 SyncImageSettings() used to set per-image attribute.
1563 */
anthony92c93bd2012-03-19 14:02:47 +00001564 (void) SetImageOption(_image_info,option+1,ArgOption("0.0"));
anthony805a2d42011-09-25 08:25:12 +00001565 break;
1566 }
anthonyebb73a22012-03-22 14:25:52 +00001567 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001568 }
1569 default:
anthonyebb73a22012-03-22 14:25:52 +00001570 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001571 }
anthony24aa8822012-03-11 00:56:06 +00001572
anthony92c93bd2012-03-19 14:02:47 +00001573#undef _image_info
1574#undef _exception
1575#undef _draw_info
1576#undef _quantize_info
anthonyfd706f92012-01-19 04:22:02 +00001577#undef IfSetOption
anthonyfd706f92012-01-19 04:22:02 +00001578#undef ArgBoolean
anthony24aa8822012-03-11 00:56:06 +00001579#undef ArgBooleanNot
1580#undef ArgBooleanString
1581#undef ArgOption
anthonyfd706f92012-01-19 04:22:02 +00001582
anthony31f1bf72012-01-30 12:37:22 +00001583 return;
anthony805a2d42011-09-25 08:25:12 +00001584}
1585
1586/*
1587%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1588% %
1589% %
1590% %
anthony43f425d2012-02-26 12:58:58 +00001591+ 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 +00001592% %
1593% %
1594% %
1595%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1596%
anthony31f1bf72012-01-30 12:37:22 +00001597% WandSimpleOperatorImages() applys one simple image operation given to all
anthony43f425d2012-02-26 12:58:58 +00001598% the images in the CLI wand, with the settings that was previously saved in
1599% the CLI wand.
anthonydcf510d2011-10-30 13:51:40 +00001600%
1601% It is assumed that any per-image settings are up-to-date with respect to
anthony43f425d2012-02-26 12:58:58 +00001602% extra settings that were already saved in the wand.
anthony805a2d42011-09-25 08:25:12 +00001603%
anthonyd1447672012-01-19 05:33:53 +00001604% The format of the WandSimpleOperatorImage method is:
anthony805a2d42011-09-25 08:25:12 +00001605%
anthony43f425d2012-02-26 12:58:58 +00001606% void CLISimpleOperatorImages(MagickCLI *cli_wand,
anthonyafa3dfc2012-03-03 11:31:30 +00001607% const char *option, const char *arg1, const char *arg2)
anthony805a2d42011-09-25 08:25:12 +00001608%
1609% A description of each parameter follows:
1610%
anthony43f425d2012-02-26 12:58:58 +00001611% o cli_wand: structure holding settings and images to be operated on
anthony805a2d42011-09-25 08:25:12 +00001612%
anthonyfd706f92012-01-19 04:22:02 +00001613% o option: The option string for the operation
anthonydcf510d2011-10-30 13:51:40 +00001614%
anthonyfd706f92012-01-19 04:22:02 +00001615% o arg1, arg2: optional argument strings to the operation
anthony805a2d42011-09-25 08:25:12 +00001616%
anthony31f1bf72012-01-30 12:37:22 +00001617% Any problems will be added to the 'exception' entry of the given wand.
anthony805a2d42011-09-25 08:25:12 +00001618%
anthony31f1bf72012-01-30 12:37:22 +00001619% Example usage...
anthonydcf510d2011-10-30 13:51:40 +00001620%
anthonyafa3dfc2012-03-03 11:31:30 +00001621% CLISimpleOperatorImages(cli_wand, "-crop","100x100+20+30",NULL);
1622% CLISimpleOperatorImages(cli_wand, "+repage",NULL,NULL);
1623% CLISimpleOperatorImages(cli_wand, "+distort","SRT","45");
anthonyfd706f92012-01-19 04:22:02 +00001624%
anthony24aa8822012-03-11 00:56:06 +00001625% Or for handling command line arguments EG: +/-option ["arg1"]
anthonydcf510d2011-10-30 13:51:40 +00001626%
anthony43f425d2012-02-26 12:58:58 +00001627% cli_wand
anthonydcf510d2011-10-30 13:51:40 +00001628% argc,argv
1629% i=index in argv
1630%
anthony2052d272012-02-28 12:48:29 +00001631% option_info = GetCommandOptionInfo(argv[i]);
1632% count=option_info->type;
1633% option_type=option_info->flags;
1634%
1635% if ( (option_type & SimpleOperatorOptionFlag) != 0 )
anthonyafa3dfc2012-03-03 11:31:30 +00001636% CLISimpleOperatorImages(cli_wand, argv[i],
anthonyfd706f92012-01-19 04:22:02 +00001637% count>=1 ? argv[i+1] : (char *)NULL,
1638% count>=2 ? argv[i+2] : (char *)NULL );
anthonydcf510d2011-10-30 13:51:40 +00001639% i += count+1;
1640%
anthony805a2d42011-09-25 08:25:12 +00001641*/
anthony31f1bf72012-01-30 12:37:22 +00001642
1643/*
1644 Internal subrountine to apply one simple image operation to the current
anthony43f425d2012-02-26 12:58:58 +00001645 image pointed to by the CLI wand.
anthony31f1bf72012-01-30 12:37:22 +00001646
1647 The image in the list may be modified in three different ways...
1648 * directly modified (EG: -negate, -gamma, -level, -annotate, -draw),
1649 * replaced by a new image (EG: -spread, -resize, -rotate, -morphology)
1650 * one image replace by a list of images (-separate and -crop only!)
1651
anthonyafa3dfc2012-03-03 11:31:30 +00001652 In each case the result replaces the single original image in the list, as
1653 well as the pointer to the modified image (last image added if replaced by a
1654 list of images) is returned.
anthony31f1bf72012-01-30 12:37:22 +00001655
1656 As the image pointed to may be replaced, the first image in the list may
1657 also change. GetFirstImageInList() should be used by caller if they wish
1658 return the Image pointer to the first image in list.
1659*/
anthony43f425d2012-02-26 12:58:58 +00001660static void CLISimpleOperatorImage(MagickCLI *cli_wand,
anthonyafa3dfc2012-03-03 11:31:30 +00001661 const char *option, const char *arg1, const char *arg2)
anthony805a2d42011-09-25 08:25:12 +00001662{
1663 Image *
1664 new_image;
1665
anthony805a2d42011-09-25 08:25:12 +00001666 GeometryInfo
1667 geometry_info;
1668
1669 RectangleInfo
1670 geometry;
1671
1672 MagickStatusType
anthony805a2d42011-09-25 08:25:12 +00001673 flags;
1674
anthony92c93bd2012-03-19 14:02:47 +00001675 ssize_t
1676 type;
1677
1678#define _image_info (cli_wand->wand.image_info)
1679#define _image (cli_wand->wand.images)
1680#define _exception (cli_wand->wand.exception)
1681#define _draw_info (cli_wand->draw_info)
1682#define _quantize_info (cli_wand->quantize_info)
anthonyafa3dfc2012-03-03 11:31:30 +00001683#define IfNormalOp (*option=='-')
1684#define IfPlusOp (*option!='-')
1685#define normal_op (IfNormalOp?MagickTrue:MagickFalse)
1686#define plus_alt_op (IfNormalOp?MagickFalse:MagickTrue)
anthonyfd706f92012-01-19 04:22:02 +00001687
anthony43f425d2012-02-26 12:58:58 +00001688 assert(cli_wand != (MagickCLI *) NULL);
1689 assert(cli_wand->signature == WandSignature);
1690 assert(cli_wand->wand.signature == WandSignature);
anthony5330ae02012-03-20 14:17:01 +00001691 assert(_image != (Image *) NULL); /* an image must be present */
anthony43f425d2012-02-26 12:58:58 +00001692 if (cli_wand->wand.debug != MagickFalse)
1693 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
anthonydcf510d2011-10-30 13:51:40 +00001694
anthony92c93bd2012-03-19 14:02:47 +00001695 (void) SyncImageSettings(_image_info,_image,_exception);
anthony24aa8822012-03-11 00:56:06 +00001696
anthony805a2d42011-09-25 08:25:12 +00001697 SetGeometryInfo(&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00001698
anthony5330ae02012-03-20 14:17:01 +00001699 new_image = (Image *)NULL; /* the replacement image, if not null at end */
anthony805a2d42011-09-25 08:25:12 +00001700
anthonyfd706f92012-01-19 04:22:02 +00001701 /* FUTURE: We may need somthing a little more optimized than this!
1702 Perhaps, do the 'sync' if 'settings tainted' before next operator.
1703 */
anthonyafa3dfc2012-03-03 11:31:30 +00001704 switch (*(option+1))
anthony805a2d42011-09-25 08:25:12 +00001705 {
1706 case 'a':
1707 {
anthonyafa3dfc2012-03-03 11:31:30 +00001708 if (LocaleCompare("adaptive-blur",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001709 {
anthony92c93bd2012-03-19 14:02:47 +00001710 if (IsGeometry(arg1) == MagickFalse)
1711 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00001712 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00001713 if ((flags & SigmaValue) == 0)
1714 geometry_info.sigma=1.0;
1715 if ((flags & XiValue) == 0)
1716 geometry_info.xi=0.0;
anthony92c93bd2012-03-19 14:02:47 +00001717 new_image=AdaptiveBlurImage(_image,geometry_info.rho,
1718 geometry_info.sigma,geometry_info.xi,_exception);
anthony805a2d42011-09-25 08:25:12 +00001719 break;
1720 }
anthonyafa3dfc2012-03-03 11:31:30 +00001721 if (LocaleCompare("adaptive-resize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001722 {
anthony92c93bd2012-03-19 14:02:47 +00001723 if (IsGeometry(arg1) == MagickFalse)
1724 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1725 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
1726 new_image=AdaptiveResizeImage(_image,geometry.width,geometry.height,
1727 _exception);
anthony805a2d42011-09-25 08:25:12 +00001728 break;
1729 }
anthonyafa3dfc2012-03-03 11:31:30 +00001730 if (LocaleCompare("adaptive-sharpen",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001731 {
anthony92c93bd2012-03-19 14:02:47 +00001732 if (IsGeometry(arg1) == MagickFalse)
1733 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00001734 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00001735 if ((flags & SigmaValue) == 0)
1736 geometry_info.sigma=1.0;
1737 if ((flags & XiValue) == 0)
1738 geometry_info.xi=0.0;
anthony92c93bd2012-03-19 14:02:47 +00001739 new_image=AdaptiveSharpenImage(_image,geometry_info.rho,
1740 geometry_info.sigma,geometry_info.xi,_exception);
anthony805a2d42011-09-25 08:25:12 +00001741 break;
1742 }
anthonyafa3dfc2012-03-03 11:31:30 +00001743 if (LocaleCompare("alpha",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001744 {
anthony92c93bd2012-03-19 14:02:47 +00001745 type=ParseCommandOption(MagickAlphaOptions,MagickFalse,arg1);
1746 if (type < 0)
1747 CLIWandExceptArgBreak(OptionError,"UnrecognizedAlphaChannelType",
1748 option,arg1);
1749 (void) SetImageAlphaChannel(_image,(AlphaChannelType)type,_exception);
anthony805a2d42011-09-25 08:25:12 +00001750 break;
1751 }
anthonyafa3dfc2012-03-03 11:31:30 +00001752 if (LocaleCompare("annotate",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001753 {
1754 char
1755 *text,
1756 geometry[MaxTextExtent];
1757
anthony92c93bd2012-03-19 14:02:47 +00001758 if (IsGeometry(arg1) == MagickFalse)
1759 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony805a2d42011-09-25 08:25:12 +00001760 SetGeometryInfo(&geometry_info);
anthonyfd706f92012-01-19 04:22:02 +00001761 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00001762 if ((flags & SigmaValue) == 0)
1763 geometry_info.sigma=geometry_info.rho;
anthony92c93bd2012-03-19 14:02:47 +00001764 text=InterpretImageProperties(_image_info,_image,arg2,
1765 _exception);
anthony805a2d42011-09-25 08:25:12 +00001766 if (text == (char *) NULL)
1767 break;
anthony92c93bd2012-03-19 14:02:47 +00001768 (void) CloneString(&_draw_info->text,text);
anthony805a2d42011-09-25 08:25:12 +00001769 text=DestroyString(text);
1770 (void) FormatLocaleString(geometry,MaxTextExtent,"%+f%+f",
1771 geometry_info.xi,geometry_info.psi);
anthony92c93bd2012-03-19 14:02:47 +00001772 (void) CloneString(&_draw_info->geometry,geometry);
1773 _draw_info->affine.sx=cos(DegreesToRadians(
anthony805a2d42011-09-25 08:25:12 +00001774 fmod(geometry_info.rho,360.0)));
anthony92c93bd2012-03-19 14:02:47 +00001775 _draw_info->affine.rx=sin(DegreesToRadians(
anthony805a2d42011-09-25 08:25:12 +00001776 fmod(geometry_info.rho,360.0)));
anthony92c93bd2012-03-19 14:02:47 +00001777 _draw_info->affine.ry=(-sin(DegreesToRadians(
anthony805a2d42011-09-25 08:25:12 +00001778 fmod(geometry_info.sigma,360.0))));
anthony92c93bd2012-03-19 14:02:47 +00001779 _draw_info->affine.sy=cos(DegreesToRadians(
anthony805a2d42011-09-25 08:25:12 +00001780 fmod(geometry_info.sigma,360.0)));
anthony92c93bd2012-03-19 14:02:47 +00001781 (void) AnnotateImage(_image,_draw_info,_exception);
1782 GetAffineMatrix(&_draw_info->affine);
anthony805a2d42011-09-25 08:25:12 +00001783 break;
1784 }
anthonyafa3dfc2012-03-03 11:31:30 +00001785 if (LocaleCompare("auto-gamma",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001786 {
anthony92c93bd2012-03-19 14:02:47 +00001787 (void) AutoGammaImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00001788 break;
1789 }
anthonyafa3dfc2012-03-03 11:31:30 +00001790 if (LocaleCompare("auto-level",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001791 {
anthony92c93bd2012-03-19 14:02:47 +00001792 (void) AutoLevelImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00001793 break;
1794 }
anthonyafa3dfc2012-03-03 11:31:30 +00001795 if (LocaleCompare("auto-orient",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001796 {
anthony5330ae02012-03-20 14:17:01 +00001797 /* This should probably be a MagickCore function */
anthony92c93bd2012-03-19 14:02:47 +00001798 switch (_image->orientation)
anthony805a2d42011-09-25 08:25:12 +00001799 {
1800 case TopRightOrientation:
1801 {
anthony92c93bd2012-03-19 14:02:47 +00001802 new_image=FlopImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00001803 break;
1804 }
1805 case BottomRightOrientation:
1806 {
anthony92c93bd2012-03-19 14:02:47 +00001807 new_image=RotateImage(_image,180.0,_exception);
anthony805a2d42011-09-25 08:25:12 +00001808 break;
1809 }
1810 case BottomLeftOrientation:
1811 {
anthony92c93bd2012-03-19 14:02:47 +00001812 new_image=FlipImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00001813 break;
1814 }
1815 case LeftTopOrientation:
1816 {
anthony92c93bd2012-03-19 14:02:47 +00001817 new_image=TransposeImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00001818 break;
1819 }
1820 case RightTopOrientation:
1821 {
anthony92c93bd2012-03-19 14:02:47 +00001822 new_image=RotateImage(_image,90.0,_exception);
anthony805a2d42011-09-25 08:25:12 +00001823 break;
1824 }
1825 case RightBottomOrientation:
1826 {
anthony92c93bd2012-03-19 14:02:47 +00001827 new_image=TransverseImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00001828 break;
1829 }
1830 case LeftBottomOrientation:
1831 {
anthony92c93bd2012-03-19 14:02:47 +00001832 new_image=RotateImage(_image,270.0,_exception);
anthony805a2d42011-09-25 08:25:12 +00001833 break;
1834 }
1835 default:
1836 break;
1837 }
1838 if (new_image != (Image *) NULL)
1839 new_image->orientation=TopLeftOrientation;
1840 break;
1841 }
anthonyebb73a22012-03-22 14:25:52 +00001842 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001843 }
1844 case 'b':
1845 {
anthonyafa3dfc2012-03-03 11:31:30 +00001846 if (LocaleCompare("black-threshold",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001847 {
anthony5330ae02012-03-20 14:17:01 +00001848 if (IsGeometry(arg1) == MagickFalse)
1849 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001850 (void) BlackThresholdImage(_image,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00001851 break;
1852 }
anthonyafa3dfc2012-03-03 11:31:30 +00001853 if (LocaleCompare("blue-shift",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001854 {
anthony805a2d42011-09-25 08:25:12 +00001855 geometry_info.rho=1.5;
anthony5330ae02012-03-20 14:17:01 +00001856 if (IfNormalOp) {
1857 if (IsGeometry(arg1) == MagickFalse)
1858 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00001859 flags=ParseGeometry(arg1,&geometry_info);
anthony5330ae02012-03-20 14:17:01 +00001860 }
anthony92c93bd2012-03-19 14:02:47 +00001861 new_image=BlueShiftImage(_image,geometry_info.rho,_exception);
anthony805a2d42011-09-25 08:25:12 +00001862 break;
1863 }
anthonyafa3dfc2012-03-03 11:31:30 +00001864 if (LocaleCompare("blur",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001865 {
anthony74b1cfc2011-10-06 12:44:16 +00001866 /* FUTURE: use of "bias" in a blur is non-sensible */
anthony5330ae02012-03-20 14:17:01 +00001867 if (IsGeometry(arg1) == MagickFalse)
1868 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00001869 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00001870 if ((flags & SigmaValue) == 0)
1871 geometry_info.sigma=1.0;
1872 if ((flags & XiValue) == 0)
1873 geometry_info.xi=0.0;
anthony92c93bd2012-03-19 14:02:47 +00001874 new_image=BlurImage(_image,geometry_info.rho,
1875 geometry_info.sigma,geometry_info.xi,_exception);
anthony805a2d42011-09-25 08:25:12 +00001876 break;
1877 }
anthonyafa3dfc2012-03-03 11:31:30 +00001878 if (LocaleCompare("border",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001879 {
anthony31f1bf72012-01-30 12:37:22 +00001880 CompositeOperator
anthony5f867ae2011-10-09 10:28:34 +00001881 compose;
1882
1883 const char*
anthony5f867ae2011-10-09 10:28:34 +00001884 value;
1885
anthony5330ae02012-03-20 14:17:01 +00001886 if (IsGeometry(arg1) == MagickFalse)
1887 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
1888
anthony92c93bd2012-03-19 14:02:47 +00001889 value=GetImageOption(_image_info,"compose");
anthony5f867ae2011-10-09 10:28:34 +00001890 if (value != (const char *) NULL)
1891 compose=(CompositeOperator) ParseCommandOption(
1892 MagickComposeOptions,MagickFalse,value);
1893 else
anthony92c93bd2012-03-19 14:02:47 +00001894 compose=OverCompositeOp; /* use Over not _image->compose */
anthony5f867ae2011-10-09 10:28:34 +00001895
anthony92c93bd2012-03-19 14:02:47 +00001896 flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00001897 if ((flags & SigmaValue) == 0)
1898 geometry.height=geometry.width;
anthony92c93bd2012-03-19 14:02:47 +00001899 new_image=BorderImage(_image,&geometry,compose,_exception);
anthony805a2d42011-09-25 08:25:12 +00001900 break;
1901 }
anthonyafa3dfc2012-03-03 11:31:30 +00001902 if (LocaleCompare("brightness-contrast",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001903 {
1904 double
1905 brightness,
1906 contrast;
1907
1908 GeometryInfo
1909 geometry_info;
1910
1911 MagickStatusType
1912 flags;
1913
anthony5330ae02012-03-20 14:17:01 +00001914 if (IsGeometry(arg1) == MagickFalse)
1915 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00001916 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00001917 brightness=geometry_info.rho;
1918 contrast=0.0;
1919 if ((flags & SigmaValue) != 0)
1920 contrast=geometry_info.sigma;
anthony92c93bd2012-03-19 14:02:47 +00001921 (void) BrightnessContrastImage(_image,brightness,contrast,
1922 _exception);
anthony805a2d42011-09-25 08:25:12 +00001923 break;
1924 }
anthonyebb73a22012-03-22 14:25:52 +00001925 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00001926 }
1927 case 'c':
1928 {
anthonyafa3dfc2012-03-03 11:31:30 +00001929 if (LocaleCompare("cdl",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001930 {
1931 char
1932 *color_correction_collection;
1933
1934 /*
1935 Color correct with a color decision list.
1936 */
anthony92c93bd2012-03-19 14:02:47 +00001937 color_correction_collection=FileToString(arg1,~0,_exception);
anthony805a2d42011-09-25 08:25:12 +00001938 if (color_correction_collection == (char *) NULL)
1939 break;
anthony92c93bd2012-03-19 14:02:47 +00001940 (void) ColorDecisionListImage(_image,color_correction_collection,
1941 _exception);
anthony805a2d42011-09-25 08:25:12 +00001942 break;
1943 }
anthonyafa3dfc2012-03-03 11:31:30 +00001944 if (LocaleCompare("charcoal",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001945 {
anthony5330ae02012-03-20 14:17:01 +00001946 if (IsGeometry(arg1) == MagickFalse)
1947 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00001948 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00001949 if ((flags & SigmaValue) == 0)
1950 geometry_info.sigma=1.0;
1951 if ((flags & XiValue) == 0)
1952 geometry_info.xi=1.0;
anthony92c93bd2012-03-19 14:02:47 +00001953 new_image=CharcoalImage(_image,geometry_info.rho,
1954 geometry_info.sigma,geometry_info.xi,_exception);
anthony805a2d42011-09-25 08:25:12 +00001955 break;
1956 }
anthonyafa3dfc2012-03-03 11:31:30 +00001957 if (LocaleCompare("chop",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001958 {
anthony5330ae02012-03-20 14:17:01 +00001959 if (IsGeometry(arg1) == MagickFalse)
1960 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00001961 (void) ParseGravityGeometry(_image,arg1,&geometry,_exception);
1962 new_image=ChopImage(_image,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00001963 break;
1964 }
anthonyafa3dfc2012-03-03 11:31:30 +00001965 if (LocaleCompare("clamp",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001966 {
anthony92c93bd2012-03-19 14:02:47 +00001967 (void) ClampImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00001968 break;
1969 }
anthonyafa3dfc2012-03-03 11:31:30 +00001970 if (LocaleCompare("clip",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001971 {
anthonyafa3dfc2012-03-03 11:31:30 +00001972 if (IfNormalOp)
anthony92c93bd2012-03-19 14:02:47 +00001973 (void) ClipImage(_image,_exception);
anthony43f425d2012-02-26 12:58:58 +00001974 else /* "+mask" remove the write mask */
anthony92c93bd2012-03-19 14:02:47 +00001975 (void) SetImageMask(_image,(Image *) NULL,_exception);
anthony805a2d42011-09-25 08:25:12 +00001976 break;
1977 }
anthonyafa3dfc2012-03-03 11:31:30 +00001978 if (LocaleCompare("clip-mask",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00001979 {
1980 CacheView
1981 *mask_view;
1982
1983 Image
1984 *mask_image;
1985
1986 register Quantum
1987 *restrict q;
1988
1989 register ssize_t
1990 x;
1991
1992 ssize_t
1993 y;
1994
anthonyafa3dfc2012-03-03 11:31:30 +00001995 if (IfPlusOp) {
1996 /* "+clip-mask" Remove the write mask */
anthony92c93bd2012-03-19 14:02:47 +00001997 (void) SetImageMask(_image,(Image *) NULL,_exception);
anthonyafa3dfc2012-03-03 11:31:30 +00001998 break;
1999 }
anthony92c93bd2012-03-19 14:02:47 +00002000 mask_image=GetImageCache(_image_info,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00002001 if (mask_image == (Image *) NULL)
2002 break;
anthony92c93bd2012-03-19 14:02:47 +00002003 if (SetImageStorageClass(mask_image,DirectClass,_exception)
anthonyfd706f92012-01-19 04:22:02 +00002004 == MagickFalse)
anthony31f1bf72012-01-30 12:37:22 +00002005 break;
anthony5330ae02012-03-20 14:17:01 +00002006 /* Create a write mask from cli_wand mask image */
anthonyfd706f92012-01-19 04:22:02 +00002007 /* FUTURE: use Alpha operations instead and create a Grey Image */
anthony805a2d42011-09-25 08:25:12 +00002008 mask_view=AcquireCacheView(mask_image);
2009 for (y=0; y < (ssize_t) mask_image->rows; y++)
2010 {
2011 q=GetCacheViewAuthenticPixels(mask_view,0,y,mask_image->columns,1,
anthony92c93bd2012-03-19 14:02:47 +00002012 _exception);
anthony805a2d42011-09-25 08:25:12 +00002013 if (q == (Quantum *) NULL)
2014 break;
2015 for (x=0; x < (ssize_t) mask_image->columns; x++)
2016 {
2017 if (mask_image->matte == MagickFalse)
2018 SetPixelAlpha(mask_image,GetPixelIntensity(mask_image,q),q);
2019 SetPixelRed(mask_image,GetPixelAlpha(mask_image,q),q);
2020 SetPixelGreen(mask_image,GetPixelAlpha(mask_image,q),q);
2021 SetPixelBlue(mask_image,GetPixelAlpha(mask_image,q),q);
2022 q+=GetPixelChannels(mask_image);
2023 }
anthony92c93bd2012-03-19 14:02:47 +00002024 if (SyncCacheViewAuthenticPixels(mask_view,_exception) == MagickFalse)
anthony805a2d42011-09-25 08:25:12 +00002025 break;
2026 }
anthonyfd706f92012-01-19 04:22:02 +00002027 /* clean up and set the write mask */
anthony805a2d42011-09-25 08:25:12 +00002028 mask_view=DestroyCacheView(mask_view);
2029 mask_image->matte=MagickTrue;
anthony92c93bd2012-03-19 14:02:47 +00002030 (void) SetImageMask(_image,mask_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002031 mask_image=DestroyImage(mask_image);
anthony805a2d42011-09-25 08:25:12 +00002032 break;
2033 }
anthonyafa3dfc2012-03-03 11:31:30 +00002034 if (LocaleCompare("clip-path",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002035 {
anthony92c93bd2012-03-19 14:02:47 +00002036 (void) ClipImagePath(_image,arg1,normal_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00002037 break;
2038 }
anthonyafa3dfc2012-03-03 11:31:30 +00002039 if (LocaleCompare("colorize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002040 {
anthony5330ae02012-03-20 14:17:01 +00002041 if (IsGeometry(arg1) == MagickFalse)
2042 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002043 new_image=ColorizeImage(_image,arg1,&_draw_info->fill,_exception);
anthony805a2d42011-09-25 08:25:12 +00002044 break;
2045 }
anthonyafa3dfc2012-03-03 11:31:30 +00002046 if (LocaleCompare("color-matrix",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002047 {
2048 KernelInfo
2049 *kernel;
2050
anthonyfd706f92012-01-19 04:22:02 +00002051 kernel=AcquireKernelInfo(arg1);
anthony805a2d42011-09-25 08:25:12 +00002052 if (kernel == (KernelInfo *) NULL)
anthony5330ae02012-03-20 14:17:01 +00002053 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002054 new_image=ColorMatrixImage(_image,kernel,_exception);
anthony805a2d42011-09-25 08:25:12 +00002055 kernel=DestroyKernelInfo(kernel);
2056 break;
2057 }
anthonyafa3dfc2012-03-03 11:31:30 +00002058 if (LocaleCompare("colors",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002059 {
anthony5330ae02012-03-20 14:17:01 +00002060 /* Reduce the number of colors in the image.
2061 FUTURE: also provide 'plus version with image 'color counts'
anthonyfd706f92012-01-19 04:22:02 +00002062 */
anthony92c93bd2012-03-19 14:02:47 +00002063 _quantize_info->number_colors=StringToUnsignedLong(arg1);
2064 if (_quantize_info->number_colors == 0)
anthony5330ae02012-03-20 14:17:01 +00002065 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002066 if ((_image->storage_class == DirectClass) ||
2067 _image->colors > _quantize_info->number_colors)
2068 (void) QuantizeImage(_quantize_info,_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002069 else
anthony92c93bd2012-03-19 14:02:47 +00002070 (void) CompressImageColormap(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002071 break;
2072 }
anthonyafa3dfc2012-03-03 11:31:30 +00002073 if (LocaleCompare("colorspace",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002074 {
anthony5330ae02012-03-20 14:17:01 +00002075 /* WARNING: this is both a image_info setting (already done)
2076 and a operator to change image colorspace.
anthony31f1bf72012-01-30 12:37:22 +00002077
2078 FUTURE: default colorspace should be sRGB!
anthonyd2cdc862011-10-07 14:07:17 +00002079 Unless some type of 'linear colorspace' mode is set.
anthony31f1bf72012-01-30 12:37:22 +00002080
anthonyd2cdc862011-10-07 14:07:17 +00002081 Note that +colorspace sets "undefined" or no effect on
2082 new images, but forces images already in memory back to RGB!
anthony31f1bf72012-01-30 12:37:22 +00002083 That seems to be a little strange!
anthonyd2cdc862011-10-07 14:07:17 +00002084 */
anthony92c93bd2012-03-19 14:02:47 +00002085 (void) TransformImageColorspace(_image,
2086 IfNormalOp ? _image_info->colorspace : RGBColorspace,
2087 _exception);
anthony805a2d42011-09-25 08:25:12 +00002088 break;
2089 }
anthonyebb73a22012-03-22 14:25:52 +00002090#if 0
2091 /* this is a stupid and pretty usless operation
2092 * -level 10% produces much better and more controlled result
2093 */
anthonyafa3dfc2012-03-03 11:31:30 +00002094 if (LocaleCompare("contrast",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002095 {
anthony92c93bd2012-03-19 14:02:47 +00002096 (void) ContrastImage(_image,normal_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00002097 break;
2098 }
anthonyebb73a22012-03-22 14:25:52 +00002099#endif
anthonyafa3dfc2012-03-03 11:31:30 +00002100 if (LocaleCompare("contrast-stretch",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002101 {
2102 double
2103 black_point,
2104 white_point;
2105
2106 MagickStatusType
2107 flags;
2108
anthonyebb73a22012-03-22 14:25:52 +00002109 if (IsGeometry(arg1) == MagickFalse)
2110 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00002111 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002112 black_point=geometry_info.rho;
2113 white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
2114 black_point;
anthonyebb73a22012-03-22 14:25:52 +00002115 if ((flags & PercentValue) != 0) {
anthony92c93bd2012-03-19 14:02:47 +00002116 black_point*=(double) _image->columns*_image->rows/100.0;
2117 white_point*=(double) _image->columns*_image->rows/100.0;
anthony805a2d42011-09-25 08:25:12 +00002118 }
anthony92c93bd2012-03-19 14:02:47 +00002119 white_point=(MagickRealType) _image->columns*_image->rows-
anthony805a2d42011-09-25 08:25:12 +00002120 white_point;
anthony92c93bd2012-03-19 14:02:47 +00002121 (void) ContrastStretchImage(_image,black_point,white_point,
2122 _exception);
anthony805a2d42011-09-25 08:25:12 +00002123 break;
2124 }
anthonyafa3dfc2012-03-03 11:31:30 +00002125 if (LocaleCompare("convolve",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002126 {
2127 KernelInfo
2128 *kernel_info;
2129
anthonyfd706f92012-01-19 04:22:02 +00002130 kernel_info=AcquireKernelInfo(arg1);
anthony805a2d42011-09-25 08:25:12 +00002131 if (kernel_info == (KernelInfo *) NULL)
anthonyebb73a22012-03-22 14:25:52 +00002132 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002133 kernel_info->bias=_image->bias;
2134 new_image=ConvolveImage(_image,kernel_info,_exception);
anthony805a2d42011-09-25 08:25:12 +00002135 kernel_info=DestroyKernelInfo(kernel_info);
2136 break;
2137 }
anthonyafa3dfc2012-03-03 11:31:30 +00002138 if (LocaleCompare("crop",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002139 {
anthony31f1bf72012-01-30 12:37:22 +00002140 /* WARNING: This can generate multiple images! */
anthonyebb73a22012-03-22 14:25:52 +00002141 if (IsGeometry(arg1) == MagickFalse)
2142 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002143 new_image=CropImageToTiles(_image,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00002144 break;
2145 }
anthonyafa3dfc2012-03-03 11:31:30 +00002146 if (LocaleCompare("cycle",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002147 {
anthonyebb73a22012-03-22 14:25:52 +00002148 if (IsGeometry(arg1) == MagickFalse)
2149 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002150 (void) CycleColormapImage(_image,(ssize_t) StringToLong(arg1),
2151 _exception);
anthony805a2d42011-09-25 08:25:12 +00002152 break;
2153 }
anthonyebb73a22012-03-22 14:25:52 +00002154 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002155 }
2156 case 'd':
2157 {
anthonyafa3dfc2012-03-03 11:31:30 +00002158 if (LocaleCompare("decipher",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002159 {
2160 StringInfo
2161 *passkey;
2162
anthony92c93bd2012-03-19 14:02:47 +00002163 passkey=FileToStringInfo(arg1,~0,_exception);
anthonyebb73a22012-03-22 14:25:52 +00002164 if (passkey == (StringInfo *) NULL)
2165 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
2166
2167 (void) PasskeyDecipherImage(_image,passkey,_exception);
2168 passkey=DestroyStringInfo(passkey);
anthony805a2d42011-09-25 08:25:12 +00002169 break;
2170 }
anthonyafa3dfc2012-03-03 11:31:30 +00002171 if (LocaleCompare("depth",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002172 {
anthony92c93bd2012-03-19 14:02:47 +00002173 /* The _image_info->depth setting has already been set
anthonydcf510d2011-10-30 13:51:40 +00002174 We just need to apply it to all images in current sequence
anthony31f1bf72012-01-30 12:37:22 +00002175
anthonydcf510d2011-10-30 13:51:40 +00002176 WARNING: Depth from 8 to 16 causes 'quantum rounding to images!
2177 That is it really is an operation, not a setting! Arrgghhh
anthony31f1bf72012-01-30 12:37:22 +00002178
anthonyfd706f92012-01-19 04:22:02 +00002179 FUTURE: this should not be an operator!!!
anthonydcf510d2011-10-30 13:51:40 +00002180 */
anthony92c93bd2012-03-19 14:02:47 +00002181 (void) SetImageDepth(_image,_image_info->depth,_exception);
anthony805a2d42011-09-25 08:25:12 +00002182 break;
2183 }
anthonyafa3dfc2012-03-03 11:31:30 +00002184 if (LocaleCompare("deskew",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002185 {
2186 double
2187 threshold;
2188
anthonyebb73a22012-03-22 14:25:52 +00002189 if (IfNormalOp) {
2190 if (IsGeometry(arg1) == MagickFalse)
2191 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
anthonyfd706f92012-01-19 04:22:02 +00002192 threshold=StringToDoubleInterval(arg1,(double) QuantumRange+1.0);
anthonyebb73a22012-03-22 14:25:52 +00002193 }
anthonyafa3dfc2012-03-03 11:31:30 +00002194 else
2195 threshold=40.0*QuantumRange/100.0;
anthony92c93bd2012-03-19 14:02:47 +00002196 new_image=DeskewImage(_image,threshold,_exception);
anthony805a2d42011-09-25 08:25:12 +00002197 break;
2198 }
anthonyafa3dfc2012-03-03 11:31:30 +00002199 if (LocaleCompare("despeckle",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002200 {
anthony92c93bd2012-03-19 14:02:47 +00002201 new_image=DespeckleImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002202 break;
2203 }
anthonyafa3dfc2012-03-03 11:31:30 +00002204 if (LocaleCompare("distort",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002205 {
2206 char
2207 *args,
2208 token[MaxTextExtent];
2209
2210 const char
2211 *p;
2212
2213 DistortImageMethod
2214 method;
2215
2216 double
2217 *arguments;
2218
2219 register ssize_t
2220 x;
2221
2222 size_t
2223 number_arguments;
2224
anthonyebb73a22012-03-22 14:25:52 +00002225 x = ParseCommandOption(MagickDistortOptions,MagickFalse,arg1);
2226 if ( x < 0 )
2227 CLIWandExceptArgBreak(OptionError,"UnrecognizedDistortMethod",
2228 option,arg1);
2229 method = (DistortImageMethod) x;
anthony80c37752012-01-16 01:03:11 +00002230 if (method == ResizeDistortion)
anthony805a2d42011-09-25 08:25:12 +00002231 {
anthony80c37752012-01-16 01:03:11 +00002232 double
2233 resize_args[2];
anthony805a2d42011-09-25 08:25:12 +00002234 /* Special Case - Argument is actually a resize geometry!
2235 ** Convert that to an appropriate distortion argument array.
anthonyfd706f92012-01-19 04:22:02 +00002236 ** FUTURE: make a separate special resize operator
anthony805a2d42011-09-25 08:25:12 +00002237 */
anthonyebb73a22012-03-22 14:25:52 +00002238 if (IsGeometry(arg2) == MagickFalse)
2239 CLIWandExceptArgBreak(OptionError,"InvalidGeometry",
2240 option,arg2);
2241 (void) ParseRegionGeometry(_image,arg2,&geometry,_exception);
anthony80c37752012-01-16 01:03:11 +00002242 resize_args[0]=(double) geometry.width;
2243 resize_args[1]=(double) geometry.height;
anthony92c93bd2012-03-19 14:02:47 +00002244 new_image=DistortImage(_image,method,(size_t)2,
2245 resize_args,MagickTrue,_exception);
anthony805a2d42011-09-25 08:25:12 +00002246 break;
2247 }
anthonyfd706f92012-01-19 04:22:02 +00002248 /* handle percent arguments */
anthonyebb73a22012-03-22 14:25:52 +00002249 args=InterpretImageProperties(_image_info,_image,arg2,_exception);
anthony805a2d42011-09-25 08:25:12 +00002250 if (args == (char *) NULL)
2251 break;
anthonyfd706f92012-01-19 04:22:02 +00002252 /* convert arguments into an array of doubles
2253 FUTURE: make this a separate function.
2254 Also make use of new 'sentinal' feature to avoid need for
2255 tokenization.
2256 */
anthony805a2d42011-09-25 08:25:12 +00002257 p=(char *) args;
2258 for (x=0; *p != '\0'; x++)
2259 {
2260 GetMagickToken(p,&p,token);
2261 if (*token == ',')
2262 GetMagickToken(p,&p,token);
2263 }
2264 number_arguments=(size_t) x;
2265 arguments=(double *) AcquireQuantumMemory(number_arguments,
2266 sizeof(*arguments));
2267 if (arguments == (double *) NULL)
anthonyebb73a22012-03-22 14:25:52 +00002268 CLIWandExceptionBreak(ResourceLimitFatalError,
2269 "MemoryAllocationFailed",option);
anthony805a2d42011-09-25 08:25:12 +00002270 (void) ResetMagickMemory(arguments,0,number_arguments*
anthonyebb73a22012-03-22 14:25:52 +00002271 sizeof(*arguments));
anthony805a2d42011-09-25 08:25:12 +00002272 p=(char *) args;
2273 for (x=0; (x < (ssize_t) number_arguments) && (*p != '\0'); x++)
2274 {
2275 GetMagickToken(p,&p,token);
2276 if (*token == ',')
2277 GetMagickToken(p,&p,token);
cristydbdd0e32011-11-04 23:29:40 +00002278 arguments[x]=StringToDouble(token,(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +00002279 }
2280 args=DestroyString(args);
anthony92c93bd2012-03-19 14:02:47 +00002281 new_image=DistortImage(_image,method,number_arguments,arguments,
2282 plus_alt_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00002283 arguments=(double *) RelinquishMagickMemory(arguments);
2284 break;
2285 }
anthonyafa3dfc2012-03-03 11:31:30 +00002286 if (LocaleCompare("draw",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002287 {
anthony92c93bd2012-03-19 14:02:47 +00002288 (void) CloneString(&_draw_info->primitive,arg1);
2289 (void) DrawImage(_image,_draw_info,_exception);
2290 (void) CloneString(&_draw_info->primitive,(char *)NULL);
anthony805a2d42011-09-25 08:25:12 +00002291 break;
2292 }
anthonyebb73a22012-03-22 14:25:52 +00002293 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002294 }
2295 case 'e':
2296 {
anthonyafa3dfc2012-03-03 11:31:30 +00002297 if (LocaleCompare("edge",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002298 {
anthonyfd706f92012-01-19 04:22:02 +00002299 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002300 if ((flags & SigmaValue) == 0)
2301 geometry_info.sigma=1.0;
anthony92c93bd2012-03-19 14:02:47 +00002302 new_image=EdgeImage(_image,geometry_info.rho,
2303 geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00002304 break;
2305 }
anthonyafa3dfc2012-03-03 11:31:30 +00002306 if (LocaleCompare("emboss",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002307 {
anthonyfd706f92012-01-19 04:22:02 +00002308 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002309 if ((flags & SigmaValue) == 0)
2310 geometry_info.sigma=1.0;
anthony92c93bd2012-03-19 14:02:47 +00002311 new_image=EmbossImage(_image,geometry_info.rho,
2312 geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00002313 break;
2314 }
anthonyafa3dfc2012-03-03 11:31:30 +00002315 if (LocaleCompare("encipher",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002316 {
2317 StringInfo
2318 *passkey;
2319
anthony92c93bd2012-03-19 14:02:47 +00002320 passkey=FileToStringInfo(arg1,~0,_exception);
anthony805a2d42011-09-25 08:25:12 +00002321 if (passkey != (StringInfo *) NULL)
2322 {
anthony92c93bd2012-03-19 14:02:47 +00002323 (void) PasskeyEncipherImage(_image,passkey,_exception);
anthony805a2d42011-09-25 08:25:12 +00002324 passkey=DestroyStringInfo(passkey);
2325 }
2326 break;
2327 }
anthonyafa3dfc2012-03-03 11:31:30 +00002328 if (LocaleCompare("enhance",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002329 {
anthony92c93bd2012-03-19 14:02:47 +00002330 new_image=EnhanceImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002331 break;
2332 }
anthonyafa3dfc2012-03-03 11:31:30 +00002333 if (LocaleCompare("equalize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002334 {
anthony92c93bd2012-03-19 14:02:47 +00002335 (void) EqualizeImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002336 break;
2337 }
anthonyafa3dfc2012-03-03 11:31:30 +00002338 if (LocaleCompare("evaluate",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002339 {
2340 double
2341 constant;
2342
2343 MagickEvaluateOperator
2344 op;
2345
anthony805a2d42011-09-25 08:25:12 +00002346 op=(MagickEvaluateOperator) ParseCommandOption(
anthonyfd706f92012-01-19 04:22:02 +00002347 MagickEvaluateOptions,MagickFalse,arg1);
2348 constant=StringToDoubleInterval(arg2,(double) QuantumRange+1.0);
anthony92c93bd2012-03-19 14:02:47 +00002349 (void) EvaluateImage(_image,op,constant,_exception);
anthony805a2d42011-09-25 08:25:12 +00002350 break;
2351 }
anthonyafa3dfc2012-03-03 11:31:30 +00002352 if (LocaleCompare("extent",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002353 {
anthony92c93bd2012-03-19 14:02:47 +00002354 flags=ParseGravityGeometry(_image,arg1,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00002355 if (geometry.width == 0)
anthony92c93bd2012-03-19 14:02:47 +00002356 geometry.width=_image->columns;
anthony805a2d42011-09-25 08:25:12 +00002357 if (geometry.height == 0)
anthony92c93bd2012-03-19 14:02:47 +00002358 geometry.height=_image->rows;
2359 new_image=ExtentImage(_image,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00002360 break;
2361 }
anthonyebb73a22012-03-22 14:25:52 +00002362 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002363 }
2364 case 'f':
2365 {
anthonyafa3dfc2012-03-03 11:31:30 +00002366 if (LocaleCompare("features",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002367 {
anthony31f1bf72012-01-30 12:37:22 +00002368 /* FUTURE: move to SyncImageSettings() and AcqireImage()??? */
anthonyafa3dfc2012-03-03 11:31:30 +00002369 if (IfPlusOp) {
anthony92c93bd2012-03-19 14:02:47 +00002370 (void) DeleteImageArtifact(_image,"identify:features");
anthony31f1bf72012-01-30 12:37:22 +00002371 break;
2372 }
anthony92c93bd2012-03-19 14:02:47 +00002373 (void) SetImageArtifact(_image,"identify:features","true");
2374 (void) SetImageArtifact(_image,"verbose","true");
anthony805a2d42011-09-25 08:25:12 +00002375 break;
2376 }
anthonyafa3dfc2012-03-03 11:31:30 +00002377 if (LocaleCompare("flip",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002378 {
anthony92c93bd2012-03-19 14:02:47 +00002379 new_image=FlipImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002380 break;
2381 }
anthonyafa3dfc2012-03-03 11:31:30 +00002382 if (LocaleCompare("flop",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002383 {
anthony92c93bd2012-03-19 14:02:47 +00002384 new_image=FlopImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002385 break;
2386 }
anthonyafa3dfc2012-03-03 11:31:30 +00002387 if (LocaleCompare("floodfill",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002388 {
2389 PixelInfo
2390 target;
2391
anthony92c93bd2012-03-19 14:02:47 +00002392 (void) ParsePageGeometry(_image,arg1,&geometry,_exception);
2393 (void) QueryColorCompliance(arg2,AllCompliance,&target,_exception);
2394 (void) FloodfillPaintImage(_image,_draw_info,&target,geometry.x,
2395 geometry.y,plus_alt_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00002396 break;
2397 }
anthonyafa3dfc2012-03-03 11:31:30 +00002398 if (LocaleCompare("frame",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002399 {
2400 FrameInfo
2401 frame_info;
2402
anthony31f1bf72012-01-30 12:37:22 +00002403 CompositeOperator
anthonyfd706f92012-01-19 04:22:02 +00002404 compose;
2405
2406 const char*
2407 value;
2408
anthony92c93bd2012-03-19 14:02:47 +00002409 value=GetImageOption(_image_info,"compose");
anthonyfd706f92012-01-19 04:22:02 +00002410 if (value != (const char *) NULL)
2411 compose=(CompositeOperator) ParseCommandOption(
2412 MagickComposeOptions,MagickFalse,value);
2413 else
anthony92c93bd2012-03-19 14:02:47 +00002414 compose=OverCompositeOp; /* use Over not _image->compose */
anthonyfd706f92012-01-19 04:22:02 +00002415
anthony92c93bd2012-03-19 14:02:47 +00002416 flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00002417 frame_info.width=geometry.width;
2418 frame_info.height=geometry.height;
2419 if ((flags & HeightValue) == 0)
2420 frame_info.height=geometry.width;
2421 frame_info.outer_bevel=geometry.x;
2422 frame_info.inner_bevel=geometry.y;
2423 frame_info.x=(ssize_t) frame_info.width;
2424 frame_info.y=(ssize_t) frame_info.height;
anthony92c93bd2012-03-19 14:02:47 +00002425 frame_info.width=_image->columns+2*frame_info.width;
2426 frame_info.height=_image->rows+2*frame_info.height;
2427 new_image=FrameImage(_image,&frame_info,compose,_exception);
anthony805a2d42011-09-25 08:25:12 +00002428 break;
2429 }
anthonyafa3dfc2012-03-03 11:31:30 +00002430 if (LocaleCompare("function",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002431 {
2432 char
2433 *arguments,
2434 token[MaxTextExtent];
2435
2436 const char
2437 *p;
2438
2439 double
2440 *parameters;
2441
2442 MagickFunction
2443 function;
2444
2445 register ssize_t
2446 x;
2447
2448 size_t
2449 number_parameters;
2450
cristy947cb4c2011-10-20 18:41:46 +00002451 /*
2452 Function Modify Image Values
anthonyfd706f92012-01-19 04:22:02 +00002453 FUTURE: code should be almost a duplicate of that is "distort"
cristy947cb4c2011-10-20 18:41:46 +00002454 */
anthony805a2d42011-09-25 08:25:12 +00002455 function=(MagickFunction) ParseCommandOption(MagickFunctionOptions,
anthonyfd706f92012-01-19 04:22:02 +00002456 MagickFalse,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002457 arguments=InterpretImageProperties(_image_info,_image,arg2,
2458 _exception);
anthony805a2d42011-09-25 08:25:12 +00002459 if (arguments == (char *) NULL)
2460 break;
2461 p=(char *) arguments;
2462 for (x=0; *p != '\0'; x++)
2463 {
2464 GetMagickToken(p,&p,token);
2465 if (*token == ',')
2466 GetMagickToken(p,&p,token);
2467 }
2468 number_parameters=(size_t) x;
2469 parameters=(double *) AcquireQuantumMemory(number_parameters,
2470 sizeof(*parameters));
2471 if (parameters == (double *) NULL)
2472 ThrowWandFatalException(ResourceLimitFatalError,
anthony92c93bd2012-03-19 14:02:47 +00002473 "MemoryAllocationFailed",_image->filename);
anthony805a2d42011-09-25 08:25:12 +00002474 (void) ResetMagickMemory(parameters,0,number_parameters*
2475 sizeof(*parameters));
2476 p=(char *) arguments;
2477 for (x=0; (x < (ssize_t) number_parameters) && (*p != '\0'); x++)
2478 {
2479 GetMagickToken(p,&p,token);
2480 if (*token == ',')
2481 GetMagickToken(p,&p,token);
cristydbdd0e32011-11-04 23:29:40 +00002482 parameters[x]=StringToDouble(token,(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +00002483 }
2484 arguments=DestroyString(arguments);
anthony92c93bd2012-03-19 14:02:47 +00002485 (void) FunctionImage(_image,function,number_parameters,parameters,
2486 _exception);
anthony805a2d42011-09-25 08:25:12 +00002487 parameters=(double *) RelinquishMagickMemory(parameters);
2488 break;
2489 }
anthonyebb73a22012-03-22 14:25:52 +00002490 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002491 }
2492 case 'g':
2493 {
anthonyafa3dfc2012-03-03 11:31:30 +00002494 if (LocaleCompare("gamma",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002495 {
anthonyafa3dfc2012-03-03 11:31:30 +00002496 if (IfNormalOp)
anthony92c93bd2012-03-19 14:02:47 +00002497 (void) GammaImage(_image,StringToDouble(arg1,(char **) NULL),
2498 _exception);
anthonyafa3dfc2012-03-03 11:31:30 +00002499 else
anthony92c93bd2012-03-19 14:02:47 +00002500 _image->gamma=StringToDouble(arg1,(char **) NULL);
anthony805a2d42011-09-25 08:25:12 +00002501 break;
2502 }
anthonyafa3dfc2012-03-03 11:31:30 +00002503 if ((LocaleCompare("gaussian-blur",option+1) == 0) ||
2504 (LocaleCompare("gaussian",option+1) == 0))
anthony805a2d42011-09-25 08:25:12 +00002505 {
anthonyfd706f92012-01-19 04:22:02 +00002506 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002507 if ((flags & SigmaValue) == 0)
2508 geometry_info.sigma=1.0;
anthony92c93bd2012-03-19 14:02:47 +00002509 new_image=GaussianBlurImage(_image,geometry_info.rho,
2510 geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00002511 break;
2512 }
anthonyafa3dfc2012-03-03 11:31:30 +00002513 if (LocaleCompare("geometry",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002514 {
anthonyfd706f92012-01-19 04:22:02 +00002515 /*
anthony31f1bf72012-01-30 12:37:22 +00002516 Record Image offset for composition. (A Setting)
anthony92c93bd2012-03-19 14:02:47 +00002517 Resize last _image. (ListOperator)
anthony31f1bf72012-01-30 12:37:22 +00002518 FUTURE: Why if no 'offset' does this resize ALL images?
2519 Also why is the setting recorded in the IMAGE non-sense!
anthonyfd706f92012-01-19 04:22:02 +00002520 */
anthonyafa3dfc2012-03-03 11:31:30 +00002521 if (IfPlusOp)
anthonyfd706f92012-01-19 04:22:02 +00002522 { /* remove the previous composition geometry offset! */
anthony92c93bd2012-03-19 14:02:47 +00002523 if (_image->geometry != (char *) NULL)
2524 _image->geometry=DestroyString(_image->geometry);
anthony805a2d42011-09-25 08:25:12 +00002525 break;
2526 }
anthony92c93bd2012-03-19 14:02:47 +00002527 flags=ParseRegionGeometry(_image,arg1,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00002528 if (((flags & XValue) != 0) || ((flags & YValue) != 0))
anthony92c93bd2012-03-19 14:02:47 +00002529 (void) CloneString(&_image->geometry,arg1);
anthony805a2d42011-09-25 08:25:12 +00002530 else
anthony92c93bd2012-03-19 14:02:47 +00002531 new_image=ResizeImage(_image,geometry.width,geometry.height,
2532 _image->filter,_image->blur,_exception);
anthony805a2d42011-09-25 08:25:12 +00002533 break;
2534 }
anthonyebb73a22012-03-22 14:25:52 +00002535 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002536 }
2537 case 'h':
2538 {
anthonyafa3dfc2012-03-03 11:31:30 +00002539 if (LocaleCompare("highlight-color",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002540 {
anthony92c93bd2012-03-19 14:02:47 +00002541 (void) SetImageArtifact(_image,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +00002542 break;
2543 }
anthonyebb73a22012-03-22 14:25:52 +00002544 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002545 }
2546 case 'i':
2547 {
anthonyafa3dfc2012-03-03 11:31:30 +00002548 if (LocaleCompare("identify",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002549 {
anthony31f1bf72012-01-30 12:37:22 +00002550 const char
2551 *format,
anthony805a2d42011-09-25 08:25:12 +00002552 *text;
2553
anthony92c93bd2012-03-19 14:02:47 +00002554 format=GetImageOption(_image_info,"format");
anthony805a2d42011-09-25 08:25:12 +00002555 if (format == (char *) NULL)
2556 {
anthony92c93bd2012-03-19 14:02:47 +00002557 (void) IdentifyImage(_image,stdout,_image_info->verbose,
2558 _exception);
anthony805a2d42011-09-25 08:25:12 +00002559 break;
2560 }
anthony92c93bd2012-03-19 14:02:47 +00002561 text=InterpretImageProperties(_image_info,_image,format,_exception);
anthony805a2d42011-09-25 08:25:12 +00002562 if (text == (char *) NULL)
2563 break;
2564 (void) fputs(text,stdout);
2565 (void) fputc('\n',stdout);
anthony31f1bf72012-01-30 12:37:22 +00002566 text=DestroyString((char *)text);
anthony805a2d42011-09-25 08:25:12 +00002567 break;
2568 }
anthonyafa3dfc2012-03-03 11:31:30 +00002569 if (LocaleCompare("implode",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002570 {
anthonyfd706f92012-01-19 04:22:02 +00002571 (void) ParseGeometry(arg1,&geometry_info);
anthony92c93bd2012-03-19 14:02:47 +00002572 new_image=ImplodeImage(_image,geometry_info.rho,
2573 _image->interpolate,_exception);
anthony805a2d42011-09-25 08:25:12 +00002574 break;
2575 }
anthonyafa3dfc2012-03-03 11:31:30 +00002576 if (LocaleCompare("interpolative-resize",option+1) == 0)
cristy947cb4c2011-10-20 18:41:46 +00002577 {
anthony92c93bd2012-03-19 14:02:47 +00002578 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
2579 new_image=InterpolativeResizeImage(_image,geometry.width,
2580 geometry.height,_image->interpolate,_exception);
cristy947cb4c2011-10-20 18:41:46 +00002581 break;
2582 }
anthonyebb73a22012-03-22 14:25:52 +00002583 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002584 }
2585 case 'l':
2586 {
anthonyafa3dfc2012-03-03 11:31:30 +00002587 if (LocaleCompare("lat",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002588 {
anthonyfd706f92012-01-19 04:22:02 +00002589 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002590 if ((flags & PercentValue) != 0)
2591 geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
anthony92c93bd2012-03-19 14:02:47 +00002592 new_image=AdaptiveThresholdImage(_image,(size_t) geometry_info.rho,
anthony31f1bf72012-01-30 12:37:22 +00002593 (size_t) geometry_info.sigma,(double) geometry_info.xi,
anthony92c93bd2012-03-19 14:02:47 +00002594 _exception);
anthony805a2d42011-09-25 08:25:12 +00002595 break;
2596 }
anthonyafa3dfc2012-03-03 11:31:30 +00002597 if (LocaleCompare("level",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002598 {
2599 MagickRealType
2600 black_point,
2601 gamma,
2602 white_point;
2603
2604 MagickStatusType
2605 flags;
2606
anthonyfd706f92012-01-19 04:22:02 +00002607 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002608 black_point=geometry_info.rho;
2609 white_point=(MagickRealType) QuantumRange;
2610 if ((flags & SigmaValue) != 0)
2611 white_point=geometry_info.sigma;
2612 gamma=1.0;
2613 if ((flags & XiValue) != 0)
2614 gamma=geometry_info.xi;
2615 if ((flags & PercentValue) != 0)
2616 {
2617 black_point*=(MagickRealType) (QuantumRange/100.0);
2618 white_point*=(MagickRealType) (QuantumRange/100.0);
2619 }
2620 if ((flags & SigmaValue) == 0)
2621 white_point=(MagickRealType) QuantumRange-black_point;
anthonyafa3dfc2012-03-03 11:31:30 +00002622 if (IfPlusOp || ((flags & AspectValue) != 0))
anthony92c93bd2012-03-19 14:02:47 +00002623 (void) LevelizeImage(_image,black_point,white_point,gamma,_exception);
anthony805a2d42011-09-25 08:25:12 +00002624 else
anthony92c93bd2012-03-19 14:02:47 +00002625 (void) LevelImage(_image,black_point,white_point,gamma,_exception);
anthony805a2d42011-09-25 08:25:12 +00002626 break;
2627 }
anthonyafa3dfc2012-03-03 11:31:30 +00002628 if (LocaleCompare("level-colors",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002629 {
2630 char
2631 token[MaxTextExtent];
2632
2633 const char
2634 *p;
2635
2636 PixelInfo
2637 black_point,
2638 white_point;
2639
anthonyfd706f92012-01-19 04:22:02 +00002640 p=(const char *) arg1;
anthony805a2d42011-09-25 08:25:12 +00002641 GetMagickToken(p,&p,token); /* get black point color */
2642 if ((isalpha((int) *token) != 0) || ((*token == '#') != 0))
cristy269c9412011-10-13 23:41:15 +00002643 (void) QueryColorCompliance(token,AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +00002644 &black_point,_exception);
anthony805a2d42011-09-25 08:25:12 +00002645 else
cristy269c9412011-10-13 23:41:15 +00002646 (void) QueryColorCompliance("#000000",AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +00002647 &black_point,_exception);
anthony805a2d42011-09-25 08:25:12 +00002648 if (isalpha((int) token[0]) || (token[0] == '#'))
2649 GetMagickToken(p,&p,token);
2650 if (*token == '\0')
2651 white_point=black_point; /* set everything to that color */
2652 else
2653 {
2654 if ((isalpha((int) *token) == 0) && ((*token == '#') == 0))
2655 GetMagickToken(p,&p,token); /* Get white point color. */
2656 if ((isalpha((int) *token) != 0) || ((*token == '#') != 0))
cristy269c9412011-10-13 23:41:15 +00002657 (void) QueryColorCompliance(token,AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +00002658 &white_point,_exception);
anthony805a2d42011-09-25 08:25:12 +00002659 else
cristy269c9412011-10-13 23:41:15 +00002660 (void) QueryColorCompliance("#ffffff",AllCompliance,
anthony92c93bd2012-03-19 14:02:47 +00002661 &white_point,_exception);
anthony805a2d42011-09-25 08:25:12 +00002662 }
anthony92c93bd2012-03-19 14:02:47 +00002663 (void) LevelImageColors(_image,&black_point,&white_point,
2664 plus_alt_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00002665 break;
2666 }
anthonyafa3dfc2012-03-03 11:31:30 +00002667 if (LocaleCompare("linear-stretch",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002668 {
2669 double
2670 black_point,
2671 white_point;
2672
2673 MagickStatusType
2674 flags;
2675
anthonyfd706f92012-01-19 04:22:02 +00002676 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002677 black_point=geometry_info.rho;
anthony92c93bd2012-03-19 14:02:47 +00002678 white_point=(MagickRealType) _image->columns*_image->rows;
anthony805a2d42011-09-25 08:25:12 +00002679 if ((flags & SigmaValue) != 0)
2680 white_point=geometry_info.sigma;
2681 if ((flags & PercentValue) != 0)
2682 {
anthony92c93bd2012-03-19 14:02:47 +00002683 black_point*=(double) _image->columns*_image->rows/100.0;
2684 white_point*=(double) _image->columns*_image->rows/100.0;
anthony805a2d42011-09-25 08:25:12 +00002685 }
2686 if ((flags & SigmaValue) == 0)
anthony92c93bd2012-03-19 14:02:47 +00002687 white_point=(MagickRealType) _image->columns*_image->rows-
anthony805a2d42011-09-25 08:25:12 +00002688 black_point;
anthony92c93bd2012-03-19 14:02:47 +00002689 (void) LinearStretchImage(_image,black_point,white_point,_exception);
anthony805a2d42011-09-25 08:25:12 +00002690 break;
2691 }
anthonyafa3dfc2012-03-03 11:31:30 +00002692 if (LocaleCompare("liquid-rescale",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002693 {
anthony92c93bd2012-03-19 14:02:47 +00002694 flags=ParseRegionGeometry(_image,arg1,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00002695 if ((flags & XValue) == 0)
2696 geometry.x=1;
2697 if ((flags & YValue) == 0)
2698 geometry.y=0;
anthony92c93bd2012-03-19 14:02:47 +00002699 new_image=LiquidRescaleImage(_image,geometry.width,
2700 geometry.height,1.0*geometry.x,1.0*geometry.y,_exception);
anthony805a2d42011-09-25 08:25:12 +00002701 break;
2702 }
anthonyafa3dfc2012-03-03 11:31:30 +00002703 if (LocaleCompare("lowlight-color",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002704 {
anthony92c93bd2012-03-19 14:02:47 +00002705 (void) SetImageArtifact(_image,option+1,arg1);
anthony805a2d42011-09-25 08:25:12 +00002706 break;
2707 }
anthonyebb73a22012-03-22 14:25:52 +00002708 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002709 }
2710 case 'm':
2711 {
anthonyafa3dfc2012-03-03 11:31:30 +00002712 if (LocaleCompare("map",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002713 {
2714 Image
2715 *remap_image;
2716
anthony31f1bf72012-01-30 12:37:22 +00002717 /* DEPRECIATED use -remap */
anthony92c93bd2012-03-19 14:02:47 +00002718 remap_image=GetImageCache(_image_info,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00002719 if (remap_image == (Image *) NULL)
2720 break;
anthony92c93bd2012-03-19 14:02:47 +00002721 (void) RemapImage(_quantize_info,_image,remap_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002722 remap_image=DestroyImage(remap_image);
2723 break;
2724 }
anthonyafa3dfc2012-03-03 11:31:30 +00002725 if (LocaleCompare("mask",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002726 {
2727 Image
2728 *mask;
2729
anthonyafa3dfc2012-03-03 11:31:30 +00002730 if (IfPlusOp)
anthony31f1bf72012-01-30 12:37:22 +00002731 { /* Remove a mask. */
anthony92c93bd2012-03-19 14:02:47 +00002732 (void) SetImageMask(_image,(Image *) NULL,_exception);
anthony805a2d42011-09-25 08:25:12 +00002733 break;
2734 }
anthony5330ae02012-03-20 14:17:01 +00002735 /* Set the image mask. */
anthony92c93bd2012-03-19 14:02:47 +00002736 mask=GetImageCache(_image_info,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00002737 if (mask == (Image *) NULL)
2738 break;
anthony92c93bd2012-03-19 14:02:47 +00002739 (void) SetImageMask(_image,mask,_exception);
anthony805a2d42011-09-25 08:25:12 +00002740 mask=DestroyImage(mask);
2741 break;
2742 }
anthonyafa3dfc2012-03-03 11:31:30 +00002743 if (LocaleCompare("matte",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002744 {
anthony31f1bf72012-01-30 12:37:22 +00002745 /* DEPRECIATED */
anthony92c93bd2012-03-19 14:02:47 +00002746 (void) SetImageAlphaChannel(_image,IfNormalOp ? SetAlphaChannel :
2747 DeactivateAlphaChannel, _exception);
anthony805a2d42011-09-25 08:25:12 +00002748 break;
2749 }
anthonya3ef4ed2012-03-17 06:52:53 +00002750 if (LocaleCompare("median",option+1) == 0)
2751 {
2752 /* DEPRECIATED - use -statistic Median */
2753 CLISimpleOperatorImage(cli_wand,"-statistic","Median",arg1);
2754 break;
2755 }
anthonyafa3dfc2012-03-03 11:31:30 +00002756 if (LocaleCompare("mode",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002757 {
anthonyfd706f92012-01-19 04:22:02 +00002758 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002759 if ((flags & SigmaValue) == 0)
2760 geometry_info.sigma=geometry_info.rho;
anthony92c93bd2012-03-19 14:02:47 +00002761 new_image=StatisticImage(_image,ModeStatistic,(size_t)
2762 geometry_info.rho,(size_t) geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00002763 break;
2764 }
anthonyafa3dfc2012-03-03 11:31:30 +00002765 if (LocaleCompare("modulate",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002766 {
anthony92c93bd2012-03-19 14:02:47 +00002767 (void) ModulateImage(_image,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00002768 break;
2769 }
anthonyafa3dfc2012-03-03 11:31:30 +00002770 if (LocaleCompare("monitor",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002771 {
anthony92c93bd2012-03-19 14:02:47 +00002772 (void) SetImageProgressMonitor(_image, IfNormalOp ? MonitorProgress :
anthonyafa3dfc2012-03-03 11:31:30 +00002773 (MagickProgressMonitor) NULL,(void *) NULL);
anthony805a2d42011-09-25 08:25:12 +00002774 break;
2775 }
anthonyafa3dfc2012-03-03 11:31:30 +00002776 if (LocaleCompare("monochrome",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002777 {
anthony92c93bd2012-03-19 14:02:47 +00002778 (void) SetImageType(_image,BilevelType,_exception);
anthony805a2d42011-09-25 08:25:12 +00002779 break;
2780 }
anthonyafa3dfc2012-03-03 11:31:30 +00002781 if (LocaleCompare("morphology",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002782 {
2783 char
2784 token[MaxTextExtent];
2785
2786 const char
2787 *p;
2788
2789 KernelInfo
2790 *kernel;
2791
2792 MorphologyMethod
2793 method;
2794
2795 ssize_t
2796 iterations;
2797
anthonyfd706f92012-01-19 04:22:02 +00002798 p=arg1;
anthony805a2d42011-09-25 08:25:12 +00002799 GetMagickToken(p,&p,token);
2800 method=(MorphologyMethod) ParseCommandOption(
2801 MagickMorphologyOptions,MagickFalse,token);
2802 iterations=1L;
2803 GetMagickToken(p,&p,token);
2804 if ((*p == ':') || (*p == ','))
2805 GetMagickToken(p,&p,token);
2806 if ((*p != '\0'))
2807 iterations=(ssize_t) StringToLong(p);
anthonyfd706f92012-01-19 04:22:02 +00002808 kernel=AcquireKernelInfo(arg2);
anthony805a2d42011-09-25 08:25:12 +00002809 if (kernel == (KernelInfo *) NULL)
2810 {
anthony92c93bd2012-03-19 14:02:47 +00002811 (void) ThrowMagickException(_exception,GetMagickModule(),
anthony31f1bf72012-01-30 12:37:22 +00002812 OptionError,"UnabletoParseKernel","morphology");
anthony805a2d42011-09-25 08:25:12 +00002813 break;
2814 }
anthony92c93bd2012-03-19 14:02:47 +00002815 new_image=MorphologyImage(_image,method,iterations,kernel,_exception);
anthony805a2d42011-09-25 08:25:12 +00002816 kernel=DestroyKernelInfo(kernel);
2817 break;
2818 }
anthonyafa3dfc2012-03-03 11:31:30 +00002819 if (LocaleCompare("motion-blur",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002820 {
anthonyfd706f92012-01-19 04:22:02 +00002821 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002822 if ((flags & SigmaValue) == 0)
2823 geometry_info.sigma=1.0;
anthony92c93bd2012-03-19 14:02:47 +00002824 new_image=MotionBlurImage(_image,geometry_info.rho,
anthony31f1bf72012-01-30 12:37:22 +00002825 geometry_info.sigma,geometry_info.xi,geometry_info.psi,
anthony92c93bd2012-03-19 14:02:47 +00002826 _exception);
anthony805a2d42011-09-25 08:25:12 +00002827 break;
2828 }
anthonyebb73a22012-03-22 14:25:52 +00002829 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002830 }
2831 case 'n':
2832 {
anthonyafa3dfc2012-03-03 11:31:30 +00002833 if (LocaleCompare("negate",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002834 {
anthony92c93bd2012-03-19 14:02:47 +00002835 (void) NegateImage(_image, plus_alt_op, _exception);
anthony805a2d42011-09-25 08:25:12 +00002836 break;
2837 }
anthonyafa3dfc2012-03-03 11:31:30 +00002838 if (LocaleCompare("noise",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002839 {
anthonyafa3dfc2012-03-03 11:31:30 +00002840 if (IfNormalOp)
anthony805a2d42011-09-25 08:25:12 +00002841 {
anthonyfd706f92012-01-19 04:22:02 +00002842 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002843 if ((flags & SigmaValue) == 0)
2844 geometry_info.sigma=geometry_info.rho;
anthony92c93bd2012-03-19 14:02:47 +00002845 new_image=StatisticImage(_image,NonpeakStatistic,(size_t)
2846 geometry_info.rho,(size_t) geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00002847 }
2848 else
2849 {
2850 NoiseType
2851 noise;
2852
anthony31f1bf72012-01-30 12:37:22 +00002853 double
2854 attenuate;
2855
2856 const char*
2857 value;
2858
anthony805a2d42011-09-25 08:25:12 +00002859 noise=(NoiseType) ParseCommandOption(MagickNoiseOptions,
anthony31f1bf72012-01-30 12:37:22 +00002860 MagickFalse,arg1),
2861
anthony92c93bd2012-03-19 14:02:47 +00002862 value=GetImageOption(_image_info,"attenuate");
anthony31f1bf72012-01-30 12:37:22 +00002863 if (value != (const char *) NULL)
2864 attenuate=StringToDouble(value,(char **) NULL);
2865 else
2866 attenuate=1.0;
2867
anthony92c93bd2012-03-19 14:02:47 +00002868 new_image=AddNoiseImage(_image,noise,attenuate,_exception);
anthony805a2d42011-09-25 08:25:12 +00002869 }
2870 break;
2871 }
anthonyafa3dfc2012-03-03 11:31:30 +00002872 if (LocaleCompare("normalize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002873 {
anthony92c93bd2012-03-19 14:02:47 +00002874 (void) NormalizeImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00002875 break;
2876 }
anthonyebb73a22012-03-22 14:25:52 +00002877 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002878 }
2879 case 'o':
2880 {
anthonyafa3dfc2012-03-03 11:31:30 +00002881 if (LocaleCompare("opaque",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002882 {
2883 PixelInfo
2884 target;
2885
anthony92c93bd2012-03-19 14:02:47 +00002886 (void) QueryColorCompliance(arg1,AllCompliance,&target,_exception);
2887 (void) OpaquePaintImage(_image,&target,&_draw_info->fill,plus_alt_op,
2888 _exception);
anthony805a2d42011-09-25 08:25:12 +00002889 break;
2890 }
anthonyafa3dfc2012-03-03 11:31:30 +00002891 if (LocaleCompare("ordered-dither",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002892 {
anthony92c93bd2012-03-19 14:02:47 +00002893 (void) OrderedPosterizeImage(_image,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00002894 break;
2895 }
anthonyebb73a22012-03-22 14:25:52 +00002896 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00002897 }
2898 case 'p':
2899 {
anthonyafa3dfc2012-03-03 11:31:30 +00002900 if (LocaleCompare("paint",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002901 {
anthonyfd706f92012-01-19 04:22:02 +00002902 (void) ParseGeometry(arg1,&geometry_info);
anthony92c93bd2012-03-19 14:02:47 +00002903 new_image=OilPaintImage(_image,geometry_info.rho,geometry_info.sigma,
2904 _exception);
anthony805a2d42011-09-25 08:25:12 +00002905 break;
2906 }
anthonyafa3dfc2012-03-03 11:31:30 +00002907 if (LocaleCompare("polaroid",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002908 {
cristye9e3d382011-12-14 01:50:13 +00002909 const char
2910 *caption;
2911
anthony805a2d42011-09-25 08:25:12 +00002912 double
2913 angle;
2914
anthonyafa3dfc2012-03-03 11:31:30 +00002915 if (IfPlusOp)
anthony31f1bf72012-01-30 12:37:22 +00002916 {
2917 RandomInfo
2918 *random_info;
anthony805a2d42011-09-25 08:25:12 +00002919
anthony31f1bf72012-01-30 12:37:22 +00002920 random_info=AcquireRandomInfo();
2921 angle=22.5*(GetPseudoRandomValue(random_info)-0.5);
2922 random_info=DestroyRandomInfo(random_info);
2923 }
2924 else
anthony805a2d42011-09-25 08:25:12 +00002925 {
2926 SetGeometryInfo(&geometry_info);
anthonyfd706f92012-01-19 04:22:02 +00002927 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00002928 angle=geometry_info.rho;
2929 }
anthony92c93bd2012-03-19 14:02:47 +00002930 caption=GetImageProperty(_image,"caption",_exception);
2931 new_image=PolaroidImage(_image,_draw_info,caption,angle,
2932 _image->interpolate,_exception);
anthony805a2d42011-09-25 08:25:12 +00002933 break;
2934 }
anthonyafa3dfc2012-03-03 11:31:30 +00002935 if (LocaleCompare("posterize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002936 {
anthony31f1bf72012-01-30 12:37:22 +00002937 (void) ParseGeometry(arg1,&geometry_info);
anthony92c93bd2012-03-19 14:02:47 +00002938 (void) PosterizeImage(_image,(size_t) geometry_info.rho,
2939 _quantize_info->dither,_exception);
anthony805a2d42011-09-25 08:25:12 +00002940 break;
2941 }
anthonyafa3dfc2012-03-03 11:31:30 +00002942 if (LocaleCompare("preview",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002943 {
2944 PreviewType
cristy947cb4c2011-10-20 18:41:46 +00002945 preview_type;
anthony170fce92011-10-20 11:50:23 +00002946
anthony31f1bf72012-01-30 12:37:22 +00002947 /* FUTURE: should be a 'Genesis' option?
2948 Option however is also in WandSettingOptionInfo()
cristy947cb4c2011-10-20 18:41:46 +00002949 */
anthony31f1bf72012-01-30 12:37:22 +00002950 preview_type=UndefinedPreview;
anthonyafa3dfc2012-03-03 11:31:30 +00002951 if (IfNormalOp)
anthony31f1bf72012-01-30 12:37:22 +00002952 preview_type=(PreviewType) ParseCommandOption(MagickPreviewOptions,
2953 MagickFalse,arg1);
anthony92c93bd2012-03-19 14:02:47 +00002954 new_image=PreviewImage(_image,preview_type,_exception);
anthony805a2d42011-09-25 08:25:12 +00002955 break;
2956 }
anthonyafa3dfc2012-03-03 11:31:30 +00002957 if (LocaleCompare("profile",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00002958 {
2959 const char
2960 *name;
2961
2962 const StringInfo
2963 *profile;
2964
2965 Image
2966 *profile_image;
2967
2968 ImageInfo
2969 *profile_info;
2970
anthonyafa3dfc2012-03-03 11:31:30 +00002971 if (IfPlusOp)
anthony92c93bd2012-03-19 14:02:47 +00002972 { /* Remove a profile from the _image. */
2973 (void) ProfileImage(_image,arg1,(const unsigned char *)
2974 NULL,0,_exception);
anthony805a2d42011-09-25 08:25:12 +00002975 break;
2976 }
anthony92c93bd2012-03-19 14:02:47 +00002977 /* Associate a profile with the _image. */
2978 profile_info=CloneImageInfo(_image_info);
2979 profile=GetImageProfile(_image,"iptc");
anthony805a2d42011-09-25 08:25:12 +00002980 if (profile != (StringInfo *) NULL)
2981 profile_info->profile=(void *) CloneStringInfo(profile);
anthony92c93bd2012-03-19 14:02:47 +00002982 profile_image=GetImageCache(profile_info,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00002983 profile_info=DestroyImageInfo(profile_info);
2984 if (profile_image == (Image *) NULL)
2985 {
2986 StringInfo
2987 *profile;
2988
anthony92c93bd2012-03-19 14:02:47 +00002989 profile_info=CloneImageInfo(_image_info);
anthonyfd706f92012-01-19 04:22:02 +00002990 (void) CopyMagickString(profile_info->filename,arg1,
anthony805a2d42011-09-25 08:25:12 +00002991 MaxTextExtent);
anthony92c93bd2012-03-19 14:02:47 +00002992 profile=FileToStringInfo(profile_info->filename,~0UL,_exception);
anthony805a2d42011-09-25 08:25:12 +00002993 if (profile != (StringInfo *) NULL)
2994 {
anthony92c93bd2012-03-19 14:02:47 +00002995 (void) ProfileImage(_image,profile_info->magick,
anthony805a2d42011-09-25 08:25:12 +00002996 GetStringInfoDatum(profile),(size_t)
anthony92c93bd2012-03-19 14:02:47 +00002997 GetStringInfoLength(profile),_exception);
anthony805a2d42011-09-25 08:25:12 +00002998 profile=DestroyStringInfo(profile);
2999 }
3000 profile_info=DestroyImageInfo(profile_info);
3001 break;
3002 }
3003 ResetImageProfileIterator(profile_image);
3004 name=GetNextImageProfile(profile_image);
3005 while (name != (const char *) NULL)
3006 {
3007 profile=GetImageProfile(profile_image,name);
3008 if (profile != (StringInfo *) NULL)
anthony92c93bd2012-03-19 14:02:47 +00003009 (void) ProfileImage(_image,name,GetStringInfoDatum(profile),
3010 (size_t) GetStringInfoLength(profile),_exception);
anthony805a2d42011-09-25 08:25:12 +00003011 name=GetNextImageProfile(profile_image);
3012 }
3013 profile_image=DestroyImage(profile_image);
3014 break;
3015 }
anthonyebb73a22012-03-22 14:25:52 +00003016 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003017 }
anthony805a2d42011-09-25 08:25:12 +00003018 case 'r':
3019 {
anthonyafa3dfc2012-03-03 11:31:30 +00003020 if (LocaleCompare("radial-blur",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003021 {
anthonyfd706f92012-01-19 04:22:02 +00003022 flags=ParseGeometry(arg1,&geometry_info);
anthony92c93bd2012-03-19 14:02:47 +00003023 new_image=RadialBlurImage(_image,geometry_info.rho,
3024 geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00003025 break;
3026 }
anthonyafa3dfc2012-03-03 11:31:30 +00003027 if (LocaleCompare("raise",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003028 {
anthony92c93bd2012-03-19 14:02:47 +00003029 flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00003030 if ((flags & SigmaValue) == 0)
3031 geometry.height=geometry.width;
anthony92c93bd2012-03-19 14:02:47 +00003032 (void) RaiseImage(_image,&geometry,normal_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00003033 break;
3034 }
anthonyafa3dfc2012-03-03 11:31:30 +00003035 if (LocaleCompare("random-threshold",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003036 {
anthony92c93bd2012-03-19 14:02:47 +00003037 (void) RandomThresholdImage(_image,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00003038 break;
3039 }
anthonyafa3dfc2012-03-03 11:31:30 +00003040 if (LocaleCompare("remap",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003041 {
3042 Image
3043 *remap_image;
3044
anthony92c93bd2012-03-19 14:02:47 +00003045 remap_image=GetImageCache(_image_info,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00003046 if (remap_image == (Image *) NULL)
3047 break;
anthony92c93bd2012-03-19 14:02:47 +00003048 (void) RemapImage(_quantize_info,_image,remap_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00003049 remap_image=DestroyImage(remap_image);
3050 break;
3051 }
anthonyafa3dfc2012-03-03 11:31:30 +00003052 if (LocaleCompare("repage",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003053 {
anthonyafa3dfc2012-03-03 11:31:30 +00003054 if (IfNormalOp)
anthony92c93bd2012-03-19 14:02:47 +00003055 (void) ResetImagePage(_image,arg1);
anthony31f1bf72012-01-30 12:37:22 +00003056 else
anthony92c93bd2012-03-19 14:02:47 +00003057 (void) ParseAbsoluteGeometry("0x0+0+0",&_image->page);
anthony805a2d42011-09-25 08:25:12 +00003058 break;
3059 }
anthonyafa3dfc2012-03-03 11:31:30 +00003060 if (LocaleCompare("resample",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003061 {
anthony31f1bf72012-01-30 12:37:22 +00003062 /* FUTURE: remove blur arguemnt - no longer used */
anthonyfd706f92012-01-19 04:22:02 +00003063 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003064 if ((flags & SigmaValue) == 0)
3065 geometry_info.sigma=geometry_info.rho;
anthony92c93bd2012-03-19 14:02:47 +00003066 new_image=ResampleImage(_image,geometry_info.rho,
3067 geometry_info.sigma,_image->filter,_image->blur,_exception);
anthony805a2d42011-09-25 08:25:12 +00003068 break;
3069 }
anthonyafa3dfc2012-03-03 11:31:30 +00003070 if (LocaleCompare("resize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003071 {
anthonyafbaed72011-10-26 12:05:04 +00003072 /* FUTURE: remove blur argument - no longer used */
anthony92c93bd2012-03-19 14:02:47 +00003073 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
3074 new_image=ResizeImage(_image,geometry.width,geometry.height,
3075 _image->filter,_image->blur,_exception);
anthony805a2d42011-09-25 08:25:12 +00003076 break;
3077 }
anthonyafa3dfc2012-03-03 11:31:30 +00003078 if (LocaleCompare("roll",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003079 {
anthony92c93bd2012-03-19 14:02:47 +00003080 (void) ParsePageGeometry(_image,arg1,&geometry,_exception);
3081 new_image=RollImage(_image,geometry.x,geometry.y,_exception);
anthony805a2d42011-09-25 08:25:12 +00003082 break;
3083 }
anthonyafa3dfc2012-03-03 11:31:30 +00003084 if (LocaleCompare("rotate",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003085 {
anthonyfd706f92012-01-19 04:22:02 +00003086 if (strchr(arg1,'>') != (char *) NULL)
anthony92c93bd2012-03-19 14:02:47 +00003087 if (_image->columns <= _image->rows)
anthony805a2d42011-09-25 08:25:12 +00003088 break;
anthonyfd706f92012-01-19 04:22:02 +00003089 if (strchr(arg1,'<') != (char *) NULL)
anthony92c93bd2012-03-19 14:02:47 +00003090 if (_image->columns >= _image->rows)
anthony805a2d42011-09-25 08:25:12 +00003091 break;
anthonyafbaed72011-10-26 12:05:04 +00003092
anthonyfd706f92012-01-19 04:22:02 +00003093 (void) ParseGeometry(arg1,&geometry_info);
anthony92c93bd2012-03-19 14:02:47 +00003094 new_image=RotateImage(_image,geometry_info.rho,_exception);
anthony805a2d42011-09-25 08:25:12 +00003095 break;
3096 }
anthonyebb73a22012-03-22 14:25:52 +00003097 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003098 }
3099 case 's':
3100 {
anthonyafa3dfc2012-03-03 11:31:30 +00003101 if (LocaleCompare("sample",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003102 {
anthony92c93bd2012-03-19 14:02:47 +00003103 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
3104 new_image=SampleImage(_image,geometry.width,geometry.height,
3105 _exception);
anthony805a2d42011-09-25 08:25:12 +00003106 break;
3107 }
anthonyafa3dfc2012-03-03 11:31:30 +00003108 if (LocaleCompare("scale",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003109 {
anthony92c93bd2012-03-19 14:02:47 +00003110 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
3111 new_image=ScaleImage(_image,geometry.width,geometry.height,
3112 _exception);
anthony805a2d42011-09-25 08:25:12 +00003113 break;
3114 }
anthonyafa3dfc2012-03-03 11:31:30 +00003115 if (LocaleCompare("selective-blur",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003116 {
anthonyfd706f92012-01-19 04:22:02 +00003117 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003118 if ((flags & PercentValue) != 0)
3119 geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
anthony92c93bd2012-03-19 14:02:47 +00003120 new_image=SelectiveBlurImage(_image,geometry_info.rho,
3121 geometry_info.sigma,geometry_info.xi,geometry_info.psi,_exception);
anthony805a2d42011-09-25 08:25:12 +00003122 break;
3123 }
anthonyafa3dfc2012-03-03 11:31:30 +00003124 if (LocaleCompare("separate",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003125 {
anthony31f1bf72012-01-30 12:37:22 +00003126 /* WARNING: This can generate multiple images! */
anthony43f425d2012-02-26 12:58:58 +00003127 /* FUTURE - this may be replaced by a "-channel" method */
cristydfdb19e2012-03-21 22:22:24 +00003128 new_image=SeparateImages(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00003129 break;
3130 }
anthonyafa3dfc2012-03-03 11:31:30 +00003131 if (LocaleCompare("sepia-tone",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003132 {
3133 double
3134 threshold;
3135
anthonyfd706f92012-01-19 04:22:02 +00003136 threshold=StringToDoubleInterval(arg1,(double) QuantumRange+1.0);
anthony92c93bd2012-03-19 14:02:47 +00003137 new_image=SepiaToneImage(_image,threshold,_exception);
anthony805a2d42011-09-25 08:25:12 +00003138 break;
3139 }
anthonyafa3dfc2012-03-03 11:31:30 +00003140 if (LocaleCompare("segment",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003141 {
anthonyfd706f92012-01-19 04:22:02 +00003142 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003143 if ((flags & SigmaValue) == 0)
3144 geometry_info.sigma=1.0;
anthony92c93bd2012-03-19 14:02:47 +00003145 (void) SegmentImage(_image,_image->colorspace,
3146 _image_info->verbose,geometry_info.rho,geometry_info.sigma,
3147 _exception);
anthony805a2d42011-09-25 08:25:12 +00003148 break;
3149 }
anthonyafa3dfc2012-03-03 11:31:30 +00003150 if (LocaleCompare("set",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003151 {
3152 char
3153 *value;
3154
anthonyafa3dfc2012-03-03 11:31:30 +00003155 if (IfPlusOp)
anthony805a2d42011-09-25 08:25:12 +00003156 {
anthonyfd706f92012-01-19 04:22:02 +00003157 if (LocaleNCompare(arg1,"registry:",9) == 0)
3158 (void) DeleteImageRegistry(arg1+9);
anthony805a2d42011-09-25 08:25:12 +00003159 else
anthony31f1bf72012-01-30 12:37:22 +00003160 if (LocaleNCompare(arg1,"option:",7) == 0)
anthony805a2d42011-09-25 08:25:12 +00003161 {
anthony92c93bd2012-03-19 14:02:47 +00003162 (void) DeleteImageOption(_image_info,arg1+7);
3163 (void) DeleteImageArtifact(_image,arg1+7);
anthony805a2d42011-09-25 08:25:12 +00003164 }
3165 else
anthony92c93bd2012-03-19 14:02:47 +00003166 (void) DeleteImageProperty(_image,arg1);
anthony805a2d42011-09-25 08:25:12 +00003167 break;
3168 }
anthony92c93bd2012-03-19 14:02:47 +00003169 value=InterpretImageProperties(_image_info,_image,arg2,
3170 _exception);
anthony805a2d42011-09-25 08:25:12 +00003171 if (value == (char *) NULL)
3172 break;
anthonyfd706f92012-01-19 04:22:02 +00003173 if (LocaleNCompare(arg1,"registry:",9) == 0)
3174 (void) SetImageRegistry(StringRegistryType,arg1+9,value,
anthony92c93bd2012-03-19 14:02:47 +00003175 _exception);
anthony805a2d42011-09-25 08:25:12 +00003176 else
anthonyfd706f92012-01-19 04:22:02 +00003177 if (LocaleNCompare(arg1,"option:",7) == 0)
anthony805a2d42011-09-25 08:25:12 +00003178 {
anthony92c93bd2012-03-19 14:02:47 +00003179 (void) SetImageOption(_image_info,arg1+7,value);
3180 (void) SetImageArtifact(_image,arg1+7,value);
anthony805a2d42011-09-25 08:25:12 +00003181 }
3182 else
anthony92c93bd2012-03-19 14:02:47 +00003183 (void) SetImageProperty(_image,arg1,value,_exception);
anthony805a2d42011-09-25 08:25:12 +00003184 value=DestroyString(value);
3185 break;
3186 }
anthonyafa3dfc2012-03-03 11:31:30 +00003187 if (LocaleCompare("shade",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003188 {
anthonyfd706f92012-01-19 04:22:02 +00003189 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003190 if ((flags & SigmaValue) == 0)
3191 geometry_info.sigma=1.0;
anthony92c93bd2012-03-19 14:02:47 +00003192 new_image=ShadeImage(_image,normal_op,geometry_info.rho,
3193 geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00003194 break;
3195 }
anthonyafa3dfc2012-03-03 11:31:30 +00003196 if (LocaleCompare("shadow",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003197 {
anthonyfd706f92012-01-19 04:22:02 +00003198 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003199 if ((flags & SigmaValue) == 0)
3200 geometry_info.sigma=1.0;
3201 if ((flags & XiValue) == 0)
3202 geometry_info.xi=4.0;
3203 if ((flags & PsiValue) == 0)
3204 geometry_info.psi=4.0;
anthony92c93bd2012-03-19 14:02:47 +00003205 new_image=ShadowImage(_image,geometry_info.rho,
3206 geometry_info.sigma,_image->bias,(ssize_t)
cristyeb6e6582011-12-09 09:14:23 +00003207 ceil(geometry_info.xi-0.5),(ssize_t) ceil(geometry_info.psi-0.5),
anthony92c93bd2012-03-19 14:02:47 +00003208 _exception);
anthony805a2d42011-09-25 08:25:12 +00003209 break;
3210 }
anthonyafa3dfc2012-03-03 11:31:30 +00003211 if (LocaleCompare("sharpen",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003212 {
anthonyfd706f92012-01-19 04:22:02 +00003213 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003214 if ((flags & SigmaValue) == 0)
3215 geometry_info.sigma=1.0;
3216 if ((flags & XiValue) == 0)
3217 geometry_info.xi=0.0;
anthony92c93bd2012-03-19 14:02:47 +00003218 new_image=SharpenImage(_image,geometry_info.rho,
3219 geometry_info.sigma,geometry_info.xi,_exception);
anthony805a2d42011-09-25 08:25:12 +00003220 break;
3221 }
anthonyafa3dfc2012-03-03 11:31:30 +00003222 if (LocaleCompare("shave",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003223 {
anthony92c93bd2012-03-19 14:02:47 +00003224 flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
3225 new_image=ShaveImage(_image,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00003226 break;
3227 }
anthonyafa3dfc2012-03-03 11:31:30 +00003228 if (LocaleCompare("shear",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003229 {
anthonyfd706f92012-01-19 04:22:02 +00003230 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003231 if ((flags & SigmaValue) == 0)
3232 geometry_info.sigma=geometry_info.rho;
anthony92c93bd2012-03-19 14:02:47 +00003233 new_image=ShearImage(_image,geometry_info.rho,
3234 geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00003235 break;
3236 }
anthonyafa3dfc2012-03-03 11:31:30 +00003237 if (LocaleCompare("sigmoidal-contrast",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003238 {
anthonyfd706f92012-01-19 04:22:02 +00003239 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003240 if ((flags & SigmaValue) == 0)
3241 geometry_info.sigma=(double) QuantumRange/2.0;
3242 if ((flags & PercentValue) != 0)
3243 geometry_info.sigma=(double) QuantumRange*geometry_info.sigma/
3244 100.0;
anthony92c93bd2012-03-19 14:02:47 +00003245 (void) SigmoidalContrastImage(_image,normal_op,geometry_info.rho,
anthony31f1bf72012-01-30 12:37:22 +00003246 geometry_info.sigma,
anthony92c93bd2012-03-19 14:02:47 +00003247 _exception);
anthony805a2d42011-09-25 08:25:12 +00003248 break;
3249 }
anthonyafa3dfc2012-03-03 11:31:30 +00003250 if (LocaleCompare("sketch",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003251 {
anthonyfd706f92012-01-19 04:22:02 +00003252 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003253 if ((flags & SigmaValue) == 0)
3254 geometry_info.sigma=1.0;
anthony92c93bd2012-03-19 14:02:47 +00003255 new_image=SketchImage(_image,geometry_info.rho,
3256 geometry_info.sigma,geometry_info.xi,geometry_info.psi,_exception);
anthony805a2d42011-09-25 08:25:12 +00003257 break;
3258 }
anthonyafa3dfc2012-03-03 11:31:30 +00003259 if (LocaleCompare("solarize",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003260 {
anthony92c93bd2012-03-19 14:02:47 +00003261 (void) SolarizeImage(_image,StringToDoubleInterval(arg1,(double)
3262 QuantumRange+1.0),_exception);
anthony805a2d42011-09-25 08:25:12 +00003263 break;
3264 }
anthonyafa3dfc2012-03-03 11:31:30 +00003265 if (LocaleCompare("sparse-color",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003266 {
3267 SparseColorMethod
3268 method;
3269
3270 char
3271 *arguments;
3272
anthony805a2d42011-09-25 08:25:12 +00003273 method=(SparseColorMethod) ParseCommandOption(
anthonyfd706f92012-01-19 04:22:02 +00003274 MagickSparseColorOptions,MagickFalse,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003275 arguments=InterpretImageProperties(_image_info,_image,arg2,_exception);
anthony805a2d42011-09-25 08:25:12 +00003276 if (arguments == (char *) NULL)
3277 break;
anthony92c93bd2012-03-19 14:02:47 +00003278 new_image=SparseColorOption(_image,method,arguments,_exception);
anthony805a2d42011-09-25 08:25:12 +00003279 arguments=DestroyString(arguments);
3280 break;
3281 }
anthonyafa3dfc2012-03-03 11:31:30 +00003282 if (LocaleCompare("splice",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003283 {
anthony92c93bd2012-03-19 14:02:47 +00003284 (void) ParseGravityGeometry(_image,arg1,&geometry,_exception);
3285 new_image=SpliceImage(_image,&geometry,_exception);
anthony805a2d42011-09-25 08:25:12 +00003286 break;
3287 }
anthonyafa3dfc2012-03-03 11:31:30 +00003288 if (LocaleCompare("spread",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003289 {
anthonyfd706f92012-01-19 04:22:02 +00003290 (void) ParseGeometry(arg1,&geometry_info);
anthony92c93bd2012-03-19 14:02:47 +00003291 new_image=SpreadImage(_image,geometry_info.rho,_image->interpolate,
3292 _exception);
anthony805a2d42011-09-25 08:25:12 +00003293 break;
3294 }
anthonyafa3dfc2012-03-03 11:31:30 +00003295 if (LocaleCompare("statistic",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003296 {
3297 StatisticType
3298 type;
3299
anthony805a2d42011-09-25 08:25:12 +00003300 type=(StatisticType) ParseCommandOption(MagickStatisticOptions,
anthonyfd706f92012-01-19 04:22:02 +00003301 MagickFalse,arg1);
3302 (void) ParseGeometry(arg2,&geometry_info);
anthony92c93bd2012-03-19 14:02:47 +00003303 new_image=StatisticImage(_image,type,(size_t) geometry_info.rho,
3304 (size_t) geometry_info.sigma,_exception);
anthony805a2d42011-09-25 08:25:12 +00003305 break;
3306 }
anthonyafa3dfc2012-03-03 11:31:30 +00003307 if (LocaleCompare("strip",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003308 {
anthony92c93bd2012-03-19 14:02:47 +00003309 (void) StripImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00003310 break;
3311 }
anthonyafa3dfc2012-03-03 11:31:30 +00003312 if (LocaleCompare("swirl",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003313 {
anthonyfd706f92012-01-19 04:22:02 +00003314 (void) ParseGeometry(arg1,&geometry_info);
anthony92c93bd2012-03-19 14:02:47 +00003315 new_image=SwirlImage(_image,geometry_info.rho,
3316 _image->interpolate,_exception);
anthony805a2d42011-09-25 08:25:12 +00003317 break;
3318 }
anthonyebb73a22012-03-22 14:25:52 +00003319 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003320 }
3321 case 't':
3322 {
anthonyafa3dfc2012-03-03 11:31:30 +00003323 if (LocaleCompare("threshold",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003324 {
3325 double
3326 threshold;
3327
anthonyafa3dfc2012-03-03 11:31:30 +00003328 if (!normal_op)
anthony805a2d42011-09-25 08:25:12 +00003329 threshold=(double) QuantumRange/2;
3330 else
anthonyfd706f92012-01-19 04:22:02 +00003331 threshold=StringToDoubleInterval(arg1,(double) QuantumRange+1.0);
anthony92c93bd2012-03-19 14:02:47 +00003332 (void) BilevelImage(_image,threshold,_exception);
anthony805a2d42011-09-25 08:25:12 +00003333 break;
3334 }
anthonyafa3dfc2012-03-03 11:31:30 +00003335 if (LocaleCompare("thumbnail",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003336 {
anthony92c93bd2012-03-19 14:02:47 +00003337 (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
3338 new_image=ThumbnailImage(_image,geometry.width,geometry.height,
3339 _exception);
anthony805a2d42011-09-25 08:25:12 +00003340 break;
3341 }
anthonyafa3dfc2012-03-03 11:31:30 +00003342 if (LocaleCompare("tint",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003343 {
anthony92c93bd2012-03-19 14:02:47 +00003344 new_image=TintImage(_image,arg1,&_draw_info->fill,_exception);
anthony805a2d42011-09-25 08:25:12 +00003345 break;
3346 }
anthonyafa3dfc2012-03-03 11:31:30 +00003347 if (LocaleCompare("transform",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003348 {
anthonya3ef4ed2012-03-17 06:52:53 +00003349 /* DEPRECIATED -- should really use Distort AffineProjection */
anthony92c93bd2012-03-19 14:02:47 +00003350 new_image=AffineTransformImage(_image,&_draw_info->affine,
3351 _exception);
anthony805a2d42011-09-25 08:25:12 +00003352 break;
3353 }
anthonyafa3dfc2012-03-03 11:31:30 +00003354 if (LocaleCompare("transparent",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003355 {
3356 PixelInfo
3357 target;
3358
anthony92c93bd2012-03-19 14:02:47 +00003359 (void) QueryColorCompliance(arg1,AllCompliance,&target,_exception);
3360 (void) TransparentPaintImage(_image,&target,(Quantum)
3361 TransparentAlpha,plus_alt_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00003362 break;
3363 }
anthonyafa3dfc2012-03-03 11:31:30 +00003364 if (LocaleCompare("transpose",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003365 {
anthony92c93bd2012-03-19 14:02:47 +00003366 new_image=TransposeImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00003367 break;
3368 }
anthonyafa3dfc2012-03-03 11:31:30 +00003369 if (LocaleCompare("transverse",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003370 {
anthony92c93bd2012-03-19 14:02:47 +00003371 new_image=TransverseImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00003372 break;
3373 }
anthonyafa3dfc2012-03-03 11:31:30 +00003374 if (LocaleCompare("trim",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003375 {
anthony92c93bd2012-03-19 14:02:47 +00003376 new_image=TrimImage(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00003377 break;
3378 }
anthonyafa3dfc2012-03-03 11:31:30 +00003379 if (LocaleCompare("type",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003380 {
anthonyab3a50c2011-10-27 11:48:57 +00003381 /* Note that "type" setting should have already been defined */
anthony92c93bd2012-03-19 14:02:47 +00003382 (void) SetImageType(_image,_image_info->type,_exception);
anthony805a2d42011-09-25 08:25:12 +00003383 break;
3384 }
anthonyebb73a22012-03-22 14:25:52 +00003385 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003386 }
3387 case 'u':
3388 {
anthonyafa3dfc2012-03-03 11:31:30 +00003389 if (LocaleCompare("unique",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003390 {
anthony31f1bf72012-01-30 12:37:22 +00003391 /* FUTURE: move to SyncImageSettings() and AcqireImage()??? */
anthony24aa8822012-03-11 00:56:06 +00003392 /* FUTURE: This option is not documented!!!!! */
anthonyafa3dfc2012-03-03 11:31:30 +00003393 if (!normal_op)
anthony805a2d42011-09-25 08:25:12 +00003394 {
anthony92c93bd2012-03-19 14:02:47 +00003395 (void) DeleteImageArtifact(_image,"identify:unique-colors");
anthony805a2d42011-09-25 08:25:12 +00003396 break;
3397 }
anthony92c93bd2012-03-19 14:02:47 +00003398 (void) SetImageArtifact(_image,"identify:unique-colors","true");
3399 (void) SetImageArtifact(_image,"verbose","true");
anthony805a2d42011-09-25 08:25:12 +00003400 break;
3401 }
anthonyafa3dfc2012-03-03 11:31:30 +00003402 if (LocaleCompare("unique-colors",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003403 {
anthony92c93bd2012-03-19 14:02:47 +00003404 new_image=UniqueImageColors(_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00003405 break;
3406 }
anthonyafa3dfc2012-03-03 11:31:30 +00003407 if (LocaleCompare("unsharp",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003408 {
anthonyfd706f92012-01-19 04:22:02 +00003409 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003410 if ((flags & SigmaValue) == 0)
3411 geometry_info.sigma=1.0;
3412 if ((flags & XiValue) == 0)
3413 geometry_info.xi=1.0;
3414 if ((flags & PsiValue) == 0)
3415 geometry_info.psi=0.05;
anthony92c93bd2012-03-19 14:02:47 +00003416 new_image=UnsharpMaskImage(_image,geometry_info.rho,
3417 geometry_info.sigma,geometry_info.xi,geometry_info.psi,_exception);
anthony805a2d42011-09-25 08:25:12 +00003418 break;
3419 }
anthonyebb73a22012-03-22 14:25:52 +00003420 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003421 }
3422 case 'v':
3423 {
anthonyafa3dfc2012-03-03 11:31:30 +00003424 if (LocaleCompare("verbose",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003425 {
anthonyafa3dfc2012-03-03 11:31:30 +00003426 /* FUTURE: move to SyncImageSettings() and AcquireImage()???
anthony92c93bd2012-03-19 14:02:47 +00003427 three places! ImageArtifact ImageOption _image_info->verbose
anthony5330ae02012-03-20 14:17:01 +00003428 Some how new images also get this artifact!
anthony31f1bf72012-01-30 12:37:22 +00003429 */
anthony92c93bd2012-03-19 14:02:47 +00003430 (void) SetImageArtifact(_image,option+1,
anthonyafa3dfc2012-03-03 11:31:30 +00003431 IfNormalOp ? "true" : "false" );
anthony805a2d42011-09-25 08:25:12 +00003432 break;
3433 }
anthonyafa3dfc2012-03-03 11:31:30 +00003434 if (LocaleCompare("vignette",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003435 {
anthonyfd706f92012-01-19 04:22:02 +00003436 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003437 if ((flags & SigmaValue) == 0)
3438 geometry_info.sigma=1.0;
3439 if ((flags & XiValue) == 0)
anthony92c93bd2012-03-19 14:02:47 +00003440 geometry_info.xi=0.1*_image->columns;
anthony805a2d42011-09-25 08:25:12 +00003441 if ((flags & PsiValue) == 0)
anthony92c93bd2012-03-19 14:02:47 +00003442 geometry_info.psi=0.1*_image->rows;
3443 new_image=VignetteImage(_image,geometry_info.rho,geometry_info.sigma,
3444 _image->bias,(ssize_t) ceil(geometry_info.xi-0.5),
3445 (ssize_t) ceil(geometry_info.psi-0.5),_exception);
anthony805a2d42011-09-25 08:25:12 +00003446 break;
3447 }
anthonyebb73a22012-03-22 14:25:52 +00003448 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003449 }
3450 case 'w':
3451 {
anthonyafa3dfc2012-03-03 11:31:30 +00003452 if (LocaleCompare("wave",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003453 {
anthonyfd706f92012-01-19 04:22:02 +00003454 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00003455 if ((flags & SigmaValue) == 0)
3456 geometry_info.sigma=1.0;
anthony92c93bd2012-03-19 14:02:47 +00003457 new_image=WaveImage(_image,geometry_info.rho,geometry_info.sigma,
3458 _image->interpolate,_exception);
anthony805a2d42011-09-25 08:25:12 +00003459 break;
3460 }
anthonyafa3dfc2012-03-03 11:31:30 +00003461 if (LocaleCompare("white-threshold",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003462 {
anthony92c93bd2012-03-19 14:02:47 +00003463 (void) WhiteThresholdImage(_image,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00003464 break;
3465 }
anthonyebb73a22012-03-22 14:25:52 +00003466 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003467 }
3468 default:
anthonyebb73a22012-03-22 14:25:52 +00003469 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003470 }
3471 /*
3472 Replace current image with any image that was generated
anthony31f1bf72012-01-30 12:37:22 +00003473 and set image point to last image (so image->next is correct)
anthony805a2d42011-09-25 08:25:12 +00003474 */
3475 if (new_image != (Image *) NULL)
anthony92c93bd2012-03-19 14:02:47 +00003476 ReplaceImageInListReturnLast(&_image,new_image);
anthony805a2d42011-09-25 08:25:12 +00003477
anthony31f1bf72012-01-30 12:37:22 +00003478 return;
anthony92c93bd2012-03-19 14:02:47 +00003479#undef _image_info
3480#undef _draw_info
3481#undef _quantize_info
3482#undef _image
3483#undef _exception
anthonyafa3dfc2012-03-03 11:31:30 +00003484#undef IfNormalOp
3485#undef IfPlusOp
anthony31f1bf72012-01-30 12:37:22 +00003486#undef normal_op
anthonyafa3dfc2012-03-03 11:31:30 +00003487#undef plus_alt_op
anthony31f1bf72012-01-30 12:37:22 +00003488}
anthonyfd706f92012-01-19 04:22:02 +00003489
anthony43f425d2012-02-26 12:58:58 +00003490WandExport void CLISimpleOperatorImages(MagickCLI *cli_wand,
anthonyafa3dfc2012-03-03 11:31:30 +00003491 const char *option, const char *arg1, const char *arg2)
anthony31f1bf72012-01-30 12:37:22 +00003492{
3493 size_t
anthony43f425d2012-02-26 12:58:58 +00003494 n,
anthony31f1bf72012-01-30 12:37:22 +00003495 i;
3496
anthony43f425d2012-02-26 12:58:58 +00003497 assert(cli_wand != (MagickCLI *) NULL);
3498 assert(cli_wand->signature == WandSignature);
3499 assert(cli_wand->wand.signature == WandSignature);
3500 assert(cli_wand->wand.images != (Image *) NULL); /* images must be present */
3501 if (cli_wand->wand.debug != MagickFalse)
3502 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
anthony31f1bf72012-01-30 12:37:22 +00003503
anthonyafa3dfc2012-03-03 11:31:30 +00003504#if !USE_WAND_METHODS
3505 /* FUTURE add appropriate tracing */
anthony31f1bf72012-01-30 12:37:22 +00003506 i=0;
anthony43f425d2012-02-26 12:58:58 +00003507 n=GetImageListLength(cli_wand->wand.images);
3508 cli_wand->wand.images=GetFirstImageInList(cli_wand->wand.images);
anthonyafa3dfc2012-03-03 11:31:30 +00003509 while (1) {
anthony31f1bf72012-01-30 12:37:22 +00003510 i++;
anthonyafa3dfc2012-03-03 11:31:30 +00003511 CLISimpleOperatorImage(cli_wand, option, arg1, arg2);
anthony43f425d2012-02-26 12:58:58 +00003512 if ( cli_wand->wand.images->next == (Image *) NULL )
3513 break;
3514 cli_wand->wand.images=cli_wand->wand.images->next;
anthony31f1bf72012-01-30 12:37:22 +00003515 }
anthony43f425d2012-02-26 12:58:58 +00003516 assert( i == n );
3517 cli_wand->wand.images=GetFirstImageInList(cli_wand->wand.images);
anthonyafa3dfc2012-03-03 11:31:30 +00003518#else
3519 MagickResetIterator(&cli_wand->wand);
3520 while ( MagickNextImage(&cli_wand->wand) != MagickFalse )
3521 CLISimpleOperatorImage(cli_wand, option, arg1, arg2);
3522 MagickResetIterator(&cli_wand->wand);
3523#endif
anthony31f1bf72012-01-30 12:37:22 +00003524 return;
anthony805a2d42011-09-25 08:25:12 +00003525}
3526
3527/*
3528%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3529% %
3530% %
3531% %
anthony43f425d2012-02-26 12:58:58 +00003532+ 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 +00003533% %
3534% %
3535% %
3536%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3537%
anthony43f425d2012-02-26 12:58:58 +00003538% CLIListOperatorImages() applies a single operation that is apply to the
anthony31f1bf72012-01-30 12:37:22 +00003539% entire image list as a whole. The result is often a complete replacment
3540% of the image list with a completely new list, or just a single image.
anthony805a2d42011-09-25 08:25:12 +00003541%
3542% The format of the MogrifyImage method is:
3543%
anthony43f425d2012-02-26 12:58:58 +00003544% void CLIListOperatorImages(MagickCLI *cli_wand,
anthonyafa3dfc2012-03-03 11:31:30 +00003545% const char *option, const char *arg1, const char *arg2)
anthony805a2d42011-09-25 08:25:12 +00003546%
3547% A description of each parameter follows:
3548%
anthony43f425d2012-02-26 12:58:58 +00003549% o cli_wand: structure holding settings to be applied
anthony805a2d42011-09-25 08:25:12 +00003550%
anthony36a8c2c2012-02-10 00:08:44 +00003551% o option: The option string for the operation
3552%
anthony31f1bf72012-01-30 12:37:22 +00003553% o arg1, arg2: optional argument strings to the operation
anthony805a2d42011-09-25 08:25:12 +00003554%
anthony8b10b462012-02-08 12:32:44 +00003555% NOTE: only "limit" currently uses two arguments.
3556%
3557% Example usage...
3558%
anthonyafa3dfc2012-03-03 11:31:30 +00003559% CLIListOperatorImages(cli_wand,MagickFalse,"-duplicate", "3", NULL);
3560% CLIListOperatorImages(cli_wand,MagickTrue, "+append", NULL, NULL);
anthony8b10b462012-02-08 12:32:44 +00003561%
anthony24aa8822012-03-11 00:56:06 +00003562% Or for handling command line arguments EG: +/-option ["arg1"]
anthony8b10b462012-02-08 12:32:44 +00003563%
anthony43f425d2012-02-26 12:58:58 +00003564% cli_wand
anthony8b10b462012-02-08 12:32:44 +00003565% argc,argv
3566% i=index in argv
3567%
anthony2052d272012-02-28 12:48:29 +00003568% option_info = GetCommandOptionInfo(argv[i]);
3569% count=option_info->type;
3570% option_type=option_info->flags;
3571%
3572% if ( (option_type & ListOperatorOptionFlag) != 0 )
anthonyafa3dfc2012-03-03 11:31:30 +00003573% CLIListOperatorImages(cli_wand,argv[i],
anthony8b10b462012-02-08 12:32:44 +00003574% count>=1 ? argv[i+1] : (char *)NULL,
3575% count>=2 ? argv[i+2] : (char *)NULL );
3576% i += count+1;
3577%
anthony805a2d42011-09-25 08:25:12 +00003578*/
anthony43f425d2012-02-26 12:58:58 +00003579WandExport void CLIListOperatorImages(MagickCLI *cli_wand,
anthonyafa3dfc2012-03-03 11:31:30 +00003580 const char *option,const char *arg1, const char *arg2)
anthony805a2d42011-09-25 08:25:12 +00003581{
anthony31f1bf72012-01-30 12:37:22 +00003582 Image
3583 *new_images;
anthony805a2d42011-09-25 08:25:12 +00003584
anthony92c93bd2012-03-19 14:02:47 +00003585#define _image_info (cli_wand->wand.image_info)
3586#define _images (cli_wand->wand.images)
3587#define _exception (cli_wand->wand.exception)
3588#define _draw_info (cli_wand->draw_info)
3589#define _quantize_info (cli_wand->quantize_info)
anthonyafa3dfc2012-03-03 11:31:30 +00003590#define IfNormalOp (*option=='-')
3591#define IfPlusOp (*option!='-')
3592#define normal_op (IfNormalOp?MagickTrue:MagickFalse)
anthony805a2d42011-09-25 08:25:12 +00003593
anthony43f425d2012-02-26 12:58:58 +00003594 assert(cli_wand != (MagickCLI *) NULL);
3595 assert(cli_wand->signature == WandSignature);
3596 assert(cli_wand->wand.signature == WandSignature);
anthony92c93bd2012-03-19 14:02:47 +00003597 assert(_images != (Image *) NULL); /* _images must be present */
anthony43f425d2012-02-26 12:58:58 +00003598 if (cli_wand->wand.debug != MagickFalse)
3599 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
anthony31f1bf72012-01-30 12:37:22 +00003600
anthony92c93bd2012-03-19 14:02:47 +00003601 (void) SyncImagesSettings(_image_info,_images,_exception);
anthony31f1bf72012-01-30 12:37:22 +00003602
3603 new_images=NewImageList();
3604
anthonyafa3dfc2012-03-03 11:31:30 +00003605 switch (*(option+1))
anthony805a2d42011-09-25 08:25:12 +00003606 {
3607 case 'a':
3608 {
anthonyafa3dfc2012-03-03 11:31:30 +00003609 if (LocaleCompare("append",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003610 {
anthony92c93bd2012-03-19 14:02:47 +00003611 new_images=AppendImages(_images,normal_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00003612 break;
3613 }
anthonyafa3dfc2012-03-03 11:31:30 +00003614 if (LocaleCompare("average",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003615 {
anthony31f1bf72012-01-30 12:37:22 +00003616 /* DEPRECIATED - use -evaluate-sequence Mean */
anthonyafa3dfc2012-03-03 11:31:30 +00003617 CLIListOperatorImages(cli_wand,"-evaluate-sequence","Mean",NULL);
anthony805a2d42011-09-25 08:25:12 +00003618 break;
3619 }
anthonyebb73a22012-03-22 14:25:52 +00003620 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003621 }
3622 case 'c':
3623 {
cristy5f257b22012-03-07 00:27:29 +00003624 if (LocaleCompare("channel-fx",option+1) == 0)
cristy87c02f42012-02-24 00:19:10 +00003625 {
anthony92c93bd2012-03-19 14:02:47 +00003626 new_images=ChannelFxImage(_images,arg1,_exception);
cristy87c02f42012-02-24 00:19:10 +00003627 break;
3628 }
anthonyafa3dfc2012-03-03 11:31:30 +00003629 if (LocaleCompare("clut",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003630 {
anthony805a2d42011-09-25 08:25:12 +00003631 Image
anthony31f1bf72012-01-30 12:37:22 +00003632 *clut_image;
anthony805a2d42011-09-25 08:25:12 +00003633
anthonyafa3dfc2012-03-03 11:31:30 +00003634 /* FUTURE - make this a compose option, and thus can be used
3635 with layers compose or even compose last image over all other
anthony92c93bd2012-03-19 14:02:47 +00003636 _images.
cristy87c02f42012-02-24 00:19:10 +00003637 */
anthony92c93bd2012-03-19 14:02:47 +00003638 new_images=RemoveFirstImageFromList(&_images);
3639 clut_image=RemoveLastImageFromList(&_images);
anthonye8f56492012-02-12 12:39:02 +00003640 /* FUTURE - produce Exception, rather than silent fail */
anthony805a2d42011-09-25 08:25:12 +00003641 if (clut_image == (Image *) NULL)
cristy87c02f42012-02-24 00:19:10 +00003642 break;
anthony92c93bd2012-03-19 14:02:47 +00003643 (void) ClutImage(new_images,clut_image,_images->interpolate,_exception);
anthony805a2d42011-09-25 08:25:12 +00003644 clut_image=DestroyImage(clut_image);
anthony805a2d42011-09-25 08:25:12 +00003645 break;
3646 }
anthonyafa3dfc2012-03-03 11:31:30 +00003647 if (LocaleCompare("coalesce",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003648 {
anthony92c93bd2012-03-19 14:02:47 +00003649 new_images=CoalesceImages(_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003650 break;
3651 }
anthonyafa3dfc2012-03-03 11:31:30 +00003652 if (LocaleCompare("combine",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003653 {
anthony43f425d2012-02-26 12:58:58 +00003654 /* FUTURE - this may be replaced by a 'channel' method */
anthony92c93bd2012-03-19 14:02:47 +00003655 new_images=CombineImages(_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003656 break;
3657 }
anthonyafa3dfc2012-03-03 11:31:30 +00003658 if (LocaleCompare("composite",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003659 {
3660 Image
3661 *mask_image,
anthony31f1bf72012-01-30 12:37:22 +00003662 *source_image;
anthony805a2d42011-09-25 08:25:12 +00003663
3664 RectangleInfo
3665 geometry;
3666
anthony31f1bf72012-01-30 12:37:22 +00003667 CompositeOperator
anthony5f867ae2011-10-09 10:28:34 +00003668 compose;
3669
3670 const char*
3671 value;
3672
anthony92c93bd2012-03-19 14:02:47 +00003673 value=GetImageOption(_image_info,"compose");
anthony5f867ae2011-10-09 10:28:34 +00003674 if (value != (const char *) NULL)
3675 compose=(CompositeOperator) ParseCommandOption(
3676 MagickComposeOptions,MagickFalse,value);
3677 else
anthony31f1bf72012-01-30 12:37:22 +00003678 compose=OverCompositeOp; /* use Over not source_image->compose */
anthony5f867ae2011-10-09 10:28:34 +00003679
anthony92c93bd2012-03-19 14:02:47 +00003680 new_images=RemoveFirstImageFromList(&_images);
3681 source_image=RemoveFirstImageFromList(&_images);
anthonye8f56492012-02-12 12:39:02 +00003682 /* FUTURE - produce Exception, rather than silent fail */
anthony31f1bf72012-01-30 12:37:22 +00003683 if (source_image == (Image *) NULL)
3684 break;
anthonye8f56492012-02-12 12:39:02 +00003685
anthony31f1bf72012-01-30 12:37:22 +00003686 /* FUTURE - this should not be here! - should be part of -geometry */
3687 (void) TransformImage(&source_image,(char *) NULL,
anthony92c93bd2012-03-19 14:02:47 +00003688 source_image->geometry,_exception);
anthony5f867ae2011-10-09 10:28:34 +00003689
anthony31f1bf72012-01-30 12:37:22 +00003690 SetGeometry(source_image,&geometry);
3691 (void) ParseAbsoluteGeometry(source_image->geometry,&geometry);
3692 GravityAdjustGeometry(new_images->columns,new_images->rows,
3693 new_images->gravity, &geometry);
anthony5f867ae2011-10-09 10:28:34 +00003694
anthony92c93bd2012-03-19 14:02:47 +00003695 mask_image=RemoveFirstImageFromList(&_images);
anthony805a2d42011-09-25 08:25:12 +00003696 if (mask_image != (Image *) NULL)
anthony31f1bf72012-01-30 12:37:22 +00003697 { /* handle a third write mask image */
anthony5f867ae2011-10-09 10:28:34 +00003698 if ((compose == DisplaceCompositeOp) ||
3699 (compose == DistortCompositeOp))
anthony31f1bf72012-01-30 12:37:22 +00003700 { /* Merge Y displacement into X displace/distort map. */
3701 (void) CompositeImage(source_image,CopyGreenCompositeOp,
anthony92c93bd2012-03-19 14:02:47 +00003702 mask_image,0,0,_exception);
anthony805a2d42011-09-25 08:25:12 +00003703 mask_image=DestroyImage(mask_image);
3704 }
3705 else
3706 {
3707 /*
3708 Set a blending mask for the composition.
anthony805a2d42011-09-25 08:25:12 +00003709 */
anthony92c93bd2012-03-19 14:02:47 +00003710 (void) NegateImage(mask_image,MagickFalse,_exception);
3711 (void) SetImageMask(new_images,mask_image,_exception);
cristy1539afd2012-01-30 01:32:59 +00003712 mask_image=DestroyImage(mask_image);
anthony805a2d42011-09-25 08:25:12 +00003713 }
3714 }
anthony31f1bf72012-01-30 12:37:22 +00003715 (void) CompositeImage(new_images,compose,source_image,geometry.x,
anthony92c93bd2012-03-19 14:02:47 +00003716 geometry.y,_exception);
3717 (void) SetImageMask(new_images,(Image *) NULL,_exception);
anthony31f1bf72012-01-30 12:37:22 +00003718 source_image=DestroyImage(source_image);
anthony805a2d42011-09-25 08:25:12 +00003719 break;
3720 }
anthonyebb73a22012-03-22 14:25:52 +00003721 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003722 }
3723 case 'd':
3724 {
anthonyafa3dfc2012-03-03 11:31:30 +00003725 if (LocaleCompare("deconstruct",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003726 {
anthony31f1bf72012-01-30 12:37:22 +00003727 /* DEPRECIATED - use -layers CompareAny */
anthonyafa3dfc2012-03-03 11:31:30 +00003728 CLIListOperatorImages(cli_wand,"-layer","CompareAny",NULL);
anthony805a2d42011-09-25 08:25:12 +00003729 break;
3730 }
anthonyafa3dfc2012-03-03 11:31:30 +00003731 if (LocaleCompare("delete",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003732 {
anthonyafa3dfc2012-03-03 11:31:30 +00003733 if (IfNormalOp)
anthony92c93bd2012-03-19 14:02:47 +00003734 DeleteImages(&_images,arg1,_exception);
anthonyafa3dfc2012-03-03 11:31:30 +00003735 else
anthony92c93bd2012-03-19 14:02:47 +00003736 DeleteImages(&_images,"-1",_exception);
anthony805a2d42011-09-25 08:25:12 +00003737 break;
3738 }
anthonyafa3dfc2012-03-03 11:31:30 +00003739 if (LocaleCompare("duplicate",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003740 {
anthonyafa3dfc2012-03-03 11:31:30 +00003741 if (IfNormalOp)
anthony805a2d42011-09-25 08:25:12 +00003742 {
3743 const char
3744 *p;
3745
3746 size_t
3747 number_duplicates;
3748
anthonyebb73a22012-03-22 14:25:52 +00003749 if (IsGeometry(arg1) == MagickFalse)
3750 CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,
3751 arg1);
anthony31f1bf72012-01-30 12:37:22 +00003752 number_duplicates=(size_t) StringToLong(arg1);
3753 p=strchr(arg1,',');
anthony805a2d42011-09-25 08:25:12 +00003754 if (p == (const char *) NULL)
anthonyebb73a22012-03-22 14:25:52 +00003755 new_images=DuplicateImages(_images,number_duplicates,"-1",
3756 _exception);
anthony805a2d42011-09-25 08:25:12 +00003757 else
anthony92c93bd2012-03-19 14:02:47 +00003758 new_images=DuplicateImages(_images,number_duplicates,p,
3759 _exception);
anthony805a2d42011-09-25 08:25:12 +00003760 }
anthonyafa3dfc2012-03-03 11:31:30 +00003761 else
anthony92c93bd2012-03-19 14:02:47 +00003762 new_images=DuplicateImages(_images,1,"-1",_exception);
3763 AppendImageToList(&_images, new_images);
anthony36a8c2c2012-02-10 00:08:44 +00003764 new_images=(Image *)NULL;
anthony805a2d42011-09-25 08:25:12 +00003765 break;
3766 }
anthonyebb73a22012-03-22 14:25:52 +00003767 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003768 }
3769 case 'e':
3770 {
anthonyafa3dfc2012-03-03 11:31:30 +00003771 if (LocaleCompare("evaluate-sequence",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003772 {
anthony805a2d42011-09-25 08:25:12 +00003773 MagickEvaluateOperator
anthony31f1bf72012-01-30 12:37:22 +00003774 method;
anthony805a2d42011-09-25 08:25:12 +00003775
anthony31f1bf72012-01-30 12:37:22 +00003776 method=(MagickEvaluateOperator) ParseCommandOption(
3777 MagickEvaluateOptions,MagickFalse,arg1);
anthony92c93bd2012-03-19 14:02:47 +00003778 new_images=EvaluateImages(_images,method,_exception);
anthony805a2d42011-09-25 08:25:12 +00003779 break;
3780 }
anthonyebb73a22012-03-22 14:25:52 +00003781 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003782 }
3783 case 'f':
3784 {
anthonyafa3dfc2012-03-03 11:31:30 +00003785 if (LocaleCompare("fft",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003786 {
anthony92c93bd2012-03-19 14:02:47 +00003787 new_images=ForwardFourierTransformImage(_images,normal_op,_exception);
anthony805a2d42011-09-25 08:25:12 +00003788 break;
3789 }
anthonyafa3dfc2012-03-03 11:31:30 +00003790 if (LocaleCompare("flatten",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003791 {
anthony319dac62012-03-06 04:12:44 +00003792 /* REDIRECTED to use -layers flatten instead */
anthonyafa3dfc2012-03-03 11:31:30 +00003793 CLIListOperatorImages(cli_wand,"-layer",option+1,NULL);
anthony805a2d42011-09-25 08:25:12 +00003794 break;
3795 }
anthonyafa3dfc2012-03-03 11:31:30 +00003796 if (LocaleCompare("fx",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003797 {
anthony92c93bd2012-03-19 14:02:47 +00003798 new_images=FxImage(_images,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00003799 break;
3800 }
anthonyebb73a22012-03-22 14:25:52 +00003801 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003802 }
3803 case 'h':
3804 {
anthonyafa3dfc2012-03-03 11:31:30 +00003805 if (LocaleCompare("hald-clut",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003806 {
anthony31f1bf72012-01-30 12:37:22 +00003807 /* FUTURE - make this a compose option (and thus layers compose )
anthony92c93bd2012-03-19 14:02:47 +00003808 or perhaps compose last image over all other _images.
anthony31f1bf72012-01-30 12:37:22 +00003809 */
anthony805a2d42011-09-25 08:25:12 +00003810 Image
anthony31f1bf72012-01-30 12:37:22 +00003811 *hald_image;
anthony805a2d42011-09-25 08:25:12 +00003812
anthony92c93bd2012-03-19 14:02:47 +00003813 new_images=RemoveFirstImageFromList(&_images);
3814 hald_image=RemoveLastImageFromList(&_images);
anthony805a2d42011-09-25 08:25:12 +00003815 if (hald_image == (Image *) NULL)
anthony31f1bf72012-01-30 12:37:22 +00003816 break;
anthony92c93bd2012-03-19 14:02:47 +00003817 (void) HaldClutImage(new_images,hald_image,_exception);
anthony805a2d42011-09-25 08:25:12 +00003818 hald_image=DestroyImage(hald_image);
anthony805a2d42011-09-25 08:25:12 +00003819 break;
3820 }
anthonyebb73a22012-03-22 14:25:52 +00003821 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003822 }
3823 case 'i':
3824 {
anthonyafa3dfc2012-03-03 11:31:30 +00003825 if (LocaleCompare("ift",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003826 {
3827 Image
anthony805a2d42011-09-25 08:25:12 +00003828 *magnitude_image,
3829 *phase_image;
3830
anthony92c93bd2012-03-19 14:02:47 +00003831 magnitude_image=RemoveFirstImageFromList(&_images);
3832 phase_image=RemoveFirstImageFromList(&_images);
anthonye8f56492012-02-12 12:39:02 +00003833 /* FUTURE - produce Exception, rather than silent fail */
anthony31f1bf72012-01-30 12:37:22 +00003834 if (phase_image == (Image *) NULL)
3835 break;
3836 new_images=InverseFourierTransformImage(magnitude_image,phase_image,
anthony92c93bd2012-03-19 14:02:47 +00003837 normal_op,_exception);
anthony31f1bf72012-01-30 12:37:22 +00003838 magnitude_image=DestroyImage(magnitude_image);
3839 phase_image=DestroyImage(phase_image);
anthony805a2d42011-09-25 08:25:12 +00003840 break;
3841 }
anthonyafa3dfc2012-03-03 11:31:30 +00003842 if (LocaleCompare("insert",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003843 {
3844 Image
anthony31f1bf72012-01-30 12:37:22 +00003845 *insert_image,
3846 *index_image;
3847
3848 ssize_t
3849 index;
anthony805a2d42011-09-25 08:25:12 +00003850
3851 index=0;
anthony92c93bd2012-03-19 14:02:47 +00003852 insert_image=RemoveLastImageFromList(&_images);
anthonyafa3dfc2012-03-03 11:31:30 +00003853 if (IfNormalOp)
anthony31f1bf72012-01-30 12:37:22 +00003854 index=(ssize_t) StringToLong(arg1);
anthony43f425d2012-02-26 12:58:58 +00003855 index_image=insert_image;
anthony805a2d42011-09-25 08:25:12 +00003856 if (index == 0)
anthony92c93bd2012-03-19 14:02:47 +00003857 PrependImageToList(&_images,insert_image);
3858 else if (index == (ssize_t) GetImageListLength(_images))
3859 AppendImageToList(&_images,insert_image);
anthony805a2d42011-09-25 08:25:12 +00003860 else
anthony43f425d2012-02-26 12:58:58 +00003861 {
anthony92c93bd2012-03-19 14:02:47 +00003862 index_image=GetImageFromList(_images,index-1);
anthony43f425d2012-02-26 12:58:58 +00003863 if (index_image == (Image *) NULL)
3864 {
anthony92c93bd2012-03-19 14:02:47 +00003865 (void) ThrowMagickException(_exception,GetMagickModule(),
anthony43f425d2012-02-26 12:58:58 +00003866 OptionError,"NoSuchImage","'%s'",arg1);
3867 break;
3868 }
3869 InsertImageInList(&index_image,insert_image);
3870 }
anthony92c93bd2012-03-19 14:02:47 +00003871 _images=GetFirstImageInList(index_image);
anthony805a2d42011-09-25 08:25:12 +00003872 break;
3873 }
anthonyebb73a22012-03-22 14:25:52 +00003874 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00003875 }
3876 case 'l':
3877 {
anthonyafa3dfc2012-03-03 11:31:30 +00003878 if (LocaleCompare("layers",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00003879 {
anthony805a2d42011-09-25 08:25:12 +00003880 ImageLayerMethod
3881 method;
3882
anthony805a2d42011-09-25 08:25:12 +00003883 method=(ImageLayerMethod) ParseCommandOption(MagickLayerOptions,
anthony31f1bf72012-01-30 12:37:22 +00003884 MagickFalse,arg1);
anthony805a2d42011-09-25 08:25:12 +00003885 switch (method)
3886 {
3887 case CoalesceLayer:
3888 {
anthony92c93bd2012-03-19 14:02:47 +00003889 new_images=CoalesceImages(_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003890 break;
3891 }
3892 case CompareAnyLayer:
3893 case CompareClearLayer:
3894 case CompareOverlayLayer:
3895 default:
3896 {
anthony92c93bd2012-03-19 14:02:47 +00003897 new_images=CompareImagesLayers(_images,method,_exception);
anthony805a2d42011-09-25 08:25:12 +00003898 break;
3899 }
3900 case MergeLayer:
3901 case FlattenLayer:
3902 case MosaicLayer:
3903 case TrimBoundsLayer:
3904 {
anthony92c93bd2012-03-19 14:02:47 +00003905 new_images=MergeImageLayers(_images,method,_exception);
anthony805a2d42011-09-25 08:25:12 +00003906 break;
3907 }
3908 case DisposeLayer:
3909 {
anthony92c93bd2012-03-19 14:02:47 +00003910 new_images=DisposeImages(_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003911 break;
3912 }
3913 case OptimizeImageLayer:
3914 {
anthony92c93bd2012-03-19 14:02:47 +00003915 new_images=OptimizeImageLayers(_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003916 break;
3917 }
3918 case OptimizePlusLayer:
3919 {
anthony92c93bd2012-03-19 14:02:47 +00003920 new_images=OptimizePlusImageLayers(_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003921 break;
3922 }
3923 case OptimizeTransLayer:
3924 {
anthony92c93bd2012-03-19 14:02:47 +00003925 OptimizeImageTransparency(_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003926 break;
3927 }
3928 case RemoveDupsLayer:
3929 {
anthony92c93bd2012-03-19 14:02:47 +00003930 RemoveDuplicateLayers(&_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003931 break;
3932 }
3933 case RemoveZeroLayer:
3934 {
anthony92c93bd2012-03-19 14:02:47 +00003935 RemoveZeroDelayLayers(&_images,_exception);
anthony805a2d42011-09-25 08:25:12 +00003936 break;
3937 }
3938 case OptimizeLayer:
anthony31f1bf72012-01-30 12:37:22 +00003939 { /* General Purpose, GIF Animation Optimizer. */
anthony92c93bd2012-03-19 14:02:47 +00003940 new_images=CoalesceImages(_images,_exception);
anthony31f1bf72012-01-30 12:37:22 +00003941 if (new_images == (Image *) NULL)
3942 break;
anthony92c93bd2012-03-19 14:02:47 +00003943 _images=DestroyImageList(_images);
3944 _images=OptimizeImageLayers(new_images,_exception);
3945 if (_images == (Image *) NULL)
anthony31f1bf72012-01-30 12:37:22 +00003946 break;
3947 new_images=DestroyImageList(new_images);
anthony92c93bd2012-03-19 14:02:47 +00003948 OptimizeImageTransparency(_images,_exception);
3949 (void) RemapImages(_quantize_info,_images,(Image *) NULL,
3950 _exception);
anthony805a2d42011-09-25 08:25:12 +00003951 break;
3952 }
3953 case CompositeLayer:
3954 {
anthony805a2d42011-09-25 08:25:12 +00003955 Image
3956 *source;
3957
3958 RectangleInfo
3959 geometry;
3960
anthony31f1bf72012-01-30 12:37:22 +00003961 CompositeOperator
anthony5f867ae2011-10-09 10:28:34 +00003962 compose;
3963
3964 const char*
3965 value;
3966
anthony92c93bd2012-03-19 14:02:47 +00003967 value=GetImageOption(_image_info,"compose");
anthony31f1bf72012-01-30 12:37:22 +00003968 compose=OverCompositeOp; /* Default to Over */
anthony5f867ae2011-10-09 10:28:34 +00003969 if (value != (const char *) NULL)
3970 compose=(CompositeOperator) ParseCommandOption(
3971 MagickComposeOptions,MagickFalse,value);
anthony5f867ae2011-10-09 10:28:34 +00003972
anthony31f1bf72012-01-30 12:37:22 +00003973 /* Split image sequence at the first 'NULL:' image. */
anthony92c93bd2012-03-19 14:02:47 +00003974 source=_images;
anthony805a2d42011-09-25 08:25:12 +00003975 while (source != (Image *) NULL)
3976 {
3977 source=GetNextImageInList(source);
3978 if ((source != (Image *) NULL) &&
3979 (LocaleCompare(source->magick,"NULL") == 0))
3980 break;
3981 }
3982 if (source != (Image *) NULL)
3983 {
3984 if ((GetPreviousImageInList(source) == (Image *) NULL) ||
3985 (GetNextImageInList(source) == (Image *) NULL))
3986 source=(Image *) NULL;
3987 else
anthony31f1bf72012-01-30 12:37:22 +00003988 { /* Separate the two lists, junk the null: image. */
anthony805a2d42011-09-25 08:25:12 +00003989 source=SplitImageList(source->previous);
3990 DeleteImageFromList(&source);
3991 }
3992 }
3993 if (source == (Image *) NULL)
3994 {
anthony92c93bd2012-03-19 14:02:47 +00003995 (void) ThrowMagickException(_exception,GetMagickModule(),
anthony805a2d42011-09-25 08:25:12 +00003996 OptionError,"MissingNullSeparator","layers Composite");
anthony805a2d42011-09-25 08:25:12 +00003997 break;
3998 }
anthony31f1bf72012-01-30 12:37:22 +00003999 /* Adjust offset with gravity and virtual canvas. */
anthony92c93bd2012-03-19 14:02:47 +00004000 SetGeometry(_images,&geometry);
4001 (void) ParseAbsoluteGeometry(_images->geometry,&geometry);
anthony805a2d42011-09-25 08:25:12 +00004002 geometry.width=source->page.width != 0 ?
4003 source->page.width : source->columns;
4004 geometry.height=source->page.height != 0 ?
4005 source->page.height : source->rows;
anthony92c93bd2012-03-19 14:02:47 +00004006 GravityAdjustGeometry(_images->page.width != 0 ?
4007 _images->page.width : _images->columns,
4008 _images->page.height != 0 ? _images->page.height :
4009 _images->rows,_images->gravity,&geometry);
anthony5f867ae2011-10-09 10:28:34 +00004010
anthony31f1bf72012-01-30 12:37:22 +00004011 /* Compose the two image sequences together */
anthony92c93bd2012-03-19 14:02:47 +00004012 CompositeLayers(_images,compose,source,geometry.x,geometry.y,
4013 _exception);
anthony805a2d42011-09-25 08:25:12 +00004014 source=DestroyImageList(source);
4015 break;
4016 }
4017 }
anthony805a2d42011-09-25 08:25:12 +00004018 break;
4019 }
anthonyafa3dfc2012-03-03 11:31:30 +00004020 if (LocaleCompare("limit",option+1) == 0)
anthony72feaa62012-01-17 06:46:23 +00004021 {
4022 MagickSizeType
4023 limit;
4024
4025 ResourceType
4026 type;
4027
anthony72feaa62012-01-17 06:46:23 +00004028 type=(ResourceType) ParseCommandOption(MagickResourceOptions,
anthony31f1bf72012-01-30 12:37:22 +00004029 MagickFalse,arg1);
anthony72feaa62012-01-17 06:46:23 +00004030 limit=MagickResourceInfinity;
anthony31f1bf72012-01-30 12:37:22 +00004031 if (LocaleCompare("unlimited",arg2) != 0)
4032 limit=(MagickSizeType) SiPrefixToDoubleInterval(arg2,100.0);
anthony72feaa62012-01-17 06:46:23 +00004033 (void) SetMagickResourceLimit(type,limit);
4034 break;
4035 }
anthonyebb73a22012-03-22 14:25:52 +00004036 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00004037 }
4038 case 'm':
4039 {
anthonyafa3dfc2012-03-03 11:31:30 +00004040 if (LocaleCompare("map",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00004041 {
anthony31f1bf72012-01-30 12:37:22 +00004042 /* DEPRECIATED use +remap */
anthony92c93bd2012-03-19 14:02:47 +00004043 (void) RemapImages(_quantize_info,_images,(Image *) NULL,_exception);
anthony805a2d42011-09-25 08:25:12 +00004044 break;
4045 }
anthonyafa3dfc2012-03-03 11:31:30 +00004046 if (LocaleCompare("morph",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00004047 {
4048 Image
4049 *morph_image;
4050
anthony92c93bd2012-03-19 14:02:47 +00004051 morph_image=MorphImages(_images,StringToUnsignedLong(arg1),
4052 _exception);
anthony805a2d42011-09-25 08:25:12 +00004053 if (morph_image == (Image *) NULL)
anthony31f1bf72012-01-30 12:37:22 +00004054 break;
anthony92c93bd2012-03-19 14:02:47 +00004055 _images=DestroyImageList(_images);
4056 _images=morph_image;
anthony805a2d42011-09-25 08:25:12 +00004057 break;
4058 }
anthonyafa3dfc2012-03-03 11:31:30 +00004059 if (LocaleCompare("mosaic",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00004060 {
anthony319dac62012-03-06 04:12:44 +00004061 /* REDIRECTED to use -layers mosaic instead */
anthonyafa3dfc2012-03-03 11:31:30 +00004062 CLIListOperatorImages(cli_wand,"-layer",option+1,NULL);
anthony805a2d42011-09-25 08:25:12 +00004063 break;
4064 }
anthonyebb73a22012-03-22 14:25:52 +00004065 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00004066 }
4067 case 'p':
4068 {
anthonyafa3dfc2012-03-03 11:31:30 +00004069 if (LocaleCompare("print",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00004070 {
4071 char
4072 *string;
4073
anthony92c93bd2012-03-19 14:02:47 +00004074 string=InterpretImageProperties(_image_info,_images,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00004075 if (string == (char *) NULL)
4076 break;
4077 (void) FormatLocaleFile(stdout,"%s",string);
4078 string=DestroyString(string);
anthony24aa8822012-03-11 00:56:06 +00004079 break;
anthony805a2d42011-09-25 08:25:12 +00004080 }
anthonyafa3dfc2012-03-03 11:31:30 +00004081 if (LocaleCompare("process",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00004082 {
4083 char
4084 **arguments;
4085
4086 int
4087 j,
4088 number_arguments;
4089
anthony31f1bf72012-01-30 12:37:22 +00004090 arguments=StringToArgv(arg1,&number_arguments);
anthony805a2d42011-09-25 08:25:12 +00004091 if (arguments == (char **) NULL)
4092 break;
anthony31f1bf72012-01-30 12:37:22 +00004093 if (strchr(arguments[1],'=') != (char *) NULL)
anthony805a2d42011-09-25 08:25:12 +00004094 {
4095 char
4096 breaker,
4097 quote,
4098 *token;
4099
4100 const char
4101 *arguments;
4102
4103 int
4104 next,
4105 status;
4106
4107 size_t
4108 length;
4109
4110 TokenInfo
4111 *token_info;
4112
4113 /*
anthony24aa8822012-03-11 00:56:06 +00004114 Support old style syntax, filter="-option arg1".
anthony805a2d42011-09-25 08:25:12 +00004115 */
anthony31f1bf72012-01-30 12:37:22 +00004116 length=strlen(arg1);
anthony805a2d42011-09-25 08:25:12 +00004117 token=(char *) NULL;
4118 if (~length >= (MaxTextExtent-1))
4119 token=(char *) AcquireQuantumMemory(length+MaxTextExtent,
4120 sizeof(*token));
4121 if (token == (char *) NULL)
4122 break;
4123 next=0;
anthony31f1bf72012-01-30 12:37:22 +00004124 arguments=arg1;
anthony805a2d42011-09-25 08:25:12 +00004125 token_info=AcquireTokenInfo();
4126 status=Tokenizer(token_info,0,token,length,arguments,"","=",
4127 "\"",'\0',&breaker,&next,&quote);
4128 token_info=DestroyTokenInfo(token_info);
4129 if (status == 0)
4130 {
4131 const char
4132 *argv;
4133
4134 argv=(&(arguments[next]));
anthony92c93bd2012-03-19 14:02:47 +00004135 (void) InvokeDynamicImageFilter(token,&_images,1,&argv,
4136 _exception);
anthony805a2d42011-09-25 08:25:12 +00004137 }
4138 token=DestroyString(token);
4139 break;
4140 }
4141 (void) SubstituteString(&arguments[1],"-","");
anthony92c93bd2012-03-19 14:02:47 +00004142 (void) InvokeDynamicImageFilter(arguments[1],&_images,
4143 number_arguments-2,(const char **) arguments+2,_exception);
anthony805a2d42011-09-25 08:25:12 +00004144 for (j=0; j < number_arguments; j++)
4145 arguments[j]=DestroyString(arguments[j]);
4146 arguments=(char **) RelinquishMagickMemory(arguments);
4147 break;
4148 }
anthonyebb73a22012-03-22 14:25:52 +00004149 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00004150 }
4151 case 'r':
4152 {
anthonyafa3dfc2012-03-03 11:31:30 +00004153 if (LocaleCompare("remap",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00004154 {
anthony92c93bd2012-03-19 14:02:47 +00004155 (void) RemapImages(_quantize_info,_images,(Image *) NULL,_exception);
4156 (void) RemapImages(_quantize_info,_images,(Image *) NULL,_exception);
anthony31f1bf72012-01-30 12:37:22 +00004157 break;
4158 }
anthonyafa3dfc2012-03-03 11:31:30 +00004159 if (LocaleCompare("reverse",option+1) == 0)
anthony31f1bf72012-01-30 12:37:22 +00004160 {
anthony92c93bd2012-03-19 14:02:47 +00004161 ReverseImageList(&_images);
anthony805a2d42011-09-25 08:25:12 +00004162 break;
4163 }
anthonyebb73a22012-03-22 14:25:52 +00004164 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00004165 }
4166 case 's':
4167 {
anthonyafa3dfc2012-03-03 11:31:30 +00004168 if (LocaleCompare("smush",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00004169 {
4170 Image
4171 *smush_image;
4172
4173 ssize_t
4174 offset;
4175
anthony31f1bf72012-01-30 12:37:22 +00004176 offset=(ssize_t) StringToLong(arg1);
anthony92c93bd2012-03-19 14:02:47 +00004177 smush_image=SmushImages(_images,normal_op,offset,_exception);
anthony805a2d42011-09-25 08:25:12 +00004178 if (smush_image == (Image *) NULL)
anthony31f1bf72012-01-30 12:37:22 +00004179 break;
anthony92c93bd2012-03-19 14:02:47 +00004180 _images=DestroyImageList(_images);
4181 _images=smush_image;
anthony805a2d42011-09-25 08:25:12 +00004182 break;
4183 }
anthonyafa3dfc2012-03-03 11:31:30 +00004184 if (LocaleCompare("swap",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00004185 {
4186 Image
4187 *p,
4188 *q,
4189 *swap;
4190
4191 ssize_t
anthony31f1bf72012-01-30 12:37:22 +00004192 index,
anthony805a2d42011-09-25 08:25:12 +00004193 swap_index;
4194
anthony31f1bf72012-01-30 12:37:22 +00004195 index=-1;
4196 swap_index=-2;
anthonyafa3dfc2012-03-03 11:31:30 +00004197 if (IfNormalOp)
anthony805a2d42011-09-25 08:25:12 +00004198 {
4199 GeometryInfo
4200 geometry_info;
4201
4202 MagickStatusType
4203 flags;
4204
4205 swap_index=(-1);
anthony31f1bf72012-01-30 12:37:22 +00004206 flags=ParseGeometry(arg1,&geometry_info);
anthony805a2d42011-09-25 08:25:12 +00004207 index=(ssize_t) geometry_info.rho;
4208 if ((flags & SigmaValue) != 0)
4209 swap_index=(ssize_t) geometry_info.sigma;
4210 }
anthony92c93bd2012-03-19 14:02:47 +00004211 p=GetImageFromList(_images,index);
4212 q=GetImageFromList(_images,swap_index);
anthony805a2d42011-09-25 08:25:12 +00004213 if ((p == (Image *) NULL) || (q == (Image *) NULL))
4214 {
anthony92c93bd2012-03-19 14:02:47 +00004215 (void) ThrowMagickException(_exception,GetMagickModule(),
4216 OptionError,"NoSuchImage","'%s'",_images->filename);
anthony805a2d42011-09-25 08:25:12 +00004217 break;
4218 }
4219 if (p == q)
4220 break;
anthony92c93bd2012-03-19 14:02:47 +00004221 swap=CloneImage(p,0,0,MagickTrue,_exception);
4222 ReplaceImageInList(&p,CloneImage(q,0,0,MagickTrue,_exception));
anthony805a2d42011-09-25 08:25:12 +00004223 ReplaceImageInList(&q,swap);
anthony92c93bd2012-03-19 14:02:47 +00004224 _images=GetFirstImageInList(q);
anthony805a2d42011-09-25 08:25:12 +00004225 break;
4226 }
anthonyebb73a22012-03-22 14:25:52 +00004227 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00004228 }
4229 case 'w':
4230 {
anthonyafa3dfc2012-03-03 11:31:30 +00004231 if (LocaleCompare("write",option+1) == 0)
anthony805a2d42011-09-25 08:25:12 +00004232 {
4233 char
4234 key[MaxTextExtent];
4235
4236 Image
4237 *write_images;
4238
4239 ImageInfo
4240 *write_info;
4241
anthony31f1bf72012-01-30 12:37:22 +00004242 (void) FormatLocaleString(key,MaxTextExtent,"cache:%s",arg1);
anthony805a2d42011-09-25 08:25:12 +00004243 (void) DeleteImageRegistry(key);
anthony92c93bd2012-03-19 14:02:47 +00004244 write_images=_images;
anthonyafa3dfc2012-03-03 11:31:30 +00004245 if (IfPlusOp)
anthony92c93bd2012-03-19 14:02:47 +00004246 write_images=CloneImageList(_images,_exception);
4247 write_info=CloneImageInfo(_image_info);
4248 (void) WriteImages(write_info,write_images,arg1,_exception);
anthony805a2d42011-09-25 08:25:12 +00004249 write_info=DestroyImageInfo(write_info);
anthonyafa3dfc2012-03-03 11:31:30 +00004250 if (IfPlusOp)
anthony805a2d42011-09-25 08:25:12 +00004251 write_images=DestroyImageList(write_images);
4252 break;
4253 }
anthonyebb73a22012-03-22 14:25:52 +00004254 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00004255 }
4256 default:
anthonyebb73a22012-03-22 14:25:52 +00004257 CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
anthony805a2d42011-09-25 08:25:12 +00004258 }
anthony31f1bf72012-01-30 12:37:22 +00004259 if (new_images == (Image *) NULL)
4260 return;
anthony805a2d42011-09-25 08:25:12 +00004261
anthony92c93bd2012-03-19 14:02:47 +00004262 if (_images != (Image *) NULL)
4263 _images=DestroyImageList(_images);
4264 _images=GetFirstImageInList(new_images);
anthony31f1bf72012-01-30 12:37:22 +00004265 return;
4266
anthony92c93bd2012-03-19 14:02:47 +00004267#undef _image_info
4268#undef _images
4269#undef _exception
4270#undef _draw_info
4271#undef _quantize_info
anthonyafa3dfc2012-03-03 11:31:30 +00004272#undef IfNormalOp
4273#undef IfPlusOp
anthony31f1bf72012-01-30 12:37:22 +00004274#undef normal_op
anthony805a2d42011-09-25 08:25:12 +00004275}
anthony43f425d2012-02-26 12:58:58 +00004276
4277/*
4278%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4279% %
4280% %
4281% %
4282+ C L I S p e c i a l O p e r a t i o n s %
4283% %
4284% %
4285% %
4286%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4287%
4288% CLISpecialOption() Applies operations that may involve empty image lists
4289% and or stacks of image lists or image_info settings.
4290%
anthonyafa3dfc2012-03-03 11:31:30 +00004291% The classic operators of this type is -read, and image stack operators,
4292% which can be applied to empty image lists.
4293%
4294% Note: unlike other Operators, these may involve other special 'option'
4295% character prefixes, other than simply '-' or '+'.
anthony43f425d2012-02-26 12:58:58 +00004296%
4297% The format of the CLISpecialOption method is:
4298%
4299% void CLISpecialOption(MagickCLI *cli_wand,const char *option,
anthony24aa8822012-03-11 00:56:06 +00004300% const char *arg1)
anthony43f425d2012-02-26 12:58:58 +00004301%
4302% A description of each parameter follows:
4303%
4304% o cli_wand: the main CLI Wand to use.
4305%
4306% o option: The special option (with any switch char) to process
4307%
anthony24aa8822012-03-11 00:56:06 +00004308% o arg1: Argument for option, if required
anthonyafa3dfc2012-03-03 11:31:30 +00004309%
anthony2052d272012-02-28 12:48:29 +00004310% Example Usage...
4311%
anthonyce8dcb32012-03-21 13:20:31 +00004312% CLISpecialOperator(cli_wand,"-read","rose:");
anthony2052d272012-02-28 12:48:29 +00004313%
anthony24aa8822012-03-11 00:56:06 +00004314% Or for handling command line arguments EG: +/-option ["arg1"]
anthony2052d272012-02-28 12:48:29 +00004315%
4316% cli_wand
4317% argc,argv
4318% i=index in argv
4319%
4320% option_info = GetCommandOptionInfo(argv[i]);
4321% count=option_info->type;
4322% option_type=option_info->flags;
4323%
4324% if ( (option_type & SpecialOptionFlag) != 0 )
4325% CLISpecialOperator(cli_wand,argv[i],
4326% count>=1 ? argv[i+1] : (char *)NULL);
4327% i += count+1;
anthony43f425d2012-02-26 12:58:58 +00004328%
4329*/
4330
anthony43f425d2012-02-26 12:58:58 +00004331WandExport void CLISpecialOperator(MagickCLI *cli_wand,
anthony24aa8822012-03-11 00:56:06 +00004332 const char *option, const char *arg1)
anthony43f425d2012-02-26 12:58:58 +00004333{
anthony92c93bd2012-03-19 14:02:47 +00004334#define _exception (cli_wand->wand.exception)
anthony43f425d2012-02-26 12:58:58 +00004335
4336 assert(cli_wand != (MagickCLI *) NULL);
4337 assert(cli_wand->signature == WandSignature);
4338 assert(cli_wand->wand.signature == WandSignature);
4339 if (cli_wand->wand.debug != MagickFalse)
4340 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);
4341
anthony24aa8822012-03-11 00:56:06 +00004342 if(cli_wand->wand.images != (Image *)NULL)
4343 (void) SyncImagesSettings(cli_wand->wand.image_info,cli_wand->wand.images,
anthony92c93bd2012-03-19 14:02:47 +00004344 _exception);
anthony24aa8822012-03-11 00:56:06 +00004345
anthonyce8dcb32012-03-21 13:20:31 +00004346 if (LocaleCompare("respect-parenthesis",option+1) == 0) {
4347 /* image-setting stack linkage */
4348 (void) SetImageOption(cli_wand->wand.image_info,option+1,
4349 *option == '-' ? "true" : (char *) NULL);
4350 return;
4351 }
4352 if (LocaleCompare("(",option) == 0) {
anthony43f425d2012-02-26 12:58:58 +00004353 /* stack 'push' images */
4354 Stack
4355 *node;
4356
4357 size_t
4358 size;
4359
anthony43f425d2012-02-26 12:58:58 +00004360 size=0;
4361 node=cli_wand->image_list_stack;
4362 for ( ; node != (Stack *)NULL; node=node->next)
4363 size++;
anthonyafa3dfc2012-03-03 11:31:30 +00004364 if ( size >= MAX_STACK_DEPTH )
anthony92c93bd2012-03-19 14:02:47 +00004365 CLIWandExceptionReturn(OptionError,"ParenthesisNestedTooDeeply",option);
anthony43f425d2012-02-26 12:58:58 +00004366 node=(Stack *) AcquireMagickMemory(sizeof(*node));
4367 if (node == (Stack *) NULL)
anthony92c93bd2012-03-19 14:02:47 +00004368 CLIWandExceptionReturn(ResourceLimitFatalError,
4369 "MemoryAllocationFailed",option);
anthony43f425d2012-02-26 12:58:58 +00004370 node->data = (void *)cli_wand->wand.images;
4371 cli_wand->wand.images = NewImageList();
4372 node->next = cli_wand->image_list_stack;
4373 cli_wand->image_list_stack = node;
4374
4375 /* handle respect-parenthesis */
anthonyce8dcb32012-03-21 13:20:31 +00004376 if ( IsMagickTrue(GetImageOption(cli_wand->wand.image_info,
4377 "respect-parenthesis")) != MagickFalse )
anthony4d4f2c72012-03-22 03:22:03 +00004378 option="{"; /* push image settings too */
anthony43f425d2012-02-26 12:58:58 +00004379 else
4380 return;
4381 }
anthonyce8dcb32012-03-21 13:20:31 +00004382 if (LocaleCompare("{",option) == 0) {
anthony43f425d2012-02-26 12:58:58 +00004383 /* stack 'push' of image_info settings */
4384 Stack
4385 *node;
4386
4387 size_t
4388 size;
4389
4390 size=0;
4391 node=cli_wand->image_info_stack;
4392 for ( ; node != (Stack *)NULL; node=node->next)
4393 size++;
anthony92c93bd2012-03-19 14:02:47 +00004394 if ( size >= MAX_STACK_DEPTH )
anthony4d4f2c72012-03-22 03:22:03 +00004395 CLIWandExceptionReturn(OptionError,"CurlyBracesNestedTooDeeply",option);
anthony43f425d2012-02-26 12:58:58 +00004396 node=(Stack *) AcquireMagickMemory(sizeof(*node));
anthony92c93bd2012-03-19 14:02:47 +00004397 if (node == (Stack *) NULL)
4398 CLIWandExceptionReturn(ResourceLimitFatalError,
4399 "MemoryAllocationFailed",option);
anthony43f425d2012-02-26 12:58:58 +00004400
4401 node->data = (void *)cli_wand->wand.image_info;
4402 cli_wand->wand.image_info = CloneImageInfo(cli_wand->wand.image_info);
anthonyafa3dfc2012-03-03 11:31:30 +00004403 if (cli_wand->wand.image_info == (ImageInfo *)NULL) {
anthony92c93bd2012-03-19 14:02:47 +00004404 CLIWandException(ResourceLimitFatalError,"MemoryAllocationFailed",
4405 option);
anthonyafa3dfc2012-03-03 11:31:30 +00004406 cli_wand->wand.image_info = (ImageInfo *)node->data;
4407 node = (Stack *)RelinquishMagickMemory(node);
4408 return;
4409 }
anthony43f425d2012-02-26 12:58:58 +00004410
4411 node->next = cli_wand->image_info_stack;
4412 cli_wand->image_info_stack = node;
4413
4414 return;
4415 }
anthonyce8dcb32012-03-21 13:20:31 +00004416 if (LocaleCompare(")",option) == 0) {
anthony43f425d2012-02-26 12:58:58 +00004417 /* pop images from stack */
4418 Stack
4419 *node;
4420
anthony43f425d2012-02-26 12:58:58 +00004421 node = (void *)cli_wand->image_list_stack;
4422 if ( node == (Stack *)NULL)
anthony92c93bd2012-03-19 14:02:47 +00004423 CLIWandExceptionReturn(OptionError,"UnbalancedParenthesis",option);
anthony43f425d2012-02-26 12:58:58 +00004424 cli_wand->image_list_stack = node->next;
4425
4426 AppendImageToList((Image **)&node->data,cli_wand->wand.images);
4427 cli_wand->wand.images= (Image *)node->data;
4428 node = (Stack *)RelinquishMagickMemory(node);
4429
anthony4d4f2c72012-03-22 03:22:03 +00004430 /* handle respect-parenthesis - of the previous 'pushed' settings */
anthony43f425d2012-02-26 12:58:58 +00004431 node = cli_wand->image_info_stack;
4432 if ( node != (Stack *)NULL)
4433 {
anthonyce8dcb32012-03-21 13:20:31 +00004434 if (IsMagickTrue(GetImageOption((ImageInfo *)node->data,
4435 "respect-parenthesis")) != MagickFalse )
anthony4d4f2c72012-03-22 03:22:03 +00004436 option="}"; /* pop image settings too */
anthony43f425d2012-02-26 12:58:58 +00004437 else
4438 return;
4439 }
4440 else
4441 return;
4442 }
anthonyce8dcb32012-03-21 13:20:31 +00004443 if (LocaleCompare("}",option) == 0) {
anthony43f425d2012-02-26 12:58:58 +00004444 /* pop image_info settings from stack */
4445 Stack
4446 *node;
4447
4448 node = (void *)cli_wand->image_info_stack;
4449 if ( node == (Stack *)NULL)
anthony4d4f2c72012-03-22 03:22:03 +00004450 CLIWandExceptionReturn(OptionError,"UnbalancedCurlyBraces",option);
anthony43f425d2012-02-26 12:58:58 +00004451 cli_wand->image_info_stack = node->next;
4452
4453 (void) DestroyImageInfo(cli_wand->wand.image_info);
4454 cli_wand->wand.image_info = (ImageInfo *)node->data;
4455 node = (Stack *)RelinquishMagickMemory(node);
4456
4457 GetDrawInfo(cli_wand->wand.image_info, cli_wand->draw_info);
4458 cli_wand->quantize_info=DestroyQuantizeInfo(cli_wand->quantize_info);
4459 cli_wand->quantize_info=AcquireQuantizeInfo(cli_wand->wand.image_info);
4460
4461 return;
4462 }
anthonyce8dcb32012-03-21 13:20:31 +00004463 if (LocaleCompare("clone",option+1) == 0) {
anthony43f425d2012-02-26 12:58:58 +00004464 Image
4465 *new_images;
4466
4467 if (*option == '+')
anthony24aa8822012-03-11 00:56:06 +00004468 arg1="-1";
4469 if (IsSceneGeometry(arg1,MagickFalse) == MagickFalse)
anthony92c93bd2012-03-19 14:02:47 +00004470 CLIWandExceptionReturn(OptionError,"InvalidArgument",option);
anthony43f425d2012-02-26 12:58:58 +00004471 if ( cli_wand->image_list_stack == (Stack *)NULL)
anthony92c93bd2012-03-19 14:02:47 +00004472 CLIWandExceptionReturn(OptionError,"UnableToCloneImage",option);
anthony43f425d2012-02-26 12:58:58 +00004473 new_images = (Image *)cli_wand->image_list_stack->data;
4474 if (new_images == (Image *) NULL)
anthony92c93bd2012-03-19 14:02:47 +00004475 CLIWandExceptionReturn(OptionError,"UnableToCloneImage",option);
4476 new_images=CloneImages(new_images,arg1,_exception);
anthony43f425d2012-02-26 12:58:58 +00004477 if (new_images == (Image *) NULL)
anthony92c93bd2012-03-19 14:02:47 +00004478 CLIWandExceptionReturn(OptionError,"NoSuchImage",option);
anthony43f425d2012-02-26 12:58:58 +00004479 AppendImageToList(&cli_wand->wand.images,new_images);
4480 return;
4481 }
anthony319dac62012-03-06 04:12:44 +00004482 if ( ( LocaleCompare("read",option+1) == 0 ) ||
anthonyce8dcb32012-03-21 13:20:31 +00004483 ( LocaleCompare("--",option) == 0 ) ) {
anthonyafa3dfc2012-03-03 11:31:30 +00004484#if !USE_WAND_METHODS
anthony43f425d2012-02-26 12:58:58 +00004485 Image *
4486 new_images;
4487
anthony43f425d2012-02-26 12:58:58 +00004488 if (cli_wand->wand.image_info->ping != MagickFalse)
anthony92c93bd2012-03-19 14:02:47 +00004489 new_images=PingImages(cli_wand->wand.image_info,arg1,_exception);
anthony43f425d2012-02-26 12:58:58 +00004490 else
anthony92c93bd2012-03-19 14:02:47 +00004491 new_images=ReadImages(cli_wand->wand.image_info,arg1,_exception);
anthony43f425d2012-02-26 12:58:58 +00004492 AppendImageToList(&cli_wand->wand.images, new_images);
4493#else
4494 /* read images using MagickWand method - no ping */
4495 /* This is not working! - it locks up in a CPU loop! */
4496 MagickSetLastIterator(&cli_wand->wand);
anthony24aa8822012-03-11 00:56:06 +00004497 MagickReadImage(&cli_wand->wand,arg1);
anthony43f425d2012-02-26 12:58:58 +00004498 MagickSetFirstIterator(&cli_wand->wand);
4499#endif
4500 return;
4501 }
anthonyafa3dfc2012-03-03 11:31:30 +00004502 /* No-op options */
4503 if (LocaleCompare("noop",option+1) == 0)
anthony43f425d2012-02-26 12:58:58 +00004504 return;
anthonyafa3dfc2012-03-03 11:31:30 +00004505 if (LocaleCompare("sans",option+1) == 0)
anthony43f425d2012-02-26 12:58:58 +00004506 return;
anthonyafa3dfc2012-03-03 11:31:30 +00004507 if (LocaleCompare("sans0",option+1) == 0)
anthony43f425d2012-02-26 12:58:58 +00004508 return;
anthonyafa3dfc2012-03-03 11:31:30 +00004509 if (LocaleCompare("sans2",option+1) == 0)
anthony43f425d2012-02-26 12:58:58 +00004510 return;
anthonyce8dcb32012-03-21 13:20:31 +00004511 if (LocaleCompare("list",option+1) == 0) {
anthony43f425d2012-02-26 12:58:58 +00004512 /* FUTURE: This should really be built into the MagickCore
4513 It does not actually require any wand or images at all!
4514 */
4515 ssize_t
4516 list;
4517
anthony24aa8822012-03-11 00:56:06 +00004518 list=ParseCommandOption(MagickListOptions,MagickFalse, arg1);
anthony43f425d2012-02-26 12:58:58 +00004519 switch (list)
4520 {
4521 case MagickCoderOptions:
4522 {
anthony92c93bd2012-03-19 14:02:47 +00004523 (void) ListCoderInfo((FILE *) NULL,_exception);
anthony43f425d2012-02-26 12:58:58 +00004524 break;
4525 }
4526 case MagickColorOptions:
4527 {
anthony92c93bd2012-03-19 14:02:47 +00004528 (void) ListColorInfo((FILE *) NULL,_exception);
anthony43f425d2012-02-26 12:58:58 +00004529 break;
4530 }
4531 case MagickConfigureOptions:
4532 {
anthony92c93bd2012-03-19 14:02:47 +00004533 (void) ListConfigureInfo((FILE *) NULL,_exception);
anthony43f425d2012-02-26 12:58:58 +00004534 break;
4535 }
4536 case MagickDelegateOptions:
4537 {
anthony92c93bd2012-03-19 14:02:47 +00004538 (void) ListDelegateInfo((FILE *) NULL,_exception);
anthony43f425d2012-02-26 12:58:58 +00004539 break;
4540 }
4541 case MagickFontOptions:
4542 {
anthony92c93bd2012-03-19 14:02:47 +00004543 (void) ListTypeInfo((FILE *) NULL,_exception);
anthony43f425d2012-02-26 12:58:58 +00004544 break;
4545 }
4546 case MagickFormatOptions:
anthony92c93bd2012-03-19 14:02:47 +00004547 (void) ListMagickInfo((FILE *) NULL,_exception);
anthony43f425d2012-02-26 12:58:58 +00004548 break;
4549 case MagickLocaleOptions:
anthony92c93bd2012-03-19 14:02:47 +00004550 (void) ListLocaleInfo((FILE *) NULL,_exception);
anthony43f425d2012-02-26 12:58:58 +00004551 break;
4552 case MagickLogOptions:
anthony92c93bd2012-03-19 14:02:47 +00004553 (void) ListLogInfo((FILE *) NULL,_exception);
anthony43f425d2012-02-26 12:58:58 +00004554 break;
4555 case MagickMagicOptions:
anthony92c93bd2012-03-19 14:02:47 +00004556 (void) ListMagicInfo((FILE *) NULL,_exception);
anthony43f425d2012-02-26 12:58:58 +00004557 break;
4558 case MagickMimeOptions:
anthony92c93bd2012-03-19 14:02:47 +00004559 (void) ListMimeInfo((FILE *) NULL,_exception);
anthony43f425d2012-02-26 12:58:58 +00004560 break;
4561 case MagickModuleOptions:
anthony92c93bd2012-03-19 14:02:47 +00004562 (void) ListModuleInfo((FILE *) NULL,_exception);
anthony43f425d2012-02-26 12:58:58 +00004563 break;
4564 case MagickPolicyOptions:
anthony92c93bd2012-03-19 14:02:47 +00004565 (void) ListPolicyInfo((FILE *) NULL,_exception);
anthony43f425d2012-02-26 12:58:58 +00004566 break;
4567 case MagickResourceOptions:
anthony92c93bd2012-03-19 14:02:47 +00004568 (void) ListMagickResourceInfo((FILE *) NULL,_exception);
anthony43f425d2012-02-26 12:58:58 +00004569 break;
4570 case MagickThresholdOptions:
anthony92c93bd2012-03-19 14:02:47 +00004571 (void) ListThresholdMaps((FILE *) NULL,_exception);
anthony43f425d2012-02-26 12:58:58 +00004572 break;
4573 default:
4574 (void) ListCommandOptions((FILE *) NULL,(CommandOption) list,
anthony92c93bd2012-03-19 14:02:47 +00004575 _exception);
anthony43f425d2012-02-26 12:58:58 +00004576 break;
4577 }
4578 return;
4579 }
4580
4581#if 0
4582 // adjust stack handling
4583 // Other 'special' options this should handle
4584 // "region" "list" "version"
4585 // It does not do "exit" however as due to its side-effect requirements
4586#endif
4587#if 0
4588 if ( ( process_flags & ProcessUnknownOptionError ) != 0 )
anthony43f425d2012-02-26 12:58:58 +00004589#endif
anthonyebb73a22012-03-22 14:25:52 +00004590 CLIWandException(OptionError,"UnrecognizedOption",option);
anthony43f425d2012-02-26 12:58:58 +00004591
anthony92c93bd2012-03-19 14:02:47 +00004592#undef _exception
anthony43f425d2012-02-26 12:58:58 +00004593}