MagickWand  7.1.2-29
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/license/ %
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  char *message = GetExceptionMessage(errno); \
426  (void) ThrowMagickException(exception,GetMagickModule(),asperity,tag, \
427  "`%s'",option == (char *) NULL ? message : option); \
428  message=DestroyString(message); \
429  DestroyComposite(); \
430  return(MagickFalse); \
431 }
432 #define ThrowCompositeInvalidArgumentException(option,argument) \
433 { \
434  (void) ThrowMagickException(exception,GetMagickModule(),OptionError, \
435  "InvalidArgument","'%s': %s",option,argument); \
436  DestroyComposite(); \
437  return(MagickFalse); \
438 }
439 
440  char
441  *filename,
442  *option;
443 
445  composite_options;
446 
447  const char
448  *format;
449 
450  Image
451  *composite_image,
452  *image,
453  *images,
454  *mask_image;
455 
456  ImageStack
457  image_stack[MaxImageStackDepth+1];
458 
459  MagickBooleanType
460  fire,
461  pend,
462  respect_parentheses;
463 
464  MagickStatusType
465  status;
466 
467  ssize_t
468  i;
469 
470  ssize_t
471  j,
472  k;
473 
474  /*
475  Set default.
476  */
477  assert(image_info != (ImageInfo *) NULL);
478  assert(image_info->signature == MagickCoreSignature);
479  assert(exception != (ExceptionInfo *) NULL);
480  if (IsEventLogging() != MagickFalse)
481  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
482  if (argc == 2)
483  {
484  option=argv[1];
485  if ((LocaleCompare("version",option+1) == 0) ||
486  (LocaleCompare("-version",option+1) == 0))
487  {
488  ListMagickVersion(stdout);
489  return(MagickTrue);
490  }
491  }
492  if (argc < 4)
493  {
494  (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
495  "MissingArgument","%s","");
496  (void) CompositeUsage();
497  return(MagickFalse);
498  }
499  GetCompositeOptions(image_info,&composite_options);
500  filename=(char *) NULL;
501  format="%w,%h,%m";
502  j=1;
503  k=0;
504  NewImageStack();
505  option=(char *) NULL;
506  pend=MagickFalse;
507  respect_parentheses=MagickFalse;
508  status=MagickTrue;
509  /*
510  Check command syntax.
511  */
512  composite_image=NewImageList();
513  image=NewImageList();
514  mask_image=NewImageList();
515  ReadCommandlLine(argc,&argv);
516  status=ExpandFilenames(&argc,&argv);
517  if (status == MagickFalse)
518  ThrowCompositeException(ResourceLimitError,"MemoryAllocationFailed",
519  (char *) NULL);
520  for (i=1; i < ((ssize_t) argc-1); i++)
521  {
522  option=argv[i];
523  if (LocaleCompare(option,"(") == 0)
524  {
525  FireImageStack(MagickFalse,MagickTrue,pend);
526  if (k == MaxImageStackDepth)
527  ThrowCompositeException(OptionError,"ParenthesisNestedTooDeeply",
528  option);
529  PushImageStack();
530  continue;
531  }
532  if (LocaleCompare(option,")") == 0)
533  {
534  FireImageStack(MagickFalse,MagickTrue,MagickTrue);
535  if (k == 0)
536  ThrowCompositeException(OptionError,"UnableToParseExpression",option);
537  PopImageStack();
538  continue;
539  }
540  if (IsCommandOption(option) == MagickFalse)
541  {
542  /*
543  Read input image.
544  */
545  FireImageStack(MagickFalse,MagickFalse,pend);
546  filename=argv[i];
547  if ((LocaleCompare(filename,"--") == 0) && (i < ((ssize_t) argc-1)))
548  filename=argv[++i];
549  images=ReadImages(image_info,filename,exception);
550  status&=(MagickStatusType) (images != (Image *) NULL) &&
551  (exception->severity < ErrorException);
552  if (images == (Image *) NULL)
553  continue;
554  AppendImageStack(images);
555  continue;
556  }
557  pend=image != (Image *) NULL ? MagickTrue : MagickFalse;
558  switch (*(option+1))
559  {
560  case 'a':
561  {
562  if (LocaleCompare("affine",option+1) == 0)
563  {
564  if (*option == '+')
565  break;
566  i++;
567  if (i == (ssize_t) argc)
568  ThrowCompositeException(OptionError,"MissingArgument",option);
569  if (IsGeometry(argv[i]) == MagickFalse)
570  ThrowCompositeInvalidArgumentException(option,argv[i]);
571  break;
572  }
573  if (LocaleCompare("alpha",option+1) == 0)
574  {
575  ssize_t
576  type;
577 
578  if (*option == '+')
579  break;
580  i++;
581  if (i == (ssize_t) argc)
582  ThrowCompositeException(OptionError,"MissingArgument",option);
583  type=ParseCommandOption(MagickAlphaChannelOptions,MagickFalse,argv[i]);
584  if (type < 0)
585  ThrowCompositeException(OptionError,
586  "UnrecognizedAlphaChannelOption",argv[i]);
587  break;
588  }
589  if (LocaleCompare("authenticate",option+1) == 0)
590  {
591  if (*option == '+')
592  break;
593  i++;
594  if (i == (ssize_t) argc)
595  ThrowCompositeException(OptionError,"MissingArgument",option);
596  break;
597  }
598  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
599  }
600  case 'b':
601  {
602  if (LocaleCompare("background",option+1) == 0)
603  {
604  if (*option == '+')
605  break;
606  i++;
607  if (i == (ssize_t) argc)
608  ThrowCompositeException(OptionError,"MissingArgument",option);
609  break;
610  }
611  if (LocaleCompare("blend",option+1) == 0)
612  {
613  (void) CloneString(&composite_options.compose_args,(char *) NULL);
614  if (*option == '+')
615  break;
616  i++;
617  if (i == (ssize_t) argc)
618  ThrowCompositeException(OptionError,"MissingArgument",option);
619  if (IsGeometry(argv[i]) == MagickFalse)
620  ThrowCompositeInvalidArgumentException(option,argv[i]);
621  (void) CloneString(&composite_options.compose_args,argv[i]);
622  composite_options.compose=BlendCompositeOp;
623  break;
624  }
625  if (LocaleCompare("blur",option+1) == 0)
626  {
627  (void) CloneString(&composite_options.compose_args,(char *) NULL);
628  if (*option == '+')
629  break;
630  i++;
631  if (i == (ssize_t) argc)
632  ThrowCompositeException(OptionError,"MissingArgument",option);
633  if (IsGeometry(argv[i]) == MagickFalse)
634  ThrowCompositeInvalidArgumentException(option,argv[i]);
635  (void) CloneString(&composite_options.compose_args,argv[i]);
636  composite_options.compose=BlurCompositeOp;
637  break;
638  }
639  if (LocaleCompare("blue-primary",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("border",option+1) == 0)
651  {
652  if (*option == '+')
653  break;
654  i++;
655  if (i == (ssize_t) argc)
656  ThrowCompositeException(OptionError,"MissingArgument",option);
657  if (IsGeometry(argv[i]) == MagickFalse)
658  ThrowCompositeInvalidArgumentException(option,argv[i]);
659  break;
660  }
661  if (LocaleCompare("bordercolor",option+1) == 0)
662  {
663  if (*option == '+')
664  break;
665  i++;
666  if (i == (ssize_t) argc)
667  ThrowCompositeException(OptionError,"MissingArgument",option);
668  break;
669  }
670  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
671  }
672  case 'c':
673  {
674  if (LocaleCompare("cache",option+1) == 0)
675  {
676  if (*option == '+')
677  break;
678  i++;
679  if (i == (ssize_t) argc)
680  ThrowCompositeException(OptionError,"MissingArgument",option);
681  if (IsGeometry(argv[i]) == MagickFalse)
682  ThrowCompositeInvalidArgumentException(option,argv[i]);
683  break;
684  }
685  if (LocaleCompare("channel",option+1) == 0)
686  {
687  ssize_t
688  channel;
689 
690  if (*option == '+')
691  {
692  composite_options.channel=DefaultChannels;
693  break;
694  }
695  i++;
696  if (i == (ssize_t) argc)
697  ThrowCompositeException(OptionError,"MissingArgument",option);
698  channel=ParseChannelOption(argv[i]);
699  if (channel < 0)
700  ThrowCompositeException(OptionError,"UnrecognizedChannelType",
701  argv[i]);
702  composite_options.channel=(ChannelType) channel;
703  break;
704  }
705  if (LocaleCompare("colors",option+1) == 0)
706  {
707  if (*option == '+')
708  break;
709  i++;
710  if (i == (ssize_t) argc)
711  ThrowCompositeException(OptionError,"MissingArgument",option);
712  if (IsGeometry(argv[i]) == MagickFalse)
713  ThrowCompositeInvalidArgumentException(option,argv[i]);
714  break;
715  }
716  if (LocaleCompare("colorspace",option+1) == 0)
717  {
718  ssize_t
719  colorspace;
720 
721  if (*option == '+')
722  break;
723  i++;
724  if (i == (ssize_t) argc)
725  ThrowCompositeException(OptionError,"MissingArgument",option);
726  colorspace=ParseCommandOption(MagickColorspaceOptions,
727  MagickFalse,argv[i]);
728  if (colorspace < 0)
729  ThrowCompositeException(OptionError,"UnrecognizedColorspace",
730  argv[i]);
731  break;
732  }
733  if (LocaleCompare("comment",option+1) == 0)
734  {
735  if (*option == '+')
736  break;
737  i++;
738  if (i == (ssize_t) argc)
739  ThrowCompositeException(OptionError,"MissingArgument",option);
740  break;
741  }
742  if (LocaleCompare("compose",option+1) == 0)
743  {
744  ssize_t
745  compose;
746 
747  composite_options.compose=UndefinedCompositeOp;
748  if (*option == '+')
749  break;
750  i++;
751  if (i == (ssize_t) argc)
752  ThrowCompositeException(OptionError,"MissingArgument",option);
753  compose=ParseCommandOption(MagickComposeOptions,MagickFalse,
754  argv[i]);
755  if (compose < 0)
756  ThrowCompositeException(OptionError,"UnrecognizedComposeOperator",
757  argv[i]);
758  composite_options.compose=(CompositeOperator) compose;
759  break;
760  }
761  if (LocaleCompare("compress",option+1) == 0)
762  {
763  ssize_t
764  compress;
765 
766  if (*option == '+')
767  break;
768  i++;
769  if (i == (ssize_t) argc)
770  ThrowCompositeException(OptionError,"MissingArgument",option);
771  compress=ParseCommandOption(MagickCompressOptions,MagickFalse,
772  argv[i]);
773  if (compress < 0)
774  ThrowCompositeException(OptionError,
775  "UnrecognizedImageCompression",argv[i]);
776  break;
777  }
778  if (LocaleCompare("concurrent",option+1) == 0)
779  break;
780  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
781  }
782  case 'd':
783  {
784  if (LocaleCompare("debug",option+1) == 0)
785  {
786  ssize_t
787  event;
788 
789  if (*option == '+')
790  break;
791  i++;
792  if (i == (ssize_t) argc)
793  ThrowCompositeException(OptionError,"MissingArgument",option);
794  event=ParseCommandOption(MagickLogEventOptions,MagickFalse,argv[i]);
795  if (event < 0)
796  ThrowCompositeException(OptionError,"UnrecognizedEventType",
797  argv[i]);
798  (void) SetLogEventMask(argv[i]);
799  break;
800  }
801  if (LocaleCompare("decipher",option+1) == 0)
802  {
803  if (*option == '+')
804  break;
805  i++;
806  if (i == (ssize_t) argc)
807  ThrowCompositeException(OptionError,"MissingArgument",option);
808  break;
809  }
810  if (LocaleCompare("define",option+1) == 0)
811  {
812  i++;
813  if (i == (ssize_t) argc)
814  ThrowCompositeException(OptionError,"MissingArgument",option);
815  if (*option == '+')
816  {
817  const char
818  *define;
819 
820  define=GetImageOption(image_info,argv[i]);
821  if (define == (const char *) NULL)
822  ThrowCompositeException(OptionError,"NoSuchOption",argv[i]);
823  break;
824  }
825  break;
826  }
827  if (LocaleCompare("density",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("depth",option+1) == 0)
839  {
840  if (*option == '+')
841  break;
842  i++;
843  if (i == (ssize_t) argc)
844  ThrowCompositeException(OptionError,"MissingArgument",option);
845  if (IsGeometry(argv[i]) == MagickFalse)
846  ThrowCompositeInvalidArgumentException(option,argv[i]);
847  break;
848  }
849  if (LocaleCompare("displace",option+1) == 0)
850  {
851  (void) CloneString(&composite_options.compose_args,(char *) NULL);
852  if (*option == '+')
853  break;
854  i++;
855  if (i == (ssize_t) argc)
856  ThrowCompositeException(OptionError,"MissingArgument",option);
857  if (IsGeometry(argv[i]) == MagickFalse)
858  ThrowCompositeInvalidArgumentException(option,argv[i]);
859  (void) CloneString(&composite_options.compose_args,argv[i]);
860  composite_options.compose=DisplaceCompositeOp;
861  break;
862  }
863  if (LocaleCompare("display",option+1) == 0)
864  {
865  if (*option == '+')
866  break;
867  i++;
868  if (i == (ssize_t) argc)
869  ThrowCompositeException(OptionError,"MissingArgument",option);
870  break;
871  }
872  if (LocaleCompare("dispose",option+1) == 0)
873  {
874  ssize_t
875  dispose;
876 
877  if (*option == '+')
878  break;
879  i++;
880  if (i == (ssize_t) argc)
881  ThrowCompositeException(OptionError,"MissingArgument",option);
882  dispose=ParseCommandOption(MagickDisposeOptions,MagickFalse,argv[i]);
883  if (dispose < 0)
884  ThrowCompositeException(OptionError,"UnrecognizedDisposeMethod",
885  argv[i]);
886  break;
887  }
888  if (LocaleCompare("dissolve",option+1) == 0)
889  {
890  (void) CloneString(&composite_options.compose_args,(char *) NULL);
891  if (*option == '+')
892  break;
893  i++;
894  if (i == (ssize_t) argc)
895  ThrowCompositeException(OptionError,"MissingArgument",option);
896  if (IsGeometry(argv[i]) == MagickFalse)
897  ThrowCompositeInvalidArgumentException(option,argv[i]);
898  (void) CloneString(&composite_options.compose_args,argv[i]);
899  composite_options.compose=DissolveCompositeOp;
900  break;
901  }
902  if (LocaleCompare("distort",option+1) == 0)
903  {
904  (void) CloneString(&composite_options.compose_args,(char *) NULL);
905  if (*option == '+')
906  break;
907  i++;
908  if (i == (ssize_t) argc)
909  ThrowCompositeException(OptionError,"MissingArgument",option);
910  if (IsGeometry(argv[i]) == MagickFalse)
911  ThrowCompositeInvalidArgumentException(option,argv[i]);
912  (void) CloneString(&composite_options.compose_args,argv[i]);
913  composite_options.compose=DistortCompositeOp;
914  break;
915  }
916  if (LocaleCompare("dither",option+1) == 0)
917  {
918  ssize_t
919  method;
920 
921  if (*option == '+')
922  break;
923  i++;
924  if (i == (ssize_t) argc)
925  ThrowCompositeException(OptionError,"MissingArgument",option);
926  method=ParseCommandOption(MagickDitherOptions,MagickFalse,argv[i]);
927  if (method < 0)
928  ThrowCompositeException(OptionError,"UnrecognizedDitherMethod",
929  argv[i]);
930  break;
931  }
932  if (LocaleCompare("duration",option+1) == 0)
933  {
934  if (*option == '+')
935  break;
936  i++;
937  if (i == (ssize_t) argc)
938  ThrowCompositeException(OptionError,"MissingArgument",option);
939  if (IsGeometry(argv[i]) == MagickFalse)
940  ThrowCompositeInvalidArgumentException(option,argv[i]);
941  break;
942  }
943  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
944  }
945  case 'e':
946  {
947  if (LocaleCompare("encipher",option+1) == 0)
948  {
949  if (*option == '+')
950  break;
951  i++;
952  if (i == (ssize_t) argc)
953  ThrowCompositeException(OptionError,"MissingArgument",option);
954  break;
955  }
956  if (LocaleCompare("encoding",option+1) == 0)
957  {
958  if (*option == '+')
959  break;
960  i++;
961  if (i == (ssize_t) argc)
962  ThrowCompositeException(OptionError,"MissingArgument",option);
963  break;
964  }
965  if (LocaleCompare("endian",option+1) == 0)
966  {
967  ssize_t
968  endian;
969 
970  if (*option == '+')
971  break;
972  i++;
973  if (i == (ssize_t) argc)
974  ThrowCompositeException(OptionError,"MissingArgument",option);
975  endian=ParseCommandOption(MagickEndianOptions,MagickFalse,
976  argv[i]);
977  if (endian < 0)
978  ThrowCompositeException(OptionError,"UnrecognizedEndianType",
979  argv[i]);
980  break;
981  }
982  if (LocaleCompare("extract",option+1) == 0)
983  {
984  if (*option == '+')
985  break;
986  i++;
987  if (i == (ssize_t) argc)
988  ThrowCompositeException(OptionError,"MissingArgument",option);
989  if (IsGeometry(argv[i]) == MagickFalse)
990  ThrowCompositeInvalidArgumentException(option,argv[i]);
991  break;
992  }
993  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
994  }
995  case 'f':
996  {
997  if (LocaleCompare("filter",option+1) == 0)
998  {
999  ssize_t
1000  filter;
1001 
1002  if (*option == '+')
1003  break;
1004  i++;
1005  if (i == (ssize_t) argc)
1006  ThrowCompositeException(OptionError,"MissingArgument",option);
1007  filter=ParseCommandOption(MagickFilterOptions,MagickFalse,argv[i]);
1008  if (filter < 0)
1009  ThrowCompositeException(OptionError,"UnrecognizedImageFilter",
1010  argv[i]);
1011  break;
1012  }
1013  if (LocaleCompare("font",option+1) == 0)
1014  {
1015  if (*option == '+')
1016  break;
1017  i++;
1018  if (i == (ssize_t) argc)
1019  ThrowCompositeException(OptionError,"MissingArgument",option);
1020  break;
1021  }
1022  if (LocaleCompare("format",option+1) == 0)
1023  {
1024  if (*option == '+')
1025  break;
1026  i++;
1027  if (i == (ssize_t) argc)
1028  ThrowCompositeException(OptionError,"MissingArgument",option);
1029  format=argv[i];
1030  break;
1031  }
1032  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1033  }
1034  case 'g':
1035  {
1036  if (LocaleCompare("geometry",option+1) == 0)
1037  {
1038  (void) CloneString(&composite_options.geometry,(char *) NULL);
1039  if (*option == '+')
1040  break;
1041  i++;
1042  if (i == (ssize_t) argc)
1043  ThrowCompositeException(OptionError,"MissingArgument",option);
1044  if (IsGeometry(argv[i]) == MagickFalse)
1045  ThrowCompositeInvalidArgumentException(option,argv[i]);
1046  (void) CloneString(&composite_options.geometry,argv[i]);
1047  break;
1048  }
1049  if (LocaleCompare("gravity",option+1) == 0)
1050  {
1051  ssize_t
1052  gravity;
1053 
1054  composite_options.gravity=UndefinedGravity;
1055  if (*option == '+')
1056  break;
1057  i++;
1058  if (i == (ssize_t) argc)
1059  ThrowCompositeException(OptionError,"MissingArgument",option);
1060  gravity=ParseCommandOption(MagickGravityOptions,MagickFalse,
1061  argv[i]);
1062  if (gravity < 0)
1063  ThrowCompositeException(OptionError,"UnrecognizedGravityType",
1064  argv[i]);
1065  composite_options.gravity=(GravityType) gravity;
1066  break;
1067  }
1068  if (LocaleCompare("green-primary",option+1) == 0)
1069  {
1070  if (*option == '+')
1071  break;
1072  i++;
1073  if (i == (ssize_t) argc)
1074  ThrowCompositeException(OptionError,"MissingArgument",option);
1075  if (IsGeometry(argv[i]) == MagickFalse)
1076  ThrowCompositeInvalidArgumentException(option,argv[i]);
1077  break;
1078  }
1079  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1080  }
1081  case 'h':
1082  {
1083  if ((LocaleCompare("help",option+1) == 0) ||
1084  (LocaleCompare("-help",option+1) == 0))
1085  {
1086  DestroyComposite();
1087  return(CompositeUsage());
1088  }
1089  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1090  }
1091  case 'i':
1092  {
1093  if (LocaleCompare("identify",option+1) == 0)
1094  break;
1095  if (LocaleCompare("interlace",option+1) == 0)
1096  {
1097  ssize_t
1098  interlace;
1099 
1100  if (*option == '+')
1101  break;
1102  i++;
1103  if (i == (ssize_t) argc)
1104  ThrowCompositeException(OptionError,"MissingArgument",option);
1105  interlace=ParseCommandOption(MagickInterlaceOptions,MagickFalse,
1106  argv[i]);
1107  if (interlace < 0)
1108  ThrowCompositeException(OptionError,
1109  "UnrecognizedInterlaceType",argv[i]);
1110  break;
1111  }
1112  if (LocaleCompare("interpolate",option+1) == 0)
1113  {
1114  ssize_t
1115  interpolate;
1116 
1117  if (*option == '+')
1118  break;
1119  i++;
1120  if (i == (ssize_t) argc)
1121  ThrowCompositeException(OptionError,"MissingArgument",option);
1122  interpolate=ParseCommandOption(MagickInterpolateOptions,MagickFalse,
1123  argv[i]);
1124  if (interpolate < 0)
1125  ThrowCompositeException(OptionError,
1126  "UnrecognizedInterpolateMethod",argv[i]);
1127  break;
1128  }
1129  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1130  }
1131  case 'l':
1132  {
1133  if (LocaleCompare("label",option+1) == 0)
1134  {
1135  if (*option == '+')
1136  break;
1137  i++;
1138  if (i == (ssize_t) argc)
1139  ThrowCompositeException(OptionError,"MissingArgument",option);
1140  break;
1141  }
1142  if (LocaleCompare("limit",option+1) == 0)
1143  {
1144  char
1145  *p;
1146 
1147  double
1148  value;
1149 
1150  ssize_t
1151  resource;
1152 
1153  if (*option == '+')
1154  break;
1155  i++;
1156  if (i == (ssize_t) argc)
1157  ThrowCompositeException(OptionError,"MissingArgument",option);
1158  resource=ParseCommandOption(MagickResourceOptions,MagickFalse,
1159  argv[i]);
1160  if (resource < 0)
1161  ThrowCompositeException(OptionError,"UnrecognizedResourceType",
1162  argv[i]);
1163  i++;
1164  if (i == (ssize_t) argc)
1165  ThrowCompositeException(OptionError,"MissingArgument",option);
1166  value=StringToDouble(argv[i],&p);
1167  (void) value;
1168  if ((p == argv[i]) && (LocaleCompare("unlimited",argv[i]) != 0))
1169  ThrowCompositeInvalidArgumentException(option,argv[i]);
1170  break;
1171  }
1172  if (LocaleCompare("list",option+1) == 0)
1173  {
1174  ssize_t
1175  list;
1176 
1177  if (*option == '+')
1178  break;
1179  i++;
1180  if (i == (ssize_t) argc)
1181  ThrowCompositeException(OptionError,"MissingArgument",option);
1182  list=ParseCommandOption(MagickListOptions,MagickFalse,argv[i]);
1183  if (list < 0)
1184  ThrowCompositeException(OptionError,"UnrecognizedListType",
1185  argv[i]);
1186  status=MogrifyImageInfo(image_info,(int) (i-j+1),(const char **)
1187  argv+j,exception);
1188  DestroyComposite();
1189  return(status == 0 ? MagickFalse : MagickTrue);
1190  }
1191  if (LocaleCompare("log",option+1) == 0)
1192  {
1193  if (*option == '+')
1194  break;
1195  i++;
1196  if ((i == (ssize_t) argc) || (strchr(argv[i],'%') == (char *) NULL))
1197  ThrowCompositeException(OptionError,"MissingArgument",option);
1198  break;
1199  }
1200  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1201  }
1202  case 'm':
1203  {
1204  if (LocaleCompare("matte",option+1) == 0)
1205  break;
1206  if (LocaleCompare("monitor",option+1) == 0)
1207  break;
1208  if (LocaleCompare("monochrome",option+1) == 0)
1209  break;
1210  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1211  }
1212  case 'n':
1213  {
1214  if (LocaleCompare("negate",option+1) == 0)
1215  break;
1216  if (LocaleCompare("noop",option+1) == 0)
1217  break;
1218  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1219  }
1220  case 'p':
1221  {
1222  if (LocaleCompare("page",option+1) == 0)
1223  {
1224  if (*option == '+')
1225  break;
1226  i++;
1227  if (i == (ssize_t) argc)
1228  ThrowCompositeException(OptionError,"MissingArgument",option);
1229  break;
1230  }
1231  if (LocaleCompare("pointsize",option+1) == 0)
1232  {
1233  if (*option == '+')
1234  break;
1235  i++;
1236  if (i == (ssize_t) argc)
1237  ThrowCompositeException(OptionError,"MissingArgument",option);
1238  if (IsGeometry(argv[i]) == MagickFalse)
1239  ThrowCompositeInvalidArgumentException(option,argv[i]);
1240  break;
1241  }
1242  if (LocaleCompare("process",option+1) == 0)
1243  {
1244  if (*option == '+')
1245  break;
1246  i++;
1247  if (i == (ssize_t) argc)
1248  ThrowCompositeException(OptionError,"MissingArgument",option);
1249  break;
1250  }
1251  if (LocaleCompare("profile",option+1) == 0)
1252  {
1253  i++;
1254  if (i == (ssize_t) argc)
1255  ThrowCompositeException(OptionError,"MissingArgument",option);
1256  break;
1257  }
1258  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1259  }
1260  case 'q':
1261  {
1262  if (LocaleCompare("quality",option+1) == 0)
1263  {
1264  if (*option == '+')
1265  break;
1266  i++;
1267  if (i == (ssize_t) argc)
1268  ThrowCompositeException(OptionError,"MissingArgument",option);
1269  if (IsGeometry(argv[i]) == MagickFalse)
1270  ThrowCompositeInvalidArgumentException(option,argv[i]);
1271  break;
1272  }
1273  if (LocaleCompare("quantize",option+1) == 0)
1274  {
1275  ssize_t
1276  colorspace;
1277 
1278  if (*option == '+')
1279  break;
1280  i++;
1281  if (i == (ssize_t) argc)
1282  ThrowCompositeException(OptionError,"MissingArgument",option);
1283  colorspace=ParseCommandOption(MagickColorspaceOptions,
1284  MagickFalse,argv[i]);
1285  if (colorspace < 0)
1286  ThrowCompositeException(OptionError,"UnrecognizedColorspace",
1287  argv[i]);
1288  break;
1289  }
1290  if (LocaleCompare("quiet",option+1) == 0)
1291  break;
1292  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1293  }
1294  case 'r':
1295  {
1296  if (LocaleCompare("red-primary",option+1) == 0)
1297  {
1298  if (*option == '+')
1299  break;
1300  i++;
1301  if (i == (ssize_t) argc)
1302  ThrowCompositeException(OptionError,"MissingArgument",option);
1303  if (IsGeometry(argv[i]) == MagickFalse)
1304  ThrowCompositeInvalidArgumentException(option,argv[i]);
1305  break;
1306  }
1307  if (LocaleCompare("regard-warnings",option+1) == 0)
1308  break;
1309  if (LocaleCompare("render",option+1) == 0)
1310  break;
1311  if (LocaleCompare("repage",option+1) == 0)
1312  {
1313  if (*option == '+')
1314  break;
1315  i++;
1316  if (i == (ssize_t) argc)
1317  ThrowCompositeException(OptionError,"MissingArgument",option);
1318  if (IsGeometry(argv[i]) == MagickFalse)
1319  ThrowCompositeInvalidArgumentException(option,argv[i]);
1320  break;
1321  }
1322  if (LocaleNCompare("respect-parentheses",option+1,17) == 0)
1323  {
1324  respect_parentheses=(*option == '-') ? MagickTrue : MagickFalse;
1325  break;
1326  }
1327  if (LocaleCompare("resize",option+1) == 0)
1328  {
1329  if (*option == '+')
1330  break;
1331  i++;
1332  if (i == (ssize_t) argc)
1333  ThrowCompositeException(OptionError,"MissingArgument",option);
1334  if (IsGeometry(argv[i]) == MagickFalse)
1335  ThrowCompositeInvalidArgumentException(option,argv[i]);
1336  break;
1337  }
1338  if (LocaleCompare("rotate",option+1) == 0)
1339  {
1340  i++;
1341  if (i == (ssize_t) argc)
1342  ThrowCompositeException(OptionError,"MissingArgument",option);
1343  if (IsGeometry(argv[i]) == MagickFalse)
1344  ThrowCompositeInvalidArgumentException(option,argv[i]);
1345  break;
1346  }
1347  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1348  }
1349  case 's':
1350  {
1351  if (LocaleCompare("sampling-factor",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("scene",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("seed",option+1) == 0)
1374  {
1375  if (*option == '+')
1376  break;
1377  i++;
1378  if (i == (ssize_t) argc)
1379  ThrowCompositeException(OptionError,"MissingArgument",option);
1380  if (IsGeometry(argv[i]) == MagickFalse)
1381  ThrowCompositeInvalidArgumentException(option,argv[i]);
1382  break;
1383  }
1384  if (LocaleCompare("sharpen",option+1) == 0)
1385  {
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("shave",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("size",option+1) == 0)
1405  {
1406  if (*option == '+')
1407  break;
1408  i++;
1409  if (i == (ssize_t) argc)
1410  ThrowCompositeException(OptionError,"MissingArgument",option);
1411  if (IsGeometry(argv[i]) == MagickFalse)
1412  ThrowCompositeInvalidArgumentException(option,argv[i]);
1413  break;
1414  }
1415  if (LocaleCompare("stegano",option+1) == 0)
1416  {
1417  composite_options.stegano=0;
1418  if (*option == '+')
1419  break;
1420  i++;
1421  if (i == (ssize_t) argc)
1422  ThrowCompositeException(OptionError,"MissingArgument",option);
1423  if (IsGeometry(argv[i]) == MagickFalse)
1424  ThrowCompositeInvalidArgumentException(option,argv[i]);
1425  composite_options.stegano=(ssize_t) StringToLong(argv[i])+1;
1426  break;
1427  }
1428  if (LocaleCompare("stereo",option+1) == 0)
1429  {
1430  MagickStatusType
1431  flags;
1432 
1433  composite_options.stereo=MagickFalse;
1434  if (*option == '+')
1435  break;
1436  i++;
1437  if (i == (ssize_t) argc)
1438  ThrowCompositeException(OptionError,"MissingArgument",option);
1439  if (IsGeometry(argv[i]) == MagickFalse)
1440  ThrowCompositeInvalidArgumentException(option,argv[i]);
1441  flags=ParseAbsoluteGeometry(argv[i],&composite_options.offset);
1442  if ((flags & YValue) == 0)
1443  composite_options.offset.y=composite_options.offset.x;
1444  composite_options.stereo=MagickTrue;
1445  break;
1446  }
1447  if (LocaleCompare("strip",option+1) == 0)
1448  break;
1449  if (LocaleCompare("support",option+1) == 0)
1450  {
1451  i++; /* deprecated */
1452  break;
1453  }
1454  if (LocaleCompare("swap",option+1) == 0)
1455  {
1456  if (*option == '+')
1457  break;
1458  i++;
1459  if (i == (ssize_t) argc)
1460  ThrowCompositeException(OptionError,"MissingArgument",option);
1461  if (IsGeometry(argv[i]) == MagickFalse)
1462  ThrowCompositeInvalidArgumentException(option,argv[i]);
1463  break;
1464  }
1465  if (LocaleCompare("synchronize",option+1) == 0)
1466  break;
1467  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1468  }
1469  case 't':
1470  {
1471  if (LocaleCompare("taint",option+1) == 0)
1472  break;
1473  if (LocaleCompare("thumbnail",option+1) == 0)
1474  {
1475  if (*option == '+')
1476  break;
1477  i++;
1478  if (i == (ssize_t) argc)
1479  ThrowCompositeException(OptionError,"MissingArgument",option);
1480  if (IsGeometry(argv[i]) == MagickFalse)
1481  ThrowCompositeInvalidArgumentException(option,argv[i]);
1482  break;
1483  }
1484  if (LocaleCompare("tile",option+1) == 0)
1485  {
1486  composite_options.tile=(*option == '-') ? MagickTrue : MagickFalse;
1487  (void) CopyMagickString(argv[i]+1,"sans",MagickPathExtent);
1488  break;
1489  }
1490  if (LocaleCompare("transform",option+1) == 0)
1491  break;
1492  if (LocaleCompare("transparent-color",option+1) == 0)
1493  {
1494  if (*option == '+')
1495  break;
1496  i++;
1497  if (i == (ssize_t) argc)
1498  ThrowCompositeException(OptionError,"MissingArgument",option);
1499  break;
1500  }
1501  if (LocaleCompare("treedepth",option+1) == 0)
1502  {
1503  if (*option == '+')
1504  break;
1505  i++;
1506  if (i == (ssize_t) argc)
1507  ThrowCompositeException(OptionError,"MissingArgument",option);
1508  if (IsGeometry(argv[i]) == MagickFalse)
1509  ThrowCompositeInvalidArgumentException(option,argv[i]);
1510  break;
1511  }
1512  if (LocaleCompare("type",option+1) == 0)
1513  {
1514  ssize_t
1515  type;
1516 
1517  if (*option == '+')
1518  break;
1519  i++;
1520  if (i == (ssize_t) argc)
1521  ThrowCompositeException(OptionError,"MissingArgument",option);
1522  type=ParseCommandOption(MagickTypeOptions,MagickFalse,argv[i]);
1523  if (type < 0)
1524  ThrowCompositeException(OptionError,"UnrecognizedImageType",
1525  argv[i]);
1526  break;
1527  }
1528  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1529  }
1530  case 'u':
1531  {
1532  if (LocaleCompare("units",option+1) == 0)
1533  {
1534  ssize_t
1535  units;
1536 
1537  if (*option == '+')
1538  break;
1539  i++;
1540  if (i == (ssize_t) argc)
1541  ThrowCompositeException(OptionError,"MissingArgument",option);
1542  units=ParseCommandOption(MagickResolutionOptions,MagickFalse,
1543  argv[i]);
1544  if (units < 0)
1545  ThrowCompositeException(OptionError,"UnrecognizedUnitsType",
1546  argv[i]);
1547  break;
1548  }
1549  if (LocaleCompare("unsharp",option+1) == 0)
1550  {
1551  (void) CloneString(&composite_options.compose_args,(char *) NULL);
1552  if (*option == '+')
1553  break;
1554  i++;
1555  if (i == (ssize_t) argc)
1556  ThrowCompositeException(OptionError,"MissingArgument",option);
1557  if (IsGeometry(argv[i]) == MagickFalse)
1558  ThrowCompositeInvalidArgumentException(option,argv[i]);
1559  (void) CloneString(&composite_options.compose_args,argv[i]);
1560  composite_options.compose=ThresholdCompositeOp;
1561  break;
1562  }
1563  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1564  }
1565  case 'v':
1566  {
1567  if (LocaleCompare("verbose",option+1) == 0)
1568  break;
1569  if ((LocaleCompare("version",option+1) == 0) ||
1570  (LocaleCompare("-version",option+1) == 0))
1571  {
1572  ListMagickVersion(stdout);
1573  break;
1574  }
1575  if (LocaleCompare("virtual-pixel",option+1) == 0)
1576  {
1577  ssize_t
1578  method;
1579 
1580  if (*option == '+')
1581  break;
1582  i++;
1583  if (i == (ssize_t) argc)
1584  ThrowCompositeException(OptionError,"MissingArgument",option);
1585  method=ParseCommandOption(MagickVirtualPixelOptions,MagickFalse,
1586  argv[i]);
1587  if (method < 0)
1588  ThrowCompositeException(OptionError,
1589  "UnrecognizedVirtualPixelMethod",argv[i]);
1590  break;
1591  }
1592  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1593  }
1594  case 'w':
1595  {
1596  if (LocaleCompare("watermark",option+1) == 0)
1597  {
1598  (void) CloneString(&composite_options.compose_args,(char *) NULL);
1599  if (*option == '+')
1600  break;
1601  i++;
1602  if (i == (ssize_t) argc)
1603  ThrowCompositeException(OptionError,"MissingArgument",option);
1604  if (IsGeometry(argv[i]) == MagickFalse)
1605  ThrowCompositeInvalidArgumentException(option,argv[i]);
1606  (void) CloneString(&composite_options.compose_args,argv[i]);
1607  composite_options.compose=ModulateCompositeOp;
1608  break;
1609  }
1610  if (LocaleCompare("white-point",option+1) == 0)
1611  {
1612  if (*option == '+')
1613  break;
1614  i++;
1615  if (i == (ssize_t) argc)
1616  ThrowCompositeException(OptionError,"MissingArgument",option);
1617  if (IsGeometry(argv[i]) == MagickFalse)
1618  ThrowCompositeInvalidArgumentException(option,argv[i]);
1619  break;
1620  }
1621  if (LocaleCompare("write",option+1) == 0)
1622  {
1623  i++;
1624  if (i == (ssize_t) argc)
1625  ThrowCompositeException(OptionError,"MissingArgument",option);
1626  break;
1627  }
1628  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1629  }
1630  case '?':
1631  break;
1632  default:
1633  ThrowCompositeException(OptionError,"UnrecognizedOption",option)
1634  }
1635  fire=(GetCommandOptionFlags(MagickCommandOptions,MagickFalse,option) &
1636  FireOptionFlag) == 0 ? MagickFalse : MagickTrue;
1637  if (fire != MagickFalse)
1638  FireImageStack(MagickFalse,MagickTrue,MagickTrue);
1639  }
1640  if (k != 0)
1641  ThrowCompositeException(OptionError,"UnbalancedParenthesis",argv[i]);
1642  if (i-- != ((ssize_t) argc-1))
1643  ThrowCompositeException(OptionError,"MissingAnImageFilename",argv[i]);
1644  if ((image == (Image *) NULL) || (GetImageListLength(image) < 2))
1645  ThrowCompositeException(OptionError,"MissingAnImageFilename",argv[argc-1]);
1646  FinalizeImageSettings(image_info,image,MagickTrue);
1647  if ((image == (Image *) NULL) || (GetImageListLength(image) < 2))
1648  ThrowCompositeException(OptionError,"MissingAnImageFilename",argv[argc-1]);
1649  /*
1650  Composite images.
1651  */
1652  RemoveImageStack(composite_image);
1653  RemoveImageStack(images);
1654  if (composite_image->geometry != (char *) NULL)
1655  {
1656  RectangleInfo
1657  resize_geometry;
1658 
1659  (void) ParseRegionGeometry(composite_image,composite_image->geometry,
1660  &resize_geometry,exception);
1661  if ((composite_image->columns != resize_geometry.width) ||
1662  (composite_image->rows != resize_geometry.height))
1663  {
1664  Image
1665  *resize_image;
1666 
1667  resize_image=ResizeImage(composite_image,resize_geometry.width,
1668  resize_geometry.height,composite_image->filter,exception);
1669  if (resize_image != (Image *) NULL)
1670  {
1671  composite_image=DestroyImage(composite_image);
1672  composite_image=resize_image;
1673  }
1674  }
1675  }
1676  RemoveImageStack(mask_image);
1677  status&=(MagickStatusType) CompositeImageList(image_info,&images,
1678  composite_image,mask_image,&composite_options,exception);
1679  composite_image=DestroyImage(composite_image);
1680  /*
1681  Write composite images.
1682  */
1683  status&=(MagickStatusType) WriteImages(image_info,images,argv[argc-1],
1684  exception);
1685  if (metadata != (char **) NULL)
1686  {
1687  char
1688  *text;
1689 
1690  text=InterpretImageProperties(image_info,images,format,exception);
1691  if (text == (char *) NULL)
1692  ThrowCompositeException(ResourceLimitError,"MemoryAllocationFailed",
1693  (char *) NULL);
1694  (void) ConcatenateString(&(*metadata),text);
1695  text=DestroyString(text);
1696  }
1697  images=DestroyImageList(images);
1698  RelinquishCompositeOptions(&composite_options);
1699  DestroyComposite();
1700  return(status != 0 ? MagickTrue : MagickFalse);
1701 }