Require webpmux and webpdemux

This commit is contained in:
Aleksandr Karpinskii 2024-07-07 21:51:14 +04:00
parent a5b415bef5
commit c1e8375af8
10 changed files with 26 additions and 86 deletions

View File

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

View File

@ -57,11 +57,6 @@ def test_webp_transparency() -> None:
assert features.check("transp_webp") == _webp.HAVE_TRANSPARENCY assert features.check("transp_webp") == _webp.HAVE_TRANSPARENCY
@skip_unless_feature("webp")
def test_webp_mux() -> None:
assert features.check("webp_mux") == _webp.HAVE_WEBPMUX
@skip_unless_feature("webp") @skip_unless_feature("webp")
def test_webp_anim() -> None: def test_webp_anim() -> None:
assert features.check("webp_anim") == _webp.HAVE_WEBPANIM assert features.check("webp_anim") == _webp.HAVE_WEBPANIM

View File

@ -10,10 +10,7 @@ from PIL import Image
from .helper import mark_if_feature_version, skip_unless_feature from .helper import mark_if_feature_version, skip_unless_feature
pytestmark = [ pytestmark = [skip_unless_feature("webp")]
skip_unless_feature("webp"),
skip_unless_feature("webp_mux"),
]
ElementTree: ModuleType | None ElementTree: ModuleType | None
try: try:

View File

@ -1252,16 +1252,13 @@ The :py:meth:`~PIL.Image.Image.save` method supports the following options:
Requires libwebp 0.5.0 or later. Requires libwebp 0.5.0 or later.
**icc_profile** **icc_profile**
The ICC Profile to include in the saved file. Only supported if The ICC Profile to include in the saved file.
the system WebP library was built with webpmux support.
**exif** **exif**
The exif data to include in the saved file. Only supported if The exif data to include in the saved file.
the system WebP library was built with webpmux support.
**xmp** **xmp**
The XMP data to include in the saved file. Only supported if The XMP data to include in the saved file.
the system WebP library was built with webpmux support.
Saving sequences Saving sequences
~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~

View File

@ -275,18 +275,18 @@ Build Options
* Config settings: ``-C zlib=disable``, ``-C jpeg=disable``, * Config settings: ``-C zlib=disable``, ``-C jpeg=disable``,
``-C tiff=disable``, ``-C freetype=disable``, ``-C raqm=disable``, ``-C tiff=disable``, ``-C freetype=disable``, ``-C raqm=disable``,
``-C lcms=disable``, ``-C webp=disable``, ``-C webpmux=disable``, ``-C lcms=disable``, ``-C webp=disable``,
``-C jpeg2000=disable``, ``-C imagequant=disable``, ``-C xcb=disable``. ``-C jpeg2000=disable``, ``-C imagequant=disable``, ``-C xcb=disable``.
Disable building the corresponding feature even if the development Disable building the corresponding feature even if the development
libraries are present on the building machine. libraries are present on the building machine.
* Config settings: ``-C zlib=enable``, ``-C jpeg=enable``, * Config settings: ``-C zlib=enable``, ``-C jpeg=enable``,
``-C tiff=enable``, ``-C freetype=enable``, ``-C raqm=enable``, ``-C tiff=enable``, ``-C freetype=enable``, ``-C raqm=enable``,
``-C lcms=enable``, ``-C webp=enable``, ``-C webpmux=enable``, ``-C lcms=enable``, ``-C webp=enable``,
``-C jpeg2000=enable``, ``-C imagequant=enable``, ``-C xcb=enable``. ``-C jpeg2000=enable``, ``-C imagequant=enable``, ``-C xcb=enable``.
Require that the corresponding feature is built. The build will raise Require that the corresponding feature is built. The build will raise
an exception if the libraries are not found. Webpmux (WebP metadata) an exception if the libraries are not found. Tcl and Tk must be used
relies on WebP support. Tcl and Tk also must be used together. together.
* Config settings: ``-C raqm=vendor``, ``-C fribidi=vendor``. * Config settings: ``-C raqm=vendor``, ``-C fribidi=vendor``.
These flags are used to compile a modified version of libraqm and These flags are used to compile a modified version of libraqm and

View File

@ -55,7 +55,6 @@ 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. * ``libjpeg_turbo``: (compile time) Whether Pillow was compiled against the libjpeg-turbo version of libjpeg. Compile-time version number is available.
* ``transp_webp``: Support for transparency in WebP images. * ``transp_webp``: Support for transparency in WebP images.
* ``webp_mux``: (compile time) Support for EXIF data in WebP images.
* ``webp_anim``: (compile time) Support for animated WebP images. * ``webp_anim``: (compile time) Support for animated WebP images.
* ``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. * ``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. * ``libimagequant``: (compile time) ImageQuant quantization support in :py:func:`PIL.Image.Image.quantize`. Run-time version number is available.

View File

