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