png++  0.2.1
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 traits row_traits;
69 
74  : m_width(0),
75  m_height(0)
76  {
77  }
78 
82  basic_pixel_buffer(size_t width, size_t height)
83  : m_width(0),
84  m_height(0)
85  {
86  resize(width, height);
87  }
88 
89  size_t get_width() const
90  {
91  return m_width;
92  }
93 
94  size_t get_height() const
95  {
96  return m_height;
97  }
98 
105  void resize(size_t width, size_t height)
106  {
107  m_width = width;
108  m_height = height;
109  m_rows.resize(height);
110  for (typename row_vec::iterator r = m_rows.begin();
111  r != m_rows.end();
112  ++r)
113  {
114  r->resize(width);
115  }
116  }
117 
126  row_type& get_row(size_t index)
127  {
128  return m_rows.at(index);
129  }
130 
137  row_type const& get_row(size_t index) const
138  {
139  return m_rows.at(index);
140  }
141 
145  row_type& operator[](size_t index)
146  {
147  return m_rows[index];
148  }
149 
153  row_type const& operator[](size_t index) const
154  {
155  return m_rows[index];
156  }
157 
161  void put_row(size_t index, row_type const& r)
162  {
163  assert(r.size() == m_width);
164  m_rows.at(index) = r;
165  }
166 
170  pixel get_pixel(size_t x, size_t y) const
171  {
172  return get_row(y).at(x);
173  }
174 
178  void set_pixel(size_t x, size_t y, pixel p)
179  {
180  get_row(y).at(x) = p;
181  }
182 
183  protected:
184  size_t m_width;
185  size_t m_height;
186  typedef std::vector< row_type > row_vec;
187  row_vec m_rows;
188  };
189 
193  template< typename pixel >
194  class row_traits< std::vector< pixel > >
195  {
196  public:
200  static pixel* get_data(std::vector< pixel >& vec)
201  {
202  assert(vec.size());
203  return & vec[0];
204  }
205  };
206 
210  template< typename pixel >
212  : public basic_pixel_buffer< pixel, std::vector< pixel > >
213  {
214  public:
216  {
217  }
218 
219  pixel_buffer(size_t width, size_t height)
220  : basic_pixel_buffer< pixel, std::vector< pixel > >(width, height)
221  {
222  }
223  };
224 
225  namespace detail
226  {
227 
228  template< class pixel, typename reference >
230  {
231  public:
232  explicit basic_packed_pixel_proxy(reference ref)
233  : m_ref(ref),
234  m_shift(0)
235  {
236  }
237 
238  basic_packed_pixel_proxy(reference ref, size_t index)
239  : m_ref(ref),
240  m_shift(get_shift(index))
241  {
242  }
243 
244  operator pixel() const
245  {
246  return pixel((m_ref >> m_shift) & pixel::get_bit_mask());
247  }
248 
249  protected:
250  /*
251  * bits: . . .
252  * 1: 7 6 5 4 3 2 1 0
253  * 2: 6 4 2 0
254  * 4: 4 0
255  */
256  static size_t get_shift(size_t index)
257  {
258  size_t const bits = pixel::get_bit_depth();
259  return (8 - bits) - (index % get_pixels_per_byte()) * bits;
260  }
261 
262  static size_t get_pixels_per_byte()
263  {
264  return 8 / pixel::get_bit_depth();
265  }
266 
267  reference m_ref;
268  size_t m_shift;
269  };
270 
271  template< class pixel >
273  : public basic_packed_pixel_proxy< pixel, byte const& >
274  {
275  public:
276  const_packed_pixel_proxy(byte const& ref, size_t index)
277  : basic_packed_pixel_proxy< pixel, byte const& >(ref, index)
278  {
279  }
280  };
281 
282  template< class pixel >
284  : public basic_packed_pixel_proxy< pixel, byte& >
285  {
286  public:
288 
289  packed_pixel_proxy(byte& ref, size_t index)
290  : basic_proxy(ref, index)
291  {
292  }
293 
295  : basic_proxy(other.m_ref)
296  {
297  this->m_shift = other.m_shift;
298  }
299 
301  {
302  return *this = static_cast< pixel >(other);
303  }
304 
305  template< typename reference >
308  {
309  return *this = static_cast< pixel >(other);
310  }
311 
313  {
314  this->m_ref = (this->m_ref
315  & ~(pixel::get_bit_mask() << this->m_shift))
316  | (p << this->m_shift);
317 
318  return *this;
319  }
320  };
321 
322  } // namespace detail
323 
330  template< class pixel >
332  {
333  public:
337  explicit packed_pixel_row(size_t size = 0)
338  {
339  resize(size);
340  }
341 
342  size_t size() const
343  {
344  return m_size;
345  }
346 
350  void resize(size_t size)
351  {
352  m_vec.resize(size / get_pixels_per_byte()
353  + (size % get_pixels_per_byte() ? 1 : 0));
354  m_size = size;
355  }
356 
361 
366 
371  const_pixel_proxy at(size_t index) const
372  {
373  return const_pixel_proxy(m_vec.at(index / get_pixels_per_byte()),
374  index);
375  }
376 
381  pixel_proxy at(size_t index)
382  {
383  return pixel_proxy(m_vec.at(index / get_pixels_per_byte()),
384  index);
385  }
386 
391  const_pixel_proxy operator[](size_t index) const
392  {
393  return const_pixel_proxy(m_vec[index / get_pixels_per_byte()],
394  index);
395  }
396 
401  pixel_proxy operator[](size_t index)
402  {
403  return pixel_proxy(m_vec[index / get_pixels_per_byte()],
404  index);
405  }
406 
411  {
412  assert(m_vec.size());
413  return & m_vec[0];
414  }
415 
416  private:
417  static size_t get_pixels_per_byte()
418  {
419  return 8 / pixel::get_bit_depth();
420  }
421 
422  std::vector< byte > m_vec;
423  size_t m_size;
424  };
425 
430  template< typename pixel >
431  class row_traits< packed_pixel_row< pixel > >
432  {
433  public:
438  {
439  return row.get_data();
440  }
441  };
442 
447  template< size_t bits >
449  : public basic_pixel_buffer< packed_gray_pixel< bits >,
450  packed_pixel_row< packed_gray_pixel
451  < bits > > >
452  {
453  public:
456 
458  {
459  }
460 
461  pixel_buffer(size_t width, size_t height)
462  : basic_pixel_buffer< pixel_type,
463  pixel_row_type >(width, height)
464  {
465  }
466  };
467 
472  template< size_t bits >
474  : public basic_pixel_buffer< packed_index_pixel< bits >,
475  packed_pixel_row< packed_index_pixel
476  < bits > > >
477  {
478  public:
481 
483  {
484  }
485 
486  pixel_buffer(size_t width, size_t height)
487  : basic_pixel_buffer< pixel_type,
488  pixel_row_type >(width, height)
489  {
490  }
491  };
492 
493 } // namespace png
494 
495 #endif // PNGPP_PIXEL_BUFFER_HPP_INCLUDED
The pixel row traits class template. Provides a common way to get starting address of the row for pac...
Definition: pixel_buffer.hpp:53
basic_pixel_buffer()
Constructs an empty 0x0 pixel buffer object.
Definition: pixel_buffer.hpp:73
detail::const_packed_pixel_proxy< pixel > const_pixel_proxy
The immutable packed pixel proxy type.
Definition: pixel_buffer.hpp:360
packed_pixel_proxy & operator=(pixel p)
Definition: pixel_buffer.hpp:312
row_vec m_rows
Definition: pixel_buffer.hpp:187
void set_pixel(size_t x, size_t y, pixel p)
Replaces a pixel at (x,y) position.
Definition: pixel_buffer.hpp:178
detail::packed_pixel_proxy< pixel > pixel_proxy
The mutable packed pixel proxy type.
Definition: pixel_buffer.hpp:365
size_t size() const
Definition: pixel_buffer.hpp:342
pixel_proxy operator[](size_t index)
Returns n mutable proxy the to the pixel at index. The non-checking version.
Definition: pixel_buffer.hpp:401
static byte * get_data(packed_pixel_row< pixel > &row)
Returns the starting address of the row.
Definition: pixel_buffer.hpp:437
const_pixel_proxy at(size_t index) const
Returns an immutable proxy the to the pixel at index.
Definition: pixel_buffer.hpp:371
Definition: pixel_buffer.hpp:272
reference m_ref
Definition: pixel_buffer.hpp:267
packed_pixel_proxy & operator=(basic_packed_pixel_proxy< pixel, reference > const &other)
Definition: pixel_buffer.hpp:307
Definition: pixel_buffer.hpp:211
byte * get_data()
Returns the starting address of the row.
Definition: pixel_buffer.hpp:410
size_t get_height() const
Definition: pixel_buffer.hpp:94
size_t get_width() const
Definition: pixel_buffer.hpp:89
pixel_buffer(size_t width, size_t height)
Definition: pixel_buffer.hpp:219
std::vector< row_type > row_vec
Definition: pixel_buffer.hpp:186
size_t m_width
Definition: pixel_buffer.hpp:184
row_type const & operator[](size_t index) const
The non-checking version of get_row() method.
Definition: pixel_buffer.hpp:153
row_type const & get_row(size_t index) const
Returns a const reference to the row of image data at specified index.
Definition: pixel_buffer.hpp:137
packed_pixel_row(size_t size=0)
Constructs a pixel row object for size packed pixels.
Definition: pixel_buffer.hpp:337
size_t m_shift
Definition: pixel_buffer.hpp:268
basic_packed_pixel_proxy(reference ref, size_t index)
Definition: pixel_buffer.hpp:238
row_type & get_row(size_t index)
Returns a reference to the row of image data at specified index.
Definition: pixel_buffer.hpp:126
const_packed_pixel_proxy(byte const &ref, size_t index)
Definition: pixel_buffer.hpp:276
packed_pixel_proxy & operator=(packed_pixel_proxy const &other)
Definition: pixel_buffer.hpp:300
pixel_buffer()
Definition: pixel_buffer.hpp:457
static size_t get_shift(size_t index)
Definition: pixel_buffer.hpp:256
png_byte byte
Definition: types.hpp:39
Definition: pixel_buffer.hpp:229
pixel_buffer(size_t width, size_t height)
Definition: pixel_buffer.hpp:461
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:391
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:486
pixel_proxy at(size_t index)
Returns a mutable proxy the to the pixel at index.
Definition: pixel_buffer.hpp:381
pixel get_pixel(size_t x, size_t y) const
Returns a pixel at (x,y) position.
Definition: pixel_buffer.hpp:170
row_type & operator[](size_t index)
The non-checking version of get_row() method.
Definition: pixel_buffer.hpp:145
void resize(size_t width, size_t height)
Resizes the pixel buffer.
Definition: pixel_buffer.hpp:105
packed_pixel_row< pixel_type > pixel_row_type
Definition: pixel_buffer.hpp:480
static pixel * get_data(std::vector< pixel > &vec)
Returns the starting address of the row.
Definition: pixel_buffer.hpp:200
The packed pixel row class template.
Definition: pixel_buffer.hpp:331
Definition: pixel_buffer.hpp:283
pixel_buffer()
Definition: pixel_buffer.hpp:215
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:479
packed_pixel_row< pixel_type > pixel_row_type
Definition: pixel_buffer.hpp:455
basic_packed_pixel_proxy< pixel, byte & > basic_proxy
Definition: pixel_buffer.hpp:287
packed_gray_pixel< bits > pixel_type
Definition: pixel_buffer.hpp:454
basic_pixel_buffer(size_t width, size_t height)
Constructs an empty pixel buffer object.
Definition: pixel_buffer.hpp:82
Definition: color.hpp:36
traits row_traits
Definition: pixel_buffer.hpp:68
void resize(size_t size)
Resizes the pixel row to hold up to size packed pixels.
Definition: pixel_buffer.hpp:350
static size_t get_pixels_per_byte()
Definition: pixel_buffer.hpp:262
packed_pixel_proxy(packed_pixel_proxy const &other)
Definition: pixel_buffer.hpp:294
size_t m_height
Definition: pixel_buffer.hpp:185
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:482
basic_packed_pixel_proxy(reference ref)
Definition: pixel_buffer.hpp:232
void put_row(size_t index, row_type const &r)
Replaces the row at specified index.
Definition: pixel_buffer.hpp:161
packed_pixel_proxy(byte &ref, size_t index)
Definition: pixel_buffer.hpp:289