Mercurial > hg > orthanc
comparison Core/FileFormats/PngReader.cpp @ 797:37adac56017a
ImageAccessor abstraction
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 06 May 2014 12:47:26 +0200 |
parents | 2d0a347e8cfc |
children | e1d27ee2114a |
comparison
equal
deleted
inserted
replaced
796:e7b1ca0f1e04 | 797:37adac56017a |
---|---|
129 } | 129 } |
130 } | 130 } |
131 | 131 |
132 PngReader::PngReader() | 132 PngReader::PngReader() |
133 { | 133 { |
134 width_ = 0; | |
135 height_ = 0; | |
136 pitch_ = 0; | |
137 format_ = PixelFormat_Grayscale8; | |
138 } | 134 } |
139 | 135 |
140 void PngReader::Read(PngRabi& rabi) | 136 void PngReader::Read(PngRabi& rabi) |
141 { | 137 { |
142 png_set_sig_bytes(rabi.png_, 8); | 138 png_set_sig_bytes(rabi.png_, 8); |
150 png_get_IHDR(rabi.png_, rabi.info_, | 146 png_get_IHDR(rabi.png_, rabi.info_, |
151 &width, &height, | 147 &width, &height, |
152 &bit_depth, &color_type, &interlace_type, | 148 &bit_depth, &color_type, &interlace_type, |
153 &compression_type, &filter_method); | 149 &compression_type, &filter_method); |
154 | 150 |
151 PixelFormat format; | |
152 unsigned int pitch; | |
153 | |
154 if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth == 8) | |
155 { | |
156 format = PixelFormat_Grayscale8; | |
157 pitch = width; | |
158 } | |
159 else if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth == 16) | |
160 { | |
161 format = PixelFormat_Grayscale16; | |
162 pitch = 2 * width; | |
163 | |
164 if (Toolbox::DetectEndianness() == Endianness_Little) | |
165 { | |
166 png_set_swap(rabi.png_); | |
167 } | |
168 } | |
169 else if (color_type == PNG_COLOR_TYPE_RGB && bit_depth == 8) | |
170 { | |
171 format = PixelFormat_RGB24; | |
172 pitch = 3 * width; | |
173 } | |
174 else | |
175 { | |
176 throw OrthancException(ErrorCode_NotImplemented); | |
177 } | |
178 | |
179 data_.resize(height * pitch); | |
180 | |
181 if (height == 0 || width == 0) | |
182 { | |
183 // Empty image, we are done | |
184 AssignEmpty(format); | |
185 return; | |
186 } | |
187 | |
188 png_read_update_info(rabi.png_, rabi.info_); | |
189 | |
190 std::vector<png_bytep> rows(height); | |
191 for (size_t i = 0; i < height; i++) | |
192 { | |
193 rows[i] = &data_[0] + i * pitch; | |
194 } | |
195 | |
196 png_read_image(rabi.png_, &rows[0]); | |
197 | |
198 AssignReadOnly(format, width, height, pitch, &data_[0]); | |
199 } | |
200 | |
201 void PngReader::ReadFromFile(const char* filename) | |
202 { | |
203 FileRabi f(filename); | |
204 | |
205 char header[8]; | |
206 if (fread(header, 1, 8, f.fp_) != 8) | |
207 { | |
208 throw OrthancException(ErrorCode_BadFileFormat); | |
209 } | |
210 | |
211 CheckHeader(header); | |
212 | |
213 PngRabi rabi; | |
214 | |
215 if (setjmp(png_jmpbuf(rabi.png_))) | |
216 { | |
217 rabi.Destruct(); | |
218 throw OrthancException(ErrorCode_BadFileFormat); | |
219 } | |
220 | |
221 png_init_io(rabi.png_, f.fp_); | |
222 | |
223 Read(rabi); | |
224 } | |
225 | |
226 | |
227 void* ImageAccessor::GetBuffer() | |
228 { | |
229 if (readOnly_) | |
230 { | |
231 throw OrthancException(ErrorCode_ReadOnly); | |
232 } | |
233 | |
234 return buffer_; | |
235 } | |
236 | |
237 | |
238 const void* ImageAccessor::GetConstRow(unsigned int y) const | |
239 { | |
240 if (buffer_ != NULL) | |
241 { | |
242 return reinterpret_cast<const uint8_t*>(buffer_) + y * pitch_; | |
243 } | |
244 else | |
245 { | |
246 return NULL; | |
247 } | |
248 } | |
249 | |
250 | |
251 void* ImageAccessor::GetRow(unsigned int y) | |
252 { | |
253 if (readOnly_) | |
254 { | |
255 throw OrthancException(ErrorCode_ReadOnly); | |
256 } | |
257 | |
258 if (buffer_ != NULL) | |
259 { | |
260 return reinterpret_cast<uint8_t*>(buffer_) + y * pitch_; | |
261 } | |
262 else | |
263 { | |
264 return NULL; | |
265 } | |
266 } | |
267 | |
268 | |
269 void ImageAccessor::AssignEmpty(PixelFormat format) | |
270 { | |
271 readOnly_ = false; | |
272 format_ = format; | |
273 width_ = 0; | |
274 height_ = 0; | |
275 pitch_ = 0; | |
276 buffer_ = NULL; | |
277 } | |
278 | |
279 | |
280 void ImageAccessor::AssignReadOnly(PixelFormat format, | |
281 unsigned int width, | |
282 unsigned int height, | |
283 unsigned int pitch, | |
284 const void *buffer) | |
285 { | |
286 readOnly_ = true; | |
287 format_ = format; | |
155 width_ = width; | 288 width_ = width; |
156 height_ = height; | 289 height_ = height; |
157 | 290 pitch_ = pitch; |
158 if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth == 8) | 291 buffer_ = const_cast<void*>(buffer); |
159 { | 292 } |
160 format_ = PixelFormat_Grayscale8; | 293 |
161 pitch_ = width_; | 294 |
162 } | 295 void ImageAccessor::AssignWritable(PixelFormat format, |
163 else if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth == 16) | 296 unsigned int width, |
164 { | 297 unsigned int height, |
165 format_ = PixelFormat_Grayscale16; | 298 unsigned int pitch, |
166 pitch_ = 2 * width_; | 299 void *buffer) |
167 | 300 { |
168 if (Toolbox::DetectEndianness() == Endianness_Little) | 301 readOnly_ = false; |
169 { | 302 format_ = format; |
170 png_set_swap(rabi.png_); | 303 width_ = width; |
171 } | 304 height_ = height; |
172 } | 305 pitch_ = pitch; |
173 else if (color_type == PNG_COLOR_TYPE_RGB && bit_depth == 8) | 306 buffer_ = buffer; |
174 { | |
175 format_ = PixelFormat_Grayscale8; | |
176 pitch_ = 3 * width_; | |
177 } | |
178 else | |
179 { | |
180 throw OrthancException(ErrorCode_NotImplemented); | |
181 } | |
182 | |
183 buffer_.resize(height_ * pitch_); | |
184 | |
185 if (height_ == 0 || width_ == 0) | |
186 { | |
187 // Empty image, we are done | |
188 return; | |
189 } | |
190 | |
191 png_read_update_info(rabi.png_, rabi.info_); | |
192 | |
193 std::vector<png_bytep> rows(height_); | |
194 for (size_t i = 0; i < height_; i++) | |
195 { | |
196 rows[i] = &buffer_[0] + i * pitch_; | |
197 } | |
198 | |
199 png_read_image(rabi.png_, &rows[0]); | |
200 } | |
201 | |
202 void PngReader::ReadFromFile(const char* filename) | |
203 { | |
204 FileRabi f(filename); | |
205 | |
206 char header[8]; | |
207 if (fread(header, 1, 8, f.fp_) != 8) | |
208 { | |
209 throw OrthancException(ErrorCode_BadFileFormat); | |
210 } | |
211 | |
212 CheckHeader(header); | |
213 | |
214 PngRabi rabi; | |
215 | |
216 if (setjmp(png_jmpbuf(rabi.png_))) | |
217 { | |
218 rabi.Destruct(); | |
219 throw OrthancException(ErrorCode_BadFileFormat); | |
220 } | |
221 | |
222 png_init_io(rabi.png_, f.fp_); | |
223 | |
224 Read(rabi); | |
225 } | 307 } |
226 | 308 |
227 | 309 |
228 | 310 |
229 namespace | 311 namespace |
296 } | 378 } |
297 | 379 |
298 void PngReader::ReadFromMemory(const std::string& buffer) | 380 void PngReader::ReadFromMemory(const std::string& buffer) |
299 { | 381 { |
300 if (buffer.size() != 0) | 382 if (buffer.size() != 0) |
383 { | |
301 ReadFromMemory(&buffer[0], buffer.size()); | 384 ReadFromMemory(&buffer[0], buffer.size()); |
385 } | |
302 else | 386 else |
387 { | |
303 ReadFromMemory(NULL, 0); | 388 ReadFromMemory(NULL, 0); |
389 } | |
304 } | 390 } |
305 } | 391 } |