root/ImageMagick/trunk/wand/composite.c

Revision 464, 57.8 KB (checked in by cristy, 4 weeks ago)
Line 
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
40/*
41  Include declarations.
42*/
43#include "wand/studio.h"
44#include "wand/MagickWand.h"
45#include "wand/mogrify-private.h"
46
47/*
48  Typedef declarations.
49*/
50typedef 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
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
109static 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
224static 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
365static 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
372static 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
379WandExport 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        if (LocaleCompare("concurrent",option+1) == 0)
748          break;
749        ThrowCompositeException(OptionError,"UnrecognizedOption",option)
750      }
751      case 'd':
752      {
753        if (LocaleCompare("debug",option+1) == 0)
754          {
755            long
756              event;
757
758            if (*option == '+')
759              break;
760            i++;
761            if (i == (long) argc)
762              ThrowCompositeException(OptionError,"MissingArgument",option);
763            event=ParseMagickOption(MagickLogEventOptions,MagickFalse,argv[i]);
764            if (event < 0)
765              ThrowCompositeException(OptionError,"UnrecognizedEventType",
766                argv[i]);
767            (void) SetLogEventMask(argv[i]);
768            break;
769          }
770        if (LocaleCompare("decipher",option+1) == 0)
771          {
772            if (*option == '+')
773              break;
774            i++;
775            if (i == (long) (argc-1))
776              ThrowCompositeException(OptionError,"MissingArgument",option);
777            break;
778          }
779        if (LocaleCompare("define",option+1) == 0)
780          {
781            i++;
782            if (i == (long) argc)
783              ThrowCompositeException(OptionError,"MissingArgument",option);
784            if (*option == '+')
785              {
786                const char
787                  *define;
788
789                define=GetImageOption(image_info,argv[i]);
790                if (define == (const char *) NULL)
791                  ThrowCompositeException(OptionError,"NoSuchOption",argv[i]);
792                break;
793              }
794            break;
795          }
796        if (LocaleCompare("density",option+1) == 0)
797          {
798            if (*option == '+')
799              break;
800            i++;
801            if (i == (long) argc)
802              ThrowCompositeException(OptionError,"MissingArgument",option);
803            if (IsGeometry(argv[i]) == MagickFalse)
804              ThrowCompositeInvalidArgumentException(option,argv[i]);
805            break;
806          }
807        if (LocaleCompare("depth",option+1) == 0)
808          {
809            if (*option == '+')
810              break;
811            i++;
812            if (i == (long) argc)
813              ThrowCompositeException(OptionError,"MissingArgument",option);
814            if (IsGeometry(argv[i]) == MagickFalse)
815              ThrowCompositeInvalidArgumentException(option,argv[i]);
816            break;
817          }
818        if (LocaleCompare("displace",option+1) == 0)
819          {
820            (void) CloneString(&composite_options.compose_args,(char *) NULL);
821            if (*option == '+')
822              break;
823            i++;
824            if (i == (long) argc)
825              ThrowCompositeException(OptionError,"MissingArgument",option);
826            if (IsGeometry(argv[i]) == MagickFalse)
827              ThrowCompositeInvalidArgumentException(option,argv[i]);
828            (void) CloneString(&composite_options.compose_args,argv[i]);
829            composite_options.compose=DisplaceCompositeOp;
830            break;
831          }
832        if (LocaleCompare("display",option+1) == 0)
833          {
834            if (*option == '+')
835              break;
836            i++;
837            if (i == (long) argc)
838              ThrowCompositeException(OptionError,"MissingArgument",option);
839            break;
840          }
841        if (LocaleCompare("dispose",option+1) == 0)
842          {
843            long
844              dispose;
845
846            if (*option == '+')
847              break;
848            i++;
849            if (i == (long) argc)
850              ThrowCompositeException(OptionError,"MissingArgument",option);
851            dispose=ParseMagickOption(MagickDisposeOptions,MagickFalse,argv[i]);
852            if (dispose < 0)
853              ThrowCompositeException(OptionError,"UnrecognizedDisposeMethod",
854                argv[i]);
855            break;
856          }
857        if (LocaleCompare("dissolve",option+1) == 0)
858          {
859            (void) CloneString(&composite_options.compose_args,(char *) NULL);
860            if (*option == '+')
861              break;
862            i++;
863            if (i == (long) argc)
864              ThrowCompositeException(OptionError,"MissingArgument",option);
865            if (IsGeometry(argv[i]) == MagickFalse)
866              ThrowCompositeInvalidArgumentException(option,argv[i]);
867            (void) CloneString(&composite_options.compose_args,argv[i]);
868            composite_options.compose=DissolveCompositeOp;
869            break;
870          }
871        if (LocaleCompare("distort",option+1) == 0)
872          {
873            (void) CloneString(&composite_options.compose_args,(char *) NULL);
874            if (*option == '+')
875              break;
876            i++;
877            if (i == (long) argc)
878              ThrowCompositeException(OptionError,"MissingArgument",option);
879            if (IsGeometry(argv[i]) == MagickFalse)
880              ThrowCompositeInvalidArgumentException(option,argv[i]);
881            (void) CloneString(&composite_options.compose_args,argv[i]);
882            composite_options.compose=DistortCompositeOp;
883            break;
884          }
885        if (LocaleCompare("dither",option+1) == 0)
886          {
887            long
888              method;
889
890            if (*option == '+')
891              break;
892            i++;
893            if (i == (long) argc)
894              ThrowCompositeException(OptionError,"MissingArgument",option);
895            method=ParseMagickOption(MagickDitherOptions,MagickFalse,argv[i]);
896            if (method < 0)
897              ThrowCompositeException(OptionError,"UnrecognizedDitherMethod",
898                argv[i]);
899            break;
900          }
901        if (LocaleCompare("duration",option+1) == 0)
902          {
903            if (*option == '+')
904              break;
905            i++;
906            if (i == (long) (argc-1))
907              ThrowCompositeException(OptionError,"MissingArgument",option);
908            if (IsGeometry(argv[i]) == MagickFalse)
909              ThrowCompositeInvalidArgumentException(option,argv[i]);
910            break;
911          }
912        ThrowCompositeException(OptionError,"UnrecognizedOption",option)
913      }
914      case 'e':
915      {
916        if (LocaleCompare("encipher",option+1) == 0)
917          {
918            if (*option == '+')
919              break;
920            i++;
921            if (i == (long) (argc-1))
922              ThrowCompositeException(OptionError,"MissingArgument",option);
923            break;
924          }
925        if (LocaleCompare("encoding",option+1) == 0)
926          {
927            if (*option == '+')
928              break;
929            i++;
930            if (i == (long) argc)
931              ThrowCompositeException(OptionError,"MissingArgument",option);
932            break;
933          }
934        if (LocaleCompare("endian",option+1) == 0)
935          {
936            long
937              endian;
938
939            if (*option == '+')
940              break;
941            i++;
942            if (i == (long) argc)
943              ThrowCompositeException(OptionError,"MissingArgument",option);
944            endian=ParseMagickOption(MagickEndianOptions,MagickFalse,
945              argv[i]);
946            if (endian < 0)
947              ThrowCompositeException(OptionError,"UnrecognizedEndianType",
948                argv[i]);
949            break;
950          }
951        if (LocaleCompare("extract",option+1) == 0)
952          {
953            if (*option == '+')
954              break;
955            i++;
956            if (i == (long) argc)
957              ThrowCompositeException(OptionError,"MissingArgument",option);
958            if (IsGeometry(argv[i]) == MagickFalse)
959              ThrowCompositeInvalidArgumentException(option,argv[i]);
960            break;
961          }
962        ThrowCompositeException(OptionError,"UnrecognizedOption",option)
963      }
964      case 'f':
965      {
966        if (LocaleCompare("filter",option+1) == 0)
967          {
968            long
969              filter;
970
971            if (*option == '+')
972              break;
973            i++;
974            if (i == (long) argc)
975              ThrowCompositeException(OptionError,"MissingArgument",option);
976            filter=ParseMagickOption(MagickFilterOptions,MagickFalse,argv[i]);
977            if (filter < 0)
978              ThrowCompositeException(OptionError,"UnrecognizedImageFilter",
979                argv[i]);
980            break;
981          }
982        if (LocaleCompare("font",option+1) == 0)
983          {
984            if (*option == '+')
985              break;
986            i++;
987            if (i == (long) argc)
988              ThrowCompositeException(OptionError,"MissingArgument",option);
989            break;
990          }
991        if (LocaleCompare("format",option+1) == 0)
992          {
993            if (*option == '+')
994              break;
995            i++;
996            if (i == (long) argc)
997              ThrowCompositeException(OptionError,"MissingArgument",option);
998            format=argv[i];
999            break;
1000          }
1001        ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1002      }
1003      case 'g':
1004      {
1005        if (LocaleCompare("geometry",option+1) == 0)
1006          {
1007            (void) CloneString(&composite_options.geometry,(char *) NULL);
1008            if (*option == '+')
1009              break;
1010            i++;
1011            if (i == (long) argc)
1012              ThrowCompositeException(OptionError,"MissingArgument",option);
1013            if (IsGeometry(argv[i]) == MagickFalse)
1014              ThrowCompositeInvalidArgumentException(option,argv[i]);
1015            (void) CloneString(&composite_options.geometry,argv[i]);
1016            break;
1017          }
1018        if (LocaleCompare("gravity",option+1) == 0)
1019          {
1020            long
1021              gravity;
1022
1023            composite_options.gravity=UndefinedGravity;
1024            if (*option == '+')
1025              break;
1026            i++;
1027            if (i == (long) argc)
1028              ThrowCompositeException(OptionError,"MissingArgument",option);
1029            gravity=ParseMagickOption(MagickGravityOptions,MagickFalse,
1030              argv[i]);
1031            if (gravity < 0)
1032              ThrowCompositeException(OptionError,"UnrecognizedGravityType",
1033                argv[i]);
1034            composite_options.gravity=(GravityType) gravity;
1035            break;
1036          }
1037        if (LocaleCompare("green-primary",option+1) == 0)
1038          {
1039            if (*option == '+')
1040              break;
1041            i++;
1042            if (i == (long) argc)
1043              ThrowCompositeException(OptionError,"MissingArgument",option);
1044            if (IsGeometry(argv[i]) == MagickFalse)
1045              ThrowCompositeInvalidArgumentException(option,argv[i]);
1046            break;
1047          }
1048        ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1049      }
1050      case 'h':
1051      {
1052        if ((LocaleCompare("help",option+1) == 0) ||
1053            (LocaleCompare("-help",option+1) == 0))
1054          return(CompositeUsage());
1055        ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1056      }
1057      case 'i':
1058      {
1059        if (LocaleCompare("identify",option+1) == 0)
1060          break;
1061        if (LocaleCompare("interlace",option+1) == 0)
1062          {
1063            long
1064              interlace;
1065
1066            if (*option == '+')
1067              break;
1068            i++;
1069            if (i == (long) argc)
1070              ThrowCompositeException(OptionError,"MissingArgument",option);
1071            interlace=ParseMagickOption(MagickInterlaceOptions,MagickFalse,
1072              argv[i]);
1073            if (interlace < 0)
1074              ThrowCompositeException(OptionError,
1075                "UnrecognizedInterlaceType",argv[i]);
1076            break;
1077          }
1078        if (LocaleCompare("interpolate",option+1) == 0)
1079          {
1080            long
1081              interpolate;
1082
1083            if (*option == '+')
1084              break;
1085            i++;
1086            if (i == (long) argc)
1087              ThrowCompositeException(OptionError,"MissingArgument",option);
1088            interpolate=ParseMagickOption(MagickInterpolateOptions,MagickFalse,
1089              argv[i]);
1090            if (interpolate < 0)
1091              ThrowCompositeException(OptionError,
1092                "UnrecognizedInterpolateMethod",argv[i]);
1093            break;
1094          }
1095        ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1096      }
1097      case 'l':
1098      {
1099        if (LocaleCompare("label",option+1) == 0)
1100          {
1101            if (*option == '+')
1102              break;
1103            i++;
1104            if (i == (long) argc)
1105              ThrowCompositeException(OptionError,"MissingArgument",option);
1106            break;
1107          }
1108        if (LocaleCompare("limit",option+1) == 0)
1109          {
1110            char
1111              *p;
1112
1113            double
1114              value;
1115
1116            long
1117              resource;
1118
1119            if (*option == '+')
1120              break;
1121            i++;
1122            if (i == (long) argc)
1123              ThrowCompositeException(OptionError,"MissingArgument",option);
1124            resource=ParseMagickOption(MagickResourceOptions,MagickFalse,
1125              argv[i]);
1126            if (resource < 0)
1127              ThrowCompositeException(OptionError,"UnrecognizedResourceType",
1128                argv[i]);
1129            i++;
1130            if (i == (long) argc)
1131              ThrowCompositeException(OptionError,"MissingArgument",option);
1132            value=strtod(argv[i],&p);
1133            if ((p == argv[i]) && (LocaleCompare("unlimited",argv[i]) != 0))
1134              ThrowCompositeInvalidArgumentException(option,argv[i]);
1135            break;
1136          }
1137        if (LocaleCompare("list",option+1) == 0)
1138          {
1139            long
1140              list;
1141
1142            if (*option == '+')
1143              break;
1144            i++;
1145            if (i == (long) argc)
1146              ThrowCompositeException(OptionError,"MissingArgument",option);
1147            list=ParseMagickOption(MagickListOptions,MagickFalse,argv[i]);
1148            if (list < 0)
1149              ThrowCompositeException(OptionError,"UnrecognizedListType",
1150                argv[i]);
1151            (void) MogrifyImageInfo(image_info,(int) (i-j+1),(const char **)
1152              argv+j,exception);
1153            DestroyComposite();
1154            return(MagickTrue);
1155          }
1156        if (LocaleCompare("log",option+1) == 0)
1157          {
1158            if (*option == '+')
1159              break;
1160            i++;
1161            if ((i == (long) argc) || (strchr(argv[i],'%') == (char *) NULL))
1162              ThrowCompositeException(OptionError,"MissingArgument",option);
1163            break;
1164          }
1165        ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1166      }
1167      case 'm':
1168      {
1169        if (LocaleCompare("matte",option+1) == 0)
1170          break;
1171        if (LocaleCompare("monitor",option+1) == 0)
1172          break;
1173        if (LocaleCompare("monochrome",option+1) == 0)
1174          break;
1175        ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1176      }
1177      case 'n':
1178      {
1179        if (LocaleCompare("negate",option+1) == 0)
1180          break;
1181        if (LocaleCompare("noop",option+1) == 0)
1182          break;
1183        ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1184      }
1185      case 'p':
1186      {
1187        if (LocaleCompare("page",option+1) == 0)
1188          {
1189            if (*option == '+')
1190              break;
1191            i++;
1192            if (i == (long) argc)
1193              ThrowCompositeException(OptionError,"MissingArgument",option);
1194            break;
1195          }
1196        if (LocaleCompare("pointsize",option+1) == 0)
1197          {
1198            if (*option == '+')
1199              break;
1200            i++;
1201            if (i == (long) (argc-1))
1202              ThrowCompositeException(OptionError,"MissingArgument",option);
1203            if (IsGeometry(argv[i]) == MagickFalse)
1204              ThrowCompositeInvalidArgumentException(option,argv[i]);
1205            break;
1206          }
1207        if (LocaleCompare("process",option+1) == 0)
1208          {
1209            if (*option == '+')
1210              break;
1211            i++;
1212            if (i == (long) argc)
1213              ThrowCompositeException(OptionError,"MissingArgument",option);
1214            break;
1215          }
1216        if (LocaleCompare("profile",option+1) == 0)
1217          {
1218            i++;
1219            if (i == (long) argc)
1220              ThrowCompositeException(OptionError,"MissingArgument",option);
1221            break;
1222          }
1223        ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1224      }
1225      case 'q':
1226      {
1227        if (LocaleCompare("quality",option+1) == 0)
1228          {
1229            if (*option == '+')
1230              break;
1231            i++;
1232            if (i == (long) argc)
1233              ThrowCompositeException(OptionError,"MissingArgument",option);
1234            if (IsGeometry(argv[i]) == MagickFalse)
1235              ThrowCompositeInvalidArgumentException(option,argv[i]);
1236            break;
1237          }
1238        if (LocaleCompare("quantize",option+1) == 0)
1239          {
1240            long
1241              colorspace;
1242
1243            if (*option == '+')
1244              break;
1245            i++;
1246            if (i == (long) (argc-1))
1247              ThrowCompositeException(OptionError,"MissingArgument",option);
1248            colorspace=ParseMagickOption(MagickColorspaceOptions,
1249              MagickFalse,argv[i]);
1250            if (colorspace < 0)
1251              ThrowCompositeException(OptionError,"UnrecognizedColorspace",
1252                argv[i]);
1253            break;
1254          }
1255        if (LocaleCompare("quiet",option+1) == 0)
1256          break;
1257        ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1258      }
1259      case 'r':
1260      {
1261        if (LocaleCompare("red-primary",option+1) == 0)
1262          {
1263            if (*option == '+')
1264              break;
1265            i++;
1266            if (i == (long) argc)
1267              ThrowCompositeException(OptionError,"MissingArgument",option);
1268            if (IsGeometry(argv[i]) == MagickFalse)
1269              ThrowCompositeInvalidArgumentException(option,argv[i]);
1270            break;
1271          }
1272        if (LocaleCompare("regard-warnings",option+1) == 0)
1273          break;
1274        if (LocaleCompare("render",option+1) == 0)
1275          break;
1276        if (LocaleCompare("repage",option+1) == 0)
1277          {
1278            if (*option == '+')
1279              break;
1280            i++;
1281            if (i == (long) argc)
1282              ThrowCompositeException(OptionError,"MissingArgument",option);
1283            if (IsGeometry(argv[i]) == MagickFalse)
1284              ThrowCompositeInvalidArgumentException(option,argv[i]);
1285            break;
1286          }
1287        if (LocaleNCompare("respect-parentheses",option+1,17) == 0)
1288          {
1289            respect_parenthesis=(*option == '-') ? MagickTrue : MagickFalse;
1290            break;
1291          }
1292        if (LocaleCompare("resize",option+1) == 0)
1293          {
1294            if (*option == '+')
1295              break;
1296            i++;
1297            if (i == (long) argc)
1298              ThrowCompositeException(OptionError,"MissingArgument",option);
1299            if (IsGeometry(argv[i]) == MagickFalse)
1300              ThrowCompositeInvalidArgumentException(option,argv[i]);
1301            break;
1302          }
1303        if (LocaleCompare("rotate",option+1) == 0)
1304          {
1305            i++;
1306            if (i == (long) argc)
1307              ThrowCompositeException(OptionError,"MissingArgument",option);
1308            if (IsGeometry(argv[i]) == MagickFalse)
1309              ThrowCompositeInvalidArgumentException(option,argv[i]);
1310            break;
1311          }
1312        ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1313      }
1314      case 's':
1315      {
1316        if (LocaleCompare("sampling-factor",option+1) == 0)
1317          {
1318            if (*option == '+')
1319              break;
1320            i++;
1321            if (i == (long) argc)
1322              ThrowCompositeException(OptionError,"MissingArgument",option);
1323            if (IsGeometry(argv[i]) == MagickFalse)
1324              ThrowCompositeInvalidArgumentException(option,argv[i]);
1325            break;
1326          }
1327        if (LocaleCompare("scene",option+1) == 0)
1328          {
1329            if (*option == '+')
1330              break;
1331            i++;
1332            if (i == (long) argc)
1333              ThrowCompositeException(OptionError,"MissingArgument",option);
1334            if (IsGeometry(argv[i]) == MagickFalse)
1335              ThrowCompositeInvalidArgumentException(option,argv[i]);
1336            break;
1337          }
1338        if (LocaleCompare("seed",option+1) == 0)
1339          {
1340            if (*option == '+')
1341              break;
1342            i++;
1343            if (i == (long) (argc-1))
1344              ThrowCompositeException(OptionError,"MissingArgument",option);
1345            if (IsGeometry(argv[i]) == MagickFalse)
1346              ThrowCompositeInvalidArgumentException(option,argv[i]);
1347            break;
1348          }
1349        if (LocaleCompare("sharpen",option+1) == 0)
1350          {
1351            i++;
1352            if (i == (long) argc)
1353              ThrowCompositeException(OptionError,"MissingArgument",option);
1354            if (IsGeometry(argv[i]) == MagickFalse)
1355              ThrowCompositeInvalidArgumentException(option,argv[i]);
1356            break;
1357          }
1358        if (LocaleCompare("shave",option+1) == 0)
1359          {
1360            if (*option == '+')
1361              break;
1362            i++;
1363            if (i == (long) (argc-1))
1364              ThrowCompositeException(OptionError,"MissingArgument",option);
1365            if (IsGeometry(argv[i]) == MagickFalse)
1366              ThrowCompositeInvalidArgumentException(option,argv[i]);
1367            break;
1368          }
1369        if (LocaleCompare("size",option+1) == 0)
1370          {
1371            if (*option == '+')
1372              break;
1373            i++;
1374            if (i == (long) argc)
1375              ThrowCompositeException(OptionError,"MissingArgument",option);
1376            if (IsGeometry(argv[i]) == MagickFalse)
1377              ThrowCompositeInvalidArgumentException(option,argv[i]);
1378            break;
1379          }
1380        if (LocaleCompare("stegano",option+1) == 0)
1381          {
1382            composite_options.stegano=0;
1383            if (*option == '+')
1384              break;
1385            i++;
1386            if (i == (long) argc)
1387              ThrowCompositeException(OptionError,"MissingArgument",option);
1388            if (IsGeometry(argv[i]) == MagickFalse)
1389              ThrowCompositeInvalidArgumentException(option,argv[i]);
1390            composite_options.stegano=atol(argv[i])+1;
1391            break;
1392          }
1393        if (LocaleCompare("stereo",option+1) == 0)
1394          {
1395            MagickStatusType
1396              flags;
1397
1398            composite_options.stereo=MagickFalse;
1399            if (*option == '+')
1400              break;
1401            i++;
1402            if (i == (long) argc)
1403              ThrowCompositeException(OptionError,"MissingArgument",option);
1404            if (IsGeometry(argv[i]) == MagickFalse)
1405              ThrowCompositeInvalidArgumentException(option,argv[i]);
1406            flags=ParseAbsoluteGeometry(argv[i],&composite_options.offset);
1407            if ((flags & YValue) == 0)
1408              composite_options.offset.y=composite_options.offset.x;
1409            composite_options.stereo=MagickTrue;
1410            break;
1411          }
1412        if (LocaleCompare("strip",option+1) == 0)
1413          break;
1414        if (LocaleCompare("support",option+1) == 0)
1415          {
1416            i++;  /* deprecated */
1417            break;
1418          }
1419        if (LocaleCompare("swap",option+1) == 0)
1420          {
1421            if (*option == '+')
1422              break;
1423            i++;
1424            if (i == (long) (argc-1))
1425              ThrowCompositeException(OptionError,"MissingArgument",option);
1426            if (IsGeometry(argv[i]) == MagickFalse)
1427              ThrowCompositeInvalidArgumentException(option,argv[i]);
1428            break;
1429          }
1430        ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1431      }
1432      case 't':
1433      {
1434        if (LocaleCompare("thumbnail",option+1) == 0)
1435          {
1436            if (*option == '+')
1437              break;
1438            i++;
1439            if (i == (long) argc)
1440              ThrowCompositeException(OptionError,"MissingArgument",option);
1441            if (IsGeometry(argv[i]) == MagickFalse)
1442              ThrowCompositeInvalidArgumentException(option,argv[i]);
1443            break;
1444          }
1445        if (LocaleCompare("tile",option+1) == 0)
1446          {
1447            composite_options.tile=(*option == '-') ? MagickTrue : MagickFalse;
1448            (void) CopyMagickString(argv[i]+1,"sans",MaxTextExtent);
1449            break;
1450          }
1451        if (LocaleCompare("transform",option+1) == 0)
1452          break;
1453        if (LocaleCompare("transparent-color",option+1) == 0)
1454          {
1455            if (*option == '+')
1456              break;
1457            i++;
1458            if (i == (long) (argc-1))
1459              ThrowCompositeException(OptionError,"MissingArgument",option);
1460            break;
1461          }
1462        if (LocaleCompare("treedepth",option+1) == 0)
1463          {
1464            if (*option == '+')
1465              break;
1466            i++;
1467            if (i == (long) argc)
1468              ThrowCompositeException(OptionError,"MissingArgument",option);
1469            if (IsGeometry(argv[i]) == MagickFalse)
1470              ThrowCompositeInvalidArgumentException(option,argv[i]);
1471            break;
1472          }
1473        if (LocaleCompare("type",option+1) == 0)
1474          {
1475            long
1476              type;
1477
1478            if (*option == '+')
1479              break;
1480            i++;
1481            if (i == (long) argc)
1482              ThrowCompositeException(OptionError,"MissingArgument",option);
1483            type=ParseMagickOption(MagickTypeOptions,MagickFalse,argv[i]);
1484            if (type < 0)
1485              ThrowCompositeException(OptionError,"UnrecognizedImageType",
1486                argv[i]);
1487            break;
1488          }
1489        ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1490      }
1491      case 'u':
1492      {
1493        if (LocaleCompare("units",option+1) == 0)
1494          {
1495            long
1496              units;
1497
1498            if (*option == '+')
1499              break;
1500            i++;
1501            if (i == (long) argc)
1502              ThrowCompositeException(OptionError,"MissingArgument",option);
1503            units=ParseMagickOption(MagickResolutionOptions,MagickFalse,
1504              argv[i]);
1505            if (units < 0)
1506              ThrowCompositeException(OptionError,"UnrecognizedUnitsType",
1507                argv[i]);
1508            break;
1509          }
1510        if (LocaleCompare("unsharp",option+1) == 0)
1511          {
1512            (void) CloneString(&composite_options.compose_args,(char *) NULL);
1513            if (*option == '+')
1514              break;
1515            i++;
1516            if (i == (long) argc)
1517              ThrowCompositeException(OptionError,"MissingArgument",option);
1518            if (IsGeometry(argv[i]) == MagickFalse)
1519              ThrowCompositeInvalidArgumentException(option,argv[i]);
1520            (void) CloneString(&composite_options.compose_args,argv[i]);
1521            composite_options.compose=ThresholdCompositeOp;
1522            break;
1523          }
1524        ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1525      }
1526      case 'v':
1527      {
1528        if (LocaleCompare("verbose",option+1) == 0)
1529          break;
1530        if ((LocaleCompare("version",option+1) == 0) ||
1531            (LocaleCompare("-version",option+1) == 0))
1532          {
1533            (void) fprintf(stdout,"Version: %s\n",
1534              GetMagickVersion((unsigned long *) NULL));
1535            (void) fprintf(stdout,"Copyright: %s\n",GetMagickCopyright());
1536            (void) fprintf(stdout,"Features: %s\n\n",GetMagickFeatures());
1537            break;
1538          }
1539        if (LocaleCompare("virtual-pixel",option+1) == 0)
1540          {
1541            long
1542              method;
1543
1544            if (*option == '+')
1545              break;
1546            i++;
1547            if (i == (long) argc)
1548              ThrowCompositeException(OptionError,"MissingArgument",option);
1549            method=ParseMagickOption(MagickVirtualPixelOptions,MagickFalse,
1550              argv[i]);
1551            if (method < 0)
1552              ThrowCompositeException(OptionError,
1553                "UnrecognizedVirtualPixelMethod",argv[i]);
1554            break;
1555          }
1556        ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1557      }
1558      case 'w':
1559      {
1560        if (LocaleCompare("watermark",option+1) == 0)
1561          {
1562            (void) CloneString(&composite_options.compose_args,(char *) NULL);
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            (void) CloneString(&composite_options.compose_args,argv[i]);
1571            composite_options.compose=ModulateCompositeOp;
1572            break;
1573          }
1574        if (LocaleCompare("white-point",option+1) == 0)
1575          {
1576            if (*option == '+')
1577              break;
1578            i++;
1579            if (i == (long) argc)
1580              ThrowCompositeException(OptionError,"MissingArgument",option);
1581            if (IsGeometry(argv[i]) == MagickFalse)
1582              ThrowCompositeInvalidArgumentException(option,argv[i]);
1583            break;
1584          }
1585        if (LocaleCompare("write",option+1) == 0)
1586          {
1587            i++;
1588            if (i == (long) argc)
1589              ThrowCompositeException(OptionError,"MissingArgument",option);
1590            break;
1591          }
1592        ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1593      }
1594      case '?':
1595        break;
1596      default:
1597        ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1598    }
1599    fire=ParseMagickOption(MagickImageListOptions,MagickFalse,option+1) < 0 ?
1600      MagickFalse : MagickTrue;
1601    if (fire != MagickFalse)
1602      FireImageStack(MagickFalse,MagickTrue,MagickTrue);
1603  }
1604  if (k != 0)
1605    ThrowCompositeException(OptionError,"UnbalancedParenthesis",argv[i]);
1606  if (i-- != (long) (argc-1))
1607    ThrowCompositeException(OptionError,"MissingAnImageFilename",argv[i]);
1608  if ((image == (Image *) NULL) || (GetImageListLength(image) < 2))
1609    ThrowCompositeException(OptionError,"MissingAnImageFilename",argv[argc-1]);
1610  FinalizeImageSettings(image_info,image,MagickTrue);
1611  if ((image == (Image *) NULL) || (GetImageListLength(image) < 2))
1612    ThrowCompositeException(OptionError,"MissingAnImageFilename",argv[argc-1]);
1613  /*
1614    Composite images.
1615  */
1616  RemoveImageStack(composite_image);
1617  RemoveImageStack(images);
1618  (void) TransformImage(&composite_image,(char *) NULL,
1619    composite_image->geometry);
1620  RemoveImageStack(mask_image);
1621  if (mask_image != (Image *) NULL)
1622    {
1623      if ((composite_options.compose == DisplaceCompositeOp) ||
1624          (composite_options.compose == DistortCompositeOp))
1625        {
1626          /*
1627            Merge Y displacement into X displacement image.
1628          */
1629          (void) CompositeImage(composite_image,CopyGreenCompositeOp,mask_image,
1630            0,0);
1631          mask_image=DestroyImage(mask_image);
1632        }
1633      else
1634        {
1635          /*
1636            Set a blending mask for the composition.
1637          */
1638          images->mask=mask_image;
1639          (void) NegateImage(images->mask,MagickFalse);
1640        }
1641    }
1642  status&=CompositeImageList(image_info,&images,composite_image,
1643    &composite_options,exception);
1644  composite_image=DestroyImage(composite_image);
1645  /*
1646    Write composite images.
1647  */
1648  status&=WriteImages(image_info,images,argv[argc-1],exception);
1649  if (metadata != (char **) NULL)
1650    {
1651      char
1652        *text;
1653
1654      text=InterpretImageProperties(image_info,images,format);
1655      if (text == (char *) NULL)
1656        ThrowCompositeException(ResourceLimitError,"MemoryAllocationFailed",
1657          GetExceptionMessage(errno));
1658      (void) ConcatenateString(&(*metadata),text);
1659      (void) ConcatenateString(&(*metadata),"\n");
1660      text=DestroyString(text);
1661    }
1662  images=DestroyImage(images);
1663  RelinquishCompositeOptions(&composite_options);
1664  DestroyComposite();
1665  return(status != 0 ? MagickTrue : MagickFalse);
1666}
Note: See TracBrowser for help on using the browser.