diff --git a/Tests/test_image_copy.py b/Tests/test_image_copy.py index 027e5338b7a..dd859c06b93 100644 --- a/Tests/test_image_copy.py +++ b/Tests/test_image_copy.py @@ -49,5 +49,6 @@ def test_copy_zero() -> None: @skip_unless_feature("libtiff") def test_deepcopy() -> None: with Image.open("Tests/images/g4_orientation_5.tif") as im: + assert im.size == (590, 88) out = copy.deepcopy(im) assert out.size == (590, 88) diff --git a/Tests/test_image_resize.py b/Tests/test_image_resize.py index c9e3045121f..839e1845bd2 100644 --- a/Tests/test_image_resize.py +++ b/Tests/test_image_resize.py @@ -17,7 +17,6 @@ assert_image_equal_tofile, assert_image_similar, hopper, - skip_unless_feature, ) @@ -299,14 +298,6 @@ def resize(mode: str, size: tuple[int, int] | list[int]) -> None: with pytest.raises(ValueError): im.resize((10, 10), "unknown") - @skip_unless_feature("libtiff") - def test_load_first(self) -> None: - # load() may change the size of the image - # Test that resize() is calling it before getting the size - with Image.open("Tests/images/g4_orientation_5.tif") as im: - im = im.resize((64, 64)) - assert im.size == (64, 64) - @pytest.mark.parametrize("mode", ("L", "RGB", "I", "F")) def test_default_filter_bicubic(self, mode: str) -> None: im = hopper(mode) diff --git a/Tests/test_image_thumbnail.py b/Tests/test_image_thumbnail.py index bdbf09c407e..4b827dff78a 100644 --- a/Tests/test_image_thumbnail.py +++ b/Tests/test_image_thumbnail.py @@ -9,7 +9,6 @@ assert_image_similar, fromstring, hopper, - skip_unless_feature, tostring, ) @@ -90,22 +89,6 @@ def test_no_resize() -> None: im.thumbnail((64, 64)) assert im.size == (64, 64) - -@skip_unless_feature("libtiff") -def test_load_first() -> None: - # load() may change the size of the image - # Test that thumbnail() is calling it before performing size calculations - with Image.open("Tests/images/g4_orientation_5.tif") as im: - im.thumbnail((64, 64)) - assert im.size == (64, 10) - - # Test thumbnail(), without draft(), - # on an image that is large enough once load() has changed the size - with Image.open("Tests/images/g4_orientation_5.tif") as im: - im.thumbnail((590, 88), reducing_gap=None) - assert im.size == (590, 88) - - def test_load_first_unless_jpeg() -> None: # Test that thumbnail() still uses draft() for JPEG with Image.open("Tests/images/hopper.jpg") as im: diff --git a/Tests/test_numpy.py b/Tests/test_numpy.py index 312e32e0ca7..d03ff0a093c 100644 --- a/Tests/test_numpy.py +++ b/Tests/test_numpy.py @@ -240,8 +240,9 @@ def test_zero_size() -> None: @skip_unless_feature("libtiff") def test_load_first() -> None: with Image.open("Tests/images/g4_orientation_5.tif") as im: + assert im.size == (590, 88) a = numpy.array(im) - assert a.shape == (88, 590) + assert a.shape == (88, 590) def test_bool() -> None: diff --git a/src/PIL/ImageFile.py b/src/PIL/ImageFile.py index b8bf0b7fe90..1c85c640fa4 100644 --- a/src/PIL/ImageFile.py +++ b/src/PIL/ImageFile.py @@ -322,8 +322,9 @@ def load(self) -> Image.core.PixelAccess | None: def load_prepare(self) -> None: # create image memory if necessary - if self._im is None or self.im.mode != self.mode or self.im.size != self.size: - self.im = Image.core.new(self.mode, self.size) + # use internal _size property for correct tile size + if self._im is None or self.im.mode != self.mode or self.im.size != self._size: + self.im = Image.core.new(self.mode, self._size) # create palette (optional) if self.mode == "P": Image.Image.load(self) diff --git a/src/PIL/TiffImagePlugin.py b/src/PIL/TiffImagePlugin.py index cc16cbfb083..bbae051bfb5 100644 --- a/src/PIL/TiffImagePlugin.py +++ b/src/PIL/TiffImagePlugin.py @@ -1275,6 +1275,13 @@ def load(self) -> Image.core.PixelAccess | None: return self._load_libtiff() return super().load() + @property + def size(self) -> tuple[int, int]: + if hasattr(self, 'tag_v2'): + if self.tag_v2.get(ExifTags.Base.Orientation) in (5, 6, 7, 8): + return (self._size[1], self._size[0]) + return self._size + def load_end(self) -> None: # allow closing if we're on the first frame, there's no next # This is the ImageFile.load path only, libtiff specific below. @@ -1559,7 +1566,7 @@ def _setup(self) -> None: if STRIPOFFSETS in self.tag_v2: offsets = self.tag_v2[STRIPOFFSETS] h = self.tag_v2.get(ROWSPERSTRIP, ysize) - w = self.size[0] + w = xsize else: # tiled image offsets = self.tag_v2[TILEOFFSETS] @@ -1593,9 +1600,9 @@ def _setup(self) -> None: ) ) x = x + w - if x >= self.size[0]: + if x >= xsize: x, y = 0, y + h - if y >= self.size[1]: + if y >= ysize: x = y = 0 layer += 1 else: