using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; namespace Ryujinx.Graphics.Texture.Astc { [StructLayout(LayoutKind.Sequential)] struct AstcPixel { internal const int StructSize = 12; public short A; public short R; public short G; public short B; private uint _bitDepthInt; private Span<byte> BitDepth => MemoryMarshal.CreateSpan(ref Unsafe.As<uint, byte>(ref _bitDepthInt), 4); private Span<short> Components => MemoryMarshal.CreateSpan(ref A, 4); public AstcPixel(short a, short r, short g, short b) { A = a; R = r; G = g; B = b; _bitDepthInt = 0x08080808; } public void ClampByte() { R = Math.Min(Math.Max(R, (short)0), (short)255); G = Math.Min(Math.Max(G, (short)0), (short)255); B = Math.Min(Math.Max(B, (short)0), (short)255); A = Math.Min(Math.Max(A, (short)0), (short)255); } public short GetComponent(int index) { return Components[index]; } public void SetComponent(int index, int value) { Components[index] = (short)value; } public int Pack() { return A << 24 | B << 16 | G << 8 | R << 0; } // Adds more precision to the blue channel as described // in C.2.14 public static AstcPixel BlueContract(int a, int r, int g, int b) { return new AstcPixel((short)(a), (short)((r + b) >> 1), (short)((g + b) >> 1), (short)(b)); } } }