-// Compress/RangeCoder/RangeCoder.h\r
-\r
-#ifndef __COMPRESS_RANGECODER_H\r
-#define __COMPRESS_RANGECODER_H\r
-\r
-#include "../../Common/InBuffer.h"\r
-#include "../../Common/OutBuffer.h"\r
-\r
-namespace NCompress {\r
-namespace NRangeCoder {\r
-\r
-const int kNumTopBits = 24;\r
-const UInt32 kTopValue = (1 << kNumTopBits);\r
-\r
-class CEncoder\r
-{\r
- UInt32 _cacheSize;\r
- Byte _cache;\r
-public:\r
- UInt64 Low;\r
- UInt32 Range;\r
- COutBuffer Stream;\r
- bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); }\r
-\r
- void SetStream(ISequentialOutStream *stream) { Stream.SetStream(stream); }\r
- void Init()\r
- {\r
- Stream.Init();\r
- Low = 0;\r
- Range = 0xFFFFFFFF;\r
- _cacheSize = 1;\r
- _cache = 0;\r
- }\r
-\r
- void FlushData()\r
- {\r
- // Low += 1; \r
- for(int i = 0; i < 5; i++)\r
- ShiftLow();\r
- }\r
-\r
- HRESULT FlushStream() { return Stream.Flush(); }\r
-\r
- void ReleaseStream() { Stream.ReleaseStream(); }\r
-\r
- void Encode(UInt32 start, UInt32 size, UInt32 total)\r
- {\r
- Low += start * (Range /= total);\r
- Range *= size;\r
- while (Range < kTopValue)\r
- {\r
- Range <<= 8;\r
- ShiftLow();\r
- }\r
- }\r
-\r
- void ShiftLow()\r
- {\r
- if ((UInt32)Low < (UInt32)0xFF000000 || (int)(Low >> 32) != 0) \r
- {\r
- Byte temp = _cache;\r
- do\r
- {\r
- Stream.WriteByte((Byte)(temp + (Byte)(Low >> 32)));\r
- temp = 0xFF;\r
- }\r
- while(--_cacheSize != 0);\r
- _cache = (Byte)((UInt32)Low >> 24); \r
- } \r
- _cacheSize++; \r
- Low = (UInt32)Low << 8; \r
- }\r
- \r
- void EncodeDirectBits(UInt32 value, int numTotalBits)\r
- {\r
- for (int i = numTotalBits - 1; i >= 0; i--)\r
- {\r
- Range >>= 1;\r
- if (((value >> i) & 1) == 1)\r
- Low += Range;\r
- if (Range < kTopValue)\r
- {\r
- Range <<= 8;\r
- ShiftLow();\r
- }\r
- }\r
- }\r
-\r
- void EncodeBit(UInt32 size0, UInt32 numTotalBits, UInt32 symbol)\r
- {\r
- UInt32 newBound = (Range >> numTotalBits) * size0;\r
- if (symbol == 0)\r
- Range = newBound;\r
- else\r
- {\r
- Low += newBound;\r
- Range -= newBound;\r
- }\r
- while (Range < kTopValue)\r
- {\r
- Range <<= 8;\r
- ShiftLow();\r
- }\r
- }\r
-\r
- UInt64 GetProcessedSize() { return Stream.GetProcessedSize() + _cacheSize + 4; }\r
-};\r
-\r
-class CDecoder\r
-{\r
-public:\r
- CInBuffer Stream;\r
- UInt32 Range;\r
- UInt32 Code;\r
- bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); }\r
-\r
- void Normalize()\r
- {\r
- while (Range < kTopValue)\r
- {\r
- Code = (Code << 8) | Stream.ReadByte();\r
- Range <<= 8;\r
- }\r
- }\r
- \r
- void SetStream(ISequentialInStream *stream) { Stream.SetStream(stream); }\r
- void Init()\r
- {\r
- Stream.Init();\r
- Code = 0;\r
- Range = 0xFFFFFFFF;\r
- for(int i = 0; i < 5; i++)\r
- Code = (Code << 8) | Stream.ReadByte();\r
- }\r
-\r
- void ReleaseStream() { Stream.ReleaseStream(); }\r
-\r
- UInt32 GetThreshold(UInt32 total)\r
- {\r
- return (Code) / ( Range /= total);\r
- }\r
-\r
- void Decode(UInt32 start, UInt32 size)\r
- {\r
- Code -= start * Range;\r
- Range *= size;\r
- Normalize();\r
- }\r
-\r
- UInt32 DecodeDirectBits(int numTotalBits)\r
- {\r
- UInt32 range = Range;\r
- UInt32 code = Code; \r
- UInt32 result = 0;\r
- for (int i = numTotalBits; i != 0; i--)\r
- {\r
- range >>= 1;\r
- /*\r
- result <<= 1;\r
- if (code >= range)\r
- {\r
- code -= range;\r
- result |= 1;\r
- }\r
- */\r
- UInt32 t = (code - range) >> 31;\r
- code -= range & (t - 1);\r
- result = (result << 1) | (1 - t);\r
-\r
- if (range < kTopValue)\r
- {\r
- code = (code << 8) | Stream.ReadByte();\r
- range <<= 8; \r
- }\r
- }\r
- Range = range;\r
- Code = code;\r
- return result;\r
- }\r
-\r
- UInt32 DecodeBit(UInt32 size0, UInt32 numTotalBits)\r
- {\r
- UInt32 newBound = (Range >> numTotalBits) * size0;\r
- UInt32 symbol;\r
- if (Code < newBound)\r
- {\r
- symbol = 0;\r
- Range = newBound;\r
- }\r
- else\r
- {\r
- symbol = 1;\r
- Code -= newBound;\r
- Range -= newBound;\r
- }\r
- Normalize();\r
- return symbol;\r
- }\r
-\r
- UInt64 GetProcessedSize() {return Stream.GetProcessedSize(); }\r
-};\r
-\r
-}}\r
-\r
-#endif\r
+// Compress/RangeCoder/RangeCoder.h
+
+#ifndef __COMPRESS_RANGECODER_H
+#define __COMPRESS_RANGECODER_H
+
+#include "../../Common/InBuffer.h"
+#include "../../Common/OutBuffer.h"
+
+namespace NCompress {
+namespace NRangeCoder {
+
+const int kNumTopBits = 24;
+const UInt32 kTopValue = (1 << kNumTopBits);
+
+class CEncoder
+{
+ UInt32 _cacheSize;
+ Byte _cache;
+public:
+ UInt64 Low;
+ UInt32 Range;
+ COutBuffer Stream;
+ bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); }
+
+ void SetStream(ISequentialOutStream *stream) { Stream.SetStream(stream); }
+ void Init()
+ {
+ Stream.Init();
+ Low = 0;
+ Range = 0xFFFFFFFF;
+ _cacheSize = 1;
+ _cache = 0;
+ }
+
+ void FlushData()
+ {
+ // Low += 1;
+ for(int i = 0; i < 5; i++)
+ ShiftLow();
+ }
+
+ HRESULT FlushStream() { return Stream.Flush(); }
+
+ void ReleaseStream() { Stream.ReleaseStream(); }
+
+ void Encode(UInt32 start, UInt32 size, UInt32 total)
+ {
+ Low += start * (Range /= total);
+ Range *= size;
+ while (Range < kTopValue)
+ {
+ Range <<= 8;
+ ShiftLow();
+ }
+ }
+
+ void ShiftLow()
+ {
+ if ((UInt32)Low < (UInt32)0xFF000000 || (int)(Low >> 32) != 0)
+ {
+ Byte temp = _cache;
+ do
+ {
+ Stream.WriteByte((Byte)(temp + (Byte)(Low >> 32)));
+ temp = 0xFF;
+ }
+ while(--_cacheSize != 0);
+ _cache = (Byte)((UInt32)Low >> 24);
+ }
+ _cacheSize++;
+ Low = (UInt32)Low << 8;
+ }
+
+ void EncodeDirectBits(UInt32 value, int numTotalBits)
+ {
+ for (int i = numTotalBits - 1; i >= 0; i--)
+ {
+ Range >>= 1;
+ if (((value >> i) & 1) == 1)
+ Low += Range;
+ if (Range < kTopValue)
+ {
+ Range <<= 8;
+ ShiftLow();
+ }
+ }
+ }
+
+ void EncodeBit(UInt32 size0, UInt32 numTotalBits, UInt32 symbol)
+ {
+ UInt32 newBound = (Range >> numTotalBits) * size0;
+ if (symbol == 0)
+ Range = newBound;
+ else
+ {
+ Low += newBound;
+ Range -= newBound;
+ }
+ while (Range < kTopValue)
+ {
+ Range <<= 8;
+ ShiftLow();
+ }
+ }
+
+ UInt64 GetProcessedSize() { return Stream.GetProcessedSize() + _cacheSize + 4; }
+};
+
+class CDecoder
+{
+public:
+ CInBuffer Stream;
+ UInt32 Range;
+ UInt32 Code;
+ bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); }
+
+ void Normalize()
+ {
+ while (Range < kTopValue)
+ {
+ Code = (Code << 8) | Stream.ReadByte();
+ Range <<= 8;
+ }
+ }
+
+ void SetStream(ISequentialInStream *stream) { Stream.SetStream(stream); }
+ void Init()
+ {
+ Stream.Init();
+ Code = 0;
+ Range = 0xFFFFFFFF;
+ for(int i = 0; i < 5; i++)
+ Code = (Code << 8) | Stream.ReadByte();
+ }
+
+ void ReleaseStream() { Stream.ReleaseStream(); }
+
+ UInt32 GetThreshold(UInt32 total)
+ {
+ return (Code) / ( Range /= total);
+ }
+
+ void Decode(UInt32 start, UInt32 size)
+ {
+ Code -= start * Range;
+ Range *= size;
+ Normalize();
+ }
+
+ UInt32 DecodeDirectBits(int numTotalBits)
+ {
+ UInt32 range = Range;
+ UInt32 code = Code;
+ UInt32 result = 0;
+ for (int i = numTotalBits; i != 0; i--)
+ {
+ range >>= 1;
+ /*
+ result <<= 1;
+ if (code >= range)
+ {
+ code -= range;
+ result |= 1;
+ }
+ */
+ UInt32 t = (code - range) >> 31;
+ code -= range & (t - 1);
+ result = (result << 1) | (1 - t);
+
+ if (range < kTopValue)
+ {
+ code = (code << 8) | Stream.ReadByte();
+ range <<= 8;
+ }
+ }
+ Range = range;
+ Code = code;
+ return result;
+ }
+
+ UInt32 DecodeBit(UInt32 size0, UInt32 numTotalBits)
+ {
+ UInt32 newBound = (Range >> numTotalBits) * size0;
+ UInt32 symbol;
+ if (Code < newBound)
+ {
+ symbol = 0;
+ Range = newBound;
+ }
+ else
+ {
+ symbol = 1;
+ Code -= newBound;
+ Range -= newBound;
+ }
+ Normalize();
+ return symbol;
+ }
+
+ UInt64 GetProcessedSize() {return Stream.GetProcessedSize(); }
+};
+
+}}
+
+#endif