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