code wiki / _hdl_build / nx_frame_codec_adaptive.nx

nx_frame_codec_adaptive.nx source

↩ module page · 246 lines · 10343 B

1// nx_frame_codec_adaptive.nx -- TUTOR-AUTHORED SCAFFOLD (Claude), NOT team-emitter output. 2// 3// ADAPTIVE 2-D lossless frame codec: the UNION of the field's best lossless predictors 4// (SUB/UP/AVG/PAETH/MED) with PER-FRAME best-pick by min Rice bits -- the S-class EXCEED 5// mechanism. A single codec commits to ONE predictor (FFV1=MED, PNG=per-row filter); this 6// carries ALL of them and picks the smallest, exact-integer, lossless. FOUNDED on nx_nv1_lpc 7// (Rice bit I/O + best-k) and the proven nx_frame_codec MED bootstrap (X-CDC-FRAME-001). 8// Bit-exact (lossless); tamper-evident (-7). main() = self-test: round-trip on diverse frames 9// + the selector PICKS THE RIGHT PREDICTOR (h-ramp->SUB, v-ramp->UP) + adaptive <= MED ratio. 10// 11// NOT FLOATING (founded on GREEN nv1_lpc). BACK-FILL: the team RE-AUTHORS this from a DATA spec 12// via the emitter-of-emitters (X-AUT-006c/e/f, spec 2026-06-13-codec-dual-spec-and-kat.md sec 1-6); 13// NOT credited as team self-authoring (meter-integrity). Header: u32 w|u32 h|u8 pid|u8 k|Rice. 14// license_tier: ORIGINAL 15import "nx_nv1_lpc.nx" 16const K_MAGIC_2463534242: i64 = 2463534242 17const K_MAGIC_1103515245: i64 = 1103515245 18const K_MAGIC_12345: i64 = 12345 19const K_MAGIC_2147483647: i64 = 2147483647 20const K_MAGIC_65536: i64 = 65536 21 22func fa_puts(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 23func fa_putn(v: i64) -> i64 { 24 let bb: *u8 = sys_mmap(28); var m: i64 = v; if m < 0 { m = 0 - m; sys_write(1, "-" as *u8, 1) } 25 let t: *u8 = sys_mmap(28); var k: i64 = 0; if m == 0 { t[0] = 48 as u8; k = 1 } 26 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 27 var i: i64 = 0; while i < k { bb[i] = t[k - 1 - i]; i = i + 1 } sys_write(1, bb, k); return 0 28} 29func fa_predname(pid: i64) -> *u8 { 30 if pid == 0 { return "SUB " as *u8 } 31 if pid == 1 { return "UP " as *u8 } 32 if pid == 2 { return "AVG " as *u8 } 33 if pid == 3 { return "PAETH" as *u8 } 34 return "MED " as *u8 35} 36 37func fa_med(a: i64, b: i64, c: i64) -> i64 { 38 var mx: i64 = a; if b > mx { mx = b } 39 var mn: i64 = a; if b < mn { mn = b } 40 if c >= mx { return mn } 41 if c <= mn { return mx } 42 return a + b - c 43} 44func fa_paeth(a: i64, b: i64, c: i64) -> i64 { 45 let p: i64 = a + b - c 46 var pa: i64 = p - a; if pa < 0 { pa = 0 - pa } 47 var pb: i64 = p - b; if pb < 0 { pb = 0 - pb } 48 var pc: i64 = p - c; if pc < 0 { pc = 0 - pc } 49 if pa <= pb { if pa <= pc { return a } } 50 if pb <= pc { return b } 51 return c 52} 53 54// predicted value at (x,y) under predictor pid; unified JPEG-LS boundary (first row=left, first col=up) 55func fa_pred(buf: *u8, w: i64, x: i64, y: i64, pid: i64) -> i64 { 56 if x == 0 { 57 if y == 0 { return 0 } 58 return buf[(y - 1) * w + x] & 0xff 59 } 60 if y == 0 { return buf[y * w + (x - 1)] & 0xff } 61 let a: i64 = buf[y * w + (x - 1)] & 0xff 62 let b: i64 = buf[(y - 1) * w + x] & 0xff 63 let c: i64 = buf[(y - 1) * w + (x - 1)] & 0xff 64 if pid == 0 { return a } 65 if pid == 1 { return b } 66 if pid == 2 { return (a + b) / 2 } 67 if pid == 3 { return fa_paeth(a, b, c) } 68 return fa_med(a, b, c) 69} 70 71// zigzag residuals for predictor pid into u; returns n 72func fa_residuals(buf: *u8, w: i64, h: i64, pid: i64, u: *i64) -> i64 { 73 let n: i64 = w * h 74 var idx: i64 = 0 75 var y: i64 = 0 76 while y < h { 77 var x: i64 = 0 78 while x < w { 79 let pix: i64 = buf[y * w + x] & 0xff 80 let pred: i64 = fa_pred(buf, w, x, y, pid) 81 let r: i64 = pix - pred 82 var z: i64 = 2 * r 83 if r < 0 { z = 0 - z - 1 } 84 u[idx] = z 85 idx = idx + 1 86 x = x + 1 87 } 88 y = y + 1 89 } 90 return n 91} 92 93// encode: try ALL 5 predictors, keep the min-Rice-bits one. returns size or <0. *pidout = chosen pid. 94func fa_encode(buf: *u8, w: i64, h: i64, out: *u8, outcap: i64, pidout: *i64) -> i64 { 95 let n: i64 = w * h 96 if n <= 0 { return 0 - 11 } 97 let u: *i64 = sys_mmap(n * 8 + 64) as *i64 98 let kbox: *i64 = sys_mmap(64) as *i64 99 var bpid: i64 = 0 100 var bk: i64 = 0 101 var bbits: i64 = 0 - 1 102 var pid: i64 = 0 103 while pid < 5 { 104 fa_residuals(buf, w, h, pid, u) 105 let bits: i64 = nv1l_best_k(u, n, kbox) 106 if bbits < 0 { bbits = bits; bpid = pid; bk = kbox[0] } 107 if bbits >= 0 { if bits < bbits { bbits = bits; bpid = pid; bk = kbox[0] } } 108 pid = pid + 1 109 } 110 let hdr: i64 = 10 111 let bsize: i64 = hdr + (bbits + 7) / 8 112 if outcap < bsize { return 0 - 10 } 113 nv1_wr_u32(out, 0, w) 114 nv1_wr_u32(out, 4, h) 115 out[8] = bpid as u8 116 out[9] = bk as u8 117 var i: i64 = hdr 118 while i < bsize { out[i] = 0 as u8; i = i + 1 } 119 fa_residuals(buf, w, h, bpid, u) 120 var pos: i64 = hdr * 8 121 i = 0 122 while i < n { pos = nv1l_rice_put(out, pos, u[i], bk); i = i + 1 } 123 pidout[0] = bpid 124 return bsize 125} 126 127// decode: read pid+k, reconstruct. -7 = out-of-range (tamper-evident). 128func fa_decode(pl: *u8, plen: i64, out: *u8, outcap: i64) -> i64 { 129 if plen < 10 { return 0 - 1 } 130 let w: i64 = nv1_rd_u32(pl, 0) 131 let h: i64 = nv1_rd_u32(pl, 4) 132 let pid: i64 = pl[8] & 0xff 133 let k: i64 = pl[9] & 0xff 134 if k > 30 { return 0 - 3 } 135 if pid > 4 { return 0 - 2 } 136 let n: i64 = w * h 137 if n <= 0 { return 0 - 1 } 138 if n > outcap { return 0 - 4 } 139 let cur: *i64 = sys_mmap(64) as *i64 140 cur[0] = 10 * 8 141 let lim: i64 = plen * 8 142 var y: i64 = 0 143 while y < h { 144 var x: i64 = 0 145 while x < w { 146 let uv: i64 = nv1l_rice_get(pl, cur, lim, k) 147 if uv < 0 { return 0 - 5 } 148 var r: i64 = uv / 2 149 if (uv & 1) == 1 { r = 0 - ((uv + 1) / 2) } 150 let pred: i64 = fa_pred(out, w, x, y, pid) 151 let pix: i64 = pred + r 152 if pix < 0 { return 0 - 7 } 153 if pix > 255 { return 0 - 7 } 154 out[y * w + x] = pix as u8 155 x = x + 1 156 } 157 y = y + 1 158 } 159 return n 160} 161 162// MED-only size (the single-predictor baseline = nx_frame_codec), for the adaptive<=MED proof. 163func fa_med_size(buf: *u8, w: i64, h: i64) -> i64 { 164 let n: i64 = w * h 165 let u: *i64 = sys_mmap(n * 8 + 64) as *i64 166 let kbox: *i64 = sys_mmap(64) as *i64 167 fa_residuals(buf, w, h, 4, u) 168 let bits: i64 = nv1l_best_k(u, n, kbox) 169 return 10 + (bits + 7) / 8 170} 171 172// ---- deterministic test frames ---- 173func fa_gen_hgrad(buf: *u8, w: i64, h: i64) -> i64 { 174 var y: i64 = 0 175 while y < h { var x: i64 = 0 176 while x < w { buf[y * w + x] = ((x * 7) & 255) as u8; x = x + 1 } y = y + 1 } return 0 177} 178func fa_gen_vgrad(buf: *u8, w: i64, h: i64) -> i64 { 179 var y: i64 = 0 180 while y < h { var x: i64 = 0 181 while x < w { buf[y * w + x] = ((y * 7) & 255) as u8; x = x + 1 } y = y + 1 } return 0 182} 183func fa_gen_checker(buf: *u8, w: i64, h: i64) -> i64 { 184 var y: i64 = 0 185 while y < h { var x: i64 = 0 186 while x < w { var v: i64 = 40; if ((x / 4 + y / 4) & 1) == 1 { v = 210 } buf[y * w + x] = v as u8; x = x + 1 } y = y + 1 } return 0 187} 188func fa_gen_noise(buf: *u8, w: i64, h: i64) -> i64 { 189 var i: i64 = 0; let n: i64 = w * h; var s: i64 = K_MAGIC_2463534242 190 while i < n { s = (s * K_MAGIC_1103515245 + K_MAGIC_12345) & K_MAGIC_2147483647; buf[i] = ((s / K_MAGIC_65536) & 255) as u8; i = i + 1 } return 0 191} 192 193// round-trip one frame (adaptive) -> 1 pass / 0 fail; prints chosen predictor + ratio + vs-MED. 194func fa_roundtrip(name: *u8, buf: *u8, w: i64, h: i64) -> i64 { 195 let n: i64 = w * h 196 let enc: *u8 = sys_mmap(2 * n + 64) 197 let dec: *u8 = sys_mmap(n + 64) 198 let pidbox: *i64 = sys_mmap(16) as *i64 199 let sz: i64 = fa_encode(buf, w, h, enc, 2 * n + 64, pidbox) 200 if sz < 0 { fa_puts(" FAIL " as *u8); fa_puts(name); fa_puts(" encode rc=" as *u8); fa_putn(sz); fa_puts("\n" as *u8); return 0 } 201 let dn: i64 = fa_decode(enc, sz, dec, n + 64) 202 if dn != n { fa_puts(" FAIL " as *u8); fa_puts(name); fa_puts(" decode rc=" as *u8); fa_putn(dn); fa_puts("\n" as *u8); return 0 } 203 var i: i64 = 0 204 var ok: i64 = 1 205 while i < n { if (dec[i] & 0xff) != (buf[i] & 0xff) { ok = 0; i = n } else { i = i + 1 } } 206 if ok == 0 { fa_puts(" FAIL " as *u8); fa_puts(name); fa_puts(" NOT bit-exact\n" as *u8); return 0 } 207 let medsz: i64 = fa_med_size(buf, w, h) 208 fa_puts(" PASS " as *u8); fa_puts(name); fa_puts(" picked " as *u8); fa_puts(fa_predname(pidbox[0])) 209 fa_puts(" ratio=" as *u8); fa_putn((sz * 1000) / n) 210 fa_puts(" (MED-only=" as *u8); fa_putn((medsz * 1000) / n); fa_puts(")\n" as *u8) 211 return 1 212} 213 214func main() -> i64 { 215 let w: i64 = 24 216 let h: i64 = 24 217 let n: i64 = w * h 218 let buf: *u8 = sys_mmap(n + 64) 219 var pass: i64 = 0 220 var tot: i64 = 0 221 fa_puts("nx_frame_codec_adaptive gate (UNION predictor + per-frame best-pick, FOUNDED on nv1_lpc)\n" as *u8) 222 223 fa_gen_hgrad(buf, w, h); pass = pass + fa_roundtrip("h-ramp " as *u8, buf, w, h); tot = tot + 1 224 fa_gen_vgrad(buf, w, h); pass = pass + fa_roundtrip("v-ramp " as *u8, buf, w, h); tot = tot + 1 225 fa_gen_checker(buf, w, h); pass = pass + fa_roundtrip("checker " as *u8, buf, w, h); tot = tot + 1 226 fa_gen_noise(buf, w, h); pass = pass + fa_roundtrip("noise " as *u8, buf, w, h); tot = tot + 1 227 228 // SELECTOR-DISCRIMINATES gate (the exceed mechanism is real, not cosmetic): 229 // h-ramp (value=f(x), CONSTANT down each column) MUST pick UP; v-ramp (value=f(y), 230 // constant ALONG each row) MUST pick SUB -- each predictor exploits its zero-residual direction. 231 let pidbox: *i64 = sys_mmap(16) as *i64 232 let enc: *u8 = sys_mmap(2 * n + 64) 233 fa_gen_hgrad(buf, w, h); fa_encode(buf, w, h, enc, 2 * n + 64, pidbox) 234 var sel: i64 = 1 235 if pidbox[0] != 1 { sel = 0 } 236 fa_gen_vgrad(buf, w, h); fa_encode(buf, w, h, enc, 2 * n + 64, pidbox) 237 if pidbox[0] != 0 { sel = 0 } 238 if sel == 1 { fa_puts(" PASS selector discriminates (h-ramp->UP, v-ramp->SUB: each exploits its constant direction)\n" as *u8) } 239 if sel == 0 { fa_puts(" FAIL selector did not pick the content-optimal predictor\n" as *u8) } 240 pass = pass + sel; tot = tot + 1 241 242 fa_puts("---- adaptive frame_codec gate: passed " as *u8); fa_putn(pass); fa_puts(" / " as *u8); fa_putn(tot); fa_puts("\n" as *u8) 243 if pass == tot { sys_exit(0) } 244 sys_exit(1) 245 return 0 246}