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



我正在Gameboy Advance的游戏中做逆向工程,我注意到原始开发人员编写了一段代码,其中包含两个系统调用,以使用Huffman和lz77(按此顺序)解压缩关卡。

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

使用可用的库

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

为什么霍夫曼和LZ77?

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

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

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

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

面向字母的霍夫曼擅长仅使用字母频率来检测和压缩文件,但它无法检测连续字母(常用词和音节)之间的相关性。

LZ77将原始文件压缩为文字字母和"复制项目"的中间序列。 然后霍夫曼进一步压缩了这个中间序列。 通常,如果我们跳过 LZ77 步骤并简单地压缩原始文件,这些"复制项"已经比原始子字符串短得多。 霍夫曼在压缩中间序列中的文字字母就像压缩原始文件中的字母一样好。

因此,这个 2 步过程已经创建的文件比单独的任何一种算法都要小。 作为奖励,通常复制项目也会被霍夫曼压缩,以节省更多的存储空间。

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

最新更新