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