Index: branches/HTM-DEV-0.3-dev2a/source/App/TAppEncoder/TAppEncCfg.cpp
===================================================================
--- branches/HTM-DEV-0.3-dev2a/source/App/TAppEncoder/TAppEncCfg.cpp	(revision 465)
+++ branches/HTM-DEV-0.3-dev2a/source/App/TAppEncoder/TAppEncCfg.cpp	(revision 468)
@@ -508,5 +508,7 @@
   ("AdvMultiviewResPred",      m_uiUseAdvResPred,           (UInt)1, "Usage of Advanced Residual Prediction" )
 #endif
-
+#if H_3D_IC
+  ("IlluCompEnable",           m_abUseIC, std::vector<Bool>(2, true), "Enable illumination compensation")
+#endif
   // Coding tools
   ("AMP",                      m_enableAMP,                 true,  "Enable asymmetric motion partitions")
@@ -2289,4 +2291,7 @@
   printf(" ARP:%d  ", m_uiUseAdvResPred  );
 #endif
+#if H_3D_IC
+  printf( "IlluCompEnable: %d %d ", m_abUseIC[0] ? 1 : 0, m_abUseIC[1] ? 1 : 0 );
+#endif
   printf("\n\n");  
 
Index: branches/HTM-DEV-0.3-dev2a/source/App/TAppEncoder/TAppEncCfg.h
===================================================================
--- branches/HTM-DEV-0.3-dev2a/source/App/TAppEncoder/TAppEncCfg.h	(revision 465)
+++ branches/HTM-DEV-0.3-dev2a/source/App/TAppEncoder/TAppEncCfg.h	(revision 468)
@@ -243,5 +243,7 @@
   UInt      m_uiARPStepNum;
 #endif
-
+#if H_3D_IC
+  vector<Bool> m_abUseIC;                                    ///< flag for using illumination compensation for inter-view prediction
+#endif
   Bool      m_useFastDecisionForMerge;                        ///< flag for using Fast Decision Merge RD-Cost 
   Bool      m_bUseCbfFastMode;                              ///< flag for using Cbf Fast PU Mode Decision
Index: branches/HTM-DEV-0.3-dev2a/source/App/TAppEncoder/TAppEncTop.cpp
===================================================================
--- branches/HTM-DEV-0.3-dev2a/source/App/TAppEncoder/TAppEncTop.cpp	(revision 465)
+++ branches/HTM-DEV-0.3-dev2a/source/App/TAppEncoder/TAppEncTop.cpp	(revision 468)
@@ -178,4 +178,7 @@
     m_cTEncTop.setUseAdvRP                     ( ( isDepth || 0==layer ) ? 0 : m_uiUseAdvResPred );
     m_cTEncTop.setARPStepNum                   ( ( isDepth || 0==layer ) ? 1 : H_3D_ARP_WFNR     );
+#endif
+#if H_3D_IC
+    m_cTEncTop.setUseIC                        ( vps.getViewIndex( layer ) == 0 ? false : m_abUseIC[isDepth ? 1 : 0] );
 #endif
 #endif // H_3D
Index: branches/HTM-DEV-0.3-dev2a/source/Lib/TLibCommon/ContextTables.h
===================================================================
--- branches/HTM-DEV-0.3-dev2a/source/Lib/TLibCommon/ContextTables.h	(revision 465)
+++ branches/HTM-DEV-0.3-dev2a/source/Lib/TLibCommon/ContextTables.h	(revision 468)
@@ -100,4 +100,8 @@
 #endif
 
+#if H_3D_IC
+#define NUM_IC_FLAG_CTX               3       ///< number of context models for illumination compensation flag
+#endif
+
 #define CNU                          154      ///< dummy initialization value for unused context models 'Context model Not Used'
 
@@ -349,4 +353,15 @@
 };
 #endif
+
+#if H_3D_IC
+static const UChar 
+INIT_IC_FLAG[3][NUM_IC_FLAG_CTX] =  
+{
+  { CNU,  CNU,  CNU, }, 
+  { 197,  185,  201, }, 
+  { 197,  185,  201, }, 
+};
+#endif
+
 //! \}
 
Index: branches/HTM-DEV-0.3-dev2a/source/Lib/TLibCommon/TComDataCU.cpp
===================================================================
--- branches/HTM-DEV-0.3-dev2a/source/Lib/TLibCommon/TComDataCU.cpp	(revision 465)
+++ branches/HTM-DEV-0.3-dev2a/source/Lib/TLibCommon/TComDataCU.cpp	(revision 468)
@@ -119,4 +119,8 @@
   m_puhARPW              = NULL;
 #endif
+
+#if H_3D_IC
+  m_pbICFlag             = NULL;
+#endif
 }
 
@@ -214,4 +218,7 @@
 #if H_3D_ARP
     m_puhARPW            = new UChar[ uiNumPartition];
+#endif
+#if H_3D_IC
+    m_pbICFlag           = (Bool* )xMalloc(Bool,   uiNumPartition);
 #endif
   }
@@ -304,5 +311,7 @@
     if ( m_puhARPW            ) { delete[] m_puhARPW;           m_puhARPW           = NULL; }
 #endif
-
+#if H_3D_IC
+    if ( m_pbICFlag           ) { xFree(m_pbICFlag);            m_pbICFlag          = NULL; }
+#endif
     m_acCUMvField[0].destroy();
     m_acCUMvField[1].destroy();
@@ -437,4 +446,7 @@
     m_puhCbf[2][ui]=pcFrom->m_puhCbf[2][ui];
     m_pbIPCMFlag[ui] = pcFrom->m_pbIPCMFlag[ui];
+#if H_3D_IC
+    m_pbICFlag[ui]   =  pcFrom->m_pbICFlag[ui];
+#endif
   }
   
@@ -472,4 +484,7 @@
 #if H_3D_ARP
     memset( m_puhARPW           + firstElement, 0,                        numElements * sizeof( UChar )         );
+#endif
+#if H_3D_IC
+    memset( m_pbICFlag          + firstElement, false,                    numElements * sizeof( *m_pbICFlag )   );
 #endif
   }
@@ -611,4 +626,7 @@
       m_puhARPW[ui] = 0;
 #endif
+#if H_3D_IC
+      m_pbICFlag[ui]  = false;
+#endif
     }
   }
@@ -692,4 +710,7 @@
   memset( m_puhHeight,         uhHeight, iSizeInUchar );
   memset( m_pbIPCMFlag,        0, iSizeInBool  );
+#if H_3D_IC
+  memset( m_pbICFlag,          0, iSizeInBool  );
+#endif
   for (UInt ui = 0; ui < m_uiNumPartition; ui++)
   {
@@ -733,4 +754,7 @@
       m_puhARPW           [ui] = pcCU->getARPW( uiPartOffset+ui );
 #endif
+#if H_3D_IC
+      m_pbICFlag[ui] = pcCU->m_pbICFlag[uiPartOffset+ui];
+#endif
     }
   }
@@ -846,4 +870,7 @@
   m_puhARPW             = pcCU->getARPW()             + uiPart;
 #endif
+#if H_3D_IC
+  m_pbICFlag            = pcCU->getICFlag()           + uiPart;
+#endif
 
   m_puhLumaIntraDir     = pcCU->getLumaIntraDir()     + uiPart;
@@ -973,4 +1000,7 @@
 #if H_3D_NBDV
   }
+#endif
+#if H_3D_IC
+  m_pbICFlag           = pcCU->getICFlag()                + uiAbsPartIdx;
 #endif
 }
@@ -1058,4 +1088,7 @@
   memcpy( m_puhARPW             + uiOffset, pcCU->getARPW(),              iSizeInUchar );
 #endif
+#if H_3D_IC
+  memcpy( m_pbICFlag            + uiOffset, pcCU->getICFlag(),            iSizeInBool );
+#endif
 }
 
@@ -1136,4 +1169,7 @@
 #if H_3D_ARP
   memcpy( rpcCU->getARPW()             + m_uiAbsIdxInLCU, m_puhARPW,             iSizeInUchar );
+#endif
+#if H_3D_IC
+  memcpy( rpcCU->getICFlag()           + m_uiAbsIdxInLCU, m_pbICFlag,            iSizeInBool );
 #endif
 }
@@ -1213,4 +1249,7 @@
   memcpy( rpcCU->getARPW()             + uiPartOffset, m_puhARPW,             iSizeInUchar );
 #endif
+#if H_3D_IC
+  memcpy( rpcCU->getICFlag()           + uiPartOffset, m_pbICFlag,            iSizeInBool );
+#endif
 }
 
@@ -1872,4 +1911,13 @@
 #endif
 
+#if H_3D_IC
+UInt TComDataCU::getCtxICFlag( UInt uiAbsPartIdx )
+{
+  UInt        uiCtx = 0;
+
+  return uiCtx;
+}
+#endif
+
 UInt TComDataCU::getCtxInterDir( UInt uiAbsPartIdx )
 {
@@ -2170,4 +2218,48 @@
 }
 
+#if H_3D_IC
+Void TComDataCU::getPartIndexAndSize( UInt uiPartIdx, UInt& ruiPartAddr, Int& riWidth, Int& riHeight, UInt uiAbsPartIdx, Bool bLCU)
+{
+  UInt uiNumPartition  = bLCU ? (getWidth(uiAbsPartIdx)*getHeight(uiAbsPartIdx) >> 4) : m_uiNumPartition;
+  UInt  uiTmpAbsPartIdx  = bLCU ? uiAbsPartIdx : 0;
+
+  switch ( m_pePartSize[uiTmpAbsPartIdx] )
+  {
+  case SIZE_2NxN:
+    riWidth = getWidth( uiTmpAbsPartIdx );      riHeight = getHeight( uiTmpAbsPartIdx ) >> 1; ruiPartAddr = ( uiPartIdx == 0 )? 0 : uiNumPartition >> 1;
+    break;
+  case SIZE_Nx2N:
+    riWidth = getWidth( uiTmpAbsPartIdx ) >> 1; riHeight = getHeight( uiTmpAbsPartIdx );      ruiPartAddr = ( uiPartIdx == 0 )? 0 : uiNumPartition >> 2;
+    break;
+  case SIZE_NxN:
+    riWidth = getWidth( uiTmpAbsPartIdx ) >> 1; riHeight = getHeight( uiTmpAbsPartIdx ) >> 1; ruiPartAddr = ( uiNumPartition >> 2 ) * uiPartIdx;
+    break;
+  case SIZE_2NxnU:
+    riWidth     = getWidth( uiTmpAbsPartIdx );
+    riHeight    = ( uiPartIdx == 0 ) ?  getHeight( uiTmpAbsPartIdx ) >> 2 : ( getHeight( uiTmpAbsPartIdx ) >> 2 ) + ( getHeight( uiTmpAbsPartIdx ) >> 1 );
+    ruiPartAddr = ( uiPartIdx == 0 ) ? 0 : uiNumPartition >> 3;
+    break;
+  case SIZE_2NxnD:
+    riWidth     = getWidth( uiTmpAbsPartIdx );
+    riHeight    = ( uiPartIdx == 0 ) ?  ( getHeight( uiTmpAbsPartIdx ) >> 2 ) + ( getHeight( uiTmpAbsPartIdx ) >> 1 ) : getHeight( uiTmpAbsPartIdx ) >> 2;
+    ruiPartAddr = ( uiPartIdx == 0 ) ? 0 : (uiNumPartition >> 1) + (uiNumPartition >> 3);
+    break;
+  case SIZE_nLx2N:
+    riWidth     = ( uiPartIdx == 0 ) ? getWidth( uiTmpAbsPartIdx ) >> 2 : ( getWidth( uiTmpAbsPartIdx ) >> 2 ) + ( getWidth( uiTmpAbsPartIdx ) >> 1 );
+    riHeight    = getHeight( uiTmpAbsPartIdx );
+    ruiPartAddr = ( uiPartIdx == 0 ) ? 0 : uiNumPartition >> 4;
+    break;
+  case SIZE_nRx2N:
+    riWidth     = ( uiPartIdx == 0 ) ? ( getWidth( uiTmpAbsPartIdx ) >> 2 ) + ( getWidth( uiTmpAbsPartIdx ) >> 1 ) : getWidth( uiTmpAbsPartIdx ) >> 2;
+    riHeight    = getHeight( uiTmpAbsPartIdx );
+    ruiPartAddr = ( uiPartIdx == 0 ) ? 0 : (uiNumPartition >> 2) + (uiNumPartition >> 4);
+    break;
+  default:
+    assert ( m_pePartSize[uiTmpAbsPartIdx] == SIZE_2Nx2N ); 
+    riWidth = getWidth( uiTmpAbsPartIdx );      riHeight = getHeight( uiTmpAbsPartIdx );      ruiPartAddr = 0;
+    break;
+  }
+}
+#else
 Void TComDataCU::getPartIndexAndSize( UInt uiPartIdx, UInt& ruiPartAddr, Int& riWidth, Int& riHeight )
 {
@@ -2209,4 +2301,5 @@
   }
 }
+#endif
 
 
@@ -3111,4 +3204,8 @@
 {
   Int  iMvShift = 2;
+#if H_3D_IC
+  if( getSlice()->getIsDepth() )
+    iMvShift = 0;
+#endif
   Int iOffset = 8;
   Int iHorMax = ( m_pcSlice->getSPS()->getPicWidthInLumaSamples() + iOffset - m_uiCUPelX - 1 ) << iMvShift;
@@ -4317,3 +4414,58 @@
 }
 #endif
+
+#if H_3D_IC
+Void TComDataCU::setICFlagSubParts( Bool bICFlag, UInt uiAbsPartIdx, UInt uiPartIdx, UInt uiDepth )
+{
+  memset( m_pbICFlag + uiAbsPartIdx, bICFlag, (m_pcPic->getNumPartInCU() >> ( 2 * uiDepth ))*sizeof(Bool) );
+}
+
+Bool TComDataCU::isICFlagRequired( UInt uiAbsPartIdx )
+{
+  UInt uiPartAddr;
+  UInt iNumbPart;
+
+  if( !( getPartitionSize( uiAbsPartIdx ) == SIZE_2Nx2N ) )
+  {
+    return false;
+  }
+
+  if( getSlice()->getIcSkipParseFlag() )
+  {
+    if( getMergeFlag( uiAbsPartIdx ) && getMergeIndex( uiAbsPartIdx ) == 0 )
+    {
+      return false;
+    }
+  }
+
+  if( getMergeFlag( uiAbsPartIdx ) )
+  {
+    return true;
+  }
+
+
+  Int iWidth, iHeight;
+
+  iNumbPart = ( getPartitionSize( uiAbsPartIdx ) == SIZE_2Nx2N ? 1 : ( getPartitionSize( uiAbsPartIdx ) == SIZE_NxN ? 4 : 2 ) );
+
+  for(UInt i = 0; i < iNumbPart; i++)
+  {
+    getPartIndexAndSize( i, uiPartAddr, iWidth, iHeight, uiAbsPartIdx, true );
+    uiPartAddr += uiAbsPartIdx;
+
+    for(UInt uiRefIdx = 0; uiRefIdx < 2; uiRefIdx++)
+    {
+      RefPicList eRefList = uiRefIdx ? REF_PIC_LIST_1 : REF_PIC_LIST_0;
+      Int iBestRefIdx = getCUMvField(eRefList)->getRefIdx(uiPartAddr);
+
+      if( ( getInterDir( uiPartAddr ) & ( uiRefIdx+1 ) ) && iBestRefIdx >= 0 && getSlice()->getViewIndex() != getSlice()->getRefPic( eRefList, iBestRefIdx )->getViewIndex() )
+      {
+        return true;
+      }
+    }
+  }
+
+  return false;
+}
+#endif
 //! \}
Index: branches/HTM-DEV-0.3-dev2a/source/Lib/TLibCommon/TComDataCU.h
===================================================================
--- branches/HTM-DEV-0.3-dev2a/source/Lib/TLibCommon/TComDataCU.h	(revision 465)
+++ branches/HTM-DEV-0.3-dev2a/source/Lib/TLibCommon/TComDataCU.h	(revision 468)
@@ -197,4 +197,7 @@
   UChar*        m_puhARPW;
 #endif
+#if H_3D_IC
+  Bool*         m_pbICFlag;           ///< array of IC flags
+#endif
   // -------------------------------------------------------------------------------------------------------------------
   // misc. variables
@@ -453,4 +456,12 @@
   Double        getARPWFactor      ( UInt uiIdx );
 #endif
+#if H_3D_IC
+  Bool*         getICFlag          ()                        { return m_pbICFlag;               }
+  Bool          getICFlag          ( UInt uiIdx )            { return m_pbICFlag[uiIdx];        }
+  Void          setICFlag          ( UInt uiIdx, Bool  uh )  { m_pbICFlag[uiIdx] = uh;          }
+  Void          setICFlagSubParts  ( Bool bICFlag,  UInt uiAbsPartIdx, UInt uiPartIdx, UInt uiDepth );
+  Bool          isICFlagRequired   ( UInt uiAbsPartIdx );
+  Void          getPartIndexAndSize( UInt uiPartIdx, UInt& ruiPartAddr, Int& riWidth, Int& riHeight, UInt uiAbsPartIdx = 0, Bool bLCU = false);
+#else
   // -------------------------------------------------------------------------------------------------------------------
   // member functions for accessing partition information
@@ -458,4 +469,5 @@
   
   Void          getPartIndexAndSize   ( UInt uiPartIdx, UInt& ruiPartAddr, Int& riWidth, Int& riHeight );
+#endif
   UChar         getNumPartInter       ();
   Bool          isFirstAbsZorderIdxInDepth (UInt uiAbsPartIdx, UInt uiDepth);
@@ -561,5 +573,7 @@
   UInt          getCTXARPWFlag                  ( UInt   uiAbsPartIdx                                 );
 #endif  
-
+#if H_3D_IC
+  UInt          getCtxICFlag                    ( UInt   uiAbsPartIdx                                 );
+#endif
   UInt          getSliceStartCU         ( UInt pos )                  { return m_sliceStartCU[pos-m_uiAbsIdxInLCU];                                                                                          }
   UInt          getSliceSegmentStartCU  ( UInt pos )                  { return m_sliceSegmentStartCU[pos-m_uiAbsIdxInLCU];                                                                                   }
