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

📄 blkenc.cpp

📁 《Visual C++小波变换技术与工程实践》靳济芳编著的光盘程序。
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*************************************************************************

This software module was originally developed by 

	Ming-Chieh Lee (mingcl@microsoft.com), Microsoft Corporation
	Wei-ge Chen (wchen@microsoft.com), Microsoft Corporation
	Bruce Lin (blin@microsoft.com), Microsoft Corporation
	Chuang Gu (chuanggu@microsoft.com), Microsoft Corporation
	Simon Winder (swinder@microsoft.com), Microsoft Corporation
	(date: March, 1996)
and edited by
        Wei Wu (weiwu@stallion.risc.rockwell.com) Rockwell Science Center

and also edited by
    Fujitsu Laboratories Ltd. (contact: Eishi Morimatsu)


in the course of development of the MPEG-4 Video (ISO/IEC 14496-2). 
This software module is an implementation of a part of one or more MPEG-4 Video tools 
as specified by the MPEG-4 Video. 
ISO/IEC gives users of the MPEG-4 Video free license to this software module or modifications 
thereof for use in hardware or software products claiming conformance to the MPEG-4 Video. 
Those intending to use this software module in hardware or software products are advised that its use may infringe existing patents. 
The original developer of this software module and his/her company, 
the subsequent editors and their companies, 
and ISO/IEC have no liability for use of this software module or modifications thereof in an implementation. 
Copyright is not released for non MPEG-4 Video conforming products. 
Microsoft retains full right to use the code for his/her own purpose, 
assign or donate the code to a third party and to inhibit third parties from using the code for non <MPEG standard> conforming products. 
This copyright notice must be included in all copies or derivative works. 

Copyright (c) 1996, 1997.

Module Name:
	
	blkenc.cpp

Abstract:

	functions for block-level encoding.

Revision History:
	Sep.13	1999 : RRV added by Eishi Morimatsu (Fujitsu Laboratories Ltd.) 

*************************************************************************/

#include <stdlib.h>
#include <math.h>
#include "typeapi.h"
#include "codehead.h"
#include "mode.hpp"
#include "global.hpp"
#include "entropy/bitstrm.hpp"
#include "entropy/entropy.hpp"
#include "entropy/huffman.hpp"
#include "dct.hpp"
#include "vopses.hpp"
#include "vopseenc.hpp"

#ifdef __MFC_
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif

#define new DEBUG_NEW				   
#endif // __MFC_

// HHI Schueuer: sadct
CScanSelectorForSADCT::CScanSelectorForSADCT(Int **rgiCurrMBCoeffWidth) :
	m_rgiCurrMBCoeffWidth(rgiCurrMBCoeffWidth)
{
	m_adaptedScan = new Int[BLOCK_SQUARE_SIZE];
}

CScanSelectorForSADCT::~CScanSelectorForSADCT()
{
	delete [] m_adaptedScan;
}         

Int *CScanSelectorForSADCT::select(Int *scan, Bool bIsBoundary, Int iBlk)
{
	if (bIsBoundary) {
    	// the incoming scan is the zigzag scan for an 8x8 block which must be modified for
        // sadct coded boundary blocks. 
    	const Int *pCoeffWidth = m_rgiCurrMBCoeffWidth[iBlk]; 	
		int n, iy, ix;
        int coeff_count = 0;
        int coeff_count_save = 0;
        Int scan_save[BLOCK_SQUARE_SIZE]; 
        for (n=0; n<BLOCK_SQUARE_SIZE; n++) {
        	iy = scan[n]/BLOCK_SIZE;
            ix = scan[n] % BLOCK_SIZE;
            if (pCoeffWidth[iy] > ix) 
            	m_adaptedScan[coeff_count++] = scan[n];  
            else
            	scan_save[coeff_count_save++] = scan[n];          
        }
        coeff_count_save = 0;
        for (n=coeff_count; n<BLOCK_SQUARE_SIZE; n++)
        	m_adaptedScan[coeff_count++] = scan_save[coeff_count_save++];
        
    	return(m_adaptedScan);
	}
    else
    	return(scan);	
}
// end

// 09/19/99 HHI Schueuer
Int *CScanSelectorForSADCT::select_DP(Int *scan, Bool bIsBoundary, Int iBlk, Int** rgiCurrMBCoeffWidth)
{
	if (bIsBoundary) {
    	// the incoming scan is the zigzag scan for an 8x8 block which must be modified for
        // sadct coded boundary blocks. 
    	const Int *pCoeffWidth = rgiCurrMBCoeffWidth[iBlk]; 
		int n, iy, ix;
        int coeff_count = 0;
        int coeff_count_save = 0;
        Int scan_save[BLOCK_SQUARE_SIZE]; 
        for (n=0; n<BLOCK_SQUARE_SIZE; n++) {
        	iy = scan[n]/BLOCK_SIZE;
            ix = scan[n] % BLOCK_SIZE;
            if (pCoeffWidth[iy] > ix) 
            	m_adaptedScan[coeff_count++] = scan[n];  
            else
            	scan_save[coeff_count_save++] = scan[n];          
        }
        coeff_count_save = 0;
        for (n=coeff_count; n<BLOCK_SQUARE_SIZE; n++)
        	m_adaptedScan[coeff_count++] = scan_save[coeff_count_save++];
        
    	return(m_adaptedScan);
	}
    else 
    	return(scan);	
}
// end 09/19/99

