mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-07-10 08:12:33 +03:00
Lint fixes
This commit is contained in:
parent
4c94fa4d13
commit
26be2ee1e4
|
@ -2,6 +2,7 @@ from __future__ import annotations
|
||||||
|
|
||||||
import struct
|
import struct
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
from typing import IO, Any
|
||||||
|
|
||||||
from PIL import BmpImagePlugin, CurImagePlugin, Image, ImageFile
|
from PIL import BmpImagePlugin, CurImagePlugin, Image, ImageFile
|
||||||
from PIL._binary import i32le as i32
|
from PIL._binary import i32le as i32
|
||||||
|
@ -10,11 +11,11 @@ from PIL._binary import o16le as o16
|
||||||
from PIL._binary import o32le as o32
|
from PIL._binary import o32le as o32
|
||||||
|
|
||||||
|
|
||||||
def _accept(s):
|
def _accept(prefix: bytes) -> bool:
|
||||||
return s[:4] == b"RIFF"
|
return prefix[:4] == b"RIFF"
|
||||||
|
|
||||||
|
|
||||||
def _save_frame(im: Image.Image, fp: BytesIO, filename: str, info: dict):
|
def _save_frame(im: Image.Image, fp: BytesIO, info: dict[str, Any]) -> None:
|
||||||
fp.write(b"\0\0\2\0")
|
fp.write(b"\0\0\2\0")
|
||||||
bmp = True
|
bmp = True
|
||||||
s = info.get(
|
s = info.get(
|
||||||
|
@ -64,7 +65,9 @@ def _save_frame(im: Image.Image, fp: BytesIO, filename: str, info: dict):
|
||||||
if bits != 32:
|
if bits != 32:
|
||||||
and_mask = Image.new("1", size)
|
and_mask = Image.new("1", size)
|
||||||
ImageFile._save(
|
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:
|
else:
|
||||||
frame.alpha = True
|
frame.alpha = True
|
||||||
|
@ -87,7 +90,7 @@ def _save_frame(im: Image.Image, fp: BytesIO, filename: str, info: dict):
|
||||||
fp.seek(current)
|
fp.seek(current)
|
||||||
|
|
||||||
|
|
||||||
def _write_single_frame(im: Image.Image, fp: BytesIO, filename: str):
|
def _write_single_frame(im: Image.Image, fp: IO[bytes]) -> None:
|
||||||
fp.write(b"anih")
|
fp.write(b"anih")
|
||||||
anih = o32(36) + o32(36) + (o32(1) * 2) + (o32(0) * 4) + o32(60) + o32(1)
|
anih = o32(36) + o32(36) + (o32(1) * 2) + (o32(0) * 4) + o32(60) + o32(1)
|
||||||
fp.write(anih)
|
fp.write(anih)
|
||||||
|
@ -99,7 +102,7 @@ def _write_single_frame(im: Image.Image, fp: BytesIO, filename: str):
|
||||||
fp.write(b"icon" + o32(0))
|
fp.write(b"icon" + o32(0))
|
||||||
icon_offset = fp.tell()
|
icon_offset = fp.tell()
|
||||||
with BytesIO(b"") as icon_fp:
|
with BytesIO(b"") as icon_fp:
|
||||||
_save_frame(im, icon_fp, filename, im.encoderinfo)
|
_save_frame(im, icon_fp, im.encoderinfo)
|
||||||
icon_fp.seek(0)
|
icon_fp.seek(0)
|
||||||
icon_data = icon_fp.read()
|
icon_data = icon_fp.read()
|
||||||
|
|
||||||
|
@ -117,7 +120,7 @@ def _write_single_frame(im: Image.Image, fp: BytesIO, filename: str):
|
||||||
fp.seek(fram_end)
|
fp.seek(fram_end)
|
||||||
|
|
||||||
|
|
||||||
def _write_multiple_frames(im: Image.Image, fp: BytesIO, filename: str):
|
def _write_multiple_frames(im: Image.Image, fp: IO[bytes]) -> None:
|
||||||
anih_offset = fp.tell()
|
anih_offset = fp.tell()
|
||||||
fp.write(b"anih" + o32(36))
|
fp.write(b"anih" + o32(36))
|
||||||
fp.write(o32(0) * 9)
|
fp.write(o32(0) * 9)
|
||||||
|
@ -132,7 +135,7 @@ def _write_multiple_frames(im: Image.Image, fp: BytesIO, filename: str):
|
||||||
fp.write(b"icon" + o32(0))
|
fp.write(b"icon" + o32(0))
|
||||||
icon_offset = fp.tell()
|
icon_offset = fp.tell()
|
||||||
with BytesIO(b"") as icon_fp:
|
with BytesIO(b"") as icon_fp:
|
||||||
_save_frame(frame, icon_fp, filename, im.encoderinfo)
|
_save_frame(frame, icon_fp, im.encoderinfo)
|
||||||
icon_fp.seek(0)
|
icon_fp.seek(0)
|
||||||
icon_data = icon_fp.read()
|
icon_data = icon_fp.read()
|
||||||
|
|
||||||
|
@ -216,7 +219,7 @@ def _write_multiple_frames(im: Image.Image, fp: BytesIO, filename: str):
|
||||||
fp.seek(fram_end)
|
fp.seek(fram_end)
|
||||||
|
|
||||||
|
|
||||||
def _write_info(im: Image.Image, fp: BytesIO, filename: str):
|
def _write_info(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None:
|
||||||
fp.write(b"LIST" + o32(0))
|
fp.write(b"LIST" + o32(0))
|
||||||
list_offset = fp.tell()
|
list_offset = fp.tell()
|
||||||
|
|
||||||
|
@ -263,7 +266,7 @@ def _write_info(im: Image.Image, fp: BytesIO, filename: str):
|
||||||
fp.seek(info_end)
|
fp.seek(info_end)
|
||||||
|
|
||||||
|
|
||||||
def _save(im: Image.Image, fp: BytesIO, filename: str):
|
def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None:
|
||||||
fp.write(b"RIFF\x00\x00\x00\x00")
|
fp.write(b"RIFF\x00\x00\x00\x00")
|
||||||
riff_offset = fp.tell()
|
riff_offset = fp.tell()
|
||||||
|
|
||||||
|
@ -272,9 +275,9 @@ def _save(im: Image.Image, fp: BytesIO, filename: str):
|
||||||
|
|
||||||
frames = im.encoderinfo.get("append_images", [])
|
frames = im.encoderinfo.get("append_images", [])
|
||||||
if frames:
|
if frames:
|
||||||
_write_multiple_frames(im, fp, filename)
|
_write_multiple_frames(im, fp)
|
||||||
else:
|
else:
|
||||||
_write_single_frame(im, fp, filename)
|
_write_single_frame(im, fp)
|
||||||
pass
|
pass
|
||||||
|
|
||||||
riff_end = fp.tell()
|
riff_end = fp.tell()
|
||||||
|
@ -352,7 +355,8 @@ class AniFile:
|
||||||
if self.rate is None:
|
if self.rate is None:
|
||||||
self.rate = [self.anih["iDispRate"] for i in range(self.anih["nFrames"])]
|
self.rate = [self.anih["iDispRate"] for i in range(self.anih["nFrames"])]
|
||||||
|
|
||||||
def frame(self, frame):
|
def frame(self, frame: int) -> CurImagePlugin.CurImageFile:
|
||||||
|
assert self.anih is not None
|
||||||
if frame > self.anih["nFrames"]:
|
if frame > self.anih["nFrames"]:
|
||||||
msg = "Frame index out of animation bounds"
|
msg = "Frame index out of animation bounds"
|
||||||
raise EOFError(msg)
|
raise EOFError(msg)
|
||||||
|
@ -361,13 +365,12 @@ class AniFile:
|
||||||
self.buf.seek(offset)
|
self.buf.seek(offset)
|
||||||
data = self.buf.read(size)
|
data = self.buf.read(size)
|
||||||
|
|
||||||
im = CurImagePlugin.CurImageFile(BytesIO(data))
|
return CurImagePlugin.CurImageFile(BytesIO(data))
|
||||||
return im
|
|
||||||
|
|
||||||
def sizes(self):
|
def sizes(self) -> list[int]:
|
||||||
return [data["size"] for data in self.image_data]
|
return [data["size"] for data in self.image_data]
|
||||||
|
|
||||||
def hotspots(self):
|
def hotspots(self) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@ -398,10 +401,12 @@ class AniImageFile(ImageFile.ImageFile):
|
||||||
format = "ANI"
|
format = "ANI"
|
||||||
format_description = "Windows Animated Cursor"
|
format_description = "Windows Animated Cursor"
|
||||||
|
|
||||||
def _open(self):
|
def _open(self) -> None:
|
||||||
self.ani = AniFile(self.fp)
|
self.ani = AniFile(self.fp)
|
||||||
self.info["seq"] = self.ani.seq
|
self.info["seq"] = self.ani.seq
|
||||||
self.info["rate"] = self.ani.rate
|
self.info["rate"] = self.ani.rate
|
||||||
|
|
||||||
|
assert self.ani.anih is not None
|
||||||
self.info["frames"] = self.ani.anih["nFrames"]
|
self.info["frames"] = self.ani.anih["nFrames"]
|
||||||
|
|
||||||
self.frame = 0
|
self.frame = 0
|
||||||
|
@ -410,24 +415,24 @@ class AniImageFile(ImageFile.ImageFile):
|
||||||
self.size = self.im.size
|
self.size = self.im.size
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def size(self):
|
def size(self) -> tuple[int, int]:
|
||||||
return self._size
|
return self._size
|
||||||
|
|
||||||
@size.setter
|
@size.setter
|
||||||
def size(self, value):
|
def size(self, value: tuple[int, int]) -> None:
|
||||||
if value not in self.info["sizes"]:
|
if value not in self.info["sizes"]:
|
||||||
msg = "This is not one of the allowed sizes of this image"
|
msg = "This is not one of the allowed sizes of this image"
|
||||||
raise ValueError(msg)
|
raise ValueError(msg)
|
||||||
self._size = value
|
self._size = value
|
||||||
|
|
||||||
def load(self):
|
def load(self) -> None:
|
||||||
im = self.ani.frame(self.frame)
|
im = self.ani.frame(self.frame)
|
||||||
self.info["sizes"] = im.info["sizes"]
|
self.info["sizes"] = im.info["sizes"]
|
||||||
self.info["hotspots"] = im.info["hotspots"]
|
self.info["hotspots"] = im.info["hotspots"]
|
||||||
self.im = im.im
|
self.im = im.im
|
||||||
self._mode = im.mode
|
self._mode = im.mode
|
||||||
|
|
||||||
def seek(self, frame):
|
def seek(self, frame: int) -> None:
|
||||||
if frame > self.info["frames"] - 1 or frame < 0:
|
if frame > self.info["frames"] - 1 or frame < 0:
|
||||||
msg = "Frame index out of animation bounds"
|
msg = "Frame index out of animation bounds"
|
||||||
raise EOFError(msg)
|
raise EOFError(msg)
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
from typing import IO, NamedTuple
|
||||||
|
|
||||||
from . import BmpImagePlugin, IcoImagePlugin, Image, ImageFile
|
from . import BmpImagePlugin, IcoImagePlugin, Image, ImageFile
|
||||||
from ._binary import i16le as i16
|
from ._binary import i16le as i16
|
||||||
|
@ -32,7 +33,7 @@ from ._binary import o32le as o32
|
||||||
_MAGIC = b"\x00\x00\x02\x00"
|
_MAGIC = b"\x00\x00\x02\x00"
|
||||||
|
|
||||||
|
|
||||||
def _save(im: Image.Image, fp: BytesIO, filename: str):
|
def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None:
|
||||||
fp.write(_MAGIC)
|
fp.write(_MAGIC)
|
||||||
bmp = im.encoderinfo.get("bitmap_format", "") == "bmp"
|
bmp = im.encoderinfo.get("bitmap_format", "") == "bmp"
|
||||||
s = im.encoderinfo.get(
|
s = im.encoderinfo.get(
|
||||||
|
@ -82,7 +83,9 @@ def _save(im: Image.Image, fp: BytesIO, filename: str):
|
||||||
if bits != 32:
|
if bits != 32:
|
||||||
and_mask = Image.new("1", size)
|
and_mask = Image.new("1", size)
|
||||||
ImageFile._save(
|
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:
|
else:
|
||||||
frame.alpha = True
|
frame.alpha = True
|
||||||
|
@ -109,10 +112,24 @@ def _accept(prefix: bytes) -> bool:
|
||||||
return prefix.startswith(_MAGIC)
|
return prefix.startswith(_MAGIC)
|
||||||
|
|
||||||
|
|
||||||
|
class IconHeader(NamedTuple):
|
||||||
|
width: int
|
||||||
|
height: int
|
||||||
|
nb_color: int
|
||||||
|
reserved: int
|
||||||
|
bpp: int
|
||||||
|
x_hotspot: int
|
||||||
|
y_hotspot: int
|
||||||
|
size: int
|
||||||
|
offset: int
|
||||||
|
dim: tuple[int, int]
|
||||||
|
square: int
|
||||||
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# Image plugin for Windows Cursor files.
|
# Image plugin for Windows Cursor files.
|
||||||
class CurFile(IcoImagePlugin.IcoFile):
|
class CurFile(IcoImagePlugin.IcoFile):
|
||||||
def __init__(self, buf: BytesIO()):
|
def __init__(self, buf: IO[bytes]) -> None:
|
||||||
"""
|
"""
|
||||||
Parse image from file-like object containing cur file data
|
Parse image from file-like object containing cur file data
|
||||||
"""
|
"""
|
||||||
|
@ -133,24 +150,12 @@ class CurFile(IcoImagePlugin.IcoFile):
|
||||||
for _ in range(self.nb_items):
|
for _ in range(self.nb_items):
|
||||||
s = buf.read(16)
|
s = buf.read(16)
|
||||||
|
|
||||||
icon_header = {
|
|
||||||
"width": s[0],
|
|
||||||
"height": s[1],
|
|
||||||
"nb_color": s[2], # No. of colors in image (0 if >=8bpp)
|
|
||||||
"reserved": s[3],
|
|
||||||
"x_hotspot": i16(s, 4),
|
|
||||||
"y_hotspot": i16(s, 6),
|
|
||||||
"size": i32(s, 8),
|
|
||||||
"offset": i32(s, 12),
|
|
||||||
}
|
|
||||||
|
|
||||||
# See Wikipedia
|
# See Wikipedia
|
||||||
for j in ("width", "height"):
|
width = s[0] or 256
|
||||||
if not icon_header[j]:
|
height = s[1] or 256
|
||||||
icon_header[j] = 256
|
|
||||||
|
|
||||||
icon_header["dim"] = (icon_header["width"], icon_header["height"])
|
size = i32(s, 8)
|
||||||
icon_header["square"] = icon_header["width"] * icon_header["height"]
|
square = width * height
|
||||||
|
|
||||||
# TODO: This needs further investigation. Cursor files do not really
|
# TODO: This needs further investigation. Cursor files do not really
|
||||||
# specify their bpp like ICO's as those bits are used for the y_hotspot.
|
# specify their bpp like ICO's as those bits are used for the y_hotspot.
|
||||||
|
@ -158,28 +163,35 @@ class CurFile(IcoImagePlugin.IcoFile):
|
||||||
# of pixels * 1bpp) and dividing by the number of pixels. This seems
|
# of pixels * 1bpp) and dividing by the number of pixels. This seems
|
||||||
# to work well so far.
|
# to work well so far.
|
||||||
BITMAP_INFO_HEADER_SIZE = 40
|
BITMAP_INFO_HEADER_SIZE = 40
|
||||||
bpp_without_and = (
|
bpp_without_and = ((size - BITMAP_INFO_HEADER_SIZE) * 8) // square
|
||||||
(icon_header["size"] - BITMAP_INFO_HEADER_SIZE) * 8
|
|
||||||
) // icon_header["square"]
|
|
||||||
|
|
||||||
if bpp_without_and != 32:
|
if bpp_without_and != 32:
|
||||||
icon_header["bpp"] = (
|
bpp = ((size - BITMAP_INFO_HEADER_SIZE) * 8 - square) // square
|
||||||
(icon_header["size"] - BITMAP_INFO_HEADER_SIZE) * 8
|
|
||||||
- icon_header["square"]
|
|
||||||
) // icon_header["square"]
|
|
||||||
else:
|
else:
|
||||||
icon_header["bpp"] = bpp_without_and
|
bpp = bpp_without_and
|
||||||
|
|
||||||
|
icon_header = IconHeader(
|
||||||
|
width=width,
|
||||||
|
height=height,
|
||||||
|
nb_color=s[2], # No. of colors in image (0 if >=8bpp)
|
||||||
|
reserved=s[3],
|
||||||
|
bpp=bpp,
|
||||||
|
x_hotspot=i16(s, 4),
|
||||||
|
y_hotspot=i16(s, 6),
|
||||||
|
size=size,
|
||||||
|
offset=i32(s, 12),
|
||||||
|
dim=(width, height),
|
||||||
|
square=square,
|
||||||
|
)
|
||||||
|
|
||||||
self.entry.append(icon_header)
|
self.entry.append(icon_header)
|
||||||
|
|
||||||
self.entry = sorted(self.entry, key=lambda x: x["square"])
|
self.entry = sorted(self.entry, key=lambda x: x.square, reverse=True)
|
||||||
self.entry.reverse()
|
|
||||||
|
|
||||||
def sizes(self):
|
def sizes(self) -> list[tuple[int, int]]:
|
||||||
return [(h["width"], h["height"]) for h in self.entry]
|
return [(h.width, h.height) for h in self.entry]
|
||||||
|
|
||||||
def hotspots(self):
|
def hotspots(self) -> list[tuple[int, int]]:
|
||||||
return [(h["x_hotspot"], h["y_hotspot"]) for h in self.entry]
|
return [(h.x_hotspot, h.y_hotspot) for h in self.entry]
|
||||||
|
|
||||||
|
|
||||||
class CurImageFile(IcoImagePlugin.IcoImageFile):
|
class CurImageFile(IcoImagePlugin.IcoImageFile):
|
||||||
|
@ -213,7 +225,7 @@ class CurImageFile(IcoImagePlugin.IcoImageFile):
|
||||||
self.info["sizes"] = self.ico.sizes()
|
self.info["sizes"] = self.ico.sizes()
|
||||||
self.info["hotspots"] = self.ico.hotspots()
|
self.info["hotspots"] = self.ico.hotspots()
|
||||||
if len(self.ico.entry) > 0:
|
if len(self.ico.entry) > 0:
|
||||||
self.size = self.ico.entry[0]["dim"]
|
self.size = self.ico.entry[0].dim
|
||||||
else:
|
else:
|
||||||
msg = "No cursors were found"
|
msg = "No cursors were found"
|
||||||
raise TypeError(msg)
|
raise TypeError(msg)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user