OLD | NEW |
| (Empty) |
1 using System; | |
2 | |
3 namespace SevenZip.Compression.RangeCoder | |
4 { | |
5 class Encoder | |
6 { | |
7 public const uint kTopValue = (1 << 24); | |
8 | |
9 System.IO.Stream Stream; | |
10 | |
11 public UInt64 Low; | |
12 public uint Range; | |
13 uint _cacheSize; | |
14 byte _cache; | |
15 | |
16 long StartPosition; | |
17 | |
18 public void SetStream(System.IO.Stream stream) | |
19 { | |
20 Stream = stream; | |
21 } | |
22 | |
23 public void ReleaseStream() | |
24 { | |
25 Stream = null; | |
26 } | |
27 | |
28 public void Init() | |
29 { | |
30 StartPosition = Stream.Position; | |
31 | |
32 Low = 0; | |
33 Range = 0xFFFFFFFF; | |
34 _cacheSize = 1; | |
35 _cache = 0; | |
36 } | |
37 | |
38 public void FlushData() | |
39 { | |
40 for (int i = 0; i < 5; i++) | |
41 ShiftLow(); | |
42 } | |
43 | |
44 public void FlushStream() | |
45 { | |
46 Stream.Flush(); | |
47 } | |
48 | |
49 public void CloseStream() | |
50 { | |
51 Stream.Close(); | |
52 } | |
53 | |
54 public void Encode(uint start, uint size, uint total) | |
55 { | |
56 Low += start * (Range /= total); | |
57 Range *= size; | |
58 while (Range < kTopValue) | |
59 { | |
60 Range <<= 8; | |
61 ShiftLow(); | |
62 } | |
63 } | |
64 | |
65 public void ShiftLow() | |
66 { | |
67 if ((uint)Low < (uint)0xFF000000 || (uint)(Low >> 32) ==
1) | |
68 { | |
69 byte temp = _cache; | |
70 do | |
71 { | |
72 Stream.WriteByte((byte)(temp + (Low >> 3
2))); | |
73 temp = 0xFF; | |
74 } | |
75 while (--_cacheSize != 0); | |
76 _cache = (byte)(((uint)Low) >> 24); | |
77 } | |
78 _cacheSize++; | |
79 Low = ((uint)Low) << 8; | |
80 } | |
81 | |
82 public void EncodeDirectBits(uint v, int numTotalBits) | |
83 { | |
84 for (int i = numTotalBits - 1; i >= 0; i--) | |
85 { | |
86 Range >>= 1; | |
87 if (((v >> i) & 1) == 1) | |
88 Low += Range; | |
89 if (Range < kTopValue) | |
90 { | |
91 Range <<= 8; | |
92 ShiftLow(); | |
93 } | |
94 } | |
95 } | |
96 | |
97 public void EncodeBit(uint size0, int numTotalBits, uint symbol) | |
98 { | |
99 uint newBound = (Range >> numTotalBits) * size0; | |
100 if (symbol == 0) | |
101 Range = newBound; | |
102 else | |
103 { | |
104 Low += newBound; | |
105 Range -= newBound; | |
106 } | |
107 while (Range < kTopValue) | |
108 { | |
109 Range <<= 8; | |
110 ShiftLow(); | |
111 } | |
112 } | |
113 | |
114 public long GetProcessedSizeAdd() | |
115 { | |
116 return _cacheSize + | |
117 Stream.Position - StartPosition + 4; | |
118 // (long)Stream.GetProcessedSize(); | |
119 } | |
120 } | |
121 | |
122 class Decoder | |
123 { | |
124 public const uint kTopValue = (1 << 24); | |
125 public uint Range; | |
126 public uint Code; | |
127 // public Buffer.InBuffer Stream = new Buffer.InBuffer(1 << 16); | |
128 public System.IO.Stream Stream; | |
129 | |
130 public void Init(System.IO.Stream stream) | |
131 { | |
132 // Stream.Init(stream); | |
133 Stream = stream; | |
134 | |
135 Code = 0; | |
136 Range = 0xFFFFFFFF; | |
137 for (int i = 0; i < 5; i++) | |
138 Code = (Code << 8) | (byte)Stream.ReadByte(); | |
139 } | |
140 | |
141 public void ReleaseStream() | |
142 { | |
143 // Stream.ReleaseStream(); | |
144 Stream = null; | |
145 } | |
146 | |
147 public void CloseStream() | |
148 { | |
149 Stream.Close(); | |
150 } | |
151 | |
152 public void Normalize() | |
153 { | |
154 while (Range < kTopValue) | |
155 { | |
156 Code = (Code << 8) | (byte)Stream.ReadByte(); | |
157 Range <<= 8; | |
158 } | |
159 } | |
160 | |
161 public void Normalize2() | |
162 { | |
163 if (Range < kTopValue) | |
164 { | |
165 Code = (Code << 8) | (byte)Stream.ReadByte(); | |
166 Range <<= 8; | |
167 } | |
168 } | |
169 | |
170 public uint GetThreshold(uint total) | |
171 { | |
172 return Code / (Range /= total); | |
173 } | |
174 | |
175 public void Decode(uint start, uint size, uint total) | |
176 { | |
177 Code -= start * Range; | |
178 Range *= size; | |
179 Normalize(); | |
180 } | |
181 | |
182 public uint DecodeDirectBits(int numTotalBits) | |
183 { | |
184 uint range = Range; | |
185 uint code = Code; | |
186 uint result = 0; | |
187 for (int i = numTotalBits; i > 0; i--) | |
188 { | |
189 range >>= 1; | |
190 /* | |
191 result <<= 1; | |
192 if (code >= range) | |
193 { | |
194 code -= range; | |
195 result |= 1; | |
196 } | |
197 */ | |
198 uint t = (code - range) >> 31; | |
199 code -= range & (t - 1); | |
200 result = (result << 1) | (1 - t); | |
201 | |
202 if (range < kTopValue) | |
203 { | |
204 code = (code << 8) | (byte)Stream.ReadBy
te(); | |
205 range <<= 8; | |
206 } | |
207 } | |
208 Range = range; | |
209 Code = code; | |
210 return result; | |
211 } | |
212 | |
213 public uint DecodeBit(uint size0, int numTotalBits) | |
214 { | |
215 uint newBound = (Range >> numTotalBits) * size0; | |
216 uint symbol; | |
217 if (Code < newBound) | |
218 { | |
219 symbol = 0; | |
220 Range = newBound; | |
221 } | |
222 else | |
223 { | |
224 symbol = 1; | |
225 Code -= newBound; | |
226 Range -= newBound; | |
227 } | |
228 Normalize(); | |
229 return symbol; | |
230 } | |
231 | |
232 // ulong GetProcessedSize() {return Stream.GetProcessedSize(); } | |
233 } | |
234 } | |
OLD | NEW |