223 lines
15 KiB
C++
223 lines
15 KiB
C++
#include "range_decoder.h"
|
|
|
|
RangeDecoder::RangeDecoder() : m_buf(nullptr) {}
|
|
|
|
//——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
|
|
/* This is a faster version of ec_tell_frac() that takes advantage of the low (1/8 bit) resolution to use just a linear function followed by a lookup to determine the exact transition thresholds. */
|
|
uint32_t RangeDecoder::tell_frac() {
|
|
const uint32_t correction[8] = {35733, 38967, 42495, 46340, 50535, 55109, 60097, 65535};
|
|
uint32_t nbits;
|
|
uint32_t r;
|
|
int32_t l;
|
|
uint32_t b;
|
|
nbits = m_nbits_total << EC_BITRES;
|
|
l = EC_ILOG(m_rng);
|
|
r = m_rng >> (l - 16);
|
|
b = (r >> 12) - 8;
|
|
b += r > correction[b];
|
|
l = (l << 3) + b;
|
|
return nbits - l;
|
|
}
|
|
//——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
|
|
int32_t RangeDecoder::read_byte() { return m_offs < m_storage ? m_buf[m_offs++] : 0; }
|
|
//——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
|
|
int32_t RangeDecoder::read_byte_from_end() {
|
|
return m_end_offs < m_storage ? m_buf[m_storage - ++(m_end_offs)] : 0;
|
|
}
|
|
//——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
|
|
/*Normalizes the contents of val and rng so that rng lies entirely in the high-order symbol.*/
|
|
void RangeDecoder::dec_normalize() {
|
|
/*If the range is too small, rescale it and input some bits.*/
|
|
while (m_rng <= EC_CODE_BOT) {
|
|
int32_t sym;
|
|
m_nbits_total += EC_SYM_BITS;
|
|
m_rng <<= EC_SYM_BITS;
|
|
/*Use up the remaining bits from our last symbol.*/
|
|
sym = m_rem;
|
|
/*Read the next value from the input.*/
|
|
m_rem = read_byte();
|
|
/*Take the rest of the bits we need from this new symbol.*/
|
|
sym = (sym << EC_SYM_BITS | m_rem) >> (EC_SYM_BITS - EC_CODE_EXTRA);
|
|
/*And subtract them from val, capped to be less than EC_CODE_TOP.*/
|
|
m_val = ((m_val << EC_SYM_BITS) + (EC_SYM_MAX & ~sym)) & ((EC_CODE_TOP) - 1);
|
|
}
|
|
}
|
|
//——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
|
|
void RangeDecoder::dec_init(uint8_t *_buf, uint32_t _storage) {
|
|
|
|
m_buf = _buf;
|
|
m_storage = _storage;
|
|
m_end_offs = 0;
|
|
m_end_window = 0;
|
|
m_nend_bits = 0;
|
|
m_nbits_total = EC_CODE_BITS + 1 - ((EC_CODE_BITS - EC_CODE_EXTRA) / EC_SYM_BITS) * EC_SYM_BITS;
|
|
m_offs = 0;
|
|
m_rng = 1U << EC_CODE_EXTRA;
|
|
m_rem = read_byte();
|
|
m_val = m_rng - 1 - (m_rem >> (EC_SYM_BITS - EC_CODE_EXTRA));
|
|
m_error = 0;
|
|
/*Normalize the interval.*/
|
|
dec_normalize();
|
|
}
|
|
//——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
|
|
uint32_t RangeDecoder::decode(uint32_t _ft) {
|
|
uint32_t s;
|
|
m_ext = m_rng / _ft;
|
|
s = (uint32_t)(m_val / m_ext);
|
|
return _ft - EC_MINI(s + 1, _ft);
|
|
}
|
|
//——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
|
|
uint32_t RangeDecoder::decode_bin(uint32_t _bits) {
|
|
uint32_t s;
|
|
m_ext = m_rng >> _bits;
|
|
s = (uint32_t)(m_val / m_ext);
|
|
return (1U << _bits) - EC_MINI(s + 1U, 1U << _bits);
|
|
}
|
|
//——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
|
|
void RangeDecoder::dec_update(uint32_t _fl, uint32_t _fh, uint32_t _ft) {
|
|
uint32_t s;
|
|
s = m_ext * (_ft - _fh);
|
|
m_val -= s;
|
|
|
|
if(_fl > 0){
|
|
m_rng = m_ext * (_fh - _fl);
|
|
}
|
|
else{
|
|
m_rng = m_rng - s;
|
|
}
|
|
dec_normalize();
|
|
}
|
|
//——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
|
|
/*The probability of having a "one" is 1/(1<<_logp).*/
|
|
int32_t RangeDecoder::dec_bit_logp( uint32_t _logp) {
|
|
uint32_t r;
|
|
uint32_t d;
|
|
uint32_t s;
|
|
int32_t ret;
|
|
r = m_rng;
|
|
d = m_val;
|
|
s = r >> _logp;
|
|
ret = d < s;
|
|
if (!ret) m_val = d - s;
|
|
m_rng = ret ? s : r - s;
|
|
dec_normalize();
|
|
return ret;
|
|
}
|
|
//——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
|
|
int32_t RangeDecoder::dec_icdf(const uint8_t *_icdf, uint32_t _ftb) {
|
|
uint32_t r;
|
|
uint32_t d;
|
|
uint32_t s;
|
|
uint32_t t;
|
|
int32_t ret;
|
|
s = m_rng;
|
|
d = m_val;
|
|
r = s >> _ftb;
|
|
ret = -1;
|
|
do {
|
|
t = s;
|
|
s = r * _icdf[++ret];
|
|
} while (d < s);
|
|
m_val = d - s;
|
|
m_rng = t - s;
|
|
dec_normalize();
|
|
return ret;
|
|
}
|
|
//——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
|
|
uint32_t RangeDecoder::dec_uint(uint32_t _ft) {
|
|
uint32_t ft;
|
|
uint32_t s;
|
|
int32_t ftb;
|
|
/*In order to optimize EC_ILOG(), it is undefined for the value 0.*/
|
|
assert(_ft > 1);
|
|
_ft--;
|
|
ftb = EC_ILOG(_ft);
|
|
if (ftb > EC_UINT_BITS) {
|
|
uint32_t t;
|
|
ftb -= EC_UINT_BITS;
|
|
ft = (uint32_t)(_ft >> ftb) + 1;
|
|
s = decode(ft);
|
|
dec_update(s, s + 1, ft);
|
|
t = (uint32_t)s << ftb | dec_bits(ftb);
|
|
if (t <= _ft) return t;
|
|
m_error = 1;
|
|
return _ft;
|
|
} else {
|
|
_ft++;
|
|
s = decode((uint32_t)_ft);
|
|
dec_update(s, s + 1, (uint32_t)_ft);
|
|
return s;
|
|
}
|
|
}
|
|
//——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
|
|
uint32_t RangeDecoder::dec_bits(uint32_t _bits) {
|
|
uint32_t window;
|
|
int32_t available;
|
|
uint32_t ret;
|
|
window = m_end_window;
|
|
available = m_nend_bits;
|
|
if ((uint32_t)available < _bits) {
|
|
do {
|
|
window |= (uint32_t)read_byte_from_end() << available;
|
|
available += EC_SYM_BITS;
|
|
} while (available <= EC_WINDOW_SIZE - EC_SYM_BITS);
|
|
}
|
|
ret = (uint32_t)window & (((uint32_t)1 << _bits) - 1U);
|
|
window >>= _bits;
|
|
available -= _bits;
|
|
m_end_window = window;
|
|
m_nend_bits = available;
|
|
m_nbits_total += _bits;
|
|
return ret;
|
|
}
|
|
//——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
|
|
int32_t RangeDecoder::tell(){return m_nbits_total-EC_ILOG(m_rng);}
|
|
void RangeDecoder::add_nbits_total(int32_t nbits_total){m_nbits_total += nbits_total;}
|
|
uint32_t RangeDecoder::get_storage(){return m_storage;}
|
|
int32_t RangeDecoder::get_error(){return m_error;}
|
|
uint32_t RangeDecoder::get_rng(){return m_rng;}
|
|
//——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
|
|
/* When called, decay is positive and at most 11456. */
|
|
uint32_t RangeDecoder::laplace_get_freq1(uint32_t fs0, int32_t decay) {
|
|
uint32_t ft;
|
|
ft = 32768 - LAPLACE_MINP * (2 * LAPLACE_NMIN) - fs0;
|
|
return ft * (int32_t)(16384 - decay) >> 15;
|
|
}
|
|
//——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
|
|
int32_t RangeDecoder::laplace_decode(uint32_t fs, int32_t decay) {
|
|
int32_t val = 0;
|
|
uint32_t fl;
|
|
uint32_t fm;
|
|
fm = decode_bin(15);
|
|
fl = 0;
|
|
if (fm >= fs) {
|
|
val++;
|
|
fl = fs;
|
|
fs = laplace_get_freq1(fs, decay) + LAPLACE_MINP;
|
|
/* Search the decaying part of the PDF.*/
|
|
while (fs > LAPLACE_MINP && fm >= fl + 2 * fs) {
|
|
fs *= 2;
|
|
fl += fs;
|
|
fs = ((fs - 2 * LAPLACE_MINP) * (int32_t)decay) >> 15;
|
|
fs += LAPLACE_MINP;
|
|
val++;
|
|
}
|
|
/* Everything beyond that has probability LAPLACE_MINP. */
|
|
if (fs <= LAPLACE_MINP) {
|
|
int32_t di;
|
|
di = (fm - fl) >> (LAPLACE_LOG_MINP + 1);
|
|
val += di;
|
|
fl += 2 * di * LAPLACE_MINP;
|
|
}
|
|
if (fm < fl + fs)
|
|
val = -val;
|
|
else
|
|
fl += fs;
|
|
}
|
|
assert(fl < 32768);
|
|
assert(fs > 0);
|
|
assert(fl <= fm);
|
|
assert(fm < min((uint32_t)(fl + fs), (uint32_t)32768));
|
|
dec_update(fl, min((uint32_t)(fl + fs), (uint32_t)32768), (uint32_t)32768);
|
|
return val;
|
|
} |