code wiki / (root) / nx_h264_chroma_pred.nx

nx_h264_chroma_pred.nx source

↩ module page · 102 lines · 3624 B

1// nx_h264_chroma_pred.nx -- Intra chroma 8x8 prediction (4:2:0), spec 8.3.4. 2// mode 0 DC : per-quadrant (TL/TR/BL/BR) DC with the spec's availability fallbacks 3// mode 1 Horiz: pred[y][x] = left[y] 4// mode 2 Vert : pred[y][x] = top[x] 5// mode 3 Plane: 8x8 plane fit (multiplier 34), Clip1 to [0,255] 6// top[0..7]=p[x,-1], left[0..7]=p[-1,y], tl=p[-1,-1]. pred = 64 i64 raster. 7// 8// genealogy_id: itu_t_h264_sec8_3_4_intra_chroma 9// lineage_id: intra_chroma_dc_quadrant + plane8x8 10// license_tier: ORIGINAL 11import "nx_syscalls.nx" 12import "nx_h264_idct.nx" 13 14func sum4(a: *i64, off: i64) -> i64 { return a[off] + a[off+1] + a[off+2] + a[off+3] } 15 16// fill one 4x4 quadrant at (qx,qy) in {0,4} with constant dc. 17func fill_quad(pred: *i64, qx: i64, qy: i64, dc: i64) -> i64 { 18 var y: i64 = 0 19 while y < 4 { 20 var x: i64 = 0 21 while x < 4 { pred[(qy + y) * 8 + (qx + x)] = dc; x = x + 1 } 22 y = y + 1 23 } 24 return 0 25} 26 27func nx_intra_chroma_pred(mode: i64, top: *i64, left: *i64, tl: i64, avail_top: i64, avail_left: i64, pred: *i64) -> i64 { 28 if mode == 1 { 29 var y: i64 = 0 30 while y < 8 { var x: i64 = 0; while x < 8 { pred[y*8+x] = left[y]; x = x + 1 } y = y + 1 } 31 return 0 32 } 33 if mode == 2 { 34 var y: i64 = 0 35 while y < 8 { var x: i64 = 0; while x < 8 { pred[y*8+x] = top[x]; x = x + 1 } y = y + 1 } 36 return 0 37 } 38 if mode == 0 { 39 let st0: i64 = sum4(top, 0) 40 let st1: i64 = sum4(top, 4) 41 let sl0: i64 = sum4(left, 0) 42 let sl1: i64 = sum4(left, 4) 43 // TL quadrant 44 var dc: i64 = 128 45 if avail_top == 1 { if avail_left == 1 { dc = (st0 + sl0 + 4) >> 3 } } 46 if avail_top == 1 { if avail_left == 0 { dc = (st0 + 2) >> 2 } } 47 if avail_top == 0 { if avail_left == 1 { dc = (sl0 + 2) >> 2 } } 48 fill_quad(pred, 0, 0, dc) 49 // TR quadrant (prefers top) 50 dc = 128 51 if avail_top == 1 { dc = (st1 + 2) >> 2 } 52 if avail_top == 0 { if avail_left == 1 { dc = (sl0 + 2) >> 2 } } 53 fill_quad(pred, 4, 0, dc) 54 // BL quadrant (prefers left) 55 dc = 128 56 if avail_left == 1 { dc = (sl1 + 2) >> 2 } 57 if avail_left == 0 { if avail_top == 1 { dc = (st0 + 2) >> 2 } } 58 fill_quad(pred, 0, 4, dc) 59 // BR quadrant 60 dc = 128 61 if avail_top == 1 { if avail_left == 1 { dc = (st1 + sl1 + 4) >> 3 } } 62 if avail_top == 1 { if avail_left == 0 { dc = (st1 + 2) >> 2 } } 63 if avail_top == 0 { if avail_left == 1 { dc = (sl1 + 2) >> 2 } } 64 fill_quad(pred, 4, 4, dc) 65 return 0 66 } 67 if mode == 3 { 68 var H: i64 = 0 69 var xp: i64 = 0 70 while xp < 4 { 71 var t2: i64 = tl 72 if 2 - xp >= 0 { t2 = top[2 - xp] } 73 H = H + (xp + 1) * (top[4 + xp] - t2) 74 xp = xp + 1 75 } 76 var V: i64 = 0 77 var yp: i64 = 0 78 while yp < 4 { 79 var l2: i64 = tl 80 if 2 - yp >= 0 { l2 = left[2 - yp] } 81 V = V + (yp + 1) * (left[4 + yp] - l2) 82 yp = yp + 1 83 } 84 let a: i64 = 16 * (left[7] + top[7]) 85 let b: i64 = asr(34 * H + 32, 6) 86 let c: i64 = asr(34 * V + 32, 6) 87 var y: i64 = 0 88 while y < 8 { 89 var x: i64 = 0 90 while x < 8 { 91 var v: i64 = asr(a + b * (x - 3) + c * (y - 3) + 16, 5) 92 if v < 0 { v = 0 } 93 if v > 255 { v = 255 } 94 pred[y * 8 + x] = v 95 x = x + 1 96 } 97 y = y + 1 98 } 99 return 0 100 } 101 return 0 102}