code wiki / (root) / nx_rangecoder_sig.nx

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 }