// HHI Schueuer: added const PixelC *rgpxlcBlkShape, Int iBlkShapeWidth for sadct 
Int CVideoObjectEncoder::quantizeIntraBlockTexture (PixelC* ppxlcBlkSrc, 
													 Int iWidthSrc,													 
													 PixelC* ppxlcCurrQBlock, 
													 Int iWidthCurrQ,
													 Int* rgiCoefQ, 
													 Int iQP,
													 Int iDcScaler,
													 Int iBlk, 
													 MacroBlockMemory* pmbmLeft, 
													 MacroBlockMemory* pmbmTop, 
													 MacroBlockMemory* pmbmLeftTop,
													 MacroBlockMemory* pmbmCurr,
													 CMBMode* pmbmdLeft,
													 CMBMode* pmbmdTop,
													 CMBMode* pmbmdLeftTop,
													 CMBMode* pmbmdCurr,
													 const PixelC *rgpxlcBlkShape, 
													 Int iBlkShapeWidth,
                           Int iAuxComp )	
{
//	m_pentrencSet->m_pentrencDCT->bitstream()->trace (ppxlcCurrQBlock, "BLK_TEXTURE");
	// HHI Schueuer: added for sadct
	Int *lx = new Int [iBlkShapeWidth];

	m_pfdct->apply  (ppxlcBlkSrc, iWidthSrc, m_rgiDCTcoef, BLOCK_SIZE, rgpxlcBlkShape, iBlkShapeWidth, lx);

	// RRV insertion
	if(m_vopmd.RRVmode.iOnOff == 1)
	{
		cutoffDCTcoef();
	}
	// ~RRV
	
	quantizeIntraDCcoef (rgiCoefQ, (Float) iDcScaler);
	inverseQuantizeIntraDc (rgiCoefQ, iDcScaler);			//get the quantized block
	if (m_volmd.fQuantizer == Q_H263)	{
		quantizeIntraDCTcoefH263 (rgiCoefQ, 1, iQP);	
		// HHI Schueuer: sadct
		if (rgpxlcBlkShape && !m_volmd.bSadctDisable) {
			// assert(pmbmd->m_rgTranspStatus [iBlk] == PARTIAL);
			// brute force method to clean out mispredictions outside the active region
			// Int *lx = m_rgiCurrMBCoeffWidth[iBlk];
			Int iy, ix;
         
			for (iy = 0; iy < BLOCK_SIZE; iy++) {
				for (ix=lx[iy]; ix<BLOCK_SIZE; ix++)
			  		rgiCoefQ[ix + iy * BLOCK_SIZE] = 0;
			}
		} 		
		//end HHI		
		inverseQuantizeDCTcoefH263 (rgiCoefQ, 1, iQP);		//get the quantized block
	}
	else	{
		quantizeIntraDCTcoefMPEG (rgiCoefQ, 1, iQP, (iBlk > V_BLOCK));	
		// HHI Schueuer: sadct
		if (rgpxlcBlkShape && !m_volmd.bSadctDisable) {
			// assert(pmbmd->m_rgTranspStatus [iBlk] == PARTIAL);
			// brute force method to clean out mispredictions outside the active region
			Int *lx = m_rgiCurrMBCoeffWidth[iBlk];
			Int iy, ix;
         
			for (iy = 0; iy < BLOCK_SIZE; iy++) {
				for (ix=lx[iy]; ix<BLOCK_SIZE; ix++)
			  		rgiCoefQ[ix + iy * BLOCK_SIZE] = 0;
			}
		} 		
		//end
		inverseQuantizeIntraDCTcoefMPEG (rgiCoefQ, 1, iQP, (iBlk > V_BLOCK), 0);											//get the quantized block
	}

	Int i, j;
//	pmbmCurr->rgblkm [iBlk - 1] [0] = rgiCoefQ [0];		//save Qcoef in memory
	pmbmCurr->rgblkm [iBlk - 1] [0] = m_rgiDCTcoef [0];		//save reconstructed DC but quantized AC in memory
	for (i = 1, j = 8; i < BLOCK_SIZE; i++, j += BLOCK_SIZE)	{
		pmbmCurr->rgblkm [iBlk - 1] [i] = rgiCoefQ [i];
		pmbmCurr->rgblkm [iBlk - 1] [i + BLOCK_SIZE - 1] = rgiCoefQ [j];
	}

	Int iSumErr = 0;
	m_rgiQPpred [iBlk - 1] = iQP; //default to current in case no predictor
	iSumErr += decideIntraPredDir (	rgiCoefQ,
								  iBlk,
									m_rgblkmCurrMB [iBlk - 1],
									pmbmLeft, 
  								pmbmTop, 
									pmbmLeftTop,									   
									pmbmCurr,
									pmbmdLeft,
									pmbmdTop,
									pmbmdLeftTop,
									pmbmdCurr,
									m_rgiQPpred [iBlk - 1],
									iQP);
	if(iBlk < A_BLOCK1 || pmbmdCurr->m_pCODAlpha[iAuxComp] == ALPHA_CODED)
		// m_pidct->apply (m_rgiDCTcoef, BLOCK_SIZE, ppxlcCurrQBlock, iWidthCurrQ);
		// HHI Schueuer: rgpxlcBlkShape, iBlkShapeWidth added for sadct
		m_pidct->apply (m_rgiDCTcoef, BLOCK_SIZE, ppxlcCurrQBlock, iWidthCurrQ, rgpxlcBlkShape, iBlkShapeWidth);
	// end HHI
	return iSumErr;
}

Void CVideoObjectEncoder::quantizeIntraDCcoef (Int* rgiCoefQ, Float fltDcScaler)
{
	if (m_volmd.nBits<=8) { // NBIT: may not valid when nBits>8
		assert (fltDcScaler > 0 && fltDcScaler < 128);
	}
#ifdef NO_APPENDIXF
	Float fltDCquantized = (Float) m_rgiDCTcoef [0] / 8.0F;
#else
	Float fltDCquantized = (Float) m_rgiDCTcoef [0] / fltDcScaler;
#endif
	assert (fltDCquantized >= 0);
	fltDCquantized = fltDCquantized + 0.5F;
	Int iMaxDC = (1<<m_volmd.nBits) - 2; // NBIT 1..254
	rgiCoefQ [0] = (Int) max (1, min (iMaxDC, fltDCquantized));
}

Void CVideoObjectEncoder::quantizeIntraDCTcoefH263 (Int* rgiCoefQ, Int iStart, Int iQP)
{
	Int iLevelBits = 12; // 12 bit FLC (= m_volmd.nBits?)
	Int iMaxAC = (1<<(iLevelBits - 1)) - 1; // NBIT 127
	for (Int i = iStart; i < BLOCK_SQUARE_SIZE; i++) {
		Int ilevel = sign(m_rgiDCTcoef [i]) * (abs (m_rgiDCTcoef [i]) / (2 * iQP));
		rgiCoefQ [i] =  min(iMaxAC, max(-iMaxAC, ilevel));
	}
}

