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_VIRTUAL_LOCATOR_HPP
|
Chris@16
|
14 #define GIL_VIRTUAL_LOCATOR_HPP
|
Chris@16
|
15
|
Chris@16
|
16 ////////////////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
17 /// \file
|
Chris@16
|
18 /// \brief Locator for virtual image views
|
Chris@16
|
19 /// \author Lubomir Bourdev and Hailin Jin \n
|
Chris@16
|
20 /// Adobe Systems Incorporated
|
Chris@16
|
21 /// \date 2005-2007 \n Last updated on February 12, 2007
|
Chris@16
|
22 ///
|
Chris@16
|
23 ////////////////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
24
|
Chris@16
|
25 #include <boost/iterator/iterator_facade.hpp>
|
Chris@16
|
26 #include "position_iterator.hpp"
|
Chris@16
|
27
|
Chris@16
|
28 namespace boost { namespace gil {
|
Chris@16
|
29
|
Chris@16
|
30 /// \brief A 2D locator over a virtual image. Upon dereferencing, invokes a given function object passing it its coordinates. Models: PixelLocatorConcept, HasDynamicXStepTypeConcept, HasDynamicYStepTypeConcept, HasTransposedTypeConcept
|
Chris@16
|
31 /// \ingroup PixelLocatorModel PixelBasedModel
|
Chris@16
|
32 ///
|
Chris@16
|
33 template <typename Deref, bool IsTransposed> // A function object that given a point returns a reference. Models PixelDereferenceAdaptorConcept
|
Chris@16
|
34 class virtual_2d_locator : public pixel_2d_locator_base<virtual_2d_locator<Deref,IsTransposed>, position_iterator<Deref,IsTransposed>, position_iterator<Deref,1-IsTransposed> > {
|
Chris@16
|
35 typedef virtual_2d_locator<Deref,IsTransposed> this_t;
|
Chris@16
|
36 public:
|
Chris@16
|
37 typedef pixel_2d_locator_base<virtual_2d_locator<Deref,IsTransposed>, position_iterator<Deref,IsTransposed>, position_iterator<Deref,1-IsTransposed> > parent_t;
|
Chris@16
|
38 typedef virtual_2d_locator<typename Deref::const_t,IsTransposed> const_t;
|
Chris@16
|
39
|
Chris@16
|
40 typedef Deref deref_fn_t;
|
Chris@16
|
41 typedef typename parent_t::point_t point_t;
|
Chris@16
|
42
|
Chris@16
|
43 typedef typename parent_t::coord_t coord_t;
|
Chris@16
|
44 typedef typename parent_t::x_coord_t x_coord_t;
|
Chris@16
|
45 typedef typename parent_t::y_coord_t y_coord_t;
|
Chris@16
|
46 typedef typename parent_t::x_iterator x_iterator;
|
Chris@16
|
47 typedef typename parent_t::y_iterator y_iterator;
|
Chris@16
|
48
|
Chris@16
|
49 template <typename NewDeref> struct add_deref {
|
Chris@16
|
50 typedef virtual_2d_locator<deref_compose<NewDeref,Deref>,IsTransposed > type;
|
Chris@16
|
51 static type make(const virtual_2d_locator<Deref,IsTransposed>& loc, const NewDeref& nderef) {
|
Chris@16
|
52 return type(loc.pos(), loc.step(), deref_compose<NewDeref,Deref>(nderef,loc.deref_fn()));
|
Chris@16
|
53 }
|
Chris@16
|
54 };
|
Chris@16
|
55
|
Chris@16
|
56 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) {}
|
Chris@16
|
57 template <typename D, bool TR> virtual_2d_locator(const virtual_2d_locator<D,TR>& loc, coord_t y_step)
|
Chris@16
|
58 : _p(loc.pos(), point_t(loc.step().x,loc.step().y*y_step), loc.deref_fn()) {}
|
Chris@16
|
59 template <typename D, bool TR> virtual_2d_locator(const virtual_2d_locator<D,TR>& loc, coord_t x_step, coord_t y_step, bool transpose=false)
|
Chris@16
|
60 : _p(loc.pos(), transpose ?
|
Chris@16
|
61 point_t(loc.step().x*y_step,loc.step().y*x_step) :
|
Chris@16
|
62 point_t(loc.step().x*x_step,loc.step().y*y_step), loc.deref_fn()) { assert(transpose==(IsTransposed!=TR));}
|
Chris@16
|
63
|
Chris@16
|
64 template <typename D, bool TR> virtual_2d_locator(const virtual_2d_locator<D,TR>& pl) : _p(pl._p) {}
|
Chris@16
|
65 virtual_2d_locator(const virtual_2d_locator& pl) : _p(pl._p) {}
|
Chris@16
|
66
|
Chris@16
|
67 bool operator==(const this_t& p) const { return _p==p._p; }
|
Chris@16
|
68
|
Chris@16
|
69 x_iterator& x() { return *gil_reinterpret_cast<x_iterator*>(this); }
|
Chris@16
|
70 y_iterator& y() { return _p; }
|
Chris@16
|
71 x_iterator const& x() const { return *gil_reinterpret_cast_c<x_iterator const*>(this); }
|
Chris@16
|
72 y_iterator const& y() const { return _p; }
|
Chris@16
|
73
|
Chris@16
|
74 // Returns the y distance between two x_iterators given the difference of their x positions
|
Chris@16
|
75 y_coord_t y_distance_to(const this_t& it2, x_coord_t xDiff) const { return (it2.pos()[1-IsTransposed] - pos()[1-IsTransposed])/step()[1-IsTransposed]; }
|
Chris@16
|
76 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?
|
Chris@16
|
77
|
Chris@16
|
78 // Methods specific for virtual 2D locator
|
Chris@16
|
79 const point_t& pos() const { return _p.pos(); }
|
Chris@16
|
80 const point_t& step() const { return _p.step(); }
|
Chris@16
|
81 const deref_fn_t& deref_fn() const { return _p.deref_fn(); }
|
Chris@16
|
82 private:
|
Chris@16
|
83 template <typename D, bool TR> friend class virtual_2d_locator;
|
Chris@16
|
84 y_iterator _p; // contains the current position, the step and the dereference object
|
Chris@16
|
85 };
|
Chris@16
|
86
|
Chris@16
|
87 /////////////////////////////
|
Chris@16
|
88 // PixelBasedConcept
|
Chris@16
|
89 /////////////////////////////
|
Chris@16
|
90
|
Chris@16
|
91 template <typename D, bool TR>
|
Chris@16
|
92 struct channel_type<virtual_2d_locator<D,TR> > : public channel_type<typename virtual_2d_locator<D,TR>::parent_t> {
|
Chris@16
|
93 };
|
Chris@16
|
94
|
Chris@16
|
95 template <typename D, bool TR>
|
Chris@16
|
96 struct color_space_type<virtual_2d_locator<D,TR> > : public color_space_type<typename virtual_2d_locator<D,TR>::parent_t> {
|
Chris@16
|
97 };
|
Chris@16
|
98
|
Chris@16
|
99 template <typename D, bool TR>
|
Chris@16
|
100 struct channel_mapping_type<virtual_2d_locator<D,TR> > : public channel_mapping_type<typename virtual_2d_locator<D,TR>::parent_t> {
|
Chris@16
|
101 };
|
Chris@16
|
102
|
Chris@16
|
103 template <typename D, bool TR>
|
Chris@16
|
104 struct is_planar<virtual_2d_locator<D,TR> > : public is_planar<typename virtual_2d_locator<D,TR>::parent_t> {
|
Chris@16
|
105 };
|
Chris@16
|
106
|
Chris@16
|
107 /////////////////////////////
|
Chris@16
|
108 // HasDynamicXStepTypeConcept
|
Chris@16
|
109 /////////////////////////////
|
Chris@16
|
110
|
Chris@16
|
111 template <typename D, bool TR>
|
Chris@16
|
112 struct dynamic_x_step_type<virtual_2d_locator<D,TR> > {
|
Chris@16
|
113 typedef virtual_2d_locator<D,TR> type;
|
Chris@16
|
114 };
|
Chris@16
|
115
|
Chris@16
|
116 /////////////////////////////
|
Chris@16
|
117 // HasDynamicYStepTypeConcept
|
Chris@16
|
118 /////////////////////////////
|
Chris@16
|
119
|
Chris@16
|
120 template <typename D, bool TR>
|
Chris@16
|
121 struct dynamic_y_step_type<virtual_2d_locator<D,TR> > {
|
Chris@16
|
122 typedef virtual_2d_locator<D,TR> type;
|
Chris@16
|
123 };
|
Chris@16
|
124
|
Chris@16
|
125 /////////////////////////////
|
Chris@16
|
126 // HasTransposedTypeConcept
|
Chris@16
|
127 /////////////////////////////
|
Chris@16
|
128
|
Chris@16
|
129 template <typename D, bool IsTransposed>
|
Chris@16
|
130 struct transposed_type<virtual_2d_locator<D,IsTransposed> > {
|
Chris@16
|
131 typedef virtual_2d_locator<D,1-IsTransposed> type;
|
Chris@16
|
132 };
|
Chris@16
|
133
|
Chris@16
|
134 } } // namespace boost::gil
|
Chris@16
|
135
|
Chris@16
|
136 #endif
|