Add proper formats for sRGB without alpha.
[movit] / flat_input_test.cpp
1 // Unit tests for FlatInput.
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 "test_util.h"
10 #include "util.h"
11
12 namespace movit {
13
14 TEST(FlatInput, SimpleGrayscale) {
15         const int size = 4;
16
17         float data[size] = {
18                 0.0,
19                 0.5,
20                 0.7,
21                 1.0,
22         };
23         float expected_data[4 * size] = {
24                 0.0, 0.0, 0.0, 1.0,
25                 0.5, 0.5, 0.5, 1.0,
26                 0.7, 0.7, 0.7, 1.0,
27                 1.0, 1.0, 1.0, 1.0,
28         };
29         float out_data[4 * size];
30
31         EffectChainTester tester(data, 1, size, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR);
32         tester.run(out_data, GL_RGBA, COLORSPACE_sRGB, GAMMA_LINEAR);
33
34         expect_equal(expected_data, out_data, 4, size);
35 }
36
37 TEST(FlatInput, RGB) {
38         const int size = 5;
39
40         float data[3 * size] = {
41                 0.0, 0.0, 0.0,
42                 0.5, 0.0, 0.0,
43                 0.0, 0.5, 0.0,
44                 0.0, 0.0, 0.7,
45                 0.0, 0.3, 0.7,
46         };
47         float expected_data[4 * size] = {
48                 0.0, 0.0, 0.0, 1.0,
49                 0.5, 0.0, 0.0, 1.0,
50                 0.0, 0.5, 0.0, 1.0,
51                 0.0, 0.0, 0.7, 1.0,
52                 0.0, 0.3, 0.7, 1.0,
53         };
54         float out_data[4 * size];
55
56         EffectChainTester tester(data, 1, size, FORMAT_RGB, COLORSPACE_sRGB, GAMMA_LINEAR);
57         tester.run(out_data, GL_RGBA, COLORSPACE_sRGB, GAMMA_LINEAR);
58
59         expect_equal(expected_data, out_data, 4, size);
60 }
61
62 TEST(FlatInput, RGBA) {
63         const int size = 5;
64
65         float data[4 * size] = {
66                 0.0, 0.0, 0.0, 1.0,
67                 0.5, 0.0, 0.0, 0.3,
68                 0.0, 0.5, 0.0, 0.7,
69                 0.0, 0.0, 0.7, 1.0,
70                 0.0, 0.3, 0.7, 0.2,
71         };
72         float expected_data[4 * size] = {
73                 0.0, 0.0, 0.0, 1.0,
74                 0.5, 0.0, 0.0, 0.3,
75                 0.0, 0.5, 0.0, 0.7,
76                 0.0, 0.0, 0.7, 1.0,
77                 0.0, 0.3, 0.7, 0.2,
78         };
79         float out_data[4 * size];
80
81         EffectChainTester tester(data, 1, size, FORMAT_RGBA_POSTMULTIPLIED_ALPHA, COLORSPACE_sRGB, GAMMA_LINEAR);
82         tester.run(out_data, GL_RGBA, COLORSPACE_sRGB, GAMMA_LINEAR);
83
84         expect_equal(expected_data, out_data, 4, size);
85 }
86
87 // Note: The sRGB conversion itself is tested in EffectChainTester,
88 // since it also wants to test the chain building itself.
89 // Here, we merely test that alpha is left alone; the test will usually
90 // run using the sRGB OpenGL extension, but might be run with a
91 // GammaExpansionEffect if the card/driver happens not to support that.
92 TEST(FlatInput, AlphaIsNotModifiedBySRGBConversion) {
93         const int size = 5;
94
95         unsigned char data[4 * size] = {
96                 0, 0, 0, 0,
97                 0, 0, 0, 63,
98                 0, 0, 0, 127,
99                 0, 0, 0, 191,
100                 0, 0, 0, 255,
101         };
102         float expected_data[4 * size] = {
103                 0, 0, 0, 0.0 / 255.0,
104                 0, 0, 0, 63.0 / 255.0,
105                 0, 0, 0, 127.0 / 255.0,
106                 0, 0, 0, 191.0 / 255.0,
107                 0, 0, 0, 255.0 / 255.0,
108         };
109         float out_data[4 * size];
110
111         EffectChainTester tester(NULL, 1, size);
112         tester.add_input(data, FORMAT_RGBA_POSTMULTIPLIED_ALPHA, COLORSPACE_sRGB, GAMMA_sRGB);
113         tester.run(out_data, GL_RGBA, COLORSPACE_sRGB, GAMMA_LINEAR);
114
115         expect_equal(expected_data, out_data, 4, size);
116 }
117
118 TEST(FlatInput, BGR) {
119         const int size = 5;
120
121         float data[3 * size] = {
122                 0.0, 0.0, 0.0,
123                 0.5, 0.0, 0.0,
124                 0.0, 0.5, 0.0,
125                 0.0, 0.0, 0.7,
126                 0.0, 0.3, 0.7,
127         };
128         float expected_data[4 * size] = {
129                 0.0, 0.0, 0.0, 1.0,
130                 0.0, 0.0, 0.5, 1.0,
131                 0.0, 0.5, 0.0, 1.0,
132                 0.7, 0.0, 0.0, 1.0,
133                 0.7, 0.3, 0.0, 1.0,
134         };
135         float out_data[4 * size];
136
137         EffectChainTester tester(data, 1, size, FORMAT_BGR, COLORSPACE_sRGB, GAMMA_LINEAR);
138         tester.run(out_data, GL_RGBA, COLORSPACE_sRGB, GAMMA_LINEAR);
139
140         expect_equal(expected_data, out_data, 4, size);
141 }
142
143 TEST(FlatInput, BGRA) {
144         const int size = 5;
145
146         float data[4 * size] = {
147                 0.0, 0.0, 0.0, 1.0,
148                 0.5, 0.0, 0.0, 0.3,
149                 0.0, 0.5, 0.0, 0.7,
150                 0.0, 0.0, 0.7, 1.0,
151                 0.0, 0.3, 0.7, 0.2,
152         };
153         float expected_data[4 * size] = {
154                 0.0, 0.0, 0.0, 1.0,
155                 0.0, 0.0, 0.5, 0.3,
156                 0.0, 0.5, 0.0, 0.7,
157                 0.7, 0.0, 0.0, 1.0,
158                 0.7, 0.3, 0.0, 0.2,
159         };
160         float out_data[4 * size];
161
162         EffectChainTester tester(data, 1, size, FORMAT_BGRA_POSTMULTIPLIED_ALPHA, COLORSPACE_sRGB, GAMMA_LINEAR);
163         tester.run(out_data, GL_RGBA, COLORSPACE_sRGB, GAMMA_LINEAR);
164
165         expect_equal(expected_data, out_data, 4, size);
166 }
167
168 TEST(FlatInput, Pitch) {
169         const int pitch = 3;
170         const int width = 2;
171         const int height = 4;
172
173         float data[pitch * height] = {
174                 0.0, 1.0, 999.0f,
175                 0.5, 0.5, 999.0f,
176                 0.7, 0.2, 999.0f,
177                 1.0, 0.6, 999.0f,
178         };
179         float expected_data[4 * width * height] = {
180                 0.0, 0.0, 0.0, 1.0,  1.0, 1.0, 1.0, 1.0,
181                 0.5, 0.5, 0.5, 1.0,  0.5, 0.5, 0.5, 1.0,
182                 0.7, 0.7, 0.7, 1.0,  0.2, 0.2, 0.2, 1.0,
183                 1.0, 1.0, 1.0, 1.0,  0.6, 0.6, 0.6, 1.0,
184         };
185         float out_data[4 * width * height];
186
187         EffectChainTester tester(NULL, width, height);
188
189         ImageFormat format;
190         format.color_space = COLORSPACE_sRGB;
191         format.gamma_curve = GAMMA_LINEAR;
192
193         FlatInput *input = new FlatInput(format, FORMAT_GRAYSCALE, GL_FLOAT, width, height);
194         input->set_pitch(pitch);
195         input->set_pixel_data(data);
196         tester.get_chain()->add_input(input);
197
198         tester.run(out_data, GL_RGBA, COLORSPACE_sRGB, GAMMA_LINEAR);
199         expect_equal(expected_data, out_data, 4 * width, height);
200 }
201
202 TEST(FlatInput, UpdatedData) {
203         const int width = 2;
204         const int height = 4;
205
206         float data[width * height] = {
207                 0.0, 1.0,
208                 0.5, 0.5,
209                 0.7, 0.2,
210                 1.0, 0.6,
211         };
212         float out_data[width * height];
213
214         EffectChainTester tester(NULL, width, height);
215
216         ImageFormat format;
217         format.color_space = COLORSPACE_sRGB;
218         format.gamma_curve = GAMMA_LINEAR;
219
220         FlatInput *input = new FlatInput(format, FORMAT_GRAYSCALE, GL_FLOAT, width, height);
221         input->set_pixel_data(data);
222         tester.get_chain()->add_input(input);
223
224         tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR);
225         expect_equal(data, out_data, width, height);
226
227         data[6] = 0.3;
228         input->invalidate_pixel_data();
229
230         tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR);
231         expect_equal(data, out_data, width, height);
232 }
233
234 TEST(FlatInput, PBO) {
235         const int width = 3;
236         const int height = 2;
237
238         float data[width * height] = {
239                 0.0, 1.0, 0.5,
240                 0.5, 0.5, 0.2,
241         };
242         float expected_data[4 * width * height] = {
243                 0.0, 0.0, 0.0, 1.0,  1.0, 1.0, 1.0, 1.0,  0.5, 0.5, 0.5, 1.0,
244                 0.5, 0.5, 0.5, 1.0,  0.5, 0.5, 0.5, 1.0,  0.2, 0.2, 0.2, 1.0,
245         };
246         float out_data[4 * width * height];
247
248         GLuint pbo;
249         glGenBuffers(1, &pbo);
250         glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, pbo);
251         glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB, width * height * sizeof(float), data, GL_STREAM_DRAW);
252         glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
253
254         EffectChainTester tester(NULL, width, height);
255
256         ImageFormat format;
257         format.color_space = COLORSPACE_sRGB;
258         format.gamma_curve = GAMMA_LINEAR;
259
260         FlatInput *input = new FlatInput(format, FORMAT_GRAYSCALE, GL_FLOAT, width, height);
261         input->set_pixel_data((float *)BUFFER_OFFSET(0), pbo);
262         tester.get_chain()->add_input(input);
263
264         tester.run(out_data, GL_RGBA, COLORSPACE_sRGB, GAMMA_LINEAR);
265         expect_equal(expected_data, out_data, 4 * width, height);
266
267         glDeleteBuffers(1, &pbo);
268 }
269
270 }  // namespace movit