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-2015
5 //
6 // Pixels Implementation
7 //
8
9 #define MAGICKCORE_IMPLEMENTATION 1
10 #define MAGICK_PLUSPLUS_IMPLEMENTATION 1
11
12 #include <cstring>
13 #include "Magick++/Include.h"
14 #include <string> // This is here to compile with Visual C++
15 #include "Magick++/Thread.h"
16 #include "Magick++/Exception.h"
17 #include "Magick++/Pixels.h"
18
Pixels(Magick::Image & image_)19 Magick::Pixels::Pixels(Magick::Image &image_)
20 : _image(image_),
21 _x(0),
22 _y(0),
23 _columns(0),
24 _rows(0)
25 {
26 GetPPException;
27 _view=AcquireVirtualCacheView(image_.image(),exceptionInfo),
28 ThrowPPException(image_.quiet());
29 }
30
~Pixels(void)31 Magick::Pixels::~Pixels(void)
32 {
33 if (_view)
34 _view=DestroyCacheView(_view);
35 }
36
get(const ssize_t x_,const ssize_t y_,const size_t columns_,const size_t rows_)37 Magick::Quantum* Magick::Pixels::get(const ssize_t x_,const ssize_t y_,
38 const size_t columns_,const size_t rows_)
39 {
40 _x=x_;
41 _y=y_;
42 _columns=columns_;
43 _rows=rows_;
44
45 GetPPException;
46 Quantum* pixels=GetCacheViewAuthenticPixels(_view,x_,y_,columns_,rows_,
47 exceptionInfo);
48 ThrowPPException(_image.quiet());
49
50 return pixels;
51 }
52
getConst(const ssize_t x_,const ssize_t y_,const size_t columns_,const size_t rows_)53 const Magick::Quantum* Magick::Pixels::getConst(const ssize_t x_,
54 const ssize_t y_,const size_t columns_,const size_t rows_)
55 {
56 _x=x_;
57 _y=y_;
58 _columns=columns_;
59 _rows=rows_;
60
61 GetPPException;
62 const Quantum* pixels=GetCacheViewVirtualPixels(_view,x_,y_,columns_,rows_,
63 exceptionInfo);
64 ThrowPPException(_image.quiet());
65
66 return pixels;
67 }
68
offset(PixelChannel channel) const69 ssize_t Magick::Pixels::offset(PixelChannel channel) const
70 {
71 if (_image.constImage()->channel_map[channel].traits == UndefinedPixelTrait)
72 return -1;
73 return _image.constImage()->channel_map[channel].offset;
74 }
75
set(const ssize_t x_,const ssize_t y_,const size_t columns_,const size_t rows_)76 Magick::Quantum* Magick::Pixels::set(const ssize_t x_,const ssize_t y_,
77 const size_t columns_,const size_t rows_)
78 {
79 _x=x_;
80 _y=y_;
81 _columns=columns_;
82 _rows=rows_;
83
84 GetPPException;
85 Quantum* pixels=QueueCacheViewAuthenticPixels(_view,x_,y_,columns_,rows_,
86 exceptionInfo);
87 ThrowPPException(_image.quiet());
88
89 return pixels;
90 }
91
sync(void)92 void Magick::Pixels::sync(void)
93 {
94 GetPPException;
95 (void) SyncCacheViewAuthenticPixels(_view,exceptionInfo);
96 ThrowPPException(_image.quiet());
97 }
98
99 // Return pixel meta content
metacontent(void)100 void* Magick::Pixels::metacontent(void)
101 {
102 void* pixel_metacontent=GetCacheViewAuthenticMetacontent(_view);
103
104 return pixel_metacontent;
105 }
106
PixelData(Magick::Image & image_,std::string map_,const StorageType type_)107 Magick::PixelData::PixelData(Magick::Image &image_,std::string map_,
108 const StorageType type_)
109 {
110 init(image_,0,0,image_.columns(),image_.rows(),map_,type_);
111 }
112
PixelData(Magick::Image & image_,const::ssize_t x_,const::ssize_t y_,const size_t width_,const size_t height_,std::string map_,const StorageType type_)113 Magick::PixelData::PixelData(Magick::Image &image_,const ::ssize_t x_,
114 const ::ssize_t y_,const size_t width_,const size_t height_,std::string map_,
115 const StorageType type_)
116 {
117 init(image_,x_,y_,width_,height_,map_,type_);
118 }
119
~PixelData(void)120 Magick::PixelData::~PixelData(void)
121 {
122 relinquish();
123 }
124
data(void) const125 const void *Magick::PixelData::data(void) const
126 {
127 return(_data);
128 }
129
length(void) const130 ::ssize_t Magick::PixelData::length(void) const
131 {
132 return(_length);
133 }
134
size(void) const135 ::ssize_t Magick::PixelData::size(void) const
136 {
137 return(_size);
138 }
139
init(Magick::Image & image_,const::ssize_t x_,const::ssize_t y_,const size_t width_,const size_t height_,std::string map_,const StorageType type_)140 void Magick::PixelData::init(Magick::Image &image_,const ::ssize_t x_,
141 const ::ssize_t y_,const size_t width_,const size_t height_,
142 std::string map_,const StorageType type_)
143 {
144 size_t
145 size;
146
147 _data=(void *) NULL;
148 _length=0;
149 _size=0;
150 if ((x_ < 0) || (width_ == 0) || (y_ < 0) || (height_ == 0) ||
151 (x_ > (ssize_t) image_.columns()) || ((width_ + x_) > image_.columns())
152 || (y_ > (ssize_t) image_.rows()) || ((height_ + y_) > image_.rows())
153 || (map_.length() == 0))
154 return;
155
156 switch(type_)
157 {
158 case CharPixel:
159 size=sizeof(unsigned char);
160 break;
161 case DoublePixel:
162 size=sizeof(double);
163 break;
164 case FloatPixel:
165 size=sizeof(float);
166 break;
167 case LongPixel:
168 size=sizeof(unsigned int);
169 break;
170 case LongLongPixel:
171 size=sizeof(MagickSizeType);
172 break;
173 case QuantumPixel:
174 size=sizeof(Quantum);
175 break;
176 case ShortPixel:
177 size=sizeof(unsigned short);
178 break;
179 default:
180 throwExceptionExplicit(MagickCore::OptionError,"Invalid type");
181 return;
182 }
183
184 _length=width_*height_*map_.length();
185 _size=_length*size;
186 _data=AcquireMagickMemory(_size);
187
188 GetPPException;
189 MagickCore::ExportImagePixels(image_.image(),x_,y_,width_,height_,
190 map_.c_str(),type_,_data,exceptionInfo);
191 if (exceptionInfo->severity != MagickCore::UndefinedException)
192 relinquish();
193 ThrowPPException(image_.quiet());
194 }
195
relinquish(void)196 void Magick::PixelData::relinquish(void) throw()
197 {
198 if (_data != (void *)NULL)
199 _data=RelinquishMagickMemory(_data);
200 _length=0;
201 _size=0;
202 }
203