-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgenerate_splash_header.py
More file actions
84 lines (70 loc) · 2.73 KB
/
Copy pathgenerate_splash_header.py
File metadata and controls
84 lines (70 loc) · 2.73 KB
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
import sys
import os
from pathlib import Path
def main():
if len(sys.argv) < 2:
print("Usage: python3 generate_splash_header.py <path_to_splash.bin>")
sys.exit(1)
input_path = Path(sys.argv[1])
if not input_path.exists():
print(f"Error: {input_path} not found.")
sys.exit(1)
output_path = Path("firmware_arduino/splash.h")
print(f"Reading {input_path}...")
with open(input_path, "rb") as f:
data = f.read()
print(f"Size: {len(data)} bytes")
# RLE Compression (PackBits variant)
compressed_data = bytearray()
i = 0
while i < len(data):
# Look for run of identical bytes
run_len = 1
while i + run_len < len(data) and run_len < 128 and data[i + run_len] == data[i]:
run_len += 1
if run_len > 1:
# Repeat run
# Flag: 128 + (run_len - 1) -> 129..255
# Actually, let's map 2..129 to 128..255?
# 128 + (run_len - 2)
# If run_len is 2, flag is 128.
# If run_len is 129, flag is 255.
# Max run length 129.
compressed_data.append(128 + (run_len - 2))
compressed_data.append(data[i])
i += run_len
else:
# Literal run
# Look ahead for repeats to stop literal run
lit_len = 0
while i + lit_len < len(data) and lit_len < 128:
# Check if next 2 bytes are identical (start of a run)
if i + lit_len + 1 < len(data) and data[i + lit_len] == data[i + lit_len + 1]:
break
lit_len += 1
# Flag: 0..127 -> 1..128 literals
compressed_data.append(lit_len - 1)
for k in range(lit_len):
compressed_data.append(data[i + k])
i += lit_len
print(f"Compressed Size: {len(compressed_data)} bytes ({(len(compressed_data)/len(data))*100:.1f}%)")
# Generate C header
print(f"Writing to {output_path}...")
with open(output_path, "w") as f:
f.write("#ifndef SPLASH_H\n")
f.write("#define SPLASH_H\n\n")
f.write("#include <Arduino.h>\n\n")
f.write("// Generated splash screen data (RLE Compressed)\n")
f.write(f"const uint8_t splash_data[{len(compressed_data)}] PROGMEM = {{\n")
# Write hex data
for i, byte in enumerate(compressed_data):
if i % 16 == 0:
f.write(" ")
f.write(f"0x{byte:02X}, ")
if (i + 1) % 16 == 0:
f.write("\n")
f.write("\n};\n\n")
f.write("#endif\n")
print("Done! Now include \"splash.h\" in your Arduino sketch.")
if __name__ == "__main__":
main()