/*
 *  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_config.h"
#include "vpx_rtcd.h"
#include "quantize.h"
#include "vp8/common/reconintra4x4.h"
#include "encodemb.h"
#include "vp8/common/invtrans.h"
#include "encodeintra.h"


int vp8_encode_intra(VP8_COMP *cpi, MACROBLOCK *x, int use_dc_pred)
{

    int i;
    int intra_pred_var = 0;
    (void) cpi;

    if (use_dc_pred)
    {
        x->e_mbd.mode_info_context->mbmi.mode = DC_PRED;
        x->e_mbd.mode_info_context->mbmi.uv_mode = DC_PRED;
        x->e_mbd.mode_info_context->mbmi.ref_frame = INTRA_FRAME;

        vp8_encode_intra16x16mby(x);

        vp8_inverse_transform_mby(&x->e_mbd);
    }
    else
    {
        for (i = 0; i < 16; i++)
        {
            x->e_mbd.block[i].bmi.as_mode = B_DC_PRED;
            vp8_encode_intra4x4block(x, i);
        }
    }

    intra_pred_var = vp8_get_mb_ss(x->src_diff);

    return intra_pred_var;
}

void vp8_encode_intra4x4block(MACROBLOCK *x, int ib)
{
    BLOCKD *b = &x->e_mbd.block[ib];
    BLOCK *be = &x->block[ib];
    int dst_stride = x->e_mbd.dst.y_stride;
    unsigned char *base_dst = x->e_mbd.dst.y_buffer;

    vp8_intra4x4_predict(base_dst + b->offset, dst_stride,
                 b->bmi.as_mode, b->predictor, 16);

    vp8_subtract_b(be, b, 16);

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

    x->quantize_b(be, b);

    if (*b->eob > 1)
    {
      vp8_short_idct4x4llm(b->dqcoeff,
            b->predictor, 16, base_dst + b->offset, dst_stride);
    }
    else
    {
      vp8_dc_only_idct_add
            (b->dqcoeff[0], b->predictor, 16, base_dst + b->offset,
                dst_stride);
    }
}

void vp8_encode_intra4x4mby(MACROBLOCK *mb)
{
    int i;

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

    for (i = 0; i < 16; i++)
        vp8_encode_intra4x4block(mb, i);
    return;
}

void vp8_encode_intra16x16mby(MACROBLOCK *x)
{
    BLOCK *b = &x->block[0];
    MACROBLOCKD *xd = &x->e_mbd;

    vp8_build_intra_predictors_mby_s(&x->e_mbd);

    vp8_subtract_mby(x->src_diff, *(b->base_src),
        b->src_stride, xd->dst.y_buffer, xd->dst.y_stride);

    vp8_transform_intra_mby(x);

    vp8_quantize_mby(x);

    if (x->optimize)
        vp8_optimize_mby(x);
}

void vp8_encode_intra16x16mbuv(MACROBLOCK *x)
{
    MACROBLOCKD *xd = &x->e_mbd;

    vp8_build_intra_predictors_mbuv_s(&x->e_mbd);

    vp8_subtract_mbuv(x->src_diff, x->src.u_buffer,
        x->src.v_buffer, x->src.uv_stride, xd->dst.u_buffer,
        xd->dst.v_buffer, xd->dst.uv_stride);

    vp8_transform_mbuv(x);

    vp8_quantize_mbuv(x);

    if (x->optimize)
        vp8_optimize_mbuv(x);
}
