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

📄 grayi.cpp

📁 MPEG-4编解码的实现(包括MPEG4视音频编解码)
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		for (CoordI x = left; x < right; x++) {
			*ppxliRet++ = *ppxliOrgX;
			ppxliOrgX += rateX;
		}
		ppxliOrgY += skipY;
	}
	return piiRet;
}

own CIntImage* CIntImage::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;

	CIntImage* piiRet = new CIntImage (CRct (left, top, right, bottom));
	PixelI* ppxliRet = (PixelI*) piiRet -> pixels ();
	const PixelI* ppxliOrgY = 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 PixelI* ppxliOrgX = ppxliOrgY;
		for (x = left, iXOrigLeft = where().left; x < right; x++, iXOrigLeft += rateX) {
			CoordI iXOrig, iYOrig;						//for scanning of the sampling square
			const PixelI* ppxliOrigScanY = ppxliOrgX;	//same
			*ppxliRet = transpValue;
			for (iYOrig = iYOrigTop; iYOrig < (iYOrigTop + (Int) rateY); iYOrig++)	{
				if (iYOrig >= where().bottom || *ppxliRet == opaqueValue)
					break;
				const PixelI* ppxliOrigScanX = ppxliOrigScanY; //for scan also
				for (iXOrig = iXOrigLeft; iXOrig < (iXOrigLeft + (Int) rateX); iXOrig++)	{
					if (iXOrig >= where().right)
						break;
					assert (*ppxliOrigScanX == transpValue || *ppxliOrigScanX == opaqueValue);
					if (*ppxliOrigScanX == opaqueValue) {
						*ppxliRet = opaqueValue;
						break;
					}
					ppxliOrigScanX++;
				}
				ppxliOrigScanY += where().width;
			}

			assert (*ppxliRet == transpValue || *ppxliRet == opaqueValue);
			ppxliRet++;
			ppxliOrgX += rateX;
		}
		ppxliOrgY += skipY;
	}
	return piiRet;
}

own CIntImage* CIntImage::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;

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

own CIntImage* CIntImage::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;

	CIntImage* piiRet = new CIntImage (CRct (left, top, right, bottom));
	PixelI* ppxlRet = (PixelI*) piiRet -> pixels ();
	const PixelI* 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 piiRet;
}

own CIntImage* CIntImage::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;
	CIntImage* piiRet = new CIntImage (CRct (left, top, right, bottom));
	PixelI* ppxliRet = (PixelI*) piiRet -> pixels ();
	const PixelI* ppxli = pixels ();
	const CoordI right1 = right - 2;
	for (y = top; y < bottom; y += 2) { // x-direction interpolation
		for (x = left; x < right1; x += 2) {
			*ppxliRet++ = *ppxli++;
			*ppxliRet++ = (*ppxli + *(ppxli - 1) + 1) >> 1;
		}
		*ppxliRet++ = *ppxli;
		*ppxliRet++ = *ppxli++; // the last pixel of every row do not need average
		ppxliRet += width;
	}
	ppxliRet = (PixelI*) piiRet -> pixels ();
	ppxliRet += 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
		PixelI* ppxliRett = ppxliRet++;
		for (y = top + 1; y < bottom1; y += 2) {
			*ppxliRett = (*(ppxliRett - width) + *(ppxliRett + width) + 1) >> 1;
			ppxliRett += width2;
		}
		*ppxliRett = *(ppxliRett - width); // the last pixel of every column do not need average
	}
	return piiRet;
}

own CIntImage* CIntImage::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;
	CIntImage* piiBuffer = new CIntImage (CRct (0, 0, iWidthSrc, iHeightDst));
	CIntImage* piiRet = new CIntImage (CRct (0, 0, iWidthDst, iHeightDst));
	assert (piiBuffer != NULL);
	assert (piiRet != NULL);

	//filter and downsample vertically
	const PixelI* ppxliSrc;	
	const PixelI* ppxliColumnHeadSrc = pixels ();
	PixelI* ppxliDst = (PixelI*) piiBuffer->pixels ();
	PixelI* ppxliColumnHeadDst = (PixelI*) piiBuffer->pixels ();
	Int i, j, k;
	for (i = 0; i < iWidthSrc; i++)	{
		ppxliSrc = ppxliColumnHeadSrc;	
		ppxliDst = ppxliColumnHeadDst;	
		for (j = 0; j < iHeightDst; j++)	{
			k = j * 2;         
			const PixelI* ppxliMinusOne = ( k < 1 ) ? ppxliSrc : ppxliSrc - iWidthSrc;		
			const PixelI* ppxliMinusTwo = ( k < 2 ) ? ppxliSrc : ppxliMinusOne - iWidthSrc;
			const PixelI* ppxliMinusThree = ( k < 3 ) ? ppxliSrc : ppxliMinusTwo - iWidthSrc;
			const PixelI* ppxliMinusFour = ( k < 4 ) ? ppxliSrc : ppxliMinusThree - iWidthSrc;
			const PixelI* ppxliMinusFive = ( k < 5 ) ? ppxliSrc : ppxliMinusFour - iWidthSrc;
			const PixelI* ppxliMinusSix = ( k < 6 ) ? ppxliSrc : ppxliMinusFive - iWidthSrc;
			const PixelI* ppxliPlusOne = ( k >= iHeightSrc - 1) ? ppxliSrc : ppxliSrc + iWidthSrc;
			const PixelI* ppxliPlusTwo = ( k >= iHeightSrc - 2) ? ppxliPlusOne : ppxliPlusOne + iWidthSrc;
			const PixelI* ppxliPlusThree = ( k >= iHeightSrc - 3) ? ppxliPlusTwo : ppxliPlusTwo + iWidthSrc;
			const PixelI* ppxliPlusFour = ( k >= iHeightSrc - 4) ? ppxliPlusThree : ppxliPlusThree + iWidthSrc;
			const PixelI* ppxliPlusFive = ( k >= iHeightSrc - 5) ? ppxliPlusFour : ppxliPlusFour + iWidthSrc;
			const PixelI* ppxliPlusSix = ( k >= iHeightSrc - 6) ? ppxliPlusFive : ppxliPlusFive + iWidthSrc;
			*ppxliDst = checkrange (
				(Int) ((*ppxliMinusSix * rgiFilterVertical [0] +
				*ppxliMinusFive * rgiFilterVertical [1] +
				*ppxliMinusFour * rgiFilterVertical [2] +
				*ppxliMinusThree * rgiFilterVertical [3] +
				*ppxliMinusTwo * rgiFilterVertical [4] +
				*ppxliMinusOne * rgiFilterVertical [5] +
				*ppxliSrc * rgiFilterVertical [6] +
				*ppxliPlusOne * rgiFilterVertical [7] +
				*ppxliPlusTwo * rgiFilterVertical [8] +
				*ppxliPlusThree * rgiFilterVertical [9] +
				*ppxliPlusFour * rgiFilterVertical [10] +
				*ppxliPlusFive * rgiFilterVertical [11] +
				*ppxliPlusSix * rgiFilterVertical [12] + 32) >> 6),
				0, 255
			);
			ppxliSrc += 2 * iWidthSrc;
			ppxliDst += iWidthSrc;	
		}
		ppxliColumnHeadSrc++;
		ppxliColumnHeadDst++;
	} 
	//filter and downsample horizontally
	ppxliSrc = piiBuffer->pixels ();	
	ppxliDst = (PixelI*) piiRet->pixels ();
	for (j = 0; j < iHeightDst; j++)	{
		for (i = 0; i < iWidthDst; i++)	{
			k = i * 2;         
			const PixelI* ppxliMinusOne = ( k < 1 ) ? ppxliSrc : ppxliSrc - 1;		
			const PixelI* ppxliPlusOne = ( k >= iWidthSrc - 1) ? ppxliSrc : ppxliSrc + 1;
			const PixelI* ppxliPlusTwo = ( k >= iWidthSrc - 2) ? ppxliSrc : ppxliSrc + 2;
			*ppxliDst = checkrange (
				(Int) ((*ppxliMinusOne * rgiFilterHorizontal [0] +
				*ppxliSrc * rgiFilterHorizontal [1] +
				*ppxliPlusOne * rgiFilterHorizontal [2] +
				*ppxliPlusTwo * rgiFilterHorizontal [3] + 16) >> 5),
				0, 255
			);
			ppxliSrc += 2;	
			ppxliDst++;	
		}
	} 
	delete piiBuffer;
	return piiRet;
}

