File indexing completed on 2025-01-18 09:36:59
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_GIL_EXTENSION_IO_TARGA_DETAIL_SCANLINE_READ_HPP
0009 #define BOOST_GIL_EXTENSION_IO_TARGA_DETAIL_SCANLINE_READ_HPP
0010
0011 #include <boost/gil/extension/io/targa/detail/is_allowed.hpp>
0012 #include <boost/gil/extension/io/targa/detail/reader_backend.hpp>
0013
0014 #include <boost/gil/io/base.hpp>
0015 #include <boost/gil/io/bit_operations.hpp>
0016 #include <boost/gil/io/conversion_policies.hpp>
0017 #include <boost/gil/io/device.hpp>
0018 #include <boost/gil/io/reader_base.hpp>
0019 #include <boost/gil/io/row_buffer_helper.hpp>
0020 #include <boost/gil/io/scanline_read_iterator.hpp>
0021 #include <boost/gil/io/typedefs.hpp>
0022
0023 #include <vector>
0024
0025 namespace boost { namespace gil {
0026
0027
0028
0029
0030 template< typename Device >
0031 class scanline_reader< Device
0032 , targa_tag
0033 >
0034 : public reader_backend< Device
0035 , targa_tag
0036 >
0037 {
0038 public:
0039
0040 using tag_t = targa_tag;
0041 using backend_t = reader_backend<Device, tag_t>;
0042 using this_t = scanline_reader<Device, tag_t>;
0043 using iterator_t = scanline_read_iterator<this_t>;
0044
0045
0046
0047
0048 scanline_reader( Device& device
0049 , const image_read_settings< targa_tag >& settings
0050 )
0051 : backend_t( device
0052 , settings
0053 )
0054 {
0055 initialize();
0056 }
0057
0058
0059 void read( byte_t* dst, int pos )
0060 {
0061
0062 long offset = this->_info._offset
0063 + ( this->_info._height - 1 - pos ) * static_cast< long >( this->_scanline_length );
0064
0065 this->_io_dev.seek( offset );
0066
0067
0068 read_row( dst );
0069 }
0070
0071
0072 void skip( byte_t*, int )
0073 {
0074 this->_io_dev.seek( static_cast<long>( this->_scanline_length )
0075 , SEEK_CUR
0076 );
0077 }
0078
0079 iterator_t begin() { return iterator_t( *this ); }
0080 iterator_t end() { return iterator_t( *this, this->_info._height ); }
0081
0082 private:
0083
0084 void initialize()
0085 {
0086 if( this->_info._color_map_type != targa_color_map_type::_rgb )
0087 {
0088 io_error( "scanline reader cannot read indexed targa files." );
0089 }
0090
0091 if( this->_info._image_type != targa_image_type::_rgb )
0092 {
0093 io_error( "scanline reader cannot read this targa image type." );
0094 }
0095
0096 switch( this->_info._image_type )
0097 {
0098 case targa_image_type::_rgb:
0099 {
0100 if( this->_info._color_map_type != targa_color_map_type::_rgb )
0101 {
0102 io_error( "Inconsistent color map type and image type in targa file." );
0103 }
0104
0105 if( this->_info._color_map_length != 0 )
0106 {
0107 io_error( "Non-indexed targa files containing a palette are not supported." );
0108 }
0109
0110 if( this->_info._screen_origin_bit )
0111 {
0112 io_error( "scanline reader cannot read targa files which have screen origin bit set." );
0113 }
0114
0115 switch( this->_info._bits_per_pixel )
0116 {
0117 case 24:
0118 case 32:
0119 {
0120 this->_scanline_length = this->_info._width * ( this->_info._bits_per_pixel / 8 );
0121
0122
0123 this->_io_dev.seek( static_cast< long >( this->_info._offset ));
0124
0125 break;
0126 }
0127 default:
0128 {
0129 io_error( "Unsupported bit depth in targa file." );
0130 break;
0131 }
0132 }
0133
0134 break;
0135 }
0136 default:
0137 {
0138 io_error( "Unsupported image type in targa file." );
0139 break;
0140 }
0141 }
0142 }
0143
0144 void read_row( byte_t* dst )
0145 {
0146 this->_io_dev.read( dst, this->_scanline_length );
0147 }
0148 };
0149
0150 }
0151 }
0152
0153 #endif