Created
November 1, 2021 18:17
-
-
Save Demonslay335/9949802d0895690096c89272fd3bd1ca to your computer and use it in GitHub Desktop.
Depack aPLib in pure C#
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections.Generic; | |
using System.IO; | |
// https://github.com/snemes/aplib/blob/master/aplib.py | |
public class APLib | |
{ | |
protected uint Tag; | |
protected int BitCount; | |
protected uint GetBit(Stream source) | |
{ | |
uint bit; | |
/* check if tag is empty */ | |
if (--BitCount < 0) | |
{ | |
/* load next tag */ | |
Tag = (uint)source.ReadByte(); | |
BitCount = 7; | |
} | |
/* shift bit out of tag */ | |
bit = (Tag >> 7) & 0x01; | |
Tag <<= 1; | |
return bit; | |
} | |
protected uint GetGamma(Stream source) | |
{ | |
uint result = 1; | |
/* input gamma2-encoded bits */ | |
do | |
{ | |
result = (result << 1) + GetBit(source); | |
} while (GetBit(source) > 0); | |
return result; | |
} | |
public byte[] Depack(byte[] src) | |
{ | |
List<byte> destination = new List<byte>(); | |
uint offs, len, R0, LWM; | |
int done; | |
int i; | |
BitCount = 0; | |
R0 = 0; | |
LWM = 0; | |
done = 0; | |
using (MemoryStream source = new MemoryStream(src)) | |
{ | |
/* first byte verbatim */ | |
destination.Add((byte)source.ReadByte()); | |
/* main decompression loop */ | |
while (done == 0) | |
{ | |
if (GetBit(source) > 0) | |
{ | |
if (GetBit(source) > 0) | |
{ | |
if (GetBit(source) > 0) | |
{ | |
offs = 0; | |
for (i = 4; i > 0; i--) | |
{ | |
offs = (offs << 1) + GetBit(source); | |
} | |
if (offs > 0) | |
{ | |
destination.Add(destination[destination.Count - (int)offs]); | |
} | |
else | |
{ | |
destination.Add(0x00); | |
} | |
LWM = 0; | |
} | |
else | |
{ | |
offs = (uint)source.ReadByte(); | |
len = 2 + (offs & 0x0001); | |
offs >>= 1; | |
if (offs > 0) | |
{ | |
for (; len > 0; len--) | |
{ | |
destination.Add(destination[destination.Count - (int)offs]); | |
} | |
} | |
else | |
{ | |
done = 1; | |
} | |
R0 = offs; | |
LWM = 1; | |
} | |
} | |
else | |
{ | |
offs = GetGamma(source); | |
if ((LWM == 0) && (offs == 2)) | |
{ | |
offs = R0; | |
len = GetGamma(source); | |
for (; len > 0; len--) | |
{ | |
destination.Add(destination[destination.Count - (int)offs]); | |
} | |
} | |
else | |
{ | |
if (LWM == 0) | |
{ | |
offs -= 3; | |
} | |
else | |
{ | |
offs -= 2; | |
} | |
offs <<= 8; | |
offs += (uint)source.ReadByte(); | |
len = GetGamma(source); | |
if (offs >= 32000) | |
{ | |
len++; | |
} | |
if (offs >= 1280) | |
{ | |
len++; | |
} | |
if (offs < 128) | |
{ | |
len += 2; | |
} | |
for (; len > 0; len--) | |
{ | |
destination.Add(destination[destination.Count - (int)offs]); | |
} | |
R0 = offs; | |
} | |
LWM = 1; | |
} | |
} | |
else | |
{ | |
destination.Add((byte)source.ReadByte()); | |
LWM = 0; | |
} | |
} | |
} | |
return destination.ToArray(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment