Index: /branches/SHM-6-dev/build/linux/lib/TLibCommon/makefile
===================================================================
--- /branches/SHM-6-dev/build/linux/lib/TLibCommon/makefile	(revision 676)
+++ /branches/SHM-6-dev/build/linux/lib/TLibCommon/makefile	(revision 677)
@@ -58,4 +58,5 @@
 			$(OBJ_DIR)/TComRdCostWeightPrediction.o \
 			$(OBJ_DIR)/TComUpsampleFilter.o \
+			$(OBJ_DIR)/TCom3DAsymLUT.o \
 
 LIBS				= -lpthread
Index: /branches/SHM-6-dev/build/linux/lib/TLibEncoder/makefile
===================================================================
--- /branches/SHM-6-dev/build/linux/lib/TLibEncoder/makefile	(revision 676)
+++ /branches/SHM-6-dev/build/linux/lib/TLibEncoder/makefile	(revision 677)
@@ -52,4 +52,5 @@
 			$(OBJ_DIR)/WeightPredAnalysis.o \
 			$(OBJ_DIR)/TEncRateCtrl.o \
+			$(OBJ_DIR)/TEnc3DAsymLUT.o \
 
 LIBS				= -lpthread
Index: /branches/SHM-6-dev/build/vc10/TLibCommon_vc10.vcxproj
===================================================================
--- /branches/SHM-6-dev/build/vc10/TLibCommon_vc10.vcxproj	(revision 676)
+++ /branches/SHM-6-dev/build/vc10/TLibCommon_vc10.vcxproj	(revision 677)
@@ -148,4 +148,5 @@
     <ClCompile Include="..\..\source\Lib\libmd5\libmd5.c" />
     <ClCompile Include="..\..\source\Lib\TLibCommon\SEI.cpp" />
+    <ClCompile Include="..\..\source\Lib\TLibCommon\TCom3DAsymLUT.cpp" />
     <ClCompile Include="..\..\source\Lib\TLibCommon\TComBitStream.cpp" />
     <ClCompile Include="..\..\source\Lib\TLibCommon\TComCABACTables.cpp" />
@@ -180,4 +181,5 @@
     <ClInclude Include="..\..\source\Lib\TLibCommon\NAL.h" />
     <ClInclude Include="..\..\source\Lib\TLibCommon\SEI.h" />
+    <ClInclude Include="..\..\source\Lib\TLibCommon\TCom3DAsymLUT.h" />
     <ClInclude Include="..\..\source\Lib\TLibCommon\TComBitCounter.h" />
     <ClInclude Include="..\..\source\Lib\TLibCommon\TComBitStream.h" />
Index: /branches/SHM-6-dev/build/vc10/TLibEncoder_vc10.vcxproj
===================================================================
--- /branches/SHM-6-dev/build/vc10/TLibEncoder_vc10.vcxproj	(revision 676)
+++ /branches/SHM-6-dev/build/vc10/TLibEncoder_vc10.vcxproj	(revision 677)
@@ -147,4 +147,5 @@
     <ClCompile Include="..\..\source\Lib\TLibEncoder\SEIwrite.cpp" />
     <ClCompile Include="..\..\source\Lib\TLibEncoder\SyntaxElementWriter.cpp" />
+    <ClCompile Include="..\..\source\Lib\TLibEncoder\TEnc3DAsymLUT.cpp" />
     <ClCompile Include="..\..\source\Lib\TLibEncoder\TEncAnalyze.cpp" />
     <ClCompile Include="..\..\source\Lib\TLibEncoder\TEncBinCoderCABAC.cpp" />
@@ -169,4 +170,5 @@
     <ClInclude Include="..\..\source\Lib\TLibEncoder\SEIwrite.h" />
     <ClInclude Include="..\..\source\Lib\TLibEncoder\SyntaxElementWriter.h" />
+    <ClInclude Include="..\..\source\Lib\TLibEncoder\TEnc3DAsymLUT.h" />
     <ClInclude Include="..\..\source\Lib\TLibEncoder\TEncAnalyze.h" />
     <ClInclude Include="..\..\source\Lib\TLibEncoder\TEncBinCoder.h" />
Index: /branches/SHM-6-dev/source/App/TAppEncoder/TAppEncCfg.cpp
===================================================================
--- /branches/SHM-6-dev/source/App/TAppEncoder/TAppEncCfg.cpp	(revision 676)
+++ /branches/SHM-6-dev/source/App/TAppEncoder/TAppEncCfg.cpp	(revision 677)
@@ -960,4 +960,10 @@
 #if O0149_CROSS_LAYER_BLA_FLAG
   ("CrossLayerBLAFlag",                m_crossLayerBLAFlag,                       false, "Specifies the value of cross_layer_bla_flag in VPS")
+#endif
+#if Q0048_CGS_3D_ASYMLUT
+  ("CGS",     m_nCGSFlag , 0, "whether CGS is enabled")
+  ("CGSMaxOctantDepth", m_nCGSMaxOctantDepth , 1, "max octant depth")
+  ("CGSMaxYPartNumLog",  m_nCGSMaxYPartNumLog2 , 2, "max Y part number ")
+  ("CGSLUTBit",     m_nCGSLUTBit , 12, "bit depth of CGS LUT")
 #endif
   ;
@@ -2301,4 +2307,7 @@
   }
 #endif 
+#if Q0048_CGS_3D_ASYMLUT
+  xConfirmPara( m_nCGSFlag < 0 || m_nCGSFlag > 1 , "0<=CGS<=1" );
+#endif
 #undef xConfirmPara
   if (check_failed)
@@ -2560,4 +2569,7 @@
   printf("RecalQP:%d", m_recalculateQPAccordingToLambda ? 1 : 0 );
 #endif
+#if Q0048_CGS_3D_ASYMLUT
+  printf("CGS: %d CGSMaxOctantDepth: %d CGSMaxYPartNumLog2: %d CGSLUTBit:%d " , m_nCGSFlag , m_nCGSMaxOctantDepth , m_nCGSMaxYPartNumLog2 , m_nCGSLUTBit );
+#endif
   printf("\n\n");
   
Index: /branches/SHM-6-dev/source/App/TAppEncoder/TAppEncCfg.h
===================================================================
--- /branches/SHM-6-dev/source/App/TAppEncoder/TAppEncCfg.h	(revision 676)
+++ /branches/SHM-6-dev/source/App/TAppEncoder/TAppEncCfg.h	(revision 677)
@@ -395,4 +395,10 @@
   Bool      m_useInterLayerWeightedPred;
 #endif
+#if Q0048_CGS_3D_ASYMLUT
+  Int  m_nCGSFlag;
+  Int  m_nCGSMaxOctantDepth;
+  Int  m_nCGSMaxYPartNumLog2;
+  Int  m_nCGSLUTBit;
+#endif
 public:
   TAppEncCfg();
Index: /branches/SHM-6-dev/source/App/TAppEncoder/TAppEncTop.cpp
===================================================================
--- /branches/SHM-6-dev/source/App/TAppEncoder/TAppEncTop.cpp	(revision 676)
+++ /branches/SHM-6-dev/source/App/TAppEncoder/TAppEncTop.cpp	(revision 677)
@@ -604,4 +604,10 @@
 #if O0149_CROSS_LAYER_BLA_FLAG
     m_acTEncTop[layer].setCrossLayerBLAFlag( m_crossLayerBLAFlag );
+#endif
+#if Q0048_CGS_3D_ASYMLUT
+    m_acTEncTop[layer].setCGSFlag( layer == 0 ? 0 : m_nCGSFlag );
+    m_acTEncTop[layer].setCGSMaxOctantDepth( m_nCGSMaxOctantDepth );
+    m_acTEncTop[layer].setCGSMaxYPartNumLog2( m_nCGSMaxYPartNumLog2 );
+    m_acTEncTop[layer].setCGSLUTBit( m_nCGSLUTBit );
 #endif
   }
