Skip to content

test(engine): lock down sRGB→BT.2020 LUT with byte-exact reference values#377

Merged
vanceingalls merged 1 commit intomainfrom
vance/srgb-hdr-reference-tests
Apr 23, 2026
Merged

test(engine): lock down sRGB→BT.2020 LUT with byte-exact reference values#377
vanceingalls merged 1 commit intomainfrom
vance/srgb-hdr-reference-tests

Conversation

@vanceingalls
Copy link
Copy Markdown
Collaborator

@vanceingalls vanceingalls commented Apr 21, 2026

Summary

Add a 12-row reference table covering the full sRGB range with byte-exact 16-bit HLG and PQ signal values, plus three guard tests, locking down the buildSrgbToHdrLut() math.

Why

Chunk 9F of plans/hdr-followups.md. The matrix-free fast path through blitRgba8OverRgb48le runs every DOM pixel through buildSrgbToHdrLut() (sRGB EOTF → linear → HDR OETF → 16-bit). Any drift in the EOTF/OETF math — constant changes, branch swaps, rounding-mode regressions — would silently corrupt every text / UI / overlay pixel composited onto an HDR frame.

Existing tests covered structural invariants (transparent passthrough, opaque overwrite, alpha blending, channel symmetry, HLG ≠ PQ) but no byte-exact reference values, so a uniform scale or constant tweak could pass everything.

What changed

  • 12-row reference table in alphaBlit.test.ts covering black, shadow, mid-grays, highlight, near-white, and white with exact 16-bit HLG and PQ signal values.
  • Three guard tests:
    • Asymmetric R/G/B (HLG): each channel hits the LUT independently.
    • Asymmetric R/G/B (PQ): same, on the PQ path.
    • BT.2408 SDR-white invariant: PQ caps sRGB 255 at 38055 (~203 nits), well below HLG's 65535. This is the load-bearing detail that makes PQ headroom work — locking the exact value prevents a future "fix" that would re-scale PQ to peak-at-SDR-white and clip every real HDR pixel.

Reference values mirror buildSrgbToHdrLut() exactly and were verified against the existing HLG mid-gray comment in the file.

Test plan

  • All new tests pass against the current LUT.
  • Existing alphaBlit.test.ts invariants unchanged.

Stack

Chunk 9F of plans/hdr-followups.md. Test-only change, independent of all other chunks.

Copy link
Copy Markdown
Collaborator Author

vanceingalls commented Apr 21, 2026

This stack of pull requests is managed by Graphite. Learn more about stacking.

@vanceingalls vanceingalls force-pushed the vance/srgb-hdr-reference-tests branch from a1d1fdd to afe3517 Compare April 21, 2026 20:48
@vanceingalls vanceingalls force-pushed the vance/lfs-test-pngs branch 2 times, most recently from 6d042d3 to 871f1ad Compare April 21, 2026 20:54
@vanceingalls vanceingalls force-pushed the vance/srgb-hdr-reference-tests branch from afe3517 to 6f1bc71 Compare April 21, 2026 20:54
@vanceingalls vanceingalls marked this pull request as ready for review April 21, 2026 20:57
@vanceingalls vanceingalls force-pushed the vance/srgb-hdr-reference-tests branch 2 times, most recently from 2af7fa2 to f675c92 Compare April 22, 2026 01:16
@vanceingalls vanceingalls force-pushed the vance/srgb-hdr-reference-tests branch from 7edeb28 to 93e21ac Compare April 23, 2026 01:58
@vanceingalls vanceingalls force-pushed the vance/srgb-hdr-reference-tests branch from 93e21ac to 23721fc Compare April 23, 2026 02:56
@vanceingalls vanceingalls force-pushed the vance/srgb-hdr-reference-tests branch from 23721fc to 29fbdb2 Compare April 23, 2026 03:19
@vanceingalls vanceingalls force-pushed the vance/srgb-hdr-reference-tests branch from 29fbdb2 to 73a1f75 Compare April 23, 2026 03:40
@vanceingalls vanceingalls force-pushed the vance/srgb-hdr-reference-tests branch from 73a1f75 to 01eb2f9 Compare April 23, 2026 04:49
@vanceingalls vanceingalls force-pushed the vance/srgb-hdr-reference-tests branch from 01eb2f9 to 1ee49d8 Compare April 23, 2026 05:08
@vanceingalls vanceingalls force-pushed the vance/srgb-hdr-reference-tests branch 2 times, most recently from 981e6a8 to b66e6e5 Compare April 23, 2026 06:07
@vanceingalls vanceingalls force-pushed the vance/lfs-test-pngs branch 3 times, most recently from 90fb170 to 4220482 Compare April 23, 2026 06:57
@vanceingalls vanceingalls force-pushed the vance/srgb-hdr-reference-tests branch from b66e6e5 to c694a91 Compare April 23, 2026 06:57
@qodo-ai-reviewer
Copy link
Copy Markdown

