rjx-mirror/Ryujinx.HLE/Loaders/Compression/Lz4.cs

78 lines
1.9 KiB
C#
Raw Normal View History

2018-02-04 23:08:20 +00:00
using System;
namespace Ryujinx.HLE.Loaders.Compression
2018-02-04 23:08:20 +00:00
{
static class Lz4
{
public static byte[] Decompress(byte[] Cmp, int DecLength)
2018-02-04 23:08:20 +00:00
{
byte[] Dec = new byte[DecLength];
2018-02-04 23:08:20 +00:00
int CmpPos = 0;
int DecPos = 0;
2018-02-04 23:08:20 +00:00
int GetLength(int Length)
2018-02-04 23:08:20 +00:00
{
byte Sum;
2018-02-04 23:08:20 +00:00
if (Length == 0xf)
2018-02-04 23:08:20 +00:00
{
do
{
Length += (Sum = Cmp[CmpPos++]);
2018-02-04 23:08:20 +00:00
}
while (Sum == 0xff);
2018-02-04 23:08:20 +00:00
}
return Length;
2018-02-04 23:08:20 +00:00
}
do
{
byte Token = Cmp[CmpPos++];
2018-02-04 23:08:20 +00:00
int EncCount = (Token >> 0) & 0xf;
int LitCount = (Token >> 4) & 0xf;
2018-02-04 23:08:20 +00:00
//Copy literal chunck
LitCount = GetLength(LitCount);
2018-02-04 23:08:20 +00:00
Buffer.BlockCopy(Cmp, CmpPos, Dec, DecPos, LitCount);
2018-02-04 23:08:20 +00:00
CmpPos += LitCount;
DecPos += LitCount;
2018-02-04 23:08:20 +00:00
if (CmpPos >= Cmp.Length)
2018-02-04 23:08:20 +00:00
{
break;
}
//Copy compressed chunck
int Back = Cmp[CmpPos++] << 0 |
Cmp[CmpPos++] << 8;
2018-02-04 23:08:20 +00:00
EncCount = GetLength(EncCount) + 4;
2018-02-04 23:08:20 +00:00
int EncPos = DecPos - Back;
2018-02-04 23:08:20 +00:00
if (EncCount <= Back)
2018-02-04 23:08:20 +00:00
{
Buffer.BlockCopy(Dec, EncPos, Dec, DecPos, EncCount);
2018-02-04 23:08:20 +00:00
DecPos += EncCount;
2018-02-04 23:08:20 +00:00
}
else
{
while (EncCount-- > 0)
2018-02-04 23:08:20 +00:00
{
Dec[DecPos++] = Dec[EncPos++];
2018-02-04 23:08:20 +00:00
}
}
}
while (CmpPos < Cmp.Length &&
DecPos < Dec.Length);
2018-02-04 23:08:20 +00:00
return Dec;
2018-02-04 23:08:20 +00:00
}
}
}