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