Skip to content

Commit 2f64f24

Browse files
committed
Restore previous position after failed seek
1 parent 0503c3d commit 2f64f24

File tree

5 files changed

+25
-33
lines changed

5 files changed

+25
-33
lines changed

Tests/test_file_jxl.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ def test_version(self) -> None:
3737

3838
def test_read_rgb(self) -> None:
3939
"""
40-
Can we read a RGB mode Jpeg XL file without error?
40+
Can we read an RGB mode JPEG XL file without error?
4141
Does it have the bits we expect?
4242
"""
4343

@@ -52,9 +52,22 @@ def test_read_rgb(self) -> None:
5252
# djxl hopper.jxl hopper_jxl_bits.ppm
5353
assert_image_similar_tofile(im, "Tests/images/hopper_jxl_bits.ppm", 1)
5454

55+
def test_read_rgba(self) -> None:
56+
# Generated with `cjxl transparent.png transparent.jxl -q 100 -e 8`
57+
with Image.open("Tests/images/transparent.jxl") as im:
58+
assert im.mode == "RGBA"
59+
assert im.size == (200, 150)
60+
assert im.format == "JPEG XL"
61+
im.load()
62+
im.getdata()
63+
64+
im.tobytes()
65+
66+
assert_image_similar_tofile(im, "Tests/images/transparent.png", 1)
67+
5568
def test_read_i16(self) -> None:
5669
"""
57-
Can we read 16-bit Grayscale Jpeg XL image?
70+
Can we read 16-bit Grayscale JPEG XL image?
5871
"""
5972

6073
with Image.open("Tests/images/jxl/16bit_subcutaneous.cropped.jxl") as im:

Tests/test_file_jxl_alpha.py

Lines changed: 0 additions & 26 deletions
This file was deleted.

Tests/test_file_jxl_animated.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ def test_n_frames() -> None:
2121
assert im.is_animated
2222

2323

24-
def test_float_duration() -> None:
24+
def test_duration() -> None:
2525
with Image.open("Tests/images/iss634.jxl") as im:
2626
assert im.info["duration"] == 70
2727
assert im.info["timestamp"] == 0
@@ -66,8 +66,11 @@ def test_seek() -> None:
6666

6767
def test_seek_errors() -> None:
6868
with Image.open("Tests/images/iss634.jxl") as im:
69-
with pytest.raises(EOFError):
69+
with pytest.raises(EOFError, match="attempt to seek outside sequence"):
7070
im.seek(-1)
7171

72-
with pytest.raises(EOFError):
72+
im.seek(1)
73+
with pytest.raises(EOFError, match="no more images in JPEG XL file"):
7374
im.seek(47)
75+
76+
assert im.tell() == 1

Tests/test_file_jxl_metadata.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ def test_read_exif_metadata() -> None:
3939
with Image.open("Tests/images/flower.jpg") as im_jpeg:
4040
expected_exif = im_jpeg.info["exif"]
4141

42-
# jpeg xl always returns exif without 'Exif\0\0' prefix
42+
# JPEG XL always returns exif without 'Exif\0\0' prefix
4343
assert exif_data == expected_exif[6:]
4444

4545

src/PIL/JpegXlImagePlugin.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ def _open(self) -> None:
5050
if icc := self._decoder.get_icc():
5151
self.info["icc_profile"] = icc
5252
if exif := self._decoder.get_exif():
53-
# jpeg xl does some weird shenanigans when storing exif
53+
# JPEG XL does some weird shenanigans when storing exif
5454
# it omits first 6 bytes of tiff header but adds 4 byte offset instead
5555
if len(exif) > 4:
5656
exif_start_offset = struct.unpack(">I", exif[:4])[0]
@@ -89,10 +89,12 @@ def seek(self, frame: int) -> None:
8989
self._decoder.rewind()
9090
self.info["timestamp"] = 0
9191

92+
last_frame = self.__frame
9293
while self.__frame < frame:
9394
self._get_next()
9495
self.__frame += 1
9596
if self._n_frames is not None and self._n_frames < frame:
97+
self.seek(last_frame)
9698
msg = "no more images in JPEG XL file"
9799
raise EOFError(msg)
98100

0 commit comments

Comments
 (0)