@ -295,7 +295,6 @@ class pil_build_ext(build_ext):
"raqm", "raqm",
"lcms", "lcms",
"webp", "webp",
"webpmux",
"jpeg2000", "jpeg2000",
"imagequant", "imagequant",
"xcb", "xcb",
@ -794,29 +793,22 @@ class pil_build_ext(build_ext):
if feature.want("webp"): if feature.want("webp"):
_dbg("Looking for webp") _dbg("Looking for webp")
if _find_include_file(self, "webp/encode.h") and _find_include_file( if all(
self, "webp/decode.h" _find_include_file(self, src)
for src in ["webp/encode.h", "webp/mux.h", "webp/demux.h"]
): ):
# In Google's precompiled zip it is call "libwebp": # In Google's precompiled zip it is call "libwebp":
if _find_library_file(self, "webp"): if all(
_find_library_file(self, lib)
for lib in ["webp", "webpmux", "webpdemux"]
):
feature.webp = "webp" feature.webp = "webp"
elif _find_library_file(self, "libwebp"): elif all(
_find_library_file(self, lib)
for lib in ["libwebp", "libwebpmux", "libwebpdemux"]
):
feature.webp = "libwebp" feature.webp = "libwebp"
if feature.want("webpmux"):
_dbg("Looking for webpmux")
if _find_include_file(self, "webp/mux.h") and _find_include_file(
self, "webp/demux.h"
):
if _find_library_file(self, "webpmux") and _find_library_file(
self, "webpdemux"
):
feature.webpmux = "webpmux"
if _find_library_file(self, "libwebpmux") and _find_library_file(
self, "libwebpdemux"
):
feature.webpmux = "libwebpmux"
if feature.want("xcb"): if feature.want("xcb"):
_dbg("Looking for xcb") _dbg("Looking for xcb")
if _find_include_file(self, "xcb/xcb.h"): if _find_include_file(self, "xcb/xcb.h"):
@ -904,15 +896,12 @@ class pil_build_ext(build_ext):
self._remove_extension("PIL._imagingcms") self._remove_extension("PIL._imagingcms")
if feature.webp: if feature.webp:
libs = [feature.webp] libs = [
defs = [] feature.webp,
feature.webp + "mux",
if feature.webpmux: feature.webp + "demux",
defs.append(("HAVE_WEBPMUX", None)) ]
libs.append(feature.webpmux) self._update_extension("PIL._webp", libs, [])
libs.append(feature.webpmux.replace("pmux", "pdemux"))
self._update_extension("PIL._webp", libs, defs)
else: else:
self._remove_extension("PIL._webp") self._remove_extension("PIL._webp")
@ -953,7 +942,6 @@ class pil_build_ext(build_ext):
(feature.raqm, "RAQM (Text shaping)", raqm_extra_info), (feature.raqm, "RAQM (Text shaping)", raqm_extra_info),
(feature.lcms, "LITTLECMS2"), (feature.lcms, "LITTLECMS2"),
(feature.webp, "WEBP"), (feature.webp, "WEBP"),
(feature.webpmux, "WEBPMUX"),
(feature.xcb, "XCB (X protocol)"), (feature.xcb, "XCB (X protocol)"),
] ]

View File

