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. 
************************************************************************ 
*/ 
 
#include "global.h" 
#include "block.h" 
#include "vlc.h" 
 
//#define AVS_1_0 
 
#define clip(a,b,c) ( (a)<(b) ? (b) : ((a)>(c)?(c):(a)) )    //!< clamp a to the range of [b;c] 
extern MacroblockHeader    MbHeader; 
extern MacroblockData      MbData  ;   
extern int sign(int a,int b); 
 
#define Q_BITS          15                //qwang 2004-3-8 
#define DQ_BITS         6                  //qwang 2004-3-8 
#define DQ_ROUND        (1<<(DQ_BITS-1))   //qwang 2004-3-8 
 
const short QP_SCALE_CR[64]= 
{ 
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 
   10,11,12,13,14,15,16,17,18,19, 
   20,21,22,23,24,25,26,27,28,29, 
   30,31,32,33,34,35,36,37,38,39, 
   40,41,42,42,43,43,44,44,45,45, 
   46,46,47,47,48,48,48,49,49,49, 
   50,50,50,51, 
}; 
 
 
static const int quant_coef[6][2][2] = { //qwang 2004-4-4  
  {	  {8192, 6205},	  {6205, 4964}  }, 
  {	  {7282, 5761},	  {5761, 4512}  }, 
  {	  {6554, 5041},	  {5041, 3818}  }, 
  {	  {5699, 4481},	  {4481, 3545}  }, 
  {	  {5041, 4033},	  {4033, 3102}  }, 
  {	  {4520, 3507},	  {3507, 2758}  } 
}; 
 
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} } 
}; 
 
#ifndef AVS_1_0 
  int ScaleM[4][4] ={ 
	  {32768,26214,32768,26214}, 
	  {26214,20972,26214,20972}, 
	  {32768,26214,32768,26214}, 
	  {26214,20972,26214,20972} 
  }; 
   int ABTScaleM[4][4] ={ 
	  {32768,37958,36158,37958}, 
	  {37958,43969,41884,43969}, 
	  {36158,41884,39898,41884}, 
	  {37958,43969,41884,43969} 
  }; 
#else 
 
    int ScaleM[4][4] ={ 
	  {32768,36158,32768,36158}, 
	  {36158,39898,36158,39898}, 
	  {32768,36158,32768,36158}, 
    {36158,39898,36158,39898} 
  }; 
 
#endif 
 
  unsigned short Q_TAB[64] = { 
	  32768,29775,27554,25268,23170,21247,19369,17770, 
		  16302,15024,13777,12634,11626,10624,9742,8958, 
		  8192,7512,6889,6305,5793,5303,4878,4467, 
		  4091,3756,3444,3161,2894,2654,2435,2235, 
		  2048,1878,1722,1579,1449,1329,1218,1117, 
		  1024,939,861,790,724,664,609,558, 
		  512,470,430,395,362,332,304,279, 
		  256,235,215,197,181,166,152,140 
		   
  }; 
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 
		 
}; 
 
