Skip to content

Commit

Permalink
implement tiff exif multistrip support
Browse files Browse the repository at this point in the history
  • Loading branch information
Yay295 committed Aug 19, 2024
1 parent 35a70e4 commit cc3fdcc
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 5 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 currently supported when saving.
del im.tag_v2[273]

outfile = str(tmp_path / "temp.tif")
Expand Down
22 changes: 22 additions & 0 deletions Tests/test_file_tiff_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,28 @@ 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)
# == 273, 4, 2, 18
# == TiffImagePlugin.STRIPOFFSETS, TiffTags.LONG, 2, 18
# the value is the index of the tag data
b"\x11\x01\x04\x00\x02\x00\x00\x00\x12\x00\x00\x00"
# end of tags marker
b"\x00\x00\x00\x00"
# tag data == (149, 482) == (123 + 26, 456 + 26)
# 26 is the number of bytes before this data
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
12 changes: 8 additions & 4 deletions src/PIL/TiffImagePlugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -560,7 +560,9 @@ class ImageFileDirectory_v2(_IFDv2Base):
"""

_load_dispatch: dict[int, Callable[[ImageFileDirectory_v2, bytes, bool], Any]] = {}
_load_dispatch: dict[
int, tuple[int, Callable[[ImageFileDirectory_v2, bytes, bool], Any]]
] = {}
_write_dispatch: dict[int, Callable[..., Any]] = {}

def __init__(
Expand Down Expand Up @@ -972,9 +974,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 cc3fdcc

Please sign in to comment.