Index: source/App/TAppDecoder/TAppDecTop.cpp
===================================================================
--- source/App/TAppDecoder/TAppDecTop.cpp	(revision 459)
+++ source/App/TAppDecoder/TAppDecTop.cpp	(working copy)
@@ -124,6 +124,9 @@
   Bool loopFiltered = false;
 
 #if BILATERAL_FILTER
+#if BILATERAL_FILTER_DIV_TO_MUL
+  TComBilateralFilter::instance()->createdivToMulLUTs();
+#endif
   // only need to do this once before encoding/decoding first slice in first picture
   for(Int qp=18; qp<MAX_QP+1; qp++ )
   {
Index: source/App/TAppEncoder/TAppEncTop.cpp
===================================================================
--- source/App/TAppEncoder/TAppEncTop.cpp	(revision 459)
+++ source/App/TAppEncoder/TAppEncTop.cpp	(working copy)
@@ -611,14 +611,18 @@
     cPicYuvTrueOrg.create(m_iSourceWidth, m_iSourceHeight, m_chromaFormatIDC, m_uiMaxCUWidth, m_uiMaxCUHeight, m_uiMaxTotalCUDepth, true );
   }
 #endif
-
+  
+  
 #if BILATERAL_FILTER
-      // only need to do this once before decoding first slice in first picture
-      for(Int qp=18; qp<MAX_QP+1; qp++ )
-      {
-          TComBilateralFilter::instance()->createBilateralFilterTable(qp);
-      }
+#if BILATERAL_FILTER_DIV_TO_MUL
+  TComBilateralFilter::instance()->createdivToMulLUTs();
 #endif
+  // only need to do this once before decoding first slice in first picture
+  for(Int qp=18; qp<MAX_QP+1; qp++ )
+  {
+    TComBilateralFilter::instance()->createBilateralFilterTable(qp);
+  }
+#endif
 
   while ( !bEos )
   {
Index: source/Lib/TLibCommon/TComBilateralFilter.cpp
===================================================================
--- source/Lib/TLibCommon/TComBilateralFilter.cpp	(revision 459)
+++ source/Lib/TLibCommon/TComBilateralFilter.cpp	(working copy)
@@ -142,6 +142,65 @@
   return m_bilateralFilterInstance;
 }
 
+#if BILATERAL_FILTER_DIV_TO_MUL
+Void TComBilateralFilter::createdivToMulLUTs()
+{
+  UInt one = 1 << BITS_PER_DIV_LUT_ENTRY; // 1 is represented by 2^14 (not 2^14 -1)
+  divToMulOneOverN[0] = one; // We can never divide by zero since the centerweight is non-zero, so we can set this value to something arbitrary.
+  divToMulShift[0] = 0;
+  
+  for (UInt n=1; n<BILATERAL_FILTER_MAX_DENOMINATOR_PLUS_ONE; n++)
+  {
+    UInt tryLUT = one / n;
+    
+    UInt tryShift = 0;
+    // Make sure the LUT entry stored does not start with (binary) zeros.
+    while(tryLUT <= one)
+    {
+      // This value of tryLUT
+      divToMulOneOverN[n] = tryLUT;
+      divToMulShift[n] = tryShift;
+      
+      tryShift++;
+      tryLUT = (one << tryShift) / n;
+    }
+    
+    // We may need to add 1 to the LUT entry in order to make 3/3, 4/4, 5/5, ... come out right.
+    UInt adiv = divToMulOneOverN[n] * n / (one << divToMulShift[n]);
+    if(adiv != 1)
+      divToMulOneOverN[n]++;
+  }
+  
+  // Testing:
+  
+#if 0
+  printf("Testing division table\n");
+  // 5 bit without 16x16 inter
+  // The largest possible nominator is (1300*4+4207/2) = (1300*4+160) = 5360
+  // The largest possible denominator is 31*4+196 = 320
+  //
+  // 14 bits is sufficient, N = 2^14
+  
+  for(Int t=0; t<=5362; t++)
+  {
+    for(Int n=1; n<=324; n++)
+    {
+      Int idiv = t/n;
+      Int adiv = (divToMulOneOverN[n] * (Int)t) >> (BITS_PER_DIV_LUT_ENTRY + divToMulShift[n]);
+      if(abs(idiv-((Int)(adiv))) != 0)
+      {
+        printf("Error constructing division table: %d/%d should be %d, is %d\n", t, n, idiv, adiv);
+        exit(1);
+      }
+    }
+  }
+  printf("Testing of the division table finished.\n");
+#endif
+
+}
+#endif
+
+
 Void TComBilateralFilter::createBilateralFilterTable(Int qp)
 {
   Int spatialSigmaValue;
@@ -224,8 +283,410 @@
   }
 }
 
