template <typename T, class M>
class PCencoder<T, M, false> {
public:
PCencoder(RCencoder* re, RCmodel*const* rm) : re(re), rm(rm) {}
T encode(T real, T pred, uint context = 0);
static const uint symbols = 2 * (1 << M::bits) - 1;
private:
static const uint bias = (1 << M::bits) - 1; M map; RCencoder*const re; RCmodel*const* rm; };
template <typename T, class M>
T PCencoder<T, M, false>::encode(T real, T pred, uint context)
{
typedef typename M::Range U;
U r = map.forward(real);
U p = map.forward(pred);
re->encode(static_cast<uint>(bias + r - p), rm[context]);
return map.inverse(r);
}
template <typename T, class M>
class PCencoder<T, M, true> {
public:
PCencoder(RCencoder* re, RCmodel*const* rm) : re(re), rm(rm) {}
T encode(T real, T pred, uint context = 0);
static const uint symbols = 2 * M::bits + 1;
private:
static const uint bias = M::bits; M map; RCencoder*const re; RCmodel*const* rm; };
template <typename T, class M>
T PCencoder<T, M, true>::encode(T real, T pred, uint context)
{
typedef typename M::Range U;
U r = map.forward(real);
U p = map.forward(pred);
if (p < r) { U d = r - p;
uint k = PC::bsr(d);
re->encode(bias + 1 + k, rm[context]);
re->encode(d - (U(1) << k), k);
}
else if (p > r) { U d = p - r;
uint k = PC::bsr(d);
re->encode(bias - 1 - k, rm[context]);
re->encode(d - (U(1) << k), k);
}
else re->encode(bias, rm[context]);
return map.inverse(r);
}