Mercurial > hg > forks > libbpg
diff jctvc/TLibCommon/TComPattern.cpp @ 0:772086c29cc7
Initial import.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Wed, 16 Nov 2016 11:16:33 +0200 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jctvc/TLibCommon/TComPattern.cpp Wed Nov 16 11:16:33 2016 +0200 @@ -0,0 +1,734 @@ +/* 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-2014, 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 TComPattern.cpp + \brief neighbouring pixel access classes +*/ + +#include "TComPic.h" +#include "TComPattern.h" +#include "TComDataCU.h" +#include "TComTU.h" +#include "Debug.h" +#include "TComPrediction.h" + +//! \ingroup TLibCommon +//! \{ + +// Forward declarations + +/// padding of unavailable reference samples for intra prediction +#if O0043_BEST_EFFORT_DECODING +Void fillReferenceSamples( const Int bitDepth, const Int bitDepthDelta, TComDataCU* pcCU, const Pel* piRoiOrigin, Pel* piAdiTemp, const Bool* bNeighborFlags, +#else +Void fillReferenceSamples( const Int bitDepth, TComDataCU* pcCU, const Pel* piRoiOrigin, Pel* piAdiTemp, const Bool* bNeighborFlags, +#endif + const Int iNumIntraNeighbor, const Int unitWidth, const Int unitHeight, const Int iAboveUnits, const Int iLeftUnits, + const UInt uiCuWidth, const UInt uiCuHeight, const UInt uiWidth, const UInt uiHeight, const Int iPicStride, + const ChannelType chType, const ChromaFormat chFmt ); + +/// constrained intra prediction +Bool isAboveLeftAvailable ( TComDataCU* pcCU, UInt uiPartIdxLT ); +Int isAboveAvailable ( TComDataCU* pcCU, UInt uiPartIdxLT, UInt uiPartIdxRT, Bool* bValidFlags ); +Int isLeftAvailable ( TComDataCU* pcCU, UInt uiPartIdxLT, UInt uiPartIdxLB, Bool* bValidFlags ); +Int isAboveRightAvailable ( TComDataCU* pcCU, UInt uiPartIdxLT, UInt uiPartIdxRT, Bool* bValidFlags ); +Int isBelowLeftAvailable ( TComDataCU* pcCU, UInt uiPartIdxLT, UInt uiPartIdxLB, Bool* bValidFlags ); + + +// ==================================================================================================================== +// Public member functions (TComPatternParam) +// ==================================================================================================================== + +/** \param piTexture pixel data + \param iRoiWidth pattern width + \param iRoiHeight pattern height + \param iStride buffer stride + \param iOffsetLeft neighbour offset (left) + \param iOffsetRight neighbour offset (right) + \param iOffsetAbove neighbour offset (above) + \param iOffsetBottom neighbour offset (bottom) + */ +Void TComPatternParam::setPatternParamPel ( Pel* piTexture, + Int iRoiWidth, + Int iRoiHeight, + Int iStride + ) +{ + m_piROIOrigin = piTexture; + m_iROIWidth = iRoiWidth; + m_iROIHeight = iRoiHeight; + m_iPatternStride = iStride; +} + +// ==================================================================================================================== +// Public member functions (TComPattern) +// ==================================================================================================================== + +Void TComPattern::initPattern (Pel* piY, + Int iRoiWidth, + Int iRoiHeight, + Int iStride) +{ + m_cPatternY. setPatternParamPel( piY, iRoiWidth, iRoiHeight, iStride); +} + + +// TODO: move this function to TComPrediction.cpp. +Void TComPrediction::initAdiPatternChType( TComTU &rTu, Bool& bAbove, Bool& bLeft, const ComponentID compID, const Bool bFilterRefSamples DEBUG_STRING_FN_DECLARE(sDebug)) +{ + const ChannelType chType = toChannelType(compID); + + TComDataCU *pcCU=rTu.getCU(); + const UInt uiZorderIdxInPart=rTu.GetAbsPartIdxTU(); + const UInt uiTuWidth = rTu.getRect(compID).width; + const UInt uiTuHeight = rTu.getRect(compID).height; + const UInt uiTuWidth2 = uiTuWidth << 1; + const UInt uiTuHeight2 = uiTuHeight << 1; + + const Int iBaseUnitSize = g_uiMaxCUWidth >> g_uiMaxCUDepth; + const Int iUnitWidth = iBaseUnitSize >> pcCU->getPic()->getPicYuvRec()->getComponentScaleX(compID); + const Int iUnitHeight = iBaseUnitSize >> pcCU->getPic()->getPicYuvRec()->getComponentScaleY(compID); + const Int iTUWidthInUnits = uiTuWidth / iUnitWidth; + const Int iTUHeightInUnits = uiTuHeight / iUnitHeight; + const Int iAboveUnits = iTUWidthInUnits << 1; + const Int iLeftUnits = iTUHeightInUnits << 1; + + assert(iTUHeightInUnits > 0 && iTUWidthInUnits > 0); + + const Int iPartIdxStride = pcCU->getPic()->getNumPartInCtuWidth(); + const UInt uiPartIdxLT = pcCU->getZorderIdxInCtu() + uiZorderIdxInPart; + const UInt uiPartIdxRT = g_auiRasterToZscan[ g_auiZscanToRaster[ uiPartIdxLT ] + iTUWidthInUnits - 1 ]; + const UInt uiPartIdxLB = g_auiRasterToZscan[ g_auiZscanToRaster[ uiPartIdxLT ] + ((iTUHeightInUnits - 1) * iPartIdxStride)]; + + Int iPicStride = pcCU->getPic()->getStride(compID); + Bool bNeighborFlags[4 * MAX_NUM_SPU_W + 1]; + Int iNumIntraNeighbor = 0; + + bNeighborFlags[iLeftUnits] = isAboveLeftAvailable( pcCU, uiPartIdxLT ); + iNumIntraNeighbor += bNeighborFlags[iLeftUnits] ? 1 : 0; + iNumIntraNeighbor += isAboveAvailable ( pcCU, uiPartIdxLT, uiPartIdxRT, (bNeighborFlags + iLeftUnits + 1) ); + iNumIntraNeighbor += isAboveRightAvailable( pcCU, uiPartIdxLT, uiPartIdxRT, (bNeighborFlags + iLeftUnits + 1 + iTUWidthInUnits ) ); + iNumIntraNeighbor += isLeftAvailable ( pcCU, uiPartIdxLT, uiPartIdxLB, (bNeighborFlags + iLeftUnits - 1) ); + iNumIntraNeighbor += isBelowLeftAvailable ( pcCU, uiPartIdxLT, uiPartIdxLB, (bNeighborFlags + iLeftUnits - 1 - iTUHeightInUnits) ); + + bAbove = true; + bLeft = true; + + const ChromaFormat chFmt = rTu.GetChromaFormat(); + const UInt uiROIWidth = uiTuWidth2+1; + const UInt uiROIHeight = uiTuHeight2+1; + + assert(uiROIWidth*uiROIHeight <= m_iYuvExtSize); + +#ifdef DEBUG_STRING + std::stringstream ss(stringstream::out); +#endif + + { + Pel *piAdiTemp = m_piYuvExt[compID][PRED_BUF_UNFILTERED]; + Pel *piRoiOrigin = pcCU->getPic()->getPicYuvRec()->getAddr(compID, pcCU->getCtuRsAddr(), pcCU->getZorderIdxInCtu()+uiZorderIdxInPart); +#if O0043_BEST_EFFORT_DECODING + fillReferenceSamples (g_bitDepthInStream[chType], g_bitDepthInStream[chType] - g_bitDepth[chType], pcCU, piRoiOrigin, piAdiTemp, bNeighborFlags, iNumIntraNeighbor, iUnitWidth, iUnitHeight, iAboveUnits, iLeftUnits, +#else + fillReferenceSamples (g_bitDepth[chType], pcCU, piRoiOrigin, piAdiTemp, bNeighborFlags, iNumIntraNeighbor, iUnitWidth, iUnitHeight, iAboveUnits, iLeftUnits, +#endif + uiTuWidth, uiTuHeight, uiROIWidth, uiROIHeight, iPicStride, toChannelType(compID), chFmt); + + +#ifdef DEBUG_STRING + if (DebugOptionList::DebugString_Pred.getInt()&DebugStringGetPredModeMask(MODE_INTRA)) + { + ss << "###: generating Ref Samples for channel " << compID << " and " << rTu.getRect(compID).width << " x " << rTu.getRect(compID).height << "\n"; + for (UInt y=0; y<uiROIHeight; y++) + { + ss << "###: - "; + for (UInt x=0; x<uiROIWidth; x++) + { + if (x==0 || y==0) + ss << piAdiTemp[y*uiROIWidth + x] << ", "; +// if (x%16==15) ss << "\nPart size: ~ "; + } + ss << "\n"; + } + } +#endif + + if (bFilterRefSamples) + { + // generate filtered intra prediction samples + + Int stride = uiROIWidth; + const Pel *piSrcPtr = piAdiTemp + (stride * uiTuHeight2); // bottom left + Pel *piDestPtr = m_piYuvExt[compID][PRED_BUF_FILTERED] + (stride * uiTuHeight2); // bottom left + + //------------------------------------------------ + + Bool useStrongIntraSmoothing = isLuma(chType) && pcCU->getSlice()->getSPS()->getUseStrongIntraSmoothing(); + + const Pel bottomLeft = piAdiTemp[stride * uiTuHeight2]; + const Pel topLeft = piAdiTemp[0]; + const Pel topRight = piAdiTemp[uiTuWidth2]; + + if (useStrongIntraSmoothing) + { +#if O0043_BEST_EFFORT_DECODING + const Int threshold = 1 << (g_bitDepthInStream[chType] - 5); +#else + const Int threshold = 1 << (g_bitDepth[chType] - 5); +#endif + const Bool bilinearLeft = abs((bottomLeft + topLeft ) - (2 * piAdiTemp[stride * uiTuHeight])) < threshold; //difference between the + const Bool bilinearAbove = abs((topLeft + topRight) - (2 * piAdiTemp[ uiTuWidth ])) < threshold; //ends and the middle + if ((uiTuWidth < 32) || (!bilinearLeft) || (!bilinearAbove)) + useStrongIntraSmoothing = false; + } + + *piDestPtr = *piSrcPtr; // bottom left is not filtered + piDestPtr -= stride; + piSrcPtr -= stride; + + //------------------------------------------------ + + //left column (bottom to top) + + if (useStrongIntraSmoothing) + { + const Int shift = g_aucConvertToBit[uiTuHeight] + 3; //log2(uiTuHeight2) + + for(UInt i=1; i<uiTuHeight2; i++, piDestPtr-=stride) + { + *piDestPtr = (((uiTuHeight2 - i) * bottomLeft) + (i * topLeft) + uiTuHeight) >> shift; + } + + piSrcPtr -= stride * (uiTuHeight2 - 1); + } + else + { + for(UInt i=1; i<uiTuHeight2; i++, piDestPtr-=stride, piSrcPtr-=stride) + { + *piDestPtr = ( piSrcPtr[stride] + 2*piSrcPtr[0] + piSrcPtr[-stride] + 2 ) >> 2; + } + } + + //------------------------------------------------ + + //top-left + + if (useStrongIntraSmoothing) + { + *piDestPtr = piSrcPtr[0]; + } + else + { + *piDestPtr = ( piSrcPtr[stride] + 2*piSrcPtr[0] + piSrcPtr[1] + 2 ) >> 2; + } + piDestPtr += 1; + piSrcPtr += 1; + + //------------------------------------------------ + + //top row (left-to-right) + + if (useStrongIntraSmoothing) + { + const Int shift = g_aucConvertToBit[uiTuWidth] + 3; //log2(uiTuWidth2) + + for(UInt i=1; i<uiTuWidth2; i++, piDestPtr++) + { + *piDestPtr = (((uiTuWidth2 - i) * topLeft) + (i * topRight) + uiTuWidth) >> shift; + } + + piSrcPtr += uiTuWidth2 - 1; + } + else + { + for(UInt i=1; i<uiTuWidth2; i++, piDestPtr++, piSrcPtr++) + { + *piDestPtr = ( piSrcPtr[1] + 2*piSrcPtr[0] + piSrcPtr[-1] + 2 ) >> 2; + } + } + + //------------------------------------------------ + + *piDestPtr=*piSrcPtr; // far right is not filtered + +#ifdef DEBUG_STRING + if (DebugOptionList::DebugString_Pred.getInt()&DebugStringGetPredModeMask(MODE_INTRA)) + { + ss << "###: filtered result for channel " << compID <<"\n"; + for (UInt y=0; y<uiROIHeight; y++) + { + ss << "###: - "; + for (UInt x=0; x<uiROIWidth; x++) + { + if (x==0 || y==0) + ss << m_piYuvExt[compID][PRED_BUF_FILTERED][y*uiROIWidth + x] << ", "; +// if (x%16==15) ss << "\nPart size: ~ "; + } + ss << "\n"; + } + } +#endif + + + } + } + DEBUG_STRING_APPEND(sDebug, ss.str()) +} + +#if O0043_BEST_EFFORT_DECODING +Void fillReferenceSamples( const Int bitDepth, const Int bitDepthDelta, TComDataCU* pcCU, const Pel* piRoiOrigin, Pel* piAdiTemp, const Bool* bNeighborFlags, +#else +Void fillReferenceSamples( const Int bitDepth, TComDataCU* pcCU, const Pel* piRoiOrigin, Pel* piAdiTemp, const Bool* bNeighborFlags, +#endif + const Int iNumIntraNeighbor, const Int unitWidth, const Int unitHeight, const Int iAboveUnits, const Int iLeftUnits, + const UInt uiCuWidth, const UInt uiCuHeight, const UInt uiWidth, const UInt uiHeight, const Int iPicStride, + const ChannelType chType, const ChromaFormat chFmt ) +{ + const Pel* piRoiTemp; + Int i, j; + Int iDCValue = 1 << (bitDepth - 1); + const Int iTotalUnits = iAboveUnits + iLeftUnits + 1; //+1 for top-left + + if (iNumIntraNeighbor == 0) + { + // Fill border with DC value + for (i=0; i<uiWidth; i++) + { + piAdiTemp[i] = iDCValue; + } + for (i=1; i<uiHeight; i++) + { + piAdiTemp[i*uiWidth] = iDCValue; + } + } + else if (iNumIntraNeighbor == iTotalUnits) + { + // Fill top-left border and top and top right with rec. samples + piRoiTemp = piRoiOrigin - iPicStride - 1; + + for (i=0; i<uiWidth; i++) + { +#if O0043_BEST_EFFORT_DECODING + piAdiTemp[i] = piRoiTemp[i] << bitDepthDelta; +#else + piAdiTemp[i] = piRoiTemp[i]; +#endif + } + + // Fill left and below left border with rec. samples + piRoiTemp = piRoiOrigin - 1; + + for (i=1; i<uiHeight; i++) + { +#if O0043_BEST_EFFORT_DECODING + piAdiTemp[i*uiWidth] = (*(piRoiTemp)) << bitDepthDelta; +#else + piAdiTemp[i*uiWidth] = *(piRoiTemp); +#endif + piRoiTemp += iPicStride; + } + } + else // reference samples are partially available + { + // all above units have "unitWidth" samples each, all left/below-left units have "unitHeight" samples each + const Int iTotalSamples = (iLeftUnits * unitHeight) + ((iAboveUnits + 1) * unitWidth); + Pel piAdiLine[5 * MAX_CU_SIZE]; + Pel *piAdiLineTemp; + const Bool *pbNeighborFlags; + + + // Initialize + for (i=0; i<iTotalSamples; i++) + { + piAdiLine[i] = iDCValue; + } + + // Fill top-left sample + piRoiTemp = piRoiOrigin - iPicStride - 1; + piAdiLineTemp = piAdiLine + (iLeftUnits * unitHeight); + pbNeighborFlags = bNeighborFlags + iLeftUnits; + if (*pbNeighborFlags) + { +#if O0043_BEST_EFFORT_DECODING + Pel topLeftVal=piRoiTemp[0] << bitDepthDelta; +#else + Pel topLeftVal=piRoiTemp[0]; +#endif + for (i=0; i<unitWidth; i++) + { + piAdiLineTemp[i] = topLeftVal; + } + } + + // Fill left & below-left samples (downwards) + piRoiTemp += iPicStride; + piAdiLineTemp--; + pbNeighborFlags--; + + for (j=0; j<iLeftUnits; j++) + { + if (*pbNeighborFlags) + { + for (i=0; i<unitHeight; i++) + { +#if O0043_BEST_EFFORT_DECODING + piAdiLineTemp[-i] = piRoiTemp[i*iPicStride] << bitDepthDelta; +#else + piAdiLineTemp[-i] = piRoiTemp[i*iPicStride]; +#endif + } + } + piRoiTemp += unitHeight*iPicStride; + piAdiLineTemp -= unitHeight; + pbNeighborFlags--; + } + + // Fill above & above-right samples (left-to-right) (each unit has "unitWidth" samples) + piRoiTemp = piRoiOrigin - iPicStride; + // offset line buffer by iNumUints2*unitHeight (for left/below-left) + unitWidth (for above-left) + piAdiLineTemp = piAdiLine + (iLeftUnits * unitHeight) + unitWidth; + pbNeighborFlags = bNeighborFlags + iLeftUnits + 1; + for (j=0; j<iAboveUnits; j++) + { + if (*pbNeighborFlags) + { + for (i=0; i<unitWidth; i++) + { +#if O0043_BEST_EFFORT_DECODING + piAdiLineTemp[i] = piRoiTemp[i] << bitDepthDelta; +#else + piAdiLineTemp[i] = piRoiTemp[i]; +#endif + } + } + piRoiTemp += unitWidth; + piAdiLineTemp += unitWidth; + pbNeighborFlags++; + } + + // Pad reference samples when necessary + Int iCurrJnit = 0; + Pel *piAdiLineCur = piAdiLine; + const UInt piAdiLineTopRowOffset = iLeftUnits * (unitHeight - unitWidth); + + if (!bNeighborFlags[0]) + { + // very bottom unit of bottom-left; at least one unit will be valid. + { + Int iNext = 1; + while (iNext < iTotalUnits && !bNeighborFlags[iNext]) + { + iNext++; + } + Pel *piAdiLineNext = piAdiLine + ((iNext < iLeftUnits) ? (iNext * unitHeight) : (piAdiLineTopRowOffset + (iNext * unitWidth))); + const Pel refSample = *piAdiLineNext; + // Pad unavailable samples with new value + Int iNextOrTop = std::min<Int>(iNext, iLeftUnits); + // fill left column + while (iCurrJnit < iNextOrTop) + { + for (i=0; i<unitHeight; i++) + { + piAdiLineCur[i] = refSample; + } + piAdiLineCur += unitHeight; + iCurrJnit++; + } + // fill top row + while (iCurrJnit < iNext) + { + for (i=0; i<unitWidth; i++) + { + piAdiLineCur[i] = refSample; + } + piAdiLineCur += unitWidth; + iCurrJnit++; + } + } + } + + // pad all other reference samples. + while (iCurrJnit < iTotalUnits) + { + if (!bNeighborFlags[iCurrJnit]) // samples not available + { + { + const Int numSamplesInCurrUnit = (iCurrJnit >= iLeftUnits) ? unitWidth : unitHeight; + const Pel refSample = *(piAdiLineCur-1); + for (i=0; i<numSamplesInCurrUnit; i++) + { + piAdiLineCur[i] = refSample; + } + piAdiLineCur += numSamplesInCurrUnit; + iCurrJnit++; + } + } + else + { + piAdiLineCur += (iCurrJnit >= iLeftUnits) ? unitWidth : unitHeight; + iCurrJnit++; + } + } + + // Copy processed samples + + piAdiLineTemp = piAdiLine + uiHeight + unitWidth - 2; + // top left, top and top right samples + for (i=0; i<uiWidth; i++) + { + piAdiTemp[i] = piAdiLineTemp[i]; + } + + piAdiLineTemp = piAdiLine + uiHeight - 1; + for (i=1; i<uiHeight; i++) + { + piAdiTemp[i*uiWidth] = piAdiLineTemp[-i]; + } + } +} + +/** Get pointer to reference samples for intra prediction + * \param uiDirMode prediction mode index + * \param log2BlkSize size of block (2 = 4x4, 3 = 8x8, 4 = 16x16, 5 = 32x32, 6 = 64x64) + * \param piAdiBuf pointer to unfiltered reference samples + * \return pointer to (possibly filtered) reference samples + * + * The prediction mode index is used to determine whether a smoothed reference sample buffer is returned. + */ + +Bool TComPrediction::filteringIntraReferenceSamples(const ComponentID compID, UInt uiDirMode, UInt uiTuChWidth, UInt uiTuChHeight, const ChromaFormat chFmt, const Bool intraReferenceSmoothingDisabled) +{ + Bool bFilter; + + if (!filterIntraReferenceSamples(toChannelType(compID), chFmt, intraReferenceSmoothingDisabled)) + { + bFilter=false; + } + else + { + assert(uiTuChWidth>=4 && uiTuChHeight>=4 && uiTuChWidth<128 && uiTuChHeight<128); + + if (uiDirMode == DC_IDX) + { + bFilter=false; //no smoothing for DC or LM chroma + } + else + { + Int diff = min<Int>(abs((Int) uiDirMode - HOR_IDX), abs((Int)uiDirMode - VER_IDX)); + UInt sizeIndex=g_aucConvertToBit[uiTuChWidth]; + assert(sizeIndex < MAX_INTRA_FILTER_DEPTHS); + bFilter = diff > m_aucIntraFilter[toChannelType(compID)][sizeIndex]; + } + } + return bFilter; +} + +Bool isAboveLeftAvailable( TComDataCU* pcCU, UInt uiPartIdxLT ) +{ + Bool bAboveLeftFlag; + UInt uiPartAboveLeft; + TComDataCU* pcCUAboveLeft = pcCU->getPUAboveLeft( uiPartAboveLeft, uiPartIdxLT ); + if(pcCU->getSlice()->getPPS()->getConstrainedIntraPred()) + { + bAboveLeftFlag = ( pcCUAboveLeft && pcCUAboveLeft->isIntra( uiPartAboveLeft ) ); + } + else + { + bAboveLeftFlag = (pcCUAboveLeft ? true : false); + } + return bAboveLeftFlag; +} + +Int isAboveAvailable( TComDataCU* pcCU, UInt uiPartIdxLT, UInt uiPartIdxRT, Bool *bValidFlags ) +{ + const UInt uiRasterPartBegin = g_auiZscanToRaster[uiPartIdxLT]; + const UInt uiRasterPartEnd = g_auiZscanToRaster[uiPartIdxRT]+1; + const UInt uiIdxStep = 1; + Bool *pbValidFlags = bValidFlags; + Int iNumIntra = 0; + + for ( UInt uiRasterPart = uiRasterPartBegin; uiRasterPart < uiRasterPartEnd; uiRasterPart += uiIdxStep ) + { + UInt uiPartAbove; + TComDataCU* pcCUAbove = pcCU->getPUAbove( uiPartAbove, g_auiRasterToZscan[uiRasterPart] ); + if(pcCU->getSlice()->getPPS()->getConstrainedIntraPred()) + { + if ( pcCUAbove && pcCUAbove->isIntra( uiPartAbove ) ) + { + iNumIntra++; + *pbValidFlags = true; + } + else + { + *pbValidFlags = false; + } + } + else + { + if (pcCUAbove) + { + iNumIntra++; + *pbValidFlags = true; + } + else + { + *pbValidFlags = false; + } + } + pbValidFlags++; + } + return iNumIntra; +} + +Int isLeftAvailable( TComDataCU* pcCU, UInt uiPartIdxLT, UInt uiPartIdxLB, Bool *bValidFlags ) +{ + const UInt uiRasterPartBegin = g_auiZscanToRaster[uiPartIdxLT]; + const UInt uiRasterPartEnd = g_auiZscanToRaster[uiPartIdxLB]+1; + const UInt uiIdxStep = pcCU->getPic()->getNumPartInCtuWidth(); + Bool *pbValidFlags = bValidFlags; + Int iNumIntra = 0; + + for ( UInt uiRasterPart = uiRasterPartBegin; uiRasterPart < uiRasterPartEnd; uiRasterPart += uiIdxStep ) + { + UInt uiPartLeft; + TComDataCU* pcCULeft = pcCU->getPULeft( uiPartLeft, g_auiRasterToZscan[uiRasterPart] ); + if(pcCU->getSlice()->getPPS()->getConstrainedIntraPred()) + { + if ( pcCULeft && pcCULeft->isIntra( uiPartLeft ) ) + { + iNumIntra++; + *pbValidFlags = true; + } + else + { + *pbValidFlags = false; + } + } + else + { + if ( pcCULeft ) + { + iNumIntra++; + *pbValidFlags = true; + } + else + { + *pbValidFlags = false; + } + } + pbValidFlags--; // opposite direction + } + + return iNumIntra; +} + +Int isAboveRightAvailable( TComDataCU* pcCU, UInt uiPartIdxLT, UInt uiPartIdxRT, Bool *bValidFlags ) +{ + const UInt uiNumUnitsInPU = g_auiZscanToRaster[uiPartIdxRT] - g_auiZscanToRaster[uiPartIdxLT] + 1; + Bool *pbValidFlags = bValidFlags; + Int iNumIntra = 0; + + for ( UInt uiOffset = 1; uiOffset <= uiNumUnitsInPU; uiOffset++ ) + { + UInt uiPartAboveRight; + TComDataCU* pcCUAboveRight = pcCU->getPUAboveRightAdi( uiPartAboveRight, uiPartIdxRT, uiOffset ); + if(pcCU->getSlice()->getPPS()->getConstrainedIntraPred()) + { + if ( pcCUAboveRight && pcCUAboveRight->isIntra( uiPartAboveRight ) ) + { + iNumIntra++; + *pbValidFlags = true; + } + else + { + *pbValidFlags = false; + } + } + else + { + if ( pcCUAboveRight ) + { + iNumIntra++; + *pbValidFlags = true; + } + else + { + *pbValidFlags = false; + } + } + pbValidFlags++; + } + + return iNumIntra; +} + +Int isBelowLeftAvailable( TComDataCU* pcCU, UInt uiPartIdxLT, UInt uiPartIdxLB, Bool *bValidFlags ) +{ + const UInt uiNumUnitsInPU = (g_auiZscanToRaster[uiPartIdxLB] - g_auiZscanToRaster[uiPartIdxLT]) / pcCU->getPic()->getNumPartInCtuWidth() + 1; + Bool *pbValidFlags = bValidFlags; + Int iNumIntra = 0; + + for ( UInt uiOffset = 1; uiOffset <= uiNumUnitsInPU; uiOffset++ ) + { + UInt uiPartBelowLeft; + TComDataCU* pcCUBelowLeft = pcCU->getPUBelowLeftAdi( uiPartBelowLeft, uiPartIdxLB, uiOffset ); + if(pcCU->getSlice()->getPPS()->getConstrainedIntraPred()) + { + if ( pcCUBelowLeft && pcCUBelowLeft->isIntra( uiPartBelowLeft ) ) + { + iNumIntra++; + *pbValidFlags = true; + } + else + { + *pbValidFlags = false; + } + } + else + { + if ( pcCUBelowLeft ) + { + iNumIntra++; + *pbValidFlags = true; + } + else + { + *pbValidFlags = false; + } + } + pbValidFlags--; // opposite direction + } + + return iNumIntra; +} +//! \}