More improvements.

Rewrote the compression handling from scatch. It's way easier and cleaner to add new formats code wise as it's handled like file formats.
Added wip TVOL support (Touhou Azure Reflections)
Added XCI support. Note I plan to improve NSP, XCI, NCA, etc later for exefs exporting.
The compression rework now compresses via streams, so files get decompressed properly within archives as streams.
Added hyrule warriors bin.gz compression along with archive rebuilding. Note i do not have texture rebuilding done just yet.
This commit is contained in:
KillzXGaming 2019-09-15 19:13:01 -04:00
parent 4d72a725c5
commit 0c126e4155
62 changed files with 1495 additions and 971 deletions

View file

@ -258,7 +258,7 @@ namespace FirstPlugin
{
if (entry.IsCompressed)
{
return STLibraryCompression.ZSTD.Decompress(entry.CompressedData);
return Zstb.SDecompress(entry.CompressedData);
}
else
return entry.CompressedData;
@ -266,7 +266,7 @@ namespace FirstPlugin
public static void SetASST(FileEntry fileEntry, byte[] data)
{
if (fileEntry.IsCompressed)
fileEntry.CompressedData = STLibraryCompression.ZSTD.Compress(data);
fileEntry.CompressedData = Zstb.SCompress(data);
else
fileEntry.CompressedData = data;
}

View file

@ -118,7 +118,7 @@ namespace FirstPlugin
get
{
if (compressedSize != fileSize)
return new MemoryStream(STLibraryCompression.ZSTD.Decompress(stream.ToBytes()));
return new MemoryStream(Zstb.SDecompress(stream.ToBytes()));
else
return stream;
}

View file

@ -115,19 +115,21 @@ namespace FirstPlugin
else if (compType == 0x30 || compType == 0x20)
{
uint decompSize = reader.ReadUInt32();
uint compSize = (uint)reader.BaseStream.Length - 14;
uint compSize = (uint)reader.BaseStream.Length - 16;
reader.SeekBegin(14);
bool IsGZIP = reader.ReadUInt16() == 0x1F8B;
reader.SeekBegin(16);
ushort signature = reader.ReadUInt16();
bool IsGZIP = signature == 0x1F8B;
bool IsZLIB = signature == 0x789C || signature == 0x78DA;
byte[] filedata = reader.getSection(14, (int)compSize);
byte[] filedata = reader.getSection(16, (int)compSize);
reader.Close();
reader.Dispose();
if (IsGZIP)
data = STLibraryCompression.GZIP.Decompress(filedata);
else
data = STLibraryCompression.ZLIB.Decompress(filedata);
data = STLibraryCompression.ZLIB.Decompress(filedata, false);
}
return data;

View file

@ -119,7 +119,7 @@ namespace FirstPlugin
get
{
if (compressedSize != fileSize)
return new MemoryStream(STLibraryCompression.ZSTD.Decompress(stream.ToBytes()));
return new MemoryStream(Zstb.SDecompress(stream.ToBytes()));
else
return stream;
}

View file

@ -207,7 +207,7 @@ namespace FirstPlugin
{
byte[] decomp = null;
if (magic == 0xDFF25B82 || magic == 0xFD2FB528)
decomp = STLibraryCompression.ZSTD.Decompress(CompressedBlock);
decomp = Zstb.SDecompress(CompressedBlock);
else if (magic == 0x184D2204 || header.Version >= 0x17)
decomp = STLibraryCompression.Type_LZ4.Decompress(CompressedBlock, 0, CompressedBlock.Length,(int)header.DecompressedSize);
else
@ -273,8 +273,8 @@ namespace FirstPlugin
public override IFileFormat OpenFile()
{
byte[] Data = FileData;
var FileFormat = STFileLoader.OpenFileFormat(
IOExtensions.RemoveIllegaleFolderNameCharacters(FileName), Data, true);
var FileFormat = STFileLoader.OpenFileFormat(new MemoryStream(Data),
IOExtensions.RemoveIllegaleFolderNameCharacters(FileName), true);
if (FileFormat is DDS)
((DDS)FileFormat).SwitchSwizzle = IsSwizzled;
@ -346,7 +346,7 @@ namespace FirstPlugin
else
{
stream.Seek((int)Offset + CompOffset, SeekOrigin.Begin);
Data.Add(STLibraryCompression.ZSTD.Decompress(stream.ReadBytes((int)CompressedSizes[i])));
Data.Add(Zstb.SDecompress(stream.ReadBytes((int)CompressedSizes[i])));
}
DecompOffset += (int)decompSize;
CompOffset += (int)CompressedSizes[i];

View file

@ -1232,14 +1232,14 @@ namespace FirstPlugin
string Name = resFile.ExternalFileDict.GetKey(index++);
//Bfsha changes versioons alot so ignore these for now
//Bfsha changes versions alot so ignore these for now
if (Utils.GetExtension(Name) == ".bfsha")
{
externalFilesFolder.AddNode(new ExternalFileData(Name, anim.Data));
continue;
}
var file = STFileLoader.OpenFileFormat(Name, anim.Data, false, true);
var file = STFileLoader.OpenFileFormat(new MemoryStream(anim.Data), Name, false, true);
//Only do once. There's usually one bntx embedded but incase there are multiple
if (file is BNTX && !IsTexturesReplaced)
@ -1305,7 +1305,7 @@ namespace FirstPlugin
sfd.Filter = Utils.GetAllFilters(formats);
if (sfd.ShowDialog() == DialogResult.OK)
STFileSaver.SaveFileFormat(Tex2, true, 0, CompressionType.Yaz0, sfd.FileName);
STFileSaver.SaveFileFormat(Tex2, true,new Yaz0(), 0, sfd.FileName);
}
else
STFileSaver.SaveFileFormat(this, FileName);
@ -1419,7 +1419,7 @@ namespace FirstPlugin
sfd.Filter = Utils.GetAllFilters(formats);
if (sfd.ShowDialog() == DialogResult.OK)
STFileSaver.SaveFileFormat(mem2.ToArray(), Compressed, 0, CompressionType.Yaz0, sfd.FileName);
STFileSaver.SaveFileFormat(mem2.ToArray(), Compressed,new Yaz0(), 0, sfd.FileName);
}
private void Rename(object sender, EventArgs args)
{

View file

@ -85,7 +85,8 @@ namespace FirstPlugin
if (tglp.SheetDataList.Count > 0)
{
var bntx = STFileLoader.OpenFileFormat("Sheet_0", Utils.CombineByteArray(tglp.SheetDataList.ToArray()));
var bntx = STFileLoader.OpenFileFormat(
new MemoryStream(Utils.CombineByteArray(tglp.SheetDataList.ToArray())), "Sheet_0");
if (bntx != null)
{
tglp.BinaryTextureFile = (BNTX)bntx;
@ -287,6 +288,8 @@ namespace FirstPlugin
return Signature;
}
public BitmapFont GetBitmapFont()
{
var FontInfo = FontSection;

View file

@ -1,353 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Windows.Forms;
using Toolbox.Library;
using Toolbox.Library.IO;
using Toolbox.Library.Forms;
using System.Drawing;
namespace FirstPlugin
{
public class G1T : TreeNodeFile, IFileFormat, IContextMenuNode, ITextureIconLoader
{
public FileType FileType { get; set; } = FileType.Image;
public bool CanSave { get; set; }
public string[] Description { get; set; } = new string[] { "G1T Textre" };
public string[] Extension { get; set; } = new string[] { "*.g1t" };
public string FileName { get; set; }
public string FilePath { get; set; }
public IFileInfo IFileInfo { get; set; }
public bool Identify(System.IO.Stream stream)
{
using (var reader = new Toolbox.Library.IO.FileReader(stream, true))
{
return reader.CheckSignature(4, "G1TG") || reader.CheckSignature(4, "GT1G");
}
}
public Type[] Types
{
get
{
List<Type> types = new List<Type>();
return types.ToArray();
}
}
public void Load(Stream stream)
{
Read(new FileReader(stream));
}
public void Unload()
{
}
public void Save(System.IO.Stream stream)
{
}
public List<STGenericTexture> IconTextureList
{
get
{
List<STGenericTexture> textures = new List<STGenericTexture>();
foreach (STGenericTexture node in Nodes)
textures.Add(node);
return textures;
}
set { }
}
public GT1Platform Platform;
public enum GT1Platform
{
PC,
WiiU,
Switch,
}
public void Read(FileReader reader)
{
reader.ByteOrder = Syroot.BinaryData.ByteOrder.BigEndian;
Text = FileName;
long StartPos = reader.Position;
string Magic = reader.ReadString(4);
if (Magic == "GT1G")
reader.ByteOrder = Syroot.BinaryData.ByteOrder.LittleEndian;
else
reader.ByteOrder = Syroot.BinaryData.ByteOrder.BigEndian;
if (Magic == "GT1G")
Platform = GT1Platform.Switch;
else
Platform = GT1Platform.WiiU;
string Version = reader.ReadString(4);
uint FileSize = reader.ReadUInt32();
uint DataOffset = reader.ReadUInt32();
uint TextureCount = reader.ReadUInt32();
uint unk = reader.ReadUInt32();
uint unk2 = reader.ReadUInt32();
uint[] unk3s = reader.ReadUInt32s((int)TextureCount);
for (int i = 0; i < TextureCount; i++)
{
reader.SeekBegin(StartPos + DataOffset + (i * 4));
uint InfoOffset = reader.ReadUInt32();
reader.SeekBegin(DataOffset + InfoOffset);
byte numMips = reader.ReadByte();
byte format = reader.ReadByte();
byte texDims = reader.ReadByte();
byte unknown3 = reader.ReadByte(); //1
byte unknown4 = reader.ReadByte(); //0
byte unknown5 = reader.ReadByte(); //1
byte unknown6 = reader.ReadByte(); //12
byte extraHeader = reader.ReadByte();
if (reader.ByteOrder == Syroot.BinaryData.ByteOrder.LittleEndian)
{
numMips = SwapEndianByte(numMips);
texDims = SwapEndianByte(texDims);
extraHeader = SwapEndianByte(extraHeader);
}
if (extraHeader == 1)
{
var extSize = reader.ReadInt32();
var ext = reader.ReadBytes(extSize - 4);
}
uint Width = (uint)Math.Pow(2, texDims / 16);
uint Height = (uint)Math.Pow(2, texDims % 16);
GITexture tex = new GITexture(this);
tex.ImageKey = "texture";
tex.SelectedImageKey = tex.ImageKey;
tex.Text = $"Texture {i} {format.ToString("x")}";
tex.Width = Width;
tex.Height = Height;
tex.MipCount = numMips;
switch (format)
{
case 0x00: //ABGR
case 0x01: //BGRA 32 bit (no mip maps)
case 0x02: //RGBA 32 bit
case 0x09:
tex.Format = TEX_FORMAT.R8G8B8A8_UNORM;
break;
case 0x06:
case 0x10: //PC and xbox (swizzled)
case 0x59:
case 0x60: //Swizzled
tex.Format = TEX_FORMAT.BC1_UNORM;
break;
case 0x7:
case 0x8:
case 0x12: //PC and xbox (swizzled)
case 0x5B:
case 0x62: //bc1 swizzled
tex.Format = TEX_FORMAT.BC3_UNORM;
break;
case 0x5C:
tex.Format = TEX_FORMAT.BC4_UNORM;
break;
case 0x5D: //DXT5 swizzled or ATI2
tex.Format = TEX_FORMAT.BC5_UNORM;
break;
case 0x5E:
tex.Format = TEX_FORMAT.BC6H_UF16; //Uses cubemaps
break;
case 0x5F:
tex.Format = TEX_FORMAT.BC7_UNORM;
break;
default:
throw new Exception("Unsupported format! " + format.ToString("x"));
}
uint textureSize = (Width * Height * STGenericTexture.GetBytesPerPixel(tex.Format)) / 8;
if (format == 0x09)
textureSize = (Width * Height * 64) / 8;
if (format == 0x01)
{
textureSize = (Width * Height * 32) / 8;
tex.Parameters.DontSwapRG = true;
}
tex.ImageData = reader.ReadBytes((int)textureSize);
Nodes.Add(tex);
}
}
private static byte SwapEndianByte(byte x)
{
return (byte)(((x & 0x0F) << 4) | ((x & 0xF0) >> 4));
}
public virtual ToolStripItem[] GetContextMenuItems()
{
List<ToolStripItem> Items = new List<ToolStripItem>();
Items.Add(new ToolStripMenuItem("Export All", null, ExportAllAction, Keys.Control | Keys.E));
return Items.ToArray();
}
private void ExportAllAction(object sender, EventArgs args)
{
ExportAll();
}
public virtual void ExportAll()
{
List<string> Formats = new List<string>();
Formats.Add("Microsoft DDS (.dds)");
Formats.Add("Portable Graphics Network (.png)");
Formats.Add("Joint Photographic Experts Group (.jpg)");
Formats.Add("Bitmap Image (.bmp)");
Formats.Add("Tagged Image File Format (.tiff)");
FolderSelectDialog sfd = new FolderSelectDialog();
if (sfd.ShowDialog() == DialogResult.OK)
{
string folderPath = sfd.SelectedPath;
BatchFormatExport form = new BatchFormatExport(Formats);
if (form.ShowDialog() == DialogResult.OK)
{
foreach (STGenericTexture tex in Nodes)
{
if (form.Index == 0)
tex.SaveDDS(folderPath + '\\' + tex.Text + ".dds");
else if (form.Index == 1)
tex.SaveBitMap(folderPath + '\\' + tex.Text + ".png");
else if (form.Index == 2)
tex.SaveBitMap(folderPath + '\\' + tex.Text + ".jpg");
else if (form.Index == 3)
tex.SaveBitMap(folderPath + '\\' + tex.Text + ".bmp");
else if (form.Index == 4)
tex.SaveBitMap(folderPath + '\\' + tex.Text + ".tiff");
}
}
}
}
}
public class GITexture : STGenericTexture
{
public G1T ContainerParent;
public override bool CanEdit { get; set; } = false;
public byte[] ImageData;
public override TEX_FORMAT[] SupportedFormats
{
get
{
return new TEX_FORMAT[] {
TEX_FORMAT.R8G8B8A8_UNORM,
};
}
}
public GITexture(G1T GT1)
{
ContainerParent = GT1;
}
public override void OnClick(TreeView treeview)
{
UpdateEditor();
}
private void UpdateEditor()
{
ImageEditorBase editor = (ImageEditorBase)LibraryGUI.GetActiveContent(typeof(ImageEditorBase));
if (editor == null)
{
editor = new ImageEditorBase();
editor.Dock = DockStyle.Fill;
LibraryGUI.LoadEditor(editor);
}
editor.Text = Text;
editor.LoadProperties(GenericProperties);
editor.LoadImage(this);
}
public override void SetImageData(Bitmap bitmap, int ArrayLevel)
{
}
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0)
{
if (ContainerParent.Platform == G1T.GT1Platform.WiiU)
{
uint bpp = GetBytesPerPixel(Format);
GX2.GX2Surface surf = new GX2.GX2Surface();
surf.bpp = bpp;
surf.height = Height;
surf.width = Width;
surf.aa = (uint)GX2.GX2AAMode.GX2_AA_MODE_1X;
surf.alignment = 0;
surf.depth = 1;
surf.dim = (uint)GX2.GX2SurfaceDimension.DIM_2D;
surf.format = (uint)Bfres.Structs.FTEX.ConvertToGx2Format(Format);
surf.use = (uint)GX2.GX2SurfaceUse.USE_COLOR_BUFFER;
surf.pitch = 0;
surf.data = ImageData;
surf.numMips = MipCount;
surf.mipOffset = new uint[0];
surf.mipData = ImageData;
surf.tileMode = (uint)GX2.GX2TileMode.MODE_2D_TILED_THIN1;
// surf.tileMode = (uint)GX2.GX2TileMode.MODE_2D_TILED_THIN1;
surf.swizzle = 0;
surf.numArray = 1;
return GX2.Decode(surf, ArrayLevel, MipLevel);
}
else if (ContainerParent.Platform == G1T.GT1Platform.Switch)
{
return ImageData;
// return TegraX1Swizzle.GetImageData(this, ImageData, ArrayLevel, MipLevel, 1);
}
else
{
return ImageData;
}
}
private void GetMipmaps(STGenericTexture tex, byte[] ImageData)
{
uint width = 0;
uint height = 0;
for (int a = 0; a < tex.ArrayCount; a++)
{
for (int m = 0; m < tex.MipCount; m++)
{
width = (uint)Math.Max(1, tex.Width >> m);
Height = (uint)Math.Max(1, tex.Height >> m);
}
}
}
}
}

View file

@ -0,0 +1,125 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Windows.Forms;
using Toolbox.Library;
using Toolbox.Library.IO;
using Toolbox.Library.Forms;
using System.Drawing;
namespace FirstPlugin
{
public class G1T : TreeNodeFile, IFileFormat, IContextMenuNode, ITextureIconLoader
{
public FileType FileType { get; set; } = FileType.Image;
public bool CanSave { get; set; }
public string[] Description { get; set; } = new string[] { "G1T Textre" };
public string[] Extension { get; set; } = new string[] { "*.g1t" };
public string FileName { get; set; }
public string FilePath { get; set; }
public IFileInfo IFileInfo { get; set; }
public bool Identify(System.IO.Stream stream)
{
using (var reader = new Toolbox.Library.IO.FileReader(stream, true))
{
return reader.CheckSignature(4, "G1TG") || reader.CheckSignature(4, "GT1G");
}
}
public Type[] Types
{
get
{
List<Type> types = new List<Type>();
return types.ToArray();
}
}
public List<STGenericTexture> IconTextureList
{
get
{
List<STGenericTexture> textures = new List<STGenericTexture>();
foreach (STGenericTexture node in Nodes)
textures.Add(node);
return textures;
}
set { }
}
public G1TFile G1TFile = new G1TFile();
public void Load(Stream stream)
{
Text = FileName;
CanSave = true;
G1TFile.Read(new FileReader(stream));
for (int i = 0; i < G1TFile.Textures.Count; i++)
Nodes.Add(G1TFile.Textures[i]);
}
public void Save(System.IO.Stream stream)
{
G1TFile.Write(new FileWriter(stream));
}
public void Unload()
{
}
public virtual ToolStripItem[] GetContextMenuItems()
{
List<ToolStripItem> Items = new List<ToolStripItem>();
Items.Add(new ToolStripMenuItem("Export All", null, ExportAllAction, Keys.Control | Keys.E));
return Items.ToArray();
}
private void ExportAllAction(object sender, EventArgs args)
{
ExportAll();
}
public virtual void ExportAll()
{
List<string> Formats = new List<string>();
Formats.Add("Microsoft DDS (.dds)");
Formats.Add("Portable Graphics Network (.png)");
Formats.Add("Joint Photographic Experts Group (.jpg)");
Formats.Add("Bitmap Image (.bmp)");
Formats.Add("Tagged Image File Format (.tiff)");
FolderSelectDialog sfd = new FolderSelectDialog();
if (sfd.ShowDialog() == DialogResult.OK)
{
string folderPath = sfd.SelectedPath;
BatchFormatExport form = new BatchFormatExport(Formats);
if (form.ShowDialog() == DialogResult.OK)
{
foreach (STGenericTexture tex in Nodes)
{
if (form.Index == 0)
tex.SaveDDS(folderPath + '\\' + tex.Text + ".dds");
else if (form.Index == 1)
tex.SaveBitMap(folderPath + '\\' + tex.Text + ".png");
else if (form.Index == 2)
tex.SaveBitMap(folderPath + '\\' + tex.Text + ".jpg");
else if (form.Index == 3)
tex.SaveBitMap(folderPath + '\\' + tex.Text + ".bmp");
else if (form.Index == 4)
tex.SaveBitMap(folderPath + '\\' + tex.Text + ".tiff");
}
}
}
}
}
}

View file

@ -0,0 +1,257 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Drawing;
using System.Windows.Forms;
using Toolbox.Library.IO;
using Toolbox.Library;
using Toolbox.Library.Forms;
namespace FirstPlugin
{
public class G1TFile
{
public GT1Platform Platform;
public bool IsBigEndian = false;
public List<GITextureWrapper> Textures = new List<GITextureWrapper>();
public enum GT1Platform
{
PC,
WiiU,
Switch,
}
public void Read(FileReader reader)
{
reader.ByteOrder = Syroot.BinaryData.ByteOrder.BigEndian;
long StartPos = reader.Position;
string Magic = reader.ReadString(4);
if (Magic == "GT1G")
reader.ByteOrder = Syroot.BinaryData.ByteOrder.LittleEndian;
else
reader.ByteOrder = Syroot.BinaryData.ByteOrder.BigEndian;
IsBigEndian = reader.IsBigEndian;
if (Magic == "GT1G")
Platform = GT1Platform.Switch;
else
Platform = GT1Platform.WiiU;
string Version = reader.ReadString(4);
uint FileSize = reader.ReadUInt32();
uint DataOffset = reader.ReadUInt32();
uint TextureCount = reader.ReadUInt32();
uint unk = reader.ReadUInt32();
uint unk2 = reader.ReadUInt32();
uint[] unk3s = reader.ReadUInt32s((int)TextureCount);
for (int i = 0; i < TextureCount; i++)
{
reader.SeekBegin(StartPos + DataOffset + (i * 4));
uint InfoOffset = reader.ReadUInt32();
reader.SeekBegin(DataOffset + InfoOffset);
byte numMips = reader.ReadByte();
byte format = reader.ReadByte();
byte texDims = reader.ReadByte();
byte unknown3 = reader.ReadByte(); //1
byte unknown4 = reader.ReadByte(); //0
byte unknown5 = reader.ReadByte(); //1
byte unknown6 = reader.ReadByte(); //12
byte extraHeader = reader.ReadByte();
if (reader.ByteOrder == Syroot.BinaryData.ByteOrder.LittleEndian)
{
numMips = SwapEndianByte(numMips);
texDims = SwapEndianByte(texDims);
extraHeader = SwapEndianByte(extraHeader);
}
if (extraHeader == 1)
{
var extSize = reader.ReadInt32();
var ext = reader.ReadBytes(extSize - 4);
}
uint Width = (uint)Math.Pow(2, texDims / 16);
uint Height = (uint)Math.Pow(2, texDims % 16);
GITextureWrapper tex = new GITextureWrapper(this);
tex.ImageKey = "texture";
tex.SelectedImageKey = tex.ImageKey;
tex.Text = $"Texture {i} {format.ToString("x")}";
tex.Width = Width;
tex.Height = Height;
tex.MipCount = numMips;
switch (format)
{
case 0x00: //ABGR
case 0x01: //BGRA 32 bit (no mip maps)
case 0x02: //RGBA 32 bit
case 0x09:
tex.Format = TEX_FORMAT.R8G8B8A8_UNORM;
break;
case 0x06:
case 0x10: //PC and xbox (swizzled)
case 0x59:
case 0x60: //Swizzled
tex.Format = TEX_FORMAT.BC1_UNORM;
break;
case 0x7:
case 0x8:
case 0x12: //PC and xbox (swizzled)
case 0x5B:
case 0x62: //bc1 swizzled
tex.Format = TEX_FORMAT.BC3_UNORM;
break;
case 0x5C:
tex.Format = TEX_FORMAT.BC4_UNORM;
break;
case 0x5D: //DXT5 swizzled or ATI2
tex.Format = TEX_FORMAT.BC5_UNORM;
break;
case 0x5E:
tex.Format = TEX_FORMAT.BC6H_UF16; //Uses cubemaps
break;
case 0x5F:
tex.Format = TEX_FORMAT.BC7_UNORM;
break;
default:
throw new Exception("Unsupported format! " + format.ToString("x"));
}
uint textureSize = (Width * Height * STGenericTexture.GetBytesPerPixel(tex.Format)) / 8;
if (format == 0x09)
textureSize = (Width * Height * 64) / 8;
if (format == 0x01)
{
textureSize = (Width * Height * 32) / 8;
tex.Parameters.DontSwapRG = true;
}
tex.ImageData = reader.ReadBytes((int)textureSize);
Textures.Add(tex);
}
}
public void Write(FileWriter writer)
{
}
private static byte SwapEndianByte(byte x)
{
return (byte)(((x & 0x0F) << 4) | ((x & 0xF0) >> 4));
}
public class GITextureWrapper : STGenericTexture
{
public G1TFile ContainerParent;
public override bool CanEdit { get; set; } = false;
public byte[] ImageData;
public override TEX_FORMAT[] SupportedFormats
{
get
{
return new TEX_FORMAT[] {
TEX_FORMAT.R8G8B8A8_UNORM,
};
}
}
public GITextureWrapper(G1TFile GT1)
{
ContainerParent = GT1;
}
public override void OnClick(TreeView treeview)
{
UpdateEditor();
}
private void UpdateEditor()
{
ImageEditorBase editor = (ImageEditorBase)LibraryGUI.GetActiveContent(typeof(ImageEditorBase));
if (editor == null)
{
editor = new ImageEditorBase();
editor.Dock = DockStyle.Fill;
LibraryGUI.LoadEditor(editor);
}
editor.Text = Text;
editor.LoadProperties(GenericProperties);
editor.LoadImage(this);
}
public override void SetImageData(Bitmap bitmap, int ArrayLevel)
{
}
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0)
{
if (ContainerParent.Platform == GT1Platform.WiiU)
{
uint bpp = GetBytesPerPixel(Format);
GX2.GX2Surface surf = new GX2.GX2Surface();
surf.bpp = bpp;
surf.height = Height;
surf.width = Width;
surf.aa = (uint)GX2.GX2AAMode.GX2_AA_MODE_1X;
surf.alignment = 0;
surf.depth = 1;
surf.dim = (uint)GX2.GX2SurfaceDimension.DIM_2D;
surf.format = (uint)Bfres.Structs.FTEX.ConvertToGx2Format(Format);
surf.use = (uint)GX2.GX2SurfaceUse.USE_COLOR_BUFFER;
surf.pitch = 0;
surf.data = ImageData;
surf.numMips = MipCount;
surf.mipOffset = new uint[0];
surf.mipData = ImageData;
surf.tileMode = (uint)GX2.GX2TileMode.MODE_2D_TILED_THIN1;
// surf.tileMode = (uint)GX2.GX2TileMode.MODE_2D_TILED_THIN1;
surf.swizzle = 0;
surf.numArray = 1;
return GX2.Decode(surf, ArrayLevel, MipLevel);
}
else
{
return ImageData;
}
}
private void GetMipmaps(STGenericTexture tex, byte[] ImageData)
{
uint width = 0;
uint height = 0;
for (int a = 0; a < tex.ArrayCount; a++)
{
for (int m = 0; m < tex.MipCount; m++)
{
width = (uint)Math.Max(1, tex.Width >> m);
Height = (uint)Math.Max(1, tex.Height >> m);
}
}
}
}
}
}

View file

@ -61,60 +61,16 @@ namespace FirstPlugin
reader.Position = 0;
}
private Stream CheckCompression(Stream stream)
{
using (var reader = new FileReader(stream, true))
{
reader.ByteOrder = Syroot.BinaryData.ByteOrder.BigEndian;
uint unk = reader.ReadUInt32();
try
{
uint chunkCount = reader.ReadUInt32();
uint unk2 = reader.ReadUInt32();
uint[] chunkSizes = reader.ReadUInt32s((int)chunkCount); //Not very sure about this
reader.Align(128);
List<byte[]> DecompressedChunks = new List<byte[]>();
//Now search for zlibbed chunks
while (!reader.EndOfStream)
{
uint size = reader.ReadUInt32();
long pos = reader.Position;
ushort magic = reader.ReadUInt16();
///Check zlib magic
if (magic == 0x78da)
{
var data = STLibraryCompression.ZLIB.Decompress(reader.getSection((uint)pos, size));
DecompressedChunks.Add(data);
reader.SeekBegin(pos + size); //Seek the compressed size and align it to goto the next chunk
reader.Align(128);
}
else //If the magic check fails, seek back 2. This shouldn't happen, but just incase
reader.Seek(-2);
}
//Return the decompressed stream with all chunks combined
return new MemoryStream(Utils.CombineByteArray(DecompressedChunks.ToArray()));
}
catch
{
}
}
return stream;
}
public bool isBigEndian = true;
public void Load(Stream stream)
{
stream = CheckCompression(stream);
CanSave = true;
using (var reader = new FileReader(stream))
{
CheckEndianness(reader);
isBigEndian = reader.IsBigEndian;
uint Count = reader.ReadUInt32();
@ -145,8 +101,9 @@ namespace FirstPlugin
case "G1TG": //Textures
G1T GITextureU = new G1T();
GITextureU.FileName = $"TextureContainer{i}.gt1";
GITextureU.Read(new FileReader(fileEntry.FileData));
GITextureU.Load(new MemoryStream(fileEntry.FileData));
Nodes.Add(GITextureU);
fileEntry.FileFormat = GITextureU;
break;
default:
break;
@ -164,6 +121,21 @@ namespace FirstPlugin
public void Save(System.IO.Stream stream)
{
using (var writer = new FileWriter(stream))
{
writer.SetByteOrder(isBigEndian);
writer.Write(files.Count);
long pos = writer.Position;
writer.Write(new uint[files.Count * 2]);
for (int i = 0; i < files.Count; i++)
{
files[i].SaveFileFormat();
writer.WriteUint32Offset(pos + (i * 8));
writer.Write(files[i].FileData.Length, pos + 4 + (i * 8));
writer.Write(files[i].FileData);
}
}
}
public bool AddFile(ArchiveFileInfo archiveFileInfo)

View file

@ -47,6 +47,8 @@ namespace FirstPlugin
public void ClearFiles() { files.Clear(); }
private FileReader DataReader;
public void Load(System.IO.Stream stream)
{
using (var reader = new FileReader(stream))
@ -65,12 +67,34 @@ namespace FirstPlugin
if (entry.Size != 0 && entry.CompFlags == 0)
files.Add(entry);
}
DataReader = GetDataFile();
SearchData();
}
}
private void SearchData()
{
if (DataReader == null) return;
DataReader.Position = 0;
for (int i = 0; i < files.Count; i++)
{
DataReader.SeekBegin(files[i].Offset);
var magicCheck = DataReader.ReadString(4);
Console.WriteLine("MAGIC=" + magicCheck);
if (magicCheck == "SARC")
files[i].FileName = $"Layout/{files[i].FileName}.szs";
else if (magicCheck == "SPKG")
files[i].FileName = $"ShaderPackage/{files[i].FileName}.spkg";
else
files[i].FileName = $"UnknownTypes/{files[i].FileName}.bin";
}
}
public void Unload()
{
DataReader?.Dispose();
}
public void Save(System.IO.Stream stream)
@ -87,6 +111,35 @@ namespace FirstPlugin
return false;
}
public FileReader GetDataFile()
{
if (DataReader != null) return DataReader;
if (IFileInfo.ArchiveParent != null)
{
foreach (var file in IFileInfo.ArchiveParent.Files)
{
if (file.FileName.Contains("DATA1.bin"))
return new FileReader(file.FileDataStream, true);
}
}
else
{
string path = "";
if (FilePath.Contains("LINKDATA.IDX"))
path = FilePath.Replace("IDX", "BIN");
if (FilePath.Contains("DATA1.bin"))
path = FilePath.Replace("DATA0", "DATA1");
if (!System.IO.File.Exists(path))
return null;
return new FileReader(path, true);
}
return null;
}
public class FileEntry : ArchiveFileInfo
{
private LINKDATA ParentFile;
@ -103,6 +156,8 @@ namespace FirstPlugin
ParentFile = data;
}
public FileType Type = FileType.Unknown;
public void Read(FileReader reader)
{
Offset = reader.ReadUInt64();
@ -111,39 +166,18 @@ namespace FirstPlugin
CompFlags = reader.ReadUInt64();
}
public enum FileType
{
Unknown,
Shader,
Texture,
Model,
Sarc,
}
public override Stream FileDataStream
{
get
{
if (ParentFile.IFileInfo.ArchiveParent != null)
{
foreach (var file in ParentFile.IFileInfo.ArchiveParent.Files)
{
if (file.FileName.Contains("DATA1.bin"))
{
return GetData(new FileReader(file.FileDataStream, true));
}
}
return new MemoryStream();
}
else
{
string path = "";
if (SourcePath.Contains("LINKDATA.IDX"))
path = SourcePath.Replace("IDX", "BIN");
if (SourcePath.Contains("DATA1.bin"))
path = SourcePath.Replace("DATA0", "DATA1");
if (!System.IO.File.Exists(path))
return new MemoryStream();
using (var reader = new FileReader(path, true))
{
return GetData(reader);
}
}
}
get { return GetData(ParentFile.GetDataFile()); }
}
private Stream GetData(FileReader reader)

