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}