File indexing completed on 2025-01-18 09:36:59
0001
0002
0003
0004
0005
0006
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
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
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
0072 void read( byte_t* dst, int pos )
0073 {
0074 _read_function( this, dst, pos );
0075 }
0076
0077
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
0256
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:
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 }
0445 }
0446
0447 #endif