blob: 1f0870b647da9f4ee99e7a1d6871626df7c18dcc [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"
Urvang Joshiee7ee7f2017-03-09 13:19:03 -080020#include "aom_ports/bitops.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070021
22#define DST(x, y) dst[(x) + (y)*stride]
23#define AVG3(a, b, c) (((a) + 2 * (b) + (c) + 2) >> 2)
24#define AVG2(a, b) (((a) + (b) + 1) >> 1)
25
Yaowu Xuc27fc142016-08-22 16:08:15 -070026static INLINE void d207e_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
27 const uint8_t *above, const uint8_t *left) {
28 int r, c;
29 (void)above;
30
31 for (r = 0; r < bs; ++r) {
32 for (c = 0; c < bs; ++c) {
33 dst[c] = c & 1 ? AVG3(left[(c >> 1) + r], left[(c >> 1) + r + 1],
34 left[(c >> 1) + r + 2])
35 : AVG2(left[(c >> 1) + r], left[(c >> 1) + r + 1]);
36 }
37 dst += stride;
38 }
39}
40
Yaowu Xuc27fc142016-08-22 16:08:15 -070041static INLINE void d63e_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
42 const uint8_t *above, const uint8_t *left) {
43 int r, c;
44 (void)left;
45 for (r = 0; r < bs; ++r) {
46 for (c = 0; c < bs; ++c) {
47 dst[c] = r & 1 ? AVG3(above[(r >> 1) + c], above[(r >> 1) + c + 1],
48 above[(r >> 1) + c + 2])
49 : AVG2(above[(r >> 1) + c], above[(r >> 1) + c + 1]);
50 }
51 dst += stride;
52 }
53}
54
Yaowu Xuc27fc142016-08-22 16:08:15 -070055static INLINE void d45e_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
56 const uint8_t *above, const uint8_t *left) {
57 int r, c;
58 (void)left;
59 for (r = 0; r < bs; ++r) {
60 for (c = 0; c < bs; ++c) {
61 dst[c] = AVG3(above[r + c], above[r + c + 1],
62 above[r + c + 1 + (r + c + 2 < bs * 2)]);
63 }
64 dst += stride;
65 }
66}
67
68static INLINE void d117_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
69 const uint8_t *above, const uint8_t *left) {
70 int r, c;
71
72 // first row
73 for (c = 0; c < bs; c++) dst[c] = AVG2(above[c - 1], above[c]);
74 dst += stride;
75
76 // second row
77 dst[0] = AVG3(left[0], above[-1], above[0]);
78 for (c = 1; c < bs; c++) dst[c] = AVG3(above[c - 2], above[c - 1], above[c]);
79 dst += stride;
80
81 // the rest of first col
82 dst[0] = AVG3(above[-1], left[0], left[1]);
83 for (r = 3; r < bs; ++r)
84 dst[(r - 2) * stride] = AVG3(left[r - 3], left[r - 2], left[r - 1]);
85
86 // the rest of the block
87 for (r = 2; r < bs; ++r) {
88 for (c = 1; c < bs; c++) dst[c] = dst[-2 * stride + c - 1];
89 dst += stride;
90 }
91}
92
93static INLINE void d135_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
94 const uint8_t *above, const uint8_t *left) {
95 int i;
Debargha Mukherjee84c56af2016-11-19 10:59:37 -080096#if CONFIG_TX64X64
97#if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ > 7
98 // silence a spurious -Warray-bounds warning, possibly related to:
99 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56273
100 uint8_t border[133];
101#else
102 uint8_t border[64 + 64 - 1]; // outer border from bottom-left to top-right
103#endif
104#else
Yaowu Xuc27fc142016-08-22 16:08:15 -0700105#if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ > 7
106 // silence a spurious -Warray-bounds warning, possibly related to:
107 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56273
108 uint8_t border[69];
109#else
110 uint8_t border[32 + 32 - 1]; // outer border from bottom-left to top-right
111#endif
Debargha Mukherjee84c56af2016-11-19 10:59:37 -0800112#endif // CONFIG_TX64X64
Yaowu Xuc27fc142016-08-22 16:08:15 -0700113
114 // dst(bs, bs - 2)[0], i.e., border starting at bottom-left
115 for (i = 0; i < bs - 2; ++i) {
116 border[i] = AVG3(left[bs - 3 - i], left[bs - 2 - i], left[bs - 1 - i]);
117 }
118 border[bs - 2] = AVG3(above[-1], left[0], left[1]);
119 border[bs - 1] = AVG3(left[0], above[-1], above[0]);
120 border[bs - 0] = AVG3(above[-1], above[0], above[1]);
121 // dst[0][2, size), i.e., remaining top border ascending
122 for (i = 0; i < bs - 2; ++i) {
123 border[bs + 1 + i] = AVG3(above[i], above[i + 1], above[i + 2]);
124 }
125
126 for (i = 0; i < bs; ++i) {
127 memcpy(dst + i * stride, border + bs - 1 - i, bs);
128 }
129}
130
131static INLINE void d153_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
132 const uint8_t *above, const uint8_t *left) {
133 int r, c;
134 dst[0] = AVG2(above[-1], left[0]);
135 for (r = 1; r < bs; r++) dst[r * stride] = AVG2(left[r - 1], left[r]);
136 dst++;
137
138 dst[0] = AVG3(left[0], above[-1], above[0]);
139 dst[stride] = AVG3(above[-1], left[0], left[1]);
140 for (r = 2; r < bs; r++)
141 dst[r * stride] = AVG3(left[r - 2], left[r - 1], left[r]);
142 dst++;
143
144 for (c = 0; c < bs - 2; c++)
145 dst[c] = AVG3(above[c - 1], above[c], above[c + 1]);
146 dst += stride;
147
148 for (r = 1; r < bs; ++r) {
149 for (c = 0; c < bs - 2; c++) dst[c] = dst[-stride + c - 2];
150 dst += stride;
151 }
152}
153
154static INLINE void v_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
155 const uint8_t *above, const uint8_t *left) {
156 int r;
157 (void)left;
158
159 for (r = 0; r < bs; r++) {
160 memcpy(dst, above, bs);
161 dst += stride;
162 }
163}
164
165static INLINE void h_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
166 const uint8_t *above, const uint8_t *left) {
167 int r;
168 (void)above;
169
170 for (r = 0; r < bs; r++) {
171 memset(dst, left[r], bs);
172 dst += stride;
173 }
174}
175
Urvang Joshi340593e2016-09-01 12:03:20 -0700176#if CONFIG_ALT_INTRA
177static INLINE int abs_diff(int a, int b) { return (a > b) ? a - b : b - a; }
178
179static INLINE uint16_t paeth_predictor_single(uint16_t left, uint16_t top,
180 uint16_t top_left) {
181 const int base = top + left - top_left;
182 const int p_left = abs_diff(base, left);
183 const int p_top = abs_diff(base, top);
184 const int p_top_left = abs_diff(base, top_left);
185
186 // Return nearest to base of left, top and top_left.
187 return (p_left <= p_top && p_left <= p_top_left)
188 ? left
189 : (p_top <= p_top_left) ? top : top_left;
190}
191
192static INLINE void paeth_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
193 const uint8_t *above, const uint8_t *left) {
194 int r, c;
195 const uint8_t ytop_left = above[-1];
196
197 for (r = 0; r < bs; r++) {
198 for (c = 0; c < bs; c++)
199 dst[c] = (uint8_t)paeth_predictor_single(left[r], above[c], ytop_left);
200 dst += stride;
201 }
202}
203
Urvang Joshi3e42acd2017-02-23 13:02:08 -0800204// Weights are quadratic from '1' to '1 / block_size', scaled by
205// 2^sm_weight_log2_scale.
206static const int sm_weight_log2_scale = 8;
Urvang Joshi7a406002017-01-31 14:52:18 -0800207
Urvang Joshi6be4a542016-11-03 15:24:05 -0700208#if CONFIG_TX64X64
Urvang Joshiee7ee7f2017-03-09 13:19:03 -0800209// max(block_size_wide[BLOCK_LARGEST], block_size_high[BLOCK_LARGEST])
210#define MAX_BLOCK_DIM 64
211#define NUM_BLOCK_DIMS 6 // log2(MAX_BLOCK_DIM)
Urvang Joshi6be4a542016-11-03 15:24:05 -0700212#else
Urvang Joshiee7ee7f2017-03-09 13:19:03 -0800213#define MAX_BLOCK_DIM 32
214#define NUM_BLOCK_DIMS 5
Urvang Joshi6be4a542016-11-03 15:24:05 -0700215#endif // CONFIG_TX64X64
Urvang Joshiee7ee7f2017-03-09 13:19:03 -0800216
217static const uint8_t sm_weight_arrays[NUM_BLOCK_DIMS][MAX_BLOCK_DIM] = {
Urvang Joshi6be4a542016-11-03 15:24:05 -0700218 // bs = 2
Urvang Joshi4d5bbbd2017-03-02 17:10:44 -0800219 { 255, 128 },
Urvang Joshi6be4a542016-11-03 15:24:05 -0700220 // bs = 4
Urvang Joshi4d5bbbd2017-03-02 17:10:44 -0800221 { 255, 149, 85, 64 },
Urvang Joshi6be4a542016-11-03 15:24:05 -0700222 // bs = 8
Urvang Joshi4d5bbbd2017-03-02 17:10:44 -0800223 { 255, 197, 146, 105, 73, 50, 37, 32 },
Urvang Joshi6be4a542016-11-03 15:24:05 -0700224 // bs = 16
Urvang Joshi4d5bbbd2017-03-02 17:10:44 -0800225 { 255, 225, 196, 170, 145, 123, 102, 84, 68, 54, 43, 33, 26, 20, 17, 16 },
Urvang Joshi6be4a542016-11-03 15:24:05 -0700226 // bs = 32
Urvang Joshi3e42acd2017-02-23 13:02:08 -0800227 {
Urvang Joshi4d5bbbd2017-03-02 17:10:44 -0800228 255, 240, 225, 210, 196, 182, 169, 157, 145, 133, 122,
Urvang Joshi3e42acd2017-02-23 13:02:08 -0800229 111, 101, 92, 83, 74, 66, 59, 52, 45, 39, 34,
230 29, 25, 21, 17, 14, 12, 10, 9, 8, 8 },
Urvang Joshi6be4a542016-11-03 15:24:05 -0700231#if CONFIG_TX64X64
232 // bs = 64
Urvang Joshi4d5bbbd2017-03-02 17:10:44 -0800233 { 255, 248, 240, 233, 225, 218, 210, 203, 196, 189, 182, 176, 169,
Urvang Joshi3e42acd2017-02-23 13:02:08 -0800234 163, 156, 150, 144, 138, 133, 127, 121, 116, 111, 106, 101, 96,
235 91, 86, 82, 77, 73, 69, 65, 61, 57, 54, 50, 47, 44,
236 41, 38, 35, 32, 29, 27, 25, 22, 20, 18, 16, 15, 13,
237 12, 10, 9, 8, 7, 6, 6, 5, 5, 4, 4, 4 },
Urvang Joshi6be4a542016-11-03 15:24:05 -0700238#endif // CONFIG_TX64X64
239};
240
Urvang Joshi4d5bbbd2017-03-02 17:10:44 -0800241// Some basic checks on weights for smooth predictor.
242#define sm_weights_sanity_checks(weights, weights_scale, pred_scale) \
243 assert(weights[0] < weights_scale); \
244 assert(weights_scale - weights[bs - 1] < weights_scale); \
245 assert(pred_scale < 31) // ensures no overflow when calculating predictor.
246
Urvang Joshi7a406002017-01-31 14:52:18 -0800247#define divide_round(value, bits) (((value) + (1 << ((bits)-1))) >> (bits))
248
Urvang Joshi6be4a542016-11-03 15:24:05 -0700249static INLINE void smooth_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
250 const uint8_t *above, const uint8_t *left) {
251 const uint8_t below_pred = left[bs - 1]; // estimated by bottom-left pixel
252 const uint8_t right_pred = above[bs - 1]; // estimated by top-right pixel
Urvang Joshiee7ee7f2017-03-09 13:19:03 -0800253 const int arr_index = get_msb(bs) - 1;
254 assert(arr_index >= 0);
255 assert(arr_index < NUM_BLOCK_DIMS);
Urvang Joshi4d5bbbd2017-03-02 17:10:44 -0800256 const uint8_t *const sm_weights = sm_weight_arrays[arr_index];
Urvang Joshi81760812017-02-15 16:47:59 -0800257 // scale = 2 * 2^sm_weight_log2_scale
258 const int log2_scale = 1 + sm_weight_log2_scale;
Urvang Joshi4d5bbbd2017-03-02 17:10:44 -0800259 const uint16_t scale = (1 << sm_weight_log2_scale);
260 sm_weights_sanity_checks(sm_weights, scale, log2_scale + sizeof(*dst));
Urvang Joshi6be4a542016-11-03 15:24:05 -0700261 int r;
262 for (r = 0; r < bs; ++r) {
263 int c;
264 for (c = 0; c < bs; ++c) {
Urvang Joshi7a406002017-01-31 14:52:18 -0800265 const uint8_t pixels[] = { above[c], below_pred, left[r], right_pred };
Urvang Joshi4d5bbbd2017-03-02 17:10:44 -0800266 const uint8_t weights[] = { sm_weights[r], scale - sm_weights[r],
267 sm_weights[c], scale - sm_weights[c] };
Urvang Joshi7a406002017-01-31 14:52:18 -0800268 uint32_t this_pred = 0;
Urvang Joshi6be4a542016-11-03 15:24:05 -0700269 int i;
Urvang Joshi81760812017-02-15 16:47:59 -0800270 assert(scale >= sm_weights[r] && scale >= sm_weights[c]);
Urvang Joshi6be4a542016-11-03 15:24:05 -0700271 for (i = 0; i < 4; ++i) {
272 this_pred += weights[i] * pixels[i];
273 }
Urvang Joshi7a406002017-01-31 14:52:18 -0800274 dst[c] = clip_pixel(divide_round(this_pred, log2_scale));
Urvang Joshi6be4a542016-11-03 15:24:05 -0700275 }
276 dst += stride;
277 }
278}
279
Urvang Joshi340593e2016-09-01 12:03:20 -0700280#else
281
Yaowu Xuc27fc142016-08-22 16:08:15 -0700282static INLINE void tm_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
283 const uint8_t *above, const uint8_t *left) {
284 int r, c;
285 int ytop_left = above[-1];
286
287 for (r = 0; r < bs; r++) {
288 for (c = 0; c < bs; c++)
289 dst[c] = clip_pixel(left[r] + above[c] - ytop_left);
290 dst += stride;
291 }
292}
Urvang Joshi340593e2016-09-01 12:03:20 -0700293#endif // CONFIG_ALT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -0700294
295static INLINE void dc_128_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
296 const uint8_t *above, const uint8_t *left) {
297 int r;
298 (void)above;
299 (void)left;
300
301 for (r = 0; r < bs; r++) {
302 memset(dst, 128, bs);
303 dst += stride;
304 }
305}
306
307static INLINE void dc_left_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
308 const uint8_t *above,
309 const uint8_t *left) {
310 int i, r, expected_dc, sum = 0;
311 (void)above;
312
313 for (i = 0; i < bs; i++) sum += left[i];
314 expected_dc = (sum + (bs >> 1)) / bs;
315
316 for (r = 0; r < bs; r++) {
317 memset(dst, expected_dc, bs);
318 dst += stride;
319 }
320}
321
322static INLINE void dc_top_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
323 const uint8_t *above, const uint8_t *left) {
324 int i, r, expected_dc, sum = 0;
325 (void)left;
326
327 for (i = 0; i < bs; i++) sum += above[i];
328 expected_dc = (sum + (bs >> 1)) / bs;
329
330 for (r = 0; r < bs; r++) {
331 memset(dst, expected_dc, bs);
332 dst += stride;
333 }
334}
335
336static INLINE void dc_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
337 const uint8_t *above, const uint8_t *left) {
338 int i, r, expected_dc, sum = 0;
339 const int count = 2 * bs;
340
341 for (i = 0; i < bs; i++) {
342 sum += above[i];
343 sum += left[i];
344 }
345
346 expected_dc = (sum + (count >> 1)) / count;
347
348 for (r = 0; r < bs; r++) {
349 memset(dst, expected_dc, bs);
350 dst += stride;
351 }
352}
353
Jingning Han03b35142016-10-19 13:04:26 -0700354void aom_d45e_predictor_2x2_c(uint8_t *dst, ptrdiff_t stride,
355 const uint8_t *above, const uint8_t *left) {
356 const int A = above[0];
357 const int B = above[1];
358 const int C = above[2];
359 const int D = above[3];
Jingning Han03b35142016-10-19 13:04:26 -0700360 (void)stride;
361 (void)left;
Jingning Han8a7786d2016-12-15 20:37:47 -0800362
Jingning Han03b35142016-10-19 13:04:26 -0700363 DST(0, 0) = AVG3(A, B, C);
364 DST(1, 0) = DST(0, 1) = AVG3(B, C, D);
Jingning Han8a7786d2016-12-15 20:37:47 -0800365 DST(1, 1) = AVG3(C, D, D);
Jingning Han03b35142016-10-19 13:04:26 -0700366}
367
368void aom_d117_predictor_2x2_c(uint8_t *dst, ptrdiff_t stride,
369 const uint8_t *above, const uint8_t *left) {
370 const int I = left[0];
371 const int X = above[-1];
372 const int A = above[0];
373 const int B = above[1];
374 DST(0, 0) = AVG2(X, A);
375 DST(1, 0) = AVG2(A, B);
376 DST(0, 1) = AVG3(I, X, A);
377 DST(1, 1) = AVG3(X, A, B);
378}
379
380void aom_d135_predictor_2x2_c(uint8_t *dst, ptrdiff_t stride,
381 const uint8_t *above, const uint8_t *left) {
382 const int I = left[0];
383 const int J = left[1];
384 const int X = above[-1];
385 const int A = above[0];
386 const int B = above[1];
387 (void)stride;
388 DST(0, 1) = AVG3(X, I, J);
389 DST(1, 1) = DST(0, 0) = AVG3(A, X, I);
390 DST(1, 0) = AVG3(B, A, X);
391}
392
393void aom_d153_predictor_2x2_c(uint8_t *dst, ptrdiff_t stride,
394 const uint8_t *above, const uint8_t *left) {
395 const int I = left[0];
396 const int J = left[1];
397 const int X = above[-1];
398 const int A = above[0];
399
400 DST(0, 0) = AVG2(I, X);
401 DST(0, 1) = AVG2(J, I);
402 DST(1, 0) = AVG3(I, X, A);
403 DST(1, 1) = AVG3(J, I, X);
404}
405
Yaowu Xuf883b422016-08-30 14:01:10 -0700406void aom_d45e_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700407 const uint8_t *above, const uint8_t *left) {
408 const int A = above[0];
409 const int B = above[1];
410 const int C = above[2];
411 const int D = above[3];
412 const int E = above[4];
413 const int F = above[5];
414 const int G = above[6];
415 const int H = above[7];
416 (void)stride;
417 (void)left;
418 DST(0, 0) = AVG3(A, B, C);
419 DST(1, 0) = DST(0, 1) = AVG3(B, C, D);
420 DST(2, 0) = DST(1, 1) = DST(0, 2) = AVG3(C, D, E);
421 DST(3, 0) = DST(2, 1) = DST(1, 2) = DST(0, 3) = AVG3(D, E, F);
422 DST(3, 1) = DST(2, 2) = DST(1, 3) = AVG3(E, F, G);
423 DST(3, 2) = DST(2, 3) = AVG3(F, G, H);
424 DST(3, 3) = AVG3(G, H, H);
425}
426
Yaowu Xuf883b422016-08-30 14:01:10 -0700427void aom_d117_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700428 const uint8_t *above, const uint8_t *left) {
429 const int I = left[0];
430 const int J = left[1];
431 const int K = left[2];
432 const int X = above[-1];
433 const int A = above[0];
434 const int B = above[1];
435 const int C = above[2];
436 const int D = above[3];
437 DST(0, 0) = DST(1, 2) = AVG2(X, A);
438 DST(1, 0) = DST(2, 2) = AVG2(A, B);
439 DST(2, 0) = DST(3, 2) = AVG2(B, C);
440 DST(3, 0) = AVG2(C, D);
441
442 DST(0, 3) = AVG3(K, J, I);
443 DST(0, 2) = AVG3(J, I, X);
444 DST(0, 1) = DST(1, 3) = AVG3(I, X, A);
445 DST(1, 1) = DST(2, 3) = AVG3(X, A, B);
446 DST(2, 1) = DST(3, 3) = AVG3(A, B, C);
447 DST(3, 1) = AVG3(B, C, D);
448}
449
Yaowu Xuf883b422016-08-30 14:01:10 -0700450void aom_d135_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700451 const uint8_t *above, const uint8_t *left) {
452 const int I = left[0];
453 const int J = left[1];
454 const int K = left[2];
455 const int L = left[3];
456 const int X = above[-1];
457 const int A = above[0];
458 const int B = above[1];
459 const int C = above[2];
460 const int D = above[3];
461 (void)stride;
462 DST(0, 3) = AVG3(J, K, L);
463 DST(1, 3) = DST(0, 2) = AVG3(I, J, K);
464 DST(2, 3) = DST(1, 2) = DST(0, 1) = AVG3(X, I, J);
465 DST(3, 3) = DST(2, 2) = DST(1, 1) = DST(0, 0) = AVG3(A, X, I);
466 DST(3, 2) = DST(2, 1) = DST(1, 0) = AVG3(B, A, X);
467 DST(3, 1) = DST(2, 0) = AVG3(C, B, A);
468 DST(3, 0) = AVG3(D, C, B);
469}
470
Yaowu Xuf883b422016-08-30 14:01:10 -0700471void aom_d153_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700472 const uint8_t *above, const uint8_t *left) {
473 const int I = left[0];
474 const int J = left[1];
475 const int K = left[2];
476 const int L = left[3];
477 const int X = above[-1];
478 const int A = above[0];
479 const int B = above[1];
480 const int C = above[2];
481
482 DST(0, 0) = DST(2, 1) = AVG2(I, X);
483 DST(0, 1) = DST(2, 2) = AVG2(J, I);
484 DST(0, 2) = DST(2, 3) = AVG2(K, J);
485 DST(0, 3) = AVG2(L, K);
486
487 DST(3, 0) = AVG3(A, B, C);
488 DST(2, 0) = AVG3(X, A, B);
489 DST(1, 0) = DST(3, 1) = AVG3(I, X, A);
490 DST(1, 1) = DST(3, 2) = AVG3(J, I, X);
491 DST(1, 2) = DST(3, 3) = AVG3(K, J, I);
492 DST(1, 3) = AVG3(L, K, J);
493}
494
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200495#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700496static INLINE void highbd_d207e_predictor(uint16_t *dst, ptrdiff_t stride,
497 int bs, const uint16_t *above,
498 const uint16_t *left, int bd) {
499 int r, c;
500 (void)above;
501 (void)bd;
502
503 for (r = 0; r < bs; ++r) {
504 for (c = 0; c < bs; ++c) {
505 dst[c] = c & 1 ? AVG3(left[(c >> 1) + r], left[(c >> 1) + r + 1],
506 left[(c >> 1) + r + 2])
507 : AVG2(left[(c >> 1) + r], left[(c >> 1) + r + 1]);
508 }
509 dst += stride;
510 }
511}
512
Urvang Joshic3bcf3b2017-04-21 13:09:43 -0700513static INLINE void highbd_d63e_predictor(uint16_t *dst, ptrdiff_t stride,
514 int bs, const uint16_t *above,
515 const uint16_t *left, int bd) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700516 int r, c;
517 (void)left;
518 (void)bd;
519 for (r = 0; r < bs; ++r) {
520 for (c = 0; c < bs; ++c) {
521 dst[c] = r & 1 ? AVG3(above[(r >> 1) + c], above[(r >> 1) + c + 1],
522 above[(r >> 1) + c + 2])
523 : AVG2(above[(r >> 1) + c], above[(r >> 1) + c + 1]);
524 }
525 dst += stride;
526 }
527}
528
Yaowu Xuc27fc142016-08-22 16:08:15 -0700529static INLINE void highbd_d45e_predictor(uint16_t *dst, ptrdiff_t stride,
530 int bs, const uint16_t *above,
531 const uint16_t *left, int bd) {
532 int r, c;
533 (void)left;
534 (void)bd;
535 for (r = 0; r < bs; ++r) {
536 for (c = 0; c < bs; ++c) {
537 dst[c] = AVG3(above[r + c], above[r + c + 1],
538 above[r + c + 1 + (r + c + 2 < bs * 2)]);
539 }
540 dst += stride;
541 }
542}
543
544static INLINE void highbd_d117_predictor(uint16_t *dst, ptrdiff_t stride,
545 int bs, const uint16_t *above,
546 const uint16_t *left, int bd) {
547 int r, c;
548 (void)bd;
549
550 // first row
551 for (c = 0; c < bs; c++) dst[c] = AVG2(above[c - 1], above[c]);
552 dst += stride;
553
554 // second row
555 dst[0] = AVG3(left[0], above[-1], above[0]);
556 for (c = 1; c < bs; c++) dst[c] = AVG3(above[c - 2], above[c - 1], above[c]);
557 dst += stride;
558
559 // the rest of first col
560 dst[0] = AVG3(above[-1], left[0], left[1]);
561 for (r = 3; r < bs; ++r)
562 dst[(r - 2) * stride] = AVG3(left[r - 3], left[r - 2], left[r - 1]);
563
564 // the rest of the block
565 for (r = 2; r < bs; ++r) {
566 for (c = 1; c < bs; c++) dst[c] = dst[-2 * stride + c - 1];
567 dst += stride;
568 }
569}
570
571static INLINE void highbd_d135_predictor(uint16_t *dst, ptrdiff_t stride,
572 int bs, const uint16_t *above,
573 const uint16_t *left, int bd) {
574 int r, c;
575 (void)bd;
576 dst[0] = AVG3(left[0], above[-1], above[0]);
577 for (c = 1; c < bs; c++) dst[c] = AVG3(above[c - 2], above[c - 1], above[c]);
578
579 dst[stride] = AVG3(above[-1], left[0], left[1]);
580 for (r = 2; r < bs; ++r)
581 dst[r * stride] = AVG3(left[r - 2], left[r - 1], left[r]);
582
583 dst += stride;
584 for (r = 1; r < bs; ++r) {
585 for (c = 1; c < bs; c++) dst[c] = dst[-stride + c - 1];
586 dst += stride;
587 }
588}
589
590static INLINE void highbd_d153_predictor(uint16_t *dst, ptrdiff_t stride,
591 int bs, const uint16_t *above,
592 const uint16_t *left, int bd) {
593 int r, c;
594 (void)bd;
595 dst[0] = AVG2(above[-1], left[0]);
596 for (r = 1; r < bs; r++) dst[r * stride] = AVG2(left[r - 1], left[r]);
597 dst++;
598
599 dst[0] = AVG3(left[0], above[-1], above[0]);
600 dst[stride] = AVG3(above[-1], left[0], left[1]);
601 for (r = 2; r < bs; r++)
602 dst[r * stride] = AVG3(left[r - 2], left[r - 1], left[r]);
603 dst++;
604
605 for (c = 0; c < bs - 2; c++)
606 dst[c] = AVG3(above[c - 1], above[c], above[c + 1]);
607 dst += stride;
608
609 for (r = 1; r < bs; ++r) {
610 for (c = 0; c < bs - 2; c++) dst[c] = dst[-stride + c - 2];
611 dst += stride;
612 }
613}
614
615static INLINE void highbd_v_predictor(uint16_t *dst, ptrdiff_t stride, int bs,
616 const uint16_t *above,
617 const uint16_t *left, int bd) {
618 int r;
619 (void)left;
620 (void)bd;
621 for (r = 0; r < bs; r++) {
622 memcpy(dst, above, bs * sizeof(uint16_t));
623 dst += stride;
624 }
625}
626
627static INLINE void highbd_h_predictor(uint16_t *dst, ptrdiff_t stride, int bs,
628 const uint16_t *above,
629 const uint16_t *left, int bd) {
630 int r;
631 (void)above;
632 (void)bd;
633 for (r = 0; r < bs; r++) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700634 aom_memset16(dst, left[r], bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700635 dst += stride;
636 }
637}
638
Jingning Han324b4c62016-12-19 09:33:04 -0800639void aom_highbd_d207_predictor_2x2_c(uint16_t *dst, ptrdiff_t stride,
640 const uint16_t *above,
641 const uint16_t *left, int bd) {
642 const int I = left[0];
643 const int J = left[1];
644 const int K = left[2];
645 const int L = left[3];
646 (void)above;
647 (void)bd;
648 DST(0, 0) = AVG2(I, J);
649 DST(0, 1) = AVG2(J, K);
650 DST(1, 0) = AVG3(I, J, K);
651 DST(1, 1) = AVG3(J, K, L);
652}
653
654void aom_highbd_d63_predictor_2x2_c(uint16_t *dst, ptrdiff_t stride,
655 const uint16_t *above, const uint16_t *left,
656 int bd) {
657 const int A = above[0];
658 const int B = above[1];
659 const int C = above[2];
660 const int D = above[3];
661 (void)left;
662 (void)bd;
663 DST(0, 0) = AVG2(A, B);
664 DST(1, 0) = AVG2(B, C);
665 DST(0, 1) = AVG3(A, B, C);
666 DST(1, 1) = AVG3(B, C, D);
667}
668
669void aom_highbd_d45e_predictor_2x2_c(uint16_t *dst, ptrdiff_t stride,
670 const uint16_t *above,
671 const uint16_t *left, int bd) {
672 const int A = above[0];
673 const int B = above[1];
674 const int C = above[2];
675 const int D = above[3];
676 (void)stride;
677 (void)left;
678 (void)bd;
679 DST(0, 0) = AVG3(A, B, C);
680 DST(1, 0) = DST(0, 1) = AVG3(B, C, D);
681 DST(1, 1) = AVG3(C, D, D);
682}
683
684void aom_highbd_d117_predictor_2x2_c(uint16_t *dst, ptrdiff_t stride,
685 const uint16_t *above,
686 const uint16_t *left, int bd) {
687 const int I = left[0];
688 const int X = above[-1];
689 const int A = above[0];
690 const int B = above[1];
691 (void)bd;
692 DST(0, 0) = AVG2(X, A);
693 DST(1, 0) = AVG2(A, B);
694 DST(0, 1) = AVG3(I, X, A);
695 DST(1, 1) = AVG3(X, A, B);
696}
697
698void aom_highbd_d135_predictor_2x2_c(uint16_t *dst, ptrdiff_t stride,
699 const uint16_t *above,
700 const uint16_t *left, int bd) {
701 const int I = left[0];
702 const int J = left[1];
703 const int X = above[-1];
704 const int A = above[0];
705 const int B = above[1];
706 (void)bd;
707 DST(0, 1) = AVG3(X, I, J);
708 DST(1, 1) = DST(0, 0) = AVG3(A, X, I);
709 DST(1, 0) = AVG3(B, A, X);
710}
711
712void aom_highbd_d153_predictor_2x2_c(uint16_t *dst, ptrdiff_t stride,
713 const uint16_t *above,
714 const uint16_t *left, int bd) {
715 const int I = left[0];
716 const int J = left[1];
717 const int X = above[-1];
718 const int A = above[0];
719 (void)bd;
720 DST(0, 0) = AVG2(I, X);
721 DST(0, 1) = AVG2(J, I);
722 DST(1, 0) = AVG3(I, X, A);
723 DST(1, 1) = AVG3(J, I, X);
724}
725
Urvang Joshi340593e2016-09-01 12:03:20 -0700726#if CONFIG_ALT_INTRA
727static INLINE void highbd_paeth_predictor(uint16_t *dst, ptrdiff_t stride,
728 int bs, const uint16_t *above,
729 const uint16_t *left, int bd) {
730 int r, c;
731 const uint16_t ytop_left = above[-1];
732 (void)bd;
733
734 for (r = 0; r < bs; r++) {
735 for (c = 0; c < bs; c++)
736 dst[c] = paeth_predictor_single(left[r], above[c], ytop_left);
737 dst += stride;
738 }
739}
740
Urvang Joshi6be4a542016-11-03 15:24:05 -0700741static INLINE void highbd_smooth_predictor(uint16_t *dst, ptrdiff_t stride,
742 int bs, const uint16_t *above,
743 const uint16_t *left, int bd) {
744 const uint16_t below_pred = left[bs - 1]; // estimated by bottom-left pixel
745 const uint16_t right_pred = above[bs - 1]; // estimated by top-right pixel
Urvang Joshiee7ee7f2017-03-09 13:19:03 -0800746 const int arr_index = get_msb(bs) - 1;
747 assert(arr_index >= 0);
748 assert(arr_index < NUM_BLOCK_DIMS);
Urvang Joshi4d5bbbd2017-03-02 17:10:44 -0800749 const uint8_t *const sm_weights = sm_weight_arrays[arr_index];
Urvang Joshi81760812017-02-15 16:47:59 -0800750 // scale = 2 * 2^sm_weight_log2_scale
751 const int log2_scale = 1 + sm_weight_log2_scale;
Urvang Joshi4d5bbbd2017-03-02 17:10:44 -0800752 const uint16_t scale = (1 << sm_weight_log2_scale);
753 sm_weights_sanity_checks(sm_weights, scale, log2_scale + sizeof(*dst));
Urvang Joshi6be4a542016-11-03 15:24:05 -0700754 int r;
755 for (r = 0; r < bs; ++r) {
756 int c;
757 for (c = 0; c < bs; ++c) {
Urvang Joshi7a406002017-01-31 14:52:18 -0800758 const uint16_t pixels[] = { above[c], below_pred, left[r], right_pred };
Urvang Joshi4d5bbbd2017-03-02 17:10:44 -0800759 const uint8_t weights[] = { sm_weights[r], scale - sm_weights[r],
760 sm_weights[c], scale - sm_weights[c] };
Urvang Joshi7a406002017-01-31 14:52:18 -0800761 uint32_t this_pred = 0;
Urvang Joshi6be4a542016-11-03 15:24:05 -0700762 int i;
Urvang Joshi81760812017-02-15 16:47:59 -0800763 assert(scale >= sm_weights[r] && scale >= sm_weights[c]);
Urvang Joshi6be4a542016-11-03 15:24:05 -0700764 for (i = 0; i < 4; ++i) {
765 this_pred += weights[i] * pixels[i];
766 }
Urvang Joshi7a406002017-01-31 14:52:18 -0800767 dst[c] = clip_pixel_highbd(divide_round(this_pred, log2_scale), bd);
Urvang Joshi6be4a542016-11-03 15:24:05 -0700768 }
769 dst += stride;
770 }
771}
772
Urvang Joshi340593e2016-09-01 12:03:20 -0700773#else
Yaowu Xuc27fc142016-08-22 16:08:15 -0700774static INLINE void highbd_tm_predictor(uint16_t *dst, ptrdiff_t stride, int bs,
775 const uint16_t *above,
776 const uint16_t *left, int bd) {
777 int r, c;
778 int ytop_left = above[-1];
779 (void)bd;
780
781 for (r = 0; r < bs; r++) {
782 for (c = 0; c < bs; c++)
783 dst[c] = clip_pixel_highbd(left[r] + above[c] - ytop_left, bd);
784 dst += stride;
785 }
786}
Urvang Joshi340593e2016-09-01 12:03:20 -0700787#endif // CONFIG_ALT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -0700788
789static INLINE void highbd_dc_128_predictor(uint16_t *dst, ptrdiff_t stride,
790 int bs, const uint16_t *above,
791 const uint16_t *left, int bd) {
792 int r;
793 (void)above;
794 (void)left;
795
796 for (r = 0; r < bs; r++) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700797 aom_memset16(dst, 128 << (bd - 8), bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700798 dst += stride;
799 }
800}
801
802static INLINE void highbd_dc_left_predictor(uint16_t *dst, ptrdiff_t stride,
803 int bs, const uint16_t *above,
804 const uint16_t *left, int bd) {
805 int i, r, expected_dc, sum = 0;
806 (void)above;
807 (void)bd;
808
809 for (i = 0; i < bs; i++) sum += left[i];
810 expected_dc = (sum + (bs >> 1)) / bs;
811
812 for (r = 0; r < bs; r++) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700813 aom_memset16(dst, expected_dc, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700814 dst += stride;
815 }
816}
817
818static INLINE void highbd_dc_top_predictor(uint16_t *dst, ptrdiff_t stride,
819 int bs, const uint16_t *above,
820 const uint16_t *left, int bd) {
821 int i, r, expected_dc, sum = 0;
822 (void)left;
823 (void)bd;
824
825 for (i = 0; i < bs; i++) sum += above[i];
826 expected_dc = (sum + (bs >> 1)) / bs;
827
828 for (r = 0; r < bs; r++) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700829 aom_memset16(dst, expected_dc, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700830 dst += stride;
831 }
832}
833
834static INLINE void highbd_dc_predictor(uint16_t *dst, ptrdiff_t stride, int bs,
835 const uint16_t *above,
836 const uint16_t *left, int bd) {
837 int i, r, expected_dc, sum = 0;
838 const int count = 2 * bs;
839 (void)bd;
840
841 for (i = 0; i < bs; i++) {
842 sum += above[i];
843 sum += left[i];
844 }
845
846 expected_dc = (sum + (count >> 1)) / count;
847
848 for (r = 0; r < bs; r++) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700849 aom_memset16(dst, expected_dc, bs);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700850 dst += stride;
851 }
852}
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200853#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700854
855// This serves as a wrapper function, so that all the prediction functions
856// can be unified and accessed as a pointer array. Note that the boundary
857// above and left are not necessarily used all the time.
858#define intra_pred_sized(type, size) \
Yaowu Xuf883b422016-08-30 14:01:10 -0700859 void aom_##type##_predictor_##size##x##size##_c( \
Yaowu Xuc27fc142016-08-22 16:08:15 -0700860 uint8_t *dst, ptrdiff_t stride, const uint8_t *above, \
861 const uint8_t *left) { \
862 type##_predictor(dst, stride, size, above, left); \
863 }
864
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200865#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700866#define intra_pred_highbd_sized(type, size) \
Yaowu Xuf883b422016-08-30 14:01:10 -0700867 void aom_highbd_##type##_predictor_##size##x##size##_c( \
Yaowu Xuc27fc142016-08-22 16:08:15 -0700868 uint16_t *dst, ptrdiff_t stride, const uint16_t *above, \
869 const uint16_t *left, int bd) { \
870 highbd_##type##_predictor(dst, stride, size, above, left, bd); \
871 }
872
873/* clang-format off */
Debargha Mukherjee84c56af2016-11-19 10:59:37 -0800874#if CONFIG_TX64X64
875#define intra_pred_allsizes(type) \
876 intra_pred_sized(type, 2) \
877 intra_pred_sized(type, 4) \
878 intra_pred_sized(type, 8) \
879 intra_pred_sized(type, 16) \
880 intra_pred_sized(type, 32) \
881 intra_pred_sized(type, 64) \
882 intra_pred_highbd_sized(type, 4) \
883 intra_pred_highbd_sized(type, 8) \
884 intra_pred_highbd_sized(type, 16) \
885 intra_pred_highbd_sized(type, 32) \
886 intra_pred_highbd_sized(type, 64)
887
888#define intra_pred_above_4x4(type) \
889 intra_pred_sized(type, 8) \
890 intra_pred_sized(type, 16) \
891 intra_pred_sized(type, 32) \
892 intra_pred_sized(type, 64) \
893 intra_pred_highbd_sized(type, 4) \
894 intra_pred_highbd_sized(type, 8) \
895 intra_pred_highbd_sized(type, 16) \
896 intra_pred_highbd_sized(type, 32) \
897 intra_pred_highbd_sized(type, 64)
898#else // CONFIG_TX64X64
Yaowu Xuc27fc142016-08-22 16:08:15 -0700899#define intra_pred_allsizes(type) \
Jingning Hane3954d82016-10-12 21:03:18 -0700900 intra_pred_sized(type, 2) \
Yaowu Xuc27fc142016-08-22 16:08:15 -0700901 intra_pred_sized(type, 4) \
902 intra_pred_sized(type, 8) \
903 intra_pred_sized(type, 16) \
904 intra_pred_sized(type, 32) \
Jingning Han324b4c62016-12-19 09:33:04 -0800905 intra_pred_highbd_sized(type, 2) \
Yaowu Xuc27fc142016-08-22 16:08:15 -0700906 intra_pred_highbd_sized(type, 4) \
907 intra_pred_highbd_sized(type, 8) \
908 intra_pred_highbd_sized(type, 16) \
909 intra_pred_highbd_sized(type, 32)
910
Jingning Hane3954d82016-10-12 21:03:18 -0700911#define intra_pred_above_4x4(type) \
Yaowu Xuc27fc142016-08-22 16:08:15 -0700912 intra_pred_sized(type, 8) \
913 intra_pred_sized(type, 16) \
914 intra_pred_sized(type, 32) \
915 intra_pred_highbd_sized(type, 4) \
916 intra_pred_highbd_sized(type, 8) \
917 intra_pred_highbd_sized(type, 16) \
918 intra_pred_highbd_sized(type, 32)
Debargha Mukherjee84c56af2016-11-19 10:59:37 -0800919#endif // CONFIG_TX64X64
Yaowu Xuc27fc142016-08-22 16:08:15 -0700920
921#else
Debargha Mukherjee84c56af2016-11-19 10:59:37 -0800922
923#if CONFIG_TX64X64
924#define intra_pred_allsizes(type) \
925 intra_pred_sized(type, 2) \
926 intra_pred_sized(type, 4) \
927 intra_pred_sized(type, 8) \
928 intra_pred_sized(type, 16) \
929 intra_pred_sized(type, 32) \
930 intra_pred_sized(type, 64)
931
932#define intra_pred_above_4x4(type) \
933 intra_pred_sized(type, 8) \
934 intra_pred_sized(type, 16) \
935 intra_pred_sized(type, 32) \
936 intra_pred_sized(type, 64)
937#else // CONFIG_TX64X64
Yaowu Xuc27fc142016-08-22 16:08:15 -0700938#define intra_pred_allsizes(type) \
Jingning Hane3954d82016-10-12 21:03:18 -0700939 intra_pred_sized(type, 2) \
Yaowu Xuc27fc142016-08-22 16:08:15 -0700940 intra_pred_sized(type, 4) \
941 intra_pred_sized(type, 8) \
942 intra_pred_sized(type, 16) \
943 intra_pred_sized(type, 32)
944
Jingning Hane3954d82016-10-12 21:03:18 -0700945#define intra_pred_above_4x4(type) \
Yaowu Xuc27fc142016-08-22 16:08:15 -0700946 intra_pred_sized(type, 8) \
947 intra_pred_sized(type, 16) \
948 intra_pred_sized(type, 32)
Debargha Mukherjee84c56af2016-11-19 10:59:37 -0800949#endif // CONFIG_TX64X64
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200950#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700951
Yaowu Xuc27fc142016-08-22 16:08:15 -0700952intra_pred_allsizes(d207e)
953intra_pred_allsizes(d63e)
Jingning Hane3954d82016-10-12 21:03:18 -0700954intra_pred_above_4x4(d45e)
955intra_pred_above_4x4(d117)
956intra_pred_above_4x4(d135)
957intra_pred_above_4x4(d153)
Yaowu Xuc27fc142016-08-22 16:08:15 -0700958intra_pred_allsizes(v)
959intra_pred_allsizes(h)
Urvang Joshi340593e2016-09-01 12:03:20 -0700960#if CONFIG_ALT_INTRA
961intra_pred_allsizes(paeth)
Urvang Joshi6be4a542016-11-03 15:24:05 -0700962intra_pred_allsizes(smooth)
Urvang Joshi340593e2016-09-01 12:03:20 -0700963#else
Yaowu Xuc27fc142016-08-22 16:08:15 -0700964intra_pred_allsizes(tm)
Urvang Joshi340593e2016-09-01 12:03:20 -0700965#endif // CONFIG_ALT_INTRA
Yaowu Xuc27fc142016-08-22 16:08:15 -0700966intra_pred_allsizes(dc_128)
967intra_pred_allsizes(dc_left)
968intra_pred_allsizes(dc_top)
969intra_pred_allsizes(dc)
970/* clang-format on */
971#undef intra_pred_allsizes