MagickWand  6.9.13-50
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/license/ %
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  char *message = GetExceptionMessage(errno); \
383  (void) ThrowMagickException(exception,GetMagickModule(),asperity,tag, \
384  "`%s'",option == (char *) NULL ? message : option); \
385  message=DestroyString(message); \
386  DestroyComposite(); \
387  return(MagickFalse); \
388 }
389 #define ThrowCompositeInvalidArgumentException(option,argument) \
390 { \
391  (void) ThrowMagickException(exception,GetMagickModule(),OptionError, \
392  "InvalidArgument","`%s': %s",option,argument); \
393  DestroyComposite(); \
394  return(MagickFalse); \
395 }
396 
397  char
398  *filename,
399  *option;
400 
402  composite_options;
403 
404  const char
405  *format;
406 
407  Image
408  *composite_image,
409  *image,
410  *images,
411  *mask_image;
412 
413  ImageStack
414  image_stack[MaxImageStackDepth+1];
415 
416  MagickBooleanType
417  fire,
418  pend,
419  respect_parenthesis;
420 
421  MagickStatusType
422  status;
423 
424  ssize_t
425  i;
426 
427  ssize_t
428  j,
429  k;
430 
431  /*
432  Set default.
433  */
434  assert(image_info != (ImageInfo *) NULL);
435  assert(image_info->signature == MagickCoreSignature);
436  if (image_info->debug != MagickFalse)
437  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
438  assert(exception != (ExceptionInfo *) NULL);
439  if (argc == 2)
440  {
441  option=argv[1];
442  if ((LocaleCompare("version",option+1) == 0) ||
443  (LocaleCompare("-version",option+1) == 0))
444  {
445  ListMagickVersion(stdout);
446  return(MagickTrue);
447  }
448  }
449  if (argc < 4)
450  {
451  (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
452  "MissingArgument","%s","");
453  (void) CompositeUsage();
454  return(MagickFalse);
455  }
456  GetCompositeOptions(&composite_options);
457  filename=(char *) NULL;
458  format="%w,%h,%m";
459  j=1;
460  k=0;
461  NewImageStack();
462  option=(char *) NULL;
463  pend=MagickFalse;
464  respect_parenthesis=MagickFalse;
465  status=MagickTrue;
466  /*
467  Check command syntax.
468  */
469  composite_image=NewImageList();
470  image=NewImageList();
471  mask_image=NewImageList();
472  ReadCommandlLine(argc,&argv);
473  status=ExpandFilenames(&argc,&argv);
474  if (status == MagickFalse)
475  ThrowCompositeException(ResourceLimitError,"MemoryAllocationFailed",
476  (char *) NULL);
477  for (i=1; i < ((ssize_t) argc-1); i++)
478  {
479  option=argv[i];
480  if (LocaleCompare(option,"(") == 0)
481  {
482  FireImageStack(MagickFalse,MagickTrue,pend);
483  if (k == MaxImageStackDepth)
484  ThrowCompositeException(OptionError,"ParenthesisNestedTooDeeply",
485  option);
486  PushImageStack();
487  continue;
488  }
489  if (LocaleCompare(option,")") == 0)
490  {
491  FireImageStack(MagickFalse,MagickTrue,MagickTrue);
492  if (k == 0)
493  ThrowCompositeException(OptionError,"UnableToParseExpression",option);
494  PopImageStack();
495  continue;
496  }
497  if (IsCommandOption(option) == MagickFalse)
498  {
499  Image
500  *images;
501 
502  /*
503  Read input image.
504  */
505  FireImageStack(MagickFalse,MagickFalse,pend);
506  filename=argv[i];
507  if ((LocaleCompare(filename,"--") == 0) && (i < ((ssize_t) argc-1)))
508  filename=argv[++i];
509  (void) SetImageOption(image_info,"filename",filename);
510  (void) CopyMagickString(image_info->filename,filename,MaxTextExtent);
511  images=ReadImages(image_info,exception);
512  status&=(images != (Image *) NULL) &&
513  (exception->severity < ErrorException);
514  if (images == (Image *) NULL)
515  continue;
516  AppendImageStack(images);
517  continue;
518  }
519  pend=image != (Image *) NULL ? MagickTrue : MagickFalse;
520  switch (*(option+1))
521  {
522  case 'a':
523  {
524  if (LocaleCompare("affine",option+1) == 0)
525  {
526  if (*option == '+')
527  break;
528  i++;
529  if (i == (ssize_t) argc)
530  ThrowCompositeException(OptionError,"MissingArgument",option);
531  if (IsGeometry(argv[i]) == MagickFalse)
532  ThrowCompositeInvalidArgumentException(option,argv[i]);
533  break;
534  }
535  if (LocaleCompare("alpha",option+1) == 0)
536  {
537  ssize_t
538  type;
539 
540  if (*option == '+')
541  break;
542  i++;
543  if (i == (ssize_t) argc)
544  ThrowCompositeException(OptionError,"MissingArgument",option);
545  type=ParseCommandOption(MagickAlphaOptions,MagickFalse,argv[i]);
546  if (type < 0)
547  ThrowCompositeException(OptionError,
548  "UnrecognizedAlphaChannelType",argv[i]);
549  break;
550  }
551  if (LocaleCompare("authenticate",option+1) == 0)
552  {
553  if (*option == '+')
554  break;
555  i++;
556  if (i == (ssize_t) argc)
557  ThrowCompositeException(OptionError,"MissingArgument",option);
558  break;
559  }
560  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
561  }
562  case 'b':
563  {
564  if (LocaleCompare("background",option+1) == 0)
565  {
566  if (*option == '+')
567  break;
568  i++;
569  if (i == (ssize_t) argc)
570  ThrowCompositeException(OptionError,"MissingArgument",option);
571  break;
572  }
573  if (LocaleCompare("blend",option+1) == 0)
574  {
575  (void) CloneString(&composite_options.compose_args,(char *) NULL);
576  if (*option == '+')
577  break;
578  i++;
579  if (i == (ssize_t) argc)
580  ThrowCompositeException(OptionError,"MissingArgument",option);
581  if (IsGeometry(argv[i]) == MagickFalse)
582  ThrowCompositeInvalidArgumentException(option,argv[i]);
583  (void) CloneString(&composite_options.compose_args,argv[i]);
584  composite_options.compose=BlendCompositeOp;
585  break;
586  }
587  if (LocaleCompare("blur",option+1) == 0)
588  {
589  (void) CloneString(&composite_options.compose_args,(char *) NULL);
590  if (*option == '+')
591  break;
592  i++;
593  if (i == (ssize_t) argc)
594  ThrowCompositeException(OptionError,"MissingArgument",option);
595  if (IsGeometry(argv[i]) == MagickFalse)
596  ThrowCompositeInvalidArgumentException(option,argv[i]);
597  (void) CloneString(&composite_options.compose_args,argv[i]);
598  composite_options.compose=BlurCompositeOp;
599  break;
600  }
601  if (LocaleCompare("blue-primary",option+1) == 0)
602  {
603  if (*option == '+')
604  break;
605  i++;
606  if (i == (ssize_t) argc)
607  ThrowCompositeException(OptionError,"MissingArgument",option);
608  if (IsGeometry(argv[i]) == MagickFalse)
609  ThrowCompositeInvalidArgumentException(option,argv[i]);
610  break;
611  }
612  if (LocaleCompare("border",option+1) == 0)
613  {
614  if (*option == '+')
615  break;
616  i++;
617  if (i == (ssize_t) argc)
618  ThrowCompositeException(OptionError,"MissingArgument",option);
619  if (IsGeometry(argv[i]) == MagickFalse)
620  ThrowCompositeInvalidArgumentException(option,argv[i]);
621  break;
622  }
623  if (LocaleCompare("bordercolor",option+1) == 0)
624  {
625  if (*option == '+')
626  break;
627  i++;
628  if (i == (ssize_t) argc)
629  ThrowCompositeException(OptionError,"MissingArgument",option);
630  break;
631  }
632  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
633  }
634  case 'c':
635  {
636  if (LocaleCompare("cache",option+1) == 0)
637  {
638  if (*option == '+')
639  break;
640  i++;
641  if (i == (ssize_t) argc)
642  ThrowCompositeException(OptionError,"MissingArgument",option);
643  if (IsGeometry(argv[i]) == MagickFalse)
644  ThrowCompositeInvalidArgumentException(option,argv[i]);
645  break;
646  }
647  if (LocaleCompare("channel",option+1) == 0)
648  {
649  ssize_t
650  channel;
651 
652  if (*option == '+')
653  {
654  composite_options.channel=DefaultChannels;
655  break;
656  }
657  i++;
658  if (i == (ssize_t) argc)
659  ThrowCompositeException(OptionError,"MissingArgument",option);
660  channel=ParseChannelOption(argv[i]);
661  if (channel < 0)
662  ThrowCompositeException(OptionError,"UnrecognizedChannelType",
663  argv[i]);
664  composite_options.channel=(ChannelType) channel;
665  break;
666  }
667  if (LocaleCompare("colors",option+1) == 0)
668  {
669  if (*option == '+')
670  break;
671  i++;
672  if (i == (ssize_t) argc)
673  ThrowCompositeException(OptionError,"MissingArgument",option);
674  if (IsGeometry(argv[i]) == MagickFalse)
675  ThrowCompositeInvalidArgumentException(option,argv[i]);
676  break;
677  }
678  if (LocaleCompare("colorspace",option+1) == 0)
679  {
680  ssize_t
681  colorspace;
682 
683  if (*option == '+')
684  break;
685  i++;
686  if (i == (ssize_t) argc)
687  ThrowCompositeException(OptionError,"MissingArgument",option);
688  colorspace=ParseCommandOption(MagickColorspaceOptions,
689  MagickFalse,argv[i]);
690  if (colorspace < 0)
691  ThrowCompositeException(OptionError,"UnrecognizedColorspace",
692  argv[i]);
693  break;
694  }
695  if (LocaleCompare("comment",option+1) == 0)
696  {
697  if (*option == '+')
698  break;
699  i++;
700  if (i == (ssize_t) argc)
701  ThrowCompositeException(OptionError,"MissingArgument",option);
702  break;
703  }
704  if (LocaleCompare("compose",option+1) == 0)
705  {
706  ssize_t
707  compose;
708 
709  composite_options.compose=UndefinedCompositeOp;
710  if (*option == '+')
711  break;
712  i++;
713  if (i == (ssize_t) argc)
714  ThrowCompositeException(OptionError,"MissingArgument",option);
715  compose=ParseCommandOption(MagickComposeOptions,MagickFalse,
716  argv[i]);
717  if (compose < 0)
718  ThrowCompositeException(OptionError,"UnrecognizedComposeOperator",
719  argv[i]);
720  composite_options.compose=(CompositeOperator) compose;
721  break;
722  }
723  if (LocaleCompare("compress",option+1) == 0)
724  {
725  ssize_t
726  compress;
727 
728  if (*option == '+')
729  break;
730  i++;
731  if (i == (ssize_t) argc)
732  ThrowCompositeException(OptionError,"MissingArgument",option);
733  compress=ParseCommandOption(MagickCompressOptions,MagickFalse,
734  argv[i]);
735  if (compress < 0)
736  ThrowCompositeException(OptionError,
737  "UnrecognizedImageCompression",argv[i]);
738  break;
739  }
740  if (LocaleCompare("concurrent",option+1) == 0)
741  break;
742  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
743  }
744  case 'd':
745  {
746  if (LocaleCompare("debug",option+1) == 0)
747  {
748  ssize_t
749  event;
750 
751  if (*option == '+')
752  break;
753  i++;
754  if (i == (ssize_t) argc)
755  ThrowCompositeException(OptionError,"MissingArgument",option);
756  event=ParseCommandOption(MagickLogEventOptions,MagickFalse,argv[i]);
757  if (event < 0)
758  ThrowCompositeException(OptionError,"UnrecognizedEventType",
759  argv[i]);
760  (void) SetLogEventMask(argv[i]);
761  break;
762  }
763  if (LocaleCompare("decipher",option+1) == 0)
764  {
765  if (*option == '+')
766  break;
767  i++;
768  if (i == (ssize_t) argc)
769  ThrowCompositeException(OptionError,"MissingArgument",option);
770  break;
771  }
772  if (LocaleCompare("define",option+1) == 0)
773  {
774  i++;
775  if (i == (ssize_t) argc)
776  ThrowCompositeException(OptionError,"MissingArgument",option);
777  if (*option == '+')
778  {
779  const char
780  *define;
781 
782  define=GetImageOption(image_info,argv[i]);
783  if (define == (const char *) NULL)
784  ThrowCompositeException(OptionError,"NoSuchOption",argv[i]);
785  break;
786  }
787  break;
788  }
789  if (LocaleCompare("density",option+1) == 0)
790  {
791  if (*option == '+')
792  break;
793  i++;
794  if (i == (ssize_t) argc)
795  ThrowCompositeException(OptionError,"MissingArgument",option);
796  if (IsGeometry(argv[i]) == MagickFalse)
797  ThrowCompositeInvalidArgumentException(option,argv[i]);
798  break;
799  }
800  if (LocaleCompare("depth",option+1) == 0)
801  {
802  if (*option == '+')
803  break;
804  i++;
805  if (i == (ssize_t) argc)
806  ThrowCompositeException(OptionError,"MissingArgument",option);
807  if (IsGeometry(argv[i]) == MagickFalse)
808  ThrowCompositeInvalidArgumentException(option,argv[i]);
809  break;
810  }
811  if (LocaleCompare("displace",option+1) == 0)
812  {
813  (void) CloneString(&composite_options.compose_args,(char *) NULL);
814  if (*option == '+')
815  break;
816  i++;
817  if (i == (ssize_t) argc)
818  ThrowCompositeException(OptionError,"MissingArgument",option);
819  if (IsGeometry(argv[i]) == MagickFalse)
820  ThrowCompositeInvalidArgumentException(option,argv[i]);
821  (void) CloneString(&composite_options.compose_args,argv[i]);
822  composite_options.compose=DisplaceCompositeOp;
823  break;
824  }
825  if (LocaleCompare("display",option+1) == 0)
826  {
827  if (*option == '+')
828  break;
829  i++;
830  if (i == (ssize_t) argc)
831  ThrowCompositeException(OptionError,"MissingArgument",option);
832  break;
833  }
834  if (LocaleCompare("dispose",option+1) == 0)
835  {
836  ssize_t
837  dispose;
838 
839  if (*option == '+')
840  break;
841  i++;
842  if (i == (ssize_t) argc)
843  ThrowCompositeException(OptionError,"MissingArgument",option);
844  dispose=ParseCommandOption(MagickDisposeOptions,MagickFalse,argv[i]);
845  if (dispose < 0)
846  ThrowCompositeException(OptionError,"UnrecognizedDisposeMethod",
847  argv[i]);
848  break;
849  }
850  if (LocaleCompare("dissolve",option+1) == 0)
851  {
852  (void) CloneString(&composite_options.compose_args,(char *) NULL);
853  if (*option == '+')
854  break;
855  i++;
856  if (i == (ssize_t) argc)
857  ThrowCompositeException(OptionError,"MissingArgument",option);
858  if (IsGeometry(argv[i]) == MagickFalse)
859  ThrowCompositeInvalidArgumentException(option,argv[i]);
860  (void) CloneString(&composite_options.compose_args,argv[i]);
861  composite_options.compose=DissolveCompositeOp;
862  break;
863  }
864  if (LocaleCompare("distort",option+1) == 0)
865  {
866  (void) CloneString(&composite_options.compose_args,(char *) NULL);
867  if (*option == '+')
868  break;
869  i++;
870  if (i == (ssize_t) argc)
871  ThrowCompositeException(OptionError,"MissingArgument",option);
872  if (IsGeometry(argv[i]) == MagickFalse)
873  ThrowCompositeInvalidArgumentException(option,argv[i]);
874  (void) CloneString(&composite_options.compose_args,argv[i]);
875  composite_options.compose=DistortCompositeOp;
876  break;
877  }
878  if (LocaleCompare("dither",option+1) == 0)
879  {
880  ssize_t
881  method;
882 
883  if (*option == '+')
884  break;
885  i++;
886  if (i == (ssize_t) argc)
887  ThrowCompositeException(OptionError,"MissingArgument",option);
888  method=ParseCommandOption(MagickDitherOptions,MagickFalse,argv[i]);
889  if (method < 0)
890  ThrowCompositeException(OptionError,"UnrecognizedDitherMethod",
891  argv[i]);
892  break;
893  }
894  if (LocaleCompare("duration",option+1) == 0)
895  {
896  if (*option == '+')
897  break;
898  i++;
899  if (i == (ssize_t) argc)
900  ThrowCompositeException(OptionError,"MissingArgument",option);
901  if (IsGeometry(argv[i]) == MagickFalse)
902  ThrowCompositeInvalidArgumentException(option,argv[i]);
903  break;
904  }
905  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
906  }
907  case 'e':
908  {
909  if (LocaleCompare("encipher",option+1) == 0)
910  {
911  if (*option == '+')
912  break;
913  i++;
914  if (i == (ssize_t) argc)
915  ThrowCompositeException(OptionError,"MissingArgument",option);
916  break;
917  }
918  if (LocaleCompare("encoding",option+1) == 0)
919  {
920  if (*option == '+')
921  break;
922  i++;
923  if (i == (ssize_t) argc)
924  ThrowCompositeException(OptionError,"MissingArgument",option);
925  break;
926  }
927  if (LocaleCompare("endian",option+1) == 0)
928  {
929  ssize_t
930  endian;
931 
932  if (*option == '+')
933  break;
934  i++;
935  if (i == (ssize_t) argc)
936  ThrowCompositeException(OptionError,"MissingArgument",option);
937  endian=ParseCommandOption(MagickEndianOptions,MagickFalse,
938  argv[i]);
939  if (endian < 0)
940  ThrowCompositeException(OptionError,"UnrecognizedEndianType",
941  argv[i]);
942  break;
943  }
944  if (LocaleCompare("extract",option+1) == 0)
945  {
946  if (*option == '+')
947  break;
948  i++;
949  if (i == (ssize_t) argc)
950  ThrowCompositeException(OptionError,"MissingArgument",option);
951  if (IsGeometry(argv[i]) == MagickFalse)
952  ThrowCompositeInvalidArgumentException(option,argv[i]);
953  break;
954  }
955  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
956  }
957  case 'f':
958  {
959  if (LocaleCompare("filter",option+1) == 0)
960  {
961  ssize_t
962  filter;
963 
964  if (*option == '+')
965  break;
966  i++;
967  if (i == (ssize_t) argc)
968  ThrowCompositeException(OptionError,"MissingArgument",option);
969  filter=ParseCommandOption(MagickFilterOptions,MagickFalse,argv[i]);
970  if (filter < 0)
971  ThrowCompositeException(OptionError,"UnrecognizedImageFilter",
972  argv[i]);
973  break;
974  }
975  if (LocaleCompare("font",option+1) == 0)
976  {
977  if (*option == '+')
978  break;
979  i++;
980  if (i == (ssize_t) argc)
981  ThrowCompositeException(OptionError,"MissingArgument",option);
982  break;
983  }
984  if (LocaleCompare("format",option+1) == 0)
985  {
986  if (*option == '+')
987  break;
988  i++;
989  if (i == (ssize_t) argc)
990  ThrowCompositeException(OptionError,"MissingArgument",option);
991  format=argv[i];
992  break;
993  }
994  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
995  }
996  case 'g':
997  {
998  if (LocaleCompare("geometry",option+1) == 0)
999  {
1000  (void) CloneString(&composite_options.geometry,(char *) NULL);
1001  if (*option == '+')
1002  break;
1003  i++;
1004  if (i == (ssize_t) argc)
1005  ThrowCompositeException(OptionError,"MissingArgument",option);
1006  if (IsGeometry(argv[i]) == MagickFalse)
1007  ThrowCompositeInvalidArgumentException(option,argv[i]);
1008  (void) CloneString(&composite_options.geometry,argv[i]);
1009  break;
1010  }
1011  if (LocaleCompare("gravity",option+1) == 0)
1012  {
1013  ssize_t
1014  gravity;
1015 
1016  composite_options.gravity=UndefinedGravity;
1017  if (*option == '+')
1018  break;
1019  i++;
1020  if (i == (ssize_t) argc)
1021  ThrowCompositeException(OptionError,"MissingArgument",option);
1022  gravity=ParseCommandOption(MagickGravityOptions,MagickFalse,
1023  argv[i]);
1024  if (gravity < 0)
1025  ThrowCompositeException(OptionError,"UnrecognizedGravityType",
1026  argv[i]);
1027  composite_options.gravity=(GravityType) gravity;
1028  break;
1029  }
1030  if (LocaleCompare("green-primary",option+1) == 0)
1031  {
1032  if (*option == '+')
1033  break;
1034  i++;
1035  if (i == (ssize_t) argc)
1036  ThrowCompositeException(OptionError,"MissingArgument",option);
1037  if (IsGeometry(argv[i]) == MagickFalse)
1038  ThrowCompositeInvalidArgumentException(option,argv[i]);
1039  break;
1040  }
1041  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1042  }
1043  case 'h':
1044  {
1045  if ((LocaleCompare("help",option+1) == 0) ||
1046  (LocaleCompare("-help",option+1) == 0))
1047  {
1048  DestroyComposite();
1049  return(CompositeUsage());
1050  }
1051  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1052  }
1053  case 'i':
1054  {
1055  if (LocaleCompare("identify",option+1) == 0)
1056  break;
1057  if (LocaleCompare("interlace",option+1) == 0)
1058  {
1059  ssize_t
1060  interlace;
1061 
1062  if (*option == '+')
1063  break;
1064  i++;
1065  if (i == (ssize_t) argc)
1066  ThrowCompositeException(OptionError,"MissingArgument",option);
1067  interlace=ParseCommandOption(MagickInterlaceOptions,MagickFalse,
1068  argv[i]);
1069  if (interlace < 0)
1070  ThrowCompositeException(OptionError,
1071  "UnrecognizedInterlaceType",argv[i]);
1072  break;
1073  }
1074  if (LocaleCompare("interpolate",option+1) == 0)
1075  {
1076  ssize_t
1077  interpolate;
1078 
1079  if (*option == '+')
1080  break;
1081  i++;
1082  if (i == (ssize_t) argc)
1083  ThrowCompositeException(OptionError,"MissingArgument",option);
1084  interpolate=ParseCommandOption(MagickInterpolateOptions,MagickFalse,
1085  argv[i]);
1086  if (interpolate < 0)
1087  ThrowCompositeException(OptionError,
1088  "UnrecognizedInterpolateMethod",argv[i]);
1089  break;
1090  }
1091  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1092  }
1093  case 'l':
1094  {
1095  if (LocaleCompare("label",option+1) == 0)
1096  {
1097  if (*option == '+')
1098  break;
1099  i++;
1100  if (i == (ssize_t) argc)
1101  ThrowCompositeException(OptionError,"MissingArgument",option);
1102  break;
1103  }
1104  if (LocaleCompare("limit",option+1) == 0)
1105  {
1106  char
1107  *p;
1108 
1109  double
1110  value;
1111 
1112  ssize_t
1113  resource;
1114 
1115  if (*option == '+')
1116  break;
1117  i++;
1118  if (i == (ssize_t) argc)
1119  ThrowCompositeException(OptionError,"MissingArgument",option);
1120  resource=ParseCommandOption(MagickResourceOptions,MagickFalse,
1121  argv[i]);
1122  if (resource < 0)
1123  ThrowCompositeException(OptionError,"UnrecognizedResourceType",
1124  argv[i]);
1125  i++;
1126  if (i == (ssize_t) argc)
1127  ThrowCompositeException(OptionError,"MissingArgument",option);
1128  value=StringToDouble(argv[i],&p);
1129  (void) value;
1130  if ((p == argv[i]) && (LocaleCompare("unlimited",argv[i]) != 0))
1131  ThrowCompositeInvalidArgumentException(option,argv[i]);
1132  break;
1133  }
1134  if (LocaleCompare("list",option+1) == 0)
1135  {
1136  ssize_t
1137  list;
1138 
1139  if (*option == '+')
1140  break;
1141  i++;
1142  if (i == (ssize_t) argc)
1143  ThrowCompositeException(OptionError,"MissingArgument",option);
1144  list=ParseCommandOption(MagickListOptions,MagickFalse,argv[i]);
1145  if (list < 0)
1146  ThrowCompositeException(OptionError,"UnrecognizedListType",
1147  argv[i]);
1148  status=MogrifyImageInfo(image_info,(int) (i-j+1),(const char **)
1149  argv+j,exception);
1150  DestroyComposite();
1151  return(status == 0 ? MagickFalse : MagickTrue);
1152  }
1153  if (LocaleCompare("log",option+1) == 0)
1154  {
1155  if (*option == '+')
1156  break;
1157  i++;
1158  if ((i == (ssize_t) argc) || (strchr(argv[i],'%') == (char *) NULL))
1159  ThrowCompositeException(OptionError,"MissingArgument",option);
1160  break;
1161  }
1162  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1163  }
1164  case 'm':
1165  {
1166  if (LocaleCompare("matte",option+1) == 0)
1167  break;
1168  if (LocaleCompare("monitor",option+1) == 0)
1169  break;
1170  if (LocaleCompare("monochrome",option+1) == 0)
1171  break;
1172  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1173  }
1174  case 'n':
1175  {
1176  if (LocaleCompare("negate",option+1) == 0)
1177  break;
1178  if (LocaleCompare("noop",option+1) == 0)
1179  break;
1180  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1181  }
1182  case 'p':
1183  {
1184  if (LocaleCompare("page",option+1) == 0)
1185  {
1186  if (*option == '+')
1187  break;
1188  i++;
1189  if (i == (ssize_t) argc)
1190  ThrowCompositeException(OptionError,"MissingArgument",option);
1191  break;
1192  }
1193  if (LocaleCompare("pointsize",option+1) == 0)
1194  {
1195  if (*option == '+')
1196  break;
1197  i++;
1198  if (i == (ssize_t) argc)
1199  ThrowCompositeException(OptionError,"MissingArgument",option);
1200  if (IsGeometry(argv[i]) == MagickFalse)
1201  ThrowCompositeInvalidArgumentException(option,argv[i]);
1202  break;
1203  }
1204  if (LocaleCompare("process",option+1) == 0)
1205  {
1206  if (*option == '+')
1207  break;
1208  i++;
1209  if (i == (ssize_t) argc)
1210  ThrowCompositeException(OptionError,"MissingArgument",option);
1211  break;
1212  }
1213  if (LocaleCompare("profile",option+1) == 0)
1214  {
1215  i++;
1216  if (i == (ssize_t) argc)
1217  ThrowCompositeException(OptionError,"MissingArgument",option);
1218  break;
1219  }
1220  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1221  }
1222  case 'q':
1223  {
1224  if (LocaleCompare("quality",option+1) == 0)
1225  {
1226  if (*option == '+')
1227  break;
1228  i++;
1229  if (i == (ssize_t) argc)
1230  ThrowCompositeException(OptionError,"MissingArgument",option);
1231  if (IsGeometry(argv[i]) == MagickFalse)
1232  ThrowCompositeInvalidArgumentException(option,argv[i]);
1233  break;
1234  }
1235  if (LocaleCompare("quantize",option+1) == 0)
1236  {
1237  ssize_t
1238  colorspace;
1239 
1240  if (*option == '+')
1241  break;
1242  i++;
1243  if (i == (ssize_t) argc)
1244  ThrowCompositeException(OptionError,"MissingArgument",option);
1245  colorspace=ParseCommandOption(MagickColorspaceOptions,
1246  MagickFalse,argv[i]);
1247  if (colorspace < 0)
1248  ThrowCompositeException(OptionError,"UnrecognizedColorspace",
1249  argv[i]);
1250  break;
1251  }
1252  if (LocaleCompare("quiet",option+1) == 0)
1253  break;
1254  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1255  }
1256  case 'r':
1257  {
1258  if (LocaleCompare("red-primary",option+1) == 0)
1259  {
1260  if (*option == '+')
1261  break;
1262  i++;
1263  if (i == (ssize_t) argc)
1264  ThrowCompositeException(OptionError,"MissingArgument",option);
1265  if (IsGeometry(argv[i]) == MagickFalse)
1266  ThrowCompositeInvalidArgumentException(option,argv[i]);
1267  break;
1268  }
1269  if (LocaleCompare("regard-warnings",option+1) == 0)
1270  break;
1271  if (LocaleCompare("render",option+1) == 0)
1272  break;
1273  if (LocaleCompare("repage",option+1) == 0)
1274  {
1275  if (*option == '+')
1276  break;
1277  i++;
1278  if (i == (ssize_t) argc)
1279  ThrowCompositeException(OptionError,"MissingArgument",option);
1280  if (IsGeometry(argv[i]) == MagickFalse)
1281  ThrowCompositeInvalidArgumentException(option,argv[i]);
1282  break;
1283  }
1284  if (LocaleNCompare("respect-parentheses",option+1,17) == 0)
1285  {
1286  respect_parenthesis=(*option == '-') ? MagickTrue : MagickFalse;
1287  break;
1288  }
1289  if (LocaleCompare("resize",option+1) == 0)
1290  {
1291  if (*option == '+')
1292  break;
1293  i++;
1294  if (i == (ssize_t) argc)
1295  ThrowCompositeException(OptionError,"MissingArgument",option);
1296  if (IsGeometry(argv[i]) == MagickFalse)
1297  ThrowCompositeInvalidArgumentException(option,argv[i]);
1298  break;
1299  }
1300  if (LocaleCompare("rotate",option+1) == 0)
1301  {
1302  i++;
1303  if (i == (ssize_t) argc)
1304  ThrowCompositeException(OptionError,"MissingArgument",option);
1305  if (IsGeometry(argv[i]) == MagickFalse)
1306  ThrowCompositeInvalidArgumentException(option,argv[i]);
1307  break;
1308  }
1309  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1310  }
1311  case 's':
1312  {
1313  if (LocaleCompare("sampling-factor",option+1) == 0)
1314  {
1315  if (*option == '+')
1316  break;
1317  i++;
1318  if (i == (ssize_t) argc)
1319  ThrowCompositeException(OptionError,"MissingArgument",option);
1320  if (IsGeometry(argv[i]) == MagickFalse)
1321  ThrowCompositeInvalidArgumentException(option,argv[i]);
1322  break;
1323  }
1324  if (LocaleCompare("scene",option+1) == 0)
1325  {
1326  if (*option == '+')
1327  break;
1328  i++;
1329  if (i == (ssize_t) argc)
1330  ThrowCompositeException(OptionError,"MissingArgument",option);
1331  if (IsGeometry(argv[i]) == MagickFalse)
1332  ThrowCompositeInvalidArgumentException(option,argv[i]);
1333  break;
1334  }
1335  if (LocaleCompare("seed",option+1) == 0)
1336  {
1337  if (*option == '+')
1338  break;
1339  i++;
1340  if (i == (ssize_t) argc)
1341  ThrowCompositeException(OptionError,"MissingArgument",option);
1342  if (IsGeometry(argv[i]) == MagickFalse)
1343  ThrowCompositeInvalidArgumentException(option,argv[i]);
1344  break;
1345  }
1346  if (LocaleCompare("sharpen",option+1) == 0)
1347  {
1348  i++;
1349  if (i == (ssize_t) argc)
1350  ThrowCompositeException(OptionError,"MissingArgument",option);
1351  if (IsGeometry(argv[i]) == MagickFalse)
1352  ThrowCompositeInvalidArgumentException(option,argv[i]);
1353  break;
1354  }
1355  if (LocaleCompare("shave",option+1) == 0)
1356  {
1357  if (*option == '+')
1358  break;
1359  i++;
1360  if (i == (ssize_t) argc)
1361  ThrowCompositeException(OptionError,"MissingArgument",option);
1362  if (IsGeometry(argv[i]) == MagickFalse)
1363  ThrowCompositeInvalidArgumentException(option,argv[i]);
1364  break;
1365  }
1366  if (LocaleCompare("size",option+1) == 0)
1367  {
1368  if (*option == '+')
1369  break;
1370  i++;
1371  if (i == (ssize_t) argc)
1372  ThrowCompositeException(OptionError,"MissingArgument",option);
1373  if (IsGeometry(argv[i]) == MagickFalse)
1374  ThrowCompositeInvalidArgumentException(option,argv[i]);
1375  break;
1376  }
1377  if (LocaleCompare("stegano",option+1) == 0)
1378  {
1379  composite_options.stegano=0;
1380  if (*option == '+')
1381  break;
1382  i++;
1383  if (i == (ssize_t) argc)
1384  ThrowCompositeException(OptionError,"MissingArgument",option);
1385  if (IsGeometry(argv[i]) == MagickFalse)
1386  ThrowCompositeInvalidArgumentException(option,argv[i]);
1387  composite_options.stegano=(ssize_t) StringToLong(argv[i])+1;
1388  break;
1389  }
1390  if (LocaleCompare("stereo",option+1) == 0)
1391  {
1392  MagickStatusType
1393  flags;
1394 
1395  composite_options.stereo=MagickFalse;
1396  if (*option == '+')
1397  break;
1398  i++;
1399  if (i == (ssize_t) argc)
1400  ThrowCompositeException(OptionError,"MissingArgument",option);
1401  if (IsGeometry(argv[i]) == MagickFalse)
1402  ThrowCompositeInvalidArgumentException(option,argv[i]);
1403  flags=ParseAbsoluteGeometry(argv[i],&composite_options.offset);
1404  if ((flags & YValue) == 0)
1405  composite_options.offset.y=composite_options.offset.x;
1406  composite_options.stereo=MagickTrue;
1407  break;
1408  }
1409  if (LocaleCompare("strip",option+1) == 0)
1410  break;
1411  if (LocaleCompare("support",option+1) == 0)
1412  {
1413  i++; /* deprecated */
1414  break;
1415  }
1416  if (LocaleCompare("swap",option+1) == 0)
1417  {
1418  if (*option == '+')
1419  break;
1420  i++;
1421  if (i == (ssize_t) argc)
1422  ThrowCompositeException(OptionError,"MissingArgument",option);
1423  if (IsGeometry(argv[i]) == MagickFalse)
1424  ThrowCompositeInvalidArgumentException(option,argv[i]);
1425  break;
1426  }
1427  if (LocaleCompare("synchronize",option+1) == 0)
1428  break;
1429  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1430  }
1431  case 't':
1432  {
1433  if (LocaleCompare("taint",option+1) == 0)
1434  break;
1435  if (LocaleCompare("thumbnail",option+1) == 0)
1436  {
1437  if (*option == '+')
1438  break;
1439  i++;
1440  if (i == (ssize_t) argc)
1441  ThrowCompositeException(OptionError,"MissingArgument",option);
1442  if (IsGeometry(argv[i]) == MagickFalse)
1443  ThrowCompositeInvalidArgumentException(option,argv[i]);
1444  break;
1445  }
1446  if (LocaleCompare("tile",option+1) == 0)
1447  {
1448  composite_options.tile=(*option == '-') ? MagickTrue : MagickFalse;
1449  (void) CopyMagickString(argv[i]+1,"sans",MaxTextExtent);
1450  break;
1451  }
1452  if (LocaleCompare("transform",option+1) == 0)
1453  break;
1454  if (LocaleCompare("transparent-color",option+1) == 0)
1455  {
1456  if (*option == '+')
1457  break;
1458  i++;
1459  if (i == (ssize_t) argc)
1460  ThrowCompositeException(OptionError,"MissingArgument",option);
1461  break;
1462  }
1463  if (LocaleCompare("treedepth",option+1) == 0)
1464  {
1465  if (*option == '+')
1466  break;
1467  i++;
1468  if (i == (ssize_t) argc)
1469  ThrowCompositeException(OptionError,"MissingArgument",option);
1470  if (IsGeometry(argv[i]) == MagickFalse)
1471  ThrowCompositeInvalidArgumentException(option,argv[i]);
1472  break;
1473  }
1474  if (LocaleCompare("type",option+1) == 0)
1475  {
1476  ssize_t
1477  type;
1478 
1479  if (*option == '+')
1480  break;
1481  i++;
1482  if (i == (ssize_t) argc)
1483  ThrowCompositeException(OptionError,"MissingArgument",option);
1484  type=ParseCommandOption(MagickTypeOptions,MagickFalse,argv[i]);
1485  if (type < 0)
1486  ThrowCompositeException(OptionError,"UnrecognizedImageType",
1487  argv[i]);
1488  break;
1489  }
1490  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1491  }
1492  case 'u':
1493  {
1494  if (LocaleCompare("units",option+1) == 0)
1495  {
1496  ssize_t
1497  units;
1498 
1499  if (*option == '+')
1500  break;
1501  i++;
1502  if (i == (ssize_t) argc)
1503  ThrowCompositeException(OptionError,"MissingArgument",option);
1504  units=ParseCommandOption(MagickResolutionOptions,MagickFalse,
1505  argv[i]);
1506  if (units < 0)
1507  ThrowCompositeException(OptionError,"UnrecognizedUnitsType",
1508  argv[i]);
1509  break;
1510  }
1511  if (LocaleCompare("unsharp",option+1) == 0)
1512  {
1513  (void) CloneString(&composite_options.compose_args,(char *) NULL);
1514  if (*option == '+')
1515  break;
1516  i++;
1517  if (i == (ssize_t) argc)
1518  ThrowCompositeException(OptionError,"MissingArgument",option);
1519  if (IsGeometry(argv[i]) == MagickFalse)
1520  ThrowCompositeInvalidArgumentException(option,argv[i]);
1521  (void) CloneString(&composite_options.compose_args,argv[i]);
1522  composite_options.compose=ThresholdCompositeOp;
1523  break;
1524  }
1525  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1526  }
1527  case 'v':
1528  {
1529  if (LocaleCompare("verbose",option+1) == 0)
1530  break;
1531  if ((LocaleCompare("version",option+1) == 0) ||
1532  (LocaleCompare("-version",option+1) == 0))
1533  {
1534  ListMagickVersion(stdout);
1535  break;
1536  }
1537  if (LocaleCompare("virtual-pixel",option+1) == 0)
1538  {
1539  ssize_t
1540  method;
1541 
1542  if (*option == '+')
1543  break;
1544  i++;
1545  if (i == (ssize_t) argc)
1546  ThrowCompositeException(OptionError,"MissingArgument",option);
1547  method=ParseCommandOption(MagickVirtualPixelOptions,MagickFalse,
1548  argv[i]);
1549  if (method < 0)
1550  ThrowCompositeException(OptionError,
1551  "UnrecognizedVirtualPixelMethod",argv[i]);
1552  break;
1553  }
1554  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1555  }
1556  case 'w':
1557  {
1558  if (LocaleCompare("watermark",option+1) == 0)
1559  {
1560  (void) CloneString(&composite_options.compose_args,(char *) NULL);
1561  if (*option == '+')
1562  break;
1563  i++;
1564  if (i == (ssize_t) argc)
1565  ThrowCompositeException(OptionError,"MissingArgument",option);
1566  if (IsGeometry(argv[i]) == MagickFalse)
1567  ThrowCompositeInvalidArgumentException(option,argv[i]);
1568  (void) CloneString(&composite_options.compose_args,argv[i]);
1569  composite_options.compose=ModulateCompositeOp;
1570  break;
1571  }
1572  if (LocaleCompare("white-point",option+1) == 0)
1573  {
1574  if (*option == '+')
1575  break;
1576  i++;
1577  if (i == (ssize_t) argc)
1578  ThrowCompositeException(OptionError,"MissingArgument",option);
1579  if (IsGeometry(argv[i]) == MagickFalse)
1580  ThrowCompositeInvalidArgumentException(option,argv[i]);
1581  break;
1582  }
1583  if (LocaleCompare("write",option+1) == 0)
1584  {
1585  i++;
1586  if (i == (ssize_t) argc)
1587  ThrowCompositeException(OptionError,"MissingArgument",option);
1588  break;
1589  }
1590  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1591  }
1592  case '?':
1593  break;
1594  default:
1595  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1596  }
1597  fire=(GetCommandOptionFlags(MagickCommandOptions,MagickFalse,option) &
1598  FireOptionFlag) == 0 ? MagickFalse : MagickTrue;
1599  if (fire != MagickFalse)
1600  FireImageStack(MagickFalse,MagickTrue,MagickTrue);
1601  }
1602  if (k != 0)
1603  ThrowCompositeException(OptionError,"UnbalancedParenthesis",argv[i]);
1604  if (i-- != ((ssize_t) argc-1))
1605  ThrowCompositeException(OptionError,"MissingAnImageFilename",argv[i]);
1606  if ((image == (Image *) NULL) || (GetImageListLength(image) < 2))
1607  ThrowCompositeException(OptionError,"MissingAnImageFilename",argv[argc-1]);
1608  FinalizeImageSettings(image_info,image,MagickTrue);
1609  if ((image == (Image *) NULL) || (GetImageListLength(image) < 2))
1610  ThrowCompositeException(OptionError,"MissingAnImageFilename",argv[argc-1]);
1611  /*
1612  Composite images.
1613  */
1614  RemoveImageStack(composite_image);
1615  RemoveImageStack(images);
1616  (void) TransformImage(&composite_image,(char *) NULL,
1617  composite_image->geometry);
1618  RemoveImageStack(mask_image);
1619  if (mask_image != (Image *) NULL)
1620  {
1621  if ((composite_options.compose == DisplaceCompositeOp) ||
1622  (composite_options.compose == DistortCompositeOp))
1623  {
1624  /*
1625  Merge Y displacement into X displacement image.
1626  */
1627  (void) CompositeImage(composite_image,CopyGreenCompositeOp,mask_image,
1628  0,0);
1629  mask_image=DestroyImage(mask_image);
1630  }
1631  else
1632  {
1633  /*
1634  Set a blending mask for the composition.
1635  */
1636  images->mask=mask_image;
1637  (void) NegateImage(images->mask,MagickFalse);
1638  }
1639  }
1640  status&=CompositeImageList(image_info,&images,composite_image,
1641  &composite_options,exception);
1642  composite_image=DestroyImage(composite_image);
1643  /*
1644  Write composite images.
1645  */
1646  status&=WriteImages(image_info,images,argv[argc-1],exception);
1647  if (metadata != (char **) NULL)
1648  {
1649  char
1650  *text;
1651 
1652  text=InterpretImageProperties(image_info,images,format);
1653  InheritException(exception,&image->exception);
1654  if (text == (char *) NULL)
1655  ThrowCompositeException(ResourceLimitError,"MemoryAllocationFailed",
1656  (char *) NULL);
1657  (void) ConcatenateString(&(*metadata),text);
1658  text=DestroyString(text);
1659  }
1660  images=DestroyImageList(images);
1661  RelinquishCompositeOptions(&composite_options);
1662  DestroyComposite();
1663  return(status != 0 ? MagickTrue : MagickFalse);
1664 }