]> granicus.if.org Git - imagemagick/blob - MagickWand/mogrify.c
Removed 3 redundant lines of code from coders/png.c
[imagemagick] / MagickWand / mogrify.c
1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 %                                                                             %
4 %                                                                             %
5 %                                                                             %
6 %              M   M   OOO   GGGGG  RRRR   IIIII  FFFFF  Y   Y                %
7 %              MM MM  O   O  G      R   R    I    F       Y Y                 %
8 %              M M M  O   O  G GGG  RRRR     I    FFF      Y                  %
9 %              M   M  O   O  G   G  R R      I    F        Y                  %
10 %              M   M   OOO   GGGG   R  R   IIIII  F        Y                  %
11 %                                                                             %
12 %                                                                             %
13 %                         MagickWand Module Methods                           %
14 %                                                                             %
15 %                              Software Design                                %
16 %                                John Cristy                                  %
17 %                                March 2000                                   %
18 %                                                                             %
19 %                                                                             %
20 %  Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization      %
21 %  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 %  Use the mogrify program to resize an image, blur, crop, despeckle, dither,
37 %  draw on, flip, join, re-sample, and much more. This tool is similiar to
38 %  convert except that the original image file is overwritten (unless you
39 %  change the file suffix with the -format option) with any changes you
40 %  request.
41 %
42 */
43 \f
44 /*
45   Include declarations.
46 */
47 #include "MagickWand/studio.h"
48 #include "MagickWand/MagickWand.h"
49 #include "MagickWand/mogrify-private.h"
50 #undef DegreesToRadians
51 #undef RadiansToDegrees
52 #include "MagickCore/image-private.h"
53 #include "MagickCore/monitor-private.h"
54 #include "MagickCore/string-private.h"
55 #include "MagickCore/thread-private.h"
56 #include "MagickCore/utility-private.h"
57 \f
58 /*
59  Constant declaration.
60 */
61 static const char
62   MogrifyBackgroundColor[] = "#ffffff",  /* white */
63   MogrifyBorderColor[] = "#dfdfdf",  /* gray */
64   MogrifyMatteColor[] = "#bdbdbd";  /* gray */
65 \f
66 /*
67   Define declarations.
68 */
69 #define UndefinedCompressionQuality  0UL
70 \f
71 /*
72 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
73 %                                                                             %
74 %                                                                             %
75 %                                                                             %
76 %     M a g i c k C o m m a n d G e n e s i s                                 %
77 %                                                                             %
78 %                                                                             %
79 %                                                                             %
80 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
81 %
82 %  MagickCommandGenesis() applies image processing options to an image as
83 %  prescribed by command line options.
84 %
85 %  The format of the MagickCommandGenesis method is:
86 %
87 %      MagickBooleanType MagickCommandGenesis(ImageInfo *image_info,
88 %        MagickCommand command,int argc,char **argv,char **metadata,
89 %        ExceptionInfo *exception)
90 %
91 %  A description of each parameter follows:
92 %
93 %    o image_info: the image info.
94 %
95 %    o command: Choose from ConvertImageCommand, IdentifyImageCommand,
96 %      MogrifyImageCommand, CompositeImageCommand, CompareImagesCommand,
97 %      ConjureImageCommand, StreamImageCommand, ImportImageCommand,
98 %      DisplayImageCommand, or AnimateImageCommand.
99 %
100 %    o argc: Specifies a pointer to an integer describing the number of
101 %      elements in the argument vector.
102 %
103 %    o argv: Specifies a pointer to a text array containing the command line
104 %      arguments.
105 %
106 %    o metadata: any metadata is returned here.
107 %
108 %    o exception: return any errors or warnings in this structure.
109 %
110 */
111
112 static inline double MagickMin(const double x,const double y)
113 {
114   if (x < y)
115     return(x);
116   return(y);
117 }
118
119 WandExport MagickBooleanType MagickCommandGenesis(ImageInfo *image_info,
120   MagickCommand command,int argc,char **argv,char **metadata,
121   ExceptionInfo *exception)
122 {
123   char
124     *option;
125
126   double
127     duration,
128     serial;
129
130   MagickBooleanType
131     concurrent,
132     regard_warnings,
133     status;
134
135   register ssize_t
136     i;
137
138   size_t
139     iterations,
140     n,
141     number_threads;
142
143   (void) setlocale(LC_ALL,"");
144   (void) setlocale(LC_NUMERIC,"C");
145   concurrent=MagickFalse;
146   duration=(-1.0);
147   iterations=1;
148   status=MagickFalse;
149   regard_warnings=MagickFalse;
150   for (i=1; i < (ssize_t) (argc-1); i++)
151   {
152     option=argv[i];
153     if ((strlen(option) == 1) || ((*option != '-') && (*option != '+')))
154       continue;
155     if (LocaleCompare("bench",option+1) == 0)
156       iterations=StringToUnsignedLong(argv[++i]);
157     if (LocaleCompare("concurrent",option+1) == 0)
158       concurrent=MagickTrue;
159     if (LocaleCompare("debug",option+1) == 0)
160       (void) SetLogEventMask(argv[++i]);
161     if (LocaleCompare("duration",option+1) == 0)
162       duration=StringToDouble(argv[++i],(char **) NULL);
163     if (LocaleCompare("regard-warnings",option+1) == 0)
164       regard_warnings=MagickTrue;
165   }
166   if (iterations == 1)
167     {
168       status=command(image_info,argc,argv,metadata,exception);
169       if (exception->severity != UndefinedException)
170         {
171           if ((exception->severity > ErrorException) ||
172               (regard_warnings != MagickFalse))
173             status=MagickTrue;
174           CatchException(exception);
175         }
176         if ((metadata != (char **) NULL) && (*metadata != (char *) NULL))
177           {
178             (void) fputs(*metadata,stdout);
179             (void) fputc('\n',stdout);
180             *metadata=DestroyString(*metadata);
181           }
182       return(status);
183     }
184   number_threads=GetOpenMPMaximumThreads();
185   serial=0.0;
186   for (n=1; n <= number_threads; n++)
187   {
188     double
189       e,
190       parallel,
191       user_time;
192
193     TimerInfo
194       *timer;
195
196     SetOpenMPMaximumThreads(n);
197     timer=AcquireTimerInfo();
198     if (concurrent == MagickFalse)
199       {
200         for (i=0; i < (ssize_t) iterations; i++)
201         {
202           if (status != MagickFalse)
203             continue;
204           if (duration > 0)
205             {
206               if (GetElapsedTime(timer) > duration)
207                 continue;
208               (void) ContinueTimer(timer);
209             }
210           status=command(image_info,argc,argv,metadata,exception);
211           if (exception->severity != UndefinedException)
212             {
213               if ((exception->severity > ErrorException) ||
214                   (regard_warnings != MagickFalse))
215                 status=MagickTrue;
216               CatchException(exception);
217             }
218           if ((metadata != (char **) NULL) && (*metadata != (char *) NULL))
219             {
220               (void) fputs(*metadata,stdout);
221               (void) fputc('\n',stdout);
222               *metadata=DestroyString(*metadata);
223             }
224         }
225       }
226     else
227       {
228         SetOpenMPNested(1);
229 #if defined(MAGICKCORE_OPENMP_SUPPORT)
230         # pragma omp parallel for shared(status)
231 #endif
232         for (i=0; i < (ssize_t) iterations; i++)
233         {
234           if (status != MagickFalse)
235             continue;
236           if (duration > 0)
237             {
238               if (GetElapsedTime(timer) > duration)
239                 continue;
240               (void) ContinueTimer(timer);
241             }
242           status=command(image_info,argc,argv,metadata,exception);
243 #if defined(MAGICKCORE_OPENMP_SUPPORT)
244            # pragma omp critical (MagickCore_CommandGenesis)
245 #endif
246           {
247             if (exception->severity != UndefinedException)
248               {
249                 if ((exception->severity > ErrorException) ||
250                     (regard_warnings != MagickFalse))
251                   status=MagickTrue;
252                 CatchException(exception);
253               }
254             if ((metadata != (char **) NULL) && (*metadata != (char *) NULL))
255               {
256                 (void) fputs(*metadata,stdout);
257                 (void) fputc('\n',stdout);
258                 *metadata=DestroyString(*metadata);
259               }
260           }
261         }
262       }
263     user_time=GetUserTime(timer);
264     parallel=GetElapsedTime(timer);
265     e=1.0;
266     if (n == 1)
267       serial=parallel;
268     else
269       e=((1.0/(1.0/((serial/(serial+parallel))+(1.0-(serial/(serial+parallel)))/
270         (double) n)))-(1.0/(double) n))/(1.0-1.0/(double) n);
271     (void) FormatLocaleFile(stderr,
272       "Performance[%.20g]: %.20gi %0.3fips %0.3fe %0.3fu %lu:%02lu.%03lu\n",
273       (double) n,(double) iterations,(double) iterations/parallel,e,
274       user_time,(unsigned long) (parallel/60.0),(unsigned long)
275       floor(fmod(parallel,60.0)),(unsigned long)
276       (1000.0*(parallel-floor(parallel))+0.5));
277     timer=DestroyTimerInfo(timer);
278   }
279   return(status);
280 }
281 \f
282 /*
283 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
284 %                                                                             %
285 %                                                                             %
286 %                                                                             %
287 +     M o g r i f y I m a g e                                                 %
288 %                                                                             %
289 %                                                                             %
290 %                                                                             %
291 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
292 %
293 %  MogrifyImage() applies simple single image processing options to a single
294 %  image that may be part of a large list, but also handles any 'region'
295 %  image handling.
296 %
297 %  The image in the list may be modified in three different ways...
298 %
299 %    * directly modified (EG: -negate, -gamma, -level, -annotate, -draw),
300 %    * replaced by a new image (EG: -spread, -resize, -rotate, -morphology)
301 %    * replace by a list of images (only the -separate option!)
302 %
303 %  In each case the result is returned into the list, and a pointer to the
304 %  modified image (last image added if replaced by a list of images) is
305 %  returned.
306 %
307 %  ASIDE: The -crop is present but restricted to non-tile single image crops
308 %
309 %  This means if all the images are being processed (such as by
310 %  MogrifyImages(), next image to be processed will be as per the pointer
311 %  (*image)->next.  Also the image list may grow as a result of some specific
312 %  operations but as images are never merged or deleted, it will never shrink
313 %  in length.  Typically the list will remain the same length.
314 %
315 %  WARNING: As the image pointed to may be replaced, the first image in the
316 %  list may also change.  GetFirstImageInList() should be used by caller if
317 %  they wish return the Image pointer to the first image in list.
318 %
319 %
320 %  The format of the MogrifyImage method is:
321 %
322 %      MagickBooleanType MogrifyImage(ImageInfo *image_info,const int argc,
323 %        const char **argv,Image **image)
324 %
325 %  A description of each parameter follows:
326 %
327 %    o image_info: the image info..
328 %
329 %    o argc: Specifies a pointer to an integer describing the number of
330 %      elements in the argument vector.
331 %
332 %    o argv: Specifies a pointer to a text array containing the command line
333 %      arguments.
334 %
335 %    o image: the image.
336 %
337 %    o exception: return any errors or warnings in this structure.
338 %
339 */
340
341 static inline Image *GetImageCache(const ImageInfo *image_info,const char *path,
342   ExceptionInfo *exception)
343 {
344   char
345     key[MaxTextExtent];
346
347   ExceptionInfo
348     *sans_exception;
349
350   Image
351     *image;
352
353   ImageInfo
354     *read_info;
355
356   /*
357     Read an image into a image cache if not already present.  Return the image
358     that is in the cache under that filename.
359   */
360   (void) FormatLocaleString(key,MaxTextExtent,"cache:%s",path);
361   sans_exception=AcquireExceptionInfo();
362   image=(Image *) GetImageRegistry(ImageRegistryType,key,sans_exception);
363   sans_exception=DestroyExceptionInfo(sans_exception);
364   if (image != (Image *) NULL)
365     return(image);
366   read_info=CloneImageInfo(image_info);
367   (void) CopyMagickString(read_info->filename,path,MaxTextExtent);
368   image=ReadImage(read_info,exception);
369   read_info=DestroyImageInfo(read_info);
370   if (image != (Image *) NULL)
371     (void) SetImageRegistry(ImageRegistryType,key,image,exception);
372   return(image);
373 }
374
375 static MagickBooleanType IsPathWritable(const char *path)
376 {
377   if (IsPathAccessible(path) == MagickFalse)
378     return(MagickFalse);
379   if (access_utf8(path,W_OK) != 0)
380     return(MagickFalse);
381   return(MagickTrue);
382 }
383
384 static inline ssize_t MagickMax(const ssize_t x,const ssize_t y)
385 {
386   if (x > y)
387     return(x);
388   return(y);
389 }
390
391 static MagickBooleanType MonitorProgress(const char *text,
392   const MagickOffsetType offset,const MagickSizeType extent,
393   void *wand_unused(client_data))
394 {
395   char
396     message[MaxTextExtent],
397     tag[MaxTextExtent];
398
399   const char
400     *locale_message;
401
402   register char
403     *p;
404
405   if (extent < 2)
406     return(MagickTrue);
407   (void) CopyMagickMemory(tag,text,MaxTextExtent);
408   p=strrchr(tag,'/');
409   if (p != (char *) NULL)
410     *p='\0';
411   (void) FormatLocaleString(message,MaxTextExtent,"Monitor/%s",tag);
412   locale_message=GetLocaleMessage(message);
413   if (locale_message == message)
414     locale_message=tag;
415   if (p == (char *) NULL)
416     (void) FormatLocaleFile(stderr,"%s: %ld of %lu, %02ld%% complete\r",
417       locale_message,(long) offset,(unsigned long) extent,(long)
418       (100L*offset/(extent-1)));
419   else
420     (void) FormatLocaleFile(stderr,"%s[%s]: %ld of %lu, %02ld%% complete\r",
421       locale_message,p+1,(long) offset,(unsigned long) extent,(long)
422       (100L*offset/(extent-1)));
423   if (offset == (MagickOffsetType) (extent-1))
424     (void) FormatLocaleFile(stderr,"\n");
425   (void) fflush(stderr);
426   return(MagickTrue);
427 }
428
429 static Image *SparseColorOption(const Image *image,
430   const SparseColorMethod method,const char *arguments,
431   const MagickBooleanType color_from_image,ExceptionInfo *exception)
432 {
433   char
434     token[MaxTextExtent];
435
436   const char
437     *p;
438
439   double
440     *sparse_arguments;
441
442   Image
443     *sparse_image;
444
445   PixelInfo
446     color;
447
448   MagickBooleanType
449     error;
450
451   register size_t
452     x;
453
454   size_t
455     number_arguments,
456     number_colors;
457
458   /*
459     SparseColorOption() parses the complex -sparse-color argument into an an
460     array of floating point values then calls SparseColorImage().  Argument is
461     a complex mix of floating-point pixel coodinates, and color specifications
462     (or direct floating point numbers).  The number of floats needed to
463     represent a color varies depending on the current channel setting.
464   */
465   assert(image != (Image *) NULL);
466   assert(image->signature == MagickSignature);
467   if (image->debug != MagickFalse)
468     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
469   assert(exception != (ExceptionInfo *) NULL);
470   assert(exception->signature == MagickSignature);
471   /*
472     Limit channels according to image - and add up number of color channel.
473   */
474   number_colors=0;
475   if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
476     number_colors++;
477   if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
478     number_colors++;
479   if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
480     number_colors++;
481   if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
482       (image->colorspace == CMYKColorspace))
483     number_colors++;
484   if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
485       (image->matte != MagickFalse))
486     number_colors++;
487
488   /*
489     Read string, to determine number of arguments needed,
490   */
491   p=arguments;
492   x=0;
493   while( *p != '\0' )
494   {
495     GetMagickToken(p,&p,token);
496     if ( token[0] == ',' ) continue;
497     if ( isalpha((int) token[0]) || token[0] == '#' ) {
498       if ( color_from_image ) {
499         (void) ThrowMagickException(exception,GetMagickModule(),
500             OptionError, "InvalidArgument", "`%s': %s", "sparse-color",
501             "Color arg given, when colors are coming from image");
502         return( (Image *)NULL);
503       }
504       x += number_colors;  /* color argument */
505     }
506     else {
507       x++;   /* floating point argument */
508     }
509   }
510   error=MagickTrue;
511   if ( color_from_image ) {
512     /* just the control points are being given */
513     error = ( x % 2 != 0 ) ? MagickTrue : MagickFalse;
514     number_arguments=(x/2)*(2+number_colors);
515   }
516   else {
517     /* control points and color values */
518     error = ( x % (2+number_colors) != 0 ) ? MagickTrue : MagickFalse;
519     number_arguments=x;
520   }
521   if ( error ) {
522     (void) ThrowMagickException(exception,GetMagickModule(),
523                OptionError, "InvalidArgument", "`%s': %s", "sparse-color",
524                "Invalid number of Arguments");
525     return( (Image *)NULL);
526   }
527
528   /* Allocate and fill in the floating point arguments */
529   sparse_arguments=(double *) AcquireQuantumMemory(number_arguments,
530     sizeof(*sparse_arguments));
531   if (sparse_arguments == (double *) NULL) {
532     (void) ThrowMagickException(exception,GetMagickModule(),ResourceLimitError,
533       "MemoryAllocationFailed","%s","SparseColorOption");
534     return( (Image *)NULL);
535   }
536   (void) ResetMagickMemory(sparse_arguments,0,number_arguments*
537     sizeof(*sparse_arguments));
538   p=arguments;
539   x=0;
540   while( *p != '\0' && x < number_arguments ) {
541     /* X coordinate */
542     token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token);
543     if ( token[0] == '\0' ) break;
544     if ( isalpha((int) token[0]) || token[0] == '#' ) {
545       (void) ThrowMagickException(exception,GetMagickModule(),
546             OptionError, "InvalidArgument", "`%s': %s", "sparse-color",
547             "Color found, instead of X-coord");
548       error = MagickTrue;
549       break;
550     }
551     sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
552     /* Y coordinate */
553     token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token);
554     if ( token[0] == '\0' ) break;
555     if ( isalpha((int) token[0]) || token[0] == '#' ) {
556       (void) ThrowMagickException(exception,GetMagickModule(),
557             OptionError, "InvalidArgument", "`%s': %s", "sparse-color",
558             "Color found, instead of Y-coord");
559       error = MagickTrue;
560       break;
561     }
562     sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
563     /* color values for this control point */
564 #if 0
565     if ( (color_from_image ) {
566       /* get color from image */
567       /* HOW??? */
568     }
569     else
570 #endif
571     {
572       /* color name or function given in string argument */
573       token[0]=','; while ( token[0] == ',' ) GetMagickToken(p,&p,token);
574       if ( token[0] == '\0' ) break;
575       if ( isalpha((int) token[0]) || token[0] == '#' ) {
576         /* Color string given */
577         (void) QueryColorCompliance(token,AllCompliance,&color,exception);
578         if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
579           sparse_arguments[x++] = QuantumScale*color.red;
580         if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
581           sparse_arguments[x++] = QuantumScale*color.green;
582         if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
583           sparse_arguments[x++] = QuantumScale*color.blue;
584         if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
585             (image->colorspace == CMYKColorspace))
586           sparse_arguments[x++] = QuantumScale*color.black;
587         if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
588             (image->matte != MagickFalse))
589           sparse_arguments[x++] = QuantumScale*color.alpha;
590       }
591       else {
592         /* Colors given as a set of floating point values - experimental */
593         /* NB: token contains the first floating point value to use! */
594         if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
595           {
596           while ( token[0] == ',' ) GetMagickToken(p,&p,token);
597           if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
598             break;
599           sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
600           token[0] = ','; /* used this token - get another */
601         }
602         if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
603           {
604           while ( token[0] == ',' ) GetMagickToken(p,&p,token);
605           if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
606             break;
607           sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
608           token[0] = ','; /* used this token - get another */
609         }
610         if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
611           {
612           while ( token[0] == ',' ) GetMagickToken(p,&p,token);
613           if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
614             break;
615           sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
616           token[0] = ','; /* used this token - get another */
617         }
618         if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
619             (image->colorspace == CMYKColorspace))
620           {
621           while ( token[0] == ',' ) GetMagickToken(p,&p,token);
622           if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
623             break;
624           sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
625           token[0] = ','; /* used this token - get another */
626         }
627         if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
628             (image->matte != MagickFalse))
629           {
630           while ( token[0] == ',' ) GetMagickToken(p,&p,token);
631           if ( token[0] == '\0' || isalpha((int)token[0]) || token[0] == '#' )
632             break;
633           sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
634           token[0] = ','; /* used this token - get another */
635         }
636       }
637     }
638   }
639   if ( number_arguments != x && !error ) {
640     (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
641       "InvalidArgument","`%s': %s","sparse-color","Argument Parsing Error");
642     sparse_arguments=(double *) RelinquishMagickMemory(sparse_arguments);
643     return( (Image *)NULL);
644   }
645   if ( error )
646     return( (Image *)NULL);
647
648   /* Call the Interpolation function with the parsed arguments */
649   sparse_image=SparseColorImage(image,method,number_arguments,sparse_arguments,
650     exception);
651   sparse_arguments=(double *) RelinquishMagickMemory(sparse_arguments);
652   return( sparse_image );
653 }
654
655 WandExport MagickBooleanType MogrifyImage(ImageInfo *image_info,const int argc,
656   const char **argv,Image **image,ExceptionInfo *exception)
657 {
658   ChannelType
659     channel;
660
661   CompositeOperator
662     compose;
663
664   const char
665     *format,
666     *option;
667
668   double
669     attenuate;
670
671   DrawInfo
672     *draw_info;
673
674   GeometryInfo
675     geometry_info;
676
677   Image
678     *region_image;
679
680   ImageInfo
681     *mogrify_info;
682
683   MagickStatusType
684     status;
685
686   PixelInfo
687     fill;
688
689   MagickStatusType
690     flags;
691
692   PixelInterpolateMethod
693     interpolate_method;
694
695   QuantizeInfo
696     *quantize_info;
697
698   RectangleInfo
699     geometry,
700     region_geometry;
701
702   register ssize_t
703     i;
704
705   /*
706     Initialize method variables.
707   */
708   assert(image_info != (const ImageInfo *) NULL);
709   assert(image_info->signature == MagickSignature);
710   assert(image != (Image **) NULL);
711   assert((*image)->signature == MagickSignature);
712   if ((*image)->debug != MagickFalse)
713     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",(*image)->filename);
714   if (argc < 0)
715     return(MagickTrue);
716   mogrify_info=CloneImageInfo(image_info);
717   draw_info=CloneDrawInfo(mogrify_info,(DrawInfo *) NULL);
718   quantize_info=AcquireQuantizeInfo(mogrify_info);
719   SetGeometryInfo(&geometry_info);
720   GetPixelInfo(*image,&fill);
721   fill=(*image)->background_color;
722   attenuate=1.0;
723   compose=(*image)->compose;
724   interpolate_method=UndefinedInterpolatePixel;
725   channel=mogrify_info->channel;
726   format=GetImageOption(mogrify_info,"format");
727   SetGeometry(*image,&region_geometry);
728   region_image=NewImageList();
729   /*
730     Transmogrify the image.
731   */
732   for (i=0; i < (ssize_t) argc; i++)
733   {
734     Image
735       *mogrify_image;
736
737     ssize_t
738       count;
739
740     option=argv[i];
741     if (IsCommandOption(option) == MagickFalse)
742       continue;
743     count=MagickMax(ParseCommandOption(MagickCommandOptions,MagickFalse,option),
744       0L);
745     if ((i+count) >= (ssize_t) argc)
746       break;
747     status=MogrifyImageInfo(mogrify_info,(int) count+1,argv+i,exception);
748     mogrify_image=(Image *)NULL;
749     switch (*(option+1))
750     {
751       case 'a':
752       {
753         if (LocaleCompare("adaptive-blur",option+1) == 0)
754           {
755             /*
756               Adaptive blur image.
757             */
758             (void) SyncImageSettings(mogrify_info,*image,exception);
759             flags=ParseGeometry(argv[i+1],&geometry_info);
760             if ((flags & SigmaValue) == 0)
761               geometry_info.sigma=1.0;
762             if ((flags & XiValue) == 0)
763               geometry_info.xi=0.0;
764             mogrify_image=AdaptiveBlurImage(*image,geometry_info.rho,
765               geometry_info.sigma,geometry_info.xi,exception);
766             break;
767           }
768         if (LocaleCompare("adaptive-resize",option+1) == 0)
769           {
770             /*
771               Adaptive resize image.
772             */
773             (void) SyncImageSettings(mogrify_info,*image,exception);
774             (void) ParseRegionGeometry(*image,argv[i+1],&geometry,exception);
775             mogrify_image=AdaptiveResizeImage(*image,geometry.width,
776               geometry.height,interpolate_method,exception);
777             break;
778           }
779         if (LocaleCompare("adaptive-sharpen",option+1) == 0)
780           {
781             /*
782               Adaptive sharpen image.
783             */
784             (void) SyncImageSettings(mogrify_info,*image,exception);
785             flags=ParseGeometry(argv[i+1],&geometry_info);
786             if ((flags & SigmaValue) == 0)
787               geometry_info.sigma=1.0;
788             if ((flags & XiValue) == 0)
789               geometry_info.xi=0.0;
790             mogrify_image=AdaptiveSharpenImage(*image,geometry_info.rho,
791               geometry_info.sigma,geometry_info.xi,exception);
792             break;
793           }
794         if (LocaleCompare("affine",option+1) == 0)
795           {
796             /*
797               Affine matrix.
798             */
799             if (*option == '+')
800               {
801                 GetAffineMatrix(&draw_info->affine);
802                 break;
803               }
804             (void) ParseAffineGeometry(argv[i+1],&draw_info->affine,exception);
805             break;
806           }
807         if (LocaleCompare("alpha",option+1) == 0)
808           {
809             AlphaChannelType
810               alpha_type;
811
812             (void) SyncImageSettings(mogrify_info,*image,exception);
813             alpha_type=(AlphaChannelType) ParseCommandOption(MagickAlphaOptions,
814               MagickFalse,argv[i+1]);
815             (void) SetImageAlphaChannel(*image,alpha_type,exception);
816             break;
817           }
818         if (LocaleCompare("annotate",option+1) == 0)
819           {
820             char
821               *text,
822               geometry[MaxTextExtent];
823
824             /*
825               Annotate image.
826             */
827             (void) SyncImageSettings(mogrify_info,*image,exception);
828             SetGeometryInfo(&geometry_info);
829             flags=ParseGeometry(argv[i+1],&geometry_info);
830             if ((flags & SigmaValue) == 0)
831               geometry_info.sigma=geometry_info.rho;
832             text=InterpretImageProperties(mogrify_info,*image,argv[i+2],
833               exception);
834             if (text == (char *) NULL)
835               break;
836             (void) CloneString(&draw_info->text,text);
837             text=DestroyString(text);
838             (void) FormatLocaleString(geometry,MaxTextExtent,"%+f%+f",
839               geometry_info.xi,geometry_info.psi);
840             (void) CloneString(&draw_info->geometry,geometry);
841             draw_info->affine.sx=cos(DegreesToRadians(
842               fmod(geometry_info.rho,360.0)));
843             draw_info->affine.rx=sin(DegreesToRadians(
844               fmod(geometry_info.rho,360.0)));
845             draw_info->affine.ry=(-sin(DegreesToRadians(
846               fmod(geometry_info.sigma,360.0))));
847             draw_info->affine.sy=cos(DegreesToRadians(
848               fmod(geometry_info.sigma,360.0)));
849             (void) AnnotateImage(*image,draw_info,exception);
850             break;
851           }
852         if (LocaleCompare("antialias",option+1) == 0)
853           {
854             draw_info->stroke_antialias=(*option == '-') ? MagickTrue :
855               MagickFalse;
856             draw_info->text_antialias=(*option == '-') ? MagickTrue :
857               MagickFalse;
858             break;
859           }
860         if (LocaleCompare("attenuate",option+1) == 0)
861           {
862             if (*option == '+')
863               {
864                 attenuate=1.0;
865                 break;
866               }
867             attenuate=StringToDouble(argv[i+1],(char **) NULL);
868             break;
869           }
870         if (LocaleCompare("auto-gamma",option+1) == 0)
871           {
872             /*
873               Auto Adjust Gamma of image based on its mean
874             */
875             (void) SyncImageSettings(mogrify_info,*image,exception);
876             (void) AutoGammaImage(*image,exception);
877             break;
878           }
879         if (LocaleCompare("auto-level",option+1) == 0)
880           {
881             /*
882               Perfectly Normalize (max/min stretch) the image
883             */
884             (void) SyncImageSettings(mogrify_info,*image,exception);
885             (void) AutoLevelImage(*image,exception);
886             break;
887           }
888         if (LocaleCompare("auto-orient",option+1) == 0)
889           {
890             (void) SyncImageSettings(mogrify_info,*image,exception);
891             switch ((*image)->orientation)
892             {
893               case TopRightOrientation:
894               {
895                 mogrify_image=FlopImage(*image,exception);
896                 break;
897               }
898               case BottomRightOrientation:
899               {
900                 mogrify_image=RotateImage(*image,180.0,exception);
901                 break;
902               }
903               case BottomLeftOrientation:
904               {
905                 mogrify_image=FlipImage(*image,exception);
906                 break;
907               }
908               case LeftTopOrientation:
909               {
910                 mogrify_image=TransposeImage(*image,exception);
911                 break;
912               }
913               case RightTopOrientation:
914               {
915                 mogrify_image=RotateImage(*image,90.0,exception);
916                 break;
917               }
918               case RightBottomOrientation:
919               {
920                 mogrify_image=TransverseImage(*image,exception);
921                 break;
922               }
923               case LeftBottomOrientation:
924               {
925                 mogrify_image=RotateImage(*image,270.0,exception);
926                 break;
927               }
928               default:
929                 break;
930             }
931             if (mogrify_image != (Image *) NULL)
932               mogrify_image->orientation=TopLeftOrientation;
933             break;
934           }
935         break;
936       }
937       case 'b':
938       {
939         if (LocaleCompare("black-threshold",option+1) == 0)
940           {
941             /*
942               Black threshold image.
943             */
944             (void) SyncImageSettings(mogrify_info,*image,exception);
945             (void) BlackThresholdImage(*image,argv[i+1],exception);
946             break;
947           }
948         if (LocaleCompare("blue-shift",option+1) == 0)
949           {
950             /*
951               Blue shift image.
952             */
953             (void) SyncImageSettings(mogrify_info,*image,exception);
954             geometry_info.rho=1.5;
955             if (*option == '-')
956               flags=ParseGeometry(argv[i+1],&geometry_info);
957             mogrify_image=BlueShiftImage(*image,geometry_info.rho,exception);
958             break;
959           }
960         if (LocaleCompare("blur",option+1) == 0)
961           {
962             /*
963               Gaussian blur image.
964             */
965             (void) SyncImageSettings(mogrify_info,*image,exception);
966             flags=ParseGeometry(argv[i+1],&geometry_info);
967             if ((flags & SigmaValue) == 0)
968               geometry_info.sigma=1.0;
969             if ((flags & XiValue) == 0)
970               geometry_info.xi=0.0;
971             mogrify_image=BlurImage(*image,geometry_info.rho,
972               geometry_info.sigma,geometry_info.xi,exception);
973             break;
974           }
975         if (LocaleCompare("border",option+1) == 0)
976           {
977             /*
978               Surround image with a border of solid color.
979             */
980             (void) SyncImageSettings(mogrify_info,*image,exception);
981             flags=ParsePageGeometry(*image,argv[i+1],&geometry,exception);
982             if ((flags & SigmaValue) == 0)
983               geometry.height=geometry.width;
984             mogrify_image=BorderImage(*image,&geometry,compose,exception);
985             break;
986           }
987         if (LocaleCompare("bordercolor",option+1) == 0)
988           {
989             if (*option == '+')
990               {
991                 (void) QueryColorCompliance(MogrifyBorderColor,AllCompliance,
992                   &draw_info->border_color,exception);
993                 break;
994               }
995             (void) QueryColorCompliance(argv[i+1],AllCompliance,
996               &draw_info->border_color,exception);
997             break;
998           }
999         if (LocaleCompare("box",option+1) == 0)
1000           {
1001             (void) QueryColorCompliance(argv[i+1],AllCompliance,
1002               &draw_info->undercolor,exception);
1003             break;
1004           }
1005         if (LocaleCompare("brightness-contrast",option+1) == 0)
1006           {
1007             double
1008               brightness,
1009               contrast;
1010
1011             GeometryInfo
1012               geometry_info;
1013
1014             MagickStatusType
1015               flags;
1016
1017             /*
1018               Brightness / contrast image.
1019             */
1020             (void) SyncImageSettings(mogrify_info,*image,exception);
1021             flags=ParseGeometry(argv[i+1],&geometry_info);
1022             brightness=geometry_info.rho;
1023             contrast=0.0;
1024             if ((flags & SigmaValue) != 0)
1025               contrast=geometry_info.sigma;
1026             (void) BrightnessContrastImage(*image,brightness,contrast,
1027               exception);
1028             break;
1029           }
1030         break;
1031       }
1032       case 'c':
1033       {
1034         if (LocaleCompare("cdl",option+1) == 0)
1035           {
1036             char
1037               *color_correction_collection;
1038
1039             /*
1040               Color correct with a color decision list.
1041             */
1042             (void) SyncImageSettings(mogrify_info,*image,exception);
1043             color_correction_collection=FileToString(argv[i+1],~0,exception);
1044             if (color_correction_collection == (char *) NULL)
1045               break;
1046             (void) ColorDecisionListImage(*image,color_correction_collection,
1047               exception);
1048             break;
1049           }
1050         if (LocaleCompare("channel",option+1) == 0)
1051           {
1052             if (*option == '+')
1053               channel=DefaultChannels;
1054             else
1055               channel=(ChannelType) ParseChannelOption(argv[i+1]);
1056             SetPixelChannelMapMask(*image,channel);
1057             break;
1058           }
1059         if (LocaleCompare("charcoal",option+1) == 0)
1060           {
1061             /*
1062               Charcoal image.
1063             */
1064             (void) SyncImageSettings(mogrify_info,*image,exception);
1065             flags=ParseGeometry(argv[i+1],&geometry_info);
1066             if ((flags & SigmaValue) == 0)
1067               geometry_info.sigma=1.0;
1068             if ((flags & XiValue) == 0)
1069               geometry_info.xi=1.0;
1070             mogrify_image=CharcoalImage(*image,geometry_info.rho,
1071               geometry_info.sigma,geometry_info.xi,exception);
1072             break;
1073           }
1074         if (LocaleCompare("chop",option+1) == 0)
1075           {
1076             /*
1077               Chop the image.
1078             */
1079             (void) SyncImageSettings(mogrify_info,*image,exception);
1080             (void) ParseGravityGeometry(*image,argv[i+1],&geometry,exception);
1081             mogrify_image=ChopImage(*image,&geometry,exception);
1082             break;
1083           }
1084         if (LocaleCompare("clamp",option+1) == 0)
1085           {
1086             /*
1087               Clamp image.
1088             */
1089             (void) SyncImageSettings(mogrify_info,*image,exception);
1090             (void) ClampImage(*image,exception);
1091             break;
1092           }
1093         if (LocaleCompare("clip",option+1) == 0)
1094           {
1095             (void) SyncImageSettings(mogrify_info,*image,exception);
1096             if (*option == '+')
1097               {
1098                 (void) SetImageClipMask(*image,(Image *) NULL,exception);
1099                 break;
1100               }
1101             (void) ClipImage(*image,exception);
1102             break;
1103           }
1104         if (LocaleCompare("clip-mask",option+1) == 0)
1105           {
1106             CacheView
1107               *mask_view;
1108
1109             Image
1110               *mask_image;
1111
1112             register Quantum
1113               *restrict q;
1114
1115             register ssize_t
1116               x;
1117
1118             ssize_t
1119               y;
1120
1121             (void) SyncImageSettings(mogrify_info,*image,exception);
1122             if (*option == '+')
1123               {
1124                 /*
1125                   Remove a mask.
1126                 */
1127                 (void) SetImageMask(*image,(Image *) NULL,exception);
1128                 break;
1129               }
1130             /*
1131               Set the image mask.
1132               FUTURE: This Should Be a SetImageAlphaChannel() call, Or two.
1133             */
1134             mask_image=GetImageCache(mogrify_info,argv[i+1],exception);
1135             if (mask_image == (Image *) NULL)
1136               break;
1137             if (SetImageStorageClass(mask_image,DirectClass,exception) == MagickFalse)
1138               return(MagickFalse);
1139             mask_view=AcquireCacheView(mask_image);
1140             for (y=0; y < (ssize_t) mask_image->rows; y++)
1141             {
1142               q=GetCacheViewAuthenticPixels(mask_view,0,y,mask_image->columns,1,
1143                 exception);
1144               if (q == (Quantum *) NULL)
1145                 break;
1146               for (x=0; x < (ssize_t) mask_image->columns; x++)
1147               {
1148                 if (mask_image->matte == MagickFalse)
1149                   SetPixelAlpha(mask_image,GetPixelIntensity(mask_image,q),q);
1150                 SetPixelRed(mask_image,GetPixelAlpha(mask_image,q),q);
1151                 SetPixelGreen(mask_image,GetPixelAlpha(mask_image,q),q);
1152                 SetPixelBlue(mask_image,GetPixelAlpha(mask_image,q),q);
1153                 q+=GetPixelChannels(mask_image);
1154               }
1155               if (SyncCacheViewAuthenticPixels(mask_view,exception) == MagickFalse)
1156                 break;
1157             }
1158             mask_view=DestroyCacheView(mask_view);
1159             mask_image->matte=MagickTrue;
1160             (void) SetImageClipMask(*image,mask_image,exception);
1161             break;
1162           }
1163         if (LocaleCompare("clip-path",option+1) == 0)
1164           {
1165             (void) SyncImageSettings(mogrify_info,*image,exception);
1166             (void) ClipImagePath(*image,argv[i+1],*option == '-' ? MagickTrue :
1167               MagickFalse,exception);
1168             break;
1169           }
1170         if (LocaleCompare("colorize",option+1) == 0)
1171           {
1172             /*
1173               Colorize the image.
1174             */
1175             (void) SyncImageSettings(mogrify_info,*image,exception);
1176             mogrify_image=ColorizeImage(*image,argv[i+1],&fill,exception);
1177             break;
1178           }
1179         if (LocaleCompare("color-matrix",option+1) == 0)
1180           {
1181             KernelInfo
1182               *kernel;
1183
1184             (void) SyncImageSettings(mogrify_info,*image,exception);
1185             kernel=AcquireKernelInfo(argv[i+1]);
1186             if (kernel == (KernelInfo *) NULL)
1187               break;
1188             mogrify_image=ColorMatrixImage(*image,kernel,exception);
1189             kernel=DestroyKernelInfo(kernel);
1190             break;
1191           }
1192         if (LocaleCompare("colors",option+1) == 0)
1193           {
1194             /*
1195               Reduce the number of colors in the image.
1196             */
1197             (void) SyncImageSettings(mogrify_info,*image,exception);
1198             quantize_info->number_colors=StringToUnsignedLong(argv[i+1]);
1199             if (quantize_info->number_colors == 0)
1200               break;
1201             if (((*image)->storage_class == DirectClass) ||
1202                 (*image)->colors > quantize_info->number_colors)
1203               (void) QuantizeImage(quantize_info,*image,exception);
1204             else
1205               (void) CompressImageColormap(*image,exception);
1206             break;
1207           }
1208         if (LocaleCompare("colorspace",option+1) == 0)
1209           {
1210             ColorspaceType
1211               colorspace;
1212
1213             (void) SyncImageSettings(mogrify_info,*image,exception);
1214             if (*option == '+')
1215               {
1216                 (void) TransformImageColorspace(*image,RGBColorspace,exception);
1217                 break;
1218               }
1219             colorspace=(ColorspaceType) ParseCommandOption(
1220               MagickColorspaceOptions,MagickFalse,argv[i+1]);
1221             (void) TransformImageColorspace(*image,colorspace,exception);
1222             break;
1223           }
1224         if (LocaleCompare("compose",option+1) == 0)
1225           {
1226             (void) SyncImageSettings(mogrify_info,*image,exception);
1227             compose=(CompositeOperator) ParseCommandOption(MagickComposeOptions,
1228               MagickFalse,argv[i+1]);
1229             break;
1230           }
1231         if (LocaleCompare("contrast",option+1) == 0)
1232           {
1233             (void) SyncImageSettings(mogrify_info,*image,exception);
1234             (void) ContrastImage(*image,(*option == '-') ? MagickTrue :
1235               MagickFalse,exception);
1236             break;
1237           }
1238         if (LocaleCompare("contrast-stretch",option+1) == 0)
1239           {
1240             double
1241               black_point,
1242               white_point;
1243
1244             MagickStatusType
1245               flags;
1246
1247             /*
1248               Contrast stretch image.
1249             */
1250             (void) SyncImageSettings(mogrify_info,*image,exception);
1251             flags=ParseGeometry(argv[i+1],&geometry_info);
1252             black_point=geometry_info.rho;
1253             white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
1254               black_point;
1255             if ((flags & PercentValue) != 0)
1256               {
1257                 black_point*=(double) (*image)->columns*(*image)->rows/100.0;
1258                 white_point*=(double) (*image)->columns*(*image)->rows/100.0;
1259               }
1260             white_point=(MagickRealType) (*image)->columns*(*image)->rows-
1261               white_point;
1262             (void) ContrastStretchImage(*image,black_point,white_point,
1263               exception);
1264             break;
1265           }
1266         if (LocaleCompare("convolve",option+1) == 0)
1267           {
1268             KernelInfo
1269               *kernel_info;
1270
1271             (void) SyncImageSettings(mogrify_info,*image,exception);
1272             kernel_info=AcquireKernelInfo(argv[i+1]);
1273             if (kernel_info == (KernelInfo *) NULL)
1274               break;
1275             kernel_info->bias=(*image)->bias;
1276             mogrify_image=ConvolveImage(*image,kernel_info,exception);
1277             kernel_info=DestroyKernelInfo(kernel_info);
1278             break;
1279           }
1280         if (LocaleCompare("crop",option+1) == 0)
1281           {
1282             /*
1283               Crop a image to a smaller size
1284             */
1285             (void) SyncImageSettings(mogrify_info,*image,exception);
1286             mogrify_image=CropImageToTiles(*image,argv[i+1],exception);
1287             break;
1288           }
1289         if (LocaleCompare("cycle",option+1) == 0)
1290           {
1291             /*
1292               Cycle an image colormap.
1293             */
1294             (void) SyncImageSettings(mogrify_info,*image,exception);
1295             (void) CycleColormapImage(*image,(ssize_t) StringToLong(argv[i+1]),
1296               exception);
1297             break;
1298           }
1299         break;
1300       }
1301       case 'd':
1302       {
1303         if (LocaleCompare("decipher",option+1) == 0)
1304           {
1305             StringInfo
1306               *passkey;
1307
1308             /*
1309               Decipher pixels.
1310             */
1311             (void) SyncImageSettings(mogrify_info,*image,exception);
1312             passkey=FileToStringInfo(argv[i+1],~0,exception);
1313             if (passkey != (StringInfo *) NULL)
1314               {
1315                 (void) PasskeyDecipherImage(*image,passkey,exception);
1316                 passkey=DestroyStringInfo(passkey);
1317               }
1318             break;
1319           }
1320         if (LocaleCompare("density",option+1) == 0)
1321           {
1322             /*
1323               Set image density.
1324             */
1325             (void) CloneString(&draw_info->density,argv[i+1]);
1326             break;
1327           }
1328         if (LocaleCompare("depth",option+1) == 0)
1329           {
1330             (void) SyncImageSettings(mogrify_info,*image,exception);
1331             if (*option == '+')
1332               {
1333                 (void) SetImageDepth(*image,MAGICKCORE_QUANTUM_DEPTH,exception);
1334                 break;
1335               }
1336             (void) SetImageDepth(*image,StringToUnsignedLong(argv[i+1]),
1337               exception);
1338             break;
1339           }
1340         if (LocaleCompare("deskew",option+1) == 0)
1341           {
1342             double
1343               threshold;
1344
1345             /*
1346               Straighten the image.
1347             */
1348             (void) SyncImageSettings(mogrify_info,*image,exception);
1349             if (*option == '+')
1350               threshold=40.0*QuantumRange/100.0;
1351             else
1352               threshold=StringToDoubleInterval(argv[i+1],(double) QuantumRange+
1353                 1.0);
1354             mogrify_image=DeskewImage(*image,threshold,exception);
1355             break;
1356           }
1357         if (LocaleCompare("despeckle",option+1) == 0)
1358           {
1359             /*
1360               Reduce the speckles within an image.
1361             */
1362             (void) SyncImageSettings(mogrify_info,*image,exception);
1363             mogrify_image=DespeckleImage(*image,exception);
1364             break;
1365           }
1366         if (LocaleCompare("display",option+1) == 0)
1367           {
1368             (void) CloneString(&draw_info->server_name,argv[i+1]);
1369             break;
1370           }
1371         if (LocaleCompare("distort",option+1) == 0)
1372           {
1373             char
1374               *args,
1375               token[MaxTextExtent];
1376
1377             const char
1378               *p;
1379
1380             DistortImageMethod
1381               method;
1382
1383             double
1384               *arguments;
1385
1386             register ssize_t
1387               x;
1388
1389             size_t
1390               number_arguments;
1391
1392             /*
1393               Distort image.
1394             */
1395             (void) SyncImageSettings(mogrify_info,*image,exception);
1396             method=(DistortImageMethod) ParseCommandOption(MagickDistortOptions,
1397               MagickFalse,argv[i+1]);
1398             if (method == ResizeDistortion)
1399               {
1400                  double
1401                    resize_args[2];
1402
1403                  /*
1404                    Special Case - Argument is actually a resize geometry!
1405                    Convert that to an appropriate distortion argument array.
1406                  */
1407                  (void) ParseRegionGeometry(*image,argv[i+2],&geometry,
1408                    exception);
1409                  resize_args[0]=(double) geometry.width;
1410                  resize_args[1]=(double) geometry.height;
1411                  mogrify_image=DistortImage(*image,method,(size_t)2,
1412                    resize_args,MagickTrue,exception);
1413                  break;
1414               }
1415             args=InterpretImageProperties(mogrify_info,*image,argv[i+2],
1416               exception);
1417             if (args == (char *) NULL)
1418               break;
1419             p=(char *) args;
1420             for (x=0; *p != '\0'; x++)
1421             {
1422               GetMagickToken(p,&p,token);
1423               if (*token == ',')
1424                 GetMagickToken(p,&p,token);
1425             }
1426             number_arguments=(size_t) x;
1427             arguments=(double *) AcquireQuantumMemory(number_arguments,
1428               sizeof(*arguments));
1429             if (arguments == (double *) NULL)
1430               ThrowWandFatalException(ResourceLimitFatalError,
1431                 "MemoryAllocationFailed",(*image)->filename);
1432             (void) ResetMagickMemory(arguments,0,number_arguments*
1433               sizeof(*arguments));
1434             p=(char *) args;
1435             for (x=0; (x < (ssize_t) number_arguments) && (*p != '\0'); x++)
1436             {
1437               GetMagickToken(p,&p,token);
1438               if (*token == ',')
1439                 GetMagickToken(p,&p,token);
1440               arguments[x]=StringToDouble(token,(char **) NULL);
1441             }
1442             args=DestroyString(args);
1443             mogrify_image=DistortImage(*image,method,number_arguments,arguments,
1444               (*option == '+') ? MagickTrue : MagickFalse,exception);
1445             arguments=(double *) RelinquishMagickMemory(arguments);
1446             break;
1447           }
1448         if (LocaleCompare("dither",option+1) == 0)
1449           {
1450             if (*option == '+')
1451               {
1452                 quantize_info->dither=MagickFalse;
1453                 break;
1454               }
1455             quantize_info->dither=MagickTrue;
1456             quantize_info->dither_method=(DitherMethod) ParseCommandOption(
1457               MagickDitherOptions,MagickFalse,argv[i+1]);
1458             if (quantize_info->dither_method == NoDitherMethod)
1459               quantize_info->dither=MagickFalse;
1460             break;
1461           }
1462         if (LocaleCompare("draw",option+1) == 0)
1463           {
1464             /*
1465               Draw image.
1466             */
1467             (void) SyncImageSettings(mogrify_info,*image,exception);
1468             (void) CloneString(&draw_info->primitive,argv[i+1]);
1469             (void) DrawImage(*image,draw_info,exception);
1470             break;
1471           }
1472         break;
1473       }
1474       case 'e':
1475       {
1476         if (LocaleCompare("edge",option+1) == 0)
1477           {
1478             /*
1479               Enhance edges in the image.
1480             */
1481             (void) SyncImageSettings(mogrify_info,*image,exception);
1482             flags=ParseGeometry(argv[i+1],&geometry_info);
1483             if ((flags & SigmaValue) == 0)
1484               geometry_info.sigma=1.0;
1485             mogrify_image=EdgeImage(*image,geometry_info.rho,
1486               geometry_info.sigma,exception);
1487             break;
1488           }
1489         if (LocaleCompare("emboss",option+1) == 0)
1490           {
1491             /*
1492               Gaussian embossen image.
1493             */
1494             (void) SyncImageSettings(mogrify_info,*image,exception);
1495             flags=ParseGeometry(argv[i+1],&geometry_info);
1496             if ((flags & SigmaValue) == 0)
1497               geometry_info.sigma=1.0;
1498             mogrify_image=EmbossImage(*image,geometry_info.rho,
1499               geometry_info.sigma,exception);
1500             break;
1501           }
1502         if (LocaleCompare("encipher",option+1) == 0)
1503           {
1504             StringInfo
1505               *passkey;
1506
1507             /*
1508               Encipher pixels.
1509             */
1510             (void) SyncImageSettings(mogrify_info,*image,exception);
1511             passkey=FileToStringInfo(argv[i+1],~0,exception);
1512             if (passkey != (StringInfo *) NULL)
1513               {
1514                 (void) PasskeyEncipherImage(*image,passkey,exception);
1515                 passkey=DestroyStringInfo(passkey);
1516               }
1517             break;
1518           }
1519         if (LocaleCompare("encoding",option+1) == 0)
1520           {
1521             (void) CloneString(&draw_info->encoding,argv[i+1]);
1522             break;
1523           }
1524         if (LocaleCompare("enhance",option+1) == 0)
1525           {
1526             /*
1527               Enhance image.
1528             */
1529             (void) SyncImageSettings(mogrify_info,*image,exception);
1530             mogrify_image=EnhanceImage(*image,exception);
1531             break;
1532           }
1533         if (LocaleCompare("equalize",option+1) == 0)
1534           {
1535             /*
1536               Equalize image.
1537             */
1538             (void) SyncImageSettings(mogrify_info,*image,exception);
1539             (void) EqualizeImage(*image,exception);
1540             break;
1541           }
1542         if (LocaleCompare("evaluate",option+1) == 0)
1543           {
1544             double
1545               constant;
1546
1547             MagickEvaluateOperator
1548               op;
1549
1550             (void) SyncImageSettings(mogrify_info,*image,exception);
1551             op=(MagickEvaluateOperator) ParseCommandOption(
1552               MagickEvaluateOptions,MagickFalse,argv[i+1]);
1553             constant=StringToDoubleInterval(argv[i+2],(double) QuantumRange+
1554               1.0);
1555             (void) EvaluateImage(*image,op,constant,exception);
1556             break;
1557           }
1558         if (LocaleCompare("extent",option+1) == 0)
1559           {
1560             /*
1561               Set the image extent.
1562             */
1563             (void) SyncImageSettings(mogrify_info,*image,exception);
1564             flags=ParseGravityGeometry(*image,argv[i+1],&geometry,exception);
1565             if (geometry.width == 0)
1566               geometry.width=(*image)->columns;
1567             if (geometry.height == 0)
1568               geometry.height=(*image)->rows;
1569             mogrify_image=ExtentImage(*image,&geometry,exception);
1570             break;
1571           }
1572         break;
1573       }
1574       case 'f':
1575       {
1576         if (LocaleCompare("family",option+1) == 0)
1577           {
1578             if (*option == '+')
1579               {
1580                 if (draw_info->family != (char *) NULL)
1581                   draw_info->family=DestroyString(draw_info->family);
1582                 break;
1583               }
1584             (void) CloneString(&draw_info->family,argv[i+1]);
1585             break;
1586           }
1587         if (LocaleCompare("features",option+1) == 0)
1588           {
1589             if (*option == '+')
1590               {
1591                 (void) DeleteImageArtifact(*image,"identify:features");
1592                 break;
1593               }
1594             (void) SetImageArtifact(*image,"identify:features",argv[i+1]);
1595             break;
1596           }
1597         if (LocaleCompare("fill",option+1) == 0)
1598           {
1599             ExceptionInfo
1600               *sans;
1601
1602             GetPixelInfo(*image,&fill);
1603             if (*option == '+')
1604               {
1605                 (void) QueryColorCompliance("none",AllCompliance,&fill,
1606                   exception);
1607                 (void) QueryColorCompliance("none",AllCompliance,
1608                   &draw_info->fill,exception);
1609                 if (draw_info->fill_pattern != (Image *) NULL)
1610                   draw_info->fill_pattern=DestroyImage(draw_info->fill_pattern);
1611                 break;
1612               }
1613             sans=AcquireExceptionInfo();
1614             (void) QueryColorCompliance(argv[i+1],AllCompliance,&fill,
1615               sans);
1616             status=QueryColorCompliance(argv[i+1],AllCompliance,
1617               &draw_info->fill,sans);
1618             sans=DestroyExceptionInfo(sans);
1619             if (status == MagickFalse)
1620               draw_info->fill_pattern=GetImageCache(mogrify_info,argv[i+1],
1621                 exception);
1622             break;
1623           }
1624         if (LocaleCompare("flip",option+1) == 0)
1625           {
1626             /*
1627               Flip image scanlines.
1628             */
1629             (void) SyncImageSettings(mogrify_info,*image,exception);
1630             mogrify_image=FlipImage(*image,exception);
1631             break;
1632           }
1633         if (LocaleCompare("floodfill",option+1) == 0)
1634           {
1635             PixelInfo
1636               target;
1637
1638             /*
1639               Floodfill image.
1640             */
1641             (void) SyncImageSettings(mogrify_info,*image,exception);
1642             (void) ParsePageGeometry(*image,argv[i+1],&geometry,exception);
1643             (void) QueryColorCompliance(argv[i+2],AllCompliance,&target,
1644               exception);
1645             (void) FloodfillPaintImage(*image,draw_info,&target,geometry.x,
1646               geometry.y,*option == '-' ? MagickFalse : MagickTrue,exception);
1647             break;
1648           }
1649         if (LocaleCompare("flop",option+1) == 0)
1650           {
1651             /*
1652               Flop image scanlines.
1653             */
1654             (void) SyncImageSettings(mogrify_info,*image,exception);
1655             mogrify_image=FlopImage(*image,exception);
1656             break;
1657           }
1658         if (LocaleCompare("font",option+1) == 0)
1659           {
1660             if (*option == '+')
1661               {
1662                 if (draw_info->font != (char *) NULL)
1663                   draw_info->font=DestroyString(draw_info->font);
1664                 break;
1665               }
1666             (void) CloneString(&draw_info->font,argv[i+1]);
1667             break;
1668           }
1669         if (LocaleCompare("format",option+1) == 0)
1670           {
1671             format=argv[i+1];
1672             break;
1673           }
1674         if (LocaleCompare("frame",option+1) == 0)
1675           {
1676             FrameInfo
1677               frame_info;
1678
1679             /*
1680               Surround image with an ornamental border.
1681             */
1682             (void) SyncImageSettings(mogrify_info,*image,exception);
1683             flags=ParsePageGeometry(*image,argv[i+1],&geometry,exception);
1684             frame_info.width=geometry.width;
1685             frame_info.height=geometry.height;
1686             if ((flags & HeightValue) == 0)
1687               frame_info.height=geometry.width;
1688             frame_info.outer_bevel=geometry.x;
1689             frame_info.inner_bevel=geometry.y;
1690             frame_info.x=(ssize_t) frame_info.width;
1691             frame_info.y=(ssize_t) frame_info.height;
1692             frame_info.width=(*image)->columns+2*frame_info.width;
1693             frame_info.height=(*image)->rows+2*frame_info.height;
1694             mogrify_image=FrameImage(*image,&frame_info,compose,exception);
1695             break;
1696           }
1697         if (LocaleCompare("function",option+1) == 0)
1698           {
1699             char
1700               *arguments,
1701               token[MaxTextExtent];
1702
1703             const char
1704               *p;
1705
1706             double
1707               *parameters;
1708
1709             MagickFunction
1710               function;
1711
1712             register ssize_t
1713               x;
1714
1715             size_t
1716               number_parameters;
1717
1718             /*
1719               Function Modify Image Values
1720             */
1721             (void) SyncImageSettings(mogrify_info,*image,exception);
1722             function=(MagickFunction) ParseCommandOption(MagickFunctionOptions,
1723               MagickFalse,argv[i+1]);
1724             arguments=InterpretImageProperties(mogrify_info,*image,argv[i+2],
1725               exception);
1726             if (arguments == (char *) NULL)
1727               break;
1728             p=(char *) arguments;
1729             for (x=0; *p != '\0'; x++)
1730             {
1731               GetMagickToken(p,&p,token);
1732               if (*token == ',')
1733                 GetMagickToken(p,&p,token);
1734             }
1735             number_parameters=(size_t) x;
1736             parameters=(double *) AcquireQuantumMemory(number_parameters,
1737               sizeof(*parameters));
1738             if (parameters == (double *) NULL)
1739               ThrowWandFatalException(ResourceLimitFatalError,
1740                 "MemoryAllocationFailed",(*image)->filename);
1741             (void) ResetMagickMemory(parameters,0,number_parameters*
1742               sizeof(*parameters));
1743             p=(char *) arguments;
1744             for (x=0; (x < (ssize_t) number_parameters) && (*p != '\0'); x++)
1745             {
1746               GetMagickToken(p,&p,token);
1747               if (*token == ',')
1748                 GetMagickToken(p,&p,token);
1749               parameters[x]=StringToDouble(token,(char **) NULL);
1750             }
1751             arguments=DestroyString(arguments);
1752             (void) FunctionImage(*image,function,number_parameters,parameters,
1753               exception);
1754             parameters=(double *) RelinquishMagickMemory(parameters);
1755             break;
1756           }
1757         break;
1758       }
1759       case 'g':
1760       {
1761         if (LocaleCompare("gamma",option+1) == 0)
1762           {
1763             /*
1764               Gamma image.
1765             */
1766             (void) SyncImageSettings(mogrify_info,*image,exception);
1767             if (*option == '+')
1768               (*image)->gamma=StringToDouble(argv[i+1],(char **) NULL);
1769             else
1770               (void) GammaImage(*image,StringToDouble(argv[i+1],
1771                 (char **) NULL),exception);
1772             break;
1773           }
1774         if ((LocaleCompare("gaussian-blur",option+1) == 0) ||
1775             (LocaleCompare("gaussian",option+1) == 0))
1776           {
1777             /*
1778               Gaussian blur image.
1779             */
1780             (void) SyncImageSettings(mogrify_info,*image,exception);
1781             flags=ParseGeometry(argv[i+1],&geometry_info);
1782             if ((flags & SigmaValue) == 0)
1783               geometry_info.sigma=1.0;
1784             if ((flags & XiValue) == 0)
1785               geometry_info.xi=0.0;
1786             mogrify_image=GaussianBlurImage(*image,geometry_info.rho,
1787               geometry_info.sigma,geometry_info.xi,exception);
1788             break;
1789           }
1790         if (LocaleCompare("geometry",option+1) == 0)
1791           {
1792               /*
1793                 Record Image offset, Resize last image.
1794               */
1795             (void) SyncImageSettings(mogrify_info,*image,exception);
1796             if (*option == '+')
1797               {
1798                 if ((*image)->geometry != (char *) NULL)
1799                   (*image)->geometry=DestroyString((*image)->geometry);
1800                 break;
1801               }
1802             flags=ParseRegionGeometry(*image,argv[i+1],&geometry,exception);
1803             if (((flags & XValue) != 0) || ((flags & YValue) != 0))
1804               (void) CloneString(&(*image)->geometry,argv[i+1]);
1805             else
1806               mogrify_image=ResizeImage(*image,geometry.width,geometry.height,
1807                 (*image)->filter,(*image)->blur,exception);
1808             break;
1809           }
1810         if (LocaleCompare("gravity",option+1) == 0)
1811           {
1812             if (*option == '+')
1813               {
1814                 draw_info->gravity=UndefinedGravity;
1815                 break;
1816               }
1817             draw_info->gravity=(GravityType) ParseCommandOption(
1818               MagickGravityOptions,MagickFalse,argv[i+1]);
1819             break;
1820           }
1821         break;
1822       }
1823       case 'h':
1824       {
1825         if (LocaleCompare("highlight-color",option+1) == 0)
1826           {
1827             (void) SetImageArtifact(*image,option+1,argv[i+1]);
1828             break;
1829           }
1830         break;
1831       }
1832       case 'i':
1833       {
1834         if (LocaleCompare("identify",option+1) == 0)
1835           {
1836             char
1837               *text;
1838
1839             (void) SyncImageSettings(mogrify_info,*image,exception);
1840             if (format == (char *) NULL)
1841               {
1842                 (void) IdentifyImage(*image,stdout,mogrify_info->verbose,
1843                   exception);
1844                 break;
1845               }
1846             text=InterpretImageProperties(mogrify_info,*image,format,
1847               exception);
1848             if (text == (char *) NULL)
1849               break;
1850             (void) fputs(text,stdout);
1851             (void) fputc('\n',stdout);
1852             text=DestroyString(text);
1853             break;
1854           }
1855         if (LocaleCompare("implode",option+1) == 0)
1856           {
1857             /*
1858               Implode image.
1859             */
1860             (void) SyncImageSettings(mogrify_info,*image,exception);
1861             (void) ParseGeometry(argv[i+1],&geometry_info);
1862             mogrify_image=ImplodeImage(*image,geometry_info.rho,
1863               interpolate_method,exception);
1864             break;
1865           }
1866         if (LocaleCompare("interline-spacing",option+1) == 0)
1867           {
1868             if (*option == '+')
1869               (void) ParseGeometry("0",&geometry_info);
1870             else
1871               (void) ParseGeometry(argv[i+1],&geometry_info);
1872             draw_info->interline_spacing=geometry_info.rho;
1873             break;
1874           }
1875         if (LocaleCompare("interpolate",option+1) == 0)
1876           {
1877             interpolate_method=(PixelInterpolateMethod) ParseCommandOption(
1878               MagickInterpolateOptions,MagickFalse,argv[i+1]);
1879             break;
1880           }
1881         if (LocaleCompare("interword-spacing",option+1) == 0)
1882           {
1883             if (*option == '+')
1884               (void) ParseGeometry("0",&geometry_info);
1885             else
1886               (void) ParseGeometry(argv[i+1],&geometry_info);
1887             draw_info->interword_spacing=geometry_info.rho;
1888             break;
1889           }
1890         break;
1891       }
1892       case 'k':
1893       {
1894         if (LocaleCompare("kerning",option+1) == 0)
1895           {
1896             if (*option == '+')
1897               (void) ParseGeometry("0",&geometry_info);
1898             else
1899               (void) ParseGeometry(argv[i+1],&geometry_info);
1900             draw_info->kerning=geometry_info.rho;
1901             break;
1902           }
1903         break;
1904       }
1905       case 'l':
1906       {
1907         if (LocaleCompare("lat",option+1) == 0)
1908           {
1909             /*
1910               Local adaptive threshold image.
1911             */
1912             (void) SyncImageSettings(mogrify_info,*image,exception);
1913             flags=ParseGeometry(argv[i+1],&geometry_info);
1914             if ((flags & PercentValue) != 0)
1915               geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
1916             mogrify_image=AdaptiveThresholdImage(*image,(size_t)
1917               geometry_info.rho,(size_t) geometry_info.sigma,(double)
1918               geometry_info.xi,exception);
1919             break;
1920           }
1921         if (LocaleCompare("level",option+1) == 0)
1922           {
1923             MagickRealType
1924               black_point,
1925               gamma,
1926               white_point;
1927
1928             MagickStatusType
1929               flags;
1930
1931             /*
1932               Parse levels.
1933             */
1934             (void) SyncImageSettings(mogrify_info,*image,exception);
1935             flags=ParseGeometry(argv[i+1],&geometry_info);
1936             black_point=geometry_info.rho;
1937             white_point=(MagickRealType) QuantumRange;
1938             if ((flags & SigmaValue) != 0)
1939               white_point=geometry_info.sigma;
1940             gamma=1.0;
1941             if ((flags & XiValue) != 0)
1942               gamma=geometry_info.xi;
1943             if ((flags & PercentValue) != 0)
1944               {
1945                 black_point*=(MagickRealType) (QuantumRange/100.0);
1946                 white_point*=(MagickRealType) (QuantumRange/100.0);
1947               }
1948             if ((flags & SigmaValue) == 0)
1949               white_point=(MagickRealType) QuantumRange-black_point;
1950             if ((*option == '+') || ((flags & AspectValue) != 0))
1951               (void) LevelizeImage(*image,black_point,white_point,gamma,
1952                 exception);
1953             else
1954               (void) LevelImage(*image,black_point,white_point,gamma,
1955                 exception);
1956             break;
1957           }
1958         if (LocaleCompare("level-colors",option+1) == 0)
1959           {
1960             char
1961               token[MaxTextExtent];
1962
1963             const char
1964               *p;
1965
1966             PixelInfo
1967               black_point,
1968               white_point;
1969
1970             p=(const char *) argv[i+1];
1971             GetMagickToken(p,&p,token);  /* get black point color */
1972             if ((isalpha((int) *token) != 0) || ((*token == '#') != 0))
1973               (void) QueryColorCompliance(token,AllCompliance,
1974                 &black_point,exception);
1975             else
1976               (void) QueryColorCompliance("#000000",AllCompliance,
1977                 &black_point,exception);
1978             if (isalpha((int) token[0]) || (token[0] == '#'))
1979               GetMagickToken(p,&p,token);
1980             if (*token == '\0')
1981               white_point=black_point; /* set everything to that color */
1982             else
1983               {
1984                 if ((isalpha((int) *token) == 0) && ((*token == '#') == 0))
1985                   GetMagickToken(p,&p,token); /* Get white point color. */
1986                 if ((isalpha((int) *token) != 0) || ((*token == '#') != 0))
1987                   (void) QueryColorCompliance(token,AllCompliance,
1988                     &white_point,exception);
1989                 else
1990                   (void) QueryColorCompliance("#ffffff",AllCompliance,
1991                     &white_point,exception);
1992               }
1993             (void) LevelImageColors(*image,&black_point,&white_point,
1994               *option == '+' ? MagickTrue : MagickFalse,exception);
1995             break;
1996           }
1997         if (LocaleCompare("linear-stretch",option+1) == 0)
1998           {
1999             double
2000               black_point,
2001               white_point;
2002
2003             MagickStatusType
2004               flags;
2005
2006             (void) SyncImageSettings(mogrify_info,*image,exception);
2007             flags=ParseGeometry(argv[i+1],&geometry_info);
2008             black_point=geometry_info.rho;
2009             white_point=(MagickRealType) (*image)->columns*(*image)->rows;
2010             if ((flags & SigmaValue) != 0)
2011               white_point=geometry_info.sigma;
2012             if ((flags & PercentValue) != 0)
2013               {
2014                 black_point*=(double) (*image)->columns*(*image)->rows/100.0;
2015                 white_point*=(double) (*image)->columns*(*image)->rows/100.0;
2016               }
2017             if ((flags & SigmaValue) == 0)
2018               white_point=(MagickRealType) (*image)->columns*(*image)->rows-
2019                 black_point;
2020             (void) LinearStretchImage(*image,black_point,white_point,exception);
2021             break;
2022           }
2023         if (LocaleCompare("linewidth",option+1) == 0)
2024           {
2025             draw_info->stroke_width=StringToDouble(argv[i+1],(char **) NULL);
2026             break;
2027           }
2028         if (LocaleCompare("liquid-rescale",option+1) == 0)
2029           {
2030             /*
2031               Liquid rescale image.
2032             */
2033             (void) SyncImageSettings(mogrify_info,*image,exception);
2034             flags=ParseRegionGeometry(*image,argv[i+1],&geometry,exception);
2035             if ((flags & XValue) == 0)
2036               geometry.x=1;
2037             if ((flags & YValue) == 0)
2038               geometry.y=0;
2039             mogrify_image=LiquidRescaleImage(*image,geometry.width,
2040               geometry.height,1.0*geometry.x,1.0*geometry.y,exception);
2041             break;
2042           }
2043         if (LocaleCompare("lowlight-color",option+1) == 0)
2044           {
2045             (void) SetImageArtifact(*image,option+1,argv[i+1]);
2046             break;
2047           }
2048         break;
2049       }
2050       case 'm':
2051       {
2052         if (LocaleCompare("map",option+1) == 0)
2053           {
2054             Image
2055               *remap_image;
2056
2057             /*
2058               Transform image colors to match this set of colors.
2059             */
2060             (void) SyncImageSettings(mogrify_info,*image,exception);
2061             if (*option == '+')
2062               break;
2063             remap_image=GetImageCache(mogrify_info,argv[i+1],exception);
2064             if (remap_image == (Image *) NULL)
2065               break;
2066             (void) RemapImage(quantize_info,*image,remap_image,exception);
2067             remap_image=DestroyImage(remap_image);
2068             break;
2069           }
2070         if (LocaleCompare("mask",option+1) == 0)
2071           {
2072             Image
2073               *mask;
2074
2075             (void) SyncImageSettings(mogrify_info,*image,exception);
2076             if (*option == '+')
2077               {
2078                 /*
2079                   Remove a mask.
2080                 */
2081                 (void) SetImageMask(*image,(Image *) NULL,exception);
2082                 break;
2083               }
2084             /*
2085               Set the image mask.
2086             */
2087             mask=GetImageCache(mogrify_info,argv[i+1],exception);
2088             if (mask == (Image *) NULL)
2089               break;
2090             (void) SetImageMask(*image,mask,exception);
2091             mask=DestroyImage(mask);
2092             break;
2093           }
2094         if (LocaleCompare("matte",option+1) == 0)
2095           {
2096             (void) SetImageAlphaChannel(*image,(*option == '-') ?
2097               SetAlphaChannel : DeactivateAlphaChannel,exception);
2098             break;
2099           }
2100         if (LocaleCompare("median",option+1) == 0)
2101           {
2102             /*
2103               Median filter image.
2104             */
2105             (void) SyncImageSettings(mogrify_info,*image,exception);
2106             flags=ParseGeometry(argv[i+1],&geometry_info);
2107             if ((flags & SigmaValue) == 0)
2108               geometry_info.sigma=geometry_info.rho;
2109             mogrify_image=StatisticImage(*image,MedianStatistic,(size_t)
2110               geometry_info.rho,(size_t) geometry_info.sigma,exception);
2111             break;
2112           }
2113         if (LocaleCompare("mode",option+1) == 0)
2114           {
2115             /*
2116               Mode image.
2117             */
2118             (void) SyncImageSettings(mogrify_info,*image,exception);
2119             flags=ParseGeometry(argv[i+1],&geometry_info);
2120             if ((flags & SigmaValue) == 0)
2121               geometry_info.sigma=geometry_info.rho;
2122             mogrify_image=StatisticImage(*image,ModeStatistic,(size_t)
2123               geometry_info.rho,(size_t) geometry_info.sigma,exception);
2124             break;
2125           }
2126         if (LocaleCompare("modulate",option+1) == 0)
2127           {
2128             (void) SyncImageSettings(mogrify_info,*image,exception);
2129             (void) ModulateImage(*image,argv[i+1],exception);
2130             break;
2131           }
2132         if (LocaleCompare("monitor",option+1) == 0)
2133           {
2134             if (*option == '+')
2135               {
2136                 (void) SetImageProgressMonitor(*image,
2137                   (MagickProgressMonitor) NULL,(void *) NULL);
2138                 break;
2139               }
2140             (void) SetImageProgressMonitor(*image,MonitorProgress,
2141               (void *) NULL);
2142             break;
2143           }
2144         if (LocaleCompare("monochrome",option+1) == 0)
2145           {
2146             (void) SyncImageSettings(mogrify_info,*image,exception);
2147             (void) SetImageType(*image,BilevelType,exception);
2148             break;
2149           }
2150         if (LocaleCompare("morphology",option+1) == 0)
2151           {
2152             char
2153               token[MaxTextExtent];
2154
2155             const char
2156               *p;
2157
2158             KernelInfo
2159               *kernel;
2160
2161             MorphologyMethod
2162               method;
2163
2164             ssize_t
2165               iterations;
2166
2167             /*
2168               Morphological Image Operation
2169             */
2170             (void) SyncImageSettings(mogrify_info,*image,exception);
2171             p=argv[i+1];
2172             GetMagickToken(p,&p,token);
2173             method=(MorphologyMethod) ParseCommandOption(
2174               MagickMorphologyOptions,MagickFalse,token);
2175             iterations=1L;
2176             GetMagickToken(p,&p,token);
2177             if ((*p == ':') || (*p == ','))
2178               GetMagickToken(p,&p,token);
2179             if ((*p != '\0'))
2180               iterations=(ssize_t) StringToLong(p);
2181             kernel=AcquireKernelInfo(argv[i+2]);
2182             if (kernel == (KernelInfo *) NULL)
2183               {
2184                 (void) ThrowMagickException(exception,GetMagickModule(),
2185                   OptionError,"UnabletoParseKernel","morphology");
2186                 status=MagickFalse;
2187                 break;
2188               }
2189             mogrify_image=MorphologyImage(*image,method,iterations,kernel,
2190               exception);
2191             kernel=DestroyKernelInfo(kernel);
2192             break;
2193           }
2194         if (LocaleCompare("motion-blur",option+1) == 0)
2195           {
2196             /*
2197               Motion blur image.
2198             */
2199             (void) SyncImageSettings(mogrify_info,*image,exception);
2200             flags=ParseGeometry(argv[i+1],&geometry_info);
2201             if ((flags & SigmaValue) == 0)
2202               geometry_info.sigma=1.0;
2203             mogrify_image=MotionBlurImage(*image,geometry_info.rho,
2204               geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception);
2205             break;
2206           }
2207         break;
2208       }
2209       case 'n':
2210       {
2211         if (LocaleCompare("negate",option+1) == 0)
2212           {
2213             (void) SyncImageSettings(mogrify_info,*image,exception);
2214             (void) NegateImage(*image,*option == '+' ? MagickTrue :
2215               MagickFalse,exception);
2216             break;
2217           }
2218         if (LocaleCompare("noise",option+1) == 0)
2219           {
2220             (void) SyncImageSettings(mogrify_info,*image,exception);
2221             if (*option == '-')
2222               {
2223                 flags=ParseGeometry(argv[i+1],&geometry_info);
2224                 if ((flags & SigmaValue) == 0)
2225                   geometry_info.sigma=geometry_info.rho;
2226                 mogrify_image=StatisticImage(*image,NonpeakStatistic,(size_t)
2227                   geometry_info.rho,(size_t) geometry_info.sigma,exception);
2228               }
2229             else
2230               {
2231                 NoiseType
2232                   noise;
2233
2234                 noise=(NoiseType) ParseCommandOption(MagickNoiseOptions,
2235                   MagickFalse,argv[i+1]);
2236                 mogrify_image=AddNoiseImage(*image,noise,attenuate,exception);
2237               }
2238             break;
2239           }
2240         if (LocaleCompare("normalize",option+1) == 0)
2241           {
2242             (void) SyncImageSettings(mogrify_info,*image,exception);
2243             (void) NormalizeImage(*image,exception);
2244             break;
2245           }
2246         break;
2247       }
2248       case 'o':
2249       {
2250         if (LocaleCompare("opaque",option+1) == 0)
2251           {
2252             PixelInfo
2253               target;
2254
2255             (void) SyncImageSettings(mogrify_info,*image,exception);
2256             (void) QueryColorCompliance(argv[i+1],AllCompliance,&target,
2257               exception);
2258             (void) OpaquePaintImage(*image,&target,&fill,*option == '-' ?
2259               MagickFalse : MagickTrue,exception);
2260             break;
2261           }
2262         if (LocaleCompare("ordered-dither",option+1) == 0)
2263           {
2264             (void) SyncImageSettings(mogrify_info,*image,exception);
2265             (void) OrderedPosterizeImage(*image,argv[i+1],exception);
2266             break;
2267           }
2268         break;
2269       }
2270       case 'p':
2271       {
2272         if (LocaleCompare("paint",option+1) == 0)
2273           {
2274             (void) SyncImageSettings(mogrify_info,*image,exception);
2275             (void) ParseGeometry(argv[i+1],&geometry_info);
2276             mogrify_image=OilPaintImage(*image,geometry_info.rho,
2277               geometry_info.sigma,exception);
2278             break;
2279           }
2280         if (LocaleCompare("pointsize",option+1) == 0)
2281           {
2282             if (*option == '+')
2283               (void) ParseGeometry("12",&geometry_info);
2284             else
2285               (void) ParseGeometry(argv[i+1],&geometry_info);
2286             draw_info->pointsize=geometry_info.rho;
2287             break;
2288           }
2289         if (LocaleCompare("polaroid",option+1) == 0)
2290           {
2291             const char
2292               *caption;
2293
2294             double
2295               angle;
2296
2297             RandomInfo
2298               *random_info;
2299
2300             /*
2301               Simulate a Polaroid picture.
2302             */
2303             (void) SyncImageSettings(mogrify_info,*image,exception);
2304             random_info=AcquireRandomInfo();
2305             angle=22.5*(GetPseudoRandomValue(random_info)-0.5);
2306             random_info=DestroyRandomInfo(random_info);
2307             if (*option == '-')
2308               {
2309                 SetGeometryInfo(&geometry_info);
2310                 flags=ParseGeometry(argv[i+1],&geometry_info);
2311                 angle=geometry_info.rho;
2312               }
2313             caption=GetImageProperty(*image,"caption",exception);
2314             mogrify_image=PolaroidImage(*image,draw_info,caption,angle,
2315               interpolate_method,exception);
2316             break;
2317           }
2318         if (LocaleCompare("posterize",option+1) == 0)
2319           {
2320             /*
2321               Posterize image.
2322             */
2323             (void) SyncImageSettings(mogrify_info,*image,exception);
2324             (void) PosterizeImage(*image,StringToUnsignedLong(argv[i+1]),
2325               quantize_info->dither,exception);
2326             break;
2327           }
2328         if (LocaleCompare("preview",option+1) == 0)
2329           {
2330             PreviewType
2331               preview_type;
2332
2333             /*
2334               Preview image.
2335             */
2336             (void) SyncImageSettings(mogrify_info,*image,exception);
2337             if (*option == '+')
2338               preview_type=UndefinedPreview;
2339             else
2340               preview_type=(PreviewType) ParseCommandOption(
2341                 MagickPreviewOptions,MagickFalse,argv[i+1]);
2342             mogrify_image=PreviewImage(*image,preview_type,exception);
2343             break;
2344           }
2345         if (LocaleCompare("profile",option+1) == 0)
2346           {
2347             const char
2348               *name;
2349
2350             const StringInfo
2351               *profile;
2352
2353             Image
2354               *profile_image;
2355
2356             ImageInfo
2357               *profile_info;
2358
2359             (void) SyncImageSettings(mogrify_info,*image,exception);
2360             if (*option == '+')
2361               {
2362                 /*
2363                   Remove a profile from the image.
2364                 */
2365                 (void) ProfileImage(*image,argv[i+1],(const unsigned char *)
2366                   NULL,0,exception);
2367                 break;
2368               }
2369             /*
2370               Associate a profile with the image.
2371             */
2372             profile_info=CloneImageInfo(mogrify_info);
2373             profile=GetImageProfile(*image,"iptc");
2374             if (profile != (StringInfo *) NULL)
2375               profile_info->profile=(void *) CloneStringInfo(profile);
2376             profile_image=GetImageCache(profile_info,argv[i+1],exception);
2377             profile_info=DestroyImageInfo(profile_info);
2378             if (profile_image == (Image *) NULL)
2379               {
2380                 StringInfo
2381                   *profile;
2382
2383                 profile_info=CloneImageInfo(mogrify_info);
2384                 (void) CopyMagickString(profile_info->filename,argv[i+1],
2385                   MaxTextExtent);
2386                 profile=FileToStringInfo(profile_info->filename,~0UL,exception);
2387                 if (profile != (StringInfo *) NULL)
2388                   {
2389                     (void) ProfileImage(*image,profile_info->magick,
2390                       GetStringInfoDatum(profile),(size_t)
2391                       GetStringInfoLength(profile),exception);
2392                     profile=DestroyStringInfo(profile);
2393                   }
2394                 profile_info=DestroyImageInfo(profile_info);
2395                 break;
2396               }
2397             ResetImageProfileIterator(profile_image);
2398             name=GetNextImageProfile(profile_image);
2399             while (name != (const char *) NULL)
2400             {
2401               profile=GetImageProfile(profile_image,name);
2402               if (profile != (StringInfo *) NULL)
2403                 (void) ProfileImage(*image,name,GetStringInfoDatum(profile),
2404                   (size_t) GetStringInfoLength(profile),exception);
2405               name=GetNextImageProfile(profile_image);
2406             }
2407             profile_image=DestroyImage(profile_image);
2408             break;
2409           }
2410         break;
2411       }
2412       case 'q':
2413       {
2414         if (LocaleCompare("quantize",option+1) == 0)
2415           {
2416             if (*option == '+')
2417               {
2418                 quantize_info->colorspace=UndefinedColorspace;
2419                 break;
2420               }
2421             quantize_info->colorspace=(ColorspaceType) ParseCommandOption(
2422               MagickColorspaceOptions,MagickFalse,argv[i+1]);
2423             break;
2424           }
2425         break;
2426       }
2427       case 'r':
2428       {
2429         if (LocaleCompare("radial-blur",option+1) == 0)
2430           {
2431             /*
2432               Radial blur image.
2433             */
2434             (void) SyncImageSettings(mogrify_info,*image,exception);
2435             flags=ParseGeometry(argv[i+1],&geometry_info);
2436             mogrify_image=RadialBlurImage(*image,geometry_info.rho,
2437               geometry_info.sigma,exception);
2438             break;
2439           }
2440         if (LocaleCompare("raise",option+1) == 0)
2441           {
2442             /*
2443               Surround image with a raise of solid color.
2444             */
2445             flags=ParsePageGeometry(*image,argv[i+1],&geometry,exception);
2446             if ((flags & SigmaValue) == 0)
2447               geometry.height=geometry.width;
2448             (void) RaiseImage(*image,&geometry,*option == '-' ? MagickTrue :
2449               MagickFalse,exception);
2450             break;
2451           }
2452         if (LocaleCompare("random-threshold",option+1) == 0)
2453           {
2454             /*
2455               Threshold image.
2456             */
2457             (void) SyncImageSettings(mogrify_info,*image,exception);
2458             (void) RandomThresholdImage(*image,argv[i+1],exception);
2459             break;
2460           }
2461         if (LocaleCompare("recolor",option+1) == 0)
2462           {
2463             KernelInfo
2464               *kernel;
2465
2466             (void) SyncImageSettings(mogrify_info,*image,exception);
2467             kernel=AcquireKernelInfo(argv[i+1]);
2468             if (kernel == (KernelInfo *) NULL)
2469               break;
2470             mogrify_image=ColorMatrixImage(*image,kernel,exception);
2471             kernel=DestroyKernelInfo(kernel);
2472             break;
2473           }
2474         if (LocaleCompare("region",option+1) == 0)
2475           {
2476             (void) SyncImageSettings(mogrify_info,*image,exception);
2477             if (region_image != (Image *) NULL)
2478               {
2479                 /*
2480                   Composite region.
2481                 */
2482                 (void) CompositeImage(region_image,region_image->matte !=
2483                    MagickFalse ? CopyCompositeOp : OverCompositeOp,*image,
2484                    region_geometry.x,region_geometry.y,exception);
2485                 *image=DestroyImage(*image);
2486                 *image=region_image;
2487                 region_image = (Image *) NULL;
2488               }
2489             if (*option == '+')
2490               break;
2491             /*
2492               Apply transformations to a selected region of the image.
2493             */
2494             (void) ParseGravityGeometry(*image,argv[i+1],&region_geometry,
2495               exception);
2496             mogrify_image=CropImage(*image,&region_geometry,exception);
2497             if (mogrify_image == (Image *) NULL)
2498               break;
2499             region_image=(*image);
2500             *image=mogrify_image;
2501             mogrify_image=(Image *) NULL;
2502             break;
2503           }
2504         if (LocaleCompare("render",option+1) == 0)
2505           {
2506             (void) SyncImageSettings(mogrify_info,*image,exception);
2507             draw_info->render=(*option == '+') ? MagickTrue : MagickFalse;
2508             break;
2509           }
2510         if (LocaleCompare("remap",option+1) == 0)
2511           {
2512             Image
2513               *remap_image;
2514
2515             /*
2516               Transform image colors to match this set of colors.
2517             */
2518             (void) SyncImageSettings(mogrify_info,*image,exception);
2519             if (*option == '+')
2520               break;
2521             remap_image=GetImageCache(mogrify_info,argv[i+1],exception);
2522             if (remap_image == (Image *) NULL)
2523               break;
2524             (void) RemapImage(quantize_info,*image,remap_image,exception);
2525             remap_image=DestroyImage(remap_image);
2526             break;
2527           }
2528         if (LocaleCompare("repage",option+1) == 0)
2529           {
2530             if (*option == '+')
2531               {
2532                 (void) ParseAbsoluteGeometry("0x0+0+0",&(*image)->page);
2533                 break;
2534               }
2535             (void) ResetImagePage(*image,argv[i+1]);
2536             break;
2537           }
2538         if (LocaleCompare("resample",option+1) == 0)
2539           {
2540             /*
2541               Resample image.
2542             */
2543             (void) SyncImageSettings(mogrify_info,*image,exception);
2544             flags=ParseGeometry(argv[i+1],&geometry_info);
2545             if ((flags & SigmaValue) == 0)
2546               geometry_info.sigma=geometry_info.rho;
2547             mogrify_image=ResampleImage(*image,geometry_info.rho,
2548               geometry_info.sigma,(*image)->filter,(*image)->blur,exception);
2549             break;
2550           }
2551         if (LocaleCompare("resize",option+1) == 0)
2552           {
2553             /*
2554               Resize image.
2555             */
2556             (void) SyncImageSettings(mogrify_info,*image,exception);
2557             (void) ParseRegionGeometry(*image,argv[i+1],&geometry,exception);
2558             mogrify_image=ResizeImage(*image,geometry.width,geometry.height,
2559               (*image)->filter,(*image)->blur,exception);
2560             break;
2561           }
2562         if (LocaleCompare("roll",option+1) == 0)
2563           {
2564             /*
2565               Roll image.
2566             */
2567             (void) SyncImageSettings(mogrify_info,*image,exception);
2568             (void) ParsePageGeometry(*image,argv[i+1],&geometry,exception);
2569             mogrify_image=RollImage(*image,geometry.x,geometry.y,exception);
2570             break;
2571           }
2572         if (LocaleCompare("rotate",option+1) == 0)
2573           {
2574             char
2575               *geometry;
2576
2577             /*
2578               Check for conditional image rotation.
2579             */
2580             (void) SyncImageSettings(mogrify_info,*image,exception);
2581             if (strchr(argv[i+1],'>') != (char *) NULL)
2582               if ((*image)->columns <= (*image)->rows)
2583                 break;
2584             if (strchr(argv[i+1],'<') != (char *) NULL)
2585               if ((*image)->columns >= (*image)->rows)
2586                 break;
2587             /*
2588               Rotate image.
2589             */
2590             geometry=ConstantString(argv[i+1]);
2591             (void) SubstituteString(&geometry,">","");
2592             (void) SubstituteString(&geometry,"<","");
2593             (void) ParseGeometry(geometry,&geometry_info);
2594             geometry=DestroyString(geometry);
2595             mogrify_image=RotateImage(*image,geometry_info.rho,exception);
2596             break;
2597           }
2598         break;
2599       }
2600       case 's':
2601       {
2602         if (LocaleCompare("sample",option+1) == 0)
2603           {
2604             /*
2605               Sample image with pixel replication.
2606             */
2607             (void) SyncImageSettings(mogrify_info,*image,exception);
2608             (void) ParseRegionGeometry(*image,argv[i+1],&geometry,exception);
2609             mogrify_image=SampleImage(*image,geometry.width,geometry.height,
2610               exception);
2611             break;
2612           }
2613         if (LocaleCompare("scale",option+1) == 0)
2614           {
2615             /*
2616               Resize image.
2617             */
2618             (void) SyncImageSettings(mogrify_info,*image,exception);
2619             (void) ParseRegionGeometry(*image,argv[i+1],&geometry,exception);
2620             mogrify_image=ScaleImage(*image,geometry.width,geometry.height,
2621               exception);
2622             break;
2623           }
2624         if (LocaleCompare("selective-blur",option+1) == 0)
2625           {
2626             /*
2627               Selectively blur pixels within a contrast threshold.
2628             */
2629             (void) SyncImageSettings(mogrify_info,*image,exception);
2630             flags=ParseGeometry(argv[i+1],&geometry_info);
2631             if ((flags & PercentValue) != 0)
2632               geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
2633             mogrify_image=SelectiveBlurImage(*image,geometry_info.rho,
2634               geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception);
2635             break;
2636           }
2637         if (LocaleCompare("separate",option+1) == 0)
2638           {
2639             /*
2640               Break channels into separate images.
2641             */
2642             (void) SyncImageSettings(mogrify_info,*image,exception);
2643             mogrify_image=SeparateImages(*image,exception);
2644             break;
2645           }
2646         if (LocaleCompare("sepia-tone",option+1) == 0)
2647           {
2648             double
2649               threshold;
2650
2651             /*
2652               Sepia-tone image.
2653             */
2654             (void) SyncImageSettings(mogrify_info,*image,exception);
2655             threshold=StringToDoubleInterval(argv[i+1],(double) QuantumRange+
2656               1.0);
2657             mogrify_image=SepiaToneImage(*image,threshold,exception);
2658             break;
2659           }
2660         if (LocaleCompare("segment",option+1) == 0)
2661           {
2662             /*
2663               Segment image.
2664             */
2665             (void) SyncImageSettings(mogrify_info,*image,exception);
2666             flags=ParseGeometry(argv[i+1],&geometry_info);
2667             if ((flags & SigmaValue) == 0)
2668               geometry_info.sigma=1.0;
2669             (void) SegmentImage(*image,(*image)->colorspace,
2670               mogrify_info->verbose,geometry_info.rho,geometry_info.sigma,
2671               exception);
2672             break;
2673           }
2674         if (LocaleCompare("set",option+1) == 0)
2675           {
2676             char
2677               *value;
2678
2679             /*
2680               Set image option.
2681             */
2682             if (*option == '+')
2683               {
2684                 if (LocaleNCompare(argv[i+1],"registry:",9) == 0)
2685                   (void) DeleteImageRegistry(argv[i+1]+9);
2686                 else
2687                   if (LocaleNCompare(argv[i+1],"option:",7) == 0)
2688                     {
2689                       (void) DeleteImageOption(mogrify_info,argv[i+1]+7);
2690                       (void) DeleteImageArtifact(*image,argv[i+1]+7);
2691                     }
2692                   else
2693                     (void) DeleteImageProperty(*image,argv[i+1]);
2694                 break;
2695               }
2696             value=InterpretImageProperties(mogrify_info,*image,argv[i+2],
2697               exception);
2698             if (value == (char *) NULL)
2699               break;
2700             if (LocaleNCompare(argv[i+1],"registry:",9) == 0)
2701               (void) SetImageRegistry(StringRegistryType,argv[i+1]+9,value,
2702                 exception);
2703             else
2704               if (LocaleNCompare(argv[i+1],"option:",7) == 0)
2705                 {
2706                   (void) SetImageOption(image_info,argv[i+1]+7,value);
2707                   (void) SetImageOption(mogrify_info,argv[i+1]+7,value);
2708                   (void) SetImageArtifact(*image,argv[i+1]+7,value);
2709                 }
2710               else
2711                 (void) SetImageProperty(*image,argv[i+1],value,exception);
2712             value=DestroyString(value);
2713             break;
2714           }
2715         if (LocaleCompare("shade",option+1) == 0)
2716           {
2717             /*
2718               Shade image.
2719             */
2720             (void) SyncImageSettings(mogrify_info,*image,exception);
2721             flags=ParseGeometry(argv[i+1],&geometry_info);
2722             if ((flags & SigmaValue) == 0)
2723               geometry_info.sigma=1.0;
2724             mogrify_image=ShadeImage(*image,(*option == '-') ? MagickTrue :
2725               MagickFalse,geometry_info.rho,geometry_info.sigma,exception);
2726             break;
2727           }
2728         if (LocaleCompare("shadow",option+1) == 0)
2729           {
2730             /*
2731               Shadow image.
2732             */
2733             (void) SyncImageSettings(mogrify_info,*image,exception);
2734             flags=ParseGeometry(argv[i+1],&geometry_info);
2735             if ((flags & SigmaValue) == 0)
2736               geometry_info.sigma=1.0;
2737             if ((flags & XiValue) == 0)
2738               geometry_info.xi=4.0;
2739             if ((flags & PsiValue) == 0)
2740               geometry_info.psi=4.0;
2741             mogrify_image=ShadowImage(*image,geometry_info.rho,
2742               geometry_info.sigma,(*image)->bias,(ssize_t)
2743               ceil(geometry_info.xi-0.5),(ssize_t) ceil(geometry_info.psi-0.5),
2744               exception);
2745             break;
2746           }
2747         if (LocaleCompare("sharpen",option+1) == 0)
2748           {
2749             /*
2750               Sharpen image.
2751             */
2752             (void) SyncImageSettings(mogrify_info,*image,exception);
2753             flags=ParseGeometry(argv[i+1],&geometry_info);
2754             if ((flags & SigmaValue) == 0)
2755               geometry_info.sigma=1.0;
2756             if ((flags & XiValue) == 0)
2757               geometry_info.xi=0.0;
2758             mogrify_image=SharpenImage(*image,geometry_info.rho,
2759               geometry_info.sigma,geometry_info.xi,exception);
2760             break;
2761           }
2762         if (LocaleCompare("shave",option+1) == 0)
2763           {
2764             /*
2765               Shave the image edges.
2766             */
2767             (void) SyncImageSettings(mogrify_info,*image,exception);
2768             flags=ParsePageGeometry(*image,argv[i+1],&geometry,exception);
2769             mogrify_image=ShaveImage(*image,&geometry,exception);
2770             break;
2771           }
2772         if (LocaleCompare("shear",option+1) == 0)
2773           {
2774             /*
2775               Shear image.
2776             */
2777             (void) SyncImageSettings(mogrify_info,*image,exception);
2778             flags=ParseGeometry(argv[i+1],&geometry_info);
2779             if ((flags & SigmaValue) == 0)
2780               geometry_info.sigma=geometry_info.rho;
2781             mogrify_image=ShearImage(*image,geometry_info.rho,
2782               geometry_info.sigma,exception);
2783             break;
2784           }
2785         if (LocaleCompare("sigmoidal-contrast",option+1) == 0)
2786           {
2787             /*
2788               Sigmoidal non-linearity contrast control.
2789             */
2790             (void) SyncImageSettings(mogrify_info,*image,exception);
2791             flags=ParseGeometry(argv[i+1],&geometry_info);
2792             if ((flags & SigmaValue) == 0)
2793               geometry_info.sigma=(double) QuantumRange/2.0;
2794             if ((flags & PercentValue) != 0)
2795               geometry_info.sigma=(double) QuantumRange*geometry_info.sigma/
2796                 100.0;
2797             (void) SigmoidalContrastImage(*image,(*option == '-') ?
2798               MagickTrue : MagickFalse,geometry_info.rho,geometry_info.sigma,
2799               exception);
2800             break;
2801           }
2802         if (LocaleCompare("sketch",option+1) == 0)
2803           {
2804             /*
2805               Sketch image.
2806             */
2807             (void) SyncImageSettings(mogrify_info,*image,exception);
2808             flags=ParseGeometry(argv[i+1],&geometry_info);
2809             if ((flags & SigmaValue) == 0)
2810               geometry_info.sigma=1.0;
2811             mogrify_image=SketchImage(*image,geometry_info.rho,
2812               geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception);
2813             break;
2814           }
2815         if (LocaleCompare("solarize",option+1) == 0)
2816           {
2817             double
2818               threshold;
2819
2820             (void) SyncImageSettings(mogrify_info,*image,exception);
2821             threshold=StringToDoubleInterval(argv[i+1],(double) QuantumRange+
2822               1.0);
2823             (void) SolarizeImage(*image,threshold,exception);
2824             break;
2825           }
2826         if (LocaleCompare("sparse-color",option+1) == 0)
2827           {
2828             SparseColorMethod
2829               method;
2830
2831             char
2832               *arguments;
2833
2834             /*
2835               Sparse Color Interpolated Gradient
2836             */
2837             (void) SyncImageSettings(mogrify_info,*image,exception);
2838             method=(SparseColorMethod) ParseCommandOption(
2839               MagickSparseColorOptions,MagickFalse,argv[i+1]);
2840             arguments=InterpretImageProperties(mogrify_info,*image,argv[i+2],
2841               exception);
2842             if (arguments == (char *) NULL)
2843               break;
2844             mogrify_image=SparseColorOption(*image,method,arguments,
2845               option[0] == '+' ? MagickTrue : MagickFalse,exception);
2846             arguments=DestroyString(arguments);
2847             break;
2848           }
2849         if (LocaleCompare("splice",option+1) == 0)
2850           {
2851             /*
2852               Splice a solid color into the image.
2853             */
2854             (void) SyncImageSettings(mogrify_info,*image,exception);
2855             (void) ParseGravityGeometry(*image,argv[i+1],&geometry,exception);
2856             mogrify_image=SpliceImage(*image,&geometry,exception);
2857             break;
2858           }
2859         if (LocaleCompare("spread",option+1) == 0)
2860           {
2861             /*
2862               Spread an image.
2863             */
2864             (void) SyncImageSettings(mogrify_info,*image,exception);
2865             (void) ParseGeometry(argv[i+1],&geometry_info);
2866             mogrify_image=SpreadImage(*image,geometry_info.rho,
2867               interpolate_method,exception);
2868             break;
2869           }
2870         if (LocaleCompare("statistic",option+1) == 0)
2871           {
2872             StatisticType
2873               type;
2874
2875             (void) SyncImageSettings(mogrify_info,*image,exception);
2876             type=(StatisticType) ParseCommandOption(MagickStatisticOptions,
2877               MagickFalse,argv[i+1]);
2878             (void) ParseGeometry(argv[i+2],&geometry_info);
2879             mogrify_image=StatisticImage(*image,type,(size_t) geometry_info.rho,
2880               (size_t) geometry_info.sigma,exception);
2881             break;
2882           }
2883         if (LocaleCompare("stretch",option+1) == 0)
2884           {
2885             if (*option == '+')
2886               {
2887                 draw_info->stretch=UndefinedStretch;
2888                 break;
2889               }
2890             draw_info->stretch=(StretchType) ParseCommandOption(
2891               MagickStretchOptions,MagickFalse,argv[i+1]);
2892             break;
2893           }
2894         if (LocaleCompare("strip",option+1) == 0)
2895           {
2896             /*
2897               Strip image of profiles and comments.
2898             */
2899             (void) SyncImageSettings(mogrify_info,*image,exception);
2900             (void) StripImage(*image,exception);
2901             break;
2902           }
2903         if (LocaleCompare("stroke",option+1) == 0)
2904           {
2905             ExceptionInfo
2906               *sans;
2907
2908             if (*option == '+')
2909               {
2910                 (void) QueryColorCompliance("none",AllCompliance,
2911                   &draw_info->stroke,exception);
2912                 if (draw_info->stroke_pattern != (Image *) NULL)
2913                   draw_info->stroke_pattern=DestroyImage(
2914                     draw_info->stroke_pattern);
2915                 break;
2916               }
2917             sans=AcquireExceptionInfo();
2918             status=QueryColorCompliance(argv[i+1],AllCompliance,
2919               &draw_info->stroke,sans);
2920             sans=DestroyExceptionInfo(sans);
2921             if (status == MagickFalse)
2922               draw_info->stroke_pattern=GetImageCache(mogrify_info,argv[i+1],
2923                 exception);
2924             break;
2925           }
2926         if (LocaleCompare("strokewidth",option+1) == 0)
2927           {
2928             draw_info->stroke_width=StringToDouble(argv[i+1],(char **) NULL);
2929             break;
2930           }
2931         if (LocaleCompare("style",option+1) == 0)
2932           {
2933             if (*option == '+')
2934               {
2935                 draw_info->style=UndefinedStyle;
2936                 break;
2937               }
2938             draw_info->style=(StyleType) ParseCommandOption(MagickStyleOptions,
2939               MagickFalse,argv[i+1]);
2940             break;
2941           }
2942         if (LocaleCompare("swirl",option+1) == 0)
2943           {
2944             /*
2945               Swirl image.
2946             */
2947             (void) SyncImageSettings(mogrify_info,*image,exception);
2948             (void) ParseGeometry(argv[i+1],&geometry_info);
2949             mogrify_image=SwirlImage(*image,geometry_info.rho,
2950               interpolate_method,exception);
2951             break;
2952           }
2953         break;
2954       }
2955       case 't':
2956       {
2957         if (LocaleCompare("threshold",option+1) == 0)
2958           {
2959             double
2960               threshold;
2961
2962             /*
2963               Threshold image.
2964             */
2965             (void) SyncImageSettings(mogrify_info,*image,exception);
2966             if (*option == '+')
2967               threshold=(double) QuantumRange/2;
2968             else
2969               threshold=StringToDoubleInterval(argv[i+1],(double) QuantumRange+
2970                 1.0);
2971             (void) BilevelImage(*image,threshold,exception);
2972             break;
2973           }
2974         if (LocaleCompare("thumbnail",option+1) == 0)
2975           {
2976             /*
2977               Thumbnail image.
2978             */
2979             (void) SyncImageSettings(mogrify_info,*image,exception);
2980             (void) ParseRegionGeometry(*image,argv[i+1],&geometry,exception);
2981             mogrify_image=ThumbnailImage(*image,geometry.width,geometry.height,
2982               exception);
2983             break;
2984           }
2985         if (LocaleCompare("tile",option+1) == 0)
2986           {
2987             if (*option == '+')
2988               {
2989                 if (draw_info->fill_pattern != (Image *) NULL)
2990                   draw_info->fill_pattern=DestroyImage(draw_info->fill_pattern);
2991                 break;
2992               }
2993             draw_info->fill_pattern=GetImageCache(mogrify_info,argv[i+1],
2994               exception);
2995             break;
2996           }
2997         if (LocaleCompare("tint",option+1) == 0)
2998           {
2999             /*
3000               Tint the image.
3001             */
3002             (void) SyncImageSettings(mogrify_info,*image,exception);
3003             mogrify_image=TintImage(*image,argv[i+1],&fill,exception);
3004             break;
3005           }
3006         if (LocaleCompare("transform",option+1) == 0)
3007           {
3008             /*
3009               Affine transform image.
3010             */
3011             (void) SyncImageSettings(mogrify_info,*image,exception);
3012             mogrify_image=AffineTransformImage(*image,&draw_info->affine,
3013               exception);
3014             break;
3015           }
3016         if (LocaleCompare("transparent",option+1) == 0)
3017           {
3018             PixelInfo
3019               target;
3020
3021             (void) SyncImageSettings(mogrify_info,*image,exception);
3022             (void) QueryColorCompliance(argv[i+1],AllCompliance,&target,
3023               exception);
3024             (void) TransparentPaintImage(*image,&target,(Quantum)
3025               TransparentAlpha,*option == '-' ? MagickFalse : MagickTrue,
3026               exception);
3027             break;
3028           }
3029         if (LocaleCompare("transpose",option+1) == 0)
3030           {
3031             /*
3032               Transpose image scanlines.
3033             */
3034             (void) SyncImageSettings(mogrify_info,*image,exception);
3035             mogrify_image=TransposeImage(*image,exception);
3036             break;
3037           }
3038         if (LocaleCompare("transverse",option+1) == 0)
3039           {
3040             /*
3041               Transverse image scanlines.
3042             */
3043             (void) SyncImageSettings(mogrify_info,*image,exception);
3044             mogrify_image=TransverseImage(*image,exception);
3045             break;
3046           }
3047         if (LocaleCompare("treedepth",option+1) == 0)
3048           {
3049             quantize_info->tree_depth=StringToUnsignedLong(argv[i+1]);
3050             break;
3051           }
3052         if (LocaleCompare("trim",option+1) == 0)
3053           {
3054             /*
3055               Trim image.
3056             */
3057             (void) SyncImageSettings(mogrify_info,*image,exception);
3058             mogrify_image=TrimImage(*image,exception);
3059             break;
3060           }
3061         if (LocaleCompare("type",option+1) == 0)
3062           {
3063             ImageType
3064               type;
3065
3066             (void) SyncImageSettings(mogrify_info,*image,exception);
3067             if (*option == '+')
3068               type=UndefinedType;
3069             else
3070               type=(ImageType) ParseCommandOption(MagickTypeOptions,MagickFalse,
3071                 argv[i+1]);
3072             (*image)->type=UndefinedType;
3073             (void) SetImageType(*image,type,exception);
3074             break;
3075           }
3076         break;
3077       }
3078       case 'u':
3079       {
3080         if (LocaleCompare("undercolor",option+1) == 0)
3081           {
3082             (void) QueryColorCompliance(argv[i+1],AllCompliance,
3083               &draw_info->undercolor,exception);
3084             break;
3085           }
3086         if (LocaleCompare("unique",option+1) == 0)
3087           {
3088             if (*option == '+')
3089               {
3090                 (void) DeleteImageArtifact(*image,"identify:unique-colors");
3091                 break;
3092               }
3093             (void) SetImageArtifact(*image,"identify:unique-colors","true");
3094             (void) SetImageArtifact(*image,"verbose","true");
3095             break;
3096           }
3097         if (LocaleCompare("unique-colors",option+1) == 0)
3098           {
3099             /*
3100               Unique image colors.
3101             */
3102             (void) SyncImageSettings(mogrify_info,*image,exception);
3103             mogrify_image=UniqueImageColors(*image,exception);
3104             break;
3105           }
3106         if (LocaleCompare("unsharp",option+1) == 0)
3107           {
3108             /*
3109               Unsharp mask image.
3110             */
3111             (void) SyncImageSettings(mogrify_info,*image,exception);
3112             flags=ParseGeometry(argv[i+1],&geometry_info);
3113             if ((flags & SigmaValue) == 0)
3114               geometry_info.sigma=1.0;
3115             if ((flags & XiValue) == 0)
3116               geometry_info.xi=1.0;
3117             if ((flags & PsiValue) == 0)
3118               geometry_info.psi=0.05;
3119             mogrify_image=UnsharpMaskImage(*image,geometry_info.rho,
3120               geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception);
3121             break;
3122           }
3123         break;
3124       }
3125       case 'v':
3126       {
3127         if (LocaleCompare("verbose",option+1) == 0)
3128           {
3129             (void) SetImageArtifact(*image,option+1,
3130               *option == '+' ? "false" : "true");
3131             break;
3132           }
3133         if (LocaleCompare("vignette",option+1) == 0)
3134           {
3135             /*
3136               Vignette image.
3137             */
3138             (void) SyncImageSettings(mogrify_info,*image,exception);
3139             flags=ParseGeometry(argv[i+1],&geometry_info);
3140             if ((flags & SigmaValue) == 0)
3141               geometry_info.sigma=1.0;
3142             if ((flags & XiValue) == 0)
3143               geometry_info.xi=0.1*(*image)->columns;
3144             if ((flags & PsiValue) == 0)
3145               geometry_info.psi=0.1*(*image)->rows;
3146             mogrify_image=VignetteImage(*image,geometry_info.rho,
3147               geometry_info.sigma,(*image)->bias,(ssize_t)
3148               ceil(geometry_info.xi-0.5),(ssize_t) ceil(geometry_info.psi-0.5),
3149               exception);
3150             break;
3151           }
3152         if (LocaleCompare("virtual-pixel",option+1) == 0)
3153           {
3154             if (*option == '+')
3155               {
3156                 (void) SetImageVirtualPixelMethod(*image,
3157                   UndefinedVirtualPixelMethod);
3158                 break;
3159               }
3160             (void) SetImageVirtualPixelMethod(*image,(VirtualPixelMethod)
3161               ParseCommandOption(MagickVirtualPixelOptions,MagickFalse,
3162               argv[i+1]));
3163             break;
3164           }
3165         break;
3166       }
3167       case 'w':
3168       {
3169         if (LocaleCompare("wave",option+1) == 0)
3170           {
3171             /*
3172               Wave image.
3173             */
3174             (void) SyncImageSettings(mogrify_info,*image,exception);
3175             flags=ParseGeometry(argv[i+1],&geometry_info);
3176             if ((flags & SigmaValue) == 0)
3177               geometry_info.sigma=1.0;
3178             mogrify_image=WaveImage(*image,geometry_info.rho,
3179               geometry_info.sigma,interpolate_method,exception);
3180             break;
3181           }
3182         if (LocaleCompare("weight",option+1) == 0)
3183           {
3184             draw_info->weight=StringToUnsignedLong(argv[i+1]);
3185             if (LocaleCompare(argv[i+1],"all") == 0)
3186               draw_info->weight=0;
3187             if (LocaleCompare(argv[i+1],"bold") == 0)
3188               draw_info->weight=700;
3189             if (LocaleCompare(argv[i+1],"bolder") == 0)
3190               if (draw_info->weight <= 800)
3191                 draw_info->weight+=100;
3192             if (LocaleCompare(argv[i+1],"lighter") == 0)
3193               if (draw_info->weight >= 100)
3194                 draw_info->weight-=100;
3195             if (LocaleCompare(argv[i+1],"normal") == 0)
3196               draw_info->weight=400;
3197             break;
3198           }
3199         if (LocaleCompare("white-threshold",option+1) == 0)
3200           {
3201             /*
3202               White threshold image.
3203             */
3204             (void) SyncImageSettings(mogrify_info,*image,exception);
3205             (void) WhiteThresholdImage(*image,argv[i+1],exception);
3206             break;
3207           }
3208         break;
3209       }
3210       default:
3211         break;
3212     }
3213     /*
3214        Replace current image with any image that was generated
3215     */
3216     if (mogrify_image != (Image *) NULL)
3217       ReplaceImageInListReturnLast(image,mogrify_image);
3218     i+=count;
3219   }
3220   if (region_image != (Image *) NULL)
3221     {
3222       /*
3223         Composite transformed region onto image.
3224       */
3225       (void) SyncImageSettings(mogrify_info,*image,exception);
3226       (void) CompositeImage(region_image,region_image->matte !=
3227          MagickFalse ? CopyCompositeOp : OverCompositeOp,*image,
3228          region_geometry.x,region_geometry.y,exception);
3229       *image=DestroyImage(*image);
3230       *image=region_image;
3231       region_image = (Image *) NULL;
3232     }
3233   /*
3234     Free resources.
3235   */
3236   quantize_info=DestroyQuantizeInfo(quantize_info);
3237   draw_info=DestroyDrawInfo(draw_info);
3238   mogrify_info=DestroyImageInfo(mogrify_info);
3239   status=(MagickStatusType) (exception->severity == UndefinedException ? 1 : 0);
3240   return(status == 0 ? MagickFalse : MagickTrue);
3241 }
3242 \f
3243 /*
3244 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3245 %                                                                             %
3246 %                                                                             %
3247 %                                                                             %
3248 +    M o g r i f y I m a g e C o m m a n d                                    %
3249 %                                                                             %
3250 %                                                                             %
3251 %                                                                             %
3252 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3253 %
3254 %  MogrifyImageCommand() transforms an image or a sequence of images. These
3255 %  transforms include image scaling, image rotation, color reduction, and
3256 %  others. The transmogrified image overwrites the original image.
3257 %
3258 %  The format of the MogrifyImageCommand method is:
3259 %
3260 %      MagickBooleanType MogrifyImageCommand(ImageInfo *image_info,int argc,
3261 %        const char **argv,char **metadata,ExceptionInfo *exception)
3262 %
3263 %  A description of each parameter follows:
3264 %
3265 %    o image_info: the image info.
3266 %
3267 %    o argc: the number of elements in the argument vector.
3268 %
3269 %    o argv: A text array containing the command line arguments.
3270 %
3271 %    o metadata: any metadata is returned here.
3272 %
3273 %    o exception: return any errors or warnings in this structure.
3274 %
3275 */
3276
3277 static MagickBooleanType MogrifyUsage(void)
3278 {
3279   static const char
3280     *miscellaneous[]=
3281     {
3282       "-debug events        display copious debugging information",
3283       "-help                print program options",
3284       "-list type           print a list of supported option arguments",
3285       "-log format          format of debugging information",
3286       "-version             print version information",
3287       (char *) NULL
3288     },
3289     *operators[]=
3290     {
3291       "-adaptive-blur geometry",
3292       "                     adaptively blur pixels; decrease effect near edges",
3293       "-adaptive-resize geometry",
3294       "                     adaptively resize image using 'mesh' interpolation",
3295       "-adaptive-sharpen geometry",
3296       "                     adaptively sharpen pixels; increase effect near edges",
3297       "-alpha option        on, activate, off, deactivate, set, opaque, copy",
3298       "                     transparent, extract, background, or shape",
3299       "-annotate geometry text",
3300       "                     annotate the image with text",
3301       "-auto-gamma          automagically adjust gamma level of image",
3302       "-auto-level          automagically adjust color levels of image",
3303       "-auto-orient         automagically orient (rotate) image",
3304       "-bench iterations    measure performance",
3305       "-black-threshold value",
3306       "                     force all pixels below the threshold into black",
3307       "-blue-shift          simulate a scene at nighttime in the moonlight",
3308       "-blur geometry       reduce image noise and reduce detail levels",
3309       "-border geometry     surround image with a border of color",
3310       "-bordercolor color   border color",
3311       "-brightness-contrast geometry",
3312       "                     improve brightness / contrast of the image",
3313       "-cdl filename        color correct with a color decision list",
3314       "-charcoal geometry   simulate a charcoal drawing",
3315       "-chop geometry       remove pixels from the image interior",
3316       "-clamp               restrict pixel range from 0 to the quantum depth",
3317       "-clip                clip along the first path from the 8BIM profile",
3318       "-clip-mask filename  associate a clip mask with the image",
3319       "-clip-path id        clip along a named path from the 8BIM profile",
3320       "-colorize value      colorize the image with the fill color",
3321       "-color-matrix matrix apply color correction to the image",
3322       "-contrast            enhance or reduce the image contrast",
3323       "-contrast-stretch geometry",
3324       "                     improve contrast by `stretching' the intensity range",
3325       "-convolve coefficients",
3326       "                     apply a convolution kernel to the image",
3327       "-cycle amount        cycle the image colormap",
3328       "-decipher filename   convert cipher pixels to plain pixels",
3329       "-deskew threshold    straighten an image",
3330       "-despeckle           reduce the speckles within an image",
3331       "-distort method args",
3332       "                     distort images according to given method ad args",
3333       "-draw string         annotate the image with a graphic primitive",
3334       "-edge radius         apply a filter to detect edges in the image",
3335       "-encipher filename   convert plain pixels to cipher pixels",
3336       "-emboss radius       emboss an image",
3337       "-enhance             apply a digital filter to enhance a noisy image",
3338       "-equalize            perform histogram equalization to an image",
3339       "-evaluate operator value",
3340       "                     evaluate an arithmetic, relational, or logical expression",
3341       "-extent geometry     set the image size",
3342       "-extract geometry    extract area from image",
3343       "-fft                 implements the discrete Fourier transform (DFT)",
3344       "-flip                flip image vertically",
3345       "-floodfill geometry color",
3346       "                     floodfill the image with color",
3347       "-flop                flop image horizontally",
3348       "-frame geometry      surround image with an ornamental border",
3349       "-function name parameters",
3350       "                     apply function over image values",
3351       "-gamma value         level of gamma correction",
3352       "-gaussian-blur geometry",
3353       "                     reduce image noise and reduce detail levels",
3354       "-geometry geometry   preferred size or location of the image",
3355       "-identify            identify the format and characteristics of the image",
3356       "-ift                 implements the inverse discrete Fourier transform (DFT)",
3357       "-implode amount      implode image pixels about the center",
3358       "-lat geometry        local adaptive thresholding",
3359       "-layers method       optimize, merge,  or compare image layers",
3360       "-level value         adjust the level of image contrast",
3361       "-level-colors color,color",
3362       "                     level image with the given colors",
3363       "-linear-stretch geometry",
3364       "                     improve contrast by `stretching with saturation'",
3365       "-liquid-rescale geometry",
3366       "                     rescale image with seam-carving",
3367       "-median geometry     apply a median filter to the image",
3368       "-mode geometry       make each pixel the 'predominant color' of the neighborhood",
3369       "-modulate value      vary the brightness, saturation, and hue",
3370       "-monochrome          transform image to black and white",
3371       "-morphology method kernel",
3372       "                     apply a morphology method to the image",
3373       "-motion-blur geometry",
3374       "                     simulate motion blur",
3375       "-negate              replace every pixel with its complementary color ",
3376       "-noise geometry      add or reduce noise in an image",
3377       "-normalize           transform image to span the full range of colors",
3378       "-opaque color        change this color to the fill color",
3379       "-ordered-dither NxN",
3380       "                     add a noise pattern to the image with specific",
3381       "                     amplitudes",
3382       "-paint radius        simulate an oil painting",
3383       "-polaroid angle      simulate a Polaroid picture",
3384       "-posterize levels    reduce the image to a limited number of color levels",
3385       "-profile filename    add, delete, or apply an image profile",
3386       "-quantize colorspace reduce colors in this colorspace",
3387       "-radial-blur angle   radial blur the image",
3388       "-raise value         lighten/darken image edges to create a 3-D effect",
3389       "-random-threshold low,high",
3390       "                     random threshold the image",
3391       "-region geometry     apply options to a portion of the image",
3392       "-render              render vector graphics",
3393       "-repage geometry     size and location of an image canvas",
3394       "-resample geometry   change the resolution of an image",
3395       "-resize geometry     resize the image",
3396       "-roll geometry       roll an image vertically or horizontally",
3397       "-rotate degrees      apply Paeth rotation to the image",
3398       "-sample geometry     scale image with pixel sampling",
3399       "-scale geometry      scale the image",
3400       "-segment values      segment an image",
3401       "-selective-blur geometry",
3402       "                     selectively blur pixels within a contrast threshold",
3403       "-sepia-tone threshold",
3404       "                     simulate a sepia-toned photo",
3405       "-set property value  set an image property",
3406       "-shade degrees       shade the image using a distant light source",
3407       "-shadow geometry     simulate an image shadow",
3408       "-sharpen geometry    sharpen the image",
3409       "-shave geometry      shave pixels from the image edges",
3410       "-shear geometry      slide one edge of the image along the X or Y axis",
3411       "-sigmoidal-contrast geometry",
3412       "                     increase the contrast without saturating highlights or shadows",
3413       "-sketch geometry     simulate a pencil sketch",
3414       "-solarize threshold  negate all pixels above the threshold level",
3415       "-sparse-color method args",
3416       "                     fill in a image based on a few color points",
3417       "-splice geometry     splice the background color into the image",
3418       "-spread radius       displace image pixels by a random amount",
3419       "-statistic type radius",
3420       "                     replace each pixel with corresponding statistic from the neighborhood",
3421       "-strip               strip image of all profiles and comments",
3422       "-swirl degrees       swirl image pixels about the center",
3423       "-threshold value     threshold the image",
3424       "-thumbnail geometry  create a thumbnail of the image",
3425       "-tile filename       tile image when filling a graphic primitive",
3426       "-tint value          tint the image with the fill color",
3427       "-transform           affine transform image",
3428       "-transparent color   make this color transparent within the image",
3429       "-transpose           flip image vertically and rotate 90 degrees",
3430       "-transverse          flop image horizontally and rotate 270 degrees",
3431       "-trim                trim image edges",
3432       "-type type           image type",
3433       "-unique-colors       discard all but one of any pixel color",
3434       "-unsharp geometry    sharpen the image",
3435       "-vignette geometry   soften the edges of the image in vignette style",
3436       "-wave geometry       alter an image along a sine wave",
3437       "-white-threshold value",
3438       "                     force all pixels above the threshold into white",
3439       (char *) NULL
3440     },
3441     *sequence_operators[]=
3442     {
3443       "-append              append an image sequence",
3444       "-clut                apply a color lookup table to the image",
3445       "-coalesce            merge a sequence of images",
3446       "-combine             combine a sequence of images",
3447       "-composite           composite image",
3448       "-crop geometry       cut out a rectangular region of the image",
3449       "-deconstruct         break down an image sequence into constituent parts",
3450       "-evaluate-sequence operator",
3451       "                     evaluate an arithmetic, relational, or logical expression",
3452       "-flatten             flatten a sequence of images",
3453       "-fx expression       apply mathematical expression to an image channel(s)",
3454       "-hald-clut           apply a Hald color lookup table to the image",
3455       "-morph value         morph an image sequence",
3456       "-mosaic              create a mosaic from an image sequence",
3457       "-print string        interpret string and print to console",
3458       "-process arguments   process the image with a custom image filter",
3459       "-separate            separate an image channel into a grayscale image",
3460       "-smush geometry      smush an image sequence together",
3461       "-write filename      write images to this file",
3462       (char *) NULL
3463     },
3464     *settings[]=
3465     {
3466       "-adjoin              join images into a single multi-image file",
3467       "-affine matrix       affine transform matrix",
3468       "-alpha option        activate, deactivate, reset, or set the alpha channel",
3469       "-antialias           remove pixel-aliasing",
3470       "-authenticate password",
3471       "                     decipher image with this password",
3472       "-attenuate value     lessen (or intensify) when adding noise to an image",
3473       "-background color    background color",
3474       "-bias value          add bias when convolving an image",
3475       "-black-point-compensation",
3476       "                     use black point compensation",
3477       "-blue-primary point  chromaticity blue primary point",
3478       "-bordercolor color   border color",
3479       "-caption string      assign a caption to an image",
3480       "-channel type        apply option to select image channels",
3481       "-colors value        preferred number of colors in the image",
3482       "-colorspace type     alternate image colorspace",
3483       "-comment string      annotate image with comment",
3484       "-compose operator    set image composite operator",
3485       "-compress type       type of pixel compression when writing the image",
3486       "-define format:option",
3487       "                     define one or more image format options",
3488       "-delay value         display the next image after pausing",
3489       "-density geometry    horizontal and vertical density of the image",
3490       "-depth value         image depth",
3491       "-direction type      render text right-to-left or left-to-right",
3492       "-display server      get image or font from this X server",
3493       "-dispose method      layer disposal method",
3494       "-dither method       apply error diffusion to image",
3495       "-encoding type       text encoding type",
3496       "-endian type         endianness (MSB or LSB) of the image",
3497       "-family name         render text with this font family",
3498       "-fill color          color to use when filling a graphic primitive",
3499       "-filter type         use this filter when resizing an image",
3500       "-font name           render text with this font",
3501       "-format \"string\"     output formatted image characteristics",
3502       "-fuzz distance       colors within this distance are considered equal",
3503       "-gravity type        horizontal and vertical text placement",
3504       "-green-primary point chromaticity green primary point",
3505       "-intent type         type of rendering intent when managing the image color",
3506       "-interlace type      type of image interlacing scheme",
3507       "-interline-spacing value",
3508       "                     set the space between two text lines",
3509       "-interpolate method  pixel color interpolation method",
3510       "-interword-spacing value",
3511       "                     set the space between two words",
3512       "-kerning value       set the space between two letters",
3513       "-label string        assign a label to an image",
3514       "-limit type value    pixel cache resource limit",
3515       "-loop iterations     add Netscape loop extension to your GIF animation",
3516       "-mask filename       associate a mask with the image",
3517       "-mattecolor color    frame color",
3518       "-monitor             monitor progress",
3519       "-orient type         image orientation",
3520       "-page geometry       size and location of an image canvas (setting)",
3521       "-ping                efficiently determine image attributes",
3522       "-pointsize value     font point size",
3523       "-precision value     maximum number of significant digits to print",
3524       "-preview type        image preview type",
3525       "-quality value       JPEG/MIFF/PNG compression level",
3526       "-quiet               suppress all warning messages",
3527       "-red-primary point   chromaticity red primary point",
3528       "-regard-warnings     pay attention to warning messages",
3529       "-remap filename      transform image colors to match this set of colors",
3530       "-respect-parentheses settings remain in effect until parenthesis boundary",
3531       "-sampling-factor geometry",
3532       "                     horizontal and vertical sampling factor",
3533       "-scene value         image scene number",
3534       "-seed value          seed a new sequence of pseudo-random numbers",
3535       "-size geometry       width and height of image",
3536       "-stretch type        render text with this font stretch",
3537       "-stroke color        graphic primitive stroke color",
3538       "-strokewidth value   graphic primitive stroke width",
3539       "-style type          render text with this font style",
3540       "-synchronize         synchronize image to storage device",
3541       "-taint               declare the image as modified",
3542       "-texture filename    name of texture to tile onto the image background",
3543       "-tile-offset geometry",
3544       "                     tile offset",
3545       "-treedepth value     color tree depth",
3546       "-transparent-color color",
3547       "                     transparent color",
3548       "-undercolor color    annotation bounding box color",
3549       "-units type          the units of image resolution",
3550       "-verbose             print detailed information about the image",
3551       "-view                FlashPix viewing transforms",
3552       "-virtual-pixel method",
3553       "                     virtual pixel access method",
3554       "-weight type         render text with this font weight",
3555       "-white-point point   chromaticity white point",
3556       (char *) NULL
3557     },
3558     *stack_operators[]=
3559     {
3560       "-delete indexes      delete the image from the image sequence",
3561       "-duplicate count,indexes",
3562       "                     duplicate an image one or more times",
3563       "-insert index        insert last image into the image sequence",
3564       "-reverse             reverse image sequence",
3565       "-swap indexes        swap two images in the image sequence",
3566       (char *) NULL
3567     };
3568
3569   const char
3570     **p;
3571
3572   (void) printf("Version: %s\n",GetMagickVersion((size_t *) NULL));
3573   (void) printf("Copyright: %s\n",GetMagickCopyright());
3574   (void) printf("Features: %s\n\n",GetMagickFeatures());
3575   (void) printf("Usage: %s [options ...] file [ [options ...] file ...]\n",
3576     GetClientName());
3577   (void) printf("\nImage Settings:\n");
3578   for (p=settings; *p != (char *) NULL; p++)
3579     (void) printf("  %s\n",*p);
3580   (void) printf("\nImage Operators:\n");
3581   for (p=operators; *p != (char *) NULL; p++)
3582     (void) printf("  %s\n",*p);
3583   (void) printf("\nImage Sequence Operators:\n");
3584   for (p=sequence_operators; *p != (char *) NULL; p++)
3585     (void) printf("  %s\n",*p);
3586   (void) printf("\nImage Stack Operators:\n");
3587   for (p=stack_operators; *p != (char *) NULL; p++)
3588     (void) printf("  %s\n",*p);
3589   (void) printf("\nMiscellaneous Options:\n");
3590   for (p=miscellaneous; *p != (char *) NULL; p++)
3591     (void) printf("  %s\n",*p);
3592   (void) printf(
3593     "\nBy default, the image format of `file' is determined by its magic\n");
3594   (void) printf(
3595     "number.  To specify a particular image format, precede the filename\n");
3596   (void) printf(
3597     "with an image format name and a colon (i.e. ps:image) or specify the\n");
3598   (void) printf(
3599     "image type as the filename suffix (i.e. image.ps).  Specify 'file' as\n");
3600   (void) printf("'-' for standard input or output.\n");
3601   return(MagickFalse);
3602 }
3603
3604 WandExport MagickBooleanType MogrifyImageCommand(ImageInfo *image_info,
3605   int argc,char **argv,char **wand_unused(metadata),ExceptionInfo *exception)
3606 {
3607 #define DestroyMogrify() \
3608 { \
3609   if (format != (char *) NULL) \
3610     format=DestroyString(format); \
3611   if (path != (char *) NULL) \
3612     path=DestroyString(path); \
3613   DestroyImageStack(); \
3614   for (i=0; i < (ssize_t) argc; i++) \
3615     argv[i]=DestroyString(argv[i]); \
3616   argv=(char **) RelinquishMagickMemory(argv); \
3617 }
3618 #define ThrowMogrifyException(asperity,tag,option) \
3619 { \
3620   (void) ThrowMagickException(exception,GetMagickModule(),asperity,tag,"`%s'", \
3621     option); \
3622   DestroyMogrify(); \
3623   return(MagickFalse); \
3624 }
3625 #define ThrowMogrifyInvalidArgumentException(option,argument) \
3626 { \
3627   (void) ThrowMagickException(exception,GetMagickModule(),OptionError, \
3628     "InvalidArgument","`%s': %s",argument,option); \
3629   DestroyMogrify(); \
3630   return(MagickFalse); \
3631 }
3632
3633   char
3634     *format,
3635     *option,
3636     *path;
3637
3638   Image
3639     *image;
3640
3641   ImageStack
3642     image_stack[MaxImageStackDepth+1];
3643
3644   MagickBooleanType
3645     global_colormap;
3646
3647   MagickBooleanType
3648     fire,
3649     pend,
3650     respect_parenthesis;
3651
3652   MagickStatusType
3653     status;
3654
3655   register ssize_t
3656     i;
3657
3658   ssize_t
3659     j,
3660     k;
3661
3662   /*
3663     Set defaults.
3664   */
3665   assert(image_info != (ImageInfo *) NULL);
3666   assert(image_info->signature == MagickSignature);
3667   if (image_info->debug != MagickFalse)
3668     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
3669   assert(exception != (ExceptionInfo *) NULL);
3670   if (argc == 2)
3671     {
3672       option=argv[1];
3673       if ((LocaleCompare("version",option+1) == 0) ||
3674           (LocaleCompare("-version",option+1) == 0))
3675         {
3676           (void) FormatLocaleFile(stdout,"Version: %s\n",
3677             GetMagickVersion((size_t *) NULL));
3678           (void) FormatLocaleFile(stdout,"Copyright: %s\n",
3679             GetMagickCopyright());
3680           (void) FormatLocaleFile(stdout,"Features: %s\n\n",
3681             GetMagickFeatures());
3682           return(MagickFalse);
3683         }
3684     }
3685   if (argc < 2)
3686     return(MogrifyUsage());
3687   format=(char *) NULL;
3688   path=(char *) NULL;
3689   global_colormap=MagickFalse;
3690   k=0;
3691   j=1;
3692   NewImageStack();
3693   option=(char *) NULL;
3694   pend=MagickFalse;
3695   respect_parenthesis=MagickFalse;
3696   status=MagickTrue;
3697   /*
3698     Parse command line.
3699   */
3700   ReadCommandlLine(argc,&argv);
3701   status=ExpandFilenames(&argc,&argv);
3702   if (status == MagickFalse)
3703     ThrowMogrifyException(ResourceLimitError,"MemoryAllocationFailed",
3704       GetExceptionMessage(errno));
3705   for (i=1; i < (ssize_t) argc; i++)
3706   {
3707     option=argv[i];
3708     if (LocaleCompare(option,"(") == 0)
3709       {
3710         FireImageStack(MagickFalse,MagickTrue,pend);
3711         if (k == MaxImageStackDepth)
3712           ThrowMogrifyException(OptionError,"ParenthesisNestedTooDeeply",
3713             option);
3714         PushImageStack();
3715         continue;
3716       }
3717     if (LocaleCompare(option,")") == 0)
3718       {
3719         FireImageStack(MagickFalse,MagickTrue,MagickTrue);
3720         if (k == 0)
3721           ThrowMogrifyException(OptionError,"UnableToParseExpression",option);
3722         PopImageStack();
3723         continue;
3724       }
3725     if (IsCommandOption(option) == MagickFalse)
3726       {
3727         char
3728           backup_filename[MaxTextExtent],
3729           *filename;
3730
3731         Image
3732           *images;
3733
3734         /*
3735           Option is a file name: begin by reading image from specified file.
3736         */
3737         FireImageStack(MagickFalse,MagickFalse,pend);
3738         filename=argv[i];
3739         if ((LocaleCompare(filename,"--") == 0) && (i < (ssize_t) (argc-1)))
3740           filename=argv[++i];
3741         (void) CopyMagickString(image_info->filename,filename,MaxTextExtent);
3742         images=ReadImages(image_info,exception);
3743         status&=(images != (Image *) NULL) &&
3744           (exception->severity < ErrorException);
3745         if (images == (Image *) NULL)
3746           continue;
3747         if (format != (char *) NULL)
3748           (void) CopyMagickString(images->filename,images->magick_filename,
3749             MaxTextExtent);
3750         if (path != (char *) NULL)
3751           {
3752             GetPathComponent(option,TailPath,filename);
3753             (void) FormatLocaleString(images->filename,MaxTextExtent,"%s%c%s",
3754               path,*DirectorySeparator,filename);
3755           }
3756         if (format != (char *) NULL)
3757           AppendImageFormat(format,images->filename);
3758         AppendImageStack(images);
3759         FinalizeImageSettings(image_info,image,MagickFalse);
3760         if (global_colormap != MagickFalse)
3761           {
3762             QuantizeInfo
3763               *quantize_info;
3764
3765             quantize_info=AcquireQuantizeInfo(image_info);
3766             (void) RemapImages(quantize_info,images,(Image *) NULL,exception);
3767             quantize_info=DestroyQuantizeInfo(quantize_info);
3768           }
3769         *backup_filename='\0';
3770         if ((LocaleCompare(image->filename,"-") != 0) &&
3771             (IsPathWritable(image->filename) != MagickFalse))
3772           {
3773             register ssize_t
3774               i;
3775
3776             /*
3777               Rename image file as backup.
3778             */
3779             (void) CopyMagickString(backup_filename,image->filename,
3780               MaxTextExtent);
3781             for (i=0; i < 6; i++)
3782             {
3783               (void) ConcatenateMagickString(backup_filename,"~",MaxTextExtent);
3784               if (IsPathAccessible(backup_filename) == MagickFalse)
3785                 break;
3786             }
3787             if ((IsPathAccessible(backup_filename) != MagickFalse) ||
3788                 (rename_utf8(image->filename,backup_filename) != 0))
3789               *backup_filename='\0';
3790           }
3791         /*
3792           Write transmogrified image to disk.
3793         */
3794         image_info->synchronize=MagickTrue;
3795         status&=WriteImages(image_info,image,image->filename,exception);
3796         if ((status == MagickFalse) && (*backup_filename != '\0'))
3797           (void) remove_utf8(backup_filename);
3798         RemoveAllImageStack();
3799         continue;
3800       }
3801     pend=image != (Image *) NULL ? MagickTrue : MagickFalse;
3802     switch (*(option+1))
3803     {
3804       case 'a':
3805       {
3806         if (LocaleCompare("adaptive-blur",option+1) == 0)
3807           {
3808             i++;
3809             if (i == (ssize_t) argc)
3810               ThrowMogrifyException(OptionError,"MissingArgument",option);
3811             if (IsGeometry(argv[i]) == MagickFalse)
3812               ThrowMogrifyInvalidArgumentException(option,argv[i]);
3813             break;
3814           }
3815         if (LocaleCompare("adaptive-resize",option+1) == 0)
3816           {
3817             i++;
3818             if (i == (ssize_t) argc)
3819               ThrowMogrifyException(OptionError,"MissingArgument",option);
3820             if (IsGeometry(argv[i]) == MagickFalse)
3821               ThrowMogrifyInvalidArgumentException(option,argv[i]);
3822             break;
3823           }
3824         if (LocaleCompare("adaptive-sharpen",option+1) == 0)
3825           {
3826             i++;
3827             if (i == (ssize_t) argc)
3828               ThrowMogrifyException(OptionError,"MissingArgument",option);
3829             if (IsGeometry(argv[i]) == MagickFalse)
3830               ThrowMogrifyInvalidArgumentException(option,argv[i]);
3831             break;
3832           }
3833         if (LocaleCompare("affine",option+1) == 0)
3834           {
3835             if (*option == '+')
3836               break;
3837             i++;
3838             if (i == (ssize_t) argc)
3839               ThrowMogrifyException(OptionError,"MissingArgument",option);
3840             break;
3841           }
3842         if (LocaleCompare("alpha",option+1) == 0)
3843           {
3844             ssize_t
3845               type;
3846
3847             if (*option == '+')
3848               break;
3849             i++;
3850             if (i == (ssize_t) argc)
3851               ThrowMogrifyException(OptionError,"MissingArgument",option);
3852             type=ParseCommandOption(MagickAlphaOptions,MagickFalse,argv[i]);
3853             if (type < 0)
3854               ThrowMogrifyException(OptionError,"UnrecognizedAlphaChannelType",
3855                 argv[i]);
3856             break;
3857           }
3858         if (LocaleCompare("annotate",option+1) == 0)
3859           {
3860             if (*option == '+')
3861               break;
3862             i++;
3863             if (i == (ssize_t) argc)
3864               ThrowMogrifyException(OptionError,"MissingArgument",option);
3865             if (IsGeometry(argv[i]) == MagickFalse)
3866               ThrowMogrifyInvalidArgumentException(option,argv[i]);
3867             if (i == (ssize_t) argc)
3868               ThrowMogrifyException(OptionError,"MissingArgument",option);
3869             i++;
3870             break;
3871           }
3872         if (LocaleCompare("antialias",option+1) == 0)
3873           break;
3874         if (LocaleCompare("append",option+1) == 0)
3875           break;
3876         if (LocaleCompare("attenuate",option+1) == 0)
3877           {
3878             if (*option == '+')
3879               break;
3880             i++;
3881             if (i == (ssize_t) (argc-1))
3882               ThrowMogrifyException(OptionError,"MissingArgument",option);
3883             if (IsGeometry(argv[i]) == MagickFalse)
3884               ThrowMogrifyInvalidArgumentException(option,argv[i]);
3885             break;
3886           }
3887         if (LocaleCompare("authenticate",option+1) == 0)
3888           {
3889             if (*option == '+')
3890               break;
3891             i++;
3892             if (i == (ssize_t) argc)
3893               ThrowMogrifyException(OptionError,"MissingArgument",option);
3894             break;
3895           }
3896         if (LocaleCompare("auto-gamma",option+1) == 0)
3897           break;
3898         if (LocaleCompare("auto-level",option+1) == 0)
3899           break;
3900         if (LocaleCompare("auto-orient",option+1) == 0)
3901           break;
3902         if (LocaleCompare("average",option+1) == 0)
3903           break;
3904         ThrowMogrifyException(OptionError,"UnrecognizedOption",option)
3905       }
3906       case 'b':
3907       {
3908         if (LocaleCompare("background",option+1) == 0)
3909           {
3910             if (*option == '+')
3911               break;
3912             i++;
3913             if (i == (ssize_t) argc)
3914               ThrowMogrifyException(OptionError,"MissingArgument",option);
3915             break;
3916           }
3917         if (LocaleCompare("bias",option+1) == 0)
3918           {
3919             if (*option == '+')
3920               break;
3921             i++;
3922             if (i == (ssize_t) (argc-1))
3923               ThrowMogrifyException(OptionError,"MissingArgument",option);
3924             if (IsGeometry(argv[i]) == MagickFalse)
3925               ThrowMogrifyInvalidArgumentException(option,argv[i]);
3926             break;
3927           }
3928         if (LocaleCompare("black-point-compensation",option+1) == 0)
3929           break;
3930         if (LocaleCompare("black-threshold",option+1) == 0)
3931           {
3932             if (*option == '+')
3933               break;
3934             i++;
3935             if (i == (ssize_t) argc)
3936               ThrowMogrifyException(OptionError,"MissingArgument",option);
3937             if (IsGeometry(argv[i]) == MagickFalse)
3938               ThrowMogrifyInvalidArgumentException(option,argv[i]);
3939             break;
3940           }
3941         if (LocaleCompare("blue-primary",option+1) == 0)
3942           {
3943             if (*option == '+')
3944               break;
3945             i++;
3946             if (i == (ssize_t) argc)
3947               ThrowMogrifyException(OptionError,"MissingArgument",option);
3948             if (IsGeometry(argv[i]) == MagickFalse)
3949               ThrowMogrifyInvalidArgumentException(option,argv[i]);
3950             break;
3951           }
3952         if (LocaleCompare("blue-shift",option+1) == 0)
3953           {
3954             i++;
3955             if (i == (ssize_t) argc)
3956               ThrowMogrifyException(OptionError,"MissingArgument",option);
3957             if (IsGeometry(argv[i]) == MagickFalse)
3958               ThrowMogrifyInvalidArgumentException(option,argv[i]);
3959             break;
3960           }
3961         if (LocaleCompare("blur",option+1) == 0)
3962           {
3963             i++;
3964             if (i == (ssize_t) argc)
3965               ThrowMogrifyException(OptionError,"MissingArgument",option);
3966             if (IsGeometry(argv[i]) == MagickFalse)
3967               ThrowMogrifyInvalidArgumentException(option,argv[i]);
3968             break;
3969           }
3970         if (LocaleCompare("border",option+1) == 0)
3971           {
3972             if (*option == '+')
3973               break;
3974             i++;
3975             if (i == (ssize_t) argc)
3976               ThrowMogrifyException(OptionError,"MissingArgument",option);
3977             if (IsGeometry(argv[i]) == MagickFalse)
3978               ThrowMogrifyInvalidArgumentException(option,argv[i]);
3979             break;
3980           }
3981         if (LocaleCompare("bordercolor",option+1) == 0)
3982           {
3983             if (*option == '+')
3984               break;
3985             i++;
3986             if (i == (ssize_t) argc)
3987               ThrowMogrifyException(OptionError,"MissingArgument",option);
3988             break;
3989           }
3990         if (LocaleCompare("box",option+1) == 0)
3991           {
3992             if (*option == '+')
3993               break;
3994             i++;
3995             if (i == (ssize_t) argc)
3996               ThrowMogrifyException(OptionError,"MissingArgument",option);
3997             break;
3998           }
3999         if (LocaleCompare("brightness-contrast",option+1) == 0)
4000           {
4001             i++;
4002             if (i == (ssize_t) argc)
4003               ThrowMogrifyException(OptionError,"MissingArgument",option);
4004             if (IsGeometry(argv[i]) == MagickFalse)
4005               ThrowMogrifyInvalidArgumentException(option,argv[i]);
4006             break;
4007           }
4008         ThrowMogrifyException(OptionError,"UnrecognizedOption",option)
4009       }
4010       case 'c':
4011       {
4012         if (LocaleCompare("cache",option+1) == 0)
4013           {
4014             if (*option == '+')
4015               break;
4016             i++;
4017             if (i == (ssize_t) argc)
4018               ThrowMogrifyException(OptionError,"MissingArgument",option);
4019             if (IsGeometry(argv[i]) == MagickFalse)
4020               ThrowMogrifyInvalidArgumentException(option,argv[i]);
4021             break;
4022           }
4023         if (LocaleCompare("caption",option+1) == 0)
4024           {
4025             if (*option == '+')
4026               break;
4027             i++;
4028             if (i == (ssize_t) argc)
4029               ThrowMogrifyException(OptionError,"MissingArgument",option);
4030             break;
4031           }
4032         if (LocaleCompare("channel",option+1) == 0)
4033           {
4034             ssize_t
4035               channel;
4036
4037             if (*option == '+')
4038               break;
4039             i++;
4040             if (i == (ssize_t) (argc-1))
4041               ThrowMogrifyException(OptionError,"MissingArgument",option);
4042             channel=ParseChannelOption(argv[i]);
4043             if (channel < 0)
4044               ThrowMogrifyException(OptionError,"UnrecognizedChannelType",
4045                 argv[i]);
4046             break;
4047           }
4048         if (LocaleCompare("cdl",option+1) == 0)
4049           {
4050             if (*option == '+')
4051               break;
4052             i++;
4053             if (i == (ssize_t) (argc-1))
4054               ThrowMogrifyException(OptionError,"MissingArgument",option);
4055             break;
4056           }
4057         if (LocaleCompare("charcoal",option+1) == 0)
4058           {
4059             if (*option == '+')
4060               break;
4061             i++;
4062             if (i == (ssize_t) argc)
4063               ThrowMogrifyException(OptionError,"MissingArgument",option);
4064             if (IsGeometry(argv[i]) == MagickFalse)
4065               ThrowMogrifyInvalidArgumentException(option,argv[i]);
4066             break;
4067           }
4068         if (LocaleCompare("chop",option+1) == 0)
4069           {
4070             if (*option == '+')
4071               break;
4072             i++;
4073             if (i == (ssize_t) argc)
4074               ThrowMogrifyException(OptionError,"MissingArgument",option);
4075             if (IsGeometry(argv[i]) == MagickFalse)
4076               ThrowMogrifyInvalidArgumentException(option,argv[i]);
4077             break;
4078           }
4079         if (LocaleCompare("clamp",option+1) == 0)
4080           break;
4081         if (LocaleCompare("clip",option+1) == 0)
4082           break;
4083         if (LocaleCompare("clip-mask",option+1) == 0)
4084           {
4085             if (*option == '+')
4086               break;
4087             i++;
4088             if (i == (ssize_t) argc)
4089               ThrowMogrifyException(OptionError,"MissingArgument",option);
4090             break;
4091           }
4092         if (LocaleCompare("clut",option+1) == 0)
4093           break;
4094         if (LocaleCompare("coalesce",option+1) == 0)
4095           break;
4096         if (LocaleCompare("colorize",option+1) == 0)
4097           {
4098             if (*option == '+')
4099               break;
4100             i++;
4101             if (i == (ssize_t) argc)
4102               ThrowMogrifyException(OptionError,"MissingArgument",option);
4103             if (IsGeometry(argv[i]) == MagickFalse)
4104               ThrowMogrifyInvalidArgumentException(option,argv[i]);
4105             break;
4106           }
4107         if (LocaleCompare("color-matrix",option+1) == 0)
4108           {
4109             KernelInfo
4110               *kernel_info;
4111
4112             if (*option == '+')
4113               break;
4114             i++;
4115             if (i == (ssize_t) (argc-1))
4116               ThrowMogrifyException(OptionError,"MissingArgument",option);
4117             kernel_info=AcquireKernelInfo(argv[i]);
4118             if (kernel_info == (KernelInfo *) NULL)
4119               ThrowMogrifyInvalidArgumentException(option,argv[i]);
4120             kernel_info=DestroyKernelInfo(kernel_info);
4121             break;
4122           }
4123         if (LocaleCompare("colors",option+1) == 0)
4124           {
4125             if (*option == '+')
4126               break;
4127             i++;
4128             if (i == (ssize_t) argc)
4129               ThrowMogrifyException(OptionError,"MissingArgument",option);
4130             if (IsGeometry(argv[i]) == MagickFalse)
4131               ThrowMogrifyInvalidArgumentException(option,argv[i]);
4132             break;
4133           }
4134         if (LocaleCompare("colorspace",option+1) == 0)
4135           {
4136             ssize_t
4137               colorspace;
4138
4139             if (*option == '+')
4140               break;
4141             i++;
4142             if (i == (ssize_t) argc)
4143               ThrowMogrifyException(OptionError,"MissingArgument",option);
4144             colorspace=ParseCommandOption(MagickColorspaceOptions,MagickFalse,
4145               argv[i]);
4146             if (colorspace < 0)
4147               ThrowMogrifyException(OptionError,"UnrecognizedColorspace",
4148                 argv[i]);
4149             break;
4150           }
4151         if (LocaleCompare("combine",option+1) == 0)
4152           break;
4153         if (LocaleCompare("comment",option+1) == 0)
4154           {
4155             if (*option == '+')
4156               break;
4157             i++;
4158             if (i == (ssize_t) argc)
4159               ThrowMogrifyException(OptionError,"MissingArgument",option);
4160             break;
4161           }
4162         if (LocaleCompare("composite",option+1) == 0)
4163           break;
4164         if (LocaleCompare("compress",option+1) == 0)
4165           {
4166             ssize_t
4167               compress;
4168
4169             if (*option == '+')
4170               break;
4171             i++;
4172             if (i == (ssize_t) argc)
4173               ThrowMogrifyException(OptionError,"MissingArgument",option);
4174             compress=ParseCommandOption(MagickCompressOptions,MagickFalse,
4175               argv[i]);
4176             if (compress < 0)
4177               ThrowMogrifyException(OptionError,"UnrecognizedImageCompression",
4178                 argv[i]);
4179             break;
4180           }
4181         if (LocaleCompare("concurrent",option+1) == 0)
4182           break;
4183         if (LocaleCompare("contrast",option+1) == 0)
4184           break;
4185         if (LocaleCompare("contrast-stretch",option+1) == 0)
4186           {
4187             i++;
4188             if (i == (ssize_t) argc)
4189               ThrowMogrifyException(OptionError,"MissingArgument",option);
4190             if (IsGeometry(argv[i]) == MagickFalse)
4191               ThrowMogrifyInvalidArgumentException(option,argv[i]);
4192             break;
4193           }
4194         if (LocaleCompare("convolve",option+1) == 0)
4195           {
4196             KernelInfo
4197               *kernel_info;
4198
4199             if (*option == '+')
4200               break;
4201             i++;
4202             if (i == (ssize_t) argc)
4203               ThrowMogrifyException(OptionError,"MissingArgument",option);
4204             kernel_info=AcquireKernelInfo(argv[i]);
4205             if (kernel_info == (KernelInfo *) NULL)
4206               ThrowMogrifyInvalidArgumentException(option,argv[i]);
4207             kernel_info=DestroyKernelInfo(kernel_info);
4208             break;
4209           }
4210         if (LocaleCompare("crop",option+1) == 0)
4211           {
4212             if (*option == '+')
4213               break;
4214             i++;
4215             if (i == (ssize_t) argc)
4216               ThrowMogrifyException(OptionError,"MissingArgument",option);
4217             if (IsGeometry(argv[i]) == MagickFalse)
4218               ThrowMogrifyInvalidArgumentException(option,argv[i]);
4219             break;
4220           }
4221         if (LocaleCompare("cycle",option+1) == 0)
4222           {
4223             if (*option == '+')
4224               break;
4225             i++;
4226             if (i == (ssize_t) argc)
4227               ThrowMogrifyException(OptionError,"MissingArgument",option);
4228             if (IsGeometry(argv[i]) == MagickFalse)
4229               ThrowMogrifyInvalidArgumentException(option,argv[i]);
4230             break;
4231           }
4232         ThrowMogrifyException(OptionError,"UnrecognizedOption",option)
4233       }
4234       case 'd':
4235       {
4236         if (LocaleCompare("decipher",option+1) == 0)
4237           {
4238             if (*option == '+')
4239               break;
4240             i++;
4241             if (i == (ssize_t) (argc-1))
4242               ThrowMogrifyException(OptionError,"MissingArgument",option);
4243             break;
4244           }
4245         if (LocaleCompare("deconstruct",option+1) == 0)
4246           break;
4247         if (LocaleCompare("debug",option+1) == 0)
4248           {
4249             ssize_t
4250               event;
4251
4252             if (*option == '+')
4253               break;
4254             i++;
4255             if (i == (ssize_t) argc)
4256               ThrowMogrifyException(OptionError,"MissingArgument",option);
4257             event=ParseCommandOption(MagickLogEventOptions,MagickFalse,argv[i]);
4258             if (event < 0)
4259               ThrowMogrifyException(OptionError,"UnrecognizedEventType",
4260                 argv[i]);
4261             (void) SetLogEventMask(argv[i]);
4262             break;
4263           }
4264         if (LocaleCompare("define",option+1) == 0)
4265           {
4266             i++;
4267             if (i == (ssize_t) argc)
4268               ThrowMogrifyException(OptionError,"MissingArgument",option);
4269             if (*option == '+')
4270               {
4271                 const char
4272                   *define;
4273
4274                 define=GetImageOption(image_info,argv[i]);
4275                 if (define == (const char *) NULL)
4276                   ThrowMogrifyException(OptionError,"NoSuchOption",argv[i]);
4277                 break;
4278               }
4279             break;
4280           }
4281         if (LocaleCompare("delay",option+1) == 0)
4282           {
4283             if (*option == '+')
4284               break;
4285             i++;
4286             if (i == (ssize_t) argc)
4287               ThrowMogrifyException(OptionError,"MissingArgument",option);
4288             if (IsGeometry(argv[i]) == MagickFalse)
4289               ThrowMogrifyInvalidArgumentException(option,argv[i]);
4290             break;
4291           }
4292         if (LocaleCompare("delete",option+1) == 0)
4293           {
4294             if (*option == '+')
4295               break;
4296             i++;
4297             if (i == (ssize_t) (argc-1))
4298               ThrowMogrifyException(OptionError,"MissingArgument",option);
4299             if (IsGeometry(argv[i]) == MagickFalse)
4300               ThrowMogrifyInvalidArgumentException(option,argv[i]);
4301             break;
4302           }
4303         if (LocaleCompare("density",option+1) == 0)
4304           {
4305             if (*option == '+')
4306               break;
4307             i++;
4308             if (i == (ssize_t) argc)
4309               ThrowMogrifyException(OptionError,"MissingArgument",option);
4310             if (IsGeometry(argv[i]) == MagickFalse)
4311               ThrowMogrifyInvalidArgumentException(option,argv[i]);
4312             break;
4313           }
4314         if (LocaleCompare("depth",option+1) == 0)
4315           {
4316             if (*option == '+')
4317               break;
4318             i++;
4319             if (i == (ssize_t) argc)
4320               ThrowMogrifyException(OptionError,"MissingArgument",option);
4321             if (IsGeometry(argv[i]) == MagickFalse)
4322               ThrowMogrifyInvalidArgumentException(option,argv[i]);
4323             break;
4324           }
4325         if (LocaleCompare("deskew",option+1) == 0)
4326           {
4327             if (*option == '+')
4328               break;
4329             i++;
4330             if (i == (ssize_t) argc)
4331               ThrowMogrifyException(OptionError,"MissingArgument",option);
4332             if (IsGeometry(argv[i]) == MagickFalse)
4333               ThrowMogrifyInvalidArgumentException(option,argv[i]);
4334             break;
4335           }
4336         if (LocaleCompare("despeckle",option+1) == 0)
4337           break;
4338         if (LocaleCompare("dft",option+1) == 0)
4339           break;
4340         if (LocaleCompare("direction",option+1) == 0)
4341           {
4342             ssize_t
4343               direction;
4344
4345             if (*option == '+')
4346               break;
4347             i++;
4348             if (i == (ssize_t) argc)
4349               ThrowMogrifyException(OptionError,"MissingArgument",option);
4350             direction=ParseCommandOption(MagickDirectionOptions,MagickFalse,
4351               argv[i]);
4352             if (direction < 0)
4353               ThrowMogrifyException(OptionError,"UnrecognizedDirectionType",
4354                 argv[i]);
4355             break;
4356           }
4357         if (LocaleCompare("display",option+1) == 0)
4358           {
4359             if (*option == '+')
4360               break;
4361             i++;
4362             if (i == (ssize_t) argc)
4363               ThrowMogrifyException(OptionError,"MissingArgument",option);
4364             break;
4365           }
4366         if (LocaleCompare("dispose",option+1) == 0)
4367           {
4368             ssize_t
4369               dispose;
4370
4371             if (*option == '+')
4372               break;
4373             i++;
4374             if (i == (ssize_t) argc)
4375               ThrowMogrifyException(OptionError,"MissingArgument",option);
4376             dispose=ParseCommandOption(MagickDisposeOptions,MagickFalse,argv[i]);
4377             if (dispose < 0)
4378               ThrowMogrifyException(OptionError,"UnrecognizedDisposeMethod",
4379                 argv[i]);
4380             break;
4381           }
4382         if (LocaleCompare("distort",option+1) == 0)
4383           {
4384             ssize_t
4385               op;
4386
4387             i++;
4388             if (i == (ssize_t) argc)
4389               ThrowMogrifyException(OptionError,"MissingArgument",option);
4390             op=ParseCommandOption(MagickDistortOptions,MagickFalse,argv[i]);
4391             if (op < 0)
4392               ThrowMogrifyException(OptionError,"UnrecognizedDistortMethod",
4393                 argv[i]);
4394             i++;
4395             if (i == (ssize_t) (argc-1))
4396               ThrowMogrifyException(OptionError,"MissingArgument",option);
4397             break;
4398           }
4399         if (LocaleCompare("dither",option+1) == 0)
4400           {
4401             ssize_t
4402               method;
4403
4404             if (*option == '+')
4405               break;
4406             i++;
4407             if (i == (ssize_t) argc)
4408               ThrowMogrifyException(OptionError,"MissingArgument",option);
4409             method=ParseCommandOption(MagickDitherOptions,MagickFalse,argv[i]);
4410             if (method < 0)
4411               ThrowMogrifyException(OptionError,"UnrecognizedDitherMethod",
4412                 argv[i]);
4413             break;
4414           }
4415         if (LocaleCompare("draw",option+1) == 0)
4416           {
4417             if (*option == '+')
4418               break;
4419             i++;
4420             if (i == (ssize_t) argc)
4421               ThrowMogrifyException(OptionError,"MissingArgument",option);
4422             break;
4423           }
4424         if (LocaleCompare("duplicate",option+1) == 0)
4425           {
4426             if (*option == '+')
4427               break;
4428             i++;
4429             if (i == (ssize_t) (argc-1))
4430               ThrowMogrifyException(OptionError,"MissingArgument",option);
4431             if (IsGeometry(argv[i]) == MagickFalse)
4432               ThrowMogrifyInvalidArgumentException(option,argv[i]);
4433             break;
4434           }
4435         if (LocaleCompare("duration",option+1) == 0)
4436           {
4437             if (*option == '+')
4438               break;
4439             i++;
4440             if (i == (ssize_t) (argc-1))
4441               ThrowMogrifyException(OptionError,"MissingArgument",option);
4442             if (IsGeometry(argv[i]) == MagickFalse)
4443               ThrowMogrifyInvalidArgumentException(option,argv[i]);
4444             break;
4445           }
4446         ThrowMogrifyException(OptionError,"UnrecognizedOption",option)
4447       }
4448       case 'e':
4449       {
4450         if (LocaleCompare("edge",option+1) == 0)
4451           {
4452             if (*option == '+')
4453               break;
4454             i++;
4455             if (i == (ssize_t) argc)
4456               ThrowMogrifyException(OptionError,"MissingArgument",option);
4457             if (IsGeometry(argv[i]) == MagickFalse)
4458               ThrowMogrifyInvalidArgumentException(option,argv[i]);
4459             break;
4460           }
4461         if (LocaleCompare("emboss",option+1) == 0)
4462           {
4463             if (*option == '+')
4464               break;
4465             i++;
4466             if (i == (ssize_t) argc)
4467               ThrowMogrifyException(OptionError,"MissingArgument",option);
4468             if (IsGeometry(argv[i]) == MagickFalse)
4469               ThrowMogrifyInvalidArgumentException(option,argv[i]);
4470             break;
4471           }
4472         if (LocaleCompare("encipher",option+1) == 0)
4473           {
4474             if (*option == '+')
4475               break;
4476             i++;
4477             if (i == (ssize_t) argc)
4478               ThrowMogrifyException(OptionError,"MissingArgument",option);
4479             break;
4480           }
4481         if (LocaleCompare("encoding",option+1) == 0)
4482           {
4483             if (*option == '+')
4484               break;
4485             i++;
4486             if (i == (ssize_t) argc)
4487               ThrowMogrifyException(OptionError,"MissingArgument",option);
4488             break;
4489           }
4490         if (LocaleCompare("endian",option+1) == 0)
4491           {
4492             ssize_t
4493               endian;
4494
4495             if (*option == '+')
4496               break;
4497             i++;
4498             if (i == (ssize_t) argc)
4499               ThrowMogrifyException(OptionError,"MissingArgument",option);
4500             endian=ParseCommandOption(MagickEndianOptions,MagickFalse,argv[i]);
4501             if (endian < 0)
4502               ThrowMogrifyException(OptionError,"UnrecognizedEndianType",
4503                 argv[i]);
4504             break;
4505           }
4506         if (LocaleCompare("enhance",option+1) == 0)
4507           break;
4508         if (LocaleCompare("equalize",option+1) == 0)
4509           break;
4510         if (LocaleCompare("evaluate",option+1) == 0)
4511           {
4512             ssize_t
4513               op;
4514
4515             if (*option == '+')
4516               break;
4517             i++;
4518             if (i == (ssize_t) argc)
4519               ThrowMogrifyException(OptionError,"MissingArgument",option);
4520             op=ParseCommandOption(MagickEvaluateOptions,MagickFalse,argv[i]);
4521             if (op < 0)
4522               ThrowMogrifyException(OptionError,"UnrecognizedEvaluateOperator",
4523                 argv[i]);
4524             i++;
4525             if (i == (ssize_t) (argc-1))
4526               ThrowMogrifyException(OptionError,"MissingArgument",option);
4527             if (IsGeometry(argv[i]) == MagickFalse)
4528               ThrowMogrifyInvalidArgumentException(option,argv[i]);
4529             break;
4530           }
4531         if (LocaleCompare("evaluate-sequence",option+1) == 0)
4532           {
4533             ssize_t
4534               op;
4535
4536             if (*option == '+')
4537               break;
4538             i++;
4539             if (i == (ssize_t) argc)
4540               ThrowMogrifyException(OptionError,"MissingArgument",option);
4541             op=ParseCommandOption(MagickEvaluateOptions,MagickFalse,argv[i]);
4542             if (op < 0)
4543               ThrowMogrifyException(OptionError,"UnrecognizedEvaluateOperator",
4544                 argv[i]);
4545             break;
4546           }
4547         if (LocaleCompare("extent",option+1) == 0)
4548           {
4549             if (*option == '+')
4550               break;
4551             i++;
4552             if (i == (ssize_t) argc)
4553               ThrowMogrifyException(OptionError,"MissingArgument",option);
4554             if (IsGeometry(argv[i]) == MagickFalse)
4555               ThrowMogrifyInvalidArgumentException(option,argv[i]);
4556             break;
4557           }
4558         if (LocaleCompare("extract",option+1) == 0)
4559           {
4560             if (*option == '+')
4561               break;
4562             i++;
4563             if (i == (ssize_t) argc)
4564               ThrowMogrifyException(OptionError,"MissingArgument",option);
4565             if (IsGeometry(argv[i]) == MagickFalse)
4566               ThrowMogrifyInvalidArgumentException(option,argv[i]);
4567             break;
4568           }
4569         ThrowMogrifyException(OptionError,"UnrecognizedOption",option)
4570       }
4571       case 'f':
4572       {
4573         if (LocaleCompare("family",option+1) == 0)
4574           {
4575             if (*option == '+')
4576               break;
4577             i++;
4578             if (i == (ssize_t) (argc-1))
4579               ThrowMogrifyException(OptionError,"MissingArgument",option);
4580             break;
4581           }
4582         if (LocaleCompare("fill",option+1) == 0)
4583           {
4584             if (*option == '+')
4585               break;
4586             i++;
4587             if (i == (ssize_t) argc)
4588               ThrowMogrifyException(OptionError,"MissingArgument",option);
4589             break;
4590           }
4591         if (LocaleCompare("filter",option+1) == 0)
4592           {
4593             ssize_t
4594               filter;
4595
4596             if (*option == '+')
4597               break;
4598             i++;
4599             if (i == (ssize_t) argc)
4600               ThrowMogrifyException(OptionError,"MissingArgument",option);
4601             filter=ParseCommandOption(MagickFilterOptions,MagickFalse,argv[i]);
4602             if (filter < 0)
4603               ThrowMogrifyException(OptionError,"UnrecognizedImageFilter",
4604                 argv[i]);
4605             break;
4606           }
4607         if (LocaleCompare("flatten",option+1) == 0)
4608           break;
4609         if (LocaleCompare("flip",option+1) == 0)
4610           break;
4611         if (LocaleCompare("flop",option+1) == 0)
4612           break;
4613         if (LocaleCompare("floodfill",option+1) == 0)
4614           {
4615             if (*option == '+')
4616               break;
4617             i++;
4618             if (i == (ssize_t) argc)
4619               ThrowMogrifyException(OptionError,"MissingArgument",option);
4620             if (IsGeometry(argv[i]) == MagickFalse)
4621               ThrowMogrifyInvalidArgumentException(option,argv[i]);
4622             i++;
4623             if (i == (ssize_t) argc)
4624               ThrowMogrifyException(OptionError,"MissingArgument",option);
4625             break;
4626           }
4627         if (LocaleCompare("font",option+1) == 0)
4628           {
4629             if (*option == '+')
4630               break;
4631             i++;
4632             if (i == (ssize_t) argc)
4633               ThrowMogrifyException(OptionError,"MissingArgument",option);
4634             break;
4635           }
4636         if (LocaleCompare("format",option+1) == 0)
4637           {
4638             (void) CopyMagickString(argv[i]+1,"sans",MaxTextExtent);
4639             (void) CloneString(&format,(char *) NULL);
4640             if (*option == '+')
4641               break;
4642             i++;
4643             if (i == (ssize_t) argc)
4644               ThrowMogrifyException(OptionError,"MissingArgument",option);
4645             (void) CloneString(&format,argv[i]);
4646             (void) CopyMagickString(image_info->filename,format,MaxTextExtent);
4647             (void) ConcatenateMagickString(image_info->filename,":",
4648               MaxTextExtent);
4649             (void) SetImageInfo(image_info,0,exception);
4650             if (*image_info->magick == '\0')
4651               ThrowMogrifyException(OptionError,"UnrecognizedImageFormat",
4652                 format);
4653             break;
4654           }
4655         if (LocaleCompare("frame",option+1) == 0)
4656           {
4657             if (*option == '+')
4658               break;
4659             i++;
4660             if (i == (ssize_t) argc)
4661               ThrowMogrifyException(OptionError,"MissingArgument",option);
4662             if (IsGeometry(argv[i]) == MagickFalse)
4663               ThrowMogrifyInvalidArgumentException(option,argv[i]);
4664             break;
4665           }
4666         if (LocaleCompare("function",option+1) == 0)
4667           {
4668             ssize_t
4669               op;
4670
4671             if (*option == '+')
4672               break;
4673             i++;
4674             if (i == (ssize_t) argc)
4675               ThrowMogrifyException(OptionError,"MissingArgument",option);
4676             op=ParseCommandOption(MagickFunctionOptions,MagickFalse,argv[i]);
4677             if (op < 0)
4678               ThrowMogrifyException(OptionError,"UnrecognizedFunction",argv[i]);
4679              i++;
4680              if (i == (ssize_t) (argc-1))
4681                ThrowMogrifyException(OptionError,"MissingArgument",option);
4682             break;
4683           }
4684         if (LocaleCompare("fuzz",option+1) == 0)
4685           {
4686             if (*option == '+')
4687               break;
4688             i++;
4689             if (i == (ssize_t) argc)
4690               ThrowMogrifyException(OptionError,"MissingArgument",option);
4691             if (IsGeometry(argv[i]) == MagickFalse)
4692               ThrowMogrifyInvalidArgumentException(option,argv[i]);
4693             break;
4694           }
4695         if (LocaleCompare("fx",option+1) == 0)
4696           {
4697             if (*option == '+')
4698               break;
4699             i++;
4700             if (i == (ssize_t) (argc-1))
4701               ThrowMogrifyException(OptionError,"MissingArgument",option);
4702             break;
4703           }
4704         ThrowMogrifyException(OptionError,"UnrecognizedOption",option)
4705       }
4706       case 'g':
4707       {
4708         if (LocaleCompare("gamma",option+1) == 0)
4709           {
4710             i++;
4711             if (i == (ssize_t) argc)
4712               ThrowMogrifyException(OptionError,"MissingArgument",option);
4713             if (IsGeometry(argv[i]) == MagickFalse)
4714               ThrowMogrifyInvalidArgumentException(option,argv[i]);
4715             break;
4716           }
4717         if ((LocaleCompare("gaussian-blur",option+1) == 0) ||
4718             (LocaleCompare("gaussian",option+1) == 0))
4719           {
4720             i++;
4721             if (i == (ssize_t) argc)
4722               ThrowMogrifyException(OptionError,"MissingArgument",option);
4723             if (IsGeometry(argv[i]) == MagickFalse)
4724               ThrowMogrifyInvalidArgumentException(option,argv[i]);
4725             break;
4726           }
4727         if (LocaleCompare("geometry",option+1) == 0)
4728           {
4729             if (*option == '+')
4730               break;
4731             i++;
4732             if (i == (ssize_t) argc)
4733               ThrowMogrifyException(OptionError,"MissingArgument",option);
4734             if (IsGeometry(argv[i]) == MagickFalse)
4735               ThrowMogrifyInvalidArgumentException(option,argv[i]);
4736             break;
4737           }
4738         if (LocaleCompare("gravity",option+1) == 0)
4739           {
4740             ssize_t
4741               gravity;
4742
4743             if (*option == '+')
4744               break;
4745             i++;
4746             if (i == (ssize_t) argc)
4747               ThrowMogrifyException(OptionError,"MissingArgument",option);
4748             gravity=ParseCommandOption(MagickGravityOptions,MagickFalse,argv[i]);
4749             if (gravity < 0)
4750               ThrowMogrifyException(OptionError,"UnrecognizedGravityType",
4751                 argv[i]);
4752             break;
4753           }
4754         if (LocaleCompare("green-primary",option+1) == 0)
4755           {
4756             if (*option == '+')
4757               break;
4758             i++;
4759             if (i == (ssize_t) argc)
4760               ThrowMogrifyException(OptionError,"MissingArgument",option);
4761             if (IsGeometry(argv[i]) == MagickFalse)
4762               ThrowMogrifyInvalidArgumentException(option,argv[i]);
4763             break;
4764           }
4765         ThrowMogrifyException(OptionError,"UnrecognizedOption",option)
4766       }
4767       case 'h':
4768       {
4769         if (LocaleCompare("hald-clut",option+1) == 0)
4770           break;
4771         if ((LocaleCompare("help",option+1) == 0) ||
4772             (LocaleCompare("-help",option+1) == 0))
4773           return(MogrifyUsage());
4774         ThrowMogrifyException(OptionError,"UnrecognizedOption",option)
4775       }
4776       case 'i':
4777       {
4778         if (LocaleCompare("identify",option+1) == 0)
4779           break;
4780         if (LocaleCompare("idft",option+1) == 0)
4781           break;
4782         if (LocaleCompare("implode",option+1) == 0)
4783           {
4784             if (*option == '+')
4785               break;
4786             i++;
4787             if (i == (ssize_t) argc)
4788               ThrowMogrifyException(OptionError,"MissingArgument",option);
4789             if (IsGeometry(argv[i]) == MagickFalse)
4790               ThrowMogrifyInvalidArgumentException(option,argv[i]);
4791             break;
4792           }
4793         if (LocaleCompare("intent",option+1) == 0)
4794           {
4795             ssize_t
4796               intent;
4797
4798             if (*option == '+')
4799               break;
4800             i++;
4801             if (i == (ssize_t) (argc-1))
4802               ThrowMogrifyException(OptionError,"MissingArgument",option);
4803             intent=ParseCommandOption(MagickIntentOptions,MagickFalse,argv[i]);
4804             if (intent < 0)
4805               ThrowMogrifyException(OptionError,"UnrecognizedIntentType",
4806                 argv[i]);
4807             break;
4808           }
4809         if (LocaleCompare("interlace",option+1) == 0)
4810           {
4811             ssize_t
4812               interlace;
4813
4814             if (*option == '+')
4815               break;
4816             i++;
4817             if (i == (ssize_t) argc)
4818               ThrowMogrifyException(OptionError,"MissingArgument",option);
4819             interlace=ParseCommandOption(MagickInterlaceOptions,MagickFalse,
4820               argv[i]);
4821             if (interlace < 0)
4822               ThrowMogrifyException(OptionError,"UnrecognizedInterlaceType",
4823                 argv[i]);
4824             break;
4825           }
4826         if (LocaleCompare("interline-spacing",option+1) == 0)
4827           {
4828             if (*option == '+')
4829               break;
4830             i++;
4831             if (i == (ssize_t) (argc-1))
4832               ThrowMogrifyException(OptionError,"MissingArgument",option);
4833             if (IsGeometry(argv[i]) == MagickFalse)
4834               ThrowMogrifyInvalidArgumentException(option,argv[i]);
4835             break;
4836           }
4837         if (LocaleCompare("interpolate",option+1) == 0)
4838           {
4839             ssize_t
4840               interpolate;
4841
4842             if (*option == '+')
4843               break;
4844             i++;
4845             if (i == (ssize_t) argc)
4846               ThrowMogrifyException(OptionError,"MissingArgument",option);
4847             interpolate=ParseCommandOption(MagickInterpolateOptions,MagickFalse,
4848               argv[i]);
4849             if (interpolate < 0)
4850               ThrowMogrifyException(OptionError,"UnrecognizedInterpolateMethod",
4851                 argv[i]);
4852             break;
4853           }
4854         if (LocaleCompare("interword-spacing",option+1) == 0)
4855           {
4856             if (*option == '+')
4857               break;
4858             i++;
4859             if (i == (ssize_t) (argc-1))
4860               ThrowMogrifyException(OptionError,"MissingArgument",option);
4861             if (IsGeometry(argv[i]) == MagickFalse)
4862               ThrowMogrifyInvalidArgumentException(option,argv[i]);
4863             break;
4864           }
4865         ThrowMogrifyException(OptionError,"UnrecognizedOption",option)
4866       }
4867       case 'k':
4868       {
4869         if (LocaleCompare("kerning",option+1) == 0)
4870           {
4871             if (*option == '+')
4872               break;
4873             i++;
4874             if (i == (ssize_t) (argc-1))
4875               ThrowMogrifyException(OptionError,"MissingArgument",option);
4876             if (IsGeometry(argv[i]) == MagickFalse)
4877               ThrowMogrifyInvalidArgumentException(option,argv[i]);
4878             break;
4879           }
4880         ThrowMogrifyException(OptionError,"UnrecognizedOption",option)
4881       }
4882       case 'l':
4883       {
4884         if (LocaleCompare("label",option+1) == 0)
4885           {
4886             if (*option == '+')
4887               break;
4888             i++;
4889             if (i == (ssize_t) argc)
4890               ThrowMogrifyException(OptionError,"MissingArgument",option);
4891             break;
4892           }
4893         if (LocaleCompare("lat",option+1) == 0)
4894           {
4895             if (*option == '+')
4896               break;
4897             i++;
4898             if (i == (ssize_t) argc)
4899               ThrowMogrifyException(OptionError,"MissingArgument",option);
4900             if (IsGeometry(argv[i]) == MagickFalse)
4901               ThrowMogrifyInvalidArgumentException(option,argv[i]);
4902           }
4903         if (LocaleCompare("layers",option+1) == 0)
4904           {
4905             ssize_t
4906               type;
4907
4908             if (*option == '+')
4909               break;
4910             i++;
4911             if (i == (ssize_t) (argc-1))
4912               ThrowMogrifyException(OptionError,"MissingArgument",option);
4913             type=ParseCommandOption(MagickLayerOptions,MagickFalse,argv[i]);
4914             if (type < 0)
4915               ThrowMogrifyException(OptionError,"UnrecognizedLayerMethod",
4916                 argv[i]);
4917             break;
4918           }
4919         if (LocaleCompare("level",option+1) == 0)
4920           {
4921             i++;
4922             if (i == (ssize_t) argc)
4923               ThrowMogrifyException(OptionError,"MissingArgument",option);
4924             if (IsGeometry(argv[i]) == MagickFalse)
4925               ThrowMogrifyInvalidArgumentException(option,argv[i]);
4926             break;
4927           }
4928         if (LocaleCompare("level-colors",option+1) == 0)
4929           {
4930             i++;
4931             if (i == (ssize_t) argc)
4932               ThrowMogrifyException(OptionError,"MissingArgument",option);
4933             break;
4934           }
4935         if (LocaleCompare("linewidth",option+1) == 0)
4936           {
4937             if (*option == '+')
4938               break;
4939             i++;
4940             if (i == (ssize_t) argc)
4941               ThrowMogrifyException(OptionError,"MissingArgument",option);
4942             if (IsGeometry(argv[i]) == MagickFalse)
4943               ThrowMogrifyInvalidArgumentException(option,argv[i]);
4944             break;
4945           }
4946         if (LocaleCompare("limit",option+1) == 0)
4947           {
4948             char
4949               *p;
4950
4951             double
4952               value;
4953
4954             ssize_t
4955               resource;
4956
4957             if (*option == '+')
4958               break;
4959             i++;
4960             if (i == (ssize_t) argc)
4961               ThrowMogrifyException(OptionError,"MissingArgument",option);
4962             resource=ParseCommandOption(MagickResourceOptions,MagickFalse,
4963               argv[i]);
4964             if (resource < 0)
4965               ThrowMogrifyException(OptionError,"UnrecognizedResourceType",
4966                 argv[i]);
4967             i++;
4968             if (i == (ssize_t) argc)
4969               ThrowMogrifyException(OptionError,"MissingArgument",option);
4970             value=StringToDouble(argv[i],&p);
4971             (void) value;
4972             if ((p == argv[i]) && (LocaleCompare("unlimited",argv[i]) != 0))
4973               ThrowMogrifyInvalidArgumentException(option,argv[i]);
4974             break;
4975           }
4976         if (LocaleCompare("liquid-rescale",option+1) == 0)
4977           {
4978             i++;
4979             if (i == (ssize_t) argc)
4980               ThrowMogrifyException(OptionError,"MissingArgument",option);
4981             if (IsGeometry(argv[i]) == MagickFalse)
4982               ThrowMogrifyInvalidArgumentException(option,argv[i]);
4983             break;
4984           }
4985         if (LocaleCompare("list",option+1) == 0)
4986           {
4987             ssize_t
4988               list;
4989
4990             if (*option == '+')
4991               break;
4992             i++;
4993             if (i == (ssize_t) argc)
4994               ThrowMogrifyException(OptionError,"MissingArgument",option);
4995             list=ParseCommandOption(MagickListOptions,MagickFalse,argv[i]);
4996             if (list < 0)
4997               ThrowMogrifyException(OptionError,"UnrecognizedListType",argv[i]);
4998             status=MogrifyImageInfo(image_info,(int) (i-j+1),(const char **)
4999               argv+j,exception);
5000             return(status != 0 ? MagickFalse : MagickTrue);
5001           }
5002         if (LocaleCompare("log",option+1) == 0)
5003           {
5004             if (*option == '+')
5005               break;
5006             i++;
5007             if ((i == (ssize_t) argc) ||
5008                 (strchr(argv[i],'%') == (char *) NULL))
5009               ThrowMogrifyException(OptionError,"MissingArgument",option);
5010             break;
5011           }
5012         if (LocaleCompare("loop",option+1) == 0)
5013           {
5014             if (*option == '+')
5015               break;
5016             i++;
5017             if (i == (ssize_t) argc)
5018               ThrowMogrifyException(OptionError,"MissingArgument",option);
5019             if (IsGeometry(argv[i]) == MagickFalse)
5020               ThrowMogrifyInvalidArgumentException(option,argv[i]);
5021             break;
5022           }
5023         ThrowMogrifyException(OptionError,"UnrecognizedOption",option)
5024       }
5025       case 'm':
5026       {
5027         if (LocaleCompare("map",option+1) == 0)
5028           {
5029             global_colormap=(*option == '+') ? MagickTrue : MagickFalse;
5030             if (*option == '+')
5031               break;
5032             i++;
5033             if (i == (ssize_t) argc)
5034               ThrowMogrifyException(OptionError,"MissingArgument",option);
5035             break;
5036           }
5037         if (LocaleCompare("mask",option+1) == 0)
5038           {
5039             if (*option == '+')
5040               break;
5041             i++;
5042             if (i == (ssize_t) argc)
5043               ThrowMogrifyException(OptionError,"MissingArgument",option);
5044             break;
5045           }
5046         if (LocaleCompare("matte",option+1) == 0)
5047           break;
5048         if (LocaleCompare("mattecolor",option+1) == 0)
5049           {
5050             if (*option == '+')
5051               break;
5052             i++;
5053             if (i == (ssize_t) argc)
5054               ThrowMogrifyException(OptionError,"MissingArgument",option);
5055             break;
5056           }
5057         if (LocaleCompare("maximum",option+1) == 0)
5058           break;
5059         if (LocaleCompare("minimum",option+1) == 0)
5060           break;
5061         if (LocaleCompare("modulate",option+1) == 0)
5062           {
5063             if (*option == '+')
5064               break;
5065             i++;
5066             if (i == (ssize_t) argc)
5067               ThrowMogrifyException(OptionError,"MissingArgument",option);
5068             if (IsGeometry(argv[i]) == MagickFalse)
5069               ThrowMogrifyInvalidArgumentException(option,argv[i]);
5070             break;
5071           }
5072         if (LocaleCompare("median",option+1) == 0)
5073           {
5074             if (*option == '+')
5075               break;
5076             i++;
5077             if (i == (ssize_t) argc)
5078               ThrowMogrifyException(OptionError,"MissingArgument",option);
5079             if (IsGeometry(argv[i]) == MagickFalse)
5080               ThrowMogrifyInvalidArgumentException(option,argv[i]);
5081             break;
5082           }
5083         if (LocaleCompare("mode",option+1) == 0)
5084           {
5085             if (*option == '+')
5086               break;
5087             i++;
5088             if (i == (ssize_t) argc)
5089               ThrowMogrifyException(OptionError,"MissingArgument",option);
5090             if (IsGeometry(argv[i]) == MagickFalse)
5091               ThrowMogrifyInvalidArgumentException(option,argv[i]);
5092             break;
5093           }
5094         if (LocaleCompare("monitor",option+1) == 0)
5095           break;
5096         if (LocaleCompare("monochrome",option+1) == 0)
5097           break;
5098         if (LocaleCompare("morph",option+1) == 0)
5099           {
5100             if (*option == '+')
5101               break;
5102             i++;
5103             if (i == (ssize_t) (argc-1))
5104               ThrowMogrifyException(OptionError,"MissingArgument",option);
5105             if (IsGeometry(argv[i]) == MagickFalse)
5106               ThrowMogrifyInvalidArgumentException(option,argv[i]);
5107             break;
5108           }
5109         if (LocaleCompare("morphology",option+1) == 0)
5110           {
5111             char
5112               token[MaxTextExtent];
5113
5114             KernelInfo
5115               *kernel_info;
5116
5117             ssize_t
5118               op;
5119
5120             i++;
5121             if (i == (ssize_t) argc)
5122               ThrowMogrifyException(OptionError,"MissingArgument",option);
5123             GetMagickToken(argv[i],NULL,token);
5124             op=ParseCommandOption(MagickMorphologyOptions,MagickFalse,token);
5125             if (op < 0)
5126               ThrowMogrifyException(OptionError,"UnrecognizedMorphologyMethod",
5127                 token);
5128             i++;
5129             if (i == (ssize_t) (argc-1))
5130               ThrowMogrifyException(OptionError,"MissingArgument",option);
5131             kernel_info=AcquireKernelInfo(argv[i]);
5132             if (kernel_info == (KernelInfo *) NULL)
5133               ThrowMogrifyInvalidArgumentException(option,argv[i]);
5134             kernel_info=DestroyKernelInfo(kernel_info);
5135             break;
5136           }
5137         if (LocaleCompare("mosaic",option+1) == 0)
5138           break;
5139         if (LocaleCompare("motion-blur",option+1) == 0)
5140           {
5141             if (*option == '+')
5142               break;
5143             i++;
5144             if (i == (ssize_t) argc)
5145               ThrowMogrifyException(OptionError,"MissingArgument",option);
5146             if (IsGeometry(argv[i]) == MagickFalse)
5147               ThrowMogrifyInvalidArgumentException(option,argv[i]);
5148             break;
5149           }
5150         ThrowMogrifyException(OptionError,"UnrecognizedOption",option)
5151       }
5152       case 'n':
5153       {
5154         if (LocaleCompare("negate",option+1) == 0)
5155           break;
5156         if (LocaleCompare("noise",option+1) == 0)
5157           {
5158             i++;
5159             if (i == (ssize_t) argc)
5160               ThrowMogrifyException(OptionError,"MissingArgument",option);
5161             if (*option == '+')
5162               {
5163                 ssize_t
5164                   noise;
5165
5166                 noise=ParseCommandOption(MagickNoiseOptions,MagickFalse,argv[i]);
5167                 if (noise < 0)
5168                   ThrowMogrifyException(OptionError,"UnrecognizedNoiseType",
5169                     argv[i]);
5170                 break;
5171               }
5172             if (IsGeometry(argv[i]) == MagickFalse)
5173               ThrowMogrifyInvalidArgumentException(option,argv[i]);
5174             break;
5175           }
5176         if (LocaleCompare("noop",option+1) == 0)
5177           break;
5178         if (LocaleCompare("normalize",option+1) == 0)
5179           break;
5180         ThrowMogrifyException(OptionError,"UnrecognizedOption",option)
5181       }
5182       case 'o':
5183       {
5184         if (LocaleCompare("opaque",option+1) == 0)
5185           {
5186             i++;
5187             if (i == (ssize_t) argc)
5188               ThrowMogrifyException(OptionError,"MissingArgument",option);
5189             break;
5190           }
5191         if (LocaleCompare("ordered-dither",option+1) == 0)
5192           {
5193             if (*option == '+')
5194               break;
5195             i++;
5196             if (i == (ssize_t) argc)
5197               ThrowMogrifyException(OptionError,"MissingArgument",option);
5198             break;
5199           }
5200         if (LocaleCompare("orient",option+1) == 0)
5201           {
5202             ssize_t
5203               orientation;
5204
5205             orientation=UndefinedOrientation;
5206             if (*option == '+')
5207               break;
5208             i++;
5209             if (i == (ssize_t) (argc-1))
5210               ThrowMogrifyException(OptionError,"MissingArgument",option);
5211             orientation=ParseCommandOption(MagickOrientationOptions,MagickFalse,
5212               argv[i]);
5213             if (orientation < 0)
5214               ThrowMogrifyException(OptionError,"UnrecognizedImageOrientation",
5215                 argv[i]);
5216             break;
5217           }
5218         ThrowMogrifyException(OptionError,"UnrecognizedOption",option)
5219       }
5220       case 'p':
5221       {
5222         if (LocaleCompare("page",option+1) == 0)
5223           {
5224             if (*option == '+')
5225               break;
5226             i++;
5227             if (i == (ssize_t) argc)
5228               ThrowMogrifyException(OptionError,"MissingArgument",option);
5229             break;
5230           }
5231         if (LocaleCompare("paint",option+1) == 0)
5232           {
5233             if (*option == '+')
5234               break;
5235             i++;
5236             if (i == (ssize_t) argc)
5237               ThrowMogrifyException(OptionError,"MissingArgument",option);
5238             if (IsGeometry(argv[i]) == MagickFalse)
5239               ThrowMogrifyInvalidArgumentException(option,argv[i]);
5240             break;
5241           }
5242         if (LocaleCompare("path",option+1) == 0)
5243           {
5244             (void) CloneString(&path,(char *) NULL);
5245             if (*option == '+')
5246               break;
5247             i++;
5248             if (i == (ssize_t) argc)
5249               ThrowMogrifyException(OptionError,"MissingArgument",option);
5250             (void) CloneString(&path,argv[i]);
5251             break;
5252           }
5253         if (LocaleCompare("pointsize",option+1) == 0)
5254           {
5255             if (*option == '+')
5256               break;
5257             i++;
5258             if (i == (ssize_t) argc)
5259               ThrowMogrifyException(OptionError,"MissingArgument",option);
5260             if (IsGeometry(argv[i]) == MagickFalse)
5261               ThrowMogrifyInvalidArgumentException(option,argv[i]);
5262             break;
5263           }
5264         if (LocaleCompare("polaroid",option+1) == 0)
5265           {
5266             if (*option == '+')
5267               break;
5268             i++;
5269             if (i == (ssize_t) argc)
5270               ThrowMogrifyException(OptionError,"MissingArgument",option);
5271             if (IsGeometry(argv[i]) == MagickFalse)
5272               ThrowMogrifyInvalidArgumentException(option,argv[i]);
5273             break;
5274           }
5275         if (LocaleCompare("posterize",option+1) == 0)
5276           {
5277             if (*option == '+')
5278               break;
5279             i++;
5280             if (i == (ssize_t) argc)
5281               ThrowMogrifyException(OptionError,"MissingArgument",option);
5282             if (IsGeometry(argv[i]) == MagickFalse)
5283               ThrowMogrifyInvalidArgumentException(option,argv[i]);
5284             break;
5285           }
5286         if (LocaleCompare("precision",option+1) == 0)
5287           {
5288             if (*option == '+')
5289               break;
5290             i++;
5291             if (i == (ssize_t) argc)
5292               ThrowMogrifyException(OptionError,"MissingArgument",option);
5293             if (IsGeometry(argv[i]) == MagickFalse)
5294               ThrowMogrifyInvalidArgumentException(option,argv[i]);
5295             break;
5296           }
5297         if (LocaleCompare("print",option+1) == 0)
5298           {
5299             if (*option == '+')
5300               break;
5301             i++;
5302             if (i == (ssize_t) argc)
5303               ThrowMogrifyException(OptionError,"MissingArgument",option);
5304             break;
5305           }
5306         if (LocaleCompare("process",option+1) == 0)
5307           {
5308             if (*option == '+')
5309               break;
5310             i++;
5311             if (i == (ssize_t) (argc-1))
5312               ThrowMogrifyException(OptionError,"MissingArgument",option);
5313             break;
5314           }
5315         if (LocaleCompare("profile",option+1) == 0)
5316           {
5317             i++;
5318             if (i == (ssize_t) argc)
5319               ThrowMogrifyException(OptionError,"MissingArgument",option);
5320             break;
5321           }
5322         ThrowMogrifyException(OptionError,"UnrecognizedOption",option)
5323       }
5324       case 'q':
5325       {
5326         if (LocaleCompare("quality",option+1) == 0)
5327           {
5328             if (*option == '+')
5329               break;
5330             i++;
5331             if (i == (ssize_t) argc)
5332               ThrowMogrifyException(OptionError,"MissingArgument",option);
5333             if (IsGeometry(argv[i]) == MagickFalse)
5334               ThrowMogrifyInvalidArgumentException(option,argv[i]);
5335             break;
5336           }
5337         if (LocaleCompare("quantize",option+1) == 0)
5338           {
5339             ssize_t
5340               colorspace;
5341
5342             if (*option == '+')
5343               break;
5344             i++;
5345             if (i == (ssize_t) (argc-1))
5346               ThrowMogrifyException(OptionError,"MissingArgument",option);
5347             colorspace=ParseCommandOption(MagickColorspaceOptions,MagickFalse,
5348               argv[i]);
5349             if (colorspace < 0)
5350               ThrowMogrifyException(OptionError,"UnrecognizedColorspace",
5351                 argv[i]);
5352             break;
5353           }
5354         if (LocaleCompare("quiet",option+1) == 0)
5355           break;
5356         ThrowMogrifyException(OptionError,"UnrecognizedOption",option)
5357       }
5358       case 'r':
5359       {
5360         if (LocaleCompare("radial-blur",option+1) == 0)
5361           {
5362             i++;
5363             if (i == (ssize_t) argc)
5364               ThrowMogrifyException(OptionError,"MissingArgument",option);
5365             if (IsGeometry(argv[i]) == MagickFalse)
5366               ThrowMogrifyInvalidArgumentException(option,argv[i]);
5367             break;
5368           }
5369         if (LocaleCompare("raise",option+1) == 0)
5370           {
5371             i++;
5372             if (i == (ssize_t) argc)
5373               ThrowMogrifyException(OptionError,"MissingArgument",option);
5374             if (IsGeometry(argv[i]) == MagickFalse)
5375               ThrowMogrifyInvalidArgumentException(option,argv[i]);
5376             break;
5377           }
5378         if (LocaleCompare("random-threshold",option+1) == 0)
5379           {
5380             if (*option == '+')
5381               break;
5382             i++;
5383             if (i == (ssize_t) argc)
5384               ThrowMogrifyException(OptionError,"MissingArgument",option);
5385             if (IsGeometry(argv[i]) == MagickFalse)
5386               ThrowMogrifyInvalidArgumentException(option,argv[i]);
5387             break;
5388           }
5389         if (LocaleCompare("recolor",option+1) == 0)
5390           {
5391             if (*option == '+')
5392               break;
5393             i++;
5394             if (i == (ssize_t) (argc-1))
5395               ThrowMogrifyException(OptionError,"MissingArgument",option);
5396             if (IsGeometry(argv[i]) == MagickFalse)
5397               ThrowMogrifyInvalidArgumentException(option,argv[i]);
5398             break;
5399           }
5400         if (LocaleCompare("red-primary",option+1) == 0)
5401           {
5402             if (*option == '+')
5403               break;
5404             i++;
5405             if (i == (ssize_t) argc)
5406               ThrowMogrifyException(OptionError,"MissingArgument",option);
5407             if (IsGeometry(argv[i]) == MagickFalse)
5408               ThrowMogrifyInvalidArgumentException(option,argv[i]);
5409           }
5410         if (LocaleCompare("regard-warnings",option+1) == 0)
5411           break;
5412         if (LocaleCompare("region",option+1) == 0)
5413           {
5414             if (*option == '+')
5415               break;
5416             i++;
5417             if (i == (ssize_t) argc)
5418               ThrowMogrifyException(OptionError,"MissingArgument",option);
5419             if (IsGeometry(argv[i]) == MagickFalse)
5420               ThrowMogrifyInvalidArgumentException(option,argv[i]);
5421             break;
5422           }
5423         if (LocaleCompare("remap",option+1) == 0)
5424           {
5425             if (*option == '+')
5426               break;
5427             i++;
5428             if (i == (ssize_t) (argc-1))
5429               ThrowMogrifyException(OptionError,"MissingArgument",option);
5430             break;
5431           }
5432         if (LocaleCompare("render",option+1) == 0)
5433           break;
5434         if (LocaleCompare("repage",option+1) == 0)
5435           {
5436             if (*option == '+')
5437               break;
5438             i++;
5439             if (i == (ssize_t) argc)
5440               ThrowMogrifyException(OptionError,"MissingArgument",option);
5441             if (IsGeometry(argv[i]) == MagickFalse)
5442               ThrowMogrifyInvalidArgumentException(option,argv[i]);
5443             break;
5444           }
5445         if (LocaleCompare("resample",option+1) == 0)
5446           {
5447             if (*option == '+')
5448               break;
5449             i++;
5450             if (i == (ssize_t) argc)
5451               ThrowMogrifyException(OptionError,"MissingArgument",option);
5452             if (IsGeometry(argv[i]) == MagickFalse)
5453               ThrowMogrifyInvalidArgumentException(option,argv[i]);
5454             break;
5455           }
5456         if (LocaleCompare("resize",option+1) == 0)
5457           {
5458             if (*option == '+')
5459               break;
5460             i++;
5461             if (i == (ssize_t) argc)
5462               ThrowMogrifyException(OptionError,"MissingArgument",option);
5463             if (IsGeometry(argv[i]) == MagickFalse)
5464               ThrowMogrifyInvalidArgumentException(option,argv[i]);
5465             break;
5466           }
5467         if (LocaleNCompare("respect-parentheses",option+1,17) == 0)
5468           {
5469             respect_parenthesis=(*option == '-') ? MagickTrue : MagickFalse;
5470             break;
5471           }
5472         if (LocaleCompare("reverse",option+1) == 0)
5473           break;
5474         if (LocaleCompare("roll",option+1) == 0)
5475           {
5476             if (*option == '+')
5477               break;
5478             i++;
5479             if (i == (ssize_t) argc)
5480               ThrowMogrifyException(OptionError,"MissingArgument",option);
5481             if (IsGeometry(argv[i]) == MagickFalse)
5482               ThrowMogrifyInvalidArgumentException(option,argv[i]);
5483             break;
5484           }
5485         if (LocaleCompare("rotate",option+1) == 0)
5486           {
5487             i++;
5488             if (i == (ssize_t) argc)
5489               ThrowMogrifyException(OptionError,"MissingArgument",option);
5490             if (IsGeometry(argv[i]) == MagickFalse)
5491               ThrowMogrifyInvalidArgumentException(option,argv[i]);
5492             break;
5493           }
5494         ThrowMogrifyException(OptionError,"UnrecognizedOption",option)
5495       }
5496       case 's':
5497       {
5498         if (LocaleCompare("sample",option+1) == 0)
5499           {
5500             if (*option == '+')
5501               break;
5502             i++;
5503             if (i == (ssize_t) argc)
5504               ThrowMogrifyException(OptionError,"MissingArgument",option);
5505             if (IsGeometry(argv[i]) == MagickFalse)
5506               ThrowMogrifyInvalidArgumentException(option,argv[i]);
5507             break;
5508           }
5509         if (LocaleCompare("sampling-factor",option+1) == 0)
5510           {
5511             if (*option == '+')
5512               break;
5513             i++;
5514             if (i == (ssize_t) argc)
5515               ThrowMogrifyException(OptionError,"MissingArgument",option);
5516             if (IsGeometry(argv[i]) == MagickFalse)
5517               ThrowMogrifyInvalidArgumentException(option,argv[i]);
5518             break;
5519           }
5520         if (LocaleCompare("scale",option+1) == 0)
5521           {
5522             if (*option == '+')
5523               break;
5524             i++;
5525             if (i == (ssize_t) argc)
5526               ThrowMogrifyException(OptionError,"MissingArgument",option);
5527             if (IsGeometry(argv[i]) == MagickFalse)
5528               ThrowMogrifyInvalidArgumentException(option,argv[i]);
5529             break;
5530           }
5531         if (LocaleCompare("scene",option+1) == 0)
5532           {
5533             if (*option == '+')
5534               break;
5535             i++;
5536             if (i == (ssize_t) argc)
5537               ThrowMogrifyException(OptionError,"MissingArgument",option);
5538             if (IsGeometry(argv[i]) == MagickFalse)
5539               ThrowMogrifyInvalidArgumentException(option,argv[i]);
5540             break;
5541           }
5542         if (LocaleCompare("seed",option+1) == 0)
5543           {
5544             if (*option == '+')
5545               break;
5546             i++;
5547             if (i == (ssize_t) argc)
5548               ThrowMogrifyException(OptionError,"MissingArgument",option);
5549             if (IsGeometry(argv[i]) == MagickFalse)
5550               ThrowMogrifyInvalidArgumentException(option,argv[i]);
5551             break;
5552           }
5553         if (LocaleCompare("segment",option+1) == 0)
5554           {
5555             if (*option == '+')
5556               break;
5557             i++;
5558             if (i == (ssize_t) argc)
5559               ThrowMogrifyException(OptionError,"MissingArgument",option);
5560             if (IsGeometry(argv[i]) == MagickFalse)
5561               ThrowMogrifyInvalidArgumentException(option,argv[i]);
5562             break;
5563           }
5564         if (LocaleCompare("selective-blur",option+1) == 0)
5565           {
5566             i++;
5567             if (i == (ssize_t) argc)
5568               ThrowMogrifyException(OptionError,"MissingArgument",option);
5569             if (IsGeometry(argv[i]) == MagickFalse)
5570               ThrowMogrifyInvalidArgumentException(option,argv[i]);
5571             break;
5572           }
5573         if (LocaleCompare("separate",option+1) == 0)
5574           break;
5575         if (LocaleCompare("sepia-tone",option+1) == 0)
5576           {
5577             if (*option == '+')
5578               break;
5579             i++;
5580             if (i == (ssize_t) argc)
5581               ThrowMogrifyException(OptionError,"MissingArgument",option);
5582             if (IsGeometry(argv[i]) == MagickFalse)
5583               ThrowMogrifyInvalidArgumentException(option,argv[i]);
5584             break;
5585           }
5586         if (LocaleCompare("set",option+1) == 0)
5587           {
5588             i++;
5589             if (i == (ssize_t) argc)
5590               ThrowMogrifyException(OptionError,"MissingArgument",option);
5591             if (*option == '+')
5592               break;
5593             i++;
5594             if (i == (ssize_t) argc)
5595               ThrowMogrifyException(OptionError,"MissingArgument",option);
5596             break;
5597           }
5598         if (LocaleCompare("shade",option+1) == 0)
5599           {
5600             i++;
5601             if (i == (ssize_t) argc)
5602               ThrowMogrifyException(OptionError,"MissingArgument",option);
5603             if (IsGeometry(argv[i]) == MagickFalse)
5604               ThrowMogrifyInvalidArgumentException(option,argv[i]);
5605             break;
5606           }
5607         if (LocaleCompare("shadow",option+1) == 0)
5608           {
5609             if (*option == '+')
5610               break;
5611             i++;
5612             if (i == (ssize_t) argc)
5613               ThrowMogrifyException(OptionError,"MissingArgument",option);
5614             if (IsGeometry(argv[i]) == MagickFalse)
5615               ThrowMogrifyInvalidArgumentException(option,argv[i]);
5616             break;
5617           }
5618         if (LocaleCompare("sharpen",option+1) == 0)
5619           {
5620             i++;
5621             if (i == (ssize_t) argc)
5622               ThrowMogrifyException(OptionError,"MissingArgument",option);
5623             if (IsGeometry(argv[i]) == MagickFalse)
5624               ThrowMogrifyInvalidArgumentException(option,argv[i]);
5625             break;
5626           }
5627         if (LocaleCompare("shave",option+1) == 0)
5628           {
5629             if (*option == '+')
5630               break;
5631             i++;
5632             if (i == (ssize_t) argc)
5633               ThrowMogrifyException(OptionError,"MissingArgument",option);
5634             if (IsGeometry(argv[i]) == MagickFalse)
5635               ThrowMogrifyInvalidArgumentException(option,argv[i]);
5636             break;
5637           }
5638         if (LocaleCompare("shear",option+1) == 0)
5639           {
5640             i++;
5641             if (i == (ssize_t) argc)
5642               ThrowMogrifyException(OptionError,"MissingArgument",option);
5643             if (IsGeometry(argv[i]) == MagickFalse)
5644               ThrowMogrifyInvalidArgumentException(option,argv[i]);
5645             break;
5646           }
5647         if (LocaleCompare("sigmoidal-contrast",option+1) == 0)
5648           {
5649             i++;
5650             if (i == (ssize_t) (argc-1))
5651               ThrowMogrifyException(OptionError,"MissingArgument",option);
5652             if (IsGeometry(argv[i]) == MagickFalse)
5653               ThrowMogrifyInvalidArgumentException(option,argv[i]);
5654             break;
5655           }
5656         if (LocaleCompare("size",option+1) == 0)
5657           {
5658             if (*option == '+')
5659               break;
5660             i++;
5661             if (i == (ssize_t) argc)
5662               ThrowMogrifyException(OptionError,"MissingArgument",option);
5663             if (IsGeometry(argv[i]) == MagickFalse)
5664               ThrowMogrifyInvalidArgumentException(option,argv[i]);
5665             break;
5666           }
5667         if (LocaleCompare("sketch",option+1) == 0)
5668           {
5669             if (*option == '+')
5670               break;
5671             i++;
5672             if (i == (ssize_t) argc)
5673               ThrowMogrifyException(OptionError,"MissingArgument",option);
5674             if (IsGeometry(argv[i]) == MagickFalse)
5675               ThrowMogrifyInvalidArgumentException(option,argv[i]);
5676             break;
5677           }
5678         if (LocaleCompare("smush",option+1) == 0)
5679           {
5680             i++;
5681             if (i == (ssize_t) argc)
5682               ThrowMogrifyException(OptionError,"MissingArgument",option);
5683             if (IsGeometry(argv[i]) == MagickFalse)
5684               ThrowMogrifyInvalidArgumentException(option,argv[i]);
5685             i++;
5686             break;
5687           }
5688         if (LocaleCompare("solarize",option+1) == 0)
5689           {
5690             if (*option == '+')
5691               break;
5692             i++;
5693             if (i == (ssize_t) argc)
5694               ThrowMogrifyException(OptionError,"MissingArgument",option);
5695             if (IsGeometry(argv[i]) == MagickFalse)
5696               ThrowMogrifyInvalidArgumentException(option,argv[i]);
5697             break;
5698           }
5699         if (LocaleCompare("sparse-color",option+1) == 0)
5700           {
5701             ssize_t
5702               op;
5703
5704             i++;
5705             if (i == (ssize_t) argc)
5706               ThrowMogrifyException(OptionError,"MissingArgument",option);
5707             op=ParseCommandOption(MagickSparseColorOptions,MagickFalse,argv[i]);
5708             if (op < 0)
5709               ThrowMogrifyException(OptionError,"UnrecognizedSparseColorMethod",
5710                 argv[i]);
5711             i++;
5712             if (i == (ssize_t) (argc-1))
5713               ThrowMogrifyException(OptionError,"MissingArgument",option);
5714             break;
5715           }
5716         if (LocaleCompare("spread",option+1) == 0)
5717           {
5718             if (*option == '+')
5719               break;
5720             i++;
5721             if (i == (ssize_t) argc)
5722               ThrowMogrifyException(OptionError,"MissingArgument",option);
5723             if (IsGeometry(argv[i]) == MagickFalse)
5724               ThrowMogrifyInvalidArgumentException(option,argv[i]);
5725             break;
5726           }
5727         if (LocaleCompare("statistic",option+1) == 0)
5728           {
5729             ssize_t
5730               op;
5731
5732             if (*option == '+')
5733               break;
5734             i++;
5735             if (i == (ssize_t) argc)
5736               ThrowMogrifyException(OptionError,"MissingArgument",option);
5737             op=ParseCommandOption(MagickStatisticOptions,MagickFalse,argv[i]);
5738             if (op < 0)
5739               ThrowMogrifyException(OptionError,"UnrecognizedStatisticType",
5740                 argv[i]);
5741             i++;
5742             if (i == (ssize_t) (argc-1))
5743               ThrowMogrifyException(OptionError,"MissingArgument",option);
5744             if (IsGeometry(argv[i]) == MagickFalse)
5745               ThrowMogrifyInvalidArgumentException(option,argv[i]);
5746             break;
5747           }
5748         if (LocaleCompare("stretch",option+1) == 0)
5749           {
5750             ssize_t
5751               stretch;
5752
5753             if (*option == '+')
5754               break;
5755             i++;
5756             if (i == (ssize_t) (argc-1))
5757               ThrowMogrifyException(OptionError,"MissingArgument",option);
5758             stretch=ParseCommandOption(MagickStretchOptions,MagickFalse,argv[i]);
5759             if (stretch < 0)
5760               ThrowMogrifyException(OptionError,"UnrecognizedStyleType",
5761                 argv[i]);
5762             break;
5763           }
5764         if (LocaleCompare("strip",option+1) == 0)
5765           break;
5766         if (LocaleCompare("stroke",option+1) == 0)
5767           {
5768             if (*option == '+')
5769               break;
5770             i++;
5771             if (i == (ssize_t) argc)
5772               ThrowMogrifyException(OptionError,"MissingArgument",option);
5773             break;
5774           }
5775         if (LocaleCompare("strokewidth",option+1) == 0)
5776           {
5777             if (*option == '+')
5778               break;
5779             i++;
5780             if (i == (ssize_t) argc)
5781               ThrowMogrifyException(OptionError,"MissingArgument",option);
5782             if (IsGeometry(argv[i]) == MagickFalse)
5783               ThrowMogrifyInvalidArgumentException(option,argv[i]);
5784             break;
5785           }
5786         if (LocaleCompare("style",option+1) == 0)
5787           {
5788             ssize_t
5789               style;
5790
5791             if (*option == '+')
5792               break;
5793             i++;
5794             if (i == (ssize_t) (argc-1))
5795               ThrowMogrifyException(OptionError,"MissingArgument",option);
5796             style=ParseCommandOption(MagickStyleOptions,MagickFalse,argv[i]);
5797             if (style < 0)
5798               ThrowMogrifyException(OptionError,"UnrecognizedStyleType",
5799                 argv[i]);
5800             break;
5801           }
5802         if (LocaleCompare("swap",option+1) == 0)
5803           {
5804             if (*option == '+')
5805               break;
5806             i++;
5807             if (i == (ssize_t) (argc-1))
5808               ThrowMogrifyException(OptionError,"MissingArgument",option);
5809             if (IsGeometry(argv[i]) == MagickFalse)
5810               ThrowMogrifyInvalidArgumentException(option,argv[i]);
5811             break;
5812           }
5813         if (LocaleCompare("swirl",option+1) == 0)
5814           {
5815             if (*option == '+')
5816               break;
5817             i++;
5818             if (i == (ssize_t) argc)
5819               ThrowMogrifyException(OptionError,"MissingArgument",option);
5820             if (IsGeometry(argv[i]) == MagickFalse)
5821               ThrowMogrifyInvalidArgumentException(option,argv[i]);
5822             break;
5823           }
5824         if (LocaleCompare("synchronize",option+1) == 0)
5825           break;
5826         ThrowMogrifyException(OptionError,"UnrecognizedOption",option)
5827       }
5828       case 't':
5829       {
5830         if (LocaleCompare("taint",option+1) == 0)
5831           break;
5832         if (LocaleCompare("texture",option+1) == 0)
5833           {
5834             if (*option == '+')
5835               break;
5836             i++;
5837             if (i == (ssize_t) argc)
5838               ThrowMogrifyException(OptionError,"MissingArgument",option);
5839             break;
5840           }
5841         if (LocaleCompare("tile",option+1) == 0)
5842           {
5843             if (*option == '+')
5844               break;
5845             i++;
5846             if (i == (ssize_t) (argc-1))
5847               ThrowMogrifyException(OptionError,"MissingArgument",option);
5848             break;
5849           }
5850         if (LocaleCompare("tile-offset",option+1) == 0)
5851           {
5852             if (*option == '+')
5853               break;
5854             i++;
5855             if (i == (ssize_t) argc)
5856               ThrowMogrifyException(OptionError,"MissingArgument",option);
5857             if (IsGeometry(argv[i]) == MagickFalse)
5858               ThrowMogrifyInvalidArgumentException(option,argv[i]);
5859             break;
5860           }
5861         if (LocaleCompare("tint",option+1) == 0)
5862           {
5863             if (*option == '+')
5864               break;
5865             i++;
5866             if (i == (ssize_t) (argc-1))
5867               ThrowMogrifyException(OptionError,"MissingArgument",option);
5868             if (IsGeometry(argv[i]) == MagickFalse)
5869               ThrowMogrifyInvalidArgumentException(option,argv[i]);
5870             break;
5871           }
5872         if (LocaleCompare("transform",option+1) == 0)
5873           break;
5874         if (LocaleCompare("transpose",option+1) == 0)
5875           break;
5876         if (LocaleCompare("transverse",option+1) == 0)
5877           break;
5878         if (LocaleCompare("threshold",option+1) == 0)
5879           {
5880             if (*option == '+')
5881               break;
5882             i++;
5883             if (i == (ssize_t) argc)
5884               ThrowMogrifyException(OptionError,"MissingArgument",option);
5885             if (IsGeometry(argv[i]) == MagickFalse)
5886               ThrowMogrifyInvalidArgumentException(option,argv[i]);
5887             break;
5888           }
5889         if (LocaleCompare("thumbnail",option+1) == 0)
5890           {
5891             if (*option == '+')
5892               break;
5893             i++;
5894             if (i == (ssize_t) argc)
5895               ThrowMogrifyException(OptionError,"MissingArgument",option);
5896             if (IsGeometry(argv[i]) == MagickFalse)
5897               ThrowMogrifyInvalidArgumentException(option,argv[i]);
5898             break;
5899           }
5900         if (LocaleCompare("transparent",option+1) == 0)
5901           {
5902             i++;
5903             if (i == (ssize_t) argc)
5904               ThrowMogrifyException(OptionError,"MissingArgument",option);
5905             break;
5906           }
5907         if (LocaleCompare("transparent-color",option+1) == 0)
5908           {
5909             if (*option == '+')
5910               break;
5911             i++;
5912             if (i == (ssize_t) (argc-1))
5913               ThrowMogrifyException(OptionError,"MissingArgument",option);
5914             break;
5915           }
5916         if (LocaleCompare("treedepth",option+1) == 0)
5917           {
5918             if (*option == '+')
5919               break;
5920             i++;
5921             if (i == (ssize_t) argc)
5922               ThrowMogrifyException(OptionError,"MissingArgument",option);
5923             if (IsGeometry(argv[i]) == MagickFalse)
5924               ThrowMogrifyInvalidArgumentException(option,argv[i]);
5925             break;
5926           }
5927         if (LocaleCompare("trim",option+1) == 0)
5928           break;
5929         if (LocaleCompare("type",option+1) == 0)
5930           {
5931             ssize_t
5932               type;
5933
5934             if (*option == '+')
5935               break;
5936             i++;
5937             if (i == (ssize_t) argc)
5938               ThrowMogrifyException(OptionError,"MissingArgument",option);
5939             type=ParseCommandOption(MagickTypeOptions,MagickFalse,argv[i]);
5940             if (type < 0)
5941               ThrowMogrifyException(OptionError,"UnrecognizedImageType",
5942                 argv[i]);
5943             break;
5944           }
5945         ThrowMogrifyException(OptionError,"UnrecognizedOption",option)
5946       }
5947       case 'u':
5948       {
5949         if (LocaleCompare("undercolor",option+1) == 0)
5950           {
5951             if (*option == '+')
5952               break;
5953             i++;
5954             if (i == (ssize_t) argc)
5955               ThrowMogrifyException(OptionError,"MissingArgument",option);
5956             break;
5957           }
5958         if (LocaleCompare("unique-colors",option+1) == 0)
5959           break;
5960         if (LocaleCompare("units",option+1) == 0)
5961           {
5962             ssize_t
5963               units;
5964
5965             if (*option == '+')
5966               break;
5967             i++;
5968             if (i == (ssize_t) argc)
5969               ThrowMogrifyException(OptionError,"MissingArgument",option);
5970             units=ParseCommandOption(MagickResolutionOptions,MagickFalse,
5971               argv[i]);
5972             if (units < 0)
5973               ThrowMogrifyException(OptionError,"UnrecognizedUnitsType",
5974                 argv[i]);
5975             break;
5976           }
5977         if (LocaleCompare("unsharp",option+1) == 0)
5978           {
5979             i++;
5980             if (i == (ssize_t) argc)
5981               ThrowMogrifyException(OptionError,"MissingArgument",option);
5982             if (IsGeometry(argv[i]) == MagickFalse)
5983               ThrowMogrifyInvalidArgumentException(option,argv[i]);
5984             break;
5985           }
5986         ThrowMogrifyException(OptionError,"UnrecognizedOption",option)
5987       }
5988       case 'v':
5989       {
5990         if (LocaleCompare("verbose",option+1) == 0)
5991           {
5992             image_info->verbose=(*option == '-') ? MagickTrue : MagickFalse;
5993             break;
5994           }
5995         if ((LocaleCompare("version",option+1) == 0) ||
5996             (LocaleCompare("-version",option+1) == 0))
5997           {
5998             (void) FormatLocaleFile(stdout,"Version: %s\n",
5999               GetMagickVersion((size_t *) NULL));
6000             (void) FormatLocaleFile(stdout,"Copyright: %s\n",
6001               GetMagickCopyright());
6002             (void) FormatLocaleFile(stdout,"Features: %s\n\n",
6003               GetMagickFeatures());
6004             break;
6005           }
6006         if (LocaleCompare("view",option+1) == 0)
6007           {
6008             if (*option == '+')
6009               break;
6010             i++;
6011             if (i == (ssize_t) argc)
6012               ThrowMogrifyException(OptionError,"MissingArgument",option);
6013             break;
6014           }
6015         if (LocaleCompare("vignette",option+1) == 0)
6016           {
6017             if (*option == '+')
6018               break;
6019             i++;
6020             if (i == (ssize_t) argc)
6021               ThrowMogrifyException(OptionError,"MissingArgument",option);
6022             if (IsGeometry(argv[i]) == MagickFalse)
6023               ThrowMogrifyInvalidArgumentException(option,argv[i]);
6024             break;
6025           }
6026         if (LocaleCompare("virtual-pixel",option+1) == 0)
6027           {
6028             ssize_t
6029               method;
6030
6031             if (*option == '+')
6032               break;
6033             i++;
6034             if (i == (ssize_t) argc)
6035               ThrowMogrifyException(OptionError,"MissingArgument",option);
6036             method=ParseCommandOption(MagickVirtualPixelOptions,MagickFalse,
6037               argv[i]);
6038             if (method < 0)
6039               ThrowMogrifyException(OptionError,
6040                 "UnrecognizedVirtualPixelMethod",argv[i]);
6041             break;
6042           }
6043         ThrowMogrifyException(OptionError,"UnrecognizedOption",option)
6044       }
6045       case 'w':
6046       {
6047         if (LocaleCompare("wave",option+1) == 0)
6048           {
6049             i++;
6050             if (i == (ssize_t) argc)
6051               ThrowMogrifyException(OptionError,"MissingArgument",option);
6052             if (IsGeometry(argv[i]) == MagickFalse)
6053               ThrowMogrifyInvalidArgumentException(option,argv[i]);
6054             break;
6055           }
6056         if (LocaleCompare("weight",option+1) == 0)
6057           {
6058             if (*option == '+')
6059               break;
6060             i++;
6061             if (i == (ssize_t) (argc-1))
6062               ThrowMogrifyException(OptionError,"MissingArgument",option);
6063             break;
6064           }
6065         if (LocaleCompare("white-point",option+1) == 0)
6066           {
6067             if (*option == '+')
6068               break;
6069             i++;
6070             if (i == (ssize_t) argc)
6071               ThrowMogrifyException(OptionError,"MissingArgument",option);
6072             if (IsGeometry(argv[i]) == MagickFalse)
6073               ThrowMogrifyInvalidArgumentException(option,argv[i]);
6074             break;
6075           }
6076         if (LocaleCompare("white-threshold",option+1) == 0)
6077           {
6078             if (*option == '+')
6079               break;
6080             i++;
6081             if (i == (ssize_t) argc)
6082               ThrowMogrifyException(OptionError,"MissingArgument",option);
6083             if (IsGeometry(argv[i]) == MagickFalse)
6084               ThrowMogrifyInvalidArgumentException(option,argv[i]);
6085             break;
6086           }
6087         if (LocaleCompare("write",option+1) == 0)
6088           {
6089             i++;
6090             if (i == (ssize_t) (argc-1))
6091               ThrowMogrifyException(OptionError,"MissingArgument",option);
6092             break;
6093           }
6094         ThrowMogrifyException(OptionError,"UnrecognizedOption",option)
6095       }
6096       case '?':
6097         break;
6098       default:
6099         ThrowMogrifyException(OptionError,"UnrecognizedOption",option)
6100     }
6101     fire=(GetCommandOptionFlags(MagickCommandOptions,MagickFalse,option) &
6102       FireOptionFlag) == 0 ?  MagickFalse : MagickTrue;
6103     if (fire != MagickFalse)
6104       FireImageStack(MagickFalse,MagickTrue,MagickTrue);
6105   }
6106   if (k != 0)
6107     ThrowMogrifyException(OptionError,"UnbalancedParenthesis",argv[i]);
6108   if (i != (ssize_t) argc)
6109     ThrowMogrifyException(OptionError,"MissingAnImageFilename",argv[i]);
6110   DestroyMogrify();
6111   return(status != 0 ? MagickTrue : MagickFalse);
6112 }
6113 \f
6114 /*
6115 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6116 %                                                                             %
6117 %                                                                             %
6118 %                                                                             %
6119 +     M o g r i f y I m a g e I n f o                                         %
6120 %                                                                             %
6121 %                                                                             %
6122 %                                                                             %
6123 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6124 %
6125 %  MogrifyImageInfo() applies image processing settings to the image as
6126 %  prescribed by command line options.
6127 %
6128 %  The format of the MogrifyImageInfo method is:
6129 %
6130 %      MagickBooleanType MogrifyImageInfo(ImageInfo *image_info,const int argc,
6131 %        const char **argv,ExceptionInfo *exception)
6132 %
6133 %  A description of each parameter follows:
6134 %
6135 %    o image_info: the image info..
6136 %
6137 %    o argc: Specifies a pointer to an integer describing the number of
6138 %      elements in the argument vector.
6139 %
6140 %    o argv: Specifies a pointer to a text array containing the command line
6141 %      arguments.
6142 %
6143 %    o exception: return any errors or warnings in this structure.
6144 %
6145 */
6146 WandExport MagickBooleanType MogrifyImageInfo(ImageInfo *image_info,
6147   const int argc,const char **argv,ExceptionInfo *exception)
6148 {
6149   const char
6150     *option;
6151
6152   GeometryInfo
6153     geometry_info;
6154
6155   ssize_t
6156     count;
6157
6158   register ssize_t
6159     i;
6160
6161   /*
6162     Initialize method variables.
6163   */
6164   assert(image_info != (ImageInfo *) NULL);
6165   assert(image_info->signature == MagickSignature);
6166   if (image_info->debug != MagickFalse)
6167     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
6168       image_info->filename);
6169   if (argc < 0)
6170     return(MagickTrue);
6171   /*
6172     Set the image settings.
6173   */
6174   for (i=0; i < (ssize_t) argc; i++)
6175   {
6176     option=argv[i];
6177     if (IsCommandOption(option) == MagickFalse)
6178       continue;
6179     count=ParseCommandOption(MagickCommandOptions,MagickFalse,option);
6180     count=MagickMax(count,0L);
6181     if ((i+count) >= (ssize_t) argc)
6182       break;
6183     switch (*(option+1))
6184     {
6185       case 'a':
6186       {
6187         if (LocaleCompare("adjoin",option+1) == 0)
6188           {
6189             image_info->adjoin=(*option == '-') ? MagickTrue : MagickFalse;
6190             break;
6191           }
6192         if (LocaleCompare("antialias",option+1) == 0)
6193           {
6194             image_info->antialias=(*option == '-') ? MagickTrue : MagickFalse;
6195             break;
6196           }
6197         if (LocaleCompare("authenticate",option+1) == 0)
6198           {
6199             if (*option == '+')
6200               (void) DeleteImageOption(image_info,option+1);
6201             else
6202               (void) SetImageOption(image_info,option+1,argv[i+1]);
6203             break;
6204           }
6205         break;
6206       }
6207       case 'b':
6208       {
6209         if (LocaleCompare("background",option+1) == 0)
6210           {
6211             if (*option == '+')
6212               {
6213                 (void) DeleteImageOption(image_info,option+1);
6214                 (void) QueryColorCompliance(MogrifyBackgroundColor,
6215                   AllCompliance,&image_info->background_color,exception);
6216                 break;
6217               }
6218             (void) SetImageOption(image_info,option+1,argv[i+1]);
6219             (void) QueryColorCompliance(argv[i+1],AllCompliance,
6220               &image_info->background_color,exception);
6221             break;
6222           }
6223         if (LocaleCompare("bias",option+1) == 0)
6224           {
6225             if (*option == '+')
6226               {
6227                 (void) SetImageOption(image_info,option+1,"0.0");
6228                 break;
6229               }
6230             (void) SetImageOption(image_info,option+1,argv[i+1]);
6231             break;
6232           }
6233         if (LocaleCompare("black-point-compensation",option+1) == 0)
6234           {
6235             if (*option == '+')
6236               {
6237                 (void) SetImageOption(image_info,option+1,"false");
6238                 break;
6239               }
6240             (void) SetImageOption(image_info,option+1,"true");
6241             break;
6242           }
6243         if (LocaleCompare("blue-primary",option+1) == 0)
6244           {
6245             if (*option == '+')
6246               {
6247                 (void) SetImageOption(image_info,option+1,"0.0");
6248                 break;
6249               }
6250             (void) SetImageOption(image_info,option+1,argv[i+1]);
6251             break;
6252           }
6253         if (LocaleCompare("bordercolor",option+1) == 0)
6254           {
6255             if (*option == '+')
6256               {
6257                 (void) DeleteImageOption(image_info,option+1);
6258                 (void) QueryColorCompliance(MogrifyBorderColor,AllCompliance,
6259                   &image_info->border_color,exception);
6260                 break;
6261               }
6262             (void) QueryColorCompliance(argv[i+1],AllCompliance,
6263               &image_info->border_color,exception);
6264             (void) SetImageOption(image_info,option+1,argv[i+1]);
6265             break;
6266           }
6267         if (LocaleCompare("box",option+1) == 0)
6268           {
6269             if (*option == '+')
6270               {
6271                 (void) SetImageOption(image_info,"undercolor","none");
6272                 break;
6273               }
6274             (void) SetImageOption(image_info,"undercolor",argv[i+1]);
6275             break;
6276           }
6277         break;
6278       }
6279       case 'c':
6280       {
6281         if (LocaleCompare("cache",option+1) == 0)
6282           {
6283             MagickSizeType
6284               limit;
6285
6286             limit=MagickResourceInfinity;
6287             if (LocaleCompare("unlimited",argv[i+1]) != 0)
6288               limit=(MagickSizeType) SiPrefixToDoubleInterval(argv[i+1],
6289                 100.0);
6290             (void) SetMagickResourceLimit(MemoryResource,limit);
6291             (void) SetMagickResourceLimit(MapResource,2*limit);
6292             break;
6293           }
6294         if (LocaleCompare("caption",option+1) == 0)
6295           {
6296             if (*option == '+')
6297               {
6298                 (void) DeleteImageOption(image_info,option+1);
6299                 break;
6300               }
6301             (void) SetImageOption(image_info,option+1,argv[i+1]);
6302             break;
6303           }
6304         if (LocaleCompare("channel",option+1) == 0)
6305           {
6306             if (*option == '+')
6307               {
6308                 image_info->channel=DefaultChannels;
6309                 break;
6310               }
6311             image_info->channel=(ChannelType) ParseChannelOption(argv[i+1]);
6312             break;
6313           }
6314         if (LocaleCompare("colorspace",option+1) == 0)
6315           {
6316             if (*option == '+')
6317               {
6318                 image_info->colorspace=UndefinedColorspace;
6319                 (void) SetImageOption(image_info,option+1,"undefined");
6320                 break;
6321               }
6322             image_info->colorspace=(ColorspaceType) ParseCommandOption(
6323               MagickColorspaceOptions,MagickFalse,argv[i+1]);
6324             (void) SetImageOption(image_info,option+1,argv[i+1]);
6325             break;
6326           }
6327         if (LocaleCompare("comment",option+1) == 0)
6328           {
6329             if (*option == '+')
6330               {
6331                 (void) DeleteImageOption(image_info,option+1);
6332                 break;
6333               }
6334             (void) SetImageOption(image_info,option+1,argv[i+1]);
6335             break;
6336           }
6337         if (LocaleCompare("compose",option+1) == 0)
6338           {
6339             if (*option == '+')
6340               {
6341                 (void) SetImageOption(image_info,option+1,"undefined");
6342                 break;
6343               }
6344             (void) SetImageOption(image_info,option+1,argv[i+1]);
6345             break;
6346           }
6347         if (LocaleCompare("compress",option+1) == 0)
6348           {
6349             if (*option == '+')
6350               {
6351                 image_info->compression=UndefinedCompression;
6352                 (void) SetImageOption(image_info,option+1,"undefined");
6353                 break;
6354               }
6355             image_info->compression=(CompressionType) ParseCommandOption(
6356               MagickCompressOptions,MagickFalse,argv[i+1]);
6357             (void) SetImageOption(image_info,option+1,argv[i+1]);
6358             break;
6359           }
6360         break;
6361       }
6362       case 'd':
6363       {
6364         if (LocaleCompare("debug",option+1) == 0)
6365           {
6366             if (*option == '+')
6367               (void) SetLogEventMask("none");
6368             else
6369               (void) SetLogEventMask(argv[i+1]);
6370             image_info->debug=IsEventLogging();
6371             break;
6372           }
6373         if (LocaleCompare("define",option+1) == 0)
6374           {
6375             if (*option == '+')
6376               {
6377                 if (LocaleNCompare(argv[i+1],"registry:",9) == 0)
6378                   (void) DeleteImageRegistry(argv[i+1]+9);
6379                 else
6380                   (void) DeleteImageOption(image_info,argv[i+1]);
6381                 break;
6382               }
6383             if (LocaleNCompare(argv[i+1],"registry:",9) == 0)
6384               {
6385                 (void) DefineImageRegistry(StringRegistryType,argv[i+1]+9,
6386                   exception);
6387                 break;
6388               }
6389             (void) DefineImageOption(image_info,argv[i+1]);
6390             break;
6391           }
6392         if (LocaleCompare("delay",option+1) == 0)
6393           {
6394             if (*option == '+')
6395               {
6396                 (void) SetImageOption(image_info,option+1,"0");
6397                 break;
6398               }
6399             (void) SetImageOption(image_info,option+1,argv[i+1]);
6400             break;
6401           }
6402         if (LocaleCompare("density",option+1) == 0)
6403           {
6404             /*
6405               Set image density.
6406             */
6407             if (*option == '+')
6408               {
6409                 if (image_info->density != (char *) NULL)
6410                   image_info->density=DestroyString(image_info->density);
6411                 (void) SetImageOption(image_info,option+1,"72");
6412                 break;
6413               }
6414             (void) CloneString(&image_info->density,argv[i+1]);
6415             (void) SetImageOption(image_info,option+1,argv[i+1]);
6416             break;
6417           }
6418         if (LocaleCompare("depth",option+1) == 0)
6419           {
6420             if (*option == '+')
6421               {
6422                 image_info->depth=MAGICKCORE_QUANTUM_DEPTH;
6423                 break;
6424               }
6425             image_info->depth=StringToUnsignedLong(argv[i+1]);
6426             break;
6427           }
6428         if (LocaleCompare("direction",option+1) == 0)
6429           {
6430             if (*option == '+')
6431               {
6432                 (void) SetImageOption(image_info,option+1,"undefined");
6433                 break;
6434               }
6435             (void) SetImageOption(image_info,option+1,argv[i+1]);
6436             break;
6437           }
6438         if (LocaleCompare("display",option+1) == 0)
6439           {
6440             if (*option == '+')
6441               {
6442                 if (image_info->server_name != (char *) NULL)
6443                   image_info->server_name=DestroyString(
6444                     image_info->server_name);
6445                 break;
6446               }
6447             (void) CloneString(&image_info->server_name,argv[i+1]);
6448             break;
6449           }
6450         if (LocaleCompare("dispose",option+1) == 0)
6451           {
6452             if (*option == '+')
6453               {
6454                 (void) SetImageOption(image_info,option+1,"undefined");
6455                 break;
6456               }
6457             (void) SetImageOption(image_info,option+1,argv[i+1]);
6458             break;
6459           }
6460         if (LocaleCompare("dither",option+1) == 0)
6461           {
6462             if (*option == '+')
6463               {
6464                 image_info->dither=MagickFalse;
6465                 (void) SetImageOption(image_info,option+1,"none");
6466                 break;
6467               }
6468             (void) SetImageOption(image_info,option+1,argv[i+1]);
6469             image_info->dither=MagickTrue;
6470             break;
6471           }
6472         break;
6473       }
6474       case 'e':
6475       {
6476         if (LocaleCompare("encoding",option+1) == 0)
6477           {
6478             if (*option == '+')
6479               {
6480                 (void) SetImageOption(image_info,option+1,"undefined");
6481                 break;
6482               }
6483             (void) SetImageOption(image_info,option+1,argv[i+1]);
6484             break;
6485           }
6486         if (LocaleCompare("endian",option+1) == 0)
6487           {
6488             if (*option == '+')
6489               {
6490                 image_info->endian=UndefinedEndian;
6491                 (void) SetImageOption(image_info,option+1,"undefined");
6492                 break;
6493               }
6494             image_info->endian=(EndianType) ParseCommandOption(
6495               MagickEndianOptions,MagickFalse,argv[i+1]);
6496             (void) SetImageOption(image_info,option+1,argv[i+1]);
6497             break;
6498           }
6499         if (LocaleCompare("extract",option+1) == 0)
6500           {
6501             /*
6502               Set image extract geometry.
6503             */
6504             if (*option == '+')
6505               {
6506                 if (image_info->extract != (char *) NULL)
6507                   image_info->extract=DestroyString(image_info->extract);
6508                 break;
6509               }
6510             (void) CloneString(&image_info->extract,argv[i+1]);
6511             break;
6512           }
6513         break;
6514       }
6515       case 'f':
6516       {
6517         if (LocaleCompare("fill",option+1) == 0)
6518           {
6519             if (*option == '+')
6520               {
6521                 (void) SetImageOption(image_info,option+1,"none");
6522                 break;
6523               }
6524             (void) SetImageOption(image_info,option+1,argv[i+1]);
6525             break;
6526           }
6527         if (LocaleCompare("filter",option+1) == 0)
6528           {
6529             if (*option == '+')
6530               {
6531                 (void) SetImageOption(image_info,option+1,"undefined");
6532                 break;
6533               }
6534             (void) SetImageOption(image_info,option+1,argv[i+1]);
6535             break;
6536           }
6537         if (LocaleCompare("font",option+1) == 0)
6538           {
6539             if (*option == '+')
6540               {
6541                 if (image_info->font != (char *) NULL)
6542                   image_info->font=DestroyString(image_info->font);
6543                 break;
6544               }
6545             (void) CloneString(&image_info->font,argv[i+1]);
6546             break;
6547           }
6548         if (LocaleCompare("format",option+1) == 0)
6549           {
6550             register const char
6551               *q;
6552
6553             for (q=strchr(argv[i+1],'%'); q != (char *) NULL; q=strchr(q+1,'%'))
6554               if (strchr("Agkrz@[#",*(q+1)) != (char *) NULL)
6555                 image_info->ping=MagickFalse;
6556             (void) SetImageOption(image_info,option+1,argv[i+1]);
6557             break;
6558           }
6559         if (LocaleCompare("fuzz",option+1) == 0)
6560           {
6561             if (*option == '+')
6562               {
6563                 image_info->fuzz=0.0;
6564                 (void) SetImageOption(image_info,option+1,"0");
6565                 break;
6566               }
6567             image_info->fuzz=StringToDoubleInterval(argv[i+1],(double)
6568               QuantumRange+1.0);
6569             (void) SetImageOption(image_info,option+1,argv[i+1]);
6570             break;
6571           }
6572         break;
6573       }
6574       case 'g':
6575       {
6576         if (LocaleCompare("gravity",option+1) == 0)
6577           {
6578             if (*option == '+')
6579               {
6580                 (void) SetImageOption(image_info,option+1,"undefined");
6581                 break;
6582               }
6583             (void) SetImageOption(image_info,option+1,argv[i+1]);
6584             break;
6585           }
6586         if (LocaleCompare("green-primary",option+1) == 0)
6587           {
6588             if (*option == '+')
6589               {
6590                 (void) SetImageOption(image_info,option+1,"0.0");
6591                 break;
6592               }
6593             (void) SetImageOption(image_info,option+1,argv[i+1]);
6594             break;
6595           }
6596         break;
6597       }
6598       case 'i':
6599       {
6600         if (LocaleCompare("intent",option+1) == 0)
6601           {
6602             if (*option == '+')
6603               {
6604                 (void) SetImageOption(image_info,option+1,"undefined");
6605                 break;
6606               }
6607             (void) SetImageOption(image_info,option+1,argv[i+1]);
6608             break;
6609           }
6610         if (LocaleCompare("interlace",option+1) == 0)
6611           {
6612             if (*option == '+')
6613               {
6614                 image_info->interlace=UndefinedInterlace;
6615                 (void) SetImageOption(image_info,option+1,"undefined");
6616                 break;
6617               }
6618             image_info->interlace=(InterlaceType) ParseCommandOption(
6619               MagickInterlaceOptions,MagickFalse,argv[i+1]);
6620             (void) SetImageOption(image_info,option+1,argv[i+1]);
6621             break;
6622           }
6623         if (LocaleCompare("interline-spacing",option+1) == 0)
6624           {
6625             if (*option == '+')
6626               {
6627                 (void) SetImageOption(image_info,option+1,"undefined");
6628                 break;
6629               }
6630             (void) SetImageOption(image_info,option+1,argv[i+1]);
6631             break;
6632           }
6633         if (LocaleCompare("interpolate",option+1) == 0)
6634           {
6635             if (*option == '+')
6636               {
6637                 (void) SetImageOption(image_info,option+1,"undefined");
6638                 break;
6639               }
6640             (void) SetImageOption(image_info,option+1,argv[i+1]);
6641             break;
6642           }
6643         if (LocaleCompare("interword-spacing",option+1) == 0)
6644           {
6645             if (*option == '+')
6646               {
6647                 (void) SetImageOption(image_info,option+1,"undefined");
6648                 break;
6649               }
6650             (void) SetImageOption(image_info,option+1,argv[i+1]);
6651             break;
6652           }
6653         break;
6654       }
6655       case 'k':
6656       {
6657         if (LocaleCompare("kerning",option+1) == 0)
6658           {
6659             if (*option == '+')
6660               {
6661                 (void) SetImageOption(image_info,option+1,"undefined");
6662                 break;
6663               }
6664             (void) SetImageOption(image_info,option+1,argv[i+1]);
6665             break;
6666           }
6667         break;
6668       }
6669       case 'l':
6670       {
6671         if (LocaleCompare("label",option+1) == 0)
6672           {
6673             if (*option == '+')
6674               {
6675                 (void) DeleteImageOption(image_info,option+1);
6676                 break;
6677               }
6678             (void) SetImageOption(image_info,option+1,argv[i+1]);
6679             break;
6680           }
6681         if (LocaleCompare("limit",option+1) == 0)
6682           {
6683             MagickSizeType
6684               limit;
6685
6686             ResourceType
6687               type;
6688
6689             if (*option == '+')
6690               break;
6691             type=(ResourceType) ParseCommandOption(MagickResourceOptions,
6692               MagickFalse,argv[i+1]);
6693             limit=MagickResourceInfinity;
6694             if (LocaleCompare("unlimited",argv[i+2]) != 0)
6695               limit=(MagickSizeType) SiPrefixToDoubleInterval(argv[i+2],100.0);
6696             (void) SetMagickResourceLimit(type,limit);
6697             break;
6698           }
6699         if (LocaleCompare("list",option+1) == 0)
6700           {
6701             ssize_t
6702               list;
6703
6704             /*
6705               Display configuration list.
6706             */
6707             list=ParseCommandOption(MagickListOptions,MagickFalse,argv[i+1]);
6708             switch (list)
6709             {
6710               case MagickCoderOptions:
6711               {
6712                 (void) ListCoderInfo((FILE *) NULL,exception);
6713                 break;
6714               }
6715               case MagickColorOptions:
6716               {
6717                 (void) ListColorInfo((FILE *) NULL,exception);
6718                 break;
6719               }
6720               case MagickConfigureOptions:
6721               {
6722                 (void) ListConfigureInfo((FILE *) NULL,exception);
6723                 break;
6724               }
6725               case MagickDelegateOptions:
6726               {
6727                 (void) ListDelegateInfo((FILE *) NULL,exception);
6728                 break;
6729               }
6730               case MagickFontOptions:
6731               {
6732                 (void) ListTypeInfo((FILE *) NULL,exception);
6733                 break;
6734               }
6735               case MagickFormatOptions:
6736               {
6737                 (void) ListMagickInfo((FILE *) NULL,exception);
6738                 break;
6739               }
6740               case MagickLocaleOptions:
6741               {
6742                 (void) ListLocaleInfo((FILE *) NULL,exception);
6743                 break;
6744               }
6745               case MagickLogOptions:
6746               {
6747                 (void) ListLogInfo((FILE *) NULL,exception);
6748                 break;
6749               }
6750               case MagickMagicOptions:
6751               {
6752                 (void) ListMagicInfo((FILE *) NULL,exception);
6753                 break;
6754               }
6755               case MagickMimeOptions:
6756               {
6757                 (void) ListMimeInfo((FILE *) NULL,exception);
6758                 break;
6759               }
6760               case MagickModuleOptions:
6761               {
6762                 (void) ListModuleInfo((FILE *) NULL,exception);
6763                 break;
6764               }
6765               case MagickPolicyOptions:
6766               {
6767                 (void) ListPolicyInfo((FILE *) NULL,exception);
6768                 break;
6769               }
6770               case MagickResourceOptions:
6771               {
6772                 (void) ListMagickResourceInfo((FILE *) NULL,exception);
6773                 break;
6774               }
6775               case MagickThresholdOptions:
6776               {
6777                 (void) ListThresholdMaps((FILE *) NULL,exception);
6778                 break;
6779               }
6780               default:
6781               {
6782                 (void) ListCommandOptions((FILE *) NULL,(CommandOption) list,
6783                   exception);
6784                 break;
6785               }
6786             }
6787             break;
6788           }
6789         if (LocaleCompare("log",option+1) == 0)
6790           {
6791             if (*option == '+')
6792               break;
6793             (void) SetLogFormat(argv[i+1]);
6794             break;
6795           }
6796         if (LocaleCompare("loop",option+1) == 0)
6797           {
6798             if (*option == '+')
6799               {
6800                 (void) SetImageOption(image_info,option+1,"0");
6801                 break;
6802               }
6803             (void) SetImageOption(image_info,option+1,argv[i+1]);
6804             break;
6805           }
6806         break;
6807       }
6808       case 'm':
6809       {
6810         if (LocaleCompare("matte",option+1) == 0)
6811           {
6812             if (*option == '+')
6813               {
6814                 (void) SetImageOption(image_info,option+1,"false");
6815                 break;
6816               }
6817             (void) SetImageOption(image_info,option+1,"true");
6818             break;
6819           }
6820         if (LocaleCompare("mattecolor",option+1) == 0)
6821           {
6822             if (*option == '+')
6823               {
6824                 (void) SetImageOption(image_info,option+1,argv[i+1]);
6825                 (void) QueryColorCompliance(MogrifyMatteColor,AllCompliance,
6826                   &image_info->matte_color,exception);
6827                 break;
6828               }
6829             (void) SetImageOption(image_info,option+1,argv[i+1]);
6830             (void) QueryColorCompliance(argv[i+1],AllCompliance,
6831               &image_info->matte_color,exception);
6832             break;
6833           }
6834         if (LocaleCompare("monitor",option+1) == 0)
6835           {
6836             (void) SetImageInfoProgressMonitor(image_info,MonitorProgress,
6837               (void *) NULL);
6838             break;
6839           }
6840         if (LocaleCompare("monochrome",option+1) == 0)
6841           {
6842             image_info->monochrome=(*option == '-') ? MagickTrue : MagickFalse;
6843             break;
6844           }
6845         break;
6846       }
6847       case 'o':
6848       {
6849         if (LocaleCompare("orient",option+1) == 0)
6850           {
6851             if (*option == '+')
6852               {
6853                 image_info->orientation=UndefinedOrientation;
6854                 (void) SetImageOption(image_info,option+1,"undefined");
6855                 break;
6856               }
6857             image_info->orientation=(OrientationType) ParseCommandOption(
6858               MagickOrientationOptions,MagickFalse,argv[i+1]);
6859             (void) SetImageOption(image_info,option+1,argv[i+1]);
6860             break;
6861           }
6862       }
6863       case 'p':
6864       {
6865         if (LocaleCompare("page",option+1) == 0)
6866           {
6867             char
6868               *canonical_page,
6869               page[MaxTextExtent];
6870
6871             const char
6872               *image_option;
6873
6874             MagickStatusType
6875               flags;
6876
6877             RectangleInfo
6878               geometry;
6879
6880             if (*option == '+')
6881               {
6882                 (void) DeleteImageOption(image_info,option+1);
6883                 (void) CloneString(&image_info->page,(char *) NULL);
6884                 break;
6885               }
6886             (void) ResetMagickMemory(&geometry,0,sizeof(geometry));
6887             image_option=GetImageOption(image_info,"page");
6888             if (image_option != (const char *) NULL)
6889               flags=ParseAbsoluteGeometry(image_option,&geometry);
6890             canonical_page=GetPageGeometry(argv[i+1]);
6891             flags=ParseAbsoluteGeometry(canonical_page,&geometry);
6892             canonical_page=DestroyString(canonical_page);
6893             (void) FormatLocaleString(page,MaxTextExtent,"%lux%lu",
6894               (unsigned long) geometry.width,(unsigned long) geometry.height);
6895             if (((flags & XValue) != 0) || ((flags & YValue) != 0))
6896               (void) FormatLocaleString(page,MaxTextExtent,"%lux%lu%+ld%+ld",
6897                 (unsigned long) geometry.width,(unsigned long) geometry.height,
6898                 (long) geometry.x,(long) geometry.y);
6899             (void) SetImageOption(image_info,option+1,page);
6900             (void) CloneString(&image_info->page,page);
6901             break;
6902           }
6903         if (LocaleCompare("ping",option+1) == 0)
6904           {
6905             image_info->ping=(*option == '-') ? MagickTrue : MagickFalse;
6906             break;
6907           }
6908         if (LocaleCompare("pointsize",option+1) == 0)
6909           {
6910             if (*option == '+')
6911               geometry_info.rho=0.0;
6912             else
6913               (void) ParseGeometry(argv[i+1],&geometry_info);
6914             image_info->pointsize=geometry_info.rho;
6915             break;
6916           }
6917         if (LocaleCompare("precision",option+1) == 0)
6918           {
6919             (void) SetMagickPrecision(StringToInteger(argv[i+1]));
6920             break;
6921           }
6922         if (LocaleCompare("preview",option+1) == 0)
6923           {
6924             /*
6925               Preview image.
6926             */
6927             if (*option == '+')
6928               {
6929                 image_info->preview_type=UndefinedPreview;
6930                 break;
6931               }
6932             image_info->preview_type=(PreviewType) ParseCommandOption(
6933               MagickPreviewOptions,MagickFalse,argv[i+1]);
6934             break;
6935           }
6936         break;
6937       }
6938       case 'q':
6939       {
6940         if (LocaleCompare("quality",option+1) == 0)
6941           {
6942             /*
6943               Set image compression quality.
6944             */
6945             if (*option == '+')
6946               {
6947                 image_info->quality=UndefinedCompressionQuality;
6948                 (void) SetImageOption(image_info,option+1,"0");
6949                 break;
6950               }
6951             image_info->quality=StringToUnsignedLong(argv[i+1]);
6952             (void) SetImageOption(image_info,option+1,argv[i+1]);
6953             break;
6954           }
6955         if (LocaleCompare("quiet",option+1) == 0)
6956           {
6957             static WarningHandler
6958               warning_handler = (WarningHandler) NULL;
6959
6960             if (*option == '+')
6961               {
6962                 /*
6963                   Restore error or warning messages.
6964                 */
6965                 warning_handler=SetWarningHandler(warning_handler);
6966                 break;
6967               }
6968             /*
6969               Suppress error or warning messages.
6970             */
6971             warning_handler=SetWarningHandler((WarningHandler) NULL);
6972             break;
6973           }
6974         break;
6975       }
6976       case 'r':
6977       {
6978         if (LocaleCompare("red-primary",option+1) == 0)
6979           {
6980             if (*option == '+')
6981               {
6982                 (void) SetImageOption(image_info,option+1,"0.0");
6983                 break;
6984               }
6985             (void) SetImageOption(image_info,option+1,argv[i+1]);
6986             break;
6987           }
6988         break;
6989       }
6990       case 's':
6991       {
6992         if (LocaleCompare("sampling-factor",option+1) == 0)
6993           {
6994             /*
6995               Set image sampling factor.
6996             */
6997             if (*option == '+')
6998               {
6999                 if (image_info->sampling_factor != (char *) NULL)
7000                   image_info->sampling_factor=DestroyString(
7001                     image_info->sampling_factor);
7002                 break;
7003               }
7004             (void) CloneString(&image_info->sampling_factor,argv[i+1]);
7005             break;
7006           }
7007         if (LocaleCompare("scene",option+1) == 0)
7008           {
7009             /*
7010               Set image scene.
7011             */
7012             if (*option == '+')
7013               {
7014                 image_info->scene=0;
7015                 (void) SetImageOption(image_info,option+1,"0");
7016                 break;
7017               }
7018             image_info->scene=StringToUnsignedLong(argv[i+1]);
7019             (void) SetImageOption(image_info,option+1,argv[i+1]);
7020             break;
7021           }
7022         if (LocaleCompare("seed",option+1) == 0)
7023           {
7024             size_t
7025               seed;
7026
7027             if (*option == '+')
7028               {
7029                 seed=(size_t) time((time_t *) NULL);
7030                 SeedPseudoRandomGenerator(seed);
7031                 break;
7032               }
7033             seed=StringToUnsignedLong(argv[i+1]);
7034             SeedPseudoRandomGenerator(seed);
7035             break;
7036           }
7037         if (LocaleCompare("size",option+1) == 0)
7038           {
7039             if (*option == '+')
7040               {
7041                 if (image_info->size != (char *) NULL)
7042                   image_info->size=DestroyString(image_info->size);
7043                 break;
7044               }
7045             (void) CloneString(&image_info->size,argv[i+1]);
7046             break;
7047           }
7048         if (LocaleCompare("stroke",option+1) == 0)
7049           {
7050             if (*option == '+')
7051               {
7052                 (void) SetImageOption(image_info,option+1,"none");
7053                 break;
7054               }
7055             (void) SetImageOption(image_info,option+1,argv[i+1]);
7056             break;
7057           }
7058         if (LocaleCompare("strokewidth",option+1) == 0)
7059           {
7060             if (*option == '+')
7061               {
7062                 (void) SetImageOption(image_info,option+1,"0");
7063                 break;
7064               }
7065             (void) SetImageOption(image_info,option+1,argv[i+1]);
7066             break;
7067           }
7068         if (LocaleCompare("synchronize",option+1) == 0)
7069           {
7070             if (*option == '+')
7071               {
7072                 image_info->synchronize=MagickFalse;
7073                 break;
7074               }
7075             image_info->synchronize=MagickTrue;
7076             break;
7077           }
7078         break;
7079       }
7080       case 't':
7081       {
7082         if (LocaleCompare("taint",option+1) == 0)
7083           {
7084             if (*option == '+')
7085               {
7086                 (void) SetImageOption(image_info,option+1,"false");
7087                 break;
7088               }
7089             (void) SetImageOption(image_info,option+1,"true");
7090             break;
7091           }
7092         if (LocaleCompare("texture",option+1) == 0)
7093           {
7094             if (*option == '+')
7095               {
7096                 if (image_info->texture != (char *) NULL)
7097                   image_info->texture=DestroyString(image_info->texture);
7098                 break;
7099               }
7100             (void) CloneString(&image_info->texture,argv[i+1]);
7101             break;
7102           }
7103         if (LocaleCompare("tile-offset",option+1) == 0)
7104           {
7105             if (*option == '+')
7106               {
7107                 (void) SetImageOption(image_info,option+1,"0");
7108                 break;
7109               }
7110             (void) SetImageOption(image_info,option+1,argv[i+1]);
7111             break;
7112           }
7113         if (LocaleCompare("transparent-color",option+1) == 0)
7114           {
7115             if (*option == '+')
7116               {
7117                 (void) QueryColorCompliance("none",AllCompliance,
7118                   &image_info->transparent_color,exception);
7119                 (void) SetImageOption(image_info,option+1,"none");
7120                 break;
7121               }
7122             (void) QueryColorCompliance(argv[i+1],AllCompliance,
7123               &image_info->transparent_color,exception);
7124             (void) SetImageOption(image_info,option+1,argv[i+1]);
7125             break;
7126           }
7127         if (LocaleCompare("type",option+1) == 0)
7128           {
7129             if (*option == '+')
7130               {
7131                 image_info->type=UndefinedType;
7132                 (void) SetImageOption(image_info,option+1,"undefined");
7133                 break;
7134               }
7135             image_info->type=(ImageType) ParseCommandOption(MagickTypeOptions,
7136               MagickFalse,argv[i+1]);
7137             (void) SetImageOption(image_info,option+1,argv[i+1]);
7138             break;
7139           }
7140         break;
7141       }
7142       case 'u':
7143       {
7144         if (LocaleCompare("undercolor",option+1) == 0)
7145           {
7146             if (*option == '+')
7147               {
7148                 (void) DeleteImageOption(image_info,option+1);
7149                 break;
7150               }
7151             (void) SetImageOption(image_info,option+1,argv[i+1]);
7152             break;
7153           }
7154         if (LocaleCompare("units",option+1) == 0)
7155           {
7156             if (*option == '+')
7157               {
7158                 image_info->units=UndefinedResolution;
7159                 (void) SetImageOption(image_info,option+1,"undefined");
7160                 break;
7161               }
7162             image_info->units=(ResolutionType) ParseCommandOption(
7163               MagickResolutionOptions,MagickFalse,argv[i+1]);
7164             (void) SetImageOption(image_info,option+1,argv[i+1]);
7165             break;
7166           }
7167         break;
7168       }
7169       case 'v':
7170       {
7171         if (LocaleCompare("verbose",option+1) == 0)
7172           {
7173             if (*option == '+')
7174               {
7175                 image_info->verbose=MagickFalse;
7176                 break;
7177               }
7178             image_info->verbose=MagickTrue;
7179             image_info->ping=MagickFalse;
7180             break;
7181           }
7182         if (LocaleCompare("view",option+1) == 0)
7183           {
7184             if (*option == '+')
7185               {
7186                 if (image_info->view != (char *) NULL)
7187                   image_info->view=DestroyString(image_info->view);
7188                 break;
7189               }
7190             (void) CloneString(&image_info->view,argv[i+1]);
7191             break;
7192           }
7193         if (LocaleCompare("virtual-pixel",option+1) == 0)
7194           {
7195             if (*option == '+')
7196               {
7197                 image_info->virtual_pixel_method=UndefinedVirtualPixelMethod;
7198                 (void) SetImageOption(image_info,option+1,"undefined");
7199                 break;
7200               }
7201             image_info->virtual_pixel_method=(VirtualPixelMethod)
7202               ParseCommandOption(MagickVirtualPixelOptions,MagickFalse,
7203               argv[i+1]);
7204             (void) SetImageOption(image_info,option+1,argv[i+1]);
7205             break;
7206           }
7207         break;
7208       }
7209       case 'w':
7210       {
7211         if (LocaleCompare("white-point",option+1) == 0)
7212           {
7213             if (*option == '+')
7214               {
7215                 (void) SetImageOption(image_info,option+1,"0.0");
7216                 break;
7217               }
7218             (void) SetImageOption(image_info,option+1,argv[i+1]);
7219             break;
7220           }
7221         break;
7222       }
7223       default:
7224         break;
7225     }
7226     i+=count;
7227   }
7228   return(MagickTrue);
7229 }
7230 \f
7231 /*
7232 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7233 %                                                                             %
7234 %                                                                             %
7235 %                                                                             %
7236 +     M o g r i f y I m a g e L i s t                                         %
7237 %                                                                             %
7238 %                                                                             %
7239 %                                                                             %
7240 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7241 %
7242 %  MogrifyImageList() applies any command line options that might affect the
7243 %  entire image list (e.g. -append, -coalesce, etc.).
7244 %
7245 %  The format of the MogrifyImage method is:
7246 %
7247 %      MagickBooleanType MogrifyImageList(ImageInfo *image_info,const int argc,
7248 %        const char **argv,Image **images,ExceptionInfo *exception)
7249 %
7250 %  A description of each parameter follows:
7251 %
7252 %    o image_info: the image info..
7253 %
7254 %    o argc: Specifies a pointer to an integer describing the number of
7255 %      elements in the argument vector.
7256 %
7257 %    o argv: Specifies a pointer to a text array containing the command line
7258 %      arguments.
7259 %
7260 %    o images: pointer to pointer of the first image in image list.
7261 %
7262 %    o exception: return any errors or warnings in this structure.
7263 %
7264 */
7265 WandExport MagickBooleanType MogrifyImageList(ImageInfo *image_info,
7266   const int argc,const char **argv,Image **images,ExceptionInfo *exception)
7267 {
7268   const char
7269     *option;
7270
7271   ImageInfo
7272     *mogrify_info;
7273
7274   MagickStatusType
7275     status;
7276
7277   PixelInterpolateMethod
7278    interpolate_method;
7279
7280   QuantizeInfo
7281     *quantize_info;
7282
7283   register ssize_t
7284     i;
7285
7286   ssize_t
7287     count,
7288     index;
7289
7290   /*
7291     Apply options to the image list.
7292   */
7293   assert(image_info != (ImageInfo *) NULL);
7294   assert(image_info->signature == MagickSignature);
7295   assert(images != (Image **) NULL);
7296   assert((*images)->previous == (Image *) NULL);
7297   assert((*images)->signature == MagickSignature);
7298   if ((*images)->debug != MagickFalse)
7299     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
7300       (*images)->filename);
7301   if ((argc <= 0) || (*argv == (char *) NULL))
7302     return(MagickTrue);
7303   interpolate_method=UndefinedInterpolatePixel;
7304   mogrify_info=CloneImageInfo(image_info);
7305   quantize_info=AcquireQuantizeInfo(mogrify_info);
7306   status=MagickTrue;
7307   for (i=0; i < (ssize_t) argc; i++)
7308   {
7309     if (*images == (Image *) NULL)
7310       break;
7311     option=argv[i];
7312     if (IsCommandOption(option) == MagickFalse)
7313       continue;
7314     count=ParseCommandOption(MagickCommandOptions,MagickFalse,option);
7315     count=MagickMax(count,0L);
7316     if ((i+count) >= (ssize_t) argc)
7317       break;
7318     status=MogrifyImageInfo(mogrify_info,(int) count+1,argv+i,exception);
7319     switch (*(option+1))
7320     {
7321       case 'a':
7322       {
7323         if (LocaleCompare("affinity",option+1) == 0)
7324           {
7325             (void) SyncImagesSettings(mogrify_info,*images,exception);
7326             if (*option == '+')
7327               {
7328                 (void) RemapImages(quantize_info,*images,(Image *) NULL,
7329                   exception);
7330                 break;
7331               }
7332             i++;
7333             break;
7334           }
7335         if (LocaleCompare("append",option+1) == 0)
7336           {
7337             Image
7338               *append_image;
7339
7340             (void) SyncImagesSettings(mogrify_info,*images,exception);
7341             append_image=AppendImages(*images,*option == '-' ? MagickTrue :
7342               MagickFalse,exception);
7343             if (append_image == (Image *) NULL)
7344               {
7345                 status=MagickFalse;
7346                 break;
7347               }
7348             *images=DestroyImageList(*images);
7349             *images=append_image;
7350             break;
7351           }
7352         if (LocaleCompare("average",option+1) == 0)
7353           {
7354             Image
7355               *average_image;
7356
7357             /*
7358               Average an image sequence (deprecated).
7359             */
7360             (void) SyncImagesSettings(mogrify_info,*images,exception);
7361             average_image=EvaluateImages(*images,MeanEvaluateOperator,
7362               exception);
7363             if (average_image == (Image *) NULL)
7364               {
7365                 status=MagickFalse;
7366                 break;
7367               }
7368             *images=DestroyImageList(*images);
7369             *images=average_image;
7370             break;
7371           }
7372         break;
7373       }
7374       case 'c':
7375       {
7376         if (LocaleCompare("channel",option+1) == 0)
7377           {
7378             ChannelType
7379               channel;
7380
7381             if (*option == '+')
7382               {
7383                 channel=DefaultChannels;
7384                 break;
7385               }
7386             channel=(ChannelType) ParseChannelOption(argv[i+1]);
7387             SetPixelChannelMapMask(*images,channel);
7388             break;
7389           }
7390         if (LocaleCompare("clut",option+1) == 0)
7391           {
7392             Image
7393               *clut_image,
7394               *image;
7395
7396             (void) SyncImagesSettings(mogrify_info,*images,exception);
7397             image=RemoveFirstImageFromList(images);
7398             clut_image=RemoveFirstImageFromList(images);
7399             if (clut_image == (Image *) NULL)
7400               {
7401                 status=MagickFalse;
7402                 break;
7403               }
7404             (void) ClutImage(image,clut_image,interpolate_method,exception);
7405             clut_image=DestroyImage(clut_image);
7406             *images=DestroyImageList(*images);
7407             *images=image;
7408             break;
7409           }
7410         if (LocaleCompare("coalesce",option+1) == 0)
7411           {
7412             Image
7413               *coalesce_image;
7414
7415             (void) SyncImagesSettings(mogrify_info,*images,exception);
7416             coalesce_image=CoalesceImages(*images,exception);
7417             if (coalesce_image == (Image *) NULL)
7418               {
7419                 status=MagickFalse;
7420                 break;
7421               }
7422             *images=DestroyImageList(*images);
7423             *images=coalesce_image;
7424             break;
7425           }
7426         if (LocaleCompare("combine",option+1) == 0)
7427           {
7428             Image
7429               *combine_image;
7430
7431             (void) SyncImagesSettings(mogrify_info,*images,exception);
7432             combine_image=CombineImages(*images,exception);
7433             if (combine_image == (Image *) NULL)
7434               {
7435                 status=MagickFalse;
7436                 break;
7437               }
7438             *images=DestroyImageList(*images);
7439             *images=combine_image;
7440             break;
7441           }
7442         if (LocaleCompare("composite",option+1) == 0)
7443           {
7444             Image
7445               *mask_image,
7446               *composite_image,
7447               *image;
7448
7449             RectangleInfo
7450               geometry;
7451
7452             (void) SyncImagesSettings(mogrify_info,*images,exception);
7453             image=RemoveFirstImageFromList(images);
7454             composite_image=RemoveFirstImageFromList(images);
7455             if (composite_image == (Image *) NULL)
7456               {
7457                 status=MagickFalse;
7458                 break;
7459               }
7460             (void) TransformImage(&composite_image,(char *) NULL,
7461               composite_image->geometry,exception);
7462             SetGeometry(composite_image,&geometry);
7463             (void) ParseAbsoluteGeometry(composite_image->geometry,&geometry);
7464             GravityAdjustGeometry(image->columns,image->rows,image->gravity,
7465               &geometry);
7466             mask_image=RemoveFirstImageFromList(images);
7467             if (mask_image != (Image *) NULL)
7468               {
7469                 if ((image->compose == DisplaceCompositeOp) ||
7470                     (image->compose == DistortCompositeOp))
7471                   {
7472                     /*
7473                       Merge Y displacement into X displacement image.
7474                     */
7475                     (void) CompositeImage(composite_image,CopyGreenCompositeOp,
7476                       mask_image,0,0,exception);
7477                     mask_image=DestroyImage(mask_image);
7478                   }
7479                 else
7480                   {
7481                     /*
7482                       Set a blending mask for the composition.
7483                       Posible error, what if image->mask already set.
7484                     */
7485                     image->mask=mask_image;
7486                     (void) NegateImage(image->mask,MagickFalse,exception);
7487                   }
7488               }
7489             (void) CompositeImage(image,image->compose,composite_image,
7490               geometry.x,geometry.y,exception);
7491             if (mask_image != (Image *) NULL)
7492               mask_image=image->mask=DestroyImage(image->mask);
7493             composite_image=DestroyImage(composite_image);
7494             *images=DestroyImageList(*images);
7495             *images=image;
7496             break;
7497           }
7498         break;
7499       }
7500       case 'd':
7501       {
7502         if (LocaleCompare("deconstruct",option+1) == 0)
7503           {
7504             Image
7505               *deconstruct_image;
7506
7507             (void) SyncImagesSettings(mogrify_info,*images,exception);
7508             deconstruct_image=CompareImagesLayers(*images,CompareAnyLayer,
7509               exception);
7510             if (deconstruct_image == (Image *) NULL)
7511               {
7512                 status=MagickFalse;
7513                 break;
7514               }
7515             *images=DestroyImageList(*images);
7516             *images=deconstruct_image;
7517             break;
7518           }
7519         if (LocaleCompare("delete",option+1) == 0)
7520           {
7521             if (*option == '+')
7522               DeleteImages(images,"-1",exception);
7523             else
7524               DeleteImages(images,argv[i+1],exception);
7525             break;
7526           }
7527         if (LocaleCompare("dither",option+1) == 0)
7528           {
7529             if (*option == '+')
7530               {
7531                 quantize_info->dither=MagickFalse;
7532                 break;
7533               }
7534             quantize_info->dither=MagickTrue;
7535             quantize_info->dither_method=(DitherMethod) ParseCommandOption(
7536               MagickDitherOptions,MagickFalse,argv[i+1]);
7537             break;
7538           }
7539         if (LocaleCompare("duplicate",option+1) == 0)
7540           {
7541             Image
7542               *duplicate_images;
7543
7544             if (*option == '+')
7545               duplicate_images=DuplicateImages(*images,1,"-1",exception);
7546             else
7547               {
7548                 const char
7549                   *p;
7550
7551                 size_t
7552                   number_duplicates;
7553
7554                 number_duplicates=(size_t) StringToLong(argv[i+1]);
7555                 p=strchr(argv[i+1],',');
7556                 if (p == (const char *) NULL)
7557                   duplicate_images=DuplicateImages(*images,number_duplicates,
7558                     "-1",exception);
7559                 else
7560                   duplicate_images=DuplicateImages(*images,number_duplicates,p,
7561                     exception);
7562               }
7563             AppendImageToList(images, duplicate_images);
7564             (void) SyncImagesSettings(mogrify_info,*images,exception);
7565             break;
7566           }
7567         break;
7568       }
7569       case 'e':
7570       {
7571         if (LocaleCompare("evaluate-sequence",option+1) == 0)
7572           {
7573             Image
7574               *evaluate_image;
7575
7576             MagickEvaluateOperator
7577               op;
7578
7579             (void) SyncImageSettings(mogrify_info,*images,exception);
7580             op=(MagickEvaluateOperator) ParseCommandOption(
7581               MagickEvaluateOptions,MagickFalse,argv[i+1]);
7582             evaluate_image=EvaluateImages(*images,op,exception);
7583             if (evaluate_image == (Image *) NULL)
7584               {
7585                 status=MagickFalse;
7586                 break;
7587               }
7588             *images=DestroyImageList(*images);
7589             *images=evaluate_image;
7590             break;
7591           }
7592         break;
7593       }
7594       case 'f':
7595       {
7596         if (LocaleCompare("fft",option+1) == 0)
7597           {
7598             Image
7599               *fourier_image;
7600
7601             /*
7602               Implements the discrete Fourier transform (DFT).
7603             */
7604             (void) SyncImageSettings(mogrify_info,*images,exception);
7605             fourier_image=ForwardFourierTransformImage(*images,*option == '-' ?
7606               MagickTrue : MagickFalse,exception);
7607             if (fourier_image == (Image *) NULL)
7608               break;
7609             *images=DestroyImage(*images);
7610             *images=fourier_image;
7611             break;
7612           }
7613         if (LocaleCompare("flatten",option+1) == 0)
7614           {
7615             Image
7616               *flatten_image;
7617
7618             (void) SyncImagesSettings(mogrify_info,*images,exception);
7619             flatten_image=MergeImageLayers(*images,FlattenLayer,exception);
7620             if (flatten_image == (Image *) NULL)
7621               break;
7622             *images=DestroyImageList(*images);
7623             *images=flatten_image;
7624             break;
7625           }
7626         if (LocaleCompare("fx",option+1) == 0)
7627           {
7628             Image
7629               *fx_image;
7630
7631             (void) SyncImagesSettings(mogrify_info,*images,exception);
7632             fx_image=FxImage(*images,argv[i+1],exception);
7633             if (fx_image == (Image *) NULL)
7634               {
7635                 status=MagickFalse;
7636                 break;
7637               }
7638             *images=DestroyImageList(*images);
7639             *images=fx_image;
7640             break;
7641           }
7642         break;
7643       }
7644       case 'h':
7645       {
7646         if (LocaleCompare("hald-clut",option+1) == 0)
7647           {
7648             Image
7649               *hald_image,
7650               *image;
7651
7652             (void) SyncImagesSettings(mogrify_info,*images,exception);
7653             image=RemoveFirstImageFromList(images);
7654             hald_image=RemoveFirstImageFromList(images);
7655             if (hald_image == (Image *) NULL)
7656               {
7657                 status=MagickFalse;
7658                 break;
7659               }
7660             (void) HaldClutImage(image,hald_image,exception);
7661             hald_image=DestroyImage(hald_image);
7662             if (*images != (Image *) NULL)
7663               *images=DestroyImageList(*images);
7664             *images=image;
7665             break;
7666           }
7667         break;
7668       }
7669       case 'i':
7670       {
7671         if (LocaleCompare("ift",option+1) == 0)
7672           {
7673             Image
7674               *fourier_image,
7675               *magnitude_image,
7676               *phase_image;
7677
7678             /*
7679               Implements the inverse fourier discrete Fourier transform (DFT).
7680             */
7681             (void) SyncImagesSettings(mogrify_info,*images,exception);
7682             magnitude_image=RemoveFirstImageFromList(images);
7683             phase_image=RemoveFirstImageFromList(images);
7684             if (phase_image == (Image *) NULL)
7685               {
7686                 status=MagickFalse;
7687                 break;
7688               }
7689             fourier_image=InverseFourierTransformImage(magnitude_image,
7690               phase_image,*option == '-' ? MagickTrue : MagickFalse,exception);
7691             if (fourier_image == (Image *) NULL)
7692               break;
7693             if (*images != (Image *) NULL)
7694               *images=DestroyImage(*images);
7695             *images=fourier_image;
7696             break;
7697           }
7698         if (LocaleCompare("insert",option+1) == 0)
7699           {
7700             Image
7701               *p,
7702               *q;
7703
7704             index=0;
7705             if (*option != '+')
7706               index=(ssize_t) StringToLong(argv[i+1]);
7707             p=RemoveLastImageFromList(images);
7708             if (p == (Image *) NULL)
7709               {
7710                 (void) ThrowMagickException(exception,GetMagickModule(),
7711                   OptionError,"NoSuchImage","`%s'",argv[i+1]);
7712                 status=MagickFalse;
7713                 break;
7714               }
7715             q=p;
7716             if (index == 0)
7717               PrependImageToList(images,q);
7718             else
7719               if (index == (ssize_t) GetImageListLength(*images))
7720                 AppendImageToList(images,q);
7721               else
7722                 {
7723                    q=GetImageFromList(*images,index-1);
7724                    if (q == (Image *) NULL)
7725                      {
7726                        (void) ThrowMagickException(exception,GetMagickModule(),
7727                          OptionError,"NoSuchImage","`%s'",argv[i+1]);
7728                        status=MagickFalse;
7729                        break;
7730                      }
7731                   InsertImageInList(&q,p);
7732                 }
7733             *images=GetFirstImageInList(q);
7734             break;
7735           }
7736         if (LocaleCompare("interpolate",option+1) == 0)
7737           {
7738             interpolate_method=(PixelInterpolateMethod) ParseCommandOption(
7739               MagickInterpolateOptions,MagickFalse,argv[i+1]);
7740             break;
7741           }
7742         break;
7743       }
7744       case 'l':
7745       {
7746         if (LocaleCompare("layers",option+1) == 0)
7747           {
7748             Image
7749               *layers;
7750
7751             ImageLayerMethod
7752               method;
7753
7754             (void) SyncImagesSettings(mogrify_info,*images,exception);
7755             layers=(Image *) NULL;
7756             method=(ImageLayerMethod) ParseCommandOption(MagickLayerOptions,
7757               MagickFalse,argv[i+1]);
7758             switch (method)
7759             {
7760               case CoalesceLayer:
7761               {
7762                 layers=CoalesceImages(*images,exception);
7763                 break;
7764               }
7765               case CompareAnyLayer:
7766               case CompareClearLayer:
7767               case CompareOverlayLayer:
7768               default:
7769               {
7770                 layers=CompareImagesLayers(*images,method,exception);
7771                 break;
7772               }
7773               case MergeLayer:
7774               case FlattenLayer:
7775               case MosaicLayer:
7776               case TrimBoundsLayer:
7777               {
7778                 layers=MergeImageLayers(*images,method,exception);
7779                 break;
7780               }
7781               case DisposeLayer:
7782               {
7783                 layers=DisposeImages(*images,exception);
7784                 break;
7785               }
7786               case OptimizeImageLayer:
7787               {
7788                 layers=OptimizeImageLayers(*images,exception);
7789                 break;
7790               }
7791               case OptimizePlusLayer:
7792               {
7793                 layers=OptimizePlusImageLayers(*images,exception);
7794                 break;
7795               }
7796               case OptimizeTransLayer:
7797               {
7798                 OptimizeImageTransparency(*images,exception);
7799                 break;
7800               }
7801               case RemoveDupsLayer:
7802               {
7803                 RemoveDuplicateLayers(images,exception);
7804                 break;
7805               }
7806               case RemoveZeroLayer:
7807               {
7808                 RemoveZeroDelayLayers(images,exception);
7809                 break;
7810               }
7811               case OptimizeLayer:
7812               {
7813                 /*
7814                   General Purpose, GIF Animation Optimizer.
7815                 */
7816                 layers=CoalesceImages(*images,exception);
7817                 if (layers == (Image *) NULL)
7818                   {
7819                     status=MagickFalse;
7820                     break;
7821                   }
7822                 *images=DestroyImageList(*images);
7823                 *images=layers;
7824                 layers=OptimizeImageLayers(*images,exception);
7825                 if (layers == (Image *) NULL)
7826                   {
7827                     status=MagickFalse;
7828                     break;
7829                   }
7830                 *images=DestroyImageList(*images);
7831                 *images=layers;
7832                 layers=(Image *) NULL;
7833                 OptimizeImageTransparency(*images,exception);
7834                 (void) RemapImages(quantize_info,*images,(Image *) NULL,
7835                   exception);
7836                 break;
7837               }
7838               case CompositeLayer:
7839               {
7840                 CompositeOperator
7841                   compose;
7842
7843                 Image
7844                   *source;
7845
7846                 RectangleInfo
7847                   geometry;
7848
7849                 /*
7850                   Split image sequence at the first 'NULL:' image.
7851                 */
7852                 source=(*images);
7853                 while (source != (Image *) NULL)
7854                 {
7855                   source=GetNextImageInList(source);
7856                   if ((source != (Image *) NULL) &&
7857                       (LocaleCompare(source->magick,"NULL") == 0))
7858                     break;
7859                 }
7860                 if (source != (Image *) NULL)
7861                   {
7862                     if ((GetPreviousImageInList(source) == (Image *) NULL) ||
7863                         (GetNextImageInList(source) == (Image *) NULL))
7864                       source=(Image *) NULL;
7865                     else
7866                       {
7867                         /*
7868                           Separate the two lists, junk the null: image.
7869                         */
7870                         source=SplitImageList(source->previous);
7871                         DeleteImageFromList(&source);
7872                       }
7873                   }
7874                 if (source == (Image *) NULL)
7875                   {
7876                     (void) ThrowMagickException(exception,GetMagickModule(),
7877                       OptionError,"MissingNullSeparator","layers Composite");
7878                     status=MagickFalse;
7879                     break;
7880                   }
7881                 /*
7882                   Adjust offset with gravity and virtual canvas.
7883                 */
7884                 SetGeometry(*images,&geometry);
7885                 (void) ParseAbsoluteGeometry((*images)->geometry,&geometry);
7886                 geometry.width=source->page.width != 0 ?
7887                   source->page.width : source->columns;
7888                 geometry.height=source->page.height != 0 ?
7889                  source->page.height : source->rows;
7890                 GravityAdjustGeometry((*images)->page.width != 0 ?
7891                   (*images)->page.width : (*images)->columns,
7892                   (*images)->page.height != 0 ? (*images)->page.height :
7893                   (*images)->rows,(*images)->gravity,&geometry);
7894                 compose=OverCompositeOp;
7895                 option=GetImageOption(mogrify_info,"compose");
7896                 if (option != (const char *) NULL)
7897                   compose=(CompositeOperator) ParseCommandOption(
7898                     MagickComposeOptions,MagickFalse,option);
7899                 CompositeLayers(*images,compose,source,geometry.x,geometry.y,
7900                   exception);
7901                 source=DestroyImageList(source);
7902                 break;
7903               }
7904             }
7905             if (layers == (Image *) NULL)
7906               break;
7907             *images=DestroyImageList(*images);
7908             *images=layers;
7909             break;
7910           }
7911         break;
7912       }
7913       case 'm':
7914       {
7915         if (LocaleCompare("map",option+1) == 0)
7916           {
7917             (void) SyncImagesSettings(mogrify_info,*images,exception);
7918             if (*option == '+')
7919               {
7920                 (void) RemapImages(quantize_info,*images,(Image *) NULL,
7921                   exception);
7922                 break;
7923               }
7924             i++;
7925             break;
7926           }
7927         if (LocaleCompare("maximum",option+1) == 0)
7928           {
7929             Image
7930               *maximum_image;
7931
7932             /*
7933               Maximum image sequence (deprecated).
7934             */
7935             (void) SyncImagesSettings(mogrify_info,*images,exception);
7936             maximum_image=EvaluateImages(*images,MaxEvaluateOperator,exception);
7937             if (maximum_image == (Image *) NULL)
7938               {
7939                 status=MagickFalse;
7940                 break;
7941               }
7942             *images=DestroyImageList(*images);
7943             *images=maximum_image;
7944             break;
7945           }
7946         if (LocaleCompare("minimum",option+1) == 0)
7947           {
7948             Image
7949               *minimum_image;
7950
7951             /*
7952               Minimum image sequence (deprecated).
7953             */
7954             (void) SyncImagesSettings(mogrify_info,*images,exception);
7955             minimum_image=EvaluateImages(*images,MinEvaluateOperator,exception);
7956             if (minimum_image == (Image *) NULL)
7957               {
7958                 status=MagickFalse;
7959                 break;
7960               }
7961             *images=DestroyImageList(*images);
7962             *images=minimum_image;
7963             break;
7964           }
7965         if (LocaleCompare("morph",option+1) == 0)
7966           {
7967             Image
7968               *morph_image;
7969
7970             (void) SyncImagesSettings(mogrify_info,*images,exception);
7971             morph_image=MorphImages(*images,StringToUnsignedLong(argv[i+1]),
7972               exception);
7973             if (morph_image == (Image *) NULL)
7974               {
7975                 status=MagickFalse;
7976                 break;
7977               }
7978             *images=DestroyImageList(*images);
7979             *images=morph_image;
7980             break;
7981           }
7982         if (LocaleCompare("mosaic",option+1) == 0)
7983           {
7984             Image
7985               *mosaic_image;
7986
7987             (void) SyncImagesSettings(mogrify_info,*images,exception);
7988             mosaic_image=MergeImageLayers(*images,MosaicLayer,exception);
7989             if (mosaic_image == (Image *) NULL)
7990               {
7991                 status=MagickFalse;
7992                 break;
7993               }
7994             *images=DestroyImageList(*images);
7995             *images=mosaic_image;
7996             break;
7997           }
7998         break;
7999       }
8000       case 'p':
8001       {
8002         if (LocaleCompare("print",option+1) == 0)
8003           {
8004             char
8005               *string;
8006
8007             (void) SyncImagesSettings(mogrify_info,*images,exception);
8008             string=InterpretImageProperties(mogrify_info,*images,argv[i+1],
8009               exception);
8010             if (string == (char *) NULL)
8011               break;
8012             (void) FormatLocaleFile(stdout,"%s",string);
8013             string=DestroyString(string);
8014           }
8015         if (LocaleCompare("process",option+1) == 0)
8016           {
8017             char
8018               **arguments;
8019
8020             int
8021               j,
8022               number_arguments;
8023
8024             (void) SyncImagesSettings(mogrify_info,*images,exception);
8025             arguments=StringToArgv(argv[i+1],&number_arguments);
8026             if (arguments == (char **) NULL)
8027               break;
8028             if ((argc > 1) && (strchr(arguments[1],'=') != (char *) NULL))
8029               {
8030                 char
8031                   breaker,
8032                   quote,
8033                   *token;
8034
8035                 const char
8036                   *arguments;
8037
8038                 int
8039                   next,
8040                   status;
8041
8042                 size_t
8043                   length;
8044
8045                 TokenInfo
8046                   *token_info;
8047
8048                 /*
8049                   Support old style syntax, filter="-option arg".
8050                 */
8051                 length=strlen(argv[i+1]);
8052                 token=(char *) NULL;
8053                 if (~length >= (MaxTextExtent-1))
8054                   token=(char *) AcquireQuantumMemory(length+MaxTextExtent,
8055                     sizeof(*token));
8056                 if (token == (char *) NULL)
8057                   break;
8058                 next=0;
8059                 arguments=argv[i+1];
8060                 token_info=AcquireTokenInfo();
8061                 status=Tokenizer(token_info,0,token,length,arguments,"","=",
8062                   "\"",'\0',&breaker,&next,&quote);
8063                 token_info=DestroyTokenInfo(token_info);
8064                 if (status == 0)
8065                   {
8066                     const char
8067                       *argv;
8068
8069                     argv=(&(arguments[next]));
8070                     (void) InvokeDynamicImageFilter(token,&(*images),1,&argv,
8071                       exception);
8072                   }
8073                 token=DestroyString(token);
8074                 break;
8075               }
8076             (void) SubstituteString(&arguments[1],"-","");
8077             (void) InvokeDynamicImageFilter(arguments[1],&(*images),
8078               number_arguments-2,(const char **) arguments+2,exception);
8079             for (j=0; j < number_arguments; j++)
8080               arguments[j]=DestroyString(arguments[j]);
8081             arguments=(char **) RelinquishMagickMemory(arguments);
8082             break;
8083           }
8084         break;
8085       }
8086       case 'r':
8087       {
8088         if (LocaleCompare("reverse",option+1) == 0)
8089           {
8090             ReverseImageList(images);
8091             break;
8092           }
8093         break;
8094       }
8095       case 's':
8096       {
8097         if (LocaleCompare("smush",option+1) == 0)
8098           {
8099             Image
8100               *smush_image;
8101
8102             ssize_t
8103               offset;
8104
8105             (void) SyncImagesSettings(mogrify_info,*images,exception);
8106             offset=(ssize_t) StringToLong(argv[i+1]);
8107             smush_image=SmushImages(*images,*option == '-' ? MagickTrue :
8108               MagickFalse,offset,exception);
8109             if (smush_image == (Image *) NULL)
8110               {
8111                 status=MagickFalse;
8112                 break;
8113               }
8114             *images=DestroyImageList(*images);
8115             *images=smush_image;
8116             break;
8117           }
8118         if (LocaleCompare("swap",option+1) == 0)
8119           {
8120             Image
8121               *p,
8122               *q,
8123               *swap;
8124
8125             ssize_t
8126               swap_index;
8127
8128             index=(-1);
8129             swap_index=(-2);
8130             if (*option != '+')
8131               {
8132                 GeometryInfo
8133                   geometry_info;
8134
8135                 MagickStatusType
8136                   flags;
8137
8138                 swap_index=(-1);
8139                 flags=ParseGeometry(argv[i+1],&geometry_info);
8140                 index=(ssize_t) geometry_info.rho;
8141                 if ((flags & SigmaValue) != 0)
8142                   swap_index=(ssize_t) geometry_info.sigma;
8143               }
8144             p=GetImageFromList(*images,index);
8145             q=GetImageFromList(*images,swap_index);
8146             if ((p == (Image *) NULL) || (q == (Image *) NULL))
8147               {
8148                 (void) ThrowMagickException(exception,GetMagickModule(),
8149                   OptionError,"NoSuchImage","`%s'",(*images)->filename);
8150                 status=MagickFalse;
8151                 break;
8152               }
8153             if (p == q)
8154               break;
8155             swap=CloneImage(p,0,0,MagickTrue,exception);
8156             ReplaceImageInList(&p,CloneImage(q,0,0,MagickTrue,exception));
8157             ReplaceImageInList(&q,swap);
8158             *images=GetFirstImageInList(q);
8159             break;
8160           }
8161         break;
8162       }
8163       case 'w':
8164       {
8165         if (LocaleCompare("write",option+1) == 0)
8166           {
8167             char
8168               key[MaxTextExtent];
8169
8170             Image
8171               *write_images;
8172
8173             ImageInfo
8174               *write_info;
8175
8176             (void) SyncImagesSettings(mogrify_info,*images,exception);
8177             (void) FormatLocaleString(key,MaxTextExtent,"cache:%s",argv[i+1]);
8178             (void) DeleteImageRegistry(key);
8179             write_images=(*images);
8180             if (*option == '+')
8181               write_images=CloneImageList(*images,exception);
8182             write_info=CloneImageInfo(mogrify_info);
8183             status&=WriteImages(write_info,write_images,argv[i+1],exception);
8184             write_info=DestroyImageInfo(write_info);
8185             if (*option == '+')
8186               write_images=DestroyImageList(write_images);
8187             break;
8188           }
8189         break;
8190       }
8191       default:
8192         break;
8193     }
8194     i+=count;
8195   }
8196   quantize_info=DestroyQuantizeInfo(quantize_info);
8197   mogrify_info=DestroyImageInfo(mogrify_info);
8198   status&=MogrifyImageInfo(image_info,argc,argv,exception);
8199   return(status != 0 ? MagickTrue : MagickFalse);
8200 }
8201 \f
8202 /*
8203 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8204 %                                                                             %
8205 %                                                                             %
8206 %                                                                             %
8207 +     M o g r i f y I m a g e s                                               %
8208 %                                                                             %
8209 %                                                                             %
8210 %                                                                             %
8211 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8212 %
8213 %  MogrifyImages() applies image processing options to a sequence of images as
8214 %  prescribed by command line options.
8215 %
8216 %  The format of the MogrifyImage method is:
8217 %
8218 %      MagickBooleanType MogrifyImages(ImageInfo *image_info,
8219 %        const MagickBooleanType post,const int argc,const char **argv,
8220 %        Image **images,Exceptioninfo *exception)
8221 %
8222 %  A description of each parameter follows:
8223 %
8224 %    o image_info: the image info..
8225 %
8226 %    o post: If true, post process image list operators otherwise pre-process.
8227 %
8228 %    o argc: Specifies a pointer to an integer describing the number of
8229 %      elements in the argument vector.
8230 %
8231 %    o argv: Specifies a pointer to a text array containing the command line
8232 %      arguments.
8233 %
8234 %    o images: pointer to a pointer of the first image in image list.
8235 %
8236 %    o exception: return any errors or warnings in this structure.
8237 %
8238 */
8239 WandExport MagickBooleanType MogrifyImages(ImageInfo *image_info,
8240   const MagickBooleanType post,const int argc,const char **argv,
8241   Image **images,ExceptionInfo *exception)
8242 {
8243 #define MogrifyImageTag  "Mogrify/Image"
8244
8245   MagickStatusType
8246     status;
8247
8248   MagickBooleanType
8249     proceed;
8250
8251   size_t
8252     n;
8253
8254   register ssize_t
8255     i;
8256
8257   assert(image_info != (ImageInfo *) NULL);
8258   assert(image_info->signature == MagickSignature);
8259   if (images == (Image **) NULL)
8260     return(MogrifyImage(image_info,argc,argv,images,exception));
8261   assert((*images)->previous == (Image *) NULL);
8262   assert((*images)->signature == MagickSignature);
8263   if ((*images)->debug != MagickFalse)
8264     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
8265       (*images)->filename);
8266   if ((argc <= 0) || (*argv == (char *) NULL))
8267     return(MagickTrue);
8268   (void) SetImageInfoProgressMonitor(image_info,(MagickProgressMonitor) NULL,
8269     (void *) NULL);
8270   status=0;
8271
8272 #if 0
8273   (void) FormatLocaleFile(stderr, "mogrify start %s %d (%s)\n",argv[0],argc,
8274     post?"post":"pre");
8275 #endif
8276
8277   /*
8278     Pre-process multi-image sequence operators
8279   */
8280   if (post == MagickFalse)
8281     status&=MogrifyImageList(image_info,argc,argv,images,exception);
8282   /*
8283     For each image, process simple single image operators
8284   */
8285   i=0;
8286   n=GetImageListLength(*images);
8287   for ( ; ; )
8288   {
8289 #if 0
8290   (void) FormatLocaleFile(stderr,"mogrify %ld of %ld\n",(long)
8291     GetImageIndexInList(*images),(long)GetImageListLength(*images));
8292 #endif
8293     status&=MogrifyImage(image_info,argc,argv,images,exception);
8294     proceed=SetImageProgress(*images,MogrifyImageTag,(MagickOffsetType) i, n);
8295     if (proceed == MagickFalse)
8296       break;
8297     if ( (*images)->next == (Image *) NULL )
8298       break;
8299     *images=(*images)->next;
8300     i++;
8301   }
8302   assert( *images != (Image *) NULL );
8303 #if 0
8304   (void) FormatLocaleFile(stderr,"mogrify end %ld of %ld\n",(long)
8305     GetImageIndexInList(*images),(long)GetImageListLength(*images));
8306 #endif
8307
8308   /*
8309     Post-process, multi-image sequence operators
8310   */
8311   *images=GetFirstImageInList(*images);
8312   if (post != MagickFalse)
8313     status&=MogrifyImageList(image_info,argc,argv,images,exception);
8314   return(status != 0 ? MagickTrue : MagickFalse);
8315 }