Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:36:57

0001 //
0002 // Copyright 2007-2012 Christian Henning, Andreas Pokorny, Lubomir Bourdev
0003 //
0004 // Distributed under the Boost Software License, Version 1.0
0005 // See accompanying file LICENSE_1_0.txt or copy at
0006 // http://www.boost.org/LICENSE_1_0.txt
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) //interaction between '_setjmp' and C++ object destruction is non-portable
0031 #endif
0032 
0033 ///
0034 /// JPEG Scanline Reader
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         // Fire exception in case of error.
0069         if( setjmp( this->_mark )) { this->raise_error(); }
0070 
0071         // read data
0072         read_scanline( dst );
0073     }
0074 
0075     /// Skip over a scanline.
0076     void skip( byte_t* dst, int )
0077     {
0078         // Fire exception in case of error.
0079         if( setjmp( this->_mark )) { this->raise_error(); }
0080 
0081         // read data
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             //!\todo add Y'CbCr? We loose image quality when reading JCS_YCbCr as JCS_RGB
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             //!\todo add Y'CbCrK? We loose image quality when reading JCS_YCCK as JCS_CMYK
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         // Read data.
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 } // namespace gil
0150 } // namespace boost
0151 
0152 #endif