Annotation of elwix/tools/oldlzma/SRC/7zip/Compress/RangeCoder/RangeCoder.h, revision 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>