⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 idct.c

📁 symbian 下的helix player源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
                        x[i][2] = temp[0] - temp[1];
                        temp[2] += (0x10001L << (FRACBITS-1));    /* Round */
                        x[7-i][0] = temp[2] + temp[3];
                        x[7-i][2] = temp[2] - temp[3];
                    // j=1
                        temp[0] = even_odd[0][2*i+1] + even_odd[2][2*i+1];
                        temp[2] = even_odd[0][2*i+1] - even_odd[2][2*i+1];
                        temp[1] = even_odd[1][2*i+1] + even_odd[3][2*i+1];
                        temp[3] = even_odd[1][2*i+1] - even_odd[3][2*i+1];
                        temp[0] += (0x10001L << (FRACBITS-1));    /* Round */
                        x[i][1] = temp[0] + temp[1];
                        x[i][3] = temp[0] - temp[1];
                        temp[2] += (0x10001L << (FRACBITS-1));    /* Round */
                        x[7-i][1] = temp[2] + temp[3];
                        x[7-i][3] = temp[2] - temp[3];
                }
            }
#endif                          
    return;
}


#ifdef DO_H263_PLUS
//  recon_advanced_intra_dc - Reconstruct DC coeff in INTRA block
static void recon_advanced_intra_dc( U8 index, S32 vec[8])
{
    int j, temp;
    double bfunc;
    bfunc = SCALE_FACTOR * dctfunc(0,0) * dctfunc(0,0);
    temp = 8 * index;
    temp = dct_tab_entry( temp * bfunc, temp * bfunc);
    for (j = 0; j < 8; j++) {
        vec[j] = temp;
    }
    return;
}

