Commit message: do not attempt to write a null image list (thanks to Vinay Rohila)
CVE: CVE-2022-2719
CWE: CWE-617
Vulnerability description: In ImageMagick, a crafted file could trigger an assertion failure when a call to WriteImages was made in MagickWand/operation.c, due to a NULL image list. This could potentially cause a denial of service. This was fixed in upstream ImageMagick version 7.1.0-30.

Project: ImageMagick
File: tim2.c

static inline void deshufflePalette(Image *image,PixelInfo* oldColormap)
{
  const size_t
    pages=image->colors/32,  /* Pages per CLUT */
    blocks=4,  /* Blocks per page */
    colors=8;  /* Colors per block */

  int
    page;

  size_t
    i=0;

  (void) memcpy(oldColormap,image->colormap,(size_t)image->colors*
    sizeof(*oldColormap));

  /*
   * Swap the 2nd and 3rd block in each page
   */
  for (page=0; page < (ssize_t) pages; page++)
  {
    memcpy(&(image->colormap[i+1*colors]),&(oldColormap[i+2*colors]),colors*
      sizeof(PixelInfo));
    memcpy(&(image->colormap[i+2*colors]),&(oldColormap[i+1*colors]),colors*
      sizeof(PixelInfo));

    i+=blocks*colors;
  }
}

Project: ImageMagick
File: tim2.c

ModuleExport void UnregisterTIM2Image(void)
{
  (void) UnregisterMagickInfo("TM2");
}

Project: ImageMagick
File: operation.c

