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第一次出现的时候就已经被按顺序编入到编码表中。
编码项结构为:
- typedef struct
- {
- char used ; //该项已被编码。
- UINT prev; //前向编码索引(0~4095)。
- BYTE c; //本项对应字符。
- }ENTRY;
编码表是(该编码表只在压缩过程中使用,并不会被写入到最终的压缩文件):
- ENTRY string_tab[4096];
具体压缩过程是:
1. 初始化编码表string_tab[0~257]。258~4095为空。即
- string_tab[i].used=TRUE, string_tab[i].prev=-1,string_tab[i].c=i(0<=i<=257)。
- 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都读完时,编码表数据是:
- string_tab[258].prev=97('a'), .c='b';
- string_tab[259].prev=98('b'), .c='a';
- string_tab[260].prev=258, .c='c';
- string_tab[261].prev=99('c'), .c='d';
- string_tab[262].prev=100('d'), .c='e';
- string_tab[263].prev=101('e'), .c='f';
- string_tab[264].prev=102('f'), .c='g';
- string_tab[265].prev=103('g'), .c='e';
- 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%以上。
附件是作者用C语言编写的LZW算法源码,LZWCOM3是压缩源码,LZWUNCOM3是解压缩源码。它们在Windows的Visual Studio下都已通过编译测试,移植到其他平台也很容易。该代码遵循GPL(GNU Public License)开源许可,且引用请标明出处。
使用如下:
LZW.zip
《返璞归真--UNIX技术内幕》
在Linux下如何在程序中获得当前调用栈信息
在Solaris下如何在程序中获得当前调用栈信息
在AIX下如何在程序中获得当前调用栈信息
在Windows下如何在程序中获得当前调用栈信息
LZW压缩(解压缩)算法详解及源码相关推荐
- tar压缩解压缩命令详解
tar压缩解压缩命令详解 tar命令详解 -c: 建立压缩档案 -x:解压 -t:查看内容 -r:向压缩归档文件末尾追加文件 -u:更新原压缩包中的文件 这五个是独立的命令,压缩解压都要用到其中一个, ...
- linux下tar命令解压缩,tar解压缩命令 Linux下的tar压缩解压缩命令详解
<tar解压缩命令 Linux下的tar压缩解压缩命令详解>由会员分享,可在线阅读,更多相关<tar解压缩命令 Linux下的tar压缩解压缩命令详解(14页珍藏版)>请在人人 ...
- 基于双向BiLstm神经网络的中文分词详解及源码
基于双向BiLstm神经网络的中文分词详解及源码 基于双向BiLstm神经网络的中文分词详解及源码 1 标注序列 2 训练网络 3 Viterbi算法求解最优路径 4 keras代码讲解 最后 源代码 ...
- hadoop作业初始化过程详解(源码分析第三篇)
(一)概述 我们在上一篇blog已经详细的分析了一个作业从用户输入提交命令到到达JobTracker之前的各个过程.在作业到达JobTracker之后初始化之前,JobTracker会通过submit ...
- SpringMVC异常处理机制详解[附带源码分析]
SpringMVC异常处理机制详解[附带源码分析] 参考文章: (1)SpringMVC异常处理机制详解[附带源码分析] (2)https://www.cnblogs.com/fangjian0423 ...
- 详解LAMP源码编译安装
实战:LAMP源码编译安装 家住海边喜欢浪:zhang789.blog.51cto.com 目录 详解LAMP源码编译安装 LAMP简介 一.准备工作 二.编译安装 Apache 三.编译安装 MyS ...
- 详解 Python 源码之对象机制
在Python中,对象就是在堆上申请的结构体,对象不能是被静态初始化的,并且也不能是在栈空间上生存的.唯一的例外就是类型对象(type object),Python中所有的类型对象都是被静态初始化的. ...
- spark RDD详解及源码分析
spark RDD详解及源码分析 @(SPARK)[spark] spark RDD详解及源码分析 一基础 一什么是RDD 二RDD的适用范围 三一些特性 四RDD的创建 1由一个已经存在的scala ...
- spark 调度模块详解及源码分析
spark 调度模块详解及源码分析 @(SPARK)[spark] spark 调度模块详解及源码分析 一概述 一三个主要的类 1class DAGScheduler 2trait TaskSched ...
最新文章
- python3项目-终于找到python3项目实战教程
- mysql 授权是哪一个表_MySQL授权系统的五个表
- 币氪共识指数排行榜0910
- arcgis判断两个字段是否相等
- JPA 中 sql 预编译 -- EntityManager 使用 预编译
- 十个模块_专栏 | ABAQUS Part模块的十个小技巧
- 求职时这样回答问题你就输了!来自IT类面试官视角的深度解读
- FPGA状态机一段式
- Spark学习之第一个程序打包、提交任务到集群
- scrapy框架之分布式操作
- 【Spring】Service 注入失败,空指针
- 当公司辞掉85后测试员选择95后测试员后...
- 单片机怎么学,先从哪入手开始学,怎么开始入门
- EF中CodeFirst中实体变化的处理方式
- 拓端tecdat|数据预处理之异常值处理
- html文件怎么兼容浏览器,如何扫描HTML和跨浏览器兼容的JavaScript文件?
- 一步一步学做一个CPU——2,Logisim的简单入门
- 如何更换IP?最简单的换IP方法
- python的基础讲解
- 缓存文件可以放在哪里?它们各自的特点是什么?