adeed manual processing using UVtools

This commit is contained in:
cpu
2026-06-12 13:36:22 +02:00
parent a731b064b6
commit 9a8635aa98
11 changed files with 340 additions and 38 deletions

View File

@@ -0,0 +1,76 @@
#!/usr/bin/env python3
"""
Decode the composite block and first layer block from a pm4n file,
report pixel counts and first/last pixel values.
Run: python3 decode_rle_blocks.py output/pm4n/Flow_Controller_Panel-Front.pm4n
"""
import struct, sys
path = sys.argv[1]
data = open(path, 'rb').read()
fsize = len(data)
print(f"File: {path} ({fsize} bytes)\n")
LAYE_HDR = 0x20
STRIDE = 0x20
laye = data.find(b'LAYE')
n_entries = struct.unpack_from('<I', data, laye + 0x10)[0]
composite_off = struct.unpack_from('<I', data, laye + 0x14)[0]
block_size = struct.unpack_from('<I', data, laye + 0x18)[0]
print(f"LAYE n_entries={n_entries} composite_off=0x{composite_off:06X} block_size={block_size}")
def decode_rle(data, offset, max_bytes):
"""Decode RLE starting at offset, stop after max_bytes read. Returns pixel list."""
pixels = []
i = offset
end = min(offset + max_bytes, len(data))
while i + 1 < end:
b0 = data[i]; b1 = data[i+1]
nibble = (b0 >> 4) & 0xF
colour = 255 if nibble == 0xF else 0
run = ((b0 & 0x0F) << 8) | b1
run += 1
pixels.extend([colour] * run)
i += 2
return pixels, i - offset
def summarize_block(name, offset, size):
print(f"\n{name} at 0x{offset:06X}, {size} bytes:")
if offset + size > fsize:
print(f" *** PAST EOF (file ends at 0x{fsize:06X}) ***")
size = max(0, fsize - offset)
# Show first 16 bytes raw
raw = data[offset:offset+16]
print(f" First 16 bytes: {raw.hex()}")
# Decode RLE
pixels, bytes_consumed = decode_rle(data, offset, size)
print(f" Decoded: {len(pixels)} pixels from {bytes_consumed} bytes")
print(f" Expected: {9024*5120} pixels ({9024}×{5120})")
if pixels:
whites = sum(1 for p in pixels if p >= 128)
blacks = len(pixels) - whites
print(f" White px: {whites} ({100*whites/len(pixels):.1f}%)")
print(f" Black px: {blacks} ({100*blacks/len(pixels):.1f}%)")
# Check if it decodes to correct pixel count
if len(pixels) == 9024 * 5120:
print(f" ✓ Correct pixel count")
else:
print(f" *** WRONG pixel count (off by {len(pixels) - 9024*5120})")
# Show first few runs
print(f" First pixels: {pixels[:20]}")
# Composite block
summarize_block("Composite block (block 0)", composite_off, block_size)
# First entry block
e0_base = laye + LAYE_HDR
e0_data_off = struct.unpack_from('<I', data, e0_base + 0x14)[0]
e0_data_sz = struct.unpack_from('<I', data, e0_base + 0x18)[0]
summarize_block("Entry[0] block", e0_data_off, e0_data_sz)