public static byte[] DecompressLZ77(this BinaryReader reader, long inputEnd, int outputSize, bool acceptInputOverflow = false, bool ffEscape = false)
{
byte[] output = new byte[outputSize];
int outputOffset = 0;
Stream stream = reader.BaseStream;
while (outputOffset < outputSize) {
if (stream.Position >= inputEnd) {
if (acceptInputOverflow) {
byte[] slice = new byte[outputOffset];
Array.Copy(output, slice, outputOffset);
return slice;
}
throw new OverflowException(String.Format("Input overflow at inputOffset {0}, for outputOffset {1} of outputSize {2}.", stream.Position, outputOffset, outputSize));
}
var flags = reader.ReadByte();
if (ffEscape && flags == 0xFF) {
while (stream.Position < inputEnd && outputOffset < outputSize && (flags = reader.ReadByte()) != 0xFF)
output[outputOffset++] = flags;
} else {
for (int flagBit = 7; flagBit >= 0 && outputOffset < outputSize && stream.Position < inputEnd; flagBit--) {
if ((flags & (1 << flagBit)) != 0) {
if (stream.Position + 2 > inputEnd) {
reader.ReadByte();
break;
}
var code = reader.ReadUInt16();
var displacement = (((code & 15) << 8) | (code >> 8)) + 1;
var length = ((code >> 4) & 15) + 3;
for (int index = 0; index < length && outputOffset < outputSize; index++, outputOffset++)
output[outputOffset] = (outputOffset - displacement >= 0) ? output[outputOffset - displacement] : (byte)0;
} else
output[outputOffset++] = reader.ReadByte();
}
}
}
return output;
}