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