/*
 *  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 <math.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "onyx_int.h"
#include "tokenize.h"
#include "vpx_mem/vpx_mem.h"

/* Global event counters used for accumulating statistics across several
   compressions, then generating context.c = initial stats. */

#ifdef ENTROPY_STATS
_int64 context_counters[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [vp8_coef_tokens];
#endif
void vp8_stuff_mb(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t) ;
void vp8_fix_contexts(VP8_COMP *cpi, MACROBLOCKD *x);

TOKENEXTRA vp8_dct_value_tokens[DCT_MAX_VALUE*2];
TOKENEXTRA *vp8_dct_value_tokens_ptr;
int vp8_dct_value_cost[DCT_MAX_VALUE*2];
int *vp8_dct_value_cost_ptr;
#if 0
int skip_true_count = 0;
int skip_false_count = 0;
#endif
static void fill_value_tokens()
{

    TOKENEXTRA *const t = vp8_dct_value_tokens + DCT_MAX_VALUE;
    vp8_extra_bit_struct *const e = vp8_extra_bits;

    int i = -DCT_MAX_VALUE;
    int sign = 1;

    do
    {
        if (!i)
            sign = 0;

        {
            const int a = sign ? -i : i;
            int eb = sign;

            if (a > 4)
            {
                int j = 4;

                while (++j < 11  &&  e[j].base_val <= a) {}

                t[i].Token = --j;
                eb |= (a - e[j].base_val) << 1;
            }
            else
                t[i].Token = a;

            t[i].Extra = eb;
        }

        // initialize the cost for extra bits for all possible coefficient value.
        {
            int cost = 0;
            vp8_extra_bit_struct *p = vp8_extra_bits + t[i].Token;

            if (p->base_val)
            {
                const int extra = t[i].Extra;
                const int Length = p->Len;

                if (Length)
                    cost += vp8_treed_cost(p->tree, p->prob, extra >> 1, Length);

                cost += vp8_cost_bit(vp8_prob_half, extra & 1); /* sign */
                vp8_dct_value_cost[i + DCT_MAX_VALUE] = cost;
            }

        }

    }
    while (++i < DCT_MAX_VALUE);

    vp8_dct_value_tokens_ptr = vp8_dct_value_tokens + DCT_MAX_VALUE;
    vp8_dct_value_cost_ptr   = vp8_dct_value_cost + DCT_MAX_VALUE;
}

static void tokenize2nd_order_b
(
    const BLOCKD *const b,
    TOKENEXTRA **tp,
    const int type,     /* which plane: 0=Y no DC, 1=Y2, 2=UV, 3=Y with DC */
    const FRAME_TYPE frametype,
    ENTROPY_CONTEXT *a,
    ENTROPY_CONTEXT *l,
    VP8_COMP *cpi
)
{
    int pt; /* near block/prev token context index */
    int c = 0;          /* start at DC */
    const int eob = b->eob;     /* one beyond last nonzero coeff */
    TOKENEXTRA *t = *tp;        /* store tokens starting here */
    int x;
    const short *qcoeff_ptr = b->qcoeff;
    VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l);

    do
    {
        const int band = vp8_coef_bands[c];

        if (c < eob)
        {
            int rc = vp8_default_zig_zag1d[c];
            const int v = qcoeff_ptr[rc];

            assert(-DCT_MAX_VALUE <= v  &&  v < (DCT_MAX_VALUE));

            t->Extra = vp8_dct_value_tokens_ptr[v].Extra;
            x        = vp8_dct_value_tokens_ptr[v].Token;
        }
        else
            x = DCT_EOB_TOKEN;

        t->Token = x;
        t->context_tree = cpi->common.fc.coef_probs [type] [band] [pt];

        t->section = frametype * BLOCK_TYPES * 2 + 2 * type + (c == 0);

        t->skip_eob_node = pt == 0 && ((band > 0 && type > 0) || (band > 1 && type == 0));

        ++cpi->coef_counts       [type] [band] [pt] [x];
    }
    while (pt = vp8_prev_token_class[x], ++t, c < eob  &&  ++c < 16);

    *tp = t;
    pt = (c != !type); /* 0 <-> all coeff data is zero */
    *a = *l = pt;

}

static void tokenize1st_order_b
(
    const BLOCKD *const b,
    TOKENEXTRA **tp,
    const int type,     /* which plane: 0=Y no DC, 1=Y2, 2=UV, 3=Y with DC */
    const FRAME_TYPE frametype,
    ENTROPY_CONTEXT *a,
    ENTROPY_CONTEXT *l,
    VP8_COMP *cpi
)
{
    int pt; /* near block/prev token context index */
    int c = type ? 0 : 1;       /* start at DC unless type 0 */
    const int eob = b->eob;     /* one beyond last nonzero coeff */
    TOKENEXTRA *t = *tp;        /* store tokens starting here */
    int x;
    const short *qcoeff_ptr = b->qcoeff;
    VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l);

    do
    {
        const int band = vp8_coef_bands[c];

        x = DCT_EOB_TOKEN;

        if (c < eob)
        {
            int rc = vp8_default_zig_zag1d[c];
            const int v = qcoeff_ptr[rc];

            assert(-DCT_MAX_VALUE <= v  &&  v < (DCT_MAX_VALUE));

            t->Extra = vp8_dct_value_tokens_ptr[v].Extra;
            x        = vp8_dct_value_tokens_ptr[v].Token;
        }

        t->Token = x;
        t->context_tree = cpi->common.fc.coef_probs [type] [band] [pt];

        t->section = frametype * BLOCK_TYPES * 2 + 2 * type + (c == 0);
        t->skip_eob_node = pt == 0 && ((band > 0 && type > 0) || (band > 1 && type == 0));

        ++cpi->coef_counts       [type] [band] [pt] [x];
    }
    while (pt = vp8_prev_token_class[x], ++t, c < eob  &&  ++c < 16);

    *tp = t;
    pt = (c != !type); /* 0 <-> all coeff data is zero */
    *a = *l = pt;

}
#if 0
void vp8_tokenize_mb(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t)
{
    //int i;
    ENTROPY_CONTEXT **const A = x->above_context;
    ENTROPY_CONTEXT(* const L)[4] = x->left_context;
    int plane_type;
    int b;

    TOKENEXTRA *start = *t;
    TOKENEXTRA *tp = *t;

    x->mbmi.dc_diff = 1;

    vpx_memcpy(cpi->coef_counts_backup, cpi->coef_counts, sizeof(cpi->coef_counts));

    if (x->mbmi.mode == B_PRED || x->mbmi.mode == SPLITMV)
    {
        plane_type = 3;
    }
    else
    {
        tokenize2nd_order_b(x->block + 24, t, 1, x->frame_type,
                            A[Y2CONTEXT] + vp8_block2above[24], L[Y2CONTEXT] + vp8_block2left[24], cpi);
        plane_type = 0;

    }

    for (b = 0; b < 16; b++)
        tokenize1st_order_b(x->block + b, t, plane_type, x->frame_type,
                            A[vp8_block2context[b]] + vp8_block2above[b],
                            L[vp8_block2context[b]] + vp8_block2left[b], cpi);

    for (b = 16; b < 24; b++)
        tokenize1st_order_b(x->block + b, t, 2, x->frame_type,
                            A[vp8_block2context[b]] + vp8_block2above[b],
                            L[vp8_block2context[b]] + vp8_block2left[b], cpi);

    if (cpi->common.mb_no_coeff_skip)
    {
        x->mbmi.mb_skip_coeff = 1;

        while ((tp != *t) && x->mbmi.mb_skip_coeff)
        {
            x->mbmi.mb_skip_coeff = (x->mbmi.mb_skip_coeff && (tp->Token == DCT_EOB_TOKEN));
            tp ++;
        }

        if (x->mbmi.mb_skip_coeff == 1)
        {
            x->mbmi.dc_diff = 0;
            //redo the coutnts
            vpx_memcpy(cpi->coef_counts, cpi->coef_counts_backup, sizeof(cpi->coef_counts));

            *t = start;
            cpi->skip_true_count++;

            //skip_true_count++;
        }
        else
        {

            cpi->skip_false_count++;
            //skip_false_count++;
        }
    }
}
#else
void vp8_tokenize_mb(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t)
{
    //int i;
    ENTROPY_CONTEXT **const A = x->above_context;
    ENTROPY_CONTEXT(* const L)[4] = x->left_context;
    int plane_type;
    int b;

    TOKENEXTRA *start = *t;
    TOKENEXTRA *tp = *t;

    x->mbmi.dc_diff = 1;

#if 0

    if (x->mbmi.force_no_skip)
    {
        x->mbmi.mb_skip_coeff = 1;
        //reset for next_mb.
        x->mbmi.force_no_skip = 0;
    }

#endif

#if 1

    if (x->mbmi.mb_skip_coeff)
    {

        cpi->skip_true_count++;

        if (!cpi->common.mb_no_coeff_skip)
            vp8_stuff_mb(cpi, x, t) ;
        else
        {
            vp8_fix_contexts(cpi, x);
        }

        if (x->mbmi.mode != B_PRED && x->mbmi.mode != SPLITMV)
            x->mbmi.dc_diff = 0;
        else
            x->mbmi.dc_diff = 1;


        return;
    }

    cpi->skip_false_count++;
#endif
#if 0

    if (x->mbmi.mode == B_PRED || x->mbmi.mode == SPLITMV)
    {
        int i, skip = 1;

        for (i = 0; i < 24; i++)
            skip &= (!x->block[i].eob);

        if (skip != x->mbmi.mb_skip_coeff)
            skip += 0;

        x->mbmi.mb_skip_coeff = skip;
    }
    else
    {
        int i, skip = 1;

        for (i = 0; i < 16; i++)
            skip &= (x->block[i].eob < 2);

        for (i = 16; i < 25; i++)
            skip &= (!x->block[i].eob);

        if (skip != x->mbmi.mb_skip_coeff)
            skip += 0;

        x->mbmi.mb_skip_coeff = skip;
    }

    vpx_memcpy(cpi->coef_counts_backup, cpi->coef_counts, sizeof(cpi->coef_counts));
#endif

    if (x->mbmi.mode == B_PRED || x->mbmi.mode == SPLITMV)
    {
        plane_type = 3;
    }
    else
    {
        tokenize2nd_order_b(x->block + 24, t, 1, x->frame_type,
                            A[Y2CONTEXT] + vp8_block2above[24], L[Y2CONTEXT] + vp8_block2left[24], cpi);
        plane_type = 0;

    }

    for (b = 0; b < 16; b++)
        tokenize1st_order_b(x->block + b, t, plane_type, x->frame_type,
                            A[vp8_block2context[b]] + vp8_block2above[b],
                            L[vp8_block2context[b]] + vp8_block2left[b], cpi);

    for (b = 16; b < 24; b++)
        tokenize1st_order_b(x->block + b, t, 2, x->frame_type,
                            A[vp8_block2context[b]] + vp8_block2above[b],
                            L[vp8_block2context[b]] + vp8_block2left[b], cpi);

#if 0

    if (cpi->common.mb_no_coeff_skip)
    {
        int skip = 1;

        while ((tp != *t) && skip)
        {
            skip = (skip && (tp->Token == DCT_EOB_TOKEN));
            tp ++;
        }

        if (skip != x->mbmi.mb_skip_coeff)
            skip += 0;

        x->mbmi.mb_skip_coeff = skip;

        if (x->mbmi.mb_skip_coeff == 1)
        {
            x->mbmi.dc_diff = 0;
            //redo the coutnts
            vpx_memcpy(cpi->coef_counts, cpi->coef_counts_backup, sizeof(cpi->coef_counts));

            *t = start;
            cpi->skip_true_count++;
            //skip_true_count++;
        }
        else
        {

            cpi->skip_false_count++;
            //skip_false_count++;
        }
    }

#endif
}
#endif