Index: /branches/SHM-6-dev/source/Lib/TLibCommon/TCom3DAsymLUT.cpp
===================================================================
--- /branches/SHM-6-dev/source/Lib/TLibCommon/TCom3DAsymLUT.cpp	(revision 677)
+++ /branches/SHM-6-dev/source/Lib/TLibCommon/TCom3DAsymLUT.cpp	(revision 677)
@@ -0,0 +1,279 @@
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <cmath>
+#include <algorithm>
+
+#include "TypeDef.h"
+#include "TCom3DAsymLUT.h"
+#include "TComPicYuv.h"
+
+#if Q0048_CGS_3D_ASYMLUT
+
+const Int TCom3DAsymLUT::m_nVertexIdxOffset[4][3] = { { 0 , 0 , 0 } , { 0 , 1 , 0 } , { 0 , 1 , 1 } , { 1 , 1 , 1 } };
+
+TCom3DAsymLUT::TCom3DAsymLUT()
+{
+  m_pCuboid = NULL;
+  m_nResQuanBit = 0;
+}
+
+TCom3DAsymLUT::~TCom3DAsymLUT()
+{
+  destroy();
+}
+
+Void TCom3DAsymLUT::create( Int nMaxOctantDepth , Int nInputBitDepth , Int nInputBitDepthC , Int nOutputBitDepth , Int nOutputBitDepthC , Int nMaxYPartNumLog2 )
+{
+  m_nMaxOctantDepth = nMaxOctantDepth;
+  m_nInputBitDepthY = nInputBitDepth;
+  m_nOutputBitDepthY = nOutputBitDepth;
+  m_nInputBitDepthC = nInputBitDepthC;
+  m_nOutputBitDepthC = nOutputBitDepthC;
+  m_nDeltaBitDepthC = m_nOutputBitDepthC - m_nInputBitDepthC;
+  m_nDeltaBitDepth = m_nOutputBitDepthY - m_nInputBitDepthY;
+  m_nMaxYPartNumLog2 = nMaxYPartNumLog2;
+  m_nMaxPartNumLog2 = 3 * m_nMaxOctantDepth + m_nMaxYPartNumLog2;
+
+  xUpdatePartitioning( nMaxOctantDepth , nMaxYPartNumLog2 );
+
+  m_nYSize = 1 << ( m_nMaxOctantDepth + m_nMaxYPartNumLog2 );
+  m_nUSize = 1 << m_nMaxOctantDepth;
+  m_nVSize = 1 << m_nMaxOctantDepth;
+  assert( m_nYSize > 0 && m_nUSize > 0 && m_nVSize > 0 );
+
+  if( m_pCuboid != NULL )
+    destroy();
+  xAllocate3DArray( m_pCuboid , m_nYSize , m_nUSize , m_nVSize );
+}
+
+Void TCom3DAsymLUT::destroy()
+{
+  xFree3DArray( m_pCuboid );
+}
+
+Void TCom3DAsymLUT::xUpdatePartitioning( Int nCurOctantDepth , Int nCurYPartNumLog2 )
+{
+  assert( nCurOctantDepth <= m_nMaxOctantDepth );
+  assert( nCurYPartNumLog2 <= m_nMaxYPartNumLog2 );
+
+  m_nCurOctantDepth = nCurOctantDepth;
+  m_nCurYPartNumLog2 = nCurYPartNumLog2;
+  m_nYShift2Idx = m_nInputBitDepthY - m_nCurOctantDepth - m_nCurYPartNumLog2;
+  m_nUShift2Idx = m_nVShift2Idx = m_nInputBitDepthC - m_nCurOctantDepth;
+  m_nMappingShift = m_nYShift2Idx + m_nUShift2Idx;
+  m_nMappingOffset = 1 << ( m_nMappingShift - 1 );
+}
+
+Void TCom3DAsymLUT::colorMapping( TComPicYuv * pcPic, TComPicYuv * pcPicDst )
+{
+  Int nWidth = pcPic->getWidth();
+  Int nHeight = pcPic->getHeight();
+  Int nStrideY = pcPic->getStride();
+  Int nStrideC = pcPic->getCStride();
+  Pel * pY = pcPic->getLumaAddr();
+  Pel * pU = pcPic->getCbAddr();
+  Pel * pV = pcPic->getCrAddr();
+
+  Int nDstStrideY = pcPicDst->getStride();
+  Int nDstStrideC = pcPicDst->getCStride();
+  Pel * pYDst = pcPicDst->getLumaAddr();
+  Pel * pUDst = pcPicDst->getCbAddr();
+  Pel * pVDst = pcPicDst->getCrAddr();
+
+  Pel *pUPrev = pU;
+  Pel *pVPrev = pV;
+  Pel *pUNext = pU+nStrideC;
+  Pel *pVNext = pV+nStrideC;
+
+  // alignment padding
+  pU += (nWidth>>1);
+  pV += (nWidth>>1);
+  for( Int y = 0 ; y < (nHeight>>1) ; y ++ )
+  {
+    *pU = pU[-1];
+    *pV = pV[-1];
+    pU += nStrideC;
+    pV += nStrideC;
+  }
+  memcpy(pU-(nWidth>>1), pU-(nWidth>>1)-nStrideC, ((nWidth>>1)+1)*sizeof(Pel));
+  memcpy(pV-(nWidth>>1), pV-(nWidth>>1)-nStrideC, ((nWidth>>1)+1)*sizeof(Pel));
+  pU = pcPic->getCbAddr();
+  pV = pcPic->getCrAddr();
+
+  Pel iMaxValY = (1<<getOutputBitDepthY())-1;
+  Pel iMaxValC = (1<<getOutputBitDepthC())-1;
+  for( Int y = 0 ; y < nHeight ; y += 2 )
+  {
+    for( Int xY = 0 , xC = 0 ; xY < nWidth ; xY += 2 , xC++ )
+    {
+      Pel srcY00 = pY[xY];
+      Pel srcY01 = pY[xY+1];
+      Pel srcY10 = pY[xY+nStrideY];
+      Pel srcY11 = pY[xY+nStrideY+1];
+      Pel srcYaver;
+      Pel srcU = pU[xC];
+      Pel srcV = pV[xC];
+      Pel dstY00, dstY01, dstY10, dstY11;
+
+      // alignment
+      srcYaver =  (srcY00 + srcY10 + 1 ) >> 1;
+      Pel srcUP0 = pUPrev[xC];
+      Pel srcVP0 = pVPrev[xC];        
+      Pel tmpU =  (srcUP0 + srcU + (srcU<<1) + 2 ) >> 2;
+      Pel tmpV =  (srcVP0 + srcV + (srcV<<1) + 2 ) >> 2;
+      dstY00 = xMapY( srcY00 , tmpU , tmpV );
+      Pel a = pU[xC+1] + srcU;
+      tmpU =  ((a<<1) + a + srcUP0 + pUPrev[xC+1] + 4 ) >> 3;
+      Pel b = pV[xC+1] + srcV;
+      tmpV =  ((b<<1) + b + srcVP0 + pVPrev[xC+1] + 4 ) >> 3;
+      dstY01 = xMapY( srcY01 , tmpU , tmpV );
+
+      srcUP0 = pUNext[xC];
+      srcVP0 = pVNext[xC];
+      tmpU =  (srcUP0 + srcU + (srcU<<1) + 2 ) >> 2;
+      tmpV =  (srcVP0 + srcV + (srcV<<1) + 2 ) >> 2;
+      dstY10 = xMapY( srcY10 , tmpU , tmpV );
+      tmpU =  ((a<<1) + a + srcUP0 + pUNext[xC+1] + 4 ) >> 3;
+      tmpV =  ((b<<1) + b + srcVP0 + pVNext[xC+1] + 4 ) >> 3;
+      dstY11 = xMapY( srcY11 , tmpU , tmpV );
+
+      SYUVP dstUV = xMapUV( srcYaver , srcU , srcV );
+      pYDst[xY] = Clip3((Pel)0, iMaxValY, dstY00 );
+      pYDst[xY+1] = Clip3((Pel)0, iMaxValY, dstY01 );
+      pYDst[xY+nDstStrideY] = Clip3((Pel)0, iMaxValY, dstY10 );
+      pYDst[xY+nDstStrideY+1] = Clip3((Pel)0, iMaxValY, dstY11 );
+      pUDst[xC] = Clip3((Pel)0, iMaxValC, dstUV.U );
+      pVDst[xC] = Clip3((Pel)0, iMaxValC, dstUV.V );
+    }
+    pY += nStrideY + nStrideY;
+
+    // alignment
+    pUPrev = pU;
+    pVPrev = pV;
+    pU = pUNext;
+    pV = pVNext;
+    pUNext += nStrideC;
+    pVNext += nStrideC;
+
+    pYDst += nDstStrideY + nDstStrideY;
+    pUDst += nDstStrideC;
+    pVDst += nDstStrideC;
+  }
+}
+
+SYUVP TCom3DAsymLUT::xGetCuboidVertexPredA( Int yIdx , Int uIdx , Int vIdx , Int nVertexIdx )
+{
+  assert( nVertexIdx < 4 );
+  
+  SYUVP sPred;
+  sPred.Y = ( yIdx + m_nVertexIdxOffset[nVertexIdx][0] ) << ( m_nYShift2Idx + m_nDeltaBitDepth );
+  sPred.U = ( uIdx + m_nVertexIdxOffset[nVertexIdx][1] ) << ( m_nUShift2Idx + m_nDeltaBitDepthC );
+  sPred.V = ( vIdx + m_nVertexIdxOffset[nVertexIdx][2] ) << ( m_nVShift2Idx + m_nDeltaBitDepthC );
+  return( sPred );
+}
+
+SYUVP  TCom3DAsymLUT::xGetCuboidVertexPredAll( Int yIdx , Int uIdx , Int vIdx , Int nVertexIdx , SCuboid *** pCurCuboid )
+{
+  SCuboid***  pCuboid = pCurCuboid ? pCurCuboid : m_pCuboid ;
+
+  // PredA
+  SYUVP sPredA = xGetCuboidVertexPredA( yIdx , uIdx , vIdx , nVertexIdx );
+
+  // PredB
+  SYUVP sPredB; 
+  memset( &sPredB , 0 , sizeof( sPredB ) );
+  if( yIdx > 0 )
+  {
+    SYUVP & recNeighborP = pCuboid[yIdx-1][uIdx][vIdx].P[nVertexIdx];
+    SYUVP sPredNeighbor = xGetCuboidVertexPredA( yIdx - 1 , uIdx , vIdx , nVertexIdx );
+    sPredB.Y += recNeighborP.Y - sPredNeighbor.Y ;
+    sPredB.U += recNeighborP.U - sPredNeighbor.U ;
+    sPredB.V += recNeighborP.V - sPredNeighbor.V ;
+
+    Pel min = - ( 1 << ( getOutputBitDepthY() - 2 ) );
+    Pel max =  - min /*- 1*/;
+    sPredB.Y = Clip3( min , max , sPredB.Y );
+    min = - ( 1 << ( getOutputBitDepthC() - 2 ) );
+    max =  - min /*- 1*/;
+    sPredB.U = Clip3( min , max , sPredB.U );
+    sPredB.V = Clip3( min , max , sPredB.V );
+  }
+
+  SYUVP sPred;
+  sPred.Y = sPredA.Y + sPredB.Y;
+  sPred.U = sPredA.U + sPredB.U;
+  sPred.V = sPredA.V + sPredB.V;
+
+  return sPred ;
+}
+
+SYUVP TCom3DAsymLUT::getCuboidVertexResTree( Int yIdx , Int uIdx , Int vIdx , Int nVertexIdx )
+{
+  const SYUVP & rYUVP = m_pCuboid[yIdx][uIdx][vIdx].P[nVertexIdx];
+  SYUVP sPred = xGetCuboidVertexPredAll( yIdx , uIdx , vIdx , nVertexIdx );
+
+  SYUVP sResidue;
+  sResidue.Y = ( rYUVP.Y - sPred.Y ) >> m_nResQuanBit;
+  sResidue.U = ( rYUVP.U - sPred.U ) >> m_nResQuanBit;
+  sResidue.V = ( rYUVP.V - sPred.V ) >> m_nResQuanBit;
+  return( sResidue );
+}
+
+Void TCom3DAsymLUT::setCuboidVertexResTree( Int yIdx , Int uIdx , Int vIdx , Int nVertexIdx , Int deltaY , Int deltaU , Int deltaV )
+{
+  SYUVP & rYUVP = m_pCuboid[yIdx][uIdx][vIdx].P[nVertexIdx];
+  SYUVP sPred = xGetCuboidVertexPredAll( yIdx , uIdx , vIdx , nVertexIdx );
+
+  rYUVP.Y = sPred.Y + ( deltaY << m_nResQuanBit );
+  rYUVP.U = sPred.U + ( deltaU << m_nResQuanBit );
+  rYUVP.V = sPred.V + ( deltaV << m_nResQuanBit );
+}
+
+Pel TCom3DAsymLUT::xMapY( Pel y , Pel u , Pel v )
+{
+  const SCuboid & rCuboid = m_pCuboid[y>>m_nYShift2Idx][u>>m_nUShift2Idx][v>>m_nVShift2Idx];
+  Pel dstY = rCuboid.P[0].Y;
+  Int deltaY = y - ( y >> m_nYShift2Idx << m_nYShift2Idx );
+  Int deltaU = u - ( u >> m_nUShift2Idx << m_nUShift2Idx );
+  Int deltaV = v - ( v >> m_nVShift2Idx << m_nVShift2Idx );
+  dstY += ( Pel )( ( ( ( deltaY * ( rCuboid.P[3].Y - rCuboid.P[2].Y ) ) << m_nUShift2Idx ) 
+                   + ( ( deltaU * ( rCuboid.P[1].Y - rCuboid.P[0].Y ) ) << m_nYShift2Idx )
+                   + ( ( deltaV * ( rCuboid.P[2].Y - rCuboid.P[1].Y ) ) << m_nYShift2Idx ) 
+                   + m_nMappingOffset ) >> m_nMappingShift );
+  return( dstY );
+}
+
+SYUVP TCom3DAsymLUT::xMapUV( Pel y , Pel u , Pel v )
+{
+  const SCuboid & rCuboid = m_pCuboid[y>>m_nYShift2Idx][u>>m_nUShift2Idx][v>>m_nVShift2Idx];
+  SYUVP dst = rCuboid.P[0];
+  Int deltaY = y - ( y >> m_nYShift2Idx << m_nYShift2Idx );
+  Int deltaU = u - ( u >> m_nUShift2Idx << m_nUShift2Idx );
+  Int deltaV = v - ( v >> m_nVShift2Idx << m_nVShift2Idx );
+  dst.U += ( Pel )( ( ( ( deltaY * ( rCuboid.P[3].U - rCuboid.P[2].U ) ) << m_nUShift2Idx ) 
+                    + ( ( deltaU * ( rCuboid.P[1].U - rCuboid.P[0].U ) ) << m_nYShift2Idx )
+                    + ( ( deltaV * ( rCuboid.P[2].U - rCuboid.P[1].U ) ) << m_nYShift2Idx ) 
+                    + m_nMappingOffset ) >> m_nMappingShift );
+  dst.V += ( Pel )( ( ( ( deltaY * ( rCuboid.P[3].V - rCuboid.P[2].V ) ) << m_nUShift2Idx ) 
+                    + ( ( deltaU * ( rCuboid.P[1].V - rCuboid.P[0].V ) ) << m_nYShift2Idx )
+                    + ( ( deltaV * ( rCuboid.P[2].V - rCuboid.P[1].V ) ) << m_nYShift2Idx ) 
+                    + m_nMappingOffset ) >> m_nMappingShift );
+  return( dst );
+}
+
+Void TCom3DAsymLUT::xSaveCuboids( SCuboid *** pSrcCuboid )
+{
+  memcpy( m_pCuboid[0][0] , pSrcCuboid[0][0] , sizeof( SCuboid ) * m_nYSize * m_nUSize * m_nVSize );
+}
+
+Void TCom3DAsymLUT::copy3DAsymLUT( TCom3DAsymLUT * pSrc )
+{
+  assert( pSrc->getMaxOctantDepth() == getMaxOctantDepth() && pSrc->getMaxYPartNumLog2() == getMaxYPartNumLog2() );
+  xUpdatePartitioning( pSrc->getCurOctantDepth() , pSrc->getCurYPartNumLog2() );
+  setResQuantBit( pSrc->getResQuantBit() );
+  xSaveCuboids( pSrc->m_pCuboid );
+}
+
+#endif
+
Index: /branches/SHM-6-dev/source/Lib/TLibCommon/TCom3DAsymLUT.h
===================================================================
--- /branches/SHM-6-dev/source/Lib/TLibCommon/TCom3DAsymLUT.h	(revision 677)
+++ /branches/SHM-6-dev/source/Lib/TLibCommon/TCom3DAsymLUT.h	(revision 677)
@@ -0,0 +1,135 @@
+
+#ifndef __TCOM3DASYMLUT__
+#define __TCOM3DASYMLUT__
+
+#include "TypeDef.h"
+
+#if Q0048_CGS_3D_ASYMLUT
+
+typedef struct _SYUVP
+{
+  Pel   Y , U , V;
+}SYUVP;
+
+typedef struct _SCuboid // vertexes for tetrahedral interpolation
+{
+  SYUVP P[4];     // YUV: P0(0,0,0), P1(0,1,0), P3(0,1,1), P7(1,1,1)
+}SCuboid;
+
+class TComPicYuv;
+
+class TCom3DAsymLUT
+{
+public:
+  TCom3DAsymLUT();
+  virtual ~TCom3DAsymLUT();
+
+  virtual Void  create( Int nMaxOctantDepth , Int nInputBitDepth , Int nInputBitDepthC , Int nOutputBitDepth , Int nOutputBitDepthC , Int nMaxYPartNumLog2 );
+  virtual Void  destroy();
+
+  Int   getMaxOctantDepth() { return m_nMaxOctantDepth; }
+  Int   getCurOctantDepth() { return m_nCurOctantDepth; }
+  Int   getInputBitDepthY()  { return m_nInputBitDepthY;  }
+  Int   getOutputBitDepthY()  { return m_nOutputBitDepthY;  }
+  Int   getInputBitDepthC()  { return m_nInputBitDepthC;  }
+  Int   getOutputBitDepthC()  { return m_nOutputBitDepthC;  }
+  Int   getResQuantBit()     { return m_nResQuanBit; }
+  Void  setResQuantBit(Int n){ m_nResQuanBit = n; }
+  Int   getMaxYPartNumLog2() { return m_nMaxYPartNumLog2; }
+  Int   getCurYPartNumLog2() { return m_nCurYPartNumLog2; }
+
+  Void  colorMapping( TComPicYuv * pcPicSrc,  TComPicYuv * pcPicDst );
+  Void  copy3DAsymLUT( TCom3DAsymLUT * pSrc );
+
+  SYUVP xGetCuboidVertexPredAll( Int yIdx , Int uIdx , Int vIdx , Int nVertexIdx , SCuboid *** pCurCuboid=NULL );
+  SYUVP getCuboidVertexResTree( Int yIdx , Int uIdx , Int vIdx , Int nVertexIdx );
+  Void  setCuboidVertexResTree( Int yIdx , Int uIdx , Int vIdx , Int nVertexIdx , Int deltaY , Int deltaU , Int deltaV );
+
+
+private:
+  Int   m_nMaxOctantDepth;
+  Int   m_nCurOctantDepth;
+  Int   m_nInputBitDepthY;
+  Int   m_nOutputBitDepthY;
+  Int   m_nInputBitDepthC;
+  Int   m_nOutputBitDepthC;
+  Int   m_nDeltaBitDepthC;
+  Int   m_nDeltaBitDepth;
+  Int   m_nMaxYPartNumLog2;
+  Int   m_nCurYPartNumLog2;
+  Int   m_nMaxPartNumLog2;
+  Int   m_nYSize;
+  Int   m_nUSize;
+  Int   m_nVSize;
+  Int   m_nYShift2Idx;
+  Int   m_nUShift2Idx;
+  Int   m_nVShift2Idx;
+  Int   m_nMappingShift;
+  Int   m_nMappingOffset;
+  Int   m_nResQuanBit;
+  SCuboid *** m_pCuboid;
+  const static Int m_nVertexIdxOffset[4][3];
+
+protected:
+  template <class T> 
+  Void xAllocate3DArray( T*** &p , Int xSize , Int ySize , Int zSize );
+  template <class T> 
+  Void xReset3DArray( T*** &p , Int xSize , Int ySize , Int zSize );
+  template <class T>
+  Void xFree3DArray( T *** &p );
+
+  Void  xUpdatePartitioning( Int nCurOctantDepth , Int nCurYPartNumLog2 );
+  SYUVP xGetCuboidVertexPredA( Int yIdx , Int uIdx , Int vIdx , Int nVertexIdx );
+  Pel   xMapY( Pel y , Pel u , Pel v );
+  SYUVP xMapUV( Pel y , Pel u , Pel v );
+  Int   xGetMaxPartNumLog2()  { return m_nMaxPartNumLog2; }
+  Int   xGetYSize()  { return m_nYSize;  }
+  Int   xGetUSize()  { return m_nUSize;  }
+  Int   xGetVSize()  { return m_nVSize;  }
+  Int   xGetYShift2Idx() { return m_nYShift2Idx; }
+  Int   xGetUShift2Idx() { return m_nUShift2Idx; }
+  Int   xGetVShift2Idx() { return m_nVShift2Idx; } 
+  SCuboid & xGetCuboid( Int yIdx , Int uIdx , Int vIdx ){ return m_pCuboid[yIdx][uIdx][vIdx];  }
+  Void  xSaveCuboids( SCuboid *** pSrcCuboid );
+};
+
+template <class T> 
+Void TCom3DAsymLUT::xAllocate3DArray( T *** &p , Int xSize , Int ySize , Int zSize )
+{
+  p = new T**[xSize];
+  p[0] = new T*[xSize*ySize];
+  for( Int x = 1 ; x < xSize ; x++ )
+    p[x] = p[x-1] + ySize;
+  p[0][0] = new T[xSize*ySize*zSize];
+  for( Int x = 0 ; x < xSize ; x++ )
+  {
+    for( Int y = 0 ; y < ySize ; y++ )
+      p[x][y] = p[0][0] + x * ySize * zSize + y * zSize;
+  }
+}
+
+template <class T>
+Void TCom3DAsymLUT::xFree3DArray( T *** &p )
+{
+  if( p != NULL )
+  {
+    if( p[0] != NULL )
+    {
+      if( p[0][0] != NULL )
+        delete [] p[0][0];
+      delete [] p[0];
+    }
+    delete [] p;
+    p = NULL;
+  }
+}
+
+template <class T>
+Void TCom3DAsymLUT::xReset3DArray( T*** &p , Int xSize , Int ySize , Int zSize )
+{
+  memset( p[0][0] , 0 , sizeof( T ) * xSize * ySize * zSize );
+}
+
+#endif
+
+#endif
Index: /branches/SHM-6-dev/source/Lib/TLibCommon/TComPic.h
===================================================================
--- /branches/SHM-6-dev/source/Lib/TLibCommon/TComPic.h	(revision 676)
+++ /branches/SHM-6-dev/source/Lib/TLibCommon/TComPic.h	(revision 677)
@@ -89,4 +89,7 @@
   TComPicYuv*           m_pcFullPelBaseRec[MAX_LAYERS];    // upsampled base layer recontruction for difference domain inter prediction
 #endif
+#if Q0048_CGS_3D_ASYMLUT
+  Int                   m_nFrameBit;
+#endif
 
 public:
@@ -220,4 +223,8 @@
 #endif
 
+#if Q0048_CGS_3D_ASYMLUT
+  Void  setFrameBit( Int n )  { m_nFrameBit = n;    }
+  Int   getFrameBit()         { return m_nFrameBit; }
+#endif
 };// END CLASS DEFINITION TComPic
 
Index: /branches/SHM-6-dev/source/Lib/TLibCommon/TComSlice.h
===================================================================
--- /branches/SHM-6-dev/source/Lib/TLibCommon/TComSlice.h	(revision 676)
+++ /branches/SHM-6-dev/source/Lib/TLibCommon/TComSlice.h	(revision 677)
@@ -1744,4 +1744,9 @@
   Bool     m_pocResetInfoPresentFlag;
 #endif
+#if Q0048_CGS_3D_ASYMLUT
+  Int      m_nCGSFlag;
+  Int      m_nCGSOutputBitDepthY; // not for syntax
+  Int      m_nCGSOutputBitDepthC; // not for syntax
+#endif
 #endif
 
@@ -1884,4 +1889,12 @@
   Bool getPocResetInfoPresentFlag   ()                    { return m_pocResetInfoPresentFlag; }
   Void setPocResetInfoPresentFlag   (const Bool val)      { m_pocResetInfoPresentFlag = val; }
+#endif
+#if Q0048_CGS_3D_ASYMLUT
+  Int     getCGSFlag()     { return m_nCGSFlag;  }
+  Void    setCGSFlag(Int n){ m_nCGSFlag = n;     }
+  Int     getCGSOutputBitDepthY()     { return m_nCGSOutputBitDepthY;  }
+  Void    setCGSOutputBitDepthY(Int n){ m_nCGSOutputBitDepthY = n;     }
+  Int     getCGSOutputBitDepthC()     { return m_nCGSOutputBitDepthC;  }
+  Void    setCGSOutputBitDepthC(Int n){ m_nCGSOutputBitDepthC = n;     }
 #endif
 };
@@ -2047,4 +2060,7 @@
   Bool        m_pocMsbValRequiredFlag;
   Bool        m_pocMsbValPresentFlag;
+#endif
+#if Q0048_CGS_3D_ASYMLUT
+  Int        m_nCGSOverWritePPS;  // for optimization, not output to bitstream
 #endif
 #endif //SVC_EXTENSION
@@ -2164,4 +2180,8 @@
 #if SVC_EXTENSION
   Void      setRefPicList       ( TComList<TComPic*>& rcListPic, Bool checkNumPocTotalCurr = false, TComPic** ilpPic = NULL );
+#if Q0048_CGS_3D_ASYMLUT
+  Int       getCGSOverWritePPS()              { return m_nCGSOverWritePPS;    }
+  Void      setCGSOverWritePPS(Int n)         { m_nCGSOverWritePPS = n;       }
+#endif
 #else
   Void      setRefPicList       ( TComList<TComPic*>& rcListPic, Bool checkNumPocTotalCurr = false );
Index: /branches/SHM-6-dev/source/Lib/TLibCommon/TComUpsampleFilter.cpp
===================================================================
--- /branches/SHM-6-dev/source/Lib/TLibCommon/TComUpsampleFilter.cpp	(revision 676)
+++ /branches/SHM-6-dev/source/Lib/TLibCommon/TComUpsampleFilter.cpp	(revision 677)
@@ -172,4 +172,11 @@
 #if O0194_JOINT_US_BITSHIFT
     Int shift = g_bitDepthYLayer[currLayerId] - g_bitDepthYLayer[refLayerId];
