8 #ifndef BOOST_GIL_LOCATOR_HPP
9 #define BOOST_GIL_LOCATOR_HPP
11 #include <boost/gil/pixel_iterator.hpp>
12 #include <boost/gil/point.hpp>
17 namespace boost {
namespace gil {
22 template <
typename P> std::ptrdiff_t memunit_step(
const P*);
23 template <
typename P> P* memunit_advanced(
const P* p, std::ptrdiff_t diff);
24 template <
typename P> P& memunit_advanced_ref(P* p, std::ptrdiff_t diff);
26 template <
typename T>
class point;
29 template <std::
size_t D,
typename Loc>
class locator_axis;
31 template <
typename T>
struct dynamic_x_step_type;
32 template <
typename T>
struct dynamic_y_step_type;
35 template <
typename T>
struct color_space_type;
36 template <
typename T>
struct channel_mapping_type;
37 template <
typename T>
struct is_planar;
41 template <
typename T>
struct transposed_type {
104 template <
typename Loc,
typename XIterator,
typename YIterator>
107 typedef XIterator x_iterator;
108 typedef YIterator y_iterator;
111 static const std::size_t num_dimensions=2;
112 typedef typename std::iterator_traits<x_iterator>::value_type value_type;
113 typedef typename std::iterator_traits<x_iterator>::reference reference;
114 typedef typename std::iterator_traits<x_iterator>::difference_type coord_t;
117 template <std::
size_t D>
struct axis {
118 typedef typename detail::locator_axis<D,Loc>::coord_t coord_t;
119 typedef typename detail::locator_axis<D,Loc>::iterator iterator;
123 typedef typename point_t::template axis<0>::coord_t x_coord_t;
124 typedef typename point_t::template axis<1>::coord_t y_coord_t;
126 bool operator!=(
const Loc& p)
const {
return !(concrete()==p); }
128 x_iterator x_at(x_coord_t dx, y_coord_t dy)
const { Loc tmp=concrete(); tmp+=
point_t(dx,dy);
return tmp.x(); }
129 x_iterator x_at(
const difference_type& d)
const { Loc tmp=concrete(); tmp+=d;
return tmp.x(); }
130 y_iterator y_at(x_coord_t dx, y_coord_t dy)
const { Loc tmp=concrete(); tmp+=
point_t(dx,dy);
return tmp.y(); }
131 y_iterator y_at(
const difference_type& d)
const { Loc tmp=concrete(); tmp+=d;
return tmp.y(); }
132 Loc xy_at(x_coord_t dx, y_coord_t dy)
const { Loc tmp=concrete(); tmp+=
point_t(dx,dy);
return tmp; }
133 Loc xy_at(
const difference_type& d)
const { Loc tmp=concrete(); tmp+=d;
return tmp; }
135 template <std::
size_t D>
typename axis<D>::iterator& axis_iterator() {
return detail::locator_axis<D,Loc>()(concrete()); }
136 template <std::
size_t D>
typename axis<D>::iterator
const& axis_iterator()
const {
return detail::locator_axis<D,Loc>()(concrete()); }
137 template <std::
size_t D>
typename axis<D>::iterator axis_iterator(
const point_t& p)
const {
return detail::locator_axis<D,Loc>()(concrete(),p); }
139 reference operator()(x_coord_t dx, y_coord_t dy)
const {
return *x_at(dx,dy); }
140 reference operator[](
const difference_type& d)
const {
return *x_at(d.x,d.y); }
142 reference operator*()
const {
return *concrete().x(); }
144 Loc& operator+=(
const difference_type& d) { concrete().x()+=d.x; concrete().y()+=d.y;
return concrete(); }
145 Loc& operator-=(
const difference_type& d) { concrete().x()-=d.x; concrete().y()-=d.y;
return concrete(); }
156 Loc& concrete() {
return (Loc&)*
this; }
157 const Loc& concrete()
const {
return (
const Loc&)*
this; }
159 template <
typename X>
friend class pixel_2d_locator;
164 template <
typename Loc>
165 class locator_axis<0,Loc> {
166 typedef typename Loc::point_t
point_t;
168 typedef typename point_t::template axis<0>::coord_t coord_t;
169 typedef typename Loc::x_iterator iterator;
171 inline iterator& operator()( Loc& loc)
const {
return loc.x(); }
172 inline iterator
const& operator()(
const Loc& loc)
const {
return loc.x(); }
173 inline iterator operator()( Loc& loc,
const point_t& d)
const {
return loc.x_at(d); }
174 inline iterator operator()(
const Loc& loc,
const point_t& d)
const {
return loc.x_at(d); }
177 template <
typename Loc>
178 class locator_axis<1,Loc> {
179 typedef typename Loc::point_t point_t;
181 typedef typename point_t::template axis<1>::coord_t coord_t;
182 typedef typename Loc::y_iterator iterator;
184 inline iterator& operator()( Loc& loc)
const {
return loc.y(); }
185 inline iterator
const& operator()(
const Loc& loc)
const {
return loc.y(); }
186 inline iterator operator()( Loc& loc,
const point_t& d)
const {
return loc.y_at(d); }
187 inline iterator operator()(
const Loc& loc,
const point_t& d)
const {
return loc.y_at(d); }
191 template <
typename Loc,
typename XIt,
typename YIt>
192 struct channel_type<pixel_2d_locator_base<Loc,XIt,YIt> > :
public channel_type<XIt> {};
194 template <
typename Loc,
typename XIt,
typename YIt>
195 struct color_space_type<pixel_2d_locator_base<Loc,XIt,YIt> > :
public color_space_type<XIt> {};
197 template <
typename Loc,
typename XIt,
typename YIt>
198 struct channel_mapping_type<pixel_2d_locator_base<Loc,XIt,YIt> > :
public channel_mapping_type<XIt> {};
200 template <
typename Loc,
typename XIt,
typename YIt>
201 struct is_planar<pixel_2d_locator_base<Loc,XIt,YIt> > :
public is_planar<XIt> {};
224 template <
typename StepIterator>
225 class memory_based_2d_locator :
public pixel_2d_locator_base<memory_based_2d_locator<StepIterator>, typename iterator_adaptor_get_base<StepIterator>::type, StepIterator> {
226 typedef memory_based_2d_locator<StepIterator> this_t;
227 GIL_CLASS_REQUIRE(StepIterator, boost::gil, StepIteratorConcept)
229 typedef pixel_2d_locator_base<memory_based_2d_locator<StepIterator>, typename iterator_adaptor_get_base<StepIterator>::type, StepIterator> parent_t;
230 typedef memory_based_2d_locator<typename const_iterator_type<StepIterator>::type> const_t;
232 typedef typename parent_t::coord_t coord_t;
233 typedef typename parent_t::x_coord_t x_coord_t;
234 typedef typename parent_t::y_coord_t y_coord_t;
235 typedef typename parent_t::x_iterator x_iterator;
236 typedef typename parent_t::y_iterator y_iterator;
237 typedef typename parent_t::difference_type difference_type;
238 typedef typename parent_t::reference reference;
240 template <typename Deref> struct add_deref {
241 typedef memory_based_2d_locator<typename iterator_add_deref<StepIterator,Deref>::type> type;
242 static type make(
const memory_based_2d_locator<StepIterator>& loc,
const Deref& nderef) {
243 return type(iterator_add_deref<StepIterator,Deref>::make(loc.y(),nderef));
247 memory_based_2d_locator() {}
248 memory_based_2d_locator(
const StepIterator& yit) : _p(yit) {}
249 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) {}
250 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)
251 : _p(make_step_iterator(loc.x(),(transpose ? loc.row_size() : loc.pixel_size())*x_step),
252 (transpose ? loc.pixel_size() : loc.row_size())*y_step ) {}
254 memory_based_2d_locator(x_iterator xit, std::ptrdiff_t row_bytes) : _p(xit,row_bytes) {}
255 template <
typename X> memory_based_2d_locator(
const memory_based_2d_locator<X>& pl) : _p(pl._p) {}
256 memory_based_2d_locator(
const memory_based_2d_locator& pl) : _p(pl._p) {}
258 bool operator==(
const this_t& p)
const {
return _p==p._p; }
260 x_iterator
const& x()
const {
return _p.base(); }
261 y_iterator
const& y()
const {
return _p; }
262 x_iterator& x() {
return _p.base(); }
263 y_iterator& y() {
return _p; }
266 x_iterator x_at (x_coord_t dx, y_coord_t dy)
const {
return memunit_advanced(x(), offset(dx,dy)); }
267 x_iterator x_at (
const difference_type& d)
const {
return memunit_advanced(x(), offset(d.x,d.y)); }
268 this_t xy_at (x_coord_t dx, y_coord_t dy)
const {
return this_t(x_at( dx , dy ), row_size()); }
269 this_t xy_at (
const difference_type& d)
const {
return this_t(x_at( d.x, d.y), row_size()); }
270 reference operator()(x_coord_t dx, y_coord_t dy)
const {
return memunit_advanced_ref(x(),offset(dx,dy)); }
271 reference operator[](
const difference_type& d)
const {
return memunit_advanced_ref(x(),offset(d.x,d.y)); }
272 this_t& operator+=(
const difference_type& d) { memunit_advance(x(),offset(d.x,d.y));
return *
this; }
273 this_t& operator-=(
const difference_type& d) { memunit_advance(x(),offset(-d.x,-d.y));
return *
this; }
276 typedef std::ptrdiff_t cached_location_t;
277 cached_location_t cache_location(
const difference_type& d)
const {
return offset(d.x,d.y); }
278 cached_location_t cache_location(x_coord_t dx, y_coord_t dy)
const {
return offset(dx,dy); }
279 reference operator[](
const cached_location_t& loc)
const {
return memunit_advanced_ref(x(),loc); }
282 std::ptrdiff_t row_size()
const {
return memunit_step(y()); }
283 std::ptrdiff_t pixel_size()
const {
return memunit_step(x()); }
285 bool is_1d_traversable(x_coord_t width)
const {
return row_size()-pixel_size()*width==0; }
288 std::ptrdiff_t y_distance_to(
const this_t& p2, x_coord_t xDiff)
const {
289 std::ptrdiff_t rowDiff=memunit_distance(x(),p2.x())-pixel_size()*xDiff;
290 assert(( rowDiff % row_size())==0);
291 return rowDiff / row_size();
295 template <
typename X>
friend class memory_based_2d_locator;
296 std::ptrdiff_t offset(x_coord_t x, y_coord_t y)
const {
return y*row_size() + x*pixel_size(); }
304 template <
typename SI>
305 struct color_space_type<memory_based_2d_locator<SI> > :
public color_space_type<typename memory_based_2d_locator<SI>::parent_t> {
308 template <
typename SI>
309 struct channel_mapping_type<memory_based_2d_locator<SI> > :
public channel_mapping_type<typename memory_based_2d_locator<SI>::parent_t> {
312 template <
typename SI>
313 struct is_planar<memory_based_2d_locator<SI> > :
public is_planar<typename memory_based_2d_locator<SI>::parent_t> {
316 template <
typename SI>
317 struct channel_type<memory_based_2d_locator<SI> > :
public channel_type<typename memory_based_2d_locator<SI>::parent_t> {
325 template <
typename SI>
326 struct dynamic_x_step_type<memory_based_2d_locator<SI> > {
328 typedef typename iterator_adaptor_get_base<SI>::type base_iterator_t;
329 typedef typename dynamic_x_step_type<base_iterator_t>::type base_iterator_step_t;
330 typedef typename iterator_adaptor_rebind<SI, base_iterator_step_t>::type dynamic_step_base_t;
332 typedef memory_based_2d_locator<dynamic_step_base_t> type;
339 template <
typename SI>
340 struct dynamic_y_step_type<memory_based_2d_locator<SI> > {
341 typedef memory_based_2d_locator<SI> type;
base class for models of PixelLocatorConceptPixel locator is similar to a pixel iterator, but allows for 2D navigation of pixels within an image view. It has a 2D difference_type and supports random access operations like:
Definition: locator.hpp:105
Returns the type (and creates an instance) of an iterator that invokes the given dereference adaptor ...
Definition: locator.hpp:25
Definition: color_convert.hpp:30
Returns the number of channels of a pixel-based GIL construct.
Definition: concepts.hpp:56
2D point both axes of which have the same dimension typeModels: Point2DConcept
Definition: concepts.hpp:42