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