source: 3DVCSoftware/branches/HTM-5.1-dev0-MERL-Mediatek-Fix/source/Lib/TLibCommon/TComPrediction.cpp @ 483

Last change on this file since 483 was 280, checked in by tech, 12 years ago

Integration of branch dev 2.

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