Skip to content

Commit

Permalink
Merge pull request #8317 from Yay295/tiff_exif_multistrip
Browse files Browse the repository at this point in the history
Fixed writing multiple StripOffsets to TIFF
  • Loading branch information
radarhere committed Sep 25, 2024
2 parents c1ba2d9 + 8b6fa92 commit 3f24276
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 4 deletions.
3 changes: 2 additions & 1 deletion Tests/test_file_tiff.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,8 @@ def test_bigtiff(self, tmp_path: Path) -> None:
assert_image_equal_tofile(im, "Tests/images/hopper.tif")

with Image.open("Tests/images/hopper_bigtiff.tif") as im:
# multistrip support not yet implemented
# The data type of this file's StripOffsets tag is LONG8,
# which is not yet supported for offset data when saving multiple frames.
del im.tag_v2[273]

outfile = str(tmp_path / "temp.tif")
Expand Down
23 changes: 23 additions & 0 deletions Tests/test_file_tiff_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,29 @@ def test_change_stripbytecounts_tag_type(tmp_path: Path) -> None:
assert reloaded.tag_v2.tagtype[TiffImagePlugin.STRIPBYTECOUNTS] == TiffTags.LONG


def test_save_multiple_stripoffsets() -> None:
ifd = TiffImagePlugin.ImageFileDirectory_v2()
ifd[TiffImagePlugin.STRIPOFFSETS] = (123, 456)
assert ifd.tagtype[TiffImagePlugin.STRIPOFFSETS] == TiffTags.LONG

# all values are in little-endian
assert ifd.tobytes() == (
# number of tags == 1
b"\x01\x00"
# tag id (2 bytes), type (2 bytes), count (4 bytes), value (4 bytes)
# TiffImagePlugin.STRIPOFFSETS, TiffTags.LONG, 2, 18
# where STRIPOFFSETS is 273, LONG is 4
# and 18 is the offset of the tag data
b"\x11\x01\x04\x00\x02\x00\x00\x00\x12\x00\x00\x00"
# end of entries
b"\x00\x00\x00\x00"
# 26 is the total number of bytes output,
# the offset for any auxiliary strip data that will then be appended
# (123 + 26, 456 + 26) == (149, 482)
b"\x95\x00\x00\x00\xe2\x01\x00\x00"
)


def test_no_duplicate_50741_tag() -> None:
assert TAG_IDS["MakerNoteSafety"] == 50741
assert TAG_IDS["BestQualityScale"] == 50780
Expand Down
8 changes: 5 additions & 3 deletions src/PIL/TiffImagePlugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -991,9 +991,11 @@ def tobytes(self, offset: int = 0) -> bytes:
if stripoffsets is not None:
tag, typ, count, value, data = entries[stripoffsets]
if data:
msg = "multistrip support not yet implemented"
raise NotImplementedError(msg)
value = self._pack("L", self._unpack("L", value)[0] + offset)
size, handler = self._load_dispatch[typ]
values = [val + offset for val in handler(self, data, self.legacy_api)]
data = self._write_dispatch[typ](self, *values)
else:
value = self._pack("L", self._unpack("L", value)[0] + offset)
entries[stripoffsets] = tag, typ, count, value, data

# pass 2: write entries to file
Expand Down

0 comments on commit 3f24276

Please sign in to comment.