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