1
0
Fork 0

Added raw format

This commit is contained in:
Casey 2024-09-10 18:51:38 +03:00
parent bf3c5e6b1c
commit 710699f5cb
Signed by: hkc
GPG Key ID: F0F6CFE11CDB0960
1 changed files with 45 additions and 4 deletions

View File

@ -27,12 +27,37 @@ class Converter:
("f", "colors.black"), ("f", "colors.black"),
] ]
DEFAULT_PALETTE = [
240, 240, 240,
242, 178, 51,
229, 127, 216,
153, 178, 242,
222, 222, 108,
127, 204, 25,
242, 178, 204,
76, 76, 76,
153, 153, 153,
76, 153, 178,
178, 102, 229,
51, 102, 204,
127, 102, 76,
87, 166, 78,
204, 76, 76,
17, 17, 17
]
PIX_BITS = [[1, 2], [4, 8], [16, 0]] PIX_BITS = [[1, 2], [4, 8], [16, 0]]
MAX_DIFF = 3 * 255 MAX_DIFF = 3 * 255
def __init__(self, image: Image.Image): def __init__(self, image: Image.Image, palette: list[int] | int = Image.ADAPTIVE):
self._img = image.convert("P", palette=Image.ADAPTIVE, colors=16) if isinstance(palette, list):
img_pal = Image.new("P", (1, 1))
img_pal.putpalette(palette)
self._img = image.quantize(16, palette=img_pal)
else:
self._img = image.convert("P", palette=palette, colors=16)
self._imgdata = self._img.load() self._imgdata = self._img.load()
self._palette: list[int] = self._img.getpalette() or [] self._palette: list[int] = self._img.getpalette() or []
if len(self._palette) < 16 * 3: if len(self._palette) < 16 * 3:
@ -57,6 +82,7 @@ class Converter:
for oy, line in enumerate(self.PIX_BITS): for oy, line in enumerate(self.PIX_BITS):
for ox in range(len(line)): for ox in range(len(line)):
pix = self._imgdata[x + ox, y + oy] pix = self._imgdata[x + ox, y + oy]
assert pix < 16, f"{pix} is too big at {x+ox}:{y+oy}"
brightness = self._brightness(pix) brightness = self._brightness(pix)
if brightness > brightest_l: if brightness > brightest_l:
brightest_l, brightest_i = brightness, pix brightest_l, brightest_i = brightness, pix
@ -70,6 +96,8 @@ class Converter:
def _get_block(self, x: int, y: int) -> tuple[int, int, int]: def _get_block(self, x: int, y: int) -> tuple[int, int, int]:
dark_i, bri_i = self._get_colors(x, y) dark_i, bri_i = self._get_colors(x, y)
assert dark_i < 16, f"{dark_i} is too big"
assert bri_i < 16, f"{bri_i} is too big"
out: int = 0 out: int = 0
for oy, line in enumerate(self.PIX_BITS): for oy, line in enumerate(self.PIX_BITS):
for ox, bit in enumerate(line): for ox, bit in enumerate(line):
@ -95,6 +123,14 @@ class Converter:
value >>= 7 value >>= 7
def export_binary(self, io: BinaryIO, version: int = -1): def export_binary(self, io: BinaryIO, version: int = -1):
if version == -2:
for y in range(0, self._img.height - 2, 3):
line: bytearray = bytearray()
for x in range(0, self._img.width - 1, 2):
ch, bg, fg = self._get_block(x, y)
line.extend([(ch + 0x80) & 0xFF, fg << 4 | bg])
io.write(line)
return
if version == -1: if version == -1:
if self._img.width <= 255 * 2 and self._img.height < 255 * 3: if self._img.width <= 255 * 2 and self._img.height < 255 * 3:
version = 0 version = 0
@ -180,12 +216,14 @@ def main():
dest="cpi_version", dest="cpi_version",
type=int, type=int,
default=-1, default=-1,
choices=(-1, 0, 1), choices=(-2, -1, 0, 1),
help=dedent( help=dedent(
"""\ """\
Force specific CPI version to be used. Force specific CPI version to be used.
Only applies to binary format. Only applies to binary format.
Valid versions: Valid versions:
-V -2 Uses raw format. No headers, default palette.
Used for OBCB-CC project.
-V -1 Choose any fitting one -V -1 Choose any fitting one
For images smaller than 255x255, uses CPIv0 For images smaller than 255x255, uses CPIv0
-V 0 OG CPI, 255x255 maximum, uncompressed -V 0 OG CPI, 255x255 maximum, uncompressed
@ -282,7 +320,10 @@ def main():
else: else:
pass pass
converter = Converter(canv) palette = Image.Palette.ADAPTIVE
if args.cpi_version == -2:
palette = Converter.DEFAULT_PALETTE
converter = Converter(canv, palette)
converter._img.save("/tmp/_ccpictmp.png") converter._img.save("/tmp/_ccpictmp.png")
if args.textmode: if args.textmode:
with open(args.output_path, "w") as fp: with open(args.output_path, "w") as fp: