📄 idct.c
字号:
} } } } for (index = 0; index < IDCT_NTAB2_SIZE; index++) { magn = 2 * IDCT_NTAB1_SIZE * (index + 1); //printf( "Init index = %d magn = %f \n", index+IDCT_NTAB1_SIZE, magn); for (zzpos = 0; zzpos < 8*8; zzpos++) { n = InvZZ[zzpos] / 8; m = InvZZ[zzpos] % 8; for (j=0; j < 4; j++) { for (i=0; i < 2; i++) { idct_tab [index + IDCT_NTAB1_SIZE][zzpos][2*j+i] = dct_tab_entry (magn * bfunc[n][m][j][2*i], magn * bfunc[n][m][j][2*i+1]); } } } } // Modify tables for index=1 to truncate more values to zero Fix_PTel_S4000_mismatch(); // LUT to clip to allowed range for PIXEL for (i = CLIPMIN; i <= CLIPMAX; i++) { clip[i-CLIPMIN] = max( PIXEL_MIN, min( PIXEL_MAX, i)); } // Classify zigzag position as even or odd, horizontally and vertically for (zzpos = 0; zzpos < 8*8; zzpos++) { n = InvZZ[zzpos] / 8; m = InvZZ[zzpos] % 8; even_odd_index[zzpos] = 2 * (n % 2) + m % 2; }#ifdef DO_H263_PLUS InitAdvancedIntraTables();#endif return;}// Fix_PTel_S4000_mismatch - Modify tables for index=1 to truncate more // values to zero. This improves the quality when communicating with a // system that has an IDCT mismatch problem (PTel S-4000, bug #250)static void Fix_PTel_S4000_mismatch( void ){ int index, i, j, zzpos; index = 1; for (i = 0; i < 2; i++) { truncate_more( &hor_ac_tab [index][i] ); } for (j = 0; j < 4; j++) { truncate_more( &vert_ac_tab [index][j] ); } for (zzpos = 0; zzpos < 8*8; zzpos++) { for (j=0; j < 4; j++) { for (i=0; i < 2; i++) { truncate_more( &idct_tab [index][zzpos][2*j+i] ); } } } return;}// truncate_morestatic void truncate_more( S32 * idct_tab_entry ){#define ONE_HALF (1 << (FRACBITS - 1))#define PTEL_FIX_INTERVAL (3) // Set to 0 if no fix needed S32 halfword[2]; int i; halfword[0] = *idct_tab_entry >> 16; // Upper part of word halfword[1] = (*idct_tab_entry << 16) >> 16; // Lower part of word for (i = 0; i < 2; ++i) { if (halfword[i] >= ONE_HALF && halfword[i] < ONE_HALF + PTEL_FIX_INTERVAL) { halfword[i] = ONE_HALF - 1; } else if (halfword[i] <= -ONE_HALF && halfword[i] > -(ONE_HALF + PTEL_FIX_INTERVAL)) { halfword[i] = -(ONE_HALF - 1); } } *idct_tab_entry = (halfword[0] << 16) | (halfword[1] & 0xffff); return;} #ifdef WHY_IS_THIS_HEREstatic int idct2_energy_test( SYMBOL sym[], int nsym, S16 recon[] ){ int isym, zzpos; int temp; isym = 0; temp = 0; zzpos = sym[0].type; while (isym < nsym && zzpos < 10) { temp += abs((int) recon[(U8)sym[isym].value]); isym++; zzpos += 1 + sym[isym].type; } return(temp);}#endifstatic void idct2_goertzel( SYMBOL sym[], int nsym, S32 x[8][4], S16 recon[], int intra, int clean, int idct_class){ int i, zzpos, isym; S32 even_odd[4][8]; /* Accumulate even/even, even/odd, odd/even, odd/odd */ S32 temp[4]; /* Used in final butterfly computations */#ifdef LITTLE_ENDIAN char msg[120]; /* Flawfinder: ignore */ int LUT_index;#endif UNREFERENCED_PARAMETER(clean);// The four special class implementations are specific to LITTLE_ENDIAN.#ifdef LITTLE_ENDIAN switch (idct_class) { case GENERAL: { memset(even_odd, 0, 128); isym = 0; zzpos = sym[0].type; // Reconstruct DC coeff if (intra == YES) { recon_intra_dc( (U8) sym[0].value, even_odd[0]); isym++; zzpos += 1 + sym[isym].type; } else if (zzpos == 0) { recon_dc( (S32) recon[(U8)sym[0].value], even_odd[0]); isym++; zzpos += 1 + sym[isym].type; } // Init even/odd: reconstruct first hor. AC coeff if (isym < nsym && zzpos == 1) { recon_hor_ac( (S32) recon[(U8)sym[isym].value], even_odd[1]); isym++; zzpos += 1 + sym[isym].type; } // Init odd/even: reconstruct first vert. AC coeff if (isym < nsym && zzpos == 2) { recon_vert_ac( (S32) recon[(U8)sym[isym].value], even_odd[2]); isym++; zzpos += 1 + sym[isym].type; } // Reconstruct remaining coeffs// if (clean == YES) { // activate this for sleazy IDCT decoder while (isym < nsym) { //printf(" Calling update with zzpos = %d\n", zzpos); update( &even_odd[ even_odd_index[zzpos]] [0], (S32) recon[(U8)sym[isym].value], (long (*)[512]) &idct_tab[0][zzpos][0]); isym++; zzpos += 1 + sym[isym].type; }// } // activate this for sleazy IDCT decoder // else { // // Sleazy reconstruction // // while (isym < nsym && zzpos < 10) { // //printf(" Calling update with zzpos = %d\n", zzpos); // update( &even_odd[ even_odd_index[zzpos]] [0], // (S32) recon[(U8)sym[isym].value], // (U32 (*)[8*8*8])&idct_tab[0][zzpos][0]); // isym++; // zzpos += 1 + sym[isym].type; // } // } } break; case DC_ONLY: case DC_AC_H: case DC_AC_V: case DC_3: { isym = 0; zzpos = sym[0].type; // Reconstruct DC coeff if (intra == YES) { LUT_index = (U8)sym[0].value; even_odd[0][0] = intra_dc_tab[LUT_index]; isym++; zzpos += 1 + sym[isym].type; } else if (zzpos == 0) { LUT_index = (S32)recon[(U8)sym[0].value]; if (LUT_index>0) even_odd[0][0] = dc_tab[LUT_index-1]; else if (LUT_index<0) even_odd[0][0] = -dc_tab[-LUT_index-1]; else { //sprintf(msg, "ERROR:recon_dc called with arg=0"); //H261ErrMsg(msg); } isym++; zzpos += 1 + sym[isym].type; } // Init even/odd: reconstruct first hor. AC coeff if (isym < nsym && zzpos == 1) { recon_hor_ac( (S32) recon[(U8)sym[isym].value], even_odd[1]); isym++; zzpos += 1 + sym[isym].type; } // Init odd/even: reconstruct first vert. AC coeff if (isym < nsym && zzpos == 2) { recon_vert_ac( (S32) recon[(U8)sym[isym].value], even_odd[2]); isym++; zzpos += 1 + sym[isym].type; } } break; default: break; } #else memset(even_odd, 0, 128); isym = 0; zzpos = sym[0].type; // Reconstruct DC coeff if (intra == YES) { recon_intra_dc( (U8) sym[0].value, even_odd[0]); isym++; zzpos += 1 + sym[isym].type; } else if (zzpos == 0) { recon_dc( (S32) recon[(U8)sym[0].value], even_odd[0]); isym++; zzpos += 1 + sym[isym].type; } // Init even/odd: reconstruct first hor. AC coeff if (isym < nsym && zzpos == 1) { recon_hor_ac( (S32) recon[(U8)sym[isym].value], even_odd[1]); isym++; zzpos += 1 + sym[isym].type; } // Init odd/even: reconstruct first vert. AC coeff if (isym < nsym && zzpos == 2) { recon_vert_ac( (S32) recon[(U8)sym[isym].value], even_odd[2]); isym++; zzpos += 1 + sym[isym].type; } // Reconstruct remaining coeffs// if (clean == YES) { // activate this for sleazy IDCT decoder while (isym < nsym) { //printf(" Calling update with zzpos = %d\n", zzpos); update( &even_odd[ even_odd_index[zzpos]] [0], (S32) recon[(U8)sym[isym].value], (S32 (*)[8*8*8]) &idct_tab[0][zzpos][0]); isym++; zzpos += 1 + sym[isym].type; }// } // activate this for sleazy IDCT decoder // else { // // Sleazy reconstruction // // while (isym < nsym && zzpos < 10) { // //printf(" Calling update with zzpos = %d\n", zzpos); // update( &even_odd[ even_odd_index[zzpos]] [0], // (S32) recon[(U8)sym[isym].value], // (U32 (*)[8*8*8]) &idct_tab[0][zzpos][0]); // isym++; // zzpos += 1 + sym[isym].type; // } // } #endif#ifdef LITTLE_ENDIAN // Final butterflies switch (idct_class) { // DC only case case DC_ONLY: { temp[0] = even_odd[0][0]; temp[0] += (0x10001L << (FRACBITS-1)); x[0][0] = temp[0]; } break; // DC + 1 horizontal AC case case DC_AC_H: { temp[0] = even_odd[0][0]; temp[0] += (0x10001L << (FRACBITS-1)); x[0][0] = temp[0] + even_odd[1][0]; x[0][2] = temp[0] - even_odd[1][0]; x[0][1] = temp[0] + even_odd[1][1]; x[0][3] = temp[0] - even_odd[1][1]; } break; // DC + 1 vertical AC case case DC_AC_V: { for (i = 0; i < 4; i++) { temp[0] = even_odd[0][0] + even_odd[2][2*i]; temp[1] = even_odd[0][0] - even_odd[2][2*i]; temp[0] += (0x10001L << (FRACBITS-1)); temp[1] += (0x10001L << (FRACBITS-1)); x[i][0] = temp[0]; x[i][1] = temp[0]; x[i][2] = temp[0]; x[i][3] = temp[0]; x[7-i][0] = temp[1]; x[7-i][1] = temp[1]; x[7-i][2] = temp[1]; x[7-i][3] = temp[1]; } } break; // DC + 1 vertical AC + 1 horizontal AC case case DC_3: { for (i = 0; i < 4; i++) { temp[0] = even_odd[0][0] + even_odd[2][2*i]; temp[2] = even_odd[0][0] - even_odd[2][2*i]; temp[0] += (0x10001L << (FRACBITS-1)); temp[2] += (0x10001L << (FRACBITS-1)); x[i][0] = temp[0] + even_odd[1][2*i]; x[i][2] = temp[0] - even_odd[1][2*i]; x[7-i][0] = temp[2] + even_odd[1][2*i]; x[7-i][2] = temp[2] - even_odd[1][2*i]; x[i][1] = temp[0] + even_odd[1][2*i+1]; x[i][3] = temp[0] - even_odd[1][2*i+1]; x[7-i][1] = temp[2] + even_odd[1][2*i+1]; x[7-i][3] = temp[2] - even_odd[1][2*i+1]; } } break; case GENERAL: { 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]; } } break; default: break; }#else { 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];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -