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

📄 grayc.cpp

📁 MPEG-4编解码的实现(包括MPEG4视音频编解码)
💻 CPP
📖 第 1 页 / 共 4 页
字号:


Bool CU8Image::atLeastOneValue (PixelC ucVl, const CRct& rct) const
{
	CRct rctRegionOfInterest = (!rct.valid ()) ? where () : rct;
	assert (rctRegionOfInterest <= where ());
	if (rctRegionOfInterest == where ()) {
		const PixelC* ppxlc = pixels ();
		UInt area = where ().area ();
		for (UInt ip = 0; ip < area; ip++) {
			if (ppxlc [ip] == ucVl)
				return TRUE;
		}
	}
	else {
		Int width = where ().width;
		const PixelC* ppxlc = pixels (rctRegionOfInterest.left, rctRegionOfInterest.top);
		for (CoordI y = rctRegionOfInterest.top; y < rctRegionOfInterest.bottom; y++) {
			const PixelC* ppxlcRow = ppxlc;
			for (CoordI x = rctRegionOfInterest.left; x < rctRegionOfInterest.right; x++, ppxlcRow++) {
				if (*ppxlcRow == ucVl)
					return TRUE;
			}
			ppxlc += width;
		}
	}
	return FALSE;
}


UInt CU8Image::numPixelsNotValued (PixelC ucVl, const CRct& rct) const // number of pixels not valued vl in region rct
{
	CRct rctInterest = (!rct.valid ()) ? where () : rct;
	assert (rctInterest <= where ());
	UInt nRet = 0;
	if (rctInterest == where ()) {
		const PixelC* ppxlc = pixels ();
		UInt area = where ().area ();
		for (UInt ip = 0; ip < area; ip++) {
			if (ppxlc [ip] != ucVl)
				nRet++;
		}
	}
	else {
		Int width = where ().width;
		const PixelC* ppxlc = pixels (rctInterest.left, rctInterest.top);
		for (CoordI y = rctInterest.top; y < rctInterest.bottom; y++) {
			const PixelC* ppxlcRow = ppxlc;
			for (CoordI x = rctInterest.left; x < rctInterest.right; x++, ppxlcRow++) {
				if (*ppxlcRow != ucVl)
					nRet++;
			}
			ppxlc += width;
		}
	}

	return nRet;
}


Void CU8Image::setRect (const CRct& rct)
{
	assert (rct.area () == m_rc.area ());
	m_rc = rct;
}

Void CU8Image::threshold (PixelC ucThresh)
{
	PixelC* ppxlThis = (PixelC*) pixels ();
	UInt area = where ().area ();
	for (UInt id = 0; id < area; id++) {
		if (ppxlThis [id] < ucThresh)
			ppxlThis [id] = 0;
	}
}

Void CU8Image::binarize (PixelC ucThresh)
{
	PixelC* ppxlcThis = (PixelC*) pixels ();
	UInt area = where ().area ();
	for (UInt id = 0; id < area; id++, ppxlcThis) {
		if (*ppxlcThis < ucThresh)
			*ppxlcThis = transpValue;
		else
			*ppxlcThis = opaqueValue;
	}
}


/* NBIT: change U8 to PixelC
Void CU8Image::checkRange (U8 ucMin, U8 ucMax)
*/
Void CU8Image::checkRange (PixelC ucMin, PixelC ucMax)
{
	PixelC* ppxlcThis = (PixelC*) pixels ();
	UInt area = where ().area ();
	for (UInt id = 0; id < area; id++, ppxlcThis++)
		*ppxlcThis = checkrange (*ppxlcThis, ucMin, ucMax);
}

own CU8Image* CU8Image::decimate (UInt rateX, UInt rateY) const
{
	const CoordI left = where ().left / (CoordI) rateX;
	const CoordI top = where ().top / (CoordI)  rateY;
	const CoordI right = 
		(where ().right >= 0) ? (where ().right + (CoordI) rateX - 1) / (CoordI) rateX :
		(where ().right - (CoordI) rateX + 1) / (CoordI) rateX;
	const CoordI bottom = 
		(where ().bottom >= 0) ? (where ().bottom + (CoordI) rateX - 1) / (CoordI) rateY :
		(where ().bottom - (CoordI) rateX + 1) / (CoordI) rateY;

	CU8Image* puciRet = new CU8Image (CRct (left, top, right, bottom));
	PixelC* ppxlcRet = (PixelC*) puciRet -> pixels ();
	const PixelC* ppxlcOrgY = pixels ();
	Int skipY = rateY * where ().width;
	
	for (CoordI y = top; y < bottom; y++) {
		const PixelC* ppxlcOrgX = ppxlcOrgY;
		for (CoordI x = left; x < right; x++) {
			*ppxlcRet++ = *ppxlcOrgX;
			ppxlcOrgX += rateX;
		}
		ppxlcOrgY += skipY;
	}
	return puciRet;
}

own CU8Image* CU8Image::decimateBinaryShape (UInt rateX, UInt rateY) const
{
	const CoordI left = where ().left / (CoordI) rateX;
	const CoordI top = where ().top / (CoordI) rateY;
	Int roundR = (where ().right >= 0) ? rateX - 1 : 1 - rateX;
	Int roundB = (where ().bottom >= 0) ? rateY - 1 : 1 - rateY;
	const CoordI right = (where ().right + roundR) / (CoordI) rateX;
	const CoordI bottom = (where ().bottom + roundB) / (CoordI) rateY;

	CU8Image* puciRet = new CU8Image (CRct (left, top, right, bottom));
	PixelC* ppxlcRet = (PixelC*) puciRet -> pixels ();
	const PixelC* ppxlcOrgY = pixels ();
	Int skipY = rateY * where ().width;
	CoordI x, y;
	CoordI iXOrigLeft, iYOrigTop;	//left top of a sampling square

	for (y = top, iYOrigTop = where().top; y < bottom; y++, iYOrigTop += rateY) {
		const PixelC* ppxlcOrgX = ppxlcOrgY;
		for (x = left, iXOrigLeft = where().left; x < right; x++, iXOrigLeft += rateX) {
			CoordI iXOrig, iYOrig;						//for scanning of the sampling square
			const PixelC* ppxlcOrigScanY = ppxlcOrgX;	//same
			*ppxlcRet = transpValue;
			for (iYOrig = iYOrigTop; iYOrig < (iYOrigTop + (Int) rateY); iYOrig++)	{
				if (iYOrig >= where().bottom || *ppxlcRet == opaqueValue)
					break;
				const PixelC* ppxlcOrigScanX = ppxlcOrigScanY; //for scan also
				//Bool bStopScan = FALSE;
				for (iXOrig = iXOrigLeft; iXOrig < (iXOrigLeft + (Int) rateX); iXOrig++)	{
					if (iXOrig >= where().right)
						break;
					assert (*ppxlcOrigScanX == transpValue || *ppxlcOrigScanX == opaqueValue);
					if (*ppxlcOrigScanX == opaqueValue) {
						*ppxlcRet = opaqueValue;
						break;
					}
					ppxlcOrigScanX++;
				}
				ppxlcOrigScanY += where().width;
			}

			assert (*ppxlcRet == transpValue || *ppxlcRet == opaqueValue);
			ppxlcRet++;
			ppxlcOrgX += rateX;
		}
		ppxlcOrgY += skipY;
	}
	return puciRet;
}

own CU8Image* CU8Image::zoomup (UInt rateX, UInt rateY) const
{
	const CoordI left = where ().left * rateX; // left-top coordinate remain the same
	const CoordI top = where ().top * rateY;
	const CoordI right = where ().right * rateX;
	const CoordI bottom = where ().bottom * rateY;

	CU8Image* puciRet = new CU8Image (CRct (left, top, right, bottom));
	PixelC* ppxlRet = (PixelC*) puciRet -> pixels ();
	for (CoordI y = top; y < bottom; y++) {
		for (CoordI x = left; x < right; x++)
			*ppxlRet++ = pixel ((CoordI) (x / (CoordI) rateX), (CoordI) (y / (CoordI) rateY));
	}
	return puciRet;
}

own CU8Image* CU8Image::expand (UInt rateX, UInt rateY) const // expand by putting zeros in between
{
	const CoordI left = where ().left * rateX; // left-top coordinate remain the same
	const CoordI top = where ().top * rateY;
	const CoordI right = where ().right * rateX;
	const CoordI bottom = where ().bottom * rateY;

	CU8Image* puciRet = new CU8Image (CRct (left, top, right, bottom));
	PixelC* ppxlRet = (PixelC*) puciRet -> pixels ();
	const PixelC* ppxlThis = pixels ();
	for (CoordI y = top; y < bottom; y++) {
		for (CoordI x = left; x < right; x++) {
			if (x % rateX == 0 && y % rateY == 0) 
				*ppxlRet++ = *ppxlThis++;
			else
				*ppxlRet++ = 0;
		}
	}
	return puciRet;
}

own CU8Image* CU8Image::biInterpolate () const // bilinearly interpolate the vframe
{
	const CoordI left = where ().left << 1; // left-top coordinate remain the same
	const CoordI top = where ().top << 1;
	const CoordI right = where ().right << 1;
	const CoordI bottom = where ().bottom << 1;
	const CoordI width = right - left;

	CoordI x, y;
	CU8Image* puciRet = new CU8Image (CRct (left, top, right, bottom));
	PixelC* ppxlcRet = (PixelC*) puciRet -> pixels ();
	const PixelC* ppxlc = pixels ();
	const CoordI right1 = right - 2;
	for (y = top; y < bottom; y += 2) { // x-direction interpolation
		for (x = left; x < right1; x += 2) {
			*ppxlcRet++ = *ppxlc++;
			*ppxlcRet++ = (*ppxlc + *(ppxlc - 1) + 1) >> 1;
		}
		*ppxlcRet++ = *ppxlc;
		*ppxlcRet++ = *ppxlc++; // the last pixel of every row do not need average
		ppxlcRet += width;
	}
	ppxlcRet = (PixelC*) puciRet -> pixels ();
	ppxlcRet += width; // start from the second row
	const CoordI width2 = width << 1;
	const CoordI bottom1 = bottom - 1;
	for (x = left; x < right; x++) { // y-direction interpolation
		PixelC* ppxlcRett = ppxlcRet++;
		for (y = top + 1; y < bottom1; y += 2) {
			*ppxlcRett = (*(ppxlcRett - width) + *(ppxlcRett + width) + 1) >> 1;
			ppxlcRett += width2;
		}
		*ppxlcRett = *(ppxlcRett - width); // the last pixel of every column do not need average
	}
	return puciRet;
}

