1 //
2 // Copyright 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/cmyk.hpp>
9 #include <boost/gil/gray.hpp>
10 #include <boost/gil/pixel.hpp>
11 #include <boost/gil/rgb.hpp>
12
13 #include <boost/mp11.hpp>
14 #include <boost/core/lightweight_test.hpp>
15
16 #include "test_fixture.hpp"
17 #include "core/channel/test_fixture.hpp"
18
19 namespace gil = boost::gil;
20 namespace fixture = boost::gil::test::fixture;
21 namespace mp11 = boost::mp11;
22
23 // Test color_convert from any pixel to CMYK pixel types
24
25 template <typename SrcPixel>
26 struct test_cmyk_from_gray
27 {
28 template<typename DstPixel>
operator ()test_cmyk_from_gray29 void operator()(DstPixel const&)
30 {
31 using pixel_src_t = SrcPixel;
32 using pixel_dst_t = DstPixel;
33 fixture::channel_value<typename gil::channel_type<pixel_src_t>::type> f_src;
34 fixture::channel_value<typename gil::channel_type<pixel_dst_t>::type> f_dst;
35
36 // FIXME: Where does this calculation come from? Shouldn't gray be inverted?
37 // Currently, white becomes black and black becomes white.
38 {
39 pixel_src_t const src{f_src.min_v_};
40 pixel_dst_t dst;
41 gil::color_convert(src, dst);
42
43 BOOST_TEST_EQ(gil::get_color(dst, gil::cyan_t{}), f_dst.min_v_);
44 BOOST_TEST_EQ(gil::get_color(dst, gil::magenta_t{}), f_dst.min_v_);
45 BOOST_TEST_EQ(gil::get_color(dst, gil::yellow_t{}), f_dst.min_v_);
46 }
47 {
48 pixel_src_t const src{f_src.max_v_};
49 pixel_dst_t dst;
50 gil::color_convert(src, dst);
51
52 BOOST_TEST_EQ(gil::get_color(dst, gil::cyan_t{}), f_dst.min_v_);
53 BOOST_TEST_EQ(gil::get_color(dst, gil::magenta_t{}), f_dst.min_v_);
54 BOOST_TEST_EQ(gil::get_color(dst, gil::yellow_t{}), f_dst.min_v_);
55 BOOST_TEST_EQ(gil::get_color(dst, gil::black_t{}), f_dst.max_v_);
56 }
57 }
runtest_cmyk_from_gray58 static void run()
59 {
60 boost::mp11::mp_for_each
61 <
62 mp11::mp_list
63 <
64 gil::cmyk8_pixel_t,
65 gil::cmyk8s_pixel_t,
66 gil::cmyk16_pixel_t,
67 gil::cmyk16s_pixel_t,
68 gil::cmyk32_pixel_t,
69 gil::cmyk32s_pixel_t,
70 gil::cmyk32f_pixel_t
71 >
72 >(test_cmyk_from_gray<SrcPixel>{});
73 }
74 };
75
76 struct test_cmyk_from_rgb
77 {
78 template <typename SrcPixel, typename DstPixel>
operator ()test_cmyk_from_rgb79 void operator()(mp11::mp_list<SrcPixel, DstPixel> const&) const
80 {
81 using pixel_src_t = SrcPixel;
82 using pixel_dst_t = DstPixel;
83 fixture::channel_value<typename gil::channel_type<pixel_src_t>::type> f_src;
84 fixture::channel_value<typename gil::channel_type<pixel_dst_t>::type> f_dst;
85
86 // black
87 {
88 pixel_src_t const src(f_src.min_v_, f_src.min_v_, f_src.min_v_);
89 pixel_dst_t dst;
90 gil::color_convert(src, dst);
91
92 BOOST_TEST_EQ(gil::get_color(dst, gil::cyan_t{}), f_dst.min_v_);
93 BOOST_TEST_EQ(gil::get_color(dst, gil::magenta_t{}), f_dst.min_v_);
94 BOOST_TEST_EQ(gil::get_color(dst, gil::yellow_t{}), f_dst.min_v_);
95 BOOST_TEST_EQ(gil::get_color(dst, gil::black_t{}), f_dst.max_v_);
96 }
97 // white
98 {
99 pixel_src_t const src(f_src.max_v_, f_src.max_v_, f_src.max_v_);
100 pixel_dst_t dst;
101 gil::color_convert(src, dst);
102
103 BOOST_TEST_EQ(gil::get_color(dst, gil::cyan_t{}), f_dst.min_v_);
104 BOOST_TEST_EQ(gil::get_color(dst, gil::magenta_t{}), f_dst.min_v_);
105 BOOST_TEST_EQ(gil::get_color(dst, gil::yellow_t{}), f_dst.min_v_);
106 BOOST_TEST_EQ(gil::get_color(dst, gil::black_t{}), f_dst.min_v_);
107 }
108 // red
109 {
110 pixel_src_t const src(f_src.max_v_, f_src.min_v_, f_src.min_v_);
111 pixel_dst_t dst;
112 gil::color_convert(src, dst);
113
114 BOOST_TEST_EQ(gil::get_color(dst, gil::cyan_t{}), f_dst.min_v_);
115 BOOST_TEST_EQ(gil::get_color(dst, gil::magenta_t{}), f_dst.max_v_);
116 BOOST_TEST_EQ(gil::get_color(dst, gil::yellow_t{}), f_dst.max_v_);
117 BOOST_TEST_EQ(gil::get_color(dst, gil::black_t{}), f_dst.min_v_);
118 }
119 // green
120 {
121 pixel_src_t const src(f_src.min_v_, f_src.max_v_, f_src.min_v_);
122 pixel_dst_t dst;
123 gil::color_convert(src, dst);
124
125 BOOST_TEST_EQ(gil::get_color(dst, gil::cyan_t{}), f_dst.max_v_);
126 BOOST_TEST_EQ(gil::get_color(dst, gil::magenta_t{}), f_dst.min_v_);
127 BOOST_TEST_EQ(gil::get_color(dst, gil::yellow_t{}), f_dst.max_v_);
128 BOOST_TEST_EQ(gil::get_color(dst, gil::black_t{}), f_dst.min_v_);
129 }
130 // blue
131 {
132 pixel_src_t const src(f_src.min_v_, f_src.min_v_, f_src.max_v_);
133 pixel_dst_t dst;
134 gil::color_convert(src, dst);
135
136 BOOST_TEST_EQ(gil::get_color(dst, gil::cyan_t{}), f_dst.max_v_);
137 BOOST_TEST_EQ(gil::get_color(dst, gil::magenta_t{}), f_dst.max_v_);
138 BOOST_TEST_EQ(gil::get_color(dst, gil::yellow_t{}), f_dst.min_v_);
139 BOOST_TEST_EQ(gil::get_color(dst, gil::black_t{}), f_dst.min_v_);
140 }
141 // yellow
142 {
143 pixel_src_t const src(f_src.max_v_, f_src.max_v_, f_src.min_v_);
144 pixel_dst_t dst;
145 gil::color_convert(src, dst);
146
147 BOOST_TEST_EQ(gil::get_color(dst, gil::cyan_t{}), f_dst.min_v_);
148 BOOST_TEST_EQ(gil::get_color(dst, gil::magenta_t{}), f_dst.min_v_);
149 BOOST_TEST_EQ(gil::get_color(dst, gil::yellow_t{}), f_dst.max_v_);
150 BOOST_TEST_EQ(gil::get_color(dst, gil::black_t{}), f_dst.min_v_);
151 }
152 // cyan
153 {
154 pixel_src_t const src(f_src.min_v_, f_src.max_v_, f_src.max_v_);
155 pixel_dst_t dst;
156 gil::color_convert(src, dst);
157
158 BOOST_TEST_EQ(gil::get_color(dst, gil::cyan_t{}), f_dst.max_v_);
159 BOOST_TEST_EQ(gil::get_color(dst, gil::magenta_t{}), f_dst.min_v_);
160 BOOST_TEST_EQ(gil::get_color(dst, gil::yellow_t{}), f_dst.min_v_);
161 BOOST_TEST_EQ(gil::get_color(dst, gil::black_t{}), f_dst.min_v_);
162 }
163 // magenta
164 {
165 pixel_src_t const src(f_src.max_v_, f_src.min_v_, f_src.max_v_);
166 pixel_dst_t dst;
167 gil::color_convert(src, dst);
168
169 BOOST_TEST_EQ(gil::get_color(dst, gil::cyan_t{}), f_dst.min_v_);
170 BOOST_TEST_EQ(gil::get_color(dst, gil::magenta_t{}), f_dst.max_v_);
171 BOOST_TEST_EQ(gil::get_color(dst, gil::yellow_t{}), f_dst.min_v_);
172 BOOST_TEST_EQ(gil::get_color(dst, gil::black_t{}), f_dst.min_v_);
173 }
174 }
runtest_cmyk_from_rgb175 static void run()
176 {
177 boost::mp11::mp_for_each
178 <
179 mp11::mp_product
180 <
181 mp11::mp_list,
182 mp11::mp_list
183 <
184 gil::rgb8_pixel_t,
185 gil::rgb8s_pixel_t,
186 gil::rgb16_pixel_t,
187 gil::rgb16s_pixel_t,
188 gil::rgb32_pixel_t,
189 gil::rgb32s_pixel_t,
190 gil::rgb32f_pixel_t
191 >,
192 mp11::mp_list
193 <
194 gil::cmyk8_pixel_t,
195 gil::cmyk16_pixel_t,
196 gil::cmyk32_pixel_t,
197 gil::cmyk32f_pixel_t
198 // FIXME: Conversion not handle properly signed CMYK pixels as destination
199 >
200 >
201 >(test_cmyk_from_rgb{});
202 }
203 };
204
main()205 int main()
206 {
207 test_cmyk_from_gray<gil::gray8_pixel_t>::run();
208 test_cmyk_from_gray<gil::gray8s_pixel_t>::run();
209 test_cmyk_from_gray<gil::gray16_pixel_t>::run();
210 test_cmyk_from_gray<gil::gray16s_pixel_t>::run();
211 test_cmyk_from_gray<gil::gray32_pixel_t>::run();
212 test_cmyk_from_gray<gil::gray32s_pixel_t>::run();
213 test_cmyk_from_gray<gil::gray32f_pixel_t>::run();
214
215 test_cmyk_from_rgb::run();
216
217 return ::boost::report_errors();
218 }
219