libpng

Language: C

Graphics / Image Processing

libpng was originally developed in 1996 as an open-source reference implementation for the PNG image format. It is widely used in graphics applications, game engines, and software that require handling of PNG images. The library focuses on speed, portability, and compliance with the PNG standard.

libpng is the official PNG reference library for C. It provides functions to read, write, and manipulate PNG (Portable Network Graphics) images, supporting compression, filtering, and color types.

Installation

linux: sudo apt install libpng-dev
mac: brew install libpng
windows: Download precompiled binaries from http://www.libpng.org/pub/png/libpng.html or build from source

Usage

libpng allows reading and writing PNG images, handling different color types (grayscale, RGB, RGBA), interlacing, and applying compression. It integrates with other image processing libraries for more advanced workflows.

Reading a PNG image

#include <png.h>
#include <stdio.h>

int main() {
    FILE *fp = fopen("image.png", "rb");
    if(!fp) return 1;

    png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    png_infop info = png_create_info_struct(png);
    png_init_io(png, fp);
    png_read_info(png, info);

    int width = png_get_image_width(png, info);
    int height = png_get_image_height(png, info);
    printf("Width: %d, Height: %d\n", width, height);

    png_destroy_read_struct(&png, &info, NULL);
    fclose(fp);
    return 0;
}

Opens a PNG file, reads its header information, and prints the width and height.

Writing a PNG image

#include <png.h>
#include <stdio.h>

int main() {
    FILE *fp = fopen("output.png", "wb");
    if(!fp) return 1;

    png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    png_infop info = png_create_info_struct(png);
    png_init_io(png, fp);

    int width = 100, height = 100;
    png_set_IHDR(png, info, width, height, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
                 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
    png_write_info(png, info);

    // Writing image data would go here (omitted for brevity)

    png_write_end(png, info);
    png_destroy_write_struct(&png, &info);
    fclose(fp);
    return 0;
}

Sets up libpng structures and writes PNG header information. Image data writing requires row buffers.

Handling RGBA pixels

// Read image and access pixel data using png_bytep rows[] and loop through width and height

Demonstrates how to manipulate individual RGBA pixels after reading the PNG image.

Applying compression level

png_set_compression_level(png, Z_BEST_COMPRESSION);

Sets the PNG compression level for writing, improving file size at the cost of CPU usage.

Interlacing support

png_set_interlace_handling(png);

Handles interlaced PNGs correctly when reading or writing images.

Error Handling

NULL pointer returned by png_create_read_struct: Ensure sufficient memory is available and libpng is initialized correctly.
libpng read error: Check file integrity and ensure it is a valid PNG file.
libpng write error: Ensure the file is writable and the PNG structures are properly initialized.

Best Practices

Always check return values for file operations and libpng functions.

Free libpng structures with png_destroy_read_struct or png_destroy_write_struct to avoid memory leaks.

Handle different color types correctly (grayscale, RGB, RGBA).

Use appropriate compression levels depending on performance vs file size trade-offs.

Consult PNG specifications for proper handling of filters and interlacing.