Index: branches/HTM-DEV-0.3-dev2a/source/Lib/TLibCommon/TComPattern.h
===================================================================
--- branches/HTM-DEV-0.3-dev2a/source/Lib/TLibCommon/TComPattern.h	(revision 465)
+++ branches/HTM-DEV-0.3-dev2a/source/Lib/TLibCommon/TComPattern.h	(revision 468)
@@ -99,5 +99,7 @@
   TComPatternParam  m_cPatternCb;
   TComPatternParam  m_cPatternCr;
-  
+#if H_3D_IC
+  Bool              m_bICFlag;
+#endif
   static const UChar m_aucIntraFilter[5];
   
@@ -109,4 +111,9 @@
   Int   getROIYHeight()           { return m_cPatternY.m_iROIHeight;      }
   Int   getPatternLStride()       { return m_cPatternY.m_iPatternStride;  }
+
+#if H_3D_IC
+  Bool  getICFlag()               { return m_bICFlag; }
+  Void  setICFlag( Bool bICFlag ) { m_bICFlag = bICFlag; }
+#endif
 
   // access functions of ADI buffers
Index: branches/HTM-DEV-0.3-dev2a/source/Lib/TLibCommon/TComPrediction.cpp
===================================================================
--- branches/HTM-DEV-0.3-dev2a/source/Lib/TLibCommon/TComPrediction.cpp	(revision 465)
+++ branches/HTM-DEV-0.3-dev2a/source/Lib/TLibCommon/TComPrediction.cpp	(revision 468)
@@ -122,4 +122,10 @@
     }
   }
+#if H_3D_IC
+  for( Int i = 1; i < 64; i++ )
+  {
+    m_uiaShift[i-1] = ( (1 << 15) + i/2 ) / i;
+  }
+#endif
 }
 
@@ -505,6 +511,20 @@
   {
 #endif
+#if H_3D_IC
+    Bool bICFlag = pcCU->getICFlag( uiPartAddr ) && ( pcCU->getSlice()->getRefPic( eRefPicList, iRefIdx )->getViewIndex() != pcCU->getSlice()->getViewIndex() );
+    xPredInterLumaBlk  ( pcCU, pcCU->getSlice()->getRefPic( eRefPicList, iRefIdx )->getPicYuvRec(), uiPartAddr, &cMv, iWidth, iHeight, rpcYuvPred, bi
+#if H_3D_ARP
+      , false
+#endif
+      , bICFlag );
+    xPredInterChromaBlk( pcCU, pcCU->getSlice()->getRefPic( eRefPicList, iRefIdx )->getPicYuvRec(), uiPartAddr, &cMv, iWidth, iHeight, rpcYuvPred, bi
+#if H_3D_ARP
+      , false
+#endif
+      , bICFlag );
+#else
   xPredInterLumaBlk  ( pcCU, pcCU->getSlice()->getRefPic( eRefPicList, iRefIdx )->getPicYuvRec(), uiPartAddr, &cMv, iWidth, iHeight, rpcYuvPred, bi );
   xPredInterChromaBlk( pcCU, pcCU->getSlice()->getRefPic( eRefPicList, iRefIdx )->getPicYuvRec(), uiPartAddr, &cMv, iWidth, iHeight, rpcYuvPred, bi );
+#endif
 #if H_3D_ARP
   }
@@ -671,4 +691,7 @@
     , Bool filterType
 #endif
+#if H_3D_IC
+    , Bool bICFlag
+#endif
   )
 {
@@ -683,4 +706,14 @@
   Int yFrac = mv->getVer() & 0x3;
 
+#if H_3D_IC
+  if( cu->getSlice()->getIsDepth() )
+  {
+    refOffset = mv->getHor() + mv->getVer() * refStride;
+    ref       = refPic->getLumaAddr( cu->getAddr(), cu->getZorderIdxInCU() + partAddr ) + refOffset;
+    xFrac     = 0;
+    yFrac     = 0;
+  }
+#endif
+
   if ( yFrac == 0 )
   {
@@ -718,4 +751,28 @@
       );    
   }
+
+#if H_3D_IC
+  if( bICFlag )
+  {
+    Int a, b, iShift, i, j;
+
+    xGetLLSICPrediction( cu, mv, refPic, a, b, iShift, TEXT_LUMA );
+
+    for ( i = 0; i < height; i++ )
+    {
+      for ( j = 0; j < width; j++ )
+      {
+        if( bi )
+        {
+          Int iIFshift = IF_INTERNAL_PREC - g_bitDepthY;
+          dst[j] = ( ( a*dst[j] + a*IF_INTERNAL_OFFS ) >> iShift ) + b*( 1 << iIFshift ) - IF_INTERNAL_OFFS;
+        }
+        else
+          dst[j] = Clip3( 0, ( 1 << g_bitDepthY ) - 1, ( ( a*dst[j] ) >> iShift ) + b );
+      }
+      dst += dstStride;
+    }
+  }
+#endif
 }
 
@@ -735,5 +792,8 @@
 #if H_3D_ARP
     , Bool filterType
-#endif   
+#endif
+#if H_3D_IC
+    , Bool bICFlag
+#endif
   )
 {
@@ -811,4 +871,41 @@
       );    
   }
+
+#if H_3D_IC
+  if( bICFlag )
+  {
+    Int a, b, iShift, i, j;
+    xGetLLSICPrediction( cu, mv, refPic, a, b, iShift, TEXT_CHROMA_U ); // Cb
+    for ( i = 0; i < cxHeight; i++ )
+    {
+      for ( j = 0; j < cxWidth; j++ )
+      {
+        if( bi )
+        {
+          Int iIFshift = IF_INTERNAL_PREC - g_bitDepthC;
+          dstCb[j] = ( ( a*dstCb[j] + a*IF_INTERNAL_OFFS ) >> iShift ) + b*( 1<<iIFshift ) - IF_INTERNAL_OFFS;
+        }
+        else
+          dstCb[j] = Clip3(  0, ( 1 << g_bitDepthC ) - 1, ( ( a*dstCb[j] ) >> iShift ) + b );
+      }
+      dstCb += dstStride;
+    }
+    xGetLLSICPrediction( cu, mv, refPic, a, b, iShift, TEXT_CHROMA_V ); // Cr
+    for ( i = 0; i < cxHeight; i++ )
+    {
+      for ( j = 0; j < cxWidth; j++ )
+      {
+        if( bi )
+        {
+          Int iIFshift = IF_INTERNAL_PREC - g_bitDepthC;
+          dstCr[j] = ( ( a*dstCr[j] + a*IF_INTERNAL_OFFS ) >> iShift ) + b*( 1<<iIFshift ) - IF_INTERNAL_OFFS;
+        }
+        else
+          dstCr[j] = Clip3( 0, ( 1 << g_bitDepthC ) - 1, ( ( a*dstCr[j] ) >> iShift ) + b );
+      }
+      dstCr += dstStride;
+    }
+  }
+#endif
 }
 
@@ -930,3 +1027,259 @@
   return;
 }
+
+#if H_3D_IC
+/** Function for deriving the position of first non-zero binary bit of a value
+ * \param x input value
+ *
+ * This function derives the position of first non-zero binary bit of a value
+ */
+Int GetMSB( UInt x )
+{
+  Int iMSB = 0, bits = ( sizeof( Int ) << 3 ), y = 1;
+
+  while( x > 1 )
+  {
+    bits >>= 1;
+    y = x >> bits;
+
+    if( y )
+    {
+      x = y;
+      iMSB += bits;
+    }
+  }
+
+  iMSB+=y;
+
+  return iMSB;
+}
+
+/** Function for counting leading number of zeros/ones
+ * \param x input value
+ \ This function counts leading number of zeros for positive numbers and
+ \ leading number of ones for negative numbers. This can be implemented in
+ \ single instructure cycle on many processors.
+ */
+
+Short CountLeadingZerosOnes (Short x)
+{
+  Short clz;
+  Short i;
+
+  if(x == 0)
+  {
+    clz = 0;
+  }
+  else
+  {
+    if (x == -1)
+    {
+      clz = 15;
+    }
+    else
+    {
+      if(x < 0)
+      {
+        x = ~x;
+      }
+      clz = 15;
+      for(i = 0;i < 15;++i)
+      {
+        if(x) 
+        {
+          clz --;
+        }
+        x = x >> 1;
+      }
+    }
+  }
+  return clz;
+}
+
+/** Function for deriving LM illumination compensation.
+ */
+Void TComPrediction::xGetLLSICPrediction( TComDataCU* pcCU, TComMv *pMv, TComPicYuv *pRefPic, Int &a, Int &b, Int &iShift, TextType eType )
+{
+  TComPicYuv *pRecPic = pcCU->getPic()->getPicYuvRec();
+  Pel *pRec = NULL, *pRef = NULL;
+  UInt uiWidth, uiHeight, uiTmpPartIdx;
+  Int iRecStride = ( eType == TEXT_LUMA ) ? pRecPic->getStride() : pRecPic->getCStride();
+  Int iRefStride = ( eType == TEXT_LUMA ) ? pRefPic->getStride() : pRefPic->getCStride();
+  Int iCUPelX, iCUPelY, iRefX, iRefY, iRefOffset, iHor, iVer;
+
+  iCUPelX = pcCU->getCUPelX() + g_auiRasterToPelX[g_auiZscanToRaster[pcCU->getZorderIdxInCU()]];
+  iCUPelY = pcCU->getCUPelY() + g_auiRasterToPelY[g_auiZscanToRaster[pcCU->getZorderIdxInCU()]];
+  iHor = pcCU->getSlice()->getIsDepth() ? pMv->getHor() : ( ( pMv->getHor() + 2 ) >> 2 );
+  iVer = pcCU->getSlice()->getIsDepth() ? pMv->getVer() : ( ( pMv->getVer() + 2 ) >> 2 );
+  iRefX   = iCUPelX + iHor;
+  iRefY   = iCUPelY + iVer;
+  if( eType != TEXT_LUMA )
+  {
+    iHor = pcCU->getSlice()->getIsDepth() ? ( ( pMv->getHor() + 1 ) >> 1 ) : ( ( pMv->getHor() + 4 ) >> 3 );
+    iVer = pcCU->getSlice()->getIsDepth() ? ( ( pMv->getVer() + 1 ) >> 1 ) : ( ( pMv->getVer() + 4 ) >> 3 );
+  }
+  uiWidth  = ( eType == TEXT_LUMA ) ? pcCU->getWidth( 0 )  : ( pcCU->getWidth( 0 )  >> 1 );
+  uiHeight = ( eType == TEXT_LUMA ) ? pcCU->getHeight( 0 ) : ( pcCU->getHeight( 0 ) >> 1 );
+
+  Int i, j, iCountShift = 0;
+
+  // LLS parameters estimation -->
+
+  Int x = 0, y = 0, xx = 0, xy = 0;
+
+  if( pcCU->getPUAbove( uiTmpPartIdx, pcCU->getZorderIdxInCU() ) && iCUPelY > 0 && iRefY > 0 )
+  {
+    iRefOffset = iHor + iVer * iRefStride - iRefStride;
+    if( eType == TEXT_LUMA )
+    {
+      pRef = pRefPic->getLumaAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() ) + iRefOffset;
+      pRec = pRecPic->getLumaAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() ) - iRecStride;
+    }
+    else if( eType == TEXT_CHROMA_U )
+    {
+      pRef = pRefPic->getCbAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() ) + iRefOffset;
+      pRec = pRecPic->getCbAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() ) - iRecStride;
+    }
+    else
+    {
+      assert( eType == TEXT_CHROMA_V );
+      pRef = pRefPic->getCrAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() ) + iRefOffset;
+      pRec = pRecPic->getCrAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() ) - iRecStride;
+    }
+
+    for( j = 0; j < uiWidth; j++ )
+    {
+      x += pRef[j];
+      y += pRec[j];
+      xx += pRef[j] * pRef[j];
+      xy += pRef[j] * pRec[j];
+    }
+    iCountShift += g_aucConvertToBit[ uiWidth ] + 2;
+  }
+
+
+  if( pcCU->getPULeft( uiTmpPartIdx, pcCU->getZorderIdxInCU() ) && iCUPelX > 0 && iRefX > 0 )
+  {
+    iRefOffset = iHor + iVer * iRefStride - 1;
+    if( eType == TEXT_LUMA )
+    {
+      pRef = pRefPic->getLumaAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() ) + iRefOffset;
+      pRec = pRecPic->getLumaAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() ) - 1;
+    }
+    else if( eType == TEXT_CHROMA_U )
+    {
+      pRef = pRefPic->getCbAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() ) + iRefOffset;
+      pRec = pRecPic->getCbAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() ) - 1;
+    }
+    else
+    {
+      assert( eType == TEXT_CHROMA_V );
+      pRef = pRefPic->getCrAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() ) + iRefOffset;
+      pRec = pRecPic->getCrAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() ) - 1;
+    }
+
+    for( i = 0; i < uiHeight; i++ )
+    {
+      x += pRef[0];
+      y += pRec[0];
+      xx += pRef[0] * pRef[0];
+      xy += pRef[0] * pRec[0];
+
+      pRef += iRefStride;
+      pRec += iRecStride;
+    }
+    iCountShift += iCountShift > 0 ? 1 : ( g_aucConvertToBit[ uiWidth ] + 2 );
+  }
+
+  Int iTempShift = ( ( eType == TEXT_LUMA ) ? g_bitDepthY : g_bitDepthC ) + g_aucConvertToBit[ uiWidth ] + 3 - 15;
+
+  if( iTempShift > 0 )
+  {
+    x  = ( x +  ( 1 << ( iTempShift - 1 ) ) ) >> iTempShift;
+    y  = ( y +  ( 1 << ( iTempShift - 1 ) ) ) >> iTempShift;
+    xx = ( xx + ( 1 << ( iTempShift - 1 ) ) ) >> iTempShift;
+    xy = ( xy + ( 1 << ( iTempShift - 1 ) ) ) >> iTempShift;
+    iCountShift -= iTempShift;
+  }
+
+  iShift = 13;
+
+  if( iCountShift == 0 )
+  {
+    a = 1;
+    b = 0;
+    iShift = 0;
+  }
+  else
+  {
+    Int a1 = ( xy << iCountShift ) - y * x;
+    Int a2 = ( xx << iCountShift ) - x * x;              
+
+    {
+      const Int iShiftA2 = 6;
+      const Int iShiftA1 = 15;
+      const Int iAccuracyShift = 15;
+
+      Int iScaleShiftA2 = 0;
+      Int iScaleShiftA1 = 0;
+      Int a1s = a1;
+      Int a2s = a2;
+
+      iScaleShiftA1 = GetMSB( abs( a1 ) ) - iShiftA1;
+      iScaleShiftA2 = GetMSB( abs( a2 ) ) - iShiftA2;  
+
+      if( iScaleShiftA1 < 0 )
+      {
+        iScaleShiftA1 = 0;
+      }
+
+      if( iScaleShiftA2 < 0 )
+      {
+        iScaleShiftA2 = 0;
+      }
+
+      Int iScaleShiftA = iScaleShiftA2 + iAccuracyShift - iShift - iScaleShiftA1;
+
+      a2s = a2 >> iScaleShiftA2;
+
+      a1s = a1 >> iScaleShiftA1;
+
+      if (a2s >= 1)
+      {
+        a = a1s * m_uiaShift[ a2s - 1];
+      }
+      else
+      {
+        a = 0;
+      }
+
+      if( iScaleShiftA < 0 )
+      {
+        a = a << -iScaleShiftA;
+      }
+      else
+      {
+        a = a >> iScaleShiftA;
+      }
+
+      a = Clip3( -( 1 << 15 ), ( 1 << 15 ) - 1, a ); 
+
+      Int minA = -(1 << (6));
+      Int maxA = (1 << 6) - 1;
+      if( a <= maxA && a >= minA )
+      {
+        // do nothing
+      }
+      else
+      {
+        Short n = CountLeadingZerosOnes( a );
+        a = a >> (9-n);
+        iShift -= (9-n);
+      }
+
+      b = (  y - ( ( a * x ) >> iShift ) + ( 1 << ( iCountShift - 1 ) ) ) >> iCountShift;
+    }
+  }   
+}
+#endif
 //! \}
Index: branches/HTM-DEV-0.3-dev2a/source/Lib/TLibCommon/TComPrediction.h
===================================================================
--- branches/HTM-DEV-0.3-dev2a/source/Lib/TLibCommon/TComPrediction.h	(revision 465)
+++ branches/HTM-DEV-0.3-dev2a/source/Lib/TLibCommon/TComPrediction.h	(revision 468)
@@ -75,5 +75,7 @@
   Pel*   m_pLumaRecBuffer;       ///< array for downsampled reconstructed luma sample 
   Int    m_iLumaRecStride;       ///< stride of #m_pLumaRecBuffer array
-
+#if H_3D_IC
+  UInt   m_uiaShift[ 63 ];       // Table for multiplication to substitue of division operation
+#endif
   Void xPredIntraAng            (Int bitDepth, Int* pSrc, Int srcStride, Pel*& rpDst, Int dstStride, UInt width, UInt height, UInt dirMode, Bool blkAboveAvailable, Bool blkLeftAvailable, Bool bFilter );
   Void xPredIntraPlanar         ( Int* pSrc, Int srcStride, Pel* rpDst, Int dstStride, UInt width, UInt height );
@@ -89,4 +91,7 @@
     , Bool filterType = false
 #endif
+#if H_3D_IC
+    , Bool bICFlag    = false
+#endif
     );
   Void xPredInterChromaBlk( TComDataCU *cu, TComPicYuv *refPic, UInt partAddr, TComMv *mv, Int width, Int height, TComYuv *&dstPic, Bool bi 
@@ -94,9 +99,14 @@
     , Bool filterType = false
 #endif
+#if H_3D_IC
+    , Bool bICFlag    = false
+#endif
     );
   Void xWeightedAverage         ( TComYuv* pcYuvSrc0, TComYuv* pcYuvSrc1, Int iRefIdx0, Int iRefIdx1, UInt uiPartAddr, Int iWidth, Int iHeight, TComYuv*& rpcYuvDst );
   
   Void xGetLLSPrediction ( TComPattern* pcPattern, Int* pSrc0, Int iSrcStride, Pel* pDst0, Int iDstStride, UInt uiWidth, UInt uiHeight, UInt uiExt0 );
