mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-03-13 09:15:46 +03:00
Merge branch 'main' into libavif-plugin
This commit is contained in:
commit
6cbad27c27
6
.github/workflows/macos-install.sh
vendored
6
.github/workflows/macos-install.sh
vendored
|
@ -10,6 +10,7 @@ brew install \
|
||||||
ghostscript \
|
ghostscript \
|
||||||
jpeg-turbo \
|
jpeg-turbo \
|
||||||
libimagequant \
|
libimagequant \
|
||||||
|
libraqm \
|
||||||
libtiff \
|
libtiff \
|
||||||
little-cms2 \
|
little-cms2 \
|
||||||
openjpeg \
|
openjpeg \
|
||||||
|
@ -18,11 +19,6 @@ brew install \
|
||||||
aom \
|
aom \
|
||||||
rav1e \
|
rav1e \
|
||||||
svt-av1
|
svt-av1
|
||||||
if [[ "$ImageOS" == "macos13" ]]; then
|
|
||||||
brew install --ignore-dependencies libraqm
|
|
||||||
else
|
|
||||||
brew install libraqm
|
|
||||||
fi
|
|
||||||
export PKG_CONFIG_PATH="/usr/local/opt/openblas/lib/pkgconfig"
|
export PKG_CONFIG_PATH="/usr/local/opt/openblas/lib/pkgconfig"
|
||||||
|
|
||||||
python3 -m pip install coverage
|
python3 -m pip install coverage
|
||||||
|
|
|
@ -3,26 +3,25 @@ from __future__ import annotations
|
||||||
import zlib
|
import zlib
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
from PIL import Image, ImageFile, PngImagePlugin
|
from PIL import Image, ImageFile, PngImagePlugin
|
||||||
|
|
||||||
TEST_FILE = "Tests/images/png_decompression_dos.png"
|
TEST_FILE = "Tests/images/png_decompression_dos.png"
|
||||||
|
|
||||||
|
|
||||||
def test_ignore_dos_text() -> None:
|
def test_ignore_dos_text(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||||
ImageFile.LOAD_TRUNCATED_IMAGES = True
|
monkeypatch.setattr(ImageFile, "LOAD_TRUNCATED_IMAGES", True)
|
||||||
|
|
||||||
try:
|
with Image.open(TEST_FILE) as im:
|
||||||
im = Image.open(TEST_FILE)
|
|
||||||
im.load()
|
im.load()
|
||||||
finally:
|
|
||||||
ImageFile.LOAD_TRUNCATED_IMAGES = False
|
|
||||||
|
|
||||||
assert isinstance(im, PngImagePlugin.PngImageFile)
|
assert isinstance(im, PngImagePlugin.PngImageFile)
|
||||||
for s in im.text.values():
|
for s in im.text.values():
|
||||||
assert len(s) < 1024 * 1024, "Text chunk larger than 1M"
|
assert len(s) < 1024 * 1024, "Text chunk larger than 1M"
|
||||||
|
|
||||||
for s in im.info.values():
|
for s in im.info.values():
|
||||||
assert len(s) < 1024 * 1024, "Text chunk larger than 1M"
|
assert len(s) < 1024 * 1024, "Text chunk larger than 1M"
|
||||||
|
|
||||||
|
|
||||||
def test_dos_text() -> None:
|
def test_dos_text() -> None:
|
||||||
|
|
|
@ -12,19 +12,16 @@ ORIGINAL_LIMIT = Image.MAX_IMAGE_PIXELS
|
||||||
|
|
||||||
|
|
||||||
class TestDecompressionBomb:
|
class TestDecompressionBomb:
|
||||||
def teardown_method(self) -> None:
|
|
||||||
Image.MAX_IMAGE_PIXELS = ORIGINAL_LIMIT
|
|
||||||
|
|
||||||
def test_no_warning_small_file(self) -> None:
|
def test_no_warning_small_file(self) -> None:
|
||||||
# Implicit assert: no warning.
|
# Implicit assert: no warning.
|
||||||
# A warning would cause a failure.
|
# A warning would cause a failure.
|
||||||
with Image.open(TEST_FILE):
|
with Image.open(TEST_FILE):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def test_no_warning_no_limit(self) -> None:
|
def test_no_warning_no_limit(self, monkeypatch: pytest.MonkeyPatch) -> None:
|
||||||
# Arrange
|
# Arrange
|
||||||
# Turn limit off
|
# Turn limit off
|
||||||
Image.MAX_IMAGE_PIXELS = None
|
monkeypatch.setattr(Image, "MAX_IMAGE_PIXELS", None)
|
||||||
assert Image.MAX_IMAGE_PIXELS is None
|
assert Image.MAX_IMAGE_PIXELS is None
|
||||||
|
|
||||||
# Act / Assert
|
# Act / Assert
|
||||||
|
@ -33,18 +30,18 @@ class TestDecompressionBomb:
|
||||||
with Image.open(TEST_FILE):
|
with Image.open(TEST_FILE):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def test_warning(self) -> None:
|
def test_warning(self, monkeypatch: pytest.MonkeyPatch) -> None:
|
||||||
# Set limit to trigger warning on the test file
|
# Set limit to trigger warning on the test file
|
||||||
Image.MAX_IMAGE_PIXELS = 128 * 128 - 1
|
monkeypatch.setattr(Image, "MAX_IMAGE_PIXELS", 128 * 128 - 1)
|
||||||
assert Image.MAX_IMAGE_PIXELS == 128 * 128 - 1
|
assert Image.MAX_IMAGE_PIXELS == 128 * 128 - 1
|
||||||
|
|
||||||
with pytest.warns(Image.DecompressionBombWarning):
|
with pytest.warns(Image.DecompressionBombWarning):
|
||||||
with Image.open(TEST_FILE):
|
with Image.open(TEST_FILE):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def test_exception(self) -> None:
|
def test_exception(self, monkeypatch: pytest.MonkeyPatch) -> None:
|
||||||
# Set limit to trigger exception on the test file
|
# Set limit to trigger exception on the test file
|
||||||
Image.MAX_IMAGE_PIXELS = 64 * 128 - 1
|
monkeypatch.setattr(Image, "MAX_IMAGE_PIXELS", 64 * 128 - 1)
|
||||||
assert Image.MAX_IMAGE_PIXELS == 64 * 128 - 1
|
assert Image.MAX_IMAGE_PIXELS == 64 * 128 - 1
|
||||||
|
|
||||||
with pytest.raises(Image.DecompressionBombError):
|
with pytest.raises(Image.DecompressionBombError):
|
||||||
|
@ -66,9 +63,9 @@ class TestDecompressionBomb:
|
||||||
with pytest.raises(Image.DecompressionBombError):
|
with pytest.raises(Image.DecompressionBombError):
|
||||||
im.seek(1)
|
im.seek(1)
|
||||||
|
|
||||||
def test_exception_gif_zero_width(self) -> None:
|
def test_exception_gif_zero_width(self, monkeypatch: pytest.MonkeyPatch) -> None:
|
||||||
# Set limit to trigger exception on the test file
|
# Set limit to trigger exception on the test file
|
||||||
Image.MAX_IMAGE_PIXELS = 4 * 64 * 128
|
monkeypatch.setattr(Image, "MAX_IMAGE_PIXELS", 4 * 64 * 128)
|
||||||
assert Image.MAX_IMAGE_PIXELS == 4 * 64 * 128
|
assert Image.MAX_IMAGE_PIXELS == 4 * 64 * 128
|
||||||
|
|
||||||
with pytest.raises(Image.DecompressionBombError):
|
with pytest.raises(Image.DecompressionBombError):
|
||||||
|
|
|
@ -35,22 +35,19 @@ def test_sanity() -> None:
|
||||||
assert im.is_animated
|
assert im.is_animated
|
||||||
|
|
||||||
|
|
||||||
def test_prefix_chunk() -> None:
|
def test_prefix_chunk(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||||
ImageFile.LOAD_TRUNCATED_IMAGES = True
|
monkeypatch.setattr(ImageFile, "LOAD_TRUNCATED_IMAGES", True)
|
||||||
try:
|
with Image.open(animated_test_file_with_prefix_chunk) as im:
|
||||||
with Image.open(animated_test_file_with_prefix_chunk) as im:
|
assert im.mode == "P"
|
||||||
assert im.mode == "P"
|
assert im.size == (320, 200)
|
||||||
assert im.size == (320, 200)
|
assert im.format == "FLI"
|
||||||
assert im.format == "FLI"
|
assert im.info["duration"] == 171
|
||||||
assert im.info["duration"] == 171
|
assert im.is_animated
|
||||||
assert im.is_animated
|
|
||||||
|
|
||||||
palette = im.getpalette()
|
palette = im.getpalette()
|
||||||
assert palette[3:6] == [255, 255, 255]
|
assert palette[3:6] == [255, 255, 255]
|
||||||
assert palette[381:384] == [204, 204, 12]
|
assert palette[381:384] == [204, 204, 12]
|
||||||
assert palette[765:] == [252, 0, 0]
|
assert palette[765:] == [252, 0, 0]
|
||||||
finally:
|
|
||||||
ImageFile.LOAD_TRUNCATED_IMAGES = False
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif(is_pypy(), reason="Requires CPython")
|
@pytest.mark.skipif(is_pypy(), reason="Requires CPython")
|
||||||
|
|
|
@ -109,7 +109,7 @@ def test_palette_not_needed_for_second_frame() -> None:
|
||||||
assert_image_similar(im, hopper("L").convert("RGB"), 8)
|
assert_image_similar(im, hopper("L").convert("RGB"), 8)
|
||||||
|
|
||||||
|
|
||||||
def test_strategy() -> None:
|
def test_strategy(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||||
with Image.open("Tests/images/iss634.gif") as im:
|
with Image.open("Tests/images/iss634.gif") as im:
|
||||||
expected_rgb_always = im.convert("RGB")
|
expected_rgb_always = im.convert("RGB")
|
||||||
|
|
||||||
|
@ -119,35 +119,36 @@ def test_strategy() -> None:
|
||||||
im.seek(1)
|
im.seek(1)
|
||||||
expected_different = im.convert("RGB")
|
expected_different = im.convert("RGB")
|
||||||
|
|
||||||
try:
|
monkeypatch.setattr(
|
||||||
GifImagePlugin.LOADING_STRATEGY = GifImagePlugin.LoadingStrategy.RGB_ALWAYS
|
GifImagePlugin, "LOADING_STRATEGY", GifImagePlugin.LoadingStrategy.RGB_ALWAYS
|
||||||
with Image.open("Tests/images/iss634.gif") as im:
|
)
|
||||||
assert im.mode == "RGB"
|
with Image.open("Tests/images/iss634.gif") as im:
|
||||||
assert_image_equal(im, expected_rgb_always)
|
assert im.mode == "RGB"
|
||||||
|
assert_image_equal(im, expected_rgb_always)
|
||||||
|
|
||||||
with Image.open("Tests/images/chi.gif") as im:
|
with Image.open("Tests/images/chi.gif") as im:
|
||||||
assert im.mode == "RGBA"
|
assert im.mode == "RGBA"
|
||||||
assert_image_equal(im, expected_rgb_always_rgba)
|
assert_image_equal(im, expected_rgb_always_rgba)
|
||||||
|
|
||||||
GifImagePlugin.LOADING_STRATEGY = (
|
monkeypatch.setattr(
|
||||||
GifImagePlugin.LoadingStrategy.RGB_AFTER_DIFFERENT_PALETTE_ONLY
|
GifImagePlugin,
|
||||||
)
|
"LOADING_STRATEGY",
|
||||||
# Stay in P mode with only a global palette
|
GifImagePlugin.LoadingStrategy.RGB_AFTER_DIFFERENT_PALETTE_ONLY,
|
||||||
with Image.open("Tests/images/chi.gif") as im:
|
)
|
||||||
assert im.mode == "P"
|
# Stay in P mode with only a global palette
|
||||||
|
with Image.open("Tests/images/chi.gif") as im:
|
||||||
|
assert im.mode == "P"
|
||||||
|
|
||||||
im.seek(1)
|
im.seek(1)
|
||||||
assert im.mode == "P"
|
assert im.mode == "P"
|
||||||
assert_image_equal(im.convert("RGB"), expected_different)
|
assert_image_equal(im.convert("RGB"), expected_different)
|
||||||
|
|
||||||
# Change to RGB mode when a frame has an individual palette
|
# Change to RGB mode when a frame has an individual palette
|
||||||
with Image.open("Tests/images/iss634.gif") as im:
|
with Image.open("Tests/images/iss634.gif") as im:
|
||||||
assert im.mode == "P"
|
assert im.mode == "P"
|
||||||
|
|
||||||
im.seek(1)
|
im.seek(1)
|
||||||
assert im.mode == "RGB"
|
assert im.mode == "RGB"
|
||||||
finally:
|
|
||||||
GifImagePlugin.LOADING_STRATEGY = GifImagePlugin.LoadingStrategy.RGB_AFTER_FIRST
|
|
||||||
|
|
||||||
|
|
||||||
def test_optimize() -> None:
|
def test_optimize() -> None:
|
||||||
|
@ -555,17 +556,15 @@ def test_dispose_background_transparency() -> None:
|
||||||
def test_transparent_dispose(
|
def test_transparent_dispose(
|
||||||
loading_strategy: GifImagePlugin.LoadingStrategy,
|
loading_strategy: GifImagePlugin.LoadingStrategy,
|
||||||
expected_colors: tuple[tuple[int | tuple[int, int, int, int], ...]],
|
expected_colors: tuple[tuple[int | tuple[int, int, int, int], ...]],
|
||||||
|
monkeypatch: pytest.MonkeyPatch,
|
||||||
) -> None:
|
) -> None:
|
||||||
GifImagePlugin.LOADING_STRATEGY = loading_strategy
|
monkeypatch.setattr(GifImagePlugin, "LOADING_STRATEGY", loading_strategy)
|
||||||
try:
|
with Image.open("Tests/images/transparent_dispose.gif") as img:
|
||||||
with Image.open("Tests/images/transparent_dispose.gif") as img:
|
for frame in range(3):
|
||||||
for frame in range(3):
|
img.seek(frame)
|
||||||
img.seek(frame)
|
for x in range(3):
|
||||||
for x in range(3):
|
color = img.getpixel((x, 0))
|
||||||
color = img.getpixel((x, 0))
|
assert color == expected_colors[frame][x]
|
||||||
assert color == expected_colors[frame][x]
|
|
||||||
finally:
|
|
||||||
GifImagePlugin.LOADING_STRATEGY = GifImagePlugin.LoadingStrategy.RGB_AFTER_FIRST
|
|
||||||
|
|
||||||
|
|
||||||
def test_dispose_previous() -> None:
|
def test_dispose_previous() -> None:
|
||||||
|
@ -1398,24 +1397,23 @@ def test_lzw_bits() -> None:
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
def test_extents(
|
def test_extents(
|
||||||
test_file: str, loading_strategy: GifImagePlugin.LoadingStrategy
|
test_file: str,
|
||||||
|
loading_strategy: GifImagePlugin.LoadingStrategy,
|
||||||
|
monkeypatch: pytest.MonkeyPatch,
|
||||||
) -> None:
|
) -> None:
|
||||||
GifImagePlugin.LOADING_STRATEGY = loading_strategy
|
monkeypatch.setattr(GifImagePlugin, "LOADING_STRATEGY", loading_strategy)
|
||||||
try:
|
with Image.open("Tests/images/" + test_file) as im:
|
||||||
with Image.open("Tests/images/" + test_file) as im:
|
assert im.size == (100, 100)
|
||||||
assert im.size == (100, 100)
|
|
||||||
|
|
||||||
# Check that n_frames does not change the size
|
# Check that n_frames does not change the size
|
||||||
assert im.n_frames == 2
|
assert im.n_frames == 2
|
||||||
assert im.size == (100, 100)
|
assert im.size == (100, 100)
|
||||||
|
|
||||||
im.seek(1)
|
im.seek(1)
|
||||||
assert im.size == (150, 150)
|
assert im.size == (150, 150)
|
||||||
|
|
||||||
im.load()
|
im.load()
|
||||||
assert im.im.size == (150, 150)
|
assert im.im.size == (150, 150)
|
||||||
finally:
|
|
||||||
GifImagePlugin.LOADING_STRATEGY = GifImagePlugin.LoadingStrategy.RGB_AFTER_FIRST
|
|
||||||
|
|
||||||
|
|
||||||
def test_missing_background() -> None:
|
def test_missing_background() -> None:
|
||||||
|
|
|
@ -243,26 +243,23 @@ def test_draw_reloaded(tmp_path: Path) -> None:
|
||||||
assert_image_equal_tofile(im, "Tests/images/hopper_draw.ico")
|
assert_image_equal_tofile(im, "Tests/images/hopper_draw.ico")
|
||||||
|
|
||||||
|
|
||||||
def test_truncated_mask() -> None:
|
def test_truncated_mask(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||||
# 1 bpp
|
# 1 bpp
|
||||||
with open("Tests/images/hopper_mask.ico", "rb") as fp:
|
with open("Tests/images/hopper_mask.ico", "rb") as fp:
|
||||||
data = fp.read()
|
data = fp.read()
|
||||||
|
|
||||||
ImageFile.LOAD_TRUNCATED_IMAGES = True
|
monkeypatch.setattr(ImageFile, "LOAD_TRUNCATED_IMAGES", True)
|
||||||
data = data[:-3]
|
data = data[:-3]
|
||||||
|
|
||||||
try:
|
with Image.open(io.BytesIO(data)) as im:
|
||||||
with Image.open(io.BytesIO(data)) as im:
|
assert im.mode == "1"
|
||||||
assert im.mode == "1"
|
|
||||||
|
|
||||||
# 32 bpp
|
# 32 bpp
|
||||||
output = io.BytesIO()
|
output = io.BytesIO()
|
||||||
expected = hopper("RGBA")
|
expected = hopper("RGBA")
|
||||||
expected.save(output, "ico", bitmap_format="bmp")
|
expected.save(output, "ico", bitmap_format="bmp")
|
||||||
|
|
||||||
data = output.getvalue()[:-1]
|
data = output.getvalue()[:-1]
|
||||||
|
|
||||||
with Image.open(io.BytesIO(data)) as im:
|
with Image.open(io.BytesIO(data)) as im:
|
||||||
assert im.mode == "RGB"
|
assert im.mode == "RGB"
|
||||||
finally:
|
|
||||||
ImageFile.LOAD_TRUNCATED_IMAGES = False
|
|
||||||
|
|
|
@ -530,12 +530,13 @@ class TestFileJpeg:
|
||||||
@mark_if_feature_version(
|
@mark_if_feature_version(
|
||||||
pytest.mark.valgrind_known_error, "libjpeg_turbo", "2.0", reason="Known Failing"
|
pytest.mark.valgrind_known_error, "libjpeg_turbo", "2.0", reason="Known Failing"
|
||||||
)
|
)
|
||||||
def test_truncated_jpeg_should_read_all_the_data(self) -> None:
|
def test_truncated_jpeg_should_read_all_the_data(
|
||||||
|
self, monkeypatch: pytest.MonkeyPatch
|
||||||
|
) -> None:
|
||||||
filename = "Tests/images/truncated_jpeg.jpg"
|
filename = "Tests/images/truncated_jpeg.jpg"
|
||||||
ImageFile.LOAD_TRUNCATED_IMAGES = True
|
monkeypatch.setattr(ImageFile, "LOAD_TRUNCATED_IMAGES", True)
|
||||||
with Image.open(filename) as im:
|
with Image.open(filename) as im:
|
||||||
im.load()
|
im.load()
|
||||||
ImageFile.LOAD_TRUNCATED_IMAGES = False
|
|
||||||
assert im.getbbox() is not None
|
assert im.getbbox() is not None
|
||||||
|
|
||||||
def test_truncated_jpeg_throws_oserror(self) -> None:
|
def test_truncated_jpeg_throws_oserror(self) -> None:
|
||||||
|
@ -1024,7 +1025,7 @@ class TestFileJpeg:
|
||||||
im.save(f, xmp=b"1" * 65505)
|
im.save(f, xmp=b"1" * 65505)
|
||||||
|
|
||||||
@pytest.mark.timeout(timeout=1)
|
@pytest.mark.timeout(timeout=1)
|
||||||
def test_eof(self) -> None:
|
def test_eof(self, monkeypatch: pytest.MonkeyPatch) -> None:
|
||||||
# Even though this decoder never says that it is finished
|
# Even though this decoder never says that it is finished
|
||||||
# the image should still end when there is no new data
|
# the image should still end when there is no new data
|
||||||
class InfiniteMockPyDecoder(ImageFile.PyDecoder):
|
class InfiniteMockPyDecoder(ImageFile.PyDecoder):
|
||||||
|
@ -1039,9 +1040,8 @@ class TestFileJpeg:
|
||||||
im.tile = [
|
im.tile = [
|
||||||
ImageFile._Tile("INFINITE", (0, 0, 128, 128), 0, ("RGB", 0, 1)),
|
ImageFile._Tile("INFINITE", (0, 0, 128, 128), 0, ("RGB", 0, 1)),
|
||||||
]
|
]
|
||||||
ImageFile.LOAD_TRUNCATED_IMAGES = True
|
monkeypatch.setattr(ImageFile, "LOAD_TRUNCATED_IMAGES", True)
|
||||||
im.load()
|
im.load()
|
||||||
ImageFile.LOAD_TRUNCATED_IMAGES = False
|
|
||||||
|
|
||||||
def test_separate_tables(self) -> None:
|
def test_separate_tables(self) -> None:
|
||||||
im = hopper()
|
im = hopper()
|
||||||
|
|
|
@ -181,14 +181,11 @@ def test_load_dpi() -> None:
|
||||||
assert "dpi" not in im.info
|
assert "dpi" not in im.info
|
||||||
|
|
||||||
|
|
||||||
def test_restricted_icc_profile() -> None:
|
def test_restricted_icc_profile(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||||
ImageFile.LOAD_TRUNCATED_IMAGES = True
|
monkeypatch.setattr(ImageFile, "LOAD_TRUNCATED_IMAGES", True)
|
||||||
try:
|
# JPEG2000 image with a restricted ICC profile and a known colorspace
|
||||||
# JPEG2000 image with a restricted ICC profile and a known colorspace
|
with Image.open("Tests/images/balloon_eciRGBv2_aware.jp2") as im:
|
||||||
with Image.open("Tests/images/balloon_eciRGBv2_aware.jp2") as im:
|
assert im.mode == "RGB"
|
||||||
assert im.mode == "RGB"
|
|
||||||
finally:
|
|
||||||
ImageFile.LOAD_TRUNCATED_IMAGES = False
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif(
|
@pytest.mark.skipif(
|
||||||
|
|
|
@ -1103,13 +1103,15 @@ class TestFileLibTiff(LibTiffTestCase):
|
||||||
)
|
)
|
||||||
def test_buffering(self, test_file: str) -> None:
|
def test_buffering(self, test_file: str) -> None:
|
||||||
# load exif first
|
# load exif first
|
||||||
with Image.open(open(test_file, "rb", buffering=1048576)) as im:
|
with open(test_file, "rb", buffering=1048576) as f:
|
||||||
exif = dict(im.getexif())
|
with Image.open(f) as im:
|
||||||
|
exif = dict(im.getexif())
|
||||||
|
|
||||||
# load image before exif
|
# load image before exif
|
||||||
with Image.open(open(test_file, "rb", buffering=1048576)) as im2:
|
with open(test_file, "rb", buffering=1048576) as f:
|
||||||
im2.load()
|
with Image.open(f) as im2:
|
||||||
exif_after_load = dict(im2.getexif())
|
im2.load()
|
||||||
|
exif_after_load = dict(im2.getexif())
|
||||||
|
|
||||||
assert exif == exif_after_load
|
assert exif == exif_after_load
|
||||||
|
|
||||||
|
@ -1156,23 +1158,22 @@ class TestFileLibTiff(LibTiffTestCase):
|
||||||
assert len(im.tag_v2[STRIPOFFSETS]) > 1
|
assert len(im.tag_v2[STRIPOFFSETS]) > 1
|
||||||
|
|
||||||
@pytest.mark.parametrize("argument", (True, False))
|
@pytest.mark.parametrize("argument", (True, False))
|
||||||
def test_save_single_strip(self, argument: bool, tmp_path: Path) -> None:
|
def test_save_single_strip(
|
||||||
|
self, argument: bool, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
||||||
|
) -> None:
|
||||||
im = hopper("RGB").resize((256, 256))
|
im = hopper("RGB").resize((256, 256))
|
||||||
out = str(tmp_path / "temp.tif")
|
out = str(tmp_path / "temp.tif")
|
||||||
|
|
||||||
if not argument:
|
if not argument:
|
||||||
TiffImagePlugin.STRIP_SIZE = 2**18
|
monkeypatch.setattr(TiffImagePlugin, "STRIP_SIZE", 2**18)
|
||||||
try:
|
arguments: dict[str, str | int] = {"compression": "tiff_adobe_deflate"}
|
||||||
arguments: dict[str, str | int] = {"compression": "tiff_adobe_deflate"}
|
if argument:
|
||||||
if argument:
|
arguments["strip_size"] = 2**18
|
||||||
arguments["strip_size"] = 2**18
|
im.save(out, "TIFF", **arguments)
|
||||||
im.save(out, "TIFF", **arguments)
|
|
||||||
|
|
||||||
with Image.open(out) as im:
|
with Image.open(out) as im:
|
||||||
assert isinstance(im, TiffImagePlugin.TiffImageFile)
|
assert isinstance(im, TiffImagePlugin.TiffImageFile)
|
||||||
assert len(im.tag_v2[STRIPOFFSETS]) == 1
|
assert len(im.tag_v2[STRIPOFFSETS]) == 1
|
||||||
finally:
|
|
||||||
TiffImagePlugin.STRIP_SIZE = 65536
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("compression", ("tiff_adobe_deflate", None))
|
@pytest.mark.parametrize("compression", ("tiff_adobe_deflate", None))
|
||||||
def test_save_zero(self, compression: str | None, tmp_path: Path) -> None:
|
def test_save_zero(self, compression: str | None, tmp_path: Path) -> None:
|
||||||
|
|
|
@ -363,7 +363,7 @@ class TestFilePng:
|
||||||
with pytest.raises((OSError, SyntaxError)):
|
with pytest.raises((OSError, SyntaxError)):
|
||||||
im.verify()
|
im.verify()
|
||||||
|
|
||||||
def test_verify_ignores_crc_error(self) -> None:
|
def test_verify_ignores_crc_error(self, monkeypatch: pytest.MonkeyPatch) -> None:
|
||||||
# check ignores crc errors in ancillary chunks
|
# check ignores crc errors in ancillary chunks
|
||||||
|
|
||||||
chunk_data = chunk(b"tEXt", b"spam")
|
chunk_data = chunk(b"tEXt", b"spam")
|
||||||
|
@ -373,24 +373,20 @@ class TestFilePng:
|
||||||
with pytest.raises(SyntaxError):
|
with pytest.raises(SyntaxError):
|
||||||
PngImagePlugin.PngImageFile(BytesIO(image_data))
|
PngImagePlugin.PngImageFile(BytesIO(image_data))
|
||||||
|
|
||||||
ImageFile.LOAD_TRUNCATED_IMAGES = True
|
monkeypatch.setattr(ImageFile, "LOAD_TRUNCATED_IMAGES", True)
|
||||||
try:
|
im = load(image_data)
|
||||||
im = load(image_data)
|
assert im is not None
|
||||||
assert im is not None
|
|
||||||
finally:
|
|
||||||
ImageFile.LOAD_TRUNCATED_IMAGES = False
|
|
||||||
|
|
||||||
def test_verify_not_ignores_crc_error_in_required_chunk(self) -> None:
|
def test_verify_not_ignores_crc_error_in_required_chunk(
|
||||||
|
self, monkeypatch: pytest.MonkeyPatch
|
||||||
|
) -> None:
|
||||||
# check does not ignore crc errors in required chunks
|
# check does not ignore crc errors in required chunks
|
||||||
|
|
||||||
image_data = MAGIC + IHDR[:-1] + b"q" + TAIL
|
image_data = MAGIC + IHDR[:-1] + b"q" + TAIL
|
||||||
|
|
||||||
ImageFile.LOAD_TRUNCATED_IMAGES = True
|
monkeypatch.setattr(ImageFile, "LOAD_TRUNCATED_IMAGES", True)
|
||||||
try:
|
with pytest.raises(SyntaxError):
|
||||||
with pytest.raises(SyntaxError):
|
PngImagePlugin.PngImageFile(BytesIO(image_data))
|
||||||
PngImagePlugin.PngImageFile(BytesIO(image_data))
|
|
||||||
finally:
|
|
||||||
ImageFile.LOAD_TRUNCATED_IMAGES = False
|
|
||||||
|
|
||||||
def test_roundtrip_dpi(self) -> None:
|
def test_roundtrip_dpi(self) -> None:
|
||||||
# Check dpi roundtripping
|
# Check dpi roundtripping
|
||||||
|
@ -600,7 +596,7 @@ class TestFilePng:
|
||||||
(b"prIV", b"VALUE3", True),
|
(b"prIV", b"VALUE3", True),
|
||||||
]
|
]
|
||||||
|
|
||||||
def test_textual_chunks_after_idat(self) -> None:
|
def test_textual_chunks_after_idat(self, monkeypatch: pytest.MonkeyPatch) -> None:
|
||||||
with Image.open("Tests/images/hopper.png") as im:
|
with Image.open("Tests/images/hopper.png") as im:
|
||||||
assert "comment" in im.text
|
assert "comment" in im.text
|
||||||
for k, v in {
|
for k, v in {
|
||||||
|
@ -614,18 +610,17 @@ class TestFilePng:
|
||||||
with pytest.raises(OSError):
|
with pytest.raises(OSError):
|
||||||
assert isinstance(im.text, dict)
|
assert isinstance(im.text, dict)
|
||||||
|
|
||||||
|
# Raises an EOFError in load_end
|
||||||
|
with Image.open("Tests/images/hopper_idat_after_image_end.png") as im:
|
||||||
|
assert im.text == {"TXT": "VALUE", "ZIP": "VALUE"}
|
||||||
|
|
||||||
# Raises a UnicodeDecodeError in load_end
|
# Raises a UnicodeDecodeError in load_end
|
||||||
with Image.open("Tests/images/truncated_image.png") as im:
|
with Image.open("Tests/images/truncated_image.png") as im:
|
||||||
# The file is truncated
|
# The file is truncated
|
||||||
with pytest.raises(OSError):
|
with pytest.raises(OSError):
|
||||||
im.text
|
im.text
|
||||||
ImageFile.LOAD_TRUNCATED_IMAGES = True
|
monkeypatch.setattr(ImageFile, "LOAD_TRUNCATED_IMAGES", True)
|
||||||
assert isinstance(im.text, dict)
|
assert isinstance(im.text, dict)
|
||||||
ImageFile.LOAD_TRUNCATED_IMAGES = False
|
|
||||||
|
|
||||||
# Raises an EOFError in load_end
|
|
||||||
with Image.open("Tests/images/hopper_idat_after_image_end.png") as im:
|
|
||||||
assert im.text == {"TXT": "VALUE", "ZIP": "VALUE"}
|
|
||||||
|
|
||||||
def test_unknown_compression_method(self) -> None:
|
def test_unknown_compression_method(self) -> None:
|
||||||
with pytest.raises(SyntaxError, match="Unknown compression method"):
|
with pytest.raises(SyntaxError, match="Unknown compression method"):
|
||||||
|
@ -651,15 +646,16 @@ class TestFilePng:
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"cid", (b"IHDR", b"sRGB", b"pHYs", b"acTL", b"fcTL", b"fdAT")
|
"cid", (b"IHDR", b"sRGB", b"pHYs", b"acTL", b"fcTL", b"fdAT")
|
||||||
)
|
)
|
||||||
def test_truncated_chunks(self, cid: bytes) -> None:
|
def test_truncated_chunks(
|
||||||
|
self, cid: bytes, monkeypatch: pytest.MonkeyPatch
|
||||||
|
) -> None:
|
||||||
fp = BytesIO()
|
fp = BytesIO()
|
||||||
with PngImagePlugin.PngStream(fp) as png:
|
with PngImagePlugin.PngStream(fp) as png:
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
png.call(cid, 0, 0)
|
png.call(cid, 0, 0)
|
||||||
|
|
||||||
ImageFile.LOAD_TRUNCATED_IMAGES = True
|
monkeypatch.setattr(ImageFile, "LOAD_TRUNCATED_IMAGES", True)
|
||||||
png.call(cid, 0, 0)
|
png.call(cid, 0, 0)
|
||||||
ImageFile.LOAD_TRUNCATED_IMAGES = False
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("save_all", (True, False))
|
@pytest.mark.parametrize("save_all", (True, False))
|
||||||
def test_specify_bits(self, save_all: bool, tmp_path: Path) -> None:
|
def test_specify_bits(self, save_all: bool, tmp_path: Path) -> None:
|
||||||
|
@ -789,17 +785,14 @@ class TestFilePng:
|
||||||
with Image.open(mystdout) as reloaded:
|
with Image.open(mystdout) as reloaded:
|
||||||
assert_image_equal_tofile(reloaded, TEST_PNG_FILE)
|
assert_image_equal_tofile(reloaded, TEST_PNG_FILE)
|
||||||
|
|
||||||
def test_truncated_end_chunk(self) -> None:
|
def test_truncated_end_chunk(self, monkeypatch: pytest.MonkeyPatch) -> None:
|
||||||
with Image.open("Tests/images/truncated_end_chunk.png") as im:
|
with Image.open("Tests/images/truncated_end_chunk.png") as im:
|
||||||
with pytest.raises(OSError):
|
with pytest.raises(OSError):
|
||||||
im.load()
|
im.load()
|
||||||
|
|
||||||
ImageFile.LOAD_TRUNCATED_IMAGES = True
|
monkeypatch.setattr(ImageFile, "LOAD_TRUNCATED_IMAGES", True)
|
||||||
try:
|
with Image.open("Tests/images/truncated_end_chunk.png") as im:
|
||||||
with Image.open("Tests/images/truncated_end_chunk.png") as im:
|
assert_image_equal_tofile(im, "Tests/images/hopper.png")
|
||||||
assert_image_equal_tofile(im, "Tests/images/hopper.png")
|
|
||||||
finally:
|
|
||||||
ImageFile.LOAD_TRUNCATED_IMAGES = False
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif(is_win32(), reason="Requires Unix or macOS")
|
@pytest.mark.skipif(is_win32(), reason="Requires Unix or macOS")
|
||||||
|
@ -808,11 +801,11 @@ class TestTruncatedPngPLeaks(PillowLeakTestCase):
|
||||||
mem_limit = 2 * 1024 # max increase in K
|
mem_limit = 2 * 1024 # max increase in K
|
||||||
iterations = 100 # Leak is 56k/iteration, this will leak 5.6megs
|
iterations = 100 # Leak is 56k/iteration, this will leak 5.6megs
|
||||||
|
|
||||||
def test_leak_load(self) -> None:
|
def test_leak_load(self, monkeypatch: pytest.MonkeyPatch) -> None:
|
||||||
with open("Tests/images/hopper.png", "rb") as f:
|
with open("Tests/images/hopper.png", "rb") as f:
|
||||||
DATA = BytesIO(f.read(16 * 1024))
|
DATA = BytesIO(f.read(16 * 1024))
|
||||||
|
|
||||||
ImageFile.LOAD_TRUNCATED_IMAGES = True
|
monkeypatch.setattr(ImageFile, "LOAD_TRUNCATED_IMAGES", True)
|
||||||
with Image.open(DATA) as im:
|
with Image.open(DATA) as im:
|
||||||
im.load()
|
im.load()
|
||||||
|
|
||||||
|
@ -820,7 +813,4 @@ class TestTruncatedPngPLeaks(PillowLeakTestCase):
|
||||||
with Image.open(DATA) as im:
|
with Image.open(DATA) as im:
|
||||||
im.load()
|
im.load()
|
||||||
|
|
||||||
try:
|
self._test_leak(core)
|
||||||
self._test_leak(core)
|
|
||||||
finally:
|
|
||||||
ImageFile.LOAD_TRUNCATED_IMAGES = False
|
|
||||||
|
|
|
@ -780,15 +780,17 @@ class TestFileTiff:
|
||||||
data = b"II\x2A\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
data = b"II\x2A\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||||
b = BytesIO(data)
|
b = BytesIO(data)
|
||||||
with TiffImagePlugin.AppendingTiffWriter(b) as a:
|
with TiffImagePlugin.AppendingTiffWriter(b) as a:
|
||||||
|
a.seek(-4, os.SEEK_CUR)
|
||||||
a.writeLong(2**32 - 1)
|
a.writeLong(2**32 - 1)
|
||||||
assert b.getvalue() == data + b"\xff\xff\xff\xff"
|
assert b.getvalue() == data[:-4] + b"\xff\xff\xff\xff"
|
||||||
|
|
||||||
def test_appending_tiff_writer_rewritelastshorttolong(self) -> None:
|
def test_appending_tiff_writer_rewritelastshorttolong(self) -> None:
|
||||||
data = b"II\x2A\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
data = b"II\x2A\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||||
b = BytesIO(data)
|
b = BytesIO(data)
|
||||||
with TiffImagePlugin.AppendingTiffWriter(b) as a:
|
with TiffImagePlugin.AppendingTiffWriter(b) as a:
|
||||||
|
a.seek(-2, os.SEEK_CUR)
|
||||||
a.rewriteLastShortToLong(2**32 - 1)
|
a.rewriteLastShortToLong(2**32 - 1)
|
||||||
assert b.getvalue() == data[:-2] + b"\xff\xff\xff\xff"
|
assert b.getvalue() == data[:-4] + b"\xff\xff\xff\xff"
|
||||||
|
|
||||||
def test_saving_icc_profile(self, tmp_path: Path) -> None:
|
def test_saving_icc_profile(self, tmp_path: Path) -> None:
|
||||||
# Tests saving TIFF with icc_profile set.
|
# Tests saving TIFF with icc_profile set.
|
||||||
|
@ -939,11 +941,10 @@ class TestFileTiff:
|
||||||
|
|
||||||
@pytest.mark.timeout(6)
|
@pytest.mark.timeout(6)
|
||||||
@pytest.mark.filterwarnings("ignore:Truncated File Read")
|
@pytest.mark.filterwarnings("ignore:Truncated File Read")
|
||||||
def test_timeout(self) -> None:
|
def test_timeout(self, monkeypatch: pytest.MonkeyPatch) -> None:
|
||||||
with Image.open("Tests/images/timeout-6646305047838720") as im:
|
with Image.open("Tests/images/timeout-6646305047838720") as im:
|
||||||
ImageFile.LOAD_TRUNCATED_IMAGES = True
|
monkeypatch.setattr(ImageFile, "LOAD_TRUNCATED_IMAGES", True)
|
||||||
im.load()
|
im.load()
|
||||||
ImageFile.LOAD_TRUNCATED_IMAGES = False
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"test_file",
|
"test_file",
|
||||||
|
|
|
@ -28,9 +28,9 @@ except ImportError:
|
||||||
|
|
||||||
|
|
||||||
class TestUnsupportedWebp:
|
class TestUnsupportedWebp:
|
||||||
def test_unsupported(self) -> None:
|
def test_unsupported(self, monkeypatch: pytest.MonkeyPatch) -> None:
|
||||||
if HAVE_WEBP:
|
if HAVE_WEBP:
|
||||||
WebPImagePlugin.SUPPORTED = False
|
monkeypatch.setattr(WebPImagePlugin, "SUPPORTED", False)
|
||||||
|
|
||||||
file_path = "Tests/images/hopper.webp"
|
file_path = "Tests/images/hopper.webp"
|
||||||
with pytest.warns(UserWarning):
|
with pytest.warns(UserWarning):
|
||||||
|
@ -38,9 +38,6 @@ class TestUnsupportedWebp:
|
||||||
with Image.open(file_path):
|
with Image.open(file_path):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if HAVE_WEBP:
|
|
||||||
WebPImagePlugin.SUPPORTED = True
|
|
||||||
|
|
||||||
|
|
||||||
@skip_unless_feature("webp")
|
@skip_unless_feature("webp")
|
||||||
class TestFileWebp:
|
class TestFileWebp:
|
||||||
|
|
|
@ -1396,6 +1396,28 @@ def test_stroke_descender() -> None:
|
||||||
assert_image_similar_tofile(im, "Tests/images/imagedraw_stroke_descender.png", 6.76)
|
assert_image_similar_tofile(im, "Tests/images/imagedraw_stroke_descender.png", 6.76)
|
||||||
|
|
||||||
|
|
||||||
|
@skip_unless_feature("freetype2")
|
||||||
|
def test_stroke_inside_gap() -> None:
|
||||||
|
# Arrange
|
||||||
|
im = Image.new("RGB", (120, 130))
|
||||||
|
draw = ImageDraw.Draw(im)
|
||||||
|
font = ImageFont.truetype("Tests/fonts/FreeMono.ttf", 120)
|
||||||
|
|
||||||
|
# Act
|
||||||
|
draw.text((12, 12), "i", "#f00", font, stroke_width=20)
|
||||||
|
|
||||||
|
# Assert
|
||||||
|
for y in range(im.height):
|
||||||
|
glyph = ""
|
||||||
|
for x in range(im.width):
|
||||||
|
if im.getpixel((x, y)) == (0, 0, 0):
|
||||||
|
if glyph == "started":
|
||||||
|
glyph = "ended"
|
||||||
|
else:
|
||||||
|
assert glyph != "ended", "Gap inside stroked glyph"
|
||||||
|
glyph = "started"
|
||||||
|
|
||||||
|
|
||||||
@skip_unless_feature("freetype2")
|
@skip_unless_feature("freetype2")
|
||||||
def test_split_word() -> None:
|
def test_split_word() -> None:
|
||||||
# Arrange
|
# Arrange
|
||||||
|
|
|
@ -191,13 +191,10 @@ class TestImageFile:
|
||||||
im.load()
|
im.load()
|
||||||
|
|
||||||
@skip_unless_feature("zlib")
|
@skip_unless_feature("zlib")
|
||||||
def test_truncated_without_errors(self) -> None:
|
def test_truncated_without_errors(self, monkeypatch: pytest.MonkeyPatch) -> None:
|
||||||
with Image.open("Tests/images/truncated_image.png") as im:
|
with Image.open("Tests/images/truncated_image.png") as im:
|
||||||
ImageFile.LOAD_TRUNCATED_IMAGES = True
|
monkeypatch.setattr(ImageFile, "LOAD_TRUNCATED_IMAGES", True)
|
||||||
try:
|
im.load()
|
||||||
im.load()
|
|
||||||
finally:
|
|
||||||
ImageFile.LOAD_TRUNCATED_IMAGES = False
|
|
||||||
|
|
||||||
@skip_unless_feature("zlib")
|
@skip_unless_feature("zlib")
|
||||||
def test_broken_datastream_with_errors(self) -> None:
|
def test_broken_datastream_with_errors(self) -> None:
|
||||||
|
@ -206,13 +203,12 @@ class TestImageFile:
|
||||||
im.load()
|
im.load()
|
||||||
|
|
||||||
@skip_unless_feature("zlib")
|
@skip_unless_feature("zlib")
|
||||||
def test_broken_datastream_without_errors(self) -> None:
|
def test_broken_datastream_without_errors(
|
||||||
|
self, monkeypatch: pytest.MonkeyPatch
|
||||||
|
) -> None:
|
||||||
with Image.open("Tests/images/broken_data_stream.png") as im:
|
with Image.open("Tests/images/broken_data_stream.png") as im:
|
||||||
ImageFile.LOAD_TRUNCATED_IMAGES = True
|
monkeypatch.setattr(ImageFile, "LOAD_TRUNCATED_IMAGES", True)
|
||||||
try:
|
im.load()
|
||||||
im.load()
|
|
||||||
finally:
|
|
||||||
ImageFile.LOAD_TRUNCATED_IMAGES = False
|
|
||||||
|
|
||||||
|
|
||||||
class MockPyDecoder(ImageFile.PyDecoder):
|
class MockPyDecoder(ImageFile.PyDecoder):
|
||||||
|
|
|
@ -461,6 +461,20 @@ def test_free_type_font_get_mask(font: ImageFont.FreeTypeFont) -> None:
|
||||||
assert mask.size == (108, 13)
|
assert mask.size == (108, 13)
|
||||||
|
|
||||||
|
|
||||||
|
def test_stroke_mask() -> None:
|
||||||
|
# Arrange
|
||||||
|
text = "i"
|
||||||
|
|
||||||
|
# Act
|
||||||
|
font = ImageFont.truetype(FONT_PATH, 128)
|
||||||
|
mask = font.getmask(text, stroke_width=2)
|
||||||
|
|
||||||
|
# Assert
|
||||||
|
assert mask.getpixel((34, 5)) == 255
|
||||||
|
assert mask.getpixel((38, 5)) == 0
|
||||||
|
assert mask.getpixel((42, 5)) == 255
|
||||||
|
|
||||||
|
|
||||||
def test_load_when_image_not_found() -> None:
|
def test_load_when_image_not_found() -> None:
|
||||||
with tempfile.NamedTemporaryFile(delete=False) as tmp:
|
with tempfile.NamedTemporaryFile(delete=False) as tmp:
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -7,36 +7,30 @@ import pytest
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
|
||||||
|
|
||||||
def test_overflow() -> None:
|
def test_overflow(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||||
# There is the potential to overflow comparisons in map.c
|
# There is the potential to overflow comparisons in map.c
|
||||||
# if there are > SIZE_MAX bytes in the image or if
|
# if there are > SIZE_MAX bytes in the image or if
|
||||||
# the file encodes an offset that makes
|
# the file encodes an offset that makes
|
||||||
# (offset + size(bytes)) > SIZE_MAX
|
# (offset + size(bytes)) > SIZE_MAX
|
||||||
|
|
||||||
# Note that this image triggers the decompression bomb warning:
|
# Note that this image triggers the decompression bomb warning:
|
||||||
max_pixels = Image.MAX_IMAGE_PIXELS
|
monkeypatch.setattr(Image, "MAX_IMAGE_PIXELS", None)
|
||||||
Image.MAX_IMAGE_PIXELS = None
|
|
||||||
|
|
||||||
# This image hits the offset test.
|
# This image hits the offset test.
|
||||||
with Image.open("Tests/images/l2rgb_read.bmp") as im:
|
with Image.open("Tests/images/l2rgb_read.bmp") as im:
|
||||||
with pytest.raises((ValueError, MemoryError, OSError)):
|
with pytest.raises((ValueError, MemoryError, OSError)):
|
||||||
im.load()
|
im.load()
|
||||||
|
|
||||||
Image.MAX_IMAGE_PIXELS = max_pixels
|
|
||||||
|
|
||||||
|
def test_tobytes(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||||
def test_tobytes() -> None:
|
|
||||||
# Note that this image triggers the decompression bomb warning:
|
# Note that this image triggers the decompression bomb warning:
|
||||||
max_pixels = Image.MAX_IMAGE_PIXELS
|
monkeypatch.setattr(Image, "MAX_IMAGE_PIXELS", None)
|
||||||
Image.MAX_IMAGE_PIXELS = None
|
|
||||||
|
|
||||||
# Previously raised an access violation on Windows
|
# Previously raised an access violation on Windows
|
||||||
with Image.open("Tests/images/l2rgb_read.bmp") as im:
|
with Image.open("Tests/images/l2rgb_read.bmp") as im:
|
||||||
with pytest.raises((ValueError, MemoryError, OSError)):
|
with pytest.raises((ValueError, MemoryError, OSError)):
|
||||||
im.tobytes()
|
im.tobytes()
|
||||||
|
|
||||||
Image.MAX_IMAGE_PIXELS = max_pixels
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif(sys.maxsize <= 2**32, reason="Requires 64-bit system")
|
@pytest.mark.skipif(sys.maxsize <= 2**32, reason="Requires 64-bit system")
|
||||||
def test_ysize() -> None:
|
def test_ysize() -> None:
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#
|
#
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import os
|
||||||
from typing import IO
|
from typing import IO
|
||||||
|
|
||||||
from . import Image, ImageFile
|
from . import Image, ImageFile
|
||||||
|
@ -40,13 +41,11 @@ class BufrStubImageFile(ImageFile.StubImageFile):
|
||||||
format_description = "BUFR"
|
format_description = "BUFR"
|
||||||
|
|
||||||
def _open(self) -> None:
|
def _open(self) -> None:
|
||||||
offset = self.fp.tell()
|
|
||||||
|
|
||||||
if not _accept(self.fp.read(4)):
|
if not _accept(self.fp.read(4)):
|
||||||
msg = "Not a BUFR file"
|
msg = "Not a BUFR file"
|
||||||
raise SyntaxError(msg)
|
raise SyntaxError(msg)
|
||||||
|
|
||||||
self.fp.seek(offset)
|
self.fp.seek(-4, os.SEEK_CUR)
|
||||||
|
|
||||||
# make something up
|
# make something up
|
||||||
self._mode = "F"
|
self._mode = "F"
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#
|
#
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import os
|
||||||
from typing import IO
|
from typing import IO
|
||||||
|
|
||||||
from . import Image, ImageFile
|
from . import Image, ImageFile
|
||||||
|
@ -40,13 +41,11 @@ class GribStubImageFile(ImageFile.StubImageFile):
|
||||||
format_description = "GRIB"
|
format_description = "GRIB"
|
||||||
|
|
||||||
def _open(self) -> None:
|
def _open(self) -> None:
|
||||||
offset = self.fp.tell()
|
|
||||||
|
|
||||||
if not _accept(self.fp.read(8)):
|
if not _accept(self.fp.read(8)):
|
||||||
msg = "Not a GRIB file"
|
msg = "Not a GRIB file"
|
||||||
raise SyntaxError(msg)
|
raise SyntaxError(msg)
|
||||||
|
|
||||||
self.fp.seek(offset)
|
self.fp.seek(-8, os.SEEK_CUR)
|
||||||
|
|
||||||
# make something up
|
# make something up
|
||||||
self._mode = "F"
|
self._mode = "F"
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#
|
#
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import os
|
||||||
from typing import IO
|
from typing import IO
|
||||||
|
|
||||||
from . import Image, ImageFile
|
from . import Image, ImageFile
|
||||||
|
@ -40,13 +41,11 @@ class HDF5StubImageFile(ImageFile.StubImageFile):
|
||||||
format_description = "HDF5"
|
format_description = "HDF5"
|
||||||
|
|
||||||
def _open(self) -> None:
|
def _open(self) -> None:
|
||||||
offset = self.fp.tell()
|
|
||||||
|
|
||||||
if not _accept(self.fp.read(8)):
|
if not _accept(self.fp.read(8)):
|
||||||
msg = "Not an HDF file"
|
msg = "Not an HDF file"
|
||||||
raise SyntaxError(msg)
|
raise SyntaxError(msg)
|
||||||
|
|
||||||
self.fp.seek(offset)
|
self.fp.seek(-8, os.SEEK_CUR)
|
||||||
|
|
||||||
# make something up
|
# make something up
|
||||||
self._mode = "F"
|
self._mode = "F"
|
||||||
|
|
|
@ -643,6 +643,7 @@ class ImageDraw:
|
||||||
features=features,
|
features=features,
|
||||||
language=language,
|
language=language,
|
||||||
stroke_width=stroke_width,
|
stroke_width=stroke_width,
|
||||||
|
stroke_filled=True,
|
||||||
anchor=anchor,
|
anchor=anchor,
|
||||||
ink=ink,
|
ink=ink,
|
||||||
start=start,
|
start=start,
|
||||||
|
@ -692,7 +693,8 @@ class ImageDraw:
|
||||||
draw_text(stroke_ink, stroke_width)
|
draw_text(stroke_ink, stroke_width)
|
||||||
|
|
||||||
# Draw normal text
|
# Draw normal text
|
||||||
draw_text(ink, 0)
|
if ink != stroke_ink:
|
||||||
|
draw_text(ink)
|
||||||
else:
|
else:
|
||||||
# Only draw normal text
|
# Only draw normal text
|
||||||
draw_text(ink)
|
draw_text(ink)
|
||||||
|
|
|
@ -644,6 +644,7 @@ class FreeTypeFont:
|
||||||
features,
|
features,
|
||||||
language,
|
language,
|
||||||
stroke_width,
|
stroke_width,
|
||||||
|
kwargs.get("stroke_filled", False),
|
||||||
anchor,
|
anchor,
|
||||||
ink,
|
ink,
|
||||||
start[0],
|
start[0],
|
||||||
|
|
|
@ -1382,7 +1382,7 @@ def _save(
|
||||||
b"\0", # 12: interlace flag
|
b"\0", # 12: interlace flag
|
||||||
)
|
)
|
||||||
|
|
||||||
chunks = [b"cHRM", b"gAMA", b"sBIT", b"sRGB", b"tIME"]
|
chunks = [b"cHRM", b"cICP", b"gAMA", b"sBIT", b"sRGB", b"tIME"]
|
||||||
|
|
||||||
icc = im.encoderinfo.get("icc_profile", im.info.get("icc_profile"))
|
icc = im.encoderinfo.get("icc_profile", im.info.get("icc_profile"))
|
||||||
if icc:
|
if icc:
|
||||||
|
|
|
@ -28,6 +28,7 @@ class Font:
|
||||||
features: list[str] | None,
|
features: list[str] | None,
|
||||||
lang: str | None,
|
lang: str | None,
|
||||||
stroke_width: float,
|
stroke_width: float,
|
||||||
|
stroke_filled: bool,
|
||||||
anchor: str | None,
|
anchor: str | None,
|
||||||
foreground_ink_long: int,
|
foreground_ink_long: int,
|
||||||
x_start: float,
|
x_start: float,
|
||||||
|
|
|
@ -473,8 +473,7 @@ getpixel(Imaging im, ImagingAccess access, int x, int y) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* unknown type */
|
/* unknown type */
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
|
@ -965,8 +964,7 @@ _convert2(ImagingObject *self, PyObject *args) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -1214,8 +1212,7 @@ _getpixel(ImagingObject *self, PyObject *args) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->access == NULL) {
|
if (self->access == NULL) {
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return getpixel(self->image, self->access, x, y);
|
return getpixel(self->image, self->access, x, y);
|
||||||
|
@ -1417,8 +1414,7 @@ _paste(ImagingObject *self, PyObject *args) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -1691,8 +1687,7 @@ _putdata(ImagingObject *self, PyObject *args) {
|
||||||
|
|
||||||
Py_XDECREF(seq);
|
Py_XDECREF(seq);
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -1752,8 +1747,7 @@ _putpalette(ImagingObject *self, PyObject *args) {
|
||||||
self->image->palette->size = palettesize * 8 / bits;
|
self->image->palette->size = palettesize * 8 / bits;
|
||||||
unpack(self->image->palette->palette, palette, self->image->palette->size);
|
unpack(self->image->palette->palette, palette, self->image->palette->size);
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -1777,8 +1771,7 @@ _putpalettealpha(ImagingObject *self, PyObject *args) {
|
||||||
strcpy(self->image->palette->mode, "RGBA");
|
strcpy(self->image->palette->mode, "RGBA");
|
||||||
self->image->palette->palette[index * 4 + 3] = (UINT8)alpha;
|
self->image->palette->palette[index * 4 + 3] = (UINT8)alpha;
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -1805,8 +1798,7 @@ _putpalettealphas(ImagingObject *self, PyObject *args) {
|
||||||
self->image->palette->palette[i * 4 + 3] = (UINT8)values[i];
|
self->image->palette->palette[i * 4 + 3] = (UINT8)values[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -1842,8 +1834,7 @@ _putpixel(ImagingObject *self, PyObject *args) {
|
||||||
self->access->put_pixel(im, x, y, ink);
|
self->access->put_pixel(im, x, y, ink);
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -2010,8 +2001,7 @@ im_setmode(ImagingObject *self, PyObject *args) {
|
||||||
}
|
}
|
||||||
self->access = ImagingAccessNew(im);
|
self->access = ImagingAccessNew(im);
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -2074,8 +2064,7 @@ _transform(ImagingObject *self, PyObject *args) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -2202,8 +2191,7 @@ _getbbox(ImagingObject *self, PyObject *args) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ImagingGetBBox(self->image, bbox, alpha_only)) {
|
if (!ImagingGetBBox(self->image, bbox, alpha_only)) {
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Py_BuildValue("iiii", bbox[0], bbox[1], bbox[2], bbox[3]);
|
return Py_BuildValue("iiii", bbox[0], bbox[1], bbox[2], bbox[3]);
|
||||||
|
@ -2283,8 +2271,7 @@ _getextrema(ImagingObject *self) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -2347,8 +2334,7 @@ _fillband(ImagingObject *self, PyObject *args) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -2363,8 +2349,7 @@ _putband(ImagingObject *self, PyObject *args) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -2950,8 +2935,7 @@ _draw_arc(ImagingDrawObject *self, PyObject *args) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -2988,8 +2972,7 @@ _draw_bitmap(ImagingDrawObject *self, PyObject *args) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -3045,8 +3028,7 @@ _draw_chord(ImagingDrawObject *self, PyObject *args) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -3100,8 +3082,7 @@ _draw_ellipse(ImagingDrawObject *self, PyObject *args) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -3164,8 +3145,7 @@ _draw_lines(ImagingDrawObject *self, PyObject *args) {
|
||||||
|
|
||||||
free(xy);
|
free(xy);
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -3196,8 +3176,7 @@ _draw_points(ImagingDrawObject *self, PyObject *args) {
|
||||||
|
|
||||||
free(xy);
|
free(xy);
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* from outline.c */
|
/* from outline.c */
|
||||||
|
@ -3225,8 +3204,7 @@ _draw_outline(ImagingDrawObject *self, PyObject *args) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -3282,8 +3260,7 @@ _draw_pieslice(ImagingDrawObject *self, PyObject *args) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -3334,8 +3311,7 @@ _draw_polygon(ImagingDrawObject *self, PyObject *args) {
|
||||||
|
|
||||||
free(ixy);
|
free(ixy);
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -3389,8 +3365,7 @@ _draw_rectangle(ImagingDrawObject *self, PyObject *args) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct PyMethodDef _draw_methods[] = {
|
static struct PyMethodDef _draw_methods[] = {
|
||||||
|
@ -3595,8 +3570,7 @@ _save_ppm(ImagingObject *self, PyObject *args) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
@ -3984,8 +3958,7 @@ _reset_stats(PyObject *self, PyObject *args) {
|
||||||
arena->stats_freed_blocks = 0;
|
arena->stats_freed_blocks = 0;
|
||||||
MUTEX_UNLOCK(&ImagingDefaultArena.mutex);
|
MUTEX_UNLOCK(&ImagingDefaultArena.mutex);
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -4045,8 +4018,7 @@ _set_alignment(PyObject *self, PyObject *args) {
|
||||||
ImagingDefaultArena.alignment = alignment;
|
ImagingDefaultArena.alignment = alignment;
|
||||||
MUTEX_UNLOCK(&ImagingDefaultArena.mutex);
|
MUTEX_UNLOCK(&ImagingDefaultArena.mutex);
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -4070,8 +4042,7 @@ _set_block_size(PyObject *self, PyObject *args) {
|
||||||
ImagingDefaultArena.block_size = block_size;
|
ImagingDefaultArena.block_size = block_size;
|
||||||
MUTEX_UNLOCK(&ImagingDefaultArena.mutex);
|
MUTEX_UNLOCK(&ImagingDefaultArena.mutex);
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -4099,8 +4070,7 @@ _set_blocks_max(PyObject *self, PyObject *args) {
|
||||||
return ImagingError_MemoryError();
|
return ImagingError_MemoryError();
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -4115,8 +4085,7 @@ _clear_cache(PyObject *self, PyObject *args) {
|
||||||
ImagingMemoryClearCache(&ImagingDefaultArena, i);
|
ImagingMemoryClearCache(&ImagingDefaultArena, i);
|
||||||
MUTEX_UNLOCK(&ImagingDefaultArena.mutex);
|
MUTEX_UNLOCK(&ImagingDefaultArena.mutex);
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
|
@ -654,8 +654,7 @@ cms_get_display_profile_win32(PyObject *self, PyObject *args) {
|
||||||
return PyUnicode_FromStringAndSize(filename, filename_size - 1);
|
return PyUnicode_FromStringAndSize(filename, filename_size - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -672,20 +671,17 @@ _profile_read_mlu(CmsProfileObject *self, cmsTagSignature info) {
|
||||||
wchar_t *buf;
|
wchar_t *buf;
|
||||||
|
|
||||||
if (!cmsIsTag(self->profile, info)) {
|
if (!cmsIsTag(self->profile, info)) {
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mlu = cmsReadTag(self->profile, info);
|
mlu = cmsReadTag(self->profile, info);
|
||||||
if (!mlu) {
|
if (!mlu) {
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
len = cmsMLUgetWide(mlu, lc, cc, NULL, 0);
|
len = cmsMLUgetWide(mlu, lc, cc, NULL, 0);
|
||||||
if (len == 0) {
|
if (len == 0) {
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
buf = malloc(len);
|
buf = malloc(len);
|
||||||
|
@ -723,14 +719,12 @@ _profile_read_signature(CmsProfileObject *self, cmsTagSignature info) {
|
||||||
unsigned int *sig;
|
unsigned int *sig;
|
||||||
|
|
||||||
if (!cmsIsTag(self->profile, info)) {
|
if (!cmsIsTag(self->profile, info)) {
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sig = (unsigned int *)cmsReadTag(self->profile, info);
|
sig = (unsigned int *)cmsReadTag(self->profile, info);
|
||||||
if (!sig) {
|
if (!sig) {
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return _profile_read_int_as_string(*sig);
|
return _profile_read_int_as_string(*sig);
|
||||||
|
@ -780,14 +774,12 @@ _profile_read_ciexyz(CmsProfileObject *self, cmsTagSignature info, int multi) {
|
||||||
cmsCIEXYZ *XYZ;
|
cmsCIEXYZ *XYZ;
|
||||||
|
|
||||||
if (!cmsIsTag(self->profile, info)) {
|
if (!cmsIsTag(self->profile, info)) {
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
XYZ = (cmsCIEXYZ *)cmsReadTag(self->profile, info);
|
XYZ = (cmsCIEXYZ *)cmsReadTag(self->profile, info);
|
||||||
if (!XYZ) {
|
if (!XYZ) {
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
if (multi) {
|
if (multi) {
|
||||||
return _xyz3_py(XYZ);
|
return _xyz3_py(XYZ);
|
||||||
|
@ -801,14 +793,12 @@ _profile_read_ciexyy_triple(CmsProfileObject *self, cmsTagSignature info) {
|
||||||
cmsCIExyYTRIPLE *triple;
|
cmsCIExyYTRIPLE *triple;
|
||||||
|
|
||||||
if (!cmsIsTag(self->profile, info)) {
|
if (!cmsIsTag(self->profile, info)) {
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
triple = (cmsCIExyYTRIPLE *)cmsReadTag(self->profile, info);
|
triple = (cmsCIExyYTRIPLE *)cmsReadTag(self->profile, info);
|
||||||
if (!triple) {
|
if (!triple) {
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Note: lcms does all the heavy lifting and error checking (nr of
|
/* Note: lcms does all the heavy lifting and error checking (nr of
|
||||||
|
@ -835,21 +825,18 @@ _profile_read_named_color_list(CmsProfileObject *self, cmsTagSignature info) {
|
||||||
PyObject *result;
|
PyObject *result;
|
||||||
|
|
||||||
if (!cmsIsTag(self->profile, info)) {
|
if (!cmsIsTag(self->profile, info)) {
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ncl = (cmsNAMEDCOLORLIST *)cmsReadTag(self->profile, info);
|
ncl = (cmsNAMEDCOLORLIST *)cmsReadTag(self->profile, info);
|
||||||
if (ncl == NULL) {
|
if (ncl == NULL) {
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
n = cmsNamedColorCount(ncl);
|
n = cmsNamedColorCount(ncl);
|
||||||
result = PyList_New(n);
|
result = PyList_New(n);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
|
@ -858,8 +845,7 @@ _profile_read_named_color_list(CmsProfileObject *self, cmsTagSignature info) {
|
||||||
str = PyUnicode_FromString(name);
|
str = PyUnicode_FromString(name);
|
||||||
if (str == NULL) {
|
if (str == NULL) {
|
||||||
Py_DECREF(result);
|
Py_DECREF(result);
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
PyList_SET_ITEM(result, i, str);
|
PyList_SET_ITEM(result, i, str);
|
||||||
}
|
}
|
||||||
|
@ -926,8 +912,7 @@ _is_intent_supported(CmsProfileObject *self, int clut) {
|
||||||
|
|
||||||
result = PyDict_New();
|
result = PyDict_New();
|
||||||
if (result == NULL) {
|
if (result == NULL) {
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
n = cmsGetSupportedIntents(INTENTS, intent_ids, intent_descs);
|
n = cmsGetSupportedIntents(INTENTS, intent_ids, intent_descs);
|
||||||
|
@ -957,8 +942,7 @@ _is_intent_supported(CmsProfileObject *self, int clut) {
|
||||||
Py_XDECREF(id);
|
Py_XDECREF(id);
|
||||||
Py_XDECREF(entry);
|
Py_XDECREF(entry);
|
||||||
Py_XDECREF(result);
|
Py_XDECREF(result);
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
PyDict_SetItem(result, id, entry);
|
PyDict_SetItem(result, id, entry);
|
||||||
Py_DECREF(id);
|
Py_DECREF(id);
|
||||||
|
@ -1042,8 +1026,7 @@ cms_profile_getattr_creation_date(CmsProfileObject *self, void *closure) {
|
||||||
|
|
||||||
result = cmsGetHeaderCreationDateTime(self->profile, &ct);
|
result = cmsGetHeaderCreationDateTime(self->profile, &ct);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return PyDateTime_FromDateAndTime(
|
return PyDateTime_FromDateAndTime(
|
||||||
|
@ -1141,8 +1124,7 @@ cms_profile_getattr_saturation_rendering_intent_gamut(
|
||||||
static PyObject *
|
static PyObject *
|
||||||
cms_profile_getattr_red_colorant(CmsProfileObject *self, void *closure) {
|
cms_profile_getattr_red_colorant(CmsProfileObject *self, void *closure) {
|
||||||
if (!cmsIsMatrixShaper(self->profile)) {
|
if (!cmsIsMatrixShaper(self->profile)) {
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
return _profile_read_ciexyz(self, cmsSigRedColorantTag, 0);
|
return _profile_read_ciexyz(self, cmsSigRedColorantTag, 0);
|
||||||
}
|
}
|
||||||
|
@ -1150,8 +1132,7 @@ cms_profile_getattr_red_colorant(CmsProfileObject *self, void *closure) {
|
||||||
static PyObject *
|
static PyObject *
|
||||||
cms_profile_getattr_green_colorant(CmsProfileObject *self, void *closure) {
|
cms_profile_getattr_green_colorant(CmsProfileObject *self, void *closure) {
|
||||||
if (!cmsIsMatrixShaper(self->profile)) {
|
if (!cmsIsMatrixShaper(self->profile)) {
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
return _profile_read_ciexyz(self, cmsSigGreenColorantTag, 0);
|
return _profile_read_ciexyz(self, cmsSigGreenColorantTag, 0);
|
||||||
}
|
}
|
||||||
|
@ -1159,8 +1140,7 @@ cms_profile_getattr_green_colorant(CmsProfileObject *self, void *closure) {
|
||||||
static PyObject *
|
static PyObject *
|
||||||
cms_profile_getattr_blue_colorant(CmsProfileObject *self, void *closure) {
|
cms_profile_getattr_blue_colorant(CmsProfileObject *self, void *closure) {
|
||||||
if (!cmsIsMatrixShaper(self->profile)) {
|
if (!cmsIsMatrixShaper(self->profile)) {
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
return _profile_read_ciexyz(self, cmsSigBlueColorantTag, 0);
|
return _profile_read_ciexyz(self, cmsSigBlueColorantTag, 0);
|
||||||
}
|
}
|
||||||
|
@ -1176,21 +1156,18 @@ cms_profile_getattr_media_white_point_temperature(
|
||||||
cmsBool result;
|
cmsBool result;
|
||||||
|
|
||||||
if (!cmsIsTag(self->profile, info)) {
|
if (!cmsIsTag(self->profile, info)) {
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
XYZ = (cmsCIEXYZ *)cmsReadTag(self->profile, info);
|
XYZ = (cmsCIEXYZ *)cmsReadTag(self->profile, info);
|
||||||
if (XYZ == NULL || XYZ->X == 0) {
|
if (XYZ == NULL || XYZ->X == 0) {
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cmsXYZ2xyY(&xyY, XYZ);
|
cmsXYZ2xyY(&xyY, XYZ);
|
||||||
result = cmsTempFromWhitePoint(&tempK, &xyY);
|
result = cmsTempFromWhitePoint(&tempK, &xyY);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
return PyFloat_FromDouble(tempK);
|
return PyFloat_FromDouble(tempK);
|
||||||
}
|
}
|
||||||
|
@ -1229,8 +1206,7 @@ cms_profile_getattr_red_primary(CmsProfileObject *self, void *closure) {
|
||||||
result = _calculate_rgb_primaries(self, &primaries);
|
result = _calculate_rgb_primaries(self, &primaries);
|
||||||
}
|
}
|
||||||
if (!result) {
|
if (!result) {
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return _xyz_py(&primaries.Red);
|
return _xyz_py(&primaries.Red);
|
||||||
|
@ -1245,8 +1221,7 @@ cms_profile_getattr_green_primary(CmsProfileObject *self, void *closure) {
|
||||||
result = _calculate_rgb_primaries(self, &primaries);
|
result = _calculate_rgb_primaries(self, &primaries);
|
||||||
}
|
}
|
||||||
if (!result) {
|
if (!result) {
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return _xyz_py(&primaries.Green);
|
return _xyz_py(&primaries.Green);
|
||||||
|
@ -1261,8 +1236,7 @@ cms_profile_getattr_blue_primary(CmsProfileObject *self, void *closure) {
|
||||||
result = _calculate_rgb_primaries(self, &primaries);
|
result = _calculate_rgb_primaries(self, &primaries);
|
||||||
}
|
}
|
||||||
if (!result) {
|
if (!result) {
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return _xyz_py(&primaries.Blue);
|
return _xyz_py(&primaries.Blue);
|
||||||
|
@ -1321,14 +1295,12 @@ cms_profile_getattr_icc_measurement_condition(CmsProfileObject *self, void *clos
|
||||||
const char *geo;
|
const char *geo;
|
||||||
|
|
||||||
if (!cmsIsTag(self->profile, info)) {
|
if (!cmsIsTag(self->profile, info)) {
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mc = (cmsICCMeasurementConditions *)cmsReadTag(self->profile, info);
|
mc = (cmsICCMeasurementConditions *)cmsReadTag(self->profile, info);
|
||||||
if (!mc) {
|
if (!mc) {
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mc->Geometry == 1) {
|
if (mc->Geometry == 1) {
|
||||||
|
@ -1362,14 +1334,12 @@ cms_profile_getattr_icc_viewing_condition(CmsProfileObject *self, void *closure)
|
||||||
cmsTagSignature info = cmsSigViewingConditionsTag;
|
cmsTagSignature info = cmsSigViewingConditionsTag;
|
||||||
|
|
||||||
if (!cmsIsTag(self->profile, info)) {
|
if (!cmsIsTag(self->profile, info)) {
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vc = (cmsICCViewingConditions *)cmsReadTag(self->profile, info);
|
vc = (cmsICCViewingConditions *)cmsReadTag(self->profile, info);
|
||||||
if (!vc) {
|
if (!vc) {
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Py_BuildValue(
|
return Py_BuildValue(
|
||||||
|
|
|
@ -834,6 +834,7 @@ font_render(FontObject *self, PyObject *args) {
|
||||||
int mask = 0; /* is FT_LOAD_TARGET_MONO enabled? */
|
int mask = 0; /* is FT_LOAD_TARGET_MONO enabled? */
|
||||||
int color = 0; /* is FT_LOAD_COLOR enabled? */
|
int color = 0; /* is FT_LOAD_COLOR enabled? */
|
||||||
float stroke_width = 0;
|
float stroke_width = 0;
|
||||||
|
int stroke_filled = 0;
|
||||||
PY_LONG_LONG foreground_ink_long = 0;
|
PY_LONG_LONG foreground_ink_long = 0;
|
||||||
unsigned int foreground_ink;
|
unsigned int foreground_ink;
|
||||||
const char *mode = NULL;
|
const char *mode = NULL;
|
||||||
|
@ -853,7 +854,7 @@ font_render(FontObject *self, PyObject *args) {
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(
|
if (!PyArg_ParseTuple(
|
||||||
args,
|
args,
|
||||||
"OO|zzOzfzLffO:render",
|
"OO|zzOzfpzLffO:render",
|
||||||
&string,
|
&string,
|
||||||
&fill,
|
&fill,
|
||||||
&mode,
|
&mode,
|
||||||
|
@ -861,6 +862,7 @@ font_render(FontObject *self, PyObject *args) {
|
||||||
&features,
|
&features,
|
||||||
&lang,
|
&lang,
|
||||||
&stroke_width,
|
&stroke_width,
|
||||||
|
&stroke_filled,
|
||||||
&anchor,
|
&anchor,
|
||||||
&foreground_ink_long,
|
&foreground_ink_long,
|
||||||
&x_start,
|
&x_start,
|
||||||
|
@ -1005,7 +1007,8 @@ font_render(FontObject *self, PyObject *args) {
|
||||||
if (stroker != NULL) {
|
if (stroker != NULL) {
|
||||||
error = FT_Get_Glyph(glyph_slot, &glyph);
|
error = FT_Get_Glyph(glyph_slot, &glyph);
|
||||||
if (!error) {
|
if (!error) {
|
||||||
error = FT_Glyph_Stroke(&glyph, stroker, 1);
|
error = stroke_filled ? FT_Glyph_StrokeBorder(&glyph, stroker, 0, 1)
|
||||||
|
: FT_Glyph_Stroke(&glyph, stroker, 1);
|
||||||
}
|
}
|
||||||
if (!error) {
|
if (!error) {
|
||||||
FT_Vector origin = {0, 0};
|
FT_Vector origin = {0, 0};
|
||||||
|
@ -1371,8 +1374,7 @@ font_setvarname(FontObject *self, PyObject *args) {
|
||||||
return geterror(error);
|
return geterror(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -1426,8 +1428,7 @@ font_setvaraxes(FontObject *self, PyObject *args) {
|
||||||
return geterror(error);
|
return geterror(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -192,8 +192,7 @@ _unop(PyObject *self, PyObject *args) {
|
||||||
|
|
||||||
unop(out, im1);
|
unop(out, im1);
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -226,8 +225,7 @@ _binop(PyObject *self, PyObject *args) {
|
||||||
|
|
||||||
binop(out, im1, im2);
|
binop(out, im1, im2);
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyMethodDef _functions[] = {
|
static PyMethodDef _functions[] = {
|
||||||
|
|
|
@ -37,8 +37,7 @@ _tkinit(PyObject *self, PyObject *args) {
|
||||||
/* This will bomb if interp is invalid... */
|
/* This will bomb if interp is invalid... */
|
||||||
TkImaging_Init(interp);
|
TkImaging_Init(interp);
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyMethodDef functions[] = {
|
static PyMethodDef functions[] = {
|
||||||
|
|
|
@ -213,8 +213,7 @@ _setimage(ImagingDecoderObject *decoder, PyObject *args) {
|
||||||
Py_XDECREF(decoder->lock);
|
Py_XDECREF(decoder->lock);
|
||||||
decoder->lock = op;
|
decoder->lock = op;
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -231,8 +230,7 @@ _setfd(ImagingDecoderObject *decoder, PyObject *args) {
|
||||||
Py_XINCREF(fd);
|
Py_XINCREF(fd);
|
||||||
state->fd = fd;
|
state->fd = fd;
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
|
|
@ -85,8 +85,7 @@ _expose(ImagingDisplayObject *display, PyObject *args) {
|
||||||
|
|
||||||
ImagingExposeDIB(display->dib, hdc);
|
ImagingExposeDIB(display->dib, hdc);
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -112,8 +111,7 @@ _draw(ImagingDisplayObject *display, PyObject *args) {
|
||||||
|
|
||||||
ImagingDrawDIB(display->dib, hdc, dst, src);
|
ImagingDrawDIB(display->dib, hdc, dst, src);
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern Imaging
|
extern Imaging
|
||||||
|
@ -143,8 +141,7 @@ _paste(ImagingDisplayObject *display, PyObject *args) {
|
||||||
|
|
||||||
ImagingPasteDIB(display->dib, im, xy);
|
ImagingPasteDIB(display->dib, im, xy);
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -190,8 +187,7 @@ _releasedc(ImagingDisplayObject *display, PyObject *args) {
|
||||||
|
|
||||||
ReleaseDC(window, dc);
|
ReleaseDC(window, dc);
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -211,8 +207,7 @@ _frombytes(ImagingDisplayObject *display, PyObject *args) {
|
||||||
memcpy(display->dib->bits, buffer.buf, buffer.len);
|
memcpy(display->dib->bits, buffer.buf, buffer.len);
|
||||||
|
|
||||||
PyBuffer_Release(&buffer);
|
PyBuffer_Release(&buffer);
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -709,8 +704,7 @@ PyImaging_EventLoopWin32(PyObject *self, PyObject *args) {
|
||||||
}
|
}
|
||||||
Py_END_ALLOW_THREADS;
|
Py_END_ALLOW_THREADS;
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
|
@ -278,8 +278,7 @@ _setimage(ImagingEncoderObject *encoder, PyObject *args) {
|
||||||
Py_XDECREF(encoder->lock);
|
Py_XDECREF(encoder->lock);
|
||||||
encoder->lock = op;
|
encoder->lock = op;
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -296,8 +295,7 @@ _setfd(ImagingEncoderObject *encoder, PyObject *args) {
|
||||||
Py_XINCREF(fd);
|
Py_XINCREF(fd);
|
||||||
state->fd = fd;
|
state->fd = fd;
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
|
|
@ -1,72 +0,0 @@
|
||||||
/*
|
|
||||||
* The Python Imaging Library
|
|
||||||
* $Id$
|
|
||||||
*
|
|
||||||
* default exception handling
|
|
||||||
*
|
|
||||||
* This module is usually overridden by application code (e.g.
|
|
||||||
* _imaging.c for PIL's standard Python bindings). If you get
|
|
||||||
* linking errors, remove this file from your project/library.
|
|
||||||
*
|
|
||||||
* history:
|
|
||||||
* 1995-06-15 fl Created
|
|
||||||
* 1998-12-29 fl Minor tweaks
|
|
||||||
* 2003-09-13 fl Added ImagingEnter/LeaveSection()
|
|
||||||
*
|
|
||||||
* Copyright (c) 1997-2003 by Secret Labs AB.
|
|
||||||
* Copyright (c) 1995-2003 by Fredrik Lundh.
|
|
||||||
*
|
|
||||||
* See the README file for information on usage and redistribution.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "Imaging.h"
|
|
||||||
|
|
||||||
/* exception state */
|
|
||||||
|
|
||||||
void *
|
|
||||||
ImagingError_OSError(void) {
|
|
||||||
fprintf(stderr, "*** exception: file access error\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *
|
|
||||||
ImagingError_MemoryError(void) {
|
|
||||||
fprintf(stderr, "*** exception: out of memory\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *
|
|
||||||
ImagingError_ModeError(void) {
|
|
||||||
return ImagingError_ValueError("bad image mode");
|
|
||||||
}
|
|
||||||
|
|
||||||
void *
|
|
||||||
ImagingError_Mismatch(void) {
|
|
||||||
return ImagingError_ValueError("images don't match");
|
|
||||||
}
|
|
||||||
|
|
||||||
void *
|
|
||||||
ImagingError_ValueError(const char *message) {
|
|
||||||
if (!message) {
|
|
||||||
message = "exception: bad argument to function";
|
|
||||||
}
|
|
||||||
fprintf(stderr, "*** %s\n", message);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ImagingError_Clear(void) {
|
|
||||||
/* nop */;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* thread state */
|
|
||||||
|
|
||||||
void
|
|
||||||
ImagingSectionEnter(ImagingSectionCookie *cookie) {
|
|
||||||
/* pass */
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ImagingSectionLeave(ImagingSectionCookie *cookie) {
|
|
||||||
/* pass */
|
|
||||||
}
|
|
|
@ -609,10 +609,6 @@ ImagingLibTiffDecode(
|
||||||
extern int
|
extern int
|
||||||
ImagingLibTiffEncode(Imaging im, ImagingCodecState state, UINT8 *buffer, int bytes);
|
ImagingLibTiffEncode(Imaging im, ImagingCodecState state, UINT8 *buffer, int bytes);
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_LIBMPEG
|
|
||||||
extern int
|
|
||||||
ImagingMpegDecode(Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes);
|
|
||||||
#endif
|
|
||||||
extern int
|
extern int
|
||||||
ImagingMspDecode(Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes);
|
ImagingMspDecode(Imaging im, ImagingCodecState state, UINT8 *buffer, Py_ssize_t bytes);
|
||||||
extern int
|
extern int
|
||||||
|
|
|
@ -89,8 +89,7 @@ _outline_move(OutlineObject *self, PyObject *args) {
|
||||||
|
|
||||||
ImagingOutlineMove(self->outline, x0, y0);
|
ImagingOutlineMove(self->outline, x0, y0);
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -102,8 +101,7 @@ _outline_line(OutlineObject *self, PyObject *args) {
|
||||||
|
|
||||||
ImagingOutlineLine(self->outline, x1, y1);
|
ImagingOutlineLine(self->outline, x1, y1);
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -115,8 +113,7 @@ _outline_curve(OutlineObject *self, PyObject *args) {
|
||||||
|
|
||||||
ImagingOutlineCurve(self->outline, x1, y1, x2, y2, x3, y3);
|
ImagingOutlineCurve(self->outline, x1, y1, x2, y2, x3, y3);
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -127,8 +124,7 @@ _outline_close(OutlineObject *self, PyObject *args) {
|
||||||
|
|
||||||
ImagingOutlineClose(self->outline);
|
ImagingOutlineClose(self->outline);
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -140,8 +136,7 @@ _outline_transform(OutlineObject *self, PyObject *args) {
|
||||||
|
|
||||||
ImagingOutlineTransform(self->outline, a);
|
ImagingOutlineTransform(self->outline, a);
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct PyMethodDef _outline_methods[] = {
|
static struct PyMethodDef _outline_methods[] = {
|
||||||
|
|
|
@ -415,8 +415,7 @@ path_map(PyPathObject *self, PyObject *args) {
|
||||||
}
|
}
|
||||||
self->mapping = 0;
|
self->mapping = 0;
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -528,8 +527,7 @@ path_transform(PyPathObject *self, PyObject *args) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_RETURN_NONE;
|
||||||
return Py_None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct PyMethodDef methods[] = {
|
static struct PyMethodDef methods[] = {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user