static MagickBooleanType CLISimpleOperatorImage(MagickCLI *cli_wand,
  const char *option, const char *arg1n, const char *arg2n,
  ExceptionInfo *exception)
{
  Image *
    new_image;

  GeometryInfo
    geometry_info;

  RectangleInfo
    geometry;

  MagickStatusType
    flags;

  ssize_t
    parse;

  const char    /* percent escaped versions of the args */
    *arg1,
    *arg2;

#define _image_info       (cli_wand->wand.image_info)
#define _image            (cli_wand->wand.images)
#define _exception        (cli_wand->wand.exception)
#define _draw_info        (cli_wand->draw_info)
#define _quantize_info    (cli_wand->quantize_info)
#define _process_flags    (cli_wand->process_flags)
#define _option_type      ((CommandOptionFlags) cli_wand->command->flags)
#define IfNormalOp        (*option=='-')
#define IfPlusOp          (*option!='-')
#define IsNormalOp        IfNormalOp ? MagickTrue : MagickFalse
#define IsPlusOp          IfNormalOp ? MagickFalse : MagickTrue

  assert(cli_wand != (MagickCLI *) NULL);
  assert(cli_wand->signature == MagickWandSignature);
  assert(cli_wand->wand.signature == MagickWandSignature);
  assert(_image != (Image *) NULL);             /* an image must be present */
  if (cli_wand->wand.debug != MagickFalse)
    (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",cli_wand->wand.name);

  arg1 = arg1n,
  arg2 = arg2n;

  /* Interpret Percent Escapes in Arguments - using first image */
  if ( (((_process_flags & ProcessInterpretProperities) != 0 )
        || ((_option_type & AlwaysInterpretArgsFlag) != 0)
       )  && ((_option_type & NeverInterpretArgsFlag) == 0) ) {
    /* Interpret Percent escapes in argument 1 */
    if (arg1n != (char *) NULL) {
      arg1=InterpretImageProperties(_image_info,_image,arg1n,_exception);
      if (arg1 == (char *) NULL) {
        CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
        arg1=arg1n;  /* use the given argument as is */
      }
    }
    if (arg2n != (char *) NULL) {
      arg2=InterpretImageProperties(_image_info,_image,arg2n,_exception);
      if (arg2 == (char *) NULL) {
        CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
        arg2=arg2n;  /* use the given argument as is */
      }
    }
  }
#undef _process_flags
#undef _option_type

#if 0
  (void) FormatLocaleFile(stderr,
    "CLISimpleOperatorImage: \"%s\" \"%s\" \"%s\"\n",option,arg1,arg2);
#endif

  new_image = (Image *) NULL; /* the replacement image, if not null at end */
  SetGeometryInfo(&geometry_info);

  switch (*(option+1))
  {
    case 'a':
    {
      if (LocaleCompare("adaptive-blur",option+1) == 0)
        {
          flags=ParseGeometry(arg1,&geometry_info);
          if ((flags & (RhoValue|SigmaValue)) == 0)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          if ((flags & SigmaValue) == 0)
            geometry_info.sigma=1.0;
          new_image=AdaptiveBlurImage(_image,geometry_info.rho,
            geometry_info.sigma,_exception);
          break;
        }
      if (LocaleCompare("adaptive-resize",option+1) == 0)
        {
          /* FUTURE: Roll into a resize special operator */
          if (IsGeometry(arg1) == MagickFalse)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
          new_image=AdaptiveResizeImage(_image,geometry.width,geometry.height,
            _exception);
          break;
        }
      if (LocaleCompare("adaptive-sharpen",option+1) == 0)
        {
          flags=ParseGeometry(arg1,&geometry_info);
          if ((flags & (RhoValue|SigmaValue)) == 0)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          if ((flags & SigmaValue) == 0)
            geometry_info.sigma=1.0;
          new_image=AdaptiveSharpenImage(_image,geometry_info.rho,
            geometry_info.sigma,_exception);
          break;
        }
      if (LocaleCompare("alpha",option+1) == 0)
        {
          parse=ParseCommandOption(MagickAlphaChannelOptions,MagickFalse,arg1);
          if (parse < 0)
            CLIWandExceptArgBreak(OptionError,"UnrecognizedAlphaChannelOption",
              option,arg1);
          (void) SetImageAlphaChannel(_image,(AlphaChannelOption) parse,
            _exception);
          break;
        }
      if (LocaleCompare("annotate",option+1) == 0)
        {
          char
            buffer[MagickPathExtent];

          SetGeometryInfo(&geometry_info);
          flags=ParseGeometry(arg1,&geometry_info);
          if (flags == 0)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          if ((flags & SigmaValue) == 0)
            geometry_info.sigma=geometry_info.rho;
          (void) CloneString(&_draw_info->text,arg2);
          (void) FormatLocaleString(buffer,MagickPathExtent,"%+f%+f",
            geometry_info.xi,geometry_info.psi);
          (void) CloneString(&_draw_info->geometry,buffer);
          _draw_info->affine.sx=cos(DegreesToRadians(
            fmod(geometry_info.rho,360.0)));
          _draw_info->affine.rx=sin(DegreesToRadians(
            fmod(geometry_info.rho,360.0)));
          _draw_info->affine.ry=(-sin(DegreesToRadians(
            fmod(geometry_info.sigma,360.0))));
          _draw_info->affine.sy=cos(DegreesToRadians(
            fmod(geometry_info.sigma,360.0)));
          (void) AnnotateImage(_image,_draw_info,_exception);
          GetAffineMatrix(&_draw_info->affine);
          break;
        }
      if (LocaleCompare("auto-gamma",option+1) == 0)
        {
          (void) AutoGammaImage(_image,_exception);
          break;
        }
      if (LocaleCompare("auto-level",option+1) == 0)
        {
          (void) AutoLevelImage(_image,_exception);
          break;
        }
      if (LocaleCompare("auto-orient",option+1) == 0)
        {
          new_image=AutoOrientImage(_image,_image->orientation,_exception);
          break;
        }
      if (LocaleCompare("auto-threshold",option+1) == 0)
        {
          AutoThresholdMethod
            method;

          method=(AutoThresholdMethod) ParseCommandOption(
            MagickAutoThresholdOptions,MagickFalse,arg1);
          (void) AutoThresholdImage(_image,method,_exception);
          break;
        }
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
    }
    case 'b':
    {
      if (LocaleCompare("bilateral-blur",option+1) == 0)
        {
          flags=ParseGeometry(arg1,&geometry_info);
          if ((flags & (RhoValue|SigmaValue)) == 0)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          if ((flags & SigmaValue) == 0)
            geometry_info.sigma=geometry_info.rho;
          if ((flags & XiValue) == 0)
            geometry_info.xi=1.0*sqrt(geometry_info.rho*geometry_info.rho+
              geometry_info.sigma*geometry_info.sigma);
          if ((flags & PsiValue) == 0)
            geometry_info.psi=0.25*sqrt(geometry_info.rho*geometry_info.rho+
              geometry_info.sigma*geometry_info.sigma);
          new_image=BilateralBlurImage(_image,(size_t) geometry_info.rho,
            (size_t) geometry_info.sigma,geometry_info.xi,geometry_info.psi,
           _exception);
          break;
        }
      if (LocaleCompare("black-threshold",option+1) == 0)
        {
          if (IsGeometry(arg1) == MagickFalse)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          (void) BlackThresholdImage(_image,arg1,_exception);
          break;
        }
      if (LocaleCompare("blue-shift",option+1) == 0)
        {
          geometry_info.rho=1.5;
          if (IfNormalOp) {
            flags=ParseGeometry(arg1,&geometry_info);
            if ((flags & RhoValue) == 0)
              CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          }
          new_image=BlueShiftImage(_image,geometry_info.rho,_exception);
          break;
        }
      if (LocaleCompare("blur",option+1) == 0)
        {
          flags=ParseGeometry(arg1,&geometry_info);
          if ((flags & (RhoValue|SigmaValue)) == 0)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          if ((flags & SigmaValue) == 0)
            geometry_info.sigma=1.0;
          new_image=BlurImage(_image,geometry_info.rho,geometry_info.sigma,
           _exception);
          break;
        }
      if (LocaleCompare("border",option+1) == 0)
        {
          CompositeOperator
            compose;

          const char*
            value;

          flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
          if ((flags & (WidthValue | HeightValue)) == 0)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          compose=OverCompositeOp;
          value=GetImageOption(_image_info,"compose");
          if (value != (const char *) NULL)
            compose=(CompositeOperator) ParseCommandOption(MagickComposeOptions,
              MagickFalse,value);
          new_image=BorderImage(_image,&geometry,compose,_exception);
          break;
        }
      if (LocaleCompare("brightness-contrast",option+1) == 0)
        {
          double
            brightness,
            contrast;

          flags=ParseGeometry(arg1,&geometry_info);
          if ((flags & RhoValue) == 0)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          brightness=geometry_info.rho;
          contrast=0.0;
          if ((flags & SigmaValue) != 0)
            contrast=geometry_info.sigma;
          (void) BrightnessContrastImage(_image,brightness,contrast,
            _exception);
          break;
        }
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
    }
    case 'c':
    {
      if (LocaleCompare("canny",option+1) == 0)
        {
          flags=ParseGeometry(arg1,&geometry_info);
          if ((flags & (RhoValue|SigmaValue)) == 0)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          if ((flags & SigmaValue) == 0)
            geometry_info.sigma=1.0;
          if ((flags & XiValue) == 0)
            geometry_info.xi=10;
          if ((flags & PsiValue) == 0)
            geometry_info.psi=30;
          if ((flags & PercentValue) != 0)
            {
              geometry_info.xi/=100.0;
              geometry_info.psi/=100.0;
            }
          new_image=CannyEdgeImage(_image,geometry_info.rho,geometry_info.sigma,
            geometry_info.xi,geometry_info.psi,_exception);
          break;
        }
      if (LocaleCompare("cdl",option+1) == 0)
        {
          char
            *color_correction_collection; /* Note: arguments do not have percent escapes expanded */

          /*
            Color correct with a color decision list.
          */
          color_correction_collection=FileToString(arg1,~0UL,_exception);
          if (color_correction_collection == (char *) NULL)
            break;
          (void) ColorDecisionListImage(_image,color_correction_collection,
            _exception);
          break;
        }
      if (LocaleCompare("channel",option+1) == 0)
        {
          if (IfPlusOp)
            {
              (void) SetPixelChannelMask(_image,DefaultChannels);
              break;
            }
          parse=ParseChannelOption(arg1);
          if (parse < 0)
            CLIWandExceptArgBreak(OptionError,"UnrecognizedChannelType",option,
              arg1);
          (void) SetPixelChannelMask(_image,(ChannelType) parse);
          break;
        }
      if (LocaleCompare("charcoal",option+1) == 0)
        {
          flags=ParseGeometry(arg1,&geometry_info);
          if ((flags & (RhoValue|SigmaValue)) == 0)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          if ((flags & SigmaValue) == 0)
            geometry_info.sigma=1.0;
          if ((flags & XiValue) == 0)
            geometry_info.xi=1.0;
          new_image=CharcoalImage(_image,geometry_info.rho,geometry_info.sigma,
            _exception);
          break;
        }
      if (LocaleCompare("chop",option+1) == 0)
        {
          if (IsGeometry(arg1) == MagickFalse)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          (void) ParseGravityGeometry(_image,arg1,&geometry,_exception);
          new_image=ChopImage(_image,&geometry,_exception);
          break;
        }
      if (LocaleCompare("clahe",option+1) == 0)
        {
          if (IsGeometry(arg1) == MagickFalse)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          flags=ParseGeometry(arg1,&geometry_info);
          flags=ParseRegionGeometry(_image,arg1,&geometry,_exception);
          (void) CLAHEImage(_image,geometry.width,geometry.height,
            (size_t) geometry.x,geometry_info.psi,_exception);
          break;
        }
      if (LocaleCompare("clamp",option+1) == 0)
        {
          (void) ClampImage(_image,_exception);
          break;
        }
      if (LocaleCompare("clip",option+1) == 0)
        {
          if (IfNormalOp)
            (void) ClipImage(_image,_exception);
          else /* "+mask" remove the write mask */
            (void) SetImageMask(_image,WritePixelMask,(const Image *) NULL,
              _exception);
          break;
        }
      if (LocaleCompare("clip-mask",option+1) == 0)
        {
          Image
            *clip_mask;

          if (IfPlusOp) {
            /* use "+clip-mask" Remove the write mask for -clip-path */
            (void) SetImageMask(_image,WritePixelMask,(const Image *) NULL,
             _exception);
            break;
          }
          clip_mask=GetImageCache(_image_info,arg1,_exception);
          if (clip_mask == (Image *) NULL)
            break;
          (void) SetImageMask(_image,WritePixelMask,clip_mask,_exception);
          clip_mask=DestroyImage(clip_mask);
          break;
        }
      if (LocaleCompare("clip-path",option+1) == 0)
        {
          (void) ClipImagePath(_image,arg1,IsNormalOp,_exception);
          /* Note: Use "+clip-mask" remove the write mask added */
          break;
        }
      if (LocaleCompare("colorize",option+1) == 0)
        {
          if (IsGeometry(arg1) == MagickFalse)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          new_image=ColorizeImage(_image,arg1,&_draw_info->fill,_exception);
          break;
        }
      if (LocaleCompare("color-matrix",option+1) == 0)
        {
          KernelInfo
            *kernel;

          kernel=AcquireKernelInfo(arg1,exception);
          if (kernel == (KernelInfo *) NULL)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          new_image=ColorMatrixImage(_image,kernel,_exception);
          kernel=DestroyKernelInfo(kernel);
          break;
        }
      if (LocaleCompare("colors",option+1) == 0)
        {
          /* Reduce the number of colors in the image.
             FUTURE: also provide 'plus version with image 'color counts'
          */
          _quantize_info->number_colors=StringToUnsignedLong(arg1);
          _quantize_info->measure_error=_image_info->verbose;
          if (_quantize_info->number_colors == 0)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          if ((_image->storage_class == DirectClass) ||
              _image->colors > _quantize_info->number_colors)
            (void) QuantizeImage(_quantize_info,_image,_exception);
          else
            (void) CompressImageColormap(_image,_exception);
          break;
        }
      if (LocaleCompare("colorspace",option+1) == 0)
        {
          /* WARNING: this is both a image_info setting (already done)
                      and a operator to change image colorspace.

             FUTURE: default colorspace should be sRGB!
             Unless some type of 'linear colorspace' mode is set.

             Note that +colorspace sets "undefined" or no effect on
             new images, but forces images already in memory back to RGB!
             That seems to be a little strange!
          */
          (void) TransformImageColorspace(_image,
                    IfNormalOp ? _image_info->colorspace : sRGBColorspace,
                    _exception);
          break;
        }
      if (LocaleCompare("color-threshold",option+1) == 0)
        {
          PixelInfo
            start,
            stop;

          /*
            Color threshold image.
          */
          if (*option == '+')
            (void) GetColorRange("white-black",&start,&stop,_exception);
          else
            (void) GetColorRange(arg1,&start,&stop,_exception);
          (void) ColorThresholdImage(_image,&start,&stop,_exception);
          break;
        }
      if (LocaleCompare("connected-components",option+1) == 0)
        {
          if (IsGeometry(arg1) == MagickFalse)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          new_image=ConnectedComponentsImage(_image,(size_t)
            StringToInteger(arg1),(CCObjectInfo **) NULL,_exception);
          break;
        }
      if (LocaleCompare("contrast",option+1) == 0)
        {
          CLIWandWarnReplaced(IfNormalOp?"-level":"+level");
          (void) ContrastImage(_image,IsNormalOp,_exception);
          break;
        }
      if (LocaleCompare("contrast-stretch",option+1) == 0)
        {
          double
            black_point,
            white_point;

          flags=ParseGeometry(arg1,&geometry_info);
          if ((flags & RhoValue) == 0)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          black_point=geometry_info.rho;
          white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
            black_point;
          if ((flags & PercentValue) != 0)
            {
              black_point*=(double) _image->columns*_image->rows/100.0;
              white_point*=(double) _image->columns*_image->rows/100.0;
            }
          white_point=(double) _image->columns*_image->rows-white_point;
          (void) ContrastStretchImage(_image,black_point,white_point,
            _exception);
          break;
        }
      if (LocaleCompare("convolve",option+1) == 0)
        {
          double
            gamma;

          KernelInfo
            *kernel_info;

          ssize_t
            j;

          kernel_info=AcquireKernelInfo(arg1,exception);
          if (kernel_info == (KernelInfo *) NULL)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          gamma=0.0;
          for (j=0; j < (ssize_t) (kernel_info->width*kernel_info->height); j++)
            gamma+=kernel_info->values[j];
          gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
          for (j=0; j < (ssize_t) (kernel_info->width*kernel_info->height); j++)
            kernel_info->values[j]*=gamma;
          new_image=MorphologyImage(_image,CorrelateMorphology,1,kernel_info,
            _exception);
          kernel_info=DestroyKernelInfo(kernel_info);
          break;
        }
      if (LocaleCompare("crop",option+1) == 0)
        {
          /* WARNING: This can generate multiple images! */
          if (IsGeometry(arg1) == MagickFalse)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          new_image=CropImageToTiles(_image,arg1,_exception);
          break;
        }
      if (LocaleCompare("cycle",option+1) == 0)
        {
          if (IsGeometry(arg1) == MagickFalse)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          (void) CycleColormapImage(_image,(ssize_t) StringToLong(arg1),
            _exception);
          break;
        }
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
    }
    case 'd':
    {
      if (LocaleCompare("decipher",option+1) == 0)
        {
          /* Note: arguments do not have percent escapes expanded */
          StringInfo
            *passkey;

          passkey=FileToStringInfo(arg1,~0UL,_exception);
          if (passkey == (StringInfo *) NULL)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);

          (void) PasskeyDecipherImage(_image,passkey,_exception);
          passkey=DestroyStringInfo(passkey);
          break;
        }
      if (LocaleCompare("depth",option+1) == 0)
        {
          /* The _image_info->depth setting has already been set
             We just need to apply it to all images in current sequence

             WARNING: Depth from 8 to 16 causes 'quantum rounding to images!
             That is it really is an operation, not a setting! Arrgghhh

             FUTURE: this should not be an operator!!!
          */
          (void) SetImageDepth(_image,_image_info->depth,_exception);
          break;
        }
      if (LocaleCompare("deskew",option+1) == 0)
        {
          double
            threshold;

          if (IfNormalOp) {
            if (IsGeometry(arg1) == MagickFalse)
              CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
            threshold=StringToDoubleInterval(arg1,(double) QuantumRange+1.0);
          }
          else
            threshold=40.0*QuantumRange/100.0;
          new_image=DeskewImage(_image,threshold,_exception);
          break;
        }
      if (LocaleCompare("despeckle",option+1) == 0)
        {
          new_image=DespeckleImage(_image,_exception);
          break;
        }
      if (LocaleCompare("distort",option+1) == 0)
        {
          double
            *args;

          ssize_t
            count;

          parse = ParseCommandOption(MagickDistortOptions,MagickFalse,arg1);
          if ( parse < 0 )
             CLIWandExceptArgBreak(OptionError,"UnrecognizedDistortMethod",
                                      option,arg1);
          if ((DistortMethod) parse == ResizeDistortion)
            {
               double
                 resize_args[2];
               /* Special Case - Argument is actually a resize geometry!
               ** Convert that to an appropriate distortion argument array.
               ** FUTURE: make a separate special resize operator
                    Roll into a resize special operator */
               if (IsGeometry(arg2) == MagickFalse)
                 CLIWandExceptArgBreak(OptionError,"InvalidGeometry",
                                           option,arg2);
               (void) ParseRegionGeometry(_image,arg2,&geometry,_exception);
               resize_args[0]=(double) geometry.width;
               resize_args[1]=(double) geometry.height;
               new_image=DistortImage(_image,(DistortMethod) parse,
                    (size_t)2,resize_args,MagickTrue,_exception);
               break;
            }
          /* convert argument string into an array of doubles */
          args = StringToArrayOfDoubles(arg2,&count,_exception);
          if (args == (double *) NULL )
            CLIWandExceptArgBreak(OptionError,"InvalidNumberList",option,arg2);

          new_image=DistortImage(_image,(DistortMethod) parse,(size_t)
             count,args,IsPlusOp,_exception);
          args=(double *) RelinquishMagickMemory(args);
          break;
        }
      if (LocaleCompare("draw",option+1) == 0)
        {
          (void) CloneString(&_draw_info->primitive,arg1);
          (void) DrawImage(_image,_draw_info,_exception);
          (void) CloneString(&_draw_info->primitive,(char *) NULL);
          break;
        }
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
    }
    case 'e':
    {
      if (LocaleCompare("edge",option+1) == 0)
        {
          flags=ParseGeometry(arg1,&geometry_info);
          if ((flags & (RhoValue|SigmaValue)) == 0)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          new_image=EdgeImage(_image,geometry_info.rho,_exception);
          break;
        }
      if (LocaleCompare("emboss",option+1) == 0)
        {
          flags=ParseGeometry(arg1,&geometry_info);
          if ((flags & (RhoValue|SigmaValue)) == 0)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          if ((flags & SigmaValue) == 0)
            geometry_info.sigma=1.0;
          new_image=EmbossImage(_image,geometry_info.rho,
            geometry_info.sigma,_exception);
          break;
        }
      if (LocaleCompare("encipher",option+1) == 0)
        {
          /* Note: arguments do not have percent escapes expanded */
          StringInfo
            *passkey;

          passkey=FileToStringInfo(arg1,~0UL,_exception);
          if (passkey != (StringInfo *) NULL)
            {
              (void) PasskeyEncipherImage(_image,passkey,_exception);
              passkey=DestroyStringInfo(passkey);
            }
          break;
        }
      if (LocaleCompare("enhance",option+1) == 0)
        {
          new_image=EnhanceImage(_image,_exception);
          break;
        }
      if (LocaleCompare("equalize",option+1) == 0)
        {
          (void) EqualizeImage(_image,_exception);
          break;
        }
      if (LocaleCompare("evaluate",option+1) == 0)
        {
          double
            constant;

          parse = ParseCommandOption(MagickEvaluateOptions,MagickFalse,arg1);
          if ( parse < 0 )
            CLIWandExceptArgBreak(OptionError,"UnrecognizedEvaluateOperator",
                 option,arg1);
          if (IsGeometry(arg2) == MagickFalse)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
          constant=StringToDoubleInterval(arg2,(double) QuantumRange+1.0);
          (void) EvaluateImage(_image,(MagickEvaluateOperator)parse,constant,
               _exception);
          break;
        }
      if (LocaleCompare("extent",option+1) == 0)
        {
          if (IsGeometry(arg1) == MagickFalse)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          flags=ParseGravityGeometry(_image,arg1,&geometry,_exception);
          if (geometry.width == 0)
            geometry.width=_image->columns;
          if (geometry.height == 0)
            geometry.height=_image->rows;
          new_image=ExtentImage(_image,&geometry,_exception);
          break;
        }
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
    }
    case 'f':
    {
      if (LocaleCompare("features",option+1) == 0)
        {
          CLIWandWarnReplaced("-version -define identify:features=");
          if (*option == '+')
            {
              (void) DeleteImageArtifact(_image,"identify:features");
              break;
            }
          (void) SetImageArtifact(_image,"identify:features",arg1);
          (void) SetImageArtifact(_image,"verbose","true");
          break;
        }
      if (LocaleCompare("flip",option+1) == 0)
        {
          new_image=FlipImage(_image,_exception);
          break;
        }
      if (LocaleCompare("flop",option+1) == 0)
        {
          new_image=FlopImage(_image,_exception);
          break;
        }
      if (LocaleCompare("floodfill",option+1) == 0)
        {
          PixelInfo
            target;

          if (IsGeometry(arg1) == MagickFalse)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          (void) ParsePageGeometry(_image,arg1,&geometry,_exception);
          (void) QueryColorCompliance(arg2,AllCompliance,&target,_exception);
          (void) FloodfillPaintImage(_image,_draw_info,&target,geometry.x,
            geometry.y,IsPlusOp,_exception);
          break;
        }
      if (LocaleCompare("frame",option+1) == 0)
        {
          FrameInfo
            frame_info;

          CompositeOperator
            compose;

          const char*
            value;

          value=GetImageOption(_image_info,"compose");
            compose=OverCompositeOp;  /* use Over not _image->compose */
          if (value != (const char *) NULL)
            compose=(CompositeOperator) ParseCommandOption(MagickComposeOptions,
              MagickFalse,value);
          if (IsGeometry(arg1) == MagickFalse)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
          frame_info.width=geometry.width;
          frame_info.height=geometry.height;
          frame_info.outer_bevel=geometry.x;
          frame_info.inner_bevel=geometry.y;
          frame_info.x=(ssize_t) frame_info.width;
          frame_info.y=(ssize_t) frame_info.height;
          frame_info.width=_image->columns+2*frame_info.width;
          frame_info.height=_image->rows+2*frame_info.height;
          new_image=FrameImage(_image,&frame_info,compose,_exception);
          break;
        }
      if (LocaleCompare("function",option+1) == 0)
        {
          double
            *args;

          ssize_t
            count;

          parse=ParseCommandOption(MagickFunctionOptions,MagickFalse,arg1);
          if ( parse < 0 )
            CLIWandExceptArgBreak(OptionError,"UnrecognizedFunction",
                 option,arg1);
          /* convert argument string into an array of doubles */
          args = StringToArrayOfDoubles(arg2,&count,_exception);
          if (args == (double *) NULL )
            CLIWandExceptArgBreak(OptionError,"InvalidNumberList",option,arg2);

          (void) FunctionImage(_image,(MagickFunction)parse,(size_t) count,args,
               _exception);
          args=(double *) RelinquishMagickMemory(args);
          break;
        }
      if (LocaleCompare("fx",option+1) == 0)
        {
          new_image=FxImage(_image,arg1,_exception);
          break;
        }
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
    }
    case 'g':
    {
      if (LocaleCompare("gamma",option+1) == 0)
        {
          double
            constant;

          if (IsGeometry(arg1) == MagickFalse)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          constant=StringToDouble(arg1,(char **) NULL);
#if 0
          /* Using Gamma, via a cache */
          if (IfPlusOp)
            constant=PerceptibleReciprocal(constant);
          (void) GammaImage(_image,constant,_exception);
#else
          /* Using Evaluate POW, direct update of values - more accurite */
          if (IfNormalOp)
            constant=PerceptibleReciprocal(constant);
          (void) EvaluateImage(_image,PowEvaluateOperator,constant,_exception);
          _image->gamma*=StringToDouble(arg1,(char **) NULL);
#endif
          /* Set gamma setting -- Old meaning of "+gamma"
           * _image->gamma=StringToDouble(arg1,(char **) NULL);
           */
          break;
        }
      if (LocaleCompare("gaussian-blur",option+1) == 0)
        {
          flags=ParseGeometry(arg1,&geometry_info);
          if ((flags & (RhoValue|SigmaValue)) == 0)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          if ((flags & SigmaValue) == 0)
            geometry_info.sigma=1.0;
          new_image=GaussianBlurImage(_image,geometry_info.rho,
            geometry_info.sigma,_exception);
          break;
        }
      if (LocaleCompare("gaussian",option+1) == 0)
        {
          CLIWandWarnReplaced("-gaussian-blur");
          (void) CLISimpleOperatorImage(cli_wand,"-gaussian-blur",arg1,NULL,exception);
        }
      if (LocaleCompare("geometry",option+1) == 0)
        {
          /*
            Record Image offset for composition. (A Setting)
            Resize last _image. (ListOperator)  -- DEPRECIATE
            FUTURE: Why if no 'offset' does this resize ALL images?
            Also why is the setting recorded in the IMAGE non-sense!
          */
          if (IfPlusOp)
            { /* remove the previous composition geometry offset! */
              if (_image->geometry != (char *) NULL)
                _image->geometry=DestroyString(_image->geometry);
              break;
            }
          if (IsGeometry(arg1) == MagickFalse)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          flags=ParseRegionGeometry(_image,arg1,&geometry,_exception);
          if (((flags & XValue) != 0) || ((flags & YValue) != 0))
            (void) CloneString(&_image->geometry,arg1);
          else
            new_image=ResizeImage(_image,geometry.width,geometry.height,
              _image->filter,_exception);
          break;
        }
      if (LocaleCompare("grayscale",option+1) == 0)
        {
          parse=ParseCommandOption(MagickPixelIntensityOptions,
            MagickFalse,arg1);
          if (parse < 0)
            CLIWandExceptArgBreak(OptionError,"UnrecognizedIntensityMethod",
              option,arg1);
          (void) GrayscaleImage(_image,(PixelIntensityMethod) parse,_exception);
          break;
        }
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
    }
    case 'h':
    {
      if (LocaleCompare("hough-lines",option+1) == 0)
        {
          flags=ParseGeometry(arg1,&geometry_info);
          if ((flags & (RhoValue|SigmaValue)) == 0)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          if ((flags & SigmaValue) == 0)
            geometry_info.sigma=geometry_info.rho;
          if ((flags & XiValue) == 0)
            geometry_info.xi=40;
          new_image=HoughLineImage(_image,(size_t) geometry_info.rho,
            (size_t) geometry_info.sigma,(size_t) geometry_info.xi,_exception);
          break;
        }
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
    }
    case 'i':
    {
      if (LocaleCompare("identify",option+1) == 0)
        {
          const char
            *format,
            *text;

          format=GetImageOption(_image_info,"format");
          if (format == (char *) NULL)
            {
              (void) IdentifyImage(_image,stdout,_image_info->verbose,
                _exception);
              break;
            }
          text=InterpretImageProperties(_image_info,_image,format,_exception);
          if (text == (char *) NULL)
            CLIWandExceptionBreak(OptionWarning,"InterpretPropertyFailure",
              option);
          (void) fputs(text,stdout);
          text=DestroyString((char *)text);
          break;
        }
      if (LocaleCompare("implode",option+1) == 0)
        {
          flags=ParseGeometry(arg1,&geometry_info);
          if ((flags & RhoValue) == 0)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          new_image=ImplodeImage(_image,geometry_info.rho,_image->interpolate,
               _exception);
          break;
        }
      if (LocaleCompare("integral",option+1) == 0)
        {
          new_image=IntegralImage(_image,_exception);
          break;
        }
      if (LocaleCompare("interpolative-resize",option+1) == 0)
        {
          /* FUTURE: New to IMv7
               Roll into a resize special operator */
          if (IsGeometry(arg1) == MagickFalse)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
          new_image=InterpolativeResizeImage(_image,geometry.width,
            geometry.height,_image->interpolate,_exception);
          break;
        }
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
    }
    case 'k':
    {
      if (LocaleCompare("kmeans",option+1) == 0)
        {
          /*
            K-means clustering.
          */
          flags=ParseGeometry(arg1,&geometry_info);
          if ((flags & (RhoValue|SigmaValue)) == 0)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          if ((flags & SigmaValue) == 0)
            geometry_info.sigma=100.0;
          if ((flags & XiValue) == 0)
            geometry_info.xi=0.01;
          (void) KmeansImage(_image,(size_t) geometry_info.rho,(size_t)
           geometry_info.sigma,geometry_info.xi,_exception);
          break;
        }
      if (LocaleCompare("kuwahara",option+1) == 0)
        {
          /*
            Edge preserving blur.
          */
          flags=ParseGeometry(arg1,&geometry_info);
          if ((flags & (RhoValue|SigmaValue)) == 0)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          if ((flags & SigmaValue) == 0)
            geometry_info.sigma=geometry_info.rho-0.5;
          new_image=KuwaharaImage(_image,geometry_info.rho,geometry_info.sigma,
           _exception);
          break;
        }
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
    }
    case 'l':
    {
      if (LocaleCompare("lat",option+1) == 0)
        {
          flags=ParseGeometry(arg1,&geometry_info);
          if ((flags & (RhoValue|SigmaValue)) == 0)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          if ((flags & SigmaValue) == 0)
            geometry_info.sigma=1.0;
          if ((flags & PercentValue) != 0)
            geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
          new_image=AdaptiveThresholdImage(_image,(size_t) geometry_info.rho,
               (size_t) geometry_info.sigma,(double) geometry_info.xi,
               _exception);
          break;
        }
      if (LocaleCompare("level",option+1) == 0)
        {
          double
            black_point,
            gamma,
            white_point;

          flags=ParseGeometry(arg1,&geometry_info);
          if ((flags & RhoValue) == 0)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          black_point=geometry_info.rho;
          white_point=(double) QuantumRange;
          if ((flags & SigmaValue) != 0)
            white_point=geometry_info.sigma;
          gamma=1.0;
          if ((flags & XiValue) != 0)
            gamma=geometry_info.xi;
          if ((flags & PercentValue) != 0)
            {
              black_point*=(double) (QuantumRange/100.0);
              white_point*=(double) (QuantumRange/100.0);
            }
          if ((flags & SigmaValue) == 0)
            white_point=(double) QuantumRange-black_point;
          if (IfPlusOp || ((flags & AspectValue) != 0))
            (void) LevelizeImage(_image,black_point,white_point,gamma,_exception);
          else
            (void) LevelImage(_image,black_point,white_point,gamma,_exception);
          break;
        }
      if (LocaleCompare("level-colors",option+1) == 0)
        {
          char
            token[MagickPathExtent];

          const char
            *p;

          PixelInfo
            black_point,
            white_point;

          p=(const char *) arg1;
          (void) GetNextToken(p,&p,MagickPathExtent,token);  /* get black point color */
          if ((isalpha((int) ((unsigned char) *token)) != 0) || ((*token == '#') != 0))
            (void) QueryColorCompliance(token,AllCompliance,
                      &black_point,_exception);
          else
            (void) QueryColorCompliance("#000000",AllCompliance,
                      &black_point,_exception);
          if (isalpha((int) ((unsigned char) *token)) || (*token == '#'))
            (void) GetNextToken(p,&p,MagickPathExtent,token);
          if (*token == '\0')
            white_point=black_point; /* set everything to that color */
          else
            {
              if ((isalpha((int) ((unsigned char) *token)) == 0) && ((*token == '#') == 0))
                (void) GetNextToken(p,&p,MagickPathExtent,token); /* Get white point color. */
              if ((isalpha((int) ((unsigned char) *token)) != 0) || ((*token == '#') != 0))
                (void) QueryColorCompliance(token,AllCompliance,
                           &white_point,_exception);
              else
                (void) QueryColorCompliance("#ffffff",AllCompliance,
                           &white_point,_exception);
            }
          (void) LevelImageColors(_image,&black_point,&white_point,
                     IsPlusOp,_exception);
          break;
        }
      if (LocaleCompare("linear-stretch",option+1) == 0)
        {
          double
            black_point,
            white_point;

          flags=ParseGeometry(arg1,&geometry_info);
          if ((flags & RhoValue) == 0)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          black_point=geometry_info.rho;
          white_point=(double) _image->columns*_image->rows;
          if ((flags & SigmaValue) != 0)
            white_point=geometry_info.sigma;
          if ((flags & PercentValue) != 0)
            {
              black_point*=(double) _image->columns*_image->rows/100.0;
              white_point*=(double) _image->columns*_image->rows/100.0;
            }
          if ((flags & SigmaValue) == 0)
            white_point=(double) _image->columns*_image->rows-
              black_point;
          (void) LinearStretchImage(_image,black_point,white_point,_exception);
          break;
        }
      if (LocaleCompare("liquid-rescale",option+1) == 0)
        {
          /* FUTURE: Roll into a resize special operator */
          if (IsGeometry(arg1) == MagickFalse)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          flags=ParseRegionGeometry(_image,arg1,&geometry,_exception);
          if ((flags & XValue) == 0)
            geometry.x=1;
          if ((flags & YValue) == 0)
            geometry.y=0;
          new_image=LiquidRescaleImage(_image,geometry.width,
            geometry.height,1.0*geometry.x,1.0*geometry.y,_exception);
          break;
        }
      if (LocaleCompare("local-contrast",option+1) == 0)
        {
          flags=ParseGeometry(arg1,&geometry_info);
          if ((flags & RhoValue) == 0)
            geometry_info.rho=10;
          if ((flags & SigmaValue) == 0)
            geometry_info.sigma=12.5;
          new_image=LocalContrastImage(_image,geometry_info.rho,
            geometry_info.sigma,exception);
          break;
        }
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
    }
    case 'm':
    {
      if (LocaleCompare("magnify",option+1) == 0)
        {
          new_image=MagnifyImage(_image,_exception);
          break;
        }
      if (LocaleCompare("map",option+1) == 0)
        {
          CLIWandWarnReplaced("-remap");
          (void) CLISimpleOperatorImage(cli_wand,"-remap",NULL,NULL,exception);
          break;
        }
      if (LocaleCompare("mask",option+1) == 0)
        {
          Image
            *mask;

          if (IfPlusOp)
            {
              /*
                Remove a mask.
              */
              (void) SetImageMask(_image,WritePixelMask,(const Image *) NULL,
                _exception);
              break;
            }
          /*
            Set the image mask.
          */
          mask=GetImageCache(_image_info,arg1,_exception);
          if (mask == (Image *) NULL)
            break;
          (void) SetImageMask(_image,WritePixelMask,mask,_exception);
          mask=DestroyImage(mask);
          break;
        }
      if (LocaleCompare("matte",option+1) == 0)
        {
          CLIWandWarnReplaced(IfNormalOp?"-alpha Set":"-alpha Off");
          (void) SetImageAlphaChannel(_image,IfNormalOp ? SetAlphaChannel :
            DeactivateAlphaChannel, _exception);
          break;
        }
      if (LocaleCompare("mean-shift",option+1) == 0)
        {
          flags=ParseGeometry(arg1,&geometry_info);
          if ((flags & (RhoValue|SigmaValue)) == 0)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          if ((flags & SigmaValue) == 0)
            geometry_info.sigma=1.0;
          if ((flags & XiValue) == 0)
            geometry_info.xi=0.10*QuantumRange;
          if ((flags & PercentValue) != 0)
            geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
          new_image=MeanShiftImage(_image,(size_t) geometry_info.rho,
            (size_t) geometry_info.sigma,geometry_info.xi,_exception);
          break;
        }
      if (LocaleCompare("median",option+1) == 0)
        {
          CLIWandWarnReplaced("-statistic Median");
          (void) CLISimpleOperatorImage(cli_wand,"-statistic","Median",arg1,exception);
          break;
        }
      if (LocaleCompare("mode",option+1) == 0)
        {
          /* FUTURE: note this is also a special "montage" option */
          CLIWandWarnReplaced("-statistic Mode");
          (void) CLISimpleOperatorImage(cli_wand,"-statistic","Mode",arg1,exception);
          break;
        }
      if (LocaleCompare("modulate",option+1) == 0)
        {
          if (IsGeometry(arg1) == MagickFalse)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          (void) ModulateImage(_image,arg1,_exception);
          break;
        }
      if (LocaleCompare("monitor",option+1) == 0)
        {
          (void) SetImageProgressMonitor(_image, IfNormalOp ? MonitorProgress :
                (MagickProgressMonitor) NULL,(void *) NULL);
          break;
        }
      if (LocaleCompare("monochrome",option+1) == 0)
        {
          (void) SetImageType(_image,BilevelType,_exception);
          break;
        }
      if (LocaleCompare("morphology",option+1) == 0)
        {
          char
            token[MagickPathExtent];

          const char
            *p;

          KernelInfo
            *kernel;

          ssize_t
            iterations;

          p=arg1;
          (void) GetNextToken(p,&p,MagickPathExtent,token);
          parse=ParseCommandOption(MagickMorphologyOptions,MagickFalse,token);
          if ( parse < 0 )
            CLIWandExceptArgBreak(OptionError,"UnrecognizedFunction",option,
              arg1);
          iterations=1L;
          (void) GetNextToken(p,&p,MagickPathExtent,token);
          if ((*p == ':') || (*p == ','))
            (void) GetNextToken(p,&p,MagickPathExtent,token);
          if ((*p != '\0'))
            iterations=(ssize_t) StringToLong(p);
          kernel=AcquireKernelInfo(arg2,exception);
          if (kernel == (KernelInfo *) NULL)
            CLIWandExceptArgBreak(OptionError,"UnabletoParseKernel",option,arg2);
          new_image=MorphologyImage(_image,(MorphologyMethod)parse,iterations,
            kernel,_exception);
          kernel=DestroyKernelInfo(kernel);
          break;
        }
      if (LocaleCompare("motion-blur",option+1) == 0)
        {
          flags=ParseGeometry(arg1,&geometry_info);
          if ((flags & (RhoValue|SigmaValue)) == 0)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          if ((flags & SigmaValue) == 0)
            geometry_info.sigma=1.0;
          new_image=MotionBlurImage(_image,geometry_info.rho,
            geometry_info.sigma,geometry_info.xi,_exception);
          break;
        }
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
    }
    case 'n':
    {
      if (LocaleCompare("negate",option+1) == 0)
        {
          (void) NegateImage(_image, IsPlusOp, _exception);
          break;
        }
      if (LocaleCompare("noise",option+1) == 0)
        {
          double
            attenuate;

          const char*
            value;

          if (IfNormalOp)
            {
              CLIWandWarnReplaced("-statistic NonPeak");
              (void) CLISimpleOperatorImage(cli_wand,"-statistic","NonPeak",arg1,exception);
              break;
            }
          parse=ParseCommandOption(MagickNoiseOptions,MagickFalse,arg1);
          if ( parse < 0 )
            CLIWandExceptArgBreak(OptionError,"UnrecognizedNoiseType",
                option,arg1);
          attenuate=1.0;
          value=GetImageOption(_image_info,"attenuate");
          if  (value != (const char *) NULL)
            attenuate=StringToDouble(value,(char **) NULL);
          new_image=AddNoiseImage(_image,(NoiseType)parse,attenuate,
               _exception);
          break;
        }
      if (LocaleCompare("normalize",option+1) == 0)
        {
          (void) NormalizeImage(_image,_exception);
          break;
        }
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
    }
    case 'o':
    {
      if (LocaleCompare("opaque",option+1) == 0)
        {
          PixelInfo
            target;

          (void) QueryColorCompliance(arg1,AllCompliance,&target,_exception);
          (void) OpaquePaintImage(_image,&target,&_draw_info->fill,IsPlusOp,
               _exception);
          break;
        }
      if (LocaleCompare("ordered-dither",option+1) == 0)
        {
          (void) OrderedDitherImage(_image,arg1,_exception);
          break;
        }
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
    }
    case 'p':
    {
      if (LocaleCompare("paint",option+1) == 0)
        {
          flags=ParseGeometry(arg1,&geometry_info);
          if ((flags & (RhoValue|SigmaValue)) == 0)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          new_image=OilPaintImage(_image,geometry_info.rho,geometry_info.sigma,
               _exception);
          break;
        }
      if (LocaleCompare("perceptible",option+1) == 0)
        {
          (void) PerceptibleImage(_image,StringToDouble(arg1,(char **) NULL),
            _exception);
          break;
        }
      if (LocaleCompare("polaroid",option+1) == 0)
        {
          const char
            *caption;

          double
            angle;

          if (IfPlusOp) {
            RandomInfo
              *random_info;

            random_info=AcquireRandomInfo();
            angle=22.5*(GetPseudoRandomValue(random_info)-0.5);
            random_info=DestroyRandomInfo(random_info);
          }
          else {
            flags=ParseGeometry(arg1,&geometry_info);
            if ((flags & RhoValue) == 0)
              CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
            angle=geometry_info.rho;
          }
          caption=GetImageProperty(_image,"caption",_exception);
          new_image=PolaroidImage(_image,_draw_info,caption,angle,
            _image->interpolate,_exception);
          break;
        }
      if (LocaleCompare("posterize",option+1) == 0)
        {
          flags=ParseGeometry(arg1,&geometry_info);
          if ((flags & RhoValue) == 0)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          (void) PosterizeImage(_image,(size_t) geometry_info.rho,
            _quantize_info->dither_method,_exception);
          break;
        }
      if (LocaleCompare("preview",option+1) == 0)
        {
          /* FUTURE: should be a 'Genesis' option?
             Option however is also in WandSettingOptionInfo()
             Why???
          */
          parse=ParseCommandOption(MagickPreviewOptions, MagickFalse,arg1);
          if ( parse < 0 )
            CLIWandExceptArgBreak(OptionError,"UnrecognizedPreviewType",
                option,arg1);
          new_image=PreviewImage(_image,(PreviewType)parse,_exception);
          break;
        }
      if (LocaleCompare("profile",option+1) == 0)
        {
          const char
            *name;

          const StringInfo
            *profile;

          Image
            *profile_image;

          ImageInfo
            *profile_info;

          /* Note: arguments do not have percent escapes expanded */
          if (IfPlusOp)
            { /* Remove a profile from the _image.  */
              (void) ProfileImage(_image,arg1,(const unsigned char *)
                NULL,0,_exception);
              break;
            }
          /* Associate a profile with the _image.  */
          profile_info=CloneImageInfo(_image_info);
          profile=GetImageProfile(_image,"iptc");
          if (profile != (const StringInfo *) NULL)
            profile_info->profile=(void *) CloneStringInfo(profile);
          profile_image=GetImageCache(profile_info,arg1,_exception);
          profile_info=DestroyImageInfo(profile_info);
          if (profile_image == (Image *) NULL)
            {
              StringInfo
                *new_profile;

              profile_info=CloneImageInfo(_image_info);
              (void) CopyMagickString(profile_info->filename,arg1,
                MagickPathExtent);
              new_profile=FileToStringInfo(profile_info->filename,~0UL,
                _exception);
              if (new_profile != (StringInfo *) NULL)
                {
                  (void) SetImageInfo(profile_info,0,_exception);
                  (void) ProfileImage(_image,profile_info->magick,
                    GetStringInfoDatum(new_profile),(size_t)
                    GetStringInfoLength(new_profile),_exception);
                  new_profile=DestroyStringInfo(new_profile);
                }
              profile_info=DestroyImageInfo(profile_info);
              break;
            }
          ResetImageProfileIterator(profile_image);
          name=GetNextImageProfile(profile_image);
          while (name != (const char *) NULL)
          {
            profile=GetImageProfile(profile_image,name);
            if (profile != (const StringInfo *) NULL)
              (void) ProfileImage(_image,name,GetStringInfoDatum(profile),
                (size_t) GetStringInfoLength(profile),_exception);
            name=GetNextImageProfile(profile_image);
          }
          profile_image=DestroyImage(profile_image);
          break;
        }
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
    }
    case 'r':
    {
      if (LocaleCompare("raise",option+1) == 0)
        {
          if (IsGeometry(arg1) == MagickFalse)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
          (void) RaiseImage(_image,&geometry,IsNormalOp,_exception);
          break;
        }
      if (LocaleCompare("random-threshold",option+1) == 0)
        {
          double
            min_threshold,
            max_threshold;

          if (IsGeometry(arg1) == MagickFalse)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          min_threshold=0.0;
          max_threshold=(double) QuantumRange;
          flags=ParseGeometry(arg1,&geometry_info);
          min_threshold=geometry_info.rho;
          max_threshold=geometry_info.sigma;
          if ((flags & SigmaValue) == 0)
            max_threshold=min_threshold;
          if (strchr(arg1,'%') != (char *) NULL)
            {
              max_threshold*=(double) (0.01*QuantumRange);
              min_threshold*=(double) (0.01*QuantumRange);
            }
          (void) RandomThresholdImage(_image,min_threshold,max_threshold,
            _exception);
          break;
        }
      if (LocaleCompare("range-threshold",option+1) == 0)
        {
          /*
            Range threshold image.
          */
          if (IsGeometry(arg1) == MagickFalse)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          flags=ParseGeometry(arg1,&geometry_info);
          if ((flags & SigmaValue) == 0)
            geometry_info.sigma=geometry_info.rho;
          if ((flags & XiValue) == 0)
            geometry_info.xi=geometry_info.sigma;
          if ((flags & PsiValue) == 0)
            geometry_info.psi=geometry_info.xi;
          if (strchr(arg1,'%') != (char *) NULL)
            {
              geometry_info.rho*=(double) (0.01*QuantumRange);
              geometry_info.sigma*=(double) (0.01*QuantumRange);
              geometry_info.xi*=(double) (0.01*QuantumRange);
              geometry_info.psi*=(double) (0.01*QuantumRange);
            }
          (void) RangeThresholdImage(_image,geometry_info.rho,
            geometry_info.sigma,geometry_info.xi,geometry_info.psi,exception);
          break;
        }
      if (LocaleCompare("read-mask",option+1) == 0)
        {
          /* Note: arguments do not have percent escapes expanded */
          Image
            *mask;

          if (IfPlusOp)
            { /* Remove a mask. */
              (void) SetImageMask(_image,ReadPixelMask,(const Image *) NULL,
                _exception);
              break;
            }
          /* Set the image mask. */
          mask=GetImageCache(_image_info,arg1,_exception);
          if (mask == (Image *) NULL)
            break;
          (void) SetImageMask(_image,ReadPixelMask,mask,_exception);
          mask=DestroyImage(mask);
          break;
        }
      if (LocaleCompare("recolor",option+1) == 0)
        {
          CLIWandWarnReplaced("-color-matrix");
          (void) CLISimpleOperatorImage(cli_wand,"-color-matrix",arg1,NULL,
            exception);
        }
      if (LocaleCompare("region",option+1) == 0)
        {
          if (*option == '+')
            {
              (void) SetImageRegionMask(_image,WritePixelMask,
                (const RectangleInfo *) NULL,_exception);
              break;
            }
          if (IsGeometry(arg1) == MagickFalse)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          (void) ParseGravityGeometry(_image,arg1,&geometry,_exception);
          (void) SetImageRegionMask(_image,WritePixelMask,&geometry,_exception);
          break;
        }
      if (LocaleCompare("remap",option+1) == 0)
        {
          /* Note: arguments do not have percent escapes expanded */
          Image
            *remap_image;

          remap_image=GetImageCache(_image_info,arg1,_exception);
          if (remap_image == (Image *) NULL)
            break;
          (void) RemapImage(_quantize_info,_image,remap_image,_exception);
          remap_image=DestroyImage(remap_image);
          break;
        }
      if (LocaleCompare("repage",option+1) == 0)
        {
          if (IfNormalOp)
            {
              if (IsGeometry(arg1) == MagickFalse)
                CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,
                  arg1);
              (void) ResetImagePage(_image,arg1);
            }
          else
            (void) ParseAbsoluteGeometry("0x0+0+0",&_image->page);
          break;
        }
      if (LocaleCompare("resample",option+1) == 0)
        {
          /* FUTURE: Roll into a resize special operation */
          flags=ParseGeometry(arg1,&geometry_info);
          if ((flags & (RhoValue|SigmaValue)) == 0)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          if ((flags & SigmaValue) == 0)
            geometry_info.sigma=geometry_info.rho;
          new_image=ResampleImage(_image,geometry_info.rho,
            geometry_info.sigma,_image->filter,_exception);
          break;
        }
      if (LocaleCompare("resize",option+1) == 0)
        {
          if (IsGeometry(arg1) == MagickFalse)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
          new_image=ResizeImage(_image,geometry.width,geometry.height,
            _image->filter,_exception);
          break;
        }
      if (LocaleCompare("roll",option+1) == 0)
        {
          if (IsGeometry(arg1) == MagickFalse)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
          if ((flags & PercentValue) != 0)
            {
              geometry.x*=(double) _image->columns/100.0;
              geometry.y*=(double) _image->rows/100.0;
            }
          new_image=RollImage(_image,geometry.x,geometry.y,_exception);
          break;
        }
      if (LocaleCompare("rotate",option+1) == 0)
        {
          flags=ParseGeometry(arg1,&geometry_info);
          if ((flags & RhoValue) == 0)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          if ((flags & GreaterValue) != 0 && (_image->columns <= _image->rows))
            break;
          if ((flags & LessValue) != 0 && (_image->columns >= _image->rows))
            break;
          new_image=RotateImage(_image,geometry_info.rho,_exception);
          break;
        }
      if (LocaleCompare("rotational-blur",option+1) == 0)
        {
          flags=ParseGeometry(arg1,&geometry_info);
          if ((flags & RhoValue) == 0)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          new_image=RotationalBlurImage(_image,geometry_info.rho,_exception);
          break;
        }
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
    }
    case 's':
    {
      if (LocaleCompare("sample",option+1) == 0)
        {
          /* FUTURE: Roll into a resize special operator */
          if (IsGeometry(arg1) == MagickFalse)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
          new_image=SampleImage(_image,geometry.width,geometry.height,
            _exception);
          break;
        }
      if (LocaleCompare("scale",option+1) == 0)
        {
          /* FUTURE: Roll into a resize special operator */
          if (IsGeometry(arg1) == MagickFalse)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
          new_image=ScaleImage(_image,geometry.width,geometry.height,
            _exception);
          break;
        }
      if (LocaleCompare("segment",option+1) == 0)
        {
          flags=ParseGeometry(arg1,&geometry_info);
          if ((flags & (RhoValue|SigmaValue)) == 0)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          if ((flags & SigmaValue) == 0)
            geometry_info.sigma=1.0;
          (void) SegmentImage(_image,_image->colorspace,
            _image_info->verbose,geometry_info.rho,geometry_info.sigma,
            _exception);
          break;
        }
      if (LocaleCompare("selective-blur",option+1) == 0)
        {
          flags=ParseGeometry(arg1,&geometry_info);
          if ((flags & (RhoValue|SigmaValue)) == 0)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          if ((flags & SigmaValue) == 0)
            geometry_info.sigma=1.0;
          if ((flags & PercentValue) != 0)
            geometry_info.xi=(double) QuantumRange*geometry_info.xi/100.0;
          new_image=SelectiveBlurImage(_image,geometry_info.rho,
            geometry_info.sigma,geometry_info.xi,_exception);
          break;
        }
      if (LocaleCompare("separate",option+1) == 0)
        {
          /* WARNING: This can generate multiple images! */
          /* FUTURE - this may be replaced by a "-channel" method */
          new_image=SeparateImages(_image,_exception);
          break;
        }
      if (LocaleCompare("sepia-tone",option+1) == 0)
        {
          if (IsGeometry(arg1) == MagickFalse)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          new_image=SepiaToneImage(_image,StringToDoubleInterval(arg1,
                 (double) QuantumRange+1.0),_exception);
          break;
        }
      if (LocaleCompare("shade",option+1) == 0)
        {
          flags=ParseGeometry(arg1,&geometry_info);
          if (((flags & RhoValue) == 0) || ((flags & SigmaValue) == 0))
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          new_image=ShadeImage(_image,IsNormalOp,geometry_info.rho,
               geometry_info.sigma,_exception);
          break;
        }
      if (LocaleCompare("shadow",option+1) == 0)
        {
          flags=ParseGeometry(arg1,&geometry_info);
          if ((flags & (RhoValue|SigmaValue)) == 0)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          if ((flags & SigmaValue) == 0)
            geometry_info.sigma=1.0;
          if ((flags & XiValue) == 0)
            geometry_info.xi=4.0;
          if ((flags & PsiValue) == 0)
            geometry_info.psi=4.0;
          new_image=ShadowImage(_image,geometry_info.rho,geometry_info.sigma,
            (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
            ceil(geometry_info.psi-0.5),_exception);
          break;
        }
      if (LocaleCompare("sharpen",option+1) == 0)
        {
          flags=ParseGeometry(arg1,&geometry_info);
          if ((flags & (RhoValue|SigmaValue)) == 0)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          if ((flags & SigmaValue) == 0)
            geometry_info.sigma=1.0;
          if ((flags & XiValue) == 0)
            geometry_info.xi=0.0;
          new_image=SharpenImage(_image,geometry_info.rho,geometry_info.sigma,
           _exception);
          break;
        }
      if (LocaleCompare("shave",option+1) == 0)
        {
          if (IsGeometry(arg1) == MagickFalse)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          flags=ParsePageGeometry(_image,arg1,&geometry,_exception);
          new_image=ShaveImage(_image,&geometry,_exception);
          break;
        }
      if (LocaleCompare("shear",option+1) == 0)
        {
          flags=ParseGeometry(arg1,&geometry_info);
          if ((flags & RhoValue) == 0)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          if ((flags & SigmaValue) == 0)
            geometry_info.sigma=geometry_info.rho;
          new_image=ShearImage(_image,geometry_info.rho,geometry_info.sigma,
            _exception);
          break;
        }
      if (LocaleCompare("sigmoidal-contrast",option+1) == 0)
        {
          flags=ParseGeometry(arg1,&geometry_info);
          if ((flags & RhoValue) == 0)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          if ((flags & SigmaValue) == 0)
            geometry_info.sigma=(double) QuantumRange/2.0;
          if ((flags & PercentValue) != 0)
            geometry_info.sigma=(double) QuantumRange*geometry_info.sigma/
              100.0;
          (void) SigmoidalContrastImage(_image,IsNormalOp,geometry_info.rho,
               geometry_info.sigma,_exception);
          break;
        }
      if (LocaleCompare("sketch",option+1) == 0)
        {
          flags=ParseGeometry(arg1,&geometry_info);
          if ((flags & (RhoValue|SigmaValue)) == 0)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          if ((flags & SigmaValue) == 0)
            geometry_info.sigma=1.0;
          new_image=SketchImage(_image,geometry_info.rho,
            geometry_info.sigma,geometry_info.xi,_exception);
          break;
        }
      if (LocaleCompare("solarize",option+1) == 0)
        {
          if (IsGeometry(arg1) == MagickFalse)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          (void) SolarizeImage(_image,StringToDoubleInterval(arg1,(double)
             QuantumRange+1.0),_exception);
          break;
        }
      if (LocaleCompare("sort-pixels",option+1) == 0)
        {
          (void) SortImagePixels(_image,_exception);
          break;
        }
      if (LocaleCompare("sparse-color",option+1) == 0)
        {
          parse=ParseCommandOption(MagickSparseColorOptions,MagickFalse,arg1);
          if (parse < 0)
            CLIWandExceptArgBreak(OptionError,"UnrecognizedSparseColorMethod",
              option,arg1);
          new_image=SparseColorOption(_image,(SparseColorMethod)parse,arg2,
            _exception);
          break;
        }
      if (LocaleCompare("splice",option+1) == 0)
        {
          if (IsGeometry(arg1) == MagickFalse)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          flags=ParseGravityGeometry(_image,arg1,&geometry,_exception);
          new_image=SpliceImage(_image,&geometry,_exception);
          break;
        }
      if (LocaleCompare("spread",option+1) == 0)
        {
          flags=ParseGeometry(arg1,&geometry_info);
          if ((flags & RhoValue) == 0)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
          new_image=SpreadImage(_image,_image->interpolate,geometry_info.rho,
           _exception);
          break;
        }
      if (LocaleCompare("statistic",option+1) == 0)
        {
          parse=ParseCommandOption(MagickStatisticOptions,MagickFalse,arg1);
          if ( parse < 0 )
            CLIWandExceptArgBreak(OptionError,"UnrecognizedStatisticType",
                 option,arg1);
          flags=ParseGeometry(arg2,&geometry_info);
          if ((flags & RhoValue) == 0)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg2);
          if ((flags & SigmaValue) == 0)
            geometry_info.sigma=geometry_info.rho;
          new_image=StatisticImage(_image,(StatisticType)parse,
               (size_t) geometry_info.rho,(size_t) geometry_info.sigma,
               _exception);
          break;
        }
      if (LocaleCompare("strip",option+1) == 0)
        {
          (void) StripImage(_image,_exception);
          break;
        }
      if (LocaleCompare("swirl",option+1) == 0)
        {
          flags=ParseGeometry(arg1,&geometry_info);
          if ((flags & RhoValue) == 0)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          new_image=SwirlImage(_image,geometry_info.rho,
            _image->interpolate,_exception);
          break;
        }
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
    }
    case 't':
    {
      if (LocaleCompare("threshold",option+1) == 0)
        {
          double
            threshold;

          threshold=(double) QuantumRange/2;
          if (IfNormalOp) {
            if (IsGeometry(arg1) == MagickFalse)
              CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
            threshold=StringToDoubleInterval(arg1,(double) QuantumRange+1.0);
          }
          (void) BilevelImage(_image,threshold,_exception);
          break;
        }
      if (LocaleCompare("thumbnail",option+1) == 0)
        {
          if (IsGeometry(arg1) == MagickFalse)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          (void) ParseRegionGeometry(_image,arg1,&geometry,_exception);
          new_image=ThumbnailImage(_image,geometry.width,geometry.height,
            _exception);
          break;
        }
      if (LocaleCompare("tint",option+1) == 0)
        {
          if (IsGeometry(arg1) == MagickFalse)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          new_image=TintImage(_image,arg1,&_draw_info->fill,_exception);
          break;
        }
      if (LocaleCompare("transform",option+1) == 0)
        {
          CLIWandWarnReplaced("+distort AffineProjection");
          new_image=AffineTransformImage(_image,&_draw_info->affine,_exception);
          break;
        }
      if (LocaleCompare("transparent",option+1) == 0)
        {
          PixelInfo
            target;

          (void) QueryColorCompliance(arg1,AllCompliance,&target,_exception);
          (void) TransparentPaintImage(_image,&target,(Quantum)
            TransparentAlpha,IsPlusOp,_exception);
          break;
        }
      if (LocaleCompare("transpose",option+1) == 0)
        {
          new_image=TransposeImage(_image,_exception);
          break;
        }
      if (LocaleCompare("transverse",option+1) == 0)
        {
          new_image=TransverseImage(_image,_exception);
          break;
        }
      if (LocaleCompare("trim",option+1) == 0)
        {
          new_image=TrimImage(_image,_exception);
          break;
        }
      if (LocaleCompare("type",option+1) == 0)
        {
          /* Note that "type" setting should have already been defined */
          (void) SetImageType(_image,_image_info->type,_exception);
          break;
        }
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
    }
    case 'u':
    {
      if (LocaleCompare("unique",option+1) == 0)
        {
          /* FUTURE: move to SyncImageSettings() and AcqireImage()???
             Option is not documented, bt appears to be for "identify".
             We may need a identify specific verbose!
          */
          if (IsPlusOp) {
              (void) DeleteImageArtifact(_image,"identify:unique-colors");
              break;
            }
          (void) SetImageArtifact(_image,"identify:unique-colors","true");
          (void) SetImageArtifact(_image,"verbose","true");
          break;
        }
      if (LocaleCompare("unique-colors",option+1) == 0)
        {
          new_image=UniqueImageColors(_image,_exception);
          break;
        }
      if (LocaleCompare("unsharp",option+1) == 0)
        {
          flags=ParseGeometry(arg1,&geometry_info);
          if ((flags & (RhoValue|SigmaValue)) == 0)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          if ((flags & SigmaValue) == 0)
            geometry_info.sigma=1.0;
          if ((flags & XiValue) == 0)
            geometry_info.xi=1.0;
          if ((flags & PsiValue) == 0)
            geometry_info.psi=0.05;
          new_image=UnsharpMaskImage(_image,geometry_info.rho,
            geometry_info.sigma,geometry_info.xi,geometry_info.psi,_exception);
          break;
        }
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
    }
    case 'v':
    {
      if (LocaleCompare("verbose",option+1) == 0)
        {
          /* FUTURE: move to SyncImageSettings() and AcquireImage()???
             three places!   ImageArtifact   ImageOption  _image_info->verbose
             Some how new images also get this artifact!
          */
          (void) SetImageArtifact(_image,option+1,IfNormalOp ? "true" :
            "false" );
          break;
        }
      if (LocaleCompare("vignette",option+1) == 0)
        {
          flags=ParseGeometry(arg1,&geometry_info);
          if ((flags & (RhoValue|SigmaValue)) == 0)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          if ((flags & SigmaValue) == 0)
            geometry_info.sigma=1.0;
          if ((flags & XiValue) == 0)
            geometry_info.xi=0.1*_image->columns;
          if ((flags & PsiValue) == 0)
            geometry_info.psi=0.1*_image->rows;
          if ((flags & PercentValue) != 0)
            {
              geometry_info.xi*=(double) _image->columns/100.0;
              geometry_info.psi*=(double) _image->rows/100.0;
            }
          new_image=VignetteImage(_image,geometry_info.rho,geometry_info.sigma,
            (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
            ceil(geometry_info.psi-0.5),_exception);
          break;
        }
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
    }
    case 'w':
    {
      if (LocaleCompare("wave",option+1) == 0)
        {
          flags=ParseGeometry(arg1,&geometry_info);
          if ((flags & (RhoValue|SigmaValue)) == 0)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          if ((flags & SigmaValue) == 0)
            geometry_info.sigma=1.0;
          new_image=WaveImage(_image,geometry_info.rho,geometry_info.sigma,
            _image->interpolate,_exception);
          break;
        }
      if (LocaleCompare("wavelet-denoise",option+1) == 0)
        {
          flags=ParseGeometry(arg1,&geometry_info);
          if ((flags & RhoValue) == 0)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          if ((flags & PercentValue) != 0)
            {
              geometry_info.rho=QuantumRange*geometry_info.rho/100.0;
              geometry_info.sigma=QuantumRange*geometry_info.sigma/100.0;
            }
          if ((flags & SigmaValue) == 0)
            geometry_info.sigma=0.0;
          new_image=WaveletDenoiseImage(_image,geometry_info.rho,
            geometry_info.sigma,_exception);
          break;
        }
      if (LocaleCompare("white-balance",option+1) == 0)
        {
          (void) WhiteBalanceImage(_image,_exception);
          break;
        }
      if (LocaleCompare("white-threshold",option+1) == 0)
        {
          if (IsGeometry(arg1) == MagickFalse)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          (void) WhiteThresholdImage(_image,arg1,_exception);
          break;
        }
      if (LocaleCompare("write-mask",option+1) == 0)
        {
          /* Note: arguments do not have percent escapes expanded */
          Image
            *mask;

          if (IfPlusOp)
            { /* Remove a mask. */
              (void) SetImageMask(_image,WritePixelMask,(const Image *) NULL,
                _exception);
              break;
            }
          /* Set the image mask. */
          mask=GetImageCache(_image_info,arg1,_exception);
          if (mask == (Image *) NULL)
            break;
          (void) SetImageMask(_image,WritePixelMask,mask,_exception);
          mask=DestroyImage(mask);
          break;
        }
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
    }
    default:
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
  }
  /* clean up percent escape interpreted strings */
  if (arg1 != arg1n )
    arg1=DestroyString((char *)arg1);
  if (arg2 != arg2n )
    arg2=DestroyString((char *)arg2);

  /* Replace current image with any image that was generated
     and set image point to last image (so image->next is correct) */
  if (new_image != (Image *) NULL)
    ReplaceImageInListReturnLast(&_image,new_image);

  return(MagickTrue);
#undef _image_info
#undef _draw_info
#undef _quantize_info
#undef _image
#undef _exception
#undef IfNormalOp
#undef IfPlusOp
#undef IsNormalOp
#undef IsPlusOp
}

Project: ImageMagick
File: tim2.c

static inline void ReadTIM2ImageHeader(Image *image,TIM2ImageHeader *header)
{
  header->total_size=ReadBlobLSBLong(image);
  header->clut_size=ReadBlobLSBLong(image);
  header->image_size=ReadBlobLSBLong(image);
  header->header_size=ReadBlobLSBShort(image);

  header->clut_color_count=ReadBlobLSBShort(image);
  header->img_format=(unsigned char) ReadBlobByte(image);
  header->mipmap_count=(unsigned char) ReadBlobByte(image);
  header->clut_type=(unsigned char) ReadBlobByte(image);
  header->bpp_type=(unsigned char) ReadBlobByte(image);

  header->width=ReadBlobLSBShort(image);
  header->height=ReadBlobLSBShort(image);

  header->GsTex0=ReadBlobMSBLongLong(image);
  header->GsTex1=ReadBlobMSBLongLong(image);
  header->GsRegs=ReadBlobMSBLong(image);
  header->GsTexClut=ReadBlobMSBLong(image);
}

Project: ImageMagick
File: operation.c

static Image *SparseColorOption(const Image *image,
  const SparseColorMethod method,const char *arguments,ExceptionInfo *exception)
{
  char
    token[MagickPathExtent];

  const char
    *p;

  double
    *sparse_arguments;

  Image
    *sparse_image;

  PixelInfo
    color;

  MagickBooleanType
    error;

  size_t
    x;

  size_t
    number_arguments,
    number_colors;

  assert(image != (Image *) NULL);
  assert(image->signature == MagickCoreSignature);
  if (image->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
  assert(exception != (ExceptionInfo *) NULL);
  assert(exception->signature == MagickCoreSignature);
  /*
    Limit channels according to image
    add up number of values needed per color.
  */
  number_colors=0;
  if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
    number_colors++;
  if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
    number_colors++;
  if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
    number_colors++;
  if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
      (image->colorspace == CMYKColorspace))
    number_colors++;
  if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
      image->alpha_trait != UndefinedPixelTrait)
    number_colors++;

  /*
    Read string, to determine number of arguments needed,
  */
  p=arguments;
  x=0;
  while( *p != '\0' )
  {
    (void) GetNextToken(p,&p,MagickPathExtent,token);
    if (*token == ',') continue;
    if ( isalpha((int) ((unsigned char) *token)) || *token == '#' )
      x += number_colors;  /* color argument found */
    else
      x++;   /* floating point argument */
  }
  /* control points and color values */
  if ((x % (2+number_colors)) != 0)
    {
      (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
        "InvalidArgument","'%s': %s", "sparse-color",
        "Invalid number of Arguments");
      return( (Image *) NULL);
    }
  error=MagickFalse;
  number_arguments=x;

  /* Allocate and fill in the floating point arguments */
  sparse_arguments=(double *) AcquireQuantumMemory(number_arguments,
    sizeof(*sparse_arguments));
  if (sparse_arguments == (double *) NULL) {
    (void) ThrowMagickException(exception,GetMagickModule(),ResourceLimitError,
      "MemoryAllocationFailed","%s","SparseColorOption");
    return( (Image *) NULL);
  }
  (void) memset(sparse_arguments,0,number_arguments*
    sizeof(*sparse_arguments));
  p=arguments;
  x=0;
  while ((*p != '\0') && (x < number_arguments))
  {
    /* X coordinate */
    *token=',';
    while (*token == ',')
      (void) GetNextToken(p,&p,MagickPathExtent,token);
    if (*token == '\0')
      break;
    if ( isalpha((int) ((unsigned char) *token)) || *token == '#' ) {
      (void) ThrowMagickException(exception,GetMagickModule(),
            OptionError, "InvalidArgument", "'%s': %s", "sparse-color",
            "Color found, instead of X-coord");
      error=MagickTrue;
      break;
    }
    sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
    /* Y coordinate */
    *token=',';
    while (*token == ',')
      (void) GetNextToken(p,&p,MagickPathExtent,token);
    if (*token == '\0')
      break;
    if ( isalpha((int) ((unsigned char) *token)) || *token == '#' ) {
      (void) ThrowMagickException(exception,GetMagickModule(),
            OptionError, "InvalidArgument", "'%s': %s", "sparse-color",
            "Color found, instead of Y-coord");
      error=MagickTrue;
      break;
    }
    sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
    /* color name or function given in string argument */
    *token=',';
    while (*token == ',')
      (void) GetNextToken(p,&p,MagickPathExtent,token);
    if (*token == '\0') break;
    if ( isalpha((int) ((unsigned char) *token)) || *token == '#' ) {
      /* Color string given */
      (void) QueryColorCompliance(token,AllCompliance,&color,
                exception);
      if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
        sparse_arguments[x++] = QuantumScale*color.red;
      if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
        sparse_arguments[x++] = QuantumScale*color.green;
      if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
        sparse_arguments[x++] = QuantumScale*color.blue;
      if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
          (image->colorspace == CMYKColorspace))
        sparse_arguments[x++] = QuantumScale*color.black;
      if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
          image->alpha_trait != UndefinedPixelTrait)
        sparse_arguments[x++] = QuantumScale*color.alpha;
    }
    else {
      /* Colors given as a set of floating point values - experimental */
      /* NB: token contains the first floating point value to use! */
      if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
        {
          while (*token == ',')
            (void) GetNextToken(p,&p,MagickPathExtent,token);
          if ((*token == '\0') || isalpha((int) ((unsigned char) *token)) || *token == '#' )
            break;
          sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
          *token=','; /* used this token - get another */
        }
      if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
        {
          while (*token == ',')
            (void) GetNextToken(p,&p,MagickPathExtent,token);
          if ((*token == '\0') || isalpha((int) ((unsigned char) *token)) || *token == '#' )
            break;
          sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
          *token=','; /* used this token - get another */
        }
      if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
        {
          while (*token == ',')
           (void) GetNextToken(p,&p,MagickPathExtent,token);
          if ((*token == '\0') || isalpha((int) ((unsigned char) *token)) || *token == '#' )
            break;
          sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
          *token = ','; /* used this token - get another */
        }
      if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
          (image->colorspace == CMYKColorspace))
        {
          while (*token == ',')
            (void) GetNextToken(p,&p,MagickPathExtent,token);
          if ((*token == '\0') || isalpha((int) ((unsigned char) *token)) || *token == '#' )
            break;
          sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
          *token=','; /* used this token - get another */
        }
      if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
          image->alpha_trait != UndefinedPixelTrait)
        {
          while (*token == ',')
            (void) GetNextToken(p,&p,MagickPathExtent,token);
          if ((*token == '\0') || isalpha((int) ((unsigned char) *token)) || *token == '#' )
            break;
          sparse_arguments[x++]=StringToDouble(token,(char **) NULL);
          *token = ','; /* used this token - get another */
        }
    }
  }
  if (error != MagickFalse)
    {
      sparse_arguments=(double *) RelinquishMagickMemory(sparse_arguments);
      return((Image *) NULL);
    }
  if (number_arguments != x)
    {
      sparse_arguments=(double *) RelinquishMagickMemory(sparse_arguments);
      (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
        "InvalidArgument","'%s': %s","sparse-color","Argument Parsing Error");
      return((Image *) NULL);
    }
  /* Call the Sparse Color Interpolation function with the parsed arguments */
  sparse_image=SparseColorImage(image,method,number_arguments,sparse_arguments,
    exception);
  sparse_arguments=(double *) RelinquishMagickMemory(sparse_arguments);
  return( sparse_image );
}

