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

📄 block.cpp

📁 H.263的编码程序,加了CPU指令优化,VC版.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//Name   : Quant_blk_I
//Input  : a 8*8 16-bit block coefficients to be quanted pointed by curr_block
//		   QUANT Parameter,QP
//Output : Quanted coefficients, qun_blk
//         zero flag, return value
//Description : quant and scan
//              special quant function for INTRA block for the difference 
//              between INTRA & INTER in quant, so you can use this function 
//              for quant in I picture encode directly.
//Last modified on 2002.11.22 by zj
int Quant_blk_I (INT16 *curr_blk,INT16 *qun_blk, int QP)
{
	int ZeroFlag = 0;
	int QPX2 = QP * 2;
	if (QP)
	{ 
		*qun_blk = mmax (1, mmin (254, *curr_blk / 8));
		for (int i = 1; i < 64; i++)
		{
			if (curr_blk[i] >= QPX2 || curr_blk[i] <= -QPX2)
			{
            // if QP is larger than 8, don't use extended quantization 
//			   if (!codeoption->modified_quantization || QP >= 8)
//			   {
			   qun_blk[MixZig[i]] = mmin (127, mmax (-127, (curr_blk[i] / QPX2))) ;
				
//			   }
//			   else
//			   {
				// no clipping, quantized coefficients  
				//qcoeff[block*64 + i] = sign (coeff[block*64 + i]) * level;
//				qcoeff[tmpposition + MixZig[i]] = coeff[tmpposition + i] / QPX2;
//			    }
			   ZeroFlag=1;
			}
			else
				qun_blk[MixZig[i]] = 0;
		}
		return ZeroFlag;
	}
	else
	{
		printf ("ERROR QUANT = 0 in THIS frame\n!");
		exit (0);
	}
}



//Name   : DeQuant_blk_I
//Input  : a 8*8 16-bit block for dequant, curr_blk
//         quant parameter,QP
//Output : Dequanted block for IDCT, curr_block
//Dciscription : the inverse process of Quant_block_I 
//Last modifid on 2002.11.22 by zj
void DeQuant_blk_I (INT16 *curr_blk, INT16 *recn_blk, int QP)
{
	int i,s,ss=0;
	if (QP)
	{
		ss = (QP%2) ? -1 : 0;
		*(recn_blk) = *(curr_blk) * 8;
		for (i =1; i < 64; i++)
		{
			if (curr_blk[MixZig[i]])
			{
				s = (curr_blk[MixZig[i]] > 0) ? 1 : -1;
				ss *= s;
				recn_blk[i] = QP * (2 * curr_blk[MixZig[i]] + s) + ss;
			}
			else
				recn_blk[i] = 0;
		}
	}
	else
	{
		printf ("ERROR!QUANT = 0 in THIS frame!\n");
		exit (0);
	}

}
*/

/*****************************************************************************
//Name        : Quant_blk_I
//Input       : a 8*8 16-bit block coefficients to be quanted pointed by curr_block
//		        QUANT Parameter,QP
//Output      : Quanted coefficients, qun_blk
//              zero flag, return value
//Description : quant and scan
//              special quant function for INTRA block for the difference 
//              between INTRA & INTER in quant, so you can use this function 
//              for quant in I picture encode directly.
//Optimization: NO
//Last modified on 2002.11.22 by zj
******************************************************************************/
int Quant_blk_I_c (INT16 *curr_blk,INT16 *qun_blk, int QP)
{
  int i;
  int level;
  int nonezero = 0;
  float  QPP2 = 0.5/QP;
    
  if (QP)
  {
      qun_blk[0] = mmax(1,mmin(254, (curr_blk[0]+4)/8));

      for (i = 1; i < 64; i++) 
	  {
        level = (abs(curr_blk[i])) * QPP2;
		if (level == 0)
		{
			qun_blk[MixZig[i]] = 0;

		}
		else
		{
			qun_blk[MixZig[i]] =  mmin(127,mmax(-127,sign(curr_blk[i]) * level));
			nonezero = 1;
		}
      }
  }

  return nonezero;
}


/************************************************************************
//Name         : DeQuant_blk_I
//Input        : a 8*8 16-bit block for dequant, curr_blk
//               quant parameter,QP
//Output       : Dequanted block for IDCT, curr_block
//Dciscription : the inverse process of Quant_block_I 
//Optimization : NO
//Last modifid on 2002.11.22 by zj
*************************************************************************/
void DeQuant_blk_I_c (INT16 *curr_blk, INT16 *recn_blk, int QP)
{
	int i;
    for (i = 0; i < 64; i++) 
	{
      if (curr_blk[MixZig[i]]) 
	  {
        if ((QP % 2) == 1)
          recn_blk[i] = QP * (2*abs(curr_blk[MixZig[i]]) + 1);
        else
          recn_blk[i] = QP * (2*abs(curr_blk[MixZig[i]]) + 1) - 1;
        recn_blk[i] = sign(curr_blk[MixZig[i]]) * recn_blk[i];
      }
      else
        recn_blk[i] = 0;
    }
      recn_blk[0] = curr_blk[0]*8;
}


