Made LZRW1 into a true CompressionModule and improved algorithm
This commit is contained in:
parent
9a3db87516
commit
1fdbae8d0f
@ -2,6 +2,8 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UniversalEditor.Accessors;
|
||||
using UniversalEditor.IO;
|
||||
|
||||
namespace UniversalEditor.Compression.Modules.LZRW1
|
||||
{
|
||||
@ -15,61 +17,6 @@ namespace UniversalEditor.Compression.Modules.LZRW1
|
||||
private const byte FLAG_COMPRESS = 0x00;
|
||||
private const byte FLAG_COPY = 0x01;
|
||||
|
||||
public static byte[] Decompress(byte[] input)
|
||||
{
|
||||
byte[] output = null;
|
||||
|
||||
if (input[0] == FLAG_COPY)
|
||||
{
|
||||
output = new byte[input.Length - FLAG_BYTES];
|
||||
Array.Copy(input, FLAG_BYTES, output, 0, input.Length - FLAG_BYTES);
|
||||
}
|
||||
else
|
||||
{
|
||||
ushort controlbits = 0, control = 0;
|
||||
int p_src = FLAG_BYTES;
|
||||
|
||||
Accessors.MemoryAccessor ma = new Accessors.MemoryAccessor();
|
||||
IO.Writer bw = new IO.Writer(ma);
|
||||
|
||||
while (p_src != input.Length)
|
||||
{
|
||||
if (controlbits == 0)
|
||||
{
|
||||
control = input[p_src++];
|
||||
control |= (ushort)(input[p_src] << 8);
|
||||
controlbits = 16;
|
||||
}
|
||||
if ((control & 1) != 0)
|
||||
{
|
||||
ushort offset, len;
|
||||
int p;
|
||||
offset = (ushort)((input[p_src] & 0xF0) << 4);
|
||||
len = (ushort)(1 + (input[p_src++] & 0xF));
|
||||
offset += (ushort)(input[p_src++] & 0xFF);
|
||||
|
||||
bw.Flush();
|
||||
byte[] out1 = ma.ToArray();
|
||||
|
||||
p = out1.Length - offset;
|
||||
while (len-- != 0)
|
||||
{
|
||||
bw.WriteByte(out1[p++]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bw.WriteByte(input[p_src++]);
|
||||
}
|
||||
control >>= 1;
|
||||
controlbits--;
|
||||
}
|
||||
bw.Flush();
|
||||
bw.Close();
|
||||
output = ma.ToArray();
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
@ -83,7 +30,56 @@ namespace UniversalEditor.Compression.Modules.LZRW1
|
||||
|
||||
protected override void DecompressInternal(System.IO.Stream inputStream, System.IO.Stream outputStream, int inputLength, int outputLength)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
StreamAccessor sao = new StreamAccessor(outputStream);
|
||||
StreamAccessor sai = new StreamAccessor(inputStream);
|
||||
Reader br = new Reader(sai);
|
||||
Writer bw = new Writer(sao);
|
||||
|
||||
int flag = br.ReadInt32();
|
||||
if (flag == FLAG_COPY)
|
||||
{
|
||||
// entire stream is uncompressed, so read it all
|
||||
byte[] data = br.ReadToEnd();
|
||||
bw.WriteBytes(data);
|
||||
}
|
||||
else
|
||||
{
|
||||
// flag is not copy, so we have to decompress
|
||||
ushort controlbits = 0, control = 0;
|
||||
while (!br.EndOfStream)
|
||||
{
|
||||
if (controlbits == 0)
|
||||
{
|
||||
// control bits are 0, so it's time to read a new control ushort
|
||||
control = br.ReadUInt16();
|
||||
controlbits = 16;
|
||||
}
|
||||
if ((control & 1) != 0)
|
||||
{
|
||||
ushort offset, len;
|
||||
offset = (ushort)((br.PeekByte() & 0xF0) << 4);
|
||||
len = (ushort)(1 + (br.ReadByte() & 0xF));
|
||||
offset += (ushort)(br.ReadByte() & 0xFF);
|
||||
|
||||
bw.Flush();
|
||||
|
||||
int p = (int)(sao.Length - offset);
|
||||
// sao.Position = p;
|
||||
byte[] nextdata = sao.Reader.ReadBytes(len);
|
||||
bw.WriteBytes(nextdata);
|
||||
}
|
||||
else
|
||||
{
|
||||
// control bit is 0, so perform a simple copy of the next byte
|
||||
bw.WriteByte(br.ReadByte());
|
||||
}
|
||||
|
||||
// pop the latest control bit off the control ushort
|
||||
control >>= 1;
|
||||
controlbits--;
|
||||
}
|
||||
bw.Flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user