Lz77编码 解码程序

来源:互联网 发布:is语音网络兼职可信吗 编辑:程序博客网 时间:2024/05/21 08:51
/* * lz77.c * *  Created on: 2014-5-9 *      Author: Administrator */#include <stdio.h>#include <stdlib.h>#define MAX_WND_SIZE 64#define BITPOOL 1024#define COLOMB3char wnd[MAX_WND_SIZE],buf[MAX_WND_SIZE];int start=0,len=0,off=0,cl=0,bp=0;unsigned char bitpool[BITPOOL];int offbits;int movewnd();int match();int offbitnum();int fillbitpool(int v,FILE *f);int writeint(int v,int bitnum,FILE *f);int writeofflen(FILE *f,char c);int mypow(int a,int b);int main(){int c,n=0;FILE *f = fopen("1.txt","rb");FILE *f2 = fopen("1","wb");if((n=fread(wnd,sizeof(char),MAX_WND_SIZE,f))<MAX_WND_SIZE)return 0;fwrite(wnd,sizeof(char),MAX_WND_SIZE,f2);offbitnum();while((c=fgetc(f))!=EOF){len=0;off=0;cl=0;buf[len]=c;len++;while((cl=match(buf,len))==len&&(c=fgetc(f))!=EOF){buf[len]=c;len++;}//printf(" %d %d %c",off,cl,buf[len-1]);writeofflen(f2,buf[len-1]);if(feof(f))break;movewnd();}if(bp>0){fwrite(bitpool,sizeof(unsigned char),(bp-1)/8+1,f2);}fflush(f2);fclose(f);fclose(f2);return 1;}int movewnd(){int i,j;for(i=start,j=0;j<cl+1;i++,j++){wnd[i%MAX_WND_SIZE]=buf[j];}start=i%MAX_WND_SIZE;//printf("current wnd:\n");//for(i=start;i<MAX_WND_SIZE+start;i++){//printf("%c ",wnd[i%MAX_WND_SIZE]);//}//printf("\n");return 1;}int match(){int i,c=cl;for(i=off+cl+start;i<MAX_WND_SIZE+start;i++){if(buf[c]==wnd[i%MAX_WND_SIZE]){c++;if(c==len){cl=c;off=(i-cl+1)-start;return cl;}}else{if(c>cl){cl=c;off=(i-cl+1)-start;}c=0;}}return cl;}int offbitnum(){int size=MAX_WND_SIZE-1;int n=sizeof(int)*8-1;while(!(size&(1<<n))){n--;}offbits=n+1;return n+1;}int fillbitpool(int v,FILE *f){if(v>0){bitpool[bp/8]=bitpool[bp/8]|(1<<(8-bp%8-1));}else{bitpool[bp/8]=bitpool[bp/8]&(0xFE<<(8-bp%8-1));}bp++;//printf("%d:%d:%d ",v,bp-1,(bitpool[(bp-1)/8]>>(8-bp%8))&1);if(bp>=BITPOOL*8){fwrite(bitpool,sizeof(unsigned char),BITPOOL,f);bp=0;}return 1;}int writeint(int v,int bitnum,FILE *f){int bn=bitnum,vb;printf("\nv=%d ",v);while(bn>0){vb=v>>(bn-1)&0x1;printf("%d ",vb);fillbitpool(vb,f);bn--;}printf("\n");return 1;}int writeofflen(FILE *f,char c){printf("bp:%d off:%d ",bp,off);writeint(off,offbits,f);int l=cl+1;int b=mypow(2,COLOMB);int q=(l-1)/b;int r=l-q*b-1;while(q>0){fillbitpool(1,f);q--;}fillbitpool(0,f);writeint(r,COLOMB,f);writeint((int)c,8,f);printf("len:%d c:%c bp:%d\n",cl,c,bp);return 1;}int mypow(int a,int b){int c=a;if(b==0)return 1;while(b>1){c*=a;b--;}return c;}
/* * lz77de.c * *  Created on: 2014-5-12 *      Author: Administrator */#include <stdio.h>#define MAX_WND_SIZE 64#define BITPOOL 1024#define COLOMB 3char wnd[MAX_WND_SIZE],buf[MAX_WND_SIZE];int start=0,len=0,off=0,cl=0,bp=0;unsigned char bitpool[BITPOOL];int offbits;int mypow(int a,int b);int offbitnum();int main(){int c,n=0,i,col,len_=0;FILE *f = fopen("1","rb");FILE *f2 = fopen("2.txt","w");offbitnum();col=mypow(2,COLOMB);if((n=fread(wnd,sizeof(char),MAX_WND_SIZE,f))<MAX_WND_SIZE)return 0;printf("%s",wnd);while((n=fread(bitpool,sizeof(unsigned char),BITPOOL,f))>0){//printf("n=%d\n",n);bp=0;while(bp<n*8){off=0;len=0;len_=0;//printf("bp:%d (%x %x %x)",bp,bitpool[bp/8],bitpool[bp/8+1],bitpool[bp/8+2]);for(i=0;i<offbits;i++){off=off*2+((bitpool[bp/8]>>(8-bp%8-1))&1);bp++;if(bp>=n*8){n=fread(bitpool,sizeof(unsigned char),BITPOOL,f);bp=0;}}while(((bitpool[bp/8]>>(8-bp%8-1))&1)==1){bp++;len++;if(bp>=n*8){n=fread(bitpool,sizeof(unsigned char),BITPOOL,f);bp=0;}}len=col*len+1;bp++;if(bp>=n*8){n=fread(bitpool,sizeof(unsigned char),BITPOOL,f);bp=0;}for(i=0;i<COLOMB;i++){len_=len_*2+((bitpool[bp/8]>>(8-bp%8-1))&1);bp++;if(bp>=n*8){n=fread(bitpool,sizeof(unsigned char),BITPOOL,f);bp=0;}}len+=len_-1;c=0;//printf("off:%d len:%d ",off,len);for(i=0;i<8;i++){c=c*2+((bitpool[bp/8]>>(8-bp%8-1))&1);bp++;if(bp>=n*8){n=fread(bitpool,sizeof(unsigned char),BITPOOL,f);bp=0;}}//printf("c:(%d) bp:%d\n",c,bp);//printf("off:%d len:%d string:",off,len);for(i=off+start;i<off+len+start;i++){printf("%c",wnd[i%MAX_WND_SIZE]);//fputc(wnd[i%MAX_WND_SIZE],f2);}printf("%c",c);//fputc(c,f2);for(i=start;i<start+len;i++){wnd[i%MAX_WND_SIZE]=wnd[(i+off)%MAX_WND_SIZE];}wnd[(start+len)%MAX_WND_SIZE]=c;start=(start+len+1)%MAX_WND_SIZE;//printf("\nwnd:");for(i=start;i<start+MAX_WND_SIZE;i++){//printf("%c",wnd[i%MAX_WND_SIZE]);}//printf(" wnd\n");}}return 1;}int offbitnum(){int size=MAX_WND_SIZE-1;int n=sizeof(int)*8-1;while(!(size&(1<<n))){n--;}offbits=n+1;return n+1;}int mypow(int a,int b){int c=a;if(b==0)return 1;while(b>1){c*=a;b--;}return c;}

我的环境是WIN7+Eclipse CDT+MinGw。Lz77原理http://hi.baidu.com/cekytggeaqbgnoe/item/c4c66e0ae3033b25a1312d65。

另外我发现,在用fopen以r模式打开文件的时候,无论用fgetc还是fread得到的字符都把0D 0A当做一个字符。当用rb模式打开的时候一切就正常了,只是用printf输出的时候有些怪异。

源文件:abcabcabc输出10个字符:abcabc


0 0
原创粉丝点击