code wiki / (root) / nx_colorsci_lib.nx

nx_colorsci_lib.nx

buildroot/runtime/nx_colorsci_lib.nx

38414 B872 linesdepth 3pulls 5 transitivereach 7 importersview sourcekind library
docsdependenciesstructsconstsfunctions

about

nx_colorsci_lib.nx -- COLOUR SCIENCE AS ONE SOVEREIGN RULER (2026-08-24, phototwin PT1: cs_de2000, cs_icc_gamut). license_tier: ORIGINAL No hw writes (Rule 26). LIB (no main). WHAT IT IS. CIE 1976 L*a*b* both ways (CIE 15:2004), CIEDE2000 (CIE 142-2001, Sharma-Wu-Dalal 2005 eqs 4-22, KAT = their Table I as data in knowledge/colorsci_ciede2000_kat.tsv), an ICC v2/v4 matrix/TRC profile reader (rXYZ gXYZ bXYZ wtpt rTRC gTRC bTRC; the PCS is D50 by the spec, so image and substrate meet in ONE space), a segment-maxima gamut boundary descriptor (Morovic and Luo 2000) and chroma clipping toward the achromatic axis at constant L and hue. All arithmetic is nx_fixq30_lib Q30 fixed point: no float, no typed-in constants. WHY THROUGH THE PROFILE. The estate had RGB/HSV/YCbCr and no CIELAB, so no colour difference could be stated in the unit the whole field uses. Going RGB -> TRC -> matrix -> XYZ(D50) -> Lab through a parsed ICC profile is the ICC workflow itself, which means a measured substrate profile from a swatch bench drops in with no code. EVERY THRESHOLD IS CONF (knowledge/colorsci.conf, cs_conf_int) and an absent key is a REFUSAL, never a default.

dependencies 2 imports · 6 importers

nx_syscalls.nx nx_fixq30_lib.nx nx_colorsci_lib.nx nx_colorsci_cat_gate.nx nx_colorsci_gate.nx nx_de_referee_lib.nx nx_garment_twin.nx nx_phototwin.nx nx_phototwin_gate.nx

imports: nx_syscalls.nxnx_fixq30_lib.nx

imported by: nx_colorsci_cat_gate.nxnx_colorsci_gate.nxnx_de_referee_lib.nxnx_garment_twin.nxnx_phototwin.nxnx_phototwin_gate.nx

structs

none

consts

