Line data Source code
1 : /*
2 : * Copyright (c) 2015 The WebM project authors. All Rights Reserved.
3 : *
4 : * Use of this source code is governed by a BSD-style license
5 : * that can be found in the LICENSE file in the root of the source
6 : * tree. An additional intellectual property rights grant can be found
7 : * in the file PATENTS. All contributing project authors may
8 : * be found in the AUTHORS file in the root of the source tree.
9 : */
10 :
11 : #include "./vpx_config.h"
12 : #include "./vpx_dsp_rtcd.h"
13 :
14 : #include "vpx_dsp/vpx_dsp_common.h"
15 : #include "vpx_mem/vpx_mem.h"
16 :
17 : #define DST(x, y) dst[(x) + (y)*stride]
18 : #define AVG3(a, b, c) (((a) + 2 * (b) + (c) + 2) >> 2)
19 : #define AVG2(a, b) (((a) + (b) + 1) >> 1)
20 :
21 0 : static INLINE void d207_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
22 : const uint8_t *above, const uint8_t *left) {
23 : int r, c;
24 : (void)above;
25 : // first column
26 0 : for (r = 0; r < bs - 1; ++r) dst[r * stride] = AVG2(left[r], left[r + 1]);
27 0 : dst[(bs - 1) * stride] = left[bs - 1];
28 0 : dst++;
29 :
30 : // second column
31 0 : for (r = 0; r < bs - 2; ++r)
32 0 : dst[r * stride] = AVG3(left[r], left[r + 1], left[r + 2]);
33 0 : dst[(bs - 2) * stride] = AVG3(left[bs - 2], left[bs - 1], left[bs - 1]);
34 0 : dst[(bs - 1) * stride] = left[bs - 1];
35 0 : dst++;
36 :
37 : // rest of last row
38 0 : for (c = 0; c < bs - 2; ++c) dst[(bs - 1) * stride + c] = left[bs - 1];
39 :
40 0 : for (r = bs - 2; r >= 0; --r)
41 0 : for (c = 0; c < bs - 2; ++c)
42 0 : dst[r * stride + c] = dst[(r + 1) * stride + c - 2];
43 0 : }
44 :
45 : #if CONFIG_MISC_FIXES
46 : static INLINE void d207e_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
47 : const uint8_t *above, const uint8_t *left) {
48 : int r, c;
49 : (void)above;
50 :
51 : for (r = 0; r < bs; ++r) {
52 : for (c = 0; c < bs; ++c) {
53 : dst[c] = c & 1 ? AVG3(left[(c >> 1) + r], left[(c >> 1) + r + 1],
54 : left[(c >> 1) + r + 2])
55 : : AVG2(left[(c >> 1) + r], left[(c >> 1) + r + 1]);
56 : }
57 : dst += stride;
58 : }
59 : }
60 : #endif // CONFIG_MISC_FIXES
61 :
62 0 : static INLINE void d63_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
63 : const uint8_t *above, const uint8_t *left) {
64 : int r, c;
65 : int size;
66 : (void)left;
67 0 : for (c = 0; c < bs; ++c) {
68 0 : dst[c] = AVG2(above[c], above[c + 1]);
69 0 : dst[stride + c] = AVG3(above[c], above[c + 1], above[c + 2]);
70 : }
71 0 : for (r = 2, size = bs - 2; r < bs; r += 2, --size) {
72 0 : memcpy(dst + (r + 0) * stride, dst + (r >> 1), size);
73 0 : memset(dst + (r + 0) * stride + size, above[bs - 1], bs - size);
74 0 : memcpy(dst + (r + 1) * stride, dst + stride + (r >> 1), size);
75 0 : memset(dst + (r + 1) * stride + size, above[bs - 1], bs - size);
76 : }
77 0 : }
78 :
79 : #if CONFIG_MISC_FIXES
80 : static INLINE void d63e_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
81 : const uint8_t *above, const uint8_t *left) {
82 : int r, c;
83 : (void)left;
84 : for (r = 0; r < bs; ++r) {
85 : for (c = 0; c < bs; ++c) {
86 : dst[c] = r & 1 ? AVG3(above[(r >> 1) + c], above[(r >> 1) + c + 1],
87 : above[(r >> 1) + c + 2])
88 : : AVG2(above[(r >> 1) + c], above[(r >> 1) + c + 1]);
89 : }
90 : dst += stride;
91 : }
92 : }
93 : #endif // CONFIG_MISC_FIXES
94 :
95 0 : static INLINE void d45_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
96 : const uint8_t *above, const uint8_t *left) {
97 0 : const uint8_t above_right = above[bs - 1];
98 0 : const uint8_t *const dst_row0 = dst;
99 : int x, size;
100 : (void)left;
101 :
102 0 : for (x = 0; x < bs - 1; ++x) {
103 0 : dst[x] = AVG3(above[x], above[x + 1], above[x + 2]);
104 : }
105 0 : dst[bs - 1] = above_right;
106 0 : dst += stride;
107 0 : for (x = 1, size = bs - 2; x < bs; ++x, --size) {
108 0 : memcpy(dst, dst_row0 + x, size);
109 0 : memset(dst + size, above_right, x + 1);
110 0 : dst += stride;
111 : }
112 0 : }
113 :
114 : #if CONFIG_MISC_FIXES
115 : static INLINE void d45e_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
116 : const uint8_t *above, const uint8_t *left) {
117 : int r, c;
118 : (void)left;
119 : for (r = 0; r < bs; ++r) {
120 : for (c = 0; c < bs; ++c) {
121 : dst[c] = AVG3(above[r + c], above[r + c + 1],
122 : above[r + c + 1 + (r + c + 2 < bs * 2)]);
123 : }
124 : dst += stride;
125 : }
126 : }
127 : #endif // CONFIG_MISC_FIXES
128 :
129 0 : static INLINE void d117_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
130 : const uint8_t *above, const uint8_t *left) {
131 : int r, c;
132 :
133 : // first row
134 0 : for (c = 0; c < bs; c++) dst[c] = AVG2(above[c - 1], above[c]);
135 0 : dst += stride;
136 :
137 : // second row
138 0 : dst[0] = AVG3(left[0], above[-1], above[0]);
139 0 : for (c = 1; c < bs; c++) dst[c] = AVG3(above[c - 2], above[c - 1], above[c]);
140 0 : dst += stride;
141 :
142 : // the rest of first col
143 0 : dst[0] = AVG3(above[-1], left[0], left[1]);
144 0 : for (r = 3; r < bs; ++r)
145 0 : dst[(r - 2) * stride] = AVG3(left[r - 3], left[r - 2], left[r - 1]);
146 :
147 : // the rest of the block
148 0 : for (r = 2; r < bs; ++r) {
149 0 : for (c = 1; c < bs; c++) dst[c] = dst[-2 * stride + c - 1];
150 0 : dst += stride;
151 : }
152 0 : }
153 :
154 0 : static INLINE void d135_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
155 : const uint8_t *above, const uint8_t *left) {
156 : int i;
157 : #if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ > 7
158 : // silence a spurious -Warray-bounds warning, possibly related to:
159 : // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56273
160 : uint8_t border[69];
161 : #else
162 : uint8_t border[32 + 32 - 1]; // outer border from bottom-left to top-right
163 : #endif
164 :
165 : // dst(bs, bs - 2)[0], i.e., border starting at bottom-left
166 0 : for (i = 0; i < bs - 2; ++i) {
167 0 : border[i] = AVG3(left[bs - 3 - i], left[bs - 2 - i], left[bs - 1 - i]);
168 : }
169 0 : border[bs - 2] = AVG3(above[-1], left[0], left[1]);
170 0 : border[bs - 1] = AVG3(left[0], above[-1], above[0]);
171 0 : border[bs - 0] = AVG3(above[-1], above[0], above[1]);
172 : // dst[0][2, size), i.e., remaining top border ascending
173 0 : for (i = 0; i < bs - 2; ++i) {
174 0 : border[bs + 1 + i] = AVG3(above[i], above[i + 1], above[i + 2]);
175 : }
176 :
177 0 : for (i = 0; i < bs; ++i) {
178 0 : memcpy(dst + i * stride, border + bs - 1 - i, bs);
179 : }
180 0 : }
181 :
182 0 : static INLINE void d153_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
183 : const uint8_t *above, const uint8_t *left) {
184 : int r, c;
185 0 : dst[0] = AVG2(above[-1], left[0]);
186 0 : for (r = 1; r < bs; r++) dst[r * stride] = AVG2(left[r - 1], left[r]);
187 0 : dst++;
188 :
189 0 : dst[0] = AVG3(left[0], above[-1], above[0]);
190 0 : dst[stride] = AVG3(above[-1], left[0], left[1]);
191 0 : for (r = 2; r < bs; r++)
192 0 : dst[r * stride] = AVG3(left[r - 2], left[r - 1], left[r]);
193 0 : dst++;
194 :
195 0 : for (c = 0; c < bs - 2; c++)
196 0 : dst[c] = AVG3(above[c - 1], above[c], above[c + 1]);
197 0 : dst += stride;
198 :
199 0 : for (r = 1; r < bs; ++r) {
200 0 : for (c = 0; c < bs - 2; c++) dst[c] = dst[-stride + c - 2];
201 0 : dst += stride;
202 : }
203 0 : }
204 :
205 0 : static INLINE void v_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
206 : const uint8_t *above, const uint8_t *left) {
207 : int r;
208 : (void)left;
209 :
210 0 : for (r = 0; r < bs; r++) {
211 0 : memcpy(dst, above, bs);
212 0 : dst += stride;
213 : }
214 0 : }
215 :
216 0 : static INLINE void h_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
217 : const uint8_t *above, const uint8_t *left) {
218 : int r;
219 : (void)above;
220 :
221 0 : for (r = 0; r < bs; r++) {
222 0 : memset(dst, left[r], bs);
223 0 : dst += stride;
224 : }
225 0 : }
226 :
227 0 : static INLINE void tm_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
228 : const uint8_t *above, const uint8_t *left) {
229 : int r, c;
230 0 : int ytop_left = above[-1];
231 :
232 0 : for (r = 0; r < bs; r++) {
233 0 : for (c = 0; c < bs; c++)
234 0 : dst[c] = clip_pixel(left[r] + above[c] - ytop_left);
235 0 : dst += stride;
236 : }
237 0 : }
238 :
239 0 : static INLINE void dc_128_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
240 : const uint8_t *above, const uint8_t *left) {
241 : int r;
242 : (void)above;
243 : (void)left;
244 :
245 0 : for (r = 0; r < bs; r++) {
246 0 : memset(dst, 128, bs);
247 0 : dst += stride;
248 : }
249 0 : }
250 :
251 0 : static INLINE void dc_left_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
252 : const uint8_t *above,
253 : const uint8_t *left) {
254 0 : int i, r, expected_dc, sum = 0;
255 : (void)above;
256 :
257 0 : for (i = 0; i < bs; i++) sum += left[i];
258 0 : expected_dc = (sum + (bs >> 1)) / bs;
259 :
260 0 : for (r = 0; r < bs; r++) {
261 0 : memset(dst, expected_dc, bs);
262 0 : dst += stride;
263 : }
264 0 : }
265 :
266 0 : static INLINE void dc_top_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
267 : const uint8_t *above, const uint8_t *left) {
268 0 : int i, r, expected_dc, sum = 0;
269 : (void)left;
270 :
271 0 : for (i = 0; i < bs; i++) sum += above[i];
272 0 : expected_dc = (sum + (bs >> 1)) / bs;
273 :
274 0 : for (r = 0; r < bs; r++) {
275 0 : memset(dst, expected_dc, bs);
276 0 : dst += stride;
277 : }
278 0 : }
279 :
280 0 : static INLINE void dc_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
281 : const uint8_t *above, const uint8_t *left) {
282 0 : int i, r, expected_dc, sum = 0;
283 0 : const int count = 2 * bs;
284 :
285 0 : for (i = 0; i < bs; i++) {
286 0 : sum += above[i];
287 0 : sum += left[i];
288 : }
289 :
290 0 : expected_dc = (sum + (count >> 1)) / count;
291 :
292 0 : for (r = 0; r < bs; r++) {
293 0 : memset(dst, expected_dc, bs);
294 0 : dst += stride;
295 : }
296 0 : }
297 :
298 0 : void vpx_he_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride,
299 : const uint8_t *above, const uint8_t *left) {
300 0 : const int H = above[-1];
301 0 : const int I = left[0];
302 0 : const int J = left[1];
303 0 : const int K = left[2];
304 0 : const int L = left[3];
305 :
306 0 : memset(dst + stride * 0, AVG3(H, I, J), 4);
307 0 : memset(dst + stride * 1, AVG3(I, J, K), 4);
308 0 : memset(dst + stride * 2, AVG3(J, K, L), 4);
309 0 : memset(dst + stride * 3, AVG3(K, L, L), 4);
310 0 : }
311 :
312 0 : void vpx_ve_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride,
313 : const uint8_t *above, const uint8_t *left) {
314 0 : const int H = above[-1];
315 0 : const int I = above[0];
316 0 : const int J = above[1];
317 0 : const int K = above[2];
318 0 : const int L = above[3];
319 0 : const int M = above[4];
320 : (void)left;
321 :
322 0 : dst[0] = AVG3(H, I, J);
323 0 : dst[1] = AVG3(I, J, K);
324 0 : dst[2] = AVG3(J, K, L);
325 0 : dst[3] = AVG3(K, L, M);
326 0 : memcpy(dst + stride * 1, dst, 4);
327 0 : memcpy(dst + stride * 2, dst, 4);
328 0 : memcpy(dst + stride * 3, dst, 4);
329 0 : }
330 :
331 0 : void vpx_d207_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride,
332 : const uint8_t *above, const uint8_t *left) {
333 0 : const int I = left[0];
334 0 : const int J = left[1];
335 0 : const int K = left[2];
336 0 : const int L = left[3];
337 : (void)above;
338 0 : DST(0, 0) = AVG2(I, J);
339 0 : DST(2, 0) = DST(0, 1) = AVG2(J, K);
340 0 : DST(2, 1) = DST(0, 2) = AVG2(K, L);
341 0 : DST(1, 0) = AVG3(I, J, K);
342 0 : DST(3, 0) = DST(1, 1) = AVG3(J, K, L);
343 0 : DST(3, 1) = DST(1, 2) = AVG3(K, L, L);
344 0 : DST(3, 2) = DST(2, 2) = DST(0, 3) = DST(1, 3) = DST(2, 3) = DST(3, 3) = L;
345 0 : }
346 :
347 0 : void vpx_d63_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride,
348 : const uint8_t *above, const uint8_t *left) {
349 0 : const int A = above[0];
350 0 : const int B = above[1];
351 0 : const int C = above[2];
352 0 : const int D = above[3];
353 0 : const int E = above[4];
354 0 : const int F = above[5];
355 0 : const int G = above[6];
356 : (void)left;
357 0 : DST(0, 0) = AVG2(A, B);
358 0 : DST(1, 0) = DST(0, 2) = AVG2(B, C);
359 0 : DST(2, 0) = DST(1, 2) = AVG2(C, D);
360 0 : DST(3, 0) = DST(2, 2) = AVG2(D, E);
361 0 : DST(3, 2) = AVG2(E, F); // differs from vp8
362 :
363 0 : DST(0, 1) = AVG3(A, B, C);
364 0 : DST(1, 1) = DST(0, 3) = AVG3(B, C, D);
365 0 : DST(2, 1) = DST(1, 3) = AVG3(C, D, E);
366 0 : DST(3, 1) = DST(2, 3) = AVG3(D, E, F);
367 0 : DST(3, 3) = AVG3(E, F, G); // differs from vp8
368 0 : }
369 :
370 0 : void vpx_d63f_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride,
371 : const uint8_t *above, const uint8_t *left) {
372 0 : const int A = above[0];
373 0 : const int B = above[1];
374 0 : const int C = above[2];
375 0 : const int D = above[3];
376 0 : const int E = above[4];
377 0 : const int F = above[5];
378 0 : const int G = above[6];
379 0 : const int H = above[7];
380 : (void)left;
381 0 : DST(0, 0) = AVG2(A, B);
382 0 : DST(1, 0) = DST(0, 2) = AVG2(B, C);
383 0 : DST(2, 0) = DST(1, 2) = AVG2(C, D);
384 0 : DST(3, 0) = DST(2, 2) = AVG2(D, E);
385 0 : DST(3, 2) = AVG3(E, F, G);
386 :
387 0 : DST(0, 1) = AVG3(A, B, C);
388 0 : DST(1, 1) = DST(0, 3) = AVG3(B, C, D);
389 0 : DST(2, 1) = DST(1, 3) = AVG3(C, D, E);
390 0 : DST(3, 1) = DST(2, 3) = AVG3(D, E, F);
391 0 : DST(3, 3) = AVG3(F, G, H);
392 0 : }
393 :
394 0 : void vpx_d45_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride,
395 : const uint8_t *above, const uint8_t *left) {
396 0 : const int A = above[0];
397 0 : const int B = above[1];
398 0 : const int C = above[2];
399 0 : const int D = above[3];
400 0 : const int E = above[4];
401 0 : const int F = above[5];
402 0 : const int G = above[6];
403 0 : const int H = above[7];
404 : (void)stride;
405 : (void)left;
406 0 : DST(0, 0) = AVG3(A, B, C);
407 0 : DST(1, 0) = DST(0, 1) = AVG3(B, C, D);
408 0 : DST(2, 0) = DST(1, 1) = DST(0, 2) = AVG3(C, D, E);
409 0 : DST(3, 0) = DST(2, 1) = DST(1, 2) = DST(0, 3) = AVG3(D, E, F);
410 0 : DST(3, 1) = DST(2, 2) = DST(1, 3) = AVG3(E, F, G);
411 0 : DST(3, 2) = DST(2, 3) = AVG3(F, G, H);
412 0 : DST(3, 3) = H; // differs from vp8
413 0 : }
414 :
415 0 : void vpx_d45e_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride,
416 : const uint8_t *above, const uint8_t *left) {
417 0 : const int A = above[0];
418 0 : const int B = above[1];
419 0 : const int C = above[2];
420 0 : const int D = above[3];
421 0 : const int E = above[4];
422 0 : const int F = above[5];
423 0 : const int G = above[6];
424 0 : const int H = above[7];
425 : (void)stride;
426 : (void)left;
427 0 : DST(0, 0) = AVG3(A, B, C);
428 0 : DST(1, 0) = DST(0, 1) = AVG3(B, C, D);
429 0 : DST(2, 0) = DST(1, 1) = DST(0, 2) = AVG3(C, D, E);
430 0 : DST(3, 0) = DST(2, 1) = DST(1, 2) = DST(0, 3) = AVG3(D, E, F);
431 0 : DST(3, 1) = DST(2, 2) = DST(1, 3) = AVG3(E, F, G);
432 0 : DST(3, 2) = DST(2, 3) = AVG3(F, G, H);
433 0 : DST(3, 3) = AVG3(G, H, H);
434 0 : }
435 :
436 0 : void vpx_d117_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride,
437 : const uint8_t *above, const uint8_t *left) {
438 0 : const int I = left[0];
439 0 : const int J = left[1];
440 0 : const int K = left[2];
441 0 : const int X = above[-1];
442 0 : const int A = above[0];
443 0 : const int B = above[1];
444 0 : const int C = above[2];
445 0 : const int D = above[3];
446 0 : DST(0, 0) = DST(1, 2) = AVG2(X, A);
447 0 : DST(1, 0) = DST(2, 2) = AVG2(A, B);
448 0 : DST(2, 0) = DST(3, 2) = AVG2(B, C);
449 0 : DST(3, 0) = AVG2(C, D);
450 :
451 0 : DST(0, 3) = AVG3(K, J, I);
452 0 : DST(0, 2) = AVG3(J, I, X);
453 0 : DST(0, 1) = DST(1, 3) = AVG3(I, X, A);
454 0 : DST(1, 1) = DST(2, 3) = AVG3(X, A, B);
455 0 : DST(2, 1) = DST(3, 3) = AVG3(A, B, C);
456 0 : DST(3, 1) = AVG3(B, C, D);
457 0 : }
458 :
459 0 : void vpx_d135_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride,
460 : const uint8_t *above, const uint8_t *left) {
461 0 : const int I = left[0];
462 0 : const int J = left[1];
463 0 : const int K = left[2];
464 0 : const int L = left[3];
465 0 : const int X = above[-1];
466 0 : const int A = above[0];
467 0 : const int B = above[1];
468 0 : const int C = above[2];
469 0 : const int D = above[3];
470 : (void)stride;
471 0 : DST(0, 3) = AVG3(J, K, L);
472 0 : DST(1, 3) = DST(0, 2) = AVG3(I, J, K);
473 0 : DST(2, 3) = DST(1, 2) = DST(0, 1) = AVG3(X, I, J);
474 0 : DST(3, 3) = DST(2, 2) = DST(1, 1) = DST(0, 0) = AVG3(A, X, I);
475 0 : DST(3, 2) = DST(2, 1) = DST(1, 0) = AVG3(B, A, X);
476 0 : DST(3, 1) = DST(2, 0) = AVG3(C, B, A);
477 0 : DST(3, 0) = AVG3(D, C, B);
478 0 : }
479 :
480 0 : void vpx_d153_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride,
481 : const uint8_t *above, const uint8_t *left) {
482 0 : const int I = left[0];
483 0 : const int J = left[1];
484 0 : const int K = left[2];
485 0 : const int L = left[3];
486 0 : const int X = above[-1];
487 0 : const int A = above[0];
488 0 : const int B = above[1];
489 0 : const int C = above[2];
490 :
491 0 : DST(0, 0) = DST(2, 1) = AVG2(I, X);
492 0 : DST(0, 1) = DST(2, 2) = AVG2(J, I);
493 0 : DST(0, 2) = DST(2, 3) = AVG2(K, J);
494 0 : DST(0, 3) = AVG2(L, K);
495 :
496 0 : DST(3, 0) = AVG3(A, B, C);
497 0 : DST(2, 0) = AVG3(X, A, B);
498 0 : DST(1, 0) = DST(3, 1) = AVG3(I, X, A);
499 0 : DST(1, 1) = DST(3, 2) = AVG3(J, I, X);
500 0 : DST(1, 2) = DST(3, 3) = AVG3(K, J, I);
501 0 : DST(1, 3) = AVG3(L, K, J);
502 0 : }
503 :
504 : #if CONFIG_VP9_HIGHBITDEPTH
505 : static INLINE void highbd_d207_predictor(uint16_t *dst, ptrdiff_t stride,
506 : int bs, const uint16_t *above,
507 : const uint16_t *left, int bd) {
508 : int r, c;
509 : (void)above;
510 : (void)bd;
511 :
512 : // First column.
513 : for (r = 0; r < bs - 1; ++r) {
514 : dst[r * stride] = AVG2(left[r], left[r + 1]);
515 : }
516 : dst[(bs - 1) * stride] = left[bs - 1];
517 : dst++;
518 :
519 : // Second column.
520 : for (r = 0; r < bs - 2; ++r) {
521 : dst[r * stride] = AVG3(left[r], left[r + 1], left[r + 2]);
522 : }
523 : dst[(bs - 2) * stride] = AVG3(left[bs - 2], left[bs - 1], left[bs - 1]);
524 : dst[(bs - 1) * stride] = left[bs - 1];
525 : dst++;
526 :
527 : // Rest of last row.
528 : for (c = 0; c < bs - 2; ++c) dst[(bs - 1) * stride + c] = left[bs - 1];
529 :
530 : for (r = bs - 2; r >= 0; --r) {
531 : for (c = 0; c < bs - 2; ++c)
532 : dst[r * stride + c] = dst[(r + 1) * stride + c - 2];
533 : }
534 : }
535 :
536 : #if CONFIG_MISC_FIXES
537 : static INLINE void highbd_d207e_predictor(uint16_t *dst, ptrdiff_t stride,
538 : int bs, const uint16_t *above,
539 : const uint16_t *left, int bd) {
540 : int r, c;
541 : (void)above;
542 : (void)bd;
543 :
544 : for (r = 0; r < bs; ++r) {
545 : for (c = 0; c < bs; ++c) {
546 : dst[c] = c & 1 ? AVG3(left[(c >> 1) + r], left[(c >> 1) + r + 1],
547 : left[(c >> 1) + r + 2])
548 : : AVG2(left[(c >> 1) + r], left[(c >> 1) + r + 1]);
549 : }
550 : dst += stride;
551 : }
552 : }
553 : #endif // CONFIG_MISC_FIXES
554 :
555 : static INLINE void highbd_d63_predictor(uint16_t *dst, ptrdiff_t stride, int bs,
556 : const uint16_t *above,
557 : const uint16_t *left, int bd) {
558 : int r, c;
559 : (void)left;
560 : (void)bd;
561 : for (r = 0; r < bs; ++r) {
562 : for (c = 0; c < bs; ++c) {
563 : dst[c] = r & 1 ? AVG3(above[(r >> 1) + c], above[(r >> 1) + c + 1],
564 : above[(r >> 1) + c + 2])
565 : : AVG2(above[(r >> 1) + c], above[(r >> 1) + c + 1]);
566 : }
567 : dst += stride;
568 : }
569 : }
570 :
571 : #define highbd_d63e_predictor highbd_d63_predictor
572 :
573 : static INLINE void highbd_d45_predictor(uint16_t *dst, ptrdiff_t stride, int bs,
574 : const uint16_t *above,
575 : const uint16_t *left, int bd) {
576 : int r, c;
577 : (void)left;
578 : (void)bd;
579 : for (r = 0; r < bs; ++r) {
580 : for (c = 0; c < bs; ++c) {
581 : dst[c] = r + c + 2 < bs * 2
582 : ? AVG3(above[r + c], above[r + c + 1], above[r + c + 2])
583 : : above[bs * 2 - 1];
584 : }
585 : dst += stride;
586 : }
587 : }
588 :
589 : #if CONFIG_MISC_FIXES
590 : static INLINE void highbd_d45e_predictor(uint16_t *dst, ptrdiff_t stride,
591 : int bs, const uint16_t *above,
592 : const uint16_t *left, int bd) {
593 : int r, c;
594 : (void)left;
595 : (void)bd;
596 : for (r = 0; r < bs; ++r) {
597 : for (c = 0; c < bs; ++c) {
598 : dst[c] = AVG3(above[r + c], above[r + c + 1],
599 : above[r + c + 1 + (r + c + 2 < bs * 2)]);
600 : }
601 : dst += stride;
602 : }
603 : }
604 : #endif // CONFIG_MISC_FIXES
605 :
606 : static INLINE void highbd_d117_predictor(uint16_t *dst, ptrdiff_t stride,
607 : int bs, const uint16_t *above,
608 : const uint16_t *left, int bd) {
609 : int r, c;
610 : (void)bd;
611 :
612 : // first row
613 : for (c = 0; c < bs; c++) dst[c] = AVG2(above[c - 1], above[c]);
614 : dst += stride;
615 :
616 : // second row
617 : dst[0] = AVG3(left[0], above[-1], above[0]);
618 : for (c = 1; c < bs; c++) dst[c] = AVG3(above[c - 2], above[c - 1], above[c]);
619 : dst += stride;
620 :
621 : // the rest of first col
622 : dst[0] = AVG3(above[-1], left[0], left[1]);
623 : for (r = 3; r < bs; ++r)
624 : dst[(r - 2) * stride] = AVG3(left[r - 3], left[r - 2], left[r - 1]);
625 :
626 : // the rest of the block
627 : for (r = 2; r < bs; ++r) {
628 : for (c = 1; c < bs; c++) dst[c] = dst[-2 * stride + c - 1];
629 : dst += stride;
630 : }
631 : }
632 :
633 : static INLINE void highbd_d135_predictor(uint16_t *dst, ptrdiff_t stride,
634 : int bs, const uint16_t *above,
635 : const uint16_t *left, int bd) {
636 : int r, c;
637 : (void)bd;
638 : dst[0] = AVG3(left[0], above[-1], above[0]);
639 : for (c = 1; c < bs; c++) dst[c] = AVG3(above[c - 2], above[c - 1], above[c]);
640 :
641 : dst[stride] = AVG3(above[-1], left[0], left[1]);
642 : for (r = 2; r < bs; ++r)
643 : dst[r * stride] = AVG3(left[r - 2], left[r - 1], left[r]);
644 :
645 : dst += stride;
646 : for (r = 1; r < bs; ++r) {
647 : for (c = 1; c < bs; c++) dst[c] = dst[-stride + c - 1];
648 : dst += stride;
649 : }
650 : }
651 :
652 : static INLINE void highbd_d153_predictor(uint16_t *dst, ptrdiff_t stride,
653 : int bs, const uint16_t *above,
654 : const uint16_t *left, int bd) {
655 : int r, c;
656 : (void)bd;
657 : dst[0] = AVG2(above[-1], left[0]);
658 : for (r = 1; r < bs; r++) dst[r * stride] = AVG2(left[r - 1], left[r]);
659 : dst++;
660 :
661 : dst[0] = AVG3(left[0], above[-1], above[0]);
662 : dst[stride] = AVG3(above[-1], left[0], left[1]);
663 : for (r = 2; r < bs; r++)
664 : dst[r * stride] = AVG3(left[r - 2], left[r - 1], left[r]);
665 : dst++;
666 :
667 : for (c = 0; c < bs - 2; c++)
668 : dst[c] = AVG3(above[c - 1], above[c], above[c + 1]);
669 : dst += stride;
670 :
671 : for (r = 1; r < bs; ++r) {
672 : for (c = 0; c < bs - 2; c++) dst[c] = dst[-stride + c - 2];
673 : dst += stride;
674 : }
675 : }
676 :
677 : static INLINE void highbd_v_predictor(uint16_t *dst, ptrdiff_t stride, int bs,
678 : const uint16_t *above,
679 : const uint16_t *left, int bd) {
680 : int r;
681 : (void)left;
682 : (void)bd;
683 : for (r = 0; r < bs; r++) {
684 : memcpy(dst, above, bs * sizeof(uint16_t));
685 : dst += stride;
686 : }
687 : }
688 :
689 : static INLINE void highbd_h_predictor(uint16_t *dst, ptrdiff_t stride, int bs,
690 : const uint16_t *above,
691 : const uint16_t *left, int bd) {
692 : int r;
693 : (void)above;
694 : (void)bd;
695 : for (r = 0; r < bs; r++) {
696 : vpx_memset16(dst, left[r], bs);
697 : dst += stride;
698 : }
699 : }
700 :
701 : static INLINE void highbd_tm_predictor(uint16_t *dst, ptrdiff_t stride, int bs,
702 : const uint16_t *above,
703 : const uint16_t *left, int bd) {
704 : int r, c;
705 : int ytop_left = above[-1];
706 : (void)bd;
707 :
708 : for (r = 0; r < bs; r++) {
709 : for (c = 0; c < bs; c++)
710 : dst[c] = clip_pixel_highbd(left[r] + above[c] - ytop_left, bd);
711 : dst += stride;
712 : }
713 : }
714 :
715 : static INLINE void highbd_dc_128_predictor(uint16_t *dst, ptrdiff_t stride,
716 : int bs, const uint16_t *above,
717 : const uint16_t *left, int bd) {
718 : int r;
719 : (void)above;
720 : (void)left;
721 :
722 : for (r = 0; r < bs; r++) {
723 : vpx_memset16(dst, 128 << (bd - 8), bs);
724 : dst += stride;
725 : }
726 : }
727 :
728 : static INLINE void highbd_dc_left_predictor(uint16_t *dst, ptrdiff_t stride,
729 : int bs, const uint16_t *above,
730 : const uint16_t *left, int bd) {
731 : int i, r, expected_dc, sum = 0;
732 : (void)above;
733 : (void)bd;
734 :
735 : for (i = 0; i < bs; i++) sum += left[i];
736 : expected_dc = (sum + (bs >> 1)) / bs;
737 :
738 : for (r = 0; r < bs; r++) {
739 : vpx_memset16(dst, expected_dc, bs);
740 : dst += stride;
741 : }
742 : }
743 :
744 : static INLINE void highbd_dc_top_predictor(uint16_t *dst, ptrdiff_t stride,
745 : int bs, const uint16_t *above,
746 : const uint16_t *left, int bd) {
747 : int i, r, expected_dc, sum = 0;
748 : (void)left;
749 : (void)bd;
750 :
751 : for (i = 0; i < bs; i++) sum += above[i];
752 : expected_dc = (sum + (bs >> 1)) / bs;
753 :
754 : for (r = 0; r < bs; r++) {
755 : vpx_memset16(dst, expected_dc, bs);
756 : dst += stride;
757 : }
758 : }
759 :
760 : static INLINE void highbd_dc_predictor(uint16_t *dst, ptrdiff_t stride, int bs,
761 : const uint16_t *above,
762 : const uint16_t *left, int bd) {
763 : int i, r, expected_dc, sum = 0;
764 : const int count = 2 * bs;
765 : (void)bd;
766 :
767 : for (i = 0; i < bs; i++) {
768 : sum += above[i];
769 : sum += left[i];
770 : }
771 :
772 : expected_dc = (sum + (count >> 1)) / count;
773 :
774 : for (r = 0; r < bs; r++) {
775 : vpx_memset16(dst, expected_dc, bs);
776 : dst += stride;
777 : }
778 : }
779 : #endif // CONFIG_VP9_HIGHBITDEPTH
780 :
781 : // This serves as a wrapper function, so that all the prediction functions
782 : // can be unified and accessed as a pointer array. Note that the boundary
783 : // above and left are not necessarily used all the time.
784 : #define intra_pred_sized(type, size) \
785 : void vpx_##type##_predictor_##size##x##size##_c( \
786 : uint8_t *dst, ptrdiff_t stride, const uint8_t *above, \
787 : const uint8_t *left) { \
788 : type##_predictor(dst, stride, size, above, left); \
789 : }
790 :
791 : #if CONFIG_VP9_HIGHBITDEPTH
792 : #define intra_pred_highbd_sized(type, size) \
793 : void vpx_highbd_##type##_predictor_##size##x##size##_c( \
794 : uint16_t *dst, ptrdiff_t stride, const uint16_t *above, \
795 : const uint16_t *left, int bd) { \
796 : highbd_##type##_predictor(dst, stride, size, above, left, bd); \
797 : }
798 :
799 : /* clang-format off */
800 : #define intra_pred_allsizes(type) \
801 : intra_pred_sized(type, 4) \
802 : intra_pred_sized(type, 8) \
803 : intra_pred_sized(type, 16) \
804 : intra_pred_sized(type, 32) \
805 : intra_pred_highbd_sized(type, 4) \
806 : intra_pred_highbd_sized(type, 8) \
807 : intra_pred_highbd_sized(type, 16) \
808 : intra_pred_highbd_sized(type, 32)
809 :
810 : #define intra_pred_no_4x4(type) \
811 : intra_pred_sized(type, 8) \
812 : intra_pred_sized(type, 16) \
813 : intra_pred_sized(type, 32) \
814 : intra_pred_highbd_sized(type, 4) \
815 : intra_pred_highbd_sized(type, 8) \
816 : intra_pred_highbd_sized(type, 16) \
817 : intra_pred_highbd_sized(type, 32)
818 :
819 : #else
820 : #define intra_pred_allsizes(type) \
821 : intra_pred_sized(type, 4) \
822 : intra_pred_sized(type, 8) \
823 : intra_pred_sized(type, 16) \
824 : intra_pred_sized(type, 32)
825 :
826 : #define intra_pred_no_4x4(type) \
827 : intra_pred_sized(type, 8) \
828 : intra_pred_sized(type, 16) \
829 : intra_pred_sized(type, 32)
830 : #endif // CONFIG_VP9_HIGHBITDEPTH
831 :
832 0 : intra_pred_no_4x4(d207)
833 0 : intra_pred_no_4x4(d63)
834 0 : intra_pred_no_4x4(d45)
835 : #if CONFIG_MISC_FIXES
836 : intra_pred_allsizes(d207e)
837 : intra_pred_allsizes(d63e)
838 : intra_pred_no_4x4(d45e)
839 : #endif
840 0 : intra_pred_no_4x4(d117)
841 0 : intra_pred_no_4x4(d135)
842 0 : intra_pred_no_4x4(d153)
843 0 : intra_pred_allsizes(v)
844 0 : intra_pred_allsizes(h)
845 0 : intra_pred_allsizes(tm)
846 0 : intra_pred_allsizes(dc_128)
847 0 : intra_pred_allsizes(dc_left)
848 0 : intra_pred_allsizes(dc_top)
849 0 : intra_pred_allsizes(dc)
850 : /* clang-format on */
851 : #undef intra_pred_allsizes
|