#!/usr/bin/env python3 """ Phase 10 step 1.5: 修补 hiyori-assets.bin 让 hiyori GIF 黑色背景变透明 ESP Emote GFX Packer 在线工具导出 EAF 时把 GIF 透明像素填充为不透明黑色 (palette idx ? = BGRA 0x00 0x00 0x00 0xFF),导致叠加到背景图上显示黑色矩形。 本脚本直接 patch .bin 文件内嵌的 EAF 数据: 1. 解析 MMAP bin 找每个 EAF 资源 2. 对每个 EAF 解析每帧 header → 找 palette 中 RGB=黑色 entry 3. 把这些 entry 的 alpha 字节从 0xFF 改 0x00(让 idx 视为透明) 4. 重算 EAF stored_chk 写回 EAF frame header layout (from gfx_eaf_dec.c): [9] bit_depth (1B): 4/8/24 [10-11] width [12-13] height [14-15] blocks [16-17] block_height [18+] block_len table: blocks × 4B [+] palette: num_colors × 4B (BGRA) [+] data EAF main header (from gfx_eaf_dec.h): [0] format magic 0x89 [1-3] "EAF" [4-7] total_frames (uint32 LE) [8-11] stored_chk (uint32 LE) [12-15] stored_len (uint32 LE) [16+] frame table: total_frames × 8B (frame_size + frame_offset) [16 + total_frames*8] frame data (each frame: 2B 0x5A5A magic + frame_header + data) """ import sys import struct from pathlib import Path BIN_PATH = Path(__file__).parent.parent / "spiffs_image" / "hiyori-assets.bin" def patch_eaf(eaf_bytes: bytearray) -> int: """对单个 EAF 二进制内容做透明 patch,返回修改的 palette entry 数""" # 校验 EAF magic if eaf_bytes[0] != 0x89 or eaf_bytes[1:4] not in (b"EAF", b"AAF"): raise ValueError(f"非 EAF/AAF 数据 (开头: {eaf_bytes[:4].hex()})") total_frames = struct.unpack(" len(eaf_bytes): print(f" ❌ frame {fi} 偏移越界 (abs={abs_frame_pos}, total={len(eaf_bytes)})") continue # 验证 frame magic if eaf_bytes[abs_frame_pos] != 0x5A or eaf_bytes[abs_frame_pos+1] != 0x5A: print(f" ❌ frame {fi} magic 错误 (got {eaf_bytes[abs_frame_pos]:#x} {eaf_bytes[abs_frame_pos+1]:#x})") continue # frame_header 从 magic 后开始,但 BIT_DEPTH_OFFSET = 9 是相对什么? # 看 gfx_eaf_dec.c line 198: file_data[EAF_FRAME_BIT_DEPTH_OFFSET] # 其中 file_data = entries[i].frame_mem (注:含 0x5A5A magic 前缀) # 所以 file_data + 9 = 帧 magic 前缀之后第 7 字节 # layout (相对 abs_frame_pos): # [0-1] 0x5A 0x5A magic # [2-8] format (3) + version (4) # [9] bit_depth # [10-11] width # [12-13] height # [14-15] blocks # [16-17] block_height # [18+] block_len: blocks × 4B # [+] palette: (1<