mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-06-29 09:23:11 +03:00
Merge pull request #8560 from Knio/tom/bufferedio
Fix file position desync when calling into libtiff
This commit is contained in:
commit
1c152258c3
|
@ -1098,6 +1098,25 @@ class TestFileLibTiff(LibTiffTestCase):
|
||||||
|
|
||||||
assert_image_similar(base_im, im, 0.7)
|
assert_image_similar(base_im, im, 0.7)
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"test_file",
|
||||||
|
[
|
||||||
|
"Tests/images/old-style-jpeg-compression-no-samplesperpixel.tif",
|
||||||
|
"Tests/images/old-style-jpeg-compression.tif",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_buffering(self, test_file: str) -> None:
|
||||||
|
# load exif first
|
||||||
|
with Image.open(open(test_file, "rb", buffering=1048576)) as im:
|
||||||
|
exif = dict(im.getexif())
|
||||||
|
|
||||||
|
# load image before exif
|
||||||
|
with Image.open(open(test_file, "rb", buffering=1048576)) as im2:
|
||||||
|
im2.load()
|
||||||
|
exif_after_load = dict(im2.getexif())
|
||||||
|
|
||||||
|
assert exif == exif_after_load
|
||||||
|
|
||||||
@pytest.mark.valgrind_known_error(reason="Backtrace in Python Core")
|
@pytest.mark.valgrind_known_error(reason="Backtrace in Python Core")
|
||||||
def test_sampleformat_not_corrupted(self) -> None:
|
def test_sampleformat_not_corrupted(self) -> None:
|
||||||
# Assert that a TIFF image with SampleFormat=UINT tag is not corrupted
|
# Assert that a TIFF image with SampleFormat=UINT tag is not corrupted
|
||||||
|
|
|
@ -1216,10 +1216,6 @@ class TiffImageFile(ImageFile.ImageFile):
|
||||||
def _seek(self, frame: int) -> None:
|
def _seek(self, frame: int) -> None:
|
||||||
self.fp = self._fp
|
self.fp = self._fp
|
||||||
|
|
||||||
# reset buffered io handle in case fp
|
|
||||||
# was passed to libtiff, invalidating the buffer
|
|
||||||
self.fp.tell()
|
|
||||||
|
|
||||||
while len(self._frame_pos) <= frame:
|
while len(self._frame_pos) <= frame:
|
||||||
if not self.__next:
|
if not self.__next:
|
||||||
msg = "no more images in TIFF file"
|
msg = "no more images in TIFF file"
|
||||||
|
@ -1303,10 +1299,6 @@ class TiffImageFile(ImageFile.ImageFile):
|
||||||
if not self.is_animated:
|
if not self.is_animated:
|
||||||
self._close_exclusive_fp_after_loading = True
|
self._close_exclusive_fp_after_loading = True
|
||||||
|
|
||||||
# reset buffered io handle in case fp
|
|
||||||
# was passed to libtiff, invalidating the buffer
|
|
||||||
self.fp.tell()
|
|
||||||
|
|
||||||
# load IFD data from fp before it is closed
|
# load IFD data from fp before it is closed
|
||||||
exif = self.getexif()
|
exif = self.getexif()
|
||||||
for key in TiffTags.TAGS_V2_GROUPS:
|
for key in TiffTags.TAGS_V2_GROUPS:
|
||||||
|
@ -1381,8 +1373,17 @@ class TiffImageFile(ImageFile.ImageFile):
|
||||||
logger.debug("have fileno, calling fileno version of the decoder.")
|
logger.debug("have fileno, calling fileno version of the decoder.")
|
||||||
if not close_self_fp:
|
if not close_self_fp:
|
||||||
self.fp.seek(0)
|
self.fp.seek(0)
|
||||||
|
# Save and restore the file position, because libtiff will move it
|
||||||
|
# outside of the Python runtime, and that will confuse
|
||||||
|
# io.BufferedReader and possible others.
|
||||||
|
# NOTE: This must use os.lseek(), and not fp.tell()/fp.seek(),
|
||||||
|
# because the buffer read head already may not equal the actual
|
||||||
|
# file position, and fp.seek() may just adjust it's internal
|
||||||
|
# pointer and not actually seek the OS file handle.
|
||||||
|
pos = os.lseek(fp, 0, os.SEEK_CUR)
|
||||||
# 4 bytes, otherwise the trace might error out
|
# 4 bytes, otherwise the trace might error out
|
||||||
n, err = decoder.decode(b"fpfp")
|
n, err = decoder.decode(b"fpfp")
|
||||||
|
os.lseek(fp, pos, os.SEEK_SET)
|
||||||
else:
|
else:
|
||||||
# we have something else.
|
# we have something else.
|
||||||
logger.debug("don't have fileno or getvalue. just reading")
|
logger.debug("don't have fileno or getvalue. just reading")
|
||||||
|
|
Loading…
Reference in New Issue
Block a user