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}