How to Decode AVIF Images Using libavif API

This article provides a step-by-step guide to the standard programming workflow for decoding AVIF (AV1 Image File Format) images using the official libavif C library. You will learn how to initialize the decoder, parse the image container, extract raw pixel data (YUV or RGB), and properly manage memory resources.

1. Initialize the Decoder

The first step is to allocate and initialize the avifDecoder structure. This structure manages the decoding state, configuration options, and the resulting decoded image data.

avifDecoder * decoder = avifDecoderCreate();
if (!decoder) {
    // Handle allocation failure
}

2. Set the Source Input

You must associate the decoder with your input AVIF data. libavif allows you to read directly from a file on disk or from an in-memory buffer. * From a file: c avifResult result = avifDecoderSetFile(decoder, "image.avif"); * From a memory buffer: c avifResult result = avifDecoderSetIOMemory(decoder, rawBuffer, rawBufferSize); Always check if the returned avifResult is AVIF_RESULT_OK before proceeding.

3. Parse the Container Metadata

Before decoding the actual pixels, parse the AVIF container to retrieve metadata such as dimensions, color space, bit depth, and duration (for animated AVIFs). This is done using avifDecoderParse().

result = avifDecoderParse(decoder);
if (result != AVIF_RESULT_OK) {
    // Handle parsing error
    avifDecoderDestroy(decoder);
}

// Access image dimensions
uint32_t width = decoder->image->width;
uint32_t height = decoder->image->height;

4. Decode the Image Frame

Once the file is parsed, trigger the decoding process using avifDecoderNextImage(). This decodes the primary static image (or the first frame of an animation).

result = avifDecoderNextImage(decoder);
if (result != AVIF_RESULT_OK) {
    // Handle decoding error
    avifDecoderDestroy(decoder);
}

5. Access and Convert the Pixel Data

Upon successful decoding, the raw YUV planes are available inside the decoder->image structure. If your application requires RGB pixels instead of YUV, you must convert the image.

avifRGBImage rgb;
avifRGBImageSetDefaults(&rgb, decoder->image);

// Configure RGB destination format (e.g., 8-bit RGBA)
rgb.depth = 8;
rgb.format = AVIF_RGB_FORMAT_RGBA;

// Allocate the pixel buffer
avifRGBImageAllocatePixels(&rgb);

// Convert YUV to RGB
result = avifImageYUVToRGB(decoder->image, &rgb);
if (result == AVIF_RESULT_OK) {
    // Access raw pixels via rgb.pixels
}

6. Clean Up Resources

To prevent memory leaks, free all allocated structures and pixel buffers once decoding and processing are complete.

avifRGBImageFreePixels(&rgb);
avifDecoderDestroy(decoder);