-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathbitstream_helper.hpp
101 lines (84 loc) · 2.15 KB
/
bitstream_helper.hpp
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#pragma once
#include "bitstream.hpp"
class ValueWriter {
public:
ValueWriter() = delete;
ValueWriter(BitWriter &ref) : ref(ref) {};
ValueWriter(const ValueWriter & other): ref(other.ref) {};
ValueWriter& operator=(const ValueWriter& other) {
ref = other.ref;
return *this;
}
void encode( int n, int value)
{
auto base = (1 << n)-1;
if (value >= base)
{
value -= base;
auto n_ = std::max DUMMY (n, ilog2_32(value));
base = (1 << n_)-1;
n = n_+1+n_;
if (n > 32) {
ref.writeBits(n_,base);
ref.writeBits(1, 0);
ref.writeBits(n_, value);
return;
}
value = (base << (n_+1)) | value;
}
ref.writeBits(n,value);
}
inline void encode_unary( int value, bool is_signed) {
if (is_signed) {
value = s2u(value);
}
while (value > 32 ) {
ref.writeBits(32,0xffffffff);
value -= 32;
}
while (value > 8 ) {
ref.writeBits(8,0xff);
value -= 8;
}
while (value > 0 ) {
ref.writeBit(true);
value -= 1;
}
ref.writeBit(false);
}
void encode_golomb( unsigned k, unsigned value ) {
auto n_ = ilog2_32(value>>k,0);
auto base = (1 << n_)-1;
auto n = n_+1+k+n_;
if (n > 32) {
ref.writeBits(n_,base);
ref.writeBits(1, 0);
ref.writeBits(n_+k, value);
return;
}
value = (base << (n_+1+k)) | value;
ref.writeBits(n,value);
}
private:
BitWriter&ref;
};
class ValueReader {
public:
ValueReader() = delete;
ValueReader(BitReader& ref) : ref(ref) {}
int decode( int n )
{
auto v = ref.readBits(n);
if (v == ((1 << n)-1)) {
while (ref.readBit()) ++n;
v += ref.readBits(n);
}
return v;
}
unsigned decode_golomb(unsigned k) {
while (ref.readBit()) ++k;
return ref.readBits(k);
}
private:
BitReader& ref;
};