The Lazy Programmer

March 17, 2010

.NET DeflateStream/zlib compatibility

Filed under: /NET,Programming — ferruccio @ 3:37 pm
Tags:

This is just a quick post to describe how to format compressed data with the .NET DeflateStream class so that it can be read back in a C or C++ program using zlib. Compressing data with DeflateStream is extremely simple. The original code I was using looked like this:

using (var compressor = new DeflateStream(data, CompressionMode.Compress))
    compressor.Write(bytes, 0, bytes.Length);

data is a MemoryStream that I used to serialize the compressed data to disk.

zlib refused to read it. It kept throwing a “zlib error” exception.

It turns out that although they use the same compression algorithm, zlib expects a header in front of the data and an adler-32 checksum at the end. The code is now:

data.WriteByte(0x58);
data.WriteByte(0x85);
using (var compressor = new DeflateStream(data, CompressionMode.Compress, true))
    compressor.Write(bytes, 0, bytes.Length);
data.Write(BitConverter.GetBytes(IPAddress.HostToNetworkOrder(Adler32(bytes))), 0, sizeof(uint));

the adler-32 code:

// naive implementation of adler-32 checksum
int Adler32(byte[] bytes) {
    const uint a32mod = 65521;
    uint s1 = 1, s2 = 0;
    foreach (byte b in bytes) {
        s1 = (s1 + b) % a32mod;
        s2 = (s2 + s1) % a32mod;
    }
    return unchecked((int) ((s2 << 16) + s1));
}

and zlib is happy again.

If you’re wondering what the magic numbers are, take a look at RFC 1950.

About these ads

The Rubric Theme. Create a free website or blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: