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