Skip to content

Commit

Permalink
Merge pull request #6213 from radarhere/fp
Browse files Browse the repository at this point in the history
  • Loading branch information
hugovk committed May 19, 2022
2 parents 5246a17 + e62449f commit 2c58c3e
Show file tree
Hide file tree
Showing 16 changed files with 82 additions and 121 deletions.
9 changes: 9 additions & 0 deletions Tests/test_file_apng.py
Expand Up @@ -637,6 +637,15 @@ def test_apng_save_blend(tmp_path):
assert im.getpixel((0, 0)) == (0, 255, 0, 255)


def test_seek_after_close():
im = Image.open("Tests/images/apng/delay.png")
im.seek(1)
im.close()

with pytest.raises(ValueError):
im.seek(0)


def test_constants_deprecation():
for enum, prefix in {
PngImagePlugin.Disposal: "APNG_DISPOSE_",
Expand Down
9 changes: 9 additions & 0 deletions Tests/test_file_fli.py
Expand Up @@ -46,6 +46,15 @@ def test_closed_file():
im.close()


def test_seek_after_close():
im = Image.open(animated_test_file)
im.seek(1)
im.close()

with pytest.raises(ValueError):
im.seek(0)


def test_context_manager():
with warnings.catch_warnings():
with Image.open(static_test_file) as im:
Expand Down
13 changes: 13 additions & 0 deletions Tests/test_file_gif.py
Expand Up @@ -46,6 +46,19 @@ def test_closed_file():
im.close()


def test_seek_after_close():
im = Image.open("Tests/images/iss634.gif")
im.load()
im.close()

with pytest.raises(ValueError):
im.is_animated
with pytest.raises(ValueError):
im.n_frames
with pytest.raises(ValueError):
im.seek(1)


def test_context_manager():
with warnings.catch_warnings():
with Image.open(TEST_GIF) as im:
Expand Down
8 changes: 8 additions & 0 deletions Tests/test_file_mpo.py
Expand Up @@ -48,6 +48,14 @@ def test_closed_file():
im.close()


def test_seek_after_close():
im = Image.open(test_files[0])
im.close()

with pytest.raises(ValueError):
im.seek(1)


def test_context_manager():
with warnings.catch_warnings():
with Image.open(test_files[0]) as im:
Expand Down
9 changes: 9 additions & 0 deletions Tests/test_file_tiff.py
Expand Up @@ -70,6 +70,15 @@ def test_closed_file(self):
im.load()
im.close()

def test_seek_after_close(self):
im = Image.open("Tests/images/multipage.tiff")
im.close()

with pytest.raises(ValueError):
im.n_frames
with pytest.raises(ValueError):
im.seek(1)

def test_context_manager(self):
with warnings.catch_warnings():
with Image.open("Tests/images/multipage.tiff") as im:
Expand Down
13 changes: 2 additions & 11 deletions src/PIL/DcxImagePlugin.py
Expand Up @@ -57,7 +57,7 @@ def _open(self):
break
self._offset.append(offset)

self.__fp = self.fp
self._fp = self.fp
self.frame = None
self.n_frames = len(self._offset)
self.is_animated = self.n_frames > 1
Expand All @@ -67,22 +67,13 @@ def seek(self, frame):
if not self._seek_check(frame):
return
self.frame = frame
self.fp = self.__fp
self.fp = self._fp
self.fp.seek(self._offset[frame])
PcxImageFile._open(self)

def tell(self):
return self.frame

def _close__fp(self):
try:
if self.__fp != self.fp:
self.__fp.close()
except AttributeError:
pass
finally:
self.__fp = None


Image.register_open(DcxImageFile.format, DcxImageFile, _accept)

Expand Down
15 changes: 3 additions & 12 deletions src/PIL/FliImagePlugin.py
Expand Up @@ -91,7 +91,7 @@ def _open(self):

# set things up to decode first frame
self.__frame = -1
self.__fp = self.fp
self._fp = self.fp
self.__rewind = self.fp.tell()
self.seek(0)

Expand Down Expand Up @@ -125,7 +125,7 @@ def seek(self, frame):
def _seek(self, frame):
if frame == 0:
self.__frame = -1
self.__fp.seek(self.__rewind)
self._fp.seek(self.__rewind)
self.__offset = 128
else:
# ensure that the previous frame was loaded
Expand All @@ -136,7 +136,7 @@ def _seek(self, frame):
self.__frame = frame

# move to next frame
self.fp = self.__fp
self.fp = self._fp
self.fp.seek(self.__offset)

s = self.fp.read(4)
Expand All @@ -153,15 +153,6 @@ def _seek(self, frame):
def tell(self):
return self.__frame

def _close__fp(self):
try:
if self.__fp != self.fp:
self.__fp.close()
except AttributeError:
pass
finally:
self.__fp = None


#
# registry
Expand Down
17 changes: 4 additions & 13 deletions src/PIL/GifImagePlugin.py
Expand Up @@ -102,7 +102,7 @@ def _open(self):
p = ImagePalette.raw("RGB", p)
self.global_palette = self.palette = p

self.__fp = self.fp # FIXME: hack
self._fp = self.fp # FIXME: hack
self.__rewind = self.fp.tell()
self._n_frames = None
self._is_animated = None
Expand Down Expand Up @@ -161,7 +161,7 @@ def _seek(self, frame, update_image=True):
self.__offset = 0
self.dispose = None
self.__frame = -1
self.__fp.seek(self.__rewind)
self._fp.seek(self.__rewind)
self.disposal_method = 0
else:
# ensure that the previous frame was loaded
Expand All @@ -171,7 +171,7 @@ def _seek(self, frame, update_image=True):
if frame != self.__frame + 1:
raise ValueError(f"cannot seek to frame {frame}")

self.fp = self.__fp
self.fp = self._fp
if self.__offset:
# backup to last frame
self.fp.seek(self.__offset)
Expand Down Expand Up @@ -281,7 +281,7 @@ def _seek(self, frame, update_image=True):
s = None

if interlace is None:
# self.__fp = None
# self._fp = None
raise EOFError
if not update_image:
return
Expand Down Expand Up @@ -443,15 +443,6 @@ def load_end(self):
def tell(self):
return self.__frame

def _close__fp(self):
try:
if self.__fp != self.fp:
self.__fp.close()
except AttributeError:
pass
finally:
self.__fp = None


# --------------------------------------------------------------------
# Write GIF files
Expand Down
13 changes: 2 additions & 11 deletions src/PIL/ImImagePlugin.py
Expand Up @@ -245,7 +245,7 @@ def _open(self):

self.__offset = offs = self.fp.tell()

self.__fp = self.fp # FIXME: hack
self._fp = self.fp # FIXME: hack

if self.rawmode[:2] == "F;":

Expand Down Expand Up @@ -294,22 +294,13 @@ def seek(self, frame):
size = ((self.size[0] * bits + 7) // 8) * self.size[1]
offs = self.__offset + frame * size

self.fp = self.__fp
self.fp = self._fp

self.tile = [("raw", (0, 0) + self.size, offs, (self.rawmode, 0, -1))]

def tell(self):
return self.frame

def _close__fp(self):
try:
if self.__fp != self.fp:
self.__fp.close()
except AttributeError:
pass
finally:
self.__fp = None


#
# --------------------------------------------------------------------
Expand Down
12 changes: 8 additions & 4 deletions src/PIL/Image.py
Expand Up @@ -549,8 +549,10 @@ def __enter__(self):

def __exit__(self, *args):
if hasattr(self, "fp") and getattr(self, "_exclusive_fp", False):
if hasattr(self, "_close__fp"):
self._close__fp()
if getattr(self, "_fp", False):
if self._fp != self.fp:
self._fp.close()
self._fp = DeferredError(ValueError("Operation on closed image"))
if self.fp:
self.fp.close()
self.fp = None
Expand All @@ -568,8 +570,10 @@ def close(self):
more information.
"""
try:
if hasattr(self, "_close__fp"):
self._close__fp()
if getattr(self, "_fp", False):
if self._fp != self.fp:
self._fp.close()
self._fp = DeferredError(ValueError("Operation on closed image"))
if self.fp:
self.fp.close()
self.fp = None
Expand Down
10 changes: 0 additions & 10 deletions src/PIL/MicImagePlugin.py
Expand Up @@ -62,7 +62,6 @@ def _open(self):
if not self.images:
raise SyntaxError("not an MIC file; no image entries")

self.__fp = self.fp
self.frame = None
self._n_frames = len(self.images)
self.is_animated = self._n_frames > 1
Expand All @@ -89,15 +88,6 @@ def seek(self, frame):
def tell(self):
return self.frame

def _close__fp(self):
try:
if self.__fp != self.fp:
self.__fp.close()
except AttributeError:
pass
finally:
self.__fp = None


#
# --------------------------------------------------------------------
Expand Down
17 changes: 4 additions & 13 deletions src/PIL/MpoImagePlugin.py
Expand Up @@ -58,20 +58,20 @@ def _after_jpeg_open(self, mpheader=None):
assert self.n_frames == len(self.__mpoffsets)
del self.info["mpoffset"] # no longer needed
self.is_animated = self.n_frames > 1
self.__fp = self.fp # FIXME: hack
self.__fp.seek(self.__mpoffsets[0]) # get ready to read first frame
self._fp = self.fp # FIXME: hack
self._fp.seek(self.__mpoffsets[0]) # get ready to read first frame
self.__frame = 0
self.offset = 0
# for now we can only handle reading and individual frame extraction
self.readonly = 1

def load_seek(self, pos):
self.__fp.seek(pos)
self._fp.seek(pos)

def seek(self, frame):
if not self._seek_check(frame):
return
self.fp = self.__fp
self.fp = self._fp
self.offset = self.__mpoffsets[frame]

self.fp.seek(self.offset + 2) # skip SOI marker
Expand All @@ -97,15 +97,6 @@ def seek(self, frame):
def tell(self):
return self.__frame

def _close__fp(self):
try:
if self.__fp != self.fp:
self.__fp.close()
except AttributeError:
pass
finally:
self.__fp = None

@staticmethod
def adopt(jpeg_instance, mpheader=None):
"""
Expand Down
19 changes: 5 additions & 14 deletions src/PIL/PngImagePlugin.py
Expand Up @@ -710,7 +710,7 @@ def _open(self):

if not _accept(self.fp.read(8)):
raise SyntaxError("not a PNG file")
self.__fp = self.fp
self._fp = self.fp
self.__frame = 0

#
Expand Down Expand Up @@ -767,7 +767,7 @@ def _open(self):
self._close_exclusive_fp_after_loading = False
self.png.save_rewind()
self.__rewind_idat = self.__prepare_idat
self.__rewind = self.__fp.tell()
self.__rewind = self._fp.tell()
if self.default_image:
# IDAT chunk contains default image and not first animation frame
self.n_frames += 1
Expand Down Expand Up @@ -822,15 +822,15 @@ def seek(self, frame):
def _seek(self, frame, rewind=False):
if frame == 0:
if rewind:
self.__fp.seek(self.__rewind)
self._fp.seek(self.__rewind)
self.png.rewind()
self.__prepare_idat = self.__rewind_idat
self.im = None
if self.pyaccess:
self.pyaccess = None
self.info = self.png.im_info
self.tile = self.png.im_tile
self.fp = self.__fp
self.fp = self._fp
self._prev_im = None
self.dispose = None
self.default_image = self.info.get("default_image", False)
Expand All @@ -849,7 +849,7 @@ def _seek(self, frame, rewind=False):
self.im.paste(self.dispose, self.dispose_extent)
self._prev_im = self.im.copy()

self.fp = self.__fp
self.fp = self._fp

# advance to the next frame
if self.__prepare_idat:
Expand Down Expand Up @@ -1027,15 +1027,6 @@ def getxmp(self):
else {}
)

def _close__fp(self):
try:
if self.__fp != self.fp:
self.__fp.close()
except AttributeError:
pass
finally:
self.__fp = None


# --------------------------------------------------------------------
# PNG writer
Expand Down

0 comments on commit 2c58c3e

Please sign in to comment.