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
|
Chris@16
|
13 #ifndef GIL_LOCATOR_H
|
Chris@16
|
14 #define GIL_LOCATOR_H
|
Chris@16
|
15
|
Chris@16
|
16
|
Chris@16
|
17 ////////////////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
18 /// \file
|
Chris@16
|
19 /// \brief pixel 2D locator
|
Chris@16
|
20 /// \author Lubomir Bourdev and Hailin Jin \n
|
Chris@16
|
21 /// Adobe Systems Incorporated
|
Chris@16
|
22 /// \date 2005-2007 \n September 20, 2006
|
Chris@16
|
23 ///
|
Chris@16
|
24 ////////////////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
25
|
Chris@16
|
26 #include <cstddef>
|
Chris@16
|
27 #include <cassert>
|
Chris@16
|
28 #include "pixel_iterator.hpp"
|
Chris@16
|
29
|
Chris@16
|
30 ////////////////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
31 /// Pixel 2D LOCATOR
|
Chris@16
|
32 ////////////////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
33
|
Chris@16
|
34
|
Chris@16
|
35 namespace boost { namespace gil {
|
Chris@16
|
36
|
Chris@16
|
37 //forward declarations
|
Chris@16
|
38 template <typename P> ptrdiff_t memunit_step(const P*);
|
Chris@16
|
39 template <typename P> P* memunit_advanced(const P* p, ptrdiff_t diff);
|
Chris@16
|
40 template <typename P> P& memunit_advanced_ref(P* p, ptrdiff_t diff);
|
Chris@16
|
41 template <typename Iterator, typename D> struct iterator_add_deref;
|
Chris@16
|
42 template <typename T> class point2;
|
Chris@16
|
43 namespace detail {
|
Chris@16
|
44 // helper class specialized for each axis of pixel_2d_locator
|
Chris@16
|
45 template <std::size_t D, typename Loc> class locator_axis;
|
Chris@16
|
46 }
|
Chris@16
|
47 template <typename T> struct dynamic_x_step_type;
|
Chris@16
|
48 template <typename T> struct dynamic_y_step_type;
|
Chris@16
|
49
|
Chris@16
|
50 template <typename T> struct channel_type;
|
Chris@16
|
51 template <typename T> struct color_space_type;
|
Chris@16
|
52 template <typename T> struct channel_mapping_type;
|
Chris@16
|
53 template <typename T> struct is_planar;
|
Chris@16
|
54 template <typename T> struct num_channels;
|
Chris@16
|
55
|
Chris@16
|
56 // The type of a locator or a view that has X and Y swapped. By default it is the same
|
Chris@16
|
57 template <typename T> struct transposed_type {
|
Chris@16
|
58 typedef T type;
|
Chris@16
|
59 };
|
Chris@16
|
60
|
Chris@16
|
61 /// \class pixel_2d_locator_base
|
Chris@16
|
62 /// \brief base class for models of PixelLocatorConcept
|
Chris@16
|
63 /// \ingroup PixelLocatorModel PixelBasedModel
|
Chris@16
|
64 ///
|
Chris@16
|
65 /// Pixel locator is similar to a pixel iterator, but allows for 2D navigation of pixels within an image view.
|
Chris@16
|
66 /// It has a 2D difference_type and supports random access operations like:
|
Chris@16
|
67 /// \code
|
Chris@16
|
68 /// difference_type offset2(2,3);
|
Chris@16
|
69 /// locator+=offset2;
|
Chris@16
|
70 /// locator[offset2]=my_pixel;
|
Chris@16
|
71 /// \endcode
|
Chris@16
|
72 ///
|
Chris@16
|
73 /// In addition, each coordinate acts as a random-access iterator that can be modified separately:
|
Chris@16
|
74 /// "++locator.x()" or "locator.y()+=10" thereby moving the locator horizontally or vertically.
|
Chris@16
|
75 ///
|
Chris@16
|
76 /// It is called a locator because it doesn't implement the complete interface of a random access iterator.
|
Chris@16
|
77 /// For example, increment and decrement operations don't make sense (no way to specify dimension).
|
Chris@16
|
78 /// Also 2D difference between two locators cannot be computed without knowledge of the X position within the image.
|
Chris@16
|
79 ///
|
Chris@16
|
80 /// This base class provides most of the methods and typedefs needed to create a model of a locator. GIL provides two
|
Chris@16
|
81 /// locator models as subclasses of \p pixel_2d_locator_base. A memory-based locator, \p memory_based_2d_locator and a virtual
|
Chris@16
|
82 /// locator, \p virtual_2d_locator.
|
Chris@16
|
83 /// The minimum functionality a subclass must provide is this:
|
Chris@16
|
84 /// \code
|
Chris@16
|
85 /// class my_locator : public pixel_2d_locator_base<my_locator, ..., ...> { // supply the types for x-iterator and y-iterator
|
Chris@16
|
86 /// typedef ... const_t; // read-only locator
|
Chris@16
|
87 ///
|
Chris@16
|
88 /// template <typename Deref> struct add_deref {
|
Chris@16
|
89 /// typedef ... type; // locator that invokes the Deref dereference object upon pixel access
|
Chris@16
|
90 /// static type make(const my_locator& loc, const Deref& d);
|
Chris@16
|
91 /// };
|
Chris@16
|
92 ///
|
Chris@16
|
93 /// my_locator();
|
Chris@16
|
94 /// my_locator(const my_locator& pl);
|
Chris@16
|
95 ///
|
Chris@16
|
96 /// // constructors with dynamic step in y (and x). Only valid for locators with dynamic steps
|
Chris@16
|
97 /// my_locator(const my_locator& loc, coord_t y_step);
|
Chris@16
|
98 /// my_locator(const my_locator& loc, coord_t x_step, coord_t y_step, bool transpose);
|
Chris@16
|
99 ///
|
Chris@16
|
100 /// bool operator==(const my_locator& p) const;
|
Chris@16
|
101 ///
|
Chris@16
|
102 /// // return _references_ to horizontal/vertical iterators. Advancing them moves this locator
|
Chris@16
|
103 /// x_iterator& x();
|
Chris@16
|
104 /// y_iterator& y();
|
Chris@16
|
105 /// x_iterator const& x() const;
|
Chris@16
|
106 /// y_iterator const& y() const;
|
Chris@16
|
107 ///
|
Chris@16
|
108 /// // return the vertical distance to another locator. Some models need the horizontal distance to compute it
|
Chris@16
|
109 /// y_coord_t y_distance_to(const my_locator& loc2, x_coord_t xDiff) const;
|
Chris@16
|
110 ///
|
Chris@16
|
111 /// // return true iff incrementing an x-iterator located at the last column will position it at the first
|
Chris@16
|
112 /// // column of the next row. Some models need the image width to determine that.
|
Chris@16
|
113 /// bool is_1d_traversable(x_coord_t width) const;
|
Chris@16
|
114 /// };
|
Chris@16
|
115 /// \endcode
|
Chris@16
|
116 ///
|
Chris@16
|
117 /// Models may choose to override some of the functions in the base class with more efficient versions.
|
Chris@16
|
118 ///
|
Chris@16
|
119
|
Chris@16
|
120 template <typename Loc, typename XIterator, typename YIterator> // The concrete subclass, the X-iterator and the Y-iterator
|
Chris@16
|
121 class pixel_2d_locator_base {
|
Chris@16
|
122 public:
|
Chris@16
|
123 typedef XIterator x_iterator;
|
Chris@16
|
124 typedef YIterator y_iterator;
|
Chris@16
|
125
|
Chris@16
|
126 // typedefs required by ConstRandomAccessNDLocatorConcept
|
Chris@16
|
127 static const std::size_t num_dimensions=2;
|
Chris@16
|
128 typedef typename std::iterator_traits<x_iterator>::value_type value_type;
|
Chris@16
|
129 typedef typename std::iterator_traits<x_iterator>::reference reference; // result of dereferencing
|
Chris@16
|
130 typedef typename std::iterator_traits<x_iterator>::difference_type coord_t; // 1D difference type (same for all dimensions)
|
Chris@16
|
131 typedef point2<coord_t> difference_type; // result of operator-(locator,locator)
|
Chris@16
|
132 typedef difference_type point_t;
|
Chris@16
|
133 template <std::size_t D> struct axis {
|
Chris@16
|
134 typedef typename detail::locator_axis<D,Loc>::coord_t coord_t;
|
Chris@16
|
135 typedef typename detail::locator_axis<D,Loc>::iterator iterator;
|
Chris@16
|
136 };
|
Chris@16
|
137
|
Chris@16
|
138 // typedefs required by ConstRandomAccess2DLocatorConcept
|
Chris@16
|
139 typedef typename point_t::template axis<0>::coord_t x_coord_t;
|
Chris@16
|
140 typedef typename point_t::template axis<1>::coord_t y_coord_t;
|
Chris@16
|
141
|
Chris@16
|
142 bool operator!=(const Loc& p) const { return !(concrete()==p); }
|
Chris@16
|
143
|
Chris@16
|
144 x_iterator x_at(x_coord_t dx, y_coord_t dy) const { Loc tmp=concrete(); tmp+=point_t(dx,dy); return tmp.x(); }
|
Chris@16
|
145 x_iterator x_at(const difference_type& d) const { Loc tmp=concrete(); tmp+=d; return tmp.x(); }
|
Chris@16
|
146 y_iterator y_at(x_coord_t dx, y_coord_t dy) const { Loc tmp=concrete(); tmp+=point_t(dx,dy); return tmp.y(); }
|
Chris@16
|
147 y_iterator y_at(const difference_type& d) const { Loc tmp=concrete(); tmp+=d; return tmp.y(); }
|
Chris@16
|
148 Loc xy_at(x_coord_t dx, y_coord_t dy) const { Loc tmp=concrete(); tmp+=point_t(dx,dy); return tmp; }
|
Chris@16
|
149 Loc xy_at(const difference_type& d) const { Loc tmp=concrete(); tmp+=d; return tmp; }
|
Chris@16
|
150
|
Chris@16
|
151 template <std::size_t D> typename axis<D>::iterator& axis_iterator() { return detail::locator_axis<D,Loc>()(concrete()); }
|
Chris@16
|
152 template <std::size_t D> typename axis<D>::iterator const& axis_iterator() const { return detail::locator_axis<D,Loc>()(concrete()); }
|
Chris@16
|
153 template <std::size_t D> typename axis<D>::iterator axis_iterator(const point_t& p) const { return detail::locator_axis<D,Loc>()(concrete(),p); }
|
Chris@16
|
154
|
Chris@16
|
155 reference operator()(x_coord_t dx, y_coord_t dy) const { return *x_at(dx,dy); }
|
Chris@16
|
156 reference operator[](const difference_type& d) const { return *x_at(d.x,d.y); }
|
Chris@16
|
157
|
Chris@16
|
158 reference operator*() const { return *concrete().x(); }
|
Chris@16
|
159
|
Chris@16
|
160 Loc& operator+=(const difference_type& d) { concrete().x()+=d.x; concrete().y()+=d.y; return concrete(); }
|
Chris@16
|
161 Loc& operator-=(const difference_type& d) { concrete().x()-=d.x; concrete().y()-=d.y; return concrete(); }
|
Chris@16
|
162
|
Chris@16
|
163 Loc operator+(const difference_type& d) const { return xy_at(d); }
|
Chris@16
|
164 Loc operator-(const difference_type& d) const { return xy_at(-d); }
|
Chris@16
|
165
|
Chris@16
|
166 // Some locators can cache 2D coordinates for faster subsequent access. By default there is no caching
|
Chris@16
|
167 typedef difference_type cached_location_t;
|
Chris@16
|
168 cached_location_t cache_location(const difference_type& d) const { return d; }
|
Chris@16
|
169 cached_location_t cache_location(x_coord_t dx, y_coord_t dy)const { return difference_type(dx,dy); }
|
Chris@16
|
170
|
Chris@16
|
171 private:
|
Chris@16
|
172 Loc& concrete() { return (Loc&)*this; }
|
Chris@16
|
173 const Loc& concrete() const { return (const Loc&)*this; }
|
Chris@16
|
174
|
Chris@16
|
175 template <typename X> friend class pixel_2d_locator;
|
Chris@16
|
176 };
|
Chris@16
|
177
|
Chris@16
|
178 // helper classes for each axis of pixel_2d_locator_base
|
Chris@16
|
179 namespace detail {
|
Chris@16
|
180 template <typename Loc>
|
Chris@16
|
181 class locator_axis<0,Loc> {
|
Chris@16
|
182 typedef typename Loc::point_t point_t;
|
Chris@16
|
183 public:
|
Chris@16
|
184 typedef typename point_t::template axis<0>::coord_t coord_t;
|
Chris@16
|
185 typedef typename Loc::x_iterator iterator;
|
Chris@16
|
186
|
Chris@16
|
187 inline iterator& operator()( Loc& loc) const { return loc.x(); }
|
Chris@16
|
188 inline iterator const& operator()(const Loc& loc) const { return loc.x(); }
|
Chris@16
|
189 inline iterator operator()( Loc& loc, const point_t& d) const { return loc.x_at(d); }
|
Chris@16
|
190 inline iterator operator()(const Loc& loc, const point_t& d) const { return loc.x_at(d); }
|
Chris@16
|
191 };
|
Chris@16
|
192
|
Chris@16
|
193 template <typename Loc>
|
Chris@16
|
194 class locator_axis<1,Loc> {
|
Chris@16
|
195 typedef typename Loc::point_t point_t;
|
Chris@16
|
196 public:
|
Chris@16
|
197 typedef typename point_t::template axis<1>::coord_t coord_t;
|
Chris@16
|
198 typedef typename Loc::y_iterator iterator;
|
Chris@16
|
199
|
Chris@16
|
200 inline iterator& operator()( Loc& loc) const { return loc.y(); }
|
Chris@16
|
201 inline iterator const& operator()(const Loc& loc) const { return loc.y(); }
|
Chris@16
|
202 inline iterator operator()( Loc& loc, const point_t& d) const { return loc.y_at(d); }
|
Chris@16
|
203 inline iterator operator()(const Loc& loc, const point_t& d) const { return loc.y_at(d); }
|
Chris@16
|
204 };
|
Chris@16
|
205 }
|
Chris@16
|
206
|
Chris@16
|
207 template <typename Loc, typename XIt, typename YIt>
|
Chris@16
|
208 struct channel_type<pixel_2d_locator_base<Loc,XIt,YIt> > : public channel_type<XIt> {};
|
Chris@16
|
209
|
Chris@16
|
210 template <typename Loc, typename XIt, typename YIt>
|
Chris@16
|
211 struct color_space_type<pixel_2d_locator_base<Loc,XIt,YIt> > : public color_space_type<XIt> {};
|
Chris@16
|
212
|
Chris@16
|
213 template <typename Loc, typename XIt, typename YIt>
|
Chris@16
|
214 struct channel_mapping_type<pixel_2d_locator_base<Loc,XIt,YIt> > : public channel_mapping_type<XIt> {};
|
Chris@16
|
215
|
Chris@16
|
216 template <typename Loc, typename XIt, typename YIt>
|
Chris@16
|
217 struct is_planar<pixel_2d_locator_base<Loc,XIt,YIt> > : public is_planar<XIt> {};
|
Chris@16
|
218
|
Chris@16
|
219 /// \class memory_based_2d_locator
|
Chris@16
|
220 /// \brief Memory-based pixel locator. Models: PixelLocatorConcept,HasDynamicXStepTypeConcept,HasDynamicYStepTypeConcept,HasTransposedTypeConcept
|
Chris@16
|
221 /// \ingroup PixelLocatorModel PixelBasedModel
|
Chris@16
|
222 ///
|
Chris@16
|
223 /// The class takes a step iterator as a parameter. The step iterator provides navigation along the vertical axis
|
Chris@16
|
224 /// while its base iterator provides horizontal navigation.
|
Chris@16
|
225 ///
|
Chris@16
|
226 /// Each instantiation is optimal in terms of size and efficiency.
|
Chris@16
|
227 /// For example, xy locator over interleaved rgb image results in a step iterator consisting of
|
Chris@16
|
228 /// one std::ptrdiff_t for the row size and one native pointer (8 bytes total). ++locator.x() resolves to pointer
|
Chris@16
|
229 /// increment. At the other extreme, a 2D navigation of the even pixels of a planar CMYK image results in a step
|
Chris@16
|
230 /// iterator consisting of one std::ptrdiff_t for the doubled row size, and one step iterator consisting of
|
Chris@16
|
231 /// one std::ptrdiff_t for the horizontal step of two and a CMYK planar_pixel_iterator consisting of 4 pointers (24 bytes).
|
Chris@16
|
232 /// In this case ++locator.x() results in four native pointer additions.
|
Chris@16
|
233 ///
|
Chris@16
|
234 /// Note also that \p memory_based_2d_locator does not require that its element type be a pixel. It could be
|
Chris@16
|
235 /// instantiated with an iterator whose \p value_type models only \p Regular. In this case the locator
|
Chris@16
|
236 /// models the weaker RandomAccess2DLocatorConcept, and does not model PixelBasedConcept.
|
Chris@16
|
237 /// Many generic algorithms don't require the elements to be pixels.
|
Chris@16
|
238 ////////////////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
239
|
Chris@16
|
240 template <typename StepIterator>
|
Chris@16
|
241 class memory_based_2d_locator : public pixel_2d_locator_base<memory_based_2d_locator<StepIterator>, typename iterator_adaptor_get_base<StepIterator>::type, StepIterator> {
|
Chris@16
|
242 typedef memory_based_2d_locator<StepIterator> this_t;
|
Chris@16
|
243 GIL_CLASS_REQUIRE(StepIterator, boost::gil, StepIteratorConcept)
|
Chris@16
|
244 public:
|
Chris@16
|
245 typedef pixel_2d_locator_base<memory_based_2d_locator<StepIterator>, typename iterator_adaptor_get_base<StepIterator>::type, StepIterator> parent_t;
|
Chris@16
|
246 typedef memory_based_2d_locator<typename const_iterator_type<StepIterator>::type> const_t; // same as this type, but over const values
|
Chris@16
|
247
|
Chris@16
|
248 typedef typename parent_t::coord_t coord_t;
|
Chris@16
|
249 typedef typename parent_t::x_coord_t x_coord_t;
|
Chris@16
|
250 typedef typename parent_t::y_coord_t y_coord_t;
|
Chris@16
|
251 typedef typename parent_t::x_iterator x_iterator;
|
Chris@16
|
252 typedef typename parent_t::y_iterator y_iterator;
|
Chris@16
|
253 typedef typename parent_t::difference_type difference_type;
|
Chris@16
|
254 typedef typename parent_t::reference reference;
|
Chris@16
|
255
|
Chris@16
|
256 template <typename Deref> struct add_deref {
|
Chris@16
|
257 typedef memory_based_2d_locator<typename iterator_add_deref<StepIterator,Deref>::type> type;
|
Chris@16
|
258 static type make(const memory_based_2d_locator<StepIterator>& loc, const Deref& nderef) {
|
Chris@16
|
259 return type(iterator_add_deref<StepIterator,Deref>::make(loc.y(),nderef));
|
Chris@16
|
260 }
|
Chris@16
|
261 };
|
Chris@16
|
262
|
Chris@16
|
263 memory_based_2d_locator() {}
|
Chris@16
|
264 memory_based_2d_locator(const StepIterator& yit) : _p(yit) {}
|
Chris@16
|
265 template <typename SI> memory_based_2d_locator(const memory_based_2d_locator<SI>& loc, coord_t y_step) : _p(loc.x(), loc.row_size()*y_step) {}
|
Chris@16
|
266 template <typename SI> memory_based_2d_locator(const memory_based_2d_locator<SI>& loc, coord_t x_step, coord_t y_step, bool transpose=false)
|
Chris@16
|
267 : _p(make_step_iterator(loc.x(),(transpose ? loc.row_size() : loc.pixel_size())*x_step),
|
Chris@16
|
268 (transpose ? loc.pixel_size() : loc.row_size())*y_step ) {}
|
Chris@16
|
269
|
Chris@16
|
270 memory_based_2d_locator(x_iterator xit, std::ptrdiff_t row_bytes) : _p(xit,row_bytes) {}
|
Chris@16
|
271 template <typename X> memory_based_2d_locator(const memory_based_2d_locator<X>& pl) : _p(pl._p) {}
|
Chris@16
|
272 memory_based_2d_locator(const memory_based_2d_locator& pl) : _p(pl._p) {}
|
Chris@16
|
273
|
Chris@16
|
274 bool operator==(const this_t& p) const { return _p==p._p; }
|
Chris@16
|
275
|
Chris@16
|
276 x_iterator const& x() const { return _p.base(); }
|
Chris@16
|
277 y_iterator const& y() const { return _p; }
|
Chris@16
|
278 x_iterator& x() { return _p.base(); }
|
Chris@16
|
279 y_iterator& y() { return _p; }
|
Chris@16
|
280
|
Chris@16
|
281 // These are faster versions of functions already provided in the superclass
|
Chris@16
|
282 x_iterator x_at (x_coord_t dx, y_coord_t dy) const { return memunit_advanced(x(), offset(dx,dy)); }
|
Chris@16
|
283 x_iterator x_at (const difference_type& d) const { return memunit_advanced(x(), offset(d.x,d.y)); }
|
Chris@16
|
284 this_t xy_at (x_coord_t dx, y_coord_t dy) const { return this_t(x_at( dx , dy ), row_size()); }
|
Chris@16
|
285 this_t xy_at (const difference_type& d) const { return this_t(x_at( d.x, d.y), row_size()); }
|
Chris@16
|
286 reference operator()(x_coord_t dx, y_coord_t dy) const { return memunit_advanced_ref(x(),offset(dx,dy)); }
|
Chris@16
|
287 reference operator[](const difference_type& d) const { return memunit_advanced_ref(x(),offset(d.x,d.y)); }
|
Chris@16
|
288 this_t& operator+=(const difference_type& d) { memunit_advance(x(),offset(d.x,d.y)); return *this; }
|
Chris@16
|
289 this_t& operator-=(const difference_type& d) { memunit_advance(x(),offset(-d.x,-d.y)); return *this; }
|
Chris@16
|
290
|
Chris@16
|
291 // Memory-based locators can have 1D caching of 2D relative coordinates
|
Chris@16
|
292 typedef std::ptrdiff_t cached_location_t; // type used to store relative location (to allow for more efficient repeated access)
|
Chris@16
|
293 cached_location_t cache_location(const difference_type& d) const { return offset(d.x,d.y); }
|
Chris@16
|
294 cached_location_t cache_location(x_coord_t dx, y_coord_t dy)const { return offset(dx,dy); }
|
Chris@16
|
295 reference operator[](const cached_location_t& loc) const { return memunit_advanced_ref(x(),loc); }
|
Chris@16
|
296
|
Chris@16
|
297 // Only make sense for memory-based locators
|
Chris@16
|
298 std::ptrdiff_t row_size() const { return memunit_step(y()); } // distance in mem units (bytes or bits) between adjacent rows
|
Chris@16
|
299 std::ptrdiff_t pixel_size() const { return memunit_step(x()); } // distance in mem units (bytes or bits) between adjacent pixels on the same row
|
Chris@16
|
300
|
Chris@16
|
301 bool is_1d_traversable(x_coord_t width) const { return row_size()-pixel_size()*width==0; } // is there no gap at the end of each row?
|
Chris@16
|
302
|
Chris@16
|
303 // Returns the vertical distance (it2.y-it1.y) between two x_iterators given the difference of their x positions
|
Chris@16
|
304 std::ptrdiff_t y_distance_to(const this_t& p2, x_coord_t xDiff) const {
|
Chris@16
|
305 std::ptrdiff_t rowDiff=memunit_distance(x(),p2.x())-pixel_size()*xDiff;
|
Chris@16
|
306 assert(( rowDiff % row_size())==0);
|
Chris@16
|
307 return rowDiff / row_size();
|
Chris@16
|
308 }
|
Chris@16
|
309
|
Chris@16
|
310 private:
|
Chris@16
|
311 template <typename X> friend class memory_based_2d_locator;
|
Chris@16
|
312 std::ptrdiff_t offset(x_coord_t x, y_coord_t y) const { return y*row_size() + x*pixel_size(); }
|
Chris@16
|
313 StepIterator _p;
|
Chris@16
|
314 };
|
Chris@16
|
315
|
Chris@16
|
316 /////////////////////////////
|
Chris@16
|
317 // PixelBasedConcept
|
Chris@16
|
318 /////////////////////////////
|
Chris@16
|
319
|
Chris@16
|
320 template <typename SI>
|
Chris@16
|
321 struct color_space_type<memory_based_2d_locator<SI> > : public color_space_type<typename memory_based_2d_locator<SI>::parent_t> {
|
Chris@16
|
322 };
|
Chris@16
|
323
|
Chris@16
|
324 template <typename SI>
|
Chris@16
|
325 struct channel_mapping_type<memory_based_2d_locator<SI> > : public channel_mapping_type<typename memory_based_2d_locator<SI>::parent_t> {
|
Chris@16
|
326 };
|
Chris@16
|
327
|
Chris@16
|
328 template <typename SI>
|
Chris@16
|
329 struct is_planar<memory_based_2d_locator<SI> > : public is_planar<typename memory_based_2d_locator<SI>::parent_t> {
|
Chris@16
|
330 };
|
Chris@16
|
331
|
Chris@16
|
332 template <typename SI>
|
Chris@16
|
333 struct channel_type<memory_based_2d_locator<SI> > : public channel_type<typename memory_based_2d_locator<SI>::parent_t> {
|
Chris@16
|
334 };
|
Chris@16
|
335
|
Chris@16
|
336 /////////////////////////////
|
Chris@16
|
337 // HasDynamicXStepTypeConcept
|
Chris@16
|
338 /////////////////////////////
|
Chris@16
|
339
|
Chris@16
|
340 // Take the base iterator of SI (which is typically a step iterator) and change it to have a step in x
|
Chris@16
|
341 template <typename SI>
|
Chris@16
|
342 struct dynamic_x_step_type<memory_based_2d_locator<SI> > {
|
Chris@16
|
343 private:
|
Chris@16
|
344 typedef typename iterator_adaptor_get_base<SI>::type base_iterator_t;
|
Chris@16
|
345 typedef typename dynamic_x_step_type<base_iterator_t>::type base_iterator_step_t;
|
Chris@16
|
346 typedef typename iterator_adaptor_rebind<SI, base_iterator_step_t>::type dynamic_step_base_t;
|
Chris@16
|
347 public:
|
Chris@16
|
348 typedef memory_based_2d_locator<dynamic_step_base_t> type;
|
Chris@16
|
349 };
|
Chris@16
|
350
|
Chris@16
|
351 /////////////////////////////
|
Chris@16
|
352 // HasDynamicYStepTypeConcept
|
Chris@16
|
353 /////////////////////////////
|
Chris@16
|
354
|
Chris@16
|
355 template <typename SI>
|
Chris@16
|
356 struct dynamic_y_step_type<memory_based_2d_locator<SI> > {
|
Chris@16
|
357 typedef memory_based_2d_locator<SI> type;
|
Chris@16
|
358 };
|
Chris@16
|
359
|
Chris@16
|
360 } } // namespace boost::gil
|
Chris@16
|
361
|
Chris@16
|
362 #endif
|