TEST(FlatInput, UpdatedData) { const int width = 2; const int height = 4; float data[width * height] = { 0.0, 1.0, 0.5, 0.5, 0.7, 0.2, 1.0, 0.6, }; float out_data[width * height]; EffectChainTester tester(NULL, width, height); ImageFormat format; format.color_space = COLORSPACE_sRGB; format.gamma_curve = GAMMA_LINEAR; FlatInput *input = new FlatInput(format, FORMAT_GRAYSCALE, GL_FLOAT, width, height); input->set_pixel_data(data); tester.get_chain()->add_input(input); tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR); expect_equal(data, out_data, width, height); data[6] = 0.3; input->invalidate_pixel_data(); tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR); expect_equal(data, out_data, width, height); }
/* Test that data values are written and read with proper alignment. */ static void test_alignment(void) { void *ctx = ralloc_context(NULL); struct blob *blob; struct blob_reader reader; uint8_t bytes[] = "ABCDEFGHIJKLMNOP"; size_t delta, last, num_bytes; blob = blob_create(ctx); /* First, write an intptr value to the blob and capture that size. This is * the expected offset between any pair of intptr values (if written with * alignment). */ blob_write_intptr(blob, (intptr_t) blob); delta = blob->size; last = blob->size; /* Then loop doing the following: * * 1. Write an unaligned number of bytes * 2. Verify that write results in an unaligned size * 3. Write an intptr_t value * 2. Verify that that write results in an aligned size */ for (num_bytes = 1; num_bytes < sizeof(intptr_t); num_bytes++) { blob_write_bytes(blob, bytes, num_bytes); expect_unequal(delta, blob->size - last, "unaligned write of bytes"); blob_write_intptr(blob, (intptr_t) blob); expect_equal(2 * delta, blob->size - last, "aligned write of intptr"); last = blob->size; } /* Finally, test that reading also does proper alignment. Since we know * that values were written with all the right alignment, all we have to do * here is verify that correct values are read. */ blob_reader_init(&reader, blob->data, blob->size); expect_equal((intptr_t) blob, blob_read_intptr(&reader), "read of initial, aligned intptr_t"); for (num_bytes = 1; num_bytes < sizeof(intptr_t); num_bytes++) { expect_equal_bytes(bytes, blob_read_bytes(&reader, num_bytes), num_bytes, "unaligned read of bytes"); expect_equal((intptr_t) blob, blob_read_intptr(&reader), "aligned read of intptr_t"); } ralloc_free(ctx); }
void jtl::consume_group::test<4>() /* copy */ { jtl::reset(); std::vector<jtl::tracked_copy> in(6); std::vector<jtl::tracked_eater<jtl::tracked_copy>> out(3); jtl::algorithm::consume_copy<2>(std::begin(in), std::end(in), std::begin(out)); /* First copied into their new home, then that home is copied into the vector. */ expect_equal(jtl::tracked_copy::count, 12ul); expect_equal(jtl::tracked_move::count, 0ul); }
void jtl::consume_group::test<0>() /* vector -> vector */ { std::vector<int> in{ 0, 1, 2, 3, 4, 5 }; std::vector<std::vector<int>> out(3); jtl::algorithm::consume<2>(std::begin(in), std::end(in), std::begin(out)); for(int i{}; i < 3; ++i) { expect_equal(out[i].size(), 2ul); expect_equal(out[i][0], i * 2); expect_equal(out[i][1], (i * 2) + 1); } }
void jtl::consume_group::test<1>() /* vector -> vector (push_back) */ { std::vector<int> in{ 0, 1, 2, 3, 4, 5 }; std::vector<std::vector<int>> out; jtl::algorithm::consume<2>(std::begin(in), std::end(in), jtl::iterator::back_inserter(out)); for(int i{}; i < 3; ++i) { expect_equal(out[i].size(), 2ul); expect_equal(out[i][0], i * 2); expect_equal(out[i][1], (i * 2) + 1); } }
void jtl::consume_group::test<2>() /* aggregate */ { struct name { std::string first, last; }; std::stringstream ss{ "john|doe|peter|parker" }; std::vector<name> names; jtl::algorithm::consume<2>(jtl::iterator::stream_delim<>{ ss, '|' }, jtl::iterator::stream_delim<>{}, jtl::iterator::back_inserter(names)); expect_equal(names[0].first, "john"); expect_equal(names[0].last, "doe"); expect_equal(names[1].first, "peter"); expect_equal(names[1].last, "parker"); }
void ex_1_group::test<1>() { int const i{}; float const f{ 3.14 }; float const f2{ f * 2.0f }; expect_equal(i, f, f2); }
TEST(PaddingEffectTest, BorderColorIsInLinearGamma) { float data[4 * 1] = { 0.2f, 0.4f, 0.6f, 0.8f, }; float expected_data[4 * 2] = { 0.5005, 0.7051, 0.8677, 0.7998, // Pixel from data[]. 0.5005, 0.7051, 0.8677, 0.7998, // Pixel from the border color. }; float out_data[4 * 2]; EffectChainTester tester(NULL, 1, 2); ImageFormat format; format.color_space = COLORSPACE_sRGB; format.gamma_curve = GAMMA_LINEAR; FlatInput *input = new FlatInput(format, FORMAT_RGBA_PREMULTIPLIED_ALPHA, GL_FLOAT, 1, 1); input->set_pixel_data(data); tester.get_chain()->add_input(input); Effect *effect = tester.get_chain()->add_effect(new PaddingEffect()); CHECK(effect->set_int("width", 1)); CHECK(effect->set_int("height", 2)); CHECK(effect->set_float("left", 0.0f)); CHECK(effect->set_float("top", 0.0f)); RGBATuple border_color(0.2f, 0.4f, 0.6f, 0.8f); // Same as the pixel in data[]. CHECK(effect->set_vec4("border_color", (float *)&border_color)); tester.run(out_data, GL_RGBA, COLORSPACE_REC_601_625, GAMMA_REC_601, OUTPUT_ALPHA_FORMAT_POSTMULTIPLIED); expect_equal(expected_data, out_data, 4, 2); }
TEST(PaddingEffectTest, WhiteBorderColor) { float data[2 * 2] = { 1.0f, 0.5f, 0.8f, 0.3f, }; float expected_data[4 * 4] = { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f, 1.0f, 1.0f, 0.8f, 0.3f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, }; float out_data[4 * 4]; EffectChainTester tester(NULL, 4, 4); ImageFormat format; format.color_space = COLORSPACE_sRGB; format.gamma_curve = GAMMA_LINEAR; FlatInput *input = new FlatInput(format, FORMAT_GRAYSCALE, GL_FLOAT, 2, 2); input->set_pixel_data(data); tester.get_chain()->add_input(input); Effect *effect = tester.get_chain()->add_effect(new PaddingEffect()); CHECK(effect->set_int("width", 4)); CHECK(effect->set_int("height", 4)); CHECK(effect->set_float("left", 1.0f)); CHECK(effect->set_float("top", 1.0f)); RGBATuple border_color(1.0f, 1.0f, 1.0f, 1.0f); CHECK(effect->set_vec4("border_color", (float *)&border_color)); tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR, OUTPUT_ALPHA_FORMAT_PREMULTIPLIED); expect_equal(expected_data, out_data, 4, 4); }
TEST(PaddingEffectTest, BorderOffsetLeftAndRight) { float data[3 * 2] = { 1.0f, 0.5f, 0.6f, 0.8f, 0.3f, 0.2f, }; float expected_data[4 * 2] = { 0.750f, 0.5f, 0.3f, 0.0f, 0.600f, 0.3f, 0.1f, 0.0f }; float out_data[4 * 2]; EffectChainTester tester(NULL, 4, 2); ImageFormat format; format.color_space = COLORSPACE_sRGB; format.gamma_curve = GAMMA_LINEAR; FlatInput *input = new FlatInput(format, FORMAT_GRAYSCALE, GL_FLOAT, 3, 2); input->set_pixel_data(data); tester.get_chain()->add_input(input); Effect *effect = tester.get_chain()->add_effect(new PaddingEffect()); CHECK(effect->set_int("width", 4)); CHECK(effect->set_int("height", 2)); CHECK(effect->set_float("left", 0.0f)); CHECK(effect->set_float("top", 0.0f)); CHECK(effect->set_float("border_offset_left", 0.25f)); CHECK(effect->set_float("border_offset_right", -0.5f)); tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR, OUTPUT_ALPHA_FORMAT_PREMULTIPLIED); expect_equal(expected_data, out_data, 4, 2); }
TEST(PaddingEffectTest, BorderOffsetTopAndBottom) { float data[2 * 2] = { 1.0f, 0.5f, 0.8f, 0.3f, }; float expected_data[4 * 4] = { 0.0f, 0.000f, 0.000f, 0.0f, 0.0f, 0.750f, 0.375f, 0.0f, 0.0f, 0.800f, 0.300f, 0.0f, 0.0f, 0.200f, 0.075f, 0.0f, // Repeated pixels, 25% opacity. }; float out_data[4 * 4]; EffectChainTester tester(NULL, 4, 4); ImageFormat format; format.color_space = COLORSPACE_sRGB; format.gamma_curve = GAMMA_LINEAR; FlatInput *input = new FlatInput(format, FORMAT_GRAYSCALE, GL_FLOAT, 2, 2); input->set_pixel_data(data); tester.get_chain()->add_input(input); Effect *effect = tester.get_chain()->add_effect(new PaddingEffect()); CHECK(effect->set_int("width", 4)); CHECK(effect->set_int("height", 4)); CHECK(effect->set_float("left", 1.0f)); CHECK(effect->set_float("top", 1.0f)); CHECK(effect->set_float("border_offset_top", 0.25f)); CHECK(effect->set_float("border_offset_bottom", 0.25f)); tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR, OUTPUT_ALPHA_FORMAT_PREMULTIPLIED); expect_equal(expected_data, out_data, 4, 4); }
TEST(PaddingEffectTest, AlphaIsCorrectEvenWithNonLinearInputsAndOutputs) { float data[2 * 1] = { 1.0f, 0.8f, }; float expected_data[4 * 4] = { 1.0f, 1.0f, 1.0f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.8f, 0.8f, 0.8f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f, }; float out_data[4 * 4]; EffectChainTester tester(NULL, 1, 4); ImageFormat format; format.color_space = COLORSPACE_REC_601_625; format.gamma_curve = GAMMA_REC_709; FlatInput *input = new FlatInput(format, FORMAT_GRAYSCALE, GL_FLOAT, 1, 2); input->set_pixel_data(data); tester.get_chain()->add_input(input); Effect *effect = tester.get_chain()->add_effect(new PaddingEffect()); CHECK(effect->set_int("width", 1)); CHECK(effect->set_int("height", 4)); CHECK(effect->set_float("left", 0.0f)); CHECK(effect->set_float("top", 1.0f)); RGBATuple border_color(1.0f, 1.0f, 1.0f, 0.5f); CHECK(effect->set_vec4("border_color", (float *)&border_color)); tester.run(out_data, GL_RGBA, COLORSPACE_REC_601_625, GAMMA_REC_709, OUTPUT_ALPHA_FORMAT_POSTMULTIPLIED); expect_equal(expected_data, out_data, 4, 4); }
TEST(PaddingEffectTest, NonIntegerOffset) { float data[4 * 1] = { 0.25f, 0.50f, 0.75f, 1.0f, }; float expected_data[5 * 2] = { 0.1875f, 0.4375f, 0.6875f, 0.9375f, 0.25f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, }; float out_data[5 * 2]; EffectChainTester tester(NULL, 5, 2); ImageFormat format; format.color_space = COLORSPACE_sRGB; format.gamma_curve = GAMMA_LINEAR; FlatInput *input = new FlatInput(format, FORMAT_GRAYSCALE, GL_FLOAT, 4, 1); input->set_pixel_data(data); tester.get_chain()->add_input(input); Effect *effect = tester.get_chain()->add_effect(new PaddingEffect()); CHECK(effect->set_int("width", 5)); CHECK(effect->set_int("height", 2)); CHECK(effect->set_float("left", 0.25f)); CHECK(effect->set_float("top", 0.0f)); tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR, OUTPUT_ALPHA_FORMAT_PREMULTIPLIED); expect_equal(expected_data, out_data, 5, 2); }
TEST(PaddingEffectTest, DifferentXAndYOffset) { float data[1 * 1] = { 1.0f }; float expected_data[3 * 3] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, }; float out_data[3 * 3]; EffectChainTester tester(NULL, 3, 3); ImageFormat format; format.color_space = COLORSPACE_sRGB; format.gamma_curve = GAMMA_LINEAR; FlatInput *input = new FlatInput(format, FORMAT_GRAYSCALE, GL_FLOAT, 1, 1); input->set_pixel_data(data); tester.get_chain()->add_input(input); Effect *effect = tester.get_chain()->add_effect(new PaddingEffect()); CHECK(effect->set_int("width", 3)); CHECK(effect->set_int("height", 3)); CHECK(effect->set_float("left", 2.0f)); CHECK(effect->set_float("top", 1.0f)); tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR, OUTPUT_ALPHA_FORMAT_PREMULTIPLIED); expect_equal(expected_data, out_data, 3, 3); }
TEST(GlowEffectTest, GlowsOntoZeroAlpha) { const int size = 7; const float sigma = 1.0f; const float amount = 1.0f; float data[4 * size] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, }; float expected_data[4 * size] = { 0.0, 1.0, 0.0, 0.002, 0.0, 1.0, 0.0, 0.014, 0.0, 1.0, 0.0, 0.065, 0.0, 1.0, 0.0, 0.635, 0.0, 1.0, 0.0, 0.065, 0.0, 1.0, 0.0, 0.014, 0.0, 1.0, 0.0, 0.002, }; float out_data[4 * size]; EffectChainTester tester(data, 1, size, FORMAT_RGBA_POSTMULTIPLIED_ALPHA, COLORSPACE_sRGB, GAMMA_LINEAR); Effect *glow_effect = tester.get_chain()->add_effect(new GlowEffect()); ASSERT_TRUE(glow_effect->set_float("radius", sigma)); ASSERT_TRUE(glow_effect->set_float("blurred_mix_amount", amount)); tester.run(out_data, GL_RGBA, COLORSPACE_sRGB, GAMMA_LINEAR); expect_equal(expected_data, out_data, 4, size); }
TEST(DeconvolutionSharpenEffectTest, CircularDeconvolutionKeepsAlpha) { // Somewhat bigger, to make sure we are much bigger than the matrix size. const int size = 32; float data[size * size * 4]; float out_data[size * size]; float expected_alpha[size * size]; // Checkerbox pattern. for (int y = 0; y < size; ++y) { for (int x = 0; x < size; ++x) { int c = (y ^ x) & 1; data[(y * size + x) * 4 + 0] = c; data[(y * size + x) * 4 + 1] = c; data[(y * size + x) * 4 + 2] = c; data[(y * size + x) * 4 + 3] = 1.0; expected_alpha[y * size + x] = 1.0; } } EffectChainTester tester(data, size, size, FORMAT_RGBA_POSTMULTIPLIED_ALPHA, COLORSPACE_sRGB, GAMMA_LINEAR); Effect *deconvolution_effect = tester.get_chain()->add_effect(new DeconvolutionSharpenEffect()); ASSERT_TRUE(deconvolution_effect->set_int("matrix_size", 5)); ASSERT_TRUE(deconvolution_effect->set_float("circle_radius", 2.0f)); ASSERT_TRUE(deconvolution_effect->set_float("gaussian_radius", 0.0f)); ASSERT_TRUE(deconvolution_effect->set_float("correlation", 0.0001f)); ASSERT_TRUE(deconvolution_effect->set_float("noise", 0.0f)); tester.run(out_data, GL_ALPHA, COLORSPACE_sRGB, GAMMA_LINEAR); expect_equal(expected_alpha, out_data, size, size); }
TEST(DiffusionEffectTest, FlattensOutWhitePyramid) { const int size = 9; float data[size * size] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.7, 0.7, 0.7, 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.7, 1.0, 0.7, 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.7, 0.7, 0.7, 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, }; float expected_data[size * size] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.4, 0.4, 0.4, 0.4, 0.4, 0.0, 0.0, 0.0, 0.0, 0.4, 0.5, 0.5, 0.5, 0.4, 0.0, 0.0, 0.0, 0.0, 0.4, 0.5, 0.6, 0.5, 0.4, 0.0, 0.0, 0.0, 0.0, 0.4, 0.5, 0.5, 0.5, 0.4, 0.0, 0.0, 0.0, 0.0, 0.4, 0.4, 0.4, 0.4, 0.4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, }; float out_data[size * size]; EffectChainTester tester(data, size, size, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR); Effect *diffusion_effect = tester.get_chain()->add_effect(new DiffusionEffect()); ASSERT_TRUE(diffusion_effect->set_float("radius", 2.0f)); ASSERT_TRUE(diffusion_effect->set_float("blurred_mix_amount", 0.7f)); tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR); expect_equal(expected_data, out_data, size, size, 0.05f, 0.002); }
// Note: The sRGB conversion itself is tested in EffectChainTester, // since it also wants to test the chain building itself. // Here, we merely test that alpha is left alone; the test will usually // run using the sRGB OpenGL extension, but might be run with a // GammaExpansionEffect if the card/driver happens not to support that. TEST(FlatInput, AlphaIsNotModifiedBySRGBConversion) { const int size = 5; unsigned char data[4 * size] = { 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 127, 0, 0, 0, 191, 0, 0, 0, 255, }; float expected_data[4 * size] = { 0, 0, 0, 0.0 / 255.0, 0, 0, 0, 63.0 / 255.0, 0, 0, 0, 127.0 / 255.0, 0, 0, 0, 191.0 / 255.0, 0, 0, 0, 255.0 / 255.0, }; float out_data[4 * size]; EffectChainTester tester(NULL, 1, size); tester.add_input(data, FORMAT_RGBA_POSTMULTIPLIED_ALPHA, COLORSPACE_sRGB, GAMMA_sRGB); tester.run(out_data, GL_RGBA, COLORSPACE_sRGB, GAMMA_LINEAR); expect_equal(expected_data, out_data, 4, size); }
TEST(FlatInput, Pitch) { const int pitch = 3; const int width = 2; const int height = 4; float data[pitch * height] = { 0.0, 1.0, 999.0f, 0.5, 0.5, 999.0f, 0.7, 0.2, 999.0f, 1.0, 0.6, 999.0f, }; float expected_data[4 * width * height] = { 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.5, 0.5, 0.5, 1.0, 0.5, 0.5, 0.5, 1.0, 0.7, 0.7, 0.7, 1.0, 0.2, 0.2, 0.2, 1.0, 1.0, 1.0, 1.0, 1.0, 0.6, 0.6, 0.6, 1.0, }; float out_data[4 * width * height]; EffectChainTester tester(NULL, width, height); ImageFormat format; format.color_space = COLORSPACE_sRGB; format.gamma_curve = GAMMA_LINEAR; FlatInput *input = new FlatInput(format, FORMAT_GRAYSCALE, GL_FLOAT, width, height); input->set_pitch(pitch); input->set_pixel_data(data); tester.get_chain()->add_input(input); tester.run(out_data, GL_RGBA, COLORSPACE_sRGB, GAMMA_LINEAR); expect_equal(expected_data, out_data, 4 * width, height); }
TEST(FlatInput, PBO) { const int width = 3; const int height = 2; float data[width * height] = { 0.0, 1.0, 0.5, 0.5, 0.5, 0.2, }; float expected_data[4 * width * height] = { 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.5, 0.5, 0.5, 1.0, 0.5, 0.5, 0.5, 1.0, 0.5, 0.5, 0.5, 1.0, 0.2, 0.2, 0.2, 1.0, }; float out_data[4 * width * height]; GLuint pbo; glGenBuffers(1, &pbo); glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, pbo); glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB, width * height * sizeof(float), data, GL_STREAM_DRAW); glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0); EffectChainTester tester(NULL, width, height); ImageFormat format; format.color_space = COLORSPACE_sRGB; format.gamma_curve = GAMMA_LINEAR; FlatInput *input = new FlatInput(format, FORMAT_GRAYSCALE, GL_FLOAT, width, height); input->set_pixel_data((float *)BUFFER_OFFSET(0), pbo); tester.get_chain()->add_input(input); tester.run(out_data, GL_RGBA, COLORSPACE_sRGB, GAMMA_LINEAR); expect_equal(expected_data, out_data, 4 * width, height); glDeleteBuffers(1, &pbo); }
TEST(YCbCrInputTest, PBO) { const int width = 1; const int height = 5; // Pure-color test inputs, calculated with the formulas in Rec. 601 // section 2.5.4. unsigned char data[width * height * 3] = { 16, 235, 81, 145, 41, 128, 128, 90, 54, 240, 128, 128, 240, 34, 110, }; float expected_data[4 * width * height] = { 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, }; float out_data[4 * width * height]; GLuint pbo; glGenBuffers(1, &pbo); glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, pbo); glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB, width * height * 3, data, GL_STREAM_DRAW); glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0); EffectChainTester tester(NULL, width, height); ImageFormat format; format.color_space = COLORSPACE_sRGB; format.gamma_curve = GAMMA_sRGB; YCbCrFormat ycbcr_format; ycbcr_format.luma_coefficients = YCBCR_REC_601; ycbcr_format.full_range = false; ycbcr_format.num_levels = 256; ycbcr_format.chroma_subsampling_x = 1; ycbcr_format.chroma_subsampling_y = 1; ycbcr_format.cb_x_position = 0.5f; ycbcr_format.cb_y_position = 0.5f; ycbcr_format.cr_x_position = 0.5f; ycbcr_format.cr_y_position = 0.5f; YCbCrInput *input = new YCbCrInput(format, ycbcr_format, width, height); input->set_pixel_data(0, (unsigned char *)BUFFER_OFFSET(0), pbo); input->set_pixel_data(1, (unsigned char *)BUFFER_OFFSET(width * height), pbo); input->set_pixel_data(2, (unsigned char *)BUFFER_OFFSET(width * height * 2), pbo); tester.get_chain()->add_input(input); tester.run(out_data, GL_RGBA, COLORSPACE_sRGB, GAMMA_sRGB); // Y'CbCr isn't 100% accurate (the input values are rounded), // so we need some leeway. expect_equal(expected_data, out_data, 4 * width, height, 0.025, 0.002); glDeleteBuffers(1, &pbo); }
void jeayeson::value_ctor_group::test<1>() /* initializer_list for array */ { json_value vm { "str0", "str1", "str2" }; expect(vm.get_type() == json_value::type::array); expect_equal(vm.as<json_array>().size(), 3ul); }
TEST(YCbCrInputTest, Rec2020) { const int width = 1; const int height = 5; // Pure-color test inputs, calculated with the formulas in Rec. 2020 // page 4, tables 4 and 5 (for conventional non-constant luminance). // Note that we still use 8-bit inputs, even though Rec. 2020 is only // defined for 10- and 12-bit. unsigned char y[width * height] = { 16, 235, 74, 164, 29, }; unsigned char cb[width * height] = { 128, 128, 97, 47, 240, }; unsigned char cr[width * height] = { 128, 128, 240, 25, 119, }; float expected_data[4 * width * height] = { 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, }; float out_data[4 * width * height]; EffectChainTester tester(NULL, width, height); ImageFormat format; format.color_space = COLORSPACE_sRGB; format.gamma_curve = GAMMA_sRGB; YCbCrFormat ycbcr_format; ycbcr_format.luma_coefficients = YCBCR_REC_2020; ycbcr_format.full_range = false; ycbcr_format.num_levels = 256; ycbcr_format.chroma_subsampling_x = 1; ycbcr_format.chroma_subsampling_y = 1; ycbcr_format.cb_x_position = 0.5f; ycbcr_format.cb_y_position = 0.5f; ycbcr_format.cr_x_position = 0.5f; ycbcr_format.cr_y_position = 0.5f; YCbCrInput *input = new YCbCrInput(format, ycbcr_format, width, height); input->set_pixel_data(0, y); input->set_pixel_data(1, cb); input->set_pixel_data(2, cr); tester.get_chain()->add_input(input); tester.run(out_data, GL_RGBA, COLORSPACE_sRGB, GAMMA_sRGB); // Y'CbCr isn't 100% accurate (the input values are rounded), // so we need some leeway. expect_equal(expected_data, out_data, 4 * width, height, 0.025, 0.002); }
/* Test that we detect overrun. */ static void test_overrun(void) { struct blob blob; struct blob_reader reader; uint32_t value = 0xdeadbeef; blob_init(&blob); blob_write_uint32(&blob, value); blob_reader_init(&reader, blob.data, blob.size); expect_equal(value, blob_read_uint32(&reader), "read before overrun"); expect_equal(false, reader.overrun, "overrun flag not set"); expect_equal(0, blob_read_uint32(&reader), "read at overrun"); expect_equal(true, reader.overrun, "overrun flag set"); blob_finish(&blob); }
TEST(YCbCrInputTest, FullRangeRec601) { const int width = 1; const int height = 5; // Pure-color test inputs, calculated with the formulas in Rec. 601 // section 2.5.4 but without the scaling factors applied // (so both R, G, B, Y, Cb and R vary from 0 to 255). unsigned char y[width * height] = { 0, 255, 76, 150, 29, }; unsigned char cb[width * height] = { 128, 128, 85, 44, 255, }; unsigned char cr[width * height] = { 128, 128, 255, 21, 107, }; float expected_data[4 * width * height] = { 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, }; float out_data[4 * width * height]; EffectChainTester tester(NULL, width, height); ImageFormat format; format.color_space = COLORSPACE_sRGB; format.gamma_curve = GAMMA_sRGB; YCbCrFormat ycbcr_format; ycbcr_format.luma_coefficients = YCBCR_REC_601; ycbcr_format.full_range = true; ycbcr_format.num_levels = 256; ycbcr_format.chroma_subsampling_x = 1; ycbcr_format.chroma_subsampling_y = 1; ycbcr_format.cb_x_position = 0.5f; ycbcr_format.cb_y_position = 0.5f; ycbcr_format.cr_x_position = 0.5f; ycbcr_format.cr_y_position = 0.5f; YCbCrInput *input = new YCbCrInput(format, ycbcr_format, width, height); input->set_pixel_data(0, y); input->set_pixel_data(1, cb); input->set_pixel_data(2, cr); tester.get_chain()->add_input(input); tester.run(out_data, GL_RGBA, COLORSPACE_sRGB, GAMMA_sRGB); // Y'CbCr isn't 100% accurate (the input values are rounded), // so we need some leeway. expect_equal(expected_data, out_data, 4 * width, height, 0.025, 0.002); }
/* Test that we can read and write some large objects, (exercising the code in * the blob_write functions to realloc blob->data. */ static void test_big_objects(void) { void *ctx = ralloc_context(NULL); struct blob blob; struct blob_reader reader; int size = 1000; int count = 1000; size_t i; char *buf; blob_init(&blob); /* Initialize our buffer. */ buf = ralloc_size(ctx, size); for (i = 0; i < size; i++) { buf[i] = i % 256; } /* Write it many times. */ for (i = 0; i < count; i++) { blob_write_bytes(&blob, buf, size); } blob_reader_init(&reader, blob.data, blob.size); /* Read and verify it many times. */ for (i = 0; i < count; i++) { expect_equal_bytes((uint8_t *) buf, blob_read_bytes(&reader, size), size, "read of large objects"); } expect_equal(reader.end - reader.data, reader.current - reader.data, "number of bytes read reading large objects"); expect_equal(false, reader.overrun, "overrun flag not set reading large objects"); blob_finish(&blob); ralloc_free(ctx); }
TEST(SaturationEffectTest, SaturationOneIsPassThrough) { float data[] = { 1.0f, 0.5f, 0.75f, 0.6f, }; float out_data[4]; EffectChainTester tester(data, 1, 1, FORMAT_RGBA_POSTMULTIPLIED_ALPHA, COLORSPACE_sRGB, GAMMA_LINEAR); Effect *saturation_effect = tester.get_chain()->add_effect(new SaturationEffect()); ASSERT_TRUE(saturation_effect->set_float("saturation", 1.0f)); tester.run(out_data, GL_RGBA, COLORSPACE_sRGB, GAMMA_LINEAR); expect_equal(data, out_data, 1, 1); }
/* Test that we detect overrun. */ static void test_overrun(void) { void *ctx =ralloc_context(NULL); struct blob *blob; struct blob_reader reader; uint32_t value = 0xdeadbeef; blob = blob_create(ctx); blob_write_uint32(blob, value); blob_reader_init(&reader, blob->data, blob->size); expect_equal(value, blob_read_uint32(&reader), "read before overrun"); expect_equal(false, reader.overrun, "overrun flag not set"); expect_equal(0, blob_read_uint32(&reader), "read at overrun"); expect_equal(true, reader.overrun, "overrun flag set"); ralloc_free(ctx); }
TEST(YCbCrInputTest, CombinedCbAndCr) { const int width = 1; const int height = 5; // Pure-color test inputs, calculated with the formulas in Rec. 601 // section 2.5.4. unsigned char y[width * height] = { 16, 235, 81, 145, 41, }; unsigned char cb_cr[width * height * 2] = { 128, 128, 128, 128, 90, 240, 54, 34, 240, 110, }; float expected_data[4 * width * height] = { 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, }; float out_data[4 * width * height]; EffectChainTester tester(NULL, width, height); ImageFormat format; format.color_space = COLORSPACE_sRGB; format.gamma_curve = GAMMA_sRGB; YCbCrFormat ycbcr_format; ycbcr_format.luma_coefficients = YCBCR_REC_601; ycbcr_format.full_range = false; ycbcr_format.num_levels = 256; ycbcr_format.chroma_subsampling_x = 1; ycbcr_format.chroma_subsampling_y = 1; ycbcr_format.cb_x_position = 0.5f; ycbcr_format.cb_y_position = 0.5f; ycbcr_format.cr_x_position = 0.5f; ycbcr_format.cr_y_position = 0.5f; YCbCrInput *input = new YCbCrInput(format, ycbcr_format, width, height, YCBCR_INPUT_SPLIT_Y_AND_CBCR); input->set_pixel_data(0, y); input->set_pixel_data(1, cb_cr); tester.get_chain()->add_input(input); tester.run(out_data, GL_RGBA, COLORSPACE_sRGB, GAMMA_sRGB); // Y'CbCr isn't 100% accurate (the input values are rounded), // so we need some leeway. expect_equal(expected_data, out_data, 4 * width, height, 0.025, 0.002); }
TEST(YCbCrInputTest, Rec709) { const int width = 1; const int height = 5; // Pure-color test inputs, calculated with the formulas in Rec. 709 // page 19, items 3.4 and 3.5. unsigned char y[width * height] = { 16, 235, 63, 173, 32, }; unsigned char cb[width * height] = { 128, 128, 102, 42, 240, }; unsigned char cr[width * height] = { 128, 128, 240, 26, 118, }; float expected_data[4 * width * height] = { 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, }; float out_data[4 * width * height]; EffectChainTester tester(NULL, width, height); ImageFormat format; format.color_space = COLORSPACE_sRGB; format.gamma_curve = GAMMA_sRGB; YCbCrFormat ycbcr_format; ycbcr_format.luma_coefficients = YCBCR_REC_709; ycbcr_format.full_range = false; ycbcr_format.num_levels = 256; ycbcr_format.chroma_subsampling_x = 1; ycbcr_format.chroma_subsampling_y = 1; ycbcr_format.cb_x_position = 0.5f; ycbcr_format.cb_y_position = 0.5f; ycbcr_format.cr_x_position = 0.5f; ycbcr_format.cr_y_position = 0.5f; YCbCrInput *input = new YCbCrInput(format, ycbcr_format, width, height); input->set_pixel_data(0, y); input->set_pixel_data(1, cb); input->set_pixel_data(2, cr); tester.get_chain()->add_input(input); tester.run(out_data, GL_RGBA, COLORSPACE_sRGB, GAMMA_sRGB); // Y'CbCr isn't 100% accurate (the input values are rounded), // so we need some leeway. expect_equal(expected_data, out_data, 4 * width, height, 0.025, 0.002); }