blob: e28f01cb7da37a74ad5f1a56ef4b41c0d3a0fa51 [file] [log] [blame]
Jingning Han3ee6db62015-08-05 19:00:31 -07001/*
2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
hui sube3559b2015-10-07 09:29:02 -070011#include <math.h>
12
Jingning Han3ee6db62015-08-05 19:00:31 -070013#include "./vpx_config.h"
14#include "./vpx_dsp_rtcd.h"
15
16#if CONFIG_VP9_HIGHBITDEPTH
17#include "vpx_dsp/vpx_dsp_common.h"
18#endif // CONFIG_VP9_HIGHBITDEPTH
19#include "vpx_mem/vpx_mem.h"
20#include "vpx_ports/mem.h"
21#include "vpx_ports/vpx_once.h"
22
Jingning Han54d66ef2015-08-06 21:14:07 -070023#include "vp10/common/reconintra.h"
24#include "vp10/common/onyxc_int.h"
Jingning Han3ee6db62015-08-05 19:00:31 -070025
Ronald S. Bultjec7dc1d72015-10-12 10:35:46 -040026enum {
27 NEED_LEFT = 1 << 1,
28 NEED_ABOVE = 1 << 2,
29 NEED_ABOVERIGHT = 1 << 3,
30 NEED_ABOVELEFT = 1 << 4,
31 NEED_BOTTOMLEFT = 1 << 5,
32};
33
34static const uint8_t extend_modes[INTRA_MODES] = {
35 NEED_ABOVE | NEED_LEFT, // DC
36 NEED_ABOVE, // V
37 NEED_LEFT, // H
38 NEED_ABOVE | NEED_ABOVERIGHT, // D45
39 NEED_LEFT | NEED_ABOVE | NEED_ABOVELEFT, // D135
40 NEED_LEFT | NEED_ABOVE | NEED_ABOVELEFT, // D117
41 NEED_LEFT | NEED_ABOVE | NEED_ABOVELEFT, // D153
42 NEED_LEFT | NEED_BOTTOMLEFT, // D207
43 NEED_ABOVE | NEED_ABOVERIGHT, // D63
44 NEED_LEFT | NEED_ABOVE | NEED_ABOVELEFT, // TM
45};
Jingning Han3ee6db62015-08-05 19:00:31 -070046
Ronald S. Bultjec7dc1d72015-10-12 10:35:46 -040047static const uint8_t orders_64x64[1] = { 0 };
48static const uint8_t orders_64x32[2] = { 0, 1 };
49static const uint8_t orders_32x64[2] = { 0, 1 };
50static const uint8_t orders_32x32[4] = {
51 0, 1,
52 2, 3,
53};
54static const uint8_t orders_32x16[8] = {
55 0, 2,
56 1, 3,
57 4, 6,
58 5, 7,
59};
60static const uint8_t orders_16x32[8] = {
61 0, 1, 2, 3,
62 4, 5, 6, 7,
63};
64static const uint8_t orders_16x16[16] = {
65 0, 1, 4, 5,
66 2, 3, 6, 7,
67 8, 9, 12, 13,
68 10, 11, 14, 15,
69};
70static const uint8_t orders_16x8[32] = {
71 0, 2, 8, 10,
72 1, 3, 9, 11,
73 4, 6, 12, 14,
74 5, 7, 13, 15,
75 16, 18, 24, 26,
76 17, 19, 25, 27,
77 20, 22, 28, 30,
78 21, 23, 29, 31,
79};
80static const uint8_t orders_8x16[32] = {
81 0, 1, 2, 3, 8, 9, 10, 11,
82 4, 5, 6, 7, 12, 13, 14, 15,
83 16, 17, 18, 19, 24, 25, 26, 27,
84 20, 21, 22, 23, 28, 29, 30, 31,
85};
86static const uint8_t orders_8x8[64] = {
87 0, 1, 4, 5, 16, 17, 20, 21,
88 2, 3, 6, 7, 18, 19, 22, 23,
89 8, 9, 12, 13, 24, 25, 28, 29,
90 10, 11, 14, 15, 26, 27, 30, 31,
91 32, 33, 36, 37, 48, 49, 52, 53,
92 34, 35, 38, 39, 50, 51, 54, 55,
93 40, 41, 44, 45, 56, 57, 60, 61,
94 42, 43, 46, 47, 58, 59, 62, 63,
95};
96static const uint8_t *const orders[BLOCK_SIZES] = {
97 orders_8x8, orders_8x8, orders_8x8, orders_8x8,
98 orders_8x16, orders_16x8, orders_16x16,
99 orders_16x32, orders_32x16, orders_32x32,
100 orders_32x64, orders_64x32, orders_64x64,
101};
102
103static int vp10_has_right(BLOCK_SIZE bsize, int mi_row, int mi_col,
104 int right_available,
105 TX_SIZE txsz, int y, int x, int ss_x) {
hui subf0ff092015-12-01 17:19:52 -0800106 const int wl = mi_width_log2_lookup[bsize];
107 const int w = VPXMAX(num_4x4_blocks_wide_lookup[bsize] >> ss_x, 1);
108 const int step = 1 << txsz;
109
hui su935a8372016-02-29 09:27:33 -0800110 // Handle block size 4x8 and 4x4
111 if (ss_x == 0 && num_4x4_blocks_wide_lookup[bsize] < 2 && x == 0)
112 return 1;
113
Ronald S. Bultjec7dc1d72015-10-12 10:35:46 -0400114 if (y == 0) {
hui subf0ff092015-12-01 17:19:52 -0800115 const int hl = mi_height_log2_lookup[bsize];
Ronald S. Bultjec7dc1d72015-10-12 10:35:46 -0400116 const uint8_t *order = orders[bsize];
117 int my_order, tr_order;
118
119 if (x + step < w)
120 return 1;
121
122 mi_row = (mi_row & 7) >> hl;
123 mi_col = (mi_col & 7) >> wl;
124
125 if (mi_row == 0)
126 return right_available;
127
128 if (((mi_col + 1) << wl) >= 8)
129 return 0;
130
131 my_order = order[((mi_row + 0) << (3 - wl)) + mi_col + 0];
132 tr_order = order[((mi_row - 1) << (3 - wl)) + mi_col + 1];
133
134 return my_order > tr_order && right_available;
135 } else {
Ronald S. Bultjec7dc1d72015-10-12 10:35:46 -0400136 return x + step < w;
137 }
138}
139
140static int vp10_has_bottom(BLOCK_SIZE bsize, int mi_row, int mi_col,
141 int bottom_available, TX_SIZE txsz,
142 int y, int x, int ss_y) {
143 if (x == 0) {
hui subf0ff092015-12-01 17:19:52 -0800144 const int wl = mi_width_log2_lookup[bsize];
145 const int hl = mi_height_log2_lookup[bsize];
146 const int h = 1 << (hl + 1 - ss_y);
147 const int step = 1 << txsz;
Ronald S. Bultjec7dc1d72015-10-12 10:35:46 -0400148 const uint8_t *order = orders[bsize];
149 int my_order, bl_order;
150
hui su935a8372016-02-29 09:27:33 -0800151 // Handle block size 8x4 and 4x4
152 if (ss_y == 0 && num_4x4_blocks_high_lookup[bsize] < 2 && y == 0)
153 return 1;
154
155 if (y + step < h)
156 return 1;
157
Ronald S. Bultjec7dc1d72015-10-12 10:35:46 -0400158 mi_row = (mi_row & 7) >> hl;
159 mi_col = (mi_col & 7) >> wl;
160
161 if (mi_col == 0)
162 return bottom_available &&
163 (mi_row << (hl + !ss_y)) + y + step < (8 << !ss_y);
164
165 if (((mi_row + 1) << hl) >= 8)
166 return 0;
167
Ronald S. Bultjec7dc1d72015-10-12 10:35:46 -0400168 my_order = order[((mi_row + 0) << (3 - wl)) + mi_col + 0];
169 bl_order = order[((mi_row + 1) << (3 - wl)) + mi_col - 1];
170
171 return bl_order < my_order && bottom_available;
172 } else {
173 return 0;
174 }
175}
Jingning Han3ee6db62015-08-05 19:00:31 -0700176
177typedef void (*intra_pred_fn)(uint8_t *dst, ptrdiff_t stride,
178 const uint8_t *above, const uint8_t *left);
179
180static intra_pred_fn pred[INTRA_MODES][TX_SIZES];
181static intra_pred_fn dc_pred[2][2][TX_SIZES];
182
183#if CONFIG_VP9_HIGHBITDEPTH
184typedef void (*intra_high_pred_fn)(uint16_t *dst, ptrdiff_t stride,
185 const uint16_t *above, const uint16_t *left,
186 int bd);
187static intra_high_pred_fn pred_high[INTRA_MODES][4];
188static intra_high_pred_fn dc_pred_high[2][2][4];
189#endif // CONFIG_VP9_HIGHBITDEPTH
190
191static void vp10_init_intra_predictors_internal(void) {
Ronald S. Bultje62a15792015-09-30 18:45:08 -0400192#define INIT_NO_4X4(p, type) \
Jingning Han3ee6db62015-08-05 19:00:31 -0700193 p[TX_8X8] = vpx_##type##_predictor_8x8; \
194 p[TX_16X16] = vpx_##type##_predictor_16x16; \
195 p[TX_32X32] = vpx_##type##_predictor_32x32
196
Ronald S. Bultje62a15792015-09-30 18:45:08 -0400197#define INIT_ALL_SIZES(p, type) \
198 p[TX_4X4] = vpx_##type##_predictor_4x4; \
199 INIT_NO_4X4(p, type)
200
Jingning Han3ee6db62015-08-05 19:00:31 -0700201 INIT_ALL_SIZES(pred[V_PRED], v);
202 INIT_ALL_SIZES(pred[H_PRED], h);
Debargha Mukherjee104636a2015-12-10 15:00:33 -0800203 INIT_ALL_SIZES(pred[D207_PRED], d207e);
204 INIT_ALL_SIZES(pred[D45_PRED], d45e);
205 INIT_ALL_SIZES(pred[D63_PRED], d63e);
Jingning Han3ee6db62015-08-05 19:00:31 -0700206 INIT_ALL_SIZES(pred[D117_PRED], d117);
207 INIT_ALL_SIZES(pred[D135_PRED], d135);
208 INIT_ALL_SIZES(pred[D153_PRED], d153);
209 INIT_ALL_SIZES(pred[TM_PRED], tm);
210
211 INIT_ALL_SIZES(dc_pred[0][0], dc_128);
212 INIT_ALL_SIZES(dc_pred[0][1], dc_top);
213 INIT_ALL_SIZES(dc_pred[1][0], dc_left);
214 INIT_ALL_SIZES(dc_pred[1][1], dc);
215
216#if CONFIG_VP9_HIGHBITDEPTH
217 INIT_ALL_SIZES(pred_high[V_PRED], highbd_v);
218 INIT_ALL_SIZES(pred_high[H_PRED], highbd_h);
Debargha Mukherjee104636a2015-12-10 15:00:33 -0800219 INIT_ALL_SIZES(pred_high[D207_PRED], highbd_d207e);
220 INIT_ALL_SIZES(pred_high[D45_PRED], highbd_d45e);
221 INIT_ALL_SIZES(pred_high[D63_PRED], highbd_d63e);
Jingning Han3ee6db62015-08-05 19:00:31 -0700222 INIT_ALL_SIZES(pred_high[D117_PRED], highbd_d117);
223 INIT_ALL_SIZES(pred_high[D135_PRED], highbd_d135);
224 INIT_ALL_SIZES(pred_high[D153_PRED], highbd_d153);
225 INIT_ALL_SIZES(pred_high[TM_PRED], highbd_tm);
226
227 INIT_ALL_SIZES(dc_pred_high[0][0], highbd_dc_128);
228 INIT_ALL_SIZES(dc_pred_high[0][1], highbd_dc_top);
229 INIT_ALL_SIZES(dc_pred_high[1][0], highbd_dc_left);
230 INIT_ALL_SIZES(dc_pred_high[1][1], highbd_dc);
231#endif // CONFIG_VP9_HIGHBITDEPTH
232
233#undef intra_pred_allsizes
234}
235
hui sube3559b2015-10-07 09:29:02 -0700236#if CONFIG_EXT_INTRA
237#define PI 3.14159265
238#define FILTER_INTRA_PREC_BITS 10
239#define FILTER_INTRA_ROUND_VAL 511
240
hui sube3559b2015-10-07 09:29:02 -0700241static const uint8_t ext_intra_extend_modes[FILTER_INTRA_MODES] = {
242 NEED_LEFT | NEED_ABOVE, // FILTER_DC
243 NEED_LEFT | NEED_ABOVE, // FILTER_V
244 NEED_LEFT | NEED_ABOVE, // FILTER_H
245 NEED_LEFT | NEED_ABOVE, // FILTER_D45
246 NEED_LEFT | NEED_ABOVE, // FILTER_D135
247 NEED_LEFT | NEED_ABOVE, // FILTER_D117
248 NEED_LEFT | NEED_ABOVE, // FILTER_D153
249 NEED_LEFT | NEED_ABOVE, // FILTER_D207
250 NEED_LEFT | NEED_ABOVE, // FILTER_D63
251 NEED_LEFT | NEED_ABOVE, // FILTER_TM
252};
hui sube3559b2015-10-07 09:29:02 -0700253
hui su3b1c7662016-01-12 16:38:58 -0800254static int intra_subpel_interp(int base, int shift, const uint8_t *ref,
255 int ref_start_idx, int ref_end_idx,
256 INTRA_FILTER filter_type) {
257 int val, k, idx, filter_idx = 0;
258 const int16_t *filter = NULL;
259
260 if (filter_type == INTRA_FILTER_LINEAR) {
261 val = ref[base] * (256 - shift) + ref[base + 1] * shift;
262 val = ROUND_POWER_OF_TWO(val, 8);
263 } else {
264 filter_idx = ROUND_POWER_OF_TWO(shift, 8 - SUBPEL_BITS);
265 filter = vp10_intra_filter_kernels[filter_type][filter_idx];
266
267 if (filter_idx < (1 << SUBPEL_BITS)) {
268 val = 0;
269 for (k = 0; k < SUBPEL_TAPS; ++k) {
270 idx = base + 1 - (SUBPEL_TAPS / 2) + k;
271 idx = VPXMAX(VPXMIN(idx, ref_end_idx), ref_start_idx);
272 val += ref[idx] * filter[k];
273 }
274 val = ROUND_POWER_OF_TWO(val, FILTER_BITS);
275 } else {
276 val = ref[base + 1];
277 }
278 }
279
280 return val;
281}
282
hui sube3559b2015-10-07 09:29:02 -0700283// Directional prediction, zone 1: 0 < angle < 90
284static void dr_prediction_z1(uint8_t *dst, ptrdiff_t stride, int bs,
285 const uint8_t *above, const uint8_t *left,
hui su3b1c7662016-01-12 16:38:58 -0800286 int dx, int dy, INTRA_FILTER filter_type) {
hui suc4b69eb2016-02-04 14:05:22 -0800287 int r, c, x, base, shift, val;
hui sube3559b2015-10-07 09:29:02 -0700288
289 (void)left;
290 (void)dy;
291 assert(dy == 1);
292 assert(dx < 0);
293
hui suc4b69eb2016-02-04 14:05:22 -0800294 if (filter_type != INTRA_FILTER_LINEAR) {
295 const int pad_size = SUBPEL_TAPS >> 1;
296 int len;
297 DECLARE_ALIGNED(16, uint8_t, buf[SUBPEL_SHIFTS][64]);
298 DECLARE_ALIGNED(16, uint8_t, src[64 + SUBPEL_TAPS]);
299 uint8_t flags[SUBPEL_SHIFTS];
300
301 memset(flags, 0, SUBPEL_SHIFTS * sizeof(flags[0]));
302 memset(src, above[0], pad_size * sizeof(above[0]));
303 memcpy(src + pad_size, above, 2 * bs * sizeof(above[0]));
304 memset(src + pad_size + 2 * bs, above[2 * bs - 1],
305 pad_size * sizeof(above[0]));
306 flags[0] = 1;
307 x = -dx;
308 for (r = 0; r < bs; ++r, dst += stride, x -= dx) {
hui sube3559b2015-10-07 09:29:02 -0700309 base = x >> 8;
hui suc4b69eb2016-02-04 14:05:22 -0800310 shift = x & 0xFF;
311 shift = ROUND_POWER_OF_TWO(shift, 8 - SUBPEL_BITS);
312 if (shift == SUBPEL_SHIFTS) {
313 base += 1;
314 shift = 0;
315 }
316 len = VPXMIN(bs, 2 * bs - 1 - base);
317 if (len <= 0) {
318 int i;
319 for (i = r; i < bs; ++i) {
320 memset(dst, above[2 * bs - 1], bs * sizeof(dst[0]));
321 dst += stride;
322 }
323 return;
324 }
325
326 if (len <= (bs >> 1) && !flags[shift]) {
327 base = x >> 8;
328 shift = x & 0xFF;
329 for (c = 0; c < len; ++c) {
330 val = intra_subpel_interp(base, shift, above, 0, 2 * bs - 1,
331 filter_type);
332 dst[c] = clip_pixel(val);
333 ++base;
334 }
335 } else {
336 if (!flags[shift]) {
Debargha Mukherjeebab29122016-02-26 00:18:03 -0800337 const int16_t *filter = vp10_intra_filter_kernels[filter_type][shift];
hui suc4b69eb2016-02-04 14:05:22 -0800338 vpx_convolve8_horiz(src + pad_size, 2 * bs, buf[shift], 2 * bs,
Debargha Mukherjeebab29122016-02-26 00:18:03 -0800339 filter, 16,
hui suc4b69eb2016-02-04 14:05:22 -0800340 NULL, 16, 2 * bs, 2 * bs < 16 ? 2 : 1);
341 flags[shift] = 1;
342 }
343 memcpy(dst, shift == 0 ? src + pad_size + base : &buf[shift][base],
344 len * sizeof(dst[0]));
345 }
346
347 if (len < bs)
348 memset(dst + len, above[2 * bs - 1], (bs - len) * sizeof(dst[0]));
349 }
350 return;
351 }
352
353 // For linear filter, C code is faster.
354 x = -dx;
355 for (r = 0; r < bs; ++r, dst += stride, x -= dx) {
356 base = x >> 8;
357 shift = x & 0xFF;
358
359 if (base >= 2 * bs - 1) {
360 int i;
361 for (i = r; i < bs; ++i) {
362 memset(dst, above[2 * bs - 1], bs * sizeof(dst[0]));
363 dst += stride;
364 }
365 return;
366 }
367
368 for (c = 0; c < bs; ++c, ++base) {
hui sube3559b2015-10-07 09:29:02 -0700369 if (base < 2 * bs - 1) {
hui suc4b69eb2016-02-04 14:05:22 -0800370 val = above[base] * (256 - shift) + above[base + 1] * shift;
371 val = ROUND_POWER_OF_TWO(val, 8);
hui sube3559b2015-10-07 09:29:02 -0700372 dst[c] = clip_pixel(val);
373 } else {
374 dst[c] = above[2 * bs - 1];
375 }
376 }
hui sube3559b2015-10-07 09:29:02 -0700377 }
378}
379
380// Directional prediction, zone 2: 90 < angle < 180
381static void dr_prediction_z2(uint8_t *dst, ptrdiff_t stride, int bs,
382 const uint8_t *above, const uint8_t *left,
hui su3b1c7662016-01-12 16:38:58 -0800383 int dx, int dy, INTRA_FILTER filter_type) {
Debargha Mukherjee3ef0db02016-02-24 10:27:56 -0800384 int r, c, x, y, shift1, shift2, val, base1, base2;
hui sube3559b2015-10-07 09:29:02 -0700385
386 assert(dx > 0);
387 assert(dy > 0);
388
hui suc4b69eb2016-02-04 14:05:22 -0800389 x = -dx;
390 for (r = 0; r < bs; ++r, x -= dx, dst += stride) {
hui suc4b69eb2016-02-04 14:05:22 -0800391 base1 = x >> 8;
392 y = (r << 8) - dy;
393 for (c = 0; c < bs; ++c, ++base1, y -= dy) {
394 if (base1 >= -1) {
395 shift1 = x & 0xFF;
396 val = intra_subpel_interp(base1, shift1, above, -1, bs - 1,
397 filter_type);
hui sube3559b2015-10-07 09:29:02 -0700398 } else {
hui suc4b69eb2016-02-04 14:05:22 -0800399 base2 = y >> 8;
400 if (base2 >= 0) {
401 shift2 = y & 0xFF;
402 val = intra_subpel_interp(base2, shift2, left, 0, bs - 1,
403 filter_type);
hui sube3559b2015-10-07 09:29:02 -0700404 } else {
hui su3b1c7662016-01-12 16:38:58 -0800405 val = left[0];
hui sube3559b2015-10-07 09:29:02 -0700406 }
407 }
hui sube3559b2015-10-07 09:29:02 -0700408 dst[c] = clip_pixel(val);
409 }
hui sube3559b2015-10-07 09:29:02 -0700410 }
411}
412
413// Directional prediction, zone 3: 180 < angle < 270
414static void dr_prediction_z3(uint8_t *dst, ptrdiff_t stride, int bs,
415 const uint8_t *above, const uint8_t *left,
hui su3b1c7662016-01-12 16:38:58 -0800416 int dx, int dy, INTRA_FILTER filter_type) {
hui suc4b69eb2016-02-04 14:05:22 -0800417 int r, c, y, base, shift, val;
hui sube3559b2015-10-07 09:29:02 -0700418
419 (void)above;
420 (void)dx;
hui su3b1c7662016-01-12 16:38:58 -0800421
hui sube3559b2015-10-07 09:29:02 -0700422 assert(dx == 1);
423 assert(dy < 0);
424
hui suc4b69eb2016-02-04 14:05:22 -0800425 if (filter_type != INTRA_FILTER_LINEAR) {
426 const int pad_size = SUBPEL_TAPS >> 1;
427 int len, i;
428 DECLARE_ALIGNED(16, uint8_t, buf[64][4 * SUBPEL_SHIFTS]);
429 DECLARE_ALIGNED(16, uint8_t, src[(64 + SUBPEL_TAPS) * 4]);
430 uint8_t flags[SUBPEL_SHIFTS];
431
432 memset(flags, 0, SUBPEL_SHIFTS * sizeof(flags[0]));
433 for (i = 0; i < pad_size; ++i)
434 src[4 * i] = left[0];
435 for (i = 0; i < 2 * bs; ++i)
436 src[4 * (i + pad_size)] = left[i];
437 for (i = 0; i < pad_size; ++i)
438 src[4 * (i + 2 * bs + pad_size)] = left[2 * bs - 1];
439 flags[0] = 1;
440 y = -dy;
441 for (c = 0; c < bs; ++c, y -= dy) {
hui sube3559b2015-10-07 09:29:02 -0700442 base = y >> 8;
hui suc4b69eb2016-02-04 14:05:22 -0800443 shift = y & 0xFF;
444 shift = ROUND_POWER_OF_TWO(shift, 8 - SUBPEL_BITS);
445 if (shift == SUBPEL_SHIFTS) {
446 base += 1;
447 shift = 0;
448 }
449 len = VPXMIN(bs, 2 * bs - 1 - base);
450
451 if (len <= 0) {
Debargha Mukherjee3ef0db02016-02-24 10:27:56 -0800452 for (r = 0; r < bs; ++r) {
453 dst[r * stride + c] = left[ 2 * bs - 1];
hui suc4b69eb2016-02-04 14:05:22 -0800454 }
455 continue;
456 }
457
458 if (len <= (bs >> 1) && !flags[shift]) {
459 base = y >> 8;
460 shift = y & 0xFF;
461 for (r = 0; r < len; ++r) {
462 val = intra_subpel_interp(base, shift, left, 0, 2 * bs - 1,
463 filter_type);
464 dst[r * stride + c] = clip_pixel(val);
465 ++base;
466 }
hui sube3559b2015-10-07 09:29:02 -0700467 } else {
hui suc4b69eb2016-02-04 14:05:22 -0800468 if (!flags[shift]) {
Debargha Mukherjeebab29122016-02-26 00:18:03 -0800469 const int16_t *filter = vp10_intra_filter_kernels[filter_type][shift];
hui suc4b69eb2016-02-04 14:05:22 -0800470 vpx_convolve8_vert(src + 4 * pad_size, 4,
471 buf[0] + 4 * shift, 4 * SUBPEL_SHIFTS, NULL, 16,
Debargha Mukherjeebab29122016-02-26 00:18:03 -0800472 filter, 16,
hui suc4b69eb2016-02-04 14:05:22 -0800473 2 * bs < 16 ? 4 : 4, 2 * bs);
474 flags[shift] = 1;
475 }
476
477 if (shift == 0) {
478 for (r = 0; r < len; ++r) {
479 dst[r * stride + c] = left[r + base];
480 }
481 } else {
482 for (r = 0; r < len; ++r) {
483 dst[r * stride + c] = buf[r + base][4 * shift];
484 }
485 }
486 }
487
488 if (len < bs) {
489 for (r = len; r < bs; ++r) {
490 dst[r * stride + c] = left[ 2 * bs - 1];
491 }
hui sube3559b2015-10-07 09:29:02 -0700492 }
493 }
hui suc4b69eb2016-02-04 14:05:22 -0800494 return;
495 }
496
497 // For linear filter, C code is faster.
498 y = -dy;
499 for (c = 0; c < bs; ++c, y -= dy) {
500 base = y >> 8;
501 shift = y & 0xFF;
502
503 for (r = 0; r < bs; ++r, ++base) {
504 if (base < 2 * bs - 1) {
505 val = left[base] * (256 - shift) + left[base + 1] * shift;
506 val = ROUND_POWER_OF_TWO(val, 8);
507 dst[r * stride + c] = clip_pixel(val);
508 } else {
509 for (; r < bs; ++r)
510 dst[r * stride + c] = left[2 * bs - 1];
511 break;
512 }
513 }
hui sube3559b2015-10-07 09:29:02 -0700514 }
515}
516
hui su4aa50c12015-11-10 12:09:59 -0800517static void dr_predictor(uint8_t *dst, ptrdiff_t stride, TX_SIZE tx_size,
hui su3b1c7662016-01-12 16:38:58 -0800518 const uint8_t *above, const uint8_t *left, int angle,
519 INTRA_FILTER filter_type) {
hui sube3559b2015-10-07 09:29:02 -0700520 double t = 0;
521 int dx, dy;
hui su4aa50c12015-11-10 12:09:59 -0800522 int bs = 4 << tx_size;
hui sube3559b2015-10-07 09:29:02 -0700523
524 if (angle != 90 && angle != 180)
525 t = tan(angle * PI / 180.0);
526 if (angle > 0 && angle < 90) {
527 dx = -((int)(256 / t));
528 dy = 1;
hui su3b1c7662016-01-12 16:38:58 -0800529 dr_prediction_z1(dst, stride, bs, above, left, dx, dy, filter_type);
hui sube3559b2015-10-07 09:29:02 -0700530 } else if (angle > 90 && angle < 180) {
531 t = -t;
532 dx = (int)(256 / t);
533 dy = (int)(256 * t);
hui su3b1c7662016-01-12 16:38:58 -0800534 dr_prediction_z2(dst, stride, bs, above, left, dx, dy, filter_type);
hui sube3559b2015-10-07 09:29:02 -0700535 } else if (angle > 180 && angle < 270) {
536 dx = 1;
537 dy = -((int)(256 * t));
hui su3b1c7662016-01-12 16:38:58 -0800538 dr_prediction_z3(dst, stride, bs, above, left, dx, dy, filter_type);
hui sube3559b2015-10-07 09:29:02 -0700539 } else if (angle == 90) {
hui su4aa50c12015-11-10 12:09:59 -0800540 pred[V_PRED][tx_size](dst, stride, above, left);
hui sube3559b2015-10-07 09:29:02 -0700541 } else if (angle == 180) {
hui su4aa50c12015-11-10 12:09:59 -0800542 pred[H_PRED][tx_size](dst, stride, above, left);
hui sube3559b2015-10-07 09:29:02 -0700543 }
544}
545
546static int filter_intra_taps_4[TX_SIZES][INTRA_MODES][4] = {
547 {
548 {735, 881, -537, -54},
549 {1005, 519, -488, -11},
550 {383, 990, -343, -6},
551 {442, 805, -542, 319},
552 {658, 616, -133, -116},
553 {875, 442, -141, -151},
554 {386, 741, -23, -80},
555 {390, 1027, -446, 51},
556 {679, 606, -523, 262},
557 {903, 922, -778, -23},
558 },
559 {
560 {648, 803, -444, 16},
561 {972, 620, -576, 7},
562 {561, 967, -499, -5},
563 {585, 762, -468, 144},
564 {596, 619, -182, -9},
565 {895, 459, -176, -153},
566 {557, 722, -126, -129},
567 {601, 839, -523, 105},
568 {562, 709, -499, 251},
569 {803, 872, -695, 43},
570 },
571 {
572 {423, 728, -347, 111},
573 {963, 685, -665, 23},
574 {281, 1024, -480, 216},
575 {640, 596, -437, 78},
576 {429, 669, -259, 99},
577 {740, 646, -415, 23},
578 {568, 771, -346, 40},
579 {404, 833, -486, 209},
580 {398, 712, -423, 307},
581 {939, 935, -887, 17},
582 },
583 {
584 {477, 737, -393, 150},
585 {881, 630, -546, 67},
586 {506, 984, -443, -20},
587 {114, 459, -270, 528},
588 {433, 528, 14, 3},
589 {837, 470, -301, -30},
590 {181, 777, 89, -107},
591 {-29, 716, -232, 259},
592 {589, 646, -495, 255},
593 {740, 884, -728, 77},
594 },
595};
596
597static void filter_intra_predictors_4tap(uint8_t *dst, ptrdiff_t stride, int bs,
598 const uint8_t *above,
599 const uint8_t *left,
600 int mode) {
601 int k, r, c;
602 int pred[33][65];
603 int mean, ipred;
604 const TX_SIZE tx_size = (bs == 32) ? TX_32X32 :
605 ((bs == 16) ? TX_16X16 : ((bs == 8) ? TX_8X8 : (TX_4X4)));
606 const int c0 = filter_intra_taps_4[tx_size][mode][0];
607 const int c1 = filter_intra_taps_4[tx_size][mode][1];
608 const int c2 = filter_intra_taps_4[tx_size][mode][2];
609 const int c3 = filter_intra_taps_4[tx_size][mode][3];
610
611 k = 0;
612 mean = 0;
613 while (k < bs) {
614 mean = mean + (int)left[k];
615 mean = mean + (int)above[k];
616 k++;
617 }
618 mean = (mean + bs) / (2 * bs);
619
620 for (r = 0; r < bs; ++r)
621 pred[r + 1][0] = (int)left[r] - mean;
622
623 for (c = 0; c < 2 * bs + 1; ++c)
624 pred[0][c] = (int)above[c - 1] - mean;
625
626 for (r = 1; r < bs + 1; ++r)
627 for (c = 1; c < 2 * bs + 1 - r; ++c) {
628 ipred = c0 * pred[r - 1][c] + c1 * pred[r][c - 1] +
629 c2 * pred[r - 1][c - 1] + c3 * pred[r - 1][c + 1];
630 pred[r][c] = ipred < 0 ?
631 -((-ipred + FILTER_INTRA_ROUND_VAL) >> FILTER_INTRA_PREC_BITS) :
632 ((ipred + FILTER_INTRA_ROUND_VAL) >> FILTER_INTRA_PREC_BITS);
633 }
634
635 for (r = 0; r < bs; ++r) {
636 for (c = 0; c < bs; ++c) {
637 ipred = pred[r + 1][c + 1] + mean;
638 dst[c] = clip_pixel(ipred);
639 }
640 dst += stride;
641 }
642}
643
644static void dc_filter_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
645 const uint8_t *above, const uint8_t *left) {
646 filter_intra_predictors_4tap(dst, stride, bs, above, left, DC_PRED);
647}
648
649static void v_filter_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
650 const uint8_t *above, const uint8_t *left) {
651 filter_intra_predictors_4tap(dst, stride, bs, above, left, V_PRED);
652}
653
654static void h_filter_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
655 const uint8_t *above, const uint8_t *left) {
656 filter_intra_predictors_4tap(dst, stride, bs, above, left, H_PRED);
657}
658
659static void d45_filter_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
660 const uint8_t *above, const uint8_t *left) {
661 filter_intra_predictors_4tap(dst, stride, bs, above, left, D45_PRED);
662}
663
664static void d135_filter_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
665 const uint8_t *above, const uint8_t *left) {
666 filter_intra_predictors_4tap(dst, stride, bs, above, left, D135_PRED);
667}
668
669static void d117_filter_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
670 const uint8_t *above, const uint8_t *left) {
671 filter_intra_predictors_4tap(dst, stride, bs, above, left, D117_PRED);
672}
673
674static void d153_filter_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
675 const uint8_t *above, const uint8_t *left) {
676 filter_intra_predictors_4tap(dst, stride, bs, above, left, D153_PRED);
677}
678
679static void d207_filter_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
680 const uint8_t *above, const uint8_t *left) {
681 filter_intra_predictors_4tap(dst, stride, bs, above, left, D207_PRED);
682}
683
684static void d63_filter_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
685 const uint8_t *above, const uint8_t *left) {
686 filter_intra_predictors_4tap(dst, stride, bs, above, left, D63_PRED);
687}
688
689static void tm_filter_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
690 const uint8_t *above, const uint8_t *left) {
691 filter_intra_predictors_4tap(dst, stride, bs, above, left, TM_PRED);
692}
693
694static void (*filter_intra_predictors[EXT_INTRA_MODES])(uint8_t *dst,
695 ptrdiff_t stride, int bs, const uint8_t *above, const uint8_t *left) = {
696 dc_filter_predictor, v_filter_predictor, h_filter_predictor,
697 d45_filter_predictor, d135_filter_predictor, d117_filter_predictor,
698 d153_filter_predictor, d207_filter_predictor, d63_filter_predictor,
699 tm_filter_predictor,
700};
701
702#if CONFIG_VP9_HIGHBITDEPTH
hui su3b1c7662016-01-12 16:38:58 -0800703static int highbd_intra_subpel_interp(int base, int shift, const uint16_t *ref,
704 int ref_start_idx, int ref_end_idx,
705 INTRA_FILTER filter_type) {
706 int val, k, idx, filter_idx = 0;
707 const int16_t *filter = NULL;
708
709 if (filter_type == INTRA_FILTER_LINEAR) {
710 val = ref[base] * (256 - shift) + ref[base + 1] * shift;
711 val = ROUND_POWER_OF_TWO(val, 8);
712 } else {
713 filter_idx = ROUND_POWER_OF_TWO(shift, 8 - SUBPEL_BITS);
714 filter = vp10_intra_filter_kernels[filter_type][filter_idx];
715
716 if (filter_idx < (1 << SUBPEL_BITS)) {
717 val = 0;
718 for (k = 0; k < SUBPEL_TAPS; ++k) {
719 idx = base + 1 - (SUBPEL_TAPS / 2) + k;
720 idx = VPXMAX(VPXMIN(idx, ref_end_idx), ref_start_idx);
721 val += ref[idx] * filter[k];
722 }
723 val = ROUND_POWER_OF_TWO(val, FILTER_BITS);
724 } else {
725 val = ref[base + 1];
726 }
727 }
728
729 return val;
730}
731
hui sube3559b2015-10-07 09:29:02 -0700732// Directional prediction, zone 1: 0 < angle < 90
733static void highbd_dr_prediction_z1(uint16_t *dst, ptrdiff_t stride, int bs,
734 const uint16_t *above, const uint16_t *left,
hui su3b1c7662016-01-12 16:38:58 -0800735 int dx, int dy, int bd,
736 INTRA_FILTER filter_type) {
hui sube3559b2015-10-07 09:29:02 -0700737 int r, c, x, y, base, shift, val;
738
739 (void)left;
740 (void)dy;
741 assert(dy == 1);
742 assert(dx < 0);
743
744 for (r = 0; r < bs; ++r) {
745 y = r + 1;
746 for (c = 0; c < bs; ++c) {
hui su3b1c7662016-01-12 16:38:58 -0800747 x = (c << 8) - y * dx;
hui sube3559b2015-10-07 09:29:02 -0700748 base = x >> 8;
hui su3b1c7662016-01-12 16:38:58 -0800749 shift = x - (base << 8);
hui sube3559b2015-10-07 09:29:02 -0700750 if (base < 2 * bs - 1) {
hui su3b1c7662016-01-12 16:38:58 -0800751 val = highbd_intra_subpel_interp(base, shift, above, 0, 2 * bs - 1,
752 filter_type);
hui sube3559b2015-10-07 09:29:02 -0700753 dst[c] = clip_pixel_highbd(val, bd);
754 } else {
755 dst[c] = above[2 * bs - 1];
756 }
757 }
758 dst += stride;
759 }
760}
761
762// Directional prediction, zone 2: 90 < angle < 180
763static void highbd_dr_prediction_z2(uint16_t *dst, ptrdiff_t stride, int bs,
764 const uint16_t *above, const uint16_t *left,
hui su3b1c7662016-01-12 16:38:58 -0800765 int dx, int dy, int bd,
766 INTRA_FILTER filter_type) {
767 int r, c, x, y, shift, val, base;
hui sube3559b2015-10-07 09:29:02 -0700768
769 assert(dx > 0);
770 assert(dy > 0);
771
772 for (r = 0; r < bs; ++r) {
773 for (c = 0; c < bs; ++c) {
774 y = r + 1;
hui su3b1c7662016-01-12 16:38:58 -0800775 x = (c << 8) - y * dx;
776 base = x >> 8;
777 if (base >= -1) {
778 shift = x - (base << 8);
779 val = highbd_intra_subpel_interp(base, shift, above, -1, bs - 1,
780 filter_type);
hui sube3559b2015-10-07 09:29:02 -0700781 } else {
782 x = c + 1;
hui su3b1c7662016-01-12 16:38:58 -0800783 y = (r << 8) - x * dy;
hui sube3559b2015-10-07 09:29:02 -0700784 base = y >> 8;
785 if (base >= 0) {
hui su3b1c7662016-01-12 16:38:58 -0800786 shift = y - (base << 8);
787 val = highbd_intra_subpel_interp(base, shift, left, 0, bs - 1,
788 filter_type);
hui sube3559b2015-10-07 09:29:02 -0700789 } else {
hui su3b1c7662016-01-12 16:38:58 -0800790 val = left[0];
hui sube3559b2015-10-07 09:29:02 -0700791 }
792 }
hui sube3559b2015-10-07 09:29:02 -0700793 dst[c] = clip_pixel_highbd(val, bd);
794 }
795 dst += stride;
796 }
797}
798
799// Directional prediction, zone 3: 180 < angle < 270
800static void highbd_dr_prediction_z3(uint16_t *dst, ptrdiff_t stride, int bs,
801 const uint16_t *above, const uint16_t *left,
hui su3b1c7662016-01-12 16:38:58 -0800802 int dx, int dy, int bd,
803 INTRA_FILTER filter_type) {
hui sube3559b2015-10-07 09:29:02 -0700804 int r, c, x, y, base, shift, val;
805
806 (void)above;
807 (void)dx;
808 assert(dx == 1);
809 assert(dy < 0);
810
811 for (r = 0; r < bs; ++r) {
812 for (c = 0; c < bs; ++c) {
813 x = c + 1;
hui su3b1c7662016-01-12 16:38:58 -0800814 y = (r << 8) - x * dy;
hui sube3559b2015-10-07 09:29:02 -0700815 base = y >> 8;
hui su3b1c7662016-01-12 16:38:58 -0800816 shift = y - (base << 8);
hui su0681f6f2015-12-10 11:50:13 -0800817 if (base < 2 * bs - 1) {
hui su3b1c7662016-01-12 16:38:58 -0800818 val = highbd_intra_subpel_interp(base, shift, left, 0, 2 * bs - 1,
819 filter_type);
hui sube3559b2015-10-07 09:29:02 -0700820 dst[c] = clip_pixel_highbd(val, bd);
821 } else {
hui su3b1c7662016-01-12 16:38:58 -0800822 dst[c] = left[2 * bs - 1];
hui sube3559b2015-10-07 09:29:02 -0700823 }
824 }
825 dst += stride;
826 }
827}
828
829static INLINE void highbd_v_predictor(uint16_t *dst, ptrdiff_t stride,
830 int bs, const uint16_t *above,
831 const uint16_t *left, int bd) {
832 int r;
833 (void) left;
834 (void) bd;
835 for (r = 0; r < bs; r++) {
836 memcpy(dst, above, bs * sizeof(uint16_t));
837 dst += stride;
838 }
839}
840
841static INLINE void highbd_h_predictor(uint16_t *dst, ptrdiff_t stride,
842 int bs, const uint16_t *above,
843 const uint16_t *left, int bd) {
844 int r;
845 (void) above;
846 (void) bd;
847 for (r = 0; r < bs; r++) {
848 vpx_memset16(dst, left[r], bs);
849 dst += stride;
850 }
851}
852
853static void highbd_dr_predictor(uint16_t *dst, ptrdiff_t stride, int bs,
854 const uint16_t *above, const uint16_t *left,
hui su3b1c7662016-01-12 16:38:58 -0800855 int angle, int bd, INTRA_FILTER filter) {
hui sube3559b2015-10-07 09:29:02 -0700856 double t = 0;
857 int dx, dy;
858
859 if (angle != 90 && angle != 180)
860 t = tan(angle * PI / 180.0);
861 if (angle > 0 && angle < 90) {
862 dx = -((int)(256 / t));
863 dy = 1;
hui su3b1c7662016-01-12 16:38:58 -0800864 highbd_dr_prediction_z1(dst, stride, bs, above, left, dx, dy, bd, filter);
hui sube3559b2015-10-07 09:29:02 -0700865 } else if (angle > 90 && angle < 180) {
866 t = -t;
867 dx = (int)(256 / t);
868 dy = (int)(256 * t);
hui su3b1c7662016-01-12 16:38:58 -0800869 highbd_dr_prediction_z2(dst, stride, bs, above, left, dx, dy, bd, filter);
hui sube3559b2015-10-07 09:29:02 -0700870 } else if (angle > 180 && angle < 270) {
871 dx = 1;
872 dy = -((int)(256 * t));
hui su3b1c7662016-01-12 16:38:58 -0800873 highbd_dr_prediction_z3(dst, stride, bs, above, left, dx, dy, bd, filter);
hui sube3559b2015-10-07 09:29:02 -0700874 } else if (angle == 90) {
875 highbd_v_predictor(dst, stride, bs, above, left, bd);
876 } else if (angle == 180) {
877 highbd_h_predictor(dst, stride, bs, above, left, bd);
878 }
879}
880
881static void highbd_filter_intra_predictors_4tap(uint16_t *dst, ptrdiff_t stride,
882 int bs, const uint16_t *above,
883 const uint16_t *left, int mode,
884 int bd) {
885 int k, r, c;
886 int pred[33][65];
887 int mean, ipred;
888 const TX_SIZE tx_size = (bs == 32) ? TX_32X32 :
889 ((bs == 16) ? TX_16X16 : ((bs == 8) ? TX_8X8 : (TX_4X4)));
890 const int c0 = filter_intra_taps_4[tx_size][mode][0];
891 const int c1 = filter_intra_taps_4[tx_size][mode][1];
892 const int c2 = filter_intra_taps_4[tx_size][mode][2];
893 const int c3 = filter_intra_taps_4[tx_size][mode][3];
894
895 k = 0;
896 mean = 0;
897 while (k < bs) {
898 mean = mean + (int)left[k];
899 mean = mean + (int)above[k];
900 k++;
901 }
902 mean = (mean + bs) / (2 * bs);
903
904 for (r = 0; r < bs; ++r)
905 pred[r + 1][0] = (int)left[r] - mean;
906
907 for (c = 0; c < 2 * bs + 1; ++c)
908 pred[0][c] = (int)above[c - 1] - mean;
909
910 for (r = 1; r < bs + 1; ++r)
911 for (c = 1; c < 2 * bs + 1 - r; ++c) {
912 ipred = c0 * pred[r - 1][c] + c1 * pred[r][c - 1] +
913 c2 * pred[r - 1][c - 1] + c3 * pred[r - 1][c + 1];
914 pred[r][c] = ipred < 0 ?
915 -((-ipred + FILTER_INTRA_ROUND_VAL) >> FILTER_INTRA_PREC_BITS) :
916 ((ipred + FILTER_INTRA_ROUND_VAL) >> FILTER_INTRA_PREC_BITS);
917 }
918
919 for (r = 0; r < bs; ++r) {
920 for (c = 0; c < bs; ++c) {
921 ipred = pred[r + 1][c + 1] + mean;
922 dst[c] = clip_pixel_highbd(ipred, bd);
923 }
924 dst += stride;
925 }
926}
927
928static void highbd_dc_filter_predictor(uint16_t *dst, ptrdiff_t stride,
929 int bs, const uint16_t *above,
930 const uint16_t *left, int bd) {
931 highbd_filter_intra_predictors_4tap(dst, stride, bs, above, left, DC_PRED,
932 bd);
933}
934
935static void highbd_v_filter_predictor(uint16_t *dst, ptrdiff_t stride,
936 int bs, const uint16_t *above,
937 const uint16_t *left, int bd) {
938 highbd_filter_intra_predictors_4tap(dst, stride, bs, above, left, V_PRED,
939 bd);
940}
941
942static void highbd_h_filter_predictor(uint16_t *dst, ptrdiff_t stride,
943 int bs, const uint16_t *above,
944 const uint16_t *left, int bd) {
945 highbd_filter_intra_predictors_4tap(dst, stride, bs, above, left, H_PRED,
946 bd);
947}
948
949static void highbd_d45_filter_predictor(uint16_t *dst, ptrdiff_t stride,
950 int bs, const uint16_t *above,
951 const uint16_t *left, int bd) {
952 highbd_filter_intra_predictors_4tap(dst, stride, bs, above, left, D45_PRED,
953 bd);
954}
955
956static void highbd_d135_filter_predictor(uint16_t *dst, ptrdiff_t stride,
957 int bs, const uint16_t *above,
958 const uint16_t *left, int bd) {
959 highbd_filter_intra_predictors_4tap(dst, stride, bs, above, left, D135_PRED,
960 bd);
961}
962
963static void highbd_d117_filter_predictor(uint16_t *dst, ptrdiff_t stride,
964 int bs, const uint16_t *above,
965 const uint16_t *left, int bd) {
966 highbd_filter_intra_predictors_4tap(dst, stride, bs, above, left, D117_PRED,
967 bd);
968}
969
970static void highbd_d153_filter_predictor(uint16_t *dst, ptrdiff_t stride,
971 int bs, const uint16_t *above,
972 const uint16_t *left, int bd) {
973 highbd_filter_intra_predictors_4tap(dst, stride, bs, above, left, D153_PRED,
974 bd);
975}
976
977static void highbd_d207_filter_predictor(uint16_t *dst, ptrdiff_t stride,
978 int bs, const uint16_t *above,
979 const uint16_t *left, int bd) {
980 highbd_filter_intra_predictors_4tap(dst, stride, bs, above, left, D207_PRED,
981 bd);
982}
983
984static void highbd_d63_filter_predictor(uint16_t *dst, ptrdiff_t stride,
985 int bs, const uint16_t *above,
986 const uint16_t *left, int bd) {
987 highbd_filter_intra_predictors_4tap(dst, stride, bs, above, left, D63_PRED,
988 bd);
989}
990
991static void highbd_tm_filter_predictor(uint16_t *dst, ptrdiff_t stride,
992 int bs, const uint16_t *above,
993 const uint16_t *left, int bd) {
994 highbd_filter_intra_predictors_4tap(dst, stride, bs, above, left, TM_PRED,
995 bd);
996}
997
998static void (*highbd_filter_intra_predictors[EXT_INTRA_MODES])(uint16_t *dst,
999 ptrdiff_t stride, int bs, const uint16_t *above, const uint16_t *left,
1000 int bd) = {
1001 highbd_dc_filter_predictor, highbd_v_filter_predictor,
1002 highbd_h_filter_predictor, highbd_d45_filter_predictor,
1003 highbd_d135_filter_predictor, highbd_d117_filter_predictor,
1004 highbd_d153_filter_predictor, highbd_d207_filter_predictor,
1005 highbd_d63_filter_predictor, highbd_tm_filter_predictor,
1006};
1007#endif // CONFIG_VP9_HIGHBITDEPTH
1008#endif // CONFIG_EXT_INTRA
1009
Jingning Han3ee6db62015-08-05 19:00:31 -07001010#if CONFIG_VP9_HIGHBITDEPTH
1011static void build_intra_predictors_high(const MACROBLOCKD *xd,
1012 const uint8_t *ref8,
1013 int ref_stride,
1014 uint8_t *dst8,
1015 int dst_stride,
1016 PREDICTION_MODE mode,
1017 TX_SIZE tx_size,
Ronald S. Bultjec7dc1d72015-10-12 10:35:46 -04001018 int n_top_px, int n_topright_px,
1019 int n_left_px, int n_bottomleft_px,
hui su66f2f652015-11-16 16:58:15 -08001020 int plane) {
Jingning Han3ee6db62015-08-05 19:00:31 -07001021 int i;
1022 uint16_t *dst = CONVERT_TO_SHORTPTR(dst8);
1023 uint16_t *ref = CONVERT_TO_SHORTPTR(ref8);
Ronald S. Bultjec7dc1d72015-10-12 10:35:46 -04001024 DECLARE_ALIGNED(16, uint16_t, left_col[64]);
Jingning Han3ee6db62015-08-05 19:00:31 -07001025 DECLARE_ALIGNED(16, uint16_t, above_data[64 + 16]);
1026 uint16_t *above_row = above_data + 16;
1027 const uint16_t *const_above_row = above_row;
1028 const int bs = 4 << tx_size;
hui sube3559b2015-10-07 09:29:02 -07001029 int need_left = extend_modes[mode] & NEED_LEFT;
1030 int need_above = extend_modes[mode] & NEED_ABOVE;
Ronald S. Bultjec7dc1d72015-10-12 10:35:46 -04001031 const uint16_t *above_ref = ref - ref_stride;
hui su66f2f652015-11-16 16:58:15 -08001032 int base = 128 << (xd->bd - 8);
Jingning Han3ee6db62015-08-05 19:00:31 -07001033 // 127 127 127 .. 127 127 127 127 127 127
1034 // 129 A B .. Y Z
1035 // 129 C D .. W X
1036 // 129 E F .. U V
1037 // 129 G H .. S T T T T T
1038
hui sube3559b2015-10-07 09:29:02 -07001039#if CONFIG_EXT_INTRA
1040 const EXT_INTRA_MODE_INFO *ext_intra_mode_info =
1041 &xd->mi[0]->mbmi.ext_intra_mode_info;
1042 const EXT_INTRA_MODE ext_intra_mode =
1043 ext_intra_mode_info->ext_intra_mode[plane != 0];
hui su4aa50c12015-11-10 12:09:59 -08001044 int p_angle = 0;
1045
1046 if (mode != DC_PRED && mode != TM_PRED &&
1047 xd->mi[0]->mbmi.sb_type >= BLOCK_8X8) {
1048 p_angle = mode_to_angle_map[mode] +
1049 xd->mi[0]->mbmi.angle_delta[plane != 0] * ANGLE_STEP;
hui su4aa50c12015-11-10 12:09:59 -08001050 if (p_angle <= 90)
1051 need_above = 1, need_left = 0;
1052 else if (p_angle < 180)
1053 need_above = 1, need_left = 1;
1054 else
1055 need_above = 0, need_left = 1;
hui su4aa50c12015-11-10 12:09:59 -08001056 }
hui sube3559b2015-10-07 09:29:02 -07001057
1058 if (ext_intra_mode_info->use_ext_intra_mode[plane != 0]) {
1059 EXT_INTRA_MODE ext_intra_mode =
1060 ext_intra_mode_info->ext_intra_mode[plane != 0];
hui su4aa50c12015-11-10 12:09:59 -08001061 need_left = ext_intra_extend_modes[ext_intra_mode] & NEED_LEFT;
1062 need_above = ext_intra_extend_modes[ext_intra_mode] & NEED_ABOVE;
hui sube3559b2015-10-07 09:29:02 -07001063 }
1064#endif // CONFIG_EXT_INTRA
1065
Ronald S. Bultjec7dc1d72015-10-12 10:35:46 -04001066 (void) plane;
1067
1068 // NEED_LEFT
hui sube3559b2015-10-07 09:29:02 -07001069 if (need_left) {
1070#if CONFIG_EXT_INTRA
1071 int need_bottom;
1072 if (ext_intra_mode_info->use_ext_intra_mode[plane != 0]) {
hui sube3559b2015-10-07 09:29:02 -07001073 need_bottom = 0;
hui su4aa50c12015-11-10 12:09:59 -08001074 } else if (mode != DC_PRED && mode != TM_PRED &&
1075 xd->mi[0]->mbmi.sb_type >= BLOCK_8X8) {
1076 need_bottom = p_angle > 180;
hui sube3559b2015-10-07 09:29:02 -07001077 } else {
1078 need_bottom = !!(extend_modes[mode] & NEED_BOTTOMLEFT);
1079 }
1080#else
Ronald S. Bultjec7dc1d72015-10-12 10:35:46 -04001081 const int need_bottom = !!(extend_modes[mode] & NEED_BOTTOMLEFT);
hui sube3559b2015-10-07 09:29:02 -07001082#endif // CONFIG_EXT_INTRA
Ronald S. Bultjec7dc1d72015-10-12 10:35:46 -04001083 i = 0;
1084 if (n_left_px > 0) {
1085 for (; i < n_left_px; i++)
1086 left_col[i] = ref[i * ref_stride - 1];
1087 if (need_bottom && n_bottomleft_px > 0) {
1088 assert(i == bs);
1089 for (; i < bs + n_bottomleft_px; i++)
1090 left_col[i] = ref[i * ref_stride - 1];
1091 }
1092 if (i < (bs << need_bottom))
Yaowu Xu4d90ae42016-02-05 09:35:34 -08001093 vpx_memset16(&left_col[i], left_col[i - 1], (bs << need_bottom) - i);
Ronald S. Bultjec7dc1d72015-10-12 10:35:46 -04001094 } else {
Yaowu Xu4d90ae42016-02-05 09:35:34 -08001095 vpx_memset16(left_col, base + 1, bs << need_bottom);
Ronald S. Bultjec7dc1d72015-10-12 10:35:46 -04001096 }
1097 }
1098
1099 // NEED_ABOVE
hui sube3559b2015-10-07 09:29:02 -07001100 if (need_above) {
1101#if CONFIG_EXT_INTRA
1102 int need_right;
1103 if (ext_intra_mode_info->use_ext_intra_mode[plane != 0]) {
hui su4aa50c12015-11-10 12:09:59 -08001104 need_right = 1;
1105 } else if (mode != DC_PRED && mode != TM_PRED &&
1106 xd->mi[0]->mbmi.sb_type >= BLOCK_8X8) {
1107 need_right = p_angle < 90;
hui sube3559b2015-10-07 09:29:02 -07001108 } else {
1109 need_right = !!(extend_modes[mode] & NEED_ABOVERIGHT);
1110 }
1111#else
Ronald S. Bultjec7dc1d72015-10-12 10:35:46 -04001112 const int need_right = !!(extend_modes[mode] & NEED_ABOVERIGHT);
hui sube3559b2015-10-07 09:29:02 -07001113#endif // CONFIG_EXT_INTRA
Ronald S. Bultjec7dc1d72015-10-12 10:35:46 -04001114 if (n_top_px > 0) {
1115 memcpy(above_row, above_ref, n_top_px * 2);
1116 i = n_top_px;
1117 if (need_right && n_topright_px > 0) {
1118 assert(n_top_px == bs);
1119 memcpy(above_row + bs, above_ref + bs, n_topright_px * 2);
1120 i += n_topright_px;
1121 }
1122 if (i < (bs << need_right))
Yaowu Xu4d90ae42016-02-05 09:35:34 -08001123 vpx_memset16(&above_row[i], above_row[i - 1], (bs << need_right) - i);
Ronald S. Bultjec7dc1d72015-10-12 10:35:46 -04001124 } else {
Yaowu Xu4d90ae42016-02-05 09:35:34 -08001125 vpx_memset16(above_row, base - 1, bs << need_right);
Ronald S. Bultjec7dc1d72015-10-12 10:35:46 -04001126 }
1127 }
1128
hui sube3559b2015-10-07 09:29:02 -07001129#if CONFIG_EXT_INTRA
1130 if (ext_intra_mode_info->use_ext_intra_mode[plane != 0] ||
hui su4aa50c12015-11-10 12:09:59 -08001131 (extend_modes[mode] & NEED_ABOVELEFT) ||
1132 (mode != DC_PRED && mode != TM_PRED &&
1133 xd->mi[0]->mbmi.sb_type >= BLOCK_8X8)) {
Ronald S. Bultjec7dc1d72015-10-12 10:35:46 -04001134 above_row[-1] = n_top_px > 0 ?
1135 (n_left_px > 0 ? above_ref[-1] : base + 1) : base - 1;
1136 }
1137#else
hui sube3559b2015-10-07 09:29:02 -07001138 if ((extend_modes[mode] & NEED_ABOVELEFT)) {
1139 above_row[-1] = n_top_px > 0 ?
1140 (n_left_px > 0 ? above_ref[-1] : base + 1) : base - 1;
1141 }
1142#endif // CONFIG_EXT_INTRA
Jingning Han3ee6db62015-08-05 19:00:31 -07001143
hui sube3559b2015-10-07 09:29:02 -07001144#if CONFIG_EXT_INTRA
1145 if (ext_intra_mode_info->use_ext_intra_mode[plane != 0]) {
hui su4aa50c12015-11-10 12:09:59 -08001146 highbd_filter_intra_predictors[ext_intra_mode](dst, dst_stride, bs,
hui su66f2f652015-11-16 16:58:15 -08001147 const_above_row, left_col, xd->bd);
hui su4aa50c12015-11-10 12:09:59 -08001148 return;
1149 }
1150
1151 if (mode != DC_PRED && mode != TM_PRED &&
1152 xd->mi[0]->mbmi.sb_type >= BLOCK_8X8) {
hui su3b1c7662016-01-12 16:38:58 -08001153 INTRA_FILTER filter = INTRA_FILTER_LINEAR;
1154 if (plane == 0 && pick_intra_filter(p_angle))
1155 filter = xd->mi[0]->mbmi.intra_filter;
hui su4aa50c12015-11-10 12:09:59 -08001156 highbd_dr_predictor(dst, dst_stride, bs, const_above_row, left_col,
hui su3b1c7662016-01-12 16:38:58 -08001157 p_angle, xd->bd, filter);
hui sube3559b2015-10-07 09:29:02 -07001158 return;
1159 }
1160#endif // CONFIG_EXT_INTRA
1161
Jingning Han3ee6db62015-08-05 19:00:31 -07001162 // predict
1163 if (mode == DC_PRED) {
Ronald S. Bultjec7dc1d72015-10-12 10:35:46 -04001164 dc_pred_high[n_left_px > 0][n_top_px > 0][tx_size](dst, dst_stride,
1165 const_above_row,
1166 left_col, xd->bd);
Jingning Han3ee6db62015-08-05 19:00:31 -07001167 } else {
1168 pred_high[mode][tx_size](dst, dst_stride, const_above_row, left_col,
1169 xd->bd);
1170 }
1171}
1172#endif // CONFIG_VP9_HIGHBITDEPTH
1173
1174static void build_intra_predictors(const MACROBLOCKD *xd, const uint8_t *ref,
1175 int ref_stride, uint8_t *dst, int dst_stride,
1176 PREDICTION_MODE mode, TX_SIZE tx_size,
Ronald S. Bultjec7dc1d72015-10-12 10:35:46 -04001177 int n_top_px, int n_topright_px,
1178 int n_left_px, int n_bottomleft_px,
hui su66f2f652015-11-16 16:58:15 -08001179 int plane) {
Jingning Han3ee6db62015-08-05 19:00:31 -07001180 int i;
Ronald S. Bultjec7dc1d72015-10-12 10:35:46 -04001181 DECLARE_ALIGNED(16, uint8_t, left_col[64]);
1182 const uint8_t *above_ref = ref - ref_stride;
Jingning Han3ee6db62015-08-05 19:00:31 -07001183 DECLARE_ALIGNED(16, uint8_t, above_data[64 + 16]);
1184 uint8_t *above_row = above_data + 16;
1185 const uint8_t *const_above_row = above_row;
1186 const int bs = 4 << tx_size;
hui sube3559b2015-10-07 09:29:02 -07001187 int need_left = extend_modes[mode] & NEED_LEFT;
1188 int need_above = extend_modes[mode] & NEED_ABOVE;
hui sube3559b2015-10-07 09:29:02 -07001189#if CONFIG_EXT_INTRA
1190 const EXT_INTRA_MODE_INFO *ext_intra_mode_info =
1191 &xd->mi[0]->mbmi.ext_intra_mode_info;
1192 const EXT_INTRA_MODE ext_intra_mode =
1193 ext_intra_mode_info->ext_intra_mode[plane != 0];
hui su4aa50c12015-11-10 12:09:59 -08001194 int p_angle = 0;
1195
1196 if (mode != DC_PRED && mode != TM_PRED &&
1197 xd->mi[0]->mbmi.sb_type >= BLOCK_8X8) {
1198 p_angle = mode_to_angle_map[mode] +
1199 xd->mi[0]->mbmi.angle_delta[plane != 0] * ANGLE_STEP;
hui su4aa50c12015-11-10 12:09:59 -08001200 if (p_angle <= 90)
1201 need_above = 1, need_left = 0;
1202 else if (p_angle < 180)
1203 need_above = 1, need_left = 1;
1204 else
1205 need_above = 0, need_left = 1;
hui su4aa50c12015-11-10 12:09:59 -08001206 }
hui sube3559b2015-10-07 09:29:02 -07001207
1208 if (ext_intra_mode_info->use_ext_intra_mode[plane != 0]) {
1209 EXT_INTRA_MODE ext_intra_mode =
1210 ext_intra_mode_info->ext_intra_mode[plane != 0];
hui su4aa50c12015-11-10 12:09:59 -08001211 need_left = ext_intra_extend_modes[ext_intra_mode] & NEED_LEFT;
1212 need_above = ext_intra_extend_modes[ext_intra_mode] & NEED_ABOVE;
hui sube3559b2015-10-07 09:29:02 -07001213 }
1214#endif // CONFIG_EXT_INTRA
Jingning Han3ee6db62015-08-05 19:00:31 -07001215
1216 // 127 127 127 .. 127 127 127 127 127 127
1217 // 129 A B .. Y Z
1218 // 129 C D .. W X
1219 // 129 E F .. U V
1220 // 129 G H .. S T T T T T
1221 // ..
1222
Ronald S. Bultjec7dc1d72015-10-12 10:35:46 -04001223 (void) xd;
Ronald S. Bultjec7dc1d72015-10-12 10:35:46 -04001224 (void) plane;
1225 assert(n_top_px >= 0);
1226 assert(n_topright_px >= 0);
1227 assert(n_left_px >= 0);
1228 assert(n_bottomleft_px >= 0);
Jingning Han3ee6db62015-08-05 19:00:31 -07001229
1230 // NEED_LEFT
hui sube3559b2015-10-07 09:29:02 -07001231 if (need_left) {
hui sube3559b2015-10-07 09:29:02 -07001232#if CONFIG_EXT_INTRA
1233 int need_bottom;
1234 if (ext_intra_mode_info->use_ext_intra_mode[plane != 0]) {
hui su4aa50c12015-11-10 12:09:59 -08001235 need_bottom = 0;
1236 } else if (mode != DC_PRED && mode != TM_PRED &&
1237 xd->mi[0]->mbmi.sb_type >= BLOCK_8X8) {
1238 need_bottom = p_angle > 180;
hui sube3559b2015-10-07 09:29:02 -07001239 } else {
1240 need_bottom = !!(extend_modes[mode] & NEED_BOTTOMLEFT);
1241 }
1242#else
Ronald S. Bultjec7dc1d72015-10-12 10:35:46 -04001243 const int need_bottom = !!(extend_modes[mode] & NEED_BOTTOMLEFT);
hui sube3559b2015-10-07 09:29:02 -07001244#endif // CONFIG_EXT_INTRA
Ronald S. Bultjec7dc1d72015-10-12 10:35:46 -04001245 i = 0;
1246 if (n_left_px > 0) {
1247 for (; i < n_left_px; i++)
1248 left_col[i] = ref[i * ref_stride - 1];
1249 if (need_bottom && n_bottomleft_px > 0) {
1250 assert(i == bs);
1251 for (; i < bs + n_bottomleft_px; i++)
1252 left_col[i] = ref[i * ref_stride - 1];
1253 }
1254 if (i < (bs << need_bottom))
1255 memset(&left_col[i], left_col[i - 1], (bs << need_bottom) - i);
1256 } else {
1257 memset(left_col, 129, bs << need_bottom);
1258 }
Jingning Han3ee6db62015-08-05 19:00:31 -07001259 }
1260
1261 // NEED_ABOVE
hui sube3559b2015-10-07 09:29:02 -07001262 if (need_above) {
hui sube3559b2015-10-07 09:29:02 -07001263#if CONFIG_EXT_INTRA
1264 int need_right;
1265 if (ext_intra_mode_info->use_ext_intra_mode[plane != 0]) {
hui su4aa50c12015-11-10 12:09:59 -08001266 need_right = 1;
1267 } else if (mode != DC_PRED && mode != TM_PRED &&
1268 xd->mi[0]->mbmi.sb_type >= BLOCK_8X8) {
1269 need_right = p_angle < 90;
hui sube3559b2015-10-07 09:29:02 -07001270 } else {
1271 need_right = !!(extend_modes[mode] & NEED_ABOVERIGHT);
1272 }
1273#else
Ronald S. Bultjec7dc1d72015-10-12 10:35:46 -04001274 const int need_right = !!(extend_modes[mode] & NEED_ABOVERIGHT);
hui sube3559b2015-10-07 09:29:02 -07001275#endif // CONFIG_EXT_INTRA
Ronald S. Bultjec7dc1d72015-10-12 10:35:46 -04001276 if (n_top_px > 0) {
1277 memcpy(above_row, above_ref, n_top_px);
1278 i = n_top_px;
1279 if (need_right && n_topright_px > 0) {
1280 assert(n_top_px == bs);
1281 memcpy(above_row + bs, above_ref + bs, n_topright_px);
1282 i += n_topright_px;
1283 }
1284 if (i < (bs << need_right))
1285 memset(&above_row[i], above_row[i - 1], (bs << need_right) - i);
1286 } else {
1287 memset(above_row, 127, bs << need_right);
1288 }
Jingning Han3ee6db62015-08-05 19:00:31 -07001289 }
1290
hui sube3559b2015-10-07 09:29:02 -07001291#if CONFIG_EXT_INTRA
1292 if (ext_intra_mode_info->use_ext_intra_mode[plane != 0] ||
hui su4aa50c12015-11-10 12:09:59 -08001293 (extend_modes[mode] & NEED_ABOVELEFT) ||
1294 (mode != DC_PRED && mode != TM_PRED &&
1295 xd->mi[0]->mbmi.sb_type >= BLOCK_8X8)) {
Ronald S. Bultjec7dc1d72015-10-12 10:35:46 -04001296 above_row[-1] = n_top_px > 0 ? (n_left_px > 0 ? above_ref[-1] : 129) : 127;
1297 }
1298#else
hui sube3559b2015-10-07 09:29:02 -07001299 if ((extend_modes[mode] & NEED_ABOVELEFT)) {
1300 above_row[-1] = n_top_px > 0 ? (n_left_px > 0 ? above_ref[-1] : 129) : 127;
1301 }
1302#endif // CONFIG_EXT_INTRA
Jingning Han3ee6db62015-08-05 19:00:31 -07001303
hui sube3559b2015-10-07 09:29:02 -07001304#if CONFIG_EXT_INTRA
1305 if (ext_intra_mode_info->use_ext_intra_mode[plane != 0]) {
hui su4aa50c12015-11-10 12:09:59 -08001306 filter_intra_predictors[ext_intra_mode](dst, dst_stride, bs,
1307 const_above_row, left_col);
1308 return;
1309 }
1310
1311 if (mode != DC_PRED && mode != TM_PRED &&
1312 xd->mi[0]->mbmi.sb_type >= BLOCK_8X8) {
hui su3b1c7662016-01-12 16:38:58 -08001313 INTRA_FILTER filter = INTRA_FILTER_LINEAR;
1314 if (plane == 0 && pick_intra_filter(p_angle))
1315 filter = xd->mi[0]->mbmi.intra_filter;
1316 dr_predictor(dst, dst_stride, tx_size, const_above_row, left_col, p_angle,
1317 filter);
hui sube3559b2015-10-07 09:29:02 -07001318 return;
1319 }
1320#endif // CONFIG_EXT_INTRA
1321
Jingning Han3ee6db62015-08-05 19:00:31 -07001322 // predict
1323 if (mode == DC_PRED) {
Ronald S. Bultjec7dc1d72015-10-12 10:35:46 -04001324 dc_pred[n_left_px > 0][n_top_px > 0][tx_size](dst, dst_stride,
1325 const_above_row, left_col);
Jingning Han3ee6db62015-08-05 19:00:31 -07001326 } else {
1327 pred[mode][tx_size](dst, dst_stride, const_above_row, left_col);
1328 }
1329}
1330
Ronald S. Bultjec7dc1d72015-10-12 10:35:46 -04001331void vp10_predict_intra_block(const MACROBLOCKD *xd, int bwl_in, int bhl_in,
hui su4aa50c12015-11-10 12:09:59 -08001332 TX_SIZE tx_size, PREDICTION_MODE mode,
1333 const uint8_t *ref, int ref_stride,
1334 uint8_t *dst, int dst_stride,
Geza Lore44dba012016-02-22 10:58:52 +00001335 int col_off, int row_off, int plane) {
Jingning Han3ee6db62015-08-05 19:00:31 -07001336 const int txw = (1 << tx_size);
Geza Lore44dba012016-02-22 10:58:52 +00001337 const int have_top = row_off || xd->up_available;
1338 const int have_left = col_off || xd->left_available;
1339 const int x = col_off * 4;
1340 const int y = row_off * 4;
Ronald S. Bultjec7dc1d72015-10-12 10:35:46 -04001341 const int bw = VPXMAX(2, 1 << bwl_in);
1342 const int bh = VPXMAX(2, 1 << bhl_in);
hui subf0ff092015-12-01 17:19:52 -08001343 const int mi_row = -xd->mb_to_top_edge >> (3 + MI_SIZE_LOG2);
1344 const int mi_col = -xd->mb_to_left_edge >> (3 + MI_SIZE_LOG2);
Ronald S. Bultjec7dc1d72015-10-12 10:35:46 -04001345 const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
1346 const struct macroblockd_plane *const pd = &xd->plane[plane];
Ronald S. Bultje3d908192015-10-20 19:13:10 -04001347 const int right_available =
hui suebc6e052016-03-02 11:22:09 -08001348 mi_col + (1 << mi_width_log2_lookup[bsize]) < xd->tile.mi_col_end;
Ronald S. Bultjec7dc1d72015-10-12 10:35:46 -04001349 const int have_right = vp10_has_right(bsize, mi_row, mi_col,
Ronald S. Bultje3d908192015-10-20 19:13:10 -04001350 right_available,
Geza Lore44dba012016-02-22 10:58:52 +00001351 tx_size, row_off, col_off,
Ronald S. Bultjec7dc1d72015-10-12 10:35:46 -04001352 pd->subsampling_x);
1353 const int have_bottom = vp10_has_bottom(bsize, mi_row, mi_col,
1354 xd->mb_to_bottom_edge > 0,
Geza Lore44dba012016-02-22 10:58:52 +00001355 tx_size, row_off, col_off,
Ronald S. Bultjec7dc1d72015-10-12 10:35:46 -04001356 pd->subsampling_y);
1357 const int wpx = 4 * bw;
1358 const int hpx = 4 * bh;
1359 const int txpx = 4 * txw;
hui subf0ff092015-12-01 17:19:52 -08001360 // Distance between the right edge of this prediction block to
1361 // the frame right edge
1362 const int xr = (xd->mb_to_right_edge >> (3 + pd->subsampling_x)) +
1363 (wpx - x - txpx);
1364 // Distance between the bottom edge of this prediction block to
1365 // the frame bottom edge
1366 const int yd = (xd->mb_to_bottom_edge >> (3 + pd->subsampling_y)) +
1367 (hpx - y - txpx);
Jingning Han3ee6db62015-08-05 19:00:31 -07001368
hui suc93e5cc2015-12-07 18:18:57 -08001369 if (xd->mi[0]->mbmi.palette_mode_info.palette_size[plane != 0] > 0) {
1370 const int bs = 4 * (1 << tx_size);
1371 const int stride = 4 * (1 << bwl_in);
1372 int r, c;
1373 uint8_t *map = NULL;
1374#if CONFIG_VP9_HIGHBITDEPTH
1375 uint16_t *palette = xd->mi[0]->mbmi.palette_mode_info.palette_colors +
1376 plane * PALETTE_MAX_SIZE;
1377#else
1378 uint8_t *palette = xd->mi[0]->mbmi.palette_mode_info.palette_colors +
1379 plane * PALETTE_MAX_SIZE;
1380#endif // CONFIG_VP9_HIGHBITDEPTH
1381
1382 map = xd->plane[plane != 0].color_index_map;
1383
1384#if CONFIG_VP9_HIGHBITDEPTH
1385 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
1386 uint16_t *dst16 = CONVERT_TO_SHORTPTR(dst);
1387 for (r = 0; r < bs; ++r)
1388 for (c = 0; c < bs; ++c)
1389 dst16[r * dst_stride + c] =
1390 palette[map[(r + y) * stride + c + x]];
1391 } else {
hui suc93e5cc2015-12-07 18:18:57 -08001392 for (r = 0; r < bs; ++r)
1393 for (c = 0; c < bs; ++c)
Yaowu Xu3c28b4a2016-02-08 09:41:43 -08001394 dst[r * dst_stride + c] =
1395 (uint8_t)(palette[map[(r + y) * stride + c + x]]);
hui suc93e5cc2015-12-07 18:18:57 -08001396 }
Yaowu Xu3c28b4a2016-02-08 09:41:43 -08001397#else
1398 for (r = 0; r < bs; ++r)
1399 for (c = 0; c < bs; ++c)
1400 dst[r * dst_stride + c] = palette[map[(r + y) * stride + c + x]];
hui suc93e5cc2015-12-07 18:18:57 -08001401#endif // CONFIG_VP9_HIGHBITDEPTH
hui suc93e5cc2015-12-07 18:18:57 -08001402 return;
1403 }
1404
Jingning Han3ee6db62015-08-05 19:00:31 -07001405#if CONFIG_VP9_HIGHBITDEPTH
1406 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
1407 build_intra_predictors_high(xd, ref, ref_stride, dst, dst_stride, mode,
Ronald S. Bultjec7dc1d72015-10-12 10:35:46 -04001408 tx_size,
1409 have_top ? VPXMIN(txpx, xr + txpx) : 0,
1410 have_top && have_right ? VPXMIN(txpx, xr) : 0,
1411 have_left ? VPXMIN(txpx, yd + txpx) : 0,
1412 have_bottom && have_left ? VPXMIN(txpx, yd) : 0,
hui su66f2f652015-11-16 16:58:15 -08001413 plane);
Ronald S. Bultjec7dc1d72015-10-12 10:35:46 -04001414 return;
1415 }
1416#endif
1417 build_intra_predictors(xd, ref, ref_stride, dst, dst_stride, mode,
1418 tx_size,
1419 have_top ? VPXMIN(txpx, xr + txpx) : 0,
1420 have_top && have_right ? VPXMIN(txpx, xr) : 0,
1421 have_left ? VPXMIN(txpx, yd + txpx) : 0,
1422 have_bottom && have_left ? VPXMIN(txpx, yd) : 0,
hui su66f2f652015-11-16 16:58:15 -08001423 plane);
Jingning Han3ee6db62015-08-05 19:00:31 -07001424}
1425
1426void vp10_init_intra_predictors(void) {
1427 once(vp10_init_intra_predictors_internal);
1428}