/*!
*******************************************************************************
*
*   Name:          Quant_blk_P      
*   Description:   Quant and scan 
*   Input:         curr_blk
*   Output:        qun_blk
*   Optimization:  NO
*   Last modified: 2003.2.27
*
*******************************************************************************/
int Quant_blk_P_c (INT16 *curr_blk,INT16 *qun_blk, int QP)
{
  int i;
  int level;
  int nonezero = 0;
  int qpp = QP/2;
  float qp = (float) 1 / (2*QP);
  
  if (QP)
  {

      for (i = 0; i < 64; i++) 
	  {
        //level = (abs(curr_blk[i]) - QP/2) / (2*QP);
		level = (abs(curr_blk[i]) - qpp) * qp;
        if (!level)
		{
			qun_blk[MixZig[i]] = 0;	

		}
		else
		{
			qun_blk[MixZig[i]] =  mmin(127,mmax(-127,sign(curr_blk[i]) * level));
			nonezero = 1;
		}
	  }
  }

  return nonezero;
}




/* removed temporarily, may be utilized in future

int Quant_blk_P(INT16 *curr_blk, INT16 *qun_blk, int QP)
{
	int ZeroFlag = 0;
	int QPX2 = QP * 2;
	int value;
	if (QP)
	{ 	
		for (int i = 0; i < 64; i++)
		{
			if (curr_blk[i] >= QPX2 || curr_blk[i] <= -QPX2)
			{
			   /*! there is a little difference between the following quantification 
			       method and tmn method
				   should be thinked over later
			   */
/*			   value = (abs(curr_blk[i])-QP/2)  / QPX2;
			   qun_blk[MixZig[i]] = mmin (127, mmax (-127, sign(curr_blk[i])*value)) ;
			   ZeroFlag=1;
			}
			else
				qun_blk[MixZig[i]] = 0;
		}
		return ZeroFlag;
	}
	else
	{
		printf ("ERROR QUANT = 0 in THIS frame\n!");
		exit (0);
	}
}
*/

/*!
*******************************************************************************
*
*   Name:          
*   Description:   
*   Input:         
*   Output:        
*   Last modified: 
*
*******************************************************************************/
/*
void DeQuant_blk_P( INT16 *qun_blk, INT16 *curr_blk, int QP)
{
   	int i,s,ss=0;

	if (QP)
	{
		ss = (QP%2) ? -1 : 0;
		for (i =0; i < 64; i++)
		{
			if (qun_blk[MixZig[i]])
			{
				s = (qun_blk[MixZig[i]] > 0) ? 1 : -1;
				ss *= s;
				curr_blk[i] = QP * (2 * qun_blk[MixZig[i]] + s) + ss;
			}
			else
				curr_blk[i] = 0;
		}
	}
	else
	{
		printf ("ERROR!QUANT = 0 in THIS frame!\n");
		exit (0);
	}
}
*/

/*!
*******************************************************************************
*
*   Name:          DeQuant_blk_P      
*   Description:   DeQuant and inverse scan 
*   Input:         curr_blk 
*   Output:        recn_blk 
*   Optimization:  NO
*   Last modified: 2003.2.27
*
*******************************************************************************/
void DeQuant_blk_P_c (INT16 *curr_blk, INT16 *recn_blk, int QP)
{
	int i;
    for (i = 0; i < 64; i++) 
	{
      if (curr_blk[MixZig[i]]) 
	  {
        if ((QP % 2) == 1)
          recn_blk[i] = QP * (2*abs(curr_blk[MixZig[i]]) + 1);
        else
          recn_blk[i] = QP * (2*abs(curr_blk[MixZig[i]]) + 1) - 1;
        recn_blk[i] = sign(curr_blk[MixZig[i]]) * recn_blk[i];
      }
      else
        recn_blk[i] = 0;
    }
}


/**************************************************************************************
//Name        : fdct
//Input       : 8*8 16-bit block data to be transformed: curr_blk.
//Output      : transformed data for quant, rsltblk.
//Description : DCT transform
//Optimization: fdct_mmx.cpp(for IA)
//Last modified on 2003.2.11 by lcl
**************************************************************************************/


