1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-27 01:48:17 +00:00
trezor-firmware/core/tools/png2toi

120 lines
3.3 KiB
Plaintext
Raw Normal View History

2016-03-24 22:00:38 +00:00
#!/usr/bin/env python3
from PIL import Image
import sys
import struct
import zlib
from os.path import basename
2016-03-24 22:00:38 +00:00
2016-04-25 16:53:40 +00:00
def process_rgb(w, h, pix):
2016-03-24 22:00:38 +00:00
data = bytes()
2016-04-25 16:53:40 +00:00
for j in range(h):
for i in range(w):
r, g, b = pix[i, j]
c = ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | ((b & 0xF8) >> 3)
2018-07-31 09:35:09 +00:00
data += struct.pack(">H", c)
2016-04-25 16:53:40 +00:00
return data
def process_grayscale(w, h, pix):
data = bytes()
for j in range(h):
2016-10-10 11:38:33 +00:00
for i in range(w // 2):
l1, l2 = pix[i * 2, j], pix[i * 2 + 1, j]
c = (l1 & 0xF0) | (l2 >> 4)
2018-07-31 09:35:09 +00:00
data += struct.pack(">B", c)
2016-04-25 16:53:40 +00:00
return data
2017-04-01 16:28:10 +00:00
def process_image(ifn, savefiles=False):
2016-04-25 16:53:40 +00:00
im = Image.open(ifn)
w, h = im.size
2018-07-31 09:35:09 +00:00
print("Opened %s ... %d x %d @ %s" % (ifn, w, h, im.mode))
2016-04-25 16:53:40 +00:00
2018-07-31 09:35:09 +00:00
if im.mode == "RGB":
print("Detected RGB mode")
elif im.mode == "L":
2016-04-25 16:53:40 +00:00
if w % 2 > 0:
2018-07-31 09:35:09 +00:00
print("PNG file must have width divisible by 2")
2016-04-25 16:53:40 +00:00
return 3
2018-07-31 09:35:09 +00:00
print("Detected GRAYSCALE mode")
2016-04-25 16:53:40 +00:00
else:
2018-07-31 09:35:09 +00:00
print("Unknown mode:", im.mode)
2016-04-25 16:53:40 +00:00
return 4
pix = im.load()
bname = basename(ifn[:-4])
2018-07-31 09:35:09 +00:00
ofn_h = "%s.h" % bname
ofn_py = "%s.py" % bname
2018-07-31 09:35:09 +00:00
if im.mode == "RGB":
ofn = "%s.toif" % bname
2016-04-27 16:45:00 +00:00
pixeldata = process_rgb(w, h, pix)
2016-04-25 16:53:40 +00:00
else:
2018-07-31 09:35:09 +00:00
ofn = "%s.toig" % bname
2016-04-27 16:45:00 +00:00
pixeldata = process_grayscale(w, h, pix)
z = zlib.compressobj(level=9, wbits=10)
zdata = z.compress(pixeldata) + z.flush()
2017-09-05 21:15:47 +00:00
zdata = zdata[2:-4] # strip header and checksum
2016-04-27 16:45:00 +00:00
2018-07-31 09:35:09 +00:00
data = b""
if im.mode == "RGB":
data += b"TOIf"
2017-04-01 16:28:10 +00:00
else:
2018-07-31 09:35:09 +00:00
data += b"TOIg"
data += struct.pack("<HH", w, h)
data += struct.pack("<I", len(zdata))
2017-04-01 16:28:10 +00:00
data += zdata
if savefiles:
2018-07-31 09:35:09 +00:00
with open(ofn, "wb") as f:
2017-04-01 16:28:10 +00:00
f.write(data)
2018-07-31 09:35:09 +00:00
print("Written %s ... %d bytes" % (ofn, len(data)))
with open(ofn_py, "wb") as f:
f.write(("%s = %s\n" % (bname, data)).encode())
print("Written %s ... %d bytes" % (ofn_py, len(data)))
with open(ofn_h, "wt") as f:
f.write("// clang-format off\n")
f.write("static const uint8_t toi_%s[] = {\n" % bname)
f.write(" // magic\n")
if im.mode == "RGB":
2017-04-01 16:28:10 +00:00
f.write(" 'T', 'O', 'I', 'f',\n")
else:
f.write(" 'T', 'O', 'I', 'g',\n")
2018-07-31 09:35:09 +00:00
f.write(" // width (16-bit), height (16-bit)\n")
f.write(
" 0x%02x, 0x%02x, 0x%02x, 0x%02x,\n"
% (w & 0xFF, w >> 8, h & 0xFF, h >> 8)
)
2017-06-21 16:18:59 +00:00
l = len(zdata)
2018-07-31 09:35:09 +00:00
f.write(" // compressed data length (32-bit)\n")
f.write(
" 0x%02x, 0x%02x, 0x%02x, 0x%02x,\n"
% (l & 0xFF, (l >> 8) & 0xFF, (l >> 16) & 0xFF, l >> 24)
)
f.write(" // compressed data\n")
f.write(" ")
2017-04-01 16:28:10 +00:00
for b in zdata:
2018-07-31 09:35:09 +00:00
f.write(" 0x%02x," % b)
f.write("\n};\n")
print("Written %s ... done" % ofn_py)
2017-04-01 16:28:10 +00:00
return data
2016-04-25 16:53:40 +00:00
def main():
if len(sys.argv) < 2:
2018-07-31 09:35:09 +00:00
print("Usage png2toi image.png")
2016-04-25 16:53:40 +00:00
return 1
ifn = sys.argv[1]
2018-07-31 09:35:09 +00:00
if not ifn.endswith(".png"):
print("Must provide PNG file")
2016-04-25 16:53:40 +00:00
return 2
2017-04-01 16:28:10 +00:00
process_image(ifn, savefiles=True)
2016-04-25 16:53:40 +00:00
2016-03-24 22:00:38 +00:00
2016-04-25 16:53:40 +00:00
main()