-
+#if H_3D_IC
+  Void xGetLLSICPrediction( TComDataCU* pcCU, TComMv *pMv, TComPicYuv *pRefPic, Int &a, Int &b, Int &iShift, TextType eType );
+#endif
   Void xDCPredFiltering( Int* pSrc, Int iSrcStride, Pel*& rpDst, Int iDstStride, Int iWidth, Int iHeight );
   Bool xCheckIdenticalMotion    ( TComDataCU* pcCU, UInt PartAddr);
Index: branches/HTM-DEV-0.3-dev2a/source/Lib/TLibCommon/TComRdCost.cpp
===================================================================
--- branches/HTM-DEV-0.3-dev2a/source/Lib/TLibCommon/TComRdCost.cpp	(revision 465)
+++ branches/HTM-DEV-0.3-dev2a/source/Lib/TLibCommon/TComRdCost.cpp	(revision 468)
@@ -502,4 +502,8 @@
   cDtParam.bitDepth = bitDepth;
 
+#if H_3D_IC
+  cDtParam.bUseIC       = false;
+#endif
+
 #if WEIGHTED_CHROMA_DISTORTION
   if (eText == TEXT_CHROMA_U)
@@ -599,4 +603,12 @@
     return xGetSADw( pcDtParam );
   }
+
+#if H_3D_IC
+  if( pcDtParam->bUseIC )
+  {
+    return xGetSADic( pcDtParam );
+  }
+#endif
+
   Pel* piOrg   = pcDtParam->pOrg;
   Pel* piCur   = pcDtParam->pCur;
@@ -627,4 +639,12 @@
     return xGetSADw( pcDtParam );
   }
+
+#if H_3D_IC
+  if( pcDtParam->bUseIC )
+  {
+    return xGetSAD4ic( pcDtParam );
+  }
+#endif
+
   Pel* piOrg   = pcDtParam->pOrg;
   Pel* piCur   = pcDtParam->pCur;
@@ -658,4 +678,12 @@
     return xGetSADw( pcDtParam );
   }
+
+#if H_3D_IC
+  if( pcDtParam->bUseIC )
+  {
+    return xGetSAD8ic( pcDtParam );
+  }
+#endif
+
   Pel* piOrg      = pcDtParam->pOrg;
   Pel* piCur      = pcDtParam->pCur;
@@ -693,4 +721,12 @@
     return xGetSADw( pcDtParam );
   }
+
+#if H_3D_IC
+  if( pcDtParam->bUseIC )
+  {
+    return xGetSAD16ic( pcDtParam );
+  }
+#endif
+
   Pel* piOrg   = pcDtParam->pOrg;
   Pel* piCur   = pcDtParam->pCur;
@@ -737,4 +773,12 @@
     return xGetSADw( pcDtParam );
   }
+
+#if H_3D_IC
+  if( pcDtParam->bUseIC )
+  {
+    return xGetSAD12ic( pcDtParam );
+  }
+#endif
+
   Pel* piOrg   = pcDtParam->pOrg;
   Pel* piCur   = pcDtParam->pCur;
@@ -773,4 +817,11 @@
 UInt TComRdCost::xGetSAD16N( DistParam* pcDtParam )
 {
+#if H_3D_IC
+  if( pcDtParam->bUseIC )
+  {
+    return xGetSAD16Nic( pcDtParam );
+  }
+#endif
+
   Pel* piOrg   = pcDtParam->pOrg;
   Pel* piCur   = pcDtParam->pCur;
@@ -819,4 +870,12 @@
     return xGetSADw( pcDtParam );
   }
+
+#if H_3D_IC
+  if( pcDtParam->bUseIC )
+  {
+    return xGetSAD32ic( pcDtParam );
+  }
+#endif
+
   Pel* piOrg   = pcDtParam->pOrg;
   Pel* piCur   = pcDtParam->pCur;
@@ -879,4 +938,12 @@
     return xGetSADw( pcDtParam );
   }
+
+#if H_3D_IC
+  if( pcDtParam->bUseIC )
+  {
+    return xGetSAD24ic( pcDtParam );
+  }
+#endif
+
   Pel* piOrg   = pcDtParam->pOrg;
   Pel* piCur   = pcDtParam->pCur;
@@ -932,4 +999,12 @@
     return xGetSADw( pcDtParam );
   }
+
+#if H_3D_IC
+  if( pcDtParam->bUseIC )
+  {
+    return xGetSAD64ic( pcDtParam );
+  }
+#endif
+
   Pel* piOrg   = pcDtParam->pOrg;
   Pel* piCur   = pcDtParam->pCur;
@@ -1024,4 +1099,12 @@
     return xGetSADw( pcDtParam );
   }
+
+#if H_3D_IC
+  if( pcDtParam->bUseIC )
+  {
+    return xGetSAD48ic( pcDtParam );
+  }
+#endif
+
   Pel* piOrg   = pcDtParam->pOrg;
   Pel* piCur   = pcDtParam->pCur;
@@ -1094,4 +1177,1138 @@
 #endif
 