View file

@ -88,7 +88,7 @@ namespace FirstPlugin
{
files.Clear();
Control = null;
Control?.Dispose();
}
public void Save(System.IO.Stream stream)

View file

@ -99,7 +99,7 @@ namespace FirstPlugin
var file = romfs.FileDict[$"/{filePath}"];
var stream = romfs.OpenFile(file).AsStream();
object fileFormat = STFileLoader.OpenFileFormat(text, stream.ToArray(), false, true);
object fileFormat = STFileLoader.OpenFileFormat(stream , text, false, true);
if (fileFormat == null)
return;

View file

@ -1,14 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading.Tasks;
using Toolbox.Library;
using Toolbox.Library.IO;
using LibHac;
using LibHac.IO;
namespace FirstPlugin
{
public class XCI : IFileFormat, ILeaveOpenOnLoad
public class XCI : IFileFormat, IArchiveFile, ILeaveOpenOnLoad
{
public FileType FileType { get; set; } = FileType.Rom;
@ -33,16 +35,64 @@ namespace FirstPlugin
return Utils.HasExtension(FileName, ".xci");
}
public bool CanAddFiles { get; set; }
public bool CanRenameFiles { get; set; }
public bool CanReplaceFiles { get; set; }
public bool CanDeleteFiles { get; set; }
public List<NSP.FileEntry> files = new List<NSP.FileEntry>();
public IEnumerable<ArchiveFileInfo> Files => files;
public void ClearFiles() { files.Clear(); }
Nca Control { get; set; }
public void Load(System.IO.Stream stream)
{
string homeFolder = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
string KeyFile = Path.Combine(homeFolder, ".switch", "prod.keys");
string TitleKeyFile = Path.Combine(homeFolder, ".switch", "title.keys");
var Keys = ExternalKeys.ReadKeyFile(KeyFile, TitleKeyFile);
Xci xci = new Xci(Keys, stream.AsStorage());
var CnmtNca = new Nca(Keys, xci.SecurePartition.OpenFile(
xci.SecurePartition.Files.FirstOrDefault(s => s.Name.Contains(".cnmt.nca"))), false);
var CnmtPfs = new Pfs(CnmtNca.OpenSection(0, false, IntegrityCheckLevel.None, true));
var Cnmt = new Cnmt(CnmtPfs.OpenFile(CnmtPfs.Files[0]).AsStream());
var Program = Cnmt.ContentEntries.FirstOrDefault(c => c.Type == CnmtContentType.Program);
var CtrlEntry = Cnmt.ContentEntries.FirstOrDefault(c => c.Type == CnmtContentType.Control);
if (CtrlEntry != null)
Control = new Nca(Keys, xci.SecurePartition.OpenFile($"{CtrlEntry.NcaId.ToHexString().ToLower()}.nca"), false);
var Input = xci.SecurePartition.OpenFile($"{Program.NcaId.ToHexString().ToLower()}.nca").AsStream();
var Nca = new Nca(Keys, Input.AsStorage(), true);
Romfs romfs = new Romfs(
Nca.OpenSection(Nca.Sections.FirstOrDefault
(s => s?.Type == SectionType.Romfs || s?.Type == SectionType.Bktr)
.SectionNum, false, IntegrityCheckLevel.None, true));
for (int i = 0; i < romfs.Files.Count; i++)
files.Add(new NSP.FileEntry(romfs, romfs.Files[i]));
}
public void Unload()
{
Control?.Dispose();
}
public void Save(System.IO.Stream stream)
{
}
public bool AddFile(ArchiveFileInfo archiveFileInfo)
{
return false;
}
public bool DeleteFile(ArchiveFileInfo archiveFileInfo)
{
return false;
}
}
}

