File indexing completed on 2025-01-18 09:36:57
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_GIL_EXTENSION_IO_JPEG_DETAIL_SCANLINE_READ_HPP
0009 #define BOOST_GIL_EXTENSION_IO_JPEG_DETAIL_SCANLINE_READ_HPP
0010
0011
0012 #include <boost/gil/extension/io/jpeg/detail/base.hpp>
0013 #include <boost/gil/extension/io/jpeg/detail/is_allowed.hpp>
0014 #include <boost/gil/extension/io/jpeg/detail/reader_backend.hpp>
0015
0016 #include <boost/gil/io/base.hpp>
0017 #include <boost/gil/io/conversion_policies.hpp>
0018 #include <boost/gil/io/device.hpp>
0019 #include <boost/gil/io/reader_base.hpp>
0020 #include <boost/gil/io/scanline_read_iterator.hpp>
0021 #include <boost/gil/io/typedefs.hpp>
0022
0023 #include <csetjmp>
0024 #include <vector>
0025
0026 namespace boost { namespace gil {
0027
0028 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
0029 #pragma warning(push)
0030 #pragma warning(disable:4611)
0031 #endif
0032
0033
0034
0035
0036 template< typename Device >
0037 class scanline_reader< Device
0038 , jpeg_tag
0039 >
0040 : public reader_backend< Device
0041 , jpeg_tag
0042 >
0043 {
0044 public:
0045
0046 using tag_t = jpeg_tag;
0047 using backend_t = reader_backend<Device, tag_t>;
0048 using this_t = scanline_reader<Device, tag_t>;
0049 using iterator_t = scanline_read_iterator<this_t>;
0050
0051 public:
0052 scanline_reader( Device& device
0053 , const image_read_settings< jpeg_tag >& settings
0054 )
0055 : reader_backend< Device
0056 , jpeg_tag
0057 >( device
0058 , settings
0059 )
0060 {
0061 initialize();
0062 }
0063
0064 void read( byte_t* dst
0065 , int
0066 )
0067 {
0068
0069 if( setjmp( this->_mark )) { this->raise_error(); }
0070
0071
0072 read_scanline( dst );
0073 }
0074
0075
0076 void skip( byte_t* dst, int )
0077 {
0078
0079 if( setjmp( this->_mark )) { this->raise_error(); }
0080
0081
0082 read_scanline( dst );
0083 }
0084
0085 iterator_t begin() { return iterator_t( *this ); }
0086 iterator_t end() { return iterator_t( *this, this->_info._height ); }
0087
0088 private:
0089
0090 void initialize()
0091 {
0092 this->get()->dct_method = this->_settings._dct_method;
0093
0094 io_error_if( jpeg_start_decompress( this->get() ) == false
0095 , "Cannot start decompression." );
0096
0097 switch( this->_info._color_space )
0098 {
0099 case JCS_GRAYSCALE:
0100 {
0101 this->_scanline_length = this->_info._width;
0102
0103 break;
0104 }
0105
0106 case JCS_RGB:
0107
0108 case JCS_YCbCr:
0109 {
0110 this->_scanline_length = this->_info._width * num_channels< rgb8_view_t >::value;
0111
0112 break;
0113 }
0114
0115
0116 case JCS_CMYK:
0117
0118 case JCS_YCCK:
0119 {
0120 this->get()->out_color_space = JCS_CMYK;
0121 this->_scanline_length = this->_info._width * num_channels< cmyk8_view_t >::value;
0122
0123 break;
0124 }
0125
0126 default: { io_error( "Unsupported jpeg color space." ); }
0127 }
0128 }
0129
0130 void read_scanline( byte_t* dst )
0131 {
0132 JSAMPLE *row_adr = reinterpret_cast< JSAMPLE* >( dst );
0133
0134
0135 io_error_if( jpeg_read_scanlines( this->get()
0136 , &row_adr
0137 , 1
0138 ) != 1
0139 , "jpeg_read_scanlines: fail to read JPEG file"
0140 );
0141
0142 }
0143 };
0144
0145 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
0146 #pragma warning(pop)
0147 #endif
0148
0149 }
0150 }
0151
0152 #endif