code wiki / _hdl_build / nx_look_compose.nx

nx_look_compose.nx source

↩ module page · 118 lines · 5856 B

1// nx_look_compose.nx -- SOVEREIGN composer for the LOOK gate (2026-07-29; retires compose.py per the 2// sovereign-no-python law: 3rd-party code is benchmark/oracle ONLY, never a lane instrument). 3// Reads THREE 8-bit grayscale BMPs (the nx_vcodec_look_dump output: SOURCE, arm A, arm B), writes ONE 4// composite grayscale BMP: the three panes side by side with a 4px white gutter, optionally a CROP of 5// each pane scaled 2x (nearest -- pixel truth, no resampling opinions). Browsers render BMP natively, 6// so the published review strip needs no PNG and no external encoder. 7// usage: nx_look_compose <src.bmp> <a.bmp> <b.bmp> <out.bmp> [x0 y0 cw ch] 8// no crop args -> full-frame strip; with crop args -> 2x-scaled crop strip. 9// CIF-class only (dimensions read from the BMP header; all three must match; width*panes padded to 4). 10// license: ORIGINAL 11import "nx_syscalls.nx" 12const LC_MAGIC_2835: i64 = 2835 13 14const LC_GUT: i64 = 4 // gutter px between panes (white) 15const LC_HDR: i64 = 1078 // 14 + 40 + 256*4 grayscale palette 16 17func gw(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 18func gn(v: i64) -> i64 { 19 let b: *u8=sys_mmap(28); var m: i64=v; if m<0{sys_write(1,"-" as *u8,1);m=0-m} 20 let t: *u8=sys_mmap(28); var k: i64=0; if m==0{t[0]=48 as u8;k=1} while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1} 21 var i: i64=0; while i<k{b[i]=t[k-1-i];i=i+1} sys_write(1,b,k); return 0 } 22func atoi(a: *u8) -> i64 { var v: i64=0; var i: i64=0 23 while a[i] != (0 as u8) { v = v*10 + ((a[i]&0xff)-48); i=i+1 } return v } 24func rd32le(b: *u8, off: i64) -> i64 { 25 return (b[off]&0xff) + ((b[off+1]&0xff)<<8) + ((b[off+2]&0xff)<<16) + ((b[off+3]&0xff)<<24) } 26func wr32le(b: *u8, off: i64, v: i64) -> i64 { 27 b[off]=(v&0xff) as u8; b[off+1]=((v>>8)&0xff) as u8 28 b[off+2]=((v>>16)&0xff) as u8; b[off+3]=((v>>24)&0xff) as u8; return 0 } 29func wr16le(b: *u8, off: i64, v: i64) -> i64 { 30 b[off]=(v&0xff) as u8; b[off+1]=((v>>8)&0xff) as u8; return 0 } 31 32// read one 8-bit BMP; returns TOP-DOWN luma buffer; wh[0]=w wh[1]=h; 0 on failure 33func bmp_read(path: *u8, wh: *i64) -> *u8 { 34 let box: *i64 = sys_mmap(16) as *i64 35 let d: *u8 = sys_read_file(path, box) 36 if (d as i64) == 0 { return 0 as *u8 } 37 if box[0] < LC_HDR { return 0 as *u8 } 38 if d[0] != (66 as u8) { return 0 as *u8 } 39 if d[1] != (77 as u8) { return 0 as *u8 } 40 let off: i64 = rd32le(d, 10) 41 let w: i64 = rd32le(d, 18) 42 let h: i64 = rd32le(d, 22) 43 if w <= 0 { return 0 as *u8 } 44 if h <= 0 { return 0 as *u8 } 45 if (w % 4) != 0 { gw("width must be /4 (unpadded rows)\n" as *u8); return 0 as *u8 } 46 let out: *u8 = sys_mmap(w*h + 64) 47 var y: i64 = 0 48 while y < h { var x: i64 = 0 49 while x < w { out[y*w + x] = d[off + (h-1-y)*w + x]; x = x + 1 } y = y + 1 } 50 wh[0] = w; wh[1] = h 51 return out } 52 53func bmp_write(path: *u8, luma: *u8, w: i64, h: i64) -> i64 { 54 let isz: i64 = w*h 55 let fsz: i64 = LC_HDR + isz 56 let buf: *u8 = sys_mmap(fsz + 64) 57 buf[0]=66 as u8; buf[1]=77 as u8 58 wr32le(buf, 2, fsz); wr32le(buf, 6, 0); wr32le(buf, 10, LC_HDR) 59 wr32le(buf, 14, 40); wr32le(buf, 18, w); wr32le(buf, 22, h) 60 wr16le(buf, 26, 1); wr16le(buf, 28, 8) 61 wr32le(buf, 30, 0); wr32le(buf, 34, isz) 62 wr32le(buf, 38, LC_MAGIC_2835); wr32le(buf, 42, LC_MAGIC_2835) 63 wr32le(buf, 46, 256); wr32le(buf, 50, 0) 64 var c: i64=0 65 while c<256 { let o: i64=54+c*4 66 buf[o]=c as u8; buf[o+1]=c as u8; buf[o+2]=c as u8; buf[o+3]=0 as u8; c=c+1 } 67 var y: i64=0 68 while y<h { var x: i64=0 69 while x<w { buf[LC_HDR + (h-1-y)*w + x] = luma[y*w + x]; x=x+1 } y=y+1 } 70 let fd: i64 = sys_openat_wr(path, 0x1a4) 71 if fd < 0 { gw("out open fail\n" as *u8); return 1 } 72 sys_write(fd, buf, fsz) 73 sys_close(fd) 74 return 0 } 75 76func main(argc: i64, argv: *i64) -> i64 { 77 if argc < 5 { gw("usage: nx_look_compose <src.bmp> <a.bmp> <b.bmp> <out.bmp> [x0 y0 cw ch]\n" as *u8); return 1 } 78 let wh: *i64 = sys_mmap(32) as *i64 79 let ps: *u8 = bmp_read(argv[1] as *u8, wh) 80 let W: i64 = wh[0]; let H: i64 = wh[1] 81 let pa: *u8 = bmp_read(argv[2] as *u8, wh) 82 if wh[0] != W { gw("dim mismatch a\n" as *u8); return 1 } 83 let pb: *u8 = bmp_read(argv[3] as *u8, wh) 84 if wh[0] != W { gw("dim mismatch b\n" as *u8); return 1 } 85 if (ps as i64)==0 { gw("read fail src\n" as *u8); return 1 } 86 if (pa as i64)==0 { gw("read fail a\n" as *u8); return 1 } 87 if (pb as i64)==0 { gw("read fail b\n" as *u8); return 1 } 88 // pane geometry: full frame, or 2x crop 89 var px: i64 = 0 90 var py: i64 = 0 91 var pw: i64 = W 92 var ph: i64 = H 93 var sc: i64 = 1 94 if argc >= 9 { px = atoi(argv[5] as *u8); py = atoi(argv[6] as *u8) 95 pw = atoi(argv[7] as *u8); ph = atoi(argv[8] as *u8); sc = 2 96 if px + pw > W { gw("crop x overflow\n" as *u8); return 1 } 97 if py + ph > H { gw("crop y overflow\n" as *u8); return 1 } } 98 let ow0: i64 = pw*sc*3 + LC_GUT*2 99 let ow: i64 = ((ow0 + 3) / 4) * 4 // BMP rows pad to 4; we pad the CANVAS instead (white) 100 let oh: i64 = ph*sc 101 let canvas: *u8 = sys_mmap(ow*oh + 64) 102 var i: i64 = 0 103 while i < ow*oh { canvas[i] = 255 as u8; i = i + 1 } 104 var pane: i64 = 0 105 while pane < 3 { 106 var src: *u8 = ps 107 if pane == 1 { src = pa } 108 if pane == 2 { src = pb } 109 let ox: i64 = pane * (pw*sc + LC_GUT) 110 var y: i64 = 0 111 while y < ph*sc { var x: i64 = 0 112 while x < pw*sc { 113 canvas[y*ow + ox + x] = src[(py + y/sc)*W + px + x/sc] 114 x = x + 1 } y = y + 1 } 115 pane = pane + 1 } 116 if bmp_write(argv[4] as *u8, canvas, ow, oh) != 0 { return 1 } 117 gw("LOOK-COMPOSE OK " as *u8); gn(ow); gw("x" as *u8); gn(oh); gw(" panes=SRC|A|B scale=" as *u8); gn(sc); gw("\n" as *u8) 118 return 0 }