static int ec_encode(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned _ftb) { unsigned l; unsigned r; int c; int s; unsigned d; unsigned u; unsigned v; #if defined(EC_MULT_FREE) unsigned ft; #endif /*printf("0x%08X %2i 0x%04X [0x%04X,0x%04X) {0x%04X}\n", _this->low,_this->cnt,_this->rng,_fl,_fh,1<<_ftb);*/ l=_this->low; c=_this->cnt; r=_this->rng; #if defined(EC_MULT_FREE) ft=1<<_ftb; s=r>=ft<<1; if(s)ft<<=1; _fl<<=s; _fh<<=s; d=r-ft; u=_fl+EC_MINI(_fl,d); v=_fh+EC_MINI(_fh,d); #else u=r*_fl>>_ftb; v=r*_fh>>_ftb; #endif r=v-u; l+=u; d=16-EC_ILOGNZ_32(r); s=c+d; /*TODO: Right now we flush every time we have at least one byte available. Instead we should use an ec_window and flush right before we're about to shift bits off the end of the window. For a 32-bit window this is about the same amount of work, but for a 64-bit window it should be a fair win.*/ if(s>=0) { unsigned short *buf; size_t cbuf; size_t nbuf; unsigned m; buf=_this->buf; cbuf=_this->cbuf; nbuf=_this->nbuf; if(nbuf>=cbuf) { cbuf=(cbuf<<1)+2; buf=(unsigned short *)realloc(buf,cbuf*sizeof(*buf)); if(buf==NULL)return -ENOMEM; } c+=16; m=(1<<c)-1; if(s>=8) { buf[nbuf++]=(unsigned short)(l>>c); l&=m; c-=8; m>>=8; }
unsigned ec_decode_bin(ec_dec *_this,unsigned bits){ unsigned s; ec_uint32 ft; ft = (ec_uint32)1<<bits; _this->nrm=_this->rng>>bits; s=(unsigned)((_this->dif-1)/_this->nrm); return ft-EC_MINI(s+1,ft); }
void ec_dec_update(ec_dec *_this,unsigned _fl,unsigned _fh,unsigned _ft){ ec_uint32 fl; ec_uint32 fh; ec_uint32 ft; ec_uint32 r; ec_uint32 s; ec_uint32 d; /*Step 4: Evaluate the two partition function values.*/ fl=(ec_uint32)_fl<<_this->nrm; fh=(ec_uint32)_fh<<_this->nrm; ft=(ec_uint32)_ft<<_this->nrm; d=_this->rng-ft; r=fh+EC_MINI(fh,d); s=fl+EC_MINI(fl,d); /*Step 5: Update the interval.*/ _this->rng=r-s; _this->dif-=s; /*Step 6: Normalize the interval.*/ ec_dec_normalize(_this); }
unsigned ec_decode_bin(ec_dec *_this,unsigned _bits){ unsigned s; _this->nrm=_this->rng>>_bits; s=(unsigned)((_this->dif-1)/_this->nrm); return (1<<_bits)-EC_MINI(s+1,1<<_bits); }
unsigned ec_decode(ec_dec *_this,unsigned _ft){ unsigned s; _this->nrm=_this->rng/_ft; s=(unsigned)((_this->dif-1)/_this->nrm); return _ft-EC_MINI(s+1,_ft); }
unsigned ec_decode_bin(ec_dec *_this,unsigned _bits){ unsigned s; _this->ext=_this->rng>>_bits; s=(unsigned)(_this->val/_this->ext); return (1<<_bits)-EC_MINI(s+1,1<<_bits); }
unsigned ec_decode(ec_dec *_this,unsigned _ft){ unsigned s; _this->ext=_this->rng/_ft; s=(unsigned)(_this->val/_this->ext); return _ft-EC_MINI(s+1,_ft); }