Skip to content

Conversation

@kadykov
Copy link
Contributor

@kadykov kadykov commented Oct 26, 2025

Add manual chroma subsampling control for AVIF export

Summary

This PR adds manual chroma subsampling control to AVIF export, allowing users to choose between 4:4:4, 4:2:2, and 4:2:0 subsampling modes independently of the quality setting. This feature is inspired by the existing implementation in JPEG export.

Problem

Currently, darktable automatically determines the chroma subsampling for AVIF export based on quality thresholds:

  • Quality ≤ 80: YUV420 (4:2:0)
  • Quality 81-90: YUV422 (4:2:2)
  • Quality ≥ 91: YUV444 (4:4:4)

This approach is too restrictive for the AVIF format. AVIF is highly efficient, and its optimal quality range is typically 50-70, where it produces excellent results with reasonable file sizes. However, at these quality levels, users are forced to use 4:2:0 chroma subsampling, which can result in rough edges and reduced color fidelity, especially in images with high-contrast color transitions.

To achieve 4:4:4 chroma subsampling (no color subsampling), users must set quality to 91 or higher, which produces unnecessarily large files that defeat the purpose of AVIF's efficiency.

Solution

This PR adds a new "chroma subsampling" option to the AVIF export dialog with the following choices:

  • auto - Uses quality-based thresholds (preserves existing behavior, set as default)
  • 4:4:4 - No chroma subsampling (best color fidelity)
  • 4:2:2 - Horizontal subsampling only
  • 4:2:0 - Horizontal and vertical subsampling (smallest files)

This allows users to optimize the quality-vs-size tradeoff according to their specific needs.

Implementation

The implementation follows the pattern used in JPEG export (src/imageio/format/jpeg.c):

  1. New enum avif_subsample_e with AUTO, 444, 422, 420 options
  2. Data structures updated to include subsample field in dt_imageio_avif_t and dt_imageio_avif_gui_t
  3. Export logic modified in write_image() to check subsample setting before determining pixel format
  4. GUI control added as a combobox with clear descriptions and tooltip
  5. Configuration handling via plugins/imageio/format/avif/subsample config key
  6. Lua API support for scripting and automation
  7. Updated tooltip for quality slider (removed quality-based subsampling reference)

Backward compatibility: The "auto" mode is set as default, preserving the existing quality-based behavior for all users.

Testing Results

Testing was performed with a 200% crop of a pattern containing white and red ribbons to highlight chroma subsampling artifacts. The results demonstrate the benefits of manual control:

Quality vs File Size Comparison:

  • 60% quality, 4:4:4 subsampling70% quality, 4:2:0 subsampling (similar file size)

GR002083-60-444
GR002083-70-420

Result: 4:4:4 version has noticeably smoother edges with better color fidelity

  • 70% quality, 4:4:4 subsampling80% quality, 4:2:0 subsampling (similar file size)

GR002083-70-444
GR002083-80-420

Result: 4:4:4 version clearly looks better with cleaner color transitions

The 4:2:0 subsampled images show rough edges and color fringing artifacts that are not present in the 4:4:4 versions, even when the 4:2:0 images are exported at higher quality settings with similar file sizes.

  • 91% quality, 4:4:4 subsampling the only way how we can achieve smooth edges in the current configuration.

GR002083-91-444

  • Lossless original

GR002083-lossless

Use Cases

This feature is particularly beneficial for:

  • Images with high-contrast color transitions (e.g., graphics, text overlays, sharp edges)
  • Color-critical work where maximum color fidelity is important
  • Users who want to optimize file size without sacrificing color accuracy
  • Batch exports where consistent subsampling is desired regardless of content

Example Usage

-- Lua scripting example
local darktable = require "darktable"

darktable.preferences.write(
  "avif",
  "subsample",
  "darktable.preferences.avif.AVIF_SUBSAMPLE_444"
)

Add a new chroma subsampling option to the AVIF export module, allowing users to manually select subsampling modes (4:4:4, 4:2:2, 4:2:0) or use auto mode based on quality thresholds. This provides finer control over compression and quality trade-offs in AVIF images.
Copilot AI review requested due to automatic review settings October 26, 2025 23:31
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR introduces manual chroma subsampling control for AVIF export, allowing users to independently select 4:4:4, 4:2:2, or 4:2:0 subsampling modes instead of relying solely on quality-based automatic selection. This addresses limitations where optimal AVIF quality ranges (50-70) forced 4:2:0 subsampling, compromising color fidelity.

Key Changes:

  • Added new avif_subsample_e enum with AUTO, 444, 422, and 420 options
  • Implemented subsample selection logic in write_image() that respects manual settings while preserving auto mode
  • Added GUI combobox control with descriptive tooltips and Lua API support

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@wpferguson
Copy link
Member

Tested the lua avif format and it works. Here's the script....

test_avif_format.zip

@TurboGit TurboGit added this to the 5.4 milestone Oct 27, 2025
Add a new configuration option for AVIF chroma subsampling in the imageio plugin settings. This allows users to control subsampling levels (0-3) for AVIF exports, defaulting to 0.
@kadykov kadykov requested a review from TurboGit October 27, 2025 15:21
Copy link
Member

@TurboGit TurboGit left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested for the first time and found an issue. If you select the lossless compression mode you still have the subsample option on the GUI but this has not effect as it is hardcoded as AVIF_PIXEL_FORMAT_YUV444 in this case:

   case AVIF_COMP_LOSSLESS:
          format = AVIF_PIXEL_FORMAT_YUV444;
          break;

I suppose that in lossless mode we need to hide the sub-sample slider as done for the quality slider.

…mode

When AVIF compression is set to lossless, the subsample control is now hidden from the GUI to prevent irrelevant options, and marked with no-show-all for better layout management. This improves user experience by simplifying the interface during lossless exports.
@kadykov
Copy link
Contributor Author

kadykov commented Oct 28, 2025

@TurboGit Thanks! Indeed, we should hide it for lossless compression. Fixed in 8cb0db4

@kadykov kadykov requested a review from TurboGit October 28, 2025 19:48
@TurboGit TurboGit added feature: enhancement current features to improve priority: low core features work as expected, only secondary/optional features don't scope: codebase making darktable source code easier to manage release notes: pending labels Oct 28, 2025
Copy link
Member

@TurboGit TurboGit left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good now. Thanks!

@TurboGit TurboGit merged commit 6cd1733 into darktable-org:master Oct 29, 2025
5 checks passed
@TurboGit
Copy link
Member

@kadykov : Can you provide a release notes entry? TIA.

@victoryforce
Copy link
Collaborator

@kadykov Sorry I wasn't here in time for the review. Even now I don't have enough time to test it thoroughly. I can only note from a cursory look at the code that it makes changes to dt_imageio_avif_t, and therefore should

  • increment module version in DT_MODULE()
  • include a legacy_params function to handle migration from an older version of the parameters to the current one.

See the source code for exporting to other formats for an example of how this is done.

@kadykov
Copy link
Contributor Author

kadykov commented Nov 8, 2025

@victoryforce Thanks! I have created a follow-up PR #19698

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature: enhancement current features to improve priority: low core features work as expected, only secondary/optional features don't scope: codebase making darktable source code easier to manage

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants