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

📄 shape.cpp

📁 jpeg and mpeg 编解码技术源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*************************************************************************

This software module was originally developed by 

	Wei-ge Chen (wchen@microsoft.com), Microsoft Corporation
	(April, 1997)
and edited by
        Wei Wu (weiwu@stallion.risc.rockwell.com) Rockwell Science Center

and also edited by
	Yoshihiro Kikuchi (TOSHIBA CORPORATION)
	Takeshi Nagai (TOSHIBA CORPORATION)
	Toshiaki Watanabe (TOSHIBA CORPORATION)
	Noboru Yamaguchi (TOSHIBA CORPORATION)

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:

	shpenc.hpp

Abstract:

	binary shape encoder with context-based arithmatic coder

Revision History:

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

#include "typeapi.h"
#include "entropy/entropy.hpp"
#include "entropy/huffman.hpp"
#include "entropy/bitstrm.hpp"
#include "global.hpp"
#include "mode.hpp"
#include "codehead.h"
#include "cae.h"
#include "vopses.hpp"


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

#define new DEBUG_NEW				   
#endif // __MFC_

own Int* CVideoObject::computeShapeSubBlkIndex (Int iSubBlkSize, Int iSrcSize)
{
	Int* rgiShapeSubBlkIndex = new Int [MB_SIZE * MB_SIZE / iSubBlkSize / iSubBlkSize];
	Int nBorderLine = (iSrcSize - MB_SIZE) / 2;
	CoordI iX, iY, i = 0;
	for (iY = nBorderLine; iY < (MB_SIZE + nBorderLine); iY += iSubBlkSize)	{
		for (iX = nBorderLine; iX < (MB_SIZE + nBorderLine); iX += iSubBlkSize)
			rgiShapeSubBlkIndex [i++] = iY * iSrcSize + iX;
	}
	return rgiShapeSubBlkIndex;
}