Project: ImageMagick
File: operation.c

WandPrivate void CLINoImageOperator(MagickCLI *cli_wand,
  const char *option,const char *arg1n,const char *arg2n)
{
  const char    /* percent escaped versions of the args */
    *arg1,
    *arg2;

#define _image_info     (cli_wand->wand.image_info)
#define _images         (cli_wand->wand.images)
#define _exception      (cli_wand->wand.exception)
#define _process_flags  (cli_wand->process_flags)
#define _option_type    ((CommandOptionFlags) cli_wand->command->flags)
#define IfNormalOp      (*option=='-')
#define IfPlusOp        (*option!='-')

  assert(cli_wand != (MagickCLI *) NULL);
  assert(cli_wand->signature == MagickWandSignature);
  assert(cli_wand->wand.signature == MagickWandSignature);

  if (cli_wand->wand.debug != MagickFalse)
    (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(),
      "- NoImage Operator: %s \"%s\" \"%s\"", option,
      arg1n != (char *) NULL ? arg1n : "",
      arg2n != (char *) NULL ? arg2n : "");

  arg1 = arg1n;
  arg2 = arg2n;

  /* Interpret Percent Escapes in Arguments - using first image */
  if ( (((_process_flags & ProcessInterpretProperities) != 0 )
        || ((_option_type & AlwaysInterpretArgsFlag) != 0)
       )  && ((_option_type & NeverInterpretArgsFlag) == 0) ) {
    /* Interpret Percent escapes in argument 1 */
    if (arg1n != (char *) NULL) {
      arg1=InterpretImageProperties(_image_info,_images,arg1n,_exception);
      if (arg1 == (char *) NULL) {
        CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
        arg1=arg1n;  /* use the given argument as is */
      }
    }
    if (arg2n != (char *) NULL) {
      arg2=InterpretImageProperties(_image_info,_images,arg2n,_exception);
      if (arg2 == (char *) NULL) {
        CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
        arg2=arg2n;  /* use the given argument as is */
      }
    }
  }
#undef _process_flags
#undef _option_type

  do {  /* break to exit code */
    /*
      No-op options  (ignore these)
    */
    if (LocaleCompare("noop",option+1) == 0)   /* zero argument */
      break;
    if (LocaleCompare("sans",option+1) == 0)   /* one argument */
      break;
    if (LocaleCompare("sans0",option+1) == 0)  /* zero argument */
      break;
    if (LocaleCompare("sans1",option+1) == 0)  /* one argument */
      break;
    if (LocaleCompare("sans2",option+1) == 0)  /* two arguments */
      break;
    /*
      Image Reading
    */
    if ( ( LocaleCompare("read",option+1) == 0 ) ||
      ( LocaleCompare("--",option) == 0 ) ) {
      /* Do Glob filename Expansion for 'arg1' then read all images.
      *
      * Expansion handles '@', '~', '*', and '?' meta-characters while ignoring
      * (but attaching to the filenames in the generated argument list) any
      * [...] read modifiers that may be present.
      *
      * For example: It will expand '*.gif[20x20]' into a list such as
      * 'abc.gif[20x20]',  'foobar.gif[20x20]',  'xyzzy.gif[20x20]'
      *
      * NOTE: In IMv6 this was done globally across all images. This
      * meant you could include IM options in '@filename' lists, but you
      * could not include comments.   Doing it only for image read makes
      * it far more secure.
      *
      * Note: arguments do not have percent escapes expanded for security
      * reasons.
      */
      int      argc;
      char     **argv;
      ssize_t  i;

      argc = 1;
      argv = (char **) &arg1;

      /* Expand 'glob' expressions in the given filename.
        Expansion handles any 'coder:' prefix, or read modifiers attached
        to the filename, including them in the resulting expanded list.
      */
      if (ExpandFilenames(&argc,&argv) == MagickFalse)
        CLIWandExceptArgBreak(ResourceLimitError,"MemoryAllocationFailed",
            option,GetExceptionMessage(errno));

      /* loop over expanded filename list, and read then all in */
      for (i=0; i < (ssize_t) argc; i++) {
        Image *
          new_images;
        if (_image_info->ping != MagickFalse)
          new_images=PingImages(_image_info,argv[i],_exception);
        else
          new_images=ReadImages(_image_info,argv[i],_exception);
        AppendImageToList(&_images, new_images);
        argv[i]=DestroyString(argv[i]);
      }
      argv=(char **) RelinquishMagickMemory(argv);
      break;
    }
    /*
      Image Writing
      Note: Writing a empty image list is valid in specific cases
    */
    if (LocaleCompare("write",option+1) == 0) {
      /* Note: arguments do not have percent escapes expanded */
      char
        key[MagickPathExtent];

      Image
        *write_images;

      ImageInfo
        *write_info;

      /* Need images, unless a "null:" output coder is used */
      if ( _images == (Image *) NULL ) {
        if ( LocaleCompare(arg1,"null:") == 0 )
          break;
        CLIWandExceptArgBreak(OptionError,"NoImagesForWrite",option,arg1);
      }

      (void) FormatLocaleString(key,MagickPathExtent,"cache:%s",arg1);
      (void) DeleteImageRegistry(key);
      write_images=CloneImageList(_images,_exception);
      write_info=CloneImageInfo(_image_info);
      if (write_images != (Image *) NULL)
        (void) WriteImages(write_info,write_images,arg1,_exception);
      write_info=DestroyImageInfo(write_info);
      write_images=DestroyImageList(write_images);
      break;
    }
    /*
      Parenthesis and Brace operations
    */
    if (LocaleCompare("(",option) == 0) {
      /* stack 'push' images */
      Stack
        *node;

      size_t
        size;

      size=0;
      node=cli_wand->image_list_stack;
      for ( ; node != (Stack *) NULL; node=node->next)
        size++;
      if ( size >= MAX_STACK_DEPTH )
        CLIWandExceptionBreak(OptionError,"ParenthesisNestedTooDeeply",option);
      node=(Stack *) AcquireMagickMemory(sizeof(*node));
      if (node == (Stack *) NULL)
        CLIWandExceptionBreak(ResourceLimitFatalError,
            "MemoryAllocationFailed",option);
      node->data = (void *)cli_wand->wand.images;
      node->next = cli_wand->image_list_stack;
      cli_wand->image_list_stack = node;
      cli_wand->wand.images = NewImageList();

      /* handle respect-parenthesis */
      if (IsStringTrue(GetImageOption(cli_wand->wand.image_info,
                    "respect-parenthesis")) != MagickFalse)
        option="{"; /* fall-thru so as to push image settings too */
      else
        break;
      /* fall thru to operation */
    }
    if (LocaleCompare("{",option) == 0) {
      /* stack 'push' of image_info settings */
      Stack
        *node;

      size_t
        size;

      size=0;
      node=cli_wand->image_info_stack;
      for ( ; node != (Stack *) NULL; node=node->next)
        size++;
      if ( size >= MAX_STACK_DEPTH )
        CLIWandExceptionBreak(OptionError,"CurlyBracesNestedTooDeeply",option);
      node=(Stack *) AcquireMagickMemory(sizeof(*node));
      if (node == (Stack *) NULL)
        CLIWandExceptionBreak(ResourceLimitFatalError,
            "MemoryAllocationFailed",option);

      node->data = (void *)cli_wand->wand.image_info;
      node->next = cli_wand->image_info_stack;

      cli_wand->image_info_stack = node;
      cli_wand->wand.image_info = CloneImageInfo(cli_wand->wand.image_info);
      if (cli_wand->wand.image_info == (ImageInfo *) NULL) {
        CLIWandException(ResourceLimitFatalError,"MemoryAllocationFailed",
            option);
        cli_wand->wand.image_info = (ImageInfo *)node->data;
        node = (Stack *)RelinquishMagickMemory(node);
        break;
      }

      break;
    }
    if (LocaleCompare(")",option) == 0) {
      /* pop images from stack */
      Stack
        *node;

      node = (Stack *)cli_wand->image_list_stack;
      if ( node == (Stack *) NULL)
        CLIWandExceptionBreak(OptionError,"UnbalancedParenthesis",option);
      cli_wand->image_list_stack = node->next;

      AppendImageToList((Image **)&node->data,cli_wand->wand.images);
      cli_wand->wand.images= (Image *)node->data;
      node = (Stack *)RelinquishMagickMemory(node);

      /* handle respect-parenthesis - of the previous 'pushed' settings */
      node = cli_wand->image_info_stack;
      if ( node != (Stack *) NULL)
        {
          if (IsStringTrue(GetImageOption(
                cli_wand->wand.image_info,"respect-parenthesis")) != MagickFalse)
            option="}"; /* fall-thru so as to pop image settings too */
          else
            break;
        }
      else
        break;
      /* fall thru to next if */
    }
    if (LocaleCompare("}",option) == 0) {
      /* pop image_info settings from stack */
      Stack
        *node;

      node = (Stack *)cli_wand->image_info_stack;
      if ( node == (Stack *) NULL)
        CLIWandExceptionBreak(OptionError,"UnbalancedCurlyBraces",option);
      cli_wand->image_info_stack = node->next;

      (void) DestroyImageInfo(cli_wand->wand.image_info);
      cli_wand->wand.image_info = (ImageInfo *)node->data;
      node = (Stack *)RelinquishMagickMemory(node);

      GetDrawInfo(cli_wand->wand.image_info, cli_wand->draw_info);
      cli_wand->quantize_info=DestroyQuantizeInfo(cli_wand->quantize_info);
      cli_wand->quantize_info=AcquireQuantizeInfo(cli_wand->wand.image_info);

      break;
    }
      if (LocaleCompare("print",option+1) == 0)
        {
          (void) FormatLocaleFile(stdout,"%s",arg1);
          break;
        }
    if (LocaleCompare("set",option+1) == 0)
      {
        /* Settings are applied to each image in memory in turn (if any).
           While a option: only need to be applied once globally.

           NOTE: rguments have not been automatically percent expaneded
        */

        /* escape the 'key' once only, using first image. */
        arg1=InterpretImageProperties(_image_info,_images,arg1n,_exception);
        if (arg1 == (char *) NULL)
          CLIWandExceptionBreak(OptionWarning,"InterpretPropertyFailure",
                option);

        if (LocaleNCompare(arg1,"registry:",9) == 0)
          {
            if (IfPlusOp)
              {
                (void) DeleteImageRegistry(arg1+9);
                arg1=DestroyString((char *)arg1);
                break;
              }
            arg2=InterpretImageProperties(_image_info,_images,arg2n,_exception);
            if (arg2 == (char *) NULL) {
              arg1=DestroyString((char *)arg1);
              CLIWandExceptionBreak(OptionWarning,"InterpretPropertyFailure",
                    option);
            }
            (void) SetImageRegistry(StringRegistryType,arg1+9,arg2,_exception);
            arg1=DestroyString((char *)arg1);
            arg2=DestroyString((char *)arg2);
            break;
          }
        if (LocaleNCompare(arg1,"option:",7) == 0)
          {
            /* delete equivelent artifact from all images (if any) */
            if (_images != (Image *) NULL)
              {
                MagickResetIterator(&cli_wand->wand);
                while (MagickNextImage(&cli_wand->wand) != MagickFalse)
                  (void) DeleteImageArtifact(_images,arg1+7);
                MagickResetIterator(&cli_wand->wand);
              }
            /* now set/delete the global option as needed */
            /* FUTURE: make escapes in a global 'option:' delayed */
            arg2=(char *) NULL;
            if (IfNormalOp)
              {
                arg2=InterpretImageProperties(_image_info,_images,arg2n,_exception);
                if (arg2 == (char *) NULL)
                  CLIWandExceptionBreak(OptionWarning,
                       "InterpretPropertyFailure",option);
              }
            (void) SetImageOption(_image_info,arg1+7,arg2);
            arg1=DestroyString((char *)arg1);
            arg2=DestroyString((char *)arg2);
            break;
          }
        /* Set Artifacts/Properties/Attributes all images (required) */
        if ( _images == (Image *) NULL )
          CLIWandExceptArgBreak(OptionWarning,"NoImageForProperty",option,arg1);

        MagickResetIterator(&cli_wand->wand);
        while (MagickNextImage(&cli_wand->wand) != MagickFalse)
          {
            arg2=(char *) NULL;
            if (IfNormalOp)
              {
                arg2=InterpretImageProperties(_image_info,_images,arg2n,_exception);
                if (arg2 == (char *) NULL)
                  CLIWandExceptionBreak(OptionWarning,
                       "InterpretPropertyFailure",option);
              }
            if (LocaleNCompare(arg1,"artifact:",9) == 0)
              (void) SetImageArtifact(_images,arg1+9,arg2);
            else if (LocaleNCompare(arg1,"property:",9) == 0)
              (void) SetImageProperty(_images,arg1+9,arg2,_exception);
            else
              (void) SetImageProperty(_images,arg1,arg2,_exception);
            arg2=DestroyString((char *)arg2);
          }
        MagickResetIterator(&cli_wand->wand);
        arg1=DestroyString((char *)arg1);
        break;
     }
    if (LocaleCompare("clone",option+1) == 0) {
        Image
          *new_images;

        if (*option == '+')
          arg1=AcquireString("-1");
        if (IsSceneGeometry(arg1,MagickFalse) == MagickFalse)
          CLIWandExceptionBreak(OptionError,"InvalidArgument",option);
        if ( cli_wand->image_list_stack == (Stack *) NULL)
          CLIWandExceptionBreak(OptionError,"UnableToCloneImage",option);
        new_images = (Image *)cli_wand->image_list_stack->data;
        if (new_images == (Image *) NULL)
          CLIWandExceptionBreak(OptionError,"UnableToCloneImage",option);
        new_images=CloneImages(new_images,arg1,_exception);
        if (new_images == (Image *) NULL)
          CLIWandExceptionBreak(OptionError,"NoSuchImage",option);
        AppendImageToList(&_images,new_images);
        break;
      }
    /*
       Informational Operations.

       Note that these do not require either a cli-wand or images!
       Though currently a cli-wand much be provided regardless.
    */
    if (LocaleCompare("version",option+1) == 0)
      {
        ListMagickVersion(stdout);
        break;
      }
    if (LocaleCompare("list",option+1) == 0) {
      /*
         FUTURE: This 'switch' should really be part of MagickCore
      */
      ssize_t
        list;

      list=ParseCommandOption(MagickListOptions,MagickFalse,arg1);
      if ( list < 0 ) {
        CLIWandExceptionArg(OptionError,"UnrecognizedListType",option,arg1);
        break;
      }
      switch (list)
      {
        case MagickCoderOptions:
        {
          (void) ListCoderInfo((FILE *) NULL,_exception);
          break;
        }
        case MagickColorOptions:
        {
          (void) ListColorInfo((FILE *) NULL,_exception);
          break;
        }
        case MagickConfigureOptions:
        {
          (void) ListConfigureInfo((FILE *) NULL,_exception);
          break;
        }
        case MagickDelegateOptions:
        {
          (void) ListDelegateInfo((FILE *) NULL,_exception);
          break;
        }
        case MagickFontOptions:
        {
          (void) ListTypeInfo((FILE *) NULL,_exception);
          break;
        }
        case MagickFormatOptions:
          (void) ListMagickInfo((FILE *) NULL,_exception);
          break;
        case MagickLocaleOptions:
          (void) ListLocaleInfo((FILE *) NULL,_exception);
          break;
        case MagickLogOptions:
          (void) ListLogInfo((FILE *) NULL,_exception);
          break;
        case MagickMagicOptions:
          (void) ListMagicInfo((FILE *) NULL,_exception);
          break;
        case MagickMimeOptions:
          (void) ListMimeInfo((FILE *) NULL,_exception);
          break;
        case MagickModuleOptions:
          (void) ListModuleInfo((FILE *) NULL,_exception);
          break;
        case MagickPolicyOptions:
          (void) ListPolicyInfo((FILE *) NULL,_exception);
          break;
        case MagickResourceOptions:
          (void) ListMagickResourceInfo((FILE *) NULL,_exception);
          break;
        case MagickThresholdOptions:
          (void) ListThresholdMaps((FILE *) NULL,_exception);
          break;
        default:
          (void) ListCommandOptions((FILE *) NULL,(CommandOption) list,
            _exception);
          break;
      }
      break;
    }

    CLIWandException(OptionError,"UnrecognizedOption",option);

DisableMSCWarning(4127)
  } while (0);  /* break to exit code. */
RestoreMSCWarning

  /* clean up percent escape interpreted strings */
  if (arg1 != arg1n )
    arg1=DestroyString((char *)arg1);
  if (arg2 != arg2n )
    arg2=DestroyString((char *)arg2);

#undef _image_info
#undef _images
#undef _exception
#undef IfNormalOp
#undef IfPlusOp
}

