intrapred.c 30.5 KB
Newer Older
1
/*
Yaowu Xu's avatar
Yaowu Xu committed
2
 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
3
 *
Yaowu Xu's avatar
Yaowu Xu committed
4 5 6 7 8 9
 * This source code is subject to the terms of the BSD 2 Clause License and
 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
 * was not distributed with this source code in the LICENSE file, you can
 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
 * Media Patent License 1.0 was not distributed with this source code in the
 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10 11
 */

Yaowu Xu's avatar
Yaowu Xu committed
12 13
#include "./aom_config.h"
#include "./aom_dsp_rtcd.h"
14

Yaowu Xu's avatar
Yaowu Xu committed
15 16
#include "aom_dsp/aom_dsp_common.h"
#include "aom_mem/aom_mem.h"
17

clang-format's avatar
clang-format committed
18
#define DST(x, y) dst[(x) + (y)*stride]
19 20 21 22 23 24
#define AVG3(a, b, c) (((a) + 2 * (b) + (c) + 2) >> 2)
#define AVG2(a, b) (((a) + (b) + 1) >> 1)

static INLINE void d207_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
                                  const uint8_t *above, const uint8_t *left) {
  int r, c;
clang-format's avatar
clang-format committed
25
  (void)above;
26
  // first column
clang-format's avatar
clang-format committed
27
  for (r = 0; r < bs - 1; ++r) dst[r * stride] = AVG2(left[r], left[r + 1]);
28 29 30 31 32 33 34 35 36 37 38
  dst[(bs - 1) * stride] = left[bs - 1];
  dst++;

  // second column
  for (r = 0; r < bs - 2; ++r)
    dst[r * stride] = AVG3(left[r], left[r + 1], left[r + 2]);
  dst[(bs - 2) * stride] = AVG3(left[bs - 2], left[bs - 1], left[bs - 1]);
  dst[(bs - 1) * stride] = left[bs - 1];
  dst++;

  // rest of last row
clang-format's avatar
clang-format committed
39
  for (c = 0; c < bs - 2; ++c) dst[(bs - 1) * stride + c] = left[bs - 1];
40 41 42 43 44 45

  for (r = bs - 2; r >= 0; --r)
    for (c = 0; c < bs - 2; ++c)
      dst[r * stride + c] = dst[(r + 1) * stride + c - 2];
}

46 47 48
static INLINE void d207e_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
                                   const uint8_t *above, const uint8_t *left) {
  int r, c;
clang-format's avatar
clang-format committed
49
  (void)above;
50 51 52 53 54

  for (r = 0; r < bs; ++r) {
    for (c = 0; c < bs; ++c) {
      dst[c] = c & 1 ? AVG3(left[(c >> 1) + r], left[(c >> 1) + r + 1],
                            left[(c >> 1) + r + 2])
clang-format's avatar
clang-format committed
55
                     : AVG2(left[(c >> 1) + r], left[(c >> 1) + r + 1]);
56 57 58 59 60
    }
    dst += stride;
  }
}

61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
static INLINE void d63_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
                                 const uint8_t *above, const uint8_t *left) {
  int r, c;
  int size;
  (void)left;
  for (c = 0; c < bs; ++c) {
    dst[c] = AVG2(above[c], above[c + 1]);
    dst[stride + c] = AVG3(above[c], above[c + 1], above[c + 2]);
  }
  for (r = 2, size = bs - 2; r < bs; r += 2, --size) {
    memcpy(dst + (r + 0) * stride, dst + (r >> 1), size);
    memset(dst + (r + 0) * stride + size, above[bs - 1], bs - size);
    memcpy(dst + (r + 1) * stride, dst + stride + (r >> 1), size);
    memset(dst + (r + 1) * stride + size, above[bs - 1], bs - size);
  }
}

78 79 80
static INLINE void d63e_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
                                  const uint8_t *above, const uint8_t *left) {
  int r, c;
clang-format's avatar
clang-format committed
81
  (void)left;
82 83 84 85
  for (r = 0; r < bs; ++r) {
    for (c = 0; c < bs; ++c) {
      dst[c] = r & 1 ? AVG3(above[(r >> 1) + c], above[(r >> 1) + c + 1],
                            above[(r >> 1) + c + 2])
clang-format's avatar
clang-format committed
86
                     : AVG2(above[(r >> 1) + c], above[(r >> 1) + c + 1]);
87 88 89 90 91
    }
    dst += stride;
  }
}

92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
static INLINE void d45_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
                                 const uint8_t *above, const uint8_t *left) {
  const uint8_t above_right = above[bs - 1];
  const uint8_t *const dst_row0 = dst;
  int x, size;
  (void)left;

  for (x = 0; x < bs - 1; ++x) {
    dst[x] = AVG3(above[x], above[x + 1], above[x + 2]);
  }
  dst[bs - 1] = above_right;
  dst += stride;
  for (x = 1, size = bs - 2; x < bs; ++x, --size) {
    memcpy(dst, dst_row0 + x, size);
    memset(dst + size, above_right, x + 1);
    dst += stride;
  }
}

111 112 113
static INLINE void d45e_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
                                  const uint8_t *above, const uint8_t *left) {
  int r, c;
clang-format's avatar
clang-format committed
114
  (void)left;
115 116 117 118 119 120 121 122 123
  for (r = 0; r < bs; ++r) {
    for (c = 0; c < bs; ++c) {
      dst[c] = AVG3(above[r + c], above[r + c + 1],
                    above[r + c + 1 + (r + c + 2 < bs * 2)]);
    }
    dst += stride;
  }
}

124 125 126 127 128
static INLINE void d117_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
                                  const uint8_t *above, const uint8_t *left) {
  int r, c;

  // first row
clang-format's avatar
clang-format committed
129
  for (c = 0; c < bs; c++) dst[c] = AVG2(above[c - 1], above[c]);
130 131 132 133
  dst += stride;

  // second row
  dst[0] = AVG3(left[0], above[-1], above[0]);
clang-format's avatar
clang-format committed
134
  for (c = 1; c < bs; c++) dst[c] = AVG3(above[c - 2], above[c - 1], above[c]);
135 136 137 138 139 140 141 142 143
  dst += stride;

  // the rest of first col
  dst[0] = AVG3(above[-1], left[0], left[1]);
  for (r = 3; r < bs; ++r)
    dst[(r - 2) * stride] = AVG3(left[r - 3], left[r - 2], left[r - 1]);

  // the rest of the block
  for (r = 2; r < bs; ++r) {
clang-format's avatar
clang-format committed
144
    for (c = 1; c < bs; c++) dst[c] = dst[-2 * stride + c - 1];
145 146 147 148 149 150
    dst += stride;
  }
}

static INLINE void d135_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
                                  const uint8_t *above, const uint8_t *left) {
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
  int i;
#if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ > 7
  // silence a spurious -Warray-bounds warning, possibly related to:
  // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56273
  uint8_t border[69];
#else
  uint8_t border[32 + 32 - 1];  // outer border from bottom-left to top-right
#endif

  // dst(bs, bs - 2)[0], i.e., border starting at bottom-left
  for (i = 0; i < bs - 2; ++i) {
    border[i] = AVG3(left[bs - 3 - i], left[bs - 2 - i], left[bs - 1 - i]);
  }
  border[bs - 2] = AVG3(above[-1], left[0], left[1]);
  border[bs - 1] = AVG3(left[0], above[-1], above[0]);
  border[bs - 0] = AVG3(above[-1], above[0], above[1]);
  // dst[0][2, size), i.e., remaining top border ascending
  for (i = 0; i < bs - 2; ++i) {
    border[bs + 1 + i] = AVG3(above[i], above[i + 1], above[i + 2]);
  }
171

172 173
  for (i = 0; i < bs; ++i) {
    memcpy(dst + i * stride, border + bs - 1 - i, bs);
174 175 176 177 178 179 180
  }
}

static INLINE void d153_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
                                  const uint8_t *above, const uint8_t *left) {
  int r, c;
  dst[0] = AVG2(above[-1], left[0]);
clang-format's avatar
clang-format committed
181
  for (r = 1; r < bs; r++) dst[r * stride] = AVG2(left[r - 1], left[r]);
182 183 184 185 186 187 188 189 190 191 192 193 194
  dst++;

  dst[0] = AVG3(left[0], above[-1], above[0]);
  dst[stride] = AVG3(above[-1], left[0], left[1]);
  for (r = 2; r < bs; r++)
    dst[r * stride] = AVG3(left[r - 2], left[r - 1], left[r]);
  dst++;

  for (c = 0; c < bs - 2; c++)
    dst[c] = AVG3(above[c - 1], above[c], above[c + 1]);
  dst += stride;

  for (r = 1; r < bs; ++r) {
clang-format's avatar
clang-format committed
195
    for (c = 0; c < bs - 2; c++) dst[c] = dst[-stride + c - 2];
196 197 198 199 200 201 202
    dst += stride;
  }
}

static INLINE void v_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
                               const uint8_t *above, const uint8_t *left) {
  int r;
clang-format's avatar
clang-format committed
203
  (void)left;
204 205 206 207 208 209 210 211 212 213

  for (r = 0; r < bs; r++) {
    memcpy(dst, above, bs);
    dst += stride;
  }
}

static INLINE void h_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
                               const uint8_t *above, const uint8_t *left) {
  int r;
clang-format's avatar
clang-format committed
214
  (void)above;
215 216 217 218 219 220 221

  for (r = 0; r < bs; r++) {
    memset(dst, left[r], bs);
    dst += stride;
  }
}

Urvang Joshi's avatar
Urvang Joshi committed
222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251
#if CONFIG_ALT_INTRA
static INLINE int abs_diff(int a, int b) { return (a > b) ? a - b : b - a; }

static INLINE uint16_t paeth_predictor_single(uint16_t left, uint16_t top,
                                              uint16_t top_left) {
  const int base = top + left - top_left;
  const int p_left = abs_diff(base, left);
  const int p_top = abs_diff(base, top);
  const int p_top_left = abs_diff(base, top_left);

  // Return nearest to base of left, top and top_left.
  return (p_left <= p_top && p_left <= p_top_left)
             ? left
             : (p_top <= p_top_left) ? top : top_left;
}

static INLINE void paeth_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
                                   const uint8_t *above, const uint8_t *left) {
  int r, c;
  const uint8_t ytop_left = above[-1];

  for (r = 0; r < bs; r++) {
    for (c = 0; c < bs; c++)
      dst[c] = (uint8_t)paeth_predictor_single(left[r], above[c], ytop_left);
    dst += stride;
  }
}

#else

252 253 254 255 256 257 258 259 260 261 262
static INLINE void tm_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
                                const uint8_t *above, const uint8_t *left) {
  int r, c;
  int ytop_left = above[-1];

  for (r = 0; r < bs; r++) {
    for (c = 0; c < bs; c++)
      dst[c] = clip_pixel(left[r] + above[c] - ytop_left);
    dst += stride;
  }
}
Urvang Joshi's avatar
Urvang Joshi committed
263
#endif  // CONFIG_ALT_INTRA
264 265 266 267

static INLINE void dc_128_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
                                    const uint8_t *above, const uint8_t *left) {
  int r;
clang-format's avatar
clang-format committed
268 269
  (void)above;
  (void)left;
270 271 272 273 274 275 276 277 278 279 280

  for (r = 0; r < bs; r++) {
    memset(dst, 128, bs);
    dst += stride;
  }
}

