首先道个歉:昨天写着写着突然熄灯,以至于写了80%的这篇文章不得不灰飞烟灭,我可怜的电脑也被裸关一次,没有办法,校有校规啊,所以只好今天从头开始再写一遍。
言归正传。
写着篇文章之前,我县假定你已经对于什么是GIF很清楚了,如果你不清楚的话,建议你到网上搜索一下“GIF文件简介”看看。
GIF作为一种面向网络的图像格式,他的种种设计都是以“便于在网络上使用”为原则的。网络使用的第一个原则就是文件大小。如何使用有效的压缩算法使文件的大小得以减小,是GIF文件要解决的首要问题。对于这个问题,GIF采用的是压缩效率很好的LZW压缩算法。这个算法的压缩效率、压缩比都是极高的,但是有一点不好:它是有版权的。
因此我的第一部分,是介绍LZW算法,与GIF文件格式的内容无关,只是一种算法,但是它是LZW-GIF压缩算法(GIF使用的压缩算法)的基础。
1、概述
LZW算法的基本思想很简单:在一个输入的未压缩的字节流中,一定有很多的重复出现的字符串,那么用一个字节来表示这个字符串,不就起到了压缩的作用了吗?
下面我们先看几个概念,这几个概念将会在下面的介绍中反复出现,因此请记住他们。
Char Stream(未编码的字节流):作为编码的输入和解码的输出,使未经压缩的字节流,我们要处理的对象。
Code Stream(已编码的流):我没有写作字节流,因为不一定输出的是字节,事实上大多数时候也不是字节。
String Table(编码表):作为编码和解码的字典,它的格式是一个index对应一个string,在初始化的时候,从0开始的index依次对应字符集中的相应的字符。LZW的编码表有一个很大的优势就是他不需要很大的存储空间,它是在编码、解码的过程中动态生成的,而生成他指需要一个变量:初始的根项的数目。
Root Item(编码表根项):生成编码表时初始的只有一个字符的那些项,他们有一系列的特点,我在算法描述的时候再详述。
好了,概念说完了。现在开始介绍编码的算法:
2、编码算法
首先是算法的伪码描述:
initial_string_table(root_number);
current_prefix = '' ; //空字符串
while (能够从Char Stream中取出一个Char c) {
current_string = current_prefix+c ;
if (current_string在string_table中存在) {