]> granicus.if.org Git - imagemagick/blob - wand/composite.c
(no commit message)
[imagemagick] / wand / 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-2010 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 "wand/studio.h"
44 #include "wand/MagickWand.h"
45 #include "wand/mogrify-private.h"
46 #include "magick/string-private.h"
47 \f
48 /*
49   Typedef declarations.
50 */
51 typedef struct _CompositeOptions
52 {
53   ChannelType
54     channel;
55
56   char
57     *compose_args,
58     *geometry;
59
60   CompositeOperator
61     compose;
62
63   GravityType
64     gravity;
65
66   ssize_t
67     stegano;
68
69   RectangleInfo
70     offset;
71
72   MagickBooleanType
73     stereo,
74     tile;
75 } CompositeOptions;
76 \f
77 /*
78 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
79 %                                                                             %
80 %                                                                             %
81 %                                                                             %
82 %  C o m p o s i t e I m a g e C o m m a n d                                  %
83 %                                                                             %
84 %                                                                             %
85 %                                                                             %
86 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
87 %
88 %  CompositeImageCommand() reads one or more images and an optional mask and
89 %  composites them into a new image.
90 %
91 %  The format of the CompositeImageCommand method is:
92 %
93 %      MagickBooleanType CompositeImageCommand(ImageInfo *image_info,int argc,
94 %        char **argv,char **metadata,ExceptionInfo *exception)
95 %
96 %  A description of each parameter follows:
97 %
98 %    o image_info: the image info.
99 %
100 %    o argc: the number of elements in the argument vector.
101 %
102 %    o argv: A text array containing the command line arguments.
103 %
104 %    o metadata: any metadata is returned here.
105 %
106 %    o exception: return any errors or warnings in this structure.
107 %
108 */
109
110 static MagickBooleanType CompositeImageList(ImageInfo *image_info,Image **image,
111   Image *composite_image,CompositeOptions *composite_options,
112   ExceptionInfo *exception)
113 {
114   MagickStatusType
115     status;
116
117   assert(image_info != (ImageInfo *) NULL);
118   assert(image_info->signature == MagickSignature);
119   assert(image != (Image **) NULL);
120   assert((*image)->signature == MagickSignature);
121   if ((*image)->debug != MagickFalse)
122     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",(*image)->filename);
123   assert(exception != (ExceptionInfo *) NULL);
124   status=MagickTrue;
125   if (composite_image != (Image *) NULL)
126     {
127       assert(composite_image->signature == MagickSignature);
128       switch( composite_options->compose )
129         {
130           case BlendCompositeOp:
131           case BlurCompositeOp:
132           case DisplaceCompositeOp:
133           case DistortCompositeOp:
134           case DissolveCompositeOp:
135           case ModulateCompositeOp:
136           case ThresholdCompositeOp:
137             (void) SetImageArtifact(composite_image,"compose:args",
138               composite_options->compose_args);
139             break;
140           default:
141             break;
142         }
143       /*
144         Composite image.
145       */
146       if (composite_options->stegano != 0)
147         {
148           Image
149             *stegano_image;
150
151           (*image)->offset=composite_options->stegano-1;
152           stegano_image=SteganoImage(*image,composite_image,exception);
153           if (stegano_image != (Image *) NULL)
154             {
155               *image=DestroyImageList(*image);
156               *image=stegano_image;
157             }
158         }
159       else
160         if (composite_options->stereo != MagickFalse)
161           {
162             Image
163               *stereo_image;
164
165             stereo_image=StereoAnaglyphImage(*image,composite_image,
166               composite_options->offset.x,composite_options->offset.y,
167               exception);
168             if (stereo_image != (Image *) NULL)
169               {
170                 *image=DestroyImageList(*image);
171                 *image=stereo_image;
172               }
173           }
174         else
175           if (composite_options->tile != MagickFalse)
176             {
177               ssize_t
178                 x,
179                 y;
180
181               size_t
182                 columns;
183
184               /*
185                 Tile the composite image.
186               */
187               (void) SetImageArtifact(composite_image,"compose:outside-overlay",
188                 "false");
189               columns=composite_image->columns;
190               for (y=0; y < (ssize_t) (*image)->rows; y+=(ssize_t) composite_image->rows)
191                 for (x=0; x < (ssize_t) (*image)->columns; x+=(ssize_t) columns)
192                   status&=CompositeImageChannel(*image,
193                     composite_options->channel,composite_options->compose,
194                     composite_image,x,y);
195               GetImageException(*image,exception);
196             }
197           else
198             {
199               RectangleInfo
200                 geometry;
201
202               /*
203                 Work out gravity Adjustment of Offset
204               */
205               SetGeometry(*image,&geometry);
206               (void) ParseAbsoluteGeometry(composite_options->geometry,
207                 &geometry);
208               geometry.width=composite_image->columns;
209               geometry.height=composite_image->rows;
210               GravityAdjustGeometry((*image)->columns,(*image)->rows,
211                 composite_options->gravity, &geometry);
212               (*image)->gravity=(GravityType) composite_options->gravity;
213               /*
214                 Digitally composite image.
215               */
216               status&=CompositeImageChannel(*image,composite_options->channel,
217                 composite_options->compose,composite_image,geometry.x,
218                 geometry.y);
219               GetImageException(*image,exception);
220             }
221     }
222   return(status != 0 ? MagickTrue : MagickFalse);
223 }
224
225 static MagickBooleanType CompositeUsage(void)
226 {
227   const char
228     **p;
229
230   static const char
231     *miscellaneous[]=
232     {
233       "-debug events        display copious debugging information",
234       "-help                print program options",
235       "-list type           print a list of supported option arguments",
236       "-log format          format of debugging information",
237       "-version             print version information",
238       (char *) NULL
239     },
240     *operators[]=
241     {
242       "-blend geometry      blend images",
243       "-border geometry     surround image with a border of color",
244       "-bordercolor color   border color",
245       "-colors value        preferred number of colors in the image",
246       "-decipher filename    convert cipher pixels to plain pixels",
247       "-displace geometry   shift lookup according to a relative displacement map",
248       "-dissolve value      dissolve the two images a given percent",
249       "-distort geometry    shift lookup according to a absolute distortion map",
250       "-encipher filename   convert plain pixels to cipher pixels",
251       "-extract geometry    extract area from image",
252       "-geometry geometry   location of the composite image",
253       "-identify            identify the format and characteristics of the image",
254       "-monochrome          transform image to black and white",
255       "-negate              replace every pixel with its complementary color ",
256       "-profile filename    add ICM or IPTC information profile to image",
257       "-quantize colorspace reduce colors in this colorspace",
258       "-repage geometry     size and location of an image canvas (operator)",
259       "-rotate degrees      apply Paeth rotation to the image",
260       "-resize geometry     resize the image",
261       "-sharpen geometry    sharpen the image",
262       "-shave geometry      shave pixels from the image edges",
263       "-stegano offset      hide watermark within an image",
264       "-stereo geometry     combine two image to create a stereo anaglyph",
265       "-strip               strip image of all profiles and comments",
266       "-thumbnail geometry  create a thumbnail of the image",
267       "-transform           affine transform image",
268       "-type type           image type",
269       "-unsharp geometry    sharpen the image",
270       "-watermark geometry  percent brightness and saturation of a watermark",
271       "-write filename      write images to this file",
272       (char *) NULL
273     },
274     *settings[]=
275     {
276       "-affine matrix       affine transform matrix",
277       "-alpha option        on, activate, off, deactivate, set, opaque, copy",
278       "                     transparent, extract, background, or shape",
279       "-authenticate password",
280       "                     decipher image with this password",
281       "-blue-primary point  chromaticity blue primary point",
282       "-channel type        apply option to select image channels",
283       "-colorspace type     alternate image colorspace",
284       "-comment string      annotate image with comment",
285       "-compose operator    composite operator",
286       "-compress type       type of pixel compression when writing the image",
287       "-define format:option",
288       "                     define one or more image format options",
289       "-depth value         image depth",
290       "-density geometry    horizontal and vertical density of the image",
291       "-display server      get image or font from this X server",
292       "-dispose method      layer disposal method",
293       "-dither method       apply error diffusion to image",
294       "-encoding type       text encoding type",
295       "-endian type         endianness (MSB or LSB) of the image",
296       "-filter type         use this filter when resizing an image",
297       "-font name           render text with this font",
298       "-format \"string\"     output formatted image characteristics",
299       "-gravity type        which direction to gravitate towards",
300       "-green-primary point chromaticity green primary point",
301       "-interlace type      type of image interlacing scheme",
302       "-interpolate method  pixel color interpolation method",
303       "-label string        assign a label to an image",
304       "-limit type value    pixel cache resource limit",
305       "-monitor             monitor progress",
306       "-page geometry       size and location of an image canvas (setting)",
307       "-pointsize value     font point size",
308       "-quality value       JPEG/MIFF/PNG compression level",
309       "-quiet               suppress all warning messages",
310       "-red-primary point   chromaticity red primary point",
311       "-regard-warnings     pay attention to warning messages",
312       "-respect-parentheses settings remain in effect until parenthesis boundary",
313       "-sampling-factor geometry",
314       "                     horizontal and vertical sampling factor",
315       "-scene value         image scene number",
316       "-seed value          seed a new sequence of pseudo-random numbers",
317       "-size geometry       width and height of image",
318       "-transparent-color color",
319       "                     transparent color",
320       "-treedepth value     color tree depth",
321       "-tile                repeat composite operation across and down image",
322       "-units type          the units of image resolution",
323       "-verbose             print detailed information about the image",
324       "-virtual-pixel method",
325       "                     virtual pixel access method",
326       "-white-point point   chromaticity white point",
327       (char *) NULL
328     },
329     *stack_operators[]=
330     {
331       "-swap indexes        swap two images in the image sequence",
332       (char *) NULL
333     };
334
335
336   (void) printf("Version: %s\n",GetMagickVersion((size_t *) NULL));
337   (void) printf("Copyright: %s\n",GetMagickCopyright());
338   (void) printf("Features: %s\n\n",GetMagickFeatures());
339   (void) printf("Usage: %s [options ...] image [options ...] composite\n"
340     "  [ [options ...] mask ] [options ...] composite\n",
341     GetClientName());
342   (void) printf("\nImage Settings:\n");
343   for (p=settings; *p != (char *) NULL; p++)
344     (void) printf("  %s\n",*p);
345   (void) printf("\nImage Operators:\n");
346   for (p=operators; *p != (char *) NULL; p++)
347     (void) printf("  %s\n",*p);
348   (void) printf("\nImage Stack Operators:\n");
349   for (p=stack_operators; *p != (char *) NULL; p++)
350     (void) printf("  %s\n",*p);
351   (void) printf("\nMiscellaneous Options:\n");
352   for (p=miscellaneous; *p != (char *) NULL; p++)
353     (void) printf("  %s\n",*p);
354   (void) printf(
355     "\nBy default, the image format of `file' is determined by its magic\n");
356   (void) printf(
357     "number.  To specify a particular image format, precede the filename\n");
358   (void) printf(
359     "with an image format name and a colon (i.e. ps:image) or specify the\n");
360   (void) printf(
361     "image type as the filename suffix (i.e. image.ps).  Specify 'file' as\n");
362   (void) printf("'-' for standard input or output.\n");
363   return(MagickFalse);
364 }
365
366 static void GetCompositeOptions(CompositeOptions *composite_options)
367 {
368   (void) ResetMagickMemory(composite_options,0,sizeof(*composite_options));
369   composite_options->channel=DefaultChannels;
370   composite_options->compose=OverCompositeOp;
371 }
372
373 static void RelinquishCompositeOptions(CompositeOptions *composite_options)
374 {
375   if (composite_options->compose_args != (char *) NULL)
376     composite_options->compose_args=(char *)
377       RelinquishMagickMemory(composite_options->compose_args);
378 }
379
380 WandExport MagickBooleanType CompositeImageCommand(ImageInfo *image_info,
381   int argc,char **argv,char **metadata,ExceptionInfo *exception)
382 {
383 #define NotInitialized  (unsigned int) (~0)
384 #define DestroyComposite() \
385 { \
386   RelinquishCompositeOptions(&composite_options); \
387   DestroyImageStack(); \
388   for (i=0; i < (ssize_t) argc; i++) \
389     argv[i]=DestroyString(argv[i]); \
390   argv=(char **) RelinquishMagickMemory(argv); \
391 }
392 #define ThrowCompositeException(asperity,tag,option) \
393 { \
394   (void) ThrowMagickException(exception,GetMagickModule(),asperity,tag,"`%s'", \
395      option == (char *) NULL ? GetExceptionMessage(errno) : option); \
396   DestroyComposite(); \
397   return(MagickFalse); \
398 }
399 #define ThrowCompositeInvalidArgumentException(option,argument) \
400 { \
401   (void) ThrowMagickException(exception,GetMagickModule(),OptionError, \
402     "InvalidArgument","`%s': %s",option,argument); \
403   DestroyComposite(); \
404   return(MagickFalse); \
405 }
406
407   char
408     *filename,
409     *option;
410
411   CompositeOptions
412     composite_options;
413
414   const char
415     *format;
416
417   Image
418     *composite_image,
419     *image,
420     *images,
421     *mask_image;
422
423   ImageStack
424     image_stack[MaxImageStackDepth+1];
425
426   MagickBooleanType
427     fire,
428     pend;
429
430   MagickStatusType
431     status;
432
433   ssize_t
434     j,
435     k;
436
437   register ssize_t
438     i;
439
440   /*
441     Set default.
442   */
443   assert(image_info != (ImageInfo *) NULL);
444   assert(image_info->signature == MagickSignature);
445   if (image_info->debug != MagickFalse)
446     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
447   assert(exception != (ExceptionInfo *) NULL);
448   if (argc == 2)
449     {
450       option=argv[1];
451       if ((LocaleCompare("version",option+1) == 0) ||
452           (LocaleCompare("-version",option+1) == 0))
453         {
454           (void) fprintf(stdout,"Version: %s\n",
455             GetMagickVersion((size_t *) NULL));
456           (void) fprintf(stdout,"Copyright: %s\n",GetMagickCopyright());
457           (void) fprintf(stdout,"Features: %s\n\n",GetMagickFeatures());
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   status=MagickTrue;
472   /*
473     Check command syntax.
474   */
475   composite_image=NewImageList();
476   image=NewImageList();
477   mask_image=NewImageList();
478   ReadCommandlLine(argc,&argv);
479   status=ExpandFilenames(&argc,&argv);
480   if (status == MagickFalse)
481     ThrowCompositeException(ResourceLimitError,"MemoryAllocationFailed",
482       GetExceptionMessage(errno));
483   for (i=1; i < (ssize_t) (argc-1); i++)
484   {
485     option=argv[i];
486     if (LocaleCompare(option,"(") == 0)
487       {
488         FireImageStack(MagickFalse,MagickTrue,pend);
489         if (k == MaxImageStackDepth)
490           ThrowCompositeException(OptionError,"ParenthesisNestedTooDeeply",
491             option);
492         PushImageStack();
493         continue;
494       }
495     if (LocaleCompare(option,")") == 0)
496       {
497         FireImageStack(MagickFalse,MagickTrue,MagickTrue);
498         if (k == 0)
499           ThrowCompositeException(OptionError,"UnableToParseExpression",option);
500         PopImageStack();
501         continue;
502       }
503     if (IsMagickOption(option) == MagickFalse)
504       {
505         Image
506           *images;
507
508         /*
509           Read input image.
510         */
511         FireImageStack(MagickFalse,MagickFalse,pend);
512         filename=argv[i];
513         if ((LocaleCompare(filename,"--") == 0) && (i < (ssize_t) (argc-1)))
514           filename=argv[++i];
515         (void) CopyMagickString(image_info->filename,filename,MaxTextExtent);
516         images=ReadImages(image_info,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=ParseMagickOption(MagickAlphaOptions,MagickFalse,argv[i]);
551             if (type < 0)
552               ThrowCompositeException(OptionError,
553                 "UnrecognizedAlphaChannelType",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=ParseMagickOption(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=ParseMagickOption(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=ParseMagickOption(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=ParseMagickOption(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=ParseMagickOption(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=ParseMagickOption(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=ParseMagickOption(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=ParseMagickOption(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=ParseMagickOption(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=ParseMagickOption(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=ParseMagickOption(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=ParseMagickOption(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=strtod(argv[i],&p);
1131             if ((p == argv[i]) && (LocaleCompare("unlimited",argv[i]) != 0))
1132               ThrowCompositeInvalidArgumentException(option,argv[i]);
1133             break;
1134           }
1135         if (LocaleCompare("list",option+1) == 0)
1136           {
1137             ssize_t
1138               list;
1139
1140             if (*option == '+')
1141               break;
1142             i++;
1143             if (i == (ssize_t) argc)
1144               ThrowCompositeException(OptionError,"MissingArgument",option);
1145             list=ParseMagickOption(MagickListOptions,MagickFalse,argv[i]);
1146             if (list < 0)
1147               ThrowCompositeException(OptionError,"UnrecognizedListType",
1148                 argv[i]);
1149             status=MogrifyImageInfo(image_info,(int) (i-j+1),(const char **)
1150               argv+j,exception);
1151             DestroyComposite();
1152             return(status != 0 ? MagickFalse : MagickTrue);
1153           }
1154         if (LocaleCompare("log",option+1) == 0)
1155           {
1156             if (*option == '+')
1157               break;
1158             i++;
1159             if ((i == (ssize_t) argc) || (strchr(argv[i],'%') == (char *) NULL))
1160               ThrowCompositeException(OptionError,"MissingArgument",option);
1161             break;
1162           }
1163         ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1164       }
1165       case 'm':
1166       {
1167         if (LocaleCompare("matte",option+1) == 0)
1168           break;
1169         if (LocaleCompare("monitor",option+1) == 0)
1170           break;
1171         if (LocaleCompare("monochrome",option+1) == 0)
1172           break;
1173         ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1174       }
1175       case 'n':
1176       {
1177         if (LocaleCompare("negate",option+1) == 0)
1178           break;
1179         if (LocaleCompare("noop",option+1) == 0)
1180           break;
1181         ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1182       }
1183       case 'p':
1184       {
1185         if (LocaleCompare("page",option+1) == 0)
1186           {
1187             if (*option == '+')
1188               break;
1189             i++;
1190             if (i == (ssize_t) argc)
1191               ThrowCompositeException(OptionError,"MissingArgument",option);
1192             break;
1193           }
1194         if (LocaleCompare("pointsize",option+1) == 0)
1195           {
1196             if (*option == '+')
1197               break;
1198             i++;
1199             if (i == (ssize_t) (argc-1))
1200               ThrowCompositeException(OptionError,"MissingArgument",option);
1201             if (IsGeometry(argv[i]) == MagickFalse)
1202               ThrowCompositeInvalidArgumentException(option,argv[i]);
1203             break;
1204           }
1205         if (LocaleCompare("process",option+1) == 0)
1206           {
1207             if (*option == '+')
1208               break;
1209             i++;
1210             if (i == (ssize_t) argc)
1211               ThrowCompositeException(OptionError,"MissingArgument",option);
1212             break;
1213           }
1214         if (LocaleCompare("profile",option+1) == 0)
1215           {
1216             i++;
1217             if (i == (ssize_t) argc)
1218               ThrowCompositeException(OptionError,"MissingArgument",option);
1219             break;
1220           }
1221         ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1222       }
1223       case 'q':
1224       {
1225         if (LocaleCompare("quality",option+1) == 0)
1226           {
1227             if (*option == '+')
1228               break;
1229             i++;
1230             if (i == (ssize_t) argc)
1231               ThrowCompositeException(OptionError,"MissingArgument",option);
1232             if (IsGeometry(argv[i]) == MagickFalse)
1233               ThrowCompositeInvalidArgumentException(option,argv[i]);
1234             break;
1235           }
1236         if (LocaleCompare("quantize",option+1) == 0)
1237           {
1238             ssize_t
1239               colorspace;
1240
1241             if (*option == '+')
1242               break;
1243             i++;
1244             if (i == (ssize_t) (argc-1))
1245               ThrowCompositeException(OptionError,"MissingArgument",option);
1246             colorspace=ParseMagickOption(MagickColorspaceOptions,
1247               MagickFalse,argv[i]);
1248             if (colorspace < 0)
1249               ThrowCompositeException(OptionError,"UnrecognizedColorspace",
1250                 argv[i]);
1251             break;
1252           }
1253         if (LocaleCompare("quiet",option+1) == 0)
1254           break;
1255         ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1256       }
1257       case 'r':
1258       {
1259         if (LocaleCompare("red-primary",option+1) == 0)
1260           {
1261             if (*option == '+')
1262               break;
1263             i++;
1264             if (i == (ssize_t) argc)
1265               ThrowCompositeException(OptionError,"MissingArgument",option);
1266             if (IsGeometry(argv[i]) == MagickFalse)
1267               ThrowCompositeInvalidArgumentException(option,argv[i]);
1268             break;
1269           }
1270         if (LocaleCompare("regard-warnings",option+1) == 0)
1271           break;
1272         if (LocaleCompare("render",option+1) == 0)
1273           break;
1274         if (LocaleCompare("repage",option+1) == 0)
1275           {
1276             if (*option == '+')
1277               break;
1278             i++;
1279             if (i == (ssize_t) argc)
1280               ThrowCompositeException(OptionError,"MissingArgument",option);
1281             if (IsGeometry(argv[i]) == MagickFalse)
1282               ThrowCompositeInvalidArgumentException(option,argv[i]);
1283             break;
1284           }
1285         if (LocaleNCompare("respect-parentheses",option+1,17) == 0)
1286           {
1287             respect_parenthesis=(*option == '-') ? MagickTrue : MagickFalse;
1288             break;
1289           }
1290         if (LocaleCompare("resize",option+1) == 0)
1291           {
1292             if (*option == '+')
1293               break;
1294             i++;
1295             if (i == (ssize_t) argc)
1296               ThrowCompositeException(OptionError,"MissingArgument",option);
1297             if (IsGeometry(argv[i]) == MagickFalse)
1298               ThrowCompositeInvalidArgumentException(option,argv[i]);
1299             break;
1300           }
1301         if (LocaleCompare("rotate",option+1) == 0)
1302           {
1303             i++;
1304             if (i == (ssize_t) argc)
1305               ThrowCompositeException(OptionError,"MissingArgument",option);
1306             if (IsGeometry(argv[i]) == MagickFalse)
1307               ThrowCompositeInvalidArgumentException(option,argv[i]);
1308             break;
1309           }
1310         ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1311       }
1312       case 's':
1313       {
1314         if (LocaleCompare("sampling-factor",option+1) == 0)
1315           {
1316             if (*option == '+')
1317               break;
1318             i++;
1319             if (i == (ssize_t) argc)
1320               ThrowCompositeException(OptionError,"MissingArgument",option);
1321             if (IsGeometry(argv[i]) == MagickFalse)
1322               ThrowCompositeInvalidArgumentException(option,argv[i]);
1323             break;
1324           }
1325         if (LocaleCompare("scene",option+1) == 0)
1326           {
1327             if (*option == '+')
1328               break;
1329             i++;
1330             if (i == (ssize_t) argc)
1331               ThrowCompositeException(OptionError,"MissingArgument",option);
1332             if (IsGeometry(argv[i]) == MagickFalse)
1333               ThrowCompositeInvalidArgumentException(option,argv[i]);
1334             break;
1335           }
1336         if (LocaleCompare("seed",option+1) == 0)
1337           {
1338             if (*option == '+')
1339               break;
1340             i++;
1341             if (i == (ssize_t) (argc-1))
1342               ThrowCompositeException(OptionError,"MissingArgument",option);
1343             if (IsGeometry(argv[i]) == MagickFalse)
1344               ThrowCompositeInvalidArgumentException(option,argv[i]);
1345             break;
1346           }
1347         if (LocaleCompare("sharpen",option+1) == 0)
1348           {
1349             i++;
1350             if (i == (ssize_t) argc)
1351               ThrowCompositeException(OptionError,"MissingArgument",option);
1352             if (IsGeometry(argv[i]) == MagickFalse)
1353               ThrowCompositeInvalidArgumentException(option,argv[i]);
1354             break;
1355           }
1356         if (LocaleCompare("shave",option+1) == 0)
1357           {
1358             if (*option == '+')
1359               break;
1360             i++;
1361             if (i == (ssize_t) (argc-1))
1362               ThrowCompositeException(OptionError,"MissingArgument",option);
1363             if (IsGeometry(argv[i]) == MagickFalse)
1364               ThrowCompositeInvalidArgumentException(option,argv[i]);
1365             break;
1366           }
1367         if (LocaleCompare("size",option+1) == 0)
1368           {
1369             if (*option == '+')
1370               break;
1371             i++;
1372             if (i == (ssize_t) argc)
1373               ThrowCompositeException(OptionError,"MissingArgument",option);
1374             if (IsGeometry(argv[i]) == MagickFalse)
1375               ThrowCompositeInvalidArgumentException(option,argv[i]);
1376             break;
1377           }
1378         if (LocaleCompare("stegano",option+1) == 0)
1379           {
1380             composite_options.stegano=0;
1381             if (*option == '+')
1382               break;
1383             i++;
1384             if (i == (ssize_t) argc)
1385               ThrowCompositeException(OptionError,"MissingArgument",option);
1386             if (IsGeometry(argv[i]) == MagickFalse)
1387               ThrowCompositeInvalidArgumentException(option,argv[i]);
1388             composite_options.stegano=StringToLong(argv[i])+1;
1389             break;
1390           }
1391         if (LocaleCompare("stereo",option+1) == 0)
1392           {
1393             MagickStatusType
1394               flags;
1395
1396             composite_options.stereo=MagickFalse;
1397             if (*option == '+')
1398               break;
1399             i++;
1400             if (i == (ssize_t) argc)
1401               ThrowCompositeException(OptionError,"MissingArgument",option);
1402             if (IsGeometry(argv[i]) == MagickFalse)
1403               ThrowCompositeInvalidArgumentException(option,argv[i]);
1404             flags=ParseAbsoluteGeometry(argv[i],&composite_options.offset);
1405             if ((flags & YValue) == 0)
1406               composite_options.offset.y=composite_options.offset.x;
1407             composite_options.stereo=MagickTrue;
1408             break;
1409           }
1410         if (LocaleCompare("strip",option+1) == 0)
1411           break;
1412         if (LocaleCompare("support",option+1) == 0)
1413           {
1414             i++;  /* deprecated */
1415             break;
1416           }
1417         if (LocaleCompare("swap",option+1) == 0)
1418           {
1419             if (*option == '+')
1420               break;
1421             i++;
1422             if (i == (ssize_t) (argc-1))
1423               ThrowCompositeException(OptionError,"MissingArgument",option);
1424             if (IsGeometry(argv[i]) == MagickFalse)
1425               ThrowCompositeInvalidArgumentException(option,argv[i]);
1426             break;
1427           }
1428         ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1429       }
1430       case 't':
1431       {
1432         if (LocaleCompare("thumbnail",option+1) == 0)
1433           {
1434             if (*option == '+')
1435               break;
1436             i++;
1437             if (i == (ssize_t) argc)
1438               ThrowCompositeException(OptionError,"MissingArgument",option);
1439             if (IsGeometry(argv[i]) == MagickFalse)
1440               ThrowCompositeInvalidArgumentException(option,argv[i]);
1441             break;
1442           }
1443         if (LocaleCompare("tile",option+1) == 0)
1444           {
1445             composite_options.tile=(*option == '-') ? MagickTrue : MagickFalse;
1446             (void) CopyMagickString(argv[i]+1,"sans",MaxTextExtent);
1447             break;
1448           }
1449         if (LocaleCompare("transform",option+1) == 0)
1450           break;
1451         if (LocaleCompare("transparent-color",option+1) == 0)
1452           {
1453             if (*option == '+')
1454               break;
1455             i++;
1456             if (i == (ssize_t) (argc-1))
1457               ThrowCompositeException(OptionError,"MissingArgument",option);
1458             break;
1459           }
1460         if (LocaleCompare("treedepth",option+1) == 0)
1461           {
1462             if (*option == '+')
1463               break;
1464             i++;
1465             if (i == (ssize_t) argc)
1466               ThrowCompositeException(OptionError,"MissingArgument",option);
1467             if (IsGeometry(argv[i]) == MagickFalse)
1468               ThrowCompositeInvalidArgumentException(option,argv[i]);
1469             break;
1470           }
1471         if (LocaleCompare("type",option+1) == 0)
1472           {
1473             ssize_t
1474               type;
1475
1476             if (*option == '+')
1477               break;
1478             i++;
1479             if (i == (ssize_t) argc)
1480               ThrowCompositeException(OptionError,"MissingArgument",option);
1481             type=ParseMagickOption(MagickTypeOptions,MagickFalse,argv[i]);
1482             if (type < 0)
1483               ThrowCompositeException(OptionError,"UnrecognizedImageType",
1484                 argv[i]);
1485             break;
1486           }
1487         ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1488       }
1489       case 'u':
1490       {
1491         if (LocaleCompare("units",option+1) == 0)
1492           {
1493             ssize_t
1494               units;
1495
1496             if (*option == '+')
1497               break;
1498             i++;
1499             if (i == (ssize_t) argc)
1500               ThrowCompositeException(OptionError,"MissingArgument",option);
1501             units=ParseMagickOption(MagickResolutionOptions,MagickFalse,
1502               argv[i]);
1503             if (units < 0)
1504               ThrowCompositeException(OptionError,"UnrecognizedUnitsType",
1505                 argv[i]);
1506             break;
1507           }
1508         if (LocaleCompare("unsharp",option+1) == 0)
1509           {
1510             (void) CloneString(&composite_options.compose_args,(char *) NULL);
1511             if (*option == '+')
1512               break;
1513             i++;
1514             if (i == (ssize_t) argc)
1515               ThrowCompositeException(OptionError,"MissingArgument",option);
1516             if (IsGeometry(argv[i]) == MagickFalse)
1517               ThrowCompositeInvalidArgumentException(option,argv[i]);
1518             (void) CloneString(&composite_options.compose_args,argv[i]);
1519             composite_options.compose=ThresholdCompositeOp;
1520             break;
1521           }
1522         ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1523       }
1524       case 'v':
1525       {
1526         if (LocaleCompare("verbose",option+1) == 0)
1527           break;
1528         if ((LocaleCompare("version",option+1) == 0) ||
1529             (LocaleCompare("-version",option+1) == 0))
1530           {
1531             (void) fprintf(stdout,"Version: %s\n",
1532               GetMagickVersion((size_t *) NULL));
1533             (void) fprintf(stdout,"Copyright: %s\n",GetMagickCopyright());
1534             (void) fprintf(stdout,"Features: %s\n\n",GetMagickFeatures());
1535             break;
1536           }
1537         if (LocaleCompare("virtual-pixel",option+1) == 0)
1538           {
1539             ssize_t
1540               method;
1541
1542             if (*option == '+')
1543               break;
1544             i++;
1545             if (i == (ssize_t) argc)
1546               ThrowCompositeException(OptionError,"MissingArgument",option);
1547             method=ParseMagickOption(MagickVirtualPixelOptions,MagickFalse,
1548               argv[i]);
1549             if (method < 0)
1550               ThrowCompositeException(OptionError,
1551                 "UnrecognizedVirtualPixelMethod",argv[i]);
1552             break;
1553           }
1554         ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1555       }
1556       case 'w':
1557       {
1558         if (LocaleCompare("watermark",option+1) == 0)
1559           {
1560             (void) CloneString(&composite_options.compose_args,(char *) NULL);
1561             if (*option == '+')
1562               break;
1563             i++;
1564             if (i == (ssize_t) argc)
1565               ThrowCompositeException(OptionError,"MissingArgument",option);
1566             if (IsGeometry(argv[i]) == MagickFalse)
1567               ThrowCompositeInvalidArgumentException(option,argv[i]);
1568             (void) CloneString(&composite_options.compose_args,argv[i]);
1569             composite_options.compose=ModulateCompositeOp;
1570             break;
1571           }
1572         if (LocaleCompare("white-point",option+1) == 0)
1573           {
1574             if (*option == '+')
1575               break;
1576             i++;
1577             if (i == (ssize_t) argc)
1578               ThrowCompositeException(OptionError,"MissingArgument",option);
1579             if (IsGeometry(argv[i]) == MagickFalse)
1580               ThrowCompositeInvalidArgumentException(option,argv[i]);
1581             break;
1582           }
1583         if (LocaleCompare("write",option+1) == 0)
1584           {
1585             i++;
1586             if (i == (ssize_t) argc)
1587               ThrowCompositeException(OptionError,"MissingArgument",option);
1588             break;
1589           }
1590         ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1591       }
1592       case '?':
1593         break;
1594       default:
1595         ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1596     }
1597     fire=ParseMagickOption(MagickImageListOptions,MagickFalse,option+1) < 0 ?
1598       MagickFalse : MagickTrue;
1599     if (fire != MagickFalse)
1600       FireImageStack(MagickFalse,MagickTrue,MagickTrue);
1601   }
1602   if (k != 0)
1603     ThrowCompositeException(OptionError,"UnbalancedParenthesis",argv[i]);
1604   if (i-- != (ssize_t) (argc-1))
1605     ThrowCompositeException(OptionError,"MissingAnImageFilename",argv[i]);
1606   if ((image == (Image *) NULL) || (GetImageListLength(image) < 2))
1607     ThrowCompositeException(OptionError,"MissingAnImageFilename",argv[argc-1]);
1608   FinalizeImageSettings(image_info,image,MagickTrue);
1609   if ((image == (Image *) NULL) || (GetImageListLength(image) < 2))
1610     ThrowCompositeException(OptionError,"MissingAnImageFilename",argv[argc-1]);
1611   /*
1612     Composite images.
1613   */
1614   RemoveImageStack(composite_image);
1615   RemoveImageStack(images);
1616   (void) TransformImage(&composite_image,(char *) NULL,
1617     composite_image->geometry);
1618   RemoveImageStack(mask_image);
1619   if (mask_image != (Image *) NULL)
1620     {
1621       if ((composite_options.compose == DisplaceCompositeOp) ||
1622           (composite_options.compose == DistortCompositeOp))
1623         {
1624           /*
1625             Merge Y displacement into X displacement image.
1626           */
1627           (void) CompositeImage(composite_image,CopyGreenCompositeOp,mask_image,
1628             0,0);
1629           mask_image=DestroyImage(mask_image);
1630         }
1631       else
1632         {
1633           /*
1634             Set a blending mask for the composition.
1635           */
1636           images->mask=mask_image;
1637           (void) NegateImage(images->mask,MagickFalse);
1638         }
1639     }
1640   status&=CompositeImageList(image_info,&images,composite_image,
1641     &composite_options,exception);
1642   composite_image=DestroyImage(composite_image);
1643   /*
1644     Write composite images.
1645   */
1646   status&=WriteImages(image_info,images,argv[argc-1],exception);
1647   if (metadata != (char **) NULL)
1648     {
1649       char
1650         *text;
1651
1652       text=InterpretImageProperties(image_info,images,format);
1653       if (text == (char *) NULL)
1654         ThrowCompositeException(ResourceLimitError,"MemoryAllocationFailed",
1655           GetExceptionMessage(errno));
1656       (void) ConcatenateString(&(*metadata),text);
1657       (void) ConcatenateString(&(*metadata),"\n");
1658       text=DestroyString(text);
1659     }
1660   images=DestroyImage(images);
1661   RelinquishCompositeOptions(&composite_options);
1662   DestroyComposite();
1663   return(status != 0 ? MagickTrue : MagickFalse);
1664 }