/// <summary> /// Decompressed (inflates) a compressed byte array using the Inflate algorithm. /// </summary> /// <param name="compressedData">The deflate-compressed data</param> /// <param name="dictionary">The dictionary originally used to compress the data, or null if no dictionary was used.</param> /// <returns>The uncompressed data</returns> internal static byte[] ZlibDecompressWithDictionary(byte[] compressedData, byte[] dictionary) { using (var ms = new MemoryStream()) { const int bufferSize = 256; var buffer = new byte[bufferSize]; var codec = new ZlibCodec { InputBuffer = compressedData, NextIn = 0, AvailableBytesIn = compressedData.Length }; codec.AssertOk("InitializeInflate", codec.InitializeInflate(false)); if (dictionary != null) { codec.AssertOk("SetDictionary", codec.SetDictionary(dictionary)); } codec.OutputBuffer = buffer; while (true) { codec.NextOut = 0; codec.AvailableBytesOut = bufferSize; var inflateReturnCode = codec.Inflate(FlushType.None); var bytesToWrite = bufferSize - codec.AvailableBytesOut; ms.Write(buffer, 0, bytesToWrite); if (inflateReturnCode == ZlibConstants.Z_STREAM_END) { break; } else if (inflateReturnCode == ZlibConstants.Z_NEED_DICT && dictionary != null) { //implies bytesToWrite was 0 var dictionaryAdler32 = ((int)Adler.Adler32(1u, dictionary, 0, dictionary.Length)); if (codec.Adler32 != dictionaryAdler32) { throw new InvalidOperationException("Compressed data is requesting a dictionary with adler32 " + codec.Adler32 + ", but the dictionary is actually " + dictionaryAdler32); } codec.AssertOk("SetDictionary", codec.SetDictionary(dictionary)); } else { codec.AssertOk("Inflate", inflateReturnCode); } } codec.AssertOk("EndInflate", codec.EndInflate()); return(ms.ToArray()); } }
private async ValueTask RunZlibCompress() { var zlibCodec = new ZlibCodec(); var buffer = new byte[1024]; zlibCodec.OutputBuffer = buffer; var result = zlibCodec.InitializeDeflate(); if (result < 0) { throw new InvalidOperationException( $"Got error code {result} when initializing deflate routine: {zlibCodec.Message}"); } result = zlibCodec.SetDictionary(_dictionary); if (result < 0) { throw new InvalidOperationException( $"Got error code {result} when setting dictionary: {zlibCodec.Message}"); } Exception?exception = null; try { System.IO.Pipelines.ReadResult inputBuffer; do { inputBuffer = await _pipe .Reader.ReadAsync(CancellationToken) .ConfigureAwait(false); foreach (var input in inputBuffer.Buffer) { zlibCodec.NextIn = 0; zlibCodec.InputBuffer = input.ToArray(); zlibCodec.AvailableBytesIn = input.Length; while (zlibCodec.AvailableBytesIn > 0) { zlibCodec.NextOut = 0; zlibCodec.AvailableBytesOut = buffer.Length; var start = zlibCodec.NextOut; result = zlibCodec.Deflate(FlushType.None); if (result < 0) { throw new InvalidOperationException( $"Got error code {result} when deflating the stream: {zlibCodec.Message}"); } var length = zlibCodec.NextOut - start; await _outputStream.WriteAsync( buffer, start, length, CancellationToken) .ConfigureAwait(false); } } _pipe.Reader.AdvanceTo(inputBuffer.Buffer.End); } while (inputBuffer.HasMoreData()); zlibCodec.InputBuffer = Array.Empty <byte>(); zlibCodec.NextIn = 0; zlibCodec.AvailableBytesIn = 0; zlibCodec.NextOut = 0; zlibCodec.AvailableBytesOut = buffer.Length; var bufferStart = zlibCodec.NextOut; result = zlibCodec.Deflate(FlushType.Sync); if (result != ZlibConstants.Z_OK) { throw new InvalidOperationException($"Expected OK, got {result}"); } result = zlibCodec.Deflate(FlushType.Finish); if (result != ZlibConstants.Z_STREAM_END) { throw new InvalidOperationException($"Expected END, got {result}"); } var bufferLength = zlibCodec.NextOut - bufferStart; await _outputStream.WriteAsync( buffer, bufferStart, bufferLength, CancellationToken) .ConfigureAwait(false); await _outputStream.FlushAsync(CancellationToken) .ConfigureAwait(false); } catch (Exception ex) { exception = ex; } finally { zlibCodec.EndDeflate(); await _pipe.Reader.CompleteAsync(exception) .ConfigureAwait(false); } }
private void Run() { int rc; int bufferSize = 40000; byte[] compressedBytes = new byte[bufferSize]; byte[] decompressedBytes = new byte[bufferSize]; ZlibCodec compressingStream = new ZlibCodec(); rc = compressingStream.InitializeDeflate(CompressionLevel.LEVEL9_BEST_COMPRESSION); CheckForError(compressingStream, rc, "InitializeDeflate"); string dictionaryWord = "hello "; byte[] dictionary = System.Text.ASCIIEncoding.ASCII.GetBytes(dictionaryWord); string TextToCompress = "hello, hello! How are you, Joe? "; byte[] BytesToCompress = System.Text.ASCIIEncoding.ASCII.GetBytes(TextToCompress); rc = compressingStream.SetDictionary(dictionary); CheckForError(compressingStream, rc, "SetDeflateDictionary"); long dictId = compressingStream.Adler32; compressingStream.OutputBuffer = compressedBytes; compressingStream.NextOut = 0; compressingStream.AvailableBytesOut = bufferSize; compressingStream.InputBuffer = BytesToCompress; compressingStream.NextIn = 0; compressingStream.AvailableBytesIn = BytesToCompress.Length; rc = compressingStream.Deflate(ZlibConstants.Z_FINISH); if (rc != ZlibConstants.Z_STREAM_END) { System.Console.Out.WriteLine("deflate should report Z_STREAM_END"); System.Environment.Exit(1); } rc = compressingStream.EndDeflate(); CheckForError(compressingStream, rc, "deflateEnd"); ZlibCodec decompressingStream = new ZlibCodec(); decompressingStream.InputBuffer = compressedBytes; decompressingStream.NextIn = 0; decompressingStream.AvailableBytesIn = bufferSize; rc = decompressingStream.InitializeInflate(); CheckForError(decompressingStream, rc, "inflateInit"); decompressingStream.OutputBuffer = decompressedBytes; decompressingStream.NextOut = 0; decompressingStream.AvailableBytesOut = decompressedBytes.Length; while (true) { rc = decompressingStream.Inflate(ZlibConstants.Z_NO_FLUSH); if (rc == ZlibConstants.Z_STREAM_END) { break; } if (rc == ZlibConstants.Z_NEED_DICT) { if ((int)decompressingStream.Adler32 != (int)dictId) { System.Console.Out.WriteLine("unexpected dictionary"); System.Environment.Exit(1); } rc = decompressingStream.SetDictionary(dictionary); } CheckForError(decompressingStream, rc, "inflate with dict"); } rc = decompressingStream.EndInflate(); CheckForError(decompressingStream, rc, "EndInflate"); int j = 0; for (; j < decompressedBytes.Length; j++) { if (decompressedBytes[j] == 0) { break; } } var result = System.Text.ASCIIEncoding.ASCII.GetString(decompressedBytes, 0, j); Console.WriteLine("orig length: {0}", TextToCompress.Length); Console.WriteLine("compressed length: {0}", compressingStream.TotalBytesOut); Console.WriteLine("decompressed length: {0}", decompressingStream.TotalBytesOut); Console.WriteLine("result length: {0}", result.Length); Console.WriteLine("result of inflate:\n{0}", result); }