• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_CORE_CHANNEL_TEST_FIXTURE_HPP
10 #define BOOST_GIL_TEST_CORE_CHANNEL_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 #include "test_utility_output_stream.hpp"
21 
22 namespace boost { namespace gil { namespace test { namespace fixture {
23 
24 using channel_byte_types = std::tuple
25     <
26         std::uint8_t,
27         std::int8_t,
28         std::uint16_t,
29         std::int16_t,
30         std::uint32_t,
31         std::int32_t,
32         gil::float32_t,
33         gil::float64_t
34     >;
35 
36 using channel_integer_types = std::tuple
37     <
38         std::uint8_t,
39         std::int8_t,
40         std::uint16_t,
41         std::int16_t,
42         std::uint32_t,
43         std::int32_t
44     >;
45 
46 using channel_integer_signed_types = std::tuple
47     <
48         std::int8_t,
49         std::int16_t,
50         std::int32_t
51     >;
52 
53 using channel_integer_unsigned_types = std::tuple
54     <
55         std::uint8_t,
56         std::uint16_t,
57         std::uint32_t
58     >;
59 
60 // FIXME: If float types are convertible between each other,
61 // currently they are not, then move to channel_byte_types and
62 // remove channel_integer_types as redundant.
63 using channel_float_types = std::tuple
64     <
65         gil::float32_t,
66         gil::float64_t
67     >;
68 
69 using channel_bitfield_types = std::tuple
70     <
71         std::uint16_t,
72         std::uint32_t,
73         std::uint64_t
74         // TODO: Shall we test signed types for unexpected conversions, etc.?
75     >;
76 
77 
78 template <typename ChannelValue>
79 struct channel_minmax_value
80 {
81     //static_assert(std::)
82     ChannelValue min_v_;
83     ChannelValue max_v_;
channel_minmax_valueboost::gil::test::fixture::channel_minmax_value84     channel_minmax_value()
85         : min_v_(gil::channel_traits<ChannelValue>::min_value())
86         , max_v_(gil::channel_traits<ChannelValue>::max_value())
87     {}
88 };
89 
90 template <typename ChannelFixtureBase>
91 struct channel : public ChannelFixtureBase
92 {
93     using channel_t = typename ChannelFixtureBase::channel_t;
94     using channel_value_t = typename gil::channel_traits<channel_t>::value_type;
95 
channelboost::gil::test::fixture::channel96     channel()
97     {
98         BOOST_TEST_EQ(this->min_v_, gil::channel_traits<channel_t>::min_value());
99         BOOST_TEST_EQ(this->max_v_, gil::channel_traits<channel_t>::max_value());
100     }
101 };
102 
103 // The channel fixtures are defined for different types of channels
104 // (ie. channel values, references and subbyte references)
105 // ensure there are two members, min_v_ and max_v_ initialized
106 // with the minimum and maximum channel value.
107 // The different channel types have different ways to initialize them,
108 // thus require different fixtures provided.
109 
110 // For basic channel types values can be initialized directly.
111 template <typename ChannelValue>
112 struct channel_value
113 {
114     using channel_t = ChannelValue;
115     channel_t min_v_;
116     channel_t max_v_;
117 
channel_valueboost::gil::test::fixture::channel_value118     channel_value()
119         : min_v_(gil::channel_traits<ChannelValue>::min_value())
120         , max_v_(gil::channel_traits<ChannelValue>::max_value())
121     {
122         boost::function_requires<gil::ChannelValueConcept<ChannelValue>>();
123     }
124 };
125 
126 // For channel references we need to have separate channel values.
127 template <typename ChannelRef>
128 struct channel_reference
129     : public channel_value<typename gil::channel_traits<ChannelRef>::value_type>
130 {
131     using parent_t = channel_value<typename gil::channel_traits<ChannelRef>::value_type>;
132     using channel_t = ChannelRef;
133     channel_t min_v_;
134     channel_t max_v_;
135 
channel_referenceboost::gil::test::fixture::channel_reference136     channel_reference()
137         : parent_t()
138         , min_v_(parent_t::min_v_)
139         , max_v_(parent_t::max_v_)
140     {
141         boost::function_requires<ChannelConcept<ChannelRef>>();
142     }
143 };
144 
145 // For sub-byte channel references we need to store the bit buffers somewhere
146 template <typename ChannelSubbyteRef, typename ChannelMutableRef = ChannelSubbyteRef>
147 struct packed_channel_reference
148 {
149     using channel_t = ChannelSubbyteRef;
150     using integer_t = typename channel_t::integer_t;
151     channel_t min_v_;
152     channel_t max_v_;
153     integer_t min_bitbuf_;
154     integer_t max_bitbuf_;
155 
packed_channel_referenceboost::gil::test::fixture::packed_channel_reference156     packed_channel_reference() : min_v_(&min_bitbuf_), max_v_(&max_bitbuf_)
157     {
158         boost::function_requires<ChannelConcept<ChannelSubbyteRef>>();
159 
160         ChannelMutableRef b1(&min_bitbuf_);
161         b1 = gil::channel_traits<channel_t>::min_value();
162         ChannelMutableRef b2(&max_bitbuf_);
163         b2 = gil::channel_traits<channel_t>::max_value();
164     }
165 };
166 
167 // For sub-byte channel references we need to store the bit buffers somewhere
168 template <typename ChannelSubbyteRef, typename ChannelMutableRef = ChannelSubbyteRef>
169 struct packed_dynamic_channel_reference
170 {
171     using channel_t = ChannelSubbyteRef;
172     using integer_t = typename channel_t::integer_t;
173     channel_t min_v_;
174     channel_t max_v_;
175     integer_t min_bitbuf_;
176     integer_t max_bitbuf_;
177 
packed_dynamic_channel_referenceboost::gil::test::fixture::packed_dynamic_channel_reference178     packed_dynamic_channel_reference(int first_bit1 = 1, int first_bit2 = 2)
179         : min_v_(&min_bitbuf_, first_bit1)
180         , max_v_(&max_bitbuf_, first_bit2)
181     {
182         boost::function_requires<ChannelConcept<ChannelSubbyteRef>>();
183 
184         ChannelMutableRef b1(&min_bitbuf_, 1);
185         b1 = gil::channel_traits<channel_t>::min_value();
186         ChannelMutableRef b2(&max_bitbuf_, 2);
187         b2 = gil::channel_traits<channel_t>::max_value();
188     }
189 };
190 
191 // Concrete fixture for 16-bit pack of 5,6,5-bit channels
192 template <typename BitField>
193 struct packed_channels565
194 {
195     static_assert(sizeof(BitField) >= sizeof(std::uint16_t), "16-bit or more required");
196     using channel_0_5_t = gil::packed_channel_reference<BitField, 0, 5,true>;
197     using channel_5_6_t = gil::packed_channel_reference<BitField, 5, 6,true>;
198     using channel_11_5_t = gil::packed_channel_reference<BitField, 11, 5,true>;
199 
200     using fixture_0_5_t = fixture::packed_channel_reference<channel_0_5_t>;
201     using fixture_5_6_t = fixture::packed_channel_reference<channel_5_6_t>;
202     using fixture_11_5_t = fixture::packed_channel_reference<channel_11_5_t>;
203 
204     std::uint16_t data_ = 0;
205     channel_0_5_t channel1_;
206     channel_5_6_t channel2_;
207     channel_11_5_t channel3_;
208 
packed_channels565boost::gil::test::fixture::packed_channels565209     packed_channels565() : channel1_(&data_), channel2_(&data_), channel3_(&data_)
210     {
211         channel1_ = gil::channel_traits<channel_0_5_t>::max_value();
212         channel2_ = gil::channel_traits<channel_5_6_t>::max_value();
213         channel3_ = gil::channel_traits<channel_11_5_t>::max_value();
214 #ifdef BOOST_TEST_EQ
215         BOOST_TEST_EQ(data_, 65535);
216 #endif
217     }
218 };
219 
220 // Concrete fixture for dynamically-referenced 16-bit pack of 5,6,5-bit channels
221 template <typename BitField>
222 struct packed_dynamic_channels565
223 {
224     static_assert(sizeof(BitField) >= sizeof(std::uint16_t), "16-bit or more required");
225     using channel_5_t = gil::packed_dynamic_channel_reference<BitField,5,true>;
226     using channel_6_t = gil::packed_dynamic_channel_reference<BitField,6,true>;
227 
228     using fixture_5_t = fixture::packed_dynamic_channel_reference<channel_5_t>;
229     using fixture_6_t = fixture::packed_dynamic_channel_reference<channel_6_t>;
230 
231     std::uint16_t data_ = 0;
232     channel_5_t channel1_;
233     channel_6_t channel2_;
234     channel_5_t channel3_;
235 
packed_dynamic_channels565boost::gil::test::fixture::packed_dynamic_channels565236     packed_dynamic_channels565()
237         : channel1_(&data_, 0)
238         , channel2_(&data_, 5)
239         , channel3_(&data_, 11)
240     {
241         channel1_ = gil::channel_traits<channel_5_t>::max_value();
242         channel2_ = gil::channel_traits<channel_6_t>::max_value();
243         channel3_ = gil::channel_traits<channel_5_t>::max_value();
244 #ifdef BOOST_TEST_EQ
245         BOOST_TEST_EQ(data_, 65535);
246 #endif
247     }
248 };
249 
250 }}}} // namespace boost::gil::test::fixture
251 
252 #endif
253