Switch-Toolbox/Switch_Toolbox_Library/Compression/LZ77_WII.cs
KillzXGaming 89d5b621b2 Giant layout update. Support BRLYT and BCLYT files!
BRLYT can now be edited and saved.
BCLYT can now be edited and saved.
BRLYT shaders greatly improved using ported shaders from WiiLayoutEditor. Plan to expand upon it for more accuacte shader rendering.
Add support for saving per character transforms.
Add support for BNR files.
Fixed flags so orientation can be edited properly.
Fix issues decoding some gamecube textures.
Fix animation timeline breaking at times for multi selecting animations.
2020-02-11 19:19:23 -05:00

83 lines
2.8 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Runtime.InteropServices;
using Toolbox.Library.IO;
namespace Toolbox.Library
{
public class LZ77_WII
{
private readonly static int N = 4096;
private readonly static ushort[] textBuffer = new ushort[N + 17];
private readonly static int F = 18;
private static readonly int threshold = 2;
public static byte[] Decompress(byte[] input)
{
if (input == null) throw new ArgumentNullException(nameof(input));
using (var reader = new FileReader(new MemoryStream(input), true))
{
reader.SetByteOrder(true);
reader.ReadSignature(4, "LZ77");
reader.Position = 0;
int i, j, k, r, c, z;
uint flags, decompressedSize, currentSize = 0;
byte[] temp = new byte[8];
reader.Read(temp, 0, 8);
if (temp[4] != 0x10)
{ reader.Dispose(); throw new Exception("Unsupported Compression Type!"); }
decompressedSize = (BitConverter.ToUInt32(temp, 4)) >> 8;
for (i = 0; i < N - F; i++) textBuffer[i] = 0xdf;
r = N - F; flags = 7; z = 7;
MemoryStream outFile = new MemoryStream();
while (outFile.Length < decompressedSize)
{
flags <<= 1;
z++;
if (z == 8)
{
if ((c = reader.ReadByte()) == -1) break;
flags = (uint)c;
z = 0;
}
if ((flags & 0x80) == 0)
{
if ((c = reader.ReadByte()) == reader.Length - 1) break;
if (currentSize < decompressedSize) outFile.WriteByte((byte)c);
textBuffer[r++] = (byte)c;
r &= (N - 1);
currentSize++;
}
else
{
if ((i = reader.ReadByte()) == -1) break;
if ((j = reader.ReadByte()) == -1) break;
j = j | ((i << 8) & 0xf00);
i = ((i >> 4) & 0x0f) + threshold;
for (k = 0; k <= i; k++)
{
c = textBuffer[(r - j - 1) & (N - 1)];
if (currentSize < decompressedSize) outFile.WriteByte((byte)c); textBuffer[r++] = (byte)c; r &= (N - 1); currentSize++;
}
}
}
return outFile.ToArray();
}
return input;
}
}
}