Merge pull request #3759 from radarhere/psd_frames

Improve handling of PSD frames
This commit is contained in:
Hugo 2019-06-19 09:15:13 +03:00 committed by GitHub
commit a9c05c7aa0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 31 additions and 3 deletions

View File

@ -17,6 +17,12 @@ class TestImagePsd(PillowTestCase):
im2 = hopper() im2 = hopper()
self.assert_image_similar(im, im2, 4.8) self.assert_image_similar(im, im2, 4.8)
def test_unclosed_file(self):
def open():
im = Image.open(test_file)
im.load()
self.assert_warning(None, open)
def test_invalid_file(self): def test_invalid_file(self):
invalid_file = "Tests/images/flower.jpg" invalid_file = "Tests/images/flower.jpg"
@ -65,6 +71,12 @@ class TestImagePsd(PillowTestCase):
self.assertRaises(EOFError, im.seek, -1) self.assertRaises(EOFError, im.seek, -1)
def test_open_after_exclusive_load(self):
im = Image.open(test_file)
im.load()
im.seek(im.tell()+1)
im.load()
def test_icc_profile(self): def test_icc_profile(self):
im = Image.open(test_file) im = Image.open(test_file)
self.assertIn("icc_profile", im.info) self.assertIn("icc_profile", im.info)

View File

@ -32,6 +32,12 @@ class TestImageSequence(PillowTestCase):
self.assertRaises(IndexError, lambda: i[index+1]) self.assertRaises(IndexError, lambda: i[index+1])
self.assertRaises(StopIteration, next, i) self.assertRaises(StopIteration, next, i)
def test_iterator_min_frame(self):
im = Image.open('Tests/images/hopper.psd')
i = ImageSequence.Iterator(im)
for index in range(1, im.n_frames):
self.assertEqual(i[index], next(i))
def _test_multipage_tiff(self): def _test_multipage_tiff(self):
im = Image.open('Tests/images/multipage.tiff') im = Image.open('Tests/images/multipage.tiff')
for index, frame in enumerate(ImageSequence.Iterator(im)): for index, frame in enumerate(ImageSequence.Iterator(im)):

View File

@ -32,7 +32,7 @@ class Iterator(object):
if not hasattr(im, "seek"): if not hasattr(im, "seek"):
raise AttributeError("im must have seek method") raise AttributeError("im must have seek method")
self.im = im self.im = im
self.position = 0 self.position = getattr(self.im, "_min_frame", 0)
def __getitem__(self, ix): def __getitem__(self, ix):
try: try:

View File

@ -54,6 +54,7 @@ class PsdImageFile(ImageFile.ImageFile):
format = "PSD" format = "PSD"
format_description = "Adobe Photoshop" format_description = "Adobe Photoshop"
_close_exclusive_fp_after_loading = False
def _open(self): def _open(self):
@ -128,7 +129,7 @@ class PsdImageFile(ImageFile.ImageFile):
self.tile = _maketile(self.fp, mode, (0, 0) + self.size, channels) self.tile = _maketile(self.fp, mode, (0, 0) + self.size, channels)
# keep the file open # keep the file open
self._fp = self.fp self.__fp = self.fp
self.frame = 1 self.frame = 1
self._min_frame = 1 self._min_frame = 1
@ -150,7 +151,7 @@ class PsdImageFile(ImageFile.ImageFile):
self.mode = mode self.mode = mode
self.tile = tile self.tile = tile
self.frame = layer self.frame = layer
self.fp = self._fp self.fp = self.__fp
return name, bbox return name, bbox
except IndexError: except IndexError:
raise EOFError("no such layer") raise EOFError("no such layer")
@ -167,6 +168,15 @@ class PsdImageFile(ImageFile.ImageFile):
if self.mode == "P": if self.mode == "P":
Image.Image.load(self) Image.Image.load(self)
def _close__fp(self):
try:
if self.__fp != self.fp:
self.__fp.close()
except AttributeError:
pass
finally:
self.__fp = None
def _layerinfo(file): def _layerinfo(file):
# read layerinfo block # read layerinfo block