/*This is meant to be a large, positive constant that can still be efficiently loadedasanimmediate(onplatformslikeARM,forexample).
Even relatively modest values like 100 would work fine.*/ #define OD_EC_LOTS_OF_BITS (0x4000)
/*The return value of od_ec_dec_tell does not change across an od_ec_dec_refill
call.*/ staticvoid od_ec_dec_refill(od_ec_dec *dec) { int s;
od_ec_window dif;
int16_t cnt; constunsignedchar *bptr; constunsignedchar *end;
dif = dec->dif;
cnt = dec->cnt;
bptr = dec->bptr;
end = dec->end;
s = OD_EC_WINDOW_SIZE - 9 - (cnt + 15); for (; s >= 0 && bptr < end; s -= 8, bptr++) { /*Each time a byte is inserted into the window (dif), bptr advances and cnt isincrementedby8,sothetotalnumberofconsumedbits(thereturn
value of od_ec_dec_tell) does not change.*/
assert(s <= OD_EC_WINDOW_SIZE - 8);
dif ^= (od_ec_window)bptr[0] << s;
cnt += 8;
} if (bptr >= end) { /*We've reached the end of the buffer. It is perfectly valid for us to need tofillthewindowwithadditionalbitspasttheendofthebuffer(and thishappensinnormaloperation).Thesebitsshouldalljustbetaken aszero.Butwecannotincrementbptrpast'end'(thisisundefined behavior),sowestarttoincrementdec->tell_offs.Wealsodon'twant tokeeptestingbptragainst'end',sowesetcnttoOD_EC_LOTS_OF_BITS andadjustdec->tell_offssothatthetotalnumberofunconsumedbitsin thewindow(dec->cnt-dec->tell_offs)doesnotchange.Thiseffectively putslotsofzerobitsintothewindow,andmeanswewon'ttrytorefill itfromthebufferforaverylongtime(atwhichpointwe'llputlots
of zero bits into the window again).*/
dec->tell_offs += OD_EC_LOTS_OF_BITS - cnt;
cnt = OD_EC_LOTS_OF_BITS;
}
dec->dif = dif;
dec->cnt = cnt;
dec->bptr = bptr;
}
/*Takes updated dif and range values, renormalizes them so that 32768<=rng<65536(readingmorebytesfromthestreamintodifif necessary),andstoresthembackinthedecodercontext. dif:Thenewvalueofdif. rng:Thenewvalueoftherange. ret:Thevaluetoreturn. Return:ret.
This allows the compiler to jump to this function via a tail-call.*/ staticint od_ec_dec_normalize(od_ec_dec *dec, od_ec_window dif, unsigned rng, int ret) { int d;
assert(rng <= 65535U); /*The number of leading zeros in the 16-bit binary representation of rng.*/
d = 16 - OD_ILOG_NZ(rng); /*d bits in dec->dif are consumed.*/
dec->cnt -= d; /*This is equivalent to shifting in 1's instead of 0's.*/
dec->dif = ((dif + 1) << d) - 1;
dec->rng = rng << d; if (dec->cnt < 0) od_ec_dec_refill(dec); return ret;
}
/*Decode a single binary value. f:Theprobabilitythatthebitisone,scaledby32768.
Return: The value decoded (0 or 1).*/ int od_ec_decode_bool_q15(od_ec_dec *dec, unsigned f) {
od_ec_window dif;
od_ec_window vw; unsigned r; unsigned r_new; unsigned v; int ret;
assert(0 < f);
assert(f < 32768U);
dif = dec->dif;
r = dec->rng;
assert(dif >> (OD_EC_WINDOW_SIZE - 16) < r);
assert(32768U <= r);
v = ((r >> 8) * (uint32_t)(f >> EC_PROB_SHIFT) >> (7 - EC_PROB_SHIFT));
v += EC_MIN_PROB;
vw = (od_ec_window)v << (OD_EC_WINDOW_SIZE - 16);
ret = 1;
r_new = v; if (dif >= vw) {
r_new = r - v;
dif -= vw;
ret = 0;
} return od_ec_dec_normalize(dec, dif, r_new, ret);
}
/*Decodes a symbol given an inverse cumulative distribution function (CDF) tableinQ15. icdf:CDF_PROB_TOPminustheCDF,suchthatsymbolsfallsintherange [s>0?(CDF_PROB_TOP-icdf[s-1]):0,CDF_PROB_TOP-icdf[s]). Thevaluesmustbemonotonicallynon-increasing,andicdf[nsyms-1] mustbe0. nsyms:Thenumberofsymbolsinthealphabet. Thisshouldbeatmost16.
Return: The decoded symbol s.*/ int od_ec_decode_cdf_q15(od_ec_dec *dec, const uint16_t *icdf, int nsyms) {
od_ec_window dif; unsigned r; unsigned c; unsigned u; unsigned v; int ret;
(void)nsyms;
dif = dec->dif;
r = dec->rng; constint N = nsyms - 1;
assert(dif >> (OD_EC_WINDOW_SIZE - 16) < r);
assert(icdf[nsyms - 1] == OD_ICDF(CDF_PROB_TOP));
assert(32768U <= r);
assert(7 - EC_PROB_SHIFT >= 0);
c = (unsigned)(dif >> (OD_EC_WINDOW_SIZE - 16));
v = r;
ret = -1; do {
u = v;
v = ((r >> 8) * (uint32_t)(icdf[++ret] >> EC_PROB_SHIFT) >>
(7 - EC_PROB_SHIFT));
v += EC_MIN_PROB * (N - ret);
} while (c < v);
assert(v < u);
assert(u <= r);
r = u - v;
dif -= (od_ec_window)v << (OD_EC_WINDOW_SIZE - 16); return od_ec_dec_normalize(dec, dif, r, ret);
}
/*Returns the number of bits "used" by the decoded symbols so far. Thissamenumbercanbecomputedineithertheencoderorthedecoder,andis suitableformakingcodingdecisions. Return:Thenumberofbits. Thiswillalwaysbeslightlylargerthantheexactvalue(e.g.,all
rounding error is in the positive direction).*/ int od_ec_dec_tell(const od_ec_dec *dec) { /*There is a window of bits stored in dec->dif. The difference (dec->bptr-dec->buf)tellsushowmanybyteshavebeenreadintothis window.Thedifference(dec->cnt-dec->tell_offs)tellsushowmanyof
the bits in that window remain unconsumed.*/ return (int)((dec->bptr - dec->buf) * 8 - dec->cnt + dec->tell_offs);
}
/*Returns the number of bits "used" by the decoded symbols so far. Thissamenumbercanbecomputedineithertheencoderorthedecoder,andis suitableformakingcodingdecisions. Return:Thenumberofbitsscaledby2**OD_BITRES. Thiswillalwaysbeslightlylargerthantheexactvalue(e.g.,all
rounding error is in the positive direction).*/
uint32_t od_ec_dec_tell_frac(const od_ec_dec *dec) { return od_ec_tell_frac(od_ec_dec_tell(dec), dec->rng);
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.13 Sekunden
(vorverarbeitet am 2026-08-23)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.