Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/boost/gil/extension/io/targa/detail/reader_backend.hpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 //
0002 // Copyright 2012 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_READER_BACKEND_HPP
0009 #define BOOST_GIL_EXTENSION_IO_TARGA_DETAIL_READER_BACKEND_HPP
0010 
0011 #include <boost/gil/extension/io/targa/tags.hpp>
0012 
0013 namespace boost { namespace gil {
0014 
0015 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
0016 #pragma warning(push)
0017 #pragma warning(disable:4512) //assignment operator could not be generated
0018 #endif
0019 
0020 ///
0021 /// Targa Backend
0022 ///
0023 template< typename Device >
0024 struct reader_backend< Device
0025                      , targa_tag
0026                      >
0027 {
0028 public:
0029 
0030     using format_tag_t = targa_tag;
0031 
0032 public:
0033 
0034     reader_backend( const Device&                           io_dev
0035                   , const image_read_settings< targa_tag >& settings
0036                   )
0037     : _io_dev  ( io_dev   )
0038     , _scanline_length(0)
0039     , _settings( settings )
0040     , _info()
0041     {
0042         read_header();
0043 
0044         if( _settings._dim.x == 0 )
0045         {
0046             _settings._dim.x = _info._width;
0047         }
0048 
0049         if( _settings._dim.y == 0 )
0050         {
0051             _settings._dim.y = _info._height;
0052         }
0053     }
0054 
0055     void read_header()
0056     {
0057         _info._header_size = targa_header_size::_size;
0058 
0059         _info._offset = _io_dev.read_uint8() + _info._header_size;
0060 
0061         _info._color_map_type = _io_dev.read_uint8();
0062         _info._image_type = _io_dev.read_uint8();
0063 
0064         _info._color_map_start  = _io_dev.read_uint16();
0065         _info._color_map_length = _io_dev.read_uint16();
0066         _info._color_map_depth  = _io_dev.read_uint8();
0067 
0068         _info._x_origin = _io_dev.read_uint16();
0069         _info._y_origin = _io_dev.read_uint16();
0070 
0071         _info._width  = _io_dev.read_uint16();
0072         _info._height = _io_dev.read_uint16();
0073 
0074         if( _info._width < 1 || _info._height < 1 )
0075         {
0076             io_error( "Invalid dimension for targa file" );
0077         }
0078 
0079         _info._bits_per_pixel = _io_dev.read_uint8();
0080         if( _info._bits_per_pixel != 24 && _info._bits_per_pixel != 32 )
0081         {
0082             io_error( "Unsupported bit depth for targa file" );
0083         }
0084 
0085         _info._descriptor = _io_dev.read_uint8();
0086 
0087         // According to TGA specs, http://www.gamers.org/dEngine/quake3/TGA.txt,
0088         // the image descriptor byte is:
0089         //
0090         // For Data Type 1, This entire byte should be set to 0.
0091         if (_info._image_type == 1 && _info._descriptor != 0)
0092         {
0093             io_error("Unsupported descriptor for targa file");
0094         }
0095         else if (_info._bits_per_pixel == 24)
0096         {
0097             // Bits 3-0 - For the Targa 24, it should be 0.
0098             if ((_info._descriptor & 0x0FU) != 0)
0099             {
0100                 io_error("Unsupported descriptor for targa file");
0101             }
0102         }
0103         else if (_info._bits_per_pixel == 32)
0104         {
0105             // Bits 3-0 - For Targa 32, it should be 8.
0106             if (_info._descriptor != 8 && _info._descriptor != 40)
0107             {
0108                 io_error("Unsupported descriptor for targa file");
0109             }
0110         }
0111         else
0112         {
0113             io_error("Unsupported descriptor for targa file");
0114         }
0115 
0116         if (_info._descriptor & 32)
0117         {
0118             _info._screen_origin_bit = true;
0119         }
0120 
0121         _info._valid = true;
0122     }
0123 
0124     /// Check if image is large enough.
0125     void check_image_size( point_t const& img_dim )
0126     {
0127         if( _settings._dim.x > 0 )
0128         {
0129             if( img_dim.x < _settings._dim.x ) { io_error( "Supplied image is too small" ); }
0130         }
0131         else
0132         {
0133             if( img_dim.x < _info._width ) { io_error( "Supplied image is too small" ); }
0134         }
0135 
0136 
0137         if( _settings._dim.y > 0 )
0138         {
0139             if( img_dim.y < _settings._dim.y ) { io_error( "Supplied image is too small" ); }
0140         }
0141         else
0142         {
0143             if( img_dim.y < _info._height ) { io_error( "Supplied image is too small" ); }
0144         }
0145     }
0146 
0147 public:
0148 
0149     Device _io_dev;
0150 
0151     std::size_t _scanline_length;
0152 
0153     image_read_settings< targa_tag > _settings;
0154     image_read_info< targa_tag >     _info;
0155 };
0156 
0157 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
0158 #pragma warning(pop)
0159 #endif
0160 
0161 } // namespace gil
0162 } // namespace boost
0163 
0164 #endif