forked from LLNL/fpzip
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpcdecoder.inl
67 lines (62 loc) · 2.06 KB
/
pcdecoder.inl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
// specialization for small alphabets -----------------------------------------
template <typename T, class M>
class PCdecoder<T, M, false> {
public:
PCdecoder(RCdecoder* rd, RCmodel*const* rm) : rd(rd), rm(rm) {}
~PCdecoder() {}
T decode(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; // maps T to some unsigned integer type
RCdecoder*const rd; // entropy decoder
RCmodel*const* rm; // probability modeler(s)
};
// decode narrow range type
template <typename T, class M>
T PCdecoder<T, M, false>::decode(T pred, uint context)
{
// map type T to unsigned integer type
typedef typename M::Range U;
U p = map.forward(pred);
// entropy decode d = r - p
U r = p + rd->decode(rm[context]) - bias;
return map.inverse(r);
}
// specialization for large alphabets -----------------------------------------
template <typename T, class M>
class PCdecoder<T, M, true> {
public:
PCdecoder(RCdecoder* rd, RCmodel*const* rm) : rd(rd), rm(rm) {}
~PCdecoder() {}
T decode(T pred, uint context = 0);
static const uint symbols = 2 * M::bits + 1;
private:
static const uint bias = M::bits;
M map; // maps T to some unsigned integer type
RCdecoder*const rd; // entropy decoder
RCmodel*const* rm; // probability modeler(s)
};
// decode wide range type
template <typename T, class M>
T PCdecoder<T, M, true>::decode(T pred, uint context)
{
typedef typename M::Range U;
uint s = rd->decode(rm[context]);
if (s > bias) { // underprediction
uint k = s - bias - 1;
U d = (U(1) << k) + rd->template decode<U>(k);
U p = map.forward(pred);
U r = p + d;
return map.inverse(r);
}
else if (s < bias) { // overprediction
uint k = bias - 1 - s;
U d = (U(1) << k) + rd->template decode<U>(k);
U p = map.forward(pred);
U r = p - d;
return map.inverse(r);
}
else // perfect prediction
return map.identity(pred);
}