From 981459df8885fef0db10fabe8d533ffb066de713 Mon Sep 17 00:00:00 2001 From: Aarni Koskela Date: Thu, 9 Jul 2026 15:07:19 +0300 Subject: [PATCH] Fix high byte of I;16* images being truncated by ImageFilter Follows up on #8438 (418ae7caa28d3ecb88f6cfaf1fb1a27b544794a8) --- Tests/test_image_filter.py | 10 ++++++++++ src/libImaging/Filter.c | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/Tests/test_image_filter.py b/Tests/test_image_filter.py index 3f1c38be3da..b429de19c2a 100644 --- a/Tests/test_image_filter.py +++ b/Tests/test_image_filter.py @@ -210,6 +210,16 @@ def test_consistency_5x5(mode: str) -> None: assert_image_equal(source.filter(kernel), reference) +@pytest.mark.parametrize("mode", ("I;16", "I;16L", "I;16B", "I;16N")) +def test_consistency_i16_high_byte(mode: str) -> None: + # Exercise filters with a 16bpc image that has content in the high byte, too. + im = Image.new(mode, (8, 8), 1000) + pixel = im.filter(ImageFilter.SMOOTH).getpixel((4, 4)) + assert isinstance(pixel, (int, float)) + # Allow for kernel rounding errors. + assert abs(pixel - 1000) <= 1 + + @pytest.mark.parametrize( "radius", ( diff --git a/src/libImaging/Filter.c b/src/libImaging/Filter.c index 76b5cd486f2..567fd2c49b3 100644 --- a/src/libImaging/Filter.c +++ b/src/libImaging/Filter.c @@ -114,7 +114,7 @@ kernel_i16(int size, UINT8 *in0, int x, const float *kernel, int bigendian) { for (i = 0; i < size; i++) { int x1 = x + i - half_size; result += (float)(in0[x1 * 2 + (bigendian ? 1 : 0)] + - (in0[x1 * 2 + (bigendian ? 0 : 1)] >> 8)) * + (in0[x1 * 2 + (bigendian ? 0 : 1)] << 8)) * kernel[i]; } return result;