code wiki / (root) / nx_hevc_recon.nx

nx_hevc_recon.nx source

↩ module page · 70 lines · 5071 B

1// nx_hevc_recon.nx -- SOVEREIGN HEVC reconstruction + frame output, RUNG 6a of the HEVC decoder. 2// reconstruct_block(): recon = clip(pred + residual) stored into a strided frame buffer (8.6.5). write_pgm(): 3// dump the luma plane as a viewable P5 PGM (10-bit -> 8-bit). This is the "see the frame" mechanism; R6b wires 4// the real decoded intra modes + IDCT residuals (R4/R5, already verified) into it. Self-test: a DC block and a 5// Planar-gradient block reconstruct + write to a PGM whose samples match hand-computed values. license_tier: ORIGINAL 6import "nx_syscalls.nx" 7 8func pe(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return sys_write(1,s,n) } 9func pn(v: i64) -> i64 { var m: i64=v; if m<0{m=0-m} let b: *u8=sys_mmap(32); var i: i64=32; if m==0{i=i-1;b[i]=(48 as u8)} while m>0{let q: i64=m/10; i=i-1; b[i]=((48+(m-q*10)) as u8); m=q} if v<0{i=i-1;b[i]=(45 as u8)} return sys_write(1,((b as i64)+i) as *u8,32-i) } 10func clip3(lo: i64, hi: i64, v: i64) -> i64 { if v<lo {return lo} if v>hi {return hi} return v } 11func ilog2(n: i64) -> i64 { var l: i64=0; var v: i64=n; while v>1 {v=v>>1; l=l+1} return l } 12 13// Planar prediction (8.4.4.2.4) 14func predict_planar(pred: *i64, N: i64, refL: *i64, refT: *i64, refTR: i64, refBL: i64) -> i64 { 15 let sh: i64=ilog2(N)+1; var y: i64=0 16 while y<N { var x: i64=0; while x<N { pred[y*N+x]=((N-1-x)*refL[y]+(x+1)*refTR+(N-1-y)*refT[x]+(y+1)*refBL+N)>>sh; x=x+1 } y=y+1 } 17 return 0 18} 19// DC prediction (8.4.4.2.5), interior only (edge filter omitted for this pipeline test) 20func predict_dc(pred: *i64, N: i64, refL: *i64, refT: *i64) -> i64 { 21 var s: i64=0; var k: i64=0; while k<N {s=s+refT[k]+refL[k]; k=k+1} 22 let dc: i64=(s+N)>>(ilog2(N)+1); var i: i64=0; while i<N*N {pred[i]=dc; i=i+1} 23 return 0 24} 25// reconstruct: frame[(y0+r)*stride + x0+c] = clip(0,maxv, pred[r*N+c] + res[r*N+c]) (8.6.5) 26func reconstruct_block(frame: *i64, stride: i64, x0: i64, y0: i64, N: i64, pred: *i64, res: *i64) -> i64 { 27 let maxv: i64=1023; var r: i64=0 28 while r<N { var c: i64=0; while c<N { frame[(y0+r)*stride+(x0+c)]=clip3(0,maxv,pred[r*N+c]+res[r*N+c]); c=c+1 } r=r+1 } 29 return 0 30} 31// write the luma plane (i64 10-bit samples) as a P5 PGM (8-bit, sample>>2). Header built by hand. 32func write_pgm(frame: *i64, w: i64, h: i64, path: *u8) -> i64 { 33 let fd: i64=sys_openat_wr(path, 420); if fd<0 {return 0-1} // 420 = 0644 file permission 34 let hdr: *u8=sys_mmap(64); var p: i64=0 35 hdr[p]=(80 as u8); p=p+1; hdr[p]=(53 as u8); p=p+1; hdr[p]=(10 as u8); p=p+1 // "P5\n" 36 let wd: *u8=sys_mmap(16); var wl: i64=0; var tw: i64=w; if tw==0{wd[wl]=(48 as u8); wl=wl+1} let tb: *u8=sys_mmap(16); var ti: i64=0; while tw>0{tb[ti]=((48+tw%10) as u8); ti=ti+1; tw=tw/10} while ti>0{ti=ti-1; wd[wl]=tb[ti]; wl=wl+1} 37 var wi: i64=0; while wi<wl {hdr[p]=wd[wi]; p=p+1; wi=wi+1} 38 hdr[p]=(32 as u8); p=p+1 39 var th: i64=h; ti=0; while th>0{tb[ti]=((48+th%10) as u8); ti=ti+1; th=th/10} while ti>0{ti=ti-1; hdr[p]=tb[ti]; p=p+1} 40 hdr[p]=(10 as u8); p=p+1; hdr[p]=(50 as u8); p=p+1; hdr[p]=(53 as u8); p=p+1; hdr[p]=(53 as u8); p=p+1; hdr[p]=(10 as u8); p=p+1 // "\n255\n" 41 sys_write(fd, hdr, p) 42 let body: *u8=sys_mmap(w*h); var i: i64=0; while i<w*h { var v: i64=frame[i]>>2; if v<0{v=0} if v>255{v=255} body[i]=(v as u8); i=i+1 } 43 sys_write(fd, body, w*h); sys_close(fd) 44 return 0 45} 46 47func main(argc: i64, argv: *i64) -> i64 { 48 let N: i64=64; let W: i64=128; let H: i64=64 49 let frame: *i64=sys_mmap(8*W*H) as *i64; var z: i64=0; while z<W*H {frame[z]=0; z=z+1} 50 let pred: *i64=sys_mmap(8*N*N) as *i64; let res: *i64=sys_mmap(8*N*N) as *i64 51 let refL: *i64=sys_mmap(8*256) as *i64; let refT: *i64=sys_mmap(8*256) as *i64 52 // block A @ (0,0): DC prediction (flat refs 412) + flat residual +200 -> recon 612 everywhere 53 var k: i64=0; while k<256 {refL[k]=412; refT[k]=412; k=k+1} 54 predict_dc(pred, N, refL, refT) 55 k=0; while k<N*N {res[k]=200; k=k+1} 56 reconstruct_block(frame, W, 0, 0, N, pred, res) 57 // block B @ (64,0): Planar gradient (top ramp 100..) + flat left 100 + zero residual 58 k=0; while k<256 {refT[k]=100+12*k; refL[k]=100; k=k+1} 59 predict_planar(pred, N, refL, refT, 100+12*N, 100) 60 k=0; while k<N*N {res[k]=0; k=k+1} 61 reconstruct_block(frame, W, 64, 0, N, pred, res) 62 write_pgm(frame, W, H, "/tmp/hevc_recon_test.pgm" as *u8) 63 // verify: A flat 612 ; B gradient (top-left ~ blends 100 ; increases to the right) 64 let a: i64=frame[10*W+10]; let bTL: i64=frame[0*W+64]; let bTR: i64=frame[0*W+127] 65 pe("block A (DC412+res200) sample=" as *u8); pn(a); pe(" (expect 612)\n" as *u8) 66 pe("block B Planar gradient: top-left=" as *u8); pn(bTL); pe(" top-right=" as *u8); pn(bTR); pe(" (rises L->R)\n" as *u8) 67 var ok: i64=1; if a!=612 {ok=0} if bTR<=bTL {ok=0} 68 if ok==1 { pe("R6a OK: reconstruct (pred+residual+clip+store) + PGM written to /tmp/hevc_recon_test.pgm\n" as *u8) } else { pe("R6a BAD a=" as *u8); pn(a); pe(" bTL=" as *u8); pn(bTL); pe(" bTR=" as *u8); pn(bTR); pe("\n" as *u8) } 69 return 0 70}