/******************************************************************************
 *
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *****************************************************************************
 * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#include <stdio.h>
#include "iv_datatypedef.h"
#include "iv.h"
#include "impeg2_buf_mgr.h"
#include "impeg2_disp_mgr.h"
#include "impeg2_defs.h"
#include "impeg2_platform_macros.h"
#include "impeg2_globals.h"

/* Table for converting the quantizer_scale_code to quantizer_scale */
const UWORD8 gau1_impeg2_non_linear_quant_scale[] =
{
    0, 1, 2, 3, 4, 5, 6, 7,
    8,10,12,14,16,18,20,22,
    24,28,32,36,40,44,48,52,
    56,64,72,80,88,96,104,112
};


/* Default quantizer matrix to be used for intra blocks */
const UWORD8 gau1_impeg2_intra_quant_matrix_default[] =
{
    8, 16, 19, 22, 26, 27, 29, 34,
    16, 16, 22, 24, 27, 29, 34, 37,
    19, 22, 26, 27, 29, 34, 34, 38,
    22, 22, 26, 27, 29, 34, 37, 40,
    22, 26, 27, 29, 32, 35, 40, 48,
    26, 27, 29, 32, 35, 40, 48, 58,
    26, 27, 29, 34, 38, 46, 56, 69,
    27, 29, 35, 38, 46, 56, 69, 83
};

/* Default quantizer matrix to be used for inter blocks */
const UWORD8 gau1_impeg2_inter_quant_matrix_default[] =
{
    16,16,16,16,16,16,16,16,
    16,16,16,16,16,16,16,16,
    16,16,16,16,16,16,16,16,
    16,16,16,16,16,16,16,16,
    16,16,16,16,16,16,16,16,
    16,16,16,16,16,16,16,16,
    16,16,16,16,16,16,16,16,
    16,16,16,16,16,16,16,16
};

/* Table to perform inverse scan when the scan direction is zigzag */
const UWORD8 gau1_impeg2_inv_scan_zig_zag[] =
{
     0,  1,  8, 16,  9,  2,  3, 10,
    17, 24, 32, 25, 18, 11,  4,  5,
    12, 19, 26, 33, 40, 48, 41, 34,
    27, 20, 13,  6,  7, 14, 21, 28,
    35, 42, 49, 56, 57, 50, 43, 36,
    29, 22, 15, 23, 30, 37, 44, 51,
    58, 59, 52, 45, 38, 31, 39, 46,
    53, 60, 61, 54, 47, 55, 62, 63
};

/*  Table to perform inverse scan when the direction of scanning is vertical */
const UWORD8 gau1_impeg2_inv_scan_vertical[] =
{
    0, 8, 16, 24, 1, 9, 2, 10,
    17, 25, 32, 40, 48, 56, 57, 49,
    41, 33, 26, 18, 3, 11, 4, 12,
    19, 27, 34, 42, 50, 58, 35, 43,
    51, 59, 20, 28, 5, 13, 6, 14,
    21, 29, 36, 44, 52, 60, 37, 45,
    53, 61, 22, 30, 7, 15, 23, 31,
    38, 46, 54, 62, 39, 47, 55, 63
};

