-
Notifications
You must be signed in to change notification settings - Fork 2
/
exif.py
129 lines (120 loc) · 3.69 KB
/
exif.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
import sys
from datetime import datetime
import random
import bisect
import time
import zipfile
from PIL import Image
from PIL.ExifTags import TAGS
argv = sys.argv
path = argv[1]
programs = {}
with zipfile.ZipFile(path) as zipObj:
zipObj.extractall("./")
for filename in zipObj.namelist():
if filename[-1] == "/":
continue
img = Image.open(filename)
exif = img._getexif()
DateTimeOriginal = ""
DateTime = ""
MeteringMode = 0
command = ""
lat = 0.0
lng = 0.0
height = 0
width = 0
for key, val in exif.items():
if TAGS.get(key, key) == "DateTimeOriginal":
DateTimeOriginal = datetime.strptime(val, "%Y:%m:%d %H:%M:%S")
elif TAGS.get(key, key) == "DateTime":
DateTime = datetime.strptime(val, "%Y:%m:%d %H:%M:%S")
elif TAGS.get(key, key) == "MeteringMode":
MeteringMode = val
elif TAGS.get(key, key) == "ISOSpeedRatings":
if val < 100:
command = "substitution"
elif val < 200:
command = "input"
elif val < 300:
command = "output"
elif val < 400:
command = "addition"
elif val < 500:
command = "substraction"
elif val < 600:
command = "multiplication"
elif val < 700:
command = "division"
elif val < 800:
command = "remainder"
elif TAGS.get(key, key) == "ExifImageHeight":
height = val
elif TAGS.get(key, key) == "ExifImageWidth":
width = val
elif TAGS.get(key, key) == "GPSInfo":
lat = (1 if val[1] == "N" else - 1) * (1.0 * val[2][0] + 1.0 / 60 * val[2][1])
lng = (1 if val[3] == "E" else - 1) * (1.0 * val[4][0] + 1.0 / 60 * val[4][1])
if DateTimeOriginal in programs:
programs[DateTimeOriginal].append({"DateTimeOriginal": DateTimeOriginal,
"DateTime": DateTime,
"MeteringMode": MeteringMode,
"command": command,
"height": height,
"width": width,
"latitude": lat,
"longitude": lng
})
else:
programs[DateTimeOriginal] = [{"DateTimeOriginal": DateTimeOriginal,
"DateTime": DateTime,
"MeteringMode": MeteringMode,
"command": command,
"height": height,
"width": width,
"latitude": lat,
"longitude": lng
}]
curTime = min(programs.keys())
times = sorted(list(programs.keys()))
def getNextTime(curTime):
if curTime >= max(programs.keys()):
return None
return times[bisect.bisect_right(times, curTime)]
data = {}
while True:
target = programs[curTime][0]
if target["DateTime"] != target["DateTimeOriginal"]:
addrfrom = target["longitude"]
if target["MeteringMode"] & 1:
addrfrom = data[target["longitude"]]
if data[addrfrom] >= 0:
curTime = target["DateTime"]
time.sleep(
abs((curTime - target["DateTimeOriginal"]).total_seconds()) / 150)
else:
addrfrom = target["longitude"]
if target["MeteringMode"] & 1:
addrfrom = data[target["longitude"]]
addrto = target["latitude"]
if target["MeteringMode"] & 2:
addrto = data[target["latitude"]]
if target["command"] == "substitution":
data[addrto] = target["width"] * target["height"]
elif target["command"] == "input":
data[addrto] = ord(sys.stdin.buffer.read(1))
elif target["command"] == "output":
sys.stdout.buffer.write(chr(data[addrfrom]).encode("ascii"))
elif target["command"] == "addition":
data[addrto] += data[addrfrom]
elif target["command"] == "substraction":
data[addrto] -= data[addrfrom]
elif target["command"] == "multiplicatoin":
data[addrto] *= data[addrfrom]
elif target["command"] == "division":
data[addrto] //= data[addrfrom]
elif target["command"] == "remainder":
data[addrto] %= data[addrfrom]
curTime = getNextTime(curTime)
if curTime is None:
break