Skip to content

Commit 0934c25

Browse files
authored
Merge pull request #6762 from radarhere/exif_hide_offsets
2 parents 7a19251 + 9dfba1f commit 0934c25

File tree

2 files changed

+45
-3
lines changed

2 files changed

+45
-3
lines changed

Tests/test_image.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -851,6 +851,31 @@ def test_exif_load_from_fp(self):
851851
34665: 196,
852852
}
853853

854+
def test_exif_hide_offsets(self):
855+
with Image.open("Tests/images/flower.jpg") as im:
856+
exif = im.getexif()
857+
858+
# Check offsets are present initially
859+
assert 0x8769 in exif
860+
for tag in (0xA005, 0x927C):
861+
assert tag in exif.get_ifd(0x8769)
862+
assert exif.get_ifd(0xA005)
863+
loaded_exif = exif
864+
865+
with Image.open("Tests/images/flower.jpg") as im:
866+
new_exif = im.getexif()
867+
868+
for exif in (loaded_exif, new_exif):
869+
exif.hide_offsets()
870+
871+
# Assert they are hidden afterwards,
872+
# but that the IFDs are still available
873+
assert 0x8769 not in exif
874+
assert exif.get_ifd(0x8769)
875+
for tag in (0xA005, 0x927C):
876+
assert tag not in exif.get_ifd(0x8769)
877+
assert exif.get_ifd(0xA005)
878+
854879
@pytest.mark.parametrize("size", ((1, 0), (0, 1), (0, 0)))
855880
def test_zero_tobytes(self, size):
856881
im = Image.new("RGB", size)

src/PIL/Image.py

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3551,6 +3551,7 @@ class Exif(MutableMapping):
35513551

35523552
def __init__(self):
35533553
self._data = {}
3554+
self._hidden_data = {}
35543555
self._ifds = {}
35553556
self._info = None
35563557
self._loaded_exif = None
@@ -3604,6 +3605,7 @@ def load(self, data):
36043605
return
36053606
self._loaded_exif = data
36063607
self._data.clear()
3608+
self._hidden_data.clear()
36073609
self._ifds.clear()
36083610
if data and data.startswith(b"Exif\x00\x00"):
36093611
data = data[6:]
@@ -3624,6 +3626,7 @@ def load(self, data):
36243626
def load_from_fp(self, fp, offset=None):
36253627
self._loaded_exif = None
36263628
self._data.clear()
3629+
self._hidden_data.clear()
36273630
self._ifds.clear()
36283631

36293632
# process dictionary
@@ -3686,8 +3689,9 @@ def get_ifd(self, tag):
36863689
if self._info is not None:
36873690
self._ifds[tag] = self._get_ifd_dict(self._info.next)
36883691
elif tag in [ExifTags.IFD.Exif, ExifTags.IFD.GPSInfo]:
3689-
if tag in self:
3690-
self._ifds[tag] = self._get_ifd_dict(self[tag])
3692+
offset = self._hidden_data.get(tag, self.get(tag))
3693+
if offset is not None:
3694+
self._ifds[tag] = self._get_ifd_dict(offset)
36913695
elif tag in [ExifTags.IFD.Interop, ExifTags.IFD.Makernote]:
36923696
if ExifTags.IFD.Exif not in self._ifds:
36933697
self.get_ifd(ExifTags.IFD.Exif)
@@ -3770,7 +3774,20 @@ def get_ifd(self, tag):
37703774
else:
37713775
# Interop
37723776
self._ifds[tag] = self._get_ifd_dict(tag_data)
3773-
return self._ifds.get(tag, {})
3777+
ifd = self._ifds.get(tag, {})
3778+
if tag == ExifTags.IFD.Exif and self._hidden_data:
3779+
ifd = {
3780+
k: v
3781+
for (k, v) in ifd.items()
3782+
if k not in (ExifTags.IFD.Interop, ExifTags.IFD.Makernote)
3783+
}
3784+
return ifd
3785+
3786+
def hide_offsets(self):
3787+
for tag in (ExifTags.IFD.Exif, ExifTags.IFD.GPSInfo):
3788+
if tag in self:
3789+
self._hidden_data[tag] = self[tag]
3790+
del self[tag]
37743791

37753792
def __str__(self):
37763793
if self._info is not None:

0 commit comments

Comments
 (0)