45 lines
1.4 KiB
Python
45 lines
1.4 KiB
Python
#!/usr/bin/env python3
|
|
"""Entpackt Argonaut-.cor-Bilder (Ein Königreich für ein Lama) nach PNG.
|
|
|
|
Aufbau: 8 Byte Signatur 17 98 AF 89 FE 42 D1 12, u32 Version (1),
|
|
u32 entpackte Größe, u32 gepackte Größe, dann LZ-Daten:
|
|
n < 0x80 -> n Bytes Rohdaten folgen
|
|
1LLL oooo oooooooo -> kopiere L+3 Bytes ab o Bytes weiter vorne
|
|
Das Ergebnis sind 640x480 Pixel à 3 Byte (RGB) oder à 1 Byte (Graustufen, z. B. 151.cor).
|
|
Aufruf: cor2png.py eingabe.cor ausgabe.png (benötigt Pillow)
|
|
"""
|
|
import struct
|
|
import sys
|
|
|
|
MAGIC = bytes.fromhex('1798af89fe42d112')
|
|
|
|
|
|
def unpack(data):
|
|
if data[:8] != MAGIC:
|
|
raise ValueError('keine COR-Datei')
|
|
_, size, packed = struct.unpack_from('<III', data, 8)
|
|
src = data[20:20 + packed]
|
|
out = bytearray()
|
|
i = 0
|
|
while i < len(src) and len(out) < size:
|
|
b = src[i]
|
|
if b < 0x80:
|
|
out += src[i + 1:i + 1 + b]
|
|
i += 1 + b
|
|
else:
|
|
length = ((b >> 4) & 7) + 3
|
|
off = ((b & 0x0F) << 8) | src[i + 1]
|
|
i += 2
|
|
for _ in range(length):
|
|
out.append(out[-off])
|
|
return bytes(out), size
|
|
|
|
|
|
if __name__ == '__main__':
|
|
raw, size = unpack(open(sys.argv[1], 'rb').read())
|
|
print(f'{sys.argv[1]}: {len(raw)} von {size} Bytes')
|
|
if len(sys.argv) > 2:
|
|
from PIL import Image
|
|
mode = {640 * 480 * 3: 'RGB', 640 * 480: 'L'}[size]
|
|
Image.frombytes(mode, (640, 480), raw).save(sys.argv[2])
|