• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2019-2020 Mateusz Loskot <mateusz at loskot dot net>
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 #include <boost/gil.hpp>
9 #include <boost/gil/extension/numeric/pixel_numeric_operations.hpp>
10 
11 #include <boost/core/lightweight_test.hpp>
12 
13 #include <tuple>
14 #include <type_traits>
15 
16 #include "test_utility_output_stream.hpp"
17 #include "core/test_fixture.hpp" // random_value
18 #include "core/pixel/test_fixture.hpp"
19 
20 namespace gil = boost::gil;
21 namespace fixture = boost::gil::test::fixture;
22 
23 struct test_plus_integer_same_types
24 {
25     template <typename Pixel>
operator ()test_plus_integer_same_types26     void operator()(Pixel const&)
27     {
28         using pixel_t = Pixel;
29         using channel_t = typename gil::channel_type<pixel_t>::type;
30         gil::pixel_plus_t<pixel_t, pixel_t, pixel_t> f;
31         {
32             pixel_t p0;
33             gil::static_fill(p0, static_cast<channel_t>(0));
34             BOOST_TEST_EQ(f(p0, p0), p0);
35         }
36         {
37             pixel_t p1;
38             gil::static_fill(p1, static_cast<channel_t>(1));
39             pixel_t r2;
40             gil::static_fill(r2, static_cast<channel_t>(2));
41             BOOST_TEST_EQ(f(p1, p1), r2);
42         }
43         {
44             // Generates pixels with consecutive channel values: {1} or {1,2,3} or {1,2,3,4} etc.
45             fixture::consecutive_value<channel_t> g(1);
46             pixel_t p;
47             gil::static_generate(p, [&g]() { return g(); });
48             auto const r = f(p, p);
49             BOOST_TEST_NE(r, p);
50             BOOST_TEST_EQ(gil::at_c<0>(r), (gil::at_c<0>(p) + gil::at_c<0>(p)));
51         }
52     }
runtest_plus_integer_same_types53     static void run()
54     {
55         boost::mp11::mp_for_each<fixture::pixel_integer_types>(test_plus_integer_same_types{});
56     }
57 };
58 
59 struct test_minus_integer_same_types
60 {
61     template <typename Pixel>
operator ()test_minus_integer_same_types62     void operator()(Pixel const&)
63     {
64         using pixel_t = Pixel;
65         using channel_t = typename gil::channel_type<pixel_t>::type;
66         gil::pixel_minus_t<pixel_t, pixel_t, pixel_t> f;
67 
68         pixel_t p0;
69         gil::static_fill(p0, static_cast<channel_t>(0));
70         BOOST_TEST_EQ(f(p0, p0), p0);
71         {
72             pixel_t p1, p2;
73             gil::static_fill(p1, static_cast<channel_t>(1));
74             gil::static_fill(p2, static_cast<channel_t>(2));
75             pixel_t r1;
76             gil::static_fill(r1, static_cast<channel_t>(1));
77             BOOST_TEST_EQ(f(p2, p1), r1);
78         }
79         {
80             // Generates pixels with consecutive channel values: {1} or {1,2,3} or {1,2,3,4} etc.
81             fixture::consecutive_value<channel_t> g(1);
82             pixel_t p;
83             gil::static_generate(p, [&g]() { return g(); });
84             BOOST_TEST_EQ(f(p, p), p0);
85         }
86     }
runtest_minus_integer_same_types87     static void run()
88     {
89         boost::mp11::mp_for_each<fixture::pixel_integer_types>(test_minus_integer_same_types{});
90     }
91 };
92 
93 struct test_pixel_multiplies_scalar_integer_same_types
94 {
95     template <typename Pixel>
operator ()test_pixel_multiplies_scalar_integer_same_types96     void operator()(Pixel const&)
97     {
98         using pixel_t = Pixel;
99         using channel_t = typename gil::channel_type<pixel_t>::type;
100         gil::pixel_multiplies_scalar_t<pixel_t, channel_t, pixel_t> f;
101 
102         pixel_t p0;
103         gil::static_fill(p0, static_cast<channel_t>(0));
104         BOOST_TEST_EQ(f(p0, 0), p0);
105 
106         {
107             pixel_t p1;
108             gil::static_fill(p1, static_cast<channel_t>(1));
109             BOOST_TEST_EQ(f(p1, 0), p0);
110             BOOST_TEST_EQ(f(p1, 1), p1);
111         }
112         {
113             // Generates pixels with consecutive channel values: {1} or {1,2,3} or {1,2,3,4} etc.
114             fixture::consecutive_value<channel_t> g(1);
115             pixel_t p;
116             gil::static_generate(p, [&g]() { return g(); });
117 
118             // check first channel value is doubled
119             auto const r = f(p, 2);
120             BOOST_TEST_NE(r, p);
121             BOOST_TEST_EQ(gil::at_c<0>(r), (gil::at_c<0>(p) * 2));
122         }
123     }
runtest_pixel_multiplies_scalar_integer_same_types124     static void run()
125     {
126         boost::mp11::mp_for_each<fixture::pixel_integer_types>(test_pixel_multiplies_scalar_integer_same_types{});
127     }
128 };
129 
130 struct test_pixel_multiply_integer_same_types
131 {
132     template <typename Pixel>
operator ()test_pixel_multiply_integer_same_types133     void operator()(Pixel const&)
134     {
135         using pixel_t = Pixel;
136         using channel_t = typename gil::channel_type<pixel_t>::type;
137         gil::pixel_multiply_t<pixel_t, pixel_t, pixel_t> f;
138 
139         pixel_t p0;
140         gil::static_fill(p0, static_cast<channel_t>(0));
141         BOOST_TEST_EQ(f(p0, p0), p0);
142 
143         pixel_t p1;
144         gil::static_fill(p1, static_cast<channel_t>(1));
145         BOOST_TEST_EQ(f(p1, p1), p1);
146 
147         pixel_t p2;
148         gil::static_fill(p2, static_cast<channel_t>(2));
149         BOOST_TEST_EQ(f(p1, p2), p2);
150     }
runtest_pixel_multiply_integer_same_types151     static void run()
152     {
153         boost::mp11::mp_for_each<fixture::pixel_integer_types>(test_pixel_multiply_integer_same_types{});
154     }
155 };
156 
157 struct test_pixel_divides_scalar_integer_same_types
158 {
159     template <typename Pixel>
operator ()test_pixel_divides_scalar_integer_same_types160     void operator()(Pixel const&)
161     {
162         using pixel_t = Pixel;
163         using channel_t = typename gil::channel_type<pixel_t>::type;
164         gil::pixel_divides_scalar_t<pixel_t, channel_t, pixel_t> f;
165 
166         pixel_t p0;
167         gil::static_fill(p0, static_cast<channel_t>(0));
168         BOOST_TEST_EQ(f(p0, 1), p0);
169 
170         pixel_t p1;
171         gil::static_fill(p1, static_cast<channel_t>(1));
172         BOOST_TEST_EQ(f(p1, 1), p1);
173 
174         pixel_t p2;
175         gil::static_fill(p2, static_cast<channel_t>(2));
176         BOOST_TEST_EQ(f(p2, 2), p1);
177     }
runtest_pixel_divides_scalar_integer_same_types178     static void run()
179     {
180         boost::mp11::mp_for_each<fixture::pixel_integer_types>(test_pixel_divides_scalar_integer_same_types{});
181     }
182 };
183 
184 struct test_pixel_divide_integer_same_types
185 {
186     template <typename Pixel>
operator ()test_pixel_divide_integer_same_types187     void operator()(Pixel const&)
188     {
189         using pixel_t = Pixel;
190         using channel_t = typename gil::channel_type<pixel_t>::type;
191         gil::pixel_divide_t<pixel_t, pixel_t, pixel_t> f;
192 
193         pixel_t p0;
194         gil::static_fill(p0, static_cast<channel_t>(0));
195         pixel_t p1;
196         gil::static_fill(p1, static_cast<channel_t>(1));
197         BOOST_TEST_EQ(f(p0, p1), p0);
198         BOOST_TEST_EQ(f(p1, p1), p1);
199 
200         pixel_t p2;
201         gil::static_fill(p2, static_cast<channel_t>(2));
202         BOOST_TEST_EQ(f(p2, p1), p2);
203     }
runtest_pixel_divide_integer_same_types204     static void run()
205     {
206         boost::mp11::mp_for_each<fixture::pixel_integer_types>(test_pixel_divide_integer_same_types{});
207     }
208 };
209 
210 struct test_pixel_halves_integer_same_types
211 {
212     template <typename Pixel>
operator ()test_pixel_halves_integer_same_types213     void operator()(Pixel const&)
214     {
215         using pixel_t = Pixel;
216         using channel_t = typename gil::channel_type<pixel_t>::type;
217         gil::pixel_halves_t<pixel_t> f;
218 
219         pixel_t p0;
220         gil::static_fill(p0, static_cast<channel_t>(0));
221         pixel_t p1;
222         gil::static_fill(p1, static_cast<channel_t>(1));
223 
224         {
225             auto p = p0;
226             BOOST_TEST_EQ(f(p), p0);
227         }
228         {
229             auto p = p1;
230             BOOST_TEST_EQ(f(p), p0); // truncates toward Zero
231         }
232         {
233             pixel_t p2;
234             gil::static_fill(p2, static_cast<channel_t>(2));
235             BOOST_TEST_EQ(f(p2), p1);
236         }
237     }
runtest_pixel_halves_integer_same_types238     static void run()
239     {
240         boost::mp11::mp_for_each<fixture::pixel_integer_types>(test_pixel_halves_integer_same_types{});
241     }
242 };
243 
244 struct test_pixel_zeros_integer_same_types
245 {
246     template <typename Pixel>
operator ()test_pixel_zeros_integer_same_types247     void operator()(Pixel const&)
248     {
249         using pixel_t = Pixel;
250         using channel_t = typename gil::channel_type<pixel_t>::type;
251         gil::pixel_zeros_t<pixel_t> f;
252 
253         pixel_t p0;
254         gil::static_fill(p0, static_cast<channel_t>(0));
255         {
256             auto p = p0;
257             BOOST_TEST_EQ(f(p), p0);
258         }
259         {
260             fixture::consecutive_value<channel_t> g(1);
261             pixel_t p;
262             gil::static_generate(p, [&g]() { return g(); });
263             BOOST_TEST_EQ(f(p), p0);
264         }
265     }
runtest_pixel_zeros_integer_same_types266     static void run()
267     {
268         boost::mp11::mp_for_each<fixture::pixel_integer_types>(test_pixel_zeros_integer_same_types{});
269     }
270 };
271 
272 struct test_zero_channels_integer_same_types
273 {
274     template <typename Pixel>
operator ()test_zero_channels_integer_same_types275     void operator()(Pixel const&)
276     {
277         using pixel_t = Pixel;
278         using channel_t = typename gil::channel_type<pixel_t>::type;
279 
280         pixel_t p0;
281         gil::static_fill(p0, static_cast<channel_t>(0));
282         {
283             auto p = p0;
284             gil::zero_channels(p);
285             BOOST_TEST_EQ(p, p0);
286         }
287         {
288             fixture::consecutive_value<channel_t> g(1);
289             pixel_t p;
290             gil::static_generate(p, [&g]() { return g(); });
291             gil::zero_channels(p);
292             BOOST_TEST_EQ(p, p0);
293         }
294     }
runtest_zero_channels_integer_same_types295     static void run()
296     {
297         boost::mp11::mp_for_each<fixture::pixel_integer_types>(test_zero_channels_integer_same_types{});
298     }
299 };
300 
301 struct test_pixel_assigns_integer_same_types
302 {
303     template <typename Pixel>
operator ()test_pixel_assigns_integer_same_types304     void operator()(Pixel const&)
305     {
306         using pixel_t = Pixel;
307         using channel_t = typename gil::channel_type<pixel_t>::type;
308         gil::pixel_assigns_t<pixel_t, pixel_t> f;
309 
310         {
311             pixel_t p0, r;
312             gil::static_fill(p0, static_cast<channel_t>(0));
313             f(p0, r);
314             BOOST_TEST_EQ(p0, r);
315         }
316         {
317             fixture::consecutive_value<channel_t> g(1);
318             pixel_t p, r;
319             gil::static_generate(p, [&g]() { return g(); });
320             f(p, r);
321             BOOST_TEST_EQ(p, r);
322         }
323     }
runtest_pixel_assigns_integer_same_types324     static void run()
325     {
326         boost::mp11::mp_for_each<fixture::pixel_integer_types>(test_pixel_assigns_integer_same_types{});
327     }
328 };
main()329 int main()
330 {
331     test_plus_integer_same_types::run();
332     test_minus_integer_same_types::run();
333     test_pixel_multiplies_scalar_integer_same_types::run();
334     test_pixel_multiply_integer_same_types::run();
335     test_pixel_divides_scalar_integer_same_types::run();
336     test_pixel_divide_integer_same_types::run();
337     test_pixel_halves_integer_same_types::run();
338     test_pixel_zeros_integer_same_types::run();
339     test_zero_channels_integer_same_types::run();
340     test_pixel_assigns_integer_same_types::run();
341 
342     return ::boost::report_errors();
343 }
344