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