Index: trunk/source/Lib/TLibEncoder/WeightPredAnalysis.cpp
===================================================================
--- trunk/source/Lib/TLibEncoder/WeightPredAnalysis.cpp	(revision 1179)
+++ trunk/source/Lib/TLibEncoder/WeightPredAnalysis.cpp	(revision 1313)
@@ -2,7 +2,7 @@
  * License, included below. This software may be subject to other third party
  * and contributor rights, including patent rights, and no such rights are
- * granted under this license.  
+ * granted under this license.
  *
-* Copyright (c) 2010-2015, ITU/ISO/IEC
+ * Copyright (c) 2010-2015, ITU/ISO/IEC
  * All rights reserved.
  *
@@ -36,5 +36,5 @@
 */
 
-#include "../TLibCommon/TypeDef.h"
+#include "../TLibCommon/CommonDef.h"
 #include "../TLibCommon/TComSlice.h"
 #include "../TLibCommon/TComPic.h"
@@ -47,13 +47,11 @@
 WeightPredAnalysis::WeightPredAnalysis()
 {
-  m_weighted_pred_flag = false;
-  m_weighted_bipred_flag = false;
-  for ( Int iList =0 ; iList<2 ; iList++ )
-  {
-    for ( Int iRefIdx=0 ; iRefIdx<MAX_NUM_REF ; iRefIdx++ ) 
-    {
-      for ( Int comp=0 ; comp<3 ;comp++ )
-      {
-        wpScalingParam  *pwp   = &(m_wp[iList][iRefIdx][comp]);
+  for ( UInt lst =0 ; lst<NUM_REF_PIC_LIST_01 ; lst++ )
+  {
+    for ( Int iRefIdx=0 ; iRefIdx<MAX_NUM_REF ; iRefIdx++ )
+    {
+      for ( Int comp=0 ; comp<MAX_NUM_COMPONENT ;comp++ )
+      {
+        WPScalingParam  *pwp   = &(m_wp[lst][iRefIdx][comp]);
         pwp->bPresentFlag      = false;
         pwp->uiLog2WeightDenom = 0;
@@ -65,82 +63,75 @@
 }
 
-/** calculate AC and DC values for current original image
- * \param TComSlice *slice
- * \returns Void
- */
-Bool  WeightPredAnalysis::xCalcACDCParamSlice(TComSlice *slice)
+
+//! calculate AC and DC values for current original image
+Void WeightPredAnalysis::xCalcACDCParamSlice(TComSlice *const slice)
 {
   //===== calculate AC/DC value =====
   TComPicYuv*   pPic = slice->getPic()->getPicYuvOrg();
-  Int   iSample  = 0;
-
-  // calculate DC/AC value for Y
-  Pel*  pOrg    = pPic->getLumaAddr();
-  Int64  iOrgDCY = xCalcDCValueSlice(slice, pOrg, &iSample);
-  Int64  iOrgNormDCY = ((iOrgDCY+(iSample>>1)) / iSample);
-  pOrg = pPic->getLumaAddr();
-  Int64  iOrgACY  = xCalcACValueSlice(slice, pOrg, iOrgNormDCY);
-
-  // calculate DC/AC value for Cb
-  pOrg = pPic->getCbAddr();
-  Int64  iOrgDCCb = xCalcDCValueUVSlice(slice, pOrg, &iSample);
-  Int64  iOrgNormDCCb = ((iOrgDCCb+(iSample>>1)) / (iSample));
-  pOrg = pPic->getCbAddr();
-  Int64  iOrgACCb  = xCalcACValueUVSlice(slice, pOrg, iOrgNormDCCb);
-
-  // calculate DC/AC value for Cr
-  pOrg = pPic->getCrAddr();
-  Int64  iOrgDCCr = xCalcDCValueUVSlice(slice, pOrg, &iSample);
-  Int64  iOrgNormDCCr = ((iOrgDCCr+(iSample>>1)) / (iSample));
-  pOrg = pPic->getCrAddr();
-  Int64  iOrgACCr  = xCalcACValueUVSlice(slice, pOrg, iOrgNormDCCr);
-
-  wpACDCParam weightACDCParam[3];
-  weightACDCParam[0].iAC = iOrgACY;
-  weightACDCParam[0].iDC = iOrgNormDCY;
-  weightACDCParam[1].iAC = iOrgACCb;
-  weightACDCParam[1].iDC = iOrgNormDCCb;
-  weightACDCParam[2].iAC = iOrgACCr;
-  weightACDCParam[2].iDC = iOrgNormDCCr;
+
+  WPACDCParam weightACDCParam[MAX_NUM_COMPONENT];
+
+  for(Int componentIndex = 0; componentIndex < pPic->getNumberValidComponents(); componentIndex++)
+  {
+    const ComponentID compID = ComponentID(componentIndex);
+
+    // calculate DC/AC value for channel
+
+    const Int iStride = pPic->getStride(compID);
+    const Int iWidth  = pPic->getWidth(compID);
+    const Int iHeight = pPic->getHeight(compID);
+
+    const Int iSample = iWidth*iHeight;
+
+    Int64 iOrgDC = 0;
+    {
+      const Pel *pPel = pPic->getAddr(compID);
+
+      for(Int y = 0; y < iHeight; y++, pPel+=iStride )
+      {
+        for(Int x = 0; x < iWidth; x++ )
+        {
+          iOrgDC += (Int)( pPel[x] );
+        }
+      }
+    }
+
+    const Int64 iOrgNormDC = ((iOrgDC+(iSample>>1)) / iSample);
+
+    Int64 iOrgAC = 0;
+    {
+      const Pel *pPel = pPic->getAddr(compID);
+
+      for(Int y = 0; y < iHeight; y++, pPel += iStride )
+      {
+        for(Int x = 0; x < iWidth; x++ )
+        {
+          iOrgAC += abs( (Int)pPel[x] - (Int)iOrgNormDC );
+        }
+      }
+    }
+
+    const Int fixedBitShift = (slice->getSPS()->getSpsRangeExtension().getHighPrecisionOffsetsEnabledFlag())?RExt__PREDICTION_WEIGHTING_ANALYSIS_DC_PRECISION:0;
+    weightACDCParam[compID].iDC = (((iOrgDC<<fixedBitShift)+(iSample>>1)) / iSample);
+    weightACDCParam[compID].iAC = iOrgAC;
+  }
 
   slice->setWpAcDcParam(weightACDCParam);
-  return (true);
-}
-
-/** store weighted_pred_flag and weighted_bipred_idc values
- * \param weighted_pred_flag
- * \param weighted_bipred_idc
- * \returns Void
- */
-Void  WeightPredAnalysis::xStoreWPparam(Bool weighted_pred_flag, Bool weighted_bipred_flag)
-{
-  m_weighted_pred_flag = weighted_pred_flag;
-  m_weighted_bipred_flag = weighted_bipred_flag;
-}
-
-/** restore weighted_pred_flag and weighted_bipred_idc values
- * \param TComSlice *slice
- * \returns Void
- */
-Void  WeightPredAnalysis::xRestoreWPparam(TComSlice *slice)
-{
-  slice->getPPS()->setUseWP(m_weighted_pred_flag);
-  slice->getPPS()->setWPBiPred(m_weighted_bipred_flag);
-}
-
-/** check weighted pred or non-weighted pred
- * \param TComSlice *slice
- * \returns Void
- */
-Void  WeightPredAnalysis::xCheckWPEnable(TComSlice *slice)
-{
+}
+
+
+//! check weighted pred or non-weighted pred
+Void  WeightPredAnalysis::xCheckWPEnable(TComSlice *const slice)
+{
+  const TComPicYuv *pPic = slice->getPic()->getPicYuvOrg();
+
   Int iPresentCnt = 0;
-  for ( Int iList=0 ; iList<2 ; iList++ )
-  {
-    for ( Int iRefIdx=0 ; iRefIdx<MAX_NUM_REF ; iRefIdx++ ) 
-    {
-      for ( Int iComp=0 ; iComp<3 ;iComp++ ) 
-      {
-        wpScalingParam  *pwp = &(m_wp[iList][iRefIdx][iComp]);
+  for ( UInt lst=0 ; lst<NUM_REF_PIC_LIST_01 ; lst++ )
+  {
+    for ( Int iRefIdx=0 ; iRefIdx<MAX_NUM_REF ; iRefIdx++ )
+    {
+      for(Int componentIndex = 0; componentIndex < pPic->getNumberValidComponents(); componentIndex++)
+      {
+        WPScalingParam  *pwp = &(m_wp[lst][iRefIdx][componentIndex]);
         iPresentCnt += (Int)pwp->bPresentFlag;
       }
@@ -150,13 +141,15 @@
   if(iPresentCnt==0)
   {
-    slice->getPPS()->setUseWP(false);
-    slice->getPPS()->setWPBiPred(false);
-    for ( Int iList=0 ; iList<2 ; iList++ )
-    {
-      for ( Int iRefIdx=0 ; iRefIdx<MAX_NUM_REF ; iRefIdx++ ) 
-      {
-        for ( Int iComp=0 ; iComp<3 ;iComp++ ) 
-        {
-          wpScalingParam  *pwp = &(m_wp[iList][iRefIdx][iComp]);
+    slice->setTestWeightPred(false);
+    slice->setTestWeightBiPred(false);
+
+    for ( UInt lst=0 ; lst<NUM_REF_PIC_LIST_01 ; lst++ )
+    {
+      for ( Int iRefIdx=0 ; iRefIdx<MAX_NUM_REF ; iRefIdx++ )
+      {
+        for(Int componentIndex = 0; componentIndex < pPic->getNumberValidComponents(); componentIndex++)
+        {
+          WPScalingParam  *pwp = &(m_wp[lst][iRefIdx][componentIndex]);
+
           pwp->bPresentFlag      = false;
           pwp->uiLog2WeightDenom = 0;
@@ -168,23 +161,26 @@
     slice->setWpScaling( m_wp );
   }
-}
-
-/** estimate wp tables for explicit wp
- * \param TComSlice *slice
- * \returns Bool
- */
-Bool  WeightPredAnalysis::xEstimateWPParamSlice(TComSlice *slice)
-{
-  Int iDenom  = 6;
+  else
+  {
+    slice->setTestWeightPred(slice->getPPS()->getUseWP());
+    slice->setTestWeightBiPred(slice->getPPS()->getWPBiPred());
+  }
+}
+
+
+//! estimate wp tables for explicit wp
+Void WeightPredAnalysis::xEstimateWPParamSlice(TComSlice *const slice)
+{
+  Int  iDenom         = 6;
   Bool validRangeFlag = false;
 
   if(slice->getNumRefIdx(REF_PIC_LIST_0)>3)
   {
-    iDenom  = 7;
+    iDenom = 7;
   }
 
   do
   {
-    validRangeFlag = xUpdatingWPParameters(slice, m_wp, iDenom);
+    validRangeFlag = xUpdatingWPParameters(slice, iDenom);
     if (!validRangeFlag)
     {
@@ -193,286 +189,163 @@
   } while (validRangeFlag == false);
 
-  // selecting whether WP is used, or not
-  xSelectWP(slice, m_wp, iDenom);
-  
+  // selecting whether WP is used, or not (fast search)
+  // NOTE: This is not operating on a slice, but the entire picture.
+  xSelectWP(slice, iDenom);
+
   slice->setWpScaling( m_wp );
-
-  return (true);
-}
-
-/** update wp tables for explicit wp w.r.t ramge limitation
- * \param TComSlice *slice
- * \returns Bool
- */
-Bool WeightPredAnalysis::xUpdatingWPParameters(TComSlice *slice, wpScalingParam weightPredTable[2][MAX_NUM_REF][3], Int log2Denom)
-{
-  Int numPredDir = slice->isInterP() ? 1 : 2;
+}
+
+
+//! update wp tables for explicit wp w.r.t range limitation
+Bool WeightPredAnalysis::xUpdatingWPParameters(TComSlice *const slice, const Int log2Denom)
+{
+  const Int  numComp                    = slice->getPic()->getPicYuvOrg()->getNumberValidComponents();
+  const Bool bUseHighPrecisionWeighting = slice->getSPS()->getSpsRangeExtension().getHighPrecisionOffsetsEnabledFlag();
+  const Int numPredDir                  = slice->isInterP() ? 1 : 2;
+
+  assert (numPredDir <= Int(NUM_REF_PIC_LIST_01));
+
   for ( Int refList = 0; refList < numPredDir; refList++ )
   {
-    RefPicList  eRefPicList = ( refList ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
+    const RefPicList eRefPicList = ( refList ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
+
     for ( Int refIdxTemp = 0; refIdxTemp < slice->getNumRefIdx(eRefPicList); refIdxTemp++ )
     {
-      wpACDCParam *currWeightACDCParam, *refWeightACDCParam;
+      WPACDCParam *currWeightACDCParam, *refWeightACDCParam;
       slice->getWpAcDcParam(currWeightACDCParam);
       slice->getRefPic(eRefPicList, refIdxTemp)->getSlice(0)->getWpAcDcParam(refWeightACDCParam);
 
-      for ( Int comp = 0; comp < 3; comp++ )
-      {
-        Int bitDepth = comp ? g_bitDepthC : g_bitDepthY;
-        Int realLog2Denom = log2Denom + bitDepth-8;
-        Int realOffset = ((Int)1<<(realLog2Denom-1));
+      for ( Int comp = 0; comp < numComp; comp++ )
+      {
+        const ComponentID compID        = ComponentID(comp);
+        const Int         bitDepth      = slice->getSPS()->getBitDepth(toChannelType(compID));
+        const Int         range         = bUseHighPrecisionWeighting ? (1<<bitDepth)/2 : 128;
+        const Int         realLog2Denom = log2Denom + (bUseHighPrecisionWeighting ? RExt__PREDICTION_WEIGHTING_ANALYSIS_DC_PRECISION : (bitDepth - 8));
+        const Int         realOffset    = ((Int)1<<(realLog2Denom-1));
 
         // current frame
-        Int64 currDC = currWeightACDCParam[comp].iDC;
-        Int64 currAC = currWeightACDCParam[comp].iAC;
+        const Int64 currDC = currWeightACDCParam[comp].iDC;
+        const Int64 currAC = currWeightACDCParam[comp].iAC;
         // reference frame
-        Int64 refDC = refWeightACDCParam[comp].iDC;
-        Int64 refAC = refWeightACDCParam[comp].iAC;
+        const Int64 refDC  = refWeightACDCParam[comp].iDC;
+        const Int64 refAC  = refWeightACDCParam[comp].iAC;
 
         // calculating iWeight and iOffset params
-        Double dWeight = (refAC==0) ? (Double)1.0 : Clip3( -16.0, 15.0, ((Double)currAC / (Double)refAC) );
-        Int weight = (Int)( 0.5 + dWeight * (Double)(1<<log2Denom) );
-        Int offset = (Int)( ((currDC<<log2Denom) - ((Int64)weight * refDC) + (Int64)realOffset) >> realLog2Denom );
-
-        // Chroma offset range limitation
-        if(comp)
-        {
-          Int pred = ( 128 - ( ( 128*weight)>>(log2Denom) ) );
-          Int deltaOffset = Clip3( -512, 511, (offset - pred) );    // signed 10bit
-          offset = Clip3( -128, 127, (deltaOffset + pred) );        // signed 8bit
-        }
-        // Luma offset range limitation
-        else
-        {
-          offset = Clip3( -128, 127, offset);
+        const Double dWeight = (refAC==0) ? (Double)1.0 : Clip3( -16.0, 15.0, ((Double)currAC / (Double)refAC) );
+        const Int weight     = (Int)( 0.5 + dWeight * (Double)(1<<log2Denom) );
+        const Int offset     = (Int)( ((currDC<<log2Denom) - ((Int64)weight * refDC) + (Int64)realOffset) >> realLog2Denom );
+
+        Int clippedOffset;
+        if(isChroma(compID)) // Chroma offset range limination
+        {
+          const Int pred        = ( range - ( ( range*weight)>>(log2Denom) ) );
+          const Int deltaOffset = Clip3( -4*range, 4*range-1, (offset - pred) ); // signed 10bit
+
+          clippedOffset = Clip3( -range, range-1, (deltaOffset + pred) );  // signed 8bit
+        }
+        else // Luma offset range limitation
+        {
+          clippedOffset = Clip3( -range, range-1, offset);
         }
 
         // Weighting factor limitation
-        Int defaultWeight = (1<<log2Denom);
-        Int deltaWeight = (defaultWeight - weight);
-        if(deltaWeight > 127 || deltaWeight < -128)
-          return (false);
-
-        m_wp[refList][refIdxTemp][comp].bPresentFlag = true;
-        m_wp[refList][refIdxTemp][comp].iWeight = (Int)weight;
-        m_wp[refList][refIdxTemp][comp].iOffset = (Int)offset;
-        m_wp[refList][refIdxTemp][comp].uiLog2WeightDenom = (Int)log2Denom;
-      }
-    }
-  }
-  return (true);
-}
-
-/** select whether weighted pred enables or not. 
- * \param TComSlice *slice
- * \param wpScalingParam
- * \param iDenom
- * \returns Bool
- */
-Bool WeightPredAnalysis::xSelectWP(TComSlice *slice, wpScalingParam weightPredTable[2][MAX_NUM_REF][3], Int iDenom)
-{
-  TComPicYuv*   pPic = slice->getPic()->getPicYuvOrg();
-  Int iWidth  = pPic->getWidth();
-  Int iHeight = pPic->getHeight();
-  Int iDefaultWeight = ((Int)1<<iDenom);
-  Int iNumPredDir = slice->isInterP() ? 1 : 2;
+        const Int defaultWeight = (1<<log2Denom);
+        const Int deltaWeight   = (defaultWeight - weight);
+
+        if(deltaWeight >= range || deltaWeight < -range)
+        {
+          return false;
+        }
+
+        m_wp[refList][refIdxTemp][comp].bPresentFlag      = true;
+        m_wp[refList][refIdxTemp][comp].iWeight           = weight;
+        m_wp[refList][refIdxTemp][comp].iOffset           = clippedOffset;
+        m_wp[refList][refIdxTemp][comp].uiLog2WeightDenom = log2Denom;
+      }
+    }
+  }
+  return true;
+}
+
+
+//! select whether weighted pred enables or not.
+Bool WeightPredAnalysis::xSelectWP(TComSlice *const slice, const Int log2Denom)
+{
+        TComPicYuv *const pPic                                = slice->getPic()->getPicYuvOrg();
+  const Int               iDefaultWeight                      = ((Int)1<<log2Denom);
+  const Int               iNumPredDir                         = slice->isInterP() ? 1 : 2;
+  const Bool              useHighPrecisionPredictionWeighting = slice->getSPS()->getSpsRangeExtension().getHighPrecisionOffsetsEnabledFlag();
+
+  assert (iNumPredDir <= Int(NUM_REF_PIC_LIST_01));
 
   for ( Int iRefList = 0; iRefList < iNumPredDir; iRefList++ )
   {
-    Int64 iSADWP = 0, iSADnoWP = 0;
-    RefPicList  eRefPicList = ( iRefList ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
+    const RefPicList eRefPicList = ( iRefList ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
+
     for ( Int iRefIdxTemp = 0; iRefIdxTemp < slice->getNumRefIdx(eRefPicList); iRefIdxTemp++ )
     {
-      Pel*  pOrg    = pPic->getLumaAddr();
-      Pel*  pRef    = slice->getRefPic(eRefPicList, iRefIdxTemp)->getPicYuvRec()->getLumaAddr();
-      Int   iOrgStride = pPic->getStride();
-      Int   iRefStride = slice->getRefPic(eRefPicList, iRefIdxTemp)->getPicYuvRec()->getStride();
-
-      // calculate SAD costs with/without wp for luma
-      iSADWP   = this->xCalcSADvalueWP(g_bitDepthY, pOrg, pRef, iWidth, iHeight, iOrgStride, iRefStride, iDenom, weightPredTable[iRefList][iRefIdxTemp][0].iWeight, weightPredTable[iRefList][iRefIdxTemp][0].iOffset);
-      iSADnoWP = this->xCalcSADvalueWP(g_bitDepthY, pOrg, pRef, iWidth, iHeight, iOrgStride, iRefStride, iDenom, iDefaultWeight, 0);
-
-      pOrg = pPic->getCbAddr();
-      pRef = slice->getRefPic(eRefPicList, iRefIdxTemp)->getPicYuvRec()->getCbAddr();
-      iOrgStride = pPic->getCStride();
-      iRefStride = slice->getRefPic(eRefPicList, iRefIdxTemp)->getPicYuvRec()->getCStride();
-
-      // calculate SAD costs with/without wp for chroma cb
-      iSADWP   += this->xCalcSADvalueWP(g_bitDepthC, pOrg, pRef, iWidth>>1, iHeight>>1, iOrgStride, iRefStride, iDenom, weightPredTable[iRefList][iRefIdxTemp][1].iWeight, weightPredTable[iRefList][iRefIdxTemp][1].iOffset);
-      iSADnoWP += this->xCalcSADvalueWP(g_bitDepthC, pOrg, pRef, iWidth>>1, iHeight>>1, iOrgStride, iRefStride, iDenom, iDefaultWeight, 0);
-
-      pOrg = pPic->getCrAddr();
-      pRef = slice->getRefPic(eRefPicList, iRefIdxTemp)->getPicYuvRec()->getCrAddr();
-
-      // calculate SAD costs with/without wp for chroma cr
-      iSADWP   += this->xCalcSADvalueWP(g_bitDepthC, pOrg, pRef, iWidth>>1, iHeight>>1, iOrgStride, iRefStride, iDenom, weightPredTable[iRefList][iRefIdxTemp][2].iWeight, weightPredTable[iRefList][iRefIdxTemp][2].iOffset);
-      iSADnoWP += this->xCalcSADvalueWP(g_bitDepthC, pOrg, pRef, iWidth>>1, iHeight>>1, iOrgStride, iRefStride, iDenom, iDefaultWeight, 0);
-
-      Double dRatio = ((Double)iSADWP / (Double)iSADnoWP);
+      Int64 iSADWP = 0, iSADnoWP = 0;
+
+      for(Int comp=0; comp<pPic->getNumberValidComponents(); comp++)
+      {
+        const ComponentID  compID     = ComponentID(comp);
+              Pel         *pOrg       = pPic->getAddr(compID);
+              Pel         *pRef       = slice->getRefPic(eRefPicList, iRefIdxTemp)->getPicYuvRec()->getAddr(compID);
+        const Int          iOrgStride = pPic->getStride(compID);
+        const Int          iRefStride = slice->getRefPic(eRefPicList, iRefIdxTemp)->getPicYuvRec()->getStride(compID);
+        const Int          iWidth     = pPic->getWidth(compID);
+        const Int          iHeight    = pPic->getHeight(compID);
+        const Int          bitDepth   = slice->getSPS()->getBitDepth(toChannelType(compID));
+
+        // calculate SAD costs with/without wp for luma
+        iSADWP   += xCalcSADvalueWP(bitDepth, pOrg, pRef, iWidth, iHeight, iOrgStride, iRefStride, log2Denom, m_wp[iRefList][iRefIdxTemp][compID].iWeight, m_wp[iRefList][iRefIdxTemp][compID].iOffset, useHighPrecisionPredictionWeighting);
+        iSADnoWP += xCalcSADvalueWP(bitDepth, pOrg, pRef, iWidth, iHeight, iOrgStride, iRefStride, log2Denom, iDefaultWeight, 0, useHighPrecisionPredictionWeighting);
+      }
+
+      const Double dRatio = ((Double)iSADWP / (Double)iSADnoWP);
       if(dRatio >= (Double)DTHRESH)
       {
-        for ( Int iComp = 0; iComp < 3; iComp++ )
-        {
-          weightPredTable[iRefList][iRefIdxTemp][iComp].bPresentFlag = false;
-          weightPredTable[iRefList][iRefIdxTemp][iComp].iOffset = (Int)0;
-          weightPredTable[iRefList][iRefIdxTemp][iComp].iWeight = (Int)iDefaultWeight;
-          weightPredTable[iRefList][iRefIdxTemp][iComp].uiLog2WeightDenom = (Int)iDenom;
-        }
-      }
-    }
-  }
-  return (true);
-}
-
-/** calculate DC value of original image for luma. 
- * \param TComSlice *slice
- * \param Pel *pPel
- * \param Int *iSample
- * \returns Int64
- */
-Int64 WeightPredAnalysis::xCalcDCValueSlice(TComSlice *slice, Pel *pPel, Int *iSample)
-{
-  TComPicYuv* pPic = slice->getPic()->getPicYuvOrg();
-  Int iStride = pPic->getStride();
-
-  *iSample = 0;
-  Int iWidth  = pPic->getWidth();
-  Int iHeight = pPic->getHeight();
-  *iSample = iWidth*iHeight;
-  Int64 iDC = xCalcDCValue(pPel, iWidth, iHeight, iStride);
-
-  return (iDC);
-}
-
-/** calculate AC value of original image for luma. 
- * \param TComSlice *slice
- * \param Pel *pPel
- * \param Int iDC
- * \returns Int64
- */
-Int64 WeightPredAnalysis::xCalcACValueSlice(TComSlice *slice, Pel *pPel, Int64 iDC)
-{
-  TComPicYuv* pPic = slice->getPic()->getPicYuvOrg();
-  Int iStride = pPic->getStride();
-
-  Int iWidth  = pPic->getWidth();
-  Int iHeight = pPic->getHeight();
-  Int64 iAC = xCalcACValue(pPel, iWidth, iHeight, iStride, iDC);
-
-  return (iAC);
-}
-
-/** calculate DC value of original image for chroma. 
- * \param TComSlice *slice
- * \param Pel *pPel
- * \param Int *iSample
- * \returns Int64
- */
-Int64 WeightPredAnalysis::xCalcDCValueUVSlice(TComSlice *slice, Pel *pPel, Int *iSample)
-{
-  TComPicYuv* pPic = slice->getPic()->getPicYuvOrg();
-  Int iCStride = pPic->getCStride();
-
-  *iSample = 0;
-  Int iWidth  = pPic->getWidth()>>1;
-  Int iHeight = pPic->getHeight()>>1;
-  *iSample = iWidth*iHeight;
-  Int64 iDC = xCalcDCValue(pPel, iWidth, iHeight, iCStride);
-
-  return (iDC);
-}
-
-/** calculate AC value of original image for chroma. 
- * \param TComSlice *slice
- * \param Pel *pPel
- * \param Int iDC
- * \returns Int64
- */
-Int64 WeightPredAnalysis::xCalcACValueUVSlice(TComSlice *slice, Pel *pPel, Int64 iDC)
-{
-  TComPicYuv* pPic = slice->getPic()->getPicYuvOrg();
-  Int iCStride = pPic->getCStride();
-
-  Int iWidth  = pPic->getWidth()>>1;
-  Int iHeight = pPic->getHeight()>>1;
-  Int64 iAC = xCalcACValue(pPel, iWidth, iHeight, iCStride, iDC);
-
-  return (iAC);
-}
-
-/** calculate DC value. 
- * \param Pel *pPel
- * \param Int iWidth
- * \param Int iHeight
- * \param Int iStride
- * \returns Int64
- */
-Int64 WeightPredAnalysis::xCalcDCValue(Pel *pPel, Int iWidth, Int iHeight, Int iStride)
-{
-  Int x, y;
-  Int64 iDC = 0;
-  for( y = 0; y < iHeight; y++ )
-  {
-    for( x = 0; x < iWidth; x++ )
-    {
-      iDC += (Int)( pPel[x] );
-    }
-    pPel += iStride;
-  }
-  return (iDC);
-}
-
-/** calculate AC value. 
- * \param Pel *pPel
- * \param Int iWidth
- * \param Int iHeight
- * \param Int iStride
- * \param Int iDC
- * \returns Int64
- */
-Int64 WeightPredAnalysis::xCalcACValue(Pel *pPel, Int iWidth, Int iHeight, Int iStride, Int64 iDC)
-{
-  Int x, y;
-  Int64 iAC = 0;
-  for( y = 0; y < iHeight; y++ )
-  {
-    for( x = 0; x < iWidth; x++ )
-    {
-      iAC += abs( (Int)pPel[x] - (Int)iDC );
-    }
-    pPel += iStride;
-  }
-  return (iAC);
-}
-
-/** calculate SAD values for both WP version and non-WP version. 
- * \param Pel *pOrgPel
- * \param Pel *pRefPel
- * \param Int iWidth
- * \param Int iHeight
- * \param Int iOrgStride
- * \param Int iRefStride
- * \param Int iDenom
- * \param Int iWeight
- * \param Int iOffset
- * \returns Int64
- */
-Int64 WeightPredAnalysis::xCalcSADvalueWP(Int bitDepth, Pel *pOrgPel, Pel *pRefPel, Int iWidth, Int iHeight, Int iOrgStride, Int iRefStride, Int iDenom, Int iWeight, Int iOffset)
-{
-  Int x, y;
+        for(Int comp=0; comp<pPic->getNumberValidComponents(); comp++)
+        {
+          m_wp[iRefList][iRefIdxTemp][comp].bPresentFlag      = false;
+          m_wp[iRefList][iRefIdxTemp][comp].iOffset           = 0;
+          m_wp[iRefList][iRefIdxTemp][comp].iWeight           = iDefaultWeight;
+          m_wp[iRefList][iRefIdxTemp][comp].uiLog2WeightDenom = log2Denom;
+        }
+      }
+    }
+  }
+
+  return true;
+}
+
+
+//! calculate SAD values for both WP version and non-WP version.
+Int64 WeightPredAnalysis::xCalcSADvalueWP(const Int   bitDepth,
+                                          const Pel  *pOrgPel,
+                                          const Pel  *pRefPel,
+                                          const Int   iWidth,
+                                          const Int   iHeight,
+                                          const Int   iOrgStride,
+                                          const Int   iRefStride,
+                                          const Int   iLog2Denom,
+                                          const Int   iWeight,
+                                          const Int   iOffset,
+                                          const Bool  useHighPrecisionPredictionWeighting)
+{
+  const Int64 iSize          = iWidth*iHeight;
+  const Int64 iRealLog2Denom = useHighPrecisionPredictionWeighting ? iLog2Denom : (iLog2Denom + (bitDepth - 8));
+
   Int64 iSAD = 0;
-  Int64 iSize   = iWidth*iHeight;
-  Int64 iRealDenom = iDenom + bitDepth-8;
-  for( y = 0; y < iHeight; y++ )
-  {
-    for( x = 0; x < iWidth; x++ )
-    {
-      iSAD += ABS(( ((Int64)pOrgPel[x]<<(Int64)iDenom) - ( (Int64)pRefPel[x] * (Int64)iWeight + ((Int64)iOffset<<iRealDenom) ) ) );
+  for( Int y = 0; y < iHeight; y++ )
+  {
+    for( Int x = 0; x < iWidth; x++ )
+    {
+      iSAD += ABS(( ((Int64)pOrgPel[x]<<(Int64)iLog2Denom) - ( (Int64)pRefPel[x] * (Int64)iWeight + ((Int64)iOffset<<iRealLog2Denom) ) ) );
     }
     pOrgPel += iOrgStride;
     pRefPel += iRefStride;
   }
+
   return (iSAD/iSize);
 }
-
-
