scanline_read_iterator.hpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. //
  2. // Copyright 2007-2008 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_IO_SCANLINE_READ_ITERATOR_HPP
  9. #define BOOST_GIL_IO_SCANLINE_READ_ITERATOR_HPP
  10. #include <boost/gil/io/error.hpp>
  11. #include <boost/gil/io/typedefs.hpp>
  12. #include <boost/iterator/iterator_facade.hpp>
  13. #include <iterator>
  14. #include <memory>
  15. #include <vector>
  16. namespace boost { namespace gil {
  17. #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
  18. #pragma warning(push)
  19. #pragma warning(disable:4512) //assignment operator could not be generated
  20. #endif
  21. /// Input iterator to read images.
  22. template< typename Reader >
  23. class scanline_read_iterator : public boost::iterator_facade< scanline_read_iterator< Reader >
  24. , byte_t*
  25. , std::input_iterator_tag
  26. >
  27. {
  28. private:
  29. using base_t = boost::iterator_facade
  30. <
  31. scanline_read_iterator<Reader>,
  32. byte_t*,
  33. std::input_iterator_tag
  34. >;
  35. public:
  36. scanline_read_iterator( Reader& reader
  37. , int pos = 0
  38. )
  39. : _pos( pos )
  40. , _read_scanline( true )
  41. , _skip_scanline( true )
  42. , _reader( reader )
  43. {
  44. _buffer = std::make_shared< buffer_t >( buffer_t( _reader._scanline_length ));
  45. _buffer_start = &_buffer->front();
  46. }
  47. private:
  48. friend class boost::iterator_core_access;
  49. void increment()
  50. {
  51. if( _skip_scanline == true )
  52. {
  53. _reader.skip( _buffer_start
  54. , _pos
  55. );
  56. }
  57. ++_pos;
  58. _skip_scanline = true;
  59. _read_scanline = true;
  60. }
  61. bool equal( const scanline_read_iterator& rhs ) const
  62. {
  63. return _pos == rhs._pos;
  64. }
  65. typename base_t::reference dereference() const
  66. {
  67. if( _read_scanline == true )
  68. {
  69. _reader.read( _buffer_start
  70. , _pos
  71. );
  72. }
  73. _skip_scanline = false;
  74. _read_scanline = false;
  75. return _buffer_start;
  76. }
  77. private:
  78. Reader& _reader;
  79. mutable int _pos;
  80. mutable bool _read_scanline;
  81. mutable bool _skip_scanline;
  82. using buffer_t = std::vector<byte_t>;
  83. using buffer_ptr_t = std::shared_ptr<buffer_t>;
  84. buffer_ptr_t _buffer;
  85. mutable byte_t* _buffer_start;
  86. };
  87. #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
  88. #pragma warning(pop)
  89. #endif
  90. } // namespace gil
  91. } // namespace boost
  92. #endif