png++  0.2.7
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 > >
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 
76  : m_width(0),
77  m_height(0)
78  {
79  }
80 
84  basic_pixel_buffer(size_t width, size_t height)
85  : m_width(0),
86  m_height(0)
87  {
88  resize(width, height);
89  }
90 
91  size_t get_width() const
92  {
93  return m_width;
94  }
95 
96  size_t get_height() const
97  {
98  return m_height;
99  }
100 
107  void resize(size_t width, size_t 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  size_t m_width;
187  size_t 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 >
214  : public basic_pixel_buffer< pixel, std::vector< pixel > >
215  {
216  public:
218  {
219  }
220 
221  pixel_buffer(size_t width, size_t 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 >
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  size_t 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 >
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 >
286  : public basic_packed_pixel_proxy< pixel, byte& >
287  {
288  public:
290 
291  packed_pixel_proxy(byte& ref, size_t index)
292  : basic_proxy(ref, index)
293  {
294  }
295 
297  : basic_proxy(other.m_ref)
298  {
299  this->m_shift = other.m_shift;
300  }
301 
303  {
304  return *this = static_cast< pixel >(other);
305  }
306 
307  template< typename reference >
310  {
311  return *this = static_cast< pixel >(other);
312  }
313 
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 >
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 
363 
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 
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:
440  {
441  return row.get_data();
442  }
443  };
444 
449  template< size_t bits >
451  : public basic_pixel_buffer< packed_gray_pixel< bits >,
452  packed_pixel_row< packed_gray_pixel
453  < bits > > >
454  {
455  public:
458 
460  {
461  }
462 
463  pixel_buffer(size_t width, size_t height)
464  : basic_pixel_buffer< pixel_type,
465  pixel_row_type >(width, height)
466  {
467  }
468  };
469 
474  template< size_t bits >
476  : public basic_pixel_buffer< packed_index_pixel< bits >,
477  packed_pixel_row< packed_index_pixel
478  < bits > > >
479  {
480  public:
483 
485  {
486  }
487 
488  pixel_buffer(size_t width, size_t 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
basic_pixel_buffer()
Constructs an empty 0x0 pixel buffer object.
Definition: pixel_buffer.hpp:75
detail::const_packed_pixel_proxy< pixel > const_pixel_proxy
The immutable packed pixel proxy type.
Definition: pixel_buffer.hpp:362
packed_pixel_proxy & operator=(pixel p)
Definition: pixel_buffer.hpp:314
row_vec m_rows
Definition: pixel_buffer.hpp:189
void set_pixel(size_t x, size_t y, pixel p)
Replaces a pixel at (x,y) position.
Definition: pixel_buffer.hpp:180
detail::packed_pixel_proxy< pixel > pixel_proxy
The mutable packed pixel proxy type.
Definition: pixel_buffer.hpp:367
size_t size() const
Definition: pixel_buffer.hpp:344
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
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
static byte * get_data(packed_pixel_row< pixel > &row)
Returns the starting address of the row.
Definition: pixel_buffer.hpp:439
const_pixel_proxy at(size_t index) const
Returns an immutable proxy the to the pixel at index.
Definition: pixel_buffer.hpp:373
Definition: pixel_buffer.hpp:274
reference m_ref
Definition: pixel_buffer.hpp:269
row_type const & row_const_access
Definition: pixel_buffer.hpp:69
packed_pixel_proxy & operator=(basic_packed_pixel_proxy< pixel, reference > const &other)
Definition: pixel_buffer.hpp:309
row_access operator[](size_t index)
The non-checking version of get_row() method.
Definition: pixel_buffer.hpp:147
Definition: pixel_buffer.hpp:213
byte * get_data()
Returns the starting address of the row.
Definition: pixel_buffer.hpp:412
size_t get_height() const
Definition: pixel_buffer.hpp:96
size_t get_width() const
Definition: pixel_buffer.hpp:91
pixel_buffer(size_t width, size_t height)
Definition: pixel_buffer.hpp:221
std::vector< row_type > row_vec
Definition: pixel_buffer.hpp:188
size_t m_width
Definition: pixel_buffer.hpp:186
packed_pixel_row(size_t size=0)
Constructs a pixel row object for size packed pixels.
Definition: pixel_buffer.hpp:339
size_t m_shift
Definition: pixel_buffer.hpp:270
basic_packed_pixel_proxy(reference ref, size_t index)
Definition: pixel_buffer.hpp:240
const_packed_pixel_proxy(byte const &ref, size_t index)
Definition: pixel_buffer.hpp:278
row_access get_row(size_t index)
Returns a reference to the row of image data at specified index.
Definition: pixel_buffer.hpp:128
packed_pixel_proxy & operator=(packed_pixel_proxy const &other)
Definition: pixel_buffer.hpp:302
pixel_buffer()
Definition: pixel_buffer.hpp:459
static size_t get_shift(size_t index)
Definition: pixel_buffer.hpp:258
png_byte byte
Definition: types.hpp:39
row_type & row_access
Definition: pixel_buffer.hpp:68
row_const_access operator[](size_t index) const
The non-checking version of get_row() method.
Definition: pixel_buffer.hpp:155
Definition: pixel_buffer.hpp:231
pixel_buffer(size_t width, size_t height)
Definition: pixel_buffer.hpp:463
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
The basic class template to represent image pixel data.
Definition: pixel_buffer.hpp:61
row row_type
A row of pixel data.
Definition: pixel_buffer.hpp:67
pixel_buffer(size_t width, size_t height)
Definition: pixel_buffer.hpp:488
pixel_proxy at(size_t index)
Returns a mutable proxy the to the pixel at index.
Definition: pixel_buffer.hpp:383
pixel get_pixel(size_t x, size_t y) const
Returns a pixel at (x,y) position.
Definition: pixel_buffer.hpp:172
void resize(size_t width, size_t height)
Resizes the pixel buffer.
Definition: pixel_buffer.hpp:107
packed_pixel_row< pixel_type > pixel_row_type
Definition: pixel_buffer.hpp:482
static pixel * get_data(std::vector< pixel > &vec)
Returns the starting address of the row.
Definition: pixel_buffer.hpp:202
The pixel row traits class template. Provides a common way to get starting address of the row for pac...
Definition: pixel_buffer.hpp:53
The packed pixel row class template.
Definition: pixel_buffer.hpp:333
Definition: pixel_buffer.hpp:285
pixel_buffer()
Definition: pixel_buffer.hpp:217
The packed indexed pixel class template. The available specializations are for 1-, 2- and 4-bit pixels.
Definition: index_pixel.hpp:66
packed_index_pixel< bits > pixel_type
Definition: pixel_buffer.hpp:481
packed_pixel_row< pixel_type > pixel_row_type
Definition: pixel_buffer.hpp:457
basic_packed_pixel_proxy< pixel, byte & > basic_proxy
Definition: pixel_buffer.hpp:289
packed_gray_pixel< bits > pixel_type
Definition: pixel_buffer.hpp:456
basic_pixel_buffer(size_t width, size_t height)
Constructs an empty pixel buffer object.
Definition: pixel_buffer.hpp:84
Definition: color.hpp:36
traits row_traits
Definition: pixel_buffer.hpp:70
void resize(size_t size)
Resizes the pixel row to hold up to size packed pixels.
Definition: pixel_buffer.hpp:352
static size_t get_pixels_per_byte()
Definition: pixel_buffer.hpp:264
packed_pixel_proxy(packed_pixel_proxy const &other)
Definition: pixel_buffer.hpp:296
size_t m_height
Definition: pixel_buffer.hpp:187
The packed gray pixel class template. The available specializations are for 1-, 2- and 4-bit pixels...
Definition: gray_pixel.hpp:56
pixel_buffer()
Definition: pixel_buffer.hpp:484
basic_packed_pixel_proxy(reference ref)
Definition: pixel_buffer.hpp:234
void put_row(size_t index, row_type const &r)
Replaces the row at specified index.
Definition: pixel_buffer.hpp:163
packed_pixel_proxy(byte &ref, size_t index)
Definition: pixel_buffer.hpp:291