LZW壓縮類實現(xiàn)無損壓縮比居然到了可恥的4:1
#include "stdafx.h"
//CLZW類實現(xiàn)
#include "LZW.h"
//華麗的分割線--------------------------------------------------------
//創(chuàng)建對象時初始化數(shù)據(jù)
CLZW::CLZW()
{
hash_code=0;
hash_prefix=0;
hash_suffix=0;
symbol_head=0;
symbol_tail=0;
symbol_stack=0;
}
//華麗的分割線--------------------------------------------------------
CLZW::~CLZW()
//銷毀對象時釋放內(nèi)存
{
if(hash_code) free(hash_code);
if(hash_prefix) free(hash_prefix);
if(hash_suffix) free(hash_prefix);
if(symbol_head) free(symbol_head);
if(symbol_tail) free(symbol_tail);
if(symbol_stack) free(symbol_stack);
}
//華麗的分割線--------------------------------------------------------
int CLZW::GetDataBlock(char *buf)
//零長度塊標(biāo)志數(shù)據(jù)塊結(jié)束
{
int count;
if ((count=getc(infile))!=EOF)
{
if(count>0)
{
if(fread(buf,1,count,infile)!=(size_t)count)
{
return -1;
}
}
}
return count;
}
//華麗的分割線--------------------------------------------------------
void CLZW::SkipDataBlocks()
//找到數(shù)據(jù)塊結(jié)尾
{
char buf[256];
while (GetDataBlock(buf)>0);
}
//華麗的分割線--------------------------------------------------------
void CLZW::ReInitLZW()
//初始化LZW狀態(tài)
{
n_bits=init_bits;
maxcode=ClearCode<<1;
code_counter=ClearCode+2;//第一個未用的代碼值
sp=symbol_stack;//初始化棧使其為空
}
//華麗的分割線--------------------------------------------------------
void CLZW::InitLZWCode(FILE* file,int ibits)
{
//GetCode初始化分配內(nèi)存
symbol_head=(code_int*)malloc(LZW_TABLE_SIZE*sizeof(code_int));
symbol_tail=(UINT_8*)malloc(LZW_TABLE_SIZE*sizeof(UINT_8));
symbol_stack=(UINT_8*)malloc(LZW_TABLE_SIZE*sizeof(UINT_8));
infile=file;
init_bits=ibits;
last_byte=2;//保證重新復(fù)制最后兩個字節(jié)
last_bit=0;//緩沖區(qū)為空
cur_bits=0;//緩沖區(qū)的第一個字符
out_of_blocks=false;
//LZWReadByte 初始化
ClearCode=((code_int)1<<(init_bits-1));
EOFCode=ClearCode+1;
first_byte=true;
ReInitLZW();
}
//華麗的分割線--------------------------------------------------------
int CLZW::GetCode()
//從壓縮數(shù)據(jù)中提取以后的code_size個比特
{
int offs,ret,count;
if((cur_bits+n_bits)>last_bit)
{
//重新裝 載緩沖區(qū)
if(out_of_blocks)
{
return EOFCode;
}
//保持最后兩個字節(jié)
code_buf[0]=code_buf[last_byte-2];
code_buf[1]=code_buf[last_byte-1];
//裝載更多的字節(jié)如到達(dá)結(jié)尾設(shè)置標(biāo)志
if((count=GetDataBlock(&code_buf[2]))==0)
{
out_of_blocks=true;
return EOFCode;
}
//重置計數(shù)器
cur_bits=(cur_bits-last_bit)+16;
last_byte=2+count;
last_bit=last_byte*8;
}
//形成積累下一個24位的字符
offs=cur_bits>>3;
cur_accum=code_buf[offs+2]&0xFF;
cur_accum<<=8;
cur_accum|=code_buf[offs+1]&0xFF;
cur_accum<<=8;
cur_accum|=code_buf[offs]&0xFF;
//向右積累排列cur_bit然后通過掩碼得到需要的bits數(shù)
cur_accum>>=(cur_bits&7);
ret=((int)cur_accum)&((1<
return ret;
}
//華麗的分割線--------------------------------------------------------
int CLZW::LzwReadByte()
{
static int oldcode;//前一個LZW符
static int firstcode;//原碼擴展后的第一個字節(jié)
register int code;//當(dāng)前工作代碼
int incode;//保存實際的輸入代碼
if(first_byte)
{
first_byte=false;
code=ClearCode;
}else{
//如果棧有以前讀過的符號返回它
if(sp>symbol_stack)return (int)*(--sp);
//讀入新的符號
code=GetCode();
}
if(code==ClearCode)
{
ReInitLZW();
do{
code=GetCode();
}while (code==ClearCode);
if(code>ClearCode){
//保證它是一個未壓縮的字節(jié)
code=0;
}
firstcode=oldcode=code;
return code;
}
if(code==EOFCode)
{
if(!out_of_blocks)
{
SkipDataBlocks();
out_of_blocks=true;
}
//沒有足夠的數(shù)據(jù)
return 257;
}
//得到正常未壓縮的字節(jié)或LZW符號
incode=code;
if(code>=code_counter)
{
if(code>code_counter)
{
//以免在符號表中產(chǎn)生循環(huán)
incode=0;
}
*sp++=(UINT_8) firstcode;
code=oldcode;
}
//如果是一個符號把它擴展后放入棧
while (code>=ClearCode)
{
//符號頭:一個字節(jié)符
*sp++=symbol_tail[code];
//符號尾:另一個LZW符號
code=symbol_head[code];
}
//表示是一個未被壓縮的字節(jié)
firstcode=code;
//判別表中是否有空間
if((code=code_counter)
//定義一個新的符號=原來的符號+這個符號擴展后的頭字節(jié)
symbol_head[code]=oldcode;
symbol_tail[code]=(UINT_8) firstcode;
code_counter++;
//增加n_bits
if((code_counter>=maxcode)&&(n_bits
n_bits++;
maxcode<<=1;
}
}
評論