Index: trunk/source/Lib/TLibEncoder/AnnexBwrite.h
===================================================================
--- trunk/source/Lib/TLibEncoder/AnnexBwrite.h	(revision 649)
+++ trunk/source/Lib/TLibEncoder/AnnexBwrite.h	(revision 713)
@@ -58,5 +58,5 @@
 
     static const Char start_code_prefix[] = {0,0,0,1};
-    if (it == au.begin() || nalu.m_nalUnitType == NAL_UNIT_SPS || nalu.m_nalUnitType == NAL_UNIT_PPS)
+    if (it == au.begin() || nalu.m_nalUnitType == NAL_UNIT_VPS || nalu.m_nalUnitType == NAL_UNIT_SPS || nalu.m_nalUnitType == NAL_UNIT_PPS)
     {
       /* From AVC, When any of the following conditions are fulfilled, the
Index: trunk/source/Lib/TLibEncoder/NALwrite.cpp
===================================================================
--- trunk/source/Lib/TLibEncoder/NALwrite.cpp	(revision 649)
+++ trunk/source/Lib/TLibEncoder/NALwrite.cpp	(revision 713)
@@ -91,7 +91,8 @@
   vector<uint8_t>& rbsp   = nalu.m_Bitstream.getFIFO();
 
-#if P0130_EOB
-  if (rbsp.size() == 0) return;
-#endif
+  if (rbsp.size() == 0)
+  {
+    return;
+  }
 
   for (vector<uint8_t>::iterator it = rbsp.begin(); it != rbsp.end();)
Index: trunk/source/Lib/TLibEncoder/SEIwrite.cpp
===================================================================
--- trunk/source/Lib/TLibEncoder/SEIwrite.cpp	(revision 649)
+++ trunk/source/Lib/TLibEncoder/SEIwrite.cpp	(revision 713)
@@ -87,4 +87,9 @@
     fprintf( g_hTrace, "=========== Tone Mapping Info SEI message ===========\n");
     break;
+#if Q0074_SEI_COLOR_MAPPING
+  case SEI::COLOR_MAPPING_INFO:
+    fprintf( g_hTrace, "=========== Color Mapping Info SEI message ===========\n");
+    break;
+#endif
   case SEI::SOP_DESCRIPTION:
     fprintf( g_hTrace, "=========== SOP Description SEI message ===========\n");
@@ -172,4 +177,9 @@
     xWriteSEIToneMappingInfo(*static_cast<const SEIToneMappingInfo*>(&sei));
     break;
+#if Q0074_SEI_COLOR_MAPPING
+  case SEI::COLOR_MAPPING_INFO:
+    xWriteSEIColorMappingInfo(*static_cast<const SEIColorMappingInfo*>(&sei));
+    break;
+#endif
   case SEI::SOP_DESCRIPTION:
     xWriteSEISOPDescription(*static_cast<const SEISOPDescription*>(&sei));
@@ -333,27 +343,16 @@
 Void SEIWriter::xWriteSEIActiveParameterSets(const SEIActiveParameterSets& sei)
 {
-  WRITE_CODE(sei.activeVPSId,     4, "active_vps_id");
-  WRITE_FLAG(sei.m_fullRandomAccessFlag, "full_random_access_flag");
-  WRITE_FLAG(sei.m_noParamSetUpdateFlag, "no_param_set_update_flag");
+  WRITE_CODE(sei.activeVPSId,     4,         "active_video_parameter_set_id");
+  WRITE_FLAG(sei.m_selfContainedCvsFlag,     "self_contained_cvs_flag");
+  WRITE_FLAG(sei.m_noParameterSetUpdateFlag, "no_parameter_set_update_flag");
   WRITE_UVLC(sei.numSpsIdsMinus1,    "num_sps_ids_minus1");
 
-  assert (sei.activeSeqParamSetId.size() == (sei.numSpsIdsMinus1 + 1));
-
-  for (Int i = 0; i < sei.activeSeqParamSetId.size(); i++)
-  {
-    WRITE_UVLC(sei.activeSeqParamSetId[i], "active_seq_param_set_id"); 
-  }
-
-  UInt uiBits = m_pcBitIf->getNumberOfWrittenBits();
-  UInt uiAlignedBits = ( 8 - (uiBits&7) ) % 8;  
-  if(uiAlignedBits) 
-  {
-    WRITE_FLAG(1, "alignment_bit" );
-    uiAlignedBits--; 
-    while(uiAlignedBits--)
-    {
-      WRITE_FLAG(0, "alignment_bit" );
-    }
-  }
+  assert (sei.activeSeqParameterSetId.size() == (sei.numSpsIdsMinus1 + 1));
+
+  for (Int i = 0; i < sei.activeSeqParameterSetId.size(); i++)
+  {
+    WRITE_UVLC(sei.activeSeqParameterSetId[i], "active_seq_parameter_set_id"); 
+  }
+  xWriteByteAlign();
 }
 
@@ -550,4 +549,9 @@
         {
           WRITE_CODE( sei.m_cameraIsoSpeedValue,    32,    "camera_iso_speed_value" );
+        }
+        WRITE_CODE( sei.m_exposureIndexIdc,     8,    "exposure_index_idc" );
+        if( sei.m_exposureIndexIdc == 255) //Extended_ISO
+        {
+          WRITE_CODE( sei.m_exposureIndexValue,     32,    "exposure_index_value" );
         }
         WRITE_FLAG( sei.m_exposureCompensationValueSignFlag,           "exposure_compensation_value_sign_flag" );
@@ -572,4 +576,65 @@
 }
 
+#if Q0074_SEI_COLOR_MAPPING
+Void SEIWriter::xWriteSEIColorMappingInfo(const SEIColorMappingInfo& sei)
+{
+  WRITE_UVLC( sei.m_colorMapId,                    "colour_map_id" );
+  WRITE_FLAG( sei.m_colorMapCancelFlag,            "colour_map_cancel_flag" );
+  if( !sei.m_colorMapCancelFlag ) 
+  {
+    WRITE_FLAG( sei.m_colorMapPersistenceFlag,            "colour_map_persistence_flag" );
+    WRITE_FLAG( sei.m_colorMap_video_signal_type_present_flag,            "colour_map_video_signal_type_present_flag" );
+    if ( sei.m_colorMap_video_signal_type_present_flag )
+    {
+      WRITE_FLAG( sei.m_colorMap_video_full_range_flag,       "colour_map_video_full_range_flag" );
+      WRITE_CODE( sei.m_colorMap_primaries,                 8,      "colour_map_primaries" );
+      WRITE_CODE( sei.m_colorMap_transfer_characteristics,  8,      "colour_map_transfer_characteristics" );
+      WRITE_CODE( sei.m_colorMap_matrix_coeffs,             8,      "colour_map_matrix_coeffs" );
+    }
+  }
+
+  WRITE_CODE( sei.m_colour_map_coded_data_bit_depth,  5,  "colour_map_coded_data_bit_depth" );
+  WRITE_CODE( sei.m_colour_map_target_bit_depth,  5,      "colour_map_target_bit_depth" );
+  WRITE_UVLC( sei.m_colorMapModelId,                      "colour_map_model_id" );
+
+  assert( sei.m_colorMapModelId == 0 );
+  
+  for( Int i=0 ; i<3 ; i++ )
+  {
+    WRITE_CODE( sei.m_num_input_pivots[i] - 1,         8,      "num_input_pivots_minus1[i]" );
+    for( Int j=0 ; j<sei.m_num_input_pivots[i] ; j++ )
+    {
+      WRITE_CODE( sei.m_coded_input_pivot_value[i][j],  (( sei.m_colour_map_coded_data_bit_depth + 7 ) >> 3 ) << 3, "coded_input_pivot_value[i][j]" );
+      WRITE_CODE( sei.m_target_input_pivot_value[i][j], (( sei.m_colour_map_coded_data_bit_depth + 7 ) >> 3 ) << 3, "target_input_pivot_value[i][j]" );
+    }
+  }
+
+  WRITE_FLAG( sei.m_matrix_flag,            "matrix_flag" );
+  if( sei.m_matrix_flag )
+  {
+    WRITE_CODE( sei.m_log2_matrix_denom, 4, "log2_matrix_denom" );
+    for( Int i=0 ; i<3 ; i++ )
+    {
+      for( Int j=0 ; j<3 ; j++ )
+      {
+        WRITE_SVLC( sei.m_matrix_coef[i][j],  "matrix_coef[i][j]" );
+      }
+    }
+  }
+
+  for( Int i=0 ; i<3 ; i++ )
+  {
+    WRITE_CODE( sei.m_num_output_pivots[i] - 1,         8,      "num_output_pivots_minus1[i]" );
+    for( Int j=0 ; j<sei.m_num_output_pivots[i] ; j++ )
+    {
+      WRITE_CODE( sei.m_coded_output_pivot_value[i][j],  (( sei.m_colour_map_coded_data_bit_depth + 7 ) >> 3 ) << 3, "coded_output_pivot_value[i][j]" );
+      WRITE_CODE( sei.m_target_output_pivot_value[i][j], (( sei.m_colour_map_coded_data_bit_depth + 7 ) >> 3 ) << 3, "target_output_pivot_value[i][j]" );
+    }
+  }
+
+  xWriteByteAlign();
+}
+#endif
+
 Void SEIWriter::xWriteSEIDisplayOrientation(const SEIDisplayOrientation &sei)
 {
@@ -633,4 +698,5 @@
     for (UInt i = (sei.m_defaultOpFlag ? 1 : 0); i <= sei.m_nestingNumOpsMinus1; i++)
     {
+      WRITE_CODE( sei.m_nestingNoOpMaxTemporalIdPlus1, 3, "nesting_no_op_max_temporal_id" );
       WRITE_CODE( sei.m_nestingMaxTemporalIdPlus1[i], 3,  "nesting_max_temporal_id"       );
       WRITE_UVLC( sei.m_nestingOpIdx[i],                  "nesting_op_idx"                );
Index: trunk/source/Lib/TLibEncoder/SEIwrite.h
===================================================================
--- trunk/source/Lib/TLibEncoder/SEIwrite.h	(revision 649)
+++ trunk/source/Lib/TLibEncoder/SEIwrite.h	(revision 713)
@@ -72,4 +72,7 @@
   Void xWriteSEIGradualDecodingRefreshInfo(const SEIGradualDecodingRefreshInfo &sei);
   Void xWriteSEIToneMappingInfo(const SEIToneMappingInfo& sei);
+#if Q0074_SEI_COLOR_MAPPING
+  Void xWriteSEIColorMappingInfo(const SEIColorMappingInfo& sei);
+#endif
   Void xWriteSEISOPDescription(const SEISOPDescription& sei);
 #if O0164_MULTI_LAYER_HRD
Index: trunk/source/Lib/TLibEncoder/TEnc3DAsymLUT.cpp
===================================================================
--- trunk/source/Lib/TLibEncoder/TEnc3DAsymLUT.cpp	(revision 713)
+++ trunk/source/Lib/TLibEncoder/TEnc3DAsymLUT.cpp	(revision 713)
@@ -0,0 +1,470 @@
+#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.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() ) 
+  {
+    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: trunk/source/Lib/TLibEncoder/TEnc3DAsymLUT.h
===================================================================
--- trunk/source/Lib/TLibEncoder/TEnc3DAsymLUT.h	(revision 713)
+++ trunk/source/Lib/TLibEncoder/TEnc3DAsymLUT.h	(revision 713)
@@ -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: trunk/source/Lib/TLibEncoder/TEncCavlc.cpp
===================================================================
--- trunk/source/Lib/TLibEncoder/TEncCavlc.cpp	(revision 649)
+++ trunk/source/Lib/TLibEncoder/TEncCavlc.cpp	(revision 713)
@@ -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() )
+      {
+        assert( pc3DAsymLUT != NULL );
+        xCode3DAsymLUT( pc3DAsymLUT );
+      }
+      pc3DAsymLUT->setPPSBit( getNumberOfWrittenBits() - uiPos );
+#endif
 #endif
     }
@@ -495,8 +509,15 @@
   if (conf.getWindowEnabledFlag())
   {
+#if REPN_FORMAT_IN_VPS
+    WRITE_UVLC( conf.getWindowLeftOffset(),   "conf_win_left_offset"   );
+    WRITE_UVLC( conf.getWindowRightOffset(),  "conf_win_right_offset"  );
+    WRITE_UVLC( conf.getWindowTopOffset(),    "conf_win_top_offset"    );
+    WRITE_UVLC( conf.getWindowBottomOffset(), "conf_win_bottom_offset" );
+#else
     WRITE_UVLC( conf.getWindowLeftOffset()   / TComSPS::getWinUnitX(pcSPS->getChromaFormatIdc() ), "conf_win_left_offset" );
     WRITE_UVLC( conf.getWindowRightOffset()  / TComSPS::getWinUnitX(pcSPS->getChromaFormatIdc() ), "conf_win_right_offset" );
     WRITE_UVLC( conf.getWindowTopOffset()    / TComSPS::getWinUnitY(pcSPS->getChromaFormatIdc() ), "conf_win_top_offset" );
     WRITE_UVLC( conf.getWindowBottomOffset() / TComSPS::getWinUnitY(pcSPS->getChromaFormatIdc() ), "conf_win_bottom_offset" );
+#endif
   }
 
@@ -777,9 +798,14 @@
     }
   }
-#if !VPS_EXTNS
-  WRITE_FLAG( 0,                     "vps_extension_flag" );
-#else
-  WRITE_FLAG( 1,                     "vps_extension_flag" );
-  if(1) // Should be conditioned on the value of vps_extension_flag
+#if VPS_EXTNS
+  // When MaxLayersMinus1 is greater than 0, vps_extension_flag shall be equal to 1.
+  if( pcVPS->getMaxLayers() > 1 )
+  {
+    assert( pcVPS->getVpsExtensionFlag() == true );
+  }
+
+  WRITE_FLAG( pcVPS->getVpsExtensionFlag() ? 1 : 0,                     "vps_extension_flag" );
+
+  if( pcVPS->getVpsExtensionFlag() )
   {
     while ( m_pcBitIf->getNumberOfWrittenBits() % 8 != 0 )
@@ -797,4 +823,6 @@
     WRITE_FLAG( 0,                     "vps_extension2_flag" );   // Flag value of 1 reserved
   }
+#else
+  WRITE_FLAG( 0,                     "vps_extension_flag" );
 #endif  
   //future extensions here..
@@ -996,8 +1024,22 @@
   }
 #else
-  Int numOutputLayerSets = vps->getNumOutputLayerSets() ;
-  assert( numOutputLayerSets - (Int)vps->getNumLayerSets() >= 0 );
+  Int numOutputLayerSets = vps->getNumOutputLayerSets();
+  Int numAddOutputLayerSets = numOutputLayerSets - (Int)vps->getNumLayerSets();
+
+  // The value of num_add_output_layer_sets shall be in the range of 0 to 1023, inclusive.
+  assert( numAddOutputLayerSets >= 0 && numAddOutputLayerSets < 1024 );
+
+#if Q0165_NUM_ADD_OUTPUT_LAYER_SETS
+  if( vps->getNumLayerSets() > 1 )
+  {
+    WRITE_UVLC( numAddOutputLayerSets, "num_add_output_layer_sets" );
+    WRITE_CODE( vps->getDefaultTargetOutputLayerIdc(), 2, "default_target_output_layer_idc" );
+  }
+#else
   WRITE_UVLC( numOutputLayerSets - vps->getNumLayerSets(), "num_add_output_layer_sets" );
 #endif
+#endif
+
+#if !Q0165_NUM_ADD_OUTPUT_LAYER_SETS
   if( numOutputLayerSets > 1 )
   {
@@ -1012,4 +1054,5 @@
 #endif
   }
+#endif
 
   for(i = 1; i < numOutputLayerSets; i++)
@@ -1059,4 +1102,9 @@
       WRITE_FLAG(vps->getAltOuputLayerFlag(i), "alt_output_layer_flag[i]");
     }
+
+#if Q0165_OUTPUT_LAYER_SET
+    assert( NumOutputLayersInOutputLayerSet[i]>0 );
+#endif
+
 #endif
   }
@@ -1072,8 +1120,46 @@
 
 #if REPN_FORMAT_IN_VPS
+#if Q0195_REP_FORMAT_CLEANUP  
+  // The value of vps_num_rep_formats_minus1 shall be in the range of 0 to 255, inclusive.
+  assert( vps->getVpsNumRepFormats() > 0 && vps->getVpsNumRepFormats() <= 256 );
+  
+  WRITE_UVLC( vps->getVpsNumRepFormats() - 1, "vps_num_rep_formats_minus1" );
+
+  for(i = 0; i < vps->getVpsNumRepFormats(); i++)
+  {
+    // Write rep_format_structures
+    codeRepFormat( vps->getVpsRepFormat(i) );
+  }
+
+  if( vps->getVpsNumRepFormats() > 1 )
+  {
+    WRITE_FLAG( vps->getRepFormatIdxPresentFlag(), "rep_format_idx_present_flag"); 
+  }
+  else
+  {
+    // When not present, the value of rep_format_idx_present_flag is inferred to be equal to 0
+    assert( !vps->getRepFormatIdxPresentFlag() );
+  }
+
+  if( vps->getRepFormatIdxPresentFlag() )
+  {
+    for(i = 1; i < vps->getMaxLayers(); i++)
+    {
+      Int numBits = 1;
+      while ((1 << numBits) < (vps->getVpsNumRepFormats()))
+      {
+        numBits++;
+      }
+      WRITE_CODE( vps->getVpsRepFormatIdx(i), numBits, "vps_rep_format_idx[i]" );
+    }
+  }
+#else
   WRITE_FLAG( vps->getRepFormatIdxPresentFlag(), "rep_format_idx_present_flag"); 
 
   if( vps->getRepFormatIdxPresentFlag() )
   {
+    // The value of vps_num_rep_formats_minus1 shall be in the range of 0 to 255, inclusive.
+    assert( vps->getVpsNumRepFormats() > 0 && vps->getVpsNumRepFormats() <= 256 );
+
 #if O0096_REP_FORMAT_INDEX
 #if !VPS_EXTN_UEV_CODING
@@ -1115,4 +1201,5 @@
     }
   }
+#endif
 #endif
 
@@ -1181,4 +1268,7 @@
 
 #if P0307_VPS_NON_VUI_EXTENSION
+  // The value of vps_non_vui_extension_length shall be in the range of 0 to 4096, inclusive.
+  assert( vps->getVpsNonVuiExtLength() >= 0 && vps->getVpsNonVuiExtLength() <= 4096 );
+
   WRITE_UVLC( vps->getVpsNonVuiExtLength(), "vps_non_vui_extension_length" );
 #if P0307_VPS_NON_VUI_EXT_UPDATE
@@ -1216,6 +1306,6 @@
 #else
 #if P0307_REMOVE_VPS_VUI_OFFSET
-  WRITE_FLAG( 1,                     "vps_vui_present_flag" );
   vps->setVpsVuiPresentFlag(true);
+  WRITE_FLAG( vps->getVpsVuiPresentFlag() ? 1 : 0,                     "vps_vui_present_flag" );
 #endif
   if(vps->getVpsVuiPresentFlag())   // Should be conditioned on the value of vps_vui_present_flag
@@ -1238,26 +1328,25 @@
 #endif
 #if REPN_FORMAT_IN_VPS
-Void  TEncCavlc::codeRepFormat      ( RepFormat *repFormat )
+Void  TEncCavlc::codeRepFormat( RepFormat *repFormat )
 {
 #if REPN_FORMAT_CONTROL_FLAG
-   WRITE_FLAG ( repFormat->getChromaAndBitDepthVpsPresentFlag(), "chroma_and_bit_depth_vps_presenet_flag"); 
-
-   WRITE_CODE ( repFormat->getPicWidthVpsInLumaSamples (), 16, "pic_width_in_luma_samples" );    
-   WRITE_CODE ( repFormat->getPicHeightVpsInLumaSamples(), 16, "pic_height_in_luma_samples" );  
-
-   if ( repFormat->getChromaAndBitDepthVpsPresentFlag() )
-   {
-     WRITE_CODE( repFormat->getChromaFormatVpsIdc(), 2, "chroma_format_idc" );   
-
-     if( repFormat->getChromaFormatVpsIdc() == 3 )
-     {
-       WRITE_FLAG( repFormat->getSeparateColourPlaneVpsFlag(), "separate_colour_plane_flag");      
-     }
-
-     assert( repFormat->getBitDepthVpsLuma() >= 8 );
-     assert( repFormat->getBitDepthVpsChroma() >= 8 );
-     WRITE_CODE( repFormat->getBitDepthVpsLuma() - 8,   4, "bit_depth_luma_minus8" );           
-     WRITE_CODE( repFormat->getBitDepthVpsChroma() - 8, 4, "bit_depth_chroma_minus8" );
-   }
+  WRITE_CODE( repFormat->getPicWidthVpsInLumaSamples (), 16, "pic_width_vps_in_luma_samples" );    
+  WRITE_CODE( repFormat->getPicHeightVpsInLumaSamples(), 16, "pic_height_vps_in_luma_samples" );  
+  WRITE_FLAG( repFormat->getChromaAndBitDepthVpsPresentFlag(), "chroma_and_bit_depth_vps_present_flag" );
+
+  if( repFormat->getChromaAndBitDepthVpsPresentFlag() )
+  {
+    WRITE_CODE( repFormat->getChromaFormatVpsIdc(), 2, "chroma_format_vps_idc" );   
+
+    if( repFormat->getChromaFormatVpsIdc() == 3 )
+    {
+      WRITE_FLAG( repFormat->getSeparateColourPlaneVpsFlag(), "separate_colour_plane_vps_flag" );      
+    }
+
+    assert( repFormat->getBitDepthVpsLuma() >= 8 );
+    assert( repFormat->getBitDepthVpsChroma() >= 8 );
+    WRITE_CODE( repFormat->getBitDepthVpsLuma() - 8,   4, "bit_depth_vps_luma_minus8" );           
+    WRITE_CODE( repFormat->getBitDepthVpsChroma() - 8, 4, "bit_depth_vps_chroma_minus8" );
+  }
 #else 
   WRITE_CODE( repFormat->getChromaFormatVpsIdc(), 2, "chroma_format_idc" );    
@@ -1275,6 +1364,5 @@
   WRITE_CODE( repFormat->getBitDepthVpsLuma() - 8,   4, "bit_depth_luma_minus8" );           
   WRITE_CODE( repFormat->getBitDepthVpsChroma() - 8, 4, "bit_depth_chroma_minus8" );
-#endif 
-
+#endif
 }
 #endif
@@ -1375,9 +1463,9 @@
         if( vps->getBitRatePresentVpsFlag() )
         {
-          WRITE_FLAG( vps->getBitRatePresentFlag( i, j),        "bit_rate_present_vps_flag[i][j]" );
+          WRITE_FLAG( vps->getBitRatePresentFlag( i, j),        "bit_rate_present_flag[i][j]" );
         }
         if( vps->getPicRatePresentVpsFlag() )
         {
-          WRITE_FLAG( vps->getPicRatePresentFlag( i, j),        "pic_rate_present_vps_flag[i][j]" );
+          WRITE_FLAG( vps->getPicRatePresentFlag( i, j),        "pic_rate_present_flag[i][j]" );
         }
         if( vps->getBitRatePresentFlag(i, j) )
@@ -1466,4 +1554,10 @@
 #endif
 #if HIGHER_LAYER_IRAP_SKIP_FLAG
+  // When single_layer_for_non_irap_flag is equal to 0, higher_layer_irap_skip_flag shall be equal to 0
+  if( !vps->getSingleLayerForNonIrapFlag() )
+  {
+    assert( !vps->getHigherLayerIrapSkipFlag() );
+  }
+
   WRITE_FLAG(vps->getHigherLayerIrapSkipFlag(), "higher_layer_irap_skip_flag" );
 #endif
@@ -1564,10 +1658,9 @@
     for(i = 1; i < vps->getMaxLayers(); i++)
     {
-      if(vps->getNumRefLayers(vps->getLayerIdInNuh(i)) == 0) 
-      {
-        if ((vps->getSPSId(i) == 0) && (vps->getPPSId(i) == 0))
+      if( vps->getNumRefLayers(vps->getLayerIdInNuh(i)) == 0 ) 
+      {
+        if( (vps->getSPSId(i) == 0) && (vps->getPPSId(i) == 0) )
         {
           vps->setBaseLayerPSCompatibilityFlag(i, 1);
-          WRITE_FLAG(vps->getBaseLayerPSCompatibilityFlag(i), "base_layer_parameter_set_compatibility_flag" );
         }
         else
@@ -1575,4 +1668,5 @@
           vps->setBaseLayerPSCompatibilityFlag(i, 0);
         }
+        WRITE_FLAG(vps->getBaseLayerPSCompatibilityFlag(i), "base_layer_parameter_set_compatibility_flag" );
       }
     }
@@ -1612,6 +1706,6 @@
   if ( pcSlice->getRapPicFlag() )
   {
-#if NO_OUTPUT_OF_PRIOR_PICS
-    WRITE_FLAG( pcSlice->getNoOutputOfPriorPicsFlag(), "no_output_of_prior_pics_flag" );
+#if SETTING_NO_OUT_PIC_PRIOR
+    WRITE_FLAG( pcSlice->getNoOutputPriorPicsFlag() ? 1 : 0, "no_output_of_prior_pics_flag" );
 #else
     WRITE_FLAG( 0, "no_output_of_prior_pics_flag" );
@@ -2616,3 +2710,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: trunk/source/Lib/TLibEncoder/TEncCavlc.h
===================================================================
--- trunk/source/Lib/TLibEncoder/TEncCavlc.h	(revision 649)
+++ trunk/source/Lib/TLibEncoder/TEncCavlc.h	(revision 713)
@@ -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: trunk/source/Lib/TLibEncoder/TEncCfg.h
===================================================================
--- trunk/source/Lib/TLibEncoder/TEncCfg.h	(revision 649)
+++ trunk/source/Lib/TLibEncoder/TEncCfg.h	(revision 713)
@@ -235,4 +235,6 @@
   Int       m_cameraIsoSpeedIdc;
   Int       m_cameraIsoSpeedValue;
+  Int       m_exposureIndexIdc;
+  Int       m_exposureIndexValue;
   Int       m_exposureCompensationValueSignFlag;
   Int       m_exposureCompensationValueNumerator;
@@ -246,4 +248,7 @@
   Int*      m_codedPivotValue;
   Int*      m_targetPivotValue;
+#if Q0074_SEI_COLOR_MAPPING
+  Char*     m_seiColorMappingFile;
+#endif
   Int       m_framePackingSEIEnabled;
   Int       m_framePackingSEIType;
@@ -362,4 +367,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
@@ -639,4 +650,8 @@
   Void  setTMISEICameraIsoSpeedValue(Int b)                  {  m_cameraIsoSpeedValue = b;  }
   Int   getTMISEICameraIsoSpeedValue()                       {  return m_cameraIsoSpeedValue;  }
+  Void  setTMISEIExposureIndexIdc(Int b)                     {  m_exposureIndexIdc = b;  }
+  Int   getTMISEIExposurIndexIdc()                           {  return m_exposureIndexIdc;  }
+  Void  setTMISEIExposureIndexValue(Int b)                   {  m_exposureIndexValue = b;  }
+  Int   getTMISEIExposurIndexValue()                         {  return m_exposureIndexValue;  }
   Void  setTMISEIExposureCompensationValueSignFlag(Int b)    {  m_exposureCompensationValueSignFlag = b;  }
   Int   getTMISEIExposureCompensationValueSignFlag()         {  return m_exposureCompensationValueSignFlag;  }
@@ -655,4 +670,8 @@
   Void  setTMISEIExtendedWhiteLevelLumaCodeValue(Int b)      {  m_extendedWhiteLevelLumaCodeValue =b;  }
   Int   getTMISEIExtendedWhiteLevelLumaCodeValue()           {  return m_extendedWhiteLevelLumaCodeValue;  }
+#if Q0074_SEI_COLOR_MAPPING
+  Void  setColorMappingInfoSEIFile( Char* nameFile )         {  m_seiColorMappingFile = nameFile; }
+  Char* getColorMappingInfoSEIFile()                         {  return m_seiColorMappingFile; }
+#endif
   Void  setFramePackingArrangementSEIEnabled(Int b)      { m_framePackingSEIEnabled = b; }
   Int   getFramePackingArrangementSEIEnabled()           { return m_framePackingSEIEnabled; }
@@ -898,4 +917,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: trunk/source/Lib/TLibEncoder/TEncEntropy.cpp
===================================================================
--- trunk/source/Lib/TLibEncoder/TEncEntropy.cpp	(revision 649)
+++ trunk/source/Lib/TLibEncoder/TEncEntropy.cpp	(revision 713)
@@ -79,4 +79,11 @@
 }
 
+#if Q0048_CGS_3D_ASYMLUT
+Void TEncEntropy::encodePPS( TComPPS* pcPPS, TEnc3DAsymLUT * pc3DAsymLUT  )
+{
+  m_pcEntropyCoderIf->codePPS( pcPPS, pc3DAsymLUT );
+  return;
+}
+#else
 Void TEncEntropy::encodePPS( TComPPS* pcPPS )
 {
@@ -84,4 +91,5 @@
   return;
 }
+#endif
 
 Void TEncEntropy::encodeSPS( TComSPS* pcSPS )
Index: trunk/source/Lib/TLibEncoder/TEncEntropy.h
===================================================================
--- trunk/source/Lib/TLibEncoder/TEncEntropy.h	(revision 649)
+++ trunk/source/Lib/TLibEncoder/TEncEntropy.h	(revision 713)
@@ -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: trunk/source/Lib/TLibEncoder/TEncGOP.cpp
===================================================================
--- trunk/source/Lib/TLibEncoder/TEncGOP.cpp	(revision 649)
+++ trunk/source/Lib/TLibEncoder/TEncGOP.cpp	(revision 713)
@@ -75,4 +75,7 @@
   m_iNumPicCoded        = 0; //Niko
   m_bFirst              = true;
+#if ALLOW_RECOVERY_POINT_AS_RAP
+  m_iLastRecoveryPicPOC = 0;
+#endif
   
   m_pcCfg               = NULL;
@@ -103,4 +106,8 @@
   m_pcPredSearch        = NULL;
 #endif
+#if Q0048_CGS_3D_ASYMLUT
+  m_temp = NULL;
+  m_pColorMappedPic = NULL;
+#endif
   return;
 }
@@ -108,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
 }
 
@@ -157,4 +177,16 @@
   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
 }
 
@@ -163,12 +195,11 @@
   SEIActiveParameterSets *seiActiveParameterSets = new SEIActiveParameterSets(); 
   seiActiveParameterSets->activeVPSId = m_pcCfg->getVPS()->getVPSId(); 
-  seiActiveParameterSets->m_fullRandomAccessFlag = false;
-  seiActiveParameterSets->m_noParamSetUpdateFlag = false;
+  seiActiveParameterSets->m_selfContainedCvsFlag = false;
+  seiActiveParameterSets->m_noParameterSetUpdateFlag = false;
   seiActiveParameterSets->numSpsIdsMinus1 = 0;
-  seiActiveParameterSets->activeSeqParamSetId.resize(seiActiveParameterSets->numSpsIdsMinus1 + 1); 
-  seiActiveParameterSets->activeSeqParamSetId[0] = sps->getSPSId();
+  seiActiveParameterSets->activeSeqParameterSetId.resize(seiActiveParameterSets->numSpsIdsMinus1 + 1); 
+  seiActiveParameterSets->activeSeqParameterSetId[0] = sps->getSPSId();
   return seiActiveParameterSets;
 }
-
 
 SEIFramePacking* TEncGOP::xCreateSEIFramePacking()
@@ -271,4 +302,7 @@
        seiToneMappingInfo->m_cameraIsoSpeedValue = m_pcCfg->getTMISEICameraIsoSpeedValue();
        assert( seiToneMappingInfo->m_cameraIsoSpeedValue !=0 );
+       seiToneMappingInfo->m_exposureIndexIdc = m_pcCfg->getTMISEIExposurIndexIdc();
+       seiToneMappingInfo->m_exposureIndexValue = m_pcCfg->getTMISEIExposurIndexValue();
+       assert( seiToneMappingInfo->m_exposureIndexValue !=0 );
        seiToneMappingInfo->m_exposureCompensationValueSignFlag = m_pcCfg->getTMISEIExposureCompensationValueSignFlag();
        seiToneMappingInfo->m_exposureCompensationValueNumerator = m_pcCfg->getTMISEIExposureCompensationValueNumerator();
@@ -293,4 +327,88 @@
 }
 
+#if Q0074_SEI_COLOR_MAPPING
+SEIColorMappingInfo*  TEncGOP::xCreateSEIColorMappingInfo( Char* file )
+{
+  SEIColorMappingInfo *seiColorMappingInfo = new SEIColorMappingInfo();
+
+  FILE* fic = fopen( file, "r" );
+
+  Int iVal, retval;
+
+  retval = fscanf( fic, "%d", &seiColorMappingInfo->m_colorMapId );
+  retval = fscanf( fic, "%d", &iVal );
+  seiColorMappingInfo->m_colorMapCancelFlag = iVal;
+  if( !seiColorMappingInfo->m_colorMapCancelFlag )
+  {
+    retval = fscanf( fic, "%d", &iVal );
+    seiColorMappingInfo->m_colorMapPersistenceFlag = iVal;
+    retval = fscanf( fic, "%d", &iVal );
+    seiColorMappingInfo->m_colorMap_video_signal_type_present_flag = iVal;
+    if( seiColorMappingInfo->m_colorMap_video_signal_type_present_flag )
+    {
+      retval = fscanf( fic, "%d", &iVal );
+      seiColorMappingInfo->m_colorMap_video_full_range_flag = iVal;
+      retval = fscanf( fic, "%d", &seiColorMappingInfo->m_colorMap_primaries );
+      retval = fscanf( fic, "%d", &seiColorMappingInfo->m_colorMap_transfer_characteristics );
+      retval = fscanf( fic, "%d", &seiColorMappingInfo->m_colorMap_matrix_coeffs );
+    }
+  }
+
+  retval = fscanf( fic, "%d", &seiColorMappingInfo->m_colour_map_coded_data_bit_depth );
+  retval = fscanf( fic, "%d", &seiColorMappingInfo->m_colour_map_target_bit_depth );
+  retval = fscanf( fic, "%d", &iVal );
+  seiColorMappingInfo->m_colorMapModelId = iVal;
+
+  assert( seiColorMappingInfo->m_colorMapModelId == 0 );
+  
+  for( Int i=0 ; i<3 ; i++ )
+  {
+    retval = fscanf( fic, "%d", &seiColorMappingInfo->m_num_input_pivots[i] );
+    seiColorMappingInfo->m_coded_input_pivot_value[i]   = new Int[ seiColorMappingInfo->m_num_input_pivots[i] ];
+    seiColorMappingInfo->m_target_input_pivot_value[i]  = new Int[ seiColorMappingInfo->m_num_input_pivots[i] ];
+    for( Int j=0 ; j<seiColorMappingInfo->m_num_input_pivots[i] ; j++ )
+    {
+      retval = fscanf( fic, "%d", &seiColorMappingInfo->m_coded_input_pivot_value[i][j] );
+      retval = fscanf( fic, "%d", &seiColorMappingInfo->m_target_input_pivot_value[i][j] );
+    }
+  }
+
+  retval = fscanf( fic, "%d", &iVal );
+  seiColorMappingInfo->m_matrix_flag = iVal;
+  if( seiColorMappingInfo->m_matrix_flag )
+  {
+    retval = fscanf( fic, "%d", &seiColorMappingInfo->m_log2_matrix_denom );
+    for( Int i=0 ; i<3 ; i++ )
+    {
+      for( Int j=0 ; j<3 ; j++ )
+      {
+        retval = fscanf( fic, "%d", &seiColorMappingInfo->m_matrix_coef[i][j] );
+      }
+    }
+  }
+
+  for( Int i=0 ; i<3 ; i++ )
+  {
+    retval = fscanf( fic, "%d", &seiColorMappingInfo->m_num_output_pivots[i] );
+    seiColorMappingInfo->m_coded_output_pivot_value[i]   = new Int[ seiColorMappingInfo->m_num_output_pivots[i] ];
+    seiColorMappingInfo->m_target_output_pivot_value[i]  = new Int[ seiColorMappingInfo->m_num_output_pivots[i] ];
+    for( Int j=0 ; j<seiColorMappingInfo->m_num_output_pivots[i] ; j++ )
+    {
+      retval = fscanf( fic, "%d", &seiColorMappingInfo->m_coded_output_pivot_value[i][j] );
+      retval = fscanf( fic, "%d", &seiColorMappingInfo->m_target_output_pivot_value[i][j] );
+    }
+  }
+
+  fclose( fic );
+
+  if( retval != 1 )
+  {
+    printf("Error: can't read color mapping information\n");
+  }
+
+  return seiColorMappingInfo;
+}
+#endif
+
 Void TEncGOP::xCreateLeadingSEIMessages (/*SEIMessages seiMessages,*/ AccessUnit &accessUnit, TComSPS *sps)
 {
@@ -359,4 +477,25 @@
     delete sei;
   }
