public void Decompress(int unpackedLength) { while (unpackedLength > 0) { int flag = (byte)_input.ReadByte(); if (flag == 0) { return; } // RAW if (flag < 0x7E) { while (flag-- > 0) { byte b = (byte)_input.ReadByte(); _circularBuffer.Write(b); _output.WriteByte(b); unpackedLength--; } continue; } // RLE if (flag >= 0x7E && flag <= 0x7F) { int length = _input.ReadByte(); if (flag == 0x7E) // Однобайтная длина { length += 4; } else { length |= (_input.ReadByte() << 8); // Двухбайтная длина } byte b = (byte)_input.ReadByte(); while (length-- > 0) { _circularBuffer.Write(b); _output.WriteByte(b); unpackedLength--; } continue; } // LZ flag -= 0x80; int offset = (byte)_input.ReadByte() + (flag % 0x8) * 0x100; flag = (byte)(3 + (flag / 0x8)); for (int i = 0; i < flag; i++) { int index = (int)(_circularBuffer.Index - offset - 1); byte b = _circularBuffer.GetByOffset(index); _circularBuffer.Write(b); _output.WriteByte(b); unpackedLength--; } } ReverseProgress.NullSafeInvoke(this, unpackedLength); }
public void Decompress(int unpackedLength) { byte bits = 0, bitsCount = 0; while (unpackedLength != 0) { int b = _input.ReadByte(); if (b == -1) { throw new Exception("Непредвиденный конец входного потока."); } if (_input.Position % 256 == 0) { ReverseProgress.NullSafeInvoke(this, unpackedLength); } byte current = (byte)b; if (bitsCount == 0) { bits = current; bitsCount = 8; continue; } if ((bits & 1) != 0) { _output.WriteByte(current); _circularBuffer.Write(current); unpackedLength--; } else { short offset = current; b = _input.ReadByte(); if (b == -1) { throw new Exception("Непредвиденный конец входного потока."); } current = (byte)b; offset += (short)((current & 0xF0) << 4); short length = (short)((current & 0xF) + 3); for (int i = offset + 18; --length >= 0; i++) { i &= 0xFFF; current = _circularBuffer.GetByOffset(i); _output.WriteByte(current); _circularBuffer.Write(current); unpackedLength--; } } bits >>= 1; bitsCount--; } ReverseProgress.NullSafeInvoke(this, unpackedLength); }