Home | History | Annotate | Download | only in Magick++
      1 // This may look like C code, but it is really -*- C++ -*-
      2 //
      3 // Copyright Bob Friesenhahn, 1999, 2000, 2001, 2002, 2003
      4 // Copyright Dirk Lemstra 2013-2016
      5 //
      6 // Definition and implementation of template functions for using
      7 // Magick::Image with STL containers.
      8 //
      9 
     10 #ifndef Magick_STL_header
     11 #define Magick_STL_header
     12 
     13 #include "Magick++/Include.h"
     14 #include <algorithm>
     15 #include <functional>
     16 #include <iterator>
     17 #include <map>
     18 #include <utility>
     19 
     20 #include "Magick++/CoderInfo.h"
     21 #include "Magick++/Drawable.h"
     22 #include "Magick++/Exception.h"
     23 #include "Magick++/Montage.h"
     24 
     25 namespace Magick
     26 {
     27   //
     28   // STL function object declarations/definitions
     29   //
     30 
     31   // Function objects provide the means to invoke an operation on one
     32   // or more image objects in an STL-compatable container.  The
     33   // arguments to the function object constructor(s) are compatable
     34   // with the arguments to the equivalent Image class method and
     35   // provide the means to supply these options when the function
     36   // object is invoked.
     37 
     38   // For example, to read a GIF animation, set the color red to
     39   // transparent for all frames, and write back out:
     40   //
     41   // list<image> images;
     42   // readImages( &images, "animation.gif" );
     43   // for_each( images.begin(), images.end(), transparentImage( "red" ) );
     44   // writeImages( images.begin(), images.end(), "animation.gif" );
     45 
     46   // Adaptive-blur image with specified blur factor
     47   class MagickPPExport adaptiveBlurImage : public std::unary_function<Image&,void>
     48   {
     49   public:
     50     adaptiveBlurImage( const double radius_ = 1, const double sigma_ = 0.5 );
     51 
     52     void operator()( Image &image_ ) const;
     53 
     54   private:
     55     double _radius;
     56     double _sigma;
     57   };
     58 
     59   // Local adaptive threshold image
     60   // http://www.dai.ed.ac.uk/HIPR2/adpthrsh.htm
     61   // Width x height define the size of the pixel neighborhood
     62   // offset = constant to subtract from pixel neighborhood mean
     63   class MagickPPExport adaptiveThresholdImage : public std::unary_function<Image&,void>
     64   {
     65   public:
     66     adaptiveThresholdImage( const size_t width_,
     67                             const size_t height_,
     68                             const ::ssize_t offset_ = 0  );
     69 
     70     void operator()( Image &image_ ) const;
     71 
     72   private:
     73     size_t _width;
     74     size_t _height;
     75     ::ssize_t _offset;
     76   };
     77 
     78   // Add noise to image with specified noise type
     79   class MagickPPExport addNoiseImage : public std::unary_function<Image&,void>
     80   {
     81   public:
     82     addNoiseImage ( NoiseType noiseType_ );
     83 
     84     void operator()( Image &image_ ) const;
     85 
     86   private:
     87     NoiseType _noiseType;
     88   };
     89 
     90   // Transform image by specified affine (or free transform) matrix.
     91   class MagickPPExport affineTransformImage : public std::unary_function<Image&,void>
     92   {
     93   public:
     94     affineTransformImage( const DrawableAffine &affine_ );
     95 
     96     void operator()( Image &image_ ) const;
     97 
     98   private:
     99     DrawableAffine _affine;
    100   };
    101 
    102   // Annotate image (draw text on image)
    103   class MagickPPExport annotateImage : public std::unary_function<Image&,void>
    104   {
    105   public:
    106     // Annotate using specified text, and placement location
    107     annotateImage ( const std::string &text_,
    108                     const Geometry &geometry_ );
    109 
    110     // Annotate using specified text, bounding area, and placement
    111     // gravity
    112     annotateImage ( const std::string &text_,
    113         const Geometry &geometry_,
    114         const GravityType gravity_ );
    115 
    116     // Annotate with text using specified text, bounding area,
    117     // placement gravity, and rotation.
    118     annotateImage ( const std::string &text_,
    119                     const Geometry &geometry_,
    120                     const GravityType gravity_,
    121                     const double degrees_ );
    122 
    123     // Annotate with text (bounding area is entire image) and
    124     // placement gravity.
    125     annotateImage ( const std::string &text_,
    126         const GravityType gravity_ );
    127 
    128     void operator()( Image &image_ ) const;
    129 
    130   private:
    131     const std::string   _text;
    132     const Geometry      _geometry;
    133     const GravityType   _gravity;
    134     const double        _degrees;
    135   };
    136 
    137   // Blur image with specified blur factor
    138   class MagickPPExport blurImage : public std::unary_function<Image&,void>
    139   {
    140   public:
    141     blurImage( const double radius_ = 1, const double sigma_ = 0.5 );
    142 
    143     void operator()( Image &image_ ) const;
    144 
    145   private:
    146     double _radius;
    147     double _sigma;
    148   };
    149 
    150   // Border image (add border to image)
    151   class MagickPPExport borderImage : public std::unary_function<Image&,void>
    152   {
    153   public:
    154     borderImage( const Geometry &geometry_ = borderGeometryDefault  );
    155 
    156     void operator()( Image &image_ ) const;
    157 
    158   private:
    159     Geometry _geometry;
    160   };
    161 
    162   // Extract channel from image
    163   class MagickPPExport channelImage : public std::unary_function<Image&,void>
    164   {
    165   public:
    166     channelImage( const ChannelType channel_ );
    167 
    168     void operator()( Image &image_ ) const;
    169 
    170   private:
    171     ChannelType _channel;
    172   };
    173 
    174   // Charcoal effect image (looks like charcoal sketch)
    175   class MagickPPExport charcoalImage : public std::unary_function<Image&,void>
    176   {
    177   public:
    178     charcoalImage( const double radius_ = 1, const double sigma_ = 0.5  );
    179 
    180     void operator()( Image &image_ ) const;
    181 
    182   private:
    183     double _radius;
    184     double _sigma;
    185   };
    186 
    187   // Chop image (remove vertical or horizontal subregion of image)
    188   class MagickPPExport chopImage : public std::unary_function<Image&,void>
    189   {
    190   public:
    191     chopImage( const Geometry &geometry_ );
    192 
    193     void operator()( Image &image_ ) const;
    194 
    195   private:
    196     Geometry _geometry;
    197   };
    198 
    199   // Accepts a lightweight Color Correction Collection (CCC) file which solely
    200   // contains one or more color corrections and applies the correction to the
    201   // image.
    202   class MagickPPExport cdlImage : public std::unary_function<Image&,void>
    203   {
    204   public:
    205     cdlImage( const std::string &cdl_ );
    206 
    207     void operator()( Image &image_ ) const;
    208 
    209   private:
    210     std::string   _cdl;
    211   };
    212 
    213   // Colorize image using pen color at specified percent alpha
    214   class MagickPPExport colorizeImage : public std::unary_function<Image&,void>
    215   {
    216   public:
    217     colorizeImage( const unsigned int alphaRed_,
    218                    const unsigned int alphaGreen_,
    219                    const unsigned int alphaBlue_,
    220        const Color &penColor_ );
    221 
    222     colorizeImage( const unsigned int alpha_,
    223                    const Color &penColor_ );
    224 
    225     void operator()( Image &image_ ) const;
    226 
    227   private:
    228     unsigned int _alphaRed;
    229     unsigned int _alphaGreen;
    230     unsigned int _alphaBlue;
    231     Color _penColor;
    232   };
    233 
    234   // Apply a color matrix to the image channels.  The user supplied
    235   // matrix may be of order 1 to 5 (1x1 through 5x5).
    236   class MagickPPExport colorMatrixImage : public std::unary_function<Image&,void>
    237   {
    238   public:
    239     colorMatrixImage( const size_t order_,
    240           const double *color_matrix_ );
    241 
    242     void operator()( Image &image_ ) const;
    243 
    244   private:
    245     size_t  _order;
    246     const double *_color_matrix;
    247   };
    248 
    249   // Convert the image colorspace representation
    250   class MagickPPExport colorSpaceImage : public std::unary_function<Image&,void>
    251   {
    252   public:
    253     colorSpaceImage( ColorspaceType colorSpace_ );
    254 
    255     void operator()( Image &image_ ) const;
    256 
    257   private:
    258     ColorspaceType _colorSpace;
    259   };
    260 
    261   // Comment image (add comment string to image)
    262   class MagickPPExport commentImage : public std::unary_function<Image&,void>
    263   {
    264   public:
    265     commentImage( const std::string &comment_ );
    266 
    267     void operator()( Image &image_ ) const;
    268 
    269   private:
    270     std::string _comment;
    271   };
    272 
    273   // Compose an image onto another at specified offset and using
    274   // specified algorithm
    275   class MagickPPExport compositeImage : public std::unary_function<Image&,void>
    276   {
    277   public:
    278     compositeImage( const Image &compositeImage_,
    279         ::ssize_t xOffset_,
    280         ::ssize_t yOffset_,
    281         CompositeOperator compose_ = InCompositeOp );
    282 
    283     compositeImage( const Image &compositeImage_,
    284         const Geometry &offset_,
    285         CompositeOperator compose_ = InCompositeOp );
    286 
    287     void operator()( Image &image_ ) const;
    288 
    289   private:
    290     Image             _compositeImage;
    291     ::ssize_t         _xOffset;
    292     ::ssize_t         _yOffset;
    293     CompositeOperator _compose;
    294   };
    295 
    296   // Contrast image (enhance intensity differences in image)
    297   class MagickPPExport contrastImage : public std::unary_function<Image&,void>
    298   {
    299   public:
    300     contrastImage( const size_t sharpen_ );
    301 
    302     void operator()( Image &image_ ) const;
    303 
    304   private:
    305     size_t _sharpen;
    306   };
    307 
    308   // Crop image (subregion of original image)
    309   class MagickPPExport cropImage : public std::unary_function<Image&,void>
    310   {
    311   public:
    312     cropImage( const Geometry &geometry_ );
    313 
    314     void operator()( Image &image_ ) const;
    315 
    316   private:
    317     Geometry _geometry;
    318   };
    319 
    320   // Cycle image colormap
    321   class MagickPPExport cycleColormapImage : public std::unary_function<Image&,void>
    322   {
    323   public:
    324     cycleColormapImage( const ::ssize_t amount_ );
    325 
    326     void operator()( Image &image_ ) const;
    327 
    328   private:
    329     ::ssize_t _amount;
    330   };
    331 
    332   // Despeckle image (reduce speckle noise)
    333   class MagickPPExport despeckleImage : public std::unary_function<Image&,void>
    334   {
    335   public:
    336     despeckleImage( void );
    337 
    338     void operator()( Image &image_ ) const;
    339 
    340   private:
    341   };
    342 
    343   // Distort image.  distorts an image using various distortion methods, by
    344   // mapping color lookups of the source image to a new destination image
    345   // usally of the same size as the source image, unless 'bestfit' is set to
    346   // true.
    347   class MagickPPExport distortImage : public std::unary_function<Image&,void>
    348   {
    349   public:
    350     distortImage( const Magick::DistortMethod method_,
    351       const size_t number_arguments_,
    352       const double *arguments_,
    353       const bool bestfit_ );
    354 
    355     distortImage( const Magick::DistortMethod method_,
    356       const size_t number_arguments_,
    357       const double *arguments_ );
    358 
    359     void operator()( Image &image_ ) const;
    360 
    361   private:
    362     DistortMethod _method;
    363     size_t _number_arguments;
    364     const double *_arguments;
    365     bool _bestfit;
    366   };
    367 
    368   // Draw on image
    369   class MagickPPExport drawImage : public std::unary_function<Image&,void>
    370   {
    371   public:
    372     // Draw on image using a single drawable
    373     // Store in list to make implementation easier
    374     drawImage( const Drawable &drawable_ );
    375 
    376     // Draw on image using a drawable list
    377     drawImage( const DrawableList &drawable_ );
    378 
    379     void operator()( Image &image_ ) const;
    380 
    381   private:
    382     DrawableList _drawableList;
    383   };
    384 
    385   // Edge image (hilight edges in image)
    386   class MagickPPExport edgeImage : public std::unary_function<Image&,void>
    387   {
    388   public:
    389     edgeImage( const double radius_ = 0.0 );
    390 
    391     void operator()( Image &image_ ) const;
    392 
    393   private:
    394     double _radius;
    395   };
    396 
    397   // Emboss image (hilight edges with 3D effect)
    398   class MagickPPExport embossImage : public std::unary_function<Image&,void>
    399   {
    400   public:
    401     embossImage( void );
    402     embossImage( const double radius_, const double sigma_ );
    403 
    404     void operator()( Image &image_ ) const;
    405 
    406   private:
    407     double _radius;
    408     double _sigma;
    409   };
    410 
    411   // Enhance image (minimize noise)
    412   class MagickPPExport enhanceImage : public std::unary_function<Image&,void>
    413   {
    414   public:
    415     enhanceImage( void );
    416 
    417     void operator()( Image &image_ ) const;
    418 
    419   private:
    420   };
    421 
    422   // Equalize image (histogram equalization)
    423   class MagickPPExport equalizeImage : public std::unary_function<Image&,void>
    424   {
    425   public:
    426     equalizeImage( void );
    427 
    428     void operator()( Image &image_ ) const;
    429 
    430   private:
    431   };
    432 
    433   // Color to use when filling drawn objects
    434   class MagickPPExport fillColorImage : public std::unary_function<Image&,void>
    435   {
    436   public:
    437     fillColorImage( const Color &fillColor_ );
    438 
    439     void operator()( Image &image_ ) const;
    440 
    441   private:
    442     Color _fillColor;
    443   };
    444 
    445   // Flip image (reflect each scanline in the vertical direction)
    446   class MagickPPExport flipImage : public std::unary_function<Image&,void>
    447   {
    448   public:
    449     flipImage( void );
    450 
    451     void operator()( Image &image_ ) const;
    452 
    453   private:
    454   };
    455 
    456   // Floodfill designated area with a matte value
    457   class MagickPPExport floodFillAlphaImage
    458     : public std::unary_function<Image&,void>
    459   {
    460   public:
    461     floodFillAlphaImage(const ::ssize_t x_,const ::ssize_t y_,
    462      const unsigned int alpha_,const Color &target_,const bool invert_=false);
    463 
    464     void operator()(Image &image_) const;
    465 
    466   private:
    467     Color        _target;
    468     unsigned int _alpha;
    469     ::ssize_t    _x;
    470     ::ssize_t    _y;
    471     bool         _invert;
    472   };
    473 
    474   // Flood-fill image with color
    475   class MagickPPExport floodFillColorImage
    476     : public std::unary_function<Image&,void>
    477   {
    478   public:
    479     // Flood-fill color across pixels starting at target-pixel and
    480     // stopping at pixels matching specified border color.
    481     // Uses current fuzz setting when determining color match.
    482     floodFillColorImage(const Geometry &point_,const Color &fillColor_,
    483       const bool invert_=false);
    484     floodFillColorImage(const ::ssize_t x_,const ::ssize_t y_,
    485       const Color &fillColor_,const bool invert_=false);
    486 
    487     // Flood-fill color across pixels starting at target-pixel and
    488     // stopping at pixels matching specified border color.
    489     // Uses current fuzz setting when determining color match.
    490     floodFillColorImage(const Geometry &point_,const Color &fillColor_,
    491       const Color &borderColor_,const bool invert_=false);
    492     floodFillColorImage(const ::ssize_t x_,const ::ssize_t y_,
    493       const Color &fillColor_,const Color &borderColor_,
    494       const bool invert_=false);
    495 
    496     void operator()(Image &image_) const;
    497 
    498   private:
    499     ::ssize_t _x;
    500     ::ssize_t _y;
    501     Color     _fillColor;
    502     Color     _borderColor;
    503     bool      _invert;
    504   };
    505 
    506   // Flood-fill image with texture
    507   class MagickPPExport floodFillTextureImage
    508     : public std::unary_function<Image&,void>
    509   {
    510   public:
    511     // Flood-fill texture across pixels that match the color of the
    512     // target pixel and are neighbors of the target pixel.
    513     // Uses current fuzz setting when determining color match.
    514     floodFillTextureImage(const ::ssize_t x_,const ::ssize_t y_,
    515       const Image &texture_,const bool invert_=false);
    516     floodFillTextureImage(const Geometry &point_,const Image &texture_,
    517       const bool invert_=false);
    518 
    519     // Flood-fill texture across pixels starting at target-pixel and
    520     // stopping at pixels matching specified border color.
    521     // Uses current fuzz setting when determining color match.
    522     floodFillTextureImage(const ::ssize_t x_,const ::ssize_t y_,
    523       const Image &texture_,const Color &borderColor_,
    524       const bool invert_=false);
    525 
    526     floodFillTextureImage(const Geometry &point_,const Image &texture_,
    527       const Color &borderColor_,const bool invert_=false);
    528 
    529     void operator()(Image &image_) const;
    530 
    531   private:
    532     ::ssize_t _x;
    533     ::ssize_t _y;
    534     Image     _texture;
    535     Color     _borderColor;
    536     bool      _invert;
    537   };
    538 
    539   // Flop image (reflect each scanline in the horizontal direction)
    540   class MagickPPExport flopImage : public std::unary_function<Image&,void>
    541   {
    542   public:
    543     flopImage( void );
    544 
    545     void operator()( Image &image_ ) const;
    546 
    547   private:
    548   };
    549 
    550   // Frame image
    551   class MagickPPExport frameImage : public std::unary_function<Image&,void>
    552   {
    553   public:
    554     frameImage( const Geometry &geometry_ = frameGeometryDefault );
    555 
    556     frameImage( const size_t width_, const size_t height_,
    557     const ::ssize_t innerBevel_ = 6, const ::ssize_t outerBevel_ = 6 );
    558 
    559     void operator()( Image &image_ ) const;
    560 
    561   private:
    562     size_t _width;
    563     size_t _height;
    564     ::ssize_t        _outerBevel;
    565     ::ssize_t        _innerBevel;
    566   };
    567 
    568   // Gamma correct image
    569   class MagickPPExport gammaImage : public std::unary_function<Image&,void>
    570   {
    571   public:
    572     gammaImage( const double gamma_ );
    573 
    574     gammaImage ( const double gammaRed_,
    575      const double gammaGreen_,
    576      const double gammaBlue_ );
    577 
    578     void operator()( Image &image_ ) const;
    579 
    580   private:
    581     double _gammaRed;
    582     double _gammaGreen;
    583     double _gammaBlue;
    584   };
    585 
    586   // Gaussian blur image
    587   // The number of neighbor pixels to be included in the convolution
    588   // mask is specified by 'width_'. The standard deviation of the
    589   // gaussian bell curve is specified by 'sigma_'.
    590   class MagickPPExport gaussianBlurImage : public std::unary_function<Image&,void>
    591   {
    592   public:
    593     gaussianBlurImage( const double width_, const double sigma_ );
    594 
    595     void operator()( Image &image_ ) const;
    596 
    597   private:
    598     double _width;
    599     double _sigma;
    600   };
    601 
    602   // Apply a color lookup table (Hald CLUT) to the image.
    603   class MagickPPExport haldClutImage : public std::unary_function<Image&,void>
    604   {
    605   public:
    606     haldClutImage( const Image &haldClutImage_ );
    607 
    608     void operator()( Image &image_ ) const;
    609 
    610   private:
    611     Image             _haldClutImage;
    612   };
    613 
    614   // Implode image (special effect)
    615   class MagickPPExport implodeImage : public std::unary_function<Image&,void>
    616   {
    617   public:
    618     implodeImage( const double factor_ = 50 );
    619 
    620     void operator()( Image &image_ ) const;
    621 
    622   private:
    623     double _factor;
    624   };
    625 
    626   // implements the inverse discrete Fourier transform (IFT) of the image
    627   // either as a magnitude / phase or real / imaginary image pair.
    628   class MagickPPExport inverseFourierTransformImage : public std::unary_function<Image&,void>
    629   {
    630   public:
    631     inverseFourierTransformImage( const Image &phaseImage_ );
    632 
    633     void operator()( Image &image_ ) const;
    634 
    635   private:
    636     Image _phaseImage;
    637   };
    638 
    639   // Set image validity. Valid images become empty (inValid) if
    640   // argument is false.
    641   class MagickPPExport isValidImage : public std::unary_function<Image&,void>
    642   {
    643   public:
    644     isValidImage( const bool isValid_ );
    645 
    646     void operator()( Image &image_ ) const;
    647 
    648   private:
    649     bool _isValid;
    650   };
    651 
    652   // Label image
    653   class MagickPPExport labelImage : public std::unary_function<Image&,void>
    654   {
    655   public:
    656     labelImage( const std::string &label_ );
    657 
    658     void operator()( Image &image_ ) const;
    659 
    660   private:
    661     std::string _label;
    662   };
    663 
    664 
    665   // Level image
    666   class MagickPPExport levelImage : public std::unary_function<Image&,void>
    667   {
    668   public:
    669     levelImage( const double black_point,
    670                 const double white_point,
    671                 const double mid_point=1.0 );
    672 
    673     void operator()( Image &image_ ) const;
    674 
    675   private:
    676     double _black_point;
    677     double _white_point;
    678     double _mid_point;
    679   };
    680 
    681   // Magnify image by integral size
    682   class MagickPPExport magnifyImage : public std::unary_function<Image&,void>
    683   {
    684   public:
    685     magnifyImage( void );
    686 
    687     void operator()( Image &image_ ) const;
    688 
    689   private:
    690   };
    691 
    692   // Remap image colors with closest color from reference image
    693   class MagickPPExport mapImage : public std::unary_function<Image&,void>
    694   {
    695   public:
    696     mapImage( const Image &mapImage_ ,
    697               const bool dither_ = false );
    698 
    699     void operator()( Image &image_ ) const;
    700 
    701   private:
    702     Image   _mapImage;
    703     bool    _dither;
    704   };
    705 
    706   // Filter image by replacing each pixel component with the median
    707   // color in a circular neighborhood
    708   class MagickPPExport medianConvolveImage : public std::unary_function<Image&,void>
    709   {
    710   public:
    711     medianConvolveImage( const double radius_ = 0.0 );
    712 
    713     void operator()( Image &image_ ) const;
    714 
    715   private:
    716     double _radius;
    717   };
    718 
    719   // Merge image layers
    720   class MagickPPExport mergeLayersImage : public
    721     std::unary_function<Image&,void>
    722   {
    723   public:
    724     mergeLayersImage ( LayerMethod layerMethod_ );
    725 
    726     void operator()( Image &image_ ) const;
    727 
    728   private:
    729     LayerMethod _layerMethod;
    730   };
    731 
    732   // Reduce image by integral size
    733   class MagickPPExport minifyImage : public std::unary_function<Image&,void>
    734   {
    735   public:
    736     minifyImage( void );
    737 
    738     void operator()( Image &image_ ) const;
    739 
    740   private:
    741   };
    742 
    743   // Modulate percent hue, saturation, and brightness of an image
    744   class MagickPPExport modulateImage : public std::unary_function<Image&,void>
    745   {
    746   public:
    747     modulateImage( const double brightness_,
    748        const double saturation_,
    749        const double hue_ );
    750 
    751     void operator()( Image &image_ ) const;
    752 
    753   private:
    754     double _brightness;
    755     double _saturation;
    756     double _hue;
    757   };
    758 
    759   // Negate colors in image.  Set grayscale to only negate grayscale
    760   // values in image.
    761   class MagickPPExport negateImage : public std::unary_function<Image&,void>
    762   {
    763   public:
    764     negateImage( const bool grayscale_ = false );
    765 
    766     void operator()( Image &image_ ) const;
    767 
    768   private:
    769     bool _grayscale;
    770   };
    771 
    772   // Normalize image (increase contrast by normalizing the pixel
    773   // values to span the full range of color values)
    774   class MagickPPExport normalizeImage : public std::unary_function<Image&,void>
    775   {
    776   public:
    777     normalizeImage( void );
    778 
    779     void operator()( Image &image_ ) const;
    780 
    781   private:
    782   };
    783 
    784   // Oilpaint image (image looks like oil painting)
    785   class MagickPPExport oilPaintImage : public std::unary_function<Image&,void>
    786   {
    787   public:
    788     oilPaintImage( const double radius_ = 3 );
    789 
    790     void operator()( Image &image_ ) const;
    791 
    792   private:
    793     double _radius;
    794   };
    795 
    796   // Set or attenuate the image alpha channel. If the image pixels
    797   // are opaque then they are set to the specified alpha value,
    798   // otherwise they are blended with the supplied alpha value.  The
    799   // value of alpha_ ranges from 0 (completely opaque) to
    800   // QuantumRange. The defines OpaqueAlpha and TransparentAlpha are
    801   // available to specify completely opaque or completely transparent,
    802   // respectively.
    803   class MagickPPExport alphaImage : public std::unary_function<Image&,void>
    804   {
    805   public:
    806     alphaImage( const unsigned int alpha_ );
    807 
    808     void operator()( Image &image_ ) const;
    809 
    810   private:
    811     unsigned int _alpha;
    812   };
    813 
    814   // Change color of opaque pixel to specified pen color.
    815   class MagickPPExport opaqueImage : public std::unary_function<Image&,void>
    816   {
    817   public:
    818     opaqueImage( const Color &opaqueColor_,
    819      const Color &penColor_ );
    820 
    821     void operator()( Image &image_ ) const;
    822 
    823   private:
    824     Color  _opaqueColor;
    825     Color  _penColor;
    826   };
    827 
    828   // Quantize image (reduce number of colors)
    829   class MagickPPExport quantizeImage : public std::unary_function<Image&,void>
    830   {
    831   public:
    832     quantizeImage( const bool measureError_ = false );
    833 
    834     void operator()( Image &image_ ) const;
    835 
    836   private:
    837     bool _measureError;
    838   };
    839 
    840   // Raise image (lighten or darken the edges of an image to give a
    841   // 3-D raised or lowered effect)
    842   class MagickPPExport raiseImage : public std::unary_function<Image&,void>
    843   {
    844   public:
    845     raiseImage( const Geometry &geometry_ = raiseGeometryDefault,
    846     const bool raisedFlag_ = false );
    847 
    848     void operator()( Image &image_ ) const;
    849 
    850   private:
    851     Geometry   _geometry;
    852     bool       _raisedFlag;
    853   };
    854 
    855   class MagickPPExport ReadOptions
    856   {
    857   public:
    858 
    859     // Default constructor
    860     ReadOptions(void);
    861 
    862     // Copy constructor
    863     ReadOptions(const ReadOptions& options_);
    864 
    865     // Destructor
    866     ~ReadOptions();
    867 
    868     // Vertical and horizontal resolution in pixels of the image
    869     void density(const Geometry &geomery_);
    870     Geometry density(void) const;
    871 
    872     // Image depth (8 or 16)
    873     void depth(size_t depth_);
    874     size_t depth(void) const;
    875 
    876     // Suppress all warning messages. Error messages are still reported.
    877     void quiet(const bool quiet_);
    878     bool quiet(void) const;
    879 
    880     // Image size (required for raw formats)
    881     void size(const Geometry &geometry_);
    882     Geometry size(void) const;
    883 
    884     //
    885     // Internal implementation methods.  Please do not use.
    886     //
    887 
    888     MagickCore::ImageInfo *imageInfo(void);
    889 
    890   private:
    891 
    892     // Assignment not supported
    893     ReadOptions& operator=(const ReadOptions&);
    894 
    895     MagickCore::ImageInfo *_imageInfo;
    896     bool                  _quiet;
    897   };
    898 
    899   // Reduce noise in image using a noise peak elimination filter
    900   class MagickPPExport reduceNoiseImage : public std::unary_function<Image&,void>
    901   {
    902   public:
    903     reduceNoiseImage( void );
    904 
    905     reduceNoiseImage (const  size_t order_ );
    906 
    907     void operator()( Image &image_ ) const;
    908 
    909   private:
    910     size_t _order;
    911   };
    912 
    913   // Resize image to specified size.
    914   class MagickPPExport resizeImage : public std::unary_function<Image&,void>
    915   {
    916   public:
    917     resizeImage( const Geometry &geometry_ );
    918 
    919     void operator()( Image &image_ ) const;
    920 
    921   private:
    922     Geometry _geometry;
    923   };
    924 
    925   // Roll image (rolls image vertically and horizontally) by specified
    926   // number of columnms and rows)
    927   class MagickPPExport rollImage : public std::unary_function<Image&,void>
    928   {
    929   public:
    930     rollImage( const Geometry &roll_ );
    931 
    932     rollImage( const ::ssize_t columns_, const ::ssize_t rows_ );
    933 
    934     void operator()( Image &image_ ) const;
    935 
    936   private:
    937     size_t _columns;
    938     size_t _rows;
    939   };
    940 
    941   // Rotate image counter-clockwise by specified number of degrees.
    942   class MagickPPExport rotateImage : public std::unary_function<Image&,void>
    943   {
    944   public:
    945     rotateImage( const double degrees_ );
    946 
    947     void operator()( Image &image_ ) const;
    948 
    949   private:
    950     double       _degrees;
    951   };
    952 
    953   // Resize image by using pixel sampling algorithm
    954   class MagickPPExport sampleImage : public std::unary_function<Image&,void>
    955   {
    956   public:
    957     sampleImage( const Geometry &geometry_ );
    958 
    959     void operator()( Image &image_ ) const;
    960 
    961   private:
    962     Geometry  _geometry;
    963   };
    964 
    965   // Resize image by using simple ratio algorithm
    966   class MagickPPExport scaleImage : public std::unary_function<Image&,void>
    967   {
    968   public:
    969     scaleImage( const Geometry &geometry_ );
    970 
    971     void operator()( Image &image_ ) const;
    972 
    973   private:
    974     Geometry  _geometry;
    975   };
    976 
    977   // Segment (coalesce similar image components) by analyzing the
    978   // histograms of the color components and identifying units that are
    979   // homogeneous with the fuzzy c-means technique.
    980   // Also uses QuantizeColorSpace and Verbose image attributes
    981   class MagickPPExport segmentImage : public std::unary_function<Image&,void>
    982   {
    983   public:
    984     segmentImage( const double clusterThreshold_ = 1.0,
    985       const double smoothingThreshold_ = 1.5 );
    986 
    987     void operator()( Image &image_ ) const;
    988 
    989   private:
    990     double  _clusterThreshold;
    991     double  _smoothingThreshold;
    992   };
    993 
    994   // Shade image using distant light source
    995   class MagickPPExport shadeImage : public std::unary_function<Image&,void>
    996   {
    997   public:
    998     shadeImage( const double azimuth_ = 30,
    999     const double elevation_ = 30,
   1000     const bool   colorShading_ = false );
   1001 
   1002     void operator()( Image &image_ ) const;
   1003 
   1004   private:
   1005     double  _azimuth;
   1006     double  _elevation;
   1007     bool    _colorShading;
   1008   };
   1009 
   1010   // Shadow effect image (simulate an image shadow)
   1011   class MagickPPExport shadowImage : public std::unary_function<Image&,void>
   1012   {
   1013   public:
   1014     shadowImage( const double percent_opacity_ = 80, const double sigma_ = 0.5,
   1015       const ssize_t x_ = 5, const ssize_t y_ = 5 );
   1016 
   1017     void operator()( Image &image_ ) const;
   1018 
   1019   private:
   1020     double _percent_opacity;
   1021     double _sigma;
   1022     ssize_t _x;
   1023     ssize_t _y;
   1024   };
   1025 
   1026   // Sharpen pixels in image
   1027   class MagickPPExport sharpenImage : public std::unary_function<Image&,void>
   1028   {
   1029   public:
   1030     sharpenImage( const double radius_ = 1, const double sigma_ = 0.5 );
   1031 
   1032     void operator()( Image &image_ ) const;
   1033 
   1034   private:
   1035     double _radius;
   1036     double _sigma;
   1037   };
   1038 
   1039   // Shave pixels from image edges.
   1040   class MagickPPExport shaveImage : public std::unary_function<Image&,void>
   1041   {
   1042   public:
   1043     shaveImage( const Geometry &geometry_ );
   1044 
   1045     void operator()( Image &image_ ) const;
   1046 
   1047   private:
   1048     Geometry _geometry;
   1049   };
   1050 
   1051 
   1052   // Shear image (create parallelogram by sliding image by X or Y axis)
   1053   class MagickPPExport shearImage : public std::unary_function<Image&,void>
   1054   {
   1055   public:
   1056     shearImage( const double xShearAngle_,
   1057     const double yShearAngle_ );
   1058 
   1059     void operator()( Image &image_ ) const;
   1060 
   1061   private:
   1062     double _xShearAngle;
   1063     double _yShearAngle;
   1064   };
   1065 
   1066   // Solarize image (similar to effect seen when exposing a
   1067   // photographic film to light during the development process)
   1068   class MagickPPExport solarizeImage : public std::unary_function<Image&,void>
   1069   {
   1070   public:
   1071     solarizeImage( const double factor_ );
   1072 
   1073     void operator()( Image &image_ ) const;
   1074 
   1075   private:
   1076     double _factor;
   1077   };
   1078 
   1079   // Splice the background color into the image.
   1080   class MagickPPExport spliceImage : public std::unary_function<Image&,void>
   1081   {
   1082   public:
   1083     spliceImage( const Geometry &geometry_ );
   1084 
   1085     void operator()( Image &image_ ) const;
   1086 
   1087   private:
   1088     Geometry _geometry;
   1089   };
   1090 
   1091   // Spread pixels randomly within image by specified ammount
   1092   class MagickPPExport spreadImage : public std::unary_function<Image&,void>
   1093   {
   1094   public:
   1095     spreadImage( const size_t amount_ = 3 );
   1096 
   1097     void operator()( Image &image_ ) const;
   1098 
   1099   private:
   1100     size_t _amount;
   1101   };
   1102 
   1103   // Add a digital watermark to the image (based on second image)
   1104   class MagickPPExport steganoImage : public std::unary_function<Image&,void>
   1105   {
   1106   public:
   1107     steganoImage( const Image &waterMark_ );
   1108 
   1109     void operator()( Image &image_ ) const;
   1110 
   1111   private:
   1112     Image _waterMark;
   1113   };
   1114 
   1115   // Create an image which appears in stereo when viewed with red-blue glasses
   1116   // (Red image on left, blue on right)
   1117   class MagickPPExport stereoImage : public std::unary_function<Image&,void>
   1118   {
   1119   public:
   1120     stereoImage( const Image &rightImage_ );
   1121 
   1122     void operator()( Image &image_ ) const;
   1123 
   1124   private:
   1125     Image _rightImage;
   1126   };
   1127 
   1128   // Color to use when drawing object outlines
   1129   class MagickPPExport strokeColorImage : public std::unary_function<Image&,void>
   1130   {
   1131   public:
   1132     strokeColorImage( const Color &strokeColor_ );
   1133 
   1134     void operator()( Image &image_ ) const;
   1135 
   1136   private:
   1137     Color _strokeColor;
   1138   };
   1139 
   1140   // Swirl image (image pixels are rotated by degrees)
   1141   class MagickPPExport swirlImage : public std::unary_function<Image&,void>
   1142   {
   1143   public:
   1144     swirlImage( const double degrees_ );
   1145 
   1146     void operator()( Image &image_ ) const;
   1147 
   1148   private:
   1149     double _degrees;
   1150   };
   1151 
   1152   // Channel a texture on image background
   1153   class MagickPPExport textureImage : public std::unary_function<Image&,void>
   1154   {
   1155   public:
   1156     textureImage( const Image &texture_ );
   1157 
   1158     void operator()( Image &image_ ) const;
   1159 
   1160   private:
   1161     Image _texture;
   1162   };
   1163 
   1164   // Threshold image
   1165   class MagickPPExport thresholdImage : public std::unary_function<Image&,void>
   1166   {
   1167   public:
   1168     thresholdImage( const double threshold_ );
   1169 
   1170     void operator()( Image &image_ ) const;
   1171 
   1172   private:
   1173     double _threshold;
   1174   };
   1175 
   1176   // Set image color to transparent
   1177   class MagickPPExport transparentImage : public std::unary_function<Image&,void>
   1178   {
   1179   public:
   1180     transparentImage( const Color& color_ );
   1181 
   1182     void operator()( Image &image_ ) const;
   1183 
   1184   private:
   1185     Color _color;
   1186   };
   1187 
   1188   // Trim edges that are the background color from the image
   1189   class MagickPPExport trimImage : public std::unary_function<Image&,void>
   1190   {
   1191   public:
   1192     trimImage( void );
   1193 
   1194     void operator()( Image &image_ ) const;
   1195 
   1196   private:
   1197   };
   1198 
   1199   // Map image pixels to a sine wave
   1200   class MagickPPExport waveImage : public std::unary_function<Image&,void>
   1201   {
   1202   public:
   1203     waveImage( const double amplitude_ = 25.0,
   1204          const double wavelength_ = 150.0 );
   1205 
   1206     void operator()( Image &image_ ) const;
   1207 
   1208   private:
   1209     double _amplitude;
   1210     double _wavelength;
   1211   };
   1212 
   1213   // Zoom image to specified size.
   1214   class MagickPPExport zoomImage : public std::unary_function<Image&,void>
   1215   {
   1216   public:
   1217     zoomImage( const Geometry &geometry_ );
   1218 
   1219     void operator()( Image &image_ ) const;
   1220 
   1221   private:
   1222     Geometry _geometry;
   1223   };
   1224 
   1225   //
   1226   // Function object image attribute accessors
   1227   //
   1228 
   1229   // Join images into a single multi-image file
   1230   class MagickPPExport adjoinImage : public std::unary_function<Image&,void>
   1231   {
   1232   public:
   1233     adjoinImage( const bool flag_ );
   1234 
   1235     void operator()( Image &image_ ) const;
   1236 
   1237   private:
   1238     bool _flag;
   1239   };
   1240 
   1241   // Time in 1/100ths of a second which must expire before displaying
   1242   // the next image in an animated sequence.
   1243   class MagickPPExport animationDelayImage : public std::unary_function<Image&,void>
   1244   {
   1245   public:
   1246     animationDelayImage( const size_t delay_ );
   1247 
   1248     void operator()( Image &image_ ) const;
   1249 
   1250   private:
   1251     size_t _delay;
   1252   };
   1253 
   1254   // Number of iterations to loop an animation (e.g. Netscape loop
   1255   // extension) for.
   1256   class MagickPPExport animationIterationsImage : public std::unary_function<Image&,void>
   1257   {
   1258   public:
   1259     animationIterationsImage( const size_t iterations_ );
   1260 
   1261     void operator()( Image &image_ ) const;
   1262 
   1263   private:
   1264     size_t _iterations;
   1265   };
   1266 
   1267   // Image background color
   1268   class MagickPPExport backgroundColorImage : public std::unary_function<Image&,void>
   1269   {
   1270   public:
   1271     backgroundColorImage( const Color &color_ );
   1272 
   1273     void operator()( Image &image_ ) const;
   1274 
   1275   private:
   1276     Color _color;
   1277   };
   1278 
   1279   // Name of texture image to tile onto the image background
   1280   class MagickPPExport backgroundTextureImage : public std::unary_function<Image&,void>
   1281   {
   1282   public:
   1283     backgroundTextureImage( const std::string &backgroundTexture_ );
   1284 
   1285     void operator()( Image &image_ ) const;
   1286 
   1287   private:
   1288     std::string _backgroundTexture;
   1289   };
   1290 
   1291   // Image border color
   1292   class MagickPPExport borderColorImage : public std::unary_function<Image&,void>
   1293   {
   1294   public:
   1295     borderColorImage( const Color &color_ );
   1296 
   1297     void operator()( Image &image_ ) const;
   1298 
   1299   private:
   1300     Color _color;
   1301   };
   1302 
   1303   // Text bounding-box base color (default none)
   1304   class MagickPPExport boxColorImage : public std::unary_function<Image&,void>
   1305   {
   1306   public:
   1307     boxColorImage( const Color &boxColor_ );
   1308 
   1309     void operator()( Image &image_ ) const;
   1310 
   1311   private:
   1312     Color _boxColor;
   1313   };
   1314 
   1315   // Chromaticity blue primary point.
   1316   class MagickPPExport chromaBluePrimaryImage : public std::unary_function<Image&,void>
   1317   {
   1318   public:
   1319     chromaBluePrimaryImage(const double x_,const double y_,const double z_);
   1320 
   1321     void operator()(Image &image_) const;
   1322 
   1323   private:
   1324     double _x;
   1325     double _y;
   1326     double _z;
   1327   };
   1328 
   1329   // Chromaticity green primary point.
   1330   class MagickPPExport chromaGreenPrimaryImage : public std::unary_function<Image&,void>
   1331   {
   1332   public:
   1333     chromaGreenPrimaryImage(const double x_,const double y_,const double z_);
   1334 
   1335     void operator()(Image &image_) const;
   1336 
   1337   private:
   1338     double _x;
   1339     double _y;
   1340     double _z;
   1341   };
   1342 
   1343   // Chromaticity red primary point.
   1344   class MagickPPExport chromaRedPrimaryImage : public std::unary_function<Image&,void>
   1345   {
   1346   public:
   1347     chromaRedPrimaryImage(const double x_,const double y_,const double z_);
   1348 
   1349     void operator()(Image &image_) const;
   1350 
   1351   private:
   1352     double _x;
   1353     double _y;
   1354     double _z;
   1355   };
   1356 
   1357   // Chromaticity white point.
   1358   class MagickPPExport chromaWhitePointImage : public std::unary_function<Image&,void>
   1359   {
   1360   public:
   1361     chromaWhitePointImage(const double x_,const double y_,const double z_);
   1362 
   1363     void operator()(Image &image_) const;
   1364 
   1365   private:
   1366     double _x;
   1367     double _y;
   1368     double _z;
   1369   };
   1370 
   1371   // Colors within this distance are considered equal
   1372   class MagickPPExport colorFuzzImage : public std::unary_function<Image&,void>
   1373   {
   1374   public:
   1375     colorFuzzImage( const double fuzz_ );
   1376 
   1377     void operator()( Image &image_ ) const;
   1378 
   1379   private:
   1380     double _fuzz;
   1381   };
   1382 
   1383   // Color at colormap position index_
   1384   class MagickPPExport colorMapImage : public std::unary_function<Image&,void>
   1385   {
   1386   public:
   1387     colorMapImage( const size_t index_, const Color &color_ );
   1388 
   1389     void operator()( Image &image_ ) const;
   1390 
   1391   private:
   1392     size_t _index;
   1393     Color        _color;
   1394   };
   1395 
   1396   // Composition operator to be used when composition is implicitly used
   1397   // (such as for image flattening).
   1398   class MagickPPExport composeImage : public std::unary_function<Image&,void>
   1399   {
   1400   public:
   1401     composeImage( const CompositeOperator compose_ );
   1402 
   1403     void operator()( Image &image_ ) const;
   1404 
   1405   private:
   1406     CompositeOperator _compose;
   1407   };
   1408 
   1409   // Compression type
   1410   class MagickPPExport compressTypeImage : public std::unary_function<Image&,void>
   1411   {
   1412   public:
   1413     compressTypeImage( const CompressionType compressType_ );
   1414 
   1415     void operator()( Image &image_ ) const;
   1416 
   1417   private:
   1418     CompressionType _compressType;
   1419   };
   1420 
   1421   // Vertical and horizontal resolution in pixels of the image
   1422   class MagickPPExport densityImage : public std::unary_function<Image&,void>
   1423   {
   1424   public:
   1425     densityImage( const Point &point_ );
   1426 
   1427     void operator()( Image &image_ ) const;
   1428 
   1429   private:
   1430     Point _point;
   1431   };
   1432 
   1433   // Image depth (bits allocated to red/green/blue components)
   1434   class MagickPPExport depthImage : public std::unary_function<Image&,void>
   1435   {
   1436   public:
   1437     depthImage( const size_t depth_ );
   1438 
   1439     void operator()( Image &image_ ) const;
   1440 
   1441   private:
   1442     size_t _depth;
   1443   };
   1444 
   1445   // Endianness (LSBEndian like Intel or MSBEndian like SPARC) for image
   1446   // formats which support endian-specific options.
   1447   class MagickPPExport endianImage : public std::unary_function<Image&,void>
   1448   {
   1449   public:
   1450     endianImage( const EndianType endian_ );
   1451 
   1452     void operator()( Image &image_ ) const;
   1453 
   1454   private:
   1455     EndianType  _endian;
   1456   };
   1457 
   1458   // Image file name
   1459   class MagickPPExport fileNameImage : public std::unary_function<Image&,void>
   1460   {
   1461   public:
   1462     fileNameImage( const std::string &fileName_ );
   1463 
   1464     void operator()( Image &image_ ) const;
   1465 
   1466   private:
   1467     std::string _fileName;
   1468   };
   1469 
   1470   // Filter to use when resizing image
   1471   class MagickPPExport filterTypeImage : public std::unary_function<Image&,void>
   1472   {
   1473   public:
   1474     filterTypeImage( const FilterType filterType_ );
   1475 
   1476     void operator()( Image &image_ ) const;
   1477 
   1478   private:
   1479     FilterType _filterType;
   1480   };
   1481 
   1482   // Text rendering font
   1483   class MagickPPExport fontImage : public std::unary_function<Image&,void>
   1484   {
   1485   public:
   1486     fontImage( const std::string &font_ );
   1487 
   1488     void operator()( Image &image_ ) const;
   1489 
   1490   private:
   1491     std::string _font;
   1492   };
   1493 
   1494   // Font point size
   1495   class MagickPPExport fontPointsizeImage : public std::unary_function<Image&,void>
   1496   {
   1497   public:
   1498     fontPointsizeImage( const size_t pointsize_ );
   1499 
   1500     void operator()( Image &image_ ) const;
   1501 
   1502   private:
   1503     size_t _pointsize;
   1504   };
   1505 
   1506   // GIF disposal method
   1507   class MagickPPExport gifDisposeMethodImage : public std::unary_function<Image&,void>
   1508   {
   1509   public:
   1510     gifDisposeMethodImage( const DisposeType disposeMethod_ );
   1511 
   1512     void operator()( Image &image_ ) const;
   1513 
   1514   private:
   1515     DisposeType _disposeMethod;
   1516   };
   1517 
   1518   // Type of interlacing to use
   1519   class MagickPPExport interlaceTypeImage : public std::unary_function<Image&,void>
   1520   {
   1521   public:
   1522     interlaceTypeImage( const InterlaceType interlace_ );
   1523 
   1524     void operator()( Image &image_ ) const;
   1525 
   1526   private:
   1527     InterlaceType _interlace;
   1528   };
   1529 
   1530   // File type magick identifier (.e.g "GIF")
   1531   class MagickPPExport magickImage : public std::unary_function<Image&,void>
   1532   {
   1533   public:
   1534     magickImage( const std::string &magick_ );
   1535 
   1536     void operator()( Image &image_ ) const;
   1537 
   1538   private:
   1539     std::string _magick;
   1540   };
   1541 
   1542   // Image supports transparent color
   1543   class MagickPPExport alphaFlagImage : public std::unary_function<Image&,void>
   1544   {
   1545   public:
   1546     alphaFlagImage( const bool alphaFlag_ );
   1547 
   1548     void operator()( Image &image_ ) const;
   1549 
   1550   private:
   1551     bool _alphaFlag;
   1552   };
   1553 
   1554   // Transparent color
   1555   class MagickPPExport alphaColorImage : public std::unary_function<Image&,void>
   1556   {
   1557   public:
   1558     alphaColorImage( const Color &alphaColor_ );
   1559 
   1560     void operator()( Image &image_ ) const;
   1561 
   1562   private:
   1563     Color _alphaColor;
   1564   };
   1565 
   1566   // Indicate that image is black and white
   1567   class MagickPPExport monochromeImage : public std::unary_function<Image&,void>
   1568   {
   1569   public:
   1570     monochromeImage( const bool monochromeFlag_ );
   1571 
   1572     void operator()( Image &image_ ) const;
   1573 
   1574   private:
   1575     bool _monochromeFlag;
   1576   };
   1577 
   1578   // Pen color
   1579   class MagickPPExport penColorImage : public std::unary_function<Image&,void>
   1580   {
   1581   public:
   1582     penColorImage( const Color &penColor_ );
   1583 
   1584     void operator()( Image &image_ ) const;
   1585 
   1586   private:
   1587     Color _penColor;
   1588   };
   1589 
   1590   // Pen texture image.
   1591   class MagickPPExport penTextureImage : public std::unary_function<Image&,void>
   1592   {
   1593   public:
   1594     penTextureImage( const Image &penTexture_ );
   1595 
   1596     void operator()( Image &image_ ) const;
   1597 
   1598   private:
   1599     Image _penTexture;
   1600   };
   1601 
   1602   // Set pixel color at location x & y.
   1603   class MagickPPExport pixelColorImage : public std::unary_function<Image&,void>
   1604   {
   1605   public:
   1606     pixelColorImage( const ::ssize_t x_,
   1607                      const ::ssize_t y_,
   1608          const Color &color_);
   1609 
   1610     void operator()( Image &image_ ) const;
   1611 
   1612   private:
   1613     ::ssize_t    _x;
   1614     ::ssize_t    _y;
   1615     Color        _color;
   1616   };
   1617 
   1618   // Postscript page size.
   1619   class MagickPPExport pageImage : public std::unary_function<Image&,void>
   1620   {
   1621   public:
   1622     pageImage( const Geometry &pageSize_ );
   1623 
   1624     void operator()( Image &image_ ) const;
   1625 
   1626   private:
   1627     Geometry _pageSize;
   1628   };
   1629 
   1630   // JPEG/MIFF/PNG compression level (default 75).
   1631   class MagickPPExport qualityImage : public std::unary_function<Image&,void>
   1632   {
   1633   public:
   1634     qualityImage( const size_t quality_ );
   1635 
   1636     void operator()( Image &image_ ) const;
   1637 
   1638   private:
   1639     size_t _quality;
   1640   };
   1641 
   1642   // Maximum number of colors to quantize to
   1643   class MagickPPExport quantizeColorsImage : public std::unary_function<Image&,void>
   1644   {
   1645   public:
   1646     quantizeColorsImage( const size_t colors_ );
   1647 
   1648     void operator()( Image &image_ ) const;
   1649 
   1650   private:
   1651     size_t _colors;
   1652   };
   1653 
   1654   // Colorspace to quantize in.
   1655   class MagickPPExport quantizeColorSpaceImage : public std::unary_function<Image&,void>
   1656   {
   1657   public:
   1658     quantizeColorSpaceImage( const ColorspaceType colorSpace_ );
   1659 
   1660     void operator()( Image &image_ ) const;
   1661 
   1662   private:
   1663     ColorspaceType _colorSpace;
   1664   };
   1665 
   1666   // Dither image during quantization (default true).
   1667   class MagickPPExport quantizeDitherImage : public std::unary_function<Image&,void>
   1668   {
   1669   public:
   1670     quantizeDitherImage( const bool ditherFlag_ );
   1671 
   1672     void operator()( Image &image_ ) const;
   1673 
   1674   private:
   1675     bool _ditherFlag;
   1676   };
   1677 
   1678   // Quantization tree-depth
   1679   class MagickPPExport quantizeTreeDepthImage : public std::unary_function<Image&,void>
   1680   {
   1681   public:
   1682     quantizeTreeDepthImage( const size_t treeDepth_ );
   1683 
   1684     void operator()( Image &image_ ) const;
   1685 
   1686   private:
   1687     size_t _treeDepth;
   1688   };
   1689 
   1690   // The type of rendering intent
   1691   class MagickPPExport renderingIntentImage : public std::unary_function<Image&,void>
   1692   {
   1693   public:
   1694     renderingIntentImage( const RenderingIntent renderingIntent_ );
   1695 
   1696     void operator()( Image &image_ ) const;
   1697 
   1698   private:
   1699     RenderingIntent _renderingIntent;
   1700   };
   1701 
   1702   // Units of image resolution
   1703   class MagickPPExport resolutionUnitsImage : public std::unary_function<Image&,void>
   1704   {
   1705   public:
   1706     resolutionUnitsImage( const ResolutionType resolutionUnits_ );
   1707 
   1708     void operator()( Image &image_ ) const;
   1709 
   1710   private:
   1711     ResolutionType _resolutionUnits;
   1712   };
   1713 
   1714   // Image scene number
   1715   class MagickPPExport sceneImage : public std::unary_function<Image&,void>
   1716   {
   1717   public:
   1718     sceneImage( const size_t scene_ );
   1719 
   1720     void operator()( Image &image_ ) const;
   1721 
   1722   private:
   1723     size_t _scene;
   1724   };
   1725 
   1726   // adjust the image contrast with a non-linear sigmoidal contrast algorithm
   1727   class MagickPPExport sigmoidalContrastImage : public std::unary_function<Image&,void>
   1728   {
   1729   public:
   1730     sigmoidalContrastImage( const size_t sharpen_,
   1731       const double contrast,
   1732       const double midpoint = QuantumRange / 2.0 );
   1733 
   1734     void operator()( Image &image_ ) const;
   1735 
   1736   private:
   1737     size_t _sharpen;
   1738     double contrast;
   1739     double midpoint;
   1740   };
   1741 
   1742   // Width and height of a raw image
   1743   class MagickPPExport sizeImage : public std::unary_function<Image&,void>
   1744   {
   1745   public:
   1746     sizeImage( const Geometry &geometry_ );
   1747 
   1748     void operator()( Image &image_ ) const;
   1749 
   1750   private:
   1751     Geometry _geometry;
   1752   };
   1753 
   1754   // stripImage strips an image of all profiles and comments.
   1755   class MagickPPExport stripImage : public std::unary_function<Image&,void>
   1756   {
   1757   public:
   1758     stripImage( void );
   1759 
   1760     void operator()( Image &image_ ) const;
   1761 
   1762   private:
   1763   };
   1764 
   1765   // Subimage of an image sequence
   1766   class MagickPPExport subImageImage : public std::unary_function<Image&,void>
   1767   {
   1768   public:
   1769     subImageImage( const size_t subImage_ );
   1770 
   1771     void operator()( Image &image_ ) const;
   1772 
   1773   private:
   1774     size_t _subImage;
   1775   };
   1776 
   1777   // Number of images relative to the base image
   1778   class MagickPPExport subRangeImage : public std::unary_function<Image&,void>
   1779   {
   1780   public:
   1781     subRangeImage( const size_t subRange_ );
   1782 
   1783     void operator()( Image &image_ ) const;
   1784 
   1785   private:
   1786     size_t _subRange;
   1787   };
   1788 
   1789   // Anti-alias Postscript and TrueType fonts (default true)
   1790   class MagickPPExport textAntiAliasImage : public std::unary_function<Image&,void>
   1791   {
   1792   public:
   1793     textAntiAliasImage( const bool flag_ );
   1794 
   1795     void operator()( Image &image_ ) const;
   1796 
   1797   private:
   1798     bool _flag;
   1799   };
   1800 
   1801   // Image storage type
   1802   class MagickPPExport typeImage : public std::unary_function<Image&,void>
   1803   {
   1804   public:
   1805     typeImage( const ImageType type_ );
   1806 
   1807     void operator()( Image &image_ ) const;
   1808 
   1809   private:
   1810     Magick::ImageType _type;
   1811   };
   1812 
   1813 
   1814   // Print detailed information about the image
   1815   class MagickPPExport verboseImage : public std::unary_function<Image&,void>
   1816   {
   1817   public:
   1818     verboseImage( const bool verbose_ );
   1819 
   1820     void operator()( Image &image_ ) const;
   1821 
   1822   private:
   1823     bool _verbose;
   1824   };
   1825 
   1826   // X11 display to display to, obtain fonts from, or to capture
   1827   // image from
   1828   class MagickPPExport x11DisplayImage : public std::unary_function<Image&,void>
   1829   {
   1830   public:
   1831     x11DisplayImage( const std::string &display_ );
   1832 
   1833     void operator()( Image &image_ ) const;
   1834 
   1835   private:
   1836     std::string _display;
   1837   };
   1838 
   1839   //////////////////////////////////////////////////////////
   1840   //
   1841   // Implementation template definitions. Not for end-use.
   1842   //
   1843   //////////////////////////////////////////////////////////
   1844 
   1845   // Changes the channel mask of the images and places the old
   1846   // values in the container.
   1847   template<class InputIterator, class Container>
   1848   void channelMaskImages(InputIterator first_,InputIterator last_,
   1849     Container *container_,const ChannelType channel_)
   1850   {
   1851     MagickCore::ChannelType
   1852       channel_mask;
   1853 
   1854     container_->clear();
   1855     for (InputIterator iter = first_; iter != last_; ++iter)
   1856     {
   1857       iter->modifyImage();
   1858       channel_mask=MagickCore::SetImageChannelMask(iter->image(),channel_);
   1859       container_->push_back(channel_mask);
   1860     }
   1861   }
   1862 
   1863   // Insert images in image list into existing container (appending to container)
   1864   // The images should not be deleted since only the image ownership is passed.
   1865   // The options are copied into the object.
   1866   template<class Container>
   1867   void insertImages(Container *sequence_,MagickCore::Image* images_)
   1868   {
   1869     MagickCore::Image
   1870       *image,
   1871       *next;
   1872 
   1873     image=images_;
   1874     while (image != (MagickCore::Image *) NULL)
   1875     {
   1876       next=image->next;
   1877       image->next=(MagickCore::Image *) NULL;
   1878 
   1879       if (next != (MagickCore::Image *) NULL)
   1880         next->previous=(MagickCore::Image *) NULL;
   1881 
   1882       sequence_->push_back(Magick::Image(image));
   1883 
   1884       image=next;
   1885     }
   1886   }
   1887 
   1888   // Link images together into an image list based on the ordering of
   1889   // the container implied by the iterator. This step is done in
   1890   // preparation for use with ImageMagick functions which operate on
   1891   // lists of images.
   1892   // Images are selected by range, first_ to last_ so that a subset of
   1893   // the container may be selected.  Specify first_ via the
   1894   // container's begin() method and last_ via the container's end()
   1895   // method in order to specify the entire container.
   1896   template<class InputIterator>
   1897   bool linkImages(InputIterator first_,InputIterator last_)
   1898   {
   1899     MagickCore::Image
   1900       *current,
   1901       *previous;
   1902 
   1903     ::ssize_t
   1904       scene;
   1905 
   1906     scene=0;
   1907     previous=(MagickCore::Image *) NULL;
   1908     for (InputIterator iter = first_; iter != last_; ++iter)
   1909     {
   1910       // Unless we reduce the reference count to one, the same image
   1911       // structure may occur more than once in the container, causing
   1912       // the linked list to fail.
   1913       iter->modifyImage();
   1914 
   1915       current=iter->image();
   1916 
   1917       current->previous=previous;
   1918       current->next=(MagickCore::Image *) NULL;
   1919       current->scene=scene++;
   1920 
   1921       if (previous != (MagickCore::Image *) NULL)
   1922         previous->next=current;
   1923 
   1924       previous=current;
   1925     }
   1926     return(scene > 0 ? true : false);
   1927   }
   1928 
   1929   // Restores the channel mask of the images.
   1930   template<class InputIterator, class Container>
   1931   void restoreChannelMaskImages(InputIterator first_,InputIterator last_,
   1932     Container *container_)
   1933   {
   1934     typename Container::iterator
   1935       channel_mask;
   1936 
   1937     channel_mask=container_->begin();
   1938     for (InputIterator iter = first_; iter != last_; ++iter)
   1939     {
   1940       iter->modifyImage();
   1941       (void) MagickCore::SetImageChannelMask(iter->image(),
   1942         (const MagickCore::ChannelType) *channel_mask);
   1943       channel_mask++;
   1944     }
   1945   }
   1946 
   1947   // Remove links added by linkImages. This should be called after the
   1948   // ImageMagick function call has completed to reset the image list
   1949   // back to its pristine un-linked state.
   1950   template<class InputIterator>
   1951   void unlinkImages(InputIterator first_,InputIterator last_)
   1952   {
   1953     MagickCore::Image
   1954       *image;
   1955 
   1956     for (InputIterator iter = first_; iter != last_; ++iter)
   1957     {
   1958       image=iter->image();
   1959       image->previous=(MagickCore::Image *) NULL;
   1960       image->next=(MagickCore::Image *) NULL;
   1961     }
   1962   }
   1963 
   1964   ///////////////////////////////////////////////////////////////////
   1965   //
   1966   // Template definitions for documented API
   1967   //
   1968   ///////////////////////////////////////////////////////////////////
   1969 
   1970   template <class InputIterator>
   1971   void animateImages( InputIterator first_,InputIterator last_)
   1972   {
   1973     if (linkImages(first_,last_) == false)
   1974       return;
   1975     GetPPException;
   1976     MagickCore::AnimateImages(first_->imageInfo(),first_->image(),
   1977       exceptionInfo);
   1978     unlinkImages(first_,last_);
   1979     ThrowPPException(first_->quiet());
   1980   }
   1981 
   1982   // Append images from list into single image in either horizontal or
   1983   // vertical direction.
   1984   template <class InputIterator>
   1985   void appendImages( Image *appendedImage_,
   1986          InputIterator first_,
   1987          InputIterator last_,
   1988          bool stack_ = false) {
   1989     if (linkImages(first_,last_) == false)
   1990       return;
   1991     GetPPException;
   1992     MagickCore::Image* image = MagickCore::AppendImages( first_->image(),
   1993                    (MagickBooleanType) stack_,
   1994                    exceptionInfo );
   1995     unlinkImages( first_, last_ );
   1996     appendedImage_->replaceImage( image );
   1997     ThrowPPException(appendedImage_->quiet());
   1998   }
   1999 
   2000   // Adds the names of the artifacts of the image to the container.
   2001   template <class Container>
   2002   void artifactNames(Container *names_,const Image* image_)
   2003   {
   2004     const char*
   2005       name;
   2006 
   2007     names_->clear();
   2008 
   2009     MagickCore::ResetImageArtifactIterator(image_->constImage());
   2010     name=MagickCore::GetNextImageArtifact(image_->constImage());
   2011     while (name != (const char *) NULL)
   2012     {
   2013       names_->push_back(std::string(name));
   2014       name=MagickCore::GetNextImageArtifact(image_->constImage());
   2015     }
   2016   }
   2017 
   2018   // Adds the names of the attributes of the image to the container.
   2019   template <class Container>
   2020   void attributeNames(Container *names_,const Image* image_)
   2021   {
   2022     const char*
   2023       name;
   2024 
   2025     names_->clear();
   2026 
   2027     MagickCore::ResetImagePropertyIterator(image_->constImage());
   2028     name=MagickCore::GetNextImageProperty(image_->constImage());
   2029     while (name != (const char *) NULL)
   2030     {
   2031       names_->push_back(std::string(name));
   2032       name=MagickCore::GetNextImageProperty(image_->constImage());
   2033     }
   2034   }
   2035 
   2036   // Average a set of images.
   2037   // All the input images must be the same size in pixels.
   2038   template <class InputIterator>
   2039   void averageImages( Image *averagedImage_,
   2040           InputIterator first_,
   2041           InputIterator last_ ) {
   2042     if (linkImages(first_,last_) == false)
   2043       return;
   2044     GetPPException;
   2045     MagickCore::Image* image = MagickCore::EvaluateImages( first_->image(),
   2046       MagickCore::MeanEvaluateOperator, exceptionInfo );
   2047     unlinkImages( first_, last_ );
   2048     averagedImage_->replaceImage( image );
   2049     ThrowPPException(averagedImage_->quiet());
   2050   }
   2051 
   2052   // Merge a sequence of images.
   2053   // This is useful for GIF animation sequences that have page
   2054   // offsets and disposal methods. A container to contain
   2055   // the updated image sequence is passed via the coalescedImages_
   2056   // option.
   2057   template <class InputIterator, class Container >
   2058   void coalesceImages( Container *coalescedImages_,
   2059                        InputIterator first_,
   2060                        InputIterator last_ ) {
   2061     if (linkImages(first_,last_) == false)
   2062       return;
   2063     GetPPException;
   2064     MagickCore::Image* images = MagickCore::CoalesceImages( first_->image(),
   2065                                                           exceptionInfo);
   2066     // Unlink image list
   2067     unlinkImages( first_, last_ );
   2068 
   2069     // Ensure container is empty
   2070     coalescedImages_->clear();
   2071 
   2072     // Move images to container
   2073     insertImages( coalescedImages_, images );
   2074 
   2075     // Report any error
   2076     ThrowPPException(first_->quiet());
   2077   }
   2078 
   2079   // Return format coders matching specified conditions.
   2080   //
   2081   // The default (if no match terms are supplied) is to return all
   2082   // available format coders.
   2083   //
   2084   // For example, to return all readable formats:
   2085   //  list<CoderInfo> coderList;
   2086   //  coderInfoList( &coderList, CoderInfo::TrueMatch, CoderInfo::AnyMatch, CoderInfo::AnyMatch)
   2087   //
   2088   template <class Container >
   2089   void coderInfoList( Container *container_,
   2090                       CoderInfo::MatchType isReadable_ = CoderInfo::AnyMatch,
   2091                       CoderInfo::MatchType isWritable_ = CoderInfo::AnyMatch,
   2092                       CoderInfo::MatchType isMultiFrame_ = CoderInfo::AnyMatch
   2093                       ) {
   2094     // Obtain first entry in MagickInfo list
   2095     size_t number_formats;
   2096     GetPPException;
   2097     char **coder_list =
   2098       MagickCore::GetMagickList( "*", &number_formats, exceptionInfo );
   2099     if( !coder_list )
   2100       {
   2101         throwException(exceptionInfo);
   2102         throwExceptionExplicit(MagickCore::MissingDelegateError,
   2103                              "Coder array not returned!", 0 );
   2104       }
   2105 
   2106     // Clear out container
   2107     container_->clear();
   2108 
   2109     for ( ::ssize_t i=0; i < (::ssize_t) number_formats; i++)
   2110       {
   2111         const MagickCore::MagickInfo *magick_info =
   2112           MagickCore::GetMagickInfo( coder_list[i], exceptionInfo );
   2113         coder_list[i]=(char *)
   2114           MagickCore::RelinquishMagickMemory( coder_list[i] );
   2115 
   2116         // Skip stealth coders
   2117         if ( MagickCore::GetMagickStealth(magick_info) )
   2118           continue;
   2119 
   2120         try {
   2121           CoderInfo coderInfo( magick_info->name );
   2122 
   2123           // Test isReadable_
   2124           if ( isReadable_ != CoderInfo::AnyMatch &&
   2125                (( coderInfo.isReadable() && isReadable_ != CoderInfo::TrueMatch ) ||
   2126                 ( !coderInfo.isReadable() && isReadable_ != CoderInfo::FalseMatch )) )
   2127             continue;
   2128 
   2129           // Test isWritable_
   2130           if ( isWritable_ != CoderInfo::AnyMatch &&
   2131                (( coderInfo.isWritable() && isWritable_ != CoderInfo::TrueMatch ) ||
   2132                 ( !coderInfo.isWritable() && isWritable_ != CoderInfo::FalseMatch )) )
   2133             continue;
   2134 
   2135           // Test isMultiFrame_
   2136           if ( isMultiFrame_ != CoderInfo::AnyMatch &&
   2137                (( coderInfo.isMultiFrame() && isMultiFrame_ != CoderInfo::TrueMatch ) ||
   2138                 ( !coderInfo.isMultiFrame() && isMultiFrame_ != CoderInfo::FalseMatch )) )
   2139             continue;
   2140 
   2141           // Append matches to container
   2142           container_->push_back( coderInfo );
   2143         }
   2144         // Intentionally ignore missing module errors
   2145         catch ( Magick::ErrorModule )
   2146           {
   2147             continue;
   2148           }
   2149       }
   2150     coder_list=(char **) MagickCore::RelinquishMagickMemory( coder_list );
   2151     ThrowPPException(false);
   2152   }
   2153 
   2154   //
   2155   // Fill container with color histogram.
   2156   // Entries are of type "std::pair<Color,size_t>".  Use the pair
   2157   // "first" member to access the Color and the "second" member to access
   2158   // the number of times the color occurs in the image.
   2159   //
   2160   // For example:
   2161   //
   2162   //  Using <map>:
   2163   //
   2164   //  Image image("image.miff");
   2165   //  map<Color,size_t> histogram;
   2166   //  colorHistogram( &histogram, image );
   2167   //  std::map<Color,size_t>::const_iterator p=histogram.begin();
   2168   //  while (p != histogram.end())
   2169   //    {
   2170   //      cout << setw(10) << (int)p->second << ": ("
   2171   //           << setw(quantum_width) << (int)p->first.redQuantum() << ","
   2172   //           << setw(quantum_width) << (int)p->first.greenQuantum() << ","
   2173   //           << setw(quantum_width) << (int)p->first.blueQuantum() << ")"
   2174   //           << endl;
   2175   //      p++;
   2176   //    }
   2177   //
   2178   //  Using <vector>:
   2179   //
   2180   //  Image image("image.miff");
   2181   //  std::vector<std::pair<Color,size_t> > histogram;
   2182   //  colorHistogram( &histogram, image );
   2183   //  std::vector<std::pair<Color,size_t> >::const_iterator p=histogram.begin();
   2184   //  while (p != histogram.end())
   2185   //    {
   2186   //      cout << setw(10) << (int)p->second << ": ("
   2187   //           << setw(quantum_width) << (int)p->first.redQuantum() << ","
   2188   //           << setw(quantum_width) << (int)p->first.greenQuantum() << ","
   2189   //           << setw(quantum_width) << (int)p->first.blueQuantum() << ")"
   2190   //           << endl;
   2191   //      p++;
   2192   //    }
   2193 
   2194   template <class Container >
   2195   void colorHistogram( Container *histogram_, const Image image)
   2196   {
   2197     GetPPException;
   2198 
   2199     // Obtain histogram array
   2200     size_t colors;
   2201     MagickCore::PixelInfo *histogram_array =
   2202       MagickCore::GetImageHistogram( image.constImage(), &colors, exceptionInfo );
   2203     ThrowPPException(image.quiet());
   2204 
   2205     // Clear out container
   2206     histogram_->clear();
   2207 
   2208     // Transfer histogram array to container
   2209     for ( size_t i=0; i < colors; i++)
   2210       {
   2211         histogram_->insert( histogram_->end(), std::pair<const Color,size_t>
   2212           ( Color(histogram_array[i]), (size_t) histogram_array[i].count) );
   2213       }
   2214 
   2215     // Deallocate histogram array
   2216     histogram_array=(MagickCore::PixelInfo *)
   2217       MagickCore::RelinquishMagickMemory(histogram_array);
   2218   }
   2219 
   2220   // Combines one or more images into a single image. The grayscale value of
   2221   // the pixels of each image in the sequence is assigned in order to the
   2222   // specified channels of the combined image. The typical ordering would be
   2223   // image 1 => Red, 2 => Green, 3 => Blue, etc.
   2224   template<class InputIterator >
   2225   void combineImages(Image *combinedImage_,InputIterator first_,
   2226     InputIterator last_,const ChannelType channel_,
   2227     const ColorspaceType colorspace_)
   2228   {
   2229     MagickCore::Image
   2230       *image;
   2231 
   2232     std::vector<ChannelType>
   2233       channelMask;
   2234 
   2235     if (linkImages(first_,last_) == false)
   2236       return;
   2237     GetPPException;
   2238     channelMaskImages(first_,last_,&channelMask,channel_);
   2239     image=CombineImages(first_->image(),colorspace_,exceptionInfo);
   2240     restoreChannelMaskImages(first_,last_,&channelMask);
   2241     unlinkImages(first_,last_);
   2242     combinedImage_->replaceImage(image);
   2243     ThrowPPException(combinedImage_->quiet());
   2244   }
   2245 
   2246   template <class Container>
   2247   void cropToTiles(Container *tiledImages_,const Image image_,
   2248     const Geometry &geometry_)
   2249   {
   2250     GetPPException;
   2251     MagickCore::Image* images=CropImageToTiles(image_.constImage(),
   2252       static_cast<std::string>(geometry_).c_str(),exceptionInfo);
   2253     tiledImages_->clear();
   2254     insertImages(tiledImages_,images);
   2255     ThrowPPException(image_.quiet());
   2256   }
   2257 
   2258   // Break down an image sequence into constituent parts.  This is
   2259   // useful for creating GIF or MNG animation sequences.
   2260   template<class InputIterator,class Container>
   2261   void deconstructImages(Container *deconstructedImages_,
   2262     InputIterator first_,InputIterator last_)
   2263   {
   2264     MagickCore::Image
   2265       *images;
   2266 
   2267     if (linkImages(first_,last_) == false)
   2268       return;
   2269     GetPPException;
   2270     images=CompareImagesLayers(first_->image(),CompareAnyLayer,exceptionInfo);
   2271     unlinkImages(first_,last_);
   2272 
   2273     deconstructedImages_->clear();
   2274     insertImages(deconstructedImages_,images);
   2275 
   2276     ThrowPPException(first_->quiet());
   2277   }
   2278 
   2279   //
   2280   // Display an image sequence
   2281   //
   2282   template <class InputIterator>
   2283   void displayImages(InputIterator first_,InputIterator last_)
   2284   {
   2285     if (linkImages(first_,last_) == false)
   2286       return;
   2287     GetPPException;
   2288     MagickCore::DisplayImages(first_->imageInfo(),first_->image(),
   2289       exceptionInfo);
   2290     unlinkImages(first_,last_);
   2291     ThrowPPException(first_->quiet());
   2292   }
   2293 
   2294   // Applies a value to the image with an arithmetic, relational,
   2295   // or logical operator to an image. Use these operations to lighten or darken
   2296   // an image, to increase or decrease contrast in an image, or to produce the
   2297   // "negative" of an image.
   2298   template <class InputIterator >
   2299   void evaluateImages( Image *evaluatedImage_,
   2300                        InputIterator first_,
   2301                        InputIterator last_,
   2302                        const MagickEvaluateOperator operator_ ) {
   2303     if (linkImages(first_,last_) == false)
   2304       return;
   2305     GetPPException;
   2306     MagickCore::Image* image = EvaluateImages( first_->image(), operator_, exceptionInfo );
   2307     unlinkImages( first_, last_ );
   2308     evaluatedImage_->replaceImage( image );
   2309     ThrowPPException(evaluatedImage_->quiet());
   2310   }
   2311 
   2312   // Merge a sequence of image frames which represent image layers.
   2313   // This is useful for combining Photoshop layers into a single image.
   2314   template <class InputIterator>
   2315   void flattenImages( Image *flattendImage_,
   2316           InputIterator first_,
   2317           InputIterator last_ ) {
   2318     if (linkImages(first_,last_) == false)
   2319       return;
   2320     GetPPException;
   2321     MagickCore::Image* image = MagickCore::MergeImageLayers( first_->image(),
   2322       FlattenLayer,exceptionInfo );
   2323     unlinkImages( first_, last_ );
   2324     flattendImage_->replaceImage( image );
   2325     ThrowPPException(flattendImage_->quiet());
   2326   }
   2327 
   2328   // Implements the discrete Fourier transform (DFT) of the image either as a
   2329   // magnitude / phase or real / imaginary image pair.
   2330   template <class Container >
   2331   void forwardFourierTransformImage( Container *fourierImages_,
   2332     const Image &image_ ) {
   2333     GetPPException;
   2334 
   2335     // Build image list
   2336     MagickCore::Image* images = ForwardFourierTransformImage(
   2337       image_.constImage(), MagickTrue, exceptionInfo);
   2338 
   2339     // Ensure container is empty
   2340     fourierImages_->clear();
   2341 
   2342     // Move images to container
   2343     insertImages( fourierImages_, images );
   2344 
   2345     // Report any error
   2346     ThrowPPException(image_.quiet());
   2347   }
   2348   template <class Container >
   2349   void forwardFourierTransformImage( Container *fourierImages_,
   2350     const Image &image_, const bool magnitude_ ) {
   2351     GetPPException;
   2352 
   2353     // Build image list
   2354     MagickCore::Image* images = ForwardFourierTransformImage(
   2355       image_.constImage(), magnitude_ == true ? MagickTrue : MagickFalse,
   2356       exceptionInfo);
   2357 
   2358     // Ensure container is empty
   2359     fourierImages_->clear();
   2360 
   2361     // Move images to container
   2362     insertImages( fourierImages_, images );
   2363 
   2364     // Report any error
   2365     ThrowPPException(image_.quiet());
   2366   }
   2367 
   2368   // Applies a mathematical expression to a sequence of images.
   2369   template <class InputIterator>
   2370   void fxImages(Image *fxImage_,InputIterator first_,InputIterator last_,
   2371     const std::string expression)
   2372   {
   2373     MagickCore::Image
   2374       *image;
   2375 
   2376     if (linkImages(first_,last_) == false)
   2377       return;
   2378     GetPPException;
   2379     image=FxImage(first_->constImage(),expression.c_str(),exceptionInfo);
   2380     unlinkImages(first_,last_);
   2381     fxImage_->replaceImage(image);
   2382     ThrowPPException(fxImage_->quiet());
   2383   }
   2384 
   2385   // Replace the colors of a sequence of images with the closest color
   2386   // from a reference image.
   2387   // Set dither_ to true to enable dithering.  Set measureError_ to
   2388   // true in order to evaluate quantization error.
   2389   template<class InputIterator>
   2390   void mapImages(InputIterator first_,InputIterator last_,
   2391     const Image& mapImage_,bool dither_=false,bool measureError_=false)
   2392   {
   2393     MagickCore::Image
   2394       *image;
   2395 
   2396     MagickCore::QuantizeInfo
   2397       quantizeInfo;
   2398 
   2399     if (linkImages(first_,last_) == false)
   2400       return;
   2401     GetPPException;
   2402     MagickCore::GetQuantizeInfo(&quantizeInfo);
   2403     quantizeInfo.dither_method = dither_ ? MagickCore::RiemersmaDitherMethod :
   2404       MagickCore::NoDitherMethod;
   2405     MagickCore::RemapImages(&quantizeInfo,first_->image(),
   2406       (mapImage_.isValid() ? mapImage_.constImage() :
   2407       (const MagickCore::Image*) NULL),exceptionInfo);
   2408     unlinkImages(first_,last_);
   2409     if (exceptionInfo->severity != MagickCore::UndefinedException)
   2410       {
   2411         unlinkImages(first_,last_);
   2412         throwException(exceptionInfo,mapImage_.quiet());
   2413       }
   2414 
   2415     image=first_->image();
   2416     while(image != (MagickCore::Image *) NULL)
   2417       {
   2418         // Calculate quantization error
   2419         if (measureError_)
   2420           {
   2421             MagickCore::GetImageQuantizeError(image,exceptionInfo);
   2422             if (exceptionInfo->severity > MagickCore::UndefinedException)
   2423               {
   2424                 unlinkImages(first_,last_);
   2425                 throwException(exceptionInfo,mapImage_.quiet());
   2426               }
   2427           }
   2428 
   2429         // Update DirectClass representation of pixels
   2430         MagickCore::SyncImage(image,exceptionInfo);
   2431         if (exceptionInfo->severity > MagickCore::UndefinedException)
   2432           {
   2433             unlinkImages(first_,last_);
   2434             throwException(exceptionInfo,mapImage_.quiet());
   2435           }
   2436 
   2437         // Next image
   2438         image=image->next;
   2439       }
   2440 
   2441     unlinkImages(first_,last_);
   2442     (void) MagickCore::DestroyExceptionInfo(exceptionInfo);
   2443   }
   2444 
   2445   // Composes all the image layers from the current given
   2446   // image onward to produce a single image of the merged layers.
   2447   template <class InputIterator >
   2448   void mergeImageLayers( Image *mergedImage_,
   2449                          InputIterator first_,
   2450                          InputIterator last_,
   2451                          const LayerMethod method_ ) {
   2452     if (linkImages(first_,last_) == false)
   2453       return;
   2454     GetPPException;
   2455     MagickCore::Image* image = MergeImageLayers( first_->image(), method_, exceptionInfo );
   2456     unlinkImages( first_, last_ );
   2457     mergedImage_->replaceImage( image );
   2458     ThrowPPException(mergedImage_->quiet());
   2459   }
   2460 
   2461   // Create a composite image by combining several separate images.
   2462   template <class Container, class InputIterator>
   2463   void montageImages(Container *montageImages_,InputIterator first_,
   2464     InputIterator last_,const Montage &options_)
   2465   {
   2466     MagickCore::Image
   2467       *images;
   2468 
   2469     MagickCore::MontageInfo
   2470       *montageInfo;
   2471 
   2472     if (linkImages(first_,last_) == false)
   2473       return;
   2474 
   2475     montageInfo=static_cast<MagickCore::MontageInfo*>(
   2476       MagickCore::AcquireMagickMemory(sizeof(MagickCore::MontageInfo)));
   2477 
   2478     // Update montage options with those set in montageOpts_
   2479     options_.updateMontageInfo(*montageInfo);
   2480 
   2481     // Update options which must transfer to image options
   2482     if (options_.label().length() != 0)
   2483       first_->label(options_.label());
   2484 
   2485     // Do montage
   2486     GetPPException;
   2487     images=MagickCore::MontageImages(first_->image(),montageInfo,
   2488       exceptionInfo);
   2489 
   2490     // Unlink linked image list
   2491     unlinkImages(first_,last_);
   2492 
   2493     // Reset output container to pristine state
   2494     montageImages_->clear();
   2495 
   2496     if (images != (MagickCore::Image *) NULL)
   2497       insertImages(montageImages_,images);
   2498 
   2499     // Clean up any allocated data in montageInfo
   2500     MagickCore::DestroyMontageInfo(montageInfo);
   2501 
   2502     // Report any montage error
   2503     ThrowPPException(first_->quiet());
   2504 
   2505     // Apply transparency to montage images
   2506     if (montageImages_->size() > 0 && options_.transparentColor().isValid())
   2507       for_each(montageImages_->begin(),montageImages_->end(),transparentImage(
   2508         options_.transparentColor()));
   2509   }
   2510 
   2511   // Morph a set of images
   2512   template <class InputIterator, class Container >
   2513   void morphImages( Container *morphedImages_,
   2514         InputIterator first_,
   2515         InputIterator last_,
   2516         size_t frames_ ) {
   2517     if (linkImages(first_,last_) == false)
   2518       return;
   2519     GetPPException;
   2520 
   2521     MagickCore::Image* images = MagickCore::MorphImages( first_->image(), frames_,
   2522                    exceptionInfo);
   2523     // Unlink image list
   2524     unlinkImages( first_, last_ );
   2525 
   2526     // Ensure container is empty
   2527     morphedImages_->clear();
   2528 
   2529     // Move images to container
   2530     insertImages( morphedImages_, images );
   2531 
   2532     // Report any error
   2533     ThrowPPException(first_->quiet());
   2534   }
   2535 
   2536   // Inlay a number of images to form a single coherent picture.
   2537   template <class InputIterator>
   2538   void mosaicImages( Image *mosaicImage_,
   2539          InputIterator first_,
   2540          InputIterator last_ ) {
   2541     if (linkImages(first_,last_) == false)
   2542       return;
   2543     GetPPException;
   2544     MagickCore::Image* image = MagickCore::MergeImageLayers( first_->image(),
   2545        MosaicLayer,exceptionInfo );
   2546     unlinkImages( first_, last_ );
   2547     mosaicImage_->replaceImage( image );
   2548     ThrowPPException(mosaicImage_->quiet());
   2549   }
   2550 
   2551   // Compares each image the GIF disposed forms of the previous image in
   2552   // the sequence. From this it attempts to select the smallest cropped
   2553   // image to replace each frame, while preserving the results of the
   2554   // GIF animation.
   2555   template <class InputIterator, class Container >
   2556   void optimizeImageLayers( Container *optimizedImages_,
   2557                             InputIterator first_,
   2558                             InputIterator last_ ) {
   2559     if (linkImages(first_,last_) == false)
   2560       return;
   2561     GetPPException;
   2562     MagickCore::Image* images = OptimizeImageLayers( first_->image(), exceptionInfo );
   2563 
   2564     unlinkImages( first_, last_ );
   2565 
   2566     optimizedImages_->clear();
   2567 
   2568     insertImages( optimizedImages_, images );
   2569 
   2570     ThrowPPException(first_->quiet());
   2571   }
   2572 
   2573   // optimizeImagePlusLayers is exactly as optimizeImageLayers, but may
   2574   // also add or even remove extra frames in the animation, if it improves
   2575   // the total number of pixels in the resulting GIF animation.
   2576   template <class InputIterator, class Container >
   2577   void optimizePlusImageLayers( Container *optimizedImages_,
   2578                                 InputIterator first_,
   2579                                 InputIterator last_ ) {
   2580     if (linkImages(first_,last_) == false)
   2581       return;
   2582     GetPPException;
   2583     MagickCore::Image* images = OptimizePlusImageLayers( first_->image(), exceptionInfo );
   2584 
   2585     unlinkImages( first_, last_ );
   2586 
   2587     optimizedImages_->clear();
   2588 
   2589     insertImages( optimizedImages_, images );
   2590 
   2591     ThrowPPDrawException(first_->quiet());
   2592   }
   2593 
   2594   // Compares each image the GIF disposed forms of the previous image in the
   2595   // sequence. Any pixel that does not change the displayed result is replaced
   2596   // with transparency.
   2597   template<class InputIterator>
   2598   void optimizeTransparency(InputIterator first_,InputIterator last_)
   2599   {
   2600     if (linkImages(first_,last_) == false)
   2601       return;
   2602     GetPPException;
   2603     OptimizeImageTransparency(first_->image(),exceptionInfo);
   2604     unlinkImages(first_,last_ );
   2605 
   2606     ThrowPPException(first_->quiet());
   2607   }
   2608 
   2609   // Adds the names of the profiles of the image to the container.
   2610   template <class Container>
   2611   void profileNames(Container *names_,const Image* image_)
   2612   {
   2613     const char*
   2614       name;
   2615 
   2616     names_->clear();
   2617 
   2618     MagickCore::ResetImageProfileIterator(image_->constImage());
   2619     name=MagickCore::GetNextImageProfile(image_->constImage());
   2620     while (name != (const char *) NULL)
   2621     {
   2622       names_->push_back(std::string(name));
   2623       name=MagickCore::GetNextImageProfile(image_->constImage());
   2624     }
   2625   }
   2626 
   2627   // Quantize colors in images using current quantization settings
   2628   // Set measureError_ to true in order to measure quantization error
   2629   template <class InputIterator>
   2630   void quantizeImages(InputIterator first_,InputIterator last_,
   2631     bool measureError_ = false)
   2632   {
   2633     if (linkImages(first_,last_) == false)
   2634       return;
   2635     GetPPException;
   2636     MagickCore::QuantizeImages(first_->quantizeInfo(),first_->image(),
   2637       exceptionInfo);
   2638     unlinkImages(first_,last_);
   2639 
   2640     MagickCore::Image *image=first_->image();
   2641     while (image != (MagickCore::Image *) NULL)
   2642     {
   2643       // Calculate quantization error
   2644       if (measureError_)
   2645         MagickCore::GetImageQuantizeError(image,exceptionInfo);
   2646 
   2647       // Update DirectClass representation of pixels
   2648       MagickCore::SyncImage(image,exceptionInfo);
   2649 
   2650       image=image->next;
   2651     }
   2652     unlinkImages(first_,last_);
   2653     ThrowPPException(first_->quiet());
   2654   }
   2655 
   2656   // Read images into existing container (appending to container)
   2657   template<class Container>
   2658   void readImages(Container *sequence_,const std::string &imageSpec_,
   2659     ReadOptions &options)
   2660   {
   2661     MagickCore::Image
   2662       *images;
   2663 
   2664     MagickCore::ImageInfo
   2665       *imageInfo;
   2666 
   2667     imageInfo=options.imageInfo();
   2668     imageSpec_.copy(imageInfo->filename,MagickPathExtent-1);
   2669     imageInfo->filename[imageSpec_.length()] = 0;
   2670     GetPPException;
   2671     images=MagickCore::ReadImage(imageInfo,exceptionInfo);
   2672     insertImages(sequence_,images);
   2673     ThrowPPException(options.quiet());
   2674   }
   2675 
   2676   template<class Container>
   2677   void readImages(Container *sequence_,const std::string &imageSpec_)
   2678   {
   2679     ReadOptions options;
   2680     readImages(sequence_,imageSpec_,options);
   2681   }
   2682 
   2683   template<class Container>
   2684   void readImages(Container *sequence_,const Blob &blob_,ReadOptions &options)
   2685   {
   2686     MagickCore::Image
   2687       *images;
   2688 
   2689     GetPPException;
   2690     images=MagickCore::BlobToImage(options.imageInfo(),blob_.data(),
   2691       blob_.length(),exceptionInfo);
   2692     insertImages(sequence_,images);
   2693     ThrowPPException(options.quiet());
   2694   }
   2695 
   2696   template<class Container>
   2697   void readImages(Container *sequence_,const Blob &blob_)
   2698   {
   2699     ReadOptions options;
   2700     readImages(sequence_,blob_,options);
   2701   }
   2702 
   2703   // Returns a separate grayscale image for each channel specified.
   2704   template<class Container>
   2705   void separateImages(Container *separatedImages_,Image &image_,
   2706     const ChannelType channel_)
   2707   {
   2708     MagickCore::ChannelType
   2709       channel_mask;
   2710 
   2711     MagickCore::Image
   2712       *images;
   2713 
   2714     GetPPException;
   2715     channel_mask=MagickCore::SetImageChannelMask(image_.image(),channel_);
   2716     images=SeparateImages(image_.constImage(),exceptionInfo);
   2717     MagickCore::SetPixelChannelMask(image_.image(),channel_mask);
   2718 
   2719     separatedImages_->clear();
   2720     insertImages(separatedImages_,images);
   2721 
   2722     ThrowPPException(image_.quiet());
   2723   }
   2724 
   2725   // Smush images from list into single image in either horizontal or
   2726   // vertical direction.
   2727   template<class InputIterator>
   2728   void smushImages(Image *smushedImage_,InputIterator first_,
   2729     InputIterator last_,const ssize_t offset_,bool stack_=false)
   2730   {
   2731     MagickCore::Image
   2732       *newImage;
   2733 
   2734     if (linkImages(first_,last_) == false)
   2735       return;
   2736     GetPPException;
   2737     newImage=MagickCore::SmushImages(first_->constImage(),
   2738       (MagickBooleanType) stack_,offset_,exceptionInfo);
   2739     unlinkImages(first_,last_);
   2740     smushedImage_->replaceImage(newImage);
   2741     ThrowPPException(smushedImage_->quiet());
   2742   }
   2743 
   2744   // Write Images
   2745   template <class InputIterator>
   2746   void writeImages( InputIterator first_,
   2747         InputIterator last_,
   2748         const std::string &imageSpec_,
   2749         bool adjoin_ = true ) {
   2750 
   2751     if (linkImages(first_,last_) == false)
   2752       return;
   2753 
   2754     first_->adjoin( adjoin_ );
   2755 
   2756     GetPPException;
   2757     ::ssize_t errorStat = MagickCore::WriteImages( first_->constImageInfo(),
   2758                                             first_->image(),
   2759                                             imageSpec_.c_str(),
   2760                                             exceptionInfo );
   2761     unlinkImages( first_, last_ );
   2762 
   2763     if ( errorStat != false )
   2764       {
   2765         (void) MagickCore::DestroyExceptionInfo( exceptionInfo );
   2766         return;
   2767       }
   2768 
   2769     ThrowPPException(first_->quiet());
   2770   }
   2771   // Write images to BLOB
   2772   template <class InputIterator>
   2773   void writeImages( InputIterator first_,
   2774         InputIterator last_,
   2775         Blob *blob_,
   2776         bool adjoin_ = true) {
   2777     if (linkImages(first_,last_) == false)
   2778       return;
   2779 
   2780     first_->adjoin( adjoin_ );
   2781 
   2782     GetPPException;
   2783     size_t length = 2048; // Efficient size for small images
   2784     void* data = MagickCore::ImagesToBlob( first_->imageInfo(),
   2785            first_->image(),
   2786            &length,
   2787            exceptionInfo);
   2788     blob_->updateNoCopy( data, length, Magick::Blob::MallocAllocator );
   2789 
   2790     unlinkImages( first_, last_ );
   2791 
   2792     ThrowPPException(first_->quiet());
   2793   }
   2794 
   2795 } // namespace Magick
   2796 
   2797 #endif // Magick_STL_header
   2798