+#if Q0074_SEI_COLOR_MAPPING
+  if(m_pcCfg->getColorMappingInfoSEIFile())
+  {
+    SEIColorMappingInfo *sei = xCreateSEIColorMappingInfo( m_pcCfg->getColorMappingInfoSEIFile() );
+      
+#if SVC_EXTENSION
+    nalu = NALUnit(NAL_UNIT_PREFIX_SEI, 0, m_layerId);  // temporalId = 0 ?
+#else
+    nalu = NALUnit(NAL_UNIT_PREFIX_SEI);
+#endif
+    m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
+#if O0164_MULTI_LAYER_HRD
+    m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, m_pcEncTop->getVPS(), sps); 
+#else
+    m_seiWriter.writeSEImessage(nalu.m_Bitstream, *sei, sps); 
+#endif
+    writeRBSPTrailingBits(nalu.m_Bitstream);
+    accessUnit.push_back(new NALUnitEBSP(nalu));
+    delete sei;
+  }
+#endif
 
 #if SVC_EXTENSION
@@ -435,4 +574,54 @@
   UInt *accumNalsDU = NULL;
   SEIDecodingUnitInfo decodingUnitInfoSEI;
+#if EFFICIENT_FIELD_IRAP
+  Int IRAPGOPid = -1;
+  Bool IRAPtoReorder = false;
+  Bool swapIRAPForward = false;
+  if(isField)
+  {
+    Int pocCurr;
+#if SVC_EXTENSION
+    for ( Int iGOPid=iPicIdInGOP; iGOPid < iPicIdInGOP+1; iGOPid++ )
+#else
+    for ( Int iGOPid=0; iGOPid < m_iGopSize; iGOPid++ )
+#endif    
+    {
+      // determine actual POC
+      if(iPOCLast == 0) //case first frame or first top field
+      {
+        pocCurr=0;
+      }
+      else if(iPOCLast == 1 && isField) //case first bottom field, just like the first frame, the poc computation is not right anymore, we set the right value
+      {
+        pocCurr = 1;
+      }
+      else
+      {
+        pocCurr = iPOCLast - iNumPicRcvd + m_pcCfg->getGOPEntry(iGOPid).m_POC - isField;
+      }
+
+      // check if POC corresponds to IRAP
+      NalUnitType tmpUnitType = getNalUnitType(pocCurr, m_iLastIDR, isField);
+      if(tmpUnitType >= NAL_UNIT_CODED_SLICE_BLA_W_LP && tmpUnitType <= NAL_UNIT_CODED_SLICE_CRA) // if picture is an IRAP
+      {
+        if(pocCurr%2 == 0 && iGOPid < m_iGopSize-1 && m_pcCfg->getGOPEntry(iGOPid).m_POC == m_pcCfg->getGOPEntry(iGOPid+1).m_POC-1)
+        { // if top field and following picture in enc order is associated bottom field
+          IRAPGOPid = iGOPid;
+          IRAPtoReorder = true;
+          swapIRAPForward = true; 
+          break;
+        }
+        if(pocCurr%2 != 0 && iGOPid > 0 && m_pcCfg->getGOPEntry(iGOPid).m_POC == m_pcCfg->getGOPEntry(iGOPid-1).m_POC+1)
+        {
+          // if picture is an IRAP remember to process it first
+          IRAPGOPid = iGOPid;
+          IRAPtoReorder = true;
+          swapIRAPForward = false; 
+          break;
+        }
+      }
+    }
+  }
+#endif
 #if SVC_EXTENSION
   for ( Int iGOPid=iPicIdInGOP; iGOPid < iPicIdInGOP+1; iGOPid++ )
