mirror of
				https://github.com/python-pillow/Pillow.git
				synced 2025-11-04 01:47:47 +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