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