Commit a093f4df authored by Timothy B. Terriberry's avatar Timothy B. Terriberry Committed by Jean-Marc Valin
Browse files

Refactor the entropy coder.

This unifies the byte buffer, encoder, and decoder into a single
 struct.
The common encoder and decoder functions (such as ec_tell()) can
 operate on either one, simplifying code which uses both.
The precision argument to ec_tell() has been removed.
It now comes in two precisions:
  ec_tell() gives 1 bit precision in two operations, and
  ec_tell_frac() gives 1/8th bit precision in... somewhat more.
ec_{enc|dec}_bit_prob() were removed (they are no longer needed).
Some of the byte buffer access functions were made static and
 removed from the cross-module API.
All of the code in rangeenc.c and rangedec.c was merged into
 entenc.c and entdec.c, respectively, as we are no longer
 considering alternative backends.
rangeenc.c and rangede.c have been removed entirely.

This passes make check, after disabling the modes that we removed
 support for in cf5d3a8c.
parent ef986e44
......@@ -16,8 +16,7 @@ lib_LTLIBRARIES = libcelt@LIBCELT_SUFFIX@.la
# Sources for compilation in the library
libcelt@LIBCELT_SUFFIX@_la_SOURCES = bands.c celt.c cwrs.c ecintrin.h entcode.c \
entdec.c entenc.c header.c kiss_fft.c laplace.c mathops.c mdct.c \
modes.c pitch.c plc.c quant_bands.c rangedec.c rangeenc.c rate.c \
vq.c
modes.c pitch.c plc.c quant_bands.c rate.c vq.c
libcelt@LIBCELT_SUFFIX@_la_LDFLAGS = \
-version-info @CELT_LT_CURRENT@:@CELT_LT_REVISION@:@CELT_LT_AGE@ \
......
......@@ -636,7 +636,7 @@ static int compute_qn(int N, int b, int offset, int pulse_cap, int stereo)
in two and transmit the energy difference with the two half-bands. It
can be called recursively so bands can end up being split in 8 parts. */
static unsigned quant_band(int encode, const CELTMode *m, int i, celt_norm *X, celt_norm *Y,
int N, int b, int spread, int B, int intensity, int tf_change, celt_norm *lowband, int resynth, void *ec,
int N, int b, int spread, int B, int intensity, int tf_change, celt_norm *lowband, int resynth, ec_ctx *ec,
celt_int32 *remaining_bits, int LM, celt_norm *lowband_out, const celt_ener *bandE, int level,
celt_uint32 *seed, celt_word16 gain, celt_norm *lowband_scratch, int fill)
{
......@@ -675,9 +675,9 @@ static unsigned quant_band(int encode, const CELTMode *m, int i, celt_norm *X, c
if (encode)
{
sign = x[0]<0;
ec_enc_bits((ec_enc*)ec, sign, 1);
ec_enc_bits(ec, sign, 1);
} else {
sign = ec_dec_bits((ec_dec*)ec, 1);
sign = ec_dec_bits(ec, 1);
}
*remaining_bits -= 1<<BITRES;
b-=1<<BITRES;
......@@ -787,7 +787,7 @@ static unsigned quant_band(int encode, const CELTMode *m, int i, celt_norm *X, c
2) they are orthogonal. */
itheta = stereo_itheta(X, Y, stereo, N);
}
tell = encode ? ec_enc_tell(ec, BITRES) : ec_dec_tell(ec, BITRES);
tell = ec_tell_frac(ec);
if (qn!=1)
{
if (encode)
......@@ -804,7 +804,7 @@ static unsigned quant_band(int encode, const CELTMode *m, int i, celt_norm *X, c
/* Use a probability of p0 up to itheta=8192 and then use 1 after */
if (encode)
{
ec_encode((ec_enc*)ec,x<=x0?p0*x:(x-1-x0)+(x0+1)*p0,x<=x0?p0*(x+1):(x-x0)+(x0+1)*p0,ft);
ec_encode(ec,x<=x0?p0*x:(x-1-x0)+(x0+1)*p0,x<=x0?p0*(x+1):(x-x0)+(x0+1)*p0,ft);
} else {
int fs;
fs=ec_decode(ec,ft);
......@@ -818,9 +818,9 @@ static unsigned quant_band(int encode, const CELTMode *m, int i, celt_norm *X, c
} else if (B0>1 || stereo) {
/* Uniform pdf */
if (encode)
ec_enc_uint((ec_enc*)ec, itheta, qn+1);
ec_enc_uint(ec, itheta, qn+1);
else
itheta = ec_dec_uint((ec_dec*)ec, qn+1);
itheta = ec_dec_uint(ec, qn+1);
} else {
int fs=1, ft;
ft = ((qn>>1)+1)*((qn>>1)+1);
......@@ -832,12 +832,12 @@ static unsigned quant_band(int encode, const CELTMode *m, int i, celt_norm *X, c
fl = itheta <= (qn>>1) ? itheta*(itheta + 1)>>1 :
ft - ((qn + 1 - itheta)*(qn + 2 - itheta)>>1);
ec_encode((ec_enc*)ec, fl, fl+fs, ft);
ec_encode(ec, fl, fl+fs, ft);
} else {
/* Triangular pdf */
int fl=0;
int fm;
fm = ec_decode((ec_dec*)ec, ft);
fm = ec_decode(ec, ft);
if (fm < ((qn>>1)*((qn>>1) + 1)>>1))
{
......@@ -853,7 +853,7 @@ static unsigned quant_band(int encode, const CELTMode *m, int i, celt_norm *X, c
fl = ft - ((qn + 1 - itheta)*(qn + 2 - itheta)>>1);
}
ec_dec_update((ec_dec*)ec, fl, fl+fs, ft);
ec_dec_update(ec, fl, fl+fs, ft);
}
}
itheta = (celt_int32)itheta*16384/qn;
......@@ -888,8 +888,7 @@ static unsigned quant_band(int encode, const CELTMode *m, int i, celt_norm *X, c
inv = 0;
itheta = 0;
}
qalloc = (encode ? ec_enc_tell(ec, BITRES) : ec_dec_tell(ec, BITRES))
- tell;
qalloc = ec_tell_frac(ec) - tell;
b -= qalloc;
orig_fill = fill;
......@@ -946,9 +945,9 @@ static unsigned quant_band(int encode, const CELTMode *m, int i, celt_norm *X, c
{
/* Here we only need to encode a sign for the side */
sign = x2[0]*y2[1] - x2[1]*y2[0] < 0;
ec_enc_bits((ec_enc*)ec, sign, 1);
ec_enc_bits(ec, sign, 1);
} else {
sign = ec_dec_bits((ec_dec*)ec, 1);
sign = ec_dec_bits(ec, 1);
}
}
sign = 1-2*sign;
......@@ -1059,9 +1058,9 @@ static unsigned quant_band(int encode, const CELTMode *m, int i, celt_norm *X, c
/* Finally do the actual quantization */
if (encode)
cm = alg_quant(X, N, K, spread, B, resynth, (ec_enc*)ec, gain);
cm = alg_quant(X, N, K, spread, B, resynth, ec, gain);
else
cm = alg_unquant(X, N, K, spread, B, (ec_dec*)ec, gain);
cm = alg_unquant(X, N, K, spread, B, ec, gain);
} else {
/* If there's no pulse, fill the band anyway */
int j;
......@@ -1160,7 +1159,7 @@ static unsigned quant_band(int encode, const CELTMode *m, int i, celt_norm *X, c
void quant_all_bands(int encode, const CELTMode *m, int start, int end,
celt_norm *_X, celt_norm *_Y, unsigned char *collapse_masks, const celt_ener *bandE, int *pulses,
int shortBlocks, int spread, int dual_stereo, int intensity, int *tf_res, int resynth,
celt_int32 total_bits, celt_int32 balance, void *ec, int LM, int codedBands, ec_uint32 *seed)
celt_int32 total_bits, celt_int32 balance, ec_ctx *ec, int LM, int codedBands, ec_uint32 *seed)
{
int i;
celt_int32 remaining_bits;
......@@ -1201,10 +1200,7 @@ void quant_all_bands(int encode, const CELTMode *m, int start, int end,
else
Y = NULL;
N = M*eBands[i+1]-M*eBands[i];
if (encode)
tell = ec_enc_tell((ec_enc*)ec, BITRES);
else
tell = ec_dec_tell((ec_dec*)ec, BITRES);
tell = ec_tell_frac(ec);
/* Compute how many bits we want to allocate to this band */
if (i != start)
......
......@@ -88,7 +88,7 @@ void haar1(celt_norm *X, int N0, int stride);
void quant_all_bands(int encode, const CELTMode *m, int start, int end,
celt_norm * X, celt_norm * Y, unsigned char *collapse_masks, const celt_ener *bandE, int *pulses,
int time_domain, int fold, int dual_stereo, int intensity, int *tf_res, int resynth,
celt_int32 total_bits, celt_int32 balance, void *enc, int M, int codedBands, ec_uint32 *seed);
celt_int32 total_bits, celt_int32 balance, ec_ctx *ec, int M, int codedBands, ec_uint32 *seed);
void stereo_decision(const CELTMode *m, celt_norm * restrict X, int *stereo_mode, int len, int M);
......
......@@ -691,8 +691,8 @@ static void tf_encode(int start, int end, int isTransient, int *tf_res, int LM,
int logp;
ec_uint32 budget;
ec_uint32 tell;
budget = enc->buf->storage*8;
tell = ec_enc_tell(enc, 0);
budget = enc->storage*8;
tell = ec_tell(enc);
logp = isTransient ? 2 : 4;
/* Reserve space to code the tf_select decision. */
tf_select_rsv = LM>0 && tell+logp+1 <= budget;
......@@ -703,7 +703,7 @@ static void tf_encode(int start, int end, int isTransient, int *tf_res, int LM,
if (tell+logp<=budget)
{
ec_enc_bit_logp(enc, tf_res[i] ^ curr, logp);
tell = ec_enc_tell(enc, 0);
tell = ec_tell(enc);
curr = tf_res[i];
tf_changed |= curr;
}
......@@ -732,8 +732,8 @@ static void tf_decode(int start, int end, int isTransient, int *tf_res, int LM,
ec_uint32 budget;
ec_uint32 tell;
budget = dec->buf->storage*8;
tell = ec_dec_tell(dec, 0);
budget = dec->storage*8;
tell = ec_tell(dec);
logp = isTransient ? 2 : 4;
tf_select_rsv = LM>0 && tell+logp+1<=budget;
budget -= tf_select_rsv;
......@@ -743,7 +743,7 @@ static void tf_decode(int start, int end, int isTransient, int *tf_res, int LM,
if (tell+logp<=budget)
{
curr ^= ec_dec_bit_logp(dec, logp);
tell = ec_dec_tell(dec, 0);
tell = ec_tell(dec);
tf_changed |= curr;
}
tf_res[i] = curr;
......@@ -871,8 +871,7 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
#endif
int i, c, N;
int bits;
ec_byte_buffer buf;
ec_enc _enc;
ec_enc _enc;
VARDECL(celt_sig, in);
VARDECL(celt_sig, freq);
VARDECL(celt_norm, X);
......@@ -944,7 +943,7 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
tell=1;
nbFilledBytes=0;
} else {
tell=ec_enc_tell(enc, 0);
tell=ec_tell(enc);
nbFilledBytes=(tell+4)>>3;
}
nbAvailableBytes = nbCompressedBytes - nbFilledBytes;
......@@ -966,8 +965,7 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
if (enc==NULL)
{
ec_byte_writeinit_buffer(&buf, compressed, nbCompressedBytes);
ec_enc_init(&_enc,&buf);
ec_enc_init(&_enc, compressed, nbCompressedBytes);
enc = &_enc;
}
......@@ -993,7 +991,7 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
{
nbCompressedBytes = nbFilledBytes+max_allowed;
nbAvailableBytes = max_allowed;
ec_byte_shrink(enc->buf, nbCompressedBytes);
ec_enc_shrink(enc, nbCompressedBytes);
}
}
}
......@@ -1058,12 +1056,12 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
effectiveBytes=nbCompressedBytes=IMIN(nbCompressedBytes, nbFilledBytes+2);
total_bits=nbCompressedBytes*8;
nbAvailableBytes=2;
ec_byte_shrink(enc->buf, nbCompressedBytes);
ec_enc_shrink(enc, nbCompressedBytes);
}
/* Pretend we've filled all the remaining bits with zeros
(that's what the initialiser did anyway) */
tell = nbCompressedBytes*8;
enc->nbits_total+=tell-ec_enc_tell(enc,0);
enc->nbits_total+=tell-ec_tell(enc);
}
#ifdef ENABLE_POSTFILTER
if (nbAvailableBytes>12*C && st->start==0 && !silence && !st->disable_pf && st->complexity >= 5)
......@@ -1131,7 +1129,7 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
ec_enc_bits(enc, pitch_index-(16<<octave), 4+octave);
pitch_index -= 1;
ec_enc_bits(enc, qg, 3);
if (ec_enc_tell(enc, 0)+2<=total_bits)
if (ec_tell(enc)+2<=total_bits)
ec_enc_icdf(enc, prefilter_tapset, tapset_icdf, 2);
else
prefilter_tapset = 0;
......@@ -1177,7 +1175,7 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
isTransient = 0;
shortBlocks = 0;
if (LM>0 && ec_enc_tell(enc, 0)+3<=total_bits)
if (LM>0 && ec_tell(enc)+3<=total_bits)
{
if (st->complexity > 1)
{
......@@ -1235,7 +1233,7 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
tf_encode(st->start, st->end, isTransient, tf_res, LM, tf_select, enc);
st->spread_decision = SPREAD_NORMAL;
if (ec_enc_tell(enc, 0)+4<=total_bits)
if (ec_tell(enc)+4<=total_bits)
{
if (shortBlocks || st->complexity < 3 || nbAvailableBytes < 10*C)
{
......@@ -1284,7 +1282,7 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
dynalloc_logp = 6;
total_bits<<=BITRES;
total_boost = 0;
tell = ec_enc_tell(enc, BITRES);
tell = ec_tell_frac(enc);
for (i=st->start;i<st->end;i++)
{
int width, quanta;
......@@ -1303,7 +1301,7 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
int flag;
flag = j<offsets[i];
ec_enc_bit_logp(enc, flag, dynalloc_loop_logp);
tell = ec_enc_tell(enc, BITRES);
tell = ec_tell_frac(enc);
if (!flag)
break;
boost += quanta;
......@@ -1321,7 +1319,7 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
alloc_trim = alloc_trim_analysis(st->mode, X, bandLogE,
st->mode->nbEBands, LM, C, N);
ec_enc_icdf(enc, alloc_trim, trim_icdf, 7);
tell = ec_enc_tell(enc, BITRES);
tell = ec_tell_frac(enc);
}
/* Variable bitrate */
......@@ -1396,7 +1394,7 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
}
nbCompressedBytes = IMIN(nbCompressedBytes,nbAvailableBytes+nbFilledBytes);
/* This moves the raw bits to take into account the new compressed size */
ec_byte_shrink(enc->buf, nbCompressedBytes);
ec_enc_shrink(enc, nbCompressedBytes);
}
if (C==2)
{
......@@ -1434,7 +1432,7 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
ALLOC(fine_priority, st->mode->nbEBands, int);
/* bits = packet size - where we are - safety*/
bits = (nbCompressedBytes*8<<BITRES) - ec_enc_tell(enc, BITRES) - 1;
bits = (nbCompressedBytes*8<<BITRES) - ec_tell_frac(enc) - 1;
anti_collapse_rsv = isTransient&&LM>=2&&bits>=(LM+2<<BITRES) ? (1<<BITRES) : 0;
bits -= anti_collapse_rsv;
codedBands = compute_allocation(st->mode, st->start, st->end, offsets, cap,
......@@ -1466,7 +1464,7 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
anti_collapse_on = st->consec_transient<2;
ec_enc_bits(enc, anti_collapse_on, 1);
}
quant_energy_finalise(st->mode, st->start, st->end, oldBandE, error, fine_quant, fine_priority, nbCompressedBytes*8-ec_enc_tell(enc, 0), enc, C);
quant_energy_finalise(st->mode, st->start, st->end, oldBandE, error, fine_quant, fine_priority, nbCompressedBytes*8-ec_tell(enc), enc, C);
if (silence)
{
......@@ -1594,7 +1592,7 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
ec_enc_done(enc);
RESTORE_STACK;
if (ec_enc_get_error(enc))
if (ec_get_error(enc))
return CELT_CORRUPTED_DATA;
else
return nbCompressedBytes;
......@@ -2135,7 +2133,6 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
int spread_decision;
int bits;
ec_dec _dec;
ec_byte_buffer buf;
VARDECL(celt_sig, freq);
VARDECL(celt_norm, X);
VARDECL(celt_ener, bandE);
......@@ -2230,8 +2227,7 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
if (dec == NULL)
{
ec_byte_readinit(&buf,(unsigned char*)data,len);
ec_dec_init(&_dec,&buf);
ec_dec_init(&_dec,(unsigned char*)data,len);
dec = &_dec;
}
......@@ -2246,7 +2242,7 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
}
total_bits = len*8;
tell = ec_dec_tell(dec, 0);
tell = ec_tell(dec);
if (tell==1)
silence = ec_dec_bit_logp(dec, 15);
......@@ -2256,7 +2252,7 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
{
/* Pretend we've read all the remaining bits */
tell = len*8;
dec->nbits_total+=tell-ec_dec_tell(dec,0);
dec->nbits_total+=tell-ec_tell(dec);
}
postfilter_gain = 0;
......@@ -2271,7 +2267,7 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
octave = ec_dec_uint(dec, 6);
postfilter_pitch = (16<<octave)+ec_dec_bits(dec, 4+octave)-1;
qg = ec_dec_bits(dec, 3);
if (ec_dec_tell(dec, 0)+2<=total_bits)
if (ec_tell(dec)+2<=total_bits)
postfilter_tapset = ec_dec_icdf(dec, tapset_icdf, 2);
postfilter_gain = QCONST16(.09375f,15)*(qg+1);
#else /* ENABLE_POSTFILTER */
......@@ -2279,13 +2275,13 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
return CELT_CORRUPTED_DATA;
#endif /* ENABLE_POSTFILTER */
}
tell = ec_dec_tell(dec, 0);
tell = ec_tell(dec);
}
if (LM > 0 && tell+3 <= total_bits)
{
isTransient = ec_dec_bit_logp(dec, 3);
tell = ec_dec_tell(dec, 0);
tell = ec_tell(dec);
}
else
isTransient = 0;
......@@ -2304,7 +2300,7 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
ALLOC(tf_res, st->mode->nbEBands, int);
tf_decode(st->start, st->end, isTransient, tf_res, LM, dec);
tell = ec_dec_tell(dec, 0);
tell = ec_tell(dec);
spread_decision = SPREAD_NORMAL;
if (tell+4 <= total_bits)
spread_decision = ec_dec_icdf(dec, spread_icdf, 5);
......@@ -2318,7 +2314,7 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
dynalloc_logp = 6;
total_bits<<=BITRES;
tell = ec_dec_tell(dec, BITRES);
tell = ec_tell_frac(dec);
for (i=st->start;i<st->end;i++)
{
int width, quanta;
......@@ -2334,7 +2330,7 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
{
int flag;
flag = ec_dec_bit_logp(dec, dynalloc_loop_logp);
tell = ec_dec_tell(dec, BITRES);
tell = ec_tell_frac(dec);
if (!flag)
break;
boost += quanta;
......@@ -2351,7 +2347,7 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
alloc_trim = tell+(6<<BITRES) <= total_bits ?
ec_dec_icdf(dec, trim_icdf, 7) : 5;
bits = (len*8<<BITRES) - ec_dec_tell(dec, BITRES) - 1;
bits = (len*8<<BITRES) - ec_tell_frac(dec) - 1;
anti_collapse_rsv = isTransient&&LM>=2&&bits>=(LM+2<<BITRES) ? (1<<BITRES) : 0;
bits -= anti_collapse_rsv;
codedBands = compute_allocation(st->mode, st->start, st->end, offsets, cap,
......@@ -2372,7 +2368,7 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
}
unquant_energy_finalise(st->mode, st->start, st->end, oldBandE,
fine_quant, fine_priority, len*8-ec_dec_tell(dec, 0), dec, C);
fine_quant, fine_priority, len*8-ec_tell(dec), dec, C);
if (anti_collapse_on)
anti_collapse(st->mode, X, collapse_masks, LM, C, CC, N,
......@@ -2476,7 +2472,7 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da
deemphasis(out_syn, pcm, N, CC, st->downsample, st->mode->preemph, st->preemph_memD);
st->loss_count = 0;
RESTORE_STACK;
if (ec_dec_tell(dec,0) > 8*len || ec_dec_get_error(dec))
if (ec_tell(dec) > 8*len || ec_get_error(dec))
return CELT_CORRUPTED_DATA;
else
return CELT_OK;
......
/* Copyright (c) 2001-2008 Timothy B. Terriberry
/* Copyright (c) 2001-2011 Timothy B. Terriberry
*/
/*
Redistribution and use in source and binary forms, with or without
......@@ -37,14 +37,8 @@
#if !defined(EC_CLZ)
int ec_ilog(ec_uint32 _v){
#if defined(EC_CLZ)
return EC_CLZ0-EC_CLZ(_v);
#else
/*On a Pentium M, this branchless version tested as the fastest on
1,000,000,000 random 32-bit integers, edging out a similar version with
branches, and a 256-entry LUT version.*/
......@@ -65,6 +59,36 @@ int ec_ilog(ec_uint32 _v){
ret|=m;
ret+=!!(_v&0x2);
return ret;
#endif
}
#endif
ec_uint32 ec_tell_frac(ec_ctx *_this){
ec_uint32 nbits;
ec_uint32 r;
int l;
int i;
/*To handle the non-integral number of bits still left in the encoder/decoder
state, we compute the worst-case number of bits of val that must be
encoded to ensure that the value is inside the range for any possible
subsequent bits.
The computation here is independent of val itself (the decoder does not
even track that value), even though the real number of bits used after
ec_enc_done() may be 1 smaller if rng is a power of two and the
corresponding trailing bits of val are all zeros.
If we did try to track that special case, then coding a value with a
probability of 1/(1<<n) might sometimes appear to use more than n bits.
This may help explain the surprising result that a newly initialized
encoder or decoder claims to have used 1 bit.*/
nbits=_this->nbits_total<<BITRES;
l=EC_ILOG(_this->rng);
r=_this->rng>>l-16;
for(i=BITRES;i-->0;){
int b;
r=r*r>>15;
b=(int)(r>>16);
l=l<<1|b;
r>>=b;
}
return nbits-l;
}
/* Copyright (c) 2001-2008 Timothy B. Terriberry
/* Copyright (c) 2001-2011 Timothy B. Terriberry
Copyright (c) 2008-2009 Xiph.Org Foundation */
/*
Redistribution and use in source and binary forms, with or without
......@@ -42,7 +42,9 @@
typedef celt_int32 ec_int32;
typedef celt_uint32 ec_uint32;
typedef size_t ec_window;
typedef struct ec_byte_buffer ec_byte_buffer;
typedef struct ec_ctx ec_ctx;
typedef struct ec_ctx ec_enc;
typedef struct ec_ctx ec_dec;
......@@ -52,40 +54,82 @@ typedef struct ec_byte_buffer ec_byte_buffer;
/*The number of bits to use for the range-coded part of unsigned integers.*/
# define EC_UINT_BITS (8)
/*Simple libogg1-style buffer.*/
struct ec_byte_buffer{
unsigned char *buf;
ec_uint32 offs;
ec_uint32 end_offs;
ec_uint32 storage;
/*The resolution of fractional-precision bit usage measurements, i.e.,
3 => 1/8th bits.*/
# define BITRES 3
/*The entropy encoder/decoder context.
We use the same structure for both, so that common functions like ec_tell()
can be used on either one.*/
struct ec_ctx{
/*Buffered input/output.*/
unsigned char *buf;
/*The size of the buffer.*/
ec_uint32 storage;
/*The offset at which the last byte containing raw bits was read/written.*/
ec_uint32 end_offs;
/*Bits that will be read from/written at the end.*/
ec_window end_window;
/*Number of valid bits in end_window.*/
int nend_bits;
/*The total number of whole bits read/written.
This does not include partial bits currently in the range coder.*/
int nbits_total;
/*The offset at which the next range coder byte will be read/written.*/
ec_uint32 offs;
/*The number of values in the current range.*/
ec_uint32 rng;
/*In the decoder: the difference between the top of the current range and
the input value, minus one.
In the encoder: the low end of the current range.*/
ec_uint32 val;
/*In the decoder: the saved normalization factor from ec_decode().
In the encoder: the number of oustanding carry propagating symbols.*/
ec_uint32 ext;
/*A buffered input/output symbol, awaiting carry propagation.*/
int rem;
/*Nonzero if an error occurred.*/
int error;
};
/*Encoding functions.*/
void ec_byte_writeinit_buffer(ec_byte_buffer *_b, unsigned char *_buf, ec_uint32 _size);
void ec_byte_shrink(ec_byte_buffer *_b, ec_uint32 _size);
int ec_byte_write(ec_byte_buffer *_b,unsigned _value);
int ec_byte_write_at_end(ec_byte_buffer *_b,unsigned _value);
int ec_byte_write_done(ec_byte_buffer *_b,int _start_bits_available,
unsigned _end_byte,int _end_bits_used);
/*Decoding functions.*/
void ec_byte_readinit(ec_byte_buffer *_b,unsigned char *_buf,ec_uint32 _bytes);
int ec_byte_read(ec_byte_buffer *_b);
int ec_byte_read_from_end(ec_byte_buffer *_b);
/*Shared functions.*/
static inline void ec_byte_reset(ec_byte_buffer *_b){
_b->offs=_b->end_offs=0;
static inline void ec_reset(ec_ctx *_this){
_this->offs=_this->end_offs=0;
}
static inline ec_uint32 ec_range_bytes(ec_ctx *_this){
return _this->offs;
}
static inline unsigned char *ec_get_buffer(ec_ctx *_this){
return _this->buf;
}
static inline ec_uint32 ec_byte_bytes(ec_byte_buffer *_b){
return _b->offs;
static inline int ec_get_error(ec_ctx *_this){
return _this->error;
}
static inline unsigned char *ec_byte_get_buffer(ec_byte_buffer *_b){
return _b->buf;
/*Returns the number of bits "used" by the encoded or decoded symbols so far.
This same number can be computed in either the encoder or the decoder, and is
suitable for making coding decisions.
Return: The number of bits.
This will always be slightly larger than the exact value (e.g., all
rounding error is in the positive direction).*/
static inline int ec_tell(ec_ctx *_this){
return _this->nbits_total-EC_ILOG(_this->rng);
}
/*Returns the number of bits "used" by the encoded or decoded symbols so far.
This same number can be computed in either the encoder or the decoder, and is
suitable for making coding decisions.
Return: The number of bits scaled by 2**BITRES.
This will always be slightly larger than the exact value (e.g., all
rounding error is in the positive direction).*/
ec_uint32 ec_tell_frac(ec_ctx *_this);
int ec_ilog(ec_uint32 _v);
#endif