Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-03-13 09:14:24

0001 // This may look like C code, but it is really -*- C++ -*-
0002 //
0003 // Copyright Bob Friesenhahn, 1999, 2000, 2001, 2002, 2003
0004 //
0005 // Copyright @ 2013 ImageMagick Studio LLC, a non-profit organization
0006 // dedicated to making software imaging solutions freely available.
0007 //
0008 // Definition and implementation of template functions for using
0009 // Magick::Image with STL containers.
0010 //
0011 
0012 #ifndef Magick_STL_header
0013 #define Magick_STL_header
0014 
0015 #include "Magick++/Include.h"
0016 #include <algorithm>
0017 #include <functional>
0018 #include <iterator>
0019 #include <map>
0020 #include <utility>
0021 
0022 #include "Magick++/CoderInfo.h"
0023 #include "Magick++/Drawable.h"
0024 #include "Magick++/Exception.h"
0025 #include "Magick++/Montage.h"
0026 
0027 namespace Magick
0028 {
0029   //
0030   // STL function object declarations/definitions
0031   //
0032 
0033   // Function objects provide the means to invoke an operation on one
0034   // or more image objects in an STL-compatable container.  The
0035   // arguments to the function object constructor(s) are compatable
0036   // with the arguments to the equivalent Image class method and
0037   // provide the means to supply these options when the function
0038   // object is invoked.
0039 
0040   // For example, to read a GIF animation, set the color red to
0041   // transparent for all frames, and write back out:
0042   //
0043   // list<image> images;
0044   // readImages( &images, "animation.gif" );
0045   // for_each( images.begin(), images.end(), transparentImage( "red" ) );
0046   // writeImages( images.begin(), images.end(), "animation.gif" );
0047 
0048   // Adaptive-blur image with specified blur factor
0049   class MagickPPExport adaptiveBlurImage
0050   {
0051   public:
0052     adaptiveBlurImage( const double radius_ = 1, const double sigma_ = 0.5 );
0053 
0054     void operator()( Image &image_ ) const;
0055 
0056   private:
0057     double _radius;
0058     double _sigma;
0059   };
0060 
0061   // Local adaptive threshold image
0062   // http://www.dai.ed.ac.uk/HIPR2/adpthrsh.htm
0063   // Width x height define the size of the pixel neighborhood
0064   // offset = constant to subtract from pixel neighborhood mean
0065   class MagickPPExport adaptiveThresholdImage
0066   {
0067   public:
0068     adaptiveThresholdImage( const size_t width_,
0069                             const size_t height_,
0070                             const ::ssize_t offset_ = 0  );
0071 
0072     void operator()( Image &image_ ) const;
0073 
0074   private:
0075     size_t _width;
0076     size_t _height;
0077     ::ssize_t _offset;
0078   };
0079 
0080   // Add noise to image with specified noise type
0081   class MagickPPExport addNoiseImage
0082   {
0083   public:
0084     addNoiseImage(const NoiseType noiseType_,const double attenuate_ = 1.0);
0085 
0086     void operator()(Image &image_) const;
0087 
0088   private:
0089     NoiseType _noiseType;
0090     double _attenuate;
0091   };
0092 
0093   // Transform image by specified affine (or free transform) matrix.
0094   class MagickPPExport affineTransformImage
0095   {
0096   public:
0097     affineTransformImage( const DrawableAffine &affine_ );
0098 
0099     void operator()( Image &image_ ) const;
0100 
0101   private:
0102     DrawableAffine _affine;
0103   };
0104 
0105   // Annotate image (draw text on image)
0106   class MagickPPExport annotateImage
0107   {
0108   public:
0109     // Annotate using specified text, and placement location
0110     annotateImage ( const std::string &text_,
0111                     const Geometry &geometry_ );
0112 
0113     // Annotate using specified text, bounding area, and placement
0114     // gravity
0115     annotateImage ( const std::string &text_,
0116         const Geometry &geometry_,
0117         const GravityType gravity_ );
0118 
0119     // Annotate with text using specified text, bounding area,
0120     // placement gravity, and rotation.
0121     annotateImage ( const std::string &text_,
0122                     const Geometry &geometry_,
0123                     const GravityType gravity_,
0124                     const double degrees_ );
0125 
0126     // Annotate with text (bounding area is entire image) and
0127     // placement gravity.
0128     annotateImage ( const std::string &text_,
0129         const GravityType gravity_ );
0130 
0131     void operator()( Image &image_ ) const;
0132 
0133   private:
0134     const std::string   _text;
0135     const Geometry      _geometry;
0136     const GravityType   _gravity;
0137     const double        _degrees;
0138   };
0139 
0140   // Blur image with specified blur factor
0141   class MagickPPExport blurImage
0142   {
0143   public:
0144     blurImage( const double radius_ = 1, const double sigma_ = 0.5 );
0145 
0146     void operator()( Image &image_ ) const;
0147 
0148   private:
0149     double _radius;
0150     double _sigma;
0151   };
0152 
0153   // Border image (add border to image)
0154   class MagickPPExport borderImage
0155   {
0156   public:
0157     borderImage( const Geometry &geometry_ = borderGeometryDefault  );
0158 
0159     void operator()( Image &image_ ) const;
0160 
0161   private:
0162     Geometry _geometry;
0163   };
0164 
0165   // Extract channel from image
0166   class MagickPPExport channelImage
0167   {
0168   public:
0169     channelImage( const ChannelType channel_ );
0170 
0171     void operator()( Image &image_ ) const;
0172 
0173   private:
0174     ChannelType _channel;
0175   };
0176 
0177   // Charcoal effect image (looks like charcoal sketch)
0178   class MagickPPExport charcoalImage
0179   {
0180   public:
0181     charcoalImage( const double radius_ = 1, const double sigma_ = 0.5  );
0182 
0183     void operator()( Image &image_ ) const;
0184 
0185   private:
0186     double _radius;
0187     double _sigma;
0188   };
0189 
0190   // Chop image (remove vertical or horizontal subregion of image)
0191   class MagickPPExport chopImage
0192   {
0193   public:
0194     chopImage( const Geometry &geometry_ );
0195 
0196     void operator()( Image &image_ ) const;
0197 
0198   private:
0199     Geometry _geometry;
0200   };
0201 
0202   // Accepts a lightweight Color Correction Collection (CCC) file which solely
0203   // contains one or more color corrections and applies the correction to the
0204   // image.
0205   class MagickPPExport cdlImage
0206   {
0207   public:
0208     cdlImage( const std::string &cdl_ );
0209 
0210     void operator()( Image &image_ ) const;
0211 
0212   private:
0213     std::string   _cdl;
0214   };
0215 
0216   // Colorize image using pen color at specified percent alpha
0217   class MagickPPExport colorizeImage
0218   {
0219   public:
0220     colorizeImage( const unsigned int alphaRed_,
0221                    const unsigned int alphaGreen_,
0222                    const unsigned int alphaBlue_,
0223        const Color &penColor_ );
0224 
0225     colorizeImage( const unsigned int alpha_,
0226                    const Color &penColor_ );
0227 
0228     void operator()( Image &image_ ) const;
0229 
0230   private:
0231     unsigned int _alphaRed;
0232     unsigned int _alphaGreen;
0233     unsigned int _alphaBlue;
0234     Color _penColor;
0235   };
0236 
0237   // Apply a color matrix to the image channels.  The user supplied
0238   // matrix may be of order 1 to 5 (1x1 through 5x5).
0239   class MagickPPExport colorMatrixImage
0240   {
0241   public:
0242     colorMatrixImage( const size_t order_,
0243           const double *color_matrix_ );
0244 
0245     void operator()( Image &image_ ) const;
0246 
0247   private:
0248     size_t  _order;
0249     const double *_color_matrix;
0250   };
0251 
0252   // Convert the image colorspace representation
0253   class MagickPPExport colorSpaceImage
0254   {
0255   public:
0256     colorSpaceImage( ColorspaceType colorSpace_ );
0257 
0258     void operator()( Image &image_ ) const;
0259 
0260   private:
0261     ColorspaceType _colorSpace;
0262   };
0263 
0264   // Comment image (add comment string to image)
0265   class MagickPPExport commentImage
0266   {
0267   public:
0268     commentImage( const std::string &comment_ );
0269 
0270     void operator()( Image &image_ ) const;
0271 
0272   private:
0273     std::string _comment;
0274   };
0275 
0276   // Compose an image onto another at specified offset and using
0277   // specified algorithm
0278   class MagickPPExport compositeImage
0279   {
0280   public:
0281     compositeImage( const Image &compositeImage_,
0282         ::ssize_t xOffset_,
0283         ::ssize_t yOffset_,
0284         CompositeOperator compose_ = InCompositeOp );
0285 
0286     compositeImage( const Image &compositeImage_,
0287         const Geometry &offset_,
0288         CompositeOperator compose_ = InCompositeOp );
0289 
0290     void operator()( Image &image_ ) const;
0291 
0292   private:
0293     Image             _compositeImage;
0294     ::ssize_t         _xOffset;
0295     ::ssize_t         _yOffset;
0296     CompositeOperator _compose;
0297   };
0298 
0299   // Contrast image (enhance intensity differences in image)
0300   class MagickPPExport contrastImage
0301   {
0302   public:
0303     contrastImage( const size_t sharpen_ );
0304 
0305     void operator()( Image &image_ ) const;
0306 
0307   private:
0308     size_t _sharpen;
0309   };
0310 
0311   // Crop image (subregion of original image)
0312   class MagickPPExport cropImage
0313   {
0314   public:
0315     cropImage( const Geometry &geometry_ );
0316 
0317     void operator()( Image &image_ ) const;
0318 
0319   private:
0320     Geometry _geometry;
0321   };
0322 
0323   // Cycle image colormap
0324   class MagickPPExport cycleColormapImage
0325   {
0326   public:
0327     cycleColormapImage( const ::ssize_t amount_ );
0328 
0329     void operator()( Image &image_ ) const;
0330 
0331   private:
0332     ::ssize_t _amount;
0333   };
0334 
0335   // Despeckle image (reduce speckle noise)
0336   class MagickPPExport despeckleImage
0337   {
0338   public:
0339     despeckleImage( void );
0340 
0341     void operator()( Image &image_ ) const;
0342 
0343   private:
0344   };
0345 
0346   // Distort image.  distorts an image using various distortion methods, by
0347   // mapping color lookups of the source image to a new destination image
0348   // usually of the same size as the source image, unless 'bestfit' is set to
0349   // true.
0350   class MagickPPExport distortImage
0351   {
0352   public:
0353     distortImage( const Magick::DistortMethod method_,
0354       const size_t number_arguments_,
0355       const double *arguments_,
0356       const bool bestfit_ );
0357 
0358     distortImage( const Magick::DistortMethod method_,
0359       const size_t number_arguments_,
0360       const double *arguments_ );
0361 
0362     void operator()( Image &image_ ) const;
0363 
0364   private:
0365     DistortMethod _method;
0366     size_t _number_arguments;
0367     const double *_arguments;
0368     bool _bestfit;
0369   };
0370 
0371   // Draw on image
0372   class MagickPPExport drawImage
0373   {
0374   public:
0375     // Draw on image using a single drawable
0376     // Store in list to make implementation easier
0377     drawImage( const Drawable &drawable_ );
0378 
0379     // Draw on image using a drawable list
0380     drawImage( const DrawableList &drawable_ );
0381 
0382     void operator()( Image &image_ ) const;
0383 
0384   private:
0385     DrawableList _drawableList;
0386   };
0387 
0388   // Edge image (highlight edges in image)
0389   class MagickPPExport edgeImage
0390   {
0391   public:
0392     edgeImage( const double radius_ = 0.0 );
0393 
0394     void operator()( Image &image_ ) const;
0395 
0396   private:
0397     double _radius;
0398   };
0399 
0400   // Emboss image (highlight edges with 3D effect)
0401   class MagickPPExport embossImage
0402   {
0403   public:
0404     embossImage( void );
0405     embossImage( const double radius_, const double sigma_ );
0406 
0407     void operator()( Image &image_ ) const;
0408 
0409   private:
0410     double _radius;
0411     double _sigma;
0412   };
0413 
0414   // Enhance image (minimize noise)
0415   class MagickPPExport enhanceImage
0416   {
0417   public:
0418     enhanceImage( void );
0419 
0420     void operator()( Image &image_ ) const;
0421 
0422   private:
0423   };
0424 
0425   // Equalize image (histogram equalization)
0426   class MagickPPExport equalizeImage
0427   {
0428   public:
0429     equalizeImage( void );
0430 
0431     void operator()( Image &image_ ) const;
0432 
0433   private:
0434   };
0435 
0436   // Color to use when filling drawn objects
0437   class MagickPPExport fillColorImage
0438   {
0439   public:
0440     fillColorImage( const Color &fillColor_ );
0441 
0442     void operator()( Image &image_ ) const;
0443 
0444   private:
0445     Color _fillColor;
0446   };
0447 
0448   // Flip image (reflect each scanline in the vertical direction)
0449   class MagickPPExport flipImage
0450   {
0451   public:
0452     flipImage( void );
0453 
0454     void operator()( Image &image_ ) const;
0455 
0456   private:
0457   };
0458 
0459   // Floodfill designated area with a matte value
0460   class MagickPPExport floodFillAlphaImage
0461 
0462   {
0463   public:
0464     floodFillAlphaImage(const ::ssize_t x_,const ::ssize_t y_,
0465      const unsigned int alpha_,const Color &target_,const bool invert_=false);
0466 
0467     void operator()(Image &image_) const;
0468 
0469   private:
0470     Color        _target;
0471     unsigned int _alpha;
0472     ::ssize_t    _x;
0473     ::ssize_t    _y;
0474     bool         _invert;
0475   };
0476 
0477   // Flood-fill image with color
0478   class MagickPPExport floodFillColorImage
0479 
0480   {
0481   public:
0482     // Flood-fill color across pixels starting at target-pixel and
0483     // stopping at pixels matching specified border color.
0484     // Uses current fuzz setting when determining color match.
0485     floodFillColorImage(const Geometry &point_,const Color &fillColor_,
0486       const bool invert_=false);
0487     floodFillColorImage(const ::ssize_t x_,const ::ssize_t y_,
0488       const Color &fillColor_,const bool invert_=false);
0489 
0490     // Flood-fill color across pixels starting at target-pixel and
0491     // stopping at pixels matching specified border color.
0492     // Uses current fuzz setting when determining color match.
0493     floodFillColorImage(const Geometry &point_,const Color &fillColor_,
0494       const Color &borderColor_,const bool invert_=false);
0495     floodFillColorImage(const ::ssize_t x_,const ::ssize_t y_,
0496       const Color &fillColor_,const Color &borderColor_,
0497       const bool invert_=false);
0498 
0499     void operator()(Image &image_) const;
0500 
0501   private:
0502     ::ssize_t _x;
0503     ::ssize_t _y;
0504     Color     _fillColor;
0505     Color     _borderColor;
0506     bool      _invert;
0507   };
0508 
0509   // Flood-fill image with texture
0510   class MagickPPExport floodFillTextureImage
0511 
0512   {
0513   public:
0514     // Flood-fill texture across pixels that match the color of the
0515     // target pixel and are neighbors of the target pixel.
0516     // Uses current fuzz setting when determining color match.
0517     floodFillTextureImage(const ::ssize_t x_,const ::ssize_t y_,
0518       const Image &texture_,const bool invert_=false);
0519     floodFillTextureImage(const Geometry &point_,const Image &texture_,
0520       const bool invert_=false);
0521 
0522     // Flood-fill texture across pixels starting at target-pixel and
0523     // stopping at pixels matching specified border color.
0524     // Uses current fuzz setting when determining color match.
0525     floodFillTextureImage(const ::ssize_t x_,const ::ssize_t y_,
0526       const Image &texture_,const Color &borderColor_,
0527       const bool invert_=false);
0528 
0529     floodFillTextureImage(const Geometry &point_,const Image &texture_,
0530       const Color &borderColor_,const bool invert_=false);
0531 
0532     void operator()(Image &image_) const;
0533 
0534   private:
0535     ::ssize_t _x;
0536     ::ssize_t _y;
0537     Image     _texture;
0538     Color     _borderColor;
0539     bool      _invert;
0540   };
0541 
0542   // Flop image (reflect each scanline in the horizontal direction)
0543   class MagickPPExport flopImage
0544   {
0545   public:
0546     flopImage( void );
0547 
0548     void operator()( Image &image_ ) const;
0549 
0550   private:
0551   };
0552 
0553   // Frame image
0554   class MagickPPExport frameImage
0555   {
0556   public:
0557     frameImage( const Geometry &geometry_ = frameGeometryDefault );
0558 
0559     frameImage( const size_t width_, const size_t height_,
0560     const ::ssize_t innerBevel_ = 6, const ::ssize_t outerBevel_ = 6 );
0561 
0562     void operator()( Image &image_ ) const;
0563 
0564   private:
0565     size_t _width;
0566     size_t _height;
0567     ::ssize_t        _outerBevel;
0568     ::ssize_t        _innerBevel;
0569   };
0570 
0571   // Gamma correct image
0572   class MagickPPExport gammaImage
0573   {
0574   public:
0575     gammaImage( const double gamma_ );
0576 
0577     gammaImage ( const double gammaRed_,
0578      const double gammaGreen_,
0579      const double gammaBlue_ );
0580 
0581     void operator()( Image &image_ ) const;
0582 
0583   private:
0584     double _gammaRed;
0585     double _gammaGreen;
0586     double _gammaBlue;
0587   };
0588 
0589   // Gaussian blur image
0590   // The number of neighbor pixels to be included in the convolution
0591   // mask is specified by 'width_'. The standard deviation of the
0592   // gaussian bell curve is specified by 'sigma_'.
0593   class MagickPPExport gaussianBlurImage
0594   {
0595   public:
0596     gaussianBlurImage( const double width_, const double sigma_ );
0597 
0598     void operator()( Image &image_ ) const;
0599 
0600   private:
0601     double _width;
0602     double _sigma;
0603   };
0604 
0605   // Apply a color lookup table (Hald CLUT) to the image.
0606   class MagickPPExport haldClutImage
0607   {
0608   public:
0609     haldClutImage( const Image &haldClutImage_ );
0610 
0611     void operator()( Image &image_ ) const;
0612 
0613   private:
0614     Image             _haldClutImage;
0615   };
0616 
0617   // Implode image (special effect)
0618   class MagickPPExport implodeImage
0619   {
0620   public:
0621     implodeImage( const double factor_ = 50 );
0622 
0623     void operator()( Image &image_ ) const;
0624 
0625   private:
0626     double _factor;
0627   };
0628 
0629   // implements the inverse discrete Fourier transform (IFT) of the image
0630   // either as a magnitude / phase or real / imaginary image pair.
0631   class MagickPPExport inverseFourierTransformImage
0632   {
0633   public:
0634     inverseFourierTransformImage( const Image &phaseImage_ );
0635 
0636     void operator()( Image &image_ ) const;
0637 
0638   private:
0639     Image _phaseImage;
0640   };
0641 
0642   // Set image validity. Valid images become empty (inValid) if
0643   // argument is false.
0644   class MagickPPExport isValidImage
0645   {
0646   public:
0647     isValidImage( const bool isValid_ );
0648 
0649     void operator()( Image &image_ ) const;
0650 
0651   private:
0652     bool _isValid;
0653   };
0654 
0655   // Label image
0656   class MagickPPExport labelImage
0657   {
0658   public:
0659     labelImage( const std::string &label_ );
0660 
0661     void operator()( Image &image_ ) const;
0662 
0663   private:
0664     std::string _label;
0665   };
0666 
0667 
0668   // Level image
0669   class MagickPPExport levelImage
0670   {
0671   public:
0672     levelImage( const double black_point,
0673                 const double white_point,
0674                 const double mid_point=1.0 );
0675 
0676     void operator()( Image &image_ ) const;
0677 
0678   private:
0679     double _black_point;
0680     double _white_point;
0681     double _mid_point;
0682   };
0683 
0684   // Magnify image by integral size
0685   class MagickPPExport magnifyImage
0686   {
0687   public:
0688     magnifyImage( void );
0689 
0690     void operator()( Image &image_ ) const;
0691 
0692   private:
0693   };
0694 
0695   // Remap image colors with closest color from reference image
0696   class MagickPPExport mapImage
0697   {
0698   public:
0699     mapImage( const Image &mapImage_ ,
0700               const bool dither_ = false );
0701 
0702     void operator()( Image &image_ ) const;
0703 
0704   private:
0705     Image   _mapImage;
0706     bool    _dither;
0707   };
0708 
0709   // Filter image by replacing each pixel component with the median
0710   // color in a circular neighborhood
0711   class MagickPPExport medianConvolveImage
0712   {
0713   public:
0714     medianConvolveImage( const double radius_ = 0.0 );
0715 
0716     void operator()( Image &image_ ) const;
0717 
0718   private:
0719     double _radius;
0720   };
0721 
0722   // Merge image layers
0723   class MagickPPExport mergeLayersImage
0724   {
0725   public:
0726     mergeLayersImage ( LayerMethod layerMethod_ );
0727 
0728     void operator()( Image &image_ ) const;
0729 
0730   private:
0731     LayerMethod _layerMethod;
0732   };
0733 
0734   // Reduce image by integral size
0735   class MagickPPExport minifyImage
0736   {
0737   public:
0738     minifyImage( void );
0739 
0740     void operator()( Image &image_ ) const;
0741 
0742   private:
0743   };
0744 
0745   // Modulate percent hue, saturation, and brightness of an image
0746   class MagickPPExport modulateImage
0747   {
0748   public:
0749     modulateImage( const double brightness_,
0750        const double saturation_,
0751        const double hue_ );
0752 
0753     void operator()( Image &image_ ) const;
0754 
0755   private:
0756     double _brightness;
0757     double _saturation;
0758     double _hue;
0759   };
0760 
0761   // Negate colors in image.  Set grayscale to only negate grayscale
0762   // values in image.
0763   class MagickPPExport negateImage
0764   {
0765   public:
0766     negateImage( const bool grayscale_ = false );
0767 
0768     void operator()( Image &image_ ) const;
0769 
0770   private:
0771     bool _grayscale;
0772   };
0773 
0774   // Normalize image (increase contrast by normalizing the pixel
0775   // values to span the full range of color values)
0776   class MagickPPExport normalizeImage
0777   {
0778   public:
0779     normalizeImage( void );
0780 
0781     void operator()( Image &image_ ) const;
0782 
0783   private:
0784   };
0785 
0786   // Oilpaint image (image looks like oil painting)
0787   class MagickPPExport oilPaintImage
0788   {
0789   public:
0790     oilPaintImage( const double radius_ = 3 );
0791 
0792     void operator()( Image &image_ ) const;
0793 
0794   private:
0795     double _radius;
0796   };
0797 
0798   // Set or attenuate the image alpha channel. If the image pixels
0799   // are opaque then they are set to the specified alpha value,
0800   // otherwise they are blended with the supplied alpha value.  The
0801   // value of alpha_ ranges from 0 (completely opaque) to
0802   // QuantumRange. The defines OpaqueAlpha and TransparentAlpha are
0803   // available to specify completely opaque or completely transparent,
0804   // respectively.
0805   class MagickPPExport alphaImage
0806   {
0807   public:
0808     alphaImage( const unsigned int alpha_ );
0809 
0810     void operator()( Image &image_ ) const;
0811 
0812   private:
0813     unsigned int _alpha;
0814   };
0815 
0816   // Change color of opaque pixel to specified pen color.
0817   class MagickPPExport opaqueImage
0818   {
0819   public:
0820     opaqueImage( const Color &opaqueColor_,
0821      const Color &penColor_ );
0822 
0823     void operator()( Image &image_ ) const;
0824 
0825   private:
0826     Color  _opaqueColor;
0827     Color  _penColor;
0828   };
0829 
0830   // Quantize image (reduce number of colors)
0831   class MagickPPExport quantizeImage
0832   {
0833   public:
0834     quantizeImage( const bool measureError_ = false );
0835 
0836     void operator()( Image &image_ ) const;
0837 
0838   private:
0839     bool _measureError;
0840   };
0841 
0842   // Raise image (lighten or darken the edges of an image to give a
0843   // 3-D raised or lowered effect)
0844   class MagickPPExport raiseImage
0845   {
0846   public:
0847     raiseImage( const Geometry &geometry_ = raiseGeometryDefault,
0848     const bool raisedFlag_ = false );
0849 
0850     void operator()( Image &image_ ) const;
0851 
0852   private:
0853     Geometry   _geometry;
0854     bool       _raisedFlag;
0855   };
0856 
0857   class MagickPPExport ReadOptions
0858   {
0859   public:
0860 
0861     // Default constructor
0862     ReadOptions(void);
0863 
0864     // Copy constructor
0865     ReadOptions(const ReadOptions& options_);
0866 
0867     // Destructor
0868     ~ReadOptions();
0869 
0870     // Vertical and horizontal resolution in pixels of the image
0871     void density(const Geometry &geometry_);
0872     Geometry density(void) const;
0873 
0874     // Image depth (8 or 16)
0875     void depth(size_t depth_);
0876     size_t depth(void) const;
0877 
0878     // Ping the image instead of reading it
0879     void ping(const bool flag_);
0880     bool ping(void) const;
0881 
0882     // Suppress all warning messages. Error messages are still reported.
0883     void quiet(const bool quiet_);
0884     bool quiet(void) const;
0885 
0886     // Image size (required for raw formats)
0887     void size(const Geometry &geometry_);
0888     Geometry size(void) const;
0889 
0890     //
0891     // Internal implementation methods.  Please do not use.
0892     //
0893 
0894     MagickCore::ImageInfo *imageInfo(void);
0895 
0896   private:
0897 
0898     // Assignment not supported
0899     ReadOptions& operator=(const ReadOptions&);
0900 
0901     MagickCore::ImageInfo *_imageInfo;
0902     bool                  _quiet;
0903   };
0904 
0905   // Reduce noise in image using a noise peak elimination filter
0906   class MagickPPExport reduceNoiseImage
0907   {
0908   public:
0909     reduceNoiseImage( void );
0910 
0911     reduceNoiseImage (const  size_t order_ );
0912 
0913     void operator()( Image &image_ ) const;
0914 
0915   private:
0916     size_t _order;
0917   };
0918 
0919   // Resize image to specified size.
0920   class MagickPPExport resizeImage
0921   {
0922   public:
0923     resizeImage( const Geometry &geometry_ );
0924 
0925     void operator()( Image &image_ ) const;
0926 
0927   private:
0928     Geometry _geometry;
0929   };
0930 
0931   // Roll image (rolls image vertically and horizontally) by specified
0932   // number of columns and rows)
0933   class MagickPPExport rollImage
0934   {
0935   public:
0936     rollImage( const Geometry &roll_ );
0937 
0938     rollImage( const ::ssize_t columns_, const ::ssize_t rows_ );
0939 
0940     void operator()( Image &image_ ) const;
0941 
0942   private:
0943     size_t _columns;
0944     size_t _rows;
0945   };
0946 
0947   // Rotate image counter-clockwise by specified number of degrees.
0948   class MagickPPExport rotateImage
0949   {
0950   public:
0951     rotateImage( const double degrees_ );
0952 
0953     void operator()( Image &image_ ) const;
0954 
0955   private:
0956     double       _degrees;
0957   };
0958 
0959   // Resize image by using pixel sampling algorithm
0960   class MagickPPExport sampleImage
0961   {
0962   public:
0963     sampleImage( const Geometry &geometry_ );
0964 
0965     void operator()( Image &image_ ) const;
0966 
0967   private:
0968     Geometry  _geometry;
0969   };
0970 
0971   // Resize image by using simple ratio algorithm
0972   class MagickPPExport scaleImage
0973   {
0974   public:
0975     scaleImage( const Geometry &geometry_ );
0976 
0977     void operator()( Image &image_ ) const;
0978 
0979   private:
0980     Geometry  _geometry;
0981   };
0982 
0983   // Segment (coalesce similar image components) by analyzing the
0984   // histograms of the color components and identifying units that are
0985   // homogeneous with the fuzzy c-means technique.
0986   // Also uses QuantizeColorSpace and Verbose image attributes
0987   class MagickPPExport segmentImage
0988   {
0989   public:
0990     segmentImage( const double clusterThreshold_ = 1.0,
0991       const double smoothingThreshold_ = 1.5 );
0992 
0993     void operator()( Image &image_ ) const;
0994 
0995   private:
0996     double  _clusterThreshold;
0997     double  _smoothingThreshold;
0998   };
0999 
1000   // Shade image using distant light source
1001   class MagickPPExport shadeImage
1002   {
1003   public:
1004     shadeImage( const double azimuth_ = 30,
1005     const double elevation_ = 30,
1006     const bool   colorShading_ = false );
1007 
1008     void operator()( Image &image_ ) const;
1009 
1010   private:
1011     double  _azimuth;
1012     double  _elevation;
1013     bool    _colorShading;
1014   };
1015 
1016   // Shadow effect image (simulate an image shadow)
1017   class MagickPPExport shadowImage
1018   {
1019   public:
1020     shadowImage( const double percent_opacity_ = 80, const double sigma_ = 0.5,
1021       const ssize_t x_ = 5, const ssize_t y_ = 5 );
1022 
1023     void operator()( Image &image_ ) const;
1024 
1025   private:
1026     double _percent_opacity;
1027     double _sigma;
1028     ssize_t _x;
1029     ssize_t _y;
1030   };
1031 
1032   // Sharpen pixels in image
1033   class MagickPPExport sharpenImage
1034   {
1035   public:
1036     sharpenImage( const double radius_ = 1, const double sigma_ = 0.5 );
1037 
1038     void operator()( Image &image_ ) const;
1039 
1040   private:
1041     double _radius;
1042     double _sigma;
1043   };
1044 
1045   // Shave pixels from image edges.
1046   class MagickPPExport shaveImage
1047   {
1048   public:
1049     shaveImage( const Geometry &geometry_ );
1050 
1051     void operator()( Image &image_ ) const;
1052 
1053   private:
1054     Geometry _geometry;
1055   };
1056 
1057 
1058   // Shear image (create parallelogram by sliding image by X or Y axis)
1059   class MagickPPExport shearImage
1060   {
1061   public:
1062     shearImage( const double xShearAngle_,
1063     const double yShearAngle_ );
1064 
1065     void operator()( Image &image_ ) const;
1066 
1067   private:
1068     double _xShearAngle;
1069     double _yShearAngle;
1070   };
1071 
1072   // Solarize image (similar to effect seen when exposing a
1073   // photographic film to light during the development process)
1074   class MagickPPExport solarizeImage
1075   {
1076   public:
1077     solarizeImage( const double factor_ );
1078 
1079     void operator()( Image &image_ ) const;
1080 
1081   private:
1082     double _factor;
1083   };
1084 
1085   // Splice the background color into the image.
1086   class MagickPPExport spliceImage
1087   {
1088   public:
1089     spliceImage( const Geometry &geometry_ );
1090 
1091     void operator()( Image &image_ ) const;
1092 
1093   private:
1094     Geometry _geometry;
1095   };
1096 
1097   // Spread pixels randomly within image by specified amount
1098   class MagickPPExport spreadImage
1099   {
1100   public:
1101     spreadImage( const size_t amount_ = 3 );
1102 
1103     void operator()( Image &image_ ) const;
1104 
1105   private:
1106     size_t _amount;
1107   };
1108 
1109   // Add a digital watermark to the image (based on second image)
1110   class MagickPPExport steganoImage
1111   {
1112   public:
1113     steganoImage( const Image &waterMark_ );
1114 
1115     void operator()( Image &image_ ) const;
1116 
1117   private:
1118     Image _waterMark;
1119   };
1120 
1121   // Create an image which appears in stereo when viewed with red-blue glasses
1122   // (Red image on left, blue on right)
1123   class MagickPPExport stereoImage
1124   {
1125   public:
1126     stereoImage( const Image &rightImage_ );
1127 
1128     void operator()( Image &image_ ) const;
1129 
1130   private:
1131     Image _rightImage;
1132   };
1133 
1134   // Color to use when drawing object outlines
1135   class MagickPPExport strokeColorImage
1136   {
1137   public:
1138     strokeColorImage( const Color &strokeColor_ );
1139 
1140     void operator()( Image &image_ ) const;
1141 
1142   private:
1143     Color _strokeColor;
1144   };
1145 
1146   // Swirl image (image pixels are rotated by degrees)
1147   class MagickPPExport swirlImage
1148   {
1149   public:
1150     swirlImage( const double degrees_ );
1151 
1152     void operator()( Image &image_ ) const;
1153 
1154   private:
1155     double _degrees;
1156   };
1157 
1158   // Channel a texture on image background
1159   class MagickPPExport textureImage
1160   {
1161   public:
1162     textureImage( const Image &texture_ );
1163 
1164     void operator()( Image &image_ ) const;
1165 
1166   private:
1167     Image _texture;
1168   };
1169 
1170   // Threshold image
1171   class MagickPPExport thresholdImage
1172   {
1173   public:
1174     thresholdImage( const double threshold_ );
1175 
1176     void operator()( Image &image_ ) const;
1177 
1178   private:
1179     double _threshold;
1180   };
1181 
1182   // Set image color to transparent
1183   class MagickPPExport transparentImage
1184   {
1185   public:
1186     transparentImage( const Color& color_ );
1187 
1188     void operator()( Image &image_ ) const;
1189 
1190   private:
1191     Color _color;
1192   };
1193 
1194   // Trim edges that are the background color from the image
1195   class MagickPPExport trimImage
1196   {
1197   public:
1198     trimImage( void );
1199 
1200     void operator()( Image &image_ ) const;
1201 
1202   private:
1203   };
1204 
1205   // Map image pixels to a sine wave
1206   class MagickPPExport waveImage
1207   {
1208   public:
1209     waveImage( const double amplitude_ = 25.0,
1210          const double wavelength_ = 150.0 );
1211 
1212     void operator()( Image &image_ ) const;
1213 
1214   private:
1215     double _amplitude;
1216     double _wavelength;
1217   };
1218 
1219   // Zoom image to specified size.
1220   class MagickPPExport zoomImage
1221   {
1222   public:
1223     zoomImage( const Geometry &geometry_ );
1224 
1225     void operator()( Image &image_ ) const;
1226 
1227   private:
1228     Geometry _geometry;
1229   };
1230 
1231   //
1232   // Function object image attribute accessors
1233   //
1234 
1235   // Join images into a single multi-image file
1236   class MagickPPExport adjoinImage
1237   {
1238   public:
1239     adjoinImage( const bool flag_ );
1240 
1241     void operator()( Image &image_ ) const;
1242 
1243   private:
1244     bool _flag;
1245   };
1246 
1247   // Time in 1/100ths of a second which must expire before displaying
1248   // the next image in an animated sequence.
1249   class MagickPPExport animationDelayImage
1250   {
1251   public:
1252     animationDelayImage( const size_t delay_ );
1253 
1254     void operator()( Image &image_ ) const;
1255 
1256   private:
1257     size_t _delay;
1258   };
1259 
1260   // Number of iterations to loop an animation (e.g. Netscape loop
1261   // extension) for.
1262   class MagickPPExport animationIterationsImage
1263   {
1264   public:
1265     animationIterationsImage( const size_t iterations_ );
1266 
1267     void operator()( Image &image_ ) const;
1268 
1269   private:
1270     size_t _iterations;
1271   };
1272 
1273   // Image background color
1274   class MagickPPExport backgroundColorImage
1275   {
1276   public:
1277     backgroundColorImage( const Color &color_ );
1278 
1279     void operator()( Image &image_ ) const;
1280 
1281   private:
1282     Color _color;
1283   };
1284 
1285   // Name of texture image to tile onto the image background
1286   class MagickPPExport backgroundTextureImage
1287   {
1288   public:
1289     backgroundTextureImage( const std::string &backgroundTexture_ );
1290 
1291     void operator()( Image &image_ ) const;
1292 
1293   private:
1294     std::string _backgroundTexture;
1295   };
1296 
1297   // Image border color
1298   class MagickPPExport borderColorImage
1299   {
1300   public:
1301     borderColorImage( const Color &color_ );
1302 
1303     void operator()( Image &image_ ) const;
1304 
1305   private:
1306     Color _color;
1307   };
1308 
1309   // Text bounding-box base color (default none)
1310   class MagickPPExport boxColorImage
1311   {
1312   public:
1313     boxColorImage( const Color &boxColor_ );
1314 
1315     void operator()( Image &image_ ) const;
1316 
1317   private:
1318     Color _boxColor;
1319   };
1320 
1321   // Chromaticity blue primary point.
1322   class MagickPPExport chromaBluePrimaryImage
1323   {
1324   public:
1325     chromaBluePrimaryImage(const double x_,const double y_,const double z_);
1326 
1327     void operator()(Image &image_) const;
1328 
1329   private:
1330     double _x;
1331     double _y;
1332     double _z;
1333   };
1334 
1335   // Chromaticity green primary point.
1336   class MagickPPExport chromaGreenPrimaryImage
1337   {
1338   public:
1339     chromaGreenPrimaryImage(const double x_,const double y_,const double z_);
1340 
1341     void operator()(Image &image_) const;
1342 
1343   private:
1344     double _x;
1345     double _y;
1346     double _z;
1347   };
1348 
1349   // Chromaticity red primary point.
1350   class MagickPPExport chromaRedPrimaryImage
1351   {
1352   public:
1353     chromaRedPrimaryImage(const double x_,const double y_,const double z_);
1354 
1355     void operator()(Image &image_) const;
1356 
1357   private:
1358     double _x;
1359     double _y;
1360     double _z;
1361   };
1362 
1363   // Chromaticity white point.
1364   class MagickPPExport chromaWhitePointImage
1365   {
1366   public:
1367     chromaWhitePointImage(const double x_,const double y_,const double z_);
1368 
1369     void operator()(Image &image_) const;
1370 
1371   private:
1372     double _x;
1373     double _y;
1374     double _z;
1375   };
1376 
1377   // Colors within this distance are considered equal
1378   class MagickPPExport colorFuzzImage
1379   {
1380   public:
1381     colorFuzzImage( const double fuzz_ );
1382 
1383     void operator()( Image &image_ ) const;
1384 
1385   private:
1386     double _fuzz;
1387   };
1388 
1389   // Color at colormap position index_
1390   class MagickPPExport colorMapImage
1391   {
1392   public:
1393     colorMapImage( const size_t index_, const Color &color_ );
1394 
1395     void operator()( Image &image_ ) const;
1396 
1397   private:
1398     size_t _index;
1399     Color        _color;
1400   };
1401 
1402   // Composition operator to be used when composition is implicitly used
1403   // (such as for image flattening).
1404   class MagickPPExport composeImage
1405   {
1406   public:
1407     composeImage( const CompositeOperator compose_ );
1408 
1409     void operator()( Image &image_ ) const;
1410 
1411   private:
1412     CompositeOperator _compose;
1413   };
1414 
1415   // Compression type
1416   class MagickPPExport compressTypeImage
1417   {
1418   public:
1419     compressTypeImage( const CompressionType compressType_ );
1420 
1421     void operator()( Image &image_ ) const;
1422 
1423   private:
1424     CompressionType _compressType;
1425   };
1426 
1427   // Vertical and horizontal resolution in pixels of the image
1428   class MagickPPExport densityImage
1429   {
1430   public:
1431     densityImage( const Point &point_ );
1432 
1433     void operator()( Image &image_ ) const;
1434 
1435   private:
1436     Point _point;
1437   };
1438 
1439   // Image depth (bits allocated to red/green/blue components)
1440   class MagickPPExport depthImage
1441   {
1442   public:
1443     depthImage( const size_t depth_ );
1444 
1445     void operator()( Image &image_ ) const;
1446 
1447   private:
1448     size_t _depth;
1449   };
1450 
1451   // Endianness (LSBEndian like Intel or MSBEndian like SPARC) for image
1452   // formats which support endian-specific options.
1453   class MagickPPExport endianImage
1454   {
1455   public:
1456     endianImage( const EndianType endian_ );
1457 
1458     void operator()( Image &image_ ) const;
1459 
1460   private:
1461     EndianType  _endian;
1462   };
1463 
1464   // Image file name
1465   class MagickPPExport fileNameImage
1466   {
1467   public:
1468     fileNameImage( const std::string &fileName_ );
1469 
1470     void operator()( Image &image_ ) const;
1471 
1472   private:
1473     std::string _fileName;
1474   };
1475 
1476   // Filter to use when resizing image
1477   class MagickPPExport filterTypeImage
1478   {
1479   public:
1480     filterTypeImage( const FilterType filterType_ );
1481 
1482     void operator()( Image &image_ ) const;
1483 
1484   private:
1485     FilterType _filterType;
1486   };
1487 
1488   // Text rendering font
1489   class MagickPPExport fontImage
1490   {
1491   public:
1492     fontImage( const std::string &font_ );
1493 
1494     void operator()( Image &image_ ) const;
1495 
1496   private:
1497     std::string _font;
1498   };
1499 
1500   // Font point size
1501   class MagickPPExport fontPointsizeImage
1502   {
1503   public:
1504     fontPointsizeImage( const size_t pointsize_ );
1505 
1506     void operator()( Image &image_ ) const;
1507 
1508   private:
1509     size_t _pointsize;
1510   };
1511 
1512   // GIF disposal method
1513   class MagickPPExport gifDisposeMethodImage
1514   {
1515   public:
1516     gifDisposeMethodImage( const DisposeType disposeMethod_ );
1517 
1518     void operator()( Image &image_ ) const;
1519 
1520   private:
1521     DisposeType _disposeMethod;
1522   };
1523 
1524   // Type of interlacing to use
1525   class MagickPPExport interlaceTypeImage
1526   {
1527   public:
1528     interlaceTypeImage( const InterlaceType interlace_ );
1529 
1530     void operator()( Image &image_ ) const;
1531 
1532   private:
1533     InterlaceType _interlace;
1534   };
1535 
1536   // File type magick identifier (.e.g "GIF")
1537   class MagickPPExport magickImage
1538   {
1539   public:
1540     magickImage( const std::string &magick_ );
1541 
1542     void operator()( Image &image_ ) const;
1543 
1544   private:
1545     std::string _magick;
1546   };
1547 
1548   // Image supports transparent color
1549   class MagickPPExport alphaFlagImage
1550   {
1551   public:
1552     alphaFlagImage( const bool alphaFlag_ );
1553 
1554     void operator()( Image &image_ ) const;
1555 
1556   private:
1557     bool _alphaFlag;
1558   };
1559 
1560   // Transparent color
1561   class MagickPPExport matteColorImage
1562   {
1563   public:
1564     matteColorImage( const Color &matteColor_ );
1565 
1566     void operator()( Image &image_ ) const;
1567 
1568   private:
1569     Color _matteColor;
1570   };
1571 
1572   // Indicate that image is black and white
1573   class MagickPPExport monochromeImage
1574   {
1575   public:
1576     monochromeImage( const bool monochromeFlag_ );
1577 
1578     void operator()( Image &image_ ) const;
1579 
1580   private:
1581     bool _monochromeFlag;
1582   };
1583 
1584   // Pen color
1585   class MagickPPExport penColorImage
1586   {
1587   public:
1588     penColorImage( const Color &penColor_ );
1589 
1590     void operator()( Image &image_ ) const;
1591 
1592   private:
1593     Color _penColor;
1594   };
1595 
1596   // Pen texture image.
1597   class MagickPPExport penTextureImage
1598   {
1599   public:
1600     penTextureImage( const Image &penTexture_ );
1601 
1602     void operator()( Image &image_ ) const;
1603 
1604   private:
1605     Image _penTexture;
1606   };
1607 
1608   // Set pixel color at location x & y.
1609   class MagickPPExport pixelColorImage
1610   {
1611   public:
1612     pixelColorImage( const ::ssize_t x_,
1613                      const ::ssize_t y_,
1614          const Color &color_);
1615 
1616     void operator()( Image &image_ ) const;
1617 
1618   private:
1619     ::ssize_t    _x;
1620     ::ssize_t    _y;
1621     Color        _color;
1622   };
1623 
1624   // Postscript page size.
1625   class MagickPPExport pageImage
1626   {
1627   public:
1628     pageImage( const Geometry &pageSize_ );
1629 
1630     void operator()( Image &image_ ) const;
1631 
1632   private:
1633     Geometry _pageSize;
1634   };
1635 
1636   // JPEG/MIFF/PNG compression level (default 75).
1637   class MagickPPExport qualityImage
1638   {
1639   public:
1640     qualityImage( const size_t quality_ );
1641 
1642     void operator()( Image &image_ ) const;
1643 
1644   private:
1645     size_t _quality;
1646   };
1647 
1648   // Maximum number of colors to quantize to
1649   class MagickPPExport quantizeColorsImage
1650   {
1651   public:
1652     quantizeColorsImage( const size_t colors_ );
1653 
1654     void operator()( Image &image_ ) const;
1655 
1656   private:
1657     size_t _colors;
1658   };
1659 
1660   // Colorspace to quantize in.
1661   class MagickPPExport quantizeColorSpaceImage
1662   {
1663   public:
1664     quantizeColorSpaceImage( const ColorspaceType colorSpace_ );
1665 
1666     void operator()( Image &image_ ) const;
1667 
1668   private:
1669     ColorspaceType _colorSpace;
1670   };
1671 
1672   // Dither image during quantization (default true).
1673   class MagickPPExport quantizeDitherImage
1674   {
1675   public:
1676     quantizeDitherImage( const bool ditherFlag_ );
1677 
1678     void operator()( Image &image_ ) const;
1679 
1680   private:
1681     bool _ditherFlag;
1682   };
1683 
1684   // Quantization tree-depth
1685   class MagickPPExport quantizeTreeDepthImage
1686   {
1687   public:
1688     quantizeTreeDepthImage( const size_t treeDepth_ );
1689 
1690     void operator()( Image &image_ ) const;
1691 
1692   private:
1693     size_t _treeDepth;
1694   };
1695 
1696   // The type of rendering intent
1697   class MagickPPExport renderingIntentImage
1698   {
1699   public:
1700     renderingIntentImage( const RenderingIntent renderingIntent_ );
1701 
1702     void operator()( Image &image_ ) const;
1703 
1704   private:
1705     RenderingIntent _renderingIntent;
1706   };
1707 
1708   // Units of image resolution
1709   class MagickPPExport resolutionUnitsImage
1710   {
1711   public:
1712     resolutionUnitsImage( const ResolutionType resolutionUnits_ );
1713 
1714     void operator()( Image &image_ ) const;
1715 
1716   private:
1717     ResolutionType _resolutionUnits;
1718   };
1719 
1720   // Image scene number
1721   class MagickPPExport sceneImage
1722   {
1723   public:
1724     sceneImage( const size_t scene_ );
1725 
1726     void operator()( Image &image_ ) const;
1727 
1728   private:
1729     size_t _scene;
1730   };
1731 
1732   // adjust the image contrast with a non-linear sigmoidal contrast algorithm
1733   class MagickPPExport sigmoidalContrastImage
1734   {
1735   public:
1736     sigmoidalContrastImage( const size_t sharpen_,
1737       const double contrast,
1738       const double midpoint = QuantumRange / 2.0 );
1739 
1740     void operator()( Image &image_ ) const;
1741 
1742   private:
1743     size_t _sharpen;
1744     double contrast;
1745     double midpoint;
1746   };
1747 
1748   // Width and height of a raw image
1749   class MagickPPExport sizeImage
1750   {
1751   public:
1752     sizeImage( const Geometry &geometry_ );
1753 
1754     void operator()( Image &image_ ) const;
1755 
1756   private:
1757     Geometry _geometry;
1758   };
1759 
1760   // stripImage strips an image of all profiles and comments.
1761   class MagickPPExport stripImage
1762   {
1763   public:
1764     stripImage( void );
1765 
1766     void operator()( Image &image_ ) const;
1767 
1768   private:
1769   };
1770 
1771   // Subimage of an image sequence
1772   class MagickPPExport subImageImage
1773   {
1774   public:
1775     subImageImage( const size_t subImage_ );
1776 
1777     void operator()( Image &image_ ) const;
1778 
1779   private:
1780     size_t _subImage;
1781   };
1782 
1783   // Number of images relative to the base image
1784   class MagickPPExport subRangeImage
1785   {
1786   public:
1787     subRangeImage( const size_t subRange_ );
1788 
1789     void operator()( Image &image_ ) const;
1790 
1791   private:
1792     size_t _subRange;
1793   };
1794 
1795   // Anti-alias Postscript and TrueType fonts (default true)
1796   class MagickPPExport textAntiAliasImage
1797   {
1798   public:
1799     textAntiAliasImage( const bool flag_ );
1800 
1801     void operator()( Image &image_ ) const;
1802 
1803   private:
1804     bool _flag;
1805   };
1806 
1807   // Image storage type
1808   class MagickPPExport typeImage
1809   {
1810   public:
1811     typeImage( const ImageType type_ );
1812 
1813     void operator()( Image &image_ ) const;
1814 
1815   private:
1816     Magick::ImageType _type;
1817   };
1818 
1819 
1820   // Print detailed information about the image
1821   class MagickPPExport verboseImage
1822   {
1823   public:
1824     verboseImage( const bool verbose_ );
1825 
1826     void operator()( Image &image_ ) const;
1827 
1828   private:
1829     bool _verbose;
1830   };
1831 
1832   // X11 display to display to, obtain fonts from, or to capture
1833   // image from
1834   class MagickPPExport x11DisplayImage
1835   {
1836   public:
1837     x11DisplayImage( const std::string &display_ );
1838 
1839     void operator()( Image &image_ ) const;
1840 
1841   private:
1842     std::string _display;
1843   };
1844 
1845   //////////////////////////////////////////////////////////
1846   //
1847   // Implementation template definitions. Not for end-use.
1848   //
1849   //////////////////////////////////////////////////////////
1850 
1851   // Changes the channel mask of the images and places the old
1852   // values in the container.
1853   template<class InputIterator, class Container>
1854   void channelMaskImages(InputIterator first_,InputIterator last_,
1855     Container *container_,const ChannelType channel_)
1856   {
1857     MagickCore::ChannelType
1858       channel_mask;
1859 
1860     container_->clear();
1861     for (InputIterator iter = first_; iter != last_; ++iter)
1862     {
1863       iter->modifyImage();
1864       channel_mask=MagickCore::SetImageChannelMask(iter->image(),channel_);
1865       container_->push_back(channel_mask);
1866     }
1867   }
1868 
1869   // Insert images in image list into existing container (appending to container)
1870   // The images should not be deleted since only the image ownership is passed.
1871   // The options are copied into the object.
1872   template<class Container>
1873   void insertImages(Container *sequence_,MagickCore::Image* images_)
1874   {
1875     MagickCore::Image
1876       *image,
1877       *next;
1878 
1879     image=images_;
1880     while (image != (MagickCore::Image *) NULL)
1881     {
1882       next=image->next;
1883       image->next=(MagickCore::Image *) NULL;
1884 
1885       if (next != (MagickCore::Image *) NULL)
1886         next->previous=(MagickCore::Image *) NULL;
1887 
1888       sequence_->push_back(Magick::Image(image));
1889 
1890       image=next;
1891     }
1892   }
1893 
1894   // Link images together into an image list based on the ordering of
1895   // the container implied by the iterator. This step is done in
1896   // preparation for use with ImageMagick functions which operate on
1897   // lists of images.
1898   // Images are selected by range, first_ to last_ so that a subset of
1899   // the container may be selected.  Specify first_ via the
1900   // container's begin() method and last_ via the container's end()
1901   // method in order to specify the entire container.
1902   template<class InputIterator>
1903   bool linkImages(InputIterator first_,InputIterator last_)
1904   {
1905     MagickCore::Image
1906       *current,
1907       *previous;
1908 
1909     ::ssize_t
1910       scene;
1911 
1912     scene=0;
1913     previous=(MagickCore::Image *) NULL;
1914     for (InputIterator iter = first_; iter != last_; ++iter)
1915     {
1916       // Unless we reduce the reference count to one, the same image
1917       // structure may occur more than once in the container, causing
1918       // the linked list to fail.
1919       iter->modifyImage();
1920 
1921       current=iter->image();
1922 
1923       current->previous=previous;
1924       current->next=(MagickCore::Image *) NULL;
1925       current->scene=scene++;
1926 
1927       if (previous != (MagickCore::Image *) NULL)
1928         previous->next=current;
1929 
1930       previous=current;
1931     }
1932     return(scene > 0 ? true : false);
1933   }
1934 
1935   // Restores the channel mask of the images.
1936   template<class InputIterator, class Container>
1937   void restoreChannelMaskImages(InputIterator first_,InputIterator last_,
1938     Container *container_)
1939   {
1940     typename Container::iterator
1941       channel_mask;
1942 
1943     channel_mask=container_->begin();
1944     for (InputIterator iter = first_; iter != last_; ++iter)
1945     {
1946       iter->modifyImage();
1947       (void) MagickCore::SetImageChannelMask(iter->image(),
1948         (const MagickCore::ChannelType) *channel_mask);
1949       channel_mask++;
1950     }
1951   }
1952 
1953   // Remove links added by linkImages. This should be called after the
1954   // ImageMagick function call has completed to reset the image list
1955   // back to its pristine un-linked state.
1956   template<class InputIterator>
1957   void unlinkImages(InputIterator first_,InputIterator last_)
1958   {
1959     MagickCore::Image
1960       *image;
1961 
1962     for (InputIterator iter = first_; iter != last_; ++iter)
1963     {
1964       image=iter->image();
1965       image->previous=(MagickCore::Image *) NULL;
1966       image->next=(MagickCore::Image *) NULL;
1967     }
1968   }
1969 
1970   ///////////////////////////////////////////////////////////////////
1971   //
1972   // Template definitions for documented API
1973   //
1974   ///////////////////////////////////////////////////////////////////
1975 
1976   template <class InputIterator>
1977   void animateImages( InputIterator first_,InputIterator last_)
1978   {
1979     if (linkImages(first_,last_) == false)
1980       return;
1981     GetPPException;
1982     MagickCore::AnimateImages(first_->imageInfo(),first_->image(),
1983       exceptionInfo);
1984     unlinkImages(first_,last_);
1985     ThrowPPException(first_->quiet());
1986   }
1987 
1988   // Append images from list into single image in either horizontal or
1989   // vertical direction.
1990   template <class InputIterator>
1991   void appendImages( Image *appendedImage_,
1992          InputIterator first_,
1993          InputIterator last_,
1994          bool stack_ = false) {
1995     if (linkImages(first_,last_) == false)
1996       return;
1997     GetPPException;
1998     MagickCore::Image* image = MagickCore::AppendImages( first_->image(),
1999                    (MagickBooleanType) stack_,
2000                    exceptionInfo );
2001     unlinkImages( first_, last_ );
2002     appendedImage_->replaceImage( image );
2003     ThrowPPException(appendedImage_->quiet());
2004   }
2005 
2006   // Adds the names of the artifacts of the image to the container.
2007   template <class Container>
2008   void artifactNames(Container *names_,const Image* image_)
2009   {
2010     const char*
2011       name;
2012 
2013     names_->clear();
2014 
2015     MagickCore::ResetImageArtifactIterator(image_->constImage());
2016     name=MagickCore::GetNextImageArtifact(image_->constImage());
2017     while (name != (const char *) NULL)
2018     {
2019       names_->push_back(std::string(name));
2020       name=MagickCore::GetNextImageArtifact(image_->constImage());
2021     }
2022   }
2023 
2024   // Adds the names of the attributes of the image to the container.
2025   template <class Container>
2026   void attributeNames(Container *names_,const Image* image_)
2027   {
2028     const char*
2029       name;
2030 
2031     names_->clear();
2032 
2033     MagickCore::ResetImagePropertyIterator(image_->constImage());
2034     name=MagickCore::GetNextImageProperty(image_->constImage());
2035     while (name != (const char *) NULL)
2036     {
2037       names_->push_back(std::string(name));
2038       name=MagickCore::GetNextImageProperty(image_->constImage());
2039     }
2040   }
2041 
2042   // Average a set of images.
2043   // All the input images must be the same size in pixels.
2044   template <class InputIterator>
2045   void averageImages( Image *averagedImage_,
2046           InputIterator first_,
2047           InputIterator last_ ) {
2048     if (linkImages(first_,last_) == false)
2049       return;
2050     GetPPException;
2051     MagickCore::Image* image = MagickCore::EvaluateImages( first_->image(),
2052       MagickCore::MeanEvaluateOperator, exceptionInfo );
2053     unlinkImages( first_, last_ );
2054     averagedImage_->replaceImage( image );
2055     ThrowPPException(averagedImage_->quiet());
2056   }
2057 
2058   // Merge a sequence of images.
2059   // This is useful for GIF animation sequences that have page
2060   // offsets and disposal methods. A container to contain
2061   // the updated image sequence is passed via the coalescedImages_
2062   // option.
2063   template <class InputIterator, class Container >
2064   void coalesceImages(Container *coalescedImages_,InputIterator first_,
2065     InputIterator last_)
2066   {
2067     bool
2068       quiet;
2069 
2070     MagickCore::Image
2071       *images;
2072 
2073     if (linkImages(first_,last_) == false)
2074       return;
2075 
2076     GetPPException;
2077     quiet=first_->quiet();
2078     images=MagickCore::CoalesceImages(first_->image(),exceptionInfo);
2079 
2080     // Unlink image list
2081     unlinkImages(first_,last_);
2082 
2083     // Ensure container is empty
2084     coalescedImages_->clear();
2085 
2086     // Move images to container
2087     insertImages(coalescedImages_,images);
2088 
2089     // Report any error
2090     ThrowPPException(quiet);
2091   }
2092 
2093   // Return format coders matching specified conditions.
2094   //
2095   // The default (if no match terms are supplied) is to return all
2096   // available format coders.
2097   //
2098   // For example, to return all readable formats:
2099   //  list<CoderInfo> coderList;
2100   //  coderInfoList( &coderList, CoderInfo::TrueMatch, CoderInfo::AnyMatch, CoderInfo::AnyMatch)
2101   //
2102   template <class Container >
2103   void coderInfoList( Container *container_,
2104                       CoderInfo::MatchType isReadable_ = CoderInfo::AnyMatch,
2105                       CoderInfo::MatchType isWritable_ = CoderInfo::AnyMatch,
2106                       CoderInfo::MatchType isMultiFrame_ = CoderInfo::AnyMatch
2107                       ) {
2108     // Obtain first entry in MagickInfo list
2109     size_t number_formats;
2110     GetPPException;
2111     char **coder_list =
2112       MagickCore::GetMagickList( "*", &number_formats, exceptionInfo );
2113     if( !coder_list )
2114       {
2115         throwException(exceptionInfo);
2116         throwExceptionExplicit(MagickCore::MissingDelegateError,
2117                              "Coder array not returned!", 0 );
2118       }
2119 
2120     // Clear out container
2121     container_->clear();
2122 
2123     for ( ::ssize_t i=0; i < (::ssize_t) number_formats; i++)
2124       {
2125         const MagickCore::MagickInfo *magick_info =
2126           MagickCore::GetMagickInfo( coder_list[i], exceptionInfo );
2127         if (!magick_info)
2128           continue;
2129 
2130         coder_list[i]=(char *)
2131           MagickCore::RelinquishMagickMemory( coder_list[i] );
2132 
2133         // Skip stealth coders
2134         if ( MagickCore::GetMagickStealth(magick_info) )
2135           continue;
2136 
2137         try {
2138           CoderInfo coderInfo( magick_info->name );
2139 
2140           // Test isReadable_
2141           if ( isReadable_ != CoderInfo::AnyMatch &&
2142                (( coderInfo.isReadable() && isReadable_ != CoderInfo::TrueMatch ) ||
2143                 ( !coderInfo.isReadable() && isReadable_ != CoderInfo::FalseMatch )) )
2144             continue;
2145 
2146           // Test isWritable_
2147           if ( isWritable_ != CoderInfo::AnyMatch &&
2148                (( coderInfo.isWritable() && isWritable_ != CoderInfo::TrueMatch ) ||
2149                 ( !coderInfo.isWritable() && isWritable_ != CoderInfo::FalseMatch )) )
2150             continue;
2151 
2152           // Test isMultiFrame_
2153           if ( isMultiFrame_ != CoderInfo::AnyMatch &&
2154                (( coderInfo.isMultiFrame() && isMultiFrame_ != CoderInfo::TrueMatch ) ||
2155                 ( !coderInfo.isMultiFrame() && isMultiFrame_ != CoderInfo::FalseMatch )) )
2156             continue;
2157 
2158           // Append matches to container
2159           container_->push_back( coderInfo );
2160         }
2161         // Intentionally ignore missing module errors
2162         catch (Magick::ErrorModule&)
2163         {
2164           continue;
2165         }
2166       }
2167     coder_list=(char **) MagickCore::RelinquishMagickMemory( coder_list );
2168     ThrowPPException(false);
2169   }
2170 
2171   //
2172   // Fill container with color histogram.
2173   // Entries are of type "std::pair<Color,size_t>".  Use the pair
2174   // "first" member to access the Color and the "second" member to access
2175   // the number of times the color occurs in the image.
2176   //
2177   // For example:
2178   //
2179   //  Using <map>:
2180   //
2181   //  Image image("image.miff");
2182   //  map<Color,size_t> histogram;
2183   //  colorHistogram( &histogram, image );
2184   //  std::map<Color,size_t>::const_iterator p=histogram.begin();
2185   //  while (p != histogram.end())
2186   //    {
2187   //      cout << setw(10) << (int)p->second << ": ("
2188   //           << setw(quantum_width) << (int)p->first.redQuantum() << ","
2189   //           << setw(quantum_width) << (int)p->first.greenQuantum() << ","
2190   //           << setw(quantum_width) << (int)p->first.blueQuantum() << ")"
2191   //           << endl;
2192   //      p++;
2193   //    }
2194   //
2195   //  Using <vector>:
2196   //
2197   //  Image image("image.miff");
2198   //  std::vector<std::pair<Color,size_t> > histogram;
2199   //  colorHistogram( &histogram, image );
2200   //  std::vector<std::pair<Color,size_t> >::const_iterator p=histogram.begin();
2201   //  while (p != histogram.end())
2202   //    {
2203   //      cout << setw(10) << (int)p->second << ": ("
2204   //           << setw(quantum_width) << (int)p->first.redQuantum() << ","
2205   //           << setw(quantum_width) << (int)p->first.greenQuantum() << ","
2206   //           << setw(quantum_width) << (int)p->first.blueQuantum() << ")"
2207   //           << endl;
2208   //      p++;
2209   //    }
2210 
2211   template <class Container >
2212   void colorHistogram( Container *histogram_, const Image image)
2213   {
2214     GetPPException;
2215 
2216     // Obtain histogram array
2217     size_t colors;
2218     MagickCore::PixelInfo *histogram_array =
2219       MagickCore::GetImageHistogram( image.constImage(), &colors, exceptionInfo );
2220     ThrowPPException(image.quiet());
2221 
2222     // Clear out container
2223     histogram_->clear();
2224 
2225     // Transfer histogram array to container
2226     for ( size_t i=0; i < colors; i++)
2227       {
2228         histogram_->insert( histogram_->end(), std::pair<const Color,size_t>
2229           ( Color(histogram_array[i]), (size_t) histogram_array[i].count) );
2230       }
2231 
2232     // Deallocate histogram array
2233     histogram_array=(MagickCore::PixelInfo *)
2234       MagickCore::RelinquishMagickMemory(histogram_array);
2235   }
2236 
2237   // Combines one or more images into a single image. The grayscale value of
2238   // the pixels of each image in the sequence is assigned in order to the
2239   // specified channels of the combined image. The typical ordering would be
2240   // image 1 => Red, 2 => Green, 3 => Blue, etc.
2241   template<class InputIterator >
2242   void combineImages(Image *combinedImage_,InputIterator first_,
2243     InputIterator last_,const ChannelType channel_,
2244     const ColorspaceType colorspace_ = MagickCore::sRGBColorspace)
2245   {
2246     MagickCore::Image
2247       *image;
2248 
2249     std::vector<ChannelType>
2250       channelMask;
2251 
2252     if (linkImages(first_,last_) == false)
2253       return;
2254     GetPPException;
2255     channelMaskImages(first_,last_,&channelMask,channel_);
2256     image=CombineImages(first_->image(),colorspace_,exceptionInfo);
2257     restoreChannelMaskImages(first_,last_,&channelMask);
2258     unlinkImages(first_,last_);
2259     combinedImage_->replaceImage(image);
2260     ThrowPPException(combinedImage_->quiet());
2261   }
2262 
2263   template <class Container>
2264   void cropToTiles(Container *tiledImages_,const Image image_,
2265     const Geometry &geometry_)
2266   {
2267     GetPPException;
2268     MagickCore::Image* images=CropImageToTiles(image_.constImage(),
2269       static_cast<std::string>(geometry_).c_str(),exceptionInfo);
2270     tiledImages_->clear();
2271     insertImages(tiledImages_,images);
2272     ThrowPPException(image_.quiet());
2273   }
2274 
2275   // Break down an image sequence into constituent parts.  This is
2276   // useful for creating GIF or MNG animation sequences.
2277   template<class InputIterator,class Container>
2278   void deconstructImages(Container *deconstructedImages_,
2279     InputIterator first_,InputIterator last_)
2280   {
2281     bool
2282       quiet;
2283 
2284     MagickCore::Image
2285       *images;
2286 
2287     if (linkImages(first_,last_) == false)
2288       return;
2289     GetPPException;
2290     quiet=first_->quiet();
2291     images=CompareImagesLayers(first_->image(),CompareAnyLayer,exceptionInfo);
2292     unlinkImages(first_,last_);
2293 
2294     deconstructedImages_->clear();
2295     insertImages(deconstructedImages_,images);
2296 
2297     ThrowPPException(quiet);
2298   }
2299 
2300   //
2301   // Display an image sequence
2302   //
2303   template <class InputIterator>
2304   void displayImages(InputIterator first_,InputIterator last_)
2305   {
2306     if (linkImages(first_,last_) == false)
2307       return;
2308     GetPPException;
2309     MagickCore::DisplayImages(first_->imageInfo(),first_->image(),
2310       exceptionInfo);
2311     unlinkImages(first_,last_);
2312     ThrowPPException(first_->quiet());
2313   }
2314 
2315   // Applies a value to the image with an arithmetic, relational,
2316   // or logical operator to an image. Use these operations to lighten or darken
2317   // an image, to increase or decrease contrast in an image, or to produce the
2318   // "negative" of an image.
2319   template <class InputIterator >
2320   void evaluateImages( Image *evaluatedImage_,
2321                        InputIterator first_,
2322                        InputIterator last_,
2323                        const MagickEvaluateOperator operator_ ) {
2324     if (linkImages(first_,last_) == false)
2325       return;
2326     GetPPException;
2327     MagickCore::Image* image = EvaluateImages( first_->image(), operator_, exceptionInfo );
2328     unlinkImages( first_, last_ );
2329     evaluatedImage_->replaceImage( image );
2330     ThrowPPException(evaluatedImage_->quiet());
2331   }
2332 
2333   // Merge a sequence of image frames which represent image layers.
2334   // This is useful for combining Photoshop layers into a single image.
2335   template <class InputIterator>
2336   void flattenImages( Image *flattenedImage_,
2337           InputIterator first_,
2338           InputIterator last_ ) {
2339     if (linkImages(first_,last_) == false)
2340       return;
2341     GetPPException;
2342     MagickCore::Image* image = MagickCore::MergeImageLayers( first_->image(),
2343       FlattenLayer,exceptionInfo );
2344     unlinkImages( first_, last_ );
2345     flattenedImage_->replaceImage( image );
2346     ThrowPPException(flattenedImage_->quiet());
2347   }
2348 
2349   // Implements the discrete Fourier transform (DFT) of the image either as a
2350   // magnitude / phase or real / imaginary image pair.
2351   template <class Container >
2352   void forwardFourierTransformImage( Container *fourierImages_,
2353     const Image &image_ ) {
2354     GetPPException;
2355 
2356     // Build image list
2357     MagickCore::Image* images = ForwardFourierTransformImage(
2358       image_.constImage(), MagickTrue, exceptionInfo);
2359 
2360     // Ensure container is empty
2361     fourierImages_->clear();
2362 
2363     // Move images to container
2364     insertImages( fourierImages_, images );
2365 
2366     // Report any error
2367     ThrowPPException(image_.quiet());
2368   }
2369   template <class Container >
2370   void forwardFourierTransformImage( Container *fourierImages_,
2371     const Image &image_, const bool magnitude_ ) {
2372     GetPPException;
2373 
2374     // Build image list
2375     MagickCore::Image* images = ForwardFourierTransformImage(
2376       image_.constImage(), magnitude_ == true ? MagickTrue : MagickFalse,
2377       exceptionInfo);
2378 
2379     // Ensure container is empty
2380     fourierImages_->clear();
2381 
2382     // Move images to container
2383     insertImages( fourierImages_, images );
2384 
2385     // Report any error
2386     ThrowPPException(image_.quiet());
2387   }
2388 
2389   // Applies a mathematical expression to a sequence of images.
2390   template <class InputIterator>
2391   void fxImages(Image *fxImage_,InputIterator first_,InputIterator last_,
2392     const std::string expression)
2393   {
2394     MagickCore::Image
2395       *image;
2396 
2397     if (linkImages(first_,last_) == false)
2398       return;
2399     GetPPException;
2400     image=FxImage(first_->constImage(),expression.c_str(),exceptionInfo);
2401     unlinkImages(first_,last_);
2402     fxImage_->replaceImage(image);
2403     ThrowPPException(fxImage_->quiet());
2404   }
2405 
2406   // Replace the colors of a sequence of images with the closest color
2407   // from a reference image.
2408   // Set dither_ to true to enable dithering.  Set measureError_ to
2409   // true in order to evaluate quantization error.
2410   template<class InputIterator>
2411   void mapImages(InputIterator first_,InputIterator last_,
2412     const Image& mapImage_,bool dither_=false,bool measureError_=false)
2413   {
2414     MagickCore::Image
2415       *image;
2416 
2417     MagickCore::QuantizeInfo
2418       quantizeInfo;
2419 
2420     if (linkImages(first_,last_) == false)
2421       return;
2422     GetPPException;
2423     MagickCore::GetQuantizeInfo(&quantizeInfo);
2424     quantizeInfo.dither_method = dither_ ? MagickCore::RiemersmaDitherMethod :
2425       MagickCore::NoDitherMethod;
2426     MagickCore::RemapImages(&quantizeInfo,first_->image(),
2427       (mapImage_.isValid() ? mapImage_.constImage() :
2428       (const MagickCore::Image*) NULL),exceptionInfo);
2429     unlinkImages(first_,last_);
2430     if (exceptionInfo->severity != MagickCore::UndefinedException)
2431       {
2432         unlinkImages(first_,last_);
2433         throwException(exceptionInfo,mapImage_.quiet());
2434       }
2435 
2436     image=first_->image();
2437     while(image != (MagickCore::Image *) NULL)
2438       {
2439         // Calculate quantization error
2440         if (measureError_)
2441           {
2442             MagickCore::GetImageQuantizeError(image,exceptionInfo);
2443             if (exceptionInfo->severity > MagickCore::UndefinedException)
2444               {
2445                 unlinkImages(first_,last_);
2446                 throwException(exceptionInfo,mapImage_.quiet());
2447               }
2448           }
2449 
2450         // Update DirectClass representation of pixels
2451         MagickCore::SyncImage(image,exceptionInfo);
2452         if (exceptionInfo->severity > MagickCore::UndefinedException)
2453           {
2454             unlinkImages(first_,last_);
2455             throwException(exceptionInfo,mapImage_.quiet());
2456           }
2457 
2458         // Next image
2459         image=image->next;
2460       }
2461 
2462     unlinkImages(first_,last_);
2463     (void) MagickCore::DestroyExceptionInfo(exceptionInfo);
2464   }
2465 
2466   // Composes all the image layers from the current given
2467   // image onward to produce a single image of the merged layers.
2468   template <class InputIterator >
2469   void mergeImageLayers( Image *mergedImage_,
2470                          InputIterator first_,
2471                          InputIterator last_,
2472                          const LayerMethod method_ ) {
2473     if (linkImages(first_,last_) == false)
2474       return;
2475     GetPPException;
2476     MagickCore::Image* image = MergeImageLayers( first_->image(), method_, exceptionInfo );
2477     unlinkImages( first_, last_ );
2478     mergedImage_->replaceImage( image );
2479     ThrowPPException(mergedImage_->quiet());
2480   }
2481 
2482   // Create a composite image by combining several separate images.
2483   template <class Container, class InputIterator>
2484   void montageImages(Container *montageImages_,InputIterator first_,
2485     InputIterator last_,const Montage &options_)
2486   {
2487     bool
2488       quiet;
2489 
2490     MagickCore::Image
2491       *images;
2492 
2493     MagickCore::MontageInfo
2494       *montageInfo;
2495 
2496     if (linkImages(first_,last_) == false)
2497       return;
2498 
2499     montageInfo=static_cast<MagickCore::MontageInfo*>(
2500       MagickCore::AcquireMagickMemory(sizeof(MagickCore::MontageInfo)));
2501 
2502     // Update montage options with those set in montageOpts_
2503     options_.updateMontageInfo(*montageInfo);
2504 
2505     // Update options which must transfer to image options
2506     if (options_.label().length() != 0)
2507       first_->label(options_.label());
2508 
2509     // Do montage
2510     GetPPException;
2511     quiet=first_->quiet();
2512     images=MagickCore::MontageImages(first_->image(),montageInfo,
2513       exceptionInfo);
2514 
2515     // Unlink linked image list
2516     unlinkImages(first_,last_);
2517 
2518     // Reset output container to pristine state
2519     montageImages_->clear();
2520 
2521     if (images != (MagickCore::Image *) NULL)
2522       insertImages(montageImages_,images);
2523 
2524     // Clean up any allocated data in montageInfo
2525     MagickCore::DestroyMontageInfo(montageInfo);
2526 
2527     // Report any montage error
2528     ThrowPPException(quiet);
2529 
2530     // Apply transparency to montage images
2531     if (montageImages_->size() > 0 && options_.transparentColor().isValid())
2532       for_each(montageImages_->begin(),montageImages_->end(),transparentImage(
2533         options_.transparentColor()));
2534   }
2535 
2536   // Morph a set of images
2537   template <class InputIterator, class Container >
2538   void morphImages(Container *morphedImages_,InputIterator first_,
2539     InputIterator last_,size_t frames_)
2540   {
2541     bool
2542       quiet;
2543 
2544     MagickCore::Image
2545       *images;
2546 
2547     if (linkImages(first_,last_) == false)
2548       return;
2549 
2550     GetPPException;
2551     quiet=first_->quiet();
2552     images=MagickCore::MorphImages(first_->image(),frames_,exceptionInfo);
2553 
2554     // Unlink image list
2555     unlinkImages(first_,last_);
2556 
2557     // Ensure container is empty
2558     morphedImages_->clear();
2559 
2560     // Move images to container
2561     insertImages(morphedImages_,images);
2562 
2563     // Report any error
2564     ThrowPPException(quiet);
2565   }
2566 
2567   // Inlay a number of images to form a single coherent picture.
2568   template <class InputIterator>
2569   void mosaicImages( Image *mosaicImage_,
2570          InputIterator first_,
2571          InputIterator last_ ) {
2572     if (linkImages(first_,last_) == false)
2573       return;
2574     GetPPException;
2575     MagickCore::Image* image = MagickCore::MergeImageLayers( first_->image(),
2576        MosaicLayer,exceptionInfo );
2577     unlinkImages( first_, last_ );
2578     mosaicImage_->replaceImage( image );
2579     ThrowPPException(mosaicImage_->quiet());
2580   }
2581 
2582   // Compares each image the GIF disposed forms of the previous image in
2583   // the sequence. From this it attempts to select the smallest cropped
2584   // image to replace each frame, while preserving the results of the
2585   // GIF animation.
2586   template <class InputIterator, class Container >
2587   void optimizeImageLayers(Container *optimizedImages_,InputIterator first_,
2588     InputIterator last_)
2589   {
2590     bool
2591       quiet;
2592 
2593     MagickCore::Image
2594       *images;
2595 
2596     if (linkImages(first_,last_) == false)
2597       return;
2598 
2599     GetPPException;
2600     quiet=first_->quiet();
2601     images=OptimizeImageLayers(first_->image(),exceptionInfo);
2602 
2603     unlinkImages(first_,last_);
2604 
2605     optimizedImages_->clear();
2606 
2607     insertImages(optimizedImages_,images);
2608 
2609     ThrowPPException(quiet);
2610   }
2611 
2612   // optimizeImagePlusLayers is exactly as optimizeImageLayers, but may
2613   // also add or even remove extra frames in the animation, if it improves
2614   // the total number of pixels in the resulting GIF animation.
2615   template <class InputIterator, class Container >
2616   void optimizePlusImageLayers(Container *optimizedImages_,
2617     InputIterator first_,InputIterator last_ )
2618   {
2619     bool
2620       quiet;
2621 
2622     MagickCore::Image
2623       *images;
2624 
2625     if (linkImages(first_,last_) == false)
2626       return;
2627 
2628     GetPPException;
2629     quiet=first_->quiet();
2630     images=OptimizePlusImageLayers(first_->image(),exceptionInfo);
2631 
2632     unlinkImages(first_,last_);
2633 
2634     optimizedImages_->clear();
2635 
2636     insertImages(optimizedImages_,images);
2637 
2638     ThrowPPException(quiet);
2639   }
2640 
2641   // Compares each image the GIF disposed forms of the previous image in the
2642   // sequence. Any pixel that does not change the displayed result is replaced
2643   // with transparency.
2644   template<class InputIterator>
2645   void optimizeTransparency(InputIterator first_,InputIterator last_)
2646   {
2647     if (linkImages(first_,last_) == false)
2648       return;
2649     GetPPException;
2650     OptimizeImageTransparency(first_->image(),exceptionInfo);
2651     unlinkImages(first_,last_ );
2652 
2653     ThrowPPException(first_->quiet());
2654   }
2655 
2656   // Ping images into existing container (appending to container)
2657   template<class Container>
2658   void pingImages(Container *sequence_,const std::string &imageSpec_,
2659     ReadOptions &options)
2660   {
2661     options.ping(true);
2662     readImages(sequence_,imageSpec_,options);
2663   }
2664 
2665   template<class Container>
2666   void pingImages(Container *sequence_,const std::string &imageSpec_)
2667   {
2668     ReadOptions options;
2669     pingImages(sequence_,imageSpec_,options);
2670   }
2671 
2672   template<class Container>
2673   void pingImages(Container *sequence_,const Blob &blob_,ReadOptions &options)
2674   {
2675     options.ping(true);
2676     readImages(sequence_,blob_,options);
2677   }
2678 
2679   template<class Container>
2680   void pingImages(Container *sequence_,const Blob &blob_)
2681   {
2682     ReadOptions options;
2683     pingImages(sequence_,blob_,options);
2684   }
2685 
2686   // Adds the names of the profiles of the image to the container.
2687   template <class Container>
2688   void profileNames(Container *names_,const Image* image_)
2689   {
2690     const char*
2691       name;
2692 
2693     names_->clear();
2694 
2695     MagickCore::ResetImageProfileIterator(image_->constImage());
2696     name=MagickCore::GetNextImageProfile(image_->constImage());
2697     while (name != (const char *) NULL)
2698     {
2699       names_->push_back(std::string(name));
2700       name=MagickCore::GetNextImageProfile(image_->constImage());
2701     }
2702   }
2703 
2704   // Quantize colors in images using current quantization settings
2705   // Set measureError_ to true in order to measure quantization error
2706   template <class InputIterator>
2707   void quantizeImages(InputIterator first_,InputIterator last_,
2708     bool measureError_ = false)
2709   {
2710     if (linkImages(first_,last_) == false)
2711       return;
2712     GetPPException;
2713     MagickCore::QuantizeImages(first_->quantizeInfo(),first_->image(),
2714       exceptionInfo);
2715     unlinkImages(first_,last_);
2716 
2717     MagickCore::Image *image=first_->image();
2718     while (image != (MagickCore::Image *) NULL)
2719     {
2720       // Calculate quantization error
2721       if (measureError_)
2722         MagickCore::GetImageQuantizeError(image,exceptionInfo);
2723 
2724       // Update DirectClass representation of pixels
2725       MagickCore::SyncImage(image,exceptionInfo);
2726 
2727       image=image->next;
2728     }
2729     unlinkImages(first_,last_);
2730     ThrowPPException(first_->quiet());
2731   }
2732 
2733   // Read images into existing container (appending to container)
2734   template<class Container>
2735   void readImages(Container *sequence_,const std::string &imageSpec_,
2736     ReadOptions &options)
2737   {
2738     MagickCore::Image
2739       *images;
2740 
2741     MagickCore::ImageInfo
2742       *imageInfo;
2743 
2744     imageInfo=options.imageInfo();
2745     imageSpec_.copy(imageInfo->filename,MagickPathExtent-1);
2746     imageInfo->filename[imageSpec_.length()] = 0;
2747     GetPPException;
2748     images=MagickCore::ReadImage(imageInfo,exceptionInfo);
2749     insertImages(sequence_,images);
2750     ThrowPPException(options.quiet());
2751   }
2752 
2753   template<class Container>
2754   void readImages(Container *sequence_,const std::string &imageSpec_)
2755   {
2756     ReadOptions options;
2757     readImages(sequence_,imageSpec_,options);
2758   }
2759 
2760   template<class Container>
2761   void readImages(Container *sequence_,const Blob &blob_,ReadOptions &options)
2762   {
2763     MagickCore::Image
2764       *images;
2765 
2766     GetPPException;
2767     images=MagickCore::BlobToImage(options.imageInfo(),blob_.data(),
2768       blob_.length(),exceptionInfo);
2769     insertImages(sequence_,images);
2770     ThrowPPException(options.quiet());
2771   }
2772 
2773   template<class Container>
2774   void readImages(Container *sequence_,const Blob &blob_)
2775   {
2776     ReadOptions options;
2777     readImages(sequence_,blob_,options);
2778   }
2779 
2780   // Returns a separate grayscale image for each channel specified.
2781   template<class Container>
2782   void separateImages(Container *separatedImages_,Image &image_,
2783     const ChannelType channel_)
2784   {
2785     MagickCore::ChannelType
2786       channel_mask;
2787 
2788     MagickCore::Image
2789       *images;
2790 
2791     GetPPException;
2792     channel_mask=MagickCore::SetImageChannelMask(image_.image(),channel_);
2793     images=SeparateImages(image_.constImage(),exceptionInfo);
2794     MagickCore::SetPixelChannelMask(image_.image(),channel_mask);
2795 
2796     separatedImages_->clear();
2797     insertImages(separatedImages_,images);
2798 
2799     ThrowPPException(image_.quiet());
2800   }
2801 
2802   // Smush images from list into single image in either horizontal or
2803   // vertical direction.
2804   template<class InputIterator>
2805   void smushImages(Image *smushedImage_,InputIterator first_,
2806     InputIterator last_,const ssize_t offset_,bool stack_=false)
2807   {
2808     MagickCore::Image
2809       *newImage;
2810 
2811     if (linkImages(first_,last_) == false)
2812       return;
2813     GetPPException;
2814     newImage=MagickCore::SmushImages(first_->constImage(),
2815       (MagickBooleanType) stack_,offset_,exceptionInfo);
2816     unlinkImages(first_,last_);
2817     smushedImage_->replaceImage(newImage);
2818     ThrowPPException(smushedImage_->quiet());
2819   }
2820 
2821   // Write Images
2822   template <class InputIterator>
2823   void writeImages( InputIterator first_,
2824         InputIterator last_,
2825         const std::string &imageSpec_,
2826         bool adjoin_ = true ) {
2827 
2828     if (linkImages(first_,last_) == false)
2829       return;
2830 
2831     first_->adjoin( adjoin_ );
2832 
2833     GetPPException;
2834     ::ssize_t errorStat = MagickCore::WriteImages( first_->constImageInfo(),
2835                                             first_->image(),
2836                                             imageSpec_.c_str(),
2837                                             exceptionInfo );
2838     unlinkImages( first_, last_ );
2839 
2840     if ( errorStat != false )
2841       {
2842         (void) MagickCore::DestroyExceptionInfo( exceptionInfo );
2843         return;
2844       }
2845 
2846     ThrowPPException(first_->quiet());
2847   }
2848   // Write images to BLOB
2849   template <class InputIterator>
2850   void writeImages( InputIterator first_,
2851         InputIterator last_,
2852         Blob *blob_,
2853         bool adjoin_ = true) {
2854     if (linkImages(first_,last_) == false)
2855       return;
2856 
2857     first_->adjoin( adjoin_ );
2858 
2859     GetPPException;
2860     size_t length = 2048; // Efficient size for small images
2861     void* data = MagickCore::ImagesToBlob( first_->imageInfo(),
2862            first_->image(),
2863            &length,
2864            exceptionInfo);
2865     blob_->updateNoCopy( data, length, Magick::Blob::MallocAllocator );
2866 
2867     unlinkImages( first_, last_ );
2868 
2869     ThrowPPException(first_->quiet());
2870   }
2871 
2872 } // namespace Magick
2873 
2874 #endif // Magick_STL_header