All formats

stb_image

LanguageC (usable from C++)
Licensepublic domain (Unlicense) or MIT, your choice
Repositorygithub.com/nothings/stb
Documentationcomments at the top of stb_image.h
Depends onnothing
Read / writeyes / no; all frames, composited, with delays

stb_image.h decodes GIF (and JPEG, PNG, BMP, TGA, PSD, HDR, PNM) into 8-bit pixel buffers. For GIF it always produces 4 channels (RGBA), with the transparent color as alpha 0. stbi_load returns the first frame; stbi_load_gif_from_memory decodes every frame onto the full canvas, applying disposal methods, and returns them stacked in one buffer with an array of delays.

It doesn’t write GIF, doesn’t return the loop count, comments or palettes, and keeps all frames in memory at canvas size (a 500x500 GIF with 200 frames needs 200 MB). It’s meant for games and tools that load trusted files.

Installation#

Copy stb_image.h into your project and in one .c/.cpp file write:

C
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"

Define STBI_ONLY_GIF before it to compile only the GIF decoder. Package managers: vcpkg install stb, Conan stb, Debian/Ubuntu libstb-dev.

Basic usage: load the first frame of a GIF#

C
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#include <stdio.h>

int main(void) {
    int w, h, channels;
    unsigned char *rgba = stbi_load("in.gif", &w, &h, &channels, 4);
    if (!rgba) {
        fprintf(stderr, "load failed: %s\n", stbi_failure_reason());
        return 1;
    }
    printf("%d x %d\n", w, h);
    // rgba[(y * w + x) * 4 + 3] == 0 for transparent pixels
    stbi_image_free(rgba);
    return 0;
}

How to load all frames of an animated GIF#

stbi_load_gif_from_memory needs the file in memory. Frame i starts at pixels + i * w * h * 4; delays[i] is in milliseconds:

C
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#include <stdio.h>
#include <stdlib.h>

int main(void) {
    FILE *f = fopen("anim.gif", "rb");
    if (!f) return 1;
    fseek(f, 0, SEEK_END);
    long size = ftell(f);
    fseek(f, 0, SEEK_SET);
    unsigned char *data = malloc(size);
    fread(data, 1, size, f);
    fclose(f);

    int *delays = NULL;
    int w, h, frames, comp;
    unsigned char *pixels = stbi_load_gif_from_memory(data, (int)size, &delays,
                                                      &w, &h, &frames, &comp, 4);
    free(data);
    if (!pixels) {
        fprintf(stderr, "decode failed: %s\n", stbi_failure_reason());
        return 1;
    }
    printf("%d x %d, %d frames\n", w, h, frames);
    for (int i = 0; i < frames; i++) {
        unsigned char *frame = pixels + (size_t)i * w * h * 4;
        printf("frame %d: %d ms, first pixel alpha %d\n", i, delays[i], frame[3]);
    }
    stbi_image_free(pixels);
    STBI_FREE(delays);
    return 0;
}

How to get GIF width and height without decoding#

C
int w, h, comp;
if (stbi_info("in.gif", &w, &h, &comp))
    printf("%d x %d\n", w, h);

Tips#