Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion Tests/test_file_libtiff.py
Original file line number Diff line number Diff line change
Expand Up @@ -1256,7 +1256,8 @@ def test_jpeg_short_strip(self, tiled: bool) -> None:
def test_orientation(self) -> None:
with Image.open("Tests/images/g4_orientation_1.tif") as base_im:
for i in range(2, 9):
with Image.open("Tests/images/g4_orientation_" + str(i) + ".tif") as im:
infile = "Tests/images/g4_orientation_" + str(i) + ".tif"
with Image.open(infile) as im:
assert isinstance(im, TiffImagePlugin.TiffImageFile)
assert 274 in im.tag_v2

Expand All @@ -1265,6 +1266,14 @@ def test_orientation(self) -> None:

assert_image_similar(base_im, im, 0.7)

with Image.open(infile) as im:
assert im.size == (590, 88)

im.tile.append(im.tile[0])
with pytest.raises(OSError, match="Not exactly one tile"):
im.load()
assert im.size == (590, 88)

def test_exif_transpose(self) -> None:
with Image.open("Tests/images/g4_orientation_1.tif") as base_im:
for i in range(2, 9):
Expand Down
19 changes: 19 additions & 0 deletions Tests/test_file_tiff.py
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,25 @@ def test_exif_frames(self) -> None:
im.seek(1)
assert im.getexif()[273] == (1408, 1907)

@pytest.mark.parametrize(
"orientation, method",
(
(5, Image.Transpose.TRANSPOSE),
(6, Image.Transpose.ROTATE_270),
(7, Image.Transpose.TRANSVERSE),
(8, Image.Transpose.ROTATE_90),
),
)
def test_orientation_mmap(
self, orientation: int, method: Image.Transpose, tmp_path: Path
) -> None:
filename = tmp_path / "temp.tif"
im = hopper("L").crop((0, 0, 128, 64))
im.save(filename, tiffinfo={274: orientation})
with Image.open(filename) as reloaded:
assert reloaded.size == (64, 128)
assert_image_equal(reloaded, im.transpose(method))

@pytest.mark.parametrize("mode", ("1", "L"))
def test_photometric(self, mode: str, tmp_path: Path) -> None:
filename = tmp_path / "temp.tif"
Expand Down
27 changes: 16 additions & 11 deletions src/PIL/TiffImagePlugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -1316,15 +1316,21 @@ def get_photoshop_blocks(self) -> dict[int, dict[str, bytes]]:
return blocks

def load(self) -> Image.core.PixelAccess | None:
if self.tile and self.use_load_libtiff:
return self._load_libtiff()
return super().load()
if not self.tile:
return super().load()

def load_prepare(self) -> None:
if self._im is None:
Image._decompression_bomb_check(self._tile_size)
self.im = Image.core.new(self.mode, self._tile_size)
ImageFile.ImageFile.load_prepare(self)
original_size = self._size
self._size = self._tile_size

try:
if self.use_load_libtiff:
self._load_libtiff()
px = Image.Image.load(self)
else:
px = super().load()
finally:
self._size = original_size
return px

def load_end(self) -> None:
# allow closing if we're on the first frame, there's no next
Expand All @@ -1343,7 +1349,7 @@ def load_end(self) -> None:
if ExifTags.Base.Orientation in self.tag_v2:
del self.tag_v2[ExifTags.Base.Orientation]

def _load_libtiff(self) -> Image.core.PixelAccess | None:
def _load_libtiff(self) -> None:
"""Overload method triggered when we detect a compressed tiff
Calls out to libtiff"""

Expand Down Expand Up @@ -1436,8 +1442,6 @@ def _load_libtiff(self) -> Image.core.PixelAccess | None:
msg = f"decoder error {err}"
raise OSError(msg)

return Image.Image.load(self)

def _setup(self) -> None:
"""Setup this image object based on current tags"""

Expand Down Expand Up @@ -1477,6 +1481,7 @@ def _setup(self) -> None:
msg = "Invalid dimensions"
raise ValueError(msg)
self._tile_size = xsize, ysize
Image._decompression_bomb_check(self._tile_size)
orientation = self.tag_v2.get(ExifTags.Base.Orientation)
if orientation in (5, 6, 7, 8):
self._size = ysize, xsize
Expand Down
Loading