Made LZRW1 into a true CompressionModule and improved algorithm

This commit is contained in:
Michael Becker 2014-04-20 16:38:08 -04:00
parent 9a3db87516
commit 1fdbae8d0f

View File

@ -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();
}
}
}
}