16fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org/*
26fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
36fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org *
46fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org *  Use of this source code is governed by a BSD-style license
56fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org *  that can be found in the LICENSE file in the root of the source
66fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org *  tree. An additional intellectual property rights grant can be found
76fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org *  in the file PATENTS.  All contributing project authors may
86fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org *  be found in the AUTHORS file in the root of the source tree.
96fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org */
106fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
11d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org#include "./vpx_config.h"
1253a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org
1353a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org#include "vpx_mem/vpx_mem.h"
1453a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org#include "vpx_ports/vpx_once.h"
1553a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org
16ecee051929d6ced19cf324688774acccc9ad4a0ajohannkoenig@chromium.org#include "./vp9_rtcd.h"
1753a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org
186fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include "vp9/common/vp9_reconintra.h"
1910a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org#include "vp9/common/vp9_onyxc_int.h"
206fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
2193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgconst TX_TYPE intra_mode_to_tx_type_lookup[INTRA_MODES] = {
2293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  DCT_DCT,    // DC
2393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  ADST_DCT,   // V
2493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  DCT_ADST,   // H
2593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  DCT_DCT,    // D45
2693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  ADST_ADST,  // D135
2793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  ADST_DCT,   // D117
2893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  DCT_ADST,   // D153
2993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  DCT_ADST,   // D207
3093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  ADST_DCT,   // D63
3193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  ADST_ADST,  // TM
3247265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org};
3347265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org
347765c078fa920ba6c949c15f16b6cc979d8bb95bjohannkoenig@chromium.org// This serves as a wrapper function, so that all the prediction functions
357765c078fa920ba6c949c15f16b6cc979d8bb95bjohannkoenig@chromium.org// can be unified and accessed as a pointer array. Note that the boundary
367765c078fa920ba6c949c15f16b6cc979d8bb95bjohannkoenig@chromium.org// above and left are not necessarily used all the time.
3747265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org#define intra_pred_sized(type, size) \
3853a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org  void vp9_##type##_predictor_##size##x##size##_c(uint8_t *dst, \
3953a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org                                                  ptrdiff_t stride, \
4053a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org                                                  const uint8_t *above, \
4153a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org                                                  const uint8_t *left) { \
4253a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org    type##_predictor(dst, stride, size, above, left); \
4353a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org  }
4453a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org
4547265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org#define intra_pred_allsizes(type) \
4647265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  intra_pred_sized(type, 4) \
4747265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  intra_pred_sized(type, 8) \
4847265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  intra_pred_sized(type, 16) \
4947265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  intra_pred_sized(type, 32)
5047265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org
5153a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.orgstatic INLINE void d207_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
5253a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org                                  const uint8_t *above, const uint8_t *left) {
531958a6b43506c5fdf713554177fdd12c3b255c54johannkoenig@chromium.org  int r, c;
547765c078fa920ba6c949c15f16b6cc979d8bb95bjohannkoenig@chromium.org  (void) above;
5510a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org  // first column
5653a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org  for (r = 0; r < bs - 1; ++r)
5753a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org    dst[r * stride] = ROUND_POWER_OF_TWO(left[r] + left[r + 1], 1);
5853a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org  dst[(bs - 1) * stride] = left[bs - 1];
5953a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org  dst++;
6053a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org
6110a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org  // second column
6253a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org  for (r = 0; r < bs - 2; ++r)
6353a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org    dst[r * stride] = ROUND_POWER_OF_TWO(left[r] + left[r + 1] * 2 +
6453a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org                                         left[r + 2], 2);
6553a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org  dst[(bs - 2) * stride] = ROUND_POWER_OF_TWO(left[bs - 2] +
6653a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org                                              left[bs - 1] * 3, 2);
6753a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org  dst[(bs - 1) * stride] = left[bs - 1];
6853a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org  dst++;
691958a6b43506c5fdf713554177fdd12c3b255c54johannkoenig@chromium.org
7010a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org  // rest of last row
7153a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org  for (c = 0; c < bs - 2; ++c)
7253a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org    dst[(bs - 1) * stride + c] = left[bs - 1];
731958a6b43506c5fdf713554177fdd12c3b255c54johannkoenig@chromium.org
7453a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org  for (r = bs - 2; r >= 0; --r)
7553a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org    for (c = 0; c < bs - 2; ++c)
7653a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org      dst[r * stride + c] = dst[(r + 1) * stride + c - 2];
776fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}
7853a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.orgintra_pred_allsizes(d207)
796fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
8053a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.orgstatic INLINE void d63_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
8153a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org                                 const uint8_t *above, const uint8_t *left) {
821958a6b43506c5fdf713554177fdd12c3b255c54johannkoenig@chromium.org  int r, c;
837765c078fa920ba6c949c15f16b6cc979d8bb95bjohannkoenig@chromium.org  (void) left;
8447265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  for (r = 0; r < bs; ++r) {
8553a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org    for (c = 0; c < bs; ++c)
8653a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org      dst[c] = r & 1 ? ROUND_POWER_OF_TWO(above[r/2 + c] +
8753a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org                                          above[r/2 + c + 1] * 2 +
8853a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org                                          above[r/2 + c + 2], 2)
8953a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org                     : ROUND_POWER_OF_TWO(above[r/2 + c] +
9053a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org                                          above[r/2 + c + 1], 1);
9153a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org    dst += stride;
926fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
936fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}
9447265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.orgintra_pred_allsizes(d63)
956fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
9653a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.orgstatic INLINE void d45_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
9753a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org                                 const uint8_t *above, const uint8_t *left) {
986fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  int r, c;
997765c078fa920ba6c949c15f16b6cc979d8bb95bjohannkoenig@chromium.org  (void) left;
10047265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  for (r = 0; r < bs; ++r) {
10153a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org    for (c = 0; c < bs; ++c)
10253a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org      dst[c] = r + c + 2 < bs * 2 ?  ROUND_POWER_OF_TWO(above[r + c] +
10353a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org                                                        above[r + c + 1] * 2 +
10453a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org                                                        above[r + c + 2], 2)
10553a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org                                  : above[bs * 2 - 1];
10653a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org    dst += stride;
1076fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
1086fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}
10947265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.orgintra_pred_allsizes(d45)
1106fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
11153a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.orgstatic INLINE void d117_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
11253a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org                                  const uint8_t *above, const uint8_t *left) {
1136fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  int r, c;
11453a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org
11510a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org  // first row
11647265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  for (c = 0; c < bs; c++)
11753a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org    dst[c] = ROUND_POWER_OF_TWO(above[c - 1] + above[c], 1);
11853a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org  dst += stride;
11910a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org
12010a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org  // second row
12153a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org  dst[0] = ROUND_POWER_OF_TWO(left[0] + above[-1] * 2 + above[0], 2);
12247265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  for (c = 1; c < bs; c++)
12353a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org    dst[c] = ROUND_POWER_OF_TWO(above[c - 2] + above[c - 1] * 2 + above[c], 2);
12453a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org  dst += stride;
12510a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org
12610a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org  // the rest of first col
12753a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org  dst[0] = ROUND_POWER_OF_TWO(above[-1] + left[0] * 2 + left[1], 2);
12847265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  for (r = 3; r < bs; ++r)
12953a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org    dst[(r - 2) * stride] = ROUND_POWER_OF_TWO(left[r - 3] + left[r - 2] * 2 +
13053a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org                                               left[r - 1], 2);
13153a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org
13210a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org  // the rest of the block
13347265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  for (r = 2; r < bs; ++r) {
13447265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org    for (c = 1; c < bs; c++)
13553a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org      dst[c] = dst[-2 * stride + c - 1];
13653a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org    dst += stride;
1376fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
1386fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}
13947265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.orgintra_pred_allsizes(d117)
14047265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org
14153a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.orgstatic INLINE void d135_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
14253a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org                                  const uint8_t *above, const uint8_t *left) {
14347265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  int r, c;
14453a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org  dst[0] = ROUND_POWER_OF_TWO(left[0] + above[-1] * 2 + above[0], 2);
14547265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  for (c = 1; c < bs; c++)
14653a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org    dst[c] = ROUND_POWER_OF_TWO(above[c - 2] + above[c - 1] * 2 + above[c], 2);
14747265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org
14853a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org  dst[stride] = ROUND_POWER_OF_TWO(above[-1] + left[0] * 2 + left[1], 2);
14947265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  for (r = 2; r < bs; ++r)
15053a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org    dst[r * stride] = ROUND_POWER_OF_TWO(left[r - 2] + left[r - 1] * 2 +
15153a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org                                         left[r], 2);
1526fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
15353a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org  dst += stride;
15447265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  for (r = 1; r < bs; ++r) {
15547265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org    for (c = 1; c < bs; c++)
15653a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org      dst[c] = dst[-stride + c - 1];
15753a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org    dst += stride;
15847265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  }
15947265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org}
16047265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.orgintra_pred_allsizes(d135)
16110a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org
16253a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.orgstatic INLINE void d153_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
16353a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org                                  const uint8_t *above, const uint8_t *left) {
1646fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  int r, c;
16553a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org  dst[0] = ROUND_POWER_OF_TWO(above[-1] + left[0], 1);
16647265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  for (r = 1; r < bs; r++)
16753a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org    dst[r * stride] = ROUND_POWER_OF_TWO(left[r - 1] + left[r], 1);
16853a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org  dst++;
16953a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org
17053a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org  dst[0] = ROUND_POWER_OF_TWO(left[0] + above[-1] * 2 + above[0], 2);
17153a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org  dst[stride] = ROUND_POWER_OF_TWO(above[-1] + left[0] * 2 + left[1], 2);
17247265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  for (r = 2; r < bs; r++)
17353a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org    dst[r * stride] = ROUND_POWER_OF_TWO(left[r - 2] + left[r - 1] * 2 +
17453a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org                                         left[r], 2);
17553a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org  dst++;
17647265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org
17747265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  for (c = 0; c < bs - 2; c++)
17853a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org    dst[c] = ROUND_POWER_OF_TWO(above[c - 1] + above[c] * 2 + above[c + 1], 2);
17953a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org  dst += stride;
18053a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org
18147265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  for (r = 1; r < bs; ++r) {
18247265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org    for (c = 0; c < bs - 2; c++)
18353a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org      dst[c] = dst[-stride + c - 2];
18453a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org    dst += stride;
18547265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  }
18647265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org}
18747265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.orgintra_pred_allsizes(d153)
18847265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org
18953a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.orgstatic INLINE void v_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
19053a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org                               const uint8_t *above, const uint8_t *left) {
19147265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  int r;
1927765c078fa920ba6c949c15f16b6cc979d8bb95bjohannkoenig@chromium.org  (void) left;
19347265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org
19447265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  for (r = 0; r < bs; r++) {
19553a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org    vpx_memcpy(dst, above, bs);
19653a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org    dst += stride;
1976fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
1986fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}
19947265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.orgintra_pred_allsizes(v)
2006fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
20153a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.orgstatic INLINE void h_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
20253a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org                               const uint8_t *above, const uint8_t *left) {
20347265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  int r;
2047765c078fa920ba6c949c15f16b6cc979d8bb95bjohannkoenig@chromium.org  (void) above;
20547265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org
20647265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  for (r = 0; r < bs; r++) {
20753a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org    vpx_memset(dst, left[r], bs);
20853a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org    dst += stride;
20947265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  }
21047265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org}
21147265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.orgintra_pred_allsizes(h)
21247265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org
21353a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.orgstatic INLINE void tm_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
21453a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org                                const uint8_t *above, const uint8_t *left) {
2156fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  int r, c;
21653a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org  int ytop_left = above[-1];
21747265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org
21847265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  for (r = 0; r < bs; r++) {
21947265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org    for (c = 0; c < bs; c++)
22053a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org      dst[c] = clip_pixel(left[r] + above[c] - ytop_left);
22153a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org    dst += stride;
22247265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  }
22347265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org}
22447265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.orgintra_pred_allsizes(tm)
22547265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org
22653a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.orgstatic INLINE void dc_128_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
22753a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org                                    const uint8_t *above, const uint8_t *left) {
22847265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  int r;
2297765c078fa920ba6c949c15f16b6cc979d8bb95bjohannkoenig@chromium.org  (void) above;
2307765c078fa920ba6c949c15f16b6cc979d8bb95bjohannkoenig@chromium.org  (void) left;
23147265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org
23247265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  for (r = 0; r < bs; r++) {
23353a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org    vpx_memset(dst, 128, bs);
23453a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org    dst += stride;
23547265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  }
23647265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org}
23747265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.orgintra_pred_allsizes(dc_128)
23847265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org
23953a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.orgstatic INLINE void dc_left_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
24053a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org                                     const uint8_t *above,
24153a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org                                     const uint8_t *left) {
24253a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org  int i, r, expected_dc, sum = 0;
2437765c078fa920ba6c949c15f16b6cc979d8bb95bjohannkoenig@chromium.org  (void) above;
24447265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org
24547265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  for (i = 0; i < bs; i++)
24653a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org    sum += left[i];
24753a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org  expected_dc = (sum + (bs >> 1)) / bs;
24847265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org
24947265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  for (r = 0; r < bs; r++) {
25053a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org    vpx_memset(dst, expected_dc, bs);
25153a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org    dst += stride;
25247265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  }
25347265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org}
25447265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.orgintra_pred_allsizes(dc_left)
25547265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org
25653a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.orgstatic INLINE void dc_top_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
25753a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org                                    const uint8_t *above, const uint8_t *left) {
25853a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org  int i, r, expected_dc, sum = 0;
2597765c078fa920ba6c949c15f16b6cc979d8bb95bjohannkoenig@chromium.org  (void) left;
26047265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org
26147265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  for (i = 0; i < bs; i++)
26253a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org    sum += above[i];
26353a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org  expected_dc = (sum + (bs >> 1)) / bs;
26447265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org
26547265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  for (r = 0; r < bs; r++) {
26653a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org    vpx_memset(dst, expected_dc, bs);
26753a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org    dst += stride;
26847265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  }
26947265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org}
27047265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.orgintra_pred_allsizes(dc_top)
27147265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org
27253a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.orgstatic INLINE void dc_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
27353a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org                                const uint8_t *above, const uint8_t *left) {
27453a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org  int i, r, expected_dc, sum = 0;
27547265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  const int count = 2 * bs;
27647265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org
27753a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org  for (i = 0; i < bs; i++) {
27853a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org    sum += above[i];
27953a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org    sum += left[i];
28053a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org  }
28153a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org
28253a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org  expected_dc = (sum + (count >> 1)) / count;
28347265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org
28447265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  for (r = 0; r < bs; r++) {
28553a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org    vpx_memset(dst, expected_dc, bs);
28653a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org    dst += stride;
2876fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
2886fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}
28947265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.orgintra_pred_allsizes(dc)
29047265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org#undef intra_pred_allsizes
29147265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org
29253a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.orgtypedef void (*intra_pred_fn)(uint8_t *dst, ptrdiff_t stride,
29353a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org                              const uint8_t *above, const uint8_t *left);
29447265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org
29553a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.orgstatic intra_pred_fn pred[INTRA_MODES][4];
29647265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.orgstatic intra_pred_fn dc_pred[2][2][4];
29747265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org
29847265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.orgstatic void init_intra_pred_fn_ptrs(void) {
29947265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org#define intra_pred_allsizes(l, type) \
30047265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  l[0] = vp9_##type##_predictor_4x4; \
30147265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  l[1] = vp9_##type##_predictor_8x8; \
30247265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  l[2] = vp9_##type##_predictor_16x16; \
30347265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  l[3] = vp9_##type##_predictor_32x32
30447265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org
30547265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  intra_pred_allsizes(pred[V_PRED], v);
30647265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  intra_pred_allsizes(pred[H_PRED], h);
30753a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org  intra_pred_allsizes(pred[D207_PRED], d207);
30847265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  intra_pred_allsizes(pred[D45_PRED], d45);
30947265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  intra_pred_allsizes(pred[D63_PRED], d63);
31047265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  intra_pred_allsizes(pred[D117_PRED], d117);
31147265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  intra_pred_allsizes(pred[D135_PRED], d135);
31247265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  intra_pred_allsizes(pred[D153_PRED], d153);
31347265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  intra_pred_allsizes(pred[TM_PRED], tm);
31447265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org
31547265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  intra_pred_allsizes(dc_pred[0][0], dc_128);
31647265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  intra_pred_allsizes(dc_pred[0][1], dc_top);
31747265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  intra_pred_allsizes(dc_pred[1][0], dc_left);
31847265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  intra_pred_allsizes(dc_pred[1][1], dc);
31947265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org
32047265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org#undef intra_pred_allsizes
32147265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org}
3226fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
3238b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.orgstatic void build_intra_predictors(const MACROBLOCKD *xd, const uint8_t *ref,
3248b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org                                   int ref_stride, uint8_t *dst, int dst_stride,
325693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com                                   PREDICTION_MODE mode, TX_SIZE tx_size,
32647265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org                                   int up_available, int left_available,
3278b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org                                   int right_available, int x, int y,
3288b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org                                   int plane) {
32947265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  int i;
33047265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  DECLARE_ALIGNED_ARRAY(16, uint8_t, left_col, 64);
33153a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org  DECLARE_ALIGNED_ARRAY(16, uint8_t, above_data, 128 + 16);
33253a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org  uint8_t *above_row = above_data + 16;
33353a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org  const uint8_t *const_above_row = above_row;
33453a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org  const int bs = 4 << tx_size;
3358b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org  int frame_width, frame_height;
3368b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org  int x0, y0;
3378b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org  const struct macroblockd_plane *const pd = &xd->plane[plane];
33810a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org
33910a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org  // 127 127 127 .. 127 127 127 127 127 127
34010a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org  // 129  A   B  ..  Y   Z
34110a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org  // 129  C   D  ..  W   X
34210a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org  // 129  E   F  ..  U   V
34310a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org  // 129  G   H  ..  S   T   T   T   T   T
34410a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org  // ..
34510a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org
34647265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  once(init_intra_pred_fn_ptrs);
34753a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org
3488b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org  // Get current frame pointer, width and height.
3498b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org  if (plane == 0) {
3508b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org    frame_width = xd->cur_buf->y_width;
3518b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org    frame_height = xd->cur_buf->y_height;
3528b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org  } else {
3538b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org    frame_width = xd->cur_buf->uv_width;
3548b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org    frame_height = xd->cur_buf->uv_height;
3558b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org  }
3568b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org
3578b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org  // Get block position in current frame.
3588b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org  x0 = (-xd->mb_to_left_edge >> (3 + pd->subsampling_x)) + x;
3598b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org  y0 = (-xd->mb_to_top_edge >> (3 + pd->subsampling_y)) + y;
3608b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org
36193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  vpx_memset(left_col, 129, 64);
36293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
36353a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org  // left
3641958a6b43506c5fdf713554177fdd12c3b255c54johannkoenig@chromium.org  if (left_available) {
3658b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org    if (xd->mb_to_bottom_edge < 0) {
3668b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org      /* slower path if the block needs border extension */
3678b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org      if (y0 + bs <= frame_height) {
3688b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org        for (i = 0; i < bs; ++i)
3698b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org          left_col[i] = ref[i * ref_stride - 1];
3708b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org      } else {
3718b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org        const int extend_bottom = frame_height - y0;
3728b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org        for (i = 0; i < extend_bottom; ++i)
3738b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org          left_col[i] = ref[i * ref_stride - 1];
3748b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org        for (; i < bs; ++i)
3758b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org          left_col[i] = ref[(extend_bottom - 1) * ref_stride - 1];
3768b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org      }
3778b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org    } else {
3788b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org      /* faster path if the block does not need extension */
3798b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org      for (i = 0; i < bs; ++i)
3808b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org        left_col[i] = ref[i * ref_stride - 1];
3818b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org    }
3821958a6b43506c5fdf713554177fdd12c3b255c54johannkoenig@chromium.org  }
3836fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
3848b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org  // TODO(hkuang) do not extend 2*bs pixels for all modes.
38553a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org  // above
3861958a6b43506c5fdf713554177fdd12c3b255c54johannkoenig@chromium.org  if (up_available) {
38753a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org    const uint8_t *above_ref = ref - ref_stride;
3888b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org    if (xd->mb_to_right_edge < 0) {
3898b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org      /* slower path if the block needs border extension */
3908b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org      if (x0 + 2 * bs <= frame_width) {
3918b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org        if (right_available && bs == 4) {
392411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org          vpx_memcpy(above_row, above_ref, 2 * bs);
3938b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org        } else {
394411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org          vpx_memcpy(above_row, above_ref, bs);
3958b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org          vpx_memset(above_row + bs, above_row[bs - 1], bs);
3968b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org        }
3978b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org      } else if (x0 + bs <= frame_width) {
3988b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org        const int r = frame_width - x0;
3998b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org        if (right_available && bs == 4) {
400411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org          vpx_memcpy(above_row, above_ref, r);
4018b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org          vpx_memset(above_row + r, above_row[r - 1],
4028b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org                     x0 + 2 * bs - frame_width);
4038b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org        } else {
404411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org          vpx_memcpy(above_row, above_ref, bs);
4058b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org          vpx_memset(above_row + bs, above_row[bs - 1], bs);
4068b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org        }
4078b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org      } else if (x0 <= frame_width) {
4088b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org        const int r = frame_width - x0;
4098b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org        if (right_available && bs == 4) {
410411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org          vpx_memcpy(above_row, above_ref, r);
4118b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org          vpx_memset(above_row + r, above_row[r - 1],
4128b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org                     x0 + 2 * bs - frame_width);
4138b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org        } else {
414411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org          vpx_memcpy(above_row, above_ref, r);
4158b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org          vpx_memset(above_row + r, above_row[r - 1],
4168b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org                     x0 + 2 * bs - frame_width);
4178b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org        }
4188b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org      }
419411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org      above_row[-1] = left_available ? above_ref[-1] : 129;
42047265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org    } else {
4218b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org      /* faster path if the block does not need extension */
4228b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org      if (bs == 4 && right_available && left_available) {
4238b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org        const_above_row = above_ref;
4248b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org      } else {
4258b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org        vpx_memcpy(above_row, above_ref, bs);
4268b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org        if (bs == 4 && right_available)
4278b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org          vpx_memcpy(above_row + bs, above_ref + bs, bs);
4288b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org        else
4298b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org          vpx_memset(above_row + bs, above_row[bs - 1], bs);
4308b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org        above_row[-1] = left_available ? above_ref[-1] : 129;
4318b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org      }
4326fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    }
43347265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  } else {
43447265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org    vpx_memset(above_row, 127, bs * 2);
43547265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org    above_row[-1] = 127;
4366fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
43710a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org
43853a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org  // predict
43947265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  if (mode == DC_PRED) {
44053a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org    dc_pred[left_available][up_available][tx_size](dst, dst_stride,
44153a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org                                                   const_above_row, left_col);
44247265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  } else {
44353a13f1fa964820f7a8f9d3932a6f3c0433f8bf5fgalligan@chromium.org    pred[mode][tx_size](dst, dst_stride, const_above_row, left_col);
44447265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org  }
44510a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org}
44610a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org
447d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.orgvoid vp9_predict_intra_block(const MACROBLOCKD *xd, int block_idx, int bwl_in,
448693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com                             TX_SIZE tx_size, PREDICTION_MODE mode,
4498b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org                             const uint8_t *ref, int ref_stride,
4508b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org                             uint8_t *dst, int dst_stride,
4518b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org                             int aoff, int loff, int plane) {
45210a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org  const int bwl = bwl_in - tx_size;
45310a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org  const int wmask = (1 << bwl) - 1;
45410a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org  const int have_top = (block_idx >> bwl) || xd->up_available;
45510a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org  const int have_left = (block_idx & wmask) || xd->left_available;
45610a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org  const int have_right = ((block_idx & wmask) != wmask);
4578b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org  const int x = aoff * 4;
4588b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org  const int y = loff * 4;
45910a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org
46010a9a0d835561a7f2300c561c514efcf374554d6fgalligan@chromium.org  assert(bwl >= 0);
4618b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org  build_intra_predictors(xd, ref, ref_stride, dst, dst_stride, mode, tx_size,
4628b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org                         have_top, have_left, have_right, x, y, plane);
4636fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}
464