source: 3DVCSoftware/branches/HTM-6.2-dev0/source/Lib/TLibCommon/TComPrediction.cpp @ 427

Last change on this file since 427 was 427, checked in by tech, 11 years ago

Merged HTM-6.2-dev1-LG

  • Property svn:eol-style set to native
File size: 138.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     TComPrediction.cpp
35    \brief    prediction class
36*/
37
38#include <memory.h>
39#include "TComPrediction.h"
40
41//! \ingroup TLibCommon
42//! \{
43
44// ====================================================================================================================
45// Constructor / destructor / initialize
46// ====================================================================================================================
47
48#if LGE_EDGE_INTRA_A0070
49#define MAX_DISTANCE_EDGEINTRA 255
50#endif
51
52#if MERL_General_Fix
53#if MERL_VSP_C0152
54#if MERL_CVSP_D0165
55Int TComPrediction::m_iRangeLuma[12]   = {14, 34, 21, 15, 36, 26, 21, 49, 41, 36, 80, 72};
56Int TComPrediction::m_iRangeChroma[12] = { 2,  8,  5,  4, 11,  9,  8, 19, 17, 15, 34, 32};
57#endif
58#endif
59#endif
60
61TComPrediction::TComPrediction()
62: m_pLumaRecBuffer(0)
63{
64  m_piYuvExt = NULL;
65#if MERL_VSP_C0152
66  m_pDepth = (Int*) malloc(64*64*sizeof(Int)); // TODO: Use a smart way to determine the size of the array
67  if (m_pDepth == NULL)
68  {
69      printf("ERROR: UKTGHU, No memory allocated.\n");
70  }
71#endif
72}
73
74TComPrediction::~TComPrediction()
75{
76 
77#if MERL_VSP_C0152
78  if (m_pDepth != NULL)
79  {
80      free(m_pDepth);
81  }
82#endif
83  delete[] m_piYuvExt;
84
85  m_acYuvPred[0].destroy();
86  m_acYuvPred[1].destroy();
87
88  m_cYuvPredTemp.destroy();
89#if QC_ARP_D0177
90  m_acYuvPredBase[0].destroy();
91  m_acYuvPredBase[1].destroy();
92  m_acYuvDiff[0].destroy();
93  m_acYuvDiff[1].destroy();
94#endif
95  if( m_pLumaRecBuffer )
96  {
97    delete [] m_pLumaRecBuffer;
98  }
99 
100  Int i, j;
101  for (i = 0; i < 4; i++)
102  {
103    for (j = 0; j < 4; j++)
104    {
105      m_filteredBlock[i][j].destroy();
106    }
107    m_filteredBlockTmp[i].destroy();
108  }
109}
110
111Void TComPrediction::initTempBuff()
112{
113  if( m_piYuvExt == NULL )
114  {
115    Int extWidth  = g_uiMaxCUWidth + 16; 
116    Int extHeight = g_uiMaxCUHeight + 1;
117    Int i, j;
118    for (i = 0; i < 4; i++)
119    {
120      m_filteredBlockTmp[i].create(extWidth, extHeight + 7);
121      for (j = 0; j < 4; j++)
122      {
123        m_filteredBlock[i][j].create(extWidth, extHeight);
124      }
125    }
126    m_iYuvExtHeight  = ((g_uiMaxCUHeight + 2) << 4);
127    m_iYuvExtStride = ((g_uiMaxCUWidth  + 8) << 4);
128    m_piYuvExt = new Int[ m_iYuvExtStride * m_iYuvExtHeight ];
129
130    // new structure
131    m_acYuvPred[0] .create( g_uiMaxCUWidth, g_uiMaxCUHeight );
132    m_acYuvPred[1] .create( g_uiMaxCUWidth, g_uiMaxCUHeight );
133
134    m_cYuvPredTemp.create( g_uiMaxCUWidth, g_uiMaxCUHeight );
135#if QC_ARP_D0177
136    m_acYuvPredBase[0] .create( g_uiMaxCUWidth, g_uiMaxCUHeight );
137    m_acYuvPredBase[1] .create( g_uiMaxCUWidth, g_uiMaxCUHeight );
138    m_acYuvDiff    [0] .create( g_uiMaxCUWidth, g_uiMaxCUHeight );
139    m_acYuvDiff    [1] .create( g_uiMaxCUWidth, g_uiMaxCUHeight );
140#endif
141  }
142
143  m_iLumaRecStride =  (g_uiMaxCUWidth>>1) + 1;
144  m_pLumaRecBuffer = new Pel[ m_iLumaRecStride * m_iLumaRecStride ];
145
146  for( Int i = 1; i < 64; i++ )
147  {
148    m_uiaShift[i-1] = ( (1 << 15) + i/2 ) / i;
149  }
150}
151
152// ====================================================================================================================
153// Public member functions
154// ====================================================================================================================
155
156// Function for calculating DC value of the reference samples used in Intra prediction
157Pel TComPrediction::predIntraGetPredValDC( Int* pSrc, Int iSrcStride, UInt iWidth, UInt iHeight, Bool bAbove, Bool bLeft )
158{
159  Int iInd, iSum = 0;
160  Pel pDcVal;
161
162  if (bAbove)
163  {
164    for (iInd = 0;iInd < iWidth;iInd++)
165    {
166      iSum += pSrc[iInd-iSrcStride];
167    }
168  }
169  if (bLeft)
170  {
171    for (iInd = 0;iInd < iHeight;iInd++)
172    {
173      iSum += pSrc[iInd*iSrcStride-1];
174    }
175  }
176
177  if (bAbove && bLeft)
178  {
179    pDcVal = (iSum + iWidth) / (iWidth + iHeight);
180  }
181  else if (bAbove)
182  {
183    pDcVal = (iSum + iWidth/2) / iWidth;
184  }
185  else if (bLeft)
186  {
187    pDcVal = (iSum + iHeight/2) / iHeight;
188  }
189  else
190  {
191    pDcVal = pSrc[-1]; // Default DC value already calculated and placed in the prediction array if no neighbors are available
192  }
193 
194  return pDcVal;
195}
196
197// Function for deriving the angular Intra predictions
198
199/** Function for deriving the simplified angular intra predictions.
200 * \param pSrc pointer to reconstructed sample array
201 * \param srcStride the stride of the reconstructed sample array
202 * \param rpDst reference to pointer for the prediction sample array
203 * \param dstStride the stride of the prediction sample array
204 * \param width the width of the block
205 * \param height the height of the block
206 * \param dirMode the intra prediction mode index
207 * \param blkAboveAvailable boolean indication if the block above is available
208 * \param blkLeftAvailable boolean indication if the block to the left is available
209 *
210 * This function derives the prediction samples for the angular mode based on the prediction direction indicated by
211 * the prediction mode index. The prediction direction is given by the displacement of the bottom row of the block and
212 * the reference row above the block in the case of vertical prediction or displacement of the rightmost column
213 * of the block and reference column left from the block in the case of the horizontal prediction. The displacement
214 * is signalled at 1/32 pixel accuracy. When projection of the predicted pixel falls inbetween reference samples,
215 * the predicted value for the pixel is linearly interpolated from the reference samples. All reference samples are taken
216 * from the extended main reference.
217 */
218Void TComPrediction::xPredIntraAng( Int* pSrc, Int srcStride, Pel*& rpDst, Int dstStride, UInt width, UInt height, UInt dirMode, Bool blkAboveAvailable, Bool blkLeftAvailable, Bool bFilter )
219{
220  Int k,l;
221  Int blkSize        = width;
222  Pel* pDst          = rpDst;
223
224  // Map the mode index to main prediction direction and angle
225  assert( dirMode > 0 ); //no planar
226  Bool modeDC        = dirMode < 2;
227  Bool modeHor       = !modeDC && (dirMode < 18);
228  Bool modeVer       = !modeDC && !modeHor;
229  Int intraPredAngle = modeVer ? (Int)dirMode - VER_IDX : modeHor ? -((Int)dirMode - HOR_IDX) : 0;
230  Int absAng         = abs(intraPredAngle);
231  Int signAng        = intraPredAngle < 0 ? -1 : 1;
232
233  // Set bitshifts and scale the angle parameter to block size
234  Int angTable[9]    = {0,    2,    5,   9,  13,  17,  21,  26,  32};
235  Int invAngTable[9] = {0, 4096, 1638, 910, 630, 482, 390, 315, 256}; // (256 * 32) / Angle
236  Int invAngle       = invAngTable[absAng];
237  absAng             = angTable[absAng];
238  intraPredAngle     = signAng * absAng;
239
240  // Do the DC prediction
241  if (modeDC)
242  {
243    Pel dcval = predIntraGetPredValDC(pSrc, srcStride, width, height, blkAboveAvailable, blkLeftAvailable);
244
245    for (k=0;k<blkSize;k++)
246    {
247      for (l=0;l<blkSize;l++)
248      {
249        pDst[k*dstStride+l] = dcval;
250      }
251    }
252  }
253
254  // Do angular predictions
255  else
256  {
257    Pel* refMain;
258    Pel* refSide;
259    Pel  refAbove[2*MAX_CU_SIZE+1];
260    Pel  refLeft[2*MAX_CU_SIZE+1];
261
262    // Initialise the Main and Left reference array.
263    if (intraPredAngle < 0)
264    {
265      for (k=0;k<blkSize+1;k++)
266      {
267        refAbove[k+blkSize-1] = pSrc[k-srcStride-1];
268      }
269      for (k=0;k<blkSize+1;k++)
270      {
271        refLeft[k+blkSize-1] = pSrc[(k-1)*srcStride-1];
272      }
273      refMain = (modeVer ? refAbove : refLeft) + (blkSize-1);
274      refSide = (modeVer ? refLeft : refAbove) + (blkSize-1);
275
276      // Extend the Main reference to the left.
277      Int invAngleSum    = 128;       // rounding for (shift by 8)
278      for (k=-1; k>blkSize*intraPredAngle>>5; k--)
279      {
280        invAngleSum += invAngle;
281        refMain[k] = refSide[invAngleSum>>8];
282      }
283    }
284    else
285    {
286      for (k=0;k<2*blkSize+1;k++)
287      {
288        refAbove[k] = pSrc[k-srcStride-1];
289      }
290      for (k=0;k<2*blkSize+1;k++)
291      {
292        refLeft[k] = pSrc[(k-1)*srcStride-1];
293      }
294      refMain = modeVer ? refAbove : refLeft;
295      refSide = modeVer ? refLeft  : refAbove;
296    }
297
298    if (intraPredAngle == 0)
299    {
300      for (k=0;k<blkSize;k++)
301      {
302        for (l=0;l<blkSize;l++)
303        {
304          pDst[k*dstStride+l] = refMain[l+1];
305        }
306      }
307
308      if ( bFilter )
309      {
310        for (k=0;k<blkSize;k++)
311        {
312          pDst[k*dstStride] = Clip ( pDst[k*dstStride] + (( refSide[k+1] - refSide[0] ) >> 1) );
313        }
314      }
315    }
316    else
317    {
318      Int deltaPos=0;
319      Int deltaInt;
320      Int deltaFract;
321      Int refMainIndex;
322
323      for (k=0;k<blkSize;k++)
324      {
325        deltaPos += intraPredAngle;
326        deltaInt   = deltaPos >> 5;
327        deltaFract = deltaPos & (32 - 1);
328
329        if (deltaFract)
330        {
331          // Do linear filtering
332          for (l=0;l<blkSize;l++)
333          {
334            refMainIndex        = l+deltaInt+1;
335            pDst[k*dstStride+l] = (Pel) ( ((32-deltaFract)*refMain[refMainIndex]+deltaFract*refMain[refMainIndex+1]+16) >> 5 );
336          }
337        }
338        else
339        {
340          // Just copy the integer samples
341          for (l=0;l<blkSize;l++)
342          {
343            pDst[k*dstStride+l] = refMain[l+deltaInt+1];
344          }
345        }
346      }
347    }
348
349    // Flip the block if this is the horizontal mode
350    if (modeHor)
351    {
352      Pel  tmp;
353      for (k=0;k<blkSize-1;k++)
354      {
355        for (l=k+1;l<blkSize;l++)
356        {
357          tmp                 = pDst[k*dstStride+l];
358          pDst[k*dstStride+l] = pDst[l*dstStride+k];
359          pDst[l*dstStride+k] = tmp;
360        }
361      }
362    }
363  }
364}
365
366Void TComPrediction::predIntraLumaAng(TComPattern* pcTComPattern, UInt uiDirMode, Pel* piPred, UInt uiStride, Int iWidth, Int iHeight,  TComDataCU* pcCU, Bool bAbove, Bool bLeft )
367{
368  Pel *pDst = piPred;
369  Int *ptrSrc;
370
371  assert( g_aucConvertToBit[ iWidth ] >= 0 ); //   4x  4
372  assert( g_aucConvertToBit[ iWidth ] <= 5 ); // 128x128
373  assert( iWidth == iHeight  );
374
375  ptrSrc = pcTComPattern->getPredictorPtr( uiDirMode, g_aucConvertToBit[ iWidth ] + 2, m_piYuvExt );
376
377  // get starting pixel in block
378  Int sw = 2 * iWidth + 1;
379
380  // Create the prediction
381  if ( uiDirMode == PLANAR_IDX )
382  {
383    xPredIntraPlanar( ptrSrc+sw+1, sw, pDst, uiStride, iWidth, iHeight );
384  }
385  else
386  {
387    xPredIntraAng( ptrSrc+sw+1, sw, pDst, uiStride, iWidth, iHeight, uiDirMode, bAbove, bLeft, true );
388
389    if( (uiDirMode == DC_IDX ) && bAbove && bLeft )
390    {
391      xDCPredFiltering( ptrSrc+sw+1, sw, pDst, uiStride, iWidth, iHeight);
392    }
393  }
394}
395
396// Angular chroma
397Void TComPrediction::predIntraChromaAng( TComPattern* pcTComPattern, Int* piSrc, UInt uiDirMode, Pel* piPred, UInt uiStride, Int iWidth, Int iHeight, TComDataCU* pcCU, Bool bAbove, Bool bLeft )
398{
399  Pel *pDst = piPred;
400  Int *ptrSrc = piSrc;
401
402  // get starting pixel in block
403  Int sw = 2 * iWidth + 1;
404
405  if ( uiDirMode == PLANAR_IDX )
406  {
407    xPredIntraPlanar( ptrSrc+sw+1, sw, pDst, uiStride, iWidth, iHeight );
408  }
409  else
410  {
411    // Create the prediction
412    xPredIntraAng( ptrSrc+sw+1, sw, pDst, uiStride, iWidth, iHeight, uiDirMode, bAbove, bLeft, false );
413  }
414}
415
416/** Function for checking identical motion.
417 * \param TComDataCU* pcCU
418 * \param UInt PartAddr
419 */
420Bool TComPrediction::xCheckIdenticalMotion ( TComDataCU* pcCU, UInt PartAddr )
421{
422  if( pcCU->getSlice()->isInterB() && pcCU->getSlice()->getPPS()->getWPBiPredIdc() == 0 )
423  {
424    if( pcCU->getCUMvField(REF_PIC_LIST_0)->getRefIdx(PartAddr) >= 0 && pcCU->getCUMvField(REF_PIC_LIST_1)->getRefIdx(PartAddr) >= 0)
425    {
426      Int RefPOCL0    = pcCU->getSlice()->getRefPic(REF_PIC_LIST_0, pcCU->getCUMvField(REF_PIC_LIST_0)->getRefIdx(PartAddr))->getPOC();
427      Int RefViewIdL0 = pcCU->getSlice()->getRefPic(REF_PIC_LIST_0, pcCU->getCUMvField(REF_PIC_LIST_0)->getRefIdx(PartAddr))->getViewId();
428      Int RefPOCL1    = pcCU->getSlice()->getRefPic(REF_PIC_LIST_1, pcCU->getCUMvField(REF_PIC_LIST_1)->getRefIdx(PartAddr))->getPOC();
429      Int RefViewIdL1 = pcCU->getSlice()->getRefPic(REF_PIC_LIST_1, pcCU->getCUMvField(REF_PIC_LIST_1)->getRefIdx(PartAddr))->getViewId();
430      if(RefPOCL0 == RefPOCL1 && RefViewIdL0 == RefViewIdL1 && pcCU->getCUMvField(REF_PIC_LIST_0)->getMv(PartAddr) == pcCU->getCUMvField(REF_PIC_LIST_1)->getMv(PartAddr))
431      {
432        return true;
433      }
434    }
435  }
436  return false;
437}
438
439#if LGE_EDGE_INTRA_A0070
440Void TComPrediction::predIntraLumaEdge ( TComDataCU* pcCU, TComPattern* pcTComPattern, UInt uiAbsPartIdx, Int iWidth, Int iHeight, Pel* piPred, UInt uiStride, Bool bDelta )
441{
442  Pel *piDst = piPred;
443  Int *piSrc;
444  Int iSrcStride = ( iWidth<<1 ) + 1;
445  Int iDstStride = uiStride;
446
447  piSrc = pcTComPattern->getPredictorPtr( 0, g_aucConvertToBit[ iWidth ] + 2, m_piYuvExt );
448
449  xPredIntraEdge ( pcCU, uiAbsPartIdx, iWidth, iHeight, piSrc, iSrcStride, piDst, iDstStride
450#if LGE_EDGE_INTRA_DELTA_DC
451    , bDelta
452#endif
453    );
454}
455
456Pel  TComPrediction::xGetNearestNeighbor( Int x, Int y, Int* pSrc, Int srcStride, Int iWidth, Int iHeight, Bool* bpRegion )
457{
458  Bool bLeft = (x < y) ? true : false;
459  Bool bFound = false;
460  Int  iFoundX = -1, iFoundY = -1;
461  Int  cResult = 0;
462
463  UChar* piTopDistance = new UChar[iWidth];
464  UChar* piLeftDistance = new UChar[iHeight];
465
466  for( Int i = 0; i < iWidth; i++ )
467  {
468    int Abs = x > i ? x - i : i - x;
469    piTopDistance[ i ] = y + Abs;
470
471    Abs = y > i ? y - i : i - y;
472    piLeftDistance[ i ] = x + Abs;
473  }
474
475  for( Int dist = 0; dist < MAX_DISTANCE_EDGEINTRA && !bFound; dist++ )
476  {
477    if( !bLeft )
478    {
479      for( Int i = 0; i < iWidth; i++ )
480      {
481        if( piTopDistance[ i ] == dist )
482        {
483          if( bpRegion[ i ] == bpRegion[ x + y * iWidth ] )
484          {
485            iFoundX = i;
486            iFoundY = 0;
487            bFound = true;
488          }
489        }
490      }
491      for( Int i = 0; i < iHeight; i++ )
492      {
493        if( piLeftDistance[ i ] == dist )
494        {
495          if( bpRegion[ i * iWidth ] == bpRegion[ x + y * iWidth ] )
496          {
497            iFoundX = 0;
498            iFoundY = i;
499            bFound = true;
500          }
501        }
502      }
503    }
504    else
505    {
506      for( Int i = 0; i < iHeight; i++ )
507      {
508        if( piLeftDistance[ i ] == dist )
509        {
510          if( bpRegion[ i * iWidth ] == bpRegion[ x + y * iWidth ] )
511          {
512            iFoundX = 0;
513            iFoundY = i;
514            bFound = true;
515          }
516        }
517      }
518      for( Int i = 0; i < iWidth; i++ )
519      {
520        if( piTopDistance[ i ] == dist )
521        {
522          if( bpRegion[ i ] == bpRegion[ x + y * iWidth ] )
523          {
524            iFoundX = i;
525            iFoundY = 0;
526            bFound = true;
527          }
528        }
529      }
530    }
531  }
532
533  if( iFoundY == 0 )
534  {
535    cResult = pSrc[ iFoundX + 1 ];
536  }
537  else // iFoundX == 0
538  {
539    cResult = pSrc[ (iFoundY + 1) * srcStride ];
540  }
541
542  delete[] piTopDistance;  piTopDistance = NULL;
543  delete[] piLeftDistance; piLeftDistance = NULL;
544
545  assert( bFound );
546
547  return cResult;
548}
549
550Void TComPrediction::xPredIntraEdge( TComDataCU* pcCU, UInt uiAbsPartIdx, Int iWidth, Int iHeight, Int* pSrc, Int srcStride, Pel*& rpDst, Int dstStride, Bool bDelta )
551{
552  Pel* pDst = rpDst;
553  Bool* pbRegion = pcCU->getEdgePartition( uiAbsPartIdx );
554
555  // Do prediction
556  {
557    //UInt uiSum0 = 0, uiSum1 = 0;
558    Int iSum0 = 0, iSum1 = 0;
559    //UInt uiMean0, uiMean1;
560    Int iMean0, iMean1;
561    //UInt uiCount0 = 0, uiCount1 = 0;
562    Int iCount0 = 0, iCount1 = 0;
563    for( UInt ui = 0; ui < iWidth; ui++ )
564    {
565      if( pbRegion[ ui ] == false )
566      {
567        iSum0 += (pSrc[ ui + 1 ]);
568        iCount0++;
569      }
570      else
571      {
572        iSum1 += (pSrc[ ui + 1 ]);
573        iCount1++;
574      }
575    }
576    for( UInt ui = 0; ui < iHeight; ui++ ) // (0,0) recount (to avoid division)
577    {
578      if( pbRegion[ ui * iWidth ] == false )
579      {
580        iSum0 += (pSrc[ (ui + 1) * srcStride ]);
581        iCount0++;
582      }
583      else
584      {
585        iSum1 += (pSrc[ (ui + 1) * srcStride ]);
586        iCount1++;
587      }
588    }
589    if( iCount0 == 0 )
590      assert(false);
591    if( iCount1 == 0 )
592      assert(false);
593    iMean0 = iSum0 / iCount0; // TODO : integer op.
594    iMean1 = iSum1 / iCount1;
595#if LGE_EDGE_INTRA_DELTA_DC
596    if( bDelta ) 
597    {
598      Int iDeltaDC0 = pcCU->getEdgeDeltaDC0( uiAbsPartIdx );
599      Int iDeltaDC1 = pcCU->getEdgeDeltaDC1( uiAbsPartIdx );
600      xDeltaDCQuantScaleUp( pcCU, iDeltaDC0 );
601      xDeltaDCQuantScaleUp( pcCU, iDeltaDC1 );
602      iMean0 = Clip( iMean0 + iDeltaDC0 );
603      iMean1 = Clip( iMean1 + iDeltaDC1 );
604    }
605#endif
606    for( UInt ui = 0; ui < iHeight; ui++ )
607    {
608      for( UInt uii = 0; uii < iWidth; uii++ )
609      {
610        if( pbRegion[ uii + ui * iWidth ] == false )
611          pDst[ uii + ui * dstStride ] = iMean0;
612        else
613          pDst[ uii + ui * dstStride ] = iMean1;
614      }
615    }
616  }
617}
618#endif
619
620#if DEPTH_MAP_GENERATION
621#if MERL_VSP_C0152
622Void TComPrediction::motionCompensation( TComDataCU* pcCU, TComYuv* pcYuvPred, UInt uiAbsPartIdx, RefPicList eRefPicList, Int iPartIdx, Bool bPrdDepthMap, UInt uiSubSampExpX, UInt uiSubSampExpY )
623#else
624Void TComPrediction::motionCompensation( TComDataCU* pcCU, TComYuv* pcYuvPred, RefPicList eRefPicList, Int iPartIdx, Bool bPrdDepthMap, UInt uiSubSampExpX, UInt uiSubSampExpY )
625#endif
626#else
627#if MERL_VSP_C0152
628Void TComPrediction::motionCompensation ( TComDataCU* pcCU, TComYuv* pcYuvPred, UInt uiAbsPartIdx, RefPicList eRefPicList, Int iPartIdx )
629#else
630Void TComPrediction::motionCompensation ( TComDataCU* pcCU, TComYuv* pcYuvPred, RefPicList eRefPicList, Int iPartIdx )
631#endif
632#endif
633{
634  Int         iWidth;
635  Int         iHeight;
636  UInt        uiPartAddr;
637
638  if ( iPartIdx >= 0 )
639  {
640    pcCU->getPartIndexAndSize( iPartIdx, uiPartAddr, iWidth, iHeight );
641
642#if DEPTH_MAP_GENERATION
643    if( bPrdDepthMap )
644    {
645      iWidth  >>= uiSubSampExpX;
646      iHeight >>= uiSubSampExpY;
647    }
648#endif
649
650    if ( eRefPicList != REF_PIC_LIST_X )
651    {
652#if LGE_ILLUCOMP_B0045
653      if( pcCU->getSlice()->getPPS()->getUseWP() && !pcCU->getICFlag(uiPartAddr))
654#else
655      if( pcCU->getSlice()->getPPS()->getUseWP())
656#endif
657      {
658#if MERL_VSP_C0152
659        xPredInterUni (pcCU, uiPartAddr, uiAbsPartIdx+uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred, iPartIdx, bPrdDepthMap, uiSubSampExpX, uiSubSampExpY, true );
660#else
661        xPredInterUni (pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred, iPartIdx, bPrdDepthMap, uiSubSampExpX, uiSubSampExpY, true );
662#endif
663      }
664      else
665      {
666#if MERL_VSP_C0152
667        xPredInterUni (pcCU, uiPartAddr, uiAbsPartIdx+uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred, iPartIdx, bPrdDepthMap, uiSubSampExpX, uiSubSampExpY, false );
668#else       
669        xPredInterUni (pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred, iPartIdx, bPrdDepthMap, uiSubSampExpX, uiSubSampExpY, false );
670#endif
671      }
672#if LGE_ILLUCOMP_B0045
673      if( pcCU->getSlice()->getPPS()->getUseWP() && !pcCU->getICFlag(uiPartAddr) )
674#else
675      if ( pcCU->getSlice()->getPPS()->getUseWP() )
676#endif
677      {
678        xWeightedPredictionUni( pcCU, pcYuvPred, uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred, iPartIdx );
679      }
680    }
681    else
682    {
683      if( xCheckIdenticalMotion( pcCU, uiPartAddr ) && !bPrdDepthMap )
684      {
685#if MERL_VSP_C0152
686        xPredInterUni (pcCU, uiPartAddr, uiAbsPartIdx+uiPartAddr, iWidth, iHeight, REF_PIC_LIST_0, pcYuvPred, iPartIdx, bPrdDepthMap, uiSubSampExpX, uiSubSampExpY, false );
687#else
688        xPredInterUni (pcCU, uiPartAddr, iWidth, iHeight, REF_PIC_LIST_0, pcYuvPred, iPartIdx, bPrdDepthMap, uiSubSampExpX, uiSubSampExpY, false );
689#endif
690      }
691      else
692      {
693#if MERL_VSP_C0152
694        xPredInterBi  (pcCU, uiPartAddr, uiAbsPartIdx+uiPartAddr, iWidth, iHeight, uiSubSampExpX, uiSubSampExpY, pcYuvPred, iPartIdx, bPrdDepthMap );
695#else
696        xPredInterBi  (pcCU, uiPartAddr, iWidth, iHeight, uiSubSampExpX, uiSubSampExpY, pcYuvPred, iPartIdx, bPrdDepthMap );
697#endif
698      }
699    }
700    return;
701  }
702
703  for ( iPartIdx = 0; iPartIdx < pcCU->getNumPartInter(); iPartIdx++ )
704  {
705    pcCU->getPartIndexAndSize( iPartIdx, uiPartAddr, iWidth, iHeight );
706
707    if( bPrdDepthMap )
708    {
709      iWidth  >>= uiSubSampExpX;
710      iHeight >>= uiSubSampExpY;
711    }
712
713    if ( eRefPicList != REF_PIC_LIST_X )
714    {
715#if LGE_ILLUCOMP_B0045
716      if( pcCU->getSlice()->getPPS()->getUseWP() && !pcCU->getICFlag(uiPartAddr))
717#else
718      if( pcCU->getSlice()->getPPS()->getUseWP())
719#endif
720      {
721#if MERL_VSP_C0152
722        xPredInterUni (pcCU, uiPartAddr, uiAbsPartIdx+uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred, iPartIdx, bPrdDepthMap, uiSubSampExpX, uiSubSampExpY, true );
723#else
724        xPredInterUni (pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred, iPartIdx, bPrdDepthMap, uiSubSampExpX, uiSubSampExpY, true );
725#endif
726  }
727  else
728  {
729#if MERL_VSP_C0152
730        xPredInterUni (pcCU, uiPartAddr, uiAbsPartIdx+uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred, iPartIdx, bPrdDepthMap, uiSubSampExpX, uiSubSampExpY, false );
731#else
732        xPredInterUni (pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred, iPartIdx, bPrdDepthMap, uiSubSampExpX, uiSubSampExpY, false );
733#endif
734      }
735#if MERL_VSP_C0152
736      xPredInterUni (pcCU, uiPartAddr, uiAbsPartIdx+uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred, iPartIdx, bPrdDepthMap, uiSubSampExpX, uiSubSampExpY, false );
737#else
738      xPredInterUni (pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred, iPartIdx, bPrdDepthMap, uiSubSampExpX, uiSubSampExpY, false );
739#endif
740
741#if LGE_ILLUCOMP_B0045
742      if( pcCU->getSlice()->getPPS()->getUseWP() && !pcCU->getICFlag(uiPartAddr))
743#else
744      if( pcCU->getSlice()->getPPS()->getUseWP())
745#endif
746      {
747        xWeightedPredictionUni( pcCU, pcYuvPred, uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred, iPartIdx );
748      }
749    }
750    else
751    {
752      if ( xCheckIdenticalMotion( pcCU, uiPartAddr ) )
753      {
754#if MERL_VSP_C0152
755        xPredInterUni (pcCU, uiPartAddr, uiAbsPartIdx+uiPartAddr, iWidth, iHeight, REF_PIC_LIST_0, pcYuvPred, iPartIdx, bPrdDepthMap, uiSubSampExpX, uiSubSampExpY, false );
756#else
757        xPredInterUni (pcCU, uiPartAddr, iWidth, iHeight, REF_PIC_LIST_0, pcYuvPred, iPartIdx, bPrdDepthMap, uiSubSampExpX, uiSubSampExpY, false );
758#endif
759      }
760      else
761      {
762#if MERL_VSP_C0152
763        xPredInterBi  (pcCU, uiPartAddr, uiAbsPartIdx+uiPartAddr, iWidth, iHeight, uiSubSampExpX, uiSubSampExpY, pcYuvPred, iPartIdx, bPrdDepthMap );
764#else
765        xPredInterBi  (pcCU, uiPartAddr, iWidth, iHeight, uiSubSampExpX, uiSubSampExpY, pcYuvPred, iPartIdx, bPrdDepthMap );
766#endif   
767      }
768    }
769  }
770  return;
771}
772
773#if H3D_IVRP & !QC_ARP_D0177
774Void TComPrediction::residualPrediction(TComDataCU* pcCU, TComYuv* pcYuvPred, TComYuv* pcYuvResPred)
775{
776  Int         iWidth;
777  Int         iHeight;
778  UInt        uiPartAddr;
779
780  pcCU->getPartIndexAndSize( 0, uiPartAddr, iWidth, iHeight );
781
782  Bool bResAvail = false;
783
784  bResAvail = pcCU->getResidualSamples( 0, true, pcYuvResPred );
785
786  assert (bResAvail);
787
788  pcYuvPred->add(pcYuvResPred, iWidth, iHeight);
789}
790#endif
791
792#if MERL_General_Fix
793#if MERL_VSP_C0152
794// Function to perform VSP block compensation
795Void  TComPrediction::xPredInterVSPBlk(TComDataCU* pcCU, UInt uiPartAddr, UInt uiAbsPartIdx, Int iWidth, Int iHeight, TComMv cMv, RefPicList eRefPicList, TComYuv*& rpcYuvPred
796                                     , Bool bi
797#if !MERL_Bi_VSP_D0166
798                                     , Int vspIdx
799#endif
800                                       )
801{
802  TComPic*    pRefPicBaseTxt        = NULL;
803  TComPicYuv* pcBaseViewTxtPicYuv   = NULL;
804  TComPicYuv* pcBaseViewDepthPicYuv = NULL;
805  Int iBlkX = 0;
806  Int iBlkY = 0;
807  Int* pShiftLUT;
808  Int  iShiftPrec;
809
810#if !MERL_VSP_NBDV_RefVId_Fix_D0166
811  pRefPicBaseTxt        = pcCU->getSlice()->getRefPicBaseTxt();
812  pcBaseViewTxtPicYuv   = pRefPicBaseTxt->getPicYuvRec();
813  TComPic* pRefPicBaseDepth = pcCU->getSlice()->getRefPicBaseDepth();
814  pcBaseViewDepthPicYuv     = pRefPicBaseDepth->getPicYuvRec();
815
816  Int iBlkX = ( pcCU->getAddr() % pRefPicBaseDepth->getFrameWidthInCU() ) * g_uiMaxCUWidth  + g_auiRasterToPelX[ g_auiZscanToRaster[ uiAbsPartIdx ] ];
817  Int iBlkY = ( pcCU->getAddr() / pRefPicBaseDepth->getFrameWidthInCU() ) * g_uiMaxCUHeight + g_auiRasterToPelY[ g_auiZscanToRaster[ uiAbsPartIdx ] ];
818  pcCU->getSlice()->getBWVSPLUTParam(pShiftLUT, iShiftPrec);
819  xPredInterLumaBlkFromDM  ( pcBaseViewTxtPicYuv, pcBaseViewDepthPicYuv, pShiftLUT, iShiftPrec, &cMv, uiPartAddr, iBlkX,    iBlkY,    iWidth,    iHeight,    pcCU->getSlice()->getSPS()->isDepth(), rpcYuvPred );
820  xPredInterChromaBlkFromDM( pcBaseViewTxtPicYuv, pcBaseViewDepthPicYuv, pShiftLUT, iShiftPrec, &cMv, uiPartAddr, iBlkX>>1, iBlkY>>1, iWidth>>1, iHeight>>1, pcCU->getSlice()->getSPS()->isDepth(), rpcYuvPred );
821
822#else // MERL_VSP_NBDV_RefVId_Fix_D0166
823
824  //recover VSP reference frame according to negative refIdx number
825  RefPicList privateRefPicList = (RefPicList) pcCU->getVSPDir( uiPartAddr );
826  assert(privateRefPicList == REF_PIC_LIST_0 || privateRefPicList == REF_PIC_LIST_1);
827
828  // Step 1: get depth reference
829  Int  refIdx = -1-pcCU->getCUMvField( privateRefPicList )->getRefIdx( uiPartAddr ); // texture ref index, a trick when storing refIdx
830  Int  viewId = pcCU->getSlice()->getRefViewId(privateRefPicList, refIdx);  // texture view id
831  Int  refPoc = pcCU->getSlice()->getRefPOC(privateRefPicList, refIdx);     // texture POC
832  TComPic* pRefPicBaseDepth = pcCU->getSlice()->getDepthRefPic(viewId, refPoc);
833
834  pcBaseViewDepthPicYuv = pRefPicBaseDepth->getPicYuvRec();
835  assert(refPoc == pcCU->getSlice()->getPOC());
836  assert(pRefPicBaseDepth != NULL);
837  assert(pcBaseViewDepthPicYuv != NULL);
838
839  iBlkX = ( pcCU->getAddr() % pRefPicBaseDepth->getFrameWidthInCU() ) * g_uiMaxCUWidth  + g_auiRasterToPelX[ g_auiZscanToRaster[ uiAbsPartIdx ] ];
840  iBlkY = ( pcCU->getAddr() / pRefPicBaseDepth->getFrameWidthInCU() ) * g_uiMaxCUHeight + g_auiRasterToPelY[ g_auiZscanToRaster[ uiAbsPartIdx ] ];
841#if MERL_Bi_VSP_D0166
842  // Step 2: get texture reference
843  pRefPicBaseTxt = xGetVspRefTxt( pcCU, uiPartAddr, eRefPicList);
844  pcBaseViewTxtPicYuv = pRefPicBaseTxt->getPicYuvRec();
845  assert(pcBaseViewTxtPicYuv != NULL);
846
847  // initialize the LUT according to the reference view idx
848  pcCU->getSlice()->getBWVSPLUTParam(pShiftLUT, iShiftPrec, pRefPicBaseTxt->getViewId());
849
850  // Step 3: Do compensation
851  xPredInterLumaBlkFromDM  ( pcBaseViewTxtPicYuv, pcBaseViewDepthPicYuv, pShiftLUT, iShiftPrec, &cMv, uiPartAddr, iBlkX,    iBlkY,    iWidth,    iHeight,    pcCU->getSlice()->getSPS()->isDepth(), rpcYuvPred, bi );
852  xPredInterChromaBlkFromDM( pcBaseViewTxtPicYuv, pcBaseViewDepthPicYuv, pShiftLUT, iShiftPrec, &cMv, uiPartAddr, iBlkX>>1, iBlkY>>1, iWidth>>1, iHeight>>1, pcCU->getSlice()->getSPS()->isDepth(), rpcYuvPred, bi );
853#else
854  // Step 2: get texture reference
855  pRefPicBaseTxt = pcCU->getSlice()->getRefPic(privateRefPicList, refIdx);
856  pcBaseViewTxtPicYuv = pRefPicBaseTxt->getPicYuvRec();
857  assert(pcBaseViewTxtPicYuv != NULL);
858
859  //initialize the LUT according to the reference view idx
860  pcCU->getSlice()->getBWVSPLUTParam(pShiftLUT, iShiftPrec, pRefPicBaseTxt->getViewId());
861
862  // Step 3: Do compensation
863  xPredInterLumaBlkFromDM  ( pcBaseViewTxtPicYuv, pcBaseViewDepthPicYuv, pShiftLUT, iShiftPrec, &cMv, uiPartAddr, iBlkX,    iBlkY,    iWidth,    iHeight,    pcCU->getSlice()->getSPS()->isDepth(), vspIdx, rpcYuvPred );
864  xPredInterChromaBlkFromDM( pcBaseViewTxtPicYuv, pcBaseViewDepthPicYuv, pShiftLUT, iShiftPrec, &cMv, uiPartAddr, iBlkX>>1, iBlkY>>1, iWidth>>1, iHeight>>1, pcCU->getSlice()->getSPS()->isDepth(), vspIdx, rpcYuvPred );
865#endif
866
867#endif
868}
869
870#endif
871
872#if MERL_Bi_VSP_D0166
873TComPic*  TComPrediction::xGetVspRefTxt(TComDataCU* pcCU, UInt uiPartAddr, RefPicList eRefPicList)
874{
875  RefPicList  privateRefPicList = (RefPicList) pcCU->getVSPDir( uiPartAddr );
876  Int         refIdx = -1-pcCU->getCUMvField( privateRefPicList )->getRefIdx( uiPartAddr ); // texture ref index, a trick when storing refIdx
877  Int         viewId = pcCU->getSlice()->getRefViewId(privateRefPicList, refIdx);  // texture view id
878  TComPic*    refPic = NULL;
879
880  assert(privateRefPicList == REF_PIC_LIST_0 || privateRefPicList == REF_PIC_LIST_1);
881
882  if (privateRefPicList == eRefPicList)
883  {
884    Int  refIdxt = -1-pcCU->getCUMvField( eRefPicList )->getRefIdx( uiPartAddr );
885    assert(refIdxt>= 0);
886    refPic = pcCU->getSlice()->getRefPic(eRefPicList, refIdxt);
887  }
888  else
889  {
890    // Find the other interview reference in order to do VSP
891    RefPicList otherRefPicList = privateRefPicList == REF_PIC_LIST_0 ? REF_PIC_LIST_1 : REF_PIC_LIST_0;
892    Bool isFound = false;
893    for (Int iRefIdx = 0; iRefIdx <pcCU->getSlice()->getNumRefIdx(otherRefPicList); iRefIdx ++ )
894    {
895      Int refViewIdx  = pcCU->getSlice()->getRefViewId( otherRefPicList, iRefIdx);
896      if ( (refViewIdx != pcCU->getSlice()->getViewId()) && (refViewIdx != viewId ) )
897      {
898        refPic = pcCU->getSlice()->getRefPic(otherRefPicList, iRefIdx);
899        isFound = true;
900        break;
901      }
902    }
903
904    if (isFound == false)
905    {
906      Int  refIdxTxt = -1-pcCU->getCUMvField( privateRefPicList )->getRefIdx( uiPartAddr );
907      assert(refIdxTxt >= 0);
908      refPic = pcCU->getSlice()->getRefPic(privateRefPicList, refIdxTxt);
909    }
910    assert(isFound);
911  }
912  assert(refPic != NULL);
913  return refPic;
914}
915#endif
916#endif
917
918#if MERL_VSP_C0152
919Void TComPrediction::xPredInterUni ( TComDataCU* pcCU, UInt uiPartAddr, UInt uiAbsPartIdx, Int iWidth, Int iHeight, RefPicList eRefPicList, TComYuv*& rpcYuvPred, Int iPartIdx, Bool bPrdDepthMap, UInt uiSubSampExpX, UInt uiSubSampExpY, Bool bi )
920#else
921Void TComPrediction::xPredInterUni ( TComDataCU* pcCU, UInt uiPartAddr, Int iWidth, Int iHeight, RefPicList eRefPicList, TComYuv*& rpcYuvPred, Int iPartIdx, Bool bPrdDepthMap, UInt uiSubSampExpX, UInt uiSubSampExpY, Bool bi )
922#endif
923{
924#if MERL_VSP_C0152
925  Int  iRefIdx = pcCU->getCUMvField( eRefPicList )->getRefIdx( uiPartAddr );   
926  Int  vspIdx  = pcCU->getVSPIndex(uiPartAddr);
927  if (vspIdx != 0)
928  {
929#if !QC_BVSP_CleanUP_D0191
930    if (iRefIdx >= 0)
931    {
932      printf("vspIdx = %d, iRefIdx = %d\n", vspIdx, iRefIdx);
933    }
934    assert (iRefIdx < 0); // assert (iRefIdx == NOT_VALID);
935#endif
936  }
937  else
938  {
939    assert (iRefIdx >= 0);
940  }
941#else
942  Int         iRefIdx     = pcCU->getCUMvField( eRefPicList )->getRefIdx( uiPartAddr );           assert (iRefIdx >= 0);
943#endif
944
945  TComMv cMv = pcCU->getCUMvField( eRefPicList )->getMv( uiPartAddr );
946  pcCU->clipMv(cMv);
947
948#if DEPTH_MAP_GENERATION
949  if( bPrdDepthMap )
950  {
951    UInt uiRShift = 0;
952    if( pcCU->getPic()->getStoredPDMforV2() == 1 )
953      xPredInterPrdDepthMap( pcCU, pcCU->getSlice()->getRefPic( eRefPicList, iRefIdx )->getPredDepthMapTemp(), uiPartAddr, &cMv, iWidth, iHeight, uiSubSampExpX, uiSubSampExpY, rpcYuvPred, uiRShift, 0 );
954    else
955      xPredInterPrdDepthMap( pcCU, pcCU->getSlice()->getRefPic( eRefPicList, iRefIdx )->getPredDepthMap(), uiPartAddr, &cMv, iWidth, iHeight, uiSubSampExpX, uiSubSampExpY, rpcYuvPred, uiRShift, 0 );
956
957    return;
958  }
959#endif
960#if QC_ARP_D0177
961  if(
962#if MERL_General_Fix // TODO: Maybe logically redundant, but easier to read. Need verification before being removed
963#if MERL_VSP_C0152
964       vspIdx == 0 &&
965#endif
966#endif
967       pcCU->getSlice()->getSPS()->isDepth() == false
968    && pcCU->getSlice()->getSPS()->getViewId() > 0
969    && pcCU->getSlice()->getSPS()->getUseAdvRP() > 0
970    && pcCU->getARPW( uiPartAddr ) > 0 
971    && pcCU->getSlice()->getRefPic( eRefPicList, iRefIdx )->getPOC()!= pcCU->getSlice()->getPOC()
972    && (pcCU->getPartitionSize(uiPartAddr)==SIZE_2Nx2N || pcCU->isSkipped(uiPartAddr))
973    )
974  {
975    xPredInterUniARP( pcCU , uiPartAddr , iWidth , iHeight , eRefPicList , rpcYuvPred , iPartIdx , bi );
976  }
977  else
978  {
979#endif
980#if HHI_FULL_PEL_DEPTH_MAP_MV_ACC
981  if( pcCU->getSlice()->getSPS()->isDepth() )
982  {
983#if MERL_VSP_C0152
984    if (vspIdx != 0)
985    { // depth, vsp compensation
986#if !MERL_General_Fix
987      // get depth estimator here
988      TComPic* pRefPicBaseDepth = pcCU->getSlice()->getRefPicBaseDepth();
989      TComPicYuv* pcBaseViewDepthPicYuv = NULL;
990      if (vspIdx < 4) // spatial
991      {
992        pcBaseViewDepthPicYuv = pRefPicBaseDepth->getPicYuvRec();
993      }
994      Int iBlkX = ( pcCU->getAddr() % pRefPicBaseDepth->getFrameWidthInCU() ) * g_uiMaxCUWidth  + g_auiRasterToPelX[ g_auiZscanToRaster[ uiAbsPartIdx ] ];
995      Int iBlkY = ( pcCU->getAddr() / pRefPicBaseDepth->getFrameWidthInCU() ) * g_uiMaxCUHeight + g_auiRasterToPelY[ g_auiZscanToRaster[ uiAbsPartIdx ] ];
996      Int* pShiftLUT;
997      Int iShiftPrec;
998      pcCU->getSlice()->getBWVSPLUTParam(pShiftLUT, iShiftPrec);
999      //using disparity to find the depth block of the base view as the depth block estimator of the current block
1000      //using depth block estimator and base view texture to get Backward warping
1001      xPredInterLumaBlkFromDM  ( pcBaseViewDepthPicYuv, pcBaseViewDepthPicYuv, pShiftLUT, iShiftPrec, &cMv, uiPartAddr, iBlkX,    iBlkY,    iWidth,    iHeight,     pcCU->getSlice()->getSPS()->isDepth(), vspIdx, rpcYuvPred );
1002      xPredInterChromaBlkFromDM( pcBaseViewDepthPicYuv, pcBaseViewDepthPicYuv, pShiftLUT, iShiftPrec, &cMv, uiPartAddr, iBlkX>>1, iBlkY>>1, iWidth>>1, iHeight>>1,  pcCU->getSlice()->getSPS()->isDepth(), vspIdx, rpcYuvPred );
1003#else
1004#if MERL_Bi_VSP_D0166
1005      xPredInterVSPBlk(pcCU, uiPartAddr, uiAbsPartIdx, iWidth, iHeight, cMv, eRefPicList, rpcYuvPred, bi );
1006#else
1007      xPredInterVSPBlk(pcCU, uiPartAddr, uiAbsPartIdx, iWidth, iHeight, cMv, eRefPicList, rpcYuvPred, bi, vspIdx );
1008#endif
1009#endif
1010    }
1011    else
1012    {
1013#endif
1014      UInt uiRShift = ( bi ? 14-g_uiBitDepth-g_uiBitIncrement : 0 );
1015      UInt uiOffset = bi ? IF_INTERNAL_OFFS : 0;
1016#if LGE_ILLUCOMP_DEPTH_C0046
1017    Bool bICFlag = pcCU->getICFlag(uiPartAddr) && (pcCU->getSlice()->getRefViewId( eRefPicList, iRefIdx ) != pcCU->getSlice()->getViewId());
1018#endif
1019#if DEPTH_MAP_GENERATION
1020    xPredInterPrdDepthMap( pcCU, pcCU->getSlice()->getRefPic( eRefPicList, iRefIdx )->getPicYuvRec(), uiPartAddr, &cMv, iWidth, iHeight, 0, 0, rpcYuvPred, uiRShift, uiOffset
1021#if LGE_ILLUCOMP_DEPTH_C0046
1022        , bICFlag
1023#endif
1024        );
1025#else
1026      xPredInterPrdDepthMap( pcCU, pcCU->getSlice()->getRefPic( eRefPicList, iRefIdx )->getPicYuvRec(), uiPartAddr, &cMv, iWidth, iHeight, rpcYuvPred, uiRShift, uiOffset );
1027#endif
1028#if MERL_VSP_C0152
1029    }
1030#endif// MERL_VSP_C0152 //else
1031  }
1032  else  // texture
1033  {
1034#endif
1035#if MERL_VSP_C0152
1036    if ( vspIdx != 0 )
1037    { // texture, vsp compensation
1038#if !MERL_General_Fix
1039      TComPic*    pRefPicBaseTxt        = pcCU->getSlice()->getRefPicBaseTxt();
1040      TComPicYuv* pcBaseViewTxtPicYuv   = pRefPicBaseTxt->getPicYuvRec();
1041      TComPicYuv* pcBaseViewDepthPicYuv = NULL;
1042      if (vspIdx < 4) // spatial
1043      {
1044        TComPic* pRefPicBaseDepth = pcCU->getSlice()->getRefPicBaseDepth();
1045        pcBaseViewDepthPicYuv     = pRefPicBaseDepth->getPicYuvRec();
1046      }
1047      Int iBlkX = ( pcCU->getAddr() % pRefPicBaseTxt->getFrameWidthInCU() ) * g_uiMaxCUWidth  + g_auiRasterToPelX[ g_auiZscanToRaster[ uiAbsPartIdx ] ];
1048      Int iBlkY = ( pcCU->getAddr() / pRefPicBaseTxt->getFrameWidthInCU() ) * g_uiMaxCUHeight + g_auiRasterToPelY[ g_auiZscanToRaster[ uiAbsPartIdx ] ];
1049      Int* pShiftLUT;
1050      Int iShiftPrec;
1051      pcCU->getSlice()->getBWVSPLUTParam(pShiftLUT, iShiftPrec);
1052
1053      //using disparity to find the depth block of the base view as the depth block estimator of the current block
1054      //using depth block estimator and base view texture to get Backward warping
1055      xPredInterLumaBlkFromDM  ( pcBaseViewTxtPicYuv, pcBaseViewDepthPicYuv, pShiftLUT, iShiftPrec, &cMv, uiPartAddr, iBlkX,    iBlkY,    iWidth,    iHeight,    pcCU->getSlice()->getSPS()->isDepth(), vspIdx, rpcYuvPred );
1056      xPredInterChromaBlkFromDM( pcBaseViewTxtPicYuv, pcBaseViewDepthPicYuv, pShiftLUT, iShiftPrec, &cMv, uiPartAddr, iBlkX>>1, iBlkY>>1, iWidth>>1, iHeight>>1, pcCU->getSlice()->getSPS()->isDepth(), vspIdx, rpcYuvPred );
1057#else
1058#if MERL_Bi_VSP_D0166
1059      xPredInterVSPBlk(pcCU, uiPartAddr, uiAbsPartIdx, iWidth, iHeight, cMv, eRefPicList, rpcYuvPred, bi );
1060#else
1061      xPredInterVSPBlk(pcCU, uiPartAddr, uiAbsPartIdx, iWidth, iHeight, cMv, eRefPicList, rpcYuvPred, bi, vspIdx );
1062#endif
1063#endif
1064    }
1065    else//texture not VSP
1066    {
1067#endif //MERL_VSP_C0152
1068#if LGE_ILLUCOMP_B0045
1069      Bool bICFlag = pcCU->getICFlag(uiPartAddr) && (pcCU->getSlice()->getRefViewId( eRefPicList, iRefIdx ) != pcCU->getSlice()->getViewId());
1070
1071      xPredInterLumaBlk  ( pcCU, pcCU->getSlice()->getRefPic( eRefPicList, iRefIdx )->getPicYuvRec(), uiPartAddr, &cMv, iWidth, iHeight, rpcYuvPred, bi, bICFlag);
1072#else
1073      xPredInterLumaBlk  ( pcCU, pcCU->getSlice()->getRefPic( eRefPicList, iRefIdx )->getPicYuvRec(), uiPartAddr, &cMv, iWidth, iHeight, rpcYuvPred, bi );
1074#endif
1075#if MERL_VSP_C0152
1076     } //texture not VSP
1077#endif
1078#if HHI_FULL_PEL_DEPTH_MAP_MV_ACC
1079  }
1080#endif
1081
1082#if MERL_VSP_C0152
1083  if ( vspIdx == 0 )//Not VSP
1084  {
1085#endif
1086#if LGE_ILLUCOMP_B0045
1087  Bool bICFlag = pcCU->getICFlag(uiPartAddr) && (pcCU->getSlice()->getRefViewId( eRefPicList, iRefIdx ) != pcCU->getSlice()->getViewId());
1088
1089  xPredInterChromaBlk( pcCU, pcCU->getSlice()->getRefPic( eRefPicList, iRefIdx )->getPicYuvRec(), uiPartAddr, &cMv, iWidth, iHeight, rpcYuvPred, bi, bICFlag );
1090#else
1091  xPredInterChromaBlk( pcCU, pcCU->getSlice()->getRefPic( eRefPicList, iRefIdx )->getPicYuvRec(), uiPartAddr, &cMv, iWidth, iHeight, rpcYuvPred, bi );
1092#endif
1093#if MERL_VSP_C0152
1094   }
1095#endif
1096#if QC_ARP_D0177
1097  }
1098#endif
1099}
1100
1101#if QC_ARP_D0177
1102Void TComPrediction::xPredInterUniARP( TComDataCU* pcCU, UInt uiPartAddr, Int iWidth, Int iHeight, RefPicList eRefPicList, TComYuv*& rpcYuvPred, Int iPartIdx, Bool bi, TComMvField * pNewMvFiled )
1103{
1104  Int         iRefIdx     = pcCU->getCUMvField( eRefPicList )->getRefIdx( uiPartAddr );           
1105  TComMv      cMv         = pcCU->getCUMvField( eRefPicList )->getMv( uiPartAddr );
1106  Bool        bTobeScaled = false;
1107  UChar dW = pcCU->getARPW ( uiPartAddr );
1108  TComPic* pcPicYuvBaseCol =  NULL;
1109  TComPic* pcPicYuvBaseRef =  NULL;
1110  DisInfo cDistparity;
1111
1112  if( pNewMvFiled )
1113  {
1114    iRefIdx = pNewMvFiled->getRefIdx(); 
1115    cMv = pNewMvFiled->getMv();
1116  }
1117
1118#if QC_CU_NBDV_D0181
1119  cDistparity.bDV           = pcCU->getDvInfo(uiPartAddr).bDV;
1120  if( cDistparity.bDV )
1121  {
1122#if MERL_VSP_C0152
1123    cDistparity.m_acMvCand[0] = pcCU->getDvInfo(0).m_acMvCandNoRef[0];
1124#else
1125    cDistparity.m_acMvCand[0] = pcCU->getDvInfo(0).m_acMvCand[0];
1126#endif
1127    assert(pcCU->getDvInfo(uiPartAddr).bDV ==  pcCU->getDvInfo(0).bDV);
1128    cDistparity.m_aVIdxCan[0] = pcCU->getDvInfo(uiPartAddr).m_aVIdxCan[0];
1129    cDistparity.iN            = pcCU->getDvInfo(uiPartAddr).iN;
1130  }
1131  else
1132    cDistparity.iN    =  0;
1133#else
1134  pcCU->getDisMvpCandNBDV( iPartIdx, uiPartAddr,  &cDistparity, false );
1135#endif
1136
1137  dW = !cDistparity.iN ? 0: dW;
1138  if( cDistparity.iN ) 
1139  {
1140    if(dW > 0 && pcCU->getSlice()->getRefPic( eRefPicList, 0 )->getPOC()!= pcCU->getSlice()->getPOC())
1141      bTobeScaled = true;
1142    pcPicYuvBaseCol =  pcCU->getSlice()->getBaseViewRefPic( pcCU->getSlice()->getPOC(),                              cDistparity.m_aVIdxCan[0] );
1143    pcPicYuvBaseRef =  pcCU->getSlice()->getBaseViewRefPic( pcCU->getSlice()->getRefPic( eRefPicList, 0 )->getPOC(), cDistparity.m_aVIdxCan[0] );
1144    if( (!pcPicYuvBaseCol || pcPicYuvBaseCol->getPOC() != pcCU->getSlice()->getPOC()) || (!pcPicYuvBaseRef || pcPicYuvBaseRef->getPOC() != pcCU->getSlice()->getRefPic( eRefPicList, 0 )->getPOC() ))
1145    {
1146      dW = 0;
1147      bTobeScaled = false;
1148    }
1149    else
1150      assert( pcPicYuvBaseCol->getPOC() == pcCU->getSlice()->getPOC() && pcPicYuvBaseRef->getPOC() == pcCU->getSlice()->getRefPic( eRefPicList, 0 )->getPOC() );
1151    if(bTobeScaled)
1152    {     
1153      Int iCurrPOC = pcCU->getSlice()->getPOC();
1154      Int iColRefPOC  = pcCU->getSlice()->getRefPOC( eRefPicList, iRefIdx );
1155      Int iCurrRefPOC = pcCU->getSlice()->getRefPOC( eRefPicList,  0);
1156      Int iScale = pcCU-> xGetDistScaleFactor(iCurrPOC, iCurrRefPOC, iCurrPOC, iColRefPOC);
1157      if ( iScale != 4096 )
1158        cMv = cMv.scaleMv( iScale );
1159      iRefIdx = 0;
1160    }
1161  }
1162  pcCU->clipMv(cMv);
1163  TComPicYuv* pcPicYuvRef = pcCU->getSlice()->getRefPic( eRefPicList, iRefIdx )->getPicYuvRec();
1164  xPredInterLumaBlk  ( pcCU, pcPicYuvRef, uiPartAddr, &cMv, iWidth, iHeight, rpcYuvPred, bi
1165#if LGE_ILLUCOMP_B0045
1166    , false
1167#endif
1168    , true 
1169    );
1170  xPredInterChromaBlk( pcCU, pcPicYuvRef, uiPartAddr, &cMv, iWidth, iHeight, rpcYuvPred, bi
1171#if LGE_ILLUCOMP_B0045
1172    , false
1173#endif
1174    , true
1175    );
1176  if( dW > 0 )
1177  {
1178    TComYuv * pYuvmB0 = &m_acYuvPredBase[0];
1179    TComYuv * pYuvB1  = &m_acYuvPredBase[1];
1180    assert ( cDistparity.iN == 1 );
1181    pcPicYuvRef = pcPicYuvBaseCol->getPicYuvRec();
1182    xPredInterLumaBlk  ( pcCU, pcPicYuvRef, uiPartAddr, &cDistparity.m_acMvCand[0], iWidth, iHeight, pYuvB1, bi
1183#if LGE_ILLUCOMP_B0045
1184      , false
1185#endif
1186      ,  true
1187      );
1188    xPredInterChromaBlk( pcCU, pcPicYuvRef, uiPartAddr, &cDistparity.m_acMvCand[0], iWidth, iHeight, pYuvB1, bi
1189#if LGE_ILLUCOMP_B0045
1190      , false
1191#endif
1192      , true
1193      );
1194    pcPicYuvRef = pcPicYuvBaseRef->getPicYuvRec();
1195    TComMv cMVwithDisparity = cMv + cDistparity.m_acMvCand[0];
1196    pcCU->clipMv(cMVwithDisparity);
1197    xPredInterLumaBlk  ( pcCU, pcPicYuvRef, uiPartAddr, &cMVwithDisparity, iWidth, iHeight, pYuvmB0, bi
1198#if LGE_ILLUCOMP_B0045
1199      , false
1200#endif
1201      , true
1202      );
1203    xPredInterChromaBlk( pcCU, pcPicYuvRef, uiPartAddr, &cMVwithDisparity, iWidth, iHeight, pYuvmB0, bi
1204#if LGE_ILLUCOMP_B0045
1205      , false
1206#endif
1207      , true
1208      );
1209    pYuvB1->subtractARP( pYuvB1 , pYuvmB0 , uiPartAddr , iWidth , iHeight );
1210    if(dW == 2)
1211      pYuvB1->multiplyARP( uiPartAddr , iWidth , iHeight , dW );
1212    rpcYuvPred->addARP( rpcYuvPred , pYuvB1 , uiPartAddr , iWidth , iHeight , !bi );
1213  }
1214}
1215#endif
1216
1217#if MERL_VSP_C0152
1218Void TComPrediction::xPredInterBi ( TComDataCU* pcCU, UInt uiPartAddr, UInt uiAbsPartIdx, Int iWidth, Int iHeight, UInt uiSubSampExpX, UInt uiSubSampExpY, TComYuv*& rpcYuvPred, Int iPartIdx, Bool bPrdDepthMap )
1219#else
1220Void TComPrediction::xPredInterBi ( TComDataCU* pcCU, UInt uiPartAddr, Int iWidth, Int iHeight, UInt uiSubSampExpX, UInt uiSubSampExpY, TComYuv*& rpcYuvPred, Int iPartIdx, Bool bPrdDepthMap )
1221#endif
1222{
1223  TComYuv* pcMbYuv;
1224  Int      iRefIdx[2] = {-1, -1};
1225
1226#if MERL_Bi_VSP_D0166
1227  Bool biDecision = 0;
1228  Int  predDirVSP = 0;
1229  if (pcCU->getVSPIndex(uiPartAddr) != 0) // is VSP
1230  {
1231    Int biVSPAvail = 0;
1232    //test whether VSP is Bi or Uni
1233    //Step1. Get derived DV view id
1234    RefPicList privateRefPicList = (RefPicList) pcCU->getVSPDir( uiPartAddr );
1235    RefPicList otherRefPicList = privateRefPicList == REF_PIC_LIST_0 ? REF_PIC_LIST_1 : REF_PIC_LIST_0;
1236    assert(privateRefPicList == REF_PIC_LIST_0 || privateRefPicList == REF_PIC_LIST_1);
1237    Int  refIdx = -1-pcCU->getCUMvField( privateRefPicList )->getRefIdx( uiPartAddr );
1238    assert(refIdx >= 0);
1239    Int  viewId = pcCU->getSlice()->getRefViewId(privateRefPicList, refIdx);
1240    Int  refPoc = pcCU->getSlice()->getRefPOC(privateRefPicList, refIdx);
1241
1242    assert(refPoc == pcCU->getSlice()->getPOC());
1243//    if(refPoc != pcCU->getSlice()->getPOC() )
1244//    {
1245//      printf("refPOC= %d, and current POC=%d\n", refPoc, pcCU->getSlice()->getPOC() );
1246//    }
1247    //Step 2. Get initial prediction direction value according to reference picture list availability
1248    Int iInterDir = ((pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_0) > 0 && pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_1) > 0) ? 3 :
1249      (pcCU->getSlice()->getNumRefIdx(REF_PIC_LIST_0) > 0 ? 1 : 2)); 
1250    //Step 3.  Check the availability of Bi VSP by checking the interview reference availability in the other reference list
1251    if(iInterDir == 3)
1252    {
1253      for (Int jRefIdx = 0; jRefIdx <pcCU->getSlice()->getNumRefIdx(otherRefPicList); jRefIdx++ )
1254      {
1255        Int refViewIdx  = pcCU->getSlice()->getRefViewId( otherRefPicList, jRefIdx);
1256        if ( (refViewIdx != pcCU->getSlice()->getViewId()) && (refViewIdx != viewId ) )
1257        {
1258          biVSPAvail = 1;
1259          break;
1260        }
1261      }
1262    }
1263    //Step 4. Update the Bi VSP prediction direction
1264    if ( iInterDir == 3 && biVSPAvail == 1)
1265    {
1266      biDecision   = 1;
1267      predDirVSP = 3;
1268    }
1269    else
1270    {
1271      biDecision = 0;
1272      if ( privateRefPicList == REF_PIC_LIST_0 )
1273        predDirVSP = 1;
1274      else
1275        predDirVSP = 2;
1276    }
1277  }
1278  else 
1279  {//not VSP
1280    if( ( pcCU->getCUMvField( REF_PIC_LIST_0 )->getRefIdx( uiPartAddr ) >= 0 && pcCU->getCUMvField( REF_PIC_LIST_1 )->getRefIdx( uiPartAddr ) >= 0 ) )
1281      biDecision = 1;
1282    else
1283      biDecision = 0;
1284  }
1285#endif
1286
1287  for ( Int iRefList = 0; iRefList < 2; iRefList++ )
1288  {
1289    RefPicList eRefPicList = (iRefList ? REF_PIC_LIST_1 : REF_PIC_LIST_0);
1290    iRefIdx[iRefList] = pcCU->getCUMvField( eRefPicList )->getRefIdx( uiPartAddr );
1291
1292#if MERL_VSP_C0152
1293    if(!pcCU->getVSPIndex(uiPartAddr))
1294    {
1295      if ( iRefIdx[iRefList] < 0 )
1296      {
1297        continue;
1298      }
1299    }
1300    else
1301    {
1302
1303#if !MERL_Bi_VSP_D0166 //both lists should go
1304      if ( iRefList == REF_PIC_LIST_1 && iRefIdx[iRefList] < 0 ) // iRefIdx[iRefList] ==NOT_VALID
1305      {
1306        continue;
1307      }
1308#else
1309      //Reference list loop termination
1310      RefPicList privateVSPRefPicList = (RefPicList) pcCU->getVSPDir( uiPartAddr );
1311      if( (pcCU->getVSPIndex(uiPartAddr)!=0) &&  iRefList != privateVSPRefPicList && !biDecision  ) 
1312      {//when VSP mode, if it is uni prediction, the other reference list should skip
1313        continue;
1314      }
1315#endif
1316
1317    }
1318#else
1319    if ( iRefIdx[iRefList] < 0 )
1320    {
1321      continue;
1322    }
1323#endif
1324
1325    assert( iRefIdx[iRefList] < pcCU->getSlice()->getNumRefIdx(eRefPicList) );
1326
1327    pcMbYuv = &m_acYuvPred[iRefList];
1328
1329#if MERL_Bi_VSP_D0166
1330    if(biDecision == 1)
1331#else
1332    if( pcCU->getCUMvField( REF_PIC_LIST_0 )->getRefIdx( uiPartAddr ) >= 0 && pcCU->getCUMvField( REF_PIC_LIST_1 )->getRefIdx( uiPartAddr ) >= 0 )
1333#endif
1334    {
1335#if MERL_VSP_C0152
1336      xPredInterUni ( pcCU, uiPartAddr, uiAbsPartIdx, iWidth, iHeight, eRefPicList, pcMbYuv, iPartIdx, bPrdDepthMap, uiSubSampExpX, uiSubSampExpY, true );
1337#else
1338      xPredInterUni ( pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, pcMbYuv, iPartIdx, bPrdDepthMap, uiSubSampExpX, uiSubSampExpY, true );
1339#endif
1340    }
1341    else
1342    {
1343#if FIX_LGE_WP_FOR_3D_C0223
1344      if ( ( pcCU->getSlice()->getPPS()->getUseWP()      && pcCU->getSlice()->getSliceType() == P_SLICE ) || 
1345         ( pcCU->getSlice()->getPPS()->getWPBiPredIdc() && pcCU->getSlice()->getSliceType() == B_SLICE ) )
1346#else
1347      if ( pcCU->getSlice()->getPPS()->getWPBiPredIdc() )
1348#endif
1349      {
1350#if MERL_VSP_C0152
1351        xPredInterUni ( pcCU, uiPartAddr, uiAbsPartIdx, iWidth, iHeight, eRefPicList, pcMbYuv, iPartIdx, bPrdDepthMap, uiSubSampExpX, uiSubSampExpY, true );
1352#else
1353        xPredInterUni ( pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, pcMbYuv, iPartIdx, bPrdDepthMap, uiSubSampExpX, uiSubSampExpY, true );
1354#endif
1355      }
1356      else
1357      {
1358#if MERL_VSP_C0152
1359        xPredInterUni ( pcCU, uiPartAddr, uiAbsPartIdx, iWidth, iHeight, eRefPicList, pcMbYuv, iPartIdx, bPrdDepthMap, uiSubSampExpX, uiSubSampExpY, false );
1360#else
1361        xPredInterUni ( pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, pcMbYuv, iPartIdx, bPrdDepthMap, uiSubSampExpX, uiSubSampExpY, false );
1362#endif
1363      }
1364    }
1365  }
1366#if FIX_LGE_WP_FOR_3D_C0223
1367  if ( pcCU->getSlice()->getPPS()->getWPBiPredIdc() && pcCU->getSlice()->getSliceType() == B_SLICE  )
1368#else
1369  if ( pcCU->getSlice()->getPPS()->getWPBiPredIdc() )
1370#endif
1371  {
1372#if MERL_VSP_C0152
1373#if !MERL_Bi_VSP_D0166
1374    if(pcCU->getVSPIndex(uiPartAddr))
1375      m_acYuvPred[0].copyPartToPartYuv( rpcYuvPred, uiPartAddr, iWidth, iHeight );
1376    else
1377#endif
1378#endif
1379    xWeightedPredictionBi( pcCU, &m_acYuvPred[0], &m_acYuvPred[1], iRefIdx[0], iRefIdx[1], uiPartAddr, iWidth, iHeight, rpcYuvPred );
1380  }
1381#if FIX_LGE_WP_FOR_3D_C0223
1382  else if ( pcCU->getSlice()->getPPS()->getUseWP() && pcCU->getSlice()->getSliceType() == P_SLICE )
1383
1384  {
1385#if MERL_VSP_C0152
1386#if !MERL_Bi_VSP_D0166
1387    if(pcCU->getVSPIndex(uiPartAddr))
1388      m_acYuvPred[0].copyPartToPartYuv( rpcYuvPred, uiPartAddr, iWidth, iHeight );
1389    else
1390#endif
1391#endif
1392      xWeightedPredictionUni( pcCU, &m_acYuvPred[0], uiPartAddr, iWidth, iHeight, REF_PIC_LIST_0, rpcYuvPred, iPartIdx ); 
1393  }
1394#endif
1395  else
1396  {
1397    if ( bPrdDepthMap )
1398    {
1399      xWeightedAveragePdm( pcCU, &m_acYuvPred[0], &m_acYuvPred[1], iRefIdx[0], iRefIdx[1], uiPartAddr, iWidth, iHeight, rpcYuvPred, uiSubSampExpX, uiSubSampExpY );
1400    }
1401    else
1402    {
1403#if MERL_VSP_C0152
1404#if !MERL_Bi_VSP_D0166
1405      if(pcCU->getVSPIndex(uiPartAddr))
1406        m_acYuvPred[0].copyPartToPartYuv( rpcYuvPred, uiPartAddr, iWidth, iHeight );
1407      else
1408        xWeightedAverage( pcCU, &m_acYuvPred[0], &m_acYuvPred[1], iRefIdx[0], iRefIdx[1], uiPartAddr, iWidth, iHeight, rpcYuvPred );
1409#else
1410      xWeightedAverage( pcCU, &m_acYuvPred[0], &m_acYuvPred[1], iRefIdx[0], iRefIdx[1], uiPartAddr, iWidth, iHeight, rpcYuvPred, predDirVSP );
1411#endif
1412#else
1413      xWeightedAverage( pcCU, &m_acYuvPred[0], &m_acYuvPred[1], iRefIdx[0], iRefIdx[1], uiPartAddr, iWidth, iHeight, rpcYuvPred );
1414#endif
1415    }
1416  }
1417}
1418
1419
1420
1421Void
1422TComPrediction::xPredInterPrdDepthMap( TComDataCU* pcCU, TComPicYuv* pcPicYuvRef, UInt uiPartAddr, TComMv* pcMv, Int iWidth, Int iHeight, UInt uiSubSampExpX, UInt uiSubSampExpY, TComYuv*& rpcYuv, UInt uiRShift, UInt uiOffset
1423#if LGE_ILLUCOMP_DEPTH_C0046
1424, Bool bICFlag
1425#endif
1426)
1427{
1428  Int     iShiftX     = 2 + uiSubSampExpX;
1429  Int     iShiftY     = 2 + uiSubSampExpY;
1430  Int     iAddX       = ( 1 << iShiftX ) >> 1;
1431  Int     iAddY       = ( 1 << iShiftY ) >> 1;
1432  Int     iHor        = ( pcMv->getHor() + iAddX ) >> iShiftX;
1433  Int     iVer        = ( pcMv->getVer() + iAddY ) >> iShiftY;
1434#if HHI_FULL_PEL_DEPTH_MAP_MV_ACC
1435  if( pcCU->getSlice()->getSPS()->isDepth() )
1436  {
1437    iHor = pcMv->getHor();
1438    iVer = pcMv->getVer();
1439  }
1440#endif
1441  Int     iRefStride  = pcPicYuvRef->getStride();
1442  Int     iDstStride  = rpcYuv->getStride();
1443  Int     iRefOffset  = iHor + iVer * iRefStride;
1444
1445  Pel*    piRefY      = pcPicYuvRef->getLumaAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() + uiPartAddr ) + iRefOffset;
1446  Pel*    piDstY      = rpcYuv->getLumaAddr( uiPartAddr );
1447
1448  for( Int y = 0; y < iHeight; y++, piDstY += iDstStride, piRefY += iRefStride )
1449  {
1450    for( Int x = 0; x < iWidth; x++ )
1451    {
1452      piDstY[ x ] = ( piRefY[ x ] << uiRShift ) - uiOffset;
1453    }
1454  }
1455
1456#if LGE_ILLUCOMP_DEPTH_C0046
1457  if(bICFlag)
1458  {
1459    Int a, b, iShift;
1460    TComMv tTmpMV(pcMv->getHor()<<2, pcMv->getVer()<<2);
1461
1462    piRefY      = pcPicYuvRef->getLumaAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() + uiPartAddr ) + iRefOffset;
1463    piDstY      = rpcYuv->getLumaAddr( uiPartAddr );
1464
1465    xGetLLSICPrediction(pcCU, &tTmpMV, pcPicYuvRef, a, b, iShift);
1466
1467    for( Int y = 0; y < iHeight; y++, piDstY += iDstStride, piRefY += iRefStride )
1468    {
1469      for( Int x = 0; x < iWidth; x++ )
1470      {
1471        if(uiOffset)
1472        {
1473          Int iIFshift = IF_INTERNAL_PREC - ( g_uiBitDepth + g_uiBitIncrement );
1474          piDstY[ x ] = ( (a*piDstY[ x ]+a*IF_INTERNAL_OFFS) >> iShift ) + b*(1<<iIFshift) - IF_INTERNAL_OFFS;
1475        }
1476        else
1477          piDstY[ x ] = Clip( ( (a*piDstY[ x ]) >> iShift ) + b );
1478      }
1479    }
1480  }
1481#endif
1482}
1483
1484
1485/**
1486 * \brief Generate motion-compensated luma block
1487 *
1488 * \param cu       Pointer to current CU
1489 * \param refPic   Pointer to reference picture
1490 * \param partAddr Address of block within CU
1491 * \param mv       Motion vector
1492 * \param width    Width of block
1493 * \param height   Height of block
1494 * \param dstPic   Pointer to destination picture
1495 * \param bi       Flag indicating whether bipred is used
1496 */
1497#if LGE_ILLUCOMP_B0045
1498Void TComPrediction::xPredInterLumaBlk( TComDataCU *cu, TComPicYuv *refPic, UInt partAddr, TComMv *mv, Int width, Int height, TComYuv *&dstPic, Bool bi, Bool bICFlag
1499#if QC_ARP_D0177
1500    ,
1501    Int filterType
1502#endif
1503    )
1504#else
1505Void TComPrediction::xPredInterLumaBlk( TComDataCU *cu, TComPicYuv *refPic, UInt partAddr, TComMv *mv, Int width, Int height, TComYuv *&dstPic, Bool bi
1506#if QC_ARP_D0177
1507    ,
1508    Int filterType
1509#endif
1510    )
1511#endif
1512{
1513  Int refStride = refPic->getStride(); 
1514  Int refOffset = ( mv->getHor() >> 2 ) + ( mv->getVer() >> 2 ) * refStride;
1515  Pel *ref      = refPic->getLumaAddr( cu->getAddr(), cu->getZorderIdxInCU() + partAddr ) + refOffset;
1516 
1517  Int dstStride = dstPic->getStride();
1518  Pel *dst      = dstPic->getLumaAddr( partAddr );
1519 
1520  Int xFrac = mv->getHor() & 0x3;
1521  Int yFrac = mv->getVer() & 0x3;
1522
1523#if HHI_FULL_PEL_DEPTH_MAP_MV_ACC
1524  assert( ! cu->getSlice()->getIsDepth() || ( xFrac == 0 && yFrac == 0 ) );
1525#endif
1526
1527  if ( yFrac == 0 )
1528  {
1529    m_if.filterHorLuma( ref, refStride, dst, dstStride, width, height, xFrac,       !bi
1530#if QC_ARP_D0177
1531    ,
1532    filterType
1533#endif
1534    );
1535  }
1536  else if ( xFrac == 0 )
1537  {
1538    m_if.filterVerLuma( ref, refStride, dst, dstStride, width, height, yFrac, true, !bi
1539#if QC_ARP_D0177
1540    ,
1541    filterType
1542#endif
1543    );
1544  }
1545  else
1546  {
1547    Int tmpStride = m_filteredBlockTmp[0].getStride();
1548    Short *tmp    = m_filteredBlockTmp[0].getLumaAddr();
1549
1550    Int filterSize = NTAPS_LUMA;
1551    Int halfFilterSize = ( filterSize >> 1 );
1552
1553    m_if.filterHorLuma(ref - (halfFilterSize-1)*refStride, refStride, tmp, tmpStride, width, height+filterSize-1, xFrac, false     
1554 #if QC_ARP_D0177
1555    ,
1556    filterType
1557#endif
1558    );
1559    m_if.filterVerLuma(tmp + (halfFilterSize-1)*tmpStride, tmpStride, dst, dstStride, width, height,              yFrac, false, !bi
1560 #if QC_ARP_D0177
1561    ,
1562    filterType
1563#endif
1564    );   
1565  }
1566
1567#if LGE_ILLUCOMP_B0045
1568  if(bICFlag)
1569  {
1570    Int a, b, iShift, i, j;
1571
1572    xGetLLSICPrediction(cu, mv, refPic, a, b, iShift);
1573
1574    for (i = 0; i < height; i++)
1575    {
1576      for (j = 0; j < width; j++)
1577      {
1578        if(bi)
1579        {
1580          Int iIFshift = IF_INTERNAL_PREC - ( g_uiBitDepth + g_uiBitIncrement );
1581          dst[j] = ( (a*dst[j]+a*IF_INTERNAL_OFFS) >> iShift ) + b*(1<<iIFshift) - IF_INTERNAL_OFFS;
1582        }
1583        else
1584          dst[j] = Clip( ( (a*dst[j]) >> iShift ) + b );
1585      }
1586      dst += dstStride;
1587    }
1588  }
1589#endif
1590}
1591
1592/**
1593 * \brief Generate motion-compensated chroma block
1594 *
1595 * \param cu       Pointer to current CU
1596 * \param refPic   Pointer to reference picture
1597 * \param partAddr Address of block within CU
1598 * \param mv       Motion vector
1599 * \param width    Width of block
1600 * \param height   Height of block
1601 * \param dstPic   Pointer to destination picture
1602 * \param bi       Flag indicating whether bipred is used
1603 */
1604#if LGE_ILLUCOMP_B0045
1605Void TComPrediction::xPredInterChromaBlk( TComDataCU *cu, TComPicYuv *refPic, UInt partAddr, TComMv *mv, Int width, Int height, TComYuv *&dstPic, Bool bi, Bool bICFlag
1606#if QC_ARP_D0177
1607    ,
1608    Int filterType
1609#endif   
1610    )
1611#else
1612Void TComPrediction::xPredInterChromaBlk( TComDataCU *cu, TComPicYuv *refPic, UInt partAddr, TComMv *mv, Int width, Int height, TComYuv *&dstPic, Bool bi
1613#if QC_ARP_D0177
1614  , Int filterType
1615#endif
1616  )
1617#endif
1618{
1619  Int     refStride  = refPic->getCStride();
1620  Int     dstStride  = dstPic->getCStride();
1621 
1622  Int     refOffset  = (mv->getHor() >> 3) + (mv->getVer() >> 3) * refStride;
1623 
1624  Pel*    refCb     = refPic->getCbAddr( cu->getAddr(), cu->getZorderIdxInCU() + partAddr ) + refOffset;
1625  Pel*    refCr     = refPic->getCrAddr( cu->getAddr(), cu->getZorderIdxInCU() + partAddr ) + refOffset;
1626 
1627  Pel* dstCb = dstPic->getCbAddr( partAddr );
1628  Pel* dstCr = dstPic->getCrAddr( partAddr );
1629 
1630  Int     xFrac  = mv->getHor() & 0x7;
1631  Int     yFrac  = mv->getVer() & 0x7;
1632  UInt    cxWidth  = width  >> 1;
1633  UInt    cxHeight = height >> 1;
1634 
1635  Int     extStride = m_filteredBlockTmp[0].getStride();
1636  Short*  extY      = m_filteredBlockTmp[0].getLumaAddr();
1637 
1638  Int filterSize = NTAPS_CHROMA;
1639 
1640  Int halfFilterSize = (filterSize>>1);
1641 
1642  if ( yFrac == 0 )
1643  {
1644    m_if.filterHorChroma(refCb, refStride, dstCb,  dstStride, cxWidth, cxHeight, xFrac, !bi
1645#if QC_ARP_D0177
1646    ,
1647    filterType
1648#endif   
1649    );   
1650    m_if.filterHorChroma(refCr, refStride, dstCr,  dstStride, cxWidth, cxHeight, xFrac, !bi
1651#if QC_ARP_D0177
1652    ,
1653    filterType
1654#endif   
1655    );   
1656  }
1657  else if ( xFrac == 0 )
1658  {
1659    m_if.filterVerChroma(refCb, refStride, dstCb, dstStride, cxWidth, cxHeight, yFrac, true, !bi
1660 #if QC_ARP_D0177
1661    ,
1662    filterType
1663#endif   
1664    );   
1665    m_if.filterVerChroma(refCr, refStride, dstCr, dstStride, cxWidth, cxHeight, yFrac, true, !bi
1666 #if QC_ARP_D0177
1667    ,
1668    filterType
1669#endif   
1670    );   
1671  }
1672  else
1673  {
1674    m_if.filterHorChroma(refCb - (halfFilterSize-1)*refStride, refStride, extY,  extStride, cxWidth, cxHeight+filterSize-1, xFrac, false
1675#if QC_ARP_D0177
1676    ,
1677    filterType
1678#endif   
1679    );
1680    m_if.filterVerChroma(extY  + (halfFilterSize-1)*extStride, extStride, dstCb, dstStride, cxWidth, cxHeight  , yFrac, false, !bi
1681#if QC_ARP_D0177
1682    ,
1683    filterType
1684#endif   
1685    );
1686   
1687    m_if.filterHorChroma(refCr - (halfFilterSize-1)*refStride, refStride, extY,  extStride, cxWidth, cxHeight+filterSize-1, xFrac, false
1688#if QC_ARP_D0177
1689    ,
1690    filterType
1691#endif   
1692    );
1693    m_if.filterVerChroma(extY  + (halfFilterSize-1)*extStride, extStride, dstCr, dstStride, cxWidth, cxHeight  , yFrac, false, !bi
1694#if QC_ARP_D0177
1695    ,
1696    filterType
1697#endif   
1698    );   
1699  }
1700#if LGE_ILLUCOMP_B0045
1701  if(bICFlag)
1702  {
1703    Int a, b, iShift, i, j;
1704    xGetLLSICPredictionChroma(cu, mv, refPic, a, b, iShift, 0); // Cb
1705    for (i = 0; i < cxHeight; i++)
1706    {
1707      for (j = 0; j < cxWidth; j++)
1708      {
1709        if(bi)
1710        {
1711          Int iIFshift = IF_INTERNAL_PREC - ( g_uiBitDepth + g_uiBitIncrement );
1712          dstCb[j] = ( (a*dstCb[j]+a*IF_INTERNAL_OFFS) >> iShift ) + b*(1<<iIFshift) - IF_INTERNAL_OFFS;
1713        }
1714        else
1715          dstCb[j] = Clip3(0, 255, ((a*dstCb[j])>>iShift)+b);
1716      }
1717      dstCb += dstStride;
1718    }
1719
1720    xGetLLSICPredictionChroma(cu, mv, refPic, a, b, iShift, 1); // Cr
1721    for (i = 0; i < cxHeight; i++)
1722    {
1723      for (j = 0; j < cxWidth; j++)
1724      {
1725        if(bi)
1726        {
1727          Int iIFshift = IF_INTERNAL_PREC - ( g_uiBitDepth + g_uiBitIncrement );
1728          dstCr[j] = ( (a*dstCr[j]+a*IF_INTERNAL_OFFS) >> iShift ) + b*(1<<iIFshift) - IF_INTERNAL_OFFS;
1729        }
1730        else
1731          dstCr[j] = Clip3(0, 255, ((a*dstCr[j])>>iShift)+b);
1732      }
1733      dstCr += dstStride;
1734    }
1735  }
1736#endif
1737}
1738
1739#if MERL_VSP_C0152
1740// Input:
1741// refPic: Ref picture. Full picture, with padding
1742// posX, posY:     PU position, texture
1743// sizeX, sizeY: PU size
1744// partAddr: z-order index
1745// mv: disparity vector. derived from neighboring blocks
1746//
1747// Output: dstPic, PU predictor 64x64
1748Void TComPrediction::xPredInterLumaBlkFromDM( TComPicYuv *refPic, TComPicYuv *pPicBaseDepth, Int* pShiftLUT, Int iShiftPrec, TComMv* mv, UInt partAddr,Int posX, Int posY, Int sizeX, Int sizeY, Bool isDepth
1749#if !MERL_Bi_VSP_D0166
1750                                            , Int vspIdx
1751#endif
1752                                            , TComYuv *&dstPic
1753#if MERL_Bi_VSP_D0166
1754                                            , Bool bi
1755#endif         
1756                                            )
1757{
1758  Int widthLuma;
1759  Int heightLuma;
1760
1761  if (isDepth)
1762  {
1763    widthLuma   =  pPicBaseDepth->getWidth();
1764    heightLuma  =  pPicBaseDepth->getHeight();
1765  }
1766  else
1767  {
1768    widthLuma   =  refPic->getWidth();
1769    heightLuma  =  refPic->getHeight();
1770  }
1771
1772#if MERL_VSP_BLOCKSIZE_C0152 != 1
1773  Int widthDepth  = pPicBaseDepth->getWidth();
1774  Int heightDepth = pPicBaseDepth->getHeight();
1775#endif
1776
1777#if MERL_CVSP_D0165
1778  Int widthDepth  = pPicBaseDepth->getWidth();
1779  Int heightDepth = pPicBaseDepth->getHeight();
1780#endif
1781
1782  Int nTxtPerDepthX = widthLuma  / ( pPicBaseDepth->getWidth() );  // texture pixel # per depth pixel
1783  Int nTxtPerDepthY = heightLuma / ( pPicBaseDepth->getHeight() );
1784
1785  Int refStride = refPic->getStride();
1786  Int dstStride = dstPic->getStride();
1787  Int depStride =  pPicBaseDepth->getStride();
1788#if LGE_ROUND_OFFSET_D0135
1789  Int depthPosX = Clip3(0,   widthLuma - sizeX,  (posX/nTxtPerDepthX) + ((mv->getHor()+2)>>2));
1790  Int depthPosY = Clip3(0,   heightLuma- sizeY,  (posY/nTxtPerDepthY) + ((mv->getVer()+2)>>2));
1791#else
1792  Int depthPosX = Clip3(0,   widthLuma - sizeX,  (posX/nTxtPerDepthX) + (mv->getHor()>>2));
1793  Int depthPosY = Clip3(0,   heightLuma- sizeY,  (posY/nTxtPerDepthY) + (mv->getVer()>>2));
1794#endif
1795  Pel *ref    = refPic->getLumaAddr() + posX + posY * refStride;
1796  Pel *dst    = dstPic->getLumaAddr(partAddr);
1797  Pel *depth  = pPicBaseDepth->getLumaAddr() + depthPosX + depthPosY * depStride;
1798
1799#if MERL_VSP_BLOCKSIZE_C0152 != 1
1800#if MERL_VSP_BLOCKSIZE_C0152 == 2
1801  Int  dW = sizeX>>1;
1802  Int  dH = sizeY>>1;
1803#endif
1804#if MERL_VSP_BLOCKSIZE_C0152 == 4
1805  Int  dW = sizeX>>2;
1806  Int  dH = sizeY>>2;
1807#endif
1808  {
1809    Pel* depthi = depth;
1810    for (Int j = 0; j < dH; j++)
1811    {
1812      for (Int i = 0; i < dW; i++)
1813      {
1814        Pel* depthTmp;
1815#if MERL_VSP_BLOCKSIZE_C0152 == 2
1816        if (depthPosX + (i<<1) < widthDepth)
1817          depthTmp = depthi + (i << 1);
1818        else
1819          depthTmp = depthi + (widthDepth - depthPosX - 1);
1820#endif
1821#if MERL_VSP_BLOCKSIZE_C0152 == 4
1822        if (depthPosX + (i<<2) < widthDepth)
1823          depthTmp = depthi + (i << 2);
1824        else
1825          depthTmp = depthi + (widthDepth - depthPosX - 1);
1826#endif
1827        Int maxV = 0;
1828#if MTK_DEPTH_TO_DISP_D0138
1829        for (Int blockj = 0; blockj < MERL_VSP_BLOCKSIZE_C0152; blockj+=(MERL_VSP_BLOCKSIZE_C0152-1))
1830#else
1831        for (Int blockj = 0; blockj < MERL_VSP_BLOCKSIZE_C0152; blockj++)
1832#endif
1833        {
1834          Int iX = 0;
1835#if MTK_DEPTH_TO_DISP_D0138
1836          for (Int blocki = 0; blocki < MERL_VSP_BLOCKSIZE_C0152; blocki+=(MERL_VSP_BLOCKSIZE_C0152-1))
1837#else
1838          for (Int blocki = 0; blocki < MERL_VSP_BLOCKSIZE_C0152; blocki++)
1839#endif
1840          {
1841            if (maxV < depthTmp[iX])
1842              maxV = depthTmp[iX];
1843#if MERL_VSP_BLOCKSIZE_C0152 == 2
1844            if (depthPosX + (i<<1) + blocki < widthDepth - 1)
1845#else // MERL_VSP_BLOCKSIZE_C0152 == 4
1846            if (depthPosX + (i<<2) + blocki < widthDepth - 1)
1847#endif
1848              iX++;
1849          }
1850#if MERL_VSP_BLOCKSIZE_C0152 == 2
1851          if (depthPosY + (j<<1) + blockj < heightDepth - 1)
1852#else // MERL_VSP_BLOCKSIZE_C0152 == 4
1853          if (depthPosY + (j<<2) + blockj < heightDepth - 1)
1854#endif
1855            depthTmp += depStride;
1856        }
1857        m_pDepth[i+j*dW] = maxV;
1858      } // end of i < dW
1859#if MERL_VSP_BLOCKSIZE_C0152 == 2
1860      if (depthPosY + ((j+1)<<1) < heightDepth)
1861        depthi += (depStride << 1);
1862      else
1863        depthi  = depth + (heightDepth-depthPosY-1)*depStride;
1864#endif
1865#if MERL_VSP_BLOCKSIZE_C0152 == 4
1866      if (depthPosY + ((j+1)<<2) < heightDepth) // heightDepth-1
1867        depthi += (depStride << 2);
1868      else
1869        depthi  = depth + (heightDepth-depthPosY-1)*depStride; // the last line
1870#endif
1871    }
1872  }
1873#endif
1874 
1875#if MERL_General_Fix
1876#if MERL_VSP_BLOCKSIZE_C0152 == 1
1877#if MERL_CVSP_D0165
1878  //get LUT based horizontal reference range
1879  Int range = 0;
1880  if( sizeX == 4 && sizeY == 8 )
1881    range = m_iRangeLuma[0];
1882  else if( sizeX == 8 && sizeY == 4 )
1883    range = m_iRangeLuma[1];
1884  else if( sizeX == 8 && sizeY == 8 )
1885    range = m_iRangeLuma[2];
1886  else if( sizeX == 8 && sizeY == 16 )
1887    range = m_iRangeLuma[3];
1888  else if( sizeX == 16 && sizeY == 8 )
1889    range = m_iRangeLuma[4];
1890  else if( sizeX == 16 && sizeY == 16 )
1891    range = m_iRangeLuma[5];
1892  else if( sizeX == 16 && sizeY == 32 )
1893    range = m_iRangeLuma[6];
1894  else if( sizeX == 32 && sizeY == 16 )
1895    range = m_iRangeLuma[7];
1896  else if( sizeX == 32 && sizeY == 32 )
1897    range = m_iRangeLuma[8];
1898  else if( sizeX == 32 && sizeY == 64 )
1899    range = m_iRangeLuma[9];
1900  else if( sizeX == 64 && sizeY == 32 )
1901    range = m_iRangeLuma[10];
1902  else if( sizeX == 64 && sizeY == 64 )
1903    range = m_iRangeLuma[11];
1904  else 
1905    assert(0);
1906
1907  // The minimum depth value
1908  Int minRelativePos = 5000;
1909  Int maxRelativePos = -5000;
1910
1911  Pel* depthTemp, *depthInitial=depth;
1912  for (Int yTxt =0; yTxt<sizeY; yTxt++)
1913  {
1914    for (Int xTxt =0; xTxt<sizeX; xTxt++)
1915    {
1916      if (depthPosX+xTxt < widthDepth)
1917        depthTemp = depthInitial + xTxt;
1918      else
1919        depthTemp = depthInitial + (widthDepth - depthPosX - 1);
1920
1921      Int disparity = pShiftLUT[ *depthTemp ] << iShiftPrec;
1922      Int disparityInt = disparity >> 2;
1923
1924      if( disparity <= 0)
1925      {
1926        if (minRelativePos > disparityInt+xTxt)
1927            minRelativePos = disparityInt+xTxt;
1928      }
1929      else
1930      {
1931        if (maxRelativePos < disparityInt+xTxt)
1932            maxRelativePos = disparityInt+xTxt;
1933      }
1934    }
1935    if (depthPosY+yTxt < heightDepth)
1936      depthInitial = depthInitial + depStride;
1937  }
1938
1939  Int disparity_tmp = pShiftLUT[ *depth ] << iShiftPrec;
1940  if (disparity_tmp <= 0)
1941    maxRelativePos = minRelativePos + range -1 ;
1942  else
1943    minRelativePos = maxRelativePos - range +1 ;
1944#endif
1945#endif
1946#endif
1947
1948#if MERL_VSP_BLOCKSIZE_C0152 != 1
1949  Int yDepth = 0;
1950#endif
1951  for ( Int yTxt = 0; yTxt < sizeY; yTxt += nTxtPerDepthY )
1952  {
1953    for ( Int xTxt = 0, xDepth = 0; xTxt < sizeX; xTxt += nTxtPerDepthX, xDepth++ )
1954    {
1955      Pel repDepth = 0; // to store the depth value used for warping
1956#if MERL_VSP_BLOCKSIZE_C0152 == 1
1957      repDepth = depth[xDepth];
1958#endif
1959#if MERL_VSP_BLOCKSIZE_C0152 == 2
1960      repDepth = m_pDepth[(xTxt>>1) + (yTxt>>1)*dW];
1961#endif
1962#if MERL_VSP_BLOCKSIZE_C0152 == 4
1963      repDepth = m_pDepth[(xTxt>>2) + (yTxt>>2)*dW];
1964#endif
1965
1966      assert( repDepth >= 0 && repDepth <= 255 );
1967      Int disparity = pShiftLUT[ repDepth ] << iShiftPrec;
1968      Int refOffset = xTxt + (disparity >> 2);
1969      Int xFrac = disparity & 0x3;
1970#if MERL_CVSP_D0165
1971      if(refOffset<minRelativePos || refOffset>maxRelativePos)
1972        xFrac = 0;
1973      refOffset = Clip3(minRelativePos, maxRelativePos, refOffset);
1974#endif
1975      Int absX  = posX + refOffset;
1976
1977      if (xFrac == 0)
1978        absX = Clip3(0, widthLuma-1, absX);
1979      else
1980        absX = Clip3(4, widthLuma-5, absX);
1981
1982      refOffset = absX - posX;
1983
1984      assert( ref[refOffset] >= 0 && ref[refOffset]<= 255 );
1985#if MERL_Bi_VSP_D0166
1986      m_if.filterHorLuma( &ref[refOffset], refStride, &dst[xTxt], dstStride, nTxtPerDepthX, nTxtPerDepthY, xFrac, !bi );
1987#else
1988      m_if.filterHorLuma( &ref[refOffset], refStride, &dst[xTxt], dstStride, nTxtPerDepthX, nTxtPerDepthY, xFrac, true );
1989#endif
1990
1991    }
1992    ref   += refStride*nTxtPerDepthY;
1993    dst   += dstStride*nTxtPerDepthY;
1994    depth += depStride;
1995#if MERL_VSP_BLOCKSIZE_C0152 != 1
1996    yDepth++;
1997#endif
1998
1999  }
2000}
2001
2002Void TComPrediction::xPredInterChromaBlkFromDM ( TComPicYuv *refPic, TComPicYuv *pPicBaseDepth, Int* pShiftLUT, Int iShiftPrec, TComMv*mv, UInt partAddr, Int posX, Int posY, Int sizeX, Int sizeY, Bool isDepth
2003#if !MERL_Bi_VSP_D0166
2004                                               , Int vspIdx
2005#endif
2006                                               , TComYuv *&dstPic
2007#if MERL_Bi_VSP_D0166
2008                                               , Bool bi
2009#endif
2010                                               )
2011{
2012  Int refStride = refPic->getCStride();
2013  Int dstStride = dstPic->getCStride();
2014  Int depStride = pPicBaseDepth->getStride();
2015
2016  Int widthChroma, heightChroma;
2017  if( isDepth)
2018  {
2019     widthChroma   = pPicBaseDepth->getWidth()>>1;
2020     heightChroma  = pPicBaseDepth->getHeight()>>1;
2021  }
2022  else
2023  {
2024     widthChroma   = refPic->getWidth()>>1;
2025     heightChroma  = refPic->getHeight()>>1;
2026  }
2027
2028  // Below is only for Texture chroma component
2029
2030  Int widthDepth  = pPicBaseDepth->getWidth();
2031  Int heightDepth = pPicBaseDepth->getHeight();
2032
2033  Int nTxtPerDepthX, nTxtPerDepthY;  // Number of texture samples per one depth sample
2034  Int nDepthPerTxtX, nDepthPerTxtY;  // Number of depth samples per one texture sample
2035
2036  Int depthPosX;  // Starting position in depth image
2037  Int depthPosY;
2038
2039  if ( widthChroma > widthDepth )
2040  {
2041    nTxtPerDepthX = widthChroma / widthDepth;
2042    nDepthPerTxtX = 1;
2043#if LGE_ROUND_OFFSET_D0135
2044    depthPosX = posX / nTxtPerDepthX + ((mv->getHor()+2)>>2);        //mv denotes the disparity for VSP
2045#else
2046    depthPosX = posX / nTxtPerDepthX + (mv->getHor()>>2);        //mv denotes the disparity for VSP
2047#endif
2048  }
2049  else
2050  {
2051    nTxtPerDepthX = 1;
2052    nDepthPerTxtX = widthDepth / widthChroma;
2053#if LGE_ROUND_OFFSET_D0135
2054    depthPosX = posX * nDepthPerTxtX + ((mv->getHor()+2)>>2);        //mv denotes the disparity for VSP
2055#else
2056    depthPosX = posX * nDepthPerTxtX + (mv->getHor()>>2);        //mv denotes the disparity for VSP
2057#endif
2058  }
2059  depthPosX = Clip3(0, widthDepth - (sizeX<<1), depthPosX);
2060  if ( heightChroma > heightDepth )
2061  {
2062    nTxtPerDepthY = heightChroma / heightDepth;
2063    nDepthPerTxtY = 1;
2064#if LGE_ROUND_OFFSET_D0135
2065    depthPosY = posY / nTxtPerDepthY + ((mv->getVer()+2)>>2);     //mv denotes the disparity for VSP
2066#else
2067    depthPosY = posY / nTxtPerDepthY + (mv->getVer()>>2);     //mv denotes the disparity for VSP
2068#endif
2069  }
2070  else
2071  {
2072    nTxtPerDepthY = 1;
2073    nDepthPerTxtY = heightDepth / heightChroma;
2074#if LGE_ROUND_OFFSET_D0135
2075    depthPosY = posY * nDepthPerTxtY + ((mv->getVer()+2)>>2);     //mv denotes the disparity for VSP
2076#else
2077    depthPosY = posY * nDepthPerTxtY + (mv->getVer()>>2);     //mv denotes the disparity for VSP
2078#endif
2079  }
2080  depthPosY = Clip3(0, heightDepth - (sizeY<<1), depthPosY);
2081
2082  Pel *refCb  = refPic->getCbAddr() + posX + posY * refStride;
2083  Pel *refCr  = refPic->getCrAddr() + posX + posY * refStride;
2084  Pel *dstCb  = dstPic->getCbAddr(partAddr);
2085  Pel *dstCr  = dstPic->getCrAddr(partAddr);
2086  Pel *depth  = pPicBaseDepth->getLumaAddr() + depthPosX + depthPosY * depStride;  // move the pointer to the current depth pixel position
2087 
2088  Int refStrideBlock = refStride * nTxtPerDepthY;
2089  Int dstStrideBlock = dstStride * nTxtPerDepthY;
2090  Int depStrideBlock = depStride * nDepthPerTxtY;
2091
2092#if !MERL_Bi_VSP_D0166
2093  if (isDepth)
2094  {
2095     // DT: Since the call for this function is redundant, ..
2096     for (Int y = 0; y < sizeY; y++)
2097     {
2098       for (Int x = 0; x < sizeX; x++)
2099       {
2100         dstCb[x] = 128;
2101         dstCr[x] = 128;
2102       }
2103       dstCb += dstStride;
2104       dstCr += dstStride;
2105     }
2106     return;
2107  }
2108#endif
2109
2110  if ( widthChroma > widthDepth ) // We assume
2111  {
2112    assert( heightChroma > heightDepth );
2113    printf("This branch should never been reached.\n");
2114    exit(0);
2115  }
2116  else
2117  {
2118#if MERL_VSP_BLOCKSIZE_C0152 == 1
2119  Int  dW = sizeX;
2120  Int  dH = sizeY;
2121  Int  sW = 2; // search window size
2122  Int  sH = 2;
2123#endif
2124#if MERL_VSP_BLOCKSIZE_C0152 == 2
2125  Int  dW = sizeX;
2126  Int  dH = sizeY;
2127  Int  sW = 2; // search window size
2128  Int  sH = 2;
2129#endif
2130#if MERL_VSP_BLOCKSIZE_C0152 == 4
2131  Int  dW = sizeX>>1;
2132  Int  dH = sizeY>>1;
2133  Int  sW = 4; // search window size
2134  Int  sH = 4;
2135#endif
2136
2137  {
2138    Pel* depthi = depth;
2139    for (Int j = 0; j < dH; j++)
2140    {
2141      for (Int i = 0; i < dW; i++)
2142      {
2143        Pel* depthTmp;
2144#if MERL_VSP_BLOCKSIZE_C0152 == 1
2145        depthTmp = depthi + (i << 1);
2146#endif
2147#if MERL_VSP_BLOCKSIZE_C0152 == 2
2148        if (depthPosX + (i<<1) < widthDepth)
2149          depthTmp = depthi + (i << 1);
2150        else
2151          depthTmp = depthi + (widthDepth - depthPosX - 1);
2152#endif
2153#if MERL_VSP_BLOCKSIZE_C0152 == 4
2154        if (depthPosX + (i<<2) < widthDepth)
2155          depthTmp = depthi + (i << 2);
2156        else
2157          depthTmp = depthi + (widthDepth - depthPosX - 1);
2158#endif
2159        Int maxV = 0;
2160        for (Int blockj = 0; blockj < sH; blockj++)
2161        {
2162          Int iX = 0;
2163          for (Int blocki = 0; blocki < sW; blocki++)
2164          {
2165            if (maxV < depthTmp[iX])
2166              maxV = depthTmp[iX];
2167            if (depthPosX + i*sW + blocki < widthDepth - 1)
2168              iX++;
2169          }
2170          if (depthPosY + j*sH + blockj < heightDepth - 1)
2171            depthTmp += depStride;
2172        }
2173        m_pDepth[i+j*dW] = maxV;
2174      } // end of i < dW
2175#if MERL_VSP_BLOCKSIZE_C0152 == 1
2176      if (depthPosY + ((j+1)<<1) < heightDepth)
2177        depthi += (depStride << 1);
2178      else
2179        depthi  = depth + (heightDepth-1)*depStride;
2180#endif
2181#if MERL_VSP_BLOCKSIZE_C0152 == 2
2182      if (depthPosY + ((j+1)<<1) < heightDepth)
2183        depthi += (depStride << 1);
2184      else
2185        depthi  = depth + (heightDepth-depthPosY-1)*depStride;
2186#endif
2187#if MERL_VSP_BLOCKSIZE_C0152 == 4
2188      if (depthPosY + ((j+1)<<2) < heightDepth) // heightDepth-1
2189        depthi += (depStride << 2);
2190      else
2191        depthi  = depth + (heightDepth-depthPosY-1)*depStride; // the last line
2192#endif
2193    }
2194  }
2195
2196
2197#if MERL_General_Fix
2198#if MERL_VSP_BLOCKSIZE_C0152 == 1
2199#if MERL_CVSP_D0165
2200  //get LUT based horizontal reference range
2201  Int range=0;
2202  if( sizeX == 2 && sizeY == 4 )
2203    range = m_iRangeChroma[0];
2204  else if( sizeX == 4 && sizeY == 2 )
2205    range = m_iRangeChroma[1];
2206  else if( sizeX == 4 && sizeY == 4 )
2207    range = m_iRangeChroma[2];
2208  else if( sizeX == 4 && sizeY == 8 )
2209    range = m_iRangeChroma[3];
2210  else if( sizeX == 8 && sizeY == 4 )
2211    range = m_iRangeChroma[4];
2212  else if( sizeX == 8 && sizeY == 8 )
2213    range = m_iRangeChroma[5];
2214  else if( sizeX == 8 && sizeY == 16 )
2215    range = m_iRangeChroma[6];
2216  else if( sizeX == 16 && sizeY == 8 )
2217    range = m_iRangeChroma[7];
2218  else if( sizeX == 16 && sizeY == 16 )
2219    range = m_iRangeChroma[8];
2220  else if( sizeX == 16 && sizeY == 32 )
2221    range = m_iRangeChroma[9];
2222  else if( sizeX == 32 && sizeY == 16 )
2223    range = m_iRangeChroma[10];
2224  else if( sizeX == 32 && sizeY == 32 )
2225    range = m_iRangeChroma[11];
2226  else
2227    assert(0);
2228 
2229  // The minimum depth value
2230  Int minRelativePos = 5000;
2231  Int maxRelativePos = -5000;
2232
2233  Int depthTmp;
2234  for (Int yTxt=0; yTxt<sizeY; yTxt++)
2235  {
2236    for (Int xTxt=0; xTxt<sizeX; xTxt++)
2237    {
2238      depthTmp = m_pDepth[xTxt+yTxt*dW];
2239      Int disparity = pShiftLUT[ depthTmp ] << iShiftPrec;
2240      Int disparityInt = disparity >> 3;//in chroma resolution
2241
2242      if (disparityInt < 0)
2243      {
2244        if (minRelativePos > disparityInt+xTxt)
2245            minRelativePos = disparityInt+xTxt;
2246      }
2247      else
2248      {
2249        if (maxRelativePos < disparityInt+xTxt)
2250            maxRelativePos = disparityInt+xTxt;
2251      }
2252    }
2253  }
2254
2255  depthTmp = m_pDepth[0];
2256  Int disparity_tmp = pShiftLUT[ depthTmp ] << iShiftPrec;
2257  if ( disparity_tmp < 0 )
2258    maxRelativePos = minRelativePos + range - 1;
2259  else
2260    minRelativePos = maxRelativePos - range + 1;
2261
2262#endif
2263#endif
2264#endif
2265
2266    // (sizeX, sizeY) is Chroma block size
2267    for ( Int yTxt = 0, yDepth = 0; yTxt < sizeY; yTxt += nTxtPerDepthY, yDepth += nDepthPerTxtY )
2268    {
2269      for ( Int xTxt = 0, xDepth = 0; xTxt < sizeX; xTxt += nTxtPerDepthX, xDepth += nDepthPerTxtX )
2270      {
2271        Pel repDepth = 0; // to store the depth value used for warping
2272#if MERL_VSP_BLOCKSIZE_C0152 == 1
2273        repDepth = m_pDepth[(xTxt) + (yTxt)*dW];
2274#endif
2275#if MERL_VSP_BLOCKSIZE_C0152 == 2
2276        repDepth = m_pDepth[(xTxt) + (yTxt)*dW];
2277#endif
2278#if MERL_VSP_BLOCKSIZE_C0152 == 4
2279        repDepth = m_pDepth[(xTxt>>1) + (yTxt>>1)*dW];
2280#endif
2281
2282      // calculate the offset in the reference picture
2283        Int disparity = pShiftLUT[ repDepth ] << iShiftPrec;
2284        Int refOffset = xTxt + (disparity >> 3); // in integer pixel in chroma image
2285        Int xFrac = disparity & 0x7;
2286#if MERL_CVSP_D0165
2287        if(refOffset < minRelativePos || refOffset > maxRelativePos)
2288          xFrac = 0;
2289        refOffset = Clip3(minRelativePos, maxRelativePos, refOffset);
2290#endif
2291        Int absX  = posX + refOffset;
2292
2293        if (xFrac == 0)
2294          absX = Clip3(0, widthChroma-1, absX);
2295        else
2296          absX = Clip3(4, widthChroma-5, absX);
2297
2298        refOffset = absX - posX;
2299
2300        assert( refCb[refOffset] >= 0 && refCb[refOffset]<= 255 );
2301        assert( refCr[refOffset] >= 0 && refCr[refOffset]<= 255 );
2302#if MERL_Bi_VSP_D0166
2303        m_if.filterHorChroma(&refCb[refOffset], refStride, &dstCb[xTxt],  dstStride, nTxtPerDepthX, nTxtPerDepthY, xFrac, !bi);
2304        m_if.filterHorChroma(&refCr[refOffset], refStride, &dstCr[xTxt],  dstStride, nTxtPerDepthX, nTxtPerDepthY, xFrac, !bi);
2305#else
2306        m_if.filterHorChroma(&refCb[refOffset], refStride, &dstCb[xTxt],  dstStride, nTxtPerDepthX, nTxtPerDepthY, xFrac, true);
2307        m_if.filterHorChroma(&refCr[refOffset], refStride, &dstCr[xTxt],  dstStride, nTxtPerDepthX, nTxtPerDepthY, xFrac, true);
2308#endif
2309
2310      }
2311      refCb += refStrideBlock;
2312      refCr += refStrideBlock;
2313      dstCb += dstStrideBlock;
2314      dstCr += dstStrideBlock;
2315      depth += depStrideBlock;
2316    }
2317  }
2318
2319}
2320
2321#endif // MERL_VSP_C0152
2322
2323#if DEPTH_MAP_GENERATION
2324Void TComPrediction::xWeightedAveragePdm( TComDataCU* pcCU, TComYuv* pcYuvSrc0, TComYuv* pcYuvSrc1, Int iRefIdx0, Int iRefIdx1, UInt uiPartIdx, Int iWidth, Int iHeight, TComYuv*& rpcYuvDst, UInt uiSubSampExpX, UInt uiSubSampExpY )
2325{
2326
2327  if( iRefIdx0 >= 0 && iRefIdx1 >= 0 )
2328  {
2329    rpcYuvDst->addAvgPdm( pcYuvSrc0, pcYuvSrc1, uiPartIdx, iWidth, iHeight, uiSubSampExpX, uiSubSampExpY );
2330  }
2331  else if ( iRefIdx0 >= 0 && iRefIdx1 <  0 )
2332  {
2333    pcYuvSrc0->copyPartToPartYuvPdm( rpcYuvDst, uiPartIdx, iWidth, iHeight, uiSubSampExpX, uiSubSampExpY );
2334  }
2335  else if ( iRefIdx0 <  0 && iRefIdx1 >= 0 )
2336  {
2337    pcYuvSrc1->copyPartToPartYuvPdm( rpcYuvDst, uiPartIdx, iWidth, iHeight, uiSubSampExpX, uiSubSampExpY );
2338  }
2339  else
2340  {
2341    assert (0);
2342  }
2343}
2344#endif
2345
2346Void TComPrediction::xWeightedAverage( TComDataCU* pcCU, TComYuv* pcYuvSrc0, TComYuv* pcYuvSrc1, Int iRefIdx0, Int iRefIdx1, UInt uiPartIdx, Int iWidth, Int iHeight, TComYuv*& rpcYuvDst
2347#if MERL_Bi_VSP_D0166
2348                                 , Int predDirVSP
2349#endif
2350  )
2351{
2352#if MERL_Bi_VSP_D0166
2353  Bool isVSP = 0;
2354  if (pcCU->getVSPIndex(uiPartIdx)!=0)//is VSP
2355  {
2356    isVSP = 1;
2357  }
2358
2359  if(( !isVSP && iRefIdx0 >= 0 && iRefIdx1 >= 0 ) || ( isVSP && predDirVSP == 3 ))
2360#else
2361  if( iRefIdx0 >= 0 && iRefIdx1 >= 0 )
2362#endif
2363  {
2364    rpcYuvDst->addAvg( pcYuvSrc0, pcYuvSrc1, uiPartIdx, iWidth, iHeight );
2365  }
2366#if MERL_Bi_VSP_D0166
2367  else if ( ( !isVSP && iRefIdx0 >= 0 && iRefIdx1 <  0 ) || ( isVSP && predDirVSP == 1))
2368#else
2369  else if ( iRefIdx0 >= 0 && iRefIdx1 <  0 )
2370#endif
2371  {
2372    pcYuvSrc0->copyPartToPartYuv( rpcYuvDst, uiPartIdx, iWidth, iHeight );
2373  }
2374#if MERL_Bi_VSP_D0166
2375  else if (( !isVSP && iRefIdx0 <  0 && iRefIdx1 >= 0 ) || ( isVSP && predDirVSP == 2))
2376#else
2377  else if ( iRefIdx0 <  0 && iRefIdx1 >= 0 )
2378#endif
2379  {
2380    pcYuvSrc1->copyPartToPartYuv( rpcYuvDst, uiPartIdx, iWidth, iHeight );
2381  }
2382#if MERL_Bi_VSP_D0166
2383  else
2384  {//for debug test only
2385    assert(0);
2386  }
2387#endif
2388}
2389
2390// AMVP
2391Void TComPrediction::getMvPredAMVP( TComDataCU* pcCU, UInt uiPartIdx, UInt uiPartAddr, RefPicList eRefPicList, Int iRefIdx, TComMv& rcMvPred )
2392{
2393  AMVPInfo* pcAMVPInfo = pcCU->getCUMvField(eRefPicList)->getAMVPInfo();
2394
2395  if( pcCU->getAMVPMode(uiPartAddr) == AM_NONE || (pcAMVPInfo->iN <= 1 && pcCU->getAMVPMode(uiPartAddr) == AM_EXPL) )
2396  {
2397    rcMvPred = pcAMVPInfo->m_acMvCand[0];
2398
2399    pcCU->setMVPIdxSubParts( 0, eRefPicList, uiPartAddr, uiPartIdx, pcCU->getDepth(uiPartAddr));
2400    pcCU->setMVPNumSubParts( pcAMVPInfo->iN, eRefPicList, uiPartAddr, uiPartIdx, pcCU->getDepth(uiPartAddr));
2401    return;
2402  }
2403
2404  assert(pcCU->getMVPIdx(eRefPicList,uiPartAddr) >= 0);
2405  rcMvPred = pcAMVPInfo->m_acMvCand[pcCU->getMVPIdx(eRefPicList,uiPartAddr)];
2406  return;
2407}
2408
2409/** Function for deriving planar intra prediction.
2410 * \param pSrc pointer to reconstructed sample array
2411 * \param srcStride the stride of the reconstructed sample array
2412 * \param rpDst reference to pointer for the prediction sample array
2413 * \param dstStride the stride of the prediction sample array
2414 * \param width the width of the block
2415 * \param height the height of the block
2416 *
2417 * This function derives the prediction samples for planar mode (intra coding).
2418 */
2419Void TComPrediction::xPredIntraPlanar( Int* pSrc, Int srcStride, Pel* rpDst, Int dstStride, UInt width, UInt height )
2420{
2421  assert(width == height);
2422
2423  Int k, l, bottomLeft, topRight;
2424  Int horPred;
2425  Int leftColumn[MAX_CU_SIZE], topRow[MAX_CU_SIZE], bottomRow[MAX_CU_SIZE], rightColumn[MAX_CU_SIZE];
2426  UInt blkSize = width;
2427  UInt offset2D = width;
2428  UInt shift1D = g_aucConvertToBit[ width ] + 2;
2429  UInt shift2D = shift1D + 1;
2430
2431  // Get left and above reference column and row
2432  for(k=0;k<blkSize+1;k++)
2433  {
2434    topRow[k] = pSrc[k-srcStride];
2435    leftColumn[k] = pSrc[k*srcStride-1];
2436  }
2437
2438  // Prepare intermediate variables used in interpolation
2439  bottomLeft = leftColumn[blkSize];
2440  topRight   = topRow[blkSize];
2441  for (k=0;k<blkSize;k++)
2442  {
2443    bottomRow[k]   = bottomLeft - topRow[k];
2444    rightColumn[k] = topRight   - leftColumn[k];
2445    topRow[k]      <<= shift1D;
2446    leftColumn[k]  <<= shift1D;
2447  }
2448
2449  // Generate prediction signal
2450  for (k=0;k<blkSize;k++)
2451  {
2452    horPred = leftColumn[k] + offset2D;
2453    for (l=0;l<blkSize;l++)
2454    {
2455      horPred += rightColumn[k];
2456      topRow[l] += bottomRow[l];
2457      rpDst[k*dstStride+l] = ( (horPred + topRow[l]) >> shift2D );
2458    }
2459  }
2460}
2461
2462/** Function for deriving chroma LM intra prediction.
2463 * \param pcPattern pointer to neighbouring pixel access pattern
2464 * \param piSrc pointer to reconstructed chroma sample array
2465 * \param pPred pointer for the prediction sample array
2466 * \param uiPredStride the stride of the prediction sample array
2467 * \param uiCWidth the width of the chroma block
2468 * \param uiCHeight the height of the chroma block
2469 * \param uiChromaId boolean indication of chroma component
2470 *
2471 * This function derives the prediction samples for chroma LM mode (chroma intra coding)
2472 */
2473Void TComPrediction::predLMIntraChroma( TComPattern* pcPattern, Int* piSrc, Pel* pPred, UInt uiPredStride, UInt uiCWidth, UInt uiCHeight, UInt uiChromaId )
2474{
2475  UInt uiWidth  = 2 * uiCWidth;
2476
2477  xGetLLSPrediction( pcPattern, piSrc+uiWidth+2, uiWidth+1, pPred, uiPredStride, uiCWidth, uiCHeight, 1 ); 
2478}
2479
2480/** Function for deriving downsampled luma sample of current chroma block and its above, left causal pixel
2481 * \param pcPattern pointer to neighbouring pixel access pattern
2482 * \param uiCWidth the width of the chroma block
2483 * \param uiCHeight the height of the chroma block
2484 *
2485 * This function derives downsampled luma sample of current chroma block and its above, left causal pixel
2486 */
2487Void TComPrediction::getLumaRecPixels( TComPattern* pcPattern, UInt uiCWidth, UInt uiCHeight )
2488{
2489  UInt uiWidth  = 2 * uiCWidth;
2490  UInt uiHeight = 2 * uiCHeight; 
2491
2492  Pel* pRecSrc = pcPattern->getROIY();
2493  Pel* pDst0 = m_pLumaRecBuffer + m_iLumaRecStride + 1;
2494
2495  Int iRecSrcStride = pcPattern->getPatternLStride();
2496  Int iRecSrcStride2 = iRecSrcStride << 1;
2497  Int iDstStride = m_iLumaRecStride;
2498  Int iSrcStride = ( max( uiWidth, uiHeight ) << 1 ) + 1;
2499
2500  Int* ptrSrc = pcPattern->getAdiOrgBuf( uiWidth, uiHeight, m_piYuvExt );
2501
2502  // initial pointers
2503  Pel* pDst = pDst0 - 1 - iDstStride; 
2504  Int* piSrc = ptrSrc;
2505
2506  // top left corner downsampled from ADI buffer
2507  // don't need this point
2508
2509  // top row downsampled from ADI buffer
2510  pDst++;     
2511  piSrc ++;
2512  for (Int i = 0; i < uiCWidth; i++)
2513  {
2514    pDst[i] = ((piSrc[2*i] * 2 ) + piSrc[2*i - 1] + piSrc[2*i + 1] + 2) >> 2;
2515  }
2516
2517  // left column downsampled from ADI buffer
2518  pDst = pDst0 - 1; 
2519  piSrc = ptrSrc + iSrcStride;
2520  for (Int j = 0; j < uiCHeight; j++)
2521  {
2522    pDst[0] = ( piSrc[0] + piSrc[iSrcStride] ) >> 1;
2523    piSrc += iSrcStride << 1; 
2524    pDst += iDstStride;   
2525  }
2526
2527  // inner part from reconstructed picture buffer
2528  for( Int j = 0; j < uiCHeight; j++ )
2529  {
2530    for (Int i = 0; i < uiCWidth; i++)
2531    {
2532      pDst0[i] = (pRecSrc[2*i] + pRecSrc[2*i + iRecSrcStride]) >> 1;
2533    }
2534
2535    pDst0 += iDstStride;
2536    pRecSrc += iRecSrcStride2;
2537  }
2538}
2539
2540/** Function for deriving the positon of first non-zero binary bit of a value
2541 * \param x input value
2542 *
2543 * This function derives the positon of first non-zero binary bit of a value
2544 */
2545Int GetMSB( UInt x )
2546{
2547  Int iMSB = 0, bits = ( sizeof( Int ) << 3 ), y = 1;
2548
2549  while( x > 1 )
2550  {
2551    bits >>= 1;
2552    y = x >> bits;
2553
2554    if( y )
2555    {
2556      x = y;
2557      iMSB += bits;
2558    }
2559  }
2560
2561  iMSB+=y;
2562
2563  return iMSB;
2564}
2565
2566/** Function for counting leading number of zeros/ones
2567 * \param x input value
2568 \ This function counts leading number of zeros for positive numbers and
2569 \ leading number of ones for negative numbers. This can be implemented in
2570 \ single instructure cycle on many processors.
2571 */
2572
2573Short CountLeadingZerosOnes (Short x)
2574{
2575  Short clz;
2576  Short i;
2577
2578  if(x == 0)
2579  {
2580    clz = 0;
2581  }
2582  else
2583  {
2584    if (x == -1)
2585    {
2586      clz = 15;
2587    }
2588    else
2589    {
2590      if(x < 0)
2591      {
2592        x = ~x;
2593      }
2594      clz = 15;
2595      for(i = 0;i < 15;++i)
2596      {
2597        if(x) 
2598        {
2599          clz --;
2600        }
2601        x = x >> 1;
2602      }
2603    }
2604  }
2605  return clz;
2606}
2607
2608/** Function for deriving LM intra prediction.
2609 * \param pcPattern pointer to neighbouring pixel access pattern
2610 * \param pSrc0 pointer to reconstructed chroma sample array
2611 * \param iSrcStride the stride of reconstructed chroma sample array
2612 * \param pDst0 reference to pointer for the prediction sample array
2613 * \param iDstStride the stride of the prediction sample array
2614 * \param uiWidth the width of the chroma block
2615 * \param uiHeight the height of the chroma block
2616 * \param uiExt0 line number of neiggboirng pixels for calculating LM model parameter, default value is 1
2617 *
2618 * This function derives the prediction samples for chroma LM mode (chroma intra coding)
2619 */
2620Void TComPrediction::xGetLLSPrediction( TComPattern* pcPattern, Int* pSrc0, Int iSrcStride, Pel* pDst0, Int iDstStride, UInt uiWidth, UInt uiHeight, UInt uiExt0 )
2621{
2622
2623  Pel  *pDst, *pLuma;
2624  Int  *pSrc;
2625
2626  Int  iLumaStride = m_iLumaRecStride;
2627  Pel* pLuma0 = m_pLumaRecBuffer + uiExt0 * iLumaStride + uiExt0;
2628
2629  Int i, j, iCountShift = 0;
2630
2631  UInt uiExt = uiExt0;
2632
2633  // LLS parameters estimation -->
2634
2635  Int x = 0, y = 0, xx = 0, xy = 0;
2636
2637  pSrc  = pSrc0  - iSrcStride;
2638  pLuma = pLuma0 - iLumaStride;
2639
2640  for( j = 0; j < uiWidth; j++ )
2641  {
2642    x += pLuma[j];
2643    y += pSrc[j];
2644    xx += pLuma[j] * pLuma[j];
2645    xy += pLuma[j] * pSrc[j];
2646  }
2647  iCountShift += g_aucConvertToBit[ uiWidth ] + 2;
2648
2649  pSrc  = pSrc0 - uiExt;
2650  pLuma = pLuma0 - uiExt;
2651
2652  for( i = 0; i < uiHeight; i++ )
2653  {
2654    x += pLuma[0];
2655    y += pSrc[0];
2656    xx += pLuma[0] * pLuma[0];
2657    xy += pLuma[0] * pSrc[0];
2658
2659    pSrc  += iSrcStride;
2660    pLuma += iLumaStride;
2661  }
2662  iCountShift += iCountShift > 0 ? 1 : ( g_aucConvertToBit[ uiWidth ] + 2 );
2663
2664  Int iTempShift = ( g_uiBitDepth + g_uiBitIncrement ) + g_aucConvertToBit[ uiWidth ] + 3 - 15;
2665
2666  if(iTempShift > 0)
2667  {
2668    x  = ( x +  ( 1 << ( iTempShift - 1 ) ) ) >> iTempShift;
2669    y  = ( y +  ( 1 << ( iTempShift - 1 ) ) ) >> iTempShift;
2670    xx = ( xx + ( 1 << ( iTempShift - 1 ) ) ) >> iTempShift;
2671    xy = ( xy + ( 1 << ( iTempShift - 1 ) ) ) >> iTempShift;
2672    iCountShift -= iTempShift;
2673  }
2674
2675  Int a, b, iShift = 13;
2676
2677  if( iCountShift == 0 )
2678  {
2679    a = 0;
2680    b = 1 << (g_uiBitDepth + g_uiBitIncrement - 1);
2681    iShift = 0;
2682  }
2683  else
2684  {
2685    Int a1 = ( xy << iCountShift ) - y * x;
2686    Int a2 = ( xx << iCountShift ) - x * x;             
2687
2688    {
2689      const Int iShiftA2 = 6;
2690      const Int iShiftA1 = 15;
2691      const Int iAccuracyShift = 15;
2692
2693      Int iScaleShiftA2 = 0;
2694      Int iScaleShiftA1 = 0;
2695      Int a1s = a1;
2696      Int a2s = a2;
2697
2698      iScaleShiftA1 = GetMSB( abs( a1 ) ) - iShiftA1;
2699      iScaleShiftA2 = GetMSB( abs( a2 ) ) - iShiftA2; 
2700
2701      if( iScaleShiftA1 < 0 )
2702      {
2703        iScaleShiftA1 = 0;
2704      }
2705     
2706      if( iScaleShiftA2 < 0 )
2707      {
2708        iScaleShiftA2 = 0;
2709      }
2710     
2711      Int iScaleShiftA = iScaleShiftA2 + iAccuracyShift - iShift - iScaleShiftA1;
2712
2713      a2s = a2 >> iScaleShiftA2;
2714
2715      a1s = a1 >> iScaleShiftA1;
2716
2717      if (a2s >= 1)
2718      {
2719        a = a1s * m_uiaShift[ a2s - 1];
2720      }
2721      else
2722      {
2723        a = 0;
2724      }
2725     
2726      if( iScaleShiftA < 0 )
2727      {
2728        a = a << -iScaleShiftA;
2729      }
2730      else
2731      {
2732        a = a >> iScaleShiftA;
2733      }
2734     
2735       a = Clip3(-( 1 << 15 ), ( 1 << 15 ) - 1, a); 
2736     
2737      Int minA = -(1 << (6));
2738      Int maxA = (1 << 6) - 1;
2739      if( a <= maxA && a >= minA )
2740      {
2741        // do nothing
2742      }
2743      else
2744      {
2745        Short n = CountLeadingZerosOnes(a);
2746        a = a >> (9-n);
2747        iShift -= (9-n);
2748      }
2749
2750      b = (  y - ( ( a * x ) >> iShift ) + ( 1 << ( iCountShift - 1 ) ) ) >> iCountShift;
2751    }
2752  }   
2753
2754  // <-- end of LLS parameters estimation
2755
2756  // get prediction -->
2757  uiExt = uiExt0;
2758  pLuma = pLuma0;
2759  pDst = pDst0;
2760
2761  for( i = 0; i < uiHeight; i++ )
2762  {
2763    for( j = 0; j < uiWidth; j++ )
2764    {
2765      pDst[j] = Clip( ( ( a * pLuma[j] ) >> iShift ) + b );
2766    }
2767   
2768    pDst  += iDstStride;
2769    pLuma += iLumaStride;
2770  }
2771  // <-- end of get prediction
2772
2773}
2774
2775
2776#if LGE_ILLUCOMP_B0045
2777/** Function for deriving LM illumination compensation.
2778 */
2779Void TComPrediction::xGetLLSICPrediction(TComDataCU* pcCU, TComMv *pMv, TComPicYuv *pRefPic, Int &a, Int &b, Int &iShift)
2780{
2781  TComPicYuv *pRecPic = pcCU->getPic()->getPicYuvRec();
2782  Pel *pRec, *pRef;
2783  UInt uiWidth, uiHeight, uiTmpPartIdx;
2784  Int iRecStride = pRecPic->getStride(), iRefStride = pRefPic->getStride();
2785  Int iCUPelX, iCUPelY, iRefX, iRefY, iRefOffset;
2786
2787  iCUPelX = pcCU->getCUPelX() + g_auiRasterToPelX[g_auiZscanToRaster[pcCU->getZorderIdxInCU()]];
2788  iCUPelY = pcCU->getCUPelY() + g_auiRasterToPelY[g_auiZscanToRaster[pcCU->getZorderIdxInCU()]];
2789#if LGE_ROUND_OFFSET_D0135
2790  iRefX   = iCUPelX + ((pMv->getHor()+2) >> 2);
2791  iRefY   = iCUPelY + ((pMv->getVer()+2) >> 2);
2792#else
2793  iRefX   = iCUPelX + (pMv->getHor() >> 2);
2794  iRefY   = iCUPelY + (pMv->getVer() >> 2);
2795#endif
2796  uiWidth = pcCU->getWidth(0);
2797  uiHeight = pcCU->getHeight(0);
2798
2799  Int i, j, iCountShift = 0;
2800
2801  // LLS parameters estimation -->
2802
2803  Int x = 0, y = 0, xx = 0, xy = 0;
2804
2805  if(pcCU->getPUAbove(uiTmpPartIdx, pcCU->getZorderIdxInCU()) && iCUPelY > 0 && iRefY > 0)
2806  {
2807#if LGE_ROUND_OFFSET_D0135
2808    iRefOffset = ( (pMv->getHor()+2) >> 2 ) + ( (pMv->getVer()+2) >> 2 ) * iRefStride - iRefStride;
2809#else
2810    iRefOffset = ( pMv->getHor() >> 2 ) + ( pMv->getVer() >> 2 ) * iRefStride - iRefStride;
2811#endif
2812    pRef = pRefPic->getLumaAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() ) + iRefOffset;
2813    pRec = pRecPic->getLumaAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() ) - iRecStride;
2814
2815    for( j = 0; j < uiWidth; j++ )
2816    {
2817      x += pRef[j];
2818      y += pRec[j];
2819      xx += pRef[j] * pRef[j];
2820      xy += pRef[j] * pRec[j];
2821    }
2822    iCountShift += g_aucConvertToBit[ uiWidth ] + 2;
2823  }
2824
2825
2826  if(pcCU->getPULeft(uiTmpPartIdx, pcCU->getZorderIdxInCU()) && iCUPelX > 0 && iRefX > 0)
2827  {
2828#if LGE_ROUND_OFFSET_D0135
2829    iRefOffset = ( (pMv->getHor()+2) >> 2 ) + ( (pMv->getVer()+2) >> 2 ) * iRefStride - 1;
2830#else
2831    iRefOffset = ( pMv->getHor() >> 2 ) + ( pMv->getVer() >> 2 ) * iRefStride - 1;
2832#endif
2833    pRef = pRefPic->getLumaAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() ) + iRefOffset;
2834    pRec = pRecPic->getLumaAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() ) - 1;
2835
2836    for( i = 0; i < uiHeight; i++ )
2837    {
2838      x += pRef[0];
2839      y += pRec[0];
2840      xx += pRef[0] * pRef[0];
2841      xy += pRef[0] * pRec[0];
2842
2843      pRef += iRefStride;
2844      pRec += iRecStride;
2845    }
2846    iCountShift += iCountShift > 0 ? 1 : ( g_aucConvertToBit[ uiWidth ] + 2 );
2847  }
2848
2849  Int iTempShift = ( g_uiBitDepth + g_uiBitIncrement ) + g_aucConvertToBit[ uiWidth ] + 3 - 15;
2850
2851  if(iTempShift > 0)
2852  {
2853    x  = ( x +  ( 1 << ( iTempShift - 1 ) ) ) >> iTempShift;
2854    y  = ( y +  ( 1 << ( iTempShift - 1 ) ) ) >> iTempShift;
2855    xx = ( xx + ( 1 << ( iTempShift - 1 ) ) ) >> iTempShift;
2856    xy = ( xy + ( 1 << ( iTempShift - 1 ) ) ) >> iTempShift;
2857    iCountShift -= iTempShift;
2858  }
2859
2860  iShift = 13;
2861
2862  if( iCountShift == 0 )
2863  {
2864    a = 1;
2865    b = 0;
2866    iShift = 0;
2867  }
2868  else
2869  {
2870    Int a1 = ( xy << iCountShift ) - y * x;
2871    Int a2 = ( xx << iCountShift ) - x * x;             
2872
2873    {
2874      const Int iShiftA2 = 6;
2875      const Int iShiftA1 = 15;
2876      const Int iAccuracyShift = 15;
2877
2878      Int iScaleShiftA2 = 0;
2879      Int iScaleShiftA1 = 0;
2880      Int a1s = a1;
2881      Int a2s = a2;
2882
2883      iScaleShiftA1 = GetMSB( abs( a1 ) ) - iShiftA1;
2884      iScaleShiftA2 = GetMSB( abs( a2 ) ) - iShiftA2; 
2885
2886      if( iScaleShiftA1 < 0 )
2887      {
2888        iScaleShiftA1 = 0;
2889      }
2890
2891      if( iScaleShiftA2 < 0 )
2892      {
2893        iScaleShiftA2 = 0;
2894      }
2895
2896      Int iScaleShiftA = iScaleShiftA2 + iAccuracyShift - iShift - iScaleShiftA1;
2897
2898      a2s = a2 >> iScaleShiftA2;
2899
2900      a1s = a1 >> iScaleShiftA1;
2901
2902      if (a2s >= 1)
2903      {
2904        a = a1s * m_uiaShift[ a2s - 1];
2905      }
2906      else
2907      {
2908        a = 0;
2909      }
2910
2911      if( iScaleShiftA < 0 )
2912      {
2913        a = a << -iScaleShiftA;
2914      }
2915      else
2916      {
2917        a = a >> iScaleShiftA;
2918      }
2919
2920      a = Clip3(-( 1 << 15 ), ( 1 << 15 ) - 1, a); 
2921
2922      Int minA = -(1 << (6));
2923      Int maxA = (1 << 6) - 1;
2924      if( a <= maxA && a >= minA )
2925      {
2926        // do nothing
2927      }
2928      else
2929      {
2930        Short n = CountLeadingZerosOnes(a);
2931        a = a >> (9-n);
2932        iShift -= (9-n);
2933      }
2934
2935      b = (  y - ( ( a * x ) >> iShift ) + ( 1 << ( iCountShift - 1 ) ) ) >> iCountShift;
2936    }
2937  }   
2938}
2939
2940Void TComPrediction::xGetLLSICPredictionChroma(TComDataCU* pcCU, TComMv *pMv, TComPicYuv *pRefPic, Int &a, Int &b, Int &iShift, Int iChromaId)
2941{
2942  TComPicYuv *pRecPic = pcCU->getPic()->getPicYuvRec();
2943  Pel *pRec = NULL, *pRef = NULL;
2944  UInt uiWidth, uiHeight, uiTmpPartIdx;
2945  Int iRecStride = pRecPic->getCStride(), iRefStride = pRefPic->getCStride();
2946  Int iCUPelX, iCUPelY, iRefX, iRefY, iRefOffset;
2947
2948  iCUPelX = pcCU->getCUPelX() + g_auiRasterToPelX[g_auiZscanToRaster[pcCU->getZorderIdxInCU()]];
2949  iCUPelY = pcCU->getCUPelY() + g_auiRasterToPelY[g_auiZscanToRaster[pcCU->getZorderIdxInCU()]];
2950#if LGE_ROUND_OFFSET_D0135
2951  iRefX   = iCUPelX + ((pMv->getHor()+2) >> 2);
2952  iRefY   = iCUPelY + ((pMv->getVer()+2) >> 2);
2953#else
2954  iRefX   = iCUPelX + (pMv->getHor() >> 2);
2955  iRefY   = iCUPelY + (pMv->getVer() >> 2);
2956#endif
2957  uiWidth = pcCU->getWidth(0) >> 1;
2958  uiHeight = pcCU->getHeight(0) >> 1;
2959
2960  Int i, j, iCountShift = 0;
2961
2962  // LLS parameters estimation -->
2963
2964  Int x = 0, y = 0, xx = 0, xy = 0;
2965
2966  if(pcCU->getPUAbove(uiTmpPartIdx, pcCU->getZorderIdxInCU()) && iCUPelY > 0 && iRefY > 0)
2967  {
2968#if LGE_ROUND_OFFSET_D0135
2969    iRefOffset = ( (pMv->getHor()+4) >> 3 ) + ( (pMv->getVer()+4) >> 3 ) * iRefStride - iRefStride;
2970#else
2971    iRefOffset = ( pMv->getHor() >> 3 ) + ( pMv->getVer() >> 3 ) * iRefStride - iRefStride;
2972#endif
2973    if (iChromaId == 0) // Cb
2974    {
2975      pRef = pRefPic->getCbAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() ) + iRefOffset;
2976      pRec = pRecPic->getCbAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() ) - iRecStride;
2977    }
2978    else if (iChromaId == 1) // Cr
2979    {
2980      pRef = pRefPic->getCrAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() ) + iRefOffset;
2981      pRec = pRecPic->getCrAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() ) - iRecStride;
2982    }
2983
2984    for( j = 0; j < uiWidth; j++ )
2985    {
2986      x += pRef[j];
2987      y += pRec[j];
2988      xx += pRef[j] * pRef[j];
2989      xy += pRef[j] * pRec[j];
2990    }
2991    iCountShift += g_aucConvertToBit[ uiWidth ] + 2;
2992  }
2993
2994
2995  if(pcCU->getPULeft(uiTmpPartIdx, pcCU->getZorderIdxInCU()) && iCUPelX > 0 && iRefX > 0)
2996  {
2997#if LGE_ROUND_OFFSET_D0135
2998    iRefOffset = ( (pMv->getHor()+4) >> 3 ) + ( (pMv->getVer()+4) >> 3 ) * iRefStride - 1;
2999#else
3000    iRefOffset = ( pMv->getHor() >> 3 ) + ( pMv->getVer() >> 3 ) * iRefStride - 1;
3001#endif
3002    if (iChromaId == 0) // Cb
3003    {
3004      pRef = pRefPic->getCbAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() ) + iRefOffset;
3005      pRec = pRecPic->getCbAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() ) - 1;
3006    }
3007    else if (iChromaId == 1) // Cr
3008    {
3009      pRef = pRefPic->getCrAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() ) + iRefOffset;
3010      pRec = pRecPic->getCrAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() ) - 1;
3011    }
3012
3013    for( i = 0; i < uiHeight; i++ )
3014    {
3015      x += pRef[0];
3016      y += pRec[0];
3017      xx += pRef[0] * pRef[0];
3018      xy += pRef[0] * pRec[0];
3019
3020      pRef += iRefStride;
3021      pRec += iRecStride;
3022    }
3023    iCountShift += iCountShift > 0 ? 1 : ( g_aucConvertToBit[ uiWidth ] + 2 );
3024  }
3025
3026  Int iTempShift = ( g_uiBitDepth + g_uiBitIncrement ) + g_aucConvertToBit[ uiWidth ] + 3 - 15;
3027
3028  if(iTempShift > 0)
3029  {
3030    x  = ( x +  ( 1 << ( iTempShift - 1 ) ) ) >> iTempShift;
3031    y  = ( y +  ( 1 << ( iTempShift - 1 ) ) ) >> iTempShift;
3032    xx = ( xx + ( 1 << ( iTempShift - 1 ) ) ) >> iTempShift;
3033    xy = ( xy + ( 1 << ( iTempShift - 1 ) ) ) >> iTempShift;
3034    iCountShift -= iTempShift;
3035  }
3036
3037  iShift = 13;
3038
3039  if( iCountShift == 0 )
3040  {
3041    a = 1;
3042    b = 0;
3043    iShift = 0;
3044  }
3045  else
3046  {
3047    Int a1 = ( xy << iCountShift ) - y * x;
3048    Int a2 = ( xx << iCountShift ) - x * x;             
3049
3050    {
3051      const Int iShiftA2 = 6;
3052      const Int iShiftA1 = 15;
3053      const Int iAccuracyShift = 15;
3054
3055      Int iScaleShiftA2 = 0;
3056      Int iScaleShiftA1 = 0;
3057      Int a1s = a1;
3058      Int a2s = a2;
3059
3060      iScaleShiftA1 = GetMSB( abs( a1 ) ) - iShiftA1;
3061      iScaleShiftA2 = GetMSB( abs( a2 ) ) - iShiftA2; 
3062
3063      if( iScaleShiftA1 < 0 )
3064      {
3065        iScaleShiftA1 = 0;
3066      }
3067
3068      if( iScaleShiftA2 < 0 )
3069      {
3070        iScaleShiftA2 = 0;
3071      }
3072
3073      Int iScaleShiftA = iScaleShiftA2 + iAccuracyShift - iShift - iScaleShiftA1;
3074
3075      a2s = a2 >> iScaleShiftA2;
3076
3077      a1s = a1 >> iScaleShiftA1;
3078
3079      if (a2s >= 1)
3080      {
3081        a = a1s * m_uiaShift[ a2s - 1];
3082      }
3083      else
3084      {
3085        a = 0;
3086      }
3087
3088      if( iScaleShiftA < 0 )
3089      {
3090        a = a << -iScaleShiftA;
3091      }
3092      else
3093      {
3094        a = a >> iScaleShiftA;
3095      }
3096
3097      a = Clip3(-( 1 << 15 ), ( 1 << 15 ) - 1, a); 
3098
3099      Int minA = -(1 << (6));
3100      Int maxA = (1 << 6) - 1;
3101      if( a <= maxA && a >= minA )
3102      {
3103        // do nothing
3104      }
3105      else
3106      {
3107        Short n = CountLeadingZerosOnes(a);
3108        a = a >> (9-n);
3109        iShift -= (9-n);
3110      }
3111
3112      b = (  y - ( ( a * x ) >> iShift ) + ( 1 << ( iCountShift - 1 ) ) ) >> iCountShift;
3113    }
3114  }   
3115}
3116#endif
3117/** Function for filtering intra DC predictor.
3118 * \param pSrc pointer to reconstructed sample array
3119 * \param iSrcStride the stride of the reconstructed sample array
3120 * \param rpDst reference to pointer for the prediction sample array
3121 * \param iDstStride the stride of the prediction sample array
3122 * \param iWidth the width of the block
3123 * \param iHeight the height of the block
3124 *
3125 * This function performs filtering left and top edges of the prediction samples for DC mode (intra coding).
3126 */
3127Void TComPrediction::xDCPredFiltering( Int* pSrc, Int iSrcStride, Pel*& rpDst, Int iDstStride, Int iWidth, Int iHeight )
3128{
3129  Pel* pDst = rpDst;
3130  Int x, y, iDstStride2, iSrcStride2;
3131
3132  // boundary pixels processing
3133  pDst[0] = (Pel)((pSrc[-iSrcStride] + pSrc[-1] + 2 * pDst[0] + 2) >> 2);
3134
3135  for ( x = 1; x < iWidth; x++ )
3136  {
3137    pDst[x] = (Pel)((pSrc[x - iSrcStride] +  3 * pDst[x] + 2) >> 2);
3138  }
3139
3140  for ( y = 1, iDstStride2 = iDstStride, iSrcStride2 = iSrcStride-1; y < iHeight; y++, iDstStride2+=iDstStride, iSrcStride2+=iSrcStride )
3141  {
3142    pDst[iDstStride2] = (Pel)((pSrc[iSrcStride2] + 3 * pDst[iDstStride2] + 2) >> 2);
3143  }
3144
3145  return;
3146}
3147
3148#if HHI_DMM_WEDGE_INTRA || HHI_DMM_PRED_TEX
3149Void TComPrediction::predIntraLumaDMM( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiMode, Pel* piPred, UInt uiStride, Int iWidth, Int iHeight, Bool bAbove, Bool bLeft, Bool bEncoder )
3150{
3151#if HHI_DMM_WEDGE_INTRA
3152  if( uiMode == DMM_WEDGE_FULL_IDX        ) { xPredIntraWedgeFull ( pcCU, uiAbsPartIdx, piPred, uiStride, iWidth, iHeight, bAbove, bLeft, bEncoder, false, pcCU->getWedgeFullTabIdx ( uiAbsPartIdx ) ); }
3153  if( uiMode == DMM_WEDGE_FULL_D_IDX      ) { xPredIntraWedgeFull ( pcCU, uiAbsPartIdx, piPred, uiStride, iWidth, iHeight, bAbove, bLeft, bEncoder, true,  pcCU->getWedgeFullTabIdx( uiAbsPartIdx ), pcCU->getWedgeFullDeltaDC1( uiAbsPartIdx ), pcCU->getWedgeFullDeltaDC2( uiAbsPartIdx ) ); }
3154  if( uiMode == DMM_WEDGE_PREDDIR_IDX     ) { xPredIntraWedgeDir  ( pcCU, uiAbsPartIdx, piPred, uiStride, iWidth, iHeight, bAbove, bLeft, bEncoder, false, pcCU->getWedgePredDirDeltaEnd( uiAbsPartIdx ) ); }
3155  if( uiMode == DMM_WEDGE_PREDDIR_D_IDX   ) { xPredIntraWedgeDir  ( pcCU, uiAbsPartIdx, piPred, uiStride, iWidth, iHeight, bAbove, bLeft, bEncoder, true,  pcCU->getWedgePredDirDeltaEnd( uiAbsPartIdx ), pcCU->getWedgePredDirDeltaDC1( uiAbsPartIdx ), pcCU->getWedgePredDirDeltaDC2( uiAbsPartIdx ) ); }
3156#endif
3157#if HHI_DMM_PRED_TEX
3158  if( uiMode == DMM_WEDGE_PREDTEX_IDX     ) { xPredIntraWedgeTex  ( pcCU, uiAbsPartIdx, piPred, uiStride, iWidth, iHeight, bAbove, bLeft, bEncoder, false ); }
3159  if( uiMode == DMM_WEDGE_PREDTEX_D_IDX   ) { xPredIntraWedgeTex  ( pcCU, uiAbsPartIdx, piPred, uiStride, iWidth, iHeight, bAbove, bLeft, bEncoder, true, pcCU->getWedgePredTexDeltaDC1( uiAbsPartIdx ), pcCU->getWedgePredTexDeltaDC2( uiAbsPartIdx ) ); }
3160  if( uiMode == DMM_CONTOUR_PREDTEX_IDX   ) { xPredIntraContourTex( pcCU, uiAbsPartIdx, piPred, uiStride, iWidth, iHeight, bAbove, bLeft, bEncoder, false ); }
3161  if( uiMode == DMM_CONTOUR_PREDTEX_D_IDX ) { xPredIntraContourTex( pcCU, uiAbsPartIdx, piPred, uiStride, iWidth, iHeight, bAbove, bLeft, bEncoder, true, pcCU->getContourPredTexDeltaDC1( uiAbsPartIdx ), pcCU->getContourPredTexDeltaDC2( uiAbsPartIdx ) ); }
3162#endif
3163}
3164
3165Void TComPrediction::getWedgePredDCs( TComWedgelet* pcWedgelet, Int* piMask, Int iMaskStride, Int& riPredDC1, Int& riPredDC2, Bool bAbove, Bool bLeft )
3166{
3167  riPredDC1 = ( 1<<( g_uiBitDepth + g_uiBitIncrement - 1) ); //pred val, if no neighbors are available
3168  riPredDC2 = ( 1<<( g_uiBitDepth + g_uiBitIncrement - 1) );
3169
3170  if( !bAbove && !bLeft ) { return; }
3171
3172  UInt uiNumSmpDC1 = 0, uiNumSmpDC2 = 0;
3173  Int iPredDC1 = 0, iPredDC2 = 0;
3174
3175  Bool* pabWedgePattern = pcWedgelet->getPattern();
3176  UInt  uiWedgeStride   = pcWedgelet->getStride();
3177
3178#if HS_REFERENCE_SUBSAMPLE_C0154
3179  Int subSamplePix;
3180  if ( pcWedgelet->getWidth() == 32 )
3181  {
3182    subSamplePix = 2;
3183  }
3184  else
3185  {
3186    subSamplePix = 1;
3187  }
3188#endif
3189
3190  if( bAbove )
3191  {
3192#if HS_REFERENCE_SUBSAMPLE_C0154
3193    for( Int k = 0; k < pcWedgelet->getWidth(); k+=subSamplePix )
3194#else
3195    for( Int k = 0; k < pcWedgelet->getWidth(); k++ )
3196#endif
3197    {
3198      if( true == pabWedgePattern[k] )
3199      {
3200        iPredDC2 += piMask[k-iMaskStride];
3201        uiNumSmpDC2++;
3202      }
3203      else
3204      {
3205        iPredDC1 += piMask[k-iMaskStride];
3206        uiNumSmpDC1++;
3207      }
3208    }
3209  }
3210  if( bLeft )
3211  {
3212#if HS_REFERENCE_SUBSAMPLE_C0154
3213    for( Int k = 0; k < pcWedgelet->getHeight(); k+=subSamplePix )
3214#else
3215    for( Int k = 0; k < pcWedgelet->getHeight(); k++ )
3216#endif
3217    {
3218      if( true == pabWedgePattern[k*uiWedgeStride] )
3219      {
3220        iPredDC2 += piMask[k*iMaskStride-1];
3221        uiNumSmpDC2++;
3222      } 
3223      else
3224      {
3225        iPredDC1 += piMask[k*iMaskStride-1];
3226        uiNumSmpDC1++;
3227      }
3228    }
3229  }
3230
3231  if( uiNumSmpDC1 > 0 )
3232  {
3233    iPredDC1 /= uiNumSmpDC1;
3234    riPredDC1 = iPredDC1;
3235  }
3236  if( uiNumSmpDC2 > 0 )
3237  {
3238    iPredDC2 /= uiNumSmpDC2;
3239    riPredDC2 = iPredDC2;
3240  }
3241}
3242
3243Void TComPrediction::calcWedgeDCs( TComWedgelet* pcWedgelet, Pel* piOrig, UInt uiStride, Int& riDC1, Int& riDC2 )
3244{
3245  UInt uiDC1 = 0;
3246  UInt uiDC2 = 0;
3247  UInt uiNumPixDC1 = 0, uiNumPixDC2 = 0;
3248  Bool* pabWedgePattern = pcWedgelet->getPattern();
3249  if( uiStride == pcWedgelet->getStride() )
3250  {
3251    for( UInt k = 0; k < (pcWedgelet->getWidth() * pcWedgelet->getHeight()); k++ )
3252    {
3253      if( true == pabWedgePattern[k] ) 
3254      {
3255        uiDC2 += piOrig[k];
3256        uiNumPixDC2++;
3257      }
3258      else
3259      {
3260        uiDC1 += piOrig[k];
3261        uiNumPixDC1++;
3262      }
3263    }
3264  }
3265  else
3266  {
3267    Pel* piTemp = piOrig;
3268    UInt uiWedgeStride = pcWedgelet->getStride();
3269    for( UInt uiY = 0; uiY < pcWedgelet->getHeight(); uiY++ )
3270    {
3271      for( UInt uiX = 0; uiX < pcWedgelet->getWidth(); uiX++ )
3272      {
3273        if( true == pabWedgePattern[uiX] ) 
3274        {
3275          uiDC2 += piTemp[uiX];
3276          uiNumPixDC2++;
3277        }
3278        else
3279        {
3280          uiDC1 += piTemp[uiX];
3281          uiNumPixDC1++;
3282        }
3283      }
3284      piTemp          += uiStride;
3285      pabWedgePattern += uiWedgeStride;
3286    }
3287  }
3288
3289  if( uiNumPixDC1 > 0 ) { riDC1 = uiDC1 / uiNumPixDC1; }
3290  else                  { riDC1 = ( 1<<( g_uiBitDepth + g_uiBitIncrement - 1) ); }
3291
3292  if( uiNumPixDC2 > 0 ) { riDC2 = uiDC2 / uiNumPixDC2; }
3293  else                  { riDC2 = ( 1<<( g_uiBitDepth + g_uiBitIncrement - 1) ); }
3294}
3295
3296Void TComPrediction::assignWedgeDCs2Pred( TComWedgelet* pcWedgelet, Pel* piPred, UInt uiStride, Int iDC1, Int iDC2 )
3297{
3298  Bool* pabWedgePattern = pcWedgelet->getPattern();
3299
3300  if( uiStride == pcWedgelet->getStride() )
3301  {
3302    for( UInt k = 0; k < (pcWedgelet->getWidth() * pcWedgelet->getHeight()); k++ )
3303    {
3304      if( true == pabWedgePattern[k] ) 
3305      {
3306        piPred[k] = iDC2;
3307      }
3308      else
3309      {
3310        piPred[k] = iDC1;
3311      }
3312    }
3313  }
3314  else
3315  {
3316    Pel* piTemp = piPred;
3317    UInt uiWedgeStride = pcWedgelet->getStride();
3318    for( UInt uiY = 0; uiY < pcWedgelet->getHeight(); uiY++ )
3319    {
3320      for( UInt uiX = 0; uiX < pcWedgelet->getWidth(); uiX++ )
3321      {
3322        if( true == pabWedgePattern[uiX] ) 
3323        {
3324          piTemp[uiX] = iDC2;
3325        }
3326        else
3327        {
3328          piTemp[uiX] = iDC1;
3329        }
3330      }
3331      piTemp          += uiStride;
3332      pabWedgePattern += uiWedgeStride;
3333    }
3334  }
3335}
3336
3337Void TComPrediction::xDeltaDCQuantScaleUp( TComDataCU* pcCU, Int& riDeltaDC )
3338{
3339  Int  iSign  = riDeltaDC < 0 ? -1 : 1;
3340  UInt uiAbs  = abs( riDeltaDC );
3341
3342  Int iQp = pcCU->getQP(0);
3343  Double dMax = (Double)( 1<<( g_uiBitDepth + g_uiBitIncrement - 1) );
3344  Double dStepSize = Clip3( 1.0, dMax, pow( 2.0, iQp/10.0 + g_iDeltaDCsQuantOffset ) );
3345
3346  riDeltaDC = iSign * roftoi( uiAbs * dStepSize );
3347  return;
3348}
3349
3350Void TComPrediction::xDeltaDCQuantScaleDown( TComDataCU*  pcCU, Int& riDeltaDC )
3351{
3352  Int  iSign  = riDeltaDC < 0 ? -1 : 1;
3353  UInt uiAbs  = abs( riDeltaDC );
3354
3355  Int iQp = pcCU->getQP(0);
3356  Double dMax = (Double)( 1<<( g_uiBitDepth + g_uiBitIncrement - 1) );
3357  Double dStepSize = Clip3( 1.0, dMax, pow( 2.0, iQp/10.0 + g_iDeltaDCsQuantOffset ) );
3358
3359  riDeltaDC = iSign * roftoi( uiAbs / dStepSize );
3360  return;
3361}
3362#endif
3363
3364#if HHI_DMM_PRED_TEX
3365Void TComPrediction::getBestContourFromTex( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiWidth, UInt uiHeight, TComWedgelet* pcContourWedge )
3366{
3367  pcContourWedge->clear();
3368
3369  // get copy of co-located texture luma block
3370  TComYuv cTempYuv;
3371  cTempYuv.create( uiWidth, uiHeight ); 
3372  cTempYuv.clear();
3373  Pel* piRefBlkY = cTempYuv.getLumaAddr();
3374  copyTextureLumaBlock( pcCU, uiAbsPartIdx, piRefBlkY, uiWidth, uiHeight );
3375  piRefBlkY = cTempYuv.getLumaAddr();
3376
3377  // find contour for texture luma block
3378  UInt iDC = 0;
3379  for( UInt k = 0; k < (uiWidth*uiHeight); k++ ) 
3380  { 
3381    iDC += piRefBlkY[k]; 
3382  }
3383  iDC /= (uiWidth*uiHeight);
3384  piRefBlkY = cTempYuv.getLumaAddr();
3385
3386  Bool* pabContourPattern = pcContourWedge->getPattern();
3387  for( UInt k = 0; k < (uiWidth*uiHeight); k++ ) 
3388  { 
3389    pabContourPattern[k] = (piRefBlkY[k] > iDC) ? true : false;
3390  }
3391
3392  cTempYuv.destroy();
3393}
3394
3395#if LGE_DMM3_SIMP_C0044
3396/**
3397 - fetch best Wedgelet pattern at decoder
3398 */
3399UInt TComPrediction::getBestWedgeFromTex( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiWidth, UInt uiHeight, UInt IntraTabIdx)
3400{
3401  assert( uiWidth >= DMM_WEDGEMODEL_MIN_SIZE && uiWidth <= DMM_WEDGEMODEL_MAX_SIZE );
3402
3403  UInt          uiBestTabIdx = 0;
3404  TComPic*      pcPicTex = pcCU->getSlice()->getTexturePic();
3405  TComDataCU*   pcColTexCU = pcPicTex->getCU(pcCU->getAddr());
3406  UInt          uiTexPartIdx = pcCU->getZorderIdxInCU() + uiAbsPartIdx;
3407  Int           uiColTexIntraDir = pcColTexCU->isIntra( uiTexPartIdx ) ? pcColTexCU->getLumaIntraDir( uiTexPartIdx ) : 255;
3408
3409  std::vector< std::vector<UInt> > pauiWdgLstSz = g_aauiWdgLstM3[g_aucConvertToBit[uiWidth]];
3410
3411  if( uiColTexIntraDir > DC_IDX && uiColTexIntraDir < 35 )
3412  {
3413    std::vector<UInt>* pauiWdgLst = &pauiWdgLstSz[uiColTexIntraDir-2];
3414    uiBestTabIdx    =   pauiWdgLst->at(IntraTabIdx);
3415  }
3416  else
3417  {
3418    WedgeNodeList* pacWedgeNodeList = &g_aacWedgeNodeLists[(g_aucConvertToBit[uiWidth])];
3419    uiBestTabIdx = pacWedgeNodeList->at(IntraTabIdx).getPatternIdx();
3420  }
3421
3422  return uiBestTabIdx;
3423}
3424#endif
3425
3426#if LGE_DMM3_SIMP_C0044
3427/**
3428 - calculate best Wedgelet pattern at encoder
3429 */
3430UInt TComPrediction::getBestWedgeFromTex( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiWidth, UInt uiHeight, Pel* piOrigi, UInt uiStride, UInt & ruiIntraTabIdx)
3431#else
3432UInt TComPrediction::getBestWedgeFromTex( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiWidth, UInt uiHeight )
3433#endif
3434{
3435  assert( uiWidth >= DMM_WEDGEMODEL_MIN_SIZE && uiWidth <= DMM_WEDGEMODEL_MAX_SIZE );
3436
3437  // get copy of co-located texture luma block
3438  TComYuv cTempYuv; 
3439  cTempYuv.create( uiWidth, uiHeight ); 
3440  cTempYuv.clear();
3441  Pel* piRefBlkY = cTempYuv.getLumaAddr();
3442
3443  copyTextureLumaBlock( pcCU, uiAbsPartIdx, piRefBlkY, uiWidth, uiHeight );
3444  piRefBlkY = cTempYuv.getLumaAddr();
3445
3446  // local pred buffer
3447  TComYuv cPredYuv; 
3448  cPredYuv.create( uiWidth, uiHeight ); 
3449  cPredYuv.clear();
3450  Pel* piPred = cPredYuv.getLumaAddr();
3451
3452  UInt uiPredStride = cPredYuv.getStride();
3453
3454  // wedge search
3455  TComWedgeDist cWedgeDist;
3456  UInt uiBestDist = MAX_UINT;
3457  UInt uiBestTabIdx = 0;
3458  Int  iDC1 = 0;
3459  Int  iDC2 = 0;
3460  WedgeList* pacWedgeList = &g_aacWedgeLists[(g_aucConvertToBit[uiWidth])];
3461#if LGE_DMM3_SIMP_C0044
3462  ruiIntraTabIdx  = 0;
3463#endif
3464  TComPic*      pcPicTex = pcCU->getSlice()->getTexturePic();
3465  TComDataCU* pcColTexCU = pcPicTex->getCU(pcCU->getAddr());
3466  UInt      uiTexPartIdx = pcCU->getZorderIdxInCU() + uiAbsPartIdx;
3467  Int   uiColTexIntraDir = pcColTexCU->isIntra( uiTexPartIdx ) ? pcColTexCU->getLumaIntraDir( uiTexPartIdx ) : 255;
3468
3469  std::vector< std::vector<UInt> > pauiWdgLstSz = g_aauiWdgLstM3[g_aucConvertToBit[uiWidth]];
3470  if( uiColTexIntraDir > DC_IDX && uiColTexIntraDir < 35 )
3471  {
3472    std::vector<UInt>* pauiWdgLst = &pauiWdgLstSz[uiColTexIntraDir-2];
3473    for( UInt uiIdxW = 0; uiIdxW < pauiWdgLst->size(); uiIdxW++ )
3474    {
3475      UInt uiIdx     =   pauiWdgLst->at(uiIdxW);
3476#if LGE_DMM3_SIMP_C0044
3477      calcWedgeDCs       ( &(pacWedgeList->at(uiIdx)), piOrigi,   uiWidth,      iDC1, iDC2 );
3478#else
3479      calcWedgeDCs       ( &(pacWedgeList->at(uiIdx)), piRefBlkY, uiWidth,      iDC1, iDC2 );
3480#endif
3481      assignWedgeDCs2Pred( &(pacWedgeList->at(uiIdx)), piPred,    uiPredStride, iDC1, iDC2 );
3482
3483#if LGE_DMM3_SIMP_C0044
3484      UInt uiActDist = cWedgeDist.getDistPart( piPred, uiPredStride, piOrigi, uiStride, uiWidth, uiHeight, WedgeDist_SAD );
3485#else
3486      UInt uiActDist = cWedgeDist.getDistPart( piPred, uiPredStride, piRefBlkY, uiWidth, uiWidth, uiHeight, WedgeDist_SAD );
3487#endif
3488
3489      if( uiActDist < uiBestDist || uiBestDist == MAX_UINT )
3490      {
3491        uiBestDist   = uiActDist;
3492        uiBestTabIdx = uiIdx;
3493#if LGE_DMM3_SIMP_C0044
3494        ruiIntraTabIdx = uiIdxW;
3495#endif
3496      }
3497    }
3498  }
3499  else
3500  {
3501    WedgeNodeList* pacWedgeNodeList = &g_aacWedgeNodeLists[(g_aucConvertToBit[uiWidth])];
3502    UInt uiBestNodeDist = MAX_UINT;
3503    UInt uiBestNodeId   = 0;
3504    for( UInt uiNodeId = 0; uiNodeId < pacWedgeNodeList->size(); uiNodeId++ )
3505    {
3506#if LGE_DMM3_SIMP_C0044
3507      calcWedgeDCs       ( &(pacWedgeList->at(pacWedgeNodeList->at(uiNodeId).getPatternIdx())), piOrigi, uiWidth,      iDC1, iDC2 );
3508#else
3509      calcWedgeDCs       ( &(pacWedgeList->at(pacWedgeNodeList->at(uiNodeId).getPatternIdx())), piRefBlkY, uiWidth,      iDC1, iDC2 );
3510#endif
3511      assignWedgeDCs2Pred( &(pacWedgeList->at(pacWedgeNodeList->at(uiNodeId).getPatternIdx())), piPred,    uiPredStride, iDC1, iDC2 );
3512
3513#if LGE_DMM3_SIMP_C0044
3514      UInt uiActDist = cWedgeDist.getDistPart( piPred, uiPredStride, piOrigi, uiStride, uiWidth, uiHeight, WedgeDist_SAD );
3515#else
3516      UInt uiActDist = cWedgeDist.getDistPart( piPred, uiPredStride, piRefBlkY, uiWidth, uiWidth, uiHeight, WedgeDist_SAD );
3517#endif
3518
3519      if( uiActDist < uiBestNodeDist || uiBestNodeDist == MAX_UINT )
3520      {
3521        uiBestNodeDist = uiActDist;
3522        uiBestNodeId   = uiNodeId;
3523#if LGE_DMM3_SIMP_C0044
3524        ruiIntraTabIdx = uiNodeId;
3525#endif
3526      }
3527    }
3528#if LGE_DMM3_SIMP_C0044
3529    uiBestTabIdx = pacWedgeNodeList->at(uiBestNodeId).getPatternIdx();
3530#else
3531    // refinement
3532    uiBestDist   = uiBestNodeDist;
3533    uiBestTabIdx = pacWedgeNodeList->at(uiBestNodeId).getPatternIdx();
3534    for( UInt uiRefId = 0; uiRefId < NUM_WEDGE_REFINES; uiRefId++ )
3535    {
3536      if( pacWedgeNodeList->at(uiBestNodeId).getRefineIdx( uiRefId ) != NO_IDX )
3537      {
3538        calcWedgeDCs       ( &(pacWedgeList->at(pacWedgeNodeList->at(uiBestNodeId).getRefineIdx( uiRefId ))), piRefBlkY, uiWidth,      iDC1, iDC2 );
3539        assignWedgeDCs2Pred( &(pacWedgeList->at(pacWedgeNodeList->at(uiBestNodeId).getRefineIdx( uiRefId ))), piPred,    uiPredStride, iDC1, iDC2 );
3540
3541        UInt uiActDist = cWedgeDist.getDistPart( piPred, uiPredStride, piRefBlkY, uiWidth, uiWidth, uiHeight, WedgeDist_SAD );
3542
3543        if( uiActDist < uiBestDist || uiBestDist == MAX_UINT )
3544        {
3545          uiBestDist   = uiActDist;
3546          uiBestTabIdx = pacWedgeNodeList->at(uiBestNodeId).getRefineIdx( uiRefId );
3547        }
3548      }
3549    }
3550#endif
3551  }
3552
3553  cPredYuv.destroy();
3554  cTempYuv.destroy();
3555  return uiBestTabIdx;
3556}
3557
3558Void TComPrediction::copyTextureLumaBlock( TComDataCU* pcCU, UInt uiAbsPartIdx, Pel* piDestBlockY, UInt uiWidth, UInt uiHeight )
3559{
3560  TComPicYuv* pcPicYuvRef = pcCU->getSlice()->getTexturePic()->getPicYuvRec();
3561  Int         iRefStride = pcPicYuvRef->getStride();
3562  Pel*        piRefY;
3563
3564  piRefY = pcPicYuvRef->getLumaAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() + uiAbsPartIdx );
3565
3566  for ( Int y = 0; y < uiHeight; y++ )
3567  {
3568    ::memcpy(piDestBlockY, piRefY, sizeof(Pel)*uiWidth);
3569//    ::memset(piDestBlockY, 128, sizeof(Pel)*uiWidth);
3570    piDestBlockY += uiWidth;
3571    piRefY += iRefStride;
3572  }
3573}
3574
3575Void TComPrediction::xPredIntraWedgeTex( TComDataCU* pcCU, UInt uiAbsPartIdx, Pel* piPred, UInt uiStride, Int iWidth, Int iHeight, Bool bAbove, Bool bLeft, Bool bEncoder, Bool bDelta, Int iDeltaDC1, Int iDeltaDC2 )
3576{
3577  assert( iWidth >= DMM_WEDGEMODEL_MIN_SIZE && iWidth <= DMM_WEDGEMODEL_MAX_SIZE );
3578  WedgeList* pacWedgeList = &g_aacWedgeLists[(g_aucConvertToBit[iWidth])];
3579
3580  // get wedge pattern
3581  UInt uiTextureWedgeTabIdx = 0;
3582  if( bEncoder ) 
3583  {
3584    // encoder: load stored wedge pattern from CU
3585    uiTextureWedgeTabIdx = pcCU->getWedgePredTexTabIdx( uiAbsPartIdx );
3586  }
3587  else
3588  {
3589    // decoder: get and store wedge pattern in CU
3590      // decoder: get and store wedge pattern in CU
3591#if LGE_DMM3_SIMP_C0044
3592    UInt uiIntraTabIdx   = pcCU->getWedgePredTexIntraTabIdx ( uiAbsPartIdx );
3593    uiTextureWedgeTabIdx = getBestWedgeFromTex( pcCU, uiAbsPartIdx, (UInt)iWidth, (UInt)iHeight, uiIntraTabIdx );
3594#else
3595    uiTextureWedgeTabIdx = getBestWedgeFromTex( pcCU, uiAbsPartIdx, (UInt)iWidth, (UInt)iHeight );
3596#endif
3597
3598    UInt uiDepth = (pcCU->getDepth(0)) + (pcCU->getPartitionSize(0) == SIZE_2Nx2N ? 0 : 1);
3599    pcCU->setWedgePredTexTabIdxSubParts( uiTextureWedgeTabIdx, uiAbsPartIdx, uiDepth );
3600  }
3601  TComWedgelet* pcWedgelet = &(pacWedgeList->at(uiTextureWedgeTabIdx));
3602
3603  // get wedge pred DCs
3604  Int iPredDC1 = 0;
3605  Int iPredDC2 = 0;
3606  Int* piMask = pcCU->getPattern()->getAdiOrgBuf( iWidth, iHeight, m_piYuvExt );
3607  Int iMaskStride = ( iWidth<<1 ) + 1;
3608  piMask += iMaskStride+1;
3609  getWedgePredDCs( pcWedgelet, piMask, iMaskStride, iPredDC1, iPredDC2, bAbove, bLeft );
3610
3611  // assign wedge pred DCs to prediction
3612  if( bDelta ) { assignWedgeDCs2Pred( pcWedgelet, piPred, uiStride, Clip ( iPredDC1+iDeltaDC1 ), Clip( iPredDC2+iDeltaDC2 ) ); }
3613  else         { assignWedgeDCs2Pred( pcWedgelet, piPred, uiStride,        iPredDC1,                   iPredDC2           ); }
3614}
3615
3616Void TComPrediction::xPredIntraContourTex( TComDataCU* pcCU, UInt uiAbsPartIdx, Pel* piPred, UInt uiStride, Int iWidth, Int iHeight, Bool bAbove, Bool bLeft, Bool bEncoder, Bool bDelta, Int iDeltaDC1, Int iDeltaDC2 )
3617{
3618  // get contour pattern
3619  TComWedgelet* pcContourWedge = new TComWedgelet( iWidth, iHeight );
3620  getBestContourFromTex( pcCU, uiAbsPartIdx, (UInt)iWidth, (UInt)iHeight, pcContourWedge );
3621
3622  // get wedge pred DCs
3623  Int iPredDC1 = 0;
3624  Int iPredDC2 = 0;
3625  Int* piMask = pcCU->getPattern()->getAdiOrgBuf( iWidth, iHeight, m_piYuvExt );
3626  Int iMaskStride = ( iWidth<<1 ) + 1;
3627  piMask += iMaskStride+1;
3628  getWedgePredDCs( pcContourWedge, piMask, iMaskStride, iPredDC1, iPredDC2, bAbove, bLeft );
3629
3630  // assign wedge pred DCs to prediction
3631  if( bDelta ) { assignWedgeDCs2Pred( pcContourWedge, piPred, uiStride, Clip ( iPredDC1+iDeltaDC1 ), Clip( iPredDC2+iDeltaDC2 ) ); }
3632  else         { assignWedgeDCs2Pred( pcContourWedge, piPred, uiStride,        iPredDC1,                   iPredDC2           ); }
3633
3634  pcContourWedge->destroy();
3635  delete pcContourWedge;
3636}
3637#endif // HHI_DMM_PRED_TEX
3638
3639#if HHI_DMM_WEDGE_INTRA
3640UInt TComPrediction::getBestContinueWedge( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiWidth, UInt uiHeight, Int iDeltaEnd )
3641{
3642  UInt uiThisBlockSize = uiWidth;
3643  assert( uiThisBlockSize >= DMM_WEDGEMODEL_MIN_SIZE && uiThisBlockSize <= DMM_WEDGEMODEL_MAX_SIZE );
3644  WedgeRefList* pacContDWedgeRefList = &g_aacWedgeRefLists[(g_aucConvertToBit[uiThisBlockSize])];
3645
3646  UInt uiPredDirWedgeTabIdx = 0;
3647  TComDataCU* pcTempCU;
3648  UInt        uiTempPartIdx;
3649  // 1st: try continue above wedgelet
3650  pcTempCU = pcCU->getPUAbove( uiTempPartIdx, pcCU->getZorderIdxInCU() + uiAbsPartIdx );
3651  if( pcTempCU )
3652  {
3653    UChar uhLumaIntraDir = pcTempCU->getLumaIntraDir( uiTempPartIdx );
3654    if( DMM_WEDGE_FULL_IDX      == uhLumaIntraDir || 
3655        DMM_WEDGE_FULL_D_IDX    == uhLumaIntraDir || 
3656        DMM_WEDGE_PREDDIR_IDX   == uhLumaIntraDir || 
3657        DMM_WEDGE_PREDDIR_D_IDX == uhLumaIntraDir
3658#if HHI_DMM_PRED_TEX
3659        ||
3660        DMM_WEDGE_PREDTEX_IDX   == uhLumaIntraDir ||
3661        DMM_WEDGE_PREDTEX_D_IDX == uhLumaIntraDir   
3662#endif
3663      )
3664    {
3665      UInt uiRefWedgeSize = (UInt)g_aucIntraSizeIdxToWedgeSize[pcTempCU->getIntraSizeIdx( uiTempPartIdx )];
3666      WedgeList* pacWedgeList = &g_aacWedgeLists[(g_aucConvertToBit[uiRefWedgeSize])];
3667
3668      // get offset between current and reference block
3669      UInt uiOffsetX = 0;
3670      UInt uiOffsetY = 0;
3671      xGetBlockOffset( pcCU, uiAbsPartIdx, pcTempCU, uiTempPartIdx, uiOffsetX, uiOffsetY );
3672
3673      // get reference wedgelet
3674      UInt uiRefWedgeTabIdx = 0;
3675      switch( uhLumaIntraDir )
3676      {
3677      case( DMM_WEDGE_FULL_IDX      ): { uiRefWedgeTabIdx = pcTempCU->getWedgeFullTabIdx   ( uiTempPartIdx ); } break;
3678      case( DMM_WEDGE_FULL_D_IDX    ): { uiRefWedgeTabIdx = pcTempCU->getWedgeFullTabIdx   ( uiTempPartIdx ); } break;
3679      case( DMM_WEDGE_PREDDIR_IDX   ): { uiRefWedgeTabIdx = pcTempCU->getWedgePredDirTabIdx( uiTempPartIdx ); } break;
3680      case( DMM_WEDGE_PREDDIR_D_IDX ): { uiRefWedgeTabIdx = pcTempCU->getWedgePredDirTabIdx( uiTempPartIdx ); } break;
3681#if HHI_DMM_PRED_TEX
3682      case( DMM_WEDGE_PREDTEX_IDX   ): { uiRefWedgeTabIdx = pcTempCU->getWedgePredTexTabIdx( uiTempPartIdx ); } break;
3683      case( DMM_WEDGE_PREDTEX_D_IDX ): { uiRefWedgeTabIdx = pcTempCU->getWedgePredTexTabIdx( uiTempPartIdx ); } break;
3684#endif
3685      default: { assert( 0 ); return uiPredDirWedgeTabIdx; }
3686      }
3687      TComWedgelet* pcRefWedgelet;
3688      pcRefWedgelet = &(pacWedgeList->at( uiRefWedgeTabIdx ));
3689
3690      // find reference wedgelet, if direction is suitable for continue wedge
3691      if( pcRefWedgelet->checkPredDirAbovePossible( uiThisBlockSize, uiOffsetX ) )
3692      {
3693        UChar uhContD_Xs, uhContD_Ys, uhContD_Xe, uhContD_Ye;
3694        pcRefWedgelet->getPredDirStartEndAbove( uhContD_Xs, uhContD_Ys, uhContD_Xe, uhContD_Ye, uiThisBlockSize, uiOffsetX, iDeltaEnd );
3695        getWedgePatternIdx( pacContDWedgeRefList, uiPredDirWedgeTabIdx, uhContD_Xs, uhContD_Ys, uhContD_Xe, uhContD_Ye );
3696        return uiPredDirWedgeTabIdx;
3697      }
3698    }
3699  }
3700
3701  // 2nd: try continue left wedglelet
3702  pcTempCU = pcCU->getPULeft( uiTempPartIdx, pcCU->getZorderIdxInCU() + uiAbsPartIdx );
3703  if( pcTempCU )
3704  {
3705    UChar uhLumaIntraDir = pcTempCU->getLumaIntraDir( uiTempPartIdx );
3706    if( DMM_WEDGE_FULL_IDX      == uhLumaIntraDir || 
3707        DMM_WEDGE_FULL_D_IDX    == uhLumaIntraDir || 
3708        DMM_WEDGE_PREDDIR_IDX   == uhLumaIntraDir || 
3709        DMM_WEDGE_PREDDIR_D_IDX == uhLumaIntraDir
3710#if HHI_DMM_PRED_TEX
3711        ||
3712        DMM_WEDGE_PREDTEX_IDX   == uhLumaIntraDir ||
3713        DMM_WEDGE_PREDTEX_D_IDX == uhLumaIntraDir   
3714#endif
3715      )
3716    {
3717      UInt uiRefWedgeSize = (UInt)g_aucIntraSizeIdxToWedgeSize[pcTempCU->getIntraSizeIdx( uiTempPartIdx )];
3718      WedgeList* pacWedgeList = &g_aacWedgeLists[(g_aucConvertToBit[uiRefWedgeSize])];
3719
3720      // get offset between current and reference block
3721      UInt uiOffsetX = 0;
3722      UInt uiOffsetY = 0;
3723      xGetBlockOffset( pcCU, uiAbsPartIdx, pcTempCU, uiTempPartIdx, uiOffsetX, uiOffsetY );
3724
3725      // get reference wedgelet
3726      UInt uiRefWedgeTabIdx = 0;
3727      switch( uhLumaIntraDir )
3728      {
3729      case( DMM_WEDGE_FULL_IDX      ): { uiRefWedgeTabIdx = pcTempCU->getWedgeFullTabIdx   ( uiTempPartIdx ); } break;
3730      case( DMM_WEDGE_FULL_D_IDX    ): { uiRefWedgeTabIdx = pcTempCU->getWedgeFullTabIdx   ( uiTempPartIdx ); } break;
3731      case( DMM_WEDGE_PREDDIR_IDX   ): { uiRefWedgeTabIdx = pcTempCU->getWedgePredDirTabIdx( uiTempPartIdx ); } break;
3732      case( DMM_WEDGE_PREDDIR_D_IDX ): { uiRefWedgeTabIdx = pcTempCU->getWedgePredDirTabIdx( uiTempPartIdx ); } break;
3733#if HHI_DMM_PRED_TEX
3734      case( DMM_WEDGE_PREDTEX_IDX   ): { uiRefWedgeTabIdx = pcTempCU->getWedgePredTexTabIdx( uiTempPartIdx ); } break;
3735      case( DMM_WEDGE_PREDTEX_D_IDX ): { uiRefWedgeTabIdx = pcTempCU->getWedgePredTexTabIdx( uiTempPartIdx ); } break;
3736#endif
3737      default: { assert( 0 ); return uiPredDirWedgeTabIdx; }
3738      }
3739      TComWedgelet* pcRefWedgelet;
3740      pcRefWedgelet = &(pacWedgeList->at( uiRefWedgeTabIdx ));
3741
3742      // find reference wedgelet, if direction is suitable for continue wedge
3743      if( pcRefWedgelet->checkPredDirLeftPossible( uiThisBlockSize, uiOffsetY ) )
3744      {
3745        UChar uhContD_Xs, uhContD_Ys, uhContD_Xe, uhContD_Ye;
3746        pcRefWedgelet->getPredDirStartEndLeft( uhContD_Xs, uhContD_Ys, uhContD_Xe, uhContD_Ye, uiThisBlockSize, uiOffsetY, iDeltaEnd );
3747        getWedgePatternIdx( pacContDWedgeRefList, uiPredDirWedgeTabIdx, uhContD_Xs, uhContD_Ys, uhContD_Xe, uhContD_Ye );
3748        return uiPredDirWedgeTabIdx;
3749      }
3750    }
3751  }
3752
3753  // 3rd: (default) make wedglet from intra dir and max slope point
3754  Int iSlopeX = 0;
3755  Int iSlopeY = 0;
3756  UInt uiStartPosX = 0;
3757  UInt uiStartPosY = 0;
3758  if( xGetWedgeIntraDirPredData( pcCU, uiAbsPartIdx, uiThisBlockSize, iSlopeX, iSlopeY, uiStartPosX, uiStartPosY ) )
3759  {
3760    UChar uhContD_Xs, uhContD_Ys, uhContD_Xe, uhContD_Ye;
3761    xGetWedgeIntraDirStartEnd( pcCU, uiAbsPartIdx, uiThisBlockSize, iSlopeX, iSlopeY, uiStartPosX, uiStartPosY, uhContD_Xs, uhContD_Ys, uhContD_Xe, uhContD_Ye, iDeltaEnd );
3762    getWedgePatternIdx( pacContDWedgeRefList, uiPredDirWedgeTabIdx, uhContD_Xs, uhContD_Ys, uhContD_Xe, uhContD_Ye );
3763    return uiPredDirWedgeTabIdx;
3764  }
3765
3766  return uiPredDirWedgeTabIdx;
3767}
3768
3769Bool TComPrediction::getWedgePatternIdx( WedgeRefList* pcWedgeRefList, UInt& ruiTabIdx, UChar uhXs, UChar uhYs, UChar uhXe, UChar uhYe )
3770{
3771  ruiTabIdx = 0;
3772
3773  for( UInt uiIdx = 0; uiIdx < pcWedgeRefList->size(); uiIdx++ )
3774  {
3775    TComWedgeRef* pcTestWedgeRef = &(pcWedgeRefList->at(uiIdx));
3776
3777    if( pcTestWedgeRef->getStartX() == uhXs &&
3778      pcTestWedgeRef->getStartY() == uhYs &&
3779      pcTestWedgeRef->getEndX()   == uhXe &&
3780      pcTestWedgeRef->getEndY()   == uhYe    )
3781    {
3782      ruiTabIdx = pcTestWedgeRef->getRefIdx();
3783      return true;
3784    }
3785  }
3786
3787  return false;
3788}
3789
3790Void TComPrediction::xPredIntraWedgeFull( TComDataCU* pcCU, UInt uiAbsPartIdx, Pel* piPred, UInt uiStride, Int iWidth, Int iHeight, Bool bAbove, Bool bLeft, Bool bEncoder, Bool bDelta, UInt uiTabIdx, Int iDeltaDC1, Int iDeltaDC2 )
3791{
3792  assert( iWidth >= DMM_WEDGEMODEL_MIN_SIZE && iWidth <= DMM_WEDGEMODEL_MAX_SIZE );
3793  WedgeList* pacWedgeList = &g_aacWedgeLists[(g_aucConvertToBit[iWidth])];
3794  TComWedgelet* pcWedgelet = &(pacWedgeList->at(uiTabIdx));
3795
3796  // get wedge pred DCs
3797  Int iPredDC1 = 0;
3798  Int iPredDC2 = 0;
3799
3800  Int* piMask = pcCU->getPattern()->getAdiOrgBuf( iWidth, iHeight, m_piYuvExt );
3801  Int iMaskStride = ( iWidth<<1 ) + 1;
3802  piMask += iMaskStride+1;
3803  getWedgePredDCs( pcWedgelet, piMask, iMaskStride, iPredDC1, iPredDC2, bAbove, bLeft );
3804
3805  // assign wedge pred DCs to prediction
3806  if( bDelta ) { assignWedgeDCs2Pred( pcWedgelet, piPred, uiStride, Clip( iPredDC1+iDeltaDC1 ), Clip( iPredDC2+iDeltaDC2 ) ); }
3807  else         { assignWedgeDCs2Pred( pcWedgelet, piPred, uiStride, iPredDC1,           iPredDC2           ); }
3808}
3809
3810Void TComPrediction::xPredIntraWedgeDir( TComDataCU* pcCU, UInt uiAbsPartIdx, Pel* piPred, UInt uiStride, Int iWidth, Int iHeight, Bool bAbove, Bool bLeft, Bool bEncoder, Bool bDelta, Int iWedgeDeltaEnd, Int iDeltaDC1, Int iDeltaDC2 )
3811{
3812  assert( iWidth >= DMM_WEDGEMODEL_MIN_SIZE && iWidth <= DMM_WEDGEMODEL_MAX_SIZE );
3813  WedgeList* pacWedgeList = &g_aacWedgeLists[(g_aucConvertToBit[iWidth])];
3814
3815  // get wedge pattern
3816  UInt uiDirWedgeTabIdx = 0;
3817  if( bEncoder )
3818  {
3819    // encoder: load stored wedge pattern from CU
3820    uiDirWedgeTabIdx = pcCU->getWedgePredDirTabIdx( uiAbsPartIdx );
3821  }
3822  else
3823  {
3824    uiDirWedgeTabIdx = getBestContinueWedge( pcCU, uiAbsPartIdx, iWidth, iHeight, iWedgeDeltaEnd );
3825
3826    UInt uiDepth = (pcCU->getDepth(0)) + (pcCU->getPartitionSize(0) == SIZE_2Nx2N ? 0 : 1);
3827    pcCU->setWedgePredDirTabIdxSubParts( uiDirWedgeTabIdx, uiAbsPartIdx, uiDepth );
3828  }
3829  TComWedgelet* pcWedgelet = &(pacWedgeList->at(uiDirWedgeTabIdx));
3830
3831  // get wedge pred DCs
3832  Int iPredDC1 = 0;
3833  Int iPredDC2 = 0;
3834
3835  Int* piMask = pcCU->getPattern()->getAdiOrgBuf( iWidth, iHeight, m_piYuvExt );
3836  Int iMaskStride = ( iWidth<<1 ) + 1;
3837  piMask += iMaskStride+1;
3838  getWedgePredDCs( pcWedgelet, piMask, iMaskStride, iPredDC1, iPredDC2, bAbove, bLeft );
3839
3840  // assign wedge pred DCs to prediction
3841  if( bDelta ) { assignWedgeDCs2Pred( pcWedgelet, piPred, uiStride, Clip( iPredDC1+iDeltaDC1 ), Clip( iPredDC2+iDeltaDC2 ) ); }
3842  else         { assignWedgeDCs2Pred( pcWedgelet, piPred, uiStride,       iPredDC1,                   iPredDC2             ); }
3843}
3844
3845Void TComPrediction::xGetBlockOffset( TComDataCU* pcCU, UInt uiAbsPartIdx, TComDataCU* pcRefCU, UInt uiRefAbsPartIdx, UInt& ruiOffsetX, UInt& ruiOffsetY )
3846{
3847  ruiOffsetX = 0;
3848  ruiOffsetY = 0;
3849
3850  // get offset between current and above/left block
3851  UInt uiThisOriginX = pcCU->getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[uiAbsPartIdx] ];
3852  UInt uiThisOriginY = pcCU->getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[uiAbsPartIdx] ];
3853
3854  UInt uiNumPartInRefCU = pcRefCU->getTotalNumPart();
3855  UInt uiMaxDepthRefCU = 0;
3856  while( uiNumPartInRefCU > 1 )
3857  {
3858    uiNumPartInRefCU >>= 2;
3859    uiMaxDepthRefCU++;
3860  }
3861
3862  UInt uiDepthRefPU = (pcRefCU->getDepth(uiRefAbsPartIdx)) + (pcRefCU->getPartitionSize(uiRefAbsPartIdx) == SIZE_2Nx2N ? 0 : 1);
3863  UInt uiShifts = (uiMaxDepthRefCU - uiDepthRefPU)*2;
3864  UInt uiRefBlockOriginPartIdx = (uiRefAbsPartIdx>>uiShifts)<<uiShifts;
3865
3866  UInt uiRefOriginX = pcRefCU->getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[uiRefBlockOriginPartIdx] ];
3867  UInt uiRefOriginY = pcRefCU->getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[uiRefBlockOriginPartIdx] ];
3868
3869  if( (uiThisOriginX - uiRefOriginX) > 0 ) { ruiOffsetX = (UInt)(uiThisOriginX - uiRefOriginX); }
3870  if( (uiThisOriginY - uiRefOriginY) > 0 ) { ruiOffsetY = (UInt)(uiThisOriginY - uiRefOriginY); }
3871}
3872
3873Bool TComPrediction::xGetWedgeIntraDirPredData( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiBlockSize, Int& riSlopeX, Int& riSlopeY, UInt& ruiStartPosX, UInt& ruiStartPosY )
3874{
3875  riSlopeX     = 0;
3876  riSlopeY     = 0;
3877  ruiStartPosX = 0;
3878  ruiStartPosY = 0;
3879
3880  // 1st step: get wedge start point (max. slope)
3881  Int* piSource = pcCU->getPattern()->getAdiOrgBuf( uiBlockSize, uiBlockSize, m_piYuvExt );
3882  Int iSourceStride = ( uiBlockSize<<1 ) + 1;
3883
3884  UInt uiSlopeMaxAbove = 0;
3885  UInt uiPosSlopeMaxAbove = 0;
3886  for( UInt uiPosHor = 0; uiPosHor < (uiBlockSize-1); uiPosHor++ )
3887  {
3888    if( abs( piSource[uiPosHor+1] - piSource[uiPosHor] ) > uiSlopeMaxAbove )
3889    {
3890      uiSlopeMaxAbove = abs( piSource[uiPosHor+1] - piSource[uiPosHor] );
3891      uiPosSlopeMaxAbove = uiPosHor;
3892    }
3893  }
3894
3895  UInt uiSlopeMaxLeft = 0;
3896  UInt uiPosSlopeMaxLeft = 0;
3897  for( UInt uiPosVer = 0; uiPosVer < (uiBlockSize-1); uiPosVer++ )
3898  {
3899    if( abs( piSource[(uiPosVer+1)*iSourceStride] - piSource[uiPosVer*iSourceStride] ) > uiSlopeMaxLeft )
3900    {
3901      uiSlopeMaxLeft = abs( piSource[(uiPosVer+1)*iSourceStride] - piSource[uiPosVer*iSourceStride] );
3902      uiPosSlopeMaxLeft = uiPosVer;
3903    }
3904  }
3905
3906  if( uiSlopeMaxAbove == 0 && uiSlopeMaxLeft == 0 ) 
3907  { 
3908    return false; 
3909  }
3910
3911  if( uiSlopeMaxAbove > uiSlopeMaxLeft )
3912  {
3913    ruiStartPosX = uiPosSlopeMaxAbove;
3914    ruiStartPosY = 0;
3915  }
3916  else
3917  {
3918    ruiStartPosX = 0;
3919    ruiStartPosY = uiPosSlopeMaxLeft;
3920  }
3921
3922  // 2nd step: derive wedge direction
3923  Int uiPreds[3] = {-1, -1, -1};
3924  Int iMode = -1;
3925  Int iPredNum = pcCU->getIntraDirLumaPredictor( uiAbsPartIdx, uiPreds, &iMode ); 
3926
3927  UInt uiDirMode = 0;
3928  if( iMode >= 0 ) { iPredNum = iMode; }
3929  if( iPredNum == 1 ) { uiDirMode = uiPreds[0]; }
3930  if( iPredNum == 2 ) { uiDirMode = uiPreds[1]; }
3931
3932  if( uiDirMode < 2 ) { return false; } // no planar & DC
3933
3934  Bool modeHor       = (uiDirMode < 18);
3935  Bool modeVer       = !modeHor;
3936  Int intraPredAngle = modeVer ? (Int)uiDirMode - VER_IDX : modeHor ? -((Int)uiDirMode - HOR_IDX) : 0;
3937  Int absAng         = abs(intraPredAngle);
3938  Int signAng        = intraPredAngle < 0 ? -1 : 1;
3939  Int angTable[9]    = {0,2,5,9,13,17,21,26,32};
3940  absAng             = angTable[absAng];
3941  intraPredAngle     = signAng * absAng;
3942
3943  // 3rd step: set slope for direction
3944  if( modeHor )
3945  {
3946    if( intraPredAngle > 0 )
3947    {
3948      riSlopeX = -32;
3949      riSlopeY = intraPredAngle;
3950    }
3951    else
3952    {
3953      riSlopeX = 32;
3954      riSlopeY = -intraPredAngle;
3955    }
3956  }
3957  else if( modeVer )
3958  {
3959    if( intraPredAngle > 0 )
3960    {
3961      riSlopeX = intraPredAngle;
3962      riSlopeY = -32;
3963    }
3964    else
3965    {
3966      riSlopeX = -intraPredAngle;
3967      riSlopeY = 32;
3968    }
3969  }
3970
3971  return true;
3972}
3973
3974Void TComPrediction::xGetWedgeIntraDirStartEnd( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiBlockSize, Int iDeltaX, Int iDeltaY, UInt uiPMSPosX, UInt uiPMSPosY, UChar& ruhXs, UChar& ruhYs, UChar& ruhXe, UChar& ruhYe, Int iDeltaEnd )
3975{
3976  ruhXs = 0;
3977  ruhYs = 0;
3978  ruhXe = 0;
3979  ruhYe = 0;
3980
3981  // scaling of start pos and block size to wedge resolution
3982  UInt uiScaledStartPosX = 0;
3983  UInt uiScaledStartPosY = 0;
3984  UInt uiScaledBlockSize = 0;
3985  WedgeResolution eWedgeRes = g_aeWedgeResolutionList[(UInt)g_aucConvertToBit[uiBlockSize]];
3986  switch( eWedgeRes )
3987  {
3988  case( DOUBLE_PEL ): { uiScaledStartPosX = (uiPMSPosX>>1); uiScaledStartPosY = (uiPMSPosY>>1); uiScaledBlockSize = (uiBlockSize>>1); break; }
3989  case(   FULL_PEL ): { uiScaledStartPosX =  uiPMSPosX;     uiScaledStartPosY =  uiPMSPosY;     uiScaledBlockSize =  uiBlockSize;     break; }
3990  case(   HALF_PEL ): { uiScaledStartPosX = (uiPMSPosX<<1); uiScaledStartPosY = (uiPMSPosY<<1); uiScaledBlockSize = (uiBlockSize<<1); break; }
3991  }
3992  Int iMaxPos = (Int)uiScaledBlockSize - 1;
3993
3994  // case above
3995  if( uiScaledStartPosX > 0 && uiScaledStartPosY == 0 )
3996  {
3997    ruhXs = (UChar)uiScaledStartPosX;
3998    ruhYs = 0;
3999
4000    if( iDeltaY == 0 )
4001    {
4002      if( iDeltaX < 0 )
4003      {
4004        ruhXe = 0;
4005        ruhYe = (UChar)std::min( std::max( iDeltaEnd, 0 ), iMaxPos );
4006        return;
4007      }
4008      else
4009      {
4010        ruhXe = (UChar)iMaxPos;
4011        ruhYe = (UChar)std::min( std::max( -iDeltaEnd, 0 ), iMaxPos );
4012        std::swap( ruhXs, ruhXe );
4013        std::swap( ruhYs, ruhYe );
4014        return;
4015      }
4016    }
4017
4018    // regular case
4019    Int iVirtualEndX = (Int)ruhXs + roftoi( (Double)iMaxPos * ((Double)iDeltaX / (Double)iDeltaY) );
4020
4021    if( iVirtualEndX < 0 )
4022    {
4023      Int iYe = roftoi( (Double)(0 - (Int)ruhXs) * ((Double)iDeltaY / (Double)iDeltaX) ) + iDeltaEnd;
4024      if( iYe < (Int)uiScaledBlockSize )
4025      {
4026        ruhXe = 0;
4027        ruhYe = (UChar)std::max( iYe, 0 );
4028        return;
4029      }
4030      else
4031      {
4032        ruhXe = (UChar)std::min( (iYe - iMaxPos), iMaxPos );
4033        ruhYe = (UChar)iMaxPos;
4034        return;
4035      }
4036    }
4037    else if( iVirtualEndX > iMaxPos )
4038    {
4039      Int iYe = roftoi( (Double)(iMaxPos - (Int)ruhXs) * ((Double)iDeltaY / (Double)iDeltaX) ) - iDeltaEnd;
4040      if( iYe < (Int)uiScaledBlockSize )
4041      {
4042        ruhXe = (UChar)iMaxPos;
4043        ruhYe = (UChar)std::max( iYe, 0 );
4044        std::swap( ruhXs, ruhXe );
4045        std::swap( ruhYs, ruhYe );
4046        return;
4047      }
4048      else
4049      {
4050        ruhXe = (UChar)std::max( (iMaxPos - (iYe - iMaxPos)), 0 );
4051        ruhYe = (UChar)iMaxPos;
4052        return;
4053      }
4054    }
4055    else
4056    {
4057      Int iXe = iVirtualEndX + iDeltaEnd;
4058      if( iXe < 0 )
4059      {
4060        ruhXe = 0;
4061        ruhYe = (UChar)std::max( (iMaxPos + iXe), 0 );
4062        return;
4063      }
4064      else if( iXe > iMaxPos )
4065      {
4066        ruhXe = (UChar)iMaxPos;
4067        ruhYe = (UChar)std::max( (iMaxPos - (iXe - iMaxPos)), 0 );
4068        std::swap( ruhXs, ruhXe );
4069        std::swap( ruhYs, ruhYe );
4070        return;
4071      }
4072      else
4073      {
4074        ruhXe = (UChar)iXe;
4075        ruhYe = (UChar)iMaxPos;
4076        return;
4077      }
4078    }
4079  }
4080
4081  // case left
4082  if( uiScaledStartPosY > 0 && uiScaledStartPosX == 0 )
4083  {
4084    ruhXs = 0;
4085    ruhYs = (UChar)uiScaledStartPosY;
4086
4087    if( iDeltaX == 0 )
4088    {
4089      if( iDeltaY < 0 )
4090      {
4091        ruhXe = (UChar)std::min( std::max( -iDeltaEnd, 0 ), iMaxPos );
4092        ruhYe = 0;
4093        std::swap( ruhXs, ruhXe );
4094        std::swap( ruhYs, ruhYe );
4095        return;
4096      }
4097      else
4098      {
4099        ruhXe = (UChar)std::min( std::max( iDeltaEnd, 0 ), iMaxPos );
4100        ruhYe = (UChar)iMaxPos;
4101        return; 
4102      }
4103    }
4104
4105    // regular case
4106    Int iVirtualEndY = (Int)ruhYs + roftoi( (Double)iMaxPos * ((Double)iDeltaY / (Double)iDeltaX) );
4107
4108    if( iVirtualEndY < 0 )
4109    {
4110      Int iXe = roftoi( (Double)(0 - (Int)ruhYs ) * ((Double)iDeltaX / (Double)iDeltaY) ) - iDeltaEnd;
4111      if( iXe < (Int)uiScaledBlockSize )
4112      {
4113        ruhXe = (UChar)std::max( iXe, 0 );
4114        ruhYe = 0;
4115        std::swap( ruhXs, ruhXe );
4116        std::swap( ruhYs, ruhYe );
4117        return;
4118      }
4119      else
4120      {
4121        ruhXe = (UChar)iMaxPos;
4122        ruhYe = (UChar)std::min( (iXe - iMaxPos), iMaxPos );
4123        std::swap( ruhXs, ruhXe );
4124        std::swap( ruhYs, ruhYe );
4125        return;
4126      }
4127    }
4128    else if( iVirtualEndY > (uiScaledBlockSize-1) )
4129    {
4130      Int iXe = roftoi( (Double)((Int)(uiScaledBlockSize-1) - (Int)ruhYs ) * ((Double)iDeltaX / (Double)iDeltaY) ) + iDeltaEnd;
4131      if( iXe < (Int)uiScaledBlockSize )
4132      {
4133        ruhXe = (UChar)std::max( iXe, 0 );
4134        ruhYe = (UChar)(uiScaledBlockSize-1);
4135        return;
4136      }
4137      else
4138      {
4139        ruhXe = (UChar)iMaxPos;
4140        ruhYe = (UChar)std::max( (iMaxPos - (iXe - iMaxPos)), 0 );
4141        std::swap( ruhXs, ruhXe );
4142        std::swap( ruhYs, ruhYe );
4143        return;
4144      }
4145    }
4146    else
4147    {
4148      Int iYe = iVirtualEndY - iDeltaEnd;
4149      if( iYe < 0 )
4150      {
4151        ruhXe = (UChar)std::max( (iMaxPos + iYe), 0 );
4152        ruhYe = 0;
4153        std::swap( ruhXs, ruhXe );
4154        std::swap( ruhYs, ruhYe );
4155        return;
4156      }
4157      else if( iYe > iMaxPos )
4158      {
4159        ruhXe = (UChar)std::max( (iMaxPos - (iYe - iMaxPos)), 0 );
4160        ruhYe = (UChar)iMaxPos;
4161        return;
4162      }
4163      else
4164      {
4165        ruhXe = (UChar)iMaxPos;
4166        ruhYe = (UChar)iYe;
4167        std::swap( ruhXs, ruhXe );
4168        std::swap( ruhYs, ruhYe );
4169        return;
4170      }
4171    }
4172  }
4173
4174  // case origin
4175  if( uiScaledStartPosX == 0 && uiScaledStartPosY == 0 )
4176  {
4177    if( iDeltaX*iDeltaY < 0 )
4178    {
4179      return;
4180    }
4181
4182    ruhXs = 0;
4183    ruhYs = 0;
4184
4185    if( iDeltaY == 0 )
4186    {
4187      ruhXe = (UChar)iMaxPos;
4188      ruhYe = 0;
4189      std::swap( ruhXs, ruhXe );
4190      std::swap( ruhYs, ruhYe );
4191      return;
4192    }
4193
4194    if( iDeltaX == 0 )
4195    {
4196      ruhXe = 0;
4197      ruhYe = (UChar)iMaxPos;
4198      return;
4199    }
4200
4201    Int iVirtualEndX = (Int)ruhXs + roftoi( (Double)iMaxPos * ((Double)iDeltaX / (Double)iDeltaY) );
4202
4203    if( iVirtualEndX > iMaxPos )
4204    {
4205      Int iYe = roftoi( (Double)((Int)iMaxPos - (Int)ruhXs) * ((Double)iDeltaY / (Double)iDeltaX) ) - iDeltaEnd;
4206      if( iYe < (Int)uiScaledBlockSize )
4207      {
4208        ruhXe = (UChar)(uiScaledBlockSize-1);
4209        ruhYe = (UChar)std::max( iYe, 0 );
4210        std::swap( ruhXs, ruhXe );
4211        std::swap( ruhYs, ruhYe );
4212        return;
4213      }
4214      else
4215      {
4216        ruhXe = (UChar)std::max( (iMaxPos - (iYe - iMaxPos)), 0 );
4217        ruhYe = (UChar)(uiScaledBlockSize-1);
4218        return;
4219      }
4220    }
4221    else
4222    {
4223      Int iXe = iVirtualEndX + iDeltaEnd;
4224      if( iXe < 0 )
4225      {
4226        ruhXe = 0;
4227        ruhYe = (UChar)std::max( (iMaxPos + iXe), 0 );
4228        return;
4229      }
4230      else if( iXe > iMaxPos )
4231      {
4232        ruhXe = (UChar)(uiScaledBlockSize-1);
4233        ruhYe = (UChar)std::max( (iMaxPos - (iXe - iMaxPos)), 0 );
4234        std::swap( ruhXs, ruhXe );
4235        std::swap( ruhYs, ruhYe );
4236        return;
4237      }
4238      else
4239      {
4240        ruhXe = (UChar)iXe;
4241        ruhYe = (UChar)(uiScaledBlockSize-1);
4242        return;
4243      }
4244    }
4245  }
4246}
4247#endif
4248
4249Void
4250TComPrediction::predIntraDepthAng(TComPattern* pcTComPattern, UInt uiDirMode, Pel* piPred, UInt uiStride, Int iWidth, Int iHeight )
4251{
4252  Pel*  pDst    = piPred;
4253  Int*  ptrSrc  = pcTComPattern->getAdiOrgBuf( iWidth, iHeight, m_piYuvExt );
4254  Int   sw      = ( iWidth<<1 ) + 1;
4255  xPredIntraAngDepth( ptrSrc+sw+1, sw, pDst, uiStride, iWidth, iHeight, uiDirMode );
4256}
4257
4258Int
4259TComPrediction::xGetDCDepth( Int* pSrc, Int iDelta, Int iBlkSize )
4260{
4261  Int iDC    = PDM_UNDEFINED_DEPTH;
4262  Int iSum   = 0;
4263  Int iNum   = 0;
4264  for( Int k = 0; k < iBlkSize; k++, pSrc += iDelta )
4265  {
4266    if( *pSrc != PDM_UNDEFINED_DEPTH )
4267    {
4268      iSum += *pSrc;
4269      iNum ++;
4270    }
4271  }
4272  if( iNum )
4273  {
4274    iDC = ( iSum + ( iNum >> 1 ) ) / iNum;
4275  }
4276  return iDC;
4277}
4278
4279Int
4280TComPrediction::xGetDCValDepth( Int iVal1, Int iVal2, Int iVal3, Int iVal4 )
4281{
4282  if     ( iVal1 != PDM_UNDEFINED_DEPTH )   return iVal1;
4283  else if( iVal2 != PDM_UNDEFINED_DEPTH )   return iVal2;
4284  else if( iVal3 != PDM_UNDEFINED_DEPTH )   return iVal3;
4285  return   iVal4;
4286}
4287
4288Void
4289TComPrediction::xPredIntraAngDepth( Int* pSrc, Int srcStride, Pel* pDst, Int dstStride, UInt width, UInt height, UInt dirMode )
4290{
4291  AOF( width == height );
4292  Int blkSize       = width;
4293  Int iDCAbove      = xGetDCDepth( pSrc - srcStride,                               1, blkSize );
4294  Int iDCAboveRight = xGetDCDepth( pSrc - srcStride + blkSize,                     1, blkSize );
4295  Int iDCLeft       = xGetDCDepth( pSrc -         1,                       srcStride, blkSize );
4296  Int iDCBelowLeft  = xGetDCDepth( pSrc -         1 + blkSize * srcStride, srcStride, blkSize );
4297  Int iWgt, iDC1, iDC2;
4298  if( dirMode < 2 ) // 1..2
4299  {
4300    iDC1  = xGetDCValDepth( iDCAbove, iDCAboveRight, iDCLeft,  iDCBelowLeft  );
4301    iDC2  = xGetDCValDepth( iDCLeft,  iDCBelowLeft,  iDCAbove, iDCAboveRight );
4302    iWgt  = 8;
4303  }
4304  else if( dirMode < 11 ) // 3..10
4305  {
4306    iDC1  = xGetDCValDepth( iDCLeft,  iDCBelowLeft,  iDCAbove, iDCAboveRight );
4307    iDC2  = xGetDCValDepth( iDCBelowLeft,  iDCLeft,  iDCAbove, iDCAboveRight );
4308    iWgt  = 6 + dirMode; 
4309  }
4310  else if( dirMode < 27 ) // 11..26
4311  {
4312    iDC1  = xGetDCValDepth( iDCAbove, iDCAboveRight, iDCLeft,  iDCBelowLeft  );
4313    iDC2  = xGetDCValDepth( iDCLeft,  iDCBelowLeft,  iDCAbove, iDCAboveRight );
4314    iWgt  = dirMode - 10;
4315  }
4316  else if( dirMode < 35 ) // 27..34
4317  {
4318    iDC1  = xGetDCValDepth( iDCAbove, iDCAboveRight, iDCLeft,  iDCBelowLeft  );
4319    iDC2  = xGetDCValDepth( iDCAboveRight, iDCAbove, iDCLeft,  iDCBelowLeft  );
4320    iWgt  = 42 - dirMode;
4321  }
4322  else // (wedgelet -> use simple DC prediction
4323  {
4324    iDC1  = xGetDCValDepth( iDCAbove, iDCAboveRight, iDCLeft,  iDCBelowLeft  );
4325    iDC2  = xGetDCValDepth( iDCLeft,  iDCBelowLeft,  iDCAbove, iDCAboveRight );
4326    iWgt  = 8;
4327  }
4328  Int iWgt2   = 16 - iWgt;
4329  Int iDCVal  = ( iWgt * iDC1 + iWgt2 * iDC2 + 8 ) >> 4;
4330
4331  // set depth
4332  for( Int iY = 0; iY < blkSize; iY++, pDst += dstStride )
4333  {
4334    for( Int iX = 0; iX < blkSize; iX++ )
4335    {
4336      pDst[ iX ] = iDCVal;
4337    }
4338  }
4339}
4340
4341//! \}
Note: See TracBrowser for help on using the repository browser.