void fdct_c (INT16 *curr_blk, INT16 *rsltblk)
{
  int j1, i, j, k;
  float b[8];
  float b1[8];
  float d[8][8];
  float f0 = (float) .7071068;
  float f1 = (float) .4903926;
  float f2 = (float) .4619398;
  float f3 = (float) .4157348;
  float f4 = (float) .3535534;
  float f5 = (float) .2777851;
  float f6 = (float) .1913417;
  float f7 = (float) .0975452;

  for (i = 0, k = 0; i < 8; i++)
  {
	  
	  for (j = 0; j < 4; j++)
	  {
		  j1 = 7 - j;
		  b1[j] = (float) curr_blk[j + k] + (float) curr_blk[j1 + k];
		  b1[j1] = (float) curr_blk[j + k] - (float) curr_blk[j1 + k];
	  }
	  k += 8;
	  b[0] = b1[0] + b1[3];
	  b[1] = b1[1] + b1[2];
	  b[2] = b1[1] - b1[2];
	  b[3] = b1[0] - b1[3];
	  b[4] = b1[4];
	  b[5] = (b1[6] - b1[5]) * f0;
	  b[6] = (b1[6] + b1[5]) * f0;
	  b[7] = b1[7];
	  d[i][0] = (b[0] + b[1]) * f4;
	  d[i][4] = (b[0] - b[1]) * f4;
	  d[i][2] = b[2] * f6 + b[3] * f2;
	  d[i][6] = b[3] * f6 - b[2] * f2;
	  b1[4] = b[4] + b[5];
	  b1[7] = b[7] + b[6];
	  b1[5] = b[4] - b[5];
	  b1[6] = b[7] - b[6];
	  d[i][1] = b1[4] * f7 + b1[7] * f1;
	  d[i][5] = b1[5] * f3 + b1[6] * f5;
	  d[i][7] = b1[7] * f7 - b1[4] * f1;
	  d[i][3] = b1[6] * f3 - b1[5] * f5;
  }
  /* Vertical transform */
  for (i = 0; i < 8; i++)
  {
	  for (j = 0; j < 4; j++)
	  {
		  j1 = 7 - j;
		  b1[j] = d[j][i] + d[j1][i];
		  b1[j1] = d[j][i] - d[j1][i];
	  }
	  b[0] = b1[0] + b1[3];
	  b[1] = b1[1] + b1[2];
	  b[2] = b1[1] - b1[2];
	  b[3] = b1[0] - b1[3];
	  b[4] = b1[4];
	  b[5] = (b1[6] - b1[5]) * f0;
	  b[6] = (b1[6] + b1[5]) * f0;
	  b[7] = b1[7];
	  rsltblk[i] = (short) ((b[0] + b[1]) * f4);
	  rsltblk[32 + i] = (short) ((b[0] - b[1]) * f4);
	  rsltblk[16 + i] = (short) (b[2] * f6 + b[3] * f2);
	  rsltblk[48 + i] = (short) (b[3] * f6 - b[2] * f2);
	  b1[4] = b[4] + b[5];
	  b1[7] = b[7] + b[6];
	  b1[5] = b[4] - b[5];
	  b1[6] = b[7] - b[6];
	  rsltblk[8 + i] = (short) (b1[4] * f7 + b1[7] * f1);
	  rsltblk[40 + i] = (short) (b1[5] * f3 + b1[6] * f5);
	  rsltblk[56 + i] = (short) (b1[7] * f7 - b1[4] * f1);
	  rsltblk[24 + i] = (short) (b1[6] * f3 - b1[5] * f5);
  }
  
}

/******************************************************************************************
//Name        : idct
//Input       : a 8*8 16-bit block dequanted: curr_blk;
//Output      : 8*8 16-bit block: des_blk
//Description : inverse DCT
//Optimization: idctmmx.asm; idct_mmx.cpp. (for IA)
//Last modified on 2002.11.22 by zj
*******************************************************************************************/


