code wiki / _hdl_build / nx_frame_codec.nx
nx_frame_codec.nx source
↩ module page · 215 lines · 9715 B
1// nx_frame_codec.nx -- TUTOR-AUTHORED SCAFFOLD (Claude), NOT team-emitter output.
2//
3// 2-D LOSSLESS image/video-FRAME codec: JPEG-LS/FFV1-class MED (median) predictor over causal
4// neighbors + zigzag + Rice residuals. FOUNDED ON nx_nv1_lpc: it REUSES that organ's proven
5// Rice bit I/O (nv1l_rice_put/get), best-k (nv1l_best_k) and the predict->zigzag->Rice machinery,
6// lifted from 1-D audio samples to 2-D pixels. Bit-exact (lossless): decode(encode(f)) == f.
7// Tamper-evident: an out-of-range reconstruction returns -7 (the nv1_lpc doctrine).
8//
9// This is the lossless-VIDEO fidelity anchor (the bird's video pixel-exact); JPEG/lossy demotes
10// to a measured fallback tier. main() is the unforgeable self-test: round-trip bit-exact on
11// gradient/checker/edge/extremes/noise + compression-actual (gradient must shrink) + tamper.
12//
13// NOT FLOATING (operator law 2026-06-13 "don't build things that hang in the air"): it sits on
14// nx_nv1_lpc (a GREEN organ). BACK-FILL: the team RE-AUTHORS this from a DATA spec via the
15// emitter-of-emitters (X-AUT-006c/e/f, spec 2026-06-13-codec-dual-spec-and-kat.md) -- this scaffold
16// is the sanctioned one-time bootstrap, NOT credited as team self-authoring (meter-integrity).
17// v1 = single 8-bit plane, single MED predictor; the adaptive predictor library + NFC1 container
18// are the named follow-ons. No verbatim escape yet (buffers sized 2n so noise cannot overrun).
19// license_tier: ORIGINAL
20import "nx_nv1_lpc.nx"
21import "nx_itoa_lib.nx" // shared MSB-first emitter (zero-alloc)
22const K_MAGIC_2463534242: i64 = 2463534242
23const K_MAGIC_1103515245: i64 = 1103515245
24const K_MAGIC_12345: i64 = 12345
25const K_MAGIC_2147483647: i64 = 2147483647
26const K_MAGIC_65536: i64 = 65536
27
28func fc_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
29// MIGRATED to the shared emitter (debt 1785563586). The old body mmapped a scratch buffer
30// per call and never freed it. At PAGE granularity that is 4096B leaked PER CALL -- the
31// defect that took 28.5GB of a 36GB host in nx_ts_lumadiff (2MB input, ~3.66M calls).
32// nxi_* is MSB-first, allocates NOTHING, and emits identical bytes including the sign.
33func fc_putn(v: i64) -> i64 { nxi_out(v); return 0 }
34
35// MED / LOCO-I median predictor of three causal neighbors (a=left, b=up, c=up-left)
36func fc_med(a: i64, b: i64, c: i64) -> i64 {
37 var mx: i64 = a; if b > mx { mx = b }
38 var mn: i64 = a; if b < mn { mn = b }
39 if c >= mx { return mn }
40 if c <= mn { return mx }
41 return a + b - c
42}
43
44// predicted value at (x,y) from already-known pixels in buf (w wide); JPEG-LS boundary rule
45func fc_pred(buf: *u8, w: i64, x: i64, y: i64) -> i64 {
46 if x == 0 {
47 if y == 0 { return 0 }
48 return buf[(y - 1) * w + x] & 0xff
49 }
50 if y == 0 { return buf[y * w + (x - 1)] & 0xff }
51 let a: i64 = buf[y * w + (x - 1)] & 0xff
52 let b: i64 = buf[(y - 1) * w + x] & 0xff
53 let c: i64 = buf[(y - 1) * w + (x - 1)] & 0xff
54 return fc_med(a, b, c)
55}
56
57// encode w*h 8-bit frame -> payload (u32 w | u32 h | u8 k | Rice bitstream). returns size or <0.
58func fc_encode(buf: *u8, w: i64, h: i64, out: *u8, outcap: i64) -> i64 {
59 let n: i64 = w * h
60 if n <= 0 { return 0 - 11 }
61 let u: *i64 = sys_mmap(n * 8 + 64) as *i64
62 var idx: i64 = 0
63 var y: i64 = 0
64 while y < h {
65 var x: i64 = 0
66 while x < w {
67 let pix: i64 = buf[y * w + x] & 0xff
68 let pred: i64 = fc_pred(buf, w, x, y)
69 let r: i64 = pix - pred
70 var z: i64 = 2 * r
71 if r < 0 { z = 0 - z - 1 }
72 u[idx] = z
73 idx = idx + 1
74 x = x + 1
75 }
76 y = y + 1
77 }
78 let kbox: *i64 = sys_mmap(64) as *i64
79 let bits: i64 = nv1l_best_k(u, n, kbox)
80 let k: i64 = kbox[0]
81 let hdr: i64 = 9
82 let bsize: i64 = hdr + (bits + 7) / 8
83 if outcap < bsize { return 0 - 10 }
84 nv1_wr_u32(out, 0, w)
85 nv1_wr_u32(out, 4, h)
86 out[8] = k as u8
87 var i: i64 = hdr
88 while i < bsize { out[i] = 0 as u8; i = i + 1 }
89 var pos: i64 = hdr * 8
90 i = 0
91 while i < n { pos = nv1l_rice_put(out, pos, u[i], k); i = i + 1 }
92 return bsize
93}
94
95// decode payload -> w*h frame at out. returns n or <0 (-7 = out-of-range reconstruction = tamper).
96func fc_decode(pl: *u8, plen: i64, out: *u8, outcap: i64) -> i64 {
97 if plen < 9 { return 0 - 1 }
98 let w: i64 = nv1_rd_u32(pl, 0)
99 let h: i64 = nv1_rd_u32(pl, 4)
100 let k: i64 = pl[8] & 0xff
101 if k > 30 { return 0 - 3 }
102 let n: i64 = w * h
103 if n <= 0 { return 0 - 1 }
104 if n > outcap { return 0 - 4 }
105 let cur: *i64 = sys_mmap(64) as *i64
106 cur[0] = 9 * 8
107 let lim: i64 = plen * 8
108 var y: i64 = 0
109 while y < h {
110 var x: i64 = 0
111 while x < w {
112 let uv: i64 = nv1l_rice_get(pl, cur, lim, k)
113 if uv < 0 { return 0 - 5 }
114 var r: i64 = uv / 2
115 if (uv & 1) == 1 { r = 0 - ((uv + 1) / 2) }
116 let pred: i64 = fc_pred(out, w, x, y)
117 let pix: i64 = pred + r
118 if pix < 0 { return 0 - 7 }
119 if pix > 255 { return 0 - 7 }
120 out[y * w + x] = pix as u8
121 x = x + 1
122 }
123 y = y + 1
124 }
125 return n
126}
127
128// ---- deterministic test frames (no RNG state escapes; pure index math) ----
129func fc_gen_gradient(buf: *u8, w: i64, h: i64) -> i64 {
130 var i: i64 = 0; let n: i64 = w * h
131 while i < n { buf[i] = (((i % w) + (i / w)) & 255) as u8; i = i + 1 } return 0
132}
133func fc_gen_checker(buf: *u8, w: i64, h: i64) -> i64 {
134 var y: i64 = 0
135 while y < h { var x: i64 = 0
136 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
137}
138func fc_gen_edge(buf: *u8, w: i64, h: i64) -> i64 {
139 var y: i64 = 0
140 while y < h { var x: i64 = 0
141 while x < w { var v: i64 = 0; if x >= w / 2 { v = 255 } buf[y * w + x] = v as u8; x = x + 1 } y = y + 1 } return 0
142}
143func fc_gen_extremes(buf: *u8, w: i64, h: i64) -> i64 {
144 var i: i64 = 0; let n: i64 = w * h
145 while i < n { var v: i64 = 0; if (i & 1) == 1 { v = 255 } buf[i] = v as u8; i = i + 1 } return 0
146}
147func fc_gen_noise(buf: *u8, w: i64, h: i64) -> i64 {
148 var i: i64 = 0; let n: i64 = w * h; var s: i64 = K_MAGIC_2463534242
149 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
150}
151
152// round-trip one frame -> 1 pass / 0 fail (prints PASS/FAIL + ratio). buffers sized 2n (no overrun).
153func fc_roundtrip(name: *u8, buf: *u8, w: i64, h: i64) -> i64 {
154 let n: i64 = w * h
155 let enc: *u8 = sys_mmap(2 * n + 64)
156 let dec: *u8 = sys_mmap(n + 64)
157 let sz: i64 = fc_encode(buf, w, h, enc, 2 * n + 64)
158 if sz < 0 { fc_puts(" FAIL " as *u8); fc_puts(name); fc_puts(" encode rc=" as *u8); fc_putn(sz); fc_puts("\n" as *u8); return 0 }
159 let dn: i64 = fc_decode(enc, sz, dec, n + 64)
160 if dn != n { fc_puts(" FAIL " as *u8); fc_puts(name); fc_puts(" decode rc=" as *u8); fc_putn(dn); fc_puts("\n" as *u8); return 0 }
161 var i: i64 = 0
162 var ok: i64 = 1
163 while i < n { if (dec[i] & 0xff) != (buf[i] & 0xff) { ok = 0; i = n } else { i = i + 1 } }
164 if ok == 0 { fc_puts(" FAIL " as *u8); fc_puts(name); fc_puts(" NOT bit-exact\n" as *u8); return 0 }
165 fc_puts(" PASS " as *u8); fc_puts(name); fc_puts(" bit-exact ratio_permil=" as *u8); fc_putn((sz * 1000) / n); fc_puts("\n" as *u8)
166 return 1
167}
168
169func main() -> i64 {
170 let w: i64 = 24
171 let h: i64 = 24
172 let n: i64 = w * h
173 let buf: *u8 = sys_mmap(n + 64)
174 var pass: i64 = 0
175 var tot: i64 = 0
176 fc_puts("nx_frame_codec gate (2-D lossless MED+Rice, FOUNDED on nv1_lpc)\n" as *u8)
177
178 fc_gen_gradient(buf, w, h); pass = pass + fc_roundtrip("gradient" as *u8, buf, w, h); tot = tot + 1
179 fc_gen_checker(buf, w, h); pass = pass + fc_roundtrip("checker " as *u8, buf, w, h); tot = tot + 1
180 fc_gen_edge(buf, w, h); pass = pass + fc_roundtrip("edge " as *u8, buf, w, h); tot = tot + 1
181 fc_gen_extremes(buf, w, h); pass = pass + fc_roundtrip("extremes" as *u8, buf, w, h); tot = tot + 1
182 fc_gen_noise(buf, w, h); pass = pass + fc_roundtrip("noise " as *u8, buf, w, h); tot = tot + 1
183
184 // compression-actual: the gradient MUST shrink (proves the predictor is load-bearing, not store)
185 fc_gen_gradient(buf, w, h)
186 let enc: *u8 = sys_mmap(2 * n + 64)
187 let gsz: i64 = fc_encode(buf, w, h, enc, 2 * n + 64)
188 var comp: i64 = 0
189 if gsz > 0 { if gsz < n { comp = 1 } }
190 if comp == 1 { fc_puts(" PASS gradient compresses " as *u8); fc_putn(gsz); fc_puts("/" as *u8); fc_putn(n); fc_puts("\n" as *u8) }
191 if comp == 0 { fc_puts(" FAIL gradient did not compress\n" as *u8) }
192 pass = pass + comp; tot = tot + 1
193
194 // tamper: flip a Rice byte -> decode must differ or be refused (the predictor is exercised)
195 let dec: *u8 = sys_mmap(n + 64)
196 var tamper: i64 = 1
197 if gsz > 9 {
198 enc[9] = (enc[9] ^ 0xff) as u8
199 let tdn: i64 = fc_decode(enc, gsz, dec, n + 64)
200 if tdn == n {
201 var j: i64 = 0
202 var same: i64 = 1
203 while j < n { if (dec[j] & 0xff) != (buf[j] & 0xff) { same = 0; j = n } else { j = j + 1 } }
204 if same == 1 { tamper = 0 }
205 }
206 }
207 if tamper == 1 { fc_puts(" PASS tamper detected (flip -> differs/refused)\n" as *u8) }
208 if tamper == 0 { fc_puts(" FAIL tamper not detected\n" as *u8) }
209 pass = pass + tamper; tot = tot + 1
210
211 fc_puts("---- frame_codec gate: passed " as *u8); fc_putn(pass); fc_puts(" / " as *u8); fc_putn(tot); fc_puts("\n" as *u8)
212 if pass == tot { sys_exit(0) }
213 sys_exit(1)
214 return 0
215}