From 4e037d8ddc65185eaae8ce6fb0b7dceb076c8fd3 Mon Sep 17 00:00:00 2001 From: Jeremy Pritts Date: Tue, 5 Jul 2022 21:52:16 -0400 Subject: [PATCH] use span more in atc decoder --- TextureDecoder/Atc/AtcDecoder.cs | 41 +++++++++++++++++++------------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/TextureDecoder/Atc/AtcDecoder.cs b/TextureDecoder/Atc/AtcDecoder.cs index 2aa36f5..d3bdfdf 100644 --- a/TextureDecoder/Atc/AtcDecoder.cs +++ b/TextureDecoder/Atc/AtcDecoder.cs @@ -1,4 +1,5 @@ using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; namespace AssetRipper.TextureDecoder.Atc { @@ -32,7 +33,7 @@ namespace AssetRipper.TextureDecoder.Atc { for (int s = 0; s < bcw; s++, inputOffset += 8) { - DecodeAtcRgb4Block(input + inputOffset, buf); + DecodeAtcRgb4Block(new ReadOnlySpan(input + inputOffset, 8), new Span(buf, 16)); int clen = s < bcw - 1 ? 4 : clen_last; uint* outputPtr = (uint*)(output + (t * 16 * width + s * 16)); uint* bufPtr = buf; @@ -79,7 +80,7 @@ namespace AssetRipper.TextureDecoder.Atc { for (int s = 0; s < bcw; s++, inputOffset += 16) { - DecodeAtcRgba8Block(input + inputOffset, buf); + DecodeAtcRgba8Block(new ReadOnlySpan(input + inputOffset, 16), new Span(buf, 16)); int clen = s < bcw - 1 ? 4 : clen_last; uint* outputPtr = (uint*)(output + (t * 16 * width + s * 16)); uint* bufPtr = buf; @@ -98,18 +99,18 @@ namespace AssetRipper.TextureDecoder.Atc return inputOffset; } - private unsafe static void DecodeAtcRgb4Block(byte* input, uint* output) + private unsafe static void DecodeAtcRgb4Block(ReadOnlySpan input, Span output) { - int* colors = stackalloc int[16]; - int c0 = *((ushort*)(input + 0)); - int c1 = *((ushort*)(input + 2)); - uint cindex = *((uint*)(input + 4)); + Span colors = stackalloc int[16]; + int c0 = input.ReadAtOffset(0); + int c1 = input.ReadAtOffset(2); + uint cindex = input.ReadAtOffset(4); DecodeColors(colors, c0, c1); for (int i = 0; i < 4 * 4; i++) { - uint cidx = cindex & 3; + int cidx = unchecked((int)(cindex & 3)); int cb = colors[cidx * 4 + 0]; int cg = colors[cidx * 4 + 1]; int cr = colors[cidx * 4 + 2]; @@ -118,18 +119,18 @@ namespace AssetRipper.TextureDecoder.Atc } } - private unsafe static void DecodeAtcRgba8Block(byte* input, uint* output) + private unsafe static void DecodeAtcRgba8Block(ReadOnlySpan input, Span output) { - int* alphas = stackalloc int[16]; - ulong avalue = *((ulong*)input); + Span alphas = stackalloc int[16]; + ulong avalue = input.ReadAtOffset(0); int a0 = unchecked((int)(avalue >> 0) & 0xFF); int a1 = unchecked((int)(avalue >> 8) & 0xFF); ulong aindex = avalue >> 16; - int* colors = stackalloc int[16]; - int c0 = *((ushort*)(input + 8)); - int c1 = *((ushort*)(input + 10)); - uint cindex = *((uint*)(input + 12)); + Span colors = stackalloc int[16]; + int c0 = input.ReadAtOffset(8); + int c1 = input.ReadAtOffset(10); + uint cindex = input.ReadAtOffset(12); DecodeColors(colors, c0, c1); DecodeAlphas(alphas, a0, a1); @@ -149,7 +150,13 @@ namespace AssetRipper.TextureDecoder.Atc } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private unsafe static void DecodeColors(int* colors, int c0, int c1) + private static T ReadAtOffset(this ReadOnlySpan input, int offset) where T : unmanaged + { + return MemoryMarshal.Read(input.Slice(offset)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private unsafe static void DecodeColors(Span colors, int c0, int c1) { if ((c0 & 0x8000) == 0) { @@ -190,7 +197,7 @@ namespace AssetRipper.TextureDecoder.Atc } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private unsafe static void DecodeAlphas(int* alphas, int a0, int a1) + private unsafe static void DecodeAlphas(Span alphas, int a0, int a1) { alphas[0] = a0; alphas[1] = a1;