/ src / Ryujinx.Graphics.Texture / Astc / BitStream128.cs
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  }