00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef GIL_LOCATOR_H
00010 #define GIL_LOCATOR_H
00011
00012
00021
00022 #include <cstddef>
00023 #include <iterator>
00024
00028
00064
00065
00066 ADOBE_GIL_NAMESPACE_BEGIN
00067
00068
00069 template <typename P> struct pixel_iterator_traits;
00070 template <typename P> ptrdiff_t byte_step(const P*);
00071 template <typename P> P* byte_advanced(const P* p, ptrdiff_t byteDiff);
00072 template <typename P> P& byte_advanced_ref(P* p, ptrdiff_t byteDiff);
00073 namespace detail {
00074
00076 template <std::size_t D, typename LOC> class pixel_2d_locator_axis;
00077 }
00078
00079 template <typename S_IT>
00080 class pixel_2d_locator {
00081 GIL_CLASS_REQUIRE(S_IT, GIL, PixelStepIteratorConcept);
00082 typedef typename pixel_iterator_traits<S_IT>::base_t X_IT;
00083 public:
00084
00085 static const std::size_t num_dimensions=2;
00086 typedef typename std::iterator_traits<X_IT>::value_type value_type;
00087 typedef value_type pixel_t;
00088 typedef typename std::iterator_traits<X_IT>::reference reference;
00089 typedef typename std::iterator_traits<X_IT>::difference_type coord_t;
00090 typedef point2<coord_t> difference_type;
00091 typedef value_type domain_t;
00092 typedef difference_type point_t;
00093 typedef std::ptrdiff_t cached_location_t;
00094 typedef pixel_2d_locator<typename pixel_iterator_traits<S_IT>::const_t> const_t;
00095 template <std::size_t D> struct axis {
00096 typedef typename detail::pixel_2d_locator_axis<D,pixel_2d_locator>::coord_t coord_t;
00097 typedef typename detail::pixel_2d_locator_axis<D,pixel_2d_locator>::iterator iterator;
00098 };
00099
00100
00101 typedef X_IT x_iterator;
00102 typedef S_IT y_iterator;
00103 typedef typename point_t::template axis<0>::coord_t x_coord_t;
00104 typedef typename point_t::template axis<1>::coord_t y_coord_t;
00105
00106
00107 typedef pixel_2d_locator<typename pixel_iterator_traits<S_IT>::dynamic_step_base_t> dynamic_step_t;
00108 typedef typename pixel_iterator_traits<X_IT>::channel_t channel_t;
00109 typedef typename pixel_iterator_traits<X_IT>::color_space_t color_space_t;
00110 BOOST_STATIC_CONSTANT(int, num_channels=color_space_t::num_channels);
00111
00112 pixel_2d_locator(){}
00113 pixel_2d_locator(x_iterator x_it, std::ptrdiff_t row_bytes) : _p(x_it,row_bytes) {}
00114 template <typename X> pixel_2d_locator(const pixel_2d_locator<X>& pl) : _p(pl._p) {}
00115 pixel_2d_locator(const pixel_2d_locator& pl) : _p(pl._p) {}
00116
00117 bool operator==(const pixel_2d_locator& p) const { return _p==p._p; }
00118 bool operator!=(const pixel_2d_locator& p) const { return _p!=p._p; }
00119
00120
00121 x_iterator& x() { return _p.base(); }
00122 x_iterator const& x() const { return _p.base(); }
00123 y_iterator& y() { return _p; }
00124 y_iterator const& y() const { return _p; }
00125 x_iterator x_at(x_coord_t dx, y_coord_t dy) const { return byte_advanced(x(), byte_offset(dx,dy)); }
00126 x_iterator x_at(const difference_type& d) const { return byte_advanced(x(), byte_offset(d.x,d.y)); }
00127 y_iterator y_at(x_coord_t dx, y_coord_t dy) const { pixel_2d_locator tmp=*this; tmp+=point_t(dx,dy); return tmp.y(); }
00128 y_iterator y_at(const difference_type& d) const { pixel_2d_locator tmp=*this; tmp+=d; return tmp.y(); }
00129 pixel_2d_locator xy_at(const difference_type& d) const { return pixel_2d_locator(x_at( d.x, d.y), row_bytes()); }
00130 pixel_2d_locator xy_at(x_coord_t dx, y_coord_t dy)const { return pixel_2d_locator(x_at( dx , dy ), row_bytes()); }
00131
00132 template <std::size_t D> typename axis<D>::iterator& axis_iterator() { return detail::pixel_2d_locator_axis<D,pixel_2d_locator>()(*this); }
00133 template <std::size_t D> typename axis<D>::iterator const& axis_iterator() const { return detail::pixel_2d_locator_axis<D,pixel_2d_locator>()(*this); }
00134 template <std::size_t D> typename axis<D>::iterator axis_iterator(const point_t& p) const { return detail::pixel_2d_locator_axis<D,pixel_2d_locator>()(*this,p); }
00135
00136 std::ptrdiff_t row_bytes() const { return byte_step(y()); }
00137 std::ptrdiff_t pix_bytestep() const { return byte_step(x()); }
00138
00139 reference operator()(x_coord_t dx, y_coord_t dy) const { return byte_advanced_ref(x(),byte_offset(dx,dy)); }
00140 reference operator[](const difference_type& d) const { return byte_advanced_ref(x(),byte_offset(d.x,d.y)); }
00141
00142 reference operator*() const { return *_p; }
00143
00144 cached_location_t cache_location(const difference_type& d)const { return byte_offset(d.x,d.y); }
00145 cached_location_t cache_location(x_coord_t dx, y_coord_t dy) const { return byte_offset(dx,dy); }
00146 reference operator[](const cached_location_t& loc) const { return byte_advanced_ref(x(),loc); }
00147
00148 pixel_2d_locator& operator+=(const difference_type& d) { byte_advance(x(),byte_offset(d.x,d.y)); return *this; }
00149 pixel_2d_locator& operator-=(const difference_type& d) { byte_advance(x(),byte_offset(-d.x,-d.y)); return *this; }
00150
00151 pixel_2d_locator operator+(const difference_type& d) const { return xy_at(d); }
00152 pixel_2d_locator operator-(const difference_type& d) const { return xy_at(-d); }
00153
00154 private:
00155 template <typename X> friend class pixel_2d_locator;
00156 std::ptrdiff_t byte_offset(x_coord_t x, y_coord_t y) const { return y*row_bytes() + x*pix_bytestep(); }
00157
00158 S_IT _p;
00159 };
00160
00161
00162 namespace detail {
00163 template <typename LOC>
00164 class pixel_2d_locator_axis<0,LOC> {
00165 typedef typename LOC::point_t point_t;
00166 public:
00167 typedef typename point_t::template axis<0>::coord_t coord_t;
00168 typedef typename LOC::x_iterator iterator;
00169
00170 inline iterator& operator()( LOC& loc) const { return loc.x(); }
00171 inline iterator const& operator()(const LOC& loc) const { return loc.x(); }
00172 inline iterator operator()( LOC& loc, const point_t& d) const { return loc.x_at(d); }
00173 inline iterator operator()(const LOC& loc, const point_t& d) const { return loc.x_at(d); }
00174 };
00175
00176 template <typename LOC>
00177 class pixel_2d_locator_axis<1,LOC> {
00178 typedef typename LOC::point_t point_t;
00179 public:
00180 typedef typename point_t::template axis<1>::coord_t coord_t;
00181 typedef typename LOC::y_iterator iterator;
00182
00183 inline iterator& operator()( LOC& loc) const { return loc.y(); }
00184 inline iterator const& operator()(const LOC& loc) const { return loc.y(); }
00185 inline iterator operator()( LOC& loc, const point_t& d) const { return loc.y_at(d); }
00186 inline iterator operator()(const LOC& loc, const point_t& d) const { return loc.y_at(d); }
00187 };
00188 }
00189
00190 ADOBE_GIL_NAMESPACE_END
00191
00192 #endif