mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-02-23 23:30:34 +03:00
Merge branch 'main' into pre-commit-ci-update-config
This commit is contained in:
commit
3344f57206
4
.github/workflows/test-cygwin.yml
vendored
4
.github/workflows/test-cygwin.yml
vendored
|
@ -55,6 +55,7 @@ jobs:
|
||||||
packages: >
|
packages: >
|
||||||
gcc-g++
|
gcc-g++
|
||||||
ghostscript
|
ghostscript
|
||||||
|
git
|
||||||
ImageMagick
|
ImageMagick
|
||||||
jpeg
|
jpeg
|
||||||
libfreetype-devel
|
libfreetype-devel
|
||||||
|
@ -132,11 +133,12 @@ jobs:
|
||||||
bash.exe .ci/after_success.sh
|
bash.exe .ci/after_success.sh
|
||||||
|
|
||||||
- name: Upload coverage
|
- name: Upload coverage
|
||||||
uses: codecov/codecov-action@v3.1.5
|
uses: codecov/codecov-action@v4
|
||||||
with:
|
with:
|
||||||
file: ./coverage.xml
|
file: ./coverage.xml
|
||||||
flags: GHA_Cygwin
|
flags: GHA_Cygwin
|
||||||
name: Cygwin Python 3.${{ matrix.python-minor-version }}
|
name: Cygwin Python 3.${{ matrix.python-minor-version }}
|
||||||
|
token: ${{ secrets.CODECOV_ORG_TOKEN }}
|
||||||
|
|
||||||
success:
|
success:
|
||||||
permissions:
|
permissions:
|
||||||
|
|
3
.github/workflows/test-docker.yml
vendored
3
.github/workflows/test-docker.yml
vendored
|
@ -100,11 +100,12 @@ jobs:
|
||||||
MATRIX_DOCKER: ${{ matrix.docker }}
|
MATRIX_DOCKER: ${{ matrix.docker }}
|
||||||
|
|
||||||
- name: Upload coverage
|
- name: Upload coverage
|
||||||
uses: codecov/codecov-action@v3.1.5
|
uses: codecov/codecov-action@v4
|
||||||
with:
|
with:
|
||||||
flags: GHA_Docker
|
flags: GHA_Docker
|
||||||
name: ${{ matrix.docker }}
|
name: ${{ matrix.docker }}
|
||||||
gcov: true
|
gcov: true
|
||||||
|
token: ${{ secrets.CODECOV_ORG_TOKEN }}
|
||||||
|
|
||||||
success:
|
success:
|
||||||
permissions:
|
permissions:
|
||||||
|
|
3
.github/workflows/test-mingw.yml
vendored
3
.github/workflows/test-mingw.yml
vendored
|
@ -85,8 +85,9 @@ jobs:
|
||||||
python3 -m pytest -vx --cov PIL --cov Tests --cov-report term --cov-report xml Tests
|
python3 -m pytest -vx --cov PIL --cov Tests --cov-report term --cov-report xml Tests
|
||||||
|
|
||||||
- name: Upload coverage
|
- name: Upload coverage
|
||||||
uses: codecov/codecov-action@v3.1.5
|
uses: codecov/codecov-action@v4
|
||||||
with:
|
with:
|
||||||
file: ./coverage.xml
|
file: ./coverage.xml
|
||||||
flags: GHA_Windows
|
flags: GHA_Windows
|
||||||
name: "MSYS2 MinGW"
|
name: "MSYS2 MinGW"
|
||||||
|
token: ${{ secrets.CODECOV_ORG_TOKEN }}
|
||||||
|
|
3
.github/workflows/test-windows.yml
vendored
3
.github/workflows/test-windows.yml
vendored
|
@ -213,11 +213,12 @@ jobs:
|
||||||
shell: pwsh
|
shell: pwsh
|
||||||
|
|
||||||
- name: Upload coverage
|
- name: Upload coverage
|
||||||
uses: codecov/codecov-action@v3.1.5
|
uses: codecov/codecov-action@v4
|
||||||
with:
|
with:
|
||||||
file: ./coverage.xml
|
file: ./coverage.xml
|
||||||
flags: GHA_Windows
|
flags: GHA_Windows
|
||||||
name: ${{ runner.os }} Python ${{ matrix.python-version }}
|
name: ${{ runner.os }} Python ${{ matrix.python-version }}
|
||||||
|
token: ${{ secrets.CODECOV_ORG_TOKEN }}
|
||||||
|
|
||||||
success:
|
success:
|
||||||
permissions:
|
permissions:
|
||||||
|
|
3
.github/workflows/test.yml
vendored
3
.github/workflows/test.yml
vendored
|
@ -150,11 +150,12 @@ jobs:
|
||||||
.ci/after_success.sh
|
.ci/after_success.sh
|
||||||
|
|
||||||
- name: Upload coverage
|
- name: Upload coverage
|
||||||
uses: codecov/codecov-action@v3.1.5
|
uses: codecov/codecov-action@v4
|
||||||
with:
|
with:
|
||||||
flags: ${{ matrix.os == 'ubuntu-latest' && 'GHA_Ubuntu' || 'GHA_macOS' }}
|
flags: ${{ matrix.os == 'ubuntu-latest' && 'GHA_Ubuntu' || 'GHA_macOS' }}
|
||||||
name: ${{ matrix.os }} Python ${{ matrix.python-version }}
|
name: ${{ matrix.os }} Python ${{ matrix.python-version }}
|
||||||
gcov: true
|
gcov: true
|
||||||
|
token: ${{ secrets.CODECOV_ORG_TOKEN }}
|
||||||
|
|
||||||
success:
|
success:
|
||||||
permissions:
|
permissions:
|
||||||
|
|
|
@ -336,9 +336,7 @@ def test_readline_psfile(tmp_path: Path) -> None:
|
||||||
strings = ["something", "else", "baz", "bif"]
|
strings = ["something", "else", "baz", "bif"]
|
||||||
|
|
||||||
def _test_readline(t: EpsImagePlugin.PSFile, ending: str) -> None:
|
def _test_readline(t: EpsImagePlugin.PSFile, ending: str) -> None:
|
||||||
ending = "Failure with line ending: %s" % (
|
ending = f"Failure with line ending: {''.join(str(ord(s)) for s in ending)}"
|
||||||
"".join("%s" % ord(s) for s in ending)
|
|
||||||
)
|
|
||||||
assert t.readline().strip("\r\n") == "something", ending
|
assert t.readline().strip("\r\n") == "something", ending
|
||||||
assert t.readline().strip("\r\n") == "else", ending
|
assert t.readline().strip("\r\n") == "else", ending
|
||||||
assert t.readline().strip("\r\n") == "baz", ending
|
assert t.readline().strip("\r\n") == "baz", ending
|
||||||
|
|
|
@ -409,13 +409,14 @@ class TestEmbeddable:
|
||||||
from setuptools.command import build_ext
|
from setuptools.command import build_ext
|
||||||
|
|
||||||
with open("embed_pil.c", "w", encoding="utf-8") as fh:
|
with open("embed_pil.c", "w", encoding="utf-8") as fh:
|
||||||
|
home = sys.prefix.replace("\\", "\\\\")
|
||||||
fh.write(
|
fh.write(
|
||||||
"""
|
f"""
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{{
|
||||||
char *home = "%s";
|
char *home = "{home}";
|
||||||
wchar_t *whome = Py_DecodeLocale(home, NULL);
|
wchar_t *whome = Py_DecodeLocale(home, NULL);
|
||||||
Py_SetPythonHome(whome);
|
Py_SetPythonHome(whome);
|
||||||
|
|
||||||
|
@ -430,9 +431,8 @@ int main(int argc, char* argv[])
|
||||||
PyMem_RawFree(whome);
|
PyMem_RawFree(whome);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}}
|
||||||
"""
|
"""
|
||||||
% sys.prefix.replace("\\", "\\\\")
|
|
||||||
)
|
)
|
||||||
|
|
||||||
compiler = getattr(build_ext, "new_compiler")()
|
compiler = getattr(build_ext, "new_compiler")()
|
||||||
|
|
|
@ -165,9 +165,9 @@ if __name__ == "__main__":
|
||||||
print("Running selftest:")
|
print("Running selftest:")
|
||||||
status = doctest.testmod(sys.modules[__name__])
|
status = doctest.testmod(sys.modules[__name__])
|
||||||
if status[0]:
|
if status[0]:
|
||||||
print("*** %s tests of %d failed." % status)
|
print(f"*** {status[0]} tests of {status[1]} failed.")
|
||||||
exit_status = 1
|
exit_status = 1
|
||||||
else:
|
else:
|
||||||
print("--- %s tests passed." % status[1])
|
print(f"--- {status[1]} tests passed.")
|
||||||
|
|
||||||
sys.exit(exit_status)
|
sys.exit(exit_status)
|
||||||
|
|
|
@ -253,7 +253,7 @@ class BlpImageFile(ImageFile.ImageFile):
|
||||||
format = "BLP"
|
format = "BLP"
|
||||||
format_description = "Blizzard Mipmap Format"
|
format_description = "Blizzard Mipmap Format"
|
||||||
|
|
||||||
def _open(self):
|
def _open(self) -> None:
|
||||||
self.magic = self.fp.read(4)
|
self.magic = self.fp.read(4)
|
||||||
|
|
||||||
self.fp.seek(5, os.SEEK_CUR)
|
self.fp.seek(5, os.SEEK_CUR)
|
||||||
|
@ -333,7 +333,7 @@ class _BLPBaseDecoder(ImageFile.PyDecoder):
|
||||||
|
|
||||||
|
|
||||||
class BLP1Decoder(_BLPBaseDecoder):
|
class BLP1Decoder(_BLPBaseDecoder):
|
||||||
def _load(self):
|
def _load(self) -> None:
|
||||||
if self._blp_compression == Format.JPEG:
|
if self._blp_compression == Format.JPEG:
|
||||||
self._decode_jpeg_stream()
|
self._decode_jpeg_stream()
|
||||||
|
|
||||||
|
@ -418,7 +418,7 @@ class BLP2Decoder(_BLPBaseDecoder):
|
||||||
class BLPEncoder(ImageFile.PyEncoder):
|
class BLPEncoder(ImageFile.PyEncoder):
|
||||||
_pushes_fd = True
|
_pushes_fd = True
|
||||||
|
|
||||||
def _write_palette(self):
|
def _write_palette(self) -> bytes:
|
||||||
data = b""
|
data = b""
|
||||||
palette = self.im.getpalette("RGBA", "RGBA")
|
palette = self.im.getpalette("RGBA", "RGBA")
|
||||||
for i in range(len(palette) // 4):
|
for i in range(len(palette) // 4):
|
||||||
|
|
|
@ -283,7 +283,7 @@ class BmpImageFile(ImageFile.ImageFile):
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
def _open(self):
|
def _open(self) -> None:
|
||||||
"""Open file, check magic number and read header"""
|
"""Open file, check magic number and read header"""
|
||||||
# read 14 bytes: magic number, filesize, reserved, header final offset
|
# read 14 bytes: magic number, filesize, reserved, header final offset
|
||||||
head_data = self.fp.read(14)
|
head_data = self.fp.read(14)
|
||||||
|
@ -376,7 +376,7 @@ class DibImageFile(BmpImageFile):
|
||||||
format = "DIB"
|
format = "DIB"
|
||||||
format_description = "Windows Bitmap"
|
format_description = "Windows Bitmap"
|
||||||
|
|
||||||
def _open(self):
|
def _open(self) -> None:
|
||||||
self._bitmap()
|
self._bitmap()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,7 @@ class DcxImageFile(PcxImageFile):
|
||||||
self.is_animated = self.n_frames > 1
|
self.is_animated = self.n_frames > 1
|
||||||
self.seek(0)
|
self.seek(0)
|
||||||
|
|
||||||
def seek(self, frame):
|
def seek(self, frame: int) -> None:
|
||||||
if not self._seek_check(frame):
|
if not self._seek_check(frame):
|
||||||
return
|
return
|
||||||
self.frame = frame
|
self.frame = frame
|
||||||
|
@ -71,7 +71,7 @@ class DcxImageFile(PcxImageFile):
|
||||||
self.fp.seek(self._offset[frame])
|
self.fp.seek(self._offset[frame])
|
||||||
PcxImageFile._open(self)
|
PcxImageFile._open(self)
|
||||||
|
|
||||||
def tell(self):
|
def tell(self) -> int:
|
||||||
return self.frame
|
return self.frame
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -331,7 +331,7 @@ class DdsImageFile(ImageFile.ImageFile):
|
||||||
format = "DDS"
|
format = "DDS"
|
||||||
format_description = "DirectDraw Surface"
|
format_description = "DirectDraw Surface"
|
||||||
|
|
||||||
def _open(self):
|
def _open(self) -> None:
|
||||||
if not _accept(self.fp.read(4)):
|
if not _accept(self.fp.read(4)):
|
||||||
msg = "not a DDS file"
|
msg = "not a DDS file"
|
||||||
raise SyntaxError(msg)
|
raise SyntaxError(msg)
|
||||||
|
|
|
@ -178,7 +178,7 @@ class PSFile:
|
||||||
self.char = None
|
self.char = None
|
||||||
self.fp.seek(offset, whence)
|
self.fp.seek(offset, whence)
|
||||||
|
|
||||||
def readline(self):
|
def readline(self) -> str:
|
||||||
s = [self.char or b""]
|
s = [self.char or b""]
|
||||||
self.char = None
|
self.char = None
|
||||||
|
|
||||||
|
@ -212,7 +212,7 @@ class EpsImageFile(ImageFile.ImageFile):
|
||||||
|
|
||||||
mode_map = {1: "L", 2: "LAB", 3: "RGB", 4: "CMYK"}
|
mode_map = {1: "L", 2: "LAB", 3: "RGB", 4: "CMYK"}
|
||||||
|
|
||||||
def _open(self):
|
def _open(self) -> None:
|
||||||
(length, offset) = self._find_offset(self.fp)
|
(length, offset) = self._find_offset(self.fp)
|
||||||
|
|
||||||
# go to offset - start of "%!PS"
|
# go to offset - start of "%!PS"
|
||||||
|
|
|
@ -123,7 +123,7 @@ class FliImageFile(ImageFile.ImageFile):
|
||||||
palette[i] = (r, g, b)
|
palette[i] = (r, g, b)
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
def seek(self, frame):
|
def seek(self, frame: int) -> None:
|
||||||
if not self._seek_check(frame):
|
if not self._seek_check(frame):
|
||||||
return
|
return
|
||||||
if frame < self.__frame:
|
if frame < self.__frame:
|
||||||
|
@ -162,7 +162,7 @@ class FliImageFile(ImageFile.ImageFile):
|
||||||
|
|
||||||
self.__offset += framesize
|
self.__offset += framesize
|
||||||
|
|
||||||
def tell(self):
|
def tell(self) -> int:
|
||||||
return self.__frame
|
return self.__frame
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -76,7 +76,7 @@ class GifImageFile(ImageFile.ImageFile):
|
||||||
|
|
||||||
global_palette = None
|
global_palette = None
|
||||||
|
|
||||||
def data(self):
|
def data(self) -> bytes | None:
|
||||||
s = self.fp.read(1)
|
s = self.fp.read(1)
|
||||||
if s and s[0]:
|
if s and s[0]:
|
||||||
return self.fp.read(s[0])
|
return self.fp.read(s[0])
|
||||||
|
@ -88,7 +88,7 @@ class GifImageFile(ImageFile.ImageFile):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def _open(self):
|
def _open(self) -> None:
|
||||||
# Screen
|
# Screen
|
||||||
s = self.fp.read(13)
|
s = self.fp.read(13)
|
||||||
if not _accept(s):
|
if not _accept(s):
|
||||||
|
@ -147,7 +147,7 @@ class GifImageFile(ImageFile.ImageFile):
|
||||||
self.seek(current)
|
self.seek(current)
|
||||||
return self._is_animated
|
return self._is_animated
|
||||||
|
|
||||||
def seek(self, frame):
|
def seek(self, frame: int) -> None:
|
||||||
if not self._seek_check(frame):
|
if not self._seek_check(frame):
|
||||||
return
|
return
|
||||||
if frame < self.__frame:
|
if frame < self.__frame:
|
||||||
|
@ -417,7 +417,7 @@ class GifImageFile(ImageFile.ImageFile):
|
||||||
elif k in self.info:
|
elif k in self.info:
|
||||||
del self.info[k]
|
del self.info[k]
|
||||||
|
|
||||||
def load_prepare(self):
|
def load_prepare(self) -> None:
|
||||||
temp_mode = "P" if self._frame_palette else "L"
|
temp_mode = "P" if self._frame_palette else "L"
|
||||||
self._prev_im = None
|
self._prev_im = None
|
||||||
if self.__frame == 0:
|
if self.__frame == 0:
|
||||||
|
@ -437,7 +437,7 @@ class GifImageFile(ImageFile.ImageFile):
|
||||||
|
|
||||||
super().load_prepare()
|
super().load_prepare()
|
||||||
|
|
||||||
def load_end(self):
|
def load_end(self) -> None:
|
||||||
if self.__frame == 0:
|
if self.__frame == 0:
|
||||||
if self.mode == "P" and LOADING_STRATEGY == LoadingStrategy.RGB_ALWAYS:
|
if self.mode == "P" and LOADING_STRATEGY == LoadingStrategy.RGB_ALWAYS:
|
||||||
if self._frame_transparency is not None:
|
if self._frame_transparency is not None:
|
||||||
|
@ -463,7 +463,7 @@ class GifImageFile(ImageFile.ImageFile):
|
||||||
else:
|
else:
|
||||||
self.im.paste(frame_im, self.dispose_extent)
|
self.im.paste(frame_im, self.dispose_extent)
|
||||||
|
|
||||||
def tell(self):
|
def tell(self) -> int:
|
||||||
return self.__frame
|
return self.__frame
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ class HDF5StubImageFile(ImageFile.StubImageFile):
|
||||||
format = "HDF5"
|
format = "HDF5"
|
||||||
format_description = "HDF5"
|
format_description = "HDF5"
|
||||||
|
|
||||||
def _open(self):
|
def _open(self) -> None:
|
||||||
offset = self.fp.tell()
|
offset = self.fp.tell()
|
||||||
|
|
||||||
if not _accept(self.fp.read(8)):
|
if not _accept(self.fp.read(8)):
|
||||||
|
|
|
@ -252,7 +252,7 @@ class IcnsImageFile(ImageFile.ImageFile):
|
||||||
format = "ICNS"
|
format = "ICNS"
|
||||||
format_description = "Mac OS icns resource"
|
format_description = "Mac OS icns resource"
|
||||||
|
|
||||||
def _open(self):
|
def _open(self) -> None:
|
||||||
self.icns = IcnsFile(self.fp)
|
self.icns = IcnsFile(self.fp)
|
||||||
self._mode = "RGBA"
|
self._mode = "RGBA"
|
||||||
self.info["sizes"] = self.icns.itersizes()
|
self.info["sizes"] = self.icns.itersizes()
|
||||||
|
|
|
@ -302,7 +302,7 @@ class IcoImageFile(ImageFile.ImageFile):
|
||||||
format = "ICO"
|
format = "ICO"
|
||||||
format_description = "Windows Icon"
|
format_description = "Windows Icon"
|
||||||
|
|
||||||
def _open(self):
|
def _open(self) -> None:
|
||||||
self.ico = IcoFile(self.fp)
|
self.ico = IcoFile(self.fp)
|
||||||
self.info["sizes"] = self.ico.sizes()
|
self.info["sizes"] = self.ico.sizes()
|
||||||
self.size = self.ico.entry[0]["dim"]
|
self.size = self.ico.entry[0]["dim"]
|
||||||
|
|
|
@ -278,7 +278,7 @@ class ImImageFile(ImageFile.ImageFile):
|
||||||
def is_animated(self):
|
def is_animated(self):
|
||||||
return self.info[FRAMES] > 1
|
return self.info[FRAMES] > 1
|
||||||
|
|
||||||
def seek(self, frame):
|
def seek(self, frame: int) -> None:
|
||||||
if not self._seek_check(frame):
|
if not self._seek_check(frame):
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -296,7 +296,7 @@ class ImImageFile(ImageFile.ImageFile):
|
||||||
|
|
||||||
self.tile = [("raw", (0, 0) + self.size, offs, (self.rawmode, 0, -1))]
|
self.tile = [("raw", (0, 0) + self.size, offs, (self.rawmode, 0, -1))]
|
||||||
|
|
||||||
def tell(self):
|
def tell(self) -> int:
|
||||||
return self.frame
|
return self.frame
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1298,7 +1298,10 @@ class Image:
|
||||||
self.load()
|
self.load()
|
||||||
return self._new(self.im.expand(xmargin, ymargin))
|
return self._new(self.im.expand(xmargin, ymargin))
|
||||||
|
|
||||||
def filter(self, filter):
|
if TYPE_CHECKING:
|
||||||
|
from . import ImageFilter
|
||||||
|
|
||||||
|
def filter(self, filter: ImageFilter.Filter | type[ImageFilter.Filter]) -> Image:
|
||||||
"""
|
"""
|
||||||
Filters this image using the given filter. For a list of
|
Filters this image using the given filter. For a list of
|
||||||
available filters, see the :py:mod:`~PIL.ImageFilter` module.
|
available filters, see the :py:mod:`~PIL.ImageFilter` module.
|
||||||
|
@ -1310,7 +1313,7 @@ class Image:
|
||||||
|
|
||||||
self.load()
|
self.load()
|
||||||
|
|
||||||
if isinstance(filter, Callable):
|
if callable(filter):
|
||||||
filter = filter()
|
filter = filter()
|
||||||
if not hasattr(filter, "filter"):
|
if not hasattr(filter, "filter"):
|
||||||
msg = "filter argument should be ImageFilter.Filter instance or class"
|
msg = "filter argument should be ImageFilter.Filter instance or class"
|
||||||
|
|
|
@ -311,7 +311,7 @@ class ImageFile(Image.Image):
|
||||||
|
|
||||||
return Image.Image.load(self)
|
return Image.Image.load(self)
|
||||||
|
|
||||||
def load_prepare(self):
|
def load_prepare(self) -> None:
|
||||||
# create image memory if necessary
|
# create image memory if necessary
|
||||||
if not self.im or self.im.mode != self.mode or self.im.size != self.size:
|
if not self.im or self.im.mode != self.mode or self.im.size != self.size:
|
||||||
self.im = Image.core.new(self.mode, self.size)
|
self.im = Image.core.new(self.mode, self.size)
|
||||||
|
@ -319,7 +319,7 @@ class ImageFile(Image.Image):
|
||||||
if self.mode == "P":
|
if self.mode == "P":
|
||||||
Image.Image.load(self)
|
Image.Image.load(self)
|
||||||
|
|
||||||
def load_end(self):
|
def load_end(self) -> None:
|
||||||
# may be overridden
|
# may be overridden
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -390,7 +390,7 @@ class Parser:
|
||||||
offset = 0
|
offset = 0
|
||||||
finished = 0
|
finished = 0
|
||||||
|
|
||||||
def reset(self):
|
def reset(self) -> None:
|
||||||
"""
|
"""
|
||||||
(Consumer) Reset the parser. Note that you can only call this
|
(Consumer) Reset the parser. Note that you can only call this
|
||||||
method immediately after you've created a parser; parser
|
method immediately after you've created a parser; parser
|
||||||
|
@ -605,7 +605,7 @@ def _safe_read(fp, size):
|
||||||
|
|
||||||
|
|
||||||
class PyCodecState:
|
class PyCodecState:
|
||||||
def __init__(self):
|
def __init__(self) -> None:
|
||||||
self.xsize = 0
|
self.xsize = 0
|
||||||
self.ysize = 0
|
self.ysize = 0
|
||||||
self.xoff = 0
|
self.xoff = 0
|
||||||
|
@ -634,7 +634,7 @@ class PyCodec:
|
||||||
"""
|
"""
|
||||||
self.args = args
|
self.args = args
|
||||||
|
|
||||||
def cleanup(self):
|
def cleanup(self) -> None:
|
||||||
"""
|
"""
|
||||||
Override to perform codec specific cleanup
|
Override to perform codec specific cleanup
|
||||||
|
|
||||||
|
|
|
@ -16,11 +16,14 @@
|
||||||
#
|
#
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import abc
|
||||||
import functools
|
import functools
|
||||||
|
|
||||||
|
|
||||||
class Filter:
|
class Filter:
|
||||||
pass
|
@abc.abstractmethod
|
||||||
|
def filter(self, image):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class MultibandFilter(Filter):
|
class MultibandFilter(Filter):
|
||||||
|
|
|
@ -204,7 +204,7 @@ class Window:
|
||||||
def ui_handle_damage(self, x0, y0, x1, y1):
|
def ui_handle_damage(self, x0, y0, x1, y1):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def ui_handle_destroy(self):
|
def ui_handle_destroy(self) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def ui_handle_repair(self, dc, x0, y0, x1, y1):
|
def ui_handle_repair(self, dc, x0, y0, x1, y1):
|
||||||
|
@ -213,7 +213,7 @@ class Window:
|
||||||
def ui_handle_resize(self, width, height):
|
def ui_handle_resize(self, width, height):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def mainloop(self):
|
def mainloop(self) -> None:
|
||||||
Image.core.eventloop()
|
Image.core.eventloop()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ def dump(c: Sequence[int | bytes]) -> None:
|
||||||
""".. deprecated:: 10.2.0"""
|
""".. deprecated:: 10.2.0"""
|
||||||
deprecate("IptcImagePlugin.dump", 12)
|
deprecate("IptcImagePlugin.dump", 12)
|
||||||
for i in c:
|
for i in c:
|
||||||
print("%02x" % _i8(i), end=" ")
|
print(f"{_i8(i):02x}", end=" ")
|
||||||
print()
|
print()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ class MicImageFile(TiffImagePlugin.TiffImageFile):
|
||||||
format_description = "Microsoft Image Composer"
|
format_description = "Microsoft Image Composer"
|
||||||
_close_exclusive_fp_after_loading = False
|
_close_exclusive_fp_after_loading = False
|
||||||
|
|
||||||
def _open(self):
|
def _open(self) -> None:
|
||||||
# read the OLE directory and see if this is a likely
|
# read the OLE directory and see if this is a likely
|
||||||
# to be a Microsoft Image Composer file
|
# to be a Microsoft Image Composer file
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ class MicImageFile(TiffImagePlugin.TiffImageFile):
|
||||||
def tell(self):
|
def tell(self):
|
||||||
return self.frame
|
return self.frame
|
||||||
|
|
||||||
def close(self):
|
def close(self) -> None:
|
||||||
self.__fp.close()
|
self.__fp.close()
|
||||||
self.ole.close()
|
self.ole.close()
|
||||||
super().close()
|
super().close()
|
||||||
|
|
|
@ -127,7 +127,7 @@ class MpoImageFile(JpegImagePlugin.JpegImageFile):
|
||||||
def load_seek(self, pos):
|
def load_seek(self, pos):
|
||||||
self._fp.seek(pos)
|
self._fp.seek(pos)
|
||||||
|
|
||||||
def seek(self, frame):
|
def seek(self, frame: int) -> None:
|
||||||
if not self._seek_check(frame):
|
if not self._seek_check(frame):
|
||||||
return
|
return
|
||||||
self.fp = self._fp
|
self.fp = self._fp
|
||||||
|
@ -149,7 +149,7 @@ class MpoImageFile(JpegImagePlugin.JpegImageFile):
|
||||||
self.tile = [("jpeg", (0, 0) + self.size, self.offset, self.tile[0][-1])]
|
self.tile = [("jpeg", (0, 0) + self.size, self.offset, self.tile[0][-1])]
|
||||||
self.__frame = frame
|
self.__frame = frame
|
||||||
|
|
||||||
def tell(self):
|
def tell(self) -> int:
|
||||||
return self.__frame
|
return self.__frame
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|
|
@ -823,11 +823,10 @@ class PdfParser:
|
||||||
m = cls.re_stream_start.match(data, offset)
|
m = cls.re_stream_start.match(data, offset)
|
||||||
if m:
|
if m:
|
||||||
try:
|
try:
|
||||||
stream_len = int(result[b"Length"])
|
stream_len_str = result.get(b"Length")
|
||||||
except (TypeError, KeyError, ValueError) as e:
|
stream_len = int(stream_len_str)
|
||||||
msg = "bad or missing Length in stream dict (%r)" % result.get(
|
except (TypeError, ValueError) as e:
|
||||||
b"Length", None
|
msg = f"bad or missing Length in stream dict ({stream_len_str})"
|
||||||
)
|
|
||||||
raise PdfFormatError(msg) from e
|
raise PdfFormatError(msg) from e
|
||||||
stream_data = data[m.end() : m.end() + stream_len]
|
stream_data = data[m.end() : m.end() + stream_len]
|
||||||
m = cls.re_stream_end.match(data, m.end() + stream_len)
|
m = cls.re_stream_end.match(data, m.end() + stream_len)
|
||||||
|
|
|
@ -800,7 +800,7 @@ class PngImageFile(ImageFile.ImageFile):
|
||||||
self.fp.close()
|
self.fp.close()
|
||||||
self.fp = None
|
self.fp = None
|
||||||
|
|
||||||
def seek(self, frame):
|
def seek(self, frame: int) -> None:
|
||||||
if not self._seek_check(frame):
|
if not self._seek_check(frame):
|
||||||
return
|
return
|
||||||
if frame < self.__frame:
|
if frame < self.__frame:
|
||||||
|
@ -909,10 +909,10 @@ class PngImageFile(ImageFile.ImageFile):
|
||||||
else:
|
else:
|
||||||
self.dispose = None
|
self.dispose = None
|
||||||
|
|
||||||
def tell(self):
|
def tell(self) -> int:
|
||||||
return self.__frame
|
return self.__frame
|
||||||
|
|
||||||
def load_prepare(self):
|
def load_prepare(self) -> None:
|
||||||
"""internal: prepare to read PNG file"""
|
"""internal: prepare to read PNG file"""
|
||||||
|
|
||||||
if self.info.get("interlace"):
|
if self.info.get("interlace"):
|
||||||
|
@ -954,7 +954,7 @@ class PngImageFile(ImageFile.ImageFile):
|
||||||
|
|
||||||
return self.fp.read(read_bytes)
|
return self.fp.read(read_bytes)
|
||||||
|
|
||||||
def load_end(self):
|
def load_end(self) -> None:
|
||||||
"""internal: finished reading image data"""
|
"""internal: finished reading image data"""
|
||||||
if self.__idat != 0:
|
if self.__idat != 0:
|
||||||
self.fp.read(self.__idat)
|
self.fp.read(self.__idat)
|
||||||
|
|
|
@ -57,7 +57,7 @@ class PsdImageFile(ImageFile.ImageFile):
|
||||||
format_description = "Adobe Photoshop"
|
format_description = "Adobe Photoshop"
|
||||||
_close_exclusive_fp_after_loading = False
|
_close_exclusive_fp_after_loading = False
|
||||||
|
|
||||||
def _open(self):
|
def _open(self) -> None:
|
||||||
read = self.fp.read
|
read = self.fp.read
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -141,23 +141,22 @@ class PsdImageFile(ImageFile.ImageFile):
|
||||||
self.frame = 1
|
self.frame = 1
|
||||||
self._min_frame = 1
|
self._min_frame = 1
|
||||||
|
|
||||||
def seek(self, layer):
|
def seek(self, layer: int) -> None:
|
||||||
if not self._seek_check(layer):
|
if not self._seek_check(layer):
|
||||||
return
|
return
|
||||||
|
|
||||||
# seek to given layer (1..max)
|
# seek to given layer (1..max)
|
||||||
try:
|
try:
|
||||||
name, mode, bbox, tile = self.layers[layer - 1]
|
_, mode, _, tile = self.layers[layer - 1]
|
||||||
self._mode = mode
|
self._mode = mode
|
||||||
self.tile = tile
|
self.tile = tile
|
||||||
self.frame = layer
|
self.frame = layer
|
||||||
self.fp = self._fp
|
self.fp = self._fp
|
||||||
return name, bbox
|
|
||||||
except IndexError as e:
|
except IndexError as e:
|
||||||
msg = "no such layer"
|
msg = "no such layer"
|
||||||
raise EOFError(msg) from e
|
raise EOFError(msg) from e
|
||||||
|
|
||||||
def tell(self):
|
def tell(self) -> int:
|
||||||
# return layer number (0=image, 1..max=layers)
|
# return layer number (0=image, 1..max=layers)
|
||||||
return self.frame
|
return self.frame
|
||||||
|
|
||||||
|
|
|
@ -97,7 +97,7 @@ class SpiderImageFile(ImageFile.ImageFile):
|
||||||
format_description = "Spider 2D image"
|
format_description = "Spider 2D image"
|
||||||
_close_exclusive_fp_after_loading = False
|
_close_exclusive_fp_after_loading = False
|
||||||
|
|
||||||
def _open(self):
|
def _open(self) -> None:
|
||||||
# check header
|
# check header
|
||||||
n = 27 * 4 # read 27 float values
|
n = 27 * 4 # read 27 float values
|
||||||
f = self.fp.read(n)
|
f = self.fp.read(n)
|
||||||
|
@ -165,13 +165,13 @@ class SpiderImageFile(ImageFile.ImageFile):
|
||||||
return self._nimages > 1
|
return self._nimages > 1
|
||||||
|
|
||||||
# 1st image index is zero (although SPIDER imgnumber starts at 1)
|
# 1st image index is zero (although SPIDER imgnumber starts at 1)
|
||||||
def tell(self):
|
def tell(self) -> int:
|
||||||
if self.imgnumber < 1:
|
if self.imgnumber < 1:
|
||||||
return 0
|
return 0
|
||||||
else:
|
else:
|
||||||
return self.imgnumber - 1
|
return self.imgnumber - 1
|
||||||
|
|
||||||
def seek(self, frame):
|
def seek(self, frame: int) -> None:
|
||||||
if self.istack == 0:
|
if self.istack == 0:
|
||||||
msg = "attempt to seek in a non-stack file"
|
msg = "attempt to seek in a non-stack file"
|
||||||
raise EOFError(msg)
|
raise EOFError(msg)
|
||||||
|
|
|
@ -1143,7 +1143,7 @@ class TiffImageFile(ImageFile.ImageFile):
|
||||||
self.seek(current)
|
self.seek(current)
|
||||||
return self._n_frames
|
return self._n_frames
|
||||||
|
|
||||||
def seek(self, frame):
|
def seek(self, frame: int) -> None:
|
||||||
"""Select a given frame as current image"""
|
"""Select a given frame as current image"""
|
||||||
if not self._seek_check(frame):
|
if not self._seek_check(frame):
|
||||||
return
|
return
|
||||||
|
@ -1198,7 +1198,7 @@ class TiffImageFile(ImageFile.ImageFile):
|
||||||
self.__frame = frame
|
self.__frame = frame
|
||||||
self._setup()
|
self._setup()
|
||||||
|
|
||||||
def tell(self):
|
def tell(self) -> int:
|
||||||
"""Return the current frame number"""
|
"""Return the current frame number"""
|
||||||
return self.__frame
|
return self.__frame
|
||||||
|
|
||||||
|
@ -1237,7 +1237,7 @@ class TiffImageFile(ImageFile.ImageFile):
|
||||||
return self._load_libtiff()
|
return self._load_libtiff()
|
||||||
return super().load()
|
return super().load()
|
||||||
|
|
||||||
def load_end(self):
|
def load_end(self) -> None:
|
||||||
# allow closing if we're on the first frame, there's no next
|
# allow closing if we're on the first frame, there's no next
|
||||||
# This is the ImageFile.load path only, libtiff specific below.
|
# This is the ImageFile.load path only, libtiff specific below.
|
||||||
if not self.is_animated:
|
if not self.is_animated:
|
||||||
|
@ -1942,7 +1942,7 @@ class AppendingTiffWriter:
|
||||||
self.beginning = self.f.tell()
|
self.beginning = self.f.tell()
|
||||||
self.setup()
|
self.setup()
|
||||||
|
|
||||||
def setup(self):
|
def setup(self) -> None:
|
||||||
# Reset everything.
|
# Reset everything.
|
||||||
self.f.seek(self.beginning, os.SEEK_SET)
|
self.f.seek(self.beginning, os.SEEK_SET)
|
||||||
|
|
||||||
|
@ -1967,7 +1967,7 @@ class AppendingTiffWriter:
|
||||||
self.skipIFDs()
|
self.skipIFDs()
|
||||||
self.goToEnd()
|
self.goToEnd()
|
||||||
|
|
||||||
def finalize(self):
|
def finalize(self) -> None:
|
||||||
if self.isFirst:
|
if self.isFirst:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -1990,7 +1990,7 @@ class AppendingTiffWriter:
|
||||||
self.f.seek(ifd_offset)
|
self.f.seek(ifd_offset)
|
||||||
self.fixIFD()
|
self.fixIFD()
|
||||||
|
|
||||||
def newFrame(self):
|
def newFrame(self) -> None:
|
||||||
# Call this to finish a frame.
|
# Call this to finish a frame.
|
||||||
self.finalize()
|
self.finalize()
|
||||||
self.setup()
|
self.setup()
|
||||||
|
@ -2013,7 +2013,7 @@ class AppendingTiffWriter:
|
||||||
self.f.seek(offset, whence)
|
self.f.seek(offset, whence)
|
||||||
return self.tell()
|
return self.tell()
|
||||||
|
|
||||||
def goToEnd(self):
|
def goToEnd(self) -> None:
|
||||||
self.f.seek(0, os.SEEK_END)
|
self.f.seek(0, os.SEEK_END)
|
||||||
pos = self.f.tell()
|
pos = self.f.tell()
|
||||||
|
|
||||||
|
@ -2029,7 +2029,7 @@ class AppendingTiffWriter:
|
||||||
self.shortFmt = f"{self.endian}H"
|
self.shortFmt = f"{self.endian}H"
|
||||||
self.tagFormat = f"{self.endian}HHL"
|
self.tagFormat = f"{self.endian}HHL"
|
||||||
|
|
||||||
def skipIFDs(self):
|
def skipIFDs(self) -> None:
|
||||||
while True:
|
while True:
|
||||||
ifd_offset = self.readLong()
|
ifd_offset = self.readLong()
|
||||||
if ifd_offset == 0:
|
if ifd_offset == 0:
|
||||||
|
@ -2084,11 +2084,11 @@ class AppendingTiffWriter:
|
||||||
msg = f"wrote only {bytes_written} bytes but wanted 4"
|
msg = f"wrote only {bytes_written} bytes but wanted 4"
|
||||||
raise RuntimeError(msg)
|
raise RuntimeError(msg)
|
||||||
|
|
||||||
def close(self):
|
def close(self) -> None:
|
||||||
self.finalize()
|
self.finalize()
|
||||||
self.f.close()
|
self.f.close()
|
||||||
|
|
||||||
def fixIFD(self):
|
def fixIFD(self) -> None:
|
||||||
num_tags = self.readShort()
|
num_tags = self.readShort()
|
||||||
|
|
||||||
for i in range(num_tags):
|
for i in range(num_tags):
|
||||||
|
|
|
@ -32,7 +32,7 @@ class WalImageFile(ImageFile.ImageFile):
|
||||||
format = "WAL"
|
format = "WAL"
|
||||||
format_description = "Quake2 Texture"
|
format_description = "Quake2 Texture"
|
||||||
|
|
||||||
def _open(self):
|
def _open(self) -> None:
|
||||||
self._mode = "P"
|
self._mode = "P"
|
||||||
|
|
||||||
# read header fields
|
# read header fields
|
||||||
|
|
|
@ -109,7 +109,7 @@ class WebPImageFile(ImageFile.ImageFile):
|
||||||
"""
|
"""
|
||||||
return self._getxmp(self.info["xmp"]) if "xmp" in self.info else {}
|
return self._getxmp(self.info["xmp"]) if "xmp" in self.info else {}
|
||||||
|
|
||||||
def seek(self, frame):
|
def seek(self, frame: int) -> None:
|
||||||
if not self._seek_check(frame):
|
if not self._seek_check(frame):
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -174,7 +174,7 @@ class WebPImageFile(ImageFile.ImageFile):
|
||||||
def load_seek(self, pos):
|
def load_seek(self, pos):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def tell(self):
|
def tell(self) -> int:
|
||||||
if not _webp.HAVE_WEBPANIM:
|
if not _webp.HAVE_WEBPANIM:
|
||||||
return super().tell()
|
return super().tell()
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user