png++  0.2.9
image.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_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