#ifndef AVS_1_0 
void Transform_B4(int blk, int subblk)   // block to be transformed.    //qwang 2004-4-4 
{ 
  int tmp[4]; 
  int i,j,i1,j1; 
    
  //  Horizontal transform 
  for (j=0; j<4; j++) 
  { 
    for (i=0; i<2; i++) 
    { 
      i1=3-i; 
      tmp[i]=MbHeader.pred_residual[blk][subblk][j][i] + MbHeader.pred_residual[blk][subblk][j][i1]; 
      tmp[i1]=MbHeader.pred_residual[blk][subblk][j][i] - MbHeader.pred_residual[blk][subblk][j][i1]; 
    } 
     
    MbHeader.pred_residual[blk][subblk][j][0] = (tmp[0]+tmp[1])<<1; 
    MbHeader.pred_residual[blk][subblk][j][2] = (tmp[0]-tmp[1])<<1; 
     
    MbHeader.pred_residual[blk][subblk][j][1] = (tmp[3]*3)+tmp[2]; 
    MbHeader.pred_residual[blk][subblk][j][3] = tmp[3]-(tmp[2]*3); 
  } 
 
  //  Vertical transform 
  for (i=0; i < 4; i++) 
  { 
    for (j=0; j < 2; j++)//zhangnan change 
    { 
      j1=3-j; 
      tmp[j]=MbHeader.pred_residual[blk][subblk][j][i] + MbHeader.pred_residual[blk][subblk][j1][i]; 
      tmp[j1]=MbHeader.pred_residual[blk][subblk][j][i] - MbHeader.pred_residual[blk][subblk][j1][i]; 
    } 
     
    MbHeader.pred_residual[blk][subblk][0][i] = (tmp[0]+tmp[1])<<1; 
    MbHeader.pred_residual[blk][subblk][2][i] = (tmp[0]-tmp[1])<<1; 
    MbHeader.pred_residual[blk][subblk][1][i] = (tmp[3]*3)+tmp[2]; 
    MbHeader.pred_residual[blk][subblk][3][i] = tmp[3]-(tmp[2]*3);     
  } 
} 
#else 
void Transform_B4(int blk, int subblk)   // block to be transformed.    //qwang 2004-4-4 
{ 
  int tmp[4]; 
  int i,j,i1,j1; 
    
  //  Horizontal transform 
  for (j=0; j<4; j++) 
  { 
    for (i=0; i<2; i++) 
    { 
      i1=3-i; 
      tmp[i]=MbHeader.pred_residual[blk][subblk][j][i] + MbHeader.pred_residual[blk][subblk][j][i1]; 
      tmp[i1]=MbHeader.pred_residual[blk][subblk][j][i] - MbHeader.pred_residual[blk][subblk][j][i1]; 
    } 
     
    MbHeader.pred_residual[blk][subblk][j][0] = (tmp[0]+tmp[1])<<2; 
    MbHeader.pred_residual[blk][subblk][j][2] = (tmp[0]-tmp[1])<<2; 
     
    MbHeader.pred_residual[blk][subblk][j][1] = (tmp[3]*5)+tmp[2]*2; 
    MbHeader.pred_residual[blk][subblk][j][3] = tmp[3]*2-(tmp[2]*5); 
  } 
 
  //  Vertical transform 
  for (i=0; i < 4; i++) 
  { 
    for (j=0; j < 2; j++)//zhangnan change 
    { 
      j1=3-j; 
      tmp[j]=MbHeader.pred_residual[blk][subblk][j][i] + MbHeader.pred_residual[blk][subblk][j1][i]; 
      tmp[j1]=MbHeader.pred_residual[blk][subblk][j][i] - MbHeader.pred_residual[blk][subblk][j1][i]; 
    } 
     
    MbHeader.pred_residual[blk][subblk][0][i] = (((tmp[0]+tmp[1])<<2) + 2)>>2; 
    MbHeader.pred_residual[blk][subblk][2][i] = (((tmp[0]-tmp[1])<<2) + 2)>>2; 
    MbHeader.pred_residual[blk][subblk][1][i] = (tmp[3]*5 + tmp[2]*2  + 2)>>2; 
    MbHeader.pred_residual[blk][subblk][3][i] = (tmp[3]*2 - tmp[2]*5  + 2)>>2;     
 
  } 
} 
#endif 
 
