code wiki / (root) / nx_lab_from_rgb.nx

nx_lab_from_rgb.nx

buildroot/runtime/nx_lab_from_rgb.nx

10664 B269 linesdepth 4pulls 4 transitivereach 7 importersview sourcekind tool
docsdependenciesstructsconstsfunctions

about

nx_lab_from_rgb.nx -- sRGB u8 -> CIELab Q10 in pure i64 fixed-point. CAPABILITY_COMPLETENESS: FULL Bridges the "RGB-proxy" tier-1 chroma axes (in nx_image_grade_v0) up to genuine colorimetric measurements: - real ITA degrees (via nx_skin_tone_ita) - real CIELab h_ab undertone angle (via nx_undertone_class) Math pipeline (CIE 15:2004 / CIE 014:2018): step 1 sRGB u8 channel value [0, 255] -> Q14 sRGB scalar [0, 16384] step 2 sRGB Q14 -> linear-light Q14 via sRGB OETF inverse: val_q14 < 0.04045 * Q14 -> linear = val / 12.92 val_q14 >= 0.04045 * Q14 -> linear = ((val + 0.055)/1.055)^2.4 Composed against nx_aces_srgb_to_linear_q14 (already shipped). step 3 Linear sRGB Q14 -> XYZ Q14 via 3x3 matrix (D65): [0.4124564 0.3575761 0.1804375] per IEC 61966-2-1 + [0.2126729 0.7151522 0.0721750] ITU-R BT.709 primaries [0.0193339 0.1191920 0.9503041] step 4 XYZ Q14 -> Lab Q10: tn_x = X / Xn (Xn = 0.95047 for D65) tn_y = Y / Yn (Yn = 1.00000) tn_z = Z / Zn (Zn = 1.08883) f(t) = t^(1/3) if t > 216/24389 (kappa*t + 16) / 116 otherwise (kappa = 24389/27) L* = 116 * f(tn_y) - 16 a* = 500 * (f(tn_x) - f(tn_y)) b* = 200 * (f(tn_y) - f(tn_z)) Output: L*_q10, a*_q10, b*_q10 all in Q10 scaled units. L*_q10 in [0, ~100 * 1024 = 102400] a*_q10 / b*_q10 in approximately [-130 * 1024, +130 * 1024] Cube root via Newton-Raphson in Q14 (5 iterations -> ~0.1% accuracy across [0, 1]).

dependencies 4 imports · 3 importers

nx_syscalls.nx nx_runtime.nx nx_tier.nx nx_aces_native.nx nx_lab_from_rgb.nx nx_image_grade_v0.nx nx_image_grade_v1.nx nx_image_grade_v2.nx

imports: nx_syscalls.nxnx_runtime.nxnx_tier.nxnx_aces_native.nx

imported by: nx_image_grade_v0.nxnx_image_grade_v1.nxnx_image_grade_v2.nx

call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown

main nx_lab_from_rgb sys_mmap nx_aces_srgb_to_linear_q14 _aces_pow_2_4_q14 _lab_ft_q14 _lab_cuberoot_q14 _lab_ft_q14 ↻ _lab_cuberoot_q14 ↻

structs

95struct NxLabColor

consts

55const NX_MAGIC_2900: i64 = 2900
56const NX_MAGIC_3200: i64 = 3200
57const NX_MAGIC_8192: i64 = 8192
58const NX_MAGIC_13005: i64 = 13005
60const NX_LAB_Q14: nx_int = 16384
61const NX_LAB_Q10: nx_int = 1024
64const NX_LAB_XN_Q14: nx_int = 15572 // 0.95047 * 16384
65const NX_LAB_YN_Q14: nx_int = 16384 // 1.00000 * 16384
66const NX_LAB_ZN_Q14: nx_int = 17839 // 1.08883 * 16384
69const NX_LAB_M00: nx_int = 6759 // 0.4124564 * 16384
70const NX_LAB_M01: nx_int = 5859 // 0.3575761 * 16384
71const NX_LAB_M02: nx_int = 2957 // 0.1804375 * 16384
72const NX_LAB_M10: nx_int = 3484 // 0.2126729 * 16384
73const NX_LAB_M11: nx_int = 11718 // 0.7151522 * 16384
74const NX_LAB_M12: nx_int = 1183 // 0.0721750 * 16384
75const NX_LAB_M20: nx_int = 317 // 0.0193339 * 16384
76const NX_LAB_M21: nx_int = 1953 // 0.1191920 * 16384
77const NX_LAB_M22: nx_int = 15569 // 0.9503041 * 16384
80const NX_LAB_FT_THRESHOLD_Q14: nx_int = 145 // 0.008856 * 16384
101const NX_LAB_COLOR_BYTES: nx_size = 24

functions

114func _lab_cuberoot_q14(t_q14: nx_int) -> nx_int
called by 2: _lab_ft_q14main
141func _lab_ft_q14(t_q14: nx_int) -> nx_int
155func nx_lab_from_rgb(r_u8: nx_int, g_u8: nx_int, b_u8: nx_int) -> *NxLabColor
200func main() -> nx_int