How libavif Ensures Color Accuracy in Bit Conversion

This article explains how the libavif library maintains precise color representation when converting image files between 8-bit, 10-bit, and 12-bit formats. It covers the underlying mechanisms of high-precision math, color space metadata preservation, and chroma subsampling handling that prevent color degradation during the encoding and decoding processes.

High-Precision Intermediate Processing

When converting between different bit depths, simple integer division or bit-shifting can introduce rounding errors, leading to visible banding or color shifts. To prevent this, libavif performs its internal color conversions and matrix multiplications using higher-precision math.

During conversion, pixel data is scaled up to a 16-bit integer or a floating-point representation. By processing the colors in a higher bit depth than the source or target format, libavif minimizes truncation errors. The final rounding down to the target bit depth (such as 8-bit) occurs only at the very end of the pipeline, using rounding algorithms that preserve color integrity.

Strict Adherence to CICP Metadata

Color accuracy is heavily dependent on how color channels are interpreted. libavif relies on Coding-Independent Code Points (CICP) metadata, which is defined in the AV1 specification. CICP explicitly defines three critical parameters: * Color Primaries: The exact coordinates of red, green, and blue. * Transfer Characteristics: The opto-electronic transfer function (gamma curve) used to encode the luminance. * Matrix Coefficients: The formula used to convert between YUV (luma/chroma) and RGB color spaces.

When converting between bit depths, libavif references these CICP parameters to apply the mathematically correct transformation matrices. This ensures that a color defined in a 10-bit BT.2020 wide color gamut is accurately mapped to its closest equivalent in an 8-bit sRGB gamut, or vice versa, without unexpected shifts in hue or saturation.

Advanced Chroma Upsampling and Downsampling

AVIF images often use chroma subsampling (such as YUV 4:2:0 or 4:2:2) to reduce file size. Converting these images to RGB (which is always YUV 4:4:4 equivalent) requires scaling the color channels.

libavif ensures color accuracy during this phase by utilizing high-quality interpolation filters (such as bilinear or Lanczos) rather than nearest-neighbor scaling. When changing bit depths alongside chroma scaling, the library performs the spatial interpolation in the higher-precision domain. This prevents color bleeding and ensures that transitions between contrasting colors remain sharp and mathematically accurate.

Dithering to Prevent Banding

Going from a higher bit depth (10-bit or 12-bit) to a lower one (8-bit) naturally results in a loss of color information, which can cause color banding in smooth gradients. To mitigate this, libavif can utilize dithering. Dithering adds a controlled amount of noise to the image before quantization. This visual trick fools the human eye into perceiving smoother gradients and highly accurate colors, effectively preserving the visual depth of the original high-bit-depth source even within an 8-bit container.