2021-05-07 22:05:11 -04:00

183 lines
4.9 KiB
C#

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace UniversalEditor.Compression.Puyo.Internal.Compressors
{
public class CNX : CompressionModule
{
public override string Name
{
get { return "CNX"; }
}
private string mvarOriginalFileNameExtension = String.Empty;
public string OriginalFileNameExtension { get { return mvarOriginalFileNameExtension; } set { mvarOriginalFileNameExtension = value; } }
protected override void DecompressInternal(System.IO.Stream inputStream, System.IO.Stream outputStream, int inputLength, int outputLength)
{
uint num = inputStream.ReadUInt(8L).SwapEndian() + 16u;
uint num2 = inputStream.ReadUInt(12L).SwapEndian();
uint num3 = 16u;
byte[] array = inputStream.ReadBytes(0L, num);
while (num3 < num && outputStream.Position < num2)
{
byte b = array[(int)((uint)((UIntPtr)num3))];
num3 += 1u;
for (int i = 0; i < 4; i++)
{
switch (b >> i * 2 & 3)
{
case 0:
{
byte b2 = array[(int)((uint)((UIntPtr)num3))];
num3 += (uint)((b2 & 255) + 1);
i = 3;
break;
}
case 1:
{
outputStream.Write(array[(int)((uint)((UIntPtr)num3))]);
num3 += 1u;
break;
}
case 2:
{
uint num5 = (uint)BitConverter.ToUInt16(array, (int)num3).SwapEndian();
uint num6 = (num5 >> 5) + 1u;
uint num7 = (num5 & 31u) + 4u;
num3 += 2u;
int num8 = 0;
while ((long)num8 < (long)((ulong)num7))
{
long pos = outputStream.Position;
outputStream.Position = pos - num6;
byte val = (byte)outputStream.ReadByte();
outputStream.Position = pos;
outputStream.Write(val);
num8++;
}
break;
}
case 3:
{
byte b3 = array[(int)((uint)((UIntPtr)num3))];
num3 += 1u;
for (int j = 0; j < (int)b3; j++)
{
outputStream.Write(array[(int)((uint)((UIntPtr)num3))]);
num3 += 1u;
}
break;
}
}
}
}
}
protected override void CompressInternal(System.IO.Stream inputStream, System.IO.Stream outputStream)
{
uint num = (uint)inputStream.Length;
uint num2 = 2048u;
byte[] array = inputStream.ToByteArray();
uint num3 = 0u;
uint num4 = 16u;
uint num5 = 16u;
CompressionDictionaries.LzWindowDictionary lzWindowDictionary = new CompressionDictionaries.LzWindowDictionary();
lzWindowDictionary.SetBlockSize(2048);
lzWindowDictionary.SetMinMatchAmount(4);
lzWindowDictionary.SetMaxMatchAmount(35);
outputStream.Write("CNX\u0002");
outputStream.Write(mvarOriginalFileNameExtension, 3);
outputStream.WriteByte(16);
outputStream.Write(0u);
outputStream.Write(num.SwapEndian());
while (num3 < num)
{
while (num5 < num2)
{
byte b = 0;
uint num6 = num4;
outputStream.WriteByte(b);
num4 += 1u;
for (int i = 0; i < 4; i++)
{
List<byte> list = new List<byte>();
int[] array2 = new int[2];
int[] array3;
do
{
array3 = lzWindowDictionary.Search(array, num3, num);
if (array3[1] == 0)
{
list.Add(array[(int)((uint)((UIntPtr)num3))]);
num3 += 1u;
}
}
while (array3[1] == 0 && list.Count < 255);
if (array3[1] > 0)
{
b |= (byte)(2 << i * 2);
outputStream.WriteByte((byte)((array3[1] - 3 & 15) << 4 | (array3[0] - 1 & 4095) >> 8));
outputStream.WriteByte((byte)(array3[0] - 1 & 255));
lzWindowDictionary.AddEntryRange(array, (int)num3, array3[1]);
lzWindowDictionary.SlideWindow(array3[1]);
num3 += (uint)array3[1];
num4 += 2u;
}
else
{
if (list.Count == 1)
{
b |= (byte)(1 << i * 2);
outputStream.WriteByte(list[0]);
}
else
{
b |= (byte)(3 << i * 2);
outputStream.WriteByte((byte)list.Count);
for (int j = 0; j < list.Count; j++)
{
outputStream.WriteByte(list[j]);
}
}
outputStream.WriteByte(array[(int)((uint)((UIntPtr)num3))]);
lzWindowDictionary.AddEntry(array, (int)num3);
lzWindowDictionary.SlideWindow(1);
num3 += 1u;
num4 += 1u;
}
if (num3 >= num)
{
break;
}
}
outputStream.Seek((long)((ulong)num6), SeekOrigin.Begin);
outputStream.WriteByte(b);
outputStream.Seek((long)((ulong)num4), SeekOrigin.Begin);
}
}
}
public string DecompressFilename(ref Stream data, string filename)
{
string text = data.ReadString(4L, 3);
string result;
if (!(text == string.Empty))
{
result = Path.GetFileNameWithoutExtension(filename) + '.' + text;
}
else
{
result = filename;
}
return result;
}
public string CompressFilename(ref Stream data, string filename)
{
return Path.GetFileNameWithoutExtension(filename) + (Path.GetExtension(filename).IsAllUpperCase() ? ".CNX" : ".cnx");
}
}
}