Index: trunk/source/Lib/TLibEncoder/TEncSampleAdaptiveOffset.cpp
===================================================================
--- trunk/source/Lib/TLibEncoder/TEncSampleAdaptiveOffset.cpp	(revision 1179)
+++ trunk/source/Lib/TLibEncoder/TEncSampleAdaptiveOffset.cpp	(revision 1313)
@@ -2,5 +2,5 @@
  * License, included below. This software may be subject to other third party
  * and contributor rights, including patent rights, and no such rights are
- * granted under this license.  
+ * granted under this license.
  *
  * Copyright (c) 2010-2015, ITU/ISO/IEC
@@ -32,5 +32,5 @@
  */
 
-/** 
+/**
  \file     TEncSampleAdaptiveOffset.cpp
  \brief       estimation part of sample adaptive offset class
@@ -46,7 +46,5 @@
 
 
-/** rounding with IBDI
- * \param  x
- */
+//! rounding with IBDI
 inline Double xRoundIbdi2(Int bitDepth, Double x)
 {
@@ -62,11 +60,9 @@
 TEncSampleAdaptiveOffset::TEncSampleAdaptiveOffset()
 {
-  m_pppcRDSbacCoder = NULL;           
+  m_pppcRDSbacCoder = NULL;
   m_pcRDGoOnSbacCoder = NULL;
-  m_pppcBinCoderCABAC = NULL;    
+  m_pppcBinCoderCABAC = NULL;
   m_statData = NULL;
-#if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
   m_preDBFstatData = NULL;
-#endif
 }
 
@@ -76,19 +72,23 @@
 }
 
-#if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
 Void TEncSampleAdaptiveOffset::createEncData(Bool isPreDBFSamplesUsed)
