From 8acf9e78311b7ca7159ea53925504c699bd7da25 Mon Sep 17 00:00:00 2001 From: KillzXGaming Date: Mon, 25 Nov 2019 17:18:15 -0500 Subject: [PATCH] Fix RGB5A1 texture decoding and some chanel issues on others --- .../FileFormats/Texture/BNTX.cs | 3 +- .../FileFormats/DDS/RGBAPixelDecoder.cs | 41 ++++++++++++++++--- Switch_Toolbox_Library/Generics/TEX_FORMAT.cs | 3 +- .../Generics/Texture/GenericTexture.cs | 19 +++++---- Toolbox/GUI/HashCalculatorForm.cs | 2 +- 5 files changed, 52 insertions(+), 16 deletions(-) diff --git a/File_Format_Library/FileFormats/Texture/BNTX.cs b/File_Format_Library/FileFormats/Texture/BNTX.cs index f2a36b37..01e54b29 100644 --- a/File_Format_Library/FileFormats/Texture/BNTX.cs +++ b/File_Format_Library/FileFormats/Texture/BNTX.cs @@ -1236,6 +1236,7 @@ namespace FirstPlugin case TEX_FORMAT.BC6H_SF16: return SurfaceFormat.BC6_UFLOAT; case TEX_FORMAT.BC7_UNORM: return SurfaceFormat.BC7_UNORM; case TEX_FORMAT.BC7_UNORM_SRGB: return SurfaceFormat.BC7_SRGB; + case TEX_FORMAT.R5G5B5A1_UNORM: return SurfaceFormat.R5_G5_B5_A1_UNORM; case TEX_FORMAT.B5G5R5A1_UNORM: return SurfaceFormat.B5_G5_R5_A1_UNORM; case TEX_FORMAT.B5G6R5_UNORM: return SurfaceFormat.B5_G6_R5_UNORM; case TEX_FORMAT.B8G8R8A8_UNORM_SRGB: return SurfaceFormat.B8_G8_R8_A8_SRGB; @@ -1317,7 +1318,7 @@ namespace FirstPlugin case SurfaceFormat.R16_UNORM: return TEX_FORMAT.R16_UNORM; case SurfaceFormat.R4_G4_B4_A4_UNORM: return TEX_FORMAT.B4G4R4A4_UNORM; case SurfaceFormat.R4_G4_UNORM: return TEX_FORMAT.B4G4R4A4_UNORM; - case SurfaceFormat.R5_G5_B5_A1_UNORM: return TEX_FORMAT.B5G5R5A1_UNORM; + case SurfaceFormat.R5_G5_B5_A1_UNORM: return TEX_FORMAT.R5G5B5A1_UNORM; case SurfaceFormat.R5_G6_B5_UNORM: return TEX_FORMAT.B5G6R5_UNORM; case SurfaceFormat.R8_G8_B8_A8_SRGB: return TEX_FORMAT.R8G8B8A8_UNORM_SRGB; case SurfaceFormat.R8_G8_B8_A8_UNORM: return TEX_FORMAT.R8G8B8A8_UNORM; diff --git a/Switch_Toolbox_Library/FileFormats/DDS/RGBAPixelDecoder.cs b/Switch_Toolbox_Library/FileFormats/DDS/RGBAPixelDecoder.cs index 66ba14be..45bc0181 100644 --- a/Switch_Toolbox_Library/FileFormats/DDS/RGBAPixelDecoder.cs +++ b/Switch_Toolbox_Library/FileFormats/DDS/RGBAPixelDecoder.cs @@ -23,16 +23,42 @@ namespace Toolbox.Library comp[0] = (byte)((pixel & 0xF) * 17); comp[1] = (byte)(((pixel & 0xF0) >> 4) * 17); break; - case TEX_FORMAT.R5G5B5_UNORM: - comp[0] = (byte)((pixel & 0x1F) / 0x1F * 0xFF); - comp[1] = (byte)(((pixel & 0x7E0) >> 5) / 0x3F * 0xFF); - comp[2] = (byte)(((pixel & 0xF800) >> 11) / 0x1F * 0xFF); - break; case TEX_FORMAT.B5G6R5_UNORM: comp[0] = (byte)(((pixel & 0xF800) >> 11) / 0x1F * 0xFF); comp[1] = (byte)(((pixel & 0x7E0) >> 5) / 0x3F * 0xFF); comp[2] = (byte)((pixel & 0x1F) / 0x1F * 0xFF); break; + case TEX_FORMAT.R5G5B5_UNORM: + { + int R = ((pixel >> 0) & 0x1f) << 3; + int G = ((pixel >> 5) & 0x1f) << 3; + int B = ((pixel >> 10) & 0x1f) << 3; + + comp[0] = (byte)(R | (R >> 5)); + comp[1] = (byte)(G | (G >> 5)); + comp[2] = (byte)(B | (B >> 5)); + } + break; + case TEX_FORMAT.R5G5B5A1_UNORM: + { + int R = ((pixel >> 0) & 0x1f) << 3; + int G = ((pixel >> 5) & 0x1f) << 3; + int B = ((pixel >> 10) & 0x1f) << 3; + int A = ((pixel & 0x8000) >> 15) * 0xFF; + + comp[0] = (byte)(R | (R >> 5)); + comp[1] = (byte)(G | (G >> 5)); + comp[2] = (byte)(B | (B >> 5)); + comp[3] = (byte)A; + } + break; + case TEX_FORMAT.R8G8B8A8_UNORM: + case TEX_FORMAT.R8G8B8A8_UNORM_SRGB: + comp[0] = (byte)(pixel & 0xFF); + comp[1] = (byte)((pixel & 0xFF00) >> 8); + comp[2] = (byte)((pixel & 0xFF0000) >> 16); + comp[3] = (byte)((pixel & 0xFF000000) >> 24); + break; } @@ -62,6 +88,11 @@ namespace Toolbox.Library } else if (format == TEX_FORMAT.L8) compSel = new byte[4] { 0, 0, 0, 5 }; + else if (format == TEX_FORMAT.R5G5B5A1_UNORM) + { + bpp = 2; + return DDSCompressor.DecodePixelBlock(data, (int)width, (int)height, DDS.DXGI_FORMAT.DXGI_FORMAT_B5G5R5A1_UNORM); + } for (int Y = 0; Y < height; Y++) { diff --git a/Switch_Toolbox_Library/Generics/TEX_FORMAT.cs b/Switch_Toolbox_Library/Generics/TEX_FORMAT.cs index bd6d60a9..ab7e9c65 100644 --- a/Switch_Toolbox_Library/Generics/TEX_FORMAT.cs +++ b/Switch_Toolbox_Library/Generics/TEX_FORMAT.cs @@ -189,6 +189,7 @@ namespace Toolbox.Library C14X2 = 248, CMPR = 249, RGB565 = 250, - RGB5A3 = 251 + RGB5A3 = 251, + R5G5B5A1_UNORM = 252, } } diff --git a/Switch_Toolbox_Library/Generics/Texture/GenericTexture.cs b/Switch_Toolbox_Library/Generics/Texture/GenericTexture.cs index 0eeccb83..917cfdcb 100644 --- a/Switch_Toolbox_Library/Generics/Texture/GenericTexture.cs +++ b/Switch_Toolbox_Library/Generics/Texture/GenericTexture.cs @@ -338,6 +338,7 @@ namespace Toolbox.Library { TEX_FORMAT.R8G8_B8G8_UNORM, new FormatInfo(4, 1, 1, 1, TargetBuffer.Color) }, { TEX_FORMAT.B8G8R8X8_UNORM, new FormatInfo(4, 1, 1, 1, TargetBuffer.Color) }, { TEX_FORMAT.B5G5R5A1_UNORM, new FormatInfo(2, 1, 1, 1, TargetBuffer.Color) }, + { TEX_FORMAT.R5G5B5A1_UNORM, new FormatInfo(2, 1, 1, 1, TargetBuffer.Color) }, { TEX_FORMAT.B8G8R8A8_UNORM, new FormatInfo(4, 1, 1, 1, TargetBuffer.Color) }, { TEX_FORMAT.B8G8R8A8_UNORM_SRGB, new FormatInfo(4, 1, 1, 1, TargetBuffer.Color) }, { TEX_FORMAT.R5G5B5_UNORM, new FormatInfo(2, 1, 1, 1, TargetBuffer.Color) }, @@ -510,8 +511,6 @@ namespace Toolbox.Library if (data == null) throw new Exception("Data is null!"); - Console.WriteLine("Decoding " + Format + " " + Runtime.UseDirectXTexDecoder); - if (PlatformSwizzle == PlatformSwizzle.Platform_3DS) { var Image = BitmapExtension.GetBitmap(ConvertBgraToRgba(CTR_3DS.DecodeBlock(data, (int)width, (int)height, Format)), @@ -539,10 +538,9 @@ namespace Toolbox.Library case TEX_FORMAT.ETC1_A4: return BitmapExtension.GetBitmap(ETC1.ETC1Decompress(data, (int)width, (int)height, true), (int)width, (int)height, System.Drawing.Imaging.PixelFormat.Format32bppArgb); - case TEX_FORMAT.L8: - return BitmapExtension.GetBitmap(RGBAPixelDecoder.Decode(data, (int)width, (int)height, Format), - (int)width, (int)height, System.Drawing.Imaging.PixelFormat.Format32bppArgb); + case TEX_FORMAT.R5G5B5A1_UNORM: case TEX_FORMAT.LA8: + case TEX_FORMAT.L8: return BitmapExtension.GetBitmap(RGBAPixelDecoder.Decode(data, (int)width, (int)height, Format), (int)width, (int)height, System.Drawing.Imaging.PixelFormat.Format32bppArgb); } @@ -639,9 +637,6 @@ namespace Toolbox.Library byte[] imageData = new byte[0]; bool DontSwapRG = false; - if (Format.ToString().StartsWith("B") && !IsCompressed(Format)) - DontSwapRG = true; - if (PlatformSwizzle == PlatformSwizzle.Platform_3DS) { imageData = CTR_3DS.DecodeBlock(data, (int)Width, (int)Height, Format); @@ -661,6 +656,8 @@ namespace Toolbox.Library return RGBAPixelDecoder.Decode(data, (int)Width, (int)Height, Format); if (Format == TEX_FORMAT.LA8) return RGBAPixelDecoder.Decode(data, (int)Width, (int)Height, Format); + if (Format == TEX_FORMAT.R5G5B5A1_UNORM) + return RGBAPixelDecoder.Decode(data, (int)Width, (int)Height, Format); if (IsCompressed(Format)) imageData = DDSCompressor.DecompressBlock(data, (int)Width, (int)Height, (DDS.DXGI_FORMAT)Format); @@ -754,6 +751,12 @@ namespace Toolbox.Library if (!Runtime.UseDirectXTexDecoder) return data; + //Channels will be swapped + if (format == TEX_FORMAT.R5G5B5A1_UNORM) { + format = TEX_FORMAT.B5G5R5A1_UNORM; + data = ConvertBgraToRgba(data); + } + if (IsCompressed(format)) return DDSCompressor.CompressBlock(data, width, height, (DDS.DXGI_FORMAT)format, multiThread, alphaRef, CompressionMode); else if (IsAtscFormat(format)) diff --git a/Toolbox/GUI/HashCalculatorForm.cs b/Toolbox/GUI/HashCalculatorForm.cs index ea1c9028..623d2c03 100644 --- a/Toolbox/GUI/HashCalculatorForm.cs +++ b/Toolbox/GUI/HashCalculatorForm.cs @@ -51,7 +51,7 @@ namespace Toolbox if (type == "NLG_Hash") return StringToHash(text); else if (type == "FNV64A1") - return FNV64A1.CalculateSuffix(text); + return FNV64A1.Calculate(text); else if (type == "CRC32") return Toolbox.Library.Security.Cryptography.Crc32.Compute(text); return 0;