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