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