一、LZW背景介绍
J.Ziv和A.Lempel在1978年首次发表了介绍第二类词典编码算法的文章。在他们的研究基础上,Terry A.Welch在1984年发表了改进这种编码算法的文章,因此把这种编码方法称为LZW压缩编码。
LZW只输出代表词典中的字符串(String)的码字(code word)。这就意味在开始时词典不能是空的,它必须包含可能在字符流出现中的所有单个字符。即在编码匹配时,至少可以在词典中找到长度为1的匹配串。
二、LZW编解码
1、LZW编码思路
2、LZW解码思路
3、LZW编解码特点
(1)优点
LZW只需要扫一遍,具有自适应的特点;算法简单,便于快速实现。
(2)限制
字符串重复概率低时,影响压缩效率;词典中的字符串不再出现,影响压缩效率;从词典中查找词条费时。
三、验证编解码效果
1、LZW编码验证
我选取了.txt、.jpg、.bmp、.pdf四种格式的文件进行验证
2、编码后再解码
将hello.txt文件编码为likeyou.zip,再将其解码为hello1.txt,结果如下:
四、代码注释
/*
* Definition for LZW coding
*
* vim: ts=4 sw=4 cindent nowrap
*/
#include <stdlib.h>
#include <stdio.h>
#include "bitio.h"
#define MAX_CODE 65535
struct
{
int suffix;
int parent, firstchild, nextsibling;
} dictionary[MAX_CODE+1];
int next_code;
int d_stack[MAX_CODE]; // stack for decoding a phrase
#define input(f) ((int)BitsInput( f, 16))
#define output(f, x) BitsOutput( f, (unsigned long)(x), 16)
int DecodeString( int start, int code);
void InitDictionary( void);
//打印词典
void PrintDictionary( void)
{
int n;
int count;
for( n=256; n<next_code; n++)
{
count = DecodeString( 0, n);
printf( "%4d->", n);
while( 0<count--)
printf("%c", (char)(d_stack[count]));
printf( "\n");
}
}
//从解出的字符串存入d_stack栈中
int DecodeString( int start, int code)
{
int count; //计数
count = start;
while( 0<=code)
{
d_stack[count] = dictionary[code