blob: 50b6a081bbc9d798878861458fa32fde1d682116 [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
Urvang Joshi7a406002017-01-31 14:52:18 -080012#include <assert.h>
Urvang Joshi6be4a542016-11-03 15:24:05 -070013#include <math.h>
14
Yaowu Xuf883b422016-08-30 14:01:10 -070015#include "./aom_config.h"
16#include "./aom_dsp_rtcd.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070017
Yaowu Xuf883b422016-08-30 14:01:10 -070018#include "aom_dsp/aom_dsp_common.h"
19#include "aom_mem/aom_mem.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070020
21#define DST(x, y) dst[(x) + (y)*stride]
22#define AVG3(a, b, c) (((a) + 2 * (b) + (c) + 2) >> 2)
23#define AVG2(a, b) (((a) + (b) + 1) >> 1)
24
25static INLINE void d207_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
26 const uint8_t *above, const uint8_t *left) {
27 int r, c;
28 (void)above;
29 // first column
30 for (r = 0; r < bs - 1; ++r) dst[r * stride] = AVG2(left[r], left[r + 1]);
31 dst[(bs - 1) * stride] = left[bs - 1];
32 dst++;
33
34 // second column
35 for (r = 0; r < bs - 2; ++r)
36 dst[r * stride] = AVG3(left[r], left[r + 1], left[r + 2]);
37 dst[(bs - 2) * stride] = AVG3(left[bs - 2], left[bs - 1], left[bs - 1]);
38 dst[(bs - 1) * stride] = left[bs - 1];
39 dst++;
40
41 // rest of last row
42 for (c = 0; c < bs - 2; ++c) dst[(bs - 1) * stride + c] = left[bs - 1];
43
44 for (r = bs - 2; r >= 0; --r)
45 for (c = 0; c < bs - 2; ++c)
46 dst[r * stride + c] = dst[(r + 1) * stride + c - 2];
47}
48
49static INLINE void d207e_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
50 const uint8_t *above, const uint8_t *left) {
51 int r, c;
52 (void)above;
53
54 for (r = 0; r < bs; ++r) {
55 for (c = 0; c < bs; ++c) {
56 dst[c] = c & 1 ? AVG3(left[(c >> 1) + r], left[(c >> 1) + r + 1],
57 left[(c >> 1) + r + 2])
58 : AVG2(left[(c >> 1) + r], left[(c >> 1) + r + 1]);
59 }
60 dst += stride;
61 }
62}
63
64static INLINE void d63_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
65 const uint8_t *above, const uint8_t *left) {
66 int r, c;
67 int size;
68 (void)left;
69 for (c = 0; c < bs; ++c) {
70 dst[c] = AVG2(above[c], above[c + 1]);
71 dst[stride + c] = AVG3(above[c], above[c + 1], above[c + 2]);
72 }
73 for (r = 2, size = bs - 2; r < bs; r += 2, --size) {
74 memcpy(dst + (r + 0) * stride, dst + (r >> 1), size);
75 memset(dst + (r + 0) * stride + size, above[bs - 1], bs - size);
76 memcpy(dst + (r + 1) * stride, dst + stride + (r >> 1), size);
77 memset(dst + (r + 1) * stride + size, above[bs - 1], bs - size);
78 }
79}
80
81static INLINE void d63e_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
82 const uint8_t *above, const uint8_t *left) {
83 int r, c;
84 (void)left;
85 for (r = 0; r < bs; ++r) {
86 for (c = 0; c < bs; ++c) {
87 dst[c] = r & 1 ? AVG3(above[(r >> 1) + c], above[(r >> 1) + c + 1],
88 above[(r >> 1) + c + 2])
89 : AVG2(above[(r >> 1) + c], above[(r >> 1) + c + 1]);
90 }
91 dst += stride;
92 }
93}
94
95static INLINE void d45_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
96 const uint8_t *above, const uint8_t *left) {
97 const uint8_t above_right = above[bs - 1];
98 const uint8_t *const dst_row0 = dst;
99 int x, size;
100 (void)left;
101
102 for (x = 0; x < bs - 1; ++x) {
103 dst[x] = AVG3(above[x], above[x + 1], above[x + 2]);
104 }
105 dst[bs - 1] = above_right;
106 dst += stride;
107 for (x = 1, size = bs - 2; x < bs; ++x, --size) {
108 memcpy(dst, dst_row0 + x, size);
109 memset(dst + size, above_right, x + 1);
110 dst += stride;
111 }
112}
113
114static INLINE void d45e_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
115 const uint8_t *above, const uint8_t *left) {
116 int r, c;
117 (void)left;
118 for (r = 0; r < bs; ++r) {
119 for (c = 0; c < bs; ++c) {
120 dst[c] = AVG3(above[r + c], above[r + c + 1],
121 above[r + c + 1 + (r + c + 2 < bs * 2)]);
122 }
123 dst += stride;
124 }
125}
126
127static INLINE void d117_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
128 const uint8_t *above, const uint8_t *left) {
129 int r, c;
130
131 // first row
132 for (c = 0; c < bs; c++) dst[c] = AVG2(above[c - 1], above[c]);
133 dst += stride;
134
135 // second row
136 dst[0] = AVG3(left[0], above[-1], above[0]);
137 for (c = 1; c < bs; c++) dst[c] = AVG3(above[c - 2], above[c - 1], above[c]);
138 dst += stride;
139
140 // the rest of first col
141 dst[0] = AVG3(above[-1], left[0], left[1]);
142 for (r = 3; r < bs; ++r)
143 dst[(r - 2) * stride] = AVG3(left[r - 3], left[r - 2], left[r - 1]);
144
145 // the rest of the block
146 for (r = 2; r < bs; ++r) {
147 for (c = 1; c < bs; c++) dst[c] = dst[-2 * stride + c - 1];
148 dst += stride;
149 }
150}
151
152static INLINE void d135_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
153 const uint8_t *above, const uint8_t *left) {
154 int i;
Debargha Mukherjee84c56af2016-11-19 10:59:37 -0800155#if CONFIG_TX64X64
156#if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ > 7
157 // silence a spurious -Warray-bounds warning, possibly related to:
158 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56273
159 uint8_t border[133];
160#else
161 uint8_t border[64 + 64 - 1]; // outer border from bottom-left to top-right
162#endif
163#else
Yaowu Xuc27fc142016-08-22 16:08:15 -0700164#if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ > 7
165 // silence a spurious -Warray-bounds warning, possibly related to:
166 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56273
167 uint8_t border[69];
168#else
169 uint8_t border[32 + 32 - 1]; // outer border from bottom-left to top-right
170#endif
Debargha Mukherjee84c56af2016-11-19 10:59:37 -0800171#endif // CONFIG_TX64X64
Yaowu Xuc27fc142016-08-22 16:08:15 -0700172
173 // dst(bs, bs - 2)[0], i.e., border starting at bottom-left
174 for (i = 0; i < bs - 2; ++i) {
175 border[i] = AVG3(left[bs - 3 - i], left[bs - 2 - i], left[bs - 1 - i]);
176 }
177 border[bs - 2] = AVG3(above[-1], left[0], left[1]);
178 border[bs - 1] = AVG3(left[0], above[-1], above[0]);
179 border[bs - 0] = AVG3(above[-1], above[0], above[1]);
180 // dst[0][2, size), i.e., remaining top border ascending
181 for (i = 0; i < bs - 2; ++i) {
182 border[bs + 1 + i] = AVG3(above[i], above[i + 1], above[i + 2]);
183 }
184
185 for (i = 0; i < bs; ++i) {
186 memcpy(dst + i * stride, border + bs - 1 - i, bs);
187 }
188}
189
190static INLINE void d153_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
191 const uint8_t *above, const uint8_t *left) {
192 int r, c;
193 dst[0] = AVG2(above[-1], left[0]);
194 for (r = 1; r < bs; r++) dst[r * stride] = AVG2(left[r - 1], left[r]);
195 dst++;
196
197 dst[0] = AVG3(left[0], above[-1], above[0]);
198 dst[stride] = AVG3(above[-1], left[0], left[1]);
199 for (r = 2; r < bs; r++)
200 dst[r * stride] = AVG3(left[r - 2], left[r - 1], left[r]);
201 dst++;
202
203 for (c = 0; c < bs - 2; c++)
204 dst[c] = AVG3(above[c - 1], above[c], above[c + 1]);
205 dst += stride;
206
207 for (r = 1; r < bs; ++r) {
208 for (c = 0; c < bs - 2; c++) dst[c] = dst[-stride + c - 2];
209 dst += stride;
210 }
211}
212
213static INLINE void v_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
214 const uint8_t *above, const uint8_t *left) {
215 int r;
216 (void)left;
217
218 for (r = 0; r < bs; r++) {
219 memcpy(dst, above, bs);
220 dst += stride;
221 }
222}
223
224static INLINE void h_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
225 const uint8_t *above, const uint8_t *left) {
226 int r;
227 (void)above;
228
229 for (r = 0; r < bs; r++) {
230 memset(dst, left[r], bs);
231 dst += stride;
232 }
233}
234
Urvang Joshi340593e2016-09-01 12:03:20 -0700235#if CONFIG_ALT_INTRA
236static INLINE int abs_diff(int a, int b) { return (a > b) ? a - b : b - a; }
237
238static INLINE uint16_t paeth_predictor_single(uint16_t left, uint16_t top,
239 uint16_t top_left) {
240 const int base = top + left - top_left;
241 const int p_left = abs_diff(base, left);
242 const int p_top = abs_diff(base, top);
243 const int p_top_left = abs_diff(base, top_left);
244
245 // Return nearest to base of left, top and top_left.
246 return (p_left <= p_top && p_left <= p_top_left)
247 ? left
248 : (p_top <= p_top_left) ? top : top_left;
249}
250
251static INLINE void paeth_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
252 const uint8_t *above, const uint8_t *left) {
253 int r, c;
254 const uint8_t ytop_left = above[-1];
255
256 for (r = 0; r < bs; r++) {
257 for (c = 0; c < bs; c++)
258 dst[c] = (uint8_t)paeth_predictor_single(left[r], above[c], ytop_left);
259 dst += stride;
260 }
261}
262
Urvang Joshi7a406002017-01-31 14:52:18 -0800263// Weights are quadratic from 'bs' to '1', scaled by 2^12.
264// TODO(urvang): All weights can be at the same scale: going from '1' to '1/bs'
265// instead (still scaled by 2^12 or more).
266// Rationale: Given that max block dimension is 64 (=2^6), and max pixel value
267// is below 2^12 (for both normal and highbitdepth), power of (31 - 6 - 12 - 1)
268// = 12 is chosen so that all weighted sums in smooth_predictor() remain within
269// 2^31 (unsigned integer) range.
270static const int sm_weight_log2_scale = 12;
271
Urvang Joshi6be4a542016-11-03 15:24:05 -0700272#if CONFIG_TX64X64
Urvang Joshi7a406002017-01-31 14:52:18 -0800273static const uint32_t sm_weight_arrays[6][64] = {
Urvang Joshi6be4a542016-11-03 15:24:05 -0700274#else
Urvang Joshi7a406002017-01-31 14:52:18 -0800275static const uint32_t sm_weight_arrays[5][32] = {
Urvang Joshi6be4a542016-11-03 15:24:05 -0700276#endif // CONFIG_TX64X64
277 // bs = 2
Urvang Joshi7a406002017-01-31 14:52:18 -0800278 { 8192, 4096 },
Urvang Joshi6be4a542016-11-03 15:24:05 -0700279 // bs = 4
Urvang Joshi7a406002017-01-31 14:52:18 -0800280 { 16384, 9557, 5461, 4096 },
Urvang Joshi6be4a542016-11-03 15:24:05 -0700281 // bs = 8
Urvang Joshi7a406002017-01-31 14:52:18 -0800282 { 32768, 25161, 18725, 13458, 9362, 6437, 4681, 4096 },
Urvang Joshi6be4a542016-11-03 15:24:05 -0700283 // bs = 16
Urvang Joshi7a406002017-01-31 14:52:18 -0800284 { 65536, 57617, 50244, 43418, 37137, 31403, 26214, 21572, 17476, 13926, 10923,
285 8465, 6554, 5188, 4369, 4096 },
Urvang Joshi6be4a542016-11-03 15:24:05 -0700286 // bs = 32
Urvang Joshi7a406002017-01-31 14:52:18 -0800287 { 131072, 123012, 115217, 107685, 100418, 93415, 86677, 80202,
288 73992, 68046, 62365, 56948, 51795, 46906, 42281, 37921,
289 33825, 29993, 26426, 23123, 20084, 17309, 14798, 12552,
290 10570, 8853, 7399, 6210, 5285, 4625, 4228, 4096 },
Urvang Joshi6be4a542016-11-03 15:24:05 -0700291#if CONFIG_TX64X64
292 // bs = 64
Urvang Joshi7a406002017-01-31 14:52:18 -0800293 { 262144, 254017, 246020, 238153, 230416, 222809, 215333, 207986,
294 200769, 193682, 186726, 179899, 173202, 166636, 160199, 153893,
295 147716, 141670, 135753, 129967, 124310, 118784, 113388, 108121,
296 102985, 97979, 93103, 88357, 83740, 79254, 74898, 70672,
297 66576, 62610, 58774, 55068, 51493, 48047, 44731, 41545,
298 38489, 35564, 32768, 30102, 27567, 25161, 22886, 20740,
299 18725, 16839, 15084, 13458, 11963, 10598, 9362, 8257,
300 7282, 6437, 5721, 5136, 4681, 4356, 4161, 4096 },
Urvang Joshi6be4a542016-11-03 15:24:05 -0700301#endif // CONFIG_TX64X64
302};
303
Urvang Joshi7a406002017-01-31 14:52:18 -0800304#define divide_round(value, bits) (((value) + (1 << ((bits)-1))) >> (bits))
305
Urvang Joshi6be4a542016-11-03 15:24:05 -0700306static INLINE void smooth_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
307 const uint8_t *above, const uint8_t *left) {
308 const uint8_t below_pred = left[bs - 1]; // estimated by bottom-left pixel
309 const uint8_t right_pred = above[bs - 1]; // estimated by top-right pixel
Urvang Joshi7a406002017-01-31 14:52:18 -0800310 const int log2_bs = (int)lround(log2(bs));
311 const int arr_index = log2_bs - 1;
312 const uint32_t *const sm_weights = sm_weight_arrays[arr_index];
313 // scale = 2 * bs * 2^sm_weight_log2_scale
314 const int log2_scale = 1 + log2_bs + sm_weight_log2_scale;
315 assert(log2_scale + 8 < 8 * 31); // sanity check: no overflow.
316 const uint32_t scaled_bs = sm_weights[0];
317 assert((int)scaled_bs == (bs << sm_weight_log2_scale));
Urvang Joshi6be4a542016-11-03 15:24:05 -0700318 int r;
319 for (r = 0; r < bs; ++r) {
320 int c;
321 for (c = 0; c < bs; ++c) {
Urvang Joshi7a406002017-01-31 14:52:18 -0800322 const uint8_t pixels[] = { above[c], below_pred, left[r], right_pred };
323 const uint32_t weights[] = { sm_weights[r], scaled_bs - sm_weights[r],
324 sm_weights[c], scaled_bs - sm_weights[c] };
325 uint32_t this_pred = 0;
Urvang Joshi6be4a542016-11-03 15:24:05 -0700326 int i;
Urvang Joshi7a406002017-01-31 14:52:18 -0800327 assert(scaled_bs >= sm_weights[r] && scaled_bs >= sm_weights[c]);
Urvang Joshi6be4a542016-11-03 15:24:05 -0700328 for (i = 0; i < 4; ++i) {
329 this_pred += weights[i] * pixels[i];
330 }
Urvang Joshi7a406002017-01-31 14:52:18 -0800331 dst[c] = clip_pixel(divide_round(this_pred, log2_scale));
Urvang Joshi6be4a542016-11-03 15:24:05 -0700332 }
333 dst += stride;
334 }
335}
336
Urvang Joshi340593e2016-09-01 12:03:20 -0700337#else
338
Yaowu Xuc27fc142016-08-22 16:08:15 -0700339static INLINE void tm_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
340 const uint8_t *above, const uint8_t *left) {
341 int r, c;
342 int ytop_left = above[-1];
343
344 for (r = 0; r < bs; r++) {
345 for (c = 0; c < bs; c++)
346 dst[c] = clip_pixel(left[r] + above[c] - ytop_left);
347 dst += stride;
348 }
349}
Urvang Joshi340593e2016-09-01 12:03:20 -0700350#endif // CONFIG_ALT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -0700351
352static INLINE void dc_128_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
353 const uint8_t *above, const uint8_t *left) {
354 int r;
355 (void)above;
356 (void)left;
357
358 for (r = 0; r < bs; r++) {
359 memset(dst, 128, bs);
360 dst += stride;
361 }
362}
363
364static INLINE void dc_left_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
365 const uint8_t *above,
366 const uint8_t *left) {
367 int i, r, expected_dc, sum = 0;
368 (void)above;
369
370 for (i = 0; i < bs; i++) sum += left[i];
371 expected_dc = (sum + (bs >> 1)) / bs;
372
373 for (r = 0; r < bs; r++) {
374 memset(dst, expected_dc, bs);
375 dst += stride;
376 }
377}
378
379static INLINE void dc_top_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
380 const uint8_t *above, const uint8_t *left) {
381 int i, r, expected_dc, sum = 0;
382 (void)left;
383
384 for (i = 0; i < bs; i++) sum += above[i];
385 expected_dc = (sum + (bs >> 1)) / bs;
386
387 for (r = 0; r < bs; r++) {
388 memset(dst, expected_dc, bs);
389 dst += stride;
390 }
391}
392
393static INLINE void dc_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
394 const uint8_t *above, const uint8_t *left) {
395 int i, r, expected_dc, sum = 0;
396 const int count = 2 * bs;
397
398 for (i = 0; i < bs; i++) {
399 sum += above[i];
400 sum += left[i];
401 }
402
403 expected_dc = (sum + (count >> 1)) / count;
404
405 for (r = 0; r < bs; r++) {
406 memset(dst, expected_dc, bs);
407 dst += stride;
408 }
409}
410
Jingning Han03b35142016-10-19 13:04:26 -0700411void aom_he_predictor_2x2_c(uint8_t *dst, ptrdiff_t stride,
412 const uint8_t *above, const uint8_t *left) {
413 const int H = above[-1];
414 const int I = left[0];
415 const int J = left[1];
416 const int K = left[2];
417
418 memset(dst + stride * 0, AVG3(H, I, J), 2);
419 memset(dst + stride * 1, AVG3(I, J, K), 2);
420}
421
422void aom_ve_predictor_2x2_c(uint8_t *dst, ptrdiff_t stride,
423 const uint8_t *above, const uint8_t *left) {
424 const int H = above[-1];
425 const int I = above[0];
426 const int J = above[1];
427 const int K = above[2];
Angie Chiang646e52a2016-10-21 11:45:31 -0700428 (void)left;
Jingning Han03b35142016-10-19 13:04:26 -0700429
430 dst[0] = AVG3(H, I, J);
431 dst[1] = AVG3(I, J, K);
432 memcpy(dst + stride * 1, dst, 2);
433}
434
435void aom_d207_predictor_2x2_c(uint8_t *dst, ptrdiff_t stride,
436 const uint8_t *above, const uint8_t *left) {
437 const int I = left[0];
438 const int J = left[1];
439 const int K = left[2];
440 const int L = left[3];
441 (void)above;
442 DST(0, 0) = AVG2(I, J);
443 DST(0, 1) = AVG2(J, K);
444 DST(1, 0) = AVG3(I, J, K);
445 DST(1, 1) = AVG3(J, K, L);
446}
447
448void aom_d63_predictor_2x2_c(uint8_t *dst, ptrdiff_t stride,
449 const uint8_t *above, const uint8_t *left) {
450 const int A = above[0];
451 const int B = above[1];
452 const int C = above[2];
453 const int D = above[3];
454 (void)left;
455 DST(0, 0) = AVG2(A, B);
456 DST(1, 0) = AVG2(B, C);
457 DST(0, 1) = AVG3(A, B, C);
458 DST(1, 1) = AVG3(B, C, D);
459}
460
461void aom_d63f_predictor_2x2_c(uint8_t *dst, ptrdiff_t stride,
462 const uint8_t *above, const uint8_t *left) {
463 const int A = above[0];
464 const int B = above[1];
465 const int C = above[2];
466 const int D = above[3];
467 (void)left;
468 DST(0, 0) = AVG2(A, B);
469 DST(1, 0) = AVG2(B, C);
470 DST(0, 1) = AVG3(A, B, C);
471 DST(1, 1) = AVG3(B, C, D);
472}
473
474void aom_d45_predictor_2x2_c(uint8_t *dst, ptrdiff_t stride,
475 const uint8_t *above, const uint8_t *left) {
476 const int A = above[0];
477 const int B = above[1];
478 const int C = above[2];
479 const int D = above[3];
Jingning Han03b35142016-10-19 13:04:26 -0700480 (void)stride;
481 (void)left;
482 DST(0, 0) = AVG3(A, B, C);
483 DST(1, 0) = DST(0, 1) = AVG3(B, C, D);
Jingning Han8a7786d2016-12-15 20:37:47 -0800484 DST(1, 1) = AVG3(C, D, D);
Jingning Han03b35142016-10-19 13:04:26 -0700485}
486
487void aom_d45e_predictor_2x2_c(uint8_t *dst, ptrdiff_t stride,
488 const uint8_t *above, const uint8_t *left) {
489 const int A = above[0];
490 const int B = above[1];
491 const int C = above[2];
492 const int D = above[3];
Jingning Han03b35142016-10-19 13:04:26 -0700493 (void)stride;
494 (void)left;
Jingning Han8a7786d2016-12-15 20:37:47 -0800495
Jingning Han03b35142016-10-19 13:04:26 -0700496 DST(0, 0) = AVG3(A, B, C);
497 DST(1, 0) = DST(0, 1) = AVG3(B, C, D);
Jingning Han8a7786d2016-12-15 20:37:47 -0800498 DST(1, 1) = AVG3(C, D, D);
Jingning Han03b35142016-10-19 13:04:26 -0700499}
500
501void aom_d117_predictor_2x2_c(uint8_t *dst, ptrdiff_t stride,
502 const uint8_t *above, const uint8_t *left) {
503 const int I = left[0];
504 const int X = above[-1];
505 const int A = above[0];
506 const int B = above[1];
507 DST(0, 0) = AVG2(X, A);
508 DST(1, 0) = AVG2(A, B);
509 DST(0, 1) = AVG3(I, X, A);
510 DST(1, 1) = AVG3(X, A, B);
511}
512
513void aom_d135_predictor_2x2_c(uint8_t *dst, ptrdiff_t stride,
514 const uint8_t *above, const uint8_t *left) {
515 const int I = left[0];
516 const int J = left[1];
517 const int X = above[-1];
518 const int A = above[0];
519 const int B = above[1];
520 (void)stride;
521 DST(0, 1) = AVG3(X, I, J);
522 DST(1, 1) = DST(0, 0) = AVG3(A, X, I);
523 DST(1, 0) = AVG3(B, A, X);
524}
525
526void aom_d153_predictor_2x2_c(uint8_t *dst, ptrdiff_t stride,
527 const uint8_t *above, const uint8_t *left) {
528 const int I = left[0];
529 const int J = left[1];
530 const int X = above[-1];
531 const int A = above[0];
532
533 DST(0, 0) = AVG2(I, X);
534 DST(0, 1) = AVG2(J, I);
535 DST(1, 0) = AVG3(I, X, A);
536 DST(1, 1) = AVG3(J, I, X);
537}
538
Yaowu Xuf883b422016-08-30 14:01:10 -0700539void aom_he_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700540 const uint8_t *above, const uint8_t *left) {
541 const int H = above[-1];
542 const int I = left[0];
543 const int J = left[1];
544 const int K = left[2];
545 const int L = left[3];
546
547 memset(dst + stride * 0, AVG3(H, I, J), 4);
548 memset(dst + stride * 1, AVG3(I, J, K), 4);
549 memset(dst + stride * 2, AVG3(J, K, L), 4);
550 memset(dst + stride * 3, AVG3(K, L, L), 4);
551}
552
Yaowu Xuf883b422016-08-30 14:01:10 -0700553void aom_ve_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700554 const uint8_t *above, const uint8_t *left) {
555 const int H = above[-1];
556 const int I = above[0];
557 const int J = above[1];
558 const int K = above[2];
559 const int L = above[3];
560 const int M = above[4];
561 (void)left;
562
563 dst[0] = AVG3(H, I, J);
564 dst[1] = AVG3(I, J, K);
565 dst[2] = AVG3(J, K, L);
566 dst[3] = AVG3(K, L, M);
567 memcpy(dst + stride * 1, dst, 4);
568 memcpy(dst + stride * 2, dst, 4);
569 memcpy(dst + stride * 3, dst, 4);
570}
571
Yaowu Xuf883b422016-08-30 14:01:10 -0700572void aom_d207_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700573 const uint8_t *above, const uint8_t *left) {
574 const int I = left[0];
575 const int J = left[1];
576 const int K = left[2];
577 const int L = left[3];
578 (void)above;
579 DST(0, 0) = AVG2(I, J);
580 DST(2, 0) = DST(0, 1) = AVG2(J, K);
581 DST(2, 1) = DST(0, 2) = AVG2(K, L);
582 DST(1, 0) = AVG3(I, J, K);
583 DST(3, 0) = DST(1, 1) = AVG3(J, K, L);
584 DST(3, 1) = DST(1, 2) = AVG3(K, L, L);
585 DST(3, 2) = DST(2, 2) = DST(0, 3) = DST(1, 3) = DST(2, 3) = DST(3, 3) = L;
586}
587
Yaowu Xuf883b422016-08-30 14:01:10 -0700588void aom_d63_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700589 const uint8_t *above, const uint8_t *left) {
590 const int A = above[0];
591 const int B = above[1];
592 const int C = above[2];
593 const int D = above[3];
594 const int E = above[4];
595 const int F = above[5];
596 const int G = above[6];
597 (void)left;
598 DST(0, 0) = AVG2(A, B);
599 DST(1, 0) = DST(0, 2) = AVG2(B, C);
600 DST(2, 0) = DST(1, 2) = AVG2(C, D);
601 DST(3, 0) = DST(2, 2) = AVG2(D, E);
602 DST(3, 2) = AVG2(E, F); // differs from vp8
603
604 DST(0, 1) = AVG3(A, B, C);
605 DST(1, 1) = DST(0, 3) = AVG3(B, C, D);
606 DST(2, 1) = DST(1, 3) = AVG3(C, D, E);
607 DST(3, 1) = DST(2, 3) = AVG3(D, E, F);
608 DST(3, 3) = AVG3(E, F, G); // differs from vp8
609}
610
Yaowu Xuf883b422016-08-30 14:01:10 -0700611void aom_d63f_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700612 const uint8_t *above, const uint8_t *left) {
613 const int A = above[0];
614 const int B = above[1];
615 const int C = above[2];
616 const int D = above[3];
617 const int E = above[4];
618 const int F = above[5];
619 const int G = above[6];
620 const int H = above[7];
621 (void)left;
622 DST(0, 0) = AVG2(A, B);
623 DST(1, 0) = DST(0, 2) = AVG2(B, C);
624 DST(2, 0) = DST(1, 2) = AVG2(C, D);
625 DST(3, 0) = DST(2, 2) = AVG2(D, E);
626 DST(3, 2) = AVG3(E, F, G);
627
628 DST(0, 1) = AVG3(A, B, C);
629 DST(1, 1) = DST(0, 3) = AVG3(B, C, D);
630 DST(2, 1) = DST(1, 3) = AVG3(C, D, E);
631 DST(3, 1) = DST(2, 3) = AVG3(D, E, F);
632 DST(3, 3) = AVG3(F, G, H);
633}
634
Yaowu Xuf883b422016-08-30 14:01:10 -0700635void aom_d45_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 A = above[0];
638 const int B = above[1];
639 const int C = above[2];
640 const int D = above[3];
641 const int E = above[4];
642 const int F = above[5];
643 const int G = above[6];
644 const int H = above[7];
645 (void)stride;
646 (void)left;
647 DST(0, 0) = AVG3(A, B, C);
648 DST(1, 0) = DST(0, 1) = AVG3(B, C, D);
649 DST(2, 0) = DST(1, 1) = DST(0, 2) = AVG3(C, D, E);
650 DST(3, 0) = DST(2, 1) = DST(1, 2) = DST(0, 3) = AVG3(D, E, F);
651 DST(3, 1) = DST(2, 2) = DST(1, 3) = AVG3(E, F, G);
652 DST(3, 2) = DST(2, 3) = AVG3(F, G, H);
653 DST(3, 3) = H; // differs from vp8
654}
655
Yaowu Xuf883b422016-08-30 14:01:10 -0700656void aom_d45e_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700657 const uint8_t *above, const uint8_t *left) {
658 const int A = above[0];
659 const int B = above[1];
660 const int C = above[2];
661 const int D = above[3];
662 const int E = above[4];
663 const int F = above[5];
664 const int G = above[6];
665 const int H = above[7];
666 (void)stride;
667 (void)left;
668 DST(0, 0) = AVG3(A, B, C);
669 DST(1, 0) = DST(0, 1) = AVG3(B, C, D);
670 DST(2, 0) = DST(1, 1) = DST(0, 2) = AVG3(C, D, E);
671 DST(3, 0) = DST(2, 1) = DST(1, 2) = DST(0, 3) = AVG3(D, E, F);
672 DST(3, 1) = DST(2, 2) = DST(1, 3) = AVG3(E, F, G);
673 DST(3, 2) = DST(2, 3) = AVG3(F, G, H);
674 DST(3, 3) = AVG3(G, H, H);
675}
676
Yaowu Xuf883b422016-08-30 14:01:10 -0700677void aom_d117_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700678 const uint8_t *above, const uint8_t *left) {
679 const int I = left[0];
680 const int J = left[1];
681 const int K = left[2];
682 const int X = above[-1];
683 const int A = above[0];
684 const int B = above[1];
685 const int C = above[2];
686 const int D = above[3];
687 DST(0, 0) = DST(1, 2) = AVG2(X, A);
688 DST(1, 0) = DST(2, 2) = AVG2(A, B);
689 DST(2, 0) = DST(3, 2) = AVG2(B, C);
690 DST(3, 0) = AVG2(C, D);
691
692 DST(0, 3) = AVG3(K, J, I);
693 DST(0, 2) = AVG3(J, I, X);
694 DST(0, 1) = DST(1, 3) = AVG3(I, X, A);
695 DST(1, 1) = DST(2, 3) = AVG3(X, A, B);
696 DST(2, 1) = DST(3, 3) = AVG3(A, B, C);
697 DST(3, 1) = AVG3(B, C, D);
698}
699
Yaowu Xuf883b422016-08-30 14:01:10 -0700700void aom_d135_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700701 const uint8_t *above, const uint8_t *left) {
702 const int I = left[0];
703 const int J = left[1];
704 const int K = left[2];
705 const int L = left[3];
706 const int X = above[-1];
707 const int A = above[0];
708 const int B = above[1];
709 const int C = above[2];
710 const int D = above[3];
711 (void)stride;
712 DST(0, 3) = AVG3(J, K, L);
713 DST(1, 3) = DST(0, 2) = AVG3(I, J, K);
714 DST(2, 3) = DST(1, 2) = DST(0, 1) = AVG3(X, I, J);
715 DST(3, 3) = DST(2, 2) = DST(1, 1) = DST(0, 0) = AVG3(A, X, I);
716 DST(3, 2) = DST(2, 1) = DST(1, 0) = AVG3(B, A, X);
717 DST(3, 1) = DST(2, 0) = AVG3(C, B, A);
718 DST(3, 0) = AVG3(D, C, B);
719}
720
Yaowu Xuf883b422016-08-30 14:01:10 -0700721void aom_d153_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700722 const uint8_t *above, const uint8_t *left) {
723 const int I = left[0];
724 const int J = left[1];
725 const int K = left[2];
726 const int L = left[3];
727 const int X = above[-1];
728 const int A = above[0];
729 const int B = above[1];
730 const int C = above[2];
731
732 DST(0, 0) = DST(2, 1) = AVG2(I, X);
733 DST(0, 1) = DST(2, 2) = AVG2(J, I);
734 DST(0, 2) = DST(2, 3) = AVG2(K, J);
735 DST(0, 3) = AVG2(L, K);
736
737 DST(3, 0) = AVG3(A, B, C);
738 DST(2, 0) = AVG3(X, A, B);
739 DST(1, 0) = DST(3, 1) = AVG3(I, X, A);
740 DST(1, 1) = DST(3, 2) = AVG3(J, I, X);
741 DST(1, 2) = DST(3, 3) = AVG3(K, J, I);
742 DST(1, 3) = AVG3(L, K, J);
743}
744
Yaowu Xuf883b422016-08-30 14:01:10 -0700745#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700746static INLINE void highbd_d207_predictor(uint16_t *dst, ptrdiff_t stride,
747 int bs, const uint16_t *above,
748 const uint16_t *left, int bd) {
749 int r, c;
750 (void)above;
751 (void)bd;
752
753 // First column.
754 for (r = 0; r < bs - 1; ++r) {
755 dst[r * stride] = AVG2(left[r], left[r + 1]);
756 }
757 dst[(bs - 1) * stride] = left[bs - 1];
758 dst++;
759
760 // Second column.
761 for (r = 0; r < bs - 2; ++r) {
762 dst[r * stride] = AVG3(left[r], left[r + 1], left[r + 2]);
763 }
764 dst[(bs - 2) * stride] = AVG3(left[bs - 2], left[bs - 1], left[bs - 1]);
765 dst[(bs - 1) * stride] = left[bs - 1];
766 dst++;
767
768 // Rest of last row.
769 for (c = 0; c < bs - 2; ++c) dst[(bs - 1) * stride + c] = left[bs - 1];
770
771 for (r = bs - 2; r >= 0; --r) {
772 for (c = 0; c < bs - 2; ++c)
773 dst[r * stride + c] = dst[(r + 1) * stride + c - 2];
774 }
775}
776
777static INLINE void highbd_d207e_predictor(uint16_t *dst, ptrdiff_t stride,
778 int bs, const uint16_t *above,
779 const uint16_t *left, int bd) {
780 int r, c;
781 (void)above;
782 (void)bd;
783
784 for (r = 0; r < bs; ++r) {
785 for (c = 0; c < bs; ++c) {
786 dst[c] = c & 1 ? AVG3(left[(c >> 1) + r], left[(c >> 1) + r + 1],
787 left[(c >> 1) + r + 2])
788 : AVG2(left[(c >> 1) + r], left[(c >> 1) + r + 1]);
789 }
790 dst += stride;
791 }
792}
793
794static INLINE void highbd_d63_predictor(uint16_t *dst, ptrdiff_t stride, int bs,
795 const uint16_t *above,
796 const uint16_t *left, int bd) {
797 int r, c;
798 (void)left;
799 (void)bd;
800 for (r = 0; r < bs; ++r) {
801 for (c = 0; c < bs; ++c) {
802 dst[c] = r & 1 ? AVG3(above[(r >> 1) + c], above[(r >> 1) + c + 1],
803 above[(r >> 1) + c + 2])
804 : AVG2(above[(r >> 1) + c], above[(r >> 1) + c + 1]);
805 }
806 dst += stride;
807 }
808}
809
810#define highbd_d63e_predictor highbd_d63_predictor
811
812static INLINE void highbd_d45_predictor(uint16_t *dst, ptrdiff_t stride, int bs,
813 const uint16_t *above,
814 const uint16_t *left, int bd) {
815 int r, c;
816 (void)left;
817 (void)bd;
818 for (r = 0; r < bs; ++r) {
819 for (c = 0; c < bs; ++c) {
820 dst[c] = r + c + 2 < bs * 2
821 ? AVG3(above[r + c], above[r + c + 1], above[r + c + 2])
822 : above[bs * 2 - 1];
823 }
824 dst += stride;
825 }
826}
827
828static INLINE void highbd_d45e_predictor(uint16_t *dst, ptrdiff_t stride,
829 int bs, const uint16_t *above,
830 const uint16_t *left, int bd) {
831 int r, c;
832 (void)left;
833 (void)bd;
834 for (r = 0; r < bs; ++r) {
835 for (c = 0; c < bs; ++c) {
836 dst[c] = AVG3(above[r + c], above[r + c + 1],
837 above[r + c + 1 + (r + c + 2 < bs * 2)]);
838 }
839 dst += stride;
840 }
841}
842
843static INLINE void highbd_d117_predictor(uint16_t *dst, ptrdiff_t stride,
844 int bs, const uint16_t *above,
845 const uint16_t *left, int bd) {
846 int r, c;
847 (void)bd;
848
849 // first row
850 for (c = 0; c < bs; c++) dst[c] = AVG2(above[c - 1], above[c]);
851 dst += stride;
852
853 // second row
854 dst[0] = AVG3(left[0], above[-1], above[0]);
855 for (c = 1; c < bs; c++) dst[c] = AVG3(above[c - 2], above[c - 1], above[c]);
856 dst += stride;
857
858 // the rest of first col
859 dst[0] = AVG3(above[-1], left[0], left[1]);
860 for (r = 3; r < bs; ++r)
861 dst[(r - 2) * stride] = AVG3(left[r - 3], left[r - 2], left[r - 1]);
862
863 // the rest of the block
864 for (r = 2; r < bs; ++r) {
865 for (c = 1; c < bs; c++) dst[c] = dst[-2 * stride + c - 1];
866 dst += stride;
867 }
868}
869
870static INLINE void highbd_d135_predictor(uint16_t *dst, ptrdiff_t stride,
871 int bs, const uint16_t *above,
872 const uint16_t *left, int bd) {
873 int r, c;
874 (void)bd;
875 dst[0] = AVG3(left[0], above[-1], above[0]);
876 for (c = 1; c < bs; c++) dst[c] = AVG3(above[c - 2], above[c - 1], above[c]);
877
878 dst[stride] = AVG3(above[-1], left[0], left[1]);
879 for (r = 2; r < bs; ++r)
880 dst[r * stride] = AVG3(left[r - 2], left[r - 1], left[r]);
881
882 dst += stride;
883 for (r = 1; r < bs; ++r) {
884 for (c = 1; c < bs; c++) dst[c] = dst[-stride + c - 1];
885 dst += stride;
886 }
887}
888
889static INLINE void highbd_d153_predictor(uint16_t *dst, ptrdiff_t stride,
890 int bs, const uint16_t *above,
891 const uint16_t *left, int bd) {
892 int r, c;
893 (void)bd;
894 dst[0] = AVG2(above[-1], left[0]);
895 for (r = 1; r < bs; r++) dst[r * stride] = AVG2(left[r - 1], left[r]);
896 dst++;
897
898 dst[0] = AVG3(left[0], above[-1], above[0]);
899 dst[stride] = AVG3(above[-1], left[0], left[1]);
900 for (r = 2; r < bs; r++)
901 dst[r * stride] = AVG3(left[r - 2], left[r - 1], left[r]);
902 dst++;
903
904 for (c = 0; c < bs - 2; c++)
905 dst[c] = AVG3(above[c - 1], above[c], above[c + 1]);
906 dst += stride;
907
908 for (r = 1; r < bs; ++r) {
909 for (c = 0; c < bs - 2; c++) dst[c] = dst[-stride + c - 2];
910 dst += stride;
911 }
912}
913
914static INLINE void highbd_v_predictor(uint16_t *dst, ptrdiff_t stride, int bs,
915 const uint16_t *above,
916 const uint16_t *left, int bd) {
917 int r;
918 (void)left;
919 (void)bd;
920 for (r = 0; r < bs; r++) {
921 memcpy(dst, above, bs * sizeof(uint16_t));
922 dst += stride;
923 }
924}
925
926static INLINE void highbd_h_predictor(uint16_t *dst, ptrdiff_t stride, int bs,
927 const uint16_t *above,
928 const uint16_t *left, int bd) {
929 int r;
930 (void)above;
931 (void)bd;
932 for (r = 0; r < bs; r++) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700933 aom_memset16(dst, left[r], bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700934 dst += stride;
935 }
936}
937
Jingning Han324b4c62016-12-19 09:33:04 -0800938void aom_highbd_d207_predictor_2x2_c(uint16_t *dst, ptrdiff_t stride,
939 const uint16_t *above,
940 const uint16_t *left, int bd) {
941 const int I = left[0];
942 const int J = left[1];
943 const int K = left[2];
944 const int L = left[3];
945 (void)above;
946 (void)bd;
947 DST(0, 0) = AVG2(I, J);
948 DST(0, 1) = AVG2(J, K);
949 DST(1, 0) = AVG3(I, J, K);
950 DST(1, 1) = AVG3(J, K, L);
951}
952
953void aom_highbd_d63_predictor_2x2_c(uint16_t *dst, ptrdiff_t stride,
954 const uint16_t *above, const uint16_t *left,
955 int bd) {
956 const int A = above[0];
957 const int B = above[1];
958 const int C = above[2];
959 const int D = above[3];
960 (void)left;
961 (void)bd;
962 DST(0, 0) = AVG2(A, B);
963 DST(1, 0) = AVG2(B, C);
964 DST(0, 1) = AVG3(A, B, C);
965 DST(1, 1) = AVG3(B, C, D);
966}
967
968void aom_highbd_d45e_predictor_2x2_c(uint16_t *dst, ptrdiff_t stride,
969 const uint16_t *above,
970 const uint16_t *left, int bd) {
971 const int A = above[0];
972 const int B = above[1];
973 const int C = above[2];
974 const int D = above[3];
975 (void)stride;
976 (void)left;
977 (void)bd;
978 DST(0, 0) = AVG3(A, B, C);
979 DST(1, 0) = DST(0, 1) = AVG3(B, C, D);
980 DST(1, 1) = AVG3(C, D, D);
981}
982
983void aom_highbd_d117_predictor_2x2_c(uint16_t *dst, ptrdiff_t stride,
984 const uint16_t *above,
985 const uint16_t *left, int bd) {
986 const int I = left[0];
987 const int X = above[-1];
988 const int A = above[0];
989 const int B = above[1];
990 (void)bd;
991 DST(0, 0) = AVG2(X, A);
992 DST(1, 0) = AVG2(A, B);
993 DST(0, 1) = AVG3(I, X, A);
994 DST(1, 1) = AVG3(X, A, B);
995}
996
997void aom_highbd_d135_predictor_2x2_c(uint16_t *dst, ptrdiff_t stride,
998 const uint16_t *above,
999 const uint16_t *left, int bd) {
1000 const int I = left[0];
1001 const int J = left[1];
1002 const int X = above[-1];
1003 const int A = above[0];
1004 const int B = above[1];
1005 (void)bd;
1006 DST(0, 1) = AVG3(X, I, J);
1007 DST(1, 1) = DST(0, 0) = AVG3(A, X, I);
1008 DST(1, 0) = AVG3(B, A, X);
1009}
1010
1011void aom_highbd_d153_predictor_2x2_c(uint16_t *dst, ptrdiff_t stride,
1012 const uint16_t *above,
1013 const uint16_t *left, int bd) {
1014 const int I = left[0];
1015 const int J = left[1];
1016 const int X = above[-1];
1017 const int A = above[0];
1018 (void)bd;
1019 DST(0, 0) = AVG2(I, X);
1020 DST(0, 1) = AVG2(J, I);
1021 DST(1, 0) = AVG3(I, X, A);
1022 DST(1, 1) = AVG3(J, I, X);
1023}
1024
Urvang Joshi340593e2016-09-01 12:03:20 -07001025#if CONFIG_ALT_INTRA
1026static INLINE void highbd_paeth_predictor(uint16_t *dst, ptrdiff_t stride,
1027 int bs, const uint16_t *above,
1028 const uint16_t *left, int bd) {
1029 int r, c;
1030 const uint16_t ytop_left = above[-1];
1031 (void)bd;
1032
1033 for (r = 0; r < bs; r++) {
1034 for (c = 0; c < bs; c++)
1035 dst[c] = paeth_predictor_single(left[r], above[c], ytop_left);
1036 dst += stride;
1037 }
1038}
1039
Urvang Joshi6be4a542016-11-03 15:24:05 -07001040static INLINE void highbd_smooth_predictor(uint16_t *dst, ptrdiff_t stride,
1041 int bs, const uint16_t *above,
1042 const uint16_t *left, int bd) {
1043 const uint16_t below_pred = left[bs - 1]; // estimated by bottom-left pixel
1044 const uint16_t right_pred = above[bs - 1]; // estimated by top-right pixel
Urvang Joshi7a406002017-01-31 14:52:18 -08001045 const int log2_bs = (int)lround(log2(bs));
1046 const int arr_index = log2_bs - 1;
1047 const uint32_t *const sm_weights = sm_weight_arrays[arr_index];
1048 // scale = 2 * bs * 2^sm_weight_log2_scale
1049 const int log2_scale = 1 + log2_bs + sm_weight_log2_scale;
1050 assert(log2_scale + 8 < 8 * 31); // sanity check: no overflow.
1051 const uint32_t scaled_bs = sm_weights[0];
1052 assert((int)scaled_bs == (bs << sm_weight_log2_scale));
Urvang Joshi6be4a542016-11-03 15:24:05 -07001053 int r;
1054 for (r = 0; r < bs; ++r) {
1055 int c;
1056 for (c = 0; c < bs; ++c) {
Urvang Joshi7a406002017-01-31 14:52:18 -08001057 const uint16_t pixels[] = { above[c], below_pred, left[r], right_pred };
1058 const uint32_t weights[] = { sm_weights[r], scaled_bs - sm_weights[r],
1059 sm_weights[c], scaled_bs - sm_weights[c] };
1060 uint32_t this_pred = 0;
Urvang Joshi6be4a542016-11-03 15:24:05 -07001061 int i;
Urvang Joshi7a406002017-01-31 14:52:18 -08001062 assert(scaled_bs >= sm_weights[r] && scaled_bs >= sm_weights[c]);
Urvang Joshi6be4a542016-11-03 15:24:05 -07001063 for (i = 0; i < 4; ++i) {
1064 this_pred += weights[i] * pixels[i];
1065 }
Urvang Joshi7a406002017-01-31 14:52:18 -08001066 dst[c] = clip_pixel_highbd(divide_round(this_pred, log2_scale), bd);
Urvang Joshi6be4a542016-11-03 15:24:05 -07001067 }
1068 dst += stride;
1069 }
1070}
1071
Urvang Joshi340593e2016-09-01 12:03:20 -07001072#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07001073static INLINE void highbd_tm_predictor(uint16_t *dst, ptrdiff_t stride, int bs,
1074 const uint16_t *above,
1075 const uint16_t *left, int bd) {
1076 int r, c;
1077 int ytop_left = above[-1];
1078 (void)bd;
1079
1080 for (r = 0; r < bs; r++) {
1081 for (c = 0; c < bs; c++)
1082 dst[c] = clip_pixel_highbd(left[r] + above[c] - ytop_left, bd);
1083 dst += stride;
1084 }
1085}
Urvang Joshi340593e2016-09-01 12:03:20 -07001086#endif // CONFIG_ALT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07001087
1088static INLINE void highbd_dc_128_predictor(uint16_t *dst, ptrdiff_t stride,
1089 int bs, const uint16_t *above,
1090 const uint16_t *left, int bd) {
1091 int r;
1092 (void)above;
1093 (void)left;
1094
1095 for (r = 0; r < bs; r++) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001096 aom_memset16(dst, 128 << (bd - 8), bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001097 dst += stride;
1098 }
1099}
1100
1101static INLINE void highbd_dc_left_predictor(uint16_t *dst, ptrdiff_t stride,
1102 int bs, const uint16_t *above,
1103 const uint16_t *left, int bd) {
1104 int i, r, expected_dc, sum = 0;
1105 (void)above;
1106 (void)bd;
1107
1108 for (i = 0; i < bs; i++) sum += left[i];
1109 expected_dc = (sum + (bs >> 1)) / bs;
1110
1111 for (r = 0; r < bs; r++) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001112 aom_memset16(dst, expected_dc, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001113 dst += stride;
1114 }
1115}
1116
1117static INLINE void highbd_dc_top_predictor(uint16_t *dst, ptrdiff_t stride,
1118 int bs, const uint16_t *above,
1119 const uint16_t *left, int bd) {
1120 int i, r, expected_dc, sum = 0;
1121 (void)left;
1122 (void)bd;
1123
1124 for (i = 0; i < bs; i++) sum += above[i];
1125 expected_dc = (sum + (bs >> 1)) / bs;
1126
1127 for (r = 0; r < bs; r++) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001128 aom_memset16(dst, expected_dc, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001129 dst += stride;
1130 }
1131}
1132
1133static INLINE void highbd_dc_predictor(uint16_t *dst, ptrdiff_t stride, int bs,
1134 const uint16_t *above,
1135 const uint16_t *left, int bd) {
1136 int i, r, expected_dc, sum = 0;
1137 const int count = 2 * bs;
1138 (void)bd;
1139
1140 for (i = 0; i < bs; i++) {
1141 sum += above[i];
1142 sum += left[i];
1143 }
1144
1145 expected_dc = (sum + (count >> 1)) / count;
1146
1147 for (r = 0; r < bs; r++) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001148 aom_memset16(dst, expected_dc, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001149 dst += stride;
1150 }
1151}
Yaowu Xuf883b422016-08-30 14:01:10 -07001152#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001153
1154// This serves as a wrapper function, so that all the prediction functions
1155// can be unified and accessed as a pointer array. Note that the boundary
1156// above and left are not necessarily used all the time.
1157#define intra_pred_sized(type, size) \
Yaowu Xuf883b422016-08-30 14:01:10 -07001158 void aom_##type##_predictor_##size##x##size##_c( \
Yaowu Xuc27fc142016-08-22 16:08:15 -07001159 uint8_t *dst, ptrdiff_t stride, const uint8_t *above, \
1160 const uint8_t *left) { \
1161 type##_predictor(dst, stride, size, above, left); \
1162 }
1163
Yaowu Xuf883b422016-08-30 14:01:10 -07001164#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001165#define intra_pred_highbd_sized(type, size) \
Yaowu Xuf883b422016-08-30 14:01:10 -07001166 void aom_highbd_##type##_predictor_##size##x##size##_c( \
Yaowu Xuc27fc142016-08-22 16:08:15 -07001167 uint16_t *dst, ptrdiff_t stride, const uint16_t *above, \
1168 const uint16_t *left, int bd) { \
1169 highbd_##type##_predictor(dst, stride, size, above, left, bd); \
1170 }
1171
1172/* clang-format off */
Debargha Mukherjee84c56af2016-11-19 10:59:37 -08001173#if CONFIG_TX64X64
1174#define intra_pred_allsizes(type) \
1175 intra_pred_sized(type, 2) \
1176 intra_pred_sized(type, 4) \
1177 intra_pred_sized(type, 8) \
1178 intra_pred_sized(type, 16) \
1179 intra_pred_sized(type, 32) \
1180 intra_pred_sized(type, 64) \
1181 intra_pred_highbd_sized(type, 4) \
1182 intra_pred_highbd_sized(type, 8) \
1183 intra_pred_highbd_sized(type, 16) \
1184 intra_pred_highbd_sized(type, 32) \
1185 intra_pred_highbd_sized(type, 64)
1186
1187#define intra_pred_above_4x4(type) \
1188 intra_pred_sized(type, 8) \
1189 intra_pred_sized(type, 16) \
1190 intra_pred_sized(type, 32) \
1191 intra_pred_sized(type, 64) \
1192 intra_pred_highbd_sized(type, 4) \
1193 intra_pred_highbd_sized(type, 8) \
1194 intra_pred_highbd_sized(type, 16) \
1195 intra_pred_highbd_sized(type, 32) \
1196 intra_pred_highbd_sized(type, 64)
1197#else // CONFIG_TX64X64
Yaowu Xuc27fc142016-08-22 16:08:15 -07001198#define intra_pred_allsizes(type) \
Jingning Hane3954d82016-10-12 21:03:18 -07001199 intra_pred_sized(type, 2) \
Yaowu Xuc27fc142016-08-22 16:08:15 -07001200 intra_pred_sized(type, 4) \
1201 intra_pred_sized(type, 8) \
1202 intra_pred_sized(type, 16) \
1203 intra_pred_sized(type, 32) \
Jingning Han324b4c62016-12-19 09:33:04 -08001204 intra_pred_highbd_sized(type, 2) \
Yaowu Xuc27fc142016-08-22 16:08:15 -07001205 intra_pred_highbd_sized(type, 4) \
1206 intra_pred_highbd_sized(type, 8) \
1207 intra_pred_highbd_sized(type, 16) \
1208 intra_pred_highbd_sized(type, 32)
1209
Jingning Hane3954d82016-10-12 21:03:18 -07001210#define intra_pred_above_4x4(type) \
Yaowu Xuc27fc142016-08-22 16:08:15 -07001211 intra_pred_sized(type, 8) \
1212 intra_pred_sized(type, 16) \
1213 intra_pred_sized(type, 32) \
1214 intra_pred_highbd_sized(type, 4) \
1215 intra_pred_highbd_sized(type, 8) \
1216 intra_pred_highbd_sized(type, 16) \
1217 intra_pred_highbd_sized(type, 32)
Debargha Mukherjee84c56af2016-11-19 10:59:37 -08001218#endif // CONFIG_TX64X64
Yaowu Xuc27fc142016-08-22 16:08:15 -07001219
1220#else
Debargha Mukherjee84c56af2016-11-19 10:59:37 -08001221
1222#if CONFIG_TX64X64
1223#define intra_pred_allsizes(type) \
1224 intra_pred_sized(type, 2) \
1225 intra_pred_sized(type, 4) \
1226 intra_pred_sized(type, 8) \
1227 intra_pred_sized(type, 16) \
1228 intra_pred_sized(type, 32) \
1229 intra_pred_sized(type, 64)
1230
1231#define intra_pred_above_4x4(type) \
1232 intra_pred_sized(type, 8) \
1233 intra_pred_sized(type, 16) \
1234 intra_pred_sized(type, 32) \
1235 intra_pred_sized(type, 64)
1236#else // CONFIG_TX64X64
Yaowu Xuc27fc142016-08-22 16:08:15 -07001237#define intra_pred_allsizes(type) \
Jingning Hane3954d82016-10-12 21:03:18 -07001238 intra_pred_sized(type, 2) \
Yaowu Xuc27fc142016-08-22 16:08:15 -07001239 intra_pred_sized(type, 4) \
1240 intra_pred_sized(type, 8) \
1241 intra_pred_sized(type, 16) \
1242 intra_pred_sized(type, 32)
1243
Jingning Hane3954d82016-10-12 21:03:18 -07001244#define intra_pred_above_4x4(type) \
Yaowu Xuc27fc142016-08-22 16:08:15 -07001245 intra_pred_sized(type, 8) \
1246 intra_pred_sized(type, 16) \
1247 intra_pred_sized(type, 32)
Debargha Mukherjee84c56af2016-11-19 10:59:37 -08001248#endif // CONFIG_TX64X64
Yaowu Xuf883b422016-08-30 14:01:10 -07001249#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001250
Jingning Hane3954d82016-10-12 21:03:18 -07001251intra_pred_above_4x4(d207)
1252intra_pred_above_4x4(d63)
1253intra_pred_above_4x4(d45)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001254intra_pred_allsizes(d207e)
1255intra_pred_allsizes(d63e)
Jingning Hane3954d82016-10-12 21:03:18 -07001256intra_pred_above_4x4(d45e)
1257intra_pred_above_4x4(d117)
1258intra_pred_above_4x4(d135)
1259intra_pred_above_4x4(d153)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001260intra_pred_allsizes(v)
1261intra_pred_allsizes(h)
Urvang Joshi340593e2016-09-01 12:03:20 -07001262#if CONFIG_ALT_INTRA
1263intra_pred_allsizes(paeth)
Urvang Joshi6be4a542016-11-03 15:24:05 -07001264intra_pred_allsizes(smooth)
Urvang Joshi340593e2016-09-01 12:03:20 -07001265#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07001266intra_pred_allsizes(tm)
Urvang Joshi340593e2016-09-01 12:03:20 -07001267#endif // CONFIG_ALT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -07001268intra_pred_allsizes(dc_128)
1269intra_pred_allsizes(dc_left)
1270intra_pred_allsizes(dc_top)
1271intra_pred_allsizes(dc)
1272/* clang-format on */
1273#undef intra_pred_allsizes