//
// Quick implementation of intra prediction
//
extern void idct2_advanced_intra( SYMBOL sym[], int nsym, S32 x[8][4], S16 recon[],
                            U8 rDCpred, S8 rACpred[8], U8 rDCstore[1], S8 rACstore[8], 
                            U8 cDCpred, S8 cACpred[8], U8 cDCstore[1], S8 cACstore[8],
                            int predtype, int fixedDC, int leftBoundary, int upperBoundary)
{
    int     i, pos, isym;
    S32     even_odd[4][8]; /* Accumulate even/even, even/odd, odd/even, odd/odd */
    S32     temp[4];        /* Used in final butterfly computations */
    int     skip;
    S8      value;
    int    *scan_to_zz;
    int    *inv_scan_order;

    memset(even_odd, 0, 128);
    
    // in advanced intra mode, the AC and DC are coded in the same way, so it
    // is possible for the DC residual to be zero and the first symbol to 
    // have a non-trivial zero run
    if(nsym) {
        if(sym[0].type) {
            value = 0;
            isym = 0;
            skip = sym[0].type - 1; // we'll take care of DC outside the loop
        } else {
            value = sym[0].value;
            isym = 1;
            skip = sym[isym].type;
        }
    } else {
        value = 0;
        isym = 0;
        skip = 0;
    }

    //  Reconstruct DC coeff
    switch(predtype) {
    case ADV_INTRA_PRED_DC_ONLY:
        scan_to_zz = &zigzag_to_zigzag[0];
        inv_scan_order = &InvZZ[0];
        rDCstore[0] = cDCstore[0] = (U8)(value + (( 
            (upperBoundary ? cDCpred : rDCpred) + // use row predictor unless on upper boundary
            (leftBoundary ? rDCpred : cDCpred) + // use column predictor unless on left boundary
            1)>>1) );
        break;
    case ADV_INTRA_PRED_COLUMN:
        scan_to_zz = &alt_ver_to_zigzag[0];
        inv_scan_order = &inv_alt_ver_scan_no_reorder[0];
        rDCstore[0] = cDCstore[0] = (U8)(value + cDCpred);
        break;
    case ADV_INTRA_PRED_ROW:
        scan_to_zz = &alt_hor_to_zigzag[0];
        inv_scan_order = &inv_alt_hor_scan_no_reorder[0];
        rDCstore[0] = cDCstore[0] = (U8)(value + rDCpred);
        break;
    case ADV_INTRA_PRED_NONE:
        scan_to_zz = &zigzag_to_zigzag[0];
        inv_scan_order = &InvZZ[0];
        rDCstore[0] = cDCstore[0] = (U8)(value);
        break;
    }

    // We deviate from the H.263+ spec and the standard H.263 8-bit INTRA_DC quantizer
    // for small quantizer values so that we avoid problems with the dynamic range
    // getting too small
    if(fixedDC) {
        recon_advanced_intra_dc( rDCstore[0], even_odd[0]);
    } else {
        if(rDCstore[0]) update( &even_odd[even_odd_index[0]][0],
                        (S32) recon[rDCstore[0]],  
                        (S32 (*)[8*8*8]) &idct_tab[0][0][0]);
    }


    for(pos=1; pos<64; pos++)
    {
       // compute the quantized AC coefficient
        if(skip || isym>=nsym) {
            value = 0;
            skip--;
        } else {
            value = sym[isym++].value;
            skip = sym[isym].type;
        }
         // row predict and store reconstructed
        if(inv_scan_order[pos] < 8) {
            if(predtype == ADV_INTRA_PRED_ROW)
                value += rACpred[inv_scan_order[pos]];
            rACstore[inv_scan_order[pos]] = value;
        }
         // col predict and store reconstructed
        if((inv_scan_order[pos] & 7) == 0) {
            if(predtype == ADV_INTRA_PRED_COLUMN)
                value += cACpred[inv_scan_order[pos]>>3];
            cACstore[inv_scan_order[pos]>>3] = value;
        }
    
        // note that both even_odd_index and idct_tab assume that we are indexing
        // by zigzag order; hence the conversion of the variable pos
        if(value) update( &even_odd[ even_odd_index[scan_to_zz[pos]]] [0],
                    (S32) recon[ (U8)value],  
                    (S32 (*)[8*8*8]) &idct_tab[0][scan_to_zz[pos]][0]);
    }


    // Do the final butterfly
    for (i = 0; i < 4; i++) 
    {
        // j=0
        temp[0] = even_odd[0][2*i] + even_odd[2][2*i];
        temp[2] = even_odd[0][2*i] - even_odd[2][2*i];
        temp[1] = even_odd[1][2*i] + even_odd[3][2*i];
        temp[3] = even_odd[1][2*i] - even_odd[3][2*i];
        temp[0] += (0x10001L << (FRACBITS-1));    /* Round */
        x[i][0] = temp[0] + temp[1];
        x[i][2] = temp[0] - temp[1];
        temp[2] += (0x10001L << (FRACBITS-1));    /* Round */
        x[7-i][0] = temp[2] + temp[3];
        x[7-i][2] = temp[2] - temp[3];
        // j=1
        temp[0] = even_odd[0][2*i+1] + even_odd[2][2*i+1];
        temp[2] = even_odd[0][2*i+1] - even_odd[2][2*i+1];
        temp[1] = even_odd[1][2*i+1] + even_odd[3][2*i+1];
        temp[3] = even_odd[1][2*i+1] - even_odd[3][2*i+1];
        temp[0] += (0x10001L << (FRACBITS-1));    /* Round */
        x[i][1] = temp[0] + temp[1];
        x[i][3] = temp[0] - temp[1];
        temp[2] += (0x10001L << (FRACBITS-1));    /* Round */
        x[7-i][1] = temp[2] + temp[3];
        x[7-i][3] = temp[2] - temp[3];
    }

    return;
}


//  Idct2 - Reconstruct DCT coeffs, perform IDCT, and clip to allowed pixel range */
//  Requires nsym > 0
extern void Idct2AdvancedIntra( SYMBOL sym[], int nsym, PIXEL x[], int xdim, S16 recon[],
                               U8 rDCpred, S8 rACpred[8], U8 rDCstore[1], S8 rACstore[8], 
                               U8 cDCpred, S8 cACpred[8], U8 cDCstore[1], S8 cACstore[8],
                               int predtype, int fixedDC, int leftBoundary, int upperBoundary)
{
    union {
        S16   bshort[8][8];
        S32    blong[8][4];
    } block;    /* Output from IDCT */

    idct2_advanced_intra( sym, nsym, block.blong, recon, 
        rDCpred, rACpred, rDCstore, rACstore,
        cDCpred, cACpred, cDCstore, cACstore,
        predtype, fixedDC,leftBoundary,upperBoundary);
    idct2_clip(x, xdim, block.blong, GENERAL);

    return;
}


