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(stream, transform_convert());
00147 }
00148
00153 template< class transformation >
00154 image(std::istream& stream, transformation const& transform)
00155 {
00156 read_stream(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(stream, transform);
00201 }
00202
00207 void read(std::istream& stream)
00208 {
00209 read_stream(stream, transform_convert());
00210 }
00211
00216 template< class transformation >
00217 void read(std::istream& stream, transformation const& transform)
00218 {
00219 read_stream(stream, transform);
00220 }
00221
00226 template< class istream >
00227 void read_stream(istream& stream)
00228 {
00229 read_stream(stream, transform_convert());
00230 }
00231
00236 template< class istream, class transformation >
00237 void read_stream(istream& stream, transformation const& transform)
00238 {
00239 pixel_consumer pixcon(m_info, m_pixbuf);
00240 pixcon.read(stream, transform);
00241 }
00242
00246 void write(std::string const& filename)
00247 {
00248 write(filename.c_str());
00249 }
00250
00254 void write(char const* filename)
00255 {
00256 std::ofstream stream(filename, std::ios::binary);
00257 if (!stream.is_open())
00258 {
00259 throw std_error(filename);
00260 }
00261 stream.exceptions(std::ios::badbit);
00262 write_stream(stream);
00263 }
00264
00268 void write_stream(std::ostream& stream)
00269 {
00270 write_stream(stream);
00271 }
00272
00276 template< class ostream >
00277 void write_stream(ostream& stream)
00278 {
00279 pixel_generator pixgen(m_info, m_pixbuf);
00280 pixgen.write(stream);
00281 }
00282
00286 pixbuf& get_pixbuf()
00287 {
00288 return m_pixbuf;
00289 }
00290
00294 pixbuf const& get_pixbuf() const
00295 {
00296 return m_pixbuf;
00297 }
00298
00304 void set_pixbuf(pixbuf const& buffer)
00305 {
00306 m_pixbuf = buffer;
00307 }
00308
00309 size_t get_width() const
00310 {
00311 return m_pixbuf.get_width();
00312 }
00313
00314 size_t get_height() const
00315 {
00316 return m_pixbuf.get_height();
00317 }
00318
00322 void resize(size_t width, size_t height)
00323 {
00324 m_pixbuf.resize(width, height);
00325 m_info.set_width(width);
00326 m_info.set_height(height);
00327 }
00328
00335 row_type& get_row(size_t index)
00336 {
00337 return m_pixbuf.get_row(index);
00338 }
00339
00346 row_type const& get_row(size_t index) const
00347 {
00348 return m_pixbuf.get_row(index);
00349 }
00350
00354 row_type& operator[](size_t index)
00355 {
00356 return m_pixbuf[index];
00357 }
00358
00362 row_type const& operator[](size_t index) const
00363 {
00364 return m_pixbuf[index];
00365 }
00366
00370 pixel get_pixel(size_t x, size_t y) const
00371 {
00372 return m_pixbuf.get_pixel(x, y);
00373 }
00374
00378 void set_pixel(size_t x, size_t y, pixel p)
00379 {
00380 m_pixbuf.set_pixel(x, y, p);
00381 }
00382
00383 interlace_type get_interlace_type() const
00384 {
00385 return m_info.get_interlace_type();
00386 }
00387
00388 void set_interlace_type(interlace_type interlace)
00389 {
00390 m_info.set_interlace_type(interlace);
00391 }
00392
00393 compression_type get_compression_type() const
00394 {
00395 return m_info.get_compression_type();
00396 }
00397
00398 void set_compression_type(compression_type compression)
00399 {
00400 m_info.set_compression_type(compression);
00401 }
00402
00403 filter_type get_filter_type() const
00404 {
00405 return m_info.get_filter_type();
00406 }
00407
00408 void set_filter_type(filter_type filter)
00409 {
00410 m_info.set_filter_type(filter);
00411 }
00412
00416 palette& get_palette()
00417 {
00418 return m_info.get_palette();
00419 }
00420
00424 palette const& get_palette() const
00425 {
00426 return m_info.get_palette();
00427 }
00428
00432 void set_palette(palette const& plte)
00433 {
00434 m_info.set_palette(plte);
00435 }
00436
00437 tRNS const& get_tRNS() const
00438 {
00439 return m_info.get_tRNS();
00440 }
00441
00442 tRNS& get_tRNS()
00443 {
00444 return m_info.get_tRNS();
00445 }
00446
00447 void set_tRNS(tRNS const& trns)
00448 {
00449 m_info.set_tRNS(trns);
00450 }
00451
00452 protected:
00457 template< typename base_impl >
00458 class streaming_impl
00459 : public base_impl
00460 {
00461 public:
00462 streaming_impl(image_info& info, pixbuf& pixels)
00463 : base_impl(info),
00464 m_pixbuf(pixels)
00465 {
00466 }
00467
00472 byte* get_next_row(size_t pos)
00473 {
00474 typedef typename pixbuf::row_traits row_traits;
00475 return reinterpret_cast< byte* >
00476 (row_traits::get_data(m_pixbuf.get_row(pos)));
00477 }
00478
00479 protected:
00480 pixbuf& m_pixbuf;
00481 };
00482
00486 class pixel_consumer
00487 : public streaming_impl< consumer< pixel,
00488 pixel_consumer,
00489 image_info_ref_holder,
00490 true > >
00491 {
00492 public:
00493 pixel_consumer(image_info& info, pixbuf& pixels)
00494 : streaming_impl< consumer< pixel,
00495 pixel_consumer,
00496 image_info_ref_holder,
00497 true > >(info, pixels)
00498 {
00499 }
00500
00501 void reset(size_t pass)
00502 {
00503 if (pass == 0)
00504 {
00505 this->m_pixbuf.resize(this->get_info().get_width(),
00506 this->get_info().get_height());
00507 }
00508 }
00509 };
00510
00514 class pixel_generator
00515 : public streaming_impl< generator< pixel,
00516 pixel_generator,
00517 image_info_ref_holder,
00518 true > >
00519 {
00520 public:
00521 pixel_generator(image_info& info, pixbuf& pixels)
00522 : streaming_impl< generator< pixel,
00523 pixel_generator,
00524 image_info_ref_holder,
00525 true > >(info, pixels)
00526 {
00527 }
00528 };
00529
00530 image_info m_info;
00531 pixbuf m_pixbuf;
00532 };
00533
00534 }
00535
00536 #endif // PNGPP_IMAGE_HPP_INCLUDED