为什么要结合霍夫曼和lz77?

Why to combine Huffman and lz77?

我正在对 Gameboy Advance 的游戏进行逆向工程,我注意到原始开发人员编写的代码有两个系统调用,使用 Huffman 和 lz77(按此顺序)解压缩关卡。

但是为什么要用哈夫曼+lzZ7呢?这种方法有什么优势?

使用可用的库

开发人员可能正在使用 DEFLATE(或一些类似的算法),只是为了能够重新使用经过测试和调试的软件,而不是从头开始编写新的东西(并花费谁知道多长时间测试并修复所有古怪的边缘情况)。

为什么霍夫曼和 LZ77 都是?

但为什么 DEFLATE、Zstandard、LZHAM、LZHUF、LZH 等同时使用 Huffman 和 LZ77?

因为这 2 种算法检测并去除了很多数据文件(视频游戏关卡、英语和其他自然语言文本等)共有的 2 种不同类型的冗余,并且可以将它们结合起来以获得更好的净压缩比任何一个单独。 (不幸的是,大多数数据压缩算法不能像这样组合)。

详情

在英语中,最常见的 2 个字母(通常)是 'e',然后是 't'。 那么最常见的一对是什么?您可能会猜到 "ee"、"et" 或 "te"——不,它是 "th"。

LZ77 擅长检测和压缩这些常见的单词和音节,这些单词和音节的出现频率远远超过您仅根据字母频率猜测的频率。

Letter-oriented Huffman擅长单独使用字母频率检测和压缩文件,但无法检测连续字母(常用词和音节)之间的相关性。

LZ77 将原始文件压缩成文字字母和 "copy items" 的中间序列。 然后霍夫曼进一步压缩该中间序列。 通常那些 "copy items" 已经比原始子字符串短得多,如果我们跳过 LZ77 步骤并简单地使用 Huffman 压缩原始文件的话。 霍夫曼压缩中间序列中的文字字母与压缩原始文件中的相同字母一样好。

所以这个两步过程创建的文件已经比单独使用任何一种算法都要小。 作为奖励,通常副本项目也会进行霍夫曼压缩,以节省更多存储空间 space。

一般来说,大多数数据压缩软件都是由这两部分组成的。 首先,他们 运行 原始数据通过“transformation" or multiple transformations,也称为 "decorrelators",通常高度调整到被压缩的特定类型数据中的特定类型的冗余(JPEG 的 DCT 变换,MPEG 的运动补偿等)或调整到人类感知的局限性(MP3 的听觉掩蔽等)。 接下来他们 运行 通过单个“entropy coder”(算术编码,或霍夫曼编码,或非对称数字系统编码)的中间数据,这对于每种数据几乎都是相同的。