lzw压缩算法的c语言实现

合集下载

lzw压缩算法的c语言实现

lzw压缩算法的c语言实现

HANDLE file_handle(CHAR* file_name) { HANDLE h_file; h_file = CreateFile(file_name, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, 0, NULL ); return h_file; } //-----------------------------------------------------------------------------WORD load_buffer(HANDLE h_sour, PBUFFER_DATA buffer) // Load file to buffer { DWORD ret; ReadFile(h_sour,buffer->lp_buffer,BUFFERSIZE,&ret,NULL); buffer->index = 0; buffer->top = (WORD)ret; return (WORD)ret; } //-----------------------------------------------------------------------------WORD empty_buffer( PLZW_DATA lzw, PBUFFER_DATA buffer)// Output buffer to file { DWORD ret; if(buffer->end_flag) // The flag mark the end of decode { if( buffer->by_left ) { buffer->lp_buffer[ } } WriteFile(lzw->h_dest, buffer->lp_buffer,buffer->index,&ret,NULL); buffer->index = 0; buffer->top = ret; return (WORD)ret; } //-----------------------------------------------------------------------------#endif (3) hash.h 定义了压缩时所用的码表操作函数,为了快速查找使用了 hash 算法,还有处理 hash 冲突的函数 buffer->index++ ] = (BYTE)( buffer->dw_buffer >> 32-buffer->by_left )<<(8-buffer->by_left);

C语言中的数据压缩与解压缩

C语言中的数据压缩与解压缩

C语言中的数据压缩与解压缩在计算机科学中,数据压缩是一种常见的技术,用于将大型数据文件或数据流以更小的尺寸存储或传输。

在C语言中,我们可以使用各种算法和技术来实现数据的压缩和解压缩。

本文将详细介绍C语言中常用的数据压缩与解压缩方法。

一、哈夫曼编码1.1 简介哈夫曼编码是一种无损压缩算法,由数学家David A. Huffman于1952年提出。

它根据数据中字符出现的频率来构建一个具有最小编码长度的前缀码。

在C语言中,我们可以使用哈夫曼编码来进行数据的压缩和解压缩。

1.2 压缩过程哈夫曼编码的压缩过程分为以下几个步骤:a) 统计数据中各字符的频率,构建字符频率表。

b) 根据字符频率表构建哈夫曼树。

c) 根据哈夫曼树构建字符编码表。

d) 遍历数据,使用字符编码表将字符转换为对应的编码,并将编码存储。

1.3 解压缩过程哈夫曼编码的解压缩过程分为以下几个步骤:a) 使用压缩时生成的字符编码表,将压缩后的编码转换为对应的字符。

b) 将解压后的字符恢复为原始数据。

二、LZ77压缩算法2.1 简介LZ77是一种常用的数据压缩算法,由Abraham Lempel和Jacob Ziv 于1977年提出。

它利用了数据中的重复出现模式,通过记录重复出现的字符串的位置和长度来实现数据的压缩。

2.2 压缩过程LZ77压缩算法的压缩过程分为以下几个步骤:a) 初始化一个滑动窗口,窗口大小为固定长度。

b) 在滑动窗口内查找与当前字符匹配的最长字符串,并记录字符串的位置和长度。

c) 将匹配的字符串以位置和长度的形式存储,并将窗口向右滑动到匹配字符串的末尾。

d) 重复步骤b和c,直到遍历完所有数据。

2.3 解压缩过程LZ77压缩算法的解压缩过程分为以下几个步骤:a) 根据压缩时存储的位置和长度信息,从滑动窗口中找到对应的字符串。

b) 将找到的字符串输出,并将窗口向右滑动到输出字符串的末尾。

c) 重复步骤a和b,直到解压缩完成。

三、LZ78压缩算法3.1 简介LZ78是一种常用的数据压缩算法,由Abraham Lempel和Jacob Ziv 于1978年提出。

packbits和lzw压缩方法

packbits和lzw压缩方法

packbits和lzw压缩方法PackBits和LZW都是常见的无损数据压缩算法,它们在不同的应用场景中发挥着重要作用。

下面我将从多个角度来介绍这两种压缩方法。

首先,我们来看PackBits压缩方法。

