How to Free avifImage Memory in libavif

This article explains how to correctly deallocate memory associated with an avifImage object when working with the libavif library in C or C++. You will learn the specific API functions required to release image structures and pixel buffers, helping you prevent memory leaks in your image processing applications.

The Standard Way: avifImageDestroy

The primary and safest way to free all memory associated with an avifImage structure is to use the avifImageDestroy() function. This function automatically releases the internal pixel buffers, metadata (such as Exif and XMP data), and the avifImage container itself.

Here is the function signature:

void avifImageDestroy(avifImage * image);

Basic Code Example

When you allocate an avifImage using avifImageCreate(), you must pair it with avifImageDestroy() once you are finished using it:

#include "avif/avif.h"

void process_image() {
    // 1. Allocate the avifImage structure
    avifImage * image = avifImageCreate(800, 600, 8, AVIF_PIXEL_FORMAT_YUV420);
    if (!image) {
        // Handle allocation failure
        return;
    }

    // ... Perform image operations ...

    // 2. Correctly free all allocated memory
    avifImageDestroy(image);
}

Freeing Just the Pixel Planes

In some advanced scenarios, you may want to keep the avifImage container allocated but free or reallocate the underlying pixel data planes (YUV/RGB or Alpha). You can achieve this using avifImageFreePlanes():

void avifImageFreePlanes(avifImage * image, avifPlanesFlags planes);

Using avifImageFreePlanes(image, AVIF_PLANES_ALL) will clear the pixel buffers, but the avifImage pointer itself remains valid and must still eventually be freed with avifImageDestroy().

Best Practices for Memory Management in libavif

  1. Safe Double-Free Prevention: After calling avifImageDestroy(image), it is highly recommended to set your image pointer to NULL. The avifImageDestroy function safely handles NULL inputs, but setting the pointer to NULL prevents accidental use-after-free bugs in your code.
  2. Decoder-Owned Images: If you are using avifDecoderRead() or avifDecoderNextImage() to populate an image, the memory of the decoded image is often tied to the avifDecoder structure. However, if you use avifDecoderDecodedImageCopy(), you are responsible for freeing the destination image using avifImageDestroy().