nx_view_transform.nx source
↩ module page · 60 lines · 3193 B
1// nx_view_transform.nx -- CLI over nx_view_transform_lib.nx (GR23). The derivation, the LUT and the
2// application all live in the lib so the gate can import them; this file is verbs and nothing else.
3// license_tier: ORIGINAL No hw writes (Rule 26).
4// usage: nx_view_transform derive | lut | glsl | wgsl | selftest
5// exit: 0 ok | 1 refuse | 2 usage
6import "nx_syscalls.nx"
7import "nx_fixq30_lib.nx"
8import "nx_view_transform_lib.nx"
9
10func main(argc: i64, argv: **u8) -> i64 {
11 if argc < 2 {
12 vt_puts("usage: nx_view_transform derive | lut | glsl | wgsl | selftest\n" as *u8)
13 return 2
14 }
15 let ctx: *i64 = fq_ctx()
16 let g: i64 = vt_exponent(ctx)
17 let v: *u8 = argv[1]
18
19 if vt_streq(v, "derive" as *u8) == 1 {
20 vt_puts("VT-DERIVE anchor_k=" as *u8); vt_pq(fq_from_micro(VT_ANCHOR_MICRO))
21 vt_puts(" src_median=" as *u8); vt_pq(fq_from_micro(VT_SRC_MEDIAN_MICRO))
22 vt_puts(" ref_band=" as *u8); vt_pq(fq_from_micro(VT_REF_LO_MICRO))
23 vt_puts("-" as *u8); vt_pq(fq_from_micro(VT_REF_HI_MICRO))
24 vt_puts("\nVT-DERIVE target_median=" as *u8); vt_pq(vt_target_median())
25 vt_puts(" exponent=" as *u8); vt_pq(g)
26 vt_puts("\nVT-DERIVE lut_n=" as *u8); vt_pn(vt_lut_size(ctx, g))
27 vt_puts(" application=luminance-scaled (HSV saturation preserved exactly)\n" as *u8)
28 return 0
29 }
30 if vt_streq(v, "lut" as *u8) == 1 {
31 let n: i64 = vt_lut_size(ctx, g)
32 if n == 0 { vt_puts("VT-REFUSE lut-search-did-not-converge\n" as *u8); return 1 }
33 let lut: *i64 = sys_mmap((n + 1) * VT_SLOT_BYTES) as *i64
34 vt_lut_fill(ctx, g, lut, n)
35 vt_puts("VT-LUT n=" as *u8); vt_pn(n); vt_puts("\n" as *u8)
36 vt_emit_lut_body(lut, n); vt_puts("\n" as *u8)
37 return 0
38 }
39 if vt_streq(v, "glsl" as *u8) == 1 { return vt_emit(ctx, 0) }
40 if vt_streq(v, "wgsl" as *u8) == 1 { return vt_emit(ctx, 1) }
41 if vt_streq(v, "selftest" as *u8) == 1 {
42 // the anchor is a FIXED POINT of the curve: k maps to k, whatever g is
43 let k: i64 = fq_from_micro(VT_ANCHOR_MICRO)
44 vt_puts("fixed-point k->" as *u8); vt_pq(vt_curve(ctx, g, k)); vt_puts(" (expect " as *u8)
45 vt_pq(k); vt_puts(")\n" as *u8)
46 // the declared target is reproduced by construction
47 vt_puts("src_median->" as *u8); vt_pq(vt_curve(ctx, g, fq_from_micro(VT_SRC_MEDIAN_MICRO)))
48 vt_puts(" (expect " as *u8); vt_pq(vt_target_median()); vt_puts(")\n" as *u8)
49 // saturation invariance: a strongly non-grey triple keeps its min/max ratio
50 let rgb: *i64 = sys_mmap(VT_RGB_SLOTS * VT_SLOT_BYTES) as *i64
51 rgb[0] = fq_from_micro(800000); rgb[1] = fq_from_micro(400000); rgb[2] = fq_from_micro(200000)
52 let before: i64 = fq_div(rgb[2], rgb[0])
53 vt_apply(ctx, g, rgb)
54 vt_puts("chroma ratio min/max before=" as *u8); vt_pq(before)
55 vt_puts(" after=" as *u8); vt_pq(fq_div(rgb[2], rgb[0])); vt_puts("\n" as *u8)
56 return 0
57 }
58 vt_puts("usage: nx_view_transform derive | lut | glsl | wgsl | selftest\n" as *u8)
59 return 2
60}