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