mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-01-27 09:44:31 +03:00
Merge pull request #5554 from radarhere/tag_group_data
This commit is contained in:
commit
2251be1a6f
|
@ -378,6 +378,20 @@ def test_too_many_entries():
|
||||||
pytest.warns(UserWarning, lambda: ifd[277])
|
pytest.warns(UserWarning, lambda: ifd[277])
|
||||||
|
|
||||||
|
|
||||||
|
def test_tag_group_data():
|
||||||
|
base_ifd = TiffImagePlugin.ImageFileDirectory_v2()
|
||||||
|
interop_ifd = TiffImagePlugin.ImageFileDirectory_v2(group=40965)
|
||||||
|
for ifd in (base_ifd, interop_ifd):
|
||||||
|
ifd[2] = "test"
|
||||||
|
ifd[256] = 10
|
||||||
|
|
||||||
|
assert base_ifd.tagtype[256] == 4
|
||||||
|
assert interop_ifd.tagtype[256] != base_ifd.tagtype[256]
|
||||||
|
|
||||||
|
assert interop_ifd.tagtype[2] == 7
|
||||||
|
assert base_ifd.tagtype[2] != interop_ifd.tagtype[256]
|
||||||
|
|
||||||
|
|
||||||
def test_empty_subifd(tmp_path):
|
def test_empty_subifd(tmp_path):
|
||||||
out = str(tmp_path / "temp.jpg")
|
out = str(tmp_path / "temp.jpg")
|
||||||
|
|
||||||
|
|
|
@ -468,7 +468,7 @@ class ImageFileDirectory_v2(MutableMapping):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, ifh=b"II\052\0\0\0\0\0", prefix=None):
|
def __init__(self, ifh=b"II\052\0\0\0\0\0", prefix=None, group=None):
|
||||||
"""Initialize an ImageFileDirectory.
|
"""Initialize an ImageFileDirectory.
|
||||||
|
|
||||||
To construct an ImageFileDirectory from a real file, pass the 8-byte
|
To construct an ImageFileDirectory from a real file, pass the 8-byte
|
||||||
|
@ -488,6 +488,7 @@ class ImageFileDirectory_v2(MutableMapping):
|
||||||
self._endian = "<"
|
self._endian = "<"
|
||||||
else:
|
else:
|
||||||
raise SyntaxError("not a TIFF IFD")
|
raise SyntaxError("not a TIFF IFD")
|
||||||
|
self.group = group
|
||||||
self.tagtype = {}
|
self.tagtype = {}
|
||||||
""" Dictionary of tag types """
|
""" Dictionary of tag types """
|
||||||
self.reset()
|
self.reset()
|
||||||
|
@ -519,7 +520,10 @@ class ImageFileDirectory_v2(MutableMapping):
|
||||||
|
|
||||||
Returns the complete tag dictionary, with named tags where possible.
|
Returns the complete tag dictionary, with named tags where possible.
|
||||||
"""
|
"""
|
||||||
return {TiffTags.lookup(code).name: value for code, value in self.items()}
|
return {
|
||||||
|
TiffTags.lookup(code, self.group).name: value
|
||||||
|
for code, value in self.items()
|
||||||
|
}
|
||||||
|
|
||||||
def __len__(self):
|
def __len__(self):
|
||||||
return len(set(self._tagdata) | set(self._tags_v2))
|
return len(set(self._tagdata) | set(self._tags_v2))
|
||||||
|
@ -544,7 +548,7 @@ class ImageFileDirectory_v2(MutableMapping):
|
||||||
def _setitem(self, tag, value, legacy_api):
|
def _setitem(self, tag, value, legacy_api):
|
||||||
basetypes = (Number, bytes, str)
|
basetypes = (Number, bytes, str)
|
||||||
|
|
||||||
info = TiffTags.lookup(tag)
|
info = TiffTags.lookup(tag, self.group)
|
||||||
values = [value] if isinstance(value, basetypes) else value
|
values = [value] if isinstance(value, basetypes) else value
|
||||||
|
|
||||||
if tag not in self.tagtype:
|
if tag not in self.tagtype:
|
||||||
|
@ -761,7 +765,7 @@ class ImageFileDirectory_v2(MutableMapping):
|
||||||
for i in range(self._unpack("H", self._ensure_read(fp, 2))[0]):
|
for i in range(self._unpack("H", self._ensure_read(fp, 2))[0]):
|
||||||
tag, typ, count, data = self._unpack("HHL4s", self._ensure_read(fp, 12))
|
tag, typ, count, data = self._unpack("HHL4s", self._ensure_read(fp, 12))
|
||||||
|
|
||||||
tagname = TiffTags.lookup(tag).name
|
tagname = TiffTags.lookup(tag, self.group).name
|
||||||
typname = TYPES.get(typ, "unknown")
|
typname = TYPES.get(typ, "unknown")
|
||||||
msg = f"tag: {tagname} ({tag}) - type: {typname} ({typ})"
|
msg = f"tag: {tagname} ({tag}) - type: {typname} ({typ})"
|
||||||
|
|
||||||
|
@ -828,7 +832,7 @@ class ImageFileDirectory_v2(MutableMapping):
|
||||||
ifh = b"II\x2A\x00\x08\x00\x00\x00"
|
ifh = b"II\x2A\x00\x08\x00\x00\x00"
|
||||||
else:
|
else:
|
||||||
ifh = b"MM\x00\x2A\x00\x00\x00\x08"
|
ifh = b"MM\x00\x2A\x00\x00\x00\x08"
|
||||||
ifd = ImageFileDirectory_v2(ifh)
|
ifd = ImageFileDirectory_v2(ifh, group=tag)
|
||||||
values = self._tags_v2[tag]
|
values = self._tags_v2[tag]
|
||||||
for ifd_tag, ifd_value in values.items():
|
for ifd_tag, ifd_value in values.items():
|
||||||
ifd[ifd_tag] = ifd_value
|
ifd[ifd_tag] = ifd_value
|
||||||
|
@ -837,7 +841,7 @@ class ImageFileDirectory_v2(MutableMapping):
|
||||||
values = value if isinstance(value, tuple) else (value,)
|
values = value if isinstance(value, tuple) else (value,)
|
||||||
data = self._write_dispatch[typ](self, *values)
|
data = self._write_dispatch[typ](self, *values)
|
||||||
|
|
||||||
tagname = TiffTags.lookup(tag).name
|
tagname = TiffTags.lookup(tag, self.group).name
|
||||||
typname = "ifd" if is_ifd else TYPES.get(typ, "unknown")
|
typname = "ifd" if is_ifd else TYPES.get(typ, "unknown")
|
||||||
msg = f"save: {tagname} ({tag}) - type: {typname} ({typ})"
|
msg = f"save: {tagname} ({tag}) - type: {typname} ({typ})"
|
||||||
msg += " - value: " + (
|
msg += " - value: " + (
|
||||||
|
|
|
@ -33,7 +33,7 @@ class TagInfo(namedtuple("_TagInfo", "value name type length enum")):
|
||||||
return self.enum.get(value, value) if self.enum else value
|
return self.enum.get(value, value) if self.enum else value
|
||||||
|
|
||||||
|
|
||||||
def lookup(tag):
|
def lookup(tag, group=None):
|
||||||
"""
|
"""
|
||||||
:param tag: Integer tag number
|
:param tag: Integer tag number
|
||||||
:returns: Taginfo namedtuple, From the TAGS_V2 info if possible,
|
:returns: Taginfo namedtuple, From the TAGS_V2 info if possible,
|
||||||
|
@ -42,7 +42,11 @@ def lookup(tag):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return TAGS_V2.get(tag, TagInfo(tag, TAGS.get(tag, "unknown")))
|
if group is not None:
|
||||||
|
info = TAGS_V2_GROUPS[group].get(tag) if group in TAGS_V2_GROUPS else None
|
||||||
|
else:
|
||||||
|
info = TAGS_V2.get(tag)
|
||||||
|
return info or TagInfo(tag, TAGS.get(tag, "unknown"))
|
||||||
|
|
||||||
|
|
||||||
##
|
##
|
||||||
|
@ -213,6 +217,19 @@ TAGS_V2 = {
|
||||||
50838: ("ImageJMetaDataByteCounts", LONG, 0), # Can be more than one
|
50838: ("ImageJMetaDataByteCounts", LONG, 0), # Can be more than one
|
||||||
50839: ("ImageJMetaData", UNDEFINED, 1), # see Issue #2006
|
50839: ("ImageJMetaData", UNDEFINED, 1), # see Issue #2006
|
||||||
}
|
}
|
||||||
|
TAGS_V2_GROUPS = {
|
||||||
|
# ExifIFD
|
||||||
|
34665: {
|
||||||
|
36864: ("ExifVersion", UNDEFINED, 1),
|
||||||
|
40960: ("FlashPixVersion", UNDEFINED, 1),
|
||||||
|
40965: ("InteroperabilityIFD", LONG, 1),
|
||||||
|
41730: ("CFAPattern", UNDEFINED, 1),
|
||||||
|
},
|
||||||
|
# GPSInfoIFD
|
||||||
|
34853: {},
|
||||||
|
# InteroperabilityIFD
|
||||||
|
40965: {1: ("InteropIndex", ASCII, 1), 2: ("InteropVersion", UNDEFINED, 1)},
|
||||||
|
}
|
||||||
|
|
||||||
# Legacy Tags structure
|
# Legacy Tags structure
|
||||||
# these tags aren't included above, but were in the previous versions
|
# these tags aren't included above, but were in the previous versions
|
||||||
|
@ -371,6 +388,10 @@ def _populate():
|
||||||
|
|
||||||
TAGS_V2[k] = TagInfo(k, *v)
|
TAGS_V2[k] = TagInfo(k, *v)
|
||||||
|
|
||||||
|
for group, tags in TAGS_V2_GROUPS.items():
|
||||||
|
for k, v in tags.items():
|
||||||
|
tags[k] = TagInfo(k, *v)
|
||||||
|
|
||||||
|
|
||||||
_populate()
|
_populate()
|
||||||
##
|
##
|
||||||
|
|
Loading…
Reference in New Issue
Block a user