From a78ed9595f8ccbf6735c48462dc58538436e1f52 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Sat, 16 Mar 2024 18:40:16 +1100 Subject: [PATCH] Determine size from markers, not EXIF data --- Tests/images/sugarshack_frame_size.mpo | Bin 120198 -> 120198 bytes Tests/test_file_mpo.py | 2 +- src/PIL/MpoImagePlugin.py | 29 ++++++++----------------- 3 files changed, 10 insertions(+), 21 deletions(-) diff --git a/Tests/images/sugarshack_frame_size.mpo b/Tests/images/sugarshack_frame_size.mpo index 009280a79a648be15d6064c96f931e71ce9fde8e..abff98ea57d051dcae4a7853dc9c367dbdf57f51 100644 GIT binary patch delta 36 scmZo$&EB?}eZx_4W+n!v%_qc9Uf!(9Si!iN^KGao None: def test_frame_size() -> None: # This image has been hexedited to contain a different size - # in the EXIF data of the second frame + # in the SOF marker of the second frame with Image.open("Tests/images/sugarshack_frame_size.mpo") as im: assert im.size == (640, 480) diff --git a/src/PIL/MpoImagePlugin.py b/src/PIL/MpoImagePlugin.py index 199a100904c..ac9820bbf68 100644 --- a/src/PIL/MpoImagePlugin.py +++ b/src/PIL/MpoImagePlugin.py @@ -24,14 +24,11 @@ import struct from . import ( - ExifTags, Image, - ImageFile, ImageSequence, JpegImagePlugin, TiffImagePlugin, ) -from ._binary import i16be as i16 from ._binary import o32le @@ -109,7 +106,6 @@ def _open(self): self._after_jpeg_open() def _after_jpeg_open(self, mpheader=None): - self._initial_size = self.size self.mpinfo = mpheader if mpheader is not None else self._getmp() self.n_frames = self.mpinfo[0xB001] self.__mpoffsets = [ @@ -137,27 +133,20 @@ def seek(self, frame): self.fp = self._fp self.offset = self.__mpoffsets[frame] + original_exif = self.info.get("exif") + if "exif" in self.info: + del self.info["exif"] + self.fp.seek(self.offset + 2) # skip SOI marker - segment = self.fp.read(2) - if not segment: + if not self.fp.read(2): msg = "No data found for frame" raise ValueError(msg) - self._size = self._initial_size - if i16(segment) == 0xFFE1: # APP1 - n = i16(self.fp.read(2)) - 2 - self.info["exif"] = ImageFile._safe_read(self.fp, n) - self._reload_exif() - - mptype = self.mpinfo[0xB002][frame]["Attribute"]["MPType"] - if mptype.startswith("Large Thumbnail"): - exif = self.getexif().get_ifd(ExifTags.IFD.Exif) - if 40962 in exif and 40963 in exif: - self._size = (exif[40962], exif[40963]) - elif "exif" in self.info: - del self.info["exif"] + self.fp.seek(self.offset) + JpegImagePlugin.JpegImageFile._open(self) + if self.info.get("exif") != original_exif: self._reload_exif() - self.tile = [("jpeg", (0, 0) + self.size, self.offset, (self.mode, ""))] + self.tile = [("jpeg", (0, 0) + self.size, self.offset, self.tile[0][-1])] self.__frame = frame def tell(self):