📄 idct.c
字号:
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 blockstatic 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 > 0extern 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 blockstatic 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 coeffstatic 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 coeffstatic 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 coeffstatic 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 lowerstatic 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 + -