-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdecoder_init.py
149 lines (128 loc) · 3.37 KB
/
decoder_init.py
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
import bitfile
global EOF
global PRECISION
global low
global high
global cum_prob
global output_file
global input_file
global ranges
global code
def init_de():
global EOF
global PRECISION
global low
global high
global cum_prob
global output_file
global input_file
global ranges
global code
EOF = 256
PRECISION = 16
low = 0
high = 0xFFFF
cum_prob = 0
output_file = None
input_file = None
ranges = []
code = 0
def decode_data(input_file_name, output_file_name):
global EOF
global PRECISION
global low
global high
global cum_prob
global output_file
global input_file
global ranges
global code
init_de()
code = 0
out = []
input_file = bitfile.BitFile()
input_file.open(input_file_name, 'rb')
ranges = [0 for i in xrange(EOF + 2)]
for i in xrange(EOF + 2):
c = input_file.get_bits_ltom(14) # get probability of symbol
ranges[i] = c
cum_prob = sum([(ranges[i+1]-ranges[i]) for i in xrange(EOF+1) if (ranges[i+1]>ranges[i]) ]) # get the sizeof encode symbol
for i in xrange(PRECISION): # initialize code
code <<= 1
try:
next_bit = input_file.get_bit()
except EOFError:
pass
else:
code |= next_bit
output_file = open(output_file_name, 'wb')
while True: # decode
unscaled = get_unscaled_code()
c = get_symbol_from_probability(unscaled)
if c == EOF:
break
output_file.write(chr(c))
out.append(c)
apply_symbol_range(c)
read_encoded_bits()
output_file.close()
input_file.close()
return out
def get_unscaled_code():
global low
global high
global cum_prob
global code
unscaled = ((code - low + 1) * cum_prob - 1) / (high - low + 1)
return unscaled
def get_symbol_from_probability(probability):
global EOF
global ranges
first = 0
last = EOF+1
middle = last / 2
while (last >= first):
if probability < ranges[middle]:
last = middle - 1
middle = first + ((last - first) / 2)
elif probability >= ranges[middle+1]:
first = middle + 1
middle = first + ((last - first) / 2)
else:
return middle
def apply_symbol_range(symbol): # change symbol range
global low
global high
Symbol_range = high - low + 1
high = low + ranges[symbol+1]* Symbol_range / cum_prob - 1
low = low + ranges[symbol]* Symbol_range / cum_prob
def read_encoded_bits():
global low
global high
global code
global input_file
while True:
if (high ^ ~low) & 0x8000: # if high < 1/2*range or low > 1/2*range
low <<= 1
high <<= 1
high |= 1
code <<= 1
elif (~high & low) & 0x4000: # if high < 3/4*range and low > 1/4*range
low &= 0x3fff
low &= 0x7fff
low <<= 1
high |= 0x4000
high &= 0x7fff
high <<= 1
high |= 1
code ^= 0x4000
code &= 0x7fff
code <<= 1
else:
return
try:
next_bit = input_file.get_bit()
except EOFError:
pass
else:
code |= next_bit