mirror of
				https://github.com/python-pillow/Pillow.git
				synced 2025-11-04 01:47:47 +03:00 
			
		
		
		
	Merge cbb1e36bea into cc4ca5bf17
				
					
				
			This commit is contained in:
		
						commit
						34efbdbf7f
					
				| 
						 | 
				
			
			@ -61,6 +61,7 @@ def test_handler(tmp_path: Path) -> None:
 | 
			
		|||
 | 
			
		||||
        def load(self, im: ImageFile.StubImageFile) -> Image.Image:
 | 
			
		||||
            self.loaded = True
 | 
			
		||||
            assert im.fp is not None
 | 
			
		||||
            im.fp.close()
 | 
			
		||||
            return Image.new("RGB", (1, 1))
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -61,6 +61,7 @@ def test_handler(tmp_path: Path) -> None:
 | 
			
		|||
 | 
			
		||||
        def load(self, im: Image.Image) -> Image.Image:
 | 
			
		||||
            self.loaded = True
 | 
			
		||||
            assert im.fp is not None
 | 
			
		||||
            im.fp.close()
 | 
			
		||||
            return Image.new("RGB", (1, 1))
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -63,6 +63,7 @@ def test_handler(tmp_path: Path) -> None:
 | 
			
		|||
 | 
			
		||||
        def load(self, im: Image.Image) -> Image.Image:
 | 
			
		||||
            self.loaded = True
 | 
			
		||||
            assert im.fp is not None
 | 
			
		||||
            im.fp.close()
 | 
			
		||||
            return Image.new("RGB", (1, 1))
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1133,8 +1133,9 @@ class TestFileCloseW32:
 | 
			
		|||
            im.save(tmpfile)
 | 
			
		||||
 | 
			
		||||
        im = Image.open(tmpfile)
 | 
			
		||||
        assert im.fp is not None
 | 
			
		||||
        assert not im.fp.closed
 | 
			
		||||
        fp = im.fp
 | 
			
		||||
        assert not fp.closed
 | 
			
		||||
        with pytest.raises(OSError):
 | 
			
		||||
            os.remove(tmpfile)
 | 
			
		||||
        im.load()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,7 +11,15 @@ from typing import Any, NamedTuple
 | 
			
		|||
 | 
			
		||||
import pytest
 | 
			
		||||
 | 
			
		||||
from PIL import Image, ImageFilter, ImageOps, TiffImagePlugin, TiffTags, features
 | 
			
		||||
from PIL import (
 | 
			
		||||
    Image,
 | 
			
		||||
    ImageFile,
 | 
			
		||||
    ImageFilter,
 | 
			
		||||
    ImageOps,
 | 
			
		||||
    TiffImagePlugin,
 | 
			
		||||
    TiffTags,
 | 
			
		||||
    features,
 | 
			
		||||
)
 | 
			
		||||
from PIL.TiffImagePlugin import OSUBFILETYPE, SAMPLEFORMAT, STRIPOFFSETS, SUBIFD
 | 
			
		||||
 | 
			
		||||