PackBits是一种简单而高效的压缩算法,通常用于图像文件的压缩。

它的原理是将连续重复的数据值用一个计数值和一个单独的数据值来表示,从而实现压缩。

例如,如果有连续重复的数值,PackBits会将这段重复的数值用一个计数值和该数值本身来表示,从而减少数据的存储空间。

这种方法适用于具有大量重复数据的情况,但在一些数据分布不均匀的情况下可能效果不佳。

其次,我们来看LZW压缩方法。

LZW是一种字典压缩算法,通常用于文本文件的压缩,例如GIF图像格式就使用了LZW压缩算法。

它的原理是建立一个字典,将输入的数据与字典中的条目进行匹配,并输出匹配的条目的编码。

当有新的数据输入时,会将其添加到字典中,从而不断扩大字典,提高压缩效率。

LZW压缩算法适用于各种类型的数据,尤其在文本文件中表现优异,但在某些特定情况下可能会受到版权限制。

从实现角度来看,PackBits相对简单,算法复杂度低,易于实现和理解。

而LZW相对复杂一些,需要建立和维护字典,算法复杂度较高,实现起来可能会更加困难。

从压缩效率来看,PackBits适用于具有大量重复数据的情况,能够取得较好的压缩效果。

而LZW适用于各种类型的数据,尤其在文本文件中表现优异,能够取得更好的压缩效果。

总的来说,PackBits和LZW都是常见的无损数据压缩算法,它们在不同的应用场景中都有各自的优势和局限性。

在实际应用中,我们需要根据具体的数据特点和压缩需求来选择合适的压缩方法,以达到最佳的压缩效果。

lzw压缩算法的c语言实现

lzw压缩算法的c语言实现

标准的LZW压缩原理:~~~~~~~~~~~~~~~~~~先来解释一下几个基本概念:LZW压缩有三个重要的对象:数据流(CharStream)、编码流(CodeStream)和编译表(String Table)。

在编码时,数据流是输入对象(图象的光栅数据序列),编码流就是输出对象(经过压缩运算的编码数据);在解码时,编码流则是输入对象,数据流是输出对象;而编译表是在编码和解码时都须要用借助的对象。

字符(Character):最基础的数据元素,在文本文件中就是一个字节,在光栅数据中就是一个像素的颜色在指定的颜色列表中的索引值;字符串(String):由几个连续的字符组成;前缀(Prefix):也是一个字符串,不过通常用在另一个字符的前面,而且它的长度可以为0;根(Root):单个长度的字符串;编码(Code):一个数字,按照固定长度(编码长度)从编码流中取出,编译表的映射值;图案:一个字符串,按不定长度从数据流中读出,映射到编译表条目.LZW压缩的原理:提取原始图象数据中的不同图案,基于这些图案创建一个编译表,然后用编译表中的图案索引来替代原始光栅数据中的相应图案,减少原始数据大小。

看起来和调色板图象的实现原理差不多,但是应该注意到的是,我们这里的编译表不是事先创建好的,而是根据原始图象数据动态创建的,解码时还要从已编码的数据中还原出原来的编译表(GIF文件中是不携带编译表信息的),为了更好理解编解码原理,我们来看看具体的处理过程:编码器(Compressor)~~~~~~~~~~~~~~~~编码数据,第一步,初始化一个编译表,假设这个编译表的大小是12位的,也就是最多有4096个单位,另外假设我们有32个不同的字符(也可以认为图象的每个像素最多有32种颜色),表示为a,b,c,d,e...,初始化编译表:第0项为a,第1项为b,第2项为c...一直到第31项,我们把这32项就称为根。

开始编译,先定义一个前缀对象Current Prefix,记为[.c.],现在它是空的,然后定义一个当前字符串Current String,标记为[.c.]k,[.c.]就为Current Prefix,k就为当前读取字符。

lzrw实现原理

lzrw实现原理

lzrw实现原理LZRW算法实现原理简介LZRW是一种常用的无损压缩算法,可以在文件传输和存储中起到很好的节省空间的作用。

本文将从浅入深解释LZRW算法的实现原理。

LZRW算法的基本思想1.Lempel-Ziv算法:LZRW算法是在LZ77算法的基础上进行改进的。

