-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathlcd-gif.py
executable file
·96 lines (77 loc) · 2.37 KB
/
lcd-gif.py
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
#!/usr/bin/env python3
# SPDX-License-Identifier: MIT
# Copyright (C) J. Neuschäfer
#
# Turn LCD commands in trace logs into an animated GIF
import re, sys
from PIL import Image, ImageDraw
re_sspi = re.compile('^\[.*\] SSPI.WR[A-Z]* ([01]), .*\[([0-9]*),([0-9]*)\] *([0-9a-f ]*) -> ([0-9a-f ]*)$')
def parse_hex(h):
h = h.strip()
if h == '':
return b''
return bytes([int(x, 16) for x in h.strip().split(' ')])
last_row = 0
matrix = {}
frame_log = []
interesting_rows = set()
max_width = 0
def save_frame():
if 0 not in matrix:
return
for row in matrix:
data = matrix[row]
if data != b'\0' * len(data):
interesting_rows.add(row)
global max_width
if len(data) > max_width:
max_width = len(data)
frame_log.append(matrix.copy())
def crunch(fn):
f = open(fn, 'r')
last_row = 0
for line in f.readlines():
m = re_sspi.match(line)
if not m:
continue
cs = int(m.group(1))
send_len = int(m.group(2))
recv_len = int(m.group(3))
send_data = parse_hex(m.group(4))
recv_data = parse_hex(m.group(5))
assert len(send_data) == send_len
assert len(recv_data) == recv_len
if cs == 0 and send_len == 4:
assert send_data[0] == 0x46
assert send_data[1] in range(0xb0, 0xbf)
row = send_data[1] - 0xb0
if row < last_row:
save_frame()
last_row = row
if cs == 1:
matrix[last_row] = send_data
def write_gif(fn):
rows = list(interesting_rows)
height = len(rows) * 8
width = max_width
frames = []
for matrix in frame_log:
im = Image.new('RGB', (width, height), "blue")
px = im.load()
for ri, row in enumerate(rows):
data = matrix[row]
for i in range(len(data)):
for j in range(8):
if (1 << j) & data[i]:
px[i, 8*ri+j] = 0xffffff
frames.append(im)
if frames == []:
print("No image data found!")
else:
frames[0].save(fn, format="GIF", append_images=frames, save_all=True, duration=10, loop=0)
print(len(frames), "frames saved.")
if len(sys.argv) == 3:
crunch(sys.argv[1])
write_gif(sys.argv[2])
else:
print("Usage: lcd.py trace.log lcd.gif")