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_IMAGE_HPP_INCLUDED
00032 #define PNGPP_IMAGE_HPP_INCLUDED
00033
00034 #include <fstream>
00035 #include "pixel_buffer.hpp"
00036 #include "generator.hpp"
00037 #include "consumer.hpp"
00038 #include "convert_color_space.hpp"
00039
00040 namespace png
00041 {
00042
00051 template< typename pixel >
00052 class image
00053 {
00054 public:
00058 typedef pixel_traits< pixel > traits;
00059
00063 typedef pixel_buffer< pixel > pixbuf;
00064
00068 typedef typename pixbuf::row_type row_type;
00069
00074 typedef convert_color_space< pixel > transform_convert;
00075
00079 struct transform_identity
00080 {
00081 void operator()(io_base&) const {}
00082 };
00083
00087 image()
00088 : m_info(make_image_info< pixel >())
00089 {
00090 }
00091
00095 image(size_t width, size_t height)
00096 : m_info(make_image_info< pixel >())
00097 {
00098 resize(width, height);
00099 }
00100
00105 explicit image(std::string const& filename)
00106 {
00107 read(filename, transform_convert());
00108 }
00109
00114 template< class transformation >
00115 image(std::string const& filename,
00116 transformation const& transform)
00117 {
00118 read(filename.c_str(), transform);
00119 }
00120
00125 explicit image(char const* filename)
00126 {
00127 read(filename, transform_convert());
00128 }
00129
00134 template< class transformation >
00135 image(char const* filename, transformation const& transform)
00136 {
00137 read(filename, transform);
00138 }
00139
00144 explicit image(std::istream& stream)
00145 {
00146 read(stream, transform_convert());
00147 }
00148
00153 template< class transformation >
00154 image(std::istream& stream, transformation const& transform)
00155 {
00156 read(stream, transform);
00157 }
00158
00163 void read(std::string const& filename)
00164 {
00165 read(filename, transform_convert());
00166 }
00167
00172 template< class transformation >
00173 void read(std::string const& filename, transformation const& transform)
00174 {
00175 read(filename.c_str(), transform);
00176 }
00177
00182 void read(char const* filename)
00183 {
00184 read(filename, transform_convert());
00185 }
00186
00191 template< class transformation >
00192 void read(char const* filename, transformation const& transform)
00193 {
00194 std::ifstream stream(filename, std::ios::binary);
00195 if (!stream.is_open())
00196 {
00197 throw std_error(filename);
00198 }
00199 stream.exceptions(std::ios::badbit);
00200 read(stream, transform);
00201 }
00202
00207 void read(std::istream& stream)
00208 {
00209 read(stream, transform_convert());
00210 }
00211
00216 template< class transformation >
00217 void read(std::istream& stream, transformation const& transform)
00218 {
00219 pixel_consumer pixcon(m_info, m_pixbuf);
00220 pixcon.read(stream, transform);
00221 }
00222
00226 void write(std::string const& filename)
00227 {
00228 write(filename.c_str());
00229 }
00230
00234 void write(char const* filename)
00235 {
00236 std::ofstream stream(filename, std::ios::binary);
00237 if (!stream.is_open())
00238 {
00239 throw std_error(filename);
00240 }
00241 stream.exceptions(std::ios::badbit);
00242 write(stream);
00243 }
00244
00248 void write(std::ostream& stream)
00249 {
00250 pixel_generator pixgen(m_info, m_pixbuf);
00251 pixgen.write(stream);
00252 }
00253
00257 pixbuf& get_pixbuf()
00258 {
00259 return m_pixbuf;
00260 }
00261
00265 pixbuf const& get_pixbuf() const
00266 {
00267 return m_pixbuf;
00268 }
00269
00275 void set_pixbuf(pixbuf const& buffer)
00276 {
00277 m_pixbuf = buffer;
00278 }
00279
00280 size_t get_width() const
00281 {
00282 return m_pixbuf.get_width();
00283 }
00284
00285 size_t get_height() const
00286 {
00287 return m_pixbuf.get_height();
00288 }
00289
00293 void resize(size_t width, size_t height)
00294 {
00295 m_pixbuf.resize(width, height);
00296 m_info.set_width(width);
00297 m_info.set_height(height);
00298 }
00299
00306 row_type& get_row(size_t index)
00307 {
00308 return m_pixbuf.get_row(index);
00309 }
00310
00317 row_type const& get_row(size_t index) const
00318 {
00319 return m_pixbuf.get_row(index);
00320 }
00321
00325 row_type& operator[](size_t index)
00326 {
00327 return m_pixbuf[index];
00328 }
00329
00333 row_type const& operator[](size_t index) const
00334 {
00335 return m_pixbuf[index];
00336 }
00337
00341 pixel get_pixel(size_t x, size_t y) const
00342 {
00343 return m_pixbuf.get_pixel(x, y);
00344 }
00345
00349 void set_pixel(size_t x, size_t y, pixel p)
00350 {
00351 m_pixbuf.set_pixel(x, y, p);
00352 }
00353
00354 interlace_type get_interlace_type() const
00355 {
00356 return m_info.get_interlace_type();
00357 }
00358
00359 void set_interlace_type(interlace_type interlace)
00360 {
00361 m_info.set_interlace_type(interlace);
00362 }
00363
00364 compression_type get_compression_type() const
00365 {
00366 return m_info.get_compression_type();
00367 }
00368
00369 void set_compression_type(compression_type compression)
00370 {
00371 m_info.set_compression_type(compression);
00372 }
00373
00374 filter_type get_filter_type() const
00375 {
00376 return m_info.get_filter_type();
00377 }
00378
00379 void set_filter_type(filter_type filter)
00380 {
00381 m_info.set_filter_type(filter);
00382 }
00383
00387 palette& get_palette()
00388 {
00389 return m_info.get_palette();
00390 }
00391
00395 palette const& get_palette() const
00396 {
00397 return m_info.get_palette();
00398 }
00399
00403 void set_palette(palette const& plte)
00404 {
00405 m_info.set_palette(plte);
00406 }
00407
00408 protected:
00413 template< typename base >
00414 class streaming_impl
00415 : public base
00416 {
00417 public:
00418 streaming_impl(image_info& info, pixbuf& pixels)
00419 : base(info),
00420 m_pixbuf(pixels)
00421 {
00422 }
00423
00428 byte* get_next_row(size_t pos)
00429 {
00430 typedef typename pixbuf::row_traits row_traits;
00431 return reinterpret_cast< byte* >
00432 (row_traits::get_data(m_pixbuf.get_row(pos)));
00433 }
00434
00435 protected:
00436 pixbuf& m_pixbuf;
00437 };
00438
00442 class pixel_consumer
00443 : public streaming_impl< consumer< pixel, pixel_consumer,
00444 image_info_ref_holder,
00445 true > >
00446 {
00447 public:
00448 pixel_consumer(image_info& info, pixbuf& pixels)
00449 : streaming_impl< consumer< pixel, pixel_consumer,
00450 image_info_ref_holder,
00451 true > >(info, pixels)
00452 {
00453 }
00454
00455 void reset(size_t pass)
00456 {
00457 if (pass == 0)
00458 {
00459 this->m_pixbuf.resize(this->get_info().get_width(),
00460 this->get_info().get_height());
00461 }
00462 }
00463 };
00464
00468 class pixel_generator
00469 : public streaming_impl< generator< pixel, pixel_generator,
00470 image_info_ref_holder,
00471 true > >
00472 {
00473 public:
00474 pixel_generator(image_info& info, pixbuf& pixels)
00475 : streaming_impl< generator< pixel, pixel_generator,
00476 image_info_ref_holder,
00477 true > >(info, pixels)
00478 {
00479 }
00480 };
00481
00482 image_info m_info;
00483 pixbuf m_pixbuf;
00484 };
00485
00486 }
00487
00488 #endif // PNGPP_IMAGE_HPP_INCLUDED