+#if H_3D_IC
+UInt TComRdCost::xGetSADic( DistParam* pcDtParam )
+{
+  if ( pcDtParam->bApplyWeight )
+  {
+    return xGetSADw( pcDtParam );
+  }
+  Pel* piOrg   = pcDtParam->pOrg;
+  Pel* piCur   = pcDtParam->pCur;
+  Int  iRows   = pcDtParam->iRows;
+  Int  iCols   = pcDtParam->iCols;
+  Int  iStrideCur = pcDtParam->iStrideCur;
+  Int  iStrideOrg = pcDtParam->iStrideOrg;
+
+  UInt uiSum = 0;
+
+  Int  iOrigAvg = 0, iCurAvg = 0;
+  Int  iDeltaC;
+
+  for( ; iRows != 0; iRows-- )
+  {
+    for (Int n = 0; n < iCols; n++ )
+    {
+      iOrigAvg += piOrg[n];
+      iCurAvg  += piCur[n];
+    }
+    piOrg += iStrideOrg;
+    piCur += iStrideCur;
+  }
+
+  piOrg   = pcDtParam->pOrg;
+  piCur   = pcDtParam->pCur;
+  iRows   = pcDtParam->iRows;
+
+  iDeltaC = (iOrigAvg - iCurAvg)/iCols/iRows;
+
+  for( ; iRows != 0; iRows-- )
+  {
+    for (Int n = 0; n < iCols; n++ )
+    {
+      uiSum += abs( piOrg[n] - piCur[n] - iDeltaC );
+    }
+    piOrg += iStrideOrg;
+    piCur += iStrideCur;
+  }
+
+  return ( uiSum >> DISTORTION_PRECISION_ADJUSTMENT( pcDtParam->bitDepth - 8 ) );
+}
+
+UInt TComRdCost::xGetSAD4ic( DistParam* pcDtParam )
+{
+  if ( pcDtParam->bApplyWeight ) 
+  {
+    return xGetSADw( pcDtParam );
+  }
+  Pel* piOrg   = pcDtParam->pOrg;
+  Pel* piCur   = pcDtParam->pCur;
+  Int  iRows   = pcDtParam->iRows;
+  Int  iSubShift  = pcDtParam->iSubShift;
+  Int  iSubStep   = ( 1 << iSubShift );
+  Int  iStrideCur = pcDtParam->iStrideCur*iSubStep;
+  Int  iStrideOrg = pcDtParam->iStrideOrg*iSubStep;
+
+  UInt uiSum = 0;
+
+  Int  iOrigAvg = 0, iCurAvg = 0, uiRowCnt = 0;
+  Int  iDeltaC;
+
+  for( ; iRows != 0; iRows-=iSubStep )
+  {
+    iOrigAvg += piOrg[0];
+    iOrigAvg += piOrg[1];
+    iOrigAvg += piOrg[2];
+    iOrigAvg += piOrg[3];
+
+    iCurAvg  += piCur[0];
+    iCurAvg  += piCur[1];
+    iCurAvg  += piCur[2];
+    iCurAvg  += piCur[3];
+
+    piOrg += iStrideOrg;
+    piCur += iStrideCur;
+    uiRowCnt++;
+  }
+
+  piOrg   = pcDtParam->pOrg;
+  piCur   = pcDtParam->pCur;
+  iRows   = pcDtParam->iRows;
+
+  iDeltaC = uiRowCnt ? ((iOrigAvg - iCurAvg)/uiRowCnt/4) : 0;
+
+  for( ; iRows != 0; iRows-=iSubStep )
+  {
+    uiSum += abs( piOrg[0] - piCur[0] - iDeltaC );
+    uiSum += abs( piOrg[1] - piCur[1] - iDeltaC );
+    uiSum += abs( piOrg[2] - piCur[2] - iDeltaC );
+    uiSum += abs( piOrg[3] - piCur[3] - iDeltaC );
+
+    piOrg += iStrideOrg;
+    piCur += iStrideCur;
+  }
+
+  uiSum <<= iSubShift;
+  return ( uiSum >> DISTORTION_PRECISION_ADJUSTMENT( pcDtParam->bitDepth - 8 ) );
+}
+
+UInt TComRdCost::xGetSAD8ic( DistParam* pcDtParam )
+{
+  if ( pcDtParam->bApplyWeight )
+  {
+    return xGetSADw( pcDtParam );
+  }
+  Pel* piOrg      = pcDtParam->pOrg;
+  Pel* piCur      = pcDtParam->pCur;
+  Int  iRows      = pcDtParam->iRows;
+  Int  iSubShift  = pcDtParam->iSubShift;
+  Int  iSubStep   = ( 1 << iSubShift );
+  Int  iStrideCur = pcDtParam->iStrideCur*iSubStep;
+  Int  iStrideOrg = pcDtParam->iStrideOrg*iSubStep;
+
+  UInt uiSum = 0;
+
+  Int  iOrigAvg = 0, iCurAvg = 0, uiRowCnt = 0;
+  Int  iDeltaC;
+
+  for( ; iRows != 0; iRows-=iSubStep )
+  {
+    iOrigAvg += piOrg[0];
+    iOrigAvg += piOrg[1];
+    iOrigAvg += piOrg[2];
+    iOrigAvg += piOrg[3];
+    iOrigAvg += piOrg[4];
+    iOrigAvg += piOrg[5];
+    iOrigAvg += piOrg[6];
+    iOrigAvg += piOrg[7];
+
+    iCurAvg  += piCur[0];
+    iCurAvg  += piCur[1];
+    iCurAvg  += piCur[2];
+    iCurAvg  += piCur[3];
+    iCurAvg  += piCur[4];
+    iCurAvg  += piCur[5];
+    iCurAvg  += piCur[6];
+    iCurAvg  += piCur[7];
+
+    piOrg += iStrideOrg;
+    piCur += iStrideCur;
+    uiRowCnt++;
+  }
+
+  piOrg   = pcDtParam->pOrg;
+  piCur   = pcDtParam->pCur;
+  iRows   = pcDtParam->iRows;
+
+  iDeltaC = uiRowCnt ? ((iOrigAvg - iCurAvg)/uiRowCnt/8) : 0;
+
+  for( ; iRows != 0; iRows-=iSubStep )
+  {
+    uiSum += abs( piOrg[0] - piCur[0] - iDeltaC );
+    uiSum += abs( piOrg[1] - piCur[1] - iDeltaC );
+    uiSum += abs( piOrg[2] - piCur[2] - iDeltaC );
+    uiSum += abs( piOrg[3] - piCur[3] - iDeltaC );
+    uiSum += abs( piOrg[4] - piCur[4] - iDeltaC );
+    uiSum += abs( piOrg[5] - piCur[5] - iDeltaC );
+    uiSum += abs( piOrg[6] - piCur[6] - iDeltaC );
+    uiSum += abs( piOrg[7] - piCur[7] - iDeltaC );
+
+    piOrg += iStrideOrg;
+    piCur += iStrideCur;
+  }
+
+  uiSum <<= iSubShift;
+  return ( uiSum >> DISTORTION_PRECISION_ADJUSTMENT( pcDtParam->bitDepth - 8 ) );
+}
+
+UInt TComRdCost::xGetSAD16ic( DistParam* pcDtParam )
+{
+  if ( pcDtParam->bApplyWeight )
+  {
+    return xGetSADw( pcDtParam );
+  }
+  Pel* piOrg   = pcDtParam->pOrg;
+  Pel* piCur   = pcDtParam->pCur;
+  Int  iRows   = pcDtParam->iRows;
+  Int  iSubShift  = pcDtParam->iSubShift;
+  Int  iSubStep   = ( 1 << iSubShift );
+  Int  iStrideCur = pcDtParam->iStrideCur*iSubStep;
+  Int  iStrideOrg = pcDtParam->iStrideOrg*iSubStep;
+
+  UInt uiSum = 0;
+
+  Int iOrigAvg = 0, iCurAvg = 0, uiRowCnt = 0;
+  Int iDeltaC;
+
+  for( ; iRows != 0; iRows-=iSubStep )
+  {
+    iOrigAvg += piOrg[0];
+    iOrigAvg += piOrg[1];
+    iOrigAvg += piOrg[2];
+    iOrigAvg += piOrg[3];
+    iOrigAvg += piOrg[4];
+    iOrigAvg += piOrg[5];
+    iOrigAvg += piOrg[6];
+    iOrigAvg += piOrg[7];
+    iOrigAvg += piOrg[8];
+    iOrigAvg += piOrg[9];
+    iOrigAvg += piOrg[10];
+    iOrigAvg += piOrg[11];
+    iOrigAvg += piOrg[12];
+    iOrigAvg += piOrg[13];
+    iOrigAvg += piOrg[14];
+    iOrigAvg += piOrg[15];
+
+    iCurAvg  += piCur[0];
+    iCurAvg  += piCur[1];
+    iCurAvg  += piCur[2];
+    iCurAvg  += piCur[3];
+    iCurAvg  += piCur[4];
+    iCurAvg  += piCur[5];
+    iCurAvg  += piCur[6];
+    iCurAvg  += piCur[7];
+    iCurAvg  += piCur[8];
+    iCurAvg  += piCur[9];
+    iCurAvg  += piCur[10];
+    iCurAvg  += piCur[11];
+    iCurAvg  += piCur[12];
+    iCurAvg  += piCur[13];
+    iCurAvg  += piCur[14];
+    iCurAvg  += piCur[15];
+
+    piOrg += iStrideOrg;
+    piCur += iStrideCur;
+    uiRowCnt++;
+  }
+
+  piOrg   = pcDtParam->pOrg;
+  piCur   = pcDtParam->pCur;
+  iRows   = pcDtParam->iRows;
+
+  iDeltaC = uiRowCnt ? ((iOrigAvg - iCurAvg)/uiRowCnt/16) : 0;
+
+  for( ; iRows != 0; iRows-=iSubStep )
+  {
+    uiSum += abs( piOrg[0] - piCur[0] - iDeltaC );
+    uiSum += abs( piOrg[1] - piCur[1] - iDeltaC );
+    uiSum += abs( piOrg[2] - piCur[2] - iDeltaC );
+    uiSum += abs( piOrg[3] - piCur[3] - iDeltaC );
+    uiSum += abs( piOrg[4] - piCur[4] - iDeltaC );
+    uiSum += abs( piOrg[5] - piCur[5] - iDeltaC );
+    uiSum += abs( piOrg[6] - piCur[6] - iDeltaC );
+    uiSum += abs( piOrg[7] - piCur[7] - iDeltaC );
+    uiSum += abs( piOrg[8] - piCur[8] - iDeltaC );
+    uiSum += abs( piOrg[9] - piCur[9] - iDeltaC );
+    uiSum += abs( piOrg[10] - piCur[10] - iDeltaC );
+    uiSum += abs( piOrg[11] - piCur[11] - iDeltaC );
+    uiSum += abs( piOrg[12] - piCur[12] - iDeltaC );
+    uiSum += abs( piOrg[13] - piCur[13] - iDeltaC );
+    uiSum += abs( piOrg[14] - piCur[14] - iDeltaC );
+    uiSum += abs( piOrg[15] - piCur[15] - iDeltaC );
+
+    piOrg += iStrideOrg;
+    piCur += iStrideCur;
+  }
+
+  uiSum <<= iSubShift;
+  return ( uiSum >> DISTORTION_PRECISION_ADJUSTMENT( pcDtParam->bitDepth - 8 ) );
+}
+
+#if AMP_SAD
+UInt TComRdCost::xGetSAD12ic( DistParam* pcDtParam )
+{
+  if ( pcDtParam->bApplyWeight )
+  {
+    return xGetSADw( pcDtParam );
+  }
+  Pel* piOrg   = pcDtParam->pOrg;
+  Pel* piCur   = pcDtParam->pCur;
+  Int  iRows   = pcDtParam->iRows;
+  Int  iSubShift  = pcDtParam->iSubShift;
+  Int  iSubStep   = ( 1 << iSubShift );
+  Int  iStrideCur = pcDtParam->iStrideCur*iSubStep;
+  Int  iStrideOrg = pcDtParam->iStrideOrg*iSubStep;
+
+  UInt uiSum = 0;
+
+  Int  iOrigAvg = 0, iCurAvg = 0, uiRowCnt = 0;
+  Int  iDeltaC;
+
+  for( ; iRows != 0; iRows-=iSubStep )
+  {
+    iOrigAvg += piOrg[0];
+    iOrigAvg += piOrg[1];
+    iOrigAvg += piOrg[2];
+    iOrigAvg += piOrg[3];
+    iOrigAvg += piOrg[4];
+    iOrigAvg += piOrg[5];
+    iOrigAvg += piOrg[6];
+    iOrigAvg += piOrg[7];
+    iOrigAvg += piOrg[8];
+    iOrigAvg += piOrg[9];
+    iOrigAvg += piOrg[10];
+    iOrigAvg += piOrg[11];
+
+    iCurAvg  += piCur[0];
+    iCurAvg  += piCur[1];
+    iCurAvg  += piCur[2];
+    iCurAvg  += piCur[3];
+    iCurAvg  += piCur[4];
+    iCurAvg  += piCur[5];
+    iCurAvg  += piCur[6];
+    iCurAvg  += piCur[7];
+    iCurAvg  += piCur[8];
+    iCurAvg  += piCur[9];
+    iCurAvg  += piCur[10];
+    iCurAvg  += piCur[11];
+
+    piOrg += iStrideOrg;
+    piCur += iStrideCur;
+    uiRowCnt++;
+  }
+
+  piOrg   = pcDtParam->pOrg;
+  piCur   = pcDtParam->pCur;
+  iRows   = pcDtParam->iRows;
+
+  iDeltaC = uiRowCnt ? ((iOrigAvg - iCurAvg)/uiRowCnt/12) : 0;
+
+  for( ; iRows != 0; iRows-=iSubStep )
+  {
+    uiSum += abs( piOrg[0] - piCur[0] - iDeltaC );
+    uiSum += abs( piOrg[1] - piCur[1] - iDeltaC );
+    uiSum += abs( piOrg[2] - piCur[2] - iDeltaC );
+    uiSum += abs( piOrg[3] - piCur[3] - iDeltaC );
+    uiSum += abs( piOrg[4] - piCur[4] - iDeltaC );
+    uiSum += abs( piOrg[5] - piCur[5] - iDeltaC );
+    uiSum += abs( piOrg[6] - piCur[6] - iDeltaC );
+    uiSum += abs( piOrg[7] - piCur[7] - iDeltaC );
+    uiSum += abs( piOrg[8] - piCur[8] - iDeltaC );
+    uiSum += abs( piOrg[9] - piCur[9] - iDeltaC );
+    uiSum += abs( piOrg[10] - piCur[10] - iDeltaC );
+    uiSum += abs( piOrg[11] - piCur[11] - iDeltaC );
+
+    piOrg += iStrideOrg;
+    piCur += iStrideCur;
+  }
+
+  uiSum <<= iSubShift;
+  return ( uiSum >> DISTORTION_PRECISION_ADJUSTMENT( pcDtParam->bitDepth - 8 ) );
+}
+#endif
+
+UInt TComRdCost::xGetSAD16Nic( DistParam* pcDtParam )
+{
+  Pel* piOrg   = pcDtParam->pOrg;
+  Pel* piCur   = pcDtParam->pCur;
+  Int  iRows   = pcDtParam->iRows;
+  Int  iCols   = pcDtParam->iCols;
+  Int  iSubShift  = pcDtParam->iSubShift;
+  Int  iSubStep   = ( 1 << iSubShift );
+  Int  iStrideCur = pcDtParam->iStrideCur*iSubStep;
+  Int  iStrideOrg = pcDtParam->iStrideOrg*iSubStep;
+
+  UInt uiSum = 0;
+
+  Int iOrigAvg = 0, iCurAvg = 0, uiRowCnt = 0, uiColCnt = (iCols-1)/16 + 1;
+  Int  iDeltaC;
+
+  for( ; iRows != 0; iRows-=iSubStep )
+  {
+    for (Int n = 0; n < iCols; n+=16 )
+    {
+      iOrigAvg += piOrg[n + 0];
+      iOrigAvg += piOrg[n + 1];
+      iOrigAvg += piOrg[n + 2];
+      iOrigAvg += piOrg[n + 3];
+      iOrigAvg += piOrg[n + 4];
+      iOrigAvg += piOrg[n + 5];
+      iOrigAvg += piOrg[n + 6];
+      iOrigAvg += piOrg[n + 7];
+      iOrigAvg += piOrg[n + 8];
+      iOrigAvg += piOrg[n + 9];
+      iOrigAvg += piOrg[n + 10];
+      iOrigAvg += piOrg[n + 11];
+      iOrigAvg += piOrg[n + 12];
+      iOrigAvg += piOrg[n + 13];
+      iOrigAvg += piOrg[n + 14];
+      iOrigAvg += piOrg[n + 15];
+
+      iCurAvg  += piCur[n + 0];
+      iCurAvg  += piCur[n + 1];
+      iCurAvg  += piCur[n + 2];
+      iCurAvg  += piCur[n + 3];
+      iCurAvg  += piCur[n + 4];
+      iCurAvg  += piCur[n + 5];
+      iCurAvg  += piCur[n + 6];
+      iCurAvg  += piCur[n + 7];
+      iCurAvg  += piCur[n + 8];
+      iCurAvg  += piCur[n + 9];
+      iCurAvg  += piCur[n + 10];
+      iCurAvg  += piCur[n + 11];
+      iCurAvg  += piCur[n + 12];
+      iCurAvg  += piCur[n + 13];
+      iCurAvg  += piCur[n + 14];
+      iCurAvg  += piCur[n + 15];
+    }
+    piOrg += iStrideOrg;
+    piCur += iStrideCur;
+    uiRowCnt++;
+  }
+  piOrg   = pcDtParam->pOrg;
+  piCur   = pcDtParam->pCur;
+  iRows   = pcDtParam->iRows;
+
+  iDeltaC = (uiRowCnt && uiColCnt) ? ((iOrigAvg - iCurAvg)/uiRowCnt/uiColCnt/16) : 0;
+
+  for( ; iRows != 0; iRows-=iSubStep )
+  {
+    for (Int n = 0; n < iCols; n+=16 )
+    {
+      uiSum += abs( piOrg[n+ 0] - piCur[n+ 0] - iDeltaC );
+      uiSum += abs( piOrg[n+ 1] - piCur[n+ 1] - iDeltaC );
+      uiSum += abs( piOrg[n+ 2] - piCur[n+ 2] - iDeltaC );
+      uiSum += abs( piOrg[n+ 3] - piCur[n+ 3] - iDeltaC );
+      uiSum += abs( piOrg[n+ 4] - piCur[n+ 4] - iDeltaC );
+      uiSum += abs( piOrg[n+ 5] - piCur[n+ 5] - iDeltaC );
+      uiSum += abs( piOrg[n+ 6] - piCur[n+ 6] - iDeltaC );
+      uiSum += abs( piOrg[n+ 7] - piCur[n+ 7] - iDeltaC );
+      uiSum += abs( piOrg[n+ 8] - piCur[n+ 8] - iDeltaC );
+      uiSum += abs( piOrg[n+ 9] - piCur[n+ 9] - iDeltaC );
+      uiSum += abs( piOrg[n+10] - piCur[n+10] - iDeltaC );
+      uiSum += abs( piOrg[n+11] - piCur[n+11] - iDeltaC );
+      uiSum += abs( piOrg[n+12] - piCur[n+12] - iDeltaC );
+      uiSum += abs( piOrg[n+13] - piCur[n+13] - iDeltaC );
+      uiSum += abs( piOrg[n+14] - piCur[n+14] - iDeltaC );
+      uiSum += abs( piOrg[n+15] - piCur[n+15] - iDeltaC );
+    }
+    piOrg += iStrideOrg;
+    piCur += iStrideCur;
+  }
+
+  uiSum <<= iSubShift;
+  return ( uiSum >> DISTORTION_PRECISION_ADJUSTMENT( pcDtParam->bitDepth - 8 ) );
+}
+
+UInt TComRdCost::xGetSAD32ic( DistParam* pcDtParam )
+{
+  if ( pcDtParam->bApplyWeight )
+  {
+    return xGetSADw( pcDtParam );
+  }
+  Pel* piOrg   = pcDtParam->pOrg;
+  Pel* piCur   = pcDtParam->pCur;
+  Int  iRows   = pcDtParam->iRows;
+  Int  iSubShift  = pcDtParam->iSubShift;
+  Int  iSubStep   = ( 1 << iSubShift );
+  Int  iStrideCur = pcDtParam->iStrideCur*iSubStep;
+  Int  iStrideOrg = pcDtParam->iStrideOrg*iSubStep;
+
+  UInt uiSum = 0;
+
+  Int  iOrigAvg = 0, iCurAvg = 0, uiRowCnt = 0;
+  Int  iDeltaC;
+
+  for( ; iRows != 0; iRows-=iSubStep )
+  {
+    iOrigAvg += piOrg[0];
+    iOrigAvg += piOrg[1];
+    iOrigAvg += piOrg[2];
+    iOrigAvg += piOrg[3];
+    iOrigAvg += piOrg[4];
+    iOrigAvg += piOrg[5];
+    iOrigAvg += piOrg[6];
+    iOrigAvg += piOrg[7];
+    iOrigAvg += piOrg[8];
+    iOrigAvg += piOrg[9];
+    iOrigAvg += piOrg[10];
+    iOrigAvg += piOrg[11];
+    iOrigAvg += piOrg[12];
+    iOrigAvg += piOrg[13];
+    iOrigAvg += piOrg[14];
+    iOrigAvg += piOrg[15];
+    iOrigAvg += piOrg[16];
+    iOrigAvg += piOrg[17];
+    iOrigAvg += piOrg[18];
+    iOrigAvg += piOrg[19];
+    iOrigAvg += piOrg[20];
+    iOrigAvg += piOrg[21];
+    iOrigAvg += piOrg[22];
+    iOrigAvg += piOrg[23];
+    iOrigAvg += piOrg[24];
+    iOrigAvg += piOrg[25];
+    iOrigAvg += piOrg[26];
+    iOrigAvg += piOrg[27];
+    iOrigAvg += piOrg[28];
+    iOrigAvg += piOrg[29];
+    iOrigAvg += piOrg[30];
+    iOrigAvg += piOrg[31];
+
+    iCurAvg  += piCur[0];
+    iCurAvg  += piCur[1];
+    iCurAvg  += piCur[2];
+    iCurAvg  += piCur[3];
+    iCurAvg  += piCur[4];
+    iCurAvg  += piCur[5];
+    iCurAvg  += piCur[6];
+    iCurAvg  += piCur[7];
+    iCurAvg  += piCur[8];
+    iCurAvg  += piCur[9];
+    iCurAvg  += piCur[10];
+    iCurAvg  += piCur[11];
+    iCurAvg  += piCur[12];
+    iCurAvg  += piCur[13];
+    iCurAvg  += piCur[14];
+    iCurAvg  += piCur[15];
+    iCurAvg  += piCur[16];
+    iCurAvg  += piCur[17];
+    iCurAvg  += piCur[18];
+    iCurAvg  += piCur[19];
+    iCurAvg  += piCur[20];
+    iCurAvg  += piCur[21];
+    iCurAvg  += piCur[22];
+    iCurAvg  += piCur[23];
+    iCurAvg  += piCur[24];
+    iCurAvg  += piCur[25];
+    iCurAvg  += piCur[26];
+    iCurAvg  += piCur[27];
+    iCurAvg  += piCur[28];
+    iCurAvg  += piCur[29];
+    iCurAvg  += piCur[30];
+    iCurAvg  += piCur[31];
+
+    piOrg += iStrideOrg;
+    piCur += iStrideCur;
+    uiRowCnt++;
+  }
+
+  piOrg   = pcDtParam->pOrg;
+  piCur   = pcDtParam->pCur;
+  iRows   = pcDtParam->iRows;
+
+  iDeltaC = uiRowCnt ? ((iOrigAvg - iCurAvg)/uiRowCnt/32) : 0;
+
+  for( ; iRows != 0; iRows-=iSubStep )
+  {
+    uiSum += abs( piOrg[0] - piCur[0] - iDeltaC );
+    uiSum += abs( piOrg[1] - piCur[1] - iDeltaC );
+    uiSum += abs( piOrg[2] - piCur[2] - iDeltaC );
+    uiSum += abs( piOrg[3] - piCur[3] - iDeltaC );
+    uiSum += abs( piOrg[4] - piCur[4] - iDeltaC );
+    uiSum += abs( piOrg[5] - piCur[5] - iDeltaC );
+    uiSum += abs( piOrg[6] - piCur[6] - iDeltaC );
+    uiSum += abs( piOrg[7] - piCur[7] - iDeltaC );
+    uiSum += abs( piOrg[8] - piCur[8] - iDeltaC );
+    uiSum += abs( piOrg[9] - piCur[9] - iDeltaC );
+    uiSum += abs( piOrg[10] - piCur[10] - iDeltaC );
+    uiSum += abs( piOrg[11] - piCur[11] - iDeltaC );
+    uiSum += abs( piOrg[12] - piCur[12] - iDeltaC );
+    uiSum += abs( piOrg[13] - piCur[13] - iDeltaC );
+    uiSum += abs( piOrg[14] - piCur[14] - iDeltaC );
+    uiSum += abs( piOrg[15] - piCur[15] - iDeltaC );
+    uiSum += abs( piOrg[16] - piCur[16] - iDeltaC );
+    uiSum += abs( piOrg[17] - piCur[17] - iDeltaC );
+    uiSum += abs( piOrg[18] - piCur[18] - iDeltaC );
+    uiSum += abs( piOrg[19] - piCur[19] - iDeltaC );
+    uiSum += abs( piOrg[20] - piCur[20] - iDeltaC );
+    uiSum += abs( piOrg[21] - piCur[21] - iDeltaC );
+    uiSum += abs( piOrg[22] - piCur[22] - iDeltaC );
+    uiSum += abs( piOrg[23] - piCur[23] - iDeltaC );
+    uiSum += abs( piOrg[24] - piCur[24] - iDeltaC );
+    uiSum += abs( piOrg[25] - piCur[25] - iDeltaC );
+    uiSum += abs( piOrg[26] - piCur[26] - iDeltaC );
+    uiSum += abs( piOrg[27] - piCur[27] - iDeltaC );
+    uiSum += abs( piOrg[28] - piCur[28] - iDeltaC );
+    uiSum += abs( piOrg[29] - piCur[29] - iDeltaC );
+    uiSum += abs( piOrg[30] - piCur[30] - iDeltaC );
+    uiSum += abs( piOrg[31] - piCur[31] - iDeltaC );
+
+    piOrg += iStrideOrg;
+    piCur += iStrideCur;
+  }
+
+  uiSum <<= iSubShift;
+  return ( uiSum >> DISTORTION_PRECISION_ADJUSTMENT( pcDtParam->bitDepth - 8 ) );
+}
+
+#if AMP_SAD
+UInt TComRdCost::xGetSAD24ic( DistParam* pcDtParam )
+{
+  if ( pcDtParam->bApplyWeight )
+  {
+    return xGetSADw( pcDtParam );
+  }
+  Pel* piOrg   = pcDtParam->pOrg;
+  Pel* piCur   = pcDtParam->pCur;
+  Int  iRows   = pcDtParam->iRows;
+  Int  iSubShift  = pcDtParam->iSubShift;
+  Int  iSubStep   = ( 1 << iSubShift );
+  Int  iStrideCur = pcDtParam->iStrideCur*iSubStep;
+  Int  iStrideOrg = pcDtParam->iStrideOrg*iSubStep;
+
+  UInt uiSum = 0;
+
+  Int  iOrigAvg = 0, iCurAvg = 0, uiRowCnt = 0;
+  Int  iDeltaC;
+
+  for( ; iRows != 0; iRows-=iSubStep )
+  {
+    iOrigAvg += piOrg[0];
+    iOrigAvg += piOrg[1];
+    iOrigAvg += piOrg[2];
+    iOrigAvg += piOrg[3];
+    iOrigAvg += piOrg[4];
+    iOrigAvg += piOrg[5];
+    iOrigAvg += piOrg[6];
+    iOrigAvg += piOrg[7];
+    iOrigAvg += piOrg[8];
+    iOrigAvg += piOrg[9];
+    iOrigAvg += piOrg[10];
+    iOrigAvg += piOrg[11];
+    iOrigAvg += piOrg[12];
+    iOrigAvg += piOrg[13];
+    iOrigAvg += piOrg[14];
+    iOrigAvg += piOrg[15];
+    iOrigAvg += piOrg[16];
+    iOrigAvg += piOrg[17];
+    iOrigAvg += piOrg[18];
+    iOrigAvg += piOrg[19];
+    iOrigAvg += piOrg[20];
+    iOrigAvg += piOrg[21];
+    iOrigAvg += piOrg[22];
+    iOrigAvg += piOrg[23];
+
+    iCurAvg  += piCur[0];
+    iCurAvg  += piCur[1];
+    iCurAvg  += piCur[2];
+    iCurAvg  += piCur[3];
+    iCurAvg  += piCur[4];
+    iCurAvg  += piCur[5];
+    iCurAvg  += piCur[6];
+    iCurAvg  += piCur[7];
+    iCurAvg  += piCur[8];
+    iCurAvg  += piCur[9];
+    iCurAvg  += piCur[10];
+    iCurAvg  += piCur[11];
+    iCurAvg  += piCur[12];
+    iCurAvg  += piCur[13];
+    iCurAvg  += piCur[14];
+    iCurAvg  += piCur[15];
+    iCurAvg  += piCur[16];
+    iCurAvg  += piCur[17];
+    iCurAvg  += piCur[18];
+    iCurAvg  += piCur[19];
+    iCurAvg  += piCur[20];
+    iCurAvg  += piCur[21];
+    iCurAvg  += piCur[22];
+    iCurAvg  += piCur[23];
+
+    piOrg += iStrideOrg;
+    piCur += iStrideCur;
+    uiRowCnt++;
+  }
+
+  piOrg   = pcDtParam->pOrg;
+  piCur   = pcDtParam->pCur;
+  iRows   = pcDtParam->iRows;
+
+  iDeltaC = uiRowCnt ? ((iOrigAvg - iCurAvg)/uiRowCnt/24) : 0;
+
+  for( ; iRows != 0; iRows-=iSubStep )
+  {
+    uiSum += abs( piOrg[0] - piCur[0] - iDeltaC );
+    uiSum += abs( piOrg[1] - piCur[1] - iDeltaC );
+    uiSum += abs( piOrg[2] - piCur[2] - iDeltaC );
+    uiSum += abs( piOrg[3] - piCur[3] - iDeltaC );
+    uiSum += abs( piOrg[4] - piCur[4] - iDeltaC );
+    uiSum += abs( piOrg[5] - piCur[5] - iDeltaC );
+    uiSum += abs( piOrg[6] - piCur[6] - iDeltaC );
+    uiSum += abs( piOrg[7] - piCur[7] - iDeltaC );
+    uiSum += abs( piOrg[8] - piCur[8] - iDeltaC );
+    uiSum += abs( piOrg[9] - piCur[9] - iDeltaC );
+    uiSum += abs( piOrg[10] - piCur[10] - iDeltaC );
+    uiSum += abs( piOrg[11] - piCur[11] - iDeltaC );
+    uiSum += abs( piOrg[12] - piCur[12] - iDeltaC );
+    uiSum += abs( piOrg[13] - piCur[13] - iDeltaC );
+    uiSum += abs( piOrg[14] - piCur[14] - iDeltaC );
+    uiSum += abs( piOrg[15] - piCur[15] - iDeltaC );
+    uiSum += abs( piOrg[16] - piCur[16] - iDeltaC );
+    uiSum += abs( piOrg[17] - piCur[17] - iDeltaC );
+    uiSum += abs( piOrg[18] - piCur[18] - iDeltaC );
+    uiSum += abs( piOrg[19] - piCur[19] - iDeltaC );
+    uiSum += abs( piOrg[20] - piCur[20] - iDeltaC );
+    uiSum += abs( piOrg[21] - piCur[21] - iDeltaC );
+    uiSum += abs( piOrg[22] - piCur[22] - iDeltaC );
+    uiSum += abs( piOrg[23] - piCur[23] - iDeltaC );
+
+    piOrg += iStrideOrg;
+    piCur += iStrideCur;
+  }
+
+  uiSum <<= iSubShift;
+  return ( uiSum >> DISTORTION_PRECISION_ADJUSTMENT( pcDtParam->bitDepth - 8 ) );
+}
+#endif
+
+UInt TComRdCost::xGetSAD64ic( DistParam* pcDtParam )
+{
+  if ( pcDtParam->bApplyWeight )
+  {
+    return xGetSADw( pcDtParam );
+  }
+  Pel* piOrg   = pcDtParam->pOrg;
+  Pel* piCur   = pcDtParam->pCur;
+  Int  iRows   = pcDtParam->iRows;
+  Int  iSubShift  = pcDtParam->iSubShift;
+  Int  iSubStep   = ( 1 << iSubShift );
+  Int  iStrideCur = pcDtParam->iStrideCur*iSubStep;
+  Int  iStrideOrg = pcDtParam->iStrideOrg*iSubStep;
+
+  UInt uiSum = 0;
+
+  Int  iOrigAvg = 0, iCurAvg = 0, uiRowCnt = 0;
+  Int  iDeltaC;
+
+  for( ; iRows != 0; iRows-=iSubStep )
+  {
+    iOrigAvg += piOrg[0] ;
+    iOrigAvg += piOrg[1] ;
+    iOrigAvg += piOrg[2] ;
+    iOrigAvg += piOrg[3] ;
+    iOrigAvg += piOrg[4] ;
+    iOrigAvg += piOrg[5] ;
+    iOrigAvg += piOrg[6] ;
+    iOrigAvg += piOrg[7] ;
+    iOrigAvg += piOrg[8] ;
+    iOrigAvg += piOrg[9] ;
+    iOrigAvg += piOrg[10] ;
+    iOrigAvg += piOrg[11] ;
+    iOrigAvg += piOrg[12] ;
+    iOrigAvg += piOrg[13] ;
+    iOrigAvg += piOrg[14] ;
+    iOrigAvg += piOrg[15] ;
+    iOrigAvg += piOrg[16] ;
+    iOrigAvg += piOrg[17] ;
+    iOrigAvg += piOrg[18] ;
+    iOrigAvg += piOrg[19] ;
+    iOrigAvg += piOrg[20] ;
+    iOrigAvg += piOrg[21] ;
+    iOrigAvg += piOrg[22] ;
+    iOrigAvg += piOrg[23] ;
+    iOrigAvg += piOrg[24] ;
+    iOrigAvg += piOrg[25] ;
+    iOrigAvg += piOrg[26] ;
+    iOrigAvg += piOrg[27] ;
+    iOrigAvg += piOrg[28] ;
+    iOrigAvg += piOrg[29] ;
+    iOrigAvg += piOrg[30] ;
+    iOrigAvg += piOrg[31] ;
+    iOrigAvg += piOrg[32] ;
+    iOrigAvg += piOrg[33] ;
+    iOrigAvg += piOrg[34] ;
+    iOrigAvg += piOrg[35] ;
+    iOrigAvg += piOrg[36] ;
+    iOrigAvg += piOrg[37] ;
+    iOrigAvg += piOrg[38] ;
+    iOrigAvg += piOrg[39] ;
+    iOrigAvg += piOrg[40] ;
+    iOrigAvg += piOrg[41] ;
+    iOrigAvg += piOrg[42] ;
+    iOrigAvg += piOrg[43] ;
+    iOrigAvg += piOrg[44] ;
+    iOrigAvg += piOrg[45] ;
+    iOrigAvg += piOrg[46] ;
+    iOrigAvg += piOrg[47] ;
+    iOrigAvg += piOrg[48] ;
+    iOrigAvg += piOrg[49] ;
+    iOrigAvg += piOrg[50] ;
+    iOrigAvg += piOrg[51] ;
+    iOrigAvg += piOrg[52] ;
+    iOrigAvg += piOrg[53] ;
+    iOrigAvg += piOrg[54] ;
+    iOrigAvg += piOrg[55] ;
+    iOrigAvg += piOrg[56] ;
+    iOrigAvg += piOrg[57] ;
+    iOrigAvg += piOrg[58] ;
+    iOrigAvg += piOrg[59] ;
+    iOrigAvg += piOrg[60] ;
+    iOrigAvg += piOrg[61] ;
+    iOrigAvg += piOrg[62] ;
+    iOrigAvg += piOrg[63] ;
+
+    iCurAvg += piCur[0] ;
+    iCurAvg += piCur[1] ;
+    iCurAvg += piCur[2] ;
+    iCurAvg += piCur[3] ;
+    iCurAvg += piCur[4] ;
+    iCurAvg += piCur[5] ;
+    iCurAvg += piCur[6] ;
+    iCurAvg += piCur[7] ;
+    iCurAvg += piCur[8] ;
+    iCurAvg += piCur[9] ;
+    iCurAvg += piCur[10] ;
+    iCurAvg += piCur[11] ;
+    iCurAvg += piCur[12] ;
+    iCurAvg += piCur[13] ;
+    iCurAvg += piCur[14] ;
+    iCurAvg += piCur[15] ;
+    iCurAvg += piCur[16] ;
+    iCurAvg += piCur[17] ;
+    iCurAvg += piCur[18] ;
+    iCurAvg += piCur[19] ;
+    iCurAvg += piCur[20] ;
+    iCurAvg += piCur[21] ;
+    iCurAvg += piCur[22] ;
+    iCurAvg += piCur[23] ;
+    iCurAvg += piCur[24] ;
+    iCurAvg += piCur[25] ;
+    iCurAvg += piCur[26] ;
+    iCurAvg += piCur[27] ;
+    iCurAvg += piCur[28] ;
+    iCurAvg += piCur[29] ;
+    iCurAvg += piCur[30] ;
+    iCurAvg += piCur[31] ;
+    iCurAvg += piCur[32] ;
+    iCurAvg += piCur[33] ;
+    iCurAvg += piCur[34] ;
+    iCurAvg += piCur[35] ;
+    iCurAvg += piCur[36] ;
+    iCurAvg += piCur[37] ;
+    iCurAvg += piCur[38] ;
+    iCurAvg += piCur[39] ;
+    iCurAvg += piCur[40] ;
+    iCurAvg += piCur[41] ;
+    iCurAvg += piCur[42] ;
+    iCurAvg += piCur[43] ;
+    iCurAvg += piCur[44] ;
+    iCurAvg += piCur[45] ;
+    iCurAvg += piCur[46] ;
+    iCurAvg += piCur[47] ;
+    iCurAvg += piCur[48] ;
+    iCurAvg += piCur[49] ;
+    iCurAvg += piCur[50] ;
+    iCurAvg += piCur[51] ;
+    iCurAvg += piCur[52] ;
+    iCurAvg += piCur[53] ;
+    iCurAvg += piCur[54] ;
+    iCurAvg += piCur[55] ;
+    iCurAvg += piCur[56] ;
+    iCurAvg += piCur[57] ;
+    iCurAvg += piCur[58] ;
+    iCurAvg += piCur[59] ;
+    iCurAvg += piCur[60] ;
+    iCurAvg += piCur[61] ;
+    iCurAvg += piCur[62] ;
+    iCurAvg += piCur[63] ;
+
+    piOrg += iStrideOrg;
+    piCur += iStrideCur;
+    uiRowCnt++;
+  }
+
+  piOrg   = pcDtParam->pOrg;
+  piCur   = pcDtParam->pCur;
+  iRows   = pcDtParam->iRows;
+
+  iDeltaC = uiRowCnt ? ((iOrigAvg - iCurAvg)/uiRowCnt/64) : 0;
+
+  for( ; iRows != 0; iRows-=iSubStep )
+  {
+    uiSum += abs( piOrg[0] - piCur[0] - iDeltaC );
+    uiSum += abs( piOrg[1] - piCur[1] - iDeltaC );
+    uiSum += abs( piOrg[2] - piCur[2] - iDeltaC );
+    uiSum += abs( piOrg[3] - piCur[3] - iDeltaC );
+    uiSum += abs( piOrg[4] - piCur[4] - iDeltaC );
+    uiSum += abs( piOrg[5] - piCur[5] - iDeltaC );
+    uiSum += abs( piOrg[6] - piCur[6] - iDeltaC );
+    uiSum += abs( piOrg[7] - piCur[7] - iDeltaC );
+    uiSum += abs( piOrg[8] - piCur[8] - iDeltaC );
+    uiSum += abs( piOrg[9] - piCur[9] - iDeltaC );
+    uiSum += abs( piOrg[10] - piCur[10] - iDeltaC );
+    uiSum += abs( piOrg[11] - piCur[11] - iDeltaC );
+    uiSum += abs( piOrg[12] - piCur[12] - iDeltaC );
+    uiSum += abs( piOrg[13] - piCur[13] - iDeltaC );
+    uiSum += abs( piOrg[14] - piCur[14] - iDeltaC );
+    uiSum += abs( piOrg[15] - piCur[15] - iDeltaC );
+    uiSum += abs( piOrg[16] - piCur[16] - iDeltaC );
+    uiSum += abs( piOrg[17] - piCur[17] - iDeltaC );
+    uiSum += abs( piOrg[18] - piCur[18] - iDeltaC );
+    uiSum += abs( piOrg[19] - piCur[19] - iDeltaC );
+    uiSum += abs( piOrg[20] - piCur[20] - iDeltaC );
+    uiSum += abs( piOrg[21] - piCur[21] - iDeltaC );
+    uiSum += abs( piOrg[22] - piCur[22] - iDeltaC );
+    uiSum += abs( piOrg[23] - piCur[23] - iDeltaC );
+    uiSum += abs( piOrg[24] - piCur[24] - iDeltaC );
+    uiSum += abs( piOrg[25] - piCur[25] - iDeltaC );
+    uiSum += abs( piOrg[26] - piCur[26] - iDeltaC );
+    uiSum += abs( piOrg[27] - piCur[27] - iDeltaC );
+    uiSum += abs( piOrg[28] - piCur[28] - iDeltaC );
+    uiSum += abs( piOrg[29] - piCur[29] - iDeltaC );
+    uiSum += abs( piOrg[30] - piCur[30] - iDeltaC );
+    uiSum += abs( piOrg[31] - piCur[31] - iDeltaC );
+    uiSum += abs( piOrg[32] - piCur[32] - iDeltaC );
+    uiSum += abs( piOrg[33] - piCur[33] - iDeltaC );
+    uiSum += abs( piOrg[34] - piCur[34] - iDeltaC );
+    uiSum += abs( piOrg[35] - piCur[35] - iDeltaC );
+    uiSum += abs( piOrg[36] - piCur[36] - iDeltaC );
+    uiSum += abs( piOrg[37] - piCur[37] - iDeltaC );
+    uiSum += abs( piOrg[38] - piCur[38] - iDeltaC );
+    uiSum += abs( piOrg[39] - piCur[39] - iDeltaC );
+    uiSum += abs( piOrg[40] - piCur[40] - iDeltaC );
+    uiSum += abs( piOrg[41] - piCur[41] - iDeltaC );
+    uiSum += abs( piOrg[42] - piCur[42] - iDeltaC );
+    uiSum += abs( piOrg[43] - piCur[43] - iDeltaC );
+    uiSum += abs( piOrg[44] - piCur[44] - iDeltaC );
+    uiSum += abs( piOrg[45] - piCur[45] - iDeltaC );
+    uiSum += abs( piOrg[46] - piCur[46] - iDeltaC );
+    uiSum += abs( piOrg[47] - piCur[47] - iDeltaC );
+    uiSum += abs( piOrg[48] - piCur[48] - iDeltaC );
+    uiSum += abs( piOrg[49] - piCur[49] - iDeltaC );
+    uiSum += abs( piOrg[50] - piCur[50] - iDeltaC );
+    uiSum += abs( piOrg[51] - piCur[51] - iDeltaC );
+    uiSum += abs( piOrg[52] - piCur[52] - iDeltaC );
+    uiSum += abs( piOrg[53] - piCur[53] - iDeltaC );
+    uiSum += abs( piOrg[54] - piCur[54] - iDeltaC );
+    uiSum += abs( piOrg[55] - piCur[55] - iDeltaC );
+    uiSum += abs( piOrg[56] - piCur[56] - iDeltaC );
+    uiSum += abs( piOrg[57] - piCur[57] - iDeltaC );
+    uiSum += abs( piOrg[58] - piCur[58] - iDeltaC );
+    uiSum += abs( piOrg[59] - piCur[59] - iDeltaC );
+    uiSum += abs( piOrg[60] - piCur[60] - iDeltaC );
+    uiSum += abs( piOrg[61] - piCur[61] - iDeltaC );
+    uiSum += abs( piOrg[62] - piCur[62] - iDeltaC );
+    uiSum += abs( piOrg[63] - piCur[63] - iDeltaC );
+
+    piOrg += iStrideOrg;
+    piCur += iStrideCur;
+  }
+
+  uiSum <<= iSubShift;
+  return ( uiSum >> DISTORTION_PRECISION_ADJUSTMENT( pcDtParam->bitDepth - 8 ) );
+}
+
+#if AMP_SAD
+UInt TComRdCost::xGetSAD48ic( DistParam* pcDtParam )
+{
+  if ( pcDtParam->bApplyWeight )
+  {
+    return xGetSADw( pcDtParam );
+  }
+
+  Pel* piOrg   = pcDtParam->pOrg;
+  Pel* piCur   = pcDtParam->pCur;
+  Int  iRows   = pcDtParam->iRows;
+  Int  iSubShift  = pcDtParam->iSubShift;
+  Int  iSubStep   = ( 1 << iSubShift );
+  Int  iStrideCur = pcDtParam->iStrideCur*iSubStep;
+  Int  iStrideOrg = pcDtParam->iStrideOrg*iSubStep;
+
+  UInt uiSum = 0;
+
+  Int  iOrigAvg = 0, iCurAvg = 0, uiRowCnt = 0;
+  Int  iDeltaC;
+
+  for( ; iRows != 0; iRows-=iSubStep )
+  {
+    iOrigAvg += piOrg[0] ;
+    iOrigAvg += piOrg[1] ;
+    iOrigAvg += piOrg[2] ;
+    iOrigAvg += piOrg[3] ;
+    iOrigAvg += piOrg[4] ;
+    iOrigAvg += piOrg[5] ;
+    iOrigAvg += piOrg[6] ;
+    iOrigAvg += piOrg[7] ;
+    iOrigAvg += piOrg[8] ;
+    iOrigAvg += piOrg[9] ;
+    iOrigAvg += piOrg[10] ;
+    iOrigAvg += piOrg[11] ;
+    iOrigAvg += piOrg[12] ;
+    iOrigAvg += piOrg[13] ;
+    iOrigAvg += piOrg[14] ;
+    iOrigAvg += piOrg[15] ;
+    iOrigAvg += piOrg[16] ;
+    iOrigAvg += piOrg[17] ;
+    iOrigAvg += piOrg[18] ;
+    iOrigAvg += piOrg[19] ;
+    iOrigAvg += piOrg[20] ;
+    iOrigAvg += piOrg[21] ;
+    iOrigAvg += piOrg[22] ;
+    iOrigAvg += piOrg[23] ;
+    iOrigAvg += piOrg[24] ;
+    iOrigAvg += piOrg[25] ;
+    iOrigAvg += piOrg[26] ;
+    iOrigAvg += piOrg[27] ;
+    iOrigAvg += piOrg[28] ;
+    iOrigAvg += piOrg[29] ;
+    iOrigAvg += piOrg[30] ;
+    iOrigAvg += piOrg[31] ;
+    iOrigAvg += piOrg[32] ;
+    iOrigAvg += piOrg[33] ;
+    iOrigAvg += piOrg[34] ;
+    iOrigAvg += piOrg[35] ;
+    iOrigAvg += piOrg[36] ;
+    iOrigAvg += piOrg[37] ;
+    iOrigAvg += piOrg[38] ;
+    iOrigAvg += piOrg[39] ;
+    iOrigAvg += piOrg[40] ;
+    iOrigAvg += piOrg[41] ;
+    iOrigAvg += piOrg[42] ;
+    iOrigAvg += piOrg[43] ;
+    iOrigAvg += piOrg[44] ;
+    iOrigAvg += piOrg[45] ;
+    iOrigAvg += piOrg[46] ;
+    iOrigAvg += piOrg[47] ;
+
+    iCurAvg += piCur[0] ;
+    iCurAvg += piCur[1] ;
+    iCurAvg += piCur[2] ;
+    iCurAvg += piCur[3] ;
+    iCurAvg += piCur[4] ;
+    iCurAvg += piCur[5] ;
+    iCurAvg += piCur[6] ;
+    iCurAvg += piCur[7] ;
+    iCurAvg += piCur[8] ;
+    iCurAvg += piCur[9] ;
+    iCurAvg += piCur[10] ;
+    iCurAvg += piCur[11] ;
+    iCurAvg += piCur[12] ;
+    iCurAvg += piCur[13] ;
+    iCurAvg += piCur[14] ;
+    iCurAvg += piCur[15] ;
+    iCurAvg += piCur[16] ;
+    iCurAvg += piCur[17] ;
+    iCurAvg += piCur[18] ;
+    iCurAvg += piCur[19] ;
+    iCurAvg += piCur[20] ;
+    iCurAvg += piCur[21] ;
+    iCurAvg += piCur[22] ;
+    iCurAvg += piCur[23] ;
+    iCurAvg += piCur[24] ;
+    iCurAvg += piCur[25] ;
+    iCurAvg += piCur[26] ;
+    iCurAvg += piCur[27] ;
+    iCurAvg += piCur[28] ;
+    iCurAvg += piCur[29] ;
+    iCurAvg += piCur[30] ;
+    iCurAvg += piCur[31] ;
+    iCurAvg += piCur[32] ;
+    iCurAvg += piCur[33] ;
+    iCurAvg += piCur[34] ;
+    iCurAvg += piCur[35] ;
+    iCurAvg += piCur[36] ;
+    iCurAvg += piCur[37] ;
+    iCurAvg += piCur[38] ;
+    iCurAvg += piCur[39] ;
+    iCurAvg += piCur[40] ;
+    iCurAvg += piCur[41] ;
+    iCurAvg += piCur[42] ;
+    iCurAvg += piCur[43] ;
+    iCurAvg += piCur[44] ;
+    iCurAvg += piCur[45] ;
+    iCurAvg += piCur[46] ;
+    iCurAvg += piCur[47] ;
+
+    piOrg += iStrideOrg;
+    piCur += iStrideCur;
+    uiRowCnt++;
+  }
+
+  piOrg   = pcDtParam->pOrg;
+  piCur   = pcDtParam->pCur;
+  iRows   = pcDtParam->iRows;
+
+  iDeltaC = uiRowCnt ? ((iOrigAvg - iCurAvg)/uiRowCnt/48) : 0;
+
+  for( ; iRows != 0; iRows-=iSubStep )
+  {
+    uiSum += abs( piOrg[0] - piCur[0] - iDeltaC );
+    uiSum += abs( piOrg[1] - piCur[1] - iDeltaC );
+    uiSum += abs( piOrg[2] - piCur[2] - iDeltaC );
+    uiSum += abs( piOrg[3] - piCur[3] - iDeltaC );
+    uiSum += abs( piOrg[4] - piCur[4] - iDeltaC );
+    uiSum += abs( piOrg[5] - piCur[5] - iDeltaC );
+    uiSum += abs( piOrg[6] - piCur[6] - iDeltaC );
+    uiSum += abs( piOrg[7] - piCur[7] - iDeltaC );
+    uiSum += abs( piOrg[8] - piCur[8] - iDeltaC );
+    uiSum += abs( piOrg[9] - piCur[9] - iDeltaC );
+    uiSum += abs( piOrg[10] - piCur[10] - iDeltaC );
+    uiSum += abs( piOrg[11] - piCur[11] - iDeltaC );
+    uiSum += abs( piOrg[12] - piCur[12] - iDeltaC );
+    uiSum += abs( piOrg[13] - piCur[13] - iDeltaC );
+    uiSum += abs( piOrg[14] - piCur[14] - iDeltaC );
+    uiSum += abs( piOrg[15] - piCur[15] - iDeltaC );
+    uiSum += abs( piOrg[16] - piCur[16] - iDeltaC );
+    uiSum += abs( piOrg[17] - piCur[17] - iDeltaC );
+    uiSum += abs( piOrg[18] - piCur[18] - iDeltaC );
+    uiSum += abs( piOrg[19] - piCur[19] - iDeltaC );
+    uiSum += abs( piOrg[20] - piCur[20] - iDeltaC );
+    uiSum += abs( piOrg[21] - piCur[21] - iDeltaC );
+    uiSum += abs( piOrg[22] - piCur[22] - iDeltaC );
+    uiSum += abs( piOrg[23] - piCur[23] - iDeltaC );
+    uiSum += abs( piOrg[24] - piCur[24] - iDeltaC );
+    uiSum += abs( piOrg[25] - piCur[25] - iDeltaC );
+    uiSum += abs( piOrg[26] - piCur[26] - iDeltaC );
+    uiSum += abs( piOrg[27] - piCur[27] - iDeltaC );
+    uiSum += abs( piOrg[28] - piCur[28] - iDeltaC );
+    uiSum += abs( piOrg[29] - piCur[29] - iDeltaC );
+    uiSum += abs( piOrg[30] - piCur[30] - iDeltaC );
+    uiSum += abs( piOrg[31] - piCur[31] - iDeltaC );
+    uiSum += abs( piOrg[32] - piCur[32] - iDeltaC );
+    uiSum += abs( piOrg[33] - piCur[33] - iDeltaC );
+    uiSum += abs( piOrg[34] - piCur[34] - iDeltaC );
+    uiSum += abs( piOrg[35] - piCur[35] - iDeltaC );
+    uiSum += abs( piOrg[36] - piCur[36] - iDeltaC );
+    uiSum += abs( piOrg[37] - piCur[37] - iDeltaC );
+    uiSum += abs( piOrg[38] - piCur[38] - iDeltaC );
+    uiSum += abs( piOrg[39] - piCur[39] - iDeltaC );
+    uiSum += abs( piOrg[40] - piCur[40] - iDeltaC );
+    uiSum += abs( piOrg[41] - piCur[41] - iDeltaC );
+    uiSum += abs( piOrg[42] - piCur[42] - iDeltaC );
+    uiSum += abs( piOrg[43] - piCur[43] - iDeltaC );
+    uiSum += abs( piOrg[44] - piCur[44] - iDeltaC );
+    uiSum += abs( piOrg[45] - piCur[45] - iDeltaC );
+    uiSum += abs( piOrg[46] - piCur[46] - iDeltaC );
+    uiSum += abs( piOrg[47] - piCur[47] - iDeltaC );
+
+    piOrg += iStrideOrg;
+    piCur += iStrideCur;
+  }
+
+  uiSum <<= iSubShift;
+  return ( uiSum >> DISTORTION_PRECISION_ADJUSTMENT( pcDtParam->bitDepth - 8 ) );
+}
+#endif
+
+#endif
 // --------------------------------------------------------------------------------------------------------------------
 // SSE
