mirror of
https://github.com/BtbN/ClanServer.git
synced 2026-03-21 17:54:21 -05:00
Rewrite LZ77 decompression as well
This commit is contained in:
parent
499952b7e6
commit
7ca1f8489b
|
|
@ -27,9 +27,7 @@ namespace ClanServer.Data.L44
|
|||
stream.CopyTo(ms);
|
||||
return new ClanMusicInfo(
|
||||
new KBinXML(
|
||||
LZ77.Decompress(
|
||||
ms.ToArray()
|
||||
).ToArray()
|
||||
LZ77.Decompress(ms.ToArray())
|
||||
).Document
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ namespace ClanServer.Formatters
|
|||
switch (compAlgo.ToLower())
|
||||
{
|
||||
case "lz77":
|
||||
return LZ77.Decompress(data).ToArray();
|
||||
return LZ77.Decompress(data);
|
||||
case "none":
|
||||
return data;
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ namespace ClanServer.Formatters
|
|||
|
||||
string algo = "none";
|
||||
|
||||
byte[] compressed = LZ77.Compress(resData);
|
||||
byte[] compressed = LZ77.Compress(resData, 32);
|
||||
if (compressed.Length < resData.Length)
|
||||
{
|
||||
resData = compressed;
|
||||
|
|
|
|||
|
|
@ -1,103 +1,50 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace eAmuseCore.Compression
|
||||
{
|
||||
public class RepeatingRingBuffer
|
||||
{
|
||||
private readonly byte[] buf;
|
||||
private readonly int mod;
|
||||
private int pos;
|
||||
|
||||
public RepeatingRingBuffer(int size)
|
||||
{
|
||||
if (size == 0 || (size & (size - 1)) != 0)
|
||||
throw new ArgumentException("Size is not a power of two.", "size");
|
||||
|
||||
buf = new byte[size];
|
||||
mod = size - 1;
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
public byte this[int index]
|
||||
{
|
||||
get => buf[(pos + index) & mod];
|
||||
set => buf[(pos + index) & mod] = value;
|
||||
}
|
||||
|
||||
public int Size
|
||||
{
|
||||
get => buf.Length;
|
||||
}
|
||||
|
||||
public void Append(byte b)
|
||||
{
|
||||
buf[pos++ & mod] = b;
|
||||
}
|
||||
|
||||
public IEnumerable<byte> Slice(int start, int end)
|
||||
{
|
||||
for (int i = start; i < end; ++i)
|
||||
{
|
||||
if (start < 0 && i >= 0)
|
||||
yield return this[start + (i % start)];
|
||||
else
|
||||
yield return this[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class LZ77
|
||||
{
|
||||
private const int minLength = 3;
|
||||
|
||||
public static IEnumerable<byte> Decompress(IEnumerable<byte> data)
|
||||
public static byte[] Decompress(byte[] data)
|
||||
{
|
||||
RepeatingRingBuffer buffer = new RepeatingRingBuffer(0x1000);
|
||||
List<byte> res = new List<byte>();
|
||||
|
||||
int pos = 0;
|
||||
int state = 0;
|
||||
|
||||
using (var iter = data.GetEnumerator())
|
||||
while (pos < data.Length)
|
||||
{
|
||||
while (iter.MoveNext())
|
||||
state >>= 1;
|
||||
if (state <= 1)
|
||||
state = data[pos++] | 0x100;
|
||||
|
||||
if ((state & 1) != 0)
|
||||
{
|
||||
state >>= 1;
|
||||
if (state <= 1)
|
||||
res.Add(data[pos++]);
|
||||
}
|
||||
else
|
||||
{
|
||||
byte byte1 = data[pos++];
|
||||
byte byte2 = data[pos++];
|
||||
|
||||
int length = (byte2 & 0xf) + minLength;
|
||||
int distance = (byte1 << 4) | (byte2 >> 4);
|
||||
|
||||
if (distance == 0)
|
||||
break;
|
||||
|
||||
int resPos = res.Count;
|
||||
for (int i = 0; i < length; ++i)
|
||||
{
|
||||
state = iter.Current | 0x100;
|
||||
if (!iter.MoveNext())
|
||||
yield break;
|
||||
}
|
||||
|
||||
if ((state & 1) != 0)
|
||||
{
|
||||
yield return iter.Current;
|
||||
buffer.Append(iter.Current);
|
||||
}
|
||||
else
|
||||
{
|
||||
byte byte1 = iter.Current;
|
||||
if (!iter.MoveNext())
|
||||
yield break;
|
||||
byte byte2 = iter.Current;
|
||||
|
||||
int length = (byte2 & 0xf) + minLength;
|
||||
int distance = (byte1 << 4) | (byte2 >> 4);
|
||||
|
||||
if (distance == 0)
|
||||
yield break;
|
||||
|
||||
for (int i = 0; i < length; ++i)
|
||||
{
|
||||
byte b = buffer[-distance];
|
||||
yield return b;
|
||||
buffer.Append(b);
|
||||
}
|
||||
int o = resPos - distance + i;
|
||||
res.Add((o < 0) ? (byte)0 : res[o]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res.ToArray();
|
||||
}
|
||||
|
||||
private struct Match
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ namespace eAmuseTest
|
|||
|
||||
byte[] rawData = data;
|
||||
if (compress == "lz77")
|
||||
rawData = LZ77.Decompress(data).ToArray();
|
||||
rawData = LZ77.Decompress(data);
|
||||
else if (compress != "none")
|
||||
throw new ArgumentException("Unsupported compression algorithm");
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user