145 lines
3.5 KiB
C#
145 lines
3.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
using System.IO;
|
|
|
|
using UniversalEditor.Compression.Common;
|
|
|
|
namespace UniversalEditor.Compression.LZSS
|
|
{
|
|
public class LZSSStream : CompressionStream
|
|
{
|
|
public override bool CanRead
|
|
{
|
|
get
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
public override bool CanWrite
|
|
{
|
|
get
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
public override bool CanSeek
|
|
{
|
|
get
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
public override long Position
|
|
{
|
|
get
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
set
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
}
|
|
public override long Length
|
|
{
|
|
get
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
}
|
|
public override int Read(byte[] buffer, int offset, int count)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
public override void Write(byte[] buffer, int offset, int count)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
public override void SetLength(long value)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
public override long Seek(long offset, SeekOrigin origin)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
public override void Flush()
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
public static byte[] Decompress(byte[] inputData, uint outputLength)
|
|
{
|
|
MT19937ar myMT19937ar = new MT19937ar();
|
|
byte[] outputData = new byte[(int)((UIntPtr)outputLength)];
|
|
uint act_outputLength = 0u;
|
|
uint act_byte = 0u;
|
|
uint nActWindowByte = 4080u;
|
|
byte[] win = new byte[4096];
|
|
ushort flag = 0;
|
|
uint[] init_key = new uint[4];
|
|
byte[] rnd = new byte[1024];
|
|
init_key[0] = (outputLength | 128u) >> 5;
|
|
init_key[1] = (outputLength << 9 | 6u);
|
|
init_key[2] = (outputLength << 6 | 4u);
|
|
init_key[3] = (outputLength | 72u) >> 3;
|
|
myMT19937ar.init_by_array(init_key, 4);
|
|
for (uint i = 0u; i < 1024u; i += 1u)
|
|
{
|
|
rnd[(int)((UIntPtr)i)] = (byte)(myMT19937ar.genrand_int32() >> (int)(i % 7u));
|
|
}
|
|
uint seed = outputLength / 1000u % 10u + outputLength / 100u % 10u + outputLength / 10u % 10u + outputLength % 10u & 794u;
|
|
win.Initialize();
|
|
byte[] result;
|
|
while (act_outputLength < outputLength)
|
|
{
|
|
flag = (ushort)(flag >> 1);
|
|
if (act_outputLength < 32860u)
|
|
{
|
|
goto IL_EE;
|
|
}
|
|
IL_EE:
|
|
if ((flag & 256) == 0)
|
|
{
|
|
seed = (seed + 1u & 1023u);
|
|
flag = (ushort)((inputData[(int)((UIntPtr)(act_byte++))] ^ rnd[(int)((UIntPtr)seed)]) | 65280);
|
|
}
|
|
seed = (seed + 1u & 1023u);
|
|
byte data;
|
|
if ((flag & 1) == 0)
|
|
{
|
|
uint win_offset = (uint)(inputData[(int)((UIntPtr)(act_byte++))] ^ rnd[(int)((UIntPtr)seed)]);
|
|
seed = (seed + 1u & 1023u);
|
|
uint copy_bytes = (uint)(inputData[(int)((UIntPtr)(act_byte++))] ^ rnd[(int)((UIntPtr)seed)]);
|
|
win_offset |= (copy_bytes & 240u) << 4;
|
|
copy_bytes &= 15u;
|
|
copy_bytes += 3u;
|
|
for (uint i = 0u; i < copy_bytes; i += 1u)
|
|
{
|
|
data = win[(int)((UIntPtr)(win_offset + i & 4095u))];
|
|
outputData[(int)((UIntPtr)(act_outputLength++))] = data;
|
|
win[(int)((UIntPtr)(nActWindowByte++))] = data;
|
|
nActWindowByte &= 4095u;
|
|
if (act_outputLength >= outputLength)
|
|
{
|
|
result = inputData;
|
|
return result;
|
|
}
|
|
}
|
|
continue;
|
|
}
|
|
data = (byte)(inputData[(int)((UIntPtr)(act_byte++))] ^ rnd[(int)((UIntPtr)seed)]);
|
|
outputData[(int)((UIntPtr)(act_outputLength++))] = data;
|
|
win[(int)((UIntPtr)(nActWindowByte++))] = data;
|
|
nActWindowByte &= 4095u;
|
|
}
|
|
result = outputData;
|
|
return result;
|
|
}
|
|
public static byte[] Compress(byte[] inputData)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
}
|
|
}
|