diff --git a/PIL/IcnsImagePlugin.py b/PIL/IcnsImagePlugin.py index cf4db20e5..2dd4e1a51 100644 --- a/PIL/IcnsImagePlugin.py +++ b/PIL/IcnsImagePlugin.py @@ -15,9 +15,13 @@ # See the README file for information on usage and redistribution. # -from PIL import Image, ImageFile, PngImagePlugin, Jpeg2KImagePlugin, _binary +from PIL import Image, ImageFile, PngImagePlugin, _binary import struct, io +enable_jpeg2k = hasattr(Image.core, 'jp2klib_version') +if enable_jpeg2k: + import Jpeg2KImagePlugin + i8 = _binary.i8 HEADERSIZE = 8 @@ -101,6 +105,8 @@ def read_png_or_jpeg2000(fobj, start_length, size): elif sig[:4] == b'\xff\x4f\xff\x51' \ or sig[:4] == b'\x0d\x0a\x87\x0a' \ or sig == b'\x00\x00\x00\x0cjP \x0d\x0a\x87\x0a': + if not enable_jpeg2k: + raise ValueError('Unsupported icon subimage format (rebuild PIL with JPEG 2000 support to fix this)') # j2k, jpc or j2c fobj.seek(start) jp2kstream = fobj.read(length) @@ -109,6 +115,8 @@ def read_png_or_jpeg2000(fobj, start_length, size): if im.mode != 'RGBA': im = im.convert('RGBA') return {"RGBA": im} + else: + raise ValueError('Unsupported icon subimage format') class IcnsFile: diff --git a/Tests/images/pillow3.icns b/Tests/images/pillow3.icns new file mode 100644 index 000000000..ef9b89178 Binary files /dev/null and b/Tests/images/pillow3.icns differ diff --git a/Tests/test_file_icns.py b/Tests/test_file_icns.py index dbffb2401..3e31f8879 100644 --- a/Tests/test_file_icns.py +++ b/Tests/test_file_icns.py @@ -6,6 +6,8 @@ from PIL import Image file = "Images/pillow.icns" data = open(file, "rb").read() +enable_jpeg2k = hasattr(Image.core, 'jp2klib_version') + def test_sanity(): # Loading this icon by default should result in the largest size # (512x512@2x) being loaded @@ -40,3 +42,25 @@ def test_older_icon(): im2.load() assert_equal(im2.mode, 'RGBA') assert_equal(im2.size, (wr, hr)) + +def test_jp2_icon(): + # This icon was made by using Uli Kusterer's oldiconutil to replace + # the PNG images with JPEG 2000 ones. The advantage of doing this is + # that OS X 10.5 supports JPEG 2000 but not PNG; some commercial + # software therefore does just this. + + # (oldiconutil is here: https://github.com/uliwitness/oldiconutil) + + if not enable_jpeg2k: + return + + im = Image.open('Tests/images/pillow3.icns') + for w,h,r in im.info['sizes']: + wr = w * r + hr = h * r + im2 = Image.open('Tests/images/pillow3.icns') + im2.size = (w, h, r) + im2.load() + assert_equal(im2.mode, 'RGBA') + assert_equal(im2.size, (wr, hr)) +