mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-01-11 17:56:18 +03:00
Wait until all markers are read to process EXIF
This commit is contained in:
parent
53e82e49c5
commit
b84c970fbf
Binary file not shown.
Before Width: | Height: | Size: 364 B After Width: | Height: | Size: 391 B |
|
@ -870,7 +870,7 @@ class TestFileJpeg:
|
||||||
|
|
||||||
def test_multiple_exif(self) -> None:
|
def test_multiple_exif(self) -> None:
|
||||||
with Image.open("Tests/images/multiple_exif.jpg") as im:
|
with Image.open("Tests/images/multiple_exif.jpg") as im:
|
||||||
assert im.info["exif"] == b"Exif\x00\x00firstsecond"
|
assert im.getexif()[270] == "firstsecond"
|
||||||
|
|
||||||
@mark_if_feature_version(
|
@mark_if_feature_version(
|
||||||
pytest.mark.valgrind_known_error, "libjpeg_turbo", "2.0", reason="Known Failing"
|
pytest.mark.valgrind_known_error, "libjpeg_turbo", "2.0", reason="Known Failing"
|
||||||
|
|
|
@ -159,38 +159,6 @@ def APP(self, marker):
|
||||||
# plus constant header size
|
# plus constant header size
|
||||||
self.info["mpoffset"] = self.fp.tell() - n + 4
|
self.info["mpoffset"] = self.fp.tell() - n + 4
|
||||||
|
|
||||||
# If DPI isn't in JPEG header, fetch from EXIF
|
|
||||||
if "dpi" not in self.info and "exif" in self.info:
|
|
||||||
try:
|
|
||||||
exif = self.getexif()
|
|
||||||
resolution_unit = exif[0x0128]
|
|
||||||
x_resolution = exif[0x011A]
|
|
||||||
try:
|
|
||||||
dpi = float(x_resolution[0]) / x_resolution[1]
|
|
||||||
except TypeError:
|
|
||||||
dpi = x_resolution
|
|
||||||
if math.isnan(dpi):
|
|
||||||
msg = "DPI is not a number"
|
|
||||||
raise ValueError(msg)
|
|
||||||
if resolution_unit == 3: # cm
|
|
||||||
# 1 dpcm = 2.54 dpi
|
|
||||||
dpi *= 2.54
|
|
||||||
self.info["dpi"] = dpi, dpi
|
|
||||||
except (
|
|
||||||
struct.error,
|
|
||||||
KeyError,
|
|
||||||
SyntaxError,
|
|
||||||
TypeError,
|
|
||||||
ValueError,
|
|
||||||
ZeroDivisionError,
|
|
||||||
):
|
|
||||||
# struct.error for truncated EXIF
|
|
||||||
# KeyError for dpi not included
|
|
||||||
# SyntaxError for invalid/unreadable EXIF
|
|
||||||
# ValueError or TypeError for dpi being an invalid float
|
|
||||||
# ZeroDivisionError for invalid dpi rational value
|
|
||||||
self.info["dpi"] = 72, 72
|
|
||||||
|
|
||||||
|
|
||||||
def COM(self: JpegImageFile, marker: int) -> None:
|
def COM(self: JpegImageFile, marker: int) -> None:
|
||||||
#
|
#
|
||||||
|
@ -409,6 +377,8 @@ class JpegImageFile(ImageFile.ImageFile):
|
||||||
msg = "no marker found"
|
msg = "no marker found"
|
||||||
raise SyntaxError(msg)
|
raise SyntaxError(msg)
|
||||||
|
|
||||||
|
self._read_dpi_from_exif()
|
||||||
|
|
||||||
def load_read(self, read_bytes: int) -> bytes:
|
def load_read(self, read_bytes: int) -> bytes:
|
||||||
"""
|
"""
|
||||||
internal: read more image data
|
internal: read more image data
|
||||||
|
@ -497,6 +467,40 @@ class JpegImageFile(ImageFile.ImageFile):
|
||||||
def _getexif(self) -> dict[str, Any] | None:
|
def _getexif(self) -> dict[str, Any] | None:
|
||||||
return _getexif(self)
|
return _getexif(self)
|
||||||
|
|
||||||
|
def _read_dpi_from_exif(self) -> None:
|
||||||
|
# If DPI isn't in JPEG header, fetch from EXIF
|
||||||
|
if "dpi" in self.info or "exif" not in self.info:
|
||||||
|
return
|
||||||
|
try:
|
||||||
|
exif = self.getexif()
|
||||||
|
resolution_unit = exif[0x0128]
|
||||||
|
x_resolution = exif[0x011A]
|
||||||
|
try:
|
||||||
|
dpi = float(x_resolution[0]) / x_resolution[1]
|
||||||
|
except TypeError:
|
||||||
|
dpi = x_resolution
|
||||||
|
if math.isnan(dpi):
|
||||||
|
msg = "DPI is not a number"
|
||||||
|
raise ValueError(msg)
|
||||||
|
if resolution_unit == 3: # cm
|
||||||
|
# 1 dpcm = 2.54 dpi
|
||||||
|
dpi *= 2.54
|
||||||
|
self.info["dpi"] = dpi, dpi
|
||||||
|
except (
|
||||||
|
struct.error,
|
||||||
|
KeyError,
|
||||||
|
SyntaxError,
|
||||||
|
TypeError,
|
||||||
|
ValueError,
|
||||||
|
ZeroDivisionError,
|
||||||
|
):
|
||||||
|
# struct.error for truncated EXIF
|
||||||
|
# KeyError for dpi not included
|
||||||
|
# SyntaxError for invalid/unreadable EXIF
|
||||||
|
# ValueError or TypeError for dpi being an invalid float
|
||||||
|
# ZeroDivisionError for invalid dpi rational value
|
||||||
|
self.info["dpi"] = 72, 72
|
||||||
|
|
||||||
def _getmp(self):
|
def _getmp(self):
|
||||||
return _getmp(self)
|
return _getmp(self)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user