File indexing completed on 2025-01-18 09:36:57
0001
0002
0003
0004
0005
0006
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
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
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
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
0079
0080 if( little_endian() )
0081 {
0082 if( this->_info._bit_depth == 16 )
0083 {
0084
0085 png_set_swap( this->get()->_struct );
0086 }
0087
0088 if( this->_info._bit_depth < 8 )
0089 {
0090
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
0106
0107
0108
0109 if( this->_settings._apply_screen_gamma )
0110 {
0111
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
0124 }
0125
0126
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
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 }
0165 }
0166
0167 #endif