-#else
-Void TEncSampleAdaptiveOffset::createEncData()
-#endif
 {
 
   //cabac coder for RDO
   m_pppcRDSbacCoder = new TEncSbac* [NUM_SAO_CABACSTATE_LABELS];
+#if FAST_BIT_EST
   m_pppcBinCoderCABAC = new TEncBinCABACCounter* [NUM_SAO_CABACSTATE_LABELS];
+#else
+  m_pppcBinCoderCABAC = new TEncBinCABAC* [NUM_SAO_CABACSTATE_LABELS];
+#endif
 
   for(Int cs=0; cs < NUM_SAO_CABACSTATE_LABELS; cs++)
   {
     m_pppcRDSbacCoder[cs] = new TEncSbac;
+#if FAST_BIT_EST
     m_pppcBinCoderCABAC[cs] = new TEncBinCABACCounter;
+#else
+    m_pppcBinCoderCABAC[cs] = new TEncBinCABAC;
+#endif
     m_pppcRDSbacCoder   [cs]->init( m_pppcBinCoderCABAC [cs] );
   }
@@ -99,11 +99,10 @@
   for(Int i=0; i< m_numCTUsPic; i++)
   {
-    m_statData[i] = new SAOStatData*[NUM_SAO_COMPONENTS];
-    for(Int compIdx=0; compIdx < NUM_SAO_COMPONENTS; compIdx++)
+    m_statData[i] = new SAOStatData*[MAX_NUM_COMPONENT];
+    for(Int compIdx=0; compIdx < MAX_NUM_COMPONENT; compIdx++)
     {
       m_statData[i][compIdx] = new SAOStatData[NUM_SAO_NEW_TYPES];
     }
   }
-#if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
   if(isPreDBFSamplesUsed)
   {
@@ -111,6 +110,6 @@
     for(Int i=0; i< m_numCTUsPic; i++)
     {
-      m_preDBFstatData[i] = new SAOStatData*[NUM_SAO_COMPONENTS];
-      for(Int compIdx=0; compIdx < NUM_SAO_COMPONENTS; compIdx++)
+      m_preDBFstatData[i] = new SAOStatData*[MAX_NUM_COMPONENT];
+      for(Int compIdx=0; compIdx < MAX_NUM_COMPONENT; compIdx++)
       {
         m_preDBFstatData[i][compIdx] = new SAOStatData[NUM_SAO_NEW_TYPES];
@@ -119,19 +118,15 @@
 
   }
-#endif
-
-#if SAO_ENCODING_CHOICE
+
   ::memset(m_saoDisabledRate, 0, sizeof(m_saoDisabledRate));
-#endif
 
   for(Int typeIdc=0; typeIdc < NUM_SAO_NEW_TYPES; typeIdc++)
   {
-    m_skipLinesR[SAO_Y ][typeIdc]= 5;
-    m_skipLinesR[SAO_Cb][typeIdc]= m_skipLinesR[SAO_Cr][typeIdc]= 3;
-
-    m_skipLinesB[SAO_Y ][typeIdc]= 4;
-    m_skipLinesB[SAO_Cb][typeIdc]= m_skipLinesB[SAO_Cr][typeIdc]= 2;
-
-#if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
+    m_skipLinesR[COMPONENT_Y ][typeIdc]= 5;
+    m_skipLinesR[COMPONENT_Cb][typeIdc]= m_skipLinesR[COMPONENT_Cr][typeIdc]= 3;
+
+    m_skipLinesB[COMPONENT_Y ][typeIdc]= 4;
+    m_skipLinesB[COMPONENT_Cb][typeIdc]= m_skipLinesB[COMPONENT_Cr][typeIdc]= 2;
+
     if(isPreDBFSamplesUsed)
     {
@@ -140,18 +135,18 @@
       case SAO_TYPE_EO_0:
         {
-          m_skipLinesR[SAO_Y ][typeIdc]= 5;
-          m_skipLinesR[SAO_Cb][typeIdc]= m_skipLinesR[SAO_Cr][typeIdc]= 3;
-
-          m_skipLinesB[SAO_Y ][typeIdc]= 3;
-          m_skipLinesB[SAO_Cb][typeIdc]= m_skipLinesB[SAO_Cr][typeIdc]= 1;
+          m_skipLinesR[COMPONENT_Y ][typeIdc]= 5;
+          m_skipLinesR[COMPONENT_Cb][typeIdc]= m_skipLinesR[COMPONENT_Cr][typeIdc]= 3;
+
+          m_skipLinesB[COMPONENT_Y ][typeIdc]= 3;
+          m_skipLinesB[COMPONENT_Cb][typeIdc]= m_skipLinesB[COMPONENT_Cr][typeIdc]= 1;
         }
         break;
       case SAO_TYPE_EO_90:
         {
-          m_skipLinesR[SAO_Y ][typeIdc]= 4;
-          m_skipLinesR[SAO_Cb][typeIdc]= m_skipLinesR[SAO_Cr][typeIdc]= 2;
-
-          m_skipLinesB[SAO_Y ][typeIdc]= 4;
-          m_skipLinesB[SAO_Cb][typeIdc]= m_skipLinesB[SAO_Cr][typeIdc]= 2;
+          m_skipLinesR[COMPONENT_Y ][typeIdc]= 4;
+          m_skipLinesR[COMPONENT_Cb][typeIdc]= m_skipLinesR[COMPONENT_Cr][typeIdc]= 2;
+
+          m_skipLinesB[COMPONENT_Y ][typeIdc]= 4;
+          m_skipLinesB[COMPONENT_Cb][typeIdc]= m_skipLinesB[COMPONENT_Cr][typeIdc]= 2;
         }
         break;
@@ -159,18 +154,18 @@
       case SAO_TYPE_EO_45:
         {
-          m_skipLinesR[SAO_Y ][typeIdc]= 5;
-          m_skipLinesR[SAO_Cb][typeIdc]= m_skipLinesR[SAO_Cr][typeIdc]= 3;
-
-          m_skipLinesB[SAO_Y ][typeIdc]= 4;
-          m_skipLinesB[SAO_Cb][typeIdc]= m_skipLinesB[SAO_Cr][typeIdc]= 2;
+          m_skipLinesR[COMPONENT_Y ][typeIdc]= 5;
+          m_skipLinesR[COMPONENT_Cb][typeIdc]= m_skipLinesR[COMPONENT_Cr][typeIdc]= 3;
+
+          m_skipLinesB[COMPONENT_Y ][typeIdc]= 4;
+          m_skipLinesB[COMPONENT_Cb][typeIdc]= m_skipLinesB[COMPONENT_Cr][typeIdc]= 2;
         }
         break;
       case SAO_TYPE_BO:
         {
-          m_skipLinesR[SAO_Y ][typeIdc]= 4;
-          m_skipLinesR[SAO_Cb][typeIdc]= m_skipLinesR[SAO_Cr][typeIdc]= 2;
-
-          m_skipLinesB[SAO_Y ][typeIdc]= 3;
-          m_skipLinesB[SAO_Cb][typeIdc]= m_skipLinesB[SAO_Cr][typeIdc]= 1;
+          m_skipLinesR[COMPONENT_Y ][typeIdc]= 4;
+          m_skipLinesR[COMPONENT_Cb][typeIdc]= m_skipLinesR[COMPONENT_Cr][typeIdc]= 2;
+
+          m_skipLinesB[COMPONENT_Y ][typeIdc]= 3;
+          m_skipLinesB[COMPONENT_Cb][typeIdc]= m_skipLinesB[COMPONENT_Cr][typeIdc]= 1;
         }
         break;
@@ -183,5 +178,4 @@
       }
     }
-#endif    
   }
 
@@ -212,5 +206,5 @@
     for(Int i=0; i< m_numCTUsPic; i++)
     {
-      for(Int compIdx=0; compIdx< NUM_SAO_COMPONENTS; compIdx++)
+      for(Int compIdx=0; compIdx< MAX_NUM_COMPONENT; compIdx++)
       {
         delete[] m_statData[i][compIdx];
@@ -220,10 +214,9 @@
     delete[] m_statData; m_statData = NULL;
   }
-#if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
   if(m_preDBFstatData != NULL)
   {
     for(Int i=0; i< m_numCTUsPic; i++)
     {
-      for(Int compIdx=0; compIdx< NUM_SAO_COMPONENTS; compIdx++)
+      for(Int compIdx=0; compIdx< MAX_NUM_COMPONENT; compIdx++)
       {
         delete[] m_preDBFstatData[i][compIdx];
@@ -233,13 +226,10 @@
     delete[] m_preDBFstatData; m_preDBFstatData = NULL;
   }
-
-#endif
-}
-
-Void TEncSampleAdaptiveOffset::initRDOCabacCoder(TEncSbac* pcRDGoOnSbacCoder, TComSlice* pcSlice) 
+}
+
+Void TEncSampleAdaptiveOffset::initRDOCabacCoder(TEncSbac* pcRDGoOnSbacCoder, TComSlice* pcSlice)
 {
   m_pcRDGoOnSbacCoder = pcRDGoOnSbacCoder;
-  m_pcRDGoOnSbacCoder->setSlice(pcSlice);
-  m_pcRDGoOnSbacCoder->resetEntropy();
+  m_pcRDGoOnSbacCoder->resetEntropy(pcSlice);
   m_pcRDGoOnSbacCoder->resetBits();
 
@@ -249,13 +239,9 @@
 
 
-Void TEncSampleAdaptiveOffset::SAOProcess(TComPic* pPic, Bool* sliceEnabled, const Double *lambdas
-#if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
-                                         , Bool isPreDBFSamplesUsed
-#endif
-                                          )
+Void TEncSampleAdaptiveOffset::SAOProcess(TComPic* pPic, Bool* sliceEnabled, const Double *lambdas, const Bool bTestSAODisableAtPictureLevel, const Double saoEncodingRate, const Double saoEncodingRateChroma, Bool isPreDBFSamplesUsed )
 {
   TComPicYuv* orgYuv= pPic->getPicYuvOrg();
   TComPicYuv* resYuv= pPic->getPicYuvRec();
-  m_lambda[SAO_Y]= lambdas[0]; m_lambda[SAO_Cb]= lambdas[1]; m_lambda[SAO_Cr]= lambdas[2];
+  memcpy(m_lambda, lambdas, sizeof(m_lambda));
   TComPicYuv* srcYuv = m_tempPicYuv;
   resYuv->copyToPic(srcYuv);
@@ -265,21 +251,17 @@
   //collect statistics
   getStatistics(m_statData, orgYuv, srcYuv, pPic);
-#if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
   if(isPreDBFSamplesUsed)
   {
     addPreDBFStatistics(m_statData);
   }
-#endif
-  //slice on/off 
-  decidePicParams(sliceEnabled, pPic->getSlice(0)->getDepth()); 
-
-  //block on/off 
+  //slice on/off
+  decidePicParams(sliceEnabled, pPic->getSlice(0)->getDepth(), saoEncodingRate, saoEncodingRateChroma);
+
+  //block on/off
   SAOBlkParam* reconParams = new SAOBlkParam[m_numCTUsPic]; //temporary parameter buffer for storing reconstructed SAO parameters
-  decideBlkParams(pPic, sliceEnabled, m_statData, srcYuv, resYuv, reconParams, pPic->getPicSym()->getSAOBlkParam());
+  decideBlkParams(pPic, sliceEnabled, m_statData, srcYuv, resYuv, reconParams, pPic->getPicSym()->getSAOBlkParam(), bTestSAODisableAtPictureLevel, saoEncodingRate, saoEncodingRateChroma);
   delete[] reconParams;
-
-}
-
-#if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
+}
+
 Void TEncSampleAdaptiveOffset::getPreDBFStatistics(TComPic* pPic)
 {
@@ -291,5 +273,5 @@
   for(Int n=0; n< m_numCTUsPic; n++)
   {
-    for(Int compIdx=0; compIdx < NUM_SAO_COMPONENTS; compIdx++)
+    for(Int compIdx=0; compIdx < MAX_NUM_COMPONENT; compIdx++)
     {
       for(Int typeIdc=0; typeIdc < NUM_SAO_NEW_TYPES; typeIdc++)
@@ -301,22 +283,18 @@
 }
 
-#endif
-
-Void TEncSampleAdaptiveOffset::getStatistics(SAOStatData*** blkStats, TComPicYuv* orgYuv, TComPicYuv* srcYuv, TComPic* pPic
-#if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
-                          , Bool isCalculatePreDeblockSamples
-#endif
-                          )
+Void TEncSampleAdaptiveOffset::getStatistics(SAOStatData*** blkStats, TComPicYuv* orgYuv, TComPicYuv* srcYuv, TComPic* pPic, Bool isCalculatePreDeblockSamples)
 {
   Bool isLeftAvail,isRightAvail,isAboveAvail,isBelowAvail,isAboveLeftAvail,isAboveRightAvail,isBelowLeftAvail,isBelowRightAvail;
 
-  for(Int ctu= 0; ctu < m_numCTUsPic; ctu++)
-  {
-    Int yPos   = (ctu / m_numCTUInWidth)*m_maxCUHeight;
-    Int xPos   = (ctu % m_numCTUInWidth)*m_maxCUWidth;
+  const Int numberOfComponents = getNumberValidComponents(m_chromaFormatIDC);
+
+  for(Int ctuRsAddr= 0; ctuRsAddr < m_numCTUsPic; ctuRsAddr++)
+  {
+    Int yPos   = (ctuRsAddr / m_numCTUInWidth)*m_maxCUHeight;
+    Int xPos   = (ctuRsAddr % m_numCTUInWidth)*m_maxCUWidth;
     Int height = (yPos + m_maxCUHeight > m_picHeight)?(m_picHeight- yPos):m_maxCUHeight;
     Int width  = (xPos + m_maxCUWidth  > m_picWidth )?(m_picWidth - xPos):m_maxCUWidth;
 
-    pPic->getPicSym()->deriveLoopFilterBoundaryAvailibility(ctu, isLeftAvail,isRightAvail,isAboveAvail,isBelowAvail,isAboveLeftAvail,isAboveRightAvail,isBelowLeftAvail,isBelowRightAvail);
+    pPic->getPicSym()->deriveLoopFilterBoundaryAvailibility(ctuRsAddr, isLeftAvail,isRightAvail,isAboveAvail,isBelowAvail,isAboveLeftAvail,isAboveRightAvail,isBelowLeftAvail,isBelowRightAvail);
 
     //NOTE: The number of skipped lines during gathering CTU statistics depends on the slice boundary availabilities.
@@ -329,21 +307,21 @@
     isAboveRightAvail = ((yPos > 0) && (isRightAvail));
 
-    for(Int compIdx=0; compIdx< NUM_SAO_COMPONENTS; compIdx++)
-    {
-      Bool isLuma     = (compIdx == SAO_Y);
-      Int  formatShift= isLuma?0:1;
-
-      Int  srcStride = isLuma?srcYuv->getStride():srcYuv->getCStride();
-      Pel* srcBlk    = getPicBuf(srcYuv, compIdx)+ (yPos >> formatShift)*srcStride+ (xPos >> formatShift);
-
-      Int  orgStride  = isLuma?orgYuv->getStride():orgYuv->getCStride();
-      Pel* orgBlk     = getPicBuf(orgYuv, compIdx)+ (yPos >> formatShift)*orgStride+ (xPos >> formatShift);
-
-      getBlkStats(compIdx, blkStats[ctu][compIdx]  
-                , srcBlk, orgBlk, srcStride, orgStride, (width  >> formatShift), (height >> formatShift)
-                , isLeftAvail,  isRightAvail, isAboveAvail, isBelowAvail, isAboveLeftAvail, isAboveRightAvail, isBelowLeftAvail, isBelowRightAvail
-#if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
+    for(Int compIdx = 0; compIdx < numberOfComponents; compIdx++)
+    {
+      const ComponentID component = ComponentID(compIdx);
+
+      const UInt componentScaleX = getComponentScaleX(component, pPic->getChromaFormat());
+      const UInt componentScaleY = getComponentScaleY(component, pPic->getChromaFormat());
+
+      Int  srcStride  = srcYuv->getStride(component);
+      Pel* srcBlk     = srcYuv->getAddr(component) + ((yPos >> componentScaleY) * srcStride) + (xPos >> componentScaleX);
+
+      Int  orgStride  = orgYuv->getStride(component);
+      Pel* orgBlk     = orgYuv->getAddr(component) + ((yPos >> componentScaleY) * orgStride) + (xPos >> componentScaleX);
+
+      getBlkStats(component, pPic->getPicSym()->getSPS().getBitDepth(toChannelType(component)), blkStats[ctuRsAddr][component]
+                , srcBlk, orgBlk, srcStride, orgStride, (width  >> componentScaleX), (height >> componentScaleY)
+                , isLeftAvail,  isRightAvail, isAboveAvail, isBelowAvail, isAboveLeftAvail, isAboveRightAvail
                 , isCalculatePreDeblockSamples
-#endif
                 );
 
@@ -352,37 +330,46 @@
 }
 
-Void TEncSampleAdaptiveOffset::decidePicParams(Bool* sliceEnabled, Int picTempLayer)
+Void TEncSampleAdaptiveOffset::decidePicParams(Bool* sliceEnabled, Int picTempLayer, const Double saoEncodingRate, const Double saoEncodingRateChroma)
 {
   //decide sliceEnabled[compIdx]
-  for (Int compIdx=0; compIdx<NUM_SAO_COMPONENTS; compIdx++)
+  const Int numberOfComponents = getNumberValidComponents(m_chromaFormatIDC);
+  for (Int compIdx = 0; compIdx < MAX_NUM_COMPONENT; compIdx++)
+  {
+    sliceEnabled[compIdx] = false;
+  }
+
+  for (Int compIdx = 0; compIdx < numberOfComponents; compIdx++)
   {
     // reset flags & counters
     sliceEnabled[compIdx] = true;
 
-#if SAO_ENCODING_CHOICE
-#if SAO_ENCODING_CHOICE_CHROMA
+    if (saoEncodingRate>0.0)
+    {
+      if (saoEncodingRateChroma>0.0)
+      {
     // decide slice-level on/off based on previous results
-    if( (picTempLayer > 0) 
-      && (m_saoDisabledRate[compIdx][picTempLayer-1] > ((compIdx==SAO_Y) ? SAO_ENCODING_RATE : SAO_ENCODING_RATE_CHROMA)) )
+    if( (picTempLayer > 0)
+          && (m_saoDisabledRate[compIdx][picTempLayer-1] > ((compIdx==COMPONENT_Y) ? saoEncodingRate : saoEncodingRateChroma)) )
     {
       sliceEnabled[compIdx] = false;
     }
-#else
+      }
+      else
+      {
     // decide slice-level on/off based on previous results
-    if( (picTempLayer > 0) 
-      && (m_saoDisabledRate[SAO_Y][0] > SAO_ENCODING_RATE) )
+    if( (picTempLayer > 0)
+          && (m_saoDisabledRate[COMPONENT_Y][0] > saoEncodingRate) )
     {
       sliceEnabled[compIdx] = false;
     }
-#endif
-#endif
-  }
-}
-
-Int64 TEncSampleAdaptiveOffset::getDistortion(Int ctu, Int compIdx, Int typeIdc, Int typeAuxInfo, Int* invQuantOffset, SAOStatData& statData)
-{
-  Int64 dist=0;
-  Int inputBitDepth    = (compIdx == SAO_Y) ? g_bitDepthY : g_bitDepthC ;
-  Int shift = 2 * DISTORTION_PRECISION_ADJUSTMENT(inputBitDepth-8);
+      }
+    }
+  }
+}
+
+Int64 TEncSampleAdaptiveOffset::getDistortion(const Int channelBitDepth, Int typeIdc, Int typeAuxInfo, Int* invQuantOffset, SAOStatData& statData)
+{
+  Int64 dist        = 0;
+  Int shift         = 2 * DISTORTION_PRECISION_ADJUSTMENT(channelBitDepth - 8);
 
   switch(typeIdc)
@@ -396,5 +383,5 @@
         {
           dist += estSaoDist( statData.count[offsetIdx], invQuantOffset[offsetIdx], statData.diff[offsetIdx], shift);
-        }        
+        }
       }
       break;
@@ -403,5 +390,5 @@
         for (Int offsetIdx=typeAuxInfo; offsetIdx<typeAuxInfo+4; offsetIdx++)
         {
-          Int bandIdx = offsetIdx % NUM_SAO_BO_CLASSES ; 
+          Int bandIdx = offsetIdx % NUM_SAO_BO_CLASSES ;
           dist += estSaoDist( statData.count[bandIdx], invQuantOffset[bandIdx], statData.diff[bandIdx], shift);
         }
@@ -425,5 +412,5 @@
 
 
-inline Int TEncSampleAdaptiveOffset::estIterOffset(Int typeIdx, Int classIdx, Double lambda, Int offsetInput, Int64 count, Int64 diffSum, Int shift, Int bitIncrease, Int64& bestDist, Double& bestCost, Int offsetTh )
+inline Int TEncSampleAdaptiveOffset::estIterOffset(Int typeIdx, Double lambda, Int offsetInput, Int64 count, Int64 diffSum, Int shift, Int bitIncrease, Int64& bestDist, Double& bestCost, Int offsetTh )
 {
   Int iterOffset, tempOffset;
@@ -432,12 +419,12 @@
   Int offsetOutput = 0;
   iterOffset = offsetInput;
-  // Assuming sending quantized value 0 results in zero offset and sending the value zero needs 1 bit. entropy coder can be used to measure the exact rate here. 
-  tempMinCost = lambda; 
+  // Assuming sending quantized value 0 results in zero offset and sending the value zero needs 1 bit. entropy coder can be used to measure the exact rate here.
+  tempMinCost = lambda;
   while (iterOffset != 0)
   {
     // Calculate the bits required for signaling the offset
-    tempRate = (typeIdx == SAO_TYPE_BO) ? (abs((Int)iterOffset)+2) : (abs((Int)iterOffset)+1); 
-    if (abs((Int)iterOffset)==offsetTh) //inclusive 
-    {  
+    tempRate = (typeIdx == SAO_TYPE_BO) ? (abs((Int)iterOffset)+2) : (abs((Int)iterOffset)+1);
+    if (abs((Int)iterOffset)==offsetTh) //inclusive
+    {
       tempRate --;
     }
@@ -458,18 +445,17 @@
 }
 
-
-Void TEncSampleAdaptiveOffset::deriveOffsets(Int ctu, Int compIdx, Int typeIdc, SAOStatData& statData, Int* quantOffsets, Int& typeAuxInfo)
-{
-  Int bitDepth = (compIdx== SAO_Y) ? g_bitDepthY : g_bitDepthC;
-  Int shift = 2 * DISTORTION_PRECISION_ADJUSTMENT(bitDepth-8);
-  Int offsetTh = g_saoMaxOffsetQVal[compIdx];  //inclusive
+Void TEncSampleAdaptiveOffset::deriveOffsets(ComponentID compIdx, const Int channelBitDepth, Int typeIdc, SAOStatData& statData, Int* quantOffsets, Int& typeAuxInfo)
+{
+  Int bitDepth = channelBitDepth;
+  Int shift    = 2 * DISTORTION_PRECISION_ADJUSTMENT(bitDepth-8);
+  Int offsetTh = TComSampleAdaptiveOffset::getMaxOffsetQVal(channelBitDepth);  //inclusive
 
   ::memset(quantOffsets, 0, sizeof(Int)*MAX_NUM_SAO_CLASSES);
 
-  //derive initial offsets 
+  //derive initial offsets
   Int numClasses = (typeIdc == SAO_TYPE_BO)?((Int)NUM_SAO_BO_CLASSES):((Int)NUM_SAO_EO_CLASSES);
   for(Int classIdx=0; classIdx< numClasses; classIdx++)
   {
-    if( (typeIdc != SAO_TYPE_BO) && (classIdx==SAO_CLASS_EO_PLAIN)  ) 
+    if( (typeIdc != SAO_TYPE_BO) && (classIdx==SAO_CLASS_EO_PLAIN)  )
     {
       continue; //offset will be zero
@@ -481,6 +467,6 @@
     }
 
-    quantOffsets[classIdx] = (Int) xRoundIbdi(bitDepth, (Double)( statData.diff[classIdx]<<(bitDepth-8)) 
-                                                                  / 
+    quantOffsets[classIdx] = (Int) xRoundIbdi(bitDepth, (Double)( statData.diff[classIdx]<<(bitDepth-8))
+                                                                  /
                                                           (Double)( statData.count[classIdx]<< m_offsetStepLog2[compIdx])
                                                );
@@ -498,17 +484,29 @@
         Int64 classDist;
         Double classCost;
-        for(Int classIdx=0; classIdx<NUM_SAO_EO_CLASSES; classIdx++)  
-        {         
-          if(classIdx==SAO_CLASS_EO_FULL_VALLEY && quantOffsets[classIdx] < 0) quantOffsets[classIdx] =0;
-          if(classIdx==SAO_CLASS_EO_HALF_VALLEY && quantOffsets[classIdx] < 0) quantOffsets[classIdx] =0;
-          if(classIdx==SAO_CLASS_EO_HALF_PEAK   && quantOffsets[classIdx] > 0) quantOffsets[classIdx] =0;
-          if(classIdx==SAO_CLASS_EO_FULL_PEAK   && quantOffsets[classIdx] > 0) quantOffsets[classIdx] =0;
+        for(Int classIdx=0; classIdx<NUM_SAO_EO_CLASSES; classIdx++)
+        {
+          if(classIdx==SAO_CLASS_EO_FULL_VALLEY && quantOffsets[classIdx] < 0)
+          {
+            quantOffsets[classIdx] =0;
+          }
+          if(classIdx==SAO_CLASS_EO_HALF_VALLEY && quantOffsets[classIdx] < 0)
+          {
+            quantOffsets[classIdx] =0;
+          }
+          if(classIdx==SAO_CLASS_EO_HALF_PEAK   && quantOffsets[classIdx] > 0)
+          {
+            quantOffsets[classIdx] =0;
+          }
+          if(classIdx==SAO_CLASS_EO_FULL_PEAK   && quantOffsets[classIdx] > 0)
+          {
+            quantOffsets[classIdx] =0;
+          }
 
           if( quantOffsets[classIdx] != 0 ) //iterative adjustment only when derived offset is not zero
           {
-            quantOffsets[classIdx] = estIterOffset( typeIdc, classIdx, m_lambda[compIdx], quantOffsets[classIdx], statData.count[classIdx], statData.diff[classIdx], shift, m_offsetStepLog2[compIdx], classDist , classCost , offsetTh );
-          }
-        }
-      
+            quantOffsets[classIdx] = estIterOffset( typeIdc, m_lambda[compIdx], quantOffsets[classIdx], statData.count[classIdx], statData.diff[classIdx], shift, m_offsetStepLog2[compIdx], classDist , classCost , offsetTh );
+          }
+        }
+
         typeAuxInfo =0;
       }
@@ -520,9 +518,9 @@
         ::memset(distBOClasses, 0, sizeof(Int64)*NUM_SAO_BO_CLASSES);
         for(Int classIdx=0; classIdx< NUM_SAO_BO_CLASSES; classIdx++)
-        {         
+        {
           costBOClasses[classIdx]= m_lambda[compIdx];
           if( quantOffsets[classIdx] != 0 ) //iterative adjustment only when derived offset is not zero
           {
-            quantOffsets[classIdx] = estIterOffset( typeIdc, classIdx, m_lambda[compIdx], quantOffsets[classIdx], statData.count[classIdx], statData.diff[classIdx], shift, m_offsetStepLog2[compIdx], distBOClasses[classIdx], costBOClasses[classIdx], offsetTh );
+            quantOffsets[classIdx] = estIterOffset( typeIdc, m_lambda[compIdx], quantOffsets[classIdx], statData.count[classIdx], statData.diff[classIdx], shift, m_offsetStepLog2[compIdx], distBOClasses[classIdx], costBOClasses[classIdx], offsetTh );
           }
         }
@@ -530,5 +528,5 @@
         //decide the starting band index
         Double minCost = MAX_DOUBLE, cost;
-        for(Int band=0; band< NUM_SAO_BO_CLASSES- 4+ 1; band++) 
+        for(Int band=0; band< NUM_SAO_BO_CLASSES- 4+ 1; band++)
         {
           cost  = costBOClasses[band  ];
@@ -546,10 +544,10 @@
         Int clearQuantOffset[NUM_SAO_BO_CLASSES];
         ::memset(clearQuantOffset, 0, sizeof(Int)*NUM_SAO_BO_CLASSES);
-        for(Int i=0; i< 4; i++) 
+        for(Int i=0; i< 4; i++)
         {
           Int band = (typeAuxInfo+i)%NUM_SAO_BO_CLASSES;
           clearQuantOffset[band] = quantOffsets[band];
         }
-        ::memcpy(quantOffsets, clearQuantOffset, sizeof(Int)*NUM_SAO_BO_CLASSES);        
+        ::memcpy(quantOffsets, clearQuantOffset, sizeof(Int)*NUM_SAO_BO_CLASSES);
       }
       break;
@@ -566,78 +564,82 @@
 }
 
-
-Void TEncSampleAdaptiveOffset::deriveModeNewRDO(Int ctu, std::vector<SAOBlkParam*>& mergeList, Bool* sliceEnabled, SAOStatData*** blkStats, SAOBlkParam& modeParam, Double& modeNormCost, TEncSbac** cabacCoderRDO, Int inCabacLabel)
+Void TEncSampleAdaptiveOffset::deriveModeNewRDO(const BitDepths &bitDepths, Int ctuRsAddr, SAOBlkParam* mergeList[NUM_SAO_MERGE_TYPES], Bool* sliceEnabled, SAOStatData*** blkStats, SAOBlkParam& modeParam, Double& modeNormCost, TEncSbac** cabacCoderRDO, Int inCabacLabel)
 {
   Double minCost, cost;
-  Int rate;
   UInt previousWrittenBits;
-  Int64 dist[NUM_SAO_COMPONENTS], modeDist[NUM_SAO_COMPONENTS];
-  SAOOffset testOffset[NUM_SAO_COMPONENTS];
-  Int compIdx;
+  const Int numberOfComponents = getNumberValidComponents(m_chromaFormatIDC);
+
+  Int64 dist[MAX_NUM_COMPONENT], modeDist[MAX_NUM_COMPONENT];
+  SAOOffset testOffset[MAX_NUM_COMPONENT];
   Int invQuantOffset[MAX_NUM_SAO_CLASSES];
-
-  modeDist[SAO_Y]= modeDist[SAO_Cb] = modeDist[SAO_Cr] = 0;
+  for(Int comp=0; comp < MAX_NUM_COMPONENT; comp++)
+  {
+    modeDist[comp] = 0;
+  }
 
   //pre-encode merge flags
-  modeParam[SAO_Y ].modeIdc = SAO_MODE_OFF;
+  modeParam[COMPONENT_Y].modeIdc = SAO_MODE_OFF;
   m_pcRDGoOnSbacCoder->load(cabacCoderRDO[inCabacLabel]);
-  m_pcRDGoOnSbacCoder->codeSAOBlkParam(modeParam, sliceEnabled, (mergeList[SAO_MERGE_LEFT]!= NULL), (mergeList[SAO_MERGE_ABOVE]!= NULL), true);
+  m_pcRDGoOnSbacCoder->codeSAOBlkParam(modeParam, bitDepths, sliceEnabled, (mergeList[SAO_MERGE_LEFT]!= NULL), (mergeList[SAO_MERGE_ABOVE]!= NULL), true);
   m_pcRDGoOnSbacCoder->store(cabacCoderRDO[SAO_CABACSTATE_BLK_MID]);
 
-  //------ luma --------//
-  compIdx = SAO_Y;
-  //"off" case as initial cost
-  modeParam[compIdx].modeIdc = SAO_MODE_OFF;
-  m_pcRDGoOnSbacCoder->resetBits();
-  m_pcRDGoOnSbacCoder->codeSAOOffsetParam(compIdx, modeParam[compIdx], sliceEnabled[compIdx]);
-  modeDist[compIdx] = 0;
-  minCost= m_lambda[compIdx]*((Double)m_pcRDGoOnSbacCoder->getNumberOfWrittenBits());
-  m_pcRDGoOnSbacCoder->store(cabacCoderRDO[SAO_CABACSTATE_BLK_TEMP]);
-  if(sliceEnabled[compIdx])
-  {
-    for(Int typeIdc=0; typeIdc< NUM_SAO_NEW_TYPES; typeIdc++)
-    {
-      testOffset[compIdx].modeIdc = SAO_MODE_NEW;
-      testOffset[compIdx].typeIdc = typeIdc;
-
-      //derive coded offset
-      deriveOffsets(ctu, compIdx, typeIdc, blkStats[ctu][compIdx][typeIdc], testOffset[compIdx].offset, testOffset[compIdx].typeAuxInfo);
-
-      //inversed quantized offsets
-      invertQuantOffsets(compIdx, typeIdc, testOffset[compIdx].typeAuxInfo, invQuantOffset, testOffset[compIdx].offset);
-
-      //get distortion
-      dist[compIdx] = getDistortion(ctu, compIdx, testOffset[compIdx].typeIdc, testOffset[compIdx].typeAuxInfo, invQuantOffset, blkStats[ctu][compIdx][typeIdc]);
-
-      //get rate
-      m_pcRDGoOnSbacCoder->load(cabacCoderRDO[SAO_CABACSTATE_BLK_MID]);
-      m_pcRDGoOnSbacCoder->resetBits();
-      m_pcRDGoOnSbacCoder->codeSAOOffsetParam(compIdx, testOffset[compIdx], sliceEnabled[compIdx]);
-      rate = m_pcRDGoOnSbacCoder->getNumberOfWrittenBits();
-      cost = (Double)dist[compIdx] + m_lambda[compIdx]*((Double)rate);
-      if(cost < minCost)
-      {
-        minCost = cost;
-        modeDist[compIdx] = dist[compIdx];
-        modeParam[compIdx]= testOffset[compIdx];
-        m_pcRDGoOnSbacCoder->store(cabacCoderRDO[SAO_CABACSTATE_BLK_TEMP]);
-      }
-    }
-  }
-  m_pcRDGoOnSbacCoder->load(cabacCoderRDO[SAO_CABACSTATE_BLK_TEMP]);
-  m_pcRDGoOnSbacCoder->store(cabacCoderRDO[SAO_CABACSTATE_BLK_MID]);
+    //------ luma --------//
+  {
+    const ComponentID compIdx = COMPONENT_Y;
+    //"off" case as initial cost
+    modeParam[compIdx].modeIdc = SAO_MODE_OFF;
+    m_pcRDGoOnSbacCoder->resetBits();
+    m_pcRDGoOnSbacCoder->codeSAOOffsetParam(compIdx, modeParam[compIdx], sliceEnabled[compIdx], bitDepths.recon[CHANNEL_TYPE_LUMA]);
+    modeDist[compIdx] = 0;
+    minCost= m_lambda[compIdx]*((Double)m_pcRDGoOnSbacCoder->getNumberOfWrittenBits());
+    m_pcRDGoOnSbacCoder->store(cabacCoderRDO[SAO_CABACSTATE_BLK_TEMP]);
+    if(sliceEnabled[compIdx])
+    {
+      for(Int typeIdc=0; typeIdc< NUM_SAO_NEW_TYPES; typeIdc++)
+      {
+        testOffset[compIdx].modeIdc = SAO_MODE_NEW;
+        testOffset[compIdx].typeIdc = typeIdc;
+
+        //derive coded offset
+        deriveOffsets(compIdx, bitDepths.recon[CHANNEL_TYPE_LUMA], typeIdc, blkStats[ctuRsAddr][compIdx][typeIdc], testOffset[compIdx].offset, testOffset[compIdx].typeAuxInfo);
+
+        //inversed quantized offsets
+        invertQuantOffsets(compIdx, typeIdc, testOffset[compIdx].typeAuxInfo, invQuantOffset, testOffset[compIdx].offset);
+
+        //get distortion
+        dist[compIdx] = getDistortion(bitDepths.recon[CHANNEL_TYPE_LUMA], testOffset[compIdx].typeIdc, testOffset[compIdx].typeAuxInfo, invQuantOffset, blkStats[ctuRsAddr][compIdx][typeIdc]);
+
+        //get rate
+        m_pcRDGoOnSbacCoder->load(cabacCoderRDO[SAO_CABACSTATE_BLK_MID]);
+        m_pcRDGoOnSbacCoder->resetBits();
+        m_pcRDGoOnSbacCoder->codeSAOOffsetParam(compIdx, testOffset[compIdx], sliceEnabled[compIdx], bitDepths.recon[CHANNEL_TYPE_LUMA]);
+        Int rate = m_pcRDGoOnSbacCoder->getNumberOfWrittenBits();
+        cost = (Double)dist[compIdx] + m_lambda[compIdx]*((Double)rate);
+        if(cost < minCost)
+        {
+          minCost = cost;
+          modeDist[compIdx] = dist[compIdx];
+          modeParam[compIdx]= testOffset[compIdx];
+          m_pcRDGoOnSbacCoder->store(cabacCoderRDO[SAO_CABACSTATE_BLK_TEMP]);
+        }
+      }
+    }
+    m_pcRDGoOnSbacCoder->load(cabacCoderRDO[SAO_CABACSTATE_BLK_TEMP]);
+    m_pcRDGoOnSbacCoder->store(cabacCoderRDO[SAO_CABACSTATE_BLK_MID]);
+  }
 
   //------ chroma --------//
-  //"off" case as initial cost
+//"off" case as initial cost
   cost = 0;
   previousWrittenBits = 0;
   m_pcRDGoOnSbacCoder->resetBits();
-  for (Int component = SAO_Cb; component < NUM_SAO_COMPONENTS; component++)
-  {
-    modeParam[component].modeIdc = SAO_MODE_OFF; 
-    modeDist [component] = 0;
-
-    m_pcRDGoOnSbacCoder->codeSAOOffsetParam(component, modeParam[component], sliceEnabled[component]);
-
+  for(UInt componentIndex = COMPONENT_Cb; componentIndex < numberOfComponents; componentIndex++)
+  {
+    const ComponentID component = ComponentID(componentIndex);
+
+    modeParam[component].modeIdc = SAO_MODE_OFF;
+    modeDist [component]         = 0;
+    m_pcRDGoOnSbacCoder->codeSAOOffsetParam(component, modeParam[component], sliceEnabled[component], bitDepths.recon[CHANNEL_TYPE_CHROMA]);
+    
     const UInt currentWrittenBits = m_pcRDGoOnSbacCoder->getNumberOfWrittenBits();
     cost += m_lambda[component] * (currentWrittenBits - previousWrittenBits);
@@ -656,24 +658,25 @@
     cost = 0;
 
-    for(compIdx= SAO_Cb; compIdx< NUM_SAO_COMPONENTS; compIdx++)
-    {
-      if(!sliceEnabled[compIdx])
-      {
-        testOffset[compIdx].modeIdc = SAO_MODE_OFF;
-        dist[compIdx]= 0;
+    for(UInt componentIndex = COMPONENT_Cb; componentIndex < numberOfComponents; componentIndex++)
+    {
+      const ComponentID component = ComponentID(componentIndex);
+      if(!sliceEnabled[component])
+      {
+        testOffset[component].modeIdc = SAO_MODE_OFF;
+        dist[component]= 0;
         continue;
       }
-      testOffset[compIdx].modeIdc = SAO_MODE_NEW;
-      testOffset[compIdx].typeIdc = typeIdc;
+      testOffset[component].modeIdc = SAO_MODE_NEW;
+      testOffset[component].typeIdc = typeIdc;
 
       //derive offset & get distortion
-      deriveOffsets(ctu, compIdx, typeIdc, blkStats[ctu][compIdx][typeIdc], testOffset[compIdx].offset, testOffset[compIdx].typeAuxInfo);
-      invertQuantOffsets(compIdx, typeIdc, testOffset[compIdx].typeAuxInfo, invQuantOffset, testOffset[compIdx].offset);
-      dist[compIdx]= getDistortion(ctu, compIdx, typeIdc, testOffset[compIdx].typeAuxInfo, invQuantOffset, blkStats[ctu][compIdx][typeIdc]);
-      
-      m_pcRDGoOnSbacCoder->codeSAOOffsetParam(compIdx, testOffset[compIdx], sliceEnabled[compIdx]);
+      deriveOffsets(component, bitDepths.recon[CHANNEL_TYPE_CHROMA], typeIdc, blkStats[ctuRsAddr][component][typeIdc], testOffset[component].offset, testOffset[component].typeAuxInfo);
+      invertQuantOffsets(component, typeIdc, testOffset[component].typeAuxInfo, invQuantOffset, testOffset[component].offset);
+      dist[component] = getDistortion(bitDepths.recon[CHANNEL_TYPE_CHROMA], typeIdc, testOffset[component].typeAuxInfo, invQuantOffset, blkStats[ctuRsAddr][component][typeIdc]);
+
+      m_pcRDGoOnSbacCoder->codeSAOOffsetParam(component, testOffset[component], sliceEnabled[component], bitDepths.recon[CHANNEL_TYPE_CHROMA]);
 
       const UInt currentWrittenBits = m_pcRDGoOnSbacCoder->getNumberOfWrittenBits();
-      cost += dist[compIdx] + (m_lambda[compIdx] * (currentWrittenBits - previousWrittenBits));
+      cost += dist[component] + (m_lambda[component] * (currentWrittenBits - previousWrittenBits));
       previousWrittenBits = currentWrittenBits;
     }
@@ -682,35 +685,35 @@
     {
       minCost = cost;
-      for(compIdx= SAO_Cb; compIdx< NUM_SAO_COMPONENTS; compIdx++)
-      {
-        modeDist [compIdx] = dist      [compIdx];
-        modeParam[compIdx] = testOffset[compIdx];
-      }
-    }
-  }
-
+      for(UInt componentIndex = COMPONENT_Cb; componentIndex < numberOfComponents; componentIndex++)
+      {
+        modeDist[componentIndex]  = dist[componentIndex];
+        modeParam[componentIndex] = testOffset[componentIndex];
+      }
+    }
+
+  } // SAO_TYPE loop
 
   //----- re-gen rate & normalized cost----//
   modeNormCost = 0;
-  for(UInt component = SAO_Y; component < NUM_SAO_COMPONENTS; component++)
-  {
-    modeNormCost += (Double)modeDist[component] / m_lambda[component];
-  }
+  for(UInt componentIndex = COMPONENT_Y; componentIndex < numberOfComponents; componentIndex++)
+  {
+    modeNormCost += (Double)modeDist[componentIndex] / m_lambda[componentIndex];
+  }
+
   m_pcRDGoOnSbacCoder->load(cabacCoderRDO[inCabacLabel]);
   m_pcRDGoOnSbacCoder->resetBits();
-  m_pcRDGoOnSbacCoder->codeSAOBlkParam(modeParam, sliceEnabled, (mergeList[SAO_MERGE_LEFT]!= NULL), (mergeList[SAO_MERGE_ABOVE]!= NULL), false);
+  m_pcRDGoOnSbacCoder->codeSAOBlkParam(modeParam, bitDepths, sliceEnabled, (mergeList[SAO_MERGE_LEFT]!= NULL), (mergeList[SAO_MERGE_ABOVE]!= NULL), false);
   modeNormCost += (Double)m_pcRDGoOnSbacCoder->getNumberOfWrittenBits();
-
-}
-
-Void TEncSampleAdaptiveOffset::deriveModeMergeRDO(Int ctu, std::vector<SAOBlkParam*>& mergeList, Bool* sliceEnabled, SAOStatData*** blkStats, SAOBlkParam& modeParam, Double& modeNormCost, TEncSbac** cabacCoderRDO, Int inCabacLabel)
-{
-  Int mergeListSize = (Int)mergeList.size();
+}
+
+Void TEncSampleAdaptiveOffset::deriveModeMergeRDO(const BitDepths &bitDepths, Int ctuRsAddr, SAOBlkParam* mergeList[NUM_SAO_MERGE_TYPES], Bool* sliceEnabled, SAOStatData*** blkStats, SAOBlkParam& modeParam, Double& modeNormCost, TEncSbac** cabacCoderRDO, Int inCabacLabel)
+{
   modeNormCost = MAX_DOUBLE;
 
   Double cost;
   SAOBlkParam testBlkParam;
-
-  for(Int mergeType=0; mergeType< mergeListSize; mergeType++)
+  const Int numberOfComponents = getNumberValidComponents(m_chromaFormatIDC);
+
+  for(Int mergeType=0; mergeType< NUM_SAO_MERGE_TYPES; mergeType++)
   {
     if(mergeList[mergeType] == NULL)
@@ -722,5 +725,5 @@
     //normalized distortion
     Double normDist=0;
-    for(Int compIdx=0; compIdx< NUM_SAO_COMPONENTS; compIdx++)
+    for(Int compIdx = 0; compIdx < numberOfComponents; compIdx++)
     {
       testBlkParam[compIdx].modeIdc = SAO_MODE_MERGE;
@@ -732,5 +735,5 @@
       {
         //offsets have been reconstructed. Don't call inversed quantization function.
-        normDist += (((Double)getDistortion(ctu, compIdx, mergedOffsetParam.typeIdc, mergedOffsetParam.typeAuxInfo, mergedOffsetParam.offset, blkStats[ctu][compIdx][mergedOffsetParam.typeIdc]))
+        normDist += (((Double)getDistortion(bitDepths.recon[toChannelType(ComponentID(compIdx))], mergedOffsetParam.typeIdc, mergedOffsetParam.typeAuxInfo, mergedOffsetParam.offset, blkStats[ctuRsAddr][compIdx][mergedOffsetParam.typeIdc]))
                        /m_lambda[compIdx]
                     );
@@ -742,5 +745,5 @@
     m_pcRDGoOnSbacCoder->load(cabacCoderRDO[inCabacLabel]);
     m_pcRDGoOnSbacCoder->resetBits();
-    m_pcRDGoOnSbacCoder->codeSAOBlkParam(testBlkParam, sliceEnabled, (mergeList[SAO_MERGE_LEFT]!= NULL), (mergeList[SAO_MERGE_ABOVE]!= NULL), false);
+    m_pcRDGoOnSbacCoder->codeSAOBlkParam(testBlkParam, bitDepths, sliceEnabled, (mergeList[SAO_MERGE_LEFT]!= NULL), (mergeList[SAO_MERGE_ABOVE]!= NULL), false);
     Int rate = m_pcRDGoOnSbacCoder->getNumberOfWrittenBits();
 
@@ -756,14 +759,18 @@
 
   m_pcRDGoOnSbacCoder->load(cabacCoderRDO[SAO_CABACSTATE_BLK_TEMP]);
-
-
-}
-
-Void TEncSampleAdaptiveOffset::decideBlkParams(TComPic* pic, Bool* sliceEnabled, SAOStatData*** blkStats, TComPicYuv* srcYuv, TComPicYuv* resYuv, SAOBlkParam* reconParams, SAOBlkParam* codedParams)
-{
-  Bool isAllBlksDisabled = false;
-  if(!sliceEnabled[SAO_Y] && !sliceEnabled[SAO_Cb] && !sliceEnabled[SAO_Cr])
-  {
-    isAllBlksDisabled = true;
+}
+
+Void TEncSampleAdaptiveOffset::decideBlkParams(TComPic* pic, Bool* sliceEnabled, SAOStatData*** blkStats, TComPicYuv* srcYuv, TComPicYuv* resYuv,
+                                               SAOBlkParam* reconParams, SAOBlkParam* codedParams, const Bool bTestSAODisableAtPictureLevel,
+                                               const Double saoEncodingRate, const Double saoEncodingRateChroma)
+{
+  Bool allBlksDisabled = true;
+  const Int numberOfComponents = getNumberValidComponents(m_chromaFormatIDC);
+  for(Int compId = COMPONENT_Y; compId < numberOfComponents; compId++)
+  {
+    if (sliceEnabled[compId])
+    {
+      allBlksDisabled = false;
+    }
   }
 
@@ -773,9 +780,12 @@
   Double minCost, modeCost;
 
-  for(Int ctu=0; ctu< m_numCTUsPic; ctu++)
-  {
-    if(isAllBlksDisabled)
-    {
-      codedParams[ctu].reset();
+
+  Double totalCost = 0; // Used if bTestSAODisableAtPictureLevel==true
+
+  for(Int ctuRsAddr=0; ctuRsAddr< m_numCTUsPic; ctuRsAddr++)
+  {
+    if(allBlksDisabled)
+    {
+      codedParams[ctuRsAddr].reset();
       continue;
     }
@@ -784,6 +794,6 @@
 
     //get merge list
-    std::vector<SAOBlkParam*> mergeList;
-    getMergeList(pic, ctu, reconParams, mergeList);
+    SAOBlkParam* mergeList[NUM_SAO_MERGE_TYPES] = { NULL };
+    getMergeList(pic, ctuRsAddr, reconParams, mergeList);
 
     minCost = MAX_DOUBLE;
@@ -799,5 +809,5 @@
       case SAO_MODE_NEW:
         {
-          deriveModeNewRDO(ctu, mergeList, sliceEnabled, blkStats, modeParam, modeCost, m_pppcRDSbacCoder, SAO_CABACSTATE_BLK_CUR);
+          deriveModeNewRDO(pic->getPicSym()->getSPS().getBitDepths(), ctuRsAddr, mergeList, sliceEnabled, blkStats, modeParam, modeCost, m_pppcRDSbacCoder, SAO_CABACSTATE_BLK_CUR);
 
         }
@@ -805,5 +815,5 @@
       case SAO_MODE_MERGE:
         {
-          deriveModeMergeRDO(ctu, mergeList, sliceEnabled, blkStats , modeParam, modeCost, m_pppcRDSbacCoder, SAO_CABACSTATE_BLK_CUR);
+          deriveModeMergeRDO(pic->getPicSym()->getSPS().getBitDepths(), ctuRsAddr, mergeList, sliceEnabled, blkStats , modeParam, modeCost, m_pppcRDSbacCoder, SAO_CABACSTATE_BLK_CUR);
         }
         break;
@@ -816,56 +826,74 @@
       }
 
+      D_PRINT_INDENT( g_traceSAOCost, "SAO mode " + n2s( mode ) + " Cost:  " + n2s( modeCost) );
+
       if(modeCost < minCost)
       {
         minCost = modeCost;
-        codedParams[ctu] = modeParam;
+        codedParams[ctuRsAddr] = modeParam;
         m_pcRDGoOnSbacCoder->store(m_pppcRDSbacCoder[ SAO_CABACSTATE_BLK_NEXT ]);
-
       }
     } //mode
+
+    totalCost += minCost;
+
     m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[ SAO_CABACSTATE_BLK_NEXT ]);
 
     //apply reconstructed offsets
-    reconParams[ctu] = codedParams[ctu];
-    reconstructBlkSAOParam(reconParams[ctu], mergeList);
-    offsetCTU(ctu, srcYuv, resYuv, reconParams[ctu], pic);
-  } //ctu
-
-#if SAO_ENCODING_CHOICE 
+    reconParams[ctuRsAddr] = codedParams[ctuRsAddr];
+    reconstructBlkSAOParam(reconParams[ctuRsAddr], mergeList);
+    offsetCTU(ctuRsAddr, srcYuv, resYuv, reconParams[ctuRsAddr], pic);
+  } //ctuRsAddr
+
+  if (!allBlksDisabled && (totalCost >= 0) && bTestSAODisableAtPictureLevel) //SAO has not beneficial in this case - disable it
+  {
+    for(Int ctuRsAddr = 0; ctuRsAddr < m_numCTUsPic; ctuRsAddr++)
+    {
+      codedParams[ctuRsAddr].reset();
+    }
+
+    for (UInt componentIndex = 0; componentIndex < MAX_NUM_COMPONENT; componentIndex++)
+    {
+      sliceEnabled[componentIndex] = false;
+    }
+
+    m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[ SAO_CABACSTATE_PIC_INIT ]);
+  }
+
+  if (saoEncodingRate > 0.0)
+  {
   Int picTempLayer = pic->getSlice(0)->getDepth();
-  Int numLcusForSAOOff[NUM_SAO_COMPONENTS];
-  numLcusForSAOOff[SAO_Y ] = numLcusForSAOOff[SAO_Cb]= numLcusForSAOOff[SAO_Cr]= 0;
-
-  for (Int compIdx=0; compIdx<NUM_SAO_COMPONENTS; compIdx++)
-  {
-    for(Int ctu=0; ctu< m_numCTUsPic; ctu++)
-    {
-      if( reconParams[ctu][compIdx].modeIdc == SAO_MODE_OFF)
-      {
-        numLcusForSAOOff[compIdx]++;
-      }
-    }
-  }
-#if SAO_ENCODING_CHOICE_CHROMA
-  for (Int compIdx=0; compIdx<NUM_SAO_COMPONENTS; compIdx++)
-  {
-    m_saoDisabledRate[compIdx][picTempLayer] = (Double)numLcusForSAOOff[compIdx]/(Double)m_numCTUsPic;
-  }
-#else
-  if (picTempLayer == 0)
-  {
-    m_saoDisabledRate[SAO_Y][0] = (Double)(numLcusForSAOOff[SAO_Y]+numLcusForSAOOff[SAO_Cb]+numLcusForSAOOff[SAO_Cr])/(Double)(m_numCTUsPic*3);
-  }
-#endif                                              
-#endif
-}
-
-
-Void TEncSampleAdaptiveOffset::getBlkStats(Int compIdx, SAOStatData* statsDataTypes  
+  Int numCtusForSAOOff[MAX_NUM_COMPONENT];
+
+  for (Int compIdx = 0; compIdx < numberOfComponents; compIdx++)
+  {
+    numCtusForSAOOff[compIdx] = 0;
+    for(Int ctuRsAddr=0; ctuRsAddr< m_numCTUsPic; ctuRsAddr++)
+    {
+      if( reconParams[ctuRsAddr][compIdx].modeIdc == SAO_MODE_OFF)
+      {
+        numCtusForSAOOff[compIdx]++;
+      }
+    }
+  }
+    if (saoEncodingRateChroma > 0.0)
+    {
+  for (Int compIdx = 0; compIdx < numberOfComponents; compIdx++)
+  {
+    m_saoDisabledRate[compIdx][picTempLayer] = (Double)numCtusForSAOOff[compIdx]/(Double)m_numCTUsPic;
+  }
+    }
+    else if (picTempLayer == 0)
+  {
+    m_saoDisabledRate[COMPONENT_Y][0] = (Double)(numCtusForSAOOff[COMPONENT_Y]+numCtusForSAOOff[COMPONENT_Cb]+numCtusForSAOOff[COMPONENT_Cr])/(Double)(m_numCTUsPic*3);
+  }
+  }
+}
+
+
+Void TEncSampleAdaptiveOffset::getBlkStats(const ComponentID compIdx, const Int channelBitDepth, SAOStatData* statsDataTypes
                         , Pel* srcBlk, Pel* orgBlk, Int srcStride, Int orgStride, Int width, Int height
-                        , Bool isLeftAvail,  Bool isRightAvail, Bool isAboveAvail, Bool isBelowAvail, Bool isAboveLeftAvail, Bool isAboveRightAvail, Bool isBelowLeftAvail, Bool isBelowRightAvail
-#if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
+                        , Bool isLeftAvail,  Bool isRightAvail, Bool isAboveAvail, Bool isBelowAvail, Bool isAboveLeftAvail, Bool isAboveRightAvail
                         , Bool isCalculatePreDeblockSamples
-#endif
                         )
 {
@@ -874,8 +902,16 @@
     m_lineBufWidth = m_maxCUWidth;
 
-    if (m_signLineBuf1) delete[] m_signLineBuf1; m_signLineBuf1 = NULL;
-    m_signLineBuf1 = new Char[m_lineBufWidth+1]; 
-
-    if (m_signLineBuf2) delete[] m_signLineBuf2; m_signLineBuf2 = NULL;
+    if (m_signLineBuf1)
+    {
+      delete[] m_signLineBuf1;
+      m_signLineBuf1 = NULL;
+    }
+    m_signLineBuf1 = new Char[m_lineBufWidth+1];
+
+    if (m_signLineBuf2)
+    {
+      delete[] m_signLineBuf2;
+      m_signLineBuf2 = NULL;
+    }
     m_signLineBuf2 = new Char[m_lineBufWidth+1];
   }
@@ -904,32 +940,16 @@
         count+=2;
         endY   = (isBelowAvail) ? (height - skipLinesB[typeIdx]) : height;
-#if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
         startX = (!isCalculatePreDeblockSamples) ? (isLeftAvail  ? 0 : 1)
                                                  : (isRightAvail ? (width - skipLinesR[typeIdx]) : (width - 1))
                                                  ;
-#else
-        startX = isLeftAvail ? 0 : 1;
-#endif
-#if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
         endX   = (!isCalculatePreDeblockSamples) ? (isRightAvail ? (width - skipLinesR[typeIdx]) : (width - 1))
                                                  : (isRightAvail ? width : (width - 1))
                                                  ;
-#else
-        endX   = isRightAvail ? (width - skipLinesR[typeIdx]): (width - 1);
-#endif
         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;
@@ -941,5 +961,4 @@
           orgLine  += orgStride;
         }
-#if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
         if(isCalculatePreDeblockSamples)
         {
@@ -951,16 +970,8 @@
             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;
@@ -974,5 +985,4 @@
           }
         }
-#endif
       }
       break;
@@ -983,17 +993,11 @@
         Char *signUpLine = m_signLineBuf1;
 
-#if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
         startX = (!isCalculatePreDeblockSamples) ? 0
                                                  : (isRightAvail ? (width - skipLinesR[typeIdx]) : width)
                                                  ;
-#endif
         startY = isAboveAvail ? 0 : 1;
-#if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
-        endX   = (!isCalculatePreDeblockSamples) ? (isRightAvail ? (width - skipLinesR[typeIdx]) : width) 
+        endX   = (!isCalculatePreDeblockSamples) ? (isRightAvail ? (width - skipLinesR[typeIdx]) : width)
                                                  : width
                                                  ;
-#else
-        endX   = isRightAvail ? (width - skipLinesR[typeIdx]) : width ;
-#endif
         endY   = isBelowAvail ? (height - skipLinesB[typeIdx]) : (height - 1);
         if (!isAboveAvail)
@@ -1004,15 +1008,7 @@
 
         Pel* srcLineAbove = srcLine - srcStride;
-#if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
-        for (x=startX; x<endX; x++) 
-#else
-        for (x=0; x< endX; x++) 
-#endif
-        {
-#if SAO_SGN_FUNC
+        for (x=startX; x<endX; x++)
+        {
           signUpLine[x] = (Char)sgn(srcLine[x] - srcLineAbove[x]);
-#else
-          signUpLine[x] = (Char)m_sign[srcLine[x] - srcLineAbove[x]];
-#endif
         }
 
@@ -1022,15 +1018,7 @@
           srcLineBelow = srcLine + srcStride;
 
-#if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
           for (x=startX; x<endX; x++)
-#else
-          for (x=0; x<endX; x++)
-#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;
@@ -1042,5 +1030,4 @@
           orgLine += orgStride;
         }
-#if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
         if(isCalculatePreDeblockSamples)
         {
@@ -1057,9 +1044,5 @@
               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] ++;
@@ -1070,5 +1053,4 @@
           }
         }
-#endif
 
       }
@@ -1083,19 +1065,11 @@
         signDownLine= m_signLineBuf2;
 
-#if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
         startX = (!isCalculatePreDeblockSamples) ? (isLeftAvail  ? 0 : 1)
                                                  : (isRightAvail ? (width - skipLinesR[typeIdx]) : (width - 1))
                                                  ;
-#else
-        startX = isLeftAvail ? 0 : 1 ;
-#endif
-
-#if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
+
         endX   = (!isCalculatePreDeblockSamples) ? (isRightAvail ? (width - skipLinesR[typeIdx]): (width - 1))
                                                  : (isRightAvail ? width : (width - 1))
                                                  ;
-#else
-        endX   = isRightAvail ? (width - skipLinesR[typeIdx]): (width - 1);
-#endif
         endY   = isBelowAvail ? (height - skipLinesB[typeIdx]) : (height - 1);
 
@@ -1104,27 +1078,14 @@
         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
         }
 
         //1st line
         Pel* srcLineAbove = srcLine - srcStride;
-#if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
         firstLineStartX = (!isCalculatePreDeblockSamples) ? (isAboveLeftAvail ? 0    : 1) : startX;
         firstLineEndX   = (!isCalculatePreDeblockSamples) ? (isAboveAvail     ? endX : 1) : endX;
-#else
-        firstLineStartX = isAboveLeftAvail ? 0    : 1;
-        firstLineEndX   = isAboveAvail     ? endX : 1;
-#endif
         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] ++;
@@ -1141,20 +1102,12 @@
           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]);
             count[edgeType] ++;
 
-            signDownLine[x+1] = -signDown; 
-          }
-#if SAO_SGN_FUNC
+            signDownLine[x+1] = -signDown;
+          }
           signDownLine[startX] = (Char)sgn(srcLineBelow[startX] - srcLine[startX-1]);
-#else
-          signDownLine[startX] = (Char)m_sign[srcLineBelow[startX] - srcLine[startX-1]];
-#endif
 
           signTmpLine  = signUpLine;
@@ -1165,5 +1118,4 @@
           orgLine += orgStride;
         }
-#if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
         if(isCalculatePreDeblockSamples)
         {
@@ -1180,9 +1132,5 @@
               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] ++;
@@ -1193,5 +1141,4 @@
           }
         }
