lzw压缩算法的c语言实现

yanglilibaobao 2007-04-11 10:14:28
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;
...全文
1094 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
DonaldKnuth 2007-04-11
  • 打赏
  • 举报
回复
//compress.h
#ifndef __COMPRESS_H__
#define __COMPRESS_H__

//==========================================================
// 使用的头文件
//==========================================================
#include "ChainHashTable.h"
#include <fstream>
#include <iostream>
#include <string>
#include <cstdlib>
#include <cmath>

using namespace std;



//compress类的声明
class compress;
//==========================================================
// element类的定义
//==========================================================
class element
{
friend class compress;
public:
operator unsigned long() const {return key;}
element& operator =(unsigned long y)
{key = y; return *this;}
private:
int code; //存储码值
unsigned long key; //存储关键字
private:

};


//==========================================================
//compress 类的定义
//==========================================================

class compress
{
public:
compress():status(0){ } //初始化为0
~compress(){};

public:
/************************************************************/
/* 功 能 : 建立输入输出流 */
/* 参 数 : argc表示传递的字符串个数,argv为指向字符串的指针数组 */
/* 返回值 : 无 */
/* 说 明 : 以给定的文件名建立输入输出, */
/* 如没有提供文件名则提示用户输入 */
/************************************************************/
void SetFiles(int argc, char* argv[]);

/************************************************************/
/* 功 能 : 从输入文件输入字符并进行相应的编码 */
/* 说 明 : 利用hash表建立字符串与编码之间的关系 */
/* 对输入字符进行编码并将编码输出到文件中 */
/************************************************************/
void Compress();
private:
/************************************************************/
/* 功 能 : 输出编码到文件中 */
/* 参 数 : pcode为当前要输出的编码 */
/* 返回值 : 无 */
/************************************************************/
void Output(unsigned long pcode);
private:
int LeftOver; // 尚未输出的代码位
int status; // 0 意味着在LeftOver中没有未输出的位
ifstream in;
ofstream out;
private:
//各种常量的声明
static const unsigned int D = 4099; // 散列函数的除数
static const unsigned int codes = 4096; // 2^12
static const unsigned int ByteSize = 8;
static const unsigned int excess = 4; // 12 - ByteSize
static const unsigned int alpha = 256; // 2^ByteSize
static const unsigned int mask1 = 255; // alpha - 1
static const unsigned int mask2 = 15; // 2^excess - 1
};


#endif


//compress.cpp
//=====================================================
//文件描述: compress类各成员定义
//时间: 2006\11\2
//=====================================================

#include "compress.h"

static const unsigned int D;
static const unsigned int codes;
static const unsigned int ByteSize;
static const unsigned int excess;
static const unsigned int alpha;
static const unsigned int mask1;
static const unsigned int mask2;

//SetFiles成员函数定义
void compress::SetFiles(int argc, char * argv[])
{
// 创建输入流和输出流
char OutputFile[50], InputFile[50];
// 检查是否提供了文件名
if (argc >= 2) strcpy(InputFile, argv[1]);
else
{ // 没有提供文件名, 提示用户输入
cout<<"Enter name of file to compress" <<endl;
cout<<"File name should have no extension" <<endl;
cin>>InputFile;
}
// 文件名不应有扩展名
if(strchr(InputFile, '.'))
{
cerr<<"File name has extension" <<endl;
exit(1);
}
// 以二进制方式打开文件
in.open(InputFile, ios::binary);
// in.open(InputFile); //对于g + +而言
if(in.fail())
{
cerr<<"Cannot open "<<InputFile<<InputFile<< endl;
exit(1);
}

strcpy(OutputFile, InputFile);
strcat(OutputFile, ".zzz");
out.open(OutputFile, ios::binary);

}
//----------------------------------------------------------

//output成员函数定义
void compress::Output(unsigned long pcode)
{
// 输出8位, 余下的位保存在LeftOver中
unsigned char c, d;
if(status)
{ // 余下4位
d = pcode & mask1; //右边ByteSize位
c = (LeftOver << excess) | (pcode >> ByteSize);
out.put(c);
out.put(d);
status = 0;
}
else
{
LeftOver = pcode & mask2; // 右边多余的位
c = pcode >> excess;
out.put(c);
status = 1;
}
}
//----------------------------------------------------------

