mirror of
https://github.com/Gericom/FastVideoDSEncoder.git
synced 2025-06-18 10:45:33 -04:00
69 lines
2.0 KiB
C#
69 lines
2.0 KiB
C#
using System;
|
|
using System.Buffers.Binary;
|
|
using System.Numerics;
|
|
|
|
namespace Gericom.FastVideoDS.Bitstream
|
|
{
|
|
public class BitReader
|
|
{
|
|
private readonly byte[] _data;
|
|
private int _offset;
|
|
public int BitsRemaining;
|
|
public uint Bits;
|
|
|
|
public BitReader(byte[] data)
|
|
{
|
|
_data = data;
|
|
Bits = (uint)(BinaryPrimitives.ReadUInt16LittleEndian(data) << 16);
|
|
BitsRemaining = 0;
|
|
_offset = 2;
|
|
}
|
|
|
|
public uint ReadUnsignedVarInt()
|
|
{
|
|
int clz = BitOperations.LeadingZeroCount(Bits); //nr zeros
|
|
Bits <<= clz; //remove the zeros
|
|
Bits += Bits; //remove the stop bit
|
|
int r9 = 32 - clz; //shift amount
|
|
uint r6 = r9 == 32 ? 0 : Bits >> r9;
|
|
r9 = 1;
|
|
r6 += (uint)(r9 << clz);
|
|
r6--;
|
|
Bits <<= clz;
|
|
BitsRemaining -= clz << 1;
|
|
if (--BitsRemaining < 0)
|
|
FillBits();
|
|
return r6;
|
|
}
|
|
|
|
public void FillBits()
|
|
{
|
|
if (_offset >= _data.Length)
|
|
return;
|
|
uint r10 = BinaryPrimitives.ReadUInt16LittleEndian(_data.AsSpan(_offset));
|
|
_offset += 2;
|
|
BitsRemaining += 0x10;
|
|
int r9 = 0x10 - BitsRemaining;
|
|
Bits |= r10 << r9;
|
|
}
|
|
|
|
private int ReadSignedVarInt()
|
|
{
|
|
int clz = BitOperations.LeadingZeroCount(Bits);
|
|
Bits <<= clz;
|
|
Bits += Bits;
|
|
int r9 = 32 - clz;
|
|
int r6 = r9 == 32 ? 0 : (int)(Bits >> r9);
|
|
r9 = 1;
|
|
r6 += r9 << clz;
|
|
if ((r6 & 1) != 0)
|
|
r6 = 1 - r6;
|
|
r6 >>= 1;
|
|
Bits <<= clz;
|
|
BitsRemaining -= clz << 1;
|
|
if (--BitsRemaining < 0)
|
|
FillBits();
|
|
return r6;
|
|
}
|
|
}
|
|
} |