// // Copyright 2012 Kenneth Riddile, Christian Henning // // Distributed under the Boost Software License, Version 1.0 // See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt // #ifndef BOOST_GIL_EXTENSION_IO_TARGA_DETAIL_SCANLINE_READ_HPP #define BOOST_GIL_EXTENSION_IO_TARGA_DETAIL_SCANLINE_READ_HPP #include #include #include #include #include #include #include #include #include #include #include namespace boost { namespace gil { /// /// Targa Scanline Reader /// template< typename Device > class scanline_reader< Device , targa_tag > : public reader_backend< Device , targa_tag > { public: using tag_t = targa_tag; using backend_t = reader_backend; using this_t = scanline_reader; using iterator_t = scanline_read_iterator; // // Constructor // scanline_reader( Device& device , const image_read_settings< targa_tag >& settings ) : backend_t( device , settings ) { initialize(); } /// Read part of image defined by View and return the data. void read( byte_t* dst, int pos ) { // jump to scanline long offset = this->_info._offset + ( this->_info._height - 1 - pos ) * static_cast< long >( this->_scanline_length ); this->_io_dev.seek( offset ); read_row( dst ); } /// Skip over a scanline. void skip( byte_t*, int ) { this->_io_dev.seek( static_cast( this->_scanline_length ) , SEEK_CUR ); } iterator_t begin() { return iterator_t( *this ); } iterator_t end() { return iterator_t( *this, this->_info._height ); } private: void initialize() { if( this->_info._color_map_type != targa_color_map_type::_rgb ) { io_error( "scanline reader cannot read indexed targa files." ); } if( this->_info._image_type != targa_image_type::_rgb ) { io_error( "scanline reader cannot read this targa image type." ); } switch( this->_info._image_type ) { case targa_image_type::_rgb: { if( this->_info._color_map_type != targa_color_map_type::_rgb ) { io_error( "Inconsistent color map type and image type in targa file." ); } if( this->_info._color_map_length != 0 ) { io_error( "Non-indexed targa files containing a palette are not supported." ); } if( this->_info._screen_origin_bit ) { io_error( "scanline reader cannot read targa files which have screen origin bit set." ); } switch( this->_info._bits_per_pixel ) { case 24: case 32: { this->_scanline_length = this->_info._width * ( this->_info._bits_per_pixel / 8 ); // jump to first scanline this->_io_dev.seek( static_cast< long >( this->_info._offset )); break; } default: { io_error( "Unsupported bit depth in targa file." ); break; } } break; } default: { io_error( "Unsupported image type in targa file." ); break; } } } void read_row( byte_t* dst ) { this->_io_dev.read( dst, this->_scanline_length ); } }; } // namespace gil } // namespace boost #endif