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