+#if Q0048_CGS_3D_ASYMLUT
+    if( currSlice->getPPS()->getCGSFlag() )
+    {
+      shift = g_bitDepthYLayer[currLayerId] - currSlice->getPPS()->getCGSOutputBitDepthY();
+    }
+    assert( shift >= 0 );
+#endif
 #endif
 
@@ -205,4 +212,10 @@
 #if O0194_JOINT_US_BITSHIFT
     shift = g_bitDepthCLayer[currLayerId] - g_bitDepthCLayer[refLayerId];
+#if Q0048_CGS_3D_ASYMLUT
+    if( currSlice->getPPS()->getCGSFlag() )
+    {
+      shift = g_bitDepthCLayer[currLayerId] - currSlice->getPPS()->getCGSOutputBitDepthC();
+    }
+#endif
 #endif
 
@@ -297,4 +310,10 @@
     // g_bitDepthY was set to EL bit-depth, but shift1 should be calculated using BL bit-depth
     Int shift1 = g_bitDepthYLayer[refLayerId] - 8;
+#if Q0048_CGS_3D_ASYMLUT
+    if( currSlice->getPPS()->getCGSFlag() )
+    {
+      shift1 = currSlice->getPPS()->getCGSOutputBitDepthY() - 8;
+    }
+#endif
 #else
     Int shift1 = g_bitDepthY - 8;
@@ -444,4 +463,10 @@
     // g_bitDepthC was set to EL bit-depth, but shift1 should be calculated using BL bit-depth
     shift1 = g_bitDepthCLayer[refLayerId] - 8;
+#if Q0048_CGS_3D_ASYMLUT
+    if( currSlice->getPPS()->getCGSFlag() )
+    {
+      shift1 = currSlice->getPPS()->getCGSOutputBitDepthC() - 8;
+    }
+#endif
 #else
     shift1 = g_bitDepthC - 8;
Index: /branches/SHM-6-dev/source/Lib/TLibCommon/TypeDef.h
===================================================================
--- /branches/SHM-6-dev/source/Lib/TLibCommon/TypeDef.h	(revision 676)
+++ /branches/SHM-6-dev/source/Lib/TLibCommon/TypeDef.h	(revision 677)
@@ -86,5 +86,12 @@
 #define O0194_JOINT_US_BITSHIFT          1      ///< JCTVC-O0194: Joint Upsampling and bit-shift
 #endif
+#define Q0048_CGS_3D_ASYMLUT                   1
+#if Q0048_CGS_3D_ASYMLUT
+#define Q0048_CGS_3D_ASYMLUT_OFF               0
+#define Q0048_CGS_3D_ASYMLUT_PPSUPDATE         1
+#define O0194_WEIGHTED_PREDICTION_CGS    0
+#else
 #define O0194_WEIGHTED_PREDICTION_CGS    1      ///< JCTVC-O0194: Weighted prediciton for color gamut scalability
+#endif
 #define MFM_ENCCONSTRAINT                1      ///< JCTVC-O0216: Encoder constraint for motion field mapping
 #define VPS_NUH_LAYER_ID                 1      ///< JCTVC-N0085: Assert that the nuh_layer_id of VPS NAL unit should be 0
Index: /branches/SHM-6-dev/source/Lib/TLibDecoder/TDecCAVLC.cpp
===================================================================
--- /branches/SHM-6-dev/source/Lib/TLibDecoder/TDecCAVLC.cpp	(revision 676)
+++ /branches/SHM-6-dev/source/Lib/TLibDecoder/TDecCAVLC.cpp	(revision 677)
@@ -39,4 +39,7 @@
 #include "SEIread.h"
 #include "TDecSlice.h"
+#if Q0048_CGS_3D_ASYMLUT
+#include "../TLibCommon/TCom3DAsymLUT.h"
+#endif
 
 //! \ingroup TLibDecoder
@@ -175,5 +178,9 @@
 }
 
-Void TDecCavlc::parsePPS(TComPPS* pcPPS)
+Void TDecCavlc::parsePPS(TComPPS* pcPPS
+#if Q0048_CGS_3D_ASYMLUT
+  , TCom3DAsymLUT * pc3DAsymLUT , Int nLayerID
+#endif
+  )
 {
 #if ENC_DEC_TRACE
@@ -348,4 +355,14 @@
       READ_FLAG( uiCode, "poc_reset_info_present_flag" );
       pcPPS->setPocResetInfoPresentFlag(uiCode ? true : false);
+#if Q0048_CGS_3D_ASYMLUT
+      READ_FLAG( uiCode , "colour_mapping_enabled_flag" ); 
+      pcPPS->setCGSFlag( uiCode );
+      if( pcPPS->getCGSFlag() == Q0048_CGS_3D_ASYMLUT_PPSUPDATE )
+      {
+        xParse3DAsymLUT( pc3DAsymLUT );
+        pcPPS->setCGSOutputBitDepthY( pc3DAsymLUT->getOutputBitDepthY() );
+        pcPPS->setCGSOutputBitDepthC( pc3DAsymLUT->getOutputBitDepthC() );
+      }
+#endif
 #endif
     }
@@ -3720,4 +3737,65 @@
 }
 
+#if Q0048_CGS_3D_ASYMLUT
+Void TDecCavlc::xParse3DAsymLUT( TCom3DAsymLUT * pc3DAsymLUT )
+{
+  UInt uiCurOctantDepth , uiCurPartNumLog2 , uiInputBitDepthM8 , uiOutputBitDepthM8 , uiResQaunBit;
+  READ_CODE( 2 , uiCurOctantDepth , "cm_octant_depth" ); 
+  READ_CODE( 2 , uiCurPartNumLog2 , "cm_y_part_num_log2" );     
+  READ_CODE( 3 , uiInputBitDepthM8 , "cm_input_bit_depth_minus8" );
+  Int iInputBitDepthCDelta;
+  READ_SVLC(iInputBitDepthCDelta, "cm_input_bit_depth_chroma delta");
+  READ_CODE( 3 , uiOutputBitDepthM8 , "cm_output_bit_depth_minus8" ); 
+  Int iOutputBitDepthCDelta;
+  READ_SVLC(iOutputBitDepthCDelta, "cm_output_bit_depth_chroma_delta");
+  READ_CODE( 2 , uiResQaunBit , "cm_res_quant_bit" );
+  pc3DAsymLUT->destroy();
+  pc3DAsymLUT->create( uiCurOctantDepth , uiInputBitDepthM8 + 8 ,  uiInputBitDepthM8 + 8 + iInputBitDepthCDelta, uiOutputBitDepthM8 + 8 , uiOutputBitDepthM8 + 8 + iOutputBitDepthCDelta ,uiCurPartNumLog2 );
+  pc3DAsymLUT->setResQuantBit( uiResQaunBit );
+
+  xParse3DAsymLUTOctant( pc3DAsymLUT , 0 , 0 , 0 , 0 , 1 << pc3DAsymLUT->getCurOctantDepth() );
+}
+
+Void TDecCavlc::xParse3DAsymLUTOctant( TCom3DAsymLUT * pc3DAsymLUT , Int nDepth , Int yIdx , Int uIdx , Int vIdx , Int nLength )
+{
+  UInt uiOctantSplit = nDepth < pc3DAsymLUT->getCurOctantDepth();
+  if( nDepth < pc3DAsymLUT->getCurOctantDepth() )
+    READ_FLAG( uiOctantSplit , "split_octant_flag" );
+  Int nYPartNum = 1 << pc3DAsymLUT->getCurYPartNumLog2();
+  if( uiOctantSplit )
+  {
+    Int nHalfLength = nLength >> 1;
+    for( Int l = 0 ; l < 2 ; l++ )
+    {
+      for( Int m = 0 ; m < 2 ; m++ )
+      {
+        for( Int n = 0 ; n < 2 ; n++ )
+        {
+          xParse3DAsymLUTOctant( pc3DAsymLUT , nDepth + 1 , yIdx + l * nHalfLength * nYPartNum , uIdx + m * nHalfLength , vIdx + n * nHalfLength , nHalfLength );
+        }
+      }
+    }
+  }
+  else
+  {
+    for( Int l = 0 ; l < nYPartNum ; l++ )
+    {
+      for( Int nVertexIdx = 0 ; nVertexIdx < 4 ; nVertexIdx++ )
+      {
+        UInt uiCodeVertex = 0;
+        Int deltaY = 0 , deltaU = 0 , deltaV = 0;
+        READ_FLAG( uiCodeVertex , "coded_vertex_flag" );
+        if( uiCodeVertex )
+        {
+          READ_SVLC( deltaY , "resY" );
+          READ_SVLC( deltaU , "resU" );
+          READ_SVLC( deltaV , "resV" );
+        }
+        pc3DAsymLUT->setCuboidVertexResTree( yIdx + l , uIdx , vIdx , nVertexIdx , deltaY , deltaU , deltaV );
+      }
+    }
+  }
+}
+#endif
 //! \}
 
Index: /branches/SHM-6-dev/source/Lib/TLibDecoder/TDecCAVLC.h
===================================================================
--- /branches/SHM-6-dev/source/Lib/TLibDecoder/TDecCAVLC.h	(revision 676)
+++ /branches/SHM-6-dev/source/Lib/TLibDecoder/TDecCAVLC.h	(revision 677)
@@ -46,4 +46,7 @@
 #include "SyntaxElementParser.h"
 
+#if Q0048_CGS_3D_ASYMLUT
+class TCom3DAsymLUT;
+#endif
 //! \ingroup TLibDecoder
 //! \{
@@ -97,5 +100,9 @@
   Void  parseSPS            ( TComSPS* pcSPS );
 #endif //SVC_EXTENSION
-  Void  parsePPS            ( TComPPS* pcPPS);
+  Void  parsePPS            ( TComPPS* pcPPS
+#if Q0048_CGS_3D_ASYMLUT
+    , TCom3DAsymLUT * pc3DAsymLUT , Int nLayerID
+#endif
+    );
   Void  parseVUI            ( TComVUI* pcVUI, TComSPS* pcSPS );
   Void  parseSEI            ( SEIMessages& );
@@ -137,4 +144,9 @@
 protected:
   Bool  xMoreRbspData();
+
+#if Q0048_CGS_3D_ASYMLUT
+  Void xParse3DAsymLUT( TCom3DAsymLUT * pc3DAsymLUT );
+  Void xParse3DAsymLUTOctant( TCom3DAsymLUT * pc3DAsymLUT , Int nDepth , Int yIdx , Int uIdx , Int vIdx , Int nLength );
+#endif
 };
 
Index: /branches/SHM-6-dev/source/Lib/TLibDecoder/TDecEntropy.h
===================================================================
--- /branches/SHM-6-dev/source/Lib/TLibDecoder/TDecEntropy.h	(revision 676)
+++ /branches/SHM-6-dev/source/Lib/TLibDecoder/TDecEntropy.h	(revision 677)
@@ -49,4 +49,7 @@
 class TDecCavlc;
 class ParameterSetManagerDecoder;
+#if Q0048_CGS_3D_ASYMLUT
+class TCom3DAsymLUT;
+#endif
 
 //! \ingroup TLibDecoder
@@ -71,5 +74,9 @@
   virtual Void  parseSPS                  ( TComSPS* pcSPS )                                      = 0;
 #endif
-  virtual Void  parsePPS                  ( TComPPS* pcPPS )                                      = 0;
+  virtual Void  parsePPS                  ( TComPPS* pcPPS 
+#if Q0048_CGS_3D_ASYMLUT
+    , TCom3DAsymLUT * pc3DAsymLUT , Int nLayerID
+#endif
+    )                                      = 0;
 
   virtual Void parseSliceHeader          ( TComSlice*& rpcSlice, ParameterSetManagerDecoder *parameterSetManager)       = 0;
@@ -138,5 +145,13 @@
   Void    decodeSPS                   ( TComSPS* pcSPS     )    { m_pcEntropyDecoderIf->parseSPS(pcSPS);                    }
 #endif
-  Void    decodePPS                   ( TComPPS* pcPPS )    { m_pcEntropyDecoderIf->parsePPS(pcPPS);                    }
+  Void    decodePPS                   ( TComPPS* pcPPS 
+#if Q0048_CGS_3D_ASYMLUT
+    , TCom3DAsymLUT * pc3DAsymLUT , Int nLayerID
+#endif
+    )    { m_pcEntropyDecoderIf->parsePPS(pcPPS
+#if Q0048_CGS_3D_ASYMLUT
+    , pc3DAsymLUT , nLayerID
+#endif
+    );                    }
   Void    decodeSliceHeader           ( TComSlice*& rpcSlice, ParameterSetManagerDecoder *parameterSetManager)  { m_pcEntropyDecoderIf->parseSliceHeader(rpcSlice, parameterSetManager);         }
 
Index: /branches/SHM-6-dev/source/Lib/TLibDecoder/TDecSbac.h
===================================================================
--- /branches/SHM-6-dev/source/Lib/TLibDecoder/TDecSbac.h	(revision 676)
+++ /branches/SHM-6-dev/source/Lib/TLibDecoder/TDecSbac.h	(revision 677)
@@ -81,5 +81,9 @@
   Void  parseSPS                  ( TComSPS* /*pcSPS*/ ) {}
 #endif
-  Void  parsePPS                  ( TComPPS* /*pcPPS*/ ) {}
+  Void  parsePPS                  ( TComPPS* /*pcPPS*/ 
+#if Q0048_CGS_3D_ASYMLUT
+    , TCom3DAsymLUT * /*pc3DAsymLUT*/ , Int /*nLayerID*/
+#endif
+    ) {}
 
   Void  parseSliceHeader          ( TComSlice*& /*rpcSlice*/, ParameterSetManagerDecoder* /*parameterSetManager*/) {}
Index: /branches/SHM-6-dev/source/Lib/TLibDecoder/TDecTop.cpp
===================================================================
--- /branches/SHM-6-dev/source/Lib/TLibDecoder/TDecTop.cpp	(revision 676)
+++ /branches/SHM-6-dev/source/Lib/TLibDecoder/TDecTop.cpp	(revision 677)
@@ -93,4 +93,7 @@
   m_subDpbIdx = -1;
 #endif
+#if Q0048_CGS_3D_ASYMLUT
+  m_pColorMappedPic = NULL;
+#endif
 }
 
@@ -99,4 +102,12 @@
 #if ENC_DEC_TRACE
   fclose( g_hTrace );
+#endif
+#if Q0048_CGS_3D_ASYMLUT
+  if(m_pColorMappedPic)
+  {
+    m_pColorMappedPic->destroy();
+    delete m_pColorMappedPic;
+    m_pColorMappedPic = NULL;
+  }
 #endif
 }
@@ -357,5 +368,9 @@
         Bool sameBitDepths = ( g_bitDepthYLayer[m_layerId] == g_bitDepthYLayer[refLayerId] ) && ( g_bitDepthCLayer[m_layerId] == g_bitDepthCLayer[refLayerId] );
 
-        if( pcPicYuvRecBase->getWidth() != pcSlice->getPicWidthInLumaSamples() || pcPicYuvRecBase->getHeight() != pcSlice->getPicHeightInLumaSamples() || !zeroOffsets || !sameBitDepths )
+        if( pcPicYuvRecBase->getWidth() != pcSlice->getPicWidthInLumaSamples() || pcPicYuvRecBase->getHeight() != pcSlice->getPicHeightInLumaSamples() || !zeroOffsets || !sameBitDepths 
+#if Q0048_CGS_3D_ASYMLUT
+          || pcSlice->getPPS()->getCGSFlag() > 0
+#endif
+          )
 #else
         if(pcPicYuvRecBase->getWidth() != pcSlice->getPicWidthInLumaSamples() || pcPicYuvRecBase->getHeight() != pcSlice->getPicHeightInLumaSamples() || !zeroOffsets )
@@ -1533,4 +1548,14 @@
         g_posScalingFactor[refLayerIdc][1] = ((heightBL << 16) + (heightEL >> 1)) / heightEL;
 
+#if Q0048_CGS_3D_ASYMLUT 
+        TComPicYuv* pBaseColRec = pcSlice->getBaseColPic(refLayerIdc)->getPicYuvRec();
+        if( pcSlice->getPPS()->getCGSFlag() != Q0048_CGS_3D_ASYMLUT_OFF )
+        {
+          if(!m_pColorMappedPic)
+            initAsymLut(pcSlice->getBaseColPic(refLayerIdc)->getSlice(0));
+          m_c3DAsymLUTPPS.colorMapping( pcSlice->getBaseColPic(refLayerIdc)->getPicYuvRec(),  m_pColorMappedPic );
+          pBaseColRec = m_pColorMappedPic;
+        }
+#endif
 #if SVC_UPSAMPLING
         if( pcPic->isSpatialEnhLayer(refLayerIdc) )
@@ -1543,13 +1568,29 @@
 #if O0215_PHASE_ALIGNMENT
 #if O0194_JOINT_US_BITSHIFT
+#if Q0048_CGS_3D_ASYMLUT 
+          m_cPrediction.upsampleBasePic( pcSlice, refLayerIdc, pcPic->getFullPelBaseRec(refLayerIdc), pBaseColRec, pcPic->getPicYuvRec(), scalEL, pcSlice->getVPS()->getPhaseAlignFlag() );
+#else
           m_cPrediction.upsampleBasePic( pcSlice, refLayerIdc, pcPic->getFullPelBaseRec(refLayerIdc), pcSlice->getBaseColPic(refLayerIdc)->getPicYuvRec(), pcPic->getPicYuvRec(), scalEL, pcSlice->getVPS()->getPhaseAlignFlag() );
