LZW壓縮類實(shí)現(xiàn)無(wú)損壓縮比居然到了可恥的4:1
//保存最后的輸入符號(hào)
oldcode=incode;
//返回符號(hào)擴(kuò)展后的第一個(gè)字節(jié)
return firstcode;
}//華麗的分割線--------------------------------------------------------
void CLZW::flush_packet()
//清空所有積累的數(shù)據(jù)
{
if(bytesinpkt>0)
{
//所寫入的長(zhǎng)度必須大于0
packetbuf[0]=(char)bytesinpkt++;
if(fwrite(packetbuf,1,bytesinpkt,outfile)!=(size_t)bytesinpkt) printf("文件寫入錯(cuò)誤!");
bytesinpkt=0;
}
}
//華麗的分割線--------------------------------------------------------
void CLZW::CHAR_OUT(int c)
//向緩沖區(qū)增加一個(gè)字節(jié)同時(shí)在有必要時(shí)向磁盤寫數(shù)據(jù)
{
packetbuf[++bytesinpkt]=(char)(c);
if(bytesinpkt>=255) flush_packet();
}
//華麗的分割線--------------------------------------------------------
//發(fā)送一個(gè)n_bits比特的代碼并重組一個(gè)8為的字節(jié)
void CLZW::output(code_int code)
{
cur_accum|=((INT32)code)<
while(cur_bits>=8)
{
CHAR_OUT(cur_accum&0xFF);
cur_accum>>=8;
cur_bits-=8;
}
//如果下一個(gè)輸入比最大的代碼大則增加它
if(free_code>maxcode)
{
n_bits++;
if(n_bits==MAX_LZW_BITS) maxcode=LZW_TABLE_SIZE;else maxcode=MAXCODE(n_bits);
}
}
//華麗的分割線--------------------------------------------------------
void CLZW::clear_hash()
//清空hash表
{
memset((void*)hash_code,0,HSIZE*sizeof(code_int));
}
//華麗的分割線--------------------------------------------------------
void CLZW::clear_block()
//重置壓縮并發(fā)送一個(gè)清除碼
{
clear_hash();
free_code=ClearCode+2;
output(ClearCode);
n_bits=init_bits;
maxcode=MAXCODE(n_bits);
}
//華麗的分割線--------------------------------------------------------
void CLZW::compress_init(FILE* file,int ibits)
//初始化LZW壓縮
{
//初始化所有靜態(tài)變量給hash表分配內(nèi)存
hash_code=(code_int*)malloc(HSIZE*sizeof(code_int));
hash_prefix=(code_int*)malloc(HSIZE*sizeof(code_int));
hash_suffix=(UINT_8*)malloc(HSIZE*sizeof(UINT_8));
outfile=file;
n_bits=init_bits=ibits;
maxcode=MAXCODE(n_bits);
ClearCode=((code_int)1<<(init_bits-1));
EOFCode=ClearCode+1;
free_code=ClearCode+2;
first_byte=true;
//初始化緩沖區(qū)變量
bytesinpkt=0;
cur_accum=0;
cur_bits=0;
//清理hash表
clear_hash();
//給定一個(gè)初始清理字符
output(ClearCode);
}
//華麗的分割線--------------------------------------------------------
void CLZW::compress_byte(int c)
//得到和壓縮一個(gè)8位的字節(jié)
{
register hash_int i;
register hash_int disp;
if(first_byte)
{
//初始化一個(gè)等待碼
waiting_code=c;
first_byte=false;
return;
}
i=((hash_int)c<<(MAX_LZW_BITS-8))+waiting_code;
if(i>=HSIZE) i-=HSIZE;
if(hash_code[i]!=0)
{
if(hash_prefix[i]==waiting_code&&hash_suffix[i]==(UINT_8)c)
{
waiting_code=hash_code[i];
return;
}
if(i==0) disp=1; else disp=HSIZE-i;
while(1)
{
i-=disp;
if(i<0) i+=HSIZE;
if(hash_code[i]==0) break;
if(hash_prefix[i]==waiting_code&&hash_suffix[i]==(UINT_8)c)
{
waiting_code=hash_code[i];
return;
}
}
}
//如果期望的符號(hào)不在表中
output(waiting_code);
if(free_code
//在hash表里增加一個(gè)符號(hào)
hash_code[i]=free_code++;
hash_prefix[i]=waiting_code;
hash_suffix[i]=(UINT_8)c;
}else clear_block();
waiting_code=c;
}
//華麗的分割線--------------------------------------------------------
void CLZW::compress_term()
//結(jié)尾保存
{
//保存緩沖區(qū)里的代碼
if(!first_byte) output(waiting_code);
//發(fā)送一個(gè)結(jié)束代碼
output(EOFCode);
if(cur_bits>0)
{
CHAR_OUT(cur_accum&0xFF);
}
//保存緩沖區(qū)里的代碼
flush_packet();
}
評(píng)論