static INLINE void dc_left_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
                                     const uint8_t *above,
                                     const uint8_t *left) {
  int i, r, expected_dc, sum = 0;
clang-format's avatar
clang-format committed
281
  (void)above;
282

clang-format's avatar
clang-format committed
283
  for (i = 0; i < bs; i++) sum += left[i];
284 285 286 287 288 289 290 291 292 293 294
  expected_dc = (sum + (bs >> 1)) / bs;

  for (r = 0; r < bs; r++) {
    memset(dst, expected_dc, bs);
    dst += stride;
  }
}

static INLINE void dc_top_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
                                    const uint8_t *above, const uint8_t *left) {
  int i, r, expected_dc, sum = 0;
clang-format's avatar
clang-format committed
295
  (void)left;
296

clang-format's avatar
clang-format committed
297
  for (i = 0; i < bs; i++) sum += above[i];
298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323
  expected_dc = (sum + (bs >> 1)) / bs;

  for (r = 0; r < bs; r++) {
    memset(dst, expected_dc, bs);
    dst += stride;
  }
}

static INLINE void dc_predictor(uint8_t *dst, ptrdiff_t stride, int bs,
                                const uint8_t *above, const uint8_t *left) {
  int i, r, expected_dc, sum = 0;
  const int count = 2 * bs;

  for (i = 0; i < bs; i++) {
    sum += above[i];
    sum += left[i];
  }

  expected_dc = (sum + (count >> 1)) / count;

  for (r = 0; r < bs; r++) {
    memset(dst, expected_dc, bs);
    dst += stride;
  }
}

324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340
void aom_he_predictor_2x2_c(uint8_t *dst, ptrdiff_t stride,
                            const uint8_t *above, const uint8_t *left) {
  const int H = above[-1];
  const int I = left[0];
  const int J = left[1];
  const int K = left[2];

  memset(dst + stride * 0, AVG3(H, I, J), 2);
  memset(dst + stride * 1, AVG3(I, J, K), 2);
}

void aom_ve_predictor_2x2_c(uint8_t *dst, ptrdiff_t stride,
                            const uint8_t *above, const uint8_t *left) {
  const int H = above[-1];
  const int I = above[0];
  const int J = above[1];
  const int K = above[2];
341
  (void)left;
342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452

  dst[0] = AVG3(H, I, J);
  dst[1] = AVG3(I, J, K);
  memcpy(dst + stride * 1, dst, 2);
}

void aom_d207_predictor_2x2_c(uint8_t *dst, ptrdiff_t stride,
                              const uint8_t *above, const uint8_t *left) {
  const int I = left[0];
  const int J = left[1];
  const int K = left[2];
  const int L = left[3];
  (void)above;
  DST(0, 0) = AVG2(I, J);
  DST(0, 1) = AVG2(J, K);
  DST(1, 0) = AVG3(I, J, K);
  DST(1, 1) = AVG3(J, K, L);
}

void aom_d63_predictor_2x2_c(uint8_t *dst, ptrdiff_t stride,
                             const uint8_t *above, const uint8_t *left) {
  const int A = above[0];
  const int B = above[1];
  const int C = above[2];
  const int D = above[3];
  (void)left;
  DST(0, 0) = AVG2(A, B);
  DST(1, 0) = AVG2(B, C);
  DST(0, 1) = AVG3(A, B, C);
  DST(1, 1) = AVG3(B, C, D);
}

void aom_d63f_predictor_2x2_c(uint8_t *dst, ptrdiff_t stride,
                              const uint8_t *above, const uint8_t *left) {
  const int A = above[0];
  const int B = above[1];
  const int C = above[2];
  const int D = above[3];
  (void)left;
  DST(0, 0) = AVG2(A, B);
  DST(1, 0) = AVG2(B, C);
  DST(0, 1) = AVG3(A, B, C);
  DST(1, 1) = AVG3(B, C, D);
}

void aom_d45_predictor_2x2_c(uint8_t *dst, ptrdiff_t stride,
                             const uint8_t *above, const uint8_t *left) {
  const int A = above[0];
  const int B = above[1];
  const int C = above[2];
  const int D = above[3];
  const int E = above[4];
  (void)stride;
  (void)left;
  DST(0, 0) = AVG3(A, B, C);
  DST(1, 0) = DST(0, 1) = AVG3(B, C, D);
  DST(1, 1) = AVG3(C, D, E);
}

void aom_d45e_predictor_2x2_c(uint8_t *dst, ptrdiff_t stride,
                              const uint8_t *above, const uint8_t *left) {
  const int A = above[0];
  const int B = above[1];
  const int C = above[2];
  const int D = above[3];
  const int E = above[4];
  (void)stride;
  (void)left;
  DST(0, 0) = AVG3(A, B, C);
  DST(1, 0) = DST(0, 1) = AVG3(B, C, D);
  DST(1, 1) = AVG3(C, D, E);
}

void aom_d117_predictor_2x2_c(uint8_t *dst, ptrdiff_t stride,
                              const uint8_t *above, const uint8_t *left) {
  const int I = left[0];
  const int X = above[-1];
  const int A = above[0];
  const int B = above[1];
  DST(0, 0) = AVG2(X, A);
  DST(1, 0) = AVG2(A, B);
  DST(0, 1) = AVG3(I, X, A);
  DST(1, 1) = AVG3(X, A, B);
}

void aom_d135_predictor_2x2_c(uint8_t *dst, ptrdiff_t stride,
                              const uint8_t *above, const uint8_t *left) {
  const int I = left[0];
  const int J = left[1];
  const int X = above[-1];
  const int A = above[0];
  const int B = above[1];
  (void)stride;
  DST(0, 1) = AVG3(X, I, J);
  DST(1, 1) = DST(0, 0) = AVG3(A, X, I);
  DST(1, 0) = AVG3(B, A, X);
}

