This commit is contained in:
Iliyan Angelov
2025-12-01 06:50:10 +02:00
parent 91f51bc6fe
commit 62c1fe5951
4682 changed files with 544807 additions and 31208 deletions

View File

@@ -14,6 +14,8 @@
#
# See the README file for information on usage and redistribution.
#
from __future__ import annotations
import olefile
from . import Image, ImageFile
@@ -39,8 +41,8 @@ MODES = {
# --------------------------------------------------------------------
def _accept(prefix):
return prefix[:8] == olefile.MAGIC
def _accept(prefix: bytes) -> bool:
return prefix.startswith(olefile.MAGIC)
##
@@ -51,7 +53,7 @@ class FpxImageFile(ImageFile.ImageFile):
format = "FPX"
format_description = "FlashPix"
def _open(self):
def _open(self) -> None:
#
# read the OLE directory and see if this is a likely
# to be a FlashPix file
@@ -62,13 +64,14 @@ class FpxImageFile(ImageFile.ImageFile):
msg = "not an FPX file; invalid OLE file"
raise SyntaxError(msg) from e
if self.ole.root.clsid != "56616700-C154-11CE-8553-00AA00A1F95B":
root = self.ole.root
if not root or root.clsid != "56616700-C154-11CE-8553-00AA00A1F95B":
msg = "not an FPX file; bad root CLSID"
raise SyntaxError(msg)
self._open_index(1)
def _open_index(self, index=1):
def _open_index(self, index: int = 1) -> None:
#
# get the Image Contents Property Set
@@ -78,12 +81,14 @@ class FpxImageFile(ImageFile.ImageFile):
# size (highest resolution)
assert isinstance(prop[0x1000002], int)
assert isinstance(prop[0x1000003], int)
self._size = prop[0x1000002], prop[0x1000003]
size = max(self.size)
i = 1
while size > 64:
size = size / 2
size = size // 2
i += 1
self.maxid = i - 1
@@ -97,16 +102,14 @@ class FpxImageFile(ImageFile.ImageFile):
s = prop[0x2000002 | id]
colors = []
bands = i32(s, 4)
if bands > 4:
if not isinstance(s, bytes) or (bands := i32(s, 4)) > 4:
msg = "Invalid number of bands"
raise OSError(msg)
for i in range(bands):
# note: for now, we ignore the "uncalibrated" flag
colors.append(i32(s, 8 + i * 4) & 0x7FFFFFFF)
self._mode, self.rawmode = MODES[tuple(colors)]
# note: for now, we ignore the "uncalibrated" flag
colors = tuple(i32(s, 8 + i * 4) & 0x7FFFFFFF for i in range(bands))
self._mode, self.rawmode = MODES[colors]
# load JPEG tables, if any
self.jpeg = {}
@@ -117,7 +120,7 @@ class FpxImageFile(ImageFile.ImageFile):
self._open_subimage(1, self.maxid)
def _open_subimage(self, index=1, subimage=0):
def _open_subimage(self, index: int = 1, subimage: int = 0) -> None:
#
# setup tile descriptors for a given subimage
@@ -163,18 +166,18 @@ class FpxImageFile(ImageFile.ImageFile):
if compression == 0:
self.tile.append(
(
ImageFile._Tile(
"raw",
(x, y, x1, y1),
i32(s, i) + 28,
(self.rawmode,),
self.rawmode,
)
)
elif compression == 1:
# FIXME: the fill decoder is not implemented
self.tile.append(
(
ImageFile._Tile(
"fill",
(x, y, x1, y1),
i32(s, i) + 28,
@@ -202,7 +205,7 @@ class FpxImageFile(ImageFile.ImageFile):
jpegmode = rawmode
self.tile.append(
(
ImageFile._Tile(
"jpeg",
(x, y, x1, y1),
i32(s, i) + 28,
@@ -227,19 +230,20 @@ class FpxImageFile(ImageFile.ImageFile):
break # isn't really required
self.stream = stream
self._fp = self.fp
self.fp = None
def load(self):
def load(self) -> Image.core.PixelAccess | None:
if not self.fp:
self.fp = self.ole.openstream(self.stream[:2] + ["Subimage 0000 Data"])
return ImageFile.ImageFile.load(self)
def close(self):
def close(self) -> None:
self.ole.close()
super().close()
def __exit__(self, *args):
def __exit__(self, *args: object) -> None:
self.ole.close()
super().__exit__()