View file

@ -79,7 +79,7 @@ namespace FirstPlugin
public override void OnAfterAdded()
{
if (textures.Count > 0)
if (textures.Count > 0 && this.TreeView != null)
this.TreeView.SelectedNode = textures[0];
}

View file

@ -0,0 +1,193 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Toolbox;
using System.Windows.Forms;
using Toolbox.Library;
using Toolbox.Library.IO;
using Toolbox.Library.Forms;
using System.Runtime.InteropServices;
namespace FirstPlugin
{
public class TVOL : TreeNodeFile, IFileFormat, ILeaveOpenOnLoad
{
public FileType FileType { get; set; } = FileType.Image;
public bool CanSave { get; set; }
public string[] Description { get; set; } = new string[] { "Texture VOL" };
public string[] Extension { get; set; } = new string[] { "*.tvol" };
public string FileName { get; set; }
public string FilePath { get; set; }
public IFileInfo IFileInfo { get; set; }
public bool Identify(System.IO.Stream stream)
{
return Utils.GetExtension(FileName) == ".tvol";
}
public List<STGenericTexture> IconTextureList
{
get
{
List<STGenericTexture> textures = new List<STGenericTexture>();
foreach (STGenericTexture node in Nodes)
textures.Add(node);
return textures;
}
set { }
}
public Type[] Types
{
get
{
List<Type> types = new List<Type>();
return types.ToArray();
}
}
public void Load(System.IO.Stream stream)
{
Text = FileName;
using (var reader = new FileReader(stream, true))
{
reader.SetByteOrder(false);
uint numTextures = reader.ReadUInt32();
for (int i = 0; i < numTextures; i++)
{
uint offset = reader.ReadUInt32();
uint size = reader.ReadUInt32();
if (size == 0)
continue;
using (reader.TemporarySeek(offset, System.IO.SeekOrigin.Begin))
{
TextureWrapper entry = new TextureWrapper();
entry.ImageKey = "texture";
entry.SelectedImageKey = "texture";
entry.Format = TEX_FORMAT.BC7_UNORM;
entry.Text = reader.ReadZeroTerminatedString();
reader.SeekBegin(offset + 48);
ulong unk = reader.ReadUInt64(); //20
ulong unk2 = reader.ReadUInt64(); //36
ulong sectionSize = reader.ReadUInt64();
ulong unk3 = reader.ReadUInt64(); //16
ulong unk4 = reader.ReadUInt64(); //4
uint unk5 = reader.ReadUInt32(); //C03F
ulong unk6 = reader.ReadUInt64(); //32
ulong unk7 = reader.ReadUInt64(); //24
ulong unk8 = reader.ReadUInt64(); //40
ulong imageSize = reader.ReadUInt64();
entry.Width = reader.ReadUInt32();
entry.Height = reader.ReadUInt32();
entry.Depth = reader.ReadUInt32();
entry.ArrayCount = reader.ReadUInt32();
uint unk9 = reader.ReadUInt32(); //77
uint unk10 = reader.ReadUInt32(); //1
entry.ImageData = reader.ReadBytes((int)imageSize);
Nodes.Add(entry);
}
}
}
}
public void Unload()
{
}
public void Save(System.IO.Stream stream)
{
}
public class TextureWrapper : STGenericTexture
{
public byte[] ImageData;
public TextureWrapper()
{
}
private Dictionary<uint, TEX_FORMAT> Formats = new Dictionary<uint, TEX_FORMAT>()
{
{0x25 , TEX_FORMAT.R8G8B8A8_UNORM},
{0x42 , TEX_FORMAT.BC1_UNORM},
{0x43, TEX_FORMAT.BC2_UNORM},
{0x44, TEX_FORMAT.BC3_UNORM},
{0x45, TEX_FORMAT.BC4_UNORM},
{0x46 , TEX_FORMAT.BC1_UNORM_SRGB},
{0x47 , TEX_FORMAT.BC2_UNORM_SRGB},
{0x48 , TEX_FORMAT.BC3_UNORM_SRGB},
{0x49, TEX_FORMAT.BC4_SNORM},
{0x50, TEX_FORMAT.BC6H_UF16},
{0x79, TEX_FORMAT.ASTC_4x4_UNORM},
{0x80, TEX_FORMAT.ASTC_8x8_UNORM},
{0x87, TEX_FORMAT.ASTC_4x4_SRGB},
{0x8E, TEX_FORMAT.ASTC_8x8_SRGB},
};
public override bool CanEdit { get; set; } = false;
public override TEX_FORMAT[] SupportedFormats
{
get
{
return new TEX_FORMAT[]
{
TEX_FORMAT.B5G6R5_UNORM,
TEX_FORMAT.R8G8_UNORM,
TEX_FORMAT.B5G5R5A1_UNORM,
TEX_FORMAT.B4G4R4A4_UNORM,
TEX_FORMAT.LA8,
TEX_FORMAT.HIL08,
TEX_FORMAT.L8,
TEX_FORMAT.A8_UNORM,
TEX_FORMAT.LA4,
TEX_FORMAT.A4,
TEX_FORMAT.ETC1_UNORM,
TEX_FORMAT.ETC1_A4,
};
}
}
public override void SetImageData(System.Drawing.Bitmap bitmap, int ArrayLevel)
{
}
private bool hasShownDialog = false;
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0)
{
return TegraX1Swizzle.GetImageData(this, ImageData, ArrayLevel, MipLevel, 1);
}
public override void OnClick(TreeView treeView)
{
UpdateEditor();
}
private void UpdateEditor()
{
ImageEditorBase editor = (ImageEditorBase)LibraryGUI.GetActiveContent(typeof(ImageEditorBase));
if (editor == null)
{
editor = new ImageEditorBase();
editor.Dock = DockStyle.Fill;
LibraryGUI.LoadEditor(editor);
}
editor.LoadProperties(GenericProperties);
editor.LoadImage(this);
}
}
}
}

View file

@ -229,7 +229,8 @@
<Compile Include="FileFormats\HyruleWarriors\G1M\G1MEnums.cs" />
<Compile Include="FileFormats\HyruleWarriors\G1M\G1MG.cs" />
<Compile Include="FileFormats\HyruleWarriors\G1M\G1MS.cs" />
<Compile Include="FileFormats\HyruleWarriors\G1T.cs" />
<Compile Include="FileFormats\HyruleWarriors\G1T\G1T.cs" />
<Compile Include="FileFormats\HyruleWarriors\G1T\G1TFile.cs" />
<Compile Include="FileFormats\HyruleWarriors\HWBinGzResource.cs" />
<Compile Include="FileFormats\CrashBandicoot\IGA_PAK.cs" />
<Compile Include="FileFormats\Archives\LM2\LM2_ChunkTable.cs" />
@ -327,6 +328,7 @@
<Compile Include="FileFormats\Rom\3DS\RomFSStructure.cs" />
<Compile Include="FileFormats\Texture\CTPK.cs" />
<Compile Include="FileFormats\Grezzo\CTXB.cs" />
<Compile Include="FileFormats\Texture\TVOL.cs" />
<Compile Include="FileFormats\Texture\TPL.cs" />
<Compile Include="FileFormats\Rom\GCDisk.cs" />
<Compile Include="FileFormats\Texture\BTI.cs" />

View file

@ -109,14 +109,13 @@
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(415, 181);
this.Controls.Add(this.setProdKeyPath);
this.Controls.Add(this.setTitleKeyPath);
this.Controls.Add(this.btnOk);
this.Controls.Add(this.stLabel2);
this.Controls.Add(this.TextBoxTitleKey);
this.Controls.Add(this.stLabel1);
this.Controls.Add(this.TextBoxProdKeyPath);
this.contentContainer.Controls.Add(this.setProdKeyPath);
this.contentContainer.Controls.Add(this.setTitleKeyPath);
this.contentContainer.Controls.Add(this.btnOk);
this.contentContainer.Controls.Add(this.stLabel2);
this.contentContainer.Controls.Add(this.TextBoxTitleKey);
this.contentContainer.Controls.Add(this.stLabel1);
this.contentContainer.Controls.Add(this.TextBoxProdKeyPath);
this.Name = "KeySelectionForm";
this.Text = "Select Key Files";
this.ResumeLayout(false);

View file

@ -28,6 +28,7 @@
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.splitContainer1 = new System.Windows.Forms.SplitContainer();
this.listViewCustom1 = new Toolbox.Library.Forms.ListViewCustom();
this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
@ -42,6 +43,7 @@
this.stMenuStrip1 = new Toolbox.Library.Forms.STMenuStrip();
this.viewToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.loadFontToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.stContextMenuStrip1 = new Toolbox.Library.Forms.STContextMenuStrip(this.components);
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
this.splitContainer1.Panel1.SuspendLayout();
this.splitContainer1.Panel2.SuspendLayout();
@ -220,6 +222,11 @@
this.loadFontToolStripMenuItem.Text = "Load Font";
this.loadFontToolStripMenuItem.Click += new System.EventHandler(this.loadFontToolStripMenuItem_Click);
//
// stContextMenuStrip1
//
this.stContextMenuStrip1.Name = "stContextMenuStrip1";
this.stContextMenuStrip1.Size = new System.Drawing.Size(61, 4);
//
// MSBTEditor
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@ -266,5 +273,6 @@
private Toolbox.Library.Forms.STMenuStrip stMenuStrip1;
private System.Windows.Forms.ToolStripMenuItem viewToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem loadFontToolStripMenuItem;
private Toolbox.Library.Forms.STContextMenuStrip stContextMenuStrip1;
}
}

View file

@ -120,4 +120,7 @@
<metadata name="stMenuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="stContextMenuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>141, 17</value>
</metadata>
</root>

View file

@ -238,7 +238,7 @@ namespace FirstPlugin
string ext = System.IO.Path.GetExtension(file.FileName);
if (ext == ".bfres")
{
bfresFiles.Add((BFRES)STFileLoader.OpenFileFormat(file.FileName, file.FileData));
bfresFiles.Add((BFRES)STFileLoader.OpenFileFormat(new System.IO.MemoryStream(file.FileData), file.FileName));
}
}
}
@ -385,6 +385,8 @@ namespace FirstPlugin
Formats.Add(typeof(BCLIM));
Formats.Add(typeof(LayoutBXLYT.BFLAN));
Formats.Add(typeof(DAT_Bayonetta));
Formats.Add(typeof(XCI));
Formats.Add(typeof(TVOL));
// Formats.Add(typeof(MSBP));
// Formats.Add(typeof(BFGRP));
@ -392,7 +394,6 @@ namespace FirstPlugin
//Unfinished wip formats not ready for use
if (Runtime.DEVELOPER_DEBUG_MODE)
{
Formats.Add(typeof(XCI));
Formats.Add(typeof(XLINK));
Formats.Add(typeof(BFSAR));
Formats.Add(typeof(GFA));

View file

@ -39,7 +39,7 @@ namespace FirstPlugin
if (bfresData != null)
{
BFRES bfresFile = (BFRES)STFileLoader.OpenFileFormat(ob.Name, bfresData);
BFRES bfresFile = (BFRES)STFileLoader.OpenFileFormat(new MemoryStream(bfresData), ob.Name);
bfresFile.BFRESRender.ModelTransform = Transform;
editor.AddNode(bfresFile);

View file

@ -21,6 +21,7 @@ namespace Toolbox.Library.IO
items.Add(new ToolStripMenuItem("Yaz0"));
items.Add(new ToolStripMenuItem("Gzip"));
items.Add(new ToolStripMenuItem("lZMA"));
items.Add(new ToolStripMenuItem("lZ4"));
items.Add(new ToolStripMenuItem("lZ4F"));
items.Add(new ToolStripMenuItem("ZSTD"));
@ -64,89 +65,48 @@ namespace Toolbox.Library.IO
private void SetToolStripFunctions(string Name, bool Compress)
{
if (Name == "Yaz0")
OpenFileForCompression(CompressionType.Yaz0, Compress);
OpenFileForCompression(new Yaz0(), Compress);
else if (Name == "Gzip")
OpenFileForCompression(CompressionType.Gzip, Compress);
OpenFileForCompression(new Gzip(), Compress);
else if (Name == "lZMA")
OpenFileForCompression(new LZMA(), Compress);
else if (Name == "lZ4")
OpenFileForCompression(CompressionType.Lz4, Compress);
OpenFileForCompression(new lz4(), Compress);
else if (Name == "lZ4F")
OpenFileForCompression(CompressionType.Lz4f, Compress);
OpenFileForCompression(new LZ4F(), Compress);
else if (Name == "ZSTD")
OpenFileForCompression(CompressionType.Zstb, Compress);
OpenFileForCompression(new Zstb(), Compress);
else if (Name == "ZLIB")
OpenFileForCompression(CompressionType.Zlib, Compress);
OpenFileForCompression(new Zlib(), Compress);
else if (Name.Contains("ZLIB_GZ"))
OpenFileForCompression(CompressionType.ZlibGz, Compress);
OpenFileForCompression(new ZlibGZ(), Compress);
else throw new Exception("Unimplimented Type! " + Name);
}
public void CompressData(CompressionType CompressionType, byte[] data)
{
switch (CompressionType)
{
case CompressionType.Yaz0:
SaveFileForCompression(EveryFileExplorer.YAZ0.Compress(data, Runtime.Yaz0CompressionLevel));
break;
case CompressionType.Zlib:
SaveFileForCompression(STLibraryCompression.ZLIB.Compress(data));
break;
case CompressionType.Gzip:
SaveFileForCompression(STLibraryCompression.GZIP.Compress(data));
break;
case CompressionType.Zstb:
SaveFileForCompression(STLibraryCompression.ZSTD.Compress(data));
break;
case CompressionType.Lz4f:
SaveFileForCompression(STLibraryCompression.Type_LZ4F.Compress(data));
break;
case CompressionType.Lz4:
SaveFileForCompression(STLibraryCompression.Type_LZ4.Compress(data));
break;
}
}
public void DecompressData(CompressionType CompressionType, byte[] data)
public void CompressData(ICompressionFormat CompressionFormat, Stream data)
{
try
{
switch (CompressionType)
{
case CompressionType.Yaz0:
SaveFileForCompression(EveryFileExplorer.YAZ0.Decompress(data));
break;
case CompressionType.Zlib:
SaveFileForCompression(STLibraryCompression.ZLIB.Decompress(data));
break;
case CompressionType.Gzip:
SaveFileForCompression(STLibraryCompression.GZIP.Decompress(data));
break;
case CompressionType.Zstb:
SaveFileForCompression(STLibraryCompression.ZSTD.Decompress(data));
break;
case CompressionType.Lz4f:
using (var reader = new FileReader(data))
{
reader.Position = 0;
int OuSize = reader.ReadInt32();
int InSize = data.Length - 4;
SaveFileForCompression(STLibraryCompression.Type_LZ4F.Decompress(reader.getSection(4, InSize)));
SaveFileForCompression(true, data, CompressionFormat);
}
break;
case CompressionType.Lz4:
SaveFileForCompression(STLibraryCompression.Type_LZ4.Decompress(data));
break;
case CompressionType.ZlibGz:
SaveFileForCompression(STLibraryCompression.ZLIB_GZ.Decompress(new MemoryStream(data)));
break;
catch (Exception ex)
{
MessageBox.Show($"File failed to compress with {CompressionFormat} compression! {ex.ToString()}");
}
}
catch
public void DecompressData(ICompressionFormat CompressionFormat, Stream data)
{
MessageBox.Show($"File not compressed with {CompressionType} compression!");
try
{
SaveFileForCompression(false, data, CompressionFormat);
}
catch (Exception ex)
{
MessageBox.Show($"File not compressed with {CompressionFormat} compression! {ex.ToString()}");
}
}
private void OpenFileForCompression(CompressionType compressionType, bool Compress)
private void OpenFileForCompression(ICompressionFormat compressionFormat, bool Compress)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "All files(*.*)|*.*";
@ -158,14 +118,14 @@ namespace Toolbox.Library.IO
foreach (string file in ofd.FileNames)
{
if (Compress)
CompressData(compressionType, File.ReadAllBytes(ofd.FileName));
CompressData(compressionFormat, File.OpenRead(ofd.FileName));
else
DecompressData(compressionType, File.ReadAllBytes(ofd.FileName));
DecompressData(compressionFormat, File.OpenRead(ofd.FileName));
}
}
}
private void SaveFileForCompression(Stream data)
private void SaveFileForCompression(bool Compress, Stream data, ICompressionFormat compressionFormat)
{
SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = "All files(*.*)|*.*";
@ -173,21 +133,13 @@ namespace Toolbox.Library.IO
Cursor.Current = Cursors.Default;
if (sfd.ShowDialog() == DialogResult.OK)
{
data.ExportToFile(sfd.FileName);
if (Compress)
compressionFormat.Compress(data).ExportToFile(sfd.FileName);
else
compressionFormat.Decompress(data).ExportToFile(sfd.FileName);
MessageBox.Show($"File has been saved to {sfd.FileName}", "Save Notification");
}
}
private void SaveFileForCompression(byte[] data)
{
SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = "All files(*.*)|*.*";
Cursor.Current = Cursors.Default;
if (sfd.ShowDialog() == DialogResult.OK)
{
STFileSaver.SaveFileFormat(data, true, 0, CompressionType.None, sfd.FileName, false);
}
}
}
}

View file

@ -0,0 +1,64 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.IO.Compression;
using System.Threading.Tasks;
using Toolbox.Library.IO;
namespace Toolbox.Library
{
public class Gzip : ICompressionFormat
{
public string[] Description { get; set; } = new string[] { "GZIP Compressed" };
public string[] Extension { get; set; } = new string[] { "*.gzip", };
private long startPosition = 0;
private bool IsSonicWinterOlypmics = false;
public override string ToString() { return "Gzip"; }
public bool Identify(Stream stream, string fileName)
{
using (var reader = new FileReader(stream, true))
{
reader.SetByteOrder(true);
ushort magicNumber = reader.ReadUInt16();
reader.Position = 0;
string magicSig = reader.ReadString(4);
IsSonicWinterOlypmics = magicSig == "ZLIB";
if (IsSonicWinterOlypmics)
startPosition = 64;
return magicNumber == 0x1f8b || IsSonicWinterOlypmics;
}
}
public bool CanCompress { get; } = true;
public Stream Decompress(Stream stream)
{
stream.Position = startPosition;
var mem = new System.IO.MemoryStream();
using (GZipStream source = new GZipStream(stream, CompressionMode.Decompress, false))
{
source.CopyTo(mem);
}
return mem;
}
public Stream Compress(Stream stream)
{
MemoryStream mem = new MemoryStream();
using (GZipStream gzip = new GZipStream(mem, CompressionMode.Compress, true))
{
stream.CopyTo(gzip);
}
return mem;
}
}
}

View file

@ -0,0 +1,60 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.IO.Compression;
using System.Threading.Tasks;
using Toolbox.Library.IO;
using K4os.Compression.LZ4.Streams;
namespace Toolbox.Library
{
public class LZ4F : ICompressionFormat
{
public string[] Description { get; set; } = new string[] { "LZ4F Compression" };
public string[] Extension { get; set; } = new string[] { "*.cmp", "*.lz4f" };
public override string ToString() { return "LZ4F"; }
public bool Identify(Stream stream, string fileName)
{
using (var reader = new FileReader(stream, true))
{
uint DecompressedSize = reader.ReadUInt32();
uint magicCheck = reader.ReadUInt32();
bool LZ4FDefault = magicCheck == 0x184D2204;
return LZ4FDefault;
}
}
public bool CanCompress { get; } = true;
public Stream Decompress(Stream stream)
{
using (var reader = new FileReader(stream, true))
{
reader.Position = 0;
int OuSize = reader.ReadInt32();
int InSize = (int)stream.Length - 4;
var dec = STLibraryCompression.Type_LZ4F.Decompress(reader.getSection(4, InSize));
return new MemoryStream(dec);
}
}
public Stream Compress(Stream stream)
{
var mem = new MemoryStream();
using (var writer = new FileWriter(mem, true))
{
writer.Write((uint)stream.Length);
byte[] buffer = LZ4.Frame.LZ4Frame.Compress(stream,
LZ4.Frame.LZ4MaxBlockSize.MB1, true, true, false, true, false);
writer.Write(buffer, 0, buffer.Length);
}
return mem;
}
}
}

View file

@ -0,0 +1,69 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.IO.Compression;
using System.Threading.Tasks;
using Toolbox.Library.IO;
namespace Toolbox.Library
{
public class LZMA : ICompressionFormat
{
public string[] Description { get; set; } = new string[] { "LZMA Compressed" };
public string[] Extension { get; set; } = new string[] { "*.lzma", };
public override string ToString() { return "LZMA"; }
public bool Identify(Stream stream, string fileName)
{
using (var reader = new FileReader(stream, true))
{
return reader.CheckSignature(4,"LZMA", 1);
}
}
public bool CanCompress { get; } = true;
public Stream Decompress(Stream stream)
{
using (var reader = new FileReader(stream))
{
reader.SetByteOrder(true);
var output = new System.IO.MemoryStream();
if (reader.CheckSignature(4, "LZMA", 1))
{
byte unk = reader.ReadByte();
uint magic = reader.ReadUInt32();
ushort unk2 = reader.ReadUInt16();
}
uint decompressedSize = reader.ReadUInt32();
var properties = reader.ReadBytes(5);
var compressedSize = stream.Length - 16;
var copressedBytes = reader.ReadBytes((int)compressedSize);
SevenZip.Compression.LZMA.Decoder decode = new SevenZip.Compression.LZMA.Decoder();
decode.SetDecoderProperties(properties);
MemoryStream ms = new MemoryStream(copressedBytes);
decode.Code(ms, output, compressedSize, decompressedSize, null);
return output;
}
}
public Stream Compress(Stream stream)
{
MemoryStream mem = new MemoryStream();
using (GZipStream gzip = new GZipStream(mem, CompressionMode.Compress, true))
{
stream.CopyTo(gzip);
}
return mem;
}
}
}

View file

@ -16,7 +16,7 @@ namespace Toolbox.Library
public string[] Description { get; set; } = new string[] { "LZSS Compression" };
public string[] Extension { get; set; } = new string[] { "*.lzs", "*.lzss" };
public bool Identify(Stream stream)
public bool Identify(Stream stream, string fileName)
{
using (var reader = new FileReader(stream, true))
{

View file

@ -13,7 +13,7 @@ namespace Toolbox.Library
public string[] Description { get; set; } = new string[] { "MIO0" };
public string[] Extension { get; set; } = new string[] { "*.mio0" };
public bool Identify(Stream stream)
public bool Identify(Stream stream, string fileName)
{
using (var reader = new FileReader(stream, true))
{

View file

@ -15,7 +15,7 @@ namespace Toolbox.Library
public string[] Description { get; set; } = new string[] { "Yay0" };
public string[] Extension { get; set; } = new string[] { "*.yay0" };
public bool Identify(Stream stream)
public bool Identify(Stream stream, string fileName)
{
using (var reader = new FileReader(stream, true))
{

View file

@ -13,7 +13,9 @@ namespace Toolbox.Library
public string[] Description { get; set; } = new string[] { "Yaz0" };
public string[] Extension { get; set; } = new string[] { "*.yaz0", "*.szs",};
public bool Identify(Stream stream)
public override string ToString() { return "Yaz0"; }
public bool Identify(Stream stream, string fileName)
{
using (var reader = new FileReader(stream, true))
{

View file

@ -13,7 +13,7 @@ namespace Toolbox.Library
public string[] Description { get; set; } = new string[] { "ZLIB Compression (ZCMP)" };
public string[] Extension { get; set; } = new string[] { "*.cmp" };
public bool Identify(Stream stream)
public bool Identify(Stream stream, string fileName)
{
using (var reader = new FileReader(stream, true))
{

View file

@ -0,0 +1,63 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.IO.Compression;
using System.Threading.Tasks;
using Toolbox.Library.IO;
namespace Toolbox.Library
{
public class Zlib : ICompressionFormat
{
public string[] Description { get; set; } = new string[] { "ZLIB Compressed" };
public string[] Extension { get; set; } = new string[] { "*.z", "*.zlib", };
private long startPosition = 0;
public override string ToString() { return "Zlib"; }
public bool Identify(Stream stream, string fileName)
{
using (var reader = new FileReader(stream, true))
{
startPosition = stream.Position;
reader.SetByteOrder(true);
ushort magicNumber = reader.ReadUInt16();
// reader.Position = stream.Position + 4;
ushort magicNumber2 = reader.ReadUInt16();
//Check 2 cases which the file is zlibbed.
//One is that it is compressed with magic at start
//Another is a size (uint) then magic
bool IsValid = magicNumber == 0x789C || magicNumber == 0x78DA;
bool IsValid2 = magicNumber2 == 0x789C || magicNumber2 == 0x78DA;
if (IsValid2)
startPosition = stream.Position + 4;
return IsValid || IsValid2;
}
}
public bool CanCompress { get; } = true;
public Stream Decompress(Stream stream)
{
stream.Position = startPosition;
var data = STLibraryCompression.ZLIB.Decompress(stream.ToArray());
return new MemoryStream(data);
}
public Stream Compress(Stream stream)
{
stream.Position = startPosition;
var data = STLibraryCompression.ZLIB.Compress(stream.ToArray());
return new MemoryStream(data);
}
}
}

View file

@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.IO.Compression;
using System.Threading.Tasks;
using Toolbox.Library.IO;
namespace Toolbox.Library
{
public class ZlibGZ : ICompressionFormat
{
public bool IsBigEndian = true;
public string[] Description { get; set; } = new string[] { "ZLIB GZ" };
public string[] Extension { get; set; } = new string[] { "*.gz", };
public bool Identify(Stream stream, string fileName)
{
if (Utils.GetExtension(fileName) != ".gz")
return false;
return STLibraryCompression.ZLIB_GZ.IsCompressed(stream);
}
public bool CanCompress { get; } = true;
public Stream Decompress(Stream stream)
{
return STLibraryCompression.ZLIB_GZ.Decompress(stream);
}
public Stream Compress(Stream stream)
{
return STLibraryCompression.ZLIB_GZ.Compress(stream, IsBigEndian);
}
}
}

View file

@ -0,0 +1,61 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.IO.Compression;
using System.Threading.Tasks;
using Toolbox.Library.IO;
namespace Toolbox.Library
{
public class Zstb : ICompressionFormat
{
public string[] Description { get; set; } = new string[] { "ZSTD" };
public string[] Extension { get; set; } = new string[] { "*.zstd", };
public override string ToString() { return "ZSTD"; }
public bool Identify(Stream stream, string fileName)
{
using (var reader = new FileReader(stream, true))
{
uint magic = reader.ReadUInt32();
return magic == 0x28B52FFD || magic == 0xFD2FB528;
}
}
public bool CanCompress { get; } = true;
public Stream Decompress(Stream stream)
{
return new MemoryStream(SDecompress(stream.ToArray()));
}
public Stream Compress(Stream stream)
{
return new MemoryStream(SCompress(stream.ToArray()));
}
public static byte[] SDecompress(byte[] b)
{
using (var decompressor = new ZstdNet.Decompressor())
{
return decompressor.Unwrap(b);
}
}
public static byte[] SDecompress(byte[] b, int MaxDecompressedSize)
{
using (var decompressor = new ZstdNet.Decompressor())
{
return decompressor.Unwrap(b, MaxDecompressedSize);
}
}
public static byte[] SCompress(byte[] b)
{
using (var compressor = new ZstdNet.Compressor())
{
return compressor.Wrap(b);
}
}
}
}

View file

@ -9,13 +9,17 @@ using K4os.Compression.LZ4.Streams;
namespace Toolbox.Library
{
public class LZ4F : ICompressionFormat
public class lz4 : ICompressionFormat
{
public string[] Description { get; set; } = new string[] { "LZ4F Compression" };
public string[] Extension { get; set; } = new string[] { "*.cmp", "*.lz4f" };
public string[] Description { get; set; } = new string[] { "LZ4 Compression" };
public string[] Extension { get; set; } = new string[] { "*.lz4" };
public bool Identify(Stream stream)
public override string ToString() { return "lz4"; }
public bool Identify(Stream stream, string fileName)
{
return false;
using (var reader = new FileReader(stream, true))
{
uint DecompressedSize = reader.ReadUInt32();
@ -44,16 +48,11 @@ namespace Toolbox.Library
public Stream Compress(Stream stream)
{
var mem = new MemoryStream();
using (var writer = new FileWriter(mem))
using (var source = LZ4Stream.Encode(stream, null, true))
{
var data = stream.ToArray();
writer.Write(data.Length);
byte[] buffer = LZ4.Frame.LZ4Frame.Compress(new MemoryStream(data),
LZ4.Frame.LZ4MaxBlockSize.MB1, true, true, false, true, false);
writer.Write(buffer, 0, buffer.Length);
source.CopyTo(mem);
}
return stream;
return mem;
}
}
}

View file

@ -20,44 +20,15 @@ namespace Toolbox.Library.IO
if (format.IFileInfo != null)
Alignment = format.IFileInfo.Alignment;
switch (format.IFileInfo.CompressionType)
{
case CompressionType.Yaz0:
return EveryFileExplorer.YAZ0.Compress(data, 3, (uint)Alignment);
case CompressionType.Zstb:
return ZSTD.Compress(data);
case CompressionType.Zlib:
return ZLIB.Compress(data);
case CompressionType.None:
return data;
default:
return data;
}
var FileCompression = format.IFileInfo.FileCompression;
if (FileCompression == null) return data;
return FileCompression.Compress(new MemoryStream(data)).ToArray();
}
public class ZSTD
{
public static byte[] Decompress(byte[] b)
{
using (var decompressor = new ZstdNet.Decompressor())
{
return decompressor.Unwrap(b);
}
}
public static byte[] Decompress(byte[] b, int MaxDecompressedSize)
{
using (var decompressor = new ZstdNet.Decompressor())
{
return decompressor.Unwrap(b, MaxDecompressedSize);
}
}
public static byte[] Compress(byte[] b)
{
using (var compressor = new ZstdNet.Compressor())
{
return compressor.Wrap(b);
}
}
}
@ -65,27 +36,29 @@ namespace Toolbox.Library.IO
{
public static bool IsCompressed(Stream stream)
{
if (stream.Length < 32) return false;
using (var reader = new FileReader(stream, true))
{
reader.ByteOrder = Syroot.BinaryData.ByteOrder.BigEndian;
reader.Position = 0;
uint chunkSize = reader.ReadUInt32();
uint chunkCount = reader.ReadUInt32();
uint unk = reader.ReadUInt32();
if (reader.BaseStream.Length > 4 + (chunkCount * 4))
uint decompressedSize = reader.ReadUInt32();
if (reader.BaseStream.Length > 8 + (chunkCount * 4) + 128)
{
uint[] chunkSizes = reader.ReadUInt32s((int)chunkCount); //Not very sure about this
uint[] chunkSizes = reader.ReadUInt32s((int)chunkCount);
reader.Align(128);
while (!reader.EndOfStream)
{
//Now search for zlibbed chunks
uint size = reader.ReadUInt32();
long pos = reader.Position;
ushort magic = reader.ReadUInt16();
reader.Position = 0;
if (magic == 0x78da)
return true;
}
else
return false;
}
reader.Position = 0;
@ -99,11 +72,11 @@ namespace Toolbox.Library.IO
using (var reader = new FileReader(stream, true))
{
reader.ByteOrder = Syroot.BinaryData.ByteOrder.BigEndian;
uint unk = reader.ReadUInt32();
try
{
uint chunkSize = reader.ReadUInt32();
uint chunkCount = reader.ReadUInt32();
uint unk2 = reader.ReadUInt32();
uint decompressedSize = reader.ReadUInt32();
uint[] chunkSizes = reader.ReadUInt32s((int)chunkCount); //Not very sure about this
reader.Align(128);
@ -141,11 +114,54 @@ namespace Toolbox.Library.IO
return null;
}
public static Stream Compress(Stream stream, bool isBigEndian = true)
{
uint decompSize = (uint)stream.Length;
uint[] section_sizes;
uint sectionCount = 0;
var mem = new MemoryStream();
using (var reader = new FileReader(stream, true))
using (var writer = new FileWriter(mem, true))
{
writer.SetByteOrder(isBigEndian);
if (!(decompSize % 0x10000 != 0))
sectionCount = decompSize / 0x10000;
else
sectionCount = (decompSize / 0x10000) + 1;
writer.Write(0x10000);
writer.Write(sectionCount);
writer.Write(decompSize);
writer.Write(new uint[sectionCount]);
writer.Align(128);
reader.SeekBegin(0);
section_sizes = new uint[sectionCount];
for (int i = 0; i < sectionCount; i++)
{
byte[] chunk = ZLIB.Compress(reader.ReadBytes(0x10000));
section_sizes[i] = (uint)chunk.Length;
writer.Write(chunk.Length);
writer.Write(chunk);
writer.Align(128);
}
writer.SeekBegin(12);
for (int i = 0; i < sectionCount; i++)
writer.Write(section_sizes[i] + 4);
}
return mem;
}
}
public class ZLIB
{
public static byte[] Decompress(byte[] b)
public static byte[] Decompress(byte[] b, bool hasMagic = true)
{
using (var br = new FileReader(new MemoryStream(b), true))
{
@ -156,7 +172,8 @@ namespace Toolbox.Library.IO
else
{
var ms = new System.IO.MemoryStream();
br.BaseStream.Position = 2;
if (hasMagic)
br.Position = 2;
using (var ds = new DeflateStream(new MemoryStream(br.ReadBytes((int)br.BaseStream.Length - 6)), CompressionMode.Decompress))
ds.CopyTo(ms);
return ms.ToArray();
@ -231,8 +248,11 @@ namespace Toolbox.Library.IO
//Mario Tennis Aces Custom compression
public class MTA_CUSTOM
{
[DllImport("Lib/LibTennis.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void DecompressBuffer(IntPtr output, IntPtr input, uint len);
[DllImport("Lib/LibTennis32.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void DecompressBuffer32(IntPtr output, IntPtr input, uint len);
[DllImport("Lib/LibTennis64.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void DecompressBuffer64(IntPtr output, IntPtr input, uint len);
public unsafe byte[] Decompress(byte[] input, uint decompressedLength)
{
@ -240,8 +260,10 @@ namespace Toolbox.Library.IO
{
fixed (byte* inputPtr = input)
{
DecompressBuffer((IntPtr)outputPtr, (IntPtr)inputPtr, decompressedLength);
if (Environment.Is64BitProcess)
DecompressBuffer64((IntPtr)outputPtr, (IntPtr)inputPtr, decompressedLength);
else
DecompressBuffer32((IntPtr)outputPtr, (IntPtr)inputPtr, decompressedLength);
// Decompress(outputPtr, inputPtr, decompressedLength);
}
@ -277,9 +299,7 @@ namespace Toolbox.Library.IO
for (int i = 0; i < 8; i++)
*output++ = *data++;
var checkFinished = CheckFinished(data, end);
data = checkFinished.data;
end = checkFinished.end;
CheckFinished(ref data, ref end);
}
flag |= 0x800000;
@ -302,11 +322,7 @@ namespace Toolbox.Library.IO
flag <<= 1;
if (flag == 0)
{
var checkFinished2 = CheckFinished(data, end);
data = checkFinished2.data;
end = checkFinished2.end;
}
CheckFinished(ref data, ref end);
int op_ofs = (data[0] >> 4) | (data[1] << 4);
int op_len = data[0] & 0xF;
@ -329,14 +345,7 @@ namespace Toolbox.Library.IO
op_len = op_len_ext + add_len;
if (op_ofs >= 2)
{
var loop1Data = Loop1(flag, op_len, chunk, data, output);
flag = loop1Data.flag;
op_len = loop1Data.op_len;
chunk = loop1Data.chunk;
data = loop1Data.data;
output = loop1Data.output;
}
Loop1(ref flag, ref op_len, ref chunk, ref data, ref output);
}
else
{
@ -344,41 +353,19 @@ namespace Toolbox.Library.IO
op_len = op_len_ext;
if (op_ofs >= 2)
{
var loop1Data = Loop1(flag, op_len, chunk, data, output);
flag = loop1Data.flag;
op_len = loop1Data.op_len;
chunk = loop1Data.chunk;
data = loop1Data.data;
output = loop1Data.output;
Loop1(ref flag, ref op_len, ref chunk, ref data, ref output);
}
}
}
var loop2Data2 = Loop2(flag, op_len, data, output, chunk);
flag = loop2Data2.flag;
op_len = loop2Data2.op_len;
chunk = loop2Data2.chunk;
data = loop2Data2.data;
output = loop2Data2.output;
Loop2(ref flag, ref op_len, ref data, ref output, ref chunk);
}
}
var endOp = EndOperation(data, end);
data = endOp.data;
end = endOp.end;
EndOperation(ref data, ref end);
}
private unsafe class Data
{
public uint flag;
public int op_len;
public byte* chunk;
public byte* data;
public byte* output;
public byte* end;
}
unsafe Data Loop1(uint flag, int op_len, byte* chunk, byte* data, byte* output)
unsafe void Loop1(ref uint flag, ref int op_len, ref byte* chunk, ref byte* data, ref byte* output)
{
if ((((byte)*chunk ^ (byte)*output) & 1) == 0)
{
@ -436,10 +423,10 @@ namespace Toolbox.Library.IO
}
}
return Loop2(flag, op_len, data, output, chunk);
Loop2(ref flag, ref op_len, ref data, ref output, ref chunk);
}
unsafe Data Loop2(uint flag, int op_len, byte* data, byte* output, byte* chunk)
unsafe void Loop2(ref uint flag, ref int op_len, ref byte* data, ref byte* output, ref byte* chunk)
{
int masked_len = op_len & 7;
byte* out_ptr = output;
@ -468,42 +455,21 @@ namespace Toolbox.Library.IO
flag <<= 1;
*output++ = *data++;
}
return new Data()
{
flag = flag,
op_len = op_len,
data = data,
output = output,
chunk = chunk,
};
}
unsafe Data CheckFinished(byte* data, byte* end)
unsafe void CheckFinished(ref byte* data, ref byte* end)
{
if (data >= end)
return EndOperation(data, end);
return new Data()
{
data = data,
end = end,
};
EndOperation(ref data, ref end);
}
unsafe Data EndOperation(byte* data, byte* end)
unsafe void EndOperation(ref byte* data, ref byte* end)
{
byte* ext = end + 0x20;
if (data < ext)
do
*end-- = *--ext;
while (data < ext);
return new Data()
{
data = data,
end = end,
};
}
}

View file

@ -329,7 +329,6 @@ namespace Toolbox.Library
}
catch (Exception)
{
// Invalid hex format.
return false;
}
}

View file

@ -26,37 +26,94 @@ namespace Toolbox.Library
Dictionary<string, Vertex> VertexSkinSources = new Dictionary<string, Vertex>();
Dictionary<string, Matrix4> MatrixSkinSources = new Dictionary<string, Matrix4>();
private Matrix4 GlobalTransform = Matrix4.Identity;
public bool LoadFile(string FileName)
{
GlobalTransform = Matrix4.Identity;
COLLADA collada = COLLADA.Load(FileName);
//Check axis up
if (collada.asset != null)
{
switch (collada.asset.up_axis)
{
case UpAxisType.X_UP:
GlobalTransform = Matrix4.CreateRotationX(90);
break;
case UpAxisType.Y_UP:
GlobalTransform = Matrix4.CreateRotationY(90);
break;
case UpAxisType.Z_UP:
GlobalTransform = Matrix4.CreateRotationZ(90);
break;
}
if (collada.asset.unit != null)
{
var amount = collada.asset.unit.meter;
var type = collada.asset.unit.name;
if (type == "meter")
{
}
else if (type == "centimeter")
{
}
}
}
foreach (var item in collada.Items)
{
if (item is library_geometries)
{
LoadGeometry((library_geometries)item);
}
if (item is library_images)
LoadImages((library_images)item);
if (item is library_controllers)
LoadControllers((library_controllers)item);
if (item is library_nodes)
LoadNodes((library_nodes)item);
if (item is library_visual_scenes)
LoadVisualScenes((library_visual_scenes)item);
}
return true;
}
private void SetControllers(COLLADA collada)
private void LoadVisualScenes(library_visual_scenes nodes)
{
}
private void LoadGeometry(library_geometries Geometries)
private void LoadNodes(library_nodes nodes)
{
foreach (var geom in Geometries.geometry)
}
private void LoadControllers(library_controllers controllers)
{
}
private void LoadMaterials(library_materials materials)
{
}
private void LoadImages(library_images images)
{
}
private void LoadGeometry(library_geometries geometries)
{
foreach (var geom in geometries.geometry)
{
var mesh = geom.Item as mesh;
if (mesh == null)
continue;
Console.WriteLine(geom.name);
foreach (var source in mesh.source)
{
var float_array = source.Item as float_array;
@ -71,6 +128,11 @@ namespace Toolbox.Library
}
}
public bool ExportFile(string FileName, List<STGenericObject> meshes, STSkeleton skeleton = null)
{
return false;
}
private List<STGenericObject> CreateGenericObjects(string Name, library_geometries Geometries)
{
List<STGenericObject> objects = new List<STGenericObject>();

View file

@ -22,7 +22,7 @@ namespace Toolbox.Library
public Dictionary<string, uint> NameTables { get; set; }
public Dictionary<uint, uint> Crc32Tables { get; set; }
private int ParseSize(string FilePath, byte[] Data = null, bool IsYaz0Compressed = false, bool Force = false)
private int ParseSize(string FilePath, System.IO.Stream Data = null, bool IsYaz0Compressed = false, bool Force = false)
{
var size = new RSTB.SizeCalculator().CalculateFileSize(FilePath, Data, IsWiiU, IsYaz0Compressed, Force);
if (size == 0)
@ -36,7 +36,7 @@ namespace Toolbox.Library
return size;
}
public void SetEntry(string FileName, byte[] Data = null, bool IsYaz0Compressed = false, bool Force = false)
public void SetEntry(string FileName, System.IO.Stream Data = null, bool IsYaz0Compressed = false, bool Force = false)
{
uint OldSize = GetSize(FileName);
uint NewSize = (uint)ParseSize(FileName, Data, IsYaz0Compressed, Force) + 8192; //Add an additional set of bytes for some room
@ -264,12 +264,12 @@ namespace Toolbox.Library
float.TryParse(value, out output);
}
public int CalculateFileSize(string FileName, byte[] Data, bool IsWiiU, bool IsYaz0Compressed, bool Force)
public int CalculateFileSize(string FileName, System.IO.Stream Data, bool IsWiiU, bool IsYaz0Compressed, bool Force)
{
return CalculateFileSizeByExtension(FileName, Data, IsWiiU, System.IO.Path.GetExtension(FileName), IsYaz0Compressed, Force);
}
private int CalculateFileSizeByExtension(string FileName, byte[] Data, bool WiiU, string Ext, bool IsYaz0Compressed, bool Force = false)
private int CalculateFileSizeByExtension(string FileName, System.IO.Stream Data, bool WiiU, string Ext, bool IsYaz0Compressed, bool Force = false)
{
int Size = 0;
if (System.IO.File.Exists(FileName))
@ -292,7 +292,7 @@ namespace Toolbox.Library
{
if (IsYaz0Compressed)
{
using (var reader = new FileReader(new System.IO.MemoryStream(Data)))
using (var reader = new FileReader(Data, true))
{
reader.ByteOrder = Syroot.BinaryData.ByteOrder.BigEndian;
reader.Seek(4, System.IO.SeekOrigin.Begin);
@ -301,11 +301,11 @@ namespace Toolbox.Library
}
else
{
Size = Data.Length;
Size = (int)Data.Length;
}
}
byte[] FileData = Data;
byte[] FileData = Data.ToBytes();
Size = (Size + 31) & -32;
string ActualExt = Ext.Replace(".s", ".").Remove(0,1);
@ -317,7 +317,7 @@ namespace Toolbox.Library
if (System.IO.File.Exists(FileName))
FileData = EveryFileExplorer.YAZ0.Decompress(FileName);
else if (Data != null)
FileData = EveryFileExplorer.YAZ0.Decompress(Data);
FileData = EveryFileExplorer.YAZ0.Decompress(FileData);
}
if (WiiU)

View file

@ -50,7 +50,7 @@ namespace Toolbox.Library
private IFileFormat OpenFile()
{
return STFileLoader.OpenFileFormat(new FileStream(filePath, FileMode.Open, FileAccess.Read),
filePath, null, true);
filePath, true);
}
public override void OnDoubleMouseClick(TreeView treeview)

View file

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Toolbox.Library
{
/// <summary>
/// A class that generates treenodes on expand based on it's children
/// </summary>
public class VirtualFileTreeNode
{
}
}

View file

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Toolbox.Library
{
public class VirtualTreeNode
{
public VirtualTreeNode Parent;
public List<VirtualTreeNode> Children;
}
}

View file

@ -23,7 +23,16 @@ namespace Toolbox.Library
public static Type[] GetCompressionFormats()
{
List<Type> Formats = new List<Type>();
Formats.Add(typeof(Gzip));
Formats.Add(typeof(lz4));
Formats.Add(typeof(LZ4F));
Formats.Add(typeof(LZSS));
Formats.Add(typeof(YAY0));
Formats.Add(typeof(Yaz0));
Formats.Add(typeof(Zlib));
Formats.Add(typeof(ZlibGZ));
Formats.Add(typeof(Zstb));
return Formats.ToArray();
}
}

View file

@ -226,6 +226,7 @@ namespace Toolbox.Library
v.uv2 = (v.uv2 * Scale) + Translate;
}
}
public void CalculateTangentBitangent(bool UseUVLayer2)
{
if (vertices.Count < 3)

View file

@ -27,6 +27,7 @@ namespace Toolbox.Library.IO
{
using (var fileStream = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite, FileShare.Write))
{
stream.Position = 0;
stream.CopyTo(fileStream);
}
}

View file

@ -19,8 +19,8 @@ namespace Toolbox.Library.IO
this.Position = 0;
}
public FileReader(string fileName)
: this(new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
public FileReader(string fileName, bool leaveOpen = false)
: this(new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite), leaveOpen)
{
this.Position = 0;
}
@ -30,6 +30,8 @@ namespace Toolbox.Library.IO
this.Position = 0;
}
public bool IsBigEndian => ByteOrder == ByteOrder.BigEndian;
//Checks signature (no stream advancement)
public bool CheckSignature(int length, string Identifier, long position = 0)
{

View file

@ -100,6 +100,20 @@ namespace Toolbox.Library.IO
SeekBegin(pos + fixedSize);
}
public void Write(object value, long pos)
{
using (TemporarySeek(pos, SeekOrigin.Begin)) {
if (value is uint) Write((uint)value);
else if (value is int) Write((int)value);
else if (value is long) Write((long)value);
else if (value is ulong) Write((ulong)value);
else if (value is ushort) Write((ushort)value);
else if (value is short) Write((short)value);
else if (value is sbyte) Write((sbyte)value);
else if (value is byte) Write((byte)value);
}
}
//Writes the total size of a section as a uint.
public void WriteSectionSizeU32(long position, long startPosition, long endPosition)
{

View file

@ -20,10 +20,10 @@ namespace Toolbox.Library.IO
/// <param name="Compressed">If the file is being compressed or not</param>
/// <param name="CompType">The type of <see cref="CompressionType"/> being used</param>
/// <returns></returns>
public static TreeNode GetNodeFileFormat(string FileName, byte[] data = null, bool InArchive = false,
TreeNode archiveNode = null, bool LeaveStreamOpen = false, bool Compressed = false, CompressionType CompType = 0)
public static TreeNode GetNodeFileFormat(string FileName, bool InArchive = false,
bool LeaveStreamOpen = false, bool Compressed = false, ICompressionFormat CompressionFormat = null)
{
IFileFormat format = OpenFileFormat(FileName, data, LeaveStreamOpen, InArchive, archiveNode);
IFileFormat format = OpenFileFormat(FileName, LeaveStreamOpen, InArchive);
if (format is TreeNode)
return (TreeNode)format;
@ -76,7 +76,7 @@ namespace Toolbox.Library.IO
if (fileFormat.Identify(stream) && fileFormat.GetType() == type)
{
fileFormat.IFileInfo = new IFileInfo();
return OpenFileFormat(FileName, data);
return OpenFileFormat(new MemoryStream(data), FileName);
}
}
}
@ -97,7 +97,7 @@ namespace Toolbox.Library.IO
foreach (IFileFormat fileFormat in FileManager.GetFileFormats())
{
if (fileFormat.GetType() == FileType)
return OpenFileFormat(FileName, data);
return OpenFileFormat(stream, FileName);
}
return null;
@ -139,9 +139,9 @@ namespace Toolbox.Library.IO
if (MagicHex == 0x28B52FFD || MagicHex == 0xFD2FB528)
{
if (data != null)
return STLibraryCompression.ZSTD.Decompress(data);
return Zstb.SDecompress(data);
else
return STLibraryCompression.ZSTD.Decompress(File.ReadAllBytes(FileName));
return Zstb.SDecompress(File.ReadAllBytes(FileName));
}
return data;
@ -157,17 +157,11 @@ namespace Toolbox.Library.IO
/// <param name="Compressed">If the file is being compressed or not</param>
/// <param name="CompType">The type of <see cref="CompressionType"/> being used</param>
/// <returns></returns>
public static IFileFormat OpenFileFormat(string FileName, byte[] data = null, bool LeaveStreamOpen = false, bool InArchive = false,
TreeNode archiveNode = null, bool Compressed = false, CompressionType CompType = 0, uint DecompressedSize = 0, uint CompressedSize = 0)
public static IFileFormat OpenFileFormat(string FileName, bool LeaveStreamOpen = false, bool InArchive = false,
bool Compressed = false, ICompressionFormat CompressionFormat = null, uint DecompressedSize = 0, uint CompressedSize = 0)
{
Stream stream;
if (data != null)
stream = new MemoryStream(data);
else
stream = File.OpenRead(FileName);
return OpenFileFormat(stream, FileName, data, LeaveStreamOpen, InArchive,
archiveNode, Compressed, CompType, DecompressedSize, CompressedSize);
return OpenFileFormat(File.OpenRead(FileName), FileName, LeaveStreamOpen, InArchive,
Compressed, CompressionFormat, DecompressedSize, CompressedSize);
}
/// <summary>
@ -176,185 +170,37 @@ namespace Toolbox.Library.IO
/// <param name="FileName">The name of the file</param>
/// <param name="data">The byte array of the data</param>
/// <param name="InArchive">If the file is in an archive so it can be saved back</param>
/// <param name="archiveNode">The node being replaced from an archive</param>
/// <param name="Compressed">If the file is being compressed or not</param>
/// <param name="CompType">The type of <see cref="CompressionType"/> being used</param>
/// <param name="CompressionFormat">The type of <see cref="ICompressionFormat"/> being used</param>
/// <returns></returns>
public static IFileFormat OpenFileFormat(Stream stream, string FileName, byte[] data = null, bool LeaveStreamOpen = false, bool InArchive = false,
TreeNode archiveNode = null, bool Compressed = false, CompressionType CompType = 0, uint DecompressedSize = 0, uint CompressedSize = 0)
public static IFileFormat OpenFileFormat(Stream stream, string FileName, bool LeaveStreamOpen = false, bool InArchive = false,
bool Compressed = false, ICompressionFormat CompressionFormat = null, long DecompressedSize = 0, long CompressedSize = 0)
{
uint DecompressedFileSize = 0;
uint CompressedFileSize = 0;
if (!Compressed)
DecompressedSize = stream.Length;
using (var fileReader = new FileReader(stream, true))
long streamStartPos = stream.Position;
//Check all supported compression formats and decompress. Then loop back
if (!Compressed)
{
if (CompType == CompressionType.None)
DecompressedFileSize = (uint)fileReader.BaseStream.Length;
if (CompType != CompressionType.None)
CompressedFileSize = (uint)fileReader.BaseStream.Length;
if (fileReader.BaseStream.Length <= 4)
{
fileReader.Close();
fileReader.Dispose();
return null;
}
Cursor.Current = Cursors.WaitCursor;
fileReader.ByteOrder = ByteOrder.BigEndian;
uint MagicHex = fileReader.ReadUInt32();
string Magic = fileReader.ReadMagic(0, 4);
fileReader.Position = 0;
ushort MagicHex2 = fileReader.ReadUInt16();
//Another hacky magic check if decomp size is first
fileReader.Position = 4;
ushort MagicHex3 = fileReader.ReadUInt16();
//Note this method will soon be how all compression formats are handled rather than being checked here
foreach (ICompressionFormat compressionFormat in FileManager.GetCompressionFormats())
{
if (compressionFormat.Identify(stream))
stream.Position = streamStartPos;
if (compressionFormat.Identify(stream, FileName))
{
stream.Position = streamStartPos;
stream = compressionFormat.Decompress(stream);
CompressedSize = stream.Length;
return OpenFileFormat(stream, FileName, LeaveStreamOpen, InArchive,
true, compressionFormat, DecompressedSize, CompressedSize);
}
}
}
if (Magic == "Yaz0")
{
data = EveryFileExplorer.YAZ0.Decompress(stream.ToArray());
return OpenFileFormat(FileName, data, LeaveStreamOpen, InArchive, archiveNode, true,
CompressionType.Yaz0, DecompressedFileSize, CompressedFileSize);
}
if (Path.GetExtension(FileName) == ".cbtex")
{
fileReader.Position = 0;
byte compType = fileReader.ReadByte();
if (compType == 0x50)
{
if (data == null)
data = File.ReadAllBytes(FileName);
fileReader.ByteOrder = Syroot.BinaryData.ByteOrder.BigEndian;
fileReader.Seek(4, System.IO.SeekOrigin.Begin);
uint decompSize = fileReader.ReadUInt32();
uint compSize = (uint)fileReader.BaseStream.Length - 8;
var comp = new STLibraryCompression.MTA_CUSTOM();
data = comp.Decompress(data, decompSize);
return OpenFileFormat(FileName, data, LeaveStreamOpen, InArchive, archiveNode, true,
CompressionType.MarioTennisCustom, DecompressedFileSize, CompressedFileSize);
}
fileReader.Position = 0;
}
if (Path.GetExtension(FileName) == ".lz")
{
if (data == null)
data = File.ReadAllBytes(FileName);
data = LZ77_WII.Decompress(fileReader.getSection(16, data.Length - 16));
return OpenFileFormat(FileName, data, LeaveStreamOpen, InArchive, archiveNode, true,
CompressionType.Yaz0, DecompressedFileSize, CompressedFileSize);
}
if (MagicHex == 0x28B52FFD || MagicHex == 0xFD2FB528)
{
if (data != null)
data = STLibraryCompression.ZSTD.Decompress(fileReader.getSection(0, data.Length));
else
data = STLibraryCompression.ZSTD.Decompress(File.ReadAllBytes(FileName));
return OpenFileFormat(FileName, data, LeaveStreamOpen, InArchive, archiveNode, true,
CompressionType.Zstb, DecompressedFileSize, CompressedFileSize);
}
if (Magic == "ZCMP" || MagicHex2 == 0x789C || MagicHex2 == 0x78DA || Path.GetExtension(FileName) == ".z" && CompType == CompressionType.None)
{
if (data == null)
data = File.ReadAllBytes(FileName);
data = STLibraryCompression.ZLIB.Decompress(data);
return OpenFileFormat(FileName, data, LeaveStreamOpen, InArchive, archiveNode, true,
CompressionType.Zlib, DecompressedFileSize, CompressedFileSize);
}
if (MagicHex3 == 0x789C || MagicHex3 == 0x78DA && CompType == CompressionType.None)
{
if (data == null)
data = File.ReadAllBytes(FileName);
fileReader.Position = 0;
int OuSize = fileReader.ReadInt32();
int InSize = data.Length - 4;
data = STLibraryCompression.ZLIB.Decompress(fileReader.getSection(4, InSize));
return OpenFileFormat(FileName, data, LeaveStreamOpen, InArchive, archiveNode, true,
CompressionType.Zlib, DecompressedFileSize, CompressedFileSize);
}
if (Path.GetExtension(FileName) == ".carc" && CompType == CompressionType.None)
{
if (data == null)
data = File.ReadAllBytes(FileName);
data = STLibraryCompression.ZLIB.Decompress(fileReader.getSection(0x10, data.Length - 0x10));
return OpenFileFormat(FileName, data, LeaveStreamOpen, InArchive, archiveNode, true,
CompressionType.Zlib, DecompressedFileSize, CompressedFileSize);
}
if (Magic == "ZLIB")
{
if (data == null)
data = File.ReadAllBytes(FileName);
data = STLibraryCompression.GZIP.Decompress(fileReader.getSection(64, data.Length - 64));
return OpenFileFormat(FileName, data, LeaveStreamOpen, InArchive, archiveNode, true,
CompressionType.Zlib, DecompressedFileSize, CompressedFileSize);
}
if (MagicHex == 0x1f8b0808 || MagicHex2 == 0x1f8b && CompType == CompressionType.None)
{
if (data == null)
data = File.ReadAllBytes(FileName);
data = STLibraryCompression.GZIP.Decompress(data);
return OpenFileFormat(FileName, data, LeaveStreamOpen, InArchive, archiveNode, true,
CompressionType.Gzip, DecompressedFileSize, CompressedFileSize);
}
if (MagicHex == 0x184D2204)
{
if (data == null)
data = File.ReadAllBytes(FileName);
data = STLibraryCompression.Type_LZ4.Decompress(data);
return OpenFileFormat(FileName, data, LeaveStreamOpen, InArchive, archiveNode, true,
CompressionType.Lz4, DecompressedFileSize, CompressedFileSize);
}
if (Path.GetExtension(FileName) == ".lz" && CompType == CompressionType.None)
{
if (data == null)
data = File.ReadAllBytes(FileName);
data = STLibraryCompression.LZ77.Decompress(fileReader.getSection(16, data.Length - 16));
return OpenFileFormat(FileName, data, LeaveStreamOpen, InArchive, archiveNode, true,
CompressionType.Zlib, DecompressedFileSize, CompressedFileSize);
}
if (Path.GetExtension(FileName) == ".cmp" && CompType == CompressionType.None)
{
if (stream != null)
data = stream.ToArray();
if (data == null)
data = File.ReadAllBytes(FileName);
fileReader.Position = 0;
int OuSize = fileReader.ReadInt32();
int InSize = data.Length - 4;
data = STLibraryCompression.Type_LZ4F.Decompress(fileReader.getSection(4, InSize));
return OpenFileFormat(FileName, data, InArchive, LeaveStreamOpen, archiveNode, true,
CompressionType.Lz4f, DecompressedFileSize, CompressedFileSize);
}
}
stream.Position = streamStartPos;
foreach (IFileFormat fileFormat in FileManager.GetFileFormats())
{
//Set the file name so we can check it's extension in the identifier.
@ -365,9 +211,9 @@ namespace Toolbox.Library.IO
if (fileFormat.Identify(stream))
{
fileFormat.IFileInfo = new IFileInfo();
fileFormat.IFileInfo.DecompressedSize = DecompressedFileSize;
fileFormat.IFileInfo.CompressedSize = CompressedFileSize;
return SetFileFormat(fileFormat, FileName, stream, LeaveStreamOpen, InArchive, archiveNode, Compressed, CompType);
fileFormat.IFileInfo.DecompressedSize = (uint)DecompressedSize;
fileFormat.IFileInfo.CompressedSize = (uint)CompressedSize;
return SetFileFormat(fileFormat, FileName, stream, LeaveStreamOpen, InArchive, Compressed, CompressionFormat);
}
}
@ -375,27 +221,15 @@ namespace Toolbox.Library.IO
}
private static IFileFormat SetFileFormat(IFileFormat fileFormat, string FileName, Stream stream, bool LeaveStreamOpen = false, bool InArchive = false,
TreeNode archiveNode = null, bool Compressed = false, CompressionType CompType = 0)
bool Compressed = false, ICompressionFormat FileCompression = null)
{
fileFormat.IFileInfo.CompressionType = CompType;
fileFormat.IFileInfo.FileCompression = FileCompression;
fileFormat.IFileInfo.FileIsCompressed = Compressed;
fileFormat.FileName = Path.GetFileName(FileName);
fileFormat.FilePath = FileName;
fileFormat.IFileInfo.InArchive = InArchive;
fileFormat.IFileInfo.FileIsCompressed = Compressed;
if (Compressed)
fileFormat.IFileInfo.CompressionType = CompType;
fileFormat.Load(stream);
if (fileFormat is TreeNode)
{
if (archiveNode != null)
{
((TreeNode)fileFormat).Text = archiveNode.Text;
((TreeNode)fileFormat).ImageKey = archiveNode.ImageKey;
((TreeNode)fileFormat).SelectedImageKey = archiveNode.SelectedImageKey;
}
}
//After file has been loaded and read, we'll dispose unless left open
if (fileFormat is ILeaveOpenOnLoad) {

View file

@ -33,25 +33,28 @@ namespace Toolbox.Library.IO
//Also make compression require streams
var mem = new System.IO.MemoryStream();
FileFormat.Save(mem);
mem = new System.IO.MemoryStream(mem.ToArray());
byte[] data = mem.ToArray();
FileFormat.IFileInfo.DecompressedSize = (uint)data.Length;
FileFormat.IFileInfo.DecompressedSize = (uint)mem.Length;
data = CompressFileFormat(data,
var finalStream = CompressFileFormat(
FileFormat.IFileInfo.FileCompression,
mem,
FileFormat.IFileInfo.FileIsCompressed,
FileFormat.IFileInfo.Alignment,
FileFormat.IFileInfo.CompressionType,
FileName,
EnableDialog);
FileFormat.IFileInfo.CompressedSize = (uint)data.Length;
FileFormat.IFileInfo.CompressedSize = (uint)finalStream.Length;
finalStream.ExportToFile(FileName);
File.WriteAllBytes(FileName, data);
DetailsLog += "\n" + SatisfyFileTables(FileFormat, FileName, data,
DetailsLog += "\n" + SatisfyFileTables(FileFormat, FileName, finalStream,
FileFormat.IFileInfo.DecompressedSize,
FileFormat.IFileInfo.CompressedSize,
FileFormat.IFileInfo.FileIsCompressed);
finalStream.Flush();
finalStream.Close();
}
else
{
@ -88,7 +91,7 @@ namespace Toolbox.Library.IO
Cursor.Current = Cursors.Default;
}
private static string SatisfyFileTables(IFileFormat FileFormat, string FilePath, byte[] Data, uint DecompressedSize, uint CompressedSize, bool IsYaz0Compressed)
private static string SatisfyFileTables(IFileFormat FileFormat, string FilePath, Stream Data, uint DecompressedSize, uint CompressedSize, bool IsYaz0Compressed)
{
string FileLog = "";
@ -210,39 +213,45 @@ namespace Toolbox.Library.IO
public static void SaveFileFormat(byte[] data, bool FileIsCompressed, int Alignment,
CompressionType CompressionType, string FileName, bool EnableDialog = true, string DetailsLog = "")
public static void SaveFileFormat(byte[] data, bool FileIsCompressed, ICompressionFormat CompressionFormat,
int Alignment, string FileName, bool EnableDialog = true, string DetailsLog = "")
{
uint DecompressedSize = (uint)data.Length;
Cursor.Current = Cursors.WaitCursor;
byte[] FinalData = CompressFileFormat(data, FileIsCompressed, Alignment, CompressionType, FileName, EnableDialog);
File.WriteAllBytes(FileName, FinalData);
Stream FinalData = CompressFileFormat(CompressionFormat, new MemoryStream(data), FileIsCompressed, Alignment, FileName, EnableDialog);
FinalData.ExportToFile(FileName);
uint CompressedSize = (uint)FinalData.Length;
DetailsLog += "\n" + SatisfyFileTables(null, FileName, data,
DetailsLog += "\n" + SatisfyFileTables(null, FileName, new MemoryStream(data),
DecompressedSize,
CompressedSize,
FileIsCompressed);
FinalData.Flush();
FinalData.Close();
MessageBox.Show($"File has been saved to {FileName}", "Save Notification");
// STSaveLogDialog.Show($"File has been saved to {FileName}", "Save Notification", DetailsLog);
Cursor.Current = Cursors.Default;
}
private static byte[] CompressFileFormat(byte[] data, bool FileIsCompressed, int Alignment,
CompressionType CompressionType, string FileName, bool EnableDialog = true)
private static Stream CompressFileFormat(ICompressionFormat compressionFormat, Stream data, bool FileIsCompressed, int Alignment,
string FileName, bool EnableDialog = true)
{
string extension = Path.GetExtension(FileName);
if (extension == ".szs" || extension == ".sbfres")
{
FileIsCompressed = true;
CompressionType = CompressionType.Yaz0;
compressionFormat = new Yaz0();
}
if (compressionFormat == null)
return data;
bool CompressFile = false;
if (EnableDialog && FileIsCompressed)
{
@ -250,38 +259,17 @@ namespace Toolbox.Library.IO
CompressFile = true;
else
{
DialogResult save = MessageBox.Show($"Compress file with {CompressionType}?", "File Save", MessageBoxButtons.YesNo);
DialogResult save = MessageBox.Show($"Compress file with {compressionFormat}?", "File Save", MessageBoxButtons.YesNo);
CompressFile = (save == DialogResult.Yes);
}
}
else if (FileIsCompressed)
CompressFile = true;
Console.WriteLine($"FileIsCompressed {FileIsCompressed} CompressFile {CompressFile} CompressionType {CompressionType}");
Console.WriteLine($"FileIsCompressed {FileIsCompressed} CompressFile {CompressFile} CompressionType {compressionFormat}");
if (CompressFile)
{
switch (CompressionType)
{
case CompressionType.Yaz0:
return EveryFileExplorer.YAZ0.Compress(data, Runtime.Yaz0CompressionLevel, (uint)Alignment);
case CompressionType.Zstb:
return STLibraryCompression.ZSTD.Compress(data);
case CompressionType.Lz4:
return STLibraryCompression.Type_LZ4.Compress(data);
case CompressionType.Lz4f:
return STLibraryCompression.Type_LZ4F.Compress(data);
case CompressionType.Gzip:
return STLibraryCompression.GZIP.Compress(data);
case CompressionType.Zlib:
return STLibraryCompression.ZLIB.Compress(data, 2);
case CompressionType.None:
return data;
default:
MessageBox.Show($"Compression Type {CompressionType} not supported!!");
break;
}
}
return compressionFormat.Compress(data);
return data;
}

View file

@ -85,12 +85,12 @@ namespace Toolbox.Library
if (FileDataStream != null)
{
return STFileLoader.OpenFileFormat(FileDataStream,
IOExtensions.RemoveIllegaleFolderNameCharacters(FileName), null, true, true);
IOExtensions.RemoveIllegaleFolderNameCharacters(FileName), true, true);
}
else
{
return STFileLoader.OpenFileFormat(
IOExtensions.RemoveIllegaleFolderNameCharacters(FileName), FileData, false, true);
return STFileLoader.OpenFileFormat(new MemoryStream(FileData),
IOExtensions.RemoveIllegaleFolderNameCharacters( FileName), false, true);
}
}

View file

@ -12,7 +12,7 @@ namespace Toolbox.Library
string[] Description { get; set; }
string[] Extension { get; set; }
bool Identify(Stream stream);
bool Identify(Stream stream, string fileName);
bool CanCompress { get; }
Stream Decompress(Stream stream);

View file

@ -56,7 +56,7 @@ namespace Toolbox.Library
}
public class IFileInfo
{
public CompressionType CompressionType { get; set; }
public ICompressionFormat FileCompression { get; set; }
public IArchiveFile ArchiveParent { get; set; }
public bool FileIsCompressed { get; set; }
public bool FileIsEdited { get; set; }

View file

@ -218,23 +218,31 @@
<Compile Include="Compression\7ZIP\LZ\LzBinTree.cs" />
<Compile Include="Compression\7ZIP\LZ\LzInWindow.cs" />
<Compile Include="Compression\7ZIP\LZ\LzOutWindow.cs" />
<Compile Include="Compression\LZ4F.cs" />
<Compile Include="Compression\Formats\Gzip.cs" />
<Compile Include="Compression\Formats\lz4.cs" />
<Compile Include="Compression\Formats\LZ4F.cs" />
<Compile Include="Compression\Formats\LZMA.cs" />
<Compile Include="Compression\Formats\ZlibGZ.cs" />
<Compile Include="Compression\Formats\Zstb.cs" />
<Compile Include="Compression\LZ77_WII.cs" />
<Compile Include="Compression\7ZIP\LZMA\LzmaBase.cs" />
<Compile Include="Compression\7ZIP\LZMA\LzmaDecoder.cs" />
<Compile Include="Compression\7ZIP\LZMA\LzmaEncoder.cs" />
<Compile Include="Compression\LZSS.cs" />
<Compile Include="Compression\MIO0.cs" />
<Compile Include="Compression\Formats\LZSS.cs" />
<Compile Include="Compression\Formats\MIO0.cs" />
<Compile Include="Compression\7ZIP\RangeCoder\RangeCoder.cs" />
<Compile Include="Compression\7ZIP\RangeCoder\RangeCoderBit.cs" />
<Compile Include="Compression\7ZIP\RangeCoder\RangeCoderBitTree.cs" />
<Compile Include="Compression\STLibraryCompression.cs" />
<Compile Include="Compression\Yay0.cs" />
<Compile Include="Compression\Yaz0.cs" />
<Compile Include="Compression\ZCMP.cs" />
<Compile Include="Compression\Formats\Yay0.cs" />
<Compile Include="Compression\Formats\Yaz0.cs" />
<Compile Include="Compression\Formats\ZCMP.cs" />
<Compile Include="Compression\Formats\Zlib.cs" />
<Compile Include="Config.cs" />
<Compile Include="Enums\CompressionType.cs" />
<Compile Include="FileFormats\DDS\RGBAPixelDecoder.cs" />
<Compile Include="FileSystem\VirtualFileTreeNode.cs" />
<Compile Include="FileSystem\VirtualTreeNode.cs" />
<Compile Include="Forms\ColorAlphaBox.cs">
<SubType>Component</SubType>
</Compile>

BIN
Toolbox/Lib/LibTennis64.dll Normal file

Binary file not shown.

View file

@ -29,7 +29,6 @@ void main()
if (debugShading == 0)
{
vec4 colorBlend = textureMap0 * whiteColor;
vec3 blackBlend = (vec3(1) - textureMap0.rgb) + blackColor.rgb;
fragColor = vertexColor0 * colorBlend;
}
else if (debugShading == 5)

View file

@ -21,9 +21,12 @@ void main()
if (debugShading == 0)
{
vec4 colorBlend = textureMap0 * whiteColor;
vec3 blackBlend = (vec3(1) - textureMap0.rgb) + blackColor.rgb;
gl_FragColor = gl_Color * colorBlend;
vec3 whiteInterpolation = mix(textureMap0.rgb, whiteColor.rgb, vec3(1));
vec3 blackInterpolation = mix(vec3(1) - textureMap0.rgb, blackColor.rgb, vec3(1));
vec3 colorBlend = textureMap0.rgb * whiteColor.rgb;
float alpha = textureMap0.a * whiteColor.a;
gl_FragColor = gl_Color * vec4(colorBlend,alpha);
}
else if (debugShading == 5)
gl_FragColor = vec4(textureMap0.rgb, 1);

View file

@ -406,7 +406,10 @@
<Content Include="Lib\LibHac.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\LibTennis.dll">
<Content Include="Lib\LibTennis32.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\LibTennis64.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\Licenses\7ZIP LZMA LICENSE.txt">