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

@@ -6,6 +6,9 @@
##
# Image plugin for Palm pixmap images (output only).
##
from __future__ import annotations
from typing import IO
from . import Image, ImageFile
from ._binary import o8
@@ -81,10 +84,10 @@ _Palm8BitColormapValues = (
# so build a prototype image to be used for palette resampling
def build_prototype_image():
def build_prototype_image() -> Image.Image:
image = Image.new("L", (1, len(_Palm8BitColormapValues)))
image.putdata(list(range(len(_Palm8BitColormapValues))))
palettedata = ()
palettedata: tuple[int, ...] = ()
for colormapValue in _Palm8BitColormapValues:
palettedata += colormapValue
palettedata += (0, 0, 0) * (256 - len(_Palm8BitColormapValues))
@@ -111,11 +114,8 @@ _COMPRESSION_TYPES = {"none": 0xFF, "rle": 0x01, "scanline": 0x00}
# (Internal) Image save plugin for the Palm format.
def _save(im, fp, filename):
def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None:
if im.mode == "P":
# we assume this is a color Palm image with the standard colormap,
# unless the "info" dict has a "custom-colormap" field
rawmode = "P"
bpp = 8
version = 1
@@ -124,24 +124,25 @@ def _save(im, fp, filename):
if im.encoderinfo.get("bpp") in (1, 2, 4):
# this is 8-bit grayscale, so we shift it to get the high-order bits,
# and invert it because
# Palm does greyscale from white (0) to black (1)
# Palm does grayscale from white (0) to black (1)
bpp = im.encoderinfo["bpp"]
im = im.point(
lambda x, shift=8 - bpp, maxval=(1 << bpp) - 1: maxval - (x >> shift)
)
maxval = (1 << bpp) - 1
shift = 8 - bpp
im = im.point(lambda x: maxval - (x >> shift))
elif im.info.get("bpp") in (1, 2, 4):
# here we assume that even though the inherent mode is 8-bit grayscale,
# only the lower bpp bits are significant.
# We invert them to match the Palm.
bpp = im.info["bpp"]
im = im.point(lambda x, maxval=(1 << bpp) - 1: maxval - (x & maxval))
maxval = (1 << bpp) - 1
im = im.point(lambda x: maxval - (x & maxval))
else:
msg = f"cannot write mode {im.mode} as Palm"
raise OSError(msg)
# we ignore the palette here
im.mode = "P"
rawmode = "P;" + str(bpp)
im._mode = "P"
rawmode = f"P;{bpp}"
version = 1
elif im.mode == "1":
@@ -168,11 +169,11 @@ def _save(im, fp, filename):
compression_type = _COMPRESSION_TYPES["none"]
flags = 0
if im.mode == "P" and "custom-colormap" in im.info:
flags = flags & _FLAGS["custom-colormap"]
colormapsize = 4 * 256 + 2
colormapmode = im.palette.mode
colormap = im.getdata().getpalette()
if im.mode == "P":
flags |= _FLAGS["custom-colormap"]
colormap = im.im.getpalette()
colors = len(colormap) // 3
colormapsize = 4 * colors + 2
else:
colormapsize = 0
@@ -191,25 +192,16 @@ def _save(im, fp, filename):
# now write colormap if necessary
if colormapsize > 0:
fp.write(o16b(256))
for i in range(256):
if colormapsize:
fp.write(o16b(colors))
for i in range(colors):
fp.write(o8(i))
if colormapmode == "RGB":
fp.write(
o8(colormap[3 * i])
+ o8(colormap[3 * i + 1])
+ o8(colormap[3 * i + 2])
)
elif colormapmode == "RGBA":
fp.write(
o8(colormap[4 * i])
+ o8(colormap[4 * i + 1])
+ o8(colormap[4 * i + 2])
)
fp.write(colormap[3 * i : 3 * i + 3])
# 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()