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