久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

專注電子技術(shù)學(xué)習(xí)與研究
當(dāng)前位置:單片機(jī)教程網(wǎng) >> MCU設(shè)計(jì)實(shí)例 >> 瀏覽文章

LZW壓縮類實(shí)現(xiàn)無損壓縮比居然到了可恥的4:1

作者:huqin   來源:本站原創(chuàng)   點(diǎn)擊數(shù):  更新時(shí)間:2013年12月17日   【字體:

一番蛋疼的調(diào)試修改終于工作正常

#include "stdafx.h"
//CLZW類實(shí)現(xiàn)
#include "LZW.h"

//華麗的分割線--------------------------------------------------------
//創(chuàng)建對象時(shí)初始化數(shù)據(jù)
CLZW::CLZW()
{
hash_code=0;
hash_prefix=0;
hash_suffix=0;
symbol_head=0;
symbol_tail=0;
symbol_stack=0;
}

//華麗的分割線--------------------------------------------------------
CLZW::~CLZW()
//銷毀對象時(shí)釋放內(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;//第一個(gè)未用的代碼值
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ù)制最后兩個(gè)字節(jié)
last_bit=0;//緩沖區(qū)為空
cur_bits=0;//緩沖區(qū)的第一個(gè)字符
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個(gè)比特
{
int offs,ret,count;
if((cur_bits+n_bits)>last_bit)
{
//重新裝 載緩沖區(qū)
if(out_of_blocks)
{
return EOFCode;
}
//保持最后兩個(gè)字節(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;
}
//重置計(jì)數(shù)器
cur_bits=(cur_bits-last_bit)+16;
last_byte=2+count;
last_bit=last_byte*8;
}
//形成積累下一個(gè)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<<n_bits)-1);
cur_bits+=n_bits;
return ret;
}

//華麗的分割線--------------------------------------------------------
int CLZW::LzwReadByte()
{
static int oldcode;//前一個(gè)LZW符
static int firstcode;//原碼擴(kuò)展后的第一個(gè)字節(jié)
register int code;//當(dāng)前工作代碼
int incode;//保存實(shí)際的輸入代碼

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){
//保證它是一個(gè)未壓縮的字節(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;
}

//如果是一個(gè)符號把它擴(kuò)展后放入棧
while (code>=ClearCode)
{
//符號頭:一個(gè)字節(jié)符
*sp++=symbol_tail[code];
//符號尾:另一個(gè)LZW符號
code=symbol_head[code];

}

//表示是一個(gè)未被壓縮的字節(jié)
firstcode=code;

//判別表中是否有空間
if((code=code_counter)<LZW_TABLE_SIZE)
{
//定義一個(gè)新的符號=原來的符號+這個(gè)符號擴(kuò)展后的頭字節(jié)
symbol_head[code]=oldcode;
symbol_tail[code]=(UINT_8) firstcode;
code_counter++;

//增加n_bits
if((code_counter>=maxcode)&&(n_bits<MAX_LZW_BITS))
{
n_bits++;
maxcode<<=1;
}
}

//保存最后的輸入符號
oldcode=incode;
//返回符號擴(kuò)展后的第一個(gè)字節(jié)
return firstcode;

}//華麗的分割線--------------------------------------------------------
void CLZW::flush_packet()
//清空所有積累的數(shù)據(jù)
{
if(bytesinpkt>0)
{
//所寫入的長度必須大于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)<<cur_bits;
cur_bits+=n_bits;
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;
}
}
}

//如果期望的符號不在表中
output(waiting_code);
if(free_code<LZW_TABLE_SIZE)
{
//在hash表里增加一個(gè)符號
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();
}

 

關(guān)閉窗口

相關(guān)文章

主站蜘蛛池模板: 国产成人91视频 | 国产一区二区三区日韩 | 中文字幕乱码视频32 | 国产精品国产成人国产三级 | 久久精品中文字幕 | 国产精品大片 | 国产色婷婷久久99精品91 | 亚洲一区二区久久 | 亚洲日韩中文字幕一区 | 超碰成人免费 | 成人影院av| 国产精品久久久久久久免费观看 | 亚洲一区二区在线 | 毛片a级 | 欧美综合久久 | jav成人av免费播放 | 久久久久国产精品一区 | 久久精品小视频 | 色综合天天天天做夜夜夜夜做 | 男人的天堂久久 | 99精品亚洲国产精品久久不卡 | 日本人麻豆| 国产色| 亚洲国产aⅴ成人精品无吗 亚洲精品久久久一区二区三区 | 91网视频| 欧美日韩1区2区 | 无码日韩精品一区二区免费 | www.日本精品 | 国产精品美女久久久久久久久久久 | 欧美99 | 亚洲一区电影 | 99久久视频| 久草青青草 | 亚洲欧美综合精品久久成人 | 农村真人裸体丰满少妇毛片 | 久久国产欧美日韩精品 | 91精品国产一区二区三区 | 久久久一区二区 | 午夜视频一区二区 | 天天草天天干 | 国产精品成人av |