Make the ResampleEffect accuracy test stricter.
[movit] / padding_effect_test.cpp
1 // Unit tests for AlphaMultiplicationEffect.
2
3 #include <GL/glew.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 TEST(PaddingEffectTest, SimpleCenter) {
15         float data[2 * 2] = {
16                 1.0f, 0.5f,
17                 0.8f, 0.3f,
18         };
19         float expected_data[4 * 4] = {
20                 0.0f, 0.0f, 0.0f, 0.0f,
21                 0.0f, 1.0f, 0.5f, 0.0f,
22                 0.0f, 0.8f, 0.3f, 0.0f,
23                 0.0f, 0.0f, 0.0f, 0.0f,
24         };
25         float out_data[4 * 4];
26
27         EffectChainTester tester(NULL, 4, 4);
28
29         ImageFormat format;
30         format.color_space = COLORSPACE_sRGB;
31         format.gamma_curve = GAMMA_LINEAR;
32
33         FlatInput *input = new FlatInput(format, FORMAT_GRAYSCALE, GL_FLOAT, 2, 2);
34         input->set_pixel_data(data);
35         tester.get_chain()->add_input(input);
36
37         Effect *effect = tester.get_chain()->add_effect(new PaddingEffect());
38         CHECK(effect->set_int("width", 4));
39         CHECK(effect->set_int("height", 4));
40         CHECK(effect->set_float("left", 1.0f));
41         CHECK(effect->set_float("top", 1.0f));
42
43         tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR, OUTPUT_ALPHA_FORMAT_PREMULTIPLIED);
44         expect_equal(expected_data, out_data, 4, 4);
45 }
46
47 TEST(PaddingEffectTest, WhiteBorderColor) {
48         float data[2 * 2] = {
49                 1.0f, 0.5f,
50                 0.8f, 0.3f,
51         };
52         float expected_data[4 * 4] = {
53                 1.0f, 1.0f, 1.0f, 1.0f,
54                 1.0f, 1.0f, 0.5f, 1.0f,
55                 1.0f, 0.8f, 0.3f, 1.0f,
56                 1.0f, 1.0f, 1.0f, 1.0f,
57         };
58         float out_data[4 * 4];
59
60         EffectChainTester tester(NULL, 4, 4);
61
62         ImageFormat format;
63         format.color_space = COLORSPACE_sRGB;
64         format.gamma_curve = GAMMA_LINEAR;
65
66         FlatInput *input = new FlatInput(format, FORMAT_GRAYSCALE, GL_FLOAT, 2, 2);
67         input->set_pixel_data(data);
68         tester.get_chain()->add_input(input);
69
70         Effect *effect = tester.get_chain()->add_effect(new PaddingEffect());
71         CHECK(effect->set_int("width", 4));
72         CHECK(effect->set_int("height", 4));
73         CHECK(effect->set_float("left", 1.0f));
74         CHECK(effect->set_float("top", 1.0f));
75
76         RGBATuple border_color(1.0f, 1.0f, 1.0f, 1.0f);
77         CHECK(effect->set_vec4("border_color", (float *)&border_color));
78
79         tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR, OUTPUT_ALPHA_FORMAT_PREMULTIPLIED);
80         expect_equal(expected_data, out_data, 4, 4);
81 }
82
83 TEST(PaddingEffectTest, BorderColorIsInLinearGamma) {
84         float data[4 * 1] = {
85                 0.2f, 0.4f, 0.6f, 0.8f,
86         };
87         float expected_data[4 * 2] = {
88                 0.5005, 0.7051, 0.8677, 0.7998,  // Pixel from data[].
89                 0.5005, 0.7051, 0.8677, 0.7998,  // Pixel from the border color.
90         };
91         float out_data[4 * 2];
92
93         EffectChainTester tester(NULL, 1, 2);
94
95         ImageFormat format;
96         format.color_space = COLORSPACE_sRGB;
97         format.gamma_curve = GAMMA_LINEAR;
98
99         FlatInput *input = new FlatInput(format, FORMAT_RGBA_PREMULTIPLIED_ALPHA, GL_FLOAT, 1, 1);
100         input->set_pixel_data(data);
101         tester.get_chain()->add_input(input);
102
103         Effect *effect = tester.get_chain()->add_effect(new PaddingEffect());
104         CHECK(effect->set_int("width", 1));
105         CHECK(effect->set_int("height", 2));
106         CHECK(effect->set_float("left", 0.0f));
107         CHECK(effect->set_float("top", 0.0f));
108
109         RGBATuple border_color(0.2f, 0.4f, 0.6f, 0.8f);  // Same as the pixel in data[].
110         CHECK(effect->set_vec4("border_color", (float *)&border_color));
111
112         tester.run(out_data, GL_RGBA, COLORSPACE_REC_601_625, GAMMA_REC_601, OUTPUT_ALPHA_FORMAT_POSTMULTIPLIED);
113         expect_equal(expected_data, out_data, 4, 2);
114 }
115
116 TEST(PaddingEffectTest, DifferentXAndYOffset) {
117         float data[1 * 1] = {
118                 1.0f
119         };
120         float expected_data[3 * 3] = {
121                 0.0f, 0.0f, 0.0f,
122                 0.0f, 0.0f, 1.0f,
123                 0.0f, 0.0f, 0.0f,
124         };
125         float out_data[3 * 3];
126
127         EffectChainTester tester(NULL, 3, 3);
128
129         ImageFormat format;
130         format.color_space = COLORSPACE_sRGB;
131         format.gamma_curve = GAMMA_LINEAR;
132
133         FlatInput *input = new FlatInput(format, FORMAT_GRAYSCALE, GL_FLOAT, 1, 1);
134         input->set_pixel_data(data);
135         tester.get_chain()->add_input(input);
136
137         Effect *effect = tester.get_chain()->add_effect(new PaddingEffect());
138         CHECK(effect->set_int("width", 3));
139         CHECK(effect->set_int("height", 3));
140         CHECK(effect->set_float("left", 2.0f));
141         CHECK(effect->set_float("top", 1.0f));
142
143         tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR, OUTPUT_ALPHA_FORMAT_PREMULTIPLIED);
144         expect_equal(expected_data, out_data, 3, 3);
145 }
146
147 TEST(PaddingEffectTest, NonIntegerOffset) {
148         float data[4 * 1] = {
149                 0.25f, 0.50f, 0.75f, 1.0f,
150         };
151         // Note that the first pixel is completely blank, since the cutoff goes
152         // at the immediate left of the texel.
153         float expected_data[5 * 2] = {
154                 0.0f, 0.4375f, 0.6875f, 0.9375f, 0.0f,
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 }