diff options
Diffstat (limited to 'boost/gil/extension/io/jpeg/detail/scanline_read.hpp')
-rw-r--r-- | boost/gil/extension/io/jpeg/detail/scanline_read.hpp | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/boost/gil/extension/io/jpeg/detail/scanline_read.hpp b/boost/gil/extension/io/jpeg/detail/scanline_read.hpp new file mode 100644 index 0000000000..ee33154c61 --- /dev/null +++ b/boost/gil/extension/io/jpeg/detail/scanline_read.hpp @@ -0,0 +1,163 @@ +/* + 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_JPEG_DETAIL_SCANLINE_READ_HPP +#define BOOST_GIL_EXTENSION_IO_JPEG_DETAIL_SCANLINE_READ_HPP + +//////////////////////////////////////////////////////////////////////////////////////// +/// \file +/// \brief +/// \author Christian Henning, Andreas Pokorny, Lubomir Bourdev \n +/// +/// \date 2007-2012 \n +/// +//////////////////////////////////////////////////////////////////////////////////////// + +#include <csetjmp> +#include <vector> + +#include <boost/gil/io/base.hpp> +#include <boost/gil/io/conversion_policies.hpp> +#include <boost/gil/io/reader_base.hpp> +#include <boost/gil/io/device.hpp> +#include <boost/gil/io/scanline_read_iterator.hpp> +#include <boost/gil/io/typedefs.hpp> + + +#include <boost/gil/extension/io/jpeg/detail/reader_backend.hpp> +#include <boost/gil/extension/io/jpeg/detail/base.hpp> +#include <boost/gil/extension/io/jpeg/detail/is_allowed.hpp> + +namespace boost { namespace gil { + +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) +#pragma warning(push) +#pragma warning(disable:4611) //interaction between '_setjmp' and C++ object destruction is non-portable +#endif + +/// +/// JPEG Scanline Reader +/// +template< typename Device > +class scanline_reader< Device + , jpeg_tag + > + : public reader_backend< Device + , jpeg_tag + > +{ +public: + + typedef jpeg_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: + scanline_reader( Device& device + , const image_read_settings< jpeg_tag >& settings + ) + : reader_backend< Device + , jpeg_tag + >( device + , settings + ) + { + initialize(); + } + + void read( byte_t* dst + , int + ) + { + // Fire exception in case of error. + if( setjmp( this->_mark )) { this->raise_error(); } + + // read data + read_scanline( dst ); + } + + /// Skip over a scanline. + void skip( byte_t* dst, int ) + { + // Fire exception in case of error. + if( setjmp( this->_mark )) { this->raise_error(); } + + // read data + read_scanline( dst ); + } + + iterator_t begin() { return iterator_t( *this ); } + iterator_t end() { return iterator_t( *this, this->_info._height ); } + +private: + + void initialize() + { + this->get()->dct_method = this->_settings._dct_method; + + io_error_if( jpeg_start_decompress( this->get() ) == false + , "Cannot start decompression." ); + + switch( this->_info._color_space ) + { + case JCS_GRAYSCALE: + { + this->_scanline_length = this->_info._width; + + break; + } + + case JCS_RGB: + //!\todo add Y'CbCr? We loose image quality when reading JCS_YCbCr as JCS_RGB + case JCS_YCbCr: + { + this->_scanline_length = this->_info._width * num_channels< rgb8_view_t >::value; + + break; + } + + + case JCS_CMYK: + //!\todo add Y'CbCrK? We loose image quality when reading JCS_YCCK as JCS_CMYK + case JCS_YCCK: + { + this->get()->out_color_space = JCS_CMYK; + this->_scanline_length = this->_info._width * num_channels< cmyk8_view_t >::value; + + break; + } + + default: { io_error( "Unsupported jpeg color space." ); } + } + } + + void read_scanline( byte_t* dst ) + { + JSAMPLE *row_adr = reinterpret_cast< JSAMPLE* >( dst ); + + // Read data. + io_error_if( jpeg_read_scanlines( this->get() + , &row_adr + , 1 + ) != 1 + , "jpeg_read_scanlines: fail to read JPEG file" + ); + + } +}; + +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) +#pragma warning(pop) +#endif + +} // namespace gil +} // namespace boost + +#endif |