]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /* |
2 | Copyright 2005-2007 Adobe Systems Incorporated | |
3 | ||
4 | Use, modification and distribution are subject to the Boost Software License, | |
5 | Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at | |
6 | http://www.boost.org/LICENSE_1_0.txt). | |
7 | ||
8 | See http://opensource.adobe.com/gil for most recent version including documentation. | |
9 | */ | |
10 | ||
11 | /*************************************************************************************************/ | |
12 | ||
13 | #ifndef GIL_PLANAR_PTR_H | |
14 | #define GIL_PLANAR_PTR_H | |
15 | ||
16 | //////////////////////////////////////////////////////////////////////////////////////// | |
17 | /// \file | |
18 | /// \brief planar pixel pointer class | |
19 | /// \author Lubomir Bourdev and Hailin Jin \n | |
20 | /// Adobe Systems Incorporated | |
21 | /// \date 2005-2007 \n Last updated on February 12, 2007 | |
22 | /// | |
23 | //////////////////////////////////////////////////////////////////////////////////////// | |
24 | ||
25 | #include <cassert> | |
26 | #include <iterator> | |
27 | #include <boost/iterator/iterator_facade.hpp> | |
28 | #include "gil_config.hpp" | |
29 | #include "pixel.hpp" | |
30 | #include "step_iterator.hpp" | |
31 | ||
32 | namespace boost { namespace gil { | |
33 | ||
34 | //forward declaration (as this file is included in planar_pixel_reference.hpp) | |
35 | template <typename ChannelReference, typename ColorSpace> | |
36 | struct planar_pixel_reference; | |
37 | ||
38 | /// \defgroup ColorBaseModelPlanarPtr planar_pixel_iterator | |
39 | /// \ingroup ColorBaseModel | |
40 | /// \brief A homogeneous color base whose element is a channel iterator. Models HomogeneousColorBaseValueConcept | |
41 | /// This class is used as an iterator to a planar pixel. | |
42 | ||
43 | /// \defgroup PixelIteratorModelPlanarPtr planar_pixel_iterator | |
44 | /// \ingroup PixelIteratorModel | |
45 | /// \brief An iterator over planar pixels. Models PixelIteratorConcept, HomogeneousPixelBasedConcept, MemoryBasedIteratorConcept, HasDynamicXStepTypeConcept | |
46 | ||
47 | //////////////////////////////////////////////////////////////////////////////////////// | |
48 | /// \brief An iterator over planar pixels. Models HomogeneousColorBaseConcept, PixelIteratorConcept, HomogeneousPixelBasedConcept, MemoryBasedIteratorConcept, HasDynamicXStepTypeConcept | |
49 | /// | |
50 | /// Planar pixels have channel data that is not consecutive in memory. | |
51 | /// To abstract this we use classes to represent references and pointers to planar pixels. | |
52 | /// | |
53 | /// \ingroup PixelIteratorModelPlanarPtr ColorBaseModelPlanarPtr PixelBasedModel | |
54 | template <typename ChannelPtr, typename ColorSpace> | |
55 | struct planar_pixel_iterator : public iterator_facade<planar_pixel_iterator<ChannelPtr,ColorSpace>, | |
56 | pixel<typename std::iterator_traits<ChannelPtr>::value_type,layout<ColorSpace> >, | |
57 | std::random_access_iterator_tag, | |
58 | const planar_pixel_reference<typename std::iterator_traits<ChannelPtr>::reference,ColorSpace> >, | |
59 | public detail::homogeneous_color_base<ChannelPtr,layout<ColorSpace>,mpl::size<ColorSpace>::value > { | |
60 | private: | |
61 | typedef iterator_facade<planar_pixel_iterator<ChannelPtr,ColorSpace>, | |
62 | pixel<typename std::iterator_traits<ChannelPtr>::value_type,layout<ColorSpace> >, | |
63 | std::random_access_iterator_tag, | |
64 | const planar_pixel_reference<typename std::iterator_traits<ChannelPtr>::reference,ColorSpace> > parent_t; | |
65 | typedef detail::homogeneous_color_base<ChannelPtr,layout<ColorSpace>,mpl::size<ColorSpace>::value> color_base_parent_t; | |
66 | typedef typename std::iterator_traits<ChannelPtr>::value_type channel_t; | |
67 | public: | |
68 | typedef typename parent_t::value_type value_type; | |
69 | typedef typename parent_t::reference reference; | |
70 | typedef typename parent_t::difference_type difference_type; | |
71 | ||
72 | planar_pixel_iterator() : color_base_parent_t(0) {} | |
73 | planar_pixel_iterator(bool) {} // constructor that does not fill with zero (for performance) | |
74 | ||
75 | planar_pixel_iterator(const ChannelPtr& v0, const ChannelPtr& v1) : color_base_parent_t(v0,v1) {} | |
76 | planar_pixel_iterator(const ChannelPtr& v0, const ChannelPtr& v1, const ChannelPtr& v2) : color_base_parent_t(v0,v1,v2) {} | |
77 | planar_pixel_iterator(const ChannelPtr& v0, const ChannelPtr& v1, const ChannelPtr& v2, const ChannelPtr& v3) : color_base_parent_t(v0,v1,v2,v3) {} | |
78 | planar_pixel_iterator(const ChannelPtr& v0, const ChannelPtr& v1, const ChannelPtr& v2, const ChannelPtr& v3, const ChannelPtr& v4) : color_base_parent_t(v0,v1,v2,v3,v4) {} | |
79 | ||
80 | template <typename IC1,typename C1> | |
81 | planar_pixel_iterator(const planar_pixel_iterator<IC1,C1>& ptr) : color_base_parent_t(ptr) {} | |
82 | ||
83 | ||
84 | /// Copy constructor and operator= from pointers to compatible planar pixels or planar pixel references. | |
85 | /// That allow constructs like pointer = &value or pointer = &reference | |
86 | /// Since we should not override operator& that's the best we can do. | |
87 | template <typename P> | |
88 | planar_pixel_iterator(P* pix) : color_base_parent_t(pix, true) { | |
89 | function_requires<PixelsCompatibleConcept<P,value_type> >(); | |
90 | } | |
91 | ||
92 | struct address_of { template <typename T> T* operator()(T& t) { return &t; } }; | |
93 | template <typename P> | |
94 | planar_pixel_iterator& operator=(P* pix) { | |
95 | function_requires<PixelsCompatibleConcept<P,value_type> >(); | |
96 | static_transform(*pix,*this, address_of()); | |
97 | ||
98 | // PERFORMANCE_CHECK: Compare to this: | |
99 | //this->template semantic_at_c<0>()=&pix->template semantic_at_c<0>(); | |
100 | //this->template semantic_at_c<1>()=&pix->template semantic_at_c<1>(); | |
101 | //this->template semantic_at_c<2>()=&pix->template semantic_at_c<2>(); | |
102 | return *this; | |
103 | } | |
104 | ||
105 | /// For some reason operator[] provided by iterator_facade returns a custom class that is convertible to reference | |
106 | /// We require our own reference because it is registered in iterator_traits | |
107 | reference operator[](difference_type d) const { return memunit_advanced_ref(*this,d*sizeof(channel_t));} | |
108 | ||
109 | reference operator->() const { return **this; } | |
110 | ||
111 | // PERFORMANCE_CHECK: Remove? | |
112 | bool operator< (const planar_pixel_iterator& ptr) const { return gil::at_c<0>(*this)< gil::at_c<0>(ptr); } | |
113 | bool operator!=(const planar_pixel_iterator& ptr) const { return gil::at_c<0>(*this)!=gil::at_c<0>(ptr); } | |
114 | private: | |
115 | friend class boost::iterator_core_access; | |
116 | ||
117 | void increment() { static_transform(*this,*this,detail::inc<ChannelPtr>()); } | |
118 | void decrement() { static_transform(*this,*this,detail::dec<ChannelPtr>()); } | |
119 | void advance(ptrdiff_t d) { static_transform(*this,*this,std::bind2nd(detail::plus_asymmetric<ChannelPtr,ptrdiff_t>(),d)); } | |
120 | reference dereference() const { return this->template deref<reference>(); } | |
121 | ||
122 | ptrdiff_t distance_to(const planar_pixel_iterator& it) const { return gil::at_c<0>(it)-gil::at_c<0>(*this); } | |
123 | bool equal(const planar_pixel_iterator& it) const { return gil::at_c<0>(*this)==gil::at_c<0>(it); } | |
124 | }; | |
125 | ||
126 | namespace detail { | |
127 | template <typename IC> struct channel_iterator_is_mutable : public mpl::true_ {}; | |
128 | template <typename T> struct channel_iterator_is_mutable<const T*> : public mpl::false_ {}; | |
129 | } | |
130 | ||
131 | template <typename IC, typename C> | |
132 | struct const_iterator_type<planar_pixel_iterator<IC,C> > { | |
133 | private: | |
134 | typedef typename std::iterator_traits<IC>::value_type channel_t; | |
135 | public: | |
136 | typedef planar_pixel_iterator<typename channel_traits<channel_t>::const_pointer,C> type; | |
137 | }; | |
138 | ||
139 | // The default implementation when the iterator is a C pointer is to use the standard constness semantics | |
140 | template <typename IC, typename C> | |
141 | struct iterator_is_mutable<planar_pixel_iterator<IC,C> > : public detail::channel_iterator_is_mutable<IC> {}; | |
142 | ||
143 | ///////////////////////////// | |
144 | // ColorBasedConcept | |
145 | ///////////////////////////// | |
146 | ||
147 | template <typename IC, typename C, int K> | |
148 | struct kth_element_type<planar_pixel_iterator<IC,C>, K> { | |
149 | typedef IC type; | |
150 | }; | |
151 | ||
152 | template <typename IC, typename C, int K> | |
153 | struct kth_element_reference_type<planar_pixel_iterator<IC,C>, K> : public add_reference<IC> {}; | |
154 | ||
155 | template <typename IC, typename C, int K> | |
156 | struct kth_element_const_reference_type<planar_pixel_iterator<IC,C>, K> : public add_reference<typename add_const<IC>::type> {}; | |
157 | ||
158 | ///////////////////////////// | |
159 | // HomogeneousPixelBasedConcept | |
160 | ///////////////////////////// | |
161 | ||
162 | template <typename IC, typename C> | |
163 | struct color_space_type<planar_pixel_iterator<IC,C> > { | |
164 | typedef C type; | |
165 | }; | |
166 | ||
167 | template <typename IC, typename C> | |
168 | struct channel_mapping_type<planar_pixel_iterator<IC,C> > : public channel_mapping_type<typename planar_pixel_iterator<IC,C>::value_type> {}; | |
169 | ||
170 | template <typename IC, typename C> | |
171 | struct is_planar<planar_pixel_iterator<IC,C> > : public mpl::true_ {}; | |
172 | ||
173 | template <typename IC, typename C> | |
174 | struct channel_type<planar_pixel_iterator<IC,C> > { | |
175 | typedef typename std::iterator_traits<IC>::value_type type; | |
176 | }; | |
177 | ||
178 | ///////////////////////////// | |
179 | // MemoryBasedIteratorConcept | |
180 | ///////////////////////////// | |
181 | ||
182 | template <typename IC, typename C> | |
183 | inline std::ptrdiff_t memunit_step(const planar_pixel_iterator<IC,C>&) { return sizeof(typename std::iterator_traits<IC>::value_type); } | |
184 | ||
185 | template <typename IC, typename C> | |
186 | inline std::ptrdiff_t memunit_distance(const planar_pixel_iterator<IC,C>& p1, const planar_pixel_iterator<IC,C>& p2) { | |
187 | return memunit_distance(gil::at_c<0>(p1),gil::at_c<0>(p2)); | |
188 | } | |
189 | ||
190 | template <typename IC> | |
191 | struct memunit_advance_fn { | |
192 | memunit_advance_fn(std::ptrdiff_t diff) : _diff(diff) {} | |
193 | IC operator()(const IC& p) const { return memunit_advanced(p,_diff); } | |
194 | ||
195 | std::ptrdiff_t _diff; | |
196 | }; | |
197 | ||
198 | template <typename IC, typename C> | |
199 | inline void memunit_advance(planar_pixel_iterator<IC,C>& p, std::ptrdiff_t diff) { | |
200 | static_transform(p, p, memunit_advance_fn<IC>(diff)); | |
201 | } | |
202 | ||
203 | template <typename IC, typename C> | |
204 | inline planar_pixel_iterator<IC,C> memunit_advanced(const planar_pixel_iterator<IC,C>& p, std::ptrdiff_t diff) { | |
205 | planar_pixel_iterator<IC,C> ret=p; | |
206 | memunit_advance(ret, diff); | |
207 | return ret; | |
208 | } | |
209 | ||
210 | template <typename ChannelPtr, typename ColorSpace> | |
211 | inline planar_pixel_reference<typename std::iterator_traits<ChannelPtr>::reference,ColorSpace> | |
212 | memunit_advanced_ref(const planar_pixel_iterator<ChannelPtr,ColorSpace>& ptr, std::ptrdiff_t diff) { | |
213 | return planar_pixel_reference<typename std::iterator_traits<ChannelPtr>::reference,ColorSpace>(ptr, diff); | |
214 | } | |
215 | ||
216 | ///////////////////////////// | |
217 | // HasDynamicXStepTypeConcept | |
218 | ///////////////////////////// | |
219 | ||
220 | template <typename IC, typename C> | |
221 | struct dynamic_x_step_type<planar_pixel_iterator<IC,C> > { | |
222 | typedef memory_based_step_iterator<planar_pixel_iterator<IC,C> > type; | |
223 | }; | |
224 | ||
225 | } } // namespace boost::gil | |
226 | ||
227 | #endif |