montage.c

Go to the documentation of this file.
00001 /*
00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00003 %                                                                             %
00004 %                                                                             %
00005 %                                                                             %
00006 %               M   M   OOO   N   N  TTTTT   AAA    GGGG  EEEEE               %
00007 %               MM MM  O   O  NN  N    T    A   A  G      E                   %
00008 %               M M M  O   O  N N N    T    AAAAA  G  GG  EEE                 %
00009 %               M   M  O   O  N  NN    T    A   A  G   G  E                   %
00010 %               M   M   OOO   N   N    T    A   A   GGG   EEEEE               %
00011 %                                                                             %
00012 %                                                                             %
00013 %                MagickWand Methods to Create Image Thumbnails                %
00014 %                                                                             %
00015 %                              Software Design                                %
00016 %                                John Cristy                                  %
00017 %                                 July 1992                                   %
00018 %                                                                             %
00019 %                                                                             %
00020 %  Copyright 1999-2008 ImageMagick Studio LLC, a non-profit organization      %
00021 %  dedicated to making software imaging solutions freely available.           %
00022 %                                                                             %
00023 %  You may not use this file except in compliance with the License.  You may  %
00024 %  obtain a copy of the License at                                            %
00025 %                                                                             %
00026 %    http://www.imagemagick.org/script/license.php                            %
00027 %                                                                             %
00028 %  Unless required by applicable law or agreed to in writing, software        %
00029 %  distributed under the License is distributed on an "AS IS" BASIS,          %
00030 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
00031 %  See the License for the specific language governing permissions and        %
00032 %  limitations under the License.                                             %
00033 %                                                                             %
00034 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00035 %
00036 %
00037 %
00038 */
00039 
00040 /*
00041   Include declarations.
00042 */
00043 #include "wand/studio.h"
00044 #include "wand/MagickWand.h"
00045 #include "wand/mogrify-private.h"
00046 
00047 /*
00048 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00049 %                                                                             %
00050 %                                                                             %
00051 %                                                                             %
00052 +    M o n t a g e I m a g e C o m m a n d                                    %
00053 %                                                                             %
00054 %                                                                             %
00055 %                                                                             %
00056 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00057 %
00058 %  MontageImageCommand() reads one or more images, applies one or more image
00059 %  processing operations, and writes out the image in the same or
00060 %  differing format.
00061 %
00062 %  The format of the MontageImageCommand method is:
00063 %
00064 %      MagickBooleanType MontageImageCommand(ImageInfo *image_info,int argc,
00065 %        char **argv,char **metadata,ExceptionInfo *exception)
00066 %
00067 %  A description of each parameter follows:
00068 %
00069 %    o image_info: the image info.
00070 %
00071 %    o argc: the number of elements in the argument vector.
00072 %
00073 %    o argv: A text array containing the command line arguments.
00074 %
00075 %    o metadata: any metadata is returned here.
00076 %
00077 %    o exception: return any errors or warnings in this structure.
00078 %
00079 */
00080 
00081 static void MontageUsage(void)
00082 {
00083   const char
00084     **p;
00085 
00086   static const char
00087     *miscellaneous[]=
00088     {
00089       "-debug events        display copious debugging information",
00090       "-help                print program options",
00091       "-list type           print a list of supported option arguments",
00092       "-log format          format of debugging information",
00093       "-version             print version information",
00094       (char *) NULL
00095     },
00096     *operators[]=
00097     {
00098       " annotate geometry text",
00099       "                     annotate the image with text",
00100       "-blur geometry      reduce image noise and reduce detail levels",
00101       "-border geometry     surround image with a border of color",
00102       "-crop geometry       preferred size and location of the cropped image",
00103       "-flatten             flatten a sequence of images",
00104       "-flip                flip image in the vertical direction",
00105       "-flop                flop image in the horizontal direction",
00106       "-frame geometry      surround image with an ornamental border",
00107       "-monochrome          transform image to black and white",
00108       "-polaroid angle      simulate a Polaroid picture",
00109       "-repage geometry     size and location of an image canvas (operator)",
00110       "-resize geometry     resize the image",
00111       "-rotate degrees      apply Paeth rotation to the image",
00112       "-strip               strip image of all profiles and comments",
00113       "-transform           affine transform image",
00114       "-transparent color   make this color transparent within the image",
00115       "-type type           image type",
00116       (char *) NULL
00117     },
00118     *settings[]=
00119     {
00120       "-adjoin              join images into a single multi-image file",
00121       "-affine matrix       affine transform matrix",
00122       "-alpha option        activate, deactivate, reset, or set the alpha channel",
00123       "-authenticate password",
00124       "                     decipher image with this password",
00125       "-blue-primary point  chromaticity blue primary point",
00126       "-bordercolor color   border color",
00127       "-caption string      assign a caption to an image",
00128       "-channel type        apply option to select image channels",
00129       "-colors value        preferred number of colors in the image",
00130       "-colorspace type     alternate image colorsapce",
00131       "-comment string      annotate image with comment",
00132       "-compose operator    composite operator",
00133       "-compress type       type of pixel compression when writing the image",
00134       "-define format:option",
00135       "                     define one or more image format options",
00136       "-density geometry    horizontal and vertical density of the image",
00137       "-depth value         image depth",
00138       "-display server      query font from this X server",
00139       "-dispose method      layer disposal method",
00140       "-dither method       apply error diffusion to image",
00141       "-draw string         annotate the image with a graphic primitive",
00142       "-encoding type       text encoding type",
00143       "-endian type         endianness (MSB or LSB) of the image",
00144       "-extract geometry    extract area from image",
00145       "-fill color          color to use when filling a graphic primitive",
00146       "-filter type         use this filter when resizing an image",
00147       "-font name           render text with this font",
00148       "-format \"string\"     output formatted image characteristics",
00149       "-gamma value         level of gamma correction",
00150       "-geometry geometry   preferred tile and border sizes",
00151       "-gravity direction   which direction to gravitate towards",
00152       "-green-primary point chromaticity green primary point",
00153       "-identify            identify the format and characteristics of the image",
00154       "-interlace type      type of image interlacing scheme",
00155       "-interpolate method  pixel color interpolation method",
00156       "-label string        assign a label to an image",
00157       "-limit type value    pixel cache resource limit",
00158       "-mattecolor color    frame color",
00159       "-mode type           framing style",
00160       "-monitor             monitor progress",
00161       "-origin geometry     image origin",
00162       "-page geometry       size and location of an image canvas (setting)",
00163       "-pointsize value     font point size",
00164       "-profile filename    add, delete, or apply an image profile",
00165       "-quality value       JPEG/MIFF/PNG compression level",
00166       "-quantize colorspace reduce colors in this colorspace",
00167       "-quiet               suppress all warning messages",
00168       "-red-primary point   chromaticity red primary point",
00169       "-regard-warnings     pay attention to warning messages",
00170       "-respect-parenthesis settings remain in effect until parenthesis boundary",
00171       "-sampling-factor geometry",
00172       "                     horizontal and vertical sampling factor",
00173       "-scenes range        image scene range",
00174       "-seed value          seed a new sequence of pseudo-random numbers",
00175       "-set attribute value set an image attribute",
00176       "-shadow              add a shadow beneath a tile to simulate depth",
00177       "-size geometry       width and height of image",
00178       "-stroke color        color to use when stroking a graphic primitive",
00179       "-texture filename    name of texture to tile onto the image background",
00180       "-thumbnail geometry  create a thumbnail of the image",
00181       "-tile geometry       number of tiles per row and column",
00182       "-transparent-color color",
00183       "                     transparent color",
00184       "-treedepth value     color tree depth",
00185       "-trim                trim image edges",
00186       "-units type          the units of image resolution",
00187       "-verbose             print detailed information about the image",
00188       "-virtual-pixel method",
00189       "                     virtual pixel access method",
00190       "-white-point point   chromaticity white point",
00191       (char *) NULL
00192     },
00193     *sequence_operators[]=
00194     {
00195       "-coalesce            merge a sequence of images",
00196       (char *) NULL
00197     },
00198     *stack_operators[]=
00199     {
00200       "-clone index         clone an image",
00201       (char *) NULL
00202     };
00203 
00204   (void) printf("Version: %s\n",GetMagickVersion((unsigned long *) NULL));
00205   (void) printf("Copyright: %s\n\n",GetMagickCopyright());
00206   (void) printf("Usage: %s [options ...] file [ [options ...] file ...] file\n",
00207     GetClientName());
00208   (void) printf("\nImage Settings:\n");
00209   for (p=settings; *p != (char *) NULL; p++)
00210     (void) printf("  %s\n",*p);
00211   (void) printf("\nImage Operators:\n");
00212   for (p=operators; *p != (char *) NULL; p++)
00213     (void) printf("  %s\n",*p);
00214   (void) printf("\nImage Sequence Operators:\n");
00215   for (p=sequence_operators; *p != (char *) NULL; p++)
00216     (void) printf("  %s\n",*p);
00217   (void) printf("\nImage Stack Operators:\n");
00218   for (p=stack_operators; *p != (char *) NULL; p++)
00219     (void) printf("  %s\n",*p);
00220   (void) printf("\nMiscellaneous Options:\n");
00221   for (p=miscellaneous; *p != (char *) NULL; p++)
00222     (void) printf("  %s\n",*p);
00223   (void) printf(
00224     "\nIn addition to those listed above, you can specify these standard X\n");
00225   (void) printf(
00226     "resources as command line options:  -background, -bordercolor,\n");
00227   (void) printf(
00228     "-borderwidth, -font, -mattecolor, or -title\n");
00229   (void) printf(
00230     "\nBy default, the image format of `file' is determined by its magic\n");
00231   (void) printf(
00232     "number.  To specify a particular image format, precede the filename\n");
00233   (void) printf(
00234     "with an image format name and a colon (i.e. ps:image) or specify the\n");
00235   (void) printf(
00236     "image type as the filename suffix (i.e. image.ps).  Specify 'file' as\n");
00237   (void) printf("'-' for standard input or output.\n");
00238   exit(0);
00239 }
00240 
00241 WandExport MagickBooleanType MontageImageCommand(ImageInfo *image_info,
00242   int argc,char **argv,char **metadata,ExceptionInfo *exception)
00243 {
00244 #define DestroyMontage() \
00245 { \
00246   if (montage_image != (Image *) NULL) \
00247     montage_image=DestroyImageList(montage_image); \
00248   DestroyImageStack(); \
00249   for (i=0; i < (long) argc; i++) \
00250     argv[i]=DestroyString(argv[i]); \
00251   argv=(char **) RelinquishMagickMemory(argv); \
00252 }
00253 #define ThrowMontageException(asperity,tag,option) \
00254 { \
00255   (void) ThrowMagickException(exception,GetMagickModule(),asperity,tag,"`%s'", \
00256     option); \
00257   DestroyMontage(); \
00258   return(MagickFalse); \
00259 }
00260 #define ThrowMontageInvalidArgumentException(option,argument) \
00261 { \
00262   (void) ThrowMagickException(exception,GetMagickModule(),OptionError, \
00263     "InvalidArgument","`%s': %s",argument,option); \
00264   DestroyMontage(); \
00265   return(MagickFalse); \
00266 }
00267 
00268   char
00269     *option,
00270     *transparent_color;
00271 
00272   const char
00273     *format;
00274 
00275   Image
00276     *image,
00277     *montage_image;
00278 
00279   ImageStack
00280     image_stack[MaxImageStackDepth+1];
00281 
00282   long
00283     first_scene,
00284     j,
00285     k,
00286     last_scene,
00287     scene;
00288 
00289   MagickBooleanType
00290     fire,
00291     pend;
00292 
00293   MagickStatusType
00294     status;
00295 
00296   MontageInfo
00297     *montage_info;
00298 
00299   register long
00300     i;
00301 
00302   /*
00303     Set defaults.
00304   */
00305   assert(image_info != (ImageInfo *) NULL);
00306   assert(image_info->signature == MagickSignature);
00307   if (image_info->debug != MagickFalse)
00308     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00309   assert(exception != (ExceptionInfo *) NULL);
00310   if (argc == 2)
00311     {
00312       option=argv[1];
00313       if ((LocaleCompare("version",option+1) == 0) ||
00314           (LocaleCompare("-version",option+1) == 0))
00315         {
00316           (void) fprintf(stdout,"Version: %s\n",
00317             GetMagickVersion((unsigned long *) NULL));
00318           (void) fprintf(stdout,"Copyright: %s\n\n",GetMagickCopyright());
00319           return(MagickFalse);
00320         }
00321     }
00322   if (argc < 3)
00323    MontageUsage();
00324   format="%w,%h,%m";
00325   first_scene=0;
00326   j=1;
00327   k=0;
00328   last_scene=0;
00329   montage_image=NewImageList();
00330   montage_info=CloneMontageInfo(image_info,(MontageInfo *) NULL);
00331   NewImageStack();
00332   option=(char *) NULL;
00333   pend=MagickFalse;
00334   scene=0;
00335   status=MagickFalse;
00336   transparent_color=(char *) NULL;
00337   /*
00338     Parse command line.
00339   */
00340   ReadCommandlLine(argc,&argv);
00341   status=ExpandFilenames(&argc,&argv);
00342   if (status == MagickFalse)
00343     ThrowMontageException(ResourceLimitError,"MemoryAllocationFailed",
00344       strerror(errno));
00345   for (i=1; i < (long) (argc-1); i++)
00346   {
00347     option=argv[i];
00348     if (LocaleCompare(option,"(") == 0)
00349       {
00350         FireImageStack(MagickTrue,MagickTrue,pend);
00351         if (k == MaxImageStackDepth)
00352           ThrowMontageException(OptionError,"ParenthesisNestedTooDeeply",
00353             option);
00354         PushImageStack();
00355         continue;
00356       }
00357     if (LocaleCompare(option,")") == 0)
00358       {
00359         FireImageStack(MagickTrue,MagickTrue,MagickTrue);
00360         if (k == 0)
00361           ThrowMontageException(OptionError,"UnableToParseExpression",option);
00362         PopImageStack();
00363         continue;
00364       }
00365     if (IsMagickOption(option) == MagickFalse)
00366       {
00367         Image
00368           *images;
00369 
00370         FireImageStack(MagickTrue,MagickTrue,pend);
00371         for (scene=first_scene; scene <= last_scene ; scene++)
00372         {
00373           char
00374             *filename;
00375 
00376           /*
00377             Option is a file name: begin by reading image from specified file.
00378           */
00379           filename=argv[i];
00380           if ((LocaleCompare(filename,"--") == 0) && (i < (argc-1)))
00381             filename=argv[++i];
00382           (void) CopyMagickString(image_info->filename,filename,MaxTextExtent);
00383           if (first_scene != last_scene)
00384             {
00385               char
00386                 filename[MaxTextExtent];
00387 
00388               /*
00389                 Form filename for multi-part images.
00390               */
00391               (void) InterpretImageFilename(filename,MaxTextExtent,
00392                 image_info->filename,(int) scene);
00393               if (LocaleCompare(filename,image_info->filename) == 0)
00394                 (void) FormatMagickString(filename,MaxTextExtent,"%s.%lu",
00395                   image_info->filename,scene);
00396               (void) CopyMagickString(image_info->filename,filename,
00397                 MaxTextExtent);
00398             }
00399           (void) CloneString(&image_info->font,montage_info->font);
00400           images=ReadImages(image_info,exception);
00401           status&=(images != (Image *) NULL) &&
00402             (exception->severity < ErrorException);
00403           if (images == (Image *) NULL)
00404             continue;
00405           AppendImageStack(images);
00406         }
00407         continue;
00408       }
00409     pend=image != (Image *) NULL ? MagickTrue : MagickFalse;
00410     switch (*(option+1))
00411     {
00412       case 'a':
00413       {
00414         if (LocaleCompare("adjoin",option+1) == 0)
00415           break;
00416         if (LocaleCompare("affine",option+1) == 0)
00417           {
00418             if (*option == '+')
00419               break;
00420             i++;
00421             if (i == (long) (argc-1))
00422               ThrowMontageException(OptionError,"MissingArgument",option);
00423             if (IsGeometry(argv[i]) == MagickFalse)
00424               ThrowMontageInvalidArgumentException(option,argv[i]);
00425             break;
00426           }
00427         if (LocaleCompare("alpha",option+1) == 0)
00428           {
00429             long
00430               type;
00431 
00432             if (*option == '+')
00433               break;
00434             i++;
00435             if (i == (long) argc)
00436               ThrowMontageException(OptionError,"MissingArgument",option);
00437             type=ParseMagickOption(MagickAlphaOptions,MagickFalse,argv[i]);
00438             if (type < 0)
00439               ThrowMontageException(OptionError,"UnrecognizedAlphaChannelType",
00440                 argv[i]);
00441             break;
00442           }
00443         if (LocaleCompare("annotate",option+1) == 0)
00444           {
00445             if (*option == '+')
00446               break;
00447             i++;
00448             if (i == (long) (argc-1))
00449               ThrowMontageException(OptionError,"MissingArgument",option);
00450             if (IsGeometry(argv[i]) == MagickFalse)
00451               ThrowMontageInvalidArgumentException(option,argv[i]);
00452             if (i == (long) (argc-1))
00453               ThrowMontageException(OptionError,"MissingArgument",option);
00454             i++;
00455             break;
00456           }
00457         if (LocaleCompare("authenticate",option+1) == 0)
00458           {
00459             if (*option == '+')
00460               break;
00461             i++;
00462             if (i == (long) argc)
00463               ThrowMontageException(OptionError,"MissingArgument",option);
00464             break;
00465           }
00466         ThrowMontageException(OptionError,"UnrecognizedOption",option)
00467       }
00468       case 'b':
00469       {
00470         if (LocaleCompare("background",option+1) == 0)
00471           {
00472             if (*option == '+')
00473               break;
00474             i++;
00475             if (i == (long) argc)
00476               ThrowMontageException(OptionError,"MissingArgument",option);
00477             (void) QueryColorDatabase(argv[i],
00478               &montage_info->background_color,exception);
00479             break;
00480           }
00481         if (LocaleCompare("blue-primary",option+1) == 0)
00482           {
00483             if (*option == '+')
00484               break;
00485             i++;
00486             if (i == (long) argc)
00487               ThrowMontageException(OptionError,"MissingArgument",option);
00488             if (IsGeometry(argv[i]) == MagickFalse)
00489               ThrowMontageInvalidArgumentException(option,argv[i]);
00490             break;
00491           }
00492         if (LocaleCompare("blur",option+1) == 0)
00493           {
00494             if (*option == '+')
00495               break;
00496             i++;
00497             if (i == (long) argc)
00498               ThrowMontageException(OptionError,"MissingArgument",option);
00499             if (IsGeometry(argv[i]) == MagickFalse)
00500               ThrowMontageInvalidArgumentException(option,argv[i]);
00501             break;
00502           }
00503         if (LocaleCompare("border",option+1) == 0)
00504           {
00505             montage_info->border_width=0;
00506             if (*option == '+')
00507               break;
00508             i++;
00509             if (i == (long) argc)
00510               ThrowMontageException(OptionError,"MissingArgument",option);
00511             if (IsGeometry(argv[i]) == MagickFalse)
00512               ThrowMontageInvalidArgumentException(option,argv[i]);
00513             montage_info->border_width=(unsigned long) atol(argv[i]);
00514             break;
00515           }
00516         if (LocaleCompare("bordercolor",option+1) == 0)
00517           {
00518             if (*option == '+')
00519               break;
00520             i++;
00521             if (i == (long) argc)
00522               ThrowMontageException(OptionError,"MissingArgument",option);
00523             (void) QueryColorDatabase(argv[i],&montage_info->border_color,
00524               exception);
00525             break;
00526           }
00527         if (LocaleCompare("borderwidth",option+1) == 0)
00528           {
00529             montage_info->border_width=0;
00530             if (*option == '+')
00531               break;
00532             i++;
00533             if (i == (long) argc)
00534               ThrowMontageException(OptionError,"MissingArgument",option);
00535             if (IsGeometry(argv[i]) == MagickFalse)
00536               ThrowMontageInvalidArgumentException(option,argv[i]);
00537             montage_info->border_width=(unsigned long) atol(argv[i]);
00538             break;
00539           }
00540         ThrowMontageException(OptionError,"UnrecognizedOption",option)
00541       }
00542       case 'c':
00543       {
00544         if (LocaleCompare("cache",option+1) == 0)
00545           {
00546             if (*option == '+')
00547               break;
00548             i++;
00549             if (i == (long) argc)
00550               ThrowMontageException(OptionError,"MissingArgument",option);
00551             if (IsGeometry(argv[i]) == MagickFalse)
00552               ThrowMontageInvalidArgumentException(option,argv[i]);
00553             break;
00554           }
00555         if (LocaleCompare("caption",option+1) == 0)
00556           {
00557             if (*option == '+')
00558               break;
00559             i++;
00560             if (i == (long) argc)
00561               ThrowMontageException(OptionError,"MissingArgument",option);
00562             break;
00563           }
00564         if (LocaleCompare("channel",option+1) == 0)
00565           {
00566             long
00567               channel;
00568 
00569             if (*option == '+')
00570               break;
00571             i++;
00572             if (i == (long) (argc-1))
00573               ThrowMontageException(OptionError,"MissingArgument",option);
00574             channel=ParseChannelOption(argv[i]);
00575             if (channel < 0)
00576               ThrowMontageException(OptionError,"UnrecognizedChannelType",
00577                 argv[i]);
00578             break;
00579           }
00580         if (LocaleCompare("clone",option+1) == 0)
00581           {
00582             Image
00583               *clone_images;
00584 
00585             clone_images=image;
00586             if (k != 0)
00587               clone_images=image_stack[k-1].image;
00588             if (clone_images == (Image *) NULL)
00589               ThrowMontageException(ImageError,"ImageSequenceRequired",option);
00590             if (*option == '+')
00591               clone_images=CloneImages(clone_images,"-1",exception);
00592             else
00593               {
00594                 i++;
00595                 if (i == (long) (argc-1))
00596                   ThrowMontageException(OptionError,"MissingArgument",option);
00597                 if (IsSceneGeometry(argv[i],MagickFalse) == MagickFalse)
00598                   ThrowMontageInvalidArgumentException(option,argv[i]);
00599                 clone_images=CloneImages(clone_images,argv[i],exception);
00600               }
00601             if (clone_images == (Image *) NULL)
00602               ThrowMontageException(OptionError,"NoSuchImage",option);
00603             FireImageStack(MagickTrue,MagickTrue,MagickTrue);
00604             AppendImageStack(clone_images);
00605             break;
00606           }
00607         if (LocaleCompare("coalesce",option+1) == 0)
00608           break;
00609         if (LocaleCompare("colors",option+1) == 0)
00610           {
00611             if (*option == '+')
00612               break;
00613             i++;
00614             if (i == (long) argc)
00615               ThrowMontageException(OptionError,"MissingArgument",option);
00616             if (IsGeometry(argv[i]) == MagickFalse)
00617               ThrowMontageInvalidArgumentException(option,argv[i]);
00618             break;
00619           }
00620         if (LocaleCompare("colorspace",option+1) == 0)
00621           {
00622             long
00623               colorspace;
00624 
00625             if (*option == '+')
00626               break;
00627             i++;
00628             if (i == (long) argc)
00629               ThrowMontageException(OptionError,"MissingArgument",option);
00630             colorspace=ParseMagickOption(MagickColorspaceOptions,
00631               MagickFalse,argv[i]);
00632             if (colorspace < 0)
00633               ThrowMontageException(OptionError,"UnrecognizedColorspace",
00634                 argv[i]);
00635             break;
00636           }
00637         if (LocaleCompare("comment",option+1) == 0)
00638           {
00639             if (*option == '+')
00640               break;
00641             i++;
00642             if (i == (long) argc)
00643               ThrowMontageException(OptionError,"MissingArgument",option);
00644             break;
00645           }
00646         if (LocaleCompare("compose",option+1) == 0)
00647           {
00648             long
00649               compose;
00650 
00651             if (*option == '+')
00652               break;
00653             i++;
00654             if (i == (long) argc)
00655               ThrowMontageException(OptionError,"MissingArgument",option);
00656             compose=ParseMagickOption(MagickComposeOptions,MagickFalse,argv[i]);
00657             if (compose < 0)
00658               ThrowMontageException(OptionError,"UnrecognizedComposeOperator",
00659                 argv[i]);
00660             break;
00661           }
00662         if (LocaleCompare("compress",option+1) == 0)
00663           {
00664             long
00665               compress;
00666 
00667             if (*option == '+')
00668               break;
00669             i++;
00670             if (i == (long) argc)
00671               ThrowMontageException(OptionError,"MissingArgument",option);
00672             compress=ParseMagickOption(MagickCompressOptions,MagickFalse,
00673               argv[i]);
00674             if (compress < 0)
00675               ThrowMontageException(OptionError,"UnrecognizedCompressType",
00676                 argv[i]);
00677             break;
00678           }
00679         if (LocaleCompare("crop",option+1) == 0)
00680           {
00681             if (*option == '+')
00682               break;
00683             i++;
00684             if (i == (long) argc)
00685               ThrowMontageException(OptionError,"MissingArgument",option);
00686             if (IsGeometry(argv[i]) == MagickFalse)
00687               ThrowMontageInvalidArgumentException(option,argv[i]);
00688             break;
00689           }
00690         ThrowMontageException(OptionError,"UnrecognizedOption",option)
00691       }
00692       case 'd':
00693       {
00694         if (LocaleCompare("debug",option+1) == 0)
00695           {
00696             long
00697               event;
00698 
00699             if (*option == '+')
00700               break;
00701             i++;
00702             if (i == (long) argc)
00703               ThrowMontageException(OptionError,"MissingArgument",option);
00704             event=ParseMagickOption(MagickLogEventOptions,MagickFalse,argv[i]);
00705             if (event < 0)
00706               ThrowMontageException(OptionError,"UnrecognizedEventType",
00707                 argv[i]);
00708             (void) SetLogEventMask(argv[i]);
00709             break;
00710           }
00711         if (LocaleCompare("define",option+1) == 0)
00712           {
00713             i++;
00714             if (i == (long) argc)
00715               ThrowMontageException(OptionError,"MissingArgument",option);
00716             if (*option == '+')
00717               {
00718                 const char
00719                   *define;
00720 
00721                 define=GetImageOption(image_info,argv[i]);
00722                 if (define == (const char *) NULL)
00723                   ThrowMontageException(OptionError,"NoSuchOption",argv[i]);
00724                 break;
00725               }
00726             break;
00727           }
00728         if (LocaleCompare("density",option+1) == 0)
00729           {
00730             if (*option == '+')
00731               break;
00732             i++;
00733             if (i == (long) argc)
00734               ThrowMontageException(OptionError,"MissingArgument",option);
00735             if (IsGeometry(argv[i]) == MagickFalse)
00736               ThrowMontageInvalidArgumentException(option,argv[i]);
00737             break;
00738           }
00739         if (LocaleCompare("depth",option+1) == 0)
00740           {
00741             if (*option == '+')
00742               break;
00743             i++;
00744             if (i == (long) argc)
00745               ThrowMontageException(OptionError,"MissingArgument",option);
00746             if (IsGeometry(argv[i]) == MagickFalse)
00747               ThrowMontageInvalidArgumentException(option,argv[i]);
00748             break;
00749           }
00750         if (LocaleCompare("display",option+1) == 0)
00751           {
00752             if (*option == '+')
00753               break;
00754             i++;
00755             if (i == (long) argc)
00756               ThrowMontageException(OptionError,"MissingArgument",option);
00757             break;
00758           }
00759         if (LocaleCompare("dispose",option+1) == 0)
00760           {
00761             long
00762               dispose;
00763 
00764             if (*option == '+')
00765               break;
00766             i++;
00767             if (i == (long) argc)
00768               ThrowMontageException(OptionError,"MissingArgument",option);
00769             dispose=ParseMagickOption(MagickDisposeOptions,MagickFalse,argv[i]);
00770             if (dispose < 0)
00771               ThrowMontageException(OptionError,"UnrecognizedDisposeMethod",
00772                 argv[i]);
00773             break;
00774           }
00775         if (LocaleCompare("dither",option+1) == 0)
00776           {
00777             long
00778               method;
00779 
00780             if (*option == '+')
00781               break;
00782             i++;
00783             if (i == (long) argc)
00784               ThrowMontageException(OptionError,"MissingArgument",option);
00785             method=ParseMagickOption(MagickDitherOptions,MagickFalse,argv[i]);
00786             if (method < 0)
00787               ThrowMontageException(OptionError,"UnrecognizedDitherMethod",
00788                 argv[i]);
00789             break;
00790           }
00791         if (LocaleCompare("draw",option+1) == 0)
00792           {
00793             if (*option == '+')
00794               break;
00795             i++;
00796             if (i == (long) argc)
00797               ThrowMontageException(OptionError,"MissingArgument",option);
00798             break;
00799           }
00800         ThrowMontageException(OptionError,"UnrecognizedOption",option)
00801       }
00802       case 'e':
00803       {
00804         if (LocaleCompare("encoding",option+1) == 0)
00805           {
00806             if (*option == '+')
00807               break;
00808             i++;
00809             if (i == (long) argc)
00810               ThrowMontageException(OptionError,"MissingArgument",option);
00811             break;
00812           }
00813         if (LocaleCompare("endian",option+1) == 0)
00814           {
00815             long
00816               endian;
00817 
00818             if (*option == '+')
00819               break;
00820             i++;
00821             if (i == (long) argc)
00822               ThrowMontageException(OptionError,"MissingArgument",option);
00823             endian=ParseMagickOption(MagickEndianOptions,MagickFalse,
00824               argv[i]);
00825             if (endian < 0)
00826               ThrowMontageException(OptionError,"UnrecognizedEndianType",
00827                 argv[i]);
00828             break;
00829           }
00830         ThrowMontageException(OptionError,"UnrecognizedOption",option)
00831       }
00832       case 'f':
00833       {
00834         if (LocaleCompare("fill",option+1) == 0)
00835           {
00836             (void) QueryColorDatabase("none",&montage_info->fill,exception);
00837             if (*option == '+')
00838               break;
00839             i++;
00840             if (i == (long) argc)
00841               ThrowMontageException(OptionError,"MissingArgument",option);
00842             (void) QueryColorDatabase(argv[i],&montage_info->fill,
00843               exception);
00844             break;
00845           }
00846         if (LocaleCompare("filter",option+1) == 0)
00847           {
00848             long
00849               filter;
00850 
00851             if (*option == '+')
00852               break;
00853             i++;
00854             if (i == (long) argc)
00855               ThrowMontageException(OptionError,"MissingArgument",option);
00856             filter=ParseMagickOption(MagickFilterOptions,MagickFalse,argv[i]);
00857             if (filter < 0)
00858               ThrowMontageException(OptionError,"UnrecognizedImageFilter",
00859                 argv[i]);
00860             break;
00861           }
00862         if (LocaleCompare("flatten",option+1) == 0)
00863           break;
00864         if (LocaleCompare("flip",option+1) == 0)
00865           break;
00866         if (LocaleCompare("flop",option+1) == 0)
00867           break;
00868         if (LocaleCompare("font",option+1) == 0)
00869           {
00870             if (*option == '+')
00871               break;
00872             i++;
00873             if (i == (long) argc)
00874               ThrowMontageException(OptionError,"MissingArgument",option);
00875             (void) CloneString(&montage_info->font,argv[i]);
00876             break;
00877           }
00878         if (LocaleCompare("format",option+1) == 0)
00879           {
00880             if (*option == '+')
00881               break;
00882             i++;
00883             if (i == (long) argc)
00884               ThrowMontageException(OptionError,"MissingArgument",option);
00885             format=argv[i];
00886             break;
00887           }
00888         if (LocaleCompare("frame",option+1) == 0)
00889           {
00890             (void) CopyMagickString(argv[i]+1,"sans",MaxTextExtent);
00891             (void) CloneString(&montage_info->frame,(char *) NULL);
00892             if (*option == '+')
00893               break;
00894             i++;
00895             if (i == (long) argc)
00896               ThrowMontageException(OptionError,"MissingArgument",option);
00897             if (IsGeometry(argv[i]) == MagickFalse)
00898               ThrowMontageInvalidArgumentException(option,argv[i]);
00899             (void) CloneString(&montage_info->frame,argv[i]);
00900             break;
00901           }
00902         ThrowMontageException(OptionError,"UnrecognizedOption",option)
00903       }
00904       case 'g':
00905       {
00906         if (LocaleCompare("gamma",option+1) == 0)
00907           {
00908             i++;
00909             if (i == (long) argc)
00910               ThrowMontageException(OptionError,"MissingArgument",option);
00911             if (IsGeometry(argv[i]) == MagickFalse)
00912               ThrowMontageInvalidArgumentException(option,argv[i]);
00913             break;
00914           }
00915         if (LocaleCompare("geometry",option+1) == 0)
00916           {
00917             (void) CloneString(&montage_info->geometry,(char *) NULL);
00918             if (*option == '+')
00919               break;
00920             i++;
00921             if (i == (long) argc)
00922               ThrowMontageException(OptionError,"MissingArgument",option);
00923             if (IsGeometry(argv[i]) == MagickFalse)
00924               ThrowMontageInvalidArgumentException(option,argv[i]);
00925             (void) CloneString(&montage_info->geometry,argv[i]);
00926             break;
00927           }
00928         if (LocaleCompare("gravity",option+1) == 0)
00929           {
00930             long
00931               gravity;
00932 
00933             montage_info->gravity=UndefinedGravity;
00934             if (*option == '+')
00935               break;
00936             i++;
00937             if (i == (long) argc)
00938               ThrowMontageException(OptionError,"MissingArgument",option);
00939             gravity=ParseMagickOption(MagickGravityOptions,MagickFalse,
00940               argv[i]);
00941             if (gravity < 0)
00942               ThrowMontageException(OptionError,"UnrecognizedGravityType",
00943                 argv[i]);
00944             montage_info->gravity=(GravityType) gravity;
00945             break;
00946           }
00947         if (LocaleCompare("green-primary",option+1) == 0)
00948           {
00949             if (*option == '+')
00950               break;
00951             i++;
00952             if (i == (long) argc)
00953               ThrowMontageException(OptionError,"MissingArgument",option);
00954             if (IsGeometry(argv[i]) == MagickFalse)
00955               ThrowMontageInvalidArgumentException(option,argv[i]);
00956             break;
00957           }
00958         ThrowMontageException(OptionError,"UnrecognizedOption",option)
00959       }
00960       case 'h':
00961       {
00962         if ((LocaleCompare("help",option+1) == 0) ||
00963             (LocaleCompare("-help",option+1) == 0))
00964           MontageUsage();
00965         ThrowMontageException(OptionError,"UnrecognizedOption",option)
00966       }
00967       case 'i':
00968       {
00969         if (LocaleCompare("identify",option+1) == 0)
00970           break;
00971         if (LocaleCompare("interlace",option+1) == 0)
00972           {
00973             long
00974               interlace;
00975 
00976             if (*option == '+')
00977               break;
00978             i++;
00979             if (i == (long) argc)
00980               ThrowMontageException(OptionError,"MissingArgument",option);
00981             interlace=ParseMagickOption(MagickInterlaceOptions,MagickFalse,
00982               argv[i]);
00983             if (interlace < 0)
00984               ThrowMontageException(OptionError,"UnrecognizedInterlaceType",
00985                 argv[i]);
00986             break;
00987           }
00988         if (LocaleCompare("interpolate",option+1) == 0)
00989           {
00990             long
00991               interpolate;
00992 
00993             if (*option == '+')
00994               break;
00995             i++;
00996             if (i == (long) argc)
00997               ThrowMontageException(OptionError,"MissingArgument",option);
00998             interpolate=ParseMagickOption(MagickInterpolateOptions,MagickFalse,
00999               argv[i]);
01000             if (interpolate < 0)
01001               ThrowMontageException(OptionError,"UnrecognizedInterpolateMethod",
01002                 argv[i]);
01003             break;
01004           }
01005         ThrowMontageException(OptionError,"UnrecognizedOption",option)
01006       }
01007       case 'l':
01008       {
01009         if (LocaleCompare("label",option+1) == 0)
01010           {
01011             if (*option == '+')
01012               break;
01013             i++;
01014             if (i == (long) argc)
01015               ThrowMontageException(OptionError,"MissingArgument",option);
01016             break;
01017           }
01018         if (LocaleCompare("limit",option+1) == 0)
01019           {
01020             char
01021               *p;
01022 
01023             long
01024               resource;
01025 
01026             if (*option == '+')
01027               break;
01028             i++;
01029             if (i == (long) argc)
01030               ThrowMontageException(OptionError,"MissingArgument",option);
01031             resource=ParseMagickOption(MagickResourceOptions,MagickFalse,
01032               argv[i]);
01033             if (resource < 0)
01034               ThrowMontageException(OptionError,"UnrecognizedResourceType",
01035                 argv[i]);
01036             i++;
01037             if (i == (long) argc)
01038               ThrowMontageException(OptionError,"MissingArgument",option);
01039             (void) strtod(argv[i],&p);
01040             if ((p == argv[i]) && (LocaleCompare("unlimited",argv[i]) != 0))
01041               ThrowMontageInvalidArgumentException(option,argv[i]);
01042             break;
01043           }
01044         if (LocaleCompare("log",option+1) == 0)
01045           {
01046             if (*option == '+')
01047               break;
01048             i++;
01049             if ((i == (long) argc) ||
01050                 (strchr(argv[i],'%') == (char *) NULL))
01051               ThrowMontageException(OptionError,"MissingArgument",option);
01052             break;
01053           }
01054         ThrowMontageException(OptionError,"UnrecognizedOption",option)
01055       }
01056       case 'm':
01057       {
01058         if (LocaleCompare("matte",option+1) == 0)
01059           break;
01060         if (LocaleCompare("mattecolor",option+1) == 0)
01061           {
01062             if (*option == '+')
01063               break;
01064             i++;
01065             if (i == (long) argc)
01066               ThrowMontageException(OptionError,"MissingArgument",option);
01067             (void) QueryColorDatabase(argv[i],&montage_info->matte_color,
01068               exception);
01069             break;
01070           }
01071         if (LocaleCompare("mode",option+1) == 0)
01072           {
01073             MontageMode
01074               mode;
01075 
01076             if (*option == '+')
01077               break;
01078             i++;
01079             if (i == (long) argc)
01080               ThrowMontageException(OptionError,"MissingArgument",option);
01081             mode=UndefinedMode;
01082             if (LocaleCompare("frame",argv[i]) == 0)
01083               {
01084                 mode=FrameMode;
01085                 (void) CloneString(&montage_info->frame,"15x15+3+3");
01086                 montage_info->shadow=MagickTrue;
01087                 break;
01088               }
01089             if (LocaleCompare("unframe",argv[i]) == 0)
01090               {
01091                 mode=UnframeMode;
01092                 montage_info->frame=(char *) NULL;
01093                 montage_info->shadow=MagickFalse;
01094                 montage_info->border_width=0;
01095                 break;
01096               }
01097             if (LocaleCompare("concatenate",argv[i]) == 0)
01098               {
01099                 mode=ConcatenateMode;
01100                 montage_info->frame=(char *) NULL;
01101                 montage_info->shadow=MagickFalse;
01102                 montage_info->gravity=(GravityType) NorthWestGravity;
01103                 (void) CloneString(&montage_info->geometry,"+0+0");
01104                 montage_info->border_width=0;
01105                 break;
01106               }
01107             if (mode == UndefinedMode)
01108               ThrowMontageException(OptionError,"UnrecognizedImageMode",
01109                 argv[i]);
01110             break;
01111           }
01112         if (LocaleCompare("monitor",option+1) == 0)
01113           break;
01114         if (LocaleCompare("monochrome",option+1) == 0)
01115           {
01116             if (*option == '+')
01117               break;
01118             break;
01119           }
01120         ThrowMontageException(OptionError,"UnrecognizedOption",option)
01121       }
01122       case 'n':
01123       {
01124         if (LocaleCompare("noop",option+1) == 0)
01125           break;
01126         ThrowMontageException(OptionError,"UnrecognizedOption",option)
01127       }
01128       case 'o':
01129       {
01130         if (LocaleCompare("origin",option+1) == 0)
01131           {
01132             if (*option == '+')
01133               break;
01134             i++;
01135             if (i == (long) argc)
01136               ThrowMontageException(OptionError,"MissingArgument",option);
01137             if (IsGeometry(argv[i]) == MagickFalse)
01138               ThrowMontageInvalidArgumentException(option,argv[i]);
01139             break;
01140           }
01141         ThrowMontageException(OptionError,"UnrecognizedOption",option)
01142       }
01143       case 'p':
01144       {
01145         if (LocaleCompare("page",option+1) == 0)
01146           {
01147             if (*option == '+')
01148               break;
01149             i++;
01150             if (i == (long) argc)
01151               ThrowMontageException(OptionError,"MissingArgument",option);
01152             break;
01153           }
01154         if (LocaleCompare("pointsize",option+1) == 0)
01155           {
01156             montage_info->pointsize=12;
01157             if (*option == '+')
01158               break;
01159             i++;
01160             if (i == (long) argc)
01161               ThrowMontageException(OptionError,"MissingArgument",option);
01162             if (IsGeometry(argv[i]) == MagickFalse)
01163               ThrowMontageInvalidArgumentException(option,argv[i]);
01164             montage_info->pointsize=atof(argv[i]);
01165             break;
01166           }
01167         if (LocaleCompare("polaroid",option+1) == 0)
01168           {
01169             if (*option == '+')
01170               break;
01171             i++;
01172             if (i == (long) (argc-1))
01173               ThrowMontageException(OptionError,"MissingArgument",option);
01174             if (IsGeometry(argv[i]) == MagickFalse)
01175               ThrowMontageInvalidArgumentException(option,argv[i]);
01176             break;
01177           }
01178         if (LocaleCompare("profile",option+1) == 0)
01179           {
01180             i++;
01181             if (i == (long) (argc-1))
01182               ThrowMontageException(OptionError,"MissingArgument",option);
01183             break;
01184           }
01185         ThrowMontageException(OptionError,"UnrecognizedOption",option)
01186       }
01187       case 'q':
01188       {
01189         if (LocaleCompare("quality",option+1) == 0)
01190           {
01191             if (*option == '+')
01192               break;
01193             i++;
01194             if (i == (long) argc)
01195               ThrowMontageException(OptionError,"MissingArgument",option);
01196             if (IsGeometry(argv[i]) == MagickFalse)
01197               ThrowMontageInvalidArgumentException(option,argv[i]);
01198             break;
01199           }
01200         if (LocaleCompare("quantize",option+1) == 0)
01201           {
01202             long
01203               colorspace;
01204 
01205             if (*option == '+')
01206               break;
01207             i++;
01208             if (i == (long) (argc-1))
01209               ThrowMontageException(OptionError,"MissingArgument",option);
01210             colorspace=ParseMagickOption(MagickColorspaceOptions,
01211               MagickFalse,argv[i]);
01212             if (colorspace < 0)
01213               ThrowMontageException(OptionError,"UnrecognizedColorspace",
01214                 argv[i]);
01215             break;
01216           }
01217         if (LocaleCompare("quiet",option+1) == 0)
01218           break;
01219         ThrowMontageException(OptionError,"UnrecognizedOption",option)
01220       }
01221       case 'r':
01222       {
01223         if (LocaleCompare("red-primary",option+1) == 0)
01224           {
01225             if (*option == '+')
01226               break;
01227             i++;
01228             if (i == (long) argc)
01229               ThrowMontageException(OptionError,"MissingArgument",option);
01230             if (IsGeometry(argv[i]) == MagickFalse)
01231               ThrowMontageInvalidArgumentException(option,argv[i]);
01232             break;
01233           }
01234         if (LocaleCompare("regard-warnings",option+1) == 0)
01235           break;
01236         if (LocaleCompare("render",option+1) == 0)
01237           break;
01238         if (LocaleCompare("repage",option+1) == 0)
01239           {
01240             if (*option == '+')
01241               break;
01242             i++;
01243             if (i == (long) argc)
01244               ThrowMontageException(OptionError,"MissingArgument",option);
01245             if (IsGeometry(argv[i]) == MagickFalse)
01246               ThrowMontageInvalidArgumentException(option,argv[i]);
01247             break;
01248           }
01249         if (LocaleCompare("resize",option+1) == 0)
01250           {
01251             if (*option == '+')
01252               break;
01253             i++;
01254             if (i == (long) argc)
01255               ThrowMontageException(OptionError,"MissingArgument",option);
01256             if (IsGeometry(argv[i]) == MagickFalse)
01257               ThrowMontageInvalidArgumentException(option,argv[i]);
01258             break;
01259           }
01260         if (LocaleCompare("respect-parenthesis",option+1) == 0)
01261           {
01262             respect_parenthesis=(*option == '-') ? MagickTrue : MagickFalse;
01263             break;
01264           }
01265         if (LocaleCompare("rotate",option+1) == 0)
01266           {
01267             i++;
01268             if (i == (long) argc)
01269               ThrowMontageException(OptionError,"MissingArgument",option);
01270             if (IsGeometry(argv[i]) == MagickFalse)
01271               ThrowMontageInvalidArgumentException(option,argv[i]);
01272             break;
01273           }
01274         ThrowMontageException(OptionError,"UnrecognizedOption",option)
01275       }
01276       case 's':
01277       {
01278         if (LocaleCompare("sampling-factor",option+1) == 0)
01279           {
01280             if (*option == '+')
01281               break;
01282             i++;
01283             if (i == (long) argc)
01284               ThrowMontageException(OptionError,"MissingArgument",option);
01285             if (IsGeometry(argv[i]) == MagickFalse)
01286               ThrowMontageInvalidArgumentException(option,argv[i]);
01287             break;
01288           }
01289         if (LocaleCompare("seed",option+1) == 0)
01290           {
01291             if (*option == '+')
01292               break;
01293             i++;
01294             if (i == (long) (argc-1))
01295               ThrowMontageException(OptionError,"MissingArgument",option);
01296             if (IsGeometry(argv[i]) == MagickFalse)
01297               ThrowMontageInvalidArgumentException(option,argv[i]);
01298             break;
01299           }
01300         if (LocaleCompare("scenes",option+1) == 0)
01301           {
01302             first_scene=0;
01303             last_scene=0;
01304             if (*option == '+')
01305               break;
01306             i++;
01307             if (i == (long) argc)
01308               ThrowMontageException(OptionError,