Imported Upstream version 1.71.0
[platform/upstream/boost.git] / libs / gil / test / channel / test_fixture.hpp
1 //
2 // Copyright 2005-2007 Adobe Systems Incorporated
3 // Copyright 2018 Mateusz Loskot <mateusz at loskot dot net>
4 //
5 // Distributed under the Boost Software License, Version 1.0
6 // See accompanying file LICENSE_1_0.txt or copy at
7 // http://www.boost.org/LICENSE_1_0.txt
8 //
9 #ifndef BOOST_GIL_TEST_TEST_FIXTURE_HPP
10 #define BOOST_GIL_TEST_TEST_FIXTURE_HPP
11
12 #include <boost/gil/channel.hpp>
13 #include <boost/gil/concepts.hpp>
14 #include <boost/gil/typedefs.hpp>
15
16 #include <cstdint>
17 #include <tuple>
18 #include <type_traits>
19
20 namespace boost { namespace gil { namespace test { namespace fixture {
21
22 using channel_byte_types = std::tuple
23     <
24         std::uint8_t,
25         std::int8_t,
26         std::uint16_t,
27         std::int16_t,
28         std::uint32_t,
29         std::int32_t,
30         gil::float32_t,
31         gil::float64_t
32     >;
33
34 using channel_integer_types = std::tuple
35     <
36         std::uint8_t,
37         std::int8_t,
38         std::uint16_t,
39         std::int16_t,
40         std::uint32_t,
41         std::int32_t
42     >;
43
44 // FIXME: If float types are convertible between each other,
45 // currently they are not, then move to channel_byte_types and
46 // remove channel_integer_types as redundant.
47 using channel_float_types = std::tuple
48     <
49         gil::float32_t,
50         gil::float64_t
51     >;
52
53 using channel_bitfield_types = std::tuple
54     <
55         std::uint16_t,
56         std::uint32_t,
57         std::uint64_t
58         // TODO: Shall we test signed types for unexpected conversions, etc.?
59     >;
60
61
62 template <typename ChannelValue>
63 struct channel_minmax_value
64 {
65     //static_assert(std::)
66     ChannelValue min_v_;
67     ChannelValue max_v_;
68     channel_minmax_value()
69         : min_v_(gil::channel_traits<ChannelValue>::min_value())
70         , max_v_(gil::channel_traits<ChannelValue>::max_value())
71     {}
72 };
73
74 template <typename ChannelFixtureBase>
75 struct channel : public ChannelFixtureBase
76 {
77     using channel_t = typename ChannelFixtureBase::channel_t;
78     using channel_value_t = typename gil::channel_traits<channel_t>::value_type;
79
80     channel()
81     {
82         BOOST_TEST(this->min_v_ == gil::channel_traits<channel_t>::min_value());
83         BOOST_TEST(this->max_v_ == gil::channel_traits<channel_t>::max_value());
84     }
85 };
86
87 // The channel fixtures are defined for different types of channels
88 // (ie. channel values, references and subbyte references)
89 // ensure there are two members, min_v_ and max_v_ initialized
90 // with the minimum and maximum channel value.
91 // The different channel types have different ways to initialize them,
92 // thus require different fixtures provided.
93
94 // For basic channel types values can be initialized directly.
95 template <typename ChannelValue>
96 struct channel_value
97 {
98     using channel_t = ChannelValue;
99     channel_t min_v_;
100     channel_t max_v_;
101
102     channel_value()
103         : min_v_(gil::channel_traits<ChannelValue>::min_value())
104         , max_v_(gil::channel_traits<ChannelValue>::max_value())
105     {
106         boost::function_requires<gil::ChannelValueConcept<ChannelValue>>();
107     }
108 };
109
110 // For channel references we need to have separate channel values.
111 template <typename ChannelRef>
112 struct channel_reference
113     : public channel_value<typename gil::channel_traits<ChannelRef>::value_type>
114 {
115     using parent_t = channel_value<typename gil::channel_traits<ChannelRef>::value_type>;
116     using channel_t = ChannelRef;
117     channel_t min_v_;
118     channel_t max_v_;
119
120     channel_reference()
121         : parent_t()
122         , min_v_(parent_t::min_v_)
123         , max_v_(parent_t::max_v_)
124     {
125         boost::function_requires<ChannelConcept<ChannelRef>>();
126     }
127 };
128
129 // For sub-byte channel references we need to store the bit buffers somewhere
130 template <typename ChannelSubbyteRef, typename ChannelMutableRef = ChannelSubbyteRef>
131 struct packed_channel_reference
132 {
133     using channel_t = ChannelSubbyteRef;
134     using integer_t = typename channel_t::integer_t;
135     channel_t min_v_;
136     channel_t max_v_;
137     integer_t min_bitbuf_;
138     integer_t max_bitbuf_;
139
140     packed_channel_reference() : min_v_(&min_bitbuf_), max_v_(&max_bitbuf_)
141     {
142         boost::function_requires<ChannelConcept<ChannelSubbyteRef>>();
143
144         ChannelMutableRef b1(&min_bitbuf_);
145         b1 = gil::channel_traits<channel_t>::min_value();
146         ChannelMutableRef b2(&max_bitbuf_);
147         b2 = gil::channel_traits<channel_t>::max_value();
148     }
149 };
150
151 // For sub-byte channel references we need to store the bit buffers somewhere
152 template <typename ChannelSubbyteRef, typename ChannelMutableRef = ChannelSubbyteRef>
153 struct packed_dynamic_channel_reference
154 {
155     using channel_t = ChannelSubbyteRef;
156     using integer_t = typename channel_t::integer_t;
157     channel_t min_v_;
158     channel_t max_v_;
159     integer_t min_bitbuf_;
160     integer_t max_bitbuf_;
161
162     packed_dynamic_channel_reference(int first_bit1 = 1, int first_bit2 = 2)
163         : min_v_(&min_bitbuf_, first_bit1)
164         , max_v_(&max_bitbuf_, first_bit2)
165     {
166         boost::function_requires<ChannelConcept<ChannelSubbyteRef>>();
167
168         ChannelMutableRef b1(&min_bitbuf_, 1);
169         b1 = gil::channel_traits<channel_t>::min_value();
170         ChannelMutableRef b2(&max_bitbuf_, 2);
171         b2 = gil::channel_traits<channel_t>::max_value();
172     }
173 };
174
175 // Concrete fixture for 16-bit pack of 5,6,5-bit channels
176 template <typename BitField>
177 struct packed_channels565
178 {
179     static_assert(sizeof(BitField) >= sizeof(std::uint16_t), "16-bit or more required");
180     using channel_0_5_t = gil::packed_channel_reference<BitField, 0, 5,true>;
181     using channel_5_6_t = gil::packed_channel_reference<BitField, 5, 6,true>;
182     using channel_11_5_t = gil::packed_channel_reference<BitField, 11, 5,true>;
183
184     using fixture_0_5_t = fixture::packed_channel_reference<channel_0_5_t>;
185     using fixture_5_6_t = fixture::packed_channel_reference<channel_5_6_t>;
186     using fixture_11_5_t = fixture::packed_channel_reference<channel_11_5_t>;
187
188     std::uint16_t data_ = 0;
189     channel_0_5_t channel1_;
190     channel_5_6_t channel2_;
191     channel_11_5_t channel3_;
192
193     packed_channels565() : channel1_(&data_), channel2_(&data_), channel3_(&data_)
194     {
195         channel1_ = gil::channel_traits<channel_0_5_t>::max_value();
196         channel2_ = gil::channel_traits<channel_5_6_t>::max_value();
197         channel3_ = gil::channel_traits<channel_11_5_t>::max_value();
198         BOOST_TEST(data_ == 65535);
199     }
200 };
201
202 // Concrete fixture for dynamically-referenced 16-bit pack of 5,6,5-bit channels
203 template <typename BitField>
204 struct packed_dynamic_channels565
205 {
206     static_assert(sizeof(BitField) >= sizeof(std::uint16_t), "16-bit or more required");
207     using channel_5_t = gil::packed_dynamic_channel_reference<BitField,5,true>;
208     using channel_6_t = gil::packed_dynamic_channel_reference<BitField,6,true>;
209
210     using fixture_5_t = fixture::packed_dynamic_channel_reference<channel_5_t>;
211     using fixture_6_t = fixture::packed_dynamic_channel_reference<channel_6_t>;
212
213     std::uint16_t data_ = 0;
214     channel_5_t channel1_;
215     channel_6_t channel2_;
216     channel_5_t channel3_;
217
218     packed_dynamic_channels565()
219         : channel1_(&data_, 0)
220         , channel2_(&data_, 5)
221         , channel3_(&data_, 11)
222     {
223         channel1_ = gil::channel_traits<channel_5_t>::max_value();
224         channel2_ = gil::channel_traits<channel_6_t>::max_value();
225         channel3_ = gil::channel_traits<channel_5_t>::max_value();
226         BOOST_TEST(data_ == 65535);
227     }
228 };
229
230 }}}} // namespace boost::gil::test::fixture
231
232 #endif