-
Notifications
You must be signed in to change notification settings - Fork 2
/
arithmetic_encoder.h
104 lines (81 loc) · 2.08 KB
/
arithmetic_encoder.h
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
102
103
#ifndef ARITHMETIC_ENCODER_H
#define ARITHMETIC_ENCODER_H
#include <math.h>
#include "common.h"
#ifdef WINDOWS
#include "file_writer.h"
#else
#include "u_file_writer.h"
#endif
////////////////////////////////////////////////////////
class arithmetic_encoder
{
private:
file_writer<bit>* m_output;
const DWORD top_value;
DWORD l, u;
int scale3;
arithmetic_encoder& operator=(const arithmetic_encoder&);
arithmetic_encoder(const arithmetic_encoder& );
public:
arithmetic_encoder(file_writer<bit>* fw) : top_value(0xFFFFFFFF),
l(0),
u(top_value),
scale3(0)
{
m_output = fw;
}
inline void encode(DWORD lower_bound, DWORD upper_bound, DWORD total)
{
bool e3_cond = false;
bool eql_cond;
QWORD range = (QWORD)(u - l) + 1;
ASSERT(l < u);
ASSERT((lower_bound <= upper_bound) && (upper_bound <= total));
u = l + (DWORD)(((range * upper_bound) / total) - 1);
l = l + (DWORD)((range * lower_bound) / total);
while( (eql_cond = (MSB(u) == MSB(l))) ||
(e3_cond = (M2SB(l) == 1) && (M2SB(u) == 0)) )
{
if(eql_cond)
{
bit bit_to_send = ((MSB(u) == 0) ? 0 : 1);
m_output->send(bit_to_send);
l <<= 1;
u <<= 1;
u |= 1;
while (scale3 > 0)
{
m_output->send(!bit_to_send);
--scale3;
}
}
else if (e3_cond)
{
l <<= 1;
u <<= 1;
u |= 1;
l += MSB_MASK;
u += MSB_MASK;
++scale3;
}
}
ASSERT(l < u);
}
inline void encode_eof()
{
for (size_t i = 0; i < sizeof(DWORD) * 8; ++i)
{
bit bit_to_send = ((MSB(l) == 0) ? 0 : 1);
m_output->send(bit_to_send);
l <<= 1;
while (scale3 > 0)
{
m_output->send(!bit_to_send);
--scale3;
}
}
}
};
////////////////////////////////////////////////////////
#endif //ARITHMETIC_ENCODER_H