2 // Copyright 2019 Mateusz Loskot <mateusz at loskot dot net>
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
8 #include <boost/gil.hpp>
9 #include <boost/gil/extension/numeric/pixel_numeric_operations.hpp>
12 #include <type_traits>
14 #define BOOST_TEST_MODULE test_ext_numeric_pixel_numeric_operations
15 #include "unit_test.hpp"
16 #include "unit_test_utility.hpp"
17 #include "core/image/test_fixture.hpp" // random_value
18 #include "core/pixel/test_fixture.hpp"
20 namespace gil = boost::gil;
21 namespace fixture = boost::gil::test::fixture;
23 BOOST_AUTO_TEST_SUITE(pixel_plus_t)
25 BOOST_AUTO_TEST_CASE_TEMPLATE(plus_integer_same_types, pixel_t, fixture::pixel_integer_types)
27 using channel_t = typename gil::channel_type<pixel_t>::type;
28 gil::pixel_plus_t<pixel_t, pixel_t, pixel_t> f;
31 gil::static_fill(p0, static_cast<channel_t>(0));
32 BOOST_TEST(f(p0, p0) == p0);
36 gil::static_fill(p1, static_cast<channel_t>(1));
38 gil::static_fill(r2, static_cast<channel_t>(2));
39 BOOST_TEST(f(p1, p1) == r2);
42 // Generates pixels with consecutive channel values: {1} or {1,2,3} or {1,2,3,4} etc.
43 fixture::consecutive_value<channel_t> g(1);
45 gil::static_generate(p, [&g]() { return g(); });
46 auto const r = f(p, p);
48 BOOST_TEST(gil::at_c<0>(r) == (gil::at_c<0>(p) + gil::at_c<0>(p)));
52 BOOST_AUTO_TEST_SUITE_END() // pixel_plus_t
54 BOOST_AUTO_TEST_SUITE(pixel_minus_t)
56 BOOST_AUTO_TEST_CASE_TEMPLATE(minus_integer_same_types, pixel_t, fixture::pixel_integer_types)
58 using channel_t = typename gil::channel_type<pixel_t>::type;
59 gil::pixel_minus_t<pixel_t, pixel_t, pixel_t> f;
62 gil::static_fill(p0, static_cast<channel_t>(0));
63 BOOST_TEST(f(p0, p0) == p0);
66 gil::static_fill(p1, static_cast<channel_t>(1));
67 gil::static_fill(p2, static_cast<channel_t>(2));
69 gil::static_fill(r1, static_cast<channel_t>(1));
70 BOOST_TEST(f(p2, p1) == r1);
73 // Generates pixels with consecutive channel values: {1} or {1,2,3} or {1,2,3,4} etc.
74 fixture::consecutive_value<channel_t> g(1);
76 gil::static_generate(p, [&g]() { return g(); });
77 BOOST_TEST(f(p, p) == p0);
81 BOOST_AUTO_TEST_SUITE_END() // pixel_minus_t
83 BOOST_AUTO_TEST_SUITE(pixel_multiplies_scalar_t)
85 BOOST_AUTO_TEST_CASE_TEMPLATE(pixel_multiplies_scalar_integer_same_types, pixel_t, fixture::pixel_integer_types)
87 using channel_t = typename gil::channel_type<pixel_t>::type;
88 gil::pixel_multiplies_scalar_t<pixel_t, channel_t, pixel_t> f;
91 gil::static_fill(p0, static_cast<channel_t>(0));
92 BOOST_TEST(f(p0, 0) == p0);
96 gil::static_fill(p1, static_cast<channel_t>(1));
97 BOOST_TEST(f(p1, 0) == p0);
98 BOOST_TEST(f(p1, 1) == p1);
101 // Generates pixels with consecutive channel values: {1} or {1,2,3} or {1,2,3,4} etc.
102 fixture::consecutive_value<channel_t> g(1);
104 gil::static_generate(p, [&g]() { return g(); });
106 // check first channel value is doubled
107 auto const r = f(p, 2);
109 BOOST_TEST(gil::at_c<0>(r) == (gil::at_c<0>(p) * 2));
113 BOOST_AUTO_TEST_SUITE_END() // pixel_multiplies_scalar_t
115 BOOST_AUTO_TEST_SUITE(pixel_multiply_t)
117 BOOST_AUTO_TEST_CASE_TEMPLATE(pixel_multiply_integer_same_types, pixel_t, fixture::pixel_integer_types)
119 using channel_t = typename gil::channel_type<pixel_t>::type;
120 gil::pixel_multiply_t<pixel_t, pixel_t, pixel_t> f;
123 gil::static_fill(p0, static_cast<channel_t>(0));
124 BOOST_TEST(f(p0, p0) == p0);
127 gil::static_fill(p1, static_cast<channel_t>(1));
128 BOOST_TEST(f(p1, p1) == p1);
131 gil::static_fill(p2, static_cast<channel_t>(2));
132 BOOST_TEST(f(p1, p2) == p2);
135 BOOST_AUTO_TEST_SUITE_END() // pixel_multiply_t
137 BOOST_AUTO_TEST_SUITE(pixel_divides_scalar_t)
139 BOOST_AUTO_TEST_CASE_TEMPLATE(pixel_divides_scalar_integer_same_types, pixel_t, fixture::pixel_integer_types)
141 using channel_t = typename gil::channel_type<pixel_t>::type;
142 gil::pixel_divides_scalar_t<pixel_t, channel_t, pixel_t> f;
145 gil::static_fill(p0, static_cast<channel_t>(0));
146 BOOST_TEST(f(p0, 1) == p0);
149 gil::static_fill(p1, static_cast<channel_t>(1));
150 BOOST_TEST(f(p1, 1) == p1);
153 gil::static_fill(p2, static_cast<channel_t>(2));
154 BOOST_TEST(f(p2, 2) == p1);
157 BOOST_AUTO_TEST_SUITE_END() // pixel_divides_scalar_t
159 BOOST_AUTO_TEST_SUITE(pixel_divide_t)
161 BOOST_AUTO_TEST_CASE_TEMPLATE(pixel_divide_integer_same_types, pixel_t, fixture::pixel_integer_types)
163 using channel_t = typename gil::channel_type<pixel_t>::type;
164 gil::pixel_divide_t<pixel_t, pixel_t, pixel_t> f;
167 gil::static_fill(p0, static_cast<channel_t>(0));
169 gil::static_fill(p1, static_cast<channel_t>(1));
170 BOOST_TEST(f(p0, p1) == p0);
171 BOOST_TEST(f(p1, p1) == p1);
174 gil::static_fill(p2, static_cast<channel_t>(2));
175 BOOST_TEST(f(p2, p1) == p2);
178 BOOST_AUTO_TEST_SUITE_END() // pixel_divide_t
180 BOOST_AUTO_TEST_SUITE(pixel_halves_t)
182 BOOST_AUTO_TEST_CASE_TEMPLATE(pixel_halves_integer_same_types, pixel_t, fixture::pixel_integer_types)
184 using channel_t = typename gil::channel_type<pixel_t>::type;
185 gil::pixel_halves_t<pixel_t> f;
188 gil::static_fill(p0, static_cast<channel_t>(0));
190 gil::static_fill(p1, static_cast<channel_t>(1));
194 BOOST_TEST(f(p) == p0);
198 BOOST_TEST(f(p) == p0); // truncates toward Zero
202 gil::static_fill(p2, static_cast<channel_t>(2));
203 BOOST_TEST(f(p2) == p1);
207 BOOST_AUTO_TEST_SUITE_END() // pixel_halves_t
209 BOOST_AUTO_TEST_SUITE(pixel_zeros_t)
211 BOOST_AUTO_TEST_CASE_TEMPLATE(pixel_zeros_integer_same_types, pixel_t, fixture::pixel_integer_types)
213 using channel_t = typename gil::channel_type<pixel_t>::type;
214 gil::pixel_zeros_t<pixel_t> f;
217 gil::static_fill(p0, static_cast<channel_t>(0));
220 BOOST_TEST(f(p) == p0);
223 fixture::consecutive_value<channel_t> g(1);
225 gil::static_generate(p, [&g]() { return g(); });
226 BOOST_TEST(f(p) == p0);
230 BOOST_AUTO_TEST_SUITE_END() // pixel_zeros_t
232 BOOST_AUTO_TEST_SUITE(zero_channels)
234 BOOST_AUTO_TEST_CASE_TEMPLATE(zero_channels_integer_same_types, pixel_t, fixture::pixel_integer_types)
236 using channel_t = typename gil::channel_type<pixel_t>::type;
239 gil::static_fill(p0, static_cast<channel_t>(0));
242 gil::zero_channels(p);
246 fixture::consecutive_value<channel_t> g(1);
248 gil::static_generate(p, [&g]() { return g(); });
249 gil::zero_channels(p);
254 BOOST_AUTO_TEST_SUITE_END() // zero_channels
256 BOOST_AUTO_TEST_SUITE(pixel_assigns_t)
258 BOOST_AUTO_TEST_CASE_TEMPLATE(pixel_assigns_integer_same_types, pixel_t, fixture::pixel_integer_types)
260 using channel_t = typename gil::channel_type<pixel_t>::type;
261 gil::pixel_assigns_t<pixel_t, pixel_t> f;
265 gil::static_fill(p0, static_cast<channel_t>(0));
270 fixture::consecutive_value<channel_t> g(1);
272 gil::static_generate(p, [&g]() { return g(); });
278 BOOST_AUTO_TEST_SUITE_END() // pixel_assigns_t