SkillAgentSearch skills...

Zigimg

Zig library for reading and writing different image formats

Install / Use

/learn @zigimg/Zigimg
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

Zig Image library

This is a work in progress library to create, process, read and write different image formats with Zig programming language.

License Issue Commit CI

Join our Discord!

Install & Build

This library currently uses zig 0.15.2, we do plan to go back to using mach nominated zig until a newer version than 0.15.2 will be nominated.

Use zigimg in your project

How to add to your project:

As a submodule

  1. Clone this repository or add as a submodule
  2. Add to your build.zig
pub fn build(b: *std.Build) void {
    exe.root_module.addAnonymousModule("zigimg", .{ .root_source_file = b.path("zigimg.zig") });
}

Through the package manager

  1. Run this command in your project folder to add zigimg to your build.zig.zon
zig fetch --save git+https://github.com/zigimg/zigimg.git
  1. Get the module in your build.zig file
const zigimg_dependency = b.dependency("zigimg", .{
    .target = target,
    .optimize = optimize,
});

exe.root_module.addImport("zigimg", zigimg_dependency.module("zigimg"));

After you are done setting up, you can look at the user guide below.

Test suite

To run the test suite, checkout the test suite and run

  1. Checkout zigimg
  2. Go back one folder and checkout the test suite
  3. Run the tests with zig build
zig build test

Supported image formats

| Image Format | Read | Write | | ------------- |:-------------:|:--------------:| | ANIM | ❌ | ❌ | | BMP | ✔️ (Partial) | ✔️ (Partial) | | Farbfeld | ✔️ | ✔️ | | GIF | ✔️ | ✔️ | | ICO | ❌ | ❌ | | IFF | ✔️ | ❌ | | JPEG | ✔️ (Partial) | ✔️ | | PAM | ✔️ | ✔️ | | PBM | ✔️ | ✔️ | | PCX | ✔️ | ✔️ | | PGM | ✔️ (Partial) | ✔️ (Partial) | | PNG | ✔️ | ✔️ (Partial) | | PPM | ✔️ (Partial) | ✔️ (Partial) | | QOI | ✔️ | ✔️ | | SGI | ✔️ | ❌ | | SUN | ✔️ | ❌ | | TGA | ✔️ | ✔️ | | TIFF | ✔️ (Partial) | ❌ | | XBM | ✔️ | ❌ | | XPM | ❌ | ❌ |

BMP - Bitmap

  • version 4 BMP
  • version 5 BMP
  • 24-bit RGB read & write
  • 32-bit RGBA read & write
  • Doesn't support any compression

GIF - Graphics Interchange Format

  • Support GIF87a and GIF89a
  • Support animated GIF with Netscape application extension for looping information
  • Supports interlaced
  • Supports tiled and layered images used to achieve pseudo true color and more.
  • The plain text extension is not supported

IFF - InterchangeFileFormat

  • Supports 1-8 bit, 24 bit, HAM6/8, EHB ILBM files
  • Supports uncompressed, byterun 1 & 2 (Atari) compressed ILBM files
  • Supports PBM (Deluxe Paint DOS) encoded files
  • Supports ACBM (Amiga Basic) files
  • Color cycle chunks are ignored
  • Mask is not supported (skipped)

JPEG - Joint Photographic Experts Group

  • 8-bit baseline and progressive

PAM - Portable Arbitrary Map

Currently, this only supports a subset of PAMs where:

  • The tuple type is official (see man 5 pam) or easily inferred (and by extension, depth is 4 or less)
  • All the images in a sequence have the same dimensions and maxval (it is technically possible to support animations with different maxvals and tuple types as each AnimationFrame has its own PixelStorage, however, this is likely not expected by users of the library)
  • Grayscale,
  • Grayscale with alpha
  • Rgb555
  • Rgb24 and Rgba32
  • Bgr24 and Bgra32
  • Rgb48 and Rgba64

PBM - Portable Bitmap format

  • Everything is supported

PCX - ZSoft Picture Exchange format

  • Support monochrome, 4 color, 16 color and 256 color indexed images
  • Support 24-bit RGB images

PGM - Portable Graymap format

  • Support 8-bit and 16-bit grayscale images
  • 16-bit ascii grayscale loading not tested

PNG - Portable Network Graphics

  • Support all pixel formats supported by PNG (grayscale, grayscale+alpha, indexed, truecolor, truecolor with alpha) in 8-bit or 16-bit.
  • Support the mininal chunks in order to decode the image.
  • Can write all supported pixel formats but writing interlaced images is not supported yet.

PPM - Portable Pixmap format

  • Support 24-bit RGB (8-bit per channel)
  • Missing 48-bit RGB (16-bit per channel)

