/*
 *  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 "treereader.h"
#include "vp8/common/entropymv.h"
#include "vp8/common/entropymode.h"
#include "onyxd_int.h"
#include "vp8/common/findnearmv.h"

#if CONFIG_DEBUG
#include <assert.h>
#endif
static B_PREDICTION_MODE read_bmode(vp8_reader *bc, const vp8_prob *p)
{
    const int i = vp8_treed_read(bc, vp8_bmode_tree, p);

    return (B_PREDICTION_MODE)i;
}

static MB_PREDICTION_MODE read_ymode(vp8_reader *bc, const vp8_prob *p)
{
    const int i = vp8_treed_read(bc, vp8_ymode_tree, p);

    return (MB_PREDICTION_MODE)i;
}

static MB_PREDICTION_MODE read_kf_ymode(vp8_reader *bc, const vp8_prob *p)
{
    const int i = vp8_treed_read(bc, vp8_kf_ymode_tree, p);

    return (MB_PREDICTION_MODE)i;
}

static MB_PREDICTION_MODE read_uv_mode(vp8_reader *bc, const vp8_prob *p)
{
    const int i = vp8_treed_read(bc, vp8_uv_mode_tree, p);

    return (MB_PREDICTION_MODE)i;
}

static void read_kf_modes(VP8D_COMP *pbi, MODE_INFO *mi)
{
    vp8_reader *const bc = & pbi->bc;
    const int mis = pbi->common.mode_info_stride;

    mi->mbmi.ref_frame = INTRA_FRAME;
    mi->mbmi.mode = read_kf_ymode(bc, vp8_kf_ymode_prob);

    if (mi->mbmi.mode == B_PRED)
    {
        int i = 0;
        mi->mbmi.is_4x4 = 1;

        do
        {
            const B_PREDICTION_MODE A = above_block_mode(mi, i, mis);
            const B_PREDICTION_MODE L = left_block_mode(mi, i);

            mi->bmi[i].as_mode =
                read_bmode(bc, vp8_kf_bmode_prob [A] [L]);
        }
        while (++i < 16);
    }

    mi->mbmi.uv_mode = read_uv_mode(bc, vp8_kf_uv_mode_prob);
}

static int read_mvcomponent(vp8_reader *r, const MV_CONTEXT *mvc)
{
    const vp8_prob *const p = (const vp8_prob *) mvc;
    int x = 0;

    if (vp8_read(r, p [mvpis_short]))  /* Large */
    {
        int i = 0;

        do
        {
            x += vp8_read(r, p [MVPbits + i]) << i;
        }
        while (++i < 3);

        i = mvlong_width - 1;  /* Skip bit 3, which is sometimes implicit */

        do
        {
            x += vp8_read(r, p [MVPbits + i]) << i;
        }
        while (--i > 3);

        if (!(x & 0xFFF0)  ||  vp8_read(r, p [MVPbits + 3]))
            x += 8;
    }
    else   /* small */
        x = vp8_treed_read(r, vp8_small_mvtree, p + MVPshort);

    if (x  &&  vp8_read(r, p [MVPsign]))
        x = -x;

    return x;
}

static void read_mv(vp8_reader *r, MV *mv, const MV_CONTEXT *mvc)
{
    mv->row = (short)(read_mvcomponent(r,   mvc) << 1);
    mv->col = (short)(read_mvcomponent(r, ++mvc) << 1);
}


static void read_mvcontexts(vp8_reader *bc, MV_CONTEXT *mvc)
{
    int i = 0;

    do
    {
        const vp8_prob *up = vp8_mv_update_probs[i].prob;
        vp8_prob *p = (vp8_prob *)(mvc + i);
        vp8_prob *const pstop = p + MVPcount;

        do
        {
            if (vp8_read(bc, *up++))
            {
                const vp8_prob x = (vp8_prob)vp8_read_literal(bc, 7);

                *p = x ? x << 1 : 1;
            }
        }
        while (++p < pstop);
    }
    while (++i < 2);
}

static const unsigned char mbsplit_fill_count[4] = {8, 8, 4, 1};
static const unsigned char mbsplit_fill_offset[4][16] = {
    { 0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12, 13, 14, 15},
    { 0,  1,  4,  5,  8,  9, 12, 13,  2,  3,   6,  7, 10, 11, 14, 15},
    { 0,  1,  4,  5,  2,  3,  6,  7,  8,  9,  12, 13, 10, 11, 14, 15},
    { 0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12, 13, 14, 15}
};


static void mb_mode_mv_init(VP8D_COMP *pbi)
{
    vp8_reader *const bc = & pbi->bc;
    MV_CONTEXT *const mvc = pbi->common.fc.mvc;

#if CONFIG_ERROR_CONCEALMENT
    /* Default is that no macroblock is corrupt, therefore we initialize
     * mvs_corrupt_from_mb to something very big, which we can be sure is
     * outside the frame. */
    pbi->mvs_corrupt_from_mb = UINT_MAX;
#endif
    pbi->prob_skip_false = 0;
    if (pbi->common.mb_no_coeff_skip)
        pbi->prob_skip_false = (vp8_prob)vp8_read_literal(bc, 8);

    if(pbi->common.frame_type != KEY_FRAME)
    {
        pbi->prob_intra = (vp8_prob)vp8_read_literal(bc, 8);
        pbi->prob_last  = (vp8_prob)vp8_read_literal(bc, 8);
        pbi->prob_gf    = (vp8_prob)vp8_read_literal(bc, 8);

        if (vp8_read_bit(bc))
        {
            int i = 0;

            do
            {
                pbi->common.fc.ymode_prob[i] =
                    (vp8_prob) vp8_read_literal(bc, 8);
            }
            while (++i < 4);
        }

        if (vp8_read_bit(bc))
        {
            int i = 0;

            do
            {
                pbi->common.fc.uv_mode_prob[i] =
                    (vp8_prob) vp8_read_literal(bc, 8);
            }
            while (++i < 3);
        }

        read_mvcontexts(bc, mvc);
    }
}

const vp8_prob vp8_sub_mv_ref_prob3 [8][VP8_SUBMVREFS-1] =
{
    { 147, 136, 18 },   /* SUBMVREF_NORMAL          */
    { 223, 1  , 34 },   /* SUBMVREF_LEFT_ABOVE_SAME */
    { 106, 145, 1  },   /* SUBMVREF_LEFT_ZED        */
    { 208, 1  , 1  },   /* SUBMVREF_LEFT_ABOVE_ZED  */
    { 179, 121, 1  },   /* SUBMVREF_ABOVE_ZED       */
    { 223, 1  , 34 },   /* SUBMVREF_LEFT_ABOVE_SAME */
    { 179, 121, 1  },   /* SUBMVREF_ABOVE_ZED       */
    { 208, 1  , 1  }    /* SUBMVREF_LEFT_ABOVE_ZED  */
};

static
const vp8_prob * get_sub_mv_ref_prob(const int left, const int above)
{
    int lez = (left == 0);
    int aez = (above == 0);
    int lea = (left == above);
    const vp8_prob * prob;

    prob = vp8_sub_mv_ref_prob3[(aez << 2) |
                                (lez << 1) |
                                (lea)];

    return prob;
}

static void decode_split_mv(vp8_reader *const bc, MODE_INFO *mi,
                        const MODE_INFO *left_mb, const MODE_INFO *above_mb,
                        MB_MODE_INFO *mbmi, int_mv best_mv,
                        MV_CONTEXT *const mvc, int mb_to_left_edge,
                        int mb_to_right_edge, int mb_to_top_edge,
                        int mb_to_bottom_edge)
{
    int s;      /* split configuration (16x8, 8x16, 8x8, 4x4) */
    int num_p;  /* number of partitions in the split configuration
                  (see vp8_mbsplit_count) */
    int j = 0;

    s = 3;
    num_p = 16;
    if( vp8_read(bc, 110) )
    {
        s = 2;
        num_p = 4;
        if( vp8_read(bc, 111) )
        {
            s = vp8_read(bc, 150);
            num_p = 2;
        }
    }

    do  /* for each subset j */
    {
        int_mv leftmv, abovemv;
        int_mv blockmv;
        int k;  /* first block in subset j */

        const vp8_prob *prob;
        k = vp8_mbsplit_offset[s][j];

        if (!(k & 3))
        {
            /* On L edge, get from MB to left of us */
            if(left_mb->mbmi.mode != SPLITMV)
                leftmv.as_int =  left_mb->mbmi.mv.as_int;
            else
                leftmv.as_int =  (left_mb->bmi + k + 4 - 1)->mv.as_int;
        }
        else
            leftmv.as_int =  (mi->bmi + k - 1)->mv.as_int;

        if (!(k >> 2))
        {
            /* On top edge, get from MB above us */
            if(above_mb->mbmi.mode != SPLITMV)
                abovemv.as_int =  above_mb->mbmi.mv.as_int;
            else
                abovemv.as_int =  (above_mb->bmi + k + 16 - 4)->mv.as_int;
        }
        else
            abovemv.as_int = (mi->bmi + k - 4)->mv.as_int;

        prob = get_sub_mv_ref_prob(leftmv.as_int, abovemv.as_int);

        if( vp8_read(bc, prob[0]) )
        {
            if( vp8_read(bc, prob[1]) )
            {
                blockmv.as_int = 0;
                if( vp8_read(bc, prob[2]) )
                {
                    blockmv.as_mv.row = read_mvcomponent(bc, &mvc[0]) << 1;
                    blockmv.as_mv.row += best_mv.as_mv.row;
                    blockmv.as_mv.col = read_mvcomponent(bc, &mvc[1]) << 1;
                    blockmv.as_mv.col += best_mv.as_mv.col;

                    mbmi->need_to_clamp_mvs |= vp8_check_mv_bounds(&blockmv,
                                                              mb_to_left_edge,
                                                              mb_to_right_edge,
                                                              mb_to_top_edge,
                                                              mb_to_bottom_edge);
                }
            }
            else
            {
                blockmv.as_int = abovemv.as_int;
                mbmi->need_to_clamp_mvs |= above_mb->mbmi.need_to_clamp_mvs;
            }
        }
        else
        {
            blockmv.as_int = leftmv.as_int;
            mbmi->need_to_clamp_mvs |= left_mb->mbmi.need_to_clamp_mvs;
        }

        {
            /* Fill (uniform) modes, mvs of jth subset.
             Must do it here because ensuing subsets can
             refer back to us via "left" or "above". */
            const unsigned char *fill_offset;
            unsigned int fill_count = mbsplit_fill_count[s];

            fill_offset = &mbsplit_fill_offset[s]
                             [(unsigned char)j * mbsplit_fill_count[s]];

            do {
                mi->bmi[ *fill_offset].mv.as_int = blockmv.as_int;
                fill_offset++;
            }while (--fill_count);
        }

    }
    while (++j < num_p);

    mbmi->partitioning = s;
}

static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi)
{
    vp8_reader *const bc = & pbi->bc;
    mbmi->ref_frame = (MV_REFERENCE_FRAME) vp8_read(bc, pbi->prob_intra);
    if (mbmi->ref_frame)    /* inter MB */
    {
        enum {CNT_INTRA, CNT_NEAREST, CNT_NEAR, CNT_SPLITMV};
        int cnt[4];
        int *cntx = cnt;
        int_mv near_mvs[4];
        int_mv *nmv = near_mvs;
        const int mis = pbi->mb.mode_info_stride;
        const MODE_INFO *above = mi - mis;
        const MODE_INFO *left = mi - 1;
        const MODE_INFO *aboveleft = above - 1;
        int *ref_frame_sign_bias = pbi->common.ref_frame_sign_bias;

        mbmi->need_to_clamp_mvs = 0;

        if (vp8_read(bc, pbi->prob_last))
        {
            mbmi->ref_frame =
                (MV_REFERENCE_FRAME)((int)(2 + vp8_read(bc, pbi->prob_gf)));
        }

        /* Zero accumulators */
        nmv[0].as_int = nmv[1].as_int = nmv[2].as_int = 0;
        cnt[0] = cnt[1] = cnt[2] = cnt[3] = 0;

        /* Process above */
        if (above->mbmi.ref_frame != INTRA_FRAME)
        {
            if (above->mbmi.mv.as_int)
            {
                (++nmv)->as_int = above->mbmi.mv.as_int;
                mv_bias(ref_frame_sign_bias[above->mbmi.ref_frame],
                        mbmi->ref_frame, nmv, ref_frame_sign_bias);
                ++cntx;
            }

            *cntx += 2;
        }

        /* Process left */
        if (left->mbmi.ref_frame != INTRA_FRAME)
        {
            if (left->mbmi.mv.as_int)
            {
                int_mv this_mv;

                this_mv.as_int = left->mbmi.mv.as_int;
                mv_bias(ref_frame_sign_bias[left->mbmi.ref_frame],
                        mbmi->ref_frame, &this_mv, ref_frame_sign_bias);

                if (this_mv.as_int != nmv->as_int)
                {
                    (++nmv)->as_int = this_mv.as_int;
                    ++cntx;
                }

                *cntx += 2;
            }
            else
                cnt[CNT_INTRA] += 2;
        }

        /* Process above left */
        if (aboveleft->mbmi.ref_frame != INTRA_FRAME)
        {
            if (aboveleft->mbmi.mv.as_int)
            {
                int_mv this_mv;

                this_mv.as_int = aboveleft->mbmi.mv.as_int;
                mv_bias(ref_frame_sign_bias[aboveleft->mbmi.ref_frame],
                        mbmi->ref_frame, &this_mv, ref_frame_sign_bias);

                if (this_mv.as_int != nmv->as_int)
                {
                    (++nmv)->as_int = this_mv.as_int;
                    ++cntx;
                }

                *cntx += 1;
            }
            else
                cnt[CNT_INTRA] += 1;
        }

        if( vp8_read(bc, vp8_mode_contexts [cnt[CNT_INTRA]] [0]) )
        {

            /* If we have three distinct MV's ... */
            /* See if above-left MV can be merged with NEAREST */
            cnt[CNT_NEAREST] += ( (cnt[CNT_SPLITMV] > 0) &
                (nmv->as_int == near_mvs[CNT_NEAREST].as_int));

            /* Swap near and nearest if necessary */
            if (cnt[CNT_NEAR] > cnt[CNT_NEAREST])
            {
                int tmp;
                tmp = cnt[CNT_NEAREST];
                cnt[CNT_NEAREST] = cnt[CNT_NEAR];
                cnt[CNT_NEAR] = tmp;
                tmp = near_mvs[CNT_NEAREST].as_int;
                near_mvs[CNT_NEAREST].as_int = near_mvs[CNT_NEAR].as_int;
                near_mvs[CNT_NEAR].as_int = tmp;
            }

            if( vp8_read(bc, vp8_mode_contexts [cnt[CNT_NEAREST]] [1]) )
            {

                if( vp8_read(bc, vp8_mode_contexts [cnt[CNT_NEAR]] [2]) )
                {
                    int mb_to_top_edge;
                    int mb_to_bottom_edge;
                    int mb_to_left_edge;
                    int mb_to_right_edge;
                    MV_CONTEXT *const mvc = pbi->common.fc.mvc;
                    int near_index;

                    mb_to_top_edge = pbi->mb.mb_to_top_edge;
                    mb_to_bottom_edge = pbi->mb.mb_to_bottom_edge;
                    mb_to_top_edge -= LEFT_TOP_MARGIN;
                    mb_to_bottom_edge += RIGHT_BOTTOM_MARGIN;
                    mb_to_right_edge = pbi->mb.mb_to_right_edge;
                    mb_to_right_edge += RIGHT_BOTTOM_MARGIN;
                    mb_to_left_edge = pbi->mb.mb_to_left_edge;
                    mb_to_left_edge -= LEFT_TOP_MARGIN;

                    /* Use near_mvs[0] to store the "best" MV */
                    near_index = CNT_INTRA +
                        (cnt[CNT_NEAREST] >= cnt[CNT_INTRA]);

                    vp8_clamp_mv2(&near_mvs[near_index], &pbi->mb);

                    cnt[CNT_SPLITMV] = ((above->mbmi.mode == SPLITMV)
                                        + (left->mbmi.mode == SPLITMV)) * 2
                                       + (aboveleft->mbmi.mode == SPLITMV);

                    if( vp8_read(bc, vp8_mode_contexts [cnt[CNT_SPLITMV]] [3]) )
                    {
                        decode_split_mv(bc, mi, left, above,
                                                    mbmi,
                                                    near_mvs[near_index],
                                                    mvc, mb_to_left_edge,
                                                    mb_to_right_edge,
                                                    mb_to_top_edge,
                                                    mb_to_bottom_edge);
                        mbmi->mv.as_int = mi->bmi[15].mv.as_int;
                        mbmi->mode =  SPLITMV;
                        mbmi->is_4x4 = 1;
                    }
                    else
                    {
                        int_mv *const mbmi_mv = & mbmi->mv;
                        read_mv(bc, &mbmi_mv->as_mv, (const MV_CONTEXT *) mvc);
                        mbmi_mv->as_mv.row += near_mvs[near_index].as_mv.row;
                        mbmi_mv->as_mv.col += near_mvs[near_index].as_mv.col;

                        /* Don't need to check this on NEARMV and NEARESTMV
                         * modes since those modes clamp the MV. The NEWMV mode
                         * does not, so signal to the prediction stage whether
                         * special handling may be required.
                         */
                        mbmi->need_to_clamp_mvs =
                            vp8_check_mv_bounds(mbmi_mv, mb_to_left_edge,
                                                mb_to_right_edge,
                                                mb_to_top_edge,
                                                mb_to_bottom_edge);
                        mbmi->mode =  NEWMV;
                    }
                }
                else
                {
                    mbmi->mode =  NEARMV;
                    vp8_clamp_mv2(&near_mvs[CNT_NEAR], &pbi->mb);
                    mbmi->mv.as_int = near_mvs[CNT_NEAR].as_int;
                }
            }
            else
            {
                mbmi->mode =  NEARESTMV;
                vp8_clamp_mv2(&near_mvs[CNT_NEAREST], &pbi->mb);
                mbmi->mv.as_int = near_mvs[CNT_NEAREST].as_int;
            }
        }
        else
        {
            mbmi->mode =  ZEROMV;
            mbmi->mv.as_int = 0;
        }

#if CONFIG_ERROR_CONCEALMENT
        if(pbi->ec_enabled && (mbmi->mode != SPLITMV))
        {
            mi->bmi[ 0].mv.as_int =
            mi->bmi[ 1].mv.as_int =
            mi->bmi[ 2].mv.as_int =
            mi->bmi[ 3].mv.as_int =
            mi->bmi[ 4].mv.as_int =
            mi->bmi[ 5].mv.as_int =
            mi->bmi[ 6].mv.as_int =
            mi->bmi[ 7].mv.as_int =
            mi->bmi[ 8].mv.as_int =
            mi->bmi[ 9].mv.as_int =
            mi->bmi[10].mv.as_int =
            mi->bmi[11].mv.as_int =
            mi->bmi[12].mv.as_int =
            mi->bmi[13].mv.as_int =
            mi->bmi[14].mv.as_int =
            mi->bmi[15].mv.as_int = mbmi->mv.as_int;
        }
#endif
    }
    else
    {
        /* required for left and above block mv */
        mbmi->mv.as_int = 0;

        /* MB is intra coded */
        if ((mbmi->mode = read_ymode(bc, pbi->common.fc.ymode_prob)) == B_PRED)
        {
            int j = 0;
            mbmi->is_4x4 = 1;
            do
            {
                mi->bmi[j].as_mode = read_bmode(bc, pbi->common.fc.bmode_prob);
            }
            while (++j < 16);
        }

        mbmi->uv_mode = read_uv_mode(bc, pbi->common.fc.uv_mode_prob);
    }

}

static void read_mb_features(vp8_reader *r, MB_MODE_INFO *mi, MACROBLOCKD *x)
{
    /* Is segmentation enabled */
    if (x->segmentation_enabled && x->update_mb_segmentation_map)
    {
        /* If so then read the segment id. */
        if (vp8_read(r, x->mb_segment_tree_probs[0]))
            mi->segment_id =
                (unsigned char)(2 + vp8_read(r, x->mb_segment_tree_probs[2]));
        else
            mi->segment_id =
                (unsigned char)(vp8_read(r, x->mb_segment_tree_probs[1]));
    }
}

static void decode_mb_mode_mvs(VP8D_COMP *pbi, MODE_INFO *mi,
                               MB_MODE_INFO *mbmi)
{
    /* Read the Macroblock segmentation map if it is being updated explicitly
     * this frame (reset to 0 above by default)
     * By default on a key frame reset all MBs to segment 0
     */
    if (pbi->mb.update_mb_segmentation_map)
        read_mb_features(&pbi->bc, &mi->mbmi, &pbi->mb);
    else if(pbi->common.frame_type == KEY_FRAME)
        mi->mbmi.segment_id = 0;

    /* Read the macroblock coeff skip flag if this feature is in use,
     * else default to 0 */
    if (pbi->common.mb_no_coeff_skip)
        mi->mbmi.mb_skip_coeff = vp8_read(&pbi->bc, pbi->prob_skip_false);
    else
        mi->mbmi.mb_skip_coeff = 0;

    mi->mbmi.is_4x4 = 0;
    if(pbi->common.frame_type == KEY_FRAME)
        read_kf_modes(pbi, mi);
    else
        read_mb_modes_mv(pbi, mi, &mi->mbmi);

}

