1 // Unit tests for YCbCrConversionEffect. Mostly done by leveraging
2 // YCbCrInput and seeing that the right thing comes out at the
8 #include "effect_chain.h"
9 #include "gtest/gtest.h"
10 #include "image_format.h"
11 #include "test_util.h"
13 #include "ycbcr_input.h"
17 TEST(YCbCrConversionEffectTest, BasicInOut) {
21 // Pure-color test inputs, calculated with the formulas in Rec. 601
23 unsigned char y[width * height] = {
26 unsigned char cb[width * height] = {
27 128, 128, 90, 54, 240,
29 unsigned char cr[width * height] = {
30 128, 128, 240, 34, 110,
32 unsigned char expected_data[width * height * 4] = {
33 // The same data, just rearranged.
41 unsigned char out_data[width * height * 4];
43 EffectChainTester tester(NULL, width, height);
46 format.color_space = COLORSPACE_sRGB;
47 format.gamma_curve = GAMMA_sRGB;
49 YCbCrFormat ycbcr_format;
50 ycbcr_format.luma_coefficients = YCBCR_REC_601;
51 ycbcr_format.full_range = false;
52 ycbcr_format.num_levels = 256;
53 ycbcr_format.chroma_subsampling_x = 1;
54 ycbcr_format.chroma_subsampling_y = 1;
55 ycbcr_format.cb_x_position = 0.5f;
56 ycbcr_format.cb_y_position = 0.5f;
57 ycbcr_format.cr_x_position = 0.5f;
58 ycbcr_format.cr_y_position = 0.5f;
60 tester.add_ycbcr_output(format, OUTPUT_ALPHA_FORMAT_POSTMULTIPLIED, ycbcr_format);
62 YCbCrInput *input = new YCbCrInput(format, ycbcr_format, width, height);
63 input->set_pixel_data(0, y);
64 input->set_pixel_data(1, cb);
65 input->set_pixel_data(2, cr);
66 tester.get_chain()->add_input(input);
68 tester.run(out_data, GL_RGBA, COLORSPACE_sRGB, GAMMA_sRGB);
69 expect_equal(expected_data, out_data, 4 * width, height);
72 TEST(YCbCrConversionEffectTest, ClampToValidRange) {
76 // Some out-of-range of at-range values.
77 // Y should be clamped to 16-235 and Cb/Cr to 16-240.
78 // (Alpha should still be 255.)
79 unsigned char y[width * height] = {
80 0, 10, 16, 235, 240, 255
82 unsigned char cb[width * height] = {
83 0, 10, 16, 235, 240, 255,
85 unsigned char cr[width * height] = {
86 255, 240, 235, 16, 10, 0,
88 unsigned char expected_data[width * height * 4] = {
97 unsigned char out_data[width * height * 4];
99 EffectChainTester tester(NULL, width, height);
102 format.color_space = COLORSPACE_sRGB;
103 format.gamma_curve = GAMMA_sRGB;
105 YCbCrFormat ycbcr_format;
106 ycbcr_format.luma_coefficients = YCBCR_REC_601;
107 ycbcr_format.full_range = false;
108 ycbcr_format.num_levels = 256;
109 ycbcr_format.chroma_subsampling_x = 1;
110 ycbcr_format.chroma_subsampling_y = 1;
111 ycbcr_format.cb_x_position = 0.5f;
112 ycbcr_format.cb_y_position = 0.5f;
113 ycbcr_format.cr_x_position = 0.5f;
114 ycbcr_format.cr_y_position = 0.5f;
116 tester.add_ycbcr_output(format, OUTPUT_ALPHA_FORMAT_POSTMULTIPLIED, ycbcr_format);
118 YCbCrInput *input = new YCbCrInput(format, ycbcr_format, width, height);
119 input->set_pixel_data(0, y);
120 input->set_pixel_data(1, cb);
121 input->set_pixel_data(2, cr);
122 tester.get_chain()->add_input(input);
124 tester.run(out_data, GL_RGBA, COLORSPACE_sRGB, GAMMA_sRGB);
125 expect_equal(expected_data, out_data, 4 * width, height);
128 TEST(YCbCrConversionEffectTest, LimitedRangeToFullRange) {
130 const int height = 5;
132 // Pure-color test inputs, calculated with the formulas in Rec. 601
134 unsigned char y[width * height] = {
135 16, 235, 81, 145, 41,
137 unsigned char cb[width * height] = {
138 128, 128, 90, 54, 240,
140 unsigned char cr[width * height] = {
141 128, 128, 240, 34, 110,
143 unsigned char expected_data[width * height * 4] = {
144 // Range now from 0-255 for all components, and values in-between
145 // also adjusted a bit.
153 unsigned char out_data[width * height * 4];
155 EffectChainTester tester(NULL, width, height);
158 format.color_space = COLORSPACE_sRGB;
159 format.gamma_curve = GAMMA_sRGB;
161 YCbCrFormat ycbcr_format;
162 ycbcr_format.luma_coefficients = YCBCR_REC_601;
163 ycbcr_format.full_range = true;
164 ycbcr_format.num_levels = 256;
165 ycbcr_format.chroma_subsampling_x = 1;
166 ycbcr_format.chroma_subsampling_y = 1;
167 ycbcr_format.cb_x_position = 0.5f;
168 ycbcr_format.cb_y_position = 0.5f;
169 ycbcr_format.cr_x_position = 0.5f;
170 ycbcr_format.cr_y_position = 0.5f;
172 tester.add_ycbcr_output(format, OUTPUT_ALPHA_FORMAT_POSTMULTIPLIED, ycbcr_format);
174 ycbcr_format.full_range = false;
175 YCbCrInput *input = new YCbCrInput(format, ycbcr_format, width, height);
176 input->set_pixel_data(0, y);
177 input->set_pixel_data(1, cb);
178 input->set_pixel_data(2, cr);
179 tester.get_chain()->add_input(input);
181 tester.run(out_data, GL_RGBA, COLORSPACE_sRGB, GAMMA_sRGB);
182 expect_equal(expected_data, out_data, 4 * width, height);