private static ReadBuffer UnpackSequences(ReadBuffer packedData, byte seqMarker) { var remaining = packedData; var result = new WriteBuffer(); while (remaining.Length > 0) { var value = remaining[0]; remaining = remaining.Drop(1); if (value != seqMarker) { result.Append(value); } else { var sequence = remaining.TakeUntil(seqMarker); var count = remaining[sequence.Length + 1]; for (int i = 0; i < count; i++) { result.Append(sequence); } remaining = remaining.Drop(sequence.Length + 2); } } return(result.ToReadBuffer()); }
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()); }