]> granicus.if.org Git - imagemagick/blob - MagickWand/composite.c
Conditional compile with MAGICKCORE_WINDOWS_SUPPORT define
[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-2016 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(MagickFalse);
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         Image
514           *images;
515
516         /*
517           Read input image.
518         */
519         FireImageStack(MagickFalse,MagickFalse,pend);
520         filename=argv[i];
521         if ((LocaleCompare(filename,"--") == 0) && (i < (ssize_t) (argc-1)))
522           filename=argv[++i];
523         images=ReadImages(image_info,filename,exception);
524         status&=(images != (Image *) NULL) &&
525           (exception->severity < ErrorException);
526         if (images == (Image *) NULL)
527           continue;
528         AppendImageStack(images);
529         continue;
530       }
531     pend=image != (Image *) NULL ? MagickTrue : MagickFalse;
532     switch (*(option+1))
533     {
534       case 'a':
535       {
536         if (LocaleCompare("affine",option+1) == 0)
537           {
538             if (*option == '+')
539               break;
540             i++;
541             if (i == (ssize_t) argc)
542               ThrowCompositeException(OptionError,"MissingArgument",option);
543             if (IsGeometry(argv[i]) == MagickFalse)
544               ThrowCompositeInvalidArgumentException(option,argv[i]);
545             break;
546           }
547         if (LocaleCompare("alpha",option+1) == 0)
548           {
549             ssize_t
550               type;
551
552             if (*option == '+')
553               break;
554             i++;
555             if (i == (ssize_t) argc)
556               ThrowCompositeException(OptionError,"MissingArgument",option);
557             type=ParseCommandOption(MagickAlphaChannelOptions,MagickFalse,argv[i]);
558             if (type < 0)
559               ThrowCompositeException(OptionError,
560                 "UnrecognizedAlphaChannelOption",argv[i]);
561             break;
562           }
563         if (LocaleCompare("authenticate",option+1) == 0)
564           {
565             if (*option == '+')
566               break;
567             i++;
568             if (i == (ssize_t) argc)
569               ThrowCompositeException(OptionError,"MissingArgument",option);
570             break;
571           }
572         ThrowCompositeException(OptionError,"UnrecognizedOption",option)
573       }
574       case 'b':
575       {
576         if (LocaleCompare("background",option+1) == 0)
577           {
578             if (*option == '+')
579               break;
580             i++;
581             if (i == (ssize_t) argc)
582               ThrowCompositeException(OptionError,"MissingArgument",option);
583             break;
584           }
585         if (LocaleCompare("blend",option+1) == 0)
586           {
587             (void) CloneString(&composite_options.compose_args,(char *) NULL);
588             if (*option == '+')
589               break;
590             i++;
591             if (i == (ssize_t) argc)
592               ThrowCompositeException(OptionError,"MissingArgument",option);
593             if (IsGeometry(argv[i]) == MagickFalse)
594               ThrowCompositeInvalidArgumentException(option,argv[i]);
595             (void) CloneString(&composite_options.compose_args,argv[i]);
596             composite_options.compose=BlendCompositeOp;
597             break;
598           }
599         if (LocaleCompare("blur",option+1) == 0)
600           {
601             (void) CloneString(&composite_options.compose_args,(char *) NULL);
602             if (*option == '+')
603               break;
604             i++;
605             if (i == (ssize_t) argc)
606               ThrowCompositeException(OptionError,"MissingArgument",option);
607             if (IsGeometry(argv[i]) == MagickFalse)
608               ThrowCompositeInvalidArgumentException(option,argv[i]);
609             (void) CloneString(&composite_options.compose_args,argv[i]);
610             composite_options.compose=BlurCompositeOp;
611             break;
612           }
613         if (LocaleCompare("blue-primary",option+1) == 0)
614           {
615             if (*option == '+')
616               break;
617             i++;
618             if (i == (ssize_t) argc)
619               ThrowCompositeException(OptionError,"MissingArgument",option);
620             if (IsGeometry(argv[i]) == MagickFalse)
621               ThrowCompositeInvalidArgumentException(option,argv[i]);
622             break;
623           }
624         if (LocaleCompare("border",option+1) == 0)
625           {
626             if (*option == '+')
627               break;
628             i++;
629             if (i == (ssize_t) argc)
630               ThrowCompositeException(OptionError,"MissingArgument",option);
631             if (IsGeometry(argv[i]) == MagickFalse)
632               ThrowCompositeInvalidArgumentException(option,argv[i]);
633             break;
634           }
635         if (LocaleCompare("bordercolor",option+1) == 0)
636           {
637             if (*option == '+')
638               break;
639             i++;
640             if (i == (ssize_t) argc)
641               ThrowCompositeException(OptionError,"MissingArgument",option);
642             break;
643           }
644         ThrowCompositeException(OptionError,"UnrecognizedOption",option)
645       }
646       case 'c':
647       {
648         if (LocaleCompare("cache",option+1) == 0)
649           {
650             if (*option == '+')
651               break;
652             i++;
653             if (i == (ssize_t) argc)
654               ThrowCompositeException(OptionError,"MissingArgument",option);
655             if (IsGeometry(argv[i]) == MagickFalse)
656               ThrowCompositeInvalidArgumentException(option,argv[i]);
657             break;
658           }
659         if (LocaleCompare("channel",option+1) == 0)
660           {
661             ssize_t
662               channel;
663
664             if (*option == '+')
665               {
666                 composite_options.channel=DefaultChannels;
667                 break;
668               }
669             i++;
670             if (i == (ssize_t) argc)
671               ThrowCompositeException(OptionError,"MissingArgument",option);
672             channel=ParseChannelOption(argv[i]);
673             if (channel < 0)
674               ThrowCompositeException(OptionError,"UnrecognizedChannelType",
675                 argv[i]);
676             composite_options.channel=(ChannelType) channel;
677             break;
678           }
679         if (LocaleCompare("colors",option+1) == 0)
680           {
681             if (*option == '+')
682               break;
683             i++;
684             if (i == (ssize_t) argc)
685               ThrowCompositeException(OptionError,"MissingArgument",option);
686             if (IsGeometry(argv[i]) == MagickFalse)
687               ThrowCompositeInvalidArgumentException(option,argv[i]);
688             break;
689           }
690         if (LocaleCompare("colorspace",option+1) == 0)
691           {
692             ssize_t
693               colorspace;
694
695             if (*option == '+')
696               break;
697             i++;
698             if (i == (ssize_t) argc)
699               ThrowCompositeException(OptionError,"MissingArgument",option);
700             colorspace=ParseCommandOption(MagickColorspaceOptions,
701               MagickFalse,argv[i]);
702             if (colorspace < 0)
703               ThrowCompositeException(OptionError,"UnrecognizedColorspace",
704                 argv[i]);
705             break;
706           }
707         if (LocaleCompare("comment",option+1) == 0)
708           {
709             if (*option == '+')
710               break;
711             i++;
712             if (i == (ssize_t) argc)
713               ThrowCompositeException(OptionError,"MissingArgument",option);
714             break;
715           }
716         if (LocaleCompare("compose",option+1) == 0)
717           {
718             ssize_t
719               compose;
720
721             composite_options.compose=UndefinedCompositeOp;
722             if (*option == '+')
723               break;
724             i++;
725             if (i == (ssize_t) argc)
726               ThrowCompositeException(OptionError,"MissingArgument",option);
727             compose=ParseCommandOption(MagickComposeOptions,MagickFalse,
728               argv[i]);
729             if (compose < 0)
730               ThrowCompositeException(OptionError,"UnrecognizedComposeOperator",
731                 argv[i]);
732             composite_options.compose=(CompositeOperator) compose;
733             break;
734           }
735         if (LocaleCompare("compress",option+1) == 0)
736           {
737             ssize_t
738               compress;
739
740             if (*option == '+')
741               break;
742             i++;
743             if (i == (ssize_t) argc)
744               ThrowCompositeException(OptionError,"MissingArgument",option);
745             compress=ParseCommandOption(MagickCompressOptions,MagickFalse,
746               argv[i]);
747             if (compress < 0)
748               ThrowCompositeException(OptionError,
749                 "UnrecognizedImageCompression",argv[i]);
750             break;
751           }
752         if (LocaleCompare("concurrent",option+1) == 0)
753           break;
754         ThrowCompositeException(OptionError,"UnrecognizedOption",option)
755       }
756       case 'd':
757       {
758         if (LocaleCompare("debug",option+1) == 0)
759           {
760             ssize_t
761               event;
762
763             if (*option == '+')
764               break;
765             i++;
766             if (i == (ssize_t) argc)
767               ThrowCompositeException(OptionError,"MissingArgument",option);
768             event=ParseCommandOption(MagickLogEventOptions,MagickFalse,argv[i]);
769             if (event < 0)
770               ThrowCompositeException(OptionError,"UnrecognizedEventType",
771                 argv[i]);
772             (void) SetLogEventMask(argv[i]);
773             break;
774           }
775         if (LocaleCompare("decipher",option+1) == 0)
776           {
777             if (*option == '+')
778               break;
779             i++;
780             if (i == (ssize_t) argc)
781               ThrowCompositeException(OptionError,"MissingArgument",option);
782             break;
783           }
784         if (LocaleCompare("define",option+1) == 0)
785           {
786             i++;
787             if (i == (ssize_t) argc)
788               ThrowCompositeException(OptionError,"MissingArgument",option);
789             if (*option == '+')
790               {
791                 const char
792                   *define;
793
794                 define=GetImageOption(image_info,argv[i]);
795                 if (define == (const char *) NULL)
796                   ThrowCompositeException(OptionError,"NoSuchOption",argv[i]);
797                 break;
798               }
799             break;
800           }
801         if (LocaleCompare("density",option+1) == 0)
802           {
803             if (*option == '+')
804               break;
805             i++;
806             if (i == (ssize_t) argc)
807               ThrowCompositeException(OptionError,"MissingArgument",option);
808             if (IsGeometry(argv[i]) == MagickFalse)
809               ThrowCompositeInvalidArgumentException(option,argv[i]);
810             break;
811           }
812         if (LocaleCompare("depth",option+1) == 0)
813           {
814             if (*option == '+')
815               break;
816             i++;
817             if (i == (ssize_t) argc)
818               ThrowCompositeException(OptionError,"MissingArgument",option);
819             if (IsGeometry(argv[i]) == MagickFalse)
820               ThrowCompositeInvalidArgumentException(option,argv[i]);
821             break;
822           }
823         if (LocaleCompare("displace",option+1) == 0)
824           {
825             (void) CloneString(&composite_options.compose_args,(char *) NULL);
826             if (*option == '+')
827               break;
828             i++;
829             if (i == (ssize_t) argc)
830               ThrowCompositeException(OptionError,"MissingArgument",option);
831             if (IsGeometry(argv[i]) == MagickFalse)
832               ThrowCompositeInvalidArgumentException(option,argv[i]);
833             (void) CloneString(&composite_options.compose_args,argv[i]);
834             composite_options.compose=DisplaceCompositeOp;
835             break;
836           }
837         if (LocaleCompare("display",option+1) == 0)
838           {
839             if (*option == '+')
840               break;
841             i++;
842             if (i == (ssize_t) argc)
843               ThrowCompositeException(OptionError,"MissingArgument",option);
844             break;
845           }
846         if (LocaleCompare("dispose",option+1) == 0)
847           {
848             ssize_t
849               dispose;
850
851             if (*option == '+')
852               break;
853             i++;
854             if (i == (ssize_t) argc)
855               ThrowCompositeException(OptionError,"MissingArgument",option);
856             dispose=ParseCommandOption(MagickDisposeOptions,MagickFalse,argv[i]);
857             if (dispose < 0)
858               ThrowCompositeException(OptionError,"UnrecognizedDisposeMethod",
859                 argv[i]);
860             break;
861           }
862         if (LocaleCompare("dissolve",option+1) == 0)
863           {
864             (void) CloneString(&composite_options.compose_args,(char *) NULL);
865             if (*option == '+')
866               break;
867             i++;
868             if (i == (ssize_t) argc)
869               ThrowCompositeException(OptionError,"MissingArgument",option);
870             if (IsGeometry(argv[i]) == MagickFalse)
871               ThrowCompositeInvalidArgumentException(option,argv[i]);
872             (void) CloneString(&composite_options.compose_args,argv[i]);
873             composite_options.compose=DissolveCompositeOp;
874             break;
875           }
876         if (LocaleCompare("distort",option+1) == 0)
877           {
878             (void) CloneString(&composite_options.compose_args,(char *) NULL);
879             if (*option == '+')
880               break;
881             i++;
882             if (i == (ssize_t) argc)
883               ThrowCompositeException(OptionError,"MissingArgument",option);
884             if (IsGeometry(argv[i]) == MagickFalse)
885               ThrowCompositeInvalidArgumentException(option,argv[i]);
886             (void) CloneString(&composite_options.compose_args,argv[i]);
887             composite_options.compose=DistortCompositeOp;
888             break;
889           }
890         if (LocaleCompare("dither",option+1) == 0)
891           {
892             ssize_t
893               method;
894
895             if (*option == '+')
896               break;
897             i++;
898             if (i == (ssize_t) argc)
899               ThrowCompositeException(OptionError,"MissingArgument",option);
900             method=ParseCommandOption(MagickDitherOptions,MagickFalse,argv[i]);
901             if (method < 0)
902               ThrowCompositeException(OptionError,"UnrecognizedDitherMethod",
903                 argv[i]);
904             break;
905           }
906         if (LocaleCompare("duration",option+1) == 0)
907           {
908             if (*option == '+')
909               break;
910             i++;
911             if (i == (ssize_t) argc)
912               ThrowCompositeException(OptionError,"MissingArgument",option);
913             if (IsGeometry(argv[i]) == MagickFalse)
914               ThrowCompositeInvalidArgumentException(option,argv[i]);
915             break;
916           }
917         ThrowCompositeException(OptionError,"UnrecognizedOption",option)
918       }
919       case 'e':
920       {
921         if (LocaleCompare("encipher",option+1) == 0)
922           {
923             if (*option == '+')
924               break;
925             i++;
926             if (i == (ssize_t) argc)
927               ThrowCompositeException(OptionError,"MissingArgument",option);
928             break;
929           }
930         if (LocaleCompare("encoding",option+1) == 0)
931           {
932             if (*option == '+')
933               break;
934             i++;
935             if (i == (ssize_t) argc)
936               ThrowCompositeException(OptionError,"MissingArgument",option);
937             break;
938           }
939         if (LocaleCompare("endian",option+1) == 0)
940           {
941             ssize_t
942               endian;
943
944             if (*option == '+')
945               break;
946             i++;
947             if (i == (ssize_t) argc)
948               ThrowCompositeException(OptionError,"MissingArgument",option);
949             endian=ParseCommandOption(MagickEndianOptions,MagickFalse,
950               argv[i]);
951             if (endian < 0)
952               ThrowCompositeException(OptionError,"UnrecognizedEndianType",
953                 argv[i]);
954             break;
955           }
956         if (LocaleCompare("extract",option+1) == 0)
957           {
958             if (*option == '+')
959               break;
960             i++;
961             if (i == (ssize_t) argc)
962               ThrowCompositeException(OptionError,"MissingArgument",option);
963             if (IsGeometry(argv[i]) == MagickFalse)
964               ThrowCompositeInvalidArgumentException(option,argv[i]);
965             break;
966           }
967         ThrowCompositeException(OptionError,"UnrecognizedOption",option)
968       }
969       case 'f':
970       {
971         if (LocaleCompare("filter",option+1) == 0)
972           {
973             ssize_t
974               filter;
975
976             if (*option == '+')
977               break;
978             i++;
979             if (i == (ssize_t) argc)
980               ThrowCompositeException(OptionError,"MissingArgument",option);
981             filter=ParseCommandOption(MagickFilterOptions,MagickFalse,argv[i]);
982             if (filter < 0)
983               ThrowCompositeException(OptionError,"UnrecognizedImageFilter",
984                 argv[i]);
985             break;
986           }
987         if (LocaleCompare("font",option+1) == 0)
988           {
989             if (*option == '+')
990               break;
991             i++;
992             if (i == (ssize_t) argc)
993               ThrowCompositeException(OptionError,"MissingArgument",option);
994             break;
995           }
996         if (LocaleCompare("format",option+1) == 0)
997           {
998             if (*option == '+')
999               break;
1000             i++;
1001             if (i == (ssize_t) argc)
1002               ThrowCompositeException(OptionError,"MissingArgument",option);
1003             format=argv[i];
1004             break;
1005           }
1006         ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1007       }
1008       case 'g':
1009       {
1010         if (LocaleCompare("geometry",option+1) == 0)
1011           {
1012             (void) CloneString(&composite_options.geometry,(char *) NULL);
1013             if (*option == '+')
1014               break;
1015             i++;
1016             if (i == (ssize_t) argc)
1017               ThrowCompositeException(OptionError,"MissingArgument",option);
1018             if (IsGeometry(argv[i]) == MagickFalse)
1019               ThrowCompositeInvalidArgumentException(option,argv[i]);
1020             (void) CloneString(&composite_options.geometry,argv[i]);
1021             break;
1022           }
1023         if (LocaleCompare("gravity",option+1) == 0)
1024           {
1025             ssize_t
1026               gravity;
1027
1028             composite_options.gravity=UndefinedGravity;
1029             if (*option == '+')
1030               break;
1031             i++;
1032             if (i == (ssize_t) argc)
1033               ThrowCompositeException(OptionError,"MissingArgument",option);
1034             gravity=ParseCommandOption(MagickGravityOptions,MagickFalse,
1035               argv[i]);
1036             if (gravity < 0)
1037               ThrowCompositeException(OptionError,"UnrecognizedGravityType",
1038                 argv[i]);
1039             composite_options.gravity=(GravityType) gravity;
1040             break;
1041           }
1042         if (LocaleCompare("green-primary",option+1) == 0)
1043           {
1044             if (*option == '+')
1045               break;
1046             i++;
1047             if (i == (ssize_t) argc)
1048               ThrowCompositeException(OptionError,"MissingArgument",option);
1049             if (IsGeometry(argv[i]) == MagickFalse)
1050               ThrowCompositeInvalidArgumentException(option,argv[i]);
1051             break;
1052           }
1053         ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1054       }
1055       case 'h':
1056       {
1057         if ((LocaleCompare("help",option+1) == 0) ||
1058             (LocaleCompare("-help",option+1) == 0))
1059           return(CompositeUsage());
1060         ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1061       }
1062       case 'i':
1063       {
1064         if (LocaleCompare("identify",option+1) == 0)
1065           break;
1066         if (LocaleCompare("interlace",option+1) == 0)
1067           {
1068             ssize_t
1069               interlace;
1070
1071             if (*option == '+')
1072               break;
1073             i++;
1074             if (i == (ssize_t) argc)
1075               ThrowCompositeException(OptionError,"MissingArgument",option);
1076             interlace=ParseCommandOption(MagickInterlaceOptions,MagickFalse,
1077               argv[i]);
1078             if (interlace < 0)
1079               ThrowCompositeException(OptionError,
1080                 "UnrecognizedInterlaceType",argv[i]);
1081             break;
1082           }
1083         if (LocaleCompare("interpolate",option+1) == 0)
1084           {
1085             ssize_t
1086               interpolate;
1087
1088             if (*option == '+')
1089               break;
1090             i++;
1091             if (i == (ssize_t) argc)
1092               ThrowCompositeException(OptionError,"MissingArgument",option);
1093             interpolate=ParseCommandOption(MagickInterpolateOptions,MagickFalse,
1094               argv[i]);
1095             if (interpolate < 0)
1096               ThrowCompositeException(OptionError,
1097                 "UnrecognizedInterpolateMethod",argv[i]);
1098             break;
1099           }
1100         ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1101       }
1102       case 'l':
1103       {
1104         if (LocaleCompare("label",option+1) == 0)
1105           {
1106             if (*option == '+')
1107               break;
1108             i++;
1109             if (i == (ssize_t) argc)
1110               ThrowCompositeException(OptionError,"MissingArgument",option);
1111             break;
1112           }
1113         if (LocaleCompare("limit",option+1) == 0)
1114           {
1115             char
1116               *p;
1117
1118             double
1119               value;
1120
1121             ssize_t
1122               resource;
1123
1124             if (*option == '+')
1125               break;
1126             i++;
1127             if (i == (ssize_t) argc)
1128               ThrowCompositeException(OptionError,"MissingArgument",option);
1129             resource=ParseCommandOption(MagickResourceOptions,MagickFalse,
1130               argv[i]);
1131             if (resource < 0)
1132               ThrowCompositeException(OptionError,"UnrecognizedResourceType",
1133                 argv[i]);
1134             i++;
1135             if (i == (ssize_t) argc)
1136               ThrowCompositeException(OptionError,"MissingArgument",option);
1137             value=StringToDouble(argv[i],&p);
1138             (void) value;
1139             if ((p == argv[i]) && (LocaleCompare("unlimited",argv[i]) != 0))
1140               ThrowCompositeInvalidArgumentException(option,argv[i]);
1141             break;
1142           }
1143         if (LocaleCompare("list",option+1) == 0)
1144           {
1145             ssize_t
1146               list;
1147
1148             if (*option == '+')
1149               break;
1150             i++;
1151             if (i == (ssize_t) argc)
1152               ThrowCompositeException(OptionError,"MissingArgument",option);
1153             list=ParseCommandOption(MagickListOptions,MagickFalse,argv[i]);
1154             if (list < 0)
1155               ThrowCompositeException(OptionError,"UnrecognizedListType",
1156                 argv[i]);
1157             status=MogrifyImageInfo(image_info,(int) (i-j+1),(const char **)
1158               argv+j,exception);
1159             DestroyComposite();
1160             return(status == 0 ? MagickTrue : MagickFalse);
1161           }
1162         if (LocaleCompare("log",option+1) == 0)
1163           {
1164             if (*option == '+')
1165               break;
1166             i++;
1167             if ((i == (ssize_t) argc) || (strchr(argv[i],'%') == (char *) NULL))
1168               ThrowCompositeException(OptionError,"MissingArgument",option);
1169             break;
1170           }
1171         ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1172       }
1173       case 'm':
1174       {
1175         if (LocaleCompare("matte",option+1) == 0)
1176           break;
1177         if (LocaleCompare("monitor",option+1) == 0)
1178           break;
1179         if (LocaleCompare("monochrome",option+1) == 0)
1180           break;
1181         ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1182       }
1183       case 'n':
1184       {
1185         if (LocaleCompare("negate",option+1) == 0)
1186           break;
1187         if (LocaleCompare("noop",option+1) == 0)
1188           break;
1189         ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1190       }
1191       case 'p':
1192       {
1193         if (LocaleCompare("page",option+1) == 0)
1194           {
1195             if (*option == '+')
1196               break;
1197             i++;
1198             if (i == (ssize_t) argc)
1199               ThrowCompositeException(OptionError,"MissingArgument",option);
1200             break;
1201           }
1202         if (LocaleCompare("pointsize",option+1) == 0)
1203           {
1204             if (*option == '+')
1205               break;
1206             i++;
1207             if (i == (ssize_t) argc)
1208               ThrowCompositeException(OptionError,"MissingArgument",option);
1209             if (IsGeometry(argv[i]) == MagickFalse)
1210               ThrowCompositeInvalidArgumentException(option,argv[i]);
1211             break;
1212           }
1213         if (LocaleCompare("process",option+1) == 0)
1214           {
1215             if (*option == '+')
1216               break;
1217             i++;
1218             if (i == (ssize_t) argc)
1219               ThrowCompositeException(OptionError,"MissingArgument",option);
1220             break;
1221           }
1222         if (LocaleCompare("profile",option+1) == 0)
1223           {
1224             i++;
1225             if (i == (ssize_t) argc)
1226               ThrowCompositeException(OptionError,"MissingArgument",option);
1227             break;
1228           }
1229         ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1230       }
1231       case 'q':
1232       {
1233         if (LocaleCompare("quality",option+1) == 0)
1234           {
1235             if (*option == '+')
1236               break;
1237             i++;
1238             if (i == (ssize_t) argc)
1239               ThrowCompositeException(OptionError,"MissingArgument",option);
1240             if (IsGeometry(argv[i]) == MagickFalse)
1241               ThrowCompositeInvalidArgumentException(option,argv[i]);
1242             break;
1243           }
1244         if (LocaleCompare("quantize",option+1) == 0)
1245           {
1246             ssize_t
1247               colorspace;
1248
1249             if (*option == '+')
1250               break;
1251             i++;
1252             if (i == (ssize_t) argc)
1253               ThrowCompositeException(OptionError,"MissingArgument",option);
1254             colorspace=ParseCommandOption(MagickColorspaceOptions,
1255               MagickFalse,argv[i]);
1256             if (colorspace < 0)
1257               ThrowCompositeException(OptionError,"UnrecognizedColorspace",
1258                 argv[i]);
1259             break;
1260           }
1261         if (LocaleCompare("quiet",option+1) == 0)
1262           break;
1263         ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1264       }
1265       case 'r':
1266       {
1267         if (LocaleCompare("red-primary",option+1) == 0)
1268           {
1269             if (*option == '+')
1270               break;
1271             i++;
1272             if (i == (ssize_t) argc)
1273               ThrowCompositeException(OptionError,"MissingArgument",option);
1274             if (IsGeometry(argv[i]) == MagickFalse)
1275               ThrowCompositeInvalidArgumentException(option,argv[i]);
1276             break;
1277           }
1278         if (LocaleCompare("regard-warnings",option+1) == 0)
1279           break;
1280         if (LocaleCompare("render",option+1) == 0)
1281           break;
1282         if (LocaleCompare("repage",option+1) == 0)
1283           {
1284             if (*option == '+')
1285               break;
1286             i++;
1287             if (i == (ssize_t) argc)
1288               ThrowCompositeException(OptionError,"MissingArgument",option);
1289             if (IsGeometry(argv[i]) == MagickFalse)
1290               ThrowCompositeInvalidArgumentException(option,argv[i]);
1291             break;
1292           }
1293         if (LocaleNCompare("respect-parentheses",option+1,17) == 0)
1294           {
1295             respect_parenthesis=(*option == '-') ? MagickTrue : MagickFalse;
1296             break;
1297           }
1298         if (LocaleCompare("resize",option+1) == 0)
1299           {
1300             if (*option == '+')
1301               break;
1302             i++;
1303             if (i == (ssize_t) argc)
1304               ThrowCompositeException(OptionError,"MissingArgument",option);
1305             if (IsGeometry(argv[i]) == MagickFalse)
1306               ThrowCompositeInvalidArgumentException(option,argv[i]);
1307             break;
1308           }
1309         if (LocaleCompare("rotate",option+1) == 0)
1310           {
1311             i++;
1312             if (i == (ssize_t) argc)
1313               ThrowCompositeException(OptionError,"MissingArgument",option);
1314             if (IsGeometry(argv[i]) == MagickFalse)
1315               ThrowCompositeInvalidArgumentException(option,argv[i]);
1316             break;
1317           }
1318         ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1319       }
1320       case 's':
1321       {
1322         if (LocaleCompare("sampling-factor",option+1) == 0)
1323           {
1324             if (*option == '+')
1325               break;
1326             i++;
1327             if (i == (ssize_t) argc)
1328               ThrowCompositeException(OptionError,"MissingArgument",option);
1329             if (IsGeometry(argv[i]) == MagickFalse)
1330               ThrowCompositeInvalidArgumentException(option,argv[i]);
1331             break;
1332           }
1333         if (LocaleCompare("scene",option+1) == 0)
1334           {
1335             if (*option == '+')
1336               break;
1337             i++;
1338             if (i == (ssize_t) argc)
1339               ThrowCompositeException(OptionError,"MissingArgument",option);
1340             if (IsGeometry(argv[i]) == MagickFalse)
1341               ThrowCompositeInvalidArgumentException(option,argv[i]);
1342             break;
1343           }
1344         if (LocaleCompare("seed",option+1) == 0)
1345           {
1346             if (*option == '+')
1347               break;
1348             i++;
1349             if (i == (ssize_t) argc)
1350               ThrowCompositeException(OptionError,"MissingArgument",option);
1351             if (IsGeometry(argv[i]) == MagickFalse)
1352               ThrowCompositeInvalidArgumentException(option,argv[i]);
1353             break;
1354           }
1355         if (LocaleCompare("sharpen",option+1) == 0)
1356           {
1357             i++;
1358             if (i == (ssize_t) argc)
1359               ThrowCompositeException(OptionError,"MissingArgument",option);
1360             if (IsGeometry(argv[i]) == MagickFalse)
1361               ThrowCompositeInvalidArgumentException(option,argv[i]);
1362             break;
1363           }
1364         if (LocaleCompare("shave",option+1) == 0)
1365           {
1366             if (*option == '+')
1367               break;
1368             i++;
1369             if (i == (ssize_t) argc)
1370               ThrowCompositeException(OptionError,"MissingArgument",option);
1371             if (IsGeometry(argv[i]) == MagickFalse)
1372               ThrowCompositeInvalidArgumentException(option,argv[i]);
1373             break;
1374           }
1375         if (LocaleCompare("size",option+1) == 0)
1376           {
1377             if (*option == '+')
1378               break;
1379             i++;
1380             if (i == (ssize_t) argc)
1381               ThrowCompositeException(OptionError,"MissingArgument",option);
1382             if (IsGeometry(argv[i]) == MagickFalse)
1383               ThrowCompositeInvalidArgumentException(option,argv[i]);
1384             break;
1385           }
1386         if (LocaleCompare("stegano",option+1) == 0)
1387           {
1388             composite_options.stegano=0;
1389             if (*option == '+')
1390               break;
1391             i++;
1392             if (i == (ssize_t) argc)
1393               ThrowCompositeException(OptionError,"MissingArgument",option);
1394             if (IsGeometry(argv[i]) == MagickFalse)
1395               ThrowCompositeInvalidArgumentException(option,argv[i]);
1396             composite_options.stegano=(ssize_t) StringToLong(argv[i])+1;
1397             break;
1398           }
1399         if (LocaleCompare("stereo",option+1) == 0)
1400           {
1401             MagickStatusType
1402               flags;
1403
1404             composite_options.stereo=MagickFalse;
1405             if (*option == '+')
1406               break;
1407             i++;
1408             if (i == (ssize_t) argc)
1409               ThrowCompositeException(OptionError,"MissingArgument",option);
1410             if (IsGeometry(argv[i]) == MagickFalse)
1411               ThrowCompositeInvalidArgumentException(option,argv[i]);
1412             flags=ParseAbsoluteGeometry(argv[i],&composite_options.offset);
1413             if ((flags & YValue) == 0)
1414               composite_options.offset.y=composite_options.offset.x;
1415             composite_options.stereo=MagickTrue;
1416             break;
1417           }
1418         if (LocaleCompare("strip",option+1) == 0)
1419           break;
1420         if (LocaleCompare("support",option+1) == 0)
1421           {
1422             i++;  /* deprecated */
1423             break;
1424           }
1425         if (LocaleCompare("swap",option+1) == 0)
1426           {
1427             if (*option == '+')
1428               break;
1429             i++;
1430             if (i == (ssize_t) argc)
1431               ThrowCompositeException(OptionError,"MissingArgument",option);
1432             if (IsGeometry(argv[i]) == MagickFalse)
1433               ThrowCompositeInvalidArgumentException(option,argv[i]);
1434             break;
1435           }
1436         if (LocaleCompare("synchronize",option+1) == 0)
1437           break;
1438         ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1439       }
1440       case 't':
1441       {
1442         if (LocaleCompare("taint",option+1) == 0)
1443           break;
1444         if (LocaleCompare("thumbnail",option+1) == 0)
1445           {
1446             if (*option == '+')
1447               break;
1448             i++;
1449             if (i == (ssize_t) argc)
1450               ThrowCompositeException(OptionError,"MissingArgument",option);
1451             if (IsGeometry(argv[i]) == MagickFalse)
1452               ThrowCompositeInvalidArgumentException(option,argv[i]);
1453             break;
1454           }
1455         if (LocaleCompare("tile",option+1) == 0)
1456           {
1457             composite_options.tile=(*option == '-') ? MagickTrue : MagickFalse;
1458             (void) CopyMagickString(argv[i]+1,"sans",MagickPathExtent);
1459             break;
1460           }
1461         if (LocaleCompare("transform",option+1) == 0)
1462           break;
1463         if (LocaleCompare("transparent-color",option+1) == 0)
1464           {
1465             if (*option == '+')
1466               break;
1467             i++;
1468             if (i == (ssize_t) argc)
1469               ThrowCompositeException(OptionError,"MissingArgument",option);
1470             break;
1471           }
1472         if (LocaleCompare("treedepth",option+1) == 0)
1473           {
1474             if (*option == '+')
1475               break;
1476             i++;
1477             if (i == (ssize_t) argc)
1478               ThrowCompositeException(OptionError,"MissingArgument",option);
1479             if (IsGeometry(argv[i]) == MagickFalse)
1480               ThrowCompositeInvalidArgumentException(option,argv[i]);
1481             break;
1482           }
1483         if (LocaleCompare("type",option+1) == 0)
1484           {
1485             ssize_t
1486               type;
1487
1488             if (*option == '+')
1489               break;
1490             i++;
1491             if (i == (ssize_t) argc)
1492               ThrowCompositeException(OptionError,"MissingArgument",option);
1493             type=ParseCommandOption(MagickTypeOptions,MagickFalse,argv[i]);
1494             if (type < 0)
1495               ThrowCompositeException(OptionError,"UnrecognizedImageType",
1496                 argv[i]);
1497             break;
1498           }
1499         ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1500       }
1501       case 'u':
1502       {
1503         if (LocaleCompare("units",option+1) == 0)
1504           {
1505             ssize_t
1506               units;
1507
1508             if (*option == '+')
1509               break;
1510             i++;
1511             if (i == (ssize_t) argc)
1512               ThrowCompositeException(OptionError,"MissingArgument",option);
1513             units=ParseCommandOption(MagickResolutionOptions,MagickFalse,
1514               argv[i]);
1515             if (units < 0)
1516               ThrowCompositeException(OptionError,"UnrecognizedUnitsType",
1517                 argv[i]);
1518             break;
1519           }
1520         if (LocaleCompare("unsharp",option+1) == 0)
1521           {
1522             (void) CloneString(&composite_options.compose_args,(char *) NULL);
1523             if (*option == '+')
1524               break;
1525             i++;
1526             if (i == (ssize_t) argc)
1527               ThrowCompositeException(OptionError,"MissingArgument",option);
1528             if (IsGeometry(argv[i]) == MagickFalse)
1529               ThrowCompositeInvalidArgumentException(option,argv[i]);
1530             (void) CloneString(&composite_options.compose_args,argv[i]);
1531             composite_options.compose=ThresholdCompositeOp;
1532             break;
1533           }
1534         ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1535       }
1536       case 'v':
1537       {
1538         if (LocaleCompare("verbose",option+1) == 0)
1539           break;
1540         if ((LocaleCompare("version",option+1) == 0) ||
1541             (LocaleCompare("-version",option+1) == 0))
1542           {
1543             ListMagickVersion(stdout);
1544             break;
1545           }
1546         if (LocaleCompare("virtual-pixel",option+1) == 0)
1547           {
1548             ssize_t
1549               method;
1550
1551             if (*option == '+')
1552               break;
1553             i++;
1554             if (i == (ssize_t) argc)
1555               ThrowCompositeException(OptionError,"MissingArgument",option);
1556             method=ParseCommandOption(MagickVirtualPixelOptions,MagickFalse,
1557               argv[i]);
1558             if (method < 0)
1559               ThrowCompositeException(OptionError,
1560                 "UnrecognizedVirtualPixelMethod",argv[i]);
1561             break;
1562           }
1563         ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1564       }
1565       case 'w':
1566       {
1567         if (LocaleCompare("watermark",option+1) == 0)
1568           {
1569             (void) CloneString(&composite_options.compose_args,(char *) NULL);
1570             if (*option == '+')
1571               break;
1572             i++;
1573             if (i == (ssize_t) argc)
1574               ThrowCompositeException(OptionError,"MissingArgument",option);
1575             if (IsGeometry(argv[i]) == MagickFalse)
1576               ThrowCompositeInvalidArgumentException(option,argv[i]);
1577             (void) CloneString(&composite_options.compose_args,argv[i]);
1578             composite_options.compose=ModulateCompositeOp;
1579             break;
1580           }
1581         if (LocaleCompare("white-point",option+1) == 0)
1582           {
1583             if (*option == '+')
1584               break;
1585             i++;
1586             if (i == (ssize_t) argc)
1587               ThrowCompositeException(OptionError,"MissingArgument",option);
1588             if (IsGeometry(argv[i]) == MagickFalse)
1589               ThrowCompositeInvalidArgumentException(option,argv[i]);
1590             break;
1591           }
1592         if (LocaleCompare("write",option+1) == 0)
1593           {
1594             i++;
1595             if (i == (ssize_t) argc)
1596               ThrowCompositeException(OptionError,"MissingArgument",option);
1597             break;
1598           }
1599         ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1600       }
1601       case '?':
1602         break;
1603       default:
1604         ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1605     }
1606     fire=(GetCommandOptionFlags(MagickCommandOptions,MagickFalse,option) &
1607       FireOptionFlag) == 0 ?  MagickFalse : MagickTrue;
1608     if (fire != MagickFalse)
1609       FireImageStack(MagickFalse,MagickTrue,MagickTrue);
1610   }
1611   if (k != 0)
1612     ThrowCompositeException(OptionError,"UnbalancedParenthesis",argv[i]);
1613   if (i-- != (ssize_t) (argc-1))
1614     ThrowCompositeException(OptionError,"MissingAnImageFilename",argv[i]);
1615   if ((image == (Image *) NULL) || (GetImageListLength(image) < 2))
1616     ThrowCompositeException(OptionError,"MissingAnImageFilename",argv[argc-1]);
1617   FinalizeImageSettings(image_info,image,MagickTrue);
1618   if ((image == (Image *) NULL) || (GetImageListLength(image) < 2))
1619     ThrowCompositeException(OptionError,"MissingAnImageFilename",argv[argc-1]);
1620   /*
1621     Composite images.
1622   */
1623   RemoveImageStack(composite_image);
1624   RemoveImageStack(images);
1625   (void) TransformImage(&composite_image,(char *) NULL,
1626     composite_image->geometry,exception);
1627   RemoveImageStack(mask_image);
1628   if (mask_image != (Image *) NULL)
1629     {
1630       if ((composite_options.compose == DisplaceCompositeOp) ||
1631           (composite_options.compose == DistortCompositeOp))
1632         status&=CompositeImage(composite_image,mask_image,
1633           CopyGreenCompositeOp,MagickTrue,0,0,exception);
1634       else
1635         status&=CompositeImage(composite_image,mask_image,IntensityCompositeOp,
1636           MagickTrue,0,0,exception);
1637       mask_image=DestroyImage(mask_image);
1638     }
1639   status&=CompositeImageList(image_info,&images,composite_image,
1640     &composite_options,exception);
1641   composite_image=DestroyImage(composite_image);
1642   /*
1643     Write composite images.
1644   */
1645   status&=WriteImages(image_info,images,argv[argc-1],exception);
1646   if (metadata != (char **) NULL)
1647     {
1648       char
1649         *text;
1650
1651       text=InterpretImageProperties(image_info,images,format,exception);
1652       if (text == (char *) NULL)
1653         ThrowCompositeException(ResourceLimitError,"MemoryAllocationFailed",
1654           GetExceptionMessage(errno));
1655       (void) ConcatenateString(&(*metadata),text);
1656       text=DestroyString(text);
1657     }
1658   images=DestroyImage(images);
1659   RelinquishCompositeOptions(&composite_options);
1660   DestroyComposite();
1661   return(status != 0 ? MagickTrue : MagickFalse);
1662 }