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

📄 idct.c

📁 symbian 下的helix player源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
              }
            }
        }
    }
    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_more
static 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_HERE
static 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);
}
#endif

static 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 + -