mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-12-27 10:26:19 +03:00
Merge pull request #2520 from wiredfool/features
Updated Features detection
This commit is contained in:
commit
9d46f4f282
|
@ -3,7 +3,7 @@
|
|||
set -e
|
||||
|
||||
sudo apt-get update
|
||||
sudo apt-get -qq install libfreetype6-dev liblcms2-dev\
|
||||
sudo apt-get -qq install libfreetype6-dev liblcms2-dev python-tk \
|
||||
python-qt4 ghostscript libffi-dev libjpeg-turbo-progs cmake imagemagick
|
||||
pip install cffi
|
||||
pip install nose
|
||||
|
|
|
@ -2,45 +2,26 @@ from . import Image
|
|||
|
||||
modules = {
|
||||
"pil": "PIL._imaging",
|
||||
"tkinter": "PIL._imagingtk",
|
||||
"tkinter": "PIL._tkinter_finder",
|
||||
"freetype2": "PIL._imagingft",
|
||||
"littlecms2": "PIL._imagingcms",
|
||||
"webp": "PIL._webp",
|
||||
"transp_webp": ("WEBP", "WebPDecoderBuggyAlpha")
|
||||
}
|
||||
|
||||
|
||||
def check_module(feature):
|
||||
if feature not in modules:
|
||||
if not (feature in modules):
|
||||
raise ValueError("Unknown module %s" % feature)
|
||||
|
||||
module = modules[feature]
|
||||
|
||||
method_to_call = None
|
||||
if isinstance(module, tuple):
|
||||
module, method_to_call = module
|
||||
|
||||
try:
|
||||
imported_module = __import__(module)
|
||||
except ImportError:
|
||||
# If a method is being checked, None means that
|
||||
# rather than the method failing, the module required for the method
|
||||
# failed to be imported first
|
||||
return None if method_to_call else False
|
||||
|
||||
if method_to_call:
|
||||
method = getattr(imported_module, method_to_call)
|
||||
return method() is True
|
||||
else:
|
||||
return True
|
||||
|
||||
except ImportError:
|
||||
return False
|
||||
|
||||
def get_supported_modules():
|
||||
supported_modules = []
|
||||
for feature in modules:
|
||||
if check_module(feature):
|
||||
supported_modules.append(feature)
|
||||
return supported_modules
|
||||
return [f for f in modules if check_module(f)]
|
||||
|
||||
codecs = {
|
||||
"jpg": "jpeg",
|
||||
|
@ -49,7 +30,6 @@ codecs = {
|
|||
"libtiff": "libtiff"
|
||||
}
|
||||
|
||||
|
||||
def check_codec(feature):
|
||||
if feature not in codecs:
|
||||
raise ValueError("Unknown codec %s" % feature)
|
||||
|
@ -60,8 +40,38 @@ def check_codec(feature):
|
|||
|
||||
|
||||
def get_supported_codecs():
|
||||
supported_codecs = []
|
||||
for feature in codecs:
|
||||
if check_codec(feature):
|
||||
supported_codecs.append(feature)
|
||||
return supported_codecs
|
||||
return [f for f in codecs if check_codec(f)]
|
||||
|
||||
features = {
|
||||
"webp_mux": ("PIL._webp", 'HAVE_WEBPMUX'),
|
||||
"transp_webp": ("PIL._webp", "HAVE_TRANSPARENCY"),
|
||||
}
|
||||
|
||||
def check_feature(feature):
|
||||
if feature not in features:
|
||||
raise ValueError("Unknown feature %s" % feature)
|
||||
|
||||
module, flag = features[feature]
|
||||
|
||||
try:
|
||||
imported_module = __import__(module, fromlist=['PIL'])
|
||||
return getattr(imported_module, flag)
|
||||
except ImportError:
|
||||
return None
|
||||
|
||||
|
||||
def get_supported_features():
|
||||
return [f for f in features if check_feature(f)]
|
||||
|
||||
|
||||
def check(feature):
|
||||
return (feature in modules and check_module(feature) or \
|
||||
feature in codecs and check_codec(feature) or \
|
||||
feature in features and check_feature(feature))
|
||||
|
||||
def get_supported():
|
||||
ret = get_supported_modules()
|
||||
ret.extend(get_supported_features())
|
||||
ret.extend(get_supported_codecs())
|
||||
return ret
|
||||
|
||||
|
|
|
@ -2,19 +2,50 @@ from helper import unittest, PillowTestCase
|
|||
|
||||
from PIL import features
|
||||
|
||||
try:
|
||||
from PIL import _webp
|
||||
HAVE_WEBP = True
|
||||
except:
|
||||
HAVE_WEBP = False
|
||||
|
||||
|
||||
class TestFeatures(PillowTestCase):
|
||||
|
||||
def test_check_features(self):
|
||||
def test_check(self):
|
||||
# Check the correctness of the convenience function
|
||||
for module in features.modules:
|
||||
self.assertEqual(features.check_module(module),
|
||||
features.check(module))
|
||||
for codec in features.codecs:
|
||||
self.assertEqual(features.check_codec(codec),
|
||||
features.check(codec))
|
||||
for feature in features.features:
|
||||
self.assertEqual(features.check_feature(feature),
|
||||
features.check(feature))
|
||||
|
||||
@unittest.skipUnless(HAVE_WEBP, True)
|
||||
def check_webp_transparency(self):
|
||||
self.assertEqual(features.check('transp_webp'),
|
||||
not _webp.WebPDecoderBuggyAlpha())
|
||||
self.assertEqual(features.check('transp_webp'),
|
||||
_webp.HAVE_TRANSPARENCY)
|
||||
|
||||
@unittest.skipUnless(HAVE_WEBP, True)
|
||||
def check_webp_mux(self):
|
||||
self.assertEqual(features.check('webp_mux'),
|
||||
_webp.HAVE_WEBPMUX)
|
||||
|
||||
def test_check_modules(self):
|
||||
for feature in features.modules:
|
||||
self.assertIn(
|
||||
features.check_module(feature), [True, False, None])
|
||||
self.assertIn(features.check_module(feature), [True, False])
|
||||
for feature in features.codecs:
|
||||
self.assertIn(features.check_codec(feature), [True, False])
|
||||
|
||||
def test_supported_features(self):
|
||||
def test_supported_modules(self):
|
||||
self.assertIsInstance(features.get_supported_modules(), list)
|
||||
self.assertIsInstance(features.get_supported_codecs(), list)
|
||||
self.assertIsInstance(features.get_supported_features(), list)
|
||||
self.assertIsInstance(features.get_supported(), list)
|
||||
|
||||
def test_unsupported_codec(self):
|
||||
# Arrange
|
||||
|
|
13
_webp.c
13
_webp.c
|
@ -247,8 +247,12 @@ PyObject* WebPDecoderVersion_wrapper(PyObject* self, PyObject* args){
|
|||
* 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.
|
||||
*/
|
||||
int WebPDecoderBuggyAlpha() {
|
||||
return WebPGetDecoderVersion()==0x0103;
|
||||
}
|
||||
|
||||
PyObject* WebPDecoderBuggyAlpha_wrapper(PyObject* self, PyObject* args){
|
||||
return Py_BuildValue("i", WebPGetDecoderVersion()==0x0103);
|
||||
return Py_BuildValue("i", WebPDecoderBuggyAlpha());
|
||||
}
|
||||
|
||||
static PyMethodDef webpMethods[] =
|
||||
|
@ -268,6 +272,11 @@ void addMuxFlagToModule(PyObject* m) {
|
|||
#endif
|
||||
}
|
||||
|
||||
void addTransparencyFlagToModule(PyObject* m) {
|
||||
PyModule_AddObject(m, "HAVE_TRANSPARENCY",
|
||||
PyBool_FromLong(!WebPDecoderBuggyAlpha()));
|
||||
}
|
||||
|
||||
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
PyMODINIT_FUNC
|
||||
|
@ -284,6 +293,7 @@ PyInit__webp(void) {
|
|||
|
||||
m = PyModule_Create(&module_def);
|
||||
addMuxFlagToModule(m);
|
||||
addTransparencyFlagToModule(m);
|
||||
return m;
|
||||
}
|
||||
#else
|
||||
|
@ -292,5 +302,6 @@ init_webp(void)
|
|||
{
|
||||
PyObject* m = Py_InitModule("_webp", webpMethods);
|
||||
addMuxFlagToModule(m);
|
||||
addTransparencyFlagToModule(m);
|
||||
}
|
||||
#endif
|
||||
|
|
17
selftest.py
17
selftest.py
|
@ -178,25 +178,14 @@ if __name__ == "__main__":
|
|||
("freetype2", "FREETYPE2"),
|
||||
("littlecms2", "LITTLECMS2"),
|
||||
("webp", "WEBP"),
|
||||
("transp_webp", "Transparent WEBP")
|
||||
]:
|
||||
supported = features.check_module(name)
|
||||
|
||||
if supported is None:
|
||||
# A method was being tested, but the module required
|
||||
# for the method could not be correctly imported
|
||||
pass
|
||||
elif supported:
|
||||
print("---", feature, "support ok")
|
||||
else:
|
||||
print("***", feature, "support not installed")
|
||||
for name, feature in [
|
||||
("transp_webp", "Transparent WEBP"),
|
||||
("webp_mux", "WEBPMUX"),
|
||||
("jpg", "JPEG"),
|
||||
("jpg_2000", "OPENJPEG (JPEG2000)"),
|
||||
("zlib", "ZLIB (PNG/ZIP)"),
|
||||
("libtiff", "LIBTIFF")
|
||||
]:
|
||||
if features.check_codec(name):
|
||||
if features.check(name):
|
||||
print("---", feature, "support ok")
|
||||
else:
|
||||
print("***", feature, "support not installed")
|
||||
|
|
Loading…
Reference in New Issue
Block a user