| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 |
- using System.IO;
- namespace Ryujinx.Graphics.VDec
- {
- class VpxRangeEncoder
- {
- private const int HalfProbability = 128;
- private static readonly int[] NormLut = new int[]
- {
- 0, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- };
- private Stream BaseStream;
- private uint LowValue;
- private uint Range;
- private int Count;
- public VpxRangeEncoder(Stream BaseStream)
- {
- this.BaseStream = BaseStream;
- Range = 0xff;
- Count = -24;
- Write(false);
- }
- public void WriteByte(byte Value)
- {
- Write(Value, 8);
- }
- public void Write(int Value, int ValueSize)
- {
- for (int Bit = ValueSize - 1; Bit >= 0; Bit--)
- {
- Write(((Value >> Bit) & 1) != 0);
- }
- }
- public void Write(bool Bit)
- {
- Write(Bit, HalfProbability);
- }
- public void Write(bool Bit, int Probability)
- {
- uint Range = this.Range;
- uint Split = 1 + (((Range - 1) * (uint)Probability) >> 8);
- Range = Split;
- if (Bit)
- {
- LowValue += Split;
- Range = this.Range - Split;
- }
- int Shift = NormLut[Range];
- Range <<= Shift;
- Count += Shift;
- if (Count >= 0)
- {
- int Offset = Shift - Count;
- if (((LowValue << (Offset - 1)) >> 31) != 0)
- {
- long CurrentPos = BaseStream.Position;
- BaseStream.Seek(-1, SeekOrigin.Current);
- while (BaseStream.Position >= 0 && PeekByte() == 0xff)
- {
- BaseStream.WriteByte(0);
- BaseStream.Seek(-2, SeekOrigin.Current);
- }
- BaseStream.WriteByte((byte)(PeekByte() + 1));
- BaseStream.Seek(CurrentPos, SeekOrigin.Begin);
- }
- BaseStream.WriteByte((byte)(LowValue >> (24 - Offset)));
- LowValue <<= Offset;
- Shift = Count;
- LowValue &= 0xffffff;
- Count -= 8;
- }
- LowValue <<= Shift;
- this.Range = Range;
- }
- private byte PeekByte()
- {
- byte Value = (byte)BaseStream.ReadByte();
- BaseStream.Seek(-1, SeekOrigin.Current);
- return Value;
- }
- public void End()
- {
- for (int Index = 0; Index < 32; Index++)
- {
- Write(false);
- }
- }
- }
- }
|