www.pudn.com > wm2.5.zip > block.c


/* 
*********************************************************************** 
* COPYRIGHT AND WARRANTY INFORMATION 
* 
* Copyright 2004, Advanced Audio Video Coding Standard, Part II 
* 
* DISCLAIMER OF WARRANTY 
* 
* These software programs are available to the users without any 
* license fee or royalty on an "as is" basis. The AVS disclaims 
* any and all warranties, whether express, implied, or statutory, 
* including any implied warranties of merchantability or of fitness 
* for a particular purpose. In no event shall the contributors or  
* the AVS be liable for any incidental, punitive, or consequential 
* damages of any kind whatsoever arising from the use of this program. 
* 
* This disclaimer of warranty extends to the user of this program 
* and user's customers, employees, agents, transferees, successors, 
* and assigns. 
* 
* The AVS does not represent or warrant that the program furnished 
* hereunder are free of infringement of any third-party patents. 
* Commercial implementations of AVS, including shareware, may be 
* subject to royalty fees to patent holders. Information regarding 
* the AVS patent policy is available from the AVS Web site at 
* http://www.avs.org.cn 
* 
* THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE AVS PATENT POLICY. 
************************************************************************ 
*/   
 
/* 
************************************************************************************* 
* File name: block.c 
* Function: Description 
* 
************************************************************************************* 
*/ 
 
#include  
#include  
#include  
#include  
#include  
 
#include "defines.h" 
#include "global.h" 
#include "elements.h" 
#include "block.h" 
#include "vlc.h" 
 
 
static const int dequant_coef[6][2][2] = { //qwang 2004-4-4 
 {	 {16, 13},	 {13,  10} }, 
 {	 {18, 14},	 {14,  11} }, 
 {	 {20, 16},	 {16,  13} }, 
 {	 {23, 18},	 {18,  14} }, 
 {	 {26, 20},	 {20,  16} }, 
 {	 {29, 23},	 {23,  18} } 
}; 
 
 
#define EP (edgepixels+20) 
unsigned short IQ_TAB[64] = { 
	 
		32768,36061,38968,42495,46341,50535,55437,60424, 
		32932,35734,38968,42495,46177,50535,55109,59933, 
		65535,35734,38968,42577,46341,50617,55027,60097, 
		32809,35734,38968,42454,46382,50576,55109,60056, 
		65535,35734,38968,42495,46320,50515,55109,60076, 
		65535,35744,38968,42495,46341,50535,55099,60087, 
		65535,35734,38973,42500,46341,50535,55109,60097, 
		32771,35734,38965,42497,46341,50535,55109,60099 
		 
}; 
 
