nx_rangecoder_sig.nx source
↩ module page · 126 lines · 6125 B
1// nx_rangecoder_sig.nx -- SIGNIFICANCE-MAP coefficient coder with NEIGHBOR CONTEXT (R2a rung-1, the CABAC-
2// class technique nx_vcodec_entropy_gap MEASURED at -36.8% on the significance map). Replaces the run-length
3// coefficient syntax: code a coded-block-flag, then a raster significance map whose context is the count of
4// already-coded significant neighbors (left/up/up-left) plus a position band, then the levels of the
5// significant coefficients. Bit-exact by construction (enc + dec share the sigmap fill order + contexts).
6// Own context block (24 ctx, seed 2048): 0=CBF · 1..16=significance(posband x nbcount) · 17..21=level-length
7// · 22=level-magnitude · 23=sign. license_tier: ORIGINAL
8import "nx_rangecoder.nx" // rc_enc_ctx / rc_dec_ctx / the range coder state
9import "nx_ventropy.nx" // ve_blen (bit length)
10
11const RC_SIG_NCTX: i64 = 24
12
13// causal neighbor significance count for raster position p in an N-coeff block of row width wd, from sigmap.
14func rcs_nb(sigmap: *i64, p: i64, wd: i64) -> i64 {
15 var nb: i64 = 0
16 if (p % wd) != 0 { nb = nb + sigmap[p-1] } // left
17 if p >= wd { nb = nb + sigmap[p-wd] } // up
18 if p >= wd { if (p % wd) != 0 { nb = nb + sigmap[p-wd-1] } } // up-left
19 if nb > 3 { nb = 3 }
20 return nb
21}
22func rcs_sigctx(p: i64, n: i64, nb: i64) -> i64 {
23 var band: i64 = (p * 4) / n // 4 position bands 0..3
24 if band > 3 { band = 3 }
25 return 1 + band * 4 + nb // contexts 1..16
26}
27// code the level (magnitude>=1 + sign) at contexts 17..23: 5-bit length field + implicit-top-bit magnitude
28// + sign. (MEASURED beat a CABAC gt1/gt2/remainder variant by 0.4% on real coeffs -- the adaptive length
29// contexts already capture the small-level skew; keep the simpler scheme.)
30func rcs_enc_level(st: *i64, out: *u8, probs: *i64, val: i64) -> i64 {
31 var mag: i64 = val; var sgn: i64 = 0
32 if mag < 0 { mag = 0 - mag; sgn = 1 }
33 let nb: i64 = ve_blen(mag) // >=1 since mag>=1
34 var b: i64 = 4; while b >= 0 { rc_enc_ctx(st, out, probs, 17 + (4 - b), (nb >> b) & 1); b = b - 1 }
35 var m: i64 = nb - 2 // top bit is implicit 1; code the low nb-1 bits
36 while m >= 0 { rc_enc_ctx(st, out, probs, 22, (mag >> m) & 1); m = m - 1 }
37 rc_enc_ctx(st, out, probs, 23, sgn)
38 return 0
39}
40func rcs_dec_level(st: *i64, in_: *u8, probs: *i64) -> i64 {
41 var nb: i64 = 0; var b: i64 = 0
42 while b < 5 { nb = (nb << 1) | rc_dec_ctx(st, in_, probs, 17 + b); b = b + 1 }
43 var mag: i64 = 0
44 if nb >= 1 { mag = 1 << (nb - 1) } // implicit top bit
45 var m: i64 = nb - 2
46 while m >= 0 { mag = mag | (rc_dec_ctx(st, in_, probs, 22) << m); m = m - 1 }
47 let sgn: i64 = rc_dec_ctx(st, in_, probs, 23)
48 if sgn == 1 { return 0 - mag }
49 return mag
50}
51// ---- READ-ONLY COST MIRRORS (P3 real-bit RD, 2026-07-12): the Q8 cost of coding a block through the sig-map
52// syntax with the CURRENT adaptive contexts -- the exact bins rc_sig_encode would emit, costed via rc_bits_q8
53// without touching est/probs/rcbuf (x264-style static-state estimation, replacing the CAVLC ve_cost tables in
54// the per-MB transform RD). Allocation-free: significance reads coeffs directly (the sigmap is only a cache).
55func rcs_nb_c(coeffs: *i64, p: i64, wd: i64) -> i64 {
56 var nb: i64 = 0
57 if (p % wd) != 0 { if coeffs[p-1] != 0 { nb = nb + 1 } }
58 if p >= wd { if coeffs[p-wd] != 0 { nb = nb + 1 } }
59 if p >= wd { if (p % wd) != 0 { if coeffs[p-wd-1] != 0 { nb = nb + 1 } } }
60 if nb > 3 { nb = 3 }
61 return nb
62}
63func rcs_level_cost_q8(probs: *i64, val: i64) -> i64 {
64 var mag: i64 = val
65 var sgn: i64 = 0
66 if mag < 0 { mag = 0 - mag; sgn = 1 }
67 let nbl: i64 = ve_blen(mag)
68 var bits: i64 = 0
69 var b: i64 = 4
70 while b >= 0 { bits = bits + rc_bits_q8(probs[17 + (4 - b)], (nbl >> b) & 1); b = b - 1 }
71 var m: i64 = nbl - 2
72 while m >= 0 { bits = bits + rc_bits_q8(probs[22], (mag >> m) & 1); m = m - 1 }
73 return bits + rc_bits_q8(probs[23], sgn)
74}
75func rc_sig_cost_q8(coeffs: *i64, n: i64, wd: i64, probs: *i64) -> i64 {
76 var anynz: i64 = 0
77 var i: i64 = 0
78 while i < n { if coeffs[i] != 0 { anynz = 1 } i = i + 1 }
79 var bits: i64 = rc_bits_q8(probs[0], anynz)
80 if anynz == 0 { return bits }
81 var p: i64 = 0
82 while p < n {
83 var s: i64 = 0
84 if coeffs[p] != 0 { s = 1 }
85 bits = bits + rc_bits_q8(probs[rcs_sigctx(p, n, rcs_nb_c(coeffs, p, wd))], s)
86 p = p + 1
87 }
88 p = 0
89 while p < n { if coeffs[p] != 0 { bits = bits + rcs_level_cost_q8(probs, coeffs[p]) } p = p + 1 }
90 return bits
91}
92// encode an N-coeff block (row width wd) via the significance-map syntax. sigmap = i64[>=N] scratch.
93func rc_sig_encode(coeffs: *i64, n: i64, wd: i64, st: *i64, out: *u8, probs: *i64, sigmap: *i64) -> i64 {
94 var anynz: i64 = 0
95 var i: i64 = 0; while i < n { if coeffs[i] != 0 { anynz = 1 } sigmap[i] = 0; i = i + 1 }
96 rc_enc_ctx(st, out, probs, 0, anynz) // coded-block-flag
97 if anynz == 0 { return 0 }
98 var p: i64 = 0
99 while p < n {
100 let nb: i64 = rcs_nb(sigmap, p, wd)
101 var s: i64 = 0; if coeffs[p] != 0 { s = 1 }
102 rc_enc_ctx(st, out, probs, rcs_sigctx(p, n, nb), s)
103 sigmap[p] = s
104 p = p + 1
105 }
106 p = 0
107 while p < n { if coeffs[p] != 0 { rcs_enc_level(st, out, probs, coeffs[p]) } p = p + 1 }
108 return 0
109}
110func rc_sig_decode(coeffs: *i64, n: i64, wd: i64, st: *i64, in_: *u8, probs: *i64, sigmap: *i64) -> i64 {
111 var i: i64 = 0; while i < n { coeffs[i] = 0; sigmap[i] = 0; i = i + 1 }
112 let anynz: i64 = rc_dec_ctx(st, in_, probs, 0)
113 if anynz == 0 { return 0 }
114 var p: i64 = 0
115 while p < n {
116 let nb: i64 = rcs_nb(sigmap, p, wd)
117 let s: i64 = rc_dec_ctx(st, in_, probs, rcs_sigctx(p, n, nb))
118 sigmap[p] = s
119 p = p + 1
120 }
121 p = 0
122 while p < n { if sigmap[p] == 1 { coeffs[p] = rcs_dec_level(st, in_, probs) } p = p + 1 }
123 return 0
124}
125
126func main() -> i64 { return 0 }