123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- //
- // Copyright 2007-2012 Christian Henning, Andreas Pokorny, Lubomir Bourdev
- //
- // Distributed under the Boost Software License, Version 1.0
- // See accompanying file LICENSE_1_0.txt or copy at
- // http://www.boost.org/LICENSE_1_0.txt
- //
- #ifndef BOOST_GIL_EXTENSION_IO_PNG_DETAIL_SCANLINE_READ_HPP
- #define BOOST_GIL_EXTENSION_IO_PNG_DETAIL_SCANLINE_READ_HPP
- #include <boost/gil/extension/io/png/detail/is_allowed.hpp>
- #include <boost/gil/extension/io/png/detail/reader_backend.hpp>
- #include <boost/gil.hpp> // FIXME: Include what you use!
- #include <boost/gil/io/base.hpp>
- #include <boost/gil/io/conversion_policies.hpp>
- #include <boost/gil/io/device.hpp>
- #include <boost/gil/io/reader_base.hpp>
- #include <boost/gil/io/row_buffer_helper.hpp>
- #include <boost/gil/io/scanline_read_iterator.hpp>
- #include <boost/gil/io/typedefs.hpp>
- namespace boost { namespace gil {
- ///
- /// PNG Reader
- ///
- template< typename Device >
- class scanline_reader< Device
- , png_tag
- >
- : public reader_backend< Device
- , png_tag
- >
- {
- public:
- using tag_t = png_tag;
- using backend_t = reader_backend<Device, tag_t>;
- using this_t = scanline_reader<Device, tag_t>;
- using iterator_t = scanline_read_iterator<this_t>;
- //
- // Constructor
- //
- scanline_reader( const Device& io_dev
- , const image_read_settings< png_tag >& settings
- )
- : reader_backend< Device
- , png_tag
- >( io_dev
- , settings
- )
- {
- initialize();
- }
- void read( byte_t* dst
- , int
- )
- {
- read_scanline( dst );
- }
- /// Skip over a scanline.
- void skip( byte_t* dst, int )
- {
- read_scanline( dst );
- }
- iterator_t begin() { return iterator_t( *this ); }
- iterator_t end() { return iterator_t( *this, this->_info._height ); }
- private:
- void initialize()
- {
- // Now it's time for some transformations.
- if( little_endian() )
- {
- if( this->_info._bit_depth == 16 )
- {
- // Swap bytes of 16 bit files to least significant byte first.
- png_set_swap( this->get()->_struct );
- }
- if( this->_info._bit_depth < 8 )
- {
- // swap bits of 1, 2, 4 bit packed pixel formats
- png_set_packswap( this->get()->_struct );
- }
- }
- if( this->_info._color_type == PNG_COLOR_TYPE_PALETTE )
- {
- png_set_palette_to_rgb( this->get()->_struct );
- }
- if( this->_info._num_trans > 0 )
- {
- png_set_tRNS_to_alpha( this->get()->_struct );
- }
- // Tell libpng to handle the gamma conversion for you. The final call
- // is a good guess for PC generated images, but it should be configurable
- // by the user at run time by the user. It is strongly suggested that
- // your application support gamma correction.
- if( this->_settings._apply_screen_gamma )
- {
- // png_set_gamma will change the image data!
- #ifdef BOOST_GIL_IO_PNG_FLOATING_POINT_SUPPORTED
- png_set_gamma( this->get()->_struct
- , this->_settings._screen_gamma
- , this->_info._file_gamma
- );
- #else
- png_set_gamma( this->get()->_struct
- , this->_settings._screen_gamma
- , this->_info._file_gamma
- );
- #endif // BOOST_GIL_IO_PNG_FLOATING_POINT_SUPPORTED
- }
- // Interlaced images are not supported.
- this->_number_passes = png_set_interlace_handling( this->get()->_struct );
- io_error_if( this->_number_passes != 1
- , "scanline_read_iterator cannot read interlaced png images."
- );
- // The above transformation might have changed the bit_depth and color type.
- png_read_update_info( this->get()->_struct
- , this->get()->_info
- );
- this->_info._bit_depth = png_get_bit_depth( this->get()->_struct
- , this->get()->_info
- );
- this->_info._num_channels = png_get_channels( this->get()->_struct
- , this->get()->_info
- );
- this->_info._color_type = png_get_color_type( this->get()->_struct
- , this->get()->_info
- );
- this->_scanline_length = png_get_rowbytes( this->get()->_struct
- , this->get()->_info
- );
- }
- void read_scanline( byte_t* dst )
- {
- png_read_row( this->get()->_struct
- , dst
- , NULL
- );
- }
- };
- } // namespace gil
- } // namespace boost
- #endif
|