Hi, generate-lut-reference.py uses PEP585 built-in generics (e.g., list[int], tuple[int, ...]) which fail to parse on Python <3.9, but the repo does not pin a minimum Python version for engine scripts, so the regeneration workflow can break for some developers/CI environments.

Severity: remediation recommended | Category: reliability

How to fix: Pin Python or avoid generics

Agent prompt to fix - you can give this to your LLM of choice:

Issue description

packages/engine/scripts/generate-lut-reference.py uses PEP585 built-in generics (list[int], tuple[int, ...]) which require Python 3.9+. The repo doesn't pin a Python version for engine scripts, so running this script on Python 3.8 will fail at parse time.

Issue Context

Other scripts either avoid these annotations or explicitly state a Python 3.9+ requirement, so this new script should either declare its Python requirement or be compatible with older versions.

Fix Focus Areas

  • packages/engine/scripts/generate-lut-reference.py[106-119]

Suggested fixes

Choose one:

  1. Make the script compatible with Python 3.8 by replacing list[int] / tuple[int, ...] with List[int] / Tuple[int, ...] from typing, or by removing those annotations.
  2. Explicitly document/enforce Python 3.9+ for this script (e.g., in the docstring header and/or a repo-level Python version pin file if the project uses one).

Found by Qodo code review

@graphite-app graphite-app Bot changed the base branch from vance/lfs-test-pngs to graphite-base/377 April 23, 2026 08:48
@vanceingalls vanceingalls force-pushed the vance/srgb-hdr-reference-tests branch from c694a91 to c642d12 Compare April 23, 2026 15:33
@vanceingalls vanceingalls force-pushed the graphite-base/377 branch 2 times, most recently from 075f18f to 3089c8e Compare April 23, 2026 16:32
@vanceingalls vanceingalls force-pushed the vance/srgb-hdr-reference-tests branch from c642d12 to b91be60 Compare April 23, 2026 16:32
@graphite-app graphite-app Bot changed the base branch from graphite-base/377 to main April 23, 2026 16:32
@vanceingalls vanceingalls force-pushed the vance/srgb-hdr-reference-tests branch from b91be60 to 699fd72 Compare April 23, 2026 16:32
Address jrusso1020's nit on PR #365 (non-blocking review): both READMEs now
explain where the tolerance values come from.

- hdr-regression/README.md: add a budget-breakdown table that derives the 30
  frames from the deltas in PRs #369 (window C fix → 5) and #375 (window F
  fix → 0). The table doubles as a contract: if a future change forces the
  budget back up, exactly one bucket has regressed and the table tells you
  which one to investigate first.
- hdr-hlg-regression/README.md: add a 'Tolerance' section explaining why 0
  is the right floor (HLG is a pure pass-through path, HEVC over rgb48le is
  byte-deterministic on the same fixture, so any drift is a real regression).

The regeneration command for generate-hdr-photo-pq.py was already documented
at README lines 67-71, so no changes needed there.
@vanceingalls vanceingalls force-pushed the vance/srgb-hdr-reference-tests branch from 699fd72 to 2e76501 Compare April 23, 2026 16:35
Copy link
Copy Markdown
Collaborator Author

Merge activity

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants