From 497080f63b62c9acbb427c7e554f222de70fe3a9 Mon Sep 17 00:00:00 2001 From: Andrew Murray Date: Mon, 5 Aug 2024 15:20:34 +1000 Subject: [PATCH] Added type hint to ImageFile._save tile parameter --- Tests/test_imagefile.py | 30 ++++++++++++++++++++++++------ src/PIL/BlpImagePlugin.py | 2 +- src/PIL/BmpImagePlugin.py | 4 +++- src/PIL/EpsImagePlugin.py | 2 +- src/PIL/GifImagePlugin.py | 8 ++++++-- src/PIL/IcoImagePlugin.py | 4 +++- src/PIL/ImImagePlugin.py | 4 +++- src/PIL/ImageFile.py | 4 ++-- src/PIL/Jpeg2KImagePlugin.py | 2 +- src/PIL/JpegImagePlugin.py | 4 +++- src/PIL/MspImagePlugin.py | 2 +- src/PIL/PalmImagePlugin.py | 4 +++- src/PIL/PcxImagePlugin.py | 4 +++- src/PIL/PdfImagePlugin.py | 2 +- src/PIL/PngImagePlugin.py | 8 ++++---- src/PIL/PpmImagePlugin.py | 4 +++- src/PIL/SpiderImagePlugin.py | 4 +++- src/PIL/TgaImagePlugin.py | 8 ++++++-- src/PIL/XbmImagePlugin.py | 2 +- 19 files changed, 72 insertions(+), 30 deletions(-) diff --git a/Tests/test_imagefile.py b/Tests/test_imagefile.py index fe7d44785..95e91db83 100644 --- a/Tests/test_imagefile.py +++ b/Tests/test_imagefile.py @@ -317,7 +317,13 @@ class TestPyEncoder(CodecsTest): fp = BytesIO() ImageFile._save( - im, fp, [("MOCK", (xoff, yoff, xoff + xsize, yoff + ysize), 0, "RGB")] + im, + fp, + [ + ImageFile._Tile( + "MOCK", (xoff, yoff, xoff + xsize, yoff + ysize), 0, "RGB" + ) + ], ) assert MockPyEncoder.last @@ -333,7 +339,7 @@ class TestPyEncoder(CodecsTest): im.tile = [("MOCK", None, 32, None)] fp = BytesIO() - ImageFile._save(im, fp, [("MOCK", None, 0, "RGB")]) + ImageFile._save(im, fp, [ImageFile._Tile("MOCK", None, 0, "RGB")]) assert MockPyEncoder.last assert MockPyEncoder.last.state.xoff == 0 @@ -350,7 +356,9 @@ class TestPyEncoder(CodecsTest): MockPyEncoder.last = None with pytest.raises(ValueError): ImageFile._save( - im, fp, [("MOCK", (xoff, yoff, -10, yoff + ysize), 0, "RGB")] + im, + fp, + [ImageFile._Tile("MOCK", (xoff, yoff, -10, yoff + ysize), 0, "RGB")], ) last: MockPyEncoder | None = MockPyEncoder.last assert last @@ -358,7 +366,9 @@ class TestPyEncoder(CodecsTest): with pytest.raises(ValueError): ImageFile._save( - im, fp, [("MOCK", (xoff, yoff, xoff + xsize, -10), 0, "RGB")] + im, + fp, + [ImageFile._Tile("MOCK", (xoff, yoff, xoff + xsize, -10), 0, "RGB")], ) def test_oversize(self) -> None: @@ -371,14 +381,22 @@ class TestPyEncoder(CodecsTest): ImageFile._save( im, fp, - [("MOCK", (xoff, yoff, xoff + xsize + 100, yoff + ysize), 0, "RGB")], + [ + ImageFile._Tile( + "MOCK", (xoff, yoff, xoff + xsize + 100, yoff + ysize), 0, "RGB" + ) + ], ) with pytest.raises(ValueError): ImageFile._save( im, fp, - [("MOCK", (xoff, yoff, xoff + xsize, yoff + ysize + 100), 0, "RGB")], + [ + ImageFile._Tile( + "MOCK", (xoff, yoff, xoff + xsize, yoff + ysize + 100), 0, "RGB" + ) + ], ) def test_encode(self) -> None: diff --git a/src/PIL/BlpImagePlugin.py b/src/PIL/BlpImagePlugin.py index 6d71049a9..569f2c9bf 100644 --- a/src/PIL/BlpImagePlugin.py +++ b/src/PIL/BlpImagePlugin.py @@ -477,7 +477,7 @@ def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None: fp.write(struct.pack(" None: if bits != 32: and_mask = Image.new("1", size) ImageFile._save( - and_mask, image_io, [("raw", (0, 0) + size, 0, ("1", 0, -1))] + and_mask, + image_io, + [ImageFile._Tile("raw", (0, 0) + size, 0, ("1", 0, -1))], ) else: frame.save(image_io, "png") diff --git a/src/PIL/ImImagePlugin.py b/src/PIL/ImImagePlugin.py index 2fb7ecd52..b94165089 100644 --- a/src/PIL/ImImagePlugin.py +++ b/src/PIL/ImImagePlugin.py @@ -360,7 +360,9 @@ def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None: palette += im_palette[colors * i : colors * (i + 1)] palette += b"\x00" * (256 - colors) fp.write(palette) # 768 bytes - ImageFile._save(im, fp, [("raw", (0, 0) + im.size, 0, (rawmode, 0, -1))]) + ImageFile._save( + im, fp, [ImageFile._Tile("raw", (0, 0) + im.size, 0, (rawmode, 0, -1))] + ) # diff --git a/src/PIL/ImageFile.py b/src/PIL/ImageFile.py index 829082e94..73554fa53 100644 --- a/src/PIL/ImageFile.py +++ b/src/PIL/ImageFile.py @@ -93,7 +93,7 @@ def _tilesort(t: _Tile) -> int: class _Tile(NamedTuple): codec_name: str - extents: tuple[int, int, int, int] + extents: tuple[int, int, int, int] | None offset: int args: tuple[Any, ...] | str | None @@ -522,7 +522,7 @@ class Parser: # -------------------------------------------------------------------- -def _save(im: Image.Image, fp: IO[bytes], tile, bufsize: int = 0) -> None: +def _save(im: Image.Image, fp: IO[bytes], tile: list[_Tile], bufsize: int = 0) -> None: """Helper to save image based on tile list :param im: Image object. diff --git a/src/PIL/Jpeg2KImagePlugin.py b/src/PIL/Jpeg2KImagePlugin.py index ef9107f00..02c2e48cf 100644 --- a/src/PIL/Jpeg2KImagePlugin.py +++ b/src/PIL/Jpeg2KImagePlugin.py @@ -419,7 +419,7 @@ def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None: plt, ) - ImageFile._save(im, fp, [("jpeg2k", (0, 0) + im.size, 0, kind)]) + ImageFile._save(im, fp, [ImageFile._Tile("jpeg2k", (0, 0) + im.size, 0, kind)]) # ------------------------------------------------------------ diff --git a/src/PIL/JpegImagePlugin.py b/src/PIL/JpegImagePlugin.py index fc897e2b9..bd4539be4 100644 --- a/src/PIL/JpegImagePlugin.py +++ b/src/PIL/JpegImagePlugin.py @@ -826,7 +826,9 @@ def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None: # Ensure that our buffer is big enough. Same with the icc_profile block. bufsize = max(bufsize, len(exif) + 5, len(extra) + 1) - ImageFile._save(im, fp, [("jpeg", (0, 0) + im.size, 0, rawmode)], bufsize) + ImageFile._save( + im, fp, [ImageFile._Tile("jpeg", (0, 0) + im.size, 0, rawmode)], bufsize + ) def _save_cjpeg(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None: diff --git a/src/PIL/MspImagePlugin.py b/src/PIL/MspImagePlugin.py index 0a75c868b..40e5fa435 100644 --- a/src/PIL/MspImagePlugin.py +++ b/src/PIL/MspImagePlugin.py @@ -188,7 +188,7 @@ def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None: fp.write(o16(h)) # image body - ImageFile._save(im, fp, [("raw", (0, 0) + im.size, 32, ("1", 0, 1))]) + ImageFile._save(im, fp, [ImageFile._Tile("raw", (0, 0) + im.size, 32, ("1", 0, 1))]) # diff --git a/src/PIL/PalmImagePlugin.py b/src/PIL/PalmImagePlugin.py index 1735070f8..62bf5f542 100644 --- a/src/PIL/PalmImagePlugin.py +++ b/src/PIL/PalmImagePlugin.py @@ -213,7 +213,9 @@ def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None: ) # now convert data to raw form - ImageFile._save(im, fp, [("raw", (0, 0) + im.size, 0, (rawmode, rowbytes, 1))]) + ImageFile._save( + im, fp, [ImageFile._Tile("raw", (0, 0) + im.size, 0, (rawmode, rowbytes, 1))] + ) if hasattr(fp, "flush"): fp.flush() diff --git a/src/PIL/PcxImagePlugin.py b/src/PIL/PcxImagePlugin.py index dd42003b5..4fb04715b 100644 --- a/src/PIL/PcxImagePlugin.py +++ b/src/PIL/PcxImagePlugin.py @@ -198,7 +198,9 @@ def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None: assert fp.tell() == 128 - ImageFile._save(im, fp, [("pcx", (0, 0) + im.size, 0, (rawmode, bits * planes))]) + ImageFile._save( + im, fp, [ImageFile._Tile("pcx", (0, 0) + im.size, 0, (rawmode, bits * planes))] + ) if im.mode == "P": # colour palette diff --git a/src/PIL/PdfImagePlugin.py b/src/PIL/PdfImagePlugin.py index 7fc1108bb..e9c20ddc1 100644 --- a/src/PIL/PdfImagePlugin.py +++ b/src/PIL/PdfImagePlugin.py @@ -138,7 +138,7 @@ def _write_image( op = io.BytesIO() if decode_filter == "ASCIIHexDecode": - ImageFile._save(im, op, [("hex", (0, 0) + im.size, 0, im.mode)]) + ImageFile._save(im, op, [ImageFile._Tile("hex", (0, 0) + im.size, 0, im.mode)]) elif decode_filter == "CCITTFaxDecode": im.save( op, diff --git a/src/PIL/PngImagePlugin.py b/src/PIL/PngImagePlugin.py index 910fa9755..fc20b18a8 100644 --- a/src/PIL/PngImagePlugin.py +++ b/src/PIL/PngImagePlugin.py @@ -1226,7 +1226,7 @@ def _write_multiple_frames( ImageFile._save( im, cast(IO[bytes], _idat(fp, chunk)), - [("zip", (0, 0) + im.size, 0, rawmode)], + [ImageFile._Tile("zip", (0, 0) + im.size, 0, rawmode)], ) seq_num = 0 @@ -1263,14 +1263,14 @@ def _write_multiple_frames( ImageFile._save( im_frame, cast(IO[bytes], _idat(fp, chunk)), - [("zip", (0, 0) + im_frame.size, 0, rawmode)], + [ImageFile._Tile("zip", (0, 0) + im_frame.size, 0, rawmode)], ) else: fdat_chunks = _fdat(fp, chunk, seq_num) ImageFile._save( im_frame, cast(IO[bytes], fdat_chunks), - [("zip", (0, 0) + im_frame.size, 0, rawmode)], + [ImageFile._Tile("zip", (0, 0) + im_frame.size, 0, rawmode)], ) seq_num = fdat_chunks.seq_num return None @@ -1471,7 +1471,7 @@ def _save( ImageFile._save( single_im, cast(IO[bytes], _idat(fp, chunk)), - [("zip", (0, 0) + single_im.size, 0, rawmode)], + [ImageFile._Tile("zip", (0, 0) + single_im.size, 0, rawmode)], ) if info: diff --git a/src/PIL/PpmImagePlugin.py b/src/PIL/PpmImagePlugin.py index 16c9ccbba..7bdaa9fe7 100644 --- a/src/PIL/PpmImagePlugin.py +++ b/src/PIL/PpmImagePlugin.py @@ -353,7 +353,9 @@ def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None: elif head == b"Pf": fp.write(b"-1.0\n") row_order = -1 if im.mode == "F" else 1 - ImageFile._save(im, fp, [("raw", (0, 0) + im.size, 0, (rawmode, 0, row_order))]) + ImageFile._save( + im, fp, [ImageFile._Tile("raw", (0, 0) + im.size, 0, (rawmode, 0, row_order))] + ) # diff --git a/src/PIL/SpiderImagePlugin.py b/src/PIL/SpiderImagePlugin.py index a07101e54..7045ab566 100644 --- a/src/PIL/SpiderImagePlugin.py +++ b/src/PIL/SpiderImagePlugin.py @@ -278,7 +278,9 @@ def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None: fp.writelines(hdr) rawmode = "F;32NF" # 32-bit native floating point - ImageFile._save(im, fp, [("raw", (0, 0) + im.size, 0, (rawmode, 0, 1))]) + ImageFile._save( + im, fp, [ImageFile._Tile("raw", (0, 0) + im.size, 0, (rawmode, 0, 1))] + ) def _save_spider(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None: diff --git a/src/PIL/TgaImagePlugin.py b/src/PIL/TgaImagePlugin.py index 39104aece..a43aae1ec 100644 --- a/src/PIL/TgaImagePlugin.py +++ b/src/PIL/TgaImagePlugin.py @@ -238,11 +238,15 @@ def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None: if rle: ImageFile._save( - im, fp, [("tga_rle", (0, 0) + im.size, 0, (rawmode, orientation))] + im, + fp, + [ImageFile._Tile("tga_rle", (0, 0) + im.size, 0, (rawmode, orientation))], ) else: ImageFile._save( - im, fp, [("raw", (0, 0) + im.size, 0, (rawmode, 0, orientation))] + im, + fp, + [ImageFile._Tile("raw", (0, 0) + im.size, 0, (rawmode, 0, orientation))], ) # write targa version 2 footer diff --git a/src/PIL/XbmImagePlugin.py b/src/PIL/XbmImagePlugin.py index 6d11bbfcf..6c2e32804 100644 --- a/src/PIL/XbmImagePlugin.py +++ b/src/PIL/XbmImagePlugin.py @@ -85,7 +85,7 @@ def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None: fp.write(b"static char im_bits[] = {\n") - ImageFile._save(im, fp, [("xbm", (0, 0) + im.size, 0, None)]) + ImageFile._save(im, fp, [ImageFile._Tile("xbm", (0, 0) + im.size, 0, None)]) fp.write(b"};\n")