from .helper import (
 | 
			
		||||
| 
						 | 
				
			
			@ -572,8 +580,9 @@ class TestFileLibTiff(LibTiffTestCase):
 | 
			
		|||
            im.save(out, compression=compression)
 | 
			
		||||
 | 
			
		||||
    def test_fp_leak(self) -> None:
 | 
			
		||||
        im: Image.Image | None = Image.open("Tests/images/hopper_g4_500.tif")
 | 
			
		||||
        im: ImageFile.ImageFile | None = Image.open("Tests/images/hopper_g4_500.tif")
 | 
			
		||||
        assert im is not None
 | 
			
		||||
        assert im.fp is not None
 | 
			
		||||
        fn = im.fp.fileno()
 | 
			
		||||
 | 
			
		||||
        os.fstat(fn)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -971,6 +971,7 @@ class TestFileTiff:
 | 
			
		|||
 | 
			
		||||
        im = Image.open(tmpfile)
 | 
			
		||||
        fp = im.fp
 | 
			
		||||
        assert fp is not None
 | 
			
		||||
        assert not fp.closed
 | 
			
		||||
        im.load()
 | 
			
		||||
        assert fp.closed
 | 
			
		||||
| 
						 | 
				
			
			@ -984,6 +985,7 @@ class TestFileTiff:
 | 
			
		|||
        with open(tmpfile, "rb") as f:
 | 
			
		||||
            im = Image.open(f)
 | 
			
		||||
            fp = im.fp
 | 
			
		||||
            assert fp is not None
 | 
			
		||||
            assert not fp.closed
 | 
			
		||||
            im.load()
 | 
			
		||||
            assert not fp.closed
 | 
			
		||||
| 
						 | 
				
			
			@ -1034,8 +1036,9 @@ class TestFileTiffW32:
 | 
			
		|||
            im.save(tmpfile)
 | 
			
		||||
 | 
			
		||||
        im = Image.open(tmpfile)
 | 
			
		||||
        assert im.fp is not None
 | 
			
		||||
        assert not im.fp.closed
 | 
			
		||||
        fp = im.fp
 | 
			
		||||
        assert not fp.closed
 | 
			
		||||
        with pytest.raises(OSError):
 | 
			
		||||
            os.remove(tmpfile)
 | 
			
		||||
        im.load()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -38,6 +38,7 @@ def test_close_after_load(caplog: pytest.LogCaptureFixture) -> None:
 | 
			
		|||
def test_contextmanager() -> None:
 | 
			
		||||
    fn = None
 | 
			
		||||
    with Image.open("Tests/images/hopper.gif") as im:
 | 
			
		||||
        assert im.fp is not None
 | 
			
		||||
        fn = im.fp.fileno()
 | 
			
		||||
        os.fstat(fn)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -213,6 +213,7 @@ class DdsImageFile(ImageFile.ImageFile):
 | 
			
		|||
    format_description = "DirectDraw Surface"
 | 
			
		||||
 | 
			
		||||
    def _open(self) -> None:
 | 
			
		||||
        assert self.fp is not None
 | 
			
		||||
        if not _accept(self.fp.read(4)):
 | 
			
		||||
            msg = "not a DDS file"
 | 
			
		||||
            raise SyntaxError(msg)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -77,6 +77,8 @@ class AvifImageFile(ImageFile.ImageFile):
 | 
			
		|||
        ):
 | 
			
		||||
            msg = "Invalid opening codec"
 | 
			
		||||
            raise ValueError(msg)
 | 
			
		||||
 | 
			
		||||
        assert self.fp is not None
 | 
			
		||||
        self._decoder = _avif.AvifDecoder(
 | 
			
		||||
            self.fp.read(),
 | 
			
		||||
            DECODE_CODEC_CHOICE,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -258,6 +258,7 @@ class BlpImageFile(ImageFile.ImageFile):
 | 
			
		|||
    format_description = "Blizzard Mipmap Format"
 | 
			
		||||
 | 
			
		||||
    def _open(self) -> None:
 | 
			
		||||
        assert self.fp is not None
 | 
			
		||||
        self.magic = self.fp.read(4)
 | 
			
		||||
        if not _accept(self.magic):
 | 
			
		||||
            msg = f"Bad BLP magic {repr(self.magic)}"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -76,6 +76,7 @@ class BmpImageFile(ImageFile.ImageFile):
 | 
			
		|||
 | 
			
		||||
    def _bitmap(self, header: int = 0, offset: int = 0) -> None:
 | 
			
		||||
        """Read relevant info about the BMP"""
 | 
			
		||||
        assert self.fp is not None
 | 
			
		||||
        read, seek = self.fp.read, self.fp.seek
 | 
			
		||||
        if header:
 | 
			
		||||
            seek(header)
 | 
			
		||||
| 
						 | 
				
			
			@ -311,6 +312,7 @@ class BmpImageFile(ImageFile.ImageFile):
 | 
			
		|||
    def _open(self) -> None:
 | 
			
		||||
        """Open file, check magic number and read header"""
 | 
			
		||||
        # read 14 bytes: magic number, filesize, reserved, header final offset
 | 
			
		||||
        assert self.fp is not None
 | 
			
		||||
        head_data = self.fp.read(14)
 | 
			
		||||
        # choke if the file does not have the required magic bytes
 | 
			
		||||
        if not _accept(head_data):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -41,6 +41,7 @@ class BufrStubImageFile(ImageFile.StubImageFile):
 | 
			
		|||
    format_description = "BUFR"
 | 
			
		||||
 | 
			
		||||
    def _open(self) -> None:
 | 
			
		||||
        assert self.fp is not None
 | 
			
		||||
        if not _accept(self.fp.read(4)):
 | 
			
		||||
            msg = "Not a BUFR file"
 | 
			
		||||
            raise SyntaxError(msg)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -45,6 +45,7 @@ class DcxImageFile(PcxImageFile):
 | 
			
		|||
 | 
			
		||||
    def _open(self) -> None:
 | 
			
		||||
        # Header
 | 
			
		||||
        assert self.fp is not None
 | 
			
		||||
        s = self.fp.read(4)
 | 
			
		||||
        if not _accept(s):
 | 
			
		||||
            msg = "not a DCX file"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -189,6 +189,7 @@ class EpsImageFile(ImageFile.ImageFile):
 | 
			
		|||
    mode_map = {1: "L", 2: "LAB", 3: "RGB", 4: "CMYK"}
 | 
			
		||||
 | 
			
		||||
    def _open(self) -> None:
 | 
			
		||||
        assert self.fp is not None
 | 
			
		||||
        (length, offset) = self._find_offset(self.fp)
 | 
			
		||||
 | 
			
		||||
        # go to offset - start of "%!PS"
 | 
			
		||||
| 
						 | 
				
			
			@ -403,6 +404,7 @@ class EpsImageFile(ImageFile.ImageFile):
 | 
			
		|||
    ) -> Image.core.PixelAccess | None:
 | 
			
		||||
        # Load EPS via Ghostscript
 | 
			
		||||
        if self.tile:
 | 
			
		||||
            assert self.fp is not None
 | 
			
		||||
            self.im = Ghostscript(self.tile, self.size, self.fp, scale, transparency)
 | 
			
		||||
            self._mode = self.im.mode
 | 
			
		||||
            self._size = self.im.size
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -58,6 +58,7 @@ class FpxImageFile(ImageFile.ImageFile):
 | 
			
		|||
        # read the OLE directory and see if this is a likely
 | 
			
		||||
        # to be a FlashPix file
 | 
			
		||||
 | 
			
		||||
        assert self.fp is not None
 | 
			
		||||
        try:
 | 
			
		||||
            self.ole = olefile.OleFileIO(self.fp)
 | 
			
		||||
        except OSError as e:
 | 
			
		||||
| 
						 | 
				
			
			@ -229,6 +230,7 @@ class FpxImageFile(ImageFile.ImageFile):
 | 
			
		|||
                if y >= ysize:
 | 
			
		||||
                    break  # isn't really required
 | 
			
		||||
 | 
			
		||||
        assert self.fp is not None
 | 
			
		||||
        self.stream = stream
 | 
			
		||||
        self._fp = self.fp
 | 
			
		||||
        self.fp = None
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -72,6 +72,7 @@ class FtexImageFile(ImageFile.ImageFile):
 | 
			
		|||
    format_description = "Texture File Format (IW2:EOC)"
 | 
			
		||||
 | 
			
		||||
    def _open(self) -> None:
 | 
			
		||||
        assert self.fp is not None
 | 
			
		||||
        if not _accept(self.fp.read(4)):
 | 
			
		||||
            msg = "not an FTEX file"
 | 
			
		||||
            raise SyntaxError(msg)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -42,6 +42,7 @@ class GbrImageFile(ImageFile.ImageFile):
 | 
			
		|||
    format_description = "GIMP brush file"
 | 
			
		||||
 | 
			
		||||
    def _open(self) -> None:
 | 
			
		||||
        assert self.fp is not None
 | 
			
		||||
        header_size = i32(self.fp.read(4))
 | 
			
		||||
        if header_size < 20:
 | 
			
		||||
            msg = "not a GIMP brush"
 | 
			
		||||
| 
						 | 
				
			
			@ -88,6 +89,7 @@ class GbrImageFile(ImageFile.ImageFile):
 | 
			
		|||
 | 
			
		||||
    def load(self) -> Image.core.PixelAccess | None:
 | 
			
		||||
        if self._im is None:
 | 
			
		||||
            assert self.fp is not None
 | 
			
		||||
            self.im = Image.core.new(self.mode, self.size)
 | 
			
		||||
            self.frombytes(self.fp.read(self._data_size))
 | 
			
		||||
        return Image.Image.load(self)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -87,6 +87,7 @@ class GifImageFile(ImageFile.ImageFile):
 | 
			
		|||
    global_palette = None
 | 
			
		||||
 | 
			
		||||
    def data(self) -> bytes | None:
 | 
			
		||||
        assert self.fp is not None
 | 
			
		||||
        s = self.fp.read(1)
 | 
			
		||||
        if s and s[0]:
 | 
			
		||||
            return self.fp.read(s[0])
 | 
			
		||||
| 
						 | 
				
			
			@ -100,6 +101,7 @@ class GifImageFile(ImageFile.ImageFile):
 | 
			
		|||
 | 
			
		||||
    def _open(self) -> None:
 | 
			
		||||
        # Screen
 | 
			
		||||
        assert self.fp is not None
 | 
			
		||||
        s = self.fp.read(13)
 | 
			
		||||
        if not _accept(s):
 | 
			
		||||
            msg = "not a GIF file"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -41,6 +41,7 @@ class GribStubImageFile(ImageFile.StubImageFile):
 | 
			
		|||
    format_description = "GRIB"
 | 
			
		||||
 | 
			
		||||
    def _open(self) -> None:
 | 
			
		||||
        assert self.fp is not None
 | 
			
		||||
        if not _accept(self.fp.read(8)):
 | 
			
		||||
            msg = "Not a GRIB file"
 | 
			
		||||
            raise SyntaxError(msg)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -41,6 +41,7 @@ class HDF5StubImageFile(ImageFile.StubImageFile):
 | 
			
		|||
    format_description = "HDF5"
 | 
			
		||||
 | 
			
		||||
    def _open(self) -> None:
 | 
			
		||||
        assert self.fp is not None
 | 
			
		||||
        if not _accept(self.fp.read(8)):
 | 
			
		||||
            msg = "Not an HDF file"
 | 
			
		||||
            raise SyntaxError(msg)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -265,6 +265,7 @@ class IcnsImageFile(ImageFile.ImageFile):
 | 
			
		|||
    format_description = "Mac OS icns resource"
 | 
			
		||||
 | 
			
		||||
    def _open(self) -> None:
 | 
			
		||||
        assert self.fp is not None
 | 
			
		||||
        self.icns = IcnsFile(self.fp)
 | 
			
		||||
        self._mode = "RGBA"
 | 
			
		||||
        self.info["sizes"] = self.icns.itersizes()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -326,6 +326,7 @@ class IcoImageFile(ImageFile.ImageFile):
 | 
			
		|||
    format_description = "Windows Icon"
 | 
			
		||||
 | 
			
		||||
    def _open(self) -> None:
 | 
			
		||||
        assert self.fp is not None
 | 
			
		||||
        self.ico = IcoFile(self.fp)
 | 
			
		||||
        self.info["sizes"] = self.ico.sizes()
 | 
			
		||||
        self.size = self.ico.entry[0].dim
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -125,6 +125,7 @@ class ImImageFile(ImageFile.ImageFile):
 | 
			
		|||
        # Quick rejection: if there's not an LF among the first
 | 
			
		||||
        # 100 bytes, this is (probably) not a text header.
 | 
			
		||||
 | 
			
		||||
        assert self.fp is not None
 | 
			
		||||
        if b"\n" not in self.fp.read(100):
 | 
			
		||||
            msg = "not an IM file"
 | 
			
		||||
            raise SyntaxError(msg)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -285,6 +285,7 @@ class ImageFile(Image.Image):
 | 
			
		|||
        self.map: mmap.mmap | None = None
 | 
			
		||||
        use_mmap = self.filename and len(self.tile) == 1
 | 
			
		||||
 | 
			
		||||
        assert self.fp is not None
 | 
			
		||||
        readonly = 0
 | 
			
		||||
 | 
			
		||||
        # look for read/seek overrides
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -49,6 +49,7 @@ class IptcImageFile(ImageFile.ImageFile):
 | 
			
		|||
    def field(self) -> tuple[tuple[int, int] | None, int]:
 | 
			
		||||
        #
 | 
			
		||||
        # get a IPTC field header
 | 
			
		||||
        assert self.fp is not None
 | 
			
		||||
        s = self.fp.read(5)
 | 
			
		||||
        if not s.strip(b"\x00"):
 | 
			
		||||
            return None, 0
 | 
			
		||||
