source: 3DVCSoftware/branches/HTM-6.2-dev2-MERL/source/Lib/TLibCommon/TComPrediction.cpp @ 420

Last change on this file since 420 was 420, checked in by mitsubishi-htm, 12 years ago

-macro updates.

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