Class ZlibCodec
Encoder and Decoder for ZLIB and DEFLATE (IETF RFC1950 and RFC1951).
Inheritance
Inherited Members
Namespace: OfficeOpenXml.Packaging.Ionic.Zlib
Assembly: EPPlus.dll
Syntax
public sealed class ZlibCodec
Remarks
This class compresses and decompresses data according to the Deflate algorithm and optionally, the ZLIB format, as documented in RFC 1950 - ZLIB and RFC 1951 - DEFLATE.
Constructors
ZlibCodec()
Create a ZlibCodec.
Declaration
public ZlibCodec()
Remarks
If you use this default constructor, you will later have to explicitly call InitializeInflate() or InitializeDeflate() before using the ZlibCodec to compress or decompress.
ZlibCodec(CompressionMode)
Create a ZlibCodec that either compresses or decompresses.
Declaration
public ZlibCodec(CompressionMode mode)
Parameters
Type | Name | Description |
---|---|---|
CompressionMode | mode | Indicates whether the codec should compress (deflate) or decompress (inflate). |
Fields
AvailableBytesIn
The number of bytes available in the InputBuffer, starting at NextIn.
Declaration
public int AvailableBytesIn
Field Value
Type | Description |
---|---|
System.Int32 |
Remarks
Generally you should set this to InputBuffer.Length before the first Inflate() or Deflate() call. The class will update this number as calls to Inflate/Deflate are made.
AvailableBytesOut
The number of bytes available in the OutputBuffer, starting at NextOut.
Declaration
public int AvailableBytesOut
Field Value
Type | Description |
---|---|
System.Int32 |
Remarks
Generally you should set this to OutputBuffer.Length before the first Inflate() or Deflate() call. The class will update this number as calls to Inflate/Deflate are made.
CompressLevel
The compression level to use in this codec. Useful only in compression mode.
Declaration
public CompressionLevel CompressLevel
Field Value
Type | Description |
---|---|
CompressionLevel |
InputBuffer
The buffer from which data is taken.
Declaration
public byte[] InputBuffer
Field Value
Type | Description |
---|---|
System.Byte[] |
Message
used for diagnostics, when something goes wrong!
Declaration
public string Message
Field Value
Type | Description |
---|---|
System.String |
NextIn
An index into the InputBuffer array, indicating where to start reading.
Declaration
public int NextIn
Field Value
Type | Description |
---|---|
System.Int32 |
NextOut
An index into the OutputBuffer array, indicating where to start writing.
Declaration
public int NextOut
Field Value
Type | Description |
---|---|
System.Int32 |
OutputBuffer
Buffer to store output data.
Declaration
public byte[] OutputBuffer
Field Value
Type | Description |
---|---|
System.Byte[] |
Strategy
The compression strategy to use.
Declaration
public CompressionStrategy Strategy
Field Value
Type | Description |
---|---|
CompressionStrategy |
Remarks
This is only effective in compression. The theory offered by ZLIB is that different strategies could potentially produce significant differences in compression behavior for different data sets. Unfortunately I don't have any good recommendations for how to set it differently. When I tested changing the strategy I got minimally different compression performance. It's best to leave this property alone if you don't have a good feel for it. Or, you may want to produce a test harness that runs through the different strategy options and evaluates them on different file types. If you do that, let me know your results.
TotalBytesIn
Total number of bytes read so far, through all calls to Inflate()/Deflate().
Declaration
public long TotalBytesIn
Field Value
Type | Description |
---|---|
System.Int64 |
TotalBytesOut
Total number of bytes written to the output so far, through all calls to Inflate()/Deflate().
Declaration
public long TotalBytesOut
Field Value
Type | Description |
---|---|
System.Int64 |
WindowBits
The number of Window Bits to use.
Declaration
public int WindowBits
Field Value
Type | Description |
---|---|
System.Int32 |
Remarks
This gauges the size of the sliding window, and hence the compression effectiveness as well as memory consumption. It's best to just leave this setting alone if you don't know what it is. The maximum value is 15 bits, which implies a 32k window.
Properties
Adler32
The Adler32 checksum on the data transferred through the codec so far. You probably don't need to look at this.
Declaration
public int Adler32 { get; }
Property Value
Type | Description |
---|---|
System.Int32 |
Methods
Deflate(FlushType)
Deflate one batch of data.
Declaration
public int Deflate(FlushType flush)
Parameters
Type | Name | Description |
---|---|---|
FlushType | flush | whether to flush all data as you deflate. Generally you will want to use Z_NO_FLUSH here, in a series of calls to Deflate(), and then call EndDeflate() to flush everything. |
Returns
Type | Description |
---|---|
System.Int32 | Z_OK if all goes well. |
Remarks
You must have set InputBuffer and OutputBuffer before calling this method.
Examples
private void DeflateBuffer(CompressionLevel level)
{
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
ZlibCodec compressor = new ZlibCodec();
Console.WriteLine("\n============================================");
Console.WriteLine("Size of Buffer to Deflate: {0} bytes.", UncompressedBytes.Length);
MemoryStream ms = new MemoryStream();
int rc = compressor.InitializeDeflate(level);
compressor.InputBuffer = UncompressedBytes;
compressor.NextIn = 0;
compressor.AvailableBytesIn = UncompressedBytes.Length;
compressor.OutputBuffer = buffer;
// pass 1: deflate
do
{
compressor.NextOut = 0;
compressor.AvailableBytesOut = buffer.Length;
rc = compressor.Deflate(FlushType.None);
if (rc != ZlibConstants.Z_OK && rc != ZlibConstants.Z_STREAM_END)
throw new Exception("deflating: " + compressor.Message);
ms.Write(compressor.OutputBuffer, 0, buffer.Length - compressor.AvailableBytesOut);
}
while (compressor.AvailableBytesIn > 0 || compressor.AvailableBytesOut == 0);
// pass 2: finish and flush
do
{
compressor.NextOut = 0;
compressor.AvailableBytesOut = buffer.Length;
rc = compressor.Deflate(FlushType.Finish);
if (rc != ZlibConstants.Z_STREAM_END && rc != ZlibConstants.Z_OK)
throw new Exception("deflating: " + compressor.Message);
if (buffer.Length - compressor.AvailableBytesOut > 0)
ms.Write(buffer, 0, buffer.Length - compressor.AvailableBytesOut);
}
while (compressor.AvailableBytesIn > 0 || compressor.AvailableBytesOut == 0);
compressor.EndDeflate();
ms.Seek(0, SeekOrigin.Begin);
CompressedBytes = new byte[compressor.TotalBytesOut];
ms.Read(CompressedBytes, 0, CompressedBytes.Length);
}
EndDeflate()
End a deflation session.
Declaration
public int EndDeflate()
Returns
Type | Description |
---|---|
System.Int32 | Z_OK if all goes well. |
Remarks
Call this after making a series of one or more calls to Deflate(). All buffers are flushed.
EndInflate()
Ends an inflation session.
Declaration
public int EndInflate()
Returns
Type | Description |
---|---|
System.Int32 | Z_OK if everything goes well. |
Remarks
Call this after successively calling Inflate(). This will cause all buffers to be flushed. After calling this you cannot call Inflate() without a intervening call to one of the InitializeInflate() overloads.
Inflate(FlushType)
Inflate the data in the InputBuffer, placing the result in the OutputBuffer.
Declaration
public int Inflate(FlushType flush)
Parameters
Type | Name | Description |
---|---|---|
FlushType | flush | The flush to use when inflating. |
Returns
Type | Description |
---|---|
System.Int32 | Z_OK if everything goes well. |
Remarks
You must have set InputBuffer and OutputBuffer, NextIn and NextOut, and AvailableBytesIn and AvailableBytesOut before calling this method.
Examples
private void InflateBuffer()
{
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
ZlibCodec decompressor = new ZlibCodec();
Console.WriteLine("\n============================================");
Console.WriteLine("Size of Buffer to Inflate: {0} bytes.", CompressedBytes.Length);
MemoryStream ms = new MemoryStream(DecompressedBytes);
int rc = decompressor.InitializeInflate();
decompressor.InputBuffer = CompressedBytes;
decompressor.NextIn = 0;
decompressor.AvailableBytesIn = CompressedBytes.Length;
decompressor.OutputBuffer = buffer;
// pass 1: inflate
do
{
decompressor.NextOut = 0;
decompressor.AvailableBytesOut = buffer.Length;
rc = decompressor.Inflate(FlushType.None);
if (rc != ZlibConstants.Z_OK && rc != ZlibConstants.Z_STREAM_END)
throw new Exception("inflating: " + decompressor.Message);
ms.Write(decompressor.OutputBuffer, 0, buffer.Length - decompressor.AvailableBytesOut);
}
while (decompressor.AvailableBytesIn > 0 || decompressor.AvailableBytesOut == 0);
// pass 2: finish and flush
do
{
decompressor.NextOut = 0;
decompressor.AvailableBytesOut = buffer.Length;
rc = decompressor.Inflate(FlushType.Finish);
if (rc != ZlibConstants.Z_STREAM_END && rc != ZlibConstants.Z_OK)
throw new Exception("inflating: " + decompressor.Message);
if (buffer.Length - decompressor.AvailableBytesOut > 0)
ms.Write(buffer, 0, buffer.Length - decompressor.AvailableBytesOut);
}
while (decompressor.AvailableBytesIn > 0 || decompressor.AvailableBytesOut == 0);
decompressor.EndInflate();
}
InitializeDeflate()
Initialize the ZlibCodec for deflation operation.
Declaration
public int InitializeDeflate()
Returns
Type | Description |
---|---|
System.Int32 | Z_OK if all goes well. You generally don't need to check the return code. |
Remarks
The codec will use the MAX window bits and the default level of compression.
Examples
int bufferSize = 40000;
byte[] CompressedBytes = new byte[bufferSize];
byte[] DecompressedBytes = new byte[bufferSize];
ZlibCodec compressor = new ZlibCodec();
compressor.InitializeDeflate(CompressionLevel.Default);
compressor.InputBuffer = System.Text.ASCIIEncoding.ASCII.GetBytes(TextToCompress);
compressor.NextIn = 0;
compressor.AvailableBytesIn = compressor.InputBuffer.Length;
compressor.OutputBuffer = CompressedBytes;
compressor.NextOut = 0;
compressor.AvailableBytesOut = CompressedBytes.Length;
while (compressor.TotalBytesIn != TextToCompress.Length && compressor.TotalBytesOut < bufferSize)
{
compressor.Deflate(FlushType.None);
}
while (true)
{
int rc= compressor.Deflate(FlushType.Finish);
if (rc == ZlibConstants.Z_STREAM_END) break;
}
compressor.EndDeflate();
InitializeDeflate(CompressionLevel)
Initialize the ZlibCodec for deflation operation, using the specified CompressionLevel.
Declaration
public int InitializeDeflate(CompressionLevel level)
Parameters
Type | Name | Description |
---|---|---|
CompressionLevel | level | The compression level for the codec. |
Returns
Type | Description |
---|---|
System.Int32 | Z_OK if all goes well. |
Remarks
The codec will use the maximum window bits (15) and the specified CompressionLevel. It will emit a ZLIB stream as it compresses.
InitializeDeflate(CompressionLevel, Boolean)
Initialize the ZlibCodec for deflation operation, using the specified CompressionLevel, and the explicit flag governing whether to emit an RFC1950 header byte pair.
Declaration
public int InitializeDeflate(CompressionLevel level, bool wantRfc1950Header)
Parameters
Type | Name | Description |
---|---|---|
CompressionLevel | level | The compression level for the codec. |
System.Boolean | wantRfc1950Header | whether to emit an initial RFC1950 byte pair in the compressed stream. |
Returns
Type | Description |
---|---|
System.Int32 | Z_OK if all goes well. |
Remarks
The codec will use the maximum window bits (15) and the specified CompressionLevel. If you want to generate a zlib stream, you should specify true for wantRfc1950Header. In this case, the library will emit a ZLIB header, as defined in RFC 1950, in the compressed stream.
InitializeDeflate(CompressionLevel, Int32)
Initialize the ZlibCodec for deflation operation, using the specified CompressionLevel, and the specified number of window bits.
Declaration
public int InitializeDeflate(CompressionLevel level, int bits)
Parameters
Type | Name | Description |
---|---|---|
CompressionLevel | level | The compression level for the codec. |
System.Int32 | bits | the number of window bits to use. If you don't know what this means, don't use this method. |
Returns
Type | Description |
---|---|
System.Int32 | Z_OK if all goes well. |
Remarks
The codec will use the specified number of window bits and the specified CompressionLevel.
InitializeDeflate(CompressionLevel, Int32, Boolean)
Initialize the ZlibCodec for deflation operation, using the specified CompressionLevel, the specified number of window bits, and the explicit flag governing whether to emit an RFC1950 header byte pair.
Declaration
public int InitializeDeflate(CompressionLevel level, int bits, bool wantRfc1950Header)
Parameters
Type | Name | Description |
---|---|---|
CompressionLevel | level | The compression level for the codec. |
System.Int32 | bits | the number of window bits to use. If you don't know what this means, don't use this method. |
System.Boolean | wantRfc1950Header | whether to emit an initial RFC1950 byte pair in the compressed stream. |
Returns
Type | Description |
---|---|
System.Int32 | Z_OK if all goes well. |
InitializeInflate()
Initialize the inflation state.
Declaration
public int InitializeInflate()
Returns
Type | Description |
---|---|
System.Int32 | Z_OK if everything goes well. |
Remarks
It is not necessary to call this before using the ZlibCodec to inflate data; It is implicitly called when you call the constructor.
InitializeInflate(Boolean)
Initialize the inflation state with an explicit flag to govern the handling of RFC1950 header bytes.
Declaration
public int InitializeInflate(bool expectRfc1950Header)
Parameters
Type | Name | Description |
---|---|---|
System.Boolean | expectRfc1950Header | whether to expect an RFC1950 header byte pair when reading the stream of data to be inflated. |
Returns
Type | Description |
---|---|
System.Int32 | Z_OK if everything goes well. |
Remarks
By default, the ZLIB header defined in RFC 1950 is expected. If you want to read a zlib stream you should specify true for expectRfc1950Header. If you have a deflate stream, you will want to specify false. It is only necessary to invoke this initializer explicitly if you want to specify false.
InitializeInflate(Int32)
Initialize the ZlibCodec for inflation, with the specified number of window bits.
Declaration
public int InitializeInflate(int windowBits)
Parameters
Type | Name | Description |
---|---|---|
System.Int32 | windowBits | The number of window bits to use. If you need to ask what that is, then you shouldn't be calling this initializer. |
Returns
Type | Description |
---|---|
System.Int32 | Z_OK if all goes well. |
InitializeInflate(Int32, Boolean)
Initialize the inflation state with an explicit flag to govern the handling of RFC1950 header bytes.
Declaration
public int InitializeInflate(int windowBits, bool expectRfc1950Header)
Parameters
Type | Name | Description |
---|---|---|
System.Int32 | windowBits | The number of window bits to use. If you need to ask what that is, then you shouldn't be calling this initializer. |
System.Boolean | expectRfc1950Header | whether to expect an RFC1950 header byte pair when reading the stream of data to be inflated. |
Returns
Type | Description |
---|---|
System.Int32 | Z_OK if everything goes well. |
Remarks
If you want to read a zlib stream you should specify true for expectRfc1950Header. In this case, the library will expect to find a ZLIB header, as defined in RFC 1950, in the compressed stream. If you will be reading a DEFLATE or GZIP stream, which does not have such a header, you will want to specify false.
ResetDeflate()
Reset a codec for another deflation session.
Declaration
public void ResetDeflate()
Remarks
Call this to reset the deflation state. For example if a thread is deflating non-consecutive blocks, you can call Reset() after the Deflate(Sync) of the first block and before the next Deflate(None) of the second block.
SetDeflateParams(CompressionLevel, CompressionStrategy)
Set the CompressionStrategy and CompressionLevel for a deflation session.
Declaration
public int SetDeflateParams(CompressionLevel level, CompressionStrategy strategy)
Parameters
Type | Name | Description |
---|---|---|
CompressionLevel | level | the level of compression to use. |
CompressionStrategy | strategy | the strategy to use for compression. |
Returns
Type | Description |
---|---|
System.Int32 | Z_OK if all goes well. |
SetDictionary(Byte[])
Set the dictionary to be used for either Inflation or Deflation.
Declaration
public int SetDictionary(byte[] dictionary)
Parameters
Type | Name | Description |
---|---|---|
System.Byte[] | dictionary | The dictionary bytes to use. |
Returns
Type | Description |
---|---|
System.Int32 | Z_OK if all goes well. |
SyncInflate()
I don't know what this does!
Declaration
public int SyncInflate()
Returns
Type | Description |
---|---|
System.Int32 | Z_OK if everything goes well. |