mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-01-13 18:56:17 +03:00
Merge pull request #4700 from nulano/features-version
This commit is contained in:
commit
1bc67c9f0f
|
@ -1,4 +1,5 @@
|
|||
import io
|
||||
import re
|
||||
|
||||
import pytest
|
||||
from PIL import features
|
||||
|
@ -21,6 +22,27 @@ def test_check():
|
|||
assert features.check_feature(feature) == features.check(feature)
|
||||
|
||||
|
||||
def test_version():
|
||||
# Check the correctness of the convenience function
|
||||
# and the format of version numbers
|
||||
|
||||
def test(name, function):
|
||||
version = features.version(name)
|
||||
if not features.check(name):
|
||||
assert version is None
|
||||
else:
|
||||
assert function(name) == version
|
||||
if name != "PIL":
|
||||
assert version is None or re.search(r"\d+(\.\d+)*$", version)
|
||||
|
||||
for module in features.modules:
|
||||
test(module, features.version_module)
|
||||
for codec in features.codecs:
|
||||
test(codec, features.version_codec)
|
||||
for feature in features.features:
|
||||
test(feature, features.version_feature)
|
||||
|
||||
|
||||
@skip_unless_feature("webp")
|
||||
def test_webp_transparency():
|
||||
assert features.check("transp_webp") != _webp.WebPDecoderBuggyAlpha()
|
||||
|
@ -37,9 +59,22 @@ def test_webp_anim():
|
|||
assert features.check("webp_anim") == _webp.HAVE_WEBPANIM
|
||||
|
||||
|
||||
@skip_unless_feature("libjpeg_turbo")
|
||||
def test_libjpeg_turbo_version():
|
||||
assert re.search(r"\d+\.\d+\.\d+$", features.version("libjpeg_turbo"))
|
||||
|
||||
|
||||
@skip_unless_feature("libimagequant")
|
||||
def test_libimagequant_version():
|
||||
assert re.search(r"\d+\.\d+\.\d+$", features.version("libimagequant"))
|
||||
|
||||
|
||||
def test_check_modules():
|
||||
for feature in features.modules:
|
||||
assert features.check_module(feature) in [True, False]
|
||||
|
||||
|
||||
def test_check_codecs():
|
||||
for feature in features.codecs:
|
||||
assert features.check_codec(feature) in [True, False]
|
||||
|
||||
|
@ -64,6 +99,8 @@ def test_unsupported_codec():
|
|||
# Act / Assert
|
||||
with pytest.raises(ValueError):
|
||||
features.check_codec(codec)
|
||||
with pytest.raises(ValueError):
|
||||
features.version_codec(codec)
|
||||
|
||||
|
||||
def test_unsupported_module():
|
||||
|
@ -72,6 +109,8 @@ def test_unsupported_module():
|
|||
# Act / Assert
|
||||
with pytest.raises(ValueError):
|
||||
features.check_module(module)
|
||||
with pytest.raises(ValueError):
|
||||
features.version_module(module)
|
||||
|
||||
|
||||
def test_pilinfo():
|
||||
|
|
|
@ -2,14 +2,14 @@ import io
|
|||
import sys
|
||||
|
||||
import pytest
|
||||
from PIL import IcnsImagePlugin, Image
|
||||
from PIL import IcnsImagePlugin, Image, features
|
||||
|
||||
from .helper import assert_image_equal, assert_image_similar
|
||||
|
||||
# sample icon file
|
||||
TEST_FILE = "Tests/images/pillow.icns"
|
||||
|
||||
ENABLE_JPEG2K = hasattr(Image.core, "jp2klib_version")
|
||||
ENABLE_JPEG2K = features.check_codec("jpg_2000")
|
||||
|
||||
|
||||
def test_sanity():
|
||||
|
|
|
@ -3,7 +3,7 @@ import re
|
|||
from io import BytesIO
|
||||
|
||||
import pytest
|
||||
from PIL import ExifTags, Image, ImageFile, JpegImagePlugin
|
||||
from PIL import ExifTags, Image, ImageFile, JpegImagePlugin, features
|
||||
|
||||
from .helper import (
|
||||
assert_image,
|
||||
|
@ -41,7 +41,7 @@ class TestFileJpeg:
|
|||
def test_sanity(self):
|
||||
|
||||
# internal version number
|
||||
assert re.search(r"\d+\.\d+$", Image.core.jpeglib_version)
|
||||
assert re.search(r"\d+\.\d+$", features.version_codec("jpg"))
|
||||
|
||||
with Image.open(TEST_FILE) as im:
|
||||
im.load()
|
||||
|
|
|
@ -2,7 +2,7 @@ import re
|
|||
from io import BytesIO
|
||||
|
||||
import pytest
|
||||
from PIL import Image, ImageFile, Jpeg2KImagePlugin
|
||||
from PIL import Image, ImageFile, Jpeg2KImagePlugin, features
|
||||
|
||||
from .helper import (
|
||||
assert_image_equal,
|
||||
|
@ -35,7 +35,7 @@ def roundtrip(im, **options):
|
|||
|
||||
def test_sanity():
|
||||
# Internal version number
|
||||
assert re.search(r"\d+\.\d+\.\d+$", Image.core.jp2klib_version)
|
||||
assert re.search(r"\d+\.\d+\.\d+$", features.version_codec("jpg_2000"))
|
||||
|
||||
with Image.open("Tests/images/test-card-lossless.jp2") as im:
|
||||
px = im.load()
|
||||
|
|
|
@ -3,11 +3,12 @@ import io
|
|||
import itertools
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
from collections import namedtuple
|
||||
from ctypes import c_float
|
||||
|
||||
import pytest
|
||||
from PIL import Image, ImageFilter, TiffImagePlugin, TiffTags
|
||||
from PIL import Image, ImageFilter, TiffImagePlugin, TiffTags, features
|
||||
|
||||
from .helper import (
|
||||
assert_image_equal,
|
||||
|
@ -47,6 +48,9 @@ class LibTiffTestCase:
|
|||
|
||||
|
||||
class TestFileLibTiff(LibTiffTestCase):
|
||||
def test_version(self):
|
||||
assert re.search(r"\d+\.\d+\.\d+$", features.version_codec("libtiff"))
|
||||
|
||||
def test_g4_tiff(self, tmp_path):
|
||||
"""Test the ordinary file path load path"""
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ import zlib
|
|||
from io import BytesIO
|
||||
|
||||
import pytest
|
||||
from PIL import Image, ImageFile, PngImagePlugin
|
||||
from PIL import Image, ImageFile, PngImagePlugin, features
|
||||
|
||||
from .helper import (
|
||||
PillowLeakTestCase,
|
||||
|
@ -73,7 +73,7 @@ class TestFilePng:
|
|||
def test_sanity(self, tmp_path):
|
||||
|
||||
# internal version number
|
||||
assert re.search(r"\d+\.\d+\.\d+(\.\d+)?$", Image.core.zlib_version)
|
||||
assert re.search(r"\d+\.\d+\.\d+(\.\d+)?$", features.version_codec("zlib"))
|
||||
|
||||
test_file = str(tmp_path / "temp.png")
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import io
|
||||
import re
|
||||
|
||||
import pytest
|
||||
from PIL import Image, WebPImagePlugin
|
||||
from PIL import Image, WebPImagePlugin, features
|
||||
|
||||
from .helper import (
|
||||
assert_image_similar,
|
||||
|
@ -38,6 +39,7 @@ class TestFileWebp:
|
|||
def test_version(self):
|
||||
_webp.WebPDecoderVersion()
|
||||
_webp.WebPDecoderBuggyAlpha()
|
||||
assert re.search(r"\d+\.\d+\.\d+$", features.version_module("webp"))
|
||||
|
||||
def test_read_rgb(self):
|
||||
"""
|
||||
|
|
|
@ -4,7 +4,7 @@ import re
|
|||
from io import BytesIO
|
||||
|
||||
import pytest
|
||||
from PIL import Image, ImageMode
|
||||
from PIL import Image, ImageMode, features
|
||||
|
||||
from .helper import assert_image, assert_image_equal, assert_image_similar, hopper
|
||||
|
||||
|
@ -46,7 +46,7 @@ def test_sanity():
|
|||
assert list(map(type, v)) == [str, str, str, str]
|
||||
|
||||
# internal version number
|
||||
assert re.search(r"\d+\.\d+$", ImageCms.core.littlecms_version)
|
||||
assert re.search(r"\d+\.\d+$", features.version_module("littlecms2"))
|
||||
|
||||
skip_missing()
|
||||
i = ImageCms.profileToProfile(hopper(), SRGB, SRGB)
|
||||
|
|
|
@ -7,7 +7,7 @@ import sys
|
|||
from io import BytesIO
|
||||
|
||||
import pytest
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
from PIL import Image, ImageDraw, ImageFont, features
|
||||
|
||||
from .helper import (
|
||||
assert_image_equal,
|
||||
|
@ -41,7 +41,7 @@ class TestImageFont:
|
|||
|
||||
@classmethod
|
||||
def setup_class(self):
|
||||
freetype = distutils.version.StrictVersion(ImageFont.core.freetype2_version)
|
||||
freetype = distutils.version.StrictVersion(features.version_module("freetype2"))
|
||||
|
||||
self.metrics = self.METRICS["Default"]
|
||||
for conditions, metrics in self.METRICS.items():
|
||||
|
@ -68,7 +68,7 @@ class TestImageFont:
|
|||
)
|
||||
|
||||
def test_sanity(self):
|
||||
assert re.search(r"\d+\.\d+\.\d+$", ImageFont.core.freetype2_version)
|
||||
assert re.search(r"\d+\.\d+\.\d+$", features.version_module("freetype2"))
|
||||
|
||||
def test_font_properties(self):
|
||||
ttf = self.get_font()
|
||||
|
@ -620,7 +620,7 @@ class TestImageFont:
|
|||
def test_variation_get(self):
|
||||
font = self.get_font()
|
||||
|
||||
freetype = distutils.version.StrictVersion(ImageFont.core.freetype2_version)
|
||||
freetype = distutils.version.StrictVersion(features.version_module("freetype2"))
|
||||
if freetype < "2.9.1":
|
||||
with pytest.raises(NotImplementedError):
|
||||
font.get_variation_names()
|
||||
|
@ -692,7 +692,7 @@ class TestImageFont:
|
|||
def test_variation_set_by_name(self):
|
||||
font = self.get_font()
|
||||
|
||||
freetype = distutils.version.StrictVersion(ImageFont.core.freetype2_version)
|
||||
freetype = distutils.version.StrictVersion(features.version_module("freetype2"))
|
||||
if freetype < "2.9.1":
|
||||
with pytest.raises(NotImplementedError):
|
||||
font.set_variation_by_name("Bold")
|
||||
|
@ -716,7 +716,7 @@ class TestImageFont:
|
|||
def test_variation_set_by_axes(self):
|
||||
font = self.get_font()
|
||||
|
||||
freetype = distutils.version.StrictVersion(ImageFont.core.freetype2_version)
|
||||
freetype = distutils.version.StrictVersion(features.version_module("freetype2"))
|
||||
if freetype < "2.9.1":
|
||||
with pytest.raises(NotImplementedError):
|
||||
font.set_variation_by_axes([100])
|
||||
|
|
|
@ -8,6 +8,7 @@ The :py:mod:`PIL.features` module can be used to detect which Pillow features ar
|
|||
|
||||
.. autofunction:: PIL.features.pilinfo
|
||||
.. autofunction:: PIL.features.check
|
||||
.. autofunction:: PIL.features.version
|
||||
.. autofunction:: PIL.features.get_supported
|
||||
|
||||
Modules
|
||||
|
@ -16,28 +17,31 @@ Modules
|
|||
Support for the following modules can be checked:
|
||||
|
||||
* ``pil``: The Pillow core module, required for all functionality.
|
||||
* ``tkinter``: Tkinter support.
|
||||
* ``tkinter``: Tkinter support. Version number not available.
|
||||
* ``freetype2``: FreeType font support via :py:func:`PIL.ImageFont.truetype`.
|
||||
* ``littlecms2``: LittleCMS 2 support via :py:mod:`PIL.ImageCms`.
|
||||
* ``webp``: WebP image support.
|
||||
|
||||
.. autofunction:: PIL.features.check_module
|
||||
.. autofunction:: PIL.features.version_module
|
||||
.. autofunction:: PIL.features.get_supported_modules
|
||||
|
||||
Codecs
|
||||
------
|
||||
|
||||
These are only checked during Pillow compilation.
|
||||
Support for these is only checked during Pillow compilation.
|
||||
If the required library was uninstalled from the system, the ``pil`` core module may fail to load instead.
|
||||
Except for ``jpg``, the version number is checked at run-time.
|
||||
|
||||
Support for the following codecs can be checked:
|
||||
|
||||
* ``jpg``: (compile time) Libjpeg support, required for JPEG based image formats.
|
||||
* ``jpg``: (compile time) Libjpeg support, required for JPEG based image formats. Only compile time version number is available.
|
||||
* ``jpg_2000``: (compile time) OpenJPEG support, required for JPEG 2000 image formats.
|
||||
* ``zlib``: (compile time) Zlib support, required for zlib compressed formats, such as PNG.
|
||||
* ``libtiff``: (compile time) LibTIFF support, required for TIFF based image formats.
|
||||
|
||||
.. autofunction:: PIL.features.check_codec
|
||||
.. autofunction:: PIL.features.version_codec
|
||||
.. autofunction:: PIL.features.get_supported_codecs
|
||||
|
||||
Features
|
||||
|
@ -45,16 +49,18 @@ Features
|
|||
|
||||
Some of these are only checked during Pillow compilation.
|
||||
If the required library was uninstalled from the system, the relevant module may fail to load instead.
|
||||
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.
|
||||
* ``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.
|
||||
* ``webp_mux``: (compile time) Support for EXIF data in 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`.
|
||||
* ``libimagequant``: (compile time) ImageQuant quantization support in :py:func:`PIL.Image.Image.quantize`.
|
||||
* ``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.
|
||||
|
||||
.. autofunction:: PIL.features.check_feature
|
||||
.. autofunction:: PIL.features.version_feature
|
||||
.. autofunction:: PIL.features.get_supported_features
|
||||
|
|
|
@ -23,10 +23,10 @@ import subprocess
|
|||
import sys
|
||||
import tempfile
|
||||
|
||||
from PIL import Image, ImageFile, PngImagePlugin
|
||||
from PIL import Image, ImageFile, PngImagePlugin, features
|
||||
from PIL._binary import i8
|
||||
|
||||
enable_jpeg2k = hasattr(Image.core, "jp2klib_version")
|
||||
enable_jpeg2k = features.check_codec("jpg_2000")
|
||||
if enable_jpeg2k:
|
||||
from PIL import Jpeg2KImagePlugin
|
||||
|
||||
|
|
|
@ -8,11 +8,11 @@ import PIL
|
|||
from . import Image
|
||||
|
||||
modules = {
|
||||
"pil": "PIL._imaging",
|
||||
"tkinter": "PIL._tkinter_finder",
|
||||
"freetype2": "PIL._imagingft",
|
||||
"littlecms2": "PIL._imagingcms",
|
||||
"webp": "PIL._webp",
|
||||
"pil": ("PIL._imaging", "PILLOW_VERSION"),
|
||||
"tkinter": ("PIL._tkinter_finder", None),
|
||||
"freetype2": ("PIL._imagingft", "freetype2_version"),
|
||||
"littlecms2": ("PIL._imagingcms", "littlecms_version"),
|
||||
"webp": ("PIL._webp", "webpdecoder_version"),
|
||||
}
|
||||
|
||||
|
||||
|
@ -27,7 +27,7 @@ def check_module(feature):
|
|||
if not (feature in modules):
|
||||
raise ValueError("Unknown module %s" % feature)
|
||||
|
||||
module = modules[feature]
|
||||
module, ver = modules[feature]
|
||||
|
||||
try:
|
||||
__import__(module)
|
||||
|
@ -36,6 +36,24 @@ def check_module(feature):
|
|||
return False
|
||||
|
||||
|
||||
def version_module(feature):
|
||||
"""
|
||||
:param feature: The module to check for.
|
||||
:returns:
|
||||
The loaded version number as a string, or ``None`` if unknown or not available.
|
||||
:raises ValueError: If the module is not defined in this version of Pillow.
|
||||
"""
|
||||
if not check_module(feature):
|
||||
return None
|
||||
|
||||
module, ver = modules[feature]
|
||||
|
||||
if ver is None:
|
||||
return None
|
||||
|
||||
return getattr(__import__(module, fromlist=[ver]), ver)
|
||||
|
||||
|
||||
def get_supported_modules():
|
||||
"""
|
||||
:returns: A list of all supported modules.
|
||||
|
@ -43,7 +61,12 @@ def get_supported_modules():
|
|||
return [f for f in modules if check_module(f)]
|
||||
|
||||
|
||||
codecs = {"jpg": "jpeg", "jpg_2000": "jpeg2k", "zlib": "zip", "libtiff": "libtiff"}
|
||||
codecs = {
|
||||
"jpg": ("jpeg", "jpeglib"),
|
||||
"jpg_2000": ("jpeg2k", "jp2klib"),
|
||||
"zlib": ("zip", "zlib"),
|
||||
"libtiff": ("libtiff", "libtiff"),
|
||||
}
|
||||
|
||||
|
||||
def check_codec(feature):
|
||||
|
@ -57,11 +80,32 @@ def check_codec(feature):
|
|||
if feature not in codecs:
|
||||
raise ValueError("Unknown codec %s" % feature)
|
||||
|
||||
codec = codecs[feature]
|
||||
codec, lib = codecs[feature]
|
||||
|
||||
return codec + "_encoder" in dir(Image.core)
|
||||
|
||||
|
||||
def version_codec(feature):
|
||||
"""
|
||||
:param feature: The codec to check for.
|
||||
:returns:
|
||||
The version number as a string, or ``None`` if not available.
|
||||
Checked at compile time for ``jpg``, run-time otherwise.
|
||||
:raises ValueError: If the codec is not defined in this version of Pillow.
|
||||
"""
|
||||
if not check_codec(feature):
|
||||
return None
|
||||
|
||||
codec, lib = codecs[feature]
|
||||
|
||||
version = getattr(Image.core, lib + "_version")
|
||||
|
||||
if feature == "libtiff":
|
||||
return version.split("\n")[0].split("Version ")[1]
|
||||
|
||||
return version
|
||||
|
||||
|
||||
def get_supported_codecs():
|
||||
"""
|
||||
:returns: A list of all supported codecs.
|
||||
|
@ -70,13 +114,13 @@ def get_supported_codecs():
|
|||
|
||||
|
||||
features = {
|
||||
"webp_anim": ("PIL._webp", "HAVE_WEBPANIM"),
|
||||
"webp_mux": ("PIL._webp", "HAVE_WEBPMUX"),
|
||||
"transp_webp": ("PIL._webp", "HAVE_TRANSPARENCY"),
|
||||
"raqm": ("PIL._imagingft", "HAVE_RAQM"),
|
||||
"libjpeg_turbo": ("PIL._imaging", "HAVE_LIBJPEGTURBO"),
|
||||
"libimagequant": ("PIL._imaging", "HAVE_LIBIMAGEQUANT"),
|
||||
"xcb": ("PIL._imaging", "HAVE_XCB"),
|
||||
"webp_anim": ("PIL._webp", "HAVE_WEBPANIM", None),
|
||||
"webp_mux": ("PIL._webp", "HAVE_WEBPMUX", None),
|
||||
"transp_webp": ("PIL._webp", "HAVE_TRANSPARENCY", None),
|
||||
"raqm": ("PIL._imagingft", "HAVE_RAQM", "raqm_version"),
|
||||
"libjpeg_turbo": ("PIL._imaging", "HAVE_LIBJPEGTURBO", "libjpeg_turbo_version"),
|
||||
"libimagequant": ("PIL._imaging", "HAVE_LIBIMAGEQUANT", "imagequant_version"),
|
||||
"xcb": ("PIL._imaging", "HAVE_XCB", None),
|
||||
}
|
||||
|
||||
|
||||
|
@ -91,7 +135,7 @@ def check_feature(feature):
|
|||
if feature not in features:
|
||||
raise ValueError("Unknown feature %s" % feature)
|
||||
|
||||
module, flag = features[feature]
|
||||
module, flag, ver = features[feature]
|
||||
|
||||
try:
|
||||
imported_module = __import__(module, fromlist=["PIL"])
|
||||
|
@ -100,6 +144,23 @@ def check_feature(feature):
|
|||
return None
|
||||
|
||||
|
||||
def version_feature(feature):
|
||||
"""
|
||||
:param feature: The feature to check for.
|
||||
:returns: The version number as a string, or ``None`` if not available.
|
||||
:raises ValueError: If the feature is not defined in this version of Pillow.
|
||||
"""
|
||||
if not check_feature(feature):
|
||||
return None
|
||||
|
||||
module, flag, ver = features[feature]
|
||||
|
||||
if ver is None:
|
||||
return None
|
||||
|
||||
return getattr(__import__(module, fromlist=[ver]), ver)
|
||||
|
||||
|
||||
def get_supported_features():
|
||||
"""
|
||||
:returns: A list of all supported features.
|
||||
|
@ -109,9 +170,9 @@ def get_supported_features():
|
|||
|
||||
def check(feature):
|
||||
"""
|
||||
:param feature: A module, feature, or codec name.
|
||||
:param feature: A module, codec, or feature name.
|
||||
:returns:
|
||||
``True`` if the module, feature, or codec is available,
|
||||
``True`` if the module, codec, or feature is available,
|
||||
``False`` or ``None`` otherwise.
|
||||
"""
|
||||
|
||||
|
@ -125,6 +186,22 @@ def check(feature):
|
|||
return False
|
||||
|
||||
|
||||
def version(feature):
|
||||
"""
|
||||
:param feature:
|
||||
The module, codec, or feature to check for.
|
||||
:returns:
|
||||
The version number as a string, or ``None`` if unknown or not available.
|
||||
"""
|
||||
if feature in modules:
|
||||
return version_module(feature)
|
||||
if feature in codecs:
|
||||
return version_codec(feature)
|
||||
if feature in features:
|
||||
return version_feature(feature)
|
||||
return None
|
||||
|
||||
|
||||
def get_supported():
|
||||
"""
|
||||
:returns: A list of all supported modules, features, and codecs.
|
||||
|
@ -187,6 +264,14 @@ def pilinfo(out=None, supported_formats=True):
|
|||
("xcb", "XCB (X protocol)"),
|
||||
]:
|
||||
if check(name):
|
||||
if name == "jpg" and check_feature("libjpeg_turbo"):
|
||||
v = "libjpeg-turbo " + version_feature("libjpeg_turbo")
|
||||
else:
|
||||
v = version(name)
|
||||
if v is not None:
|
||||
t = "compiled for" if name in ("pil", "jpg") else "loaded"
|
||||
print("---", feature, "support ok,", t, v, file=out)
|
||||
else:
|
||||
print("---", feature, "support ok", file=out)
|
||||
else:
|
||||
print("***", feature, "support not installed", file=out)
|
||||
|
|
|
@ -4168,12 +4168,21 @@ setup_module(PyObject* m) {
|
|||
|
||||
#ifdef LIBJPEG_TURBO_VERSION
|
||||
PyModule_AddObject(m, "HAVE_LIBJPEGTURBO", Py_True);
|
||||
#define tostr1(a) #a
|
||||
#define tostr(a) tostr1(a)
|
||||
PyDict_SetItemString(d, "libjpeg_turbo_version", PyUnicode_FromString(tostr(LIBJPEG_TURBO_VERSION)));
|
||||
#undef tostr
|
||||
#undef tostr1
|
||||
#else
|
||||
PyModule_AddObject(m, "HAVE_LIBJPEGTURBO", Py_False);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBIMAGEQUANT
|
||||
PyModule_AddObject(m, "HAVE_LIBIMAGEQUANT", Py_True);
|
||||
{
|
||||
extern const char* ImagingImageQuantVersion(void);
|
||||
PyDict_SetItemString(d, "imagequant_version", PyUnicode_FromString(ImagingImageQuantVersion()));
|
||||
}
|
||||
#else
|
||||
PyModule_AddObject(m, "HAVE_LIBIMAGEQUANT", Py_False);
|
||||
#endif
|
||||
|
|
|
@ -1608,6 +1608,7 @@ static int
|
|||
setup_module(PyObject* m) {
|
||||
PyObject *d;
|
||||
PyObject *v;
|
||||
int vn;
|
||||
|
||||
d = PyModule_GetDict(m);
|
||||
|
||||
|
@ -1622,7 +1623,8 @@ setup_module(PyObject* m) {
|
|||
|
||||
d = PyModule_GetDict(m);
|
||||
|
||||
v = PyUnicode_FromFormat("%d.%d", LCMS_VERSION / 100, LCMS_VERSION % 100);
|
||||
vn = cmsGetEncodedCMMversion();
|
||||
v = PyUnicode_FromFormat("%d.%d", vn / 100, vn % 100);
|
||||
PyDict_SetItemString(d, "littlecms_version", v);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -81,6 +81,7 @@ typedef struct {
|
|||
|
||||
static PyTypeObject Font_Type;
|
||||
|
||||
typedef const char* (*t_raqm_version_string) (void);
|
||||
typedef bool (*t_raqm_version_atleast)(unsigned int major,
|
||||
unsigned int minor,
|
||||
unsigned int micro);
|
||||
|
@ -112,6 +113,7 @@ typedef void (*t_raqm_destroy) (raqm_t *rq);
|
|||
typedef struct {
|
||||
void* raqm;
|
||||
int version;
|
||||
t_raqm_version_string version_string;
|
||||
t_raqm_version_atleast version_atleast;
|
||||
t_raqm_create create;
|
||||
t_raqm_set_text set_text;
|
||||
|
@ -173,6 +175,7 @@ setraqm(void)
|
|||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
p_raqm.version_string = (t_raqm_version_atleast)dlsym(p_raqm.raqm, "raqm_version_string");
|
||||
p_raqm.version_atleast = (t_raqm_version_atleast)dlsym(p_raqm.raqm, "raqm_version_atleast");
|
||||
p_raqm.create = (t_raqm_create)dlsym(p_raqm.raqm, "raqm_create");
|
||||
p_raqm.set_text = (t_raqm_set_text)dlsym(p_raqm.raqm, "raqm_set_text");
|
||||
|
@ -206,6 +209,7 @@ setraqm(void)
|
|||
return 2;
|
||||
}
|
||||
#else
|
||||
p_raqm.version_string = (t_raqm_version_atleast)GetProcAddress(p_raqm.raqm, "raqm_version_string");
|
||||
p_raqm.version_atleast = (t_raqm_version_atleast)GetProcAddress(p_raqm.raqm, "raqm_version_atleast");
|
||||
p_raqm.create = (t_raqm_create)GetProcAddress(p_raqm.raqm, "raqm_create");
|
||||
p_raqm.set_text = (t_raqm_set_text)GetProcAddress(p_raqm.raqm, "raqm_set_text");
|
||||
|
@ -1257,6 +1261,9 @@ setup_module(PyObject* m) {
|
|||
setraqm();
|
||||
v = PyBool_FromLong(!!p_raqm.raqm);
|
||||
PyDict_SetItemString(d, "HAVE_RAQM", v);
|
||||
if (p_raqm.version_string) {
|
||||
PyDict_SetItemString(d, "raqm_version", PyUnicode_FromString(p_raqm.version_string()));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
13
src/_webp.c
13
src/_webp.c
|
@ -821,6 +821,16 @@ PyObject* WebPDecoderVersion_wrapper() {
|
|||
return Py_BuildValue("i", WebPGetDecoderVersion());
|
||||
}
|
||||
|
||||
// Version as string
|
||||
const char*
|
||||
WebPDecoderVersion_str(void)
|
||||
{
|
||||
static char version[20];
|
||||
int version_number = WebPGetDecoderVersion();
|
||||
sprintf(version, "%d.%d.%d", version_number >> 16, (version_number >> 8) % 0x100, version_number % 0x100);
|
||||
return version;
|
||||
}
|
||||
|
||||
/*
|
||||
* The version of webp that ships with (0.1.3) Ubuntu 12.04 doesn't handle alpha well.
|
||||
* Files that are valid with 0.3 are reported as being invalid.
|
||||
|
@ -872,10 +882,13 @@ void addTransparencyFlagToModule(PyObject* m) {
|
|||
}
|
||||
|
||||
static int setup_module(PyObject* m) {
|
||||
PyObject* d = PyModule_GetDict(m);
|
||||
addMuxFlagToModule(m);
|
||||
addAnimFlagToModule(m);
|
||||
addTransparencyFlagToModule(m);
|
||||
|
||||
PyDict_SetItemString(d, "webpdecoder_version", PyUnicode_FromString(WebPDecoderVersion_str()));
|
||||
|
||||
#ifdef HAVE_WEBPANIM
|
||||
/* Ready object types */
|
||||
if (PyType_Ready(&WebPAnimDecoder_Type) < 0 ||
|
||||
|
|
|
@ -113,4 +113,13 @@ err:
|
|||
return result;
|
||||
}
|
||||
|
||||
const char*
|
||||
ImagingImageQuantVersion(void)
|
||||
{
|
||||
static char version[20];
|
||||
int number = liq_version();
|
||||
sprintf(version, "%d.%d.%d", number / 10000, (number / 100) % 100, number % 100);
|
||||
return version;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -373,7 +373,7 @@ ImagingZipEncodeCleanup(ImagingCodecState state) {
|
|||
const char*
|
||||
ImagingZipVersion(void)
|
||||
{
|
||||
return ZLIB_VERSION;
|
||||
return zlibVersion();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue
Block a user