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