Remove C++11 dependency from ResampleEffect.
[movit] / padding_effect_test.cpp
1 // Unit tests for PaddingEffect.
2
3 #include <epoxy/gl.h>
4 #include <stddef.h>
5
6 #include "effect_chain.h"
7 #include "flat_input.h"
8 #include "gtest/gtest.h"
9 #include "image_format.h"
10 #include "padding_effect.h"
11 #include "test_util.h"
12 #include "util.h"
13
14 namespace movit {
15
16 TEST(PaddingEffectTest, SimpleCenter) {
17         float data[2 * 2] = {
18                 1.0f, 0.5f,
19                 0.8f, 0.3f,
20         };
21         float expected_data[4 * 4] = {
22                 0.0f, 0.0f, 0.0f, 0.0f,
23                 0.0f, 1.0f, 0.5f, 0.0f,
24                 0.0f, 0.8f, 0.3f, 0.0f,
25                 0.0f, 0.0f, 0.0f, 0.0f,
26         };
27         float out_data[4 * 4];
28
29         EffectChainTester tester(NULL, 4, 4);
30
31         ImageFormat format;
32         format.color_space = COLORSPACE_sRGB;
33         format.gamma_curve = GAMMA_LINEAR;
34
35         FlatInput *input = new FlatInput(format, FORMAT_GRAYSCALE, GL_FLOAT, 2, 2);
36         input->set_pixel_data(data);
37         tester.get_chain()->add_input(input);
38
39         Effect *effect = tester.get_chain()->add_effect(new PaddingEffect());
40         CHECK(effect->set_int("width", 4));
41         CHECK(effect->set_int("height", 4));
42         CHECK(effect->set_float("left", 1.0f));
43         CHECK(effect->set_float("top", 1.0f));
44
45         tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR, OUTPUT_ALPHA_FORMAT_PREMULTIPLIED);
46         expect_equal(expected_data, out_data, 4, 4);
47 }
48
49 TEST(PaddingEffectTest, WhiteBorderColor) {
50         float data[2 * 2] = {
51                 1.0f, 0.5f,
52                 0.8f, 0.3f,
53         };
54         float expected_data[4 * 4] = {
55                 1.0f, 1.0f, 1.0f, 1.0f,
56                 1.0f, 1.0f, 0.5f, 1.0f,
57                 1.0f, 0.8f, 0.3f, 1.0f,
58                 1.0f, 1.0f, 1.0f, 1.0f,
59         };
60         float out_data[4 * 4];
61
62         EffectChainTester tester(NULL, 4, 4);
63
64         ImageFormat format;
65         format.color_space = COLORSPACE_sRGB;
66         format.gamma_curve = GAMMA_LINEAR;
67
68         FlatInput *input = new FlatInput(format, FORMAT_GRAYSCALE, GL_FLOAT, 2, 2);
69         input->set_pixel_data(data);
70         tester.get_chain()->add_input(input);
71
72         Effect *effect = tester.get_chain()->add_effect(new PaddingEffect());
73         CHECK(effect->set_int("width", 4));
74         CHECK(effect->set_int("height", 4));
75         CHECK(effect->set_float("left", 1.0f));
76         CHECK(effect->set_float("top", 1.0f));
77
78         RGBATuple border_color(1.0f, 1.0f, 1.0f, 1.0f);
79         CHECK(effect->set_vec4("border_color", (float *)&border_color));
80
81         tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR, OUTPUT_ALPHA_FORMAT_PREMULTIPLIED);
82         expect_equal(expected_data, out_data, 4, 4);
83 }
84
85 TEST(PaddingEffectTest, BorderColorIsInLinearGamma) {
86         float data[4 * 1] = {
87                 0.2f, 0.4f, 0.6f, 0.8f,
88         };
89         float expected_data[4 * 2] = {
90                 0.5005, 0.7051, 0.8677, 0.7998,  // Pixel from data[].
91                 0.5005, 0.7051, 0.8677, 0.7998,  // Pixel from the border color.
92         };
93         float out_data[4 * 2];
94
95         EffectChainTester tester(NULL, 1, 2);
96
97         ImageFormat format;
98         format.color_space = COLORSPACE_sRGB;
99         format.gamma_curve = GAMMA_LINEAR;
100
101         FlatInput *input = new FlatInput(format, FORMAT_RGBA_PREMULTIPLIED_ALPHA, GL_FLOAT, 1, 1);
102         input->set_pixel_data(data);
103         tester.get_chain()->add_input(input);
104
105         Effect *effect = tester.get_chain()->add_effect(new PaddingEffect());
106         CHECK(effect->set_int("width", 1));
107         CHECK(effect->set_int("height", 2));
108         CHECK(effect->set_float("left", 0.0f));
109         CHECK(effect->set_float("top", 0.0f));
110
111         RGBATuple border_color(0.2f, 0.4f, 0.6f, 0.8f);  // Same as the pixel in data[].
112         CHECK(effect->set_vec4("border_color", (float *)&border_color));
113
114         tester.run(out_data, GL_RGBA, COLORSPACE_REC_601_625, GAMMA_REC_601, OUTPUT_ALPHA_FORMAT_POSTMULTIPLIED);
115         expect_equal(expected_data, out_data, 4, 2);
116 }
117
118 TEST(PaddingEffectTest, DifferentXAndYOffset) {
119         float data[1 * 1] = {
120                 1.0f
121         };
122         float expected_data[3 * 3] = {
123                 0.0f, 0.0f, 0.0f,
124                 0.0f, 0.0f, 1.0f,
125                 0.0f, 0.0f, 0.0f,
126         };
127         float out_data[3 * 3];
128
129         EffectChainTester tester(NULL, 3, 3);
130
131         ImageFormat format;
132         format.color_space = COLORSPACE_sRGB;
133         format.gamma_curve = GAMMA_LINEAR;
134
135         FlatInput *input = new FlatInput(format, FORMAT_GRAYSCALE, GL_FLOAT, 1, 1);
136         input->set_pixel_data(data);
137         tester.get_chain()->add_input(input);
138
139         Effect *effect = tester.get_chain()->add_effect(new PaddingEffect());
140         CHECK(effect->set_int("width", 3));
141         CHECK(effect->set_int("height", 3));
142         CHECK(effect->set_float("left", 2.0f));
143         CHECK(effect->set_float("top", 1.0f));
144
145         tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR, OUTPUT_ALPHA_FORMAT_PREMULTIPLIED);
146         expect_equal(expected_data, out_data, 3, 3);
147 }
148
149 TEST(PaddingEffectTest, NonIntegerOffset) {
150         float data[4 * 1] = {
151                 0.25f, 0.50f, 0.75f, 1.0f,
152         };
153         float expected_data[5 * 2] = {
154                 0.1875f, 0.4375f, 0.6875f, 0.9375f, 0.25f,
155                 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
156         };
157         float out_data[5 * 2];
158
159         EffectChainTester tester(NULL, 5, 2);
160
161         ImageFormat format;
162         format.color_space = COLORSPACE_sRGB;
163         format.gamma_curve = GAMMA_LINEAR;
164
165         FlatInput *input = new FlatInput(format, FORMAT_GRAYSCALE, GL_FLOAT, 4, 1);
166         input->set_pixel_data(data);
167         tester.get_chain()->add_input(input);
168
169         Effect *effect = tester.get_chain()->add_effect(new PaddingEffect());
170         CHECK(effect->set_int("width", 5));
171         CHECK(effect->set_int("height", 2));
172         CHECK(effect->set_float("left", 0.25f));
173         CHECK(effect->set_float("top", 0.0f));
174
175         tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR, OUTPUT_ALPHA_FORMAT_PREMULTIPLIED);
176         expect_equal(expected_data, out_data, 5, 2);
177 }
178
179 TEST(PaddingEffectTest, Crop) {
180         float data[2 * 2] = {
181                 1.0f, 0.5f,
182                 0.8f, 0.3f,
183         };
184         float expected_data[1 * 1] = {
185                 0.3f,
186         };
187         float out_data[1 * 1];
188
189         EffectChainTester tester(NULL, 1, 1);
190
191         ImageFormat format;
192         format.color_space = COLORSPACE_sRGB;
193         format.gamma_curve = GAMMA_LINEAR;
194
195         FlatInput *input = new FlatInput(format, FORMAT_GRAYSCALE, GL_FLOAT, 2, 2);
196         input->set_pixel_data(data);
197         tester.get_chain()->add_input(input);
198
199         Effect *effect = tester.get_chain()->add_effect(new PaddingEffect());
200         CHECK(effect->set_int("width", 1));
201         CHECK(effect->set_int("height", 1));
202         CHECK(effect->set_float("left", -1.0f));
203         CHECK(effect->set_float("top", -1.0f));
204
205         tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR, OUTPUT_ALPHA_FORMAT_PREMULTIPLIED);
206         expect_equal(expected_data, out_data, 1, 1);
207 }
208
209 TEST(PaddingEffectTest, AlphaIsCorrectEvenWithNonLinearInputsAndOutputs) {
210         float data[2 * 1] = {
211                 1.0f,
212                 0.8f,
213         };
214         float expected_data[4 * 4] = {
215                 1.0f, 1.0f, 1.0f, 0.5f,
216                 1.0f, 1.0f, 1.0f, 1.0f,
217                 0.8f, 0.8f, 0.8f, 1.0f,
218                 1.0f, 1.0f, 1.0f, 0.5f,
219         };
220         float out_data[4 * 4];
221
222         EffectChainTester tester(NULL, 1, 4);
223
224         ImageFormat format;
225         format.color_space = COLORSPACE_REC_601_625;
226         format.gamma_curve = GAMMA_REC_709;
227
228         FlatInput *input = new FlatInput(format, FORMAT_GRAYSCALE, GL_FLOAT, 1, 2);
229         input->set_pixel_data(data);
230         tester.get_chain()->add_input(input);
231
232         Effect *effect = tester.get_chain()->add_effect(new PaddingEffect());
233         CHECK(effect->set_int("width", 1));
234         CHECK(effect->set_int("height", 4));
235         CHECK(effect->set_float("left", 0.0f));
236         CHECK(effect->set_float("top", 1.0f));
237
238         RGBATuple border_color(1.0f, 1.0f, 1.0f, 0.5f);
239         CHECK(effect->set_vec4("border_color", (float *)&border_color));
240
241         tester.run(out_data, GL_RGBA, COLORSPACE_REC_601_625, GAMMA_REC_709, OUTPUT_ALPHA_FORMAT_POSTMULTIPLIED);
242         expect_equal(expected_data, out_data, 4, 4);
243 }
244
245 TEST(PaddingEffectTest, RedBorder) {  // Not black nor white, but still a saturated primary.
246         float data[2 * 1] = {
247                 1.0f,
248                 0.8f,
249         };
250         float expected_data[4 * 4] = {
251                 1.0f, 0.0f, 0.0f, 1.0f,
252                 1.0f, 1.0f, 1.0f, 1.0f,
253                 0.8f, 0.8f, 0.8f, 1.0f,
254                 1.0f, 0.0f, 0.0f, 1.0f,
255         };
256         float out_data[4 * 4];
257
258         EffectChainTester tester(NULL, 1, 4);
259
260         ImageFormat format;
261         format.color_space = COLORSPACE_REC_601_625;
262         format.gamma_curve = GAMMA_REC_709;
263
264         FlatInput *input = new FlatInput(format, FORMAT_GRAYSCALE, GL_FLOAT, 1, 2);
265         input->set_pixel_data(data);
266         tester.get_chain()->add_input(input);
267
268         Effect *effect = tester.get_chain()->add_effect(new PaddingEffect());
269         CHECK(effect->set_int("width", 1));
270         CHECK(effect->set_int("height", 4));
271         CHECK(effect->set_float("left", 0.0f));
272         CHECK(effect->set_float("top", 1.0f));
273
274         RGBATuple border_color(1.0f, 0.0f, 0.0f, 1.0f);
275         CHECK(effect->set_vec4("border_color", (float *)&border_color));
276
277         tester.run(out_data, GL_RGBA, COLORSPACE_REC_709, GAMMA_REC_709, OUTPUT_ALPHA_FORMAT_POSTMULTIPLIED);
278         expect_equal(expected_data, out_data, 4, 4);
279 }
280
281 TEST(PaddingEffectTest, BorderOffsetTopAndBottom) {
282         float data[2 * 2] = {
283                 1.0f, 0.5f,
284                 0.8f, 0.3f,
285         };
286         float expected_data[4 * 4] = {
287                 0.0f, 0.000f, 0.000f, 0.0f,
288                 0.0f, 0.750f, 0.375f, 0.0f,
289                 0.0f, 0.800f, 0.300f, 0.0f,
290                 0.0f, 0.200f, 0.075f, 0.0f,  // Repeated pixels, 25% opacity.
291         };
292         float out_data[4 * 4];
293
294         EffectChainTester tester(NULL, 4, 4);
295
296         ImageFormat format;
297         format.color_space = COLORSPACE_sRGB;
298         format.gamma_curve = GAMMA_LINEAR;
299
300         FlatInput *input = new FlatInput(format, FORMAT_GRAYSCALE, GL_FLOAT, 2, 2);
301         input->set_pixel_data(data);
302         tester.get_chain()->add_input(input);
303
304         Effect *effect = tester.get_chain()->add_effect(new PaddingEffect());
305         CHECK(effect->set_int("width", 4));
306         CHECK(effect->set_int("height", 4));
307         CHECK(effect->set_float("left", 1.0f));
308         CHECK(effect->set_float("top", 1.0f));
309         CHECK(effect->set_float("border_offset_top", 0.25f));
310         CHECK(effect->set_float("border_offset_bottom", 0.25f));
311
312         tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR, OUTPUT_ALPHA_FORMAT_PREMULTIPLIED);
313         expect_equal(expected_data, out_data, 4, 4);
314 }
315
316 TEST(PaddingEffectTest, BorderOffsetLeftAndRight) {
317         float data[3 * 2] = {
318                 1.0f, 0.5f, 0.6f,
319                 0.8f, 0.3f, 0.2f,
320         };
321         float expected_data[4 * 2] = {
322                 0.750f, 0.5f, 0.3f, 0.0f,
323                 0.600f, 0.3f, 0.1f, 0.0f
324         };
325         float out_data[4 * 2];
326
327         EffectChainTester tester(NULL, 4, 2);
328
329         ImageFormat format;
330         format.color_space = COLORSPACE_sRGB;
331         format.gamma_curve = GAMMA_LINEAR;
332
333         FlatInput *input = new FlatInput(format, FORMAT_GRAYSCALE, GL_FLOAT, 3, 2);
334         input->set_pixel_data(data);
335         tester.get_chain()->add_input(input);
336
337         Effect *effect = tester.get_chain()->add_effect(new PaddingEffect());
338         CHECK(effect->set_int("width", 4));
339         CHECK(effect->set_int("height", 2));
340         CHECK(effect->set_float("left", 0.0f));
341         CHECK(effect->set_float("top", 0.0f));
342         CHECK(effect->set_float("border_offset_left", 0.25f));
343         CHECK(effect->set_float("border_offset_right", -0.5f));
344
345         tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR, OUTPUT_ALPHA_FORMAT_PREMULTIPLIED);
346         expect_equal(expected_data, out_data, 4, 2);
347 }
348
349 }  // namespace movit