@ -120,7 +120,6 @@ def get_supported_codecs() -> list[str]:
features = { features = {
"webp_anim": ("PIL._webp", "HAVE_WEBPANIM", None), "webp_anim": ("PIL._webp", "HAVE_WEBPANIM", None),
"webp_mux": ("PIL._webp", "HAVE_WEBPMUX", None),
"transp_webp": ("PIL._webp", "HAVE_TRANSPARENCY", None), "transp_webp": ("PIL._webp", "HAVE_TRANSPARENCY", None),
"raqm": ("PIL._imagingft", "HAVE_RAQM", "raqm_version"), "raqm": ("PIL._imagingft", "HAVE_RAQM", "raqm_version"),
"fribidi": ("PIL._imagingft", "HAVE_FRIBIDI", "fribidi_version"), "fribidi": ("PIL._imagingft", "HAVE_FRIBIDI", "fribidi_version"),
@ -272,7 +271,6 @@ def pilinfo(out: IO[str] | None = None, supported_formats: bool = True) -> None:
("littlecms2", "LITTLECMS2"), ("littlecms2", "LITTLECMS2"),
("webp", "WEBP"), ("webp", "WEBP"),
("transp_webp", "WEBP Transparency"), ("transp_webp", "WEBP Transparency"),
("webp_mux", "WEBPMUX"),
("webp_anim", "WEBP Animation"), ("webp_anim", "WEBP Animation"),
("jpg", "JPEG"), ("jpg", "JPEG"),
("jpg_2000", "OPENJPEG (JPEG2000)"), ("jpg_2000", "OPENJPEG (JPEG2000)"),

View File

@ -4,8 +4,6 @@
#include <webp/encode.h> #include <webp/encode.h>
#include <webp/decode.h> #include <webp/decode.h>
#include <webp/types.h> #include <webp/types.h>
#ifdef HAVE_WEBPMUX
#include <webp/mux.h> #include <webp/mux.h>
#include <webp/demux.h> #include <webp/demux.h>
@ -19,8 +17,6 @@
#define HAVE_WEBPANIM #define HAVE_WEBPANIM
#endif #endif
#endif
void void
ImagingSectionEnter(ImagingSectionCookie *cookie) { ImagingSectionEnter(ImagingSectionCookie *cookie) {
*cookie = (PyThreadState *)PyEval_SaveThread(); *cookie = (PyThreadState *)PyEval_SaveThread();
@ -35,8 +31,6 @@ ImagingSectionLeave(ImagingSectionCookie *cookie) {
/* WebP Muxer Error Handling */ /* WebP Muxer Error Handling */
/* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */
#ifdef HAVE_WEBPMUX
static const char *const kErrorMessages[-WEBP_MUX_NOT_ENOUGH_DATA + 1] = { static const char *const kErrorMessages[-WEBP_MUX_NOT_ENOUGH_DATA + 1] = {
"WEBP_MUX_NOT_FOUND", "WEBP_MUX_NOT_FOUND",
"WEBP_MUX_INVALID_ARGUMENT", "WEBP_MUX_INVALID_ARGUMENT",
@ -89,8 +83,6 @@ HandleMuxError(WebPMuxError err, char *chunk) {
return NULL; return NULL;
} }
#endif
/* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */
/* WebP Animation Support */ /* WebP Animation Support */
/* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */
@ -693,13 +685,6 @@ WebPEncode_wrapper(PyObject *self, PyObject *args) {
output = writer.mem; output = writer.mem;
ret_size = writer.size; ret_size = writer.size;
#ifndef HAVE_WEBPMUX
if (ret_size > 0) {
PyObject *ret = PyBytes_FromStringAndSize((char *)output, ret_size);
free(output);
return ret;
}
#else
{ {
/* I want to truncate the *_size items that get passed into WebP /* I want to truncate the *_size items that get passed into WebP
data. Pypy2.1.0 had some issues where the Py_ssize_t items had data. Pypy2.1.0 had some issues where the Py_ssize_t items had
@ -775,7 +760,6 @@ WebPEncode_wrapper(PyObject *self, PyObject *args) {
return ret; return ret;
} }
} }
#endif
Py_RETURN_NONE; Py_RETURN_NONE;
} }
@ -809,9 +793,6 @@ WebPDecode_wrapper(PyObject *self, PyObject *args) {
mode = "RGBA"; mode = "RGBA";
} }
#ifndef HAVE_WEBPMUX
vp8_status_code = WebPDecode(webp, size, &config);
#else
{ {
int copy_data = 0; int copy_data = 0;
WebPData data = {webp, size}; WebPData data = {webp, size};
@ -849,7 +830,6 @@ WebPDecode_wrapper(PyObject *self, PyObject *args) {
WebPDataClear(&image.bitstream); WebPDataClear(&image.bitstream);
WebPMuxDelete(mux); WebPMuxDelete(mux);
} }
#endif
} }
if (vp8_status_code != VP8_STATUS_OK) { if (vp8_status_code != VP8_STATUS_OK) {
@ -949,18 +929,6 @@ static PyMethodDef webpMethods[] = {
{NULL, NULL} {NULL, NULL}
}; };
void
addMuxFlagToModule(PyObject *m) {
PyObject *have_webpmux;
#ifdef HAVE_WEBPMUX
have_webpmux = Py_True;
#else
have_webpmux = Py_False;
#endif
Py_INCREF(have_webpmux);
PyModule_AddObject(m, "HAVE_WEBPMUX", have_webpmux);
}
void void
addAnimFlagToModule(PyObject *m) { addAnimFlagToModule(PyObject *m) {
PyObject *have_webpanim; PyObject *have_webpanim;
@ -991,7 +959,6 @@ setup_module(PyObject *m) {
} }
#endif #endif
PyObject *d = PyModule_GetDict(m); PyObject *d = PyModule_GetDict(m);
addMuxFlagToModule(m);
addAnimFlagToModule(m); addAnimFlagToModule(m);
addTransparencyFlagToModule(m); addTransparencyFlagToModule(m);

View File

@ -201,7 +201,7 @@ DEPS = {
}, },
"build": [ "build": [
*cmds_cmake( *cmds_cmake(
"webp webpdemux webpmux", "webp webpmux webpdemux",
"-DBUILD_SHARED_LIBS:BOOL=OFF", "-DBUILD_SHARED_LIBS:BOOL=OFF",
"-DWEBP_LINK_STATIC:BOOL=OFF", "-DWEBP_LINK_STATIC:BOOL=OFF",
), ),