//Compress成员函数定义
void compress::Compress()
{
// Lempel-Ziv-Welch压缩器
// 定义并初始化代码字典
ChainHashTable<element, unsigned long> h(D);
element e;
for(int i = 0; i < alpha; i++)
{ // 初始化
e.key = i;
e.code = i;
h.Insert(e);
}
int used = alpha; // 所使用的代码数目
// 输入并压缩
unsigned char c;
//char c;
//in.get(c); // 输入文件的第一个字符
in>>c;
unsigned long pcode = c; // 前缀代码
if (!in.eof())
{ // 文件长度> 1
do
{ // 处理文件的其余部分
//in.get(c);
in>>c;
if(in.eof()) break; // 完成
unsigned long k = (pcode << ByteSize) + c;
// 检查k的代码是否已经在字典中
if(h.Search(k, e))
pcode = e.code; // 在字典中
else
{ // k不在表中
Output(pcode);
if(used < codes) // 创建新的代码
{
e.code = used++;
e.key = (pcode << ByteSize) | c;
h.Insert(e);
}
pcode = c;
}
}
while(true);
// 输出最后一个(部分)代码
Output(pcode);
if(status)
{
c = LeftOver << excess;
out.put(c);
}
}
out.close();
in.close();
}
//---------------------------------------------------------
DonaldKnuth 2007-04-11
  • 打赏
  • 举报
回复
lzw压缩算法的关键在于文本的字符串映射为数字编码,及相当于建立一个字典,可以使用散列表来建立这个关系,给出一个链表散列模板类的实现作参考。

//sortedchain.h
#ifndef _SORTEDCHAIN_H_
#define _SORTEDCHAIN_H_

#include <exception>

//SortedChain类的声明,注意格式
//*********************************************************
template<typename E, typename K> //注:这里的模板声明必不可少
class SortedChain; //class SortedChain类的声明
//*********************************************************


//链表节点定义
//*********************************************************
template <typename E, typename K>
class SortedChainNode
{
friend SortedChain<E, K>;
private:
E data; //数据域
SortedChainNode<E, K> *link;
};
//********************************************************


//SortedChain类的定义
//********************************************************
template<typename E, typename K>
class SortedChain
{
public:
SortedChain() { first=0; }
//析构函数
~SortedChain();

bool IsEmpty() const {return first==0;}
int Length() const;
bool Search(const K& k , E& e) const;
SortedChain<E, K> & Delete(const K& k , E& e);
SortedChain<E, K> & Insert(const E& e);
SortedChain<E, K> & DistinctInsert(const E& e);

//自定义的异常处理成员类
public:
class BadInput:public std::exception
{
public:
virtual const char* what() const throw()
{
return "Bad Input";
}
};

private:
SortedChainNode<E, K> *first;
};
//*********************************************************

//析构函数定义
template<typename E, typename K>
SortedChain<E, K>::~SortedChain()
{
SortedChainNode<E, K> * next; //指向first的下一个节点
while(first)
{
next = first->link;
delete first;
first = next;
}
}
//-------------------------------------------------------------



//返回链表中元素的总数
template<typename E, typename K>
int SortedChain<E, K>::Length() const
{
SortedChainNode<E, K> * current = first;
int len = 0;
while(current)
{
len++;
current = current->link;
}
return len;
}


//Search成员函数定义
template<typename E, typename K>
bool SortedChain<E, K>::Search(const K & k, E& e) const
{ // 搜索与k匹配的元素,结果放入e
// 如果没有匹配的元素,则返回false
SortedChainNode<E,K> *p = first;
// 搜索与k相匹配的元素
//涉及到p->data与k进行各种比较操作时
//是通过data类型中的重载operator k()操作符进行转换的
for (; p && p->data <k; p = p->link);
// 验证是否与k匹配operator k()操作符进行转换
if(p && p->data == k) // 与k相匹配
{
e = p->data;
return true;
}
return false; // 不存在相匹配的元素
}
//-------------------------------------------------------

//Delete成员函数定义
template<typename E, typename K>
SortedChain<E, K> & SortedChain<E, K>::Delete(const K& k, E& e)
{ // 删除与k相匹配的元素
// 并将被删除的元素放入e
// 如果不存在匹配元素,则引发异常BadInput
SortedChainNode<E, K> *p = first;
SortedChainNode<E, K> *tp = 0; //跟踪p
// 搜索与k相匹配的元素

for (; p && p->data< k; tp=p, p=p->link);
// 验证是否与k匹配operator k()操作符进行转换
if (p && p->data==k)
{
// 找到一个相匹配的元素
e = p->data; // 保存data域
// 从链表中删除p所指向的元素
if(tp)
tp->link = p->link;
else
first = p->link; // p是链首节点
delete p;
return *this;
}
throw BadInput(); // 不存在相匹配的元素
}
//-----------------------------------------------------

