]> 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             if ((p == argv[i]) && (LocaleCompare("unlimited",argv[i]) != 0))
1124               ThrowMontageInvalidArgumentException(option,argv[i]);
1125             break;
1126           }
1127         if (LocaleCompare("list",option+1) == 0)
1128           {
1129             ssize_t
1130               list;
1131
1132             if (*option == '+')
1133               break;
1134             i++;
1135             if (i == (ssize_t) argc)
1136               ThrowMontageException(OptionError,"MissingArgument",option);
1137             list=ParseMagickOption(MagickListOptions,MagickFalse,argv[i]);
1138             if (list < 0)
1139               ThrowMontageException(OptionError,"UnrecognizedListType",argv[i]);
1140             status=MogrifyImageInfo(image_info,(int) (i-j+1),(const char **)
1141               argv+j,exception);
1142             DestroyMontage();
1143             return(status != 0 ? MagickFalse : MagickTrue);
1144           }
1145         if (LocaleCompare("log",option+1) == 0)
1146           {
1147             if (*option == '+')
1148               break;
1149             i++;
1150             if ((i == (ssize_t) argc) ||
1151                 (strchr(argv[i],'%') == (char *) NULL))
1152               ThrowMontageException(OptionError,"MissingArgument",option);
1153             break;
1154           }
1155         ThrowMontageException(OptionError,"UnrecognizedOption",option)
1156       }
1157       case 'm':
1158       {
1159         if (LocaleCompare("matte",option+1) == 0)
1160           break;
1161         if (LocaleCompare("mattecolor",option+1) == 0)
1162           {
1163             if (*option == '+')
1164               break;
1165             i++;
1166             if (i == (ssize_t) argc)
1167               ThrowMontageException(OptionError,"MissingArgument",option);
1168             (void) QueryColorDatabase(argv[i],&montage_info->matte_color,
1169               exception);
1170             break;
1171           }
1172         if (LocaleCompare("mode",option+1) == 0)
1173           {
1174             MontageMode
1175               mode;
1176
1177             if (*option == '+')
1178               break;
1179             i++;
1180             if (i == (ssize_t) argc)
1181               ThrowMontageException(OptionError,"MissingArgument",option);
1182             mode=UndefinedMode;
1183             if (LocaleCompare("frame",argv[i]) == 0)
1184               {
1185                 mode=FrameMode;
1186                 (void) CloneString(&montage_info->frame,"15x15+3+3");
1187                 montage_info->shadow=MagickTrue;
1188                 break;
1189               }
1190             if (LocaleCompare("unframe",argv[i]) == 0)
1191               {
1192                 mode=UnframeMode;
1193                 montage_info->frame=(char *) NULL;
1194                 montage_info->shadow=MagickFalse;
1195                 montage_info->border_width=0;
1196                 break;
1197               }
1198             if (LocaleCompare("concatenate",argv[i]) == 0)
1199               {
1200                 mode=ConcatenateMode;
1201                 montage_info->frame=(char *) NULL;
1202                 montage_info->shadow=MagickFalse;
1203                 montage_info->gravity=(GravityType) NorthWestGravity;
1204                 (void) CloneString(&montage_info->geometry,"+0+0");
1205                 montage_info->border_width=0;
1206                 break;
1207               }
1208             if (mode == UndefinedMode)
1209               ThrowMontageException(OptionError,"UnrecognizedImageMode",
1210                 argv[i]);
1211             break;
1212           }
1213         if (LocaleCompare("monitor",option+1) == 0)
1214           break;
1215         if (LocaleCompare("monochrome",option+1) == 0)
1216           {
1217             if (*option == '+')
1218               break;
1219             break;
1220           }
1221         ThrowMontageException(OptionError,"UnrecognizedOption",option)
1222       }
1223       case 'n':
1224       {
1225         if (LocaleCompare("noop",option+1) == 0)
1226           break;
1227         ThrowMontageException(OptionError,"UnrecognizedOption",option)
1228       }
1229       case 'o':
1230       {
1231         if (LocaleCompare("origin",option+1) == 0)
1232           {
1233             if (*option == '+')
1234               break;
1235             i++;
1236             if (i == (ssize_t) argc)
1237               ThrowMontageException(OptionError,"MissingArgument",option);
1238             if (IsGeometry(argv[i]) == MagickFalse)
1239               ThrowMontageInvalidArgumentException(option,argv[i]);
1240             break;
1241           }
1242         ThrowMontageException(OptionError,"UnrecognizedOption",option)
1243       }
1244       case 'p':
1245       {
1246         if (LocaleCompare("page",option+1) == 0)
1247           {
1248             if (*option == '+')
1249               break;
1250             i++;
1251             if (i == (ssize_t) argc)
1252               ThrowMontageException(OptionError,"MissingArgument",option);
1253             break;
1254           }
1255         if (LocaleCompare("pointsize",option+1) == 0)
1256           {
1257             montage_info->pointsize=12;
1258             if (*option == '+')
1259               break;
1260             i++;
1261             if (i == (ssize_t) argc)
1262               ThrowMontageException(OptionError,"MissingArgument",option);
1263             if (IsGeometry(argv[i]) == MagickFalse)
1264               ThrowMontageInvalidArgumentException(option,argv[i]);
1265             montage_info->pointsize=StringToDouble(argv[i]);
1266             break;
1267           }
1268         if (LocaleCompare("polaroid",option+1) == 0)
1269           {
1270             if (*option == '+')
1271               break;
1272             i++;
1273             if (i == (ssize_t) (argc-1))
1274               ThrowMontageException(OptionError,"MissingArgument",option);
1275             if (IsGeometry(argv[i]) == MagickFalse)
1276               ThrowMontageInvalidArgumentException(option,argv[i]);
1277             break;
1278           }
1279         if (LocaleCompare("profile",option+1) == 0)
1280           {
1281             i++;
1282             if (i == (ssize_t) (argc-1))
1283               ThrowMontageException(OptionError,"MissingArgument",option);
1284             break;
1285           }
1286         ThrowMontageException(OptionError,"UnrecognizedOption",option)
1287       }
1288       case 'q':
1289       {
1290         if (LocaleCompare("quality",option+1) == 0)
1291           {
1292             if (*option == '+')
1293               break;
1294             i++;
1295             if (i == (ssize_t) argc)
1296               ThrowMontageException(OptionError,"MissingArgument",option);
1297             if (IsGeometry(argv[i]) == MagickFalse)
1298               ThrowMontageInvalidArgumentException(option,argv[i]);
1299             break;
1300           }
1301         if (LocaleCompare("quantize",option+1) == 0)
1302           {
1303             ssize_t
1304               colorspace;
1305
1306             if (*option == '+')
1307               break;
1308             i++;
1309             if (i == (ssize_t) (argc-1))
1310               ThrowMontageException(OptionError,"MissingArgument",option);
1311             colorspace=ParseMagickOption(MagickColorspaceOptions,
1312               MagickFalse,argv[i]);
1313             if (colorspace < 0)
1314               ThrowMontageException(OptionError,"UnrecognizedColorspace",
1315                 argv[i]);
1316             break;
1317           }
1318         if (LocaleCompare("quiet",option+1) == 0)
1319           break;
1320         ThrowMontageException(OptionError,"UnrecognizedOption",option)
1321       }
1322       case 'r':
1323       {
1324         if (LocaleCompare("red-primary",option+1) == 0)
1325           {
1326             if (*option == '+')
1327               break;
1328             i++;
1329             if (i == (ssize_t) argc)
1330               ThrowMontageException(OptionError,"MissingArgument",option);
1331             if (IsGeometry(argv[i]) == MagickFalse)
1332               ThrowMontageInvalidArgumentException(option,argv[i]);
1333             break;
1334           }
1335         if (LocaleCompare("regard-warnings",option+1) == 0)
1336           break;
1337         if (LocaleCompare("render",option+1) == 0)
1338           break;
1339         if (LocaleCompare("repage",option+1) == 0)
1340           {
1341             if (*option == '+')
1342               break;
1343             i++;
1344             if (i == (ssize_t) argc)
1345               ThrowMontageException(OptionError,"MissingArgument",option);
1346             if (IsGeometry(argv[i]) == MagickFalse)
1347               ThrowMontageInvalidArgumentException(option,argv[i]);
1348             break;
1349           }
1350         if (LocaleCompare("resize",option+1) == 0)
1351           {
1352             if (*option == '+')
1353               break;
1354             i++;
1355             if (i == (ssize_t) argc)
1356               ThrowMontageException(OptionError,"MissingArgument",option);
1357             if (IsGeometry(argv[i]) == MagickFalse)
1358               ThrowMontageInvalidArgumentException(option,argv[i]);
1359             break;
1360           }
1361         if (LocaleNCompare("respect-parentheses",option+1,17) == 0)
1362           {
1363             respect_parenthesis=(*option == '-') ? MagickTrue : MagickFalse;
1364             break;
1365           }
1366         if (LocaleCompare("rotate",option+1) == 0)
1367           {
1368             i++;
1369             if (i == (ssize_t) argc)
1370               ThrowMontageException(OptionError,"MissingArgument",option);
1371             if (IsGeometry(argv[i]) == MagickFalse)
1372               ThrowMontageInvalidArgumentException(option,argv[i]);
1373             break;
1374           }
1375         ThrowMontageException(OptionError,"UnrecognizedOption",option)
1376       }
1377       case 's':
1378       {
1379         if (LocaleCompare("sampling-factor",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("seed",option+1) == 0)
1391           {
1392             if (*option == '+')
1393               break;
1394             i++;
1395             if (i == (ssize_t) (argc-1))
1396               ThrowMontageException(OptionError,"MissingArgument",option);
1397             if (IsGeometry(argv[i]) == MagickFalse)
1398               ThrowMontageInvalidArgumentException(option,argv[i]);
1399             break;
1400           }
1401         if (LocaleCompare("scenes",option+1) == 0)
1402           {
1403             first_scene=0;
1404             last_scene=0;
1405             if (*option == '+')
1406               break;
1407             i++;
1408             if (i == (ssize_t) argc)
1409               ThrowMontageException(OptionError,"MissingArgument",option);
1410             if (IsSceneGeometry(argv[i],MagickFalse) == MagickFalse)
1411               ThrowMontageInvalidArgumentException(option,argv[i]);
1412             first_scene=(int) StringToLong(argv[i]);
1413             last_scene=first_scene;
1414             (void) sscanf(argv[i],"%ld-%ld",&first_scene,&last_scene);
1415             break;
1416           }
1417         if (LocaleCompare("set",option+1) == 0)
1418           {
1419             i++;
1420             if (i == (ssize_t) argc)
1421               ThrowMontageException(OptionError,"MissingArgument",option);
1422             if (*option == '+')
1423               break;
1424             i++;
1425             if (i == (ssize_t) argc)
1426               ThrowMontageException(OptionError,"MissingArgument",option);
1427             break;
1428           }
1429         if (LocaleCompare("shadow",option+1) == 0)
1430           {
1431             if (k == 0)
1432               {
1433                 (void) CopyMagickString(argv[i]+1,"sans",MaxTextExtent);
1434                 montage_info->shadow=(*option == '-') ? MagickTrue :
1435                   MagickFalse;
1436                 break;
1437               }
1438             if (*option == '+')
1439               break;
1440             i++;
1441             if (i == (ssize_t) (argc-1))
1442               ThrowMontageException(OptionError,"MissingArgument",option);
1443             if (IsGeometry(argv[i]) == MagickFalse)
1444               ThrowMontageInvalidArgumentException(option,argv[i]);
1445             break;
1446           }
1447         if (LocaleCompare("sharpen",option+1) == 0)
1448           {
1449             if (*option == '+')
1450               break;
1451             i++;
1452             if ((i == (ssize_t) argc) || (IsGeometry(argv[i]) == MagickFalse))
1453               ThrowMontageException(OptionError,"MissingArgument",option);
1454             break;
1455           }
1456         if (LocaleCompare("size",option+1) == 0)
1457           {
1458             if (*option == '+')
1459               break;
1460             i++;
1461             if (i == (ssize_t) argc)
1462               ThrowMontageException(OptionError,"MissingArgument",option);
1463             if (IsGeometry(argv[i]) == MagickFalse)
1464               ThrowMontageInvalidArgumentException(option,argv[i]);
1465             break;
1466           }
1467         if (LocaleCompare("stroke",option+1) == 0)
1468           {
1469             (void) QueryColorDatabase("none",&montage_info->stroke,exception);
1470             if (*option == '+')
1471               break;
1472             i++;
1473             if (i == (ssize_t) argc)
1474               ThrowMontageException(OptionError,"MissingArgument",option);
1475             (void) QueryColorDatabase(argv[i],&montage_info->stroke,
1476               exception);
1477             break;
1478           }
1479         if (LocaleCompare("strip",option+1) == 0)
1480           break;
1481         if (LocaleCompare("strokewidth",option+1) == 0)
1482           {
1483             if (*option == '+')
1484               break;
1485             i++;
1486             if (i == (ssize_t) argc)
1487               ThrowMontageException(OptionError,"MissingArgument",option);
1488             if (IsGeometry(argv[i]) == MagickFalse)
1489               ThrowMontageInvalidArgumentException(option,argv[i]);
1490             break;
1491           }
1492         if (LocaleCompare("support",option+1) == 0)
1493           {
1494             i++;  /* deprecated */
1495             break;
1496           }
1497         if (LocaleCompare("synchronize",option+1) == 0)
1498           break;
1499         ThrowMontageException(OptionError,"UnrecognizedOption",option)
1500       }
1501       case 't':
1502       {
1503         if (LocaleCompare("taint",option+1) == 0)
1504           break;
1505         if (LocaleCompare("texture",option+1) == 0)
1506           {
1507             (void) CloneString(&montage_info->texture,(char *) NULL);
1508             if (*option == '+')
1509               break;
1510             i++;
1511             if (i == (ssize_t) argc)
1512               ThrowMontageException(OptionError,"MissingArgument",option);
1513             (void) CloneString(&montage_info->texture,argv[i]);
1514             break;
1515           }
1516         if (LocaleCompare("thumbnail",option+1) == 0)
1517           {
1518             if (*option == '+')
1519               break;
1520             i++;
1521             if (i == (ssize_t) argc)
1522               ThrowMontageException(OptionError,"MissingArgument",option);
1523             if (IsGeometry(argv[i]) == MagickFalse)
1524               ThrowMontageInvalidArgumentException(option,argv[i]);
1525             break;
1526           }
1527         if (LocaleCompare("tile",option+1) == 0)
1528           {
1529             if (k == 0)
1530               {
1531                 (void) CopyMagickString(argv[i]+1,"sans",MaxTextExtent);
1532                 (void) CloneString(&montage_info->tile,(char *) NULL);
1533               }
1534             if (*option == '+')
1535               break;
1536             i++;
1537             if (i == (ssize_t) argc)
1538               ThrowMontageException(OptionError,"MissingArgument",option);
1539             if (IsGeometry(argv[i]) == MagickFalse)
1540               ThrowMontageInvalidArgumentException(option,argv[i]);
1541             if (k == 0)
1542               (void) CloneString(&montage_info->tile,argv[i]);
1543             break;
1544           }
1545         if (LocaleCompare("tile-offset",option+1) == 0)
1546           {
1547             if (*option == '+')
1548               break;
1549             i++;
1550             if (i == (ssize_t) (argc-1))
1551               ThrowMontageException(OptionError,"MissingArgument",option);
1552             if (IsGeometry(argv[i]) == MagickFalse)
1553               ThrowMontageInvalidArgumentException(option,argv[i]);
1554             break;
1555           }
1556         if (LocaleCompare("tint",option+1) == 0)
1557           {
1558             if (*option == '+')
1559               break;
1560             i++;
1561             if (i == (ssize_t) argc)
1562               ThrowMontageException(OptionError,"MissingArgument",option);
1563             if (IsGeometry(argv[i]) == MagickFalse)
1564               ThrowMontageInvalidArgumentException(option,argv[i]);
1565             break;
1566           }
1567         if (LocaleCompare("transform",option+1) == 0)
1568           break;
1569         if (LocaleCompare("transpose",option+1) == 0)
1570           break;
1571         if (LocaleCompare("title",option+1) == 0)
1572           {
1573             (void) CloneString(&montage_info->title,(char *) NULL);
1574             if (*option == '+')
1575               break;
1576             i++;
1577             if (i == (ssize_t) argc)
1578               ThrowMontageException(OptionError,"MissingArgument",option);
1579             (void) CloneString(&montage_info->title,argv[i]);
1580             break;
1581           }
1582         if (LocaleCompare("transform",option+1) == 0)
1583           break;
1584         if (LocaleCompare("transparent",option+1) == 0)
1585           {
1586             transparent_color=(char *) NULL;
1587             i++;
1588             if (i == (ssize_t) argc)
1589               ThrowMontageException(OptionError,"MissingArgument",option);
1590             (void) CloneString(&transparent_color,argv[i]);
1591             break;
1592           }
1593         if (LocaleCompare("transparent-color",option+1) == 0)
1594           {
1595             if (*option == '+')
1596               break;
1597             i++;
1598             if (i == (ssize_t) (argc-1))
1599               ThrowMontageException(OptionError,"MissingArgument",option);
1600             break;
1601           }
1602         if (LocaleCompare("treedepth",option+1) == 0)
1603           {
1604             if (*option == '+')
1605               break;
1606             i++;
1607             if (i == (ssize_t) argc)
1608               ThrowMontageException(OptionError,"MissingArgument",option);
1609             if (IsGeometry(argv[i]) == MagickFalse)
1610               ThrowMontageInvalidArgumentException(option,argv[i]);
1611             break;
1612           }
1613         if (LocaleCompare("trim",option+1) == 0)
1614           break;
1615         if (LocaleCompare("type",option+1) == 0)
1616           {
1617             ssize_t
1618               type;
1619
1620             if (*option == '+')
1621               break;
1622             i++;
1623             if (i == (ssize_t) argc)
1624               ThrowMontageException(OptionError,"MissingArgument",option);
1625             type=ParseMagickOption(MagickTypeOptions,MagickFalse,argv[i]);
1626             if (type < 0)
1627               ThrowMontageException(OptionError,"UnrecognizedImageType",
1628                 argv[i]);
1629             break;
1630           }
1631         ThrowMontageException(OptionError,"UnrecognizedOption",option)
1632       }
1633       case 'u':
1634       {
1635         if (LocaleCompare("units",option+1) == 0)
1636           {
1637             ssize_t
1638               units;
1639
1640             if (*option == '+')
1641               break;
1642             i++;
1643             if (i == (ssize_t) (argc-1))
1644               ThrowMontageException(OptionError,"MissingArgument",option);
1645             units=ParseMagickOption(MagickResolutionOptions,MagickFalse,
1646               argv[i]);
1647             if (units < 0)
1648               ThrowMontageException(OptionError,"UnrecognizedUnitsType",
1649                 argv[i]);
1650             break;
1651           }
1652         if (LocaleCompare("unsharp",option+1) == 0)
1653           {
1654             if (*option == '+')
1655               break;
1656             i++;
1657             if (i == (ssize_t) (argc-1))
1658               ThrowMontageException(OptionError,"MissingArgument",option);
1659             if (IsGeometry(argv[i]) == MagickFalse)
1660               ThrowMontageInvalidArgumentException(option,argv[i]);
1661             break;
1662           }
1663         ThrowMontageException(OptionError,"UnrecognizedOption",option)
1664       }
1665       case 'v':
1666       {
1667         if (LocaleCompare("verbose",option+1) == 0)
1668           {
1669             break;
1670           }
1671         if ((LocaleCompare("version",option+1) == 0) ||
1672             (LocaleCompare("-version",option+1) == 0))
1673           {
1674             (void) fprintf(stdout,"Version: %s\n",
1675               GetMagickVersion((size_t *) NULL));
1676             (void) fprintf(stdout,"Copyright: %s\n",GetMagickCopyright());
1677             (void) fprintf(stdout,"Features: %s\n\n",GetMagickFeatures());
1678             break;
1679           }
1680         if (LocaleCompare("virtual-pixel",option+1) == 0)
1681           {
1682             ssize_t
1683               method;
1684
1685             if (*option == '+')
1686               break;
1687             i++;
1688             if (i == (ssize_t) argc)
1689               ThrowMontageException(OptionError,"MissingArgument",option);
1690             method=ParseMagickOption(MagickVirtualPixelOptions,MagickFalse,
1691               argv[i]);
1692             if (method < 0)
1693               ThrowMontageException(OptionError,
1694                 "UnrecognizedVirtualPixelMethod",argv[i]);
1695             break;
1696           }
1697         ThrowMontageException(OptionError,"UnrecognizedOption",option)
1698       }
1699       case 'w':
1700       {
1701         if (LocaleCompare("white-point",option+1) == 0)
1702           {
1703             if (*option == '+')
1704               break;
1705             i++;
1706             if (i == (ssize_t) argc)
1707               ThrowMontageException(OptionError,"MissingArgument",option);
1708             if (IsGeometry(argv[i]) == MagickFalse)
1709               ThrowMontageInvalidArgumentException(option,argv[i]);
1710             break;
1711           }
1712         ThrowMontageException(OptionError,"UnrecognizedOption",option)
1713       }
1714       case '?':
1715         break;
1716       default:
1717         ThrowMontageException(OptionError,"UnrecognizedOption",option)
1718     }
1719     fire=ParseMagickOption(MagickImageListOptions,MagickFalse,option+1) < 0 ?
1720       MagickFalse : MagickTrue;
1721     if (fire != MagickFalse)
1722       FireImageStack(MagickTrue,MagickTrue,MagickTrue);
1723   }
1724   if (k != 0)
1725     ThrowMontageException(OptionError,"UnbalancedParenthesis",argv[i]);
1726   if (i-- != (ssize_t) (argc-1))
1727     ThrowMontageException(OptionError,"MissingAnImageFilename",argv[i]);
1728   if (image == (Image *) NULL)
1729     ThrowMontageException(OptionError,"MissingAnImageFilename",argv[argc-1]);
1730   FinalizeImageSettings(image_info,image,MagickTrue);
1731   if (image == (Image *) NULL)
1732     ThrowMontageException(OptionError,"MissingAnImageFilename",argv[argc-1]);
1733   (void) CopyMagickString(montage_info->filename,argv[argc-1],MaxTextExtent);
1734   montage_image=MontageImageList(image_info,montage_info,image,exception);
1735   if (montage_image == (Image *) NULL)
1736     status=MagickFalse;
1737   else
1738     {
1739       /*
1740         Write image.
1741       */
1742       GetImageException(montage_image,exception);
1743       (void) CopyMagickString(image_info->filename,argv[argc-1],MaxTextExtent);
1744       (void) CopyMagickString(montage_image->magick_filename,argv[argc-1],
1745         MaxTextExtent);
1746       if (*montage_image->magick == '\0')
1747         (void) CopyMagickString(montage_image->magick,image->magick,
1748           MaxTextExtent);
1749       status&=WriteImages(image_info,montage_image,argv[argc-1],exception);
1750       if (metadata != (char **) NULL)
1751         {
1752           char
1753             *text;
1754
1755           text=InterpretImageProperties(image_info,montage_image,format);
1756           if (text == (char *) NULL)
1757             ThrowMontageException(ResourceLimitError,"MemoryAllocationFailed",
1758               GetExceptionMessage(errno));
1759           (void) ConcatenateString(&(*metadata),text);
1760           (void) ConcatenateString(&(*metadata),"\n");
1761           text=DestroyString(text);
1762         }
1763     }
1764   montage_info=DestroyMontageInfo(montage_info);
1765   DestroyMontage();
1766   return(status != 0 ? MagickTrue : MagickFalse);
1767 }