short IQ_SHIFT[64] = { 
	  14,14,14,14,14,14,14,14, 
		13,13,13,13,13,13,13,13, 
		13,12,12,12,12,12,12,12, 
		11,11,11,11,11,11,11,11, 
		11,10,10,10,10,10,10,10, 
		10,9,9,9,9,9,9,9, 
		9,8,8,8,8,8,8,8, 
		7,7,7,7,7,7,7,7 
		 
}; 
/* 
************************************************************************* 
* Function:Dequantization of 4x4 block. 
* Input: 
* Output: 
* Return:  
* Attention:input curr_blk has to be [lines][pixels]  /[y][x] 
************************************************************************* 
*/ 
void Dequant_B4(int qp, int b8, int b4)     
{ 
  int i, j; 
  int val; 
  int shift, QPI; 
 
  //if chroma, CurrentQP is indexed by the global table. 
  //if luma, CurrentQP = qp; 
  if(b8>=4) 
    qp =  QP_SCALE_CR[qp]; 
 
  for (j=0; j<4; j++) 
	  for (i=0; i<4; i++) 
	  { 
		  val  = pgcurrMB->pred_residual[b8][b4][j][i];   //VLD's residual before IQ 
		  shift = IQ_SHIFT[qp]; 
		  QPI   = IQ_TAB[qp];  
		   
		  pgcurrMB->pred_residual[b8][b4][j][i] = (val*QPI+(1<<(shift-1)))>>shift; //IQ coefficients after Dequantization 
		   
#if TRACE 
		  if(b8<4) 
			  MB_IQ_Y[((b8>>1)<<3)+((b4>>1)<<2)+j][((b8 &1)<<3)+((b4 &1)<<2)+i] = pgcurrMB->pred_residual[b8][b4][j][i]; 
		  else 
			  MB_IQ_UV[b8-4][((b4>>1)<<2)+j][((b4 &1)<<2)+i] = pgcurrMB->pred_residual[b8][b4][j][i];    
#endif 
	  } 
 
} 
/* 
************************************************************************* 
* Function:Inverse transform 4x4 block. 
* Input: 
* Output: 
* Return:  
* Attention:input curr_blk has to be [lines][pixels] 
************************************************************************* 
*/ 
#ifndef AVS_1_0 
void Inv_Transform_B4(int b8,int b4)     
{ 
    int i, j, i1, j1; 
	int tmp[4]; 
	int tmp_blk[BLOCK_SIZE][BLOCK_SIZE]; 
	 
	//using intermediate array tmp_blk[4][4] as transform unit. 
	//4x4 image data swapping 
	for(j=0; j<4; j++) 
		for(i=0; i<4; i++) 
			tmp_blk[j][i] = pgcurrMB->pred_residual[b8][b4][j][i]; 
		 
	//horizontal transform 
	for (j=0; j<4; j++) 
	{ 
		 
		tmp[0] = (tmp_blk[j][0]+tmp_blk[j][2])<<1;               
		tmp[1] = (tmp_blk[j][0]-tmp_blk[j][2])<<1;                                        
		tmp[3] = (tmp_blk[j][1]*3)+tmp_blk[j][3];        
		tmp[2] = tmp_blk[j][1]-(tmp_blk[j][3]*3);       
		 
		for (i=0; i<2; i++) 
		{ 
			i1=3-i; 
			tmp_blk[j][i] = tmp[i]+tmp[i1]; 
			tmp_blk[j][i1]= tmp[i]-tmp[i1]; 
		} 
	} 
 
	//vertical transform 
	for (i=0; i<4; i++) 
	{ 
		tmp[0] =(tmp_blk[0][i]+tmp_blk[2][i])<<1;               
		tmp[1] =(tmp_blk[0][i]-tmp_blk[2][i])<<1;               
		 
		tmp[3]= (tmp_blk[1][i]*3)+tmp_blk[3][i];        
		tmp[2]= tmp_blk[1][i]- (tmp_blk[3][i]*3);        
		 
		for (j=0; j<2; j++) 
		{ 
			j1=3-j; 
			tmp_blk[j][i] =(tmp[j]+tmp[j1]+16)>>5; 
			tmp_blk[j1][i]=(tmp[j]-tmp[j1]+16)>>5;   // 
		} 
	} 
		 
	//swapping 
	for(j=0; j<4; j++) 
	  for(i=0; i<4; i++) 
		{pgcurrMB->pred_residual[b8][b4][j][i] = tmp_blk[j][i]; 
		 
		//Just as a intermediate variable for decoding trace 
#if TRACE  
		if(b8<4) 
			MB_IDCT_Y[((b8>>1)<<3)+((b4>>1)<<2)+j][((b8 &1)<<3)+((b4 &1)<<2)+i] = pgcurrMB->pred_residual[b8][b4][j][i]; 
		else 
			MB_IDCT_UV[b8-4][((b4>>1)<<2)+j][((b4 &1)<<2)+i] = pgcurrMB->pred_residual[b8][b4][j][i]; 
#endif 
		} 
 
} 
 
