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