File: interleaved_ref.hpp

package info (click to toggle)
boost1.90 1.90.0-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 593,156 kB
  • sloc: cpp: 4,190,642; xml: 196,648; python: 34,618; ansic: 23,145; asm: 5,468; sh: 3,776; makefile: 1,161; perl: 1,020; sql: 728; ruby: 676; yacc: 478; java: 77; lisp: 24; csh: 6
file content (159 lines) | stat: -rw-r--r-- 6,369 bytes parent folder | download | duplicates (8)
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
//
// Copyright 2005-2007 Adobe Systems Incorporated
//
// Distributed under 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
//

#ifndef BOOST_GIL_EXAMPLE_INTERLEAVED_REF_HPP
#define BOOST_GIL_EXAMPLE_INTERLEAVED_REF_HPP

#include <boost/gil.hpp>
#include <boost/gil/extension/dynamic_image/dynamic_image_all.hpp>

#include <type_traits>

// Example on how to create a new model of a pixel reference

namespace boost { namespace gil {

// A model of an interleaved pixel reference. Holds a pointer to the first channel
// MODELS:
//    MutableHomogeneousPixelConcept
//       MutableHomogeneousColorBaseConcept
//           MutableColorBaseConcept
//           HomogeneousColorBaseConcept
//               ColorBaseConcept
//    HomogeneousPixelBasedConcept
//       PixelBasedConcept
//
// For planar reference proxies to work properly, all of their methods must be const-qualified
// and their iterator's reference type must be const-qualified.
// Mutability of the reference proxy is part of its type (in this case, depends on the mutability of ChannelReference)

/// \tparam ChannelReference - Models ChannelConcept.
///         A channel reference, unsigned char& or const unsigned char&
/// \tparam Layout - A layout (includes the color space and channel ordering)
template <typename ChannelReference, typename Layout>
struct interleaved_ref
{
private:
    using channel_t = typename channel_traits<ChannelReference>::value_type;
    using channel_pointer_t = typename channel_traits<ChannelReference>::pointer;
    using channel_reference_t = typename channel_traits<ChannelReference>::reference;
    using channel_const_reference_t = typename channel_traits<ChannelReference>::const_reference;

public:
    using layout_t = Layout; // Required by ColorBaseConcept

    // Copy construction from a compatible type. The copy constructor of references is shallow. The channels themselves are not copied.
    interleaved_ref(const interleaved_ref& p) : _channels(p._channels) {}
    template <typename P> interleaved_ref(const P& p) : _channels(p._channels) { check_compatible<P>(); }

    template <typename P> bool operator==(const P& p)    const { check_compatible<P>(); return static_equal(*this,p); }
    template <typename P> bool operator!=(const P& p)    const { return !(*this==p); }

// Required by MutableColorBaseConcept

    // Assignment from a compatible type
    const interleaved_ref&  operator=(const interleaved_ref& p)  const { static_copy(p,*this); return *this; }
    template <typename P> const interleaved_ref& operator=(const P& p) const { check_compatible<P>(); static_copy(p,*this); return *this; }

// Required by PixelConcept
    using value_type = pixel<channel_t, layout_t>;
    using reference = interleaved_ref;
    using const_reference = interleaved_ref<channel_const_reference_t, layout_t>;
    static const bool is_mutable = channel_traits<ChannelReference>::is_mutable;

// Required by HomogeneousPixelConcept
    ChannelReference                   operator[](std::size_t i) const { return _channels[i]; }

// Custom constructor (not part of any concept)
    explicit interleaved_ref(channel_pointer_t channels) : _channels(channels) {}
// This is needed for the reference proxy to work properly
    const interleaved_ref*             operator->()              const { return this; }
private:
    channel_pointer_t _channels;

    template <typename Pixel> static void check_compatible() { gil_function_requires<PixelsCompatibleConcept<Pixel,interleaved_ref>>(); }
};

// Required by ColorBaseConcept
template <typename ChannelReference, typename Layout, int K>
struct kth_element_type<interleaved_ref<ChannelReference, Layout>, K>
{
    using type = ChannelReference;
};

template <typename ChannelReference, typename Layout, int K>
struct kth_element_reference_type<interleaved_ref<ChannelReference, Layout>, K>
{
    using type = ChannelReference;
};

template <typename ChannelReference, typename Layout, int K>
struct kth_element_const_reference_type<interleaved_ref<ChannelReference, Layout>, K>
{
    using type = ChannelReference;
    // XXX: using type = typename channel_traits<ChannelReference>::const_reference;
};

// Required by ColorBaseConcept
template <int K, typename ChannelReference, typename Layout>
typename element_reference_type<interleaved_ref<ChannelReference,Layout>>::type
at_c(const interleaved_ref<ChannelReference,Layout>& p) { return p[K]; };

// Required by HomogeneousColorBaseConcept
template <typename ChannelReference, typename Layout>
typename element_reference_type<interleaved_ref<ChannelReference,Layout>>::type
dynamic_at_c(const interleaved_ref<ChannelReference,Layout>& p, std::size_t n) { return p[n]; };

namespace detail {
    struct swap_fn_t {
        template <typename T> void operator()(T& x, T& y) const {
            using std::swap;
            swap(x,y);
        }
    };
}

// Required by MutableColorBaseConcept. The default std::swap does not do the right thing for proxy references - it swaps the references, not the values
template <typename ChannelReference, typename Layout>
void swap(const interleaved_ref<ChannelReference,Layout>& x, const interleaved_ref<ChannelReference,Layout>& y) {
    static_for_each(x,y,detail::swap_fn_t());
};

// Required by PixelConcept
template <typename ChannelReference, typename Layout>
struct is_pixel<interleaved_ref<ChannelReference,Layout>> : public std::true_type {};


// Required by PixelBasedConcept
template <typename ChannelReference, typename Layout>
struct color_space_type<interleaved_ref<ChannelReference, Layout>>
{
    using type = typename Layout::color_space_t;
};

// Required by PixelBasedConcept
template <typename ChannelReference, typename Layout>
struct channel_mapping_type<interleaved_ref<ChannelReference, Layout>>
{
    using type = typename Layout::channel_mapping_t;
};

// Required by PixelBasedConcept
template <typename ChannelReference, typename Layout>
struct is_planar<interleaved_ref<ChannelReference,Layout>> : std::false_type {};

// Required by HomogeneousPixelBasedConcept
template <typename ChannelReference, typename Layout>
struct channel_type<interleaved_ref<ChannelReference, Layout>>
{
    using type = typename channel_traits<ChannelReference>::value_type;
};

} }  // namespace boost::gil

#endif