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