void aom_d153_predictor_2x2_c(uint8_t *dst, ptrdiff_t stride,
                              const uint8_t *above, const uint8_t *left) {
  const int I = left[0];
  const int J = left[1];
  const int X = above[-1];
  const int A = above[0];

  DST(0, 0) = AVG2(I, X);
  DST(0, 1) = AVG2(J, I);
  DST(1, 0) = AVG3(I, X, A);
  DST(1, 1) = AVG3(J, I, X);
}

Yaowu Xu's avatar
Yaowu Xu committed
453
void aom_he_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride,
454 455 456 457 458 459 460 461 462 463 464 465 466
                            const uint8_t *above, const uint8_t *left) {
  const int H = above[-1];
  const int I = left[0];
  const int J = left[1];
  const int K = left[2];
  const int L = left[3];

  memset(dst + stride * 0, AVG3(H, I, J), 4);
  memset(dst + stride * 1, AVG3(I, J, K), 4);
  memset(dst + stride * 2, AVG3(J, K, L), 4);
  memset(dst + stride * 3, AVG3(K, L, L), 4);
}

Yaowu Xu's avatar
Yaowu Xu committed
467
void aom_ve_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride,
468 469 470 471 472 473 474
                            const uint8_t *above, const uint8_t *left) {
  const int H = above[-1];
  const int I = above[0];
  const int J = above[1];
  const int K = above[2];
  const int L = above[3];
  const int M = above[4];
475
  (void)left;
476 477 478 479 480 481 482 483 484 485

  dst[0] = AVG3(H, I, J);
  dst[1] = AVG3(I, J, K);
  dst[2] = AVG3(J, K, L);
  dst[3] = AVG3(K, L, M);
  memcpy(dst + stride * 1, dst, 4);
  memcpy(dst + stride * 2, dst, 4);
  memcpy(dst + stride * 3, dst, 4);
}

Yaowu Xu's avatar
Yaowu Xu committed
486
void aom_d207_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride,
487 488 489 490 491 492
                              const uint8_t *above, const uint8_t *left) {
  const int I = left[0];
  const int J = left[1];
  const int K = left[2];
  const int L = left[3];
  (void)above;
clang-format's avatar
clang-format committed
493
  DST(0, 0) = AVG2(I, J);
494 495
  DST(2, 0) = DST(0, 1) = AVG2(J, K);
  DST(2, 1) = DST(0, 2) = AVG2(K, L);
clang-format's avatar
clang-format committed
496
  DST(1, 0) = AVG3(I, J, K);
497 498
  DST(3, 0) = DST(1, 1) = AVG3(J, K, L);
  DST(3, 1) = DST(1, 2) = AVG3(K, L, L);
clang-format's avatar
clang-format committed
499
  DST(3, 2) = DST(2, 2) = DST(0, 3) = DST(1, 3) = DST(2, 3) = DST(3, 3) = L;
500 501
}

Yaowu Xu's avatar
Yaowu Xu committed
502
void aom_d63_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride,
503 504 505 506 507 508 509 510 511
                             const uint8_t *above, const uint8_t *left) {
  const int A = above[0];
  const int B = above[1];
  const int C = above[2];
  const int D = above[3];
  const int E = above[4];
  const int F = above[5];
  const int G = above[6];
  (void)left;
clang-format's avatar
clang-format committed
512
  DST(0, 0) = AVG2(A, B);
513 514 515
  DST(1, 0) = DST(0, 2) = AVG2(B, C);
  DST(2, 0) = DST(1, 2) = AVG2(C, D);
  DST(3, 0) = DST(2, 2) = AVG2(D, E);
clang-format's avatar
clang-format committed
516
  DST(3, 2) = AVG2(E, F);  // differs from vp8
517

clang-format's avatar
clang-format committed
518
  DST(0, 1) = AVG3(A, B, C);
519 520 521
  DST(1, 1) = DST(0, 3) = AVG3(B, C, D);
  DST(2, 1) = DST(1, 3) = AVG3(C, D, E);
  DST(3, 1) = DST(2, 3) = AVG3(D, E, F);
clang-format's avatar
clang-format committed
522
  DST(3, 3) = AVG3(E, F, G);  // differs from vp8
523 524
}

Yaowu Xu's avatar
Yaowu Xu committed
525
void aom_d63f_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride,
526 527 528 529 530 531 532 533 534 535
                              const uint8_t *above, const uint8_t *left) {
  const int A = above[0];
  const int B = above[1];
  const int C = above[2];
  const int D = above[3];
  const int E = above[4];
  const int F = above[5];
  const int G = above[6];
  const int H = above[7];
  (void)left;
clang-format's avatar
clang-format committed
536
  DST(0, 0) = AVG2(A, B);
537 538 539
  DST(1, 0) = DST(0, 2) = AVG2(B, C);
  DST(2, 0) = DST(1, 2) = AVG2(C, D);
  DST(3, 0) = DST(2, 2) = AVG2(D, E);
clang-format's avatar
clang-format committed
540
  DST(3, 2) = AVG3(E, F, G);
541

clang-format's avatar
clang-format committed
542
  DST(0, 1) = AVG3(A, B, C);
543 544 545
  DST(1, 1) = DST(0, 3) = AVG3(B, C, D);
  DST(2, 1) = DST(1, 3) = AVG3(C, D, E);
  DST(3, 1) = DST(2, 3) = AVG3(D, E, F);
clang-format's avatar
clang-format committed
546
  DST(3, 3) = AVG3(F, G, H);
547 548
}

