diff options
Diffstat (limited to 'boost/gil/extension/io/png/detail/scanline_read.hpp')
-rw-r--r-- | boost/gil/extension/io/png/detail/scanline_read.hpp | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/boost/gil/extension/io/png/detail/scanline_read.hpp b/boost/gil/extension/io/png/detail/scanline_read.hpp new file mode 100644 index 0000000000..33b1dcba31 --- /dev/null +++ b/boost/gil/extension/io/png/detail/scanline_read.hpp @@ -0,0 +1,181 @@ +/* + Copyright 2007-2012 Christian Henning, Andreas Pokorny, Lubomir Bourdev + Use, modification and distribution are subject to 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 + +//////////////////////////////////////////////////////////////////////////////////////// +/// \file +/// \brief +/// \author Christian Henning, Andreas Pokorny, Lubomir Bourdev \n +/// +/// \date 2007-2012 \n +/// +//////////////////////////////////////////////////////////////////////////////////////// + +#include <boost/gil.hpp> + +#include <boost/gil/io/base.hpp> +#include <boost/gil/io/reader_base.hpp> +#include <boost/gil/io/conversion_policies.hpp> +#include <boost/gil/io/device.hpp> +#include <boost/gil/io/typedefs.hpp> +#include <boost/gil/io/row_buffer_helper.hpp> +#include <boost/gil/io/scanline_read_iterator.hpp> + +#include <boost/gil/extension/io/png/detail/reader_backend.hpp> +#include <boost/gil/extension/io/png/detail/is_allowed.hpp> + +namespace boost { namespace gil { + +/// +/// PNG Reader +/// +template< typename Device > +class scanline_reader< Device + , png_tag + > + : public reader_backend< Device + , png_tag + > +{ +public: + + typedef png_tag tag_t; + typedef reader_backend < Device, tag_t > backend_t; + typedef scanline_reader< Device, tag_t > this_t; + typedef scanline_read_iterator< this_t > iterator_t; + +public: + + // + // 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 |