]> granicus.if.org Git - imagemagick/blob - MagickWand/composite.c
...
[imagemagick] / MagickWand / composite.c
1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 %                                                                             %
4 %                                                                             %
5 %                                                                             %
6 %        CCCC    OOO   M   M  PPPP    OOO   SSSSS  IIIII  TTTTT  EEEEE        %
7 %       C       O   O  MM MM  P   P  O   O  SS       I      T    E            %
8 %       C       O   O  M M M  PPPP   O   O   SSS     I      T    EEE          %
9 %       C       O   O  M   M  P      O   O     SS    I      T    E            %
10 %        CCCC    OOO   M   M  P       OOO   SSSSS  IIIII    T    EEEEE        %
11 %                                                                             %
12 %                                                                             %
13 %                      MagickWand Image Composite Methods                     %
14 %                                                                             %
15 %                              Software Design                                %
16 %                                   Cristy                                    %
17 %                                 July 1992                                   %
18 %                                                                             %
19 %                                                                             %
20 %  Copyright 1999-2017 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 composite program to overlap one image over another.
37 %
38 */
39 \f
40 /*
41   Include declarations.
42 */
43 #include "MagickWand/studio.h"
44 #include "MagickWand/MagickWand.h"
45 #include "MagickWand/mogrify-private.h"
46 #include "MagickCore/string-private.h"
47 \f
48 /*
49   Typedef declarations.
50 */
51 typedef struct _CompositeOptions
52 {
53   ChannelType
54     channel;
55
56   char
57     *compose_args,
58     *geometry;
59
60   CompositeOperator
61     compose;
62
63   GravityType
64     gravity;
65
66   ssize_t
67     stegano;
68
69   RectangleInfo
70     offset;
71
72   MagickBooleanType
73     stereo,
74     tile;
75 } CompositeOptions;
76 \f
77 /*
78 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
79 %                                                                             %
80 %                                                                             %
81 %                                                                             %
82 %  C o m p o s i t e I m a g e C o m m a n d                                  %
83 %                                                                             %
84 %                                                                             %
85 %                                                                             %
86 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
87 %
88 %  CompositeImageCommand() reads one or more images and an optional mask and
89 %  composites them into a new image.
90 %
91 %  The format of the CompositeImageCommand method is:
92 %
93 %      MagickBooleanType CompositeImageCommand(ImageInfo *image_info,int argc,
94 %        char **argv,char **metadata,ExceptionInfo *exception)
95 %
96 %  A description of each parameter follows:
97 %
98 %    o image_info: the image info.
99 %
100 %    o argc: the number of elements in the argument vector.
101 %
102 %    o argv: A text array containing the command line arguments.
103 %
104 %    o metadata: any metadata is returned here.
105 %
106 %    o exception: return any errors or warnings in this structure.
107 %
108 */
109
110 static MagickBooleanType CompositeImageList(ImageInfo *image_info,Image **image,
111   Image *composite_image,CompositeOptions *composite_options,
112   ExceptionInfo *exception)
113 {
114   MagickStatusType
115     status;
116
117   assert(image_info != (ImageInfo *) NULL);
118   assert(image_info->signature == MagickCoreSignature);
119   assert(image != (Image **) NULL);
120   assert((*image)->signature == MagickCoreSignature);
121   if ((*image)->debug != MagickFalse)
122     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",(*image)->filename);
123   assert(exception != (ExceptionInfo *) NULL);
124   status=MagickTrue;
125   if (composite_image != (Image *) NULL)
126     {
127       ChannelType
128         channel_mask;
129
130       channel_mask=SetImageChannelMask(composite_image,
131         composite_options->channel);
132       assert(composite_image->signature == MagickCoreSignature);
133       switch (composite_options->compose)
134       {
135         case BlendCompositeOp:
136         case BlurCompositeOp:
137         case DisplaceCompositeOp:
138         case DistortCompositeOp:
139         case DissolveCompositeOp:
140         case ModulateCompositeOp:
141         case ThresholdCompositeOp:
142         {
143           (void) SetImageArtifact(*image,"compose:args",
144             composite_options->compose_args);
145           break;
146         }
147         default:
148           break;
149       }
150       /*
151         Composite image.
152       */
153       if (composite_options->stegano != 0)
154         {
155           Image
156             *stegano_image;
157
158           (*image)->offset=composite_options->stegano-1;
159           stegano_image=SteganoImage(*image,composite_image,exception);
160           if (stegano_image != (Image *) NULL)
161             {
162               *image=DestroyImageList(*image);
163               *image=stegano_image;
164             }
165         }
166       else
167         if (composite_options->stereo != MagickFalse)
168           {
169             Image
170               *stereo_image;
171
172             stereo_image=StereoAnaglyphImage(*image,composite_image,
173               composite_options->offset.x,composite_options->offset.y,
174               exception);
175             if (stereo_image != (Image *) NULL)
176               {
177                 *image=DestroyImageList(*image);
178                 *image=stereo_image;
179               }
180           }
181         else
182           if (composite_options->tile != MagickFalse)
183             {
184               size_t
185                 columns;
186
187               ssize_t
188                 x,
189                 y;
190
191               /*
192                 Tile the composite image.
193               */
194               (void) SetImageArtifact(*image,"compose:outside-overlay","false");
195               columns=composite_image->columns;
196               for (y=0; y < (ssize_t) (*image)->rows; y+=(ssize_t) composite_image->rows)
197                 for (x=0; x < (ssize_t) (*image)->columns; x+=(ssize_t) columns)
198                   status&=CompositeImage(*image,composite_image,
199                     composite_options->compose,MagickTrue,x,y,exception);
200             }
201           else
202             {
203               RectangleInfo
204                 geometry;
205
206               /*
207                 Work out gravity Adjustment of Offset
208               */
209               SetGeometry(*image,&geometry);
210               (void) ParseAbsoluteGeometry(composite_options->geometry,
211                 &geometry);
212               geometry.width=composite_image->columns;
213               geometry.height=composite_image->rows;
214               GravityAdjustGeometry((*image)->columns,(*image)->rows,
215                 composite_options->gravity, &geometry);
216               (*image)->gravity=(GravityType) composite_options->gravity;
217               /*
218                 Digitally composite image.
219               */
220               status&=CompositeImage(*image,composite_image,
221                 composite_options->compose,MagickTrue,geometry.x,geometry.y,
222                 exception);
223             }
224       (void) SetPixelChannelMask(composite_image,channel_mask);
225     }
226   return(status != 0 ? MagickTrue : MagickFalse);
227 }
228
229 static MagickBooleanType CompositeUsage(void)
230 {
231   const char
232     **p;
233
234   static const char
235     *miscellaneous[]=
236     {
237       "-debug events        display copious debugging information",
238       "-help                print program options",
239       "-list type           print a list of supported option arguments",
240       "-log format          format of debugging information",
241       "-version             print version information",
242       (char *) NULL
243     },
244     *operators[]=
245     {
246       "-blend geometry      blend images",
247       "-border geometry     surround image with a border of color",
248       "-bordercolor color   border color",
249       "-channel mask        set the image channel mask",
250       "-colors value        preferred number of colors in the image",
251       "-decipher filename    convert cipher pixels to plain pixels",
252       "-displace geometry   shift lookup according to a relative displacement map",
253       "-dissolve value      dissolve the two images a given percent",
254       "-distort geometry    shift lookup according to a absolute distortion map",
255       "-encipher filename   convert plain pixels to cipher pixels",
256       "-extract geometry    extract area from image",
257       "-geometry geometry   location of the composite image",
258       "-identify            identify the format and characteristics of the image",
259       "-monochrome          transform image to black and white",
260       "-negate              replace every pixel with its complementary color ",
261       "-profile filename    add ICM or IPTC information profile to image",
262       "-quantize colorspace reduce colors in this colorspace",
263       "-repage geometry     size and location of an image canvas (operator)",
264       "-rotate degrees      apply Paeth rotation to the image",
265       "-resize geometry     resize the image",
266       "-sharpen geometry    sharpen the image",
267       "-shave geometry      shave pixels from the image edges",
268       "-stegano offset      hide watermark within an image",
269       "-stereo geometry     combine two image to create a stereo anaglyph",
270       "-strip               strip image of all profiles and comments",
271       "-thumbnail geometry  create a thumbnail of the image",
272       "-transform           affine transform image",
273       "-type type           image type",
274       "-unsharp geometry    sharpen the image",
275       "-watermark geometry  percent brightness and saturation of a watermark",
276       "-write filename      write images to this file",
277       (char *) NULL
278     },
279     *settings[]=
280     {
281       "-affine matrix       affine transform matrix",
282       "-alpha option        on, activate, off, deactivate, set, opaque, copy",
283       "                     transparent, extract, background, or shape",
284       "-authenticate password",
285       "                     decipher image with this password",
286       "-blue-primary point  chromaticity blue primary point",
287       "-colorspace type     alternate image colorspace",
288       "-comment string      annotate image with comment",
289       "-compose operator    composite operator",
290       "-compress type       type of pixel compression when writing the image",
291       "-define format:option",
292       "                     define one or more image format options",
293       "-depth value         image depth",
294       "-density geometry    horizontal and vertical density of the image",
295       "-display server      get image or font from this X server",
296       "-dispose method      layer disposal method",
297       "-dither method       apply error diffusion to image",
298       "-encoding type       text encoding type",
299       "-endian type         endianness (MSB or LSB) of the image",
300       "-filter type         use this filter when resizing an image",
301       "-font name           render text with this font",
302       "-format \"string\"     output formatted image characteristics",
303       "-gravity type        which direction to gravitate towards",
304       "-green-primary point chromaticity green primary point",
305       "-interlace type      type of image interlacing scheme",
306       "-interpolate method  pixel color interpolation method",
307       "-label string        assign a label to an image",
308       "-limit type value    pixel cache resource limit",
309       "-matte               store matte channel if the image has one",
310       "-monitor             monitor progress",
311       "-page geometry       size and location of an image canvas (setting)",
312       "-pointsize value     font point size",
313       "-quality value       JPEG/MIFF/PNG compression level",
314       "-quiet               suppress all warning messages",
315       "-red-primary point   chromaticity red primary point",
316       "-regard-warnings     pay attention to warning messages",
317       "-respect-parentheses settings remain in effect until parenthesis boundary",
318       "-sampling-factor geometry",
319       "                     horizontal and vertical sampling factor",
320       "-scene value         image scene number",
321       "-seed value          seed a new sequence of pseudo-random numbers",
322       "-size geometry       width and height of image",
323       "-support factor      resize support: > 1.0 is blurry, < 1.0 is sharp",
324       "-synchronize         synchronize image to storage device",
325       "-taint               declare the image as modified",
326       "-transparent-color color",
327       "                     transparent color",
328       "-treedepth value     color tree depth",
329       "-tile                repeat composite operation across and down image",
330       "-units type          the units of image resolution",
331       "-verbose             print detailed information about the image",
332       "-virtual-pixel method",
333       "                     virtual pixel access method",
334       "-white-point point   chromaticity white point",
335       (char *) NULL
336     },
337     *stack_operators[]=
338     {
339       "-swap indexes        swap two images in the image sequence",
340       (char *) NULL
341     };
342
343
344   ListMagickVersion(stdout);
345   (void) printf("Usage: %s [options ...] image [options ...] composite\n"
346     "  [ [options ...] mask ] [options ...] composite\n",
347     GetClientName());
348   (void) printf("\nImage Settings:\n");
349   for (p=settings; *p != (char *) NULL; p++)
350     (void) printf("  %s\n",*p);
351   (void) printf("\nImage Operators:\n");
352   for (p=operators; *p != (char *) NULL; p++)
353     (void) printf("  %s\n",*p);
354   (void) printf("\nImage Stack Operators:\n");
355   for (p=stack_operators; *p != (char *) NULL; p++)
356     (void) printf("  %s\n",*p);
357   (void) printf("\nMiscellaneous Options:\n");
358   for (p=miscellaneous; *p != (char *) NULL; p++)
359     (void) printf("  %s\n",*p);
360   (void) printf(
361     "\nBy default, the image format of 'file' is determined by its magic\n");
362   (void) printf(
363     "number.  To specify a particular image format, precede the filename\n");
364   (void) printf(
365     "with an image format name and a colon (i.e. ps:image) or specify the\n");
366   (void) printf(
367     "image type as the filename suffix (i.e. image.ps).  Specify 'file' as\n");
368   (void) printf("'-' for standard input or output.\n");
369   return(MagickFalse);
370 }
371
372 static void GetCompositeOptions(CompositeOptions *composite_options)
373 {
374   (void) ResetMagickMemory(composite_options,0,sizeof(*composite_options));
375   composite_options->channel=DefaultChannels;
376   composite_options->compose=OverCompositeOp;
377 }
378
379 static void RelinquishCompositeOptions(CompositeOptions *composite_options)
380 {
381   if (composite_options->compose_args != (char *) NULL)
382     composite_options->compose_args=(char *)
383       RelinquishMagickMemory(composite_options->compose_args);
384   if (composite_options->geometry != (char *) NULL)
385     composite_options->geometry=(char *)
386       RelinquishMagickMemory(composite_options->geometry);
387 }
388
389 WandExport MagickBooleanType CompositeImageCommand(ImageInfo *image_info,
390   int argc,char **argv,char **metadata,ExceptionInfo *exception)
391 {
392 #define NotInitialized  (unsigned int) (~0)
393 #define DestroyComposite() \
394 { \
395   RelinquishCompositeOptions(&composite_options); \
396   DestroyImageStack(); \
397   for (i=0; i < (ssize_t) argc; i++) \
398     argv[i]=DestroyString(argv[i]); \
399   argv=(char **) RelinquishMagickMemory(argv); \
400 }
401 #define ThrowCompositeException(asperity,tag,option) \
402 { \
403   (void) ThrowMagickException(exception,GetMagickModule(),asperity,tag,"`%s'", \
404      option == (char *) NULL ? GetExceptionMessage(errno) : option); \
405   DestroyComposite(); \
406   return(MagickFalse); \
407 }
408 #define ThrowCompositeInvalidArgumentException(option,argument) \
409 { \
410   (void) ThrowMagickException(exception,GetMagickModule(),OptionError, \
411     "InvalidArgument","'%s': %s",option,argument); \
412   DestroyComposite(); \
413   return(MagickFalse); \
414 }
415
416   char
417     *filename,
418     *option;
419
420   CompositeOptions
421     composite_options;
422
423   const char
424     *format;
425
426   Image
427     *composite_image,
428     *image,
429     *images,
430     *mask_image;
431
432   ImageStack
433     image_stack[MaxImageStackDepth+1];
434
435   MagickBooleanType
436     fire,
437     pend,
438     respect_parenthesis;
439
440   MagickStatusType
441     status;
442
443   register ssize_t
444     i;
445
446   ssize_t
447     j,
448     k;
449
450   /*
451     Set default.
452   */
453   assert(image_info != (ImageInfo *) NULL);
454   assert(image_info->signature == MagickCoreSignature);
455   if (image_info->debug != MagickFalse)
456     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
457   assert(exception != (ExceptionInfo *) NULL);
458   if (argc == 2)
459     {
460       option=argv[1];
461       if ((LocaleCompare("version",option+1) == 0) ||
462           (LocaleCompare("-version",option+1) == 0))
463         {
464           ListMagickVersion(stdout);
465           return(MagickTrue);
466         }
467     }
468   if (argc < 4)
469     return(CompositeUsage());
470   GetCompositeOptions(&composite_options);
471   filename=(char *) NULL;
472   format="%w,%h,%m";
473   j=1;
474   k=0;
475   NewImageStack();
476   option=(char *) NULL;
477   pend=MagickFalse;
478   respect_parenthesis=MagickFalse;
479   status=MagickTrue;
480   /*
481     Check command syntax.
482   */
483   composite_image=NewImageList();
484   image=NewImageList();
485   mask_image=NewImageList();
486   ReadCommandlLine(argc,&argv);
487   status=ExpandFilenames(&argc,&argv);
488   if (status == MagickFalse)
489     ThrowCompositeException(ResourceLimitError,"MemoryAllocationFailed",
490       GetExceptionMessage(errno));
491   for (i=1; i < (ssize_t) (argc-1); i++)
492   {
493     option=argv[i];
494     if (LocaleCompare(option,"(") == 0)
495       {
496         FireImageStack(MagickFalse,MagickTrue,pend);
497         if (k == MaxImageStackDepth)
498           ThrowCompositeException(OptionError,"ParenthesisNestedTooDeeply",
499             option);
500         PushImageStack();
501         continue;
502       }
503     if (LocaleCompare(option,")") == 0)
504       {
505         FireImageStack(MagickFalse,MagickTrue,MagickTrue);
506         if (k == 0)
507           ThrowCompositeException(OptionError,"UnableToParseExpression",option);
508         PopImageStack();
509         continue;
510       }
511     if (IsCommandOption(option) == MagickFalse)
512       {
513         /*
514           Read input image.
515         */
516         FireImageStack(MagickFalse,MagickFalse,pend);
517         filename=argv[i];
518         if ((LocaleCompare(filename,"--") == 0) && (i < (ssize_t) (argc-1)))
519           filename=argv[++i];
520         images=ReadImages(image_info,filename,exception);
521         status&=(images != (Image *) NULL) &&
522           (exception->severity < ErrorException);
523         if (images == (Image *) NULL)
524           continue;
525         AppendImageStack(images);
526         continue;
527       }
528     pend=image != (Image *) NULL ? MagickTrue : MagickFalse;
529     switch (*(option+1))
530     {
531       case 'a':
532       {
533         if (LocaleCompare("affine",option+1) == 0)
534           {
535             if (*option == '+')
536               break;
537             i++;
538             if (i == (ssize_t) argc)
539               ThrowCompositeException(OptionError,"MissingArgument",option);
540             if (IsGeometry(argv[i]) == MagickFalse)
541               ThrowCompositeInvalidArgumentException(option,argv[i]);
542             break;
543           }
544         if (LocaleCompare("alpha",option+1) == 0)
545           {
546             ssize_t
547               type;
548
549             if (*option == '+')
550               break;
551             i++;
552             if (i == (ssize_t) argc)
553               ThrowCompositeException(OptionError,"MissingArgument",option);
554             type=ParseCommandOption(MagickAlphaChannelOptions,MagickFalse,argv[i]);
555             if (type < 0)
556               ThrowCompositeException(OptionError,
557                 "UnrecognizedAlphaChannelOption",argv[i]);
558             break;
559           }
560         if (LocaleCompare("authenticate",option+1) == 0)
561           {
562             if (*option == '+')
563               break;
564             i++;
565             if (i == (ssize_t) argc)
566               ThrowCompositeException(OptionError,"MissingArgument",option);
567             break;
568           }
569         ThrowCompositeException(OptionError,"UnrecognizedOption",option)
570       }
571       case 'b':
572       {
573         if (LocaleCompare("background",option+1) == 0)
574           {
575             if (*option == '+')
576               break;
577             i++;
578             if (i == (ssize_t) argc)
579               ThrowCompositeException(OptionError,"MissingArgument",option);
580             break;
581           }
582         if (LocaleCompare("blend",option+1) == 0)
583           {
584             (void) CloneString(&composite_options.compose_args,(char *) NULL);
585             if (*option == '+')
586               break;
587             i++;
588             if (i == (ssize_t) argc)
589               ThrowCompositeException(OptionError,"MissingArgument",option);
590             if (IsGeometry(argv[i]) == MagickFalse)
591               ThrowCompositeInvalidArgumentException(option,argv[i]);
592             (void) CloneString(&composite_options.compose_args,argv[i]);
593             composite_options.compose=BlendCompositeOp;
594             break;
595           }
596         if (LocaleCompare("blur",option+1) == 0)
597           {
598             (void) CloneString(&composite_options.compose_args,(char *) NULL);
599             if (*option == '+')
600               break;
601             i++;
602             if (i == (ssize_t) argc)
603               ThrowCompositeException(OptionError,"MissingArgument",option);
604             if (IsGeometry(argv[i]) == MagickFalse)
605               ThrowCompositeInvalidArgumentException(option,argv[i]);
606             (void) CloneString(&composite_options.compose_args,argv[i]);
607             composite_options.compose=BlurCompositeOp;
608             break;
609           }
610         if (LocaleCompare("blue-primary",option+1) == 0)
611           {
612             if (*option == '+')
613               break;
614             i++;
615             if (i == (ssize_t) argc)
616               ThrowCompositeException(OptionError,"MissingArgument",option);
617             if (IsGeometry(argv[i]) == MagickFalse)
618               ThrowCompositeInvalidArgumentException(option,argv[i]);
619             break;
620           }
621         if (LocaleCompare("border",option+1) == 0)
622           {
623             if (*option == '+')
624               break;
625             i++;
626             if (i == (ssize_t) argc)
627               ThrowCompositeException(OptionError,"MissingArgument",option);
628             if (IsGeometry(argv[i]) == MagickFalse)
629               ThrowCompositeInvalidArgumentException(option,argv[i]);
630             break;
631           }
632         if (LocaleCompare("bordercolor",option+1) == 0)
633           {
634             if (*option == '+')
635               break;
636             i++;
637             if (i == (ssize_t) argc)
638               ThrowCompositeException(OptionError,"MissingArgument",option);
639             break;
640           }
641         ThrowCompositeException(OptionError,"UnrecognizedOption",option)
642       }
643       case 'c':
644       {
645         if (LocaleCompare("cache",option+1) == 0)
646           {
647             if (*option == '+')
648               break;
649             i++;
650             if (i == (ssize_t) argc)
651               ThrowCompositeException(OptionError,"MissingArgument",option);
652             if (IsGeometry(argv[i]) == MagickFalse)
653               ThrowCompositeInvalidArgumentException(option,argv[i]);
654             break;
655           }
656         if (LocaleCompare("channel",option+1) == 0)
657           {
658             ssize_t
659               channel;
660
661             if (*option == '+')
662               {
663                 composite_options.channel=DefaultChannels;
664                 break;
665               }
666             i++;
667             if (i == (ssize_t) argc)
668               ThrowCompositeException(OptionError,"MissingArgument",option);
669             channel=ParseChannelOption(argv[i]);
670             if (channel < 0)
671               ThrowCompositeException(OptionError,"UnrecognizedChannelType",
672                 argv[i]);
673             composite_options.channel=(ChannelType) channel;
674             break;
675           }
676         if (LocaleCompare("colors",option+1) == 0)
677           {
678             if (*option == '+')
679               break;
680             i++;
681             if (i == (ssize_t) argc)
682               ThrowCompositeException(OptionError,"MissingArgument",option);
683             if (IsGeometry(argv[i]) == MagickFalse)
684               ThrowCompositeInvalidArgumentException(option,argv[i]);
685             break;
686           }
687         if (LocaleCompare("colorspace",option+1) == 0)
688           {
689             ssize_t
690               colorspace;
691
692             if (*option == '+')
693               break;
694             i++;
695             if (i == (ssize_t) argc)
696               ThrowCompositeException(OptionError,"MissingArgument",option);
697             colorspace=ParseCommandOption(MagickColorspaceOptions,
698               MagickFalse,argv[i]);
699             if (colorspace < 0)
700               ThrowCompositeException(OptionError,"UnrecognizedColorspace",
701                 argv[i]);
702             break;
703           }
704         if (LocaleCompare("comment",option+1) == 0)
705           {
706             if (*option == '+')
707               break;
708             i++;
709             if (i == (ssize_t) argc)
710               ThrowCompositeException(OptionError,"MissingArgument",option);
711             break;
712           }
713         if (LocaleCompare("compose",option+1) == 0)
714           {
715             ssize_t
716               compose;
717
718             composite_options.compose=UndefinedCompositeOp;
719             if (*option == '+')
720               break;
721             i++;
722             if (i == (ssize_t) argc)
723               ThrowCompositeException(OptionError,"MissingArgument",option);
724             compose=ParseCommandOption(MagickComposeOptions,MagickFalse,
725               argv[i]);
726             if (compose < 0)
727               ThrowCompositeException(OptionError,"UnrecognizedComposeOperator",
728                 argv[i]);
729             composite_options.compose=(CompositeOperator) compose;
730             break;
731           }
732         if (LocaleCompare("compress",option+1) == 0)
733           {
734             ssize_t
735               compress;
736
737             if (*option == '+')
738               break;
739             i++;
740             if (i == (ssize_t) argc)
741               ThrowCompositeException(OptionError,"MissingArgument",option);
742             compress=ParseCommandOption(MagickCompressOptions,MagickFalse,
743               argv[i]);
744             if (compress < 0)
745               ThrowCompositeException(OptionError,
746                 "UnrecognizedImageCompression",argv[i]);
747             break;
748           }
749         if (LocaleCompare("concurrent",option+1) == 0)
750           break;
751         ThrowCompositeException(OptionError,"UnrecognizedOption",option)
752       }
753       case 'd':
754       {
755         if (LocaleCompare("debug",option+1) == 0)
756           {
757             ssize_t
758               event;
759
760             if (*option == '+')
761               break;
762             i++;
763             if (i == (ssize_t) argc)
764               ThrowCompositeException(OptionError,"MissingArgument",option);
765             event=ParseCommandOption(MagickLogEventOptions,MagickFalse,argv[i]);
766             if (event < 0)
767               ThrowCompositeException(OptionError,"UnrecognizedEventType",
768                 argv[i]);
769             (void) SetLogEventMask(argv[i]);
770             break;
771           }
772         if (LocaleCompare("decipher",option+1) == 0)
773           {
774             if (*option == '+')
775               break;
776             i++;
777             if (i == (ssize_t) argc)
778               ThrowCompositeException(OptionError,"MissingArgument",option);
779             break;
780           }
781         if (LocaleCompare("define",option+1) == 0)
782           {
783             i++;
784             if (i == (ssize_t) argc)
785               ThrowCompositeException(OptionError,"MissingArgument",option);
786             if (*option == '+')
787               {
788                 const char
789                   *define;
790
791                 define=GetImageOption(image_info,argv[i]);
792                 if (define == (const char *) NULL)
793                   ThrowCompositeException(OptionError,"NoSuchOption",argv[i]);
794                 break;
795               }
796             break;
797           }
798         if (LocaleCompare("density",option+1) == 0)
799           {
800             if (*option == '+')
801               break;
802             i++;
803             if (i == (ssize_t) argc)
804               ThrowCompositeException(OptionError,"MissingArgument",option);
805             if (IsGeometry(argv[i]) == MagickFalse)
806               ThrowCompositeInvalidArgumentException(option,argv[i]);
807             break;
808           }
809         if (LocaleCompare("depth",option+1) == 0)
810           {
811             if (*option == '+')
812               break;
813             i++;
814             if (i == (ssize_t) argc)
815               ThrowCompositeException(OptionError,"MissingArgument",option);
816             if (IsGeometry(argv[i]) == MagickFalse)
817               ThrowCompositeInvalidArgumentException(option,argv[i]);
818             break;
819           }
820         if (LocaleCompare("displace",option+1) == 0)
821           {
822             (void) CloneString(&composite_options.compose_args,(char *) NULL);
823             if (*option == '+')
824               break;
825             i++;
826             if (i == (ssize_t) argc)
827               ThrowCompositeException(OptionError,"MissingArgument",option);
828             if (IsGeometry(argv[i]) == MagickFalse)
829               ThrowCompositeInvalidArgumentException(option,argv[i]);
830             (void) CloneString(&composite_options.compose_args,argv[i]);
831             composite_options.compose=DisplaceCompositeOp;
832             break;
833           }
834         if (LocaleCompare("display",option+1) == 0)
835           {
836             if (*option == '+')
837               break;
838             i++;
839             if (i == (ssize_t) argc)
840               ThrowCompositeException(OptionError,"MissingArgument",option);
841             break;
842           }
843         if (LocaleCompare("dispose",option+1) == 0)
844           {
845             ssize_t
846               dispose;
847
848             if (*option == '+')
849               break;
850             i++;
851             if (i == (ssize_t) argc)
852               ThrowCompositeException(OptionError,"MissingArgument",option);
853             dispose=ParseCommandOption(MagickDisposeOptions,MagickFalse,argv[i]);
854             if (dispose < 0)
855               ThrowCompositeException(OptionError,"UnrecognizedDisposeMethod",
856                 argv[i]);
857             break;
858           }
859         if (LocaleCompare("dissolve",option+1) == 0)
860           {
861             (void) CloneString(&composite_options.compose_args,(char *) NULL);
862             if (*option == '+')
863               break;
864             i++;
865             if (i == (ssize_t) argc)
866               ThrowCompositeException(OptionError,"MissingArgument",option);
867             if (IsGeometry(argv[i]) == MagickFalse)
868               ThrowCompositeInvalidArgumentException(option,argv[i]);
869             (void) CloneString(&composite_options.compose_args,argv[i]);
870             composite_options.compose=DissolveCompositeOp;
871             break;
872           }
873         if (LocaleCompare("distort",option+1) == 0)
874           {
875             (void) CloneString(&composite_options.compose_args,(char *) NULL);
876             if (*option == '+')
877               break;
878             i++;
879             if (i == (ssize_t) argc)
880               ThrowCompositeException(OptionError,"MissingArgument",option);
881             if (IsGeometry(argv[i]) == MagickFalse)
882               ThrowCompositeInvalidArgumentException(option,argv[i]);
883             (void) CloneString(&composite_options.compose_args,argv[i]);
884             composite_options.compose=DistortCompositeOp;
885             break;
886           }
887         if (LocaleCompare("dither",option+1) == 0)
888           {
889             ssize_t
890               method;
891
892             if (*option == '+')
893               break;
894             i++;
895             if (i == (ssize_t) argc)
896               ThrowCompositeException(OptionError,"MissingArgument",option);
897             method=ParseCommandOption(MagickDitherOptions,MagickFalse,argv[i]);
898             if (method < 0)
899               ThrowCompositeException(OptionError,"UnrecognizedDitherMethod",
900                 argv[i]);
901             break;
902           }
903         if (LocaleCompare("duration",option+1) == 0)
904           {
905             if (*option == '+')
906               break;
907             i++;
908             if (i == (ssize_t) argc)
909               ThrowCompositeException(OptionError,"MissingArgument",option);
910             if (IsGeometry(argv[i]) == MagickFalse)
911               ThrowCompositeInvalidArgumentException(option,argv[i]);
912             break;
913           }
914         ThrowCompositeException(OptionError,"UnrecognizedOption",option)
915       }
916       case 'e':
917       {
918         if (LocaleCompare("encipher",option+1) == 0)
919           {
920             if (*option == '+')
921               break;
922             i++;
923             if (i == (ssize_t) argc)
924               ThrowCompositeException(OptionError,"MissingArgument",option);
925             break;
926           }
927         if (LocaleCompare("encoding",option+1) == 0)
928           {
929             if (*option == '+')
930               break;
931             i++;
932             if (i == (ssize_t) argc)
933               ThrowCompositeException(OptionError,"MissingArgument",option);
934             break;
935           }
936         if (LocaleCompare("endian",option+1) == 0)
937           {
938             ssize_t
939               endian;
940
941             if (*option == '+')
942               break;
943             i++;
944             if (i == (ssize_t) argc)
945               ThrowCompositeException(OptionError,"MissingArgument",option);
946             endian=ParseCommandOption(MagickEndianOptions,MagickFalse,
947               argv[i]);
948             if (endian < 0)
949               ThrowCompositeException(OptionError,"UnrecognizedEndianType",
950                 argv[i]);
951             break;
952           }
953         if (LocaleCompare("extract",option+1) == 0)
954           {
955             if (*option == '+')
956               break;
957             i++;
958             if (i == (ssize_t) argc)
959               ThrowCompositeException(OptionError,"MissingArgument",option);
960             if (IsGeometry(argv[i]) == MagickFalse)
961               ThrowCompositeInvalidArgumentException(option,argv[i]);
962             break;
963           }
964         ThrowCompositeException(OptionError,"UnrecognizedOption",option)
965       }
966       case 'f':
967       {
968         if (LocaleCompare("filter",option+1) == 0)
969           {
970             ssize_t
971               filter;
972
973             if (*option == '+')
974               break;
975             i++;
976             if (i == (ssize_t) argc)
977               ThrowCompositeException(OptionError,"MissingArgument",option);
978             filter=ParseCommandOption(MagickFilterOptions,MagickFalse,argv[i]);
979             if (filter < 0)
980               ThrowCompositeException(OptionError,"UnrecognizedImageFilter",
981                 argv[i]);
982             break;
983           }
984         if (LocaleCompare("font",option+1) == 0)
985           {
986             if (*option == '+')
987               break;
988             i++;
989             if (i == (ssize_t) argc)
990               ThrowCompositeException(OptionError,"MissingArgument",option);
991             break;
992           }
993         if (LocaleCompare("format",option+1) == 0)
994           {
995             if (*option == '+')
996               break;
997             i++;
998             if (i == (ssize_t) argc)
999               ThrowCompositeException(OptionError,"MissingArgument",option);
1000             format=argv[i];
1001             break;
1002           }
1003         ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1004       }
1005       case 'g':
1006       {
1007         if (LocaleCompare("geometry",option+1) == 0)
1008           {
1009             (void) CloneString(&composite_options.geometry,(char *) NULL);
1010             if (*option == '+')
1011               break;
1012             i++;
1013             if (i == (ssize_t) argc)
1014               ThrowCompositeException(OptionError,"MissingArgument",option);
1015             if (IsGeometry(argv[i]) == MagickFalse)
1016               ThrowCompositeInvalidArgumentException(option,argv[i]);
1017             (void) CloneString(&composite_options.geometry,argv[i]);
1018             break;
1019           }
1020         if (LocaleCompare("gravity",option+1) == 0)
1021           {
1022             ssize_t
1023               gravity;
1024
1025             composite_options.gravity=UndefinedGravity;
1026             if (*option == '+')
1027               break;
1028             i++;
1029             if (i == (ssize_t) argc)
1030               ThrowCompositeException(OptionError,"MissingArgument",option);
1031             gravity=ParseCommandOption(MagickGravityOptions,MagickFalse,
1032               argv[i]);
1033             if (gravity < 0)
1034               ThrowCompositeException(OptionError,"UnrecognizedGravityType",
1035                 argv[i]);
1036             composite_options.gravity=(GravityType) gravity;
1037             break;
1038           }
1039         if (LocaleCompare("green-primary",option+1) == 0)
1040           {
1041             if (*option == '+')
1042               break;
1043             i++;
1044             if (i == (ssize_t) argc)
1045               ThrowCompositeException(OptionError,"MissingArgument",option);
1046             if (IsGeometry(argv[i]) == MagickFalse)
1047               ThrowCompositeInvalidArgumentException(option,argv[i]);
1048             break;
1049           }
1050         ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1051       }
1052       case 'h':
1053       {
1054         if ((LocaleCompare("help",option+1) == 0) ||
1055             (LocaleCompare("-help",option+1) == 0))
1056           return(CompositeUsage());
1057         ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1058       }
1059       case 'i':
1060       {
1061         if (LocaleCompare("identify",option+1) == 0)
1062           break;
1063         if (LocaleCompare("interlace",option+1) == 0)
1064           {
1065             ssize_t
1066               interlace;
1067
1068             if (*option == '+')
1069               break;
1070             i++;
1071             if (i == (ssize_t) argc)
1072               ThrowCompositeException(OptionError,"MissingArgument",option);
1073             interlace=ParseCommandOption(MagickInterlaceOptions,MagickFalse,
1074               argv[i]);
1075             if (interlace < 0)
1076               ThrowCompositeException(OptionError,
1077                 "UnrecognizedInterlaceType",argv[i]);
1078             break;
1079           }
1080         if (LocaleCompare("interpolate",option+1) == 0)
1081           {
1082             ssize_t
1083               interpolate;
1084
1085             if (*option == '+')
1086               break;
1087             i++;
1088             if (i == (ssize_t) argc)
1089               ThrowCompositeException(OptionError,"MissingArgument",option);
1090             interpolate=ParseCommandOption(MagickInterpolateOptions,MagickFalse,
1091               argv[i]);
1092             if (interpolate < 0)
1093               ThrowCompositeException(OptionError,
1094                 "UnrecognizedInterpolateMethod",argv[i]);
1095             break;
1096           }
1097         ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1098       }
1099       case 'l':
1100       {
1101         if (LocaleCompare("label",option+1) == 0)
1102           {
1103             if (*option == '+')
1104               break;
1105             i++;
1106             if (i == (ssize_t) argc)
1107               ThrowCompositeException(OptionError,"MissingArgument",option);
1108             break;
1109           }
1110         if (LocaleCompare("limit",option+1) == 0)
1111           {
1112             char
1113               *p;
1114
1115             double
1116               value;
1117
1118             ssize_t
1119               resource;
1120
1121             if (*option == '+')
1122               break;
1123             i++;
1124             if (i == (ssize_t) argc)
1125               ThrowCompositeException(OptionError,"MissingArgument",option);
1126             resource=ParseCommandOption(MagickResourceOptions,MagickFalse,
1127               argv[i]);
1128             if (resource < 0)
1129               ThrowCompositeException(OptionError,"UnrecognizedResourceType",
1130                 argv[i]);
1131             i++;
1132             if (i == (ssize_t) argc)
1133               ThrowCompositeException(OptionError,"MissingArgument",option);
1134             value=StringToDouble(argv[i],&p);
1135             (void) value;
1136             if ((p == argv[i]) && (LocaleCompare("unlimited",argv[i]) != 0))
1137               ThrowCompositeInvalidArgumentException(option,argv[i]);
1138             break;
1139           }
1140         if (LocaleCompare("list",option+1) == 0)
1141           {
1142             ssize_t
1143               list;
1144
1145             if (*option == '+')
1146               break;
1147             i++;
1148             if (i == (ssize_t) argc)
1149               ThrowCompositeException(OptionError,"MissingArgument",option);
1150             list=ParseCommandOption(MagickListOptions,MagickFalse,argv[i]);
1151             if (list < 0)
1152               ThrowCompositeException(OptionError,"UnrecognizedListType",
1153                 argv[i]);
1154             status=MogrifyImageInfo(image_info,(int) (i-j+1),(const char **)
1155               argv+j,exception);
1156             DestroyComposite();
1157             return(status == 0 ? MagickTrue : MagickFalse);
1158           }
1159         if (LocaleCompare("log",option+1) == 0)
1160           {
1161             if (*option == '+')
1162               break;
1163             i++;
1164             if ((i == (ssize_t) argc) || (strchr(argv[i],'%') == (char *) NULL))
1165               ThrowCompositeException(OptionError,"MissingArgument",option);
1166             break;
1167           }
1168         ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1169       }
1170       case 'm':
1171       {
1172         if (LocaleCompare("matte",option+1) == 0)
1173           break;
1174         if (LocaleCompare("monitor",option+1) == 0)
1175           break;
1176         if (LocaleCompare("monochrome",option+1) == 0)
1177           break;
1178         ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1179       }
1180       case 'n':
1181       {
1182         if (LocaleCompare("negate",option+1) == 0)
1183           break;
1184         if (LocaleCompare("noop",option+1) == 0)
1185           break;
1186         ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1187       }
1188       case 'p':
1189       {
1190         if (LocaleCompare("page",option+1) == 0)
1191           {
1192             if (*option == '+')
1193               break;
1194             i++;
1195             if (i == (ssize_t) argc)
1196               ThrowCompositeException(OptionError,"MissingArgument",option);
1197             break;
1198           }
1199         if (LocaleCompare("pointsize",option+1) == 0)
1200           {
1201             if (*option == '+')
1202               break;
1203             i++;
1204             if (i == (ssize_t) argc)
1205               ThrowCompositeException(OptionError,"MissingArgument",option);
1206             if (IsGeometry(argv[i]) == MagickFalse)
1207               ThrowCompositeInvalidArgumentException(option,argv[i]);
1208             break;
1209           }
1210         if (LocaleCompare("process",option+1) == 0)
1211           {
1212             if (*option == '+')
1213               break;
1214             i++;
1215             if (i == (ssize_t) argc)
1216               ThrowCompositeException(OptionError,"MissingArgument",option);
1217             break;
1218           }
1219         if (LocaleCompare("profile",option+1) == 0)
1220           {
1221             i++;
1222             if (i == (ssize_t) argc)
1223               ThrowCompositeException(OptionError,"MissingArgument",option);
1224             break;
1225           }
1226         ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1227       }
1228       case 'q':
1229       {
1230         if (LocaleCompare("quality",option+1) == 0)
1231           {
1232             if (*option == '+')
1233               break;
1234             i++;
1235             if (i == (ssize_t) argc)
1236               ThrowCompositeException(OptionError,"MissingArgument",option);
1237             if (IsGeometry(argv[i]) == MagickFalse)
1238               ThrowCompositeInvalidArgumentException(option,argv[i]);
1239             break;
1240           }
1241         if (LocaleCompare("quantize",option+1) == 0)
1242           {
1243             ssize_t
1244               colorspace;
1245
1246             if (*option == '+')
1247               break;
1248             i++;
1249             if (i == (ssize_t) argc)
1250               ThrowCompositeException(OptionError,"MissingArgument",option);
1251             colorspace=ParseCommandOption(MagickColorspaceOptions,
1252               MagickFalse,argv[i]);
1253             if (colorspace < 0)
1254               ThrowCompositeException(OptionError,"UnrecognizedColorspace",
1255                 argv[i]);
1256             break;
1257           }
1258         if (LocaleCompare("quiet",option+1) == 0)
1259           break;
1260         ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1261       }
1262       case 'r':
1263       {
1264         if (LocaleCompare("red-primary",option+1) == 0)
1265           {
1266             if (*option == '+')
1267               break;
1268             i++;
1269             if (i == (ssize_t) argc)
1270               ThrowCompositeException(OptionError,"MissingArgument",option);
1271             if (IsGeometry(argv[i]) == MagickFalse)
1272               ThrowCompositeInvalidArgumentException(option,argv[i]);
1273             break;
1274           }
1275         if (LocaleCompare("regard-warnings",option+1) == 0)
1276           break;
1277         if (LocaleCompare("render",option+1) == 0)
1278           break;
1279         if (LocaleCompare("repage",option+1) == 0)
1280           {
1281             if (*option == '+')
1282               break;
1283             i++;
1284             if (i == (ssize_t) argc)
1285               ThrowCompositeException(OptionError,"MissingArgument",option);
1286             if (IsGeometry(argv[i]) == MagickFalse)
1287               ThrowCompositeInvalidArgumentException(option,argv[i]);
1288             break;
1289           }
1290         if (LocaleNCompare("respect-parentheses",option+1,17) == 0)
1291           {
1292             respect_parenthesis=(*option == '-') ? MagickTrue : MagickFalse;
1293             break;
1294           }
1295         if (LocaleCompare("resize",option+1) == 0)
1296           {
1297             if (*option == '+')
1298               break;
1299             i++;
1300             if (i == (ssize_t) argc)
1301               ThrowCompositeException(OptionError,"MissingArgument",option);
1302             if (IsGeometry(argv[i]) == MagickFalse)
1303               ThrowCompositeInvalidArgumentException(option,argv[i]);
1304             break;
1305           }
1306         if (LocaleCompare("rotate",option+1) == 0)
1307           {
1308             i++;
1309             if (i == (ssize_t) argc)
1310               ThrowCompositeException(OptionError,"MissingArgument",option);
1311             if (IsGeometry(argv[i]) == MagickFalse)
1312               ThrowCompositeInvalidArgumentException(option,argv[i]);
1313             break;
1314           }
1315         ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1316       }
1317       case 's':
1318       {
1319         if (LocaleCompare("sampling-factor",option+1) == 0)
1320           {
1321             if (*option == '+')
1322               break;
1323             i++;
1324             if (i == (ssize_t) argc)
1325               ThrowCompositeException(OptionError,"MissingArgument",option);
1326             if (IsGeometry(argv[i]) == MagickFalse)
1327               ThrowCompositeInvalidArgumentException(option,argv[i]);
1328             break;
1329           }
1330         if (LocaleCompare("scene",option+1) == 0)
1331           {
1332             if (*option == '+')
1333               break;
1334             i++;
1335             if (i == (ssize_t) argc)
1336               ThrowCompositeException(OptionError,"MissingArgument",option);
1337             if (IsGeometry(argv[i]) == MagickFalse)
1338               ThrowCompositeInvalidArgumentException(option,argv[i]);
1339             break;
1340           }
1341         if (LocaleCompare("seed",option+1) == 0)
1342           {
1343             if (*option == '+')
1344               break;
1345             i++;
1346             if (i == (ssize_t) argc)
1347               ThrowCompositeException(OptionError,"MissingArgument",option);
1348             if (IsGeometry(argv[i]) == MagickFalse)
1349               ThrowCompositeInvalidArgumentException(option,argv[i]);
1350             break;
1351           }
1352         if (LocaleCompare("sharpen",option+1) == 0)
1353           {
1354             i++;
1355             if (i == (ssize_t) argc)
1356               ThrowCompositeException(OptionError,"MissingArgument",option);
1357             if (IsGeometry(argv[i]) == MagickFalse)
1358               ThrowCompositeInvalidArgumentException(option,argv[i]);
1359             break;
1360           }
1361         if (LocaleCompare("shave",option+1) == 0)
1362           {
1363             if (*option == '+')
1364               break;
1365             i++;
1366             if (i == (ssize_t) argc)
1367               ThrowCompositeException(OptionError,"MissingArgument",option);
1368             if (IsGeometry(argv[i]) == MagickFalse)
1369               ThrowCompositeInvalidArgumentException(option,argv[i]);
1370             break;
1371           }
1372         if (LocaleCompare("size",option+1) == 0)
1373           {
1374             if (*option == '+')
1375               break;
1376             i++;
1377             if (i == (ssize_t) argc)
1378               ThrowCompositeException(OptionError,"MissingArgument",option);
1379             if (IsGeometry(argv[i]) == MagickFalse)
1380               ThrowCompositeInvalidArgumentException(option,argv[i]);
1381             break;
1382           }
1383         if (LocaleCompare("stegano",option+1) == 0)
1384           {
1385             composite_options.stegano=0;
1386             if (*option == '+')
1387               break;
1388             i++;
1389             if (i == (ssize_t) argc)
1390               ThrowCompositeException(OptionError,"MissingArgument",option);
1391             if (IsGeometry(argv[i]) == MagickFalse)
1392               ThrowCompositeInvalidArgumentException(option,argv[i]);
1393             composite_options.stegano=(ssize_t) StringToLong(argv[i])+1;
1394             break;
1395           }
1396         if (LocaleCompare("stereo",option+1) == 0)
1397           {
1398             MagickStatusType
1399               flags;
1400
1401             composite_options.stereo=MagickFalse;
1402             if (*option == '+')
1403               break;
1404             i++;
1405             if (i == (ssize_t) argc)
1406               ThrowCompositeException(OptionError,"MissingArgument",option);
1407             if (IsGeometry(argv[i]) == MagickFalse)
1408               ThrowCompositeInvalidArgumentException(option,argv[i]);
1409             flags=ParseAbsoluteGeometry(argv[i],&composite_options.offset);
1410             if ((flags & YValue) == 0)
1411               composite_options.offset.y=composite_options.offset.x;
1412             composite_options.stereo=MagickTrue;
1413             break;
1414           }
1415         if (LocaleCompare("strip",option+1) == 0)
1416           break;
1417         if (LocaleCompare("support",option+1) == 0)
1418           {
1419             i++;  /* deprecated */
1420             break;
1421           }
1422         if (LocaleCompare("swap",option+1) == 0)
1423           {
1424             if (*option == '+')
1425               break;
1426             i++;
1427             if (i == (ssize_t) argc)
1428               ThrowCompositeException(OptionError,"MissingArgument",option);
1429             if (IsGeometry(argv[i]) == MagickFalse)
1430               ThrowCompositeInvalidArgumentException(option,argv[i]);
1431             break;
1432           }
1433         if (LocaleCompare("synchronize",option+1) == 0)
1434           break;
1435         ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1436       }
1437       case 't':
1438       {
1439         if (LocaleCompare("taint",option+1) == 0)
1440           break;
1441         if (LocaleCompare("thumbnail",option+1) == 0)
1442           {
1443             if (*option == '+')
1444               break;
1445             i++;
1446             if (i == (ssize_t) argc)
1447               ThrowCompositeException(OptionError,"MissingArgument",option);
1448             if (IsGeometry(argv[i]) == MagickFalse)
1449               ThrowCompositeInvalidArgumentException(option,argv[i]);
1450             break;
1451           }
1452         if (LocaleCompare("tile",option+1) == 0)
1453           {
1454             composite_options.tile=(*option == '-') ? MagickTrue : MagickFalse;
1455             (void) CopyMagickString(argv[i]+1,"sans",MagickPathExtent);
1456             break;
1457           }
1458         if (LocaleCompare("transform",option+1) == 0)
1459           break;
1460         if (LocaleCompare("transparent-color",option+1) == 0)
1461           {
1462             if (*option == '+')
1463               break;
1464             i++;
1465             if (i == (ssize_t) argc)
1466               ThrowCompositeException(OptionError,"MissingArgument",option);
1467             break;
1468           }
1469         if (LocaleCompare("treedepth",option+1) == 0)
1470           {
1471             if (*option == '+')
1472               break;
1473             i++;
1474             if (i == (ssize_t) argc)
1475               ThrowCompositeException(OptionError,"MissingArgument",option);
1476             if (IsGeometry(argv[i]) == MagickFalse)
1477               ThrowCompositeInvalidArgumentException(option,argv[i]);
1478             break;
1479           }
1480         if (LocaleCompare("type",option+1) == 0)
1481           {
1482             ssize_t
1483               type;
1484
1485             if (*option == '+')
1486               break;
1487             i++;
1488             if (i == (ssize_t) argc)
1489               ThrowCompositeException(OptionError,"MissingArgument",option);
1490             type=ParseCommandOption(MagickTypeOptions,MagickFalse,argv[i]);
1491             if (type < 0)
1492               ThrowCompositeException(OptionError,"UnrecognizedImageType",
1493                 argv[i]);
1494             break;
1495           }
1496         ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1497       }
1498       case 'u':
1499       {
1500         if (LocaleCompare("units",option+1) == 0)
1501           {
1502             ssize_t
1503               units;
1504
1505             if (*option == '+')
1506               break;
1507             i++;
1508             if (i == (ssize_t) argc)
1509               ThrowCompositeException(OptionError,"MissingArgument",option);
1510             units=ParseCommandOption(MagickResolutionOptions,MagickFalse,
1511               argv[i]);
1512             if (units < 0)
1513               ThrowCompositeException(OptionError,"UnrecognizedUnitsType",
1514                 argv[i]);
1515             break;
1516           }
1517         if (LocaleCompare("unsharp",option+1) == 0)
1518           {
1519             (void) CloneString(&composite_options.compose_args,(char *) NULL);
1520             if (*option == '+')
1521               break;
1522             i++;
1523             if (i == (ssize_t) argc)
1524               ThrowCompositeException(OptionError,"MissingArgument",option);
1525             if (IsGeometry(argv[i]) == MagickFalse)
1526               ThrowCompositeInvalidArgumentException(option,argv[i]);
1527             (void) CloneString(&composite_options.compose_args,argv[i]);
1528             composite_options.compose=ThresholdCompositeOp;
1529             break;
1530           }
1531         ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1532       }
1533       case 'v':
1534       {
1535         if (LocaleCompare("verbose",option+1) == 0)
1536           break;
1537         if ((LocaleCompare("version",option+1) == 0) ||
1538             (LocaleCompare("-version",option+1) == 0))
1539           {
1540             ListMagickVersion(stdout);
1541             break;
1542           }
1543         if (LocaleCompare("virtual-pixel",option+1) == 0)
1544           {
1545             ssize_t
1546               method;
1547
1548             if (*option == '+')
1549               break;
1550             i++;
1551             if (i == (ssize_t) argc)
1552               ThrowCompositeException(OptionError,"MissingArgument",option);
1553             method=ParseCommandOption(MagickVirtualPixelOptions,MagickFalse,
1554               argv[i]);
1555             if (method < 0)
1556               ThrowCompositeException(OptionError,
1557                 "UnrecognizedVirtualPixelMethod",argv[i]);
1558             break;
1559           }
1560         ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1561       }
1562       case 'w':
1563       {
1564         if (LocaleCompare("watermark",option+1) == 0)
1565           {
1566             (void) CloneString(&composite_options.compose_args,(char *) NULL);
1567             if (*option == '+')
1568               break;
1569             i++;
1570             if (i == (ssize_t) argc)
1571               ThrowCompositeException(OptionError,"MissingArgument",option);
1572             if (IsGeometry(argv[i]) == MagickFalse)
1573               ThrowCompositeInvalidArgumentException(option,argv[i]);
1574             (void) CloneString(&composite_options.compose_args,argv[i]);
1575             composite_options.compose=ModulateCompositeOp;
1576             break;
1577           }
1578         if (LocaleCompare("white-point",option+1) == 0)
1579           {
1580             if (*option == '+')
1581               break;
1582             i++;
1583             if (i == (ssize_t) argc)
1584               ThrowCompositeException(OptionError,"MissingArgument",option);
1585             if (IsGeometry(argv[i]) == MagickFalse)
1586               ThrowCompositeInvalidArgumentException(option,argv[i]);
1587             break;
1588           }
1589         if (LocaleCompare("write",option+1) == 0)
1590           {
1591             i++;
1592             if (i == (ssize_t) argc)
1593               ThrowCompositeException(OptionError,"MissingArgument",option);
1594             break;
1595           }
1596         ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1597       }
1598       case '?':
1599         break;
1600       default:
1601         ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1602     }
1603     fire=(GetCommandOptionFlags(MagickCommandOptions,MagickFalse,option) &
1604       FireOptionFlag) == 0 ?  MagickFalse : MagickTrue;
1605     if (fire != MagickFalse)
1606       FireImageStack(MagickFalse,MagickTrue,MagickTrue);
1607   }
1608   if (k != 0)
1609     ThrowCompositeException(OptionError,"UnbalancedParenthesis",argv[i]);
1610   if (i-- != (ssize_t) (argc-1))
1611     ThrowCompositeException(OptionError,"MissingAnImageFilename",argv[i]);
1612   if ((image == (Image *) NULL) || (GetImageListLength(image) < 2))
1613     ThrowCompositeException(OptionError,"MissingAnImageFilename",argv[argc-1]);
1614   FinalizeImageSettings(image_info,image,MagickTrue);
1615   if ((image == (Image *) NULL) || (GetImageListLength(image) < 2))
1616     ThrowCompositeException(OptionError,"MissingAnImageFilename",argv[argc-1]);
1617   /*
1618     Composite images.
1619   */
1620   RemoveImageStack(composite_image);
1621   RemoveImageStack(images);
1622   if (composite_image->geometry != (char *) NULL)
1623     {
1624       RectangleInfo
1625         resize_geometry;
1626
1627       (void) ParseRegionGeometry(composite_image,composite_image->geometry,
1628         &resize_geometry,exception);
1629       if ((composite_image->columns != resize_geometry.width) ||
1630           (composite_image->rows != resize_geometry.height))
1631         {
1632           Image
1633             *resize_image;
1634
1635           resize_image=ResizeImage(composite_image,resize_geometry.width,
1636             resize_geometry.height,composite_image->filter,exception);
1637           if (resize_image != (Image *) NULL)
1638             {
1639               composite_image=DestroyImage(composite_image);
1640               composite_image=resize_image;
1641             }
1642         }
1643     }
1644   RemoveImageStack(mask_image);
1645   if (mask_image != (Image *) NULL)
1646     {
1647       if ((composite_options.compose == DisplaceCompositeOp) ||
1648           (composite_options.compose == DistortCompositeOp))
1649         status&=CompositeImage(composite_image,mask_image,
1650           CopyGreenCompositeOp,MagickTrue,0,0,exception);
1651       else
1652         status&=CompositeImage(composite_image,mask_image,IntensityCompositeOp,
1653           MagickTrue,0,0,exception);
1654       mask_image=DestroyImage(mask_image);
1655     }
1656   status&=CompositeImageList(image_info,&images,composite_image,
1657     &composite_options,exception);
1658   composite_image=DestroyImage(composite_image);
1659   /*
1660     Write composite images.
1661   */
1662   status&=WriteImages(image_info,images,argv[argc-1],exception);
1663   if (metadata != (char **) NULL)
1664     {
1665       char
1666         *text;
1667
1668       text=InterpretImageProperties(image_info,images,format,exception);
1669       if (text == (char *) NULL)
1670         ThrowCompositeException(ResourceLimitError,"MemoryAllocationFailed",
1671           GetExceptionMessage(errno));
1672       (void) ConcatenateString(&(*metadata),text);
1673       text=DestroyString(text);
1674     }
1675   images=DestroyImage(images);
1676   RelinquishCompositeOptions(&composite_options);
1677   DestroyComposite();
1678   return(status != 0 ? MagickTrue : MagickFalse);
1679 }