+#if BILATERAL_FILTER_DIV_TO_MUL
 Void TComBilateralFilter::smoothBlockBilateralFilter(TComDataCU* pcCU, UInt uiWidth, UInt uiHeight, Short block[], Int length, Int optimalSpatialSigmaIndex, Int qp)
 {
+  Int rightPixel, centerPixel;
+  Int rightWeight, bottomWeight, centerWeight;
+  Int sumWeights[128];
+  Int sumDelta[128];
+  Int blockLengthIndex;
+  
+  Int dIB, dIR;
+  
+  
+#if BILATERAL_FILTER_AVOID_16x16_INTER
+  if(length > 8 && optimalSpatialSigmaIndex == 1)
+  {
+    return;
+  }
+#endif
+  
+  switch (length)
+  {
+    case 4:
+      blockLengthIndex = 0;
+      break;
+    case 8:
+      blockLengthIndex = 1;
+      break;
+    default:
+      blockLengthIndex = 2;
+      break;
+  }
+  
+  UShort *lookupTablePtr;
+  
+#if BILATERAL_FILTER_MULTIPLY_CENTER_VALUE
+  centerWeight = m_bilateralCenterWeightTable[blockLengthIndex + 3 * optimalSpatialSigmaIndex];
+#else
+  Not Implemented
+#endif
+  
+  Int theMaxPos = maxPosList[qp-18];
+  lookupTablePtr = m_bilateralFilterTable[qp-18];
+
+  // for each pixel in block
+  
+  // These are the types of pixels:
+  //
+  // A BB C
+  //
+  // D EE F
+  // D EE F
+  //
+  // G HH I
+  //
+  // If the block is larger than 4x4, the E-part is larger.
+  //
+  // Filter types:
+  //
+  // AA  BBB   CC
+  // A    B     C
+  //
+  // D    E     F
+  // DD  EEE   FF
+  // D    E     F
+  //
+  // G    H     I
+  // GG  HHH   II
+  // C uses a filter of type x
+  Int currentPixelDeltaSum;
+  Int currentPixelSumWeights;
+  Int rightPixelDeltaSum;
+  Int rightPixelSumWeights;
+  Int rightWeightTimesdIR;
+  Int bottomWeightTimesdIB;
+  
+  Int mySignIfNeg;
+  Int mySign;
+  
+  Short *blockCurrentPixelPtr = block;
+  Short *blockRightPixelPtr = blockCurrentPixelPtr+1;
+  Short *blockNextLinePixelPtr = blockCurrentPixelPtr + uiWidth;
+  Int *sumWeightsPtr = sumWeights;
+  Int *sumDeltaPtr = sumDelta;
+  
+  // A pixel. uses filter type xx
+  //                           x
+  //
+  // No information from previous row
+  // No information from previous pixel
+  // Storing information to next row
+  // Storing information to next pixel
+#if BILATERAL_FILTER_ONLY_REF_NZFILTERCOEFF
+#else
+  Not implemented.
+#endif
+  
+#if BILATERAL_FILTER_FIX_OVERFLOW_FOR_16BITS
+  Not implemented.
+#endif
+  // top left pixel; i = 0, j = 0;
+  
+  centerPixel = *(blockCurrentPixelPtr);
+  rightPixel = *(blockRightPixelPtr++);
+  dIR = rightPixel - centerPixel;
+  dIB = *(blockNextLinePixelPtr++) - centerPixel;
+  
+  rightWeight = lookupTablePtr[std::min(theMaxPos, abs(dIR))];
+  bottomWeight = lookupTablePtr[std::min(theMaxPos, abs(dIB))];
+  
+  rightWeightTimesdIR = rightWeight*dIR;
+  bottomWeightTimesdIB = bottomWeight*dIB;
+  
+  currentPixelSumWeights = centerWeight + rightWeight + bottomWeight;
+  currentPixelDeltaSum = rightWeightTimesdIR + bottomWeightTimesdIB;
+  
+  rightPixelSumWeights = rightWeight; //next pixel to the right
+  rightPixelDeltaSum = rightWeightTimesdIR;
+  
+  *(sumWeightsPtr++) = bottomWeight; //next pixel to the bottom
+  *(sumDeltaPtr++) = bottomWeightTimesdIB; //next pixel to the bottom
+  
+  mySignIfNeg = SIGN_IF_NEG(currentPixelDeltaSum);
+  mySign = 1 | mySignIfNeg;
+#if BILATERAL_FILTER_DIV_TO_MUL
+  *(blockCurrentPixelPtr++) = centerPixel + mySign*((((mySign*currentPixelDeltaSum + ((currentPixelSumWeights+mySignIfNeg) >> 1))*divToMulOneOverN[currentPixelSumWeights]) >> (BITS_PER_DIV_LUT_ENTRY + divToMulShift[currentPixelSumWeights])));
+#else
+  *(blockCurrentPixelPtr++) = centerPixel + (currentPixelDeltaSum + mySign*((currentPixelSumWeights+mySignIfNeg) >> 1) )/currentPixelSumWeights;
+#endif
+  
+  for (Int i = 1; i < (uiWidth-1); i++)
+  {
+    // B pixel. uses filter type xxx
+    //                            x
+    //
+    // No information from previous row
+    // Information reused from previous pixel
+    // Storing information to next row
+    // Storing information to next pixel
+    
+    centerPixel = rightPixel;
+    rightPixel = *(blockRightPixelPtr++);
+    dIR = rightPixel - centerPixel;
+    dIB = *(blockNextLinePixelPtr++) - centerPixel;
+    
+    rightWeight = lookupTablePtr[std::min(theMaxPos, abs(dIR))];
+    bottomWeight = lookupTablePtr[std::min(theMaxPos, abs(dIB))];
+    
+    rightWeightTimesdIR = rightWeight*dIR;
+    bottomWeightTimesdIB = bottomWeight*dIB;
+    
+    currentPixelSumWeights = centerWeight + rightPixelSumWeights + rightWeight + bottomWeight;
+    currentPixelDeltaSum = rightWeightTimesdIR + bottomWeightTimesdIB - rightPixelDeltaSum;
+    
+    rightPixelSumWeights = rightWeight; //next pixel to the right
+    rightPixelDeltaSum = rightWeightTimesdIR; //next pixel to the right
+    
+    *(sumWeightsPtr++) = bottomWeight; //next pixel to the bottom
+    *(sumDeltaPtr++) = bottomWeightTimesdIB; //next pixel to the bottom
+    
+    mySignIfNeg = SIGN_IF_NEG(currentPixelDeltaSum);
+    mySign = 1 | mySignIfNeg;
+#if BILATERAL_FILTER_DIV_TO_MUL
+    *(blockCurrentPixelPtr++) = centerPixel + mySign*((((mySign*currentPixelDeltaSum + ((currentPixelSumWeights+mySignIfNeg) >> 1))*divToMulOneOverN[currentPixelSumWeights]) >> (BITS_PER_DIV_LUT_ENTRY + divToMulShift[currentPixelSumWeights])));
+#else
+    *(blockCurrentPixelPtr++) = centerPixel + (currentPixelDeltaSum + mySign*((currentPixelSumWeights+mySignIfNeg) >> 1) )/currentPixelSumWeights;
+#endif
+    
+  }
+  
+  // C pixel. uses filter type xx
+  //                            x
+  //
+  // No information from previous row
+  // Information reused from previous pixel
+  // Storing information to next row
+  // No information to store to next pixel
+  
+  centerPixel = rightPixel;
+  blockRightPixelPtr++;
+  dIB = *(blockNextLinePixelPtr++) - centerPixel;
+  
+  bottomWeight = lookupTablePtr[std::min(theMaxPos, abs(dIB))];
+  bottomWeightTimesdIB = bottomWeight*dIB;
+  
+  currentPixelSumWeights = centerWeight + rightPixelSumWeights + bottomWeight;
+  currentPixelDeltaSum = bottomWeightTimesdIB - rightPixelDeltaSum;
+  
+  *(sumWeightsPtr) = bottomWeight; //next pixel to the bottom
+  *(sumDeltaPtr++) = bottomWeightTimesdIB; //next pixel to the bottom
+  
+  mySignIfNeg = SIGN_IF_NEG(currentPixelDeltaSum);
+  mySign = 1 | mySignIfNeg;
+#if BILATERAL_FILTER_DIV_TO_MUL
+  *(blockCurrentPixelPtr++) = centerPixel + mySign*((((mySign*currentPixelDeltaSum + ((currentPixelSumWeights+mySignIfNeg) >> 1))*divToMulOneOverN[currentPixelSumWeights]) >> (BITS_PER_DIV_LUT_ENTRY + divToMulShift[currentPixelSumWeights])));
+#else
+  *(blockCurrentPixelPtr++) = centerPixel + (currentPixelDeltaSum + mySign*((currentPixelSumWeights+mySignIfNeg) >> 1) )/currentPixelSumWeights;
+#endif
+  
+  for (Int j = 1; j < (uiHeight-1); j++)
+  {
+    sumWeightsPtr = sumWeights;
+    sumDeltaPtr = sumDelta;
+    
+    //                           x
+    // D pixel. uses filter type xx
+    //                           x
+    //
+    // Uses information from previous row
+    // No information from previous pixel
+    // Storing information to next row
+    // Storing information to next pixel
+    
+    centerPixel = *(blockCurrentPixelPtr);
+    rightPixel = *(blockRightPixelPtr++);
+    dIR = rightPixel - centerPixel;
+    dIB = *(blockNextLinePixelPtr++) - centerPixel;
+    
+    rightWeight = lookupTablePtr[std::min(theMaxPos, abs(dIR))];
+    bottomWeight = lookupTablePtr[std::min(theMaxPos, abs(dIB))];
+    
+    rightWeightTimesdIR = rightWeight*dIR;
+    bottomWeightTimesdIB = bottomWeight*dIB;
+    
+    currentPixelSumWeights = centerWeight + *(sumWeightsPtr) + rightWeight + bottomWeight;
+    currentPixelDeltaSum = rightWeightTimesdIR + bottomWeightTimesdIB - *(sumDeltaPtr);
+    
+    rightPixelSumWeights = rightWeight; //next pixel to the right
+    rightPixelDeltaSum = rightWeightTimesdIR;
+    
+    *(sumWeightsPtr++) = bottomWeight; //next pixel to the bottom
+    *(sumDeltaPtr++) = bottomWeightTimesdIB; //next pixel to the bottom
+    
+    mySignIfNeg = SIGN_IF_NEG(currentPixelDeltaSum);
+    mySign = 1 | mySignIfNeg;
+#if BILATERAL_FILTER_DIV_TO_MUL
+    *(blockCurrentPixelPtr++) = centerPixel + mySign*((((mySign*currentPixelDeltaSum + ((currentPixelSumWeights+mySignIfNeg) >> 1))*divToMulOneOverN[currentPixelSumWeights]) >> (BITS_PER_DIV_LUT_ENTRY + divToMulShift[currentPixelSumWeights])));
+#else
+    *(blockCurrentPixelPtr++) = centerPixel + (currentPixelDeltaSum + mySign*((currentPixelSumWeights+mySignIfNeg) >> 1) )/currentPixelSumWeights;
+#endif
+    
+    for (Int i = 1; i < (uiWidth-1); i++)
+    {
+      //                            x
+      // E pixel. uses filter type xxx
+      //                            x
+      //
+      // Uses information from previous row
+      // Uses information from previous pixel
+      // Storing information to next row
+      // No information to store to next pixel
+      
+      centerPixel = rightPixel;
+      rightPixel = *(blockRightPixelPtr++);
+      dIR = rightPixel - centerPixel;
+      dIB = *(blockNextLinePixelPtr++) - centerPixel;
+      
+      rightWeight = lookupTablePtr[std::min(theMaxPos, abs(dIR))];
+      bottomWeight = lookupTablePtr[std::min(theMaxPos, abs(dIB))];
+      
+      rightWeightTimesdIR = rightWeight*dIR;
+      bottomWeightTimesdIB = bottomWeight*dIB;
+      
+      currentPixelSumWeights = centerWeight + *(sumWeightsPtr) + rightPixelSumWeights + rightWeight + bottomWeight;
+      currentPixelDeltaSum = rightWeightTimesdIR + bottomWeightTimesdIB - rightPixelDeltaSum - *(sumDeltaPtr);
+      
+      rightPixelSumWeights = rightWeight; //next pixel to the right
+      rightPixelDeltaSum = rightWeightTimesdIR;
+      
+      *(sumWeightsPtr++) = bottomWeight; //next pixel to the bottom
+      *(sumDeltaPtr++) = bottomWeightTimesdIB; //next pixel to the bottom
+      
+      mySignIfNeg = SIGN_IF_NEG(currentPixelDeltaSum);
+      mySign = 1 | mySignIfNeg;
+#if BILATERAL_FILTER_DIV_TO_MUL
+      *(blockCurrentPixelPtr++) = centerPixel + mySign*((((mySign*currentPixelDeltaSum + ((currentPixelSumWeights+mySignIfNeg) >> 1))*divToMulOneOverN[currentPixelSumWeights]) >> (BITS_PER_DIV_LUT_ENTRY + divToMulShift[currentPixelSumWeights])));
+#else
+      *(blockCurrentPixelPtr++) = centerPixel + (currentPixelDeltaSum + mySign*((currentPixelSumWeights+mySignIfNeg) >> 1) )/currentPixelSumWeights;
+#endif
+    }
+    
+    //                            x
+    // F pixel. uses filter type xx
+    //                            x
+    //
+    // Uses information from previous row
+    // Uses information from previous pixel
+    // Storing information to next row
+    // Storing information to next pixel
+    
+    centerPixel = rightPixel;
+    blockRightPixelPtr++;
+    dIB = *(blockNextLinePixelPtr++) - centerPixel;
+    
+    bottomWeight = lookupTablePtr[std::min(theMaxPos, abs(dIB))];
+    bottomWeightTimesdIB = bottomWeight*dIB;
+    
+    currentPixelSumWeights = centerWeight + *(sumWeightsPtr) + rightPixelSumWeights + bottomWeight;
+    currentPixelDeltaSum = bottomWeightTimesdIB - rightPixelDeltaSum - *(sumDeltaPtr);
+    
+    *(sumWeightsPtr) = bottomWeight; //next pixel to the bottom
+    *(sumDeltaPtr++) = bottomWeightTimesdIB; //next pixel to the bottom
+    
+    mySignIfNeg = SIGN_IF_NEG(currentPixelDeltaSum);
+    mySign = 1 | mySignIfNeg;
+#if BILATERAL_FILTER_DIV_TO_MUL
+    *(blockCurrentPixelPtr++) = centerPixel + mySign*((((mySign*currentPixelDeltaSum + ((currentPixelSumWeights+mySignIfNeg) >> 1))*divToMulOneOverN[currentPixelSumWeights]) >> (BITS_PER_DIV_LUT_ENTRY + divToMulShift[currentPixelSumWeights])));
+#else
+    *(blockCurrentPixelPtr++) = centerPixel + (currentPixelDeltaSum + mySign*((currentPixelSumWeights+mySignIfNeg) >> 1) )/currentPixelSumWeights;
+#endif
+    
+  }
+  
+  sumWeightsPtr = sumWeights;
+  sumDeltaPtr = sumDelta;
+  
+  //                           x
+  // G pixel. uses filter type xx
+  //
+  // Uses information from previous row
+  // No information from previous pixel
+  // No information to store to next row
+  // Storing information to next pixel
+  
+  
+  centerPixel = *(blockCurrentPixelPtr);
+  rightPixel = *(blockRightPixelPtr++);
+  dIR = rightPixel - centerPixel;
+  
+  rightWeight = lookupTablePtr[std::min(theMaxPos, abs(dIR))];
+  rightWeightTimesdIR = rightWeight*dIR;
+  
+  currentPixelSumWeights = centerWeight + *(sumWeightsPtr++) + rightWeight;
+  currentPixelDeltaSum = rightWeightTimesdIR - *(sumDeltaPtr++);
+  
+  rightPixelSumWeights = rightWeight; //next pixel to the right
+  rightPixelDeltaSum = rightWeightTimesdIR;
+  
+  mySignIfNeg = SIGN_IF_NEG(currentPixelDeltaSum);
+  mySign = 1 | mySignIfNeg;
+#if BILATERAL_FILTER_DIV_TO_MUL
+  *(blockCurrentPixelPtr++) = centerPixel + mySign*((((mySign*currentPixelDeltaSum + ((currentPixelSumWeights+mySignIfNeg) >> 1))*divToMulOneOverN[currentPixelSumWeights]) >> (BITS_PER_DIV_LUT_ENTRY + divToMulShift[currentPixelSumWeights])));
+#else
+  *(blockCurrentPixelPtr++) = centerPixel + (currentPixelDeltaSum + mySign*((currentPixelSumWeights+mySignIfNeg) >> 1) )/currentPixelSumWeights;
+#endif
+  
+  for (Int i = 1; i < (uiWidth-1); i++)
+  {
+    //                            x
+    // H pixel. uses filter type xxx
+    //
+    // Uses information from previous row
+    // Uses information from previous pixel
+    // No information to store to next row
+    // Storing information to next pixel
+    
+    centerPixel = rightPixel;
+    rightPixel = *(blockRightPixelPtr++);
+    dIR = rightPixel - centerPixel;
+    
+    rightWeight = lookupTablePtr[std::min(theMaxPos, abs(dIR))];
+    rightWeightTimesdIR = rightWeight*dIR;
+    
+    currentPixelSumWeights = centerWeight + *(sumWeightsPtr++) + rightWeight + rightPixelSumWeights;
+    currentPixelDeltaSum = rightWeightTimesdIR - rightPixelDeltaSum - *(sumDeltaPtr++);
+    
+    rightPixelSumWeights = rightWeight; //next pixel to the right
+    rightPixelDeltaSum = rightWeightTimesdIR;
+    
+    mySignIfNeg = SIGN_IF_NEG(currentPixelDeltaSum);
+    mySign = 1 | mySignIfNeg;
+#if BILATERAL_FILTER_DIV_TO_MUL
+    *(blockCurrentPixelPtr++) = centerPixel + mySign*((((mySign*currentPixelDeltaSum + ((currentPixelSumWeights+mySignIfNeg) >> 1))*divToMulOneOverN[currentPixelSumWeights]) >> (BITS_PER_DIV_LUT_ENTRY + divToMulShift[currentPixelSumWeights])));
+#else
+    *(blockCurrentPixelPtr++) = centerPixel + (currentPixelDeltaSum + mySign*((currentPixelSumWeights+mySignIfNeg) >> 1) )/currentPixelSumWeights;
+#endif
+    
+  }
+  
+  //                            x
+  // I pixel. uses filter type xx
+  //
+  // Uses information from previous row
+  // Uses information from previous pixel
+  // No information to store to next row
+  // No information to store to nex pixel
+  
+  centerPixel = rightPixel;
+  
+  currentPixelSumWeights = centerWeight + *(sumWeightsPtr) + rightPixelSumWeights;
+  currentPixelDeltaSum = - rightPixelDeltaSum - *(sumDeltaPtr);
+  
+  mySignIfNeg = SIGN_IF_NEG(currentPixelDeltaSum);
+  mySign = 1 | mySignIfNeg;
+#if BILATERAL_FILTER_DIV_TO_MUL
+  *(blockCurrentPixelPtr) = centerPixel + mySign*((((mySign*currentPixelDeltaSum + ((currentPixelSumWeights+mySignIfNeg) >> 1))*divToMulOneOverN[currentPixelSumWeights]) >> (BITS_PER_DIV_LUT_ENTRY + divToMulShift[currentPixelSumWeights])));
+#else
+  *(blockCurrentPixelPtr) = centerPixel + (currentPixelDeltaSum + mySign*((currentPixelSumWeights+mySignIfNeg) >> 1) )/currentPixelSumWeights;
+#endif
+  
+}
+
+#else
+Void TComBilateralFilter::smoothBlockBilateralFilter(TComDataCU* pcCU, UInt uiWidth, UInt uiHeight, Short block[], Int length, Int optimalSpatialSigmaIndex, Int qp)
+{
   Int rightPixel, bottomPixel, centerPixel;
   Int rightWeight, bottomWeight, centerWeight;
   Int sumWeights[128], sum[128];
@@ -234,6 +695,13 @@
   Short shiftEntry;
 #endif
 
+#if BILATERAL_FILTER_AVOID_16x16_INTER
+  if(length > 8 && optimalSpatialSigmaIndex == 1)
+  {
+    return;
+  }
+#endif
+  
   switch (length)
   {
     case 4:
@@ -623,6 +1091,10 @@
 
 }
 
+#endif
+
+
+
 Void TComBilateralFilter::bilateralFilterIntra(TComDataCU *pcCU, UInt uiWidth, UInt uiHeight, Pel *piReco, UInt uiStride, Int qp)
 {
   UInt uiMinSize = std::min(uiWidth, uiHeight);
Index: source/Lib/TLibCommon/TComBilateralFilter.h
===================================================================
--- source/Lib/TLibCommon/TComBilateralFilter.h	(revision 459)
+++ source/Lib/TLibCommon/TComBilateralFilter.h	(working copy)
@@ -60,6 +60,12 @@
 #if BILATERAL_FILTER_MULTIPLY_CENTER_VALUE
   Int m_bilateralCenterWeightTable[6];
 #endif
+  
+#if BILATERAL_FILTER_DIV_TO_MUL
+  UInt divToMulOneOverN[BILATERAL_FILTER_MAX_DENOMINATOR_PLUS_ONE];
+  UChar divToMulShift[BILATERAL_FILTER_MAX_DENOMINATOR_PLUS_ONE];
+  Void createdivToMulLUTs();
+#endif
 
   static TComBilateralFilter* instance();
   Void createBilateralFilterTable(Int qp);
Index: source/Lib/TLibCommon/TypeDef.h
===================================================================
--- source/Lib/TLibCommon/TypeDef.h	(revision 459)
+++ source/Lib/TLibCommon/TypeDef.h	(working copy)
@@ -53,7 +53,7 @@
 #if BILATERAL_FILTER
 #define BILATERAL_FILTER_ONLY_REF_NZFILTERCOEFF 1 // reduce stored table and not compute the table for positions that will be 0
 
-#define BILATERAL_FILTER_TEST 1 //1: Bilateral filter after transform as proposed E0032
+#define BILATERAL_FILTER_TEST 2 //1: Bilateral filter after transform as proposed E0032
                                 //2: LUT memory reduction (not bitexact with E0032)
                                 
 
@@ -67,10 +67,20 @@
 #if BILATERAL_FILTER_REDUCE_RANGE == 0
 #define BILATERAL_FILTER_FIX_OVERFLOW_FOR_16BITS 1 // Use this to avoid overflow in 32-bit unsigned int for 16x16 inter filtering. This is only needed if we store 16 bit values.
 #endif
+
+#define BILATERAL_FILTER_AVOID_16x16_INTER 1 // avoid filtering for inter blocks of size 16x16 and larger
+
+#if BILATERAL_FILTER_REDUCE_RANGE==65 && BILATERAL_FILTER_AVOID_16x16_INTER==1
+#define BILATERAL_FILTER_DIV_TO_MUL 1
+#define BILATERAL_FILTER_MAX_DENOMINATOR_PLUS_ONE  325
+#define BITS_PER_DIV_LUT_ENTRY 14
+#define SIGN_IF_NEG(x) (-((x)<0))                  // Returns -1 if x is negative, otherwise 0
 #endif
 
 #endif
 
+#endif
+
 #define JVET_E0062_MULTI_DMS                              1   ///< Extended chroma multiple DM modes
 
 #define JVET_E0077_ENHANCED_LM                            1   ///< Enhanced LM mode
