BitStream128.cs
1 using Ryujinx.Common.Utilities; 2 using System; 3 using System.Diagnostics; 4 5 namespace Ryujinx.Graphics.Texture.Astc 6 { 7 public struct BitStream128 8 { 9 #pragma warning disable IDE0044 // Make field readonly 10 private Buffer16 _data; 11 #pragma warning restore IDE0044 12 public int BitsLeft { get; set; } 13 14 public BitStream128(Buffer16 data) 15 { 16 _data = data; 17 BitsLeft = 128; 18 } 19 20 public int ReadBits(int bitCount) 21 { 22 Debug.Assert(bitCount < 32); 23 24 if (bitCount == 0) 25 { 26 return 0; 27 } 28 29 int mask = (1 << bitCount) - 1; 30 int value = _data.As<int>() & mask; 31 32 Span<ulong> span = _data.AsSpan<ulong>(); 33 34 ulong carry = span[1] << (64 - bitCount); 35 span[0] = (span[0] >> bitCount) | carry; 36 span[1] >>= bitCount; 37 38 BitsLeft -= bitCount; 39 40 return value; 41 } 42 43 public void WriteBits(int value, int bitCount) 44 { 45 Debug.Assert(bitCount < 32); 46 47 if (bitCount == 0) 48 { 49 return; 50 } 51 52 ulong maskedValue = (uint)(value & ((1 << bitCount) - 1)); 53 54 Span<ulong> span = _data.AsSpan<ulong>(); 55 56 if (BitsLeft < 64) 57 { 58 ulong lowMask = maskedValue << BitsLeft; 59 span[0] |= lowMask; 60 } 61 62 if (BitsLeft + bitCount > 64) 63 { 64 if (BitsLeft > 64) 65 { 66 span[1] |= maskedValue << (BitsLeft - 64); 67 } 68 else 69 { 70 span[1] |= maskedValue >> (64 - BitsLeft); 71 } 72 } 73 74 BitsLeft += bitCount; 75 } 76 } 77 }