1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
#!/usr/bin/env python3
from PIL import BdfFontFile, Image
import os
import serial
import argparse
compiled_output_path = 'compiled_eeprom'
header_path = 'eeprom_address.h'
eeprom_length = 131072 # 128 kib
data_path = "./eeprom_data"
output = open(compiled_output_path, 'wb')
header = open(header_path, 'w')
page_bit_width = 128
page_bit_height = 8
page_cnt = 4
#fonts
# for some reason BdfFontFile.BdfFontFile.bitmap doesn't have proper spacing
# so we'll just manually go through each character ourselves
# it's expected I'll rename fonts to how I think they should be refrenced beorehand
# also note we have no protection from using unsed chars, I can't let this project
# get to big for litteraly no reason
header.write("/** GENERATED BY EEPROM COMPILER SCRIPT **/\n\n")
header.write("// FONTS\n")
for file in os.listdir("{}/fonts/".format(data_path)):
path = "{}/fonts/{}".format(data_path, file)
if os.path.isfile(path) and path.split('.')[-1] == 'bdf':
with open(path, 'rb') as font_fd:
font_bdf = BdfFontFile.BdfFontFile(font_fd)
font_name = file.split('.')[0].capitalize()
header.write("#define FONT_{}_ADDR\t0x{:04x}\n".format(font_name, output.tell()))
first_char = False
for char in enumerate(font_bdf.glyph):
if char[1]:
if not first_char:
first_char = True
header.write(("#define FONT_{}_FIRST_CHAR\t{}\n"
"#define FONT_{}_WIDTH\t{}\n"
"#define FONT_{}_HEIGHT\t{}\n").format(
font_name, char[0],
font_name, char[1][-1].size[0],
font_name, char[1][-1].size[1]))
output.write(char[1][-1].tobytes('raw'))
header.write("\n\n// IMAGES\n#define IMG_BEGIN\t0x{:04x}\n".format(output.tell()))
image_cnt = 0
# images
for file in os.listdir("{}/images/".format(data_path)):
path = "{}/images/{}".format(data_path, file)
if os.path.isfile(path) and path.split('.')[-1] == 'png':
with open(path, 'rb') as image_fd:
image_cnt += 1
image_bitmap = []
image_bitmap_remapped = []
image = Image.open(image_fd)
if not image.mode == 'RGB':
print("this script only compiles RGB formatted photos! (I'm lazy\n")
exit(1)
header.write("#define IMG_{}_ADDR\t0x{:04x}\n".format(
file.split('.')[0].capitalize(),
output.tell()))
for byte in range(0, len(image.tobytes()), 3):
if (byte / 3) % 8 == 0:
image_bitmap.append(0)
if sum(image.tobytes()[byte:byte+3]) > 0:
image_bitmap[-1] |= (int(byte / 3)) % 8
# is this supposed to be big endian?
image_bitmap_remapped = [0] * len(image_bitmap)
for bit in range(0, page_bit_width * page_bit_height * page_cnt):
w = page_bit_width
h = page_bit_height
i = bit
#I am so sorry.
extract_bit = (((i % w) * page_bit_height) +
(int(i / w) % page_bit_height) +
(int(i / (w * page_bit_height)) *
(w * page_bit_height)))
if (extract_bit % 8) - (bit % 8) >= 0:
image_bitmap_remapped[int(bit / 8)] |= \
(image_bitmap[int(extract_bit / 8)] & (extract_bit % 8)) >> \
((extract_bit % 8) - (bit % 8))
else:
image_bitmap_remapped[int(bit / 8)] |= \
(image_bitmap[int(extract_bit / 8)] & (extract_bit % 8)) << \
((bit % 8) - (extract_bit % 8))
[output.write(byte.to_bytes(1, 'big')) for byte in image_bitmap_remapped]
header.write("#define IMG_COUNT\t{}\n\n".format(image_cnt))
print("EEPROM used: {}% ({} out of {} bits)".format(
(output.tell() / eeprom_length) * 100,
output.tell(), eeprom_length))
if(output.tell() > eeprom_length):
print("WARNING: You've used more eeprom then there is available!\n")
output.close()
header.close()
|