diff --git a/Tests/test_file_avif.py b/Tests/test_file_avif.py index 1b3eb7d8b0b..191591bac5a 100644 --- a/Tests/test_file_avif.py +++ b/Tests/test_file_avif.py @@ -25,6 +25,7 @@ assert_image, assert_image_similar, assert_image_similar_tofile, + has_feature_version, hopper, skip_if_tsan, skip_unless_feature, @@ -133,13 +134,14 @@ def test_read(self) -> None: image, "Tests/images/avif/hopper_avif_write.png", 11.5 ) - @skip_unless_feature_version("avif", "1.3.0") - def test_write_l(self) -> None: - im = hopper("L") - reloaded = roundtrip(im) + @pytest.mark.parametrize("mode", ["1", "L", "I", "I;16", "F"]) + def test_write_grayscale(self, mode: str) -> None: + im = hopper(mode) + reloaded: Image.Image = roundtrip(im) - assert reloaded.mode == "L" - assert_image_similar(reloaded, im, 1.69) + if not has_feature_version("avif", "1.3.0"): + reloaded = reloaded.convert("L") + assert_image_similar(reloaded, im.convert("L"), 1.69) def test_write_rgb(self, tmp_path: Path) -> None: """ @@ -193,6 +195,8 @@ def test_encoder_finish_none_error( """Save should raise an OSError if AvifEncoder.finish returns None""" class _mock_avif: + libavif_version = "1.3.0" + class AvifEncoder: def __init__(self, *args: Any) -> None: pass diff --git a/src/PIL/AvifImagePlugin.py b/src/PIL/AvifImagePlugin.py index dd87a508313..4222ac6add2 100644 --- a/src/PIL/AvifImagePlugin.py +++ b/src/PIL/AvifImagePlugin.py @@ -239,6 +239,11 @@ def _save( advanced, ) + supported_modes = {"RGB", "RGBA"} + if tuple(int(v) for v in _avif.libavif_version.split(".")) >= (1, 3): + # AVIF_RGB_FORMAT_GRAY was only added in libavif 1.3.0 + supported_modes.add("L") + # Add each frame frame_idx = 0 frame_duration = 0 @@ -249,10 +254,10 @@ def _save( for frame in ImageSequence.Iterator(ims): # Make sure image mode is supported rawmode = frame.mode - if ims.mode not in {"L", "RGB", "RGBA"}: + if ims.mode not in supported_modes: if ims.has_transparency_data: rawmode = "RGBA" - elif ims.mode in grayscale_modes: + elif ims.mode in grayscale_modes and "L" in supported_modes: rawmode = "L" else: rawmode = "RGB"