Imported Upstream version 1.71.0
[platform/upstream/boost.git] / libs / gil / numeric / test / numeric.cpp
1 // Copyright 2013 Krzysztof Czainski
2 // Distributed under the Boost Software License, Version 1.0. (See
3 // accompanying file LICENSE_1_0.txt or copy at
4 // http://www.boost.org/LICENSE_1_0.txt)
5
6 /// \file numeric.cpp
7
8 /// \brief Unit test for Numeric extension
9
10 #include <boost/gil/image.hpp>
11 #include <boost/gil/typedefs.hpp>
12
13 #include <boost/gil/extension/numeric/resample.hpp>
14 #include <boost/gil/extension/numeric/sampler.hpp>
15
16 #include <boost/assert.hpp>
17
18 #if defined(BOOST_CLANG)
19 #pragma clang diagnostic push
20 #pragma clang diagnostic ignored "-Wfloat-equal"
21 #endif
22
23 #if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
24 #pragma GCC diagnostic push
25 #pragma GCC diagnostic ignored "-Wfloat-equal"
26 #endif
27
28 #define BOOST_TEST_MAIN
29 #include <boost/test/unit_test.hpp>
30
31 using namespace boost;
32 using namespace gil;
33
34 template < class F, class I >
35 struct TestMapFn
36 {
37     using point_t = point<F>;
38     using result_type = point_t;
39     result_type operator()(point<I> const& src) const
40     {
41         F x = static_cast<F>( src.x ) - 0.5;
42         F y = static_cast<F>( src.y ) - 0.5;
43         return { x, y };
44     }
45 };
46
47 namespace boost { namespace gil {
48
49 // NOTE: I suggest this could be the default behavior:
50
51 template <typename T> struct mapping_traits;
52
53 template < class F, class I >
54 struct mapping_traits<TestMapFn<F, I>>
55 {
56     using result_type = typename TestMapFn<F, I>::result_type;
57 };
58
59 template <class F, class I>
60 inline point<F> transform(TestMapFn<F, I> const& mf, point<I> const& src)
61 {
62     return mf(src);
63 }
64
65 }} // boost::gil
66
67
68 BOOST_AUTO_TEST_SUITE(Numeric_Tests)
69
70 BOOST_AUTO_TEST_CASE( pixel_numeric_operations_plus )
71 {
72     rgb8_pixel_t a( 10, 20, 30 );
73     bgr8_pixel_t b( 30, 20, 10 );
74
75     pixel_plus_t< rgb8_pixel_t
76                 , bgr8_pixel_t
77                 , rgb8_pixel_t
78                 > op;
79     rgb8_pixel_t c = op( a, b );
80
81     BOOST_ASSERT( get_color( c, red_t()   ) == 20 );
82     BOOST_ASSERT( get_color( c, green_t() ) == 40 );
83     BOOST_ASSERT( get_color( c, blue_t()  ) == 60 );
84
85     pixel_plus_t< rgb8_pixel_t
86                 , bgr8_pixel_t
87                 , bgr8_pixel_t
88                 > op2;
89     bgr8_pixel_t d = op2( a, b );
90
91     BOOST_ASSERT( get_color( d, red_t()   ) == 20 );
92     BOOST_ASSERT( get_color( d, green_t() ) == 40 );
93     BOOST_ASSERT( get_color( d, blue_t()  ) == 60 );
94 }
95
96 BOOST_AUTO_TEST_CASE( pixel_numeric_operations_multiply )
97 {
98     rgb32f_pixel_t a( 1.f, 2.f, 3.f );
99     bgr32f_pixel_t b( 2.f, 2.f, 2.f );
100
101     pixel_multiply_t< rgb32f_pixel_t
102                     , bgr32f_pixel_t
103                     , rgb32f_pixel_t
104                     > op;
105     rgb32f_pixel_t c = op( a, b );
106
107     float epsilon = 1e-6f;
108     BOOST_CHECK_CLOSE( static_cast<float>( get_color( c,   red_t() )), 2.f, epsilon );
109     BOOST_CHECK_CLOSE( static_cast<float>( get_color( c, green_t() )), 4.f, epsilon );
110     BOOST_CHECK_CLOSE( static_cast<float>( get_color( c,  blue_t() )), 6.f, epsilon );
111 }
112
113 BOOST_AUTO_TEST_CASE( pixel_numeric_operations_divide )
114 {
115     // integer
116     {
117         rgb8_pixel_t a( 10, 20, 30 );
118         bgr8_pixel_t b(  2,  2,  2 );
119
120         pixel_divide_t< rgb8_pixel_t
121                       , bgr8_pixel_t
122                       , rgb8_pixel_t
123                       > op;
124         rgb32f_pixel_t c = op( a, b );
125
126         BOOST_ASSERT( get_color( c,   red_t() ) ==  5 );
127         BOOST_ASSERT( get_color( c, green_t() ) == 10 );
128         BOOST_ASSERT( get_color( c,  blue_t() ) == 15 );
129     }
130
131     // float
132     {
133         rgb32f_pixel_t a( 1.f, 2.f, 3.f );
134         bgr32f_pixel_t b( 2.f, 2.f, 2.f );
135
136         pixel_divide_t< rgb32f_pixel_t
137                       , bgr32f_pixel_t
138                       , rgb32f_pixel_t
139                       > op;
140         rgb32f_pixel_t c = op( a, b );
141
142         float epsilon = 1e-6f;
143         BOOST_CHECK_CLOSE( static_cast< float >( get_color( c,   red_t() )), 0.5f, epsilon );
144         BOOST_CHECK_CLOSE( static_cast< float >( get_color( c, green_t() )),  1.f, epsilon );
145         BOOST_CHECK_CLOSE( static_cast< float >( get_color( c,  blue_t() )), 1.5f, epsilon );
146     }
147 }
148
149 BOOST_AUTO_TEST_CASE(bilinear_sampler_test)
150 {
151     // R G B
152     // G W R
153     // B R G
154     rgb8_image_t img(3,3);
155     rgb8_view_t v = view(img);
156     v(0,0) = v(1,2) = v(2,1) = rgb8_pixel_t(128,0,0);
157     v(0,1) = v(1,0) = v(2,2) = rgb8_pixel_t(0,128,0);
158     v(0,2) = v(2,0) = rgb8_pixel_t(0,0,128);
159     v(1,1) = rgb8_pixel_t(128,128,128);
160
161     rgb8_image_t dimg(4,4);
162     rgb8c_view_t dv = const_view(dimg);
163
164     TestMapFn<double,rgb8_image_t::coord_t> mf;
165
166     resample_pixels(const_view(img), view(dimg), mf, bilinear_sampler());
167
168     BOOST_ASSERT(rgb8_pixel_t(128,0,0) == dv(0,0));
169     BOOST_ASSERT(rgb8_pixel_t(64,64,0) == dv(0,1));
170     BOOST_ASSERT(rgb8_pixel_t(0,64,64) == dv(0,2));
171     BOOST_ASSERT(rgb8_pixel_t(0,0,128) == dv(0,3));
172
173     BOOST_ASSERT(rgb8_pixel_t(64,64,0) == dv(1,0));
174     BOOST_ASSERT(rgb8_pixel_t(64,96,32) == dv(1,1));
175     BOOST_ASSERT(rgb8_pixel_t(64,64,64) == dv(1,2));
176     BOOST_ASSERT(rgb8_pixel_t(64,0,64) == dv(1,3));
177
178     BOOST_ASSERT(rgb8_pixel_t(0,64,64) == dv(2,0));
179     BOOST_ASSERT(rgb8_pixel_t(64,64,64) == dv(2,1));
180     BOOST_ASSERT(rgb8_pixel_t(96,64,32) == dv(2,2));
181     BOOST_ASSERT(rgb8_pixel_t(64,64,0) == dv(2,3));
182
183     BOOST_ASSERT(rgb8_pixel_t(0,0,128) == dv(3,0));
184     BOOST_ASSERT(rgb8_pixel_t(64,0,64) == dv(3,1));
185     BOOST_ASSERT(rgb8_pixel_t(64,64,0) == dv(3,2));
186     BOOST_ASSERT(rgb8_pixel_t(0,128,0) == dv(3,3));
187 }
188
189 BOOST_AUTO_TEST_SUITE_END()