OLD | NEW |
| (Empty) |
1 using System; | |
2 | |
3 namespace SevenZip.Compression.RangeCoder | |
4 { | |
5 struct BitEncoder | |
6 { | |
7 public const int kNumBitModelTotalBits = 11; | |
8 public const uint kBitModelTotal = (1 << kNumBitModelTotalBits); | |
9 const int kNumMoveBits = 5; | |
10 const int kNumMoveReducingBits = 2; | |
11 public const int kNumBitPriceShiftBits = 6; | |
12 | |
13 uint Prob; | |
14 | |
15 public void Init() { Prob = kBitModelTotal >> 1; } | |
16 | |
17 public void UpdateModel(uint symbol) | |
18 { | |
19 if (symbol == 0) | |
20 Prob += (kBitModelTotal - Prob) >> kNumMoveBits; | |
21 else | |
22 Prob -= (Prob) >> kNumMoveBits; | |
23 } | |
24 | |
25 public void Encode(Encoder encoder, uint symbol) | |
26 { | |
27 // encoder.EncodeBit(Prob, kNumBitModelTotalBits, symbol
); | |
28 // UpdateModel(symbol); | |
29 uint newBound = (encoder.Range >> kNumBitModelTotalBits)
* Prob; | |
30 if (symbol == 0) | |
31 { | |
32 encoder.Range = newBound; | |
33 Prob += (kBitModelTotal - Prob) >> kNumMoveBits; | |
34 } | |
35 else | |
36 { | |
37 encoder.Low += newBound; | |
38 encoder.Range -= newBound; | |
39 Prob -= (Prob) >> kNumMoveBits; | |
40 } | |
41 if (encoder.Range < Encoder.kTopValue) | |
42 { | |
43 encoder.Range <<= 8; | |
44 encoder.ShiftLow(); | |
45 } | |
46 } | |
47 | |
48 private static UInt32[] ProbPrices = new UInt32[kBitModelTotal >
> kNumMoveReducingBits]; | |
49 | |
50 static BitEncoder() | |
51 { | |
52 const int kNumBits = (kNumBitModelTotalBits - kNumMoveRe
ducingBits); | |
53 for (int i = kNumBits - 1; i >= 0; i--) | |
54 { | |
55 UInt32 start = (UInt32)1 << (kNumBits - i - 1); | |
56 UInt32 end = (UInt32)1 << (kNumBits - i); | |
57 for (UInt32 j = start; j < end; j++) | |
58 ProbPrices[j] = ((UInt32)i << kNumBitPri
ceShiftBits) + | |
59 (((end - j) << kNumBitPriceShift
Bits) >> (kNumBits - i - 1)); | |
60 } | |
61 } | |
62 | |
63 public uint GetPrice(uint symbol) | |
64 { | |
65 return ProbPrices[(((Prob - symbol) ^ ((-(int)symbol)))
& (kBitModelTotal - 1)) >> kNumMoveReducingBits]; | |
66 } | |
67 public uint GetPrice0() { return ProbPrices[Prob >> kNumMoveReducingBi
ts]; } | |
68 public uint GetPrice1() { return ProbPrices[(kBitModelTotal - Pr
ob) >> kNumMoveReducingBits]; } | |
69 } | |
70 | |
71 struct BitDecoder | |
72 { | |
73 public const int kNumBitModelTotalBits = 11; | |
74 public const uint kBitModelTotal = (1 << kNumBitModelTotalBits); | |
75 const int kNumMoveBits = 5; | |
76 | |
77 uint Prob; | |
78 | |
79 public void UpdateModel(int numMoveBits, uint symbol) | |
80 { | |
81 if (symbol == 0) | |
82 Prob += (kBitModelTotal - Prob) >> numMoveBits; | |
83 else | |
84 Prob -= (Prob) >> numMoveBits; | |
85 } | |
86 | |
87 public void Init() { Prob = kBitModelTotal >> 1; } | |
88 | |
89 public uint Decode(RangeCoder.Decoder rangeDecoder) | |
90 { | |
91 uint newBound = (uint)(rangeDecoder.Range >> kNumBitMode
lTotalBits) * (uint)Prob; | |
92 if (rangeDecoder.Code < newBound) | |
93 { | |
94 rangeDecoder.Range = newBound; | |
95 Prob += (kBitModelTotal - Prob) >> kNumMoveBits; | |
96 if (rangeDecoder.Range < Decoder.kTopValue) | |
97 { | |
98 rangeDecoder.Code = (rangeDecoder.Code <
< 8) | (byte)rangeDecoder.Stream.ReadByte(); | |
99 rangeDecoder.Range <<= 8; | |
100 } | |
101 return 0; | |
102 } | |
103 else | |
104 { | |
105 rangeDecoder.Range -= newBound; | |
106 rangeDecoder.Code -= newBound; | |
107 Prob -= (Prob) >> kNumMoveBits; | |
108 if (rangeDecoder.Range < Decoder.kTopValue) | |
109 { | |
110 rangeDecoder.Code = (rangeDecoder.Code <
< 8) | (byte)rangeDecoder.Stream.ReadByte(); | |
111 rangeDecoder.Range <<= 8; | |
112 } | |
113 return 1; | |
114 } | |
115 } | |
116 } | |
117 } | |
OLD | NEW |