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