Back to home page

EIC code displayed by LXR

 
 

    


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

0001 //
0002 // Copyright 2007-2012 Christian Henning, 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_TIFF_DETAIL_SCANLINE_READ_HPP
0009 #define BOOST_GIL_EXTENSION_IO_TIFF_DETAIL_SCANLINE_READ_HPP
0010 
0011 #include <boost/gil/extension/io/tiff/detail/device.hpp>
0012 #include <boost/gil/extension/io/tiff/detail/is_allowed.hpp>
0013 #include <boost/gil/extension/io/tiff/detail/reader_backend.hpp>
0014 
0015 #include <boost/gil/io/base.hpp>
0016 #include <boost/gil/io/bit_operations.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/row_buffer_helper.hpp>
0021 #include <boost/gil/io/scanline_read_iterator.hpp>
0022 
0023 #include <algorithm>
0024 #include <functional>
0025 #include <string>
0026 #include <type_traits>
0027 #include <vector>
0028 
0029 // taken from jpegxx - https://bitbucket.org/edd/jpegxx/src/ea2492a1a4a6/src/ijg_headers.hpp
0030 #ifndef BOOST_GIL_EXTENSION_IO_TIFF_C_LIB_COMPILED_AS_CPLUSPLUS
0031     extern "C" {
0032 #endif
0033 
0034 #include <tiff.h>
0035 #include <tiffio.h>
0036 
0037 #ifndef BOOST_GIL_EXTENSION_IO_TIFF_C_LIB_COMPILED_AS_CPLUSPLUS
0038     }
0039 #endif
0040 
0041 namespace boost { namespace gil {
0042 
0043 ///
0044 /// TIFF scanline reader
0045 ///
0046 template< typename Device >
0047 class scanline_reader< Device
0048                      , tiff_tag
0049                      >
0050     : public reader_backend< Device
0051                            , tiff_tag
0052                            >
0053 {
0054 public:
0055 
0056     using tag_t = tiff_tag;
0057     using backend_t = reader_backend<Device, tag_t>;
0058     using this_t = scanline_reader<Device, tag_t>;
0059     using iterator_t = scanline_read_iterator<this_t>;
0060 
0061     scanline_reader( Device&                                device
0062                    , const image_read_settings< tiff_tag >& settings
0063                    )
0064     : backend_t( device
0065                , settings
0066                )
0067     {
0068         initialize();
0069     }
0070 
0071     /// Read part of image defined by View and return the data.
0072     void read( byte_t* dst, int pos )
0073     {
0074         _read_function( this, dst, pos );
0075     }
0076 
0077     /// Skip over a scanline.
0078     void skip( byte_t* dst, int pos )
0079     {
0080         this->_read_function( this, dst, pos );
0081     }
0082 
0083     iterator_t begin() { return iterator_t( *this ); }
0084     iterator_t end()   { return iterator_t( *this, this->_info._height ); }
0085 
0086 private:
0087 
0088     void initialize()
0089     {
0090         io_error_if( this->_info._is_tiled
0091                    , "scanline_reader doesn't support tiled tiff images."
0092                    );
0093 
0094         if( this->_info._photometric_interpretation == PHOTOMETRIC_PALETTE )
0095         {
0096 
0097             this->_scanline_length = this->_info._width
0098                                    * num_channels< rgb16_view_t >::value
0099                                    * sizeof( channel_type<rgb16_view_t>::type );
0100 
0101             this->_io_dev.get_field_defaulted( this->_red
0102                                         , this->_green
0103                                         , this->_blue
0104                                         );
0105 
0106             _buffer = std::vector< byte_t >( this->_io_dev.get_scanline_size() );
0107 
0108             switch( this->_info._bits_per_sample )
0109             {
0110                 case 1:
0111                 {
0112                     using channel_t = channel_type<get_pixel_type<gray1_image_t::view_t>::type>::type;
0113 
0114                     int num_colors = channel_traits< channel_t >::max_value() + 1;
0115 
0116                     this->_palette = planar_rgb_view( num_colors
0117                                               , 1
0118                                               , this->_red
0119                                               , this->_green
0120                                               , this->_blue
0121                                               , sizeof(uint16_t) * num_colors
0122                                               );
0123 
0124                     _read_function = std::mem_fn(&this_t::read_1_bit_index_image);
0125 
0126                     break;
0127                 }
0128 
0129                 case 2:
0130                 {
0131                     using channel_t = channel_type<get_pixel_type<gray2_image_t::view_t>::type>::type;
0132 
0133                     int num_colors = channel_traits< channel_t >::max_value() + 1;
0134 
0135                     this->_palette = planar_rgb_view( num_colors
0136                                               , 1
0137                                               , this->_red
0138                                               , this->_green
0139                                               , this->_blue
0140                                               , sizeof(uint16_t) * num_colors
0141                                               );
0142 
0143                     _read_function = std::mem_fn(&this_t::read_2_bits_index_image);
0144 
0145                     break;
0146                 }
0147                 case 4:
0148                 {
0149                     using channel_t = channel_type<get_pixel_type<gray4_image_t::view_t>::type>::type;
0150 
0151                     int num_colors = channel_traits< channel_t >::max_value() + 1;
0152 
0153                     this->_palette = planar_rgb_view( num_colors
0154                                               , 1
0155                                               , this->_red
0156                                               , this->_green
0157                                               , this->_blue
0158                                               , sizeof(uint16_t) * num_colors
0159                                               );
0160 
0161                     _read_function = std::mem_fn(&this_t::read_4_bits_index_image);
0162 
0163                     break;
0164                 }
0165 
0166                 case 8:
0167                 {
0168                     using channel_t = channel_type<get_pixel_type<gray8_image_t::view_t>::type>::type;
0169 
0170                     int num_colors = channel_traits< channel_t >::max_value() + 1;
0171 
0172                     this->_palette = planar_rgb_view( num_colors
0173                                               , 1
0174                                               , this->_red
0175                                               , this->_green
0176                                               , this->_blue
0177                                               , sizeof(uint16_t) * num_colors
0178                                               );
0179 
0180                     _read_function = std::mem_fn(&this_t::read_8_bits_index_image);
0181 
0182                     break;
0183                 }
0184 
0185                 case 16:
0186                 {
0187                     using channel_t = channel_type<get_pixel_type<gray16_image_t::view_t>::type>::type;
0188 
0189                     int num_colors = channel_traits< channel_t >::max_value() + 1;
0190 
0191                     this->_palette = planar_rgb_view( num_colors
0192                                               , 1
0193                                               , this->_red
0194                                               , this->_green
0195                                               , this->_blue
0196                                               , sizeof(uint16_t) * num_colors
0197                                               );
0198 
0199                     _read_function = std::mem_fn(&this_t::read_16_bits_index_image);
0200 
0201                     break;
0202                 }
0203 
0204                 case 24:
0205                 {
0206                     using channel_t = channel_type<get_pixel_type<gray24_image_t::view_t>::type>::type;
0207 
0208                     int num_colors = channel_traits< channel_t >::max_value() + 1;
0209 
0210                     this->_palette = planar_rgb_view( num_colors
0211                                               , 1
0212                                               , this->_red
0213                                               , this->_green
0214                                               , this->_blue
0215                                               , sizeof(uint16_t) * num_colors
0216                                               );
0217 
0218                     _read_function = std::mem_fn(&this_t::read_24_bits_index_image);
0219 
0220                     break;
0221                 }
0222 
0223                 case 32:
0224                 {
0225                     using channel_t = channel_type<get_pixel_type<gray32_image_t::view_t>::type>::type;
0226 
0227                     int num_colors = channel_traits< channel_t >::max_value() + 1;
0228 
0229                     this->_palette = planar_rgb_view( num_colors
0230                                               , 1
0231                                               , this->_red
0232                                               , this->_green
0233                                               , this->_blue
0234                                               , sizeof(uint16_t) * num_colors
0235                                               );
0236 
0237                     _read_function = std::mem_fn(&this_t::read_32_bits_index_image);
0238 
0239                     break;
0240                 }
0241                 default: { io_error( "Not supported palette " ); }
0242             }
0243         }
0244         else
0245         {
0246             this->_scanline_length = this->_io_dev.get_scanline_size();
0247 
0248             if( this->_info._planar_configuration == PLANARCONFIG_SEPARATE )
0249             {
0250                 io_error( "scanline_reader doesn't support planar tiff images." );
0251             }
0252             else if( this->_info._planar_configuration == PLANARCONFIG_CONTIG )
0253             {
0254 
0255                 // the read_data function needs to know what gil type the source image is
0256                 // to have the default color converter function correctly
0257 
0258                 switch( this->_info._photometric_interpretation )
0259                 {
0260                     case PHOTOMETRIC_MINISWHITE:
0261                     case PHOTOMETRIC_MINISBLACK:
0262                     {
0263                         switch( this->_info._bits_per_sample )
0264                         {
0265                             case  1:
0266                             case  2:
0267                             case  4:
0268                             case  6:
0269                             case  8:
0270                             case 10:
0271                             case 12:
0272                             case 14:
0273                             case 16:
0274                             case 24:
0275                             case 32: { _read_function = std::mem_fn(&this_t::read_row); break; }
0276                             default: { io_error( "Image type is not supported." ); }
0277                         }
0278 
0279                         break;
0280                     }
0281 
0282                     case PHOTOMETRIC_RGB:
0283                     {
0284                         switch( this->_info._samples_per_pixel )
0285                         {
0286                             case 3:
0287                             {
0288                                 switch( this->_info._bits_per_sample )
0289                                 {
0290                                     case  2:
0291                                     case  4:
0292                                     case  8:
0293                                     case 10:
0294                                     case 12:
0295                                     case 14:
0296                                     case 16:
0297                                     case 24:
0298                                     case 32: { _read_function = std::mem_fn(&this_t::read_row);  break; }
0299                                     default: { io_error( "Image type is not supported." ); }
0300                                 }
0301 
0302                                 break;
0303                             }
0304 
0305                             case 4:
0306                             {
0307                                 switch( this->_info._bits_per_sample )
0308                                 {
0309                                     case  2:
0310                                     case  4:
0311                                     case  8:
0312                                     case 10:
0313                                     case 12:
0314                                     case 14:
0315                                     case 16:
0316                                     case 24:
0317                                     case 32: { _read_function = std::mem_fn(&this_t::read_row);  break; }
0318                                     default: { io_error( "Image type is not supported." ); }
0319                                 }
0320 
0321                                 break;
0322                             }
0323 
0324                             default: { io_error( "Image type is not supported." ); }
0325                         }
0326 
0327                         break;
0328                     }
0329                     case PHOTOMETRIC_SEPARATED: // CYMK
0330                     {
0331                         switch( this->_info._bits_per_sample )
0332                         {
0333                             case  2:
0334                             case  4:
0335                             case  8:
0336                             case 10:
0337                             case 12:
0338                             case 14:
0339                             case 16:
0340                             case 24:
0341                             case 32: { _read_function = std::mem_fn(&this_t::read_row);  break; }
0342                             default: { io_error( "Image type is not supported." ); }
0343                         }
0344 
0345                         break;
0346                     }
0347 
0348                     default: { io_error( "Image type is not supported." ); }
0349                 }
0350             }
0351             else
0352             {
0353                 io_error( "Wrong planar configuration setting." );
0354             }
0355         }
0356     }
0357 
0358     template< typename Src_View >
0359     void read_n_bits_row( byte_t* dst, int pos )
0360     {
0361         using dst_view_t = rgb16_view_t;
0362 
0363         this->_io_dev.read_scanline( _buffer
0364                                    , pos
0365                                    , 0
0366                                    );
0367 
0368         Src_View src_view = interleaved_view( this->_info._width
0369                                             , 1
0370                                             , (typename Src_View::x_iterator) &_buffer.front()
0371                                             , this->_scanline_length
0372                                             );
0373 
0374         dst_view_t dst_view = interleaved_view( this->_info._width
0375                                               , 1
0376                                               , (typename dst_view_t::value_type*) dst
0377                                               , num_channels< dst_view_t >::value * 2 * this->_info._width
0378                                               );
0379 
0380 
0381         typename Src_View::x_iterator   src_it = src_view.row_begin( 0 );
0382         typename dst_view_t::x_iterator dst_it = dst_view.row_begin( 0 );
0383 
0384         for( dst_view_t::x_coord_t i = 0
0385            ; i < this->_info._width
0386            ; ++i, src_it++, dst_it++
0387            )
0388         {
0389             auto const c = static_cast<std::uint16_t>(get_color(*src_it, gray_color_t()));
0390             *dst_it = this->_palette[c];
0391         }
0392     }
0393 
0394     void read_1_bit_index_image( byte_t* dst, int pos )
0395     {
0396         read_n_bits_row< gray1_image_t::view_t >( dst, pos );
0397     }
0398 
0399     void read_2_bits_index_image( byte_t* dst, int pos )
0400     {
0401         read_n_bits_row< gray2_image_t::view_t >( dst, pos );
0402     }
0403 
0404     void read_4_bits_index_image( byte_t* dst, int pos )
0405     {
0406         read_n_bits_row< gray4_image_t::view_t >( dst, pos );
0407     }
0408 
0409     void read_8_bits_index_image( byte_t* dst, int pos )
0410     {
0411         read_n_bits_row< gray8_image_t::view_t >( dst, pos );
0412     }
0413 
0414     void read_16_bits_index_image( byte_t* dst, int pos )
0415     {
0416         read_n_bits_row< gray16_image_t::view_t >( dst, pos );
0417     }
0418 
0419     void read_24_bits_index_image( byte_t* dst, int pos )
0420     {
0421         read_n_bits_row< gray24_image_t::view_t >( dst, pos );
0422     }
0423 
0424     void read_32_bits_index_image( byte_t* dst, int pos )
0425     {
0426         read_n_bits_row< gray32_image_t::view_t >( dst, pos );
0427     }
0428 
0429     void read_row(byte_t* dst, int pos )
0430     {
0431          this->_io_dev.read_scanline( dst
0432                                     , pos
0433                                     , 0
0434                                     );
0435     }
0436 
0437 private:
0438 
0439     std::vector< byte_t> _buffer;
0440     detail::mirror_bits<std::vector<byte_t>, std::true_type> _mirror_bites;
0441     std::function<void(this_t*, byte_t*, int)> _read_function;
0442 };
0443 
0444 } // namespace gil
0445 } // namespace boost
0446 
0447 #endif