From 8af857d45a56db656954873dd782bc8c6b46028b Mon Sep 17 00:00:00 2001 From: AskaEth Date: Thu, 27 Aug 2026 09:25:18 +0800 Subject: [PATCH] Fix luni block: missing 4-byte character count field The unicode layer name block must be [char_count(4B)][utf-16-be chars]. We wrote raw utf-16 without the count, so Photoshop read the first characters as the length, shifted the entire extra-data parse, and every layer's pixels came out empty (all layers transparent). Fixed: name now reads back correctly and 167/167 layers match the rendered originals (mean diff 0.000). --- ppl2psd.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ppl2psd.py b/ppl2psd.py index 8f6dc52..612dafe 100644 --- a/ppl2psd.py +++ b/ppl2psd.py @@ -508,9 +508,12 @@ def _layer_record(top, left, bottom, right, name, opacity, visible, channels, pad = (-len(extra)) % 4 if pad: extra += b"\x00" * pad - # luni: unicode layer name + # luni: unicode layer name. Data = 4-byte CHARACTER count + utf-16-be + # chars. (Writing raw utf-16 without the count shifts the extra-data + # parse and Photoshop reads every layer's pixels as empty.) uni = name.encode("utf-16-be") - extra += b"8BIMluni" + struct.pack(">I", len(uni)) + uni + luni_data = struct.pack(">I", len(uni) // 2) + uni + extra += b"8BIMluni" + struct.pack(">I", len(luni_data)) + luni_data # standard blocks Photoshop expects (see _standard_blocks) extra += _standard_blocks(layer_id) rec += struct.pack(">I", len(extra))