private static ReadBuffer UnpackPass(ReadBuffer packedData) { switch (packedData[0]) { case 1: return(UnpackRLE(packedData.Drop(8))); case 2: return(UnpackVLE(packedData.Drop(4))); default: throw new ArgumentException("Unknown compression type!"); } }
public static byte[] Unpack(byte[] packedData) { var buffer = new ReadBuffer(packedData); bool singlePass = (buffer[0] & 0x80) == 0; int passCount = singlePass ? 1 : buffer[0] & 0x7f; ReadBuffer currentPass = singlePass ? buffer : buffer.Drop(4); for (int i = 0; i < passCount; i++) { currentPass = UnpackPass(currentPass); } return(currentPass.ToArray()); }
private static ReadBuffer UnpackRLE(ReadBuffer packedData) { int escCount = packedData[0] & 0x7f; var escCodes = packedData.Slice(1, escCount); var rleData = packedData.Drop(escCount + 1); var escLookup = new byte[0x100]; for (int i = 0; i < escCount; i++) { escLookup[escCodes[i]] = (byte)(i + 1); } bool compressed = (packedData[0] & 0x80) == 0; var encodedData = compressed ? UnpackSequences(rleData, escCodes[1]) : rleData; var result = new WriteBuffer(); while (encodedData.Length > 0) { var code = escLookup[encodedData[0]]; switch (code) { case 0: result.Append(encodedData[0]); encodedData = encodedData.Drop(1); break; case 1: result.AppendRepeat(encodedData[2], encodedData[1]); encodedData = encodedData.Drop(3); break; case 3: result.AppendRepeat(encodedData[3], encodedData[1] + (((int)encodedData[2]) << 8)); encodedData = encodedData.Drop(4); break; default: result.AppendRepeat(encodedData[1], code - 1); encodedData = encodedData.Drop(2); break; } } return(result.ToReadBuffer()); }
private static ReadBuffer UnpackVLE(ReadBuffer packedData) { var widthsCount = packedData[0]; var widths = packedData.Slice(1, widthsCount); var alphabetCount = widths.Select(val => (int)val).Sum(); var alphabet = packedData.Slice(1 + widthsCount, alphabetCount); var dictionary = new HuffmanTree(widths, alphabet); var stream = EnumerateBits(packedData.Drop(1 + widthsCount + alphabetCount)); var result = new WriteBuffer(); while (true) { int value = dictionary.DecodeByte(stream); if (value < 0) { break; } result.Append((byte)value); } return(result.ToReadBuffer()); }