Lempel-Ziv算法通过建立一个字典,将重复出现的字符串替换为索引值,从而实现对数据的压缩。

但是LZ77算法存在一些问题,如字典的存储开销过大和效率较低等。

因此,LZRW算法在LZ77算法的基础上进行了一些优化和改进。

2.LZRW算法流程:LZRW算法的基本流程如下:–初始化:建立一个空白字典。

–读取输入数据:将输入数据按照预定的窗口大小进行分割。

–查找字典:在字典中查找与当前窗口内容匹配的最长字符串。

–替换字符串:将匹配的字符串替换为对应的索引值。

–更新字典:将当前窗口内容加入字典中。

–输出结果:输出压缩后的数据。

LZRW算法核心原理1.字典的建立:LZRW算法通过使用前缀树(Trie)来实现字典的建立和查找。

前缀树是一种以字符串为边的有向无环图,每个节点代表一个字符串的前缀。

节点之间的边表示字符关系。

通过遍历前缀树,就可以确定最长匹配字符串,并将其替换为对应的索引。

2.最长匹配字符串的查找:从当前窗口的起始位置开始向后遍历,逐个比较字符,直到遇到一个不匹配的字符。

查找过程可以通过快速查找算法(如KMP算法)来优化。

3.字符串的替换和索引的编码:被匹配到的字符串会被替换为字典中对应字符串的索引值,以便产生更好的压缩效果。

索引值可以使用变长编码进行表示,以节省空间。

4.字典的更新:每次进行字符串匹配和替换后,都需要将当前窗口内容加入字典中,以便下一次的匹配查找。

LZRW算法的优化策略1.滑动窗口:为了降低字典的存储需求,LZRW算法采用滑动窗口,只保留最近的一段数据作为字典。

滑动窗口的大小可以根据实际需求进行调整。

2.动态字典更新:由于字典的大小受限,为了保证匹配字符串的准确性,LZRW算法采用了动态更新字典的策略。

设计一个高效的文件压缩算法

设计一个高效的文件压缩算法

设计一个高效的文件压缩算法文件压缩算法是一种将文件的大小减小,以便在存储和传输过程中节省空间和时间的技术。

高效的文件压缩算法应该能够以更少的空间要求存储文件,并且在解压缩过程中能够快速恢复原始文件。

以下是一种高效的文件压缩算法的设计概要。

1.基于字典的压缩算法基于字典的压缩算法是一种常见且高效的文件压缩算法,其中最流行的一种是Lempel-Ziv-Welch (LZW)算法。

该算法通过建立一个字典,其中包含当前输入的所有短语的编码,以便在后续的输入中使用。

算法通过将输入分解成较短的片段并将其编码来实现压缩。

在解压缩过程中,字典会逐渐增长,并且编码的内容会匹配到字典中的短语。

2.帧间压缩帧间压缩算法是一种针对视频和动画等多媒体文件的高效压缩算法。

该算法利用视频或动画的连续帧之间的相似性来减少数据量。

算法通过保存关键帧(例如I帧)的全部内容,并仅保存后续帧与关键帧之间的差异。

解压缩过程中,算法使用关键帧和差异数据来重建所有帧。

3.数学编码数学编码是一种基于数学模型的高效压缩算法。

其中最著名的算法之一是Huffman编码。

该算法根据输入中各个符号的出现频率来分配变长编码,以便频繁出现的符号使用较短的编码。

解压缩过程中,通过读取编码并映射到相应的符号,可以重建原始数据。

4.字节对齐字节对齐是一种基本的文件压缩技术,通过将数据存储在更紧凑的格式中来减小文件大小。

常见的字节对齐技术包括位压缩和字节填充。

位压缩技术利用二进制位来存储数据,可以将数值范围较小的数据占用更少的位数。

字节填充技术通过在数据之间插入填充字节,使每个数据项都对齐到固定的字节边界,从而减少浪费空间。

5.数据变换数据变换是一种通过改变数据的表示形式来减少文件大小的技术。

常用的数据变换技术包括离散余弦变换(DCT)和小波变换。

这些变换技术可以将数据从时域转换到频域,其中较大的频域系数可以更紧凑地表示,从而减小了文件大小。

在解压缩过程中,可以通过逆变换将数据转换回时域。

