/// <summary> /// Constructor which creates a new <see cref="ZLibStream" /> object and initializes it as a compression or a decompression one depending on the <paramref name="dir"/> parameter. /// </summary> /// <param name="stream">The stream containing compressed data for decompression or the stream to store compressed data for compression.</param> /// <param name="dir">One of the <see cref="CompressionDirection" /> values that indicates the action to take (compression or decompression).</param> /// <param name="leaveOpen">Whether we need to leave the underlying stream open when <see cref="ZLibStream.Close">closing</see> the current stream.</param> public ZLibStream(Stream stream, CompressionDirection dir, bool leaveOpen) { if (stream == null) { throw new ArgumentNullException("Stream to decompression cannot be null", "stream"); } this.compressionDirection = dir; this._stream = stream; this.leaveOpen = leaveOpen; if (dir == CompressionDirection.Compression) { if (!this._stream.CanWrite) { throw new ArgumentException("The stream is not writable", "stream"); } this.compressionStream = new ZOutputStream(this._stream, this.compLevel); } else { if (!this._stream.CanRead) { throw new ArgumentException("The stream is not readable", "stream"); } this.decompressionStream = new ZInputStream(this._stream); } }
/// <summary> /// Decompresses (inflates) bytes from input stream. /// </summary> /// <remarks> /// Stream marker is being set at +<code>numOfBytes</code> position of the stream. /// </remarks> /// <param name="buf">Input byte buffer stream.</param> /// <param name="numOfBytes">The number of bytes to be read.</param> /// <returns>new <c>ByteBuffer</c> with the inflated block of data.</returns> /// <exception cref="IOException">When an error occurs while reading or inflating the buffer.</exception> private Stream Inflate(Stream buf, int numOfBytes) { if (buf.Length - buf.Position < numOfBytes) { throw new MatlabIOException("Compressed buffer length miscalculated!"); } #if false // test code! byte[] byteBuffer = new byte[numOfBytes]; long pos = buf.Position; int n = buf.Read(byteBuffer, 0, numOfBytes); buf.Position = pos; File.WriteAllBytes("DeflatedMatlabData.bin", byteBuffer); #endif try { #if NET20 MemoryStream inflatedStream = new MemoryStream(numOfBytes); // copy all the compressed bytes to a new stream. byte[] compressedBytes = new byte[numOfBytes]; int numBytesRead = buf.Read(compressedBytes, 0, numOfBytes); if (numBytesRead != numOfBytes) { throw new IOException("numBytesRead != numOfBytes"); } // now use zlib on the compressedBytes MemoryStream compressedStream = new MemoryStream(compressedBytes); zlib.ZInputStream zis = new zlib.ZInputStream(compressedStream); Helpers.CopyStream(zis, inflatedStream); zis.Close(); inflatedStream.Position = 0; return(inflatedStream); #endif #if NET40 || NET45 // skip CRC (at end) and zip format (0x789C at begin) buf.Position += 2; numOfBytes -= 6; MemoryStream compressedStream = new MemoryStream(); int data; do { data = buf.ReadByte(); if (data != -1) { compressedStream.WriteByte((byte)(data & 0x000000FF)); } }while (data != -1 && compressedStream.Length < numOfBytes); // skip CRC buf.Position += 4; compressedStream.Position = 0; MemoryStream decompressedStream = new MemoryStream(); using (DeflateStream df = new DeflateStream(compressedStream, CompressionMode.Decompress)) { do { data = df.ReadByte(); if (data != -1) { decompressedStream.WriteByte((byte)(data & 0x000000FF)); } }while (data != -1); } decompressedStream.Position = 0; return(decompressedStream); #endif } catch (IOException e) { throw new MatlabIOException("Could not decompress data: " + e); } }