|
1 package SevenZip.Compression.RangeCoder; |
|
2 import java.io.IOException; |
|
3 |
|
4 public class BitTreeEncoder |
|
5 { |
|
6 short[] Models; |
|
7 int NumBitLevels; |
|
8 |
|
9 public BitTreeEncoder(int numBitLevels) |
|
10 { |
|
11 NumBitLevels = numBitLevels; |
|
12 Models = new short[1 << numBitLevels]; |
|
13 } |
|
14 |
|
15 public void Init() |
|
16 { |
|
17 Decoder.InitBitModels(Models); |
|
18 } |
|
19 |
|
20 public void Encode(Encoder rangeEncoder, int symbol) throws IOException |
|
21 { |
|
22 int m = 1; |
|
23 for (int bitIndex = NumBitLevels; bitIndex != 0; ) |
|
24 { |
|
25 bitIndex--; |
|
26 int bit = (symbol >>> bitIndex) & 1; |
|
27 rangeEncoder.Encode(Models, m, bit); |
|
28 m = (m << 1) | bit; |
|
29 } |
|
30 } |
|
31 |
|
32 public void ReverseEncode(Encoder rangeEncoder, int symbol) throws IOException |
|
33 { |
|
34 int m = 1; |
|
35 for (int i = 0; i < NumBitLevels; i++) |
|
36 { |
|
37 int bit = symbol & 1; |
|
38 rangeEncoder.Encode(Models, m, bit); |
|
39 m = (m << 1) | bit; |
|
40 symbol >>= 1; |
|
41 } |
|
42 } |
|
43 |
|
44 public int GetPrice(int symbol) |
|
45 { |
|
46 int price = 0; |
|
47 int m = 1; |
|
48 for (int bitIndex = NumBitLevels; bitIndex != 0; ) |
|
49 { |
|
50 bitIndex--; |
|
51 int bit = (symbol >>> bitIndex) & 1; |
|
52 price += Encoder.GetPrice(Models[m], bit); |
|
53 m = (m << 1) + bit; |
|
54 } |
|
55 return price; |
|
56 } |
|
57 |
|
58 public int ReverseGetPrice(int symbol) |
|
59 { |
|
60 int price = 0; |
|
61 int m = 1; |
|
62 for (int i = NumBitLevels; i != 0; i--) |
|
63 { |
|
64 int bit = symbol & 1; |
|
65 symbol >>>= 1; |
|
66 price += Encoder.GetPrice(Models[m], bit); |
|
67 m = (m << 1) | bit; |
|
68 } |
|
69 return price; |
|
70 } |
|
71 |
|
72 public static int ReverseGetPrice(short[] Models, int startIndex, |
|
73 int NumBitLevels, int symbol) |
|
74 { |
|
75 int price = 0; |
|
76 int m = 1; |
|
77 for (int i = NumBitLevels; i != 0; i--) |
|
78 { |
|
79 int bit = symbol & 1; |
|
80 symbol >>>= 1; |
|
81 price += Encoder.GetPrice(Models[startIndex + m], bit); |
|
82 m = (m << 1) | bit; |
|
83 } |
|
84 return price; |
|
85 } |
|
86 |
|
87 public static void ReverseEncode(short[] Models, int startIndex, |
|
88 Encoder rangeEncoder, int NumBitLevels, int symbol) throws IOException |
|
89 { |
|
90 int m = 1; |
|
91 for (int i = 0; i < NumBitLevels; i++) |
|
92 { |
|
93 int bit = symbol & 1; |
|
94 rangeEncoder.Encode(Models, startIndex + m, bit); |
|
95 m = (m << 1) | bit; |
|
96 symbol >>= 1; |
|
97 } |
|
98 } |
|
99 } |