composite.c

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