public static void DecompressInPlace(byte[] buffer, int headerEnd) { BackwardsReader reader = new BackwardsReader(buffer, headerEnd); int additionalDecLength = reader.ReadInt32(); int startOffset = reader.ReadInt32(); int compressedLength = reader.ReadInt32(); reader.SeekCurrent(12 - startOffset); int decBase = headerEnd - compressedLength; int decPos = compressedLength + additionalDecLength; byte mask = 0; byte header = 0; while (decPos > 0) { if ((mask >>= 1) == 0) { header = reader.ReadByte(); mask = 0x80; } if ((header & mask) == 0) { buffer[decBase + --decPos] = reader.ReadByte(); } else { ushort pair = (ushort)reader.ReadInt16(); int length = (pair >> 12) + 3; int position = (pair & 0xfff) + 3; if (length > decPos) { length = decPos; } decPos -= length; int dstPos = decBase + decPos; if (length <= position) { int srcPos = dstPos + position; Buffer.BlockCopy(buffer, srcPos, buffer, dstPos, length); } else { for (int offset = 0; offset < length; offset++) { buffer[dstPos + offset] = buffer[dstPos + position + offset]; } } } } }
public static byte[] Decompress(Stream input, int decompressedLength) { long end = input.Position; BackwardsReader reader = new BackwardsReader(input); int additionalDecLength = reader.ReadInt32(); int startOffset = reader.ReadInt32(); int compressedLength = reader.ReadInt32(); input.Seek(12 - startOffset, SeekOrigin.Current); byte[] dec = new byte[decompressedLength]; int decompressedLengthUnpadded = compressedLength + additionalDecLength; int decompressionStart = decompressedLength - decompressedLengthUnpadded; int decPos = dec.Length; byte mask = 0; byte header = 0; while (decPos > decompressionStart) { if ((mask >>= 1) == 0) { header = reader.ReadByte(); mask = 0x80; } if ((header & mask) == 0) { dec[--decPos] = reader.ReadByte(); } else { ushort pair = (ushort)reader.ReadInt16(); int length = (pair >> 12) + 3; int position = (pair & 0xfff) + 3; decPos -= length; if (length <= position) { int srcPos = decPos + position; Buffer.BlockCopy(dec, srcPos, dec, decPos, length); } else { for (int offset = 0; offset < length; offset++) { dec[decPos + offset] = dec[decPos + position + offset]; } } } } return(dec); }
public static byte[] Decompress(Stream Input, int DecompressedLength) { long End = Input.Position; BackwardsReader Reader = new BackwardsReader(Input); int AdditionalDecLength = Reader.ReadInt32(); int StartOffset = Reader.ReadInt32(); int CompressedLength = Reader.ReadInt32(); Input.Seek(12 - StartOffset, SeekOrigin.Current); byte[] Dec = new byte[DecompressedLength]; int DecompressedLengthUnpadded = CompressedLength + AdditionalDecLength; int DecompressionStart = DecompressedLength - DecompressedLengthUnpadded; int DecPos = Dec.Length; byte Mask = 0; byte Header = 0; while (DecPos > DecompressionStart) { if ((Mask >>= 1) == 0) { Header = Reader.ReadByte(); Mask = 0x80; } if ((Header & Mask) == 0) { Dec[--DecPos] = Reader.ReadByte(); } else { ushort Pair = (ushort)Reader.ReadInt16(); int Length = (Pair >> 12) + 3; int Position = (Pair & 0xfff) + 3; DecPos -= Length; if (Length <= Position) { int SrcPos = DecPos + Position; Buffer.BlockCopy(Dec, SrcPos, Dec, DecPos, Length); } else { for (int Offset = 0; Offset < Length; Offset++) { Dec[DecPos + Offset] = Dec[DecPos + Position + Offset]; } } } } return(Dec); }