own CIntImage* CIntImage::upsampleForSpatialScalability () const
{
	CRct rctDst = where () * 2;
	Int iWidthSrc = where (). width;
	Int iHeightSrc = where (). height ();
	Int iHeightDst = iHeightSrc * 2;
	CIntImage* piiBuffer = new CIntImage (CRct (where().left, rctDst.top, where().right, rctDst.bottom));
	CIntImage* piiRet = new CIntImage (CRct (rctDst.left, rctDst.top, rctDst.right, rctDst.bottom));

	//upsample vertically
	const PixelI* ppxliSrc;	
	const PixelI* ppxliSrcPlusOne;	
	const PixelI* ppxliColumnHeadSrc = pixels ();
	PixelI* ppxliDst;
	PixelI* ppxliColumnHeadDst = (PixelI*) piiBuffer->pixels ();
	Int i, j;
	for (i = 0; i < iWidthSrc; i++)	{
		ppxliSrc = ppxliColumnHeadSrc;	
		ppxliSrcPlusOne = ppxliSrc + iWidthSrc;
		ppxliDst = ppxliColumnHeadDst;	
		for (j = 0; j < iHeightSrc; j++)	{
			*ppxliDst = checkrange (
				(Int) ((*ppxliSrc * 3 + *ppxliSrcPlusOne + 2) >> 2),
				0, 255
			);
			ppxliDst += iWidthSrc;
			*ppxliDst = checkrange ( 
				(Int) ((*ppxliSrc + *ppxliSrcPlusOne * 3 + 2) >> 2),
				0, 255
			);
			ppxliDst += iWidthSrc;
			ppxliSrc += iWidthSrc;
			ppxliSrcPlusOne = (j >= iHeightSrc - 2) ? ppxliSrc : ppxliSrc + iWidthSrc;
		}
		ppxliColumnHeadSrc++;
		ppxliColumnHeadDst++;
	} 

	//upsample horizontally	
	ppxliSrc = piiBuffer->pixels ();
	ppxliDst = (PixelI*) piiRet->pixels ();
	for (j = 0; j < iHeightDst; j++)	{
		ppxliSrcPlusOne = ppxliSrc + 1;
		for (i = 0; i < iWidthSrc; i++)	{
			*ppxliDst = checkrange ( 
				(Int) ((*ppxliSrc * 3 + *ppxliSrcPlusOne + 2) >> 2),
				0, 255
			);
			ppxliDst++;
			*ppxliDst = checkrange ( 
				(Int) ((*ppxliSrc + *ppxliSrcPlusOne * 3 + 2) >> 2),
				0, 255
			);
			ppxliDst++;
			ppxliSrc++;
			ppxliSrcPlusOne = (i >= iWidthSrc - 2) ? ppxliSrc : ppxliSrc + 1;
		}
	} 
	delete piiBuffer;
	return piiRet;
}

own CIntImage* CIntImage::biInterpolate (UInt accuracy) const // bilinearly interpolate the vframe
{
	const CoordI left = where ().left * accuracy;
	const CoordI top = where ().top * accuracy;
	const CoordI right = where ().right * accuracy;
	const CoordI bottom = where ().bottom * accuracy;

	CIntImage* piiRet = new CIntImage (CRct (left, top, right, bottom));
	PixelI* ppxliRet = (PixelI*) piiRet -> pixels ();
	for (CoordI y = top; y < bottom; y++) { // x-direction interpolation
		for (CoordI x = left; x < right; x++) {
			*ppxliRet = pixel (x, y, accuracy);
			ppxliRet++;
		}
	}
	return piiRet;
}

own CIntImage* CIntImage::transpose () const
{
	CRct rctDst = where ();
	rctDst.transpose ();
	CIntImage* piiDst = new CIntImage (rctDst);
	const PixelI* ppxlSrc = pixels ();
	PixelI* ppxlDstRow = (PixelI*) piiDst->pixels ();
	PixelI* ppxlDst;
	UInt height = where ().height ();
	for (CoordI iy = where ().top; iy < where ().bottom; iy++)	{
		ppxlDst = ppxlDstRow;
		for (CoordI ix = where ().left; ix < where ().right; ix++)	{
			*ppxlDst = *ppxlSrc++;
			ppxlDst += height;
		}
		ppxlDstRow++;
	}
	return piiDst;
}

