public static bool Decompress(Stream input, Stream output) { if (!input.CanRead || !output.CanWrite) { return false; } BinaryReader reader = new BinaryReader(input); int header = reader.ReadInt32(); if ((header & 0xFF) != 0x10) { return false; } var slidingWindow = new LinkedList<byte>(); //var slidingWindow = new LinkedArrayList<byte>(); doesn't work int decompSize = header >> 8; long startPosition = output.Position; while ((output.Position - startPosition) < decompSize) { if (input.Position >= input.Length) return false; byte flags = reader.ReadByte(); for (int i = 0; i < BlockSize; i++) { if ((flags & (0x80 >> i)) != 0) { if (input.Position >= input.Length - 1) return false; byte first = reader.ReadByte(); byte second = reader.ReadByte(); int position = (((first << 8) + second + 1) & 0xFFF); int amountToCopy = (3 + ((first >> 4) & 0xF)); if (position > (output.Position - startPosition)) return false; byte[] dataToCopy = slidingWindow .EnumerateLast(position) .Repeat() .Take(amountToCopy) .ToArray(); output.Write(dataToCopy, 0, dataToCopy.Length); for (int slidingI = 0; slidingI < dataToCopy.Length; slidingI++) { slidingWindow.AddLast(dataToCopy[slidingI]); } slidingWindow.RemoveExtra(SlidingWindowSize); } else { if (input.Position > input.Length) return false; byte raw = reader.ReadByte(); slidingWindow.AddLast(raw); slidingWindow.RemoveExtra(SlidingWindowSize); output.WriteByte(raw); } if ((output.Position - startPosition) >= decompSize) break; } } slidingWindow.Clear(); return true; }