+#endif
+#else
+#if Q0048_CGS_3D_ASYMLUT 
+          m_cPrediction.upsampleBasePic( refLayerIdc, pcPic->getFullPelBaseRec(refLayerIdc), pBaseColRec, pcPic->getPicYuvRec(), pcSlice->getSPS()->getScaledRefLayerWindow(refLayerIdc), pcSlice->getVPS()->getPhaseAlignFlag() );
 #else
           m_cPrediction.upsampleBasePic( refLayerIdc, pcPic->getFullPelBaseRec(refLayerIdc), pcSlice->getBaseColPic(refLayerIdc)->getPicYuvRec(), pcPic->getPicYuvRec(), scalEL, pcSlice->getVPS()->getPhaseAlignFlag() );
 #endif
+#endif
 #else
 #if O0194_JOINT_US_BITSHIFT
+#if Q0048_CGS_3D_ASYMLUT 
+          m_cPrediction.upsampleBasePic( pcSlice, refLayerIdc, pcPic->getFullPelBaseRec(refLayerIdc), pBaseColRec, pcPic->getPicYuvRec(), scalEL );
+#else
           m_cPrediction.upsampleBasePic( pcSlice, refLayerIdc, pcPic->getFullPelBaseRec(refLayerIdc), pcSlice->getBaseColPic(refLayerIdc)->getPicYuvRec(), pcPic->getPicYuvRec(), scalEL );
+#endif
+#else
+#if Q0048_CGS_3D_ASYMLUT 
+          m_cPrediction.upsampleBasePic( refLayerIdc, pcPic->getFullPelBaseRec(refLayerIdc), pBaseColRec, pcPic->getPicYuvRec(), scalEL );
 #else
           m_cPrediction.upsampleBasePic( refLayerIdc, pcPic->getFullPelBaseRec(refLayerIdc), pcSlice->getBaseColPic(refLayerIdc)->getPicYuvRec(), pcPic->getPicYuvRec(), scalEL );
+#endif
 #endif
 #endif
@@ -1763,5 +1804,9 @@
 }
 
-Void TDecTop::xDecodePPS()
+Void TDecTop::xDecodePPS(
+#if Q0048_CGS_3D_ASYMLUT
+  TCom3DAsymLUT * pc3DAsymLUT
+#endif
+  )
 {
   TComPPS* pps = new TComPPS();
@@ -1771,5 +1816,9 @@
 #endif
 
-  m_cEntropyDecoder.decodePPS( pps );
+  m_cEntropyDecoder.decodePPS( pps 
+#if Q0048_CGS_3D_ASYMLUT
+    , pc3DAsymLUT , m_layerId 
+#endif
+    );
   m_parameterSetManagerDecoder.storePrefetchedPPS( pps );
 
@@ -1949,5 +1998,9 @@
 
     case NAL_UNIT_PPS:
-      xDecodePPS();
+      xDecodePPS(
+#if Q0048_CGS_3D_ASYMLUT
+        &m_c3DAsymLUTPPS
+#endif
+        );
       return false;
       
@@ -2313,4 +2366,20 @@
 }
 #endif
+
+#if Q0048_CGS_3D_ASYMLUT
+Void TDecTop::initAsymLut(TComSlice *pcSlice)
+{
+  if(m_layerId>0)
+  {
+    if(!m_pColorMappedPic)
+    {
+      Int picWidth    = pcSlice->getPicWidthInLumaSamples();
+      Int picHeight   = pcSlice->getPicHeightInLumaSamples();
+      m_pColorMappedPic = new TComPicYuv;
+      m_pColorMappedPic->create( picWidth, picHeight, pcSlice->getChromaFormatIdc()/*CHROMA_420*/, g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth, NULL );
+    }
+  }
+}
+#endif
 #endif //SVC_EXTENSION
 //! \}
Index: /branches/SHM-6-dev/source/Lib/TLibDecoder/TDecTop.h
===================================================================
--- /branches/SHM-6-dev/source/Lib/TLibDecoder/TDecTop.h	(revision 676)
+++ /branches/SHM-6-dev/source/Lib/TLibDecoder/TDecTop.h	(revision 677)
@@ -45,4 +45,7 @@
 #include "TLibCommon/TComTrQuant.h"
 #include "TLibCommon/SEI.h"
+#if Q0048_CGS_3D_ASYMLUT
+#include "TLibCommon/TCom3DAsymLUT.h"
+#endif
 
 #include "TDecGop.h"
@@ -79,4 +82,8 @@
   // functional classes
   TComPrediction          m_cPrediction;
+#if Q0048_CGS_3D_ASYMLUT
+  TCom3DAsymLUT           m_c3DAsymLUTPPS;
+  TComPicYuv*             m_pColorMappedPic;
+#endif
   TComTrQuant             m_cTrQuant;
   TDecGop                 m_cGopDecoder;
@@ -268,5 +275,9 @@
   Void      xDecodeVPS();
   Void      xDecodeSPS();
-  Void      xDecodePPS();
+  Void      xDecodePPS(
+#if Q0048_CGS_3D_ASYMLUT
+    TCom3DAsymLUT * pc3DAsymLUT
+#endif
+    );
   Void      xDecodeSEI( TComInputBitstream* bs, const NalUnitType nalUnitType );
 
@@ -279,4 +290,7 @@
   Void setFirstPicInLayerDecodedFlag(Bool x) { m_firstPicInLayerDecodedFlag = x;   }
 #endif
+#if Q0048_CGS_3D_ASYMLUT
+  Void initAsymLut(TComSlice *pcSlice);
+#endif
 };// END CLASS DEFINITION TDecTop
 
