chunklate 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- Chunklate.py +2578 -0
- chunklate/__init__.py +108 -0
- chunklate/ancillary.py +59 -0
- chunklate/ancillary_runtime.py +57 -0
- chunklate/bruteforce.py +1156 -0
- chunklate/bruteforce_result.py +132 -0
- chunklate/bruteforce_runtime.py +3525 -0
- chunklate/bruteforce_viewer.py +221 -0
- chunklate/checkpoint.py +338 -0
- chunklate/checkpoint_actions_runtime.py +1079 -0
- chunklate/checkpoint_runtime.py +933 -0
- chunklate/chunk_info.py +1700 -0
- chunklate/chunk_name_runtime.py +816 -0
- chunklate/chunk_order.py +378 -0
- chunklate/chunk_order_runtime.py +529 -0
- chunklate/chunk_report.py +545 -0
- chunklate/chunk_scanner.py +266 -0
- chunklate/chunk_state.py +362 -0
- chunklate/chunk_state_runtime.py +183 -0
- chunklate/chunk_story.py +55 -0
- chunklate/chunk_validation_runtime.py +277 -0
- chunklate/cli.py +840 -0
- chunklate/compression_signatures.py +437 -0
- chunklate/crc32_forge.py +182 -0
- chunklate/decisions.py +116 -0
- chunklate/deflate_crc_solver.py +1875 -0
- chunklate/deflate_header.py +774 -0
- chunklate/deflate_probe.py +1518 -0
- chunklate/deflate_reverse.py +243 -0
- chunklate/dummy_chunk.py +101 -0
- chunklate/dummy_chunk_runtime.py +571 -0
- chunklate/error_log.py +110 -0
- chunklate/fixit_felix.py +1966 -0
- chunklate/fixit_felix_runtime.py +11071 -0
- chunklate/fog_of_war.py +275 -0
- chunklate/full_chunk_forcer.py +300 -0
- chunklate/getinfo_runtime.py +451 -0
- chunklate/getspec_runtime.py +179 -0
- chunklate/gpu_opengl.py +163 -0
- chunklate/gpu_runtime.py +28 -0
- chunklate/history.py +7 -0
- chunklate/idat.py +1837 -0
- chunklate/idat_bruteforce.py +18999 -0
- chunklate/idat_chain.py +254 -0
- chunklate/idat_crc_forge.py +2287 -0
- chunklate/idat_kraft_opengl_backend.py +224 -0
- chunklate/image_viewer.py +195 -0
- chunklate/libpng_check.py +141 -0
- chunklate/libpng_runtime.py +98 -0
- chunklate/magic_runtime.py +2634 -0
- chunklate/main_runtime.py +1938 -0
- chunklate/messages.py +5 -0
- chunklate/name_shift.py +237 -0
- chunklate/name_shift_runtime.py +275 -0
- chunklate/nearby.py +279 -0
- chunklate/nearby_runtime.py +684 -0
- chunklate/output.py +787 -0
- chunklate/package_update.py +140 -0
- chunklate/palette.py +45 -0
- chunklate/palette_runtime.py +920 -0
- chunklate/palette_ui.py +641 -0
- chunklate/platform_runtime.py +175 -0
- chunklate/png.py +5798 -0
- chunklate/prompts.py +67 -0
- chunklate/question_runtime.py +359 -0
- chunklate/relics.py +1221 -0
- chunklate/relics_runtime.py +855 -0
- chunklate/relics_ui.py +271 -0
- chunklate/repair_routes.py +72 -0
- chunklate/runtime_state.py +266 -0
- chunklate/smash_backend.py +966 -0
- chunklate/smash_bruteforce.py +579 -0
- chunklate/smash_checkpoint.py +182 -0
- chunklate/smash_opengl_backend.py +1077 -0
- chunklate/sorting.py +11 -0
- chunklate/spec_length_runtime.py +56 -0
- chunklate/specs.py +1147 -0
- chunklate/stdio.py +51 -0
- chunklate/ui.py +738 -0
- chunklate/ui_runtime.py +97 -0
- chunklate/ultimate_opengl_backend.py +1384 -0
- chunklate/ultimate_reference_ui.py +895 -0
- chunklate/writer.py +133 -0
- chunklate/writer_runtime.py +676 -0
- chunklate/youshallpass_runtime.py +198 -0
- chunklate-0.1.0.dist-info/METADATA +411 -0
- chunklate-0.1.0.dist-info/RECORD +90 -0
- chunklate-0.1.0.dist-info/WHEEL +5 -0
- chunklate-0.1.0.dist-info/entry_points.txt +2 -0
- chunklate-0.1.0.dist-info/top_level.txt +2 -0
Chunklate.py
ADDED
|
@@ -0,0 +1,2578 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
from argparse import ArgumentParser, SUPPRESS
|
|
3
|
+
from datetime import datetime
|
|
4
|
+
import os
|
|
5
|
+
import sys
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def Local_Venv_Python(script_path=None, *, os_name=None):
|
|
9
|
+
root = os.path.dirname(os.path.abspath(script_path or __file__))
|
|
10
|
+
os_name = os.name if os_name is None else os_name
|
|
11
|
+
if os_name == "nt":
|
|
12
|
+
candidate = os.path.join(root, ".venv", "Scripts", "python.exe")
|
|
13
|
+
else:
|
|
14
|
+
candidate = os.path.join(root, ".venv", "bin", "python")
|
|
15
|
+
if os.path.exists(candidate):
|
|
16
|
+
return candidate
|
|
17
|
+
return None
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def Should_Reexec_Local_Venv(script_path=None, executable=None, env=None):
|
|
21
|
+
env = env if env is not None else os.environ
|
|
22
|
+
if env.get("CHUNKLATE_NO_VENV_REEXEC"):
|
|
23
|
+
return False
|
|
24
|
+
venv_python = Local_Venv_Python(script_path)
|
|
25
|
+
if not venv_python:
|
|
26
|
+
return False
|
|
27
|
+
current = executable or sys.executable
|
|
28
|
+
return os.path.normcase(os.path.abspath(current)) != os.path.normcase(os.path.abspath(venv_python))
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def Maybe_Reexec_Local_Venv():
|
|
32
|
+
if __name__ != "__main__" or not Should_Reexec_Local_Venv():
|
|
33
|
+
return
|
|
34
|
+
venv_python = Local_Venv_Python()
|
|
35
|
+
os.execv(venv_python, [venv_python, os.path.abspath(__file__), *sys.argv[1:]])
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
Maybe_Reexec_Local_Venv()
|
|
39
|
+
|
|
40
|
+
MISSING_IMPORT_ERRORS = {}
|
|
41
|
+
|
|
42
|
+
try:
|
|
43
|
+
from PIL import Image,ImageShow,ImageTk
|
|
44
|
+
except ImportError as exc:
|
|
45
|
+
MISSING_IMPORT_ERRORS["Pillow"] = exc
|
|
46
|
+
Image = ImageShow = ImageTk = None
|
|
47
|
+
|
|
48
|
+
try:
|
|
49
|
+
from inputimeout import TimeoutOccurred, inputimeout
|
|
50
|
+
except ImportError as exc:
|
|
51
|
+
MISSING_IMPORT_ERRORS["inputimeout"] = exc
|
|
52
|
+
TimeoutOccurred = TimeoutError
|
|
53
|
+
def inputimeout(prompt="", timeout=None):
|
|
54
|
+
return input(prompt)
|
|
55
|
+
|
|
56
|
+
try:
|
|
57
|
+
import numpy as np
|
|
58
|
+
except ImportError as exc:
|
|
59
|
+
MISSING_IMPORT_ERRORS["numpy"] = exc
|
|
60
|
+
np = None
|
|
61
|
+
|
|
62
|
+
try:
|
|
63
|
+
import tkinter
|
|
64
|
+
except ImportError as exc:
|
|
65
|
+
MISSING_IMPORT_ERRORS["tkinter"] = exc
|
|
66
|
+
tkinter = None
|
|
67
|
+
|
|
68
|
+
import random, time, zlib, io, inspect, types, collections, itertools, shutil, shlex, subprocess
|
|
69
|
+
|
|
70
|
+
try:
|
|
71
|
+
import cv2
|
|
72
|
+
except ImportError as exc:
|
|
73
|
+
MISSING_IMPORT_ERRORS["opencv-python"] = exc
|
|
74
|
+
cv2 = None
|
|
75
|
+
|
|
76
|
+
try:
|
|
77
|
+
import psutil
|
|
78
|
+
except ImportError as exc:
|
|
79
|
+
MISSING_IMPORT_ERRORS["psutil"] = exc
|
|
80
|
+
psutil = None
|
|
81
|
+
|
|
82
|
+
try:
|
|
83
|
+
import imagehash
|
|
84
|
+
except ImportError as exc:
|
|
85
|
+
MISSING_IMPORT_ERRORS["ImageHash"] = exc
|
|
86
|
+
imagehash = None
|
|
87
|
+
|
|
88
|
+
try:
|
|
89
|
+
import colorama
|
|
90
|
+
except ImportError as exc:
|
|
91
|
+
MISSING_IMPORT_ERRORS["colorama"] = exc
|
|
92
|
+
colorama = None
|
|
93
|
+
|
|
94
|
+
from chunklate import ancillary, ancillary_runtime, bruteforce, checkpoint, checkpoint_actions_runtime, checkpoint_runtime, chunk_info, chunk_name_runtime, chunk_order, chunk_order_runtime, chunk_report, chunk_scanner, chunk_state, chunk_state_runtime, chunk_story, chunk_validation_runtime, cli, decisions, dummy_chunk, dummy_chunk_runtime, error_log, fixit_felix, fixit_felix_runtime, full_chunk_forcer, getinfo_runtime, getspec_runtime, history, image_viewer, libpng_check, libpng_runtime, magic_runtime, main_runtime, name_shift, name_shift_runtime, nearby, nearby_runtime, output, package_update, palette, palette_runtime, palette_ui, platform_runtime, prompts, question_runtime, relics, relics_runtime, relics_ui, runtime_state, smash_bruteforce, sorting, spec_length_runtime, specs, stdio, ui, ui_runtime, ultimate_reference_ui, writer, writer_runtime, youshallpass_runtime
|
|
95
|
+
from chunklate.png import (
|
|
96
|
+
chunk_type_crc_matches,
|
|
97
|
+
detect_png_signature_recovery,
|
|
98
|
+
legacy_crc_checkpoint_args,
|
|
99
|
+
legacy_crc_decision,
|
|
100
|
+
legacy_crc_debug_lines,
|
|
101
|
+
legacy_crc_monkey_lines,
|
|
102
|
+
legacy_find_magic_checkpoint_args,
|
|
103
|
+
legacy_length_checkpoint_args,
|
|
104
|
+
legacy_length_decision,
|
|
105
|
+
validate_png_structure,
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
RUNTIME_IMPORTS = (
|
|
110
|
+
("Pillow", "PIL.Image/PIL.ImageTk", lambda: Image is not None and ImageShow is not None and ImageTk is not None),
|
|
111
|
+
("inputimeout", "inputimeout", lambda: "inputimeout" not in MISSING_IMPORT_ERRORS),
|
|
112
|
+
("numpy", "numpy", lambda: np is not None),
|
|
113
|
+
("opencv-python", "cv2", lambda: cv2 is not None),
|
|
114
|
+
("psutil", "psutil", lambda: psutil is not None),
|
|
115
|
+
("ImageHash", "imagehash", lambda: imagehash is not None),
|
|
116
|
+
("python3-tk", "tkinter", lambda: tkinter is not None),
|
|
117
|
+
("colorama", "colorama", lambda: colorama is not None),
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def Missing_Runtime_Dependencies():
|
|
122
|
+
missing = []
|
|
123
|
+
for package, import_name, is_available in RUNTIME_IMPORTS:
|
|
124
|
+
if not is_available():
|
|
125
|
+
missing.append((package, import_name, MISSING_IMPORT_ERRORS.get(package)))
|
|
126
|
+
return tuple(missing)
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def Format_Missing_Runtime_Dependencies(missing, *, os_name=None):
|
|
130
|
+
os_name = os.name if os_name is None else os_name
|
|
131
|
+
root = os.path.dirname(os.path.abspath(__file__))
|
|
132
|
+
bootstrap_command = Bootstrap_Command(os_name=os_name)
|
|
133
|
+
local_python = Local_Venv_Python(os_name=os_name) or platform_runtime.local_venv_python(root, os_name=os_name)
|
|
134
|
+
run_command = platform_runtime.format_command(
|
|
135
|
+
[local_python, os.path.abspath(__file__), "-f", "<file>"],
|
|
136
|
+
os_name=os_name,
|
|
137
|
+
)
|
|
138
|
+
lines = [
|
|
139
|
+
"Missing runtime dependencies; Chunklate cannot safely continue.",
|
|
140
|
+
"",
|
|
141
|
+
"Missing imports:",
|
|
142
|
+
]
|
|
143
|
+
for package, import_name, error in missing:
|
|
144
|
+
lines.append("- %s (import %s)" % (package, import_name))
|
|
145
|
+
if error is not None:
|
|
146
|
+
lines.append(" error: %s" % error)
|
|
147
|
+
lines.extend(
|
|
148
|
+
[
|
|
149
|
+
"",
|
|
150
|
+
"Install/refresh the local virtual environment with:",
|
|
151
|
+
" %s" % platform_runtime.format_command(bootstrap_command, os_name=os_name),
|
|
152
|
+
"",
|
|
153
|
+
"Then run Chunklate with:",
|
|
154
|
+
" %s" % run_command,
|
|
155
|
+
]
|
|
156
|
+
)
|
|
157
|
+
if any(package == "python3-tk" for package, _, _ in missing) and os_name != "nt":
|
|
158
|
+
lines.extend(
|
|
159
|
+
[
|
|
160
|
+
"",
|
|
161
|
+
"Tkinter is a system Python module on many Linux distributions.",
|
|
162
|
+
"On Debian/Ubuntu install it with: sudo apt install python3-tk",
|
|
163
|
+
]
|
|
164
|
+
)
|
|
165
|
+
elif any(package == "python3-tk" for package, _, _ in missing):
|
|
166
|
+
lines.extend(
|
|
167
|
+
[
|
|
168
|
+
"",
|
|
169
|
+
"Tkinter is normally installed by the official Python for Windows installer.",
|
|
170
|
+
"Repair or reinstall Python with the Tcl/Tk option enabled if tkinter is missing.",
|
|
171
|
+
]
|
|
172
|
+
)
|
|
173
|
+
return "\n".join(lines)
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
def Bootstrap_Script_Path(script_path=None, *, os_name=None):
|
|
177
|
+
root = os.path.dirname(os.path.abspath(script_path or __file__))
|
|
178
|
+
return platform_runtime.bootstrap_python_script(
|
|
179
|
+
root,
|
|
180
|
+
os_name=os.name if os_name is None else os_name,
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
def Bootstrap_Command(script_path=None, *, os_name=None):
|
|
185
|
+
root = os.path.dirname(os.path.abspath(script_path or __file__))
|
|
186
|
+
return platform_runtime.bootstrap_command(
|
|
187
|
+
root,
|
|
188
|
+
executable=sys.executable,
|
|
189
|
+
os_name=os.name if os_name is None else os_name,
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
def Can_Prompt_Dependency_Install(stdin=None):
|
|
194
|
+
stream = stdin or sys.stdin
|
|
195
|
+
return (
|
|
196
|
+
not NODIALOGUE
|
|
197
|
+
and not AUTO
|
|
198
|
+
and hasattr(stream, "isatty")
|
|
199
|
+
and stream.isatty()
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
def Prompt_Dependency_Install(missing, *, input_func=input, stdin=None, runner=subprocess.run):
|
|
204
|
+
print(Format_Missing_Runtime_Dependencies(missing), file=sys.stderr)
|
|
205
|
+
if not Can_Prompt_Dependency_Install(stdin):
|
|
206
|
+
return False
|
|
207
|
+
|
|
208
|
+
answer = input_func("Install/refresh missing dependencies now? (yes/no): ").strip().lower()
|
|
209
|
+
if answer not in ("y", "yes"):
|
|
210
|
+
return False
|
|
211
|
+
|
|
212
|
+
command = Bootstrap_Command()
|
|
213
|
+
print("Running: %s" % platform_runtime.format_command(command), file=sys.stderr)
|
|
214
|
+
result = runner(command, cwd=os.path.dirname(os.path.abspath(__file__)))
|
|
215
|
+
return getattr(result, "returncode", 0) == 0
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
def Reexec_Local_Venv_Or_Exit():
|
|
219
|
+
venv_python = Local_Venv_Python()
|
|
220
|
+
if not venv_python:
|
|
221
|
+
print("Dependency install finished, but .venv Python was not found.", file=sys.stderr)
|
|
222
|
+
sys.exit(1)
|
|
223
|
+
os.execv(venv_python, [venv_python, os.path.abspath(__file__), *sys.argv[1:]])
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
def Configure_Terminal_Color():
|
|
227
|
+
global USE_COLOR
|
|
228
|
+
platform_runtime.configure_text_stream_errors(sys.stdout, sys.stderr)
|
|
229
|
+
decision = platform_runtime.decide_terminal_color(
|
|
230
|
+
COLOR_MODE,
|
|
231
|
+
stream=sys.stdout,
|
|
232
|
+
os_name=os.name,
|
|
233
|
+
platform=sys.platform,
|
|
234
|
+
colorama_module=colorama,
|
|
235
|
+
)
|
|
236
|
+
USE_COLOR = decision.use_color
|
|
237
|
+
return decision
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
def Ensure_Runtime_Dependencies(*, prompt_installer=Prompt_Dependency_Install, reexec=Reexec_Local_Venv_Or_Exit):
|
|
241
|
+
missing = Missing_Runtime_Dependencies()
|
|
242
|
+
if missing:
|
|
243
|
+
if prompt_installer(missing):
|
|
244
|
+
reexec()
|
|
245
|
+
return True
|
|
246
|
+
sys.exit(1)
|
|
247
|
+
return True
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
def Check_Package_Update(*, current_version=None, fetch_latest=package_update.latest_pypi_version):
|
|
251
|
+
return package_update.check_package_update(
|
|
252
|
+
current_version=current_version,
|
|
253
|
+
fetch_latest=fetch_latest,
|
|
254
|
+
)
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
def Format_Package_Update_Message(status):
|
|
258
|
+
return package_update.format_update_message(status, python_executable=sys.executable)
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
def Should_Run_Package_Update_Check(args, *, argv0=None):
|
|
262
|
+
if bool(getattr(args, "NO_UPDATE_CHECK", False)):
|
|
263
|
+
return False
|
|
264
|
+
return True
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
def Can_Prompt_Package_Update(stdin=None):
|
|
268
|
+
stream = stdin or sys.stdin
|
|
269
|
+
return (
|
|
270
|
+
not NODIALOGUE
|
|
271
|
+
and not AUTO
|
|
272
|
+
and hasattr(stream, "isatty")
|
|
273
|
+
and stream.isatty()
|
|
274
|
+
)
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
def Prompt_Package_Update_Continue(status, *, input_func=input, stdin=None, stream=None):
|
|
278
|
+
if not status.update_available:
|
|
279
|
+
return True
|
|
280
|
+
out = stream or sys.stderr
|
|
281
|
+
print(Format_Package_Update_Message(status), file=out)
|
|
282
|
+
if not Can_Prompt_Package_Update(stdin):
|
|
283
|
+
print("Continuing with the installed version.", file=out)
|
|
284
|
+
return True
|
|
285
|
+
while True:
|
|
286
|
+
answer = input_func("Continue with this older Chunklate anyway? (yes/no): ").strip().lower()
|
|
287
|
+
if answer in ("y", "yes"):
|
|
288
|
+
return True
|
|
289
|
+
if answer in ("n", "no"):
|
|
290
|
+
return False
|
|
291
|
+
print("I need yes or no before continuing with an older package.", file=out)
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
def Ensure_Package_Current_Or_Continue(
|
|
295
|
+
*,
|
|
296
|
+
checker=Check_Package_Update,
|
|
297
|
+
prompt_continue=Prompt_Package_Update_Continue,
|
|
298
|
+
exit_process=sys.exit,
|
|
299
|
+
):
|
|
300
|
+
status = checker()
|
|
301
|
+
if status.up_to_date is None:
|
|
302
|
+
return True
|
|
303
|
+
if prompt_continue(status):
|
|
304
|
+
return True
|
|
305
|
+
exit_process(1)
|
|
306
|
+
return False
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
def Betterror(error_msg, def_name): ##useless since 3.11
|
|
310
|
+
return error_log.betterror_from_namespace(globals(), error_msg, def_name)
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
def Error_Log(Err_to_log):
|
|
314
|
+
return error_log.append_error_log_from_namespace(globals(), Err_to_log)
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
# Relics state model:
|
|
318
|
+
# - PandoraBox holds current-file findings that still need a decision or repair.
|
|
319
|
+
# Keys look like "Function_Error_N:message"; values are "<Chunk>_Tool_N" dicts.
|
|
320
|
+
# - Cornucopia holds fixes already accepted by CheckPoint/FixItFelix.
|
|
321
|
+
# - WriteClone snapshots those two stores into Pandemonium/ArkOfCovenant so
|
|
322
|
+
# Relics can react to the repair history when libpng reports a later failure.
|
|
323
|
+
def CheckPoint_Record_Finding(registration):
|
|
324
|
+
if registration.side_note is not None:
|
|
325
|
+
SideNotes.append(registration.side_note)
|
|
326
|
+
return relics.record_checkpoint_registration(PandoraBox, Cornucopia, registration)
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
def CheckPoint_Apply_Flags(flags):
|
|
330
|
+
if not flags:
|
|
331
|
+
return
|
|
332
|
+
globals().update(flags)
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
def CheckPoint_Print_Libpng_Critical(info):
|
|
336
|
+
PRINT("\n-\033[1;31;49mCriticalHit\033[m: %s" % info)
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
def CheckPoint_Discard_Libpng_Warning():
|
|
340
|
+
for nb, key in enumerate(PandoraBox):
|
|
341
|
+
if "libpng warning:" in str(key):
|
|
342
|
+
relics.discard_pandora_error(PandoraBox, key)
|
|
343
|
+
SideNotes.append("-Found False-Positive :[Error:-%s]." % (str(key)))
|
|
344
|
+
break
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
def CheckPoint_Libpng_End_Success(message):
|
|
348
|
+
saved_path = Current_Display_Image_Path()
|
|
349
|
+
visual_reference_note = Final_Image_Visual_Reference_Note(saved_path)
|
|
350
|
+
if visual_reference_note:
|
|
351
|
+
Candy(
|
|
352
|
+
"Cowsay",
|
|
353
|
+
visual_reference_note,
|
|
354
|
+
"com",
|
|
355
|
+
)
|
|
356
|
+
SideNotes.append("-Visual reference route: %s" % visual_reference_note)
|
|
357
|
+
PRINT("-Visual reference route: %s" % visual_reference_note)
|
|
358
|
+
TheEnd()
|
|
359
|
+
return
|
|
360
|
+
|
|
361
|
+
Candy(
|
|
362
|
+
"Cowsay",
|
|
363
|
+
message,
|
|
364
|
+
"good",
|
|
365
|
+
)
|
|
366
|
+
Candy("Cowsay", "Your file is here: %s" % saved_path, "good")
|
|
367
|
+
PRINT(Candy("Color", "green", "-Saved in : %s") % saved_path)
|
|
368
|
+
Open_Final_Image_Once(saved_path)
|
|
369
|
+
TheEnd()
|
|
370
|
+
|
|
371
|
+
|
|
372
|
+
def _Valid_Png_Path(path):
|
|
373
|
+
if not path or not os.path.exists(path):
|
|
374
|
+
return False
|
|
375
|
+
try:
|
|
376
|
+
with open(path, "rb") as file:
|
|
377
|
+
return validate_png_structure(output.clone_bytes(file.read())).ok
|
|
378
|
+
except (OSError, ValueError):
|
|
379
|
+
return False
|
|
380
|
+
|
|
381
|
+
|
|
382
|
+
def Current_Display_Image_Path():
|
|
383
|
+
sample_dir = output.clone_folder(FILE_Origin, FILE_DIR)
|
|
384
|
+
clone_path = os.path.join(sample_dir, Sample_Name) if Sample_Name else ""
|
|
385
|
+
if SAVE_COUNT > 0:
|
|
386
|
+
candidates = (clone_path, Sample, FILE_Origin)
|
|
387
|
+
else:
|
|
388
|
+
candidates = (Sample, FILE_Origin)
|
|
389
|
+
for path in candidates:
|
|
390
|
+
if _Valid_Png_Path(path):
|
|
391
|
+
return path
|
|
392
|
+
for path in candidates:
|
|
393
|
+
if path:
|
|
394
|
+
return path
|
|
395
|
+
return ""
|
|
396
|
+
|
|
397
|
+
|
|
398
|
+
def _Load_Rgba_Image(path):
|
|
399
|
+
if Image is None or not path:
|
|
400
|
+
return None
|
|
401
|
+
try:
|
|
402
|
+
with Image.open(path) as image:
|
|
403
|
+
return image.convert("RGBA")
|
|
404
|
+
except Exception:
|
|
405
|
+
return None
|
|
406
|
+
|
|
407
|
+
|
|
408
|
+
def Final_Image_Visual_Reference_Note(path):
|
|
409
|
+
reference_path = Ultimate_Linefeed_Reference()
|
|
410
|
+
if not reference_path:
|
|
411
|
+
return ""
|
|
412
|
+
if not _Valid_Png_Path(path):
|
|
413
|
+
return ""
|
|
414
|
+
if not os.path.exists(reference_path):
|
|
415
|
+
return "PNG is structurally valid; visual repair needs a reference/ROI, but the configured reference is missing: %s." % reference_path
|
|
416
|
+
|
|
417
|
+
candidate = _Load_Rgba_Image(path)
|
|
418
|
+
reference = _Load_Rgba_Image(reference_path)
|
|
419
|
+
if candidate is None or reference is None:
|
|
420
|
+
return "PNG is structurally valid; visual repair needs a reference/ROI, but I could not decode the configured reference."
|
|
421
|
+
if candidate.size != reference.size:
|
|
422
|
+
return "PNG is structurally valid; visual mismatch detected against the reference size %s vs %s; repair needs reference/ROI." % (
|
|
423
|
+
candidate.size,
|
|
424
|
+
reference.size,
|
|
425
|
+
)
|
|
426
|
+
if candidate.tobytes() != reference.tobytes():
|
|
427
|
+
return "PNG is structurally valid; visual mismatch detected against the reference; repair needs reference/ROI."
|
|
428
|
+
return ""
|
|
429
|
+
|
|
430
|
+
|
|
431
|
+
def Open_Final_Image_Once(path):
|
|
432
|
+
global FINAL_IMAGE_OPEN_REQUESTED
|
|
433
|
+
|
|
434
|
+
if FINAL_IMAGE_OPEN_REQUESTED:
|
|
435
|
+
return None
|
|
436
|
+
if Has_Unresolved_Findings():
|
|
437
|
+
return None
|
|
438
|
+
if not _Valid_Png_Path(path):
|
|
439
|
+
return None
|
|
440
|
+
if SAVE_COUNT == 0 and path in (Sample, FILE_Origin):
|
|
441
|
+
Candy(
|
|
442
|
+
"Cowsay",
|
|
443
|
+
"Wtf... why did you give that to me? It's perfect!",
|
|
444
|
+
"good",
|
|
445
|
+
)
|
|
446
|
+
FINAL_IMAGE_OPEN_REQUESTED = True
|
|
447
|
+
return Open_Final_Image(path)
|
|
448
|
+
|
|
449
|
+
|
|
450
|
+
def Open_Current_Final_Image_If_Valid():
|
|
451
|
+
return Open_Final_Image_Once(Current_Display_Image_Path())
|
|
452
|
+
|
|
453
|
+
|
|
454
|
+
def Has_Unresolved_Findings():
|
|
455
|
+
return bool(PandoraBox)
|
|
456
|
+
|
|
457
|
+
|
|
458
|
+
def Open_Final_Image(path, emit=None):
|
|
459
|
+
emit = PRINT if emit is None else emit
|
|
460
|
+
if not sys.stdout.isatty():
|
|
461
|
+
return None
|
|
462
|
+
try:
|
|
463
|
+
with open(path, "rb") as file:
|
|
464
|
+
validation = validate_png_structure(output.clone_bytes(file.read()))
|
|
465
|
+
except (OSError, ValueError):
|
|
466
|
+
validation = None
|
|
467
|
+
if validation is None or not validation.ok:
|
|
468
|
+
emit(Candy("Color", "yellow", "-Not opening image automatically: PNG structure is not valid."))
|
|
469
|
+
return None
|
|
470
|
+
|
|
471
|
+
result = image_viewer.open_image(path)
|
|
472
|
+
if result.success:
|
|
473
|
+
emit(Candy("Color", "green", "-Opening image with : %s") % result.opener)
|
|
474
|
+
else:
|
|
475
|
+
emit(Candy("Color", "yellow", "-Could not open image automatically: %s") % result.error)
|
|
476
|
+
return result
|
|
477
|
+
|
|
478
|
+
|
|
479
|
+
ACTIVE_PREVIEW_IMAGE = None
|
|
480
|
+
LAST_PROGRESS_LINE = ""
|
|
481
|
+
PREVIEW_OUTPUT_FOLDER = "Bruteforce_Previews"
|
|
482
|
+
|
|
483
|
+
|
|
484
|
+
def Close_Preview_Image():
|
|
485
|
+
global ACTIVE_PREVIEW_IMAGE
|
|
486
|
+
|
|
487
|
+
preview = ACTIVE_PREVIEW_IMAGE
|
|
488
|
+
ACTIVE_PREVIEW_IMAGE = None
|
|
489
|
+
if preview is None:
|
|
490
|
+
return False
|
|
491
|
+
close = getattr(preview, "close", None)
|
|
492
|
+
if close is None:
|
|
493
|
+
return False
|
|
494
|
+
try:
|
|
495
|
+
return bool(close())
|
|
496
|
+
except Exception:
|
|
497
|
+
return False
|
|
498
|
+
|
|
499
|
+
|
|
500
|
+
def Preview_Repair_Image(data, label, *, show=True, emit=None, announce=True):
|
|
501
|
+
global ACTIVE_PREVIEW_IMAGE
|
|
502
|
+
|
|
503
|
+
emit = PRINT if emit is None else emit
|
|
504
|
+
Close_Preview_Image()
|
|
505
|
+
preview_bytes = output.clone_bytes(data)
|
|
506
|
+
validation = validate_png_structure(preview_bytes)
|
|
507
|
+
if not validation.ok:
|
|
508
|
+
emit(Candy("Color", "yellow", "-Preview skipped: PNG structure is not valid."))
|
|
509
|
+
return None
|
|
510
|
+
|
|
511
|
+
folder = output.ensure_clone_folder(FILE_Origin, FILE_DIR)
|
|
512
|
+
safe_label = "".join(
|
|
513
|
+
char if char.isalnum() or char in ("-", "_", ".") else "_"
|
|
514
|
+
for char in str(label)
|
|
515
|
+
)
|
|
516
|
+
preview_folder = os.path.join(folder, PREVIEW_OUTPUT_FOLDER)
|
|
517
|
+
os.makedirs(preview_folder, exist_ok=True)
|
|
518
|
+
path = os.path.join(preview_folder, "_Preview_%s.png" % safe_label)
|
|
519
|
+
with open(path, "wb") as file:
|
|
520
|
+
file.write(preview_bytes)
|
|
521
|
+
|
|
522
|
+
if announce:
|
|
523
|
+
emit(Candy("Color", "green", "-Preview image : %s") % path)
|
|
524
|
+
if not show:
|
|
525
|
+
return types.SimpleNamespace(success=False, path=path, opened=False)
|
|
526
|
+
ACTIVE_PREVIEW_IMAGE = Open_Final_Image(path, emit=emit)
|
|
527
|
+
if ACTIVE_PREVIEW_IMAGE is None:
|
|
528
|
+
return types.SimpleNamespace(success=False, path=path, opened=False)
|
|
529
|
+
return ACTIVE_PREVIEW_IMAGE
|
|
530
|
+
|
|
531
|
+
|
|
532
|
+
def Ultimate_Linefeed_Checkpoint_Path():
|
|
533
|
+
return globals().get("ULTIMATE_LINEFEED_CHECKPOINT_PATH") or os.path.join(
|
|
534
|
+
output.ensure_clone_folder(FILE_Origin, FILE_DIR),
|
|
535
|
+
"_ULF.checkpoint.jsonl",
|
|
536
|
+
)
|
|
537
|
+
|
|
538
|
+
|
|
539
|
+
def Ultimate_Linefeed_Progress_Path():
|
|
540
|
+
return globals().get("ULTIMATE_LINEFEED_PROGRESS_PATH") or os.path.join(
|
|
541
|
+
output.ensure_clone_folder(FILE_Origin, FILE_DIR),
|
|
542
|
+
"_ULF.progress.json",
|
|
543
|
+
)
|
|
544
|
+
|
|
545
|
+
|
|
546
|
+
def Ultimate_Linefeed_Source_Path():
|
|
547
|
+
return globals().get("ULTIMATE_LINEFEED_SOURCE_PATH") or os.path.join(
|
|
548
|
+
output.ensure_clone_folder(FILE_Origin, FILE_DIR),
|
|
549
|
+
"_ULF.Source.png",
|
|
550
|
+
)
|
|
551
|
+
|
|
552
|
+
|
|
553
|
+
def _Ultimate_Linefeed_Budget_Decision(mode, estimate, manual_budget=None):
|
|
554
|
+
total = int(getattr(estimate, "total_combinations", 0) or 0)
|
|
555
|
+
return magic_runtime.idat_bruteforce.ultimate_linefeed_budget_decision(
|
|
556
|
+
total,
|
|
557
|
+
mode,
|
|
558
|
+
manual_budget=manual_budget,
|
|
559
|
+
)
|
|
560
|
+
|
|
561
|
+
|
|
562
|
+
def _Ultimate_Linefeed_Print_Budget_Menu(estimate):
|
|
563
|
+
total = int(getattr(estimate, "total_combinations", 0) or 0)
|
|
564
|
+
operations = int(getattr(estimate, "operation_count", 0) or 0)
|
|
565
|
+
depth = int(getattr(estimate, "max_depth", 0) or 0)
|
|
566
|
+
lines = [
|
|
567
|
+
"Ultimate budget no jutsu:",
|
|
568
|
+
"operations: %s" % format(operations, ","),
|
|
569
|
+
"max depth: %s" % depth,
|
|
570
|
+
"possible combinations: %s" % format(total, ","),
|
|
571
|
+
*magic_runtime.idat_bruteforce.ultimate_linefeed_universe_atom_comparison_lines(total),
|
|
572
|
+
"",
|
|
573
|
+
"Enter a number from 1 to 10.",
|
|
574
|
+
"",
|
|
575
|
+
"1. quick total / 100000",
|
|
576
|
+
"2. normal total / 50000",
|
|
577
|
+
"3. deep total / 10000",
|
|
578
|
+
"4. very deep total / 1000",
|
|
579
|
+
"5. deeeeeeep total / 100",
|
|
580
|
+
"6. abyssal total / 10",
|
|
581
|
+
"7. inception total / 2",
|
|
582
|
+
"8. no limit",
|
|
583
|
+
"9. manual exact candidate budget",
|
|
584
|
+
"10. quit like a looser.",
|
|
585
|
+
]
|
|
586
|
+
Prompt_Candy("Cowsay", "\n".join(lines), "com")
|
|
587
|
+
|
|
588
|
+
|
|
589
|
+
def _Ultimate_Linefeed_Manual_Budget():
|
|
590
|
+
while True:
|
|
591
|
+
try:
|
|
592
|
+
value = input("Exact candidate budget > ").strip()
|
|
593
|
+
except EOFError:
|
|
594
|
+
return None
|
|
595
|
+
try:
|
|
596
|
+
budget = int(value)
|
|
597
|
+
except ValueError:
|
|
598
|
+
PRINT(Candy("Color", "red", "-Budget must be a positive integer."))
|
|
599
|
+
continue
|
|
600
|
+
if budget > 0:
|
|
601
|
+
return budget
|
|
602
|
+
PRINT(Candy("Color", "red", "-Budget must be greater than zero."))
|
|
603
|
+
|
|
604
|
+
|
|
605
|
+
def Ultimate_Linefeed_Budget(estimate=None):
|
|
606
|
+
if globals().get("ULTIMATE_LINEFEED_UNBOUNDED", False):
|
|
607
|
+
return _Ultimate_Linefeed_Budget_Decision("unbounded", estimate)
|
|
608
|
+
budget = globals().get("ULTIMATE_LINEFEED_BUDGET", None)
|
|
609
|
+
if budget is None:
|
|
610
|
+
if globals().get("AUTO", False) or globals().get("NODIALOGUE", False):
|
|
611
|
+
return _Ultimate_Linefeed_Budget_Decision("normal", estimate)
|
|
612
|
+
choices = {
|
|
613
|
+
"1": "quick",
|
|
614
|
+
"2": "normal",
|
|
615
|
+
"": "normal",
|
|
616
|
+
"3": "deep",
|
|
617
|
+
"4": "very_deep",
|
|
618
|
+
"5": "deeeeeeep",
|
|
619
|
+
"6": "abyssal",
|
|
620
|
+
"7": "inception",
|
|
621
|
+
"8": "unbounded",
|
|
622
|
+
"9": "manual",
|
|
623
|
+
"10": "abort",
|
|
624
|
+
}
|
|
625
|
+
while True:
|
|
626
|
+
_Ultimate_Linefeed_Print_Budget_Menu(estimate)
|
|
627
|
+
try:
|
|
628
|
+
choice = input("Ultimate budget choice number [2 normal] > ").strip().lower()
|
|
629
|
+
except EOFError:
|
|
630
|
+
choice = ""
|
|
631
|
+
mode = choices.get(choice)
|
|
632
|
+
if mode is None:
|
|
633
|
+
PRINT(Candy("Color", "red", "-Enter a number from 1 to 10."))
|
|
634
|
+
continue
|
|
635
|
+
if mode == "manual":
|
|
636
|
+
manual_budget = _Ultimate_Linefeed_Manual_Budget()
|
|
637
|
+
if manual_budget is None:
|
|
638
|
+
return _Ultimate_Linefeed_Budget_Decision("normal", estimate)
|
|
639
|
+
return _Ultimate_Linefeed_Budget_Decision(
|
|
640
|
+
"manual",
|
|
641
|
+
estimate,
|
|
642
|
+
manual_budget=manual_budget,
|
|
643
|
+
)
|
|
644
|
+
return _Ultimate_Linefeed_Budget_Decision(mode, estimate)
|
|
645
|
+
return magic_runtime.idat_bruteforce.UltimateLinefeedBudgetDecision(
|
|
646
|
+
"override",
|
|
647
|
+
int(budget),
|
|
648
|
+
coverage=magic_runtime.idat_bruteforce.ultimate_linefeed_budget_coverage(
|
|
649
|
+
int(getattr(estimate, "total_combinations", 0) or 0),
|
|
650
|
+
int(budget),
|
|
651
|
+
),
|
|
652
|
+
)
|
|
653
|
+
|
|
654
|
+
|
|
655
|
+
def _Ultimate_Linefeed_Recommended_Workers():
|
|
656
|
+
return platform_runtime.recommended_worker_count(profile="normal")
|
|
657
|
+
|
|
658
|
+
|
|
659
|
+
def _Ultimate_Linefeed_Worker_Profile_Counts():
|
|
660
|
+
cpu_count = platform_runtime.detected_cpu_count()
|
|
661
|
+
return {
|
|
662
|
+
"cpu": cpu_count,
|
|
663
|
+
"min": platform_runtime.recommended_worker_count(cpu_count, profile="min"),
|
|
664
|
+
"normal": platform_runtime.recommended_worker_count(cpu_count, profile="normal"),
|
|
665
|
+
"max": platform_runtime.recommended_worker_count(cpu_count, profile="max"),
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
|
|
669
|
+
def _Ultimate_Linefeed_Workers_From_Value(value):
|
|
670
|
+
if value is None:
|
|
671
|
+
return None
|
|
672
|
+
text = str(value).strip().lower()
|
|
673
|
+
if text in ("auto", "normal"):
|
|
674
|
+
return platform_runtime.recommended_worker_count(profile="normal")
|
|
675
|
+
if text in ("min", "max"):
|
|
676
|
+
return platform_runtime.recommended_worker_count(profile=text)
|
|
677
|
+
return max(0, int(text))
|
|
678
|
+
|
|
679
|
+
|
|
680
|
+
def _Ultimate_Linefeed_Print_Worker_Menu():
|
|
681
|
+
counts = _Ultimate_Linefeed_Worker_Profile_Counts()
|
|
682
|
+
lines = [
|
|
683
|
+
"Ultimate CPU worker no jutsu:",
|
|
684
|
+
"CPU detected: %s" % counts["cpu"],
|
|
685
|
+
"min workers: %s" % counts["min"],
|
|
686
|
+
"normal workers: %s" % counts["normal"],
|
|
687
|
+
"max workers: %s" % counts["max"],
|
|
688
|
+
"",
|
|
689
|
+
"Choose how many Cpu workers to use (0,min, normal, max, or enter an exact number).",
|
|
690
|
+
"",
|
|
691
|
+
"0. disabled",
|
|
692
|
+
"min. CPU / 4",
|
|
693
|
+
"normal. CPU / 2",
|
|
694
|
+
"max. CPU - 1",
|
|
695
|
+
"custom. enter an exact worker count",
|
|
696
|
+
"",
|
|
697
|
+
"Empty keeps Ultimate single-process.",
|
|
698
|
+
]
|
|
699
|
+
Prompt_Candy("Cowsay", "\n".join(lines), "com")
|
|
700
|
+
|
|
701
|
+
|
|
702
|
+
def Ultimate_Linefeed_Workers():
|
|
703
|
+
configured = globals().get("ULTIMATE_LINEFEED_WORKERS", None)
|
|
704
|
+
if configured is not None:
|
|
705
|
+
return _Ultimate_Linefeed_Workers_From_Value(configured)
|
|
706
|
+
if globals().get("AUTO", False) or globals().get("NODIALOGUE", False):
|
|
707
|
+
return 0
|
|
708
|
+
|
|
709
|
+
while True:
|
|
710
|
+
_Ultimate_Linefeed_Print_Worker_Menu()
|
|
711
|
+
try:
|
|
712
|
+
choice = input("Ultimate worker profile [0 disabled] > ").strip().lower()
|
|
713
|
+
except EOFError:
|
|
714
|
+
choice = ""
|
|
715
|
+
if choice == "":
|
|
716
|
+
return 0
|
|
717
|
+
if choice in ("min", "normal", "max", "auto"):
|
|
718
|
+
return _Ultimate_Linefeed_Workers_From_Value(choice)
|
|
719
|
+
if choice == "custom":
|
|
720
|
+
try:
|
|
721
|
+
choice = input("Custom Ultimate worker count > ").strip().lower()
|
|
722
|
+
except EOFError:
|
|
723
|
+
choice = ""
|
|
724
|
+
try:
|
|
725
|
+
workers = int(choice)
|
|
726
|
+
except ValueError:
|
|
727
|
+
PRINT(Candy("Color", "red", "-Enter 0, min, normal, max, custom, or a worker count."))
|
|
728
|
+
continue
|
|
729
|
+
if workers >= 0:
|
|
730
|
+
return workers
|
|
731
|
+
PRINT(Candy("Color", "red", "-Worker count must be zero or higher."))
|
|
732
|
+
|
|
733
|
+
|
|
734
|
+
def Ultimate_Linefeed_Reference():
|
|
735
|
+
return str(globals().get("ULTIMATE_LINEFEED_REFERENCE", "") or "")
|
|
736
|
+
|
|
737
|
+
|
|
738
|
+
def Ultimate_Linefeed_Reference_Mode():
|
|
739
|
+
mode = str(globals().get("ULTIMATE_LINEFEED_REFERENCE_MODE", "exact") or "exact").strip().lower()
|
|
740
|
+
return mode if mode in ("exact", "similar") else "exact"
|
|
741
|
+
|
|
742
|
+
|
|
743
|
+
def Ultimate_Linefeed_Reference_Regions():
|
|
744
|
+
return str(globals().get("ULTIMATE_LINEFEED_REFERENCE_REGIONS", "") or "")
|
|
745
|
+
|
|
746
|
+
|
|
747
|
+
def Ultimate_Linefeed_Reference_Region_Editor():
|
|
748
|
+
return bool(globals().get("ULTIMATE_LINEFEED_REFERENCE_REGION_EDITOR", False))
|
|
749
|
+
|
|
750
|
+
|
|
751
|
+
def Ultimate_Linefeed_Reference_Region_Editor_Run(source_path, reference_path, regions_path, source_data=b""):
|
|
752
|
+
return ultimate_reference_ui.open_ultimate_reference_region_editor(
|
|
753
|
+
source_path,
|
|
754
|
+
reference_path,
|
|
755
|
+
regions_path,
|
|
756
|
+
candidate_data=source_data,
|
|
757
|
+
)
|
|
758
|
+
|
|
759
|
+
|
|
760
|
+
def Ultimate_Linefeed_Visual_Gallery_Limit():
|
|
761
|
+
return int(globals().get("ULTIMATE_LINEFEED_VISUAL_GALLERY_LIMIT", 100) or 0)
|
|
762
|
+
|
|
763
|
+
|
|
764
|
+
def Ultimate_Linefeed_Visual_Min_Coverage():
|
|
765
|
+
return float(globals().get("ULTIMATE_LINEFEED_VISUAL_MIN_COVERAGE", 0.95) or 0.0)
|
|
766
|
+
|
|
767
|
+
|
|
768
|
+
def Ultimate_Linefeed_Live_Preview_Folder():
|
|
769
|
+
return os.path.join(output.ensure_clone_folder(FILE_Origin, FILE_DIR), PREVIEW_OUTPUT_FOLDER)
|
|
770
|
+
|
|
771
|
+
|
|
772
|
+
def Announce_Ultimate_Linefeed_Live_Preview_Folder(preview_folder):
|
|
773
|
+
global ULTIMATE_LINEFEED_LIVE_PREVIEW_FOLDER_REPORTED
|
|
774
|
+
if ULTIMATE_LINEFEED_LIVE_PREVIEW_FOLDER_REPORTED == preview_folder:
|
|
775
|
+
return
|
|
776
|
+
ULTIMATE_LINEFEED_LIVE_PREVIEW_FOLDER_REPORTED = preview_folder
|
|
777
|
+
PRINT_With_Loader_Redraw(Candy("Color", "green", "-Preview folder : %s") % preview_folder)
|
|
778
|
+
|
|
779
|
+
|
|
780
|
+
def Ultimate_Linefeed_Candidate_Preview(candidate, tested, budget):
|
|
781
|
+
timeout = float(globals().get("ULTIMATE_LINEFEED_PREVIEW_TIMEOUT", 5.0) or 0.0)
|
|
782
|
+
show_preview = bool(globals().get("ULTIMATE_LINEFEED_SHOW_PREVIEWS", False))
|
|
783
|
+
Announce_Ultimate_Linefeed_Live_Preview_Folder(Ultimate_Linefeed_Live_Preview_Folder())
|
|
784
|
+
|
|
785
|
+
after = getattr(candidate, "after", None)
|
|
786
|
+
scanlines = getattr(after, "usable_scanlines", "unknown")
|
|
787
|
+
height = getattr(after, "height", "unknown")
|
|
788
|
+
adler_status = getattr(after, "adler_status", "adler_unknown")
|
|
789
|
+
label = "UltimateLive_%09d_%s_of_%s_%s" % (
|
|
790
|
+
int(tested),
|
|
791
|
+
scanlines,
|
|
792
|
+
height,
|
|
793
|
+
adler_status,
|
|
794
|
+
)
|
|
795
|
+
preview = Preview_Repair_Image(
|
|
796
|
+
candidate.data,
|
|
797
|
+
label,
|
|
798
|
+
show=show_preview,
|
|
799
|
+
emit=lambda _message: None,
|
|
800
|
+
announce=False,
|
|
801
|
+
)
|
|
802
|
+
if preview is None:
|
|
803
|
+
return None
|
|
804
|
+
if not show_preview:
|
|
805
|
+
return preview
|
|
806
|
+
if not getattr(preview, "success", False):
|
|
807
|
+
Close_Preview_Image()
|
|
808
|
+
return preview
|
|
809
|
+
try:
|
|
810
|
+
if timeout > 0:
|
|
811
|
+
time.sleep(timeout)
|
|
812
|
+
finally:
|
|
813
|
+
Close_Preview_Image()
|
|
814
|
+
return preview
|
|
815
|
+
|
|
816
|
+
|
|
817
|
+
def CheckPoint_Runtime():
|
|
818
|
+
return checkpoint_runtime.build_checkpoint_runtime_from_namespace(globals())
|
|
819
|
+
|
|
820
|
+
|
|
821
|
+
def CheckPoint_Set_Brute_LvL(value):
|
|
822
|
+
global Brute_LvL
|
|
823
|
+
|
|
824
|
+
Brute_LvL = value
|
|
825
|
+
|
|
826
|
+
|
|
827
|
+
def CheckPoint_Action_Runtime():
|
|
828
|
+
return checkpoint_actions_runtime.build_checkpoint_action_runtime_from_namespace(globals())
|
|
829
|
+
|
|
830
|
+
def CheckPoint_Apply_Action_Decision(decision, chunk, info, toolkit):
|
|
831
|
+
return checkpoint_actions_runtime.apply_action_decision(
|
|
832
|
+
CheckPoint_Action_Runtime(),
|
|
833
|
+
decision,
|
|
834
|
+
chunk,
|
|
835
|
+
info,
|
|
836
|
+
toolkit,
|
|
837
|
+
)
|
|
838
|
+
|
|
839
|
+
|
|
840
|
+
def Pandemonium_Remember_Current_Sample():
|
|
841
|
+
relics.remember_sample(Pandemonium, ArkOfCovenant, Sample, PandoraBox, Cornucopia)
|
|
842
|
+
|
|
843
|
+
|
|
844
|
+
def IDAT_Bytes_Nbr(): # tmpworkaround
|
|
845
|
+
global IBN
|
|
846
|
+
IBN = specs.estimate_idat_bytes_from_hex(DATAX, tuple(CHUNKS))
|
|
847
|
+
return IBN
|
|
848
|
+
|
|
849
|
+
|
|
850
|
+
|
|
851
|
+
def Max_Res():
|
|
852
|
+
try:
|
|
853
|
+
MaxRes, size = specs.estimate_max_resolution_from_file(FILE_Origin)
|
|
854
|
+
if DEBUG:
|
|
855
|
+
PRINT("Size:%s"%str(size))
|
|
856
|
+
PRINT(
|
|
857
|
+
"-Maximum resolution estimation based on file size: %s*%s"
|
|
858
|
+
% (MaxRes, MaxRes)
|
|
859
|
+
)
|
|
860
|
+
except Exception as e:
|
|
861
|
+
Betterror(e, inspect.stack()[0][3])
|
|
862
|
+
PRINT(Candy("Color", "red", "Error:%s")% Candy("Color", "yellow", e))
|
|
863
|
+
TheEnd()
|
|
864
|
+
|
|
865
|
+
return MaxRes
|
|
866
|
+
|
|
867
|
+
|
|
868
|
+
def GetSpec(GetChunk,Mode,Fields=["All"],StructIndex=None,IterNbr=1):
|
|
869
|
+
return getspec_runtime.run_getspec_from_namespace(
|
|
870
|
+
globals(),
|
|
871
|
+
GetChunk,
|
|
872
|
+
Mode,
|
|
873
|
+
Fields,
|
|
874
|
+
StructIndex,
|
|
875
|
+
IterNbr,
|
|
876
|
+
)
|
|
877
|
+
|
|
878
|
+
|
|
879
|
+
def Sync_Chunk_Info_Legacy_State(section=None):
|
|
880
|
+
if hasattr(section, "legacy_globals"):
|
|
881
|
+
globals().update(section.legacy_globals())
|
|
882
|
+
return None
|
|
883
|
+
return chunk_state_runtime.sync_state_to_legacy(globals(), CHUNK_INFO_STATE, section)
|
|
884
|
+
|
|
885
|
+
|
|
886
|
+
def Sync_Chunk_Info_State_From_Legacy(section=None):
|
|
887
|
+
return chunk_state_runtime.sync_legacy_to_state(CHUNK_INFO_STATE, globals(), section)
|
|
888
|
+
|
|
889
|
+
|
|
890
|
+
def Chunk_Report_Color(color, value):
|
|
891
|
+
return Candy("Color", color, value)
|
|
892
|
+
|
|
893
|
+
|
|
894
|
+
def Chunky_Report(name):
|
|
895
|
+
return Candy("Chunky", name)
|
|
896
|
+
|
|
897
|
+
|
|
898
|
+
####
|
|
899
|
+
def GetInfo_Set_Legacy(**values):
|
|
900
|
+
globals().update(values)
|
|
901
|
+
|
|
902
|
+
|
|
903
|
+
def GetInfo_Runtime():
|
|
904
|
+
return getinfo_runtime.GetInfoRuntime(
|
|
905
|
+
chunk_state=CHUNK_INFO_STATE,
|
|
906
|
+
set_legacy=GetInfo_Set_Legacy,
|
|
907
|
+
sync_legacy=Sync_Chunk_Info_Legacy_State,
|
|
908
|
+
max_resolution=Max_Res,
|
|
909
|
+
checkpoint=CheckPoint,
|
|
910
|
+
emit=PRINT,
|
|
911
|
+
candy=Candy,
|
|
912
|
+
color=Chunk_Report_Color,
|
|
913
|
+
chunky=Chunky_Report,
|
|
914
|
+
raw_length=Raw_Length,
|
|
915
|
+
orig_cl=Orig_CL,
|
|
916
|
+
ihdr_color=IHDR_Color,
|
|
917
|
+
ihdr_depth=IHDR_Depht,
|
|
918
|
+
chunks_history=tuple(Chunks_History),
|
|
919
|
+
private_chunks=tuple(PRIVATE_CHUNKS),
|
|
920
|
+
allchunks=tuple(ALLCHUNKS),
|
|
921
|
+
)
|
|
922
|
+
|
|
923
|
+
|
|
924
|
+
def GetInfo(Chunk, data, Dummy=False):
|
|
925
|
+
globals().update(
|
|
926
|
+
iCCP_Name="",
|
|
927
|
+
iTXt_String="",
|
|
928
|
+
iTXt_Key="",
|
|
929
|
+
zTXt_Key="",
|
|
930
|
+
tEXt_Text="",
|
|
931
|
+
tEXt_Key="",
|
|
932
|
+
)
|
|
933
|
+
|
|
934
|
+
getinfo_runtime.run_getinfo(GetInfo_Runtime(), Chunk, data)
|
|
935
|
+
|
|
936
|
+
if Dummy is False:
|
|
937
|
+
CheckChunkOrder(Chunk, "TheGoodPlace")
|
|
938
|
+
return
|
|
939
|
+
|
|
940
|
+
|
|
941
|
+
####
|
|
942
|
+
|
|
943
|
+
|
|
944
|
+
def YouShallPass_Runtime():
|
|
945
|
+
return youshallpass_runtime.YouShallPassRuntime(
|
|
946
|
+
chunk_state=CHUNK_INFO_STATE,
|
|
947
|
+
sync_state=Sync_Chunk_Info_State_From_Legacy,
|
|
948
|
+
chunks_history=tuple(Chunks_History),
|
|
949
|
+
orig_cl=Orig_CL,
|
|
950
|
+
)
|
|
951
|
+
|
|
952
|
+
|
|
953
|
+
def YouShallPass(Chunk, data):
|
|
954
|
+
return youshallpass_runtime.youshallpass(YouShallPass_Runtime(), Chunk, data)
|
|
955
|
+
|
|
956
|
+
|
|
957
|
+
def ChunkbyChunk(offset):
|
|
958
|
+
ChunkScan = chunk_scanner.scan_legacy_chunk(DATA_BYTES, offset)
|
|
959
|
+
Sync_Chunk_Info_Legacy_State(ChunkScan)
|
|
960
|
+
|
|
961
|
+
Candy("Title", "Chunk Infos:")
|
|
962
|
+
chunk_report.render_legacy_chunk_window(
|
|
963
|
+
ChunkScan.window,
|
|
964
|
+
PRINT,
|
|
965
|
+
lambda color, value: Candy("Color", color, value),
|
|
966
|
+
)
|
|
967
|
+
|
|
968
|
+
return
|
|
969
|
+
|
|
970
|
+
|
|
971
|
+
def GroundhogDay(NewDay):
|
|
972
|
+
|
|
973
|
+
Relaunch = runtime_state.groundhogday_relaunch_args(sys.argv, NewDay)
|
|
974
|
+
sys.argv[:] = Relaunch.argv
|
|
975
|
+
if DEBUG is True:
|
|
976
|
+
PRINT("sys.executable was %s"% sys.executable)
|
|
977
|
+
PRINT("argv is %s"% Relaunch.strargs)
|
|
978
|
+
PRINT("rebooting chunklate")
|
|
979
|
+
if PAUSEDEBUG is True:
|
|
980
|
+
Pause("Pause:Reboot")
|
|
981
|
+
os.execv(sys.executable, Relaunch.exec_args)
|
|
982
|
+
|
|
983
|
+
|
|
984
|
+
def Chunklate(sec):
|
|
985
|
+
|
|
986
|
+
for line in ui.render_chunklate_banner(os.name, random.randint, use_color=USE_COLOR):
|
|
987
|
+
print(line)
|
|
988
|
+
|
|
989
|
+
if sec:
|
|
990
|
+
time.sleep(sec)
|
|
991
|
+
|
|
992
|
+
|
|
993
|
+
def Minibar_Group(Indication=""):
|
|
994
|
+
return "".join("#" if char.isdigit() else char for char in str(Indication))
|
|
995
|
+
|
|
996
|
+
|
|
997
|
+
def Minibar(Indication=""):
|
|
998
|
+
global CharPos
|
|
999
|
+
global GoBack
|
|
1000
|
+
global Loading_txt
|
|
1001
|
+
global Loading_sep
|
|
1002
|
+
global PROGRESS_LINE_ACTIVE
|
|
1003
|
+
minibar_group = Minibar_Group(Indication)
|
|
1004
|
+
if minibar_group != Loading_sep:
|
|
1005
|
+
Loading_txt = ""
|
|
1006
|
+
CharPos = 1
|
|
1007
|
+
GoBack = False
|
|
1008
|
+
Loading_sep = minibar_group
|
|
1009
|
+
Step = ui.minibar_step(Indication, Loading_txt, CharPos, GoBack, MAXCHAR)
|
|
1010
|
+
Loading_txt = Step.loading_text
|
|
1011
|
+
CharPos = Step.char_pos
|
|
1012
|
+
GoBack = Step.go_back
|
|
1013
|
+
if Step.should_print:
|
|
1014
|
+
print(Loading_txt + "\033[K", end="\r")
|
|
1015
|
+
PROGRESS_LINE_ACTIVE = True
|
|
1016
|
+
|
|
1017
|
+
|
|
1018
|
+
def Loadingbar(fishs, fishsize, loop, build):
|
|
1019
|
+
global PROGRESS_LINE_ACTIVE
|
|
1020
|
+
global LAST_PROGRESS_LINE
|
|
1021
|
+
result = ui.run_loadingbar_from_namespace(globals(), fishs, fishsize, loop, build)
|
|
1022
|
+
if not build:
|
|
1023
|
+
if result is not None:
|
|
1024
|
+
LAST_PROGRESS_LINE = result.text
|
|
1025
|
+
PROGRESS_LINE_ACTIVE = True
|
|
1026
|
+
return result
|
|
1027
|
+
|
|
1028
|
+
|
|
1029
|
+
def Finish_Progress_Line(*, clear=False):
|
|
1030
|
+
global PROGRESS_LINE_ACTIVE
|
|
1031
|
+
if PROGRESS_LINE_ACTIVE:
|
|
1032
|
+
if clear:
|
|
1033
|
+
print("\r\033[K", end="")
|
|
1034
|
+
else:
|
|
1035
|
+
print("")
|
|
1036
|
+
PROGRESS_LINE_ACTIVE = False
|
|
1037
|
+
|
|
1038
|
+
|
|
1039
|
+
def Redraw_Progress_Line():
|
|
1040
|
+
global PROGRESS_LINE_ACTIVE
|
|
1041
|
+
if LAST_PROGRESS_LINE:
|
|
1042
|
+
print(LAST_PROGRESS_LINE + "\033[K", end="\r")
|
|
1043
|
+
PROGRESS_LINE_ACTIVE = True
|
|
1044
|
+
|
|
1045
|
+
|
|
1046
|
+
def PRINT_With_Loader_Redraw(msg):
|
|
1047
|
+
was_active = PROGRESS_LINE_ACTIVE
|
|
1048
|
+
Finish_Progress_Line(clear=True)
|
|
1049
|
+
if DEBUGFILE is True:
|
|
1050
|
+
DebugNotes.append(msg)
|
|
1051
|
+
output.append_terminal_transcript(globals(), msg)
|
|
1052
|
+
ui.emit_printable_message(print, msg, max_columns=MAXCHAR, no_dialogue=NODIALOGUE)
|
|
1053
|
+
if was_active:
|
|
1054
|
+
Redraw_Progress_Line()
|
|
1055
|
+
|
|
1056
|
+
|
|
1057
|
+
def Sumform(waitforit, switch):
|
|
1058
|
+
return output.summary_separator(waitforit, switch, MAXCHAR)
|
|
1059
|
+
|
|
1060
|
+
|
|
1061
|
+
def Summarise(infos, Summary_Footer=False):
|
|
1062
|
+
return output.run_summarise_from_namespace(globals(), infos, Summary_Footer)
|
|
1063
|
+
|
|
1064
|
+
|
|
1065
|
+
def Prepare_Immediate_Summary():
|
|
1066
|
+
return output.ensure_immediate_summary_notes(globals())
|
|
1067
|
+
|
|
1068
|
+
|
|
1069
|
+
def Legacy_UI_Runtime():
|
|
1070
|
+
return ui_runtime.LegacyUiRuntime(
|
|
1071
|
+
emit=PRINT,
|
|
1072
|
+
random_int=random.randint,
|
|
1073
|
+
max_columns=MAXCHAR,
|
|
1074
|
+
no_dialogue=NODIALOGUE,
|
|
1075
|
+
use_color=USE_COLOR,
|
|
1076
|
+
pause_dialogue_enabled=PAUSEDIALOGUE,
|
|
1077
|
+
pause_dialogue=lambda: prompts.pause_dialogue(Transcript_Input, PAUSEDIALOGUE),
|
|
1078
|
+
pause_state=DIALOGUE_PAUSE_STATE,
|
|
1079
|
+
)
|
|
1080
|
+
|
|
1081
|
+
|
|
1082
|
+
def Candy(mode, arg, data=None):
|
|
1083
|
+
return Legacy_UI_Runtime().candy(mode, arg, data)
|
|
1084
|
+
|
|
1085
|
+
|
|
1086
|
+
def Prompt_Candy(mode, arg, data=None):
|
|
1087
|
+
def emit(message):
|
|
1088
|
+
output.append_terminal_transcript(globals(), message)
|
|
1089
|
+
print(message, flush=True)
|
|
1090
|
+
|
|
1091
|
+
return ui_runtime.LegacyUiRuntime(
|
|
1092
|
+
emit=emit,
|
|
1093
|
+
random_int=random.randint,
|
|
1094
|
+
max_columns=MAXCHAR,
|
|
1095
|
+
no_dialogue=False,
|
|
1096
|
+
use_color=USE_COLOR,
|
|
1097
|
+
).candy(mode, arg, data)
|
|
1098
|
+
|
|
1099
|
+
|
|
1100
|
+
def SplitDigits(lst):
|
|
1101
|
+
return sorting.natural_sort_key(lst)
|
|
1102
|
+
|
|
1103
|
+
|
|
1104
|
+
def DigDigits(dig):
|
|
1105
|
+
return sorting.digit_or_text(dig)
|
|
1106
|
+
|
|
1107
|
+
|
|
1108
|
+
def ChunkStory(action, Chunk, start, end, chuck_length):
|
|
1109
|
+
global Chunks_History
|
|
1110
|
+
global Chunks_History_Index
|
|
1111
|
+
|
|
1112
|
+
if action == "add":
|
|
1113
|
+
chunk_story.add(Chunks_History, Chunks_History_Index, Chunk, start, end, chuck_length)
|
|
1114
|
+
elif action == "del":
|
|
1115
|
+
try:
|
|
1116
|
+
chunk_story.delete_legacy(Chunks_History, Chunks_History_Index, Chunk)
|
|
1117
|
+
except Exception as e:
|
|
1118
|
+
Betterror(e, inspect.stack()[0][3])
|
|
1119
|
+
if DEBUG is True:
|
|
1120
|
+
PRINT(Candy("Color", "red", "Error:%s")% Candy("Color", "yellow", e))
|
|
1121
|
+
if PAUSEDEBUG is True:
|
|
1122
|
+
Pause("Pause:Chunkstory")
|
|
1123
|
+
|
|
1124
|
+
|
|
1125
|
+
def Clear_Terminal_Dialogue_Pause():
|
|
1126
|
+
DIALOGUE_PAUSE_STATE.pending = False
|
|
1127
|
+
DIALOGUE_PAUSE_STATE.paused_in_group = False
|
|
1128
|
+
DIALOGUE_PAUSE_STATE.rendering_dialogue = False
|
|
1129
|
+
|
|
1130
|
+
|
|
1131
|
+
def Record_Terminal_Transcript(message):
|
|
1132
|
+
output.append_terminal_transcript(globals(), message)
|
|
1133
|
+
|
|
1134
|
+
|
|
1135
|
+
def Transcript_Input(prompt=""):
|
|
1136
|
+
answer = input(prompt)
|
|
1137
|
+
Record_Terminal_Transcript("%s%s" % (prompt, answer))
|
|
1138
|
+
return answer
|
|
1139
|
+
|
|
1140
|
+
|
|
1141
|
+
def TheEnd():
|
|
1142
|
+
Clear_Terminal_Dialogue_Pause()
|
|
1143
|
+
if DEBUG is True:
|
|
1144
|
+
for line in output.the_end_debug_lines(
|
|
1145
|
+
Chunks_History_Index,
|
|
1146
|
+
idatcounter,
|
|
1147
|
+
Chunks_History,
|
|
1148
|
+
IDAT_Bytes_Len,
|
|
1149
|
+
):
|
|
1150
|
+
PRINT(line)
|
|
1151
|
+
if PAUSEDEBUG is True:
|
|
1152
|
+
Pause("ThenEnd debug")
|
|
1153
|
+
Open_Current_Final_Image_If_Valid()
|
|
1154
|
+
Summarise(None, True)
|
|
1155
|
+
Chunklate(0)
|
|
1156
|
+
Candy("Cowsay", "See you Space Cowboy...", "good")
|
|
1157
|
+
sys.exit(0)
|
|
1158
|
+
|
|
1159
|
+
|
|
1160
|
+
def ToBitstory(bytenbr):
|
|
1161
|
+
global Bytes_History
|
|
1162
|
+
history.append_byte_history(Bytes_History, bytenbr)
|
|
1163
|
+
|
|
1164
|
+
|
|
1165
|
+
def stderr_redirector(stream):
|
|
1166
|
+
return stdio.stderr_redirector(stream)
|
|
1167
|
+
|
|
1168
|
+
def Product(chunk_data,color_type,gen_nbr=None):
|
|
1169
|
+
yield from specs.iter_product_values(chunk_data, color_type)
|
|
1170
|
+
|
|
1171
|
+
|
|
1172
|
+
class Tk_Gen_Scale_Plte:
|
|
1173
|
+
|
|
1174
|
+
def __init__(self, master=None, label='', value=0,to=None,from_=None,ln=None,afn=None,bfn=None,h=None,w=None,nbr=None):
|
|
1175
|
+
widget = palette_ui.create_palette_scale(
|
|
1176
|
+
tkinter_module=tkinter,
|
|
1177
|
+
master=master,
|
|
1178
|
+
label=label,
|
|
1179
|
+
value=value,
|
|
1180
|
+
from_=from_,
|
|
1181
|
+
to=to,
|
|
1182
|
+
length=ln,
|
|
1183
|
+
command=lambda event: Tk_ImgUpdate_Plte(event,nbr=nbr,bfn=bfn,afn=afn,h=h,w=w),
|
|
1184
|
+
grid_options={"padx": 10, "pady": 5},
|
|
1185
|
+
)
|
|
1186
|
+
self.var = widget.var
|
|
1187
|
+
self.s = widget.scale
|
|
1188
|
+
self.swatch = widget.swatch
|
|
1189
|
+
self.container = widget.container
|
|
1190
|
+
def clean(self):
|
|
1191
|
+
if hasattr(self, "container") and hasattr(self.container, "destroy"):
|
|
1192
|
+
self.container.destroy()
|
|
1193
|
+
else:
|
|
1194
|
+
self.s.destroy()
|
|
1195
|
+
|
|
1196
|
+
|
|
1197
|
+
def Tk_Render_Plte_Preview(wanabyte, w, h, frame=None):
|
|
1198
|
+
return palette_runtime.render_palette_preview_from_namespace(globals(), wanabyte, w, h, frame)
|
|
1199
|
+
|
|
1200
|
+
|
|
1201
|
+
def Sync_Palette_Legacy_State():
|
|
1202
|
+
return palette_runtime.sync_palette_legacy_state(globals(), palette_state)
|
|
1203
|
+
|
|
1204
|
+
|
|
1205
|
+
def Tk_ImgUpdate_Plte(event,nbr=None,bfn=None,afn=None,w=None,h=None):
|
|
1206
|
+
return palette_runtime.update_palette_value_from_namespace(globals(), event, nbr, bfn, afn, w, h)
|
|
1207
|
+
|
|
1208
|
+
# if DEBUG:
|
|
1209
|
+
# PRINT("PlteId : %s Value : %s Plte_Blst[PlteId]:%s bvalue: %s Lnx_New : %s"%(str(nbr),str(event),str(Plte_Blst[nbr]),str(bvalue),str(Lnx_New)))
|
|
1210
|
+
|
|
1211
|
+
def Tk_X11_Randomize_Plte(bfn=None,afn=None,w=None,h=None):
|
|
1212
|
+
return palette_runtime.apply_random_palette_colors_from_namespace(globals(), X11_Colors, bfn, afn, w, h)
|
|
1213
|
+
|
|
1214
|
+
def Tk_X11_Plte(bfn=None,afn=None,w=None,h=None):
|
|
1215
|
+
return palette_runtime.apply_palette_colors_from_namespace(globals(), X11_Colors, bfn, afn, w, h)
|
|
1216
|
+
|
|
1217
|
+
|
|
1218
|
+
def Tk_Web_Safe_Randomize_Plte(bfn=None,afn=None,w=None,h=None):
|
|
1219
|
+
return palette_runtime.apply_random_palette_colors_from_namespace(globals(), Web_Safe_Colors, bfn, afn, w, h)
|
|
1220
|
+
|
|
1221
|
+
def Tk_Web_Safe_Plte(bfn=None,afn=None,w=None,h=None):
|
|
1222
|
+
return palette_runtime.apply_palette_colors_from_namespace(globals(), Web_Safe_Colors, bfn, afn, w, h)
|
|
1223
|
+
|
|
1224
|
+
|
|
1225
|
+
def Tk_Randomize_Plte(bfn=None,afn=None,w=None,h=None):
|
|
1226
|
+
return palette_runtime.randomize_palette_from_namespace(globals(), bfn, afn, w, h)
|
|
1227
|
+
|
|
1228
|
+
def Tk_update_scrollregion_Plte(event):
|
|
1229
|
+
canvas = getattr(event, "widget", None)
|
|
1230
|
+
if canvas is None or not hasattr(canvas, "bbox"):
|
|
1231
|
+
canvas = globals().get("canvas_slider")
|
|
1232
|
+
if canvas is not None and hasattr(canvas, "bbox"):
|
|
1233
|
+
canvas.configure(scrollregion=canvas.bbox("all"))
|
|
1234
|
+
|
|
1235
|
+
def Tk_Save_Plte(Tkwin,Cancel,ChunkLength,DataOffset,FromError,wanabyte):
|
|
1236
|
+
return palette_runtime.save_manual_palette_from_namespace(
|
|
1237
|
+
globals(),
|
|
1238
|
+
Tkwin,
|
|
1239
|
+
Cancel,
|
|
1240
|
+
ChunkLength,
|
|
1241
|
+
DataOffset,
|
|
1242
|
+
FromError,
|
|
1243
|
+
wanabyte,
|
|
1244
|
+
)
|
|
1245
|
+
|
|
1246
|
+
|
|
1247
|
+
def Guess_Palettes_Nbr(bfn,afn):
|
|
1248
|
+
return palette_runtime.guess_palette_count_from_namespace(globals(), bfn, afn)
|
|
1249
|
+
|
|
1250
|
+
|
|
1251
|
+
|
|
1252
|
+
def Tk_Manual_Plte(
|
|
1253
|
+
File,
|
|
1254
|
+
ChunkName,
|
|
1255
|
+
ChunkLength,
|
|
1256
|
+
DataOffset,
|
|
1257
|
+
FromError,
|
|
1258
|
+
DataHex=None,
|
|
1259
|
+
):
|
|
1260
|
+
PaletteEditor = palette_runtime.create_manual_palette_editor_from_namespace(
|
|
1261
|
+
globals(),
|
|
1262
|
+
File,
|
|
1263
|
+
ChunkName,
|
|
1264
|
+
ChunkLength,
|
|
1265
|
+
DataOffset,
|
|
1266
|
+
FromError,
|
|
1267
|
+
data_hex=DataHex,
|
|
1268
|
+
)
|
|
1269
|
+
PaletteEditor.window.mainloop()
|
|
1270
|
+
|
|
1271
|
+
|
|
1272
|
+
def SmashBruteBrawl(
|
|
1273
|
+
File,
|
|
1274
|
+
ChunkName,
|
|
1275
|
+
ChunkLength,
|
|
1276
|
+
DataOffset,
|
|
1277
|
+
FromError,
|
|
1278
|
+
EditMode="Replace",
|
|
1279
|
+
BfMode="Brutus",
|
|
1280
|
+
BruteCrc=True,
|
|
1281
|
+
BruteLength=True,
|
|
1282
|
+
OldCrc=False,
|
|
1283
|
+
BruteLevel=None,
|
|
1284
|
+
):
|
|
1285
|
+
return smash_bruteforce.run_legacy_smash_brute_brawl_from_namespace(
|
|
1286
|
+
globals(),
|
|
1287
|
+
File,
|
|
1288
|
+
ChunkName,
|
|
1289
|
+
ChunkLength,
|
|
1290
|
+
DataOffset,
|
|
1291
|
+
FromError,
|
|
1292
|
+
EditMode,
|
|
1293
|
+
BfMode,
|
|
1294
|
+
BruteCrc,
|
|
1295
|
+
BruteLength,
|
|
1296
|
+
OldCrc,
|
|
1297
|
+
brute_level=BruteLevel,
|
|
1298
|
+
)
|
|
1299
|
+
|
|
1300
|
+
|
|
1301
|
+
|
|
1302
|
+
|
|
1303
|
+
def FullChunkForcerNoCrc(
|
|
1304
|
+
File, Chunk, DataOffset, ChunkLength, FromError
|
|
1305
|
+
): ## need to be merged with SmashBruteBrawl
|
|
1306
|
+
return full_chunk_forcer.run_full_chunk_forcer_no_crc_from_namespace(
|
|
1307
|
+
globals(),
|
|
1308
|
+
File,
|
|
1309
|
+
Chunk,
|
|
1310
|
+
DataOffset,
|
|
1311
|
+
ChunkLength,
|
|
1312
|
+
FromError,
|
|
1313
|
+
)
|
|
1314
|
+
|
|
1315
|
+
|
|
1316
|
+
|
|
1317
|
+
|
|
1318
|
+
def Deferred_Linefeed_Signature_Repair(data_bytes, sample_name, linefeed_pattern):
|
|
1319
|
+
globals()["DEFERRED_LINEFEED_SIGNATURE_REPAIR"] = {
|
|
1320
|
+
"data_bytes": data_bytes,
|
|
1321
|
+
"sample_name": sample_name,
|
|
1322
|
+
"linefeed_pattern": linefeed_pattern,
|
|
1323
|
+
}
|
|
1324
|
+
return True
|
|
1325
|
+
|
|
1326
|
+
|
|
1327
|
+
def Clear_Deferred_FindMagic_Repair():
|
|
1328
|
+
globals()["DEFERRED_LINEFEED_SIGNATURE_REPAIR"] = None
|
|
1329
|
+
|
|
1330
|
+
|
|
1331
|
+
def Apply_Deferred_FindMagic_Repair():
|
|
1332
|
+
return magic_runtime.run_deferred_linefeed_signature_repair_from_namespace(globals())
|
|
1333
|
+
|
|
1334
|
+
|
|
1335
|
+
def Run_Ultimate_Linefeed_Direct_Resume():
|
|
1336
|
+
return magic_runtime.run_ultimate_linefeed_direct_resume_from_namespace(globals())
|
|
1337
|
+
|
|
1338
|
+
|
|
1339
|
+
def Run_Smash_Brute_Brawl_Direct_Resume():
|
|
1340
|
+
return smash_bruteforce.run_smash_brute_brawl_direct_resume_from_namespace(globals())
|
|
1341
|
+
|
|
1342
|
+
|
|
1343
|
+
def FindMagic():
|
|
1344
|
+
return magic_runtime.run_find_magic_from_namespace(globals())
|
|
1345
|
+
|
|
1346
|
+
|
|
1347
|
+
def FindFuckingMagic():
|
|
1348
|
+
return magic_runtime.run_find_fucking_magic_from_namespace(globals())
|
|
1349
|
+
|
|
1350
|
+
|
|
1351
|
+
def Ancillary(Chunk):
|
|
1352
|
+
global Bad_Ancillary
|
|
1353
|
+
Bad_Ancillary = ancillary_runtime.run_ancillary_check(
|
|
1354
|
+
ancillary_runtime.AncillaryRuntime(
|
|
1355
|
+
candy=Candy,
|
|
1356
|
+
emit=PRINT,
|
|
1357
|
+
betterror=Betterror,
|
|
1358
|
+
),
|
|
1359
|
+
Chunk,
|
|
1360
|
+
)
|
|
1361
|
+
|
|
1362
|
+
|
|
1363
|
+
def NullFind(data, search4=None):
|
|
1364
|
+
return nearby.null_find(data, search4)
|
|
1365
|
+
|
|
1366
|
+
|
|
1367
|
+
def LibpngCheck(file):
|
|
1368
|
+
return libpng_runtime.run_libpng_check(
|
|
1369
|
+
libpng_runtime.LibpngCheckRuntime(
|
|
1370
|
+
candy=Candy,
|
|
1371
|
+
emit=PRINT,
|
|
1372
|
+
checkpoint=CheckPoint,
|
|
1373
|
+
),
|
|
1374
|
+
libpng_runtime.LibpngCheckContext(
|
|
1375
|
+
sample_name=Sample_Name,
|
|
1376
|
+
libpng_errors=LIBPNG_ERR,
|
|
1377
|
+
cv2_module=cv2,
|
|
1378
|
+
image_module=Image,
|
|
1379
|
+
stderr_redirector=stderr_redirector,
|
|
1380
|
+
warning_reader=KnownBadSrgbProfileWarning,
|
|
1381
|
+
pending_errors=tuple(PandoraBox),
|
|
1382
|
+
),
|
|
1383
|
+
file,
|
|
1384
|
+
)
|
|
1385
|
+
|
|
1386
|
+
|
|
1387
|
+
def KnownBadSrgbProfileWarning(file):
|
|
1388
|
+
return libpng_runtime.run_known_bad_srgb_profile_warning(file)
|
|
1389
|
+
|
|
1390
|
+
|
|
1391
|
+
def Double_Check(CType, ChunkLen, LastCType):
|
|
1392
|
+
return nearby_runtime.run_double_check_from_namespace(globals(), CType, ChunkLen, LastCType)
|
|
1393
|
+
|
|
1394
|
+
|
|
1395
|
+
def RandomSample(data,colortype,chunk_format):
|
|
1396
|
+
return specs.random_sample_hex(data, colortype, chunk_format, random.random)
|
|
1397
|
+
|
|
1398
|
+
|
|
1399
|
+
def DummyChunk_Runtime():
|
|
1400
|
+
return dummy_chunk_runtime.DummyChunkRuntime(
|
|
1401
|
+
data_hex=DATAX,
|
|
1402
|
+
side_notes=SideNotes,
|
|
1403
|
+
candy=Candy,
|
|
1404
|
+
emit=PRINT,
|
|
1405
|
+
checkpoint=CheckPoint,
|
|
1406
|
+
end=TheEnd,
|
|
1407
|
+
pause=Pause,
|
|
1408
|
+
get_spec=GetSpec,
|
|
1409
|
+
spec_length=SpecLength,
|
|
1410
|
+
random_sample=RandomSample,
|
|
1411
|
+
repair_note=fixit_felix.repair_note,
|
|
1412
|
+
debug=DEBUG,
|
|
1413
|
+
pause_debug=PAUSEDEBUG,
|
|
1414
|
+
question=Question,
|
|
1415
|
+
file_origin=FILE_Origin,
|
|
1416
|
+
write_clone=WriteClone,
|
|
1417
|
+
)
|
|
1418
|
+
|
|
1419
|
+
|
|
1420
|
+
def DummyChunk(Chunkname, bad_pos, bad_start, bad_end, FromError): ##TODO bad_pos is not used well enough
|
|
1421
|
+
return dummy_chunk_runtime.run_dummy_chunk(
|
|
1422
|
+
DummyChunk_Runtime(),
|
|
1423
|
+
Chunkname,
|
|
1424
|
+
bad_pos,
|
|
1425
|
+
bad_start,
|
|
1426
|
+
bad_end,
|
|
1427
|
+
FromError,
|
|
1428
|
+
)
|
|
1429
|
+
|
|
1430
|
+
|
|
1431
|
+
def Remove_Extra_Bytes_Before_Chunk(CType, LastCType, Excluded):
|
|
1432
|
+
return nearby_runtime.run_remove_extra_bytes_before_chunk_from_namespace(
|
|
1433
|
+
globals(),
|
|
1434
|
+
CType,
|
|
1435
|
+
LastCType,
|
|
1436
|
+
Excluded,
|
|
1437
|
+
)
|
|
1438
|
+
|
|
1439
|
+
|
|
1440
|
+
def NearbyChunk(CType, ChunkLen, LastCType, DoubleCheck, FromError=None):
|
|
1441
|
+
return nearby_runtime.run_nearby_chunk_from_namespace(
|
|
1442
|
+
globals(),
|
|
1443
|
+
CType,
|
|
1444
|
+
ChunkLen,
|
|
1445
|
+
LastCType,
|
|
1446
|
+
DoubleCheck,
|
|
1447
|
+
FromError,
|
|
1448
|
+
)
|
|
1449
|
+
|
|
1450
|
+
|
|
1451
|
+
def TheGoodPlace(Missplaced_Chunkname, Missplaced_Chunkpos, ToFix_Chunkname):
|
|
1452
|
+
return chunk_order_runtime.run_the_good_place_from_namespace(
|
|
1453
|
+
globals(),
|
|
1454
|
+
Missplaced_Chunkname,
|
|
1455
|
+
Missplaced_Chunkpos,
|
|
1456
|
+
ToFix_Chunkname,
|
|
1457
|
+
)
|
|
1458
|
+
|
|
1459
|
+
|
|
1460
|
+
def CheckChunkOrder(lastchunk, mode):
|
|
1461
|
+
return chunk_order_runtime.run_check_chunk_order_from_namespace(globals(), lastchunk, mode)
|
|
1462
|
+
|
|
1463
|
+
|
|
1464
|
+
|
|
1465
|
+
def NameShift():
|
|
1466
|
+
return name_shift_runtime.run_name_shift_from_namespace(globals())
|
|
1467
|
+
|
|
1468
|
+
|
|
1469
|
+
def BruteChunk_Crc_Matches(candidates):
|
|
1470
|
+
try:
|
|
1471
|
+
# Add validation to check if Raw_Data and Raw_Crc are not empty
|
|
1472
|
+
if not Raw_Data or Raw_Data.strip() == '':
|
|
1473
|
+
return []
|
|
1474
|
+
if not Raw_Crc or Raw_Crc.strip() == '':
|
|
1475
|
+
return []
|
|
1476
|
+
|
|
1477
|
+
chunk_data = bytes.fromhex(Raw_Data)
|
|
1478
|
+
stored_crc = int(Raw_Crc, 16)
|
|
1479
|
+
except Exception as e:
|
|
1480
|
+
Betterror(e, inspect.stack()[0][3])
|
|
1481
|
+
return []
|
|
1482
|
+
|
|
1483
|
+
return chunk_type_crc_matches(chunk_data, stored_crc, candidates)
|
|
1484
|
+
|
|
1485
|
+
|
|
1486
|
+
def BruteChunk_Save_Auto_Name(CType, FromError, ChunkName, reason):
|
|
1487
|
+
return chunk_name_runtime.save_auto_name_from_namespace(
|
|
1488
|
+
globals(),
|
|
1489
|
+
CType,
|
|
1490
|
+
FromError,
|
|
1491
|
+
ChunkName,
|
|
1492
|
+
reason,
|
|
1493
|
+
)
|
|
1494
|
+
|
|
1495
|
+
|
|
1496
|
+
def ChunkName_Runtime():
|
|
1497
|
+
return chunk_name_runtime.build_chunk_name_runtime_from_namespace(globals())
|
|
1498
|
+
|
|
1499
|
+
|
|
1500
|
+
def ChunkName_Context():
|
|
1501
|
+
return chunk_name_runtime.build_chunk_name_context_from_namespace(globals())
|
|
1502
|
+
|
|
1503
|
+
|
|
1504
|
+
def BruteChunk(CType, LastCType, ChunkLen, FromError):
|
|
1505
|
+
return chunk_name_runtime.run_brute_chunk_from_namespace(
|
|
1506
|
+
globals(),
|
|
1507
|
+
CType,
|
|
1508
|
+
LastCType,
|
|
1509
|
+
ChunkLen,
|
|
1510
|
+
FromError,
|
|
1511
|
+
)
|
|
1512
|
+
|
|
1513
|
+
|
|
1514
|
+
def CheckChunkName(ChunkType, ChunkLen, LastCType, Next=None):
|
|
1515
|
+
return chunk_name_runtime.run_check_chunk_name_from_namespace(
|
|
1516
|
+
globals(),
|
|
1517
|
+
ChunkType,
|
|
1518
|
+
ChunkLen,
|
|
1519
|
+
LastCType,
|
|
1520
|
+
Next,
|
|
1521
|
+
)
|
|
1522
|
+
|
|
1523
|
+
|
|
1524
|
+
def SpecLength(chunk_name, chunk_length=None):
|
|
1525
|
+
return spec_length_runtime.run_spec_length(
|
|
1526
|
+
spec_length_runtime.SpecLengthRuntime(
|
|
1527
|
+
candy=Candy,
|
|
1528
|
+
emit=PRINT,
|
|
1529
|
+
end=TheEnd,
|
|
1530
|
+
get_spec=GetSpec,
|
|
1531
|
+
side_notes=SideNotes,
|
|
1532
|
+
),
|
|
1533
|
+
chunk_name,
|
|
1534
|
+
chunk_length,
|
|
1535
|
+
)
|
|
1536
|
+
|
|
1537
|
+
|
|
1538
|
+
def CheckLength(Cdata, Clen, Ctype):
|
|
1539
|
+
return chunk_validation_runtime.run_check_length_from_namespace(
|
|
1540
|
+
globals(),
|
|
1541
|
+
Cdata,
|
|
1542
|
+
Clen,
|
|
1543
|
+
Ctype,
|
|
1544
|
+
)
|
|
1545
|
+
|
|
1546
|
+
|
|
1547
|
+
|
|
1548
|
+
|
|
1549
|
+
def Question(
|
|
1550
|
+
id=None,
|
|
1551
|
+
idhash=None,
|
|
1552
|
+
skipauto=False,
|
|
1553
|
+
timeout_seconds=None,
|
|
1554
|
+
timeout_default=None,
|
|
1555
|
+
):
|
|
1556
|
+
globals()["LAST_QUESTION_STATUS"] = None
|
|
1557
|
+
|
|
1558
|
+
def asker(prompt):
|
|
1559
|
+
if timeout_seconds is None:
|
|
1560
|
+
return Transcript_Input(prompt)
|
|
1561
|
+
try:
|
|
1562
|
+
answer = inputimeout(prompt, timeout=timeout_seconds)
|
|
1563
|
+
Record_Terminal_Transcript("%s%s" % (prompt, answer))
|
|
1564
|
+
return answer
|
|
1565
|
+
except TimeoutOccurred:
|
|
1566
|
+
default_answer = "yes" if timeout_default is True else "no"
|
|
1567
|
+
Record_Terminal_Transcript(
|
|
1568
|
+
"%s%s [timeout after %s seconds]"
|
|
1569
|
+
% (prompt, default_answer, timeout_seconds)
|
|
1570
|
+
)
|
|
1571
|
+
PRINT("")
|
|
1572
|
+
PRINT(
|
|
1573
|
+
"-Question timed out after %s seconds; auto-answering %s.\n"
|
|
1574
|
+
% (timeout_seconds, default_answer)
|
|
1575
|
+
)
|
|
1576
|
+
return default_answer
|
|
1577
|
+
|
|
1578
|
+
runtime = question_runtime.QuestionRuntime(
|
|
1579
|
+
history=IFOP,
|
|
1580
|
+
nodialogue=NODIALOGUE,
|
|
1581
|
+
auto=AUTO,
|
|
1582
|
+
clear=CLEAR_SCREEN_ACTIVE_THIS_PASS,
|
|
1583
|
+
debug=DEBUG,
|
|
1584
|
+
pause_debug=PAUSEDEBUG,
|
|
1585
|
+
offset=CLoffI,
|
|
1586
|
+
asker=asker,
|
|
1587
|
+
candy=Candy,
|
|
1588
|
+
emit=PRINT,
|
|
1589
|
+
pause=Pause,
|
|
1590
|
+
end=TheEnd,
|
|
1591
|
+
prompt_candy=Prompt_Candy,
|
|
1592
|
+
status_sink=lambda status: globals().__setitem__("LAST_QUESTION_STATUS", status),
|
|
1593
|
+
)
|
|
1594
|
+
try:
|
|
1595
|
+
return question_runtime.ask_question(runtime, id, idhash, skipauto=skipauto)
|
|
1596
|
+
finally:
|
|
1597
|
+
Clear_Terminal_Dialogue_Pause()
|
|
1598
|
+
Close_Preview_Image()
|
|
1599
|
+
|
|
1600
|
+
|
|
1601
|
+
def Checksum(Ctype, Cdata, Crc, next=None):
|
|
1602
|
+
return chunk_validation_runtime.run_checksum_from_namespace(
|
|
1603
|
+
globals(),
|
|
1604
|
+
Ctype,
|
|
1605
|
+
Cdata,
|
|
1606
|
+
Crc,
|
|
1607
|
+
next,
|
|
1608
|
+
)
|
|
1609
|
+
|
|
1610
|
+
|
|
1611
|
+
def RemoveChunk(start,length,infos):
|
|
1612
|
+
return writer_runtime.run_remove_chunk(
|
|
1613
|
+
writer_runtime.ClonePatchRuntime(
|
|
1614
|
+
data_hex=DATAX,
|
|
1615
|
+
candy=Candy,
|
|
1616
|
+
emit=PRINT,
|
|
1617
|
+
betterror=Betterror,
|
|
1618
|
+
write_clone=WriteClone,
|
|
1619
|
+
set_show_must_go_on=lambda value: globals().__setitem__("Show_Must_Go_On", value),
|
|
1620
|
+
),
|
|
1621
|
+
start,
|
|
1622
|
+
length,
|
|
1623
|
+
infos,
|
|
1624
|
+
)
|
|
1625
|
+
|
|
1626
|
+
def SaveClone(DataFix, start, end, infos):
|
|
1627
|
+
return writer_runtime.run_save_clone(
|
|
1628
|
+
writer_runtime.ClonePatchRuntime(
|
|
1629
|
+
data_hex=DATAX,
|
|
1630
|
+
candy=Candy,
|
|
1631
|
+
emit=PRINT,
|
|
1632
|
+
betterror=Betterror,
|
|
1633
|
+
write_clone=WriteClone,
|
|
1634
|
+
set_show_must_go_on=lambda value: globals().__setitem__("Show_Must_Go_On", value),
|
|
1635
|
+
save_debug_payloads=lambda label, start, end, payloads: writer_runtime.save_clone_debug_payloads(
|
|
1636
|
+
FILE_Origin,
|
|
1637
|
+
FILE_DIR,
|
|
1638
|
+
label,
|
|
1639
|
+
start,
|
|
1640
|
+
end,
|
|
1641
|
+
payloads,
|
|
1642
|
+
),
|
|
1643
|
+
side_notes=SideNotes,
|
|
1644
|
+
),
|
|
1645
|
+
DataFix,
|
|
1646
|
+
start,
|
|
1647
|
+
end,
|
|
1648
|
+
infos,
|
|
1649
|
+
)
|
|
1650
|
+
|
|
1651
|
+
|
|
1652
|
+
def WriteClone(data,infos):
|
|
1653
|
+
return writer_runtime.run_write_clone_from_namespace(globals(), data, infos)
|
|
1654
|
+
|
|
1655
|
+
|
|
1656
|
+
def Relics_Runtime():
|
|
1657
|
+
return relics_runtime.build_relics_runtime_from_namespace(globals())
|
|
1658
|
+
|
|
1659
|
+
|
|
1660
|
+
def Relics_Context(FromError):
|
|
1661
|
+
return relics_runtime.build_relics_context_from_namespace(globals(), FromError)
|
|
1662
|
+
|
|
1663
|
+
|
|
1664
|
+
def Relics(FromError):
|
|
1665
|
+
return relics_runtime.handle_relics_from_namespace(globals(), FromError)
|
|
1666
|
+
|
|
1667
|
+
|
|
1668
|
+
def Naming(filename):
|
|
1669
|
+
|
|
1670
|
+
target = output.next_clone_target(filename, FILE_DIR)
|
|
1671
|
+
return (target.name, target.directory)
|
|
1672
|
+
|
|
1673
|
+
def LockDown():
|
|
1674
|
+
Candy("Title", "LockDown: ", Candy("Color", "white", Chunk))
|
|
1675
|
+
|
|
1676
|
+
for folder in output.lockdown_folder_lines(FILE_Origin, FILE_DIR):
|
|
1677
|
+
PRINT(folder)
|
|
1678
|
+
|
|
1679
|
+
|
|
1680
|
+
def FixItFelix_Set_Skip_Bad_Crc(value):
|
|
1681
|
+
global Skip_Bad_Crc
|
|
1682
|
+
|
|
1683
|
+
Skip_Bad_Crc = value
|
|
1684
|
+
|
|
1685
|
+
|
|
1686
|
+
def FixItFelix_Set_Old_Bad_Crc(value):
|
|
1687
|
+
global Old_Bad_Crc
|
|
1688
|
+
|
|
1689
|
+
Old_Bad_Crc = value
|
|
1690
|
+
|
|
1691
|
+
|
|
1692
|
+
def FixItFelix_Wrong_Crc_Runtime():
|
|
1693
|
+
return fixit_felix_runtime.build_wrong_crc_runtime_from_namespace(globals())
|
|
1694
|
+
|
|
1695
|
+
|
|
1696
|
+
def FixItFelix_Wrong_Crc(key, chkd, PandoraBox_len):
|
|
1697
|
+
CrcDecision = fixit_felix.wrong_crc_decision(
|
|
1698
|
+
key,
|
|
1699
|
+
solved=str(key) in Cornucopia,
|
|
1700
|
+
pandora_box_len=PandoraBox_len,
|
|
1701
|
+
)
|
|
1702
|
+
|
|
1703
|
+
CrcTools = None
|
|
1704
|
+
if CrcDecision.action != "already_in_cornucopia":
|
|
1705
|
+
try:
|
|
1706
|
+
chkd = relics.resolve_tool_prefix(PandoraBox[key], chkd)
|
|
1707
|
+
CrcTools = relics.wrong_crc_tools(PandoraBox[key], chkd)
|
|
1708
|
+
except KeyError:
|
|
1709
|
+
Candy(
|
|
1710
|
+
"Cowsay",
|
|
1711
|
+
"CRC repair data is missing for this malformed chunk. I will leave it to the chunk-name/length repair path.",
|
|
1712
|
+
"com",
|
|
1713
|
+
)
|
|
1714
|
+
FixItFelix_Set_Skip_Bad_Crc(True)
|
|
1715
|
+
return False, None
|
|
1716
|
+
|
|
1717
|
+
success, result = fixit_felix_runtime.apply_wrong_crc(
|
|
1718
|
+
FixItFelix_Wrong_Crc_Runtime(),
|
|
1719
|
+
CrcDecision,
|
|
1720
|
+
chkd,
|
|
1721
|
+
CrcTools,
|
|
1722
|
+
)
|
|
1723
|
+
|
|
1724
|
+
return success, result
|
|
1725
|
+
|
|
1726
|
+
|
|
1727
|
+
def FixItFelix_Set_Skip_Bad_Libpng(value):
|
|
1728
|
+
global Skip_Bad_Libpng
|
|
1729
|
+
|
|
1730
|
+
Skip_Bad_Libpng = value
|
|
1731
|
+
|
|
1732
|
+
|
|
1733
|
+
def FixItFelix_Libpng_Error_Runtime():
|
|
1734
|
+
return fixit_felix_runtime.build_libpng_error_runtime_from_namespace(globals())
|
|
1735
|
+
|
|
1736
|
+
|
|
1737
|
+
def FixItFelix_Libpng_Error(key, chkd):
|
|
1738
|
+
return fixit_felix_runtime.apply_libpng_error(
|
|
1739
|
+
FixItFelix_Libpng_Error_Runtime(),
|
|
1740
|
+
fixit_felix.libpng_error_decision(
|
|
1741
|
+
key,
|
|
1742
|
+
solved=str(key) in Cornucopia,
|
|
1743
|
+
skip_bad_libpng=Skip_Bad_Libpng,
|
|
1744
|
+
),
|
|
1745
|
+
chkd,
|
|
1746
|
+
)
|
|
1747
|
+
|
|
1748
|
+
|
|
1749
|
+
def FixItFelix_Set_Skip_Bad_Next_Name(value):
|
|
1750
|
+
global Skip_Bad_Next_Name
|
|
1751
|
+
|
|
1752
|
+
Skip_Bad_Next_Name = value
|
|
1753
|
+
|
|
1754
|
+
|
|
1755
|
+
def FixItFelix_Set_Skip_Bad_Current_Name(value):
|
|
1756
|
+
global Skip_Bad_Current_Name
|
|
1757
|
+
|
|
1758
|
+
Skip_Bad_Current_Name = value
|
|
1759
|
+
|
|
1760
|
+
|
|
1761
|
+
def FixItFelix_Wrong_Chunk_Name_Runtime():
|
|
1762
|
+
return fixit_felix_runtime.build_wrong_chunk_name_runtime_from_namespace(globals())
|
|
1763
|
+
|
|
1764
|
+
|
|
1765
|
+
def FixItFelix_Wrong_Chunk_Name(key, chkd):
|
|
1766
|
+
if Skip_Bad_Current_Name is False:
|
|
1767
|
+
NameDecision = fixit_felix.wrong_chunk_name_decision(
|
|
1768
|
+
key,
|
|
1769
|
+
solved=str(key) in Cornucopia,
|
|
1770
|
+
bad_crc=Bad_Crc,
|
|
1771
|
+
)
|
|
1772
|
+
|
|
1773
|
+
NameTools = None
|
|
1774
|
+
name_chkd = chkd
|
|
1775
|
+
if NameDecision.action != "save_existing_solution":
|
|
1776
|
+
name_chkd = relics.resolve_tool_prefix(PandoraBox[key], chkd)
|
|
1777
|
+
NameTools = relics.wrong_chunk_name_tools(PandoraBox[key], name_chkd)
|
|
1778
|
+
|
|
1779
|
+
return fixit_felix_runtime.apply_wrong_chunk_name(
|
|
1780
|
+
FixItFelix_Wrong_Chunk_Name_Runtime(),
|
|
1781
|
+
NameDecision,
|
|
1782
|
+
name_chkd,
|
|
1783
|
+
NameTools,
|
|
1784
|
+
)
|
|
1785
|
+
|
|
1786
|
+
return False, None
|
|
1787
|
+
|
|
1788
|
+
|
|
1789
|
+
def FixItFelix_Set_Skip_Bad_No_Next_Chunk(value):
|
|
1790
|
+
global Skip_Bad_No_Next_Chunk
|
|
1791
|
+
|
|
1792
|
+
Skip_Bad_No_Next_Chunk = value
|
|
1793
|
+
|
|
1794
|
+
|
|
1795
|
+
def FixItFelix_Set_EOF(value):
|
|
1796
|
+
global EOF
|
|
1797
|
+
|
|
1798
|
+
EOF = value
|
|
1799
|
+
|
|
1800
|
+
|
|
1801
|
+
def FixItFelix_No_NextChunk_Runtime():
|
|
1802
|
+
return fixit_felix_runtime.build_no_next_chunk_runtime_from_namespace(globals())
|
|
1803
|
+
|
|
1804
|
+
|
|
1805
|
+
def FixItFelix_No_NextChunk_Decision_Chunk(Chunk, chkd, no_next_chkd, tools):
|
|
1806
|
+
if Chunk in (None, b"", ""):
|
|
1807
|
+
return tools.chunk_type
|
|
1808
|
+
if no_next_chkd != chkd:
|
|
1809
|
+
return tools.chunk_type
|
|
1810
|
+
return Chunk
|
|
1811
|
+
|
|
1812
|
+
|
|
1813
|
+
def FixItFelix_No_NextChunk(key, chkd, Chunk):
|
|
1814
|
+
global Skip_Bad_No_Next_Chunk
|
|
1815
|
+
|
|
1816
|
+
if Skip_Bad_No_Next_Chunk is False:
|
|
1817
|
+
no_next_chkd = relics.resolve_tool_prefix(PandoraBox[key], chkd)
|
|
1818
|
+
NoNextTools = relics.no_next_chunk_tools(PandoraBox[key], no_next_chkd)
|
|
1819
|
+
decision_chunk = FixItFelix_No_NextChunk_Decision_Chunk(
|
|
1820
|
+
Chunk,
|
|
1821
|
+
chkd,
|
|
1822
|
+
no_next_chkd,
|
|
1823
|
+
NoNextTools,
|
|
1824
|
+
)
|
|
1825
|
+
NoNextDecision = fixit_felix.no_next_chunk_decision(
|
|
1826
|
+
current_chunk=decision_chunk,
|
|
1827
|
+
chunk_type=NoNextTools.chunk_type,
|
|
1828
|
+
chunk_length=NoNextTools.chunk_length,
|
|
1829
|
+
bad_critical=Bad_Critical,
|
|
1830
|
+
)
|
|
1831
|
+
return fixit_felix_runtime.apply_no_next_chunk(
|
|
1832
|
+
FixItFelix_No_NextChunk_Runtime(),
|
|
1833
|
+
NoNextDecision,
|
|
1834
|
+
key,
|
|
1835
|
+
no_next_chkd,
|
|
1836
|
+
NoNextTools,
|
|
1837
|
+
)
|
|
1838
|
+
|
|
1839
|
+
return False, None
|
|
1840
|
+
|
|
1841
|
+
|
|
1842
|
+
def FixItFelix_Gama_Zero_Runtime():
|
|
1843
|
+
return fixit_felix_runtime.build_gama_zero_runtime_from_namespace(globals())
|
|
1844
|
+
|
|
1845
|
+
|
|
1846
|
+
def FixItFelix_Gama_Zero(key):
|
|
1847
|
+
return fixit_felix_runtime.apply_gama_zero(
|
|
1848
|
+
FixItFelix_Gama_Zero_Runtime(),
|
|
1849
|
+
fixit_felix.gama_zero_decision(key),
|
|
1850
|
+
)
|
|
1851
|
+
|
|
1852
|
+
|
|
1853
|
+
def FixItFelix_Critical_Miss_Runtime():
|
|
1854
|
+
return fixit_felix_runtime.build_critical_miss_runtime_from_namespace(globals())
|
|
1855
|
+
|
|
1856
|
+
|
|
1857
|
+
def FixItFelix_Critical_Miss(key):
|
|
1858
|
+
return fixit_felix_runtime.apply_critical_miss(
|
|
1859
|
+
FixItFelix_Critical_Miss_Runtime(),
|
|
1860
|
+
fixit_felix.critical_miss_decision(
|
|
1861
|
+
key,
|
|
1862
|
+
debug=DEBUG,
|
|
1863
|
+
pause_debug=PAUSEDEBUG,
|
|
1864
|
+
),
|
|
1865
|
+
)
|
|
1866
|
+
|
|
1867
|
+
|
|
1868
|
+
def FixItFelix_Automatic_Repair_Runtime():
|
|
1869
|
+
return fixit_felix_runtime.build_automatic_repair_runtime_from_namespace(globals())
|
|
1870
|
+
|
|
1871
|
+
|
|
1872
|
+
def FixItFelix_Apply_Repair(repair):
|
|
1873
|
+
return fixit_felix_runtime.apply_repair(
|
|
1874
|
+
FixItFelix_Automatic_Repair_Runtime(),
|
|
1875
|
+
repair,
|
|
1876
|
+
)
|
|
1877
|
+
|
|
1878
|
+
|
|
1879
|
+
def FixItFelix_Try_Automatic_Repair(name):
|
|
1880
|
+
global Bad_Libpng
|
|
1881
|
+
|
|
1882
|
+
repair_intent = fixit_felix.automatic_repair_intent(name, PandoraBox)
|
|
1883
|
+
repair = fixit_felix.automatic_repair(
|
|
1884
|
+
name,
|
|
1885
|
+
DATA_BYTES,
|
|
1886
|
+
PandoraBox,
|
|
1887
|
+
known_chunk_types=ALLCHUNKS,
|
|
1888
|
+
auto=AUTO,
|
|
1889
|
+
nodialogue=NODIALOGUE,
|
|
1890
|
+
max_saves=MAX_SAVES,
|
|
1891
|
+
)
|
|
1892
|
+
if repair is None:
|
|
1893
|
+
failure_explanation = fixit_felix.automatic_repair_failure_explanation(
|
|
1894
|
+
name,
|
|
1895
|
+
PandoraBox,
|
|
1896
|
+
)
|
|
1897
|
+
if failure_explanation is not None:
|
|
1898
|
+
Candy("Cowsay", failure_explanation, "bad")
|
|
1899
|
+
SideNotes.append("-FixItFelix:%s." % failure_explanation)
|
|
1900
|
+
return None
|
|
1901
|
+
|
|
1902
|
+
if repair_intent is not None:
|
|
1903
|
+
Candy("Cowsay", repair_intent, "com")
|
|
1904
|
+
|
|
1905
|
+
if name == "hist_out_of_place_cleanup":
|
|
1906
|
+
if NODIALOGUE:
|
|
1907
|
+
for key in list(PandoraBox):
|
|
1908
|
+
key_text = str(key)
|
|
1909
|
+
if "hIST: out of place" in key_text or "hIST chunk must appear before" in key_text:
|
|
1910
|
+
relics.discard_pandora_error(PandoraBox, key)
|
|
1911
|
+
SideNotes.append(
|
|
1912
|
+
"-Keeping optional hIST chunk(s): non-interactive mode cannot confirm metadata removal."
|
|
1913
|
+
)
|
|
1914
|
+
Bad_Libpng = False
|
|
1915
|
+
return True
|
|
1916
|
+
if not AUTO and not Question(
|
|
1917
|
+
id="hIST Optional Metadata Removal:-Remove hIST chunk(s) to silence libpng?"
|
|
1918
|
+
):
|
|
1919
|
+
for key in list(PandoraBox):
|
|
1920
|
+
key_text = str(key)
|
|
1921
|
+
if "hIST: out of place" in key_text or "hIST chunk must appear before" in key_text:
|
|
1922
|
+
relics.discard_pandora_error(PandoraBox, key)
|
|
1923
|
+
SideNotes.append("-Keeping optional hIST chunk(s) as requested.")
|
|
1924
|
+
PRINT("-Keeping hIST chunk(s) as requested.")
|
|
1925
|
+
Bad_Libpng = False
|
|
1926
|
+
return True
|
|
1927
|
+
|
|
1928
|
+
if name == "ihdr_rebuild":
|
|
1929
|
+
crc_bruteforce_result = fixit_felix_runtime.try_ihdr_stored_crc_bruteforce(
|
|
1930
|
+
FixItFelix_Automatic_Repair_Runtime(),
|
|
1931
|
+
repair,
|
|
1932
|
+
)
|
|
1933
|
+
if crc_bruteforce_result is not None:
|
|
1934
|
+
return crc_bruteforce_result
|
|
1935
|
+
|
|
1936
|
+
return FixItFelix_Apply_Repair(repair)
|
|
1937
|
+
|
|
1938
|
+
|
|
1939
|
+
def FixItFelix_Runtime_Callbacks():
|
|
1940
|
+
return fixit_felix_runtime.build_legacy_fixit_felix_handlers_from_namespace(globals())
|
|
1941
|
+
|
|
1942
|
+
|
|
1943
|
+
def FixItFelix_Runtime():
|
|
1944
|
+
return fixit_felix_runtime.build_fixit_felix_runtime_from_namespace(globals())
|
|
1945
|
+
|
|
1946
|
+
|
|
1947
|
+
def FixItFelix_Tool_Prefix(Chunk):
|
|
1948
|
+
if isinstance(Chunk, str):
|
|
1949
|
+
return Chunk + "_Tool_"
|
|
1950
|
+
try:
|
|
1951
|
+
return Chunk.decode(errors="ignore") + "_Tool_"
|
|
1952
|
+
except AttributeError as e:
|
|
1953
|
+
Betterror(e, "FixItFelix")
|
|
1954
|
+
return fixit_felix.tool_prefix_for_chunk(Chunk)
|
|
1955
|
+
|
|
1956
|
+
|
|
1957
|
+
def FixItFelix(Chunk=None):
|
|
1958
|
+
Candy("Title", "Fix It Felix: ", Candy("Color", "white", Chunk))
|
|
1959
|
+
##TODOFIND A WAY TO MAKE IT READABLE
|
|
1960
|
+
|
|
1961
|
+
global Show_Must_Go_On
|
|
1962
|
+
|
|
1963
|
+
chkd = FixItFelix_Tool_Prefix(Chunk)
|
|
1964
|
+
RunResult = fixit_felix_runtime.run_fixit_felix_pipeline_from_namespace(
|
|
1965
|
+
globals(),
|
|
1966
|
+
Chunk,
|
|
1967
|
+
chkd,
|
|
1968
|
+
)
|
|
1969
|
+
if RunResult.should_return:
|
|
1970
|
+
return RunResult.result
|
|
1971
|
+
|
|
1972
|
+
Show_Must_Go_On = True
|
|
1973
|
+
|
|
1974
|
+
def CheckPoint(error, fixed, function, chunk, infos, *ToolKit):
|
|
1975
|
+
if DEBUGFILE is True:
|
|
1976
|
+
DebugNotes.extend(
|
|
1977
|
+
checkpoint_runtime.checkpoint_debug_lines(
|
|
1978
|
+
error=error,
|
|
1979
|
+
fixed=fixed,
|
|
1980
|
+
function=function,
|
|
1981
|
+
infos=infos,
|
|
1982
|
+
chunk=chunk,
|
|
1983
|
+
toolkit=ToolKit,
|
|
1984
|
+
pandora_keys=tuple(PandoraBox),
|
|
1985
|
+
)
|
|
1986
|
+
)
|
|
1987
|
+
return checkpoint_runtime.run_checkpoint_from_namespace(
|
|
1988
|
+
globals(),
|
|
1989
|
+
error=error,
|
|
1990
|
+
fixed=fixed,
|
|
1991
|
+
function=function,
|
|
1992
|
+
chunk=chunk,
|
|
1993
|
+
infos=infos,
|
|
1994
|
+
toolkit=ToolKit,
|
|
1995
|
+
)
|
|
1996
|
+
|
|
1997
|
+
|
|
1998
|
+
def Pause(msg):
|
|
1999
|
+
prompts.pause_with_legacy_eof_report(
|
|
2000
|
+
Transcript_Input,
|
|
2001
|
+
msg,
|
|
2002
|
+
error_emit=print,
|
|
2003
|
+
stderr_redirector=stderr_redirector,
|
|
2004
|
+
stream_factory=io.BytesIO,
|
|
2005
|
+
)
|
|
2006
|
+
return ()
|
|
2007
|
+
|
|
2008
|
+
def PRINT(msg):
|
|
2009
|
+
Finish_Progress_Line()
|
|
2010
|
+
if DEBUGFILE is True:
|
|
2011
|
+
DebugNotes.append(msg)
|
|
2012
|
+
output.append_terminal_transcript(globals(), msg)
|
|
2013
|
+
ui.emit_printable_message(print, msg, max_columns=MAXCHAR, no_dialogue=NODIALOGUE)
|
|
2014
|
+
|
|
2015
|
+
# else:
|
|
2016
|
+
# print("-not print-")
|
|
2017
|
+
# print(msg)
|
|
2018
|
+
|
|
2019
|
+
|
|
2020
|
+
def DebugPrint(*args, **kwargs):
|
|
2021
|
+
if DEBUGFILE is True:
|
|
2022
|
+
DebugNotes.append(" ".join(str(arg) for arg in args))
|
|
2023
|
+
print(*args, **kwargs)
|
|
2024
|
+
|
|
2025
|
+
def main():
|
|
2026
|
+
parser = cli.configure_parser(ArgumentParser())
|
|
2027
|
+
Args, unknown = parser.parse_known_args()
|
|
2028
|
+
MainOptions = main_runtime.apply_main_cli_options_from_namespace(
|
|
2029
|
+
globals(),
|
|
2030
|
+
Args,
|
|
2031
|
+
unknown,
|
|
2032
|
+
argv_len=len(sys.argv),
|
|
2033
|
+
parser=parser,
|
|
2034
|
+
)
|
|
2035
|
+
if MainOptions is None:
|
|
2036
|
+
return
|
|
2037
|
+
Ensure_Runtime_Dependencies()
|
|
2038
|
+
Configure_Terminal_Color()
|
|
2039
|
+
if Should_Run_Package_Update_Check(Args):
|
|
2040
|
+
Ensure_Package_Current_Or_Continue()
|
|
2041
|
+
|
|
2042
|
+
while True:
|
|
2043
|
+
MainLoopState = main_runtime.run_main_loop_once_from_namespace(globals())
|
|
2044
|
+
if MainLoopState.should_return:
|
|
2045
|
+
return
|
|
2046
|
+
|
|
2047
|
+
|
|
2048
|
+
###
|
|
2049
|
+
|
|
2050
|
+
|
|
2051
|
+
###
|
|
2052
|
+
|
|
2053
|
+
MINIMAL_CHUNKS = list(specs.MINIMAL_CHUNKS)
|
|
2054
|
+
CRITICAL_CHUNKS = list(specs.CRITICAL_CHUNKS)
|
|
2055
|
+
CHUNKS = list(specs.CHUNKS)
|
|
2056
|
+
PRIVATE_CHUNKS = list(specs.PRIVATE_CHUNKS)
|
|
2057
|
+
BEFORE_PLTE = list(specs.BEFORE_PLTE)
|
|
2058
|
+
AFTER_PLTE = list(specs.AFTER_PLTE)
|
|
2059
|
+
BEFORE_IDAT = list(specs.BEFORE_IDAT)
|
|
2060
|
+
BEFORE_IDAT2 = list(specs.BEFORE_IDAT2)
|
|
2061
|
+
UNIQUE_CHUNK = list(specs.UNIQUE_CHUNK)
|
|
2062
|
+
NO_ORDER_CHUNKS = list(specs.NO_ORDER_CHUNKS)
|
|
2063
|
+
CHUNKS_LEN_NOT_FIXED = list(specs.CHUNKS_LEN_NOT_FIXED)
|
|
2064
|
+
ALLCHUNKS = list(specs.ALLCHUNKS)
|
|
2065
|
+
LIBPNG_ERR = list(specs.LIBPNG_ERR)
|
|
2066
|
+
|
|
2067
|
+
|
|
2068
|
+
|
|
2069
|
+
IFOP = []
|
|
2070
|
+
Chunks_History = []
|
|
2071
|
+
IDAT_Bytes_Len_History = []
|
|
2072
|
+
Chunks_History_Index = []
|
|
2073
|
+
pCAL_Param = []
|
|
2074
|
+
PLTE_R = []
|
|
2075
|
+
PLTE_G = []
|
|
2076
|
+
PLTE_B = []
|
|
2077
|
+
Plte_Blst = []
|
|
2078
|
+
palette_state = None
|
|
2079
|
+
slider_list = []
|
|
2080
|
+
wanabyte = b""
|
|
2081
|
+
sPLT_Name = []
|
|
2082
|
+
sPLT_Depht = []
|
|
2083
|
+
sPLT_Red = []
|
|
2084
|
+
sPLT_Green = []
|
|
2085
|
+
sPLT_Blue = []
|
|
2086
|
+
sPLT_Alpha = []
|
|
2087
|
+
sPLT_Freq = []
|
|
2088
|
+
hIST = []
|
|
2089
|
+
tEXt_Key_List = []
|
|
2090
|
+
tEXt_Str_List = []
|
|
2091
|
+
iTXt_String_List = []
|
|
2092
|
+
iTXt_Key_List = []
|
|
2093
|
+
tRNS_Index = []
|
|
2094
|
+
zTXt_Key_List = []
|
|
2095
|
+
zTXt_Str_List = []
|
|
2096
|
+
ThksForTheFish = []
|
|
2097
|
+
SideNotes = []
|
|
2098
|
+
DebugNotes = []
|
|
2099
|
+
TerminalTranscript = []
|
|
2100
|
+
ERRORSFLAG = []
|
|
2101
|
+
|
|
2102
|
+
PandoraBox = {}
|
|
2103
|
+
Cornucopia = {}
|
|
2104
|
+
IDAT_CRC_PATCH_FAILED = False
|
|
2105
|
+
IDAT_CRC_PATCH_FAILED_FINDING = None
|
|
2106
|
+
IDAT_CRC_DEFER_EXPLAINED = False
|
|
2107
|
+
IDAT_CRC_DEFERRED_FINDINGS = set()
|
|
2108
|
+
IDAT_CRC_DEFERRED_ROUTES = set()
|
|
2109
|
+
IDAT_DEFLATE_PROBE_KEYS = set()
|
|
2110
|
+
WRONG_CHUNK_NAME_TRIED_ROUTES = set()
|
|
2111
|
+
REPAIR_ROUTE_STATES = {}
|
|
2112
|
+
NEARBY_FOUND_LATER_IEND = None
|
|
2113
|
+
FOG_OF_WAR_BAD_CHUNKS = set()
|
|
2114
|
+
FOG_OF_WAR_LAST_MAP = None
|
|
2115
|
+
FOG_OF_WAR_LAST_WIDTH = None
|
|
2116
|
+
FOG_OF_WAR_LAST_RENDER_KEY = None
|
|
2117
|
+
FOG_OF_WAR_PREVIEW_CHUNK = None
|
|
2118
|
+
FOG_OF_WAR_PREVIEW_ERROR = False
|
|
2119
|
+
ArkOfCovenant = {}
|
|
2120
|
+
Pandemonium = {}
|
|
2121
|
+
CHUNK_INFO_STATE = chunk_state.ChunkInfoState()
|
|
2122
|
+
|
|
2123
|
+
|
|
2124
|
+
MAXCHAR = shutil.get_terminal_size(fallback=(120, 24)).columns - 1
|
|
2125
|
+
# TMPFIX = False
|
|
2126
|
+
|
|
2127
|
+
FirStart = True
|
|
2128
|
+
Switch = False
|
|
2129
|
+
GoBack = False
|
|
2130
|
+
CharPos = 1
|
|
2131
|
+
Loading_sep = ""
|
|
2132
|
+
PROGRESS_LINE_ACTIVE = False
|
|
2133
|
+
Have_A_KitKat = False
|
|
2134
|
+
TmpFixIHDR = False
|
|
2135
|
+
Warning = False
|
|
2136
|
+
Summary_Header = True
|
|
2137
|
+
Bad_Current_Name = False
|
|
2138
|
+
Bad_Ancillary = False
|
|
2139
|
+
Bad_No_Next_Chunk = False
|
|
2140
|
+
Bad_Next_Name = False
|
|
2141
|
+
Bad_Next_Ancillary = False
|
|
2142
|
+
Bad_Length = False
|
|
2143
|
+
Bad_Infos = False
|
|
2144
|
+
Bad_Crc = False
|
|
2145
|
+
Bad_Critical = False
|
|
2146
|
+
Bad_Missplaced = False
|
|
2147
|
+
Bad_Libpng = False
|
|
2148
|
+
Skip_Bad_Current_Name = False
|
|
2149
|
+
Skip_Bad_Ancillary = False
|
|
2150
|
+
Skip_Bad_No_Next_Chunk = False
|
|
2151
|
+
Skip_Bad_Next_Name = False
|
|
2152
|
+
Skip_Bad_Next_Ancillary = False
|
|
2153
|
+
Skip_Bad_Length = False
|
|
2154
|
+
Skip_Bad_Infos = False
|
|
2155
|
+
Skip_Bad_Crc = False
|
|
2156
|
+
Skip_Bad_Critical = False
|
|
2157
|
+
Skip_Bad_Missplaced = False
|
|
2158
|
+
Skip_Bad_Libpng = False
|
|
2159
|
+
EOF = False
|
|
2160
|
+
Show_Must_Go_On = False
|
|
2161
|
+
CLEAR = False
|
|
2162
|
+
CLEAR_SCREEN_ACTIVE_THIS_PASS = False
|
|
2163
|
+
LAST_QUESTION_STATUS = None
|
|
2164
|
+
FINAL_IMAGE_OPEN_REQUESTED = False
|
|
2165
|
+
CRASH = False
|
|
2166
|
+
PAUSE = False
|
|
2167
|
+
DEBUG = False
|
|
2168
|
+
DEBUGFILE = False
|
|
2169
|
+
PAUSEDEBUG = False
|
|
2170
|
+
PAUSEERROR = False
|
|
2171
|
+
PAUSEDIALOGUE = False
|
|
2172
|
+
DIALOGUE_PAUSE_STATE = ui_runtime.LegacyDialoguePauseState()
|
|
2173
|
+
NODIALOGUE = False
|
|
2174
|
+
AUTO = False
|
|
2175
|
+
COLOR_MODE = "auto"
|
|
2176
|
+
USE_COLOR = os.name != "nt"
|
|
2177
|
+
CLONESWAR = False
|
|
2178
|
+
MAX_SAVES = None
|
|
2179
|
+
SAVE_COUNT = 0
|
|
2180
|
+
ULTIMATE_LINEFEED_PREVIEW_TIMEOUT = 5.0
|
|
2181
|
+
ULTIMATE_LINEFEED_SHOW_PREVIEWS = False
|
|
2182
|
+
ULTIMATE_LINEFEED_REFERENCE_MODE = "exact"
|
|
2183
|
+
ULTIMATE_LINEFEED_REFERENCE_REGIONS = ""
|
|
2184
|
+
ULTIMATE_LINEFEED_REFERENCE_REGION_EDITOR = False
|
|
2185
|
+
ULTIMATE_LINEFEED_VISUAL_GALLERY_LIMIT = 100
|
|
2186
|
+
ULTIMATE_LINEFEED_VISUAL_MIN_COVERAGE = 0.95
|
|
2187
|
+
ULTIMATE_LINEFEED_RESUME = "ask"
|
|
2188
|
+
ULTIMATE_LINEFEED_LIVE_PREVIEW_FOLDER_REPORTED = ""
|
|
2189
|
+
SMASH_BRUTE_BRAWL_RESUME = "ask"
|
|
2190
|
+
SMASH_BRUTE_BRAWL_WORKERS = None
|
|
2191
|
+
|
|
2192
|
+
FishPos = 0
|
|
2193
|
+
LenFishList = 0
|
|
2194
|
+
Brute_LvL = 0
|
|
2195
|
+
IBN = 0
|
|
2196
|
+
IDAT_Bytes_Len = 0
|
|
2197
|
+
IDAT_Datastream = ""
|
|
2198
|
+
idatcounter = 0
|
|
2199
|
+
ETA = 0
|
|
2200
|
+
Old_Bad_Crc = ""
|
|
2201
|
+
IDAT_Avg_Len = ""
|
|
2202
|
+
FILE_Origin = ""
|
|
2203
|
+
FILE_DIR = ""
|
|
2204
|
+
Loading_txt = ""
|
|
2205
|
+
DIFF = ""
|
|
2206
|
+
DATAX = ""
|
|
2207
|
+
DATA_BYTES = b""
|
|
2208
|
+
Sample_Name = ""
|
|
2209
|
+
Sample = ""
|
|
2210
|
+
|
|
2211
|
+
Raw_Length = ""
|
|
2212
|
+
Raw_Data = ""
|
|
2213
|
+
Raw_Crc = ""
|
|
2214
|
+
Raw_NextChunk = ""
|
|
2215
|
+
Raw_Type = ""
|
|
2216
|
+
Orig_CL = ""
|
|
2217
|
+
Orig_CT = ""
|
|
2218
|
+
Orig_NC = ""
|
|
2219
|
+
Orig_CD = ""
|
|
2220
|
+
Orig_CRC = ""
|
|
2221
|
+
CLoffX = ""
|
|
2222
|
+
CLoffB = ""
|
|
2223
|
+
CLoffI = ""
|
|
2224
|
+
CToffX = ""
|
|
2225
|
+
CToffB = ""
|
|
2226
|
+
CToffI = ""
|
|
2227
|
+
NCoffX = ""
|
|
2228
|
+
NCoffB = ""
|
|
2229
|
+
NCoffI = ""
|
|
2230
|
+
NCoff_CRC = ""
|
|
2231
|
+
Bad_Ancillary = ""
|
|
2232
|
+
CDoffX = ""
|
|
2233
|
+
CDoffB = ""
|
|
2234
|
+
CDoffI = ""
|
|
2235
|
+
CrcoffX = ""
|
|
2236
|
+
CrcoffB = ""
|
|
2237
|
+
CrcoffI = ""
|
|
2238
|
+
iCCP_Name = ""
|
|
2239
|
+
iCCP_Method = ""
|
|
2240
|
+
iCCP_Profile = ""
|
|
2241
|
+
IHDR_Height = 0
|
|
2242
|
+
IHDR_Width = 0
|
|
2243
|
+
IHDR_Depht = ""
|
|
2244
|
+
IHDR_Color = ""
|
|
2245
|
+
IHDR_Method = ""
|
|
2246
|
+
IHDR_Filter = ""
|
|
2247
|
+
IHDR_Interlace = ""
|
|
2248
|
+
bKGD_Gray = ""
|
|
2249
|
+
bKGD_Red = ""
|
|
2250
|
+
bKGD_Green = ""
|
|
2251
|
+
bKGD_Blue = ""
|
|
2252
|
+
bKGD_Index = ""
|
|
2253
|
+
sRGB = ""
|
|
2254
|
+
|
|
2255
|
+
pCAL_Key = ""
|
|
2256
|
+
pCAL_Zero = ""
|
|
2257
|
+
pCAL_Max = ""
|
|
2258
|
+
pCAL_Eq = ""
|
|
2259
|
+
pCAL_PNBR = ""
|
|
2260
|
+
|
|
2261
|
+
cHRM_WhiteX = ""
|
|
2262
|
+
cHRM_WhiteY = ""
|
|
2263
|
+
cHRM_Redx = ""
|
|
2264
|
+
cHRM_Redy = ""
|
|
2265
|
+
cHRM_Greenx = ""
|
|
2266
|
+
cHRM_Greeny = ""
|
|
2267
|
+
cHRM_Bluex = ""
|
|
2268
|
+
cHRM_Bluey = ""
|
|
2269
|
+
|
|
2270
|
+
gAMA = ""
|
|
2271
|
+
|
|
2272
|
+
pHYs_Y = ""
|
|
2273
|
+
pHYs_X = ""
|
|
2274
|
+
pHYs_Unit = ""
|
|
2275
|
+
sTER = ""
|
|
2276
|
+
gIFID = ""
|
|
2277
|
+
gIFCD = ""
|
|
2278
|
+
gIFDT = ""
|
|
2279
|
+
gIFgM = ""
|
|
2280
|
+
gIFgU = ""
|
|
2281
|
+
gIFgT = ""
|
|
2282
|
+
|
|
2283
|
+
sBIT_Gray = ""
|
|
2284
|
+
sBIT_TrueR = ""
|
|
2285
|
+
sBIT_TrueG = ""
|
|
2286
|
+
sBIT_TrueB = ""
|
|
2287
|
+
sBIT_GrayScale = ""
|
|
2288
|
+
sBIT_GrayAlpha = ""
|
|
2289
|
+
sBIT_TrueAlphaR = ""
|
|
2290
|
+
sBIT_TrueAlphaG = ""
|
|
2291
|
+
sBIT_TrueAlphaB = ""
|
|
2292
|
+
sBIT_TrueAlpha = ""
|
|
2293
|
+
|
|
2294
|
+
tEXt_Key = ""
|
|
2295
|
+
tEXt_Text = ""
|
|
2296
|
+
|
|
2297
|
+
iTXt_String = ""
|
|
2298
|
+
iTXt_Key = ""
|
|
2299
|
+
tIME_Yr = ""
|
|
2300
|
+
tIME_Mth = ""
|
|
2301
|
+
tIME_Day = ""
|
|
2302
|
+
tIME_Hr = ""
|
|
2303
|
+
tIME_Min = ""
|
|
2304
|
+
tIME_Sec = ""
|
|
2305
|
+
tRNS_Gray = ""
|
|
2306
|
+
tRNS_TrueR = ""
|
|
2307
|
+
tRNS_TrueG = ""
|
|
2308
|
+
tRNS_TrueB = ""
|
|
2309
|
+
|
|
2310
|
+
zTXt_Key = ""
|
|
2311
|
+
zTXt_Meth = ""
|
|
2312
|
+
zTXt_Text = ""
|
|
2313
|
+
eXIf_endian = ""
|
|
2314
|
+
|
|
2315
|
+
Web_Safe_Colors =['000000', '000033', '000066', '000099', '0000cc', '0000ff', '003300', '003333', '003366', '003399', '0033cc', '0033ff', '006600', '006633', '006666', '006699', '0066cc', '0066ff', '009900', '009933', '009966', '009999', '0099cc', '0099ff', '00cc00', '00cc33', '00cc66', '00cc99', '00cccc', '00ccff', '00ff00', '00ff33', '00ff66', '00ff99', '00ffcc', '00ffff', '330000', '330033', '330066', '330099', '3300cc', '3300ff', '333300', '333333', '333366', '333399', '3333cc', '3333ff', '336600', '336633', '336666', '336699', '3366cc', '3366ff', '339900', '339933', '339966', '339999', '3399cc', '3399ff', '33cc00', '33cc33', '33cc66', '33cc99', '33cccc', '33ccff', '33ff00', '33ff33', '33ff66', '33ff99', '33ffcc', '33ffff', '660000', '660033', '660066', '660099', '6600cc', '6600ff', '663300', '663333', '663366', '663399', '6633cc', '6633ff', '666600', '666633', '666666', '666699', '6666cc', '6666ff', '669900', '669933', '669966', '669999', '6699cc', '6699ff', '66cc00', '66cc33', '66cc66', '66cc99', '66cccc', '66ccff', '66ff00', '66ff33', '66ff66', '66ff99', '66ffcc', '66ffff', '990000', '990033', '990066', '990099', '9900cc', '9900ff', '993300', '993333', '993366', '993399', '9933cc', '9933ff', '996600', '996633', '996666', '996699', '9966cc', '9966ff', '999900', '999933', '999966', '999999', '9999cc', '9999ff', '99cc00', '99cc33', '99cc66', '99cc99', '99cccc', '99ccff', '99ff00', '99ff33', '99ff66', '99ff99', '99ffcc', '99ffff', 'cc0000', 'cc0033', 'cc0066', 'cc0099', 'cc00cc', 'cc00ff', 'cc3300', 'cc3333', 'cc3366', 'cc3399', 'cc33cc', 'cc33ff', 'cc6600', 'cc6633', 'cc6666', 'cc6699', 'cc66cc', 'cc66ff', 'cc9900', 'cc9933', 'cc9966', 'cc9999', 'cc99cc', 'cc99ff', 'cccc00', 'cccc33', 'cccc66', 'cccc99', 'cccccc', 'ccccff', 'ccff00', 'ccff33', 'ccff66', 'ccff99', 'ccffcc', 'ccffff', 'ff0000', 'ff0033', 'ff0066', 'ff0099', 'ff00cc', 'ff00ff', 'ff3300', 'ff3333', 'ff3366', 'ff3399', 'ff33cc', 'ff33ff', 'ff6600', 'ff6633', 'ff6666', 'ff6699', 'ff66cc', 'ff66ff', 'ff9900', 'ff9933', 'ff9966', 'ff9999', 'ff99cc', 'ff99ff', 'ffcc00', 'ffcc33', 'ffcc66', 'ffcc99', 'ffcccc', 'ffccff', 'ffff00', 'ffff33', 'ffff66', 'ffff99', 'ffffcc', 'ffffff']
|
|
2316
|
+
|
|
2317
|
+
X11_Colors =[
|
|
2318
|
+
"000000",
|
|
2319
|
+
"800000",
|
|
2320
|
+
"008000",
|
|
2321
|
+
"808000",
|
|
2322
|
+
"000080",
|
|
2323
|
+
"800080",
|
|
2324
|
+
"008080",
|
|
2325
|
+
"c0c0c0",
|
|
2326
|
+
"808080",
|
|
2327
|
+
"ff0000",
|
|
2328
|
+
"00ff00",
|
|
2329
|
+
"ffff00",
|
|
2330
|
+
"0000ff",
|
|
2331
|
+
"ff00ff",
|
|
2332
|
+
"00ffff",
|
|
2333
|
+
"ffffff",
|
|
2334
|
+
"000000",
|
|
2335
|
+
"00005f",
|
|
2336
|
+
"000087",
|
|
2337
|
+
"0000af",
|
|
2338
|
+
"0000d7",
|
|
2339
|
+
"0000ff",
|
|
2340
|
+
"005f00",
|
|
2341
|
+
"005f5f",
|
|
2342
|
+
"005f87",
|
|
2343
|
+
"005faf",
|
|
2344
|
+
"005fd7",
|
|
2345
|
+
"005fff",
|
|
2346
|
+
"008700",
|
|
2347
|
+
"00875f",
|
|
2348
|
+
"008787",
|
|
2349
|
+
"0087af",
|
|
2350
|
+
"0087d7",
|
|
2351
|
+
"0087ff",
|
|
2352
|
+
"00af00",
|
|
2353
|
+
"00af5f",
|
|
2354
|
+
"00af87",
|
|
2355
|
+
"00afaf",
|
|
2356
|
+
"00afd7",
|
|
2357
|
+
"00afff",
|
|
2358
|
+
"00d700",
|
|
2359
|
+
"00d75f",
|
|
2360
|
+
"00d787",
|
|
2361
|
+
"00d7af",
|
|
2362
|
+
"00d7d7",
|
|
2363
|
+
"00d7ff",
|
|
2364
|
+
"00ff00",
|
|
2365
|
+
"00ff5f",
|
|
2366
|
+
"00ff87",
|
|
2367
|
+
"00ffaf",
|
|
2368
|
+
"00ffd7",
|
|
2369
|
+
"00ffff",
|
|
2370
|
+
"5f0000",
|
|
2371
|
+
"5f005f",
|
|
2372
|
+
"5f0087",
|
|
2373
|
+
"5f00af",
|
|
2374
|
+
"5f00d7",
|
|
2375
|
+
"5f00ff",
|
|
2376
|
+
"5f5f00",
|
|
2377
|
+
"5f5f5f",
|
|
2378
|
+
"5f5f87",
|
|
2379
|
+
"5f5faf",
|
|
2380
|
+
"5f5fd7",
|
|
2381
|
+
"5f5fff",
|
|
2382
|
+
"5f8700",
|
|
2383
|
+
"5f875f",
|
|
2384
|
+
"5f8787",
|
|
2385
|
+
"5f87af",
|
|
2386
|
+
"5f87d7",
|
|
2387
|
+
"5f87ff",
|
|
2388
|
+
"5faf00",
|
|
2389
|
+
"5faf5f",
|
|
2390
|
+
"5faf87",
|
|
2391
|
+
"5fafaf",
|
|
2392
|
+
"5fafd7",
|
|
2393
|
+
"5fafff",
|
|
2394
|
+
"5fd700",
|
|
2395
|
+
"5fd75f",
|
|
2396
|
+
"5fd787",
|
|
2397
|
+
"5fd7af",
|
|
2398
|
+
"5fd7d7",
|
|
2399
|
+
"5fd7ff",
|
|
2400
|
+
"5fff00",
|
|
2401
|
+
"5fff5f",
|
|
2402
|
+
"5fff87",
|
|
2403
|
+
"5fffaf",
|
|
2404
|
+
"5fffd7",
|
|
2405
|
+
"5fffff",
|
|
2406
|
+
"870000",
|
|
2407
|
+
"87005f",
|
|
2408
|
+
"870087",
|
|
2409
|
+
"8700af",
|
|
2410
|
+
"8700d7",
|
|
2411
|
+
"8700ff",
|
|
2412
|
+
"875f00",
|
|
2413
|
+
"875f5f",
|
|
2414
|
+
"875f87",
|
|
2415
|
+
"875faf",
|
|
2416
|
+
"875fd7",
|
|
2417
|
+
"875fff",
|
|
2418
|
+
"878700",
|
|
2419
|
+
"87875f",
|
|
2420
|
+
"878787",
|
|
2421
|
+
"8787af",
|
|
2422
|
+
"8787d7",
|
|
2423
|
+
"8787ff",
|
|
2424
|
+
"87af00",
|
|
2425
|
+
"87af5f",
|
|
2426
|
+
"87af87",
|
|
2427
|
+
"87afaf",
|
|
2428
|
+
"87afd7",
|
|
2429
|
+
"87afff",
|
|
2430
|
+
"87d700",
|
|
2431
|
+
"87d75f",
|
|
2432
|
+
"87d787",
|
|
2433
|
+
"87d7af",
|
|
2434
|
+
"87d7d7",
|
|
2435
|
+
"87d7ff",
|
|
2436
|
+
"87ff00",
|
|
2437
|
+
"87ff5f",
|
|
2438
|
+
"87ff87",
|
|
2439
|
+
"87ffaf",
|
|
2440
|
+
"87ffd7",
|
|
2441
|
+
"87ffff",
|
|
2442
|
+
"af0000",
|
|
2443
|
+
"af005f",
|
|
2444
|
+
"af0087",
|
|
2445
|
+
"af00af",
|
|
2446
|
+
"af00d7",
|
|
2447
|
+
"af00ff",
|
|
2448
|
+
"af5f00",
|
|
2449
|
+
"af5f5f",
|
|
2450
|
+
"af5f87",
|
|
2451
|
+
"af5faf",
|
|
2452
|
+
"af5fd7",
|
|
2453
|
+
"af5fff",
|
|
2454
|
+
"af8700",
|
|
2455
|
+
"af875f",
|
|
2456
|
+
"af8787",
|
|
2457
|
+
"af87af",
|
|
2458
|
+
"af87d7",
|
|
2459
|
+
"af87ff",
|
|
2460
|
+
"afaf00",
|
|
2461
|
+
"afaf5f",
|
|
2462
|
+
"afaf87",
|
|
2463
|
+
"afafaf",
|
|
2464
|
+
"afafd7",
|
|
2465
|
+
"afafff",
|
|
2466
|
+
"afd700",
|
|
2467
|
+
"afd75f",
|
|
2468
|
+
"afd787",
|
|
2469
|
+
"afd7af",
|
|
2470
|
+
"afd7d7",
|
|
2471
|
+
"afd7ff",
|
|
2472
|
+
"afff00",
|
|
2473
|
+
"afff5f",
|
|
2474
|
+
"afff87",
|
|
2475
|
+
"afffaf",
|
|
2476
|
+
"afffd7",
|
|
2477
|
+
"afffff",
|
|
2478
|
+
"d70000",
|
|
2479
|
+
"d7005f",
|
|
2480
|
+
"d70087",
|
|
2481
|
+
"d700af",
|
|
2482
|
+
"d700d7",
|
|
2483
|
+
"d700ff",
|
|
2484
|
+
"d75f00",
|
|
2485
|
+
"d75f5f",
|
|
2486
|
+
"d75f87",
|
|
2487
|
+
"d75faf",
|
|
2488
|
+
"d75fd7",
|
|
2489
|
+
"d75fff",
|
|
2490
|
+
"d78700",
|
|
2491
|
+
"d7875f",
|
|
2492
|
+
"d78787",
|
|
2493
|
+
"d787af",
|
|
2494
|
+
"d787d7",
|
|
2495
|
+
"d787ff",
|
|
2496
|
+
"d7af00",
|
|
2497
|
+
"d7af5f",
|
|
2498
|
+
"d7af87",
|
|
2499
|
+
"d7afaf",
|
|
2500
|
+
"d7afd7",
|
|
2501
|
+
"d7afff",
|
|
2502
|
+
"d7d700",
|
|
2503
|
+
"d7d75f",
|
|
2504
|
+
"d7d787",
|
|
2505
|
+
"d7d7af",
|
|
2506
|
+
"d7d7d7",
|
|
2507
|
+
"d7d7ff",
|
|
2508
|
+
"d7ff00",
|
|
2509
|
+
"d7ff5f",
|
|
2510
|
+
"d7ff87",
|
|
2511
|
+
"d7ffaf",
|
|
2512
|
+
"d7ffd7",
|
|
2513
|
+
"d7ffff",
|
|
2514
|
+
"ff0000",
|
|
2515
|
+
"ff005f",
|
|
2516
|
+
"ff0087",
|
|
2517
|
+
"ff00af",
|
|
2518
|
+
"ff00d7",
|
|
2519
|
+
"ff00ff",
|
|
2520
|
+
"ff5f00",
|
|
2521
|
+
"ff5f5f",
|
|
2522
|
+
"ff5f87",
|
|
2523
|
+
"ff5faf",
|
|
2524
|
+
"ff5fd7",
|
|
2525
|
+
"ff5fff",
|
|
2526
|
+
"ff8700",
|
|
2527
|
+
"ff875f",
|
|
2528
|
+
"ff8787",
|
|
2529
|
+
"ff87af",
|
|
2530
|
+
"ff87d7",
|
|
2531
|
+
"ff87ff",
|
|
2532
|
+
"ffaf00",
|
|
2533
|
+
"ffaf5f",
|
|
2534
|
+
"ffaf87",
|
|
2535
|
+
"ffafaf",
|
|
2536
|
+
"ffafd7",
|
|
2537
|
+
"ffafff",
|
|
2538
|
+
"ffd700",
|
|
2539
|
+
"ffd75f",
|
|
2540
|
+
"ffd787",
|
|
2541
|
+
"ffd7af",
|
|
2542
|
+
"ffd7d7",
|
|
2543
|
+
"ffd7ff",
|
|
2544
|
+
"ffff00",
|
|
2545
|
+
"ffff5f",
|
|
2546
|
+
"ffff87",
|
|
2547
|
+
"ffffaf",
|
|
2548
|
+
"ffffd7",
|
|
2549
|
+
"ffffff",
|
|
2550
|
+
"080808",
|
|
2551
|
+
"121212",
|
|
2552
|
+
"1c1c1c",
|
|
2553
|
+
"262626",
|
|
2554
|
+
"303030",
|
|
2555
|
+
"3a3a3a",
|
|
2556
|
+
"444444",
|
|
2557
|
+
"4e4e4e",
|
|
2558
|
+
"585858",
|
|
2559
|
+
"606060",
|
|
2560
|
+
"666666",
|
|
2561
|
+
"767676",
|
|
2562
|
+
"808080",
|
|
2563
|
+
"8a8a8a",
|
|
2564
|
+
"949494",
|
|
2565
|
+
"9e9e9e",
|
|
2566
|
+
"a8a8a8",
|
|
2567
|
+
"b2b2b2",
|
|
2568
|
+
"bcbcbc",
|
|
2569
|
+
"c6c6c6",
|
|
2570
|
+
"d0d0d0",
|
|
2571
|
+
"dadada",
|
|
2572
|
+
"e4e4e4",
|
|
2573
|
+
"eeeeee"
|
|
2574
|
+
]
|
|
2575
|
+
|
|
2576
|
+
|
|
2577
|
+
if __name__ == "__main__":
|
|
2578
|
+
main()
|