Void CVideoObject::downSampleShapeMCPred(const PixelC*ppxlcSrc,
												PixelC* ppxlcDst,Int iRate)
{
	assert(iRate==1 || iRate==2 || iRate==4);
	static Int rgiScan[16] = {0,1,MC_BAB_SIZE,MC_BAB_SIZE+1,
		2,3,MC_BAB_SIZE+2,MC_BAB_SIZE+3,
		2*MC_BAB_SIZE,2*MC_BAB_SIZE+1,2*MC_BAB_SIZE+2,2*MC_BAB_SIZE+3,
		3*MC_BAB_SIZE,3*MC_BAB_SIZE+1,3*MC_BAB_SIZE+2,3*MC_BAB_SIZE+3};
	static Int rgiThresh[5] = {0,0,MPEG4_OPAQUE,0,7*MPEG4_OPAQUE};
	Int iBdrThresh=0;
	if(iRate>2)
		iBdrThresh=MPEG4_OPAQUE;
	Int iThreshold = rgiThresh[iRate];

#ifdef __TRACE_AND_STATS_
	//m_pbitstrmOut->trace ((PixelC*)ppxlcSrc, MC_BAB_SIZE, MC_BAB_SIZE, "MB_MC_BAB_ORIG");
#endif //__TRACE_AND_STATS_

	const PixelC *ppxlcSrcScan = ppxlcSrc+(MC_BAB_SIZE+1)*MC_BAB_BORDER;
	Int iDstSize = 2*MC_BAB_BORDER+(MC_BAB_SIZE-2*MC_BAB_BORDER)/iRate;
	PixelC *ppxlcDstScan = ppxlcDst+(iDstSize+1)*MC_BAB_BORDER;
	Int iX,iY,i,iSum,iSum1,iSum2,iSum3,iSum4;
	Int iRateSqd=iRate*iRate;
	const PixelC *ppxlcSrcBdr1 = ppxlcSrc+MC_BAB_SIZE*MC_BAB_BORDER;
	const PixelC *ppxlcSrcBdr2 = ppxlcSrc+2*MC_BAB_SIZE-1;
	const PixelC *ppxlcSrcBdr3 = ppxlcSrc+MC_BAB_BORDER;
	const PixelC *ppxlcSrcBdr4 = ppxlcSrc+MC_BAB_SIZE*(MC_BAB_SIZE-1)+MC_BAB_BORDER;
	PixelC *ppxlcDstBdr1 = ppxlcDst+iDstSize*MC_BAB_BORDER;
	PixelC *ppxlcDstBdr2 = ppxlcDst+2*iDstSize-1;
	PixelC *ppxlcDstBdr3 = ppxlcDst+MC_BAB_BORDER;
	PixelC *ppxlcDstBdr4 = ppxlcDst+iDstSize*(iDstSize-1)+MC_BAB_BORDER;

	for(iY=MC_BAB_BORDER;iY<iDstSize-MC_BAB_BORDER;iY++)
	{
		for(iX=MC_BAB_BORDER;iX<iDstSize-MC_BAB_BORDER;iX++,ppxlcDstScan++)
		{
			iSum=0;
			for(i=0;i<iRateSqd;i++)
				iSum+=ppxlcSrcScan[rgiScan[i]];
			*ppxlcDstScan=(iSum>iThreshold)?MPEG4_OPAQUE:MPEG4_TRANSPARENT;
			ppxlcSrcScan+=iRate;
		}
		ppxlcDstScan+=2*MC_BAB_BORDER;
		ppxlcSrcScan+=MC_BAB_SIZE*iRate-MC_BAB_SIZE+2*MC_BAB_BORDER;

		// border
		iSum1=iSum2=iSum3=iSum4=0;
		for(i=0;i<iRate;i++)
		{
			iSum1+=ppxlcSrcBdr1[i*MC_BAB_SIZE];
			iSum2+=ppxlcSrcBdr2[i*MC_BAB_SIZE];
			iSum3+=ppxlcSrcBdr3[i];
			iSum4+=ppxlcSrcBdr4[i];
		}
		*ppxlcDstBdr1=(iSum1>iBdrThresh)?MPEG4_OPAQUE:MPEG4_TRANSPARENT;
		*ppxlcDstBdr2=(iSum2>iBdrThresh)?MPEG4_OPAQUE:MPEG4_TRANSPARENT;
		*ppxlcDstBdr3++=(iSum3>iBdrThresh)?MPEG4_OPAQUE:MPEG4_TRANSPARENT;
		*ppxlcDstBdr4++=(iSum4>iBdrThresh)?MPEG4_OPAQUE:MPEG4_TRANSPARENT;
		ppxlcDstBdr1+=iDstSize;
		ppxlcDstBdr2+=iDstSize;
		ppxlcSrcBdr1+=MC_BAB_SIZE*iRate;
		ppxlcSrcBdr2+=MC_BAB_SIZE*iRate;
		ppxlcSrcBdr3+=iRate;
		ppxlcSrcBdr4+=iRate;
	}

	// corners
	ppxlcDst[0]=ppxlcSrc[0];
	ppxlcDst[iDstSize-1]=ppxlcSrc[MC_BAB_SIZE-1];
	ppxlcDst[(iDstSize-1)*iDstSize]=ppxlcSrc[(MC_BAB_SIZE-1)*MC_BAB_SIZE];
	ppxlcDst[iDstSize*iDstSize-1]=ppxlcSrc[MC_BAB_SIZE*MC_BAB_SIZE-1];

#ifdef __TRACE_AND_STATS_
	//m_pbitstrmOut->trace ((PixelC*)ppxlcDst, iDstSize, iDstSize, "MB_MC_BAB_DOWN");
#endif // __TRACE_AND_STATS_
}

Void CVideoObject::upSampleShape(PixelC*ppxlcBYFrm,const PixelC* rgpxlcSrc, PixelC* rgpxlcDst)
{
	if(m_iInverseCR==2)
		adaptiveUpSampleShape(rgpxlcSrc, rgpxlcDst,8,8);
	else
	{
		static PixelC rgpxlcTmp[12*12];
		
		assert(m_iInverseCR==4);
		adaptiveUpSampleShape(rgpxlcSrc, rgpxlcTmp,4,4);

		Int iSizeTmp=12;
		Int iSizeSrc=8;
		Int i,j;

		// top left corner 
		rgpxlcTmp[0]=rgpxlcSrc[0];
		rgpxlcTmp[1]=rgpxlcSrc[1];
		rgpxlcTmp[iSizeTmp]=rgpxlcSrc[iSizeSrc];
		rgpxlcTmp[iSizeTmp+1]=rgpxlcSrc[iSizeSrc+1];

		// top right corner
		rgpxlcTmp[iSizeTmp-2]=rgpxlcSrc[iSizeSrc-2];
		rgpxlcTmp[iSizeTmp-1]=rgpxlcSrc[iSizeSrc-1];
		rgpxlcTmp[(iSizeTmp<<1)-2]=rgpxlcSrc[(iSizeSrc<<1)-2];
		rgpxlcTmp[(iSizeTmp<<1)-1]=rgpxlcSrc[(iSizeSrc<<1)-1];

		// top border
		for(j=0;j<2;j++)
			for(i=BAB_BORDER;i<iSizeTmp-BAB_BORDER;i++)
				rgpxlcTmp[j*iSizeTmp+i]=rgpxlcSrc[j*iSizeSrc+i/2+1];

		// left border 
		for(i=0;i<2;i++)
			for(j=BAB_BORDER;j<iSizeTmp-BAB_BORDER;j++)
				rgpxlcTmp[j*iSizeTmp+i]=rgpxlcSrc[(j/2+1)*iSizeSrc+i];

		/*Int iTmp = m_iWidthCurrBAB;
		m_iInverseCR = 2;
		m_iWidthCurrBAB = 12;
		subsampleLeftTopBorderFromVOP (ppxlcBYFrm, rgpxlcTmp);
		m_iInverseCR = 4;
		m_iWidthCurrBAB = iTmp;*/
		
		adaptiveUpSampleShape(rgpxlcTmp, rgpxlcDst,8,8);
	}
}

Int CVideoObject::getContextUS( PixelC a,
                                PixelC b,
                                PixelC c,
                                PixelC d,
                                PixelC e,
                                PixelC f,
                                PixelC g,
                                PixelC h)
{
        Int     ret =(Int)(a+(b<<1)+(c<<2)+(d<<3)+(e<<4)+(f<<5)+(g<<6)+(h<<7));
 
        return  ret;
}

PixelC CVideoObject::getRefValue(const PixelC* ppxlcRow,
                                Int x_adr, Int y_adr,
                                Int h_size, Int v_size)
{
        assert ((x_adr>=-2) && (x_adr<=h_size+1) && (y_adr>=-2) && (y_adr<=v_size+1));
 
        Int     x_lim, y_lim;
        PixelC  ret;
 
        if(x_adr>=0 && x_adr<h_size && y_adr>=0 && y_adr<v_size) {
                ret=(ppxlcRow[y_adr*(h_size+BAB_BORDER_BOTH)+x_adr]>0) ? 1 : 0;
        } else {
                if(y_adr<0 || (x_adr<0 && y_adr<v_size)) {
			ret=(ppxlcRow[y_adr*(h_size+BAB_BORDER_BOTH)+x_adr]>0) ? 1 : 0;
                } else {
                        x_lim=(x_adr<0)? 0: (x_adr>=h_size)? h_size-1 :x_adr;
                        y_lim=(y_adr<0)? 0: (y_adr>=v_size)? v_size-1 :y_adr;
                        ret=(ppxlcRow[y_lim*(h_size+BAB_BORDER_BOTH)+x_lim]>0) ? 1 : 0;
                }
        }
 
        return ret;
}