#ifndef AVS_1_0 
void Quant_B4(int qp, int blk, int subblk, int* coeff_cost)     // Quantization parameter    //qwang 2004-3-7 
{ 
  int i, j; 
  int val, temp; 
  int qp_const, qp_const1; 
 
  if(blk>=4)  
    qp = QP_SCALE_CR[qp]; 
 
   
	if (pgImage->picture_code_type == INTRA_IMG)   //need modification if intra is used in P frame  ?? 
	{ 
      qp_const = (1<<15)/3;    // intra 
      qp_const1 = (1<<16)/3; 
  } 
	else 
  { 
    qp_const = (1<<15)/6;    // inter 
    qp_const1 = (1<<16)/6; 
  } 
 
 
	for (j=0; j<4; j++) 
	{ 
		for (i=0; i<4; i++) 
		{ 
			val = MbHeader.pred_residual[blk][subblk][j][i]; 
			temp = absm(MbHeader.pred_residual[blk][subblk][j][i]); 
			//sw Chroma DC 
			if ((blk==4 || blk==5) && (i==0 && j==0)) 
				//MbHeader.pred_residual[blk][subblk][j][i] = (((temp * ScaleM[i][j] + (1<<18)) >> 19)*Q_TAB[qp] + qp_const1)>>16; 
				MbHeader.pred_residual[blk][subblk][j][i] = (((temp * ScaleM[i][j] + (1<<18)) >> 19)*Q_TAB[qp] + qp_const)>>15;//zcx 
			else 
				MbHeader.pred_residual[blk][subblk][j][i] = (((temp * ScaleM[i][j] + (1<<18)) >> 19)*Q_TAB[qp] + qp_const)>>15; 
			if (temp!=val) 
				MbHeader.pred_residual[blk][subblk][j][i] = -1*MbHeader.pred_residual[blk][subblk][j][i]; 
		} 
	} 
 
	//zigza scan for vlx out 
	if (zigzag_scan_B4(blk, subblk, coeff_cost)>0) // there are coefficients 
	{ 
		//	removed by dongjie	(pgMbHeader->cbp)     |= (1<cbp_4x4[blk]) |= (1<cbp_4x4[blk]) &= (~(1<=4)  
    qp = QP_SCALE_CR[qp]; 
 
	if (pgImage->picture_code_type == INTRA_IMG)   //need modification if intra is used in P frame  ?? 
	{ 
      qp_const = (1<<15)/3;    // intra 
      qp_const1 = (1<<16)/3; 
  } 
	else 
  { 
    qp_const = (1<<15)/6;    // inter 
    qp_const1 = (1<<16)/6; 
  } 
 
	for (j=0; j<4; j++) 
	{ 
		for (i=0; i<4; i++) 
		{ 
			val = MbHeader.pred_residual[blk][subblk][j][i]; 
			temp = absm(MbHeader.pred_residual[blk][subblk][j][i]); 
			//sw Chroma DC 
			if ((blk==4 || blk==5) && (i==0 && j==0)) 
				MbHeader.pred_residual[blk][subblk][j][i] = (((temp * ScaleM[i][j] + (1<<18)) >> 19)*Q_TAB[qp] + qp_const1)>>16; 
			else 
				MbHeader.pred_residual[blk][subblk][j][i] = (((temp * ScaleM[i][j] + (1<<18)) >> 19)*Q_TAB[qp] + qp_const)>>15; 
			if (temp!=val) 
				MbHeader.pred_residual[blk][subblk][j][i] = -1*MbHeader.pred_residual[blk][subblk][j][i]; 
		} 
	} 
 
	//zigza scan for vlx out 
	if (zigzag_scan_B4(blk, subblk, coeff_cost)>0) // there are coefficients 
		(pgMbHeader->cbp)     |= (1<=4)  
    qp = QP_SCALE_CR[qp]; 
 
  for (j=0; j<4; j++) 
    for (i=0; i<4; i++) 
    { 
      val  = MbHeader.pred_residual[blk][subblk][j][i]; 
      shift = IQ_SHIFT[qp]; 
      QPI   = IQ_TAB[qp];  
 
      MbData.recon_residual[blk][subblk][j][i] = (val*QPI+(1<<(shift-1)))>>shift; 
    } 
} 
 
/* 
************************************************************************* 
* Function: 
		Inverse transform of a 4x4 block. 
* Input: 
* Output: 
* Return:  
* Attention: 
************************************************************************* 
*/ 
#ifndef AVS_1_0 
void Inv_Transform_B4(int blk, int subblk)    //qwang 2004-3-7 
{ 
   int tmp[4]; 
   int i,j,i1,j1; 
 
  //horizontal 
  for (j=0; j<4; j++) 
  { 
 	 
    tmp[0]=(MbData.recon_residual[blk][subblk][j][0]+MbData.recon_residual[blk][subblk][j][2])<<1;               //zzy 
    tmp[1]=(MbData.recon_residual[blk][subblk][j][0]-MbData.recon_residual[blk][subblk][j][2])<<1;               //zzy 
      
   	tmp[3]= (MbData.recon_residual[blk][subblk][j][1]*3)+MbData.recon_residual[blk][subblk][j][3];       //zzy 
	  tmp[2]= MbData.recon_residual[blk][subblk][j][1]-(MbData.recon_residual[blk][subblk][j][3]*3); 
  	 
    for (i=0; i<2; i++) 
    { 
      i1=3-i; 
      MbData.recon_residual[blk][subblk][j][i]=tmp[i]+tmp[i1]; 
      MbData.recon_residual[blk][subblk][j][i1]=tmp[i]-tmp[i1]; 
    } 
  } 
 
  //vertical 
  for (i=0; i<4; i++) 
  { 
    tmp[0]= (MbData.recon_residual[blk][subblk][0][i]+MbData.recon_residual[blk][subblk][2][i])<<1;               //zzy 
    tmp[1]= (MbData.recon_residual[blk][subblk][0][i]-MbData.recon_residual[blk][subblk][2][i])<<1;               //zzy 
      
    tmp[3]= (MbData.recon_residual[blk][subblk][1][i]*3)+MbData.recon_residual[blk][subblk][3][i]; 
    tmp[2]= MbData.recon_residual[blk][subblk][1][i]-(MbData.recon_residual[blk][subblk][3][i]*3); 
 
    for (j=0; j<2; j++) 
    { 
      j1=3-j; 
      MbData.recon_residual[blk][subblk][j][i] =(tmp[j]+tmp[j1]+16)>>5; 
      MbData.recon_residual[blk][subblk][j1][i]=(tmp[j]-tmp[j1]+16)>>5; 
    } 
  } 
} 
#else 
void Inv_Transform_B4(int blk, int subblk)    //qwang 2004-3-7 
{ 
   int tmp[4]; 
   int i,j,i1,j1; 
 
  //horizontal 
  for (j=0; j<4; j++) 
  { 
 	 
    tmp[0]=(MbData.recon_residual[blk][subblk][j][0]+MbData.recon_residual[blk][subblk][j][2])<<2;               //zzy 
    tmp[1]=(MbData.recon_residual[blk][subblk][j][0]-MbData.recon_residual[blk][subblk][j][2])<<2;               //zzy 
      
   	tmp[3]= (MbData.recon_residual[blk][subblk][j][1]*5)+MbData.recon_residual[blk][subblk][j][3]*2;       //zzy 
	  tmp[2]= MbData.recon_residual[blk][subblk][j][1]*2-(MbData.recon_residual[blk][subblk][j][3]*5); 
  	 
    for (i=0; i<2; i++) 
    { 
      i1=3-i; 
      MbData.recon_residual[blk][subblk][j][i]= (tmp[i]+tmp[i1] + 2)>>2; 
      MbData.recon_residual[blk][subblk][j][i1]= (tmp[i]-tmp[i1] +2 )>>2; 
    } 
  } 
 
  //vertical 
  for (i=0; i<4; i++) 
  { 
    tmp[0]= (MbData.recon_residual[blk][subblk][0][i]+MbData.recon_residual[blk][subblk][2][i])<<2;               //zzy 
    tmp[1]= (MbData.recon_residual[blk][subblk][0][i]-MbData.recon_residual[blk][subblk][2][i])<<2;               //zzy 
      
    tmp[3]= (MbData.recon_residual[blk][subblk][1][i]*5)+MbData.recon_residual[blk][subblk][3][i]*2; 
    tmp[2]= MbData.recon_residual[blk][subblk][1][i]*2-(MbData.recon_residual[blk][subblk][3][i]*5); 
 
    for (j=0; j<2; j++) 
    { 
      j1=3-j; 
      MbData.recon_residual[blk][subblk][j][i] =(tmp[j]+tmp[j1]+16)>>5; 
      MbData.recon_residual[blk][subblk][j1][i]=(tmp[j]-tmp[j1]+16)>>5; 
    } 
  } 
} 
#endif 
/******************************************************************** 
	Function: 
	         Reconstruction of a 4x4 block 
	Created:	13:2:2004   
	Author : 
	Input  : 
    Output : 
 
	Function:	 
*********************************************************************/ 
void Recon_B4(int blk, int subblk, int Update_Flag_Inter)    //zhangnan 
{ 
  int left_offset = 0; 
  int pic_x = (MbData.mb_x<<4)+((blk&1)<<3)+((subblk &1)<<2);//zhangnan 
  int pic_x_c = (MbData.mb_x<<3)+((subblk &1)<<2); 
  int i,j; 
  short temp; 
 
  for(j=0; j<4; j++) 
  { 
    for(i=0; i<4; i++) 
    { 
      temp = (short) (MbData.pred_sample[blk][subblk][j][i] + MbData.recon_residual[blk][subblk][j][i]); 
      MbData.pred_sample[blk][subblk][j][i] = clip(temp,0,255); 
    } 
  } 
 
  if (blk<4) 
  { 
	  for(j=0; j<4; j++) 
		  for(i=0; i<4; i++)	 
		  { 
			  imgY1[j][i] = MbData.pred_sample[blk][subblk][j][i];   //zhangnan 
		  } 
  }else 
  { 
    for(j=0; j<4; j++) 
      for(i=0; i<4; i++)	 
      { 
        imgUV1[blk-4][j][i] = MbData.pred_sample[blk][subblk][j][i];  
      } 
  } 
} 
 
 
/* 
************************************************************************* 
* Function: 
		Transfromation of a 2x2 Chroma DC block. 
* Input: 
* Output: 
* Return:  
* Attention: 
************************************************************************* 
 
void TranformChromaDC(int blk) 
{ 
	int m1[4]; 
	int i; 
 
	m1[0] = (MbHeader.pred_residual[blk][0][0][0] + MbHeader.pred_residual[blk][1][0][0] 
	       +  MbHeader.pred_residual[blk][2][0][0] + MbHeader.pred_residual[blk][3][0][0]); 
 
 
	m1[1] = (MbHeader.pred_residual[blk][0][0][0] - MbHeader.pred_residual[blk][1][0][0] 
	       +  MbHeader.pred_residual[blk][2][0][0] - MbHeader.pred_residual[blk][3][0][0]); 
 
	m1[2] = (MbHeader.pred_residual[blk][0][0][0] + MbHeader.pred_residual[blk][1][0][0] 
	       -  MbHeader.pred_residual[blk][2][0][0] - MbHeader.pred_residual[blk][3][0][0]); 
 
	m1[3] = (MbHeader.pred_residual[blk][0][0][0] - MbHeader.pred_residual[blk][1][0][0] 
	       -  MbHeader.pred_residual[blk][2][0][0] + MbHeader.pred_residual[blk][3][0][0]); 
 
	for(i=0; i<4; i++) 
		//MbHeader.pred_residual[blk][i][0][0] = m1[i]; 
		MbHeader.pred_residual[blk][i][0][0] = m1[i]>>1;//zcx 
} 
*/ 
/* 
************************************************************************* 
* Function: 
		Inverse Transfrom of a 2x2 Chroma DC block. 
* Input: 
* Output: 
* Return:  
* Attention: 
************************************************************************* 
 
void InvTransformChromaDC(int blk) 
{ 
  int m1[4]; 
  int i; 
	   
  m1[0] = (MbData.recon_residual[blk][0][0][0] + MbData.recon_residual[blk][1][0][0] 
	       +  MbData.recon_residual[blk][2][0][0] + MbData.recon_residual[blk][3][0][0])>>1; 
 
 
  m1[1] = (MbData.recon_residual[blk][0][0][0] - MbData.recon_residual[blk][1][0][0] 
	       +  MbData.recon_residual[blk][2][0][0] - MbData.recon_residual[blk][3][0][0])>>1; 
 
  m1[2] = (MbData.recon_residual[blk][0][0][0] + MbData.recon_residual[blk][1][0][0] 
	       -  MbData.recon_residual[blk][2][0][0] - MbData.recon_residual[blk][3][0][0])>>1; 
 
  m1[3] = (MbData.recon_residual[blk][0][0][0] - MbData.recon_residual[blk][1][0][0] 
	       -  MbData.recon_residual[blk][2][0][0] + MbData.recon_residual[blk][3][0][0])>>1; 
 
  for(i=0; i<4; i++) 
    MbData.recon_residual[blk][i][0][0] = m1[i]; 
} 
 
*/ 
 
 
 
//#ifdef AVS_ABT 
/************************************************************************* 
* Function: Transfromation of a 8x8 block for ABT. 
* Input:  
* Output: 
* Return:  
* Attention: used by 16x16 16x8 8x16 8x8 
*************************************************************************/ 
 
void abt_transform_B8(int blk)   // for abt 8x8 and up transform 
{ 
  int xx, yy; 
  int b[8]; 
  int tmp[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]=MbHeader.pred_residual[blk][subblk][yy&3][xx&3]; 
	  } 
   
  // Horizontal Transform 
  for(yy=0; yy<8; yy++) 
  { 
    // First Butterfly 
    b[0]=curr_blk[yy][0] + curr_blk[yy][7]; 
    b[1]=curr_blk[yy][1] + curr_blk[yy][6]; 
    b[2]=curr_blk[yy][2] + curr_blk[yy][5]; 
    b[3]=curr_blk[yy][3] + curr_blk[yy][4]; 
    b[4]=curr_blk[yy][0] - curr_blk[yy][7]; 
    b[5]=curr_blk[yy][1] - curr_blk[yy][6]; 
    b[6]=curr_blk[yy][2] - curr_blk[yy][5]; 
    b[7]=curr_blk[yy][3] - curr_blk[yy][4]; 
     
    // Upright Butterfly 
    tmp[0]=b[0] + b[3]; 
    tmp[1]=b[1] + b[2]; 
    tmp[2]=b[0] - b[3]; 
    tmp[3]=b[1] - b[2]; 
     
    b[0]=(tmp[0] + tmp[1])<<3; 
    b[1]=(tmp[0] - tmp[1])<<3; 
    /*Lou Change*/ 
	b[2]=((tmp[2]*10)+(tmp[3]<<2)); 
	b[3]=((tmp[2]<<2)-(tmp[3]*10)); 
    /*Lou End*/ 
     
    // Downright Butterfly 
    tmp[4]=b[4]; 
    tmp[5]=b[5]; 
    tmp[6]=b[6]; 
    tmp[7]=b[7]; 
		   
/*Lou Change*/			 
	tmp[0]=(((tmp[4] - tmp[7])<<1) + tmp[4]); 
	tmp[1]=(((tmp[5] + tmp[6])<<1) + tmp[5]); 
	tmp[2]=(((tmp[5] - tmp[6])<<1) - tmp[6]); 
	tmp[3]=(((tmp[4] + tmp[7])<<1) + tmp[7]);		   
	 
	b[4]=(((tmp[0] + tmp[1] + tmp[3])<<1) + tmp[1]);//			  10*tmp[4]   +9*tmp[5]  +6*tmp[6]  +2*tmp[7]; 
	b[5]=(((tmp[0] - tmp[1] + tmp[2])<<1) + tmp[0]);//			  9*tmp[4]   -2*tmp[5]  -10*tmp[6]  -6*tmp[7]; 
	b[6]=(((-tmp[1] - tmp[2] + tmp[3])<<1) + tmp[3]);//			  6*tmp[4]   -10*tmp[5]  -2*tmp[6]  +9*tmp[7]; 
	b[7]=(((tmp[0] - tmp[2] - tmp[3])<<1) - tmp[2]);//			  2*tmp[4]   -6*tmp[5]  +9*tmp[6]  -10*tmp[7]; 
/*Lou End*/	 
 	 
    // Output 
    curr_blk[yy][0]=b[0]; 
    curr_blk[yy][1]=b[4]; 
    curr_blk[yy][2]=b[2]; 
    curr_blk[yy][3]=b[5]; 
    curr_blk[yy][4]=b[1]; 
    curr_blk[yy][5]=b[6]; 
    curr_blk[yy][6]=b[3]; 
    curr_blk[yy][7]=b[7]; 
  } 
   
  // Vertical transform 
  for(xx=0; xx<8; xx++) 
  { 
    // First Butterfly 
    b[0]=curr_blk[0][xx] + curr_blk[7][xx]; 
    b[1]=curr_blk[1][xx] + curr_blk[6][xx]; 
    b[2]=curr_blk[2][xx] + curr_blk[5][xx]; 
    b[3]=curr_blk[3][xx] + curr_blk[4][xx]; 
    b[4]=curr_blk[0][xx] - curr_blk[7][xx]; 
    b[5]=curr_blk[1][xx] - curr_blk[6][xx]; 
    b[6]=curr_blk[2][xx] - curr_blk[5][xx]; 
    b[7]=curr_blk[3][xx] - curr_blk[4][xx]; 
     
    // Upright Butterfly 
    tmp[0]=b[0] + b[3]; 
    tmp[1]=b[1] + b[2]; 
    tmp[2]=b[0] - b[3]; 
    tmp[3]=b[1] - b[2]; 
     
    b[0]=(tmp[0] + tmp[1])<<3; 
    b[1]=(tmp[0] - tmp[1])<<3; 
    /*Lou Change*/ 
		b[2]=((tmp[2]*10)+(tmp[3]<<2)); 
		b[3]=((tmp[2]<<2)-(tmp[3]*10)); 
    /*Lou End*/ 
     
    // Downright Butterfly 
    tmp[4]=b[4]; 
    tmp[5]=b[5]; 
    tmp[6]=b[6]; 
    tmp[7]=b[7];		   
     
/*Lou Change*/			 
	tmp[0]=(((tmp[4] - tmp[7])<<1) + tmp[4]); 
	tmp[1]=(((tmp[5] + tmp[6])<<1) + tmp[5]); 
	tmp[2]=(((tmp[5] - tmp[6])<<1) - tmp[6]); 
	tmp[3]=(((tmp[4] + tmp[7])<<1) + tmp[7]);		   
	 
	b[4]=(((tmp[0] + tmp[1] + tmp[3])<<1) + tmp[1]);//			  10*tmp[4]   +9*tmp[5]  +6*tmp[6]  +2*tmp[7]; 
	b[5]=(((tmp[0] - tmp[1] + tmp[2])<<1) + tmp[0]);//			  9*tmp[4]   -2*tmp[5]  -10*tmp[6]  -6*tmp[7]; 
	b[6]=(((-tmp[1] - tmp[2] + tmp[3])<<1) + tmp[3]);//			  6*tmp[4]   -10*tmp[5]  -2*tmp[6]  +9*tmp[7]; 
	b[7]=(((tmp[0] - tmp[2] - tmp[3])<<1) - tmp[2]);//			  2*tmp[4]   -6*tmp[5]  +9*tmp[6]  -10*tmp[7]; 
/*Lou End*/ 
			 
     // Output 
    curr_blk[0][xx] = (b[0]+(1<<4))>>5; 
    curr_blk[1][xx] = (b[4]+(1<<4))>>5; 
    curr_blk[2][xx] = (b[2]+(1<<4))>>5; 
    curr_blk[3][xx] = (b[5]+(1<<4))>>5; 
    curr_blk[4][xx] = (b[1]+(1<<4))>>5; 
    curr_blk[5][xx] = (b[6]+(1<<4))>>5; 
    curr_blk[6][xx] = (b[3]+(1<<4))>>5; 
    curr_blk[7][xx] = (b[7]+(1<<4))>>5; 
  }	 
 
 for(yy=0; yy<8; yy++) 
	  for(xx=0; xx<8; xx++) 
	  { 
		  subblk=((yy>>2)<<1)+(xx>>2); 
		  MbHeader.pred_residual[blk][subblk][yy&3][xx&3]=curr_blk[yy][xx]; 
	  }	   
} 
/************************************************************************* 
* Function: 
		for abt 8x8 quantization. 
* Input: 
* Output: 
* Return:  
* Attention: 
*************************************************************************/ 
void abt_quant_B8(int qp, int blk, int *coeff_cost) 
{ 
	int xx, yy; 
	int val, temp; 
	int qp_const; 
	int intra = 0; 
	int divfac; 
	 
	short 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] =MbHeader.pred_residual[blk][subblk][yy&3][xx&3]; 
	}   
	divfac=( intra ? 3:6 ); 
	qp_const = (1<<15)/divfac;  
    qp_const = (1<<15)*10/62; 
	for (yy=0; yy<8; yy++) 
	for (xx=0; xx<8; xx++) 
	{ 
		val = curr_blk[yy][xx]; 
		temp = absm(val); 
		curr_blk[yy][xx] = sign(((((temp * ABTScaleM[yy&3][xx&3] + (1<<18)) >> 19)*Q_TAB[qp]+qp_const)>>15), val); 
		 
	} 
	for(yy=0; yy<8; yy++) 
	for(xx=0; xx<8; xx++) 
	{ 
		subblk=((yy>>2)<<1)+(xx>>2); 
		MbHeader.pred_residual[blk][subblk][yy&3][xx&3] =curr_blk[yy][xx]; 
	} 
	if(abt_zigzag_B8(blk, coeff_cost)>0) // there are coefficients 
		(pgMbHeader->cbp)|= (1<>2)<<1)+(xx>>2); 
		val =MbHeader.pred_residual[blk][subblk][yy&3][xx&3]; 
		MbHeader.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] = MbHeader.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); 
		MbData.recon_residual[blk][subblk][yy&3][xx&3] = curr_blk[yy][xx]; 
	}	    
} 
//for sign qhg for abt 
int sign(int a,int b) 
{ 
	int x; 
	x=absm(a); 
	if (b >= 0) 
		return x; 
	else 
		return -x; 
} 
//#endif