• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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>
channelMaskImages(InputIterator first_,InputIterator last_,Container * container_,const ChannelType channel_)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>
insertImages(Container * sequence_,MagickCore::Image * images_)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>
linkImages(InputIterator first_,InputIterator last_)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>
restoreChannelMaskImages(InputIterator first_,InputIterator last_,Container * 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>
unlinkImages(InputIterator first_,InputIterator last_)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>
animateImages(InputIterator first_,InputIterator last_)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>
artifactNames(Container * names_,const Image * image_)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>
attributeNames(Container * names_,const Image * image_)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>
averageImages(Image * averagedImage_,InputIterator first_,InputIterator last_)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 >
coalesceImages(Container * coalescedImages_,InputIterator first_,InputIterator last_)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
catch(Magick::ErrorModule)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 >
colorHistogram(Container * histogram_,const Image image)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 >
combineImages(Image * combinedImage_,InputIterator first_,InputIterator last_,const ChannelType channel_,const ColorspaceType colorspace_)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>
cropToTiles(Container * tiledImages_,const Image image_,const Geometry & geometry_)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>
deconstructImages(Container * deconstructedImages_,InputIterator first_,InputIterator last_)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>
displayImages(InputIterator first_,InputIterator last_)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 >
evaluateImages(Image * evaluatedImage_,InputIterator first_,InputIterator last_,const MagickEvaluateOperator operator_)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>
flattenImages(Image * flattendImage_,InputIterator first_,InputIterator last_)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 >
forwardFourierTransformImage(Container * fourierImages_,const Image & image_)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 >
forwardFourierTransformImage(Container * fourierImages_,const Image & image_,const bool magnitude_)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>
fxImages(Image * fxImage_,InputIterator first_,InputIterator last_,const std::string expression)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 >
mergeImageLayers(Image * mergedImage_,InputIterator first_,InputIterator last_,const LayerMethod method_)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>
montageImages(Container * montageImages_,InputIterator first_,InputIterator last_,const Montage & options_)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 >
morphImages(Container * morphedImages_,InputIterator first_,InputIterator last_,size_t frames_)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>
mosaicImages(Image * mosaicImage_,InputIterator first_,InputIterator last_)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 >
optimizeImageLayers(Container * optimizedImages_,InputIterator first_,InputIterator last_)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 >
optimizePlusImageLayers(Container * optimizedImages_,InputIterator first_,InputIterator last_)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>
optimizeTransparency(InputIterator first_,InputIterator last_)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>
profileNames(Container * names_,const Image * image_)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>
readImages(Container * sequence_,const std::string & imageSpec_,ReadOptions & options)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>
readImages(Container * sequence_,const std::string & imageSpec_)2677   void readImages(Container *sequence_,const std::string &imageSpec_)
2678   {
2679     ReadOptions options;
2680     readImages(sequence_,imageSpec_,options);
2681   }
2682 
2683   template<class Container>
readImages(Container * sequence_,const Blob & blob_,ReadOptions & options)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>
readImages(Container * sequence_,const Blob & blob_)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>
separateImages(Container * separatedImages_,Image & image_,const ChannelType channel_)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