Apple的LZF算法解析
有关LZF算法的相关解析文档比较少,但是Apple对LZF的开源,可以让我们对该算法进行一个简单的解析。LZFSE 基于 Lempel-Ziv ,并使用了有限状态熵编码。LZF采用类似lz77和lzss的混合编码。使用3种“起始标记”来代表每段输出的数据串。
接下来看一下开源的LZF算法的实现源码。
1.定义的全局字段:
privatereadonlylong[]_hashTable=newlong[Hsize];privateconstuintHlog=14;privateconstuintHsize=(1<<14);privateconstuintMaxLit=(1<<5);privateconstuintMaxOff=(1<<13);privateconstuintMaxRef=((1<<8)+(1<<3));
2.使用LibLZF算法压缩数据:
///<summary>///使用LibLZF算法压缩数据///</summary>///<paramname="input">需要压缩的数据</param>///<paramname="inputLength">要压缩的数据的长度</param>///<paramname="output">引用将包含压缩数据的缓冲区</param>///<paramname="outputLength">压缩缓冲区的长度(应大于输入缓冲区)</param>///<returns>输出缓冲区中压缩归档的大小</returns>publicintCompress(byte[]input,intinputLength,byte[]output,intoutputLength){Array.Clear(_hashTable,0,(int)Hsize);uintiidx=0;uintoidx=0;varhval=(uint)(((input[iidx])<<8)|input[iidx+1]);varlit=0;for(;;){if(iidx<inputLength-2){hval=(hval<<8)|input[iidx+2];longhslot=((hval^(hval<<5))>>(int)(((3*8-Hlog))-hval*5)&(Hsize-1));varreference=_hashTable[hslot];_hashTable[hslot]=iidx;longoff;if((off=iidx-reference-1)<MaxOff&&iidx+4<inputLength&&reference>0&&input[reference+0]==input[iidx+0]&&input[reference+1]==input[iidx+1]&&input[reference+2]==input[iidx+2]){uintlen=2;varmaxlen=(uint)inputLength-iidx-len;maxlen=maxlen>MaxRef?MaxRef:maxlen;if(oidx+lit+1+3>=outputLength)return0;dolen++;while(len<maxlen&&input[reference+len]==input[iidx+len]);if(lit!=0){output[oidx++]=(byte)(lit-1);lit=-lit;dooutput[oidx++]=input[iidx+lit];while((++lit)!=0);}len-=2;iidx++;if(len<7){output[oidx++]=(byte)((off>>8)+(len<<5));}else{output[oidx++]=(byte)((off>>8)+(7<<5));output[oidx++]=(byte)(len-7);}output[oidx++]=(byte)off;iidx+=len-1;hval=(uint)(((input[iidx])<<8)|input[iidx+1]);hval=(hval<<8)|input[iidx+2];_hashTable[((hval^(hval<<5))>>(int)(((3*8-Hlog))-hval*5)&(Hsize-1))]=iidx;iidx++;hval=(hval<<8)|input[iidx+2];_hashTable[((hval^(hval<<5))>>(int)(((3*8-Hlog))-hval*5)&(Hsize-1))]=iidx;iidx++;continue;}}elseif(iidx==inputLength)break;lit++;iidx++;if(lit!=MaxLit)continue;if(oidx+1+MaxLit>=outputLength)return0;output[oidx++]=(byte)(MaxLit-1);lit=-lit;dooutput[oidx++]=input[iidx+lit];while((++lit)!=0);}if(lit==0)return(int)oidx;if(oidx+lit+1>=outputLength)return0;output[oidx++]=(byte)(lit-1);lit=-lit;dooutput[oidx++]=input[iidx+lit];while((++lit)!=0);return(int)oidx;}
3.使用LibLZF算法重载压缩数据:
///<summary>///使用LibLZF算法解压缩数据///</summary>///<paramname="input">参考数据进行解压缩</param>///<paramname="inputLength">要解压缩的数据的长度</param>///<paramname="output">引用包含解压缩数据的缓冲区</param>///<paramname="outputLength">输出缓冲区中压缩归档的大小</param>///<returns>返回解压缩大小</returns>publicintDecompress(byte[]input,intinputLength,byte[]output,intoutputLength){uintiidx=0;uintoidx=0;do{uintctrl=input[iidx++];if(ctrl<(1<<5)){ctrl++;if(oidx+ctrl>outputLength){return0;}dooutput[oidx++]=input[iidx++];while((--ctrl)!=0);}else{varlen=ctrl>>5;varreference=(int)(oidx-((ctrl&0x1f)<<8)-1);if(len==7)len+=input[iidx++];reference-=input[iidx++];if(oidx+len+2>outputLength){return0;}if(reference<0){return0;}output[oidx++]=output[reference++];output[oidx++]=output[reference++];dooutput[oidx++]=output[reference++];while((--len)!=0);}}while(iidx<inputLength);return(int)oidx;}
以上是LZF算法的代码。
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。