Yaowu Xu's avatar
Yaowu Xu committed
549
void aom_d45_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride,
550 551 552 553 554 555 556 557 558 559 560
                             const uint8_t *above, const uint8_t *left) {
  const int A = above[0];
  const int B = above[1];
  const int C = above[2];
  const int D = above[3];
  const int E = above[4];
  const int F = above[5];
  const int G = above[6];
  const int H = above[7];
  (void)stride;
  (void)left;
clang-format's avatar
clang-format committed
561 562 563
  DST(0, 0) = AVG3(A, B, C);
  DST(1, 0) = DST(0, 1) = AVG3(B, C, D);
  DST(2, 0) = DST(1, 1) = DST(0, 2) = AVG3(C, D, E);
564
  DST(3, 0) = DST(2, 1) = DST(1, 2) = DST(0, 3) = AVG3(D, E, F);
clang-format's avatar
clang-format committed
565 566 567
  DST(3, 1) = DST(2, 2) = DST(1, 3) = AVG3(E, F, G);
  DST(3, 2) = DST(2, 3) = AVG3(F, G, H);
  DST(3, 3) = H;  // differs from vp8
568 569
}

Yaowu Xu's avatar
Yaowu Xu committed
570
void aom_d45e_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride,
571 572 573 574 575 576 577 578 579 580 581
                              const uint8_t *above, const uint8_t *left) {
  const int A = above[0];
  const int B = above[1];
  const int C = above[2];
  const int D = above[3];
  const int E = above[4];
  const int F = above[5];
  const int G = above[6];
  const int H = above[7];
  (void)stride;
  (void)left;
clang-format's avatar
clang-format committed
582 583 584
  DST(0, 0) = AVG3(A, B, C);
  DST(1, 0) = DST(0, 1) = AVG3(B, C, D);
  DST(2, 0) = DST(1, 1) = DST(0, 2) = AVG3(C, D, E);
585
  DST(3, 0) = DST(2, 1) = DST(1, 2) = DST(0, 3) = AVG3(D, E, F);
clang-format's avatar
clang-format committed
586 587 588
  DST(3, 1) = DST(2, 2) = DST(1, 3) = AVG3(E, F, G);
  DST(3, 2) = DST(2, 3) = AVG3(F, G, H);
  DST(3, 3) = AVG3(G, H, H);
589 590
}

Yaowu Xu's avatar
Yaowu Xu committed
591
void aom_d117_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride,
592 593 594 595 596 597 598 599 600 601 602 603
                              const uint8_t *above, const uint8_t *left) {
  const int I = left[0];
  const int J = left[1];
  const int K = left[2];
  const int X = above[-1];
  const int A = above[0];
  const int B = above[1];
  const int C = above[2];
  const int D = above[3];
  DST(0, 0) = DST(1, 2) = AVG2(X, A);
  DST(1, 0) = DST(2, 2) = AVG2(A, B);
  DST(2, 0) = DST(3, 2) = AVG2(B, C);
clang-format's avatar
clang-format committed
604
  DST(3, 0) = AVG2(C, D);
605

clang-format's avatar
clang-format committed
606 607
  DST(0, 3) = AVG3(K, J, I);
  DST(0, 2) = AVG3(J, I, X);
608 609 610
  DST(0, 1) = DST(1, 3) = AVG3(I, X, A);
  DST(1, 1) = DST(2, 3) = AVG3(X, A, B);
  DST(2, 1) = DST(3, 3) = AVG3(A, B, C);
clang-format's avatar
clang-format committed
611
  DST(3, 1) = AVG3(B, C, D);
612 613
}

Yaowu Xu's avatar
Yaowu Xu committed
614
void aom_d135_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride,
615 616 617 618 619 620 621 622 623 624 625
                              const uint8_t *above, const uint8_t *left) {
  const int I = left[0];
  const int J = left[1];
  const int K = left[2];
  const int L = left[3];
  const int X = above[-1];
  const int A = above[0];
  const int B = above[1];
  const int C = above[2];
  const int D = above[3];
  (void)stride;
clang-format's avatar
clang-format committed
626 627 628
  DST(0, 3) = AVG3(J, K, L);
  DST(1, 3) = DST(0, 2) = AVG3(I, J, K);
  DST(2, 3) = DST(1, 2) = DST(0, 1) = AVG3(X, I, J);
629
  DST(3, 3) = DST(2, 2) = DST(1, 1) = DST(0, 0) = AVG3(A, X, I);
clang-format's avatar
clang-format committed
630 631 632
  DST(3, 2) = DST(2, 1) = DST(1, 0) = AVG3(B, A, X);
  DST(3, 1) = DST(2, 0) = AVG3(C, B, A);
  DST(3, 0) = AVG3(D, C, B);
633 634
}

Yaowu Xu's avatar
Yaowu Xu committed
635
void aom_d153_predictor_4x4_c(uint8_t *dst, ptrdiff_t stride,
636 637 638 639 640 641 642 643 644 645 646 647 648
                              const uint8_t *above, const uint8_t *left) {
  const int I = left[0];
  const int J = left[1];
  const int K = left[2];
  const int L = left[3];
  const int X = above[-1];
  const int A = above[0];
  const int B = above[1];
  const int C = above[2];

  DST(0, 0) = DST(2, 1) = AVG2(I, X);
  DST(0, 1) = DST(2, 2) = AVG2(J, I);
  DST(0, 2) = DST(2, 3) = AVG2(K, J);
clang-format's avatar
clang-format committed
649
  DST(0, 3) = AVG2(L, K);
650

clang-format's avatar
clang-format committed
651 652
  DST(3, 0) = AVG3(A, B, C);
  DST(2, 0) = AVG3(X, A, B);
653 654 655
  DST(1, 0) = DST(3, 1) = AVG3(I, X, A);
  DST(1, 1) = DST(3, 2) = AVG3(J, I, X);
  DST(1, 2) = DST(3, 3) = AVG3(K, J, I);
clang-format's avatar
clang-format committed
656
  DST(1, 3) = AVG3(L, K, J);
657 658
}

