Chris@16
|
1 /*
|
Chris@16
|
2 Copyright 2005-2007 Adobe Systems Incorporated
|
Chris@16
|
3
|
Chris@16
|
4 Use, modification and distribution are subject to the Boost Software License,
|
Chris@16
|
5 Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
6 http://www.boost.org/LICENSE_1_0.txt).
|
Chris@16
|
7
|
Chris@16
|
8 See http://opensource.adobe.com/gil for most recent version including documentation.
|
Chris@16
|
9 */
|
Chris@16
|
10 /*************************************************************************************************/
|
Chris@16
|
11
|
Chris@16
|
12 #ifndef GIL_ITERATOR_FROM_2D_H
|
Chris@16
|
13 #define GIL_ITERATOR_FROM_2D_H
|
Chris@16
|
14
|
Chris@16
|
15 ////////////////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
16 /// \file
|
Chris@16
|
17 /// \brief pixel step iterator, pixel image iterator and pixel dereference iterator
|
Chris@16
|
18 /// \author Lubomir Bourdev and Hailin Jin \n
|
Chris@16
|
19 /// Adobe Systems Incorporated
|
Chris@16
|
20 /// \date 2005-2007 \n Last updated on September 18, 2007
|
Chris@16
|
21 ///
|
Chris@16
|
22 ////////////////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
23
|
Chris@16
|
24 #include <cassert>
|
Chris@16
|
25 #include <boost/iterator/iterator_facade.hpp>
|
Chris@16
|
26 #include "gil_concept.hpp"
|
Chris@16
|
27 #include "gil_config.hpp"
|
Chris@16
|
28 #include "pixel_iterator.hpp"
|
Chris@16
|
29 #include "locator.hpp"
|
Chris@16
|
30
|
Chris@16
|
31 namespace boost { namespace gil {
|
Chris@16
|
32
|
Chris@16
|
33 ////////////////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
34 ///
|
Chris@16
|
35 /// ITERATOR FROM 2D ADAPTOR
|
Chris@16
|
36 ///
|
Chris@16
|
37 ////////////////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
38
|
Chris@16
|
39
|
Chris@16
|
40 /// \defgroup PixelIteratorModelFromLocator iterator_from_2d
|
Chris@16
|
41 /// \ingroup PixelIteratorModel
|
Chris@16
|
42 /// \brief An iterator over two-dimensional locator. Useful for iterating over the pixels of an image view. Models PixelIteratorConcept, PixelBasedConcept, HasDynamicXStepTypeConcept
|
Chris@16
|
43
|
Chris@16
|
44
|
Chris@16
|
45 /// \ingroup PixelIteratorModelFromLocator PixelBasedModel
|
Chris@16
|
46 /// \brief Provides 1D random-access navigation to the pixels of the image. Models: PixelIteratorConcept, PixelBasedConcept, HasDynamicXStepTypeConcept
|
Chris@16
|
47 ///
|
Chris@16
|
48 /// Pixels are traversed from the top to the bottom row and from the left to the right
|
Chris@16
|
49 /// within each row
|
Chris@16
|
50
|
Chris@16
|
51 template <typename Loc2> // Models PixelLocatorConcept
|
Chris@16
|
52 class iterator_from_2d : public iterator_facade<iterator_from_2d<Loc2>,
|
Chris@16
|
53 typename Loc2::value_type,
|
Chris@16
|
54 std::random_access_iterator_tag,
|
Chris@16
|
55 typename Loc2::reference,
|
Chris@16
|
56 typename Loc2::coord_t> {
|
Chris@16
|
57 GIL_CLASS_REQUIRE(Loc2, boost::gil, PixelLocatorConcept)
|
Chris@16
|
58 public:
|
Chris@16
|
59 typedef iterator_facade<iterator_from_2d<Loc2>,
|
Chris@16
|
60 typename Loc2::value_type,
|
Chris@16
|
61 std::random_access_iterator_tag,
|
Chris@16
|
62 typename Loc2::reference,
|
Chris@16
|
63 typename Loc2::coord_t> parent_t;
|
Chris@16
|
64 typedef typename parent_t::reference reference;
|
Chris@16
|
65 typedef typename parent_t::difference_type difference_type;
|
Chris@16
|
66 typedef typename Loc2::x_iterator x_iterator;
|
Chris@16
|
67 typedef typename Loc2::point_t point_t;
|
Chris@16
|
68
|
Chris@16
|
69 std::ptrdiff_t width() const { return _width; } // number of pixels per image row
|
Chris@16
|
70 std::ptrdiff_t x_pos() const { return _coords.x; } // current x position
|
Chris@16
|
71 std::ptrdiff_t y_pos() const { return _coords.y; } // current y position
|
Chris@16
|
72
|
Chris@16
|
73 /// For some reason operator[] provided by iterator_adaptor returns a custom class that is convertible to reference
|
Chris@16
|
74 /// We require our own reference because it is registered in iterator_traits
|
Chris@16
|
75 reference operator[](difference_type d) const { return *(*this+d); }
|
Chris@16
|
76
|
Chris@16
|
77 bool is_1d_traversable() const { return _p.is_1d_traversable(width()); } // is there no gap at the end of each row?
|
Chris@16
|
78 x_iterator& x() { return _p.x(); }
|
Chris@16
|
79
|
Chris@16
|
80 iterator_from_2d(){}
|
Chris@16
|
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) {}
|
Chris@16
|
82 iterator_from_2d(const iterator_from_2d& pit) : _coords(pit._coords), _width(pit._width), _p(pit._p) {}
|
Chris@16
|
83 template <typename Loc> iterator_from_2d(const iterator_from_2d<Loc>& pit) : _coords(pit._coords), _width(pit._width), _p(pit._p) {}
|
Chris@16
|
84
|
Chris@16
|
85 private:
|
Chris@16
|
86 template <typename Loc> friend class iterator_from_2d;
|
Chris@16
|
87 friend class boost::iterator_core_access;
|
Chris@16
|
88 reference dereference() const { return *_p; }
|
Chris@16
|
89 void increment() {
|
Chris@16
|
90 ++_coords.x;
|
Chris@16
|
91 ++_p.x();
|
Chris@16
|
92 if (_coords.x>=_width) {
|
Chris@16
|
93 _coords.x=0;
|
Chris@16
|
94 ++_coords.y;
|
Chris@16
|
95 _p+=point_t(-_width,1);
|
Chris@16
|
96 }
|
Chris@16
|
97 }
|
Chris@16
|
98 void decrement() {
|
Chris@16
|
99 --_coords.x;
|
Chris@16
|
100 --_p.x();
|
Chris@16
|
101 if (_coords.x<0) {
|
Chris@16
|
102 _coords.x=_width-1;
|
Chris@16
|
103 --_coords.y;
|
Chris@16
|
104 _p+=point_t(_width,-1);
|
Chris@16
|
105 }
|
Chris@16
|
106 }
|
Chris@16
|
107
|
Chris@16
|
108 GIL_FORCEINLINE void advance(difference_type d) {
|
Chris@16
|
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.
|
Chris@16
|
110 point_t delta;
|
Chris@16
|
111 if (_coords.x+d>=0) { // not going back to a previous row?
|
Chris@16
|
112 delta.x=(_coords.x+(std::ptrdiff_t)d)%_width - _coords.x;
|
Chris@16
|
113 delta.y=(_coords.x+(std::ptrdiff_t)d)/_width;
|
Chris@16
|
114 } else {
|
Chris@16
|
115 delta.x=(_coords.x+(std::ptrdiff_t)d*(1-_width))%_width -_coords.x;
|
Chris@16
|
116 delta.y=-(_width-_coords.x-(std::ptrdiff_t)d-1)/_width;
|
Chris@16
|
117 }
|
Chris@16
|
118 _p+=delta;
|
Chris@16
|
119 _coords.x+=delta.x;
|
Chris@16
|
120 _coords.y+=delta.y;
|
Chris@16
|
121 }
|
Chris@16
|
122
|
Chris@16
|
123 difference_type distance_to(const iterator_from_2d& it) const {
|
Chris@16
|
124 if (_width==0) return 0;
|
Chris@16
|
125 return (it.y_pos()-_coords.y)*_width + (it.x_pos()-_coords.x);
|
Chris@16
|
126 }
|
Chris@16
|
127
|
Chris@16
|
128 bool equal(const iterator_from_2d& it) const {
|
Chris@16
|
129 assert(_width==it.width()); // they must belong to the same image
|
Chris@16
|
130 return _coords==it._coords && _p==it._p;
|
Chris@16
|
131 }
|
Chris@16
|
132
|
Chris@16
|
133 point2<std::ptrdiff_t> _coords;
|
Chris@16
|
134 std::ptrdiff_t _width;
|
Chris@16
|
135 Loc2 _p;
|
Chris@16
|
136 };
|
Chris@16
|
137
|
Chris@16
|
138 template <typename Loc> // Models PixelLocatorConcept
|
Chris@16
|
139 struct const_iterator_type<iterator_from_2d<Loc> > {
|
Chris@16
|
140 typedef iterator_from_2d<typename Loc::const_t> type;
|
Chris@16
|
141 };
|
Chris@16
|
142
|
Chris@16
|
143 template <typename Loc> // Models PixelLocatorConcept
|
Chris@16
|
144 struct iterator_is_mutable<iterator_from_2d<Loc> > : public iterator_is_mutable<typename Loc::x_iterator> {};
|
Chris@16
|
145
|
Chris@16
|
146
|
Chris@16
|
147 /////////////////////////////
|
Chris@16
|
148 // HasDynamicXStepTypeConcept
|
Chris@16
|
149 /////////////////////////////
|
Chris@16
|
150
|
Chris@16
|
151 template <typename Loc>
|
Chris@16
|
152 struct dynamic_x_step_type<iterator_from_2d<Loc> > {
|
Chris@16
|
153 typedef iterator_from_2d<typename dynamic_x_step_type<Loc>::type> type;
|
Chris@16
|
154 };
|
Chris@16
|
155
|
Chris@16
|
156
|
Chris@16
|
157 /////////////////////////////
|
Chris@16
|
158 // PixelBasedConcept
|
Chris@16
|
159 /////////////////////////////
|
Chris@16
|
160
|
Chris@16
|
161 template <typename Loc> // Models PixelLocatorConcept
|
Chris@16
|
162 struct color_space_type<iterator_from_2d<Loc> > : public color_space_type<Loc> {};
|
Chris@16
|
163
|
Chris@16
|
164 template <typename Loc> // Models PixelLocatorConcept
|
Chris@16
|
165 struct channel_mapping_type<iterator_from_2d<Loc> > : public channel_mapping_type<Loc> {};
|
Chris@16
|
166
|
Chris@16
|
167 template <typename Loc> // Models PixelLocatorConcept
|
Chris@16
|
168 struct is_planar<iterator_from_2d<Loc> > : public is_planar<Loc> {};
|
Chris@16
|
169
|
Chris@16
|
170 template <typename Loc> // Models PixelLocatorConcept
|
Chris@16
|
171 struct channel_type<iterator_from_2d<Loc> > : public channel_type<Loc> {};
|
Chris@16
|
172
|
Chris@16
|
173 } } // namespace boost::gil
|
Chris@16
|
174
|
Chris@16
|
175 #endif
|