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