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 11 #include <boost/gil/io/error.hpp> 12 #include <boost/gil/io/typedefs.hpp> 13 14 #include <boost/iterator/iterator_facade.hpp> 15 16 #include <iterator> 17 #include <memory> 18 #include <vector> 19 20 namespace boost { namespace gil { 21 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 27 /// Input iterator to read images. 28 template <typename Reader> 29 class scanline_read_iterator 30 : public boost::iterator_facade<scanline_read_iterator<Reader>, byte_t*, std::input_iterator_tag> 31 { 32 private: 33 using base_t = boost::iterator_facade 34 < 35 scanline_read_iterator<Reader>, 36 byte_t*, 37 std::input_iterator_tag 38 >; 39 public: scanline_read_iterator(Reader & reader,int pos=0)40 scanline_read_iterator(Reader& reader, int pos = 0) 41 : reader_(reader), pos_(pos) 42 { 43 buffer_ = std::make_shared<buffer_t>(buffer_t(reader_._scanline_length)); 44 buffer_start_ = &buffer_->front(); 45 } 46 47 private: 48 friend class boost::iterator_core_access; 49 increment()50 void increment() 51 { 52 if (skip_scanline_) 53 { 54 reader_.skip(buffer_start_, pos_); 55 } 56 57 ++pos_; 58 59 skip_scanline_ = true; 60 read_scanline_ = true; 61 } 62 equal(scanline_read_iterator const & rhs) const63 bool equal(scanline_read_iterator const& rhs) const 64 { 65 return pos_ == rhs.pos_; 66 } 67 dereference() const68 typename base_t::reference dereference() const 69 { 70 if (read_scanline_) 71 { 72 reader_.read(buffer_start_, pos_); 73 } 74 skip_scanline_ = false; 75 read_scanline_ = false; 76 77 return buffer_start_; 78 } 79 80 private: 81 Reader& reader_; 82 83 mutable int pos_ = 0; 84 mutable bool read_scanline_ = true; 85 mutable bool skip_scanline_ = true; 86 87 using buffer_t = std::vector<byte_t>; 88 using buffer_ptr_t = std::shared_ptr<buffer_t>; 89 buffer_ptr_t buffer_; 90 mutable byte_t* buffer_start_ = nullptr; 91 }; 92 93 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) 94 #pragma warning(pop) 95 #endif 96 97 } // namespace gil 98 } // namespace boost 99 100 #endif 101