own CIntImage* CIntImage::warp (const CAffine2D& aff) const // affine warp
{
	CSiteD stdLeftTopWarp = aff * CSiteD (where ().left, where ().top);
	CSiteD stdRightTopWarp = aff * CSiteD (where ().right, where ().top);
	CSiteD stdLeftBottomWarp = aff * CSiteD (where ().left, where ().bottom);
	CSiteD stdRightBottomWarp = aff * CSiteD (where ().right, where ().bottom);
	CRct rctWarp (stdLeftTopWarp, stdRightTopWarp, stdLeftBottomWarp, stdRightBottomWarp);

	CIntImage* piiRet = new CIntImage (rctWarp);
	PixelI* ppxliRet = (PixelI*) piiRet -> pixels ();
	CAffine2D affInv = aff.inverse ();
	for (CoordI y = rctWarp.top; y < rctWarp.bottom; y++) {
		for (CoordI x = rctWarp.left; x < rctWarp.right; x++) {
			CSiteD src = affInv * CSiteD (x, y); 
			CoordI fx = (CoordI) floor (src.x); //.5 is for better truncation
			CoordI fy = (CoordI) floor (src.y); //.5 is for better truncation
			CoordI cx = (CoordI) ceil (src.x); //.5 is for better truncation
			CoordI cy = (CoordI) ceil (src.y); //.5 is for better truncation
			if (
				where ().includes (fx, fy) && 
				where ().includes (fx, cy) && 
				where ().includes (cx, fy) && 
				where ().includes (cx, cy)
			)
				*ppxliRet = pixel (src);
			ppxliRet++;
		}
	}
	return piiRet;
}


own CIntImage* CIntImage::warp (const CPerspective2D& persp) const // perspective warp
{
	CSiteD src [4], dest [4];
	src [0] = CSiteD (where ().left, where ().top);
	src [1] = CSiteD (where ().right, where ().top);
	src [2] = CSiteD (where ().left, where ().bottom);
	src [3] = CSiteD (where ().right, where ().bottom);
	for (UInt i = 0; i < 4; i++) {
		dest [i] = (persp * src [i]).s;
	}
	CRct rctWarp (dest [0], dest [1], dest [2], dest [3]);

	CIntImage* piiRet = new CIntImage (rctWarp);
	PixelI* ppxliRet = (PixelI*) piiRet -> pixels ();
	CPerspective2D perspInv = CPerspective2D (dest, src);
	for (CoordI y = rctWarp.top; y != rctWarp.bottom; y++) {
		for (CoordI x = rctWarp.left; x != rctWarp.right; x++) {
			CSiteD src = (perspInv * CSiteD (x, y)).s; 
			CoordI fx = (CoordI) floor (src.x); //.5 is for better truncation
			CoordI fy = (CoordI) floor (src.y); //.5 is for better truncation
			CoordI cx = (CoordI) ceil (src.x); //.5 is for better truncation
			CoordI cy = (CoordI) ceil (src.y); //.5 is for better truncation
			if (
				where ().includes (fx, fy) && 
				where ().includes (fx, cy) && 
				where ().includes (cx, fy) && 
				where ().includes (cx, cy)
			)
				*ppxliRet = pixel (src);
			ppxliRet++;
		}
	}
	return piiRet;
}

own CIntImage* CIntImage::warp (const CPerspective2D& persp, const CRct& rctWarp) const // perspective warp
{
	CIntImage* piiRet = new CIntImage (rctWarp);
	PixelI* ppxliRet = (PixelI*) piiRet -> pixels ();
	CPerspective2D perspInv = persp.inverse ();
	for (CoordI y = rctWarp.top; y != rctWarp.bottom; y++) {
		for (CoordI x = rctWarp.left; x != rctWarp.right; x++) {
			CSiteD src = (perspInv * CSiteD (x, y)).s; 
			CoordI fx = (CoordI) floor (src.x); //.5 is for better truncation
			CoordI fy = (CoordI) floor (src.y); //.5 is for better truncation
			CoordI cx = (CoordI) ceil (src.x); //.5 is for better truncation
			CoordI cy = (CoordI) ceil (src.y); //.5 is for better truncation
			if (
				where ().includes (fx, fy) && 
				where ().includes (fx, cy) && 
				where ().includes (cx, fy) && 
				where ().includes (cx, cy)
			)
				*ppxliRet = pixel (src);
			ppxliRet++;
		}
	}
	return piiRet;
}

