Skip to content

Commit 354daad

Browse files
committed
add a unit test for underflow
1 parent 7a69fb1 commit 354daad

1 file changed

Lines changed: 27 additions & 1 deletion

File tree

Tests/test_image_resample.py

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -630,7 +630,7 @@ def test_skip_vertical(self, flt: Image.Resampling) -> None:
630630

631631

632632
class TestCoreResample16bpc:
633-
def test_resampling_clamp(self) -> None:
633+
def test_resampling_clamp_overflow(self) -> None:
634634
# Lanczos weighting during downsampling can push accumulated float sums
635635
# above 65535. These must be clamped to 65535, not corrupted byte-by-byte.
636636
ims = {}
@@ -655,3 +655,29 @@ def test_resampling_clamp(self) -> None:
655655
assert (
656656
value == expected
657657
), f"Pixel ({x}, {y}): expected {expected}, got {value}"
658+
659+
def test_resampling_clamp_underflow(self) -> None:
660+
# Lanczos weighting during downsampling can push accumulated float sums
661+
# below 0. These must be clamped to 0, not corrupted byte-by-byte.
662+
ims = {}
663+
width, height = 100, 10
664+
for mode in ("I;16", "F"):
665+
# Left half = 65535, right half = 0
666+
im = Image.new(mode, (width, height))
667+
for y in range(height):
668+
for x in range(width // 2):
669+
im.putpixel((x, y), 65535)
670+
671+
# 5x downsampling with Lanczos creates ~8.7% undershoot at the step edge
672+
ims[mode] = im.resize((20, height), Image.Resampling.LANCZOS)
673+
674+
for y in range(height):
675+
for x in range(20):
676+
v = ims["F"].getpixel((x, y))
677+
assert isinstance(v, float)
678+
expected = max(0, min(65535, round(v)))
679+
680+
value = ims["I;16"].getpixel((x, y))
681+
assert (
682+
value == expected
683+
), f"Pixel ({x}, {y}): expected {expected}, got {value}"

0 commit comments

Comments
 (0)