From d8b01c80815f74603eddd2b8f66249a967fa7bab Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Sun, 30 Mar 2014 19:12:22 +0200 Subject: [PATCH] Fix a bug when scaling and doing offset at the same time. (At least one more remains.) --- resample_effect.cpp | 4 ++-- resample_effect_test.cpp | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/resample_effect.cpp b/resample_effect.cpp index 17745bc..2a6aecf 100644 --- a/resample_effect.cpp +++ b/resample_effect.cpp @@ -309,13 +309,13 @@ void SingleResamplePassEffect::update_texture(GLuint glsl_program_num, const str for (unsigned y = 0; y < dst_samples; ++y) { // Find the point around which we want to sample the source image, // compensating for differing pixel centers as the scale changes. - float center_src_y = (y + subpixel_offset + 0.5f) * float(src_size) / float(dst_size) - 0.5f; + float center_src_y = (y + 0.5f) * float(src_size) / float(dst_size) - 0.5f; int base_src_y = lrintf(center_src_y); // Now sample pixels on each side around that point. for (int i = 0; i < src_samples; ++i) { int src_y = base_src_y + i - int_radius; - float weight = lanczos_weight(radius_scaling_factor * (src_y - center_src_y), LANCZOS_RADIUS); + float weight = lanczos_weight(radius_scaling_factor * (src_y - center_src_y - subpixel_offset), LANCZOS_RADIUS); weights[(y * src_samples + i) * 2 + 0] = weight * radius_scaling_factor; weights[(y * src_samples + i) * 2 + 1] = (src_y + 0.5) / float(src_size); } diff --git a/resample_effect_test.cpp b/resample_effect_test.cpp index e4b9439..dbb213a 100644 --- a/resample_effect_test.cpp +++ b/resample_effect_test.cpp @@ -304,4 +304,41 @@ TEST(ResampleEffectTest, ReadQuarterPixelFromTop) { expect_equal(expected_data, out_data, width, height); } +TEST(ResampleEffectTest, ReadHalfPixelFromLeftAndScale) { + const int src_width = 4; + const int dst_width = 8; + + float data[src_width * 1] = { + 1.0, 2.0, 3.0, 4.0, + }; + float expected_data[dst_width * 1] = { + // Empirical; the real test is that we are the same for 0.499 and 0.501. + 1.1553, 1.7158, 2.2500, 2.7461, 3.2812, 3.8418, 4.0703, 4.0508 + }; + float out_data[dst_width * 1]; + + EffectChainTester tester(NULL, dst_width, 1, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR); + + ImageFormat format; + format.color_space = COLORSPACE_sRGB; + format.gamma_curve = GAMMA_LINEAR; + + FlatInput *input = new FlatInput(format, FORMAT_GRAYSCALE, GL_FLOAT, src_width, 1); + input->set_pixel_data(data); + tester.get_chain()->add_input(input); + + Effect *resample_effect = tester.get_chain()->add_effect(new ResampleEffect()); + ASSERT_TRUE(resample_effect->set_int("width", dst_width)); + ASSERT_TRUE(resample_effect->set_int("height", 1)); + + // Check that we are (almost) the same no matter the rounding. + ASSERT_TRUE(resample_effect->set_float("left", 0.499f)); + tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR); + expect_equal(expected_data, out_data, dst_width, 1); + + ASSERT_TRUE(resample_effect->set_float("left", 0.501f)); + tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR); + expect_equal(expected_data, out_data, dst_width, 1); +} + } // namespace movit -- 2.39.2