@@ -2206,4 +3423,12 @@
     return xGetHADsw( pcDtParam );
   }
+
+#if H_3D_IC
+  if( pcDtParam->bUseIC )
+  {
+    return xGetHADsic( pcDtParam );
+  }
+#endif
+
   Pel* piOrg   = pcDtParam->pOrg;
   Pel* piCur   = pcDtParam->pCur;
@@ -2302,4 +3527,151 @@
   return uiSum >> DISTORTION_PRECISION_ADJUSTMENT(pcDtParam->bitDepth-8);
 }
+
+#if H_3D_IC
+UInt TComRdCost::xGetHADsic( DistParam* pcDtParam )
+{
+  if ( pcDtParam->bApplyWeight )
+  {
+    return xGetHADsw( pcDtParam );
+  }
+  Pel* piOrg   = pcDtParam->pOrg;
+  Pel* piCur   = pcDtParam->pCur;
+  Int  iRows   = pcDtParam->iRows;
+  Int  iCols   = pcDtParam->iCols;
+  Int  iStrideCur = pcDtParam->iStrideCur;
+  Int  iStrideOrg = pcDtParam->iStrideOrg;
+  Int  iStep  = pcDtParam->iStep;
+
+  Int  x, y;
+
+  UInt uiSum = 0;
+
+  Int  iOrigAvg = 0, iCurAvg = 0;
+  Int  iDeltaC;
+
+  for ( y=0; y<iRows; y++ )
+  {
+    for ( x=0; x<iCols; x++ )
+    {        
+      iOrigAvg += piOrg[x];
+      iCurAvg  += piCur[x];
+    }
+    piOrg += iStrideOrg;
+    piCur += iStrideCur;
+  }
+
+  piOrg   = pcDtParam->pOrg;
+  piCur   = pcDtParam->pCur;
+
+  iDeltaC = (iOrigAvg - iCurAvg)/iRows/iCols;
+
+  for ( y=0; y<iRows; y++ )
+  {
+    for ( x=0; x<iCols; x++ )
+    {        
+      piOrg[x] -= iDeltaC;
+    }
+    piOrg += iStrideOrg;
+  }
+
+  piOrg   = pcDtParam->pOrg;
+
+#if NS_HAD
+  if( ( ( iRows % 8 == 0) && (iCols % 8 == 0) && ( iRows == iCols ) ) || ( ( iRows % 8 == 0 ) && (iCols % 8 == 0) && !pcDtParam->bUseNSHAD ) )
+#else
+  if( ( iRows % 8 == 0) && (iCols % 8 == 0) )
+#endif
+  {
+    Int  iOffsetOrg = iStrideOrg<<3;
+    Int  iOffsetCur = iStrideCur<<3;
+    for ( y=0; y<iRows; y+= 8 )
+    {
+      for ( x=0; x<iCols; x+= 8 )
+      {
+        uiSum += xCalcHADs8x8( &piOrg[x], &piCur[x*iStep], iStrideOrg, iStrideCur, iStep );
+      }
+      piOrg += iOffsetOrg;
+      piCur += iOffsetCur;
+    }
+  }
+#if NS_HAD
+  else if ( ( iCols > 8 ) && ( iCols > iRows ) && pcDtParam->bUseNSHAD ) 
+  {
+    Int  iOffsetOrg = iStrideOrg<<2;
+    Int  iOffsetCur = iStrideCur<<2;
+    for ( y=0; y<iRows; y+= 4 )
+    {
+      for ( x=0; x<iCols; x+= 16 )
+      {
+        uiSum += xCalcHADs16x4( &piOrg[x], &piCur[x*iStep], iStrideOrg, iStrideCur, iStep );
+      }
+      piOrg += iOffsetOrg;
+      piCur += iOffsetCur;
+    }
+  }
+  else if ( ( iRows > 8 ) && ( iCols < iRows ) && pcDtParam->bUseNSHAD ) 
+  {
+    Int  iOffsetOrg = iStrideOrg<<4;
+    Int  iOffsetCur = iStrideCur<<4;
+    for ( y=0; y<iRows; y+= 16 )
+    {
+      for ( x=0; x<iCols; x+= 4 )
+      {
+        uiSum += xCalcHADs4x16( &piOrg[x], &piCur[x*iStep], iStrideOrg, iStrideCur, iStep );
+      }
+      piOrg += iOffsetOrg;
+      piCur += iOffsetCur;
+    }
+  }
+#endif
+  else if( ( iRows % 4 == 0) && (iCols % 4 == 0) )
+  {
+    Int  iOffsetOrg = iStrideOrg<<2;
+    Int  iOffsetCur = iStrideCur<<2;
+
+    for ( y=0; y<iRows; y+= 4 )
+    {
+      for ( x=0; x<iCols; x+= 4 )
+      {
+        uiSum += xCalcHADs4x4( &piOrg[x], &piCur[x*iStep], iStrideOrg, iStrideCur, iStep );
+      }
+      piOrg += iOffsetOrg;
+      piCur += iOffsetCur;
+    }
+  }
+  else if( ( iRows % 2 == 0) && (iCols % 2 == 0) )
+  {
+    Int  iOffsetOrg = iStrideOrg<<1;
+    Int  iOffsetCur = iStrideCur<<1;
+    for ( y=0; y<iRows; y+=2 )
+    {
+      for ( x=0; x<iCols; x+=2 )
+      {
+        uiSum += xCalcHADs2x2( &piOrg[x], &piCur[x*iStep], iStrideOrg, iStrideCur, iStep );
+      }
+      piOrg += iOffsetOrg;
+      piCur += iOffsetCur;
+    }
+  }
+  else
+  {
+    assert(false);
+  }
+
+  piOrg   = pcDtParam->pOrg;
+
+  for ( y=0; y<iRows; y++ )
+  {
+    for ( x=0; x<iCols; x++ )
+    {        
+      piOrg[x] += iDeltaC;
+    }
+    piOrg += iStrideOrg;
+  }
+
+  return ( uiSum >> DISTORTION_PRECISION_ADJUSTMENT( pcDtParam->bitDepth - 8 ) );
+}
+#endif
+
 #if H_3D_VSO
 Void TComRdCost::setLambdaVSO( Double dLambdaVSO )
