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