-
Notifications
You must be signed in to change notification settings - Fork 10
/
extract_edof.py
176 lines (138 loc) · 3.98 KB
/
extract_edof.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
#!/usr/bin/python3
#encoding=utf-8
# Author João Paulo Barraca <[email protected]>
import sys
import os
import binascii
from PIL import Image
# Configuration defaults
show_edof = False
save_edof = False
save_original = False
save_processed = False
delete_file = False
def extract_edof(data, idx, fname):
if data[idx + 4:idx + 8] != b'edof':
print("ERROR: Frame is not EDOF")
return False
idx += 8
columns = int.from_bytes(data[idx + 16: idx + 18], byteorder='little')
rows = int.from_bytes(data[idx + 18: idx + 20], byteorder='little')
print("\t* found EDOF at %d with geometry=%dx%d" % (idx, columns, rows))
orientation = data[idx + 7]
idx += 68
img = Image.frombuffer('L', (columns, rows), data[idx:], 'raw', 'L', 0, 0)
if orientation == 0x10:
img = img.transpose(Image.FLIP_TOP_BOTTOM)
elif orientation == 0x12:
img = img.transpose(Image.FLIP_LEFT_RIGHT)
elif orientation == 0x13:
img = img.transpose(Image.TRANSPOSE)
if show_edof:
img.show()
if save_edof:
outfname = (''.join(fname.split('.')[:-1])) + '-EDOF.png'
print("\t * saving to %s" % outfname)
img.save(outfname)
return True
def scan_segment(data, idx, fname, segment_index):
if data[idx:idx + 2] != b'\xff\xd8':
return -1
i = idx + 2
while i < len(data):
if data[i] == 0xff:
if data[i + 1] == 0xd9 or data[i + 1] == 0xd8:
i += 2
continue
if data[i + 1] == 0xda: # SOA
j = i + 2
while not (data[j] == 0xff and data[j + 1] == 0xd9):
j += 1
j += 1
print("\t* found segment %d, range %d to %d, length %d" % (segment_index, idx, j, j - idx))
if (save_original and segment_index == 1) or (save_processed and segment_index == 0):
outfname = (''.join(fname.split('.')[:-1])) + ('-%d.JPG' % segment_index)
print("\t * saving segment to %s" % outfname)
f = open(outfname, "wb")
f.write(data[idx: j + 1])
f.close()
return j
length = 256 * data[i+2] + data[i+3] + 2
i += length
continue
i += 1
return 0
def print_usage():
print("Usage: %s [options] img1 img2 img3... " % sys.argv[0])
print("Options: ")
print("\t-p: Save the originaly processed image to the same directory")
print("\t-o: Save the originaly unprocessed image to the same directory")
print("\t-e: Save the EDOF as an image to the same directory")
print("\t-v: View the EDOF image")
print("\t-d: Delete file and only keep extracted (will enforce -o -e)")
def main(fname):
print("Processing: %s" % fname)
fin = None
try:
fin = open(fname, "rb")
except FileNotFoundError:
print("ERROR: Could not open %s" % fname)
return False
data = fin.read()
if data[:3] != b'\xff\xd8\xff':
print("No JPEG header found")
return False
print ("\t* scanning file")
if data.find(bytes([0x00, 0x65, 0x64, 0x6f, 0x66, 0x00])) < 0:
print("No EDOF header found")
return False
idx = 0
segment_index = 0
while True:
r = scan_segment(data, idx, fname, segment_index)
if r == -1:
if segment_index > 1:
# No standard segment was found. Search for EDOF
return extract_edof(data, idx, fname)
else:
return False
segment_index += 1
idx = r + 1
if idx > len(data):
return False
if __name__ == "__main__":
print("Huawei Dual Camera EDOF Extractor\n")
if sys.version_info[0] < 3:
print("This script requires Python 3")
sys.exit(-1)
if len(sys.argv) < 2:
print_usage()
sys.exit(-1)
else:
for o in sys.argv[1:]:
if o.startswith("-"):
for c in o[1:]:
if c == 'e':
save_edof = True
elif c == 'o':
save_original = True
elif c == 'p':
save_processed = True
elif c == 'v':
show_edof = True
elif c == 'd':
save_original = True
delete_file = True
else:
print("Unknown Option: %s" % c)
print_usage()
sys.exit(-1)
for p in sys.argv[1:]:
if p[0] != "-":
if not os.path.exists(p):
print("File not found: %s" % p)
continue
r = main(p)
if r and delete_file:
print("\t* Deleting file: %s" % p)
os.unlink(p)