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