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

📄 quantize.c

📁 魔兽2Linux版
💻 C
📖 第 1 页 / 共 3 页
字号:
        pbi->FrameQIndex --;    }    // Re-initialise the q tables for forward and reverse transforms.        init_quantizer ( cpi, qscale, (UINT8) pbi->FrameQIndex );	init_dequantizer ( pbi, qscale, (UINT8) pbi->FrameQIndex );}/***************************************************************************** *   Routine:	init_quantizer**   Purpose:    Used to initialize the encoding/decoding data structures*				and to select DCT algorithm	**   Parameters :*       Input :*           UINT32          scale_factor*                           Defines the factor by which to scale QUANT_ARRAY to*                           produce quantization_array**           UINT8           QIndex          :: *                           Index into Q table for current quantiser value.*   Return value :*       None.******************************************************************************/#define SHIFT16 (1<<16)void init_quantizer ( CP_INSTANCE *cpi, UINT32 scale_factor, UINT8 QIndex ){    int i;                   // Loop counters    double ZBinFactor;    double RoundingFactor;    double temp_fp_quant_coeffs;    double temp_fp_quant_round;    double temp_fp_ZeroBinSize;	PB_INSTANCE *pbi = &cpi->pb;	// Pointers to encoder/decoder specific tables	Q_LIST_ENTRY * Inter_coeffs;	 	Q_LIST_ENTRY * Y_coeffs;	 	Q_LIST_ENTRY * UV_coeffs;	 	Q_LIST_ENTRY * DcScaleFactorTable;	Q_LIST_ENTRY * UVDcScaleFactorTable;    // Notes on setup of quantisers.    // The initial multiplication  by the scale factor is done in the INT32 domain     // to insure that the precision in the quantiser is the same as in the inverse     // quantiser where all calculations are integer.     // The "<< 2" is a normalisation factor for the forward DCT transform.	// New version rounding and ZB characteristics.	Inter_coeffs = Inter_coeffsV1;	Y_coeffs = Y_coeffsV1;	UV_coeffs = UV_coeffsV1;	DcScaleFactorTable = DcScaleFactorTableV1;	UVDcScaleFactorTable = DcScaleFactorTableV1;	ZBinFactor = 0.9;	switch(cpi->Sharpness)	{	case 0:		ZBinFactor = 0.65;		if ( scale_factor <= 50 )			RoundingFactor = 0.499;		else			RoundingFactor = 0.46;		break;	case 1:		ZBinFactor = 0.75;		if ( scale_factor <= 50 )			RoundingFactor = 0.476;		else			RoundingFactor = 0.400;		break;	default:		ZBinFactor = 0.9;		if ( scale_factor <= 50 )			RoundingFactor = 0.476;		else			RoundingFactor = 0.333;		break;	}			    // Use fixed multiplier for intra Y DC	temp_fp_quant_coeffs = (double)(((UINT32)(DcScaleFactorTable[QIndex] * Y_coeffs[0])/100) << 2);	if ( temp_fp_quant_coeffs < MIN_LEGAL_QUANT_ENTRY * 2 )		temp_fp_quant_coeffs = MIN_LEGAL_QUANT_ENTRY * 2;		temp_fp_quant_round = temp_fp_quant_coeffs * RoundingFactor;	pbi->fp_quant_Y_round[0]	= (INT32) (0.5 + temp_fp_quant_round);    temp_fp_ZeroBinSize = temp_fp_quant_coeffs * ZBinFactor;	pbi->fp_ZeroBinSize_Y[0]	= (INT32) (0.5 + temp_fp_ZeroBinSize);   	temp_fp_quant_coeffs = 1.0 / temp_fp_quant_coeffs;	pbi->fp_quant_Y_coeffs[0]	= (INT32) (0.5 + SHIFT16 * temp_fp_quant_coeffs);    	// Intra UV    temp_fp_quant_coeffs = (double)(((UINT32)(UVDcScaleFactorTable[QIndex] * UV_coeffs[0])/100) << 2);	if ( temp_fp_quant_coeffs < MIN_LEGAL_QUANT_ENTRY * 2)		temp_fp_quant_coeffs = MIN_LEGAL_QUANT_ENTRY * 2;    temp_fp_quant_round = temp_fp_quant_coeffs * RoundingFactor;	pbi->fp_quant_UV_round[0]	= (INT32) (0.5 + temp_fp_quant_round);    temp_fp_ZeroBinSize = temp_fp_quant_coeffs * ZBinFactor;	pbi->fp_ZeroBinSize_UV[0]	= (INT32) (0.5 + temp_fp_ZeroBinSize);    	temp_fp_quant_coeffs = 1.0 / temp_fp_quant_coeffs;	pbi->fp_quant_UV_coeffs[0]= (INT32) (0.5 + SHIFT16 * temp_fp_quant_coeffs);	    // Inter Y    temp_fp_quant_coeffs = (double)(((UINT32)(DcScaleFactorTable[QIndex] * Inter_coeffs[0])/100) << 2);	if ( temp_fp_quant_coeffs < MIN_LEGAL_QUANT_ENTRY * 4)		temp_fp_quant_coeffs = MIN_LEGAL_QUANT_ENTRY * 4;	temp_fp_quant_round = temp_fp_quant_coeffs * RoundingFactor;	pbi->fp_quant_Inter_round[0]= (INT32) (0.5 + temp_fp_quant_round);        temp_fp_ZeroBinSize = temp_fp_quant_coeffs * ZBinFactor;	pbi->fp_ZeroBinSize_Inter[0]= (INT32) (0.5 + temp_fp_ZeroBinSize);	temp_fp_quant_coeffs= 1.0 / temp_fp_quant_coeffs;	pbi->fp_quant_Inter_coeffs[0]= (INT32) (0.5 + SHIFT16 * temp_fp_quant_coeffs);    // Inter UV    temp_fp_quant_coeffs = (double)(((UINT32)(UVDcScaleFactorTable[QIndex] * Inter_coeffs[0])/100) << 2);	if ( temp_fp_quant_coeffs < MIN_LEGAL_QUANT_ENTRY * 4)		temp_fp_quant_coeffs = MIN_LEGAL_QUANT_ENTRY * 4;	temp_fp_quant_round = temp_fp_quant_coeffs * RoundingFactor;	pbi->fp_quant_InterUV_round[0]= (INT32) (0.5 + temp_fp_quant_round);        temp_fp_ZeroBinSize = temp_fp_quant_coeffs * ZBinFactor;	pbi->fp_ZeroBinSize_InterUV[0]= (INT32) (0.5 + temp_fp_ZeroBinSize);	temp_fp_quant_coeffs= 1.0 / temp_fp_quant_coeffs;	pbi->fp_quant_InterUV_coeffs[0]= (INT32) (0.5 + SHIFT16 * temp_fp_quant_coeffs);    for ( i = 1; i < 64; i++ )    {		// now scale coefficients by required compression factor		// Intra Y		temp_fp_quant_coeffs =  (double)(((UINT32)(scale_factor * Y_coeffs[i]) / 100 ) << 2 );		if ( temp_fp_quant_coeffs < (MIN_LEGAL_QUANT_ENTRY) )			temp_fp_quant_coeffs = (MIN_LEGAL_QUANT_ENTRY);		temp_fp_quant_round = temp_fp_quant_coeffs * RoundingFactor;		pbi->fp_quant_Y_round[i]		= (INT32) (0.5 + temp_fp_quant_round);        temp_fp_ZeroBinSize = temp_fp_quant_coeffs * ZBinFactor;		pbi->fp_ZeroBinSize_Y[i]		= (INT32) (0.5 + temp_fp_ZeroBinSize);        temp_fp_quant_coeffs = 1.0 / temp_fp_quant_coeffs; 		pbi->fp_quant_Y_coeffs[i]		= (INT32) (0.5 + SHIFT16 * temp_fp_quant_coeffs);        // Intra UV        temp_fp_quant_coeffs =  (double)(((UINT32)(scale_factor * UV_coeffs[i]) / 100 ) << 2 );        if ( temp_fp_quant_coeffs < (MIN_LEGAL_QUANT_ENTRY))            temp_fp_quant_coeffs = (MIN_LEGAL_QUANT_ENTRY);		temp_fp_quant_round = temp_fp_quant_coeffs * RoundingFactor;		pbi->fp_quant_UV_round[i]		= (INT32) (0.5 + temp_fp_quant_round);        temp_fp_ZeroBinSize = temp_fp_quant_coeffs * ZBinFactor;		pbi->fp_ZeroBinSize_UV[i]		= (INT32) (0.5 + temp_fp_ZeroBinSize);        temp_fp_quant_coeffs = 1.0 / temp_fp_quant_coeffs;		pbi->fp_quant_UV_coeffs[i]		= (INT32) (0.5 + SHIFT16 * temp_fp_quant_coeffs);	        // Inter Y		temp_fp_quant_coeffs =  (double)(((UINT32)(scale_factor * Inter_coeffs[i]) / 100 ) << 2 );		if ( temp_fp_quant_coeffs < (MIN_LEGAL_QUANT_ENTRY * 2) )			temp_fp_quant_coeffs = (MIN_LEGAL_QUANT_ENTRY * 2);        temp_fp_quant_round = temp_fp_quant_coeffs * RoundingFactor;    		pbi->fp_quant_Inter_round[i]		= (INT32) (0.5 + temp_fp_quant_round);                    temp_fp_ZeroBinSize = temp_fp_quant_coeffs * ZBinFactor;		pbi->fp_ZeroBinSize_Inter[i]		= (INT32) (0.5 + temp_fp_ZeroBinSize);  		temp_fp_quant_coeffs = 1.0 / temp_fp_quant_coeffs;		pbi->fp_quant_Inter_coeffs[i]	= (INT32) (0.5 + SHIFT16 * temp_fp_quant_coeffs);        // Inter UV		temp_fp_quant_coeffs =  (double)(((UINT32)(scale_factor * Inter_coeffs[i]) / 100 ) << 2 );		if ( temp_fp_quant_coeffs < (MIN_LEGAL_QUANT_ENTRY * 2) )			temp_fp_quant_coeffs = (MIN_LEGAL_QUANT_ENTRY * 2);        temp_fp_quant_round = temp_fp_quant_coeffs * RoundingFactor;    		pbi->fp_quant_InterUV_round[i]		= (INT32) (0.5 + temp_fp_quant_round);                    temp_fp_ZeroBinSize = temp_fp_quant_coeffs * ZBinFactor;		pbi->fp_ZeroBinSize_InterUV[i]		= (INT32) (0.5 + temp_fp_ZeroBinSize);  		temp_fp_quant_coeffs = 1.0 / temp_fp_quant_coeffs;		pbi->fp_quant_InterUV_coeffs[i]	= (INT32) (0.5 + SHIFT16 * temp_fp_quant_coeffs);		}    pbi->fquant_coeffs = pbi->fp_quant_Y_coeffs;}/****************************************************************************//*																			*//*		Select Quantisation Parameters										*//*																			*//*		void select_Y_quantiser ( void )									*//*			sets quantiser to use for Intra Y																			*//*		void select_Inter_quantiser ( void )								*//*			sets quantiser to use for Inter Y																			*//*		void select_UV_quantiser ( void )									*//*			sets quantiser to use UV compression constants					*//*																			*//*		void select_InterUV_quantiser ( void )								*//*			sets quantiser to use for Inter UV																			*//****************************************************************************/void select_Y_quantiser ( PB_INSTANCE *pbi ){	    pbi->fquant_coeffs = pbi->fp_quant_Y_coeffs;    pbi->fquant_round = pbi->fp_quant_Y_round;    pbi->fquant_ZbSize = pbi->fp_ZeroBinSize_Y;}void select_Inter_quantiser ( PB_INSTANCE *pbi ){	    pbi->fquant_coeffs = pbi->fp_quant_Inter_coeffs;    pbi->fquant_round = pbi->fp_quant_Inter_round;    pbi->fquant_ZbSize = pbi->fp_ZeroBinSize_Inter;}void select_UV_quantiser ( PB_INSTANCE *pbi ){	    pbi->fquant_coeffs = pbi->fp_quant_UV_coeffs;    pbi->fquant_round = pbi->fp_quant_UV_round;    pbi->fquant_ZbSize = pbi->fp_quant_UV_round;}void select_InterUV_quantiser ( PB_INSTANCE *pbi ){		pbi->fquant_coeffs = pbi->fp_quant_InterUV_coeffs;	pbi->fquant_round = pbi->fp_quant_InterUV_round;	pbi->fquant_ZbSize = pbi->fp_ZeroBinSize_InterUV;}/**************************************************************************** *   Routine:    quantize**   Purpose:    Quantizes a block of pixels by dividing *               each element by the corresponding entry in the quantization*               array. Output is in a list of values in the zig-zag order.**   Parameters :*       Input :*           DCT_block        -- The block to by quantized*       Output :*           quantized_list   -- The quantized values in zig-zag order**   Return value :*       None.**   Persistent data referenced :*       quantization_array   Module static array read*       zig_zag_index        Module static array read* *****************************************************************************/#define MIN16 ((1<<16)-1)void quantize( PB_INSTANCE *pbi, INT16 * DCT_block, Q_LIST_ENTRY * quantized_list){    UINT32   		i;              /*	Row index */    Q_LIST_ENTRY    val;            /* Quantised value. */        INT32 * FquantRoundPtr = pbi->fquant_round;    INT32 * FquantCoeffsPtr = pbi->fquant_coeffs;    INT32 * FquantZBinSizePtr = pbi->fquant_ZbSize;    INT16 * DCT_blockPtr = DCT_block;    UINT32 * QIndexPtr = (UINT32 *)pbi->quant_index;	INT32 temp;    // Set the quantized_list to default to 0    memset( quantized_list, 0, 64 * sizeof(Q_LIST_ENTRY) );    // Note that we add half divisor to effect rounding on positive number     for( i = 0; i < pbi->Configuration.VFragPixels; i++)    {        // Column 0         if ( DCT_blockPtr[0] >= FquantZBinSizePtr[0] )        {			temp = FquantCoeffsPtr[0] * ( DCT_blockPtr[0] + FquantRoundPtr[0] ) ;			val = (Q_LIST_ENTRY) (temp>>16);            quantized_list[QIndexPtr[0]] = ( val > 511 ) ? 511 : val;        }        else if ( DCT_blockPtr[0] <= -FquantZBinSizePtr[0] )        {			temp = FquantCoeffsPtr[0] * ( DCT_blockPtr[0] - FquantRoundPtr[0] ) + MIN16;			val = (Q_LIST_ENTRY) (temp>>16);            quantized_list[QIndexPtr[0]] = ( val < -511 ) ? -511 : val;        }        // Column 1         if ( DCT_blockPtr[1] >= FquantZBinSizePtr[1] )        {			temp = FquantCoeffsPtr[1] * ( DCT_blockPtr[1] + FquantRoundPtr[1] ) ;			val = (Q_LIST_ENTRY) (temp>>16);            quantized_list[QIndexPtr[1]] = ( val > 511 ) ? 511 : val;        }        else if ( DCT_blockPtr[1] <= -FquantZBinSizePtr[1] )        {			temp = FquantCoeffsPtr[1] * ( DCT_blockPtr[1] - FquantRoundPtr[1] ) + MIN16;			val = (Q_LIST_ENTRY) (temp>>16);            quantized_list[QIndexPtr[1]] = ( val < -511 ) ? -511 : val;        }        // Column 2         if ( DCT_blockPtr[2] >= FquantZBinSizePtr[2] )        {			temp = FquantCoeffsPtr[2] * ( DCT_blockPtr[2] + FquantRoundPtr[2] ) ;			val = (Q_LIST_ENTRY) (temp>>16);            quantized_list[QIndexPtr[2]] = ( val > 511 ) ? 511 : val;        }

⌨️ 快捷键说明

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