Annotation of elwix/tools/oldlzma/SRC/7zip/Compress/RangeCoder/RangeCoder.h, revision 1.1.1.1
1.1 misho 1: // Compress/RangeCoder/RangeCoder.h
2:
3: #ifndef __COMPRESS_RANGECODER_H
4: #define __COMPRESS_RANGECODER_H
5:
6: #include "../../Common/InBuffer.h"
7: #include "../../Common/OutBuffer.h"
8:
9: namespace NCompress {
10: namespace NRangeCoder {
11:
12: const int kNumTopBits = 24;
13: const UInt32 kTopValue = (1 << kNumTopBits);
14:
15: class CEncoder
16: {
17: UInt32 _ffNum;
18: Byte _cache;
19: public:
20: UInt64 Low;
21: UInt32 Range;
22: COutBuffer Stream;
23: bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); }
24:
25: void SetStream(ISequentialOutStream *stream) { Stream.SetStream(stream); }
26: void Init()
27: {
28: Stream.Init();
29: Low = 0;
30: Range = 0xFFFFFFFF;
31: _ffNum = 0;
32: _cache = 0;
33: }
34:
35: void FlushData()
36: {
37: // Low += 1;
38: for(int i = 0; i < 5; i++)
39: ShiftLow();
40: }
41:
42: HRESULT FlushStream() { return Stream.Flush(); }
43:
44: void ReleaseStream() { Stream.ReleaseStream(); }
45:
46: void Encode(UInt32 start, UInt32 size, UInt32 total)
47: {
48: Low += start * (Range /= total);
49: Range *= size;
50: while (Range < kTopValue)
51: {
52: Range <<= 8;
53: ShiftLow();
54: }
55: }
56:
57: /*
58: void EncodeDirectBitsDiv(UInt32 value, UInt32 numTotalBits)
59: {
60: Low += value * (Range >>= numTotalBits);
61: Normalize();
62: }
63:
64: void EncodeDirectBitsDiv2(UInt32 value, UInt32 numTotalBits)
65: {
66: if (numTotalBits <= kNumBottomBits)
67: EncodeDirectBitsDiv(value, numTotalBits);
68: else
69: {
70: EncodeDirectBitsDiv(value >> kNumBottomBits, (numTotalBits - kNumBottomBits));
71: EncodeDirectBitsDiv(value & ((1 << kBottomValueBits) - 1), kNumBottomBits);
72: }
73: }
74: */
75: void ShiftLow()
76: {
77: if (Low < (UInt32)0xFF000000 || UInt32(Low >> 32) == 1)
78: {
79: Stream.WriteByte(Byte(_cache + Byte(Low >> 32)));
80: for (;_ffNum != 0; _ffNum--)
81: Stream.WriteByte(Byte(0xFF + Byte(Low >> 32)));
82: _cache = Byte(UInt32(Low) >> 24);
83: }
84: else
85: _ffNum++;
86: Low = UInt32(Low) << 8;
87: }
88:
89: void EncodeDirectBits(UInt32 value, int numTotalBits)
90: {
91: for (int i = numTotalBits - 1; i >= 0; i--)
92: {
93: Range >>= 1;
94: if (((value >> i) & 1) == 1)
95: Low += Range;
96: if (Range < kTopValue)
97: {
98: Range <<= 8;
99: ShiftLow();
100: }
101: }
102: }
103:
104: void EncodeBit(UInt32 size0, UInt32 numTotalBits, UInt32 symbol)
105: {
106: UInt32 newBound = (Range >> numTotalBits) * size0;
107: if (symbol == 0)
108: Range = newBound;
109: else
110: {
111: Low += newBound;
112: Range -= newBound;
113: }
114: while (Range < kTopValue)
115: {
116: Range <<= 8;
117: ShiftLow();
118: }
119: }
120:
121: UInt64 GetProcessedSize() { return Stream.GetProcessedSize() + _ffNum; }
122: };
123:
124: class CDecoder
125: {
126: public:
127: CInBuffer Stream;
128: UInt32 Range;
129: UInt32 Code;
130: bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); }
131:
132: void Normalize()
133: {
134: while (Range < kTopValue)
135: {
136: Code = (Code << 8) | Stream.ReadByte();
137: Range <<= 8;
138: }
139: }
140:
141: void SetStream(ISequentialInStream *stream) { Stream.SetStream(stream); }
142: void Init()
143: {
144: Stream.Init();
145: Code = 0;
146: Range = 0xFFFFFFFF;
147: for(int i = 0; i < 5; i++)
148: Code = (Code << 8) | Stream.ReadByte();
149: }
150:
151: void ReleaseStream() { Stream.ReleaseStream(); }
152:
153: UInt32 GetThreshold(UInt32 total)
154: {
155: return (Code) / ( Range /= total);
156: }
157:
158: void Decode(UInt32 start, UInt32 size)
159: {
160: Code -= start * Range;
161: Range *= size;
162: Normalize();
163: }
164:
165: /*
166: UInt32 DecodeDirectBitsDiv(UInt32 numTotalBits)
167: {
168: Range >>= numTotalBits;
169: UInt32 threshold = Code / Range;
170: Code -= threshold * Range;
171:
172: Normalize();
173: return threshold;
174: }
175:
176: UInt32 DecodeDirectBitsDiv2(UInt32 numTotalBits)
177: {
178: if (numTotalBits <= kNumBottomBits)
179: return DecodeDirectBitsDiv(numTotalBits);
180: UInt32 result = DecodeDirectBitsDiv(numTotalBits - kNumBottomBits) << kNumBottomBits;
181: return (result | DecodeDirectBitsDiv(kNumBottomBits));
182: }
183: */
184:
185: UInt32 DecodeDirectBits(int numTotalBits)
186: {
187: UInt32 range = Range;
188: UInt32 code = Code;
189: UInt32 result = 0;
190: for (int i = numTotalBits; i != 0; i--)
191: {
192: range >>= 1;
193: /*
194: result <<= 1;
195: if (code >= range)
196: {
197: code -= range;
198: result |= 1;
199: }
200: */
201: UInt32 t = (code - range) >> 31;
202: code -= range & (t - 1);
203: result = (result << 1) | (1 - t);
204:
205: if (range < kTopValue)
206: {
207: code = (code << 8) | Stream.ReadByte();
208: range <<= 8;
209: }
210: }
211: Range = range;
212: Code = code;
213: return result;
214: }
215:
216: UInt32 DecodeBit(UInt32 size0, UInt32 numTotalBits)
217: {
218: UInt32 newBound = (Range >> numTotalBits) * size0;
219: UInt32 symbol;
220: if (Code < newBound)
221: {
222: symbol = 0;
223: Range = newBound;
224: }
225: else
226: {
227: symbol = 1;
228: Code -= newBound;
229: Range -= newBound;
230: }
231: Normalize();
232: return symbol;
233: }
234:
235: UInt64 GetProcessedSize() {return Stream.GetProcessedSize(); }
236: };
237:
238: }}
239:
240: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>