own CU8Image* CU8Image::downsampleForSpatialScalability () const
{
	static Int rgiFilterVertical[13] = {2, 0, -4, -3, 5, 19, 26, 19, 5, -3, -4, 0, 2};
	static Int rgiFilterHorizontal[4] = {5, 11, 11, 5};
	Int iWidthSrc = where (). width;
	Int iHeightSrc = where (). height ();
	assert (iWidthSrc % 2 == 0 && iHeightSrc % 2 == 0);
	Int iWidthDst = iWidthSrc / 2;
	Int iHeightDst = iHeightSrc / 2;
	CU8Image* puciBuffer = new CU8Image (CRct (0, 0, iWidthSrc, iHeightDst));
	CU8Image* puciRet = new CU8Image (CRct (0, 0, iWidthDst, iHeightDst));
	assert (puciBuffer != NULL);
	assert (puciRet != NULL);

	//filter and downsample vertically
	const PixelC* ppxlcSrc;	
	const PixelC* ppxlcColumnHeadSrc = pixels ();
	PixelC* ppxlcDst = (PixelC*) puciBuffer->pixels ();
	PixelC* ppxlcColumnHeadDst = (PixelC*) puciBuffer->pixels ();
	Int i, j, k;
	for (i = 0; i < iWidthSrc; i++)	{
		ppxlcSrc = ppxlcColumnHeadSrc;	
		ppxlcDst = ppxlcColumnHeadDst;	
		for (j = 0; j < iHeightDst; j++)	{
			k = j * 2;         
			const PixelC* ppxlcMinusOne = ( k < 1 ) ? ppxlcSrc : ppxlcSrc - iWidthSrc;		
			const PixelC* ppxlcMinusTwo = ( k < 2 ) ? ppxlcSrc : ppxlcMinusOne - iWidthSrc;
			const PixelC* ppxlcMinusThree = ( k < 3 ) ? ppxlcSrc : ppxlcMinusTwo - iWidthSrc;
			const PixelC* ppxlcMinusFour = ( k < 4 ) ? ppxlcSrc : ppxlcMinusThree - iWidthSrc;
			const PixelC* ppxlcMinusFive = ( k < 5 ) ? ppxlcSrc : ppxlcMinusFour - iWidthSrc;
			const PixelC* ppxlcMinusSix = ( k < 6 ) ? ppxlcSrc : ppxlcMinusFive - iWidthSrc;
			const PixelC* ppxlcPlusOne = ( k >= iHeightSrc - 1) ? ppxlcSrc : ppxlcSrc + iWidthSrc;
			const PixelC* ppxlcPlusTwo = ( k >= iHeightSrc - 2) ? ppxlcPlusOne : ppxlcPlusOne + iWidthSrc;
			const PixelC* ppxlcPlusThree = ( k >= iHeightSrc - 3) ? ppxlcPlusTwo : ppxlcPlusTwo + iWidthSrc;
			const PixelC* ppxlcPlusFour = ( k >= iHeightSrc - 4) ? ppxlcPlusThree : ppxlcPlusThree + iWidthSrc;
			const PixelC* ppxlcPlusFive = ( k >= iHeightSrc - 5) ? ppxlcPlusFour : ppxlcPlusFour + iWidthSrc;
			const PixelC* ppxlcPlusSix = ( k >= iHeightSrc - 6) ? ppxlcPlusFive : ppxlcPlusFive + iWidthSrc;
			*ppxlcDst = checkrangeU8 (
				(U8) ((*ppxlcMinusSix * rgiFilterVertical [0] +
				*ppxlcMinusFive * rgiFilterVertical [1] +
				*ppxlcMinusFour * rgiFilterVertical [2] +
				*ppxlcMinusThree * rgiFilterVertical [3] +
				*ppxlcMinusTwo * rgiFilterVertical [4] +
				*ppxlcMinusOne * rgiFilterVertical [5] +
				*ppxlcSrc * rgiFilterVertical [6] +
				*ppxlcPlusOne * rgiFilterVertical [7] +
				*ppxlcPlusTwo * rgiFilterVertical [8] +
				*ppxlcPlusThree * rgiFilterVertical [9] +
				*ppxlcPlusFour * rgiFilterVertical [10] +
				*ppxlcPlusFive * rgiFilterVertical [11] +
				*ppxlcPlusSix * rgiFilterVertical [12] + 32) >> 6),
				0, 255
			);
			ppxlcSrc += 2 * iWidthSrc;
			ppxlcDst += iWidthSrc;	
		}
		ppxlcColumnHeadSrc++;
		ppxlcColumnHeadDst++;
	} 
	//filter and downsample horizontally
	ppxlcSrc = puciBuffer->pixels ();	
	ppxlcDst = (PixelC*) puciRet->pixels ();
	for (j = 0; j < iHeightDst; j++)	{
		for (i = 0; i < iWidthDst; i++)	{
			k = i * 2;         
			const PixelC* ppxlcMinusOne = ( k < 1 ) ? ppxlcSrc : ppxlcSrc - 1;		
			const PixelC* ppxlcPlusOne = ( k >= iWidthSrc - 1) ? ppxlcSrc : ppxlcSrc + 1;
			const PixelC* ppxlcPlusTwo = ( k >= iWidthSrc - 2) ? ppxlcSrc : ppxlcSrc + 2;
			*ppxlcDst = checkrangeU8 (
				(U8) ((*ppxlcMinusOne * rgiFilterHorizontal [0] +
				*ppxlcSrc * rgiFilterHorizontal [1] +
				*ppxlcPlusOne * rgiFilterHorizontal [2] +
				*ppxlcPlusTwo * rgiFilterHorizontal [3] + 16) >> 5),
				0, 255
			);
			ppxlcSrc += 2;	
			ppxlcDst++;	
		}
	} 
	delete puciBuffer;
	return puciRet;
}