Void CVideoObject::adaptiveUpSampleShape (const PixelC* rgpxlcSrc, 
						PixelC* rgpxlcDst,
						Int h_size, Int v_size)
{
	Int	x[12], y[12], other_total, context, rvalue, th, m;
	Int width_up = h_size << 1;
	Int width_up_border = width_up + BAB_BORDER_BOTH;
	Int j, i, py, px, py_st, py_en, px_st, px_en, py_p;
	PixelC	val[12];
	const PixelC* ppxlcRow = rgpxlcSrc + BAB_BORDER+BAB_BORDER * (h_size + BAB_BORDER_BOTH);

	/* --  4  5 -- */
	/*  6  0  1  7 */
	/*  8  2  3  9 */
	/* -- 10 11 -- */
	for (j = -1; j < v_size; j++) {

		y[0] = y[1] = y[6] =y[7] = j;
		y[2] = y[3] = y[8] =y[9] = j + 1;
		y[4] = y[5] = j - 1;
		y[10]= y[11]= j + 2;
		if (j > -1) 
			py_st = 0;
		else	 
			py_st = 1;
		if (j < v_size - 1) 
			py_en = 2;
		else	       
			py_en = 1;

		for(i = -1; i < h_size; i++) {
			x[0] = x[2] = x[4] = x[10] = i;
			x[1] = x[3] = x[5] = x[11] = i+1;
			x[6] = x[8] = i - 1;
			x[7] = x[9] = i + 2;

			for(m = 0; m < 12; m++)
				val[m] = getRefValue (ppxlcRow, x[m], y[m], h_size, v_size);

			if (i > -1) 
				px_st = 0;
			else	    
				px_st = 1;

			if (i < h_size-1) 
				px_en = 2;
			else		  
				px_en=1;		

			other_total = val[4] + val[5] + val[6] + val[7] + val[8] + val[9] + val[10] + val[11];
			for (py = py_st; py < py_en; py++)	{
				py_p = ((j << 1) + 1 + py + BAB_BORDER) * width_up_border + (i << 1) + 1;
				for (px = px_st; px < px_en; px++)	{
					if(px < 1 && py < 1)	{			
						context = getContextUS (val[5], val[4], val[6], val[8], val[10], val[11], val[9], val[7]);
						th = grgchInterpolationFilterTh[context];
						rvalue = (val[0] << 2) + ((val[1] + val[2] + val[3]) << 1) + other_total;
					} 
					else if	(py < 1) {
						context = getContextUS(val[9], val[7], val[5], val[4], val[6], val[8], val[10], val[11]);
						th = grgchInterpolationFilterTh [context];
						rvalue = (val[1] << 2) + ((val[0] + val[2] + val[3]) << 1) + other_total;
					} 
					else if (px < 1) {
						context = getContextUS(val[6], val[8], val[10], val[11], val[9], val[7], val[5], val[4]);
						th = grgchInterpolationFilterTh [context];
						rvalue = (val[2] << 2) + ((val[1] + val[0] + val[3]) << 1) + other_total;
					} 
					else {
						context = getContextUS(val[10], val[11], val[9], val[7], val[5], val[4], val[6], val[8]);
						th = grgchInterpolationFilterTh [context];
						rvalue = (val[3] << 2) + ((val[1] + val[2] + val[0]) << 1) + other_total;
					}
					rgpxlcDst [py_p+(px+BAB_BORDER)] = (rvalue > th) ? opaqueValue: transpValue;
				}
			}
		}
	}
}

Void CVideoObject::copyLeftTopBorderFromVOP (PixelC* ppxlcSrc, PixelC* ppxlcDst)
{
	PixelC* ppxlcSrcTop1  = ppxlcSrc - BAB_BORDER  * m_iFrameWidthY - BAB_BORDER;
	PixelC* ppxlcSrcTop2  = ppxlcSrcTop1 + m_iFrameWidthY;
	PixelC* ppxlcSrcLeft1 = ppxlcSrcTop1;
	PixelC* ppxlcSrcLeft2 = ppxlcSrcLeft1 + 1;
	PixelC* ppxlcDstTop1  = ppxlcDst;
	PixelC* ppxlcDstTop2  = ppxlcDst + TOTAL_BAB_SIZE;
	PixelC* ppxlcDstLeft  = ppxlcDst;
	CoordI iPixel;
//	Modified for error resilient mode by Toshiba(1997-11-14)
	for (iPixel = 0; iPixel < BAB_BORDER; iPixel++)	{
		if (!m_bVPNoLeftTop) {
			ppxlcDstTop1 [iPixel]  = *ppxlcSrcTop1;
			//src pixel never out of bound due to padding of Ref1
			ppxlcDstTop2 [iPixel]  = *ppxlcSrcTop2;
			//BY should be intialized as zero outside of VOP
		}
		else {
			ppxlcDstTop1 [iPixel]  = (PixelC) 0;
			ppxlcDstTop2 [iPixel]  = (PixelC) 0;
		}
		ppxlcSrcTop1++; 
		ppxlcSrcTop2++; 
	}
	for (iPixel = BAB_BORDER; iPixel < TOTAL_BAB_SIZE-BAB_BORDER; iPixel++)	{
		if (!m_bVPNoTop) {

⌨️ 快捷键说明

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