-#endif
       }
       break;
@@ -1202,18 +1149,10 @@
         Char *signUpLine = m_signLineBuf1+1;
 
-#if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
         startX = (!isCalculatePreDeblockSamples) ? (isLeftAvail  ? 0 : 1)
                                                  : (isRightAvail ? (width - skipLinesR[typeIdx]) : (width - 1))
                                                  ;
-#else
-        startX = isLeftAvail ? 0 : 1;
-#endif
-#if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
         endX   = (!isCalculatePreDeblockSamples) ? (isRightAvail ? (width - skipLinesR[typeIdx]) : (width - 1))
                                                  : (isRightAvail ? width : (width - 1))
                                                  ;
-#else
-        endX   = isRightAvail ? (width - skipLinesR[typeIdx]) : (width - 1);
-#endif
         endY   = isBelowAvail ? (height - skipLinesB[typeIdx]) : (height - 1);
 
@@ -1222,9 +1161,5 @@
         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
         }
 
@@ -1232,5 +1167,4 @@
         //first line
         Pel* srcLineAbove = srcLine - srcStride;
-#if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
         firstLineStartX = (!isCalculatePreDeblockSamples) ? (isAboveAvail ? startX : endX)
                                                           : startX
@@ -1239,15 +1173,7 @@
                                                           : endX
                                                           ;
