code wiki / (root) / nx_vp8_pred.nx

nx_vp8_pred.nx source

↩ module page · 450 lines · 18144 B

1// nx_vp8_pred.nx -- Performs inverse DCT and intra prediction for VP8 keyframes in the Nishi sovereign ecosystem. 2// nx_vp8_pred.nx -- VP8 keyframe PIXEL half: inverse DCT/WHT, the 4 whole-block 3// and 10 subblock intra predictors, border fixups, and per-MB reconstruction. 4// 5// Ported against RFC 6386 reference decoder sections 20.8 (idct_add.c) and 6// 20.14 (predict.c) EXACTLY, including: 7// - THE BORDER IS REWRITTEN PER MACROBLOCK. Out-of-frame pixels are 127 8// (above) / 129 (left), but a DC_PRED macroblock on an edge instead 9// COPIES the available edge into the missing one, so the plain 2n-point 10// average degenerates to the spec's n-point edge-aware DC. The two 11// fixups deliberately clobber each other's work, so they re-run per MB. 12// - Every >>16 and >>3 on a possibly-negative value goes through the 13// floor-shift helpers below: NishiLang's >> semantics on negatives are 14// not assumed, they are made irrelevant by construction. 15// - All addressing is plane-base + i64 offset; no negative pointer values. 16// 17// genealogy_id: vp8_rfc6386 18// lineage_id: nx_vp8_pred_v1 19// license_tier: ORIGINAL 20 21import "nx_syscalls.nx" 22 23const NX_VP8P_C1: i64 = 20091 24const NX_VP8P_C2: i64 = 35468 25 26func vp8p_clamp(x: i64) -> i64 { if x < 0 { return 0 } if x > 255 { return 255 } return x } 27 28// floor shifts that are correct whether or not >> is arithmetic on negatives 29func vp8p_sr16(x: i64) -> i64 { 30 if x >= 0 { return x >> 16 } 31 return 0 - (((0 - x) + 65535) >> 16) 32} 33func vp8p_sr3(x: i64) -> i64 { 34 if x >= 0 { return x >> 3 } 35 return 0 - (((0 - x) + 7) >> 3) 36} 37 38func vp8p_px(pl: *u8, o: i64) -> i64 { return (pl[o] as i64) & 255 } 39 40// ===== inverse WHT (Y2 second order), RFC 20.8 vp8_dixie_walsh ==== 41 42func vp8p_walsh(inp: *i64, inb: i64, outp: *i64) -> i64 { 43 var i: i64 = 0 44 while i < 4 { 45 let a1: i64 = inp[inb+i] + inp[inb+12+i] 46 let b1: i64 = inp[inb+4+i] + inp[inb+8+i] 47 let c1: i64 = inp[inb+4+i] - inp[inb+8+i] 48 let d1: i64 = inp[inb+i] - inp[inb+12+i] 49 outp[i] = a1 + b1 50 outp[4+i] = c1 + d1 51 outp[8+i] = a1 - b1 52 outp[12+i] = d1 - c1 53 i = i + 1 54 } 55 i = 0 56 while i < 4 { 57 let a1: i64 = outp[i*4] + outp[i*4+3] 58 let b1: i64 = outp[i*4+1] + outp[i*4+2] 59 let c1: i64 = outp[i*4+1] - outp[i*4+2] 60 let d1: i64 = outp[i*4] - outp[i*4+3] 61 outp[i*4] = vp8p_sr3(a1 + b1 + 3) 62 outp[i*4+1] = vp8p_sr3(c1 + d1 + 3) 63 outp[i*4+2] = vp8p_sr3(a1 - b1 + 3) 64 outp[i*4+3] = vp8p_sr3(d1 - c1 + 3) 65 i = i + 1 66 } 67 return 0 68} 69 70// ===== inverse DCT + predictor add, RFC 20.8 vp8_dixie_idct_add === 71// recon==predict in place: reads the predicted pixel, adds the residue. 72// tmp is caller-provided scratch of 16 i64 (avoids an mmap per subblock). 73 74func vp8p_idct_add(pl: *u8, off: i64, stride: i64, cf: *i64, cfb: i64, tmp: *i64) -> i64 { 75 var i: i64 = 0 76 while i < 4 { 77 let a1: i64 = cf[cfb+i] + cf[cfb+8+i] 78 let b1: i64 = cf[cfb+i] - cf[cfb+8+i] 79 let c1: i64 = vp8p_sr16(cf[cfb+4+i] * NX_VP8P_C2) - (cf[cfb+12+i] + vp8p_sr16(cf[cfb+12+i] * NX_VP8P_C1)) 80 let d1: i64 = (cf[cfb+4+i] + vp8p_sr16(cf[cfb+4+i] * NX_VP8P_C1)) + vp8p_sr16(cf[cfb+12+i] * NX_VP8P_C2) 81 tmp[i] = a1 + d1 82 tmp[12+i] = a1 - d1 83 tmp[4+i] = b1 + c1 84 tmp[8+i] = b1 - c1 85 i = i + 1 86 } 87 i = 0 88 while i < 4 { 89 let a1: i64 = tmp[i*4] + tmp[i*4+2] 90 let b1: i64 = tmp[i*4] - tmp[i*4+2] 91 let c1: i64 = vp8p_sr16(tmp[i*4+1] * NX_VP8P_C2) - (tmp[i*4+3] + vp8p_sr16(tmp[i*4+3] * NX_VP8P_C1)) 92 let d1: i64 = (tmp[i*4+1] + vp8p_sr16(tmp[i*4+1] * NX_VP8P_C1)) + vp8p_sr16(tmp[i*4+3] * NX_VP8P_C2) 93 let ro: i64 = off + i*stride 94 pl[ro] = vp8p_clamp(vp8p_px(pl, ro) + vp8p_sr3(a1 + d1 + 4)) as u8 95 pl[ro+3] = vp8p_clamp(vp8p_px(pl, ro+3) + vp8p_sr3(a1 - d1 + 4)) as u8 96 pl[ro+1] = vp8p_clamp(vp8p_px(pl, ro+1) + vp8p_sr3(b1 + c1 + 4)) as u8 97 pl[ro+2] = vp8p_clamp(vp8p_px(pl, ro+2) + vp8p_sr3(b1 - c1 + 4)) as u8 98 i = i + 1 99 } 100 return 0 101} 102 103// ===== whole-block predictors (n = 4, 8, 16) ====================== 104 105func vp8p_pred_dc(pl: *u8, off: i64, stride: i64, n: i64) -> i64 { 106 var dc: i64 = 0 107 var i: i64 = 0 108 while i < n { 109 dc = dc + vp8p_px(pl, off - 1 + i*stride) + vp8p_px(pl, off - stride + i) 110 i = i + 1 111 } 112 if n == 16 { dc = (dc + 16) >> 5 } 113 if n == 8 { dc = (dc + 8) >> 4 } 114 if n == 4 { dc = (dc + 4) >> 3 } 115 var y: i64 = 0 116 while y < n { 117 var x: i64 = 0 118 while x < n { pl[off + y*stride + x] = dc as u8; x = x + 1 } 119 y = y + 1 120 } 121 return 0 122} 123 124func vp8p_pred_h(pl: *u8, off: i64, stride: i64, n: i64) -> i64 { 125 var y: i64 = 0 126 while y < n { 127 let v: i64 = vp8p_px(pl, off - 1 + y*stride) 128 var x: i64 = 0 129 while x < n { pl[off + y*stride + x] = v as u8; x = x + 1 } 130 y = y + 1 131 } 132 return 0 133} 134 135func vp8p_pred_v(pl: *u8, off: i64, stride: i64, n: i64) -> i64 { 136 var y: i64 = 0 137 while y < n { 138 var x: i64 = 0 139 while x < n { pl[off + y*stride + x] = pl[off - stride + x]; x = x + 1 } 140 y = y + 1 141 } 142 return 0 143} 144 145func vp8p_pred_tm(pl: *u8, off: i64, stride: i64, n: i64) -> i64 { 146 let p: i64 = vp8p_px(pl, off - stride - 1) 147 var y: i64 = 0 148 while y < n { 149 let l: i64 = vp8p_px(pl, off - 1 + y*stride) 150 var x: i64 = 0 151 while x < n { 152 pl[off + y*stride + x] = vp8p_clamp(l + vp8p_px(pl, off - stride + x) - p) as u8 153 x = x + 1 154 } 155 y = y + 1 156 } 157 return 0 158} 159 160// ===== 4x4 subblock predictors (RFC 20.14, ported line-for-line) == 161// A(k) = above row pixel k (k may be -1..7), L(r) = left column pixel r. 162 163func vp8p_a(pl: *u8, off: i64, stride: i64, k: i64) -> i64 { return vp8p_px(pl, off - stride + k) } 164func vp8p_l(pl: *u8, off: i64, stride: i64, r: i64) -> i64 { return vp8p_px(pl, off - 1 + r*stride) } 165 166func vp8p_pred_ve4(pl: *u8, off: i64, stride: i64) -> i64 { 167 let p0: i64 = (vp8p_a(pl,off,stride,0-1) + 2*vp8p_a(pl,off,stride,0) + vp8p_a(pl,off,stride,1) + 2) >> 2 168 let p1: i64 = (vp8p_a(pl,off,stride,0) + 2*vp8p_a(pl,off,stride,1) + vp8p_a(pl,off,stride,2) + 2) >> 2 169 let p2: i64 = (vp8p_a(pl,off,stride,1) + 2*vp8p_a(pl,off,stride,2) + vp8p_a(pl,off,stride,3) + 2) >> 2 170 let p3: i64 = (vp8p_a(pl,off,stride,2) + 2*vp8p_a(pl,off,stride,3) + vp8p_a(pl,off,stride,4) + 2) >> 2 171 var y: i64 = 0 172 while y < 4 { 173 pl[off+y*stride] = p0 as u8 174 pl[off+y*stride+1] = p1 as u8 175 pl[off+y*stride+2] = p2 as u8 176 pl[off+y*stride+3] = p3 as u8 177 y = y + 1 178 } 179 return 0 180} 181 182func vp8p_pred_he4(pl: *u8, off: i64, stride: i64) -> i64 { 183 let al: i64 = vp8p_px(pl, off - stride - 1) 184 let l0: i64 = vp8p_l(pl,off,stride,0) 185 let l1: i64 = vp8p_l(pl,off,stride,1) 186 let l2: i64 = vp8p_l(pl,off,stride,2) 187 let l3: i64 = vp8p_l(pl,off,stride,3) 188 let r0: i64 = (al + 2*l0 + l1 + 2) >> 2 189 let r1: i64 = (l0 + 2*l1 + l2 + 2) >> 2 190 let r2: i64 = (l1 + 2*l2 + l3 + 2) >> 2 191 let r3: i64 = (l2 + 2*l3 + l3 + 2) >> 2 192 var x: i64 = 0 193 while x < 4 { 194 pl[off+x] = r0 as u8 195 pl[off+stride+x] = r1 as u8 196 pl[off+2*stride+x] = r2 as u8 197 pl[off+3*stride+x] = r3 as u8 198 x = x + 1 199 } 200 return 0 201} 202 203func vp8p_pred_ld4(pl: *u8, off: i64, stride: i64) -> i64 { 204 let a0: i64 = vp8p_a(pl,off,stride,0) 205 let a1: i64 = vp8p_a(pl,off,stride,1) 206 let a2: i64 = vp8p_a(pl,off,stride,2) 207 let a3: i64 = vp8p_a(pl,off,stride,3) 208 let a4: i64 = vp8p_a(pl,off,stride,4) 209 let a5: i64 = vp8p_a(pl,off,stride,5) 210 let a6: i64 = vp8p_a(pl,off,stride,6) 211 let a7: i64 = vp8p_a(pl,off,stride,7) 212 let p0: i64 = (a0 + 2*a1 + a2 + 2) >> 2 213 let p1: i64 = (a1 + 2*a2 + a3 + 2) >> 2 214 let p2: i64 = (a2 + 2*a3 + a4 + 2) >> 2 215 let p3: i64 = (a3 + 2*a4 + a5 + 2) >> 2 216 let p4: i64 = (a4 + 2*a5 + a6 + 2) >> 2 217 let p5: i64 = (a5 + 2*a6 + a7 + 2) >> 2 218 let p6: i64 = (a6 + 2*a7 + a7 + 2) >> 2 219 pl[off]=p0 as u8; pl[off+1]=p1 as u8; pl[off+2]=p2 as u8; pl[off+3]=p3 as u8 220 pl[off+stride]=p1 as u8; pl[off+stride+1]=p2 as u8; pl[off+stride+2]=p3 as u8; pl[off+stride+3]=p4 as u8 221 pl[off+2*stride]=p2 as u8; pl[off+2*stride+1]=p3 as u8; pl[off+2*stride+2]=p4 as u8; pl[off+2*stride+3]=p5 as u8 222 pl[off+3*stride]=p3 as u8; pl[off+3*stride+1]=p4 as u8; pl[off+3*stride+2]=p5 as u8; pl[off+3*stride+3]=p6 as u8 223 return 0 224} 225 226func vp8p_pred_rd4(pl: *u8, off: i64, stride: i64) -> i64 { 227 let al: i64 = vp8p_px(pl, off - stride - 1) 228 let a0: i64 = vp8p_a(pl,off,stride,0) 229 let a1: i64 = vp8p_a(pl,off,stride,1) 230 let a2: i64 = vp8p_a(pl,off,stride,2) 231 let a3: i64 = vp8p_a(pl,off,stride,3) 232 let l0: i64 = vp8p_l(pl,off,stride,0) 233 let l1: i64 = vp8p_l(pl,off,stride,1) 234 let l2: i64 = vp8p_l(pl,off,stride,2) 235 let l3: i64 = vp8p_l(pl,off,stride,3) 236 let p0: i64 = (l0 + 2*al + a0 + 2) >> 2 237 let p1: i64 = (al + 2*a0 + a1 + 2) >> 2 238 let p2: i64 = (a0 + 2*a1 + a2 + 2) >> 2 239 let p3: i64 = (a1 + 2*a2 + a3 + 2) >> 2 240 let p4: i64 = (l1 + 2*l0 + al + 2) >> 2 241 let p5: i64 = (l2 + 2*l1 + l0 + 2) >> 2 242 let p6: i64 = (l3 + 2*l2 + l1 + 2) >> 2 243 pl[off]=p0 as u8; pl[off+1]=p1 as u8; pl[off+2]=p2 as u8; pl[off+3]=p3 as u8 244 pl[off+stride]=p4 as u8; pl[off+stride+1]=p0 as u8; pl[off+stride+2]=p1 as u8; pl[off+stride+3]=p2 as u8 245 pl[off+2*stride]=p5 as u8; pl[off+2*stride+1]=p4 as u8; pl[off+2*stride+2]=p0 as u8; pl[off+2*stride+3]=p1 as u8 246 pl[off+3*stride]=p6 as u8; pl[off+3*stride+1]=p5 as u8; pl[off+3*stride+2]=p4 as u8; pl[off+3*stride+3]=p0 as u8 247 return 0 248} 249 250func vp8p_pred_vr4(pl: *u8, off: i64, stride: i64) -> i64 { 251 let al: i64 = vp8p_px(pl, off - stride - 1) 252 let a0: i64 = vp8p_a(pl,off,stride,0) 253 let a1: i64 = vp8p_a(pl,off,stride,1) 254 let a2: i64 = vp8p_a(pl,off,stride,2) 255 let a3: i64 = vp8p_a(pl,off,stride,3) 256 let l0: i64 = vp8p_l(pl,off,stride,0) 257 let l1: i64 = vp8p_l(pl,off,stride,1) 258 let l2: i64 = vp8p_l(pl,off,stride,2) 259 let p0: i64 = (al + a0 + 1) >> 1 260 let p1: i64 = (a0 + a1 + 1) >> 1 261 let p2: i64 = (a1 + a2 + 1) >> 1 262 let p3: i64 = (a2 + a3 + 1) >> 1 263 let p4: i64 = (l0 + 2*al + a0 + 2) >> 2 264 let p5: i64 = (al + 2*a0 + a1 + 2) >> 2 265 let p6: i64 = (a0 + 2*a1 + a2 + 2) >> 2 266 let p7: i64 = (a1 + 2*a2 + a3 + 2) >> 2 267 let p8: i64 = (l1 + 2*l0 + al + 2) >> 2 268 let p9: i64 = (l2 + 2*l1 + l0 + 2) >> 2 269 pl[off]=p0 as u8; pl[off+1]=p1 as u8; pl[off+2]=p2 as u8; pl[off+3]=p3 as u8 270 pl[off+stride]=p4 as u8; pl[off+stride+1]=p5 as u8; pl[off+stride+2]=p6 as u8; pl[off+stride+3]=p7 as u8 271 pl[off+2*stride]=p8 as u8; pl[off+2*stride+1]=p0 as u8; pl[off+2*stride+2]=p1 as u8; pl[off+2*stride+3]=p2 as u8 272 pl[off+3*stride]=p9 as u8; pl[off+3*stride+1]=p4 as u8; pl[off+3*stride+2]=p5 as u8; pl[off+3*stride+3]=p6 as u8 273 return 0 274} 275 276func vp8p_pred_vl4(pl: *u8, off: i64, stride: i64) -> i64 { 277 let a0: i64 = vp8p_a(pl,off,stride,0) 278 let a1: i64 = vp8p_a(pl,off,stride,1) 279 let a2: i64 = vp8p_a(pl,off,stride,2) 280 let a3: i64 = vp8p_a(pl,off,stride,3) 281 let a4: i64 = vp8p_a(pl,off,stride,4) 282 let a5: i64 = vp8p_a(pl,off,stride,5) 283 let a6: i64 = vp8p_a(pl,off,stride,6) 284 let a7: i64 = vp8p_a(pl,off,stride,7) 285 let p0: i64 = (a0 + a1 + 1) >> 1 286 let p1: i64 = (a1 + a2 + 1) >> 1 287 let p2: i64 = (a2 + a3 + 1) >> 1 288 let p3: i64 = (a3 + a4 + 1) >> 1 289 let p4: i64 = (a0 + 2*a1 + a2 + 2) >> 2 290 let p5: i64 = (a1 + 2*a2 + a3 + 2) >> 2 291 let p6: i64 = (a2 + 2*a3 + a4 + 2) >> 2 292 let p7: i64 = (a3 + 2*a4 + a5 + 2) >> 2 293 let p8: i64 = (a4 + 2*a5 + a6 + 2) >> 2 294 let p9: i64 = (a5 + 2*a6 + a7 + 2) >> 2 295 pl[off]=p0 as u8; pl[off+1]=p1 as u8; pl[off+2]=p2 as u8; pl[off+3]=p3 as u8 296 pl[off+stride]=p4 as u8; pl[off+stride+1]=p5 as u8; pl[off+stride+2]=p6 as u8; pl[off+stride+3]=p7 as u8 297 pl[off+2*stride]=p1 as u8; pl[off+2*stride+1]=p2 as u8; pl[off+2*stride+2]=p3 as u8; pl[off+2*stride+3]=p8 as u8 298 pl[off+3*stride]=p5 as u8; pl[off+3*stride+1]=p6 as u8; pl[off+3*stride+2]=p7 as u8; pl[off+3*stride+3]=p9 as u8 299 return 0 300} 301 302func vp8p_pred_hd4(pl: *u8, off: i64, stride: i64) -> i64 { 303 let al: i64 = vp8p_px(pl, off - stride - 1) 304 let a0: i64 = vp8p_a(pl,off,stride,0) 305 let a1: i64 = vp8p_a(pl,off,stride,1) 306 let a2: i64 = vp8p_a(pl,off,stride,2) 307 let l0: i64 = vp8p_l(pl,off,stride,0) 308 let l1: i64 = vp8p_l(pl,off,stride,1) 309 let l2: i64 = vp8p_l(pl,off,stride,2) 310 let l3: i64 = vp8p_l(pl,off,stride,3) 311 let p0: i64 = (l0 + al + 1) >> 1 312 let p1: i64 = (l0 + 2*al + a0 + 2) >> 2 313 let p2: i64 = (al + 2*a0 + a1 + 2) >> 2 314 let p3: i64 = (a0 + 2*a1 + a2 + 2) >> 2 315 let p4: i64 = (l1 + l0 + 1) >> 1 316 let p5: i64 = (l1 + 2*l0 + al + 2) >> 2 317 let p6: i64 = (l2 + l1 + 1) >> 1 318 let p7: i64 = (l2 + 2*l1 + l0 + 2) >> 2 319 let p8: i64 = (l3 + l2 + 1) >> 1 320 let p9: i64 = (l3 + 2*l2 + l1 + 2) >> 2 321 pl[off]=p0 as u8; pl[off+1]=p1 as u8; pl[off+2]=p2 as u8; pl[off+3]=p3 as u8 322 pl[off+stride]=p4 as u8; pl[off+stride+1]=p5 as u8; pl[off+stride+2]=p0 as u8; pl[off+stride+3]=p1 as u8 323 pl[off+2*stride]=p6 as u8; pl[off+2*stride+1]=p7 as u8; pl[off+2*stride+2]=p4 as u8; pl[off+2*stride+3]=p5 as u8 324 pl[off+3*stride]=p8 as u8; pl[off+3*stride+1]=p9 as u8; pl[off+3*stride+2]=p6 as u8; pl[off+3*stride+3]=p7 as u8 325 return 0 326} 327 328func vp8p_pred_hu4(pl: *u8, off: i64, stride: i64) -> i64 { 329 let l0: i64 = vp8p_l(pl,off,stride,0) 330 let l1: i64 = vp8p_l(pl,off,stride,1) 331 let l2: i64 = vp8p_l(pl,off,stride,2) 332 let l3: i64 = vp8p_l(pl,off,stride,3) 333 let p0: i64 = (l0 + l1 + 1) >> 1 334 let p1: i64 = (l0 + 2*l1 + l2 + 2) >> 2 335 let p2: i64 = (l1 + l2 + 1) >> 1 336 let p3: i64 = (l1 + 2*l2 + l3 + 2) >> 2 337 let p4: i64 = (l2 + l3 + 1) >> 1 338 let p5: i64 = (l2 + 2*l3 + l3 + 2) >> 2 339 let p6: i64 = l3 340 pl[off]=p0 as u8; pl[off+1]=p1 as u8; pl[off+2]=p2 as u8; pl[off+3]=p3 as u8 341 pl[off+stride]=p2 as u8; pl[off+stride+1]=p3 as u8; pl[off+stride+2]=p4 as u8; pl[off+stride+3]=p5 as u8 342 pl[off+2*stride]=p4 as u8; pl[off+2*stride+1]=p5 as u8; pl[off+2*stride+2]=p6 as u8; pl[off+2*stride+3]=p6 as u8 343 pl[off+3*stride]=p6 as u8; pl[off+3*stride+1]=p6 as u8; pl[off+3*stride+2]=p6 as u8; pl[off+3*stride+3]=p6 as u8 344 return 0 345} 346 347// ===== border fixups (RFC 20.14 fixup_left / fixup_above) ========= 348 349func vp8p_fixup_left(pl: *u8, off: i64, width: i64, stride: i64, row: i64, mode: i64) -> i64 { 350 if mode == 0 { if row != 0 { 351 var i: i64 = 0 352 while i < width { pl[off - 1 + i*stride] = pl[off - stride + i]; i = i + 1 } 353 return 0 354 } } 355 var i: i64 = 0 - 1 356 while i < width { pl[off - 1 + i*stride] = 129 as u8; i = i + 1 } 357 return 0 358} 359 360func vp8p_fixup_above(pl: *u8, off: i64, width: i64, stride: i64, col: i64, mode: i64) -> i64 { 361 var done: i64 = 0 362 if mode == 0 { if col != 0 { 363 var i: i64 = 0 364 while i < width { pl[off - stride + i] = pl[off - 1 + i*stride]; i = i + 1 } 365 done = 1 366 } } 367 if done == 0 { 368 var i: i64 = 0 - 1 369 while i < width { pl[off - stride + i] = 127 as u8; i = i + 1 } 370 } 371 var k: i64 = 0 372 while k < 4 { pl[off - stride + width + k] = 127 as u8; k = k + 1 } 373 return 0 374} 375 376// copy the 4 above-right pixels of subblock 3 down for subblocks 7/11/15 377func vp8p_copy_down(pl: *u8, off: i64, stride: i64) -> i64 { 378 var k: i64 = 0 379 while k < 4 { 380 let v: u8 = pl[off - stride + 16 + k] 381 pl[off + 3*stride + 16 + k] = v 382 pl[off + 7*stride + 16 + k] = v 383 pl[off + 11*stride + 16 + k] = v 384 k = k + 1 385 } 386 return 0 387} 388 389// ===== per-MB reconstruction ====================================== 390// bmodes: 16 subblock modes (only used when ymode==4/B_PRED) 391// cf: this MB's 25*16 coefficients; tmp: 16-i64 idct scratch 392 393func vp8p_bpred_dispatch(pl: *u8, off: i64, stride: i64, m: i64) -> i64 { 394 if m == 0 { return vp8p_pred_dc(pl, off, stride, 4) } 395 if m == 1 { return vp8p_pred_tm(pl, off, stride, 4) } 396 if m == 2 { return vp8p_pred_ve4(pl, off, stride) } 397 if m == 3 { return vp8p_pred_he4(pl, off, stride) } 398 if m == 4 { return vp8p_pred_ld4(pl, off, stride) } 399 if m == 5 { return vp8p_pred_rd4(pl, off, stride) } 400 if m == 6 { return vp8p_pred_vr4(pl, off, stride) } 401 if m == 7 { return vp8p_pred_vl4(pl, off, stride) } 402 if m == 8 { return vp8p_pred_hd4(pl, off, stride) } 403 return vp8p_pred_hu4(pl, off, stride) 404} 405 406func vp8p_mode_dispatch(pl: *u8, off: i64, stride: i64, m: i64, n: i64) -> i64 { 407 if m == 0 { return vp8p_pred_dc(pl, off, stride, n) } 408 if m == 1 { return vp8p_pred_v(pl, off, stride, n) } 409 if m == 2 { return vp8p_pred_h(pl, off, stride, n) } 410 return vp8p_pred_tm(pl, off, stride, n) 411} 412 413func vp8p_recon_luma(pl: *u8, off: i64, stride: i64, ymode: i64, bmodes: *u8, 414 cf: *i64, tmp: *i64) -> i64 { 415 if ymode == 4 { 416 vp8p_copy_down(pl, off, stride) 417 var i: i64 = 0 418 while i < 16 { 419 let bo: i64 = off + (i>>2)*4*stride + (i&3)*4 420 vp8p_bpred_dispatch(pl, bo, stride, (bmodes[i] as i64) & 255) 421 vp8p_idct_add(pl, bo, stride, cf, i*16, tmp) 422 i = i + 1 423 } 424 return 0 425 } 426 vp8p_mode_dispatch(pl, off, stride, ymode, 16) 427 var i: i64 = 0 428 while i < 16 { 429 vp8p_idct_add(pl, off + (i>>2)*4*stride + (i&3)*4, stride, cf, i*16, tmp) 430 i = i + 1 431 } 432 return 0 433} 434 435func vp8p_recon_chroma(pu: *u8, uoff: i64, pv: *u8, voff: i64, stride: i64, 436 uvmode: i64, cf: *i64, tmp: *i64) -> i64 { 437 vp8p_mode_dispatch(pu, uoff, stride, uvmode, 8) 438 vp8p_mode_dispatch(pv, voff, stride, uvmode, 8) 439 var k: i64 = 0 440 while k < 4 { 441 vp8p_idct_add(pu, uoff + (k>>1)*4*stride + (k&1)*4, stride, cf, (16+k)*16, tmp) 442 k = k + 1 443 } 444 k = 0 445 while k < 4 { 446 vp8p_idct_add(pv, voff + (k>>1)*4*stride + (k&1)*4, stride, cf, (20+k)*16, tmp) 447 k = k + 1 448 } 449 return 0 450}