Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:36:57

0001 //
0002 // Copyright 2007-2012 Christian Henning, Andreas Pokorny, Lubomir Bourdev
0003 //
0004 // Distributed under the Boost Software License, Version 1.0
0005 // See accompanying file LICENSE_1_0.txt or copy at
0006 // http://www.boost.org/LICENSE_1_0.txt
0007 //
0008 #ifndef BOOST_GIL_EXTENSION_IO_PNG_DETAIL_SCANLINE_READ_HPP
0009 #define BOOST_GIL_EXTENSION_IO_PNG_DETAIL_SCANLINE_READ_HPP
0010 
0011 #include <boost/gil/extension/io/png/detail/is_allowed.hpp>
0012 #include <boost/gil/extension/io/png/detail/reader_backend.hpp>
0013 
0014 #include <boost/gil.hpp> // FIXME: Include what you use!
0015 #include <boost/gil/io/base.hpp>
0016 #include <boost/gil/io/conversion_policies.hpp>
0017 #include <boost/gil/io/device.hpp>
0018 #include <boost/gil/io/reader_base.hpp>
0019 #include <boost/gil/io/row_buffer_helper.hpp>
0020 #include <boost/gil/io/scanline_read_iterator.hpp>
0021 #include <boost/gil/io/typedefs.hpp>
0022 
0023 namespace boost { namespace gil {
0024 
0025 ///
0026 /// PNG Reader
0027 ///
0028 template< typename Device >
0029 class scanline_reader< Device
0030                      , png_tag
0031                      >
0032     : public reader_backend< Device
0033                            , png_tag
0034                            >
0035 {
0036 public:
0037 
0038     using tag_t = png_tag;
0039     using backend_t = reader_backend<Device, tag_t>;
0040     using this_t = scanline_reader<Device, tag_t>;
0041     using iterator_t = scanline_read_iterator<this_t>;
0042 
0043     //
0044     // Constructor
0045     //
0046     scanline_reader( const Device&                         io_dev
0047                    , const image_read_settings< png_tag >& settings
0048                    )
0049     : reader_backend< Device
0050                     , png_tag
0051                     >( io_dev
0052                      , settings
0053                      )
0054     {
0055         initialize();
0056     }
0057 
0058     void read( byte_t* dst
0059              , int
0060              )
0061     {
0062         read_scanline( dst );
0063     }
0064 
0065     /// Skip over a scanline.
0066     void skip( byte_t* dst, int )
0067     {
0068         read_scanline( dst );
0069     }
0070 
0071     iterator_t begin() { return iterator_t( *this ); }
0072     iterator_t end()   { return iterator_t( *this, this->_info._height ); }
0073 
0074 private:
0075 
0076     void initialize()
0077     {
0078         // Now it's time for some transformations.
0079 
0080         if( little_endian() )
0081         {
0082             if( this->_info._bit_depth == 16 )
0083             {
0084                 // Swap bytes of 16 bit files to least significant byte first.
0085                 png_set_swap( this->get()->_struct );
0086             }
0087 
0088             if( this->_info._bit_depth < 8 )
0089             {
0090                 // swap bits of 1, 2, 4 bit packed pixel formats
0091                 png_set_packswap( this->get()->_struct );
0092             }
0093         }
0094 
0095         if( this->_info._color_type == PNG_COLOR_TYPE_PALETTE )
0096         {
0097             png_set_palette_to_rgb( this->get()->_struct );
0098         }
0099 
0100         if( this->_info._num_trans > 0 )
0101         {
0102             png_set_tRNS_to_alpha( this->get()->_struct );
0103         }
0104 
0105         // Tell libpng to handle the gamma conversion for you.  The final call
0106         // is a good guess for PC generated images, but it should be configurable
0107         // by the user at run time by the user.  It is strongly suggested that
0108         // your application support gamma correction.
0109         if( this->_settings._apply_screen_gamma )
0110         {
0111             // png_set_gamma will change the image data!
0112 
0113 #ifdef BOOST_GIL_IO_PNG_FLOATING_POINT_SUPPORTED
0114         png_set_gamma( this->get()->_struct
0115                      , this->_settings._screen_gamma
0116                      , this->_info._file_gamma
0117                      );
0118 #else
0119         png_set_gamma( this->get()->_struct
0120                      , this->_settings._screen_gamma
0121                      , this->_info._file_gamma
0122                      );
0123 #endif // BOOST_GIL_IO_PNG_FLOATING_POINT_SUPPORTED
0124         }
0125 
0126         // Interlaced images are not supported.
0127         this->_number_passes = png_set_interlace_handling( this->get()->_struct );
0128         io_error_if( this->_number_passes != 1
0129                    , "scanline_read_iterator cannot read interlaced png images."
0130                    );
0131 
0132 
0133         // The above transformation might have changed the bit_depth and color type.
0134         png_read_update_info( this->get()->_struct
0135                             , this->get()->_info
0136                             );
0137 
0138         this->_info._bit_depth = png_get_bit_depth( this->get()->_struct
0139                                                   , this->get()->_info
0140                                                   );
0141 
0142         this->_info._num_channels = png_get_channels( this->get()->_struct
0143                                                     , this->get()->_info
0144                                                     );
0145 
0146         this->_info._color_type = png_get_color_type( this->get()->_struct
0147                                                     , this->get()->_info
0148                                                     );
0149 
0150         this->_scanline_length = png_get_rowbytes( this->get()->_struct
0151                                                  , this->get()->_info
0152                                                  );
0153     }
0154 
0155     void read_scanline( byte_t* dst )
0156     {
0157         png_read_row( this->get()->_struct
0158                     , dst
0159                     , NULL
0160                     );
0161     }
0162 };
0163 
0164 } // namespace gil
0165 } // namespace boost
0166 
0167 #endif