scanline_read_iterator.hpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. /*
  2. Copyright 2012 Christian Henning
  3. Use, modification and distribution are subject to the Boost Software License,
  4. Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  5. http://www.boost.org/LICENSE_1_0.txt).
  6. */
  7. /*************************************************************************************************/
  8. #ifndef BOOST_GIL_IO_SCANLINE_READ_ITERATOR_HPP
  9. #define BOOST_GIL_IO_SCANLINE_READ_ITERATOR_HPP
  10. ////////////////////////////////////////////////////////////////////////////////////////
  11. /// \file
  12. /// \brief
  13. /// \author Christian Henning
  14. ///
  15. /// \date 2012 \n
  16. ///
  17. ////////////////////////////////////////////////////////////////////////////////////////
  18. #include <boost/iterator/iterator_facade.hpp>
  19. #include <boost/gil/io/error.hpp>
  20. #include <memory>
  21. namespace boost { namespace gil {
  22. #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
  23. #pragma warning(push)
  24. #pragma warning(disable:4512) //assignment operator could not be generated
  25. #endif
  26. /// Input iterator to read images.
  27. template< typename Reader >
  28. class scanline_read_iterator : public boost::iterator_facade< scanline_read_iterator< Reader >
  29. , byte_t*
  30. , std::input_iterator_tag
  31. >
  32. {
  33. private:
  34. typedef boost::iterator_facade< scanline_read_iterator< Reader >
  35. , byte_t*
  36. , std::input_iterator_tag
  37. > base_t;
  38. public:
  39. scanline_read_iterator( Reader& reader
  40. , int pos = 0
  41. )
  42. : _pos( pos )
  43. , _read_scanline( true )
  44. , _skip_scanline( true )
  45. , _reader( reader )
  46. {
  47. _buffer = std::make_shared< buffer_t >( buffer_t( _reader._scanline_length ));
  48. _buffer_start = &_buffer->front();
  49. }
  50. private:
  51. friend class boost::iterator_core_access;
  52. void increment()
  53. {
  54. if( _skip_scanline == true )
  55. {
  56. _reader.skip( _buffer_start
  57. , _pos
  58. );
  59. }
  60. ++_pos;
  61. _skip_scanline = true;
  62. _read_scanline = true;
  63. }
  64. bool equal( const scanline_read_iterator& rhs ) const
  65. {
  66. return _pos == rhs._pos;
  67. }
  68. typename base_t::reference dereference() const
  69. {
  70. if( _read_scanline == true )
  71. {
  72. _reader.read( _buffer_start
  73. , _pos
  74. );
  75. }
  76. _skip_scanline = false;
  77. _read_scanline = false;
  78. return _buffer_start;
  79. }
  80. private:
  81. Reader& _reader;
  82. mutable int _pos;
  83. mutable bool _read_scanline;
  84. mutable bool _skip_scanline;
  85. using buffer_t = std::vector<byte_t>;
  86. using buffer_ptr_t = std::shared_ptr<buffer_t>;
  87. buffer_ptr_t _buffer;
  88. mutable byte_t* _buffer_start;
  89. };
  90. #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
  91. #pragma warning(pop)
  92. #endif
  93. } // namespace gil
  94. } // namespace boost
  95. #endif