Boost GIL


iterator_from_2d.hpp
Go to the documentation of this file.
1 /*
2  Copyright 2005-2007 Adobe Systems Incorporated
3 
4  Use, modification and distribution are subject to the Boost Software License,
5  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
6  http://www.boost.org/LICENSE_1_0.txt).
7 
8  See http://opensource.adobe.com/gil for most recent version including documentation.
9 */
10 /*************************************************************************************************/
11 
12 #ifndef GIL_ITERATOR_FROM_2D_H
13 #define GIL_ITERATOR_FROM_2D_H
14 
23 
24 #include <cassert>
25 #include <boost/iterator/iterator_facade.hpp>
26 #include "gil_concept.hpp"
27 #include "gil_config.hpp"
28 #include "pixel_iterator.hpp"
29 #include "locator.hpp"
30 
31 namespace boost { namespace gil {
32 
38 
39 
43 
44 
50 
51 template <typename Loc2> // Models PixelLocatorConcept
52 class iterator_from_2d : public iterator_facade<iterator_from_2d<Loc2>,
53  typename Loc2::value_type,
54  std::random_access_iterator_tag,
55  typename Loc2::reference,
56  typename Loc2::coord_t> {
57  GIL_CLASS_REQUIRE(Loc2, boost::gil, PixelLocatorConcept)
58 public:
59  typedef iterator_facade<iterator_from_2d<Loc2>,
60  typename Loc2::value_type,
61  std::random_access_iterator_tag,
62  typename Loc2::reference,
63  typename Loc2::coord_t> parent_t;
64  typedef typename parent_t::reference reference;
65  typedef typename parent_t::difference_type difference_type;
66  typedef typename Loc2::x_iterator x_iterator;
67  typedef typename Loc2::point_t point_t;
68 
69  std::ptrdiff_t width() const { return _width; } // number of pixels per image row
70  std::ptrdiff_t x_pos() const { return _coords.x; } // current x position
71  std::ptrdiff_t y_pos() const { return _coords.y; } // current y position
72 
75  reference operator[](difference_type d) const { return *(*this+d); }
76 
77  bool is_1d_traversable() const { return _p.is_1d_traversable(width()); } // is there no gap at the end of each row?
78  x_iterator& x() { return _p.x(); }
79 
80  iterator_from_2d(){}
81  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) {}
82  iterator_from_2d(const iterator_from_2d& pit) : _coords(pit._coords), _width(pit._width), _p(pit._p) {}
83  template <typename Loc> iterator_from_2d(const iterator_from_2d<Loc>& pit) : _coords(pit._coords), _width(pit._width), _p(pit._p) {}
84 
85 private:
86  template <typename Loc> friend class iterator_from_2d;
87  friend class boost::iterator_core_access;
88  reference dereference() const { return *_p; }
89  void increment() {
90  ++_coords.x;
91  ++_p.x();
92  if (_coords.x>=_width) {
93  _coords.x=0;
94  ++_coords.y;
95  _p+=point_t(-_width,1);
96  }
97  }
98  void decrement() {
99  --_coords.x;
100  --_p.x();
101  if (_coords.x<0) {
102  _coords.x=_width-1;
103  --_coords.y;
104  _p+=point_t(_width,-1);
105  }
106  }
107 
108  BOOST_FORCEINLINE void advance(difference_type d) {
109  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.
110  point_t delta;
111  if (_coords.x+d>=0) { // not going back to a previous row?
112  delta.x=(_coords.x+(std::ptrdiff_t)d)%_width - _coords.x;
113  delta.y=(_coords.x+(std::ptrdiff_t)d)/_width;
114  } else {
115  delta.x=(_coords.x+(std::ptrdiff_t)d*(1-_width))%_width -_coords.x;
116  delta.y=-(_width-_coords.x-(std::ptrdiff_t)d-1)/_width;
117  }
118  _p+=delta;
119  _coords.x+=delta.x;
120  _coords.y+=delta.y;
121  }
122 
123  difference_type distance_to(const iterator_from_2d& it) const {
124  if (_width==0) return 0;
125  return (it.y_pos()-_coords.y)*_width + (it.x_pos()-_coords.x);
126  }
127 
128  bool equal(const iterator_from_2d& it) const {
129  assert(_width==it.width()); // they must belong to the same image
130  return _coords==it._coords && _p==it._p;
131  }
132 
133  point2<std::ptrdiff_t> _coords;
134  std::ptrdiff_t _width;
135  Loc2 _p;
136 };
137 
138 template <typename Loc> // Models PixelLocatorConcept
139 struct const_iterator_type<iterator_from_2d<Loc> > {
140  typedef iterator_from_2d<typename Loc::const_t> type;
141 };
142 
143 template <typename Loc> // Models PixelLocatorConcept
144 struct iterator_is_mutable<iterator_from_2d<Loc> > : public iterator_is_mutable<typename Loc::x_iterator> {};
145 
146 
148 // HasDynamicXStepTypeConcept
150 
151 template <typename Loc>
152 struct dynamic_x_step_type<iterator_from_2d<Loc> > {
153  typedef iterator_from_2d<typename dynamic_x_step_type<Loc>::type> type;
154 };
155 
156 
158 // PixelBasedConcept
160 
161 template <typename Loc> // Models PixelLocatorConcept
162 struct color_space_type<iterator_from_2d<Loc> > : public color_space_type<Loc> {};
163 
164 template <typename Loc> // Models PixelLocatorConcept
165 struct channel_mapping_type<iterator_from_2d<Loc> > : public channel_mapping_type<Loc> {};
166 
167 template <typename Loc> // Models PixelLocatorConcept
168 struct is_planar<iterator_from_2d<Loc> > : public is_planar<Loc> {};
169 
170 template <typename Loc> // Models PixelLocatorConcept
171 struct channel_type<iterator_from_2d<Loc> > : public channel_type<Loc> {};
172 
173 } } // namespace boost::gil
174 
175 #endif
pixel 2D locator
Concept check classes for GIL concepts.
Provides 1D random-access navigation to the pixels of the image. Models: PixelIteratorConcept, PixelBasedConcept, HasDynamicXStepTypeConcept.
Definition: iterator_from_2d.hpp:52
GIL's 2-dimensional locator over immutable GIL pixels.
Definition: gil_concept.hpp:1616
pixel iterator support
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:934
reference operator[](difference_type d) const
Definition: iterator_from_2d.hpp:75
GIL configuration file.