00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #ifndef PNGPP_PIXEL_BUFFER_HPP_INCLUDED
00032 #define PNGPP_PIXEL_BUFFER_HPP_INCLUDED
00033
00034 #include <cassert>
00035 #include <cstddef>
00036 #include <stdexcept>
00037 #include <vector>
00038
00039 #include "packed_pixel.hpp"
00040 #include "gray_pixel.hpp"
00041 #include "index_pixel.hpp"
00042
00043 namespace png
00044 {
00045
00053 template< typename row > class row_traits;
00054
00058 template< typename pixel,
00059 typename row,
00060 class traits = row_traits< row > >
00061 class basic_pixel_buffer
00062 {
00063 public:
00067 typedef row row_type;
00068 typedef traits row_traits;
00069
00073 basic_pixel_buffer()
00074 : m_width(0),
00075 m_height(0)
00076 {
00077 }
00078
00082 basic_pixel_buffer(size_t width, size_t height)
00083 : m_width(0),
00084 m_height(0)
00085 {
00086 resize(width, height);
00087 }
00088
00089 size_t get_width() const
00090 {
00091 return m_width;
00092 }
00093
00094 size_t get_height() const
00095 {
00096 return m_height;
00097 }
00098
00105 void resize(size_t width, size_t height)
00106 {
00107 m_width = width;
00108 m_height = height;
00109 m_rows.resize(height);
00110 for (typename row_vec::iterator r = m_rows.begin();
00111 r != m_rows.end();
00112 ++r)
00113 {
00114 r->resize(width);
00115 }
00116 }
00117
00126 row_type& get_row(size_t index)
00127 {
00128 return m_rows.at(index);
00129 }
00130
00137 row_type const& get_row(size_t index) const
00138 {
00139 return m_rows.at(index);
00140 }
00141
00145 row_type& operator[](size_t index)
00146 {
00147 return m_rows[index];
00148 }
00149
00153 row_type const& operator[](size_t index) const
00154 {
00155 return m_rows[index];
00156 }
00157
00161 void put_row(size_t index, row_type const& r)
00162 {
00163 assert(r.size() == m_width);
00164 m_rows.at(index) = r;
00165 }
00166
00170 pixel get_pixel(size_t x, size_t y) const
00171 {
00172 return get_row(y).at(x);
00173 }
00174
00178 void set_pixel(size_t x, size_t y, pixel p)
00179 {
00180 get_row(y).at(x) = p;
00181 }
00182
00183 protected:
00184 size_t m_width;
00185 size_t m_height;
00186 typedef std::vector< row_type > row_vec;
00187 row_vec m_rows;
00188 };
00189
00193 template< typename pixel >
00194 class row_traits< std::vector< pixel > >
00195 {
00196 public:
00200 static pixel* get_data(std::vector< pixel >& vec)
00201 {
00202 assert(vec.size());
00203 return & vec[0];
00204 }
00205 };
00206
00210 template< typename pixel >
00211 class pixel_buffer
00212 : public basic_pixel_buffer< pixel, std::vector< pixel > >
00213 {
00214 public:
00215 pixel_buffer()
00216 {
00217 }
00218
00219 pixel_buffer(size_t width, size_t height)
00220 : basic_pixel_buffer< pixel, std::vector< pixel > >(width, height)
00221 {
00222 }
00223 };
00224
00225 namespace
00226 {
00227
00228 template< class pixel, typename reference >
00229 class basic_packed_pixel_proxy
00230 {
00231 public:
00232 explicit basic_packed_pixel_proxy(reference ref)
00233 : m_ref(ref),
00234 m_shift(0)
00235 {
00236 }
00237
00238 basic_packed_pixel_proxy(reference ref, size_t index)
00239 : m_ref(ref),
00240 m_shift(get_shift(index))
00241 {
00242 }
00243
00244 operator pixel() const
00245 {
00246 return pixel((m_ref >> m_shift) & pixel::get_bit_mask());
00247 }
00248
00249 protected:
00250
00251
00252
00253
00254
00255
00256 static size_t get_shift(size_t index)
00257 {
00258 size_t const bits = pixel::get_bit_depth();
00259 return (8 - bits) - (index % get_pixels_per_byte()) * bits;
00260 }
00261
00262 static size_t get_pixels_per_byte()
00263 {
00264 return 8 / pixel::get_bit_depth();
00265 }
00266
00267 reference m_ref;
00268 size_t m_shift;
00269 };
00270
00271 template< class pixel >
00272 class const_packed_pixel_proxy
00273 : public basic_packed_pixel_proxy< pixel, byte const& >
00274 {
00275 public:
00276 const_packed_pixel_proxy(byte const& ref, size_t index)
00277 : basic_packed_pixel_proxy< pixel, byte const& >(ref, index)
00278 {
00279 }
00280 };
00281
00282 template< class pixel >
00283 class packed_pixel_proxy
00284 : public basic_packed_pixel_proxy< pixel, byte& >
00285 {
00286 public:
00287 typedef basic_packed_pixel_proxy< pixel, byte& > basic_proxy;
00288
00289 packed_pixel_proxy(byte& ref, size_t index)
00290 : basic_proxy(ref, index)
00291 {
00292 }
00293
00294 packed_pixel_proxy(packed_pixel_proxy const& other)
00295 : basic_proxy(other.m_ref)
00296 {
00297 this->m_shift = other.m_shift;
00298 }
00299
00300 packed_pixel_proxy& operator=(packed_pixel_proxy const& other)
00301 {
00302 return *this = static_cast< pixel >(other);
00303 }
00304
00305 template< typename reference >
00306 packed_pixel_proxy&
00307 operator=(basic_packed_pixel_proxy< pixel, reference > const& other)
00308 {
00309 return *this = static_cast< pixel >(other);
00310 }
00311
00312 packed_pixel_proxy& operator=(pixel p)
00313 {
00314 this->m_ref = this->m_ref
00315 & ~(pixel::get_bit_mask() << this->m_shift)
00316 | (p << this->m_shift);
00317
00318 return *this;
00319 }
00320 };
00321
00322 }
00323
00330 template< class pixel >
00331 class packed_pixel_row
00332 {
00333 public:
00337 explicit packed_pixel_row(size_t size = 0)
00338 {
00339 resize(size);
00340 }
00341
00342 size_t size() const
00343 {
00344 return m_size;
00345 }
00346
00350 void resize(size_t size)
00351 {
00352 m_vec.resize(size / get_pixels_per_byte()
00353 + (size % get_pixels_per_byte() ? 1 : 0));
00354 m_size = size;
00355 }
00356
00360 typedef const_packed_pixel_proxy< pixel > const_pixel_proxy;
00361
00365 typedef packed_pixel_proxy< pixel > pixel_proxy;
00366
00371 const_pixel_proxy at(size_t index) const
00372 {
00373 return const_pixel_proxy(m_vec.at(index / get_pixels_per_byte()),
00374 index);
00375 }
00376
00381 pixel_proxy at(size_t index)
00382 {
00383 return pixel_proxy(m_vec.at(index / get_pixels_per_byte()),
00384 index);
00385 }
00386
00391 const_pixel_proxy operator[](size_t index) const
00392 {
00393 return const_pixel_proxy(m_vec[index / get_pixels_per_byte()],
00394 index);
00395 }
00396
00401 pixel_proxy operator[](size_t index)
00402 {
00403 return pixel_proxy(m_vec[index / get_pixels_per_byte()],
00404 index);
00405 }
00406
00410 byte* get_data()
00411 {
00412 assert(m_vec.size());
00413 return & m_vec[0];
00414 }
00415
00416 private:
00417 static size_t get_pixels_per_byte()
00418 {
00419 return 8 / pixel::get_bit_depth();
00420 }
00421
00422 std::vector< byte > m_vec;
00423 size_t m_size;
00424 };
00425
00430 template< typename pixel >
00431 class row_traits< packed_pixel_row< pixel > >
00432 {
00433 public:
00437 static byte* get_data(packed_pixel_row< pixel >& row)
00438 {
00439 return row.get_data();
00440 }
00441 };
00442
00447 template< size_t bits >
00448 class pixel_buffer< packed_gray_pixel< bits > >
00449 : public basic_pixel_buffer< packed_gray_pixel< bits >,
00450 packed_pixel_row< packed_gray_pixel
00451 < bits > > >
00452 {
00453 public:
00454 typedef packed_gray_pixel< bits > pixel_type;
00455 typedef packed_pixel_row< pixel_type > pixel_row_type;
00456
00457 pixel_buffer()
00458 {
00459 }
00460
00461 pixel_buffer(size_t width, size_t height)
00462 : basic_pixel_buffer< pixel_type, pixel_row_type >(width, height)
00463 {
00464 }
00465 };
00466
00471 template< size_t bits >
00472 class pixel_buffer< packed_index_pixel< bits > >
00473 : public basic_pixel_buffer< packed_index_pixel< bits >,
00474 packed_pixel_row< packed_index_pixel
00475 < bits > > >
00476 {
00477 public:
00478 typedef packed_index_pixel< bits > pixel_type;
00479 typedef packed_pixel_row< pixel_type > pixel_row_type;
00480
00481 pixel_buffer()
00482 {
00483 }
00484
00485 pixel_buffer(size_t width, size_t height)
00486 : basic_pixel_buffer< pixel_type, pixel_row_type >(width, height)
00487 {
00488 }
00489 };
00490
00491 }
00492
00493 #endif // PNGPP_PIXEL_BUFFER_HPP_INCLUDED