/*
 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "vpx_ports/config.h"
#include "vpx_mem/vpx_mem.h"
#include "vp8/common/blockd.h"

#define build_intra_predictors_mbuv_prototype(sym) \
  void sym(unsigned char *dst, int dst_stride, \
           const unsigned char *src, int src_stride)
typedef build_intra_predictors_mbuv_prototype((*build_intra_predictors_mbuv_fn_t));

extern build_intra_predictors_mbuv_prototype(vp8_intra_pred_uv_dc_mmx2);
extern build_intra_predictors_mbuv_prototype(vp8_intra_pred_uv_dctop_mmx2);
extern build_intra_predictors_mbuv_prototype(vp8_intra_pred_uv_dcleft_mmx2);
extern build_intra_predictors_mbuv_prototype(vp8_intra_pred_uv_dc128_mmx);
extern build_intra_predictors_mbuv_prototype(vp8_intra_pred_uv_ho_mmx2);
extern build_intra_predictors_mbuv_prototype(vp8_intra_pred_uv_ho_ssse3);
extern build_intra_predictors_mbuv_prototype(vp8_intra_pred_uv_ve_mmx);
extern build_intra_predictors_mbuv_prototype(vp8_intra_pred_uv_tm_sse2);
extern build_intra_predictors_mbuv_prototype(vp8_intra_pred_uv_tm_ssse3);

static void vp8_build_intra_predictors_mbuv_x86(MACROBLOCKD *xd,
                                                unsigned char *dst_u,
                                                unsigned char *dst_v,
                                                int dst_stride,
                                                build_intra_predictors_mbuv_fn_t tm_func,
                                                build_intra_predictors_mbuv_fn_t ho_func) {
  int mode = xd->mode_info_context->mbmi.uv_mode;
  build_intra_predictors_mbuv_fn_t fn;
  int src_stride = xd->dst.uv_stride;

  switch (mode) {
    case  V_PRED:
      fn = vp8_intra_pred_uv_ve_mmx;
      break;
    case  H_PRED:
      fn = ho_func;
      break;
    case TM_PRED:
      fn = tm_func;
      break;
    case DC_PRED:
      if (xd->up_available) {
        if (xd->left_available) {
          fn = vp8_intra_pred_uv_dc_mmx2;
          break;
        } else {
          fn = vp8_intra_pred_uv_dctop_mmx2;
          break;
        }
      } else if (xd->left_available) {
        fn = vp8_intra_pred_uv_dcleft_mmx2;
        break;
      } else {
        fn = vp8_intra_pred_uv_dc128_mmx;
        break;
      }
      break;
    default:
      return;
  }

  fn(dst_u, dst_stride, xd->dst.u_buffer, src_stride);
  fn(dst_v, dst_stride, xd->dst.v_buffer, src_stride);
}

void vp8_build_intra_predictors_mbuv_sse2(MACROBLOCKD *xd) {
  vp8_build_intra_predictors_mbuv_x86(xd, &xd->predictor[256],
                                      &xd->predictor[320], 8,
                                      vp8_intra_pred_uv_tm_sse2,
                                      vp8_intra_pred_uv_ho_mmx2);
}

void vp8_build_intra_predictors_mbuv_ssse3(MACROBLOCKD *xd) {
  vp8_build_intra_predictors_mbuv_x86(xd, &xd->predictor[256],
                                      &xd->predictor[320], 8,
                                      vp8_intra_pred_uv_tm_ssse3,
                                      vp8_intra_pred_uv_ho_ssse3);
}

void vp8_build_intra_predictors_mbuv_s_sse2(MACROBLOCKD *xd) {
  vp8_build_intra_predictors_mbuv_x86(xd, xd->dst.u_buffer,
                                      xd->dst.v_buffer, xd->dst.uv_stride,
                                      vp8_intra_pred_uv_tm_sse2,
                                      vp8_intra_pred_uv_ho_mmx2);
}

void vp8_build_intra_predictors_mbuv_s_ssse3(MACROBLOCKD *xd) {
  vp8_build_intra_predictors_mbuv_x86(xd, xd->dst.u_buffer,
                                      xd->dst.v_buffer, xd->dst.uv_stride,
                                      vp8_intra_pred_uv_tm_ssse3,
                                      vp8_intra_pred_uv_ho_ssse3);
}
