mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-12-24 00:46:16 +03:00
check run-time version numbers where available, add docs
This commit is contained in:
parent
a324f4a466
commit
6c1ff252d6
|
@ -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
|
||||
|
|
|
@ -8,11 +8,11 @@ import PIL
|
|||
from . import Image
|
||||
|
||||
modules = {
|
||||
"pil": ("PIL._imaging", None),
|
||||
"pil": ("PIL._imaging", "PILLOW_VERSION"),
|
||||
"tkinter": ("PIL._tkinter_finder", None),
|
||||
"freetype2": ("PIL._imagingft", "freetype2"),
|
||||
"littlecms2": ("PIL._imagingcms", "littlecms"),
|
||||
"webp": ("PIL._webp", 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, lib = modules[feature]
|
||||
module, ver = modules[feature]
|
||||
|
||||
try:
|
||||
__import__(module)
|
||||
|
@ -37,17 +37,21 @@ def check_module(feature):
|
|||
|
||||
|
||||
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, lib = modules[feature]
|
||||
module, ver = modules[feature]
|
||||
|
||||
if lib is None:
|
||||
if ver is None:
|
||||
return None
|
||||
|
||||
attr = lib + "_version"
|
||||
|
||||
return getattr(__import__(module, fromlist=[attr]), attr)
|
||||
return getattr(__import__(module, fromlist=[ver]), ver)
|
||||
|
||||
|
||||
def get_supported_modules():
|
||||
|
@ -82,6 +86,13 @@ def check_codec(feature):
|
|||
|
||||
|
||||
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
|
||||
|
||||
|
@ -103,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),
|
||||
}
|
||||
|
||||
|
||||
|
@ -124,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"])
|
||||
|
@ -133,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.
|
||||
|
@ -142,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.
|
||||
"""
|
||||
|
||||
|
@ -159,10 +187,18 @@ def check(feature):
|
|||
|
||||
|
||||
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
|
||||
|
||||
|
||||
|
@ -228,12 +264,15 @@ def pilinfo(out=None, supported_formats=True):
|
|||
("xcb", "XCB (X protocol)"),
|
||||
]:
|
||||
if check(name):
|
||||
v = version(name)
|
||||
if v is not None:
|
||||
support = "ok (version {})".format(v)
|
||||
if name == "jpg" and check_feature("libjpeg_turbo"):
|
||||
v = "libjpeg-turbo " + version_feature("libjpeg_turbo")
|
||||
else:
|
||||
support = "ok"
|
||||
print("---", feature, "support", support, file=out)
|
||||
v = version(name)
|
||||
if v is not None:
|
||||
t = "compiled for" if name in ("pil", "jpg") else "loaded"
|
||||
print("---", feature, "support ok,", t, "version", v, file=out)
|
||||
else:
|
||||
print("---", feature, "support ok", file=out)
|
||||
else:
|
||||
print("***", feature, "support not installed", file=out)
|
||||
print("-" * 68, 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");
|
||||
|
@ -1251,6 +1255,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