From 8c23a3a0fd2dae1407a56e994485b0f9c57910cc Mon Sep 17 00:00:00 2001 From: "Timothy B. Terriberry" Date: Fri, 17 Dec 2010 14:32:00 -0800 Subject: [PATCH] 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. --- libcelt/entdec.h | 3 ++- libcelt/rangedec.c | 18 +++++++++--------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/libcelt/entdec.h b/libcelt/entdec.h index 66960b2c..6a3841bf 100644 --- a/libcelt/entdec.h +++ b/libcelt/entdec.h @@ -47,7 +47,8 @@ struct ec_dec{ 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; diff --git a/libcelt/rangedec.c b/libcelt/rangedec.c index 462fce41..97dd7ff6 100644 --- a/libcelt/rangedec.c +++ b/libcelt/rangedec.c @@ -126,11 +126,11 @@ static inline void ec_dec_normalize(ec_dec *_this){ _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<dif=(_this->dif<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 @@ void ec_dec_init(ec_dec *_this,ec_byte_buffer *_buf){ _this->buf=_buf; _this->rem=ec_dec_in(_this); _this->rng=1U<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,14 +151,14 @@ void ec_dec_init(ec_dec *_this,ec_byte_buffer *_buf){ 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); } 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 @@ int ec_dec_bit_prob(ec_dec *_this,unsigned _prob){ r=_this->rng; d=_this->dif; s=(r>>16)*_prob; - val=d<=s; + val=ddif=d-s; _this->rng=val?s:r-s; ec_dec_normalize(_this); @@ -215,7 +215,7 @@ int ec_dec_cdf(ec_dec *_this,const int *_cdf,unsigned _ftb){ val=0; t=0; s=IMUL32(r,(1<<_ftb)-_cdf[0]); - while(d<=s){ + while(d