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