1//
2// Copyright 2005-2007 Adobe Systems Incorporated
3//
4// Distributed under the Boost Software License, Version 1.0
5// See accompanying file LICENSE_1_0.txt or copy at
6// http://www.boost.org/LICENSE_1_0.txt
7//
8
9#ifndef BOOST_GIL_EXAMPLE_INTERLEAVED_REF_HPP
10#define BOOST_GIL_EXAMPLE_INTERLEAVED_REF_HPP
11
12#include <boost/gil.hpp>
13#include <boost/gil/extension/dynamic_image/dynamic_image_all.hpp>
14
15#include <type_traits>
16
17// Example on how to create a new model of a pixel reference
18
19namespace boost { namespace gil {
20
21// A model of an interleaved pixel reference. Holds a pointer to the first channel
22// MODELS:
23// MutableHomogeneousPixelConcept
24// MutableHomogeneousColorBaseConcept
25// MutableColorBaseConcept
26// HomogeneousColorBaseConcept
27// ColorBaseConcept
28// HomogeneousPixelBasedConcept
29// PixelBasedConcept
30//
31// For planar reference proxies to work properly, all of their methods must be const-qualified
32// and their iterator's reference type must be const-qualified.
33// Mutability of the reference proxy is part of its type (in this case, depends on the mutability of ChannelReference)
34
35/// \tparam ChannelReference - Models ChannelConcept.
36/// A channel reference, unsigned char& or const unsigned char&
37/// \tparam Layout - A layout (includes the color space and channel ordering)
38template <typename ChannelReference, typename Layout>
39struct interleaved_ref
40{
41private:
42 using channel_t = typename channel_traits<ChannelReference>::value_type;
43 using channel_pointer_t = typename channel_traits<ChannelReference>::pointer;
44 using channel_reference_t = typename channel_traits<ChannelReference>::reference;
45 using channel_const_reference_t = typename channel_traits<ChannelReference>::const_reference;
46
47public:
48 using layout_t = Layout; // Required by ColorBaseConcept
49
50 // Copy construction from a compatible type. The copy constructor of references is shallow. The channels themselves are not copied.
51 interleaved_ref(const interleaved_ref& p) : _channels(p._channels) {}
52 template <typename P> interleaved_ref(const P& p) : _channels(p._channels) { check_compatible<P>(); }
53
54 template <typename P> bool operator==(const P& p) const { check_compatible<P>(); return static_equal(*this,p); }
55 template <typename P> bool operator!=(const P& p) const { return !(*this==p); }
56
57// Required by MutableColorBaseConcept
58
59 // Assignment from a compatible type
60 const interleaved_ref& operator=(const interleaved_ref& p) const { static_copy(p,*this); return *this; }
61 template <typename P> const interleaved_ref& operator=(const P& p) const { check_compatible<P>(); static_copy(p,*this); return *this; }
62
63// Required by PixelConcept
64 using value_type = pixel<channel_t, layout_t>;
65 using reference = interleaved_ref;
66 using const_reference = interleaved_ref<channel_const_reference_t, layout_t>;
67 static const bool is_mutable = channel_traits<ChannelReference>::is_mutable;
68
69// Required by HomogeneousPixelConcept
70 ChannelReference operator[](std::size_t i) const { return _channels[i]; }
71
72// Custom constructor (not part of any concept)
73 explicit interleaved_ref(channel_pointer_t channels) : _channels(channels) {}
74// This is needed for the reference proxy to work properly
75 const interleaved_ref* operator->() const { return this; }
76private:
77 channel_pointer_t _channels;
78
79 template <typename Pixel> static void check_compatible() { gil_function_requires<PixelsCompatibleConcept<Pixel,interleaved_ref>>(); }
80};
81
82// Required by ColorBaseConcept
83template <typename ChannelReference, typename Layout, int K>
84struct kth_element_type<interleaved_ref<ChannelReference, Layout>, K>
85{
86 using type = ChannelReference;
87};
88
89template <typename ChannelReference, typename Layout, int K>
90struct kth_element_reference_type<interleaved_ref<ChannelReference, Layout>, K>
91{
92 using type = ChannelReference;
93};
94
95template <typename ChannelReference, typename Layout, int K>
96struct kth_element_const_reference_type<interleaved_ref<ChannelReference, Layout>, K>
97{
98 using type = ChannelReference;
99 // XXX: using type = typename channel_traits<ChannelReference>::const_reference;
100};
101
102// Required by ColorBaseConcept
103template <int K, typename ChannelReference, typename Layout>
104typename element_reference_type<interleaved_ref<ChannelReference,Layout>>::type
105at_c(const interleaved_ref<ChannelReference,Layout>& p) { return p[K]; };
106
107// Required by HomogeneousColorBaseConcept
108template <typename ChannelReference, typename Layout>
109typename element_reference_type<interleaved_ref<ChannelReference,Layout>>::type
110dynamic_at_c(const interleaved_ref<ChannelReference,Layout>& p, std::size_t n) { return p[n]; };
111
112namespace detail {
113 struct swap_fn_t {
114 template <typename T> void operator()(T& x, T& y) const {
115 using std::swap;
116 swap(x,y);
117 }
118 };
119}
120
121// Required by MutableColorBaseConcept. The default std::swap does not do the right thing for proxy references - it swaps the references, not the values
122template <typename ChannelReference, typename Layout>
123void swap(const interleaved_ref<ChannelReference,Layout>& x, const interleaved_ref<ChannelReference,Layout>& y) {
124 static_for_each(x,y,detail::swap_fn_t());
125};
126
127// Required by PixelConcept
128template <typename ChannelReference, typename Layout>
129struct is_pixel<interleaved_ref<ChannelReference,Layout>> : public std::true_type {};
130
131
132// Required by PixelBasedConcept
133template <typename ChannelReference, typename Layout>
134struct color_space_type<interleaved_ref<ChannelReference, Layout>>
135{
136 using type = typename Layout::color_space_t;
137};
138
139// Required by PixelBasedConcept
140template <typename ChannelReference, typename Layout>
141struct channel_mapping_type<interleaved_ref<ChannelReference, Layout>>
142{
143 using type = typename Layout::channel_mapping_t;
144};
145
146// Required by PixelBasedConcept
147template <typename ChannelReference, typename Layout>
148struct is_planar<interleaved_ref<ChannelReference,Layout>> : std::false_type {};
149
150// Required by HomogeneousPixelBasedConcept
151template <typename ChannelReference, typename Layout>
152struct channel_type<interleaved_ref<ChannelReference, Layout>>
153{
154 using type = typename channel_traits<ChannelReference>::value_type;
155};
156
157} } // namespace boost::gil
158
159#endif
160

source code of boost/libs/gil/example/interleaved_ref.hpp