19const CS_LAB_DELTA_NUM: i64 = 6
20const CS_LAB_DELTA_DEN: i64 = 29
21const CS_LAB_L_SCALE: i64 = 116
22const CS_LAB_L_OFFSET: i64 = 16
23const CS_LAB_A_SCALE: i64 = 500
24const CS_LAB_B_SCALE: i64 = 200
25const CS_LAB_F_LIN_NUM: i64 = 4
26const CS_LAB_F_LIN_DEN: i64 = 29
27const CS_THREE: i64 = 3
28const CS_TWO: i64 = 2
30const CS_DE_C_REF: i64 = 25
31const CS_DE_T_W1_MILLI: i64 = 170
32const CS_DE_T_W2_MILLI: i64 = 240
33const CS_DE_T_W3_MILLI: i64 = 320
34const CS_DE_T_W4_MILLI: i64 = 200
35const CS_DE_T_D1_DEG: i64 = 30
36const CS_DE_T_M2: i64 = 2
37const CS_DE_T_M3: i64 = 3
38const CS_DE_T_D3_DEG: i64 = 6
39const CS_DE_T_M4: i64 = 4
40const CS_DE_T_D4_DEG: i64 = 63
41const CS_DE_THETA_CENTER_DEG: i64 = 275
42const CS_DE_THETA_WIDTH_DEG: i64 = 25
43const CS_DE_THETA_SCALE_DEG: i64 = 30
44const CS_DE_SL_K_MILLI: i64 = 15
45const CS_DE_SL_L0: i64 = 50
46const CS_DE_SL_C: i64 = 20
47const CS_DE_SC_K_MILLI: i64 = 45
48const CS_DE_SH_K_MILLI: i64 = 15
49const CS_MILLI: i64 = 1000
50const CS_DEG_FULL: i64 = 360
51const CS_DEG_HALF: i64 = 180
52const CS_HUE_KNIFE_EPS_Q30: i64 = 64 // 6e-8 degrees: the rounding bound of two Q30 rad->deg conversions (see cs_de2000_ex)
54const CS_X_FQ: i64 = 0
55const CS_X_DELTA3: i64 = 1
56const CS_X_INV3D2: i64 = 2
57const CS_X_FLIN_OFF: i64 = 3
58const CS_X_DELTA: i64 = 4
59const CS_X_SLOTS: i64 = 8
60const CS_SLOT: i64 = 8
62const CS_ICC_HDR_BYTES: i64 = 128
63const CS_ICC_MAGIC_OFF: i64 = 36
64const CS_ICC_TAG_ENTRY_BYTES: i64 = 12
65const CS_ICC_TAG_OFF_FIELD: i64 = 4
66const CS_ICC_TAG_SIZE_FIELD: i64 = 8
67const CS_ICC_TYPE_HDR_BYTES: i64 = 8
68const CS_ICC_XYZ_BYTES: i64 = 4
69const CS_ICC_S15F16_SCALE: i64 = 16384 // 2^(30-16): s15Fixed16 -> Q30
70const CS_ICC_U8F8_SCALE: i64 = 4194304 // 2^(30-8): u8Fixed8 -> Q30
71const CS_ICC_U16_MAX: i64 = 65535
72const CS_ICC_U32_SIGN: i64 = 2147483648
73const CS_ICC_U32_WRAP: i64 = 4294967296
74const CS_ICC_TRC_IDENTITY: i64 = 0
75const CS_ICC_TRC_GAMMA: i64 = 1
76const CS_ICC_TRC_TABLE: i64 = 2
77const CS_ICC_TAGS_NEEDED: i64 = 7
78const CS_BYTE_BITS_3: i64 = 24
79const CS_BYTE_BITS_2: i64 = 16
80const CS_BYTE_BITS_1: i64 = 8
81const CS_BYTE_MAX: i64 = 255
82const CS_LUT_ENTRIES: i64 = 256
83const CS_FOURCC: i64 = 4
84const CS_P_MAT: i64 = 0
85const CS_P_WTPT: i64 = 9
86const CS_P_LUT_R: i64 = 12
87const CS_P_LUT_G: i64 = 13
88const CS_P_LUT_B: i64 = 14
89const CS_P_INV: i64 = 15
90const CS_P_OK: i64 = 24
91const CS_P_BYTES: i64 = 25
92const CS_P_TAGS: i64 = 26
93const CS_P_TRC_R: i64 = 27
94const CS_P_TRC_G: i64 = 28
95const CS_P_TRC_B: i64 = 29
96const CS_P_HAVE: i64 = 30
97const CS_P_B64: i64 = 31 // 1 when the profile arrived as base64 text
98const CS_P_SLOTS: i64 = 32
100const CS_B64_UPPER_A: i64 = 65
101const CS_B64_UPPER_Z: i64 = 90
102const CS_B64_LOWER_A: i64 = 97
103const CS_B64_LOWER_Z: i64 = 122
104const CS_B64_LOWER_BASE: i64 = 26
105const CS_B64_DIGIT_BASE: i64 = 52
106const CS_B64_PLUS: i64 = 43
107const CS_B64_PLUS_VAL: i64 = 62
108const CS_B64_SLASH: i64 = 47
109const CS_B64_SLASH_VAL: i64 = 63
110const CS_B64_PAD: i64 = 61
111const CS_B64_BITS: i64 = 6
112const CS_MAT_N: i64 = 9
113const CS_MAT_COLS: i64 = 3
115const CS_G_H: i64 = 0
116const CS_G_E: i64 = 1
117const CS_G_COUNT: i64 = 2
118const CS_G_BASE: i64 = 3
119const CS_G_CENTER_L: i64 = 50
120const CS_PERMIL: i64 = 1000
121const CS_G_UNSAMPLED: i64 = 0 - 1
122const CS_CUBE_FACES: i64 = 6
123const CS_CLIP_LOW_RADIUS: i64 = 0
125const CS_CONF_MISS: i64 = 0 - 999999999
126const CS_ASCII_NL: i64 = 10
127const CS_ASCII_EQ: i64 = 61
128const CS_ASCII_ZERO: i64 = 48
129const CS_ASCII_NINE: i64 = 57
130const CS_DECIMAL: i64 = 10
140const CS_CAT_SCALE: i64 = 10000
141const CS_CAT_BRADFORD: i64 = 0
142const CS_CAT_CAT02: i64 = 1
143const CS_CAT_M: i64 = 9
144const CS_CAT_BFD_0: i64 = 8951
145const CS_CAT_BFD_1: i64 = 2664
146const CS_CAT_BFD_2: i64 = 0 - 1614
147const CS_CAT_BFD_3: i64 = 0 - 7502
148const CS_CAT_BFD_4: i64 = 17135
149const CS_CAT_BFD_5: i64 = 367
150const CS_CAT_BFD_6: i64 = 389
151const CS_CAT_BFD_7: i64 = 0 - 685
152const CS_CAT_BFD_8: i64 = 10296
153const CS_CAT_02_0: i64 = 7328
154const CS_CAT_02_1: i64 = 4296
155const CS_CAT_02_2: i64 = 0 - 1624
156const CS_CAT_02_3: i64 = 0 - 7036
157const CS_CAT_02_4: i64 = 16975
158const CS_CAT_02_5: i64 = 61
159const CS_CAT_02_6: i64 = 30
160const CS_CAT_02_7: i64 = 136
161const CS_CAT_02_8: i64 = 9834

