/*
 *  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 "vp8/common/blockd.h"
#include "onyxd_int.h"
#include "vpx_mem/vpx_mem.h"
#include "vpx_ports/mem.h"
#include "detokenize.h"

void vp8_reset_mb_tokens_context(MACROBLOCKD *x)
{
    ENTROPY_CONTEXT *a_ctx = ((ENTROPY_CONTEXT *)x->above_context);
    ENTROPY_CONTEXT *l_ctx = ((ENTROPY_CONTEXT *)x->left_context);

    vpx_memset(a_ctx, 0, sizeof(ENTROPY_CONTEXT_PLANES)-1);
    vpx_memset(l_ctx, 0, sizeof(ENTROPY_CONTEXT_PLANES)-1);

    /* Clear entropy contexts for Y2 blocks */
    if (!x->mode_info_context->mbmi.is_4x4)
    {
        a_ctx[8] = l_ctx[8] = 0;
    }
}

/*
    ------------------------------------------------------------------------------
    Residual decoding (Paragraph 13.2 / 13.3)
*/
static const uint8_t kBands[16 + 1] = {
  0, 1, 2, 3, 6, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 7,
  0  /* extra entry as sentinel */
};

static const uint8_t kCat3[] = { 173, 148, 140, 0 };
static const uint8_t kCat4[] = { 176, 155, 140, 135, 0 };
static const uint8_t kCat5[] = { 180, 157, 141, 134, 130, 0 };
static const uint8_t kCat6[] =
  { 254, 254, 243, 230, 196, 177, 153, 140, 133, 130, 129, 0 };
static const uint8_t* const kCat3456[] = { kCat3, kCat4, kCat5, kCat6 };
static const uint8_t kZigzag[16] = {
  0, 1, 4, 8,  5, 2, 3, 6,  9, 12, 13, 10,  7, 11, 14, 15
};

#define VP8GetBit vp8dx_decode_bool
#define NUM_PROBAS  11
#define NUM_CTX  3

/* for const-casting */
typedef const uint8_t (*ProbaArray)[NUM_CTX][NUM_PROBAS];

static int GetSigned(BOOL_DECODER *br, int value_to_sign)
{
    int split = (br->range + 1) >> 1;
    VP8_BD_VALUE bigsplit = (VP8_BD_VALUE)split << (VP8_BD_VALUE_SIZE - 8);
    int v;

    if(br->count < 0)
        vp8dx_bool_decoder_fill(br);

    if ( br->value < bigsplit )
    {
        br->range = split;
        v= value_to_sign;
    }
    else
    {
        br->range = br->range-split;
        br->value = br->value-bigsplit;
        v = -value_to_sign;
    }
    br->range +=br->range;
    br->value +=br->value;
    br->count--;

    return v;
}
/*
   Returns the position of the last non-zero coeff plus one
   (and 0 if there's no coeff at all)
*/
static int GetCoeffs(BOOL_DECODER *br, ProbaArray prob,
                     int ctx, int n, int16_t* out)
{
    const uint8_t* p = prob[n][ctx];
    if (!VP8GetBit(br, p[0]))
    {   /* first EOB is more a 'CBP' bit. */
        return 0;
    }
    while (1)
    {
        ++n;
        if (!VP8GetBit(br, p[1]))
        {
            p = prob[kBands[n]][0];
        }
        else
        {  /* non zero coeff */
            int v, j;
            if (!VP8GetBit(br, p[2]))
            {
                p = prob[kBands[n]][1];
                v = 1;
            }
            else
            {
                if (!VP8GetBit(br, p[3]))
                {
                    if (!VP8GetBit(br, p[4]))
                    {
                        v = 2;
                    }
                    else
                    {
                        v = 3 + VP8GetBit(br, p[5]);
                    }
                }
                else
                {
                    if (!VP8GetBit(br, p[6]))
                    {
                        if (!VP8GetBit(br, p[7]))
                        {
                            v = 5 + VP8GetBit(br, 159);
                        } else
                        {
                            v = 7 + 2 * VP8GetBit(br, 165);
                            v += VP8GetBit(br, 145);
                        }
                    }
                    else
                    {
                        const uint8_t* tab;
                        const int bit1 = VP8GetBit(br, p[8]);
                        const int bit0 = VP8GetBit(br, p[9 + bit1]);
                        const int cat = 2 * bit1 + bit0;
                        v = 0;
                        for (tab = kCat3456[cat]; *tab; ++tab)
                        {
                            v += v + VP8GetBit(br, *tab);
                        }
                        v += 3 + (8 << cat);
                    }
                }
                p = prob[kBands[n]][2];
            }
            j = kZigzag[n - 1];

            out[j] = GetSigned(br, v);

            if (n == 16 || !VP8GetBit(br, p[0]))
            {   /* EOB */
                return n;
            }
        }
        if (n == 16)
        {
            return 16;
        }
    }
}

int vp8_decode_mb_tokens(VP8D_COMP *dx, MACROBLOCKD *x)
{
    BOOL_DECODER *bc = x->current_bc;
    const FRAME_CONTEXT * const fc = &dx->common.fc;
    char *eobs = x->eobs;

    int i;
    int nonzeros;
    int eobtotal = 0;

    short *qcoeff_ptr;
    ProbaArray coef_probs;
    ENTROPY_CONTEXT *a_ctx = ((ENTROPY_CONTEXT *)x->above_context);
    ENTROPY_CONTEXT *l_ctx = ((ENTROPY_CONTEXT *)x->left_context);
    ENTROPY_CONTEXT *a;
    ENTROPY_CONTEXT *l;
    int skip_dc = 0;

    qcoeff_ptr = &x->qcoeff[0];

    if (!x->mode_info_context->mbmi.is_4x4)
    {
        a = a_ctx + 8;
        l = l_ctx + 8;

        coef_probs = fc->coef_probs [1];

        nonzeros = GetCoeffs(bc, coef_probs, (*a + *l), 0, qcoeff_ptr + 24 * 16);
        *a = *l = (nonzeros > 0);

        eobs[24] = nonzeros;
        eobtotal += nonzeros - 16;

        coef_probs = fc->coef_probs [0];
        skip_dc = 1;
    }
    else
    {
        coef_probs = fc->coef_probs [3];
        skip_dc = 0;
    }

    for (i = 0; i < 16; ++i)
    {
        a = a_ctx + (i&3);
        l = l_ctx + ((i&0xc)>>2);

        nonzeros = GetCoeffs(bc, coef_probs, (*a + *l), skip_dc, qcoeff_ptr);
        *a = *l = (nonzeros > 0);

        nonzeros += skip_dc;
        eobs[i] = nonzeros;
        eobtotal += nonzeros;
        qcoeff_ptr += 16;
    }

    coef_probs = fc->coef_probs [2];

    a_ctx += 4;
    l_ctx += 4;
    for (i = 16; i < 24; ++i)
    {
        a = a_ctx + ((i > 19)<<1) + (i&1);
        l = l_ctx + ((i > 19)<<1) + ((i&3)>1);

        nonzeros = GetCoeffs(bc, coef_probs, (*a + *l), 0, qcoeff_ptr);
        *a = *l = (nonzeros > 0);

        eobs[i] = nonzeros;
        eobtotal += nonzeros;
        qcoeff_ptr += 16;
    }

    return eobtotal;
}

