/*
 *  Copyright (c) 2010 The VP8 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 "idct.h"
#include "quantize.h"
#include "reconintra.h"
#include "reconintra4x4.h"
#include "encodemb.h"
#include "invtrans.h"
#include "recon.h"
#include "dct.h"
#include "g_common.h"
#include "encodeintra.h"

#define intra4x4ibias_rate    128
#define intra4x4pbias_rate    256


void vp8_update_mode_context(int *abmode, int *lbmode, int i, int best_mode)
{
    if (i < 12)
    {
        abmode[i+4] = best_mode;
    }

    if ((i & 3) != 3)
    {
        lbmode[i+1] = best_mode;
    }

}
#if CONFIG_RUNTIME_CPU_DETECT
#define IF_RTCD(x) (x)
#else
#define IF_RTCD(x) NULL
#endif
void vp8_encode_intra4x4block(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x, BLOCK *be, BLOCKD *b, int best_mode)
{
    vp8_predict_intra4x4(b, best_mode, b->predictor);

    ENCODEMB_INVOKE(&rtcd->encodemb, subb)(be, b, 16);

    x->vp8_short_fdct4x4(be->src_diff, be->coeff, 32);

    x->quantize_b(be, b);

    x->e_mbd.mbmi.mb_skip_coeff &= (!b->eob);

    vp8_inverse_transform_b(IF_RTCD(&rtcd->common->idct), b, 32);

    RECON_INVOKE(&rtcd->common->recon, recon)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
}

void vp8_encode_intra4x4block_rd(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x, BLOCK *be, BLOCKD *b, int best_mode)
{
    vp8_predict_intra4x4(b, best_mode, b->predictor);

    ENCODEMB_INVOKE(&rtcd->encodemb, subb)(be, b, 16);

    x->vp8_short_fdct4x4(be->src_diff, be->coeff, 32);

    x->quantize_b(be, b);

    x->e_mbd.mbmi.mb_skip_coeff &= (!b->eob);

    IDCT_INVOKE(&rtcd->common->idct, idct16)(b->dqcoeff, b->diff, 32);

    RECON_INVOKE(&rtcd->common->recon, recon)(b->predictor, b->diff, *(b->base_dst) + b->dst, b->dst_stride);
}

void vp8_encode_intra4x4mby(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *mb)
{
    int i;

    MACROBLOCKD *x = &mb->e_mbd;
    vp8_intra_prediction_down_copy(x);

    for (i = 0; i < 16; i++)
    {
        BLOCK *be = &mb->block[i];
        BLOCKD *b = &x->block[i];

        vp8_encode_intra4x4block(rtcd, mb, be, b, b->bmi.mode);
    }

    return;
}

void vp8_encode_intra16x16mby(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x)
{
    int b;

    vp8_build_intra_predictors_mby_ptr(&x->e_mbd);

    ENCODEMB_INVOKE(&rtcd->encodemb, submby)(x->src_diff, x->src.y_buffer, x->e_mbd.predictor, x->src.y_stride);

    vp8_transform_intra_mby(x);

    vp8_quantize_mby(x);

#if !(CONFIG_REALTIME_ONLY)
#if 1

    if (x->optimize && x->rddiv > 1)
        vp8_optimize_mby(x, rtcd);

#endif
#endif

    vp8_inverse_transform_mby(IF_RTCD(&rtcd->common->idct), &x->e_mbd);

    vp8_recon16x16mby(IF_RTCD(&rtcd->common->recon), &x->e_mbd);

    // make sure block modes are set the way we want them for context updates
    for (b = 0; b < 16; b++)
    {
        BLOCKD *d = &x->e_mbd.block[b];

        switch (x->e_mbd.mbmi.mode)
        {

        case DC_PRED:
            d->bmi.mode = B_DC_PRED;
            break;
        case V_PRED:
            d->bmi.mode = B_VE_PRED;
            break;
        case H_PRED:
            d->bmi.mode = B_HE_PRED;
            break;
        case TM_PRED:
            d->bmi.mode = B_TM_PRED;
            break;
        default:
            d->bmi.mode = B_DC_PRED;
            break;

        }
    }
}

void vp8_encode_intra16x16mbyrd(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x)
{
    int b;

    vp8_build_intra_predictors_mby_ptr(&x->e_mbd);

    ENCODEMB_INVOKE(&rtcd->encodemb, submby)(x->src_diff, x->src.y_buffer, x->e_mbd.predictor, x->src.y_stride);

    vp8_transform_intra_mbyrd(x);

    x->e_mbd.mbmi.mb_skip_coeff = 1;

    vp8_quantize_mby(x);

    vp8_inverse_transform_mby(IF_RTCD(&rtcd->common->idct), &x->e_mbd);

    vp8_recon16x16mby(IF_RTCD(&rtcd->common->recon), &x->e_mbd);

    // make sure block modes are set the way we want them for context updates
    for (b = 0; b < 16; b++)
    {
        BLOCKD *d = &x->e_mbd.block[b];

        switch (x->e_mbd.mbmi.mode)
        {

        case DC_PRED:
            d->bmi.mode = B_DC_PRED;
            break;
        case V_PRED:
            d->bmi.mode = B_VE_PRED;
            break;
        case H_PRED:
            d->bmi.mode = B_HE_PRED;
            break;
        case TM_PRED:
            d->bmi.mode = B_TM_PRED;
            break;
        default:
            d->bmi.mode = B_DC_PRED;
            break;

        }
    }
}

void vp8_encode_intra16x16mbuv(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x)
{
    vp8_build_intra_predictors_mbuv(&x->e_mbd);

    ENCODEMB_INVOKE(&rtcd->encodemb, submbuv)(x->src_diff, x->src.u_buffer, x->src.v_buffer, x->e_mbd.predictor, x->src.uv_stride);

    vp8_transform_mbuv(x);

    vp8_quantize_mbuv(x);

#if !(CONFIG_REALTIME_ONLY)
#if 1

    if (x->optimize && x->rddiv > 1)
        vp8_optimize_mbuv(x, rtcd);

#endif
#endif

    vp8_inverse_transform_mbuv(IF_RTCD(&rtcd->common->idct), &x->e_mbd);

    vp8_recon_intra_mbuv(IF_RTCD(&rtcd->common->recon), &x->e_mbd);
}

void vp8_encode_intra16x16mbuvrd(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x)
{
    vp8_build_intra_predictors_mbuv(&x->e_mbd);

    ENCODEMB_INVOKE(&rtcd->encodemb, submbuv)(x->src_diff, x->src.u_buffer, x->src.v_buffer, x->e_mbd.predictor, x->src.uv_stride);

    vp8_transform_mbuvrd(x);

    vp8_quantize_mbuv(x);

    vp8_inverse_transform_mbuv(IF_RTCD(&rtcd->common->idct), &x->e_mbd);

    vp8_recon_intra_mbuv(IF_RTCD(&rtcd->common->recon), &x->e_mbd);
}
