#region Using using System; using System.IO; #endregion namespace SharpCompress.Compressor.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 RangeTop = 1 << 24; private const uint RangeBottom = 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)) < RangeTop || range < RangeBottom && ((range = (uint) -low & (RangeBottom - 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)) < RangeTop || range < RangeBottom && ((range = (uint) -low & (RangeBottom - 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; } } }