own CIntImage* CIntImage::warp (const CPerspective2D& persp, const CRct& rctWarp, const UInt accuracy) const // perspective warp
{
	CIntImage* piiRet = new CIntImage (rctWarp);
	PixelI* ppxliRet = (PixelI*) piiRet -> pixels ();
	for (CoordI y = rctWarp.top; y != rctWarp.bottom; y++) {
		for (CoordI x = rctWarp.left; x != rctWarp.right; x++) {
			CSite src = (persp * CSite (x, y)).s; 
			CoordI fx = (CoordI) floor ((CoordD) src.x / (CoordD) accuracy); //.5 is for better truncation
			CoordI fy = (CoordI) floor ((CoordD) src.y / (CoordD) accuracy); //.5 is for better truncation
			CoordI cx = (CoordI) ceil ((CoordD) src.x / (CoordD) accuracy); //.5 is for better truncation
			CoordI cy = (CoordI) ceil ((CoordD) src.y / (CoordD) accuracy); //.5 is for better truncation
			if (
				where ().includes (fx, fy) && 
				where ().includes (fx, cy) && 
				where ().includes (cx, fy) && 
				where ().includes (cx, cy)
			)
				*ppxliRet = pixel (src, accuracy);
			ppxliRet++;
		}
	}
	return piiRet;
}

PixelI CIntImage::pixel (CoordD x, CoordD y) const
{
	CoordI left = (CoordI) floor (x); // find the coordinates of the four corners
	CoordI wLeft = where ().left, wRight1 = where ().right - 1, wTop = where ().top, wBottom1 = where ().bottom - 1;
	left = checkrange (left, wLeft, wRight1);
	CoordI right = (CoordI) ceil (x);
	right = checkrange (right, wLeft, wRight1);
	CoordI top = (CoordI) floor (y);
	top	= checkrange (top, wTop, wBottom1);
	CoordI bottom = (CoordI) ceil (y);
	bottom = checkrange (bottom, wTop, wBottom1);

	const PixelI lt = pixel (left, top);
	const PixelI rt = pixel (right, top);
	const PixelI lb = pixel (left, bottom);
	const PixelI rb = pixel (right, bottom);
	const Double distX = x - left;
	const Double distY = y - top;
	Double x01 = distX * (rt - lt) + lt; // use p.59's notation (Wolberg, Digital Image Warping)
	Double x23 = distX * (rb - lb) + lb;
	PixelI pxlRet = checkrange ((Int) (x01 + (x23 - x01) * distY + .5), 0, 255);
	return pxlRet;
}

PixelI CIntImage::pixel (CoordI x, CoordI y, UInt accuracy) const	// accuracy indicates the 2/4/8/16 quantization
{
	CoordI left = (CoordI) floor ((CoordD) x / (CoordD) accuracy); // find the coordinates of the four corners
	CoordI wLeft = where ().left, wRight1 = where ().right - 1, wTop = where ().top, wBottom1 = where ().bottom - 1;
	left = checkrange (left, wLeft, wRight1);
	CoordI right = (CoordI) ceil ((CoordD) x / (CoordD) accuracy);
	right = checkrange (right, wLeft, wRight1);
	CoordI top = (CoordI) floor ((CoordD) y / (CoordD) accuracy);
	top	= checkrange (top, wTop, wBottom1);
	CoordI bottom = (CoordI) ceil ((CoordD) y / (CoordD) accuracy);
	bottom = checkrange (bottom, wTop, wBottom1);

	const PixelI lt = pixel (left, top);
	const PixelI rt = pixel (right, top);
	const PixelI lb = pixel (left, bottom);
	const PixelI rb = pixel (right, bottom);
	const CoordI distX = x - left * accuracy;
	const CoordI distY = y - top * accuracy;
	Double x01 = distX * (rt - lt) + accuracy * lt; // use p.59's notation (Wolberg, Digital Image Warping)
	Double x23 = distX * (rb - lb) + accuracy * lb;
	PixelI pxlRet = checkrange ((Int) ((accuracy * x01 + (x23 - x01) * distY)) / (accuracy * accuracy), 0, 255);
	return pxlRet;
}

own CIntImage* CIntImage::complement () const

⌨️ 快捷键说明

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