Index: /branches/SHM-6-dev/source/Lib/TLibEncoder/TEnc3DAsymLUT.cpp
===================================================================
--- /branches/SHM-6-dev/source/Lib/TLibEncoder/TEnc3DAsymLUT.cpp	(revision 677)
+++ /branches/SHM-6-dev/source/Lib/TLibEncoder/TEnc3DAsymLUT.cpp	(revision 677)
@@ -0,0 +1,450 @@
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <cmath>
+#include <algorithm>
+
+#include "TEnc3DAsymLUT.h"
+
+#if Q0048_CGS_3D_ASYMLUT
+
+TEnc3DAsymLUT::TEnc3DAsymLUT()
+{
+  m_pColorInfo = NULL;
+  m_pColorInfoC = NULL;
+  m_pEncCuboid = NULL;
+  m_pBestEncCuboid = NULL;
+  memset( m_nPrevFrameBit , 0 , sizeof( m_nPrevFrameBit ) );
+  memset( m_nPrevFrameCGSBit , 0 , sizeof( m_nPrevFrameCGSBit ) );
+  memset( m_nPrevFrameCGSPartNumLog2 , 0 , sizeof( m_nPrevFrameCGSPartNumLog2 ) );
+  memset( m_nPrevFrameOverWritePPS , 0 , sizeof( m_nPrevFrameOverWritePPS ) );
+  m_dTotalFrameBit = 0;
+  m_nTotalCGSBit = 0;
+  m_nPPSBit = 0;
+  m_pDsOrigPic = NULL;
+}
+
+Void TEnc3DAsymLUT::create( Int nMaxOctantDepth , Int nInputBitDepth , Int nInputBitDepthC , Int nOutputBitDepth , Int nOutputBitDepthC , Int nMaxYPartNumLog2 )
+{
+  if( m_pColorInfo != NULL )
+    destroy();
+  TCom3DAsymLUT::create( nMaxOctantDepth , nInputBitDepth , nInputBitDepthC, nOutputBitDepth , nOutputBitDepthC, nMaxYPartNumLog2 );
+  xAllocate3DArray( m_pColorInfo , xGetYSize() , xGetUSize() , xGetVSize() );
+  xAllocate3DArray( m_pColorInfoC , xGetYSize() , xGetUSize() , xGetVSize() );
+  xAllocate3DArray( m_pEncCuboid , xGetYSize() , xGetUSize() , xGetVSize() );
+  xAllocate3DArray( m_pBestEncCuboid , xGetYSize() , xGetUSize() , xGetVSize() );
+}
+
+Void TEnc3DAsymLUT::destroy()
+{
+  xFree3DArray( m_pColorInfo );
+  xFree3DArray( m_pColorInfoC );
+  xFree3DArray( m_pEncCuboid );
+  xFree3DArray( m_pBestEncCuboid );
+  TCom3DAsymLUT::destroy();
+}
+
+TEnc3DAsymLUT::~TEnc3DAsymLUT()
+{
+  if( m_dTotalFrameBit != 0 )
+    printf( "\nTotal CGS bit: %d, %.2lf%%" , m_nTotalCGSBit , m_nTotalCGSBit * 100 / m_dTotalFrameBit );
+  destroy();
+}
+
+Double TEnc3DAsymLUT::xxDeriveVertexPerColor( Double N , Double Ys , Double Yy , Double Yu , Double Yv , Double ys , Double us , Double vs , Double yy , Double yu , Double yv , Double uu , Double uv , Double vv , Double YY ,
+  Int y0 , Int u0 , Int v0 , Int nLengthY , Int nLengthUV ,
+  Pel & rP0 , Pel & rP1 , Pel & rP3 , Pel & rP7 , Int nResQuantBit )
+{
+  Int nInitP0 = rP0;
+  Int nInitP1 = rP1;
+  Int nInitP3 = rP3;
+  Int nInitP7 = rP7;
+
+  Double dNorm = (N * yy * vv * uu - N * yy * uv * uv - N * yv * yv * uu - N * vv * yu * yu + 2 * N * yv * uv * yu - yy * vs * vs * uu + 2 * yy * vs * uv * us - yy * vv * us * us - 2 * vs * uv * yu * ys + uv * uv * ys * ys + vs * vs * yu * yu - 2 * yv * vs * us * yu + 2 * yv * vs * ys * uu - 2 * yv * uv * us * ys + 2 * vv * yu * ys * us - vv * uu * ys * ys + yv * yv * us * us);
+  if( N > 16 && dNorm != 0 )
+  {
+    Double dInitA = (-N * uu * yv * Yv + N * uu * Yy * vv - N * Yy * uv * uv + N * yv * uv * Yu - N * yu * Yu * vv + N * yu * uv * Yv + yu * us * Ys * vv - vs * ys * uv * Yu - yu * vs * us * Yv - yv * uv * us * Ys - yv * vs * us * Yu - yu * uv * vs * Ys - ys * us * uv * Yv + ys * us * Yu * vv + 2 * Yy * vs * uv * us + uu * yv * vs * Ys - uu * ys * Ys * vv + uu * vs * ys * Yv + ys * Ys * uv * uv - Yy * vv * us * us + yu * Yu * vs * vs + yv * Yv * us * us - uu * Yy * vs * vs) / dNorm;
+    Double dInitB = (N * yy * Yu * vv - N * yy * uv * Yv - N * Yu * yv * yv - N * yu * Yy * vv + N * uv * yv * Yy + N * yv * yu * Yv - yy * us * Ys * vv + yy * uv * vs * Ys - yy * Yu * vs * vs + yy * vs * us * Yv - uv * vs * ys * Yy - yv * yu * vs * Ys + yu * Yy * vs * vs + yu * ys * Ys * vv - uv * yv * ys * Ys + 2 * Yu * yv * vs * ys + us * ys * Yy * vv - vs * ys * yu * Yv + uv * ys * ys * Yv + us * Ys * yv * yv - Yu * ys * ys * vv - yv * ys * us * Yv - vs * us * yv * Yy) / dNorm;
+    Double dInitC = -(-N * yy * Yv * uu + N * yy * uv * Yu - N * yv * yu * Yu - N * uv * yu * Yy + N * Yv * yu * yu + N * yv * Yy * uu - yy * uv * us * Ys + yy * Yv * us * us + yy * vs * Ys * uu - yy * vs * us * Yu + yv * ys * us * Yu - vs * Ys * yu * yu - yv * ys * Ys * uu + vs * us * yu * Yy + vs * ys * yu * Yu - uv * Yu * ys * ys + Yv * uu * ys * ys - yv * Yy * us * us - 2 * Yv * yu * ys * us - vs * ys * Yy * uu + uv * us * ys * Yy + uv * yu * ys * Ys + yv * yu * us * Ys) / dNorm;
+    Double dInitD = (-uu * yy * vs * Yv + uu * yy * Ys * vv + uu * vs * yv * Yy - uu * ys * Yy * vv + uu * ys * yv * Yv - uu * Ys * yv * yv + yy * vs * uv * Yu + yy * us * uv * Yv - yy * Ys * uv * uv - yy * us * Yu * vv + ys * yu * Yu * vv + vs * Yv * yu * yu + ys * Yy * uv * uv - us * yu * yv * Yv + us * yu * Yy * vv + 2 * Ys * yv * uv * yu - vs * uv * yu * Yy - vs * yv * yu * Yu - Ys * vv * yu * yu - us * uv * yv * Yy - ys * yv * uv * Yu - ys * yu * uv * Yv + us * Yu * yv * yv) / dNorm;
+    nInitP0 = xxCoeff2Vertex( dInitA , dInitB , dInitC , dInitD , y0 , u0 , v0 ) >> nResQuantBit  << nResQuantBit ; 
+    nInitP1 = xxCoeff2Vertex( dInitA , dInitB , dInitC , dInitD , y0 , u0 + nLengthUV , v0 ) >> nResQuantBit  << nResQuantBit ;
+    nInitP3 = xxCoeff2Vertex( dInitA , dInitB , dInitC , dInitD , y0 , u0 + nLengthUV , v0 + nLengthUV ) >> nResQuantBit  << nResQuantBit ;
+    nInitP7 = xxCoeff2Vertex( dInitA , dInitB , dInitC , dInitD , y0 + nLengthY , u0 + nLengthUV , v0 + nLengthUV ) >> nResQuantBit  << nResQuantBit ;
+  }
+
+  Int nMin = - ( 1 << ( m_nLUTBitDepth - 1 ) );
+  Int nMax = - nMin - ( 1 << nResQuantBit  );
+  Int nMask = ( 1 << nResQuantBit ) - 1;
+
+  Double dMinError = MAX_DOUBLE;
+  Int testRange = 2;
+  for( Int i = - testRange , nDeltaP01 = nInitP1 - nInitP0 - testRange * ( 1 << nResQuantBit  ) ; i <= testRange ; i++ , nDeltaP01 += ( 1 << nResQuantBit  ) )
+  {
+    for( Int j = - testRange , nDeltaP13 = nInitP3 - nInitP1 - testRange * ( 1 << nResQuantBit  ) ; j <= testRange ; j++ , nDeltaP13 += ( 1 << nResQuantBit  ) )
+    {
+      for( Int k = - testRange , nDeltaP37 = nInitP7 - nInitP3 - testRange * ( 1 << nResQuantBit  ) ; k <= testRange ; k++ , nDeltaP37 += ( 1 << nResQuantBit  ) )
+      {
+        Double a = 1.0 * nDeltaP37 / nLengthY;
+        Double b = 1.0 * nDeltaP01 / nLengthUV;
+        Double c = 1.0 * nDeltaP13 / nLengthUV;
+        Double d = ( Ys - a * ys - b * us - c * vs ) / N;
+        Int nP0 = xxCoeff2Vertex( a , b , c , d , y0 , u0 , v0 ) >> nResQuantBit  << nResQuantBit ;
+        nP0 = Clip3( nMin , nMax , nP0 );
+        Int nP1 = Clip3( nMin , nMax , nP0 + nDeltaP01 );
+        Int nP3 = Clip3( nMin , nMax , nP1 + nDeltaP13 );
+        Int nP7 = Clip3( nMin , nMax , nP3 + nDeltaP37 );
+        if ( nP0 & nMask )  
+          nP0 -= ( nP0 & nMask );
+        if ( nP1 & nMask )  
+          nP1 -= ( nP1 & nMask );
+        if ( nP3 & nMask )  
+          nP3 -= ( nP3 & nMask );
+        if ( nP7 & nMask )  
+          nP7 -= ( nP7 & nMask );
+        assert( !( nP0 & nMask ) && !( nP1 & nMask ) && !( nP3 & nMask ) && !( nP7 & nMask ) );
+        Double dError = xxCalEstDist( N , Ys , Yy , Yu , Yv , ys , us , vs , yy , yu , yv , uu , uv , vv , YY , y0 , u0 , v0 , nLengthY , nLengthUV , nP0 , nP1 , nP3 , nP7 );
+        if( dError < dMinError )
+        {
+          dMinError = dError;
+          rP0 = ( Pel )nP0;
+          rP1 = ( Pel )nP1;
+          rP3 = ( Pel )nP3;
+          rP7 = ( Pel )nP7;
+          assert( nMin <= rP0 && rP0 <= nMax && nMin <= rP1 && rP1 <= nMax  && nMin <= rP3 && rP3 <= nMax && nMin <= rP7 && rP7 <= nMax );
+        }
+      }
+    }
+  }
+
+  return( dMinError );
+}
+
+Double TEnc3DAsymLUT::estimateDistWithCur3DAsymLUT( TComPic * pCurPic , UInt refLayerIdc )
+{
+  xxCollectData( pCurPic , refLayerIdc );
+
+  Double dErrorLuma = 0 , dErrorChroma = 0;
+  Int nYSize = 1 << ( getCurOctantDepth() + getCurYPartNumLog2() );
+  Int nUVSize = 1 << getCurOctantDepth();
+  Int nLengthY = 1 << ( getInputBitDepthY() - getCurOctantDepth() - getCurYPartNumLog2() );
+  Int nLengthUV = 1 << ( getInputBitDepthC() - getCurOctantDepth() );
+  for( Int yIdx = 0 ; yIdx < nYSize ; yIdx++ )
+  {
+    for( Int uIdx = 0 ; uIdx < nUVSize ; uIdx++ )
+    {
+      for( Int vIdx = 0 ; vIdx < nUVSize ; vIdx++ )
+      {
+        SColorInfo & rCuboidColorInfo = m_pColorInfo[yIdx][uIdx][vIdx];
+        SColorInfo & rCuboidColorInfoC = m_pColorInfoC[yIdx][uIdx][vIdx];
+        SCuboid & rCuboid = xGetCuboid( yIdx , uIdx , vIdx );
+        Int y0 = yIdx << xGetYShift2Idx();
+        Int u0 = uIdx << xGetUShift2Idx();
+        Int v0 = vIdx << xGetVShift2Idx();
+        if( rCuboidColorInfo.N > 0 )
+        {
+          dErrorLuma += xxCalEstDist( rCuboidColorInfo.N , rCuboidColorInfo.Ys , rCuboidColorInfo.Yy , rCuboidColorInfo.Yu , rCuboidColorInfo.Yv , rCuboidColorInfo.ys , rCuboidColorInfo.us , rCuboidColorInfo.vs , rCuboidColorInfo.yy , rCuboidColorInfo.yu , rCuboidColorInfo.yv , rCuboidColorInfo.uu , rCuboidColorInfo.uv , rCuboidColorInfo.vv , rCuboidColorInfo.YY ,
+            y0 , u0 , v0 , nLengthY , nLengthUV , rCuboid.P[0].Y , rCuboid.P[1].Y , rCuboid.P[2].Y , rCuboid.P[3].Y );
+        }
+        if( rCuboidColorInfoC.N > 0 )
+        {
+          dErrorChroma += xxCalEstDist( rCuboidColorInfoC.N , rCuboidColorInfoC.Us , rCuboidColorInfoC.Uy , rCuboidColorInfoC.Uu , rCuboidColorInfoC.Uv , rCuboidColorInfoC.ys , rCuboidColorInfoC.us , rCuboidColorInfoC.vs , rCuboidColorInfoC.yy , rCuboidColorInfoC.yu , rCuboidColorInfoC.yv , rCuboidColorInfoC.uu , rCuboidColorInfoC.uv , rCuboidColorInfoC.vv , rCuboidColorInfoC.UU ,
+            y0 , u0 , v0 , nLengthY , nLengthUV , rCuboid.P[0].U , rCuboid.P[1].U , rCuboid.P[2].U , rCuboid.P[3].U );
+          dErrorChroma += xxCalEstDist( rCuboidColorInfoC.N , rCuboidColorInfoC.Vs , rCuboidColorInfoC.Vy , rCuboidColorInfoC.Vu , rCuboidColorInfoC.Vv , rCuboidColorInfoC.ys , rCuboidColorInfoC.us , rCuboidColorInfoC.vs , rCuboidColorInfoC.yy , rCuboidColorInfoC.yu , rCuboidColorInfoC.yv , rCuboidColorInfoC.uu , rCuboidColorInfoC.uv , rCuboidColorInfoC.vv , rCuboidColorInfoC.VV ,
+            y0 , u0 , v0 , nLengthY , nLengthUV , rCuboid.P[0].V , rCuboid.P[1].V , rCuboid.P[2].V , rCuboid.P[3].V );
+        }
+    }
+    }
+  }
+
+  return( dErrorLuma + dErrorChroma);
+}
+
+Double TEnc3DAsymLUT::derive3DAsymLUT( TComSlice * pSlice , TComPic * pCurPic , UInt refLayerIdc , TEncCfg * pCfg , Bool bSignalPPS , Bool bElRapSliceTypeB )
+{
+  m_nLUTBitDepth = pCfg->getCGSLUTBit();
+  Int nCurYPartNumLog2 = 0 , nCurOctantDepth = 0; 
+  xxDerivePartNumLog2( pSlice , pCfg , nCurOctantDepth , nCurYPartNumLog2 , bSignalPPS , bElRapSliceTypeB );
+  xUpdatePartitioning( nCurOctantDepth , nCurYPartNumLog2 );
+  xxCollectData( pCurPic , refLayerIdc );
+  Int nBestResQuanBit = 0;
+  Double dError0 = xxDeriveVertexes( nBestResQuanBit , m_pBestEncCuboid );
+  Double dCurError = dError0;
+  Double dFactor = 1 + 0.001 * ( pSlice->getDepth() + 1 );
+  for( Int nResQuanBit = 1 ; nResQuanBit < 4 ; nResQuanBit++ )
+  {
+    Double dError = xxDeriveVertexes( nResQuanBit , m_pEncCuboid );
+    if( dError < dError0 * dFactor )
+    {
+      nBestResQuanBit = nResQuanBit;
+      SCuboid *** tmp = m_pBestEncCuboid;
+      m_pBestEncCuboid = m_pEncCuboid;
+      m_pEncCuboid = tmp;
+      dCurError = dError;
+    }
+    else
+      break;
+  }
+  setResQuantBit( nBestResQuanBit );
+  xSaveCuboids( m_pBestEncCuboid );
+  return( dCurError );
+}
+
+Double TEnc3DAsymLUT::xxDeriveVertexes( Int nResQuanBit , SCuboid *** pCurCuboid )
+{
+  Double dErrorLuma = 0 , dErrorChroma = 0;
+  Int nYSize = 1 << ( getCurOctantDepth() + getCurYPartNumLog2() );
+  Int nUVSize = 1 << getCurOctantDepth();
+  Int nLengthY = 1 << ( getInputBitDepthY() - getCurOctantDepth() - getCurYPartNumLog2() );
+  Int nLengthUV = 1 << ( getInputBitDepthC() - getCurOctantDepth() );
+  for( Int yIdx = 0 ; yIdx < nYSize ; yIdx++ )
+  {
+    for( Int uIdx = 0 ; uIdx < nUVSize ; uIdx++ )
+    {
+      for( Int vIdx = 0 ; vIdx < nUVSize ; vIdx++ )
+      {
+        SColorInfo & rCuboidColorInfo = m_pColorInfo[yIdx][uIdx][vIdx];
+        SColorInfo & rCuboidColorInfoC = m_pColorInfoC[yIdx][uIdx][vIdx];
+        SCuboid & rCuboid = pCurCuboid[yIdx][uIdx][vIdx];
+        Int y0 = yIdx << xGetYShift2Idx();
+        Int u0 = uIdx << xGetUShift2Idx();
+        Int v0 = vIdx << xGetVShift2Idx();
+        for( Int idxVertex = 0 ; idxVertex < 4 ; idxVertex++ )
+          rCuboid.P[idxVertex] = xGetCuboidVertexPredAll( yIdx , uIdx , vIdx , idxVertex , pCurCuboid );
+
+        if( rCuboidColorInfo.N > 0 )
+        {
+          dErrorLuma += xxDeriveVertexPerColor( rCuboidColorInfo.N , rCuboidColorInfo.Ys , rCuboidColorInfo.Yy , rCuboidColorInfo.Yu , rCuboidColorInfo.Yv , rCuboidColorInfo.ys , rCuboidColorInfo.us , rCuboidColorInfo.vs , rCuboidColorInfo.yy , rCuboidColorInfo.yu , rCuboidColorInfo.yv , rCuboidColorInfo.uu , rCuboidColorInfo.uv , rCuboidColorInfo.vv , rCuboidColorInfo.YY ,
+            y0 , u0 , v0 , nLengthY , nLengthUV , rCuboid.P[0].Y , rCuboid.P[1].Y , rCuboid.P[2].Y , rCuboid.P[3].Y , nResQuanBit );
+        }
+        if( rCuboidColorInfoC.N > 0 )
+        {
+          dErrorChroma += xxDeriveVertexPerColor( rCuboidColorInfoC.N , rCuboidColorInfoC.Us , rCuboidColorInfoC.Uy , rCuboidColorInfoC.Uu , rCuboidColorInfoC.Uv , rCuboidColorInfoC.ys , rCuboidColorInfoC.us , rCuboidColorInfoC.vs , rCuboidColorInfoC.yy , rCuboidColorInfoC.yu , rCuboidColorInfoC.yv , rCuboidColorInfoC.uu , rCuboidColorInfoC.uv , rCuboidColorInfoC.vv , rCuboidColorInfoC.UU ,
+            y0 , u0 , v0 , nLengthY , nLengthUV , rCuboid.P[0].U , rCuboid.P[1].U , rCuboid.P[2].U , rCuboid.P[3].U , nResQuanBit );
+          dErrorChroma += xxDeriveVertexPerColor( rCuboidColorInfoC.N , rCuboidColorInfoC.Vs , rCuboidColorInfoC.Vy , rCuboidColorInfoC.Vu , rCuboidColorInfoC.Vv , rCuboidColorInfoC.ys , rCuboidColorInfoC.us , rCuboidColorInfoC.vs , rCuboidColorInfoC.yy , rCuboidColorInfoC.yu , rCuboidColorInfoC.yv , rCuboidColorInfoC.uu , rCuboidColorInfoC.uv , rCuboidColorInfoC.vv , rCuboidColorInfoC.VV ,
+            y0 , u0 , v0 , nLengthY , nLengthUV , rCuboid.P[0].V , rCuboid.P[1].V , rCuboid.P[2].V , rCuboid.P[3].V , nResQuanBit );
+        }
+
+        if( nResQuanBit > 0 )
+        {
+          // check quantization
+          for( Int idxVertex = 0 ; idxVertex < 4 ; idxVertex++ )
+          {
+            SYUVP sPred = xGetCuboidVertexPredAll( yIdx , uIdx , vIdx , idxVertex , pCurCuboid );
+            assert( ( ( rCuboid.P[idxVertex].Y - sPred.Y ) >> nResQuanBit << nResQuanBit ) == rCuboid.P[idxVertex].Y - sPred.Y );
+            assert( ( ( rCuboid.P[idxVertex].U - sPred.U ) >> nResQuanBit << nResQuanBit ) == rCuboid.P[idxVertex].U - sPred.U );
+            assert( ( ( rCuboid.P[idxVertex].V - sPred.V ) >> nResQuanBit << nResQuanBit ) == rCuboid.P[idxVertex].V - sPred.V );
+          }
+        }
+      }
+    }
+  }
+
+  return( dErrorLuma + dErrorChroma );
+}
+
+Void TEnc3DAsymLUT::xxCollectData( TComPic * pCurPic , UInt refLayerIdc )
+{
+  Pel * pSrcY = m_pDsOrigPic->getLumaAddr();
+  Pel * pSrcU = m_pDsOrigPic->getCbAddr();
+  Pel * pSrcV = m_pDsOrigPic->getCrAddr();
+  Int nStrideSrcY = m_pDsOrigPic->getStride();
+  Int nStrideSrcC = m_pDsOrigPic->getCStride();
+  TComPicYuv *pRecPic = pCurPic->getSlice(pCurPic->getCurrSliceIdx())->getBaseColPic(refLayerIdc)->getPicYuvRec();
+  Pel * pIRLY = pRecPic->getLumaAddr();
+  Pel * pIRLU = pRecPic->getCbAddr();
+  Pel * pIRLV = pRecPic->getCrAddr();
+  Int nStrideILRY = pRecPic->getStride();
+  Int nStrideILRC = pRecPic->getCStride();
+  Int nWidth = m_pDsOrigPic->getWidth();   //should exclude the padding;
+  Int nHeight= m_pDsOrigPic->getHeight();
+  xReset3DArray( m_pColorInfo , xGetYSize() , xGetUSize() , xGetVSize() );
+  xReset3DArray( m_pColorInfoC , xGetYSize() , xGetUSize() , xGetVSize() );
+
+  //alignment padding
+  Pel *pU = pRecPic->getCbAddr();
+  Pel *pV = pRecPic->getCrAddr();
+  pU[(nWidth>>1)] = pU[(nWidth>>1)-1];
+  pV[(nWidth>>1)] = pV[(nWidth>>1)-1];
+  memcpy(pU-nStrideILRC, pU, ((nWidth>>1)+1)*sizeof(Pel));
+  memcpy(pV-nStrideILRC, pV, ((nWidth>>1)+1)*sizeof(Pel));
+  pU += nStrideILRC+ (nWidth>>1);
+  pV += nStrideILRC+ (nWidth>>1);
+
+  for( Int y = 1 ; y < (nHeight>>1) ; y ++ )
+  {
+    *pU = pU[-1];
+    *pV = pV[-1];
+    pU += nStrideILRC;
+    pV += nStrideILRC;
+  }
+  memcpy(pU-(nWidth>>1), pU-(nWidth>>1)-nStrideILRC, ((nWidth>>1)+1)*sizeof(Pel));
+  memcpy(pV-(nWidth>>1), pV-(nWidth>>1)-nStrideILRC, ((nWidth>>1)+1)*sizeof(Pel));
+
+  for( Int i = 0 ; i < nHeight ; i++ )
+  {
+    Int posSrcY = i * nStrideSrcY;
+    Int posIRLY = i * nStrideILRY;
+    Int posSrcUV = ( i >> 1 ) * nStrideSrcC;
+    Int posIRLUV = ( i >> 1 ) * nStrideILRC;
+    for( Int j = 0 ; j < nWidth ; j++ , posSrcY++ , posIRLY++ , posSrcUV += !( j & 0x01 ) , posIRLUV += !( j & 0x01 ) )
+    {
+      Int Y = pSrcY[posSrcY];
+      Int y = pIRLY[posIRLY];
+      Int U = pSrcU[posSrcUV];
+      Int u = pIRLU[posIRLUV];
+      Int V = pSrcV[posSrcUV];
+      Int v = pIRLV[posIRLUV];
+
+      // alignment
+      //filtering u, v for luma;
+      Int posIRLUVN =  posIRLUV + ((i&1)? nStrideILRC : -nStrideILRC);
+      if((j&1))
+      {
+        u = (pIRLU[posIRLUVN] + pIRLU[posIRLUVN+1] +(u + pIRLU[posIRLUV+1])*3 +4)>>3;
+        v = (pIRLV[posIRLUVN] + pIRLV[posIRLUVN+1] +(v + pIRLV[posIRLUV+1])*3 +4)>>3;
+      }
+      else
+      { 
+        u = (pIRLU[posIRLUVN] +u*3 +2)>>2;
+        v = (pIRLV[posIRLUVN] +v*3 +2)>>2;
+      }
+
+      SColorInfo sColorInfo;
+      SColorInfo & rCuboidColorInfo = m_pColorInfo[y>>xGetYShift2Idx()][u>>xGetUShift2Idx()][v>>xGetVShift2Idx()];
+      memset(&sColorInfo, 0, sizeof(SColorInfo));
+      sColorInfo.Ys = Y;
+      sColorInfo.ys = y;
+      sColorInfo.us = u;
+      sColorInfo.vs = v;
+      sColorInfo.Yy = Y * y;
+      sColorInfo.Yu = Y * u;
+      sColorInfo.Yv = Y * v;
+      sColorInfo.yy = y * y;
+      sColorInfo.yu = y * u;
+      sColorInfo.yv = y * v;
+      sColorInfo.uu = u * u;
+      sColorInfo.uv = u * v;
+      sColorInfo.vv = v * v;
+      sColorInfo.YY = Y * Y;
+      sColorInfo.N  = 1;
+
+      rCuboidColorInfo += sColorInfo;
+
+      if(!((i&1) || (j&1)))
+      {
+        // alignment
+        y =  (pIRLY[posIRLY] + pIRLY[posIRLY+nStrideILRY] + 1)>>1;
+
+        u = pIRLU[posIRLUV];
+        v = pIRLV[posIRLUV];
+        SColorInfo & rCuboidColorInfoC = m_pColorInfoC[y>>xGetYShift2Idx()][u>>xGetUShift2Idx()][v>>xGetVShift2Idx()];
+        //sColorInfo.Ys = Y;
+        sColorInfo.Us = U;
+        sColorInfo.Vs = V;
+        sColorInfo.ys = y;
+        sColorInfo.us = u;
+        sColorInfo.vs = v;
+
+        sColorInfo.Uy = U * y;
+        sColorInfo.Uu = U * u;
+        sColorInfo.Uv = U * v;
+        sColorInfo.Vy = V * y;
+        sColorInfo.Vu = V * u;
+        sColorInfo.Vv = V * v;
+        sColorInfo.yy = y * y;
+        sColorInfo.yu = y * u;
+        sColorInfo.yv = y * v;
+        sColorInfo.uu = u * u;
+        sColorInfo.uv = u * v;
+        sColorInfo.vv = v * v;
+        sColorInfo.UU = U * U;
+        sColorInfo.VV = V * V;
+        sColorInfo.N  = 1;
+
+        rCuboidColorInfoC += sColorInfo;
+      }
+    }
+  }
+}
+
+Void TEnc3DAsymLUT::xxDerivePartNumLog2( TComSlice * pSlice , TEncCfg * pcCfg , Int & rOctantDepth , Int & rYPartNumLog2 , Bool bSignalPPS , Bool bElRapSliceTypeB )
+{
+  Int nSliceType = pSlice->getSliceType();
+  // update slice type as what will be done later
+  if( pSlice->getActiveNumILRRefIdx() == 0 && pSlice->getNalUnitType() >= NAL_UNIT_CODED_SLICE_BLA_W_LP && pSlice->getNalUnitType() <= NAL_UNIT_CODED_SLICE_CRA )
+  {
+    nSliceType = I_SLICE;
+  }
+  else if( !bElRapSliceTypeB )
+  {
+    if( (pSlice->getNalUnitType() >= NAL_UNIT_CODED_SLICE_BLA_W_LP) &&
+      (pSlice->getNalUnitType() <= NAL_UNIT_CODED_SLICE_CRA) &&
+      pSlice->getSliceType() == B_SLICE )
+    {
+      nSliceType = P_SLICE;
+    }
+  }
+
+  const Int nSliceTempLevel = pSlice->getDepth();
+  Int nPartNumLog2 = 4;
+  if( pSlice->getBaseColPic( pSlice->getInterLayerPredLayerIdc( 0 ) )->getSlice( 0 )->isIntra() )
+    nPartNumLog2 = xGetMaxPartNumLog2();
+  if( m_nPrevFrameBit[nSliceType][nSliceTempLevel] && pSlice->getPPS()->getCGSFlag() == Q0048_CGS_3D_ASYMLUT_PPSUPDATE  ) 
+  {
+    Double dBitCost = 1.0 * m_nPrevFrameCGSBit[nSliceType][nSliceTempLevel] / m_nPrevFrameBit[nSliceType][nSliceTempLevel];
+    nPartNumLog2 = m_nPrevFrameCGSPartNumLog2[nSliceType][nSliceTempLevel];
+    Double dBitCostT = 0.03;
+    if( dBitCost < dBitCostT / 6.0 )
+    {
+      nPartNumLog2++;
+    }
+    else if( dBitCost >= dBitCostT )
+    {
+      nPartNumLog2--;
+    }
+  }
+  else
+  {
+    nPartNumLog2 -= nSliceTempLevel;
+  }
+  nPartNumLog2 = Clip3( 0 , xGetMaxPartNumLog2() , nPartNumLog2 );
+  xxMapPartNum2DepthYPart( nPartNumLog2 , rOctantDepth , rYPartNumLog2 );
+}
+
+Void TEnc3DAsymLUT::xxMapPartNum2DepthYPart( Int nPartNumLog2 , Int & rOctantDepth , Int & rYPartNumLog2 )
+{
+  for( Int y = getMaxYPartNumLog2() ; y >= 0 ; y-- )
+  {
+    for( Int depth = ( nPartNumLog2 - y ) >> 1 ; depth >= 0 ; depth-- )
+    {
+      if( y + 3 * depth == nPartNumLog2 )
+      {
+        rOctantDepth = depth;
+        rYPartNumLog2 = y;
+        return;
+      }
+    }
+  }
+  rOctantDepth = min( getMaxOctantDepth() , nPartNumLog2 / 3 );
+  rYPartNumLog2 = min( getMaxYPartNumLog2() , nPartNumLog2 - 3 * rOctantDepth );
+}
+
+Void TEnc3DAsymLUT::updatePicCGSBits( TComSlice * pcSlice , Int nPPSBit )
+{
+  const Int nSliceType = pcSlice->getSliceType();
+  const Int nSliceTempLevel = pcSlice->getDepth();
+
+  for( Int i = 0; i < pcSlice->getActiveNumILRRefIdx(); i++ )
+  {
+    UInt refLayerIdc = pcSlice->getInterLayerPredLayerIdc(i);
+    m_nPrevFrameBit[nSliceType][nSliceTempLevel] = pcSlice->getPic()->getFrameBit() + pcSlice->getBaseColPic(refLayerIdc)->getFrameBit();
+    m_dTotalFrameBit += pcSlice->getPic()->getFrameBit() + pcSlice->getBaseColPic(refLayerIdc)->getFrameBit();
+  }
+  m_nPrevFrameOverWritePPS[nSliceType][nSliceTempLevel] = pcSlice->getCGSOverWritePPS();
+  m_nPrevFrameCGSBit[nSliceType][nSliceTempLevel] = nPPSBit;
+  m_nTotalCGSBit += nPPSBit;
+  m_nPrevFrameCGSPartNumLog2[nSliceType][nSliceTempLevel] = getCurOctantDepth() * 3 + getCurYPartNumLog2();
+}
+
+#endif
Index: /branches/SHM-6-dev/source/Lib/TLibEncoder/TEnc3DAsymLUT.h
===================================================================
--- /branches/SHM-6-dev/source/Lib/TLibEncoder/TEnc3DAsymLUT.h	(revision 677)
+++ /branches/SHM-6-dev/source/Lib/TLibEncoder/TEnc3DAsymLUT.h	(revision 677)
@@ -0,0 +1,122 @@
+
+#ifndef __TENC3DASYMLUT__
+#define __TENC3DASYMLUT__
+
+#include "../TLibCommon/TCom3DAsymLUT.h"
+#include "../TLibCommon/TComSlice.h"
+#include "../TLibCommon/CommonDef.h"
+#include "../TLibCommon/TComPic.h"
+#include "TEncCfg.h"
+
+#if Q0048_CGS_3D_ASYMLUT
+
+typedef struct _ColorInfo
+{
+  Double YY , UU , VV;
+  Double Ys , Us , Vs;  // sum of enhancement
+  Double ys , us , vs;  // sum of base
+  Double Yy , Yu , Yv;  // product of enhancement and base
+  Double Uy , Uu , Uv;
+  Double Vy , Vu , Vv;
+  Double yy , yu , yv , uu , uv , vv; // product of base
+  Double N; // number of pixel
+
+public:
+  _ColorInfo & operator += ( const _ColorInfo & rColorInfo )
+  {
+    YY += rColorInfo.YY;
+    UU += rColorInfo.UU;
+    VV += rColorInfo.VV;
+    Ys += rColorInfo.Ys;
+    Us += rColorInfo.Us;
+    Vs += rColorInfo.Vs;
+    ys += rColorInfo.ys;
+    us += rColorInfo.us;
+    vs += rColorInfo.vs;
+    Yy += rColorInfo.Yy;
+    Yu += rColorInfo.Yu;
+    Yv += rColorInfo.Yv;
+    Uy += rColorInfo.Uy;
+    Uu += rColorInfo.Uu;
+    Uv += rColorInfo.Uv;
+    Vy += rColorInfo.Vy;
+    Vu += rColorInfo.Vu;
+    Vv += rColorInfo.Vv;
+    yy += rColorInfo.yy;
+    yu += rColorInfo.yu;
+    yv += rColorInfo.yv;
+    uu += rColorInfo.uu;
+    uv += rColorInfo.uv;
+    vv += rColorInfo.vv;
+    N  += rColorInfo.N; 
+    return *this;
+  }
+
+}SColorInfo;
+
+
+class TEnc3DAsymLUT : public TCom3DAsymLUT
+{
+public:
+  TEnc3DAsymLUT();
+  virtual ~TEnc3DAsymLUT();
+
+  virtual Void  create( Int nMaxOctantDepth , Int nInputBitDepth , Int nInputBitDepthC , Int nOutputBitDepth , Int nOutputBitDepthC , Int nMaxYPartNumLog2 );
+  virtual Void  destroy();
+  Double derive3DAsymLUT( TComSlice * pSlice , TComPic * pCurPic , UInt refLayerIdc , TEncCfg * pCfg , Bool bSignalPPS , Bool bElRapSliceTypeB );
+  Double estimateDistWithCur3DAsymLUT( TComPic * pCurPic , UInt refLayerIdc );
+
+  Void  updatePicCGSBits( TComSlice * pcSlice , Int nPPSBit );
+  Void  setPPSBit(Int n)  { m_nPPSBit = n;  }
+  Int   getPPSBit()       { return m_nPPSBit;}
+  Void  setDsOrigPic(TComPicYuv *pPicYuv) { m_pDsOrigPic = pPicYuv; };
+
+protected:
+  SColorInfo *** m_pColorInfo;
+  SColorInfo *** m_pColorInfoC;
+  TComPicYuv* m_pDsOrigPic;
+  SCuboid *** m_pEncCuboid;
+  SCuboid *** m_pBestEncCuboid;
+  Int   m_nPrevFrameBit[3][MAX_TLAYER];                  // base + enhancement layer
+  Int   m_nPrevFrameCGSBit[3][MAX_TLAYER];
+  Int   m_nPrevFrameCGSPartNumLog2[3][MAX_TLAYER];
+  Int   m_nPrevFrameOverWritePPS[3][MAX_TLAYER];
+  Double m_dTotalFrameBit;
+  Int   m_nTotalCGSBit;
+  Int   m_nPPSBit;
+  Int   m_nLUTBitDepth;
+
+private:
+  Double  xxDeriveVertexPerColor( Double N , Double Ys , Double Yy , Double Yu , Double Yv , Double ys , Double us , Double vs , Double yy , Double yu , Double yv , Double uu , Double uv , Double vv , Double YY ,
+    Int y0 , Int u0 , Int v0 , Int nLengthY , Int nLengthUV ,
+    Pel & rP0 , Pel & rP1 , Pel & rP3 , Pel & rP7 , Int nResQuantBit );
+  Void    xxDerivePartNumLog2( TComSlice * pSlice , TEncCfg * pcCfg , Int & rOctantDepth , Int & rYPartNumLog2 , Bool bSignalPPS , Bool bElRapSliceTypeB );
+  Void    xxMapPartNum2DepthYPart( Int nPartNumLog2 , Int & rOctantDepth , Int & rYPartNumLog2 );
+  Int     xxCoeff2Vertex( Double a , Double b , Double c , Double d , Int y , Int u , Int v ) { return ( ( Int )( a * y + b * u + c * v + d + 0.5 ) ); }
+  Void    xxCollectData( TComPic * pCurPic , UInt refLayerIdc );
+  Double  xxDeriveVertexes( Int nResQuantBit , SCuboid *** pCurCuboid );
+  inline Double  xxCalEstDist( Double N , Double Ys , Double Yy , Double Yu , Double Yv , Double ys , Double us , Double vs , Double yy , Double yu , Double yv , Double uu , Double uv , Double vv , Double YY ,
+    Int y0 , Int u0 , Int v0 , Int nLengthY , Int nLengthUV , Pel nP0 , Pel nP1 , Pel nP3 , Pel nP7 );
+  inline Double  xxCalEstDist( Double N , Double Ys , Double Yy , Double Yu , Double Yv , Double ys , Double us , Double vs , Double yy , Double yu , Double yv , Double uu , Double uv , Double vv , Double YY ,
+    Double a , Double b , Double c , Double d );
+};
+
+Double TEnc3DAsymLUT::xxCalEstDist( Double N , Double Ys , Double Yy , Double Yu , Double Yv , Double ys , Double us , Double vs , Double yy , Double yu , Double yv , Double uu , Double uv , Double vv , Double YY ,
+  Int y0 , Int u0 , Int v0 , Int nLengthY , Int nLengthUV , Pel nP0 , Pel nP1 , Pel nP3 , Pel nP7 )
+{
+  Double a = 1.0 * ( nP7 - nP3 ) / nLengthY;
+  Double b = 1.0 * ( nP1 - nP0 ) / nLengthUV;
+  Double c = 1.0 * ( nP3 - nP1 ) / nLengthUV;
+  Double d = ( ( nP0 * nLengthUV + u0 * nP0 + ( v0 - u0 ) * nP1 - v0 * nP3 ) * nLengthY + y0 * nLengthUV * ( nP3 - nP7 ) ) / nLengthUV / nLengthY;
+  return( xxCalEstDist( N , Ys , Yy , Yu , Yv , ys , us , vs , yy , yu , yv , uu , uv , vv , YY , a , b , c , d ) );
+}
+
+Double TEnc3DAsymLUT::xxCalEstDist( Double N , Double Ys , Double Yy , Double Yu , Double Yv , Double ys , Double us , Double vs , Double yy , Double yu , Double yv , Double uu , Double uv , Double vv , Double YY ,
+  Double a , Double b , Double c , Double d )
+{
+  Double dError = N * d * d + 2 * b * c * uv + 2 * a * c * yv + 2 * a * b * yu - 2 * c * Yv - 2 * b * Yu - 2 * a * Yy + 2 * c * d * vs + 2 * b * d * us + 2 * a * d * ys + a * a * yy + c * c * vv + b * b * uu - 2 * d * Ys + YY;
+  return( dError );
+};
+#endif
+
+#endif
Index: /branches/SHM-6-dev/source/Lib/TLibEncoder/TEncCavlc.cpp
===================================================================
--- /branches/SHM-6-dev/source/Lib/TLibEncoder/TEncCavlc.cpp	(revision 676)
+++ /branches/SHM-6-dev/source/Lib/TLibEncoder/TEncCavlc.cpp	(revision 677)
@@ -154,5 +154,9 @@
 
 
-Void TEncCavlc::codePPS( TComPPS* pcPPS )
+Void TEncCavlc::codePPS( TComPPS* pcPPS 
+#if Q0048_CGS_3D_ASYMLUT
+  , TEnc3DAsymLUT * pc3DAsymLUT
+#endif
+  )
 {
 #if ENC_DEC_TRACE  
@@ -268,4 +272,14 @@
     {
       WRITE_FLAG( pcPPS->getPocResetInfoPresentFlag() ? 1 : 0, "poc_reset_info_present_flag" );
+#if Q0048_CGS_3D_ASYMLUT
+      UInt uiPos = getNumberOfWrittenBits();
+      WRITE_FLAG( pcPPS->getCGSFlag() , "colour_mapping_enabled_flag" );
+      if( pcPPS->getCGSFlag() == Q0048_CGS_3D_ASYMLUT_PPSUPDATE )
+      {
+        assert( pc3DAsymLUT != NULL );
+        xCode3DAsymLUT( pc3DAsymLUT );
+      }
+      pc3DAsymLUT->setPPSBit( getNumberOfWrittenBits() - uiPos );
+#endif
 #endif
     }
@@ -2689,3 +2703,63 @@
   return true;
 }
