GZIP压缩原理分析(26)——第五章 Deflate算法详解(五17) 动态哈夫曼编码分析(06) LZ77过程(05)

时间:2021-01-11 20:01:05

*找不到匹配怎么办?

在上一个问题中,那些匹配长度不够的字符串的首个字符被视为没有找到匹配并当做单个字符处理,其实这种处理方法并不仅仅针对这种情况,对于那些根本没有匹配串,就是说算出哈希值后发现head[ins_h]是空的情况,也采用这种处理方法。那这个时候问题就来了,怎么区分一个字节到底是表示literal还是表示length?例如,有如下经过替换之后的字符串,

“1abc23bcdefghijklm456a(12, 16)nopq”,

实际的长度距离对儿是不可能带着括号的,就是两个普通的数,距离可以通过长度来判断,只要知道一个字节表示length,那length后面就表示距离,可length又怎么判断?提前和大家说明一下,length也用一个字节来表示(更详细的内容后续介绍)。

 

一个字节是length还是literal,只有这么两种情况,那么就可以考虑用1来表示length,用0来表示literal,如果能有个标记位来记录,那不就可以区分了么!压缩算法的确是使用标记位来区分length和literal的,但使用方式可能不是大家常见的样子。我们先来看几个数据结构及变量:

i.   unsigned  char    l_buf[32768];(实际的要比这个大64B,但不影响,源码分析时再细看)

ii.  unsigned  short  d_buf[32768];

iii. unsigned  char   flag_buf[32768/8];

iv. unsigned  last_lit, last_dist;

整数last_lit和last_dist分别是数组l_buf[]和d_buf[]的索引,数组l_buf[]用于存放literal和length,一共可以存放32768个;数组d_buf[]用于存放distance,一共可以存放32768个;关键就是数组flag_buf[],该数组有4096个元素,直接看4096有些唐突,但是结合(32768/8)是不是更好理解一些?!数组flag_buf[]是一个unsigned char类型的数组,每个元素占用一个字节,8bits,所以该数组总共占用32768bits。看到这里,应该有点感觉了吧。数组l_buf[]记录literal和length,总共可以记录32768个;数组flag_buf[]共占用32768bits,每一比特代表数组l_buf[]中的一个元素,通过判断该比特位的值是0还是1就可以知道数组l_buf[]中对应的那个元素到底是literal还是length,提前说一句,0表示literal,1表示length。

 

整数last_lit作为数组l_buf[]的索引,如果l_buf[last_lit]是literal,那么数组flag_buf[]中的第last_lit比特就是0;如果l_buf[last_lit]是length,那么数组flag_buf[]中的第last_lit比特就是1,并且d_buf[last_dist]要记录对应的distance。

 

这里将标记位的处理原理简单介绍给大家,让大家有一个基本印象,还有很多细节没有介绍,我把这些细节留到源码分析中讲解。