LZW压缩算法的软件实现

LZW压缩算法的软件实现

毕业设计(论文)题目LZW压缩算法的软件实现学生姓名学号专业计算机科学与技术班级指导教师评阅教师完成日期2008 年5 月18 日LZW压缩算法的研究与实现摘要随着计算机技术和网络技术的发展,人们需要存储和传播的数据越来越多,因此我们可以通过压缩数据来提高数据存储与传播的效率。

本系统按照LZW算法压缩原理,使用Microsoft Visual C++ 6.0 进行了开发,完成了压缩函数和解压缩函数的编写,实现了文件的无损压缩和解压缩。

关键字无损压缩解压缩LZWResearching and Implementing of LosslessCompression AlgorithmsABSTRACTAlong with the development of computer technical and network technology, the data that people need to stock and propagate is more and more. These datas have occupied plenty of disk spaces and network bandwidthes. However in data, there is also a lot of redundancies, therefore we may decrease the disk space of data occupation and the bandwidth with network occupied on transmit through compress data to stock. Data compression divides into loss compression and lossless compression, data reconciles before reducing to reduce rear content the compression that does not occur any change is called as lossless compression.Through long development has arisen a lot of lossless data compressed algorithms, we have compare various relatively lossless compression algorithm, has reached the advantage and disadvantage of each kind of algorithm.This system is used Microsoft Visual C++ 6.0 developed. According to LZW algorithms, we have accomplished the Compresses function and Decompresses function, and realizes lossless compression and decompress file.Keyword: Lossless compression Decompress LZW目录摘要 (II)ABSTRACT ...................................................................................................... I II 引言 (1)第1章系统需求分析 (3)1.1功能需求 (3)1.2性能需求 (3)1.3无损压缩算法的简介和比较 (4)1.3.1 LZ77算法 (4)1.3.2 LZSS算法 (6)1.3.3 LZ78算法 (8)1.3.4 LZW算法 (11)1.3.5 各种算法的比较 (17)1.4本课题的目标 (19)1.5系统开发环境 (19)第2章系统设计 (20)2.1系统结构 (2)2.2压缩文件格式的设计 (22)2.3开发方法的说明 (22)2.4各模块设计 (23)2.5算法分析 (26)第3章系统的实现 (29)3.1系统界面和主要功能 (29)3.2测试 (35)第4章结论 (37)致谢 (39)参考文献 (39)附录:主要源程序 (40)引言21世纪是一个属于网络信息高速发展的世纪,随着人们对网络的使用频率迅速提升,网络所负载的信息压力也越来越大,这主要体现在人们需要存储和传输的数据会越来越多。

lzw和霍夫曼编码

lzw和霍夫曼编码

lzw和霍夫曼编码LZW(Lempel-Ziv-Welch)编码和Huffman编码是常见的无损数据压缩算法。

它们可以将数据以更高效的方式表示,并减少数据所占用的存储空间。

虽然两种编码算法有一些相似之处,但它们的工作原理和实施方法略有不同。

1.LZW编码:LZW编码是一种基于字典的压缩算法,广泛应用于文本和图像等数据的压缩。

它的工作原理是根据已有的字典和输入数据,将连续出现的字符序列转换为对应的索引,从而减少数据的存储空间。

LZW编码的过程如下:•初始化字典,将所有可能的字符作为初始词条。

•从输入数据中读取字符序列,并检查字典中是否已有当前序列。

•如果字典中存在当前序列,则继续读取下一个字符,将该序列与下一个字符连接成一个长序列。

•如果字典中不存在当前序列,则将当前序列添加到字典中,并输出该序列在字典中的索引。

•重复以上步骤,直到输入数据全部编码完成。

LZW编码的优点是可以根据实际数据动态更新字典,适用于压缩包含重复模式的数据。

2.霍夫曼编码:霍夫曼编码是一种基于频率的前缀编码方法。

它根据字符出现的频率构建一个最优二叉树(霍夫曼树),将出现频率较高的字符用较短的二进制码表示,出现频率较低的字符用较长的二进制码表示。

霍夫曼编码的过程如下:•统计输入数据中各个字符的频率。

•使用字符频率构建霍夫曼树,频率较高的字符在树的较低层,频率较低的字符在树的较高层。

