diff --git a/File_Format_Library/FileFormats/BFRES/Bfres Structs/SubFiles/FTEX.cs b/File_Format_Library/FileFormats/BFRES/Bfres Structs/SubFiles/FTEX.cs index 2f5314da..4828bb61 100644 --- a/File_Format_Library/FileFormats/BFRES/Bfres Structs/SubFiles/FTEX.cs +++ b/File_Format_Library/FileFormats/BFRES/Bfres Structs/SubFiles/FTEX.cs @@ -627,6 +627,8 @@ namespace Bfres.Structs case TEX_FORMAT.R32G32B32A32_FLOAT: return GX2SurfaceFormat.TC_R32_G32_B32_A32_Float; case TEX_FORMAT.R32G32B32A32_UINT: return GX2SurfaceFormat.TC_R32_G32_B32_A32_UInt; case TEX_FORMAT.R32G32B32A32_SINT: return GX2SurfaceFormat.TC_R32_G32_B32_A32_SInt; + case TEX_FORMAT.L8: return GX2SurfaceFormat.TC_R8_UNorm; + case TEX_FORMAT.LA8: return GX2SurfaceFormat.TC_R8_G8_UNorm; default: throw new Exception($"Cannot convert format {texFormat}"); } diff --git a/File_Format_Library/FileFormats/Rom/IStorage.cs b/File_Format_Library/FileFormats/Rom/IStorage.cs index b3706c18..e0ac1178 100644 --- a/File_Format_Library/FileFormats/Rom/IStorage.cs +++ b/File_Format_Library/FileFormats/Rom/IStorage.cs @@ -9,7 +9,7 @@ using LibHac; namespace FirstPlugin { - public class IStorage : IArchiveFile, IFileFormat + public class IStorage : IArchiveFile, IFileFormat, IFileDisposeAfterLoad { public FileType FileType { get; set; } = FileType.Rom; @@ -34,6 +34,8 @@ namespace FirstPlugin public bool CanReplaceFiles { get; set; } public bool CanDeleteFiles { get; set; } + public bool CanDispose { get { return false; } } + public List files = new List(); public IEnumerable Files => files; diff --git a/File_Format_Library/FileFormats/Rom/NCA.cs b/File_Format_Library/FileFormats/Rom/NCA.cs index 86cd201a..807eaf90 100644 --- a/File_Format_Library/FileFormats/Rom/NCA.cs +++ b/File_Format_Library/FileFormats/Rom/NCA.cs @@ -9,7 +9,7 @@ using LibHac.IO; namespace FirstPlugin { - public class NCA : IFileFormat, IArchiveFile + public class NCA : IFileFormat, IArchiveFile, IFileDisposeAfterLoad { public FileType FileType { get; set; } = FileType.Rom; @@ -34,6 +34,8 @@ namespace FirstPlugin public bool CanReplaceFiles { get; set; } public bool CanDeleteFiles { get; set; } + public bool CanDispose { get { return false; } } + public List files = new List(); public IEnumerable Files => files; diff --git a/File_Format_Library/FileFormats/Rom/NSP.cs b/File_Format_Library/FileFormats/Rom/NSP.cs index babf0f78..77b02773 100644 --- a/File_Format_Library/FileFormats/Rom/NSP.cs +++ b/File_Format_Library/FileFormats/Rom/NSP.cs @@ -16,7 +16,7 @@ using System.ComponentModel; namespace FirstPlugin { - public class NSP : IArchiveFile, IFileFormat + public class NSP : IArchiveFile, IFileFormat, IFileDisposeAfterLoad { public FileType FileType { get; set; } = FileType.Rom; @@ -39,6 +39,8 @@ namespace FirstPlugin Nca Control { get; set; } RomfsNodeWrapper romfsWrapper; + public bool CanDispose { get { return false; } } + public bool CanAddFiles { get; set; } public bool CanRenameFiles { get; set; } public bool CanReplaceFiles { get; set; } @@ -121,12 +123,9 @@ namespace FirstPlugin { get { - using (var stream = ParentROMFS.OpenFile(File).AsStream()) - { - var mem = new MemoryStream(); - stream.CopyTo(mem); - return mem.ToArray(); - } + var mem = new MemoryStream(); + ParentROMFS.OpenFile(File).CopyToStream(mem); + return mem.ToArray(); } } diff --git a/File_Format_Library/FileFormats/Rom/XCI.cs b/File_Format_Library/FileFormats/Rom/XCI.cs index fdda194f..694848c8 100644 --- a/File_Format_Library/FileFormats/Rom/XCI.cs +++ b/File_Format_Library/FileFormats/Rom/XCI.cs @@ -7,7 +7,7 @@ using Toolbox.Library; namespace FirstPlugin { - public class XCI : IFileFormat + public class XCI : IFileFormat, IFileDisposeAfterLoad { public FileType FileType { get; set; } = FileType.Rom; @@ -32,6 +32,8 @@ namespace FirstPlugin return Utils.HasExtension(FileName, ".xci"); } + public bool CanDispose { get { return false; } } + public void Load(System.IO.Stream stream) { } diff --git a/Switch_Toolbox_Library/Generics/Texture/GenericTexture.cs b/Switch_Toolbox_Library/Generics/Texture/GenericTexture.cs index a5de5824..eae15909 100644 --- a/Switch_Toolbox_Library/Generics/Texture/GenericTexture.cs +++ b/Switch_Toolbox_Library/Generics/Texture/GenericTexture.cs @@ -416,6 +416,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.LA8: + return BitmapExtension.GetBitmap(DecodeLA8(data, (int)width, (int)height), + (int)width, (int)height, System.Drawing.Imaging.PixelFormat.Format32bppArgb); } Console.WriteLine("Decoding " + Format + " " + Runtime.UseDirectXTexDecoder); @@ -446,6 +449,43 @@ namespace Toolbox.Library } } + private static byte[] DecodeLA8(byte[] Input, int Width, int Height) + { + int bpp = 16; + + if (Input.Length != Width * Height * bpp) + throw new Exception($"Unexpected size! {Input.Length}. Expected {Width * Height * bpp}"); + + byte[] Output = new byte[Width * Height * 4]; + + int inPos = 0; + int outPos = 0; + + for (int Y = 0; Y < Height; Y++) + { + for (int X = 0; X < Width; X++) + { + inPos = (Y * Width + X) * bpp; + outPos = (Y * Width + X) * 4; + + int pixel = 0; + for (int i = 0; i < bpp; i++) + pixel |= Input[inPos + i] << (8 * i); + + byte[] Components = new byte[4]; + Components[2] = (byte)(pixel & 0xFF); + Components[3] = (byte)((pixel & 0xFF00) >> 8); + + Output[outPos + 3] = Components[3]; + Output[outPos + 2] = Components[2]; + Output[outPos + 1] = Components[1]; + Output[outPos + 0] = Components[0]; + } + } + + return Output; + } + private Bitmap DecodeNotDirectXTex(byte[] data, uint Width, uint Height, TEX_FORMAT Format) { if (Format == TEX_FORMAT.R8G8B8A8_UNORM) diff --git a/Switch_Toolbox_Library/IO/STFileLoader.cs b/Switch_Toolbox_Library/IO/STFileLoader.cs index 5a4be11c..f57c3859 100644 --- a/Switch_Toolbox_Library/IO/STFileLoader.cs +++ b/Switch_Toolbox_Library/IO/STFileLoader.cs @@ -361,6 +361,10 @@ namespace Toolbox.Library.IO } //After file has been loaded and read, we'll dispose unless left open + if (fileFormat is IFileDisposeAfterLoad) { + LeaveStreamOpen = !((IFileDisposeAfterLoad)fileFormat).CanDispose; + } + if (!LeaveStreamOpen) { stream.Dispose(); diff --git a/Switch_Toolbox_Library/Interfaces/ICanDispose.cs b/Switch_Toolbox_Library/Interfaces/ICanDispose.cs new file mode 100644 index 00000000..a5f2a8bc --- /dev/null +++ b/Switch_Toolbox_Library/Interfaces/ICanDispose.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Toolbox.Library +{ + //Check if the opened file stream should be disposed after loading + public interface IFileDisposeAfterLoad + { + bool CanDispose { get; } + } +} diff --git a/Switch_Toolbox_Library/Toolbox.Library.dll b/Switch_Toolbox_Library/Toolbox.Library.dll index 916da8eb..2c9f6bae 100644 Binary files a/Switch_Toolbox_Library/Toolbox.Library.dll and b/Switch_Toolbox_Library/Toolbox.Library.dll differ diff --git a/Switch_Toolbox_Library/Toolbox.Library.pdb b/Switch_Toolbox_Library/Toolbox.Library.pdb index 140caec3..7549aa1c 100644 Binary files a/Switch_Toolbox_Library/Toolbox.Library.pdb and b/Switch_Toolbox_Library/Toolbox.Library.pdb differ diff --git a/Switch_Toolbox_Library/Toolbox_Library.csproj b/Switch_Toolbox_Library/Toolbox_Library.csproj index 545e41ee..2fff02d8 100644 --- a/Switch_Toolbox_Library/Toolbox_Library.csproj +++ b/Switch_Toolbox_Library/Toolbox_Library.csproj @@ -245,6 +245,7 @@ +