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