Add interface to not dispose data (for NSP, NCA, XCI, etc)

This commit is contained in:
KillzXGaming 2019-07-31 19:33:45 -04:00
parent 116d114c77
commit 2df6d35d17
11 changed files with 76 additions and 10 deletions

View file

@ -627,6 +627,8 @@ namespace Bfres.Structs
case TEX_FORMAT.R32G32B32A32_FLOAT: return GX2SurfaceFormat.TC_R32_G32_B32_A32_Float; 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_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.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: default:
throw new Exception($"Cannot convert format {texFormat}"); throw new Exception($"Cannot convert format {texFormat}");
} }

View file

@ -9,7 +9,7 @@ using LibHac;
namespace FirstPlugin namespace FirstPlugin
{ {
public class IStorage : IArchiveFile, IFileFormat public class IStorage : IArchiveFile, IFileFormat, IFileDisposeAfterLoad
{ {
public FileType FileType { get; set; } = FileType.Rom; public FileType FileType { get; set; } = FileType.Rom;
@ -34,6 +34,8 @@ namespace FirstPlugin
public bool CanReplaceFiles { get; set; } public bool CanReplaceFiles { get; set; }
public bool CanDeleteFiles { get; set; } public bool CanDeleteFiles { get; set; }
public bool CanDispose { get { return false; } }
public List<NSP.FileEntry> files = new List<NSP.FileEntry>(); public List<NSP.FileEntry> files = new List<NSP.FileEntry>();
public IEnumerable<ArchiveFileInfo> Files => files; public IEnumerable<ArchiveFileInfo> Files => files;

View file

@ -9,7 +9,7 @@ using LibHac.IO;
namespace FirstPlugin namespace FirstPlugin
{ {
public class NCA : IFileFormat, IArchiveFile public class NCA : IFileFormat, IArchiveFile, IFileDisposeAfterLoad
{ {
public FileType FileType { get; set; } = FileType.Rom; public FileType FileType { get; set; } = FileType.Rom;
@ -34,6 +34,8 @@ namespace FirstPlugin
public bool CanReplaceFiles { get; set; } public bool CanReplaceFiles { get; set; }
public bool CanDeleteFiles { get; set; } public bool CanDeleteFiles { get; set; }
public bool CanDispose { get { return false; } }
public List<NSP.FileEntry> files = new List<NSP.FileEntry>(); public List<NSP.FileEntry> files = new List<NSP.FileEntry>();
public IEnumerable<ArchiveFileInfo> Files => files; public IEnumerable<ArchiveFileInfo> Files => files;

View file

@ -16,7 +16,7 @@ using System.ComponentModel;
namespace FirstPlugin namespace FirstPlugin
{ {
public class NSP : IArchiveFile, IFileFormat public class NSP : IArchiveFile, IFileFormat, IFileDisposeAfterLoad
{ {
public FileType FileType { get; set; } = FileType.Rom; public FileType FileType { get; set; } = FileType.Rom;
@ -39,6 +39,8 @@ namespace FirstPlugin
Nca Control { get; set; } Nca Control { get; set; }
RomfsNodeWrapper romfsWrapper; RomfsNodeWrapper romfsWrapper;
public bool CanDispose { get { return false; } }
public bool CanAddFiles { get; set; } public bool CanAddFiles { get; set; }
public bool CanRenameFiles { get; set; } public bool CanRenameFiles { get; set; }
public bool CanReplaceFiles { get; set; } public bool CanReplaceFiles { get; set; }
@ -121,12 +123,9 @@ namespace FirstPlugin
{ {
get get
{ {
using (var stream = ParentROMFS.OpenFile(File).AsStream()) var mem = new MemoryStream();
{ ParentROMFS.OpenFile(File).CopyToStream(mem);
var mem = new MemoryStream(); return mem.ToArray();
stream.CopyTo(mem);
return mem.ToArray();
}
} }
} }

View file

@ -7,7 +7,7 @@ using Toolbox.Library;
namespace FirstPlugin namespace FirstPlugin
{ {
public class XCI : IFileFormat public class XCI : IFileFormat, IFileDisposeAfterLoad
{ {
public FileType FileType { get; set; } = FileType.Rom; public FileType FileType { get; set; } = FileType.Rom;
@ -32,6 +32,8 @@ namespace FirstPlugin
return Utils.HasExtension(FileName, ".xci"); return Utils.HasExtension(FileName, ".xci");
} }
public bool CanDispose { get { return false; } }
public void Load(System.IO.Stream stream) public void Load(System.IO.Stream stream)
{ {
} }

View file

@ -416,6 +416,9 @@ namespace Toolbox.Library
case TEX_FORMAT.ETC1_A4: case TEX_FORMAT.ETC1_A4:
return BitmapExtension.GetBitmap(ETC1.ETC1Decompress(data, (int)width, (int)height, true), return BitmapExtension.GetBitmap(ETC1.ETC1Decompress(data, (int)width, (int)height, true),
(int)width, (int)height, System.Drawing.Imaging.PixelFormat.Format32bppArgb); (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); 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) private Bitmap DecodeNotDirectXTex(byte[] data, uint Width, uint Height, TEX_FORMAT Format)
{ {
if (Format == TEX_FORMAT.R8G8B8A8_UNORM) if (Format == TEX_FORMAT.R8G8B8A8_UNORM)

View file

@ -361,6 +361,10 @@ namespace Toolbox.Library.IO
} }
//After file has been loaded and read, we'll dispose unless left open //After file has been loaded and read, we'll dispose unless left open
if (fileFormat is IFileDisposeAfterLoad) {
LeaveStreamOpen = !((IFileDisposeAfterLoad)fileFormat).CanDispose;
}
if (!LeaveStreamOpen) if (!LeaveStreamOpen)
{ {
stream.Dispose(); stream.Dispose();

View file

@ -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; }
}
}

View file

@ -245,6 +245,7 @@
</Compile> </Compile>
<Compile Include="Generics\Texture\ImageParameters.cs" /> <Compile Include="Generics\Texture\ImageParameters.cs" />
<Compile Include="Generics\Texture\STTextureFolder.cs" /> <Compile Include="Generics\Texture\STTextureFolder.cs" />
<Compile Include="Interfaces\ICanDispose.cs" />
<Compile Include="Interfaces\ICloneableNode.cs" /> <Compile Include="Interfaces\ICloneableNode.cs" />
<Compile Include="Interfaces\IMeshContainer.cs" /> <Compile Include="Interfaces\IMeshContainer.cs" />
<Compile Include="Interfaces\ITextureContainer.cs" /> <Compile Include="Interfaces\ITextureContainer.cs" />