MagickWand  7.0.9
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-2020 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(MagickFalse);
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  register 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  return(CompositeUsage());
1073  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1074  }
1075  case 'i':
1076  {
1077  if (LocaleCompare("identify",option+1) == 0)
1078  break;
1079  if (LocaleCompare("interlace",option+1) == 0)
1080  {
1081  ssize_t
1082  interlace;
1083 
1084  if (*option == '+')
1085  break;
1086  i++;
1087  if (i == (ssize_t) argc)
1088  ThrowCompositeException(OptionError,"MissingArgument",option);
1089  interlace=ParseCommandOption(MagickInterlaceOptions,MagickFalse,
1090  argv[i]);
1091  if (interlace < 0)
1092  ThrowCompositeException(OptionError,
1093  "UnrecognizedInterlaceType",argv[i]);
1094  break;
1095  }
1096  if (LocaleCompare("interpolate",option+1) == 0)
1097  {
1098  ssize_t
1099  interpolate;
1100 
1101  if (*option == '+')
1102  break;
1103  i++;
1104  if (i == (ssize_t) argc)
1105  ThrowCompositeException(OptionError,"MissingArgument",option);
1106  interpolate=ParseCommandOption(MagickInterpolateOptions,MagickFalse,
1107  argv[i]);
1108  if (interpolate < 0)
1109  ThrowCompositeException(OptionError,
1110  "UnrecognizedInterpolateMethod",argv[i]);
1111  break;
1112  }
1113  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1114  }
1115  case 'l':
1116  {
1117  if (LocaleCompare("label",option+1) == 0)
1118  {
1119  if (*option == '+')
1120  break;
1121  i++;
1122  if (i == (ssize_t) argc)
1123  ThrowCompositeException(OptionError,"MissingArgument",option);
1124  break;
1125  }
1126  if (LocaleCompare("limit",option+1) == 0)
1127  {
1128  char
1129  *p;
1130 
1131  double
1132  value;
1133 
1134  ssize_t
1135  resource;
1136 
1137  if (*option == '+')
1138  break;
1139  i++;
1140  if (i == (ssize_t) argc)
1141  ThrowCompositeException(OptionError,"MissingArgument",option);
1142  resource=ParseCommandOption(MagickResourceOptions,MagickFalse,
1143  argv[i]);
1144  if (resource < 0)
1145  ThrowCompositeException(OptionError,"UnrecognizedResourceType",
1146  argv[i]);
1147  i++;
1148  if (i == (ssize_t) argc)
1149  ThrowCompositeException(OptionError,"MissingArgument",option);
1150  value=StringToDouble(argv[i],&p);
1151  (void) value;
1152  if ((p == argv[i]) && (LocaleCompare("unlimited",argv[i]) != 0))
1154  break;
1155  }
1156  if (LocaleCompare("list",option+1) == 0)
1157  {
1158  ssize_t
1159  list;
1160 
1161  if (*option == '+')
1162  break;
1163  i++;
1164  if (i == (ssize_t) argc)
1165  ThrowCompositeException(OptionError,"MissingArgument",option);
1166  list=ParseCommandOption(MagickListOptions,MagickFalse,argv[i]);
1167  if (list < 0)
1168  ThrowCompositeException(OptionError,"UnrecognizedListType",
1169  argv[i]);
1170  status=MogrifyImageInfo(image_info,(int) (i-j+1),(const char **)
1171  argv+j,exception);
1172  DestroyComposite();
1173  return(status == 0 ? MagickFalse : MagickTrue);
1174  }
1175  if (LocaleCompare("log",option+1) == 0)
1176  {
1177  if (*option == '+')
1178  break;
1179  i++;
1180  if ((i == (ssize_t) argc) || (strchr(argv[i],'%') == (char *) NULL))
1181  ThrowCompositeException(OptionError,"MissingArgument",option);
1182  break;
1183  }
1184  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1185  }
1186  case 'm':
1187  {
1188  if (LocaleCompare("matte",option+1) == 0)
1189  break;
1190  if (LocaleCompare("monitor",option+1) == 0)
1191  break;
1192  if (LocaleCompare("monochrome",option+1) == 0)
1193  break;
1194  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1195  }
1196  case 'n':
1197  {
1198  if (LocaleCompare("negate",option+1) == 0)
1199  break;
1200  if (LocaleCompare("noop",option+1) == 0)
1201  break;
1202  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1203  }
1204  case 'p':
1205  {
1206  if (LocaleCompare("page",option+1) == 0)
1207  {
1208  if (*option == '+')
1209  break;
1210  i++;
1211  if (i == (ssize_t) argc)
1212  ThrowCompositeException(OptionError,"MissingArgument",option);
1213  break;
1214  }
1215  if (LocaleCompare("pointsize",option+1) == 0)
1216  {
1217  if (*option == '+')
1218  break;
1219  i++;
1220  if (i == (ssize_t) argc)
1221  ThrowCompositeException(OptionError,"MissingArgument",option);
1222  if (IsGeometry(argv[i]) == MagickFalse)
1224  break;
1225  }
1226  if (LocaleCompare("process",option+1) == 0)
1227  {
1228  if (*option == '+')
1229  break;
1230  i++;
1231  if (i == (ssize_t) argc)
1232  ThrowCompositeException(OptionError,"MissingArgument",option);
1233  break;
1234  }
1235  if (LocaleCompare("profile",option+1) == 0)
1236  {
1237  i++;
1238  if (i == (ssize_t) argc)
1239  ThrowCompositeException(OptionError,"MissingArgument",option);
1240  break;
1241  }
1242  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1243  }
1244  case 'q':
1245  {
1246  if (LocaleCompare("quality",option+1) == 0)
1247  {
1248  if (*option == '+')
1249  break;
1250  i++;
1251  if (i == (ssize_t) argc)
1252  ThrowCompositeException(OptionError,"MissingArgument",option);
1253  if (IsGeometry(argv[i]) == MagickFalse)
1255  break;
1256  }
1257  if (LocaleCompare("quantize",option+1) == 0)
1258  {
1259  ssize_t
1260  colorspace;
1261 
1262  if (*option == '+')
1263  break;
1264  i++;
1265  if (i == (ssize_t) argc)
1266  ThrowCompositeException(OptionError,"MissingArgument",option);
1267  colorspace=ParseCommandOption(MagickColorspaceOptions,
1268  MagickFalse,argv[i]);
1269  if (colorspace < 0)
1270  ThrowCompositeException(OptionError,"UnrecognizedColorspace",
1271  argv[i]);
1272  break;
1273  }
1274  if (LocaleCompare("quiet",option+1) == 0)
1275  break;
1276  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1277  }
1278  case 'r':
1279  {
1280  if (LocaleCompare("red-primary",option+1) == 0)
1281  {
1282  if (*option == '+')
1283  break;
1284  i++;
1285  if (i == (ssize_t) argc)
1286  ThrowCompositeException(OptionError,"MissingArgument",option);
1287  if (IsGeometry(argv[i]) == MagickFalse)
1289  break;
1290  }
1291  if (LocaleCompare("regard-warnings",option+1) == 0)
1292  break;
1293  if (LocaleCompare("render",option+1) == 0)
1294  break;
1295  if (LocaleCompare("repage",option+1) == 0)
1296  {
1297  if (*option == '+')
1298  break;
1299  i++;
1300  if (i == (ssize_t) argc)
1301  ThrowCompositeException(OptionError,"MissingArgument",option);
1302  if (IsGeometry(argv[i]) == MagickFalse)
1304  break;
1305  }
1306  if (LocaleNCompare("respect-parentheses",option+1,17) == 0)
1307  {
1308  respect_parenthesis=(*option == '-') ? MagickTrue : MagickFalse;
1309  break;
1310  }
1311  if (LocaleCompare("resize",option+1) == 0)
1312  {
1313  if (*option == '+')
1314  break;
1315  i++;
1316  if (i == (ssize_t) argc)
1317  ThrowCompositeException(OptionError,"MissingArgument",option);
1318  if (IsGeometry(argv[i]) == MagickFalse)
1320  break;
1321  }
1322  if (LocaleCompare("rotate",option+1) == 0)
1323  {
1324  i++;
1325  if (i == (ssize_t) argc)
1326  ThrowCompositeException(OptionError,"MissingArgument",option);
1327  if (IsGeometry(argv[i]) == MagickFalse)
1329  break;
1330  }
1331  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1332  }
1333  case 's':
1334  {
1335  if (LocaleCompare("sampling-factor",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)
1344  break;
1345  }
1346  if (LocaleCompare("scene",option+1) == 0)
1347  {
1348  if (*option == '+')
1349  break;
1350  i++;
1351  if (i == (ssize_t) argc)
1352  ThrowCompositeException(OptionError,"MissingArgument",option);
1353  if (IsGeometry(argv[i]) == MagickFalse)
1355  break;
1356  }
1357  if (LocaleCompare("seed",option+1) == 0)
1358  {
1359  if (*option == '+')
1360  break;
1361  i++;
1362  if (i == (ssize_t) argc)
1363  ThrowCompositeException(OptionError,"MissingArgument",option);
1364  if (IsGeometry(argv[i]) == MagickFalse)
1366  break;
1367  }
1368  if (LocaleCompare("sharpen",option+1) == 0)
1369  {
1370  i++;
1371  if (i == (ssize_t) argc)
1372  ThrowCompositeException(OptionError,"MissingArgument",option);
1373  if (IsGeometry(argv[i]) == MagickFalse)
1375  break;
1376  }
1377  if (LocaleCompare("shave",option+1) == 0)
1378  {
1379  if (*option == '+')
1380  break;
1381  i++;
1382  if (i == (ssize_t) argc)
1383  ThrowCompositeException(OptionError,"MissingArgument",option);
1384  if (IsGeometry(argv[i]) == MagickFalse)
1386  break;
1387  }
1388  if (LocaleCompare("size",option+1) == 0)
1389  {
1390  if (*option == '+')
1391  break;
1392  i++;
1393  if (i == (ssize_t) argc)
1394  ThrowCompositeException(OptionError,"MissingArgument",option);
1395  if (IsGeometry(argv[i]) == MagickFalse)
1397  break;
1398  }
1399  if (LocaleCompare("stegano",option+1) == 0)
1400  {
1401  composite_options.stegano=0;
1402  if (*option == '+')
1403  break;
1404  i++;
1405  if (i == (ssize_t) argc)
1406  ThrowCompositeException(OptionError,"MissingArgument",option);
1407  if (IsGeometry(argv[i]) == MagickFalse)
1409  composite_options.stegano=(ssize_t) StringToLong(argv[i])+1;
1410  break;
1411  }
1412  if (LocaleCompare("stereo",option+1) == 0)
1413  {
1414  MagickStatusType
1415  flags;
1416 
1417  composite_options.stereo=MagickFalse;
1418  if (*option == '+')
1419  break;
1420  i++;
1421  if (i == (ssize_t) argc)
1422  ThrowCompositeException(OptionError,"MissingArgument",option);
1423  if (IsGeometry(argv[i]) == MagickFalse)
1425  flags=ParseAbsoluteGeometry(argv[i],&composite_options.offset);
1426  if ((flags & YValue) == 0)
1427  composite_options.offset.y=composite_options.offset.x;
1428  composite_options.stereo=MagickTrue;
1429  break;
1430  }
1431  if (LocaleCompare("strip",option+1) == 0)
1432  break;
1433  if (LocaleCompare("support",option+1) == 0)
1434  {
1435  i++; /* deprecated */
1436  break;
1437  }
1438  if (LocaleCompare("swap",option+1) == 0)
1439  {
1440  if (*option == '+')
1441  break;
1442  i++;
1443  if (i == (ssize_t) argc)
1444  ThrowCompositeException(OptionError,"MissingArgument",option);
1445  if (IsGeometry(argv[i]) == MagickFalse)
1447  break;
1448  }
1449  if (LocaleCompare("synchronize",option+1) == 0)
1450  break;
1451  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1452  }
1453  case 't':
1454  {
1455  if (LocaleCompare("taint",option+1) == 0)
1456  break;
1457  if (LocaleCompare("thumbnail",option+1) == 0)
1458  {
1459  if (*option == '+')
1460  break;
1461  i++;
1462  if (i == (ssize_t) argc)
1463  ThrowCompositeException(OptionError,"MissingArgument",option);
1464  if (IsGeometry(argv[i]) == MagickFalse)
1466  break;
1467  }
1468  if (LocaleCompare("tile",option+1) == 0)
1469  {
1470  composite_options.tile=(*option == '-') ? MagickTrue : MagickFalse;
1471  (void) CopyMagickString(argv[i]+1,"sans",MagickPathExtent);
1472  break;
1473  }
1474  if (LocaleCompare("transform",option+1) == 0)
1475  break;
1476  if (LocaleCompare("transparent-color",option+1) == 0)
1477  {
1478  if (*option == '+')
1479  break;
1480  i++;
1481  if (i == (ssize_t) argc)
1482  ThrowCompositeException(OptionError,"MissingArgument",option);
1483  break;
1484  }
1485  if (LocaleCompare("treedepth",option+1) == 0)
1486  {
1487  if (*option == '+')
1488  break;
1489  i++;
1490  if (i == (ssize_t) argc)
1491  ThrowCompositeException(OptionError,"MissingArgument",option);
1492  if (IsGeometry(argv[i]) == MagickFalse)
1494  break;
1495  }
1496  if (LocaleCompare("type",option+1) == 0)
1497  {
1498  ssize_t
1499  type;
1500 
1501  if (*option == '+')
1502  break;
1503  i++;
1504  if (i == (ssize_t) argc)
1505  ThrowCompositeException(OptionError,"MissingArgument",option);
1506  type=ParseCommandOption(MagickTypeOptions,MagickFalse,argv[i]);
1507  if (type < 0)
1508  ThrowCompositeException(OptionError,"UnrecognizedImageType",
1509  argv[i]);
1510  break;
1511  }
1512  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1513  }
1514  case 'u':
1515  {
1516  if (LocaleCompare("units",option+1) == 0)
1517  {
1518  ssize_t
1519  units;
1520 
1521  if (*option == '+')
1522  break;
1523  i++;
1524  if (i == (ssize_t) argc)
1525  ThrowCompositeException(OptionError,"MissingArgument",option);
1526  units=ParseCommandOption(MagickResolutionOptions,MagickFalse,
1527  argv[i]);
1528  if (units < 0)
1529  ThrowCompositeException(OptionError,"UnrecognizedUnitsType",
1530  argv[i]);
1531  break;
1532  }
1533  if (LocaleCompare("unsharp",option+1) == 0)
1534  {
1535  (void) CloneString(&composite_options.compose_args,(char *) NULL);
1536  if (*option == '+')
1537  break;
1538  i++;
1539  if (i == (ssize_t) argc)
1540  ThrowCompositeException(OptionError,"MissingArgument",option);
1541  if (IsGeometry(argv[i]) == MagickFalse)
1543  (void) CloneString(&composite_options.compose_args,argv[i]);
1544  composite_options.compose=ThresholdCompositeOp;
1545  break;
1546  }
1547  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1548  }
1549  case 'v':
1550  {
1551  if (LocaleCompare("verbose",option+1) == 0)
1552  break;
1553  if ((LocaleCompare("version",option+1) == 0) ||
1554  (LocaleCompare("-version",option+1) == 0))
1555  {
1556  ListMagickVersion(stdout);
1557  break;
1558  }
1559  if (LocaleCompare("virtual-pixel",option+1) == 0)
1560  {
1561  ssize_t
1562  method;
1563 
1564  if (*option == '+')
1565  break;
1566  i++;
1567  if (i == (ssize_t) argc)
1568  ThrowCompositeException(OptionError,"MissingArgument",option);
1569  method=ParseCommandOption(MagickVirtualPixelOptions,MagickFalse,
1570  argv[i]);
1571  if (method < 0)
1572  ThrowCompositeException(OptionError,
1573  "UnrecognizedVirtualPixelMethod",argv[i]);
1574  break;
1575  }
1576  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1577  }
1578  case 'w':
1579  {
1580  if (LocaleCompare("watermark",option+1) == 0)
1581  {
1582  (void) CloneString(&composite_options.compose_args,(char *) NULL);
1583  if (*option == '+')
1584  break;
1585  i++;
1586  if (i == (ssize_t) argc)
1587  ThrowCompositeException(OptionError,"MissingArgument",option);
1588  if (IsGeometry(argv[i]) == MagickFalse)
1590  (void) CloneString(&composite_options.compose_args,argv[i]);
1591  composite_options.compose=ModulateCompositeOp;
1592  break;
1593  }
1594  if (LocaleCompare("white-point",option+1) == 0)
1595  {
1596  if (*option == '+')
1597  break;
1598  i++;
1599  if (i == (ssize_t) argc)
1600  ThrowCompositeException(OptionError,"MissingArgument",option);
1601  if (IsGeometry(argv[i]) == MagickFalse)
1603  break;
1604  }
1605  if (LocaleCompare("write",option+1) == 0)
1606  {
1607  i++;
1608  if (i == (ssize_t) argc)
1609  ThrowCompositeException(OptionError,"MissingArgument",option);
1610  break;
1611  }
1612  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1613  }
1614  case '?':
1615  break;
1616  default:
1617  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1618  }
1619  fire=(GetCommandOptionFlags(MagickCommandOptions,MagickFalse,option) &
1620  FireOptionFlag) == 0 ? MagickFalse : MagickTrue;
1621  if (fire != MagickFalse)
1622  FireImageStack(MagickFalse,MagickTrue,MagickTrue);
1623  }
1624  if (k != 0)
1625  ThrowCompositeException(OptionError,"UnbalancedParenthesis",argv[i]);
1626  if (i-- != (ssize_t) (argc-1))
1627  ThrowCompositeException(OptionError,"MissingAnImageFilename",argv[i]);
1628  if ((image == (Image *) NULL) || (GetImageListLength(image) < 2))
1629  ThrowCompositeException(OptionError,"MissingAnImageFilename",argv[argc-1]);
1630  FinalizeImageSettings(image_info,image,MagickTrue);
1631  if ((image == (Image *) NULL) || (GetImageListLength(image) < 2))
1632  ThrowCompositeException(OptionError,"MissingAnImageFilename",argv[argc-1]);
1633  /*
1634  Composite images.
1635  */
1636  RemoveImageStack(composite_image);
1637  RemoveImageStack(images);
1638  if (composite_image->geometry != (char *) NULL)
1639  {
1640  RectangleInfo
1641  resize_geometry;
1642 
1643  (void) ParseRegionGeometry(composite_image,composite_image->geometry,
1644  &resize_geometry,exception);
1645  if ((composite_image->columns != resize_geometry.width) ||
1646  (composite_image->rows != resize_geometry.height))
1647  {
1648  Image
1649  *resize_image;
1650 
1651  resize_image=ResizeImage(composite_image,resize_geometry.width,
1652  resize_geometry.height,composite_image->filter,exception);
1653  if (resize_image != (Image *) NULL)
1654  {
1655  composite_image=DestroyImage(composite_image);
1656  composite_image=resize_image;
1657  }
1658  }
1659  }
1660  RemoveImageStack(mask_image);
1661  status&=CompositeImageList(image_info,&images,composite_image,mask_image,
1662  &composite_options,exception);
1663  composite_image=DestroyImage(composite_image);
1664  /*
1665  Write composite images.
1666  */
1667  status&=WriteImages(image_info,images,argv[argc-1],exception);
1668  if (metadata != (char **) NULL)
1669  {
1670  char
1671  *text;
1672 
1673  text=InterpretImageProperties(image_info,images,format,exception);
1674  if (text == (char *) NULL)
1675  ThrowCompositeException(ResourceLimitError,"MemoryAllocationFailed",
1676  GetExceptionMessage(errno));
1677  (void) ConcatenateString(&(*metadata),text);
1678  text=DestroyString(text);
1679  }
1680  images=DestroyImageList(images);
1681  RelinquishCompositeOptions(&composite_options);
1682  DestroyComposite();
1683  return(status != 0 ? MagickTrue : MagickFalse);
1684 }
#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:6578
#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:254
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