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