Magick++ 7.1.1
Loading...
Searching...
No Matches
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// 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
27namespace 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
49 class MagickPPExport adaptiveBlurImage
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
65 class MagickPPExport adaptiveThresholdImage
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
81 class MagickPPExport addNoiseImage
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.
94 class MagickPPExport affineTransformImage
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)
106 class MagickPPExport annotateImage
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
141 class MagickPPExport blurImage
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 // usually of the same size as the source image, unless 'bestfit' is set to
349 // true.
350 class MagickPPExport distortImage
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
372 class MagickPPExport drawImage
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 (highlight edges in image)
389 class MagickPPExport edgeImage
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 (highlight edges with 3D effect)
401 class MagickPPExport embossImage
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)
415 class MagickPPExport enhanceImage
416 {
417 public:
418 enhanceImage( void );
419
420 void operator()( Image &image_ ) const;
421
422 private:
423 };
424
425 // Equalize image (histogram equalization)
426 class MagickPPExport equalizeImage
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
437 class MagickPPExport fillColorImage
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)
449 class MagickPPExport flipImage
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
460 class MagickPPExport floodFillAlphaImage
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
478 class MagickPPExport floodFillColorImage
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
510 class MagickPPExport floodFillTextureImage
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)
543 class MagickPPExport flopImage
544 {
545 public:
546 flopImage( void );
547
548 void operator()( Image &image_ ) const;
549
550 private:
551 };
552
553 // Frame image
554 class MagickPPExport frameImage
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
572 class MagickPPExport gammaImage
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_'.
593 class MagickPPExport gaussianBlurImage
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.
606 class MagickPPExport haldClutImage
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)
618 class MagickPPExport implodeImage
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.
631 class MagickPPExport inverseFourierTransformImage
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.
644 class MagickPPExport isValidImage
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
656 class MagickPPExport labelImage
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
669 class MagickPPExport levelImage
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
685 class MagickPPExport magnifyImage
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
696 class MagickPPExport mapImage
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
711 class MagickPPExport medianConvolveImage
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
723 class MagickPPExport mergeLayersImage
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
735 class MagickPPExport minifyImage
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
746 class MagickPPExport modulateImage
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.
763 class MagickPPExport negateImage
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)
776 class MagickPPExport normalizeImage
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)
787 class MagickPPExport oilPaintImage
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.
805 class MagickPPExport alphaImage
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.
817 class MagickPPExport opaqueImage
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)
831 class MagickPPExport quantizeImage
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)
844 class MagickPPExport raiseImage
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
857 class MagickPPExport ReadOptions
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 &geometry_);
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
906 class MagickPPExport reduceNoiseImage
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.
920 class MagickPPExport resizeImage
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 columns and rows)
933 class MagickPPExport rollImage
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 ssize_t _columns;
944 ssize_t _rows;
945 };
946
947 // Rotate image counter-clockwise by specified number of degrees.
948 class MagickPPExport rotateImage
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
960 class MagickPPExport sampleImage
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
972 class MagickPPExport scaleImage
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
987 class MagickPPExport segmentImage
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
1001 class MagickPPExport shadeImage
1002 {
1003 public:
1004 shadeImage( const double azimuth_ = 30,
1005 const double elevation_ = 30,
1006 const bool colorShading_ = false );
1007
1008 void operator()( Image &image_ ) const;
1009
1010 private:
1011 double _azimuth;
1012 double _elevation;
1013 bool _colorShading;
1014 };
1015
1016 // Shadow effect image (simulate an image shadow)
1017 class MagickPPExport shadowImage
1018 {
1019 public:
1020 shadowImage( const double percent_opacity_ = 80, const double sigma_ = 0.5,
1021 const ssize_t x_ = 5, const ssize_t y_ = 5 );
1022
1023 void operator()( Image &image_ ) const;
1024
1025 private:
1026 double _percent_opacity;
1027 double _sigma;
1028 ssize_t _x;
1029 ssize_t _y;
1030 };
1031
1032 // Sharpen pixels in image
1033 class MagickPPExport sharpenImage
1034 {
1035 public:
1036 sharpenImage( const double radius_ = 1, const double sigma_ = 0.5 );
1037
1038 void operator()( Image &image_ ) const;
1039
1040 private:
1041 double _radius;
1042 double _sigma;
1043 };
1044
1045 // Shave pixels from image edges.
1046 class MagickPPExport shaveImage
1047 {
1048 public:
1049 shaveImage( const Geometry &geometry_ );
1050
1051 void operator()( Image &image_ ) const;
1052
1053 private:
1054 Geometry _geometry;
1055 };
1056
1057
1058 // Shear image (create parallelogram by sliding image by X or Y axis)
1059 class MagickPPExport shearImage
1060 {
1061 public:
1062 shearImage( const double xShearAngle_,
1063 const double yShearAngle_ );
1064
1065 void operator()( Image &image_ ) const;
1066
1067 private:
1068 double _xShearAngle;
1069 double _yShearAngle;
1070 };
1071
1072 // Solarize image (similar to effect seen when exposing a
1073 // photographic film to light during the development process)
1074 class MagickPPExport solarizeImage
1075 {
1076 public:
1077 solarizeImage( const double factor_ );
1078
1079 void operator()( Image &image_ ) const;
1080
1081 private:
1082 double _factor;
1083 };
1084
1085 // Splice the background color into the image.
1086 class MagickPPExport spliceImage
1087 {
1088 public:
1089 spliceImage( const Geometry &geometry_ );
1090
1091 void operator()( Image &image_ ) const;
1092
1093 private:
1094 Geometry _geometry;
1095 };
1096
1097 // Spread pixels randomly within image by specified amount
1098 class MagickPPExport spreadImage
1099 {
1100 public:
1101 spreadImage( const size_t amount_ = 3 );
1102
1103 void operator()( Image &image_ ) const;
1104
1105 private:
1106 size_t _amount;
1107 };
1108
1109 // Add a digital watermark to the image (based on second image)
1110 class MagickPPExport steganoImage
1111 {
1112 public:
1113 steganoImage( const Image &waterMark_ );
1114
1115 void operator()( Image &image_ ) const;
1116
1117 private:
1118 Image _waterMark;
1119 };
1120
1121 // Create an image which appears in stereo when viewed with red-blue glasses
1122 // (Red image on left, blue on right)
1123 class MagickPPExport stereoImage
1124 {
1125 public:
1126 stereoImage( const Image &rightImage_ );
1127
1128 void operator()( Image &image_ ) const;
1129
1130 private:
1131 Image _rightImage;
1132 };
1133
1134 // Color to use when drawing object outlines
1135 class MagickPPExport strokeColorImage
1136 {
1137 public:
1138 strokeColorImage( const Color &strokeColor_ );
1139
1140 void operator()( Image &image_ ) const;
1141
1142 private:
1143 Color _strokeColor;
1144 };
1145
1146 // Swirl image (image pixels are rotated by degrees)
1147 class MagickPPExport swirlImage
1148 {
1149 public:
1150 swirlImage( const double degrees_ );
1151
1152 void operator()( Image &image_ ) const;
1153
1154 private:
1155 double _degrees;
1156 };
1157
1158 // Channel a texture on image background
1159 class MagickPPExport textureImage
1160 {
1161 public:
1162 textureImage( const Image &texture_ );
1163
1164 void operator()( Image &image_ ) const;
1165
1166 private:
1167 Image _texture;
1168 };
1169
1170 // Threshold image
1171 class MagickPPExport thresholdImage
1172 {
1173 public:
1174 thresholdImage( const double threshold_ );
1175
1176 void operator()( Image &image_ ) const;
1177
1178 private:
1179 double _threshold;
1180 };
1181
1182 // Set image color to transparent
1183 class MagickPPExport transparentImage
1184 {
1185 public:
1186 transparentImage( const Color& color_ );
1187
1188 void operator()( Image &image_ ) const;
1189
1190 private:
1191 Color _color;
1192 };
1193
1194 // Trim edges that are the background color from the image
1195 class MagickPPExport trimImage
1196 {
1197 public:
1198 trimImage( void );
1199
1200 void operator()( Image &image_ ) const;
1201
1202 private:
1203 };
1204
1205 // Map image pixels to a sine wave
1206 class MagickPPExport waveImage
1207 {
1208 public:
1209 waveImage( const double amplitude_ = 25.0,
1210 const double wavelength_ = 150.0 );
1211
1212 void operator()( Image &image_ ) const;
1213
1214 private:
1215 double _amplitude;
1216 double _wavelength;
1217 };
1218
1219 // Zoom image to specified size.
1220 class MagickPPExport zoomImage
1221 {
1222 public:
1223 zoomImage( const Geometry &geometry_ );
1224
1225 void operator()( Image &image_ ) const;
1226
1227 private:
1228 Geometry _geometry;
1229 };
1230
1231 //
1232 // Function object image attribute accessors
1233 //
1234
1235 // Join images into a single multi-image file
1236 class MagickPPExport adjoinImage
1237 {
1238 public:
1239 adjoinImage( const bool flag_ );
1240
1241 void operator()( Image &image_ ) const;
1242
1243 private:
1244 bool _flag;
1245 };
1246
1247 // Time in 1/100ths of a second which must expire before displaying
1248 // the next image in an animated sequence.
1249 class MagickPPExport animationDelayImage
1250 {
1251 public:
1252 animationDelayImage( const size_t delay_ );
1253
1254 void operator()( Image &image_ ) const;
1255
1256 private:
1257 size_t _delay;
1258 };
1259
1260 // Number of iterations to loop an animation (e.g. Netscape loop
1261 // extension) for.
1262 class MagickPPExport animationIterationsImage
1263 {
1264 public:
1265 animationIterationsImage( const size_t iterations_ );
1266
1267 void operator()( Image &image_ ) const;
1268
1269 private:
1270 size_t _iterations;
1271 };
1272
1273 // Image background color
1274 class MagickPPExport backgroundColorImage
1275 {
1276 public:
1277 backgroundColorImage( const Color &color_ );
1278
1279 void operator()( Image &image_ ) const;
1280
1281 private:
1282 Color _color;
1283 };
1284
1285 // Name of texture image to tile onto the image background
1286 class MagickPPExport backgroundTextureImage
1287 {
1288 public:
1289 backgroundTextureImage( const std::string &backgroundTexture_ );
1290
1291 void operator()( Image &image_ ) const;
1292
1293 private:
1294 std::string _backgroundTexture;
1295 };
1296
1297 // Image border color
1298 class MagickPPExport borderColorImage
1299 {
1300 public:
1301 borderColorImage( const Color &color_ );
1302
1303 void operator()( Image &image_ ) const;
1304
1305 private:
1306 Color _color;
1307 };
1308
1309 // Text bounding-box base color (default none)
1310 class MagickPPExport boxColorImage
1311 {
1312 public:
1313 boxColorImage( const Color &boxColor_ );
1314
1315 void operator()( Image &image_ ) const;
1316
1317 private:
1318 Color _boxColor;
1319 };
1320
1321 // Chromaticity blue primary point.
1322 class MagickPPExport chromaBluePrimaryImage
1323 {
1324 public:
1325 chromaBluePrimaryImage(const double x_,const double y_,const double z_);
1326
1327 void operator()(Image &image_) const;
1328
1329 private:
1330 double _x;
1331 double _y;
1332 double _z;
1333 };
1334
1335 // Chromaticity green primary point.
1336 class MagickPPExport chromaGreenPrimaryImage
1337 {
1338 public:
1339 chromaGreenPrimaryImage(const double x_,const double y_,const double z_);
1340
1341 void operator()(Image &image_) const;
1342
1343 private:
1344 double _x;
1345 double _y;
1346 double _z;
1347 };
1348
1349 // Chromaticity red primary point.
1350 class MagickPPExport chromaRedPrimaryImage
1351 {
1352 public:
1353 chromaRedPrimaryImage(const double x_,const double y_,const double z_);
1354
1355 void operator()(Image &image_) const;
1356
1357 private:
1358 double _x;
1359 double _y;
1360 double _z;
1361 };
1362
1363 // Chromaticity white point.
1364 class MagickPPExport chromaWhitePointImage
1365 {
1366 public:
1367 chromaWhitePointImage(const double x_,const double y_,const double z_);
1368
1369 void operator()(Image &image_) const;
1370
1371 private:
1372 double _x;
1373 double _y;
1374 double _z;
1375 };
1376
1377 // Colors within this distance are considered equal
1378 class MagickPPExport colorFuzzImage
1379 {
1380 public:
1381 colorFuzzImage( const double fuzz_ );
1382
1383 void operator()( Image &image_ ) const;
1384
1385 private:
1386 double _fuzz;
1387 };
1388
1389 // Color at colormap position index_
1390 class MagickPPExport colorMapImage
1391 {
1392 public:
1393 colorMapImage( const size_t index_, const Color &color_ );
1394
1395 void operator()( Image &image_ ) const;
1396
1397 private:
1398 size_t _index;
1399 Color _color;
1400 };
1401
1402 // Composition operator to be used when composition is implicitly used
1403 // (such as for image flattening).
1404 class MagickPPExport composeImage
1405 {
1406 public:
1407 composeImage( const CompositeOperator compose_ );
1408
1409 void operator()( Image &image_ ) const;
1410
1411 private:
1412 CompositeOperator _compose;
1413 };
1414
1415 // Compression type
1416 class MagickPPExport compressTypeImage
1417 {
1418 public:
1419 compressTypeImage( const CompressionType compressType_ );
1420
1421 void operator()( Image &image_ ) const;
1422
1423 private:
1424 CompressionType _compressType;
1425 };
1426
1427 // Vertical and horizontal resolution in pixels of the image
1428 class MagickPPExport densityImage
1429 {
1430 public:
1431 densityImage( const Point &point_ );
1432
1433 void operator()( Image &image_ ) const;
1434
1435 private:
1436 Point _point;
1437 };
1438
1439 // Image depth (bits allocated to red/green/blue components)
1440 class MagickPPExport depthImage
1441 {
1442 public:
1443 depthImage( const size_t depth_ );
1444
1445 void operator()( Image &image_ ) const;
1446
1447 private:
1448 size_t _depth;
1449 };
1450
1451 // Endianness (LSBEndian like Intel or MSBEndian like SPARC) for image
1452 // formats which support endian-specific options.
1453 class MagickPPExport endianImage
1454 {
1455 public:
1456 endianImage( const EndianType endian_ );
1457
1458 void operator()( Image &image_ ) const;
1459
1460 private:
1461 EndianType _endian;
1462 };
1463
1464 // Image file name
1465 class MagickPPExport fileNameImage
1466 {
1467 public:
1468 fileNameImage( const std::string &fileName_ );
1469
1470 void operator()( Image &image_ ) const;
1471
1472 private:
1473 std::string _fileName;
1474 };
1475
1476 // Filter to use when resizing image
1477 class MagickPPExport filterTypeImage
1478 {
1479 public:
1480 filterTypeImage( const FilterType filterType_ );
1481
1482 void operator()( Image &image_ ) const;
1483
1484 private:
1485 FilterType _filterType;
1486 };
1487
1488 // Text rendering font
1489 class MagickPPExport fontImage
1490 {
1491 public:
1492 fontImage( const std::string &font_ );
1493
1494 void operator()( Image &image_ ) const;
1495
1496 private:
1497 std::string _font;
1498 };
1499
1500 // Font point size
1501 class MagickPPExport fontPointsizeImage
1502 {
1503 public:
1504 fontPointsizeImage( const size_t pointsize_ );
1505
1506 void operator()( Image &image_ ) const;
1507
1508 private:
1509 size_t _pointsize;
1510 };
1511
1512 // GIF disposal method
1513 class MagickPPExport gifDisposeMethodImage
1514 {
1515 public:
1516 gifDisposeMethodImage( const DisposeType disposeMethod_ );
1517
1518 void operator()( Image &image_ ) const;
1519
1520 private:
1521 DisposeType _disposeMethod;
1522 };
1523
1524 // Type of interlacing to use
1525 class MagickPPExport interlaceTypeImage
1526 {
1527 public:
1528 interlaceTypeImage( const InterlaceType interlace_ );
1529
1530 void operator()( Image &image_ ) const;
1531
1532 private:
1533 InterlaceType _interlace;
1534 };
1535
1536 // File type magick identifier (.e.g "GIF")
1537 class MagickPPExport magickImage
1538 {
1539 public:
1540 magickImage( const std::string &magick_ );
1541
1542 void operator()( Image &image_ ) const;
1543
1544 private:
1545 std::string _magick;
1546 };
1547
1548 // Image supports transparent color
1549 class MagickPPExport alphaFlagImage
1550 {
1551 public:
1552 alphaFlagImage( const bool alphaFlag_ );
1553
1554 void operator()( Image &image_ ) const;
1555
1556 private:
1557 bool _alphaFlag;
1558 };
1559
1560 // Transparent color
1561 class MagickPPExport matteColorImage
1562 {
1563 public:
1564 matteColorImage( const Color &matteColor_ );
1565
1566 void operator()( Image &image_ ) const;
1567
1568 private:
1569 Color _matteColor;
1570 };
1571
1572 // Indicate that image is black and white
1573 class MagickPPExport monochromeImage
1574 {
1575 public:
1576 monochromeImage( const bool monochromeFlag_ );
1577
1578 void operator()( Image &image_ ) const;
1579
1580 private:
1581 bool _monochromeFlag;
1582 };
1583
1584 // Pen color
1585 class MagickPPExport penColorImage
1586 {
1587 public:
1588 penColorImage( const Color &penColor_ );
1589
1590 void operator()( Image &image_ ) const;
1591
1592 private:
1593 Color _penColor;
1594 };
1595
1596 // Pen texture image.
1597 class MagickPPExport penTextureImage
1598 {
1599 public:
1600 penTextureImage( const Image &penTexture_ );
1601
1602 void operator()( Image &image_ ) const;
1603
1604 private:
1605 Image _penTexture;
1606 };
1607
1608 // Set pixel color at location x & y.
1609 class MagickPPExport pixelColorImage
1610 {
1611 public:
1612 pixelColorImage( const ::ssize_t x_,
1613 const ::ssize_t y_,
1614 const Color &color_);
1615
1616 void operator()( Image &image_ ) const;
1617
1618 private:
1619 ::ssize_t _x;
1620 ::ssize_t _y;
1621 Color _color;
1622 };
1623
1624 // Postscript page size.
1625 class MagickPPExport pageImage
1626 {
1627 public:
1628 pageImage( const Geometry &pageSize_ );
1629
1630 void operator()( Image &image_ ) const;
1631
1632 private:
1633 Geometry _pageSize;
1634 };
1635
1636 // JPEG/MIFF/PNG compression level (default 75).
1637 class MagickPPExport qualityImage
1638 {
1639 public:
1640 qualityImage( const size_t quality_ );
1641
1642 void operator()( Image &image_ ) const;
1643
1644 private:
1645 size_t _quality;
1646 };
1647
1648 // Maximum number of colors to quantize to
1649 class MagickPPExport quantizeColorsImage
1650 {
1651 public:
1652 quantizeColorsImage( const size_t colors_ );
1653
1654 void operator()( Image &image_ ) const;
1655
1656 private:
1657 size_t _colors;
1658 };
1659
1660 // Colorspace to quantize in.
1661 class MagickPPExport quantizeColorSpaceImage
1662 {
1663 public:
1664 quantizeColorSpaceImage( const ColorspaceType colorSpace_ );
1665
1666 void operator()( Image &image_ ) const;
1667
1668 private:
1669 ColorspaceType _colorSpace;
1670 };
1671
1672 // Dither image during quantization (default true).
1673 class MagickPPExport quantizeDitherImage
1674 {
1675 public:
1676 quantizeDitherImage( const bool ditherFlag_ );
1677
1678 void operator()( Image &image_ ) const;
1679
1680 private:
1681 bool _ditherFlag;
1682 };
1683
1684 // Quantization tree-depth
1685 class MagickPPExport quantizeTreeDepthImage
1686 {
1687 public:
1688 quantizeTreeDepthImage( const size_t treeDepth_ );
1689
1690 void operator()( Image &image_ ) const;
1691
1692 private:
1693 size_t _treeDepth;
1694 };
1695
1696 // The type of rendering intent
1697 class MagickPPExport renderingIntentImage
1698 {
1699 public:
1700 renderingIntentImage( const RenderingIntent renderingIntent_ );
1701
1702 void operator()( Image &image_ ) const;
1703
1704 private:
1705 RenderingIntent _renderingIntent;
1706 };
1707
1708 // Units of image resolution
1709 class MagickPPExport resolutionUnitsImage
1710 {
1711 public:
1712 resolutionUnitsImage( const ResolutionType resolutionUnits_ );
1713
1714 void operator()( Image &image_ ) const;
1715
1716 private:
1717 ResolutionType _resolutionUnits;
1718 };
1719
1720 // Image scene number
1721 class MagickPPExport sceneImage
1722 {
1723 public:
1724 sceneImage( const size_t scene_ );
1725
1726 void operator()( Image &image_ ) const;
1727
1728 private:
1729 size_t _scene;
1730 };
1731
1732 // adjust the image contrast with a non-linear sigmoidal contrast algorithm
1733 class MagickPPExport sigmoidalContrastImage
1734 {
1735 public:
1736 sigmoidalContrastImage( const size_t sharpen_,
1737 const double contrast,
1738 const double midpoint = (double) QuantumRange / 2.0 );
1739
1740 void operator()( Image &image_ ) const;
1741
1742 private:
1743 size_t _sharpen;
1744 double contrast;
1745 double midpoint;
1746 };
1747
1748 // Width and height of a raw image
1749 class MagickPPExport sizeImage
1750 {
1751 public:
1752 sizeImage( const Geometry &geometry_ );
1753
1754 void operator()( Image &image_ ) const;
1755
1756 private:
1757 Geometry _geometry;
1758 };
1759
1760 // stripImage strips an image of all profiles and comments.
1761 class MagickPPExport stripImage
1762 {
1763 public:
1764 stripImage( void );
1765
1766 void operator()( Image &image_ ) const;
1767
1768 private:
1769 };
1770
1771 // Subimage of an image sequence
1772 class MagickPPExport subImageImage
1773 {
1774 public:
1775 subImageImage( const size_t subImage_ );
1776
1777 void operator()( Image &image_ ) const;
1778
1779 private:
1780 size_t _subImage;
1781 };
1782
1783 // Number of images relative to the base image
1784 class MagickPPExport subRangeImage
1785 {
1786 public:
1787 subRangeImage( const size_t subRange_ );
1788
1789 void operator()( Image &image_ ) const;
1790
1791 private:
1792 size_t _subRange;
1793 };
1794
1795 // Anti-alias Postscript and TrueType fonts (default true)
1796 class MagickPPExport textAntiAliasImage
1797 {
1798 public:
1799 textAntiAliasImage( const bool flag_ );
1800
1801 void operator()( Image &image_ ) const;
1802
1803 private:
1804 bool _flag;
1805 };
1806
1807 // Image storage type
1808 class MagickPPExport typeImage
1809 {
1810 public:
1811 typeImage( const ImageType type_ );
1812
1813 void operator()( Image &image_ ) const;
1814
1815 private:
1816 Magick::ImageType _type;
1817 };
1818
1819
1820 // Print detailed information about the image
1821 class MagickPPExport verboseImage
1822 {
1823 public:
1824 verboseImage( const bool verbose_ );
1825
1826 void operator()( Image &image_ ) const;
1827
1828 private:
1829 bool _verbose;
1830 };
1831
1832 // X11 display to display to, obtain fonts from, or to capture
1833 // image from
1834 class MagickPPExport x11DisplayImage
1835 {
1836 public:
1837 x11DisplayImage( const std::string &display_ );
1838
1839 void operator()( Image &image_ ) const;
1840
1841 private:
1842 std::string _display;
1843 };
1844
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 {
1875 MagickCore::Image
1876 *image,
1877 *next;
1878
1879 image=images_;
1880 while (image != (MagickCore::Image *) NULL)
1881 {
1882 next=image->next;
1883 image->next=(MagickCore::Image *) NULL;
1884
1885 if (next != (MagickCore::Image *) NULL)
1886 next->previous=(MagickCore::Image *) NULL;
1887
1888 sequence_->push_back(Magick::Image(image));
1889
1890 image=next;
1891 }
1892 }
1893
1894 // Link images together into an image list based on the ordering of
1895 // the container implied by the iterator. This step is done in
1896 // preparation for use with ImageMagick functions which operate on
1897 // lists of images.
1898 // Images are selected by range, first_ to last_ so that a subset of
1899 // the container may be selected. Specify first_ via the
1900 // container's begin() method and last_ via the container's end()
1901 // method in order to specify the entire container.
1902 template<class InputIterator>
1903 bool linkImages(InputIterator first_,InputIterator last_)
1904 {
1905 MagickCore::Image
1906 *current,
1907 *previous;
1908
1909 ::ssize_t
1910 scene;
1911
1912 scene=0;
1913 previous=(MagickCore::Image *) NULL;
1914 for (InputIterator iter = first_; iter != last_; ++iter)
1915 {
1916 // Unless we reduce the reference count to one, the same image
1917 // structure may occur more than once in the container, causing
1918 // the linked list to fail.
1919 iter->modifyImage();
1920
1921 current=iter->image();
1922
1923 current->previous=previous;
1924 current->next=(MagickCore::Image *) NULL;
1925 current->scene=(size_t) scene++;
1926
1927 if (previous != (MagickCore::Image *) NULL)
1928 previous->next=current;
1929
1930 previous=current;
1931 }
1932 return(scene > 0 ? true : false);
1933 }
1934
1935 // Restores the channel mask of the images.
1936 template<class InputIterator, class Container>
1937 void restoreChannelMaskImages(InputIterator first_,InputIterator last_,
1938 Container *container_)
1939 {
1940 typename Container::iterator
1941 channel_mask;
1942
1943 channel_mask=container_->begin();
1944 for (InputIterator iter = first_; iter != last_; ++iter)
1945 {
1946 iter->modifyImage();
1947 (void) MagickCore::SetImageChannelMask(iter->image(),
1948 (const MagickCore::ChannelType) *channel_mask);
1949 channel_mask++;
1950 }
1951 }
1952
1953 // Remove links added by linkImages. This should be called after the
1954 // ImageMagick function call has completed to reset the image list
1955 // back to its pristine un-linked state.
1956 template<class InputIterator>
1957 void unlinkImages(InputIterator first_,InputIterator last_)
1958 {
1959 MagickCore::Image
1960 *image;
1961
1962 for (InputIterator iter = first_; iter != last_; ++iter)
1963 {
1964 image=iter->image();
1965 image->previous=(MagickCore::Image *) NULL;
1966 image->next=(MagickCore::Image *) NULL;
1967 }
1968 }
1969
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;
1981 GetPPException;
1982 MagickCore::AnimateImages(first_->imageInfo(),first_->image(),
1983 exceptionInfo);
1984 unlinkImages(first_,last_);
1985 ThrowPPException(first_->quiet());
1986 }
1987
1988 // Append images from list into single image in either horizontal or
1989 // vertical direction.
1990 template <class InputIterator>
1991 void appendImages( Image *appendedImage_,
1992 InputIterator first_,
1993 InputIterator last_,
1994 bool stack_ = false) {
1995 if (linkImages(first_,last_) == false)
1996 return;
1997 GetPPException;
1998 MagickCore::Image* image = MagickCore::AppendImages( first_->image(),
1999 (MagickBooleanType) stack_,
2000 exceptionInfo );
2001 unlinkImages( first_, last_ );
2002 appendedImage_->replaceImage( image );
2003 ThrowPPException(appendedImage_->quiet());
2004 }
2005
2006 // Adds the names of the artifacts of the image to the container.
2007 template <class Container>
2008 void artifactNames(Container *names_,const Image* image_)
2009 {
2010 const char*
2011 name;
2012
2013 names_->clear();
2014
2015 MagickCore::ResetImageArtifactIterator(image_->constImage());
2016 name=MagickCore::GetNextImageArtifact(image_->constImage());
2017 while (name != (const char *) NULL)
2018 {
2019 names_->push_back(std::string(name));
2020 name=MagickCore::GetNextImageArtifact(image_->constImage());
2021 }
2022 }
2023
2024 // Adds the names of the attributes of the image to the container.
2025 template <class Container>
2026 void attributeNames(Container *names_,const Image* image_)
2027 {
2028 const char*
2029 name;
2030
2031 names_->clear();
2032
2033 MagickCore::ResetImagePropertyIterator(image_->constImage());
2034 name=MagickCore::GetNextImageProperty(image_->constImage());
2035 while (name != (const char *) NULL)
2036 {
2037 names_->push_back(std::string(name));
2038 name=MagickCore::GetNextImageProperty(image_->constImage());
2039 }
2040 }
2041
2042 // Average a set of images.
2043 // All the input images must be the same size in pixels.
2044 template <class InputIterator>
2045 void averageImages( Image *averagedImage_,
2046 InputIterator first_,
2047 InputIterator last_ ) {
2048 if (linkImages(first_,last_) == false)
2049 return;
2050 GetPPException;
2051 MagickCore::Image* image = MagickCore::EvaluateImages( first_->image(),
2052 MagickCore::MeanEvaluateOperator, exceptionInfo );
2053 unlinkImages( first_, last_ );
2054 averagedImage_->replaceImage( image );
2055 ThrowPPException(averagedImage_->quiet());
2056 }
2057
2058 // Merge a sequence of images.
2059 // This is useful for GIF animation sequences that have page
2060 // offsets and disposal methods. A container to contain
2061 // the updated image sequence is passed via the coalescedImages_
2062 // option.
2063 template <class InputIterator, class Container >
2064 void coalesceImages(Container *coalescedImages_,InputIterator first_,
2065 InputIterator last_)
2066 {
2067 bool
2068 quiet;
2069
2070 MagickCore::Image
2071 *images;
2072
2073 if (linkImages(first_,last_) == false)
2074 return;
2075
2076 GetPPException;
2077 quiet=first_->quiet();
2078 images=MagickCore::CoalesceImages(first_->image(),exceptionInfo);
2079
2080 // Unlink image list
2081 unlinkImages(first_,last_);
2082
2083 // Ensure container is empty
2084 coalescedImages_->clear();
2085
2086 // Move images to container
2087 insertImages(coalescedImages_,images);
2088
2089 // Report any error
2090 ThrowPPException(quiet);
2091 }
2092
2093 // Return format coders matching specified conditions.
2094 //
2095 // The default (if no match terms are supplied) is to return all
2096 // available format coders.
2097 //
2098 // For example, to return all readable formats:
2099 // list<CoderInfo> coderList;
2100 // coderInfoList( &coderList, CoderInfo::TrueMatch, CoderInfo::AnyMatch, CoderInfo::AnyMatch)
2101 //
2102 template <class Container >
2103 void coderInfoList( Container *container_,
2104 CoderInfo::MatchType isReadable_ = CoderInfo::AnyMatch,
2105 CoderInfo::MatchType isWritable_ = CoderInfo::AnyMatch,
2106 CoderInfo::MatchType isMultiFrame_ = CoderInfo::AnyMatch
2107 ) {
2108 // Obtain first entry in MagickInfo list
2109 size_t number_formats;
2110 GetPPException;
2111 char **coder_list =
2112 MagickCore::GetMagickList( "*", &number_formats, exceptionInfo );
2113 if( !coder_list )
2114 {
2115 throwException(exceptionInfo);
2116 throwExceptionExplicit(MagickCore::MissingDelegateError,
2117 "Coder array not returned!", 0 );
2118 }
2119
2120 // Clear out container
2121 container_->clear();
2122
2123 for ( ::ssize_t i=0; i < (::ssize_t) number_formats; i++)
2124 {
2125 const MagickCore::MagickInfo *magick_info =
2126 MagickCore::GetMagickInfo( coder_list[i], exceptionInfo );
2127 if (!magick_info)
2128 continue;
2129
2130 coder_list[i]=(char *)
2131 MagickCore::RelinquishMagickMemory( coder_list[i] );
2132
2133 // Skip stealth coders
2134 if ( MagickCore::GetMagickStealth(magick_info) )
2135 continue;
2136
2137 try {
2138 CoderInfo coderInfo( magick_info->name );
2139
2140 // Test isReadable_
2141 if ( isReadable_ != CoderInfo::AnyMatch &&
2142 (( coderInfo.isReadable() && isReadable_ != CoderInfo::TrueMatch ) ||
2143 ( !coderInfo.isReadable() && isReadable_ != CoderInfo::FalseMatch )) )
2144 continue;
2145
2146 // Test isWritable_
2147 if ( isWritable_ != CoderInfo::AnyMatch &&
2148 (( coderInfo.isWritable() && isWritable_ != CoderInfo::TrueMatch ) ||
2149 ( !coderInfo.isWritable() && isWritable_ != CoderInfo::FalseMatch )) )
2150 continue;
2151
2152 // Test isMultiFrame_
2153 if ( isMultiFrame_ != CoderInfo::AnyMatch &&
2154 (( coderInfo.isMultiFrame() && isMultiFrame_ != CoderInfo::TrueMatch ) ||
2155 ( !coderInfo.isMultiFrame() && isMultiFrame_ != CoderInfo::FalseMatch )) )
2156 continue;
2157
2158 // Append matches to container
2159 container_->push_back( coderInfo );
2160 }
2161 // Intentionally ignore missing module errors
2162 catch (Magick::ErrorModule&)
2163 {
2164 continue;
2165 }
2166 }
2167 coder_list=(char **) MagickCore::RelinquishMagickMemory( coder_list );
2168 ThrowPPException(false);
2169 }
2170
2171 //
2172 // Fill container with color histogram.
2173 // Entries are of type "std::pair<Color,size_t>". Use the pair
2174 // "first" member to access the Color and the "second" member to access
2175 // the number of times the color occurs in the image.
2176 //
2177 // For example:
2178 //
2179 // Using <map>:
2180 //
2181 // Image image("image.miff");
2182 // map<Color,size_t> histogram;
2183 // colorHistogram( &histogram, image );
2184 // std::map<Color,size_t>::const_iterator p=histogram.begin();
2185 // while (p != histogram.end())
2186 // {
2187 // cout << setw(10) << (int)p->second << ": ("
2188 // << setw(quantum_width) << (int)p->first.redQuantum() << ","
2189 // << setw(quantum_width) << (int)p->first.greenQuantum() << ","
2190 // << setw(quantum_width) << (int)p->first.blueQuantum() << ")"
2191 // << endl;
2192 // p++;
2193 // }
2194 //
2195 // Using <vector>:
2196 //
2197 // Image image("image.miff");
2198 // std::vector<std::pair<Color,size_t> > histogram;
2199 // colorHistogram( &histogram, image );
2200 // std::vector<std::pair<Color,size_t> >::const_iterator p=histogram.begin();
2201 // while (p != histogram.end())
2202 // {
2203 // cout << setw(10) << (int)p->second << ": ("
2204 // << setw(quantum_width) << (int)p->first.redQuantum() << ","
2205 // << setw(quantum_width) << (int)p->first.greenQuantum() << ","
2206 // << setw(quantum_width) << (int)p->first.blueQuantum() << ")"
2207 // << endl;
2208 // p++;
2209 // }
2210
2211 template <class Container >
2212 void colorHistogram( Container *histogram_, const Image image)
2213 {
2214 GetPPException;
2215
2216 // Obtain histogram array
2217 size_t colors;
2218 MagickCore::PixelInfo *histogram_array =
2219 MagickCore::GetImageHistogram( image.constImage(), &colors, exceptionInfo );
2220 ThrowPPException(image.quiet());
2221
2222 // Clear out container
2223 histogram_->clear();
2224
2225 // Transfer histogram array to container
2226 for ( size_t i=0; i < colors; i++)
2227 {
2228 histogram_->insert( histogram_->end(), std::pair<const Color,size_t>
2229 ( Color(histogram_array[i]), (size_t) histogram_array[i].count) );
2230 }
2231
2232 // Deallocate histogram array
2233 histogram_array=(MagickCore::PixelInfo *)
2234 MagickCore::RelinquishMagickMemory(histogram_array);
2235 }
2236
2237 // Combines one or more images into a single image. The grayscale value of
2238 // the pixels of each image in the sequence is assigned in order to the
2239 // specified channels of the combined image. The typical ordering would be
2240 // image 1 => Red, 2 => Green, 3 => Blue, etc.
2241 template<class InputIterator >
2242 void combineImages(Image *combinedImage_,InputIterator first_,
2243 InputIterator last_,const ChannelType channel_,
2244 const ColorspaceType colorspace_ = MagickCore::sRGBColorspace)
2245 {
2246 MagickCore::Image
2247 *image;
2248
2249 std::vector<ChannelType>
2250 channelMask;
2251
2252 if (linkImages(first_,last_) == false)
2253 return;
2254 GetPPException;
2255 channelMaskImages(first_,last_,&channelMask,channel_);
2256 image=CombineImages(first_->image(),colorspace_,exceptionInfo);
2257 restoreChannelMaskImages(first_,last_,&channelMask);
2258 unlinkImages(first_,last_);
2259 combinedImage_->replaceImage(image);
2260 ThrowPPException(combinedImage_->quiet());
2261 }
2262
2263 template <class Container>
2264 void cropToTiles(Container *tiledImages_,const Image image_,
2265 const Geometry &geometry_)
2266 {
2267 GetPPException;
2268 MagickCore::Image* images=CropImageToTiles(image_.constImage(),
2269 static_cast<std::string>(geometry_).c_str(),exceptionInfo);
2270 tiledImages_->clear();
2271 insertImages(tiledImages_,images);
2272 ThrowPPException(image_.quiet());
2273 }
2274
2275 // Break down an image sequence into constituent parts. This is
2276 // useful for creating GIF or MNG animation sequences.
2277 template<class InputIterator,class Container>
2278 void deconstructImages(Container *deconstructedImages_,
2279 InputIterator first_,InputIterator last_)
2280 {
2281 bool
2282 quiet;
2283
2284 MagickCore::Image
2285 *images;
2286
2287 if (linkImages(first_,last_) == false)
2288 return;
2289 GetPPException;
2290 quiet=first_->quiet();
2291 images=CompareImagesLayers(first_->image(),CompareAnyLayer,exceptionInfo);
2292 unlinkImages(first_,last_);
2293
2294 deconstructedImages_->clear();
2295 insertImages(deconstructedImages_,images);
2296
2297 ThrowPPException(quiet);
2298 }
2299
2300 //
2301 // Display an image sequence
2302 //
2303 template <class InputIterator>
2304 void displayImages(InputIterator first_,InputIterator last_)
2305 {
2306 if (linkImages(first_,last_) == false)
2307 return;
2308 GetPPException;
2309 MagickCore::DisplayImages(first_->imageInfo(),first_->image(),
2310 exceptionInfo);
2311 unlinkImages(first_,last_);
2312 ThrowPPException(first_->quiet());
2313 }
2314
2315 // Applies a value to the image with an arithmetic, relational,
2316 // or logical operator to an image. Use these operations to lighten or darken
2317 // an image, to increase or decrease contrast in an image, or to produce the
2318 // "negative" of an image.
2319 template <class InputIterator >
2320 void evaluateImages( Image *evaluatedImage_,
2321 InputIterator first_,
2322 InputIterator last_,
2323 const MagickEvaluateOperator operator_ ) {
2324 if (linkImages(first_,last_) == false)
2325 return;
2326 GetPPException;
2327 MagickCore::Image* image = EvaluateImages( first_->image(), operator_, exceptionInfo );
2328 unlinkImages( first_, last_ );
2329 evaluatedImage_->replaceImage( image );
2330 ThrowPPException(evaluatedImage_->quiet());
2331 }
2332
2333 // Merge a sequence of image frames which represent image layers.
2334 // This is useful for combining Photoshop layers into a single image.
2335 template <class InputIterator>
2336 void flattenImages( Image *flattenedImage_,
2337 InputIterator first_,
2338 InputIterator last_ ) {
2339 if (linkImages(first_,last_) == false)
2340 return;
2341 GetPPException;
2342 MagickCore::Image* image = MagickCore::MergeImageLayers( first_->image(),
2343 FlattenLayer,exceptionInfo );
2344 unlinkImages( first_, last_ );
2345 flattenedImage_->replaceImage( image );
2346 ThrowPPException(flattenedImage_->quiet());
2347 }
2348
2349 // Implements the discrete Fourier transform (DFT) of the image either as a
2350 // magnitude / phase or real / imaginary image pair.
2351 template <class Container >
2352 void forwardFourierTransformImage( Container *fourierImages_,
2353 const Image &image_ ) {
2354 GetPPException;
2355
2356 // Build image list
2357 MagickCore::Image* images = ForwardFourierTransformImage(
2358 image_.constImage(), MagickTrue, exceptionInfo);
2359
2360 // Ensure container is empty
2361 fourierImages_->clear();
2362
2363 // Move images to container
2364 insertImages( fourierImages_, images );
2365
2366 // Report any error
2367 ThrowPPException(image_.quiet());
2368 }
2369 template <class Container >
2370 void forwardFourierTransformImage( Container *fourierImages_,
2371 const Image &image_, const bool magnitude_ ) {
2372 GetPPException;
2373
2374 // Build image list
2375 MagickCore::Image* images = ForwardFourierTransformImage(
2376 image_.constImage(), magnitude_ == true ? MagickTrue : MagickFalse,
2377 exceptionInfo);
2378
2379 // Ensure container is empty
2380 fourierImages_->clear();
2381
2382 // Move images to container
2383 insertImages( fourierImages_, images );
2384
2385 // Report any error
2386 ThrowPPException(image_.quiet());
2387 }
2388
2389 // Applies a mathematical expression to a sequence of images.
2390 template <class InputIterator>
2391 void fxImages(Image *fxImage_,InputIterator first_,InputIterator last_,
2392 const std::string expression)
2393 {
2394 MagickCore::Image
2395 *image;
2396
2397 if (linkImages(first_,last_) == false)
2398 return;
2399 GetPPException;
2400 image=FxImage(first_->constImage(),expression.c_str(),exceptionInfo);
2401 unlinkImages(first_,last_);
2402 fxImage_->replaceImage(image);
2403 ThrowPPException(fxImage_->quiet());
2404 }
2405
2406 // Replace the colors of a sequence of images with the closest color
2407 // from a reference image.
2408 // Set dither_ to true to enable dithering. Set measureError_ to
2409 // true in order to evaluate quantization error.
2410 template<class InputIterator>
2411 void mapImages(InputIterator first_,InputIterator last_,
2412 const Image& mapImage_,bool dither_=false,bool measureError_=false)
2413 {
2414 MagickCore::Image
2415 *image;
2416
2417 MagickCore::QuantizeInfo
2418 quantizeInfo;
2419
2420 if (linkImages(first_,last_) == false)
2421 return;
2422 GetPPException;
2423 MagickCore::GetQuantizeInfo(&quantizeInfo);
2424 quantizeInfo.dither_method = dither_ ? MagickCore::RiemersmaDitherMethod :
2425 MagickCore::NoDitherMethod;
2426 MagickCore::RemapImages(&quantizeInfo,first_->image(),
2427 (mapImage_.isValid() ? mapImage_.constImage() :
2428 (const MagickCore::Image*) NULL),exceptionInfo);
2429 unlinkImages(first_,last_);
2430 if (exceptionInfo->severity != MagickCore::UndefinedException)
2431 {
2432 unlinkImages(first_,last_);
2433 throwException(exceptionInfo,mapImage_.quiet());
2434 }
2435
2436 image=first_->image();
2437 while(image != (MagickCore::Image *) NULL)
2438 {
2439 // Calculate quantization error
2440 if (measureError_)
2441 {
2442 MagickCore::GetImageQuantizeError(image,exceptionInfo);
2443 if (exceptionInfo->severity > MagickCore::UndefinedException)
2444 {
2445 unlinkImages(first_,last_);
2446 throwException(exceptionInfo,mapImage_.quiet());
2447 }
2448 }
2449
2450 // Update DirectClass representation of pixels
2451 MagickCore::SyncImage(image,exceptionInfo);
2452 if (exceptionInfo->severity > MagickCore::UndefinedException)
2453 {
2454 unlinkImages(first_,last_);
2455 throwException(exceptionInfo,mapImage_.quiet());
2456 }
2457
2458 // Next image
2459 image=image->next;
2460 }
2461
2462 unlinkImages(first_,last_);
2463 (void) MagickCore::DestroyExceptionInfo(exceptionInfo);
2464 }
2465
2466 // Composes all the image layers from the current given
2467 // image onward to produce a single image of the merged layers.
2468 template <class InputIterator >
2469 void mergeImageLayers( Image *mergedImage_,
2470 InputIterator first_,
2471 InputIterator last_,
2472 const LayerMethod method_ ) {
2473 if (linkImages(first_,last_) == false)
2474 return;
2475 GetPPException;
2476 MagickCore::Image* image = MergeImageLayers( first_->image(), method_, exceptionInfo );
2477 unlinkImages( first_, last_ );
2478 mergedImage_->replaceImage( image );
2479 ThrowPPException(mergedImage_->quiet());
2480 }
2481
2482 // Create a composite image by combining several separate images.
2483 template <class Container, class InputIterator>
2484 void montageImages(Container *montageImages_,InputIterator first_,
2485 InputIterator last_,const Montage &options_)
2486 {
2487 bool
2488 quiet;
2489
2490 MagickCore::Image
2491 *images;
2492
2493 MagickCore::MontageInfo
2494 *montageInfo;
2495
2496 if (linkImages(first_,last_) == false)
2497 return;
2498
2499 montageInfo=static_cast<MagickCore::MontageInfo*>(
2500 MagickCore::AcquireMagickMemory(sizeof(MagickCore::MontageInfo)));
2501
2502 // Update montage options with those set in montageOpts_
2503 options_.updateMontageInfo(*montageInfo);
2504
2505 // Update options which must transfer to image options
2506 if (options_.label().length() != 0)
2507 first_->label(options_.label());
2508
2509 // Do montage
2510 GetPPException;
2511 quiet=first_->quiet();
2512 images=MagickCore::MontageImages(first_->image(),montageInfo,
2513 exceptionInfo);
2514
2515 // Unlink linked image list
2516 unlinkImages(first_,last_);
2517
2518 // Reset output container to pristine state
2519 montageImages_->clear();
2520
2521 if (images != (MagickCore::Image *) NULL)
2522 insertImages(montageImages_,images);
2523
2524 // Clean up any allocated data in montageInfo
2525 MagickCore::DestroyMontageInfo(montageInfo);
2526
2527 // Report any montage error
2528 ThrowPPException(quiet);
2529
2530 // Apply transparency to montage images
2531 if (montageImages_->size() > 0 && options_.transparentColor().isValid())
2532 for_each(montageImages_->begin(),montageImages_->end(),transparentImage(
2533 options_.transparentColor()));
2534 }
2535
2536 // Morph a set of images
2537 template <class InputIterator, class Container >
2538 void morphImages(Container *morphedImages_,InputIterator first_,
2539 InputIterator last_,size_t frames_)
2540 {
2541 bool
2542 quiet;
2543
2544 MagickCore::Image
2545 *images;
2546
2547 if (linkImages(first_,last_) == false)
2548 return;
2549
2550 GetPPException;
2551 quiet=first_->quiet();
2552 images=MagickCore::MorphImages(first_->image(),frames_,exceptionInfo);
2553
2554 // Unlink image list
2555 unlinkImages(first_,last_);
2556
2557 // Ensure container is empty
2558 morphedImages_->clear();
2559
2560 // Move images to container
2561 insertImages(morphedImages_,images);
2562
2563 // Report any error
2564 ThrowPPException(quiet);
2565 }
2566
2567 // Inlay a number of images to form a single coherent picture.
2568 template <class InputIterator>
2569 void mosaicImages( Image *mosaicImage_,
2570 InputIterator first_,
2571 InputIterator last_ ) {
2572 if (linkImages(first_,last_) == false)
2573 return;
2574 GetPPException;
2575 MagickCore::Image* image = MagickCore::MergeImageLayers( first_->image(),
2576 MosaicLayer,exceptionInfo );
2577 unlinkImages( first_, last_ );
2578 mosaicImage_->replaceImage( image );
2579 ThrowPPException(mosaicImage_->quiet());
2580 }
2581
2582 // Compares each image the GIF disposed forms of the previous image in
2583 // the sequence. From this it attempts to select the smallest cropped
2584 // image to replace each frame, while preserving the results of the
2585 // GIF animation.
2586 template <class InputIterator, class Container >
2587 void optimizeImageLayers(Container *optimizedImages_,InputIterator first_,
2588 InputIterator last_)
2589 {
2590 bool
2591 quiet;
2592
2593 MagickCore::Image
2594 *images;
2595
2596 if (linkImages(first_,last_) == false)
2597 return;
2598
2599 GetPPException;
2600 quiet=first_->quiet();
2601 images=OptimizeImageLayers(first_->image(),exceptionInfo);
2602
2603 unlinkImages(first_,last_);
2604
2605 optimizedImages_->clear();
2606
2607 insertImages(optimizedImages_,images);
2608
2609 ThrowPPException(quiet);
2610 }
2611
2612 // optimizeImagePlusLayers is exactly as optimizeImageLayers, but may
2613 // also add or even remove extra frames in the animation, if it improves
2614 // the total number of pixels in the resulting GIF animation.
2615 template <class InputIterator, class Container >
2616 void optimizePlusImageLayers(Container *optimizedImages_,
2617 InputIterator first_,InputIterator last_ )
2618 {
2619 bool
2620 quiet;
2621
2622 MagickCore::Image
2623 *images;
2624
2625 if (linkImages(first_,last_) == false)
2626 return;
2627
2628 GetPPException;
2629 quiet=first_->quiet();
2630 images=OptimizePlusImageLayers(first_->image(),exceptionInfo);
2631
2632 unlinkImages(first_,last_);
2633
2634 optimizedImages_->clear();
2635
2636 insertImages(optimizedImages_,images);
2637
2638 ThrowPPException(quiet);
2639 }
2640
2641 // Compares each image the GIF disposed forms of the previous image in the
2642 // sequence. Any pixel that does not change the displayed result is replaced
2643 // with transparency.
2644 template<class InputIterator>
2645 void optimizeTransparency(InputIterator first_,InputIterator last_)
2646 {
2647 if (linkImages(first_,last_) == false)
2648 return;
2649 GetPPException;
2650 OptimizeImageTransparency(first_->image(),exceptionInfo);
2651 unlinkImages(first_,last_ );
2652
2653 ThrowPPException(first_->quiet());
2654 }
2655
2656 // Ping images into existing container (appending to container)
2657 template<class Container>
2658 void pingImages(Container *sequence_,const std::string &imageSpec_,
2659 ReadOptions &options)
2660 {
2661 options.ping(true);
2662 readImages(sequence_,imageSpec_,options);
2663 }
2664
2665 template<class Container>
2666 void pingImages(Container *sequence_,const std::string &imageSpec_)
2667 {
2668 ReadOptions options;
2669 pingImages(sequence_,imageSpec_,options);
2670 }
2671
2672 template<class Container>
2673 void pingImages(Container *sequence_,const Blob &blob_,ReadOptions &options)
2674 {
2675 options.ping(true);
2676 readImages(sequence_,blob_,options);
2677 }
2678
2679 template<class Container>
2680 void pingImages(Container *sequence_,const Blob &blob_)
2681 {
2682 ReadOptions options;
2683 pingImages(sequence_,blob_,options);
2684 }
2685
2686 // Adds the names of the profiles of the image to the container.
2687 template <class Container>
2688 void profileNames(Container *names_,const Image* image_)
2689 {
2690 const char*
2691 name;
2692
2693 names_->clear();
2694
2695 MagickCore::ResetImageProfileIterator(image_->constImage());
2696 name=MagickCore::GetNextImageProfile(image_->constImage());
2697 while (name != (const char *) NULL)
2698 {
2699 names_->push_back(std::string(name));
2700 name=MagickCore::GetNextImageProfile(image_->constImage());
2701 }
2702 }
2703
2704 // Quantize colors in images using current quantization settings
2705 // Set measureError_ to true in order to measure quantization error
2706 template <class InputIterator>
2707 void quantizeImages(InputIterator first_,InputIterator last_,
2708 bool measureError_ = false)
2709 {
2710 if (linkImages(first_,last_) == false)
2711 return;
2712 GetPPException;
2713 MagickCore::QuantizeImages(first_->quantizeInfo(),first_->image(),
2714 exceptionInfo);
2715 unlinkImages(first_,last_);
2716
2717 MagickCore::Image *image=first_->image();
2718 while (image != (MagickCore::Image *) NULL)
2719 {
2720 // Calculate quantization error
2721 if (measureError_)
2722 MagickCore::GetImageQuantizeError(image,exceptionInfo);
2723
2724 // Update DirectClass representation of pixels
2725 MagickCore::SyncImage(image,exceptionInfo);
2726
2727 image=image->next;
2728 }
2729 unlinkImages(first_,last_);
2730 ThrowPPException(first_->quiet());
2731 }
2732
2733 // Read images into existing container (appending to container)
2734 template<class Container>
2735 void readImages(Container *sequence_,const std::string &imageSpec_,
2736 ReadOptions &options)
2737 {
2738 MagickCore::Image
2739 *images;
2740
2741 MagickCore::ImageInfo
2742 *imageInfo;
2743
2744 imageInfo=options.imageInfo();
2745 imageSpec_.copy(imageInfo->filename,MagickPathExtent-1);
2746 imageInfo->filename[imageSpec_.length()] = 0;
2747 GetPPException;
2748 images=MagickCore::ReadImage(imageInfo,exceptionInfo);
2749 insertImages(sequence_,images);
2750 ThrowPPException(options.quiet());
2751 }
2752
2753 template<class Container>
2754 void readImages(Container *sequence_,const std::string &imageSpec_)
2755 {
2756 ReadOptions options;
2757 readImages(sequence_,imageSpec_,options);
2758 }
2759
2760 template<class Container>
2761 void readImages(Container *sequence_,const Blob &blob_,ReadOptions &options)
2762 {
2763 MagickCore::Image
2764 *images;
2765
2766 GetPPException;
2767 images=MagickCore::BlobToImage(options.imageInfo(),blob_.data(),
2768 blob_.length(),exceptionInfo);
2769 insertImages(sequence_,images);
2770 ThrowPPException(options.quiet());
2771 }
2772
2773 template<class Container>
2774 void readImages(Container *sequence_,const Blob &blob_)
2775 {
2776 ReadOptions options;
2777 readImages(sequence_,blob_,options);
2778 }
2779
2780 // Returns a separate grayscale image for each channel specified.
2781 template<class Container>
2782 void separateImages(Container *separatedImages_,Image &image_,
2783 const ChannelType channel_)
2784 {
2785 MagickCore::ChannelType
2786 channel_mask;
2787
2788 MagickCore::Image
2789 *images;
2790
2791 GetPPException;
2792 channel_mask=MagickCore::SetImageChannelMask(image_.image(),channel_);
2793 images=SeparateImages(image_.constImage(),exceptionInfo);
2794 MagickCore::SetPixelChannelMask(image_.image(),channel_mask);
2795
2796 separatedImages_->clear();
2797 insertImages(separatedImages_,images);
2798
2799 ThrowPPException(image_.quiet());
2800 }
2801
2802 // Smush images from list into single image in either horizontal or
2803 // vertical direction.
2804 template<class InputIterator>
2805 void smushImages(Image *smushedImage_,InputIterator first_,
2806 InputIterator last_,const ssize_t offset_,bool stack_=false)
2807 {
2808 MagickCore::Image
2809 *newImage;
2810
2811 if (linkImages(first_,last_) == false)
2812 return;
2813 GetPPException;
2814 newImage=MagickCore::SmushImages(first_->constImage(),
2815 (MagickBooleanType) stack_,offset_,exceptionInfo);
2816 unlinkImages(first_,last_);
2817 smushedImage_->replaceImage(newImage);
2818 ThrowPPException(smushedImage_->quiet());
2819 }
2820
2821 // Write Images
2822 template <class InputIterator>
2823 void writeImages( InputIterator first_,
2824 InputIterator last_,
2825 const std::string &imageSpec_,
2826 bool adjoin_ = true ) {
2827
2828 if (linkImages(first_,last_) == false)
2829 return;
2830
2831 first_->adjoin( adjoin_ );
2832
2833 GetPPException;
2834 ::ssize_t errorStat = MagickCore::WriteImages( first_->constImageInfo(),
2835 first_->image(),
2836 imageSpec_.c_str(),
2837 exceptionInfo );
2838 unlinkImages( first_, last_ );
2839
2840 if ( errorStat != false )
2841 {
2842 (void) MagickCore::DestroyExceptionInfo( exceptionInfo );
2843 return;
2844 }
2845
2846 ThrowPPException(first_->quiet());
2847 }
2848 // Write images to BLOB
2849 template <class InputIterator>
2850 void writeImages( InputIterator first_,
2851 InputIterator last_,
2852 Blob *blob_,
2853 bool adjoin_ = true) {
2854 if (linkImages(first_,last_) == false)
2855 return;
2856
2857 first_->adjoin( adjoin_ );
2858
2859 GetPPException;
2860 size_t length = 2048; // Efficient size for small images
2861 void* data = MagickCore::ImagesToBlob( first_->imageInfo(),
2862 first_->image(),
2863 &length,
2864 exceptionInfo);
2865 blob_->updateNoCopy( data, length, Magick::Blob::MallocAllocator );
2866
2867 unlinkImages( first_, last_ );
2868
2869 ThrowPPException(first_->quiet());
2870 }
2871
2872} // namespace Magick
2873
2874#endif // Magick_STL_header