own CU8Image* CU8Image::upsampleForSpatialScalability (	Int iVerticalSamplingFactorM,
														Int iVerticalSamplingFactorN,
														Int iHorizontalSamplingFactorM,
														Int iHorizontalSamplingFactorN,
														Int iType,
														Int iExpandYRefFrame
														) const
{
/*	SONY
	CRct rctDst = where () * 2;
	rctDst.right -=iExpandYRefFrame/iType;
	rctDst.bottom-=iExpandYRefFrame/iType;
	rctDst.left  +=iExpandYRefFrame/iType;
	rctDst.top   +=iExpandYRefFrame/iType;
	rctDst.width -=iExpandYRefFrame/iType*2;

	CRct rctBuf2 = where()*2;
	Int iWidthSrc = where (). width ;
	Int iHeightSrc = where (). height ();
	Int iWidthDst = iWidthSrc*2;
	Int iHeightDst = iHeightSrc*2;
*/

	CRct rctDst = where ();
	Float tmp;

	rctDst.right -= iExpandYRefFrame/iType;
	tmp = (Float) 	rctDst.right * ((Float)iHorizontalSamplingFactorN/iHorizontalSamplingFactorM);
	rctDst.right = (Int) tmp;
	rctDst.right += iExpandYRefFrame/iType;

	rctDst.left += iExpandYRefFrame/iType;
	tmp = (Float)rctDst.left*((Float)iHorizontalSamplingFactorN/iHorizontalSamplingFactorM);
	rctDst.left  = (Int) tmp;
	rctDst.left -= iExpandYRefFrame/iType;

	rctDst.width -= iExpandYRefFrame/iType*2;
	tmp = (Float) rctDst.width * ((Float)iHorizontalSamplingFactorN/iHorizontalSamplingFactorM);
	rctDst.width = (Int ) tmp;
	rctDst.width += iExpandYRefFrame/iType*2;

	
	rctDst.bottom -= iExpandYRefFrame/iType;
	tmp = (Float) rctDst.bottom * ((Float)iVerticalSamplingFactorN/iVerticalSamplingFactorM);
	rctDst.bottom = (Int) tmp;
	rctDst.bottom += iExpandYRefFrame/iType;

	rctDst.top += iExpandYRefFrame/iType;
	tmp = (Float) rctDst.top * ((Float)iVerticalSamplingFactorN/iVerticalSamplingFactorM);
	rctDst.top = (Int) tmp;
	rctDst.top -= iExpandYRefFrame/iType;

	Int iWidthSrc = where (). width ;
	Int iHeightSrc = where (). height ();
	tmp =	(Float) iWidthSrc*((Float)iHorizontalSamplingFactorN/iHorizontalSamplingFactorM);
	//Int iWidthDst = (Int) tmp;

	tmp = (Float)  iHeightSrc*((Float)iVerticalSamplingFactorN/iVerticalSamplingFactorM);
	//Int iHeightDst = (Int) tmp;

	//wchen: this approach is very slow; will have to change later

⌨️ 快捷键说明

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