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