@@ -441,4 +630,31 @@
 #endif
   {
+#if EFFICIENT_FIELD_IRAP
+    if(IRAPtoReorder)
+    {
+      if(swapIRAPForward)
+      {
+        if(iGOPid == IRAPGOPid)
+        {
+          iGOPid = IRAPGOPid +1;
+        }
+        else if(iGOPid == IRAPGOPid +1)
+        {
+          iGOPid = IRAPGOPid;
+        }
+      }
+      else
+      {
+        if(iGOPid == IRAPGOPid -1)
+        {
+          iGOPid = IRAPGOPid;
+        }
+        else if(iGOPid == IRAPGOPid)
+        {
+          iGOPid = IRAPGOPid -1;
+        }
+      }
+    }
+#endif
     UInt uiColDir = 1;
     //-- For time output for each slice
@@ -510,4 +726,33 @@
     if(pocCurr>=m_pcCfg->getFramesToBeEncoded())
     {
+#if EFFICIENT_FIELD_IRAP
+      if(IRAPtoReorder)
+      {
+        if(swapIRAPForward)
+        {
+          if(iGOPid == IRAPGOPid)
+          {
+            iGOPid = IRAPGOPid +1;
+            IRAPtoReorder = false;
+          }
+          else if(iGOPid == IRAPGOPid +1)
+          {
+            iGOPid --;
+          }
+        }
+        else
+        {
+          if(iGOPid == IRAPGOPid)
+          {
+            iGOPid = IRAPGOPid -1;
+          }
+          else if(iGOPid == IRAPGOPid -1)
+          {
+            iGOPid = IRAPGOPid;
+            IRAPtoReorder = false;
+          }
+        }
+      }
+#endif
       continue;
     }
@@ -803,5 +1048,10 @@
         Int widthBL   = pcSlice->getBaseColPic(refLayerIdc)->getPicYuvRec()->getWidth();
         Int heightBL  = pcSlice->getBaseColPic(refLayerIdc)->getPicYuvRec()->getHeight();
-
+#if Q0200_CONFORMANCE_BL_SIZE
+        Int chromaFormatIdc = pcSlice->getBaseColPic(refLayerIdc)->getSlice(0)->getChromaFormatIdc();
+        const Window &confBL = pcSlice->getBaseColPic(refLayerIdc)->getConformanceWindow();
+        widthBL  -= ( confBL.getWindowLeftOffset() + confBL.getWindowRightOffset() ) * TComSPS::getWinUnitX( chromaFormatIdc );
+        heightBL -= ( confBL.getWindowTopOffset() + confBL.getWindowBottomOffset() ) * TComSPS::getWinUnitY( chromaFormatIdc );
+#endif
         Int widthEL   = pcPic->getPicYuvRec()->getWidth()  - scalEL.getWindowLeftOffset() - scalEL.getWindowRightOffset();
         Int heightEL  = pcPic->getPicYuvRec()->getHeight() - scalEL.getWindowTopOffset()  - scalEL.getWindowBottomOffset();
@@ -813,12 +1063,32 @@
         g_posScalingFactor[refLayerIdc][1] = ((heightBL << 16) + (heightEL >> 1)) / heightEL;
 
+#if Q0048_CGS_3D_ASYMLUT 
+        TComPicYuv* pBaseColRec = pcSlice->getBaseColPic(refLayerIdc)->getPicYuvRec();
+        if( pcSlice->getPPS()->getCGSFlag() )
+        {
+          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))
         {
-/*#if O0098_SCALED_REF_LAYER_ID
-          Window scalEL = pcSlice->getSPS()->getScaledRefLayerWindowForLayer(pcSlice->getVPS()->getRefLayerId(m_layerId, refLayerIdc));
-#else
-          Window scalEL = pcSlice->getSPS()->getScaledRefLayerWindow(refLayerIdc);
-#endif*/
 #if P0312_VERT_PHASE_ADJ
           //when PhasePositionEnableFlag is equal to 1, set vertPhasePositionFlag to 0 if BL is top field and 1 if bottom
@@ -830,19 +1100,39 @@
 #if O0215_PHASE_ALIGNMENT
 #if O0194_JOINT_US_BITSHIFT
-          m_pcPredSearch->upsampleBasePic( pcSlice, refLayerIdc, pcPic->getFullPelBaseRec(refLayerIdc), pcSlice->getBaseColPic(refLayerIdc)->getPicYuvRec(), pcPic->getPicYuvRec(), scalEL, pcSlice->getVPS()->getPhaseAlignFlag() );
+#if Q0048_CGS_3D_ASYMLUT 
+          m_pcPredSearch->upsampleBasePic( pcSlice, refLayerIdc, pcPic->getFullPelBaseRec(refLayerIdc), pBaseColRec, pcPic->getPicYuvRec(), pcSlice->getVPS()->getPhaseAlignFlag() );
+#else
+          m_pcPredSearch->upsampleBasePic( pcSlice, refLayerIdc, pcPic->getFullPelBaseRec(refLayerIdc), pcSlice->getBaseColPic(refLayerIdc)->getPicYuvRec(), pcPic->getPicYuvRec(), 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) );
@@ -856,5 +1146,5 @@
       }
 
