📄 downconvert.cpp
字号:
{
for( int i = 0; i < iCurrW; i++ )
{
int* piSrc = &m_paiImageBuffer[i];
for( int j = -iYBorder; j < iCurrH+iYBorder; j++ )
{
if( i < iLOffset || i >= iCurrW - iROffset ||
j < iTOffset - iYBorder || j >= iCurrH - iBOffset + iYBorder )
{
m_paiTmp1dBuffer[j+iYBorder] = 128; // set to mid gray
continue;
}
m_paiTmp1dBuffer[j+iYBorder] = 0;
int iRefPos16 = ( ( ( j - iOffsetY ) * iScaleY + iAddY ) >> ( iShiftY - 4 ) ) - iDeltaY;
int iPhase = iRefPos16 & 15;
int iRefPos = iRefPos16 >> 4;
if( bChromaFilter )
{
for( int k = 0; k < 2; k++ )
{
int m = xClip( iRefPos + k, 0, iBaseH - 1 );
m_paiTmp1dBuffer[j+iYBorder] += filter16_chroma[iPhase][k] * piSrc[m*m_iImageStride];
}
}
else
{
for( int k = 0; k < 4; k++ )
{
int m = xClip( iRefPos + k - 1, 0, iBaseH - 1 );
m_paiTmp1dBuffer[j+iYBorder] += filter16_luma[iPhase][k] * piSrc[m*m_iImageStride];
}
}
m_paiTmp1dBuffer[j+iYBorder] = ( m_paiTmp1dBuffer[j+iYBorder] + 512 ) >> 10;
}
//----- clip and copy back to image buffer -----
for( int n = 0; n < iCurrH+2*iYBorder; n++ )
{
piSrc[n*m_iImageStride] = xClip( m_paiTmp1dBuffer[n], 0, 255 );
}
}
}
}
#ifdef DOWN_CONVERT_STATIC
//===============================================================================
//
// H E L P E R F U N C T I O N S F O R D O W N C O N V E R T T O O L
//
//===============================================================================
void
DownConvert::xInitLanczosFilter()
{
const double pi = 3.14159265359;
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 );
}
}
void
DownConvert::xCopyToImageBuffer( unsigned char* pucSrc, int iWidth, int iHeight, int iStride )
{
int* piDes = m_paiImageBuffer;
for( int j = 0; j < iHeight; j++ )
{
for( int i = 0; i < iWidth; i++ )
{
piDes[i] = (int)pucSrc[i];
}
piDes += m_iImageStride;
pucSrc += iStride;
}
}
void
DownConvert::xCopyFromImageBuffer( unsigned char* pucDes, int iWidth, int iHeight, int iStride )
{
int* piSrc = m_paiImageBuffer;
for( int j = 0; j < iHeight; j++ )
{
for( int i = 0; i < iWidth; i++ )
{
pucDes[i] = (unsigned char)piSrc[i];
}
pucDes += iStride;
piSrc += m_iImageStride;
}
}
void
DownConvert::xInitializeWithValue( unsigned char* pucBuffer, int iWidth, int iHeight, int iStride, unsigned char cValue )
{
for( int y = 0; y < iHeight; y++, pucBuffer += iStride )
{
::memset( pucBuffer, cValue, iWidth );
}
}
void
DownConvert::xCompUpsamplingDyadic( int iBaseW, int iBaseH, bool bChroma )
{
int aiLumaFilter[6] = { 1, -5, 20, 20, -5, 1 };
//========== vertical upsampling ===========
{
for( int j = 0; j < iBaseW; j++ )
{
int* piSrc = &m_paiImageBuffer[j];
//----- upsample column -----
for( int i = 0; i < iBaseH; i++)
{
m_paiTmp1dBuffer[2*i ] = piSrc[i*m_iImageStride] << 5;
m_paiTmp1dBuffer[2*i+1] = 0;
if( bChroma )
{
int m1 = i;
int m2 = min( i + 1, iBaseH - 1 );
m_paiTmp1dBuffer[2*i+1] += piSrc[m1*m_iImageStride] << 4;
m_paiTmp1dBuffer[2*i+1] += piSrc[m2*m_iImageStride] << 4;
}
else
{
for( int k = 0; k < 6; k++ )
{
int m = xClip( i + k - 2, 0, iBaseH - 1 );
m_paiTmp1dBuffer[2*i+1] += aiLumaFilter[k] * piSrc[m*m_iImageStride];
}
}
}
//----- copy back to image buffer -----
for( int n = 0; n < 2*iBaseH; n++ )
{
piSrc[n*m_iImageStride] = m_paiTmp1dBuffer[n];
}
}
}
//========== horizontal upsampling ==========
{
for( int j = 0; j < 2*iBaseH; j++ )
{
int* piSrc = &m_paiImageBuffer[j*m_iImageStride];
//----- upsample row -----
for( int i = 0; i < iBaseW; i++)
{
m_paiTmp1dBuffer[2*i ] = piSrc[i] << 5;
m_paiTmp1dBuffer[2*i+1] = 0;
if( bChroma )
{
int m1 = i;
int m2 = min( i + 1, iBaseW - 1 );
m_paiTmp1dBuffer[2*i+1] += piSrc[m1] << 4;
m_paiTmp1dBuffer[2*i+1] += piSrc[m2] << 4;
}
else
{
for( int k = 0; k < 6; k++ )
{
int m = xClip( i + k - 2, 0, iBaseW - 1 );
m_paiTmp1dBuffer[2*i+1] += aiLumaFilter[k] * piSrc[m];
}
}
}
//----- round, clip, and copy back to image buffer -----
for( int n = 0; n < 2*iBaseW; n++ )
{
int iS = ( m_paiTmp1dBuffer[n] + 512 ) >> 10;
piSrc[n] = xClip( iS, 0, 255 );
}
}
}
}
void
DownConvert::xCompUpsamplingLanczos( ResizeParameters* pcParameters, bool bChroma )
{
int iShift = ( bChroma ? 1 : 0 );
int iInWidth = pcParameters->m_iRefLayerFrmWidth >> iShift;
int iInHeight = pcParameters->m_iRefLayerFrmHeight >> iShift;
int iOutWidth = pcParameters->m_iScaledRefFrmWidth >> iShift;
int iOutHeight = pcParameters->m_iScaledRefFrmHeight >> iShift;
int iNumerator = 1;
int iDenominator = 1;
long spos = 0;
//===== vertical upsampling =====
xGetNumDenomLanczos( 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];
}
xUpsamplingDataLanczos( iInHeight, iOutHeight, spos );
for( int yout = 0; yout < iOutHeight; yout++ )
{
piSrc[yout*m_iImageStride] = m_paiTmp1dBufferOut[yout];
}
}
//===== horizontal upsampling =====
xGetNumDenomLanczos( 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];
}
xUpsamplingDataLanczos( iInWidth, iOutWidth, spos );
::memcpy( piSrc, m_paiTmp1dBufferOut, iOutWidth*sizeof(int) );
}
}
void
DownConvert::xUpsamplingDataLanczos( 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 = xGetFilterLanczos( posi );
int m = xClip( i, 0, iInLength - 1 );
int val = m_paiTmp1dBuffer[m];
sval += val * fact;
}
m_paiTmp1dBufferOut[iout] = xClip( sval >> NFACT, 0, 255 );
}
}
void
DownConvert::xGetNumDenomLanczos( int iInWidth, int iOutWidth, int& riNumerator, int& riDenominator )
{
int iA = 1;
int iB = iOutWidth;
int iC = iInWidth;
while (iC != 0)
{
iA = iB;
iB = iC;
iC = iA % iB;
}
riNumerator = iOutWidth / iB;
riDenominator = iInWidth / iB;
}
long
DownConvert::xGetFilterLanczos( long x )
{
x = abs( x );
int i = (int)( ( x / TMM_FILTER_WINDOW_SIZE ) * TMM_TABLE_SIZE ) >> NFACT;
if( i >= TMM_TABLE_SIZE )
{
return 0;
}
return m_padFilter[ i ];
}
void
DownConvert::xCompUpsampling6tapBilin( ResizeParameters* pcParameters, bool bChroma )
{
int iShift = ( bChroma ? 1 : 0 );
int iInWidth = pcParameters->m_iRefLayerFrmWidth >> iShift;
int iInHeight = pcParameters->m_iRefLayerFrmHeight >> iShift;
int iOutWidth = pcParameters->m_iScaledRefFrmWidth >> iShift;
int iOutHeight = pcParameters->m_iScaledRefFrmHeight >> iShift;
//===== 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];
}
xUpsamplingData6tapBilin( 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];
}
xUpsamplingData6tapBilin( iInWidth, iOutWidth );
for( int i = 0; i < iOutWidth; i++ )
{
piSrc[i] = xClip( ( m_paiTmp1dBufferOut[i] + 512 ) >> 10, 0, 255 );
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -