blob: c3af1f4697d46bf5b776d7a7c23111cbe3bc5dcc [file] [log] [blame]
Yaowu Xuc27fc142016-08-22 16:08:15 -07001/*
Yaowu Xu9c01aa12016-09-01 14:32:49 -07002 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Yaowu Xuc27fc142016-08-22 16:08:15 -07003 *
Yaowu Xu9c01aa12016-09-01 14:32:49 -07004 * This source code is subject to the terms of the BSD 2 Clause License and
5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6 * was not distributed with this source code in the LICENSE file, you can
7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8 * Media Patent License 1.0 was not distributed with this source code in the
9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
Yaowu Xuc27fc142016-08-22 16:08:15 -070010 */
11
Yaowu Xuf883b422016-08-30 14:01:10 -070012#include "./aom_config.h"
13#include "./aom_dsp_rtcd.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070014
Yaowu Xuf883b422016-08-30 14:01:10 -070015#include "aom_dsp/aom_dsp_common.h"
16#include "aom_mem/aom_mem.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070017
18#define DST(x, y) dst[(x) + (y)*stride]
19#define AVG3(a, b, c) (((a) + 2 * (b) + (c) + 2) >> 2)
20#define AVG2(a, b) (((a) + (b) + 1) >> 1)
21
22static INLINE void d207_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
23 const uint8_t *above, const uint8_t *left) {
24 int r, c;
25 (void)above;
26 // first column
27 for (r = 0; r < bs - 1; ++r) dst[r * stride] = AVG2(left[r], left[r + 1]);
28 dst[(bs - 1) * stride] = left[bs - 1];
29 dst++;
30
31 // second column
32 for (r = 0; r < bs - 2; ++r)
33 dst[r * stride] = AVG3(left[r], left[r + 1], left[r + 2]);
34 dst[(bs - 2) * stride] = AVG3(left[bs - 2], left[bs - 1], left[bs - 1]);
35 dst[(bs - 1) * stride] = left[bs - 1];
36 dst++;
37
38 // rest of last row
39 for (c = 0; c < bs - 2; ++c) dst[(bs - 1) * stride + c] = left[bs - 1];
40
41 for (r = bs - 2; r >= 0; --r)
42 for (c = 0; c < bs - 2; ++c)
43 dst[r * stride + c] = dst[(r + 1) * stride + c - 2];
44}
45
46static 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
61static INLINE void d63_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
62 const uint8_t *above, const uint8_t *left) {
63 int r, c;
64 int size;
65 (void)left;
66 for (c = 0; c < bs; ++c) {
67 dst[c] = AVG2(above[c], above[c + 1]);
68 dst[stride + c] = AVG3(above[c], above[c + 1], above[c + 2]);
69 }
70 for (r = 2, size = bs - 2; r < bs; r += 2, --size) {
71 memcpy(dst + (r + 0) * stride, dst + (r >> 1), size);
72 memset(dst + (r + 0) * stride + size, above[bs - 1], bs - size);
73 memcpy(dst + (r + 1) * stride, dst + stride + (r >> 1), size);
74 memset(dst + (r + 1) * stride + size, above[bs - 1], bs - size);
75 }
76}
77
78static INLINE void d63e_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
79 const uint8_t *above, const uint8_t *left) {
80 int r, c;
81 (void)left;
82 for (r = 0; r < bs; ++r) {
83 for (c = 0; c < bs; ++c) {
84 dst[c] = r & 1 ? AVG3(above[(r >> 1) + c], above[(r >> 1) + c + 1],
85 above[(r >> 1) + c + 2])
86 : AVG2(above[(r >> 1) + c], above[(r >> 1) + c + 1]);
87 }
88 dst += stride;
89 }
90}
91
92static INLINE void d45_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
93 const uint8_t *above, const uint8_t *left) {
94 const uint8_t above_right = above[bs - 1];
95 const uint8_t *const dst_row0 = dst;
96 int x, size;
97 (void)left;
98
99 for (x = 0; x < bs - 1; ++x) {
100 dst[x] = AVG3(above[x], above[x + 1], above[x + 2]);
101 }
102 dst[bs - 1] = above_right;
103 dst += stride;
104 for (x = 1, size = bs - 2; x < bs; ++x, --size) {
105 memcpy(dst, dst_row0 + x, size);
106 memset(dst + size, above_right, x + 1);
107 dst += stride;
108 }
109}
110
111static INLINE void d45e_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
112 const uint8_t *above, const uint8_t *left) {
113 int r, c;
114 (void)left;
115 for (r = 0; r < bs; ++r) {
116 for (c = 0; c < bs; ++c) {
117 dst[c] = AVG3(above[r + c], above[r + c + 1],
118 above[r + c + 1 + (r + c + 2 < bs * 2)]);
119 }
120 dst += stride;
121 }
122}
123
124static INLINE void d117_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
125 const uint8_t *above, const uint8_t *left) {
126 int r, c;
127
128 // first row
129 for (c = 0; c < bs; c++) dst[c] = AVG2(above[c - 1], above[c]);
130 dst += stride;
131
132 // second row
133 dst[0] = AVG3(left[0], above[-1], above[0]);
134 for (c = 1; c < bs; c++) dst[c] = AVG3(above[c - 2], above[c - 1], above[c]);
135 dst += stride;
136
137 // the rest of first col
138 dst[0] = AVG3(above[-1], left[0], left[1]);
139 for (r = 3; r < bs; ++r)
140 dst[(r - 2) * stride] = AVG3(left[r - 3], left[r - 2], left[r - 1]);
141
142 // the rest of the block
143 for (r = 2; r < bs; ++r) {
144 for (c = 1; c < bs; c++) dst[c] = dst[-2 * stride + c - 1];
145 dst += stride;
146 }
147}
148
149static INLINE void d135_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
150 const uint8_t *above, const uint8_t *left) {
151 int i;
152#if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ > 7
153 // silence a spurious -Warray-bounds warning, possibly related to:
154 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56273
155 uint8_t border[69];
156#else
157 uint8_t border[32 + 32 - 1]; // outer border from bottom-left to top-right
158#endif
159
160 // dst(bs, bs - 2)[0], i.e., border starting at bottom-left
161 for (i = 0; i < bs - 2; ++i) {
162 border[i] = AVG3(left[bs - 3 - i], left[bs - 2 - i], left[bs - 1 - i]);
163 }
164 border[bs - 2] = AVG3(above[-1], left[0], left[1]);
165 border[bs - 1] = AVG3(left[0], above[-1], above[0]);
166 border[bs - 0] = AVG3(above[-1], above[0], above[1]);
167 // dst[0][2, size), i.e., remaining top border ascending
168 for (i = 0; i < bs - 2; ++i) {
169 border[bs + 1 + i] = AVG3(above[i], above[i + 1], above[i + 2]);
170 }
171
172 for (i = 0; i < bs; ++i) {
173 memcpy(dst + i * stride, border + bs - 1 - i, bs);
174 }
175}
176
177static INLINE void d153_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
178 const uint8_t *above, const uint8_t *left) {
179 int r, c;
180 dst[0] = AVG2(above[-1], left[0]);
181 for (r = 1; r < bs; r++) dst[r * stride] = AVG2(left[r - 1], left[r]);
182 dst++;
183
184 dst[0] = AVG3(left[0], above[-1], above[0]);
185 dst[stride] = AVG3(above[-1], left[0], left[1]);
186 for (r = 2; r < bs; r++)
187 dst[r * stride] = AVG3(left[r - 2], left[r - 1], left[r]);
188 dst++;
189
190 for (c = 0; c < bs - 2; c++)
191 dst[c] = AVG3(above[c - 1], above[c], above[c + 1]);
192 dst += stride;
193
194 for (r = 1; r < bs; ++r) {
195 for (c = 0; c < bs - 2; c++) dst[c] = dst[-stride + c - 2];
196 dst += stride;
197 }
198}
199
200static INLINE void v_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
201 const uint8_t *above, const uint8_t *left) {
202 int r;
203 (void)left;
204
205 for (r = 0; r < bs; r++) {
206 memcpy(dst, above, bs);
207 dst += stride;
208 }
209}
210
211static INLINE void h_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
212 const uint8_t *above, const uint8_t *left) {
213 int r;
214 (void)above;
215
216 for (r = 0; r < bs; r++) {
217 memset(dst, left[r], bs);
218 dst += stride;
219 }
220}
221
Urvang Joshi340593e2016-09-01 12:03:20 -0700222#if CONFIG_ALT_INTRA
223static INLINE int abs_diff(int a, int b) { return (a > b) ? a - b : b - a; }
224
225static INLINE uint16_t paeth_predictor_single(uint16_t left, uint16_t top,
226 uint16_t top_left) {
227 const int base = top + left - top_left;
228 const int p_left = abs_diff(base, left);
229 const int p_top = abs_diff(base, top);
230 const int p_top_left = abs_diff(base, top_left);
231
232 // Return nearest to base of left, top and top_left.
233 return (p_left <= p_top && p_left <= p_top_left)
234 ? left
235 : (p_top <= p_top_left) ? top : top_left;
236}
237
238static INLINE void paeth_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
239 const uint8_t *above, const uint8_t *left) {
240 int r, c;
241 const uint8_t ytop_left = above[-1];
242
243 for (r = 0; r < bs; r++) {
244 for (c = 0; c < bs; c++)
245 dst[c] = (uint8_t)paeth_predictor_single(left[r], above[c], ytop_left);
246 dst += stride;
247 }
248}
249
250#else
251
Yaowu Xuc27fc142016-08-22 16:08:15 -0700252static INLINE void tm_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
253 const uint8_t *above, const uint8_t *left) {
254 int r, c;
255 int ytop_left = above[-1];
256
257 for (r = 0; r < bs; r++) {
258 for (c = 0; c < bs; c++)
259 dst[c] = clip_pixel(left[r] + above[c] - ytop_left);
260 dst += stride;
261 }
262}
Urvang Joshi340593e2016-09-01 12:03:20 -0700263#endif // CONFIG_ALT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -0700264
265static INLINE void dc_128_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
266 const uint8_t *above, const uint8_t *left) {
267 int r;
268 (void)above;
269 (void)left;
270
271 for (r = 0; r < bs; r++) {
272 memset(dst, 128, bs);
273 dst += stride;
274 }
275}
276
277static INLINE void dc_left_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
278 const uint8_t *above,
279 const uint8_t *left) {
280 int i, r, expected_dc, sum = 0;
281 (void)above;
282
283 for (i = 0; i < bs; i++) sum += left[i];
284 expected_dc = (sum + (bs >> 1)) / bs;
285
286 for (r = 0; r < bs; r++) {
287 memset(dst, expected_dc, bs);
288 dst += stride;
289 }
290}
291
292static INLINE void dc_top_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
293 const uint8_t *above, const uint8_t *left) {
294 int i, r, expected_dc, sum = 0;
295 (void)left;
296
297 for (i = 0; i < bs; i++) sum += above[i];
298 expected_dc = (sum + (bs >> 1)) / bs;
299
300 for (r = 0; r < bs; r++) {
301 memset(dst, expected_dc, bs);
302 dst += stride;
303 }
304}
305
306static INLINE void dc_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
307 const uint8_t *above, const uint8_t *left) {
308 int i, r, expected_dc, sum = 0;
309 const int count = 2 * bs;
310
311 for (i = 0; i < bs; i++) {
312 sum += above[i];
313 sum += left[i];
314 }
315
316 expected_dc = (sum + (count >> 1)) / count;
317
318 for (r = 0; r < bs; r++) {
319 memset(dst, expected_dc, bs);
320 dst += stride;
321 }
322}
323
Yaowu Xuf883b422016-08-30 14:01:10 -0700324void aom_he_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700325 const uint8_t *above, const uint8_t *left) {
326 const int H = above[-1];
327 const int I = left[0];
328 const int J = left[1];
329 const int K = left[2];
330 const int L = left[3];
331
332 memset(dst + stride * 0, AVG3(H, I, J), 4);
333 memset(dst + stride * 1, AVG3(I, J, K), 4);
334 memset(dst + stride * 2, AVG3(J, K, L), 4);
335 memset(dst + stride * 3, AVG3(K, L, L), 4);
336}
337
Yaowu Xuf883b422016-08-30 14:01:10 -0700338void aom_ve_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700339 const uint8_t *above, const uint8_t *left) {
340 const int H = above[-1];
341 const int I = above[0];
342 const int J = above[1];
343 const int K = above[2];
344 const int L = above[3];
345 const int M = above[4];
346 (void)left;
347
348 dst[0] = AVG3(H, I, J);
349 dst[1] = AVG3(I, J, K);
350 dst[2] = AVG3(J, K, L);
351 dst[3] = AVG3(K, L, M);
352 memcpy(dst + stride * 1, dst, 4);
353 memcpy(dst + stride * 2, dst, 4);
354 memcpy(dst + stride * 3, dst, 4);
355}
356
Yaowu Xuf883b422016-08-30 14:01:10 -0700357void aom_d207_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700358 const uint8_t *above, const uint8_t *left) {
359 const int I = left[0];
360 const int J = left[1];
361 const int K = left[2];
362 const int L = left[3];
363 (void)above;
364 DST(0, 0) = AVG2(I, J);
365 DST(2, 0) = DST(0, 1) = AVG2(J, K);
366 DST(2, 1) = DST(0, 2) = AVG2(K, L);
367 DST(1, 0) = AVG3(I, J, K);
368 DST(3, 0) = DST(1, 1) = AVG3(J, K, L);
369 DST(3, 1) = DST(1, 2) = AVG3(K, L, L);
370 DST(3, 2) = DST(2, 2) = DST(0, 3) = DST(1, 3) = DST(2, 3) = DST(3, 3) = L;
371}
372
Yaowu Xuf883b422016-08-30 14:01:10 -0700373void aom_d63_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700374 const uint8_t *above, const uint8_t *left) {
375 const int A = above[0];
376 const int B = above[1];
377 const int C = above[2];
378 const int D = above[3];
379 const int E = above[4];
380 const int F = above[5];
381 const int G = above[6];
382 (void)left;
383 DST(0, 0) = AVG2(A, B);
384 DST(1, 0) = DST(0, 2) = AVG2(B, C);
385 DST(2, 0) = DST(1, 2) = AVG2(C, D);
386 DST(3, 0) = DST(2, 2) = AVG2(D, E);
387 DST(3, 2) = AVG2(E, F); // differs from vp8
388
389 DST(0, 1) = AVG3(A, B, C);
390 DST(1, 1) = DST(0, 3) = AVG3(B, C, D);
391 DST(2, 1) = DST(1, 3) = AVG3(C, D, E);
392 DST(3, 1) = DST(2, 3) = AVG3(D, E, F);
393 DST(3, 3) = AVG3(E, F, G); // differs from vp8
394}
395
Yaowu Xuf883b422016-08-30 14:01:10 -0700396void aom_d63f_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700397 const uint8_t *above, const uint8_t *left) {
398 const int A = above[0];
399 const int B = above[1];
400 const int C = above[2];
401 const int D = above[3];
402 const int E = above[4];
403 const int F = above[5];
404 const int G = above[6];
405 const int H = above[7];
406 (void)left;
407 DST(0, 0) = AVG2(A, B);
408 DST(1, 0) = DST(0, 2) = AVG2(B, C);
409 DST(2, 0) = DST(1, 2) = AVG2(C, D);
410 DST(3, 0) = DST(2, 2) = AVG2(D, E);
411 DST(3, 2) = AVG3(E, F, G);
412
413 DST(0, 1) = AVG3(A, B, C);
414 DST(1, 1) = DST(0, 3) = AVG3(B, C, D);
415 DST(2, 1) = DST(1, 3) = AVG3(C, D, E);
416 DST(3, 1) = DST(2, 3) = AVG3(D, E, F);
417 DST(3, 3) = AVG3(F, G, H);
418}
419
Yaowu Xuf883b422016-08-30 14:01:10 -0700420void aom_d45_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700421 const uint8_t *above, const uint8_t *left) {
422 const int A = above[0];
423 const int B = above[1];
424 const int C = above[2];
425 const int D = above[3];
426 const int E = above[4];
427 const int F = above[5];
428 const int G = above[6];
429 const int H = above[7];
430 (void)stride;
431 (void)left;
432 DST(0, 0) = AVG3(A, B, C);
433 DST(1, 0) = DST(0, 1) = AVG3(B, C, D);
434 DST(2, 0) = DST(1, 1) = DST(0, 2) = AVG3(C, D, E);
435 DST(3, 0) = DST(2, 1) = DST(1, 2) = DST(0, 3) = AVG3(D, E, F);
436 DST(3, 1) = DST(2, 2) = DST(1, 3) = AVG3(E, F, G);
437 DST(3, 2) = DST(2, 3) = AVG3(F, G, H);
438 DST(3, 3) = H; // differs from vp8
439}
440
Yaowu Xuf883b422016-08-30 14:01:10 -0700441void aom_d45e_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700442 const uint8_t *above, const uint8_t *left) {
443 const int A = above[0];
444 const int B = above[1];
445 const int C = above[2];
446 const int D = above[3];
447 const int E = above[4];
448 const int F = above[5];
449 const int G = above[6];
450 const int H = above[7];
451 (void)stride;
452 (void)left;
453 DST(0, 0) = AVG3(A, B, C);
454 DST(1, 0) = DST(0, 1) = AVG3(B, C, D);
455 DST(2, 0) = DST(1, 1) = DST(0, 2) = AVG3(C, D, E);
456 DST(3, 0) = DST(2, 1) = DST(1, 2) = DST(0, 3) = AVG3(D, E, F);
457 DST(3, 1) = DST(2, 2) = DST(1, 3) = AVG3(E, F, G);
458 DST(3, 2) = DST(2, 3) = AVG3(F, G, H);
459 DST(3, 3) = AVG3(G, H, H);
460}
461
Yaowu Xuf883b422016-08-30 14:01:10 -0700462void aom_d117_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700463 const uint8_t *above, const uint8_t *left) {
464 const int I = left[0];
465 const int J = left[1];
466 const int K = left[2];
467 const int X = above[-1];
468 const int A = above[0];
469 const int B = above[1];
470 const int C = above[2];
471 const int D = above[3];
472 DST(0, 0) = DST(1, 2) = AVG2(X, A);
473 DST(1, 0) = DST(2, 2) = AVG2(A, B);
474 DST(2, 0) = DST(3, 2) = AVG2(B, C);
475 DST(3, 0) = AVG2(C, D);
476
477 DST(0, 3) = AVG3(K, J, I);
478 DST(0, 2) = AVG3(J, I, X);
479 DST(0, 1) = DST(1, 3) = AVG3(I, X, A);
480 DST(1, 1) = DST(2, 3) = AVG3(X, A, B);
481 DST(2, 1) = DST(3, 3) = AVG3(A, B, C);
482 DST(3, 1) = AVG3(B, C, D);
483}
484
Yaowu Xuf883b422016-08-30 14:01:10 -0700485void aom_d135_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700486 const uint8_t *above, const uint8_t *left) {
487 const int I = left[0];
488 const int J = left[1];
489 const int K = left[2];
490 const int L = left[3];
491 const int X = above[-1];
492 const int A = above[0];
493 const int B = above[1];
494 const int C = above[2];
495 const int D = above[3];
496 (void)stride;
497 DST(0, 3) = AVG3(J, K, L);
498 DST(1, 3) = DST(0, 2) = AVG3(I, J, K);
499 DST(2, 3) = DST(1, 2) = DST(0, 1) = AVG3(X, I, J);
500 DST(3, 3) = DST(2, 2) = DST(1, 1) = DST(0, 0) = AVG3(A, X, I);
501 DST(3, 2) = DST(2, 1) = DST(1, 0) = AVG3(B, A, X);
502 DST(3, 1) = DST(2, 0) = AVG3(C, B, A);
503 DST(3, 0) = AVG3(D, C, B);
504}
505
Yaowu Xuf883b422016-08-30 14:01:10 -0700506void aom_d153_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700507 const uint8_t *above, const uint8_t *left) {
508 const int I = left[0];
509 const int J = left[1];
510 const int K = left[2];
511 const int L = left[3];
512 const int X = above[-1];
513 const int A = above[0];
514 const int B = above[1];
515 const int C = above[2];
516
517 DST(0, 0) = DST(2, 1) = AVG2(I, X);
518 DST(0, 1) = DST(2, 2) = AVG2(J, I);
519 DST(0, 2) = DST(2, 3) = AVG2(K, J);
520 DST(0, 3) = AVG2(L, K);
521
522 DST(3, 0) = AVG3(A, B, C);
523 DST(2, 0) = AVG3(X, A, B);
524 DST(1, 0) = DST(3, 1) = AVG3(I, X, A);
525 DST(1, 1) = DST(3, 2) = AVG3(J, I, X);
526 DST(1, 2) = DST(3, 3) = AVG3(K, J, I);
527 DST(1, 3) = AVG3(L, K, J);
528}
529
Yaowu Xuf883b422016-08-30 14:01:10 -0700530#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700531static INLINE void highbd_d207_predictor(uint16_t *dst, ptrdiff_t stride,
532 int bs, const uint16_t *above,
533 const uint16_t *left, int bd) {
534 int r, c;
535 (void)above;
536 (void)bd;
537
538 // First column.
539 for (r = 0; r < bs - 1; ++r) {
540 dst[r * stride] = AVG2(left[r], left[r + 1]);
541 }
542 dst[(bs - 1) * stride] = left[bs - 1];
543 dst++;
544
545 // Second column.
546 for (r = 0; r < bs - 2; ++r) {
547 dst[r * stride] = AVG3(left[r], left[r + 1], left[r + 2]);
548 }
549 dst[(bs - 2) * stride] = AVG3(left[bs - 2], left[bs - 1], left[bs - 1]);
550 dst[(bs - 1) * stride] = left[bs - 1];
551 dst++;
552
553 // Rest of last row.
554 for (c = 0; c < bs - 2; ++c) dst[(bs - 1) * stride + c] = left[bs - 1];
555
556 for (r = bs - 2; r >= 0; --r) {
557 for (c = 0; c < bs - 2; ++c)
558 dst[r * stride + c] = dst[(r + 1) * stride + c - 2];
559 }
560}
561
562static INLINE void highbd_d207e_predictor(uint16_t *dst, ptrdiff_t stride,
563 int bs, const uint16_t *above,
564 const uint16_t *left, int bd) {
565 int r, c;
566 (void)above;
567 (void)bd;
568
569 for (r = 0; r < bs; ++r) {
570 for (c = 0; c < bs; ++c) {
571 dst[c] = c & 1 ? AVG3(left[(c >> 1) + r], left[(c >> 1) + r + 1],
572 left[(c >> 1) + r + 2])
573 : AVG2(left[(c >> 1) + r], left[(c >> 1) + r + 1]);
574 }
575 dst += stride;
576 }
577}
578
579static INLINE void highbd_d63_predictor(uint16_t *dst, ptrdiff_t stride, int bs,
580 const uint16_t *above,
581 const uint16_t *left, int bd) {
582 int r, c;
583 (void)left;
584 (void)bd;
585 for (r = 0; r < bs; ++r) {
586 for (c = 0; c < bs; ++c) {
587 dst[c] = r & 1 ? AVG3(above[(r >> 1) + c], above[(r >> 1) + c + 1],
588 above[(r >> 1) + c + 2])
589 : AVG2(above[(r >> 1) + c], above[(r >> 1) + c + 1]);
590 }
591 dst += stride;
592 }
593}
594
595#define highbd_d63e_predictor highbd_d63_predictor
596
597static INLINE void highbd_d45_predictor(uint16_t *dst, ptrdiff_t stride, int bs,
598 const uint16_t *above,
599 const uint16_t *left, int bd) {
600 int r, c;
601 (void)left;
602 (void)bd;
603 for (r = 0; r < bs; ++r) {
604 for (c = 0; c < bs; ++c) {
605 dst[c] = r + c + 2 < bs * 2
606 ? AVG3(above[r + c], above[r + c + 1], above[r + c + 2])
607 : above[bs * 2 - 1];
608 }
609 dst += stride;
610 }
611}
612
613static INLINE void highbd_d45e_predictor(uint16_t *dst, ptrdiff_t stride,
614 int bs, const uint16_t *above,
615 const uint16_t *left, int bd) {
616 int r, c;
617 (void)left;
618 (void)bd;
619 for (r = 0; r < bs; ++r) {
620 for (c = 0; c < bs; ++c) {
621 dst[c] = AVG3(above[r + c], above[r + c + 1],
622 above[r + c + 1 + (r + c + 2 < bs * 2)]);
623 }
624 dst += stride;
625 }
626}
627
628static INLINE void highbd_d117_predictor(uint16_t *dst, ptrdiff_t stride,
629 int bs, const uint16_t *above,
630 const uint16_t *left, int bd) {
631 int r, c;
632 (void)bd;
633
634 // first row
635 for (c = 0; c < bs; c++) dst[c] = AVG2(above[c - 1], above[c]);
636 dst += stride;
637
638 // second row
639 dst[0] = AVG3(left[0], above[-1], above[0]);
640 for (c = 1; c < bs; c++) dst[c] = AVG3(above[c - 2], above[c - 1], above[c]);
641 dst += stride;
642
643 // the rest of first col
644 dst[0] = AVG3(above[-1], left[0], left[1]);
645 for (r = 3; r < bs; ++r)
646 dst[(r - 2) * stride] = AVG3(left[r - 3], left[r - 2], left[r - 1]);
647
648 // the rest of the block
649 for (r = 2; r < bs; ++r) {
650 for (c = 1; c < bs; c++) dst[c] = dst[-2 * stride + c - 1];
651 dst += stride;
652 }
653}
654
655static INLINE void highbd_d135_predictor(uint16_t *dst, ptrdiff_t stride,
656 int bs, const uint16_t *above,
657 const uint16_t *left, int bd) {
658 int r, c;
659 (void)bd;
660 dst[0] = AVG3(left[0], above[-1], above[0]);
661 for (c = 1; c < bs; c++) dst[c] = AVG3(above[c - 2], above[c - 1], above[c]);
662
663 dst[stride] = AVG3(above[-1], left[0], left[1]);
664 for (r = 2; r < bs; ++r)
665 dst[r * stride] = AVG3(left[r - 2], left[r - 1], left[r]);
666
667 dst += stride;
668 for (r = 1; r < bs; ++r) {
669 for (c = 1; c < bs; c++) dst[c] = dst[-stride + c - 1];
670 dst += stride;
671 }
672}
673
674static INLINE void highbd_d153_predictor(uint16_t *dst, ptrdiff_t stride,
675 int bs, const uint16_t *above,
676 const uint16_t *left, int bd) {
677 int r, c;
678 (void)bd;
679 dst[0] = AVG2(above[-1], left[0]);
680 for (r = 1; r < bs; r++) dst[r * stride] = AVG2(left[r - 1], left[r]);
681 dst++;
682
683 dst[0] = AVG3(left[0], above[-1], above[0]);
684 dst[stride] = AVG3(above[-1], left[0], left[1]);
685 for (r = 2; r < bs; r++)
686 dst[r * stride] = AVG3(left[r - 2], left[r - 1], left[r]);
687 dst++;
688
689 for (c = 0; c < bs - 2; c++)
690 dst[c] = AVG3(above[c - 1], above[c], above[c + 1]);
691 dst += stride;
692
693 for (r = 1; r < bs; ++r) {
694 for (c = 0; c < bs - 2; c++) dst[c] = dst[-stride + c - 2];
695 dst += stride;
696 }
697}
698
699static INLINE void highbd_v_predictor(uint16_t *dst, ptrdiff_t stride, int bs,
700 const uint16_t *above,
701 const uint16_t *left, int bd) {
702 int r;
703 (void)left;
704 (void)bd;
705 for (r = 0; r < bs; r++) {
706 memcpy(dst, above, bs * sizeof(uint16_t));
707 dst += stride;
708 }
709}
710
711static INLINE void highbd_h_predictor(uint16_t *dst, ptrdiff_t stride, int bs,
712 const uint16_t *above,
713 const uint16_t *left, int bd) {
714 int r;
715 (void)above;
716 (void)bd;
717 for (r = 0; r < bs; r++) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700718 aom_memset16(dst, left[r], bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700719 dst += stride;
720 }
721}
722
Urvang Joshi340593e2016-09-01 12:03:20 -0700723#if CONFIG_ALT_INTRA
724static INLINE void highbd_paeth_predictor(uint16_t *dst, ptrdiff_t stride,
725 int bs, const uint16_t *above,
726 const uint16_t *left, int bd) {
727 int r, c;
728 const uint16_t ytop_left = above[-1];
729 (void)bd;
730
731 for (r = 0; r < bs; r++) {
732 for (c = 0; c < bs; c++)
733 dst[c] = paeth_predictor_single(left[r], above[c], ytop_left);
734 dst += stride;
735 }
736}
737
738#else
Yaowu Xuc27fc142016-08-22 16:08:15 -0700739static INLINE void highbd_tm_predictor(uint16_t *dst, ptrdiff_t stride, int bs,
740 const uint16_t *above,
741 const uint16_t *left, int bd) {
742 int r, c;
743 int ytop_left = above[-1];
744 (void)bd;
745
746 for (r = 0; r < bs; r++) {
747 for (c = 0; c < bs; c++)
748 dst[c] = clip_pixel_highbd(left[r] + above[c] - ytop_left, bd);
749 dst += stride;
750 }
751}
Urvang Joshi340593e2016-09-01 12:03:20 -0700752#endif // CONFIG_ALT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -0700753
754static INLINE void highbd_dc_128_predictor(uint16_t *dst, ptrdiff_t stride,
755 int bs, const uint16_t *above,
756 const uint16_t *left, int bd) {
757 int r;
758 (void)above;
759 (void)left;
760
761 for (r = 0; r < bs; r++) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700762 aom_memset16(dst, 128 << (bd - 8), bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700763 dst += stride;
764 }
765}
766
767static INLINE void highbd_dc_left_predictor(uint16_t *dst, ptrdiff_t stride,
768 int bs, const uint16_t *above,
769 const uint16_t *left, int bd) {
770 int i, r, expected_dc, sum = 0;
771 (void)above;
772 (void)bd;
773
774 for (i = 0; i < bs; i++) sum += left[i];
775 expected_dc = (sum + (bs >> 1)) / bs;
776
777 for (r = 0; r < bs; r++) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700778 aom_memset16(dst, expected_dc, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700779 dst += stride;
780 }
781}
782
783static INLINE void highbd_dc_top_predictor(uint16_t *dst, ptrdiff_t stride,
784 int bs, const uint16_t *above,
785 const uint16_t *left, int bd) {
786 int i, r, expected_dc, sum = 0;
787 (void)left;
788 (void)bd;
789
790 for (i = 0; i < bs; i++) sum += above[i];
791 expected_dc = (sum + (bs >> 1)) / bs;
792
793 for (r = 0; r < bs; r++) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700794 aom_memset16(dst, expected_dc, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700795 dst += stride;
796 }
797}
798
799static INLINE void highbd_dc_predictor(uint16_t *dst, ptrdiff_t stride, int bs,
800 const uint16_t *above,
801 const uint16_t *left, int bd) {
802 int i, r, expected_dc, sum = 0;
803 const int count = 2 * bs;
804 (void)bd;
805
806 for (i = 0; i < bs; i++) {
807 sum += above[i];
808 sum += left[i];
809 }
810
811 expected_dc = (sum + (count >> 1)) / count;
812
813 for (r = 0; r < bs; r++) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700814 aom_memset16(dst, expected_dc, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700815 dst += stride;
816 }
817}
Yaowu Xuf883b422016-08-30 14:01:10 -0700818#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700819
820// This serves as a wrapper function, so that all the prediction functions
821// can be unified and accessed as a pointer array. Note that the boundary
822// above and left are not necessarily used all the time.
823#define intra_pred_sized(type, size) \
Yaowu Xuf883b422016-08-30 14:01:10 -0700824 void aom_##type##_predictor_##size##x##size##_c( \
Yaowu Xuc27fc142016-08-22 16:08:15 -0700825 uint8_t *dst, ptrdiff_t stride, const uint8_t *above, \
826 const uint8_t *left) { \
827 type##_predictor(dst, stride, size, above, left); \
828 }
829
Yaowu Xuf883b422016-08-30 14:01:10 -0700830#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700831#define intra_pred_highbd_sized(type, size) \
Yaowu Xuf883b422016-08-30 14:01:10 -0700832 void aom_highbd_##type##_predictor_##size##x##size##_c( \
Yaowu Xuc27fc142016-08-22 16:08:15 -0700833 uint16_t *dst, ptrdiff_t stride, const uint16_t *above, \
834 const uint16_t *left, int bd) { \
835 highbd_##type##_predictor(dst, stride, size, above, left, bd); \
836 }
837
838/* clang-format off */
839#define intra_pred_allsizes(type) \
Jingning Hane3954d82016-10-12 21:03:18 -0700840 intra_pred_sized(type, 2) \
Yaowu Xuc27fc142016-08-22 16:08:15 -0700841 intra_pred_sized(type, 4) \
842 intra_pred_sized(type, 8) \
843 intra_pred_sized(type, 16) \
844 intra_pred_sized(type, 32) \
845 intra_pred_highbd_sized(type, 4) \
846 intra_pred_highbd_sized(type, 8) \
847 intra_pred_highbd_sized(type, 16) \
848 intra_pred_highbd_sized(type, 32)
849
Jingning Hane3954d82016-10-12 21:03:18 -0700850#define intra_pred_above_4x4(type) \
Yaowu Xuc27fc142016-08-22 16:08:15 -0700851 intra_pred_sized(type, 8) \
852 intra_pred_sized(type, 16) \
853 intra_pred_sized(type, 32) \
854 intra_pred_highbd_sized(type, 4) \
855 intra_pred_highbd_sized(type, 8) \
856 intra_pred_highbd_sized(type, 16) \
857 intra_pred_highbd_sized(type, 32)
858
859#else
860#define intra_pred_allsizes(type) \
Jingning Hane3954d82016-10-12 21:03:18 -0700861 intra_pred_sized(type, 2) \
Yaowu Xuc27fc142016-08-22 16:08:15 -0700862 intra_pred_sized(type, 4) \
863 intra_pred_sized(type, 8) \
864 intra_pred_sized(type, 16) \
865 intra_pred_sized(type, 32)
866
Jingning Hane3954d82016-10-12 21:03:18 -0700867#define intra_pred_above_4x4(type) \
Yaowu Xuc27fc142016-08-22 16:08:15 -0700868 intra_pred_sized(type, 8) \
869 intra_pred_sized(type, 16) \
870 intra_pred_sized(type, 32)
Yaowu Xuf883b422016-08-30 14:01:10 -0700871#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700872
Jingning Hane3954d82016-10-12 21:03:18 -0700873intra_pred_above_4x4(d207)
874intra_pred_above_4x4(d63)
875intra_pred_above_4x4(d45)
Yaowu Xuc27fc142016-08-22 16:08:15 -0700876intra_pred_allsizes(d207e)
877intra_pred_allsizes(d63e)
Jingning Hane3954d82016-10-12 21:03:18 -0700878intra_pred_above_4x4(d45e)
879intra_pred_above_4x4(d117)
880intra_pred_above_4x4(d135)
881intra_pred_above_4x4(d153)
Yaowu Xuc27fc142016-08-22 16:08:15 -0700882intra_pred_allsizes(v)
883intra_pred_allsizes(h)
Urvang Joshi340593e2016-09-01 12:03:20 -0700884#if CONFIG_ALT_INTRA
885intra_pred_allsizes(paeth)
886#else
Yaowu Xuc27fc142016-08-22 16:08:15 -0700887intra_pred_allsizes(tm)
Urvang Joshi340593e2016-09-01 12:03:20 -0700888#endif // CONFIG_ALT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -0700889intra_pred_allsizes(dc_128)
890intra_pred_allsizes(dc_left)
891intra_pred_allsizes(dc_top)
892intra_pred_allsizes(dc)
893/* clang-format on */
894#undef intra_pred_allsizes