diff --git a/Tests/test_file_pdf.py b/Tests/test_file_pdf.py
index 310619fb2..df0b7abe6 100644
--- a/Tests/test_file_pdf.py
+++ b/Tests/test_file_pdf.py
@@ -37,6 +37,7 @@ def helper_save_as_pdf(tmp_path, mode, **kwargs):
return outfile
+@pytest.mark.valgrind_known_error(reason="Temporary skip")
def test_monochrome(tmp_path):
# Arrange
mode = "1"
diff --git a/Tests/test_image_paste.py b/Tests/test_image_paste.py
index 4ea1d73ce..1ab02017d 100644
--- a/Tests/test_image_paste.py
+++ b/Tests/test_image_paste.py
@@ -1,3 +1,5 @@
+import pytest
+
from PIL import Image
from .helper import CachedProperty, assert_image_equal
@@ -101,226 +103,226 @@ class TestImagingPaste:
],
)
- def test_image_solid(self):
- for mode in ("RGBA", "RGB", "L"):
- im = Image.new(mode, (200, 200), "red")
- im2 = getattr(self, "gradient_" + mode)
+ @pytest.mark.parametrize("mode", ["RGBA", "RGB", "L"])
+ def test_image_solid(self, mode):
+ im = Image.new(mode, (200, 200), "red")
+ im2 = getattr(self, "gradient_" + mode)
- im.paste(im2, (12, 23))
+ im.paste(im2, (12, 23))
- im = im.crop((12, 23, im2.width + 12, im2.height + 23))
- assert_image_equal(im, im2)
+ im = im.crop((12, 23, im2.width + 12, im2.height + 23))
+ assert_image_equal(im, im2)
- def test_image_mask_1(self):
- for mode in ("RGBA", "RGB", "L"):
- im = Image.new(mode, (200, 200), "white")
- im2 = getattr(self, "gradient_" + mode)
+ @pytest.mark.parametrize("mode", ["RGBA", "RGB", "L"])
+ def test_image_mask_1(self, mode):
+ im = Image.new(mode, (200, 200), "white")
+ im2 = getattr(self, "gradient_" + mode)
- self.assert_9points_paste(
- im,
- im2,
- self.mask_1,
- [
- (255, 255, 255, 255),
- (255, 255, 255, 255),
- (127, 254, 127, 0),
- (255, 255, 255, 255),
- (255, 255, 255, 255),
- (191, 190, 63, 64),
- (127, 0, 127, 254),
- (191, 64, 63, 190),
- (255, 255, 255, 255),
- ],
- )
+ self.assert_9points_paste(
+ im,
+ im2,
+ self.mask_1,
+ [
+ (255, 255, 255, 255),
+ (255, 255, 255, 255),
+ (127, 254, 127, 0),
+ (255, 255, 255, 255),
+ (255, 255, 255, 255),
+ (191, 190, 63, 64),
+ (127, 0, 127, 254),
+ (191, 64, 63, 190),
+ (255, 255, 255, 255),
+ ],
+ )
- def test_image_mask_L(self):
- for mode in ("RGBA", "RGB", "L"):
- im = Image.new(mode, (200, 200), "white")
- im2 = getattr(self, "gradient_" + mode)
+ @pytest.mark.parametrize("mode", ["RGBA", "RGB", "L"])
+ def test_image_mask_L(self, mode):
+ im = Image.new(mode, (200, 200), "white")
+ im2 = getattr(self, "gradient_" + mode)
- self.assert_9points_paste(
- im,
- im2,
- self.mask_L,
- [
- (128, 191, 255, 191),
- (208, 239, 239, 208),
- (255, 255, 255, 255),
- (112, 111, 206, 207),
- (192, 191, 191, 191),
- (239, 239, 207, 207),
- (128, 1, 128, 254),
- (207, 113, 112, 207),
- (255, 191, 128, 191),
- ],
- )
+ self.assert_9points_paste(
+ im,
+ im2,
+ self.mask_L,
+ [
+ (128, 191, 255, 191),
+ (208, 239, 239, 208),
+ (255, 255, 255, 255),
+ (112, 111, 206, 207),
+ (192, 191, 191, 191),
+ (239, 239, 207, 207),
+ (128, 1, 128, 254),
+ (207, 113, 112, 207),
+ (255, 191, 128, 191),
+ ],
+ )
- def test_image_mask_LA(self):
- for mode in ("RGBA", "RGB", "L"):
- im = Image.new(mode, (200, 200), "white")
- im2 = getattr(self, "gradient_" + mode)
+ @pytest.mark.parametrize("mode", ["RGBA", "RGB", "L"])
+ def test_image_mask_LA(self, mode):
+ im = Image.new(mode, (200, 200), "white")
+ im2 = getattr(self, "gradient_" + mode)
- self.assert_9points_paste(
- im,
- im2,
- self.gradient_LA,
- [
- (128, 191, 255, 191),
- (112, 207, 206, 111),
- (128, 254, 128, 1),
- (208, 208, 239, 239),
- (192, 191, 191, 191),
- (207, 207, 112, 113),
- (255, 255, 255, 255),
- (239, 207, 207, 239),
- (255, 191, 128, 191),
- ],
- )
+ self.assert_9points_paste(
+ im,
+ im2,
+ self.gradient_LA,
+ [
+ (128, 191, 255, 191),
+ (112, 207, 206, 111),
+ (128, 254, 128, 1),
+ (208, 208, 239, 239),
+ (192, 191, 191, 191),
+ (207, 207, 112, 113),
+ (255, 255, 255, 255),
+ (239, 207, 207, 239),
+ (255, 191, 128, 191),
+ ],
+ )
- def test_image_mask_RGBA(self):
- for mode in ("RGBA", "RGB", "L"):
- im = Image.new(mode, (200, 200), "white")
- im2 = getattr(self, "gradient_" + mode)
+ @pytest.mark.parametrize("mode", ["RGBA", "RGB", "L"])
+ def test_image_mask_RGBA(self, mode):
+ im = Image.new(mode, (200, 200), "white")
+ im2 = getattr(self, "gradient_" + mode)
- self.assert_9points_paste(
- im,
- im2,
- self.gradient_RGBA,
- [
- (128, 191, 255, 191),
- (208, 239, 239, 208),
- (255, 255, 255, 255),
- (112, 111, 206, 207),
- (192, 191, 191, 191),
- (239, 239, 207, 207),
- (128, 1, 128, 254),
- (207, 113, 112, 207),
- (255, 191, 128, 191),
- ],
- )
+ self.assert_9points_paste(
+ im,
+ im2,
+ self.gradient_RGBA,
+ [
+ (128, 191, 255, 191),
+ (208, 239, 239, 208),
+ (255, 255, 255, 255),
+ (112, 111, 206, 207),
+ (192, 191, 191, 191),
+ (239, 239, 207, 207),
+ (128, 1, 128, 254),
+ (207, 113, 112, 207),
+ (255, 191, 128, 191),
+ ],
+ )
- def test_image_mask_RGBa(self):
- for mode in ("RGBA", "RGB", "L"):
- im = Image.new(mode, (200, 200), "white")
- im2 = getattr(self, "gradient_" + mode)
+ @pytest.mark.parametrize("mode", ["RGBA", "RGB", "L"])
+ def test_image_mask_RGBa(self, mode):
+ im = Image.new(mode, (200, 200), "white")
+ im2 = getattr(self, "gradient_" + mode)
- self.assert_9points_paste(
- im,
- im2,
- self.gradient_RGBa,
- [
- (128, 255, 126, 255),
- (0, 127, 126, 255),
- (126, 253, 126, 255),
- (128, 127, 254, 255),
- (0, 255, 254, 255),
- (126, 125, 254, 255),
- (128, 1, 128, 255),
- (0, 129, 128, 255),
- (126, 255, 128, 255),
- ],
- )
+ self.assert_9points_paste(
+ im,
+ im2,
+ self.gradient_RGBa,
+ [
+ (128, 255, 126, 255),
+ (0, 127, 126, 255),
+ (126, 253, 126, 255),
+ (128, 127, 254, 255),
+ (0, 255, 254, 255),
+ (126, 125, 254, 255),
+ (128, 1, 128, 255),
+ (0, 129, 128, 255),
+ (126, 255, 128, 255),
+ ],
+ )
- def test_color_solid(self):
- for mode in ("RGBA", "RGB", "L"):
- im = Image.new(mode, (200, 200), "black")
+ @pytest.mark.parametrize("mode", ["RGBA", "RGB", "L"])
+ def test_color_solid(self, mode):
+ im = Image.new(mode, (200, 200), "black")
- rect = (12, 23, 128 + 12, 128 + 23)
- im.paste("white", rect)
+ rect = (12, 23, 128 + 12, 128 + 23)
+ im.paste("white", rect)
- hist = im.crop(rect).histogram()
- while hist:
- head, hist = hist[:256], hist[256:]
- assert head[255] == 128 * 128
- assert sum(head[:255]) == 0
+ hist = im.crop(rect).histogram()
+ while hist:
+ head, hist = hist[:256], hist[256:]
+ assert head[255] == 128 * 128
+ assert sum(head[:255]) == 0
- def test_color_mask_1(self):
- for mode in ("RGBA", "RGB", "L"):
- im = Image.new(mode, (200, 200), (50, 60, 70, 80)[: len(mode)])
- color = (10, 20, 30, 40)[: len(mode)]
+ @pytest.mark.parametrize("mode", ["RGBA", "RGB", "L"])
+ def test_color_mask_1(self, mode):
+ im = Image.new(mode, (200, 200), (50, 60, 70, 80)[: len(mode)])
+ color = (10, 20, 30, 40)[: len(mode)]
- self.assert_9points_paste(
- im,
- color,
- self.mask_1,
- [
- (50, 60, 70, 80),
- (50, 60, 70, 80),
- (10, 20, 30, 40),
- (50, 60, 70, 80),
- (50, 60, 70, 80),
- (10, 20, 30, 40),
- (10, 20, 30, 40),
- (10, 20, 30, 40),
- (50, 60, 70, 80),
- ],
- )
+ self.assert_9points_paste(
+ im,
+ color,
+ self.mask_1,
+ [
+ (50, 60, 70, 80),
+ (50, 60, 70, 80),
+ (10, 20, 30, 40),
+ (50, 60, 70, 80),
+ (50, 60, 70, 80),
+ (10, 20, 30, 40),
+ (10, 20, 30, 40),
+ (10, 20, 30, 40),
+ (50, 60, 70, 80),
+ ],
+ )
- def test_color_mask_L(self):
- for mode in ("RGBA", "RGB", "L"):
- im = getattr(self, "gradient_" + mode).copy()
- color = "white"
+ @pytest.mark.parametrize("mode", ["RGBA", "RGB", "L"])
+ def test_color_mask_L(self, mode):
+ im = getattr(self, "gradient_" + mode).copy()
+ color = "white"
- self.assert_9points_paste(
- im,
- color,
- self.mask_L,
- [
- (127, 191, 254, 191),
- (111, 207, 206, 110),
- (127, 254, 127, 0),
- (207, 207, 239, 239),
- (191, 191, 190, 191),
- (207, 206, 111, 112),
- (254, 254, 254, 255),
- (239, 206, 206, 238),
- (254, 191, 127, 191),
- ],
- )
+ self.assert_9points_paste(
+ im,
+ color,
+ self.mask_L,
+ [
+ (127, 191, 254, 191),
+ (111, 207, 206, 110),
+ (127, 254, 127, 0),
+ (207, 207, 239, 239),
+ (191, 191, 190, 191),
+ (207, 206, 111, 112),
+ (254, 254, 254, 255),
+ (239, 206, 206, 238),
+ (254, 191, 127, 191),
+ ],
+ )
- def test_color_mask_RGBA(self):
- for mode in ("RGBA", "RGB", "L"):
- im = getattr(self, "gradient_" + mode).copy()
- color = "white"
+ @pytest.mark.parametrize("mode", ["RGBA", "RGB", "L"])
+ def test_color_mask_RGBA(self, mode):
+ im = getattr(self, "gradient_" + mode).copy()
+ color = "white"
- self.assert_9points_paste(
- im,
- color,
- self.gradient_RGBA,
- [
- (127, 191, 254, 191),
- (111, 207, 206, 110),
- (127, 254, 127, 0),
- (207, 207, 239, 239),
- (191, 191, 190, 191),
- (207, 206, 111, 112),
- (254, 254, 254, 255),
- (239, 206, 206, 238),
- (254, 191, 127, 191),
- ],
- )
+ self.assert_9points_paste(
+ im,
+ color,
+ self.gradient_RGBA,
+ [
+ (127, 191, 254, 191),
+ (111, 207, 206, 110),
+ (127, 254, 127, 0),
+ (207, 207, 239, 239),
+ (191, 191, 190, 191),
+ (207, 206, 111, 112),
+ (254, 254, 254, 255),
+ (239, 206, 206, 238),
+ (254, 191, 127, 191),
+ ],
+ )
- def test_color_mask_RGBa(self):
- for mode in ("RGBA", "RGB", "L"):
- im = getattr(self, "gradient_" + mode).copy()
- color = "white"
+ @pytest.mark.parametrize("mode", ["RGBA", "RGB", "L"])
+ def test_color_mask_RGBa(self, mode):
+ im = getattr(self, "gradient_" + mode).copy()
+ color = "white"
- self.assert_9points_paste(
- im,
- color,
- self.gradient_RGBa,
- [
- (255, 63, 126, 63),
- (47, 143, 142, 46),
- (126, 253, 126, 255),
- (15, 15, 47, 47),
- (63, 63, 62, 63),
- (142, 141, 46, 47),
- (255, 255, 255, 0),
- (48, 15, 15, 47),
- (126, 63, 255, 63),
- ],
- )
+ self.assert_9points_paste(
+ im,
+ color,
+ self.gradient_RGBa,
+ [
+ (255, 63, 126, 63),
+ (47, 143, 142, 46),
+ (126, 253, 126, 255),
+ (15, 15, 47, 47),
+ (63, 63, 62, 63),
+ (142, 141, 46, 47),
+ (255, 255, 255, 0),
+ (48, 15, 15, 47),
+ (126, 63, 255, 63),
+ ],
+ )
def test_different_sizes(self):
im = Image.new("RGB", (100, 100))
diff --git a/depends/install_imagequant.sh b/depends/install_imagequant.sh
index 9b3088b94..76f4cb95f 100755
--- a/depends/install_imagequant.sh
+++ b/depends/install_imagequant.sh
@@ -1,7 +1,7 @@
#!/bin/bash
# install libimagequant
-archive=libimagequant-4.0.1
+archive=libimagequant-4.0.2
./download-and-extract.sh $archive https://raw.githubusercontent.com/python-pillow/pillow-depends/main/$archive.tar.gz
diff --git a/docs/installation.rst b/docs/installation.rst
index 42cd7df9d..a8cd5e441 100644
--- a/docs/installation.rst
+++ b/docs/installation.rst
@@ -166,7 +166,7 @@ Many of Pillow's features require external libraries:
* **libimagequant** provides improved color quantization
- * Pillow has been tested with libimagequant **2.6-4.0.1**
+ * Pillow has been tested with libimagequant **2.6-4.0.2**
* Libimagequant is licensed GPLv3, which is more restrictive than
the Pillow license, therefore we will not be distributing binaries
with libimagequant support enabled.
diff --git a/winbuild/build_prepare.py b/winbuild/build_prepare.py
index a381d636d..94e5dd871 100644
--- a/winbuild/build_prepare.py
+++ b/winbuild/build_prepare.py
@@ -226,21 +226,21 @@ deps = {
"filename": "lcms2-2.13.1.tar.gz",
"dir": "lcms2-2.13.1",
"patch": {
- r"Projects\VC2019\lcms2_static\lcms2_static.vcxproj": {
+ r"Projects\VC2022\lcms2_static\lcms2_static.vcxproj": {
# default is /MD for x86 and /MT for x64, we need /MD always
"MultiThreaded": "MultiThreadedDLL", # noqa: E501
# retarget to default toolset (selected by vcvarsall.bat)
- "v142": "$(DefaultPlatformToolset)", # noqa: E501
+ "v143": "$(DefaultPlatformToolset)", # noqa: E501
# retarget to latest (selected by vcvarsall.bat)
"10.0": "$(WindowsSDKVersion)", # noqa: E501
}
},
"build": [
cmd_rmdir("Lib"),
- cmd_rmdir(r"Projects\VC2019\Release"),
- cmd_msbuild(r"Projects\VC2019\lcms2.sln", "Release", "Clean"),
+ cmd_rmdir(r"Projects\VC2022\Release"),
+ cmd_msbuild(r"Projects\VC2022\lcms2.sln", "Release", "Clean"),
cmd_msbuild(
- r"Projects\VC2019\lcms2.sln", "Release", "lcms2_static:Rebuild"
+ r"Projects\VC2022\lcms2.sln", "Release", "lcms2_static:Rebuild"
),
cmd_xcopy("include", "{inc_dir}"),
],