aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Texture/Astc/AstcPixel.cs
diff options
context:
space:
mode:
authorgdk <gab.dark.100@gmail.com>2019-10-13 03:02:07 -0300
committerThog <thog@protonmail.com>2020-01-09 02:13:00 +0100
commit1876b346fea647e8284a66bb6d62c38801035cff (patch)
tree6eeff094298cda84d1613dc5ec0691e51d7b35f1 /Ryujinx.Graphics.Texture/Astc/AstcPixel.cs
parentf617fb542a0e3d36012d77a4b5acbde7b08902f2 (diff)
Initial work
Diffstat (limited to 'Ryujinx.Graphics.Texture/Astc/AstcPixel.cs')
-rw-r--r--Ryujinx.Graphics.Texture/Astc/AstcPixel.cs138
1 files changed, 138 insertions, 0 deletions
diff --git a/Ryujinx.Graphics.Texture/Astc/AstcPixel.cs b/Ryujinx.Graphics.Texture/Astc/AstcPixel.cs
new file mode 100644
index 00000000..7d127878
--- /dev/null
+++ b/Ryujinx.Graphics.Texture/Astc/AstcPixel.cs
@@ -0,0 +1,138 @@
+using System;
+using System.Diagnostics;
+
+namespace Ryujinx.Graphics.Texture.Astc
+{
+ class AstcPixel
+ {
+ public short R { get; set; }
+ public short G { get; set; }
+ public short B { get; set; }
+ public short A { get; set; }
+
+ byte[] _bitDepth = new byte[4];
+
+ public AstcPixel(short a, short r, short g, short b)
+ {
+ A = a;
+ R = r;
+ G = g;
+ B = b;
+
+ for (int i = 0; i < 4; i++)
+ _bitDepth[i] = 8;
+ }
+
+ 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)
+ {
+ switch(index)
+ {
+ case 0: return A;
+ case 1: return R;
+ case 2: return G;
+ case 3: return B;
+ }
+
+ return 0;
+ }
+
+ public void SetComponent(int index, int value)
+ {
+ switch (index)
+ {
+ case 0:
+ A = (short)value;
+ break;
+ case 1:
+ R = (short)value;
+ break;
+ case 2:
+ G = (short)value;
+ break;
+ case 3:
+ B = (short)value;
+ break;
+ }
+ }
+
+ public void ChangeBitDepth(byte[] depth)
+ {
+ for (int i = 0; i< 4; i++)
+ {
+ int value = ChangeBitDepth(GetComponent(i), _bitDepth[i], depth[i]);
+
+ SetComponent(i, value);
+ _bitDepth[i] = depth[i];
+ }
+ }
+
+ short ChangeBitDepth(short value, byte oldDepth, byte newDepth)
+ {
+ Debug.Assert(newDepth <= 8);
+ Debug.Assert(oldDepth <= 8);
+
+ if (oldDepth == newDepth)
+ {
+ // Do nothing
+ return value;
+ }
+ else if (oldDepth == 0 && newDepth != 0)
+ {
+ return (short)((1 << newDepth) - 1);
+ }
+ else if (newDepth > oldDepth)
+ {
+ return (short)BitArrayStream.Replicate(value, oldDepth, newDepth);
+ }
+ else
+ {
+ // oldDepth > newDepth
+ if (newDepth == 0)
+ {
+ return 0xFF;
+ }
+ else
+ {
+ byte bitsWasted = (byte)(oldDepth - newDepth);
+ short tempValue = value;
+
+ tempValue = (short)((tempValue + (1 << (bitsWasted - 1))) >> bitsWasted);
+ tempValue = Math.Min(Math.Max((short)0, tempValue), (short)((1 << newDepth) - 1));
+
+ return (byte)(tempValue);
+ }
+ }
+ }
+
+ public int Pack()
+ {
+ AstcPixel newPixel = new AstcPixel(A, R, G, B);
+ byte[] eightBitDepth = { 8, 8, 8, 8 };
+
+ newPixel.ChangeBitDepth(eightBitDepth);
+
+ return (byte)newPixel.A << 24 |
+ (byte)newPixel.B << 16 |
+ (byte)newPixel.G << 8 |
+ (byte)newPixel.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));
+ }
+ }
+}