#else 
void Inv_Transform_B4(int b8,int b4)     
{ 
  int i, j, i1, j1; 
  int tmp[4]; 
  int tmp_blk[BLOCK_SIZE][BLOCK_SIZE]; 
 
  for(j=0; j<4; j++) 
    for(i=0; i<4; i++) 
      tmp_blk[j][i] = pgcurrMB->pred_residual[b8][b4][j][i]; 
 
  //horizontal 
  for (j=0; j<4; j++) 
  { 
 
	  tmp[0]= (tmp_blk[j][0]+tmp_blk[j][2])<<2;               
    tmp[1]= (tmp_blk[j][0]-tmp_blk[j][2])<<2;                                        
    tmp[3]= (tmp_blk[j][1]*5)+tmp_blk[j][3]*2;        
    tmp[2]= tmp_blk[j][1]*2-(tmp_blk[j][3]*5);       //zzy 
  
    for (i=0; i<2; i++) 
    { 
      i1=3-i; 
      tmp_blk[j][i]=(tmp[i]+tmp[i1]+2)>>2; 
      tmp_blk[j][i1]=(tmp[i]-tmp[i1]+2)>>2; 
    } 
  } 
 
  //vertical 
  for (i=0; i<4; i++) 
  { 
  	tmp[0]=(tmp_blk[0][i]+tmp_blk[2][i])<<2;               //zzy 
    tmp[1]=(tmp_blk[0][i]-tmp_blk[2][i])<<2;               //zzy 
      
    tmp[3]= (tmp_blk[1][i]*5)+tmp_blk[3][i]*2;       //zzy 
    tmp[2]= tmp_blk[1][i]*2- (tmp_blk[3][i]*5);       //zzy 
     
    for (j=0; j<2; j++) 
    { 
      j1=3-j; 
      tmp_blk[j][i] =(tmp[j]+tmp[j1]+16)>>5; 
      tmp_blk[j1][i]=(tmp[j]-tmp[j1]+16)>>5; 
    } 
  } 
 
  for(j=0; j<4; j++) 
    for(i=0; i<4; i++) 
      pgcurrMB->pred_residual[b8][b4][j][i] = tmp_blk[j][i]; 
} 
#endif 
/* 
************************************************************************* 
* Function:Reconstruction of a 4x4 block. 
* Input: 
* Output: 
* Return:  
* Attention:input curr_blk has to be [lines][pixels] 
************************************************************************* 
*/ 
void Recon_B4(int b8, int b4)    //qwang 2004-3-9 
{ 
	int i,j; 
	short temp; 
	int blk_off_x, blk_off_y; 
	int Mb_off_x, Mb_off_y; 
	 
	blk_off_x = ((b4 &1)<<2); 
	blk_off_y = ((b4>>1)<<2); 
	Mb_off_x  = ((b8 &1)<<3) + blk_off_x; 
	Mb_off_y  = ((b8>>1)<<3) + blk_off_y; 
	 
	for(j=0; j<4; j++) 
	{ 
		for(i=0; i<4; i++) 
		{ 
			if(b8 < 4)   //luma 
			{ 
				 
				temp = (pgcurrMB->pred_sample[b8][b4][i][j] + pgcurrMB->pred_residual[b8][b4][j][i]); 
				pgImage->m7[Mb_off_x+i][Mb_off_y+j] =  pgcurrMB->pred_residual[b8][b4][j][i] = clamp(temp,0,255); 
				imgY[pgImage->pix_y+Mb_off_y+j][pgImage->pix_x+Mb_off_x+i] = pgcurrMB->pred_residual[b8][b4][j][i]; 
#if TRACE			 
				MB_Y[Mb_off_y+j][Mb_off_x+i] = pgcurrMB->pred_residual[b8][b4][j][i]; 
#endif 
			} 
			else        //chroma 
			{ 
				temp = (pgcurrMB->pred_sample[b8][b4][i][j] + pgcurrMB->pred_residual[b8][b4][j][i] ); 
				pgcurrMB->pred_residual[b8][b4][j][i] = clamp(temp,0,255); 
				imgUV[b8-4][pgImage->pix_c_y+blk_off_y+j][pgImage->pix_c_x+blk_off_x+i] = pgcurrMB->pred_residual[b8][b4][j][i]; 
#if TRACE        
				MB_UV[b8-4][blk_off_y+j][blk_off_x+i] = pgcurrMB->pred_residual[b8][b4][j][i]; 
#endif 
				 
			} 
		} 
	} 
} 
 