-#if !O0225_TID_BASED_IL_RPS_DERIV
+#if !O0225_TID_BASED_IL_RPS_DERIV || Q0060_MAX_TID_REF_EQUAL_TO_ZERO
       pcSlice->setActiveNumILRRefIdx( activeNumILRRefIdxTmp );
 #endif 
@@ -932,12 +1222,5 @@
     }
 
-    // Do decoding refresh marking if any 
-#if NO_CLRAS_OUTPUT_FLAG
-    pcSlice->decodingRefreshMarking(m_pocCRA, m_bRefreshPending, rcListPic, m_pcEncTop->getNoClrasOutputFlag());
-#else
-    pcSlice->decodingRefreshMarking(m_pocCRA, m_bRefreshPending, rcListPic);
-#endif
-    m_pcEncTop->selectReferencePictureSet(pcSlice, pocCurr, iGOPid);
-    pcSlice->getRPS()->setNumberOfLongtermPictures(0);
+#if EFFICIENT_FIELD_IRAP
 #if FIX1172
     if ( pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_LP
@@ -954,9 +1237,46 @@
     pcSlice->setAssociatedIRAPPOC(m_associatedIRAPPOC);
 #endif
-
+#endif
+    // Do decoding refresh marking if any 
+#if NO_CLRAS_OUTPUT_FLAG
+    pcSlice->decodingRefreshMarking(m_pocCRA, m_bRefreshPending, rcListPic, m_pcEncTop->getNoClrasOutputFlag());
+#else
+    pcSlice->decodingRefreshMarking(m_pocCRA, m_bRefreshPending, rcListPic);
+#endif
+    m_pcEncTop->selectReferencePictureSet(pcSlice, pocCurr, iGOPid);
+    pcSlice->getRPS()->setNumberOfLongtermPictures(0);
+#if EFFICIENT_FIELD_IRAP
+#else
+#if FIX1172
+    if ( pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_LP
+      || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_RADL
+      || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_N_LP
+      || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL
+      || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP
+      || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA )  // IRAP picture
+    {
+      m_associatedIRAPType = pcSlice->getNalUnitType();
+      m_associatedIRAPPOC = pocCurr;
+    }
+    pcSlice->setAssociatedIRAPType(m_associatedIRAPType);
+    pcSlice->setAssociatedIRAPPOC(m_associatedIRAPPOC);
+#endif
+#endif
+
+#if ALLOW_RECOVERY_POINT_AS_RAP
+    if ((pcSlice->checkThatAllRefPicsAreAvailable(rcListPic, pcSlice->getRPS(), false, m_iLastRecoveryPicPOC, m_pcCfg->getDecodingRefreshType() == 3) != 0) || (pcSlice->isIRAP()) 
+#if EFFICIENT_FIELD_IRAP
+      || (isField && pcSlice->getAssociatedIRAPType() >= NAL_UNIT_CODED_SLICE_BLA_W_LP && pcSlice->getAssociatedIRAPType() <= NAL_UNIT_CODED_SLICE_CRA && pcSlice->getAssociatedIRAPPOC() == pcSlice->getPOC()+1)
+#endif
+      )
+    {
+      pcSlice->createExplicitReferencePictureSetFromReference(rcListPic, pcSlice->getRPS(), pcSlice->isIRAP(), m_iLastRecoveryPicPOC, m_pcCfg->getDecodingRefreshType() == 3);
+    }
+#else
     if ((pcSlice->checkThatAllRefPicsAreAvailable(rcListPic, pcSlice->getRPS(), false) != 0) || (pcSlice->isIRAP()))
     {
       pcSlice->createExplicitReferencePictureSetFromReference(rcListPic, pcSlice->getRPS(), pcSlice->isIRAP());
     }
+#endif
 #if ALIGNED_BUMPING
     pcSlice->checkLeadingPictureRestrictions(rcListPic);
@@ -1743,5 +2063,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));
@@ -1776,4 +2100,17 @@
       m_bSeqFirst = false;
     }
+#if Q0048_CGS_3D_ASYMLUT
+    else if( m_pcCfg->getCGSFlag() && 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
@@ -1849,7 +2186,14 @@
       pictureTimingSEI.m_auCpbRemovalDelay = std::min<Int>(std::max<Int>(1, m_totalCoded - m_lastBPSEI), static_cast<Int>(pow(2, static_cast<double>(pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getCpbRemovalDelayLengthMinus1()+1)))); // Syntax element signalled as minus, hence the .
 #if POC_RESET_FLAG
-      pictureTimingSEI.m_picDpbOutputDelay = pcSlice->getSPS()->getNumReorderPics(0) + pocCurr - m_totalCoded;
-#else
-      pictureTimingSEI.m_picDpbOutputDelay = pcSlice->getSPS()->getNumReorderPics(0) + pcSlice->getPOC() - m_totalCoded;
+      pictureTimingSEI.m_picDpbOutputDelay = pcSlice->getSPS()->getNumReorderPics(pcSlice->getSPS()->getMaxTLayers()-1) + pocCurr - m_totalCoded;
+#else
+      pictureTimingSEI.m_picDpbOutputDelay = pcSlice->getSPS()->getNumReorderPics(pcSlice->getSPS()->getMaxTLayers()-1) + pcSlice->getPOC() - m_totalCoded;
+#endif
+#if EFFICIENT_FIELD_IRAP
+      if(IRAPGOPid > 0 && IRAPGOPid < m_iGopSize)
+      {
+        // if pictures have been swapped there is likely one more picture delay on their tid. Very rough approximation
+        pictureTimingSEI.m_picDpbOutputDelay ++;
+      }
 #endif
       Int factor = pcSlice->getSPS()->getVuiParameters()->getHrdParameters()->getTickDivisorMinus2() + 2;
@@ -1975,4 +2319,10 @@
 #endif
       sei_recovery_point.m_brokenLinkFlag    = false;
+#if ALLOW_RECOVERY_POINT_AS_RAP
+      if(m_pcCfg->getDecodingRefreshType() == 3)
+      {
+        m_iLastRecoveryPicPOC = pocCurr;
+      }
+#endif
 
 #if O0164_MULTI_LAYER_HRD
@@ -2110,4 +2460,23 @@
           }
           m_pcEntropyCoder->setBitstream(&nalu.m_Bitstream);
+
+#if SETTING_NO_OUT_PIC_PRIOR
+          if (pcSlice->isIRAP())
+          {
+            if (pcSlice->getNalUnitType() >= NAL_UNIT_CODED_SLICE_BLA_W_LP && pcSlice->getNalUnitType() <= NAL_UNIT_CODED_SLICE_IDR_N_LP)
+            {
+              pcSlice->setNoRaslOutputFlag(true);
+            }
+            //the inference for NoOutputPriorPicsFlag
+            if (!m_bFirst && pcSlice->isIRAP() && pcSlice->getNoRaslOutputFlag())
+            {
+              if (pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA)
+              {
+                pcSlice->setNoOutputPriorPicsFlag(true);
+              }
+            }
+          }
+#endif
+
           tmpBitsBeforeWriting = m_pcEntropyCoder->getNumberOfWrittenBits();
           m_pcEntropyCoder->encodeSliceHeader(pcSlice);
@@ -2657,4 +3026,34 @@
 
       delete[] pcSubstreamsOut;
+
+#if EFFICIENT_FIELD_IRAP
+    if(IRAPtoReorder)
+    {
+      if(swapIRAPForward)
+      {
+        if(iGOPid == IRAPGOPid)
+        {
+          iGOPid = IRAPGOPid +1;
+          IRAPtoReorder = false;
+        }
+        else if(iGOPid == IRAPGOPid +1)
+        {
+          iGOPid --;
+        }
+      }
+      else
+      {
+        if(iGOPid == IRAPGOPid)
+        {
+          iGOPid = IRAPGOPid -1;
+        }
+        else if(iGOPid == IRAPGOPid -1)
+        {
+          iGOPid = IRAPGOPid;
+          IRAPtoReorder = false;
+        }
+      }
+    }
+#endif
   }
   delete pcBitstreamRedirect;
@@ -2918,5 +3317,7 @@
     case NAL_UNIT_CODED_SLICE_CRA:        return "CRA";
     case NAL_UNIT_CODED_SLICE_RADL_R:     return "RADL_R";
+    case NAL_UNIT_CODED_SLICE_RADL_N:     return "RADL_N";
     case NAL_UNIT_CODED_SLICE_RASL_R:     return "RASL_R";
+    case NAL_UNIT_CODED_SLICE_RASL_N:     return "RASL_N";
     case NAL_UNIT_VPS:                    return "VPS";
     case NAL_UNIT_SPS:                    return "SPS";
@@ -3080,5 +3481,5 @@
          pcSlice->getTLayer(),
          c,
-         NaluToStr( pcSlice->getNalUnitType() ).data().
+         NaluToStr( pcSlice->getNalUnitType() ).data(),
          pcSlice->getSliceQp(),
          uibits );
@@ -3134,4 +3535,11 @@
     printf("]");
   }
+#if Q0048_CGS_3D_ASYMLUT
+  pcPic->setFrameBit( (Int)uibits );
+  if( m_layerId && pcSlice->getPPS()->getCGSFlag() )
+  {
+    m_Enc3DAsymLUTPicUpdate.updatePicCGSBits( pcSlice , m_Enc3DAsymLUTPPS.getPPSBit() );
+  }
+#endif
 }
 
@@ -3316,5 +3724,17 @@
     return NAL_UNIT_CODED_SLICE_IDR_W_RADL;
   }