Void CVideoObjectEncoder::quantizeInterDCTcoefH263 (Int* rgiCoefQ, Int iStart, Int iQP)
{
	Int iLevelBits = 12; // 12 bit FLC (= m_volmd.nBits?)
	Int iMaxAC = (1<<(iLevelBits - 1)) - 1; // NBIT 127
	for (Int i = iStart; i < BLOCK_SQUARE_SIZE; i++) {
		Int ilevel = sign(m_rgiDCTcoef [i]) * ((abs (m_rgiDCTcoef [i]) - iQP / 2) / (2 * iQP));
		rgiCoefQ [i] =  min(iMaxAC, max(-iMaxAC, ilevel));
	}
}

Void CVideoObjectEncoder::quantizeIntraDCTcoefMPEG (Int* rgiCoefQ, Int iStart, Int iQP,
													Bool bUseAlphaMatrix)
{
	Float fltScaledCoef;
	Int i, iScaledQP, iScaledCoef;
	Int *piQuantizerMatrix;
	if(bUseAlphaMatrix)
		piQuantizerMatrix = m_volmd.rgiIntraQuantizerMatrixAlpha[0];
	else
		piQuantizerMatrix = m_volmd.rgiIntraQuantizerMatrix;
	Int iMaxVal = 1<<(m_volmd.nBits+3); // NBIT 2048
	Int iLevelBits = 12; // 12 bit FLC (= m_volmd.nBits?)
	Int iMaxAC = (1<<(iLevelBits - 1)) - 1; // NBIT 127

	for (i = iStart; i < BLOCK_SQUARE_SIZE; i++) {
		fltScaledCoef = 16.0F * m_rgiDCTcoef [i] / piQuantizerMatrix [i]; 
		iScaledCoef = (Int) rounded (fltScaledCoef);
		iScaledCoef = checkrange (iScaledCoef, -iMaxVal, iMaxVal - 1);
		iScaledQP = (Int) (3.0F * (Float) iQP / 4.0F + 0.5);
		assert (iScaledQP >= 0);
		iScaledCoef = (iScaledCoef + sign(iScaledCoef) * iScaledQP) / (2 * iQP);
		rgiCoefQ [i]  = min(iMaxAC, max(-iMaxAC, iScaledCoef ));
	}
}

Void CVideoObjectEncoder::quantizeInterDCTcoefMPEG (Int* rgiCoefQ, Int iStart, Int iQP,
													Bool bUseAlphaMatrix)
{
	Float fltScaledCoef;
	Int i, iScaledCoef;
	Int *piQuantizerMatrix;
	if(bUseAlphaMatrix)
		piQuantizerMatrix = m_volmd.rgiInterQuantizerMatrixAlpha[0];
	else
		piQuantizerMatrix = m_volmd.rgiInterQuantizerMatrix;
	Int iLevelBits = 12; // 12 bit FLC (= m_volmd.nBits?)
	Int iMaxAC = (1<<(iLevelBits - 1)) - 1; // NBIT 127

	for (i = iStart; i < BLOCK_SQUARE_SIZE; i++) {
		fltScaledCoef = 16.0F * m_rgiDCTcoef [i] / piQuantizerMatrix [i]; 
		iScaledCoef = (Int) rounded (fltScaledCoef);
		iScaledCoef  = iScaledCoef / (2 * iQP);
		rgiCoefQ [i] = min(iMaxAC, max(-iMaxAC, iScaledCoef ));
	}
}

Int CVideoObject::decideIntraPredDir (Int* rgiCoefQ,
									   Int blkn,
									   const BlockMemory& blkmRet, 
									   const MacroBlockMemory* pmbmLeft, 
  									   const MacroBlockMemory* pmbmTop, 
									   const MacroBlockMemory* pmbmLeftTop,
									   const MacroBlockMemory* pmbmCurr,
									   const CMBMode* pmbmdLeft,
									   const CMBMode* pmbmdTop,
									   const CMBMode* pmbmdLeftTop,
									   CMBMode* pmbmdCurr,
									   Int&	iQPpred,
									   Int iQPcurr,
									   Bool bDecideDCOnly)
{
	UInt nBits = m_volmd.nBits;
	Int iDefVal = 1<<(nBits+2);// NBIT: start to calculate default value
	Int iRange = (1<<(nBits-1))-1; // 127 for 8-bit

	Int iQPpredTop, iQPpredLeftTop, iQPpredLeft;
	const BlockMemory blkmTop = findPredictorBlock (blkn, VERTICAL,
		pmbmLeft, pmbmTop, pmbmLeftTop, pmbmCurr,
		pmbmdLeft, pmbmdTop, pmbmdLeftTop, pmbmdCurr, iQPpredTop);
	const BlockMemory blkmLeftTop = findPredictorBlock (blkn, DIAGONAL,
		pmbmLeft, pmbmTop, pmbmLeftTop, pmbmCurr,
		pmbmdLeft, pmbmdTop, pmbmdLeftTop, pmbmdCurr, iQPpredLeftTop);
	const BlockMemory blkmLeft = findPredictorBlock (blkn, HORIZONTAL,
		pmbmLeft, pmbmTop, pmbmLeftTop, pmbmCurr,
		pmbmdLeft, pmbmdTop, pmbmdLeftTop, pmbmdCurr, iQPpredLeft);
	//wchen: changed to 1024 per CD (based on recon instead of Q value now)
/* NBIT: change 1024 to iDefVal
	Int iPredLeftTop = (blkmLeftTop == NULL) ? 1024 : blkmLeftTop [0];		
	Int iHorizontalGrad				= ((blkmTop  == NULL) ? 1024 : blkmTop  [0]) - iPredLeftTop;
	Int iVerticalGrad				= ((blkmLeft == NULL) ? 1024 : blkmLeft [0]) - iPredLeftTop;
*/
	Int iPredLeftTop = (blkmLeftTop == NULL) ? iDefVal : blkmLeftTop [0];		
	Int iHorizontalGrad				= ((blkmTop  == NULL) ? iDefVal : blkmTop  [0]) - iPredLeftTop;
	Int iVerticalGrad				= ((blkmLeft == NULL) ? iDefVal : blkmLeft [0]) - iPredLeftTop;

	blkmRet = NULL;
	UInt i, j;
	Int iSumErr = 0; //per vm4.0, p53
	if (abs(iVerticalGrad)  < abs (iHorizontalGrad))	{
		pmbmdCurr->m_preddir [blkn - 1] = VERTICAL;
		if (blkmTop != NULL)	{
			blkmRet = blkmTop;
			iQPpred = iQPpredTop;
			if (bDecideDCOnly != TRUE)	{
				for (i = 1; i < BLOCK_SIZE; i++)	{
					Int iDiff = rgiCoefQ [i] - divroundnearest(blkmTop [i] * iQPpred, iQPcurr);
					if (iDiff >= -iRange && iDiff <= iRange)	//hack to deal with vm deficiency: ac pred out of range; dc pred is not dealt with
						iSumErr += abs (rgiCoefQ [i]) - abs (iDiff);
					else
						return -100000;	//arbitrary  negative number to turn off ac pred.
				}
			}
		}
	}
	else	{
		pmbmdCurr->m_preddir [blkn - 1] = HORIZONTAL;
		if (blkmLeft != NULL)	{
			blkmRet = blkmLeft;
			iQPpred = iQPpredLeft;
			if (bDecideDCOnly != TRUE)	{
				for (i = 8, j = 8; i < BLOCK_SQUARE_SIZE; i += 8, j++)	{
					Int iDiff = rgiCoefQ [i] - divroundnearest(blkmLeft [j] * iQPpred, iQPcurr);
					if (iDiff >= -iRange && iDiff <= iRange)	//hack to deal with vm deficiency: ac pred out of range; dc pred is not dealt with

⌨️ 快捷键说明

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