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