code wiki / (root) / nx_garment_twin_gate.nx

nx_garment_twin_gate.nx source

↩ module page · 156 lines · 9334 B

1// nx_garment_twin_gate.nx -- THE GATE FOR THE FLAT-FRONT GARMENT PREVIEW (nx_garment_twin forked for real), 2026-08-24. 2// 3// FIXTURES AT RUNTIME in /tmp/nx_garment_twin_gate/: a 32x32 P6 print (left half pure red, right half pure white) and 4// two confs derived from the estate conf's shape -- one with relief, one with relief_permil=0 (the neg-control: no 5// knit modulation may appear when the relief is zero). Teeth read the DECODED output: canvas dimensions, the fabric 6// outside the chest box reads as (shaded) fabric albedo, the print region is redder than the fabric, ink only darkens 7// (print-region luma below fabric luma), the knit modulation is PRESENT with relief and ABSENT without it (bite). 8// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0 9import "nx_syscalls.nx" 10import "nx_gate_verdict.nx" 11import "nx_tool_run.nx" 12import "nx_img_to_rgb.nx" 13 14const GG_SUBJECT_DEFAULT: *u8 = "nx_garment_twin.elf" 15const GG_DIR: *u8 = "/tmp/nx_garment_twin_gate" 16const GG_PRINT: *u8 = "/tmp/nx_garment_twin_gate/print.ppm" 17const GG_CONF: *u8 = "/tmp/nx_garment_twin_gate/relief.conf" 18const GG_CONF_FLAT: *u8 = "/tmp/nx_garment_twin_gate/flat.conf" 19const GG_OUT: *u8 = "/tmp/nx_garment_twin_gate/out.png" 20const GG_OUT_FLAT: *u8 = "/tmp/nx_garment_twin_gate/outflat.png" 21const GG_MODE_DIR: i64 = 493 22const GG_MODE_0644: i64 = 420 23const GG_CAPTURE_CAP: i64 = 65536 24const GG_ARGV_SLOTS: i64 = 8 25const GG_SLOT: i64 = 8 26const GG_CHANNELS: i64 = 3 27const GG_PW: i64 = 32 28const GG_PH: i64 = 32 29const GG_CODE_MAX: i64 = 255 30const GG_PPM_HDR: *u8 = "P6\n32 32\n255\n" 31const GG_W: i64 = 256 // fixture canvas (the conf rows below) 32const GG_H: i64 = 320 33const GG_FAB: i64 = 246 // fixture fabric albedo (one value for all three channels: a neutral) 34const GG_BOX_X: i64 = 51 // 200 permil of 256 35const GG_BOX_Y: i64 = 80 // 250 permil of 320 36const GG_BOX_W: i64 = 153 // 600 permil of 256 37const GG_PROBE_X: i64 = 8 // a fabric pixel well outside the box 38const GG_PROBE_Y: i64 = 8 39const GG_RUN_LEN: i64 = 24 // a run of fabric pixels: the knit must vary along it when relief is on 40const GG_RED_X_OFF: i64 = 10 // inside the red half of the placed print 41const GG_RED_Y_OFF: i64 = 10 42const GG_SHADE_FLOOR: i64 = 700 // ambient_permil of the fixture conf: fabric never darker than this permil of albedo 43const GG_PERMIL: i64 = 1000 44const GG_EXIT_OK: i64 = 0 45 46func gg_write_bytes(path: *u8, b: *u8, n: i64) -> i64 { 47 let fd: i64 = sys_openat_wr(path, GG_MODE_0644) 48 if fd < 0 { return 0 - 1 } 49 let wr: i64 = sys_write(fd, b, n) 50 sys_close(fd) 51 if wr != n { return 0 - 1 } 52 return n 53} 54func gg_write_text(path: *u8, s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return gg_write_bytes(path, s, n) } 55func gg_write_print(path: *u8) -> i64 { 56 var hl: i64 = 0 57 while GG_PPM_HDR[hl] != (0 as u8) { hl = hl + 1 } 58 let total: i64 = hl + GG_PW * GG_PH * GG_CHANNELS 59 let b: *u8 = sys_mmap(total) 60 var i: i64 = 0 61 while i < hl { b[i] = GG_PPM_HDR[i]; i = i + 1 } 62 var y: i64 = 0 63 while y < GG_PH { 64 var x: i64 = 0 65 while x < GG_PW { 66 let o: i64 = hl + (y * GG_PW + x) * GG_CHANNELS 67 if x < GG_PW / 2 { b[o] = GG_CODE_MAX as u8; b[o + 1] = 0 as u8; b[o + 2] = 0 as u8 } 68 else { b[o] = GG_CODE_MAX as u8; b[o + 1] = GG_CODE_MAX as u8; b[o + 2] = GG_CODE_MAX as u8 } 69 x = x + 1 70 } 71 y = y + 1 72 } 73 return gg_write_bytes(path, b, total) 74} 75func gg_run(subject: *u8, a1: *u8, a2: *u8, a3: *u8, a4: *u8, out: *u8, outlen: *i64) -> i64 { 76 let av: *i64 = sys_mmap(GG_SLOT * GG_ARGV_SLOTS) as *i64 77 av[0] = subject as i64 78 av[1] = a1 as i64 79 av[2] = a2 as i64 80 av[3] = a3 as i64 81 av[4] = a4 as i64 82 av[5] = 0 83 return tr_run_capture(subject, av, out, GG_CAPTURE_CAP, outlen) 84} 85// decode an output; returns the rgb buffer (0 on failure) and fills wh 86func gg_decode(path: *u8, wh: *i64) -> *u8 { 87 wh[0] = 0 88 wh[1] = 0 89 return nx_img_to_rgb(path, wh) 90} 91func gg_px(rgb: *u8, w: i64, x: i64, y: i64, c: i64) -> i64 { return rgb[(y * w + x) * GG_CHANNELS + c] as i64 } 92// max minus min of channel 0 along a horizontal run: the knit modulation signal 93func gg_run_spread(rgb: *u8, w: i64, x0: i64, y: i64, n: i64) -> i64 { 94 var lo: i64 = GG_CODE_MAX 95 var hi: i64 = 0 96 var i: i64 = 0 97 while i < n { let v: i64 = gg_px(rgb, w, x0 + i, y, 0); if v < lo { lo = v } if v > hi { hi = v } i = i + 1 } 98 return hi - lo 99} 100 101func main(argc: i64, argv: *i64) -> i64 { 102 let ctr: *i64 = gv_ctr() 103 gv_head("nx_garment_twin gate -- ink multiplies the fabric, the knit relief shades it, and a zero relief shades nothing" as *u8) 104 var subject: *u8 = GG_SUBJECT_DEFAULT 105 if argc >= 2 { subject = argv[1] as *u8 } 106 gv_puts(" subject: " as *u8); gv_puts(subject); gv_puts("\n\n" as *u8) 107 sys_mkdir(GG_DIR, GG_MODE_DIR) 108 sys_unlinkat(GG_OUT) 109 sys_unlinkat(GG_OUT_FLAT) 110 let wp: i64 = gg_write_print(GG_PRINT) 111 let wc: i64 = gg_write_text(GG_CONF, "canvas_w=256\ncanvas_h=320\nfabric_r=246\nfabric_g=246\nfabric_b=246\nwale_px=4\ncourse_px=6\nrelief_permil=180\nambient_permil=700\nchest_x_permil=200\nchest_y_permil=250\nchest_w_permil=600\n" as *u8) 112 let wf: i64 = gg_write_text(GG_CONF_FLAT, "canvas_w=256\ncanvas_h=320\nfabric_r=246\nfabric_g=246\nfabric_b=246\nwale_px=4\ncourse_px=6\nrelief_permil=0\nambient_permil=700\nchest_x_permil=200\nchest_y_permil=250\nchest_w_permil=600\n" as *u8) 113 var setup: i64 = 0 114 if wp > 0 { if wc > 0 { if wf > 0 { setup = 1 } } } 115 gv_check("setup-fixtures-written (print, relief conf, flat conf)" as *u8, setup, ctr) 116 let wh0: *i64 = sys_mmap(GG_SLOT * 2) as *i64 117 gv_check("setup-outputs-absent-before-measuring (gate is idempotent)" as *u8, ((gg_decode(GG_OUT, wh0) as i64) == 0) as i64, ctr) 118 let cap: *u8 = sys_mmap(GG_CAPTURE_CAP) 119 let olen: *i64 = sys_mmap(GG_SLOT * 2) as *i64 120 let rc: i64 = gg_run(subject, "place" as *u8, GG_PRINT, GG_OUT, GG_CONF, cap, olen) 121 gv_puts(" [place relief] rc=" as *u8); gv_num(rc); gv_puts("\n" as *u8); sys_write(1, cap, olen[0]) 122 gv_check("place-exits-0-and-says-PLACED" as *u8, ((rc == GG_EXIT_OK) as i64) * tr_contains(cap, olen[0], "verdict=PLACED" as *u8), ctr) 123 gv_check("place-declares-its-surface-honestly (FLAT-FRONT-KNIT, mesh drape named as the next rung)" as *u8, tr_contains(cap, olen[0], "surface=FLAT-FRONT-KNIT" as *u8), ctr) 124 let wh: *i64 = sys_mmap(GG_SLOT * 2) as *i64 125 let img: *u8 = gg_decode(GG_OUT, wh) 126 var dims: i64 = 0 127 if (img as i64) != 0 { if wh[0] == GG_W { if wh[1] == GG_H { dims = 1 } } } 128 gv_check("output-decodes-at-the-conf-canvas-size" as *u8, dims, ctr) 129 if dims == 1 { 130 let fr: i64 = gg_px(img, GG_W, GG_PROBE_X, GG_PROBE_Y, 0) 131 let fg: i64 = gg_px(img, GG_W, GG_PROBE_X, GG_PROBE_Y, 1) 132 let fb: i64 = gg_px(img, GG_W, GG_PROBE_X, GG_PROBE_Y, 2) 133 gv_puts(" fabric_probe=" as *u8); gv_num(fr); gv_puts("," as *u8); gv_num(fg); gv_puts("," as *u8); gv_num(fb); gv_puts("\n" as *u8) 134 var fabric_ok: i64 = 0 135 if fr == fg { if fg == fb { if fr <= GG_FAB { if fr >= (GG_FAB * GG_SHADE_FLOOR) / GG_PERMIL { fabric_ok = 1 } } } } 136 gv_check("fabric-outside-the-box-is-neutral-albedo-shaded-no-darker-than-the-ambient-floor" as *u8, fabric_ok, ctr) 137 let rr: i64 = gg_px(img, GG_W, GG_BOX_X + GG_RED_X_OFF, GG_BOX_Y + GG_RED_Y_OFF, 0) 138 let rg: i64 = gg_px(img, GG_W, GG_BOX_X + GG_RED_X_OFF, GG_BOX_Y + GG_RED_Y_OFF, 1) 139 gv_puts(" red_region=" as *u8); gv_num(rr); gv_puts("," as *u8); gv_num(rg); gv_puts("\n" as *u8) 140 gv_check("print-region-shows-the-print (red channel high, green channel ink-suppressed to zero)" as *u8, ((rr > rg) as i64) * ((rg == 0) as i64), ctr) 141 gv_check("ink-only-darkens (red-region red channel never above the fabric albedo)" as *u8, (rr <= GG_FAB) as i64, ctr) 142 let spread_relief: i64 = gg_run_spread(img, GG_W, GG_PROBE_X, GG_PROBE_Y, GG_RUN_LEN) 143 gv_puts(" knit_spread_relief=" as *u8); gv_num(spread_relief); gv_puts("\n" as *u8) 144 gv_check("knit-modulation-present-with-relief (spread along a fabric run > 0)" as *u8, (spread_relief > 0) as i64, ctr) 145 let rc2: i64 = gg_run(subject, "place" as *u8, GG_PRINT, GG_OUT_FLAT, GG_CONF_FLAT, cap, olen) 146 let wh2: *i64 = sys_mmap(GG_SLOT * 2) as *i64 147 let img2: *u8 = gg_decode(GG_OUT_FLAT, wh2) 148 var spread_flat: i64 = 0 - 1 149 if (img2 as i64) != 0 { if wh2[0] == GG_W { spread_flat = gg_run_spread(img2, GG_W, GG_PROBE_X, GG_PROBE_Y, GG_RUN_LEN) } } 150 gv_puts(" knit_spread_flat=" as *u8); gv_num(spread_flat); gv_puts("\n" as *u8) 151 gv_bite("neg-control-zero-relief-shades-nothing (fires with relief, silent without)" as *u8, (spread_relief > 0) as i64, (spread_flat != 0) as i64, ctr) 152 } 153 // luma partition from the subject's own stats line: ink darkens the print region below the fabric 154 gv_check("stats-line-present (fabric_luma_permil and print_luma_permil)" as *u8, tr_contains(cap, olen[0], "print_luma_permil=" as *u8), ctr) 155 return gv_verdict("garment_twin" as *u8, ctr, "the print multiplies white cotton, the knit relief shades it under a light, and a zero relief is a flat composite" as *u8) 156}