LZW压缩(解压缩)算法详解

LZW压缩算法是Lempel-Ziv-Welch 3个人共同发明的,简称 LZW 的压缩算法,可以用任何一种语言来实现它.
LZW是GIF图片文件的压缩算法,而且zip压缩的思想也是基于LZW实现的,所以LZW对文本文件具有很好的压缩性能。

LZW压缩算法的基本原理:提取原始文本文件数据中的不同字符,基于这些字符创建一个编码表,然后用编码表中的字符的索引来替代原始文本文件数据中的相应字符,减少原始数据大小。看起来和 调色板图象的实现原理差不多,但是应该注意到的是,我们这里的编码表不是事先创建好的,而是根据原始文件数据动态创建的,解码时还要从已编码的数据中还原出原来的编码表.

编码表中每一项的大小一般为12位,用来代表一个字符串。这样编码表有2**12=4096项,编码值是0~4095。通常情况下0~255是固定的,用来代表单个字符0~255。而值256通常用来表示开始新的编码表,因为如果编码表的4096项都用完了,而待压缩文件还没有处理完,那么就需要生成新的编码表继续压缩;257表示压缩结束,用来写到压缩文件尾。从258开始,每个值都代表一个字符串(至少2个字符)。
举个例子,有下面的字符串:ababcdefgefg。(a的ascii码是0x61=97)
压缩后的数据是:97 98 258 99 100 101 102 103 263 103。

其中第二个ab被压缩成258,第二个ef被压缩成263,因为这之前在ab和ef第一次出现的时候就已经被按顺序编入到编码表中。
编码项结构为:
  1. typedef struct
  2. {
  3.     char used ; //该项已被编码。
  4.     UINT prev; //前向编码索引(0~4095)
  5.     BYTE c; //本项对应字符。
  6. }ENTRY;

编码表是(该编码表只在压缩过程中使用,并不会被写入到最终的压缩文件):
  1. ENTRY string_tab[4096];

具体压缩过程是:
1. 初始化编码表string_tab[0~257]。258~4095为空。即

  1. string_tab[i].used=TRUE, string_tab[i].prev=-1,string_tab[i].c=i(0<=i<=257)
  2. string_tab[j].used = FALSE(258<=j<=4095)

2. 程序读入第一个字符a,到编码表中查找到对应编码97,记录临时前向编码索引prevcode=97,再读入下一个字符b,然后在编码表中查找prev=97、c='b'的编码项,没有找到, 则表明'ab'没有对应的编码项,则把当前prevcode的值--97写入压缩缓存(该缓存最后会被写入压缩文件);再创建新的编码项string_tab[258],且string_tab[258].prev=97,string_tab[258].c='b'。最后更新临时前向编码索引prevcode=当前字符'b'=98。
3. 程序读入下一个字符a,在编码表中查找prev=prevcode(98)、c='a'的编码项,没有找到,则把当前prevcode的值98写入压缩缓存;再创建新的编码项string_tab[259],且string_tab[259].prev=98, string_tab[259].c='a'。最后更新临时前向编码索引prevcode=当前字符'a'=97。
4.程序读入下一个字符b,在编码表中查找prev=prevcode(97)、c='b'的编码项,找到了为258!则跳转到第3步,继续读入下一个字符c处理。
程序如此按照以上步骤处理,到ababcdefgefg都读完时,编码表数据是:
  1. string_tab[258].prev=97('a'), .c='b'
  2. string_tab[259].prev=98('b'), .c='a'
  3. string_tab[260].prev=258, .c='c'
  4. string_tab[261].prev=99('c'), .c='d'
  5. string_tab[262].prev=100('d'), .c='e'
  6. string_tab[263].prev=101('e'), .c='f'
  7. string_tab[264].prev=102('f'), .c='g'
  8. string_tab[265].prev=103('g'), .c='e'
  9. string_tab[266].prev=263, .c='g'

 最终压缩文件中的数据是:
 256 97 98 258 99 100 101 102 103 263 103 257。     
下面是LZW压缩算法的流程图:


LZW的解压缩过程则刚好相反,具体请参见附件中的源码。
对于文本文件,LZW算法的压缩率(压缩率=压缩后文件大小/压缩前文件大小)可以达到30%~50%。
对于二进制文件,LZW算法的压缩率则不太好,一般在50%以上。

原地址:http://blog.chinaunix.net/uid-23741326-id-3124208.html

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
LZW(Lempel-Ziv-Welch)压缩算法是一种常用的无损数据压缩算法,它可以将输入的数据流进行压缩,并在需要时进行解压缩以还原原始数据。VHDL(VHSIC Hardware Description Language)是一种硬件描述语言,常用于数字电路设计和硬件描述。 LZW压缩算法的核心思想是利用字典来存储已经出现的序列,然后将序列替换为对应的索引值。在压缩过程中,算法会不断扩展字典,以适应新出现的序列。而在解压缩过程中,算法会根据索引值从字典中查找对应的序列,并将其还原。 在VHDL语言中实现LZW压缩算法,可以采用状态机的方式描述算法的不同状态和操作。其中,需要实现的核心功能包括: 1. 初始化字典:在算法开始时,需要初始化字典,包括预定义的单字符序列和初始的索引值。 2. 压缩过程:读取输入数据流,并根据当前读取的序列在字典中查找对应的索引值。如果查找成功,则继续读取下一个字符并与当前序列拼接,继续在字典中查找;如果查找失败,则将当前序列的索引值输出,并将当前序列添加到字典中,并将下一个字符作为新的序列开始。 3. 解压缩过程:读取压缩后的数据流,并根据索引值在字典中查找对应的序列。然后将序列输出,并将序列添加到字典中,并将下一个索引值作为新的序列开始。 需要注意的是,在VHDL语言中实现LZW压缩算法需要考虑到硬件资源和性能的限制,需要合理设计状态机和字典存储结构,以达到高效的压缩解压缩效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值