📄 downconverttools.inl
字号:
void
DownConvert::xUpsampling2( ResizeParameters* pcParameters, bool bLuma)
{
int iInWidth = pcParameters->m_iInWidth;
int iInHeight = pcParameters->m_iInHeight;
int iOutWidth = pcParameters->m_iOutWidth;
int iOutHeight = pcParameters->m_iOutHeight;
if (!bLuma)
{
iInWidth >>= 1;
iInHeight >>= 1;
iOutWidth >>= 1;
iOutHeight >>= 1;
}
// ===== vertical upsampling =====
for (int xin=0; xin<iInWidth; xin++)
{
int* piSrc = &m_paiImageBuffer[xin];
for (int yin=0; yin<iInHeight; yin++)
m_paiTmp1dBuffer[yin] = piSrc[yin * m_iImageStride];
xUpsamplingData2(iInHeight, iOutHeight);
for(int yout = 0; yout < iOutHeight; yout++ )
piSrc[yout*m_iImageStride] = m_paiTmp1dBufferOut[yout];
}
// ===== horizontal upsampling =====
for (int yout=0; yout<iOutHeight; yout++)
{
int* piSrc = &m_paiImageBuffer[yout * m_iImageStride];
for (int xin=0; xin<iInWidth; xin++)
m_paiTmp1dBuffer[xin] = piSrc[xin];
xUpsamplingData2(iInWidth, iOutWidth);
for( int i = 0; i < iOutWidth; i++ )
piSrc[i] = ( m_paiTmp1dBufferOut[i] + 512 ) >> 10;
}
}
__inline
void
DownConvert::xUpsamplingData2 ( int iInLength , int iOutLength )
{
int *Tmp1dBufferInHalfpel = m_aiTmp1dBufferInHalfpel;
int *Tmp1dBufferInQ1pel = m_aiTmp1dBufferInQ1pel;
int *Tmp1dBufferInQ3pel = m_aiTmp1dBufferInQ3pel;
int x,y;
int iTemp;
// half pel samples (6 taps 1 -5 20 20 -5 1)
for( x = 0; x < iInLength ; x++)
{
y=x;
iTemp = m_paiTmp1dBuffer[y];
y = (x+1 < iInLength ? x+1 : iInLength -1);
iTemp += m_paiTmp1dBuffer[y];
iTemp = iTemp << 2;
y = (x-1 >= 0 ? x-1 : 0);
iTemp -= m_paiTmp1dBuffer[y];
y = (x+2 < iInLength ? x+2 : iInLength -1);
iTemp -= m_paiTmp1dBuffer[y];
iTemp += iTemp << 2;
y = (x-2 >= 0 ? x-2 : 0);
iTemp += m_paiTmp1dBuffer[y];
y = (x+3 < iInLength ? x+3 : iInLength -1);
iTemp += m_paiTmp1dBuffer[y];
Tmp1dBufferInHalfpel[x] = iTemp;
}
// 1/4 pel samples
for( x = 0; x < iInLength-1 ; x++)
{
Tmp1dBufferInQ1pel[x] = ( (m_paiTmp1dBuffer[x]<<5) + Tmp1dBufferInHalfpel[x] + 1) >> 1;
Tmp1dBufferInQ3pel[x] = ( (m_paiTmp1dBuffer[x+1]<<5) + Tmp1dBufferInHalfpel[x] + 1) >> 1;
}
Tmp1dBufferInQ1pel[iInLength-1] = ( (m_paiTmp1dBuffer[iInLength-1]<<5) + Tmp1dBufferInHalfpel[iInLength-1] + 1) >> 1;
Tmp1dBufferInQ3pel[iInLength-1] = Tmp1dBufferInHalfpel[iInLength-1] ;
// generic interpolation to nearest 1/4 pel position
for (int iout=0; iout<iOutLength; iout++)
{
double dpos0 = ((double)iout * iInLength / iOutLength);
int ipos0 = (int)dpos0;
double rpos0 = dpos0 - ipos0;
int iIndex = (int) (8 * rpos0);
switch (iIndex)
{
case 0:
m_paiTmp1dBufferOut[iout] = m_paiTmp1dBuffer[ipos0] << 5; // original pel value
break;
case 1:
case 2:
m_paiTmp1dBufferOut[iout] = Tmp1dBufferInQ1pel[ipos0]; // 1/4 pel value
break;
case 3:
case 4:
m_paiTmp1dBufferOut[iout] = Tmp1dBufferInHalfpel[ipos0]; // half pel value
break;
case 5:
case 6:
m_paiTmp1dBufferOut[iout] = Tmp1dBufferInQ3pel[ipos0]; // 1/4 pel value
break;
case 7:
int ipos1 = (ipos0+1 < iInLength) ? ipos0+1 : ipos0;
m_paiTmp1dBufferOut[iout] = m_paiTmp1dBuffer[ipos1] << 5; // original pel value
break;
}
}
}
// =================================================================================
// INTRA 1 Lanczos
// =================================================================================
#define TMM_TABLE_SIZE 512
#define TMM_FILTER_WINDOW_SIZE 3
#define NFACT 12
#define VALFACT (1l<<NFACT)
#define MASKFACT (VALFACT-1)
//*************************************************************************
// lanczos filter coeffs computation
__inline
void
DownConvert::xInitFilterTmm1 ()
{
xDestroyFilterTmm1();
const double pi = 3.14159265359;
m_padFilter = new long[TMM_TABLE_SIZE];
m_padFilter[0] = VALFACT;
for (int i=1; i<TMM_TABLE_SIZE; i++)
{
double x = ((double)i/TMM_TABLE_SIZE) * TMM_FILTER_WINDOW_SIZE;
double pix = pi*x;
double pixw = pix/TMM_FILTER_WINDOW_SIZE;
m_padFilter[i] = (long)(sin(pix)/pix * sin(pixw)/pixw * VALFACT);
}
}
__inline
void
DownConvert::xDestroyFilterTmm1 ( )
{
if(m_padFilter)
{
delete [] m_padFilter;
m_padFilter=NULL;
}
}
//*************************************************************************
__inline
void
DownConvert::xUpsampling1( ResizeParameters* pcParameters,
bool bLuma)
{
int iInWidth = pcParameters->m_iInWidth;
int iInHeight = pcParameters->m_iInHeight;
int iOutWidth = pcParameters->m_iOutWidth;
int iOutHeight = pcParameters->m_iOutHeight;
if (!bLuma)
{
iInWidth >>= 1;
iInHeight >>= 1;
iOutWidth >>= 1;
iOutHeight >>= 1;
}
int iNumerator = 1;
int iDenominator = 1;
long spos;
// ===== vertical upsampling =====
xComputeNumeratorDenominator(iInHeight,iOutHeight,&iNumerator,&iDenominator);
spos = (1<<NFACT) * iDenominator / iNumerator;
for (int xin=0; xin<iInWidth; xin++)
{
int* piSrc = &m_paiImageBuffer[xin];
for (int yin=0; yin<iInHeight; yin++)
m_paiTmp1dBuffer[yin] = piSrc[yin * m_iImageStride];
xUpsamplingData1(iInHeight, iOutHeight, spos);
for(int yout = 0; yout < iOutHeight; yout++ )
piSrc[yout*m_iImageStride] = m_paiTmp1dBufferOut[yout];
}
// ===== horizontal upsampling =====
xComputeNumeratorDenominator(iInWidth,iOutWidth,&iNumerator,&iDenominator);
spos = (1<<NFACT) * iDenominator / iNumerator;
for (int yout=0; yout<iOutHeight; yout++)
{
int* piSrc = &m_paiImageBuffer[yout * m_iImageStride];
for (int xin=0; xin<iInWidth; xin++)
m_paiTmp1dBuffer[xin] = piSrc[xin];
xUpsamplingData1(iInWidth, iOutWidth, spos);
memcpy(piSrc, m_paiTmp1dBufferOut, iOutWidth*sizeof(int));
}
}
__inline
void
DownConvert::xUpsamplingData1 ( int iInLength , int iOutLength , long spos )
{
long dpos0 = -spos;
for (int iout=0; iout<iOutLength; iout++)
{
dpos0 += spos;
long rpos0 = dpos0 & MASKFACT;
int ipos0 = dpos0 >> NFACT;
if (rpos0 == 0) {
m_paiTmp1dBufferOut[iout] = m_paiTmp1dBuffer[ipos0];
continue;
}
int end = ipos0 + TMM_FILTER_WINDOW_SIZE;
int begin = end - TMM_FILTER_WINDOW_SIZE*2;
long sval = 0;
long posi = ((begin-ipos0)<<NFACT) - rpos0;
for (int i=begin; i<=end; i++, posi += VALFACT)
{
long fact = xGetFilter(posi);
int val;
if (i<0) val = m_paiTmp1dBuffer[0];
else if (i>=iInLength) val = m_paiTmp1dBuffer[iInLength-1];
else val = m_paiTmp1dBuffer[i];
sval += val * fact;
}
m_paiTmp1dBufferOut[iout] = sval>>NFACT;
}
}
__inline
void
DownConvert::xComputeNumeratorDenominator ( int iInWidth , int iOutWidth ,
int* iNumerator, int *iDenominator)
{
int iA = 1;
int iB = iOutWidth;
int iC = iInWidth;
while (iC != 0)
{
iA = iB;
iB = iC;
iC = iA % iB;
}
*iNumerator = iOutWidth / iB;
*iDenominator = iInWidth / iB;
}
__inline
long
DownConvert::xGetFilter ( long x )
{
x = abs(x);
int ind = (int)((x / TMM_FILTER_WINDOW_SIZE) * TMM_TABLE_SIZE) >> NFACT;
if (ind >= TMM_TABLE_SIZE) return 0;
return m_padFilter[ind];
}
#undef NFACT
#undef VALFACT
#undef MASKFACT
#undef TMM_TABLE_SIZE
#undef TMM_FILTER_WINDOW_SIZE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -