scanline_read.hpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. //
  2. // Copyright 2012 Kenneth Riddile, Christian Henning
  3. //
  4. // Distributed under the Boost Software License, Version 1.0
  5. // See accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt
  7. //
  8. #ifndef BOOST_GIL_EXTENSION_IO_TARGA_DETAIL_SCANLINE_READ_HPP
  9. #define BOOST_GIL_EXTENSION_IO_TARGA_DETAIL_SCANLINE_READ_HPP
  10. #include <boost/gil/extension/io/targa/detail/is_allowed.hpp>
  11. #include <boost/gil/extension/io/targa/detail/reader_backend.hpp>
  12. #include <boost/gil/io/base.hpp>
  13. #include <boost/gil/io/bit_operations.hpp>
  14. #include <boost/gil/io/conversion_policies.hpp>
  15. #include <boost/gil/io/device.hpp>
  16. #include <boost/gil/io/reader_base.hpp>
  17. #include <boost/gil/io/row_buffer_helper.hpp>
  18. #include <boost/gil/io/scanline_read_iterator.hpp>
  19. #include <boost/gil/io/typedefs.hpp>
  20. #include <vector>
  21. namespace boost { namespace gil {
  22. ///
  23. /// Targa Scanline Reader
  24. ///
  25. template< typename Device >
  26. class scanline_reader< Device
  27. , targa_tag
  28. >
  29. : public reader_backend< Device
  30. , targa_tag
  31. >
  32. {
  33. public:
  34. using tag_t = targa_tag;
  35. using backend_t = reader_backend<Device, tag_t>;
  36. using this_t = scanline_reader<Device, tag_t>;
  37. using iterator_t = scanline_read_iterator<this_t>;
  38. //
  39. // Constructor
  40. //
  41. scanline_reader( Device& device
  42. , const image_read_settings< targa_tag >& settings
  43. )
  44. : backend_t( device
  45. , settings
  46. )
  47. {
  48. initialize();
  49. }
  50. /// Read part of image defined by View and return the data.
  51. void read( byte_t* dst, int pos )
  52. {
  53. // jump to scanline
  54. long offset = this->_info._offset
  55. + ( this->_info._height - 1 - pos ) * static_cast< long >( this->_scanline_length );
  56. this->_io_dev.seek( offset );
  57. read_row( dst );
  58. }
  59. /// Skip over a scanline.
  60. void skip( byte_t*, int )
  61. {
  62. this->_io_dev.seek( static_cast<long>( this->_scanline_length )
  63. , SEEK_CUR
  64. );
  65. }
  66. iterator_t begin() { return iterator_t( *this ); }
  67. iterator_t end() { return iterator_t( *this, this->_info._height ); }
  68. private:
  69. void initialize()
  70. {
  71. if( this->_info._color_map_type != targa_color_map_type::_rgb )
  72. {
  73. io_error( "scanline reader cannot read indexed targa files." );
  74. }
  75. if( this->_info._image_type != targa_image_type::_rgb )
  76. {
  77. io_error( "scanline reader cannot read this targa image type." );
  78. }
  79. switch( this->_info._image_type )
  80. {
  81. case targa_image_type::_rgb:
  82. {
  83. if( this->_info._color_map_type != targa_color_map_type::_rgb )
  84. {
  85. io_error( "Inconsistent color map type and image type in targa file." );
  86. }
  87. if( this->_info._color_map_length != 0 )
  88. {
  89. io_error( "Non-indexed targa files containing a palette are not supported." );
  90. }
  91. if( this->_info._screen_origin_bit )
  92. {
  93. io_error( "scanline reader cannot read targa files which have screen origin bit set." );
  94. }
  95. switch( this->_info._bits_per_pixel )
  96. {
  97. case 24:
  98. case 32:
  99. {
  100. this->_scanline_length = this->_info._width * ( this->_info._bits_per_pixel / 8 );
  101. // jump to first scanline
  102. this->_io_dev.seek( static_cast< long >( this->_info._offset ));
  103. break;
  104. }
  105. default:
  106. {
  107. io_error( "Unsupported bit depth in targa file." );
  108. break;
  109. }
  110. }
  111. break;
  112. }
  113. default:
  114. {
  115. io_error( "Unsupported image type in targa file." );
  116. break;
  117. }
  118. }
  119. }
  120. void read_row( byte_t* dst )
  121. {
  122. this->_io_dev.read( dst, this->_scanline_length );
  123. }
  124. };
  125. } // namespace gil
  126. } // namespace boost
  127. #endif