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