+
+#if Q0048_CGS_3D_ASYMLUT
+Void TEncCavlc::xCode3DAsymLUT( TCom3DAsymLUT * pc3DAsymLUT )
+{
+  assert( pc3DAsymLUT->getCurOctantDepth() < 4 );
+  WRITE_CODE( pc3DAsymLUT->getCurOctantDepth() , 2 , "cm_octant_depth" );
+  assert( pc3DAsymLUT->getCurYPartNumLog2() < 4 );
+  WRITE_CODE( pc3DAsymLUT->getCurYPartNumLog2() , 2 , "cm_y_part_num_log2" );
+  assert( pc3DAsymLUT->getInputBitDepthY() < 16 );
+  WRITE_CODE( pc3DAsymLUT->getInputBitDepthY() - 8 , 3 , "cm_input_bit_depth_minus8" );
+  WRITE_SVLC(pc3DAsymLUT->getInputBitDepthC()-pc3DAsymLUT->getInputBitDepthY(), "cm_input_bit_depth_chroma delta");
+  assert( pc3DAsymLUT->getOutputBitDepthY() < 16 );
+  WRITE_CODE( pc3DAsymLUT->getOutputBitDepthY() - 8 , 3 , "cm_output_bit_depth_minus8" );
+  WRITE_SVLC(pc3DAsymLUT->getOutputBitDepthC()-pc3DAsymLUT->getOutputBitDepthY(), "cm_output_bit_depth_chroma_delta");
+  assert( pc3DAsymLUT->getResQuantBit() < 4 );
+  WRITE_CODE( pc3DAsymLUT->getResQuantBit() , 2 , "cm_res_quant_bit" );
+
+  xCode3DAsymLUTOctant( pc3DAsymLUT , 0 , 0 , 0 , 0 , 1 << pc3DAsymLUT->getCurOctantDepth() );
+}
+
+Void TEncCavlc::xCode3DAsymLUTOctant( TCom3DAsymLUT * pc3DAsymLUT , Int nDepth , Int yIdx , Int uIdx , Int vIdx , Int nLength )
+{
+  UInt uiOctantSplit = nDepth < pc3DAsymLUT->getCurOctantDepth();
+  if( nDepth < pc3DAsymLUT->getCurOctantDepth() )
+    WRITE_FLAG( uiOctantSplit , "split_octant_flag" );
+  Int nYPartNum = 1 << pc3DAsymLUT->getCurYPartNumLog2();
+  if( uiOctantSplit )
+  {
+    Int nHalfLength = nLength >> 1;
+    for( Int l = 0 ; l < 2 ; l++ )
+    {
+      for( Int m = 0 ; m < 2 ; m++ )
+      {
+        for( Int n = 0 ; n < 2 ; n++ )
+        {
+          xCode3DAsymLUTOctant( pc3DAsymLUT , nDepth + 1 , yIdx + l * nHalfLength * nYPartNum , uIdx + m * nHalfLength , vIdx + n * nHalfLength , nHalfLength );
+        }
+      }
+    }
+  }
+  else
+  {
+    for( Int l = 0 ; l < nYPartNum ; l++ )
+    {
+      for( Int nVertexIdx = 0 ; nVertexIdx < 4 ; nVertexIdx++ )
+      {
+        SYUVP sRes = pc3DAsymLUT->getCuboidVertexResTree( yIdx + l , uIdx , vIdx , nVertexIdx );
+        UInt uiCodeVertex = sRes.Y != 0 || sRes.U != 0 || sRes.V != 0;
+        WRITE_FLAG( uiCodeVertex , "coded_vertex_flag" );
+        if( uiCodeVertex )
+        {
+          WRITE_SVLC( sRes.Y , "resY" );
+          WRITE_SVLC( sRes.U , "resU" );
+          WRITE_SVLC( sRes.V , "resV" );
+        }
+      }
+    }
+  }
+}
+#endif
 //! \}