-#else
-        firstLineStartX = isAboveAvail ? startX : endX;
-        firstLineEndX   = (!isRightAvail && isAboveRightAvail) ? width : endX;
-#endif
         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] ++;
@@ -1264,9 +1190,5 @@
           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];
 
@@ -1274,15 +1196,10 @@
             count[edgeType] ++;
 
-            signUpLine[x-1] = -signDown; 
-          }
-#if SAO_SGN_FUNC
+            signUpLine[x-1] = -signDown;
+          }
           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;
         }
-#if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
         if(isCalculatePreDeblockSamples)
         {
@@ -1299,9 +1216,5 @@
               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] ++;
@@ -1312,10 +1225,8 @@
           }
         }
-#endif
       }
       break;
     case SAO_TYPE_BO:
       {
-#if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
         startX = (!isCalculatePreDeblockSamples)?0
                                                 :( isRightAvail?(width- skipLinesR[typeIdx]):width)
@@ -1324,19 +1235,12 @@
                                                 :width
                                                 ;
-#else
-        endX = isRightAvail ? (width- skipLinesR[typeIdx]) : width;
-#endif
         endY = isBelowAvail ? (height- skipLinesB[typeIdx]) : height;
-        Int shiftBits = ((compIdx == SAO_Y)?g_bitDepthY:g_bitDepthC)- NUM_SAO_BO_CLASSES_LOG2;
+        Int shiftBits = channelBitDepth - NUM_SAO_BO_CLASSES_LOG2;
         for (y=0; y< endY; y++)
         {
-#if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
           for (x=startX; x< endX; x++)
-#else
-          for (x=0; x< endX; x++)
-#endif
-          {
-
-            Int bandIdx= srcLine[x] >> shiftBits; 
+          {
+
+            Int bandIdx= srcLine[x] >> shiftBits;
             diff [bandIdx] += (orgLine[x] - srcLine[x]);
             count[bandIdx] ++;
@@ -1345,5 +1249,4 @@
           orgLine += orgStride;
         }
-#if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
         if(isCalculatePreDeblockSamples)
         {
@@ -1357,5 +1260,5 @@
               for (x=startX; x< endX; x++)
               {
-                Int bandIdx= srcLine[x] >> shiftBits; 
+                Int bandIdx= srcLine[x] >> shiftBits;
                 diff [bandIdx] += (orgLine[x] - srcLine[x]);
                 count[bandIdx] ++;
@@ -1368,5 +1271,4 @@
           }
         }
-#endif
       }
       break;
@@ -1381,3 +1283,4 @@
 }
 
+
 //! \}
