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