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