/* Written 2005 By Brendan G Bohannon I release this under the public domain. However, I do requst mention in any derived source if applicable. This is intended, where possible, to be used as an example of an encoder. */ #include #include #include #include //#define WHUFF_NOLONGLONG //'long long' type not present //#define WHUFF_BITIO //a few extra functions, may cost speed #define WHUFF_LOWER 0x00000000 #define WHUFF_UPPER 0xFFFFFFFF #define WHUFF_NEUTRAL 0x8000 #define WHUFF_WBITS 16 #define WHUFF_WMASK ((1<1) { c++; v++; v>>=1; } return(c); } unsigned int PDRLELZ_DataAdler32(void *buf, int sz, unsigned int lcrc) { byte *s; int i, c, s1, s2; s=buf; s1=lcrc&0xFFFF; s2=(lcrc>>16)&0xFFFF; for(i=0; i>WHUFF_WBITS)*w; v+=((r&WHUFF_WMASK)*w)>>WHUFF_WBITS; #else v=whuff_rmin+((((ull)r)*((ull)(w<<(32-WHUFF_WBITS))))>>32); #endif if(i)whuff_rmin=v+1; else whuff_rmax=v; //while bits while((whuff_rmin&0xFF000000)==(whuff_rmax&0xFF000000)) { HUFF_OutputByte(whuff_rmin>>24); whuff_rmin<<=8; whuff_rmax<<=8; whuff_rmax|=255; } } int WHUFF_InputBit(unsigned int w) { unsigned int r, r2, v, i; r=whuff_rmax-whuff_rmin; #ifdef WHUFF_NOLONGLONG v=whuff_rmin+(r>>WHUFF_WBITS)*w; v+=((r&WHUFF_WMASK)*w)>>WHUFF_WBITS; #else v=whuff_rmin+((((ull)r)*((ull)(w<<(32-WHUFF_WBITS))))>>32); #endif i=(whuff_rval>v); if(i)whuff_rmin=v+1; else whuff_rmax=v; //while bits while((whuff_rmin&0xFF000000)==(whuff_rmax&0xFF000000)) { whuff_rmin<<=8; whuff_rmax<<=8; whuff_rmax|=255; whuff_rval<<=8; whuff_rval|=HUFF_InputByte(); } return(i); } int WHUFF_InputModelBit(unsigned char *model, int ctx) { unsigned int r, v, i, w; // w=warith2_divtab2[((unsigned short *)model)[ctx]]; r=whuff_rmax-whuff_rmin; // v=whuff_rmin+(((ull)r*(ull)w)>>32); #ifdef WHUFF_NOLONGLONG w=warith2_divtab[((unsigned short *)model)[ctx]]; v=whuff_rmin+(r>>WHUFF_WBITS)*w; v+=((r&WHUFF_WMASK)*w)>>WHUFF_WBITS; #else w=warith2_divtab2[((unsigned short *)model)[ctx]]; v=whuff_rmin+(((ull)r*(ull)w)>>32); #endif i=(whuff_rval>v); if(i) { whuff_rmin=v+1; model[(ctx<<1)|1]++; if(!model[(ctx<<1)|1]) { model[(ctx<<1)|0]>>=1; model[(ctx<<1)|1]=0x80; } }else { whuff_rmax=v; model[ctx<<1]++; if(!model[ctx<<1]) { model[(ctx<<1)|0]=0x80; model[(ctx<<1)|1]>>=1; } } //while bits while(!((whuff_rmin^whuff_rmax)&0xFF000000)) { whuff_rmin<<=8; whuff_rmax<<=8; whuff_rmax|=255; whuff_rval<<=8; whuff_rval|=HUFF_InputByte(); } return(i); } void WHUFF_FlushWBits() { while((whuff_rmin!=WHUFF_LOWER) || (whuff_rmax!=WHUFF_UPPER)) { HUFF_OutputByte(whuff_rmin>>24); whuff_rmin<<=8; whuff_rmax<<=8; whuff_rmax|=255; } } int WHUFF_SetupEncode(byte *out) { huff_outbits=0; huff_winbuf=out; huff_winofs=0; whuff_rmin=WHUFF_LOWER; whuff_rmax=WHUFF_UPPER; } int WHUFF_SetupDecode(byte *in) { int i; huff_outbits=0; huff_winbuf=in; huff_winofs=0; whuff_rmin=WHUFF_LOWER; whuff_rmax=WHUFF_UPPER; whuff_rval=WHUFF_LOWER; for(i=0; i<4; i++) whuff_rval=(whuff_rval<<8)|HUFF_InputByte(); } //arithmatic coder model/init //arithmetic frontend/modeler #if 1 INLINE int WArith2_Predict(unsigned char *model, int ctx) { return(warith2_divtab[((unsigned short *)model)[ctx]]); } #endif int WArith2_Update(unsigned char *model, int ctx, int v) { if(v) { model[(ctx<<1)|1]++; if(!model[(ctx<<1)|1]) { model[(ctx<<1)|0]>>=1; model[(ctx<<1)|1]=0x80; } }else { model[(ctx<<1)]++; if(!model[ctx<<1]) { model[(ctx<<1)|0]=0x80; model[(ctx<<1)|1]>>=1; } } } int WArith2_EncodeSymbol(int v) { int i, j, k; i=WARITH2_BITS; while(i--) { j=(v>>i)&1; k=WArith2_Predict(warith2_model, warith2_ctx); WArith2_Update(warith2_model, warith2_ctx, j); WHUFF_OutputBit(j, k); warith2_ctx=((warith2_ctx<<1)|j)&warith2_ctxmask; } } int WArith2_DecodeSymbol() { int i, j; i=WARITH2_BITS; while(i--) { j=WHUFF_InputModelBit(warith2_model, warith2_ctx); warith2_ctx=((warith2_ctx<<1)|j)&warith2_ctxmask; } return(warith2_ctx&((1<>8)&0xFF; out[10]=(sz>>16)&0xFF; out[11]=(sz>>24)&0xFF; i=PDRLELZ_DataAdler32(in, sz, 1); out[12]=i&0xFF; out[13]=(i>>8)&0xFF; out[14]=(i>>16)&0xFF; out[15]=(i>>24)&0xFF; WArith2_SetupEncode(out+16); cs=in; ce=in+sz; while(cs