Boost GIL


virtual_locator.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_VIRTUAL_LOCATOR_HPP
9 #define BOOST_GIL_VIRTUAL_LOCATOR_HPP
10 
11 #include <boost/gil/dynamic_step.hpp>
12 #include <boost/gil/position_iterator.hpp>
13 
14 #include <boost/assert.hpp>
15 #include <boost/iterator/iterator_facade.hpp>
16 
17 namespace boost { namespace gil {
18 
22 template <typename Deref, bool IsTransposed> // A function object that given a point returns a reference. Models PixelDereferenceAdaptorConcept
23 class virtual_2d_locator : public pixel_2d_locator_base<virtual_2d_locator<Deref,IsTransposed>, position_iterator<Deref,IsTransposed>, position_iterator<Deref,1-IsTransposed>>
24 {
26 public:
29 
30  using deref_fn_t = Deref;
31  using point_t = typename parent_t::point_t;
32 
33  using coord_t = typename parent_t::coord_t;
34  using x_coord_t = typename parent_t::x_coord_t;
35  using y_coord_t = typename parent_t::y_coord_t;
36  using x_iterator = typename parent_t::x_iterator;
37  using y_iterator = typename parent_t::y_iterator;
38 
39  template <typename NewDeref> struct add_deref
40  {
41  using type = virtual_2d_locator<deref_compose<NewDeref,Deref>,IsTransposed>;
42  static type make(const virtual_2d_locator<Deref,IsTransposed>& loc, const NewDeref& nderef) {
43  return type(loc.pos(), loc.step(), deref_compose<NewDeref,Deref>(nderef,loc.deref_fn()));
44  }
45  };
46 
47  virtual_2d_locator(const point_t& p=point_t(0,0), const point_t& step=point_t(1,1), const deref_fn_t& d=deref_fn_t()) : _p(p,step,d) {}
48  template <typename D, bool TR> virtual_2d_locator(const virtual_2d_locator<D,TR>& loc, coord_t y_step)
49  : _p(loc.pos(), point_t(loc.step().x,loc.step().y*y_step), loc.deref_fn()) {}
50 
51  template <typename D, bool TR>
52  virtual_2d_locator(virtual_2d_locator<D, TR> const& loc, coord_t x_step, coord_t y_step, bool transpose = false)
53  : _p(loc.pos()
54  , transpose ?
55  point_t(loc.step().x * y_step, loc.step().y * x_step) :
56  point_t(loc.step().x * x_step, loc.step().y * y_step)
57  , loc.deref_fn())
58  {
59  BOOST_ASSERT(transpose == (IsTransposed != TR));
60  }
61 
62  template <typename D, bool TR> virtual_2d_locator(const virtual_2d_locator<D,TR>& pl) : _p(pl._p) {}
63  virtual_2d_locator(const virtual_2d_locator& pl) : _p(pl._p) {}
64 
65  bool operator==(const this_t& p) const { return _p==p._p; }
66 
67  x_iterator& x() { return *gil_reinterpret_cast<x_iterator*>(this); }
68  y_iterator& y() { return _p; }
69  x_iterator const& x() const { return *gil_reinterpret_cast_c<x_iterator const*>(this); }
70  y_iterator const& y() const { return _p; }
71 
72  // Returns the y distance between two x_iterators given the difference of their x positions
73  y_coord_t y_distance_to(const this_t& it2, x_coord_t) const { return (it2.pos()[1-IsTransposed] - pos()[1-IsTransposed])/step()[1-IsTransposed]; }
74  bool is_1d_traversable(x_coord_t) const { return false; } // is there no gap at the end of each row? I.e. can we use x_iterator to visit every pixel instead of nested loops?
75 
76  // Methods specific for virtual 2D locator
77  const point_t& pos() const { return _p.pos(); }
78  const point_t& step() const { return _p.step(); }
79  const deref_fn_t& deref_fn() const { return _p.deref_fn(); }
80 private:
81  template <typename D, bool TR> friend class virtual_2d_locator;
82  y_iterator _p; // contains the current position, the step and the dereference object
83 };
84 
86 // PixelBasedConcept
88 
89 template <typename D, bool TR>
90 struct channel_type<virtual_2d_locator<D,TR> > : public channel_type<typename virtual_2d_locator<D,TR>::parent_t> {
91 };
92 
93 template <typename D, bool TR>
94 struct color_space_type<virtual_2d_locator<D,TR> > : public color_space_type<typename virtual_2d_locator<D,TR>::parent_t> {
95 };
96 
97 template <typename D, bool TR>
98 struct channel_mapping_type<virtual_2d_locator<D,TR> > : public channel_mapping_type<typename virtual_2d_locator<D,TR>::parent_t> {
99 };
100 
101 template <typename D, bool TR>
102 struct is_planar<virtual_2d_locator<D,TR> > : public is_planar<typename virtual_2d_locator<D,TR>::parent_t> {
103 };
104 
106 // HasDynamicXStepTypeConcept
108 
109 template <typename D, bool TR>
110 struct dynamic_x_step_type<virtual_2d_locator<D,TR>>
111 {
112  using type = virtual_2d_locator<D,TR>;
113 };
114 
116 // HasDynamicYStepTypeConcept
118 
119 template <typename D, bool TR>
120 struct dynamic_y_step_type<virtual_2d_locator<D,TR>>
121 {
122  using type = virtual_2d_locator<D,TR>;
123 };
124 
126 // HasTransposedTypeConcept
128 
129 template <typename D, bool IsTransposed>
130 struct transposed_type<virtual_2d_locator<D,IsTransposed>>
131 {
132  using type = virtual_2d_locator<D,1-IsTransposed>;
133 };
134 
135 }} // namespace boost::gil
136 
137 #endif
Definition: algorithm.hpp:30
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:109
An iterator that remembers its current X,Y position and invokes a function object with it upon derefe...
Definition: position_iterator.hpp:27
A 2D locator over a virtual image. Upon dereferencing, invokes a given function object passing it its...
Definition: virtual_locator.hpp:23
Definition: image_view_factory.hpp:37
Composes two dereference function objects. Similar to std::unary_compose but needs to pull some alias...
Definition: utilities.hpp:105
Base template for types that model HasDynamicYStepTypeConcept.
Definition: dynamic_step.hpp:21
Definition: color_convert.hpp:30
2D point both axes of which have the same dimension typeModels: Point2DConcept
Definition: locator.hpp:28
Base template for types that model HasDynamicXStepTypeConcept.
Definition: dynamic_step.hpp:17