QOI - Quite OK Image format

  • Imported from https://github.com/MasterQ32/zig-qoi with blessing of the author

SGI - Silicon Graphics Image

  • Supports 8-bit, RGB (24/48-bit), RGBA(32/64-bit) files
  • Supports RLE and uncompressed files

SUN - Sun Raster format

  • Supports 1/8/24/32-bit files
  • Supports uncompressed & RLE files
  • Supports BGR/RGB encoding
  • TIFF/IFF/Experimental encoding is not supported

TGA - Truevision TGA format

  • Supports uncompressed and compressed 8-bit grayscale, indexed with 16-bit and 24-bit colormap, truecolor with 16-bit(RGB555), 24-bit or 32-bit bit depth.
  • Supports reading version 1 and version 2
  • Supports writing version 2

TIFF - Tagged Image File Format

What's supported:

  • bilevel, grayscale, palette and RGB(A) files
  • most baseline tags
  • Raw, LZW, Deflate, PackBits, CCITT 1D files
  • big-endian (MM) and little-endian (II) files should both be decoded fine

What's missing:

  • Tile-based files are not supported
  • YCbCr, CMJN and CIE Lab files are not supported
  • JPEG, CCITT Fax 3 / 4 are not supported yet

Notes

  • Only the first IFD is decoded
  • Orientation tag is not supported yet

XBM - X BitMap format

  • Everything is supported

Supported Pixel formats

  • Indexed: 1bpp (bit per pixel), 2bpp, 4bpp, 8bpp, 16bpp
  • Grayscale: 1bpp, 2bpp, 4bpp, 8bpp, 16bpp, 8bpp with alpha, 16bpp with alpha
  • Truecolor: RGB332, RGB555, RGB565, RGB24 (8-bit per channel), RGBA32 (8-bit per channel), BGR555, BGR24 (8-bit per channel), BGRA32 (8-bit per channel), RGB48 (16-bit per channel), RGBA64 (16-bit per channel)
  • float: 32-bit float RGBA, this is the neutral format.

User Guide

Design philosophy

zigimg offers color and image functionality. The library is designed around either using the convenient Image (or Image.Managed) struct that can read and write image formats no matter the format.

Or you can also use the image format directly in case you want to extract more data from the image format. So if you find that Image does not give you the information that you need from a PNG or other format, you can use the PNG format albeit with a more manual API that Image hide from you.

Image vs Image.Managed

Image does not bundle a memory allocator and Image.Managed does, similar to std.ArrayList() and std.array_list.Managed in Zig standard library. For all the examples we are going to use Image but the API is similar when using Image.Managed.

Buffer requirements

Starting with Zig 0.15, all the I/O operations on file can accept a buffer for buffering. zigimg requires valid buffering buffers for reading from files and writing images to file. You can use zigimg.io.DEFAULT_BUFFER_SIZE as a size for the buffer you pass to the various file functions.

Read an image

It is pretty straightforward to read an image using the Image struct.

From a file

You can use either a file path

const std = @import("std");
const zigimg = @import("zigimg");

pub fn main() !void {
    const allocator = std.heap.smp_allocator;

    var read_buffer: [zigimg.io.DEFAULT_BUFFER_SIZE]u8 = undefined;
    var image = try zigimg.Image.fromFilePath(allocator,  "my_image.png", read_buffer[0..]);
    defer image.deinit(allocator);

    // Do something with your image
}

or a std.fs.File directly

const std = @import("std");
const zigimg = @import("zigimg");

pub fn main() !void {
    const allocator = std.heap.smp_allocator;

    var file = try std.fs.cwd().openFile(file_path, .{});
    defer file.close();

    var read_buffer: [zigimg.io.DEFAULT_BUFFER_SIZE]u8 = undefined;
    var image = try zigimg.Image.fromFile(allocator, &file, read_buffer[0..]);
    defer image.deinit(allocator);

    // Do something with your image
}

From memory

const std = @import("std");
const zigimg = @import("zigimg");

const image_data = @embedFile("test.bmp");

pub fn main() !void {
    const allocator = std.heap.smp_allocator;

    const image = try zigimg.Image.fromMemory(allocator, image_data[0..]);
    defer image.deinit(allocator);

    // Do something with your image
}

Accessing pixel data

For a single image, they are two ways to get access to the pixel data.

Accessing a specific format directly

You can access the pixel data directly using Image.pixels. pixels is an union of all supported pixel formats.

For RGB pixel formats, just use the pixel format enum value and addresss the data directly.

pub fn example() void {
    // [...]
    // Assuming you already have an image loa
View on GitHub
GitHub Stars761
CategoryContent
Updated1d ago
Forks131

Languages

Zig

Security Score

100/100

Audited on Mar 25, 2026

No findings