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