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