public static MemoryStream ReadEntry( Stream input, ArchiveFile.Entry entry, ArchiveCompressionMode mode, Endian endian) { switch (mode) { case ArchiveCompressionMode.Bogocrypt1: { var output = new MemoryStream(); var key = entry.BogocryptKey; long remaining = entry.Length; var block = new byte[1024]; while (remaining > 0) { var blockLength = (int)Math.Min(block.Length, remaining + 3 & ~3); var actualBlockLength = (int)Math.Min(block.Length, remaining); if (blockLength == 0) { throw new InvalidOperationException(); } if (input.Read(block, 0, blockLength) < actualBlockLength) { throw new EndOfStreamException(); } key = ArchiveFile.Bogocrypt1(block, 0, blockLength, key); output.Write(block, 0, actualBlockLength); remaining -= blockLength; } output.Position = 0; return(output); } case ArchiveCompressionMode.LZW: { var output = new MemoryStream(); LZW.Decompress(input, entry.Length, output, endian); output.Position = 0; return(output); } case ArchiveCompressionMode.MiniZ: { ISAAC isaac = null; var outputBytes = new byte[entry.Length]; var outputOffset = 0; var blockBytes = new byte[0x800]; long remaining = entry.Length; bool isCompressed = true; bool isLastBlock; do { var blockFlags = input.ReadValueU32(endian); var blockLength = (int)(blockFlags & ~0x80000000u); isLastBlock = (blockFlags & 0x80000000u) != 0; if (blockLength > blockBytes.Length) { throw new InvalidOperationException(); } if (input.Read(blockBytes, 0, blockLength) != blockLength) { throw new EndOfStreamException(); } if (isCompressed == false || (isLastBlock == false && blockLength == 1024)) { isCompressed = false; if (isaac == null) { isaac = entry.GetISAAC(); } int seed = 0; for (int o = 0; o < blockLength; o++) { if ((o & 3) != 0) { seed >>= 8; } else { seed = isaac.Value(); } blockBytes[o] ^= (byte)seed; } Array.Copy(blockBytes, 0, outputBytes, outputOffset, blockLength); outputOffset += blockLength; remaining -= blockLength; } else { using (var temp = new MemoryStream(blockBytes, false)) { var zlib = new InflaterInputStream(temp, new Inflater(true)); var read = zlib.Read(outputBytes, outputOffset, (int)Math.Min(remaining, 1024)); outputOffset += read; remaining -= read; } } }while (isLastBlock == false); return(new MemoryStream(outputBytes)); } case ArchiveCompressionMode.Bogocrypt2: { var blockBytes = new byte[1024]; var output = new MemoryStream(); long remaining = entry.Length; while (remaining >= 4) { var blockLength = (int)Math.Min(blockBytes.Length, remaining); if (input.Read(blockBytes, 0, blockLength) != blockLength) { throw new EndOfStreamException(); } ArchiveFile.Bogocrypt2(blockBytes, 0, blockLength); output.Write(blockBytes, 0, blockLength); remaining -= blockLength; } if (remaining > 0) { output.WriteFromStream(input, remaining); } output.Position = 0; return(output); } default: { throw new NotSupportedException(); } } }