Back to home page

EIC code displayed by LXR

 
 

    


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

0001 //
0002 // Copyright 2012 Kenneth Riddile, Christian Henning
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_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 /// Targa Scanline Reader
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     // Constructor
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     /// Read part of image defined by View and return the data.
0059     void read( byte_t* dst, int pos )
0060     {
0061         // jump to scanline
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     /// Skip over a scanline.
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                         // jump to first scanline
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 } // namespace gil
0151 } // namespace boost
0152 
0153 #endif