Merge pull request #3836 from radarhere/ico_size

Handle unexpected ICO image sizes
This commit is contained in:
Hugo 2019-05-12 19:53:48 +03:00 committed by GitHub
commit feb413e0f3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 24 additions and 5 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -83,3 +83,10 @@ class TestFileIco(PillowTestCase):
self.assertEqual( self.assertEqual(
im_saved.info['sizes'], im_saved.info['sizes'],
{(16, 16), (24, 24), (32, 32), (48, 48)}) {(16, 16), (24, 24), (32, 32), (48, 48)})
def test_unexpected_size(self):
# This image has been manually hexedited to state that it is 16x32
# while the image within is still 16x16
im = self.assert_warning(UserWarning,
Image.open, "Tests/images/hopper_unexpected.ico")
self.assertEqual(im.size, (16, 16))

View File

@ -23,6 +23,7 @@
import struct import struct
import warnings
from io import BytesIO from io import BytesIO
from . import Image, ImageFile, BmpImagePlugin, PngImagePlugin from . import Image, ImageFile, BmpImagePlugin, PngImagePlugin
@ -143,14 +144,17 @@ class IcoFile(object):
""" """
return {(h['width'], h['height']) for h in self.entry} return {(h['width'], h['height']) for h in self.entry}
def getentryindex(self, size, bpp=False):
for (i, h) in enumerate(self.entry):
if size == h['dim'] and (bpp is False or bpp == h['color_depth']):
return i
return 0
def getimage(self, size, bpp=False): def getimage(self, size, bpp=False):
""" """
Get an image from the icon Get an image from the icon
""" """
for (i, h) in enumerate(self.entry): return self.frame(self.getentryindex(size, bpp))
if size == h['dim'] and (bpp is False or bpp == h['color_depth']):
return self.frame(i)
return self.frame(0)
def frame(self, idx): def frame(self, idx):
""" """
@ -282,7 +286,15 @@ class IcoImageFile(ImageFile.ImageFile):
im.load() im.load()
self.im = im.im self.im = im.im
self.mode = im.mode self.mode = im.mode
self.size = im.size if im.size != self.size:
warnings.warn("Image was not the expected size")
index = self.ico.getentryindex(self.size)
sizes = list(self.info['sizes'])
sizes[index] = im.size
self.info['sizes'] = set(sizes)
self.size = im.size
def load_seek(self): def load_seek(self):
# Flag the ImageFile.Parser so that it # Flag the ImageFile.Parser so that it