-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathstealth_pnginfo.py
141 lines (133 loc) · 5.36 KB
/
stealth_pnginfo.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
from PIL import Image
import PIL
import warnings
import gzip
import json
from pprint import pp
import sys
def read_info_from_image_stealth(image):
# geninfo, items = original_read_info_from_image(image)
# possible_sigs = {'stealth_pnginfo', 'stealth_pngcomp', 'stealth_rgbinfo', 'stealth_rgbcomp'}
# respecting original pnginfo
# if geninfo is not None:
# return geninfo, items
# trying to read stealth pnginfo
width, height = image.size
pixels = image.load()
has_alpha = True if image.mode == 'RGBA' else False
mode = None
compressed = False
binary_data = ''
buffer_a = ''
buffer_rgb = ''
index_a = 0
index_rgb = 0
sig_confirmed = False
confirming_signature = True
reading_param_len = False
reading_param = False
read_end = False
for x in range(width):
for y in range(height):
if has_alpha:
r, g, b, a = pixels[x, y]
buffer_a += str(a & 1)
index_a += 1
else:
r, g, b = pixels[x, y]
buffer_rgb += str(r & 1)
buffer_rgb += str(g & 1)
buffer_rgb += str(b & 1)
index_rgb += 3
if confirming_signature:
if index_a == len('stealth_pnginfo') * 8:
decoded_sig = bytearray(int(buffer_a[i:i + 8], 2) for i in
range(0, len(buffer_a), 8)).decode('utf-8', errors='ignore')
if decoded_sig in {'stealth_pnginfo', 'stealth_pngcomp'}:
confirming_signature = False
sig_confirmed = True
reading_param_len = True
mode = 'alpha'
if decoded_sig == 'stealth_pngcomp':
compressed = True
buffer_a = ''
index_a = 0
else:
read_end = True
break
elif index_rgb == len('stealth_pnginfo') * 8:
decoded_sig = bytearray(int(buffer_rgb[i:i + 8], 2) for i in
range(0, len(buffer_rgb), 8)).decode('utf-8', errors='ignore')
if decoded_sig in {'stealth_rgbinfo', 'stealth_rgbcomp'}:
confirming_signature = False
sig_confirmed = True
reading_param_len = True
mode = 'rgb'
if decoded_sig == 'stealth_rgbcomp':
compressed = True
buffer_rgb = ''
index_rgb = 0
elif reading_param_len:
if mode == 'alpha':
if index_a == 32:
param_len = int(buffer_a, 2)
reading_param_len = False
reading_param = True
buffer_a = ''
index_a = 0
else:
if index_rgb == 33:
pop = buffer_rgb[-1]
buffer_rgb = buffer_rgb[:-1]
param_len = int(buffer_rgb, 2)
reading_param_len = False
reading_param = True
buffer_rgb = pop
index_rgb = 1
elif reading_param:
if mode == 'alpha':
if index_a == param_len:
binary_data = buffer_a
read_end = True
break
else:
if index_rgb >= param_len:
diff = param_len - index_rgb
if diff < 0:
buffer_rgb = buffer_rgb[:diff]
binary_data = buffer_rgb
read_end = True
break
else:
# impossible
read_end = True
break
if read_end:
break
if sig_confirmed and binary_data != '':
# Convert binary string to UTF-8 encoded text
byte_data = bytearray(int(binary_data[i:i + 8], 2) for i in range(0, len(binary_data), 8))
try:
if compressed:
decoded_data = gzip.decompress(bytes(byte_data)).decode('utf-8')
else:
decoded_data = byte_data.decode('utf-8', errors='ignore')
geninfo = decoded_data
except:
pass
result = json.loads(geninfo)
if "Comment" in result:
result["Comment"] = json.loads(result["Comment"])
return result, geninfo
# LANCZOS = (Image.Resampling.LANCZOS if hasattr(Image, 'Resampling') else Image.LANCZOS)
# original_read_info_from_image = images.read_info_from_image
# images.read_info_from_image = read_info_from_image_stealth
# generation_parameters_copypaste.send_image_and_dimensions = send_rgb_image_and_dimension
# original_resize_image = images.resize_image
# images.resize_image = stealth_resize_image
# script_callbacks.on_ui_settings(on_ui_settings)
# script_callbacks.on_before_image_saved(add_stealth_pnginfo)
# script_callbacks.on_after_component(on_after_component_change_pnginfo_image_mode)
with Image.open(sys.argv[1]) as image:
result, geninfo = read_info_from_image_stealth(image)
print(geninfo)