summaryrefslogtreecommitdiff
path: root/boost/gil/extension/io/png/detail/scanline_read.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/gil/extension/io/png/detail/scanline_read.hpp')
-rw-r--r--boost/gil/extension/io/png/detail/scanline_read.hpp181
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