source: SHVCSoftware/branches/SHM-dev/source/Lib/TLibCommon/TComPattern.cpp @ 1510

Last change on this file since 1510 was 1502, checked in by seregin, 9 years ago

infer parameters in SPS after activation, fixing chroma scaling for non 4:2:0

  • Property svn:eol-style set to native
File size: 23.9 KB
RevLine 
[313]1/* The copyright in this software is being made available under the BSD
2 * License, included below. This software may be subject to other third party
3 * and contributor rights, including patent rights, and no such rights are
[1029]4 * granted under this license.
[313]5 *
[1259]6 * Copyright (c) 2010-2015, ITU/ISO/IEC
[313]7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 *  * Redistributions of source code must retain the above copyright notice,
13 *    this list of conditions and the following disclaimer.
14 *  * Redistributions in binary form must reproduce the above copyright notice,
15 *    this list of conditions and the following disclaimer in the documentation
16 *    and/or other materials provided with the distribution.
17 *  * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
18 *    be used to endorse or promote products derived from this software without
19 *    specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31 * THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34/** \file     TComPattern.cpp
35    \brief    neighbouring pixel access classes
36*/
37
38#include "TComPic.h"
39#include "TComPattern.h"
40#include "TComDataCU.h"
[1029]41#include "TComTU.h"
42#include "Debug.h"
43#include "TComPrediction.h"
[313]44
45//! \ingroup TLibCommon
46//! \{
47
[1029]48// Forward declarations
[313]49
[1029]50/// padding of unavailable reference samples for intra prediction
[1307]51Void fillReferenceSamples( const Int bitDepth, 
[1029]52#if O0043_BEST_EFFORT_DECODING
[1307]53                           const Int bitDepthDelta, 
[1029]54#endif
[1307]55                           const Pel* piRoiOrigin, 
[1315]56                                 Pel* piIntraTemp,
[1307]57                           const Bool* bNeighborFlags,
58                           const Int iNumIntraNeighbor, 
59                           const Int unitWidth, 
60                           const Int unitHeight, 
61                           const Int iAboveUnits, 
62                           const Int iLeftUnits,
63                           const UInt uiWidth, 
64                           const UInt uiHeight, 
65                           const Int iPicStride );
[313]66
[1029]67/// constrained intra prediction
[1465]68Bool  isAboveLeftAvailable  ( const TComDataCU* pcCU, UInt uiPartIdxLT );
69Int   isAboveAvailable      ( const TComDataCU* pcCU, UInt uiPartIdxLT, UInt uiPartIdxRT, Bool* bValidFlags );
70Int   isLeftAvailable       ( const TComDataCU* pcCU, UInt uiPartIdxLT, UInt uiPartIdxLB, Bool* bValidFlags );
71Int   isAboveRightAvailable ( const TComDataCU* pcCU, UInt uiPartIdxLT, UInt uiPartIdxRT, Bool* bValidFlags );
72Int   isBelowLeftAvailable  ( const TComDataCU* pcCU, UInt uiPartIdxLT, UInt uiPartIdxLB, Bool* bValidFlags );
[1029]73
74
[313]75// ====================================================================================================================
76// Public member functions (TComPatternParam)
77// ====================================================================================================================
78
[1260]79/**
80 \param  piTexture     pixel data
[313]81 \param  iRoiWidth     pattern width
82 \param  iRoiHeight    pattern height
83 \param  iStride       buffer stride
[1305]84 \param  bitDepth      bit depth
[313]85 */
86Void TComPatternParam::setPatternParamPel ( Pel* piTexture,
87                                           Int iRoiWidth,
88                                           Int iRoiHeight,
[1287]89                                           Int iStride,
90                                           Int bitDepth
[1029]91                                           )
[313]92{
[1029]93  m_piROIOrigin    = piTexture;
[1287]94  m_iROIWidth      = iRoiWidth;
95  m_iROIHeight     = iRoiHeight;
96  m_iPatternStride = iStride;
97  m_bitDepth       = bitDepth;
[313]98}
99
100// ====================================================================================================================
101// Public member functions (TComPattern)
102// ====================================================================================================================
103
[1029]104Void TComPattern::initPattern (Pel* piY,
[313]105                               Int iRoiWidth,
106                               Int iRoiHeight,
[1287]107                               Int iStride,
108                               Int bitDepthLuma)
[313]109{
[1287]110  m_cPatternY. setPatternParamPel( piY,  iRoiWidth, iRoiHeight, iStride, bitDepthLuma);
[313]111}
112
[1029]113
114// TODO: move this function to TComPrediction.cpp.
[1368]115Void TComPrediction::initIntraPatternChType( TComTU &rTu, const ComponentID compID, const Bool bFilterRefSamples DEBUG_STRING_FN_DECLARE(sDebug))
[313]116{
[1029]117  const ChannelType chType    = toChannelType(compID);
[313]118
[1029]119  TComDataCU *pcCU=rTu.getCU();
[1289]120  const TComSPS &sps = *(pcCU->getSlice()->getSPS());
[1029]121  const UInt uiZorderIdxInPart=rTu.GetAbsPartIdxTU();
122  const UInt uiTuWidth        = rTu.getRect(compID).width;
123  const UInt uiTuHeight       = rTu.getRect(compID).height;
124  const UInt uiTuWidth2       = uiTuWidth  << 1;
125  const UInt uiTuHeight2      = uiTuHeight << 1;
126
[1290]127  const Int  iBaseUnitSize    = sps.getMaxCUWidth() >> sps.getMaxTotalCUDepth();
[1029]128  const Int  iUnitWidth       = iBaseUnitSize  >> pcCU->getPic()->getPicYuvRec()->getComponentScaleX(compID);
129  const Int  iUnitHeight      = iBaseUnitSize  >> pcCU->getPic()->getPicYuvRec()->getComponentScaleY(compID);
130  const Int  iTUWidthInUnits  = uiTuWidth  / iUnitWidth;
131  const Int  iTUHeightInUnits = uiTuHeight / iUnitHeight;
132  const Int  iAboveUnits      = iTUWidthInUnits  << 1;
133  const Int  iLeftUnits       = iTUHeightInUnits << 1;
[1289]134  const Int  bitDepthForChannel = sps.getBitDepth(chType);
[1029]135
136  assert(iTUHeightInUnits > 0 && iTUWidthInUnits > 0);
137
138  const Int  iPartIdxStride   = pcCU->getPic()->getNumPartInCtuWidth();
139  const UInt uiPartIdxLT      = pcCU->getZorderIdxInCtu() + uiZorderIdxInPart;
140  const UInt uiPartIdxRT      = g_auiRasterToZscan[ g_auiZscanToRaster[ uiPartIdxLT ] +   iTUWidthInUnits  - 1                   ];
141  const UInt uiPartIdxLB      = g_auiRasterToZscan[ g_auiZscanToRaster[ uiPartIdxLT ] + ((iTUHeightInUnits - 1) * iPartIdxStride)];
142
143  Int   iPicStride = pcCU->getPic()->getStride(compID);
[1335]144  Bool  bNeighborFlags[4 * MAX_NUM_PART_IDXS_IN_CTU_WIDTH + 1];
[313]145  Int   iNumIntraNeighbor = 0;
146
[1029]147  bNeighborFlags[iLeftUnits] = isAboveLeftAvailable( pcCU, uiPartIdxLT );
148  iNumIntraNeighbor += bNeighborFlags[iLeftUnits] ? 1 : 0;
149  iNumIntraNeighbor  += isAboveAvailable     ( pcCU, uiPartIdxLT, uiPartIdxRT, (bNeighborFlags + iLeftUnits + 1)                    );
150  iNumIntraNeighbor  += isAboveRightAvailable( pcCU, uiPartIdxLT, uiPartIdxRT, (bNeighborFlags + iLeftUnits + 1 + iTUWidthInUnits ) );
151  iNumIntraNeighbor  += isLeftAvailable      ( pcCU, uiPartIdxLT, uiPartIdxLB, (bNeighborFlags + iLeftUnits - 1)                    );
152  iNumIntraNeighbor  += isBelowLeftAvailable ( pcCU, uiPartIdxLT, uiPartIdxLB, (bNeighborFlags + iLeftUnits - 1 - iTUHeightInUnits) );
[313]153
[1029]154  const UInt         uiROIWidth  = uiTuWidth2+1;
155  const UInt         uiROIHeight = uiTuHeight2+1;
[313]156
[1029]157  assert(uiROIWidth*uiROIHeight <= m_iYuvExtSize);
[313]158
[1335]159#if DEBUG_STRING
[1029]160  std::stringstream ss(stringstream::out);
161#endif
[313]162
163  {
[1315]164    Pel *piIntraTemp   = m_piYuvExt[compID][PRED_BUF_UNFILTERED];
[1029]165    Pel *piRoiOrigin = pcCU->getPic()->getPicYuvRec()->getAddr(compID, pcCU->getCtuRsAddr(), pcCU->getZorderIdxInCtu()+uiZorderIdxInPart);
166#if O0043_BEST_EFFORT_DECODING
[1289]167    const Int  bitDepthForChannelInStream = sps.getStreamBitDepth(chType);
[1307]168    fillReferenceSamples (bitDepthForChannelInStream, bitDepthForChannelInStream - bitDepthForChannel,
[1029]169#else
[1307]170    fillReferenceSamples (bitDepthForChannel,
[1029]171#endif
[1315]172                          piRoiOrigin, piIntraTemp, bNeighborFlags, iNumIntraNeighbor,  iUnitWidth, iUnitHeight, iAboveUnits, iLeftUnits,
[1307]173                          uiROIWidth, uiROIHeight, iPicStride);
[313]174
[1029]175
[1335]176#if DEBUG_STRING
[1029]177    if (DebugOptionList::DebugString_Pred.getInt()&DebugStringGetPredModeMask(MODE_INTRA))
[313]178    {
[1029]179      ss << "###: generating Ref Samples for channel " << compID << " and " << rTu.getRect(compID).width << " x " << rTu.getRect(compID).height << "\n";
180      for (UInt y=0; y<uiROIHeight; y++)
[313]181      {
[1029]182        ss << "###: - ";
183        for (UInt x=0; x<uiROIWidth; x++)
184        {
185          if (x==0 || y==0)
[1246]186          {
[1315]187            ss << piIntraTemp[y*uiROIWidth + x] << ", ";
[1029]188//          if (x%16==15) ss << "\nPart size: ~ ";
[1246]189          }
[1029]190        }
191        ss << "\n";
[313]192      }
[1029]193    }
194#endif
195
196    if (bFilterRefSamples)
197    {
198      // generate filtered intra prediction samples
199
200            Int          stride    = uiROIWidth;
[1315]201      const Pel         *piSrcPtr  = piIntraTemp                           + (stride * uiTuHeight2); // bottom left
[1029]202            Pel         *piDestPtr = m_piYuvExt[compID][PRED_BUF_FILTERED] + (stride * uiTuHeight2); // bottom left
203
204      //------------------------------------------------
205
[1289]206      Bool useStrongIntraSmoothing = isLuma(chType) && sps.getUseStrongIntraSmoothing();
[1029]207
[1315]208      const Pel bottomLeft = piIntraTemp[stride * uiTuHeight2];
209      const Pel topLeft    = piIntraTemp[0];
210      const Pel topRight   = piIntraTemp[uiTuWidth2];
[1029]211
212      if (useStrongIntraSmoothing)
[313]213      {
[1029]214#if O0043_BEST_EFFORT_DECODING
[1287]215        const Int  threshold     = 1 << (bitDepthForChannelInStream - 5);
[1029]216#else
[1287]217        const Int  threshold     = 1 << (bitDepthForChannel - 5);
[1029]218#endif
[1315]219        const Bool bilinearLeft  = abs((bottomLeft + topLeft ) - (2 * piIntraTemp[stride * uiTuHeight])) < threshold; //difference between the
220        const Bool bilinearAbove = abs((topLeft    + topRight) - (2 * piIntraTemp[         uiTuWidth ])) < threshold; //ends and the middle
[1029]221        if ((uiTuWidth < 32) || (!bilinearLeft) || (!bilinearAbove))
[1246]222        {
[1029]223          useStrongIntraSmoothing = false;
[1246]224        }
[313]225      }
[1029]226
227      *piDestPtr = *piSrcPtr; // bottom left is not filtered
228      piDestPtr -= stride;
229      piSrcPtr  -= stride;
230
231      //------------------------------------------------
232
233      //left column (bottom to top)
234
235      if (useStrongIntraSmoothing)
236      {
237        const Int shift = g_aucConvertToBit[uiTuHeight] + 3; //log2(uiTuHeight2)
238
239        for(UInt i=1; i<uiTuHeight2; i++, piDestPtr-=stride)
240        {
241          *piDestPtr = (((uiTuHeight2 - i) * bottomLeft) + (i * topLeft) + uiTuHeight) >> shift;
242        }
243
244        piSrcPtr -= stride * (uiTuHeight2 - 1);
245      }
246      else
247      {
248        for(UInt i=1; i<uiTuHeight2; i++, piDestPtr-=stride, piSrcPtr-=stride)
249        {
250          *piDestPtr = ( piSrcPtr[stride] + 2*piSrcPtr[0] + piSrcPtr[-stride] + 2 ) >> 2;
251        }
252      }
253
254      //------------------------------------------------
255
256      //top-left
257
258      if (useStrongIntraSmoothing)
259      {
260        *piDestPtr = piSrcPtr[0];
261      }
262      else
263      {
264        *piDestPtr = ( piSrcPtr[stride] + 2*piSrcPtr[0] + piSrcPtr[1] + 2 ) >> 2;
265      }
266      piDestPtr += 1;
267      piSrcPtr  += 1;
268
269      //------------------------------------------------
270
271      //top row (left-to-right)
272
273      if (useStrongIntraSmoothing)
274      {
275        const Int shift = g_aucConvertToBit[uiTuWidth] + 3; //log2(uiTuWidth2)
276
277        for(UInt i=1; i<uiTuWidth2; i++, piDestPtr++)
278        {
279          *piDestPtr = (((uiTuWidth2 - i) * topLeft) + (i * topRight) + uiTuWidth) >> shift;
280        }
281
282        piSrcPtr += uiTuWidth2 - 1;
283      }
284      else
285      {
286        for(UInt i=1; i<uiTuWidth2; i++, piDestPtr++, piSrcPtr++)
287        {
288          *piDestPtr = ( piSrcPtr[1] + 2*piSrcPtr[0] + piSrcPtr[-1] + 2 ) >> 2;
289        }
290      }
291
292      //------------------------------------------------
293
294      *piDestPtr=*piSrcPtr; // far right is not filtered
295
[1335]296#if DEBUG_STRING
[1029]297    if (DebugOptionList::DebugString_Pred.getInt()&DebugStringGetPredModeMask(MODE_INTRA))
[313]298    {
[1029]299      ss << "###: filtered result for channel " << compID <<"\n";
300      for (UInt y=0; y<uiROIHeight; y++)
[313]301      {
[1029]302        ss << "###: - ";
303        for (UInt x=0; x<uiROIWidth; x++)
304        {
305          if (x==0 || y==0)
[1246]306          {
[1029]307            ss << m_piYuvExt[compID][PRED_BUF_FILTERED][y*uiROIWidth + x] << ", ";
308//          if (x%16==15) ss << "\nPart size: ~ ";
[1246]309          }
[1029]310        }
311        ss << "\n";
[313]312      }
313    }
[1029]314#endif
[313]315
316
[1029]317    }
[313]318  }
[1029]319  DEBUG_STRING_APPEND(sDebug, ss.str())
[313]320}
321
[1307]322Void fillReferenceSamples( const Int bitDepth, 
[1029]323#if O0043_BEST_EFFORT_DECODING
[1307]324                           const Int bitDepthDelta, 
[1029]325#endif
[1307]326                           const Pel* piRoiOrigin, 
[1315]327                                 Pel* piIntraTemp,
[1307]328                           const Bool* bNeighborFlags,
329                           const Int iNumIntraNeighbor, 
330                           const Int unitWidth, 
331                           const Int unitHeight, 
332                           const Int iAboveUnits, 
333                           const Int iLeftUnits,
334                           const UInt uiWidth, 
335                           const UInt uiHeight, 
336                           const Int iPicStride )
[313]337{
[1029]338  const Pel* piRoiTemp;
[313]339  Int  i, j;
340  Int  iDCValue = 1 << (bitDepth - 1);
[1029]341  const Int iTotalUnits = iAboveUnits + iLeftUnits + 1; //+1 for top-left
[313]342
343  if (iNumIntraNeighbor == 0)
344  {
345    // Fill border with DC value
346    for (i=0; i<uiWidth; i++)
347    {
[1315]348      piIntraTemp[i] = iDCValue;
[313]349    }
350    for (i=1; i<uiHeight; i++)
351    {
[1315]352      piIntraTemp[i*uiWidth] = iDCValue;
[313]353    }
354  }
355  else if (iNumIntraNeighbor == iTotalUnits)
356  {
[1029]357    // Fill top-left border and top and top right with rec. samples
[313]358    piRoiTemp = piRoiOrigin - iPicStride - 1;
359
[1029]360    for (i=0; i<uiWidth; i++)
[313]361    {
[1029]362#if O0043_BEST_EFFORT_DECODING
[1315]363      piIntraTemp[i] = piRoiTemp[i] << bitDepthDelta;
[1029]364#else
[1315]365      piIntraTemp[i] = piRoiTemp[i];
[1029]366#endif
[313]367    }
368
[1029]369    // Fill left and below left border with rec. samples
370    piRoiTemp = piRoiOrigin - 1;
[313]371
[1029]372    for (i=1; i<uiHeight; i++)
[313]373    {
[1029]374#if O0043_BEST_EFFORT_DECODING
[1315]375      piIntraTemp[i*uiWidth] = (*(piRoiTemp)) << bitDepthDelta;
[1029]376#else
[1315]377      piIntraTemp[i*uiWidth] = *(piRoiTemp);
[1029]378#endif
[313]379      piRoiTemp += iPicStride;
380    }
381  }
382  else // reference samples are partially available
383  {
[1029]384    // all above units have "unitWidth" samples each, all left/below-left units have "unitHeight" samples each
385    const Int  iTotalSamples = (iLeftUnits * unitHeight) + ((iAboveUnits + 1) * unitWidth);
[1315]386    Pel  piIntraLine[5 * MAX_CU_SIZE];
387    Pel  *piIntraLineTemp;
[1029]388    const Bool *pbNeighborFlags;
[313]389
[1029]390
[313]391    // Initialize
392    for (i=0; i<iTotalSamples; i++)
393    {
[1315]394      piIntraLine[i] = iDCValue;
[313]395    }
[1029]396
[313]397    // Fill top-left sample
398    piRoiTemp = piRoiOrigin - iPicStride - 1;
[1315]399    piIntraLineTemp = piIntraLine + (iLeftUnits * unitHeight);
[1029]400    pbNeighborFlags = bNeighborFlags + iLeftUnits;
[313]401    if (*pbNeighborFlags)
402    {
[1029]403#if O0043_BEST_EFFORT_DECODING
404      Pel topLeftVal=piRoiTemp[0] << bitDepthDelta;
405#else
406      Pel topLeftVal=piRoiTemp[0];
407#endif
408      for (i=0; i<unitWidth; i++)
[313]409      {
[1315]410        piIntraLineTemp[i] = topLeftVal;
[313]411      }
412    }
413
[1029]414    // Fill left & below-left samples (downwards)
[313]415    piRoiTemp += iPicStride;
[1315]416    piIntraLineTemp--;
[313]417    pbNeighborFlags--;
[1029]418
419    for (j=0; j<iLeftUnits; j++)
[313]420    {
421      if (*pbNeighborFlags)
422      {
[1029]423        for (i=0; i<unitHeight; i++)
[313]424        {
[1029]425#if O0043_BEST_EFFORT_DECODING
[1315]426          piIntraLineTemp[-i] = piRoiTemp[i*iPicStride] << bitDepthDelta;
[1029]427#else
[1315]428          piIntraLineTemp[-i] = piRoiTemp[i*iPicStride];
[1029]429#endif
[313]430        }
431      }
[1029]432      piRoiTemp += unitHeight*iPicStride;
[1315]433      piIntraLineTemp -= unitHeight;
[313]434      pbNeighborFlags--;
435    }
436
[1029]437    // Fill above & above-right samples (left-to-right) (each unit has "unitWidth" samples)
[313]438    piRoiTemp = piRoiOrigin - iPicStride;
[1029]439    // offset line buffer by iNumUints2*unitHeight (for left/below-left) + unitWidth (for above-left)
[1315]440    piIntraLineTemp = piIntraLine + (iLeftUnits * unitHeight) + unitWidth;
[1029]441    pbNeighborFlags = bNeighborFlags + iLeftUnits + 1;
442    for (j=0; j<iAboveUnits; j++)
[313]443    {
444      if (*pbNeighborFlags)
445      {
[1029]446        for (i=0; i<unitWidth; i++)
[313]447        {
[1029]448#if O0043_BEST_EFFORT_DECODING
[1315]449          piIntraLineTemp[i] = piRoiTemp[i] << bitDepthDelta;
[1029]450#else
[1315]451          piIntraLineTemp[i] = piRoiTemp[i];
[1029]452#endif
[313]453        }
454      }
[1029]455      piRoiTemp += unitWidth;
[1315]456      piIntraLineTemp += unitWidth;
[313]457      pbNeighborFlags++;
458    }
459
460    // Pad reference samples when necessary
[1029]461    Int iCurrJnit = 0;
[1315]462    Pel  *piIntraLineCur   = piIntraLine;
463    const UInt piIntraLineTopRowOffset = iLeftUnits * (unitHeight - unitWidth);
[1029]464
465    if (!bNeighborFlags[0])
[313]466    {
[1029]467      // very bottom unit of bottom-left; at least one unit will be valid.
[313]468      {
[1029]469        Int   iNext = 1;
470        while (iNext < iTotalUnits && !bNeighborFlags[iNext])
[313]471        {
[1029]472          iNext++;
473        }
[1315]474        Pel *piIntraLineNext = piIntraLine + ((iNext < iLeftUnits) ? (iNext * unitHeight) : (piIntraLineTopRowOffset + (iNext * unitWidth)));
475        const Pel refSample = *piIntraLineNext;
[1029]476        // Pad unavailable samples with new value
477        Int iNextOrTop = std::min<Int>(iNext, iLeftUnits);
478        // fill left column
479        while (iCurrJnit < iNextOrTop)
480        {
481          for (i=0; i<unitHeight; i++)
[313]482          {
[1315]483            piIntraLineCur[i] = refSample;
[313]484          }
[1315]485          piIntraLineCur += unitHeight;
[1029]486          iCurrJnit++;
487        }
488        // fill top row
489        while (iCurrJnit < iNext)
490        {
491          for (i=0; i<unitWidth; i++)
[313]492          {
[1315]493            piIntraLineCur[i] = refSample;
[313]494          }
[1315]495          piIntraLineCur += unitWidth;
[1029]496          iCurrJnit++;
[313]497        }
[1029]498      }
499    }
500
501    // pad all other reference samples.
502    while (iCurrJnit < iTotalUnits)
503    {
504      if (!bNeighborFlags[iCurrJnit]) // samples not available
505      {
[313]506        {
[1029]507          const Int numSamplesInCurrUnit = (iCurrJnit >= iLeftUnits) ? unitWidth : unitHeight;
[1315]508          const Pel refSample = *(piIntraLineCur-1);
[1029]509          for (i=0; i<numSamplesInCurrUnit; i++)
[313]510          {
[1315]511            piIntraLineCur[i] = refSample;
[313]512          }
[1315]513          piIntraLineCur += numSamplesInCurrUnit;
[1029]514          iCurrJnit++;
[313]515        }
516      }
517      else
518      {
[1315]519        piIntraLineCur += (iCurrJnit >= iLeftUnits) ? unitWidth : unitHeight;
[1029]520        iCurrJnit++;
[313]521      }
522    }
523
524    // Copy processed samples
[1029]525
[1315]526    piIntraLineTemp = piIntraLine + uiHeight + unitWidth - 2;
[1029]527    // top left, top and top right samples
[313]528    for (i=0; i<uiWidth; i++)
529    {
[1315]530      piIntraTemp[i] = piIntraLineTemp[i];
[313]531    }
[1029]532
[1315]533    piIntraLineTemp = piIntraLine + uiHeight - 1;
[313]534    for (i=1; i<uiHeight; i++)
535    {
[1315]536      piIntraTemp[i*uiWidth] = piIntraLineTemp[-i];
[313]537    }
538  }
539}
540
[1029]541Bool TComPrediction::filteringIntraReferenceSamples(const ComponentID compID, UInt uiDirMode, UInt uiTuChWidth, UInt uiTuChHeight, const ChromaFormat chFmt, const Bool intraReferenceSmoothingDisabled)
[313]542{
[1029]543  Bool bFilter;
544
545  if (!filterIntraReferenceSamples(toChannelType(compID), chFmt, intraReferenceSmoothingDisabled))
[313]546  {
[1029]547    bFilter=false;
[313]548  }
[1029]549  else
550  {
551    assert(uiTuChWidth>=4 && uiTuChHeight>=4 && uiTuChWidth<128 && uiTuChHeight<128);
[313]552
[1029]553    if (uiDirMode == DC_IDX)
554    {
555      bFilter=false; //no smoothing for DC or LM chroma
556    }
557    else
558    {
559      Int diff = min<Int>(abs((Int) uiDirMode - HOR_IDX), abs((Int)uiDirMode - VER_IDX));
560      UInt sizeIndex=g_aucConvertToBit[uiTuChWidth];
561      assert(sizeIndex < MAX_INTRA_FILTER_DEPTHS);
562      bFilter = diff > m_aucIntraFilter[toChannelType(compID)][sizeIndex];
563    }
[313]564  }
[1029]565  return bFilter;
[313]566}
567
[1465]568Bool isAboveLeftAvailable( const TComDataCU* pcCU, UInt uiPartIdxLT )
[313]569{
570  Bool bAboveLeftFlag;
571  UInt uiPartAboveLeft;
[1465]572  const TComDataCU* pcCUAboveLeft = pcCU->getPUAboveLeft( uiPartAboveLeft, uiPartIdxLT );
[313]573  if(pcCU->getSlice()->getPPS()->getConstrainedIntraPred())
574  {
[1029]575    bAboveLeftFlag = ( pcCUAboveLeft && pcCUAboveLeft->isIntra( uiPartAboveLeft ) );
[313]576  }
577  else
578  {
579    bAboveLeftFlag = (pcCUAboveLeft ? true : false);
580  }
581  return bAboveLeftFlag;
582}
583
[1465]584Int isAboveAvailable( const TComDataCU* pcCU, UInt uiPartIdxLT, UInt uiPartIdxRT, Bool *bValidFlags )
[313]585{
586  const UInt uiRasterPartBegin = g_auiZscanToRaster[uiPartIdxLT];
587  const UInt uiRasterPartEnd = g_auiZscanToRaster[uiPartIdxRT]+1;
588  const UInt uiIdxStep = 1;
589  Bool *pbValidFlags = bValidFlags;
590  Int iNumIntra = 0;
591
592  for ( UInt uiRasterPart = uiRasterPartBegin; uiRasterPart < uiRasterPartEnd; uiRasterPart += uiIdxStep )
593  {
594    UInt uiPartAbove;
[1465]595    const TComDataCU* pcCUAbove = pcCU->getPUAbove( uiPartAbove, g_auiRasterToZscan[uiRasterPart] );
[313]596    if(pcCU->getSlice()->getPPS()->getConstrainedIntraPred())
597    {
[1029]598      if ( pcCUAbove && pcCUAbove->isIntra( uiPartAbove ) )
[313]599      {
600        iNumIntra++;
601        *pbValidFlags = true;
602      }
603      else
604      {
605        *pbValidFlags = false;
606      }
607    }
608    else
609    {
610      if (pcCUAbove)
611      {
612        iNumIntra++;
613        *pbValidFlags = true;
614      }
615      else
616      {
617        *pbValidFlags = false;
618      }
619    }
620    pbValidFlags++;
621  }
622  return iNumIntra;
623}
624
[1465]625Int isLeftAvailable( const TComDataCU* pcCU, UInt uiPartIdxLT, UInt uiPartIdxLB, Bool *bValidFlags )
[313]626{
627  const UInt uiRasterPartBegin = g_auiZscanToRaster[uiPartIdxLT];
628  const UInt uiRasterPartEnd = g_auiZscanToRaster[uiPartIdxLB]+1;
[1029]629  const UInt uiIdxStep = pcCU->getPic()->getNumPartInCtuWidth();
[313]630  Bool *pbValidFlags = bValidFlags;
631  Int iNumIntra = 0;
632
633  for ( UInt uiRasterPart = uiRasterPartBegin; uiRasterPart < uiRasterPartEnd; uiRasterPart += uiIdxStep )
634  {
635    UInt uiPartLeft;
[1465]636    const TComDataCU* pcCULeft = pcCU->getPULeft( uiPartLeft, g_auiRasterToZscan[uiRasterPart] );
[313]637    if(pcCU->getSlice()->getPPS()->getConstrainedIntraPred())
638    {
[1029]639      if ( pcCULeft && pcCULeft->isIntra( uiPartLeft ) )
[313]640      {
641        iNumIntra++;
642        *pbValidFlags = true;
643      }
644      else
645      {
646        *pbValidFlags = false;
647      }
648    }
649    else
650    {
651      if ( pcCULeft )
652      {
653        iNumIntra++;
654        *pbValidFlags = true;
655      }
656      else
657      {
658        *pbValidFlags = false;
659      }
660    }
661    pbValidFlags--; // opposite direction
662  }
663
664  return iNumIntra;
665}
666
[1465]667Int isAboveRightAvailable( const TComDataCU* pcCU, UInt uiPartIdxLT, UInt uiPartIdxRT, Bool *bValidFlags )
[313]668{
669  const UInt uiNumUnitsInPU = g_auiZscanToRaster[uiPartIdxRT] - g_auiZscanToRaster[uiPartIdxLT] + 1;
670  Bool *pbValidFlags = bValidFlags;
671  Int iNumIntra = 0;
672
673  for ( UInt uiOffset = 1; uiOffset <= uiNumUnitsInPU; uiOffset++ )
674  {
675    UInt uiPartAboveRight;
[1465]676    const TComDataCU* pcCUAboveRight = pcCU->getPUAboveRight( uiPartAboveRight, uiPartIdxRT, uiOffset );
[313]677    if(pcCU->getSlice()->getPPS()->getConstrainedIntraPred())
678    {
[1029]679      if ( pcCUAboveRight && pcCUAboveRight->isIntra( uiPartAboveRight ) )
[313]680      {
681        iNumIntra++;
682        *pbValidFlags = true;
683      }
684      else
685      {
686        *pbValidFlags = false;
687      }
688    }
689    else
690    {
691      if ( pcCUAboveRight )
692      {
693        iNumIntra++;
694        *pbValidFlags = true;
695      }
696      else
697      {
698        *pbValidFlags = false;
699      }
700    }
701    pbValidFlags++;
702  }
703
704  return iNumIntra;
705}
706
[1465]707Int isBelowLeftAvailable( const TComDataCU* pcCU, UInt uiPartIdxLT, UInt uiPartIdxLB, Bool *bValidFlags )
[313]708{
[1029]709  const UInt uiNumUnitsInPU = (g_auiZscanToRaster[uiPartIdxLB] - g_auiZscanToRaster[uiPartIdxLT]) / pcCU->getPic()->getNumPartInCtuWidth() + 1;
[313]710  Bool *pbValidFlags = bValidFlags;
711  Int iNumIntra = 0;
712
713  for ( UInt uiOffset = 1; uiOffset <= uiNumUnitsInPU; uiOffset++ )
714  {
715    UInt uiPartBelowLeft;
[1465]716    const TComDataCU* pcCUBelowLeft = pcCU->getPUBelowLeft( uiPartBelowLeft, uiPartIdxLB, uiOffset );
[313]717    if(pcCU->getSlice()->getPPS()->getConstrainedIntraPred())
718    {
[1029]719      if ( pcCUBelowLeft && pcCUBelowLeft->isIntra( uiPartBelowLeft ) )
[313]720      {
721        iNumIntra++;
722        *pbValidFlags = true;
723      }
724      else
725      {
726        *pbValidFlags = false;
727      }
728    }
729    else
730    {
731      if ( pcCUBelowLeft )
732      {
733        iNumIntra++;
734        *pbValidFlags = true;
735      }
736      else
737      {
738        *pbValidFlags = false;
739      }
740    }
741    pbValidFlags--; // opposite direction
742  }
743
744  return iNumIntra;
745}
746//! \}
Note: See TracBrowser for help on using the repository browser.