Index: branches/HTM-DEV-0.3-dev2a/source/Lib/TLibCommon/TComRdCost.h
===================================================================
--- branches/HTM-DEV-0.3-dev2a/source/Lib/TLibCommon/TComRdCost.h	(revision 465)
+++ branches/HTM-DEV-0.3-dev2a/source/Lib/TLibCommon/TComRdCost.h	(revision 468)
@@ -91,4 +91,7 @@
   Int   iStrideVir;
 #endif
+#if H_3D_IC
+  Bool  bUseIC;
+#endif
   Int   iRows;
   Int   iCols;
@@ -268,5 +271,13 @@
   static UInt xGetSSE64         ( DistParam* pcDtParam );
   static UInt xGetSSE16N        ( DistParam* pcDtParam );
-  
+#if H_3D_IC
+  static UInt xGetSADic         ( DistParam* pcDtParam );
+  static UInt xGetSAD4ic        ( DistParam* pcDtParam );
+  static UInt xGetSAD8ic        ( DistParam* pcDtParam );
+  static UInt xGetSAD16ic       ( DistParam* pcDtParam );
+  static UInt xGetSAD32ic       ( DistParam* pcDtParam );
+  static UInt xGetSAD64ic       ( DistParam* pcDtParam );
+  static UInt xGetSAD16Nic      ( DistParam* pcDtParam );
+#endif
   static UInt xGetSAD           ( DistParam* pcDtParam );
   static UInt xGetSAD4          ( DistParam* pcDtParam );
@@ -288,4 +299,9 @@
 
 #if AMP_SAD
+#if H_3D_IC
+  static UInt xGetSAD12ic       ( DistParam* pcDtParam );
+  static UInt xGetSAD24ic       ( DistParam* pcDtParam );
+  static UInt xGetSAD48ic       ( DistParam* pcDtParam );
+#endif
   static UInt xGetSAD12         ( DistParam* pcDtParam );
   static UInt xGetSAD24         ( DistParam* pcDtParam );
@@ -294,4 +310,7 @@
 #endif
 
+#if H_3D_IC
+  static UInt xGetHADsic          ( DistParam* pcDtParam );
+#endif
   static UInt xGetHADs4         ( DistParam* pcDtParam );
   static UInt xGetHADs8         ( DistParam* pcDtParam );
Index: branches/HTM-DEV-0.3-dev2a/source/Lib/TLibCommon/TComSlice.cpp
===================================================================
--- branches/HTM-DEV-0.3-dev2a/source/Lib/TLibCommon/TComSlice.cpp	(revision 465)
+++ branches/HTM-DEV-0.3-dev2a/source/Lib/TLibCommon/TComSlice.cpp	(revision 468)
@@ -114,4 +114,8 @@
 , m_isDepth                       (false)
 #endif
+#if H_3D_IC
+, m_bApplyIC                      ( false )
+, m_icSkipParseFlag               ( false )
+#endif
 #endif
 {
@@ -966,4 +970,8 @@
   m_enableTMVPFlag                = pSrc->m_enableTMVPFlag;
   m_maxNumMergeCand               = pSrc->m_maxNumMergeCand;
+#if H_3D_IC
+  m_bApplyIC = pSrc->m_bApplyIC;
+  m_icSkipParseFlag = pSrc->m_icSkipParseFlag;
+#endif
 }
 
@@ -2300,4 +2308,86 @@
 #endif
 #endif
