png++: pixel_buffer.hpp Source File

png++ 0.2.10

pixel_buffer.hpp
Go to the documentation of this file.
1 /*
2 * Copyright (C) 2007,2008 Alex Shulgin
3 *
4 * This file is part of png++ the C++ wrapper for libpng. PNG++ is free
5 * software; the exact copying conditions are as follows:
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * 3. The name of the author may not be used to endorse or promote products
18 * derived from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
23 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
25 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31 #ifndef PNGPP_PIXEL_BUFFER_HPP_INCLUDED
32 #define PNGPP_PIXEL_BUFFER_HPP_INCLUDED
33
34 #include <cassert>
35 #include <cstddef>
36 #include <stdexcept>
37 #include <vector>
38
39 #include "packed_pixel.hpp"
40 #include "gray_pixel.hpp"
41 #include "index_pixel.hpp"
42
43 namespace png
44 {
45
53 template< typename row > class row_traits;
54
58 template< typename pixel,
59 typename row,
60 class traits = row_traits< row > >
61 class basic_pixel_buffer
62 {
63 public:
67 typedef row row_type;
68 typedef row_type& row_access;
69 typedef row_type const& row_const_access;
70 typedef traits row_traits;
71
75 basic_pixel_buffer()
76 : m_width(0),
77 m_height(0)
78 {
79 }
80
84 basic_pixel_buffer(uint_32 width, uint_32 height)
85 : m_width(0),
86 m_height(0)
87 {
88 resize(width, height);
89 }
90
91 uint_32 get_width() const
92 {
93 return m_width;
94 }
95
96 uint_32 get_height() const
97 {
98 return m_height;
99 }
100
107 void resize(uint_32 width, uint_32 height)
108 {
109 m_width = width;
110 m_height = height;
111 m_rows.resize(height);
112 for (typename row_vec::iterator r = m_rows.begin();
113 r != m_rows.end();
114 ++r)
115 {
116 r->resize(width);
117 }
118 }
119
128 row_access get_row(size_t index)
129 {
130 return m_rows.at(index);
131 }
132
139 row_const_access get_row(size_t index) const
140 {
141 return m_rows.at(index);
142 }
143
147 row_access operator[](size_t index)
148 {
149 return m_rows[index];
150 }
151
155 row_const_access operator[](size_t index) const
156 {
157 return m_rows[index];
158 }
159
163 void put_row(size_t index, row_type const& r)
164 {
165 assert(r.size() == m_width);
166 m_rows.at(index) = r;
167 }
168
172 pixel get_pixel(size_t x, size_t y) const
173 {
174 return get_row(y).at(x);
175 }
176
180 void set_pixel(size_t x, size_t y, pixel p)
181 {
182 get_row(y).at(x) = p;
183 }
184
185 protected:
186 uint_32 m_width;
187 uint_32 m_height;
188 typedef std::vector< row_type > row_vec;
189 row_vec m_rows;
190 };
191
195 template< typename pixel >
196 class row_traits< std::vector< pixel > >
197 {
198 public:
202 static pixel* get_data(std::vector< pixel >& vec)
203 {
204 assert(vec.size());
205 return & vec[0];
206 }
207 };
208
212 template< typename pixel >
213 class pixel_buffer
214 : public basic_pixel_buffer< pixel, std::vector< pixel > >
215 {
216 public:
217 pixel_buffer()
218 {
219 }
220
221 pixel_buffer(uint_32 width, uint_32 height)
222 : basic_pixel_buffer< pixel, std::vector< pixel > >(width, height)
223 {
224 }
225 };
226
227 namespace detail
228 {
229
230 template< class pixel, typename reference >
231 class basic_packed_pixel_proxy
232 {
233 public:
234 explicit basic_packed_pixel_proxy(reference ref)
235 : m_ref(ref),
236 m_shift(0)
237 {
238 }
239
240 basic_packed_pixel_proxy(reference ref, size_t index)
241 : m_ref(ref),
242 m_shift(get_shift(index))
243 {
244 }
245
246 operator pixel() const
247 {
248 return pixel((m_ref >> m_shift) & pixel::get_bit_mask());
249 }
250
251 protected:
252 /*
253 * bits: . . .
254 * 1: 7 6 5 4 3 2 1 0
255 * 2: 6 4 2 0
256 * 4: 4 0
257 */
258 static size_t get_shift(size_t index)
259 {
260 int const bits = pixel::get_bit_depth();
261 return (8 - bits) - (index % get_pixels_per_byte()) * bits;
262 }
263
264 static size_t get_pixels_per_byte()
265 {
266 return 8 / pixel::get_bit_depth();
267 }
268
269 reference m_ref;
270 size_t m_shift;
271 };
272
273 template< class pixel >
274 class const_packed_pixel_proxy
275 : public basic_packed_pixel_proxy< pixel, byte const& >
276 {
277 public:
278 const_packed_pixel_proxy(byte const& ref, size_t index)
279 : basic_packed_pixel_proxy< pixel, byte const& >(ref, index)
280 {
281 }
282 };
283
284 template< class pixel >
285 class packed_pixel_proxy
286 : public basic_packed_pixel_proxy< pixel, byte& >
287 {
288 public:
289 typedef basic_packed_pixel_proxy< pixel, byte& > basic_proxy;
290
291 packed_pixel_proxy(byte& ref, size_t index)
292 : basic_proxy(ref, index)
293 {
294 }
295
296 packed_pixel_proxy(packed_pixel_proxy const& other)
297 : basic_proxy(other.m_ref)
298 {
299 this->m_shift = other.m_shift;
300 }
301
302 packed_pixel_proxy& operator=(packed_pixel_proxy const& other)
303 {
304 return *this = static_cast< pixel >(other);
305 }
306
307 template< typename reference >
308 packed_pixel_proxy&
309 operator=(basic_packed_pixel_proxy< pixel, reference > const& other)
310 {
311 return *this = static_cast< pixel >(other);
312 }
313
314 packed_pixel_proxy& operator=(pixel p)
315 {
316 this->m_ref = (this->m_ref
317 & ~(pixel::get_bit_mask() << this->m_shift))
318 | (p << this->m_shift);
319
320 return *this;
321 }
322 };
323
324 } // namespace detail
325
332 template< class pixel >
333 class packed_pixel_row
334 {
335 public:
339 explicit packed_pixel_row(size_t size = 0)
340 {
341 resize(size);
342 }
343
344 size_t size() const
345 {
346 return m_size;
347 }
348
352 void resize(size_t size)
353 {
354 m_vec.resize(size / get_pixels_per_byte()
355 + (size % get_pixels_per_byte() ? 1 : 0));
356 m_size = size;
357 }
358
362 typedef detail::const_packed_pixel_proxy< pixel > const_pixel_proxy;
363
367 typedef detail::packed_pixel_proxy< pixel > pixel_proxy;
368
373 const_pixel_proxy at(size_t index) const
374 {
375 return const_pixel_proxy(m_vec.at(index / get_pixels_per_byte()),
376 index);
377 }
378
383 pixel_proxy at(size_t index)
384 {
385 return pixel_proxy(m_vec.at(index / get_pixels_per_byte()),
386 index);
387 }
388
393 const_pixel_proxy operator[](size_t index) const
394 {
395 return const_pixel_proxy(m_vec[index / get_pixels_per_byte()],
396 index);
397 }
398
403 pixel_proxy operator[](size_t index)
404 {
405 return pixel_proxy(m_vec[index / get_pixels_per_byte()],
406 index);
407 }
408
412 byte* get_data()
413 {
414 assert(m_vec.size());
415 return & m_vec[0];
416 }
417
418 private:
419 static size_t get_pixels_per_byte()
420 {
421 return 8 / pixel::get_bit_depth();
422 }
423
424 std::vector< byte > m_vec;
425 size_t m_size;
426 };
427
432 template< typename pixel >
433 class row_traits< packed_pixel_row< pixel > >
434 {
435 public:
439 static byte* get_data(packed_pixel_row< pixel >& row)
440 {
441 return row.get_data();
442 }
443 };
444
449 template< int bits >
450 class pixel_buffer< packed_gray_pixel< bits > >
451 : public basic_pixel_buffer< packed_gray_pixel< bits >,
452 packed_pixel_row< packed_gray_pixel
453 < bits > > >
454 {
455 public:
456 typedef packed_gray_pixel< bits > pixel_type;
457 typedef packed_pixel_row< pixel_type > pixel_row_type;
458
459 pixel_buffer()
460 {
461 }
462
463 pixel_buffer(uint_32 width, uint_32 height)
464 : basic_pixel_buffer< pixel_type,
465 pixel_row_type >(width, height)
466 {
467 }
468 };
469
474 template< int bits >
475 class pixel_buffer< packed_index_pixel< bits > >
476 : public basic_pixel_buffer< packed_index_pixel< bits >,
477 packed_pixel_row< packed_index_pixel
478 < bits > > >
479 {
480 public:
481 typedef packed_index_pixel< bits > pixel_type;
482 typedef packed_pixel_row< pixel_type > pixel_row_type;
483
484 pixel_buffer()
485 {
486 }
487
488 pixel_buffer(uint_32 width, uint_32 height)
489 : basic_pixel_buffer< pixel_type,
490 pixel_row_type >(width, height)
491 {
492 }
493 };
494
495 } // namespace png
496
497 #endif // PNGPP_PIXEL_BUFFER_HPP_INCLUDED
png::basic_pixel_buffer::operator[]
row_const_access operator[](size_t index) const
The non-checking version of get_row() method.
Definition: pixel_buffer.hpp:155
png::packed_pixel_row::at
const_pixel_proxy at(size_t index) const
Returns an immutable proxy the to the pixel at index.
Definition: pixel_buffer.hpp:373
gray_pixel.hpp
png::row_traits
The pixel row traits class template. Provides a common way to get starting address of the row for pac...
Definition: pixel_buffer.hpp:53
png::basic_pixel_buffer::basic_pixel_buffer
basic_pixel_buffer()
Constructs an empty 0x0 pixel buffer object.
Definition: pixel_buffer.hpp:75
png::packed_pixel_row::const_pixel_proxy
detail::const_packed_pixel_proxy< pixel > const_pixel_proxy
The immutable packed pixel proxy type.
Definition: pixel_buffer.hpp:362
png::detail::packed_pixel_proxy::operator=
packed_pixel_proxy & operator=(pixel p)
Definition: pixel_buffer.hpp:314
png::basic_pixel_buffer::m_rows
row_vec m_rows
Definition: pixel_buffer.hpp:189
png::basic_pixel_buffer::set_pixel
void set_pixel(size_t x, size_t y, pixel p)
Replaces a pixel at (x,y) position.
Definition: pixel_buffer.hpp:180
png::packed_pixel_row::pixel_proxy
detail::packed_pixel_proxy< pixel > pixel_proxy
The mutable packed pixel proxy type.
Definition: pixel_buffer.hpp:367
png::basic_pixel_buffer::basic_pixel_buffer
basic_pixel_buffer(uint_32 width, uint_32 height)
Constructs an empty pixel buffer object.
Definition: pixel_buffer.hpp:84
png::packed_pixel_row::operator[]
pixel_proxy operator[](size_t index)
Returns n mutable proxy the to the pixel at index. The non-checking version.
Definition: pixel_buffer.hpp:403
png::row_traits< packed_pixel_row< pixel > >::get_data
static byte * get_data(packed_pixel_row< pixel > &row)
Returns the starting address of the row.
Definition: pixel_buffer.hpp:439
png::detail::const_packed_pixel_proxy
Definition: pixel_buffer.hpp:274
png::packed_pixel_row::size
size_t size() const
Definition: pixel_buffer.hpp:344
png::detail::basic_packed_pixel_proxy::m_ref
reference m_ref
Definition: pixel_buffer.hpp:269
png::basic_pixel_buffer::get_height
uint_32 get_height() const
Definition: pixel_buffer.hpp:96
png::basic_pixel_buffer::row_const_access
row_type const & row_const_access
Definition: pixel_buffer.hpp:69
png::basic_pixel_buffer::get_row
row_const_access get_row(size_t index) const
Returns a const reference to the row of image data at specified index.
Definition: pixel_buffer.hpp:139
png::detail::packed_pixel_proxy::operator=
packed_pixel_proxy & operator=(basic_packed_pixel_proxy< pixel, reference > const &other)
Definition: pixel_buffer.hpp:309
png::basic_pixel_buffer::operator[]
row_access operator[](size_t index)
The non-checking version of get_row() method.
Definition: pixel_buffer.hpp:147
png::pixel_buffer
Definition: pixel_buffer.hpp:213
png::packed_pixel_row::get_data
byte * get_data()
Returns the starting address of the row.
Definition: pixel_buffer.hpp:412
png::basic_pixel_buffer::get_width
uint_32 get_width() const
Definition: pixel_buffer.hpp:91
index_pixel.hpp
png::basic_pixel_buffer::row_vec
std::vector< row_type > row_vec
Definition: pixel_buffer.hpp:188
png::packed_pixel_row::packed_pixel_row
packed_pixel_row(size_t size=0)
Constructs a pixel row object for size packed pixels.
Definition: pixel_buffer.hpp:339
png::detail::basic_packed_pixel_proxy::m_shift
size_t m_shift
Definition: pixel_buffer.hpp:270
png::detail::basic_packed_pixel_proxy::basic_packed_pixel_proxy
basic_packed_pixel_proxy(reference ref, size_t index)
Definition: pixel_buffer.hpp:240
packed_pixel.hpp
png::basic_pixel_buffer::m_height
uint_32 m_height
Definition: pixel_buffer.hpp:187
png::pixel_buffer::pixel_buffer
pixel_buffer(uint_32 width, uint_32 height)
Definition: pixel_buffer.hpp:221
png::detail::const_packed_pixel_proxy::const_packed_pixel_proxy
const_packed_pixel_proxy(byte const &ref, size_t index)
Definition: pixel_buffer.hpp:278
png::basic_pixel_buffer::get_row
row_access get_row(size_t index)
Returns a reference to the row of image data at specified index.
Definition: pixel_buffer.hpp:128
png::basic_pixel_buffer::get_pixel
pixel get_pixel(size_t x, size_t y) const
Returns a pixel at (x,y) position.
Definition: pixel_buffer.hpp:172
png::detail::packed_pixel_proxy::operator=
packed_pixel_proxy & operator=(packed_pixel_proxy const &other)
Definition: pixel_buffer.hpp:302
png::pixel_buffer< packed_gray_pixel< bits > >::pixel_buffer
pixel_buffer()
Definition: pixel_buffer.hpp:459
png::uint_32
png_uint_32 uint_32
Definition: types.hpp:41
png::detail::basic_packed_pixel_proxy::get_shift
static size_t get_shift(size_t index)
Definition: pixel_buffer.hpp:258
png::byte
png_byte byte
Definition: types.hpp:39
png::basic_pixel_buffer::row_access
row_type & row_access
Definition: pixel_buffer.hpp:68
png::detail::basic_packed_pixel_proxy
Definition: pixel_buffer.hpp:231
png::basic_pixel_buffer
The basic class template to represent image pixel data.
Definition: pixel_buffer.hpp:61
png::packed_pixel_row::operator[]
const_pixel_proxy operator[](size_t index) const
Returns an immutable proxy the to the pixel at index. The non-checking version.
Definition: pixel_buffer.hpp:393
png::basic_pixel_buffer::row_type
row row_type
A row of pixel data.
Definition: pixel_buffer.hpp:67
png::packed_pixel_row::at
pixel_proxy at(size_t index)
Returns a mutable proxy the to the pixel at index.
Definition: pixel_buffer.hpp:383
png::basic_pixel_buffer::resize
void resize(uint_32 width, uint_32 height)
Resizes the pixel buffer.
Definition: pixel_buffer.hpp:107
png::pixel_buffer< packed_index_pixel< bits > >::pixel_row_type
packed_pixel_row< pixel_type > pixel_row_type
Definition: pixel_buffer.hpp:482
png::row_traits< std::vector< pixel > >::get_data
static pixel * get_data(std::vector< pixel > &vec)
Returns the starting address of the row.
Definition: pixel_buffer.hpp:202
png::packed_pixel_row
The packed pixel row class template.
Definition: pixel_buffer.hpp:333
png::detail::packed_pixel_proxy
Definition: pixel_buffer.hpp:285
png::basic_pixel_buffer::m_width
uint_32 m_width
Definition: pixel_buffer.hpp:186
png::pixel_buffer::pixel_buffer
pixel_buffer()
Definition: pixel_buffer.hpp:217
png::packed_index_pixel
The packed indexed pixel class template. The available specializations are for 1-,...
Definition: index_pixel.hpp:66
png::pixel_buffer< packed_index_pixel< bits > >::pixel_type
packed_index_pixel< bits > pixel_type
Definition: pixel_buffer.hpp:481
png::pixel_buffer< packed_gray_pixel< bits > >::pixel_row_type
packed_pixel_row< pixel_type > pixel_row_type
Definition: pixel_buffer.hpp:457
png::pixel_buffer< packed_gray_pixel< bits > >::pixel_buffer
pixel_buffer(uint_32 width, uint_32 height)
Definition: pixel_buffer.hpp:463
png::detail::packed_pixel_proxy::basic_proxy
basic_packed_pixel_proxy< pixel, byte & > basic_proxy
Definition: pixel_buffer.hpp:289
png::pixel_buffer< packed_gray_pixel< bits > >::pixel_type
packed_gray_pixel< bits > pixel_type
Definition: pixel_buffer.hpp:456
png
Definition: color.hpp:36
png::basic_pixel_buffer::row_traits
traits row_traits
Definition: pixel_buffer.hpp:70
png::packed_pixel_row::resize
void resize(size_t size)
Resizes the pixel row to hold up to size packed pixels.
Definition: pixel_buffer.hpp:352
png::detail::basic_packed_pixel_proxy::get_pixels_per_byte
static size_t get_pixels_per_byte()
Definition: pixel_buffer.hpp:264
png::detail::packed_pixel_proxy::packed_pixel_proxy
packed_pixel_proxy(packed_pixel_proxy const &other)
Definition: pixel_buffer.hpp:296
png::packed_gray_pixel
The packed gray pixel class template. The available specializations are for 1-, 2- and 4-bit pixels.
Definition: gray_pixel.hpp:56
png::pixel_buffer< packed_index_pixel< bits > >::pixel_buffer
pixel_buffer()
Definition: pixel_buffer.hpp:484
png::detail::basic_packed_pixel_proxy::basic_packed_pixel_proxy
basic_packed_pixel_proxy(reference ref)
Definition: pixel_buffer.hpp:234
png::basic_pixel_buffer::put_row
void put_row(size_t index, row_type const &r)
Replaces the row at specified index.
Definition: pixel_buffer.hpp:163
png::pixel_buffer< packed_index_pixel< bits > >::pixel_buffer
pixel_buffer(uint_32 width, uint_32 height)
Definition: pixel_buffer.hpp:488
png::detail::packed_pixel_proxy::packed_pixel_proxy
packed_pixel_proxy(byte &ref, size_t index)
Definition: pixel_buffer.hpp:291