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