From 171e497e05518491c6e1505a71326440851335a0 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Fri, 22 Mar 2024 17:36:04 +1100 Subject: [PATCH 1/2] Raise ValueError if kmeans is negative --- Tests/test_image_quantize.py | 9 +++++++++ src/PIL/Image.py | 6 +++++- src/libImaging/Quant.c | 4 ++-- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/Tests/test_image_quantize.py b/Tests/test_image_quantize.py index 873a9bb5dcb..da736d6ede1 100644 --- a/Tests/test_image_quantize.py +++ b/Tests/test_image_quantize.py @@ -94,6 +94,15 @@ def test_quantize_dither_diff() -> None: assert dither.tobytes() != nodither.tobytes() +@pytest.mark.parametrize( + "method", (Image.Quantize.MEDIANCUT, Image.Quantize.MAXCOVERAGE) +) +def test_quantize_kmeans(method) -> None: + im = hopper() + with pytest.raises(ValueError): + im.quantize(kmeans=-1, method=method) + + def test_colors() -> None: im = hopper() colors = 2 diff --git a/src/PIL/Image.py b/src/PIL/Image.py index ac3a533211b..59c5c36f3b6 100644 --- a/src/PIL/Image.py +++ b/src/PIL/Image.py @@ -1141,7 +1141,7 @@ def quantize( The exception to this is RGBA images. :data:`Quantize.MEDIANCUT` and :data:`Quantize.MAXCOVERAGE` do not support RGBA images, so :data:`Quantize.FASTOCTREE` is used by default instead. - :param kmeans: Integer + :param kmeans: Integer greater than or equal to zero. :param palette: Quantize to the palette of given :py:class:`PIL.Image.Image`. :param dither: Dithering method, used when converting from @@ -1184,6 +1184,10 @@ def quantize( new_im.palette = palette.palette.copy() return new_im + if kmeans < 0: + msg = "kmeans must not be negative" + raise ValueError(msg) + im = self._new(self.im.quantize(colors, method, kmeans)) from . import ImagePalette diff --git a/src/libImaging/Quant.c b/src/libImaging/Quant.c index 398fbf6db57..2582830c4a4 100644 --- a/src/libImaging/Quant.c +++ b/src/libImaging/Quant.c @@ -1471,7 +1471,7 @@ quantize( fflush(stdout); timer = clock(); #endif - if (kmeans) { + if (kmeans > 0) { k_means(pixelData, nPixels, p, nPaletteEntries, qp, kmeans - 1); } #ifndef NO_OUTPUT @@ -1627,7 +1627,7 @@ quantize2( pixelData, nPixels, p, nQuantPixels, avgDist, avgDistSortKey, qp)) { goto error_4; } - if (kmeans) { + if (kmeans > 0) { k_means(pixelData, nPixels, p, nQuantPixels, qp, kmeans - 1); } From 47040c7b35b1fa616035a26784ebb2fc1abef343 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Fri, 22 Mar 2024 23:53:07 +1100 Subject: [PATCH 2/2] Test positive and zero kmeans --- Tests/test_image_quantize.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Tests/test_image_quantize.py b/Tests/test_image_quantize.py index da736d6ede1..e1aa6252b7a 100644 --- a/Tests/test_image_quantize.py +++ b/Tests/test_image_quantize.py @@ -99,6 +99,10 @@ def test_quantize_dither_diff() -> None: ) def test_quantize_kmeans(method) -> None: im = hopper() + no_kmeans = im.quantize(kmeans=0, method=method) + kmeans = im.quantize(kmeans=1, method=method) + assert kmeans.tobytes() != no_kmeans.tobytes() + with pytest.raises(ValueError): im.quantize(kmeans=-1, method=method)