zlib

Language: C

Compression / Data

zlib was created by Jean-loup Gailly and Mark Adler in 1995. Its goal was to provide a free, efficient, and portable compression library that could be used across platforms. It has become one of the most widely used libraries for data compression in software development, forming the basis for formats like gzip and PNG.

zlib is a general-purpose, lossless data compression library written in C. It provides in-memory compression and decompression functions using the widely used DEFLATE algorithm, suitable for various applications including file compression, network protocols, and data storage.

Installation

linux: sudo apt install zlib1g-dev
mac: brew install zlib
windows: Download precompiled binaries or build from source at https://zlib.net/

Usage

zlib provides functions for compressing and decompressing data buffers in memory, reading and writing compressed files, and integrating with network protocols. It supports both streaming and one-shot compression/decompression operations.

Compressing a string in memory

#include <stdio.h>
#include <string.h>
#include <zlib.h>

int main() {
    char input[] = "Hello, zlib compression!";
    unsigned char compressed[100];
    uLongf compressed_len = sizeof(compressed);

    if (compress(compressed, &compressed_len, (const unsigned char*)input, strlen(input)+1) == Z_OK) {
        printf("Compressed length: %lu\n", compressed_len);
    }
    return 0;
}

Compresses a C string into a memory buffer using `compress()`.

Decompressing a string in memory

#include <stdio.h>
#include <string.h>
#include <zlib.h>

int main() {
    unsigned char compressed[] = { /* compressed data */ };
    unsigned char decompressed[100];
    uLongf decompressed_len = sizeof(decompressed);

    if (uncompress(decompressed, &decompressed_len, compressed, sizeof(compressed)) == Z_OK) {
        printf("Decompressed string: %s\n", decompressed);
    }
    return 0;
}

Decompresses a memory buffer back into the original string using `uncompress()`.

Using zlib streams for large data

#include <stdio.h>
#include <zlib.h>

int main() {
    z_stream strm = {0};
    deflateInit(&strm, Z_BEST_COMPRESSION);
    // Feed data to strm.next_in and strm.avail_in
    // Retrieve compressed data from strm.next_out
    deflateEnd(&strm);
    return 0;
}

Shows how to use `z_stream` and `deflateInit` for streaming compression of large datasets.

Writing a gzip file

#include <zlib.h>
#include <stdio.h>

int main() {
    gzFile file = gzopen("output.gz", "wb");
    gzwrite(file, "Hello gzip!", 11);
    gzclose(file);
    return 0;
}

Creates a gzip-compressed file and writes data to it using zlib’s `gzFile` API.

Reading a gzip file

#include <zlib.h>
#include <stdio.h>

int main() {
    char buffer[100];
    gzFile file = gzopen("output.gz", "rb");
    int bytes = gzread(file, buffer, sizeof(buffer)-1);
    buffer[bytes] = '\0';
    printf("Read: %s\n", buffer);
    gzclose(file);
    return 0;
}

Opens a gzip file, reads its contents, and prints the decompressed data.

Error Handling

Z_MEM_ERROR: Occurs when zlib cannot allocate enough memory. Reduce buffer size or free memory.
Z_BUF_ERROR: The output buffer is too small. Increase the size of the destination buffer.
Z_DATA_ERROR: The input data is corrupted or incomplete. Verify source data integrity.

Best Practices

Always check return codes for errors (Z_OK, Z_MEM_ERROR, Z_BUF_ERROR, etc.).

Use streaming APIs (`z_stream`) for large or continuous data instead of one-shot functions.

Release any resources using `deflateEnd()` or `inflateEnd()` to prevent memory leaks.

Choose compression levels based on performance vs. size trade-offs (Z_BEST_SPEED, Z_BEST_COMPRESSION).

Ensure the destination buffer is large enough to hold compressed or decompressed data.