1/*
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
11#include "./vpx_config.h"
12#include "./vp9_rtcd.h"
13
14#include "vpx_mem/vpx_mem.h"
15
16#include "vp9/common/vp9_reconintra.h"
17#include "vp9/common/vp9_onyxc_int.h"
18
19const TX_TYPE intra_mode_to_tx_type_lookup[INTRA_MODES] = {
20  DCT_DCT,    // DC
21  ADST_DCT,   // V
22  DCT_ADST,   // H
23  DCT_DCT,    // D45
24  ADST_ADST,  // D135
25  ADST_DCT,   // D117
26  DCT_ADST,   // D153
27  DCT_ADST,   // D207
28  ADST_DCT,   // D63
29  ADST_ADST,  // TM
30};
31
32// This serves as a wrapper function, so that all the prediction functions
33// can be unified and accessed as a pointer array. Note that the boundary
34// above and left are not necessarily used all the time.
35#define intra_pred_sized(type, size) \
36  void vp9_##type##_predictor_##size##x##size##_c(uint8_t *dst, \
37                                                  ptrdiff_t stride, \
38                                                  const uint8_t *above, \
39                                                  const uint8_t *left) { \
40    type##_predictor(dst, stride, size, above, left); \
41  }
42
43#if CONFIG_VP9_HIGHBITDEPTH
44#define intra_pred_high_sized(type, size) \
45  void vp9_high_##type##_predictor_##size##x##size##_c( \
46      uint16_t *dst, ptrdiff_t stride, const uint16_t *above, \
47      const uint16_t *left, int bd) { \
48    high_##type##_predictor(dst, stride, size, above, left, bd); \
49  }
50
51#define intra_pred_allsizes(type) \
52  intra_pred_sized(type, 4) \
53  intra_pred_sized(type, 8) \
54  intra_pred_sized(type, 16) \
55  intra_pred_sized(type, 32) \
56  intra_pred_high_sized(type, 4) \
57  intra_pred_high_sized(type, 8) \
58  intra_pred_high_sized(type, 16) \
59  intra_pred_high_sized(type, 32)
60
61#else
62
63#define intra_pred_allsizes(type) \
64  intra_pred_sized(type, 4) \
65  intra_pred_sized(type, 8) \
66  intra_pred_sized(type, 16) \
67  intra_pred_sized(type, 32)
68#endif  // CONFIG_VP9_HIGHBITDEPTH
69
70#if CONFIG_VP9_HIGHBITDEPTH
71static INLINE void high_d207_predictor(uint16_t *dst, ptrdiff_t stride, int bs,
72                                       const uint16_t *above,
73                                       const uint16_t *left, int bd) {
74  int r, c;
75  (void) above;
76  (void) bd;
77
78  // First column.
79  for (r = 0; r < bs - 1; ++r) {
80    dst[r * stride] = ROUND_POWER_OF_TWO(left[r] + left[r + 1], 1);
81  }
82  dst[(bs - 1) * stride] = left[bs - 1];
83  dst++;
84
85  // Second column.
86  for (r = 0; r < bs - 2; ++r) {
87    dst[r * stride] = ROUND_POWER_OF_TWO(left[r] + left[r + 1] * 2 +
88                                         left[r + 2], 2);
89  }
90  dst[(bs - 2) * stride] = ROUND_POWER_OF_TWO(left[bs - 2] +
91                                              left[bs - 1] * 3, 2);
92  dst[(bs - 1) * stride] = left[bs - 1];
93  dst++;
94
95  // Rest of last row.
96  for (c = 0; c < bs - 2; ++c)
97    dst[(bs - 1) * stride + c] = left[bs - 1];
98
99  for (r = bs - 2; r >= 0; --r) {
100    for (c = 0; c < bs - 2; ++c)
101      dst[r * stride + c] = dst[(r + 1) * stride + c - 2];
102  }
103}
104
105static INLINE void high_d63_predictor(uint16_t *dst, ptrdiff_t stride, int bs,
106                                      const uint16_t *above,
107                                      const uint16_t *left, int bd) {
108  int r, c;
109  (void) left;
110  (void) bd;
111  for (r = 0; r < bs; ++r) {
112    for (c = 0; c < bs; ++c) {
113      dst[c] = r & 1 ? ROUND_POWER_OF_TWO(above[r/2 + c] +
114                                          above[r/2 + c + 1] * 2 +
115                                          above[r/2 + c + 2], 2)
116                     : ROUND_POWER_OF_TWO(above[r/2 + c] +
117                                          above[r/2 + c + 1], 1);
118    }
119    dst += stride;
120  }
121}
122
123static INLINE void high_d45_predictor(uint16_t *dst, ptrdiff_t stride, int bs,
124                                      const uint16_t *above,
125                                      const uint16_t *left, int bd) {
126  int r, c;
127  (void) left;
128  (void) bd;
129  for (r = 0; r < bs; ++r) {
130    for (c = 0; c < bs; ++c) {
131      dst[c] = r + c + 2 < bs * 2 ?  ROUND_POWER_OF_TWO(above[r + c] +
132                                                        above[r + c + 1] * 2 +
133                                                        above[r + c + 2], 2)
134                                  : above[bs * 2 - 1];
135    }
136    dst += stride;
137  }
138}
139
140static INLINE void high_d117_predictor(uint16_t *dst, ptrdiff_t stride,
141                                       int bs, const uint16_t *above,
142                                       const uint16_t *left, int bd) {
143  int r, c;
144  (void) bd;
145
146  // first row
147  for (c = 0; c < bs; c++)
148    dst[c] = ROUND_POWER_OF_TWO(above[c - 1] + above[c], 1);
149  dst += stride;
150
151  // second row
152  dst[0] = ROUND_POWER_OF_TWO(left[0] + above[-1] * 2 + above[0], 2);
153  for (c = 1; c < bs; c++)
154    dst[c] = ROUND_POWER_OF_TWO(above[c - 2] + above[c - 1] * 2 + above[c], 2);
155  dst += stride;
156
157  // the rest of first col
158  dst[0] = ROUND_POWER_OF_TWO(above[-1] + left[0] * 2 + left[1], 2);
159  for (r = 3; r < bs; ++r)
160    dst[(r - 2) * stride] = ROUND_POWER_OF_TWO(left[r - 3] + left[r - 2] * 2 +
161                                               left[r - 1], 2);
162
163  // the rest of the block
164  for (r = 2; r < bs; ++r) {
165    for (c = 1; c < bs; c++)
166      dst[c] = dst[-2 * stride + c - 1];
167    dst += stride;
168  }
169}
170
171static INLINE void high_d135_predictor(uint16_t *dst, ptrdiff_t stride, int bs,
172                                       const uint16_t *above,
173                                       const uint16_t *left, int bd) {
174  int r, c;
175  (void) bd;
176  dst[0] = ROUND_POWER_OF_TWO(left[0] + above[-1] * 2 + above[0], 2);
177  for (c = 1; c < bs; c++)
178    dst[c] = ROUND_POWER_OF_TWO(above[c - 2] + above[c - 1] * 2 + above[c], 2);
179
180  dst[stride] = ROUND_POWER_OF_TWO(above[-1] + left[0] * 2 + left[1], 2);
181  for (r = 2; r < bs; ++r)
182    dst[r * stride] = ROUND_POWER_OF_TWO(left[r - 2] + left[r - 1] * 2 +
183                                         left[r], 2);
184
185  dst += stride;
186  for (r = 1; r < bs; ++r) {
187    for (c = 1; c < bs; c++)
188      dst[c] = dst[-stride + c - 1];
189    dst += stride;
190  }
191}
192
193static INLINE void high_d153_predictor(uint16_t *dst, ptrdiff_t stride, int bs,
194                                       const uint16_t *above,
195                                       const uint16_t *left, int bd) {
196  int r, c;
197  (void) bd;
198  dst[0] = ROUND_POWER_OF_TWO(above[-1] + left[0], 1);
199  for (r = 1; r < bs; r++)
200    dst[r * stride] = ROUND_POWER_OF_TWO(left[r - 1] + left[r], 1);
201  dst++;
202
203  dst[0] = ROUND_POWER_OF_TWO(left[0] + above[-1] * 2 + above[0], 2);
204  dst[stride] = ROUND_POWER_OF_TWO(above[-1] + left[0] * 2 + left[1], 2);
205  for (r = 2; r < bs; r++)
206    dst[r * stride] = ROUND_POWER_OF_TWO(left[r - 2] + left[r - 1] * 2 +
207                                         left[r], 2);
208  dst++;
209
210  for (c = 0; c < bs - 2; c++)
211    dst[c] = ROUND_POWER_OF_TWO(above[c - 1] + above[c] * 2 + above[c + 1], 2);
212  dst += stride;
213
214  for (r = 1; r < bs; ++r) {
215    for (c = 0; c < bs - 2; c++)
216      dst[c] = dst[-stride + c - 2];
217    dst += stride;
218  }
219}
220
221static INLINE void high_v_predictor(uint16_t *dst, ptrdiff_t stride, int bs,
222                                    const uint16_t *above,
223                                    const uint16_t *left, int bd) {
224  int r;
225  (void) left;
226  (void) bd;
227  for (r = 0; r < bs; r++) {
228    vpx_memcpy(dst, above, bs * sizeof(uint16_t));
229    dst += stride;
230  }
231}
232
233static INLINE void high_h_predictor(uint16_t *dst, ptrdiff_t stride, int bs,
234                                    const uint16_t *above, const uint16_t *left,
235                                    int bd) {
236  int r;
237  (void) above;
238  (void) bd;
239  for (r = 0; r < bs; r++) {
240    vpx_memset16(dst, left[r], bs);
241    dst += stride;
242  }
243}
244
245static INLINE void high_tm_predictor(uint16_t *dst, ptrdiff_t stride, int bs,
246                                     const uint16_t *above,
247                                     const uint16_t *left, int bd) {
248  int r, c;
249  int ytop_left = above[-1];
250  (void) bd;
251
252  for (r = 0; r < bs; r++) {
253    for (c = 0; c < bs; c++)
254      dst[c] = clip_pixel_high(left[r] + above[c] - ytop_left, bd);
255    dst += stride;
256  }
257}
258
259static INLINE void high_dc_128_predictor(uint16_t *dst, ptrdiff_t stride,
260                                         int bs, const uint16_t *above,
261                                         const uint16_t *left, int bd) {
262  int r;
263  (void) above;
264  (void) left;
265
266  for (r = 0; r < bs; r++) {
267    vpx_memset16(dst, 128 << (bd - 8), bs);
268    dst += stride;
269  }
270}
271
272static INLINE void high_dc_left_predictor(uint16_t *dst, ptrdiff_t stride,
273                                          int bs, const uint16_t *above,
274                                          const uint16_t *left, int bd) {
275  int i, r, expected_dc, sum = 0;
276  (void) above;
277  (void) bd;
278
279  for (i = 0; i < bs; i++)
280    sum += left[i];
281  expected_dc = (sum + (bs >> 1)) / bs;
282
283  for (r = 0; r < bs; r++) {
284    vpx_memset16(dst, expected_dc, bs);
285    dst += stride;
286  }
287}
288
289static INLINE void high_dc_top_predictor(uint16_t *dst, ptrdiff_t stride,
290                                         int bs, const uint16_t *above,
291                                         const uint16_t *left, int bd) {
292  int i, r, expected_dc, sum = 0;
293  (void) left;
294  (void) bd;
295
296  for (i = 0; i < bs; i++)
297    sum += above[i];
298  expected_dc = (sum + (bs >> 1)) / bs;
299
300  for (r = 0; r < bs; r++) {
301    vpx_memset16(dst, expected_dc, bs);
302    dst += stride;
303  }
304}
305
306static INLINE void high_dc_predictor(uint16_t *dst, ptrdiff_t stride,
307                                     int bs, const uint16_t *above,
308                                     const uint16_t *left, int bd) {
309  int i, r, expected_dc, sum = 0;
310  const int count = 2 * bs;
311  (void) bd;
312
313  for (i = 0; i < bs; i++) {
314    sum += above[i];
315    sum += left[i];
316  }
317
318  expected_dc = (sum + (count >> 1)) / count;
319
320  for (r = 0; r < bs; r++) {
321    vpx_memset16(dst, expected_dc, bs);
322    dst += stride;
323  }
324}
325#endif  // CONFIG_VP9_HIGHBITDEPTH
326
327static INLINE void d207_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
328                                  const uint8_t *above, const uint8_t *left) {
329  int r, c;
330  (void) above;
331  // first column
332  for (r = 0; r < bs - 1; ++r)
333    dst[r * stride] = ROUND_POWER_OF_TWO(left[r] + left[r + 1], 1);
334  dst[(bs - 1) * stride] = left[bs - 1];
335  dst++;
336
337  // second column
338  for (r = 0; r < bs - 2; ++r)
339    dst[r * stride] = ROUND_POWER_OF_TWO(left[r] + left[r + 1] * 2 +
340                                         left[r + 2], 2);
341  dst[(bs - 2) * stride] = ROUND_POWER_OF_TWO(left[bs - 2] +
342                                              left[bs - 1] * 3, 2);
343  dst[(bs - 1) * stride] = left[bs - 1];
344  dst++;
345
346  // rest of last row
347  for (c = 0; c < bs - 2; ++c)
348    dst[(bs - 1) * stride + c] = left[bs - 1];
349
350  for (r = bs - 2; r >= 0; --r)
351    for (c = 0; c < bs - 2; ++c)
352      dst[r * stride + c] = dst[(r + 1) * stride + c - 2];
353}
354intra_pred_allsizes(d207)
355
356static INLINE void d63_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
357                                 const uint8_t *above, const uint8_t *left) {
358  int r, c;
359  (void) left;
360  for (r = 0; r < bs; ++r) {
361    for (c = 0; c < bs; ++c)
362      dst[c] = r & 1 ? ROUND_POWER_OF_TWO(above[r/2 + c] +
363                                          above[r/2 + c + 1] * 2 +
364                                          above[r/2 + c + 2], 2)
365                     : ROUND_POWER_OF_TWO(above[r/2 + c] +
366                                          above[r/2 + c + 1], 1);
367    dst += stride;
368  }
369}
370intra_pred_allsizes(d63)
371
372static INLINE void d45_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
373                                 const uint8_t *above, const uint8_t *left) {
374  int r, c;
375  (void) left;
376  for (r = 0; r < bs; ++r) {
377    for (c = 0; c < bs; ++c)
378      dst[c] = r + c + 2 < bs * 2 ?  ROUND_POWER_OF_TWO(above[r + c] +
379                                                        above[r + c + 1] * 2 +
380                                                        above[r + c + 2], 2)
381                                  : above[bs * 2 - 1];
382    dst += stride;
383  }
384}
385intra_pred_allsizes(d45)
386
387static INLINE void d117_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
388                                  const uint8_t *above, const uint8_t *left) {
389  int r, c;
390
391  // first row
392  for (c = 0; c < bs; c++)
393    dst[c] = ROUND_POWER_OF_TWO(above[c - 1] + above[c], 1);
394  dst += stride;
395
396  // second row
397  dst[0] = ROUND_POWER_OF_TWO(left[0] + above[-1] * 2 + above[0], 2);
398  for (c = 1; c < bs; c++)
399    dst[c] = ROUND_POWER_OF_TWO(above[c - 2] + above[c - 1] * 2 + above[c], 2);
400  dst += stride;
401
402  // the rest of first col
403  dst[0] = ROUND_POWER_OF_TWO(above[-1] + left[0] * 2 + left[1], 2);
404  for (r = 3; r < bs; ++r)
405    dst[(r - 2) * stride] = ROUND_POWER_OF_TWO(left[r - 3] + left[r - 2] * 2 +
406                                               left[r - 1], 2);
407
408  // the rest of the block
409  for (r = 2; r < bs; ++r) {
410    for (c = 1; c < bs; c++)
411      dst[c] = dst[-2 * stride + c - 1];
412    dst += stride;
413  }
414}
415intra_pred_allsizes(d117)
416
417static INLINE void d135_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
418                                  const uint8_t *above, const uint8_t *left) {
419  int r, c;
420  dst[0] = ROUND_POWER_OF_TWO(left[0] + above[-1] * 2 + above[0], 2);
421  for (c = 1; c < bs; c++)
422    dst[c] = ROUND_POWER_OF_TWO(above[c - 2] + above[c - 1] * 2 + above[c], 2);
423
424  dst[stride] = ROUND_POWER_OF_TWO(above[-1] + left[0] * 2 + left[1], 2);
425  for (r = 2; r < bs; ++r)
426    dst[r * stride] = ROUND_POWER_OF_TWO(left[r - 2] + left[r - 1] * 2 +
427                                         left[r], 2);
428
429  dst += stride;
430  for (r = 1; r < bs; ++r) {
431    for (c = 1; c < bs; c++)
432      dst[c] = dst[-stride + c - 1];
433    dst += stride;
434  }
435}
436intra_pred_allsizes(d135)
437
438static INLINE void d153_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
439                                  const uint8_t *above, const uint8_t *left) {
440  int r, c;
441  dst[0] = ROUND_POWER_OF_TWO(above[-1] + left[0], 1);
442  for (r = 1; r < bs; r++)
443    dst[r * stride] = ROUND_POWER_OF_TWO(left[r - 1] + left[r], 1);
444  dst++;
445
446  dst[0] = ROUND_POWER_OF_TWO(left[0] + above[-1] * 2 + above[0], 2);
447  dst[stride] = ROUND_POWER_OF_TWO(above[-1] + left[0] * 2 + left[1], 2);
448  for (r = 2; r < bs; r++)
449    dst[r * stride] = ROUND_POWER_OF_TWO(left[r - 2] + left[r - 1] * 2 +
450                                         left[r], 2);
451  dst++;
452
453  for (c = 0; c < bs - 2; c++)
454    dst[c] = ROUND_POWER_OF_TWO(above[c - 1] + above[c] * 2 + above[c + 1], 2);
455  dst += stride;
456
457  for (r = 1; r < bs; ++r) {
458    for (c = 0; c < bs - 2; c++)
459      dst[c] = dst[-stride + c - 2];
460    dst += stride;
461  }
462}
463intra_pred_allsizes(d153)
464
465static INLINE void v_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
466                               const uint8_t *above, const uint8_t *left) {
467  int r;
468  (void) left;
469
470  for (r = 0; r < bs; r++) {
471    vpx_memcpy(dst, above, bs);
472    dst += stride;
473  }
474}
475intra_pred_allsizes(v)
476
477static INLINE void h_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
478                               const uint8_t *above, const uint8_t *left) {
479  int r;
480  (void) above;
481
482  for (r = 0; r < bs; r++) {
483    vpx_memset(dst, left[r], bs);
484    dst += stride;
485  }
486}
487intra_pred_allsizes(h)
488
489static INLINE void tm_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
490                                const uint8_t *above, const uint8_t *left) {
491  int r, c;
492  int ytop_left = above[-1];
493
494  for (r = 0; r < bs; r++) {
495    for (c = 0; c < bs; c++)
496      dst[c] = clip_pixel(left[r] + above[c] - ytop_left);
497    dst += stride;
498  }
499}
500intra_pred_allsizes(tm)
501
502static INLINE void dc_128_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
503                                    const uint8_t *above, const uint8_t *left) {
504  int r;
505  (void) above;
506  (void) left;
507
508  for (r = 0; r < bs; r++) {
509    vpx_memset(dst, 128, bs);
510    dst += stride;
511  }
512}
513intra_pred_allsizes(dc_128)
514
515static INLINE void dc_left_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
516                                     const uint8_t *above,
517                                     const uint8_t *left) {
518  int i, r, expected_dc, sum = 0;
519  (void) above;
520
521  for (i = 0; i < bs; i++)
522    sum += left[i];
523  expected_dc = (sum + (bs >> 1)) / bs;
524
525  for (r = 0; r < bs; r++) {
526    vpx_memset(dst, expected_dc, bs);
527    dst += stride;
528  }
529}
530intra_pred_allsizes(dc_left)
531
532static INLINE void dc_top_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
533                                    const uint8_t *above, const uint8_t *left) {
534  int i, r, expected_dc, sum = 0;
535  (void) left;
536
537  for (i = 0; i < bs; i++)
538    sum += above[i];
539  expected_dc = (sum + (bs >> 1)) / bs;
540
541  for (r = 0; r < bs; r++) {
542    vpx_memset(dst, expected_dc, bs);
543    dst += stride;
544  }
545}
546intra_pred_allsizes(dc_top)
547
548static INLINE void dc_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
549                                const uint8_t *above, const uint8_t *left) {
550  int i, r, expected_dc, sum = 0;
551  const int count = 2 * bs;
552
553  for (i = 0; i < bs; i++) {
554    sum += above[i];
555    sum += left[i];
556  }
557
558  expected_dc = (sum + (count >> 1)) / count;
559
560  for (r = 0; r < bs; r++) {
561    vpx_memset(dst, expected_dc, bs);
562    dst += stride;
563  }
564}
565intra_pred_allsizes(dc)
566#undef intra_pred_allsizes
567
568typedef void (*intra_pred_fn)(uint8_t *dst, ptrdiff_t stride,
569                              const uint8_t *above, const uint8_t *left);
570
571static intra_pred_fn pred[INTRA_MODES][TX_SIZES];
572static intra_pred_fn dc_pred[2][2][TX_SIZES];
573
574#if CONFIG_VP9_HIGHBITDEPTH
575typedef void (*intra_high_pred_fn)(uint16_t *dst, ptrdiff_t stride,
576                                   const uint16_t *above, const uint16_t *left,
577                                   int bd);
578static intra_high_pred_fn pred_high[INTRA_MODES][4];
579static intra_high_pred_fn dc_pred_high[2][2][4];
580#endif  // CONFIG_VP9_HIGHBITDEPTH
581
582void vp9_init_intra_predictors() {
583#define INIT_ALL_SIZES(p, type) \
584  p[TX_4X4] = vp9_##type##_predictor_4x4; \
585  p[TX_8X8] = vp9_##type##_predictor_8x8; \
586  p[TX_16X16] = vp9_##type##_predictor_16x16; \
587  p[TX_32X32] = vp9_##type##_predictor_32x32
588
589  INIT_ALL_SIZES(pred[V_PRED], v);
590  INIT_ALL_SIZES(pred[H_PRED], h);
591  INIT_ALL_SIZES(pred[D207_PRED], d207);
592  INIT_ALL_SIZES(pred[D45_PRED], d45);
593  INIT_ALL_SIZES(pred[D63_PRED], d63);
594  INIT_ALL_SIZES(pred[D117_PRED], d117);
595  INIT_ALL_SIZES(pred[D135_PRED], d135);
596  INIT_ALL_SIZES(pred[D153_PRED], d153);
597  INIT_ALL_SIZES(pred[TM_PRED], tm);
598
599  INIT_ALL_SIZES(dc_pred[0][0], dc_128);
600  INIT_ALL_SIZES(dc_pred[0][1], dc_top);
601  INIT_ALL_SIZES(dc_pred[1][0], dc_left);
602  INIT_ALL_SIZES(dc_pred[1][1], dc);
603
604#if CONFIG_VP9_HIGHBITDEPTH
605  INIT_ALL_SIZES(pred_high[V_PRED], high_v);
606  INIT_ALL_SIZES(pred_high[H_PRED], high_h);
607  INIT_ALL_SIZES(pred_high[D207_PRED], high_d207);
608  INIT_ALL_SIZES(pred_high[D45_PRED], high_d45);
609  INIT_ALL_SIZES(pred_high[D63_PRED], high_d63);
610  INIT_ALL_SIZES(pred_high[D117_PRED], high_d117);
611  INIT_ALL_SIZES(pred_high[D135_PRED], high_d135);
612  INIT_ALL_SIZES(pred_high[D153_PRED], high_d153);
613  INIT_ALL_SIZES(pred_high[TM_PRED], high_tm);
614
615  INIT_ALL_SIZES(dc_pred_high[0][0], high_dc_128);
616  INIT_ALL_SIZES(dc_pred_high[0][1], high_dc_top);
617  INIT_ALL_SIZES(dc_pred_high[1][0], high_dc_left);
618  INIT_ALL_SIZES(dc_pred_high[1][1], high_dc);
619#endif  // CONFIG_VP9_HIGHBITDEPTH
620
621#undef intra_pred_allsizes
622}
623
624#if CONFIG_VP9_HIGHBITDEPTH
625static void build_intra_predictors_high(const MACROBLOCKD *xd,
626                                        const uint8_t *ref8,
627                                        int ref_stride,
628                                        uint8_t *dst8,
629                                        int dst_stride,
630                                        PREDICTION_MODE mode,
631                                        TX_SIZE tx_size,
632                                        int up_available,
633                                        int left_available,
634                                        int right_available,
635                                        int x, int y,
636                                        int plane, int bd) {
637  int i;
638  uint16_t *dst = CONVERT_TO_SHORTPTR(dst8);
639  uint16_t *ref = CONVERT_TO_SHORTPTR(ref8);
640  DECLARE_ALIGNED_ARRAY(16, uint16_t, left_col, 64);
641  DECLARE_ALIGNED_ARRAY(16, uint16_t, above_data, 128 + 16);
642  uint16_t *above_row = above_data + 16;
643  const uint16_t *const_above_row = above_row;
644  const int bs = 4 << tx_size;
645  int frame_width, frame_height;
646  int x0, y0;
647  const struct macroblockd_plane *const pd = &xd->plane[plane];
648  //  int base=128;
649  int base = 128 << (bd - 8);
650  // 127 127 127 .. 127 127 127 127 127 127
651  // 129  A   B  ..  Y   Z
652  // 129  C   D  ..  W   X
653  // 129  E   F  ..  U   V
654  // 129  G   H  ..  S   T   T   T   T   T
655
656  // Get current frame pointer, width and height.
657  if (plane == 0) {
658    frame_width = xd->cur_buf->y_width;
659    frame_height = xd->cur_buf->y_height;
660  } else {
661    frame_width = xd->cur_buf->uv_width;
662    frame_height = xd->cur_buf->uv_height;
663  }
664
665  // Get block position in current frame.
666  x0 = (-xd->mb_to_left_edge >> (3 + pd->subsampling_x)) + x;
667  y0 = (-xd->mb_to_top_edge >> (3 + pd->subsampling_y)) + y;
668
669  // left
670  if (left_available) {
671    if (xd->mb_to_bottom_edge < 0) {
672      /* slower path if the block needs border extension */
673      if (y0 + bs <= frame_height) {
674        for (i = 0; i < bs; ++i)
675          left_col[i] = ref[i * ref_stride - 1];
676      } else {
677        const int extend_bottom = frame_height - y0;
678        for (i = 0; i < extend_bottom; ++i)
679          left_col[i] = ref[i * ref_stride - 1];
680        for (; i < bs; ++i)
681          left_col[i] = ref[(extend_bottom - 1) * ref_stride - 1];
682      }
683    } else {
684      /* faster path if the block does not need extension */
685      for (i = 0; i < bs; ++i)
686        left_col[i] = ref[i * ref_stride - 1];
687    }
688  } else {
689    // TODO(Peter): this value should probably change for high bitdepth
690    vpx_memset16(left_col, base + 1, bs);
691  }
692
693  // TODO(hkuang) do not extend 2*bs pixels for all modes.
694  // above
695  if (up_available) {
696    const uint16_t *above_ref = ref - ref_stride;
697    if (xd->mb_to_right_edge < 0) {
698      /* slower path if the block needs border extension */
699      if (x0 + 2 * bs <= frame_width) {
700        if (right_available && bs == 4) {
701          vpx_memcpy(above_row, above_ref, 2 * bs * sizeof(uint16_t));
702        } else {
703          vpx_memcpy(above_row, above_ref, bs * sizeof(uint16_t));
704          vpx_memset16(above_row + bs, above_row[bs - 1], bs);
705        }
706      } else if (x0 + bs <= frame_width) {
707        const int r = frame_width - x0;
708        if (right_available && bs == 4) {
709          vpx_memcpy(above_row, above_ref, r * sizeof(uint16_t));
710          vpx_memset16(above_row + r, above_row[r - 1],
711                       x0 + 2 * bs - frame_width);
712        } else {
713          vpx_memcpy(above_row, above_ref, bs * sizeof(uint16_t));
714          vpx_memset16(above_row + bs, above_row[bs - 1], bs);
715        }
716      } else if (x0 <= frame_width) {
717        const int r = frame_width - x0;
718        if (right_available && bs == 4) {
719          vpx_memcpy(above_row, above_ref, r * sizeof(uint16_t));
720          vpx_memset16(above_row + r, above_row[r - 1],
721                       x0 + 2 * bs - frame_width);
722        } else {
723          vpx_memcpy(above_row, above_ref, r * sizeof(uint16_t));
724          vpx_memset16(above_row + r, above_row[r - 1],
725                       x0 + 2 * bs - frame_width);
726        }
727      }
728      // TODO(Peter) this value should probably change for high bitdepth
729      above_row[-1] = left_available ? above_ref[-1] : (base+1);
730    } else {
731      /* faster path if the block does not need extension */
732      if (bs == 4 && right_available && left_available) {
733        const_above_row = above_ref;
734      } else {
735        vpx_memcpy(above_row, above_ref, bs * sizeof(uint16_t));
736        if (bs == 4 && right_available)
737          vpx_memcpy(above_row + bs, above_ref + bs, bs * sizeof(uint16_t));
738        else
739          vpx_memset16(above_row + bs, above_row[bs - 1], bs);
740        // TODO(Peter): this value should probably change for high bitdepth
741        above_row[-1] = left_available ? above_ref[-1] : (base+1);
742      }
743    }
744  } else {
745    vpx_memset16(above_row, base - 1, bs * 2);
746    // TODO(Peter): this value should probably change for high bitdepth
747    above_row[-1] = base - 1;
748  }
749
750  // predict
751  if (mode == DC_PRED) {
752    dc_pred_high[left_available][up_available][tx_size](dst, dst_stride,
753                                                        const_above_row,
754                                                        left_col, xd->bd);
755  } else {
756    pred_high[mode][tx_size](dst, dst_stride, const_above_row, left_col,
757                             xd->bd);
758  }
759}
760#endif  // CONFIG_VP9_HIGHBITDEPTH
761
762static void build_intra_predictors(const MACROBLOCKD *xd, const uint8_t *ref,
763                                   int ref_stride, uint8_t *dst, int dst_stride,
764                                   PREDICTION_MODE mode, TX_SIZE tx_size,
765                                   int up_available, int left_available,
766                                   int right_available, int x, int y,
767                                   int plane) {
768  int i;
769  DECLARE_ALIGNED_ARRAY(16, uint8_t, left_col, 64);
770  DECLARE_ALIGNED_ARRAY(16, uint8_t, above_data, 128 + 16);
771  uint8_t *above_row = above_data + 16;
772  const uint8_t *const_above_row = above_row;
773  const int bs = 4 << tx_size;
774  int frame_width, frame_height;
775  int x0, y0;
776  const struct macroblockd_plane *const pd = &xd->plane[plane];
777
778  // 127 127 127 .. 127 127 127 127 127 127
779  // 129  A   B  ..  Y   Z
780  // 129  C   D  ..  W   X
781  // 129  E   F  ..  U   V
782  // 129  G   H  ..  S   T   T   T   T   T
783  // ..
784
785  // Get current frame pointer, width and height.
786  if (plane == 0) {
787    frame_width = xd->cur_buf->y_width;
788    frame_height = xd->cur_buf->y_height;
789  } else {
790    frame_width = xd->cur_buf->uv_width;
791    frame_height = xd->cur_buf->uv_height;
792  }
793
794  // Get block position in current frame.
795  x0 = (-xd->mb_to_left_edge >> (3 + pd->subsampling_x)) + x;
796  y0 = (-xd->mb_to_top_edge >> (3 + pd->subsampling_y)) + y;
797
798  vpx_memset(left_col, 129, 64);
799
800  // left
801  if (left_available) {
802    if (xd->mb_to_bottom_edge < 0) {
803      /* slower path if the block needs border extension */
804      if (y0 + bs <= frame_height) {
805        for (i = 0; i < bs; ++i)
806          left_col[i] = ref[i * ref_stride - 1];
807      } else {
808        const int extend_bottom = frame_height - y0;
809        for (i = 0; i < extend_bottom; ++i)
810          left_col[i] = ref[i * ref_stride - 1];
811        for (; i < bs; ++i)
812          left_col[i] = ref[(extend_bottom - 1) * ref_stride - 1];
813      }
814    } else {
815      /* faster path if the block does not need extension */
816      for (i = 0; i < bs; ++i)
817        left_col[i] = ref[i * ref_stride - 1];
818    }
819  }
820
821  // TODO(hkuang) do not extend 2*bs pixels for all modes.
822  // above
823  if (up_available) {
824    const uint8_t *above_ref = ref - ref_stride;
825    if (xd->mb_to_right_edge < 0) {
826      /* slower path if the block needs border extension */
827      if (x0 + 2 * bs <= frame_width) {
828        if (right_available && bs == 4) {
829          vpx_memcpy(above_row, above_ref, 2 * bs);
830        } else {
831          vpx_memcpy(above_row, above_ref, bs);
832          vpx_memset(above_row + bs, above_row[bs - 1], bs);
833        }
834      } else if (x0 + bs <= frame_width) {
835        const int r = frame_width - x0;
836        if (right_available && bs == 4) {
837          vpx_memcpy(above_row, above_ref, r);
838          vpx_memset(above_row + r, above_row[r - 1],
839                     x0 + 2 * bs - frame_width);
840        } else {
841          vpx_memcpy(above_row, above_ref, bs);
842          vpx_memset(above_row + bs, above_row[bs - 1], bs);
843        }
844      } else if (x0 <= frame_width) {
845        const int r = frame_width - x0;
846        if (right_available && bs == 4) {
847          vpx_memcpy(above_row, above_ref, r);
848          vpx_memset(above_row + r, above_row[r - 1],
849                     x0 + 2 * bs - frame_width);
850        } else {
851          vpx_memcpy(above_row, above_ref, r);
852          vpx_memset(above_row + r, above_row[r - 1],
853                     x0 + 2 * bs - frame_width);
854        }
855      }
856      above_row[-1] = left_available ? above_ref[-1] : 129;
857    } else {
858      /* faster path if the block does not need extension */
859      if (bs == 4 && right_available && left_available) {
860        const_above_row = above_ref;
861      } else {
862        vpx_memcpy(above_row, above_ref, bs);
863        if (bs == 4 && right_available)
864          vpx_memcpy(above_row + bs, above_ref + bs, bs);
865        else
866          vpx_memset(above_row + bs, above_row[bs - 1], bs);
867        above_row[-1] = left_available ? above_ref[-1] : 129;
868      }
869    }
870  } else {
871    vpx_memset(above_row, 127, bs * 2);
872    above_row[-1] = 127;
873  }
874
875  // predict
876  if (mode == DC_PRED) {
877    dc_pred[left_available][up_available][tx_size](dst, dst_stride,
878                                                   const_above_row, left_col);
879  } else {
880    pred[mode][tx_size](dst, dst_stride, const_above_row, left_col);
881  }
882}
883
884void vp9_predict_intra_block(const MACROBLOCKD *xd, int block_idx, int bwl_in,
885                             TX_SIZE tx_size, PREDICTION_MODE mode,
886                             const uint8_t *ref, int ref_stride,
887                             uint8_t *dst, int dst_stride,
888                             int aoff, int loff, int plane) {
889  const int bwl = bwl_in - tx_size;
890  const int wmask = (1 << bwl) - 1;
891  const int have_top = (block_idx >> bwl) || xd->up_available;
892  const int have_left = (block_idx & wmask) || xd->left_available;
893  const int have_right = ((block_idx & wmask) != wmask);
894  const int x = aoff * 4;
895  const int y = loff * 4;
896
897  assert(bwl >= 0);
898#if CONFIG_VP9_HIGHBITDEPTH
899  if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
900    build_intra_predictors_high(xd, ref, ref_stride, dst, dst_stride, mode,
901                                tx_size, have_top, have_left, have_right,
902                                x, y, plane, xd->bd);
903    return;
904  }
905#endif
906  build_intra_predictors(xd, ref, ref_stride, dst, dst_stride, mode, tx_size,
907                         have_top, have_left, have_right, x, y, plane);
908}
909