+#if EFFICIENT_FIELD_IRAP
+  if(isField && pocCurr == 1)
+  {
+    // to avoid the picture becoming an IRAP
+    return NAL_UNIT_CODED_SLICE_TRAIL_R;
+  }
+#endif
+
+#if ALLOW_RECOVERY_POINT_AS_RAP
+  if(m_pcCfg->getDecodingRefreshType() != 3 && (pocCurr - isField) % m_pcCfg->getIntraPeriod() == 0)
+#else
   if ((pocCurr - isField) % m_pcCfg->getIntraPeriod() == 0)
+#endif
   {
     if (m_pcCfg->getDecodingRefreshType() == 1)
@@ -3828,4 +4248,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 )
+  {
+    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    =  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 = 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: trunk/source/Lib/TLibEncoder/TEncGOP.h
===================================================================
--- trunk/source/Lib/TLibEncoder/TEncGOP.h	(revision 649)
+++ trunk/source/Lib/TLibEncoder/TEncGOP.h	(revision 713)
@@ -54,4 +54,7 @@
 #include "TEncSbac.h"
 #include "SEIwrite.h"
+#if Q0048_CGS_3D_ASYMLUT
+#include "TEnc3DAsymLUT.h"
+#endif
 
 #include "TEncAnalyze.h"
@@ -82,4 +85,7 @@
   Int                     m_iNumPicCoded;
   Bool                    m_bFirst;
+#if ALLOW_RECOVERY_POINT_AS_RAP
+  Int                     m_iLastRecoveryPicPOC;
+#endif
   
   //  Access channel
@@ -132,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
   
@@ -187,4 +209,7 @@
 
   SEIToneMappingInfo*     xCreateSEIToneMappingInfo();
+#if Q0074_SEI_COLOR_MAPPING
+  SEIColorMappingInfo*    xCreateSEIColorMappingInfo( Char* file );
+#endif
 
   Void xCreateLeadingSEIMessages (/*SEIMessages seiMessages,*/ AccessUnit &accessUnit, TComSPS *sps);
@@ -214,4 +239,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: trunk/source/Lib/TLibEncoder/TEncSampleAdaptiveOffset.cpp
===================================================================
--- trunk/source/Lib/TLibEncoder/TEncSampleAdaptiveOffset.cpp	(revision 649)
+++ trunk/source/Lib/TLibEncoder/TEncSampleAdaptiveOffset.cpp	(revision 713)
@@ -952,8 +952,16 @@
         for (y=0; y<endY; y++)
         {
+#if SAO_SGN_FUNC
+          signLeft = (Char)sgn(srcLine[startX] - srcLine[startX-1]);
+#else
           signLeft = (Char)m_sign[srcLine[startX] - srcLine[startX-1]];
+#endif
           for (x=startX; x<endX; x++)
           {
+#if SAO_SGN_FUNC
+            signRight =  (Char)sgn(srcLine[x] - srcLine[x+1]);
+#else
             signRight =  (Char)m_sign[srcLine[x] - srcLine[x+1]]; 
+#endif
             edgeType  =  signRight + signLeft;
             signLeft  = -signRight;
@@ -975,8 +983,16 @@
             for(y=0; y<skipLinesB[typeIdx]; y++)
             {
+#if SAO_SGN_FUNC
+              signLeft = (Char)sgn(srcLine[startX] - srcLine[startX-1]);
+#else
               signLeft = (Char)m_sign[srcLine[startX] - srcLine[startX-1]];
+#endif
               for (x=startX; x<endX; x++)
               {
+#if SAO_SGN_FUNC
+                signRight =  (Char)sgn(srcLine[x] - srcLine[x+1]);
+#else
                 signRight =  (Char)m_sign[srcLine[x] - srcLine[x+1]]; 
+#endif
                 edgeType  =  signRight + signLeft;
                 signLeft  = -signRight;
@@ -1026,5 +1042,9 @@
 #endif
         {
+#if SAO_SGN_FUNC
+          signUpLine[x] = (Char)sgn(srcLine[x] - srcLineAbove[x]);
+#else
           signUpLine[x] = (Char)m_sign[srcLine[x] - srcLineAbove[x]];
+#endif
         }
 
@@ -1040,5 +1060,9 @@
 #endif
           {
+#if SAO_SGN_FUNC
+            signDown  = (Char)sgn(srcLine[x] - srcLineBelow[x]); 
+#else
             signDown  = (Char)m_sign[srcLine[x] - srcLineBelow[x]]; 
+#endif
             edgeType  = signDown + signUpLine[x];
             signUpLine[x]= -signDown;
@@ -1065,5 +1089,9 @@
               for (x=startX; x<endX; x++)
               {
+#if SAO_SGN_FUNC
+                edgeType = sgn(srcLine[x] - srcLineBelow[x]) + sgn(srcLine[x] - srcLineAbove[x]);
+#else
                 edgeType = m_sign[srcLine[x] - srcLineBelow[x]] + m_sign[srcLine[x] - srcLineAbove[x]];
+#endif
                 diff [edgeType] += (orgLine[x] - srcLine[x]);
                 count[edgeType] ++;
@@ -1108,5 +1136,9 @@
         for (x=startX; x<endX+1; x++)
         {
+#if SAO_SGN_FUNC
+          signUpLine[x] = (Char)sgn(srcLineBelow[x] - srcLine[x-1]);
+#else
           signUpLine[x] = (Char)m_sign[srcLineBelow[x] - srcLine[x-1]];
+#endif
         }
 
@@ -1122,5 +1154,9 @@
         for(x=firstLineStartX; x<firstLineEndX; x++)
         {
+#if SAO_SGN_FUNC
+          edgeType = sgn(srcLine[x] - srcLineAbove[x-1]) - signUpLine[x+1];
+#else
           edgeType = m_sign[srcLine[x] - srcLineAbove[x-1]] - signUpLine[x+1];
+#endif
           diff [edgeType] += (orgLine[x] - srcLine[x]);
           count[edgeType] ++;
@@ -1137,5 +1173,9 @@
           for (x=startX; x<endX; x++)
           {
+#if SAO_SGN_FUNC
+            signDown = (Char)sgn(srcLine[x] - srcLineBelow[x+1]);
+#else
             signDown = (Char)m_sign[srcLine[x] - srcLineBelow[x+1]] ;
+#endif
             edgeType = signDown + signUpLine[x];
             diff [edgeType] += (orgLine[x] - srcLine[x]);
@@ -1144,5 +1184,9 @@
             signDownLine[x+1] = -signDown; 
           }
+#if SAO_SGN_FUNC
+          signDownLine[startX] = (Char)sgn(srcLineBelow[startX] - srcLine[startX-1]);
+#else
           signDownLine[startX] = (Char)m_sign[srcLineBelow[startX] - srcLine[startX-1]];
+#endif
 
           signTmpLine  = signUpLine;
@@ -1168,5 +1212,9 @@
               for (x=startX; x< endX; x++)
               {
+#if SAO_SGN_FUNC
+                edgeType = sgn(srcLine[x] - srcLineBelow[x+1]) + sgn(srcLine[x] - srcLineAbove[x-1]);
+#else
                 edgeType = m_sign[srcLine[x] - srcLineBelow[x+1]] + m_sign[srcLine[x] - srcLineAbove[x-1]];
+#endif
                 diff [edgeType] += (orgLine[x] - srcLine[x]);
                 count[edgeType] ++;
@@ -1206,5 +1254,9 @@
         for (x=startX-1; x<endX; x++)
         {
+#if SAO_SGN_FUNC
+          signUpLine[x] = (Char)sgn(srcLineBelow[x] - srcLine[x+1]);
+#else
           signUpLine[x] = (Char)m_sign[srcLineBelow[x] - srcLine[x+1]];
+#endif
         }
 
@@ -1225,5 +1277,9 @@
         for(x=firstLineStartX; x<firstLineEndX; x++)
         {
+#if SAO_SGN_FUNC
+          edgeType = sgn(srcLine[x] - srcLineAbove[x+1]) - signUpLine[x-1];
+#else
           edgeType = m_sign[srcLine[x] - srcLineAbove[x+1]] - signUpLine[x-1];
+#endif
           diff [edgeType] += (orgLine[x] - srcLine[x]);
           count[edgeType] ++;
@@ -1240,5 +1296,9 @@
           for(x=startX; x<endX; x++)
           {
+#if SAO_SGN_FUNC
+            signDown = (Char)sgn(srcLine[x] - srcLineBelow[x-1]);
+#else
             signDown = (Char)m_sign[srcLine[x] - srcLineBelow[x-1]] ;
+#endif
             edgeType = signDown + signUpLine[x];
 
@@ -1248,5 +1308,9 @@
             signUpLine[x-1] = -signDown; 
           }
+#if SAO_SGN_FUNC
+          signUpLine[endX-1] = (Char)sgn(srcLineBelow[endX-1] - srcLine[endX]);
+#else
           signUpLine[endX-1] = (Char)m_sign[srcLineBelow[endX-1] - srcLine[endX]];
+#endif
           srcLine  += srcStride;
           orgLine  += orgStride;
@@ -1267,5 +1331,9 @@
               for (x=startX; x<endX; x++)
               {
+#if SAO_SGN_FUNC
+                edgeType = sgn(srcLine[x] - srcLineBelow[x-1]) + sgn(srcLine[x] - srcLineAbove[x+1]);
+#else
                 edgeType = m_sign[srcLine[x] - srcLineBelow[x-1]] + m_sign[srcLine[x] - srcLineAbove[x+1]];
+#endif
                 diff [edgeType] += (orgLine[x] - srcLine[x]);
                 count[edgeType] ++;
Index: trunk/source/Lib/TLibEncoder/TEncSbac.cpp
===================================================================
--- trunk/source/Lib/TLibEncoder/TEncSbac.cpp	(revision 649)
+++ trunk/source/Lib/TLibEncoder/TEncSbac.cpp	(revision 713)
@@ -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: trunk/source/Lib/TLibEncoder/TEncSbac.h
===================================================================
--- trunk/source/Lib/TLibEncoder/TEncSbac.h	(revision 649)
+++ trunk/source/Lib/TLibEncoder/TEncSbac.h	(revision 713)
@@ -92,10 +92,11 @@
   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 );
-#if POC_RESET_IDC_SIGNALLING
-  Void  codeSliceHeaderExtn     ( TComSlice* pSlice, Int shBitsWrittenTillNow );
-#endif
   Void  codeTerminatingBit      ( UInt uilsLast      );
   Void  codeSliceFinish         ();
@@ -108,4 +109,7 @@
 
 #if SVC_EXTENSION
+#if POC_RESET_IDC_SIGNALLING
+  Void  codeSliceHeaderExtn     ( TComSlice* pSlice, Int shBitsWrittenTillNow );
+#endif
   Void codeSAOOffsetParam(Int compIdx, SAOOffset& ctbParam, Bool sliceEnabled, UInt* saoMaxOffsetQVal);
   Void codeSAOBlkParam(SAOBlkParam& saoBlkParam
Index: trunk/source/Lib/TLibEncoder/TEncSearch.cpp
===================================================================
--- trunk/source/Lib/TLibEncoder/TEncSearch.cpp	(revision 649)
+++ trunk/source/Lib/TLibEncoder/TEncSearch.cpp	(revision 713)
@@ -2398,5 +2398,5 @@
 {
   UInt    uiDepth        = pcCU->getDepth(0);
-  UInt    uiNumPU        = pcCU->getNumPartInter();
+  UInt    uiNumPU        = pcCU->getNumPartitions();
   UInt    uiInitTrDepth  = pcCU->getPartitionSize(0) == SIZE_2Nx2N ? 0 : 1;
   UInt    uiWidth        = pcCU->getWidth (0) >> uiInitTrDepth;
@@ -3130,5 +3130,5 @@
   TComMv        cMvTemp[2][33];
   
-  Int           iNumPart    = pcCU->getNumPartInter();
+  Int           iNumPart    = pcCU->getNumPartitions();
   Int           iNumPredDir = pcCU->getSlice()->isInterP() ? 1 : 2;
   
@@ -4612,14 +4612,5 @@
     
     m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[pcCU->getDepth(0)][CI_CURR_BEST] );
-#if 0 // check
-    {
-      m_pcEntropyCoder->resetBits();
-      m_pcEntropyCoder->encodeCoeff( pcCU, 0, pcCU->getDepth(0), pcCU->getWidth(0), pcCU->getHeight(0) );
-      const UInt uiBitsForCoeff = m_pcEntropyCoder->getNumberOfWrittenBits();
-      m_pcRDGoOnSbacCoder->load( m_pppcRDSbacCoder[pcCU->getDepth(0)][CI_CURR_BEST] );
-      if( uiBitsForCoeff != uiBits )
-        assert( 0 );
-    }
-#endif
+    
     uiBits = 0;
     {
Index: trunk/source/Lib/TLibEncoder/TEncSlice.cpp
===================================================================
--- trunk/source/Lib/TLibEncoder/TEncSlice.cpp	(revision 649)
+++ trunk/source/Lib/TLibEncoder/TEncSlice.cpp	(revision 713)
@@ -225,5 +225,17 @@
   Int depth;
   {
+#if FIX_FIELD_DEPTH    
+    Int poc = rpcSlice->getPOC();
+    if(isField)
+    {
+      poc = (poc/2)%(m_pcCfg->getGOPSize()/2);
+    }
+    else
+    {
+      poc = poc%m_pcCfg->getGOPSize();   
+    }
+#else
     Int poc = rpcSlice->getPOC()%m_pcCfg->getGOPSize();
+#endif
     if ( poc == 0 )
     {
@@ -248,4 +260,17 @@
       }
     }
+#if FIX_FIELD_DEPTH  
+#if HARMONIZE_GOP_FIRST_FIELD_COUPLE
+    if(poc != 0)
+    {
+#endif
+    if(isField && rpcSlice->getPOC()%2 == 1)
+    {
+      depth ++;
+    }
+#if HARMONIZE_GOP_FIRST_FIELD_COUPLE
+  }
+#endif
+#endif
   }
 
@@ -254,5 +279,23 @@
 
   eSliceType=B_SLICE;
+#if EFFICIENT_FIELD_IRAP
+  if(!(isField && pocLast == 1))
+  {
+#endif // EFFICIENT_FIELD_IRAP
+#if ALLOW_RECOVERY_POINT_AS_RAP
+  if(m_pcCfg->getDecodingRefreshType() == 3)
+  {
+    eSliceType = (pocLast == 0 || pocCurr % m_pcCfg->getIntraPeriod() == 0             || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
+  }
+  else
+  {
   eSliceType = (pocLast == 0 || (pocCurr - isField) % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
+  }
+#else
+  eSliceType = (pocLast == 0 || (pocCurr - isField) % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
+#endif
+#if EFFICIENT_FIELD_IRAP
+  }
+#endif
 
   rpcSlice->setSliceType    ( eSliceType );
@@ -423,5 +466,25 @@
 #if HB_LAMBDA_FOR_LDC
   // restore original slice type
+  
+#if EFFICIENT_FIELD_IRAP
+  if(!(isField && pocLast == 1))
+  {
+#endif // EFFICIENT_FIELD_IRAP
+#if ALLOW_RECOVERY_POINT_AS_RAP
+  if(m_pcCfg->getDecodingRefreshType() == 3)
+  {
+    eSliceType = (pocLast == 0 || (pocCurr)           % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
+
+  }
+  else
+  {
   eSliceType = (pocLast == 0 || (pocCurr - isField) % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
+  }
+#else
+  eSliceType = (pocLast == 0 || (pocCurr - isField) % m_pcCfg->getIntraPeriod() == 0 || m_pcGOPEncoder->getGOPSize() == 0) ? I_SLICE : eSliceType;
+#endif
+#if EFFICIENT_FIELD_IRAP
+  }
+#endif // EFFICIENT_FIELD_IRAP
 
 #if SVC_EXTENSION
@@ -544,5 +607,7 @@
   // store lambda
   slice->setSliceQp( sliceQP );
+#if ADAPTIVE_QP_SELECTION
   slice->setSliceQpBase ( sliceQP );
+#endif
   m_pcRdCost ->setLambda( lambda );
   // for RDO
@@ -1041,5 +1106,7 @@
 
       m_pcRateCtrl->setRCQP( estQP );
+#if ADAPTIVE_QP_SELECTION
       pcCU->getSlice()->setSliceQpBase( estQP );
+#endif
     }
 
Index: trunk/source/Lib/TLibEncoder/TEncTop.cpp
===================================================================
--- trunk/source/Lib/TLibEncoder/TEncTop.cpp	(revision 649)
+++ trunk/source/Lib/TLibEncoder/TEncTop.cpp	(revision 713)
@@ -795,5 +795,12 @@
           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
+#if LAYER_CTB
+            || pcEncTopBase->getSPS()->getMaxCUWidth() != m_cSPS.getMaxCUWidth() || pcEncTopBase->getSPS()->getMaxCUHeight() != m_cSPS.getMaxCUHeight() || pcEncTopBase->getSPS()->getMaxCUDepth() != m_cSPS.getMaxCUDepth()
+#endif
+            )
 #else
           if(m_iSourceWidth != pcEncTopBase->getSourceWidth() || m_iSourceHeight != pcEncTopBase->getSourceHeight() || !zeroOffsets )
@@ -857,5 +864,12 @@
           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
+#if LAYER_CTB
+            || pcEncTopBase->getSPS()->getMaxCUWidth() != m_cSPS.getMaxCUWidth() || pcEncTopBase->getSPS()->getMaxCUHeight() != m_cSPS.getMaxCUHeight() || pcEncTopBase->getSPS()->getMaxCUDepth() != m_cSPS.getMaxCUDepth()
+#endif
+)
 #else
           if(m_iSourceWidth != pcEncTopBase->getSourceWidth() || m_iSourceHeight != pcEncTopBase->getSourceHeight() || !zeroOffsets )
@@ -1188,4 +1202,7 @@
   }
 #endif
+#if Q0048_CGS_3D_ASYMLUT
+  m_cPPS.setCGSFlag( m_nCGSFlag );
+#endif
 }
 
Index: trunk/source/Lib/TLibEncoder/TEncTop.h
===================================================================
--- trunk/source/Lib/TLibEncoder/TEncTop.h	(revision 649)
+++ trunk/source/Lib/TLibEncoder/TEncTop.h	(revision 713)
@@ -273,5 +273,5 @@
 
   /// encode several number of pictures until end-of-sequence
-  Void encode( bool bEos, TComPicYuv* pcPicYuvOrg, TComList<TComPicYuv*>& rcListPicYuvRecOut,
+  Void encode( Bool bEos, TComPicYuv* pcPicYuvOrg, TComList<TComPicYuv*>& rcListPicYuvRecOut,
               std::list<AccessUnit>& accessUnitsOut, Int& iNumEncoded, Bool isTff);
 