+
+#if H_3D_IC
+Void TComSlice::xSetApplyIC()
+{
+  Int iMaxPelValue = ( 1 << g_bitDepthY ); 
+  Int *aiRefOrgHist;
+  Int *aiCurrHist;
+  aiRefOrgHist = new Int;
+  aiCurrHist   = new Int;
+  aiRefOrgHist = (Int *) xMalloc( Int,iMaxPelValue );
+  aiCurrHist   = (Int *) xMalloc( Int,iMaxPelValue );
+  memset( aiRefOrgHist, 0, iMaxPelValue*sizeof(Int) );
+  memset( aiCurrHist, 0, iMaxPelValue*sizeof(Int) );
+  // Reference Idx Number
+  Int iNumRefIdx = getNumRefIdx( REF_PIC_LIST_0 );
+  TComPic* pcCurrPic = NULL;
+  TComPic* pcRefPic = NULL;
+  TComPicYuv* pcCurrPicYuv = NULL;
+  TComPicYuv* pcRefPicYuvOrg = NULL;
+  pcCurrPic = getPic();
+  pcCurrPicYuv = pcCurrPic->getPicYuvOrg();
+  Int iWidth = pcCurrPicYuv->getWidth();
+  Int iHeight = pcCurrPicYuv->getHeight();
+
+
+  // Get InterView Reference picture
+  // !!!!! Assume only one Interview Reference Picture in L0
+  for ( Int i = 0; i < iNumRefIdx; i++ )
+  {
+    pcRefPic = getRefPic( REF_PIC_LIST_0, i );
+    if ( pcRefPic != NULL )
+    {
+      if ( pcCurrPic->getViewIndex() != pcRefPic->getViewIndex() )
+      {
+        pcRefPicYuvOrg = pcRefPic->getPicYuvOrg();
+      }
+    }
+  }
+
+  if ( pcRefPicYuvOrg != NULL )
+  {
+    Pel* pCurrY = pcCurrPicYuv ->getLumaAddr();
+    Pel* pRefOrgY = pcRefPicYuvOrg  ->getLumaAddr();
+    Int iCurrStride = pcCurrPicYuv->getStride();
+    Int iRefStride = pcRefPicYuvOrg->getStride();
+    Int iSumOrgSAD = 0;
+    Double dThresholdOrgSAD = getIsDepth() ? 0.1 : 0.05;
+
+    // Histogram building - luminance
+    for ( Int y = 0; y < iHeight; y++ )
+    {
+      for ( Int x = 0; x < iWidth; x++ )
+      {
+        aiCurrHist[pCurrY[x]]++;
+        aiRefOrgHist[pRefOrgY[x]]++;
+      }
+      pCurrY += iCurrStride;
+      pRefOrgY += iRefStride;
+    }
+    // Histogram SAD
+    for ( Int i = 0; i < iMaxPelValue; i++ )
+    {
+      iSumOrgSAD += abs( aiCurrHist[i] - aiRefOrgHist[i] );
+    }
+    // Setting
+    if ( iSumOrgSAD > Int( dThresholdOrgSAD * iWidth * iHeight ) )
+    {
+      m_bApplyIC = true;
+    }
+    else
+    {
+      m_bApplyIC = false;
+    }
+  }
+
+  xFree( aiCurrHist   );
+  xFree( aiRefOrgHist );
+  aiCurrHist = NULL;
+  aiRefOrgHist = NULL;
+}
+#endif
+
 /** get scaling matrix from RefMatrixID
  * \param sizeId size index
Index: branches/HTM-DEV-0.3-dev2a/source/Lib/TLibCommon/TComSlice.h
===================================================================
--- branches/HTM-DEV-0.3-dev2a/source/Lib/TLibCommon/TComSlice.h	(revision 465)
+++ branches/HTM-DEV-0.3-dev2a/source/Lib/TLibCommon/TComSlice.h	(revision 468)
@@ -1502,4 +1502,9 @@
 #endif
 #endif
+#if H_3D_IC
+  Bool      m_bApplyIC;
+  Bool      m_icSkipParseFlag;
+#endif
+
 public:
   TComSlice();
@@ -1582,4 +1587,11 @@
   Bool      getRefPicListCombinationFlag()                      {return m_bRefPicListCombinationFlag;}
   Void      setRefPicListCombinationFlag(Bool bflag)            {m_bRefPicListCombinationFlag=bflag;}   
+#endif
+#if H_3D_IC
+  Void      setApplyIC( Bool b )                                { m_bApplyIC = b; }
+  Bool      getApplyIC()                                        { return m_bApplyIC; }
+  Void      xSetApplyIC();
+  Void      setIcSkipParseFlag( Bool b )                        { m_icSkipParseFlag = b; }
+  Bool      getIcSkipParseFlag()                                { return m_icSkipParseFlag; }
 #endif
   Void      setReferenced(Bool b)                               { m_bRefenced = b; }
Index: branches/HTM-DEV-0.3-dev2a/source/Lib/TLibCommon/TypeDef.h
===================================================================
--- branches/HTM-DEV-0.3-dev2a/source/Lib/TLibCommon/TypeDef.h	(revision 465)
+++ branches/HTM-DEV-0.3-dev2a/source/Lib/TLibCommon/TypeDef.h	(revision 468)
@@ -92,4 +92,7 @@
 #define H_3D_ARP                          1   // Advanced residual prediction (ARP), JCT3V-D0177
 #define H_3D_FIX                          1   // Temporary for minor fixes
+#define H_3D_IC                           1   // Illumination Compensation, JCT3V-B0045, JCT3V-C0046, JCT3V-D0060
+                                              // Unifying rounding offset, for IC part, JCT3V-D0135
+                                              // Full Pel Interpolation for Depth, HHI_FULL_PEL_DEPTH_MAP_MV_ACC
 #endif 
 
Index: branches/HTM-DEV-0.3-dev2a/source/Lib/TLibDecoder/TDecCAVLC.cpp
===================================================================
--- branches/HTM-DEV-0.3-dev2a/source/Lib/TLibDecoder/TDecCAVLC.cpp	(revision 465)
+++ branches/HTM-DEV-0.3-dev2a/source/Lib/TLibDecoder/TDecCAVLC.cpp	(revision 468)
@@ -1428,4 +1428,19 @@
       rpcSlice->initWpScaling();
     }
+#if H_3D_IC
+    else if( rpcSlice->getViewIndex() && ( rpcSlice->getSliceType() == P_SLICE || rpcSlice->getSliceType() == B_SLICE ) )
+    {
+      UInt uiCodeTmp = 0;
+
+      READ_FLAG ( uiCodeTmp, "slice_ic_enable_flag" );
+      rpcSlice->setApplyIC( uiCodeTmp );
+
+      if ( uiCodeTmp )
+      {
+        READ_FLAG ( uiCodeTmp, "ic_skip_mergeidx0" );
+        rpcSlice->setIcSkipParseFlag( uiCodeTmp );
+      }
+    }
+#endif
     if (!rpcSlice->isIntra())
     {
@@ -1884,4 +1899,11 @@
 #endif
 
+#if H_3D_IC
+Void TDecCavlc::parseICFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth )
+{
+  assert(0);
+}
+#endif
+
 // ====================================================================================================================
 // Protected member functions
Index: branches/HTM-DEV-0.3-dev2a/source/Lib/TLibDecoder/TDecCAVLC.h
===================================================================
--- branches/HTM-DEV-0.3-dev2a/source/Lib/TLibDecoder/TDecCAVLC.h	(revision 465)
+++ branches/HTM-DEV-0.3-dev2a/source/Lib/TLibDecoder/TDecCAVLC.h	(revision 468)
@@ -102,4 +102,7 @@
   Void parseARPW            ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth );
 #endif
+#if H_3D_IC
+  Void  parseICFlag         ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth );
+#endif
   Void parseSplitFlag       ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth );
   Void parsePartSize        ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth );
Index: branches/HTM-DEV-0.3-dev2a/source/Lib/TLibDecoder/TDecCu.cpp
===================================================================
--- branches/HTM-DEV-0.3-dev2a/source/Lib/TLibDecoder/TDecCu.cpp	(revision 465)
+++ branches/HTM-DEV-0.3-dev2a/source/Lib/TLibDecoder/TDecCu.cpp	(revision 468)
@@ -347,4 +347,7 @@
       }
     }
+#if H_3D_IC
+    m_pcEntropyDecoder->decodeICFlag( pcCU, uiAbsPartIdx, uiDepth );
+#endif
 #if H_3D_ARP
     m_pcEntropyDecoder->decodeARPW( pcCU , uiAbsPartIdx , uiDepth );
@@ -373,4 +376,7 @@
   // prediction mode ( Intra : direction mode, Inter : Mv, reference idx )
   m_pcEntropyDecoder->decodePredInfo( pcCU, uiAbsPartIdx, uiDepth, m_ppcCU[uiDepth]);
+#if H_3D_IC
+  m_pcEntropyDecoder->decodeICFlag( pcCU, uiAbsPartIdx, uiDepth );
+#endif
 #if H_3D_ARP
   m_pcEntropyDecoder->decodeARPW    ( pcCU , uiAbsPartIdx , uiDepth );  
Index: branches/HTM-DEV-0.3-dev2a/source/Lib/TLibDecoder/TDecEntropy.cpp
===================================================================
--- branches/HTM-DEV-0.3-dev2a/source/Lib/TLibDecoder/TDecEntropy.cpp	(revision 465)
+++ branches/HTM-DEV-0.3-dev2a/source/Lib/TLibDecoder/TDecEntropy.cpp	(revision 468)
@@ -106,4 +106,22 @@
 #endif
 
+#if H_3D_IC
+Void TDecEntropy::decodeICFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth )
+{
+  pcCU->setICFlagSubParts( false , uiAbsPartIdx, 0, uiDepth );
+
+  if ( pcCU->isIntra( uiAbsPartIdx ) || ( pcCU->getSlice()->getViewIndex() == 0 ) )
+  {
+    return;
+  }
+
+  if( !pcCU->getSlice()->getApplyIC() )
+    return;
+
+  if( pcCU->isICFlagRequired( uiAbsPartIdx ) )
+    m_pcEntropyDecoderIf->parseICFlag( pcCU, uiAbsPartIdx, uiDepth );
+}
+#endif
+
 Void TDecEntropy::decodeSplitFlag   ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth )
 {
Index: branches/HTM-DEV-0.3-dev2a/source/Lib/TLibDecoder/TDecEntropy.h
===================================================================
--- branches/HTM-DEV-0.3-dev2a/source/Lib/TLibDecoder/TDecEntropy.h	(revision 465)
+++ branches/HTM-DEV-0.3-dev2a/source/Lib/TLibDecoder/TDecEntropy.h	(revision 468)
@@ -88,4 +88,7 @@
   virtual Void parseARPW          ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth ) = 0;
 #endif
+#if H_3D_IC
+  virtual Void parseICFlag        ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth ) = 0;
+#endif
   virtual Void parsePartSize      ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth ) = 0;
   virtual Void parsePredMode      ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth ) = 0;
@@ -160,4 +163,7 @@
   Void decodeARPW              ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth );
 #endif
+#if H_3D_IC
+  Void decodeICFlag            ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth );
+#endif
 
   Void decodeIPCMInfo          ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth );
Index: branches/HTM-DEV-0.3-dev2a/source/Lib/TLibDecoder/TDecSbac.cpp
===================================================================
--- branches/HTM-DEV-0.3-dev2a/source/Lib/TLibDecoder/TDecSbac.cpp	(revision 465)
+++ branches/HTM-DEV-0.3-dev2a/source/Lib/TLibDecoder/TDecSbac.cpp	(revision 468)
@@ -57,4 +57,7 @@
 , m_cCUPUARPW                 ( 1,             1,               NUM_ARPW_CTX                  , m_contextModels + m_numContextModels, m_numContextModels)
 #endif
+#if H_3D_IC
+, m_cCUICFlagSCModel          ( 1,             1,               NUM_IC_FLAG_CTX               , m_contextModels + m_numContextModels, m_numContextModels)
+#endif
 , m_cCUPartSizeSCModel        ( 1,             1,               NUM_PART_SIZE_CTX             , m_contextModels + m_numContextModels, m_numContextModels)
 , m_cCUPredModeSCModel        ( 1,             1,               NUM_PRED_MODE_CTX             , m_contextModels + m_numContextModels, m_numContextModels)
@@ -119,4 +122,7 @@
   m_cCUPUARPW.initBuffer                 ( sliceType, qp, (UChar*)INIT_ARPW );
 #endif
+#if H_3D_IC
+  m_cCUICFlagSCModel.initBuffer          ( sliceType, qp, (UChar*)INIT_IC_FLAG );
+#endif
   m_cCUPartSizeSCModel.initBuffer        ( sliceType, qp, (UChar*)INIT_PART_SIZE );
   m_cCUAMPSCModel.initBuffer             ( sliceType, qp, (UChar*)INIT_CU_AMP_POS );
@@ -166,4 +172,7 @@
 #if H_3D_ARP
   m_cCUPUARPW.initBuffer                 ( eSliceType, iQp, (UChar*)INIT_ARPW );
+#endif
+#if H_3D_IC
+  m_cCUICFlagSCModel.initBuffer          ( eSliceType, iQp, (UChar*)INIT_IC_FLAG );
 #endif
   m_cCUPartSizeSCModel.initBuffer        ( eSliceType, iQp, (UChar*)INIT_PART_SIZE );
@@ -1582,3 +1591,28 @@
 }
 #endif
+
+#if H_3D_IC
+/** parse illumination compensation flag
+ * \param pcCU
+ * \param uiAbsPartIdx 
+ * \param uiDepth
+ * \returns Void
+ */
+Void TDecSbac::parseICFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth )
+{ 
+  UInt uiSymbol = 0;
+  UInt uiCtxIC = pcCU->getCtxICFlag( uiAbsPartIdx );
+  m_pcTDecBinIf->decodeBin( uiSymbol, m_cCUICFlagSCModel.get( 0, 0, uiCtxIC ) );
+  DTRACE_CABAC_VL( g_nSymbolCounter++ );
+  DTRACE_CABAC_T( "\tICFlag" );
+  DTRACE_CABAC_T( "\tuiCtxIC: ");
+  DTRACE_CABAC_V( uiCtxIC );
+  DTRACE_CABAC_T( "\tuiSymbol: ");
+  DTRACE_CABAC_V( uiSymbol );
+  DTRACE_CABAC_T( "\n");
+  
+  pcCU->setICFlagSubParts( uiSymbol ? true : false , uiAbsPartIdx, 0, uiDepth );
+}
+#endif
+
 //! \}
Index: branches/HTM-DEV-0.3-dev2a/source/Lib/TLibDecoder/TDecSbac.h
===================================================================
--- branches/HTM-DEV-0.3-dev2a/source/Lib/TLibDecoder/TDecSbac.h	(revision 465)
+++ branches/HTM-DEV-0.3-dev2a/source/Lib/TLibDecoder/TDecSbac.h	(revision 468)
@@ -111,4 +111,7 @@
   Void parseARPW          ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth );
 #endif
+#if H_3D_IC
+  Void parseICFlag        ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth );
+#endif
   Void parsePartSize      ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth );
   Void parsePredMode      ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth );
@@ -151,4 +154,7 @@
   ContextModel3DBuffer m_cCUPUARPW;
 #endif
+#if H_3D_IC
+  ContextModel3DBuffer m_cCUICFlagSCModel;
+#endif
   ContextModel3DBuffer m_cCUPartSizeSCModel;
   ContextModel3DBuffer m_cCUPredModeSCModel;
Index: branches/HTM-DEV-0.3-dev2a/source/Lib/TLibEncoder/TEncCavlc.cpp
===================================================================
--- branches/HTM-DEV-0.3-dev2a/source/Lib/TLibEncoder/TEncCavlc.cpp	(revision 465)
+++ branches/HTM-DEV-0.3-dev2a/source/Lib/TLibEncoder/TEncCavlc.cpp	(revision 468)
@@ -1086,4 +1086,14 @@
       xCodePredWeightTable( pcSlice );
     }
+#if H_3D_IC
+    else if( pcSlice->getViewIndex() && ( pcSlice->getSliceType() == P_SLICE || pcSlice->getSliceType() == B_SLICE ) )
+    {
+      WRITE_FLAG( pcSlice->getApplyIC() ? 1 : 0, "slice_ic_enable_flag" );
+      if( pcSlice->getApplyIC() )
+      {
+        WRITE_FLAG( pcSlice->getIcSkipParseFlag() ? 1 : 0, "ic_skip_mergeidx0" );
+      }
+    }
+#endif
     assert(pcSlice->getMaxNumMergeCand()<=MRG_MAX_NUM_CANDS);
     if (!pcSlice->isIntra())
@@ -1371,4 +1381,11 @@
 #endif
 
+#if H_3D_IC
+Void TEncCavlc::codeICFlag( TComDataCU* pcCU, UInt uiAbsPartIdx )
+{
+  assert(0);
+}
+#endif
+
 Void TEncCavlc::codeInterModeFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, UInt uiEncMode )
 {
Index: branches/HTM-DEV-0.3-dev2a/source/Lib/TLibEncoder/TEncCavlc.h
===================================================================
--- branches/HTM-DEV-0.3-dev2a/source/Lib/TLibEncoder/TEncCavlc.h	(revision 465)
+++ branches/HTM-DEV-0.3-dev2a/source/Lib/TLibEncoder/TEncCavlc.h	(revision 468)
@@ -117,4 +117,7 @@
   Void codeARPW          ( TComDataCU* pcCU, UInt uiAbsPartIdx );
 #endif
+#if H_3D_IC
+  Void codeICFlag        ( TComDataCU* pcCU, UInt uiAbsPartIdx );
+#endif
 
   Void codeInterModeFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, UInt uiEncMode );
Index: branches/HTM-DEV-0.3-dev2a/source/Lib/TLibEncoder/TEncCfg.h
===================================================================
--- branches/HTM-DEV-0.3-dev2a/source/Lib/TLibEncoder/TEncCfg.h	(revision 465)
+++ branches/HTM-DEV-0.3-dev2a/source/Lib/TLibEncoder/TEncCfg.h	(revision 468)
@@ -399,4 +399,8 @@
   UInt      m_uiARPStepNum;
 #endif
+
+#if H_3D_IC
+  Bool      m_bUseIC;
+#endif
 #endif
 
@@ -481,4 +485,8 @@
 #endif
 
+#if H_3D_IC
+  Void       setUseIC                       ( Bool bVal )    { m_bUseIC = bVal; }
+  Bool       getUseIC                       ()               { return m_bUseIC; }
+#endif
   //======== Transform =============
   Void      setQuadtreeTULog2MaxSize        ( UInt  u )      { m_uiQuadtreeTULog2MaxSize = u; }
Index: branches/HTM-DEV-0.3-dev2a/source/Lib/TLibEncoder/TEncCu.cpp
===================================================================
--- branches/HTM-DEV-0.3-dev2a/source/Lib/TLibEncoder/TEncCu.cpp	(revision 465)
+++ branches/HTM-DEV-0.3-dev2a/source/Lib/TLibEncoder/TEncCu.cpp	(revision 468)
@@ -457,5 +457,8 @@
   }
 #endif
-
+#if H_3D_IC
+  Bool bICEnabled = rpcTempCU->getSlice()->getViewIndex() && ( rpcTempCU->getSlice()->getSliceType() == P_SLICE || rpcTempCU->getSlice()->getSliceType() == B_SLICE );
+  bICEnabled = bICEnabled && rpcTempCU->getSlice()->getApplyIC();
+#endif
   // If slice start or slice end is within this cu...
   TComSlice * pcSlice = rpcTempCU->getPic()->getSlice(rpcTempCU->getPic()->getCurrSliceIdx());
@@ -513,10 +516,21 @@
       if( rpcBestCU->getSlice()->getSliceType() != I_SLICE )
       {
+#if H_3D_IC
+        for( UInt uiICId = 0; uiICId < ( bICEnabled ? 2 : 1 ); uiICId++ )
+        {
+          Bool bICFlag = uiICId ? true : false;
+#endif
         // 2Nx2N
         if(m_pcEncCfg->getUseEarlySkipDetection())
         {
+#if H_3D_IC
+          rpcTempCU->setICFlagSubParts(bICFlag, 0, 0, uiDepth);
+#endif
           xCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_2Nx2N );  rpcTempCU->initEstData( uiDepth, iQP );//by Competition for inter_2Nx2N
         }
         // SKIP
+#if H_3D_IC
+        rpcTempCU->setICFlagSubParts(bICFlag, 0, 0, uiDepth);
+#endif
         xCheckRDCostMerge2Nx2N( rpcBestCU, rpcTempCU, &earlyDetectionSkipMode );//by Merge for inter_2Nx2N
         rpcTempCU->initEstData( uiDepth, iQP );
@@ -538,4 +552,7 @@
           if ( !bEarlySkip )
           {
+#if H_3D_IC
+            rpcTempCU->setICFlagSubParts(bICFlag, 0, 0, uiDepth);
+#endif
             xCheckRDCostInter( rpcBestCU, rpcTempCU, SIZE_2Nx2N );  rpcTempCU->initEstData( uiDepth, iQP );
             if(m_pcEncCfg->getUseCbfFastMode())
@@ -545,4 +562,7 @@
           }
         }