Yaowu Xu's avatar
Yaowu Xu committed
659
#if CONFIG_AOM_HIGHBITDEPTH
660 661 662 663
static INLINE void highbd_d207_predictor(uint16_t *dst, ptrdiff_t stride,
                                         int bs, const uint16_t *above,
                                         const uint16_t *left, int bd) {
  int r, c;
clang-format's avatar
clang-format committed
664 665
  (void)above;
  (void)bd;
666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682

  // First column.
  for (r = 0; r < bs - 1; ++r) {
    dst[r * stride] = AVG2(left[r], left[r + 1]);
  }
  dst[(bs - 1) * stride] = left[bs - 1];
  dst++;

  // Second column.
  for (r = 0; r < bs - 2; ++r) {
    dst[r * stride] = AVG3(left[r], left[r + 1], left[r + 2]);
  }
  dst[(bs - 2) * stride] = AVG3(left[bs - 2], left[bs - 1], left[bs - 1]);
  dst[(bs - 1) * stride] = left[bs - 1];
  dst++;

  // Rest of last row.
clang-format's avatar
clang-format committed
683
  for (c = 0; c < bs - 2; ++c) dst[(bs - 1) * stride + c] = left[bs - 1];
684 685 686 687 688 689 690

  for (r = bs - 2; r >= 0; --r) {
    for (c = 0; c < bs - 2; ++c)
      dst[r * stride + c] = dst[(r + 1) * stride + c - 2];
  }
}

691 692 693 694
static INLINE void highbd_d207e_predictor(uint16_t *dst, ptrdiff_t stride,
                                          int bs, const uint16_t *above,
                                          const uint16_t *left, int bd) {
  int r, c;
clang-format's avatar
clang-format committed
695 696
  (void)above;
  (void)bd;
697 698 699 700 701

  for (r = 0; r < bs; ++r) {
    for (c = 0; c < bs; ++c) {
      dst[c] = c & 1 ? AVG3(left[(c >> 1) + r], left[(c >> 1) + r + 1],
                            left[(c >> 1) + r + 2])
clang-format's avatar
clang-format committed
702
                     : AVG2(left[(c >> 1) + r], left[(c >> 1) + r + 1]);
703 704 705 706 707
    }
    dst += stride;
  }
}

clang-format's avatar
clang-format committed
708 709
static INLINE void highbd_d63_predictor(uint16_t *dst, ptrdiff_t stride, int bs,
                                        const uint16_t *above,
710 711
                                        const uint16_t *left, int bd) {
  int r, c;
clang-format's avatar
clang-format committed
712 713
  (void)left;
  (void)bd;
714 715 716 717
  for (r = 0; r < bs; ++r) {
    for (c = 0; c < bs; ++c) {
      dst[c] = r & 1 ? AVG3(above[(r >> 1) + c], above[(r >> 1) + c + 1],
                            above[(r >> 1) + c + 2])
clang-format's avatar
clang-format committed
718
                     : AVG2(above[(r >> 1) + c], above[(r >> 1) + c + 1]);
719 720 721 722 723
    }
    dst += stride;
  }
}

724 725
#define highbd_d63e_predictor highbd_d63_predictor

726 727 728 729
static INLINE void highbd_d45_predictor(uint16_t *dst, ptrdiff_t stride, int bs,
                                        const uint16_t *above,
                                        const uint16_t *left, int bd) {
  int r, c;
clang-format's avatar
clang-format committed
730 731
  (void)left;
  (void)bd;
732 733
  for (r = 0; r < bs; ++r) {
    for (c = 0; c < bs; ++c) {
clang-format's avatar
clang-format committed
734 735 736
      dst[c] = r + c + 2 < bs * 2
                   ? AVG3(above[r + c], above[r + c + 1], above[r + c + 2])
                   : above[bs * 2 - 1];
737 738 739 740 741
    }
    dst += stride;
  }
}

742 743 744 745
static INLINE void highbd_d45e_predictor(uint16_t *dst, ptrdiff_t stride,
                                         int bs, const uint16_t *above,
                                         const uint16_t *left, int bd) {
  int r, c;
clang-format's avatar
clang-format committed
746 747
  (void)left;
  (void)bd;
748 749 750
  for (r = 0; r < bs; ++r) {
    for (c = 0; c < bs; ++c) {
      dst[c] = AVG3(above[r + c], above[r + c + 1],
751
                    above[r + c + 1 + (r + c + 2 < bs * 2)]);
752 753 754 755 756
    }
    dst += stride;
  }
}

757 758 759 760
static INLINE void highbd_d117_predictor(uint16_t *dst, ptrdiff_t stride,
                                         int bs, const uint16_t *above,
                                         const uint16_t *left, int bd) {
  int r, c;
clang-format's avatar
clang-format committed
761
  (void)bd;
762 763

  // first row
clang-format's avatar
clang-format committed
764
  for (c = 0; c < bs; c++) dst[c] = AVG2(above[c - 1], above[c]);
765 766 767 768
  dst += stride;

  // second row
  dst[0] = AVG3(left[0], above[-1], above[0]);
clang-format's avatar
clang-format committed
769
  for (c = 1; c < bs; c++) dst[c] = AVG3(above[c - 2], above[c - 1], above[c]);
770 771 772 773 774 775 776 777 778
  dst += stride;

  // the rest of first col
  dst[0] = AVG3(above[-1], left[0], left[1]);
  for (r = 3; r < bs; ++r)
    dst[(r - 2) * stride] = AVG3(left[r - 3], left[r - 2], left[r - 1]);

  // the rest of the block
  for (r = 2; r < bs; ++r) {
clang-format's avatar
clang-format committed
779
    for (c = 1; c < bs; c++) dst[c] = dst[-2 * stride + c - 1];
780 781 782 783 784 785 786 787
    dst += stride;
  }
}

