diff --git a/Tests/test_image_quantize.py b/Tests/test_image_quantize.py index 873a9bb5dcb..e1aa6252b7a 100644 --- a/Tests/test_image_quantize.py +++ b/Tests/test_image_quantize.py @@ -94,6 +94,19 @@ 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() + 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) + + 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); }