+#if H_3D_IC
+        }
+#endif
       }
 
@@ -1245,4 +1265,7 @@
   {
     m_pcEntropyCoder->encodeMergeIndex( pcCU, uiAbsPartIdx );
+#if H_3D_IC
+    m_pcEntropyCoder->encodeICFlag  ( pcCU, uiAbsPartIdx );
+#endif
 #if H_3D_ARP
     m_pcEntropyCoder->encodeARPW( pcCU , uiAbsPartIdx );
@@ -1269,4 +1292,7 @@
   // prediction Info ( Intra : direction mode, Inter : Mv, reference idx )
   m_pcEntropyCoder->encodePredInfo( pcCU, uiAbsPartIdx );
+#if H_3D_IC
+  m_pcEntropyCoder->encodeICFlag  ( pcCU, uiAbsPartIdx );
+#endif
 #if H_3D_ARP
   m_pcEntropyCoder->encodeARPW( pcCU , uiAbsPartIdx );
@@ -1299,5 +1325,7 @@
   }
   UChar uhDepth = rpcTempCU->getDepth( 0 );
-
+#if H_3D_IC
+  Bool bICFlag = rpcTempCU->getICFlag( 0 );
+#endif
 #if H_3D_VSO // M1  //nececcary here?
   if( m_pcRdCost->getUseRenModel() )
@@ -1348,4 +1376,13 @@
     {
       {
+#if H_3D_IC
+        if( rpcTempCU->getSlice()->getApplyIC() && rpcTempCU->getSlice()->getIcSkipParseFlag() )
+        {
+          if( bICFlag && uiMergeCand == 0 ) 
+          {
+            continue;
+          }
+        }
+#endif
         if(!(uiNoResidual==1 && mergeCandBuffer[uiMergeCand]==1))
         {
@@ -1357,4 +1394,7 @@
           rpcTempCU->setCUTransquantBypassSubParts( m_pcEncCfg->getCUTransquantBypassFlagValue(),     0, uhDepth );
           rpcTempCU->setPartSizeSubParts( SIZE_2Nx2N, 0, uhDepth ); // interprets depth relative to LCU level
+#if H_3D_IC
+          rpcTempCU->setICFlagSubParts( bICFlag, 0, 0, uhDepth );
+#endif
 #if H_3D_ARP
           rpcTempCU->setARPWSubParts( (UChar)nARPW , 0 , uhDepth );
Index: branches/HTM-DEV-0.3-dev2a/source/Lib/TLibEncoder/TEncEntropy.cpp
===================================================================
--- branches/HTM-DEV-0.3-dev2a/source/Lib/TLibEncoder/TEncEntropy.cpp	(revision 465)
+++ branches/HTM-DEV-0.3-dev2a/source/Lib/TLibEncoder/TEncEntropy.cpp	(revision 468)
@@ -157,4 +157,25 @@
 }
 
+#if H_3D_IC
+Void TEncEntropy::encodeICFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD )
+{
+  if ( pcCU->isIntra( uiAbsPartIdx ) || ( pcCU->getSlice()->getViewIndex() == 0 ) )
+  {
+    return;
+  }
+
+  if( !pcCU->getSlice()->getApplyIC() )
+    return;
+
+  if( bRD )
+  {
+    uiAbsPartIdx = 0;
+  }
+
+  if( pcCU->isICFlagRequired( uiAbsPartIdx ) )
+    m_pcEntropyCoderIf->codeICFlag( pcCU, uiAbsPartIdx );
+}
+#endif
+
 #if H_3D_ARP
 Void TEncEntropy::encodeARPW( TComDataCU* pcCU, UInt uiAbsPartIdx )
Index: branches/HTM-DEV-0.3-dev2a/source/Lib/TLibEncoder/TEncEntropy.h
===================================================================
--- branches/HTM-DEV-0.3-dev2a/source/Lib/TLibEncoder/TEncEntropy.h	(revision 465)
+++ branches/HTM-DEV-0.3-dev2a/source/Lib/TLibEncoder/TEncEntropy.h	(revision 468)
@@ -90,4 +90,7 @@
 #if H_3D_ARP
   virtual Void codeARPW          ( TComDataCU* pcCU, UInt uiAbsPartIdx ) = 0;
+#endif
+#if H_3D_IC
+  virtual Void codeICFlag        ( TComDataCU* pcCU, UInt uiAbsPartIdx ) = 0;
 #endif
   virtual Void codeSplitFlag     ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth ) = 0;
@@ -175,4 +178,7 @@
   Void encodeARPW         ( TComDataCU* pcCU, UInt uiAbspartIdx );
 #endif
+#if H_3D_IC
+  Void encodeICFlag       ( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD = false );
+#endif
   Void encodePredMode          ( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD = false );
   Void encodePartSize          ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, Bool bRD = false );
Index: branches/HTM-DEV-0.3-dev2a/source/Lib/TLibEncoder/TEncSbac.cpp
===================================================================
--- branches/HTM-DEV-0.3-dev2a/source/Lib/TLibEncoder/TEncSbac.cpp	(revision 465)
+++ branches/HTM-DEV-0.3-dev2a/source/Lib/TLibEncoder/TEncSbac.cpp	(revision 468)
@@ -63,4 +63,7 @@
 , m_cCUPUARPW                 ( 1,             1,               NUM_ARPW_CTX                  , m_contextModels + m_numContextModels, m_numContextModels)
 #endif
+#if H_3D_IC
+, m_cCUICFlagSCModel          ( 1,             1,               NUM_IC_FLAG_CTX               , m_contextModels + m_numContextModels, m_numContextModels)
+#endif
 , m_cCUPartSizeSCModel        ( 1,             1,               NUM_PART_SIZE_CTX             , m_contextModels + m_numContextModels, m_numContextModels)
 , m_cCUPredModeSCModel        ( 1,             1,               NUM_PRED_MODE_CTX             , m_contextModels + m_numContextModels, m_numContextModels)
@@ -116,4 +119,7 @@
 #if H_3D_ARP
   m_cCUPUARPW.initBuffer                 ( eSliceType, iQp, (UChar*)INIT_ARPW );
+#endif
+#if H_3D_IC
+  m_cCUICFlagSCModel.initBuffer          ( eSliceType, iQp, (UChar*)INIT_IC_FLAG );
 #endif
   m_cCUPartSizeSCModel.initBuffer        ( eSliceType, iQp, (UChar*)INIT_PART_SIZE );
@@ -171,4 +177,7 @@
       curCost += m_cCUMergeFlagExtSCModel.calcCost    ( curSliceType, qp, (UChar*)INIT_MERGE_FLAG_EXT);
       curCost += m_cCUMergeIdxExtSCModel.calcCost     ( curSliceType, qp, (UChar*)INIT_MERGE_IDX_EXT);
+#if H_3D_IC
+      curCost += m_cCUICFlagSCModel.calcCost          ( curSliceType, qp, (UChar*)INIT_IC_FLAG );
+#endif
       curCost += m_cCUPartSizeSCModel.calcCost        ( curSliceType, qp, (UChar*)INIT_PART_SIZE );
       curCost += m_cCUAMPSCModel.calcCost             ( curSliceType, qp, (UChar*)INIT_CU_AMP_POS );
@@ -222,4 +231,7 @@
 #if H_3D_ARP
   m_cCUPUARPW.initBuffer                 ( eSliceType, iQp, (UChar*)INIT_ARPW );
+#endif
+#if H_3D_IC
+  m_cCUICFlagSCModel.initBuffer          ( eSliceType, iQp, (UChar*)INIT_IC_FLAG );
 #endif
   m_cCUPartSizeSCModel.initBuffer        ( eSliceType, iQp, (UChar*)INIT_PART_SIZE );
@@ -616,4 +628,27 @@
 #endif
 
+#if H_3D_IC
+/** code Illumination Compensation flag
+ * \param pcCU
+ * \param uiAbsPartIdx 
+ * \returns Void
+ */
+Void TEncSbac::codeICFlag( TComDataCU* pcCU, UInt uiAbsPartIdx )
+{
+  // get context function is here
+  UInt uiSymbol = pcCU->getICFlag( uiAbsPartIdx ) ? 1 : 0;
+  UInt uiCtxIC  = pcCU->getCtxICFlag( uiAbsPartIdx ) ;
+  m_pcBinIf->encodeBin( uiSymbol, m_cCUICFlagSCModel.get( 0, 0, uiCtxIC ) );
+  DTRACE_CABAC_VL( g_nSymbolCounter++ );
+  DTRACE_CABAC_T( "\tICFlag" );
+  DTRACE_CABAC_T( "\tuiCtxIC: ");
+  DTRACE_CABAC_V( uiCtxIC );
+  DTRACE_CABAC_T( "\tuiSymbol: ");
+  DTRACE_CABAC_V( uiSymbol );
+  DTRACE_CABAC_T( "\n");
+}
+#endif
+
+
 Void TEncSbac::codeSplitFlag   ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth )
 {
Index: branches/HTM-DEV-0.3-dev2a/source/Lib/TLibEncoder/TEncSbac.h
===================================================================
--- branches/HTM-DEV-0.3-dev2a/source/Lib/TLibEncoder/TEncSbac.h	(revision 465)
+++ branches/HTM-DEV-0.3-dev2a/source/Lib/TLibEncoder/TEncSbac.h	(revision 468)
@@ -137,4 +137,7 @@
   Void codeARPW          ( TComDataCU* pcCU, UInt uiAbsPartIdx );
 #endif
+#if H_3D_IC
+  Void codeICFlag        ( TComDataCU* pcCU, UInt uiAbsPartIdx );
+#endif
   Void codeSplitFlag     ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth );
   Void codeMVPIdx        ( TComDataCU* pcCU, UInt uiAbsPartIdx, RefPicList eRefList );
@@ -186,4 +189,7 @@
 #if H_3D_ARP
   ContextModel3DBuffer m_cCUPUARPW;
+#endif
+#if H_3D_IC
+  ContextModel3DBuffer m_cCUICFlagSCModel;
 #endif
   ContextModel3DBuffer m_cCUPartSizeSCModel;
Index: branches/HTM-DEV-0.3-dev2a/source/Lib/TLibEncoder/TEncSearch.cpp
===================================================================
--- branches/HTM-DEV-0.3-dev2a/source/Lib/TLibEncoder/TEncSearch.cpp	(revision 465)
+++ branches/HTM-DEV-0.3-dev2a/source/Lib/TLibEncoder/TEncSearch.cpp	(revision 468)
@@ -317,5 +317,7 @@
   
   piRefSrch = rcStruct.piRefY + iSearchY * rcStruct.iYStride + iSearchX;
-  
+#if H_3D_IC
+  m_cDistParam.bUseIC = pcPatternKey->getICFlag();
+#endif
   //-- jclee for using the SAD function pointer
   m_pcRdCost->setDistParam( pcPatternKey, piRefSrch, rcStruct.iYStride,  m_cDistParam );
@@ -744,5 +746,7 @@
 
     setDistParamComp(0);  // Y component
-
+#if H_3D_IC
+    m_cDistParam.bUseIC = pcPatternKey->getICFlag();
+#endif
     m_cDistParam.pCur = piRefPos;
     m_cDistParam.bitDepth = g_bitDepthY;
@@ -3147,4 +3151,7 @@
 #else
                             iWidth, iHeight, m_pcEncCfg->getUseHADME() );
+#endif
+#if H_3D_IC
+  cDistParam.bUseIC = false;
 #endif
   ruiErr = cDistParam.DistFunc( &cDistParam );
@@ -4235,4 +4242,8 @@
   pcCU->clipMv( cMvCand );
 
+#if H_3D_IC
+  Bool bICFlag = pcCU->getICFlag( uiPartAddr ) && ( pcCU->getSlice()->getViewIndex() != pcCU->getSlice()->getRefPic( eRefPicList, iRefIdx )->getViewIndex() );
+#endif
+
   // prediction pattern
   if ( pcCU->getSlice()->getPPS()->getUseWP() && pcCU->getSlice()->getSliceType()==P_SLICE )
@@ -4242,5 +4253,9 @@
   else
   {
-    xPredInterLumaBlk( pcCU, pcPicYuvRef, uiPartAddr, &cMvCand, iSizeX, iSizeY, pcTemplateCand, false );
+    xPredInterLumaBlk( pcCU, pcPicYuvRef, uiPartAddr, &cMvCand, iSizeX, iSizeY, pcTemplateCand, false 
+#if H_3D_IC
+    , bICFlag
+#endif
+      );
   }
 
@@ -4295,4 +4310,9 @@
   pcCU->getPartIndexAndSize( iPartIdx, uiPartAddr, iRoiWidth, iRoiHeight );
   
+#if H_3D_IC
+  Bool bICFlag = pcCU->getICFlag( uiPartAddr ) && ( pcCU->getSlice()->getViewIndex() != pcCU->getSlice()->getRefPic( eRefPicList, iRefIdxPred )->getViewIndex() );
+  pcPatternKey->setICFlag( bICFlag );
+#endif
+
   if ( bBi )
   {
@@ -4327,4 +4347,9 @@
   
   m_pcRdCost->setPredictor  ( *pcMvPred );
+#if H_3D_IC
+  if( pcCU->getSlice()->getIsDepth() )
+    m_pcRdCost->setCostScale  ( 0 );
+  else
+#endif
   m_pcRdCost->setCostScale  ( 2 );
 
@@ -4342,4 +4367,8 @@
   
   m_pcRdCost->getMotionCost( 1, 0 );
+#if H_3D_IC
+  if( ! pcCU->getSlice()->getIsDepth() )
+  {
+#endif
   m_pcRdCost->setCostScale ( 1 );
   
@@ -4356,7 +4385,13 @@
   rcMv += (cMvHalf <<= 1);
   rcMv +=  cMvQter;
+#if H_3D_IC
+  }
+#endif
   
   UInt uiMvBits = m_pcRdCost->getBits( rcMv.getHor(), rcMv.getVer() );
-  
+#if H_3D_IC
+  if( pcCU->getSlice()->getIsDepth() )
+    ruiCost += m_pcRdCost->getCost( uiMvBits );
+#endif
   ruiBits      += uiMvBits;
   ruiCost       = (UInt)( floor( fWeight * ( (Double)ruiCost - (Double)m_pcRdCost->getCost( uiMvBits ) ) ) + (Double)m_pcRdCost->getCost( ruiBits ) );
@@ -4367,4 +4402,8 @@
 {
   Int  iMvShift = 2;
+#if H_3D_IC
+  if( pcCU->getSlice()->getIsDepth() )
+    iMvShift = 0;
+#endif
   TComMv cTmpMvPred = cMvPred;
   pcCU->clipMv( cTmpMvPred );
@@ -4418,5 +4457,7 @@
 
       setDistParamComp(0);
-
+#if H_3D_IC
+      m_cDistParam.bUseIC = pcPatternKey->getICFlag();
+#endif
       m_cDistParam.bitDepth = g_bitDepthY;
       uiSad = m_cDistParam.DistFunc( &m_cDistParam );
@@ -4469,4 +4510,7 @@
   UInt uiSearchRange = m_iSearchRange;
   pcCU->clipMv( rcMv );
+#if H_3D_IC
+  if( ! pcCU->getSlice()->getIsDepth() )
+#endif
   rcMv >>= 2;
   // init TZSearchStruct
@@ -4486,4 +4530,7 @@
       TComMv cMv = m_acMvPredictors[index];
       pcCU->clipMv( cMv );
+#if H_3D_IC
+      if( ! pcCU->getSlice()->getIsDepth() )
+#endif
       cMv >>= 2;
       xTZSearchHelp( pcPatternKey, cStruct, cMv.getHor(), cMv.getVer(), 0, 0 );
@@ -4741,4 +4788,7 @@
     m_pcEntropyCoder->encodeSkipFlag(pcCU, 0, true);
     m_pcEntropyCoder->encodeMergeIndex( pcCU, 0, true );
+#if H_3D_IC
+    m_pcEntropyCoder->encodeICFlag( pcCU, 0, true );
+#endif
 #if H_3D_ARP
     m_pcEntropyCoder->encodeARPW( pcCU, 0 );
@@ -6152,4 +6202,7 @@
     m_pcEntropyCoder->encodeSkipFlag(pcCU, 0, true);
     m_pcEntropyCoder->encodeMergeIndex(pcCU, 0, true);
+#if H_3D_IC
+    m_pcEntropyCoder->encodeICFlag( pcCU, 0, true );
+#endif
 #if H_3D_ARP
     m_pcEntropyCoder->encodeARPW( pcCU, 0 );
@@ -6168,4 +6221,7 @@
     m_pcEntropyCoder->encodePartSize( pcCU, 0, pcCU->getDepth(0), true );
     m_pcEntropyCoder->encodePredInfo( pcCU, 0, true );
+#if H_3D_IC
+    m_pcEntropyCoder->encodeICFlag( pcCU, 0, true );
+#endif
 #if H_3D_ARP
     m_pcEntropyCoder->encodeARPW( pcCU , 0 );
Index: branches/HTM-DEV-0.3-dev2a/source/Lib/TLibEncoder/TEncSlice.cpp
===================================================================
--- branches/HTM-DEV-0.3-dev2a/source/Lib/TLibEncoder/TEncSlice.cpp	(revision 465)
+++ branches/HTM-DEV-0.3-dev2a/source/Lib/TLibEncoder/TEncSlice.cpp	(revision 468)
@@ -189,5 +189,7 @@
   rpcSlice->setPicOutputFlag( true );
   rpcSlice->setPOC( pocCurr );
-  
+#if H_3D_IC
+  rpcSlice->setApplyIC( false );
+#endif
   // depth computation based on GOP size
   Int depth;
@@ -933,5 +935,14 @@
   Int  iNumSubstreams = 1;
   UInt uiTilesAcross  = 0;
-
+#if H_3D_IC
+  if ( pcEncTop->getViewIndex() && pcEncTop->getUseIC() ) // DCP of ViewID 0 is not available
+  {
+    pcSlice ->xSetApplyIC();
+    if ( pcSlice->getApplyIC() )
+    {
+      pcSlice->setIcSkipParseFlag( pcSlice->getPOC() % m_pcCfg->getIntraPeriod() != 0 );
+    }
+  }
+#endif
   if( m_pcCfg->getUseSBACRD() )
   {
