Skip to content

Instantly share code, notes, and snippets.

@Demonslay335
Created November 1, 2021 18:17
Show Gist options
  • Save Demonslay335/9949802d0895690096c89272fd3bd1ca to your computer and use it in GitHub Desktop.
Save Demonslay335/9949802d0895690096c89272fd3bd1ca to your computer and use it in GitHub Desktop.
Depack aPLib in pure C#
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