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