#endif


//  recon_intra_dc - Reconstruct DC coeff in INTRA block
static void recon_intra_dc( U8 index, S32 vec[8])
{
    int j, temp;
    
    temp = intra_dc_tab [index];
    for (j = 0; j < 8; j++) {
        vec[j] = temp;
    }
    return;
}


//  recon_dc - Reconstruct DC coeff
static void recon_dc( S32 y, S32 vec[8])
{
    int j, temp;
    char msg[120]; /* Flawfinder: ignore */
    
    if (y > 0) {
        temp = dc_tab[ y - 1 ];
    } else if (y < 0) {
        temp = -dc_tab[ -y - 1 ];
    } else {
        //sprintf( msg, "ERROR: recon_dc called with arg=0");
        //H261ErrMsg( msg );
    }
    for (j = 0; j < 8; j++) {
        vec[j] = temp;
    }
    return;
}


//  recon_hor_ac - Reconstruct first hor. AC coeff
static void recon_hor_ac( S32 y, S32 vec[8])
{
    int j, temp0, temp1;
    char msg[120]; /* Flawfinder: ignore */
    
    if (y > 0) {
        temp0 = hor_ac_tab[ y - 1 ] [0];
        temp1 = hor_ac_tab[ y - 1 ] [1];
    } else if (y < 0) {
        temp0 = -hor_ac_tab[ -y - 1 ] [0];
        temp1 = -hor_ac_tab[ -y - 1 ] [1];
    } else {
        //sprintf( msg, "ERROR: recon_hor_ac called with arg=0");
        //H261ErrMsg( msg );
    }
    for (j = 0; j < 8; j += 2) {
        vec[j] = temp0;
        vec[j+1] = temp1;
    }
    return;
}


//  recon_vert_ac - Reconstruct first vert. AC coeff
static void recon_vert_ac( S32 y, S32 vec[8])
{
    int j, temp, index;
    char msg[120]; /* Flawfinder: ignore */
    
    if (y > 0) {
        for (j = 0; j < 4; j++) {
            vec[2*j] = vert_ac_tab[ y - 1 ] [j];
            vec[2*j+1] = vert_ac_tab[ y - 1 ] [j];
        }
    } else if (y < 0) {
        index = -y - 1;
        for (j = 0; j < 4; j++) {
            temp = -vert_ac_tab[ index ] [j];
            vec[2*j] = temp;
            vec[2*j+1] = temp;
        }
    } else {
        //sprintf( msg, "ERROR: recon_vert_ac called with arg=0");
        //H261ErrMsg( msg );
    }
    return;
}