static INLINE void highbd_d135_predictor(uint16_t *dst, ptrdiff_t stride,
                                         int bs, const uint16_t *above,
                                         const uint16_t *left, int bd) {
  int r, c;
clang-format's avatar
clang-format committed
788
  (void)bd;
789
  dst[0] = AVG3(left[0], above[-1], above[0]);
clang-format's avatar
clang-format committed
790
  for (c = 1; c < bs; c++) dst[c] = AVG3(above[c - 2], above[c - 1], above[c]);
791 792 793 794 795 796 797

  dst[stride] = AVG3(above[-1], left[0], left[1]);
  for (r = 2; r < bs; ++r)
    dst[r * stride] = AVG3(left[r - 2], left[r - 1], left[r]);

  dst += stride;
  for (r = 1; r < bs; ++r) {
clang-format's avatar
clang-format committed
798
    for (c = 1; c < bs; c++) dst[c] = dst[-stride + c - 1];
799 800 801 802 803 804 805 806
    dst += stride;
  }
}

static INLINE void highbd_d153_predictor(uint16_t *dst, ptrdiff_t stride,
                                         int bs, const uint16_t *above,
                                         const uint16_t *left, int bd) {
  int r, c;
clang-format's avatar
clang-format committed
807
  (void)bd;
808
  dst[0] = AVG2(above[-1], left[0]);
clang-format's avatar
clang-format committed
809
  for (r = 1; r < bs; r++) dst[r * stride] = AVG2(left[r - 1], left[r]);
810 811 812 813 814 815 816 817 818 819 820 821 822
  dst++;

  dst[0] = AVG3(left[0], above[-1], above[0]);
  dst[stride] = AVG3(above[-1], left[0], left[1]);
  for (r = 2; r < bs; r++)
    dst[r * stride] = AVG3(left[r - 2], left[r - 1], left[r]);
  dst++;

  for (c = 0; c < bs - 2; c++)
    dst[c] = AVG3(above[c - 1], above[c], above[c + 1]);
  dst += stride;

  for (r = 1; r < bs; ++r) {
clang-format's avatar
clang-format committed
823
    for (c = 0; c < bs - 2; c++) dst[c] = dst[-stride + c - 2];
824 825 826 827
    dst += stride;
  }
}

clang-format's avatar
clang-format committed
828 829
static INLINE void highbd_v_predictor(uint16_t *dst, ptrdiff_t stride, int bs,
                                      const uint16_t *above,
830 831
                                      const uint16_t *left, int bd) {
  int r;
clang-format's avatar
clang-format committed
832 833
  (void)left;
  (void)bd;
834 835 836 837 838 839
  for (r = 0; r < bs; r++) {
    memcpy(dst, above, bs * sizeof(uint16_t));
    dst += stride;
  }
}

clang-format's avatar
clang-format committed
840 841
static INLINE void highbd_h_predictor(uint16_t *dst, ptrdiff_t stride, int bs,
                                      const uint16_t *above,
842 843
                                      const uint16_t *left, int bd) {
  int r;
clang-format's avatar
clang-format committed
844 845
  (void)above;
  (void)bd;
846
  for (r = 0; r < bs; r++) {
Yaowu Xu's avatar
Yaowu Xu committed
847
    aom_memset16(dst, left[r], bs);
848 849 850 851
    dst += stride;
  }
}

Urvang Joshi's avatar
Urvang Joshi committed
852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867
#if CONFIG_ALT_INTRA
static INLINE void highbd_paeth_predictor(uint16_t *dst, ptrdiff_t stride,
                                          int bs, const uint16_t *above,
                                          const uint16_t *left, int bd) {
  int r, c;
  const uint16_t ytop_left = above[-1];
  (void)bd;

  for (r = 0; r < bs; r++) {
    for (c = 0; c < bs; c++)
      dst[c] = paeth_predictor_single(left[r], above[c], ytop_left);
    dst += stride;
  }
}

#else
clang-format's avatar
clang-format committed
868 869
static INLINE void highbd_tm_predictor(uint16_t *dst, ptrdiff_t stride, int bs,
                                       const uint16_t *above,
870 871 872
                                       const uint16_t *left, int bd) {
  int r, c;
  int ytop_left = above[-1];
clang-format's avatar
clang-format committed
873
  (void)bd;
874 875 876 877 878 879 880

  for (r = 0; r < bs; r++) {
    for (c = 0; c < bs; c++)
      dst[c] = clip_pixel_highbd(left[r] + above[c] - ytop_left, bd);
    dst += stride;
  }
}
Urvang Joshi's avatar
Urvang Joshi committed
881
#endif  // CONFIG_ALT_INTRA
882 883 884 885 886

static INLINE void highbd_dc_128_predictor(uint16_t *dst, ptrdiff_t stride,
                                           int bs, const uint16_t *above,
                                           const uint16_t *left, int bd) {
  int r;
clang-format's avatar
clang-format committed
887 888
  (void)above;
  (void)left;
889 890

  for (r = 0; r < bs; r++) {
Yaowu Xu's avatar
Yaowu Xu committed
891
    aom_memset16(dst, 128 << (bd - 8), bs);
892 893 894 895 896 897 898 899
    dst += stride;
  }
}

static INLINE void highbd_dc_left_predictor(uint16_t *dst, ptrdiff_t stride,
                                            int bs, const uint16_t *above,
                                            const uint16_t *left, int bd) {
  int i, r, expected_dc, sum = 0;
clang-format's avatar
clang-format committed
900 901
  (void)above;
  (void)bd;
902

clang-format's avatar
clang-format committed
903
  for (i = 0; i < bs; i++) sum += left[i];
904 905 906
  expected_dc = (sum + (bs >> 1)) / bs;

  for (r = 0; r < bs; r++) {
Yaowu Xu's avatar
Yaowu Xu committed
907
    aom_memset16(dst, expected_dc, bs);
908 909 910 911 912 913 914 915
    dst += stride;
  }
}

