Deflate算法解读

gzip 使用deflate算法进行压缩。
通用类库为zlib,由LZ77+Huffman共同实现。

1、 LZ77算法简介
这一算法是由Jacob Ziv 和 Abraham Lempel 于 1977 年提出,所以命名为 LZ77,被一些人称为字典算法。

2、 LZ77算法的压缩原理
如果文件中有两块内容相同的话,那么只要知道前一块的位置和大小,我们就可以确定后一块的内容。
所以我们可以用(两者之间的距离,相同内容的长度)这样一对信息,来替换后一块内容。
由于(两者之间的距离,相同内容的长度)这一对信息的大小,小于被替换内容的大小,所以文件得到了压缩。
LZ77算法使用"滑动窗口"的方法,来寻找文件中的相同部分,也就是匹配串(它是指一个任意字节的序列)。

3、 Huffman编码原理
我们把文件中一定位长的值看作是符号,比如把8位长的256种值,也就是字节的256种值看作是符号。
根据这些符号在文件中出现的频率,对这些符号重新编码。对于出现次数非常多的用较少的位来表示,对于出现次数非常少的用较多的位来表示。这样一来文件的一些部分位数变少了而一部分位数变多了,但由于变小的部分>变大的部分,所以实现了压缩。

4、Huffman树编码
进行Huffman编码,首先要把整个文件读一遍,在读的过程中,统计每个符号的出现次数(1个字节的256种值看作是256种符号)。
然后根据符号的出现次数建立Huffman树,通过Huffman树得到每个符号的新的编码,然后把文件中的每个字节替换成他们新的编码。
建立Huffman树:父结点组成一个新的树,这个新的树的值为它的两个子树的值的和,等于父节点的值。
Huffman树的所有父结点到它的左子结点的路径标记为0,右子结点的路径上标为1。
看看网上提供的一个示例图,如下所示:
a b c d e
1 4 4 3 1
Deflate算法解读_第1张图片
通过最终的Huffman树,我们可以得到每个符号的Huffman编码。
a 为 110、b 为 00、c 为 01、d 为 10、e 为 111
另外:
比如,a的编码为000,b的编码为0001,c的编码为1,那么当遇到0001时,就不知道0001代表ac,还是代表b。
出现这种问题的原因是a的编码是b的编码的前缀。
由于Huffman编码为根结点到叶子结点路径上的0和1的序列,而一个叶子结点的路径不可能是另一个叶子结点路径的前缀,所以一个Huffman编码不可能为另一个Huffman编码的前缀,这就保证了Huffman编码是可以区分的。

5、使用Huffman编码进行压缩和解压缩

为了在解压缩的时候,得到压缩时所使用的Huffman树,我们需要在压缩文件中,保存树的信息,也就是保存每个符号的出现次数的信息。
压缩:
读文件,统计每个符号的出现次数。根据每个符号的出现次数,建立Huffman树,得到每个符号的Huffman编码。将每个符号的出现次数的信息保存在压缩文件中,将文件中的每个符号替换成它的Huffman编码,并输出。
解压缩:
得到保存在压缩文件中的,每个符号的出现次数的信息。根据每个符号的出现次数,建立Huffman树,得到每个符号的Huffman编码。将压缩文件中的每个Huffman编码替换成它对应的符号,并输出。

6、实现摘要
deflate中的huffman编码:
对Lz77得到的压缩后结果,需要统计字符生成编码表huffmantree(指示每个编码代表什么字符),根据码表对内容进行编码,具体的压缩大小在于精细分配结构体的位域来实现Huffman编码的压缩效果的。

编码表huffmantree和编码后的data都一起放置在文件中。
deflate中的解压:
读取二进制文件,构建huffmantree表,读取数据根据huffmantree生成字符(这些字符是符合LZ77算法的)。
用LZ77解码,这个时候应该需要对窗口生成哈希表(数组+链表);对解压的数据,进行搜索匹配拷贝替换为相应的串即可。
gzip源码分析
   main()中调用函数 treat_file()。
   treat_file()中打开文件,调用函数 zip()。注意这里的 work的用法,这是一个函数指针。
   zip()中输出gzip文件格式的头,调用 bi_init,ct_init,lm_init,
  其中在lm_init中将 head初始化清0。初始化strstart为0。从文件中读入64KB的内容到window缓冲区中。
  由于计算strstart=0时的ins_h,需要0,1,2这三个字节和哈希函数发生关系,所以在lm_init中,预读0,1两个字节,并和哈希函数发生关系。
  然后lm_init调用 deflate()。
   deflate() gzip的LZ77的实现主要deflate()中。

你可能感兴趣的:(其他)