TIFF图像文件(四):LZW压缩

只谈情不闲聊 提交于 2019-12-17 13:51:21

 LZW压缩算法是Unisys的专利,由Lempel-Ziv-Welch三人发明,有效期到2003年。

LZW思路:

ASCII字符有255个,每个用8bits表示,如果要表示2个字符,就用16bits;3个字符就用24bits,依此类推。假设我们对ASCII码扩展成12位,可以有4096个字符,并自己定义255以后的含义,如ab定义成258,abc定义成259,那么ab只用12位,较原来节约4位;abc也只用12位,较原来24bits节约12位,可以想象,代替的字符串越长,位数越节约。一般LZW压缩比为2:1或3:1。这是以前系统内存以及存储能力较小,为提高计算和存储能力而设计的。到现在,计算机性能突飞猛进,其优势就不复存在。

LZW核心是在于其压缩算法——动态生成压缩字典,自动还原压缩字典进行解压,压缩数据内含压缩字典,边压缩边生成压缩字典,但不保存;解压时,边解压边还原压缩字典,进行解压。

压缩

生成压缩字典就是如何将255个的ASCII码动态扩展成4096个字符码的过程。

(1)形成关键字为255个ascii码,值为0~255的初始字典,设定clearcode=256,endcode=257。(clearcode是为了在解压时避免扩展字典容量超过4096时,告诉程序以后的压缩数据的压缩字典重新计算;endcode表示结束)

(2)读取一个字符(input),和根字符(root)形成新的字符串(key),如果新字符串(key)在字典里存在,将根字符用新字符串(key)取代;如果key不存在,则将root计入输出流,input计为root字符,在字典关键字中添加Key,以及递增的值。

以ababababa为例,演示其压缩过程:

步骤

数据流

(Input)

根字符

(Root)

关键字字符

(Key=Root+Input)

字典

(Diction)

输出流

(Output)

 
1

a

 

a

-

-

a在字典中,root=a
2

b

a

ab

[ab]=258

97(a)

ab不在字典,将ab作为字典关键字,值自动加1=258,a输出,b=>root
3

a

b

ba

[ba]=259

98(b)

添加ba,输出b,a=>root
4

b

a

ab

-

-

ab存在字典,ab=》root
5

a

ab

aba

[aba]=260

258(ab)

aba不存在,添加关键字aba,输出关键字ab的值258,a=》root
6

b

a

ab

-

-

ab存在字典,ab=》root
7

a

ab

aba

-

-

aba存在字典,aba=》root
8

b

aba

abab

[abab]=261

260(aba)

abab不存在,添加关键字abab,输出关键字aba的值260,b=》root
9

a

b

ba

-

-

ba存在字典,ba=》root
10

EOF

ba

 

 

259(ba)

结束,输出关键字ba值 259

原值:97 98 97 98 97 98 97 98 97=》保存为8位二进制数据流:1100001 1100010 1100001 1100010 1100001 1100010 1100001 1100010 1100001,共72bits

压缩后的值:97 98 258 260 259=》保存为12位二进制数据流:00001100001 00001100010 000100000010 000100000100 000100000011,共60bits。

注:由于字典关键字个数小于4096,没有用到clearcdoe(256)。

解压

(1)同压缩,生成初始字典;

(2)读取一个字符(input)的第一个数值,在字典中找到对应的字符串输出,key字符=Root字符+input字符串第一个字符,并将key添加到字典中,将input设为新Root;

如果没有对应的关键字,key字符=Root+Root的第一个字符,并将key添加到字典中,输出key字符,将key设为新Root;

以上面压缩数据97 98 258 260 259 解压为例

步骤

数据流

(Input)

根字符

(Root)

关键字字符

(Key=Root+Input.FirstChar)

字典

(Dictionary)

输出流

(Output)

说明

1

97

 

a

-

a

a存在,输出97,a=》root

2

98

a

ab

[258]=ab

b

98存在字典,输出98(b),b=>root,ab不存在,添加ab。

3

258(ab)

b

ba

[259]=ba

ab

258存在,输出[258]=ab,ab=>root;ba不存在,添加ba,

4

260

ab

aba=ab+ab.firstchar

[260]=aba

aba

260不存在字典,关键字=Root+Root.firstChar,添加到字典,并输出(这是lzw最巧妙的地方,没有在字典里,如何推算出260),aba=>root

5

259(ba)

aba

abab

[261]=abab

ba

259存在,输出[259]=ba,ba=》root,abab不存在,添加abab。

6

EOF

ba

 

 

-

 

还原出a b ab aba ba。

注意:

压缩时,按8位一个字节读出;字典关键字是字符串,值为数值;

解压时,按12位读出;字典关键字是数字,值为字符串;

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!