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