/* The copyright in this software is being made available under the BSD * License, included below. This software may be subject to other third party * and contributor rights, including patent rights, and no such rights are * granted under this license. * * Copyright (c) 2010-2012, ITU/ISO/IEC * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the ITU/ISO/IEC nor the names of its contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ /** \file TComYuv.cpp \brief general YUV buffer class \todo this should be merged with TComPicYuv */ #include #include #include #include #include "CommonDef.h" #include "TComYuv.h" #include "TComInterpolationFilter.h" //! \ingroup TLibCommon //! \{ TComYuv::TComYuv() { m_apiBufY = NULL; m_apiBufU = NULL; m_apiBufV = NULL; } TComYuv::~TComYuv() { } Void TComYuv::create( UInt iWidth, UInt iHeight ) { // memory allocation m_apiBufY = (Pel*)xMalloc( Pel, iWidth*iHeight ); m_apiBufU = (Pel*)xMalloc( Pel, iWidth*iHeight >> 2 ); m_apiBufV = (Pel*)xMalloc( Pel, iWidth*iHeight >> 2 ); // set width and height m_iWidth = iWidth; m_iHeight = iHeight; m_iCWidth = iWidth >> 1; m_iCHeight = iHeight >> 1; } Void TComYuv::destroy() { // memory free xFree( m_apiBufY ); m_apiBufY = NULL; xFree( m_apiBufU ); m_apiBufU = NULL; xFree( m_apiBufV ); m_apiBufV = NULL; } Void TComYuv::clear() { ::memset( m_apiBufY, 0, ( m_iWidth * m_iHeight )*sizeof(Pel) ); ::memset( m_apiBufU, 0, ( m_iCWidth * m_iCHeight )*sizeof(Pel) ); ::memset( m_apiBufV, 0, ( m_iCWidth * m_iCHeight )*sizeof(Pel) ); } Void TComYuv::copyToPicYuv ( TComPicYuv* pcPicYuvDst, UInt iCuAddr, UInt uiAbsZorderIdx, UInt uiPartDepth, UInt uiPartIdx ) { copyToPicLuma ( pcPicYuvDst, iCuAddr, uiAbsZorderIdx, uiPartDepth, uiPartIdx ); copyToPicChroma( pcPicYuvDst, iCuAddr, uiAbsZorderIdx, uiPartDepth, uiPartIdx ); } Void TComYuv::copyToPicLuma ( TComPicYuv* pcPicYuvDst, UInt iCuAddr, UInt uiAbsZorderIdx, UInt uiPartDepth, UInt uiPartIdx ) { Int y, iWidth, iHeight; iWidth = m_iWidth >>uiPartDepth; iHeight = m_iHeight>>uiPartDepth; Pel* pSrc = getLumaAddr(uiPartIdx, iWidth); Pel* pDst = pcPicYuvDst->getLumaAddr ( iCuAddr, uiAbsZorderIdx ); UInt iSrcStride = getStride(); UInt iDstStride = pcPicYuvDst->getStride(); for ( y = iHeight; y != 0; y-- ) { ::memcpy( pDst, pSrc, sizeof(Pel)*iWidth); pDst += iDstStride; pSrc += iSrcStride; } } Void TComYuv::copyToPicChroma( TComPicYuv* pcPicYuvDst, UInt iCuAddr, UInt uiAbsZorderIdx, UInt uiPartDepth, UInt uiPartIdx ) { Int y, iWidth, iHeight; iWidth = m_iCWidth >>uiPartDepth; iHeight = m_iCHeight>>uiPartDepth; Pel* pSrcU = getCbAddr(uiPartIdx, iWidth); Pel* pSrcV = getCrAddr(uiPartIdx, iWidth); Pel* pDstU = pcPicYuvDst->getCbAddr( iCuAddr, uiAbsZorderIdx ); Pel* pDstV = pcPicYuvDst->getCrAddr( iCuAddr, uiAbsZorderIdx ); UInt iSrcStride = getCStride(); UInt iDstStride = pcPicYuvDst->getCStride(); for ( y = iHeight; y != 0; y-- ) { ::memcpy( pDstU, pSrcU, sizeof(Pel)*(iWidth) ); ::memcpy( pDstV, pSrcV, sizeof(Pel)*(iWidth) ); pSrcU += iSrcStride; pSrcV += iSrcStride; pDstU += iDstStride; pDstV += iDstStride; } } Void TComYuv::copyFromPicYuv ( TComPicYuv* pcPicYuvSrc, UInt iCuAddr, UInt uiAbsZorderIdx ) { copyFromPicLuma ( pcPicYuvSrc, iCuAddr, uiAbsZorderIdx ); copyFromPicChroma( pcPicYuvSrc, iCuAddr, uiAbsZorderIdx ); } Void TComYuv::copyFromPicLuma ( TComPicYuv* pcPicYuvSrc, UInt iCuAddr, UInt uiAbsZorderIdx ) { Int y; Pel* pDst = m_apiBufY; Pel* pSrc = pcPicYuvSrc->getLumaAddr ( iCuAddr, uiAbsZorderIdx ); UInt iDstStride = getStride(); UInt iSrcStride = pcPicYuvSrc->getStride(); for ( y = m_iHeight; y != 0; y-- ) { ::memcpy( pDst, pSrc, sizeof(Pel)*m_iWidth); pDst += iDstStride; pSrc += iSrcStride; } } Void TComYuv::copyFromPicChroma( TComPicYuv* pcPicYuvSrc, UInt iCuAddr, UInt uiAbsZorderIdx ) { Int y; Pel* pDstU = m_apiBufU; Pel* pDstV = m_apiBufV; Pel* pSrcU = pcPicYuvSrc->getCbAddr( iCuAddr, uiAbsZorderIdx ); Pel* pSrcV = pcPicYuvSrc->getCrAddr( iCuAddr, uiAbsZorderIdx ); UInt iDstStride = getCStride(); UInt iSrcStride = pcPicYuvSrc->getCStride(); for ( y = m_iCHeight; y != 0; y-- ) { ::memcpy( pDstU, pSrcU, sizeof(Pel)*(m_iCWidth) ); ::memcpy( pDstV, pSrcV, sizeof(Pel)*(m_iCWidth) ); pSrcU += iSrcStride; pSrcV += iSrcStride; pDstU += iDstStride; pDstV += iDstStride; } } Void TComYuv::copyToPartYuv( TComYuv* pcYuvDst, UInt uiDstPartIdx ) { copyToPartLuma ( pcYuvDst, uiDstPartIdx ); copyToPartChroma( pcYuvDst, uiDstPartIdx ); } Void TComYuv::copyToPartLuma( TComYuv* pcYuvDst, UInt uiDstPartIdx ) { Int y; Pel* pSrc = m_apiBufY; Pel* pDst = pcYuvDst->getLumaAddr( uiDstPartIdx ); UInt iSrcStride = getStride(); UInt iDstStride = pcYuvDst->getStride(); for ( y = m_iHeight; y != 0; y-- ) { ::memcpy( pDst, pSrc, sizeof(Pel)*m_iWidth); pDst += iDstStride; pSrc += iSrcStride; } } Void TComYuv::copyToPartChroma( TComYuv* pcYuvDst, UInt uiDstPartIdx ) { Int y; Pel* pSrcU = m_apiBufU; Pel* pSrcV = m_apiBufV; Pel* pDstU = pcYuvDst->getCbAddr( uiDstPartIdx ); Pel* pDstV = pcYuvDst->getCrAddr( uiDstPartIdx ); UInt iSrcStride = getCStride(); UInt iDstStride = pcYuvDst->getCStride(); for ( y = m_iCHeight; y != 0; y-- ) { ::memcpy( pDstU, pSrcU, sizeof(Pel)*(m_iCWidth) ); ::memcpy( pDstV, pSrcV, sizeof(Pel)*(m_iCWidth) ); pSrcU += iSrcStride; pSrcV += iSrcStride; pDstU += iDstStride; pDstV += iDstStride; } } Void TComYuv::copyPartToYuv( TComYuv* pcYuvDst, UInt uiSrcPartIdx ) { copyPartToLuma ( pcYuvDst, uiSrcPartIdx ); copyPartToChroma( pcYuvDst, uiSrcPartIdx ); } Void TComYuv::copyPartToLuma( TComYuv* pcYuvDst, UInt uiSrcPartIdx ) { Int y; Pel* pSrc = getLumaAddr(uiSrcPartIdx); Pel* pDst = pcYuvDst->getLumaAddr( 0 ); UInt iSrcStride = getStride(); UInt iDstStride = pcYuvDst->getStride(); UInt uiHeight = pcYuvDst->getHeight(); UInt uiWidth = pcYuvDst->getWidth(); for ( y = uiHeight; y != 0; y-- ) { ::memcpy( pDst, pSrc, sizeof(Pel)*uiWidth); pDst += iDstStride; pSrc += iSrcStride; } } Void TComYuv::copyPartToChroma( TComYuv* pcYuvDst, UInt uiSrcPartIdx ) { Int y; Pel* pSrcU = getCbAddr( uiSrcPartIdx ); Pel* pSrcV = getCrAddr( uiSrcPartIdx ); Pel* pDstU = pcYuvDst->getCbAddr( 0 ); Pel* pDstV = pcYuvDst->getCrAddr( 0 ); UInt iSrcStride = getCStride(); UInt iDstStride = pcYuvDst->getCStride(); UInt uiCHeight = pcYuvDst->getCHeight(); UInt uiCWidth = pcYuvDst->getCWidth(); for ( y = uiCHeight; y != 0; y-- ) { ::memcpy( pDstU, pSrcU, sizeof(Pel)*(uiCWidth) ); ::memcpy( pDstV, pSrcV, sizeof(Pel)*(uiCWidth) ); pSrcU += iSrcStride; pSrcV += iSrcStride; pDstU += iDstStride; pDstV += iDstStride; } } #if DEPTH_MAP_GENERATION Void TComYuv::copyPartToPartYuvPdm ( TComYuv* pcYuvDst, UInt uiPartIdx, UInt iWidth, UInt iHeight, UInt uiSubSampExpX, UInt uiSubSampExpY ) { copyPartToPartLumaPdm (pcYuvDst, uiPartIdx, iWidth, iHeight, uiSubSampExpX, uiSubSampExpY ); } #endif Void TComYuv::copyPartToPartYuv ( TComYuv* pcYuvDst, UInt uiPartIdx, UInt iWidth, UInt iHeight ) { copyPartToPartLuma (pcYuvDst, uiPartIdx, iWidth, iHeight ); copyPartToPartChroma (pcYuvDst, uiPartIdx, iWidth>>1, iHeight>>1 ); } #if DEPTH_MAP_GENERATION Void TComYuv::copyPartToPartLumaPdm ( TComYuv* pcYuvDst, UInt uiPartIdx, UInt iWidth, UInt iHeight, UInt uiSubSampExpX, UInt uiSubSampExpY ) { UInt uiBlkX = g_auiRasterToPelX[ g_auiZscanToRaster[ uiPartIdx ] ] >> uiSubSampExpX; UInt uiBlkY = g_auiRasterToPelY[ g_auiZscanToRaster[ uiPartIdx ] ] >> uiSubSampExpY; Pel* pSrc = getLumaAddr(uiPartIdx); Pel* pDst = pcYuvDst->getLumaAddr() + uiBlkY * pcYuvDst->getStride() + uiBlkX; if( pSrc == pDst ) { //th not a good idea //th best would be to fix the caller return ; } UInt iSrcStride = getStride(); UInt iDstStride = pcYuvDst->getStride(); for ( UInt y = iHeight; y != 0; y-- ) { ::memcpy( pDst, pSrc, iWidth * sizeof(Pel) ); pSrc += iSrcStride; pDst += iDstStride; } } #endif Void TComYuv::copyPartToPartLuma ( TComYuv* pcYuvDst, UInt uiPartIdx, UInt iWidth, UInt iHeight ) { Pel* pSrc = getLumaAddr(uiPartIdx); Pel* pDst = pcYuvDst->getLumaAddr(uiPartIdx); if( pSrc == pDst ) { //th not a good idea //th best would be to fix the caller return ; } UInt iSrcStride = getStride(); UInt iDstStride = pcYuvDst->getStride(); for ( UInt y = iHeight; y != 0; y-- ) { ::memcpy( pDst, pSrc, iWidth * sizeof(Pel) ); pSrc += iSrcStride; pDst += iDstStride; } } Void TComYuv::copyPartToPartChroma( TComYuv* pcYuvDst, UInt uiPartIdx, UInt iWidth, UInt iHeight ) { Pel* pSrcU = getCbAddr(uiPartIdx); Pel* pSrcV = getCrAddr(uiPartIdx); Pel* pDstU = pcYuvDst->getCbAddr(uiPartIdx); Pel* pDstV = pcYuvDst->getCrAddr(uiPartIdx); if( pSrcU == pDstU && pSrcV == pDstV) { //th not a good idea //th best would be to fix the caller return ; } UInt iSrcStride = getCStride(); UInt iDstStride = pcYuvDst->getCStride(); for ( UInt y = iHeight; y != 0; y-- ) { ::memcpy( pDstU, pSrcU, iWidth * sizeof(Pel) ); ::memcpy( pDstV, pSrcV, iWidth * sizeof(Pel) ); pSrcU += iSrcStride; pSrcV += iSrcStride; pDstU += iDstStride; pDstV += iDstStride; } } Void TComYuv::addClipPartLuma( TComYuv* pcYuvSrc0, TComYuv* pcYuvSrc1, UInt uiTrUnitIdx, UInt uiPartSize ) { Int x, y; Pel* pSrc0 = pcYuvSrc0->getLumaAddr( uiTrUnitIdx); Pel* pSrc1 = pcYuvSrc1->getLumaAddr( uiTrUnitIdx); Pel* pDst = getLumaAddr( uiTrUnitIdx); UInt iSrc0Stride = pcYuvSrc0->getStride(); UInt iSrc1Stride = pcYuvSrc1->getStride(); UInt iDstStride = getStride(); for ( y = uiPartSize-1; y >= 0; y-- ) { for ( x = uiPartSize-1; x >= 0; x-- ) { pDst[x] = Clip( pSrc0[x] + pSrc1[x] ); } pSrc0 += iSrc0Stride; pSrc1 += iSrc1Stride; pDst += iDstStride; } } #if LG_RESTRICTEDRESPRED_M24766 Void TComYuv::add(Int *iPUResiPredShift, PartSize uhPartitionSize, TComYuv* pcYuvAdd, Int iWidth, Int iHeight, Bool bSubtract ) { addLuma (iPUResiPredShift, uhPartitionSize, pcYuvAdd, iWidth, iHeight, bSubtract ); addChroma (iPUResiPredShift, uhPartitionSize, pcYuvAdd, iWidth>>1, iHeight>>1, bSubtract ); } #else Void TComYuv::add( TComYuv* pcYuvAdd, Int iWidth, Int iHeight, Bool bSubtract ) { addLuma ( pcYuvAdd, iWidth, iHeight, bSubtract ); addChroma ( pcYuvAdd, iWidth>>1, iHeight>>1, bSubtract ); } #endif #if LG_RESTRICTEDRESPRED_M24766 void TComYuv::getPUXYOffset(PartSize uhPartitionSize, Int iWidth, Int iHeight, Int &iXOffset, Int &iYOffset) { switch(uhPartitionSize) { case SIZE_2NxN: iXOffset = iWidth; iYOffset = iHeight >> 1; break; case SIZE_2NxnU: iXOffset = iWidth; iYOffset = iHeight >> 2; break; case SIZE_2NxnD: iXOffset = iWidth; iYOffset = (iHeight >> 1) + (iHeight >> 2); break; case SIZE_Nx2N: iXOffset = iWidth >> 1; iYOffset = iHeight; break; case SIZE_nLx2N: iXOffset = iWidth >> 2; iYOffset = iHeight; break; case SIZE_nRx2N: iXOffset = (iWidth >> 1) + (iWidth >> 2); iYOffset = iHeight; break; case SIZE_NxN: iXOffset = iWidth >> 1; iYOffset = iHeight >> 1; break; default: assert(uhPartitionSize == SIZE_2Nx2N); iXOffset = iWidth; iYOffset = iHeight; break; } } #endif #if LG_RESTRICTEDRESPRED_M24766 Void TComYuv::addLuma(Int *iPUResiPredShift, PartSize uhPartitionSize, TComYuv* pcYuvAdd, Int iWidth, Int iHeight, Bool bSubtract ) #else Void TComYuv::addLuma( TComYuv* pcYuvAdd, Int iWidth, Int iHeight, Bool bSubtract ) #endif { Int iScale = ( bSubtract ? -1 : 1 ); Int iAddStride = pcYuvAdd->getStride(); Int iDstStride = getStride(); Pel* pAddSamples = pcYuvAdd->getLumaAddr(); Pel* pDstSamples = getLumaAddr(); #if LG_RESTRICTEDRESPRED_M24766 Int iXOffset, iYOffset; getPUXYOffset(uhPartitionSize, iWidth, iHeight, iXOffset, iYOffset); for( Int iY = 0; iY < iYOffset; iY++, pDstSamples += iDstStride, pAddSamples += iAddStride ) { if(iPUResiPredShift[0] >= 0) { for( Int iX = 0; iX < iXOffset; iX++ ) { pDstSamples[iX] += iScale * (pAddSamples[iX] >> iPUResiPredShift[0]); } } if(iPUResiPredShift[1] >= 0) { for( Int iX = iXOffset; iX < iWidth; iX++ ) { pDstSamples[iX] += iScale * (pAddSamples[iX] >> iPUResiPredShift[1]); } } } for( Int iY = iYOffset; iY < iHeight; iY++, pDstSamples += iDstStride, pAddSamples += iAddStride ) { if(iPUResiPredShift[2] >= 0) { for( Int iX = 0; iX < iXOffset; iX++ ) { pDstSamples[iX] += iScale * (pAddSamples[iX] >> iPUResiPredShift[2]); } } if(iPUResiPredShift[3] >= 0) { for( Int iX = iXOffset; iX < iWidth; iX++ ) { pDstSamples[iX] += iScale * (pAddSamples[iX] >> iPUResiPredShift[3]); } } } #else for( Int iY = 0; iY < iHeight; iY++, pDstSamples += iDstStride, pAddSamples += iAddStride ) { for( Int iX = 0; iX < iWidth; iX++ ) { pDstSamples[iX] += iScale * pAddSamples[iX]; } } #endif } #if LG_RESTRICTEDRESPRED_M24766 Void TComYuv::addChroma(Int *iPUResiPredShift, PartSize uhPartitionSize, TComYuv* pcYuvAdd, Int iWidth, Int iHeight, Bool bSubtract ) #else Void TComYuv::addChroma( TComYuv* pcYuvAdd, Int iWidth, Int iHeight, Bool bSubtract ) #endif { Int iScale = ( bSubtract ? -1 : 1 ); Int iAddStride = pcYuvAdd->getCStride(); Int iDstStride = getCStride(); Pel* pAddSamplesCb = pcYuvAdd->getCbAddr(); Pel* pAddSamplesCr = pcYuvAdd->getCrAddr(); Pel* pDstSamplesCb = getCbAddr(); Pel* pDstSamplesCr = getCrAddr(); #if LG_RESTRICTEDRESPRED_M24766 Int iXOffset, iYOffset; getPUXYOffset(uhPartitionSize, iWidth, iHeight, iXOffset, iYOffset); for( Int iY = 0; iY < iYOffset; iY++, pDstSamplesCb += iDstStride, pAddSamplesCb += iAddStride, pDstSamplesCr += iDstStride, pAddSamplesCr += iAddStride ) { if(iPUResiPredShift[0] >= 0) { for( Int iX = 0; iX < iXOffset; iX++ ) { pDstSamplesCb[iX] += iScale * (pAddSamplesCb[iX] >> iPUResiPredShift[0]); pDstSamplesCr[iX] += iScale * (pAddSamplesCr[iX] >> iPUResiPredShift[0]); } } if(iPUResiPredShift[1] >= 0) { for( Int iX = iXOffset; iX < iWidth; iX++ ) { pDstSamplesCb[iX] += iScale * (pAddSamplesCb[iX] >> iPUResiPredShift[1]); pDstSamplesCr[iX] += iScale * (pAddSamplesCr[iX] >> iPUResiPredShift[1]); } } } for( Int iY = iYOffset; iY < iHeight; iY++, pDstSamplesCb += iDstStride, pAddSamplesCb += iAddStride, pDstSamplesCr += iDstStride, pAddSamplesCr += iAddStride ) { if(iPUResiPredShift[2] >= 0) { for( Int iX = 0; iX < iXOffset; iX++ ) { pDstSamplesCb[iX] += iScale * (pAddSamplesCb[iX] >> iPUResiPredShift[2]); pDstSamplesCr[iX] += iScale * (pAddSamplesCr[iX] >> iPUResiPredShift[2]); } } if(iPUResiPredShift[3] >= 0) { for( Int iX = iXOffset; iX < iWidth; iX++ ) { pDstSamplesCb[iX] += iScale * (pAddSamplesCb[iX] >> iPUResiPredShift[3]); pDstSamplesCr[iX] += iScale * (pAddSamplesCr[iX] >> iPUResiPredShift[3]); } } } #else for( Int iY = 0; iY < iHeight; iY++, pDstSamplesCb += iDstStride, pAddSamplesCb += iAddStride, pDstSamplesCr += iDstStride, pAddSamplesCr += iAddStride ) { for( Int iX = 0; iX < iWidth; iX++ ) { pDstSamplesCb[iX] += iScale * pAddSamplesCb[iX]; pDstSamplesCr[iX] += iScale * pAddSamplesCr[iX]; } } #endif } Void TComYuv::clip( Int iWidth, Int iHeight ) { clipLuma ( iWidth, iHeight ); clipChroma ( iWidth>>1, iHeight>>1 ); } Void TComYuv::clipLuma( Int iWidth, Int iHeight ) { Int iStride = getStride(); Pel* pSamples = getLumaAddr(); for( Int iY = 0; iY < iHeight; iY++, pSamples += iStride ) { for( Int iX = 0; iX < iWidth; iX++ ) { pSamples[iX] = xClip( pSamples[iX] ); } } } Void TComYuv::clipChroma( Int iWidth, Int iHeight ) { Int iStride = getCStride(); Pel* pSamplesCb = getCbAddr(); Pel* pSamplesCr = getCrAddr(); for( Int iY = 0; iY < iHeight; iY++, pSamplesCb += iStride, pSamplesCr += iStride ) { for( Int iX = 0; iX < iWidth; iX++ ) { pSamplesCb[iX] = xClip( pSamplesCb[iX] ); pSamplesCr[iX] = xClip( pSamplesCr[iX] ); } } } Void TComYuv::addClip( TComYuv* pcYuvSrc0, TComYuv* pcYuvSrc1, UInt uiTrUnitIdx, UInt uiPartSize ) { addClipLuma ( pcYuvSrc0, pcYuvSrc1, uiTrUnitIdx, uiPartSize ); addClipChroma ( pcYuvSrc0, pcYuvSrc1, uiTrUnitIdx, uiPartSize>>1 ); } Void TComYuv::addClipLuma( TComYuv* pcYuvSrc0, TComYuv* pcYuvSrc1, UInt uiTrUnitIdx, UInt uiPartSize ) { Int x, y; Pel* pSrc0 = pcYuvSrc0->getLumaAddr( uiTrUnitIdx, uiPartSize ); Pel* pSrc1 = pcYuvSrc1->getLumaAddr( uiTrUnitIdx, uiPartSize ); Pel* pDst = getLumaAddr( uiTrUnitIdx, uiPartSize ); UInt iSrc0Stride = pcYuvSrc0->getStride(); UInt iSrc1Stride = pcYuvSrc1->getStride(); UInt iDstStride = getStride(); for ( y = uiPartSize-1; y >= 0; y-- ) { for ( x = uiPartSize-1; x >= 0; x-- ) { pDst[x] = Clip( pSrc0[x] + pSrc1[x] ); } pSrc0 += iSrc0Stride; pSrc1 += iSrc1Stride; pDst += iDstStride; } } Void TComYuv::addClipChroma( TComYuv* pcYuvSrc0, TComYuv* pcYuvSrc1, UInt uiTrUnitIdx, UInt uiPartSize ) { Int x, y; Pel* pSrcU0 = pcYuvSrc0->getCbAddr( uiTrUnitIdx, uiPartSize ); Pel* pSrcU1 = pcYuvSrc1->getCbAddr( uiTrUnitIdx, uiPartSize ); Pel* pSrcV0 = pcYuvSrc0->getCrAddr( uiTrUnitIdx, uiPartSize ); Pel* pSrcV1 = pcYuvSrc1->getCrAddr( uiTrUnitIdx, uiPartSize ); Pel* pDstU = getCbAddr( uiTrUnitIdx, uiPartSize ); Pel* pDstV = getCrAddr( uiTrUnitIdx, uiPartSize ); UInt iSrc0Stride = pcYuvSrc0->getCStride(); UInt iSrc1Stride = pcYuvSrc1->getCStride(); UInt iDstStride = getCStride(); for ( y = uiPartSize-1; y >= 0; y-- ) { for ( x = uiPartSize-1; x >= 0; x-- ) { pDstU[x] = Clip( pSrcU0[x] + pSrcU1[x] ); pDstV[x] = Clip( pSrcV0[x] + pSrcV1[x] ); } pSrcU0 += iSrc0Stride; pSrcU1 += iSrc1Stride; pSrcV0 += iSrc0Stride; pSrcV1 += iSrc1Stride; pDstU += iDstStride; pDstV += iDstStride; } } #if LG_RESTRICTEDRESPRED_M24766 Void TComYuv::subtract(Int *iPUResiPredShift, PartSize uhPartitionSize, TComYuv* pcYuvSrc0, TComYuv* pcYuvSrc1, UInt uiTrUnitIdx, UInt uiPartSize ) { subtractLuma (iPUResiPredShift, uhPartitionSize, pcYuvSrc0, pcYuvSrc1, uiTrUnitIdx, uiPartSize ); subtractChroma(iPUResiPredShift, uhPartitionSize, pcYuvSrc0, pcYuvSrc1, uiTrUnitIdx, uiPartSize>>1 ); } #else Void TComYuv::subtract( TComYuv* pcYuvSrc0, TComYuv* pcYuvSrc1, UInt uiTrUnitIdx, UInt uiPartSize ) { subtractLuma ( pcYuvSrc0, pcYuvSrc1, uiTrUnitIdx, uiPartSize ); subtractChroma( pcYuvSrc0, pcYuvSrc1, uiTrUnitIdx, uiPartSize>>1 ); } #endif #if LG_RESTRICTEDRESPRED_M24766 Void TComYuv::subtractLuma(Int *iPUResiPredShift, PartSize uhPartitionSize, TComYuv* pcYuvSrc0, TComYuv* pcYuvSrc1, UInt uiTrUnitIdx, UInt uiPartSize ) #else Void TComYuv::subtractLuma( TComYuv* pcYuvSrc0, TComYuv* pcYuvSrc1, UInt uiTrUnitIdx, UInt uiPartSize ) #endif { Int x, y; Pel* pSrc0 = pcYuvSrc0->getLumaAddr( uiTrUnitIdx, uiPartSize ); Pel* pSrc1 = pcYuvSrc1->getLumaAddr( uiTrUnitIdx, uiPartSize ); Pel* pDst = getLumaAddr( uiTrUnitIdx, uiPartSize ); Int iSrc0Stride = pcYuvSrc0->getStride(); Int iSrc1Stride = pcYuvSrc1->getStride(); Int iDstStride = getStride(); #if LG_RESTRICTEDRESPRED_M24766 Int iXOffset, iYOffset; getPUXYOffset(uhPartitionSize, uiPartSize, uiPartSize, iXOffset, iYOffset); #if FIX_LG_RESTRICTEDRESPRED_M24766 for ( y = 0; y < iYOffset; y++ ) { if(iPUResiPredShift[0] >= 0) { for ( x = 0; x < iXOffset; x++ ) { pDst[x] = pSrc0[x] - (pSrc1[x] >> iPUResiPredShift[0]); } } if(iPUResiPredShift[1] >= 0) { for ( x = iXOffset; x < uiPartSize; x++ ) { pDst[x] = pSrc0[x] - (pSrc1[x] >> iPUResiPredShift[1]); } } pSrc0 += iSrc0Stride; pSrc1 += iSrc1Stride; pDst += iDstStride; } for ( y = iYOffset; y < uiPartSize; y++ ) { if(iPUResiPredShift[2] >= 0) { for ( x = 0; x < iXOffset; x++ ) { pDst[x] = pSrc0[x] - (pSrc1[x] >> iPUResiPredShift[2]); } } if(iPUResiPredShift[3] >= 0) { for ( x = iXOffset; x < uiPartSize; x++ ) { pDst[x] = pSrc0[x] - (pSrc1[x] >> iPUResiPredShift[3]); } } pSrc0 += iSrc0Stride; pSrc1 += iSrc1Stride; pDst += iDstStride; } #else for ( y = uiPartSize-1; y >= iYOffset; y-- ) { if(iPUResiPredShift[3] >= 0) { for ( x = uiPartSize-1; x >= iXOffset; x-- ) { pDst[x] = pSrc0[x] - (pSrc1[x] >> iPUResiPredShift[3]); } } if(iPUResiPredShift[2] >= 0) { for ( x = iXOffset-1; x >= 0; x-- ) { pDst[x] = pSrc0[x] - (pSrc1[x] >> iPUResiPredShift[2]); } } pSrc0 += iSrc0Stride; pSrc1 += iSrc1Stride; pDst += iDstStride; } for ( y = iYOffset-1; y >= 0; y-- ) { if(iPUResiPredShift[1] >= 0) { for ( x = uiPartSize-1; x >= iXOffset; x-- ) { pDst[x] = pSrc0[x] - (pSrc1[x] >> iPUResiPredShift[3]); } } if(iPUResiPredShift[0] >= 0) { for ( x = iXOffset-1; x >= 0; x-- ) { pDst[x] = pSrc0[x] - (pSrc1[x] >> iPUResiPredShift[2]); } } pSrc0 += iSrc0Stride; pSrc1 += iSrc1Stride; pDst += iDstStride; } #endif #else for ( y = uiPartSize-1; y >= 0; y-- ) { for ( x = uiPartSize-1; x >= 0; x-- ) { pDst[x] = pSrc0[x] - pSrc1[x]; } pSrc0 += iSrc0Stride; pSrc1 += iSrc1Stride; pDst += iDstStride; } #endif } #if LG_RESTRICTEDRESPRED_M24766 Void TComYuv::subtractChroma(Int *iPUResiPredShift, PartSize uhPartitionSize, TComYuv* pcYuvSrc0, TComYuv* pcYuvSrc1, UInt uiTrUnitIdx, UInt uiPartSize ) #else Void TComYuv::subtractChroma( TComYuv* pcYuvSrc0, TComYuv* pcYuvSrc1, UInt uiTrUnitIdx, UInt uiPartSize ) #endif { Int x, y; Pel* pSrcU0 = pcYuvSrc0->getCbAddr( uiTrUnitIdx, uiPartSize ); Pel* pSrcU1 = pcYuvSrc1->getCbAddr( uiTrUnitIdx, uiPartSize ); Pel* pSrcV0 = pcYuvSrc0->getCrAddr( uiTrUnitIdx, uiPartSize ); Pel* pSrcV1 = pcYuvSrc1->getCrAddr( uiTrUnitIdx, uiPartSize ); Pel* pDstU = getCbAddr( uiTrUnitIdx, uiPartSize ); Pel* pDstV = getCrAddr( uiTrUnitIdx, uiPartSize ); Int iSrc0Stride = pcYuvSrc0->getCStride(); Int iSrc1Stride = pcYuvSrc1->getCStride(); Int iDstStride = getCStride(); #if LG_RESTRICTEDRESPRED_M24766 Int iXOffset, iYOffset; getPUXYOffset(uhPartitionSize, uiPartSize, uiPartSize, iXOffset, iYOffset); #if FIX_LG_RESTRICTEDRESPRED_M24766 for ( y = 0; y < iYOffset; y++ ) { if(iPUResiPredShift[0] >= 0) { for ( x = 0; x < iXOffset; x++ ) { pDstU[x] = pSrcU0[x] - (pSrcU1[x]>>iPUResiPredShift[0]); pDstV[x] = pSrcV0[x] - (pSrcV1[x]>>iPUResiPredShift[0]); } } if(iPUResiPredShift[1] >= 0) { for ( x = iXOffset; x < uiPartSize; x++ ) { pDstU[x] = pSrcU0[x] - (pSrcU1[x]>>iPUResiPredShift[1]); pDstV[x] = pSrcV0[x] - (pSrcV1[x]>>iPUResiPredShift[1]); } } pSrcU0 += iSrc0Stride; pSrcU1 += iSrc1Stride; pSrcV0 += iSrc0Stride; pSrcV1 += iSrc1Stride; pDstU += iDstStride; pDstV += iDstStride; } for ( y = iYOffset; y < uiPartSize; y++ ) { if(iPUResiPredShift[2] >= 0) { for ( x = 0; x < iXOffset; x++ ) { pDstU[x] = pSrcU0[x] - (pSrcU1[x]>>iPUResiPredShift[2]); pDstV[x] = pSrcV0[x] - (pSrcV1[x]>>iPUResiPredShift[2]); } } if(iPUResiPredShift[3] >= 0) { for ( x = iXOffset; x < uiPartSize; x++ ) { pDstU[x] = pSrcU0[x] - (pSrcU1[x]>>iPUResiPredShift[3]); pDstV[x] = pSrcV0[x] - (pSrcV1[x]>>iPUResiPredShift[3]); } } pSrcU0 += iSrc0Stride; pSrcU1 += iSrc1Stride; pSrcV0 += iSrc0Stride; pSrcV1 += iSrc1Stride; pDstU += iDstStride; pDstV += iDstStride; } #else for ( y = uiPartSize-1; y >= iYOffset; y-- ) { if(iPUResiPredShift[3] >= 0) { for ( x = uiPartSize-1; x >= iXOffset; x-- ) { pDstU[x] = pSrcU0[x] - (pSrcU1[x]>>iPUResiPredShift[3]); pDstV[x] = pSrcV0[x] - (pSrcV1[x]>>iPUResiPredShift[3]); } } if(iPUResiPredShift[2] >= 0) { for ( x = iXOffset-1; x >= 0; x-- ) { pDstU[x] = pSrcU0[x] - (pSrcU1[x]>>iPUResiPredShift[2]); pDstV[x] = pSrcV0[x] - (pSrcV1[x]>>iPUResiPredShift[2]); } } pSrcU0 += iSrc0Stride; pSrcU1 += iSrc1Stride; pSrcV0 += iSrc0Stride; pSrcV1 += iSrc1Stride; pDstU += iDstStride; pDstV += iDstStride; } for ( y = iYOffset-1; y >= 0; y-- ) { if(iPUResiPredShift[1] >= 0) { for ( x = uiPartSize-1; x >= iXOffset; x-- ) { pDstU[x] = pSrcU0[x] - (pSrcU1[x]>>iPUResiPredShift[1]); pDstV[x] = pSrcV0[x] - (pSrcV1[x]>>iPUResiPredShift[1]); } } if(iPUResiPredShift[0] >= 0) { for ( x = iXOffset-1; x >= 0; x-- ) { pDstU[x] = pSrcU0[x] - (pSrcU1[x]>>iPUResiPredShift[0]); pDstV[x] = pSrcV0[x] - (pSrcV1[x]>>iPUResiPredShift[0]); } } pSrcU0 += iSrc0Stride; pSrcU1 += iSrc1Stride; pSrcV0 += iSrc0Stride; pSrcV1 += iSrc1Stride; pDstU += iDstStride; pDstV += iDstStride; } #endif #else for ( y = uiPartSize-1; y >= 0; y-- ) { for ( x = uiPartSize-1; x >= 0; x-- ) { pDstU[x] = pSrcU0[x] - pSrcU1[x]; pDstV[x] = pSrcV0[x] - pSrcV1[x]; } pSrcU0 += iSrc0Stride; pSrcU1 += iSrc1Stride; pSrcV0 += iSrc0Stride; pSrcV1 += iSrc1Stride; pDstU += iDstStride; pDstV += iDstStride; } #endif } Void TComYuv::addAvg( TComYuv* pcYuvSrc0, TComYuv* pcYuvSrc1, UInt iPartUnitIdx, UInt iWidth, UInt iHeight ) { Int x, y; Pel* pSrcY0 = pcYuvSrc0->getLumaAddr( iPartUnitIdx ); Pel* pSrcU0 = pcYuvSrc0->getCbAddr ( iPartUnitIdx ); Pel* pSrcV0 = pcYuvSrc0->getCrAddr ( iPartUnitIdx ); Pel* pSrcY1 = pcYuvSrc1->getLumaAddr( iPartUnitIdx ); Pel* pSrcU1 = pcYuvSrc1->getCbAddr ( iPartUnitIdx ); Pel* pSrcV1 = pcYuvSrc1->getCrAddr ( iPartUnitIdx ); Pel* pDstY = getLumaAddr( iPartUnitIdx ); Pel* pDstU = getCbAddr ( iPartUnitIdx ); Pel* pDstV = getCrAddr ( iPartUnitIdx ); UInt iSrc0Stride = pcYuvSrc0->getStride(); UInt iSrc1Stride = pcYuvSrc1->getStride(); UInt iDstStride = getStride(); Int shiftNum = IF_INTERNAL_PREC + 1 - ( g_uiBitDepth + g_uiBitIncrement ); Int offset = ( 1 << ( shiftNum - 1 ) ) + 2 * IF_INTERNAL_OFFS; for ( y = 0; y < iHeight; y++ ) { for ( x = 0; x < iWidth; x += 4 ) { pDstY[ x + 0 ] = Clip( ( pSrcY0[ x + 0 ] + pSrcY1[ x + 0 ] + offset ) >> shiftNum ); pDstY[ x + 1 ] = Clip( ( pSrcY0[ x + 1 ] + pSrcY1[ x + 1 ] + offset ) >> shiftNum ); pDstY[ x + 2 ] = Clip( ( pSrcY0[ x + 2 ] + pSrcY1[ x + 2 ] + offset ) >> shiftNum ); pDstY[ x + 3 ] = Clip( ( pSrcY0[ x + 3 ] + pSrcY1[ x + 3 ] + offset ) >> shiftNum ); } pSrcY0 += iSrc0Stride; pSrcY1 += iSrc1Stride; pDstY += iDstStride; } iSrc0Stride = pcYuvSrc0->getCStride(); iSrc1Stride = pcYuvSrc1->getCStride(); iDstStride = getCStride(); iWidth >>=1; iHeight >>=1; for ( y = iHeight-1; y >= 0; y-- ) { for ( x = iWidth-1; x >= 0; ) { // note: chroma min width is 2 pDstU[x] = Clip((pSrcU0[x] + pSrcU1[x] + offset) >> shiftNum); pDstV[x] = Clip((pSrcV0[x] + pSrcV1[x] + offset) >> shiftNum); x--; pDstU[x] = Clip((pSrcU0[x] + pSrcU1[x] + offset) >> shiftNum); pDstV[x] = Clip((pSrcV0[x] + pSrcV1[x] + offset) >> shiftNum); x--; } pSrcU0 += iSrc0Stride; pSrcU1 += iSrc1Stride; pSrcV0 += iSrc0Stride; pSrcV1 += iSrc1Stride; pDstU += iDstStride; pDstV += iDstStride; } } #if DEPTH_MAP_GENERATION Void TComYuv::addAvgPdm( TComYuv* pcYuvSrc0, TComYuv* pcYuvSrc1, UInt iPartUnitIdx, UInt iWidth, UInt iHeight, UInt uiSubSampExpX, UInt uiSubSampExpY ) { Int x, y; UInt uiBlkX = g_auiRasterToPelX[ g_auiZscanToRaster[ iPartUnitIdx ] ] >> uiSubSampExpX; UInt uiBlkY = g_auiRasterToPelY[ g_auiZscanToRaster[ iPartUnitIdx ] ] >> uiSubSampExpY; Pel* pSrcY0 = pcYuvSrc0->getLumaAddr( iPartUnitIdx ); Pel* pSrcY1 = pcYuvSrc1->getLumaAddr( iPartUnitIdx ); Pel* pDstY = getLumaAddr() + uiBlkY * getStride() + uiBlkX; UInt iSrc0Stride = pcYuvSrc0->getStride(); UInt iSrc1Stride = pcYuvSrc1->getStride(); UInt iDstStride = getStride(); for ( y = iHeight-1; y >= 0; y-- ) { for ( x = iWidth-1; x >= 0; x-- ) { pDstY[x] = (pSrcY0[x] + pSrcY1[x] + 1) >> 1; } pSrcY0 += iSrc0Stride; pSrcY1 += iSrc1Stride; pDstY += iDstStride; } } #endif Void TComYuv::removeHighFreq( TComYuv* pcYuvSrc, UInt uiPartIdx, UInt uiWidht, UInt uiHeight ) { Int x, y; Pel* pSrc = pcYuvSrc->getLumaAddr(uiPartIdx); Pel* pSrcU = pcYuvSrc->getCbAddr(uiPartIdx); Pel* pSrcV = pcYuvSrc->getCrAddr(uiPartIdx); Pel* pDst = getLumaAddr(uiPartIdx); Pel* pDstU = getCbAddr(uiPartIdx); Pel* pDstV = getCrAddr(uiPartIdx); Int iSrcStride = pcYuvSrc->getStride(); Int iDstStride = getStride(); for ( y = uiHeight-1; y >= 0; y-- ) { for ( x = uiWidht-1; x >= 0; x-- ) { #if DISABLING_CLIP_FOR_BIPREDME pDst[x ] = (pDst[x ]<<1) - pSrc[x ] ; #else pDst[x ] = Clip( (pDst[x ]<<1) - pSrc[x ] ); #endif } pSrc += iSrcStride; pDst += iDstStride; } iSrcStride = pcYuvSrc->getCStride(); iDstStride = getCStride(); uiHeight >>= 1; uiWidht >>= 1; for ( y = uiHeight-1; y >= 0; y-- ) { for ( x = uiWidht-1; x >= 0; x-- ) { #if DISABLING_CLIP_FOR_BIPREDME pDstU[x ] = (pDstU[x ]<<1) - pSrcU[x ] ; pDstV[x ] = (pDstV[x ]<<1) - pSrcV[x ] ; #else pDstU[x ] = Clip( (pDstU[x ]<<1) - pSrcU[x ] ); pDstV[x ] = Clip( (pDstV[x ]<<1) - pSrcV[x ] ); #endif } pSrcU += iSrcStride; pSrcV += iSrcStride; pDstU += iDstStride; pDstV += iDstStride; } } //! \}