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