1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 % %
4 % %
5 % %
6 % M M OOO N N TTTTT AAA GGGG EEEEE %
7 % MM MM O O NN N T A A G E %
8 % M M M O O N N N T AAAAA G GG EEE %
9 % M M O O N NN T A A G G E %
10 % M M OOO N N T A A GGG EEEEE %
11 % %
12 % %
13 % MagickWand Methods to Create Image Thumbnails %
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 montage program to create a composite image by combining several
37 % separate images. The images are tiled on the composite image optionally
38 % adorned with a border, frame, image name, and more.
39 %
40 */
41
42 /*
43 Include declarations.
44 */
45 #include "MagickWand/studio.h"
46 #include "MagickWand/MagickWand.h"
47 #include "MagickWand/mogrify-private.h"
48 #include "MagickCore/string-private.h"
49
50 /*
51 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
52 % %
53 % %
54 % %
55 + M o n t a g e I m a g e C o m m a n d %
56 % %
57 % %
58 % %
59 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
60 %
61 % MontageImageCommand() reads one or more images, applies one or more image
62 % processing operations, and writes out the image in the same or
63 % differing format.
64 %
65 % The format of the MontageImageCommand method is:
66 %
67 % MagickBooleanType MontageImageCommand(ImageInfo *image_info,int argc,
68 % char **argv,char **metadata,ExceptionInfo *exception)
69 %
70 % A description of each parameter follows:
71 %
72 % o image_info: the image info.
73 %
74 % o argc: the number of elements in the argument vector.
75 %
76 % o argv: A text array containing the command line arguments.
77 %
78 % o metadata: any metadata is returned here.
79 %
80 % o exception: return any errors or warnings in this structure.
81 %
82 */
83
MontageUsage(void)84 static MagickBooleanType MontageUsage(void)
85 {
86 static const char
87 miscellaneous[] =
88 " -debug events display copious debugging information\n"
89 " -help print program options\n"
90 " -list type print a list of supported option arguments\n"
91 " -log format format of debugging information\n"
92 " -version print version information",
93 operators[] =
94 " -adaptive-sharpen geometry\n"
95 " adaptively sharpen pixels; increase effect near edges\n"
96 " -annotate geometry text\n"
97 " annotate the image with text\n"
98 " -auto-orient automagically orient image\n"
99 " -blur geometry reduce image noise and reduce detail levels\n"
100 " -border geometry surround image with a border of color\n"
101 " -channel mask set the image channel mask\n"
102 " -crop geometry preferred size and location of the cropped image\n"
103 " -distort method args\n"
104 " distort images according to given method and args\n"
105 " -extent geometry set the image size\n"
106 " -flatten flatten a sequence of images\n"
107 " -flip flip image in the vertical direction\n"
108 " -flop flop image in the horizontal direction\n"
109 " -frame geometry surround image with an ornamental border\n"
110 " -layers method optimize, merge, or compare image layers\n"
111 " -monochrome transform image to black and white\n"
112 " -polaroid angle simulate a Polaroid picture\n"
113 " -repage geometry size and location of an image canvas (operator)\n"
114 " -resize geometry resize the image\n"
115 " -rotate degrees apply Paeth rotation to the image\n"
116 " -scale geometry scale the image\n"
117 " -strip strip image of all profiles and comments\n"
118 " -transform affine transform image\n"
119 " -transpose flip image vertically and rotate 90 degrees\n"
120 " -transparent color make this color transparent within the image\n"
121 " -type type image type\n"
122 " -unsharp geometry sharpen the image",
123 settings[] =
124 " -adjoin join images into a single multi-image file\n"
125 " -affine matrix affine transform matrix\n"
126 " -alpha option on, activate, off, deactivate, set, opaque, copy\n"
127 " transparent, extract, background, or shape\n"
128 " -authenticate password\n"
129 " decipher image with this password\n"
130 " -blue-primary point chromaticity blue primary point\n"
131 " -bordercolor color border color\n"
132 " -caption string assign a caption to an image\n"
133 " -colors value preferred number of colors in the image\n"
134 " -colorspace type alternate image colorsapce\n"
135 " -comment string annotate image with comment\n"
136 " -compose operator composite operator\n"
137 " -compress type type of pixel compression when writing the image\n"
138 " -define format:option\n"
139 " define one or more image format options\n"
140 " -delay value display the next image after pausing\n"
141 " -density geometry horizontal and vertical density of the image\n"
142 " -depth value image depth\n"
143 " -display server query font from this X server\n"
144 " -dispose method layer disposal method\n"
145 " -dither method apply error diffusion to image\n"
146 " -draw string annotate the image with a graphic primitive\n"
147 " -encoding type text encoding type\n"
148 " -endian type endianness (MSB or LSB) of the image\n"
149 " -extract geometry extract area from image\n"
150 " -fill color color to use when filling a graphic primitive\n"
151 " -filter type use this filter when resizing an image\n"
152 " -font name render text with this font\n"
153 " -format \"string\" output formatted image characteristics\n"
154 " -gamma value level of gamma correction\n"
155 " -geometry geometry preferred tile and border sizes\n"
156 " -gravity direction which direction to gravitate towards\n"
157 " -green-primary point chromaticity green primary point\n"
158 " -identify identify the format and characteristics of the image\n"
159 " -interlace type type of image interlacing scheme\n"
160 " -interpolate method pixel color interpolation method\n"
161 " -kerning value set the space between two letters\n"
162 " -label string assign a label to an image\n"
163 " -limit type value pixel cache resource limit\n"
164 " -matte store matte channel if the image has one\n"
165 " -mattecolor color frame color\n"
166 " -mode type framing style\n"
167 " -monitor monitor progress\n"
168 " -page geometry size and location of an image canvas (setting)\n"
169 " -pointsize value font point size\n"
170 " -profile filename add, delete, or apply an image profile\n"
171 " -quality value JPEG/MIFF/PNG compression level\n"
172 " -quantize colorspace reduce colors in this colorspace\n"
173 " -quiet suppress all warning messages\n"
174 " -red-primary point chromaticity red primary point\n"
175 " -regard-warnings pay attention to warning messages\n"
176 " -respect-parentheses settings remain in effect until parenthesis boundary\n"
177 " -sampling-factor geometry\n"
178 " horizontal and vertical sampling factor\n"
179 " -scenes range image scene range\n"
180 " -seed value seed a new sequence of pseudo-random numbers\n"
181 " -set attribute value set an image attribute\n"
182 " -shadow add a shadow beneath a tile to simulate depth\n"
183 " -size geometry width and height of image\n"
184 " -stroke color color to use when stroking a graphic primitive\n"
185 " -support factor resize support: > 1.0 is blurry, < 1.0 is sharp\n"
186 " -synchronize synchronize image to storage device\n"
187 " -taint declare the image as modified\n"
188 " -texture filename name of texture to tile onto the image background\n"
189 " -thumbnail geometry create a thumbnail of the image\n"
190 " -tile geometry number of tiles per row and column\n"
191 " -title string decorate the montage image with a title\n"
192 " -transparent-color color\n"
193 " transparent color\n"
194 " -treedepth value color tree depth\n"
195 " -trim trim image edges\n"
196 " -units type the units of image resolution\n"
197 " -verbose print detailed information about the image\n"
198 " -virtual-pixel method\n"
199 " virtual pixel access method\n"
200 " -white-point point chromaticity white point",
201 sequence_operators[] =
202 " -coalesce merge a sequence of images\n"
203 " -composite composite image",
204 stack_operators[] =
205 " -clone indexes clone an image\n"
206 " -delete indexes delete the image from the image sequence\n"
207 " -duplicate count,indexes\n"
208 " duplicate an image one or more times\n"
209 " -insert index insert last image into the image sequence\n"
210 " -reverse reverse image sequence\n"
211 " -swap indexes swap two images in the image sequence";
212
213 ListMagickVersion(stdout);
214 (void) printf("Usage: %s [options ...] file [ [options ...] file ...] file\n",
215 GetClientName());
216 (void) printf("\nImage Settings:\n");
217 (void) puts(settings);
218 (void) printf("\nImage Operators:\n");
219 (void) puts(operators);
220 (void) printf("\nImage Sequence Operators:\n");
221 (void) puts(sequence_operators);
222 (void) printf("\nImage Stack Operators:\n");
223 (void) puts(stack_operators);
224 (void) printf("\nMiscellaneous Options:\n");
225 (void) puts(miscellaneous);
226 (void) printf(
227 "\nIn addition to those listed above, you can specify these standard X\n");
228 (void) printf(
229 "resources as command line options: -background, -bordercolor,\n");
230 (void) printf(
231 "-mattecolor, -borderwidth, -font, or -title\n");
232 (void) printf(
233 "\nBy default, the image format of 'file' is determined by its magic\n");
234 (void) printf(
235 "number. To specify a particular image format, precede the filename\n");
236 (void) printf(
237 "with an image format name and a colon (i.e. ps:image) or specify the\n");
238 (void) printf(
239 "image type as the filename suffix (i.e. image.ps). Specify 'file' as\n");
240 (void) printf("'-' for standard input or output.\n");
241 return(MagickTrue);
242 }
243
MontageImageCommand(ImageInfo * image_info,int argc,char ** argv,char ** metadata,ExceptionInfo * exception)244 WandExport MagickBooleanType MontageImageCommand(ImageInfo *image_info,
245 int argc,char **argv,char **metadata,ExceptionInfo *exception)
246 {
247 #define DestroyMontage() \
248 { \
249 if (montage_image != (Image *) NULL) \
250 montage_image=DestroyImageList(montage_image); \
251 if (montage_info != (MontageInfo *) NULL) \
252 montage_info=DestroyMontageInfo(montage_info); \
253 DestroyImageStack(); \
254 for (i=0; i < (ssize_t) argc; i++) \
255 argv[i]=DestroyString(argv[i]); \
256 argv=(char **) RelinquishMagickMemory(argv); \
257 }
258 #define ThrowMontageException(asperity,tag,option) \
259 { \
260 (void) ThrowMagickException(exception,GetMagickModule(),asperity,tag,"`%s'", \
261 option); \
262 DestroyMontage(); \
263 return(MagickFalse); \
264 }
265 #define ThrowMontageInvalidArgumentException(option,argument) \
266 { \
267 (void) ThrowMagickException(exception,GetMagickModule(),OptionError, \
268 "InvalidArgument","'%s': %s",option,argument); \
269 DestroyMontage(); \
270 return(MagickFalse); \
271 }
272
273 char
274 *option,
275 *transparent_color;
276
277 const char
278 *format;
279
280 Image
281 *image,
282 *montage_image;
283
284 ImageStack
285 image_stack[MaxImageStackDepth+1];
286
287 long
288 first_scene,
289 last_scene;
290
291 MagickBooleanType
292 fire,
293 pend,
294 respect_parenthesis;
295
296 MagickStatusType
297 status;
298
299 MontageInfo
300 *montage_info;
301
302 ssize_t
303 i;
304
305 ssize_t
306 j,
307 k,
308 scene;
309
310 /*
311 Set defaults.
312 */
313 assert(image_info != (ImageInfo *) NULL);
314 assert(image_info->signature == MagickCoreSignature);
315 if (image_info->debug != MagickFalse)
316 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
317 assert(exception != (ExceptionInfo *) NULL);
318 if (argc == 2)
319 {
320 option=argv[1];
321 if ((LocaleCompare("version",option+1) == 0) ||
322 (LocaleCompare("-version",option+1) == 0))
323 {
324 ListMagickVersion(stdout);
325 return(MagickTrue);
326 }
327 }
328 if (argc < 3)
329 return(MontageUsage());
330 format="%w,%h,%m";
331 first_scene=0;
332 j=1;
333 k=0;
334 last_scene=0;
335 montage_image=NewImageList();
336 montage_info=CloneMontageInfo(image_info,(MontageInfo *) NULL);
337 NewImageStack();
338 option=(char *) NULL;
339 pend=MagickFalse;
340 respect_parenthesis=MagickFalse;
341 scene=0;
342 status=MagickFalse;
343 transparent_color=(char *) NULL;
344 /*
345 Parse command line.
346 */
347 ReadCommandlLine(argc,&argv);
348 status=ExpandFilenames(&argc,&argv);
349 if (status == MagickFalse)
350 ThrowMontageException(ResourceLimitError,"MemoryAllocationFailed",
351 GetExceptionMessage(errno));
352 for (i=1; i < (ssize_t) (argc-1); i++)
353 {
354 option=argv[i];
355 if (LocaleCompare(option,"(") == 0)
356 {
357 FireImageStack(MagickTrue,MagickTrue,pend);
358 if (k == MaxImageStackDepth)
359 ThrowMontageException(OptionError,"ParenthesisNestedTooDeeply",
360 option);
361 PushImageStack();
362 continue;
363 }
364 if (LocaleCompare(option,")") == 0)
365 {
366 FireImageStack(MagickTrue,MagickTrue,MagickTrue);
367 if (k == 0)
368 ThrowMontageException(OptionError,"UnableToParseExpression",option);
369 PopImageStack();
370 continue;
371 }
372 if (IsCommandOption(option) == MagickFalse)
373 {
374 Image
375 *images;
376
377 FireImageStack(MagickFalse,MagickFalse,pend);
378 for (scene=(ssize_t) first_scene; scene <= (ssize_t) last_scene ; scene++)
379 {
380 char
381 *filename;
382
383 /*
384 Option is a file name: begin by reading image from specified file.
385 */
386 filename=argv[i];
387 if ((LocaleCompare(filename,"--") == 0) && (i < (ssize_t) (argc-1)))
388 filename=argv[++i];
389 (void) CloneString(&image_info->font,montage_info->font);
390 if (first_scene == last_scene)
391 images=ReadImages(image_info,filename,exception);
392 else
393 {
394 char
395 scene_filename[MagickPathExtent];
396
397 /*
398 Form filename for multi-part images.
399 */
400 (void) InterpretImageFilename(image_info,(Image *) NULL,
401 image_info->filename,(int) scene,scene_filename,exception);
402 if (LocaleCompare(filename,image_info->filename) == 0)
403 (void) FormatLocaleString(scene_filename,MagickPathExtent,
404 "%s.%.20g",image_info->filename,(double) scene);
405 images=ReadImages(image_info,scene_filename,exception);
406 }
407 status&=(images != (Image *) NULL) &&
408 (exception->severity < ErrorException);
409 if (images == (Image *) NULL)
410 continue;
411 AppendImageStack(images);
412 }
413 continue;
414 }
415 pend=image != (Image *) NULL ? MagickTrue : MagickFalse;
416 switch (*(option+1))
417 {
418 case 'a':
419 {
420 if (LocaleCompare("adaptive-sharpen",option+1) == 0)
421 {
422 i++;
423 if (i == (ssize_t) argc)
424 ThrowMontageException(OptionError,"MissingArgument",option);
425 if (IsGeometry(argv[i]) == MagickFalse)
426 ThrowMontageInvalidArgumentException(option,argv[i]);
427 break;
428 }
429 if (LocaleCompare("adjoin",option+1) == 0)
430 break;
431 if (LocaleCompare("affine",option+1) == 0)
432 {
433 if (*option == '+')
434 break;
435 i++;
436 if (i == (ssize_t) argc)
437 ThrowMontageException(OptionError,"MissingArgument",option);
438 if (IsGeometry(argv[i]) == MagickFalse)
439 ThrowMontageInvalidArgumentException(option,argv[i]);
440 break;
441 }
442 if (LocaleCompare("alpha",option+1) == 0)
443 {
444 ssize_t
445 type;
446
447 if (*option == '+')
448 break;
449 i++;
450 if (i == (ssize_t) argc)
451 ThrowMontageException(OptionError,"MissingArgument",option);
452 type=ParseCommandOption(MagickAlphaChannelOptions,MagickFalse,
453 argv[i]);
454 if (type < 0)
455 ThrowMontageException(OptionError,
456 "UnrecognizedAlphaChannelOption",argv[i]);
457 break;
458 }
459 if (LocaleCompare("annotate",option+1) == 0)
460 {
461 if (*option == '+')
462 break;
463 i++;
464 if (i == (ssize_t) argc)
465 ThrowMontageException(OptionError,"MissingArgument",option);
466 if (IsGeometry(argv[i]) == MagickFalse)
467 ThrowMontageInvalidArgumentException(option,argv[i]);
468 if (i == (ssize_t) argc)
469 ThrowMontageException(OptionError,"MissingArgument",option);
470 i++;
471 break;
472 }
473 if (LocaleCompare("auto-orient",option+1) == 0)
474 break;
475 if (LocaleCompare("authenticate",option+1) == 0)
476 {
477 if (*option == '+')
478 break;
479 i++;
480 if (i == (ssize_t) argc)
481 ThrowMontageException(OptionError,"MissingArgument",option);
482 break;
483 }
484 ThrowMontageException(OptionError,"UnrecognizedOption",option)
485 }
486 case 'b':
487 {
488 if (LocaleCompare("background",option+1) == 0)
489 {
490 if (*option == '+')
491 break;
492 i++;
493 if (i == (ssize_t) argc)
494 ThrowMontageException(OptionError,"MissingArgument",option);
495 (void) QueryColorCompliance(argv[i],AllCompliance,
496 &montage_info->background_color,exception);
497 break;
498 }
499 if (LocaleCompare("blue-primary",option+1) == 0)
500 {
501 if (*option == '+')
502 break;
503 i++;
504 if (i == (ssize_t) argc)
505 ThrowMontageException(OptionError,"MissingArgument",option);
506 if (IsGeometry(argv[i]) == MagickFalse)
507 ThrowMontageInvalidArgumentException(option,argv[i]);
508 break;
509 }
510 if (LocaleCompare("blur",option+1) == 0)
511 {
512 if (*option == '+')
513 break;
514 i++;
515 if (i == (ssize_t) argc)
516 ThrowMontageException(OptionError,"MissingArgument",option);
517 if (IsGeometry(argv[i]) == MagickFalse)
518 ThrowMontageInvalidArgumentException(option,argv[i]);
519 break;
520 }
521 if (LocaleCompare("border",option+1) == 0)
522 {
523 if (k == 0)
524 {
525 (void) CopyMagickString(argv[i]+1,"sans",MagickPathExtent);
526 montage_info->border_width=0;
527 }
528 if (*option == '+')
529 break;
530 i++;
531 if (i == (ssize_t) argc)
532 ThrowMontageException(OptionError,"MissingArgument",option);
533 if (IsGeometry(argv[i]) == MagickFalse)
534 ThrowMontageInvalidArgumentException(option,argv[i]);
535 if (k == 0)
536 montage_info->border_width=StringToUnsignedLong(argv[i]);
537 break;
538 }
539 if (LocaleCompare("bordercolor",option+1) == 0)
540 {
541 if (*option == '+')
542 break;
543 i++;
544 if (i == (ssize_t) argc)
545 ThrowMontageException(OptionError,"MissingArgument",option);
546 (void) QueryColorCompliance(argv[i],AllCompliance,
547 &montage_info->border_color,exception);
548 break;
549 }
550 if (LocaleCompare("borderwidth",option+1) == 0)
551 {
552 montage_info->border_width=0;
553 if (*option == '+')
554 break;
555 i++;
556 if (i == (ssize_t) argc)
557 ThrowMontageException(OptionError,"MissingArgument",option);
558 if (IsGeometry(argv[i]) == MagickFalse)
559 ThrowMontageInvalidArgumentException(option,argv[i]);
560 montage_info->border_width=StringToUnsignedLong(argv[i]);
561 break;
562 }
563 ThrowMontageException(OptionError,"UnrecognizedOption",option)
564 }
565 case 'c':
566 {
567 if (LocaleCompare("cache",option+1) == 0)
568 {
569 if (*option == '+')
570 break;
571 i++;
572 if (i == (ssize_t) argc)
573 ThrowMontageException(OptionError,"MissingArgument",option);
574 if (IsGeometry(argv[i]) == MagickFalse)
575 ThrowMontageInvalidArgumentException(option,argv[i]);
576 break;
577 }
578 if (LocaleCompare("caption",option+1) == 0)
579 {
580 if (*option == '+')
581 break;
582 i++;
583 if (i == (ssize_t) argc)
584 ThrowMontageException(OptionError,"MissingArgument",option);
585 break;
586 }
587 if (LocaleCompare("channel",option+1) == 0)
588 {
589 ssize_t
590 channel;
591
592 if (*option == '+')
593 break;
594 i++;
595 if (i == (ssize_t) argc)
596 ThrowMontageException(OptionError,"MissingArgument",option);
597 channel=ParseChannelOption(argv[i]);
598 if (channel < 0)
599 ThrowMontageException(OptionError,"UnrecognizedChannelType",
600 argv[i]);
601 break;
602 }
603 if (LocaleCompare("clone",option+1) == 0)
604 {
605 Image
606 *clone_images,
607 *clone_list;
608
609 clone_list=CloneImageList(image,exception);
610 if (k != 0)
611 clone_list=CloneImageList(image_stack[k-1].image,exception);
612 if (clone_list == (Image *) NULL)
613 ThrowMontageException(ImageError,"ImageSequenceRequired",option);
614 FireImageStack(MagickTrue,MagickTrue,MagickTrue);
615 if (*option == '+')
616 clone_images=CloneImages(clone_list,"-1",exception);
617 else
618 {
619 i++;
620 if (i == (ssize_t) argc)
621 ThrowMontageException(OptionError,"MissingArgument",option);
622 if (IsSceneGeometry(argv[i],MagickFalse) == MagickFalse)
623 ThrowMontageInvalidArgumentException(option,argv[i]);
624 clone_images=CloneImages(clone_list,argv[i],exception);
625 }
626 if (clone_images == (Image *) NULL)
627 ThrowMontageException(OptionError,"NoSuchImage",option);
628 AppendImageStack(clone_images);
629 clone_list=DestroyImageList(clone_list);
630 break;
631 }
632 if (LocaleCompare("coalesce",option+1) == 0)
633 break;
634 if (LocaleCompare("colors",option+1) == 0)
635 {
636 if (*option == '+')
637 break;
638 i++;
639 if (i == (ssize_t) argc)
640 ThrowMontageException(OptionError,"MissingArgument",option);
641 if (IsGeometry(argv[i]) == MagickFalse)
642 ThrowMontageInvalidArgumentException(option,argv[i]);
643 break;
644 }
645 if (LocaleCompare("colorspace",option+1) == 0)
646 {
647 ssize_t
648 colorspace;
649
650 if (*option == '+')
651 break;
652 i++;
653 if (i == (ssize_t) argc)
654 ThrowMontageException(OptionError,"MissingArgument",option);
655 colorspace=ParseCommandOption(MagickColorspaceOptions,
656 MagickFalse,argv[i]);
657 if (colorspace < 0)
658 ThrowMontageException(OptionError,"UnrecognizedColorspace",
659 argv[i]);
660 break;
661 }
662 if (LocaleCompare("comment",option+1) == 0)
663 {
664 if (*option == '+')
665 break;
666 i++;
667 if (i == (ssize_t) argc)
668 ThrowMontageException(OptionError,"MissingArgument",option);
669 break;
670 }
671 if (LocaleCompare("compose",option+1) == 0)
672 {
673 ssize_t
674 compose;
675
676 if (*option == '+')
677 break;
678 i++;
679 if (i == (ssize_t) argc)
680 ThrowMontageException(OptionError,"MissingArgument",option);
681 compose=ParseCommandOption(MagickComposeOptions,MagickFalse,argv[i]);
682 if (compose < 0)
683 ThrowMontageException(OptionError,"UnrecognizedComposeOperator",
684 argv[i]);
685 break;
686 }
687 if (LocaleCompare("composite",option+1) == 0)
688 break;
689 if (LocaleCompare("compress",option+1) == 0)
690 {
691 ssize_t
692 compress;
693
694 if (*option == '+')
695 break;
696 i++;
697 if (i == (ssize_t) argc)
698 ThrowMontageException(OptionError,"MissingArgument",option);
699 compress=ParseCommandOption(MagickCompressOptions,MagickFalse,
700 argv[i]);
701 if (compress < 0)
702 ThrowMontageException(OptionError,"UnrecognizedCompressType",
703 argv[i]);
704 break;
705 }
706 if (LocaleCompare("concurrent",option+1) == 0)
707 break;
708 if (LocaleCompare("crop",option+1) == 0)
709 {
710 if (*option == '+')
711 break;
712 i++;
713 if (i == (ssize_t) argc)
714 ThrowMontageException(OptionError,"MissingArgument",option);
715 if (IsGeometry(argv[i]) == MagickFalse)
716 ThrowMontageInvalidArgumentException(option,argv[i]);
717 break;
718 }
719 ThrowMontageException(OptionError,"UnrecognizedOption",option)
720 }
721 case 'd':
722 {
723 if (LocaleCompare("debug",option+1) == 0)
724 {
725 ssize_t
726 event;
727
728 if (*option == '+')
729 break;
730 i++;
731 if (i == (ssize_t) argc)
732 ThrowMontageException(OptionError,"MissingArgument",option);
733 event=ParseCommandOption(MagickLogEventOptions,MagickFalse,argv[i]);
734 if (event < 0)
735 ThrowMontageException(OptionError,"UnrecognizedEventType",
736 argv[i]);
737 (void) SetLogEventMask(argv[i]);
738 break;
739 }
740 if (LocaleCompare("define",option+1) == 0)
741 {
742 i++;
743 if (i == (ssize_t) argc)
744 ThrowMontageException(OptionError,"MissingArgument",option);
745 if (*option == '+')
746 {
747 const char
748 *define;
749
750 define=GetImageOption(image_info,argv[i]);
751 if (define == (const char *) NULL)
752 ThrowMontageException(OptionError,"NoSuchOption",argv[i]);
753 break;
754 }
755 break;
756 }
757 if (LocaleCompare("delay",option+1) == 0)
758 {
759 if (*option == '+')
760 break;
761 i++;
762 if (i == (ssize_t) argc)
763 ThrowMontageException(OptionError,"MissingArgument",option);
764 if (IsGeometry(argv[i]) == MagickFalse)
765 ThrowMontageInvalidArgumentException(option,argv[i]);
766 break;
767 }
768 if (LocaleCompare("delete",option+1) == 0)
769 {
770 if (*option == '+')
771 break;
772 i++;
773 if (i == (ssize_t) argc)
774 ThrowMontageException(OptionError,"MissingArgument",option);
775 if (IsSceneGeometry(argv[i],MagickFalse) == MagickFalse)
776 ThrowMontageInvalidArgumentException(option,argv[i]);
777 break;
778 }
779 if (LocaleCompare("density",option+1) == 0)
780 {
781 if (*option == '+')
782 break;
783 i++;
784 if (i == (ssize_t) argc)
785 ThrowMontageException(OptionError,"MissingArgument",option);
786 if (IsGeometry(argv[i]) == MagickFalse)
787 ThrowMontageInvalidArgumentException(option,argv[i]);
788 break;
789 }
790 if (LocaleCompare("depth",option+1) == 0)
791 {
792 if (*option == '+')
793 break;
794 i++;
795 if (i == (ssize_t) argc)
796 ThrowMontageException(OptionError,"MissingArgument",option);
797 if (IsGeometry(argv[i]) == MagickFalse)
798 ThrowMontageInvalidArgumentException(option,argv[i]);
799 break;
800 }
801 if (LocaleCompare("display",option+1) == 0)
802 {
803 if (*option == '+')
804 break;
805 i++;
806 if (i == (ssize_t) argc)
807 ThrowMontageException(OptionError,"MissingArgument",option);
808 break;
809 }
810 if (LocaleCompare("dispose",option+1) == 0)
811 {
812 ssize_t
813 dispose;
814
815 if (*option == '+')
816 break;
817 i++;
818 if (i == (ssize_t) argc)
819 ThrowMontageException(OptionError,"MissingArgument",option);
820 dispose=ParseCommandOption(MagickDisposeOptions,MagickFalse,
821 argv[i]);
822 if (dispose < 0)
823 ThrowMontageException(OptionError,"UnrecognizedDisposeMethod",
824 argv[i]);
825 break;
826 }
827 if (LocaleCompare("distort",option+1) == 0)
828 {
829 ssize_t
830 op;
831
832 i++;
833 if (i == (ssize_t) argc)
834 ThrowMontageException(OptionError,"MissingArgument",option);
835 op=ParseCommandOption(MagickDistortOptions,MagickFalse,argv[i]);
836 if (op < 0)
837 ThrowMontageException(OptionError,"UnrecognizedDistortMethod",
838 argv[i]);
839 i++;
840 if (i == (ssize_t) argc)
841 ThrowMontageException(OptionError,"MissingArgument",option);
842 break;
843 }
844 if (LocaleCompare("dither",option+1) == 0)
845 {
846 ssize_t
847 method;
848
849 if (*option == '+')
850 break;
851 i++;
852 if (i == (ssize_t) argc)
853 ThrowMontageException(OptionError,"MissingArgument",option);
854 method=ParseCommandOption(MagickDitherOptions,MagickFalse,argv[i]);
855 if (method < 0)
856 ThrowMontageException(OptionError,"UnrecognizedDitherMethod",
857 argv[i]);
858 break;
859 }
860 if (LocaleCompare("draw",option+1) == 0)
861 {
862 if (*option == '+')
863 break;
864 i++;
865 if (i == (ssize_t) argc)
866 ThrowMontageException(OptionError,"MissingArgument",option);
867 break;
868 }
869 if (LocaleCompare("duplicate",option+1) == 0)
870 {
871 if (*option == '+')
872 break;
873 i++;
874 if (i == (ssize_t) argc)
875 ThrowMontageException(OptionError,"MissingArgument",option);
876 if (IsGeometry(argv[i]) == MagickFalse)
877 ThrowMontageInvalidArgumentException(option,argv[i]);
878 break;
879 }
880 if (LocaleCompare("duration",option+1) == 0)
881 {
882 if (*option == '+')
883 break;
884 i++;
885 if (i == (ssize_t) argc)
886 ThrowMontageException(OptionError,"MissingArgument",option);
887 if (IsGeometry(argv[i]) == MagickFalse)
888 ThrowMontageInvalidArgumentException(option,argv[i]);
889 break;
890 }
891 ThrowMontageException(OptionError,"UnrecognizedOption",option)
892 }
893 case 'e':
894 {
895 if (LocaleCompare("encoding",option+1) == 0)
896 {
897 if (*option == '+')
898 break;
899 i++;
900 if (i == (ssize_t) argc)
901 ThrowMontageException(OptionError,"MissingArgument",option);
902 break;
903 }
904 if (LocaleCompare("endian",option+1) == 0)
905 {
906 ssize_t
907 endian;
908
909 if (*option == '+')
910 break;
911 i++;
912 if (i == (ssize_t) argc)
913 ThrowMontageException(OptionError,"MissingArgument",option);
914 endian=ParseCommandOption(MagickEndianOptions,MagickFalse,
915 argv[i]);
916 if (endian < 0)
917 ThrowMontageException(OptionError,"UnrecognizedEndianType",
918 argv[i]);
919 break;
920 }
921 if (LocaleCompare("extent",option+1) == 0)
922 {
923 if (*option == '+')
924 break;
925 i++;
926 if (i == (ssize_t) argc)
927 ThrowMontageException(OptionError,"MissingArgument",option);
928 if (IsGeometry(argv[i]) == MagickFalse)
929 ThrowMontageInvalidArgumentException(option,argv[i]);
930 break;
931 }
932 ThrowMontageException(OptionError,"UnrecognizedOption",option)
933 }
934 case 'f':
935 {
936 if (LocaleCompare("fill",option+1) == 0)
937 {
938 (void) QueryColorCompliance("none",AllCompliance,
939 &montage_info->fill,exception);
940 if (*option == '+')
941 break;
942 i++;
943 if (i == (ssize_t) argc)
944 ThrowMontageException(OptionError,"MissingArgument",option);
945 (void) QueryColorCompliance(argv[i],AllCompliance,
946 &montage_info->fill,exception);
947 break;
948 }
949 if (LocaleCompare("filter",option+1) == 0)
950 {
951 ssize_t
952 filter;
953
954 if (*option == '+')
955 break;
956 i++;
957 if (i == (ssize_t) argc)
958 ThrowMontageException(OptionError,"MissingArgument",option);
959 filter=ParseCommandOption(MagickFilterOptions,MagickFalse,argv[i]);
960 if (filter < 0)
961 ThrowMontageException(OptionError,"UnrecognizedImageFilter",
962 argv[i]);
963 break;
964 }
965 if (LocaleCompare("flatten",option+1) == 0)
966 break;
967 if (LocaleCompare("flip",option+1) == 0)
968 break;
969 if (LocaleCompare("flop",option+1) == 0)
970 break;
971 if (LocaleCompare("font",option+1) == 0)
972 {
973 if (*option == '+')
974 break;
975 i++;
976 if (i == (ssize_t) argc)
977 ThrowMontageException(OptionError,"MissingArgument",option);
978 (void) CloneString(&montage_info->font,argv[i]);
979 break;
980 }
981 if (LocaleCompare("format",option+1) == 0)
982 {
983 if (*option == '+')
984 break;
985 i++;
986 if (i == (ssize_t) argc)
987 ThrowMontageException(OptionError,"MissingArgument",option);
988 format=argv[i];
989 break;
990 }
991 if (LocaleCompare("frame",option+1) == 0)
992 {
993 if (k == 0)
994 {
995 (void) CopyMagickString(argv[i]+1,"sans",MagickPathExtent);
996 (void) CloneString(&montage_info->frame,(char *) NULL);
997 }
998 if (*option == '+')
999 break;
1000 i++;
1001 if (i == (ssize_t) argc)
1002 ThrowMontageException(OptionError,"MissingArgument",option);
1003 if (IsGeometry(argv[i]) == MagickFalse)
1004 ThrowMontageInvalidArgumentException(option,argv[i]);
1005 if (k == 0)
1006 (void) CloneString(&montage_info->frame,argv[i]);
1007 break;
1008 }
1009 ThrowMontageException(OptionError,"UnrecognizedOption",option)
1010 }
1011 case 'g':
1012 {
1013 if (LocaleCompare("gamma",option+1) == 0)
1014 {
1015 i++;
1016 if (i == (ssize_t) argc)
1017 ThrowMontageException(OptionError,"MissingArgument",option);
1018 if (IsGeometry(argv[i]) == MagickFalse)
1019 ThrowMontageInvalidArgumentException(option,argv[i]);
1020 break;
1021 }
1022 if (LocaleCompare("geometry",option+1) == 0)
1023 {
1024 (void) CloneString(&montage_info->geometry,(char *) NULL);
1025 if (*option == '+')
1026 break;
1027 i++;
1028 if (i == (ssize_t) argc)
1029 ThrowMontageException(OptionError,"MissingArgument",option);
1030 if (IsGeometry(argv[i]) == MagickFalse)
1031 ThrowMontageInvalidArgumentException(option,argv[i]);
1032 (void) CloneString(&montage_info->geometry,argv[i]);
1033 break;
1034 }
1035 if (LocaleCompare("gravity",option+1) == 0)
1036 {
1037 ssize_t
1038 gravity;
1039
1040 montage_info->gravity=UndefinedGravity;
1041 if (*option == '+')
1042 break;
1043 i++;
1044 if (i == (ssize_t) argc)
1045 ThrowMontageException(OptionError,"MissingArgument",option);
1046 gravity=ParseCommandOption(MagickGravityOptions,MagickFalse,
1047 argv[i]);
1048 if (gravity < 0)
1049 ThrowMontageException(OptionError,"UnrecognizedGravityType",
1050 argv[i]);
1051 montage_info->gravity=(GravityType) gravity;
1052 break;
1053 }
1054 if (LocaleCompare("green-primary",option+1) == 0)
1055 {
1056 if (*option == '+')
1057 break;
1058 i++;
1059 if (i == (ssize_t) argc)
1060 ThrowMontageException(OptionError,"MissingArgument",option);
1061 if (IsGeometry(argv[i]) == MagickFalse)
1062 ThrowMontageInvalidArgumentException(option,argv[i]);
1063 break;
1064 }
1065 ThrowMontageException(OptionError,"UnrecognizedOption",option)
1066 }
1067 case 'h':
1068 {
1069 if ((LocaleCompare("help",option+1) == 0) ||
1070 (LocaleCompare("-help",option+1) == 0))
1071 {
1072 DestroyMontage();
1073 return(MontageUsage());
1074 }
1075 ThrowMontageException(OptionError,"UnrecognizedOption",option)
1076 }
1077 case 'i':
1078 {
1079 if (LocaleCompare("identify",option+1) == 0)
1080 break;
1081 if (LocaleCompare("insert",option+1) == 0)
1082 {
1083 if (*option == '+')
1084 break;
1085 i++;
1086 if (i == (ssize_t) argc)
1087 ThrowMontageException(OptionError,"MissingArgument",option);
1088 if (IsGeometry(argv[i]) == MagickFalse)
1089 ThrowMontageInvalidArgumentException(option,argv[i]);
1090 break;
1091 }
1092 if (LocaleCompare("interlace",option+1) == 0)
1093 {
1094 ssize_t
1095 interlace;
1096
1097 if (*option == '+')
1098 break;
1099 i++;
1100 if (i == (ssize_t) argc)
1101 ThrowMontageException(OptionError,"MissingArgument",option);
1102 interlace=ParseCommandOption(MagickInterlaceOptions,MagickFalse,
1103 argv[i]);
1104 if (interlace < 0)
1105 ThrowMontageException(OptionError,"UnrecognizedInterlaceType",
1106 argv[i]);
1107 break;
1108 }
1109 if (LocaleCompare("interpolate",option+1) == 0)
1110 {
1111 ssize_t
1112 interpolate;
1113
1114 if (*option == '+')
1115 break;
1116 i++;
1117 if (i == (ssize_t) argc)
1118 ThrowMontageException(OptionError,"MissingArgument",option);
1119 interpolate=ParseCommandOption(MagickInterpolateOptions,MagickFalse,
1120 argv[i]);
1121 if (interpolate < 0)
1122 ThrowMontageException(OptionError,"UnrecognizedInterpolateMethod",
1123 argv[i]);
1124 break;
1125 }
1126 ThrowMontageException(OptionError,"UnrecognizedOption",option)
1127 }
1128 case 'k':
1129 {
1130 if (LocaleCompare("kerning",option+1) == 0)
1131 {
1132 if (*option == '+')
1133 break;
1134 i++;
1135 if (i == (ssize_t) argc)
1136 ThrowMontageException(OptionError,"MissingArgument",option);
1137 if (IsGeometry(argv[i]) == MagickFalse)
1138 ThrowMontageInvalidArgumentException(option,argv[i]);
1139 break;
1140 }
1141 ThrowMontageException(OptionError,"UnrecognizedOption",option)
1142 }
1143 case 'l':
1144 {
1145 if (LocaleCompare("label",option+1) == 0)
1146 {
1147 if (*option == '+')
1148 break;
1149 i++;
1150 if (i == (ssize_t) argc)
1151 ThrowMontageException(OptionError,"MissingArgument",option);
1152 break;
1153 }
1154 if (LocaleCompare("layers",option+1) == 0)
1155 {
1156 ssize_t
1157 type;
1158
1159 if (*option == '+')
1160 break;
1161 i++;
1162 if (i == (ssize_t) argc)
1163 ThrowMontageException(OptionError,"MissingArgument",option);
1164 type=ParseCommandOption(MagickLayerOptions,MagickFalse,argv[i]);
1165 if (type < 0)
1166 ThrowMontageException(OptionError,"UnrecognizedLayerMethod",
1167 argv[i]);
1168 break;
1169 }
1170 if (LocaleCompare("limit",option+1) == 0)
1171 {
1172 char
1173 *p;
1174
1175 double
1176 value;
1177
1178 ssize_t
1179 resource;
1180
1181 if (*option == '+')
1182 break;
1183 i++;
1184 if (i == (ssize_t) argc)
1185 ThrowMontageException(OptionError,"MissingArgument",option);
1186 resource=ParseCommandOption(MagickResourceOptions,MagickFalse,
1187 argv[i]);
1188 if (resource < 0)
1189 ThrowMontageException(OptionError,"UnrecognizedResourceType",
1190 argv[i]);
1191 i++;
1192 if (i == (ssize_t) argc)
1193 ThrowMontageException(OptionError,"MissingArgument",option);
1194 value=StringToDouble(argv[i],&p);
1195 (void) value;
1196 if ((p == argv[i]) && (LocaleCompare("unlimited",argv[i]) != 0))
1197 ThrowMontageInvalidArgumentException(option,argv[i]);
1198 break;
1199 }
1200 if (LocaleCompare("list",option+1) == 0)
1201 {
1202 ssize_t
1203 list;
1204
1205 if (*option == '+')
1206 break;
1207 i++;
1208 if (i == (ssize_t) argc)
1209 ThrowMontageException(OptionError,"MissingArgument",option);
1210 list=ParseCommandOption(MagickListOptions,MagickFalse,argv[i]);
1211 if (list < 0)
1212 ThrowMontageException(OptionError,"UnrecognizedListType",argv[i]);
1213 status=MogrifyImageInfo(image_info,(int) (i-j+1),(const char **)
1214 argv+j,exception);
1215 DestroyMontage();
1216 return(status == 0 ? MagickFalse : MagickTrue);
1217 }
1218 if (LocaleCompare("log",option+1) == 0)
1219 {
1220 if (*option == '+')
1221 break;
1222 i++;
1223 if ((i == (ssize_t) argc) ||
1224 (strchr(argv[i],'%') == (char *) NULL))
1225 ThrowMontageException(OptionError,"MissingArgument",option);
1226 break;
1227 }
1228 ThrowMontageException(OptionError,"UnrecognizedOption",option)
1229 }
1230 case 'm':
1231 {
1232 if (LocaleCompare("matte",option+1) == 0)
1233 break;
1234 if (LocaleCompare("mattecolor",option+1) == 0)
1235 {
1236 if (*option == '+')
1237 break;
1238 i++;
1239 if (i == (ssize_t) argc)
1240 ThrowMontageException(OptionError,"MissingArgument",option);
1241 (void) QueryColorCompliance(argv[i],AllCompliance,
1242 &montage_info->matte_color,exception);
1243 break;
1244 }
1245 if (LocaleCompare("mode",option+1) == 0)
1246 {
1247 MontageMode
1248 mode;
1249
1250 (void) CopyMagickString(argv[i]+1,"sans",MagickPathExtent);
1251 if (*option == '+')
1252 break;
1253 i++;
1254 if (i == (ssize_t) argc)
1255 ThrowMontageException(OptionError,"MissingArgument",option);
1256 mode=UndefinedMode;
1257 if (LocaleCompare("frame",argv[i]) == 0)
1258 {
1259 mode=FrameMode;
1260 (void) CloneString(&montage_info->frame,"15x15+3+3");
1261 montage_info->shadow=MagickTrue;
1262 break;
1263 }
1264 if (LocaleCompare("unframe",argv[i]) == 0)
1265 {
1266 mode=UnframeMode;
1267 montage_info->frame=(char *) NULL;
1268 montage_info->shadow=MagickFalse;
1269 montage_info->border_width=0;
1270 break;
1271 }
1272 if (LocaleCompare("concatenate",argv[i]) == 0)
1273 {
1274 mode=ConcatenateMode;
1275 montage_info->frame=(char *) NULL;
1276 montage_info->shadow=MagickFalse;
1277 montage_info->gravity=(GravityType) NorthWestGravity;
1278 (void) CloneString(&montage_info->geometry,"+0+0");
1279 montage_info->border_width=0;
1280 break;
1281 }
1282 if (mode == UndefinedMode)
1283 ThrowMontageException(OptionError,"UnrecognizedImageMode",
1284 argv[i]);
1285 break;
1286 }
1287 if (LocaleCompare("monitor",option+1) == 0)
1288 break;
1289 if (LocaleCompare("monochrome",option+1) == 0)
1290 break;
1291 ThrowMontageException(OptionError,"UnrecognizedOption",option)
1292 }
1293 case 'n':
1294 {
1295 if (LocaleCompare("noop",option+1) == 0)
1296 break;
1297 ThrowMontageException(OptionError,"UnrecognizedOption",option)
1298 }
1299 case 'p':
1300 {
1301 if (LocaleCompare("page",option+1) == 0)
1302 {
1303 if (*option == '+')
1304 break;
1305 i++;
1306 if (i == (ssize_t) argc)
1307 ThrowMontageException(OptionError,"MissingArgument",option);
1308 break;
1309 }
1310 if (LocaleCompare("pointsize",option+1) == 0)
1311 {
1312 montage_info->pointsize=12;
1313 if (*option == '+')
1314 break;
1315 i++;
1316 if (i == (ssize_t) argc)
1317 ThrowMontageException(OptionError,"MissingArgument",option);
1318 if (IsGeometry(argv[i]) == MagickFalse)
1319 ThrowMontageInvalidArgumentException(option,argv[i]);
1320 montage_info->pointsize=StringToDouble(argv[i],(char **) NULL);
1321 break;
1322 }
1323 if (LocaleCompare("polaroid",option+1) == 0)
1324 {
1325 if (*option == '+')
1326 break;
1327 i++;
1328 if (i == (ssize_t) argc)
1329 ThrowMontageException(OptionError,"MissingArgument",option);
1330 if (IsGeometry(argv[i]) == MagickFalse)
1331 ThrowMontageInvalidArgumentException(option,argv[i]);
1332 break;
1333 }
1334 if (LocaleCompare("profile",option+1) == 0)
1335 {
1336 i++;
1337 if (i == (ssize_t) argc)
1338 ThrowMontageException(OptionError,"MissingArgument",option);
1339 break;
1340 }
1341 ThrowMontageException(OptionError,"UnrecognizedOption",option)
1342 }
1343 case 'q':
1344 {
1345 if (LocaleCompare("quality",option+1) == 0)
1346 {
1347 if (*option == '+')
1348 break;
1349 i++;
1350 if (i == (ssize_t) argc)
1351 ThrowMontageException(OptionError,"MissingArgument",option);
1352 if (IsGeometry(argv[i]) == MagickFalse)
1353 ThrowMontageInvalidArgumentException(option,argv[i]);
1354 break;
1355 }
1356 if (LocaleCompare("quantize",option+1) == 0)
1357 {
1358 ssize_t
1359 colorspace;
1360
1361 if (*option == '+')
1362 break;
1363 i++;
1364 if (i == (ssize_t) argc)
1365 ThrowMontageException(OptionError,"MissingArgument",option);
1366 colorspace=ParseCommandOption(MagickColorspaceOptions,
1367 MagickFalse,argv[i]);
1368 if (colorspace < 0)
1369 ThrowMontageException(OptionError,"UnrecognizedColorspace",
1370 argv[i]);
1371 break;
1372 }
1373 if (LocaleCompare("quiet",option+1) == 0)
1374 break;
1375 ThrowMontageException(OptionError,"UnrecognizedOption",option)
1376 }
1377 case 'r':
1378 {
1379 if (LocaleCompare("red-primary",option+1) == 0)
1380 {
1381 if (*option == '+')
1382 break;
1383 i++;
1384 if (i == (ssize_t) argc)
1385 ThrowMontageException(OptionError,"MissingArgument",option);
1386 if (IsGeometry(argv[i]) == MagickFalse)
1387 ThrowMontageInvalidArgumentException(option,argv[i]);
1388 break;
1389 }
1390 if (LocaleCompare("regard-warnings",option+1) == 0)
1391 break;
1392 if (LocaleCompare("render",option+1) == 0)
1393 break;
1394 if (LocaleCompare("repage",option+1) == 0)
1395 {
1396 if (*option == '+')
1397 break;
1398 i++;
1399 if (i == (ssize_t) argc)
1400 ThrowMontageException(OptionError,"MissingArgument",option);
1401 if (IsGeometry(argv[i]) == MagickFalse)
1402 ThrowMontageInvalidArgumentException(option,argv[i]);
1403 break;
1404 }
1405 if (LocaleCompare("resize",option+1) == 0)
1406 {
1407 if (*option == '+')
1408 break;
1409 i++;
1410 if (i == (ssize_t) argc)
1411 ThrowMontageException(OptionError,"MissingArgument",option);
1412 if (IsGeometry(argv[i]) == MagickFalse)
1413 ThrowMontageInvalidArgumentException(option,argv[i]);
1414 break;
1415 }
1416 if (LocaleNCompare("respect-parentheses",option+1,17) == 0)
1417 {
1418 respect_parenthesis=(*option == '-') ? MagickTrue : MagickFalse;
1419 break;
1420 }
1421 if (LocaleCompare("reverse",option+1) == 0)
1422 break;
1423 if (LocaleCompare("rotate",option+1) == 0)
1424 {
1425 i++;
1426 if (i == (ssize_t) argc)
1427 ThrowMontageException(OptionError,"MissingArgument",option);
1428 if (IsGeometry(argv[i]) == MagickFalse)
1429 ThrowMontageInvalidArgumentException(option,argv[i]);
1430 break;
1431 }
1432 ThrowMontageException(OptionError,"UnrecognizedOption",option)
1433 }
1434 case 's':
1435 {
1436 if (LocaleCompare("sampling-factor",option+1) == 0)
1437 {
1438 if (*option == '+')
1439 break;
1440 i++;
1441 if (i == (ssize_t) argc)
1442 ThrowMontageException(OptionError,"MissingArgument",option);
1443 if (IsGeometry(argv[i]) == MagickFalse)
1444 ThrowMontageInvalidArgumentException(option,argv[i]);
1445 break;
1446 }
1447 if (LocaleCompare("scale",option+1) == 0)
1448 {
1449 if (*option == '+')
1450 break;
1451 i++;
1452 if (i == (ssize_t) argc)
1453 ThrowMontageException(OptionError,"MissingArgument",option);
1454 if (IsGeometry(argv[i]) == MagickFalse)
1455 ThrowMontageInvalidArgumentException(option,argv[i]);
1456 break;
1457 }
1458 if (LocaleCompare("scenes",option+1) == 0)
1459 {
1460 first_scene=0;
1461 last_scene=0;
1462 if (*option == '+')
1463 break;
1464 i++;
1465 if (i == (ssize_t) argc)
1466 ThrowMontageException(OptionError,"MissingArgument",option);
1467 if (IsSceneGeometry(argv[i],MagickFalse) == MagickFalse)
1468 ThrowMontageInvalidArgumentException(option,argv[i]);
1469 first_scene=(int) StringToLong(argv[i]);
1470 last_scene=first_scene;
1471 (void) sscanf(argv[i],"%ld-%ld",&first_scene,&last_scene);
1472 break;
1473 }
1474 if (LocaleCompare("seed",option+1) == 0)
1475 {
1476 if (*option == '+')
1477 break;
1478 i++;
1479 if (i == (ssize_t) argc)
1480 ThrowMontageException(OptionError,"MissingArgument",option);
1481 if (IsGeometry(argv[i]) == MagickFalse)
1482 ThrowMontageInvalidArgumentException(option,argv[i]);
1483 break;
1484 }
1485 if (LocaleCompare("set",option+1) == 0)
1486 {
1487 i++;
1488 if (i == (ssize_t) argc)
1489 ThrowMontageException(OptionError,"MissingArgument",option);
1490 if (*option == '+')
1491 break;
1492 i++;
1493 if (i == (ssize_t) argc)
1494 ThrowMontageException(OptionError,"MissingArgument",option);
1495 break;
1496 }
1497 if (LocaleCompare("shadow",option+1) == 0)
1498 {
1499 if (k == 0)
1500 {
1501 (void) CopyMagickString(argv[i]+1,"sans",MagickPathExtent);
1502 montage_info->shadow=(*option == '-') ? MagickTrue :
1503 MagickFalse;
1504 break;
1505 }
1506 if (*option == '+')
1507 break;
1508 i++;
1509 if (i == (ssize_t) argc)
1510 ThrowMontageException(OptionError,"MissingArgument",option);
1511 if (IsGeometry(argv[i]) == MagickFalse)
1512 ThrowMontageInvalidArgumentException(option,argv[i]);
1513 break;
1514 }
1515 if (LocaleCompare("sharpen",option+1) == 0)
1516 {
1517 if (*option == '+')
1518 break;
1519 i++;
1520 if ((i == (ssize_t) argc) || (IsGeometry(argv[i]) == MagickFalse))
1521 ThrowMontageException(OptionError,"MissingArgument",option);
1522 break;
1523 }
1524 if (LocaleCompare("size",option+1) == 0)
1525 {
1526 if (*option == '+')
1527 break;
1528 i++;
1529 if (i == (ssize_t) argc)
1530 ThrowMontageException(OptionError,"MissingArgument",option);
1531 if (IsGeometry(argv[i]) == MagickFalse)
1532 ThrowMontageInvalidArgumentException(option,argv[i]);
1533 break;
1534 }
1535 if (LocaleCompare("stroke",option+1) == 0)
1536 {
1537 (void) QueryColorCompliance("none",AllCompliance,
1538 &montage_info->stroke,exception);
1539 if (*option == '+')
1540 break;
1541 i++;
1542 if (i == (ssize_t) argc)
1543 ThrowMontageException(OptionError,"MissingArgument",option);
1544 (void) QueryColorCompliance(argv[i],AllCompliance,
1545 &montage_info->stroke,exception);
1546 break;
1547 }
1548 if (LocaleCompare("strip",option+1) == 0)
1549 break;
1550 if (LocaleCompare("strokewidth",option+1) == 0)
1551 {
1552 if (*option == '+')
1553 break;
1554 i++;
1555 if (i == (ssize_t) argc)
1556 ThrowMontageException(OptionError,"MissingArgument",option);
1557 if (IsGeometry(argv[i]) == MagickFalse)
1558 ThrowMontageInvalidArgumentException(option,argv[i]);
1559 break;
1560 }
1561 if (LocaleCompare("support",option+1) == 0)
1562 {
1563 i++; /* deprecated */
1564 break;
1565 }
1566 if (LocaleCompare("swap",option+1) == 0)
1567 {
1568 if (*option == '+')
1569 break;
1570 i++;
1571 if (i == (ssize_t) argc)
1572 ThrowMontageException(OptionError,"MissingArgument",option);
1573 if (IsGeometry(argv[i]) == MagickFalse)
1574 ThrowMontageInvalidArgumentException(option,argv[i]);
1575 break;
1576 }
1577 if (LocaleCompare("synchronize",option+1) == 0)
1578 break;
1579 ThrowMontageException(OptionError,"UnrecognizedOption",option)
1580 }
1581 case 't':
1582 {
1583 if (LocaleCompare("taint",option+1) == 0)
1584 break;
1585 if (LocaleCompare("texture",option+1) == 0)
1586 {
1587 (void) CloneString(&montage_info->texture,(char *) NULL);
1588 if (*option == '+')
1589 break;
1590 i++;
1591 if (i == (ssize_t) argc)
1592 ThrowMontageException(OptionError,"MissingArgument",option);
1593 (void) CloneString(&montage_info->texture,argv[i]);
1594 break;
1595 }
1596 if (LocaleCompare("thumbnail",option+1) == 0)
1597 {
1598 if (*option == '+')
1599 break;
1600 i++;
1601 if (i == (ssize_t) argc)
1602 ThrowMontageException(OptionError,"MissingArgument",option);
1603 if (IsGeometry(argv[i]) == MagickFalse)
1604 ThrowMontageInvalidArgumentException(option,argv[i]);
1605 break;
1606 }
1607 if (LocaleCompare("tile",option+1) == 0)
1608 {
1609 if (k == 0)
1610 {
1611 (void) CopyMagickString(argv[i]+1,"sans",MagickPathExtent);
1612 (void) CloneString(&montage_info->tile,(char *) NULL);
1613 }
1614 if (*option == '+')
1615 break;
1616 i++;
1617 if (i == (ssize_t) argc)
1618 ThrowMontageException(OptionError,"MissingArgument",option);
1619 if (IsGeometry(argv[i]) == MagickFalse)
1620 ThrowMontageInvalidArgumentException(option,argv[i]);
1621 if (k == 0)
1622 (void) CloneString(&montage_info->tile,argv[i]);
1623 break;
1624 }
1625 if (LocaleCompare("tile-offset",option+1) == 0)
1626 {
1627 if (*option == '+')
1628 break;
1629 i++;
1630 if (i == (ssize_t) argc)
1631 ThrowMontageException(OptionError,"MissingArgument",option);
1632 if (IsGeometry(argv[i]) == MagickFalse)
1633 ThrowMontageInvalidArgumentException(option,argv[i]);
1634 break;
1635 }
1636 if (LocaleCompare("tint",option+1) == 0)
1637 {
1638 if (*option == '+')
1639 break;
1640 i++;
1641 if (i == (ssize_t) argc)
1642 ThrowMontageException(OptionError,"MissingArgument",option);
1643 if (IsGeometry(argv[i]) == MagickFalse)
1644 ThrowMontageInvalidArgumentException(option,argv[i]);
1645 break;
1646 }
1647 if (LocaleCompare("transform",option+1) == 0)
1648 break;
1649 if (LocaleCompare("transpose",option+1) == 0)
1650 break;
1651 if (LocaleCompare("title",option+1) == 0)
1652 {
1653 (void) CloneString(&montage_info->title,(char *) NULL);
1654 if (*option == '+')
1655 break;
1656 i++;
1657 if (i == (ssize_t) argc)
1658 ThrowMontageException(OptionError,"MissingArgument",option);
1659 (void) CloneString(&montage_info->title,argv[i]);
1660 break;
1661 }
1662 if (LocaleCompare("transform",option+1) == 0)
1663 break;
1664 if (LocaleCompare("transparent",option+1) == 0)
1665 {
1666 transparent_color=(char *) NULL;
1667 i++;
1668 if (i == (ssize_t) argc)
1669 ThrowMontageException(OptionError,"MissingArgument",option);
1670 (void) CloneString(&transparent_color,argv[i]);
1671 break;
1672 }
1673 if (LocaleCompare("transparent-color",option+1) == 0)
1674 {
1675 if (*option == '+')
1676 break;
1677 i++;
1678 if (i == (ssize_t) argc)
1679 ThrowMontageException(OptionError,"MissingArgument",option);
1680 break;
1681 }
1682 if (LocaleCompare("treedepth",option+1) == 0)
1683 {
1684 if (*option == '+')
1685 break;
1686 i++;
1687 if (i == (ssize_t) argc)
1688 ThrowMontageException(OptionError,"MissingArgument",option);
1689 if (IsGeometry(argv[i]) == MagickFalse)
1690 ThrowMontageInvalidArgumentException(option,argv[i]);
1691 break;
1692 }
1693 if (LocaleCompare("trim",option+1) == 0)
1694 break;
1695 if (LocaleCompare("type",option+1) == 0)
1696 {
1697 ssize_t
1698 type;
1699
1700 if (*option == '+')
1701 break;
1702 i++;
1703 if (i == (ssize_t) argc)
1704 ThrowMontageException(OptionError,"MissingArgument",option);
1705 type=ParseCommandOption(MagickTypeOptions,MagickFalse,argv[i]);
1706 if (type < 0)
1707 ThrowMontageException(OptionError,"UnrecognizedImageType",
1708 argv[i]);
1709 break;
1710 }
1711 ThrowMontageException(OptionError,"UnrecognizedOption",option)
1712 }
1713 case 'u':
1714 {
1715 if (LocaleCompare("units",option+1) == 0)
1716 {
1717 ssize_t
1718 units;
1719
1720 if (*option == '+')
1721 break;
1722 i++;
1723 if (i == (ssize_t) argc)
1724 ThrowMontageException(OptionError,"MissingArgument",option);
1725 units=ParseCommandOption(MagickResolutionOptions,MagickFalse,
1726 argv[i]);
1727 if (units < 0)
1728 ThrowMontageException(OptionError,"UnrecognizedUnitsType",
1729 argv[i]);
1730 break;
1731 }
1732 if (LocaleCompare("unsharp",option+1) == 0)
1733 {
1734 if (*option == '+')
1735 break;
1736 i++;
1737 if (i == (ssize_t) argc)
1738 ThrowMontageException(OptionError,"MissingArgument",option);
1739 if (IsGeometry(argv[i]) == MagickFalse)
1740 ThrowMontageInvalidArgumentException(option,argv[i]);
1741 break;
1742 }
1743 ThrowMontageException(OptionError,"UnrecognizedOption",option)
1744 }
1745 case 'v':
1746 {
1747 if (LocaleCompare("verbose",option+1) == 0)
1748 {
1749 break;
1750 }
1751 if ((LocaleCompare("version",option+1) == 0) ||
1752 (LocaleCompare("-version",option+1) == 0))
1753 {
1754 ListMagickVersion(stdout);
1755 break;
1756 }
1757 if (LocaleCompare("virtual-pixel",option+1) == 0)
1758 {
1759 ssize_t
1760 method;
1761
1762 if (*option == '+')
1763 break;
1764 i++;
1765 if (i == (ssize_t) argc)
1766 ThrowMontageException(OptionError,"MissingArgument",option);
1767 method=ParseCommandOption(MagickVirtualPixelOptions,MagickFalse,
1768 argv[i]);
1769 if (method < 0)
1770 ThrowMontageException(OptionError,
1771 "UnrecognizedVirtualPixelMethod",argv[i]);
1772 break;
1773 }
1774 ThrowMontageException(OptionError,"UnrecognizedOption",option)
1775 }
1776 case 'w':
1777 {
1778 if (LocaleCompare("white-point",option+1) == 0)
1779 {
1780 if (*option == '+')
1781 break;
1782 i++;
1783 if (i == (ssize_t) argc)
1784 ThrowMontageException(OptionError,"MissingArgument",option);
1785 if (IsGeometry(argv[i]) == MagickFalse)
1786 ThrowMontageInvalidArgumentException(option,argv[i]);
1787 break;
1788 }
1789 ThrowMontageException(OptionError,"UnrecognizedOption",option)
1790 }
1791 case '?':
1792 break;
1793 default:
1794 ThrowMontageException(OptionError,"UnrecognizedOption",option)
1795 }
1796 fire=(GetCommandOptionFlags(MagickCommandOptions,MagickFalse,option) &
1797 FireOptionFlag) == 0 ? MagickFalse : MagickTrue;
1798 if (fire != MagickFalse)
1799 FireImageStack(MagickTrue,MagickTrue,MagickTrue);
1800 }
1801 if (k != 0)
1802 ThrowMontageException(OptionError,"UnbalancedParenthesis",argv[i]);
1803 if (i-- != (ssize_t) (argc-1))
1804 ThrowMontageException(OptionError,"MissingAnImageFilename",argv[i]);
1805 if (image == (Image *) NULL)
1806 ThrowMontageException(OptionError,"MissingAnImageFilename",argv[argc-1]);
1807 FinalizeImageSettings(image_info,image,MagickTrue);
1808 if (image == (Image *) NULL)
1809 ThrowMontageException(OptionError,"MissingAnImageFilename",argv[argc-1]);
1810 (void) CopyMagickString(montage_info->filename,argv[argc-1],MagickPathExtent);
1811 montage_image=MontageImageList(image_info,montage_info,image,exception);
1812 if (montage_image == (Image *) NULL)
1813 status=MagickFalse;
1814 else
1815 {
1816 /*
1817 Write image.
1818 */
1819 (void) CopyMagickString(image_info->filename,argv[argc-1],
1820 MagickPathExtent);
1821 (void) CopyMagickString(montage_image->magick_filename,argv[argc-1],
1822 MagickPathExtent);
1823 if (*montage_image->magick == '\0')
1824 (void) CopyMagickString(montage_image->magick,image->magick,
1825 MagickPathExtent);
1826 status&=WriteImages(image_info,montage_image,argv[argc-1],exception);
1827 if (metadata != (char **) NULL)
1828 {
1829 char
1830 *text;
1831
1832 text=InterpretImageProperties(image_info,montage_image,format,
1833 exception);
1834 if (text == (char *) NULL)
1835 ThrowMontageException(ResourceLimitError,"MemoryAllocationFailed",
1836 GetExceptionMessage(errno));
1837 (void) ConcatenateString(&(*metadata),text);
1838 text=DestroyString(text);
1839 }
1840 }
1841 DestroyMontage();
1842 return(status != 0 ? MagickTrue : MagickFalse);
1843 }
1844