| 
						 | 
				
			
			@ -76,6 +77,7 @@ class IptcImageFile(ImageFile.ImageFile):
 | 
			
		|||
 | 
			
		||||
    def _open(self) -> None:
 | 
			
		||||
        # load descriptive fields
 | 
			
		||||
        assert self.fp is not None
 | 
			
		||||
        while True:
 | 
			
		||||
            offset = self.fp.tell()
 | 
			
		||||
            tag, size = self.field()
 | 
			
		||||
| 
						 | 
				
			
			@ -131,6 +133,7 @@ class IptcImageFile(ImageFile.ImageFile):
 | 
			
		|||
            assert isinstance(args, tuple)
 | 
			
		||||
            compression, band = args
 | 
			
		||||
 | 
			
		||||
            assert self.fp is not None
 | 
			
		||||
            self.fp.seek(self.tile[0].offset)
 | 
			
		||||
 | 
			
		||||
            # Copy image data to temporary file
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -252,6 +252,7 @@ class Jpeg2KImageFile(ImageFile.ImageFile):
 | 
			
		|||
    format_description = "JPEG 2000 (ISO 15444)"
 | 
			
		||||
 | 
			
		||||
    def _open(self) -> None:
 | 
			
		||||
        assert self.fp is not None
 | 
			
		||||
        sig = self.fp.read(4)
 | 
			
		||||
        if sig == b"\xff\x4f\xff\x51":
 | 
			
		||||
            self.codec = "j2k"
 | 
			
		||||
| 
						 | 
				
			
			@ -304,6 +305,7 @@ class Jpeg2KImageFile(ImageFile.ImageFile):
 | 
			
		|||
        ]
 | 
			
		||||
 | 
			
		||||
    def _parse_comment(self) -> None:
 | 
			
		||||
        assert self.fp is not None
 | 
			
		||||
        while True:
 | 
			
		||||
            marker = self.fp.read(2)
 | 
			
		||||
            if not marker:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -61,6 +61,7 @@ if TYPE_CHECKING:
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
def Skip(self: JpegImageFile, marker: int) -> None:
 | 
			
		||||
    assert self.fp is not None
 | 
			
		||||
    n = i16(self.fp.read(2)) - 2
 | 
			
		||||
    ImageFile._safe_read(self.fp, n)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -70,6 +71,7 @@ def APP(self: JpegImageFile, marker: int) -> None:
 | 
			
		|||
    # Application marker.  Store these in the APP dictionary.
 | 
			
		||||
    # Also look for well-known application markers.
 | 
			
		||||
 | 
			
		||||
    assert self.fp is not None
 | 
			
		||||
    n = i16(self.fp.read(2)) - 2
 | 
			
		||||
    s = ImageFile._safe_read(self.fp, n)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -174,6 +176,7 @@ def APP(self: JpegImageFile, marker: int) -> None:
 | 
			
		|||
def COM(self: JpegImageFile, marker: int) -> None:
 | 
			
		||||
    #
 | 
			
		||||
    # Comment marker.  Store these in the APP dictionary.
 | 
			
		||||
    assert self.fp is not None
 | 
			
		||||
    n = i16(self.fp.read(2)) - 2
 | 
			
		||||
    s = ImageFile._safe_read(self.fp, n)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -190,6 +193,7 @@ def SOF(self: JpegImageFile, marker: int) -> None:
 | 
			
		|||
    # mode.  Note that this could be made a bit brighter, by
 | 
			
		||||
    # looking for JFIF and Adobe APP markers.
 | 
			
		||||
 | 
			
		||||
    assert self.fp is not None
 | 
			
		||||
    n = i16(self.fp.read(2)) - 2
 | 
			
		||||
    s = ImageFile._safe_read(self.fp, n)
 | 
			
		||||
    self._size = i16(s, 3), i16(s, 1)
 | 
			
		||||