functions

164func cs_be32(b: *u8, off: i64) -> i64
167func cs_be16(b: *u8, off: i64) -> i64 { return ((b[off] as i64) << CS_BYTE_BITS_1) + (b[off + 1] as i64) }
called by 1: cs_icc_trc_tag
168func cs_s15f16_q30(b: *u8, off: i64) -> i64
173func cs_tag_is(b: *u8, off: i64, s: *u8) -> i64
called by 1: cs_icc_load
180func cs_conf_int(path: *u8, key: *u8) -> i64
221func cs_ctx() -> *i64
233func cs_fq(cs: *i64) -> *i64 { return cs[CS_X_FQ] as *i64 }
236func cs_lab_f(cs: *i64, t: i64) -> i64
called by 1: cs_lab_from_xyz calls 3: fq_cbrtcs_fqfq_mul
240func cs_lab_finv(cs: *i64, f: i64) -> i64
called by 2: maincs_xyz_from_lab calls 2: fq_mulfq_div
245func cs_lab_from_xyz(cs: *i64, X: i64, Y: i64, Z: i64, Xn: i64, Yn: i64, Zn: i64, out3: *i64) -> i64
254func cs_xyz_from_lab(cs: *i64, L: i64, a: i64, b: i64, Xn: i64, Yn: i64, Zn: i64, out3: *i64) -> i64
269func cs_de_c7_sqrt_ratio(fq: *i64, C: i64) -> i64
281func cs_hue_deg(fq: *i64, a: i64, b: i64) -> i64
288func cs_cos_deg(fq: *i64, deg: i64) -> i64 { return fq_cos(fq, fq_deg2rad(fq, deg)) }
called by 1: cs_de2000_ex calls 2: fq_cosfq_deg2rad
289func cs_sin_deg(fq: *i64, deg: i64) -> i64 { return fq_sin(fq, fq_deg2rad(fq, deg)) }
called by 1: cs_de2000_ex calls 2: fq_sinfq_deg2rad
290func cs_milli(m: i64) -> i64 { return fq_div(fq_from_int(m), fq_from_int(CS_MILLI)) }
called by 1: cs_de2000_ex calls 2: fq_divfq_from_int
292func cs_de2000_ex(cs: *i64, L1: i64, a1: i64, b1: i64, L2: i64, a2: i64, b2: i64, out4: *i64) -> i64
353func cs_de2000(cs: *i64, L1: i64, a1: i64, b1: i64, L2: i64, a2: i64, b2: i64) -> i64
360func cs_icc_xyz_tag(b: *u8, off: i64, p: *i64, col: i64) -> i64
called by 1: cs_icc_load calls 1: cs_s15f16_q30
367func cs_icc_wtpt_tag(b: *u8, off: i64, p: *i64) -> i64
called by 1: cs_icc_load calls 1: cs_s15f16_q30
375func cs_icc_trc_tag(cs: *i64, b: *u8, off: i64, lut: *i64) -> i64
406func cs_inv3(m: *i64, mo: i64, out: *i64, oo: i64) -> i64
441func cs_b64_val(c: i64) -> i64
called by 1: cs_b64_decode
449func cs_b64_decode(src: *u8, n: i64, out: *u8) -> i64
called by 1: cs_icc_load calls 1: cs_b64_val
475func cs_icc_load(cs: *i64, path: *u8) -> *i64
530func cs_prof_rgb_to_lab(cs: *i64, p: *i64, r: i64, g: i64, b: i64, out3: *i64) -> i64
543func cs_lut_inverse(lut: *i64, lin: i64) -> i64
called by 1: cs_prof_lab_to_rgb
555func cs_clamp01(v: i64) -> i64 { if v < 0 { return 0 } if v > FQ_ONE { return FQ_ONE } return v }
called by 1: cs_prof_lab_to_rgb
557func cs_prof_lab_to_rgb(cs: *i64, p: *i64, L: i64, a: i64, b: i64, out3: *i64) -> i64
578func cs_gbd_alloc(hs: i64, es: i64) -> *i64
called by 3: maincs_icc_gamutmain calls 1: sys_mmap
588func cs_gbd_sector(cs: *i64, g: *i64, L: i64, a: i64, b: i64, out3: *i64) -> i64
607func cs_gbd_add(cs: *i64, g: *i64, L: i64, a: i64, b: i64) -> i64
616func cs_gbd_rmax(g: *i64, hs: i64, es: i64) -> i64
called by 1: cs_gbd_permil
641func cs_gbd_unsampled(g: *i64) -> i64
called by 1: main
649func cs_gbd_permil(cs: *i64, g: *i64, L: i64, a: i64, b: i64) -> i64
658func cs_gbd_from_profile(cs: *i64, p: *i64, g: *i64, steps: i64) -> i64
691func cs_icc_gamut(cs: *i64, path: *u8, hs: i64, es: i64, steps: i64) -> *i64
700func cs_gamut_clip(cs: *i64, g: *i64, L: i64, a: i64, b: i64, iters: i64, out3: *i64) -> i64
729func cs_prof_lab_to_lin(cs: *i64, p: *i64, L: i64, a: i64, b: i64, out3: *i64) -> i64
740func cs_prof_gamut_permil(cs: *i64, p: *i64, L: i64, a: i64, b: i64) -> i64
756func cs_cat_q(v: i64) -> i64 { return fq_div(fq_from_int(v), fq_from_int(CS_CAT_SCALE)) }
called by 1: cs_cat_cone calls 2: fq_divfq_from_int
760func cs_cat_cone(which: i64, out9: *i64) -> i64
called by 1: cs_cat_build calls 1: cs_cat_q
788func cs_cat_mul3(a: *i64, b: *i64, out9: *i64) -> i64
called by 1: cs_cat_build calls 1: fq_mul
807func cs_cat_apply(m9: *i64, X: i64, Y: i64, Z: i64, out3: *i64) -> i64
called by 3: maincs_cat_buildcs_cat_xyz calls 1: fq_mul
817func cs_cat_build(Xs: i64, Ys: i64, Zs: i64, Xd: i64, Yd: i64, Zd: i64, which: i64, out9: *i64) -> i64
846func cs_cat_xyz(X: i64, Y: i64, Z: i64, Xs: i64, Ys: i64, Zs: i64, Xd: i64, Yd: i64, Zd: i64, which: i64, out3: *i64) -> i64
854func cs_prof_gamut_clip(cs: *i64, p: *i64, L: i64, a: i64, b: i64, iters: i64, out3: *i64) -> i64