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

📄 block.cpp

📁 jpeg and mpeg 编解码技术源代码
💻 CPP
字号:
/*************************************************************************

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

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:

	block.cpp

Abstract:

	Block base class

Revision History:
        May. 9   1998:  add boundary by Hyundai Electronics 
                                  Cheol-Soo Park (cspark@super5.hyundai.co.kr) 
*************************************************************************/

#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"

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

#define new DEBUG_NEW				   
#endif // __MFC_

Int divroundnearest(Int i, Int iDenom)
{
	assert(iDenom>0);
	if(i>=0)
		return (i+(iDenom>>1))/iDenom;
	else
		return (i-(iDenom>>1))/iDenom;
}

Void CVideoObject::inverseQuantizeIntraDc (Int* rgiCoefQ, Int iDcScaler)
{
#ifdef NO_APPENDIXF
		m_rgiDCTcoef [0] = (Float) rgiCoefQ [0] * 8;
#else
		m_rgiDCTcoef [0] = rgiCoefQ [0] * iDcScaler;
/*
		if (iQP <= 4)
			m_rgiDCTcoef [0] = rgiCoefQ [0] * 8;
		else if (iQP >= 5 && iQP <= 8)
			m_rgiDCTcoef [0] = rgiCoefQ [0] * 2 * iQP;
		else if (iQP >= 9 && iQP <= 24)
			m_rgiDCTcoef [0] = rgiCoefQ [0] * (iQP + 8);
		else
			m_rgiDCTcoef [0] = rgiCoefQ [0] * (iQP * 2 - 16);
*/
#endif
}

Void CVideoObject::inverseQuantizeDCTcoefH263 (Int* rgiCoefQ, Int iStart, Int iQP)
{
	Int i;
	for (i = iStart; i < BLOCK_SQUARE_SIZE; i++) {
		if (rgiCoefQ[i]) {
			if (iQP % 2 == 1)			//?
				m_rgiDCTcoef [i] = iQP * (2 * abs (rgiCoefQ[i]) + 1);
			else
				m_rgiDCTcoef [i] = iQP * (2 * abs (rgiCoefQ[i]) + 1) - 1;
			m_rgiDCTcoef [i] = sign (rgiCoefQ[i]) * m_rgiDCTcoef [i] ;
		}
		else
			m_rgiDCTcoef [i] = 0;
	}
}

Void CVideoObject::inverseQuantizeIntraDCTcoefMPEG (Int* rgiCoefQ, Int iStart, Int iQP,
													Bool bUseAlphaMatrix)
{
	assert (iQP != 0);
	Int iSum = m_rgiDCTcoef [0];
	Bool bCoefQAllZero = (m_rgiDCTcoef [0] == 0)? TRUE : FALSE;
	Int *piQuantizerMatrix;
	if(bUseAlphaMatrix)
		piQuantizerMatrix = m_volmd.rgiIntraQuantizerMatrixAlpha;
	else
		piQuantizerMatrix = m_volmd.rgiIntraQuantizerMatrix;

	Int iMaxVal = 1<<(m_volmd.nBits+3); // NBIT
	UInt i;
	for (i = iStart; i < BLOCK_SQUARE_SIZE; i++) {
		if (rgiCoefQ [i] == 0)
			m_rgiDCTcoef [i] = 0;
		else {
			m_rgiDCTcoef [i] = iQP * rgiCoefQ [i] * piQuantizerMatrix [i] / 8;
/* NBIT: change
			m_rgiDCTcoef [i] = checkrange (m_rgiDCTcoef [i], -2048, 2047);
*/
			m_rgiDCTcoef [i] = checkrange (m_rgiDCTcoef [i], -iMaxVal, iMaxVal-1);
			bCoefQAllZero = FALSE;
		}
		iSum ^= m_rgiDCTcoef [i];
	}
	if (!bCoefQAllZero) {
		if ((iSum & 0x00000001) == 0)
			m_rgiDCTcoef [i - 1] ^= 0x00000001;
	}
}

Void CVideoObject::inverseQuantizeInterDCTcoefMPEG (Int* rgiCoefQ, Int iStart, Int iQP,
													Bool bUseAlphaMatrix)
{
	assert (iQP != 0);
	Int iSum = 0;
	Bool bCoefQAllZero = TRUE;
	Int *piQuantizerMatrix;
	if(bUseAlphaMatrix)
		piQuantizerMatrix = m_volmd.rgiInterQuantizerMatrixAlpha;
	else
		piQuantizerMatrix = m_volmd.rgiInterQuantizerMatrix;

	Int iMaxVal = 1<<(m_volmd.nBits+3); // NBIT
	UInt i;
	for (i = iStart; i < BLOCK_SQUARE_SIZE; i++)	{
		if (rgiCoefQ [i] == 0)
			m_rgiDCTcoef [i] = 0;
		else {
			m_rgiDCTcoef [i] = (iQP * (rgiCoefQ [i] * 2 + sign(rgiCoefQ [i])) * piQuantizerMatrix [i]) / 16;
/* NBIT: change
			m_rgiDCTcoef [i] = checkrange (m_rgiDCTcoef [i], -2048, 2047);
*/
			m_rgiDCTcoef [i] = checkrange (m_rgiDCTcoef [i], -iMaxVal, iMaxVal-1);
			bCoefQAllZero = FALSE;
		}
		iSum ^= m_rgiDCTcoef [i];
	}
	if (!bCoefQAllZero) {
		if ((iSum & 0x00000001) == 0)
			m_rgiDCTcoef [i - 1] ^= 0x00000001;
	}
}

const BlockMemory CVideoObject::findPredictorBlock (
	BlockNum iBlk, 
	IntraPredDirection predDir,
	const MacroBlockMemory* pmbmLeft, 
	const MacroBlockMemory* pmbmTop,
	const MacroBlockMemory* pmbmLeftTop,
	const MacroBlockMemory* pmbmCurr,
	const CMBMode* pmbmdLeft, 
	const CMBMode* pmbmdTop,
	const CMBMode* pmbmdLeftTop,
	const CMBMode* pmbmdCurr,
	Int& iQPpred
)
{
	const BlockMemory blkmRet = NULL;
	/*BBM// Added for Boundary by Hyundai(1998-5-9)
	if (m_vopmd.bInterlace && pmbmdCurr->m_bMerged [0])
                swapTransparentModes ((CMBMode*)pmbmdCurr, BBM);
	// End of Hyundai(1998-5-9)*/
	if (predDir == HORIZONTAL)	{
		switch (iBlk)	{
		case Y_BLOCK1:
			if (pmbmLeft != NULL && 
				(pmbmdLeft->m_dctMd == INTRA || pmbmdLeft->m_dctMd == INTRAQ) &&
				pmbmdLeft->m_rgTranspStatus [Y_BLOCK2] != ALL)	{
				blkmRet = pmbmLeft->rgblkm [Y_BLOCK2 - 1];
				iQPpred = pmbmdLeft->m_stepSize;
			}
			break;
		case Y_BLOCK2:
			if (pmbmdCurr->m_rgTranspStatus [Y_BLOCK1] != ALL)	{
				blkmRet = pmbmCurr->rgblkm [Y_BLOCK1 - 1];
				iQPpred = pmbmdCurr->m_stepSize;
			}
			break;
		case Y_BLOCK3:
			if (pmbmLeft != NULL && 
				(pmbmdLeft->m_dctMd == INTRA || pmbmdLeft->m_dctMd == INTRAQ) &&
				pmbmdLeft->m_rgTranspStatus [Y_BLOCK4] != ALL)	{
				blkmRet = pmbmLeft->rgblkm [Y_BLOCK4 - 1];
				iQPpred = pmbmdLeft->m_stepSize;
			}
			break;
		case Y_BLOCK4:
			if (pmbmdCurr->m_rgTranspStatus [Y_BLOCK3] != ALL)	{
				blkmRet = pmbmCurr->rgblkm [Y_BLOCK3 - 1];
				iQPpred = pmbmdCurr->m_stepSize;	
			}
			break;
		case A_BLOCK1:
			if (pmbmLeft != NULL && 
				(pmbmdLeft->m_dctMd == INTRA || pmbmdLeft->m_dctMd == INTRAQ) &&
				pmbmdLeft->m_rgTranspStatus [Y_BLOCK2] != ALL)	{
				blkmRet = pmbmLeft->rgblkm [A_BLOCK2 - 1];
				iQPpred = pmbmdLeft->m_stepSizeAlpha;	
			}
			break;
		case A_BLOCK2:
			if (pmbmdCurr->m_rgTranspStatus [Y_BLOCK1] != ALL)	{
				blkmRet = pmbmCurr->rgblkm [A_BLOCK1 - 1];
				iQPpred = pmbmdCurr->m_stepSizeAlpha;	
			}
			break;
		case A_BLOCK3:
			if (pmbmLeft != NULL && 
				(pmbmdLeft->m_dctMd == INTRA || pmbmdLeft->m_dctMd == INTRAQ) &&
				pmbmdLeft->m_rgTranspStatus [Y_BLOCK4] != ALL)	{
				blkmRet = pmbmLeft->rgblkm [A_BLOCK4 - 1];
				iQPpred = pmbmdLeft->m_stepSizeAlpha;	
			}
			break;
		case A_BLOCK4:
			if (pmbmdCurr->m_rgTranspStatus [Y_BLOCK3] != ALL)	{
				blkmRet = pmbmCurr->rgblkm [A_BLOCK3 - 1];
				iQPpred = pmbmdCurr->m_stepSizeAlpha;	
			}
			break;
		default:								//U, V block
			if (pmbmLeft != NULL && 
				(pmbmdLeft->m_dctMd == INTRA || pmbmdLeft->m_dctMd == INTRAQ) &&
				pmbmdLeft->m_rgTranspStatus [ALL_Y_BLOCKS] != ALL)	{
				blkmRet = pmbmLeft->rgblkm [iBlk - 1];
				iQPpred = pmbmdLeft->m_stepSize;	
			}
		}
	}
	else if  (predDir == VERTICAL)	{
		switch (iBlk)	{
		case Y_BLOCK1:
			if (pmbmTop != NULL && 
				(pmbmdTop->m_dctMd == INTRA || pmbmdTop->m_dctMd == INTRAQ) &&
				pmbmdTop->m_rgTranspStatus [Y_BLOCK3] != ALL)	{
				blkmRet = pmbmTop->rgblkm [Y_BLOCK3 - 1];
				iQPpred = pmbmdTop->m_stepSize;	
			}
			break;
		case Y_BLOCK2:
			if (pmbmTop != NULL && 
				(pmbmdTop->m_dctMd == INTRA || pmbmdTop->m_dctMd == INTRAQ) &&
				pmbmdTop->m_rgTranspStatus [Y_BLOCK4] != ALL)	{
				blkmRet = pmbmTop->rgblkm [Y_BLOCK4 - 1];
				iQPpred = pmbmdTop->m_stepSize;	
			}
			break;
		case Y_BLOCK3:
			if (pmbmdCurr->m_rgTranspStatus [Y_BLOCK1] != ALL)	{
				blkmRet = pmbmCurr->rgblkm [Y_BLOCK1 - 1];
				iQPpred = pmbmdCurr->m_stepSize;	
			}
			break;
		case Y_BLOCK4:
			if (pmbmdCurr->m_rgTranspStatus [Y_BLOCK2] != ALL)	{
				blkmRet = pmbmCurr->rgblkm [Y_BLOCK2 - 1];
				iQPpred = pmbmdCurr->m_stepSize;	
			}
			break;
		case A_BLOCK1:
			if (pmbmTop != NULL && 
				(pmbmdTop->m_dctMd == INTRA || pmbmdTop->m_dctMd == INTRAQ) &&
				pmbmdTop->m_rgTranspStatus [Y_BLOCK3] != ALL)	{
				blkmRet = pmbmTop->rgblkm [A_BLOCK3 - 1];
				iQPpred = pmbmdTop->m_stepSizeAlpha;	
			}
			break;
		case A_BLOCK2:
			if (pmbmTop != NULL && 
				(pmbmdTop->m_dctMd == INTRA || pmbmdTop->m_dctMd == INTRAQ) &&
				pmbmdTop->m_rgTranspStatus [Y_BLOCK4] != ALL)	{
				blkmRet = pmbmTop->rgblkm [A_BLOCK4 - 1];
				iQPpred = pmbmdTop->m_stepSizeAlpha;	
			}
			break;
		case A_BLOCK3:
			if (pmbmdCurr->m_rgTranspStatus [Y_BLOCK1] != ALL)	{
				blkmRet = pmbmCurr->rgblkm [A_BLOCK1 - 1];
				iQPpred = pmbmdCurr->m_stepSizeAlpha;	
			}
			break;
		case A_BLOCK4:
			if (pmbmdCurr->m_rgTranspStatus [Y_BLOCK2] != ALL)	{
				blkmRet = pmbmCurr->rgblkm [A_BLOCK2 - 1];
				iQPpred = pmbmdCurr->m_stepSizeAlpha;	
			}
			break;
		default:								//U, V block
			if (pmbmTop != NULL && 
				(pmbmdTop->m_dctMd == INTRA || pmbmdTop->m_dctMd == INTRAQ) &&
				pmbmdTop->m_rgTranspStatus [ALL_Y_BLOCKS] != ALL)	{
				blkmRet = pmbmTop->rgblkm [iBlk - 1];
				iQPpred = pmbmdTop->m_stepSize;	
			}
		}
	}
	else if (predDir == DIAGONAL)	{
		switch (iBlk)	{
		case Y_BLOCK1:
			if (pmbmLeftTop != NULL && 
				(pmbmdLeftTop->m_dctMd == INTRA || pmbmdLeftTop->m_dctMd == INTRAQ) &&
				pmbmdLeftTop->m_rgTranspStatus [Y_BLOCK4] != ALL)	{
				blkmRet = pmbmLeftTop->rgblkm [Y_BLOCK4 - 1];
				iQPpred = pmbmdLeftTop->m_stepSize;	
			}
			break;
		case Y_BLOCK2:
			if (pmbmTop != NULL && 
				(pmbmdTop->m_dctMd == INTRA || pmbmdTop->m_dctMd == INTRAQ) &&
				pmbmdTop->m_rgTranspStatus [Y_BLOCK3] != ALL)	{
				blkmRet = pmbmTop->rgblkm [Y_BLOCK3 - 1];
				iQPpred = pmbmdTop->m_stepSize;	
			}
			break;
		case Y_BLOCK3:
			if (pmbmLeft != NULL && 
				(pmbmdLeft->m_dctMd == INTRA || pmbmdLeft->m_dctMd == INTRAQ) &&
				pmbmdLeft->m_rgTranspStatus [Y_BLOCK2] != ALL)	{
				blkmRet = pmbmLeft->rgblkm [Y_BLOCK2 - 1];
				iQPpred = pmbmdLeft->m_stepSize;	
			}
			break;
		case Y_BLOCK4:
			if (pmbmdCurr->m_rgTranspStatus [Y_BLOCK1] != ALL)	{
				blkmRet = pmbmCurr->rgblkm [Y_BLOCK1 - 1];
				iQPpred = pmbmdCurr->m_stepSize;	
			}
			break;
		case A_BLOCK1:
			if (pmbmLeftTop != NULL && 
				(pmbmdLeftTop->m_dctMd == INTRA || pmbmdLeftTop->m_dctMd == INTRAQ) &&
				pmbmdLeftTop->m_rgTranspStatus [Y_BLOCK4] != ALL)	{
				blkmRet = pmbmLeftTop->rgblkm [A_BLOCK4 - 1];
				iQPpred = pmbmdLeftTop->m_stepSizeAlpha;	
			}
			break;
		case A_BLOCK2:
			if (pmbmTop != NULL && 
				(pmbmdTop->m_dctMd == INTRA || pmbmdTop->m_dctMd == INTRAQ) &&
				pmbmdTop->m_rgTranspStatus [Y_BLOCK3] != ALL)	{
				blkmRet = pmbmTop->rgblkm [A_BLOCK3 - 1];
				iQPpred = pmbmdTop->m_stepSizeAlpha;	
			}
			break;
		case A_BLOCK3:
			if (pmbmLeft != NULL && 
				(pmbmdLeft->m_dctMd == INTRA || pmbmdLeft->m_dctMd == INTRAQ) &&
				pmbmdLeft->m_rgTranspStatus [Y_BLOCK2] != ALL)	{
				blkmRet = pmbmLeft->rgblkm [A_BLOCK2 - 1];
				iQPpred = pmbmdLeft->m_stepSizeAlpha;	
			}
			break;
		case A_BLOCK4:
			if (pmbmdCurr->m_rgTranspStatus [Y_BLOCK1] != ALL)	{
				blkmRet = pmbmCurr->rgblkm [A_BLOCK1 - 1];
				iQPpred = pmbmdCurr->m_stepSizeAlpha;	
			}
			break;
		default:								//U, V block
			if (pmbmLeftTop != NULL && 
				(pmbmdLeftTop->m_dctMd == INTRA || pmbmdLeftTop->m_dctMd == INTRAQ) &&
				pmbmdLeftTop->m_rgTranspStatus [ALL_Y_BLOCKS] != ALL)	{
				blkmRet = pmbmLeftTop->rgblkm [iBlk - 1];
				iQPpred = pmbmdLeftTop->m_stepSize;	
			}
		}
	}
	else 
		assert (FALSE);
	/*BBM// Added for Boundary by Hyundai(1998-5-9)
	if (m_vopmd.bInterlace && pmbmdCurr->m_bMerged [0])
                swapTransparentModes ((CMBMode*)pmbmdCurr, BBS);
	// End of Hyundai(1998-5-9)*/
	return (blkmRet);
}

⌨️ 快捷键说明

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