Index: /branches/SHM-6-dev/source/Lib/TLibEncoder/TEncCavlc.h
===================================================================
--- /branches/SHM-6-dev/source/Lib/TLibEncoder/TEncCavlc.h	(revision 676)
+++ /branches/SHM-6-dev/source/Lib/TLibEncoder/TEncCavlc.h	(revision 677)
@@ -48,4 +48,8 @@
 #include "TEncEntropy.h"
 #include "SyntaxElementWriter.h"
+#if Q0048_CGS_3D_ASYMLUT
+#include "../TLibCommon/TCom3DAsymLUT.h"
+#include "TEnc3DAsymLUT.h"
+#endif
 
 //! \ingroup TLibEncoder
@@ -53,4 +57,7 @@
 
 class TEncTop;
+#if Q0048_CGS_3D_ASYMLUT
+class TCom3DAsymLUT;
+#endif
 
 // ====================================================================================================================
@@ -90,5 +97,9 @@
   Void  codeVUI                 ( TComVUI *pcVUI, TComSPS* pcSPS );
   Void  codeSPS                 ( TComSPS* pcSPS );
-  Void  codePPS                 ( TComPPS* pcPPS );
+  Void  codePPS                 ( TComPPS* pcPPS 
+#if Q0048_CGS_3D_ASYMLUT
+    , TEnc3DAsymLUT * pc3DAsymLUT
+#endif
+    );
   Void  codeSliceHeader         ( TComSlice* pcSlice );
   Void  codePTL                 ( TComPTL* pcPTL, Bool profilePresentFlag, Int maxNumSubLayersMinus1);
@@ -162,4 +173,9 @@
   Void  codeVpsDpbSizeTable      (TComVPS *vps);
 #endif
+#if Q0048_CGS_3D_ASYMLUT
+protected:
+  Void xCode3DAsymLUT( TCom3DAsymLUT * pc3DAsymLUT );
+  Void xCode3DAsymLUTOctant( TCom3DAsymLUT * pc3DAsymLUT , Int nDepth , Int yIdx , Int uIdx , Int vIdx , Int nLength );
+#endif
 #endif //SVC_EXTENSION
 
Index: /branches/SHM-6-dev/source/Lib/TLibEncoder/TEncCfg.h
===================================================================
--- /branches/SHM-6-dev/source/Lib/TLibEncoder/TEncCfg.h	(revision 676)
+++ /branches/SHM-6-dev/source/Lib/TLibEncoder/TEncCfg.h	(revision 677)
@@ -364,4 +364,10 @@
   UInt      m_bottomRightTileIndex[1024];
   UInt      m_ilcIdc[1024];
+#endif
+#if Q0048_CGS_3D_ASYMLUT
+  Int  m_nCGSFlag;
+  Int  m_nCGSMaxOctantDepth;
+  Int  m_nCGSMaxYPartNumLog2;
+  Int  m_nCGSLUTBit;
 #endif
 #endif //SVC_EXTENSION
@@ -904,4 +910,14 @@
   UInt  getIlcIdc(UInt b)                                  { return m_ilcIdc[b]; }
 #endif
+#if Q0048_CGS_3D_ASYMLUT
+  Void      setCGSFlag(Int n)  { m_nCGSFlag = n;    }
+  Int       getCGSFlag()       { return m_nCGSFlag; }
+  Void      setCGSMaxOctantDepth(Int n)  { m_nCGSMaxOctantDepth = n;    }
+  Int       getCGSMaxOctantDepth()       { return m_nCGSMaxOctantDepth; }
+  Void      setCGSMaxYPartNumLog2(Int n)  { m_nCGSMaxYPartNumLog2 = n;    }
+  Int       getCGSMaxYPartNumLog2()       { return m_nCGSMaxYPartNumLog2; }
+  Void      setCGSLUTBit(Int n)  { m_nCGSLUTBit = n;    }
+  Int       getCGSLUTBit()       { return m_nCGSLUTBit; }
+#endif
 #endif
 };
Index: /branches/SHM-6-dev/source/Lib/TLibEncoder/TEncEntropy.cpp
===================================================================
--- /branches/SHM-6-dev/source/Lib/TLibEncoder/TEncEntropy.cpp	(revision 676)
+++ /branches/SHM-6-dev/source/Lib/TLibEncoder/TEncEntropy.cpp	(revision 677)
@@ -79,7 +79,15 @@
 }
 
-Void TEncEntropy::encodePPS( TComPPS* pcPPS )
-{
-  m_pcEntropyCoderIf->codePPS( pcPPS );
+Void TEncEntropy::encodePPS( TComPPS* pcPPS 
+#if Q0048_CGS_3D_ASYMLUT
+  , TEnc3DAsymLUT * pc3DAsymLUT
+#endif
+  )
+{
+  m_pcEntropyCoderIf->codePPS( pcPPS 
+#if Q0048_CGS_3D_ASYMLUT
+    , pc3DAsymLUT
+#endif
+    );
   return;
 }
Index: /branches/SHM-6-dev/source/Lib/TLibEncoder/TEncEntropy.h
===================================================================
--- /branches/SHM-6-dev/source/Lib/TLibEncoder/TEncEntropy.h	(revision 676)
+++ /branches/SHM-6-dev/source/Lib/TLibEncoder/TEncEntropy.h	(revision 677)
@@ -50,4 +50,7 @@
 class TEncCavlc;
 class SEI;
+#if Q0048_CGS_3D_ASYMLUT
+class TEnc3DAsymLUT;
+#endif
 
 // ====================================================================================================================
@@ -70,5 +73,9 @@
   virtual Void  codeVPS                 ( TComVPS* pcVPS )                                      = 0;
   virtual Void  codeSPS                 ( TComSPS* pcSPS )                                      = 0;
-  virtual Void  codePPS                 ( TComPPS* pcPPS )                                      = 0;
+  virtual Void  codePPS                 ( TComPPS* pcPPS 
+#if Q0048_CGS_3D_ASYMLUT
+    , TEnc3DAsymLUT * pc3DAsymLUT
+#endif
+    )                                      = 0;
   virtual Void  codeSliceHeader         ( TComSlice* pcSlice )                                  = 0;
 
@@ -156,5 +163,9 @@
   // SPS
   Void encodeSPS               ( TComSPS* pcSPS );
-  Void encodePPS               ( TComPPS* pcPPS );
+  Void encodePPS               ( TComPPS* pcPPS 
+#if Q0048_CGS_3D_ASYMLUT
+    , TEnc3DAsymLUT * pc3DAsymLUT
+#endif
+    );
   Void encodeSplitFlag         ( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, Bool bRD = false );
   Void encodeCUTransquantBypassFlag( TComDataCU* pcCU, UInt uiAbsPartIdx, Bool bRD = false );
Index: /branches/SHM-6-dev/source/Lib/TLibEncoder/TEncGOP.cpp
===================================================================
--- /branches/SHM-6-dev/source/Lib/TLibEncoder/TEncGOP.cpp	(revision 676)
+++ /branches/SHM-6-dev/source/Lib/TLibEncoder/TEncGOP.cpp	(revision 677)
@@ -106,4 +106,8 @@
   m_pcPredSearch        = NULL;
 #endif
+#if Q0048_CGS_3D_ASYMLUT
+  m_temp = NULL;
+  m_pColorMappedPic = NULL;
+#endif
   return;
 }
@@ -111,4 +115,17 @@
 TEncGOP::~TEncGOP()
 {
+#if Q0048_CGS_3D_ASYMLUT
+  if(m_pColorMappedPic)
+  {
+    m_pColorMappedPic->destroy();
+    delete m_pColorMappedPic;
+    m_pColorMappedPic = NULL;                
+  }
+  if(m_temp)
+  {
+    free_mem2DintWithPad(m_temp, m_iTap>>1, 0);
+    m_temp = NULL;
+  }
+#endif
 }
 
@@ -159,4 +176,16 @@
 #if SVC_UPSAMPLING
   m_pcPredSearch         = pcTEncTop->getPredSearch();                       ///< encoder search class
+#endif
+#if Q0048_CGS_3D_ASYMLUT
+  if( pcTEncTop->getLayerId() )
+  {
+    m_Enc3DAsymLUTPicUpdate.create( m_pcCfg->getCGSMaxOctantDepth() , g_bitDepthYLayer[pcTEncTop->getLayerId()-1] , g_bitDepthCLayer[pcTEncTop->getLayerId()-1] , g_bitDepthYLayer[pcTEncTop->getLayerId()] , g_bitDepthCLayer[pcTEncTop->getLayerId()] , m_pcCfg->getCGSMaxYPartNumLog2() /*, m_pcCfg->getCGSPhaseAlignment()*/ );
+    m_Enc3DAsymLUTPPS.create(   m_pcCfg->getCGSMaxOctantDepth() , g_bitDepthYLayer[pcTEncTop->getLayerId()-1] , g_bitDepthCLayer[pcTEncTop->getLayerId()-1] , g_bitDepthYLayer[pcTEncTop->getLayerId()] , g_bitDepthCLayer[pcTEncTop->getLayerId()] , m_pcCfg->getCGSMaxYPartNumLog2() /*, m_pcCfg->getCGSPhaseAlignment()*/ );
+    if(!m_pColorMappedPic)
+    {
+      m_pColorMappedPic = new TComPicYuv;
+      m_pColorMappedPic->create( m_ppcTEncTop[0]->getSourceWidth(), m_ppcTEncTop[0]->getSourceHeight(), CHROMA_420, g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth, NULL );
+    }
+  }
 #endif
 }
@@ -924,4 +953,29 @@
         g_posScalingFactor[refLayerIdc][1] = ((heightBL << 16) + (heightEL >> 1)) / heightEL;
 
+#if Q0048_CGS_3D_ASYMLUT 
+        TComPicYuv* pBaseColRec = pcSlice->getBaseColPic(refLayerIdc)->getPicYuvRec();
+        if( pcSlice->getPPS()->getCGSFlag() != Q0048_CGS_3D_ASYMLUT_OFF)
+        {
+          if(g_posScalingFactor[refLayerIdc][0] < (1<<16) || g_posScalingFactor[refLayerIdc][1] < (1<<16)) //if(pcPic->isSpatialEnhLayer(refLayerIdc))
+          {
+            //downsampling;
+            downScalePic(pcPic->getPicYuvOrg(), pcSlice->getBaseColPic(refLayerIdc)->getPicYuvOrg());
+            //pcSlice->getBaseColPic(refLayerIdc)->getPicYuvOrg()->dump("ds.yuv", true, true);
+            m_Enc3DAsymLUTPPS.setDsOrigPic(pcSlice->getBaseColPic(refLayerIdc)->getPicYuvOrg());
+            m_Enc3DAsymLUTPicUpdate.setDsOrigPic(pcSlice->getBaseColPic(refLayerIdc)->getPicYuvOrg());
+          }
+          else
+          {
+            m_Enc3DAsymLUTPPS.setDsOrigPic(pcPic->getPicYuvOrg());
+            m_Enc3DAsymLUTPicUpdate.setDsOrigPic(pcPic->getPicYuvOrg());
+          }
+
+          Bool bSignalPPS = m_bSeqFirst;
+          bSignalPPS |= m_pcCfg->getGOPSize() > 1 ? pocCurr % m_pcCfg->getIntraPeriod() == 0 : pocCurr % m_pcCfg->getFrameRate() == 0;
+          xDetermin3DAsymLUT( pcSlice , pcPic , refLayerIdc , m_pcCfg , bSignalPPS );
+          m_Enc3DAsymLUTPPS.colorMapping( pcSlice->getBaseColPic(refLayerIdc)->getPicYuvRec(),  m_pColorMappedPic );
+          pBaseColRec = m_pColorMappedPic;
+        }
+#endif
 #if SVC_UPSAMPLING
         if( pcPic->isSpatialEnhLayer(refLayerIdc))
@@ -941,19 +995,39 @@
 #if O0215_PHASE_ALIGNMENT
 #if O0194_JOINT_US_BITSHIFT
+#if Q0048_CGS_3D_ASYMLUT 
+          m_pcPredSearch->upsampleBasePic( pcSlice, refLayerIdc, pcPic->getFullPelBaseRec(refLayerIdc), pBaseColRec, pcPic->getPicYuvRec(), scalEL, pcSlice->getVPS()->getPhaseAlignFlag() );
+#else
           m_pcPredSearch->upsampleBasePic( pcSlice, refLayerIdc, pcPic->getFullPelBaseRec(refLayerIdc), pcSlice->getBaseColPic(refLayerIdc)->getPicYuvRec(), pcPic->getPicYuvRec(), scalEL, pcSlice->getVPS()->getPhaseAlignFlag() );
+#endif
+#else
+#if Q0048_CGS_3D_ASYMLUT
+          m_pcPredSearch->upsampleBasePic( refLayerIdc, pcPic->getFullPelBaseRec(refLayerIdc), pBaseColRec, pcPic->getPicYuvRec(), scalEL, pcSlice->getVPS()->getPhaseAlignFlag() );
 #else
           m_pcPredSearch->upsampleBasePic( refLayerIdc, pcPic->getFullPelBaseRec(refLayerIdc), pcSlice->getBaseColPic(refLayerIdc)->getPicYuvRec(), pcPic->getPicYuvRec(), scalEL, pcSlice->getVPS()->getPhaseAlignFlag() );
 #endif
+#endif
 #else
 #if O0194_JOINT_US_BITSHIFT
+#if Q0048_CGS_3D_ASYMLUT 
+          m_pcPredSearch->upsampleBasePic( pcSlice, refLayerIdc, pcPic->getFullPelBaseRec(refLayerIdc), pBaseColRec, pcPic->getPicYuvRec(), scalEL );
+#else
           m_pcPredSearch->upsampleBasePic( pcSlice, refLayerIdc, pcPic->getFullPelBaseRec(refLayerIdc), pcSlice->getBaseColPic(refLayerIdc)->getPicYuvRec(), pcPic->getPicYuvRec(), scalEL );
+#endif
+#else
+#if Q0048_CGS_3D_ASYMLUT 
+          m_pcPredSearch->upsampleBasePic( refLayerIdc, pcPic->getFullPelBaseRec(refLayerIdc), pBaseColRec, pcPic->getPicYuvRec(), scalEL );
 #else
           m_pcPredSearch->upsampleBasePic( refLayerIdc, pcPic->getFullPelBaseRec(refLayerIdc), pcSlice->getBaseColPic(refLayerIdc)->getPicYuvRec(), pcPic->getPicYuvRec(), scalEL );
 #endif
 #endif
+#endif
         }
         else
         {
+#if Q0048_CGS_3D_ASYMLUT 
+          pcPic->setFullPelBaseRec( refLayerIdc, pBaseColRec );
+#else
           pcPic->setFullPelBaseRec( refLayerIdc, pcSlice->getBaseColPic(refLayerIdc)->getPicYuvRec() );
+#endif
         }
         pcSlice->setFullPelBaseRec ( refLayerIdc, pcPic->getFullPelBaseRec(refLayerIdc) );
@@ -1884,5 +1958,9 @@
       assert( pcSlice->getPPS()->getPPSId() == 0 || pcSlice->getPPS()->getPPSId() == m_layerId || m_pcEncTop->getVPS()->getRecursiveRefLayerFlag(m_layerId, pcSlice->getPPS()->getPPSId()) );
 #endif
-      m_pcEntropyCoder->encodePPS(pcSlice->getPPS());
+      m_pcEntropyCoder->encodePPS(pcSlice->getPPS()
+#if Q0048_CGS_3D_ASYMLUT
+        , & m_Enc3DAsymLUTPPS
+#endif
+        );
       writeRBSPTrailingBits(nalu.m_Bitstream);
       accessUnit.push_back(new NALUnitEBSP(nalu));
@@ -1917,4 +1995,17 @@
       m_bSeqFirst = false;
     }
+#if Q0048_CGS_3D_ASYMLUT
+    else if( m_pcCfg->getCGSFlag() == Q0048_CGS_3D_ASYMLUT_PPSUPDATE && pcSlice->getLayerId() && pcSlice->getCGSOverWritePPS() )
+    {
+#if SVC_EXTENSION
+      OutputNALUnit nalu(NAL_UNIT_PPS, 0, m_layerId);
+#endif
+
+      m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
+      m_pcEntropyCoder->encodePPS(pcSlice->getPPS() , &m_Enc3DAsymLUTPPS );
+      writeRBSPTrailingBits(nalu.m_Bitstream);
+      accessUnit.push_back(new NALUnitEBSP(nalu));
+    }
+#endif
 
     if (writeSOP) // write SOP description SEI (if enabled) at the beginning of GOP
@@ -3339,4 +3430,9 @@
     printf("]");
   }
+#if Q0048_CGS_3D_ASYMLUT
+  pcPic->setFrameBit( (Int)uibits );
+  if( m_layerId && pcSlice->getPPS()->getCGSFlag())
+    m_Enc3DAsymLUTPicUpdate.updatePicCGSBits( pcSlice , m_Enc3DAsymLUTPPS.getPPSBit() );
+#endif
 }
 
@@ -4045,4 +4141,223 @@
 #endif
 
