228 lines
6.3 KiB
C#
228 lines
6.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
using System.IO;
|
|
|
|
using UniversalEditor.Compression.Puyo.Internal.CompressionDictionaries;
|
|
|
|
namespace UniversalEditor.Compression.Puyo.Internal.Compressors
|
|
{
|
|
public class LZ00 : PuyoCompressionModule
|
|
{
|
|
public LZ00()
|
|
{
|
|
base.Name = "LZ00";
|
|
base.CanCompress = true;
|
|
base.CanDecompress = true;
|
|
}
|
|
public override MemoryStream Decompress(ref Stream data)
|
|
{
|
|
MemoryStream result;
|
|
try
|
|
{
|
|
uint num = data.ReadUInt(4L);
|
|
uint num2 = data.ReadUInt(48L);
|
|
uint xValue = data.ReadUInt(52L);
|
|
byte[] array = data.ToByteArray();
|
|
byte[] array2 = new byte[(int)((uint)((UIntPtr)num2))];
|
|
byte[] array3 = new byte[4096];
|
|
uint num3 = 64u;
|
|
uint num4 = 0u;
|
|
uint num5 = 4078u;
|
|
while (num3 < num && num4 < num2)
|
|
{
|
|
xValue = this.GetNewMagicValue(xValue);
|
|
byte b = this.DecryptByte(array[(int)((uint)((UIntPtr)num3))], xValue);
|
|
num3 += 1u;
|
|
for (int i = 0; i < 8; i++)
|
|
{
|
|
if (((int)b & 1 << i) > 0)
|
|
{
|
|
xValue = this.GetNewMagicValue(xValue);
|
|
array2[(int)((uint)((UIntPtr)num4))] = this.DecryptByte(array[(int)((uint)((UIntPtr)num3))], xValue);
|
|
array3[(int)((uint)((UIntPtr)num5))] = array2[(int)((uint)((UIntPtr)num4))];
|
|
num3 += 1u;
|
|
num4 += 1u;
|
|
num5 = (num5 + 1u & 4095u);
|
|
}
|
|
else
|
|
{
|
|
xValue = this.GetNewMagicValue(xValue);
|
|
byte b2 = this.DecryptByte(array[(int)((uint)((UIntPtr)num3))], xValue);
|
|
xValue = this.GetNewMagicValue(xValue);
|
|
byte b3 = this.DecryptByte(array[(int)((uint)((UIntPtr)(num3 + 1u)))], xValue);
|
|
int num6 = (b3 >> 4 & 15) << 8 | (int)b2;
|
|
int num7 = (int)((b3 & 15) + 3);
|
|
num3 += 2u;
|
|
for (int j = 0; j < num7; j++)
|
|
{
|
|
array2[(int)((IntPtr)((long)((ulong)num4 + (ulong)((long)j))))] = array3[num6 + j & 4095];
|
|
array3[(int)((uint)((UIntPtr)num5))] = array2[(int)((IntPtr)((long)((ulong)num4 + (ulong)((long)j))))];
|
|
num5 = (num5 + 1u & 4095u);
|
|
}
|
|
num4 += (uint)num7;
|
|
}
|
|
if (num3 >= num || num4 >= num2)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
result = new MemoryStream(array2);
|
|
}
|
|
catch
|
|
{
|
|
result = null;
|
|
}
|
|
return result;
|
|
}
|
|
public override MemoryStream Compress(ref Stream data, string filename)
|
|
{
|
|
MemoryStream result;
|
|
try
|
|
{
|
|
uint num = (uint)data.Length;
|
|
MemoryStream memoryStream = new MemoryStream();
|
|
byte[] array = data.ToByteArray();
|
|
uint num2 = 0u;
|
|
uint num3 = 64u;
|
|
uint num4 = (uint)(DateTime.Now - new DateTime(1970, 1, 1)).TotalSeconds;
|
|
LzBufferDictionary lzBufferDictionary = new LzBufferDictionary();
|
|
lzBufferDictionary.SetBufferSize(4096);
|
|
lzBufferDictionary.SetBufferStart(4078);
|
|
lzBufferDictionary.SetMaxMatchAmount(18);
|
|
memoryStream.Write("LZ00");
|
|
memoryStream.Write(0u);
|
|
memoryStream.Seek(8L, SeekOrigin.Current);
|
|
if (Path.GetExtension(filename).ToLower() == ".mrz")
|
|
{
|
|
filename = Path.GetFileNameWithoutExtension(filename) + ".mrg";
|
|
}
|
|
else
|
|
{
|
|
if (Path.GetExtension(filename).ToLower() == ".tez")
|
|
{
|
|
filename = Path.GetFileNameWithoutExtension(filename) + ".tex";
|
|
}
|
|
}
|
|
memoryStream.Write(filename, 31, 32, Encoding.GetEncoding("Shift_JIS"));
|
|
memoryStream.Write(num);
|
|
memoryStream.Write(num4);
|
|
memoryStream.Seek(8L, SeekOrigin.Current);
|
|
while (num2 < num)
|
|
{
|
|
num4 = this.GetNewMagicValue(num4);
|
|
byte b = 0;
|
|
uint num5 = num3;
|
|
uint xValue = num4;
|
|
memoryStream.WriteByte(b);
|
|
num3 += 1u;
|
|
for (int i = 0; i < 8; i++)
|
|
{
|
|
int[] array2 = lzBufferDictionary.Search(array, num2, num);
|
|
if (array2[1] > 0)
|
|
{
|
|
num4 = this.GetNewMagicValue(num4);
|
|
memoryStream.WriteByte(this.EncryptByte((byte)(array2[0] & 255), num4));
|
|
num4 = this.GetNewMagicValue(num4);
|
|
memoryStream.WriteByte(this.EncryptByte((byte)((array2[0] & 3840) >> 4 | (array2[1] - 3 & 15)), num4));
|
|
lzBufferDictionary.AddEntryRange(array, (int)num2, array2[1]);
|
|
num2 += (uint)array2[1];
|
|
num3 += 2u;
|
|
}
|
|
else
|
|
{
|
|
b |= (byte)(1 << i);
|
|
num4 = this.GetNewMagicValue(num4);
|
|
memoryStream.WriteByte(this.EncryptByte(array[(int)((uint)((UIntPtr)num2))], num4));
|
|
lzBufferDictionary.AddEntry(array, (int)num2);
|
|
num2 += 1u;
|
|
num3 += 1u;
|
|
}
|
|
if (num2 >= num)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
memoryStream.Seek((long)((ulong)num5), SeekOrigin.Begin);
|
|
memoryStream.WriteByte(this.EncryptByte(b, xValue));
|
|
memoryStream.Seek((long)((ulong)num3), SeekOrigin.Begin);
|
|
}
|
|
memoryStream.Seek(4L, SeekOrigin.Begin);
|
|
memoryStream.Write((uint)memoryStream.Length);
|
|
memoryStream.Seek(0L, SeekOrigin.End);
|
|
result = memoryStream;
|
|
}
|
|
catch
|
|
{
|
|
result = null;
|
|
}
|
|
return result;
|
|
}
|
|
private uint GetNewMagicValue(uint xValue)
|
|
{
|
|
uint num = ((((xValue << 1) + xValue << 5) - xValue << 5) + xValue << 7) - xValue;
|
|
num = (num << 6) - num;
|
|
num = (num << 4) - num;
|
|
return (num << 2) - num + 12345u;
|
|
}
|
|
private byte DecryptByte(byte value, uint xValue)
|
|
{
|
|
uint num = xValue >> 16 & 32767u;
|
|
return (byte)((uint)value ^ (num << 8) - num >> 15);
|
|
}
|
|
private byte EncryptByte(byte value, uint xValue)
|
|
{
|
|
uint num = xValue >> 16 & 32767u;
|
|
return (byte)((uint)value ^ (num << 8) - num >> 15);
|
|
}
|
|
public override string DecompressFilename(ref Stream data, string filename)
|
|
{
|
|
string text = data.ReadString(16L, 32, Encoding.GetEncoding("Shift_JIS"));
|
|
string result;
|
|
if (!(text == string.Empty))
|
|
{
|
|
result = text;
|
|
}
|
|
else
|
|
{
|
|
result = filename;
|
|
}
|
|
return result;
|
|
}
|
|
public override string CompressFilename(ref Stream data, string filename)
|
|
{
|
|
string extension;
|
|
string result;
|
|
if ((extension = Path.GetExtension(filename)) != null)
|
|
{
|
|
if (extension == ".mrg")
|
|
{
|
|
result = Path.GetFileNameWithoutExtension(filename) + ".mrz";
|
|
return result;
|
|
}
|
|
if (extension == ".tex")
|
|
{
|
|
result = Path.GetFileNameWithoutExtension(filename) + ".tez";
|
|
return result;
|
|
}
|
|
}
|
|
result = filename;
|
|
return result;
|
|
}
|
|
public override bool Check(ref Stream data, string filename)
|
|
{
|
|
bool result;
|
|
try
|
|
{
|
|
result = (data.ReadString(0L, 4) == "LZ00");
|
|
}
|
|
catch
|
|
{
|
|
result = false;
|
|
}
|
|
return result;
|
|
}
|
|
}
|
|
}
|