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