code wiki / (root) / nx_intra.nx

nx_intra.nx source

↩ module page · 43 lines · 2566 B

1// nx_intra.nx -- sovereign INTRA PREDICTION (V-R7, the q/bit gap-closer). Instead of coding raw pixels-128, an 2// intra block is predicted from its already-reconstructed neighbours (the row above, the column to the left) and 3// only the small RESIDUAL is transform-coded -> far fewer bits at the same quality. This is the H.264/VP9 intra 4// technique; we ship the 3 highest-value modes and pick the cheapest per block. 4x4 blocks, 8bpp. license_tier: ORIGINAL 5 6const IN_DC: i64 = 0 7const IN_VERT: i64 = 1 // copy the top row down (good for vertical structure) 8const IN_HORIZ: i64 = 2 // copy the left column across (good for horizontal structure) 9 10// fill a 4x4 predictor for `mode`. top[4] = reconstructed pixels above; left[4] = to the left. 11func in_predict(mode: i64, top: *i64, left: *i64, has_top: i64, has_left: i64, pred: *i64) -> i64 { 12 if mode == IN_VERT { var y: i64=0; while y<4 { var x: i64=0; while x<4 { pred[y*4+x] = top[x]; x=x+1 } y=y+1 } return 0 } 13 if mode == IN_HORIZ { var y: i64=0; while y<4 { var x: i64=0; while x<4 { pred[y*4+x] = left[y]; x=x+1 } y=y+1 } return 0 } 14 var sum: i64 = 0; var cnt: i64 = 0 15 if has_top == 1 { var x: i64=0; while x<4 { sum = sum + top[x]; cnt = cnt + 1; x=x+1 } } 16 if has_left == 1 { var y: i64=0; while y<4 { sum = sum + left[y]; cnt = cnt + 1; y=y+1 } } 17 var dc: i64 = 128 18 if cnt > 0 { dc = sum / cnt } 19 var i: i64 = 0; while i < 16 { pred[i] = dc; i = i + 1 } 20 return 0 21} 22// SAD of a 4x4 block vs a predictor (the residual energy = a bits proxy) 23func in_sad(block: *i64, pred: *i64) -> i64 { 24 var s: i64 = 0; var i: i64 = 0 25 while i < 16 { let d: i64 = block[i] - pred[i]; if d < 0 { s = s - d } else { s = s + d } i = i + 1 } 26 return s 27} 28// pick the cheapest mode (min residual SAD); leaves the chosen predictor in `pred`; returns the mode. 29func in_best(block: *i64, top: *i64, left: *i64, has_top: i64, has_left: i64, pred: *i64) -> i64 { 30 var best_mode: i64 = IN_DC 31 in_predict(IN_DC, top, left, has_top, has_left, pred) 32 var best: i64 = in_sad(block, pred) 33 if has_top == 1 { 34 in_predict(IN_VERT, top, left, has_top, has_left, pred) 35 let s: i64 = in_sad(block, pred); if s < best { best = s; best_mode = IN_VERT } 36 } 37 if has_left == 1 { 38 in_predict(IN_HORIZ, top, left, has_top, has_left, pred) 39 let s: i64 = in_sad(block, pred); if s < best { best = s; best_mode = IN_HORIZ } 40 } 41 in_predict(best_mode, top, left, has_top, has_left, pred) // leave the winning predictor in pred 42 return best_mode 43}