143 lines
3.6 KiB
C#
143 lines
3.6 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 LZSS : PuyoCompressionModule
|
|
{
|
|
public LZSS()
|
|
{
|
|
base.Name = "LZSS";
|
|
base.CanCompress = true;
|
|
base.CanDecompress = true;
|
|
}
|
|
public override MemoryStream Decompress(ref Stream data)
|
|
{
|
|
MemoryStream result;
|
|
try
|
|
{
|
|
uint num = (uint)data.Length;
|
|
uint num2 = data.ReadUInt(0L) >> 8;
|
|
uint num3 = 4u;
|
|
uint num4 = 0u;
|
|
byte[] array = data.ToByteArray();
|
|
byte[] array2 = new byte[(int)((uint)((UIntPtr)num2))];
|
|
while (num3 < num && num4 < num2)
|
|
{
|
|
byte b = array[(int)((uint)((UIntPtr)num3))];
|
|
num3 += 1u;
|
|
for (int i = 7; i >= 0; i--)
|
|
{
|
|
if (((int)b & 1 << i) == 0)
|
|
{
|
|
array2[(int)((uint)((UIntPtr)num4))] = array[(int)((uint)((UIntPtr)num3))];
|
|
num3 += 1u;
|
|
num4 += 1u;
|
|
}
|
|
else
|
|
{
|
|
int num5 = ((int)(array[(int)((uint)((UIntPtr)num3))] & 15) << 8 | (int)array[(int)((uint)((UIntPtr)(num3 + 1u)))]) + 1;
|
|
int num6 = (array[(int)((uint)((UIntPtr)num3))] >> 4) + 3;
|
|
num3 += 2u;
|
|
for (int j = 0; j < num6; j++)
|
|
{
|
|
array2[(int)((IntPtr)((long)((ulong)num4 + (ulong)((long)j))))] = array2[(int)((IntPtr)((long)((ulong)num4 - (ulong)((long)num5) + (ulong)((long)j))))];
|
|
}
|
|
num4 += (uint)num6;
|
|
}
|
|
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 = 4u;
|
|
if (data.Length > 16777215L)
|
|
{
|
|
throw new Exception("Input file is too large to compress.");
|
|
}
|
|
LzWindowDictionary lzWindowDictionary = new LzWindowDictionary();
|
|
lzWindowDictionary.SetWindowSize(4096);
|
|
lzWindowDictionary.SetMaxMatchAmount(18);
|
|
memoryStream.Write(16u | num << 8);
|
|
while (num2 < num)
|
|
{
|
|
byte b = 0;
|
|
uint num4 = num3;
|
|
memoryStream.WriteByte(b);
|
|
num3 += 1u;
|
|
for (int i = 7; i >= 0; i--)
|
|
{
|
|
int[] array2 = lzWindowDictionary.Search(array, num2, num);
|
|
if (array2[1] > 0)
|
|
{
|
|
b |= (byte)(1 << i);
|
|
memoryStream.WriteByte((byte)((array2[1] - 3 & 15) << 4 | (array2[0] - 1 & 4095) >> 8));
|
|
memoryStream.WriteByte((byte)(array2[0] - 1 & 255));
|
|
lzWindowDictionary.AddEntryRange(array, (int)num2, array2[1]);
|
|
lzWindowDictionary.SlideWindow(array2[1]);
|
|
num2 += (uint)array2[1];
|
|
num3 += 2u;
|
|
}
|
|
else
|
|
{
|
|
memoryStream.WriteByte(array[(int)((uint)((UIntPtr)num2))]);
|
|
lzWindowDictionary.AddEntry(array, (int)num2);
|
|
lzWindowDictionary.SlideWindow(1);
|
|
num2 += 1u;
|
|
num3 += 1u;
|
|
}
|
|
if (num2 >= num)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
memoryStream.Seek((long)((ulong)num4), SeekOrigin.Begin);
|
|
memoryStream.WriteByte(b);
|
|
memoryStream.Seek((long)((ulong)num3), SeekOrigin.Begin);
|
|
}
|
|
result = memoryStream;
|
|
}
|
|
catch
|
|
{
|
|
result = null;
|
|
}
|
|
return result;
|
|
}
|
|
public override bool Check(ref Stream data, string filename)
|
|
{
|
|
bool result;
|
|
try
|
|
{
|
|
result = (data.ReadString(0L, 1) == "\u0010" && !Compression.Dictionary[CompressionFormat.PRS].Check(ref data, filename));
|
|
}
|
|
catch
|
|
{
|
|
result = false;
|
|
}
|
|
return result;
|
|
}
|
|
}
|
|
}
|