#region Using using System.IO; #endregion namespace SharpCompress.Compressors.PPMd.I1 { /// /// A simple range coder. /// /// /// Note that in most cases fields are used rather than properties for performance reasons (for example, /// is a field rather than a property). /// internal class Coder { private const uint RANGE_TOP = 1 << 24; private const uint RANGE_BOTTOM = 1 << 15; private uint _low; private uint _code; private uint _range; public uint _lowCount; public uint _highCount; public uint _scale; public void RangeEncoderInitialize() { _low = 0; _range = uint.MaxValue; } public void RangeEncoderNormalize(Stream stream) { while ((_low ^ (_low + _range)) < RANGE_TOP || _range < RANGE_BOTTOM && ((_range = (uint)-_low & (RANGE_BOTTOM - 1)) != 0 || true)) { stream.WriteByte((byte)(_low >> 24)); _range <<= 8; _low <<= 8; } } public void RangeEncodeSymbol() { _low += _lowCount * (_range /= _scale); _range *= _highCount - _lowCount; } public void RangeShiftEncodeSymbol(int rangeShift) { _low += _lowCount * (_range >>= rangeShift); _range *= _highCount - _lowCount; } public void RangeEncoderFlush(Stream stream) { for (uint index = 0; index < 4; index++) { stream.WriteByte((byte)(_low >> 24)); _low <<= 8; } } public void RangeDecoderInitialize(Stream stream) { _low = 0; _code = 0; _range = uint.MaxValue; for (uint index = 0; index < 4; index++) { _code = (_code << 8) | (byte)stream.ReadByte(); } } public void RangeDecoderNormalize(Stream stream) { while ((_low ^ (_low + _range)) < RANGE_TOP || _range < RANGE_BOTTOM && ((_range = (uint)-_low & (RANGE_BOTTOM - 1)) != 0 || true)) { _code = (_code << 8) | (byte)stream.ReadByte(); _range <<= 8; _low <<= 8; } } public uint RangeGetCurrentCount() { return (_code - _low) / (_range /= _scale); } public uint RangeGetCurrentShiftCount(int rangeShift) { return (_code - _low) / (_range >>= rangeShift); } public void RangeRemoveSubrange() { _low += _range * _lowCount; _range *= _highCount - _lowCount; } } }