•根据霍夫曼树,为每个字符分配唯一的二进制码,保持没有一个字符的编码是另一个字符编码的前缀。

•将输入数据中的每个字符替换为相应的霍夫曼编码。

•输出霍夫曼编码后的数据。

霍夫曼编码的优点是可以根据字符频率进行编码,使高频字符的编码更短,适用于压缩频率差异较大的数据。

总的来说,LZW编码和霍夫曼编码都是常见的无损数据压缩算法,用于减少数据的存储空间。

它们的选择取决于具体的场景、数据特点和应用需求。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

lzw压缩算法的c语言实现1 程序由五个模块组成。

(1) lzw.h 定义了一些基本的数据结构,常量,还有变量的初始化等。

#ifndef __LZW_H__#define __LZW_H__//------------------------------------------------------------------------------#include <stdio.h>#include <stdlib.h>#include <windows.h>#include <memory.h>//------------------------------------------------------------------------------#define LZW_BASE 0x102// The code base#define CODE_LEN 12 // Max code length#define TABLE_LEN 4099 // It must be prime number and bigger than 2^CODE_LEN=4096.// Such as 5051 is also ok.#define BUFFERSIZE 1024//------------------------------------------------------------------------------typedef struct{HANDLE h_sour; // Source file handle.HANDLE h_dest; // Destination file handle.HANDLE h_suffix; // Suffix table handle.HANDLE h_prefix; // Prefix table handle.HANDLE h_code; // Code table handle.LPWORD lp_prefix; // Prefix table head pointer.LPBYTE lp_suffix; // Suffix table head pointer.LPWORD lp_code; // Code table head pointer.WORD code;WORD prefix;BYTE suffix;BYTE cur_code_len; // Current code length.[ used in Dynamic-Code-Length mode ] }LZW_DATA,*PLZW_DATA;typedef struct{WORD top;WORD index;LPBYTE lp_buffer;HANDLE h_buffer;BYTE by_left;DWORD dw_buffer;BOOL end_flag;}BUFFER_DATA,*PBUFFER_DATA;typedef struct //Stack used in decode{WORD index;HANDLE h_stack;LPBYTE lp_stack;}STACK_DATA,*PSTACK_DATA;//------------------------------------------------------------------------------VOID stack_create( PSTACK_DATA stack ){stack->h_stack = GlobalAlloc( GHND , TABLE_LEN*sizeof(BYTE) );stack->lp_stack = GlobalLock( stack->h_stack );stack->index = 0;}//------------------------------------------------------------------------------VOID stack_destory( PSTACK_DATA stack ){GlobalUnlock( stack->h_stack );GlobalFree ( stack->h_stack );}//------------------------------------------------------------------------------VOID buffer_create( PBUFFER_DATA buffer ){buffer->h_buffer = GlobalAlloc( GHND, BUFFERSIZE*sizeof(BYTE) ); buffer->lp_buffer = GlobalLock( buffer->h_buffer );buffer->top = 0;buffer->index = 0;buffer->by_left = 0;buffer->dw_buffer = 0;buffer->end_flag = FALSE;}//------------------------------------------------------------------------------VOID buffer_destory( PBUFFER_DATA buffer ){GlobalUnlock( buffer->h_buffer );GlobalFree ( buffer->h_buffer );}//------------------------------------------------------------------------------VOID re_init_lzw( PLZW_DATA lzw ) //When code table reached its top it should { //be reinitialized.memset( lzw->lp_code, 0xFFFF, TABLE_LEN*sizeof(WORD) );lzw->code = LZW_BASE;lzw->cur_code_len = 9;}//------------------------------------------------------------------------------VOID lzw_create(PLZW_DATA lzw, HANDLE h_sour, HANDLE h_dest) {WORD i;lzw->h_code = GlobalAlloc( GHND, TABLE_LEN*sizeof(WORD) );lzw->h_prefix = GlobalAlloc( GHND, TABLE_LEN*sizeof(WORD) );lzw->h_suffix = GlobalAlloc( GHND, TABLE_LEN*sizeof(BYTE) );lzw->lp_code = GlobalLock( lzw->h_code );lzw->lp_prefix = GlobalLock( lzw->h_prefix );lzw->lp_suffix = GlobalLock( lzw->h_suffix );lzw->code = LZW_BASE;lzw->cur_code_len = 9;lzw->h_sour = h_sour;lzw->h_dest = h_dest;memset( lzw->lp_code, 0xFFFF, TABLE_LEN*sizeof(WORD) );}//------------------------------------------------------------------------------VOID lzw_destory(PLZW_DATA lzw){GlobalUnlock( lzw->h_code );GlobalUnlock( lzw->h_prefix );GlobalUnlock( lzw->h_suffix );GlobalFree( lzw->h_code );GlobalFree( lzw->h_prefix );GlobalFree( lzw->h_suffix );}//------------------------------------------------------------------------------#endif(2) fileio.h 定义了一些文件操作#ifndef __FILEIO_H__#define __FILEIO_H__//------------------------------------------------------------------------------#include <stdio.h>#include <stdlib.h>#include <windows.h>//------------------------------------------------------------------------------HANDLE file_handle(CHAR* file_name){HANDLE h_file;h_file = CreateFile(file_name,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_ALWAYS,0,NULL);return h_file;}//------------------------------------------------------------------------------WORD load_buffer(HANDLE h_sour, PBUFFER_DATA buffer) // Load file to buffer{DWORD ret;ReadFile(h_sour,buffer->lp_buffer,BUFFERSIZE,&ret,NULL);buffer->index = 0;buffer->top = (WORD)ret;return (WORD)ret;}//------------------------------------------------------------------------------WORD empty_buffer( PLZW_DATA lzw, PBUFFER_DATA buffer)// Output buffer to file {DWORD ret;if(buffer->end_flag) // The flag mark the end of decode{if( buffer->by_left ){buffer->lp_buffer[ buffer->index++ ] =(BYTE)( buffer->dw_buffer >>32-buffer->by_left )<<(8-buffer->by_left);}}WriteFile(lzw->h_dest, buffer->lp_buffer,buffer->index,&ret,NULL);buffer->index = 0;buffer->top = ret;return (WORD)ret;}//------------------------------------------------------------------------------#endif(3) hash.h 定义了压缩时所用的码表操作函数,为了快速查找使用了hash算法,还有处理hash冲突的函数#ifndef __HASH_H__#define __HASH_H__//------------------------------------------------------------------------------#include <stdio.h>#include <stdlib.h>#include <windows.h>//------------------------------------------------------------------------------#define DIV TABLE_LEN#define HASHSTEP 13 // It should bigger than 0.//------------------------------------------------------------------------------WORD get_hash_index( PLZW_DATA lzw ){DWORD tmp;WORD result;DWORD prefix;DWORD suffix;prefix = lzw->prefix;suffix = lzw->suffix;tmp = prefix<<8 | suffix;result = tmp % DIV;return result;}//------------------------------------------------------------------------------WORD re_hash_index( WORD hash ) // If hash conflict occured we must recalculate { // hash index .WORD result;result = hash + HASHSTEP;result = result % DIV;return result;}//------------------------------------------------------------------------------BOOL in_table( PLZW_DATA lzw ) // To find whether current code is already in table. {BOOL result;WORD hash;hash = get_hash_index( lzw );if( lzw->lp_code[ hash ] == 0xFFFF ){result = FALSE;}else{if( lzw->lp_prefix[ hash ] == lzw->prefix &&lzw->lp_suffix[ hash ] == lzw->suffix ){result = TRUE;}else{result = FALSE;while( lzw->lp_code[ hash ] != 0xFFFF ){if( lzw->lp_prefix[ hash ] == lzw->prefix &&lzw->lp_suffix[ hash ] == lzw->suffix ){result = TRUE;break;}hash = re_hash_index( hash );}}}return result;}//------------------------------------------------------------------------------WORD get_code( PLZW_DATA lzw ){WORD hash;WORD code;hash = get_hash_index( lzw );if( lzw->lp_prefix[ hash ] == lzw->prefix &&lzw->lp_suffix[ hash ] == lzw->suffix ){code = lzw->lp_code[ hash ];}else{while( lzw->lp_prefix[ hash ] != lzw->prefix ||lzw->lp_suffix[ hash ] != lzw->suffix ){hash = re_hash_index( hash );}code = lzw->lp_code[ hash ];}return code;}//------------------------------------------------------------------------------ VOID insert_table( PLZW_DATA lzw ){WORD hash;hash = get_hash_index( lzw );if( lzw->lp_code[ hash ] == 0xFFFF ){lzw->lp_prefix[ hash ] = lzw->prefix;lzw->lp_suffix[ hash ] = lzw->suffix;lzw->lp_code[ hash ] = lzw->code;}else{while( lzw->lp_code[ hash ] != 0xFFFF ){hash = re_hash_index( hash );}lzw->lp_prefix[ hash ] = lzw->prefix;lzw->lp_suffix[ hash ] = lzw->suffix;lzw->lp_code[ hash ] = lzw->code;}}//------------------------------------------------------------------------------ #endif(4) encode.h 压缩程序主函数#ifndef __ENCODE_H__#define __ENCODE_H__//------------------------------------------------------------------------------#include <stdio.h>#include <stdlib.h>#include <windows.h>//------------------------------------------------------------------------------VOID output_code( DWORD code ,PBUFFER_DATA out, PLZW_DATA lzw) {out->dw_buffer |= code << ( 32 - out->by_left - lzw->cur_code_len );out->by_left += lzw->cur_code_len;while( out->by_left >= 8 ){if( out->index == BUFFERSIZE ){empty_buffer( lzw,out);}out->lp_buffer[ out->index++ ] = (BYTE)( out->dw_buffer >> 24 );out->dw_buffer <<= 8;out->by_left -= 8;}}//------------------------------------------------------------------------------VOID do_encode( PBUFFER_DATA in, PBUFFER_DATA out, PLZW_DATA lzw) {WORD prefix;while( in->index != in->top ){if( !in_table(lzw) ){// current code not in code table// then add it to table and output prefixinsert_table(lzw);prefix = lzw->suffix;output_code( lzw->prefix ,out ,lzw );lzw->code++;if( lzw->code == (WORD)1<< lzw->cur_code_len ){// code reached current code top(1<<cur_code_len) // then current code length add onelzw->cur_code_len++;if( lzw->cur_code_len == CODE_LEN + 1 ){re_init_lzw( lzw );}}}else{// current code already in code table// then output nothingprefix = get_code(lzw);}lzw->prefix = prefix;lzw->suffix = in->lp_buffer[ in->index++ ];}}//------------------------------------------------------------------------------ VOID encode(HANDLE h_sour,HANDLE h_dest){LZW_DATA lzw;BUFFER_DATA in ;BUFFER_DATA out;BOOL first_run = TRUE;lzw_create( &lzw ,h_sour,h_dest );buffer_create( &in );buffer_create( &out );while( load_buffer( h_sour, &in ) ){if( first_run ){// File length should be considered but here we simply// believe file length bigger than 2 bytes.lzw.prefix = in.lp_buffer[ in.index++ ];lzw.suffix = in.lp_buffer[ in.index++ ];first_run = FALSE;}do_encode(&in , &out, &lzw);}output_code(lzw.prefix, &out , &lzw);output_code(lzw.suffix, &out , &lzw);out.end_flag = TRUE;empty_buffer( &lzw,&out);lzw_destory( &lzw );buffer_destory( &in );buffer_destory( &out );}//------------------------------------------------------------------------------#endif(5) decode.h 解压函数主函数#ifndef __DECODE_H__#define __DECODE_H__//------------------------------------------------------------------------------#include <stdio.h>#include <stdlib.h>#include <windows.h>//------------------------------------------------------------------------------VOID out_code( WORD code ,PBUFFER_DATA buffer,PLZW_DATA lzw,PSTACK_DATA stack){WORD tmp;if( code < 0x100 ){stack->lp_stack[ stack->index++ ] = code;}else{stack->lp_stack[ stack->index++ ] = lzw->lp_suffix[ code ];tmp = lzw->lp_prefix[ code ];while( tmp > 0x100 ){stack->lp_stack[ stack->index++ ] = lzw->lp_suffix[ tmp ];tmp = lzw->lp_prefix[ tmp ];}stack->lp_stack[ stack->index++ ] = (BYTE)tmp;}while( stack->index ){if( buffer->index == BUFFERSIZE ){empty_buffer(lzw,buffer);}buffer->lp_buffer[ buffer->index++ ] = stack->lp_stack[ --stack->index ] ; }}//------------------------------------------------------------------------------VOID insert_2_table(PLZW_DATA lzw ){lzw->lp_code[ lzw->code ] = lzw->code;lzw->lp_prefix[ lzw->code ] = lzw->prefix;lzw->lp_suffix[ lzw->code ] = lzw->suffix;lzw->code++;if( lzw->code == ((WORD)1<<lzw->cur_code_len)-1 ){lzw->cur_code_len++;if( lzw->cur_code_len == CODE_LEN+1 )lzw->cur_code_len = 9;}if(lzw->code >= 1<<CODE_LEN ){re_init_lzw(lzw);}}//------------------------------------------------------------------------------WORD get_next_code( PBUFFER_DATA buffer , PLZW_DATA lzw ) {BYTE next;WORD code;while( buffer->by_left < lzw->cur_code_len ){if( buffer->index == BUFFERSIZE )load_buffer( lzw->h_sour, buffer );}next = buffer->lp_buffer[ buffer->index++ ];buffer->dw_buffer |= (DWORD)next << (24-buffer->by_left);buffer->by_left += 8;}code = buffer->dw_buffer >> ( 32 - lzw->cur_code_len );buffer->dw_buffer <<= lzw->cur_code_len;buffer->by_left -= lzw->cur_code_len;return code;}//------------------------------------------------------------------------------VOID do_decode( PBUFFER_DATA in, PBUFFER_DATA out, PLZW_DATA lzw, PSTACK_DATA stack){WORD code;WORD tmp;while( in->index != in->top ){code = get_next_code( in ,lzw );if( code < 0x100 ){// code already in table// then simply output the codelzw->suffix = (BYTE)code;}else{if( code < lzw->code ){// code also in table// then output code chaintmp = lzw->lp_prefix[ code ];while( tmp > 0x100 ){tmp = lzw->lp_prefix[ tmp ];}lzw->suffix = (BYTE)tmp;}else// code == lzw->code// code not in table// add code into table// and out put codetmp = lzw->prefix;while( tmp > 0x100 ){tmp = lzw->lp_prefix[ tmp ];}lzw->suffix = (BYTE)tmp;}}insert_2_table( lzw );out_code(code,out,lzw,stack);lzw->prefix = code;}}//------------------------------------------------------------------------------ VOID decode( HANDLE h_sour, HANDLE h_dest ){LZW_DATA lzw;BUFFER_DATA in ;BUFFER_DATA out;STACK_DATA stack;BOOL first_run;first_run = TRUE;lzw_create( &lzw ,h_sour,h_dest );buffer_create( &in );buffer_create( &out );stack_create(&stack );while( load_buffer( h_sour, &in ) ){if( first_run ){lzw.prefix = get_next_code( &in, &lzw );lzw.suffix = lzw.prefix;out_code(lzw.prefix, &out, &lzw , &stack);first_run = FALSE;}do_decode(&in , &out, &lzw, &stack);}empty_buffer( &lzw,&out);lzw_destory( &lzw );buffer_destory( &in );buffer_destory( &out );stack_destory( &stack);}#endif2 下面给出一个应用上面模块的简单例子#include <stdio.h>#include <stdlib.h>//------------------------------------------------------------------------------#include "lzw.h"#include "hash.h"#include "fileio.h"#include "encode.h"#include "decode.h"//------------------------------------------------------------------------------ HANDLE h_file_sour;HANDLE h_file_dest;HANDLE h_file;CHAR* file_name_in = "d:\\code.c";CHAR* file_name_out= "d:\\encode.e";CHAR* file_name = "d:\\decode.d";//------------------------------------------------------------------------------ int main(int argc, char *argv[]){h_file_sour = file_handle(file_name_in);h_file_dest = file_handle(file_name_out);h_file = file_handle(file_name);encode(h_file_sour, h_file_dest); // decode(h_file_dest,h_file);CloseHandle(h_file_sour);CloseHandle(h_file_dest);CloseHandle(h_file);return 0;}。

相关文档
最新文档