123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- #region Using
- using System.IO;
- #endregion
- namespace SharpCompress.Compressors.PPMd.I1
- {
- /// <summary>
- /// A simple range coder.
- /// </summary>
- /// <remarks>
- /// Note that in most cases fields are used rather than properties for performance reasons (for example,
- /// <see cref="_scale"/> is a field rather than a property).
- /// </remarks>
- 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;
- }
- }
- }
|