#ifdef ENTROPY_STATS

void init_context_counters(void)
{
    vpx_memset(context_counters, 0, sizeof(context_counters));
}

void print_context_counters()
{

    int type, band, pt, t;

    FILE *const f = fopen("context.c", "w");

    fprintf(f, "#include \"entropy.h\"\n");

    fprintf(f, "\n/* *** GENERATED FILE: DO NOT EDIT *** */\n\n");

    fprintf(f, "int Contexts[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [vp8_coef_tokens];\n\n");

    fprintf(f, "const int default_contexts[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [vp8_coef_tokens] = {");

# define Comma( X) (X? ",":"")

    type = 0;

    do
    {
        fprintf(f, "%s\n  { /* block Type %d */", Comma(type), type);

        band = 0;

        do
        {
            fprintf(f, "%s\n    { /* Coeff Band %d */", Comma(band), band);

            pt = 0;

            do
            {
                fprintf(f, "%s\n      {", Comma(pt));

                t = 0;

                do
                {
                    const _int64 x = context_counters [type] [band] [pt] [t];
                    const int y = (int) x;

                    assert(x == (_int64) y);  /* no overflow handling yet */
                    fprintf(f, "%s %d", Comma(t), y);

                }
                while (++t < vp8_coef_tokens);

                fprintf(f, "}");
            }
            while (++pt < PREV_COEF_CONTEXTS);

            fprintf(f, "\n    }");

        }
        while (++band < COEF_BANDS);

        fprintf(f, "\n  }");
    }
    while (++type < BLOCK_TYPES);

    fprintf(f, "\n};\n");
    fclose(f);
}
#endif


void vp8_tokenize_initialize()
{
    fill_value_tokens();
}


static __inline void stuff2nd_order_b
(
    const BLOCKD *const b,
    TOKENEXTRA **tp,
    const int type,     /* which plane: 0=Y no DC, 1=Y2, 2=UV, 3=Y with DC */
    const FRAME_TYPE frametype,
    ENTROPY_CONTEXT *a,
    ENTROPY_CONTEXT *l,
    VP8_COMP *cpi
)
{
    int pt; /* near block/prev token context index */
    TOKENEXTRA *t = *tp;        /* store tokens starting here */
    VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l);
    (void) frametype;
    (void) type;
    (void) b;

    t->Token = DCT_EOB_TOKEN;
    t->context_tree = cpi->common.fc.coef_probs [1] [0] [pt];
    t->section = 11;
    t->skip_eob_node = 0;
    ++cpi->coef_counts       [1] [0] [pt] [DCT_EOB_TOKEN];
    ++t;

    *tp = t;
    pt = 0;
    *a = *l = pt;

}

