mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-02-11 17:10:58 +03:00
Merge branch 'main' into libavif-plugin
This commit is contained in:
commit
9b6e575fd6
2
.github/workflows/wheels-dependencies.sh
vendored
2
.github/workflows/wheels-dependencies.sh
vendored
|
@ -95,7 +95,7 @@ function build_harfbuzz {
|
||||||
if [ -e harfbuzz-stamp ]; then return; fi
|
if [ -e harfbuzz-stamp ]; then return; fi
|
||||||
python3 -m pip install meson ninja
|
python3 -m pip install meson ninja
|
||||||
|
|
||||||
local out_dir=$(fetch_unpack https://github.com/harfbuzz/harfbuzz/releases/download/$HARFBUZZ_VERSION/$HARFBUZZ_VERSION.tar.xz harfbuzz-$HARFBUZZ_VERSION.tar.xz)
|
local out_dir=$(fetch_unpack https://github.com/harfbuzz/harfbuzz/releases/download/$HARFBUZZ_VERSION/harfbuzz-$HARFBUZZ_VERSION.tar.xz harfbuzz-$HARFBUZZ_VERSION.tar.xz)
|
||||||
(cd $out_dir \
|
(cd $out_dir \
|
||||||
&& meson setup build --prefix=$BUILD_PREFIX --libdir=$BUILD_PREFIX/lib --buildtype=release -Dfreetype=enabled -Dglib=disabled)
|
&& meson setup build --prefix=$BUILD_PREFIX --libdir=$BUILD_PREFIX/lib --buildtype=release -Dfreetype=enabled -Dglib=disabled)
|
||||||
(cd $out_dir/build \
|
(cd $out_dir/build \
|
||||||
|
|
|
@ -4,6 +4,7 @@ import warnings
|
||||||
from collections.abc import Generator
|
from collections.abc import Generator
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
@ -1435,7 +1436,8 @@ def test_saving_rgba(tmp_path: Path) -> None:
|
||||||
assert reloaded_rgba.load()[0, 0][3] == 0
|
assert reloaded_rgba.load()[0, 0][3] == 0
|
||||||
|
|
||||||
|
|
||||||
def test_optimizing_p_rgba(tmp_path: Path) -> None:
|
@pytest.mark.parametrize("params", ({}, {"disposal": 2, "optimize": False}))
|
||||||
|
def test_p_rgba(tmp_path: Path, params: dict[str, Any]) -> None:
|
||||||
out = str(tmp_path / "temp.gif")
|
out = str(tmp_path / "temp.gif")
|
||||||
|
|
||||||
im1 = Image.new("P", (100, 100))
|
im1 = Image.new("P", (100, 100))
|
||||||
|
@ -1447,7 +1449,7 @@ def test_optimizing_p_rgba(tmp_path: Path) -> None:
|
||||||
im2 = Image.new("P", (100, 100))
|
im2 = Image.new("P", (100, 100))
|
||||||
im2.putpalette(data, "RGBA")
|
im2.putpalette(data, "RGBA")
|
||||||
|
|
||||||
im1.save(out, save_all=True, append_images=[im2])
|
im1.save(out, save_all=True, append_images=[im2], **params)
|
||||||
|
|
||||||
with Image.open(out) as reloaded:
|
with Image.open(out) as reloaded:
|
||||||
assert reloaded.n_frames == 2
|
assert reloaded.n_frames == 2
|
||||||
|
|
59
docs/releasenotes/11.1.0.rst
Normal file
59
docs/releasenotes/11.1.0.rst
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
11.1.0
|
||||||
|
------
|
||||||
|
|
||||||
|
Security
|
||||||
|
========
|
||||||
|
|
||||||
|
TODO
|
||||||
|
^^^^
|
||||||
|
|
||||||
|
TODO
|
||||||
|
|
||||||
|
:cve:`YYYY-XXXXX`: TODO
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
TODO
|
||||||
|
|
||||||
|
Backwards Incompatible Changes
|
||||||
|
==============================
|
||||||
|
|
||||||
|
TODO
|
||||||
|
^^^^
|
||||||
|
|
||||||
|
Deprecations
|
||||||
|
============
|
||||||
|
|
||||||
|
TODO
|
||||||
|
^^^^
|
||||||
|
|
||||||
|
TODO
|
||||||
|
|
||||||
|
API Changes
|
||||||
|
===========
|
||||||
|
|
||||||
|
TODO
|
||||||
|
^^^^
|
||||||
|
|
||||||
|
TODO
|
||||||
|
|
||||||
|
API Additions
|
||||||
|
=============
|
||||||
|
|
||||||
|
Check for zlib-ng
|
||||||
|
^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
You can check if Pillow has been built against the zlib-ng version of the
|
||||||
|
zlib library, and what version of zlib-ng is being used::
|
||||||
|
|
||||||
|
from PIL import features
|
||||||
|
features.check_feature("zlib_ng") # True or False
|
||||||
|
features.version_feature("zlib_ng") # "2.2.2" for example, or None
|
||||||
|
|
||||||
|
Other Changes
|
||||||
|
=============
|
||||||
|
|
||||||
|
zlib-ng in wheels
|
||||||
|
^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Wheels are now built against zlib-ng for improved speed. In tests, saving a PNG
|
||||||
|
was found to be more than twice as fast at higher compression levels.
|
|
@ -14,6 +14,7 @@ expected to be backported to earlier versions.
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 2
|
:maxdepth: 2
|
||||||
|
|
||||||
|
11.1.0
|
||||||
11.0.0
|
11.0.0
|
||||||
10.4.0
|
10.4.0
|
||||||
10.3.0
|
10.3.0
|
||||||
|
|
|
@ -695,8 +695,9 @@ def _write_multiple_frames(
|
||||||
)
|
)
|
||||||
background = _get_background(im_frame, color)
|
background = _get_background(im_frame, color)
|
||||||
background_im = Image.new("P", im_frame.size, background)
|
background_im = Image.new("P", im_frame.size, background)
|
||||||
assert im_frames[0].im.palette is not None
|
first_palette = im_frames[0].im.palette
|
||||||
background_im.putpalette(im_frames[0].im.palette)
|
assert first_palette is not None
|
||||||
|
background_im.putpalette(first_palette, first_palette.mode)
|
||||||
bbox = _getbbox(background_im, im_frame)[1]
|
bbox = _getbbox(background_im, im_frame)[1]
|
||||||
elif encoderinfo.get("optimize") and im_frame.mode != "1":
|
elif encoderinfo.get("optimize") and im_frame.mode != "1":
|
||||||
if "transparency" not in encoderinfo:
|
if "transparency" not in encoderinfo:
|
||||||
|
|
|
@ -935,8 +935,8 @@ class ImageFileDirectory_v2(_IFDv2Base):
|
||||||
self._tagdata[tag] = data
|
self._tagdata[tag] = data
|
||||||
self.tagtype[tag] = typ
|
self.tagtype[tag] = typ
|
||||||
|
|
||||||
bytes_value = size if size > 32 else repr(data)
|
msg += " - value: "
|
||||||
msg += f" - value: <table: {bytes_value} bytes>"
|
msg += f"<table: {size} bytes>" if size > 32 else repr(data)
|
||||||
|
|
||||||
logger.debug(msg)
|
logger.debug(msg)
|
||||||
|
|
||||||
|
@ -981,11 +981,8 @@ class ImageFileDirectory_v2(_IFDv2Base):
|
||||||
|
|
||||||
tagname = TiffTags.lookup(tag, self.group).name
|
tagname = TiffTags.lookup(tag, self.group).name
|
||||||
typname = "ifd" if is_ifd else TYPES.get(typ, "unknown")
|
typname = "ifd" if is_ifd else TYPES.get(typ, "unknown")
|
||||||
bytes_value = len(data) if len(data) >= 16 else str(values)
|
msg = f"save: {tagname} ({tag}) - type: {typname} ({typ}) - value: "
|
||||||
msg = (
|
msg += f"<table: {len(data)} bytes>" if len(data) >= 16 else str(values)
|
||||||
f"save: {tagname} ({tag}) - type: {typname} ({typ})"
|
|
||||||
f" - value: <table: {bytes_value} bytes>"
|
|
||||||
)
|
|
||||||
logger.debug(msg)
|
logger.debug(msg)
|
||||||
|
|
||||||
# count is sum of lengths for string and arbitrary data
|
# count is sum of lengths for string and arbitrary data
|
||||||
|
|
|
@ -131,9 +131,8 @@ V["LIBPNG_XY"] = "".join(V["LIBPNG"].split(".")[:2])
|
||||||
# dependencies, listed in order of compilation
|
# dependencies, listed in order of compilation
|
||||||
DEPS: dict[str, dict[str, Any]] = {
|
DEPS: dict[str, dict[str, Any]] = {
|
||||||
"libjpeg": {
|
"libjpeg": {
|
||||||
"url": f"{SF_PROJECTS}/libjpeg-turbo/files/{V['JPEGTURBO']}/FILENAME/download",
|
"url": f"https://github.com/libjpeg-turbo/libjpeg-turbo/releases/download/{V['JPEGTURBO']}/libjpeg-turbo-{V['JPEGTURBO']}.tar.gz",
|
||||||
"filename": f"libjpeg-turbo-{V['JPEGTURBO']}.tar.gz",
|
"filename": f"libjpeg-turbo-{V['JPEGTURBO']}.tar.gz",
|
||||||
"dir": f"libjpeg-turbo-{V['JPEGTURBO']}",
|
|
||||||
"license": ["README.ijg", "LICENSE.md"],
|
"license": ["README.ijg", "LICENSE.md"],
|
||||||
"license_pattern": (
|
"license_pattern": (
|
||||||
"(LEGAL ISSUES\n============\n\n.+?)\n\nREFERENCES\n=========="
|
"(LEGAL ISSUES\n============\n\n.+?)\n\nREFERENCES\n=========="
|
||||||
|
@ -161,9 +160,8 @@ DEPS: dict[str, dict[str, Any]] = {
|
||||||
"bins": ["cjpeg.exe", "djpeg.exe"],
|
"bins": ["cjpeg.exe", "djpeg.exe"],
|
||||||
},
|
},
|
||||||
"zlib": {
|
"zlib": {
|
||||||
"url": f"https://github.com/zlib-ng/zlib-ng/archive/refs/tags/{V['ZLIBNG']}.zip",
|
"url": f"https://github.com/zlib-ng/zlib-ng/archive/refs/tags/{V['ZLIBNG']}.tar.gz",
|
||||||
"filename": f"zlib-ng-{V['ZLIBNG']}.zip",
|
"filename": f"zlib-ng-{V['ZLIBNG']}.tar.gz",
|
||||||
"dir": f"zlib-ng-{V['ZLIBNG']}",
|
|
||||||
"license": "LICENSE.md",
|
"license": "LICENSE.md",
|
||||||
"patch": {
|
"patch": {
|
||||||
r"CMakeLists.txt": {
|
r"CMakeLists.txt": {
|
||||||
|
@ -181,7 +179,6 @@ DEPS: dict[str, dict[str, Any]] = {
|
||||||
"xz": {
|
"xz": {
|
||||||
"url": f"https://github.com/tukaani-project/xz/releases/download/v{V['XZ']}/FILENAME",
|
"url": f"https://github.com/tukaani-project/xz/releases/download/v{V['XZ']}/FILENAME",
|
||||||
"filename": f"xz-{V['XZ']}.tar.gz",
|
"filename": f"xz-{V['XZ']}.tar.gz",
|
||||||
"dir": f"xz-{V['XZ']}",
|
|
||||||
"license": "COPYING",
|
"license": "COPYING",
|
||||||
"build": [
|
"build": [
|
||||||
*cmds_cmake("liblzma", "-DBUILD_SHARED_LIBS:BOOL=OFF"),
|
*cmds_cmake("liblzma", "-DBUILD_SHARED_LIBS:BOOL=OFF"),
|
||||||
|
@ -194,7 +191,6 @@ DEPS: dict[str, dict[str, Any]] = {
|
||||||
"libwebp": {
|
"libwebp": {
|
||||||
"url": "http://downloads.webmproject.org/releases/webp/FILENAME",
|
"url": "http://downloads.webmproject.org/releases/webp/FILENAME",
|
||||||
"filename": f"libwebp-{V['LIBWEBP']}.tar.gz",
|
"filename": f"libwebp-{V['LIBWEBP']}.tar.gz",
|
||||||
"dir": f"libwebp-{V['LIBWEBP']}",
|
|
||||||
"license": "COPYING",
|
"license": "COPYING",
|
||||||
"patch": {
|
"patch": {
|
||||||
r"src\enc\picture_csp_enc.c": {
|
r"src\enc\picture_csp_enc.c": {
|
||||||
|
@ -216,7 +212,6 @@ DEPS: dict[str, dict[str, Any]] = {
|
||||||
"libtiff": {
|
"libtiff": {
|
||||||
"url": "https://download.osgeo.org/libtiff/FILENAME",
|
"url": "https://download.osgeo.org/libtiff/FILENAME",
|
||||||
"filename": f"tiff-{V['TIFF']}.tar.gz",
|
"filename": f"tiff-{V['TIFF']}.tar.gz",
|
||||||
"dir": f"tiff-{V['TIFF']}",
|
|
||||||
"license": "LICENSE.md",
|
"license": "LICENSE.md",
|
||||||
"patch": {
|
"patch": {
|
||||||
r"libtiff\tif_lzma.c": {
|
r"libtiff\tif_lzma.c": {
|
||||||
|
@ -249,7 +244,6 @@ DEPS: dict[str, dict[str, Any]] = {
|
||||||
"url": f"{SF_PROJECTS}/libpng/files/libpng{V['LIBPNG_XY']}/{V['LIBPNG']}/"
|
"url": f"{SF_PROJECTS}/libpng/files/libpng{V['LIBPNG_XY']}/{V['LIBPNG']}/"
|
||||||
f"lpng{V['LIBPNG_DOTLESS']}.zip/download",
|
f"lpng{V['LIBPNG_DOTLESS']}.zip/download",
|
||||||
"filename": f"lpng{V['LIBPNG_DOTLESS']}.zip",
|
"filename": f"lpng{V['LIBPNG_DOTLESS']}.zip",
|
||||||
"dir": f"lpng{V['LIBPNG_DOTLESS']}",
|
|
||||||
"license": "LICENSE",
|
"license": "LICENSE",
|
||||||
"build": [
|
"build": [
|
||||||
*cmds_cmake("png_static", "-DPNG_SHARED:BOOL=OFF", "-DPNG_TESTS:BOOL=OFF"),
|
*cmds_cmake("png_static", "-DPNG_SHARED:BOOL=OFF", "-DPNG_TESTS:BOOL=OFF"),
|
||||||
|
@ -263,7 +257,6 @@ DEPS: dict[str, dict[str, Any]] = {
|
||||||
"brotli": {
|
"brotli": {
|
||||||
"url": f"https://github.com/google/brotli/archive/refs/tags/v{V['BROTLI']}.tar.gz",
|
"url": f"https://github.com/google/brotli/archive/refs/tags/v{V['BROTLI']}.tar.gz",
|
||||||
"filename": f"brotli-{V['BROTLI']}.tar.gz",
|
"filename": f"brotli-{V['BROTLI']}.tar.gz",
|
||||||
"dir": f"brotli-{V['BROTLI']}",
|
|
||||||
"license": "LICENSE",
|
"license": "LICENSE",
|
||||||
"build": [
|
"build": [
|
||||||
*cmds_cmake(("brotlicommon", "brotlidec"), "-DBUILD_SHARED_LIBS:BOOL=OFF"),
|
*cmds_cmake(("brotlicommon", "brotlidec"), "-DBUILD_SHARED_LIBS:BOOL=OFF"),
|
||||||
|
@ -274,7 +267,6 @@ DEPS: dict[str, dict[str, Any]] = {
|
||||||
"freetype": {
|
"freetype": {
|
||||||
"url": "https://download.savannah.gnu.org/releases/freetype/FILENAME",
|
"url": "https://download.savannah.gnu.org/releases/freetype/FILENAME",
|
||||||
"filename": f"freetype-{V['FREETYPE']}.tar.gz",
|
"filename": f"freetype-{V['FREETYPE']}.tar.gz",
|
||||||
"dir": f"freetype-{V['FREETYPE']}",
|
|
||||||
"license": ["LICENSE.TXT", r"docs\FTL.TXT", r"docs\GPLv2.TXT"],
|
"license": ["LICENSE.TXT", r"docs\FTL.TXT", r"docs\GPLv2.TXT"],
|
||||||
"patch": {
|
"patch": {
|
||||||
r"builds\windows\vc2010\freetype.vcxproj": {
|
r"builds\windows\vc2010\freetype.vcxproj": {
|
||||||
|
@ -309,7 +301,6 @@ DEPS: dict[str, dict[str, Any]] = {
|
||||||
"lcms2": {
|
"lcms2": {
|
||||||
"url": f"{SF_PROJECTS}/lcms/files/lcms/{V['LCMS2']}/FILENAME/download",
|
"url": f"{SF_PROJECTS}/lcms/files/lcms/{V['LCMS2']}/FILENAME/download",
|
||||||
"filename": f"lcms2-{V['LCMS2']}.tar.gz",
|
"filename": f"lcms2-{V['LCMS2']}.tar.gz",
|
||||||
"dir": f"lcms2-{V['LCMS2']}",
|
|
||||||
"license": "LICENSE",
|
"license": "LICENSE",
|
||||||
"patch": {
|
"patch": {
|
||||||
r"Projects\VC2022\lcms2_static\lcms2_static.vcxproj": {
|
r"Projects\VC2022\lcms2_static\lcms2_static.vcxproj": {
|
||||||
|
@ -335,7 +326,6 @@ DEPS: dict[str, dict[str, Any]] = {
|
||||||
"openjpeg": {
|
"openjpeg": {
|
||||||
"url": f"https://github.com/uclouvain/openjpeg/archive/v{V['OPENJPEG']}.tar.gz",
|
"url": f"https://github.com/uclouvain/openjpeg/archive/v{V['OPENJPEG']}.tar.gz",
|
||||||
"filename": f"openjpeg-{V['OPENJPEG']}.tar.gz",
|
"filename": f"openjpeg-{V['OPENJPEG']}.tar.gz",
|
||||||
"dir": f"openjpeg-{V['OPENJPEG']}",
|
|
||||||
"license": "LICENSE",
|
"license": "LICENSE",
|
||||||
"build": [
|
"build": [
|
||||||
*cmds_cmake(
|
*cmds_cmake(
|
||||||
|
@ -350,7 +340,6 @@ DEPS: dict[str, dict[str, Any]] = {
|
||||||
# commit: Merge branch 'master' into msvc (matches 2.17.0 tag)
|
# commit: Merge branch 'master' into msvc (matches 2.17.0 tag)
|
||||||
"url": "https://github.com/ImageOptim/libimagequant/archive/e4c1334be0eff290af5e2b4155057c2953a313ab.zip",
|
"url": "https://github.com/ImageOptim/libimagequant/archive/e4c1334be0eff290af5e2b4155057c2953a313ab.zip",
|
||||||
"filename": "libimagequant-e4c1334be0eff290af5e2b4155057c2953a313ab.zip",
|
"filename": "libimagequant-e4c1334be0eff290af5e2b4155057c2953a313ab.zip",
|
||||||
"dir": "libimagequant-e4c1334be0eff290af5e2b4155057c2953a313ab",
|
|
||||||
"license": "COPYRIGHT",
|
"license": "COPYRIGHT",
|
||||||
"patch": {
|
"patch": {
|
||||||
"CMakeLists.txt": {
|
"CMakeLists.txt": {
|
||||||
|
@ -370,7 +359,6 @@ DEPS: dict[str, dict[str, Any]] = {
|
||||||
"harfbuzz": {
|
"harfbuzz": {
|
||||||
"url": f"https://github.com/harfbuzz/harfbuzz/archive/{V['HARFBUZZ']}.zip",
|
"url": f"https://github.com/harfbuzz/harfbuzz/archive/{V['HARFBUZZ']}.zip",
|
||||||
"filename": f"harfbuzz-{V['HARFBUZZ']}.zip",
|
"filename": f"harfbuzz-{V['HARFBUZZ']}.zip",
|
||||||
"dir": f"harfbuzz-{V['HARFBUZZ']}",
|
|
||||||
"license": "COPYING",
|
"license": "COPYING",
|
||||||
"build": [
|
"build": [
|
||||||
*cmds_cmake(
|
*cmds_cmake(
|
||||||
|
@ -385,7 +373,6 @@ DEPS: dict[str, dict[str, Any]] = {
|
||||||
"fribidi": {
|
"fribidi": {
|
||||||
"url": f"https://github.com/fribidi/fribidi/archive/v{V['FRIBIDI']}.zip",
|
"url": f"https://github.com/fribidi/fribidi/archive/v{V['FRIBIDI']}.zip",
|
||||||
"filename": f"fribidi-{V['FRIBIDI']}.zip",
|
"filename": f"fribidi-{V['FRIBIDI']}.zip",
|
||||||
"dir": f"fribidi-{V['FRIBIDI']}",
|
|
||||||
"license": "COPYING",
|
"license": "COPYING",
|
||||||
"build": [
|
"build": [
|
||||||
cmd_copy(r"COPYING", rf"{{bin_dir}}\fribidi-{V['FRIBIDI']}-COPYING"),
|
cmd_copy(r"COPYING", rf"{{bin_dir}}\fribidi-{V['FRIBIDI']}-COPYING"),
|
||||||
|
@ -793,6 +780,8 @@ def main() -> None:
|
||||||
}
|
}
|
||||||
|
|
||||||
for k, v in DEPS.items():
|
for k, v in DEPS.items():
|
||||||
|
if "dir" not in v:
|
||||||
|
v["dir"] = re.sub(r"\.(tar\.gz|zip)", "", v["filename"])
|
||||||
prefs[f"dir_{k}"] = os.path.join(sources_dir, v["dir"])
|
prefs[f"dir_{k}"] = os.path.join(sources_dir, v["dir"])
|
||||||
|
|
||||||
print()
|
print()
|
||||||
|
|
Loading…
Reference in New Issue
Block a user