1 // Compress/RangeCoder/RangeCoder.h
\r
3 #ifndef __COMPRESS_RANGECODER_H
\r
4 #define __COMPRESS_RANGECODER_H
\r
6 #include "../../Common/InBuffer.h"
\r
7 #include "../../Common/OutBuffer.h"
\r
9 namespace NCompress {
\r
10 namespace NRangeCoder {
\r
12 const int kNumTopBits = 24;
\r
13 const UInt32 kTopValue = (1 << kNumTopBits);
\r
23 bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); }
\r
25 void SetStream(ISequentialOutStream *stream) { Stream.SetStream(stream); }
\r
38 for(int i = 0; i < 5; i++)
\r
42 HRESULT FlushStream() { return Stream.Flush(); }
\r
44 void ReleaseStream() { Stream.ReleaseStream(); }
\r
46 void Encode(UInt32 start, UInt32 size, UInt32 total)
\r
48 Low += start * (Range /= total);
\r
50 while (Range < kTopValue)
\r
59 if ((UInt32)Low < (UInt32)0xFF000000 || (int)(Low >> 32) != 0)
\r
64 Stream.WriteByte((Byte)(temp + (Byte)(Low >> 32)));
\r
67 while(--_cacheSize != 0);
\r
68 _cache = (Byte)((UInt32)Low >> 24);
\r
71 Low = (UInt32)Low << 8;
\r
74 void EncodeDirectBits(UInt32 value, int numTotalBits)
\r
76 for (int i = numTotalBits - 1; i >= 0; i--)
\r
79 if (((value >> i) & 1) == 1)
\r
81 if (Range < kTopValue)
\r
89 void EncodeBit(UInt32 size0, UInt32 numTotalBits, UInt32 symbol)
\r
91 UInt32 newBound = (Range >> numTotalBits) * size0;
\r
99 while (Range < kTopValue)
\r
106 UInt64 GetProcessedSize() { return Stream.GetProcessedSize() + _cacheSize + 4; }
\r
115 bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); }
\r
119 while (Range < kTopValue)
\r
121 Code = (Code << 8) | Stream.ReadByte();
\r
126 void SetStream(ISequentialInStream *stream) { Stream.SetStream(stream); }
\r
131 Range = 0xFFFFFFFF;
\r
132 for(int i = 0; i < 5; i++)
\r
133 Code = (Code << 8) | Stream.ReadByte();
\r
136 void ReleaseStream() { Stream.ReleaseStream(); }
\r
138 UInt32 GetThreshold(UInt32 total)
\r
140 return (Code) / ( Range /= total);
\r
143 void Decode(UInt32 start, UInt32 size)
\r
145 Code -= start * Range;
\r
150 UInt32 DecodeDirectBits(int numTotalBits)
\r
152 UInt32 range = Range;
\r
153 UInt32 code = Code;
\r
155 for (int i = numTotalBits; i != 0; i--)
\r
166 UInt32 t = (code - range) >> 31;
\r
167 code -= range & (t - 1);
\r
168 result = (result << 1) | (1 - t);
\r
170 if (range < kTopValue)
\r
172 code = (code << 8) | Stream.ReadByte();
\r
181 UInt32 DecodeBit(UInt32 size0, UInt32 numTotalBits)
\r
183 UInt32 newBound = (Range >> numTotalBits) * size0;
\r
185 if (Code < newBound)
\r
200 UInt64 GetProcessedSize() {return Stream.GetProcessedSize(); }
\r