void idct_c (INT16 *curr_blk, INT16 *des_blk)
{
  int j1, i, j, k;
  double b[8], b1[8], d[8][8];
  double f0 = .7071068;
  double f1 = .4903926;
  double f2 = .4619398;
  double f3 = .4157348;
  double f4 = .3535534;
  double f5 = .2777851;
  double f6 = .1913417;
  double f7 = .0975452;
  double e, f, g, h;

  /* Horizontal */

  for (i = 0, k = 0; i < 8; i++, k += 8)
  {
    e = ((double) curr_blk[1 + k]) * f7 - ((double) curr_blk[7 + k]) * f1;
    h = ((double) curr_blk[7 + k]) * f7 + ((double) curr_blk[1 + k]) * f1;
    f = ((double) curr_blk[k + 5]) * f3 - ((double) curr_blk[k + 3]) * f5;
    g = ((double) curr_blk[k + 3]) * f3 + ((double) curr_blk[k + 5]) * f5;

    b1[0] = ((double) (curr_blk[k + 0] + curr_blk[k + 4])) * f4;
    b1[1] = ((double) (curr_blk[k + 0] - curr_blk[k + 4])) * f4;
    b1[2] = ((double) curr_blk[k + 2]) * f6 - ((double) curr_blk[k + 6]) * f2;
    b1[3] = ((double) curr_blk[k + 6]) * f6 + ((double) curr_blk[k + 2]) * f2;
    b[4] = e + f;
    b1[5] = e - f;
    b1[6] = h - g;
    b[7] = h + g;

    b[5] = (b1[6] - b1[5]) * f0;
    b[6] = (b1[6] + b1[5]) * f0;
    b[0] = b1[0] + b1[3];
    b[1] = b1[1] + b1[2];
    b[2] = b1[1] - b1[2];
    b[3] = b1[0] - b1[3];

    for (j = 0; j < 4; j++)
    {
      j1 = 7 - j;
      d[i][j] = b[j] + b[j1];
      d[i][j1] = b[j] - b[j1];
    }
  }


  /* Vertical */

  for (i = 0; i < 8; i++)
  {
    e = d[1][i] * f7 - d[7][i] * f1;
    h = d[7][i] * f7 + d[1][i] * f1;
    f = d[5][i] * f3 - d[3][i] * f5;
    g = d[3][i] * f3 + d[5][i] * f5;

    b1[0] = (d[0][i] + d[4][i]) * f4;
    b1[1] = (d[0][i] - d[4][i]) * f4;
    b1[2] = d[2][i] * f6 - d[6][i] * f2;
    b1[3] = d[6][i] * f6 + d[2][i] * f2;
    b[4] = e + f;
    b1[5] = e - f;
    b1[6] = h - g;
    b[7] = h + g;

    b[5] = (b1[6] - b1[5]) * f0;
    b[6] = (b1[6] + b1[5]) * f0;
    b[0] = b1[0] + b1[3];
    b[1] = b1[1] + b1[2];
    b[2] = b1[1] - b1[2];
    b[3] = b1[0] - b1[3];


	for (j = 0, k = 0; j < 4; j++, k += 8)
	{
		j1 = 7 - j;
		des_blk[k + i] = (INT16) mnint(b[j] + b[j1]);
		des_blk[56 - k + i] = (INT16) mnint(b[j] - b[j1]);
	}

  }
}



/*!
*******************************************************************************
*
*   Name:          block_copy1
*   Description:   copy a block(8x8) of data to somewhere in a image
*   Input:         the pointer of source block, the pointer of destination,
*                  width of image
*   Output:        none
*   Optimization:  
*   Last modified: 2002/11/20
*
*******************************************************************************/
void block_copy1_c( unsigned char *des_block, unsigned char *src_block, int lx_des)
{
	unsigned char *tmp = src_block;
	int i, j, k;

	for (i = 0, k = 0; i < 8; i++, k+=lx_des)
	{
		
		for(j = 0; j < 8; j++)
		{
			*(des_block + k + j) = *tmp;
			tmp++;
		}
	
	}	

}
/*!
*******************************************************************************
*
*   Name:          block_copy2
*   Description:   copy a block(8x8) of data in the picture to a 8x8 block
*   Input:         the pointer of source block, the pointer of destination,
*                  width of image
*   Output:        none
*   Optimization:   
*   Last modified: 2003/2/11
*
*******************************************************************************/
void block_copy2_c(INT16 *des_block, unsigned char *src_block, int lx_src)
{
	INT16 *tmp = des_block;
	int i, j, k;

	for (i = 0, k = 0; i < 8; i++, k+=lx_src)
	{
		for(j = 0; j < 8; j++)
		{
		*tmp = (INT16) (*(src_block + k + j)); 		
		tmp++;
		}
	}
}
/*!
*******************************************************************************
*
*   Name:          block_copy3
*   Description:   copy a block(8x8) of data in 8x8 block to the picture
*   Input:         the pointer of source block, the pointer of destination,
*                  width of image
*   Output:        none
*   Optimizaiton:  
*   Last modified: 2003/2/25
*
*******************************************************************************/
void block_copy3_c(unsigned char *des_block, INT16 *src_block, int lx_des)
{
	INT16 *tmp = src_block;
	int i, j, k;

	for (i = 0, k = 0; i < 8; i++, k+=lx_des)
	{
		for(j = 0; j < 8; j++)
		{
			*(des_block + k + j) =(unsigned char)mmin(255, mmax(0, mnint (*tmp))); 
			tmp++;
		}
	}

}

int  block_SAD(INT16 *block)
{
	int sad = 0;
	int i;

	for (i = 0; i < 64; i++)
	{
		sad += absm(block[i]);
	}
	return sad;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -