mirror of
https://github.com/KillzXGaming/Switch-Toolbox
synced 2024-11-22 04:23:09 +00:00
Add support for decompressing gz.bin files on it's own
This commit is contained in:
parent
82761a6120
commit
c7d2a5d8eb
6 changed files with 261 additions and 1 deletions
|
@ -25,6 +25,7 @@ namespace Toolbox.Library.IO
|
||||||
items.Add(new ToolStripMenuItem("lZ4F"));
|
items.Add(new ToolStripMenuItem("lZ4F"));
|
||||||
items.Add(new ToolStripMenuItem("ZSTD"));
|
items.Add(new ToolStripMenuItem("ZSTD"));
|
||||||
items.Add(new ToolStripMenuItem("ZLIB"));
|
items.Add(new ToolStripMenuItem("ZLIB"));
|
||||||
|
items.Add(new ToolStripMenuItem("ZLIB_GZ (Hyrule Warriors)"));
|
||||||
|
|
||||||
SetFunctions(items);
|
SetFunctions(items);
|
||||||
return items;
|
return items;
|
||||||
|
@ -74,6 +75,8 @@ namespace Toolbox.Library.IO
|
||||||
OpenFileForCompression(CompressionType.Zstb, Compress);
|
OpenFileForCompression(CompressionType.Zstb, Compress);
|
||||||
else if (Name == "ZLIB")
|
else if (Name == "ZLIB")
|
||||||
OpenFileForCompression(CompressionType.Zlib, Compress);
|
OpenFileForCompression(CompressionType.Zlib, Compress);
|
||||||
|
else if (Name.Contains("ZLIB_GZ"))
|
||||||
|
OpenFileForCompression(CompressionType.ZlibGz, Compress);
|
||||||
else throw new Exception("Unimplimented Type! " + Name);
|
else throw new Exception("Unimplimented Type! " + Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,6 +102,7 @@ namespace Toolbox.Library.IO
|
||||||
case CompressionType.Lz4:
|
case CompressionType.Lz4:
|
||||||
SaveFileForCompression(STLibraryCompression.Type_LZ4.Compress(data));
|
SaveFileForCompression(STLibraryCompression.Type_LZ4.Compress(data));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public void DecompressData(CompressionType CompressionType, byte[] data)
|
public void DecompressData(CompressionType CompressionType, byte[] data)
|
||||||
|
@ -131,6 +135,9 @@ namespace Toolbox.Library.IO
|
||||||
case CompressionType.Lz4:
|
case CompressionType.Lz4:
|
||||||
SaveFileForCompression(STLibraryCompression.Type_LZ4.Decompress(data));
|
SaveFileForCompression(STLibraryCompression.Type_LZ4.Decompress(data));
|
||||||
break;
|
break;
|
||||||
|
case CompressionType.ZlibGz:
|
||||||
|
SaveFileForCompression(STLibraryCompression.ZLIB_GZ.Decompress(new MemoryStream(data)));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
|
@ -158,6 +165,19 @@ namespace Toolbox.Library.IO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void SaveFileForCompression(Stream data)
|
||||||
|
{
|
||||||
|
SaveFileDialog sfd = new SaveFileDialog();
|
||||||
|
sfd.Filter = "All files(*.*)|*.*";
|
||||||
|
|
||||||
|
Cursor.Current = Cursors.Default;
|
||||||
|
if (sfd.ShowDialog() == DialogResult.OK)
|
||||||
|
{
|
||||||
|
data.ExportToFile(sfd.FileName);
|
||||||
|
MessageBox.Show($"File has been saved to {sfd.FileName}", "Save Notification");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void SaveFileForCompression(byte[] data)
|
private void SaveFileForCompression(byte[] data)
|
||||||
{
|
{
|
||||||
SaveFileDialog sfd = new SaveFileDialog();
|
SaveFileDialog sfd = new SaveFileDialog();
|
||||||
|
|
|
@ -61,6 +61,88 @@ namespace Toolbox.Library.IO
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class ZLIB_GZ
|
||||||
|
{
|
||||||
|
public static bool IsCompressed(Stream stream)
|
||||||
|
{
|
||||||
|
using (var reader = new FileReader(stream, true))
|
||||||
|
{
|
||||||
|
reader.ByteOrder = Syroot.BinaryData.ByteOrder.BigEndian;
|
||||||
|
uint chunkCount = reader.ReadUInt32();
|
||||||
|
uint unk = reader.ReadUInt32();
|
||||||
|
if (reader.BaseStream.Length > 4 + (chunkCount * 4))
|
||||||
|
{
|
||||||
|
uint[] chunkSizes = reader.ReadUInt32s((int)chunkCount); //Not very sure about this
|
||||||
|
reader.Align(128);
|
||||||
|
|
||||||
|
while (!reader.EndOfStream)
|
||||||
|
{
|
||||||
|
uint size = reader.ReadUInt32();
|
||||||
|
|
||||||
|
long pos = reader.Position;
|
||||||
|
ushort magic = reader.ReadUInt16();
|
||||||
|
|
||||||
|
reader.Position = 0;
|
||||||
|
if (magic == 0x78da)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reader.Position = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Stream Decompress(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 null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class ZLIB
|
public class ZLIB
|
||||||
{
|
{
|
||||||
public static byte[] Decompress(byte[] b)
|
public static byte[] Decompress(byte[] b)
|
||||||
|
|
|
@ -15,6 +15,7 @@ namespace Toolbox.Library
|
||||||
Lz4,
|
Lz4,
|
||||||
Lz4f,
|
Lz4f,
|
||||||
Zstb,
|
Zstb,
|
||||||
|
ZlibGz,
|
||||||
MarioTennisCustom,
|
MarioTennisCustom,
|
||||||
}
|
}
|
||||||
}
|
}
|
154
Switch_Toolbox_Library/Imaging/BitmapFont.cs
Normal file
154
Switch_Toolbox_Library/Imaging/BitmapFont.cs
Normal file
|
@ -0,0 +1,154 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Drawing;
|
||||||
|
|
||||||
|
//Thanks EFE!
|
||||||
|
//https://github.com/Gericom/EveryFileExplorer/blob/f9f00d193c9608d71c9a23d9f3ab7e752f4ada2a/LibEveryFileExplorer/GFX/BitmapFont.cs
|
||||||
|
namespace LibEveryFileExplorer.GFX
|
||||||
|
{
|
||||||
|
public class BitmapFont : IDisposable
|
||||||
|
{
|
||||||
|
public BitmapFont()
|
||||||
|
{
|
||||||
|
Characters = new Dictionary<char, Character>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Dictionary<char, Character> Characters { get; private set; }
|
||||||
|
public int LineHeight { get; set; }
|
||||||
|
|
||||||
|
public int GetLineWidth(String Text, FontRenderSettings Settings, out int LineEnd)
|
||||||
|
{
|
||||||
|
LineEnd = -1;
|
||||||
|
int result = 0;
|
||||||
|
int i = 0;
|
||||||
|
foreach (char c in Text)
|
||||||
|
{
|
||||||
|
if (c == '\n')
|
||||||
|
{
|
||||||
|
if (Text.Length > i + 1) LineEnd = i + 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (c == '\r') { i++; continue; }
|
||||||
|
if (!Characters.ContainsKey(c)) result += Settings.CharSpacing * 4;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Character info = Characters[c];
|
||||||
|
result += (int)(info.CharWidth * Settings.XScale) + Settings.CharSpacing;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (result > 0) result -= Settings.CharSpacing;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Bitmap PrintToBitmap(String Text, FontRenderSettings Settings)
|
||||||
|
{
|
||||||
|
int Width = 0;
|
||||||
|
int Height = 0;
|
||||||
|
|
||||||
|
int linestart = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
int lns;
|
||||||
|
int linewidth = GetLineWidth(Text.Substring(linestart), Settings, out lns);
|
||||||
|
if (lns != -1) linestart += lns;
|
||||||
|
else linestart = -1;
|
||||||
|
if (linewidth > Width) Width = linewidth;
|
||||||
|
Height += (int)(LineHeight * Settings.YScale) + Settings.LineSpacing;
|
||||||
|
}
|
||||||
|
while (linestart != -1);
|
||||||
|
if (Width == 0 || Height == 0) return null;
|
||||||
|
Height -= Settings.LineSpacing;
|
||||||
|
Width += 2;
|
||||||
|
Bitmap b = new Bitmap(Width, Height);
|
||||||
|
using (Graphics g = Graphics.FromImage(b))
|
||||||
|
{
|
||||||
|
g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
|
||||||
|
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.None;
|
||||||
|
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Default;
|
||||||
|
int X = 0;
|
||||||
|
int Y = 0;
|
||||||
|
foreach (char c in Text)
|
||||||
|
{
|
||||||
|
if (c == '\n')
|
||||||
|
{
|
||||||
|
X = 0;
|
||||||
|
Y += (int)(LineHeight * Settings.YScale) + Settings.LineSpacing;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (c == '\r') continue;
|
||||||
|
if (!Characters.ContainsKey(c)) X += Settings.CharSpacing * 4;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Character info = Characters[c];
|
||||||
|
g.DrawImage(info.CharBitmap,
|
||||||
|
new RectangleF(X + info.LeftOffset, Y, info.GlyphWidth * Settings.XScale, LineHeight * Settings.YScale),
|
||||||
|
new Rectangle(0, 0, info.GlyphWidth, LineHeight),
|
||||||
|
GraphicsUnit.Pixel);
|
||||||
|
X += (int)(info.CharWidth * Settings.XScale) + Settings.CharSpacing;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
if (Characters == null) return;
|
||||||
|
|
||||||
|
foreach (var character in Characters.Values)
|
||||||
|
character.CharBitmap?.Dispose();
|
||||||
|
|
||||||
|
Characters.Clear();
|
||||||
|
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Character
|
||||||
|
{
|
||||||
|
public Character(Bitmap CharBitmap, int LeftOffset, int GlyphWidth, int CharWidth)
|
||||||
|
{
|
||||||
|
this.CharBitmap = CharBitmap;
|
||||||
|
this.LeftOffset = LeftOffset;
|
||||||
|
this.GlyphWidth = GlyphWidth;
|
||||||
|
this.CharWidth = CharWidth;
|
||||||
|
}
|
||||||
|
public Bitmap CharBitmap { get; set; }
|
||||||
|
public int LeftOffset { get; set; }
|
||||||
|
public int GlyphWidth { get; set; }
|
||||||
|
public int CharWidth { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class FontRenderSettings
|
||||||
|
{
|
||||||
|
public FontRenderSettings()
|
||||||
|
{
|
||||||
|
CharSpacing = 3;
|
||||||
|
XScale = YScale = 1;
|
||||||
|
HAlignment = XAlignment.Left;
|
||||||
|
VAlignment = YAlignment.Top;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int CharSpacing { get; set; }
|
||||||
|
public int LineSpacing { get; set; }
|
||||||
|
|
||||||
|
public float XScale { get; set; }
|
||||||
|
public float YScale { get; set; }
|
||||||
|
|
||||||
|
public XAlignment HAlignment { get; set; }
|
||||||
|
public YAlignment VAlignment { get; set; }
|
||||||
|
|
||||||
|
public enum XAlignment
|
||||||
|
{
|
||||||
|
Left, Center, Right
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum YAlignment
|
||||||
|
{
|
||||||
|
Top, Center, Bottom
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -233,6 +233,7 @@
|
||||||
<Compile Include="Compression\Yaz0.cs" />
|
<Compile Include="Compression\Yaz0.cs" />
|
||||||
<Compile Include="Compression\ZCMP.cs" />
|
<Compile Include="Compression\ZCMP.cs" />
|
||||||
<Compile Include="Config.cs" />
|
<Compile Include="Config.cs" />
|
||||||
|
<Compile Include="Enums\CompressionType.cs" />
|
||||||
<Compile Include="FileFormats\DDS\RGBAPixelDecoder.cs" />
|
<Compile Include="FileFormats\DDS\RGBAPixelDecoder.cs" />
|
||||||
<Compile Include="Forms\ColorAlphaBox.cs">
|
<Compile Include="Forms\ColorAlphaBox.cs">
|
||||||
<SubType>Component</SubType>
|
<SubType>Component</SubType>
|
||||||
|
@ -301,6 +302,7 @@
|
||||||
<Compile Include="Helpers\ArchiveNodeMenuHelper.cs" />
|
<Compile Include="Helpers\ArchiveNodeMenuHelper.cs" />
|
||||||
<Compile Include="Helpers\DirectoryHelper.cs" />
|
<Compile Include="Helpers\DirectoryHelper.cs" />
|
||||||
<Compile Include="Helpers\DragHelper.cs" />
|
<Compile Include="Helpers\DragHelper.cs" />
|
||||||
|
<Compile Include="Imaging\BitmapFont.cs" />
|
||||||
<Compile Include="Interfaces\FileFormatting\IFormEditorParameters.cs" />
|
<Compile Include="Interfaces\FileFormatting\IFormEditorParameters.cs" />
|
||||||
<Compile Include="Interfaces\FileFormatting\ILeaveOpenOnLoad.cs" />
|
<Compile Include="Interfaces\FileFormatting\ILeaveOpenOnLoad.cs" />
|
||||||
<Compile Include="Interfaces\FileFormatting\IPropertyContainer.cs" />
|
<Compile Include="Interfaces\FileFormatting\IPropertyContainer.cs" />
|
||||||
|
@ -812,7 +814,6 @@
|
||||||
<DesignTime>True</DesignTime>
|
<DesignTime>True</DesignTime>
|
||||||
<DependentUpon>Resources.resx</DependentUpon>
|
<DependentUpon>Resources.resx</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="PublicEnums.cs" />
|
|
||||||
<Compile Include="Rendering\DrawableBackground.cs" />
|
<Compile Include="Rendering\DrawableBackground.cs" />
|
||||||
<Compile Include="Rendering\DrawableDividedCube.cs" />
|
<Compile Include="Rendering\DrawableDividedCube.cs" />
|
||||||
<Compile Include="Rendering\DrawableBoundingBox.cs" />
|
<Compile Include="Rendering\DrawableBoundingBox.cs" />
|
||||||
|
|
|
@ -293,7 +293,9 @@ namespace Toolbox
|
||||||
if (inter.IsGenericType && inter.GetGenericTypeDefinition() == typeof(IEditor<>))
|
if (inter.IsGenericType && inter.GetGenericTypeDefinition() == typeof(IEditor<>))
|
||||||
{
|
{
|
||||||
MethodInfo method = objectType.GetMethod("OpenForm");
|
MethodInfo method = objectType.GetMethod("OpenForm");
|
||||||
|
MethodInfo methodFill = objectType.GetMethod("FillEditor");
|
||||||
var control = (UserControl)method.Invoke(file, new object[0]);
|
var control = (UserControl)method.Invoke(file, new object[0]);
|
||||||
|
methodFill.Invoke(file, new object[1] { control });
|
||||||
var form = new GenericEditorForm(false, control);
|
var form = new GenericEditorForm(false, control);
|
||||||
TabDupeIndex = 0;
|
TabDupeIndex = 0;
|
||||||
form.Text = CheckTabDupes(((IFileFormat)file).FileName);
|
form.Text = CheckTabDupes(((IFileFormat)file).FileName);
|
||||||
|
|
Loading…
Reference in a new issue