How libavif Signals Full vs Studio Range Color

This article explains how the libavif library manages and flags color range metadata, detailing how it distinguishes between full range (0–255 for 8-bit) and studio/limited range (16–235 for 8-bit) color. It covers the library’s internal API representations, how this data is written into the ISOBMFF container, and how it is signaled within the AV1 compressed bitstream.

At the software level, libavif utilizes the avifImage structure to store image properties. Within this structure, the color range is defined by the yuvRange member, which accepts values from the avifRange enumeration. This enum contains two primary constants: AVIF_RANGE_LIMITED (representing studio range) and AVIF_RANGE_FULL (representing full range). When preparing an image for encoding, setting this variable tells libavif how to interpret the input YUV coordinates and how to configure the output metadata.

AVIF files are based on the ISO Base Media File Format (ISOBMFF). To signal color properties at the container level, libavif writes a Color Information (colr) box of type nclx (on-screen colors) into the file metadata. Within the nclx payload, there is a dedicated 1-bit field named full_range_flag. When avifImage->yuvRange is set to AVIF_RANGE_FULL, libavif sets this flag to 1. Conversely, if the range is limited, the flag is set to 0. This allows media parsers to quickly identify the color range without needing to decode the underlying AV1 video bitstream.

Because AVIF wraps an AV1 video frame, color range must also be defined within the compressed image payload. During the encoding process, libavif passes the range configuration to the AV1 encoder (such as aom or rav1e). The encoder writes this information into the AV1 Sequence Header OBU (Open Bitstream Unit), specifically inside the color_config() syntax element. Here, the color_range bit is set to 1 for full range and 0 for studio/limited range.

When decoding an AVIF file, libavif extracts the range information from both the container’s colr box and the AV1 bitstream to ensure consistency. The library uses this range state to perform accurate color space conversion. If full range is signaled, the YUV values are mapped directly from 0 to 2^depth - 1. If limited range is signaled, the library scales the YUV values using the standard studio range coefficients (e.g., scaling Y between 16 and 235 in 8-bit depth) to prevent color clipping and ensure accurate RGB reconstruction on the display.