static INLINE void highbd_dc_top_predictor(uint16_t *dst, ptrdiff_t stride,
                                           int bs, const uint16_t *above,
                                           const uint16_t *left, int bd) {
  int i, r, expected_dc, sum = 0;
clang-format's avatar
clang-format committed
916 917
  (void)left;
  (void)bd;
918

clang-format's avatar
clang-format committed
919
  for (i = 0; i < bs; i++) sum += above[i];
920 921 922
  expected_dc = (sum + (bs >> 1)) / bs;

  for (r = 0; r < bs; r++) {
Yaowu Xu's avatar
Yaowu Xu committed
923
    aom_memset16(dst, expected_dc, bs);
924 925 926 927
    dst += stride;
  }
}

clang-format's avatar
clang-format committed
928 929
static INLINE void highbd_dc_predictor(uint16_t *dst, ptrdiff_t stride, int bs,
                                       const uint16_t *above,
930 931 932
                                       const uint16_t *left, int bd) {
  int i, r, expected_dc, sum = 0;
  const int count = 2 * bs;
clang-format's avatar
clang-format committed
933
  (void)bd;
934 935 936 937 938 939 940 941 942

  for (i = 0; i < bs; i++) {
    sum += above[i];
    sum += left[i];
  }

  expected_dc = (sum + (count >> 1)) / count;

  for (r = 0; r < bs; r++) {
Yaowu Xu's avatar
Yaowu Xu committed
943
    aom_memset16(dst, expected_dc, bs);
944 945 946
    dst += stride;
  }
}
Yaowu Xu's avatar
Yaowu Xu committed
947
#endif  // CONFIG_AOM_HIGHBITDEPTH
948 949 950 951

// This serves as a wrapper function, so that all the prediction functions
// can be unified and accessed as a pointer array. Note that the boundary
// above and left are not necessarily used all the time.
clang-format's avatar
clang-format committed
952
#define intra_pred_sized(type, size)                        \
Yaowu Xu's avatar
Yaowu Xu committed
953
  void aom_##type##_predictor_##size##x##size##_c(          \
clang-format's avatar
clang-format committed
954 955 956
      uint8_t *dst, ptrdiff_t stride, const uint8_t *above, \
      const uint8_t *left) {                                \
    type##_predictor(dst, stride, size, above, left);       \
957 958
  }

Yaowu Xu's avatar
Yaowu Xu committed
959
#if CONFIG_AOM_HIGHBITDEPTH
clang-format's avatar
clang-format committed
960
#define intra_pred_highbd_sized(type, size)                        \
Yaowu Xu's avatar
Yaowu Xu committed
961
  void aom_highbd_##type##_predictor_##size##x##size##_c(          \
clang-format's avatar
clang-format committed
962 963
      uint16_t *dst, ptrdiff_t stride, const uint16_t *above,      \
      const uint16_t *left, int bd) {                              \
964 965 966
    highbd_##type##_predictor(dst, stride, size, above, left, bd); \
  }

clang-format's avatar
clang-format committed
967
/* clang-format off */
968
#define intra_pred_allsizes(type) \
Jingning Han's avatar
Jingning Han committed
969
  intra_pred_sized(type, 2) \
970 971 972 973 974 975 976 977 978
  intra_pred_sized(type, 4) \
  intra_pred_sized(type, 8) \
  intra_pred_sized(type, 16) \
  intra_pred_sized(type, 32) \
  intra_pred_highbd_sized(type, 4) \
  intra_pred_highbd_sized(type, 8) \
  intra_pred_highbd_sized(type, 16) \
  intra_pred_highbd_sized(type, 32)

Jingning Han's avatar
Jingning Han committed
979
#define intra_pred_above_4x4(type) \
980 981 982 983 984 985 986 987 988 989
  intra_pred_sized(type, 8) \
  intra_pred_sized(type, 16) \
  intra_pred_sized(type, 32) \
  intra_pred_highbd_sized(type, 4) \
  intra_pred_highbd_sized(type, 8) \
  intra_pred_highbd_sized(type, 16) \
  intra_pred_highbd_sized(type, 32)

#else
#define intra_pred_allsizes(type) \
Jingning Han's avatar
Jingning Han committed
990
  intra_pred_sized(type, 2) \
991 992 993 994 995
  intra_pred_sized(type, 4) \
  intra_pred_sized(type, 8) \
  intra_pred_sized(type, 16) \
  intra_pred_sized(type, 32)

Jingning Han's avatar
Jingning Han committed
996
#define intra_pred_above_4x4(type) \
997 998 999
  intra_pred_sized(type, 8) \
  intra_pred_sized(type, 16) \
  intra_pred_sized(type, 32)
Yaowu Xu's avatar
Yaowu Xu committed
1000
#endif  // CONFIG_AOM_HIGHBITDEPTH
1001

Jingning Han's avatar
Jingning Han committed
1002 1003 1004
intra_pred_above_4x4(d207)
intra_pred_above_4x4(d63)
intra_pred_above_4x4(d45)
1005 1006
intra_pred_allsizes(d207e)
intra_pred_allsizes(d63e)
Jingning Han's avatar
Jingning Han committed
1007 1008 1009 1010
intra_pred_above_4x4(d45e)
intra_pred_above_4x4(d117)
intra_pred_above_4x4(d135)
intra_pred_above_4x4(d153)
1011 1012
intra_pred_allsizes(v)
intra_pred_allsizes(h)
Urvang Joshi's avatar
Urvang Joshi committed
1013 1014 1015
#if CONFIG_ALT_INTRA
intra_pred_allsizes(paeth)
#else
1016
intra_pred_allsizes(tm)
Urvang Joshi's avatar
Urvang Joshi committed
1017
#endif  // CONFIG_ALT_INTRA
1018 1019 1020 1021
intra_pred_allsizes(dc_128)
intra_pred_allsizes(dc_left)
intra_pred_allsizes(dc_top)
intra_pred_allsizes(dc)
clang-format's avatar
clang-format committed
1022
/* clang-format on */
1023
#undef intra_pred_allsizes