nx_vcodec_color_frame.nx source
↩ module page · 75 lines · 3786 B
1// nx_vcodec_color_frame.nx -- RUNG H5 of the sovereign s-class video codec: the COLOR frame codec. Takes
2// an RGB frame -> YCbCr (H4) -> 4:2:0 (chroma at half resolution = half the chroma data) -> per-plane 4x4
3// integer transform + quantization (the proven WHT block codec) -> reconstruct -> upsample -> RGB. This is
4// the grayscale-demo's successor: real color, real compression, pure integer, built on the ALU/transform
5// hardware rungs. No float, no third-party. license_tier: ORIGINAL
6import "nx_vcodec_color.nx"
7
8// ---- 4x4 Walsh-Hadamard transform (out = H*X*H), integer, self-inverse up to /16 ----
9func wht4(X: *i64, tmp: *i64, out: *i64) -> i64 {
10 var c: i64=0
11 while c<4 { let a0: i64=X[c]; let a1: i64=X[4+c]; let a2: i64=X[8+c]; let a3: i64=X[12+c]; tmp[c]=a0+a1+a2+a3; tmp[4+c]=a0+a1-a2-a3; tmp[8+c]=a0-a1-a2+a3; tmp[12+c]=a0-a1+a2-a3; c=c+1 }
12 var r: i64=0
13 while r<4 { let b0: i64=tmp[r*4]; let b1: i64=tmp[r*4+1]; let b2: i64=tmp[r*4+2]; let b3: i64=tmp[r*4+3]; out[r*4]=b0+b1+b2+b3; out[r*4+1]=b0+b1-b2-b3; out[r*4+2]=b0-b1-b2+b3; out[r*4+3]=b0-b1+b2-b3; r=r+1 }
14 return 0
15}
16// transform a pixel block + quantize -> q[16]; returns nonzero coeff count (the compressed cost proxy)
17func enc_block(blk: *i64, tmp: *i64, T: *i64, q: *i64, QSTEP: i64) -> i64 {
18 wht4(blk, tmp, T)
19 var nz: i64=0; var i: i64=0
20 while i<16 { var v: i64=T[i]; var qq: i64=0; if v>=0 { qq=(v+QSTEP/2)/QSTEP } else { qq=0-((0-v+QSTEP/2)/QSTEP) } q[i]=qq; if qq!=0 {nz=nz+1} i=i+1 }
21 return nz
22}
23// dequantize + inverse transform -> reconstructed pixel block out[16]
24func dec_block(q: *i64, tmp: *i64, T: *i64, out: *i64, QSTEP: i64) -> i64 {
25 var i: i64=0; while i<16 { T[i]=q[i]*QSTEP; i=i+1 }
26 wht4(T, tmp, out)
27 i=0; while i<16 { out[i]=out[i]/16; i=i+1 }
28 return 0
29}
30// code a W x H plane (W,H multiples of 4) block-by-block: transform+quant+reconstruct into rec. returns nonzeros.
31func code_plane(plane: *u8, W: i64, H: i64, QSTEP: i64, rec: *u8) -> i64 {
32 let blk: *i64 = sys_mmap(8*16) as *i64; let q: *i64 = sys_mmap(8*16) as *i64
33 let tmp: *i64 = sys_mmap(8*16) as *i64; let T: *i64 = sys_mmap(8*16) as *i64; let rb: *i64 = sys_mmap(8*16) as *i64
34 var total_nz: i64=0
35 let BX: i64=W/4; let BY: i64=H/4
36 var by: i64=0
37 while by<BY {
38 var bx: i64=0
39 while bx<BX {
40 var i: i64=0; while i<4 { var j: i64=0; while j<4 { blk[i*4+j]=plane[(by*4+i)*W+(bx*4+j)] as i64; j=j+1 } i=i+1 }
41 total_nz = total_nz + enc_block(blk, tmp, T, q, QSTEP)
42 dec_block(q, tmp, T, rb, QSTEP)
43 i=0; while i<4 { var j: i64=0; while j<4 { var v: i64=rb[i*4+j]; if v<0{v=0} if v>255{v=255} rec[(by*4+i)*W+(bx*4+j)]=v as u8; j=j+1 } i=i+1 }
44 bx=bx+1
45 }
46 by=by+1
47 }
48 return total_nz
49}
50// 4:2:0 chroma subsample: out[(W/2)*(H/2)] = box-average of each 2x2 of plane[W*H]
51func subsample420(plane: *u8, W: i64, H: i64, out: *u8) -> i64 {
52 let Ws: i64=W/2; let Hs: i64=H/2
53 var y: i64=0
54 while y<Hs { var x: i64=0
55 while x<Ws {
56 let a: i64=plane[(2*y)*W+2*x] as i64; let b: i64=plane[(2*y)*W+2*x+1] as i64
57 let c: i64=plane[(2*y+1)*W+2*x] as i64; let d: i64=plane[(2*y+1)*W+2*x+1] as i64
58 out[y*Ws+x]=((a+b+c+d+2)/4) as u8; x=x+1 }
59 y=y+1 }
60 return 0
61}
62// upsample (replicate) chroma back to full resolution
63func upsample420(ps: *u8, Ws: i64, Hs: i64, out: *u8) -> i64 {
64 let W: i64=Ws*2
65 var y: i64=0
66 while y<Hs { var x: i64=0
67 while x<Ws {
68 let v: i64=ps[y*Ws+x] as u8 as i64
69 out[(2*y)*W+2*x]=v as u8; out[(2*y)*W+2*x+1]=v as u8; out[(2*y+1)*W+2*x]=v as u8; out[(2*y+1)*W+2*x+1]=v as u8
70 x=x+1 }
71 y=y+1 }
72 return 0
73}
74
75func main() -> i64 { return 0 }