mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-01-25 00:34:14 +03:00
Remove webp animations flags and conditions
Removed: _webp.WebPDecode _webp.HAVE_WEBPANIM features.webp_anim
This commit is contained in:
parent
9bed5b4264
commit
a3468996c0
|
@ -27,7 +27,6 @@ def test_wheel_codecs() -> None:
|
|||
|
||||
def test_wheel_features() -> None:
|
||||
expected_features = {
|
||||
"webp_anim",
|
||||
"raqm",
|
||||
"fribidi",
|
||||
"harfbuzz",
|
||||
|
|
|
@ -10,11 +10,6 @@ from PIL import features
|
|||
|
||||
from .helper import skip_unless_feature
|
||||
|
||||
try:
|
||||
from PIL import _webp
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
def test_check() -> None:
|
||||
# Check the correctness of the convenience function
|
||||
|
@ -51,11 +46,6 @@ def test_version() -> None:
|
|||
test(feature, features.version_feature)
|
||||
|
||||
|
||||
@skip_unless_feature("webp")
|
||||
def test_webp_anim() -> None:
|
||||
assert features.check("webp_anim") == _webp.HAVE_WEBPANIM
|
||||
|
||||
|
||||
@skip_unless_feature("libjpeg_turbo")
|
||||
def test_libjpeg_turbo_version() -> None:
|
||||
version = features.version("libjpeg_turbo")
|
||||
|
|
|
@ -978,7 +978,7 @@ def test_webp_background(tmp_path: Path) -> None:
|
|||
out = str(tmp_path / "temp.gif")
|
||||
|
||||
# Test opaque WebP background
|
||||
if features.check("webp") and features.check("webp_anim"):
|
||||
if features.check("webp"):
|
||||
with Image.open("Tests/images/hopper.webp") as im:
|
||||
assert im.info["background"] == (255, 255, 255, 255)
|
||||
im.save(out)
|
||||
|
|
|
@ -48,7 +48,6 @@ class TestFileWebp:
|
|||
self.rgb_mode = "RGB"
|
||||
|
||||
def test_version(self) -> None:
|
||||
_webp.WebPDecoderVersion()
|
||||
version = features.version_module("webp")
|
||||
assert version is not None
|
||||
assert re.search(r"\d+\.\d+\.\d+$", version)
|
||||
|
@ -116,7 +115,6 @@ class TestFileWebp:
|
|||
hopper().save(buffer_method, format="WEBP", method=6)
|
||||
assert buffer_no_args.getbuffer() != buffer_method.getbuffer()
|
||||
|
||||
@skip_unless_feature("webp_anim")
|
||||
def test_save_all(self, tmp_path: Path) -> None:
|
||||
temp_file = str(tmp_path / "temp.webp")
|
||||
im = Image.new("RGB", (1, 1))
|
||||
|
@ -131,10 +129,9 @@ class TestFileWebp:
|
|||
|
||||
def test_icc_profile(self, tmp_path: Path) -> None:
|
||||
self._roundtrip(tmp_path, self.rgb_mode, 12.5, {"icc_profile": None})
|
||||
if _webp.HAVE_WEBPANIM:
|
||||
self._roundtrip(
|
||||
tmp_path, self.rgb_mode, 12.5, {"icc_profile": None, "save_all": True}
|
||||
)
|
||||
self._roundtrip(
|
||||
tmp_path, self.rgb_mode, 12.5, {"icc_profile": None, "save_all": True}
|
||||
)
|
||||
|
||||
def test_write_unsupported_mode_L(self, tmp_path: Path) -> None:
|
||||
"""
|
||||
|
@ -164,10 +161,8 @@ class TestFileWebp:
|
|||
"""
|
||||
Calling encoder functions with no arguments should result in an error.
|
||||
"""
|
||||
|
||||
if _webp.HAVE_WEBPANIM:
|
||||
with pytest.raises(TypeError):
|
||||
_webp.WebPAnimEncoder()
|
||||
with pytest.raises(TypeError):
|
||||
_webp.WebPAnimEncoder()
|
||||
with pytest.raises(TypeError):
|
||||
_webp.WebPEncode()
|
||||
|
||||
|
@ -175,12 +170,8 @@ class TestFileWebp:
|
|||
"""
|
||||
Calling decoder functions with no arguments should result in an error.
|
||||
"""
|
||||
|
||||
if _webp.HAVE_WEBPANIM:
|
||||
with pytest.raises(TypeError):
|
||||
_webp.WebPAnimDecoder()
|
||||
with pytest.raises(TypeError):
|
||||
_webp.WebPDecode()
|
||||
_webp.WebPAnimDecoder()
|
||||
|
||||
def test_no_resource_warning(self, tmp_path: Path) -> None:
|
||||
file_path = "Tests/images/hopper.webp"
|
||||
|
@ -199,7 +190,6 @@ class TestFileWebp:
|
|||
"background",
|
||||
(0, (0,), (-1, 0, 1, 2), (253, 254, 255, 256)),
|
||||
)
|
||||
@skip_unless_feature("webp_anim")
|
||||
def test_invalid_background(
|
||||
self, background: int | tuple[int, ...], tmp_path: Path
|
||||
) -> None:
|
||||
|
@ -208,7 +198,6 @@ class TestFileWebp:
|
|||
with pytest.raises(OSError):
|
||||
im.save(temp_file, save_all=True, append_images=[im], background=background)
|
||||
|
||||
@skip_unless_feature("webp_anim")
|
||||
def test_background_from_gif(self, tmp_path: Path) -> None:
|
||||
# Save L mode GIF with background
|
||||
with Image.open("Tests/images/no_palette_with_background.gif") as im:
|
||||
|
@ -233,7 +222,6 @@ class TestFileWebp:
|
|||
difference = sum(abs(original_value[i] - reread_value[i]) for i in range(0, 3))
|
||||
assert difference < 5
|
||||
|
||||
@skip_unless_feature("webp_anim")
|
||||
def test_duration(self, tmp_path: Path) -> None:
|
||||
with Image.open("Tests/images/dispose_bgnd.gif") as im:
|
||||
assert im.info["duration"] == 1000
|
||||
|
|
|
@ -85,12 +85,7 @@ def test_write_rgba(tmp_path: Path) -> None:
|
|||
image.load()
|
||||
image.getdata()
|
||||
|
||||
# Early versions of WebP are known to produce higher deviations:
|
||||
# deal with it
|
||||
if _webp.WebPDecoderVersion() <= 0x201:
|
||||
assert_image_similar(image, pil_image, 3.0)
|
||||
else:
|
||||
assert_image_similar(image, pil_image, 1.0)
|
||||
assert_image_similar(image, pil_image, 1.0)
|
||||
|
||||
|
||||
def test_keep_rgb_values_when_transparent(tmp_path: Path) -> None:
|
||||
|
|
|
@ -15,10 +15,7 @@ from .helper import (
|
|||
skip_unless_feature,
|
||||
)
|
||||
|
||||
pytestmark = [
|
||||
skip_unless_feature("webp"),
|
||||
skip_unless_feature("webp_anim"),
|
||||
]
|
||||
pytestmark = skip_unless_feature("webp")
|
||||
|
||||
|
||||
def test_n_frames() -> None:
|
||||
|
|
|
@ -13,9 +13,6 @@ RGB_MODE = "RGB"
|
|||
|
||||
|
||||
def test_write_lossless_rgb(tmp_path: Path) -> None:
|
||||
if _webp.WebPDecoderVersion() < 0x0200:
|
||||
pytest.skip("lossless not included")
|
||||
|
||||
temp_file = str(tmp_path / "temp.webp")
|
||||
|
||||
hopper(RGB_MODE).save(temp_file, lossless=True)
|
||||
|
|
|
@ -10,7 +10,7 @@ from PIL import Image
|
|||
|
||||
from .helper import mark_if_feature_version, skip_unless_feature
|
||||
|
||||
pytestmark = [skip_unless_feature("webp")]
|
||||
pytestmark = skip_unless_feature("webp")
|
||||
|
||||
ElementTree: ModuleType | None
|
||||
try:
|
||||
|
@ -133,7 +133,6 @@ def test_getxmp() -> None:
|
|||
)
|
||||
|
||||
|
||||
@skip_unless_feature("webp_anim")
|
||||
def test_write_animated_metadata(tmp_path: Path) -> None:
|
||||
iccp_data = b"<iccp_data>"
|
||||
exif_data = b"<exif_data>"
|
||||
|
|
|
@ -817,7 +817,6 @@ class TestImage:
|
|||
assert reloaded_exif[305] == "Pillow test"
|
||||
|
||||
@skip_unless_feature("webp")
|
||||
@skip_unless_feature("webp_anim")
|
||||
def test_exif_webp(self, tmp_path: Path) -> None:
|
||||
with Image.open("Tests/images/hopper.webp") as im:
|
||||
exif = im.getexif()
|
||||
|
|
|
@ -94,7 +94,6 @@ class TestImageFile:
|
|||
assert (48, 48) == p.image.size
|
||||
|
||||
@skip_unless_feature("webp")
|
||||
@skip_unless_feature("webp_anim")
|
||||
def test_incremental_webp(self) -> None:
|
||||
with ImageFile.Parser() as p:
|
||||
with open("Tests/images/hopper.webp", "rb") as f:
|
||||
|
|
|
@ -390,7 +390,7 @@ def test_colorize_3color_offset() -> None:
|
|||
|
||||
def test_exif_transpose() -> None:
|
||||
exts = [".jpg"]
|
||||
if features.check("webp") and features.check("webp_anim"):
|
||||
if features.check("webp"):
|
||||
exts.append(".webp")
|
||||
for ext in exts:
|
||||
with Image.open("Tests/images/hopper" + ext) as base_im:
|
||||
|
|
|
@ -1220,8 +1220,7 @@ using the general tags available through tiffinfo.
|
|||
WebP
|
||||
^^^^
|
||||
|
||||
Pillow reads and writes WebP files. The specifics of Pillow's capabilities with
|
||||
this format are currently undocumented.
|
||||
Pillow reads and writes WebP files. Requires libwebp v0.5.0 or later.
|
||||
|
||||
.. _webp-saving:
|
||||
|
||||
|
@ -1263,12 +1262,6 @@ The :py:meth:`~PIL.Image.Image.save` method supports the following options:
|
|||
Saving sequences
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
.. note::
|
||||
|
||||
Support for animated WebP files will only be enabled if the system WebP
|
||||
library is v0.5.0 or later. You can check webp animation support at
|
||||
runtime by calling ``features.check("webp_anim")``.
|
||||
|
||||
When calling :py:meth:`~PIL.Image.Image.save` to write a WebP file, by default
|
||||
only the first frame of a multiframe image will be saved. If the ``save_all``
|
||||
argument is present and true, then all frames will be saved, and the following
|
||||
|
|
|
@ -54,7 +54,6 @@ 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.
|
||||
* ``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.
|
||||
* ``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.
|
||||
|
|
7
setup.py
7
setup.py
|
@ -795,7 +795,12 @@ class pil_build_ext(build_ext):
|
|||
_dbg("Looking for webp")
|
||||
if all(
|
||||
_find_include_file(self, src)
|
||||
for src in ["webp/encode.h", "webp/mux.h", "webp/demux.h"]
|
||||
for src in [
|
||||
"webp/encode.h",
|
||||
"webp/decode.h",
|
||||
"webp/mux.h",
|
||||
"webp/demux.h",
|
||||
]
|
||||
):
|
||||
# In Google's precompiled zip it is call "libwebp":
|
||||
if all(
|
||||
|
|
|
@ -45,22 +45,6 @@ class WebPImageFile(ImageFile.ImageFile):
|
|||
__logical_frame = 0
|
||||
|
||||
def _open(self) -> None:
|
||||
if not _webp.HAVE_WEBPANIM:
|
||||
# Legacy mode
|
||||
data, width, height, self._mode, icc_profile, exif = _webp.WebPDecode(
|
||||
self.fp.read()
|
||||
)
|
||||
if icc_profile:
|
||||
self.info["icc_profile"] = icc_profile
|
||||
if exif:
|
||||
self.info["exif"] = exif
|
||||
self._size = width, height
|
||||
self.fp = BytesIO(data)
|
||||
self.tile = [("raw", (0, 0) + self.size, 0, self.mode)]
|
||||
self.n_frames = 1
|
||||
self.is_animated = False
|
||||
return
|
||||
|
||||
# Use the newer AnimDecoder API to parse the (possibly) animated file,
|
||||
# and access muxed chunks like ICC/EXIF/XMP.
|
||||
self._decoder = _webp.WebPAnimDecoder(self.fp.read())
|
||||
|
@ -145,21 +129,20 @@ class WebPImageFile(ImageFile.ImageFile):
|
|||
self._get_next() # Advance to the requested frame
|
||||
|
||||
def load(self) -> Image.core.PixelAccess | None:
|
||||
if _webp.HAVE_WEBPANIM:
|
||||
if self.__loaded != self.__logical_frame:
|
||||
self._seek(self.__logical_frame)
|
||||
if self.__loaded != self.__logical_frame:
|
||||
self._seek(self.__logical_frame)
|
||||
|
||||
# We need to load the image data for this frame
|
||||
data, timestamp, duration = self._get_next()
|
||||
self.info["timestamp"] = timestamp
|
||||
self.info["duration"] = duration
|
||||
self.__loaded = self.__logical_frame
|
||||
# We need to load the image data for this frame
|
||||
data, timestamp, duration = self._get_next()
|
||||
self.info["timestamp"] = timestamp
|
||||
self.info["duration"] = duration
|
||||
self.__loaded = self.__logical_frame
|
||||
|
||||
# Set tile
|
||||
if self.fp and self._exclusive_fp:
|
||||
self.fp.close()
|
||||
self.fp = BytesIO(data)
|
||||
self.tile = [("raw", (0, 0) + self.size, 0, self.rawmode)]
|
||||
# Set tile
|
||||
if self.fp and self._exclusive_fp:
|
||||
self.fp.close()
|
||||
self.fp = BytesIO(data)
|
||||
self.tile = [("raw", (0, 0) + self.size, 0, self.rawmode)]
|
||||
|
||||
return super().load()
|
||||
|
||||
|
@ -167,9 +150,6 @@ class WebPImageFile(ImageFile.ImageFile):
|
|||
pass
|
||||
|
||||
def tell(self) -> int:
|
||||
if not _webp.HAVE_WEBPANIM:
|
||||
return super().tell()
|
||||
|
||||
return self.__logical_frame
|
||||
|
||||
|
||||
|
@ -357,7 +337,6 @@ def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None:
|
|||
Image.register_open(WebPImageFile.format, WebPImageFile, _accept)
|
||||
if SUPPORTED:
|
||||
Image.register_save(WebPImageFile.format, _save)
|
||||
if _webp.HAVE_WEBPANIM:
|
||||
Image.register_save_all(WebPImageFile.format, _save_all)
|
||||
Image.register_save_all(WebPImageFile.format, _save_all)
|
||||
Image.register_extension(WebPImageFile.format, ".webp")
|
||||
Image.register_mime(WebPImageFile.format, "image/webp")
|
||||
|
|
|
@ -119,7 +119,6 @@ def get_supported_codecs() -> list[str]:
|
|||
|
||||
|
||||
features = {
|
||||
"webp_anim": ("PIL._webp", "HAVE_WEBPANIM", None),
|
||||
"raqm": ("PIL._imagingft", "HAVE_RAQM", "raqm_version"),
|
||||
"fribidi": ("PIL._imagingft", "HAVE_FRIBIDI", "fribidi_version"),
|
||||
"harfbuzz": ("PIL._imagingft", "HAVE_HARFBUZZ", "harfbuzz_version"),
|
||||
|
@ -269,7 +268,6 @@ def pilinfo(out: IO[str] | None = None, supported_formats: bool = True) -> None:
|
|||
("freetype2", "FREETYPE2"),
|
||||
("littlecms2", "LITTLECMS2"),
|
||||
("webp", "WEBP"),
|
||||
("webp_anim", "WEBP Animation"),
|
||||
("jpg", "JPEG"),
|
||||
("jpg_2000", "OPENJPEG (JPEG2000)"),
|
||||
("zlib", "ZLIB (PNG/ZIP)"),
|
||||
|
|
150
src/_webp.c
150
src/_webp.c
|
@ -13,8 +13,8 @@
|
|||
* very early versions had some significant differences, so we require later
|
||||
* versions, before enabling animation support.
|
||||
*/
|
||||
#if WEBP_MUX_ABI_VERSION >= 0x0104 && WEBP_DEMUX_ABI_VERSION >= 0x0105
|
||||
#define HAVE_WEBPANIM
|
||||
#if WEBP_MUX_ABI_VERSION < 0x0106 || WEBP_DEMUX_ABI_VERSION < 0x0107
|
||||
#error libwebp 0.5.0 and above is required. Upgrade libwebp or build with --disable-webp flag
|
||||
#endif
|
||||
|
||||
void
|
||||
|
@ -87,8 +87,6 @@ HandleMuxError(WebPMuxError err, char *chunk) {
|
|||
/* WebP Animation Support */
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
#ifdef HAVE_WEBPANIM
|
||||
|
||||
// Encoder type
|
||||
typedef struct {
|
||||
PyObject_HEAD WebPAnimEncoder *enc;
|
||||
|
@ -568,8 +566,6 @@ static PyTypeObject WebPAnimDecoder_Type = {
|
|||
0, /*tp_getset*/
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* Legacy WebP Support */
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
@ -644,10 +640,7 @@ WebPEncode_wrapper(PyObject *self, PyObject *args) {
|
|||
config.quality = quality_factor;
|
||||
config.alpha_quality = alpha_quality_factor;
|
||||
config.method = method;
|
||||
#if WEBP_ENCODER_ABI_VERSION >= 0x0209
|
||||
// the "exact" flag is only available in libwebp 0.5.0 and later
|
||||
config.exact = exact;
|
||||
#endif
|
||||
|
||||
// Validate the config
|
||||
if (!WebPValidateConfig(&config)) {
|
||||
|
@ -763,124 +756,6 @@ WebPEncode_wrapper(PyObject *self, PyObject *args) {
|
|||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyObject *
|
||||
WebPDecode_wrapper(PyObject *self, PyObject *args) {
|
||||
PyBytesObject *webp_string;
|
||||
const uint8_t *webp;
|
||||
Py_ssize_t size;
|
||||
PyObject *ret = Py_None, *bytes = NULL, *pymode = NULL, *icc_profile = NULL,
|
||||
*exif = NULL;
|
||||
WebPDecoderConfig config;
|
||||
VP8StatusCode vp8_status_code = VP8_STATUS_OK;
|
||||
char *mode = "RGB";
|
||||
|
||||
if (!PyArg_ParseTuple(args, "S", &webp_string)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!WebPInitDecoderConfig(&config)) {
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyBytes_AsStringAndSize((PyObject *)webp_string, (char **)&webp, &size);
|
||||
|
||||
vp8_status_code = WebPGetFeatures(webp, size, &config.input);
|
||||
if (vp8_status_code == VP8_STATUS_OK) {
|
||||
// If we don't set it, we don't get alpha.
|
||||
// Initialized to MODE_RGB
|
||||
if (config.input.has_alpha) {
|
||||
config.output.colorspace = MODE_RGBA;
|
||||
mode = "RGBA";
|
||||
}
|
||||
|
||||
{
|
||||
int copy_data = 0;
|
||||
WebPData data = {webp, size};
|
||||
WebPMuxFrameInfo image;
|
||||
WebPData icc_profile_data = {0};
|
||||
WebPData exif_data = {0};
|
||||
|
||||
WebPMux *mux = WebPMuxCreate(&data, copy_data);
|
||||
if (NULL == mux) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (WEBP_MUX_OK != WebPMuxGetFrame(mux, 1, &image)) {
|
||||
WebPMuxDelete(mux);
|
||||
goto end;
|
||||
}
|
||||
|
||||
webp = image.bitstream.bytes;
|
||||
size = image.bitstream.size;
|
||||
|
||||
vp8_status_code = WebPDecode(webp, size, &config);
|
||||
|
||||
if (WEBP_MUX_OK == WebPMuxGetChunk(mux, "ICCP", &icc_profile_data)) {
|
||||
icc_profile = PyBytes_FromStringAndSize(
|
||||
(const char *)icc_profile_data.bytes, icc_profile_data.size
|
||||
);
|
||||
}
|
||||
|
||||
if (WEBP_MUX_OK == WebPMuxGetChunk(mux, "EXIF", &exif_data)) {
|
||||
exif = PyBytes_FromStringAndSize(
|
||||
(const char *)exif_data.bytes, exif_data.size
|
||||
);
|
||||
}
|
||||
|
||||
WebPDataClear(&image.bitstream);
|
||||
WebPMuxDelete(mux);
|
||||
}
|
||||
}
|
||||
|
||||
if (vp8_status_code != VP8_STATUS_OK) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (config.output.colorspace < MODE_YUV) {
|
||||
bytes = PyBytes_FromStringAndSize(
|
||||
(char *)config.output.u.RGBA.rgba, config.output.u.RGBA.size
|
||||
);
|
||||
} else {
|
||||
// Skipping YUV for now. Need Test Images.
|
||||
// UNDONE -- unclear if we'll ever get here if we set mode_rgb*
|
||||
bytes = PyBytes_FromStringAndSize(
|
||||
(char *)config.output.u.YUVA.y, config.output.u.YUVA.y_size
|
||||
);
|
||||
}
|
||||
|
||||
pymode = PyUnicode_FromString(mode);
|
||||
ret = Py_BuildValue(
|
||||
"SiiSSS",
|
||||
bytes,
|
||||
config.output.width,
|
||||
config.output.height,
|
||||
pymode,
|
||||
NULL == icc_profile ? Py_None : icc_profile,
|
||||
NULL == exif ? Py_None : exif
|
||||
);
|
||||
|
||||
end:
|
||||
WebPFreeDecBuffer(&config.output);
|
||||
|
||||
Py_XDECREF(bytes);
|
||||
Py_XDECREF(pymode);
|
||||
Py_XDECREF(icc_profile);
|
||||
Py_XDECREF(exif);
|
||||
|
||||
if (Py_None == ret) {
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Return the decoder's version number, packed in hexadecimal using 8bits for
|
||||
// each of major/minor/revision. E.g: v2.5.7 is 0x020507.
|
||||
PyObject *
|
||||
WebPDecoderVersion_wrapper() {
|
||||
return Py_BuildValue("i", WebPGetDecoderVersion());
|
||||
}
|
||||
|
||||
// Version as string
|
||||
const char *
|
||||
WebPDecoderVersion_str(void) {
|
||||
|
@ -901,39 +776,20 @@ WebPDecoderVersion_str(void) {
|
|||
/* -------------------------------------------------------------------- */
|
||||
|
||||
static PyMethodDef webpMethods[] = {
|
||||
#ifdef HAVE_WEBPANIM
|
||||
{"WebPAnimDecoder", _anim_decoder_new, METH_VARARGS, "WebPAnimDecoder"},
|
||||
{"WebPAnimEncoder", _anim_encoder_new, METH_VARARGS, "WebPAnimEncoder"},
|
||||
#endif
|
||||
{"WebPEncode", WebPEncode_wrapper, METH_VARARGS, "WebPEncode"},
|
||||
{"WebPDecode", WebPDecode_wrapper, METH_VARARGS, "WebPDecode"},
|
||||
{"WebPDecoderVersion", WebPDecoderVersion_wrapper, METH_NOARGS, "WebPVersion"},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
void
|
||||
addAnimFlagToModule(PyObject *m) {
|
||||
PyObject *have_webpanim;
|
||||
#ifdef HAVE_WEBPANIM
|
||||
have_webpanim = Py_True;
|
||||
#else
|
||||
have_webpanim = Py_False;
|
||||
#endif
|
||||
Py_INCREF(have_webpanim);
|
||||
PyModule_AddObject(m, "HAVE_WEBPANIM", have_webpanim);
|
||||
}
|
||||
|
||||
static int
|
||||
setup_module(PyObject *m) {
|
||||
#ifdef HAVE_WEBPANIM
|
||||
PyObject *d = PyModule_GetDict(m);
|
||||
/* Ready object types */
|
||||
if (PyType_Ready(&WebPAnimDecoder_Type) < 0 ||
|
||||
PyType_Ready(&WebPAnimEncoder_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
PyObject *d = PyModule_GetDict(m);
|
||||
addAnimFlagToModule(m);
|
||||
|
||||
PyObject *v = PyUnicode_FromString(WebPDecoderVersion_str());
|
||||
PyDict_SetItemString(d, "webpdecoder_version", v ? v : Py_None);
|
||||
|
|
Loading…
Reference in New Issue
Block a user