00001 /*00002 Copyright 2005-2007 Adobe Systems Incorporated00003 00004 Use, modification and distribution are subject to the Boost Software License,00005 Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at00006 http://www.boost.org/LICENSE_1_0.txt).00007
00008 See http://opensource.adobe.com/gil for most recent version including documentation.00009 */00010
00011 /*************************************************************************************************/00012
00013 #ifndef GIL_LOCATOR_H00014 #define GIL_LOCATOR_H00015
00016
00025
00026 #include <cstddef>00027 #include <cassert>00028 #include "pixel_iterator.hpp"00029
00033
00034
00035 namespace boost { namespace gil {
00036
00037 //forward declarations00038 template <typename P> ptrdiff_t memunit_step(const P*);
00039 template <typename P> P* memunit_advanced(const P* p, ptrdiff_t diff);
00040 template <typename P> P& memunit_advanced_ref(P* p, ptrdiff_t diff);
00041 template <typename Iterator, typename D> struct iterator_add_deref;
00042 template <typename T> class point2;
00043 namespace detail {
00044 // helper class specialized for each axis of pixel_2d_locator00045 template <std::size_t D, typename Loc> class locator_axis;
00046 }
00047 template <typename T> struct dynamic_x_step_type;
00048 template <typename T> struct dynamic_y_step_type;
00049
00050 template <typename T> struct channel_type;
00051 template <typename T> struct color_space_type;
00052 template <typename T> struct channel_mapping_type;
00053 template <typename T> struct is_planar;
00054 template <typename T> struct num_channels;
00055
00056 // The type of a locator or a view that has X and Y swapped. By default it is the same00057 template <typename T> struct transposed_type {
00058 typedef T type;
00059 };
00060
00119
00120 template <typename Loc, typename XIterator, typename YIterator> // The concrete subclass, the X-iterator and the Y-iterator00121class pixel_2d_locator_base {
00122 public:
00123 typedef XIterator x_iterator;
00124 typedef YIterator y_iterator;
00125
00126 // typedefs required by ConstRandomAccessNDLocatorConcept00127 staticconst std::size_t num_dimensions=2;
00128 typedeftypename std::iterator_traits<x_iterator>::value_type value_type;
00129 typedeftypename std::iterator_traits<x_iterator>::reference reference; // result of dereferencing00130 typedeftypename std::iterator_traits<x_iterator>::difference_type coord_t; // 1D difference type (same for all dimensions)00131 typedefpoint2<coord_t>difference_type; // result of operator-(locator,locator)00132 typedefdifference_typepoint_t;
00133 template <std::size_t D> struct axis {
00134 typedeftypename detail::locator_axis<D,Loc>::coord_t coord_t;
00135 typedeftypename detail::locator_axis<D,Loc>::iterator iterator;
00136 };
00137
00138 // typedefs required by ConstRandomAccess2DLocatorConcept00139 typedeftypename point_t::template axis<0>::coord_t x_coord_t;
00140 typedeftypename point_t::template axis<1>::coord_t y_coord_t;
00141
00142 bool operator!=(const Loc& p) const { return !(concrete()==p); }
00143
00144 x_iterator x_at(x_coord_t dx, y_coord_t dy) const { Loc tmp=concrete(); tmp+=point_t(dx,dy); return tmp.x(); }
00145 x_iterator x_at(constdifference_type& d) const { Loc tmp=concrete(); tmp+=d; return tmp.x(); }
00146 y_iterator y_at(x_coord_t dx, y_coord_t dy) const { Loc tmp=concrete(); tmp+=point_t(dx,dy); return tmp.y(); }
00147 y_iterator y_at(constdifference_type& d) const { Loc tmp=concrete(); tmp+=d; return tmp.y(); }
00148 Loc xy_at(x_coord_t dx, y_coord_t dy) const { Loc tmp=concrete(); tmp+=point_t(dx,dy); return tmp; }
00149 Loc xy_at(constdifference_type& d) const { Loc tmp=concrete(); tmp+=d; return tmp; }
00150
00151 template <std::size_t D> typename axis<D>::iterator& axis_iterator() { return detail::locator_axis<D,Loc>()(concrete()); }
00152 template <std::size_t D> typename axis<D>::iterator const& axis_iterator() const { return detail::locator_axis<D,Loc>()(concrete()); }
00153 template <std::size_t D> typename axis<D>::iterator axis_iterator(constpoint_t& p) const { return detail::locator_axis<D,Loc>()(concrete(),p); }
00154
00155 reference operator()(x_coord_t dx, y_coord_t dy) const { return *x_at(dx,dy); }
00156 reference operator[](constdifference_type& d) const { return *x_at(d.x,d.y); }
00157
00158 reference operator*() const { return *concrete().x(); }
00159
00160 Loc& operator+=(constdifference_type& d) { concrete().x()+=d.x; concrete().y()+=d.y; return concrete(); }
00161 Loc& operator-=(constdifference_type& d) { concrete().x()-=d.x; concrete().y()-=d.y; return concrete(); }
00162
00163 Loc operator+(constdifference_type& d) const { return xy_at(d); }
00164 Loc operator-(constdifference_type& d) const { return xy_at(-d); }
00165
00166 // Some locators can cache 2D coordinates for faster subsequent access. By default there is no caching00167 typedefdifference_typecached_location_t;
00168 cached_location_t cache_location(constdifference_type& d) const { return d; }
00169 cached_location_t cache_location(x_coord_t dx, y_coord_t dy)const { returndifference_type(dx,dy); }
00170
00171 private:
00172 Loc& concrete() { return (Loc&)*this; }
00173 const Loc& concrete() const { return (const Loc&)*this; }
00174
00175 template <typename X> friendclass pixel_2d_locator;
00176 };
00177
00178 // helper classes for each axis of pixel_2d_locator_base00179 namespace detail {
00180 template <typename Loc>
00181 class locator_axis<0,Loc> {
00182 typedeftypename Loc::point_t point_t;
00183 public:
00184 typedeftypename point_t::template axis<0>::coord_t coord_t;
00185 typedeftypename Loc::x_iterator iterator;
00186
00187 inline iterator& operator()( Loc& loc) const { return loc.x(); }
00188 inline iterator const& operator()(const Loc& loc) const { return loc.x(); }
00189 inline iterator operator()( Loc& loc, const point_t& d) const { return loc.x_at(d); }
00190 inline iterator operator()(const Loc& loc, const point_t& d) const { return loc.x_at(d); }
00191 };
00192
00193 template <typename Loc>
00194 class locator_axis<1,Loc> {
00195 typedeftypename Loc::point_t point_t;
00196 public:
00197 typedeftypename point_t::template axis<1>::coord_t coord_t;
00198 typedeftypename Loc::y_iterator iterator;
00199
00200 inline iterator& operator()( Loc& loc) const { return loc.y(); }
00201 inline iterator const& operator()(const Loc& loc) const { return loc.y(); }
00202 inline iterator operator()( Loc& loc, const point_t& d) const { return loc.y_at(d); }
00203 inline iterator operator()(const Loc& loc, const point_t& d) const { return loc.y_at(d); }
00204 };
00205 }
00206
00207 template <typename Loc, typename XIt, typename YIt>
00208 struct channel_type<pixel_2d_locator_base<Loc,XIt,YIt> > : public channel_type<XIt> {};
00209
00210 template <typename Loc, typename XIt, typename YIt>
00211 struct color_space_type<pixel_2d_locator_base<Loc,XIt,YIt> > : public color_space_type<XIt> {};
00212
00213 template <typename Loc, typename XIt, typename YIt>
00214 struct channel_mapping_type<pixel_2d_locator_base<Loc,XIt,YIt> > : public channel_mapping_type<XIt> {};
00215
00216 template <typename Loc, typename XIt, typename YIt>
00217 struct is_planar<pixel_2d_locator_base<Loc,XIt,YIt> > : public is_planar<XIt> {};
00218
00239
00240 template <typename StepIterator>
00241class memory_based_2d_locator : publicpixel_2d_locator_base<memory_based_2d_locator<StepIterator>, typename iterator_adaptor_get_base<StepIterator>::type, StepIterator> {
00242 typedefmemory_based_2d_locator<StepIterator>this_t;
00243 GIL_CLASS_REQUIRE(StepIterator, boost::gil, StepIteratorConcept)
00244 public:
00245 typedefpixel_2d_locator_base<memory_based_2d_locator<StepIterator>, typename iterator_adaptor_get_base<StepIterator>::type, StepIterator> parent_t;
00246 typedefmemory_based_2d_locator<typename const_iterator_type<StepIterator>::type> const_t; // same as this type, but over const values00247
00248 typedeftypename parent_t::coord_t coord_t;
00249 typedeftypename parent_t::x_coord_t x_coord_t;
00250 typedeftypename parent_t::y_coord_t y_coord_t;
00251 typedeftypename parent_t::x_iterator x_iterator;
00252 typedeftypename parent_t::y_iterator y_iterator;
00253 typedeftypenameparent_t::difference_typedifference_type;
00254 typedeftypename parent_t::reference reference;
00255
00256 template <typename Deref> struct add_deref {
00257 typedefmemory_based_2d_locator<typename iterator_add_deref<StepIterator,Deref>::type> type;
00258 static type make(constmemory_based_2d_locator<StepIterator>& loc, const Deref& nderef) {
00259 return type(iterator_add_deref<StepIterator,Deref>::make(loc.y(),nderef));
00260 }
00261 };
00262
00263 memory_based_2d_locator() {}
00264 memory_based_2d_locator(const StepIterator& yit) : _p(yit) {}
00265 template <typename SI> memory_based_2d_locator(constmemory_based_2d_locator<SI>& loc, coord_t y_step) : _p(loc.x(), loc.row_size()*y_step) {}
00266 template <typename SI> memory_based_2d_locator(constmemory_based_2d_locator<SI>& loc, coord_t x_step, coord_t y_step, bool transpose=false)
00267 : _p(make_step_iterator(loc.x(),(transpose ? loc.row_size() : loc.pixel_size())*x_step),
00268 (transpose ? loc.pixel_size() : loc.row_size())*y_step ) {}
00269
00270 memory_based_2d_locator(x_iterator xit, std::ptrdiff_t row_bytes) : _p(xit,row_bytes) {}
00271 template <typename X> memory_based_2d_locator(constmemory_based_2d_locator<X>& pl) : _p(pl._p) {}
00272 memory_based_2d_locator(constmemory_based_2d_locator& pl) : _p(pl._p) {}
00273
00274 bool operator==(constthis_t& p) const { return _p==p._p; }
00275
00276 x_iterator const& x() const { return _p.base(); }
00277 y_iterator const& y() const { return _p; }
00278 x_iterator& x() { return _p.base(); }
00279 y_iterator& y() { return _p; }
00280
00281 // These are faster versions of functions already provided in the superclass 00282 x_iterator x_at (x_coord_t dx, y_coord_t dy) const { return memunit_advanced(x(), offset(dx,dy)); }
00283 x_iterator x_at (constdifference_type& d) const { return memunit_advanced(x(), offset(d.x,d.y)); }
00284 this_t xy_at (x_coord_t dx, y_coord_t dy) const { returnthis_t(x_at( dx , dy ), row_size()); }
00285 this_t xy_at (constdifference_type& d) const { returnthis_t(x_at( d.x, d.y), row_size()); }
00286 reference operator()(x_coord_t dx, y_coord_t dy) const { return memunit_advanced_ref(x(),offset(dx,dy)); }
00287 reference operator[](constdifference_type& d) const { return memunit_advanced_ref(x(),offset(d.x,d.y)); }
00288 this_t& operator+=(constdifference_type& d) { memunit_advance(x(),offset(d.x,d.y)); return *this; }
00289 this_t& operator-=(constdifference_type& d) { memunit_advance(x(),offset(-d.x,-d.y)); return *this; }
00290
00291 // Memory-based locators can have 1D caching of 2D relative coordinates00292 typedef std::ptrdiff_t cached_location_t; // type used to store relative location (to allow for more efficient repeated access)00293 cached_location_t cache_location(constdifference_type& d) const { return offset(d.x,d.y); }
00294 cached_location_t cache_location(x_coord_t dx, y_coord_t dy)const { return offset(dx,dy); }
00295 reference operator[](constcached_location_t& loc) const { return memunit_advanced_ref(x(),loc); }
00296
00297 // Only make sense for memory-based locators00298 std::ptrdiff_t row_size() const { return memunit_step(y()); } // distance in mem units (bytes or bits) between adjacent rows00299 std::ptrdiff_t pixel_size() const { return memunit_step(x()); } // distance in mem units (bytes or bits) between adjacent pixels on the same row00300
00301 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?00302
00303 // Returns the vertical distance (it2.y-it1.y) between two x_iterators given the difference of their x positions00304 std::ptrdiff_t y_distance_to(constthis_t& p2, x_coord_t xDiff) const {
00305 std::ptrdiff_t rowDiff=memunit_distance(x(),p2.x())-pixel_size()*xDiff;
00306 assert(( rowDiff % row_size())==0);
00307 return rowDiff / row_size();
00308 }
00309
00310 private:
00311 template <typename X> friendclass memory_based_2d_locator;
00312 std::ptrdiff_t offset(x_coord_t x, y_coord_t y) const { return y*row_size() + x*pixel_size(); }
00313 StepIterator _p;
00314 };
00315
00317 // PixelBasedConcept00319
00320 template <typename SI>
00321 struct color_space_type<memory_based_2d_locator<SI> > : public color_space_type<typename memory_based_2d_locator<SI>::parent_t> {
00322 };
00323
00324 template <typename SI>
00325 struct channel_mapping_type<memory_based_2d_locator<SI> > : public channel_mapping_type<typename memory_based_2d_locator<SI>::parent_t> {
00326 };
00327
00328 template <typename SI>
00329 struct is_planar<memory_based_2d_locator<SI> > : public is_planar<typename memory_based_2d_locator<SI>::parent_t> {
00330 };
00331
00332 template <typename SI>
00333 struct channel_type<memory_based_2d_locator<SI> > : public channel_type<typename memory_based_2d_locator<SI>::parent_t> {
00334 };
00335
00337 // HasDynamicXStepTypeConcept00339
00340 // Take the base iterator of SI (which is typically a step iterator) and change it to have a step in x00341 template <typename SI>
00342 struct dynamic_x_step_type<memory_based_2d_locator<SI> > {
00343 private:
00344 typedeftypename iterator_adaptor_get_base<SI>::type base_iterator_t;
00345 typedeftypename dynamic_x_step_type<base_iterator_t>::type base_iterator_step_t;
00346 typedeftypename iterator_adaptor_rebind<SI, base_iterator_step_t>::type dynamic_step_base_t;
00347 public:
00348 typedef memory_based_2d_locator<dynamic_step_base_t> type;
00349 };
00350
00352 // HasDynamicYStepTypeConcept00354
00355 template <typename SI>
00356 struct dynamic_y_step_type<memory_based_2d_locator<SI> > {
00357 typedef memory_based_2d_locator<SI> type;
00358 };
00359
00360 } } // namespace boost::gil00361
00362 #endif
Generated on Sat May 2 13:50:14 2009 for Generic Image Library by
1.5.6
Статья Generic Image Library: locator.hpp Source File раздела может быть полезна для разработчиков на c++ и boost.
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.