code wiki / (root) / nx_h264_hadamard.nx

nx_h264_hadamard.nx source

↩ module page · 44 lines · 1528 B

1// nx_h264_hadamard.nx -- 4x4 inverse Hadamard for the Intra_16x16 luma DC block 2// (spec 8.5.10). The 16 luma DC coefficients are Hadamard-transformed (then 3// scaled by the caller) before becoming the DC term of each 4x4 sub-block. 4// H = [[1,1,1,1],[1,1,-1,-1],[1,-1,-1,1],[1,-1,1,-1]] (symmetric); f = H c H. 5// 1D butterfly: s0=c0+c1 s1=c0-c1 s2=c2+c3 s3=c2-c3; 6// y0=s0+s2 y1=s0-s2 y2=s1-s3 y3=s1+s3. Pure i64, no shifts. 7// 8// genealogy_id: itu_t_h264_sec8_5_10_luma_dc_hadamard 9// lineage_id: hadamard_4x4_2pass_butterfly 10// license_tier: ORIGINAL 11import "nx_syscalls.nx" 12 13// 1D inverse Hadamard of 4 values -> y 14func had1d(c0: i64, c1: i64, c2: i64, c3: i64, y: *i64) -> i64 { 15 let s0: i64 = c0 + c1 16 let s1: i64 = c0 - c1 17 let s2: i64 = c2 + c3 18 let s3: i64 = c2 - c3 19 y[0] = s0 + s2 20 y[1] = s0 - s2 21 y[2] = s1 - s3 22 y[3] = s1 + s3 23 return 0 24} 25 26// in-place 4x4 inverse Hadamard (row-major d[16]) 27func nx_h264_hadamard4x4(d: *i64) -> i64 { 28 let y: *i64 = sys_mmap(8 * 8) as *i64 29 // rows 30 var i: i64 = 0 31 while i < 4 { 32 had1d(d[i * 4 + 0], d[i * 4 + 1], d[i * 4 + 2], d[i * 4 + 3], y) 33 d[i * 4 + 0] = y[0]; d[i * 4 + 1] = y[1]; d[i * 4 + 2] = y[2]; d[i * 4 + 3] = y[3] 34 i = i + 1 35 } 36 // columns 37 var j: i64 = 0 38 while j < 4 { 39 had1d(d[0 * 4 + j], d[1 * 4 + j], d[2 * 4 + j], d[3 * 4 + j], y) 40 d[0 * 4 + j] = y[0]; d[1 * 4 + j] = y[1]; d[2 * 4 + j] = y[2]; d[3 * 4 + j] = y[3] 41 j = j + 1 42 } 43 return 0 44}