/*
 *  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 "vp8_rtcd.h"
#include "./vpx_dsp_rtcd.h"
#include "vp8/encoder/quantize.h"
#include "vp8/common/reconintra.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 = vpx_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 *dst = x->e_mbd.dst.y_buffer + b->offset;
    unsigned char *Above = dst - dst_stride;
    unsigned char *yleft = dst - 1;
    unsigned char top_left = Above[-1];

    vp8_intra4x4_predict(Above, yleft, dst_stride, b->bmi.as_mode,
                         b->predictor, 16, top_left);

    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, dst, dst_stride);
    }
    else
    {
      vp8_dc_only_idct_add(b->dqcoeff[0], b->predictor, 16, dst, dst_stride);
    }
}

void vp8_encode_intra4x4mby(MACROBLOCK *mb)
{
    int i;

    MACROBLOCKD *xd = &mb->e_mbd;
    intra_prediction_down_copy(xd, xd->dst.y_buffer - xd->dst.y_stride + 16);

    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(xd,
                                         xd->dst.y_buffer - xd->dst.y_stride,
                                         xd->dst.y_buffer - 1,
                                         xd->dst.y_stride,
                                         xd->dst.y_buffer,
                                         xd->dst.y_stride);

    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(xd, xd->dst.u_buffer - xd->dst.uv_stride,
                                      xd->dst.v_buffer - xd->dst.uv_stride,
                                      xd->dst.u_buffer - 1,
                                      xd->dst.v_buffer - 1,
                                      xd->dst.uv_stride,
                                      xd->dst.u_buffer, xd->dst.v_buffer,
                                      xd->dst.uv_stride);

    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);
}