+#if Q0048_CGS_3D_ASYMLUT
+Void TEncGOP::xDetermin3DAsymLUT( TComSlice * pSlice , TComPic * pCurPic , UInt refLayerIdc , TEncCfg * pCfg , Bool bSignalPPS )
+{
+  Int nCGSFlag = pSlice->getPPS()->getCGSFlag();
+  m_Enc3DAsymLUTPPS.setPPSBit( 0 );
+  Double dErrorUpdatedPPS = 0 , dErrorPPS = 0;
+  dErrorUpdatedPPS = m_Enc3DAsymLUTPicUpdate.derive3DAsymLUT( pSlice , pCurPic , refLayerIdc , pCfg , bSignalPPS , m_pcEncTop->getElRapSliceTypeB() );
+  if( bSignalPPS )
+  {
+    m_Enc3DAsymLUTPPS.copy3DAsymLUT( &m_Enc3DAsymLUTPicUpdate );
+    pSlice->setCGSOverWritePPS( 1 ); // regular PPS update
+  }
+  else if( nCGSFlag == Q0048_CGS_3D_ASYMLUT_PPSUPDATE )
+  {
+    dErrorPPS = m_Enc3DAsymLUTPPS.estimateDistWithCur3DAsymLUT( pCurPic , refLayerIdc );
+    Double dFactor = pCfg->getIntraPeriod() == 1 ? 0.99 : 0.9;
+    pSlice->setCGSOverWritePPS( dErrorUpdatedPPS < dFactor * dErrorPPS );
+    if( pSlice->getCGSOverWritePPS() )
+      m_Enc3DAsymLUTPPS.copy3DAsymLUT( &m_Enc3DAsymLUTPicUpdate );
+  }
+  pSlice->getPPS()->setCGSOutputBitDepthY( m_Enc3DAsymLUTPPS.getOutputBitDepthY() );
+  pSlice->getPPS()->setCGSOutputBitDepthC( m_Enc3DAsymLUTPPS.getOutputBitDepthC() );
+}
+
+Void TEncGOP::downScalePic( TComPicYuv* pcYuvSrc, TComPicYuv* pcYuvDest)
+{
+  Int inputBitDepth = g_bitDepthYLayer[m_layerId];
+  Int outputBitDepth = g_bitDepthYLayer[m_layerId];
+  {
+    pcYuvSrc->setBorderExtension(false);
+    pcYuvSrc->extendPicBorder   (); // extend the border.
+    pcYuvSrc->setBorderExtension(false);
+
+    Int iWidth = pcYuvSrc->getWidth();
+    Int iHeight =pcYuvSrc->getHeight(); 
+
+    if(!m_temp)
+      initDs(iWidth, iHeight, m_pcCfg->getIntraPeriod()>1);
+
+    filterImg(pcYuvSrc->getLumaAddr(), pcYuvSrc->getStride(), pcYuvDest->getLumaAddr(), pcYuvDest->getStride(), iHeight, iWidth,  inputBitDepth-outputBitDepth, 0);
+    filterImg(pcYuvSrc->getCbAddr(), pcYuvSrc->getCStride(), pcYuvDest->getCbAddr(), pcYuvDest->getCStride(), iHeight>>1, iWidth>>1, inputBitDepth-outputBitDepth, 1);
+    filterImg(pcYuvSrc->getCrAddr(), pcYuvSrc->getCStride(), pcYuvDest->getCrAddr(), pcYuvDest->getCStride(), iHeight>>1, iWidth>>1, inputBitDepth-outputBitDepth, 2);  
+  }
+}
+const int TEncGOP::m_phase_filter_0_t0[4][13]={
+  {0,  2,  -3,  -9,   6,  39,  58,  39,   6,  -9,  -3,  2,  0},  
+  {0, 0,  0,  -2,  8,-20, 116, 34, -10,  2,  0, 0,  0},                      //{0,  1,  -1,  -8,  -1,  31,  57,  47,  13,  -7,  -5,  1,  0},  //
+  {0,  1,   0,  -7,  -5,  22,  53,  53,  22,  -5,  -7,  0,  1},  
+  {0,  0,   1,  -5,  -7,  13,  47,  57,  31,  -1,  -8,-1,  1}  
+};
+
+const int TEncGOP::m_phase_filter_0_t1[4][13]={
+  {0,  4,  0,  -12, 0,  40,  64,  40, 0, -12,  0,  4,  0},
+  {0, 0,  0,  -2,  8,-20, 116,34,-10,  2,  0, 0,  0},                      //{0,  1,  -1,  -8,  -1,  31,  57,  47,  13,  -7,  -5,  1,  0},  //
+  {0,  1,   0,  -7,  -5,  22,  53,  53,  22,  -5,  -7,  0,  1},  
+  {0,  0,   1,  -5,  -7,  13,  47,  57,  31,  -1,  -8,-1,  1}  
+};
+const int TEncGOP::m_phase_filter_0_t1_chroma[4][13]={
+  {0,  0,  0,   0,  0,   0,  128, 0,  0,  0,  0,  0,  0},
+  {0, 0,  0,  -2,  8,-20, 116,34,-10,  2,  0, 0,  0},                      //{0,  1,  -1,  -8,  -1,  31,  57,  47,  13,  -7,  -5,  1,  0},  //
+  {0,  1,   0,  -7,  -5,  22,  53,  53,  22,  -5,  -7,  0,  1},  
+  {0,  0,   1,  -5,  -7,  13,  47,  57,  31,  -1,  -8,-1,  1}  
+};
+
+const int TEncGOP::m_phase_filter_1[8][13]={
+  {0,   0,  5,  -6,  -10,37,  76,  37,-10,   -6, 5,  0,   0},    
+  {0,  -1,  5,  -3,  -12,29,  75,  45,  -7,   -8, 5,  0,   0},    
+  {0,  -1,  4,  -1,  -13,22,  73,  52,  -3,  -10, 4,  1,   0},    
+  {0,  -1,  4,   1,  -13,14,  70,  59,   2,  -12, 3,  2,  -1},  
+  {0,  -1,  3,   2,  -13, 8,  65,  65,   8,  -13, 2,  3,  -1},    
+  {0,  -1,  2,   3,  -12, 2,  59,  70,  14,  -13, 1,  4,  -1},    
+  {0,   0,  1,   4,  -10,-3,  52,  73,  22,  -13,-1,  4,  -1},    
+  {0,   0,  0,   5,   -8,-7,  45,  75,  29,  -12,-3,  5,  -1}    
+};
+
+Void TEncGOP::filterImg(
+    Pel           *src,
+    Int           iSrcStride,
+    Pel           *dst,
+    Int           iDstStride,
+    Int           height1,  
+    Int           width1,  
+    Int           shift,
+    Int           plane)
+{
+  Int length = m_iTap;
+  Int height2,width2;
+  Int k,iSum;
+  Int i0, div_i0, i1;
+  Int j0, div_j0, j1;
+  const Int *p_filter;
+  Pel *p_src, *p_dst;
+  Pel *p_src_line, *p_dst_line;
+  Int **p_temp, *p_tmp;
+  Int shift2 = 2*7+shift;
+  Int shift_round = (1 << (shift2 - 1));
+  Int iMax = (1<<(g_bitDepthY-shift))-1;
+  height2 = (height1 * m_iM) / m_iN;
+  width2  = (width1  * m_iM) / m_iN;
+
+  m_phase_filter = plane? m_phase_filter_chroma : m_phase_filter_luma;
+
+  // horizontal filtering
+  p_src_line = src;
+  for(j1 = 0; j1 < height1; j1++)
+  {
+    i0=-m_iN;
+    p_tmp = m_temp[j1];
+    
+    for(i1 = 0; i1 < width2; i1++)
+    {
+      i0      += m_iN;
+      div_i0   = (i0 / m_iM);
+      //p_src    = &src[j1][ div_i0 - (length >> 1)];
+      p_src    =  p_src_line + ( div_i0 - (length >> 1));
+      p_filter = m_phase_filter[i0 - div_i0 * m_iM]; // phase_filter[i0 % M]
+      iSum     = 0;
+      for(k = 0; k < length; k++)
+      {
+        iSum += (*p_src++) * (*p_filter++);
+      }
+      *p_tmp++ = iSum;
+    }
+    p_src_line +=  iSrcStride;
+  }
+
+  // pad temp (vertical)
+  for (k=-(length>>1); k<0; k++)
+    memcpy(m_temp[k], m_temp[0], width2*sizeof(int));
+  for (k=height1; k<(height1+(length>>1)); k++)
+    memcpy(m_temp[k], m_temp[k-1], (width2)* sizeof(int));
+
+  // vertical filtering
+  j0 = (plane == 0) ? -m_iN : -(m_iN-1);
+  
+  p_dst_line = dst;
+  for(j1 = 0; j1 < height2; j1++)
+  {
+    j0      += m_iN;
+    div_j0   = (j0 / m_iM);
+    //p_dst    = dst[j1];
+    p_dst = p_dst_line;
+    p_temp   = &m_temp[div_j0 - (length>>1)];
+    p_filter = m_phase_filter[j0 - div_j0 * m_iM]; // phase_filter[j0 % M]
+    for(i1 = 0; i1 < width2;i1++)
+    {
+      iSum=0;
+      for(k = 0; k < length; k++)
+      {
+        iSum += p_temp[k][i1] * p_filter[k];
+      }
+      iSum=((iSum + shift_round) >> shift2);
+      *p_dst++ = (short)(iSum > iMax ? iMax : (iSum < 0 ? 0 : iSum));
+    }
+    p_dst_line += iDstStride;
+  }
+}
+
+Void TEncGOP::initDs(Int iWidth, Int iHeight, Int iType)
+{
+  m_iTap = 13;
+  if(g_posScalingFactor[0][0] == (1<<15))
+  {
+    m_iM = 4;
+    m_iN = 8;
+    m_phase_filter_luma = iType? m_phase_filter_0_t1 : m_phase_filter_0_t0;
+    m_phase_filter_chroma = m_phase_filter_0_t1_chroma; 
+  }
+  else
+  {
+    m_iM = 8;
+    m_iN = 12;
+    m_phase_filter_luma = m_phase_filter_chroma =  m_phase_filter_1;
+    m_phase_filter = m_phase_filter_1;
+  }
+
+  get_mem2DintWithPad (&m_temp, iHeight, iWidth*m_iM/m_iN,   m_iTap>>1, 0);
+}
+
+Int TEncGOP::get_mem2DintWithPad(Int ***array2D, Int dim0, Int dim1, Int iPadY, Int iPadX)
+{
+  Int i;
+  Int *curr = NULL;
+  Int iHeight, iWidth;
+
+  iHeight = dim0+2*iPadY;
+  iWidth = dim1+2*iPadX;
+  (*array2D) = (Int**)malloc(iHeight*sizeof(Int*));
+  *(*array2D) = (Int* )xMalloc(Int, iHeight*iWidth);
+
+  (*array2D)[0] += iPadX;
+  curr = (*array2D)[0];
+  for(i = 1 ; i < iHeight; i++)
+  {
+    curr += iWidth;
+    (*array2D)[i] = curr;
+  }
+  (*array2D) = &((*array2D)[iPadY]);
+
+  return 0;
+}
+
+Void TEncGOP::free_mem2DintWithPad(Int **array2D, Int iPadY, Int iPadX)
+{
+  if (array2D)
+  {
+    if (*array2D)
+      xFree(array2D[-iPadY]-iPadX);
+    else 
+      printf("free_mem2DintWithPad: trying to free unused memory\r\nPress Any Key\r\n");
+
+    free (&array2D[-iPadY]);
+  } 
+  else
+  {
+    printf("free_mem2DintWithPad: trying to free unused memory\r\nPress Any Key\r\n");
+  }
+}
+#endif
 #endif //SVC_EXTENSION
 
Index: /branches/SHM-6-dev/source/Lib/TLibEncoder/TEncGOP.h
===================================================================
--- /branches/SHM-6-dev/source/Lib/TLibEncoder/TEncGOP.h	(revision 676)
+++ /branches/SHM-6-dev/source/Lib/TLibEncoder/TEncGOP.h	(revision 677)
@@ -54,4 +54,7 @@
 #include "TEncSbac.h"
 #include "SEIwrite.h"
+#if Q0048_CGS_3D_ASYMLUT
+#include "TEnc3DAsymLUT.h"
+#endif
 
 #include "TEncAnalyze.h"
@@ -135,4 +138,20 @@
   TEncSearch*             m_pcPredSearch;                       ///< encoder search class
 #endif  
+#if Q0048_CGS_3D_ASYMLUT
+  TEnc3DAsymLUT           m_Enc3DAsymLUTPicUpdate;
+  TEnc3DAsymLUT           m_Enc3DAsymLUTPPS;
+  TComPicYuv*             m_pColorMappedPic;
+
+  Int m_iTap;
+  const Int (*m_phase_filter)[13];
+  const Int (*m_phase_filter_luma)[13];
+  const Int (*m_phase_filter_chroma)[13];
+  Int m_iM, m_iN;
+  static const Int m_phase_filter_0_t0[4][13];
+  static const Int m_phase_filter_0_t1[4][13];
+  static const Int m_phase_filter_0_t1_chroma[4][13];
+  static const Int m_phase_filter_1[8][13];
+  Int   **m_temp;
+#endif
 #endif
   
@@ -217,4 +236,23 @@
   SEIScalableNesting* xCreateBspNestingSEI(TComSlice *pcSlice);
 #endif
+#if Q0048_CGS_3D_ASYMLUT
+  Void xDetermin3DAsymLUT( TComSlice * pSlice , TComPic * pCurPic , UInt refLayerIdc , TEncCfg * pCfg , Bool bSignalPPS );
+  Void downScalePic( TComPicYuv* pcYuvSrc, TComPicYuv* pcYuvDest);
+  Void downScaleComponent2x2( const Pel* pSrc, Pel* pDest, const Int iSrcStride, const Int iDestStride, const Int iSrcWidth, const Int iSrcHeight, const Int inputBitDepth, const Int outputBitDepth );
+  inline Short  xClip( Short x , Int bitdepth );
+  Void initDs(Int iWidth, Int iHeight, Int iType);
+  Void filterImg(
+    Pel           *src,
+    Int           iSrcStride,
+    Pel           *dst,
+    Int           iDstStride,
+    Int           height1,  
+    Int           width1,  
+    Int           shift,
+    Int           plane);
+
+  Int get_mem2DintWithPad(Int ***array2D, Int dim0, Int dim1, Int iPadY, Int iPadX);
+  Void free_mem2DintWithPad(Int **array2D, Int iPadY, Int iPadX);
+#endif
 #endif //SVC_EXTENSION
 };// END CLASS DEFINITION TEncGOP
Index: /branches/SHM-6-dev/source/Lib/TLibEncoder/TEncSbac.cpp
===================================================================
--- /branches/SHM-6-dev/source/Lib/TLibEncoder/TEncSbac.cpp	(revision 676)
+++ /branches/SHM-6-dev/source/Lib/TLibEncoder/TEncSbac.cpp	(revision 677)
@@ -248,5 +248,9 @@
 }
 
-Void TEncSbac::codePPS( TComPPS* pcPPS )
+Void TEncSbac::codePPS( TComPPS* pcPPS 
+#if Q0048_CGS_3D_ASYMLUT
+  , TEnc3DAsymLUT * pc3DAsymLUT
+#endif
+  )
 {
   assert (0);
Index: /branches/SHM-6-dev/source/Lib/TLibEncoder/TEncSbac.h
===================================================================
--- /branches/SHM-6-dev/source/Lib/TLibEncoder/TEncSbac.h	(revision 676)
+++ /branches/SHM-6-dev/source/Lib/TLibEncoder/TEncSbac.h	(revision 677)
@@ -92,5 +92,9 @@
   Void  codeVPS                 ( TComVPS* pcVPS );
   Void  codeSPS                 ( TComSPS* pcSPS     );
-  Void  codePPS                 ( TComPPS* pcPPS     );
+  Void  codePPS                 ( TComPPS* pcPPS     
+#if Q0048_CGS_3D_ASYMLUT
+    , TEnc3DAsymLUT * pc3DAsymLUT
+#endif
+    );
   Void  codeSliceHeader         ( TComSlice* pcSlice );
   Void  codeTilesWPPEntryPoint( TComSlice* pSlice );
Index: /branches/SHM-6-dev/source/Lib/TLibEncoder/TEncTop.cpp
===================================================================
--- /branches/SHM-6-dev/source/Lib/TLibEncoder/TEncTop.cpp	(revision 676)
+++ /branches/SHM-6-dev/source/Lib/TLibEncoder/TEncTop.cpp	(revision 677)
@@ -795,5 +795,9 @@
           Bool sameBitDepths = ( g_bitDepthYLayer[m_layerId] == g_bitDepthYLayer[refLayerId] ) && ( g_bitDepthCLayer[m_layerId] == g_bitDepthCLayer[refLayerId] );
 
-          if( m_iSourceWidth != pcEncTopBase->getSourceWidth() || m_iSourceHeight != pcEncTopBase->getSourceHeight() || !zeroOffsets || !sameBitDepths )
+          if( m_iSourceWidth != pcEncTopBase->getSourceWidth() || m_iSourceHeight != pcEncTopBase->getSourceHeight() || !zeroOffsets || !sameBitDepths 
+#if Q0048_CGS_3D_ASYMLUT
+            || m_cPPS.getCGSFlag() > 0
+#endif
+            )
 #else
           if(m_iSourceWidth != pcEncTopBase->getSourceWidth() || m_iSourceHeight != pcEncTopBase->getSourceHeight() || !zeroOffsets )
@@ -1188,4 +1192,7 @@
   }
 #endif
+#if Q0048_CGS_3D_ASYMLUT
+  m_cPPS.setCGSFlag( m_nCGSFlag );
+#endif
 }
 
