]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/gil/example/interleaved_ptr.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / gil / example / interleaved_ptr.hpp
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 ////////////////////////////////////////////////////////////////////////////////////////
14 /// \file
15 /// \brief Example on how to create a pixel iterator
16 /// \author Lubomir Bourdev and Hailin Jin \n
17 /// Adobe Systems Incorporated
18 /// \date 2005-2007 \n Last updated on February 26, 2007
19 ///
20 /// Definitions of standard GIL channel models
21 ///
22 ////////////////////////////////////////////////////////////////////////////////////////
23
24 #ifndef GIL_INTERLEAVED_PTR_HPP
25 #define GIL_INTERLEAVED_PTR_HPP
26
27 #include <boost/gil/pixel_iterator.hpp>
28 #include "interleaved_ref.hpp"
29
30 namespace boost { namespace gil {
31
32 /////////////////////////////////////////////////////////////////////////
33 ///
34 /// A model of an interleaved pixel iterator. Contains an iterator to the first channel of the current pixel
35 ///
36 /// Models:
37 /// MutablePixelIteratorConcept
38 /// PixelIteratorConcept
39 /// boost_concepts::RandomAccessTraversalConcept
40 /// PixelBasedConcept
41 /// HomogeneousPixelBasedConcept
42 /// PixelBasedConcept
43 /// ByteAdvanceableConcept
44 /// HasDynamicXStepTypeConcept
45 ///
46 /////////////////////////////////////////////////////////////////////////
47
48 template <typename ChannelPtr, // Models Channel Iterator (examples: unsigned char* or const unsigned char*)
49 typename Layout> // A layout (includes the color space and channel ordering)
50 struct interleaved_ptr : public boost::iterator_facade<interleaved_ptr<ChannelPtr,Layout>,
51 pixel<typename std::iterator_traits<ChannelPtr>::value_type,Layout>,
52 boost::random_access_traversal_tag,
53 const interleaved_ref<typename std::iterator_traits<ChannelPtr>::reference,Layout> >
54 {
55 private:
56 typedef boost::iterator_facade<interleaved_ptr<ChannelPtr,Layout>,
57 pixel<typename std::iterator_traits<ChannelPtr>::value_type,Layout>,
58 boost::random_access_traversal_tag,
59 const interleaved_ref<typename std::iterator_traits<ChannelPtr>::reference,Layout> > parent_t;
60 typedef typename std::iterator_traits<ChannelPtr>::value_type channel_t;
61 public:
62 typedef typename parent_t::reference reference;
63 typedef typename parent_t::difference_type difference_type;
64
65 interleaved_ptr() {}
66 interleaved_ptr(const interleaved_ptr& ptr) : _channels(ptr._channels) {}
67 template <typename CP> interleaved_ptr(const interleaved_ptr<CP,Layout>& ptr) : _channels(ptr._channels) {}
68
69 interleaved_ptr(const ChannelPtr& channels) : _channels(channels) {}
70
71 // Construct from a pointer to the reference type. Not required by concepts but important
72 interleaved_ptr(reference* pix) : _channels(&((*pix)[0])) {}
73 interleaved_ptr& operator=(reference* pix) { _channels=&((*pix)[0]); return *this; }
74
75 /// For some reason operator[] provided by boost::iterator_facade returns a custom class that is convertible to reference
76 /// We require our own reference because it is registered in iterator_traits
77 reference operator[](difference_type d) const { return memunit_advanced_ref(*this,d*sizeof(channel_t));}
78
79 // Put this for every iterator whose reference is a proxy type
80 reference operator->() const { return **this; }
81
82 // Channels accessor (not required by any concept)
83 const ChannelPtr& channels() const { return _channels; }
84 ChannelPtr& channels() { return _channels; }
85
86 // Not required by concepts but useful
87 static const std::size_t num_channels = mpl::size<typename Layout::color_space_t>::value;
88 private:
89 ChannelPtr _channels;
90 friend class boost::iterator_core_access;
91 template <typename CP, typename L> friend struct interleaved_ptr;
92
93 void increment() { _channels+=num_channels; }
94 void decrement() { _channels-=num_channels; }
95 void advance(ptrdiff_t d) { _channels+=num_channels*d; }
96
97 ptrdiff_t distance_to(const interleaved_ptr& it) const { return (it._channels-_channels)/num_channels; }
98 bool equal(const interleaved_ptr& it) const { return _channels==it._channels; }
99
100 reference dereference() const { return reference(_channels); }
101 };
102
103 /////////////////////////////
104 // PixelIteratorConcept
105 /////////////////////////////
106
107 // To get from the channel pointer a channel pointer to const, we have to go through the channel traits, which take a model of channel
108 // So we can get a model of channel from the channel pointer via iterator_traits. Notice that we take the iterator_traits::reference and not
109 // iterator_traits::value_type. This is because sometimes multiple reference and pointer types share the same value type. An example of this is
110 // GIL's planar reference and iterator ("planar_pixel_reference" and "planar_pixel_iterator") which share the class "pixel" as the value_type. The
111 // class "pixel" is also the value type for interleaved pixel references. Here we are dealing with channels, not pixels, but the principles still apply.
112 template <typename ChannelPtr, typename Layout>
113 struct const_iterator_type<interleaved_ptr<ChannelPtr,Layout> > {
114 private:
115 typedef typename std::iterator_traits<ChannelPtr>::reference channel_ref_t;
116 typedef typename channel_traits<channel_ref_t>::const_pointer channel_const_ptr_t;
117 public:
118 typedef interleaved_ptr<channel_const_ptr_t,Layout> type;
119 };
120
121 template <typename ChannelPtr, typename Layout>
122 struct iterator_is_mutable<interleaved_ptr<ChannelPtr,Layout> > : public boost::mpl::true_ {};
123 template <typename Channel, typename Layout>
124 struct iterator_is_mutable<interleaved_ptr<const Channel*,Layout> > : public boost::mpl::false_ {};
125
126 template <typename ChannelPtr, typename Layout>
127 struct is_iterator_adaptor<interleaved_ptr<ChannelPtr,Layout> > : public boost::mpl::false_ {};
128
129 /////////////////////////////
130 // PixelBasedConcept
131 /////////////////////////////
132
133 template <typename ChannelPtr, typename Layout>
134 struct color_space_type<interleaved_ptr<ChannelPtr,Layout> > {
135 typedef typename Layout::color_space_t type;
136 };
137
138 template <typename ChannelPtr, typename Layout>
139 struct channel_mapping_type<interleaved_ptr<ChannelPtr,Layout> > {
140 typedef typename Layout::channel_mapping_t type;
141 };
142
143 template <typename ChannelPtr, typename Layout>
144 struct is_planar<interleaved_ptr<ChannelPtr,Layout> > : public mpl::false_ {};
145
146 /////////////////////////////
147 // HomogeneousPixelBasedConcept
148 /////////////////////////////
149
150 template <typename ChannelPtr, typename Layout>
151 struct channel_type<interleaved_ptr<ChannelPtr,Layout> > {
152 typedef typename std::iterator_traits<ChannelPtr>::value_type type;
153 };
154
155 /////////////////////////////
156 // ByteAdvanceableConcept
157 /////////////////////////////
158
159 template <typename ChannelPtr, typename Layout>
160 inline std::ptrdiff_t memunit_step(const interleaved_ptr<ChannelPtr,Layout>&) {
161 return sizeof(typename std::iterator_traits<ChannelPtr>::value_type)* // size of each channel in bytes
162 interleaved_ptr<ChannelPtr,Layout>::num_channels; // times the number of channels
163 }
164
165 template <typename ChannelPtr, typename Layout>
166 inline std::ptrdiff_t memunit_distance(const interleaved_ptr<ChannelPtr,Layout>& p1, const interleaved_ptr<ChannelPtr,Layout>& p2) {
167 return memunit_distance(p1.channels(),p2.channels());
168 }
169
170 template <typename ChannelPtr, typename Layout>
171 inline void memunit_advance(interleaved_ptr<ChannelPtr,Layout>& p, std::ptrdiff_t diff) {
172 memunit_advance(p.channels(), diff);
173 }
174
175 template <typename ChannelPtr, typename Layout>
176 inline interleaved_ptr<ChannelPtr,Layout> memunit_advanced(const interleaved_ptr<ChannelPtr,Layout>& p, std::ptrdiff_t diff) {
177 interleaved_ptr<ChannelPtr,Layout> ret=p;
178 memunit_advance(ret, diff);
179 return ret;
180 }
181
182 template <typename ChannelPtr, typename Layout>
183 inline typename interleaved_ptr<ChannelPtr,Layout>::reference memunit_advanced_ref(const interleaved_ptr<ChannelPtr,Layout>& p, std::ptrdiff_t diff) {
184 interleaved_ptr<ChannelPtr,Layout> ret=p;
185 memunit_advance(ret, diff);
186 return *ret;
187 }
188
189 /////////////////////////////
190 // HasDynamicXStepTypeConcept
191 /////////////////////////////
192
193 template <typename ChannelPtr, typename Layout>
194 struct dynamic_x_step_type<interleaved_ptr<ChannelPtr,Layout> > {
195 typedef memory_based_step_iterator<interleaved_ptr<ChannelPtr,Layout> > type;
196 };
197
198 } } // namespace boost::gil
199
200 #endif