Boost GIL


iterator_from_2d.hpp
1 //
2 // Copyright 2005-2007 Adobe Systems Incorporated
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_ITERATOR_FROM_2D_HPP
9 #define BOOST_GIL_ITERATOR_FROM_2D_HPP
10 
11 #include <boost/gil/concepts.hpp>
12 #include <boost/gil/locator.hpp>
13 #include <boost/gil/pixel_iterator.hpp>
14 #include <boost/gil/point.hpp>
15 
16 #include <boost/assert.hpp>
17 #include <boost/iterator/iterator_facade.hpp>
18 
19 namespace boost { namespace gil {
20 
22 
28 
29 
33 
34 
40 
41 template <typename Loc2> // Models PixelLocatorConcept
42 class iterator_from_2d : public iterator_facade<iterator_from_2d<Loc2>,
43  typename Loc2::value_type,
44  std::random_access_iterator_tag,
45  typename Loc2::reference,
46  typename Loc2::coord_t> {
47  GIL_CLASS_REQUIRE(Loc2, boost::gil, PixelLocatorConcept)
48 public:
49  using parent_t = iterator_facade<iterator_from_2d<Loc2>,
50  typename Loc2::value_type,
51  std::random_access_iterator_tag,
52  typename Loc2::reference,
53  typename Loc2::coord_t>;
54  using reference = typename parent_t::reference;
55  using difference_type = typename parent_t::difference_type;
56  using x_iterator = typename Loc2::x_iterator;
57  using point_t = typename Loc2::point_t;
58 
59  std::ptrdiff_t width() const { return _width; } // number of pixels per image row
60  std::ptrdiff_t x_pos() const { return _coords.x; } // current x position
61  std::ptrdiff_t y_pos() const { return _coords.y; } // current y position
62 
65  reference operator[](difference_type d) const { return *(*this+d); }
66 
67  bool is_1d_traversable() const { return _p.is_1d_traversable(width()); } // is there no gap at the end of each row?
68  x_iterator& x() { return _p.x(); }
69 
71  iterator_from_2d(const Loc2& p, std::ptrdiff_t width, std::ptrdiff_t x=0, std::ptrdiff_t y=0) : _coords(x,y), _width(width), _p(p) {}
72  iterator_from_2d(const iterator_from_2d& pit) : _coords(pit._coords), _width(pit._width), _p(pit._p) {}
73  template <typename Loc> iterator_from_2d(const iterator_from_2d<Loc>& pit) : _coords(pit._coords), _width(pit._width), _p(pit._p) {}
74 
75 private:
76  template <typename Loc> friend class iterator_from_2d;
77  friend class boost::iterator_core_access;
78  reference dereference() const { return *_p; }
79  void increment() {
80  ++_coords.x;
81  ++_p.x();
82  if (_coords.x>=_width) {
83  _coords.x=0;
84  ++_coords.y;
85  _p+=point_t(-_width,1);
86  }
87  }
88  void decrement() {
89  --_coords.x;
90  --_p.x();
91  if (_coords.x<0) {
92  _coords.x=_width-1;
93  --_coords.y;
94  _p+=point_t(_width,-1);
95  }
96  }
97 
98  BOOST_FORCEINLINE void advance(difference_type d) {
99  if (_width==0) return; // unfortunately we need to check for that. Default-constructed images have width of 0 and the code below will throw if executed.
100  point_t delta;
101  if (_coords.x+d>=0) { // not going back to a previous row?
102  delta.x=(_coords.x+(std::ptrdiff_t)d)%_width - _coords.x;
103  delta.y=(_coords.x+(std::ptrdiff_t)d)/_width;
104  } else {
105  delta.x=(_coords.x+(std::ptrdiff_t)d*(1-_width))%_width -_coords.x;
106  delta.y=-(_width-_coords.x-(std::ptrdiff_t)d-1)/_width;
107  }
108  _p+=delta;
109  _coords.x+=delta.x;
110  _coords.y+=delta.y;
111  }
112 
113  difference_type distance_to(const iterator_from_2d& it) const {
114  if (_width==0) return 0;
115  return (it.y_pos()-_coords.y)*_width + (it.x_pos()-_coords.x);
116  }
117 
118  bool equal(iterator_from_2d const& it) const
119  {
120  BOOST_ASSERT(_width == it.width()); // they must belong to the same image
121  return _coords == it._coords && _p == it._p;
122  }
123 
124  point_t _coords;
125  std::ptrdiff_t _width;
126  Loc2 _p;
127 };
128 
129 template <typename Loc> // Models PixelLocatorConcept
130 struct const_iterator_type<iterator_from_2d<Loc> > {
132 };
133 
134 template <typename Loc> // Models PixelLocatorConcept
135 struct iterator_is_mutable<iterator_from_2d<Loc> > : public iterator_is_mutable<typename Loc::x_iterator> {};
136 
137 
139 // HasDynamicXStepTypeConcept
141 
142 template <typename Loc>
143 struct dynamic_x_step_type<iterator_from_2d<Loc> > {
145 };
146 
147 
149 // PixelBasedConcept
151 
152 template <typename Loc> // Models PixelLocatorConcept
153 struct color_space_type<iterator_from_2d<Loc> > : public color_space_type<Loc> {};
154 
155 template <typename Loc> // Models PixelLocatorConcept
156 struct channel_mapping_type<iterator_from_2d<Loc> > : public channel_mapping_type<Loc> {};
157 
158 template <typename Loc> // Models PixelLocatorConcept
159 struct is_planar<iterator_from_2d<Loc> > : public is_planar<Loc> {};
160 
161 template <typename Loc> // Models PixelLocatorConcept
162 struct channel_type<iterator_from_2d<Loc> > : public channel_type<Loc> {};
163 
164 } } // namespace boost::gil
165 
166 #endif
Definition: algorithm.hpp:30
Definition: algorithm.hpp:30
Provides 1D random-access navigation to the pixels of the image. Models: PixelIteratorConcept, PixelBasedConcept, HasDynamicXStepTypeConcept.
Definition: iterator_from_2d.hpp:42
reference operator[](difference_type d) const
Definition: iterator_from_2d.hpp:65
GIL&#39;s 2-dimensional locator over immutable GIL pixels.
Definition: pixel_locator.hpp:288
BOOST_FORCEINLINE bool equal(boost::gil::iterator_from_2d< Loc1 > first, boost::gil::iterator_from_2d< Loc1 > last, boost::gil::iterator_from_2d< Loc2 > first2)
std::equal(I1,I1,I2) with I1 and I2 being a iterator_from_2d
Definition: algorithm.hpp:929
Definition: color_convert.hpp:30
Metafunction predicate returning whether the given iterator allows for changing its values...
Definition: pixel_iterator.hpp:48
Returns the type of an iterator just like the input iterator, except operating over immutable values...
Definition: pixel_iterator.hpp:39
Base template for types that model HasDynamicXStepTypeConcept.
Definition: dynamic_step.hpp:17