13ed852eea50f9d4cd633efb8c2b054b8e33c253cristy// This may look like C code, but it is really -*- C++ -*- 23ed852eea50f9d4cd633efb8c2b054b8e33c253cristy// 33ed852eea50f9d4cd633efb8c2b054b8e33c253cristy// Copyright Bob Friesenhahn, 1999, 2000, 2001, 2002, 2003 477328896b876314656427663695bc7b2c9be3f74dirk// Copyright Dirk Lemstra 2013-2015 53ed852eea50f9d4cd633efb8c2b054b8e33c253cristy// 63ed852eea50f9d4cd633efb8c2b054b8e33c253cristy// Pixels Implementation 73ed852eea50f9d4cd633efb8c2b054b8e33c253cristy// 83ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 93ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MAGICKCORE_IMPLEMENTATION 1 103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MAGICK_PLUSPLUS_IMPLEMENTATION 1 113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1205065f4c09f42c5cd3b5720e5b52c0c3928d2b2bcristy#include <cstring> 133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "Magick++/Include.h" 143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include <string> // This is here to compile with Visual C++ 153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "Magick++/Thread.h" 163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "Magick++/Exception.h" 173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "Magick++/Pixels.h" 183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 196f0033cdfd3b04c652521d2ff9c375366972225adirkMagick::Pixels::Pixels(Magick::Image &image_) 203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy : _image(image_), 213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy _x(0), 223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy _y(0), 233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy _columns(0), 243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy _rows(0) 253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 26e31feb8a39ea937a6328da579085cd2ee66ab4c0dirk GetPPException; 2707f84e72b205d18eb8ad35380af95351d9f0a1a3dirk _view=AcquireVirtualCacheView(image_.image(),exceptionInfo), 2877328896b876314656427663695bc7b2c9be3f74dirk ThrowPPException(image_.quiet()); 293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 316f0033cdfd3b04c652521d2ff9c375366972225adirkMagick::Pixels::~Pixels(void) 323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 336f0033cdfd3b04c652521d2ff9c375366972225adirk if (_view) 346f0033cdfd3b04c652521d2ff9c375366972225adirk _view=DestroyCacheView(_view); 353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 376f0033cdfd3b04c652521d2ff9c375366972225adirkMagick::Quantum* Magick::Pixels::get(const ssize_t x_,const ssize_t y_, 386f0033cdfd3b04c652521d2ff9c375366972225adirk const size_t columns_,const size_t rows_) 393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 406f0033cdfd3b04c652521d2ff9c375366972225adirk _x=x_; 416f0033cdfd3b04c652521d2ff9c375366972225adirk _y=y_; 426f0033cdfd3b04c652521d2ff9c375366972225adirk _columns=columns_; 436f0033cdfd3b04c652521d2ff9c375366972225adirk _rows=rows_; 443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 45e31feb8a39ea937a6328da579085cd2ee66ab4c0dirk GetPPException; 466f0033cdfd3b04c652521d2ff9c375366972225adirk Quantum* pixels=GetCacheViewAuthenticPixels(_view,x_,y_,columns_,rows_, 47e31feb8a39ea937a6328da579085cd2ee66ab4c0dirk exceptionInfo); 4807f84e72b205d18eb8ad35380af95351d9f0a1a3dirk ThrowPPException(_image.quiet()); 493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return pixels; 513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 536f0033cdfd3b04c652521d2ff9c375366972225adirkconst Magick::Quantum* Magick::Pixels::getConst(const ssize_t x_, 546f0033cdfd3b04c652521d2ff9c375366972225adirk const ssize_t y_,const size_t columns_,const size_t rows_) 553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 566f0033cdfd3b04c652521d2ff9c375366972225adirk _x=x_; 576f0033cdfd3b04c652521d2ff9c375366972225adirk _y=y_; 586f0033cdfd3b04c652521d2ff9c375366972225adirk _columns=columns_; 596f0033cdfd3b04c652521d2ff9c375366972225adirk _rows=rows_; 603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 61e31feb8a39ea937a6328da579085cd2ee66ab4c0dirk GetPPException; 626f0033cdfd3b04c652521d2ff9c375366972225adirk const Quantum* pixels=GetCacheViewVirtualPixels(_view,x_,y_,columns_,rows_, 63e31feb8a39ea937a6328da579085cd2ee66ab4c0dirk exceptionInfo); 6407f84e72b205d18eb8ad35380af95351d9f0a1a3dirk ThrowPPException(_image.quiet()); 653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 666f0033cdfd3b04c652521d2ff9c375366972225adirk return pixels; 673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 6900bcb8c08b29ab70e1d24a21ccfe8515baa2af6cdirkssize_t Magick::Pixels::offset(PixelChannel channel) const 7000bcb8c08b29ab70e1d24a21ccfe8515baa2af6cdirk{ 7100bcb8c08b29ab70e1d24a21ccfe8515baa2af6cdirk if (_image.constImage()->channel_map[channel].traits == UndefinedPixelTrait) 7200bcb8c08b29ab70e1d24a21ccfe8515baa2af6cdirk return -1; 7300bcb8c08b29ab70e1d24a21ccfe8515baa2af6cdirk return _image.constImage()->channel_map[channel].offset; 7400bcb8c08b29ab70e1d24a21ccfe8515baa2af6cdirk} 7500bcb8c08b29ab70e1d24a21ccfe8515baa2af6cdirk 766f0033cdfd3b04c652521d2ff9c375366972225adirkMagick::Quantum* Magick::Pixels::set(const ssize_t x_,const ssize_t y_, 776f0033cdfd3b04c652521d2ff9c375366972225adirk const size_t columns_,const size_t rows_) 783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 796f0033cdfd3b04c652521d2ff9c375366972225adirk _x=x_; 806f0033cdfd3b04c652521d2ff9c375366972225adirk _y=y_; 816f0033cdfd3b04c652521d2ff9c375366972225adirk _columns=columns_; 826f0033cdfd3b04c652521d2ff9c375366972225adirk _rows=rows_; 836f0033cdfd3b04c652521d2ff9c375366972225adirk 84e31feb8a39ea937a6328da579085cd2ee66ab4c0dirk GetPPException; 856f0033cdfd3b04c652521d2ff9c375366972225adirk Quantum* pixels=QueueCacheViewAuthenticPixels(_view,x_,y_,columns_,rows_, 86e31feb8a39ea937a6328da579085cd2ee66ab4c0dirk exceptionInfo); 8707f84e72b205d18eb8ad35380af95351d9f0a1a3dirk ThrowPPException(_image.quiet()); 886f0033cdfd3b04c652521d2ff9c375366972225adirk 896f0033cdfd3b04c652521d2ff9c375366972225adirk return pixels; 903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 916f0033cdfd3b04c652521d2ff9c375366972225adirk 926f0033cdfd3b04c652521d2ff9c375366972225adirkvoid Magick::Pixels::sync(void) 933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 94e31feb8a39ea937a6328da579085cd2ee66ab4c0dirk GetPPException; 958aebeb37446aee3cd6a9649420bfe2a167bb2de9cristy (void) SyncCacheViewAuthenticPixels(_view,exceptionInfo); 9607f84e72b205d18eb8ad35380af95351d9f0a1a3dirk ThrowPPException(_image.quiet()); 973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy// Return pixel colormap index array 1004c08aed51c5899665ade97263692328eea4af106cristy/* 1016f0033cdfd3b04c652521d2ff9c375366972225adirkMagick::void* Magick::Pixels::metacontent(void) 1023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 1036f0033cdfd3b04c652521d2ff9c375366972225adirk void* pixel_metacontent=GetCacheViewAuthenticMetacontent(_view); 1043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1056f0033cdfd3b04c652521d2ff9c375366972225adirk if (!pixel_metacontent) 1063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy _image.throwImageException(); 1073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1084c08aed51c5899665ade97263692328eea4af106cristy return pixel_metacontent; 1093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 1104c08aed51c5899665ade97263692328eea4af106cristy*/ 111a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk 112a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirkMagick::PixelData::PixelData(Magick::Image &image_,std::string map_, 113a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk const StorageType type_) 114a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk{ 115a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk init(image_,0,0,image_.columns(),image_.rows(),map_,type_); 116a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk} 117a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk 118a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirkMagick::PixelData::PixelData(Magick::Image &image_,const ::ssize_t x_, 119a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk const ::ssize_t y_,const size_t width_,const size_t height_,std::string map_, 120a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk const StorageType type_) 121a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk{ 122a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk init(image_,x_,y_,width_,height_,map_,type_); 123a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk} 124a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk 125a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirkMagick::PixelData::~PixelData(void) 126a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk{ 127a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk relinquish(); 128a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk} 129a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk 130a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirkconst void *Magick::PixelData::data(void) const 131a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk{ 132a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk return(_data); 133a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk} 134a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk 1352a9bf2113bca33b919674599c11805300c7b7a7bdirk::ssize_t Magick::PixelData::length(void) const 136a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk{ 137a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk return(_length); 138a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk} 139a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk 1402a9bf2113bca33b919674599c11805300c7b7a7bdirk::ssize_t Magick::PixelData::size(void) const 141a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk{ 142a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk return(_size); 143a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk} 144a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk 145a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirkvoid Magick::PixelData::init(Magick::Image &image_,const ::ssize_t x_, 146a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk const ::ssize_t y_,const size_t width_,const size_t height_, 147a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk std::string map_,const StorageType type_) 148a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk{ 149a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk size_t 150a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk size; 151a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk 152a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk _data=(void *) NULL; 153a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk _length=0; 154a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk _size=0; 1559bb7c84a6ae3b9a07cf67c2e18d5dce78e75ad31cristy if ((x_ < 0) || (width_ == 0) || (y_ < 0) || (height_ == 0) || 156d9b47c63dc5ef8f7f38d1aa7e012306696f8bf57cristy (x_ > (ssize_t) image_.columns()) || ((width_ + x_) > image_.columns()) 157d9b47c63dc5ef8f7f38d1aa7e012306696f8bf57cristy || (y_ > (ssize_t) image_.rows()) || ((height_ + y_) > image_.rows()) 15898d9f1c5c10b246b0a5cb86c4ae849b45885c7cbdirk || (map_.length() == 0)) 159a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk return; 160a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk 161a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk switch(type_) 162a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk { 163a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk case CharPixel: 164a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk size=sizeof(unsigned char); 165a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk break; 166a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk case DoublePixel: 167a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk size=sizeof(double); 168a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk break; 169a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk case FloatPixel: 170a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk size=sizeof(float); 171a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk break; 172a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk case LongPixel: 173a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk size=sizeof(unsigned int); 174a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk break; 175a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk case LongLongPixel: 176a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk size=sizeof(MagickSizeType); 177a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk break; 178a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk case QuantumPixel: 179a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk size=sizeof(Quantum); 180a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk break; 181a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk case ShortPixel: 182a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk size=sizeof(unsigned short); 183a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk break; 184a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk default: 18577328896b876314656427663695bc7b2c9be3f74dirk throwExceptionExplicit(MagickCore::OptionError,"Invalid type"); 186a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk return; 187a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk } 188a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk 189a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk _length=width_*height_*map_.length(); 190a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk _size=_length*size; 191a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk _data=AcquireMagickMemory(_size); 192a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk 193a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk GetPPException; 194933b13290dde32a0c054340cb1a242564684e0e8dirk MagickCore::ExportImagePixels(image_.image(),x_,y_,width_,height_, 195e31feb8a39ea937a6328da579085cd2ee66ab4c0dirk map_.c_str(),type_,_data,exceptionInfo); 19677328896b876314656427663695bc7b2c9be3f74dirk if (exceptionInfo->severity != MagickCore::UndefinedException) 197a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk relinquish(); 19877328896b876314656427663695bc7b2c9be3f74dirk ThrowPPException(image_.quiet()); 199a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk} 200a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk 201a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirkvoid Magick::PixelData::relinquish(void) throw() 202a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk{ 203a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk if (_data != (void *)NULL) 204a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk _data=RelinquishMagickMemory(_data); 205a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk _length=0; 206a7c1e5c12b9aec82327d2cae6ff71712c4b875d4dirk _size=0; 2079bb7c84a6ae3b9a07cf67c2e18d5dce78e75ad31cristy} 208