Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use zlib-ng instead of zlib #8500

Merged
merged 10 commits into from
Dec 14, 2024
Merged
18 changes: 12 additions & 6 deletions .github/workflows/wheels-dependencies.sh
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,7 @@ if [[ -n "$IS_MACOS" ]]; then
else
GIFLIB_VERSION=5.2.1
fi
if [[ -n "$IS_MACOS" ]] || [[ "$MB_ML_VER" != 2014 ]]; then
ZLIB_VERSION=1.3.1
else
ZLIB_VERSION=1.2.8
fi
ZLIB_NG_VERSION=2.2.2
LIBWEBP_VERSION=1.4.0
BZIP2_VERSION=1.0.8
LIBXCB_VERSION=1.17.0
Expand All @@ -74,6 +70,16 @@ function build_pkg_config {
touch pkg-config-stamp
}

function build_zlib_ng {
if [ -e zlib-stamp ]; then return; fi
fetch_unpack https://github.com/zlib-ng/zlib-ng/archive/$ZLIB_NG_VERSION.tar.gz zlib-ng-$ZLIB_NG_VERSION.tar.gz
(cd zlib-ng-$ZLIB_NG_VERSION \
&& ./configure --prefix=$BUILD_PREFIX --zlib-compat \
&& make -j4 \
&& make install)
touch zlib-stamp
}

