Remove deprecations for Pillow 12.0.0 (#9053)

This commit is contained in:
Hugo van Kemenade 2025-07-07 11:49:02 +03:00 committed by GitHub
commit dcd202568a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
47 changed files with 394 additions and 943 deletions

View File

@ -271,17 +271,13 @@ def _cached_hopper(mode: str) -> Image.Image:
im = hopper("L")
else:
im = hopper()
if mode.startswith("BGR;"):
with pytest.warns(DeprecationWarning, match="BGR;"):
im = im.convert(mode)
else:
try:
im = im.convert(mode)
except ImportError:
if mode == "LAB":
im = Image.open("Tests/images/hopper.Lab.tif")
else:
raise
try:
im = im.convert(mode)
except ImportError:
if mode == "LAB":
im = Image.open("Tests/images/hopper.Lab.tif")
else:
raise
return im

View File

@ -9,9 +9,9 @@ from PIL import _deprecate
"version, expected",
[
(
12,
"Old thing is deprecated and will be removed in Pillow 12 "
r"\(2025-10-15\)\. Use new thing instead\.",
13,
"Old thing is deprecated and will be removed in Pillow 13 "
r"\(2026-10-15\)\. Use new thing instead\.",
),
(
None,
@ -53,18 +53,18 @@ def test_old_version(deprecated: str, plural: bool, expected: str) -> None:
def test_plural() -> None:
expected = (
r"Old things are deprecated and will be removed in Pillow 12 \(2025-10-15\)\. "
r"Old things are deprecated and will be removed in Pillow 13 \(2026-10-15\)\. "
r"Use new thing instead\."
)
with pytest.warns(DeprecationWarning, match=expected):
_deprecate.deprecate("Old things", 12, "new thing", plural=True)
_deprecate.deprecate("Old things", 13, "new thing", plural=True)
def test_replacement_and_action() -> None:
expected = "Use only one of 'replacement' and 'action'"
with pytest.raises(ValueError, match=expected):
_deprecate.deprecate(
"Old thing", 12, replacement="new thing", action="Upgrade to new thing"
"Old thing", 13, replacement="new thing", action="Upgrade to new thing"
)
@ -77,16 +77,16 @@ def test_replacement_and_action() -> None:
)
def test_action(action: str) -> None:
expected = (
r"Old thing is deprecated and will be removed in Pillow 12 \(2025-10-15\)\. "
r"Old thing is deprecated and will be removed in Pillow 13 \(2026-10-15\)\. "
r"Upgrade to new thing\."
)
with pytest.warns(DeprecationWarning, match=expected):
_deprecate.deprecate("Old thing", 12, action=action)
_deprecate.deprecate("Old thing", 13, action=action)
def test_no_replacement_or_action() -> None:
expected = (
r"Old thing is deprecated and will be removed in Pillow 12 \(2025-10-15\)"
r"Old thing is deprecated and will be removed in Pillow 13 \(2026-10-15\)"
)
with pytest.warns(DeprecationWarning, match=expected):
_deprecate.deprecate("Old thing", 12)
_deprecate.deprecate("Old thing", 13)

View File

@ -55,21 +55,6 @@ def test_version() -> None:
test(feature, features.version_feature)
def test_webp_transparency() -> None:
with pytest.warns(DeprecationWarning, match="transp_webp"):
assert (features.check("transp_webp") or False) == features.check_module("webp")
def test_webp_mux() -> None:
with pytest.warns(DeprecationWarning, match="webp_mux"):
assert (features.check("webp_mux") or False) == features.check_module("webp")
def test_webp_anim() -> None:
with pytest.warns(DeprecationWarning, match="webp_anim"):
assert (features.check("webp_anim") or False) == features.check_module("webp")
@skip_unless_feature("libjpeg_turbo")
def test_libjpeg_turbo_version() -> None:
version = features.version("libjpeg_turbo")

View File

@ -93,21 +93,11 @@ def test_sizes() -> None:
with Image.open(TEST_FILE) as im:
assert isinstance(im, IcnsImagePlugin.IcnsImageFile)
for w, h, r in im.info["sizes"]:
wr = w * r
hr = h * r
with pytest.warns(
DeprecationWarning, match=r"Setting size to \(width, height, scale\)"
):
im.size = (w, h, r)
im.load()
assert im.mode == "RGBA"
assert im.size == (wr, hr)
# Test using load() with scale
im.size = (w, h)
im.load(scale=r)
assert im.mode == "RGBA"
assert im.size == (wr, hr)
assert im.size == (w * r, h * r)
# Check that we cannot load an incorrect size
with pytest.raises(ValueError):

View File

@ -1,9 +1,6 @@
from __future__ import annotations
import sys
from io import BytesIO, StringIO
import pytest
from io import BytesIO
from PIL import Image, IptcImagePlugin, TiffImagePlugin, TiffTags
@ -101,35 +98,3 @@ def test_getiptcinfo_tiff_none() -> None:
# Assert
assert iptc is None
def test_i() -> None:
# Arrange
c = b"a"
# Act
with pytest.warns(DeprecationWarning, match="IptcImagePlugin.i"):
ret = IptcImagePlugin.i(c)
# Assert
assert ret == 97
def test_dump(monkeypatch: pytest.MonkeyPatch) -> None:
# Arrange
c = b"abc"
# Temporarily redirect stdout
mystdout = StringIO()
monkeypatch.setattr(sys, "stdout", mystdout)
# Act
with pytest.warns(DeprecationWarning, match="IptcImagePlugin.dump"):
IptcImagePlugin.dump(c)
# Assert
assert mystdout.getvalue() == "61 62 63 \n"
def test_pad_deprecation() -> None:
with pytest.warns(DeprecationWarning, match="IptcImagePlugin.PAD"):
assert IptcImagePlugin.PAD == b"\0\0\0\0"

View File

@ -1115,14 +1115,6 @@ class TestFileJpeg:
assert im._repr_jpeg_() is None
def test_deprecation(self) -> None:
with Image.open(TEST_FILE) as im:
assert isinstance(im, JpegImagePlugin.JpegImageFile)
with pytest.warns(DeprecationWarning, match="huffman_ac"):
assert im.huffman_ac == {}
with pytest.warns(DeprecationWarning, match="huffman_dc"):
assert im.huffman_dc == {}
@pytest.mark.skipif(not is_win32(), reason="Windows only")
@skip_unless_feature("jpg")

View File

@ -256,19 +256,7 @@ class TestFileLibTiff(LibTiffTestCase):
im.save(out, tiffinfo=new_ifd)
@pytest.mark.parametrize(
"libtiff",
(
pytest.param(
True,
marks=pytest.mark.skipif(
not getattr(Image.core, "libtiff_support_custom_tags", False),
reason="Custom tags not supported by older libtiff",
),
),
False,
),
)
@pytest.mark.parametrize("libtiff", (True, False))
def test_custom_metadata(
self, monkeypatch: pytest.MonkeyPatch, tmp_path: Path, libtiff: bool
) -> None:
@ -724,8 +712,7 @@ class TestFileLibTiff(LibTiffTestCase):
with Image.open(out) as reloaded:
assert isinstance(reloaded, TiffImagePlugin.TiffImageFile)
if Image.core.libtiff_support_custom_tags:
assert reloaded.tag_v2[34665] == 125456
assert reloaded.tag_v2[34665] == 125456
def test_crashing_metadata(
self, monkeypatch: pytest.MonkeyPatch, tmp_path: Path
@ -777,19 +764,7 @@ class TestFileLibTiff(LibTiffTestCase):
assert icc_libtiff is not None
assert icc == icc_libtiff
@pytest.mark.parametrize(
"libtiff",
(
pytest.param(
True,
marks=pytest.mark.skipif(
not getattr(Image.core, "libtiff_support_custom_tags", False),
reason="Custom tags not supported by older libtiff",
),
),
False,
),
)
@pytest.mark.parametrize("libtiff", (True, False))
def test_write_icc(
self, monkeypatch: pytest.MonkeyPatch, tmp_path: Path, libtiff: bool
) -> None:

View File

@ -30,7 +30,6 @@ from .helper import (
assert_image_similar_tofile,
assert_not_all_same,
hopper,
is_big_endian,
is_win32,
mark_if_feature_version,
skip_unless_feature,
@ -50,19 +49,10 @@ except ImportError:
PrettyPrinter = None
# Deprecation helper
def helper_image_new(mode: str, size: tuple[int, int]) -> Image.Image:
if mode.startswith("BGR;"):
with pytest.warns(DeprecationWarning, match="BGR;"):
return Image.new(mode, size)
else:
return Image.new(mode, size)
class TestImage:
@pytest.mark.parametrize("mode", Image.MODES + ["BGR;15", "BGR;16", "BGR;24"])
@pytest.mark.parametrize("mode", Image.MODES)
def test_image_modes_success(self, mode: str) -> None:
helper_image_new(mode, (1, 1))
Image.new(mode, (1, 1))
@pytest.mark.parametrize("mode", ("", "bad", "very very long"))
def test_image_modes_fail(self, mode: str) -> None:
@ -1142,39 +1132,29 @@ class TestImage:
assert len(caplog.records) == 0
assert im.fp is None
def test_deprecation(self) -> None:
with pytest.warns(DeprecationWarning, match="Image.isImageType"):
assert not Image.isImageType(None)
class TestImageBytes:
@pytest.mark.parametrize("mode", Image.MODES + ["BGR;15", "BGR;16", "BGR;24"])
@pytest.mark.parametrize("mode", Image.MODES)
def test_roundtrip_bytes_constructor(self, mode: str) -> None:
im = hopper(mode)
source_bytes = im.tobytes()
if mode.startswith("BGR;"):
with pytest.warns(DeprecationWarning, match=mode):
reloaded = Image.frombytes(mode, im.size, source_bytes)
else:
reloaded = Image.frombytes(mode, im.size, source_bytes)
reloaded = Image.frombytes(mode, im.size, source_bytes)
assert reloaded.tobytes() == source_bytes
@pytest.mark.parametrize("mode", Image.MODES + ["BGR;15", "BGR;16", "BGR;24"])
@pytest.mark.parametrize("mode", Image.MODES)
def test_roundtrip_bytes_method(self, mode: str) -> None:
im = hopper(mode)
source_bytes = im.tobytes()
reloaded = helper_image_new(mode, im.size)
reloaded = Image.new(mode, im.size)
reloaded.frombytes(source_bytes)
assert reloaded.tobytes() == source_bytes
@pytest.mark.parametrize("mode", Image.MODES + ["BGR;15", "BGR;16", "BGR;24"])
@pytest.mark.parametrize("mode", Image.MODES)
def test_getdata_putdata(self, mode: str) -> None:
if is_big_endian() and mode == "BGR;15":
pytest.xfail("Known failure of BGR;15 on big-endian")
im = hopper(mode)
reloaded = helper_image_new(mode, im.size)
reloaded = Image.new(mode, im.size)
reloaded.putdata(im.getdata())
assert_image_equal(im, reloaded)

View File

@ -123,10 +123,6 @@ class TestImageGetPixel:
bands = Image.getmodebands(mode)
if bands == 1:
return 1
if mode in ("BGR;15", "BGR;16"):
# These modes have less than 8 bits per band,
# so (1, 2, 3) cannot be roundtripped.
return (16, 32, 49)
return tuple(range(1, bands + 1))
def check(self, mode: str, expected_color_int: int | None = None) -> None:
@ -191,11 +187,6 @@ class TestImageGetPixel:
def test_basic(self, mode: str) -> None:
self.check(mode)
@pytest.mark.parametrize("mode", ("BGR;15", "BGR;16", "BGR;24"))
def test_deprecated(self, mode: str) -> None:
with pytest.warns(DeprecationWarning, match="BGR;"):
self.check(mode)
def test_list(self) -> None:
im = hopper()
assert im.getpixel([0, 0]) == (20, 20, 70)
@ -218,7 +209,7 @@ class TestImageGetPixel:
class TestImagePutPixelError:
IMAGE_MODES1 = ["LA", "RGB", "RGBA", "BGR;15"]
IMAGE_MODES1 = ["LA", "RGB", "RGBA"]
IMAGE_MODES2 = ["L", "I", "I;16"]
INVALID_TYPES = ["foo", 1.0, None]
@ -234,11 +225,6 @@ class TestImagePutPixelError:
(
("L", (0, 2), "color must be int or single-element tuple"),
("LA", (0, 3), "color must be int, or tuple of one or two elements"),
(
"BGR;15",
(0, 2),
"color must be int, or tuple of one or three elements",
),
(
"RGB",
(0, 2, 5),

View File

@ -1,7 +1,5 @@
from __future__ import annotations
import pytest
from .helper import hopper
@ -10,10 +8,3 @@ def test_sanity() -> None:
type_repr = repr(type(im.getim()))
assert "PyCapsule" in type_repr
with pytest.warns(DeprecationWarning, match="id property"):
assert isinstance(im.im.id, int)
with pytest.warns(DeprecationWarning, match="unsafe_ptrs property"):
ptrs = dict(im.im.unsafe_ptrs)
assert ptrs.keys() == {"image8", "image32", "image"}

View File

@ -78,16 +78,6 @@ def test_mode_F() -> None:
assert list(im.getdata()) == target
@pytest.mark.parametrize("mode", ("BGR;15", "BGR;16", "BGR;24"))
def test_mode_BGR(mode: str) -> None:
data = [(16, 32, 49), (32, 32, 98)]
with pytest.warns(DeprecationWarning, match=mode):
im = Image.new(mode, (1, 2))
im.putdata(data)
assert list(im.getdata()) == data
def test_array_B() -> None:
# shouldn't segfault
# see https://github.com/python-pillow/Pillow/issues/1008

View File

@ -324,7 +324,7 @@ class TestImageResize:
im = hopper(mode)
assert im.resize((20, 20), Image.Resampling.BICUBIC) == im.resize((20, 20))
@pytest.mark.parametrize("mode", ("1", "P", "BGR;15", "BGR;16"))
@pytest.mark.parametrize("mode", ("1", "P"))
def test_default_filter_nearest(self, mode: str) -> None:
im = hopper(mode)
assert im.resize((20, 20), Image.Resampling.NEAREST) == im.resize((20, 20))

View File

@ -54,10 +54,6 @@ def skip_missing() -> None:
def test_sanity() -> None:
# basic smoke test.
# this mostly follows the cms_test outline.
with pytest.warns(DeprecationWarning, match="PIL.ImageCms.versions"):
v = ImageCms.versions() # should return four strings
assert v[0] == "1.0.0 pil"
assert list(map(type, v)) == [str, str, str, str]
# internal version number
version = features.version_module("littlecms2")
@ -677,12 +673,6 @@ def test_auxiliary_channels_isolated() -> None:
assert_image_equal(test_image.convert(dst_format[2]), reference_image)
def test_long_modes() -> None:
p = ImageCms.getOpenProfile("Tests/icc/sGrey-v2-nano.icc")
with pytest.warns(DeprecationWarning, match="ABCDEFGHI"):
ImageCms.buildTransform(p, p, "ABCDEFGHI", "ABCDEFGHI")
@pytest.mark.parametrize("mode", ("RGB", "RGBA", "RGBX"))
def test_rgb_lab(mode: str) -> None:
im = Image.new(mode, (1, 1))
@ -700,18 +690,3 @@ def test_cmyk_lab() -> None:
im = Image.new("CMYK", (1, 1))
converted_im = im.convert("LAB")
assert converted_im.getpixel((0, 0)) == (255, 128, 128)
def test_deprecation() -> None:
with pytest.warns(DeprecationWarning, match="ImageCms.DESCRIPTION"):
assert ImageCms.DESCRIPTION.strip().startswith("pyCMS")
with pytest.warns(DeprecationWarning, match="ImageCms.VERSION"):
assert ImageCms.VERSION == "1.0.0 pil"
with pytest.warns(DeprecationWarning, match="ImageCms.FLAGS"):
assert isinstance(ImageCms.FLAGS, dict)
profile = ImageCmsProfile(ImageCms.createProfile("sRGB"))
with pytest.warns(DeprecationWarning, match="RGBA;16B"):
ImageCms.ImageCmsTransform(profile, profile, "RGBA;16B", "RGB")
with pytest.warns(DeprecationWarning, match="RGBA;16B"):
ImageCms.ImageCmsTransform(profile, profile, "RGB", "RGBA;16B")

View File

@ -1732,8 +1732,3 @@ def test_incorrectly_ordered_coordinates(xy: tuple[int, int, int, int]) -> None:
draw.rectangle(xy)
with pytest.raises(ValueError):
draw.rounded_rectangle(xy)
def test_getdraw() -> None:
with pytest.warns(DeprecationWarning, match="'hints' parameter"):
ImageDraw.getdraw(None, [])

View File

@ -151,11 +151,6 @@ class TestImageFile:
# Despite multiple tiles, assert only one tile caused a read of maxblock size
assert reads.count(im.decodermaxblock) == 1
def test_raise_oserror(self) -> None:
with pytest.warns(DeprecationWarning, match="raise_oserror"):
with pytest.raises(OSError):
ImageFile.raise_oserror(1)
def test_raise_typeerror(self) -> None:
with pytest.raises(TypeError):
parser = ImageFile.Parser()

View File

@ -11,7 +11,6 @@ from pathlib import Path
from typing import Any, BinaryIO
import pytest
from packaging.version import parse as parse_version
from PIL import Image, ImageDraw, ImageFont, features
from PIL._typing import StrOrBytesPath
@ -691,16 +690,6 @@ def test_complex_font_settings() -> None:
def test_variation_get(font: ImageFont.FreeTypeFont) -> None:
version = features.version_module("freetype2")
assert version is not None
freetype = parse_version(version)
if freetype < parse_version("2.9.1"):
with pytest.raises(NotImplementedError):
font.get_variation_names()
with pytest.raises(NotImplementedError):
font.get_variation_axes()
return
with pytest.raises(OSError):
font.get_variation_names()
with pytest.raises(OSError):
@ -763,14 +752,6 @@ def _check_text(font: ImageFont.FreeTypeFont, path: str, epsilon: float) -> None
def test_variation_set_by_name(font: ImageFont.FreeTypeFont) -> None:
version = features.version_module("freetype2")
assert version is not None
freetype = parse_version(version)
if freetype < parse_version("2.9.1"):
with pytest.raises(NotImplementedError):
font.set_variation_by_name("Bold")
return
with pytest.raises(OSError):
font.set_variation_by_name("Bold")
@ -790,14 +771,6 @@ def test_variation_set_by_name(font: ImageFont.FreeTypeFont) -> None:
def test_variation_set_by_axes(font: ImageFont.FreeTypeFont) -> None:
version = features.version_module("freetype2")
assert version is not None
freetype = parse_version(version)
if freetype < parse_version("2.9.1"):
with pytest.raises(NotImplementedError):
font.set_variation_by_axes([100])
return
with pytest.raises(OSError):
font.set_variation_by_axes([500, 50])
@ -1209,15 +1182,3 @@ def test_invalid_truetype_sizes_raise_valueerror(
) -> None:
with pytest.raises(ValueError):
ImageFont.truetype(FONT_PATH, size, layout_engine=layout_engine)
def test_freetype_deprecation(monkeypatch: pytest.MonkeyPatch) -> None:
# Arrange: mock features.version_module to return fake FreeType version
def fake_version_module(module: str) -> str:
return "2.9.0"
monkeypatch.setattr(features, "version_module", fake_version_module)
# Act / Assert
with pytest.warns(DeprecationWarning, match="FreeType 2.9.0"):
ImageFont.truetype(FONT_PATH, FONT_SIZE)

View File

@ -2,8 +2,6 @@ from __future__ import annotations
from typing import Any
import pytest
from PIL import Image, ImageMath
@ -55,11 +53,6 @@ def test_sanity() -> None:
)
def test_options_deprecated() -> None:
with pytest.warns(DeprecationWarning, match="ImageMath.lambda_eval options"):
assert ImageMath.lambda_eval(lambda args: 1, images) == 1
def test_ops() -> None:
assert pixel(ImageMath.lambda_eval(lambda args: args["A"] * -1, **images)) == "I -1"

View File

@ -35,16 +35,6 @@ def test_sanity() -> None:
assert pixel(ImageMath.unsafe_eval("int(float(A)+B)", **images)) == "I 3"
def test_eval_deprecated() -> None:
with pytest.warns(DeprecationWarning, match="ImageMath.eval"):
assert ImageMath.eval("1") == 1
def test_options_deprecated() -> None:
with pytest.warns(DeprecationWarning, match="ImageMath.unsafe_eval options"):
assert ImageMath.unsafe_eval("1", images) == 1
def test_ops() -> None:
assert pixel(ImageMath.unsafe_eval("-A", **images)) == "I -1"
assert pixel(ImageMath.unsafe_eval("+B", **images)) == "L 2"

View File

@ -361,18 +361,6 @@ class TestLibUnpack:
"RGB", "CMYK", 4, (250, 249, 248), (242, 241, 240), (234, 233, 233)
)
def test_BGR(self) -> None:
with pytest.warns(DeprecationWarning, match="BGR;15"):
self.assert_unpack(
"BGR;15", "BGR;15", 3, (8, 131, 0), (24, 0, 8), (41, 131, 8)
)
with pytest.warns(DeprecationWarning, match="BGR;16"):
self.assert_unpack(
"BGR;16", "BGR;16", 3, (8, 64, 0), (24, 129, 0), (41, 194, 0)
)
with pytest.warns(DeprecationWarning, match="BGR;24"):
self.assert_unpack("BGR;24", "BGR;24", 3, (1, 2, 3), (4, 5, 6), (7, 8, 9))
def test_RGBA(self) -> None:
self.assert_unpack("RGBA", "LA", 2, (1, 1, 1, 2), (3, 3, 3, 4), (5, 5, 5, 6))
self.assert_unpack(

View File

@ -39,9 +39,6 @@ def test_wheel_codecs() -> None:
def test_wheel_features() -> None:
expected_features = {
"webp_anim",
"webp_mux",
"transp_webp",
"raqm",
"fribidi",
"harfbuzz",

View File

@ -12,96 +12,6 @@ Deprecated features
Below are features which are considered deprecated. Where appropriate,
a :py:exc:`DeprecationWarning` is issued.
ImageFile.raise_oserror
~~~~~~~~~~~~~~~~~~~~~~~
.. deprecated:: 10.2.0
``ImageFile.raise_oserror()`` has been deprecated and will be removed in Pillow
12.0.0 (2025-10-15). The function is undocumented and is only useful for translating
error codes returned by a codec's ``decode()`` method, which ImageFile already does
automatically.
IptcImageFile helper functions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. deprecated:: 10.2.0
The functions ``IptcImageFile.dump`` and ``IptcImageFile.i``, and the constant
``IptcImageFile.PAD`` have been deprecated and will be removed in Pillow
12.0.0 (2025-10-15). These are undocumented helper functions intended
for internal use, so there is no replacement. They can each be replaced
by a single line of code using builtin functions in Python.
ImageCms constants and versions() function
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. deprecated:: 10.3.0
A number of constants and a function in :py:mod:`.ImageCms` have been deprecated.
This includes a table of flags based on LittleCMS version 1 which has been
replaced with a new class :py:class:`.ImageCms.Flags` based on LittleCMS 2 flags.
============================================ ====================================================
Deprecated Use instead
============================================ ====================================================
``ImageCms.DESCRIPTION`` No replacement
``ImageCms.VERSION`` ``PIL.__version__``
``ImageCms.FLAGS["MATRIXINPUT"]`` :py:attr:`.ImageCms.Flags.CLUT_POST_LINEARIZATION`
``ImageCms.FLAGS["MATRIXOUTPUT"]`` :py:attr:`.ImageCms.Flags.FORCE_CLUT`
``ImageCms.FLAGS["MATRIXONLY"]`` No replacement
``ImageCms.FLAGS["NOWHITEONWHITEFIXUP"]`` :py:attr:`.ImageCms.Flags.NOWHITEONWHITEFIXUP`
``ImageCms.FLAGS["NOPRELINEARIZATION"]`` :py:attr:`.ImageCms.Flags.CLUT_PRE_LINEARIZATION`
``ImageCms.FLAGS["GUESSDEVICECLASS"]`` :py:attr:`.ImageCms.Flags.GUESSDEVICECLASS`
``ImageCms.FLAGS["NOTCACHE"]`` :py:attr:`.ImageCms.Flags.NOCACHE`
``ImageCms.FLAGS["NOTPRECALC"]`` :py:attr:`.ImageCms.Flags.NOOPTIMIZE`
``ImageCms.FLAGS["NULLTRANSFORM"]`` :py:attr:`.ImageCms.Flags.NULLTRANSFORM`
``ImageCms.FLAGS["HIGHRESPRECALC"]`` :py:attr:`.ImageCms.Flags.HIGHRESPRECALC`
``ImageCms.FLAGS["LOWRESPRECALC"]`` :py:attr:`.ImageCms.Flags.LOWRESPRECALC`
``ImageCms.FLAGS["GAMUTCHECK"]`` :py:attr:`.ImageCms.Flags.GAMUTCHECK`
``ImageCms.FLAGS["WHITEBLACKCOMPENSATION"]`` :py:attr:`.ImageCms.Flags.BLACKPOINTCOMPENSATION`
``ImageCms.FLAGS["BLACKPOINTCOMPENSATION"]`` :py:attr:`.ImageCms.Flags.BLACKPOINTCOMPENSATION`
``ImageCms.FLAGS["SOFTPROOFING"]`` :py:attr:`.ImageCms.Flags.SOFTPROOFING`
``ImageCms.FLAGS["PRESERVEBLACK"]`` :py:attr:`.ImageCms.Flags.NONEGATIVES`
``ImageCms.FLAGS["NODEFAULTRESOURCEDEF"]`` :py:attr:`.ImageCms.Flags.NODEFAULTRESOURCEDEF`
``ImageCms.FLAGS["GRIDPOINTS"]`` :py:attr:`.ImageCms.Flags.GRIDPOINTS()`
``ImageCms.versions()`` :py:func:`PIL.features.version_module` with
``feature="littlecms2"``, :py:data:`sys.version` or
:py:data:`sys.version_info`, and ``PIL.__version__``
============================================ ====================================================
ImageMath eval()
^^^^^^^^^^^^^^^^
.. deprecated:: 10.3.0
``ImageMath.eval()`` has been deprecated. Use :py:meth:`~PIL.ImageMath.lambda_eval` or
:py:meth:`~PIL.ImageMath.unsafe_eval` instead.
BGR;15, BGR 16 and BGR;24
^^^^^^^^^^^^^^^^^^^^^^^^^
.. deprecated:: 10.4.0
The experimental BGR;15, BGR;16 and BGR;24 modes have been deprecated.
Non-image modes in ImageCms
^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. deprecated:: 10.4.0
The use in :py:mod:`.ImageCms` of input modes and output modes that are not Pillow
image modes has been deprecated. Defaulting to "L" or "1" if the mode cannot be mapped
is also deprecated.
Support for LibTIFF earlier than 4
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. deprecated:: 10.4.0
Support for LibTIFF earlier than version 4 has been deprecated.
Upgrade to a newer version of LibTIFF instead.
ImageDraw.getdraw hints parameter
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -109,72 +19,6 @@ ImageDraw.getdraw hints parameter
The ``hints`` parameter in :py:meth:`~PIL.ImageDraw.getdraw()` has been deprecated.
FreeType 2.9.0
^^^^^^^^^^^^^^
.. deprecated:: 11.0.0
Support for FreeType 2.9.0 is deprecated and will be removed in Pillow 12.0.0
(2025-10-15), when FreeType 2.9.1 will be the minimum supported.
We recommend upgrading to at least FreeType `2.10.4`_, which fixed a severe
vulnerability introduced in FreeType 2.6 (:cve:`2020-15999`).
.. _2.10.4: https://sourceforge.net/projects/freetype/files/freetype2/2.10.4/
ICNS (width, height, scale) sizes
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. deprecated:: 11.0.0
Setting an ICNS image size to ``(width, height, scale)`` before loading has been
deprecated. Instead, ``load(scale)`` can be used.
Image isImageType()
^^^^^^^^^^^^^^^^^^^
.. deprecated:: 11.0.0
``Image.isImageType(im)`` has been deprecated. Use ``isinstance(im, Image.Image)``
instead.
ImageMath.lambda_eval and ImageMath.unsafe_eval options parameter
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. deprecated:: 11.0.0
The ``options`` parameter in :py:meth:`~PIL.ImageMath.lambda_eval()` and
:py:meth:`~PIL.ImageMath.unsafe_eval()` has been deprecated. One or more keyword
arguments can be used instead.
JpegImageFile.huffman_ac and JpegImageFile.huffman_dc
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. deprecated:: 11.0.0
The ``huffman_ac`` and ``huffman_dc`` dictionaries on JPEG images were unused. They
have been deprecated, and will be removed in Pillow 12 (2025-10-15).
Specific WebP feature checks
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. deprecated:: 11.0.0
``features.check("transp_webp")``, ``features.check("webp_mux")`` and
``features.check("webp_anim")`` are now deprecated. They will always return
``True`` if the WebP module is installed, until they are removed in Pillow
12.0.0 (2025-10-15).
Get internal pointers to objects
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. deprecated:: 11.0.0
``Image.core.ImagingCore.id`` and ``Image.core.ImagingCore.unsafe_ptrs`` have been
deprecated and will be removed in Pillow 12 (2025-10-15). They were used for obtaining
raw pointers to ``ImagingCore`` internals. To interact with C code, you can use
``Image.Image.getim()``, which returns a ``Capsule`` object.
ExifTags.IFD.Makernote
^^^^^^^^^^^^^^^^^^^^^^
@ -221,12 +65,185 @@ Removed features
Deprecated features are only removed in major releases after an appropriate
period of deprecation has passed.
ImageFile.raise_oserror
^^^^^^^^^^^^^^^^^^^^^^^
.. deprecated:: 10.2.0
.. versionremoved:: 12.0.0
``ImageFile.raise_oserror()`` has been removed. The function was undocumented and was
only useful for translating error codes returned by a codec's ``decode()`` method,
which ImageFile already did automatically.
IptcImageFile helper functions
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. deprecated:: 10.2.0
.. versionremoved:: 12.0.0
The functions ``IptcImageFile.dump`` and ``IptcImageFile.i``, and the constant
``IptcImageFile.PAD`` have been removed. These were undocumented helper functions
intended for internal use, so there is no replacement. They can each be replaced by a
single line of code using builtin functions in Python.
ImageCms constants and versions() function
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. deprecated:: 10.3.0
.. versionremoved:: 12.0.0
A number of constants and a function in :py:mod:`.ImageCms` have been removed. This
includes a table of flags based on LittleCMS version 1 which has been replaced with a
new class :py:class:`.ImageCms.Flags` based on LittleCMS 2 flags.
============================================ ====================================================
Deprecated Use instead
============================================ ====================================================
``ImageCms.DESCRIPTION`` No replacement
``ImageCms.VERSION`` ``PIL.__version__``
``ImageCms.FLAGS["MATRIXINPUT"]`` :py:attr:`.ImageCms.Flags.CLUT_POST_LINEARIZATION`
``ImageCms.FLAGS["MATRIXOUTPUT"]`` :py:attr:`.ImageCms.Flags.FORCE_CLUT`
``ImageCms.FLAGS["MATRIXONLY"]`` No replacement
``ImageCms.FLAGS["NOWHITEONWHITEFIXUP"]`` :py:attr:`.ImageCms.Flags.NOWHITEONWHITEFIXUP`
``ImageCms.FLAGS["NOPRELINEARIZATION"]`` :py:attr:`.ImageCms.Flags.CLUT_PRE_LINEARIZATION`
``ImageCms.FLAGS["GUESSDEVICECLASS"]`` :py:attr:`.ImageCms.Flags.GUESSDEVICECLASS`
``ImageCms.FLAGS["NOTCACHE"]`` :py:attr:`.ImageCms.Flags.NOCACHE`
``ImageCms.FLAGS["NOTPRECALC"]`` :py:attr:`.ImageCms.Flags.NOOPTIMIZE`
``ImageCms.FLAGS["NULLTRANSFORM"]`` :py:attr:`.ImageCms.Flags.NULLTRANSFORM`
``ImageCms.FLAGS["HIGHRESPRECALC"]`` :py:attr:`.ImageCms.Flags.HIGHRESPRECALC`
``ImageCms.FLAGS["LOWRESPRECALC"]`` :py:attr:`.ImageCms.Flags.LOWRESPRECALC`
``ImageCms.FLAGS["GAMUTCHECK"]`` :py:attr:`.ImageCms.Flags.GAMUTCHECK`
``ImageCms.FLAGS["WHITEBLACKCOMPENSATION"]`` :py:attr:`.ImageCms.Flags.BLACKPOINTCOMPENSATION`
``ImageCms.FLAGS["BLACKPOINTCOMPENSATION"]`` :py:attr:`.ImageCms.Flags.BLACKPOINTCOMPENSATION`
``ImageCms.FLAGS["SOFTPROOFING"]`` :py:attr:`.ImageCms.Flags.SOFTPROOFING`
``ImageCms.FLAGS["PRESERVEBLACK"]`` :py:attr:`.ImageCms.Flags.NONEGATIVES`
``ImageCms.FLAGS["NODEFAULTRESOURCEDEF"]`` :py:attr:`.ImageCms.Flags.NODEFAULTRESOURCEDEF`
``ImageCms.FLAGS["GRIDPOINTS"]`` :py:attr:`.ImageCms.Flags.GRIDPOINTS()`
``ImageCms.versions()`` :py:func:`PIL.features.version_module` with
``feature="littlecms2"``, :py:data:`sys.version` or
:py:data:`sys.version_info`, and ``PIL.__version__``
============================================ ====================================================
ImageMath eval()
^^^^^^^^^^^^^^^^
.. deprecated:: 10.3.0
.. versionremoved:: 12.0.0
``ImageMath.eval()`` has been removed. Use :py:meth:`~PIL.ImageMath.lambda_eval` or
:py:meth:`~PIL.ImageMath.unsafe_eval` instead.
BGR;15, BGR 16 and BGR;24
^^^^^^^^^^^^^^^^^^^^^^^^^
.. deprecated:: 10.4.0
.. versionremoved:: 12.0.0
The experimental BGR;15, BGR;16 and BGR;24 modes have been removed.
Non-image modes in ImageCms
^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. deprecated:: 10.4.0
.. versionremoved:: 12.0.0
The use in :py:mod:`.ImageCms` of input modes and output modes that are not Pillow
image modes has been removed. Defaulting to "L" or "1" if the mode cannot be mapped has
also been removed.
Support for LibTIFF earlier than 4
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. deprecated:: 10.4.0
.. versionremoved:: 12.0.0
Support for LibTIFF earlier than version 4 has been removed.
Upgrade to a newer version of LibTIFF instead.
ImageDraw.getdraw hints parameter
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. deprecated:: 10.4.0
.. versionremoved:: 12.0.0
The ``hints`` parameter in :py:meth:`~PIL.ImageDraw.getdraw()` has been removed.
FreeType 2.9.0
^^^^^^^^^^^^^^
.. deprecated:: 11.0.0
.. versionremoved:: 12.0.0
Support for FreeType 2.9.0 has been removed. FreeType 2.9.1 is the minimum version
supported.
We recommend upgrading to at least FreeType `2.10.4`_, which fixed a severe
vulnerability introduced in FreeType 2.6 (:cve:`2020-15999`).
.. _2.10.4: https://sourceforge.net/projects/freetype/files/freetype2/2.10.4/
ICNS (width, height, scale) sizes
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. deprecated:: 11.0.0
Setting an ICNS image size to ``(width, height, scale)`` before loading has been
removed. Instead, ``load(scale)`` can be used.
Image isImageType()
^^^^^^^^^^^^^^^^^^^
.. deprecated:: 11.0.0
.. versionremoved:: 12.0.0
``Image.isImageType(im)`` has been removed. Use ``isinstance(im, Image.Image)``
instead.
ImageMath.lambda_eval and ImageMath.unsafe_eval options parameter
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. deprecated:: 11.0.0
.. versionremoved:: 12.0.0
The ``options`` parameter in :py:meth:`~PIL.ImageMath.lambda_eval()` and
:py:meth:`~PIL.ImageMath.unsafe_eval()` has been removed. One or more keyword
arguments can be used instead.
JpegImageFile.huffman_ac and JpegImageFile.huffman_dc
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. deprecated:: 11.0.0
.. versionremoved:: 12.0.0
The ``huffman_ac`` and ``huffman_dc`` dictionaries on JPEG images were unused. They
have been removed.
Specific WebP feature checks
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. deprecated:: 11.0.0
.. versionremoved:: 12.0.0
``features.check("transp_webp")``, ``features.check("webp_mux")`` and
``features.check("webp_anim")`` have been removed.
Get internal pointers to objects
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. deprecated:: 11.0.0
.. versionremoved:: 12.0.0
``Image.core.ImagingCore.id`` and ``Image.core.ImagingCore.unsafe_ptrs`` have been
removed. They were used for obtaining raw pointers to ``ImagingCore`` internals. To
interact with C code, you can use ``Image.Image.getim()``, which returns a ``Capsule``
object.
TiffImagePlugin IFD_LEGACY_API
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. versionremoved:: 11.0.0
``TiffImagePlugin.IFD_LEGACY_API`` was removed, as it was an unused setting.
``TiffImagePlugin.IFD_LEGACY_API`` has been removed, as it was an unused setting.
PSFile
~~~~~~

View File

@ -56,7 +56,6 @@ Functions
.. autofunction:: get_display_profile
.. autofunction:: isIntentSupported
.. autofunction:: profileToProfile
.. autofunction:: versions
CmsProfile
----------

View File

@ -21,9 +21,7 @@ with any Arrow provider or consumer in the Python ecosystem.
Data formats
============
Pillow currently supports exporting Arrow images in all modes
**except** for ``BGR;15``, ``BGR;16`` and ``BGR;24``. This is due to
line-length packing in these modes making for non-continuous memory.
Pillow currently supports exporting Arrow images in all modes.
For single-band images, the exported array is width*height elements,
with each pixel corresponding to the appropriate Arrow type.

View File

@ -60,9 +60,6 @@ Support for the following features can be checked:
* ``raqm``: Raqm library, required for ``ImageFont.Layout.RAQM`` in :py:func:`PIL.ImageFont.truetype`. Run-time version number is available for Raqm 0.7.0 or newer.
* ``libimagequant``: (compile time) ImageQuant quantization support in :py:func:`PIL.Image.Image.quantize`. Run-time version number is available.
* ``xcb``: (compile time) Support for X11 in :py:func:`PIL.ImageGrab.grab` via the XCB library.
* ``transp_webp``: Deprecated. Always ``True`` if WebP module is installed.
* ``webp_mux``: Deprecated. Always ``True`` if WebP module is installed.
* ``webp_anim``: Deprecated. Always ``True`` if WebP module is installed.
.. autofunction:: PIL.features.check_feature
.. autofunction:: PIL.features.version_feature

View File

@ -0,0 +1,140 @@
12.0.0
------
Security
========
TODO
^^^^
TODO
:cve:`YYYY-XXXXX`: TODO
^^^^^^^^^^^^^^^^^^^^^^^
TODO
Backwards incompatible changes
==============================
ImageFile.raise_oserror
^^^^^^^^^^^^^^^^^^^^^^^
``ImageFile.raise_oserror()`` has been removed. The function was undocumented and was
only useful for translating error codes returned by a codec's ``decode()`` method,
which ImageFile already did automatically.
IptcImageFile helper functions
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The functions ``IptcImageFile.dump`` and ``IptcImageFile.i``, and the constant
``IptcImageFile.PAD`` have been removed. These were undocumented helper functions
intended for internal use, so there is no replacement. They can each be replaced by a
single line of code using builtin functions in Python.
ImageCms constants and versions() function
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
A number of constants and a function in :py:mod:`.ImageCms` have been removed. This
includes a table of flags based on LittleCMS version 1 which has been replaced with a
new class :py:class:`.ImageCms.Flags` based on LittleCMS 2 flags.
============================================ ====================================================
Deprecated Use instead
============================================ ====================================================
``ImageCms.DESCRIPTION`` No replacement
``ImageCms.VERSION`` ``PIL.__version__``
``ImageCms.FLAGS["MATRIXINPUT"]`` :py:attr:`.ImageCms.Flags.CLUT_POST_LINEARIZATION`
``ImageCms.FLAGS["MATRIXOUTPUT"]`` :py:attr:`.ImageCms.Flags.FORCE_CLUT`
``ImageCms.FLAGS["MATRIXONLY"]`` No replacement
``ImageCms.FLAGS["NOWHITEONWHITEFIXUP"]`` :py:attr:`.ImageCms.Flags.NOWHITEONWHITEFIXUP`
``ImageCms.FLAGS["NOPRELINEARIZATION"]`` :py:attr:`.ImageCms.Flags.CLUT_PRE_LINEARIZATION`
``ImageCms.FLAGS["GUESSDEVICECLASS"]`` :py:attr:`.ImageCms.Flags.GUESSDEVICECLASS`
``ImageCms.FLAGS["NOTCACHE"]`` :py:attr:`.ImageCms.Flags.NOCACHE`
``ImageCms.FLAGS["NOTPRECALC"]`` :py:attr:`.ImageCms.Flags.NOOPTIMIZE`
``ImageCms.FLAGS["NULLTRANSFORM"]`` :py:attr:`.ImageCms.Flags.NULLTRANSFORM`
``ImageCms.FLAGS["HIGHRESPRECALC"]`` :py:attr:`.ImageCms.Flags.HIGHRESPRECALC`
``ImageCms.FLAGS["LOWRESPRECALC"]`` :py:attr:`.ImageCms.Flags.LOWRESPRECALC`
``ImageCms.FLAGS["GAMUTCHECK"]`` :py:attr:`.ImageCms.Flags.GAMUTCHECK`
``ImageCms.FLAGS["WHITEBLACKCOMPENSATION"]`` :py:attr:`.ImageCms.Flags.BLACKPOINTCOMPENSATION`
``ImageCms.FLAGS["BLACKPOINTCOMPENSATION"]`` :py:attr:`.ImageCms.Flags.BLACKPOINTCOMPENSATION`
``ImageCms.FLAGS["SOFTPROOFING"]`` :py:attr:`.ImageCms.Flags.SOFTPROOFING`
``ImageCms.FLAGS["PRESERVEBLACK"]`` :py:attr:`.ImageCms.Flags.NONEGATIVES`
``ImageCms.FLAGS["NODEFAULTRESOURCEDEF"]`` :py:attr:`.ImageCms.Flags.NODEFAULTRESOURCEDEF`
``ImageCms.FLAGS["GRIDPOINTS"]`` :py:attr:`.ImageCms.Flags.GRIDPOINTS()`
``ImageCms.versions()`` :py:func:`PIL.features.version_module` with
``feature="littlecms2"``, :py:data:`sys.version` or
:py:data:`sys.version_info`, and ``PIL.__version__``
============================================ ====================================================
ImageMath eval()
^^^^^^^^^^^^^^^^
``ImageMath.eval()`` has been removed. Use :py:meth:`~PIL.ImageMath.lambda_eval` or
:py:meth:`~PIL.ImageMath.unsafe_eval` instead.
BGR;15, BGR 16 and BGR;24
^^^^^^^^^^^^^^^^^^^^^^^^^
The experimental BGR;15, BGR;16 and BGR;24 modes have been removed.
Non-image modes in ImageCms
^^^^^^^^^^^^^^^^^^^^^^^^^^^
The use in :py:mod:`.ImageCms` of input modes and output modes that are not Pillow
image modes has been removed. Defaulting to "L" or "1" if the mode cannot be mapped has
also been removed.
Support for LibTIFF earlier than 4
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Support for LibTIFF earlier than version 4 has been removed.
Upgrade to a newer version of LibTIFF instead.
ImageDraw.getdraw hints parameter
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The ``hints`` parameter in :py:meth:`~PIL.ImageDraw.getdraw()` has been removed.
FreeType 2.9.0
^^^^^^^^^^^^^^
Support for FreeType 2.9.0 has been removed. FreeType 2.9.1 is the minimum version
supported.
We recommend upgrading to at least FreeType `2.10.4`_, which fixed a severe
vulnerability introduced in FreeType 2.6 (:cve:`2020-15999`).
.. _2.10.4: https://sourceforge.net/projects/freetype/files/freetype2/2.10.4/
Deprecations
============
TODO
^^^^
TODO
API changes
===========
TODO
^^^^
TODO
API additions
=============
TODO
^^^^
TODO
Other changes
=============
TODO
^^^^
TODO

View File

@ -14,6 +14,7 @@ expected to be backported to earlier versions.
.. toctree::
:maxdepth: 2
12.0.0
11.3.0
11.2.1
11.1.0

View File

@ -20,6 +20,8 @@ Backwards incompatible changes
TODO
^^^^
TODO
Deprecations
============

View File

@ -25,7 +25,6 @@ import sys
from typing import IO
from . import Image, ImageFile, PngImagePlugin, features
from ._deprecate import deprecate
enable_jpeg2k = features.check_codec("jpg_2000")
if enable_jpeg2k:
@ -275,34 +274,25 @@ class IcnsImageFile(ImageFile.ImageFile):
self.best_size[1] * self.best_size[2],
)
@property # type: ignore[override]
def size(self) -> tuple[int, int] | tuple[int, int, int]:
@property
def size(self) -> tuple[int, int]:
return self._size
@size.setter
def size(self, value: tuple[int, int] | tuple[int, int, int]) -> None:
if len(value) == 3:
deprecate("Setting size to (width, height, scale)", 12, "load(scale)")
if value in self.info["sizes"]:
self._size = value # type: ignore[assignment]
def size(self, value: tuple[int, int]) -> None:
# Check that a matching size exists,
# or that there is a scale that would create a size that matches
for size in self.info["sizes"]:
simple_size = size[0] * size[2], size[1] * size[2]
scale = simple_size[0] // value[0]
if simple_size[1] / value[1] == scale:
self._size = value
return
else:
# Check that a matching size exists,
# or that there is a scale that would create a size that matches
for size in self.info["sizes"]:
simple_size = size[0] * size[2], size[1] * size[2]
scale = simple_size[0] // value[0]
if simple_size[1] / value[1] == scale:
self._size = value
return
msg = "This is not one of the allowed sizes of this image"
raise ValueError(msg)
def load(self, scale: int | None = None) -> Image.core.PixelAccess | None:
if scale is not None or len(self.size) == 3:
if scale is None and len(self.size) == 3:
scale = self.size[2]
assert scale is not None
if scale is not None:
width, height = self.size[:2]
self.size = width * scale, height * scale
self.best_size = width, height, scale

View File

@ -115,21 +115,6 @@ except ImportError as v:
raise
def isImageType(t: Any) -> TypeGuard[Image]:
"""
Checks if an object is an image object.
.. warning::
This function is for internal use only.
:param t: object to check if it's an image
:returns: True if the object is an image
"""
deprecate("Image.isImageType(im)", 12, "isinstance(im, Image.Image)")
return hasattr(t, "im")
#
# Constants
@ -219,7 +204,7 @@ if TYPE_CHECKING:
from IPython.lib.pretty import PrettyPrinter
from . import ImageFile, ImageFilter, ImagePalette, ImageQt, TiffImagePlugin
from ._typing import CapsuleType, NumpyArray, StrOrBytesPath, TypeGuard
from ._typing import CapsuleType, NumpyArray, StrOrBytesPath
ID: list[str] = []
OPEN: dict[
str,
@ -980,9 +965,6 @@ class Image:
:returns: An :py:class:`~PIL.Image.Image` object.
"""
if mode in ("BGR;15", "BGR;16", "BGR;24"):
deprecate(mode, 12)
self.load()
has_transparency = "transparency" in self.info
@ -2229,8 +2211,6 @@ class Image:
:py:data:`Resampling.BILINEAR`, :py:data:`Resampling.HAMMING`,
:py:data:`Resampling.BICUBIC` or :py:data:`Resampling.LANCZOS`.
If the image has mode "1" or "P", it is always set to
:py:data:`Resampling.NEAREST`. If the image mode is "BGR;15",
"BGR;16" or "BGR;24", then the default filter is
:py:data:`Resampling.NEAREST`. Otherwise, the default filter is
:py:data:`Resampling.BICUBIC`. See: :ref:`concept-filters`.
:param box: An optional 4-tuple of floats providing
@ -2253,8 +2233,7 @@ class Image:
"""
if resample is None:
bgr = self.mode.startswith("BGR;")
resample = Resampling.NEAREST if bgr else Resampling.BICUBIC
resample = Resampling.BICUBIC
elif resample not in (
Resampling.NEAREST,
Resampling.BILINEAR,
@ -3085,9 +3064,6 @@ def new(
:returns: An :py:class:`~PIL.Image.Image` object.
"""
if mode in ("BGR;15", "BGR;16", "BGR;24"):
deprecate(mode, 12)
_check_size(size)
if color is None:

View File

@ -23,10 +23,9 @@ import operator
import sys
from enum import IntEnum, IntFlag
from functools import reduce
from typing import Any, Literal, SupportsFloat, SupportsInt, Union
from typing import Literal, SupportsFloat, SupportsInt, Union
from . import Image, __version__
from ._deprecate import deprecate
from . import Image
from ._typing import SupportsRead
try:
@ -108,20 +107,6 @@ pyCMS
_VERSION = "1.0.0 pil"
def __getattr__(name: str) -> Any:
if name == "DESCRIPTION":
deprecate("PIL.ImageCms.DESCRIPTION", 12)
return _DESCRIPTION
elif name == "VERSION":
deprecate("PIL.ImageCms.VERSION", 12)
return _VERSION
elif name == "FLAGS":
deprecate("PIL.ImageCms.FLAGS", 12, "PIL.ImageCms.Flags")
return _FLAGS
msg = f"module '{__name__}' has no attribute '{name}'"
raise AttributeError(msg)
# --------------------------------------------------------------------.
@ -301,31 +286,6 @@ class ImageCmsTransform(Image.ImagePointHandler):
proof_intent: Intent = Intent.ABSOLUTE_COLORIMETRIC,
flags: Flags = Flags.NONE,
):
supported_modes = (
"RGB",
"RGBA",
"RGBX",
"CMYK",
"I;16",
"I;16L",
"I;16B",
"YCbCr",
"LAB",
"L",
"1",
)
for mode in (input_mode, output_mode):
if mode not in supported_modes:
deprecate(
mode,
12,
{
"L;16": "I;16 or I;16L",
"L:16B": "I;16B",
"YCCA": "YCbCr",
"YCC": "YCbCr",
}.get(mode),
)
if proof is None:
self.transform = core.buildTransform(
input.profile, output.profile, input_mode, output_mode, intent, flags
@ -1108,16 +1068,3 @@ def isIntentSupported(
return -1
except (AttributeError, OSError, TypeError, ValueError) as v:
raise PyCMSError(v) from v
def versions() -> tuple[str, str | None, str, str]:
"""
(pyCMS) Fetches versions.
"""
deprecate(
"PIL.ImageCms.versions()",
12,
'(PIL.features.version("littlecms2"), sys.version, PIL.__version__)',
)
return _VERSION, core.littlecms_version, sys.version.split()[0], __version__

View File

@ -38,7 +38,6 @@ from types import ModuleType
from typing import Any, AnyStr, Callable, Union, cast
from . import Image, ImageColor
from ._deprecate import deprecate
from ._typing import Coords
# experimental access to the outline API
@ -1009,16 +1008,11 @@ def Draw(im: Image.Image, mode: str | None = None) -> ImageDraw:
return ImageDraw(im, mode)
def getdraw(
im: Image.Image | None = None, hints: list[str] | None = None
) -> tuple[ImageDraw2.Draw | None, ModuleType]:
def getdraw(im: Image.Image | None = None) -> tuple[ImageDraw2.Draw | None, ModuleType]:
"""
:param im: The image to draw in.
:param hints: An optional list of hints. Deprecated.
:returns: A (drawing context, drawing resource factory) tuple.
"""
if hints is not None:
deprecate("'hints' parameter", 12)
from . import ImageDraw2
draw = ImageDraw2.Draw(im) if im is not None else None

View File

@ -37,7 +37,6 @@ import struct
from typing import IO, Any, NamedTuple, cast
from . import ExifTags, Image
from ._deprecate import deprecate
from ._util import DeferredError, is_path
TYPE_CHECKING = False
@ -83,16 +82,6 @@ def _get_oserror(error: int, *, encoder: bool) -> OSError:
return OSError(msg)
def raise_oserror(error: int) -> OSError:
deprecate(
"raise_oserror",
12,
action="It is only useful for translating error codes returned by a codec's "
"decode() method, which ImageFile already does automatically.",
)
raise _get_oserror(error, encoder=False)
def _tilesort(t: _Tile) -> int:
# sort on offset
return t[2]

View File

@ -36,7 +36,7 @@ from io import BytesIO
from types import ModuleType
from typing import IO, Any, BinaryIO, TypedDict, cast
from . import Image, features
from . import Image
from ._typing import StrOrBytesPath
from ._util import DeferredError, is_path
@ -236,21 +236,6 @@ class FreeTypeFont:
self.index = index
self.encoding = encoding
try:
from packaging.version import parse as parse_version
except ImportError:
pass
else:
if freetype_version := features.version_module("freetype2"):
if parse_version(freetype_version) < parse_version("2.9.1"):
warnings.warn(
"Support for FreeType 2.9.0 is deprecated and will be removed "
"in Pillow 12 (2025-10-15). Please upgrade to FreeType 2.9.1 "
"or newer, preferably FreeType 2.10.4 which fixes "
"CVE-2020-15999.",
DeprecationWarning,
)
if layout_engine not in (Layout.BASIC, Layout.RAQM):
layout_engine = Layout.BASIC
if core.HAVE_RAQM:

View File

@ -21,7 +21,6 @@ from types import CodeType
from typing import Any, Callable
from . import Image, _imagingmath
from ._deprecate import deprecate
class _Operand:
@ -233,11 +232,7 @@ ops = {
}
def lambda_eval(
expression: Callable[[dict[str, Any]], Any],
options: dict[str, Any] = {},
**kw: Any,
) -> Any:
def lambda_eval(expression: Callable[[dict[str, Any]], Any], **kw: Any) -> Any:
"""
Returns the result of an image function.
@ -246,23 +241,13 @@ def lambda_eval(
:py:func:`~PIL.Image.merge` function.
:param expression: A function that receives a dictionary.
:param options: Values to add to the function's dictionary. Deprecated.
You can instead use one or more keyword arguments.
:param **kw: Values to add to the function's dictionary.
:return: The expression result. This is usually an image object, but can
also be an integer, a floating point value, or a pixel tuple,
depending on the expression.
"""
if options:
deprecate(
"ImageMath.lambda_eval options",
12,
"ImageMath.lambda_eval keyword arguments",
)
args: dict[str, Any] = ops.copy()
args.update(options)
args.update(kw)
for k, v in args.items():
if isinstance(v, Image.Image):
@ -275,11 +260,7 @@ def lambda_eval(
return out
def unsafe_eval(
expression: str,
options: dict[str, Any] = {},
**kw: Any,
) -> Any:
def unsafe_eval(expression: str, **kw: Any) -> Any:
"""
Evaluates an image expression. This uses Python's ``eval()`` function to process
the expression string, and carries the security risks of doing so. It is not
@ -291,29 +272,19 @@ def unsafe_eval(
:py:func:`~PIL.Image.merge` function.
:param expression: A string containing a Python-style expression.
:param options: Values to add to the evaluation context. Deprecated.
You can instead use one or more keyword arguments.
:param **kw: Values to add to the evaluation context.
:return: The evaluated expression. This is usually an image object, but can
also be an integer, a floating point value, or a pixel tuple,
depending on the expression.
"""
if options:
deprecate(
"ImageMath.unsafe_eval options",
12,
"ImageMath.unsafe_eval keyword arguments",
)
# build execution namespace
args: dict[str, Any] = ops.copy()
for k in [*options, *kw]:
for k in kw:
if "__" in k or hasattr(builtins, k):
msg = f"'{k}' not allowed"
raise ValueError(msg)
args.update(options)
args.update(kw)
for k, v in args.items():
if isinstance(v, Image.Image):
@ -337,32 +308,3 @@ def unsafe_eval(
return out.im
except AttributeError:
return out
def eval(
expression: str,
_dict: dict[str, Any] = {},
**kw: Any,
) -> Any:
"""
Evaluates an image expression.
Deprecated. Use lambda_eval() or unsafe_eval() instead.
:param expression: A string containing a Python-style expression.
:param _dict: Values to add to the evaluation context. You
can either use a dictionary, or one or more keyword
arguments.
:return: The evaluated expression. This is usually an image object, but can
also be an integer, a floating point value, or a pixel tuple,
depending on the expression.
.. deprecated:: 10.3.0
"""
deprecate(
"ImageMath.eval",
12,
"ImageMath.lambda_eval or ImageMath.unsafe_eval",
)
return unsafe_eval(expression, _dict, **kw)

View File

@ -18,8 +18,6 @@ import sys
from functools import lru_cache
from typing import NamedTuple
from ._deprecate import deprecate
class ModeDescriptor(NamedTuple):
"""Wrapper for mode strings."""
@ -57,16 +55,11 @@ def getmode(mode: str) -> ModeDescriptor:
"HSV": ("RGB", "L", ("H", "S", "V"), "|u1"),
# extra experimental modes
"RGBa": ("RGB", "L", ("R", "G", "B", "a"), "|u1"),
"BGR;15": ("RGB", "L", ("B", "G", "R"), "|u1"),
"BGR;16": ("RGB", "L", ("B", "G", "R"), "|u1"),
"BGR;24": ("RGB", "L", ("B", "G", "R"), "|u1"),
"LA": ("L", "L", ("L", "A"), "|u1"),
"La": ("L", "L", ("L", "a"), "|u1"),
"PA": ("RGB", "L", ("P", "A"), "|u1"),
}
if mode in modes:
if mode in ("BGR;15", "BGR;16", "BGR;24"):
deprecate(mode, 12)
base_mode, base_type, bands, type_str = modes[mode]
return ModeDescriptor(mode, bands, base_mode, base_type, type_str)

View File

@ -16,26 +16,16 @@
#
from __future__ import annotations
from collections.abc import Sequence
from io import BytesIO
from typing import cast
from . import Image, ImageFile
from ._binary import i16be as i16
from ._binary import i32be as i32
from ._deprecate import deprecate
COMPRESSION = {1: "raw", 5: "jpeg"}
def __getattr__(name: str) -> bytes:
if name == "PAD":
deprecate("IptcImagePlugin.PAD", 12)
return b"\0\0\0\0"
msg = f"module '{__name__}' has no attribute '{name}'"
raise AttributeError(msg)
#
# Helpers
@ -48,20 +38,6 @@ def _i8(c: int | bytes) -> int:
return c if isinstance(c, int) else c[0]
def i(c: bytes) -> int:
""".. deprecated:: 10.2.0"""
deprecate("IptcImagePlugin.i", 12)
return _i(c)
def dump(c: Sequence[int | bytes]) -> None:
""".. deprecated:: 10.2.0"""
deprecate("IptcImagePlugin.dump", 12)
for i in c:
print(f"{_i8(i):02x}", end=" ")
print()
##
# Image plugin for IPTC/NAA datastreams. To read IPTC/NAA fields
# from TIFF and JPEG files, use the <b>getiptcinfo</b> function.

View File

@ -49,7 +49,6 @@ from ._binary import i16be as i16
from ._binary import i32be as i32
from ._binary import o8
from ._binary import o16be as o16
from ._deprecate import deprecate
from .JpegPresets import presets
TYPE_CHECKING = False
@ -393,12 +392,6 @@ class JpegImageFile(ImageFile.ImageFile):
self._read_dpi_from_exif()
def __getattr__(self, name: str) -> Any:
if name in ("huffman_ac", "huffman_dc"):
deprecate(name, 12)
return getattr(self, "_" + name)
raise AttributeError(name)
def __getstate__(self) -> list[Any]:
return super().__getstate__() + [self.layers, self.layer]

View File

@ -56,7 +56,6 @@ from . import ExifTags, Image, ImageFile, ImageOps, ImagePalette, TiffTags
from ._binary import i16be as i16
from ._binary import i32be as i32
from ._binary import o8
from ._deprecate import deprecate
from ._typing import StrOrBytesPath
from ._util import DeferredError, is_path
from .TiffTags import TYPES
@ -284,9 +283,6 @@ PREFIXES = [
b"II\x2b\x00", # BigTIFF with little-endian byte order
]
if not getattr(Image.core, "libtiff_support_custom_tags", True):
deprecate("Support for LibTIFF earlier than version 4", 12)
def _accept(prefix: bytes) -> bool:
return prefix.startswith(tuple(PREFIXES))
@ -1934,9 +1930,6 @@ def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None:
# Custom items are supported for int, float, unicode, string and byte
# values. Other types and tuples require a tagtype.
if tag not in TiffTags.LIBTIFF_CORE:
if not getattr(Image.core, "libtiff_support_custom_tags", False):
continue
if tag in TiffTags.TAGS_V2_GROUPS:
types[tag] = TiffTags.LONG8
elif tag in ifd.tagtype:

View File

@ -46,8 +46,6 @@ def deprecate(
elif when <= int(__version__.split(".")[0]):
msg = f"{deprecated} {is_} deprecated and should be removed."
raise RuntimeError(msg)
elif when == 12:
removed = "Pillow 12 (2025-10-15)"
elif when == 13:
removed = "Pillow 13 (2026-10-15)"
else:

View File

@ -121,9 +121,6 @@ def get_supported_codecs() -> list[str]:
features: dict[str, tuple[str, str | bool, str | None]] = {
"webp_anim": ("PIL._webp", True, None),
"webp_mux": ("PIL._webp", True, None),
"transp_webp": ("PIL._webp", True, None),
"raqm": ("PIL._imagingft", "HAVE_RAQM", "raqm_version"),
"fribidi": ("PIL._imagingft", "HAVE_FRIBIDI", "fribidi_version"),
"harfbuzz": ("PIL._imagingft", "HAVE_HARFBUZZ", "harfbuzz_version"),

View File

@ -681,30 +681,6 @@ getink(PyObject *color, Imaging im, char *ink) {
} else if (!PyArg_ParseTuple(color, "iiL", &b, &g, &r)) {
return NULL;
}
if (!strcmp(im->mode, "BGR;15")) {
UINT16 v = ((((UINT16)r) << 7) & 0x7c00) +
((((UINT16)g) << 2) & 0x03e0) +
((((UINT16)b) >> 3) & 0x001f);
ink[0] = (UINT8)v;
ink[1] = (UINT8)(v >> 8);
ink[2] = ink[3] = 0;
return ink;
} else if (!strcmp(im->mode, "BGR;16")) {
UINT16 v = ((((UINT16)r) << 8) & 0xf800) +
((((UINT16)g) << 3) & 0x07e0) +
((((UINT16)b) >> 3) & 0x001f);
ink[0] = (UINT8)v;
ink[1] = (UINT8)(v >> 8);
ink[2] = ink[3] = 0;
return ink;
} else if (!strcmp(im->mode, "BGR;24")) {
ink[0] = (UINT8)b;
ink[1] = (UINT8)g;
ink[2] = (UINT8)r;
ink[3] = 0;
return ink;
}
}
}
@ -1650,54 +1626,33 @@ _putdata(ImagingObject *self, PyObject *args) {
return NULL;
}
double value;
if (image->bands == 1) {
int bigendian = 0;
if (image->type == IMAGING_TYPE_SPECIAL) {
// I;16*
if (
strcmp(image->mode, "I;16B") == 0
int bigendian = 0;
if (image->type == IMAGING_TYPE_SPECIAL) {
// I;16*
if (
strcmp(image->mode, "I;16B") == 0
#ifdef WORDS_BIGENDIAN
|| strcmp(image->mode, "I;16N") == 0
|| strcmp(image->mode, "I;16N") == 0
#endif
) {
bigendian = 1;
}
) {
bigendian = 1;
}
for (i = x = y = 0; i < n; i++) {
set_value_to_item(seq, i);
if (scale != 1.0 || offset != 0.0) {
value = value * scale + offset;
}
if (image->type == IMAGING_TYPE_SPECIAL) {
image->image8[y][x * 2 + (bigendian ? 1 : 0)] =
CLIP8((int)value % 256);
image->image8[y][x * 2 + (bigendian ? 0 : 1)] =
CLIP8((int)value >> 8);
} else {
image->image8[y][x] = (UINT8)CLIP8(value);
}
if (++x >= (int)image->xsize) {
x = 0, y++;
}
}
for (i = x = y = 0; i < n; i++) {
set_value_to_item(seq, i);
if (scale != 1.0 || offset != 0.0) {
value = value * scale + offset;
}
} else {
// BGR;*
int b;
for (i = x = y = 0; i < n; i++) {
char ink[4];
op = PySequence_Fast_GET_ITEM(seq, i);
if (!op || !getink(op, image, ink)) {
Py_DECREF(seq);
return NULL;
}
/* FIXME: what about scale and offset? */
for (b = 0; b < image->pixelsize; b++) {
image->image8[y][x * image->pixelsize + b] = ink[b];
}
if (++x >= (int)image->xsize) {
x = 0, y++;
}
if (image->type == IMAGING_TYPE_SPECIAL) {
image->image8[y][x * 2 + (bigendian ? 1 : 0)] =
CLIP8((int)value % 256);
image->image8[y][x * 2 + (bigendian ? 0 : 1)] =
CLIP8((int)value >> 8);
} else {
image->image8[y][x] = (UINT8)CLIP8(value);
}
if (++x >= (int)image->xsize) {
x = 0, y++;
}
}
PyErr_Clear(); /* Avoid weird exceptions */
@ -3769,18 +3724,6 @@ _getattr_bands(ImagingObject *self, void *closure) {
return PyLong_FromLong(self->image->bands);
}
static PyObject *
_getattr_id(ImagingObject *self, void *closure) {
if (PyErr_WarnEx(
PyExc_DeprecationWarning,
"id property is deprecated and will be removed in Pillow 12 (2025-10-15)",
1
) < 0) {
return NULL;
}
return PyLong_FromSsize_t((Py_ssize_t)self->image);
}
static void
_ptr_destructor(PyObject *capsule) {
PyObject *self = (PyObject *)PyCapsule_GetContext(capsule);
@ -3795,27 +3738,6 @@ _getattr_ptr(ImagingObject *self, void *closure) {
return capsule;
}
static PyObject *
_getattr_unsafe_ptrs(ImagingObject *self, void *closure) {
if (PyErr_WarnEx(
PyExc_DeprecationWarning,
"unsafe_ptrs property is deprecated and will be removed in Pillow 12 "
"(2025-10-15)",
1
) < 0) {
return NULL;
}
return Py_BuildValue(
"(sn)(sn)(sn)",
"image8",
self->image->image8,
"image32",
self->image->image32,
"image",
self->image->image
);
}
static PyObject *
_getattr_readonly(ImagingObject *self, void *closure) {
return PyLong_FromLong(self->image->read_only);
@ -3825,9 +3747,7 @@ static struct PyGetSetDef getsetters[] = {
{"mode", (getter)_getattr_mode},
{"size", (getter)_getattr_size},
{"bands", (getter)_getattr_bands},
{"id", (getter)_getattr_id},
{"ptr", (getter)_getattr_ptr},
{"unsafe_ptrs", (getter)_getattr_unsafe_ptrs},
{"readonly", (getter)_getattr_readonly},
{NULL}
};
@ -4432,16 +4352,6 @@ setup_module(PyObject *m) {
PyObject *v = PyUnicode_FromString(ImagingTiffVersion());
PyDict_SetItemString(d, "libtiff_version", v ? v : Py_None);
Py_XDECREF(v);
// Test for libtiff 4.0 or later, excluding libtiff 3.9.6 and 3.9.7
PyObject *support_custom_tags;
#if TIFFLIB_VERSION >= 20111221 && TIFFLIB_VERSION != 20120218 && \
TIFFLIB_VERSION != 20120922
support_custom_tags = Py_True;
#else
support_custom_tags = Py_False;
#endif
PyDict_SetItemString(d, "libtiff_support_custom_tags", support_custom_tags);
}
#endif

View File

@ -82,31 +82,6 @@ get_pixel_16B(Imaging im, int x, int y, void *color) {
#endif
}
static void
get_pixel_BGR15(Imaging im, int x, int y, void *color) {
UINT8 *in = (UINT8 *)&im->image8[y][x * 2];
UINT16 pixel = in[0] + (in[1] << 8);
char *out = color;
out[0] = (pixel & 31) * 255 / 31;
out[1] = ((pixel >> 5) & 31) * 255 / 31;
out[2] = ((pixel >> 10) & 31) * 255 / 31;
}
static void
get_pixel_BGR16(Imaging im, int x, int y, void *color) {
UINT8 *in = (UINT8 *)&im->image8[y][x * 2];
UINT16 pixel = in[0] + (in[1] << 8);
char *out = color;
out[0] = (pixel & 31) * 255 / 31;
out[1] = ((pixel >> 5) & 63) * 255 / 63;
out[2] = ((pixel >> 11) & 31) * 255 / 31;
}
static void
get_pixel_BGR24(Imaging im, int x, int y, void *color) {
memcpy(color, &im->image8[y][x * 3], sizeof(UINT8) * 3);
}
static void
get_pixel_32(Imaging im, int x, int y, void *color) {
memcpy(color, &im->image32[y][x], sizeof(INT32));
@ -154,16 +129,6 @@ put_pixel_16B(Imaging im, int x, int y, const void *color) {
out[1] = in[0];
}
static void
put_pixel_BGR1516(Imaging im, int x, int y, const void *color) {
memcpy(&im->image8[y][x * 2], color, 2);
}
static void
put_pixel_BGR24(Imaging im, int x, int y, const void *color) {
memcpy(&im->image8[y][x * 3], color, 3);
}
static void
put_pixel_32L(Imaging im, int x, int y, const void *color) {
memcpy(&im->image8[y][x * 4], color, 4);
@ -212,9 +177,6 @@ ImagingAccessInit(void) {
ADD("F", get_pixel_32, put_pixel_32);
ADD("P", get_pixel_8, put_pixel_8);
ADD("PA", get_pixel_32_2bands, put_pixel_32);
ADD("BGR;15", get_pixel_BGR15, put_pixel_BGR1516);
ADD("BGR;16", get_pixel_BGR16, put_pixel_BGR1516);
ADD("BGR;24", get_pixel_BGR24, put_pixel_BGR24);
ADD("RGB", get_pixel_32, put_pixel_32);
ADD("RGBA", get_pixel_32, put_pixel_32);
ADD("RGBa", get_pixel_32, put_pixel_32);

View File

@ -277,38 +277,6 @@ rgb2f(UINT8 *out_, const UINT8 *in, int xsize) {
}
}
static void
rgb2bgr15(UINT8 *out_, const UINT8 *in, int xsize) {
int x;
for (x = 0; x < xsize; x++, in += 4, out_ += 2) {
UINT16 v = ((((UINT16)in[0]) << 7) & 0x7c00) +
((((UINT16)in[1]) << 2) & 0x03e0) +
((((UINT16)in[2]) >> 3) & 0x001f);
memcpy(out_, &v, sizeof(v));
}
}
static void
rgb2bgr16(UINT8 *out_, const UINT8 *in, int xsize) {
int x;
for (x = 0; x < xsize; x++, in += 4, out_ += 2) {
UINT16 v = ((((UINT16)in[0]) << 8) & 0xf800) +
((((UINT16)in[1]) << 3) & 0x07e0) +
((((UINT16)in[2]) >> 3) & 0x001f);
memcpy(out_, &v, sizeof(v));
}
}
static void
rgb2bgr24(UINT8 *out, const UINT8 *in, int xsize) {
int x;
for (x = 0; x < xsize; x++, in += 4) {
*out++ = in[2];
*out++ = in[1];
*out++ = in[0];
}
}
static void
rgb2hsv_row(UINT8 *out, const UINT8 *in) { // following colorsys.py
float h, s, rc, gc, bc, cr;
@ -971,9 +939,6 @@ static struct {
{"RGB", "I;16N", rgb2i16l},
#endif
{"RGB", "F", rgb2f},
{"RGB", "BGR;15", rgb2bgr15},
{"RGB", "BGR;16", rgb2bgr16},
{"RGB", "BGR;24", rgb2bgr24},
{"RGB", "RGBA", rgb2rgba},
{"RGB", "RGBa", rgb2rgba},
{"RGB", "RGBX", rgb2rgba},

View File

@ -471,12 +471,6 @@ copy2(UINT8 *out, const UINT8 *in, int pixels) {
memcpy(out, in, pixels * 2);
}
static void
copy3(UINT8 *out, const UINT8 *in, int pixels) {
/* BGR;24, etc */
memcpy(out, in, pixels * 3);
}
static void
copy4(UINT8 *out, const UINT8 *in, int pixels) {
/* RGBA, CMYK quadruples */
@ -657,9 +651,6 @@ static struct {
{"I;16", "I;16N", 16, packI16N_I16}, // LibTiff native->image endian.
{"I;16L", "I;16N", 16, packI16N_I16},
{"I;16B", "I;16N", 16, packI16N_I16B},
{"BGR;15", "BGR;15", 16, copy2},
{"BGR;16", "BGR;16", 16, copy2},
{"BGR;24", "BGR;24", 24, copy3},
{NULL} /* sentinel */
};

View File

@ -151,36 +151,6 @@ ImagingNewPrologueSubtype(const char *mode, int xsize, int ysize, int size) {
strcpy(im->band_names[2], "B");
strcpy(im->band_names[3], "X");
} else if (strcmp(mode, "BGR;15") == 0) {
/* EXPERIMENTAL */
/* 15-bit reversed true colour */
im->bands = 3;
im->pixelsize = 2;
im->linesize = (xsize * 2 + 3) & -4;
im->type = IMAGING_TYPE_SPECIAL;
/* not allowing arrow due to line length packing */
strcpy(im->arrow_band_format, "");
} else if (strcmp(mode, "BGR;16") == 0) {
/* EXPERIMENTAL */
/* 16-bit reversed true colour */
im->bands = 3;
im->pixelsize = 2;
im->linesize = (xsize * 2 + 3) & -4;
im->type = IMAGING_TYPE_SPECIAL;
/* not allowing arrow due to line length packing */
strcpy(im->arrow_band_format, "");
} else if (strcmp(mode, "BGR;24") == 0) {
/* EXPERIMENTAL */
/* 24-bit reversed true colour */
im->bands = 3;
im->pixelsize = 3;
im->linesize = (xsize * 3 + 3) & -4;
im->type = IMAGING_TYPE_SPECIAL;
/* not allowing arrow due to line length packing */
strcpy(im->arrow_band_format, "");
} else if (strcmp(mode, "RGBX") == 0) {
/* 32-bit true colour images with padding */
im->bands = im->pixelsize = 4;

View File

@ -884,7 +884,6 @@ ImagingLibTiffMergeFieldInfo(
// Refer to libtiff docs (http://www.simplesystems.org/libtiff/addingtags.html)
TIFFSTATE *clientstate = (TIFFSTATE *)state->context;
uint32_t n;
int status = 0;
// custom fields added with ImagingLibTiffMergeFieldInfo are only used for
// decoding, ignore readcount;
@ -907,14 +906,7 @@ ImagingLibTiffMergeFieldInfo(
n = sizeof(info) / sizeof(info[0]);
// Test for libtiff 4.0 or later, excluding libtiff 3.9.6 and 3.9.7
#if TIFFLIB_VERSION >= 20111221 && TIFFLIB_VERSION != 20120218 && \
TIFFLIB_VERSION != 20120922
status = TIFFMergeFieldInfo(clientstate->tiff, info, n);
#else
TIFFMergeFieldInfo(clientstate->tiff, info, n);
#endif
return status;
return TIFFMergeFieldInfo(clientstate->tiff, info, n);
}
int

View File

@ -1284,12 +1284,6 @@ copy2(UINT8 *out, const UINT8 *in, int pixels) {
memcpy(out, in, pixels * 2);
}
static void
copy3(UINT8 *out, const UINT8 *in, int pixels) {
/* BGR;24 */
memcpy(out, in, pixels * 3);
}
static void
copy4(UINT8 *out, const UINT8 *in, int pixels) {
/* RGBA, CMYK quadruples */
@ -1649,10 +1643,6 @@ static struct {
{"RGB", "B;16B", 16, band216B},
{"RGB", "CMYK", 32, cmyk2rgb},
{"BGR;15", "BGR;15", 16, copy2},
{"BGR;16", "BGR;16", 16, copy2},
{"BGR;24", "BGR;24", 24, copy3},
/* true colour w. alpha */
{"RGBA", "LA", 16, unpackRGBALA},
{"RGBA", "LA;16B", 32, unpackRGBALA16B},