1 // Unit tests for ColorspaceConversionEffect.
5 #include "colorspace_conversion_effect.h"
6 #include "gtest/gtest.h"
9 TEST(ColorspaceConversionEffectTest, Reversible) {
11 0.0f, 0.0f, 0.0f, 1.0f,
12 1.0f, 1.0f, 1.0f, 1.0f,
13 1.0f, 0.0f, 0.0f, 1.0f,
14 0.0f, 1.0f, 0.0f, 1.0f,
15 0.0f, 0.0f, 1.0f, 1.0f,
16 0.0f, 1.0f, 1.0f, 0.5f,
18 float temp_data[4 * 6], out_data[4 * 6];
21 EffectChainTester tester(data, 1, 6, FORMAT_RGBA_POSTMULTIPLIED_ALPHA, COLORSPACE_sRGB, GAMMA_LINEAR);
22 tester.run(temp_data, GL_RGBA, COLORSPACE_REC_601_525, GAMMA_LINEAR);
25 EffectChainTester tester(temp_data, 1, 6, FORMAT_RGBA_POSTMULTIPLIED_ALPHA, COLORSPACE_REC_601_525, GAMMA_LINEAR);
26 tester.run(out_data, GL_RGBA, COLORSPACE_sRGB, GAMMA_LINEAR);
29 expect_equal(data, out_data, 4, 6);
32 TEST(ColorspaceConversionEffectTest, sRGB_Primaries) {
34 0.0f, 0.0f, 0.0f, 1.0f,
35 1.0f, 1.0f, 1.0f, 1.0f,
36 1.0f, 0.0f, 0.0f, 1.0f,
37 0.0f, 1.0f, 0.0f, 1.0f,
38 0.0f, 0.0f, 1.0f, 1.0f,
40 float out_data[4 * 5];
42 EffectChainTester tester(data, 1, 5, FORMAT_RGBA_POSTMULTIPLIED_ALPHA, COLORSPACE_sRGB, GAMMA_LINEAR);
43 tester.run(out_data, GL_RGBA, COLORSPACE_XYZ, GAMMA_LINEAR);
45 // Black should stay black.
46 EXPECT_FLOAT_EQ(0.0f, out_data[0 * 4 + 0]);
47 EXPECT_FLOAT_EQ(0.0f, out_data[0 * 4 + 1]);
48 EXPECT_FLOAT_EQ(0.0f, out_data[0 * 4 + 2]);
49 EXPECT_FLOAT_EQ(1.0f, out_data[0 * 4 + 3]);
51 // White point should be D65.
52 // XYZ values from http://en.wikipedia.org/wiki/CIE_Standard_Illuminant_D65.
53 EXPECT_NEAR(0.9505, out_data[1 * 4 + 0], 1e-3);
54 EXPECT_NEAR(1.0000, out_data[1 * 4 + 1], 1e-3);
55 EXPECT_NEAR(1.0889, out_data[1 * 4 + 2], 1e-3);
56 EXPECT_FLOAT_EQ(1.0f, out_data[1 * 4 + 3]);
58 float white_xyz_sum = out_data[1 * 4 + 0] + out_data[1 * 4 + 1] + out_data[1 * 4 + 2];
59 float white_x = out_data[1 * 4 + 0] / white_xyz_sum;
60 float white_y = out_data[1 * 4 + 1] / white_xyz_sum;
61 EXPECT_NEAR(0.3127, white_x, 1e-3);
62 EXPECT_NEAR(0.3290, white_y, 1e-3);
63 EXPECT_FLOAT_EQ(1.0f, out_data[1 * 4 + 3]);
65 // Convert the primaries from XYZ to xyz, and compare to the references
66 // given by Rec. 709 (which are shared with sRGB).
68 float red_xyz_sum = out_data[2 * 4 + 0] + out_data[2 * 4 + 1] + out_data[2 * 4 + 2];
69 float red_x = out_data[2 * 4 + 0] / red_xyz_sum;
70 float red_y = out_data[2 * 4 + 1] / red_xyz_sum;
71 EXPECT_NEAR(0.640, red_x, 1e-3);
72 EXPECT_NEAR(0.330, red_y, 1e-3);
73 EXPECT_FLOAT_EQ(1.0f, out_data[2 * 4 + 3]);
75 float green_xyz_sum = out_data[3 * 4 + 0] + out_data[3 * 4 + 1] + out_data[3 * 4 + 2];
76 float green_x = out_data[3 * 4 + 0] / green_xyz_sum;
77 float green_y = out_data[3 * 4 + 1] / green_xyz_sum;
78 EXPECT_NEAR(0.300, green_x, 1e-3);
79 EXPECT_NEAR(0.600, green_y, 1e-3);
80 EXPECT_FLOAT_EQ(1.0f, out_data[3 * 4 + 3]);
82 float blue_xyz_sum = out_data[4 * 4 + 0] + out_data[4 * 4 + 1] + out_data[4 * 4 + 2];
83 float blue_x = out_data[4 * 4 + 0] / blue_xyz_sum;
84 float blue_y = out_data[4 * 4 + 1] / blue_xyz_sum;
85 EXPECT_NEAR(0.150, blue_x, 1e-3);
86 EXPECT_NEAR(0.060, blue_y, 1e-3);
87 EXPECT_FLOAT_EQ(1.0f, out_data[4 * 4 + 3]);
90 TEST(ColorspaceConversionEffectTest, Rec601_525_Primaries) {
92 0.0f, 0.0f, 0.0f, 1.0f,
93 1.0f, 1.0f, 1.0f, 1.0f,
94 1.0f, 0.0f, 0.0f, 1.0f,
95 0.0f, 1.0f, 0.0f, 1.0f,
96 0.0f, 0.0f, 1.0f, 1.0f,
98 float out_data[4 * 5];
100 EffectChainTester tester(data, 1, 5, FORMAT_RGBA_POSTMULTIPLIED_ALPHA, COLORSPACE_REC_601_525, GAMMA_LINEAR);
101 tester.run(out_data, GL_RGBA, COLORSPACE_XYZ, GAMMA_LINEAR);
103 // Black should stay black.
104 EXPECT_FLOAT_EQ(0.0f, out_data[0 * 4 + 0]);
105 EXPECT_FLOAT_EQ(0.0f, out_data[0 * 4 + 1]);
106 EXPECT_FLOAT_EQ(0.0f, out_data[0 * 4 + 2]);
107 EXPECT_FLOAT_EQ(1.0f, out_data[0 * 4 + 3]);
109 // Convert the primaries from XYZ to xyz, and compare to the references
110 // given by Rec. 601.
111 float white_xyz_sum = out_data[1 * 4 + 0] + out_data[1 * 4 + 1] + out_data[1 * 4 + 2];
112 float white_x = out_data[1 * 4 + 0] / white_xyz_sum;
113 float white_y = out_data[1 * 4 + 1] / white_xyz_sum;
114 EXPECT_NEAR(0.3127, white_x, 1e-3);
115 EXPECT_NEAR(0.3290, white_y, 1e-3);
116 EXPECT_FLOAT_EQ(1.0f, out_data[1 * 4 + 3]);
118 float red_xyz_sum = out_data[2 * 4 + 0] + out_data[2 * 4 + 1] + out_data[2 * 4 + 2];
119 float red_x = out_data[2 * 4 + 0] / red_xyz_sum;
120 float red_y = out_data[2 * 4 + 1] / red_xyz_sum;
121 EXPECT_NEAR(0.630, red_x, 1e-3);
122 EXPECT_NEAR(0.340, red_y, 1e-3);
123 EXPECT_FLOAT_EQ(1.0f, out_data[2 * 4 + 3]);
125 float green_xyz_sum = out_data[3 * 4 + 0] + out_data[3 * 4 + 1] + out_data[3 * 4 + 2];
126 float green_x = out_data[3 * 4 + 0] / green_xyz_sum;
127 float green_y = out_data[3 * 4 + 1] / green_xyz_sum;
128 EXPECT_NEAR(0.310, green_x, 1e-3);
129 EXPECT_NEAR(0.595, green_y, 1e-3);
130 EXPECT_FLOAT_EQ(1.0f, out_data[3 * 4 + 3]);
132 float blue_xyz_sum = out_data[4 * 4 + 0] + out_data[4 * 4 + 1] + out_data[4 * 4 + 2];
133 float blue_x = out_data[4 * 4 + 0] / blue_xyz_sum;
134 float blue_y = out_data[4 * 4 + 1] / blue_xyz_sum;
135 EXPECT_NEAR(0.155, blue_x, 1e-3);
136 EXPECT_NEAR(0.070, blue_y, 1e-3);
137 EXPECT_FLOAT_EQ(1.0f, out_data[4 * 4 + 3]);
140 TEST(ColorspaceConversionEffectTest, Rec601_625_Primaries) {
142 0.0f, 0.0f, 0.0f, 1.0f,
143 1.0f, 1.0f, 1.0f, 1.0f,
144 1.0f, 0.0f, 0.0f, 1.0f,
145 0.0f, 1.0f, 0.0f, 1.0f,
146 0.0f, 0.0f, 1.0f, 1.0f,
148 float out_data[4 * 5];
150 EffectChainTester tester(data, 1, 5, FORMAT_RGBA_POSTMULTIPLIED_ALPHA, COLORSPACE_REC_601_625, GAMMA_LINEAR);
151 tester.run(out_data, GL_RGBA, COLORSPACE_XYZ, GAMMA_LINEAR);
153 // Black should stay black.
154 EXPECT_FLOAT_EQ(0.0f, out_data[0 * 4 + 0]);
155 EXPECT_FLOAT_EQ(0.0f, out_data[0 * 4 + 1]);
156 EXPECT_FLOAT_EQ(0.0f, out_data[0 * 4 + 2]);
157 EXPECT_FLOAT_EQ(1.0f, out_data[0 * 4 + 3]);
159 // Convert the primaries from XYZ to xyz, and compare to the references
160 // given by Rec. 601.
161 float white_xyz_sum = out_data[1 * 4 + 0] + out_data[1 * 4 + 1] + out_data[1 * 4 + 2];
162 float white_x = out_data[1 * 4 + 0] / white_xyz_sum;
163 float white_y = out_data[1 * 4 + 1] / white_xyz_sum;
164 EXPECT_NEAR(0.3127, white_x, 1e-3);
165 EXPECT_NEAR(0.3290, white_y, 1e-3);
166 EXPECT_FLOAT_EQ(1.0f, out_data[1 * 4 + 3]);
168 float red_xyz_sum = out_data[2 * 4 + 0] + out_data[2 * 4 + 1] + out_data[2 * 4 + 2];
169 float red_x = out_data[2 * 4 + 0] / red_xyz_sum;
170 float red_y = out_data[2 * 4 + 1] / red_xyz_sum;
171 EXPECT_NEAR(0.640, red_x, 1e-3);
172 EXPECT_NEAR(0.330, red_y, 1e-3);
173 EXPECT_FLOAT_EQ(1.0f, out_data[2 * 4 + 3]);
175 float green_xyz_sum = out_data[3 * 4 + 0] + out_data[3 * 4 + 1] + out_data[3 * 4 + 2];
176 float green_x = out_data[3 * 4 + 0] / green_xyz_sum;
177 float green_y = out_data[3 * 4 + 1] / green_xyz_sum;
178 EXPECT_NEAR(0.290, green_x, 1e-3);
179 EXPECT_NEAR(0.600, green_y, 1e-3);
180 EXPECT_FLOAT_EQ(1.0f, out_data[3 * 4 + 3]);
182 float blue_xyz_sum = out_data[4 * 4 + 0] + out_data[4 * 4 + 1] + out_data[4 * 4 + 2];
183 float blue_x = out_data[4 * 4 + 0] / blue_xyz_sum;
184 float blue_y = out_data[4 * 4 + 1] / blue_xyz_sum;
185 EXPECT_NEAR(0.150, blue_x, 1e-3);
186 EXPECT_NEAR(0.060, blue_y, 1e-3);
187 EXPECT_FLOAT_EQ(1.0f, out_data[4 * 4 + 3]);
190 TEST(ColorspaceConversionEffectTest, sRGBToRec601_525) {
192 0.0f, 0.0f, 0.0f, 1.0f,
193 1.0f, 1.0f, 1.0f, 1.0f,
194 1.0f, 0.0f, 0.0f, 1.0f,
195 0.0f, 1.0f, 0.0f, 1.0f,
196 0.0f, 0.0f, 1.0f, 1.0f,
197 0.0f, 1.0f, 1.0f, 0.5f,
200 // I have to admit that most of these come from the code itself;
201 // however, they do make sense if you look at the two gamuts
203 float expected_data[] = {
204 // Black should stay black.
205 0.0f, 0.0f, 0.0f, 1.0f,
207 // White should stay white (both use the D65 white point).
208 1.0f, 1.0f, 1.0f, 1.0f,
210 // sRGB red is slightly out-of-gamut for Rec. 601/525.
211 1.064f, -0.020f, 0.0f, 1.0f,
214 -0.055f, 1.036f, 0.004f, 1.0f,
216 // The blues are much closer; it _is_ still out-of-gamut,
217 // but not actually more saturated (farther from the
219 -0.010f, -0.017f, 0.994f, 1.0f,
221 // Cyan is a mix of green and blue. Note: The alpha is kept.
222 -0.065f, 1.0195f, 0.998f, 0.5f,
224 float out_data[4 * 6];
226 EffectChainTester tester(data, 1, 6, FORMAT_RGBA_POSTMULTIPLIED_ALPHA, COLORSPACE_sRGB, GAMMA_LINEAR);
227 tester.run(out_data, GL_RGBA, COLORSPACE_REC_601_525, GAMMA_LINEAR);
229 expect_equal(expected_data, out_data, 4, 6);