Project: ImageMagick
File: tim2.c

static Image *ReadTIM2Image(const ImageInfo *image_info,
  ExceptionInfo *exception)
{
  Image
    *image;

  MagickBooleanType
    status;

  ssize_t
    i,
    str_read;

  TIM2FileHeader
    file_header;

  /*
   * Open image file.
   */
  assert(image_info != (const ImageInfo *) NULL);
  assert(image_info->signature == MagickCoreSignature);

  if (image_info->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
      image_info->filename);
  assert(exception != (ExceptionInfo *) NULL);
  assert(exception->signature == MagickCoreSignature);
  image=AcquireImage(image_info,exception);
  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
  if (status == MagickFalse)
    {
      image=DestroyImageList(image);
      return((Image *) NULL);
    }
  /*
   * Verify TIM2 magic number.
   */
  file_header.magic_num=ReadBlobMSBLong(image);
  if (file_header.magic_num != 0x54494D32) /* "TIM2" */
    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
  /*
   * #### Read File Header ####
   */
  file_header.format_vers=ReadBlobByte(image);
  if (file_header.format_vers != 0x04)
    ThrowReaderException(CoderError,"ImageTypeNotSupported");
  file_header.format_type=ReadBlobByte(image);
  file_header.image_count=ReadBlobLSBShort(image);
  ReadBlobStream(image,8,&(file_header.reserved),&str_read);
  /*
   * Jump to first image header
   */
  switch(file_header.format_type)
  {
    case 0x00:
      if (DiscardBlobBytes(image,16) == MagickFalse)
        ThrowReaderException(CorruptImageError,"InsufficientImageDataInFile");
      break;
    case 0x01:
      if (DiscardBlobBytes(image,128) == MagickFalse)
        ThrowReaderException(CorruptImageError,"InsufficientImageDataInFile");
      break;
    default:
      ThrowReaderException(CoderError,"ImageTypeNotSupported");
  }
  /*
   * Process each image. Only one image supported for now
   */
  if (file_header.image_count != 1)
    ThrowReaderException(CoderError,"NumberOfImagesIsNotSupported");
  for (i=0; i < (ssize_t) file_header.image_count; i++)
  {
    char
      clut_depth,
      bits_per_pixel;

    TIM2ImageHeader
      image_header;

    ReadTIM2ImageHeader(image,&image_header);
    if (image_header.mipmap_count != 1)
      ThrowReaderException(CoderError,"NumberOfImagesIsNotSupported");
    if (image_header.header_size < 48)
      ThrowReaderException(CorruptImageError,"ImproperImageHeader");
    if ((MagickSizeType) image_header.image_size > GetBlobSize(image))
      ThrowReaderException(CorruptImageError,"InsufficientImageDataInFile");
    if ((MagickSizeType) image_header.clut_size > GetBlobSize(image))
      ThrowReaderException(CorruptImageError,"InsufficientImageDataInFile");
    image->columns=image_header.width;
    image->rows=image_header.height;
    clut_depth=0;
    if (image_header.clut_type !=0)
      {
        switch((int) image_header.clut_type&0x0F)  /* Low 4 bits */
        {
          case 1:
            clut_depth=16;
            break;
          case 2:
            clut_depth=24;
            break;
          case 3:
            clut_depth=32;
            break;
          default:
            ThrowReaderException(CorruptImageError,"ImproperImageHeader");
            break;
        }
      }
    switch ((int) image_header.bpp_type)
    {
      case 1:
        bits_per_pixel=16;
        break;
      case 2:
        bits_per_pixel=24;
        break;
      case 3:
        bits_per_pixel=32;
        break;
      case 4:
        bits_per_pixel=4;  /* Implies CLUT */
        break;
      case 5:
        bits_per_pixel=8;  /* Implies CLUT */
        break;
      default:
        ThrowReaderException(CorruptImageError,"ImproperImageHeader");
        break;
    }
    image->depth=(clut_depth != 0) ? clut_depth : bits_per_pixel;
    if ((image->depth == 16) || (image->depth == 32))
      image->alpha_trait=BlendPixelTrait;
    if (image->ping != MagickFalse)
      {
        status=ReadTIM2ImageData(image_info,image,&image_header,clut_depth,
          bits_per_pixel,exception);
        if (status==MagickFalse)
          break;
      }
    if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
      if (image->scene >= (image_info->scene+image_info->number_scenes-1))
        break;
    if ((image->storage_class == PseudoClass) && (EOFBlob(image) != MagickFalse))
      {
        ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
          image->filename);
        break;
      }
    /*
      Proceed to next image.
    */
    if (image_info->number_scenes != 0)
      if (image->scene >= (image_info->scene+image_info->number_scenes-1))
        break;
    /*
      Allocate next image structure.
    */
    AcquireNextImage(image_info,image,exception);
    if (GetNextImageInList(image) == (Image *) NULL)
      {
        status=MagickFalse;
        break;
      }
    image=SyncNextImageInList(image);
    status=SetImageProgress(image,LoadImagesTag,image->scene-1,image->scene);
    if (status == MagickFalse)
      break;
  }
  (void) CloseBlob(image);
  if (status == MagickFalse)
    return(DestroyImageList(image));
  return(GetFirstImageInList(image));
}

Project: ImageMagick
File: tim2.c

ModuleExport size_t RegisterTIM2Image(void)
{
  MagickInfo
    *entry;

  entry=AcquireMagickInfo("TIM2","TM2","PS2 TIM2");
  entry->decoder=(DecodeImageHandler *) ReadTIM2Image;
  (void) RegisterMagickInfo(entry);
  return(MagickImageCoderSignature);
}

Project: ImageMagick
File: operation.c