static __inline void stuff1st_order_b
(
    const BLOCKD *const b,
    TOKENEXTRA **tp,
    const int type,     /* which plane: 0=Y no DC, 1=Y2, 2=UV, 3=Y with DC */
    const FRAME_TYPE frametype,
    ENTROPY_CONTEXT *a,
    ENTROPY_CONTEXT *l,
    VP8_COMP *cpi
)
{
    int pt; /* near block/prev token context index */
    TOKENEXTRA *t = *tp;        /* store tokens starting here */
    VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l);
    (void) frametype;
    (void) type;
    (void) b;

    t->Token = DCT_EOB_TOKEN;
    t->context_tree = cpi->common.fc.coef_probs [0] [1] [pt];
    t->section = 8;
    t->skip_eob_node = 0;
    ++cpi->coef_counts       [0] [1] [pt] [DCT_EOB_TOKEN];
    ++t;
    *tp = t;
    pt = 0; /* 0 <-> all coeff data is zero */
    *a = *l = pt;

}
static __inline
void stuff1st_order_buv
(
    const BLOCKD *const b,
    TOKENEXTRA **tp,
    const int type,     /* which plane: 0=Y no DC, 1=Y2, 2=UV, 3=Y with DC */
    const FRAME_TYPE frametype,
    ENTROPY_CONTEXT *a,
    ENTROPY_CONTEXT *l,
    VP8_COMP *cpi
)
{
    int pt; /* near block/prev token context index */
    TOKENEXTRA *t = *tp;        /* store tokens starting here */
    VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l);
    (void) frametype;
    (void) type;
    (void) b;

    t->Token = DCT_EOB_TOKEN;
    t->context_tree = cpi->common.fc.coef_probs [2] [0] [pt];
    t->section = 13;
    t->skip_eob_node = 0;
    ++cpi->coef_counts[2] [0] [pt] [DCT_EOB_TOKEN];
    ++t;
    *tp = t;
    pt = 0; /* 0 <-> all coeff data is zero */
    *a = *l = pt;

}

void vp8_stuff_mb(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t)
{
    //int i;
    ENTROPY_CONTEXT **const A = x->above_context;
    ENTROPY_CONTEXT(* const L)[4] = x->left_context;
    int plane_type;
    int b;

    stuff2nd_order_b(x->block + 24, t, 1, x->frame_type,
                     A[Y2CONTEXT] + vp8_block2above[24], L[Y2CONTEXT] + vp8_block2left[24], cpi);
    plane_type = 0;


    if (x->mbmi.mode != B_PRED && x->mbmi.mode != SPLITMV)
        x->mbmi.dc_diff = 0;
    else
        x->mbmi.dc_diff = 1;


    for (b = 0; b < 16; b++)
        stuff1st_order_b(x->block + b, t, plane_type, x->frame_type,
                         A[vp8_block2context[b]] + vp8_block2above[b],
                         L[vp8_block2context[b]] + vp8_block2left[b], cpi);

    for (b = 16; b < 24; b++)
        stuff1st_order_buv(x->block + b, t, 2, x->frame_type,
                           A[vp8_block2context[b]] + vp8_block2above[b],
                           L[vp8_block2context[b]] + vp8_block2left[b], cpi);

}
void vp8_fix_contexts(VP8_COMP *cpi, MACROBLOCKD *x)
{
    x->left_context[Y1CONTEXT][0] = 0;
    x->left_context[Y1CONTEXT][1] = 0;
    x->left_context[Y1CONTEXT][2] = 0;
    x->left_context[Y1CONTEXT][3] = 0;
    x->left_context[UCONTEXT][0]  = 0;
    x->left_context[VCONTEXT][0]  = 0;
    x->left_context[UCONTEXT][1]  = 0;
    x->left_context[VCONTEXT][1]  = 0;

    x->above_context[Y1CONTEXT][0] = 0;
    x->above_context[Y1CONTEXT][1] = 0;
    x->above_context[Y1CONTEXT][2] = 0;
    x->above_context[Y1CONTEXT][3] = 0;
    x->above_context[UCONTEXT][0]  = 0;
    x->above_context[VCONTEXT][0]  = 0;
    x->above_context[UCONTEXT][1]  = 0;
    x->above_context[VCONTEXT][1]  = 0;

    if (x->mbmi.mode != B_PRED && x->mbmi.mode != SPLITMV)
    {
        x->left_context[Y2CONTEXT][0] = 0;
        x->above_context[Y2CONTEXT][0] = 0;
    }
}
