scanline_read_iterator.hpp 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  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
  24. : public boost::iterator_facade<scanline_read_iterator<Reader>, byte_t*, std::input_iterator_tag>
  25. {
  26. private:
  27. using base_t = boost::iterator_facade
  28. <
  29. scanline_read_iterator<Reader>,
  30. byte_t*,
  31. std::input_iterator_tag
  32. >;
  33. public:
  34. scanline_read_iterator(Reader& reader, int pos = 0)
  35. : reader_(reader), pos_(pos)
  36. {
  37. buffer_ = std::make_shared<buffer_t>(buffer_t(reader_._scanline_length));
  38. buffer_start_ = &buffer_->front();
  39. }
  40. private:
  41. friend class boost::iterator_core_access;
  42. void increment()
  43. {
  44. if (skip_scanline_)
  45. {
  46. reader_.skip(buffer_start_, pos_);
  47. }
  48. ++pos_;
  49. skip_scanline_ = true;
  50. read_scanline_ = true;
  51. }
  52. bool equal(scanline_read_iterator const& rhs) const
  53. {
  54. return pos_ == rhs.pos_;
  55. }
  56. typename base_t::reference dereference() const
  57. {
  58. if (read_scanline_)
  59. {
  60. reader_.read(buffer_start_, pos_);
  61. }
  62. skip_scanline_ = false;
  63. read_scanline_ = false;
  64. return buffer_start_;
  65. }
  66. private:
  67. Reader& reader_;
  68. mutable int pos_ = 0;
  69. mutable bool read_scanline_ = true;
  70. mutable bool skip_scanline_ = true;
  71. using buffer_t = std::vector<byte_t>;
  72. using buffer_ptr_t = std::shared_ptr<buffer_t>;
  73. buffer_ptr_t buffer_;
  74. mutable byte_t* buffer_start_ = nullptr;
  75. };
  76. #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
  77. #pragma warning(pop)
  78. #endif
  79. } // namespace gil
  80. } // namespace boost
  81. #endif