1 //
2 // Copyright 2013 Krzysztof Czainski
3 // Copyright 2020 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 #include <boost/gil.hpp>
10 #include <boost/gil/extension/numeric/resample.hpp>
11 #include <boost/gil/extension/numeric/sampler.hpp>
12
13 #include <boost/core/lightweight_test.hpp>
14
15 #include <cmath>
16
17 #include "test_utility_output_stream.hpp"
18
19 namespace gil = boost::gil;
20
21 // FIXME: Remove when https://github.com/boostorg/core/issues/38 happens
22 #define BOOST_GIL_TEST_IS_CLOSE(a, b, epsilon) BOOST_TEST_LT(std::fabs((a) - (b)), (epsilon))
23
24 template <class F, class I>
25 struct test_map_fn
26 {
27 using point_t = gil::point<F>;
28 using result_type = point_t;
operator ()test_map_fn29 result_type operator()(gil::point<I> const &src) const
30 {
31 F x = static_cast<F>(src.x) - 0.5;
32 F y = static_cast<F>(src.y) - 0.5;
33 return {x, y};
34 }
35 };
36
37 namespace boost { namespace gil {
38
39 // NOTE: I suggest this could be the default behavior:
40
41 template <typename T>
42 struct mapping_traits;
43
44 template <class F, class I>
45 struct mapping_traits<test_map_fn<F, I>>
46 {
47 using result_type = typename test_map_fn<F, I>::result_type;
48 };
49
50 template <class F, class I>
transform(test_map_fn<F,I> const & mf,point<I> const & src)51 inline point<F> transform(test_map_fn<F, I> const &mf, point<I> const &src)
52 {
53 return mf(src);
54 }
55
56 }} // namespace boost::gil
57
test_bilinear_sampler_test()58 void test_bilinear_sampler_test()
59 {
60 // R G B
61 // G W R
62 // B R G
63 gil::rgb8_image_t img(3, 3);
64 gil::rgb8_view_t v = view(img);
65 v(0, 0) = v(1, 2) = v(2, 1) = gil::rgb8_pixel_t(128, 0, 0);
66 v(0, 1) = v(1, 0) = v(2, 2) = gil::rgb8_pixel_t(0, 128, 0);
67 v(0, 2) = v(2, 0) = gil::rgb8_pixel_t(0, 0, 128);
68 v(1, 1) = gil::rgb8_pixel_t(128, 128, 128);
69
70 gil::rgb8_image_t dims(4, 4);
71 gil::rgb8c_view_t dv = gil::const_view(dims);
72
73 test_map_fn<double, gil::rgb8_image_t::coord_t> mf;
74
75 gil::resample_pixels(gil::const_view(img), gil::view(dims), mf, gil::bilinear_sampler());
76
77 BOOST_TEST_EQ(gil::rgb8_pixel_t(128, 0, 0), dv(0, 0));
78 BOOST_TEST_EQ(gil::rgb8_pixel_t(64, 64, 0), dv(0, 1));
79 BOOST_TEST_EQ(gil::rgb8_pixel_t(0, 64, 64), dv(0, 2));
80 BOOST_TEST_EQ(gil::rgb8_pixel_t(0, 0, 128), dv(0, 3));
81
82 BOOST_TEST_EQ(gil::rgb8_pixel_t(64, 64, 0), dv(1, 0));
83 BOOST_TEST_EQ(gil::rgb8_pixel_t(64, 96, 32), dv(1, 1));
84 BOOST_TEST_EQ(gil::rgb8_pixel_t(64, 64, 64), dv(1, 2));
85 BOOST_TEST_EQ(gil::rgb8_pixel_t(64, 0, 64), dv(1, 3));
86
87 BOOST_TEST_EQ(gil::rgb8_pixel_t(0, 64, 64), dv(2, 0));
88 BOOST_TEST_EQ(gil::rgb8_pixel_t(64, 64, 64), dv(2, 1));
89 BOOST_TEST_EQ(gil::rgb8_pixel_t(96, 64, 32), dv(2, 2));
90 BOOST_TEST_EQ(gil::rgb8_pixel_t(64, 64, 0), dv(2, 3));
91
92 BOOST_TEST_EQ(gil::rgb8_pixel_t(0, 0, 128), dv(3, 0));
93 BOOST_TEST_EQ(gil::rgb8_pixel_t(64, 0, 64), dv(3, 1));
94 BOOST_TEST_EQ(gil::rgb8_pixel_t(64, 64, 0), dv(3, 2));
95 BOOST_TEST_EQ(gil::rgb8_pixel_t(0, 128, 0), dv(3, 3));
96 }
97
main()98 int main()
99 {
100 test_bilinear_sampler_test();
101
102 return ::boost::report_errors();
103 }
104