static void update( S32 x[8], S32 index, S32 table[][8*8*8])
{
    int tab1_index, tab2_index;
    char msg[120]; /* Flawfinder: ignore */
    
    //printf( "Entered update\n" );
    if (index > 0) {
        index -= 1;
        tab1_index = index & ((0x1L << IDCT_NTAB1_BITS) - 1);  /* index % SIZE */
        tab2_index = index >> IDCT_NTAB1_BITS;
        //printf( "update plus: tab2 = %d    tab1 = %d\n", tab2_index, tab1_index);
        //printf( "x0 = %d  table = %d\n", x[0], table[tab1_index][0]);
        x[0] += table [tab1_index][0];
        x[1] += table [tab1_index][1];
        x[2] += table [tab1_index][2];
        x[3] += table [tab1_index][3];
        x[4] += table [tab1_index][4];
        x[5] += table [tab1_index][5];
        x[6] += table [tab1_index][6];
        x[7] += table [tab1_index][7];
        if (tab2_index != 0) {
            //printf( "x0 = %d  table = %d\n", x[0],
            //            table[tab2_index - 1 + IDCT_NTAB1_SIZE][0]);
            x[0] += table [tab2_index - 1 + IDCT_NTAB1_SIZE][0];
            x[1] += table [tab2_index - 1 + IDCT_NTAB1_SIZE][1];
            x[2] += table [tab2_index - 1 + IDCT_NTAB1_SIZE][2];
            x[3] += table [tab2_index - 1 + IDCT_NTAB1_SIZE][3];
            x[4] += table [tab2_index - 1 + IDCT_NTAB1_SIZE][4];
            x[5] += table [tab2_index - 1 + IDCT_NTAB1_SIZE][5];
            x[6] += table [tab2_index - 1 + IDCT_NTAB1_SIZE][6];
            x[7] += table [tab2_index - 1 + IDCT_NTAB1_SIZE][7];
        //printf( "x0 = %d\n", x[0]);
        }
    } else if (index < 0) {
        index = -index - 1;
        tab1_index = index & ((0x1L << IDCT_NTAB1_BITS) - 1);  /* index % SIZE */
        tab2_index = index >> IDCT_NTAB1_BITS;
        //printf( "update minus: tab2 = %d    tab1 = %d\n", tab2_index, tab1_index);
        x[0] -= table [tab1_index][0];
        x[1] -= table [tab1_index][1];
        x[2] -= table [tab1_index][2];
        x[3] -= table [tab1_index][3];
        x[4] -= table [tab1_index][4];
        x[5] -= table [tab1_index][5];
        x[6] -= table [tab1_index][6];
        x[7] -= table [tab1_index][7];
        if (tab2_index != 0) {
            x[0] -= table [tab2_index - 1 + IDCT_NTAB1_SIZE][0];
            x[1] -= table [tab2_index - 1 + IDCT_NTAB1_SIZE][1];
            x[2] -= table [tab2_index - 1 + IDCT_NTAB1_SIZE][2];
            x[3] -= table [tab2_index - 1 + IDCT_NTAB1_SIZE][3];
            x[4] -= table [tab2_index - 1 + IDCT_NTAB1_SIZE][4];
            x[5] -= table [tab2_index - 1 + IDCT_NTAB1_SIZE][5];
            x[6] -= table [tab2_index - 1 + IDCT_NTAB1_SIZE][6];
            x[7] -= table [tab2_index - 1 + IDCT_NTAB1_SIZE][7];
        }
    } else if (index == 0) {
        //sprintf( msg, "ERROR: update called with arg=0");
        //H261ErrMsg( msg );
    }
    return;
}


static double dctfunc (int freq, int index)
{
    if (freq == 0) {
        return (1./sqrt(8.));
    }
    return ( cos(PI*freq*(index+0.5)/8.) / 2.);
}


// Turn off "warning C4244: '=' : conversion from 'double ' to 'long ', 
//     possible loss of data" for MSVC 4.0
#pragma message("Turning off ConvFromDblToLong Warning")
#pragma warning(disable:4244)


//  Round x and y; put x in lower halfword, y in upper halfword (if little-endian)
static S32 dct_tab_entry (double x, double y)
{
    S32 ix, iy;

    ix = x * 65536.;    /* Mult by 2**16 */
    iy = y * 65536.;
#ifdef LITTLE_ENDIAN    /* x in lower halfword, y in upper */
    return (combine (iy, ix));
#elif defined BIG_ENDIAN    /* x in upper halfword, y in lower */
    return (combine (ix, iy));
#else
#   error
#endif
}

// Turn back on "warning C4244: '=' : conversion from 'double ' to 'long ', 
//     possible loss of data" for MSVC 4.0
#pragma warning(default:4244)


//  iy in upper halfword, ix>>16 in lower
static S32 combine (S32 iy, S32 ix)
{
    S32 low_tab, high_tab;

	// Note: this should not be a big-endian problem because calls to this function
	// exchange the order of ix and iy as needed. (Though wouldn't it have been
	// simpler to make the change here?) tkent
    low_tab = (ix + 0x8000L) >> 16  &  0x0000ffffL;
    high_tab = iy + 0x8000L - low_tab;
    high_tab &= 0xffff0000L;
    return (low_tab | high_tab);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -