-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathbinmap.py
402 lines (303 loc) · 9.61 KB
/
binmap.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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
#!/usr/bin/env python2
from __future__ import division
import os
import sys
import cv2
import numpy as np
# class DragDropHandler(object):
# def __init__(self, cbstart, cbdrag, cbstop):
# self.cbstart = cbstart
# self.cbdrag = cbdrag
# self.cbstop = cbstop
# self.data_origin = None
# def on_down(self, event, x, y, flags, param):
# self.data_origin = self.cbstart()
# self.screen_origin = (x,y)
# def on_drag(self, event, x, y, flags, param):
# self.cbdrag()
scrollbarwidth = 512
scrollbarheight = 768
selection_start = 0 # bits
selection_width = 128
selection_height = 128
# selected bits = w*h
visualization_display_width = 512
visualization_display_height = 2048
scrollbar_drag_start_origin = None
scrollbar_drag_start_screen = None
visualization_drag_start_map = None
visualization_drag_start_screen = None
infile = np.memmap(sys.argv[1], dtype=np.uint8, mode='r')
sourcebits = np.unpackbits(infile) * 255
im_scrollbar = None
im_scrollbar_display = None
def round_down(x, k):
return (x // k) * k
def round_up(x, k):
return x + (-x % k)
def redraw_scrollbar():
global im_scrollbar
global im_scrollbar_display
w = int(selection_width)
h = int(selection_height)
if im_scrollbar is None:
im_scrollbar = np.pad(sourcebits, (0, -len(sourcebits) % scrollbarwidth), 'constant').reshape((-1, scrollbarwidth))
im_scrollbar_display = None
if im_scrollbar_display is None:
im_scrollbar_display = cv2.resize(
im_scrollbar,
dsize=(scrollbarwidth, scrollbarheight),
interpolation=cv2.INTER_AREA)
canvas = im_scrollbar_display.copy()
canvas = cv2.cvtColor(src=canvas, code=cv2.COLOR_GRAY2BGR)
#print canvas.shape
#canvas[:,:,(0,2)] = 0
cv2.rectangle(
canvas,
(0, int(selection_start / len(sourcebits) * scrollbarheight)),
(scrollbarwidth, int((selection_start + w*h) / len(sourcebits) * scrollbarheight)),
(0, 0, 255),
thickness=1)
cv2.imshow("scrollbar", canvas)
return im_scrollbar
def redraw_visualization():
w = int(selection_width)
h = int(selection_height)
start = selection_start
stop = selection_start + w*h
pixels = sourcebits[start:stop].reshape((h, w))
canvas = cv2.resize(
pixels,
(visualization_display_width, visualization_display_height),
interpolation=cv2.INTER_AREA)
cv2.imshow("visualization", canvas)
do_redraw = True
def invalidate():
global do_redraw
do_redraw = True
def redraw():
global selection_start
w = int(selection_width)
h = int(selection_height)
if selection_start < 0:
selection_start = 0
elif selection_start + w*h >= len(sourcebits):
selection_start = len(sourcebits) - w*h
redraw_scrollbar()
redraw_visualization()
print_status()
def on_scrollbar_scroll(event, x, y, flags, param):
global selection_height
direction = (flags > 0) - (flags < 0)
k = 1.0/16
if direction < 0:
selection_height *= 1+k
else:
selection_height /= 1+k
invalidate()
def on_scrollbar_down(event, x, y, flags, param):
global scrollbar_drag_start_origin, scrollbar_drag_start_screen
scrollbar_drag_start_screen = y / scrollbarheight * len(sourcebits)
scrollbar_drag_start_origin = selection_start
def on_scrollbar_drag(event, x, y, flags, param):
w = int(selection_width)
h = int(selection_height)
scrollbar_drag_now_screen = y / scrollbarheight * len(sourcebits)
delta = scrollbar_drag_now_screen - scrollbar_drag_start_screen
global selection_start
selection_start = scrollbar_drag_start_origin
selection_start += int(round_down(delta * w*h*32.0/len(sourcebits), w))
invalidate()
def on_scrollbar_up(event, x, y, flags, param):
global scrollbar_drag_start_origin, scrollbar_drag_start_screen
scrollbar_drag_start_screen = None
scrollbar_drag_start_origin = None
def on_visualization_scroll(event, x, y, flags, param):
global selection_width
direction = (flags > 0) - (flags < 0)
selection_width += direction
invalidate()
def on_visualization_down(event, x, y, flags, param):
global visualization_drag_start_map
global visualization_drag_start_screen
w = int(selection_width)
h = int(selection_height)
visualization_drag_start_screen = np.array([
x / visualization_display_width * w,
y / visualization_display_height * h])
visualization_drag_start_map = selection_start
def on_visualization_drag(event, x, y, flags, param):
#visualization_drag_now_screen = np.array([x, y])
w = int(selection_width)
h = int(selection_height)
offset_bits = visualization_drag_start_map
offset_bits -= w * (
int((y/visualization_display_height*h) - visualization_drag_start_screen[1])
)
offset_bits -= (x/visualization_display_width*w - visualization_drag_start_screen[0])
global selection_start
selection_start = int(offset_bits)
invalidate()
def on_visualization_up(event, x, y, flags, param):
global visualization_drag_start_map, visualization_drag_start_screen
visualization_drag_start_screen = None
visualization_drag_start_map = None
def visualization_callback(event, x, y, flags, param):
if event == 10: # scroll wheel
on_visualization_scroll(event, x, y, flags, param)
elif event == 1: # mouse down
print "viz down"
on_visualization_down(event, x, y, flags, param)
elif event == 0 and flags == 1: # mouse drag
on_visualization_drag(event, x, y, flags, param)
elif event == 4: # mouse up
on_visualization_up(event, x, y, flags, param)
def on_scrollbar_rightclick(event, x, y, flags, param):
global selection_start
w = int(selection_width)
h = int(selection_height)
center = y/scrollbarheight * len(sourcebits)
selection_start = center - 0.5 * w*h
selection_start = round(selection_start / selection_width) * selection_width
invalidate()
def scrollbar_callback(event, x, y, flags, param):
if event == 10: # scroll wheel
on_scrollbar_scroll(event, x, y, flags, param)
elif event == 1: # mouse down
on_scrollbar_down(event, x, y, flags, param)
elif event == 0 and flags == 1: # mouse drag
on_scrollbar_drag(event, x, y, flags, param)
elif event == 4: # mouse up
on_scrollbar_up(event, x, y, flags, param)
elif event == 2: # right click
on_scrollbar_rightclick(event, x, y, flags, param)
elif event == 0 and flags == 2: # right drag
on_scrollbar_rightclick(event, x, y, flags, param)
def hexdump(start, bytes, width=16):
def charfunc(code):
if code is None:
return ' '
elif 32 <= code < 128:
return chr(code)
else:
return '.'
for i in range(0, len(bytes), width):
row = bytes[i:i+width]
print "{:8x} : {} : {}".format(
start + i,
' '.join(
"{:02X}".format(row[j]) if j < len(row) else ' '
for j in xrange(width)
),
''.join(
charfunc(row[j] if j < len(row) else None)
for j in xrange(width)
),
)
def process_key(keycode):
global keybuffer
global selection_start
global selection_width
w = int(selection_width)
h = int(selection_height)
if keycode == 0x08:
keybuffer = keybuffer[:-1]
sys.stdout.write('\b \b')
elif keycode == 0x0D or keycode == 0x0A:
print
process_command(keybuffer)
keybuffer = ""
elif keycode == ord('-'):
selection_width -= 1
elif keycode in [ord('='), ord('+')]:
selection_width += 1
elif keycode == VK_PGUP:
selection_start -= w*h
elif keycode == VK_PGDN:
selection_start += w*h
elif keycode == VK_LEFT:
selection_start -= 1
elif keycode == VK_RIGHT:
selection_start += 1
elif keycode == VK_UP:
selection_start -= w
elif keycode == VK_DOWN:
selection_start += w
elif keycode == 4: # ctrl-d
hexdump(
selection_start // 8,
np.packbits(sourcebits[selection_start:selection_start+w*h]),
width=round_up(w, 8) // 8
)
else:
print "keycode", keycode
invalidate()
def process_command(cmd):
if cmd.startswith('g'):
global selection_start
offset = int(cmd[1:], 16)
selection_start = offset * 8
elif cmd.startswith('w'):
global selection_width
width = int(cmd[1:], 0)
selection_width = width
elif cmd.startswith('h'):
global selection_height
height = int(cmd[1:], 0)
selection_height = height
invalidate()
def print_status():
print "start: 0x{:8x} + {} bits, {:.1f} ({}+{}) x {:.1f} pixels (stride {} B)".format(
int(selection_start // 8),
selection_start % 8,
selection_width, int(selection_width) // 8, int(selection_width) % 8,
selection_height,
int(selection_width)*int(selection_height) // 8,
)
cv2.namedWindow("visualization", cv2.WINDOW_NORMAL)
cv2.namedWindow("scrollbar", cv2.WINDOW_NORMAL)
#cv2.resizeWindow("scrollbar", int(scrollbarwidth), int(scrollbarheight))
cv2.setMouseCallback("visualization", visualization_callback)
cv2.setMouseCallback("scrollbar", scrollbar_callback)
keybuffer = ""
# [25.08. 22:10:29] <jn> keycode 65362
# [25.08. 22:10:29] <jn> start: 0x 6e3c3 + 2 bits, 128.0 x 128.0 pixels
# [25.08. 22:10:29] <jn> start: 0x 6e3c3 + 2 bits, 128.0 x 128.0 pixels
# [25.08. 22:10:29] <jn> keycode 65363
# [25.08. 22:10:29] <jn> start: 0x 6e3c3 + 2 bits, 128.0 x 128.0 pixels
# [25.08. 22:10:31] <jn> start: 0x 6e3c3 + 2 bits, 128.0 x 128.0 pixels
# [25.08. 22:10:34] <jn> keycode 65364
# [25.08. 22:10:36] <jn> start: 0x 6e3c3 + 2 bits, 128.0 x 128.0 pixels
# [25.08. 22:10:39] <jn> start: 0x 6e3c3 + 2 bits, 128.0 x 128.0 pixels
# [25.08. 22:10:41] <jn> keycode 65361
# [25.08. 22:10:42] <Cracki> hoch rechts unten links
if os.name == 'nt':
VK_PGUP = 2162688
VK_PGDN = 2228224
VK_UP = 2490368
VK_DOWN = 2621440
VK_LEFT = 2424832
VK_RIGHT = 2555904
else:
VK_PGUP = 65365
VK_PGDN = 65366
VK_UP = 65362
VK_DOWN = 65364
VK_LEFT = 65361
VK_RIGHT = 65363
invalidate()
while True:
if do_redraw:
redraw()
do_redraw = False
key = cv2.waitKey(20)
if key == -1:
continue
elif key in (27,):
break
elif not (0x20 <= key < 0x80) or chr(key) in '-=+':
process_key(key)
else:
keybuffer += chr(key)
sys.stdout.write(chr(key))
cv2.destroyAllWindows()