ref: 8c23a3a0fd2dae1407a56e994485b0f9c57910cc
parent: a0b664df3dd7cdaf01d1c30af928bb24c675211e
author: Timothy B. Terriberry <[email protected]>
date: Fri Dec 17 09:32:00 EST 2010
Subtract one from dif in the range decoder. It turns out to be more convenient to store dif=low+rng-code-1 instead of dif=low+rng-code. This gets rid of a decrement in the normal decode path, replaces a decrement and an "and" in the normalization loop with a single add, and makes it clear that the new ec_dec_cdf() will not result in an infinite loop. This does not change the bitstream.
--- a/libcelt/entdec.h
+++ b/libcelt/entdec.h
@@ -47,7 +47,8 @@
int rem;
/*The number of values in the current range.*/
ec_uint32 rng;
- /*The difference between the top of the current range and the input value.*/
+ /*The difference between the top of the current range and the input value,
+ minus one.*/
ec_uint32 dif;
/*Normalization factor.*/
ec_uint32 nrm;
--- a/libcelt/rangedec.c
+++ b/libcelt/rangedec.c
@@ -126,11 +126,11 @@
_this->rem=ec_dec_in(_this);
/*Take the rest of the bits we need from this new symbol.*/
sym|=_this->rem>>EC_SYM_BITS-EC_CODE_EXTRA;
- _this->dif=(_this->dif<<EC_SYM_BITS)-sym&EC_CODE_MASK;
- /*dif can never be larger than EC_CODE_TOP.
+ _this->dif=(_this->dif<<EC_SYM_BITS)-sym+((1<<EC_SYM_BITS)-1)&EC_CODE_MASK;
+ /*dif must be smaller than EC_CODE_TOP.
This is equivalent to the slightly more readable:
- if(_this->dif>EC_CODE_TOP)_this->dif-=EC_CODE_TOP;*/
- _this->dif^=_this->dif&_this->dif-1&EC_CODE_TOP;
+ if(_this->dif>=EC_CODE_TOP)_this->dif-=EC_CODE_TOP;*/
+ _this->dif^=_this->dif&EC_CODE_TOP;
}
}
@@ -138,7 +138,7 @@
_this->buf=_buf;
_this->rem=ec_dec_in(_this);
_this->rng=1U<<EC_CODE_EXTRA;
- _this->dif=_this->rng-(_this->rem>>EC_SYM_BITS-EC_CODE_EXTRA);
+ _this->dif=_this->rng-1-(_this->rem>>EC_SYM_BITS-EC_CODE_EXTRA);
/*Normalize the interval.*/
ec_dec_normalize(_this);
_this->end_byte=0; /* Required for platforms that have chars > 8 bits */
@@ -151,7 +151,7 @@
unsigned ec_decode(ec_dec *_this,unsigned _ft){
unsigned s;
_this->nrm=_this->rng/_ft;
- s=(unsigned)((_this->dif-1)/_this->nrm);
+ s=(unsigned)(_this->dif/_this->nrm);
return _ft-EC_MINI(s+1,_ft);
}
@@ -158,7 +158,7 @@
unsigned ec_decode_bin(ec_dec *_this,unsigned _bits){
unsigned s;
_this->nrm=_this->rng>>_bits;
- s=(unsigned)((_this->dif-1)/_this->nrm);
+ s=(unsigned)(_this->dif/_this->nrm);
return (1<<_bits)-EC_MINI(s+1,1<<_bits);
}
@@ -196,7 +196,7 @@
r=_this->rng;
d=_this->dif;
s=(r>>16)*_prob;
- val=d<=s;
+ val=d<s;
if(!val)_this->dif=d-s;
_this->rng=val?s:r-s;
ec_dec_normalize(_this);
@@ -215,7 +215,7 @@
val=0;
t=0;
s=IMUL32(r,(1<<_ftb)-_cdf[0]);
- while(d<=s){
+ while(d<s){
t=s;
s=IMUL32(r,(1<<_ftb)-_cdf[++val]);
}