/* 
************************************************************************* 
* Function:Get predition residual. VLD 
* Input: 
* Output: 
* Return:  
* Attention:input curr_blk has to be [lines][pixels] 
************************************************************************* 
*/ 
void Get_residual( int b8,int b4)  //zhangnan 2004-05-03 
{ 
	int  xx, yy; 
	int  mb_y       = (b8 / 2) << 3; 
	int  mb_x       = (b8 % 2) << 3; 
	 
	if (b8<=3) 
	{ 
		for (yy=0; yypred_residual[b8][b4][yy][xx] = pgImage->m7[mb_x+((b4 &1)<<2)+xx][mb_y+((b4>>1)<<2)+yy];  
	} 
	else 
	{	   
		for (yy=0; yypred_residual[b8][b4][yy][xx] = pgImage->m8[b8-4][((b4 &1)<<2)+xx][((b4>>1)<<2)+yy];  
	} 
	 
} 
 
//#ifdef AVS_ABT 
/************************************************************************* 
* Function: 
		for abt 8x8 dequant. 
* Input: 
* Output: 
* Return:  
* Attention: 
*************************************************************************/ 
void abt_dequant_B8(int qp, int blk)  
{ 
	int val, shift, QPI; 
	int subblk; 
	int xx,yy; 
	shift = IQ_SHIFT[qp]; 
	QPI   = IQ_TAB[qp];  
	for (yy=0; yy<8; yy++) 
	for (xx=0; xx<8; xx++) 
	{ 
		subblk=((yy>>2)<<1)+(xx>>2); 
		val =pgcurrMB->pred_residual[blk][subblk][yy&3][xx&3]; 
		pgcurrMB->pred_residual[blk][subblk][yy&3][xx&3]= (val*QPI+(1<<(shift-1)) )>>(shift); 
	} 
} 
/******************************************************************** 
	Function: 
	         for abt inverse transform 8x8 
	Created:	  
	Author : 
	Input  : 
    Output : 
 
	Function:	 
*********************************************************************/ 
void abt_Itransform_B8(int blk)  
{ 
	short int xx, yy; 
	short int tmp[8]; 
	short int t; 
	short int b[8]; 
	int curr_blk[8][8];	 
	int subblk; 
	 
	for(yy=0; yy<8; yy++) 
	for(xx=0; xx<8; xx++) 
	{ 
		subblk=((yy>>2)<<1)+(xx>>2); 
		curr_blk[yy][xx] = pgcurrMB->pred_residual[blk][subblk][yy&3][xx&3]; 
	} 
		 
	for(yy=0; yy<8; yy++) 
	{ 
		// Horizontal inverse transform 
		// Reorder 
		tmp[0]=curr_blk[yy][0]; 
		tmp[1]=curr_blk[yy][4]; 
		tmp[2]=curr_blk[yy][2]; 
		tmp[3]=curr_blk[yy][6]; 
		tmp[4]=curr_blk[yy][1]; 
		tmp[5]=curr_blk[yy][3]; 
		tmp[6]=curr_blk[yy][5]; 
		tmp[7]=curr_blk[yy][7]; 
		 
		// Downleft Butterfly 
		/*Lou Change*/ 
		b[0] = ((tmp[4] - tmp[7])<<1) + tmp[4]; 
		b[1] = ((tmp[5] + tmp[6])<<1) + tmp[5]; 
		b[2] = ((tmp[5] - tmp[6])<<1) - tmp[6]; 
		b[3] = ((tmp[4] + tmp[7])<<1) + tmp[7]; 
		 
		b[4] = ((b[0] + b[1] + b[3])<<1) + b[1]; 
		b[5] = ((b[0] - b[1] + b[2])<<1) + b[0]; 
		b[6] = ((-b[1] - b[2] + b[3])<<1) + b[3]; 
		b[7] = ((b[0] - b[2] - b[3])<<1) - b[2]; 
		/*Lou End*/ 
		 
		// Upleft Butterfly 
		/*Lou Change*/ 
		t=((tmp[2]*10)+(tmp[3]<<2)); 
		tmp[3]=((tmp[2]<<2)-(tmp[3]*10)); 
		tmp[2]=t; 
		 
		t=(tmp[0]+tmp[1])<<3; 
		tmp[1]=(tmp[0]-tmp[1])<<3; 
		tmp[0]=t; 
		/*Lou End*/ 
		 
		b[0]=tmp[0]+tmp[2]; 
		b[1]=tmp[1]+tmp[3]; 
		b[2]=tmp[1]-tmp[3]; 
		b[3]=tmp[0]-tmp[2];	  
		 
		// Last Butterfly 
		/*Lou Change*/ 
		curr_blk[yy][0]=((b[0]+b[4])+(1<<2))>>3; 
		curr_blk[yy][1]=((b[1]+b[5])+(1<<2))>>3; 
		curr_blk[yy][2]=((b[2]+b[6])+(1<<2))>>3; 
		curr_blk[yy][3]=((b[3]+b[7])+(1<<2))>>3; 
		curr_blk[yy][7]=((b[0]-b[4])+(1<<2))>>3; 
		curr_blk[yy][6]=((b[1]-b[5])+(1<<2))>>3; 
		curr_blk[yy][5]=((b[2]-b[6])+(1<<2))>>3; 
		curr_blk[yy][4]=((b[3]-b[7])+(1<<2))>>3; 
		/*Lou End*/ 
	} 
	// Vertical inverse transform 
	for(xx=0; xx<8; xx++) 
	{ 
		 
		// Reorder 
		tmp[0]=curr_blk[0][xx]; 
		tmp[1]=curr_blk[4][xx]; 
		tmp[2]=curr_blk[2][xx]; 
		tmp[3]=curr_blk[6][xx]; 
		tmp[4]=curr_blk[1][xx]; 
		tmp[5]=curr_blk[3][xx]; 
		tmp[6]=curr_blk[5][xx]; 
		tmp[7]=curr_blk[7][xx]; 
		 
		// Downleft Butterfly 
		/*Lou Change*/ 
		b[0] = ((tmp[4] - tmp[7])<<1) + tmp[4]; 
		b[1] = ((tmp[5] + tmp[6])<<1) + tmp[5]; 
		b[2] = ((tmp[5] - tmp[6])<<1) - tmp[6]; 
		b[3] = ((tmp[4] + tmp[7])<<1) + tmp[7]; 
		 
		b[4] = ((b[0] + b[1] + b[3])<<1) + b[1]; 
		b[5] = ((b[0] - b[1] + b[2])<<1) + b[0]; 
		b[6] = ((-b[1] - b[2] + b[3])<<1) + b[3]; 
		b[7] = ((b[0] - b[2] - b[3])<<1) - b[2]; 
		/*Lou End*/ 
		 
		// Upleft Butterfly 
		/*Lou Change*/ 
		t=((tmp[2]*10)+(tmp[3]<<2)); 
		tmp[3]=((tmp[2]<<2)-(tmp[3]*10)); 
		tmp[2]=t; 
		 
		t=(tmp[0]+tmp[1])<<3; 
		tmp[1]=(tmp[0]-tmp[1])<<3; 
		tmp[0]=t; 
		/*Lou End*/ 
		 
		b[0]=tmp[0]+tmp[2]; 
		b[1]=tmp[1]+tmp[3]; 
		b[2]=tmp[1]-tmp[3]; 
		b[3]=tmp[0]-tmp[2]; 
		 
		// Last Butterfly 
		curr_blk[0][xx]=(b[0]+b[4]+64)>>7; 
		curr_blk[1][xx]=(b[1]+b[5]+64)>>7; 
		curr_blk[2][xx]=(b[2]+b[6]+64)>>7; 
		curr_blk[3][xx]=(b[3]+b[7]+64)>>7; 
		curr_blk[7][xx]=(b[0]-b[4]+64)>>7; 
		curr_blk[6][xx]=(b[1]-b[5]+64)>>7; 
		curr_blk[5][xx]=(b[2]-b[6]+64)>>7; 
		curr_blk[4][xx]=(b[3]-b[7]+64)>>7; 
	} 
	 
	for(yy=0; yy<8; yy++) 
	for(xx=0; xx<8; xx++) 
	{ 
		subblk=((yy>>2)<<1)+(xx>>2); 
		pgcurrMB->pred_residual[blk][subblk][yy&3][xx&3] = curr_blk[yy][xx]; 
	} 
	 
} 
//#endif