123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- //
- // 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_JPEG_DETAIL_SCANLINE_READ_HPP
- #define BOOST_GIL_EXTENSION_IO_JPEG_DETAIL_SCANLINE_READ_HPP
- #include <boost/gil/extension/io/jpeg/detail/base.hpp>
- #include <boost/gil/extension/io/jpeg/detail/is_allowed.hpp>
- #include <boost/gil/extension/io/jpeg/detail/reader_backend.hpp>
- #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/scanline_read_iterator.hpp>
- #include <boost/gil/io/typedefs.hpp>
- #include <csetjmp>
- #include <vector>
- 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:
- using tag_t = jpeg_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>;
- 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
|