/*
 *  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 "vp8/common/idct.h"
#include "quantize.h"
#include "vp8/common/reconintra.h"
#include "vp8/common/reconintra4x4.h"
#include "encodemb.h"
#include "vp8/common/invtrans.h"
#include "vp8/common/recon.h"
#include "dct.h"
#include "vp8/common/g_common.h"
#include "encodeintra.h"


#ifdef ENC_DEBUG
extern int enc_debug;
#endif

#if CONFIG_RUNTIME_CPU_DETECT
#define IF_RTCD(x) (x)
#else
#define IF_RTCD(x) NULL
#endif

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

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

    if (use_16x16_pred)
    {
        x->e_mbd.mode_info_context->mbmi.mode = DC_PRED;
#if CONFIG_COMP_INTRA_PRED
        x->e_mbd.mode_info_context->mbmi.second_mode = (MB_PREDICTION_MODE) (DC_PRED - 1);
#endif
        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(IF_RTCD(&cpi->rtcd), x);
    }
    else
    {
        for (i = 0; i < 16; i++)
        {
            x->e_mbd.block[i].bmi.as_mode.first = B_DC_PRED;
            vp8_encode_intra4x4block(IF_RTCD(&cpi->rtcd), x, i);
        }
    }

    intra_pred_var = VARIANCE_INVOKE(&cpi->rtcd.variance, getmbss)(x->src_diff);

    return intra_pred_var;
}

void vp8_encode_intra4x4block(const VP8_ENCODER_RTCD *rtcd,
                              MACROBLOCK *x, int ib)
{
    BLOCKD *b = &x->e_mbd.block[ib];
    BLOCK *be = &x->block[ib];

#if CONFIG_COMP_INTRA_PRED
    if (b->bmi.as_mode.second == (B_PREDICTION_MODE) (B_DC_PRED - 1))
    {
#endif
    RECON_INVOKE(&rtcd->common->recon, intra4x4_predict)
                (b, b->bmi.as_mode.first, b->predictor);
#if CONFIG_COMP_INTRA_PRED
    }
    else
    {
        RECON_INVOKE(&rtcd->common->recon, comp_intra4x4_predict)
            (b, b->bmi.as_mode.first, b->bmi.as_mode.second, b->predictor);
    }
#endif

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

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

    x->quantize_b(be, b);

    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_intra4x4mby(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *mb)
{
    int i;

    MACROBLOCKD *x = &mb->e_mbd;
#if 0
    // Intra modes requiring top-right MB reconstructed data have been disabled
    vp8_intra_prediction_down_copy(x);
#endif

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

void vp8_encode_intra16x16mby(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x)
{
    BLOCK *b = &x->block[0];

    int tx_type = x->e_mbd.mode_info_context->mbmi.txfm_size;

#if CONFIG_COMP_INTRA_PRED
    if (x->e_mbd.mode_info_context->mbmi.second_mode == (MB_PREDICTION_MODE) (DC_PRED - 1))
#endif
    RECON_INVOKE(&rtcd->common->recon, build_intra_predictors_mby)(&x->e_mbd);
#if CONFIG_COMP_INTRA_PRED
    else
        RECON_INVOKE(&rtcd->common->recon, build_comp_intra_predictors_mby)(&x->e_mbd);
#endif

    ENCODEMB_INVOKE(&rtcd->encodemb, submby)(x->src_diff, *(b->base_src), x->e_mbd.predictor, b->src_stride);

    if( tx_type == TX_8X8 )
        vp8_transform_intra_mby_8x8(x);
    else
        vp8_transform_intra_mby(x);

    if(tx_type == TX_8X8)
      vp8_quantize_mby_8x8(x);
    else
      vp8_quantize_mby(x);

    if (x->optimize)
    {
      if( tx_type == TX_8X8 )
        vp8_optimize_mby_8x8(x, rtcd);
      else
        vp8_optimize_mby(x, rtcd);
    }

    if(tx_type == TX_8X8)
        vp8_inverse_transform_mby_8x8(IF_RTCD(&rtcd->common->idct), &x->e_mbd);
    else
        vp8_inverse_transform_mby(IF_RTCD(&rtcd->common->idct), &x->e_mbd);

#ifdef ENC_DEBUG
    if (enc_debug) {
      int i;
      printf("Intra qcoeff:\n");
      printf("%d %d:\n", x->e_mbd.mb_to_left_edge, x->e_mbd.mb_to_top_edge);
      for (i =0; i<400; i++) {
        printf("%3d ", x->e_mbd.qcoeff[i]);
        if (i%16 == 15) printf("\n");
      }
      printf("Intra dqcoeff:\n");
      for (i =0; i<400; i++) {
        printf("%3d ", x->e_mbd.dqcoeff[i]);
        if (i%16 == 15) printf("\n");
      }
      printf("Intra diff:\n");
      for (i =0; i<400; i++) {
        printf("%3d ", x->e_mbd.diff[i]);
        if (i%16 == 15) printf("\n");
      }
      printf("Intra predictor:\n");
      for (i =0; i<400; i++) {
        printf("%3d ", x->e_mbd.predictor[i]);
        if (i%16 == 15) printf("\n");
      }
      printf("eobs:\n");
      for (i=0;i<25;i++)
        printf("%d ", x->e_mbd.block[i].eob);
      printf("\n");
    }
#endif

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

}

void vp8_encode_intra16x16mbuv(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x)
{
    int tx_type = x->e_mbd.mode_info_context->mbmi.txfm_size;
#if CONFIG_COMP_INTRA_PRED
    if (x->e_mbd.mode_info_context->mbmi.second_uv_mode == (MB_PREDICTION_MODE) (DC_PRED - 1))
    {
#endif
    RECON_INVOKE(&rtcd->common->recon, build_intra_predictors_mbuv)(&x->e_mbd);
#if CONFIG_COMP_INTRA_PRED
    }
    else
    {
        RECON_INVOKE(&rtcd->common->recon, build_comp_intra_predictors_mbuv)(&x->e_mbd);
    }
#endif

    ENCODEMB_INVOKE(&rtcd->encodemb, submbuv)(x->src_diff, x->src.u_buffer, x->src.v_buffer, x->e_mbd.predictor, x->src.uv_stride);
    if(tx_type == TX_8X8)
        vp8_transform_mbuv_8x8(x);
    else
        vp8_transform_mbuv(x);

    if(tx_type == TX_8X8)
        vp8_quantize_mbuv_8x8(x);
    else
        vp8_quantize_mbuv(x);

#ifdef ENC_DEBUG
    if (enc_debug) {
      int i;
      printf("vp8_encode_intra16x16mbuv\n");
      printf("%d %d:\n", x->e_mbd.mb_to_left_edge, x->e_mbd.mb_to_top_edge);
      printf("qcoeff:\n");
      for (i =0; i<400; i++) {
        printf("%3d ", x->e_mbd.qcoeff[i]);
        if (i%16 == 15) printf("\n");
      }
      printf("dqcoeff:\n");
      for (i =0; i<400; i++) {
        printf("%3d ", x->e_mbd.dqcoeff[i]);
        if (i%16 == 15) printf("\n");
      }
      printf("diff:\n");
      for (i =0; i<400; i++) {
        printf("%3d ", x->e_mbd.diff[i]);
        if (i%16 == 15) printf("\n");
      }
      printf("predictor:\n");
      for (i =0; i<400; i++) {
        printf("%3d ", x->e_mbd.predictor[i]);
        if (i%16 == 15) printf("\n");
      }
      printf("eobs:\n");
      for (i=0;i<25;i++)
        printf("%d ", x->e_mbd.block[i].eob);
      printf("\n");
    }
#endif
    if (x->optimize)
    {
      if(tx_type == TX_8X8)
        vp8_optimize_mbuv_8x8(x, rtcd);
      else
        vp8_optimize_mbuv(x, rtcd);
    }

    if(tx_type == TX_8X8)
        vp8_inverse_transform_mbuv_8x8(IF_RTCD(&rtcd->common->idct), &x->e_mbd);
    else
        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_intra8x8(const VP8_ENCODER_RTCD *rtcd,
                              MACROBLOCK *x, int ib)
{
    BLOCKD *b = &x->e_mbd.block[ib];
    BLOCK *be = &x->block[ib];
    const int iblock[4]={0,1,4,5};
    int i;

#if CONFIG_COMP_INTRA_PRED
    if (b->bmi.as_mode.second == (MB_PREDICTION_MODE) (DC_PRED - 1))
    {
#endif
    RECON_INVOKE(&rtcd->common->recon, intra8x8_predict)
                (b, b->bmi.as_mode.first, b->predictor);
#if CONFIG_COMP_INTRA_PRED
    }
    else
    {
        RECON_INVOKE(&rtcd->common->recon, comp_intra8x8_predict)
            (b, b->bmi.as_mode.first, b->bmi.as_mode.second, b->predictor);
    }
#endif

    for(i=0;i<4;i++)
    {
        b = &x->e_mbd.block[ib + iblock[i]];
        be = &x->block[ib + iblock[i]];
        ENCODEMB_INVOKE(&rtcd->encodemb, subb)(be, b, 16);
        x->vp8_short_fdct4x4(be->src_diff, be->coeff, 32);
        x->quantize_b(be, b);
        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);
    }

}

extern const int vp8_i8x8_block[4];
void vp8_encode_intra8x8mby(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x)
{
    int i, ib;

    for(i=0;i<4;i++)
    {
        ib = vp8_i8x8_block[i];
        vp8_encode_intra8x8(rtcd, x, ib);
    }

}

void vp8_encode_intra_uv4x4(const VP8_ENCODER_RTCD *rtcd,
                              MACROBLOCK *x, int ib,
                              int mode, int second)
{
    BLOCKD *b = &x->e_mbd.block[ib];
    BLOCK *be = &x->block[ib];

#if CONFIG_COMP_INTRA_PRED
    if (second == -1)
    {
#endif
    RECON_INVOKE(&rtcd->common->recon, intra_uv4x4_predict)
                (b, mode, b->predictor);
#if CONFIG_COMP_INTRA_PRED
    }
    else
    {
        RECON_INVOKE(&rtcd->common->recon, comp_intra_uv4x4_predict)
            (b, mode, second, b->predictor);
    }
#endif

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

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

    x->quantize_b(be, b);

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

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



void vp8_encode_intra8x8mbuv(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x)
{
    int i, ib, mode, second;
    BLOCKD *b;
    for(i=0;i<4;i++)
    {
        ib = vp8_i8x8_block[i];
        b = &x->e_mbd.block[ib];
        mode = b->bmi.as_mode.first;
#if CONFIG_COMP_INTRA_PRED
        second = b->bmi.as_mode.second;
#else
        second = -1;
#endif
        /*u */
        vp8_encode_intra_uv4x4(rtcd, x, i+16, mode, second);
        /*v */
        vp8_encode_intra_uv4x4(rtcd, x, i+20, mode, second);
    }
}