//DistinctInsert成员函数保证链中所有元素有不同关键字
template<typename E, typename K>
SortedChain<E, K> & SortedChain<E, K>::DistinctInsert(const E& e)
{
// 如果表中不存在关键值与e相同的元素,则插入e
//否则引发异常BadInput
SortedChainNode<E,K> *p = first, *tp = 0; // 跟踪p
// 移动tp 以便把e 插入到t p之后
for (; p && p->data< e; tp=p, p = p->link);
// 检查关键值是否重复
if(p && p->data == e)
throw BadInput();
// 若没有出现重复关键值, 则产生一个关键值为e的新节点
SortedChainNode<E, K> * q = new SortedChainNode<E, K>;
q->data = e;
// 将新节点插入到tp之后
q->link = p;
if(tp)
tp->link = q;
else
first = q;
return *this;
}
//--------------------------------------------------------

//Insert成员函数,链中所有元素可以有相同的关键字
template<typename E, typename K>
SortedChain<E, K> & SortedChain<E, K>
::Insert(const E& e)
{
SortedChainNode<E,K> *p = first, *tp = 0; // 跟踪p
// 移动tp 以便把e 插入到t p之后
for (; p && p->data< e; tp=p, p = p->link);

// 则产生一个关键值为e的新节点
SortedChainNode<E, K> * q = new SortedChainNode<E, K>;
q->data = e;
// 将新节点插入到tp之后
q->link = p;
if(tp)
tp->link = q;
else
first = q;
return *this;
}
//--------------------------------------------------------


#endif

//chainHashTable.h
#ifndef _CHAINHASHTABLE_H_
#define _CHAINHASHTABLE_H_

#include "SortChain.h"


//建立基于链表的哈西表
//****************************************************
template<class E, class K>
class ChainHashTable
{
public:
ChainHashTable(int divisor = 11)
{
D = divisor;
ht = new SortedChain<E, K> [D];
}
~ChainHashTable() {delete [] ht;}
bool Search(const K& k, E& e) const
{
return ht[k % D].Search(k, e);
}
ChainHashTable<E,K>& Insert(const E& e)
{
ht[e % D].DistinctInsert(e);
return *this;
}
ChainHashTable<E,K>& Delete(const K& k, E& e)
{
ht[k % D].Delete(k, e);
return *this;
}
void Output() const; // 输出散列表
private:
int D; // 总的位置数
SortedChain<E, K> *ht; // 链表
};
//******************************************************


#endif
jixingzhong 2007-04-11
  • 打赏
  • 举报
回复
代码不少,先收藏 ~
yanglilibaobao 2007-04-11
  • 打赏
  • 举报
回复
(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 code
lzw->suffix = (BYTE)code;
}
else
{
if( code < lzw->code )
{
// code also in table
// then output code chain

tmp = 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 code
tmp = 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);
}

#endif

2 下面给出一个应用上面模块的简单例子

#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;
}

3 后语

编者语:"之前研究gif文件格式时偶然接触了lzw压缩算法,于是就想自己动手实现。从一开始看人家的原码,然后跟着模仿,到现在用自己的语言表达出来,从理解原理到代码的实现花费了不少时间与精力,但是真正的快乐也就在这里,现在把她拿出来跟大家分享也就是分享快乐。"

转http://www.programfan.com/
yanglilibaobao 2007-04-11
  • 打赏
  • 举报
回复
(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 prefix


insert_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 one
lzw->cur_code_len++;
if( lzw->cur_code_len == CODE_LEN + 1 )
{
re_init_lzw( lzw );
}

}
}
else
{
// current code already in code table
// then output nothing
prefix = 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

zhouzidane46 2007-04-11
  • 打赏
  • 举报
回复
好久没看C了
看起头痛
回去有时间再慢慢琢磨
yanglilibaobao 2007-04-11
  • 打赏
  • 举报
回复
//------------------------------------------------------------------------------
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
iu_81 2007-04-11
  • 打赏
  • 举报
回复
mark
todototry 2007-04-11
  • 打赏
  • 举报
回复
mark
huiminlee 2007-04-11
  • 打赏
  • 举报
回复
楼主也做过GIF解码?
我刚去公司时做过GIF解码,不过只做了解码,是LZW压缩的逆过程。

69,364

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