/*****************************************************************************/
/* Table that indicate which interpolation  type is to used                  */
/*****************************************************************************/
/* Chroma when motion vector is positive */
const UWORD16 gau2_impeg2_chroma_interp_mv[][16] =
{
    /* Pos X Pos Y */
    {
        0,  0,  1,  1,
        0,  0,  1,  1,
        2,  2,  3,  3,
        2,  2,  3,  3
    },
    /* Neg X Pos Y */
    {
        0,  1,  1,  0,
        0,  1,  1,  0,
        2,  3,  3,  2,
        2,  3,  3,  2
    },
    /* Pos X Neg Y */
    {
        0,  0,  1,  1,
        2,  2,  3,  3,
        2,  2,  3,  3,
        0,  0,  1,  1
    },
    /* Neg X Neg Y */
    {
        0,  1,  1, 0,
        2,  3,  3, 2,
        2,  3,  3, 2,
        0,  1,  1, 0
    }
};
/*****************************************************************************/
/* Input #1 Offset in bytes                                                  */
/*****************************************************************************/
/* Chroma */
const UWORD16 gau2_impeg2_chroma_interp_inp1[][16] =
{
    /* Pos X Pos Y */
    {
        0,  0,  0,  0,
        0,  0,  0,  0,
        0,  0,  0,  0,
        0,  0,  0,  0
    },
    /* Neg X Pos Y */
    {
        0,  0,  0,  4,
        0,  0,  0,  4,
        0,  0,  0,  4,
        0,  0,  0,  4
    },
    /* Pos X Neg Y */
    {
        0,  0,  0,  0,
        0,  0,  0,  0,
        0,  0,  0,  0,
        72, 72, 72, 72
    },
    /* Neg X Neg Y */
    {
        0,  0,  0,  4,
        0,  0,  0,  4,
        0,  0,  0,  4,
        72, 72, 72, 76
    }
};
/* Luma */
const UWORD16 gau2_impeg2_luma_interp_inp1[] =
{
    1,  1,  3,  3,
    1,  1,  3,  3,
    37, 37, 39, 39,
    37, 37, 39, 39
};
/*****************************************************************************/
/* Input #2 Offset from Input #1 in bytes                                    */
/*****************************************************************************/
/*
    FXFY  0,
    HXFY  2,
    FXHY 36,
    HXHY 36
*/
const UWORD16 gau2_impeg2_luma_interp_inp2[] =
{
      0,  2,  0,  2,
     36, 36, 36, 36,
      0,  2,  0,  2,
     36, 36, 36, 36
};
const UWORD16 gau2_impeg2_chroma_interp_inp2[] =
{
    /* FXFY */
    0,
    /* HXFY */
    4,
    /* FXHY */
    72,
    /* HXHY */
    72
};

/*****************************************************************************/
/* Corresponds to Table 6-4 frame_rate_value  of the standard                */
/*****************************************************************************/
/*
    frame_rate_code frame_rate_value

    0000            Forbidden
    0001            24 000 ÷ 1001
    0010            24
    0011            25
    0100            30 000 ÷ 1001
    0101            30
    0110            50
    0111            60 000 ÷ 1001
    1000            60
    1001            Reserved
    ....
    1111            Reserved
*/
const UWORD16 gau2_impeg2_frm_rate_code[][2] =
{
    {1    ,    1}, /* Forbidden */
    {24000, 1001},
    {24000, 1000},
    {25000, 1000},
    {30000, 1001},
    {30000, 1000},
    {50000, 1000},
    {60000, 1001},
    {60000, 1000}
    /* Rest reserved */
};

const WORD16 gai2_impeg2_idct_q15[] =
{
    23170,    23170,    23170,    23170,    23170,    23170,    23170,    23170,
    32138,    27246,    18205,     6393,    -6393,   -18205,   -27246,   -32138,
    30274,    12540,   -12540,   -30274,   -30274,   -12540,    12540,    30274,
    27246,    -6393,   -32138,   -18205,    18205,    32138,     6393,   -27246,
    23170,   -23170,   -23170,    23170,    23170,   -23170,   -23170,    23170,
    18205,   -32138,     6393,    27246,   -27246,    -6393,    32138,   -18205,
    12540,   -30274,    30274,   -12540,   -12540,    30274,   -30274,    12540,
     6393,   -18205,    27246,   -32138,    32138,   -27246,    18205,    -6393,
};

const WORD16 gai2_impeg2_idct_q11[] =
{
    1448,     1448,     1448,     1448,     1448,     1448,     1448,     1448,
    2009,     1703,     1138,      400,     -400,    -1138,    -1703,    -2009,
    1892,      784,     -784,    -1892,    -1892,     -784,      784,     1892,
    1703,     -400,    -2009,    -1138,     1138,     2009,      400,    -1703,
    1448,    -1448,    -1448,     1448,     1448,    -1448,    -1448,     1448,
    1138,    -2009,      400,     1703,    -1703,     -400,     2009,    -1138,
     784,    -1892,     1892,     -784,     -784,     1892,    -1892,      784,
     400,    -1138,     1703,    -2009,     2009,    -1703,     1138,     -400,
};

