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