added export to pm4n
This commit is contained in:
62
scripts/diagnose_pm4n.py
Normal file
62
scripts/diagnose_pm4n.py
Normal file
@@ -0,0 +1,62 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Run this on your machine: python3 diagnose_pm4n.py Dummy.pm4n"""
|
||||
import struct, sys
|
||||
|
||||
path = sys.argv[1] if len(sys.argv) > 1 else 'Dummy.pm4n'
|
||||
data = open(path, 'rb').read()
|
||||
fsize = len(data)
|
||||
print(f"File: {path} ({fsize} bytes)")
|
||||
print()
|
||||
|
||||
# Parse ANYCUBIC header
|
||||
magic = data[0:8]
|
||||
version = struct.unpack_from('<I', data, 8)[0]
|
||||
n_sections = struct.unpack_from('<I', data, 12)[0]
|
||||
header_size = struct.unpack_from('<I', data, 16)[0]
|
||||
print(f"Magic: {magic}")
|
||||
print(f"Bytes 8-11: {data[8:12].hex()} (={version})")
|
||||
print(f"Section count: {n_sections}")
|
||||
print(f"Header size: {header_size} (0x{header_size:X})")
|
||||
print()
|
||||
|
||||
# Section table: n_sections entries of (offset:u32, length:u32) starting at byte 20
|
||||
print(f"Section table ({n_sections} entries from offset 20):")
|
||||
sections = []
|
||||
for i in range(n_sections):
|
||||
base = 20 + i * 8
|
||||
if base + 8 > fsize:
|
||||
break
|
||||
off = struct.unpack_from('<I', data, base)[0]
|
||||
ln = struct.unpack_from('<I', data, base+4)[0]
|
||||
sections.append((off, ln))
|
||||
|
||||
for idx, (off, ln) in enumerate(sections):
|
||||
tag = data[off:off+4] if off + 4 <= fsize else b'????'
|
||||
tag_str = tag.decode('ascii', errors='replace')
|
||||
print(f" [{idx:2d}] offset=0x{off:06X} ({off:7d}) length={ln:7d} tag@offset={tag_str!r}")
|
||||
|
||||
print()
|
||||
# Also peek at each section start for tag-like content
|
||||
print("Content at each section offset (first 32 bytes):")
|
||||
for idx, (off, ln) in enumerate(sections):
|
||||
if off + 16 <= fsize:
|
||||
chunk = data[off:off+32]
|
||||
# Try to find sub-tags
|
||||
for sub_off in range(0, min(32, len(chunk))-3):
|
||||
sub_tag = chunk[sub_off:sub_off+4]
|
||||
if all(32 <= b < 127 for b in sub_tag):
|
||||
sub_len = struct.unpack_from('<I', chunk, sub_off+4)[0] if sub_off+8 <= len(chunk) else 0
|
||||
print(f" section[{idx}]+0x{sub_off:02X} tag={sub_tag.decode()!r} next_u32={sub_len}")
|
||||
break
|
||||
else:
|
||||
print(f" section[{idx}] hex: {chunk[:16].hex()}")
|
||||
|
||||
print()
|
||||
# Look for exposure-like floats (1.0 to 600.0) across the whole file
|
||||
print("Float values in range [1.0 .. 600.0] across whole file:")
|
||||
for off in range(0, fsize - 3, 4):
|
||||
v = struct.unpack_from('<f', data, off)[0]
|
||||
if 1.0 <= v <= 600.0 and v == round(v, 1):
|
||||
# Show context
|
||||
section_hint = next((f"sec[{i}]+{off-s:d}" for i,(s,l) in enumerate(sections) if s <= off < s+l), "outside")
|
||||
print(f" 0x{off:06X} {v:.1f} ({section_hint})")
|
||||
Reference in New Issue
Block a user