This removes an XOR, an ADD, and an AND, and replaces them with
an AND NOT in ec_dec_normalize().
Also, simplify the loop structure of ec_dec_cdf() and eliminate a
CMOV.
All of our usage of ec_{enc|dec}_bit_prob had the probability of a
"one" being a power of two.
This adds a new ec_{enc|dec}_bit_logp() function that takes this
explicitly into account.
It introduces less rounding error than the bit_prob version, does not
require 17-bit integers to be emulated by ec_{encode|decode}_bin(),
and does not require any multiplies or divisions at all.
It is exactly equivalent to
ec_encode_bin(enc,_val?0:(1<<_logp)-1,(1<<_logp)-(_val?1:0),1<<_logp)
The old ec_{enc|dec}_bit_prob functions are left in place for now,
because I am not sure if SILK is still using them or not when
combined in Opus.
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.
This decodes a value encoded with ec_encode_bin() without using any
divisions.
It is only meant for small alphabets.
If a symbol can take on a large number of possible values, a binary
search would be better.
This patch also converts spread_decision to use it, since it is
faster and introduces less rounding error to encode a single
decision for the entire value than to encode it a bit at a time.
Making it so all the information encoded directly with ec_enc_bits() gets
stored at the end of the stream, without going through the range coder. This
should be both faster and reduce the effects of bit errors.
Conflicts:
tests/ectest.c
Instead of trying to maximize the number of trailing zeros (minimize the number
of bits encoded), we try to maximize the number of trailing bits that can
contain arbitrary data.
Note that this requires ec_enc_tell() and ec_dec_tell() to reserve an extra
bit, since depending on the exact final codeword, as little as half the final
range might be available for storing arbitrary data.
This is the first step needed to start packing literal bits outside the range
coder (for speed and robustness purposes).