| 
						 | 
				
			
			@ -240,6 +244,7 @@ def DQT(self: JpegImageFile, marker: int) -> None:
 | 
			
		|||
    # FIXME: The quantization tables can be used to estimate the
 | 
			
		||||
    # compression quality.
 | 
			
		||||
 | 
			
		||||
    assert self.fp is not None
 | 
			
		||||
    n = i16(self.fp.read(2)) - 2
 | 
			
		||||
    s = ImageFile._safe_read(self.fp, n)
 | 
			
		||||
    while len(s):
 | 
			
		||||
| 
						 | 
				
			
			@ -340,6 +345,7 @@ class JpegImageFile(ImageFile.ImageFile):
 | 
			
		|||
    format_description = "JPEG (ISO 10918)"
 | 
			
		||||
 | 
			
		||||
    def _open(self) -> None:
 | 
			
		||||
        assert self.fp is not None
 | 
			
		||||
        s = self.fp.read(3)
 | 
			
		||||
 | 
			
		||||
        if not _accept(s):
 | 
			
		||||
| 
						 | 
				
			
			@ -408,6 +414,7 @@ class JpegImageFile(ImageFile.ImageFile):
 | 
			
		|||
        For premature EOF and LOAD_TRUNCATED_IMAGES adds EOI marker
 | 
			
		||||
        so libjpeg can finish decoding
 | 
			
		||||
        """
 | 
			
		||||
        assert self.fp is not None
 | 
			
		||||
        s = self.fp.read(read_bytes)
 | 
			
		||||
 | 
			
		||||
        if not s and ImageFile.LOAD_TRUNCATED_IMAGES and not hasattr(self, "_ended"):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -67,6 +67,7 @@ class MicImageFile(TiffImagePlugin.TiffImageFile):
 | 
			
		|||
        self._n_frames = len(self.images)
 | 
			
		||||
        self.is_animated = self._n_frames > 1
 | 
			
		||||
 | 
			
		||||
        assert self.fp is not None
 | 
			
		||||
        self.__fp = self.fp
 | 
			
		||||
        self.seek(0)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -106,6 +106,7 @@ class MpoImageFile(JpegImagePlugin.JpegImageFile):
 | 
			
		|||
    _close_exclusive_fp_after_loading = False
 | 
			
		||||
 | 
			
		||||
    def _open(self) -> None:
 | 
			
		||||
        assert self.fp is not None
 | 
			
		||||
        self.fp.seek(0)  # prep the fp in order to pass the JPEG test
 | 
			
		||||
        JpegImagePlugin.JpegImageFile._open(self)
 | 
			
		||||
        self._after_jpeg_open()
 | 
			
		||||
| 
						 | 
				
			
			@ -125,6 +126,7 @@ class MpoImageFile(JpegImagePlugin.JpegImageFile):
 | 
			
		|||
        assert self.n_frames == len(self.__mpoffsets)
 | 
			
		||||
        del self.info["mpoffset"]  # no longer needed
 | 
			
		||||
        self.is_animated = self.n_frames > 1
 | 
			
		||||
        assert self.fp is not None
 | 
			
		||||
        self._fp = self.fp  # FIXME: hack
 | 
			
		||||
        self._fp.seek(self.__mpoffsets[0])  # get ready to read first frame
 | 
			
		||||
        self.__frame = 0
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -757,6 +757,7 @@ class PngImageFile(ImageFile.ImageFile):
 | 
			
		|||
    format_description = "Portable network graphics"
 | 
			
		||||
 | 
			
		||||
    def _open(self) -> None:
 | 
			
		||||
        assert self.fp is not None
 | 
			
		||||
        if not _accept(self.fp.read(8)):
 | 
			
		||||
            msg = "not a PNG file"
 | 
			
		||||
            raise SyntaxError(msg)
 | 
			
		||||
| 
						 | 
				
			
			@ -988,6 +989,7 @@ class PngImageFile(ImageFile.ImageFile):
 | 
			
		|||
        """internal: read more image data"""
 | 
			
		||||
 | 
			
		||||
        assert self.png is not None
 | 
			
		||||
        assert self.fp is not None
 | 
			
		||||
        while self.__idat == 0:
 | 
			
		||||
            # end of chunk, skip forward to next one
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1021,6 +1023,7 @@ class PngImageFile(ImageFile.ImageFile):
 | 
			
		|||
    def load_end(self) -> None:
 | 
			
		||||
        """internal: finished reading image data"""
 | 
			
		||||
        assert self.png is not None
 | 
			
		||||
        assert self.fp is not None
 | 
			
		||||
        if self.__idat != 0:
 | 
			
		||||
            self.fp.read(self.__idat)
 | 
			
		||||
        while True:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -61,6 +61,7 @@ class PsdImageFile(ImageFile.ImageFile):
 | 
			
		|||
    _close_exclusive_fp_after_loading = False
 | 
			
		||||
 | 
			
		||||
    def _open(self) -> None:
 | 
			
		||||
        assert self.fp is not None
 | 
			
		||||
        read = self.fp.read
 | 
			
		||||
 | 
			
		||||
        #
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,6 +25,7 @@ class QoiImageFile(ImageFile.ImageFile):
 | 
			
		|||
    format_description = "Quite OK Image"
 | 
			
		||||
 | 
			
		||||
    def _open(self) -> None:
 | 
			
		||||
        assert self.fp is not None
 | 
			
		||||
        if not _accept(self.fp.read(4)):
 | 
			
		||||
            msg = "not a QOI file"
 | 
			
		||||
            raise SyntaxError(msg)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -104,6 +104,7 @@ class SpiderImageFile(ImageFile.ImageFile):
 | 
			
		|||
    def _open(self) -> None:
 | 
			
		||||
        # check header
 | 
			
		||||
        n = 27 * 4  # read 27 float values
 | 
			
		||||
        assert self.fp is not None
 | 
			
		||||
        f = self.fp.read(n)
 | 
			
		||||
 | 
			
		||||
        try:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -39,6 +39,7 @@ class WalImageFile(ImageFile.ImageFile):
 | 
			
		|||
        self._mode = "P"
 | 
			
		||||
 | 
			
		||||
        # read header fields
 | 
			
		||||
        assert self.fp is not None
 | 
			
		||||
        header = self.fp.read(32 + 24 + 32 + 12)
 | 
			
		||||
        self._size = i32(header, 32), i32(header, 36)
 | 
			
		||||
        Image._decompression_bomb_check(self.size)
 | 
			
		||||
| 
						 | 
				
			
			@ -54,6 +55,7 @@ class WalImageFile(ImageFile.ImageFile):
 | 
			
		|||
 | 
			
		||||
    def load(self) -> Image.core.PixelAccess | None:
 | 
			
		||||
        if self._im is None:
 | 
			
		||||
            assert self.fp is not None
 | 
			
		||||
            self.im = Image.core.new(self.mode, self.size)
 | 
			
		||||
            self.frombytes(self.fp.read(self.size[0] * self.size[1]))
 | 
			
		||||
            self.putpalette(quake2palette)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -45,6 +45,7 @@ class WebPImageFile(ImageFile.ImageFile):
 | 
			
		|||
    def _open(self) -> None:
 | 
			
		||||
        # Use the newer AnimDecoder API to parse the (possibly) animated file,
 | 
			
		||||
        # and access muxed chunks like ICC/EXIF/XMP.
 | 
			
		||||
        assert self.fp is not None
 | 
			
		||||
        self._decoder = _webp.WebPAnimDecoder(self.fp.read())
 | 
			
		||||
 | 
			
		||||
        # Get info from decoder
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -49,6 +49,7 @@ if hasattr(Image.core, "drawwmf"):
 | 
			
		|||
            self.bbox = im.info["wmf_bbox"]
 | 
			
		||||
 | 
			
		||||
        def load(self, im: ImageFile.StubImageFile) -> Image.Image:
 | 
			
		||||
            assert im.fp is not None
 | 
			
		||||
            im.fp.seek(0)  # rewind
 | 
			
		||||
            return Image.frombytes(
 | 
			
		||||
                "RGB",
 | 
			
		||||
| 
						 | 
				
			
			@ -81,6 +82,7 @@ class WmfStubImageFile(ImageFile.StubImageFile):
 | 
			
		|||
 | 
			
		||||
    def _open(self) -> None:
 | 
			
		||||
        # check placeable header
 | 
			
		||||
        assert self.fp is not None
 | 
			
		||||
        s = self.fp.read(44)
 | 
			
		||||
 | 
			
		||||
        if s.startswith(b"\xd7\xcd\xc6\x9a\x00\x00"):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user