source: SHVCSoftware/trunk/source/Lib/TLibCommon/TComPattern.cpp @ 842

Last change on this file since 842 was 595, checked in by seregin, 11 years ago

merge with SHM-5.0-dev branch

  • Property svn:eol-style set to native
File size: 25.1 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
4 * granted under this license. 
5 *
[595]6 * Copyright (c) 2010-2014, 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"
41
42//! \ingroup TLibCommon
43//! \{
44
45// ====================================================================================================================
46// Tables
47// ====================================================================================================================
48
49const UChar TComPattern::m_aucIntraFilter[5] =
50{
51  10, //4x4
52  7, //8x8
53  1, //16x16
54  0, //32x32
55  10, //64x64
56};
57
58// ====================================================================================================================
59// Public member functions (TComPatternParam)
60// ====================================================================================================================
61
62/** \param  piTexture     pixel data
63 \param  iRoiWidth     pattern width
64 \param  iRoiHeight    pattern height
65 \param  iStride       buffer stride
66 \param  iOffsetLeft   neighbour offset (left)
67 \param  iOffsetAbove  neighbour offset (above)
68 */
69Void TComPatternParam::setPatternParamPel ( Pel* piTexture,
70                                           Int iRoiWidth,
71                                           Int iRoiHeight,
72                                           Int iStride,
73                                           Int iOffsetLeft,
74                                           Int iOffsetAbove )
75{
76  m_piPatternOrigin = piTexture;
77  m_iROIWidth       = iRoiWidth;
78  m_iROIHeight      = iRoiHeight;
79  m_iPatternStride  = iStride;
80  m_iOffsetLeft     = iOffsetLeft;
81  m_iOffsetAbove    = iOffsetAbove;
82}
83
84/**
85 \param  pcCU          CU data structure
86 \param  iComp         component index (0=Y, 1=Cb, 2=Cr)
87 \param  iRoiWidth     pattern width
88 \param  iRoiHeight    pattern height
89 \param  iStride       buffer stride
90 \param  iOffsetLeft   neighbour offset (left)
91 \param  iOffsetAbove  neighbour offset (above)
92 \param  uiAbsPartIdx  part index
93 */
94Void TComPatternParam::setPatternParamCU( TComDataCU* pcCU,
95                                         UChar       iComp,
96                                         UChar       iRoiWidth,
97                                         UChar       iRoiHeight,
98                                         Int         iOffsetLeft,
99                                         Int         iOffsetAbove,
100                                         UInt        uiAbsPartIdx )
101{
102  m_iOffsetLeft   = iOffsetLeft;
103  m_iOffsetAbove  = iOffsetAbove;
104 
105  m_iROIWidth     = iRoiWidth;
106  m_iROIHeight    = iRoiHeight;
107 
108  UInt uiAbsZorderIdx = pcCU->getZorderIdxInCU() + uiAbsPartIdx;
109 
110  if ( iComp == 0 )
111  {
112    m_iPatternStride  = pcCU->getPic()->getStride();
113    m_piPatternOrigin = pcCU->getPic()->getPicYuvRec()->getLumaAddr(pcCU->getAddr(), uiAbsZorderIdx) - m_iOffsetAbove * m_iPatternStride - m_iOffsetLeft;
114  }
115  else
116  {
117    m_iPatternStride = pcCU->getPic()->getCStride();
118    if ( iComp == 1 )
119    {
120      m_piPatternOrigin = pcCU->getPic()->getPicYuvRec()->getCbAddr(pcCU->getAddr(), uiAbsZorderIdx) - m_iOffsetAbove * m_iPatternStride - m_iOffsetLeft;
121    }
122    else
123    {
124      m_piPatternOrigin = pcCU->getPic()->getPicYuvRec()->getCrAddr(pcCU->getAddr(), uiAbsZorderIdx) - m_iOffsetAbove * m_iPatternStride - m_iOffsetLeft;
125    }
126  }
127}
128
129// ====================================================================================================================
130// Public member functions (TComPattern)
131// ====================================================================================================================
132
133Void TComPattern::initPattern ( Pel* piY,
134                               Pel* piCb,
135                               Pel* piCr,
136                               Int iRoiWidth,
137                               Int iRoiHeight,
138                               Int iStride,
139                               Int iOffsetLeft,
140                               Int iOffsetAbove )
141{
142  m_cPatternY. setPatternParamPel( piY,  iRoiWidth,      iRoiHeight,      iStride,      iOffsetLeft,      iOffsetAbove      );
143  m_cPatternCb.setPatternParamPel( piCb, iRoiWidth >> 1, iRoiHeight >> 1, iStride >> 1, iOffsetLeft >> 1, iOffsetAbove >> 1 );
144  m_cPatternCr.setPatternParamPel( piCr, iRoiWidth >> 1, iRoiHeight >> 1, iStride >> 1, iOffsetLeft >> 1, iOffsetAbove >> 1 );
145 
146  return;
147}
148
149Void TComPattern::initPattern( TComDataCU* pcCU, UInt uiPartDepth, UInt uiAbsPartIdx )
150{
151  Int   uiOffsetLeft  = 0;
152  Int   uiOffsetAbove = 0;
153 
154  UChar uiWidth          = pcCU->getWidth (0)>>uiPartDepth;
155  UChar uiHeight         = pcCU->getHeight(0)>>uiPartDepth;
156 
157  UInt  uiAbsZorderIdx   = pcCU->getZorderIdxInCU() + uiAbsPartIdx;
158  UInt  uiCurrPicPelX    = pcCU->getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[uiAbsZorderIdx] ];
159  UInt  uiCurrPicPelY    = pcCU->getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[uiAbsZorderIdx] ];
160 
161  if( uiCurrPicPelX != 0 )
162  {
163    uiOffsetLeft = 1;
164  }
165 
166  if( uiCurrPicPelY != 0 )
167  {
168    uiOffsetAbove = 1;
169  }
170 
171  m_cPatternY .setPatternParamCU( pcCU, 0, uiWidth,      uiHeight,      uiOffsetLeft, uiOffsetAbove, uiAbsPartIdx );
172  m_cPatternCb.setPatternParamCU( pcCU, 1, uiWidth >> 1, uiHeight >> 1, uiOffsetLeft, uiOffsetAbove, uiAbsPartIdx );
173  m_cPatternCr.setPatternParamCU( pcCU, 2, uiWidth >> 1, uiHeight >> 1, uiOffsetLeft, uiOffsetAbove, uiAbsPartIdx );
174}
175
176Void TComPattern::initAdiPattern( TComDataCU* pcCU, UInt uiZorderIdxInPart, UInt uiPartDepth, Int* piAdiBuf, Int iOrgBufStride, Int iOrgBufHeight, Bool& bAbove, Bool& bLeft, Bool bLMmode )
177{
178  Pel*  piRoiOrigin;
179  Int*  piAdiTemp;
180  UInt  uiCuWidth   = pcCU->getWidth(0) >> uiPartDepth;
181  UInt  uiCuHeight  = pcCU->getHeight(0)>> uiPartDepth;
182  UInt  uiCuWidth2  = uiCuWidth<<1;
183  UInt  uiCuHeight2 = uiCuHeight<<1;
184  UInt  uiWidth;
185  UInt  uiHeight;
186  Int   iPicStride = pcCU->getPic()->getStride();
187  Int   iUnitSize = 0;
188  Int   iNumUnitsInCu = 0;
189  Int   iTotalUnits = 0;
190  Bool  bNeighborFlags[4 * MAX_NUM_SPU_W + 1];
191  Int   iNumIntraNeighbor = 0;
192 
193  UInt uiPartIdxLT, uiPartIdxRT, uiPartIdxLB;
194
195 
196  pcCU->deriveLeftRightTopIdxAdi( uiPartIdxLT, uiPartIdxRT, uiZorderIdxInPart, uiPartDepth );
197  pcCU->deriveLeftBottomIdxAdi  ( uiPartIdxLB,              uiZorderIdxInPart, uiPartDepth );
198 
199  iUnitSize      = g_uiMaxCUWidth >> g_uiMaxCUDepth;
200  iNumUnitsInCu  = uiCuWidth / iUnitSize;
201  iTotalUnits    = (iNumUnitsInCu << 2) + 1;
202
203  bNeighborFlags[iNumUnitsInCu*2] = isAboveLeftAvailable( pcCU, uiPartIdxLT );
204  iNumIntraNeighbor  += (Int)(bNeighborFlags[iNumUnitsInCu*2]);
205  iNumIntraNeighbor  += isAboveAvailable     ( pcCU, uiPartIdxLT, uiPartIdxRT, bNeighborFlags+(iNumUnitsInCu*2)+1 );
206  iNumIntraNeighbor  += isAboveRightAvailable( pcCU, uiPartIdxLT, uiPartIdxRT, bNeighborFlags+(iNumUnitsInCu*3)+1 );
207  iNumIntraNeighbor  += isLeftAvailable      ( pcCU, uiPartIdxLT, uiPartIdxLB, bNeighborFlags+(iNumUnitsInCu*2)-1 );
208  iNumIntraNeighbor  += isBelowLeftAvailable ( pcCU, uiPartIdxLT, uiPartIdxLB, bNeighborFlags+ iNumUnitsInCu   -1 );
209 
210  bAbove = true;
211  bLeft  = true;
212
213  uiWidth=uiCuWidth2+1;
214  uiHeight=uiCuHeight2+1;
215 
216  if (((uiWidth<<2)>iOrgBufStride)||((uiHeight<<2)>iOrgBufHeight))
217  {
218    return;
219  }
220 
221  piRoiOrigin = pcCU->getPic()->getPicYuvRec()->getLumaAddr(pcCU->getAddr(), pcCU->getZorderIdxInCU()+uiZorderIdxInPart);
222  piAdiTemp   = piAdiBuf;
223
224  fillReferenceSamples (g_bitDepthY, piRoiOrigin, piAdiTemp, bNeighborFlags, iNumIntraNeighbor, iUnitSize, iNumUnitsInCu, iTotalUnits, uiCuWidth, uiCuHeight, uiWidth, uiHeight, iPicStride, bLMmode);
225 
226  Int   i;
227  // generate filtered intra prediction samples
228  Int iBufSize = uiCuHeight2 + uiCuWidth2 + 1;  // left and left above border + above and above right border + top left corner = length of 3. filter buffer
229
230  UInt uiWH = uiWidth * uiHeight;               // number of elements in one buffer
231
232  Int* piFilteredBuf1 = piAdiBuf + uiWH;        // 1. filter buffer
233  Int* piFilteredBuf2 = piFilteredBuf1 + uiWH;  // 2. filter buffer
234  Int* piFilterBuf = piFilteredBuf2 + uiWH;     // buffer for 2. filtering (sequential)
235  Int* piFilterBufN = piFilterBuf + iBufSize;   // buffer for 1. filtering (sequential)
236
237  Int l = 0;
238  // left border from bottom to top
239  for (i = 0; i < uiCuHeight2; i++)
240  {
241    piFilterBuf[l++] = piAdiTemp[uiWidth * (uiCuHeight2 - i)];
242  }
243  // top left corner
244  piFilterBuf[l++] = piAdiTemp[0];
245  // above border from left to right
246  for (i=0; i < uiCuWidth2; i++)
247  {
248    piFilterBuf[l++] = piAdiTemp[1 + i];
249  }
250
251  if (pcCU->getSlice()->getSPS()->getUseStrongIntraSmoothing())
252  {
253    Int blkSize = 32;
254    Int bottomLeft = piFilterBuf[0];
255    Int topLeft = piFilterBuf[uiCuHeight2];
256    Int topRight = piFilterBuf[iBufSize-1];
257    Int threshold = 1 << (g_bitDepthY - 5);
258    Bool bilinearLeft = abs(bottomLeft+topLeft-2*piFilterBuf[uiCuHeight]) < threshold;
259    Bool bilinearAbove  = abs(topLeft+topRight-2*piFilterBuf[uiCuHeight2+uiCuHeight]) < threshold;
260 
261    if (uiCuWidth>=blkSize && (bilinearLeft && bilinearAbove))
262    {
263      Int shift = g_aucConvertToBit[uiCuWidth] + 3;  // log2(uiCuHeight2)
264      piFilterBufN[0] = piFilterBuf[0];
265      piFilterBufN[uiCuHeight2] = piFilterBuf[uiCuHeight2];
266      piFilterBufN[iBufSize - 1] = piFilterBuf[iBufSize - 1];
267      for (i = 1; i < uiCuHeight2; i++)
268      {
269        piFilterBufN[i] = ((uiCuHeight2-i)*bottomLeft + i*topLeft + uiCuHeight) >> shift;
270      }
271 
272      for (i = 1; i < uiCuWidth2; i++)
273      {
274        piFilterBufN[uiCuHeight2 + i] = ((uiCuWidth2-i)*topLeft + i*topRight + uiCuWidth) >> shift;
275      }
276    }
277    else 
278    {
279      // 1. filtering with [1 2 1]
280      piFilterBufN[0] = piFilterBuf[0];
281      piFilterBufN[iBufSize - 1] = piFilterBuf[iBufSize - 1];
282      for (i = 1; i < iBufSize - 1; i++)
283      {
284        piFilterBufN[i] = (piFilterBuf[i - 1] + 2 * piFilterBuf[i]+piFilterBuf[i + 1] + 2) >> 2;
285      }
286    }
287  }
288  else 
289  {
290    // 1. filtering with [1 2 1]
291    piFilterBufN[0] = piFilterBuf[0];
292    piFilterBufN[iBufSize - 1] = piFilterBuf[iBufSize - 1];
293    for (i = 1; i < iBufSize - 1; i++)
294    {
295      piFilterBufN[i] = (piFilterBuf[i - 1] + 2 * piFilterBuf[i]+piFilterBuf[i + 1] + 2) >> 2;
296    }
297  }
298
299  // fill 1. filter buffer with filtered values
300  l=0;
301  for (i = 0; i < uiCuHeight2; i++)
302  {
303    piFilteredBuf1[uiWidth * (uiCuHeight2 - i)] = piFilterBufN[l++];
304  }
305  piFilteredBuf1[0] = piFilterBufN[l++];
306  for (i = 0; i < uiCuWidth2; i++)
307  {
308    piFilteredBuf1[1 + i] = piFilterBufN[l++];
309  }
310}
311
312Void TComPattern::initAdiPatternChroma( TComDataCU* pcCU, UInt uiZorderIdxInPart, UInt uiPartDepth, Int* piAdiBuf, Int iOrgBufStride, Int iOrgBufHeight, Bool& bAbove, Bool& bLeft )
313{
314  Pel*  piRoiOrigin;
315  Int*  piAdiTemp;
316  UInt  uiCuWidth  = pcCU->getWidth (0) >> uiPartDepth;
317  UInt  uiCuHeight = pcCU->getHeight(0) >> uiPartDepth;
318  UInt  uiWidth;
319  UInt  uiHeight;
320  Int   iPicStride = pcCU->getPic()->getCStride();
321
322  Int   iUnitSize = 0;
323  Int   iNumUnitsInCu = 0;
324  Int   iTotalUnits = 0;
325  Bool  bNeighborFlags[4 * MAX_NUM_SPU_W + 1];
326  Int   iNumIntraNeighbor = 0;
327 
328  UInt uiPartIdxLT, uiPartIdxRT, uiPartIdxLB;
329 
330  pcCU->deriveLeftRightTopIdxAdi( uiPartIdxLT, uiPartIdxRT, uiZorderIdxInPart, uiPartDepth );
331  pcCU->deriveLeftBottomIdxAdi  ( uiPartIdxLB,              uiZorderIdxInPart, uiPartDepth );
332 
333  iUnitSize      = (g_uiMaxCUWidth >> g_uiMaxCUDepth) >> 1; // for chroma
334  iNumUnitsInCu  = (uiCuWidth / iUnitSize) >> 1;            // for chroma
335  iTotalUnits    = (iNumUnitsInCu << 2) + 1;
336
337  bNeighborFlags[iNumUnitsInCu*2] = isAboveLeftAvailable( pcCU, uiPartIdxLT );
338  iNumIntraNeighbor  += (Int)(bNeighborFlags[iNumUnitsInCu*2]);
339  iNumIntraNeighbor  += isAboveAvailable     ( pcCU, uiPartIdxLT, uiPartIdxRT, bNeighborFlags+(iNumUnitsInCu*2)+1 );
340  iNumIntraNeighbor  += isAboveRightAvailable( pcCU, uiPartIdxLT, uiPartIdxRT, bNeighborFlags+(iNumUnitsInCu*3)+1 );
341  iNumIntraNeighbor  += isLeftAvailable      ( pcCU, uiPartIdxLT, uiPartIdxLB, bNeighborFlags+(iNumUnitsInCu*2)-1 );
342  iNumIntraNeighbor  += isBelowLeftAvailable ( pcCU, uiPartIdxLT, uiPartIdxLB, bNeighborFlags+ iNumUnitsInCu   -1 );
343 
344  bAbove = true;
345  bLeft  = true;
346 
347  uiCuWidth=uiCuWidth>>1;  // for chroma
348  uiCuHeight=uiCuHeight>>1;  // for chroma
349 
350  uiWidth=uiCuWidth*2+1;
351  uiHeight=uiCuHeight*2+1;
352 
353  if ((4*uiWidth>iOrgBufStride)||(4*uiHeight>iOrgBufHeight))
354  {
355    return;
356  }
357 
358  // get Cb pattern
359  piRoiOrigin = pcCU->getPic()->getPicYuvRec()->getCbAddr(pcCU->getAddr(), pcCU->getZorderIdxInCU()+uiZorderIdxInPart);
360  piAdiTemp   = piAdiBuf;
361
362  fillReferenceSamples (g_bitDepthC, piRoiOrigin, piAdiTemp, bNeighborFlags, iNumIntraNeighbor, iUnitSize, iNumUnitsInCu, iTotalUnits, uiCuWidth, uiCuHeight, uiWidth, uiHeight, iPicStride);
363 
364  // get Cr pattern
365  piRoiOrigin = pcCU->getPic()->getPicYuvRec()->getCrAddr(pcCU->getAddr(), pcCU->getZorderIdxInCU()+uiZorderIdxInPart);
366  piAdiTemp   = piAdiBuf+uiWidth*uiHeight;
367 
368  fillReferenceSamples (g_bitDepthC, piRoiOrigin, piAdiTemp, bNeighborFlags, iNumIntraNeighbor, iUnitSize, iNumUnitsInCu, iTotalUnits, uiCuWidth, uiCuHeight, uiWidth, uiHeight, iPicStride);
369}
370
371Void TComPattern::fillReferenceSamples(Int bitDepth, Pel* piRoiOrigin, Int* piAdiTemp, Bool* bNeighborFlags, Int iNumIntraNeighbor, Int iUnitSize, Int iNumUnitsInCu, Int iTotalUnits, UInt uiCuWidth, UInt uiCuHeight, UInt uiWidth, UInt uiHeight, Int iPicStride, Bool bLMmode )
372{
373  Pel* piRoiTemp;
374  Int  i, j;
375  Int  iDCValue = 1 << (bitDepth - 1);
376
377  if (iNumIntraNeighbor == 0)
378  {
379    // Fill border with DC value
380    for (i=0; i<uiWidth; i++)
381    {
382      piAdiTemp[i] = iDCValue;
383    }
384    for (i=1; i<uiHeight; i++)
385    {
386      piAdiTemp[i*uiWidth] = iDCValue;
387    }
388  }
389  else if (iNumIntraNeighbor == iTotalUnits)
390  {
391    // Fill top-left border with rec. samples
392    piRoiTemp = piRoiOrigin - iPicStride - 1;
393    piAdiTemp[0] = piRoiTemp[0];
394
395    // Fill left border with rec. samples
396    piRoiTemp = piRoiOrigin - 1;
397
398    if (bLMmode)
399    {
400      piRoiTemp --; // move to the second left column
401    }
402
403    for (i=0; i<uiCuHeight; i++)
404    {
405      piAdiTemp[(1+i)*uiWidth] = piRoiTemp[0];
406      piRoiTemp += iPicStride;
407    }
408
409    // Fill below left border with rec. samples
410    for (i=0; i<uiCuHeight; i++)
411    {
412      piAdiTemp[(1+uiCuHeight+i)*uiWidth] = piRoiTemp[0];
413      piRoiTemp += iPicStride;
414    }
415
416    // Fill top border with rec. samples
417    piRoiTemp = piRoiOrigin - iPicStride;
418    for (i=0; i<uiCuWidth; i++)
419    {
420      piAdiTemp[1+i] = piRoiTemp[i];
421    }
422   
423    // Fill top right border with rec. samples
424    piRoiTemp = piRoiOrigin - iPicStride + uiCuWidth;
425    for (i=0; i<uiCuWidth; i++)
426    {
427      piAdiTemp[1+uiCuWidth+i] = piRoiTemp[i];
428    }
429  }
430  else // reference samples are partially available
431  {
432    Int  iNumUnits2 = iNumUnitsInCu<<1;
433    Int  iTotalSamples = iTotalUnits*iUnitSize;
434    Pel  piAdiLine[5 * MAX_CU_SIZE];
435    Pel  *piAdiLineTemp; 
436    Bool *pbNeighborFlags;
437    Int  iNext, iCurr;
438    Pel  piRef = 0;
439
440    // Initialize
441    for (i=0; i<iTotalSamples; i++)
442    {
443      piAdiLine[i] = iDCValue;
444    }
445   
446    // Fill top-left sample
447    piRoiTemp = piRoiOrigin - iPicStride - 1;
448    piAdiLineTemp = piAdiLine + (iNumUnits2*iUnitSize);
449    pbNeighborFlags = bNeighborFlags + iNumUnits2;
450    if (*pbNeighborFlags)
451    {
452      piAdiLineTemp[0] = piRoiTemp[0];
453      for (i=1; i<iUnitSize; i++)
454      {
455        piAdiLineTemp[i] = piAdiLineTemp[0];
456      }
457    }
458
459    // Fill left & below-left samples
460    piRoiTemp += iPicStride;
461    if (bLMmode)
462    {
463      piRoiTemp --; // move the second left column
464    }
465    piAdiLineTemp--;
466    pbNeighborFlags--;
467    for (j=0; j<iNumUnits2; j++)
468    {
469      if (*pbNeighborFlags)
470      {
471        for (i=0; i<iUnitSize; i++)
472        {
473          piAdiLineTemp[-i] = piRoiTemp[i*iPicStride];
474        }
475      }
476      piRoiTemp += iUnitSize*iPicStride;
477      piAdiLineTemp -= iUnitSize;
478      pbNeighborFlags--;
479    }
480
481    // Fill above & above-right samples
482    piRoiTemp = piRoiOrigin - iPicStride;
483    piAdiLineTemp = piAdiLine + ((iNumUnits2+1)*iUnitSize);
484    pbNeighborFlags = bNeighborFlags + iNumUnits2 + 1;
485    for (j=0; j<iNumUnits2; j++)
486    {
487      if (*pbNeighborFlags)
488      {
489        for (i=0; i<iUnitSize; i++)
490        {
491          piAdiLineTemp[i] = piRoiTemp[i];
492        }
493      }
494      piRoiTemp += iUnitSize;
495      piAdiLineTemp += iUnitSize;
496      pbNeighborFlags++;
497    }
498
499    // Pad reference samples when necessary
500    iCurr = 0;
501    iNext = 1;
502    piAdiLineTemp = piAdiLine;
503    while (iCurr < iTotalUnits)
504    {
505      if (!bNeighborFlags[iCurr])
506      {
507        if(iCurr == 0)
508        {
509          while (iNext < iTotalUnits && !bNeighborFlags[iNext])
510          {
511            iNext++;
512          }
513          piRef = piAdiLine[iNext*iUnitSize];
514          // Pad unavailable samples with new value
515          while (iCurr < iNext)
516          {
517            for (i=0; i<iUnitSize; i++)
518            {
519              piAdiLineTemp[i] = piRef;
520            }
521            piAdiLineTemp += iUnitSize;
522            iCurr++;
523          }
524        }
525        else
526        {
527          piRef = piAdiLine[iCurr*iUnitSize-1];
528          for (i=0; i<iUnitSize; i++)
529          {
530            piAdiLineTemp[i] = piRef;
531          }
532          piAdiLineTemp += iUnitSize;
533          iCurr++;
534        }
535      }
536      else
537      {
538        piAdiLineTemp += iUnitSize;
539        iCurr++;
540      }
541    }
542
543    // Copy processed samples
544    piAdiLineTemp = piAdiLine + uiHeight + iUnitSize - 2;
545    for (i=0; i<uiWidth; i++)
546    {
547      piAdiTemp[i] = piAdiLineTemp[i];
548    }
549    piAdiLineTemp = piAdiLine + uiHeight - 1;
550    for (i=1; i<uiHeight; i++)
551    {
552      piAdiTemp[i*uiWidth] = piAdiLineTemp[-i];
553    }
554  }
555}
556
557Int* TComPattern::getAdiOrgBuf( Int /*iCuWidth*/, Int /*iCuHeight*/, Int* piAdiBuf)
558{
559  return piAdiBuf;
560}
561
562Int* TComPattern::getAdiCbBuf( Int /*iCuWidth*/, Int /*iCuHeight*/, Int* piAdiBuf)
563{
564  return piAdiBuf;
565}
566
567Int* TComPattern::getAdiCrBuf(Int iCuWidth,Int iCuHeight, Int* piAdiBuf)
568{
569  return piAdiBuf+(iCuWidth*2+1)*(iCuHeight*2+1);
570}
571
572/** Get pointer to reference samples for intra prediction
573 * \param uiDirMode   prediction mode index
574 * \param log2BlkSize size of block (2 = 4x4, 3 = 8x8, 4 = 16x16, 5 = 32x32, 6 = 64x64)
575 * \param piAdiBuf    pointer to unfiltered reference samples
576 * \return            pointer to (possibly filtered) reference samples
577 *
578 * The prediction mode index is used to determine whether a smoothed reference sample buffer is returned.
579 */
580Int* TComPattern::getPredictorPtr( UInt uiDirMode, UInt log2BlkSize, Int* piAdiBuf )
581{
582  Int* piSrc;
583  assert(log2BlkSize >= 2 && log2BlkSize < 7);
584  Int diff = min<Int>(abs((Int) uiDirMode - HOR_IDX), abs((Int)uiDirMode - VER_IDX));
585  UChar ucFiltIdx = diff > m_aucIntraFilter[log2BlkSize - 2] ? 1 : 0;
586  if (uiDirMode == DC_IDX)
587  {
588    ucFiltIdx = 0; //no smoothing for DC or LM chroma
589  }
590
591  assert( ucFiltIdx <= 1 );
592
593  Int width  = 1 << log2BlkSize;
594  Int height = 1 << log2BlkSize;
595 
596  piSrc = getAdiOrgBuf( width, height, piAdiBuf );
597
598  if ( ucFiltIdx )
599  {
600    piSrc += (2 * width + 1) * (2 * height + 1);
601  }
602
603  return piSrc;
604}
605
606Bool TComPattern::isAboveLeftAvailable( TComDataCU* pcCU, UInt uiPartIdxLT )
607{
608  Bool bAboveLeftFlag;
609  UInt uiPartAboveLeft;
610  TComDataCU* pcCUAboveLeft = pcCU->getPUAboveLeft( uiPartAboveLeft, uiPartIdxLT );
611  if(pcCU->getSlice()->getPPS()->getConstrainedIntraPred())
612  {
613    bAboveLeftFlag = ( pcCUAboveLeft && pcCUAboveLeft->getPredictionMode( uiPartAboveLeft ) == MODE_INTRA );
614  }
615  else
616  {
617    bAboveLeftFlag = (pcCUAboveLeft ? true : false);
618  }
619  return bAboveLeftFlag;
620}
621
622Int TComPattern::isAboveAvailable( TComDataCU* pcCU, UInt uiPartIdxLT, UInt uiPartIdxRT, Bool *bValidFlags )
623{
624  const UInt uiRasterPartBegin = g_auiZscanToRaster[uiPartIdxLT];
625  const UInt uiRasterPartEnd = g_auiZscanToRaster[uiPartIdxRT]+1;
626  const UInt uiIdxStep = 1;
627  Bool *pbValidFlags = bValidFlags;
628  Int iNumIntra = 0;
629
630  for ( UInt uiRasterPart = uiRasterPartBegin; uiRasterPart < uiRasterPartEnd; uiRasterPart += uiIdxStep )
631  {
632    UInt uiPartAbove;
633    TComDataCU* pcCUAbove = pcCU->getPUAbove( uiPartAbove, g_auiRasterToZscan[uiRasterPart] );
634    if(pcCU->getSlice()->getPPS()->getConstrainedIntraPred())
635    {
636      if ( pcCUAbove && pcCUAbove->getPredictionMode( uiPartAbove ) == MODE_INTRA )
637      {
638        iNumIntra++;
639        *pbValidFlags = true;
640      }
641      else
642      {
643        *pbValidFlags = false;
644      }
645    }
646    else
647    {
648      if (pcCUAbove)
649      {
650        iNumIntra++;
651        *pbValidFlags = true;
652      }
653      else
654      {
655        *pbValidFlags = false;
656      }
657    }
658    pbValidFlags++;
659  }
660  return iNumIntra;
661}
662
663Int TComPattern::isLeftAvailable( TComDataCU* pcCU, UInt uiPartIdxLT, UInt uiPartIdxLB, Bool *bValidFlags )
664{
665  const UInt uiRasterPartBegin = g_auiZscanToRaster[uiPartIdxLT];
666  const UInt uiRasterPartEnd = g_auiZscanToRaster[uiPartIdxLB]+1;
667  const UInt uiIdxStep = pcCU->getPic()->getNumPartInWidth();
668  Bool *pbValidFlags = bValidFlags;
669  Int iNumIntra = 0;
670
671  for ( UInt uiRasterPart = uiRasterPartBegin; uiRasterPart < uiRasterPartEnd; uiRasterPart += uiIdxStep )
672  {
673    UInt uiPartLeft;
674    TComDataCU* pcCULeft = pcCU->getPULeft( uiPartLeft, g_auiRasterToZscan[uiRasterPart] );
675    if(pcCU->getSlice()->getPPS()->getConstrainedIntraPred())
676    {
677      if ( pcCULeft && pcCULeft->getPredictionMode( uiPartLeft ) == MODE_INTRA )
678      {
679        iNumIntra++;
680        *pbValidFlags = true;
681      }
682      else
683      {
684        *pbValidFlags = false;
685      }
686    }
687    else
688    {
689      if ( pcCULeft )
690      {
691        iNumIntra++;
692        *pbValidFlags = true;
693      }
694      else
695      {
696        *pbValidFlags = false;
697      }
698    }
699    pbValidFlags--; // opposite direction
700  }
701
702  return iNumIntra;
703}
704
705Int TComPattern::isAboveRightAvailable( TComDataCU* pcCU, UInt uiPartIdxLT, UInt uiPartIdxRT, Bool *bValidFlags )
706{
707  const UInt uiNumUnitsInPU = g_auiZscanToRaster[uiPartIdxRT] - g_auiZscanToRaster[uiPartIdxLT] + 1;
708  Bool *pbValidFlags = bValidFlags;
709  Int iNumIntra = 0;
710
711  for ( UInt uiOffset = 1; uiOffset <= uiNumUnitsInPU; uiOffset++ )
712  {
713    UInt uiPartAboveRight;
714    TComDataCU* pcCUAboveRight = pcCU->getPUAboveRightAdi( uiPartAboveRight, uiPartIdxRT, uiOffset );
715    if(pcCU->getSlice()->getPPS()->getConstrainedIntraPred())
716    {
717      if ( pcCUAboveRight && pcCUAboveRight->getPredictionMode( uiPartAboveRight ) == MODE_INTRA )
718      {
719        iNumIntra++;
720        *pbValidFlags = true;
721      }
722      else
723      {
724        *pbValidFlags = false;
725      }
726    }
727    else
728    {
729      if ( pcCUAboveRight )
730      {
731        iNumIntra++;
732        *pbValidFlags = true;
733      }
734      else
735      {
736        *pbValidFlags = false;
737      }
738    }
739    pbValidFlags++;
740  }
741
742  return iNumIntra;
743}
744
745Int TComPattern::isBelowLeftAvailable( TComDataCU* pcCU, UInt uiPartIdxLT, UInt uiPartIdxLB, Bool *bValidFlags )
746{
747  const UInt uiNumUnitsInPU = (g_auiZscanToRaster[uiPartIdxLB] - g_auiZscanToRaster[uiPartIdxLT]) / pcCU->getPic()->getNumPartInWidth() + 1;
748  Bool *pbValidFlags = bValidFlags;
749  Int iNumIntra = 0;
750
751  for ( UInt uiOffset = 1; uiOffset <= uiNumUnitsInPU; uiOffset++ )
752  {
753    UInt uiPartBelowLeft;
754    TComDataCU* pcCUBelowLeft = pcCU->getPUBelowLeftAdi( uiPartBelowLeft, uiPartIdxLB, uiOffset );
755    if(pcCU->getSlice()->getPPS()->getConstrainedIntraPred())
756    {
757      if ( pcCUBelowLeft && pcCUBelowLeft->getPredictionMode( uiPartBelowLeft ) == MODE_INTRA )
758      {
759        iNumIntra++;
760        *pbValidFlags = true;
761      }
762      else
763      {
764        *pbValidFlags = false;
765      }
766    }
767    else
768    {
769      if ( pcCUBelowLeft )
770      {
771        iNumIntra++;
772        *pbValidFlags = true;
773      }
774      else
775      {
776        *pbValidFlags = false;
777      }
778    }
779    pbValidFlags--; // opposite direction
780  }
781
782  return iNumIntra;
783}
784//! \}
Note: See TracBrowser for help on using the repository browser.