blob: 29b5a74ccb51f6b99f91f40bc83e67fb1bab4b15 [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
Jingning Han03b35142016-10-19 13:04:26 -0700324void aom_he_predictor_2x2_c(uint8_t *dst, ptrdiff_t stride,
325 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
331 memset(dst + stride * 0, AVG3(H, I, J), 2);
332 memset(dst + stride * 1, AVG3(I, J, K), 2);
333}
334
335void aom_ve_predictor_2x2_c(uint8_t *dst, ptrdiff_t stride,
336 const uint8_t *above, const uint8_t *left) {
337 const int H = above[-1];
338 const int I = above[0];
339 const int J = above[1];
340 const int K = above[2];
Angie Chiang646e52a2016-10-21 11:45:31 -0700341 (void)left;
Jingning Han03b35142016-10-19 13:04:26 -0700342
343 dst[0] = AVG3(H, I, J);
344 dst[1] = AVG3(I, J, K);
345 memcpy(dst + stride * 1, dst, 2);
346}
347
348void aom_d207_predictor_2x2_c(uint8_t *dst, ptrdiff_t stride,
349 const uint8_t *above, const uint8_t *left) {
350 const int I = left[0];
351 const int J = left[1];
352 const int K = left[2];
353 const int L = left[3];
354 (void)above;
355 DST(0, 0) = AVG2(I, J);
356 DST(0, 1) = AVG2(J, K);
357 DST(1, 0) = AVG3(I, J, K);
358 DST(1, 1) = AVG3(J, K, L);
359}
360
361void aom_d63_predictor_2x2_c(uint8_t *dst, ptrdiff_t stride,
362 const uint8_t *above, const uint8_t *left) {
363 const int A = above[0];
364 const int B = above[1];
365 const int C = above[2];
366 const int D = above[3];
367 (void)left;
368 DST(0, 0) = AVG2(A, B);
369 DST(1, 0) = AVG2(B, C);
370 DST(0, 1) = AVG3(A, B, C);
371 DST(1, 1) = AVG3(B, C, D);
372}
373
374void aom_d63f_predictor_2x2_c(uint8_t *dst, ptrdiff_t stride,
375 const uint8_t *above, const uint8_t *left) {
376 const int A = above[0];
377 const int B = above[1];
378 const int C = above[2];
379 const int D = above[3];
380 (void)left;
381 DST(0, 0) = AVG2(A, B);
382 DST(1, 0) = AVG2(B, C);
383 DST(0, 1) = AVG3(A, B, C);
384 DST(1, 1) = AVG3(B, C, D);
385}
386
387void aom_d45_predictor_2x2_c(uint8_t *dst, ptrdiff_t stride,
388 const uint8_t *above, const uint8_t *left) {
389 const int A = above[0];
390 const int B = above[1];
391 const int C = above[2];
392 const int D = above[3];
393 const int E = above[4];
394 (void)stride;
395 (void)left;
396 DST(0, 0) = AVG3(A, B, C);
397 DST(1, 0) = DST(0, 1) = AVG3(B, C, D);
398 DST(1, 1) = AVG3(C, D, E);
399}
400
401void aom_d45e_predictor_2x2_c(uint8_t *dst, ptrdiff_t stride,
402 const uint8_t *above, const uint8_t *left) {
403 const int A = above[0];
404 const int B = above[1];
405 const int C = above[2];
406 const int D = above[3];
407 const int E = above[4];
408 (void)stride;
409 (void)left;
410 DST(0, 0) = AVG3(A, B, C);
411 DST(1, 0) = DST(0, 1) = AVG3(B, C, D);
412 DST(1, 1) = AVG3(C, D, E);
413}
414
415void aom_d117_predictor_2x2_c(uint8_t *dst, ptrdiff_t stride,
416 const uint8_t *above, const uint8_t *left) {
417 const int I = left[0];
418 const int X = above[-1];
419 const int A = above[0];
420 const int B = above[1];
421 DST(0, 0) = AVG2(X, A);
422 DST(1, 0) = AVG2(A, B);
423 DST(0, 1) = AVG3(I, X, A);
424 DST(1, 1) = AVG3(X, A, B);
425}
426
427void aom_d135_predictor_2x2_c(uint8_t *dst, ptrdiff_t stride,
428 const uint8_t *above, const uint8_t *left) {
429 const int I = left[0];
430 const int J = left[1];
431 const int X = above[-1];
432 const int A = above[0];
433 const int B = above[1];
434 (void)stride;
435 DST(0, 1) = AVG3(X, I, J);
436 DST(1, 1) = DST(0, 0) = AVG3(A, X, I);
437 DST(1, 0) = AVG3(B, A, X);
438}
439
440void aom_d153_predictor_2x2_c(uint8_t *dst, ptrdiff_t stride,
441 const uint8_t *above, const uint8_t *left) {
442 const int I = left[0];
443 const int J = left[1];
444 const int X = above[-1];
445 const int A = above[0];
446
447 DST(0, 0) = AVG2(I, X);
448 DST(0, 1) = AVG2(J, I);
449 DST(1, 0) = AVG3(I, X, A);
450 DST(1, 1) = AVG3(J, I, X);
451}
452
Yaowu Xuf883b422016-08-30 14:01:10 -0700453void aom_he_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700454 const uint8_t *above, const uint8_t *left) {
455 const int H = above[-1];
456 const int I = left[0];
457 const int J = left[1];
458 const int K = left[2];
459 const int L = left[3];
460
461 memset(dst + stride * 0, AVG3(H, I, J), 4);
462 memset(dst + stride * 1, AVG3(I, J, K), 4);
463 memset(dst + stride * 2, AVG3(J, K, L), 4);
464 memset(dst + stride * 3, AVG3(K, L, L), 4);
465}
466
Yaowu Xuf883b422016-08-30 14:01:10 -0700467void aom_ve_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700468 const uint8_t *above, const uint8_t *left) {
469 const int H = above[-1];
470 const int I = above[0];
471 const int J = above[1];
472 const int K = above[2];
473 const int L = above[3];
474 const int M = above[4];
475 (void)left;
476
477 dst[0] = AVG3(H, I, J);
478 dst[1] = AVG3(I, J, K);
479 dst[2] = AVG3(J, K, L);
480 dst[3] = AVG3(K, L, M);
481 memcpy(dst + stride * 1, dst, 4);
482 memcpy(dst + stride * 2, dst, 4);
483 memcpy(dst + stride * 3, dst, 4);
484}
485
Yaowu Xuf883b422016-08-30 14:01:10 -0700486void aom_d207_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700487 const uint8_t *above, const uint8_t *left) {
488 const int I = left[0];
489 const int J = left[1];
490 const int K = left[2];
491 const int L = left[3];
492 (void)above;
493 DST(0, 0) = AVG2(I, J);
494 DST(2, 0) = DST(0, 1) = AVG2(J, K);
495 DST(2, 1) = DST(0, 2) = AVG2(K, L);
496 DST(1, 0) = AVG3(I, J, K);
497 DST(3, 0) = DST(1, 1) = AVG3(J, K, L);
498 DST(3, 1) = DST(1, 2) = AVG3(K, L, L);
499 DST(3, 2) = DST(2, 2) = DST(0, 3) = DST(1, 3) = DST(2, 3) = DST(3, 3) = L;
500}
501
Yaowu Xuf883b422016-08-30 14:01:10 -0700502void aom_d63_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700503 const uint8_t *above, const uint8_t *left) {
504 const int A = above[0];
505 const int B = above[1];
506 const int C = above[2];
507 const int D = above[3];
508 const int E = above[4];
509 const int F = above[5];
510 const int G = above[6];
511 (void)left;
512 DST(0, 0) = AVG2(A, B);
513 DST(1, 0) = DST(0, 2) = AVG2(B, C);
514 DST(2, 0) = DST(1, 2) = AVG2(C, D);
515 DST(3, 0) = DST(2, 2) = AVG2(D, E);
516 DST(3, 2) = AVG2(E, F); // differs from vp8
517
518 DST(0, 1) = AVG3(A, B, C);
519 DST(1, 1) = DST(0, 3) = AVG3(B, C, D);
520 DST(2, 1) = DST(1, 3) = AVG3(C, D, E);
521 DST(3, 1) = DST(2, 3) = AVG3(D, E, F);
522 DST(3, 3) = AVG3(E, F, G); // differs from vp8
523}
524
Yaowu Xuf883b422016-08-30 14:01:10 -0700525void aom_d63f_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700526 const uint8_t *above, const uint8_t *left) {
527 const int A = above[0];
528 const int B = above[1];
529 const int C = above[2];
530 const int D = above[3];
531 const int E = above[4];
532 const int F = above[5];
533 const int G = above[6];
534 const int H = above[7];
535 (void)left;
536 DST(0, 0) = AVG2(A, B);
537 DST(1, 0) = DST(0, 2) = AVG2(B, C);
538 DST(2, 0) = DST(1, 2) = AVG2(C, D);
539 DST(3, 0) = DST(2, 2) = AVG2(D, E);
540 DST(3, 2) = AVG3(E, F, G);
541
542 DST(0, 1) = AVG3(A, B, C);
543 DST(1, 1) = DST(0, 3) = AVG3(B, C, D);
544 DST(2, 1) = DST(1, 3) = AVG3(C, D, E);
545 DST(3, 1) = DST(2, 3) = AVG3(D, E, F);
546 DST(3, 3) = AVG3(F, G, H);
547}
548
Yaowu Xuf883b422016-08-30 14:01:10 -0700549void aom_d45_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700550 const uint8_t *above, const uint8_t *left) {
551 const int A = above[0];
552 const int B = above[1];
553 const int C = above[2];
554 const int D = above[3];
555 const int E = above[4];
556 const int F = above[5];
557 const int G = above[6];
558 const int H = above[7];
559 (void)stride;
560 (void)left;
561 DST(0, 0) = AVG3(A, B, C);
562 DST(1, 0) = DST(0, 1) = AVG3(B, C, D);
563 DST(2, 0) = DST(1, 1) = DST(0, 2) = AVG3(C, D, E);
564 DST(3, 0) = DST(2, 1) = DST(1, 2) = DST(0, 3) = AVG3(D, E, F);
565 DST(3, 1) = DST(2, 2) = DST(1, 3) = AVG3(E, F, G);
566 DST(3, 2) = DST(2, 3) = AVG3(F, G, H);
567 DST(3, 3) = H; // differs from vp8
568}
569
Yaowu Xuf883b422016-08-30 14:01:10 -0700570void aom_d45e_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700571 const uint8_t *above, const uint8_t *left) {
572 const int A = above[0];
573 const int B = above[1];
574 const int C = above[2];
575 const int D = above[3];
576 const int E = above[4];
577 const int F = above[5];
578 const int G = above[6];
579 const int H = above[7];
580 (void)stride;
581 (void)left;
582 DST(0, 0) = AVG3(A, B, C);
583 DST(1, 0) = DST(0, 1) = AVG3(B, C, D);
584 DST(2, 0) = DST(1, 1) = DST(0, 2) = AVG3(C, D, E);
585 DST(3, 0) = DST(2, 1) = DST(1, 2) = DST(0, 3) = AVG3(D, E, F);
586 DST(3, 1) = DST(2, 2) = DST(1, 3) = AVG3(E, F, G);
587 DST(3, 2) = DST(2, 3) = AVG3(F, G, H);
588 DST(3, 3) = AVG3(G, H, H);
589}
590
Yaowu Xuf883b422016-08-30 14:01:10 -0700591void aom_d117_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700592 const uint8_t *above, const uint8_t *left) {
593 const int I = left[0];
594 const int J = left[1];
595 const int K = left[2];
596 const int X = above[-1];
597 const int A = above[0];
598 const int B = above[1];
599 const int C = above[2];
600 const int D = above[3];
601 DST(0, 0) = DST(1, 2) = AVG2(X, A);
602 DST(1, 0) = DST(2, 2) = AVG2(A, B);
603 DST(2, 0) = DST(3, 2) = AVG2(B, C);
604 DST(3, 0) = AVG2(C, D);
605
606 DST(0, 3) = AVG3(K, J, I);
607 DST(0, 2) = AVG3(J, I, X);
608 DST(0, 1) = DST(1, 3) = AVG3(I, X, A);
609 DST(1, 1) = DST(2, 3) = AVG3(X, A, B);
610 DST(2, 1) = DST(3, 3) = AVG3(A, B, C);
611 DST(3, 1) = AVG3(B, C, D);
612}
613
Yaowu Xuf883b422016-08-30 14:01:10 -0700614void aom_d135_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700615 const uint8_t *above, const uint8_t *left) {
616 const int I = left[0];
617 const int J = left[1];
618 const int K = left[2];
619 const int L = left[3];
620 const int X = above[-1];
621 const int A = above[0];
622 const int B = above[1];
623 const int C = above[2];
624 const int D = above[3];
625 (void)stride;
626 DST(0, 3) = AVG3(J, K, L);
627 DST(1, 3) = DST(0, 2) = AVG3(I, J, K);
628 DST(2, 3) = DST(1, 2) = DST(0, 1) = AVG3(X, I, J);
629 DST(3, 3) = DST(2, 2) = DST(1, 1) = DST(0, 0) = AVG3(A, X, I);
630 DST(3, 2) = DST(2, 1) = DST(1, 0) = AVG3(B, A, X);
631 DST(3, 1) = DST(2, 0) = AVG3(C, B, A);
632 DST(3, 0) = AVG3(D, C, B);
633}
634
Yaowu Xuf883b422016-08-30 14:01:10 -0700635void aom_d153_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700636 const uint8_t *above, const uint8_t *left) {
637 const int I = left[0];
638 const int J = left[1];
639 const int K = left[2];
640 const int L = left[3];
641 const int X = above[-1];
642 const int A = above[0];
643 const int B = above[1];
644 const int C = above[2];
645
646 DST(0, 0) = DST(2, 1) = AVG2(I, X);
647 DST(0, 1) = DST(2, 2) = AVG2(J, I);
648 DST(0, 2) = DST(2, 3) = AVG2(K, J);
649 DST(0, 3) = AVG2(L, K);
650
651 DST(3, 0) = AVG3(A, B, C);
652 DST(2, 0) = AVG3(X, A, B);
653 DST(1, 0) = DST(3, 1) = AVG3(I, X, A);
654 DST(1, 1) = DST(3, 2) = AVG3(J, I, X);
655 DST(1, 2) = DST(3, 3) = AVG3(K, J, I);
656 DST(1, 3) = AVG3(L, K, J);
657}
658
Yaowu Xuf883b422016-08-30 14:01:10 -0700659#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700660static INLINE void highbd_d207_predictor(uint16_t *dst, ptrdiff_t stride,
661 int bs, const uint16_t *above,
662 const uint16_t *left, int bd) {
663 int r, c;
664 (void)above;
665 (void)bd;
666
667 // First column.
668 for (r = 0; r < bs - 1; ++r) {
669 dst[r * stride] = AVG2(left[r], left[r + 1]);
670 }
671 dst[(bs - 1) * stride] = left[bs - 1];
672 dst++;
673
674 // Second column.
675 for (r = 0; r < bs - 2; ++r) {
676 dst[r * stride] = AVG3(left[r], left[r + 1], left[r + 2]);
677 }
678 dst[(bs - 2) * stride] = AVG3(left[bs - 2], left[bs - 1], left[bs - 1]);
679 dst[(bs - 1) * stride] = left[bs - 1];
680 dst++;
681
682 // Rest of last row.
683 for (c = 0; c < bs - 2; ++c) dst[(bs - 1) * stride + c] = left[bs - 1];
684
685 for (r = bs - 2; r >= 0; --r) {
686 for (c = 0; c < bs - 2; ++c)
687 dst[r * stride + c] = dst[(r + 1) * stride + c - 2];
688 }
689}
690
691static INLINE void highbd_d207e_predictor(uint16_t *dst, ptrdiff_t stride,
692 int bs, const uint16_t *above,
693 const uint16_t *left, int bd) {
694 int r, c;
695 (void)above;
696 (void)bd;
697
698 for (r = 0; r < bs; ++r) {
699 for (c = 0; c < bs; ++c) {
700 dst[c] = c & 1 ? AVG3(left[(c >> 1) + r], left[(c >> 1) + r + 1],
701 left[(c >> 1) + r + 2])
702 : AVG2(left[(c >> 1) + r], left[(c >> 1) + r + 1]);
703 }
704 dst += stride;
705 }
706}
707
708static INLINE void highbd_d63_predictor(uint16_t *dst, ptrdiff_t stride, int bs,
709 const uint16_t *above,
710 const uint16_t *left, int bd) {
711 int r, c;
712 (void)left;
713 (void)bd;
714 for (r = 0; r < bs; ++r) {
715 for (c = 0; c < bs; ++c) {
716 dst[c] = r & 1 ? AVG3(above[(r >> 1) + c], above[(r >> 1) + c + 1],
717 above[(r >> 1) + c + 2])
718 : AVG2(above[(r >> 1) + c], above[(r >> 1) + c + 1]);
719 }
720 dst += stride;
721 }
722}
723
724#define highbd_d63e_predictor highbd_d63_predictor
725
726static INLINE void highbd_d45_predictor(uint16_t *dst, ptrdiff_t stride, int bs,
727 const uint16_t *above,
728 const uint16_t *left, int bd) {
729 int r, c;
730 (void)left;
731 (void)bd;
732 for (r = 0; r < bs; ++r) {
733 for (c = 0; c < bs; ++c) {
734 dst[c] = r + c + 2 < bs * 2
735 ? AVG3(above[r + c], above[r + c + 1], above[r + c + 2])
736 : above[bs * 2 - 1];
737 }
738 dst += stride;
739 }
740}
741
742static INLINE void highbd_d45e_predictor(uint16_t *dst, ptrdiff_t stride,
743 int bs, const uint16_t *above,
744 const uint16_t *left, int bd) {
745 int r, c;
746 (void)left;
747 (void)bd;
748 for (r = 0; r < bs; ++r) {
749 for (c = 0; c < bs; ++c) {
750 dst[c] = AVG3(above[r + c], above[r + c + 1],
751 above[r + c + 1 + (r + c + 2 < bs * 2)]);
752 }
753 dst += stride;
754 }
755}
756
757static INLINE void highbd_d117_predictor(uint16_t *dst, ptrdiff_t stride,
758 int bs, const uint16_t *above,
759 const uint16_t *left, int bd) {
760 int r, c;
761 (void)bd;
762
763 // first row
764 for (c = 0; c < bs; c++) dst[c] = AVG2(above[c - 1], above[c]);
765 dst += stride;
766
767 // second row
768 dst[0] = AVG3(left[0], above[-1], above[0]);
769 for (c = 1; c < bs; c++) dst[c] = AVG3(above[c - 2], above[c - 1], above[c]);
770 dst += stride;
771
772 // the rest of first col
773 dst[0] = AVG3(above[-1], left[0], left[1]);
774 for (r = 3; r < bs; ++r)
775 dst[(r - 2) * stride] = AVG3(left[r - 3], left[r - 2], left[r - 1]);
776
777 // the rest of the block
778 for (r = 2; r < bs; ++r) {
779 for (c = 1; c < bs; c++) dst[c] = dst[-2 * stride + c - 1];
780 dst += stride;
781 }
782}
783
784static INLINE void highbd_d135_predictor(uint16_t *dst, ptrdiff_t stride,
785 int bs, const uint16_t *above,
786 const uint16_t *left, int bd) {
787 int r, c;
788 (void)bd;
789 dst[0] = AVG3(left[0], above[-1], above[0]);
790 for (c = 1; c < bs; c++) dst[c] = AVG3(above[c - 2], above[c - 1], above[c]);
791
792 dst[stride] = AVG3(above[-1], left[0], left[1]);
793 for (r = 2; r < bs; ++r)
794 dst[r * stride] = AVG3(left[r - 2], left[r - 1], left[r]);
795
796 dst += stride;
797 for (r = 1; r < bs; ++r) {
798 for (c = 1; c < bs; c++) dst[c] = dst[-stride + c - 1];
799 dst += stride;
800 }
801}
802
803static INLINE void highbd_d153_predictor(uint16_t *dst, ptrdiff_t stride,
804 int bs, const uint16_t *above,
805 const uint16_t *left, int bd) {
806 int r, c;
807 (void)bd;
808 dst[0] = AVG2(above[-1], left[0]);
809 for (r = 1; r < bs; r++) dst[r * stride] = AVG2(left[r - 1], left[r]);
810 dst++;
811
812 dst[0] = AVG3(left[0], above[-1], above[0]);
813 dst[stride] = AVG3(above[-1], left[0], left[1]);
814 for (r = 2; r < bs; r++)
815 dst[r * stride] = AVG3(left[r - 2], left[r - 1], left[r]);
816 dst++;
817
818 for (c = 0; c < bs - 2; c++)
819 dst[c] = AVG3(above[c - 1], above[c], above[c + 1]);
820 dst += stride;
821
822 for (r = 1; r < bs; ++r) {
823 for (c = 0; c < bs - 2; c++) dst[c] = dst[-stride + c - 2];
824 dst += stride;
825 }
826}
827
828static INLINE void highbd_v_predictor(uint16_t *dst, ptrdiff_t stride, int bs,
829 const uint16_t *above,
830 const uint16_t *left, int bd) {
831 int r;
832 (void)left;
833 (void)bd;
834 for (r = 0; r < bs; r++) {
835 memcpy(dst, above, bs * sizeof(uint16_t));
836 dst += stride;
837 }
838}
839
840static INLINE void highbd_h_predictor(uint16_t *dst, ptrdiff_t stride, int bs,
841 const uint16_t *above,
842 const uint16_t *left, int bd) {
843 int r;
844 (void)above;
845 (void)bd;
846 for (r = 0; r < bs; r++) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700847 aom_memset16(dst, left[r], bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700848 dst += stride;
849 }
850}
851
Urvang Joshi340593e2016-09-01 12:03:20 -0700852#if CONFIG_ALT_INTRA
853static INLINE void highbd_paeth_predictor(uint16_t *dst, ptrdiff_t stride,
854 int bs, const uint16_t *above,
855 const uint16_t *left, int bd) {
856 int r, c;
857 const uint16_t ytop_left = above[-1];
858 (void)bd;
859
860 for (r = 0; r < bs; r++) {
861 for (c = 0; c < bs; c++)
862 dst[c] = paeth_predictor_single(left[r], above[c], ytop_left);
863 dst += stride;
864 }
865}
866
867#else
Yaowu Xuc27fc142016-08-22 16:08:15 -0700868static INLINE void highbd_tm_predictor(uint16_t *dst, ptrdiff_t stride, int bs,
869 const uint16_t *above,
870 const uint16_t *left, int bd) {
871 int r, c;
872 int ytop_left = above[-1];
873 (void)bd;
874
875 for (r = 0; r < bs; r++) {
876 for (c = 0; c < bs; c++)
877 dst[c] = clip_pixel_highbd(left[r] + above[c] - ytop_left, bd);
878 dst += stride;
879 }
880}
Urvang Joshi340593e2016-09-01 12:03:20 -0700881#endif // CONFIG_ALT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -0700882
883static INLINE void highbd_dc_128_predictor(uint16_t *dst, ptrdiff_t stride,
884 int bs, const uint16_t *above,
885 const uint16_t *left, int bd) {
886 int r;
887 (void)above;
888 (void)left;
889
890 for (r = 0; r < bs; r++) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700891 aom_memset16(dst, 128 << (bd - 8), bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700892 dst += stride;
893 }
894}
895
896static INLINE void highbd_dc_left_predictor(uint16_t *dst, ptrdiff_t stride,
897 int bs, const uint16_t *above,
898 const uint16_t *left, int bd) {
899 int i, r, expected_dc, sum = 0;
900 (void)above;
901 (void)bd;
902
903 for (i = 0; i < bs; i++) sum += left[i];
904 expected_dc = (sum + (bs >> 1)) / bs;
905
906 for (r = 0; r < bs; r++) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700907 aom_memset16(dst, expected_dc, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700908 dst += stride;
909 }
910}
911
912static INLINE void highbd_dc_top_predictor(uint16_t *dst, ptrdiff_t stride,
913 int bs, const uint16_t *above,
914 const uint16_t *left, int bd) {
915 int i, r, expected_dc, sum = 0;
916 (void)left;
917 (void)bd;
918
919 for (i = 0; i < bs; i++) sum += above[i];
920 expected_dc = (sum + (bs >> 1)) / bs;
921
922 for (r = 0; r < bs; r++) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700923 aom_memset16(dst, expected_dc, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700924 dst += stride;
925 }
926}
927
928static INLINE void highbd_dc_predictor(uint16_t *dst, ptrdiff_t stride, int bs,
929 const uint16_t *above,
930 const uint16_t *left, int bd) {
931 int i, r, expected_dc, sum = 0;
932 const int count = 2 * bs;
933 (void)bd;
934
935 for (i = 0; i < bs; i++) {
936 sum += above[i];
937 sum += left[i];
938 }
939
940 expected_dc = (sum + (count >> 1)) / count;
941
942 for (r = 0; r < bs; r++) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700943 aom_memset16(dst, expected_dc, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700944 dst += stride;
945 }
946}
Yaowu Xuf883b422016-08-30 14:01:10 -0700947#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700948
949// This serves as a wrapper function, so that all the prediction functions
950// can be unified and accessed as a pointer array. Note that the boundary
951// above and left are not necessarily used all the time.
952#define intra_pred_sized(type, size) \
Yaowu Xuf883b422016-08-30 14:01:10 -0700953 void aom_##type##_predictor_##size##x##size##_c( \
Yaowu Xuc27fc142016-08-22 16:08:15 -0700954 uint8_t *dst, ptrdiff_t stride, const uint8_t *above, \
955 const uint8_t *left) { \
956 type##_predictor(dst, stride, size, above, left); \
957 }
958
Yaowu Xuf883b422016-08-30 14:01:10 -0700959#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700960#define intra_pred_highbd_sized(type, size) \
Yaowu Xuf883b422016-08-30 14:01:10 -0700961 void aom_highbd_##type##_predictor_##size##x##size##_c( \
Yaowu Xuc27fc142016-08-22 16:08:15 -0700962 uint16_t *dst, ptrdiff_t stride, const uint16_t *above, \
963 const uint16_t *left, int bd) { \
964 highbd_##type##_predictor(dst, stride, size, above, left, bd); \
965 }
966
967/* clang-format off */
968#define intra_pred_allsizes(type) \
Jingning Hane3954d82016-10-12 21:03:18 -0700969 intra_pred_sized(type, 2) \
Yaowu Xuc27fc142016-08-22 16:08:15 -0700970 intra_pred_sized(type, 4) \
971 intra_pred_sized(type, 8) \
972 intra_pred_sized(type, 16) \
973 intra_pred_sized(type, 32) \
974 intra_pred_highbd_sized(type, 4) \
975 intra_pred_highbd_sized(type, 8) \
976 intra_pred_highbd_sized(type, 16) \
977 intra_pred_highbd_sized(type, 32)
978
Jingning Hane3954d82016-10-12 21:03:18 -0700979#define intra_pred_above_4x4(type) \
Yaowu Xuc27fc142016-08-22 16:08:15 -0700980 intra_pred_sized(type, 8) \
981 intra_pred_sized(type, 16) \
982 intra_pred_sized(type, 32) \
983 intra_pred_highbd_sized(type, 4) \
984 intra_pred_highbd_sized(type, 8) \
985 intra_pred_highbd_sized(type, 16) \
986 intra_pred_highbd_sized(type, 32)
987
988#else
989#define intra_pred_allsizes(type) \
Jingning Hane3954d82016-10-12 21:03:18 -0700990 intra_pred_sized(type, 2) \
Yaowu Xuc27fc142016-08-22 16:08:15 -0700991 intra_pred_sized(type, 4) \
992 intra_pred_sized(type, 8) \
993 intra_pred_sized(type, 16) \
994 intra_pred_sized(type, 32)
995
Jingning Hane3954d82016-10-12 21:03:18 -0700996#define intra_pred_above_4x4(type) \
Yaowu Xuc27fc142016-08-22 16:08:15 -0700997 intra_pred_sized(type, 8) \
998 intra_pred_sized(type, 16) \
999 intra_pred_sized(type, 32)
Yaowu Xuf883b422016-08-30 14:01:10 -07001000#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001001
Jingning Hane3954d82016-10-12 21:03:18 -07001002intra_pred_above_4x4(d207)
1003intra_pred_above_4x4(d63)
1004intra_pred_above_4x4(d45)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001005intra_pred_allsizes(d207e)
1006intra_pred_allsizes(d63e)
Jingning Hane3954d82016-10-12 21:03:18 -07001007intra_pred_above_4x4(d45e)
1008intra_pred_above_4x4(d117)
1009intra_pred_above_4x4(d135)
1010intra_pred_above_4x4(d153)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001011intra_pred_allsizes(v)
1012intra_pred_allsizes(h)
Urvang Joshi340593e2016-09-01 12:03:20 -07001013#if CONFIG_ALT_INTRA
1014intra_pred_allsizes(paeth)
1015#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07001016intra_pred_allsizes(tm)
Urvang Joshi340593e2016-09-01 12:03:20 -07001017#endif // CONFIG_ALT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07001018intra_pred_allsizes(dc_128)
1019intra_pred_allsizes(dc_left)
1020intra_pred_allsizes(dc_top)
1021intra_pred_allsizes(dc)
1022/* clang-format on */
1023#undef intra_pred_allsizes