const WORD16 gai2_impeg2_idct_even_8_q15[][8] =
{
    {  23170,  23170,  23170,  23170,  23170,  23170,  23170,  23170  },
    {  12540, -30274,  12540, -30274,  12540, -30274,  12540, -30274  },
    {  30274,  12540,  30274,  12540,  30274,  12540,  30274,  12540  },
    {  23170, -23170,  23170, -23170,  23170, -23170,  23170, -23170  }
};
const WORD16 gai2_impeg2_idct_odd_8_q15[][8] =
{
    {  32138,  27246,  32138,  27246,  32138,  27246,  32138,  27246 },
    {  18205,   6393,  18205,   6393,  18205,   6393,  18205,   6393 },
    {  27246,  -6393,  27246,  -6393,  27246,  -6393,  27246,  -6393 },
    {  32138,  18205,  32138,  18205,  32138,  18205,  32138,  18205 },
    {  18205, -32138,  18205, -32138,  18205, -32138,  18205, -32138 },
    {  6393,   27246,   6393,  27246,   6393,  27246,   6393,  27246 },
    {  6393,  -18205,   6393, -18205,   6393, -18205,   6393, -18205 },
    {  27246, -32138,  27246, -32138,  27246, -32138,  27246, -32138 },
};

const WORD16 gai2_impeg2_idct_even_8_q11[][8] =
{
    {   1448,   1448,   1448,   1448,   1448,   1448,   1448,   1448 },
    {    784,  -1892,    784,  -1892,    784,  -1892,    784,  -1892 },
    {   1892,    784,   1892,    784,   1892,    784,   1892,    784 },
    {   1448,  -1448,   1448,  -1448,   1448,  -1448,   1448,  -1448 }
};
const WORD16 gai2_impeg2_idct_odd_8_q11[][8] =
{
    {   2009,   1703,   2009,   1703,   2009,   1703,   2009,   1703 },
    {   1138,    400,   1138,    400,   1138,    400,   1138,    400 },
    {   1703,   -400,   1703,   -400,   1703,   -400,   1703,   -400 },
    {   2009,   1138,   2009,   1138,   2009,   1138,   2009,   1138 },
    {   1138,  -2009,   1138,  -2009,   1138,  -2009,   1138,  -2009 },
    {    400,   1703,    400,   1703,    400,   1703,    400,   1703 },
    {    400,  -1138,    400,  -1138,    400,  -1138,    400,  -1138 },
    {   1703,  -2009,   1703,  -2009,   1703,  -2009,   1703,  -2009 },
};



/*****************************************************************************/
/* Last row IDCT Coefficients in Q11 format                                           */
/*****************************************************************************/
const WORD16 gai2_impeg2_idct_last_row_q11[] =
{
     400,    -1138,     1703,    -2009,     2009,    -1703,     1138,     -400,
};

const WORD16 gai2_impeg2_idct_first_col_q15[] =
{
   23170,    32138,    30274,    27246,    23170,    18205,    12540,     6393,
};

const WORD16 gai2_impeg2_idct_first_col_q11[] =
{
     1448,    2009,     1892,     1703,     1448,     1138,      784,      400,
};

/*****************************************************************************/
/* Output of first stage dct (using gai2_impeg2_idct_q15 as coeffs)          */
/* for a 1D data (0, 0, 0, 0, 0, 0, 0, 1)                                    */
/*****************************************************************************/

const WORD16 gai2_impeg2_mismatch_stg1_outp[] =
{
    2, -4, 7, -8, 8, -7, 4, -2
};

const WORD16 gai2_impeg2_mismatch_stg2_additive[] =
{
     800,   -2276,  3406,   -4018,  4018,   -3406,  2276,   -800,
     -1600, 4552,   -6812,  8036,   -8036,  6812,   -4552,  1600,
     2800,  -7966,  11921,  -14063, 14063,  -11921, 7966,   -2800,
     -3200, 9104,   -13624, 16072,  -16072, 13624,  -9104,  3200,
     3200,  -9104,  13624,  -16072, 16072,  -13624, 9104,   -3200,
     -2800, 7966,   -11921, 14063,  -14063, 11921,  -7966,  2800,
     1600,  -4552,  6812,   -8036,  8036,   -6812,  4552,   -1600,
     -800,  2276,   -3406,  4018,   -4018,  3406,   -2276,  800,
};


const UWORD8 gau1_impeg2_zerobuf[] =
{
    0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0,
};
/*****************************************************************************/
/* Tables of offset needed to address block in an MB                         */
/*****************************************************************************/
const WORD16  gai2_impeg2_blk_y_off_fld[]  = {0,0,1,1};
const WORD16  gai2_impeg2_blk_y_off_frm[]  = {0,0,8,8};
const WORD16  gai2_impeg2_blk_x_off[]      = {0,8,0,8};