void vp8_decode_mode_mvs(VP8D_COMP *pbi)
{
    MODE_INFO *mi = pbi->common.mi;
    int mb_row = -1;
    int mb_to_right_edge_start;

    mb_mode_mv_init(pbi);

    pbi->mb.mb_to_top_edge = 0;
    pbi->mb.mb_to_bottom_edge = ((pbi->common.mb_rows - 1) * 16) << 3;
    mb_to_right_edge_start = ((pbi->common.mb_cols - 1) * 16) << 3;

    while (++mb_row < pbi->common.mb_rows)
    {
        int mb_col = -1;

        pbi->mb.mb_to_left_edge =  0;
        pbi->mb.mb_to_right_edge = mb_to_right_edge_start;

        while (++mb_col < pbi->common.mb_cols)
        {
#if CONFIG_ERROR_CONCEALMENT
            int mb_num = mb_row * pbi->common.mb_cols + mb_col;
#endif

            decode_mb_mode_mvs(pbi, mi, &mi->mbmi);

#if CONFIG_ERROR_CONCEALMENT
            /* look for corruption. set mvs_corrupt_from_mb to the current
             * mb_num if the frame is corrupt from this macroblock. */
            if (vp8dx_bool_error(&pbi->bc) && mb_num < pbi->mvs_corrupt_from_mb)
            {
                pbi->mvs_corrupt_from_mb = mb_num;
                /* no need to continue since the partition is corrupt from
                 * here on.
                 */
                return;
            }
#endif

            pbi->mb.mb_to_left_edge -= (16 << 3);
            pbi->mb.mb_to_right_edge -= (16 << 3);
            mi++;       /* next macroblock */
        }
        pbi->mb.mb_to_top_edge -= (16 << 3);
        pbi->mb.mb_to_bottom_edge -= (16 << 3);

        mi++;           /* skip left predictor each row */
    }
}
