nx_aces_native.nx
buildroot/runtime/nx_aces_native.nx
about
nx_aces_native.nx -- scene-referred linear color transforms,
rewritten bits-up in NishiLang. No external library, no
OSI license inherited. Numerical constants only -- the matrix
values are PUBLISHED MATH from SMPTE / CIE standards work, not
any one organisation's intellectual property.
Per cardinal `feedback-dont-rebuild-commodity-platform-layers`:
the sRGB OETF and the Rec.709-to-ACEScg-style working-space
matrices are public standards (CIE 15:2004, IEC 61966-2-1,
SMPTE ST 2065-1) -- we derive them from first principles + ship
our own NishiLang implementation. The substrate's color
pipeline is therefore Nishi-stack from bits up.
Three primitives:
nx_aces_srgb_to_linear_q14 -- piecewise sRGB OETF inverse
nx_aces_linear_to_srgb_q14 -- piecewise sRGB OETF forward
nx_aces_linear_to_workingspace -- 3x3 matrix mul to a wide
scene-linear working primary set (substrate's own primaries;
dimensionally compatible with ACEScg but our own values).
Q14 fixed-point throughout (16384 unit) so we have headroom for
HDR values > 1.0 without losing the low-end. All math is i64
integer + bit-shift, no float ops. Substrate's "no FPU dep"
discipline.
IMPORTANT: caller is responsible for pixel-shape consistency.
This primitive operates on a single (r, g, b) triple at a time.
Composes with future nx_image_pixel_map for bulk image transform.
genealogy_id: substrate_native_color_transform_2026_05_16
lineage_id: nishi_family_custom_license_color_v1
dependencies 3 imports · 1 importers
imports: nx_syscalls.nxnx_runtime.nxnx_tier.nx
imported by: nx_lab_from_rgb.nx
call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown
structs
| 184 | struct NxAcesTriple { |
consts
| 37 | const NX_ACES_Q14: nx_int = 16384 |
| 59 | const NX_ACES_SRGB_THR_Q14: nx_int = 662 |
| 60 | const NX_ACES_LIN_THR_Q14: nx_int = 51 |
| 61 | const NX_ACES_12_92_Q14: nx_int = 211681 |
| 62 | const NX_ACES_1_055_Q14: nx_int = 17285 |
| 63 | const NX_ACES_0_055_Q14: nx_int = 901 |
| 84 | const NX_ACES_POW24_A: nx_int = 17531 |
| 85 | const NX_ACES_POW24_B: nx_int = -3277 |
| 86 | const NX_ACES_POW24_C: nx_int = 2130 |
| 88 | const NX_ACES_INV24_A: nx_int = 1638 |
| 89 | const NX_ACES_INV24_B: nx_int = 24576 |
| 90 | const NX_ACES_INV24_C: nx_int = -9830 |
| 174 | const NX_ACES_M00: nx_int = 10047 |
| 175 | const NX_ACES_M01: nx_int = 5562 |
| 176 | const NX_ACES_M02: nx_int = 776 |
| 177 | const NX_ACES_M10: nx_int = 1150 |
| 178 | const NX_ACES_M11: nx_int = 15013 |
| 179 | const NX_ACES_M12: nx_int = 220 |
| 180 | const NX_ACES_M20: nx_int = 337 |
| 181 | const NX_ACES_M21: nx_int = 1795 |
| 182 | const NX_ACES_M22: nx_int = 14251 |
| 190 | const NX_ACES_TRIPLE_BYTES: nx_size = 24 |
functions
| 93 | func _aces_pow_2_4_q14(x_q14: nx_int) -> nx_int {
called by 1: nx_aces_srgb_to_linear_q14 |
| 108 | func _aces_pow_inv_2_4_q14(x_q14: nx_int) -> nx_int {
called by 1: nx_aces_linear_to_srgb_q14 |
| 126 | func nx_aces_srgb_to_linear_q14(s_q14: nx_int) -> nx_int { |
| 137 | func nx_aces_linear_to_srgb_q14(l_q14: nx_int) -> nx_int { |
| 192 | func nx_aces_alloc_triple(r_q14: nx_int, g_q14: nx_int, b_q14: nx_int) -> *NxAcesTriple { |
| 201 | func nx_aces_linear_to_workingspace( |
| 220 | func nx_aces_pipeline_u8(r_u8: nx_int, g_u8: nx_int, b_u8: nx_int) -> *NxAcesTriple {
called by 1: main calls 3: nx_aces_srgb_to_linear_q14nx_aces_alloc_triplenx_aces_linear_to_workingspace |
| 233 | func main() -> nx_int { |