File: interleaved_ptr.hpp

package info (click to toggle)
boost1.35 1.35.0-5
  • links: PTS
  • area: main
  • in suites: lenny
  • size: 203,856 kB
  • ctags: 337,867
  • sloc: cpp: 938,683; xml: 56,847; ansic: 41,589; python: 18,999; sh: 11,566; makefile: 664; perl: 494; yacc: 456; asm: 353; csh: 6
file content (200 lines) | stat: -rw-r--r-- 8,980 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
/*
    Copyright 2005-2007 Adobe Systems Incorporated
   
    Use, modification and distribution are subject to the Boost Software License,
    Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
    http://www.boost.org/LICENSE_1_0.txt).

    See http://opensource.adobe.com/gil for most recent version including documentation.
*/

/*************************************************************************************************/

////////////////////////////////////////////////////////////////////////////////////////
/// \file               
/// \brief Example on how to create a pixel iterator
/// \author Lubomir Bourdev and Hailin Jin \n
///         Adobe Systems Incorporated
/// \date 2005-2007 \n Last updated on February 26, 2007
///
/// Definitions of standard GIL channel models
///
////////////////////////////////////////////////////////////////////////////////////////

#ifndef GIL_INTERLEAVED_PTR_HPP
#define GIL_INTERLEAVED_PTR_HPP

#include <boost/gil/pixel_iterator.hpp>
#include "interleaved_ref.hpp"

namespace boost { namespace gil {

/////////////////////////////////////////////////////////////////////////
///
/// A model of an interleaved pixel iterator. Contains an iterator to the first channel of the current pixel
///
/// Models: 
///     MutablePixelIteratorConcept
///        PixelIteratorConcept
///           boost_concepts::RandomAccessTraversalConcept
///           PixelBasedConcept
///     HomogeneousPixelBasedConcept
///        PixelBasedConcept
///     ByteAdvanceableConcept
///     HasDynamicXStepTypeConcept
///
/////////////////////////////////////////////////////////////////////////

template <typename ChannelPtr,  // Models Channel Iterator (examples: unsigned char* or const unsigned char*)
          typename Layout>      // A layout (includes the color space and channel ordering)
struct interleaved_ptr : public  boost::iterator_facade<interleaved_ptr<ChannelPtr,Layout>,
                                   pixel<typename std::iterator_traits<ChannelPtr>::value_type,Layout>,
                                   boost::random_access_traversal_tag,
                                   const interleaved_ref<typename std::iterator_traits<ChannelPtr>::reference,Layout> >
{
private:
    typedef boost::iterator_facade<interleaved_ptr<ChannelPtr,Layout>,
                                   pixel<typename std::iterator_traits<ChannelPtr>::value_type,Layout>,
                                   boost::random_access_traversal_tag,
                                   const interleaved_ref<typename std::iterator_traits<ChannelPtr>::reference,Layout> > parent_t;
    typedef typename std::iterator_traits<ChannelPtr>::value_type channel_t;
public:
    typedef typename parent_t::reference                  reference;
    typedef typename parent_t::difference_type            difference_type;

    interleaved_ptr() {}
    interleaved_ptr(const interleaved_ptr& ptr) : _channels(ptr._channels) {}
    template <typename CP> interleaved_ptr(const interleaved_ptr<CP,Layout>& ptr) : _channels(ptr._channels) {}

    interleaved_ptr(const ChannelPtr& channels) : _channels(channels) {}

    // Construct from a pointer to the reference type. Not required by concepts but important
    interleaved_ptr(reference* pix) : _channels(&((*pix)[0])) {}
    interleaved_ptr& operator=(reference* pix) { _channels=&((*pix)[0]); return *this; }

    /// For some reason operator[] provided by boost::iterator_facade returns a custom class that is convertible to reference
    /// We require our own reference because it is registered in iterator_traits
    reference operator[](difference_type d) const { return memunit_advanced_ref(*this,d*sizeof(channel_t));}

    // Put this for every iterator whose reference is a proxy type
    reference operator->()                  const { return **this; }

    // Channels accessor (not required by any concept)
    const ChannelPtr& channels()            const { return _channels; }
          ChannelPtr& channels()                  { return _channels; }
    
    // Not required by concepts but useful
    static const std::size_t num_channels = mpl::size<typename Layout::color_space_t>::value;
private:
    ChannelPtr _channels;
    friend class boost::iterator_core_access;
    template <typename CP, typename L> friend struct interleaved_ptr;

    void increment()            { _channels+=num_channels; }
    void decrement()            { _channels-=num_channels; }
    void advance(ptrdiff_t d)   { _channels+=num_channels*d; }

    ptrdiff_t distance_to(const interleaved_ptr& it) const { return (it._channels-_channels)/num_channels; }
    bool equal(const interleaved_ptr& it) const { return _channels==it._channels; }

    reference dereference() const { return reference(_channels); }
};

/////////////////////////////
//  PixelIteratorConcept
/////////////////////////////

// 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
// 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
// iterator_traits::value_type. This is because sometimes multiple reference and pointer types share the same value type. An example of this is
// GIL's planar reference and iterator ("planar_pixel_reference" and "planar_pixel_iterator") which share the class "pixel" as the value_type. The
// class "pixel" is also the value type for interleaved pixel references. Here we are dealing with channels, not pixels, but the principles still apply.
template <typename ChannelPtr, typename Layout>
struct const_iterator_type<interleaved_ptr<ChannelPtr,Layout> > { 
private:
    typedef typename std::iterator_traits<ChannelPtr>::reference channel_ref_t;
    typedef typename channel_traits<channel_ref_t>::const_pointer channel_const_ptr_t;
public:
    typedef interleaved_ptr<channel_const_ptr_t,Layout> type; 
};

template <typename ChannelPtr, typename Layout>
struct iterator_is_mutable<interleaved_ptr<ChannelPtr,Layout> > : public boost::mpl::true_ {};
template <typename Channel, typename Layout>
struct iterator_is_mutable<interleaved_ptr<const Channel*,Layout> > : public boost::mpl::false_ {};

template <typename ChannelPtr, typename Layout>
struct is_iterator_adaptor<interleaved_ptr<ChannelPtr,Layout> > : public boost::mpl::false_ {};

/////////////////////////////
//  PixelBasedConcept
/////////////////////////////

template <typename ChannelPtr, typename Layout>
struct color_space_type<interleaved_ptr<ChannelPtr,Layout> > {
    typedef typename Layout::color_space_t type;
};

template <typename ChannelPtr, typename Layout>
struct channel_mapping_type<interleaved_ptr<ChannelPtr,Layout> > {
    typedef typename Layout::channel_mapping_t type;
};

template <typename ChannelPtr, typename Layout>
struct is_planar<interleaved_ptr<ChannelPtr,Layout> > : public mpl::false_ {};

/////////////////////////////
//  HomogeneousPixelBasedConcept
/////////////////////////////

template <typename ChannelPtr, typename Layout>
struct channel_type<interleaved_ptr<ChannelPtr,Layout> > {
    typedef typename std::iterator_traits<ChannelPtr>::value_type type;
};

/////////////////////////////
//  ByteAdvanceableConcept
/////////////////////////////

template <typename ChannelPtr, typename Layout>
inline std::ptrdiff_t memunit_step(const interleaved_ptr<ChannelPtr,Layout>&) { 
    return sizeof(typename std::iterator_traits<ChannelPtr>::value_type)*   // size of each channel in bytes
           interleaved_ptr<ChannelPtr,Layout>::num_channels;                // times the number of channels
}

template <typename ChannelPtr, typename Layout>
inline std::ptrdiff_t memunit_distance(const interleaved_ptr<ChannelPtr,Layout>& p1, const interleaved_ptr<ChannelPtr,Layout>& p2) { 
    return memunit_distance(p1.channels(),p2.channels()); 
}

template <typename ChannelPtr, typename Layout>
inline void memunit_advance(interleaved_ptr<ChannelPtr,Layout>& p, std::ptrdiff_t diff) { 
    memunit_advance(p.channels(), diff);
}

template <typename ChannelPtr, typename Layout>
inline interleaved_ptr<ChannelPtr,Layout> memunit_advanced(const interleaved_ptr<ChannelPtr,Layout>& p, std::ptrdiff_t diff) {
    interleaved_ptr<ChannelPtr,Layout> ret=p;
    memunit_advance(ret, diff);
    return ret;
}

template <typename ChannelPtr, typename Layout>
inline typename interleaved_ptr<ChannelPtr,Layout>::reference memunit_advanced_ref(const interleaved_ptr<ChannelPtr,Layout>& p, std::ptrdiff_t diff) {
    interleaved_ptr<ChannelPtr,Layout> ret=p;
    memunit_advance(ret, diff);
    return *ret;
}

/////////////////////////////
//  HasDynamicXStepTypeConcept
/////////////////////////////

template <typename ChannelPtr, typename Layout>
struct dynamic_x_step_type<interleaved_ptr<ChannelPtr,Layout> > {
    typedef memory_based_step_iterator<interleaved_ptr<ChannelPtr,Layout> > type;
};

} }  // namespace boost::gil

#endif