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