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