WandPrivate void CLISettingOptionInfo(MagickCLI *cli_wand,
     const char *option,const char *arg1n, const char *arg2n)
{
  ssize_t
    parse;     /* option argument parsing (string to value table lookup) */

  const char    /* percent escaped versions of the args */
    *arg1,
    *arg2;

#define _image_info       (cli_wand->wand.image_info)
#define _image            (cli_wand->wand.images)
#define _exception        (cli_wand->wand.exception)
#define _draw_info        (cli_wand->draw_info)
#define _quantize_info    (cli_wand->quantize_info)
#define IfSetOption       (*option=='-')
#define ArgBoolean        IfSetOption ? MagickTrue : MagickFalse
#define ArgBooleanNot     IfSetOption ? MagickFalse : MagickTrue
#define ArgBooleanString  (IfSetOption?"true":"false")
#define ArgOption(def)    (IfSetOption?arg1:(const char *)(def))

  assert(cli_wand != (MagickCLI *) NULL);
  assert(cli_wand->signature == MagickWandSignature);
  assert(cli_wand->wand.signature == MagickWandSignature);

  if (cli_wand->wand.debug != MagickFalse)
    (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(),
         "- Setting Option: %s \"%s\" \"%s\"", option,arg1n,arg2n);

  arg1 = arg1n,
  arg2 = arg2n;

#if 1
#define _process_flags    (cli_wand->process_flags)
#define _option_type      ((CommandOptionFlags) cli_wand->command->flags)
  /* Interpret Percent Escapes in Arguments - using first image */
  if ( (((_process_flags & ProcessInterpretProperities) != 0 )
        || ((_option_type & AlwaysInterpretArgsFlag) != 0)
       )  && ((_option_type & NeverInterpretArgsFlag) == 0) ) {
    /* Interpret Percent escapes in argument 1 */
    if (arg1n != (char *) NULL) {
      arg1=InterpretImageProperties(_image_info,_image,arg1n,_exception);
      if (arg1 == (char *) NULL) {
        CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
        arg1=arg1n;  /* use the given argument as is */
      }
    }
    if (arg2n != (char *) NULL) {
      arg2=InterpretImageProperties(_image_info,_image,arg2n,_exception);
      if (arg2 == (char *) NULL) {
        CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
        arg2=arg2n;  /* use the given argument as is */
      }
    }
  }
#undef _process_flags
#undef _option_type
#endif

  switch (*(option+1))
  {
    case 'a':
    {
      if (LocaleCompare("adjoin",option+1) == 0)
        {
          _image_info->adjoin = ArgBoolean;
          break;
        }
      if (LocaleCompare("affine",option+1) == 0)
        {
          CLIWandWarnReplaced("-draw 'affine ...'");
          if (IfSetOption)
            (void) ParseAffineGeometry(arg1,&_draw_info->affine,_exception);
          else
            GetAffineMatrix(&_draw_info->affine);
          break;
        }
      if (LocaleCompare("antialias",option+1) == 0)
        {
          _image_info->antialias =
            _draw_info->stroke_antialias =
              _draw_info->text_antialias = ArgBoolean;
          break;
        }
      if (LocaleCompare("attenuate",option+1) == 0)
        {
          if (IfSetOption && (IsGeometry(arg1) == MagickFalse))
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          (void) SetImageOption(_image_info,option+1,ArgOption("1.0"));
          break;
        }
      if (LocaleCompare("authenticate",option+1) == 0)
        {
          (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
          break;
        }
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
    }
    case 'b':
    {
      if (LocaleCompare("background",option+1) == 0)
        {
          /* FUTURE: both _image_info attribute & ImageOption in use!
             _image_info only used directly for generating new images.
             SyncImageSettings() used to set per-image attribute.

             FUTURE: if _image_info->background_color is not set then
             we should fall back to per-image background_color

             At this time -background will 'wipe out' the per-image
             background color!

             Better error handling of QueryColorCompliance() needed.
          */
          (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
          (void) QueryColorCompliance(ArgOption(MogrifyBackgroundColor),AllCompliance,
             &_image_info->background_color,_exception);
          break;
        }
      if (LocaleCompare("bias",option+1) == 0)
        {
          /* FUTURE: bias OBSOLETED, replaced by Artifact "convolve:bias"
             as it is actually rarely used except in direct convolve operations
             Usage outside a direct convolve operation is actally non-sensible!

             SyncImageSettings() used to set per-image attribute.
          */
          if (IfSetOption && (IsGeometry(arg1) == MagickFalse))
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          (void) SetImageOption(_image_info,"convolve:bias",ArgOption(NULL));
          break;
        }
      if (LocaleCompare("black-point-compensation",option+1) == 0)
        {
          /* Used as a image chromaticity setting
             SyncImageSettings() used to set per-image attribute.
          */
          (void) SetImageOption(_image_info,option+1,ArgBooleanString);
          break;
        }
      if (LocaleCompare("blue-primary",option+1) == 0)
        {
          /* Image chromaticity X,Y  NB: Y=X if Y not defined
             Used by many coders including PNG
             SyncImageSettings() used to set per-image attribute.
          */
          arg1=ArgOption("0.0");
          if (IsGeometry(arg1) == MagickFalse)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          (void) SetImageOption(_image_info,option+1,arg1);
          break;
        }
      if (LocaleCompare("bordercolor",option+1) == 0)
        {
          /* FUTURE: both _image_info attribute & ImageOption in use!
             SyncImageSettings() used to set per-image attribute.
             Better error checking of QueryColorCompliance().
          */
          if (IfSetOption)
            {
              (void) SetImageOption(_image_info,option+1,arg1);
              (void) QueryColorCompliance(arg1,AllCompliance,
                  &_image_info->border_color,_exception);
              (void) QueryColorCompliance(arg1,AllCompliance,
                  &_draw_info->border_color,_exception);
              break;
            }
          (void) DeleteImageOption(_image_info,option+1);
          (void) QueryColorCompliance(MogrifyBorderColor,AllCompliance,
            &_image_info->border_color,_exception);
          (void) QueryColorCompliance(MogrifyBorderColor,AllCompliance,
            &_draw_info->border_color,_exception);
          break;
        }
      if (LocaleCompare("box",option+1) == 0)
        {
          CLIWandWarnReplaced("-undercolor");
          CLISettingOptionInfo(cli_wand,"-undercolor",arg1, arg2);
          break;
        }
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
    }
    case 'c':
    {
      if (LocaleCompare("cache",option+1) == 0)
        {
          MagickSizeType
            limit;

          if (IfSetOption && (IsGeometry(arg1) == MagickFalse))
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          limit=MagickResourceInfinity;
          if (LocaleCompare("unlimited",arg1) != 0)
            limit=(MagickSizeType) SiPrefixToDoubleInterval(arg1,100.0);
          (void) SetMagickResourceLimit(MemoryResource,limit);
          (void) SetMagickResourceLimit(MapResource,2*limit);
          break;
        }
      if (LocaleCompare("caption",option+1) == 0)
        {
          (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
          break;
        }
      if (LocaleCompare("colorspace",option+1) == 0)
        {
          /* Setting used for new images via AquireImage()
             But also used as a SimpleImageOperator
             Undefined colorspace means don't modify images on
             read or as a operation */
          parse=ParseCommandOption(MagickColorspaceOptions,MagickFalse,
             ArgOption("undefined"));
          if (parse < 0)
            CLIWandExceptArgBreak(OptionError,"UnrecognizedColorspace",option,
              arg1);
          _image_info->colorspace=(ColorspaceType) parse;
          break;
        }
      if (LocaleCompare("comment",option+1) == 0)
        {
          (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
          break;
        }
      if (LocaleCompare("compose",option+1) == 0)
        {
          /* FUTURE: _image_info should be used,
             SyncImageSettings() used to set per-image attribute. - REMOVE

             This setting should NOT be used to set image 'compose'
             "-layer" operators shoud use _image_info if defined otherwise
             they should use a per-image compose setting.
          */
          parse = ParseCommandOption(MagickComposeOptions,MagickFalse,
                          ArgOption("undefined"));
          if (parse < 0)
            CLIWandExceptArgBreak(OptionError,"UnrecognizedComposeOperator",
                                      option,arg1);
          _image_info->compose=(CompositeOperator) parse;
          (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
          break;
        }
      if (LocaleCompare("compress",option+1) == 0)
        {
          /* FUTURE: What should be used?  _image_info  or ImageOption ???
             The former is more efficent, but Crisy prefers the latter!
             SyncImageSettings() used to set per-image attribute.

             The coders appears to use _image_info, not Image_Option
             however the image attribute (for save) is set from the
             ImageOption!

             Note that "undefined" is a different setting to "none".
          */
          parse = ParseCommandOption(MagickCompressOptions,MagickFalse,
                     ArgOption("undefined"));
          if (parse < 0)
            CLIWandExceptArgBreak(OptionError,"UnrecognizedImageCompression",
                                      option,arg1);
          _image_info->compression=(CompressionType) parse;
          (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
          break;
        }
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
    }
    case 'd':
    {
      if (LocaleCompare("debug",option+1) == 0)
        {
          /* SyncImageSettings() used to set per-image attribute. */
          arg1=ArgOption("none");
          parse = ParseCommandOption(MagickLogEventOptions,MagickFalse,arg1);
          if (parse < 0)
            CLIWandExceptArgBreak(OptionError,"UnrecognizedEventType",
                                      option,arg1);
          (void) SetLogEventMask(arg1);
          _image_info->debug=IsEventLogging();   /* extract logging*/
          cli_wand->wand.debug=IsEventLogging();
          break;
        }
      if (LocaleCompare("define",option+1) == 0)
        {
          if (LocaleNCompare(arg1,"registry:",9) == 0)
            {
              if (IfSetOption)
                (void) DefineImageRegistry(StringRegistryType,arg1+9,_exception);
              else
                (void) DeleteImageRegistry(arg1+9);
              break;
            }
          /* DefineImageOption() equals SetImageOption() but with '=' */
          if (IfSetOption)
            (void) DefineImageOption(_image_info,arg1);
          else if (DeleteImageOption(_image_info,arg1) == MagickFalse)
            CLIWandExceptArgBreak(OptionError,"NoSuchOption",option,arg1);
          break;
        }
      if (LocaleCompare("delay",option+1) == 0)
        {
          /* Only used for new images via AcquireImage()
             FUTURE: Option should also be used for "-morph" (color morphing)
          */
          arg1=ArgOption("0");
          if (IsGeometry(arg1) == MagickFalse)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          (void) SetImageOption(_image_info,option+1,arg1);
          break;
        }
      if (LocaleCompare("density",option+1) == 0)
        {
          /* FUTURE: strings used in _image_info attr and _draw_info!
             Basically as density can be in a XxY form!

             SyncImageSettings() used to set per-image attribute.
          */
          if (IfSetOption && (IsGeometry(arg1) == MagickFalse))
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
          (void) CloneString(&_image_info->density,ArgOption(NULL));
          (void) CloneString(&_draw_info->density,_image_info->density);
          break;
        }
      if (LocaleCompare("depth",option+1) == 0)
        {
          /* This is also a SimpleImageOperator! for 8->16 vaule trunc !!!!
             SyncImageSettings() used to set per-image attribute.
          */
          if (IfSetOption && (IsGeometry(arg1) == MagickFalse))
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          _image_info->depth=IfSetOption?StringToUnsignedLong(arg1)
                                       :MAGICKCORE_QUANTUM_DEPTH;
          break;
        }
      if (LocaleCompare("direction",option+1) == 0)
        {
          /* Image Option is only used to set _draw_info */
          arg1=ArgOption("undefined");
          parse = ParseCommandOption(MagickDirectionOptions,MagickFalse,arg1);
          if (parse < 0)
            CLIWandExceptArgBreak(OptionError,"UnrecognizedDirectionType",
                                      option,arg1);
          _draw_info->direction=(DirectionType) parse;
          (void) SetImageOption(_image_info,option+1,arg1);
          break;
        }
      if (LocaleCompare("display",option+1) == 0)
        {
          (void) CloneString(&_image_info->server_name,ArgOption(NULL));
          (void) CloneString(&_draw_info->server_name,_image_info->server_name);
          break;
        }
      if (LocaleCompare("dispose",option+1) == 0)
        {
          /* only used in setting new images */
          arg1=ArgOption("undefined");
          parse = ParseCommandOption(MagickDisposeOptions,MagickFalse,arg1);
          if (parse < 0)
            CLIWandExceptArgBreak(OptionError,"UnrecognizedDisposeMethod",
                                      option,arg1);
          (void) SetImageOption(_image_info,option+1,ArgOption("undefined"));
          break;
        }
      if (LocaleCompare("dissimilarity-threshold",option+1) == 0)
        {
          /* FUTURE: this is only used by CompareImages() which is used
             only by the "compare" CLI program at this time.  */
          arg1=ArgOption(DEFAULT_DISSIMILARITY_THRESHOLD);
          if (IsGeometry(arg1) == MagickFalse)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          (void) SetImageOption(_image_info,option+1,arg1);
          break;
        }
      if (LocaleCompare("dither",option+1) == 0)
        {
          /* _image_info attr (on/off), _quantize_info attr (on/off)
             but also ImageInfo and _quantize_info method!
             FUTURE: merge the duality of the dithering options
          */
          _image_info->dither = ArgBoolean;
          (void) SetImageOption(_image_info,option+1,ArgOption("none"));
          _quantize_info->dither_method=(DitherMethod) ParseCommandOption(
             MagickDitherOptions,MagickFalse,ArgOption("none"));
          if (_quantize_info->dither_method == NoDitherMethod)
            _image_info->dither = MagickFalse;
          break;
        }
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
    }
    case 'e':
    {
      if (LocaleCompare("encoding",option+1) == 0)
        {
          (void) CloneString(&_draw_info->encoding,ArgOption("undefined"));
          (void) SetImageOption(_image_info,option+1,_draw_info->encoding);
          break;
        }
      if (LocaleCompare("endian",option+1) == 0)
        {
          /* Both _image_info attr and ImageInfo */
          arg1 = ArgOption("undefined");
          parse = ParseCommandOption(MagickEndianOptions,MagickFalse,arg1);
          if (parse < 0)
            CLIWandExceptArgBreak(OptionError,"UnrecognizedEndianType",
                                      option,arg1);
          /* FUTURE: check alloc/free of endian string!  - remove? */
          _image_info->endian=(EndianType) (*arg1);
          (void) SetImageOption(_image_info,option+1,arg1);
          break;
        }
      if (LocaleCompare("extract",option+1) == 0)
        {
          (void) CloneString(&_image_info->extract,ArgOption(NULL));
          break;
        }
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
    }
    case 'f':
    {
      if (LocaleCompare("family",option+1) == 0)
        {
          (void) CloneString(&_draw_info->family,ArgOption(NULL));
          break;
        }
      if (LocaleCompare("features",option+1) == 0)
        {
          (void) SetImageOption(_image_info,"identify:features",
            ArgBooleanString);
          if (IfSetOption)
            (void) SetImageArtifact(_image,"verbose","true");
          break;
        }
      if (LocaleCompare("fill",option+1) == 0)
        {
          /* Set "fill" OR "fill-pattern" in _draw_info
             The original fill color is preserved if a fill-pattern is given.
             That way it does not effect other operations that directly using
             the fill color and, can be retored using "+tile".
          */
          MagickBooleanType
            status;

          ExceptionInfo
            *sans;

          PixelInfo
            color;

          arg1 = ArgOption("none");  /* +fill turns it off! */
          (void) SetImageOption(_image_info,option+1,arg1);
          if (_draw_info->fill_pattern != (Image *) NULL)
            _draw_info->fill_pattern=DestroyImage(_draw_info->fill_pattern);

          /* is it a color or a image? -- ignore exceptions */
          sans=AcquireExceptionInfo();
          status=QueryColorCompliance(arg1,AllCompliance,&color,sans);
          sans=DestroyExceptionInfo(sans);

          if (status == MagickFalse)
            _draw_info->fill_pattern=GetImageCache(_image_info,arg1,_exception);
          else
            _draw_info->fill=color;
          break;
        }
      if (LocaleCompare("filter",option+1) == 0)
        {
          /* SyncImageSettings() used to set per-image attribute. */
          arg1 = ArgOption("undefined");
          parse = ParseCommandOption(MagickFilterOptions,MagickFalse,arg1);
          if (parse < 0)
            CLIWandExceptArgBreak(OptionError,"UnrecognizedImageFilter",
                                      option,arg1);
          (void) SetImageOption(_image_info,option+1,arg1);
          break;
        }
      if (LocaleCompare("font",option+1) == 0)
        {
          (void) CloneString(&_draw_info->font,ArgOption(NULL));
          (void) CloneString(&_image_info->font,_draw_info->font);
          break;
        }
      if (LocaleCompare("format",option+1) == 0)
        {
          (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
          break;
        }
      if (LocaleCompare("fuzz",option+1) == 0)
        {
          /* Option used to set image fuzz! unless blank canvas (from color)
             Image attribute used for color compare operations
             SyncImageSettings() used to set per-image attribute.

             FUTURE: Can't find anything else using _image_info->fuzz directly!
                     convert structure attribute to 'option' string
          */
          arg1=ArgOption("0");
          if (IsGeometry(arg1) == MagickFalse)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          _image_info->fuzz=StringToDoubleInterval(arg1,(double)
                QuantumRange+1.0);
          (void) SetImageOption(_image_info,option+1,arg1);
          break;
        }
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
    }
    case 'g':
    {
      if (LocaleCompare("gravity",option+1) == 0)
        {
          /* SyncImageSettings() used to set per-image attribute. */
          arg1 = ArgOption("none");
          parse = ParseCommandOption(MagickGravityOptions,MagickFalse,arg1);
          if (parse < 0)
            CLIWandExceptArgBreak(OptionError,"UnrecognizedGravityType",
                                      option,arg1);
          _draw_info->gravity=(GravityType) parse;
          (void) SetImageOption(_image_info,option+1,arg1);
          break;
        }
      if (LocaleCompare("green-primary",option+1) == 0)
        {
          /* Image chromaticity X,Y  NB: Y=X if Y not defined
             SyncImageSettings() used to set per-image attribute.
             Used directly by many coders
          */
          arg1=ArgOption("0.0");
          if (IsGeometry(arg1) == MagickFalse)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          (void) SetImageOption(_image_info,option+1,arg1);
          break;
        }
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
    }
    case 'h':
    {
      if (LocaleCompare("highlight-color",option+1) == 0)
        {
          /* FUTURE: this is only used by CompareImages() which is used
             only by the "compare" CLI program at this time.  */
          (void) SetImageOption(_image_info,"compare:highlight-color",
            ArgOption(NULL));
          break;
        }
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
    }
    case 'i':
    {
      if (LocaleCompare("illuminant",option+1) == 0)
        {
          (void) SetImageOption(_image_info,"color:illuminant",
            ArgOption(NULL));
          break;
        }
      if (LocaleCompare("intensity",option+1) == 0)
        {
          arg1 = ArgOption("undefined");
          parse = ParseCommandOption(MagickPixelIntensityOptions,MagickFalse,
            arg1);
          if (parse < 0)
            CLIWandExceptArgBreak(OptionError,"UnrecognizedIntensityType",
              option,arg1);
          (void) SetImageOption(_image_info,option+1,arg1);
          break;
        }
      if (LocaleCompare("intent",option+1) == 0)
        {
          /* Only used by coders: MIFF, MPC, BMP, PNG
             and for image profile call to AcquireTransformTLS()
             SyncImageSettings() used to set per-image attribute.
          */
          arg1 = ArgOption("undefined");
          parse = ParseCommandOption(MagickIntentOptions,MagickFalse,arg1);
          if (parse < 0)
            CLIWandExceptArgBreak(OptionError,"UnrecognizedIntentType",
                                      option,arg1);
          (void) SetImageOption(_image_info,option+1,arg1);
          break;
        }
      if (LocaleCompare("interlace",option+1) == 0)
        {
          /* _image_info is directly used by coders (so why an image setting?)
             SyncImageSettings() used to set per-image attribute.
          */
          arg1 = ArgOption("undefined");
          parse = ParseCommandOption(MagickInterlaceOptions,MagickFalse,arg1);
          if (parse < 0)
            CLIWandExceptArgBreak(OptionError,"UnrecognizedInterlaceType",
                                      option,arg1);
          _image_info->interlace=(InterlaceType) parse;
          (void) SetImageOption(_image_info,option+1,arg1);
          break;
        }
      if (LocaleCompare("interline-spacing",option+1) == 0)
        {
          if (IfSetOption && (IsGeometry(arg1) == MagickFalse))
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          (void) SetImageOption(_image_info,option+1, ArgOption(NULL));
          _draw_info->interline_spacing=StringToDouble(ArgOption("0"),
               (char **) NULL);
          break;
        }
      if (LocaleCompare("interpolate",option+1) == 0)
        {
          /* SyncImageSettings() used to set per-image attribute. */
          arg1 = ArgOption("undefined");
          parse = ParseCommandOption(MagickInterpolateOptions,MagickFalse,arg1);
          if (parse < 0)
            CLIWandExceptArgBreak(OptionError,"UnrecognizedInterpolateMethod",
                                      option,arg1);
          (void) SetImageOption(_image_info,option+1,arg1);
          break;
        }
      if (LocaleCompare("interword-spacing",option+1) == 0)
        {
          if (IfSetOption && (IsGeometry(arg1) == MagickFalse))
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          (void) SetImageOption(_image_info,option+1, ArgOption(NULL));
          _draw_info->interword_spacing=StringToDouble(ArgOption("0"),(char **) NULL);
          break;
        }
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
    }
    case 'k':
    {
      if (LocaleCompare("kerning",option+1) == 0)
        {
          if (IfSetOption && (IsGeometry(arg1) == MagickFalse))
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
          _draw_info->kerning=StringToDouble(ArgOption("0"),(char **) NULL);
          break;
        }
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
    }
    case 'l':
    {
      if (LocaleCompare("label",option+1) == 0)
        {
          /* only used for new images - not in SyncImageOptions() */
          (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
          break;
        }
      if (LocaleCompare("limit",option+1) == 0)
        {
          MagickSizeType
            limit;

          limit=MagickResourceInfinity;
          parse= ParseCommandOption(MagickResourceOptions,MagickFalse,arg1);
          if ( parse < 0 )
            CLIWandExceptArgBreak(OptionError,"UnrecognizedResourceType",
                option,arg1);
          if (LocaleCompare("unlimited",arg2) != 0)
            limit=(MagickSizeType) SiPrefixToDoubleInterval(arg2,100.0);
          (void) SetMagickResourceLimit((ResourceType)parse,limit);
          break;
        }
      if (LocaleCompare("log",option+1) == 0)
        {
          if (IfSetOption) {
            if ((strchr(arg1,'%') == (char *) NULL))
              CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
            (void) SetLogFormat(arg1);
          }
          break;
        }
      if (LocaleCompare("lowlight-color",option+1) == 0)
        {
          /* FUTURE: this is only used by CompareImages() which is used
             only by the "compare" CLI program at this time.  */
          (void) SetImageOption(_image_info,"compare:lowlight-color",
            ArgOption(NULL));
          break;
        }
      if (LocaleCompare("loop",option+1) == 0)
        {
          /* SyncImageSettings() used to set per-image attribute. */
          arg1=ArgOption("0");
          if (IsGeometry(arg1) == MagickFalse)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          (void) SetImageOption(_image_info,option+1,arg1);
          break;
        }
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
    }
    case 'm':
    {
      if (LocaleCompare("mattecolor",option+1) == 0)
        {
          /* SyncImageSettings() used to set per-image attribute. */
          (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
          (void) QueryColorCompliance(ArgOption(MogrifyAlphaColor),
            AllCompliance,&_image_info->matte_color,_exception);
          break;
        }
      if (LocaleCompare("metric",option+1) == 0)
        {
          /* FUTURE: this is only used by CompareImages() which is used
             only by the "compare" CLI program at this time.  */
          parse=ParseCommandOption(MagickMetricOptions,MagickFalse,arg1);
          if ( parse < 0 )
            CLIWandExceptArgBreak(OptionError,"UnrecognizedMetricType",
                option,arg1);
          (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
          break;
        }
      if (LocaleCompare("moments",option+1) == 0)
        {
          (void) SetImageOption(_image_info,"identify:moments",
            ArgBooleanString);
          if (IfSetOption)
            (void) SetImageArtifact(_image,"verbose","true");
          break;
        }
      if (LocaleCompare("monitor",option+1) == 0)
        {
          (void) SetImageInfoProgressMonitor(_image_info, IfSetOption?
                MonitorProgress: (MagickProgressMonitor) NULL, (void *) NULL);
          break;
        }
      if (LocaleCompare("monochrome",option+1) == 0)
        {
          /* Setting (used by some input coders!) -- why?
             Warning: This is also Special '-type' SimpleOperator
          */
          _image_info->monochrome= ArgBoolean;
          break;
        }
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
    }
    case 'o':
    {
      if (LocaleCompare("orient",option+1) == 0)
        {
          /* Is not used when defining for new images.
             This makes it more of a 'operation' than a setting
             FUTURE: make set meta-data operator instead.
             SyncImageSettings() used to set per-image attribute.
          */
          parse=ParseCommandOption(MagickOrientationOptions,MagickFalse,
               ArgOption("undefined"));
          if (parse < 0)
            CLIWandExceptArgBreak(OptionError,"UnrecognizedImageOrientation",
                                      option,arg1);
          _image_info->orientation=(OrientationType)parse;
          (void) SetImageOption(_image_info,option+1, ArgOption(NULL));
          break;
        }
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
    }
    case 'p':
    {
      if (LocaleCompare("page",option+1) == 0)
        {
          /* Only used for new images and image generators.
             SyncImageSettings() used to set per-image attribute. ?????
             That last is WRONG!!!!
             FUTURE: adjust named 'page' sizes according density
          */
          char
            *canonical_page,
            page[MagickPathExtent];

          const char
            *image_option;

          MagickStatusType
            flags;

          RectangleInfo
            geometry;

          if (!IfSetOption)
            {
              (void) DeleteImageOption(_image_info,option+1);
              (void) CloneString(&_image_info->page,(char *) NULL);
              break;
            }
          (void) memset(&geometry,0,sizeof(geometry));
          image_option=GetImageOption(_image_info,"page");
          if (image_option != (const char *) NULL)
            flags=ParseAbsoluteGeometry(image_option,&geometry);
          canonical_page=GetPageGeometry(arg1);
          flags=ParseAbsoluteGeometry(canonical_page,&geometry);
          canonical_page=DestroyString(canonical_page);
          (void) FormatLocaleString(page,MagickPathExtent,"%lux%lu",
            (unsigned long) geometry.width,(unsigned long) geometry.height);
          if (((flags & XValue) != 0) || ((flags & YValue) != 0))
            (void) FormatLocaleString(page,MagickPathExtent,"%lux%lu%+ld%+ld",
              (unsigned long) geometry.width,(unsigned long) geometry.height,
              (long) geometry.x,(long) geometry.y);
          (void) SetImageOption(_image_info,option+1,page);
          (void) CloneString(&_image_info->page,page);
          break;
        }
      if (LocaleCompare("ping",option+1) == 0)
        {
          _image_info->ping=ArgBoolean;
          break;
        }
      if (LocaleCompare("pointsize",option+1) == 0)
        {
          if (IfSetOption) {
            if (IsGeometry(arg1) == MagickFalse)
              CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
            _image_info->pointsize =
            _draw_info->pointsize =
              StringToDouble(arg1,(char **) NULL);
          }
          else {
            _image_info->pointsize=0.0; /* unset pointsize */
            _draw_info->pointsize=12.0;
          }
          break;
        }
      if (LocaleCompare("precision",option+1) == 0)
        {
          arg1=ArgOption("-1");
          if (IsGeometry(arg1) == MagickFalse)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          (void) SetMagickPrecision(StringToInteger(arg1));
          break;
        }
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
    }
    case 'q':
    {
      if (LocaleCompare("quality",option+1) == 0)
        {
          if (IfSetOption && (IsGeometry(arg1) == MagickFalse))
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          _image_info->quality= IfSetOption ? StringToUnsignedLong(arg1)
                                            : UNDEFINED_COMPRESSION_QUALITY;
          (void) SetImageOption(_image_info,option+1,ArgOption("0"));
          break;
        }
      if (LocaleCompare("quantize",option+1) == 0)
        {
          /* Just a set direct in _quantize_info */
          arg1=ArgOption("undefined");
          parse=ParseCommandOption(MagickColorspaceOptions,MagickFalse,arg1);
          if (parse < 0)
            CLIWandExceptArgBreak(OptionError,"UnrecognizedColorspace",
                 option,arg1);
          _quantize_info->colorspace=(ColorspaceType)parse;
          break;
        }
      if (LocaleCompare("quiet",option+1) == 0)
        {
          /* FUTURE: if two -quiet is performed you can not do +quiet!
             This needs to be checked over thoughly.
          */
          static WarningHandler
            warning_handler = (WarningHandler) NULL;

          WarningHandler
            tmp = SetWarningHandler((WarningHandler) NULL);

          if ( tmp != (WarningHandler) NULL)
            warning_handler = tmp; /* remember the old handler */
          if (!IfSetOption)        /* set the old handler */
            warning_handler=SetWarningHandler(warning_handler);
          break;
        }
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
    }
    case 'r':
    {
      if (LocaleCompare("red-primary",option+1) == 0)
        {
          /* Image chromaticity X,Y  NB: Y=X if Y not defined
             Used by many coders
             SyncImageSettings() used to set per-image attribute.
          */
          arg1=ArgOption("0.0");
          if (IsGeometry(arg1) == MagickFalse)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          (void) SetImageOption(_image_info,option+1,arg1);
          break;
        }
      if (LocaleCompare("regard-warnings",option+1) == 0)
        /* FUTURE: to be replaced by a 'fatal-level' type setting */
        break;
      if (LocaleCompare("render",option+1) == 0)
        {
          /* _draw_info only setting */
          _draw_info->render= ArgBooleanNot;
          break;
        }
      if (LocaleCompare("respect-parenthesis",option+1) == 0)
        {
          /* link image and setting stacks - option is itself saved on stack! */
          (void) SetImageOption(_image_info,option+1,ArgBooleanString);
          break;
        }
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
    }
    case 's':
    {
      if (LocaleCompare("sampling-factor",option+1) == 0)
        {
          /* FUTURE: should be converted to jpeg:sampling_factor */
          if (IfSetOption && (IsGeometry(arg1) == MagickFalse))
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          (void) CloneString(&_image_info->sampling_factor,ArgOption(NULL));
          break;
        }
      if (LocaleCompare("scene",option+1) == 0)
        {
          /* SyncImageSettings() used to set this as a per-image attribute.
             What ??? Why ????
          */
          if (IfSetOption && (IsGeometry(arg1) == MagickFalse))
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
          _image_info->scene=StringToUnsignedLong(ArgOption("0"));
          break;
        }
      if (LocaleCompare("seed",option+1) == 0)
        {
          if (IfSetOption && (IsGeometry(arg1) == MagickFalse))
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          SetRandomSecretKey(
               IfSetOption ? (unsigned long) StringToUnsignedLong(arg1)
                           : (unsigned long) time((time_t *) NULL));
          break;
        }
      if (LocaleCompare("size",option+1) == 0)
        {
          /* FUTURE: string in _image_info -- convert to Option ???
             Look at the special handling for "size" in SetImageOption()
           */
          (void) CloneString(&_image_info->size,ArgOption(NULL));
          break;
        }
      if (LocaleCompare("stretch",option+1) == 0)
        {
          arg1=ArgOption("undefined");
          parse = ParseCommandOption(MagickStretchOptions,MagickFalse,arg1);
          if (parse < 0)
            CLIWandExceptArgBreak(OptionError,"UnrecognizedStretchType",
                 option,arg1);
          _draw_info->stretch=(StretchType) parse;
          break;
        }
      if (LocaleCompare("stroke",option+1) == 0)
        {
          /* set stroke color OR stroke-pattern
             UPDATE: ensure stroke color is not destroyed is a pattern
             is given. Just in case the color is also used for other purposes.
           */
          MagickBooleanType
            status;

          ExceptionInfo
            *sans;

          PixelInfo
            color;

          arg1 = ArgOption("none");  /* +fill turns it off! */
          (void) SetImageOption(_image_info,option+1,arg1);
          if (_draw_info->stroke_pattern != (Image *) NULL)
            _draw_info->stroke_pattern=DestroyImage(_draw_info->stroke_pattern);

          /* is it a color or a image? -- ignore exceptions */
          sans=AcquireExceptionInfo();
          status=QueryColorCompliance(arg1,AllCompliance,&color,sans);
          sans=DestroyExceptionInfo(sans);

          if (status == MagickFalse)
            _draw_info->stroke_pattern=GetImageCache(_image_info,arg1,_exception);
          else
            _draw_info->stroke=color;
          break;
        }
      if (LocaleCompare("strokewidth",option+1) == 0)
        {
          if (IfSetOption && (IsGeometry(arg1) == MagickFalse))
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
          _draw_info->stroke_width=StringToDouble(ArgOption("1.0"),
               (char **) NULL);
          break;
        }
      if (LocaleCompare("style",option+1) == 0)
        {
          arg1=ArgOption("undefined");
          parse = ParseCommandOption(MagickStyleOptions,MagickFalse,arg1);
          if (parse < 0)
            CLIWandExceptArgBreak(OptionError,"UnrecognizedStyleType",
                 option,arg1);
          _draw_info->style=(StyleType) parse;
          break;
        }
#if 0
      if (LocaleCompare("subimage-search",option+1) == 0)
        {
        /* FUTURE: this is only used by CompareImages() which is used
            only by the "compare" CLI program at this time.  */
          (void) SetImageOption(_image_info,option+1,ArgBooleanString);
          break;
        }
#endif
      if (LocaleCompare("synchronize",option+1) == 0)
        {
          /* FUTURE: syncronize to storage - but what does that mean? */
          _image_info->synchronize = ArgBoolean;
          break;
        }
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
    }
    case 't':
    {
      if (LocaleCompare("taint",option+1) == 0)
        {
          /* SyncImageSettings() used to set per-image attribute. */
          (void) SetImageOption(_image_info,option+1,ArgBooleanString);
          break;
        }
      if (LocaleCompare("texture",option+1) == 0)
        {
          /* Note: arguments do not have percent escapes expanded */
          /* FUTURE: move _image_info string to option splay-tree
             Other than "montage" what uses "texture" ????
          */
          (void) CloneString(&_image_info->texture,ArgOption(NULL));
          break;
        }
      if (LocaleCompare("tile",option+1) == 0)
        {
          /* Note: arguments do not have percent escapes expanded */
          _draw_info->fill_pattern=IfSetOption
                                 ?GetImageCache(_image_info,arg1,_exception)
                                 :DestroyImage(_draw_info->fill_pattern);
          break;
        }
      if (LocaleCompare("tile-offset",option+1) == 0)
        {
          /* SyncImageSettings() used to set per-image attribute. ??? */
          arg1=ArgOption("0");
          if (IsGeometry(arg1) == MagickFalse)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          (void) SetImageOption(_image_info,option+1,arg1);
          break;
        }
      if (LocaleCompare("transparent-color",option+1) == 0)
        {
          /* FUTURE: both _image_info attribute & ImageOption in use!
             _image_info only used for generating new images.
             SyncImageSettings() used to set per-image attribute.

             Note that +transparent-color, means fall-back to image
             attribute so ImageOption is deleted, not set to a default.
          */
          if (IfSetOption && (IsGeometry(arg1) == MagickFalse))
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
          (void) QueryColorCompliance(ArgOption("none"),AllCompliance,
              &_image_info->transparent_color,_exception);
          break;
        }
      if (LocaleCompare("treedepth",option+1) == 0)
        {
          (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
          _quantize_info->tree_depth=StringToUnsignedLong(ArgOption("0"));
          break;
        }
      if (LocaleCompare("type",option+1) == 0)
        {
          /* SyncImageSettings() used to set per-image attribute. */
          parse=ParseCommandOption(MagickTypeOptions,MagickFalse,
               ArgOption("undefined"));
          if (parse < 0)
            CLIWandExceptArgBreak(OptionError,"UnrecognizedImageType",
                 option,arg1);
          _image_info->type=(ImageType) parse;
          (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
          break;
        }
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
    }
    case 'u':
    {
      if (LocaleCompare("undercolor",option+1) == 0)
        {
          (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
          (void) QueryColorCompliance(ArgOption("none"),AllCompliance,
               &_draw_info->undercolor,_exception);
          break;
        }
      if (LocaleCompare("units",option+1) == 0)
        {
          /* SyncImageSettings() used to set per-image attribute.
             Should this effect _draw_info X and Y resolution?
             FUTURE: this probably should be part of the density setting
          */
          parse=ParseCommandOption(MagickResolutionOptions,MagickFalse,
               ArgOption("undefined"));
          if (parse < 0)
            CLIWandExceptArgBreak(OptionError,"UnrecognizedUnitsType",
                 option,arg1);
          _image_info->units=(ResolutionType) parse;
          (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
          break;
        }
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
    }
    case 'v':
    {
      if (LocaleCompare("verbose",option+1) == 0)
        {
          /* FUTURE: Remember all options become image artifacts
             _image_info->verbose is only used by coders.
          */
          (void) SetImageOption(_image_info,option+1,ArgBooleanString);
          _image_info->verbose= ArgBoolean;
          _image_info->ping=MagickFalse; /* verbose can't be a ping */
          break;
        }
      if (LocaleCompare("virtual-pixel",option+1) == 0)
        {
          /* SyncImageSettings() used to set per-image attribute.
             This is VERY deep in the image caching structure.
          */
          parse=ParseCommandOption(MagickVirtualPixelOptions,MagickFalse,
               ArgOption("undefined"));
          if (parse < 0)
            CLIWandExceptArgBreak(OptionError,"UnrecognizedVirtualPixelMethod",
                 option,arg1);
          (void) SetImageOption(_image_info,option+1,ArgOption(NULL));
          break;
        }
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
    }
    case 'w':
    {
      if (LocaleCompare("weight",option+1) == 0)
        {
          ssize_t
            weight;

          weight=ParseCommandOption(MagickWeightOptions,MagickFalse,arg1);
          if (weight == -1)
            weight=(ssize_t) StringToUnsignedLong(arg1);
          _draw_info->weight=(size_t) weight;
          break;
        }
      if (LocaleCompare("white-point",option+1) == 0)
        {
          /* Used as a image chromaticity setting
             SyncImageSettings() used to set per-image attribute.
          */
          arg1=ArgOption("0.0");
          if (IsGeometry(arg1) == MagickFalse)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          (void) SetImageOption(_image_info,option+1,arg1);
          break;
        }
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
    }
    default:
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
  }

  /* clean up percent escape interpreted strings */
  if ((arg1 && arg1n) && (arg1 != arg1n ))
    arg1=DestroyString((char *) arg1);
  if ((arg2 && arg2n) && (arg2 != arg2n ))
    arg2=DestroyString((char *) arg2);

#undef _image_info
#undef _exception
#undef _draw_info
#undef _quantize_info
#undef IfSetOption
#undef ArgBoolean
#undef ArgBooleanNot
#undef ArgBooleanString
#undef ArgOption

  return;
}

Project: ImageMagick
File: operation.c

WandPrivate MagickBooleanType CLIListOperatorImages(MagickCLI *cli_wand,
  const char *option,const char *arg1n,const char *arg2n)
{
  const char    /* percent escaped versions of the args */
    *arg1,
    *arg2;

  Image
    *new_images;

  MagickStatusType
    status;

  ssize_t
    parse;

#define _image_info     (cli_wand->wand.image_info)
#define _images         (cli_wand->wand.images)
#define _exception      (cli_wand->wand.exception)
#define _draw_info      (cli_wand->draw_info)
#define _quantize_info  (cli_wand->quantize_info)
#define _process_flags  (cli_wand->process_flags)
#define _option_type    ((CommandOptionFlags) cli_wand->command->flags)
#define IfNormalOp      (*option=='-')
#define IfPlusOp        (*option!='-')
#define IsNormalOp      IfNormalOp ? MagickTrue : MagickFalse

  assert(cli_wand != (MagickCLI *) NULL);
  assert(cli_wand->signature == MagickWandSignature);
  assert(cli_wand->wand.signature == MagickWandSignature);
  assert(_images != (Image *) NULL);             /* _images must be present */

  if (cli_wand->wand.debug != MagickFalse)
    (void) CLILogEvent(cli_wand,CommandEvent,GetMagickModule(),
       "- List Operator: %s \"%s\" \"%s\"", option,
       arg1n == (const char *) NULL ? "null" : arg1n,
       arg2n == (const char *) NULL ? "null" : arg2n);

  arg1 = arg1n;
  arg2 = arg2n;

  /* Interpret Percent Escapes in Arguments - using first image */
  if ( (((_process_flags & ProcessInterpretProperities) != 0 )
        || ((_option_type & AlwaysInterpretArgsFlag) != 0)
       )  && ((_option_type & NeverInterpretArgsFlag) == 0) ) {
    /* Interpret Percent escapes in argument 1 */
    if (arg1n != (char *) NULL) {
      arg1=InterpretImageProperties(_image_info,_images,arg1n,_exception);
      if (arg1 == (char *) NULL) {
        CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
        arg1=arg1n;  /* use the given argument as is */
      }
    }
    if (arg2n != (char *) NULL) {
      arg2=InterpretImageProperties(_image_info,_images,arg2n,_exception);
      if (arg2 == (char *) NULL) {
        CLIWandException(OptionWarning,"InterpretPropertyFailure",option);
        arg2=arg2n;  /* use the given argument as is */
      }
    }
  }
#undef _process_flags
#undef _option_type

  status=MagickTrue;
  new_images=NewImageList();

  switch (*(option+1))
  {
    case 'a':
    {
      if (LocaleCompare("append",option+1) == 0)
        {
          new_images=AppendImages(_images,IsNormalOp,_exception);
          break;
        }
      if (LocaleCompare("average",option+1) == 0)
        {
          CLIWandWarnReplaced("-evaluate-sequence Mean");
          (void) CLIListOperatorImages(cli_wand,"-evaluate-sequence","Mean",
            NULL);
          break;
        }
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
    }
    case 'c':
    {
      if (LocaleCompare("channel-fx",option+1) == 0)
        {
          new_images=ChannelFxImage(_images,arg1,_exception);
          break;
        }
      if (LocaleCompare("clut",option+1) == 0)
        {
          Image
            *clut_image;

          /* FUTURE - make this a compose option, and thus can be used
             with layers compose or even compose last image over all other
             _images.
          */
          new_images=RemoveFirstImageFromList(&_images);
          clut_image=RemoveFirstImageFromList(&_images);
          /* FUTURE - produce Exception, rather than silent fail */
          if (clut_image == (Image *) NULL)
            {
              (void) ThrowMagickException(_exception,GetMagickModule(),
                OptionError,"ImageSequenceRequired","`%s'",option);
              new_images=DestroyImage(new_images);
              status=MagickFalse;
              break;
            }
          (void) ClutImage(new_images,clut_image,new_images->interpolate,
            _exception);
          clut_image=DestroyImage(clut_image);
          break;
        }
      if (LocaleCompare("coalesce",option+1) == 0)
        {
          new_images=CoalesceImages(_images,_exception);
          break;
        }
      if (LocaleCompare("combine",option+1) == 0)
        {
          parse=(ssize_t) _images->colorspace;
          if (_images->number_channels < GetImageListLength(_images))
            parse=sRGBColorspace;
          if ( IfPlusOp )
            parse=ParseCommandOption(MagickColorspaceOptions,MagickFalse,arg1);
          if (parse < 0)
            CLIWandExceptArgBreak(OptionError,"UnrecognizedColorspace",option,
              arg1);
          new_images=CombineImages(_images,(ColorspaceType) parse,_exception);
          break;
        }
      if (LocaleCompare("compare",option+1) == 0)
        {
          double
            distortion;

          Image
            *image,
            *reconstruct_image;

          MetricType
            metric;

          /*
            Mathematically and visually annotate the difference between an
            image and its reconstruction.
          */
          image=RemoveFirstImageFromList(&_images);
          reconstruct_image=RemoveFirstImageFromList(&_images);
          /* FUTURE - produce Exception, rather than silent fail */
          if (reconstruct_image == (Image *) NULL)
            {
              (void) ThrowMagickException(_exception,GetMagickModule(),
                OptionError,"ImageSequenceRequired","`%s'",option);
              image=DestroyImage(image);
              status=MagickFalse;
              break;
            }
          metric=UndefinedErrorMetric;
          option=GetImageOption(_image_info,"metric");
          if (option != (const char *) NULL)
            metric=(MetricType) ParseCommandOption(MagickMetricOptions,
              MagickFalse,option);
          new_images=CompareImages(image,reconstruct_image,metric,&distortion,
            _exception);
          (void) distortion;
          reconstruct_image=DestroyImage(reconstruct_image);
          image=DestroyImage(image);
          break;
        }
      if (LocaleCompare("complex",option+1) == 0)
        {
          parse=ParseCommandOption(MagickComplexOptions,MagickFalse,arg1);
          if (parse < 0)
            CLIWandExceptArgBreak(OptionError,"UnrecognizedEvaluateOperator",
              option,arg1);
          new_images=ComplexImages(_images,(ComplexOperator) parse,_exception);
          break;
        }
      if (LocaleCompare("composite",option+1) == 0)
        {
          CompositeOperator
            compose;

          const char*
            value;

          MagickBooleanType
            clip_to_self;

          Image
            *mask_image,
            *source_image;

          RectangleInfo
            geometry;

          /* Compose value from "-compose" option only */
          value=GetImageOption(_image_info,"compose");
          if (value == (const char *) NULL)
            compose=OverCompositeOp;  /* use Over not source_image->compose */
          else
            compose=(CompositeOperator) ParseCommandOption(MagickComposeOptions,
              MagickFalse,value);

          /* Get "clip-to-self" expert setting (false is normal) */
          clip_to_self=GetCompositeClipToSelf(compose);
          value=GetImageOption(_image_info,"compose:clip-to-self");
          if (value != (const char *) NULL)
            clip_to_self=IsStringTrue(value);
          value=GetImageOption(_image_info,"compose:outside-overlay");
          if (value != (const char *) NULL)
            clip_to_self=IsStringFalse(value);  /* deprecated */

          new_images=RemoveFirstImageFromList(&_images);
          source_image=RemoveFirstImageFromList(&_images);
          if (source_image == (Image *) NULL)
            {
              (void) ThrowMagickException(_exception,GetMagickModule(),
                OptionError,"ImageSequenceRequired","`%s'",option);
              new_images=DestroyImage(new_images);
              status=MagickFalse;
              break;
            }

          /* FUTURE - this should not be here! - should be part of -geometry */
          if (source_image->geometry != (char *) NULL)
            {
              RectangleInfo
                resize_geometry;

              (void) ParseRegionGeometry(source_image,source_image->geometry,
                &resize_geometry,_exception);
              if ((source_image->columns != resize_geometry.width) ||
                  (source_image->rows != resize_geometry.height))
                {
                  Image
                    *resize_image;

                  resize_image=ResizeImage(source_image,resize_geometry.width,
                    resize_geometry.height,source_image->filter,_exception);
                  if (resize_image != (Image *) NULL)
                    {
                      source_image=DestroyImage(source_image);
                      source_image=resize_image;
                    }
                }
            }
          SetGeometry(source_image,&geometry);
          (void) ParseAbsoluteGeometry(source_image->geometry,&geometry);
          GravityAdjustGeometry(new_images->columns,new_images->rows,
            new_images->gravity, &geometry);
          mask_image=RemoveFirstImageFromList(&_images);
          if (mask_image == (Image *) NULL)
            status&=CompositeImage(new_images,source_image,compose,clip_to_self,
              geometry.x,geometry.y,_exception);
          else
            {
              Image
                *canvas_images;

              canvas_images=CloneImage(new_images,0,0,MagickTrue,_exception);
              if (canvas_images == (Image *) NULL)
                break;
              switch (compose)
              {
                case BlendCompositeOp:
                {
                  status&=CompositeImage(new_images,source_image,compose,
                    clip_to_self,geometry.x,geometry.y,_exception);
                  status&=CompositeImage(new_images,mask_image,
                    CopyAlphaCompositeOp,MagickTrue,0,0,_exception);
                  break;
                }
                case DisplaceCompositeOp:
                case DistortCompositeOp:
                {
                  status&=CompositeImage(source_image,mask_image,
                    CopyGreenCompositeOp,MagickTrue,0,0,_exception);
                  status&=CompositeImage(new_images,source_image,compose,
                    clip_to_self,geometry.x,geometry.y,_exception);
                  break;
                }
                case SaliencyBlendCompositeOp:
                case SeamlessBlendCompositeOp:
                {
                  status&=CompositeImage(source_image,mask_image,
                    CopyAlphaCompositeOp,MagickTrue,0,0,_exception);
                  status&=CompositeImage(new_images,source_image,compose,
                    clip_to_self,geometry.x,geometry.y,_exception);
                  break;
                }
                default:
                {
                  Image
                    *clone_image;

                  clone_image=CloneImage(new_images,0,0,MagickTrue,_exception);
                  if (clone_image == (Image *) NULL)
                    break;
                  status&=CompositeImage(new_images,source_image,compose,
                    clip_to_self,geometry.x,geometry.y,_exception);
                  status&=CompositeImage(new_images,mask_image,
                    CopyAlphaCompositeOp,MagickTrue,0,0,_exception);
                  status&=CompositeImage(clone_image,new_images,OverCompositeOp,
                    clip_to_self,0,0,_exception);
                  new_images=DestroyImageList(new_images);
                  new_images=clone_image;
                  break;
                }
              }
              status&=CompositeImage(canvas_images,new_images,OverCompositeOp,
                clip_to_self,0,0,_exception);
              new_images=DestroyImageList(new_images);
              new_images=canvas_images;
              mask_image=DestroyImage(mask_image);
            }
          source_image=DestroyImage(source_image);
          break;
        }
        if (LocaleCompare("copy",option+1) == 0)
          {
            Image
              *source_image;

            OffsetInfo
              offset;

            RectangleInfo
              geometry;

            /*
              Copy image pixels.
            */
            if (IsGeometry(arg1) == MagickFalse)
              CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
            if (IsGeometry(arg2) == MagickFalse)
              CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
            (void) ParsePageGeometry(_images,arg2,&geometry,_exception);
            offset.x=geometry.x;
            offset.y=geometry.y;
            source_image=_images;
            if (source_image->next != (Image *) NULL)
              source_image=source_image->next;
            (void) ParsePageGeometry(source_image,arg1,&geometry,_exception);
            (void) CopyImagePixels(_images,source_image,&geometry,&offset,
              _exception);
            break;
          }
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
    }
    case 'd':
    {
      if (LocaleCompare("deconstruct",option+1) == 0)
        {
          CLIWandWarnReplaced("-layers CompareAny");
          (void) CLIListOperatorImages(cli_wand,"-layers","CompareAny",NULL);
          break;
        }
      if (LocaleCompare("delete",option+1) == 0)
        {
          if (IfNormalOp)
            DeleteImages(&_images,arg1,_exception);
          else
            DeleteImages(&_images,"-1",_exception);
          break;
        }
      if (LocaleCompare("duplicate",option+1) == 0)
        {
          if (!IfNormalOp)
            new_images=DuplicateImages(_images,1,"-1",_exception);
          else
            {
              const char
                *p;

              size_t
                number_duplicates;

              if (IsGeometry(arg1) == MagickFalse)
                CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,
                  arg1);
              number_duplicates=(size_t) StringToLong(arg1);
              p=strchr(arg1,',');
              if (p == (const char *) NULL)
                new_images=DuplicateImages(_images,number_duplicates,"-1",
                  _exception);
              else
                new_images=DuplicateImages(_images,number_duplicates,p+1,
                  _exception);
            }
          AppendImageToList(&_images, new_images);
          new_images=(Image *) NULL;
          break;
        }
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
    }
    case 'e':
    {
      if (LocaleCompare("evaluate-sequence",option+1) == 0)
        {
          parse=ParseCommandOption(MagickEvaluateOptions,MagickFalse,arg1);
          if (parse < 0)
            CLIWandExceptArgBreak(OptionError,"UnrecognizedEvaluateOperator",
              option,arg1);
          new_images=EvaluateImages(_images,(MagickEvaluateOperator) parse,
            _exception);
          break;
        }
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
    }
    case 'f':
    {
      if (LocaleCompare("fft",option+1) == 0)
        {
          new_images=ForwardFourierTransformImage(_images,IsNormalOp,
           _exception);
          break;
        }
      if (LocaleCompare("flatten",option+1) == 0)
        {
          /* REDIRECTED to use -layers flatten instead */
          (void) CLIListOperatorImages(cli_wand,"-layers",option+1,NULL);
          break;
        }
      if (LocaleCompare("fx",option+1) == 0)
        {
          new_images=FxImage(_images,arg1,_exception);
          break;
        }
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
    }
    case 'h':
    {
      if (LocaleCompare("hald-clut",option+1) == 0)
        {
          /* FUTURE - make this a compose option (and thus layers compose )
             or perhaps compose last image over all other _images.
          */
          Image
            *hald_image;

          new_images=RemoveFirstImageFromList(&_images);
          hald_image=RemoveLastImageFromList(&_images);
          if (hald_image == (Image *) NULL)
            {
              (void) ThrowMagickException(_exception,GetMagickModule(),
                OptionError,"ImageSequenceRequired","`%s'",option);
              new_images=DestroyImage(new_images);
              status=MagickFalse;
              break;
            }
          (void) HaldClutImage(new_images,hald_image,_exception);
          hald_image=DestroyImage(hald_image);
          break;
        }
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
    }
    case 'i':
    {
      if (LocaleCompare("ift",option+1) == 0)
        {
          Image
            *magnitude_image,
            *phase_image;

          magnitude_image=RemoveFirstImageFromList(&_images);
          phase_image=RemoveFirstImageFromList(&_images);
          if (phase_image == (Image *) NULL)
            {
              (void) ThrowMagickException(_exception,GetMagickModule(),
                OptionError,"ImageSequenceRequired","`%s'",option);
              magnitude_image=DestroyImage(magnitude_image);
              status=MagickFalse;
              break;
            }
          new_images=InverseFourierTransformImage(magnitude_image,phase_image,
            IsNormalOp,_exception);
          magnitude_image=DestroyImage(magnitude_image);
          phase_image=DestroyImage(phase_image);
          break;
        }
      if (LocaleCompare("insert",option+1) == 0)
        {
          Image
            *insert_image,
            *index_image;

          ssize_t
            index;

          if (IfNormalOp && (IsGeometry(arg1) == MagickFalse))
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          index=0;
          insert_image=RemoveLastImageFromList(&_images);
          if (IfNormalOp)
            index=(ssize_t) StringToLong(arg1);
          index_image=insert_image;
          if (index == 0)
            PrependImageToList(&_images,insert_image);
          else if (index == (ssize_t) GetImageListLength(_images))
            AppendImageToList(&_images,insert_image);
          else
            {
               index_image=GetImageFromList(_images,index-1);
               if (index_image == (Image *) NULL)
                 {
                   insert_image=DestroyImage(insert_image);
                   CLIWandExceptArgBreak(OptionError,"NoSuchImage",option,arg1);
                 }
              InsertImageInList(&index_image,insert_image);
            }
          _images=GetFirstImageInList(index_image);
          break;
        }
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
    }
    case 'l':
    {
      if (LocaleCompare("layers",option+1) == 0)
        {
          parse=ParseCommandOption(MagickLayerOptions,MagickFalse,arg1);
          if ( parse < 0 )
            CLIWandExceptArgBreak(OptionError,"UnrecognizedLayerMethod",
                 option,arg1);
          switch ((LayerMethod) parse)
          {
            case CoalesceLayer:
            {
              new_images=CoalesceImages(_images,_exception);
              break;
            }
            case CompareAnyLayer:
            case CompareClearLayer:
            case CompareOverlayLayer:
            default:
            {
              new_images=CompareImagesLayers(_images,(LayerMethod) parse,
                   _exception);
              break;
            }
            case MergeLayer:
            case FlattenLayer:
            case MosaicLayer:
            case TrimBoundsLayer:
            {
              new_images=MergeImageLayers(_images,(LayerMethod) parse,
                _exception);
              break;
            }
            case DisposeLayer:
            {
              new_images=DisposeImages(_images,_exception);
              break;
            }
            case OptimizeImageLayer:
            {
              new_images=OptimizeImageLayers(_images,_exception);
              break;
            }
            case OptimizePlusLayer:
            {
              new_images=OptimizePlusImageLayers(_images,_exception);
              break;
            }
            case OptimizeTransLayer:
            {
              OptimizeImageTransparency(_images,_exception);
              break;
            }
            case RemoveDupsLayer:
            {
              RemoveDuplicateLayers(&_images,_exception);
              break;
            }
            case RemoveZeroLayer:
            {
              RemoveZeroDelayLayers(&_images,_exception);
              break;
            }
            case OptimizeLayer:
            { /* General Purpose, GIF Animation Optimizer.  */
              new_images=CoalesceImages(_images,_exception);
              if (new_images == (Image *) NULL)
                break;
              _images=DestroyImageList(_images);
              _images=OptimizeImageLayers(new_images,_exception);
              if (_images == (Image *) NULL)
                break;
              new_images=DestroyImageList(new_images);
              OptimizeImageTransparency(_images,_exception);
              (void) RemapImages(_quantize_info,_images,(Image *) NULL,
                _exception);
              break;
            }
            case CompositeLayer:
            {
              Image
                *source;

              RectangleInfo
                geometry;

              CompositeOperator
                compose;

              const char*
                value;

              value=GetImageOption(_image_info,"compose");
              compose=OverCompositeOp;  /* Default to Over */
              if (value != (const char *) NULL)
                compose=(CompositeOperator) ParseCommandOption(
                      MagickComposeOptions,MagickFalse,value);

              /* Split image sequence at the first 'NULL:' image. */
              source=_images;
              while (source != (Image *) NULL)
              {
                source=GetNextImageInList(source);
                if ((source != (Image *) NULL) &&
                    (LocaleCompare(source->magick,"NULL") == 0))
                  break;
              }
              if (source != (Image *) NULL)
                {
                  if ((GetPreviousImageInList(source) == (Image *) NULL) ||
                      (GetNextImageInList(source) == (Image *) NULL))
                    source=(Image *) NULL;
                  else
                    { /* Separate the two lists, junk the null: image.  */
                      source=SplitImageList(source->previous);
                      DeleteImageFromList(&source);
                    }
                }
              if (source == (Image *) NULL)
                {
                  (void) ThrowMagickException(_exception,GetMagickModule(),
                    OptionError,"MissingNullSeparator","layers Composite");
                  break;
                }
              /* Adjust offset with gravity and virtual canvas.  */
              SetGeometry(_images,&geometry);
              (void) ParseAbsoluteGeometry(_images->geometry,&geometry);
              geometry.width=source->page.width != 0 ?
                source->page.width : source->columns;
              geometry.height=source->page.height != 0 ?
               source->page.height : source->rows;
              GravityAdjustGeometry(_images->page.width != 0 ?
                _images->page.width : _images->columns,
                _images->page.height != 0 ? _images->page.height :
                _images->rows,_images->gravity,&geometry);

              /* Compose the two image sequences together */
              CompositeLayers(_images,compose,source,geometry.x,geometry.y,
                _exception);
              source=DestroyImageList(source);
              break;
            }
          }
          break;
        }
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
    }
    case 'm':
    {
      if (LocaleCompare("map",option+1) == 0)
        {
          CLIWandWarnReplaced("+remap");
          (void) RemapImages(_quantize_info,_images,(Image *) NULL,_exception);
          break;
        }
      if (LocaleCompare("metric",option+1) == 0)
        {
          (void) SetImageOption(_image_info,option+1,arg1);
          break;
        }
      if (LocaleCompare("morph",option+1) == 0)
        {
          Image
            *morph_image;

          if (IsGeometry(arg1) == MagickFalse)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          morph_image=MorphImages(_images,StringToUnsignedLong(arg1),
            _exception);
          if (morph_image == (Image *) NULL)
            break;
          _images=DestroyImageList(_images);
          _images=morph_image;
          break;
        }
      if (LocaleCompare("mosaic",option+1) == 0)
        {
          /* REDIRECTED to use -layers mosaic instead */
          (void) CLIListOperatorImages(cli_wand,"-layers",option+1,NULL);
          break;
        }
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
    }
    case 'p':
    {
      if (LocaleCompare("poly",option+1) == 0)
        {
          double
            *args;

          ssize_t
            count;

          /* convert argument string into an array of doubles */
          args = StringToArrayOfDoubles(arg1,&count,_exception);
          if (args == (double *) NULL )
            CLIWandExceptArgBreak(OptionError,"InvalidNumberList",option,arg1);
          new_images=PolynomialImage(_images,(size_t) (count >> 1),args,
           _exception);
          args=(double *) RelinquishMagickMemory(args);
          break;
        }
      if (LocaleCompare("process",option+1) == 0)
        {
          /* FUTURE: better parsing using ScriptToken() from string ??? */
          char
            **arguments;

          int
            j,
            number_arguments;

          arguments=StringToArgv(arg1,&number_arguments);
          if (arguments == (char **) NULL)
            break;
          if (strchr(arguments[1],'=') != (char *) NULL)
            {
              char
                breaker,
                quote,
                *token;

              const char
                *p;

              int
                next,
                tokenizer_status;

              size_t
                length;

              TokenInfo
                *token_info;

              /*
                Support old style syntax, filter="-option arg1".
              */
              assert(arg1 != (const char *) NULL);
              length=strlen(arg1);
              token=(char *) NULL;
              if (~length >= (MagickPathExtent-1))
                token=(char *) AcquireQuantumMemory(length+MagickPathExtent,
                  sizeof(*token));
              if (token == (char *) NULL)
                break;
              next=0;
              p=arg1;
              token_info=AcquireTokenInfo();
              tokenizer_status=Tokenizer(token_info,0,token,length,p,"","=",
                "\"",'\0',&breaker,&next,&quote);
              token_info=DestroyTokenInfo(token_info);
              if (tokenizer_status == 0)
                {
                  const char
                    *argv;

                  argv=(&(p[next]));
                  (void) InvokeDynamicImageFilter(token,&_images,1,&argv,
                    _exception);
                }
              token=DestroyString(token);
              break;
            }
          (void) SubstituteString(&arguments[1],"-","");
          (void) InvokeDynamicImageFilter(arguments[1],&_images,
            number_arguments-2,(const char **) arguments+2,_exception);
          for (j=0; j < number_arguments; j++)
            arguments[j]=DestroyString(arguments[j]);
          arguments=(char **) RelinquishMagickMemory(arguments);
          break;
        }
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
    }
    case 'r':
    {
      if (LocaleCompare("remap",option+1) == 0)
        {
          (void) RemapImages(_quantize_info,_images,(Image *) NULL,_exception);
          break;
        }
      if (LocaleCompare("reverse",option+1) == 0)
        {
          ReverseImageList(&_images);
          break;
        }
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
    }
    case 's':
    {
      if (LocaleCompare("smush",option+1) == 0)
        {
          /* FUTURE: this option needs more work to make better */
          ssize_t
            offset;

          if (IsGeometry(arg1) == MagickFalse)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          offset=(ssize_t) StringToLong(arg1);
          new_images=SmushImages(_images,IsNormalOp,offset,_exception);
          break;
        }
      if (LocaleCompare("subimage",option+1) == 0)
        {
          Image
            *base_image,
            *compare_image;

          const char
            *value;

          MetricType
            metric;

          double
            similarity;

          RectangleInfo
            offset;

          base_image=GetImageFromList(_images,0);
          compare_image=GetImageFromList(_images,1);

          /* Comparision Metric */
          metric=UndefinedErrorMetric;
          value=GetImageOption(_image_info,"metric");
          if (value != (const char *) NULL)
            metric=(MetricType) ParseCommandOption(MagickMetricOptions,
              MagickFalse,value);

          new_images=SimilarityImage(base_image,compare_image,metric,0.0,
            &offset,&similarity,_exception);

          if (new_images != (Image *) NULL)
            {
              (void) FormatImageProperty(new_images,"subimage:similarity",
                "%.*g",GetMagickPrecision(),similarity);
              (void) FormatImageProperty(new_images,"subimage:x","%+ld",(long)
                offset.x);
              (void) FormatImageProperty(new_images,"subimage:y","%+ld",(long)
                offset.y);
              (void) FormatImageProperty(new_images,"subimage:offset",
                "%lux%lu%+ld%+ld",(unsigned long) offset.width,(unsigned long)
                offset.height,(long) offset.x,(long) offset.y);
            }
          break;
        }
      if (LocaleCompare("swap",option+1) == 0)
        {
        Image
          *p,
          *q,
          *swap;

        ssize_t
          index,
          swap_index;

        index=(-1);
        swap_index=(-2);
        if (IfNormalOp) {
          GeometryInfo
            geometry_info;

          MagickStatusType
            flags;

          swap_index=(-1);
          flags=ParseGeometry(arg1,&geometry_info);
          if ((flags & RhoValue) == 0)
            CLIWandExceptArgBreak(OptionError,"InvalidArgument",option,arg1);
          index=(ssize_t) geometry_info.rho;
          if ((flags & SigmaValue) != 0)
            swap_index=(ssize_t) geometry_info.sigma;
        }
        p=GetImageFromList(_images,index);
        q=GetImageFromList(_images,swap_index);
        if ((p == (Image *) NULL) || (q == (Image *) NULL)) {
          if (IfNormalOp)
            CLIWandExceptArgBreak(OptionError,"InvalidImageIndex",option,arg1)
          else
            CLIWandExceptionBreak(OptionError,"TwoOrMoreImagesRequired",option);
        }
        if (p == q)
          CLIWandExceptArgBreak(OptionError,"InvalidImageIndex",option,arg1);
        swap=CloneImage(p,0,0,MagickTrue,_exception);
        if (swap == (Image *) NULL)
          CLIWandExceptArgBreak(ResourceLimitError,"MemoryAllocationFailed",
            option,GetExceptionMessage(errno));
        ReplaceImageInList(&p,CloneImage(q,0,0,MagickTrue,_exception));
        ReplaceImageInList(&q,swap);
        _images=GetFirstImageInList(q);
        break;
      }
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
    }
    default:
      CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
  }

  /* clean up percent escape interpreted strings */
  if (arg1 != arg1n )
    arg1=DestroyString((char *)arg1);
  if (arg2 != arg2n )
    arg2=DestroyString((char *)arg2);

  /* if new image list generated, replace existing image list */
  if (new_images == (Image *) NULL)
    return(status == 0 ? MagickFalse : MagickTrue);
  _images=DestroyImageList(_images);
  _images=GetFirstImageInList(new_images);
  return(status == 0 ? MagickFalse : MagickTrue);

#undef _image_info
#undef _images
#undef _exception
#undef _draw_info
#undef _quantize_info
#undef IfNormalOp
#undef IfPlusOp
#undef IsNormalOp
}

Project: ImageMagick
File: operation.c

static MagickBooleanType MonitorProgress(const char *text,
  const MagickOffsetType offset,const MagickSizeType extent,
  void *wand_unused(client_data))
{
  char
    message[MagickPathExtent],
    tag[MagickPathExtent];

  const char
    *locale_message;

  char
    *p;

  magick_unreferenced(client_data);

  if ((extent <= 1) || (offset < 0) || (offset >= (MagickOffsetType) extent))
    return(MagickTrue);
  if ((offset != (MagickOffsetType) (extent-1)) && ((offset % 50) != 0))
    return(MagickTrue);
  (void) CopyMagickString(tag,text,MagickPathExtent);
  p=strrchr(tag,'/');
  if (p != (char *) NULL)
    *p='\0';
  (void) FormatLocaleString(message,MagickPathExtent,"Monitor/%s",tag);
  locale_message=GetLocaleMessage(message);
  if (locale_message == message)
    locale_message=tag;
  if (p == (char *) NULL)
    (void) FormatLocaleFile(stderr,"%s: %ld of %lu, %02ld%% complete\r",
      locale_message,(long) offset,(unsigned long) extent,(long)
      (100L*offset/(extent-1)));
  else
    (void) FormatLocaleFile(stderr,"%s[%s]: %ld of %lu, %02ld%% complete\r",
      locale_message,p+1,(long) offset,(unsigned long) extent,(long)
      (100L*offset/(extent-1)));
  if (offset == (MagickOffsetType) (extent-1))
    (void) FormatLocaleFile(stderr,"\n");
  (void) fflush(stderr);
  return(MagickTrue);
}

Project: ImageMagick
File: tim2.c

static inline Quantum GetChannelValue(unsigned int word,unsigned char channel,
  TIM2ColorEncoding ce)
{
  switch(ce)
  {
    case RGBA16:
      /* Documentation specifies padding with zeros for converting from 5 to 8 bits. */
      return ScaleCharToQuantum((word>>channel*5 & ~(~0x0U<<5))<<3);
    case RGB24:
    case RGBA32:
      return ScaleCharToQuantum(word>>channel*8 & ~(~0x0U<<8));
    default:
      return QuantumRange;
  }
}

Project: ImageMagick
File: tim2.c

static inline Quantum GetAlpha(unsigned int word,TIM2ColorEncoding ce)
{
  switch(ce)
  {
    case RGBA16:
      return ScaleCharToQuantum((word>>3*5&0x1F)==0?0:0xFF);
    case RGBA32:
      /* 0x80 -> 1.0 alpha. Multiply by 2 and clamp to 0xFF */
      return ScaleCharToQuantum(MagickMin((word>>3*8&0xFF)<<1,0xFF));
    default:
      return 0xFF;
  }
}