mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-07-08 13:53:21 +03:00
Merge branch 'main' into add-cygwin-to-ci
This commit is contained in:
commit
3005ea1ef3
1149
CHANGES.rst
1149
CHANGES.rst
File diff suppressed because it is too large
Load Diff
BIN
Tests/images/tiff_wrong_bits_per_sample_3.tiff
Normal file
BIN
Tests/images/tiff_wrong_bits_per_sample_3.tiff
Normal file
Binary file not shown.
BIN
Tests/images/zero_height.j2k
Normal file
BIN
Tests/images/zero_height.j2k
Normal file
Binary file not shown.
|
@ -145,6 +145,19 @@ def test_truncated_file(tmp_path):
|
||||||
im.load()
|
im.load()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("maxval", (0, 65536))
|
||||||
|
def test_invalid_maxval(maxval, tmp_path):
|
||||||
|
path = str(tmp_path / "temp.ppm")
|
||||||
|
with open(path, "w") as f:
|
||||||
|
f.write("P6\n3 1 " + str(maxval))
|
||||||
|
|
||||||
|
with pytest.raises(ValueError) as e:
|
||||||
|
with Image.open(path):
|
||||||
|
pass
|
||||||
|
|
||||||
|
assert str(e.value) == "maxval must be greater than 0 and less than 65536"
|
||||||
|
|
||||||
|
|
||||||
def test_neg_ppm():
|
def test_neg_ppm():
|
||||||
# Storage.c accepted negative values for xsize, ysize. the
|
# Storage.c accepted negative values for xsize, ysize. the
|
||||||
# internal open_ppm function didn't check for sanity but it
|
# internal open_ppm function didn't check for sanity but it
|
||||||
|
|
|
@ -92,17 +92,33 @@ class TestFileTiff:
|
||||||
assert_image_equal_tofile(im, "Tests/images/hopper.tif")
|
assert_image_equal_tofile(im, "Tests/images/hopper.tif")
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"file_name,mode,size,offset",
|
"file_name,mode,size,tile",
|
||||||
[
|
[
|
||||||
("tiff_wrong_bits_per_sample.tiff", "RGBA", (52, 53), 160),
|
(
|
||||||
("tiff_wrong_bits_per_sample_2.tiff", "RGB", (16, 16), 8),
|
"tiff_wrong_bits_per_sample.tiff",
|
||||||
|
"RGBA",
|
||||||
|
(52, 53),
|
||||||
|
[("raw", (0, 0, 52, 53), 160, ("RGBA", 0, 1))],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"tiff_wrong_bits_per_sample_2.tiff",
|
||||||
|
"RGB",
|
||||||
|
(16, 16),
|
||||||
|
[("raw", (0, 0, 16, 16), 8, ("RGB", 0, 1))],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"tiff_wrong_bits_per_sample_3.tiff",
|
||||||
|
"RGBA",
|
||||||
|
(512, 256),
|
||||||
|
[("libtiff", (0, 0, 512, 256), 0, ("RGBA", "tiff_lzw", False, 48782))],
|
||||||
|
),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_wrong_bits_per_sample(self, file_name, mode, size, offset):
|
def test_wrong_bits_per_sample(self, file_name, mode, size, tile):
|
||||||
with Image.open("Tests/images/" + file_name) as im:
|
with Image.open("Tests/images/" + file_name) as im:
|
||||||
assert im.mode == mode
|
assert im.mode == mode
|
||||||
assert im.size == size
|
assert im.size == size
|
||||||
assert im.tile == [("raw", (0, 0) + size, offset, (mode, 0, 1))]
|
assert im.tile == tile
|
||||||
im.load()
|
im.load()
|
||||||
|
|
||||||
def test_set_legacy_api(self):
|
def test_set_legacy_api(self):
|
||||||
|
|
|
@ -2,7 +2,15 @@ from io import BytesIO
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from PIL import BmpImagePlugin, EpsImagePlugin, Image, ImageFile, _binary, features
|
from PIL import (
|
||||||
|
BmpImagePlugin,
|
||||||
|
EpsImagePlugin,
|
||||||
|
Image,
|
||||||
|
ImageFile,
|
||||||
|
UnidentifiedImageError,
|
||||||
|
_binary,
|
||||||
|
features,
|
||||||
|
)
|
||||||
|
|
||||||
from .helper import (
|
from .helper import (
|
||||||
assert_image,
|
assert_image,
|
||||||
|
@ -377,3 +385,7 @@ class TestPyEncoder(CodecsTest):
|
||||||
|
|
||||||
with pytest.raises(NotImplementedError):
|
with pytest.raises(NotImplementedError):
|
||||||
encoder.encode_to_file(None, None)
|
encoder.encode_to_file(None, None)
|
||||||
|
|
||||||
|
def test_zero_height(self):
|
||||||
|
with pytest.raises(UnidentifiedImageError):
|
||||||
|
Image.open("Tests/images/zero_height.j2k")
|
||||||
|
|
|
@ -26,6 +26,8 @@ def setup_module():
|
||||||
# setup tk
|
# setup tk
|
||||||
tk.Frame()
|
tk.Frame()
|
||||||
# root = tk.Tk()
|
# root = tk.Tk()
|
||||||
|
except RuntimeError as v:
|
||||||
|
pytest.skip(f"RuntimeError: {v}")
|
||||||
except tk.TclError as v:
|
except tk.TclError as v:
|
||||||
pytest.skip(f"TCL Error: {v}")
|
pytest.skip(f"TCL Error: {v}")
|
||||||
|
|
||||||
|
|
10
setup.py
10
setup.py
|
@ -250,15 +250,21 @@ def _cmd_exists(cmd):
|
||||||
|
|
||||||
|
|
||||||
def _pkg_config(name):
|
def _pkg_config(name):
|
||||||
try:
|
|
||||||
command = os.environ.get("PKG_CONFIG", "pkg-config")
|
command = os.environ.get("PKG_CONFIG", "pkg-config")
|
||||||
|
for keep_system in (True, False):
|
||||||
|
try:
|
||||||
command_libs = [command, "--libs-only-L", name]
|
command_libs = [command, "--libs-only-L", name]
|
||||||
command_cflags = [command, "--cflags-only-I", name]
|
command_cflags = [command, "--cflags-only-I", name]
|
||||||
|
stderr = None
|
||||||
|
if keep_system:
|
||||||
|
command_libs.append("--keep-system-libs")
|
||||||
|
command_cflags.append("--keep-system-cflags")
|
||||||
|
stderr = subprocess.DEVNULL
|
||||||
if not DEBUG:
|
if not DEBUG:
|
||||||
command_libs.append("--silence-errors")
|
command_libs.append("--silence-errors")
|
||||||
command_cflags.append("--silence-errors")
|
command_cflags.append("--silence-errors")
|
||||||
libs = (
|
libs = (
|
||||||
subprocess.check_output(command_libs)
|
subprocess.check_output(command_libs, stderr=stderr)
|
||||||
.decode("utf8")
|
.decode("utf8")
|
||||||
.strip()
|
.strip()
|
||||||
.replace("-L", "")
|
.replace("-L", "")
|
||||||
|
|
|
@ -123,7 +123,7 @@ class ImageFile(Image.Image):
|
||||||
) as v:
|
) as v:
|
||||||
raise SyntaxError(v) from v
|
raise SyntaxError(v) from v
|
||||||
|
|
||||||
if not self.mode or self.size[0] <= 0:
|
if not self.mode or self.size[0] <= 0 or self.size[1] <= 0:
|
||||||
raise SyntaxError("not identified by this driver")
|
raise SyntaxError("not identified by this driver")
|
||||||
except BaseException:
|
except BaseException:
|
||||||
# close the file only if we have opened it this constructor
|
# close the file only if we have opened it this constructor
|
||||||
|
|
|
@ -116,6 +116,10 @@ class PpmImageFile(ImageFile.ImageFile):
|
||||||
break
|
break
|
||||||
elif ix == 2: # token is maxval
|
elif ix == 2: # token is maxval
|
||||||
maxval = token
|
maxval = token
|
||||||
|
if not 0 < maxval < 65536:
|
||||||
|
raise ValueError(
|
||||||
|
"maxval must be greater than 0 and less than 65536"
|
||||||
|
)
|
||||||
if maxval > 255 and mode == "L":
|
if maxval > 255 and mode == "L":
|
||||||
self.mode = "I"
|
self.mode = "I"
|
||||||
|
|
||||||
|
|
|
@ -1355,19 +1355,19 @@ class TiffImageFile(ImageFile.ImageFile):
|
||||||
bps_count = 1
|
bps_count = 1
|
||||||
bps_count += len(extra_tuple)
|
bps_count += len(extra_tuple)
|
||||||
bps_actual_count = len(bps_tuple)
|
bps_actual_count = len(bps_tuple)
|
||||||
if bps_count < bps_actual_count:
|
|
||||||
# If a file has more values in bps_tuple than expected,
|
|
||||||
# remove the excess.
|
|
||||||
bps_tuple = bps_tuple[:bps_count]
|
|
||||||
elif bps_count > bps_actual_count and bps_actual_count == 1:
|
|
||||||
# If a file has only one value in bps_tuple, when it should have more,
|
|
||||||
# presume it is the same number of bits for all of the samples.
|
|
||||||
bps_tuple = bps_tuple * bps_count
|
|
||||||
|
|
||||||
samples_per_pixel = self.tag_v2.get(
|
samples_per_pixel = self.tag_v2.get(
|
||||||
SAMPLESPERPIXEL,
|
SAMPLESPERPIXEL,
|
||||||
3 if self._compression == "tiff_jpeg" and photo in (2, 6) else 1,
|
3 if self._compression == "tiff_jpeg" and photo in (2, 6) else 1,
|
||||||
)
|
)
|
||||||
|
if samples_per_pixel < bps_actual_count:
|
||||||
|
# If a file has more values in bps_tuple than expected,
|
||||||
|
# remove the excess.
|
||||||
|
bps_tuple = bps_tuple[:samples_per_pixel]
|
||||||
|
elif samples_per_pixel > bps_actual_count and bps_actual_count == 1:
|
||||||
|
# If a file has only one value in bps_tuple, when it should have more,
|
||||||
|
# presume it is the same number of bits for all of the samples.
|
||||||
|
bps_tuple = bps_tuple * samples_per_pixel
|
||||||
|
|
||||||
if len(bps_tuple) != samples_per_pixel:
|
if len(bps_tuple) != samples_per_pixel:
|
||||||
raise SyntaxError("unknown data organization")
|
raise SyntaxError("unknown data organization")
|
||||||
|
|
||||||
|
|
|
@ -186,9 +186,9 @@ deps = {
|
||||||
"libs": [r"libpng16.lib"],
|
"libs": [r"libpng16.lib"],
|
||||||
},
|
},
|
||||||
"freetype": {
|
"freetype": {
|
||||||
"url": "https://download.savannah.gnu.org/releases/freetype/freetype-2.12.0.tar.gz", # noqa: E501
|
"url": "https://download.savannah.gnu.org/releases/freetype/freetype-2.12.1.tar.gz", # noqa: E501
|
||||||
"filename": "freetype-2.12.0.tar.gz",
|
"filename": "freetype-2.12.1.tar.gz",
|
||||||
"dir": "freetype-2.12.0",
|
"dir": "freetype-2.12.1",
|
||||||
"patch": {
|
"patch": {
|
||||||
r"builds\windows\vc2010\freetype.vcxproj": {
|
r"builds\windows\vc2010\freetype.vcxproj": {
|
||||||
# freetype setting is /MD for .dll and /MT for .lib, we need /MD
|
# freetype setting is /MD for .dll and /MT for .lib, we need /MD
|
||||||
|
|
Loading…
Reference in New Issue
Block a user