function build_brotli {
if [ -e brotli-stamp ]; then return; fi
local out_dir=$(fetch_unpack https://github.com/google/brotli/archive/v$BROTLI_VERSION.tar.gz brotli-$BROTLI_VERSION.tar.gz)
Expand All @@ -100,7 +106,7 @@ function build {
if [ -z "$IS_ALPINE" ] && [ -z "$IS_MACOS" ]; then
yum remove -y zlib-devel
fi
build_new_zlib
build_zlib_ng

build_simple xcb-proto 1.17.0 https://xorg.freedesktop.org/archive/individual/proto
if [ -n "$IS_MACOS" ]; then
Expand Down
1 change: 1 addition & 0 deletions Tests/check_wheel.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ def test_wheel_features() -> None:
"fribidi",
"harfbuzz",
"libjpeg_turbo",
"zlib_ng",
"xcb",
}

Expand Down
9 changes: 5 additions & 4 deletions Tests/test_features.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,11 @@ def test(name: str, function: Callable[[str], str | None]) -> None:
else:
assert function(name) == version
if name != "PIL":
if name == "zlib" and version is not None:
version = re.sub(".zlib-ng$", "", version)
elif name == "libtiff" and version is not None:
version = re.sub("t$", "", version)
if version is not None:
if name == "zlib" and features.check_feature("zlib_ng"):
version = re.sub(".zlib-ng$", "", version)
elif name == "libtiff":
version = re.sub("t$", "", version)
assert version is None or re.search(r"\d+(\.\d+)*$", version)

for module in features.modules:
Expand Down
1 change: 1 addition & 0 deletions docs/reference/features.rst
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ Feature version numbers are available only where stated.
Support for the following features can be checked:

* ``libjpeg_turbo``: (compile time) Whether Pillow was compiled against the libjpeg-turbo version of libjpeg. Compile-time version number is available.
* ``zlib_ng``: (compile time) Whether Pillow was compiled against the zlib-ng version of zlib. Compile-time version number is available.
* ``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.
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ test-extras = "tests"

[tool.cibuildwheel.macos.environment]
PATH = "$(pwd)/build/deps/darwin/bin:$(dirname $(which python3)):/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin"
DYLD_LIBRARY_PATH = "$(pwd)/build/deps/darwin/lib"

[tool.black]
exclude = "wheels/multibuild"
Expand Down
7 changes: 6 additions & 1 deletion src/PIL/features.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ def get_supported_codecs() -> list[str]:
"fribidi": ("PIL._imagingft", "HAVE_FRIBIDI", "fribidi_version"),
"harfbuzz": ("PIL._imagingft", "HAVE_HARFBUZZ", "harfbuzz_version"),
"libjpeg_turbo": ("PIL._imaging", "HAVE_LIBJPEGTURBO", "libjpeg_turbo_version"),
"zlib_ng": ("PIL._imaging", "HAVE_ZLIBNG", "zlib_ng_version"),
"libimagequant": ("PIL._imaging", "HAVE_LIBIMAGEQUANT", "imagequant_version"),
"xcb": ("PIL._imaging", "HAVE_XCB", None),
}
Expand Down Expand Up @@ -308,7 +309,11 @@ def pilinfo(out: IO[str] | None = None, supported_formats: bool = True) -> None:
# this check is also in src/_imagingcms.c:setup_module()
version_static = tuple(int(x) for x in v.split(".")) < (2, 7)
t = "compiled for" if version_static else "loaded"
if name == "raqm":
if name == "zlib":
zlib_ng_version = version_feature("zlib_ng")
if zlib_ng_version is not None:
v += ", compiled for zlib-ng " + zlib_ng_version
elif name == "raqm":
for f in ("fribidi", "harfbuzz"):
v2 = version_feature(f)
if v2 is not None:
Expand Down
14 changes: 14 additions & 0 deletions src/_imaging.c
Original file line number Diff line number Diff line change
Expand Up @@ -4397,6 +4397,20 @@ setup_module(PyObject *m) {
}
#endif

PyObject *have_zlibng;
#ifdef ZLIBNG_VERSION
have_zlibng = Py_True;
{
PyObject *v = PyUnicode_FromString(ZLIBNG_VERSION);
PyDict_SetItemString(d, "zlib_ng_version", v ? v : Py_None);
Py_XDECREF(v);
}
#else
have_zlibng = Py_False;
#endif
Py_INCREF(have_zlibng);
PyModule_AddObject(m, "HAVE_ZLIBNG", have_zlibng);

#ifdef HAVE_LIBTIFF
{
extern const char *ImagingTiffVersion(void);
Expand Down
25 changes: 14 additions & 11 deletions winbuild/build_prepare.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,11 +120,10 @@ def cmd_msbuild(
"OPENJPEG": "2.5.3",
"TIFF": "4.6.0",
"XZ": "5.6.3",
"ZLIB": "1.3.1",
"ZLIBNG": "2.2.2",
}
V["LIBPNG_DOTLESS"] = V["LIBPNG"].replace(".", "")
V["LIBPNG_XY"] = "".join(V["LIBPNG"].split(".")[:2])
V["ZLIB_DOTLESS"] = V["ZLIB"].replace(".", "")


# dependencies, listed in order of compilation
Expand Down Expand Up @@ -160,18 +159,22 @@ def cmd_msbuild(
"bins": ["cjpeg.exe", "djpeg.exe"],
},
"zlib": {
"url": "https://zlib.net/FILENAME",
"filename": f"zlib{V['ZLIB_DOTLESS']}.zip",
"dir": f"zlib-{V['ZLIB']}",
"license": "README",
"license_pattern": "Copyright notice:\n\n(.+)$",
"url": f"https://github.com/zlib-ng/zlib-ng/archive/refs/tags/{V['ZLIBNG']}.zip",
"filename": f"zlib-ng-{V['ZLIBNG']}.zip",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've created #8601 to change this to .tar.gz, so that it matches wheels-dependencies.sh

"dir": f"zlib-ng-{V['ZLIBNG']}",
"license": "LICENSE.md",
"patch": {
r"CMakeLists.txt": {
"set_target_properties(zlib PROPERTIES OUTPUT_NAME zlibstatic${{SUFFIX}})": "set_target_properties(zlib PROPERTIES OUTPUT_NAME zlib)", # noqa: E501
Copy link
Member

@radarhere radarhere Nov 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If zlib-ng creates zlibstatic.lib by default, then wouldn't it seem helpful to detect that in setup.py, in case a user had built it themselves? nulano#44

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, is the concern that zlib-ng might have been built without --zlib-compat?

},
},
"build": [
cmd_nmake(r"win32\Makefile.msc", "clean"),
cmd_nmake(r"win32\Makefile.msc", "zlib.lib"),
cmd_copy("zlib.lib", "z.lib"),
*cmds_cmake(
"zlib", "-DBUILD_SHARED_LIBS:BOOL=OFF", "-DZLIB_COMPAT:BOOL=ON"
),
],
"headers": [r"z*.h"],
"libs": [r"*.lib"],
"libs": [r"zlib.lib"],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"libs": [r"zlib.lib"],
"libs": ["zlib.lib"],

},
"xz": {
"url": f"https://github.com/tukaani-project/xz/releases/download/v{V['XZ']}/FILENAME",
Expand Down
Loading