1370b324cSopenharmony_ciusing System; 2370b324cSopenharmony_ci 3370b324cSopenharmony_cinamespace SevenZip.Compression.RangeCoder 4370b324cSopenharmony_ci{ 5370b324cSopenharmony_ci class Encoder 6370b324cSopenharmony_ci { 7370b324cSopenharmony_ci public const uint kTopValue = (1 << 24); 8370b324cSopenharmony_ci 9370b324cSopenharmony_ci System.IO.Stream Stream; 10370b324cSopenharmony_ci 11370b324cSopenharmony_ci public UInt64 Low; 12370b324cSopenharmony_ci public uint Range; 13370b324cSopenharmony_ci uint _cacheSize; 14370b324cSopenharmony_ci byte _cache; 15370b324cSopenharmony_ci 16370b324cSopenharmony_ci long StartPosition; 17370b324cSopenharmony_ci 18370b324cSopenharmony_ci public void SetStream(System.IO.Stream stream) 19370b324cSopenharmony_ci { 20370b324cSopenharmony_ci Stream = stream; 21370b324cSopenharmony_ci } 22370b324cSopenharmony_ci 23370b324cSopenharmony_ci public void ReleaseStream() 24370b324cSopenharmony_ci { 25370b324cSopenharmony_ci Stream = null; 26370b324cSopenharmony_ci } 27370b324cSopenharmony_ci 28370b324cSopenharmony_ci public void Init() 29370b324cSopenharmony_ci { 30370b324cSopenharmony_ci StartPosition = Stream.Position; 31370b324cSopenharmony_ci 32370b324cSopenharmony_ci Low = 0; 33370b324cSopenharmony_ci Range = 0xFFFFFFFF; 34370b324cSopenharmony_ci _cacheSize = 1; 35370b324cSopenharmony_ci _cache = 0; 36370b324cSopenharmony_ci } 37370b324cSopenharmony_ci 38370b324cSopenharmony_ci public void FlushData() 39370b324cSopenharmony_ci { 40370b324cSopenharmony_ci for (int i = 0; i < 5; i++) 41370b324cSopenharmony_ci ShiftLow(); 42370b324cSopenharmony_ci } 43370b324cSopenharmony_ci 44370b324cSopenharmony_ci public void FlushStream() 45370b324cSopenharmony_ci { 46370b324cSopenharmony_ci Stream.Flush(); 47370b324cSopenharmony_ci } 48370b324cSopenharmony_ci 49370b324cSopenharmony_ci public void CloseStream() 50370b324cSopenharmony_ci { 51370b324cSopenharmony_ci Stream.Close(); 52370b324cSopenharmony_ci } 53370b324cSopenharmony_ci 54370b324cSopenharmony_ci public void Encode(uint start, uint size, uint total) 55370b324cSopenharmony_ci { 56370b324cSopenharmony_ci Low += start * (Range /= total); 57370b324cSopenharmony_ci Range *= size; 58370b324cSopenharmony_ci while (Range < kTopValue) 59370b324cSopenharmony_ci { 60370b324cSopenharmony_ci Range <<= 8; 61370b324cSopenharmony_ci ShiftLow(); 62370b324cSopenharmony_ci } 63370b324cSopenharmony_ci } 64370b324cSopenharmony_ci 65370b324cSopenharmony_ci public void ShiftLow() 66370b324cSopenharmony_ci { 67370b324cSopenharmony_ci if ((uint)Low < (uint)0xFF000000 || (uint)(Low >> 32) == 1) 68370b324cSopenharmony_ci { 69370b324cSopenharmony_ci byte temp = _cache; 70370b324cSopenharmony_ci do 71370b324cSopenharmony_ci { 72370b324cSopenharmony_ci Stream.WriteByte((byte)(temp + (Low >> 32))); 73370b324cSopenharmony_ci temp = 0xFF; 74370b324cSopenharmony_ci } 75370b324cSopenharmony_ci while (--_cacheSize != 0); 76370b324cSopenharmony_ci _cache = (byte)(((uint)Low) >> 24); 77370b324cSopenharmony_ci } 78370b324cSopenharmony_ci _cacheSize++; 79370b324cSopenharmony_ci Low = ((uint)Low) << 8; 80370b324cSopenharmony_ci } 81370b324cSopenharmony_ci 82370b324cSopenharmony_ci public void EncodeDirectBits(uint v, int numTotalBits) 83370b324cSopenharmony_ci { 84370b324cSopenharmony_ci for (int i = numTotalBits - 1; i >= 0; i--) 85370b324cSopenharmony_ci { 86370b324cSopenharmony_ci Range >>= 1; 87370b324cSopenharmony_ci if (((v >> i) & 1) == 1) 88370b324cSopenharmony_ci Low += Range; 89370b324cSopenharmony_ci if (Range < kTopValue) 90370b324cSopenharmony_ci { 91370b324cSopenharmony_ci Range <<= 8; 92370b324cSopenharmony_ci ShiftLow(); 93370b324cSopenharmony_ci } 94370b324cSopenharmony_ci } 95370b324cSopenharmony_ci } 96370b324cSopenharmony_ci 97370b324cSopenharmony_ci public void EncodeBit(uint size0, int numTotalBits, uint symbol) 98370b324cSopenharmony_ci { 99370b324cSopenharmony_ci uint newBound = (Range >> numTotalBits) * size0; 100370b324cSopenharmony_ci if (symbol == 0) 101370b324cSopenharmony_ci Range = newBound; 102370b324cSopenharmony_ci else 103370b324cSopenharmony_ci { 104370b324cSopenharmony_ci Low += newBound; 105370b324cSopenharmony_ci Range -= newBound; 106370b324cSopenharmony_ci } 107370b324cSopenharmony_ci while (Range < kTopValue) 108370b324cSopenharmony_ci { 109370b324cSopenharmony_ci Range <<= 8; 110370b324cSopenharmony_ci ShiftLow(); 111370b324cSopenharmony_ci } 112370b324cSopenharmony_ci } 113370b324cSopenharmony_ci 114370b324cSopenharmony_ci public long GetProcessedSizeAdd() 115370b324cSopenharmony_ci { 116370b324cSopenharmony_ci return _cacheSize + 117370b324cSopenharmony_ci Stream.Position - StartPosition + 4; 118370b324cSopenharmony_ci // (long)Stream.GetProcessedSize(); 119370b324cSopenharmony_ci } 120370b324cSopenharmony_ci } 121370b324cSopenharmony_ci 122370b324cSopenharmony_ci class Decoder 123370b324cSopenharmony_ci { 124370b324cSopenharmony_ci public const uint kTopValue = (1 << 24); 125370b324cSopenharmony_ci public uint Range; 126370b324cSopenharmony_ci public uint Code; 127370b324cSopenharmony_ci // public Buffer.InBuffer Stream = new Buffer.InBuffer(1 << 16); 128370b324cSopenharmony_ci public System.IO.Stream Stream; 129370b324cSopenharmony_ci 130370b324cSopenharmony_ci public void Init(System.IO.Stream stream) 131370b324cSopenharmony_ci { 132370b324cSopenharmony_ci // Stream.Init(stream); 133370b324cSopenharmony_ci Stream = stream; 134370b324cSopenharmony_ci 135370b324cSopenharmony_ci Code = 0; 136370b324cSopenharmony_ci Range = 0xFFFFFFFF; 137370b324cSopenharmony_ci for (int i = 0; i < 5; i++) 138370b324cSopenharmony_ci Code = (Code << 8) | (byte)Stream.ReadByte(); 139370b324cSopenharmony_ci } 140370b324cSopenharmony_ci 141370b324cSopenharmony_ci public void ReleaseStream() 142370b324cSopenharmony_ci { 143370b324cSopenharmony_ci // Stream.ReleaseStream(); 144370b324cSopenharmony_ci Stream = null; 145370b324cSopenharmony_ci } 146370b324cSopenharmony_ci 147370b324cSopenharmony_ci public void CloseStream() 148370b324cSopenharmony_ci { 149370b324cSopenharmony_ci Stream.Close(); 150370b324cSopenharmony_ci } 151370b324cSopenharmony_ci 152370b324cSopenharmony_ci public void Normalize() 153370b324cSopenharmony_ci { 154370b324cSopenharmony_ci while (Range < kTopValue) 155370b324cSopenharmony_ci { 156370b324cSopenharmony_ci Code = (Code << 8) | (byte)Stream.ReadByte(); 157370b324cSopenharmony_ci Range <<= 8; 158370b324cSopenharmony_ci } 159370b324cSopenharmony_ci } 160370b324cSopenharmony_ci 161370b324cSopenharmony_ci public void Normalize2() 162370b324cSopenharmony_ci { 163370b324cSopenharmony_ci if (Range < kTopValue) 164370b324cSopenharmony_ci { 165370b324cSopenharmony_ci Code = (Code << 8) | (byte)Stream.ReadByte(); 166370b324cSopenharmony_ci Range <<= 8; 167370b324cSopenharmony_ci } 168370b324cSopenharmony_ci } 169370b324cSopenharmony_ci 170370b324cSopenharmony_ci public uint GetThreshold(uint total) 171370b324cSopenharmony_ci { 172370b324cSopenharmony_ci return Code / (Range /= total); 173370b324cSopenharmony_ci } 174370b324cSopenharmony_ci 175370b324cSopenharmony_ci public void Decode(uint start, uint size, uint total) 176370b324cSopenharmony_ci { 177370b324cSopenharmony_ci Code -= start * Range; 178370b324cSopenharmony_ci Range *= size; 179370b324cSopenharmony_ci Normalize(); 180370b324cSopenharmony_ci } 181370b324cSopenharmony_ci 182370b324cSopenharmony_ci public uint DecodeDirectBits(int numTotalBits) 183370b324cSopenharmony_ci { 184370b324cSopenharmony_ci uint range = Range; 185370b324cSopenharmony_ci uint code = Code; 186370b324cSopenharmony_ci uint result = 0; 187370b324cSopenharmony_ci for (int i = numTotalBits; i > 0; i--) 188370b324cSopenharmony_ci { 189370b324cSopenharmony_ci range >>= 1; 190370b324cSopenharmony_ci /* 191370b324cSopenharmony_ci result <<= 1; 192370b324cSopenharmony_ci if (code >= range) 193370b324cSopenharmony_ci { 194370b324cSopenharmony_ci code -= range; 195370b324cSopenharmony_ci result |= 1; 196370b324cSopenharmony_ci } 197370b324cSopenharmony_ci */ 198370b324cSopenharmony_ci uint t = (code - range) >> 31; 199370b324cSopenharmony_ci code -= range & (t - 1); 200370b324cSopenharmony_ci result = (result << 1) | (1 - t); 201370b324cSopenharmony_ci 202370b324cSopenharmony_ci if (range < kTopValue) 203370b324cSopenharmony_ci { 204370b324cSopenharmony_ci code = (code << 8) | (byte)Stream.ReadByte(); 205370b324cSopenharmony_ci range <<= 8; 206370b324cSopenharmony_ci } 207370b324cSopenharmony_ci } 208370b324cSopenharmony_ci Range = range; 209370b324cSopenharmony_ci Code = code; 210370b324cSopenharmony_ci return result; 211370b324cSopenharmony_ci } 212370b324cSopenharmony_ci 213370b324cSopenharmony_ci public uint DecodeBit(uint size0, int numTotalBits) 214370b324cSopenharmony_ci { 215370b324cSopenharmony_ci uint newBound = (Range >> numTotalBits) * size0; 216370b324cSopenharmony_ci uint symbol; 217370b324cSopenharmony_ci if (Code < newBound) 218370b324cSopenharmony_ci { 219370b324cSopenharmony_ci symbol = 0; 220370b324cSopenharmony_ci Range = newBound; 221370b324cSopenharmony_ci } 222370b324cSopenharmony_ci else 223370b324cSopenharmony_ci { 224370b324cSopenharmony_ci symbol = 1; 225370b324cSopenharmony_ci Code -= newBound; 226370b324cSopenharmony_ci Range -= newBound; 227370b324cSopenharmony_ci } 228370b324cSopenharmony_ci Normalize(); 229370b324cSopenharmony_ci return symbol; 230370b324cSopenharmony_ci } 231370b324cSopenharmony_ci 232370b324cSopenharmony_ci // ulong GetProcessedSize() {return Stream.GetProcessedSize(); } 233370b324cSopenharmony_ci } 234370b324cSopenharmony_ci} 235