Merge pull request #3658 from Glandos/fast_mpo_open

Fast MPO open
This commit is contained in:
Andrew Murray 2019-03-31 12:58:07 +11:00 committed by GitHub
commit 2c09252640
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 22 additions and 2 deletions

View File

@ -827,7 +827,8 @@ def jpeg_factory(fp=None, filename=None):
if mpheader[45057] > 1:
# It's actually an MPO
from .MpoImagePlugin import MpoImageFile
im = MpoImageFile(fp, filename)
# Don't reload everything, just convert it.
im = MpoImageFile.adopt(im, mpheader)
except (TypeError, IndexError):
# It is really a JPEG
pass

View File

@ -47,7 +47,10 @@ class MpoImageFile(JpegImagePlugin.JpegImageFile):
def _open(self):
self.fp.seek(0) # prep the fp in order to pass the JPEG test
JpegImagePlugin.JpegImageFile._open(self)
self.mpinfo = self._getmp()
self._after_jpeg_open()
def _after_jpeg_open(self, mpheader=None):
self.mpinfo = mpheader if mpheader is not None else self._getmp()
self.__framecount = self.mpinfo[0xB001]
self.__mpoffsets = [mpent['DataOffset'] + self.info['mpoffset']
for mpent in self.mpinfo[0xB002]]
@ -110,6 +113,22 @@ class MpoImageFile(JpegImagePlugin.JpegImageFile):
finally:
self.__fp = None
@staticmethod
def adopt(jpeg_instance, mpheader=None):
"""
Transform the instance of JpegImageFile into
an instance of MpoImageFile.
After the call, the JpegImageFile is extended
to be an MpoImageFile.
This is essentially useful when opening a JPEG
file that reveals itself as an MPO, to avoid
double call to _open.
"""
jpeg_instance.__class__ = MpoImageFile
jpeg_instance._after_jpeg_open(mpheader)
return jpeg_instance
# ---------------------------------------------------------------------
# Registry stuff