trezor-core/tools/png2toi

100 lines
2.6 KiB
Python
Executable File

#!/usr/bin/env python3
from PIL import Image
import sys
import struct
import zlib
def process_rgb(w, h, pix):
data = bytes()
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)
data += struct.pack('>H', c)
return data
def process_grayscale(w, h, pix):
data = bytes()
for j in range(h):
for i in range(w // 2):
l1, l2 = pix[i * 2, j], pix[i * 2 + 1, j]
c = (l1 & 0xF0) | (l2 >> 4)
data += struct.pack('>B', c)
return data
def process_image(ifn, savefiles=False):
im = Image.open(ifn)
w, h = im.size
print('Opened %s ... %d x %d @ %s' % (ifn, w, h, im.mode))
if im.mode == 'RGB':
print('Detected RGB mode')
elif im.mode == 'L':
if w % 2 > 0:
print('PNG file must have width divisible by 2')
return 3
print('Detected GRAYSCALE mode')
else:
print('Unknown mode:', im.mode)
return 4
pix = im.load()
if im.mode == 'RGB':
ofn = '%s.toif' % ifn[:-4]
pixeldata = process_rgb(w, h, pix)
else:
ofn = '%s.toig' % ifn[:-4]
pixeldata = process_grayscale(w, h, pix)
z = zlib.compressobj(level=9, wbits=10)
zdata = z.compress(pixeldata) + z.flush()
zdata = zdata[2:-4] # strip header and checksum
data = b''
if im.mode == 'RGB':
data += b'TOIf'
else:
data += b'TOIg'
data += struct.pack('<HH', w, h)
data += struct.pack('<I', len(zdata))
data += zdata
if savefiles:
with open(ofn, 'wb') as f:
f.write(data)
print('Written %s ... %d bytes' % (ofn, len(data)))
with open(ofn + '.h', 'wt') as f:
f.write('static const uint8_t toi_%s[] = {\n' % ifn[:-4])
if im.mode == 'RGB':
f.write(" 'T', 'O', 'I', 'f',\n")
else:
f.write(" 'T', 'O', 'I', 'g',\n")
f.write(' (uint16_t)%d, (uint16_t)%d,\n' % (w, h))
f.write(' (uint32_t)%d,\n' % len(zdata))
f.write(' ')
for b in zdata:
f.write(' 0x%02x,' % b)
f.write('\n};\n')
print('Written %s ... done' % (ofn + '.h'))
return data
def main():
if len(sys.argv) < 2:
print('Usage png2toi image.png')
return 1
ifn = sys.argv[1]
if not ifn.endswith('.png'):
print('Must provide PNG file')
return 2
process_image(ifn, savefiles=True)
main()