pixel_buffer.hpp
Go to the documentation of this file.
/*
* Copyright (C) 2007,2008 Alex Shulgin
*
* This file is part of png++ the C++ wrapper for libpng. PNG++ is free
* software; the exact copying conditions are as follows:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef PNGPP_PIXEL_BUFFER_HPP_INCLUDED
#define PNGPP_PIXEL_BUFFER_HPP_INCLUDED
#include <cassert>
#include <cstddef>
#include <stdexcept>
#include <vector>
#include "packed_pixel.hpp"
#include "gray_pixel.hpp"
#include "index_pixel.hpp"
namespace png
{
template< typename row > class row_traits;
template< typename pixel,
typename row,
class traits = row_traits< row > >
class basic_pixel_buffer
{
public:
typedef row row_type;
typedef row_type& row_access;
typedef row_type const& row_const_access;
typedef traits row_traits;
basic_pixel_buffer()
: m_width(0),
m_height(0)
{
}
basic_pixel_buffer(uint_32 width, uint_32 height)
: m_width(0),
m_height(0)
{
resize(width, height);
}
uint_32 get_width() const
{
return m_width;
}
uint_32 get_height() const
{
return m_height;
}
void resize(uint_32 width, uint_32 height)
{
m_width = width;
m_height = height;
m_rows.resize(height);
for (typename row_vec::iterator r = m_rows.begin();
r != m_rows.end();
++r)
{
r->resize(width);
}
}
row_access get_row(size_t index)
{
return m_rows.at(index);
}
row_const_access get_row(size_t index) const
{
return m_rows.at(index);
}
row_access operator[](size_t index)
{
return m_rows[index];
}
row_const_access operator[](size_t index) const
{
return m_rows[index];
}
void put_row(size_t index, row_type const& r)
{
assert(r.size() == m_width);
m_rows.at(index) = r;
}
pixel get_pixel(size_t x, size_t y) const
{
return get_row(y).at(x);
}
void set_pixel(size_t x, size_t y, pixel p)
{
get_row(y).at(x) = p;
}
protected:
uint_32 m_width;
uint_32 m_height;
typedef std::vector< row_type > row_vec;
row_vec m_rows;
};
template< typename pixel >
class row_traits< std::vector< pixel > >
{
public:
static pixel* get_data(std::vector< pixel >& vec)
{
assert(vec.size());
return & vec[0];
}
};
template< typename pixel >
class pixel_buffer
: public basic_pixel_buffer< pixel, std::vector< pixel > >
{
public:
pixel_buffer()
{
}
pixel_buffer(uint_32 width, uint_32 height)
: basic_pixel_buffer< pixel, std::vector< pixel > >(width, height)
{
}
};
namespace detail
{
template< class pixel, typename reference >
class basic_packed_pixel_proxy
{
public:
explicit basic_packed_pixel_proxy(reference ref)
: m_ref(ref),
m_shift(0)
{
}
basic_packed_pixel_proxy(reference ref, size_t index)
: m_ref(ref),
m_shift(get_shift(index))
{
}
operator pixel() const
{
return pixel((m_ref >> m_shift) & pixel::get_bit_mask());
}
protected:
/*
* bits: . . .
* 1: 7 6 5 4 3 2 1 0
* 2: 6 4 2 0
* 4: 4 0
*/
static size_t get_shift(size_t index)
{
int const bits = pixel::get_bit_depth();
return (8 - bits) - (index % get_pixels_per_byte()) * bits;
}
static size_t get_pixels_per_byte()
{
return 8 / pixel::get_bit_depth();
}
reference m_ref;
size_t m_shift;
};
template< class pixel >
class const_packed_pixel_proxy
: public basic_packed_pixel_proxy< pixel, byte const& >
{
public:
const_packed_pixel_proxy(byte const& ref, size_t index)
: basic_packed_pixel_proxy< pixel, byte const& >(ref, index)
{
}
};
template< class pixel >
class packed_pixel_proxy
: public basic_packed_pixel_proxy< pixel, byte& >
{
public:
typedef basic_packed_pixel_proxy< pixel, byte& > basic_proxy;
packed_pixel_proxy(byte& ref, size_t index)
: basic_proxy(ref, index)
{
}
packed_pixel_proxy(packed_pixel_proxy const& other)
: basic_proxy(other.m_ref)
{
this->m_shift = other.m_shift;
}
packed_pixel_proxy& operator=(packed_pixel_proxy const& other)
{
return *this = static_cast< pixel >(other);
}
template< typename reference >
packed_pixel_proxy&
operator=(basic_packed_pixel_proxy< pixel, reference > const& other)
{
return *this = static_cast< pixel >(other);
}
packed_pixel_proxy& operator=(pixel p)
{
this->m_ref = (this->m_ref
& ~(pixel::get_bit_mask() << this->m_shift))
| (p << this->m_shift);
return *this;
}
};
} // namespace detail
template< class pixel >
class packed_pixel_row
{
public:
explicit packed_pixel_row(size_t size = 0)
{
resize(size);
}
size_t size() const
{
return m_size;
}
void resize(size_t size)
{
m_vec.resize(size / get_pixels_per_byte()
+ (size % get_pixels_per_byte() ? 1 : 0));
m_size = size;
}
typedef detail::const_packed_pixel_proxy< pixel > const_pixel_proxy;
typedef detail::packed_pixel_proxy< pixel > pixel_proxy;
const_pixel_proxy at(size_t index) const
{
return const_pixel_proxy(m_vec.at(index / get_pixels_per_byte()),
index);
}
pixel_proxy at(size_t index)
{
return pixel_proxy(m_vec.at(index / get_pixels_per_byte()),
index);
}
const_pixel_proxy operator[](size_t index) const
{
return const_pixel_proxy(m_vec[index / get_pixels_per_byte()],
index);
}
pixel_proxy operator[](size_t index)
{
return pixel_proxy(m_vec[index / get_pixels_per_byte()],
index);
}
byte* get_data()
{
assert(m_vec.size());
return & m_vec[0];
}
private:
static size_t get_pixels_per_byte()
{
return 8 / pixel::get_bit_depth();
}
std::vector< byte > m_vec;
size_t m_size;
};
template< typename pixel >
class row_traits< packed_pixel_row< pixel > >
{
public:
static byte* get_data(packed_pixel_row< pixel >& row)
{
return row.get_data();
}
};
template< int bits >
class pixel_buffer< packed_gray_pixel< bits > >
: public basic_pixel_buffer< packed_gray_pixel< bits >,
packed_pixel_row< packed_gray_pixel
< bits > > >
{
public:
typedef packed_gray_pixel< bits > pixel_type;
typedef packed_pixel_row< pixel_type > pixel_row_type;
pixel_buffer()
{
}
pixel_buffer(uint_32 width, uint_32 height)
: basic_pixel_buffer< pixel_type,
pixel_row_type >(width, height)
{
}
};
template< int bits >
class pixel_buffer< packed_index_pixel< bits > >
: public basic_pixel_buffer< packed_index_pixel< bits >,
packed_pixel_row< packed_index_pixel
< bits > > >
{
public:
typedef packed_index_pixel< bits > pixel_type;
typedef packed_pixel_row< pixel_type > pixel_row_type;
pixel_buffer()
{
}
pixel_buffer(uint_32 width, uint_32 height)
: basic_pixel_buffer< pixel_type,
pixel_row_type >(width, height)
{
}
};
} // namespace png
#endif // PNGPP_PIXEL_BUFFER_HPP_INCLUDED
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::packed_pixel_row::size
size_t size() const
Definition: pixel_buffer.hpp:344
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::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::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
png::detail::const_packed_pixel_proxy
Definition: pixel_buffer.hpp:274
png::detail::basic_packed_pixel_proxy::m_ref
reference m_ref
Definition: pixel_buffer.hpp:269
png::basic_pixel_buffer::row_const_access
row_type const & row_const_access
Definition: pixel_buffer.hpp:69
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
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::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::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::detail::basic_packed_pixel_proxy
Definition: pixel_buffer.hpp:231
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
The basic class template to represent image pixel data.
Definition: pixel_buffer.hpp:61
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::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::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-, 2- and 4-bit pixels.
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::basic_pixel_buffer::get_height
uint_32 get_height() const
Definition: pixel_buffer.hpp:96
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
png::basic_pixel_buffer::get_width
uint_32 get_width() const
Definition: pixel_buffer.hpp:91