diff --git a/Tests/test_file_webp.py b/Tests/test_file_webp.py index fa01cf93e..d815ab09a 100644 --- a/Tests/test_file_webp.py +++ b/Tests/test_file_webp.py @@ -1,6 +1,6 @@ from helper import unittest, PillowTestCase, hopper -from PIL import Image +from PIL import Image, WebPImagePlugin try: from PIL import _webp @@ -13,15 +13,27 @@ class TestFileWebp(PillowTestCase): def setUp(self): if not HAVE_WEBP: - self.skipTest('WebP support not installed') return self.rgb_mode = "RGB" + def test_unsupported(self): + if HAVE_WEBP: + WebPImagePlugin.SUPPORTED = False + + file_path = "Tests/images/hopper.webp" + self.assert_warning(UserWarning, + lambda: self.assertRaises(IOError, Image.open, file_path)) + + if HAVE_WEBP: + WebPImagePlugin.SUPPORTED = True + + @unittest.skipIf(not HAVE_WEBP, "WebP support not installed") def test_version(self): _webp.WebPDecoderVersion() _webp.WebPDecoderBuggyAlpha() + @unittest.skipIf(not HAVE_WEBP, "WebP support not installed") def test_read_rgb(self): """ Can we read a RGB mode WebP file without error? @@ -41,6 +53,7 @@ class TestFileWebp(PillowTestCase): self.assert_image_similar_tofile( image, 'Tests/images/hopper_webp_bits.ppm', 1.0) + @unittest.skipIf(not HAVE_WEBP, "WebP support not installed") def test_write_rgb(self): """ Can we write a RGB mode file to webp without error. @@ -70,6 +83,7 @@ class TestFileWebp(PillowTestCase): target = hopper(self.rgb_mode) self.assert_image_similar(image, target, 12.0) + @unittest.skipIf(not HAVE_WEBP, "WebP support not installed") def test_write_unsupported_mode_L(self): """ Saving a black-and-white file to WebP format should work, and be @@ -90,6 +104,7 @@ class TestFileWebp(PillowTestCase): self.assert_image_similar(image, target, 10.0) + @unittest.skipIf(not HAVE_WEBP, "WebP support not installed") def test_write_unsupported_mode_P(self): """ Saving a palette-based file to WebP format should work, and be @@ -110,6 +125,7 @@ class TestFileWebp(PillowTestCase): self.assert_image_similar(image, target, 50.0) + @unittest.skipIf(not HAVE_WEBP, "WebP support not installed") def test_WebPEncode_with_invalid_args(self): """ Calling encoder functions with no arguments should result in an error. @@ -119,6 +135,7 @@ class TestFileWebp(PillowTestCase): self.assertRaises(TypeError, _webp.WebPAnimEncoder) self.assertRaises(TypeError, _webp.WebPEncode) + @unittest.skipIf(not HAVE_WEBP, "WebP support not installed") def test_WebPDecode_with_invalid_args(self): """ Calling decoder functions with no arguments should result in an error. @@ -128,6 +145,7 @@ class TestFileWebp(PillowTestCase): self.assertRaises(TypeError, _webp.WebPAnimDecoder) self.assertRaises(TypeError, _webp.WebPDecode) + @unittest.skipIf(not HAVE_WEBP, "WebP support not installed") def test_no_resource_warning(self): file_path = "Tests/images/hopper.webp" image = Image.open(file_path) diff --git a/src/PIL/Image.py b/src/PIL/Image.py index 3631c78eb..88a677b5e 100644 --- a/src/PIL/Image.py +++ b/src/PIL/Image.py @@ -2615,11 +2615,15 @@ def open(fp, mode="r"): preinit() + accept_warnings = [] def _open_core(fp, filename, prefix): for i in ID: try: factory, accept = OPEN[i] - if not accept or accept(prefix): + result = not accept or accept(prefix) + if type(result) in [str, bytes]: + accept_warnings.append(result) + elif result: fp.seek(0) im = factory(fp, filename) _decompression_bomb_check(im.size) @@ -2643,6 +2647,8 @@ def open(fp, mode="r"): if exclusive_fp: fp.close() + for message in accept_warnings: + warnings.warn(message) raise IOError("cannot identify image file %r" % (filename if filename else fp)) diff --git a/src/PIL/WebPImagePlugin.py b/src/PIL/WebPImagePlugin.py index 08c6b26ac..7a5f8cdad 100644 --- a/src/PIL/WebPImagePlugin.py +++ b/src/PIL/WebPImagePlugin.py @@ -1,4 +1,9 @@ -from . import Image, ImageFile, _webp +from . import Image, ImageFile +try: + from . import _webp + SUPPORTED = True +except ImportError as e: + SUPPORTED = False from io import BytesIO @@ -25,7 +30,10 @@ def _accept(prefix): is_webp_file = prefix[8:12] == b"WEBP" is_valid_vp8_mode = prefix[12:16] in _VP8_MODES_BY_IDENTIFIER - return is_riff_file_format and is_webp_file and is_valid_vp8_mode + if is_riff_file_format and is_webp_file and is_valid_vp8_mode: + if not SUPPORTED: + return "image file could not be identified because WEBP support not installed" + return True class WebPImageFile(ImageFile.ImageFile): @@ -321,8 +329,9 @@ def _save(im, fp, filename): Image.register_open(WebPImageFile.format, WebPImageFile, _accept) -Image.register_save(WebPImageFile.format, _save) -if _webp.HAVE_WEBPANIM: - Image.register_save_all(WebPImageFile.format, _save_all) -Image.register_extension(WebPImageFile.format, ".webp") -Image.register_mime(WebPImageFile.format, "image/webp") +if SUPPORTED: + Image.register_save(WebPImageFile.format, _save) + if _webp.HAVE_WEBPANIM: + Image.register_save_all(WebPImageFile.format, _save_all) + Image.register_extension(WebPImageFile.format, ".webp") + Image.register_mime(WebPImageFile.format, "image/webp")