png++  0.2.9
solid_pixel_buffer.hpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2007,2008   Alex Shulgin
00003  *
00004  * This file is part of png++ the C++ wrapper for libpng.  PNG++ is free
00005  * software; the exact copying conditions are as follows:
00006  *
00007  * Redistribution and use in source and binary forms, with or without
00008  * modification, are permitted provided that the following conditions are met:
00009  *
00010  * 1. Redistributions of source code must retain the above copyright notice,
00011  * this list of conditions and the following disclaimer.
00012  *
00013  * 2. Redistributions in binary form must reproduce the above copyright
00014  * notice, this list of conditions and the following disclaimer in the
00015  * documentation and/or other materials provided with the distribution.
00016  *
00017  * 3. The name of the author may not be used to endorse or promote products
00018  * derived from this software without specific prior written permission.
00019  *
00020  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00021  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00022  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
00023  * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00024  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
00025  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00026  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00027  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00028  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00029  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00030  */
00031 #ifndef PNGPP_SOLID_PIXEL_BUFFER_HPP_INCLUDED
00032 #define PNGPP_SOLID_PIXEL_BUFFER_HPP_INCLUDED
00033 
00034 #include <cassert>
00035 #include <cstddef>
00036 #include <climits>
00037 #include <stdexcept>
00038 #include <vector>
00039 
00040 #include "config.hpp"
00041 #include "packed_pixel.hpp"
00042 #include "gray_pixel.hpp"
00043 #include "index_pixel.hpp"
00044 
00045 namespace png
00046 {
00047 
00053     template< typename pixel >
00054     class solid_pixel_buffer
00055     {
00056     public:
00057         typedef pixel_traits< pixel > pixel_traits_t;
00058         struct row_traits
00059         {
00060             typedef pixel* row_access;
00061             typedef const pixel* row_const_access;
00062 
00063             static byte* get_data(row_access row)
00064             {
00065                 return reinterpret_cast<byte*>(row);
00066             }
00067         };
00068 
00069 
00073         typedef typename row_traits::row_access row_access;
00074         typedef typename row_traits::row_const_access row_const_access;
00075         typedef row_access row_type;
00076 
00080         solid_pixel_buffer()
00081             : m_width(0),
00082               m_height(0),
00083               m_stride(0)
00084         {
00085         }
00086 
00090         solid_pixel_buffer(uint_32 width, uint_32 height)
00091             : m_width(0),
00092               m_height(0),
00093               m_stride(0)
00094         {
00095             resize(width, height);
00096         }
00097 
00098         uint_32 get_width() const
00099         {
00100             return m_width;
00101         }
00102 
00103         uint_32 get_height() const
00104         {
00105             return m_height;
00106         }
00107 
00114         void resize(uint_32 width, uint_32 height)
00115         {
00116             m_width = width;
00117             m_height = height;
00118             m_stride = m_width * bytes_per_pixel;
00119             m_bytes.resize(height * m_stride);
00120         }
00121 
00130         row_access get_row(size_t index)
00131         {
00132             return reinterpret_cast<row_access>(&m_bytes.at(index * m_stride));
00133         }
00134 
00141         row_const_access get_row(size_t index) const
00142         {
00143             return (row_const_access)(&m_bytes.at(index * m_stride));
00144         }
00145 
00149         row_access operator[](size_t index)
00150         {
00151             return (row_access)(&m_bytes[index * m_stride]);
00152         }
00153 
00157         row_const_access operator[](size_t index) const
00158         {
00159             return (row_const_access)(&m_bytes[index * m_stride]);
00160         }
00161 
00165         void put_row(size_t index, row_const_access r)
00166         {
00167             row_access row = get_row();
00168             for (uint_32 i = 0; i < m_width; ++i)
00169                 *row++ = *r++;
00170         }
00171 
00175         pixel get_pixel(size_t x, size_t y) const
00176         {
00177             size_t index = (y * m_width + x) * bytes_per_pixel;
00178             return *reinterpret_cast< const pixel* >(&m_bytes.at(index));
00179         }
00180 
00184         void set_pixel(size_t x, size_t y, pixel p)
00185         {
00186             size_t index = (y * m_width + x) * bytes_per_pixel;
00187             *reinterpret_cast< pixel* >(&m_bytes.at(index)) = p;
00188         }
00189 
00193         const std::vector< byte >& get_bytes() const
00194         {
00195             return m_bytes;
00196         }
00197 
00198 #ifdef PNGPP_HAS_STD_MOVE
00199 
00202         std::vector< byte > fetch_bytes()
00203         {
00204             m_width = 0;
00205             m_height = 0;
00206             m_stride = 0;
00207 
00208             // the buffer is moved outside without copying and leave m_bytes empty.
00209             return std::move(m_bytes);
00210         }
00211 #endif
00212 
00213     protected:
00214         static const size_t bytes_per_pixel = pixel_traits_t::channels *
00215                 pixel_traits_t::bit_depth / CHAR_BIT;
00216 
00217     protected:
00218         uint_32 m_width;
00219         uint_32 m_height;
00220         size_t m_stride;
00221         std::vector< byte > m_bytes;
00222 
00223 #ifdef PNGPP_HAS_STATIC_ASSERT
00224         static_assert(pixel_traits_t::bit_depth % CHAR_BIT == 0,
00225             "Bit_depth should consist of integer number of bytes");
00226 
00227         static_assert(sizeof(pixel) * CHAR_BIT ==
00228             pixel_traits_t::channels * pixel_traits_t::bit_depth,
00229             "pixel type should contain channels data only");
00230 #endif
00231     };
00232 
00238     template< int bits >
00239     class solid_pixel_buffer< packed_pixel< bits > >;
00240 
00241 } // namespace png
00242 
00243 #endif // PNGPP_solid_pixel_buffer_HPP_INCLUDED