世嘉BZ与BZW解压算法剖析

💡 原文中文,约4000字,阅读约需10分钟。
📝

内容提要

本文解析世嘉Dreamcast与PS2游戏中的LZSS压缩变体BZ和BZW。BZ以字节为单位,用8位控制掩码区分明文与引用,短引用1字节、长引用2字节,以长引用长度0作EOF。BZW以16位字为单位,用16位掩码,需字节交换,以长度1作EOF。两者通过控制掩码、引用编码和回溯复制实现解压,兼顾存储与读取效率。

🔎

延伸解读

控制掩码与引用编码的配合

BZ 和 BZW 都依赖控制掩码来区分明文与引用,但掩码本身不携带数据,只指示操作类型。BZ 用 8 位掩码控制 8 次操作,BZW 用 16 位掩码控制 16 次操作。引用编码则负责描述回溯距离和复制长度,短引用和长引用的设计让解压器能根据数据局部性灵活选择。这种分离设计使解压流程清晰,但也要求掩码与后续数据严格同步,否则解码会错位。

短引用与长引用的取舍

BZ 的短引用仅占 1 字节,可表示长度 2~9、回溯距离 1~16 字节的重复片段;长引用占 2 字节,长度可达 2~256,回溯距离 1~128 字节。短引用适合近距离小段重复,长引用适合远距离大段重复。这种双编码策略在压缩率和解压速度之间取得平衡,但短引用的回溯范围有限,不能误以为整个 BZ 的回溯距离只有 16 字节。

BZW 的字节序处理与输出转换

BZW 以 16 位字为单位,控制掩码和引用字段在读取后需交换高低字节,因为格式源自大端序设计,而 PS2 是小端序平台。明文读取和引用解析都按字操作,回溯距离以字为单位。解压完成后,每个字按低字节在前、高字节在后的顺序展平为字节流。这些字节序细节是正确还原数据的关键,忽略它们会导致输出完全错误。

EOF 标记的保留值复用

BZ 将长引用中长度编码为 0 的情况用作流结束标记,因为正常长引用长度至少为 2;BZW 则使用长度编码为 1 作为 EOF,因为正常引用不会生成单字引用。这种保留值复用节省了额外的结束标记字节,但属于具体格式的约定,并非所有 LZSS 变体都采用相同方式。逆向时需结合样本验证,不能直接套用其他算法的 EOF 规则。

❓

Q&A

BZ和BZW压缩算法分别用在哪些游戏机上?

BZ和BZW是世嘉Dreamcast与PlayStation 2游戏中出现的LZSS类压缩算法变体。

BZ算法中控制掩码是如何工作的?

BZ每次读取一个控制字节,其中的8个比特分别控制接下来的8次解码操作。bit=1表示明文,直接输出下一个字节;bit=0表示引用,读取引用信息并回溯复制。

BZ的短引用和长引用有什么区别?

短引用占1字节,长度2~9,回溯距离1~16字节;长引用占2字节,正常长度2~256,回溯距离1~128字节。短引用适合近距短重复,长引用适合远距长重复。

BZW为什么需要进行字节交换?

BZW格式是大端序设计(Saturn血统),而PS2是小端序平台,因此控制掩码和引用字段必须做字节交换,字面字则不需要。

BZ和BZW的EOF标记分别是什么?

BZ用长引用中第二个字节为0(即length=0)作为流结束标记;BZW使用长度编码1作为特殊结束标记。

BZ和BZW在解码单位和回溯距离上有什么主要区别?

BZ以1字节为解码单位,短引用回溯1~16字节,长引用回溯1~128字节;BZW以1个word(2字节)为单位,回溯距离1~256 word,即2~512字节。

🏷️

标签

➡️

继续阅读