Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

.NET ZLib Implementation

0.00/5 (No votes)
17 Feb 2018 1  
Zlib compress / decompress implementation using .NET 4.5.1, with no external DLLs

Introduction

Some weeks ago, I discovered that Microsoft .NET 4.5 supports the Deflate version used in ZLib, and I decided to develop an implementation using only the .NET Framework.

This library has the basic Zlib functions, read and write, and supports the 3 .NET compression levels:

  1. Faster
  2. NoCompression
  3. Optimal

Inside the Code

My ZLib implementation has 3 classes:

  1. ZLibStream.cs
  2. ZLibHeader.cs
  3. Adler32.cs

ZlibStream

This class contains the I/O functions to correctly read or write the ZLib stream. Also, it has the control to determine if it's a supported ZLib stream or not.

ZLibHeader

The ZlibHeader class has the functions for encode or decode the ZLib header.

Adler32

This class has the functions for check the hash in Adler32. The result determines if the stream is correct or not.

How to Encode or Decode a ZLib Header

If you wish to encode a new ZLib header and get the correct 2 first bytes, you need to create a new instance of ZLibHeader. Then, you can set the properties as you want and call the function EncodeZlibHeader. This function will return the 2 bytes of the header.

private void GetZLibHeader()
{
    byte[] bytesHeader;

    //Create a new instance of ZLibHeader
    ZLibHeader header = new ZLibHeader();

    //Set the properties
    header.CompressionMethod = 8; //Deflate
    header.CompressionInfo = 7;

    header.FDict = false; //without dictionary. Note: This library doesn't support dictionary
    switch (this.mCompressionLevel)
    {
        case CompressionLevel.NoCompression:
            {
                header.FLevel = FLevel.Faster;
                break;
            }
        case CompressionLevel.Fastest:
            {
                header.FLevel = FLevel.Default;
                break;
            }
        case CompressionLevel.Optimal:
            {
                header.FLevel = FLevel.Optimal;
                break;
            }
    }

    bytesHeader = header.EncodeZlibHeader();
.
.
.
}

To decode is more easy, ZLibHeader has a static property that receives the 2 bytes of the header. The function will return an instance of ZLibHeader with all header information.

Using the Code for Compress or Decompress

The use of this library is very similar to using GZipStream. The only thing you need is to create a new instance of ZLIBStream, and read or write the wished stream.

//
// File compression
//
Using System.IO.Compression;
Using ZLib;

.
.
.

    OpenFileDialog dlgOpen = new OpenFileDialog();
    CompressionLevel level = CompressionLevel.Optimal;

    if (dlgOpen.ShowDialog() == DialogResult.OK) 
    {
        using (FileStream fsSource = new FileStream(dlgOpen.FileName, FileMode.Open, FileAccess.Read))
        {
            using (FileStream fsTarget = new FileStream(dlgOpen.FileName + ".zlib", 
                   FileMode.Create, FileAccess.Write))
            {
                using (ZLIBStream zs = new ZLIBStream(fsTarget, level, true))
                {
                    int bytesLeidos = 0;
                    byte[] buffer = new byte[1024];

                    while ((bytesLeidos = fsSource.Read(buffer, 0, buffer.Length)) > 0) 
                    {
                        zs.Write(buffer, 0,bytesLeidos);                        
                    }
                }
            }
        }            
    }
//
// File decompression
//
Using System.IO.Compression;
Using ZLib;

.
.
.

OpenFileDialog dlgOpen = new OpenFileDialog();

if (dlgOpen.ShowDialog() == DialogResult.OK)
{ 
    using (FileStream fsSource = new FileStream(dlgOpen.FileName, FileMode.Open, FileAccess.Read))
    {
        using (ZLIBStream zs = new ZLIBStream(fsSource, CompressionMode.Decompress, true))
        {
            using (FileStream fsTarget = new FileStream(dlgOpen.FileName + ".txt", 
                   FileMode.Create, FileAccess.Write))
            {
                int bytesLeidos = 0;
                byte[] buffer = new byte[1024];

                while ((bytesLeidos = zs.Read(buffer, 0, buffer.Length)) > 0)
                {
                    fsTarget.Write(buffer, 0, bytesLeidos);
                }

            }
        }
    }            
}

History

  • 17/02/2018: Improved some functions with bitwise operations
  • 16/02/2015: Initial release

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here