code wiki / (root) / nx_vcodec_color_frame.nx

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 }