Skip to content

Commit 1ee3bd1

Browse files
authored
Merge pull request #8390 from radarhere/tiff_exif_transpose
Use transposed size after opening for TIFF images
2 parents 743ddc7 + 629f5be commit 1ee3bd1

File tree

7 files changed

+31
-31
lines changed

7 files changed

+31
-31
lines changed

Tests/test_image_copy.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,5 +49,7 @@ def test_copy_zero() -> None:
4949
@skip_unless_feature("libtiff")
5050
def test_deepcopy() -> None:
5151
with Image.open("Tests/images/g4_orientation_5.tif") as im:
52+
assert im.size == (590, 88)
53+
5254
out = copy.deepcopy(im)
5355
assert out.size == (590, 88)

Tests/test_image_resize.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -300,9 +300,7 @@ def resize(mode: str, size: tuple[int, int] | list[int]) -> None:
300300
im.resize((10, 10), "unknown")
301301

302302
@skip_unless_feature("libtiff")
303-
def test_load_first(self) -> None:
304-
# load() may change the size of the image
305-
# Test that resize() is calling it before getting the size
303+
def test_transposed(self) -> None:
306304
with Image.open("Tests/images/g4_orientation_5.tif") as im:
307305
im = im.resize((64, 64))
308306
assert im.size == (64, 64)

Tests/test_image_thumbnail.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -92,15 +92,13 @@ def test_no_resize() -> None:
9292

9393

9494
@skip_unless_feature("libtiff")
95-
def test_load_first() -> None:
96-
# load() may change the size of the image
97-
# Test that thumbnail() is calling it before performing size calculations
95+
def test_transposed() -> None:
9896
with Image.open("Tests/images/g4_orientation_5.tif") as im:
97+
assert im.size == (590, 88)
98+
9999
im.thumbnail((64, 64))
100100
assert im.size == (64, 10)
101101

102-
# Test thumbnail(), without draft(),
103-
# on an image that is large enough once load() has changed the size
104102
with Image.open("Tests/images/g4_orientation_5.tif") as im:
105103
im.thumbnail((590, 88), reducing_gap=None)
106104
assert im.size == (590, 88)

Tests/test_numpy.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,8 +238,10 @@ def test_zero_size() -> None:
238238

239239

240240
@skip_unless_feature("libtiff")
241-
def test_load_first() -> None:
241+
def test_transposed() -> None:
242242
with Image.open("Tests/images/g4_orientation_5.tif") as im:
243+
assert im.size == (590, 88)
244+
243245
a = numpy.array(im)
244246
assert a.shape == (88, 590)
245247

src/PIL/Image.py

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2332,7 +2332,6 @@ def resize(
23322332
msg = "reducing_gap must be 1.0 or greater"
23332333
raise ValueError(msg)
23342334

2335-
self.load()
23362335
if box is None:
23372336
box = (0, 0) + self.size
23382337

@@ -2781,27 +2780,18 @@ def round_aspect(number: float, key: Callable[[int], float]) -> int:
27812780
)
27822781
return x, y
27832782

2783+
preserved_size = preserve_aspect_ratio()
2784+
if preserved_size is None:
2785+
return
2786+
final_size = preserved_size
2787+
27842788
box = None
2785-
final_size: tuple[int, int]
27862789
if reducing_gap is not None:
2787-
preserved_size = preserve_aspect_ratio()
2788-
if preserved_size is None:
2789-
return
2790-
final_size = preserved_size
2791-
27922790
res = self.draft(
27932791
None, (int(size[0] * reducing_gap), int(size[1] * reducing_gap))
27942792
)
27952793
if res is not None:
27962794
box = res[1]
2797-
if box is None:
2798-
self.load()
2799-
2800-
# load() may have changed the size of the image
2801-
preserved_size = preserve_aspect_ratio()
2802-
if preserved_size is None:
2803-
return
2804-
final_size = preserved_size
28052795

28062796
if self.size != final_size:
28072797
im = self.resize(final_size, resample, box=box, reducing_gap=reducing_gap)

src/PIL/ImageFile.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ def load(self) -> Image.core.PixelAccess | None:
322322

323323
def load_prepare(self) -> None:
324324
# create image memory if necessary
325-
if self._im is None or self.im.mode != self.mode or self.im.size != self.size:
325+
if self._im is None:
326326
self.im = Image.core.new(self.mode, self.size)
327327
# create palette (optional)
328328
if self.mode == "P":

src/PIL/TiffImagePlugin.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1194,8 +1194,8 @@ def seek(self, frame: int) -> None:
11941194
# Create a new core image object on second and
11951195
# subsequent frames in the image. Image may be
11961196
# different size/mode.
1197-
Image._decompression_bomb_check(self.size)
1198-
self.im = Image.core.new(self.mode, self.size)
1197+
Image._decompression_bomb_check(self._tile_size)
1198+
self.im = Image.core.new(self.mode, self._tile_size)
11991199

12001200
def _seek(self, frame: int) -> None:
12011201
self.fp = self._fp
@@ -1275,6 +1275,11 @@ def load(self) -> Image.core.PixelAccess | None:
12751275
return self._load_libtiff()
12761276
return super().load()
12771277

1278+
def load_prepare(self) -> None:
1279+
if self._im is None:
1280+
self.im = Image.core.new(self.mode, self._tile_size)
1281+
ImageFile.ImageFile.load_prepare(self)
1282+
12781283
def load_end(self) -> None:
12791284
# allow closing if we're on the first frame, there's no next
12801285
# This is the ImageFile.load path only, libtiff specific below.
@@ -1416,7 +1421,12 @@ def _setup(self) -> None:
14161421
if not isinstance(xsize, int) or not isinstance(ysize, int):
14171422
msg = "Invalid dimensions"
14181423
raise ValueError(msg)
1419-
self._size = xsize, ysize
1424+
self._tile_size = xsize, ysize
1425+
orientation = self.tag_v2.get(ExifTags.Base.Orientation)
1426+
if orientation in (5, 6, 7, 8):
1427+
self._size = ysize, xsize
1428+
else:
1429+
self._size = xsize, ysize
14201430

14211431
logger.debug("- size: %s", self.size)
14221432

@@ -1559,7 +1569,7 @@ def _setup(self) -> None:
15591569
if STRIPOFFSETS in self.tag_v2:
15601570
offsets = self.tag_v2[STRIPOFFSETS]
15611571
h = self.tag_v2.get(ROWSPERSTRIP, ysize)
1562-
w = self.size[0]
1572+
w = xsize
15631573
else:
15641574
# tiled image
15651575
offsets = self.tag_v2[TILEOFFSETS]
@@ -1593,9 +1603,9 @@ def _setup(self) -> None:
15931603
)
15941604
)
15951605
x = x + w
1596-
if x >= self.size[0]:
1606+
if x >= xsize:
15971607
x, y = 0, y + h
1598-
if y >= self.size[1]:
1608+
if y >= ysize:
15991609
x = y = 0
16001610
layer += 1
16011611
else:

0 commit comments

Comments
 (0)