png++
0.2.9
|
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_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 00061 template< typename pixel, typename pixel_buffer_type = pixel_buffer< pixel > > 00062 class image 00063 { 00064 public: 00068 typedef pixel_traits< pixel > traits; 00069 00073 typedef pixel_buffer_type pixbuf; 00074 00078 typedef typename pixbuf::row_type row_type; 00079 typedef typename pixbuf::row_access row_access; 00080 typedef typename pixbuf::row_const_access row_const_access; 00081 00086 typedef convert_color_space< pixel > transform_convert; 00087 00091 struct transform_identity 00092 { 00093 void operator()(io_base&) const {} 00094 }; 00095 00099 image() 00100 : m_info(make_image_info< pixel >()) 00101 { 00102 } 00103 00107 image(uint_32 width, uint_32 height) 00108 : m_info(make_image_info< pixel >()) 00109 { 00110 resize(width, height); 00111 } 00112 00117 explicit image(std::string const& filename) 00118 { 00119 read(filename, transform_convert()); 00120 } 00121 00126 template< class transformation > 00127 image(std::string const& filename, 00128 transformation const& transform) 00129 { 00130 read(filename.c_str(), transform); 00131 } 00132 00137 explicit image(char const* filename) 00138 { 00139 read(filename, transform_convert()); 00140 } 00141 00146 template< class transformation > 00147 image(char const* filename, transformation const& transform) 00148 { 00149 read(filename, transform); 00150 } 00151 00156 explicit image(std::istream& stream) 00157 { 00158 read_stream(stream, transform_convert()); 00159 } 00160 00165 template< class transformation > 00166 image(std::istream& stream, transformation const& transform) 00167 { 00168 read_stream(stream, transform); 00169 } 00170 00175 void read(std::string const& filename) 00176 { 00177 read(filename, transform_convert()); 00178 } 00179 00184 template< class transformation > 00185 void read(std::string const& filename, transformation const& transform) 00186 { 00187 read(filename.c_str(), transform); 00188 } 00189 00194 void read(char const* filename) 00195 { 00196 read(filename, transform_convert()); 00197 } 00198 00203 template< class transformation > 00204 void read(char const* filename, transformation const& transform) 00205 { 00206 std::ifstream stream(filename, std::ios::binary); 00207 if (!stream.is_open()) 00208 { 00209 throw std_error(filename); 00210 } 00211 stream.exceptions(std::ios::badbit); 00212 read_stream(stream, transform); 00213 } 00214 00219 void read(std::istream& stream) 00220 { 00221 read_stream(stream, transform_convert()); 00222 } 00223 00228 template< class transformation > 00229 void read(std::istream& stream, transformation const& transform) 00230 { 00231 read_stream(stream, transform); 00232 } 00233 00238 template< class istream > 00239 void read_stream(istream& stream) 00240 { 00241 read_stream(stream, transform_convert()); 00242 } 00243 00248 template< class istream, class transformation > 00249 void read_stream(istream& stream, transformation const& transform) 00250 { 00251 pixel_consumer pixcon(m_info, m_pixbuf); 00252 pixcon.read(stream, transform); 00253 } 00254 00258 void write(std::string const& filename) 00259 { 00260 write(filename.c_str()); 00261 } 00262 00266 void write(char const* filename) 00267 { 00268 std::ofstream stream(filename, std::ios::binary); 00269 if (!stream.is_open()) 00270 { 00271 throw std_error(filename); 00272 } 00273 stream.exceptions(std::ios::badbit); 00274 write_stream(stream); 00275 } 00276 00280 template< class ostream > 00281 void write_stream(ostream& stream) 00282 { 00283 pixel_generator pixgen(m_info, m_pixbuf); 00284 pixgen.write(stream); 00285 } 00286 00290 pixbuf& get_pixbuf() 00291 { 00292 return m_pixbuf; 00293 } 00294 00298 pixbuf const& get_pixbuf() const 00299 { 00300 return m_pixbuf; 00301 } 00302 00308 void set_pixbuf(pixbuf const& buffer) 00309 { 00310 m_pixbuf = buffer; 00311 } 00312 00313 uint_32 get_width() const 00314 { 00315 return m_pixbuf.get_width(); 00316 } 00317 00318 uint_32 get_height() const 00319 { 00320 return m_pixbuf.get_height(); 00321 } 00322 00326 void resize(uint_32 width, uint_32 height) 00327 { 00328 m_pixbuf.resize(width, height); 00329 m_info.set_width(width); 00330 m_info.set_height(height); 00331 } 00332 00339 row_access get_row(size_t index) 00340 { 00341 return m_pixbuf.get_row(index); 00342 } 00343 00350 row_const_access get_row(size_t index) const 00351 { 00352 return m_pixbuf.get_row(index); 00353 } 00354 00358 row_access operator[](size_t index) 00359 { 00360 return m_pixbuf[index]; 00361 } 00362 00366 row_const_access operator[](size_t index) const 00367 { 00368 return m_pixbuf[index]; 00369 } 00370 00374 pixel get_pixel(size_t x, size_t y) const 00375 { 00376 return m_pixbuf.get_pixel(x, y); 00377 } 00378 00382 void set_pixel(size_t x, size_t y, pixel p) 00383 { 00384 m_pixbuf.set_pixel(x, y, p); 00385 } 00386 00387 interlace_type get_interlace_type() const 00388 { 00389 return m_info.get_interlace_type(); 00390 } 00391 00392 void set_interlace_type(interlace_type interlace) 00393 { 00394 m_info.set_interlace_type(interlace); 00395 } 00396 00397 compression_type get_compression_type() const 00398 { 00399 return m_info.get_compression_type(); 00400 } 00401 00402 void set_compression_type(compression_type compression) 00403 { 00404 m_info.set_compression_type(compression); 00405 } 00406 00407 filter_type get_filter_type() const 00408 { 00409 return m_info.get_filter_type(); 00410 } 00411 00412 void set_filter_type(filter_type filter) 00413 { 00414 m_info.set_filter_type(filter); 00415 } 00416 00420 palette& get_palette() 00421 { 00422 return m_info.get_palette(); 00423 } 00424 00428 palette const& get_palette() const 00429 { 00430 return m_info.get_palette(); 00431 } 00432 00436 void set_palette(palette const& plte) 00437 { 00438 m_info.set_palette(plte); 00439 } 00440 00441 tRNS const& get_tRNS() const 00442 { 00443 return m_info.get_tRNS(); 00444 } 00445 00446 tRNS& get_tRNS() 00447 { 00448 return m_info.get_tRNS(); 00449 } 00450 00451 void set_tRNS(tRNS const& trns) 00452 { 00453 m_info.set_tRNS(trns); 00454 } 00455 00456 double get_gamma() const 00457 { 00458 return m_info.get_gamma(); 00459 } 00460 00461 void set_gamma(double gamma) 00462 { 00463 m_info.set_gamma(gamma); 00464 } 00465 00466 protected: 00471 template< typename base_impl > 00472 class streaming_impl 00473 : public base_impl 00474 { 00475 public: 00476 streaming_impl(image_info& info, pixbuf& pixels) 00477 : base_impl(info), 00478 m_pixbuf(pixels) 00479 { 00480 } 00481 00486 byte* get_next_row(size_t pos) 00487 { 00488 typedef typename pixbuf::row_traits row_traits; 00489 return reinterpret_cast< byte* > 00490 (row_traits::get_data(m_pixbuf.get_row(pos))); 00491 } 00492 00493 protected: 00494 pixbuf& m_pixbuf; 00495 }; 00496 00500 class pixel_consumer 00501 : public streaming_impl< consumer< pixel, 00502 pixel_consumer, 00503 image_info_ref_holder, 00504 /* interlacing = */ true > > 00505 { 00506 public: 00507 pixel_consumer(image_info& info, pixbuf& pixels) 00508 : streaming_impl< consumer< pixel, 00509 pixel_consumer, 00510 image_info_ref_holder, 00511 true > >(info, pixels) 00512 { 00513 } 00514 00515 void reset(size_t pass) 00516 { 00517 if (pass == 0) 00518 { 00519 this->m_pixbuf.resize(this->get_info().get_width(), 00520 this->get_info().get_height()); 00521 } 00522 } 00523 }; 00524 00528 class pixel_generator 00529 : public streaming_impl< generator< pixel, 00530 pixel_generator, 00531 image_info_ref_holder, 00532 /* interlacing = */ true > > 00533 { 00534 public: 00535 pixel_generator(image_info& info, pixbuf& pixels) 00536 : streaming_impl< generator< pixel, 00537 pixel_generator, 00538 image_info_ref_holder, 00539 true > >(info, pixels) 00540 { 00541 } 00542 }; 00543 00544 image_info m_info; 00545 pixbuf m_pixbuf; 00546 }; 00547 00548 } // namespace png 00549 00550 #endif // PNGPP_IMAGE_HPP_INCLUDED