source: SHVCSoftware/branches/0.1.1-bugfix/source/Lib/TLibCommon/TComPattern.cpp

Last change on this file was 2, checked in by seregin, 12 years ago

Initial import by Vadim Seregin <vseregin@…>

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