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