1 // Unit tests for ColorspaceConversionEffect.
4 #include "gtest/gtest.h"
5 #include "colorspace_conversion_effect.h"
7 TEST(ColorspaceConversionEffectTest, Reversible) {
9 0.0f, 0.0f, 0.0f, 1.0f,
10 1.0f, 1.0f, 1.0f, 1.0f,
11 1.0f, 0.0f, 0.0f, 1.0f,
12 0.0f, 1.0f, 0.0f, 1.0f,
13 0.0f, 0.0f, 1.0f, 1.0f,
14 0.0f, 1.0f, 1.0f, 0.5f,
16 float temp_data[4 * 6], out_data[4 * 6];
19 EffectChainTester tester(data, 1, 6, FORMAT_RGBA_POSTMULTIPLIED_ALPHA, COLORSPACE_sRGB, GAMMA_LINEAR);
20 tester.run(temp_data, GL_RGBA, COLORSPACE_REC_601_525, GAMMA_LINEAR);
23 EffectChainTester tester(temp_data, 1, 6, FORMAT_RGBA_POSTMULTIPLIED_ALPHA, COLORSPACE_REC_601_525, GAMMA_LINEAR);
24 tester.run(out_data, GL_RGBA, COLORSPACE_sRGB, GAMMA_LINEAR);
27 expect_equal(data, out_data, 4, 6);
30 TEST(ColorspaceConversionEffectTest, sRGB_Primaries) {
32 0.0f, 0.0f, 0.0f, 1.0f,
33 1.0f, 1.0f, 1.0f, 1.0f,
34 1.0f, 0.0f, 0.0f, 1.0f,
35 0.0f, 1.0f, 0.0f, 1.0f,
36 0.0f, 0.0f, 1.0f, 1.0f,
38 float out_data[4 * 5];
40 EffectChainTester tester(data, 1, 5, FORMAT_RGBA_POSTMULTIPLIED_ALPHA, COLORSPACE_sRGB, GAMMA_LINEAR);
41 tester.run(out_data, GL_RGBA, COLORSPACE_XYZ, GAMMA_LINEAR);
43 // Black should stay black.
44 EXPECT_FLOAT_EQ(0.0f, out_data[0 * 4 + 0]);
45 EXPECT_FLOAT_EQ(0.0f, out_data[0 * 4 + 1]);
46 EXPECT_FLOAT_EQ(0.0f, out_data[0 * 4 + 2]);
47 EXPECT_FLOAT_EQ(1.0f, out_data[0 * 4 + 3]);
49 // White point should be D65.
50 // XYZ values from http://en.wikipedia.org/wiki/CIE_Standard_Illuminant_D65.
51 EXPECT_NEAR(0.9505, out_data[1 * 4 + 0], 1e-3);
52 EXPECT_NEAR(1.0000, out_data[1 * 4 + 1], 1e-3);
53 EXPECT_NEAR(1.0889, out_data[1 * 4 + 2], 1e-3);
54 EXPECT_FLOAT_EQ(1.0f, out_data[1 * 4 + 3]);
56 float white_xyz_sum = out_data[1 * 4 + 0] + out_data[1 * 4 + 1] + out_data[1 * 4 + 2];
57 float white_x = out_data[1 * 4 + 0] / white_xyz_sum;
58 float white_y = out_data[1 * 4 + 1] / white_xyz_sum;
59 EXPECT_NEAR(0.3127, white_x, 1e-3);
60 EXPECT_NEAR(0.3290, white_y, 1e-3);
61 EXPECT_FLOAT_EQ(1.0f, out_data[1 * 4 + 3]);
63 // Convert the primaries from XYZ to xyz, and compare to the references
64 // given by Rec. 709 (which are shared with sRGB).
66 float red_xyz_sum = out_data[2 * 4 + 0] + out_data[2 * 4 + 1] + out_data[2 * 4 + 2];
67 float red_x = out_data[2 * 4 + 0] / red_xyz_sum;
68 float red_y = out_data[2 * 4 + 1] / red_xyz_sum;
69 EXPECT_NEAR(0.640, red_x, 1e-3);
70 EXPECT_NEAR(0.330, red_y, 1e-3);
71 EXPECT_FLOAT_EQ(1.0f, out_data[2 * 4 + 3]);
73 float green_xyz_sum = out_data[3 * 4 + 0] + out_data[3 * 4 + 1] + out_data[3 * 4 + 2];
74 float green_x = out_data[3 * 4 + 0] / green_xyz_sum;
75 float green_y = out_data[3 * 4 + 1] / green_xyz_sum;
76 EXPECT_NEAR(0.300, green_x, 1e-3);
77 EXPECT_NEAR(0.600, green_y, 1e-3);
78 EXPECT_FLOAT_EQ(1.0f, out_data[3 * 4 + 3]);
80 float blue_xyz_sum = out_data[4 * 4 + 0] + out_data[4 * 4 + 1] + out_data[4 * 4 + 2];
81 float blue_x = out_data[4 * 4 + 0] / blue_xyz_sum;
82 float blue_y = out_data[4 * 4 + 1] / blue_xyz_sum;
83 EXPECT_NEAR(0.150, blue_x, 1e-3);
84 EXPECT_NEAR(0.060, blue_y, 1e-3);
85 EXPECT_FLOAT_EQ(1.0f, out_data[4 * 4 + 3]);
88 TEST(ColorspaceConversionEffectTest, Rec601_525_Primaries) {
90 0.0f, 0.0f, 0.0f, 1.0f,
91 1.0f, 1.0f, 1.0f, 1.0f,
92 1.0f, 0.0f, 0.0f, 1.0f,
93 0.0f, 1.0f, 0.0f, 1.0f,
94 0.0f, 0.0f, 1.0f, 1.0f,
96 float out_data[4 * 5];
98 EffectChainTester tester(data, 1, 5, FORMAT_RGBA_POSTMULTIPLIED_ALPHA, COLORSPACE_REC_601_525, GAMMA_LINEAR);
99 tester.run(out_data, GL_RGBA, COLORSPACE_XYZ, GAMMA_LINEAR);
101 // Black should stay black.
102 EXPECT_FLOAT_EQ(0.0f, out_data[0 * 4 + 0]);
103 EXPECT_FLOAT_EQ(0.0f, out_data[0 * 4 + 1]);
104 EXPECT_FLOAT_EQ(0.0f, out_data[0 * 4 + 2]);
105 EXPECT_FLOAT_EQ(1.0f, out_data[0 * 4 + 3]);
107 // Convert the primaries from XYZ to xyz, and compare to the references
108 // given by Rec. 601.
109 float white_xyz_sum = out_data[1 * 4 + 0] + out_data[1 * 4 + 1] + out_data[1 * 4 + 2];
110 float white_x = out_data[1 * 4 + 0] / white_xyz_sum;
111 float white_y = out_data[1 * 4 + 1] / white_xyz_sum;
112 EXPECT_NEAR(0.3127, white_x, 1e-3);
113 EXPECT_NEAR(0.3290, white_y, 1e-3);
114 EXPECT_FLOAT_EQ(1.0f, out_data[1 * 4 + 3]);
116 float red_xyz_sum = out_data[2 * 4 + 0] + out_data[2 * 4 + 1] + out_data[2 * 4 + 2];
117 float red_x = out_data[2 * 4 + 0] / red_xyz_sum;
118 float red_y = out_data[2 * 4 + 1] / red_xyz_sum;
119 EXPECT_NEAR(0.630, red_x, 1e-3);
120 EXPECT_NEAR(0.340, red_y, 1e-3);
121 EXPECT_FLOAT_EQ(1.0f, out_data[2 * 4 + 3]);
123 float green_xyz_sum = out_data[3 * 4 + 0] + out_data[3 * 4 + 1] + out_data[3 * 4 + 2];
124 float green_x = out_data[3 * 4 + 0] / green_xyz_sum;
125 float green_y = out_data[3 * 4 + 1] / green_xyz_sum;
126 EXPECT_NEAR(0.310, green_x, 1e-3);
127 EXPECT_NEAR(0.595, green_y, 1e-3);
128 EXPECT_FLOAT_EQ(1.0f, out_data[3 * 4 + 3]);
130 float blue_xyz_sum = out_data[4 * 4 + 0] + out_data[4 * 4 + 1] + out_data[4 * 4 + 2];
131 float blue_x = out_data[4 * 4 + 0] / blue_xyz_sum;
132 float blue_y = out_data[4 * 4 + 1] / blue_xyz_sum;
133 EXPECT_NEAR(0.155, blue_x, 1e-3);
134 EXPECT_NEAR(0.070, blue_y, 1e-3);
135 EXPECT_FLOAT_EQ(1.0f, out_data[4 * 4 + 3]);
138 TEST(ColorspaceConversionEffectTest, Rec601_625_Primaries) {
140 0.0f, 0.0f, 0.0f, 1.0f,
141 1.0f, 1.0f, 1.0f, 1.0f,
142 1.0f, 0.0f, 0.0f, 1.0f,
143 0.0f, 1.0f, 0.0f, 1.0f,
144 0.0f, 0.0f, 1.0f, 1.0f,
146 float out_data[4 * 5];
148 EffectChainTester tester(data, 1, 5, FORMAT_RGBA_POSTMULTIPLIED_ALPHA, COLORSPACE_REC_601_625, GAMMA_LINEAR);
149 tester.run(out_data, GL_RGBA, COLORSPACE_XYZ, GAMMA_LINEAR);
151 // Black should stay black.
152 EXPECT_FLOAT_EQ(0.0f, out_data[0 * 4 + 0]);
153 EXPECT_FLOAT_EQ(0.0f, out_data[0 * 4 + 1]);
154 EXPECT_FLOAT_EQ(0.0f, out_data[0 * 4 + 2]);
155 EXPECT_FLOAT_EQ(1.0f, out_data[0 * 4 + 3]);
157 // Convert the primaries from XYZ to xyz, and compare to the references
158 // given by Rec. 601.
159 float white_xyz_sum = out_data[1 * 4 + 0] + out_data[1 * 4 + 1] + out_data[1 * 4 + 2];
160 float white_x = out_data[1 * 4 + 0] / white_xyz_sum;
161 float white_y = out_data[1 * 4 + 1] / white_xyz_sum;
162 EXPECT_NEAR(0.3127, white_x, 1e-3);
163 EXPECT_NEAR(0.3290, white_y, 1e-3);
164 EXPECT_FLOAT_EQ(1.0f, out_data[1 * 4 + 3]);
166 float red_xyz_sum = out_data[2 * 4 + 0] + out_data[2 * 4 + 1] + out_data[2 * 4 + 2];
167 float red_x = out_data[2 * 4 + 0] / red_xyz_sum;
168 float red_y = out_data[2 * 4 + 1] / red_xyz_sum;
169 EXPECT_NEAR(0.640, red_x, 1e-3);
170 EXPECT_NEAR(0.330, red_y, 1e-3);
171 EXPECT_FLOAT_EQ(1.0f, out_data[2 * 4 + 3]);
173 float green_xyz_sum = out_data[3 * 4 + 0] + out_data[3 * 4 + 1] + out_data[3 * 4 + 2];
174 float green_x = out_data[3 * 4 + 0] / green_xyz_sum;
175 float green_y = out_data[3 * 4 + 1] / green_xyz_sum;
176 EXPECT_NEAR(0.290, green_x, 1e-3);
177 EXPECT_NEAR(0.600, green_y, 1e-3);
178 EXPECT_FLOAT_EQ(1.0f, out_data[3 * 4 + 3]);
180 float blue_xyz_sum = out_data[4 * 4 + 0] + out_data[4 * 4 + 1] + out_data[4 * 4 + 2];
181 float blue_x = out_data[4 * 4 + 0] / blue_xyz_sum;
182 float blue_y = out_data[4 * 4 + 1] / blue_xyz_sum;
183 EXPECT_NEAR(0.150, blue_x, 1e-3);
184 EXPECT_NEAR(0.060, blue_y, 1e-3);
185 EXPECT_FLOAT_EQ(1.0f, out_data[4 * 4 + 3]);
188 TEST(ColorspaceConversionEffectTest, sRGBToRec601_525) {
190 0.0f, 0.0f, 0.0f, 1.0f,
191 1.0f, 1.0f, 1.0f, 1.0f,
192 1.0f, 0.0f, 0.0f, 1.0f,
193 0.0f, 1.0f, 0.0f, 1.0f,
194 0.0f, 0.0f, 1.0f, 1.0f,
195 0.0f, 1.0f, 1.0f, 0.5f,
198 // I have to admit that most of these come from the code itself;
199 // however, they do make sense if you look at the two gamuts
201 float expected_data[] = {
202 // Black should stay black.
203 0.0f, 0.0f, 0.0f, 1.0f,
205 // White should stay white (both use the D65 white point).
206 1.0f, 1.0f, 1.0f, 1.0f,
208 // sRGB red is slightly out-of-gamut for Rec. 601/525.
209 1.064f, -0.020f, 0.0f, 1.0f,
212 -0.055f, 1.036f, 0.004f, 1.0f,
214 // The blues are much closer; it _is_ still out-of-gamut,
215 // but not actually more saturated (farther from the
217 -0.010f, -0.017f, 0.994f, 1.0f,
219 // Cyan is a mix of green and blue. Note: The alpha is kept.
220 -0.065f, 1.0195f, 0.998f, 0.5f,
222 float out_data[4 * 6];
224 EffectChainTester tester(data, 1, 6, FORMAT_RGBA_POSTMULTIPLIED_ALPHA, COLORSPACE_sRGB, GAMMA_LINEAR);
225 tester.run(out_data, GL_RGBA, COLORSPACE_REC_601_525, GAMMA_LINEAR);
227 expect_equal(expected_data, out_data, 4, 6);