From e5ceb6022bf99dedf0c36fb2a619c6b13c18be7d Mon Sep 17 00:00:00 2001
From: Adrian Browne <adrian.browne@sony.com>
Date: Wed, 22 Jul 2020 17:44:26 +0100
Subject: [PATCH] Fix for Visual Studio compiler warnings and errors when
 JVET_R0351_HIGH_BIT_DEPTH_ENABLED is enabled

---
 source/Lib/CommonLib/Buffer.h           |  9 ++++
 source/Lib/CommonLib/ContextModelling.h | 65 +++++++++++++++++++++++++
 source/Lib/CommonLib/DepQuant.cpp       | 45 +++++++++++++++++
 source/Lib/CommonLib/TrQuant.cpp        |  8 +++
 source/Lib/CommonLib/TrQuant_EMT.cpp    | 28 +++++++++++
 source/Lib/CommonLib/TypeDef.h          |  1 +
 source/Lib/DecoderLib/CABACReader.cpp   | 24 +++++++++
 source/Lib/DecoderLib/DecCu.cpp         | 14 ++++++
 source/Lib/EncoderLib/CABACWriter.cpp   | 12 +++++
 source/Lib/EncoderLib/IntraSearch.cpp   | 22 +++++++++
 10 files changed, 228 insertions(+)

diff --git a/source/Lib/CommonLib/Buffer.h b/source/Lib/CommonLib/Buffer.h
index 4dfe5a27c4..a1366bfba0 100644
--- a/source/Lib/CommonLib/Buffer.h
+++ b/source/Lib/CommonLib/Buffer.h
@@ -439,7 +439,11 @@ void AreaBuf<T>::removeWeightHighFreq(const AreaBuf<T>& other, const bool bClip,
   else
   {
 #endif
+#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS
+    Intermediate_Int normalizer = ((1 << 16) + (bcwWeight > 0 ? (bcwWeight >> 1) : -(bcwWeight >> 1))) / bcwWeight;
+#else
     int normalizer = ((1 << 16) + (bcwWeight > 0 ? (bcwWeight >> 1) : -(bcwWeight >> 1))) / bcwWeight;
+#endif
 #if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT
     Intermediate_Int weight0 = normalizer << log2WeightBase;
     Intermediate_Int weight1 = bcwWeightOther * normalizer;
@@ -451,8 +455,13 @@ void AreaBuf<T>::removeWeightHighFreq(const AreaBuf<T>& other, const bool bClip,
   src += srcStride; \
   dst += dstStride; \
 
+#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS
+#define REM_HF_OP_CLIP( ADDR ) dst[ADDR] = ClipPel<T>( T((dst[ADDR]*weight0 - src[ADDR]*weight1 + (1<<15))>>16), clpRng )
+#define REM_HF_OP( ADDR )      dst[ADDR] =             T((dst[ADDR]*weight0 - src[ADDR]*weight1 + (1<<15))>>16)
+#else
 #define REM_HF_OP_CLIP( ADDR ) dst[ADDR] = ClipPel<T>( (dst[ADDR]*weight0 - src[ADDR]*weight1 + (1<<15))>>16, clpRng )
 #define REM_HF_OP( ADDR )      dst[ADDR] =             (dst[ADDR]*weight0 - src[ADDR]*weight1 + (1<<15))>>16
+#endif
 
     if(bClip)
     {
diff --git a/source/Lib/CommonLib/ContextModelling.h b/source/Lib/CommonLib/ContextModelling.h
index 10160254f3..11b8fd7b9b 100644
--- a/source/Lib/CommonLib/ContextModelling.h
+++ b/source/Lib/CommonLib/ContextModelling.h
@@ -114,8 +114,13 @@ public:
     const TCoeff* pData     = coeff + posX + posY * m_width;
     const int     diag      = posX + posY;
     int           numPos    = 0;
+#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS
+    TCoeff        sumAbs    = 0;
+#define UPDATE(x) {TCoeff a=abs(x);sumAbs+=std::min(4+(a&1),a);numPos+=int(!!a);}
+#else
     int           sumAbs    = 0;
 #define UPDATE(x) {int a=abs(x);sumAbs+=std::min(4+(a&1),a);numPos+=!!a;}
+#endif
     if( posX < m_width-1 )
     {
       UPDATE( pData[1] );
@@ -139,7 +144,11 @@ public:
 #undef UPDATE
 
 
+#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS
+    int ctxOfs = int(std::min<TCoeff>((sumAbs+1)>>1, 3)) + ( diag < 2 ? 4 : 0 );
+#else
     int ctxOfs = std::min((sumAbs+1)>>1, 3) + ( diag < 2 ? 4 : 0 );
+#endif
 
     if( m_chType == CHANNEL_TYPE_LUMA )
     {
@@ -156,7 +165,11 @@ public:
     int offset = 0;
     if( m_tmplCpDiag != -1 )
     {
+#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS
+      offset  = int(std::min<TCoeff>( m_tmplCpSum1, 4 )) + 1;
+#else
       offset  = std::min( m_tmplCpSum1, 4 ) + 1;
+#endif
       offset += ( !m_tmplCpDiag ? ( m_chType == CHANNEL_TYPE_LUMA ? 15 : 5 ) : m_chType == CHANNEL_TYPE_LUMA ? m_tmplCpDiag < 3 ? 10 : ( m_tmplCpDiag < 10 ? 5 : 0 ) : 0 );
     }
     return uint8_t(offset);
@@ -170,7 +183,11 @@ public:
     const uint32_t  posY  = m_scan[scanPos].y;
     const uint32_t  posX  = m_scan[scanPos].x;
     const TCoeff*   pData = coeff + posX + posY * m_width;
+#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS
+    TCoeff          sum   = 0;
+#else
     int             sum   = 0;
+#endif
     if (posX < m_width - 1)
     {
       sum += abs(pData[1]);
@@ -191,7 +208,11 @@ public:
         sum += abs(pData[m_width << 1]);
       }
     }
+#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS
+    return unsigned(std::max<TCoeff>(std::min<TCoeff>(sum - 5 * baseLevel, 31), 0));
+#else
     return std::max(std::min(sum - 5 * baseLevel, 31), 0);
+#endif
   }
 
   unsigned sigCtxIdAbsTS( int scanPos, const TCoeff* coeff )
@@ -200,7 +221,11 @@ public:
     const uint32_t  posX   = m_scan[scanPos].x;
     const TCoeff*   posC   = coeff + posX + posY * m_width;
     int             numPos = 0;
+#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS
+#define UPDATE(x) {TCoeff a=abs(x);numPos+=int(!!a);}
+#else
 #define UPDATE(x) {int a=abs(x);numPos+=!!a;}
+#endif
     if( posX > 0 )
     {
       UPDATE( posC[-1] );
@@ -224,7 +249,11 @@ public:
     const TCoeff*   posC = coeff + posX + posY * m_width;
 
     int             numPos = 0;
+#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS
+#define UPDATE(x) {TCoeff a=abs(x);numPos+=int(!!a);}
+#else
 #define UPDATE(x) {int a=abs(x);numPos+=!!a;}
+#endif
 
     if (bdpcm)
     {
@@ -308,41 +337,69 @@ public:
 
     if (posX > 0)
     {
+#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS
+      rightPixel = int(data[-1]);
+#else
       rightPixel = data[-1];
+#endif
     }
     if (posY > 0)
     {
+#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS
+      belowPixel = int(data[-(int)m_width]);
+#else
       belowPixel = data[-(int)m_width];
+#endif
     }
   }
 
+#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS
+  int deriveModCoeff(int rightPixel, int belowPixel, TCoeff absCoeff, int bdpcm = 0)
+#else
   int deriveModCoeff(int rightPixel, int belowPixel, int absCoeff, int bdpcm = 0)
+#endif
   {
 
     if (absCoeff == 0)
       return 0;
     int pred1, absBelow = abs(belowPixel), absRight = abs(rightPixel);
 
+#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS
+    int absCoeffMod = int(absCoeff);
+#else
     int absCoeffMod = absCoeff;
+#endif
 
     if (bdpcm == 0)
     {
       pred1 = std::max(absBelow, absRight);
 
+#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS
+      if (absCoeffMod == pred1)
+#else
       if (absCoeff == pred1)
+#endif
       {
         absCoeffMod = 1;
       }
       else
       {
+#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS
+        absCoeffMod = absCoeffMod < pred1 ? absCoeffMod + 1 : absCoeffMod;
+#else
         absCoeffMod = absCoeff < pred1 ? absCoeff + 1 : absCoeff;
+#endif
       }
     }
 
     return(absCoeffMod);
   }
 
+#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS
+  TCoeff decDeriveModCoeff(int rightPixel, int belowPixel, TCoeff absCoeff)
+#else
   int decDeriveModCoeff(int rightPixel, int belowPixel, int absCoeff)
+#endif
   {
 
     if (absCoeff == 0)
@@ -351,7 +408,11 @@ public:
     int pred1, absBelow = abs(belowPixel), absRight = abs(rightPixel);
     pred1 = std::max(absBelow, absRight);
 
+#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS
+    TCoeff absCoeffMod;
+#else
     int absCoeffMod;
+#endif
 
     if (absCoeff == 1 && pred1 > 0)
     {
@@ -413,7 +474,11 @@ private:
   int                       m_minSubPos;
   int                       m_maxSubPos;
   unsigned                  m_sigGroupCtxId;
+#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS
+  TCoeff                    m_tmplCpSum1;
+#else
   int                       m_tmplCpSum1;
+#endif
   int                       m_tmplCpDiag;
   CtxSet                    m_sigFlagCtxSet[3];
   CtxSet                    m_parFlagCtxSet;
diff --git a/source/Lib/CommonLib/DepQuant.cpp b/source/Lib/CommonLib/DepQuant.cpp
index 916e9fe189..6dc1fd2709 100644
--- a/source/Lib/CommonLib/DepQuant.cpp
+++ b/source/Lib/CommonLib/DepQuant.cpp
@@ -629,7 +629,11 @@ namespace DQIntern
     Quantizer() {}
     void  dequantBlock         ( const TransformUnit& tu, const ComponentID compID, const QpParam& cQP, CoeffBuf& recCoeff, bool enableScalingLists, int* piDequantCoef ) const;
     void  initQuantBlock       ( const TransformUnit& tu, const ComponentID compID, const QpParam& cQP, const double lambda, int gValue );
+#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS
+    inline void   preQuantCoeff( const TCoeff absCoeff, PQData *pqData, TCoeff quanCoeff ) const;
+#else
     inline void   preQuantCoeff( const TCoeff absCoeff, PQData *pqData, int quanCoeff ) const;
+#endif
     inline TCoeff getLastThreshold() const { return m_thresLast; }
     inline TCoeff getSSbbThreshold() const { return m_thresSSbb; }
 
@@ -682,7 +686,11 @@ namespace DQIntern
     // quant parameters
     m_QShift                    = QUANT_SHIFT  - 1 + qpPer + transformShift;
     m_QAdd                      = -( ( 3 << m_QShift ) >> 1 );
+#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS
+    int               invShift  = IQUANT_SHIFT + 1 - qpPer - transformShift;
+#else
     Intermediate_Int  invShift  = IQUANT_SHIFT + 1 - qpPer - transformShift;
+#endif
     m_QScale                    = g_quantScales[needsSqrt2ScaleAdjustment?1:0][ qpRem ];
     const unsigned    qIdxBD    = std::min<unsigned>( maxLog2TrDynamicRange + 1, 8*sizeof(Intermediate_Int) + invShift - IQUANT_SHIFT - 1 );
     m_maxQIdx                   = ( 1 << (qIdxBD-1) ) - 4;
@@ -769,7 +777,11 @@ namespace DQIntern
     }
   }
 
+#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS
+  inline void Quantizer::preQuantCoeff(const TCoeff absCoeff, PQData *pqData, TCoeff quanCoeff) const
+#else
   inline void Quantizer::preQuantCoeff(const TCoeff absCoeff, PQData *pqData, int quanCoeff) const
+#endif
   {
     int64_t scaledOrg = int64_t( absCoeff ) * quanCoeff;
     TCoeff  qIdx      = std::max<TCoeff>( 1, std::min<TCoeff>( m_maxQIdx, TCoeff( ( scaledOrg + m_QAdd ) >> m_QShift ) ) );
@@ -886,14 +898,22 @@ namespace DQIntern
             rdCostA += m_coeffFracBits.bits[ pqDataA.absLevel ];
           else
           {
+#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS
+            const TCoeff value = ( pqDataA.absLevel - 4 ) >> 1;
+#else
             const unsigned value = ( pqDataA.absLevel - 4 ) >> 1;
+#endif
             rdCostA += m_coeffFracBits.bits[ pqDataA.absLevel - ( value << 1 ) ] + goRiceTab[ value < RICEMAX ? value : RICEMAX - 1 ];
           }
           if( pqDataB.absLevel < 4 )
             rdCostB += m_coeffFracBits.bits[ pqDataB.absLevel ];
           else
           {
+#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS
+            const TCoeff value = ( pqDataB.absLevel - 4 ) >> 1;
+#else
             const unsigned value = ( pqDataB.absLevel - 4 ) >> 1;
+#endif
             rdCostB += m_coeffFracBits.bits[ pqDataB.absLevel - ( value << 1 ) ] + goRiceTab[ value < RICEMAX ? value : RICEMAX - 1 ];
           }
           if( spt == SCAN_ISCSBB )
@@ -954,7 +974,11 @@ namespace DQIntern
       }
       else
       {
+#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS
+        const TCoeff value = (pqData.absLevel - 4) >> 1;
+#else
         const unsigned value = (pqData.absLevel - 4) >> 1;
+#endif
         rdCost += m_coeffFracBits.bits[pqData.absLevel - (value << 1)] + g_goRiceBits[m_goRicePar][value < RICEMAX ? value : RICEMAX-1];
       }
       if( rdCost < decision.rdCost )
@@ -1030,7 +1054,11 @@ namespace DQIntern
         m_goRicePar             = prvState->m_goRicePar;
         if( m_remRegBins >= 4 )
         {
+#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS
+          m_remRegBins -= (decision.absLevel < 2 ? (unsigned)decision.absLevel : 3);
+#else
           m_remRegBins -= (decision.absLevel < 2 ? decision.absLevel : 3);
+#endif
         }
         ::memcpy( m_absLevelsAndCtxInit, prvState->m_absLevelsAndCtxInit, 48*sizeof(uint8_t) );
       }
@@ -1039,7 +1067,11 @@ namespace DQIntern
         m_numSigSbb     =  1;
         m_refSbbCtxId   = -1;
         int ctxBinSampleRatio = (scanInfo.chType == CHANNEL_TYPE_LUMA) ? MAX_TU_LEVEL_CTX_CODED_BIN_CONSTRAINT_LUMA : MAX_TU_LEVEL_CTX_CODED_BIN_CONSTRAINT_CHROMA;
+#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS
+        m_remRegBins = (effWidth * effHeight *ctxBinSampleRatio) / 16 - (decision.absLevel < 2 ? (unsigned)decision.absLevel : 3);
+#else
         m_remRegBins = (effWidth * effHeight *ctxBinSampleRatio) / 16 - (decision.absLevel < 2 ? decision.absLevel : 3);
+#endif
         ::memset( m_absLevelsAndCtxInit, 0, 48*sizeof(uint8_t) );
       }
 
@@ -1299,8 +1331,13 @@ namespace DQIntern
     void    dequant ( const TransformUnit& tu, CoeffBuf& recCoeff, const ComponentID compID, const QpParam& cQP, bool enableScalingLists, int* quantCoeff );
 
   private:
+#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS
+    void    xDecideAndUpdate  ( const TCoeff absCoeff, const ScanInfo& scanInfo, bool zeroOut, TCoeff quantCoeff);
+    void    xDecide           ( const ScanPosType spt, const TCoeff absCoeff, const int lastOffset, Decision* decisions, bool zeroOut, TCoeff quantCoeff );
+#else
     void    xDecideAndUpdate  ( const TCoeff absCoeff, const ScanInfo& scanInfo, bool zeroOut, int quantCoeff);
     void    xDecide           ( const ScanPosType spt, const TCoeff absCoeff, const int lastOffset, Decision* decisions, bool zeroOut, int quantCoeff );
+#endif
 
   private:
     CommonCtx   m_commonCtx;
@@ -1338,7 +1375,11 @@ namespace DQIntern
 #undef  DINIT
 
 
+#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS
+  void DepQuant::xDecide( const ScanPosType spt, const TCoeff absCoeff, const int lastOffset, Decision* decisions, bool zeroOut, TCoeff quanCoeff)
+#else
   void DepQuant::xDecide( const ScanPosType spt, const TCoeff absCoeff, const int lastOffset, Decision* decisions, bool zeroOut, int quanCoeff)
+#endif
   {
     ::memcpy( decisions, startDec, 8*sizeof(Decision) );
 
@@ -1372,7 +1413,11 @@ namespace DQIntern
     m_startState.checkRdCostStart( lastOffset, pqData[2], decisions[2] );
   }
 
+#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS
+  void DepQuant::xDecideAndUpdate( const TCoeff absCoeff, const ScanInfo& scanInfo, bool zeroOut, TCoeff quantCoeff )
+#else
   void DepQuant::xDecideAndUpdate( const TCoeff absCoeff, const ScanInfo& scanInfo, bool zeroOut, int quantCoeff )
+#endif
   {
     Decision* decisions = m_trellis[ scanInfo.scanIdx ];
 
diff --git a/source/Lib/CommonLib/TrQuant.cpp b/source/Lib/CommonLib/TrQuant.cpp
index 69908d9af2..d0df03baa7 100644
--- a/source/Lib/CommonLib/TrQuant.cpp
+++ b/source/Lib/CommonLib/TrQuant.cpp
@@ -983,7 +983,11 @@ void TrQuant::transformNxN( TransformUnit& tu, const ComponentID& compID, const
       xT( tu, compID, resiBuf, tempCoeff, width, height );
     }
 
+#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS
+    TCoeff sumAbs = 0;
+#else
     int sumAbs = 0;
+#endif
     for( int pos = 0; pos < width*height; pos++ )
     {
       sumAbs += abs( tempCoeff.buf[pos] );
@@ -1000,7 +1004,11 @@ void TrQuant::transformNxN( TransformUnit& tu, const ComponentID& compID, const
         scaleSAD *= pow(2, trShift);
     }
 
+#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS
+    trCosts.push_back( TrCost( int(std::min<double>(sumAbs*scaleSAD, std::numeric_limits<int>::max())), pos++ ) );
+#else
     trCosts.push_back( TrCost( int(sumAbs*scaleSAD), pos++ ) );
+#endif
     it++;
   }
 
diff --git a/source/Lib/CommonLib/TrQuant_EMT.cpp b/source/Lib/CommonLib/TrQuant_EMT.cpp
index 82e34f176f..34918f6b20 100644
--- a/source/Lib/CommonLib/TrQuant_EMT.cpp
+++ b/source/Lib/CommonLib/TrQuant_EMT.cpp
@@ -91,7 +91,11 @@ void fastInverseDCT2_B2(const TCoeff *src, TCoeff *dst, int shift, int line, int
   int j;
 #if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT
   TCoeff E, O;
+#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS
+  TCoeff add = TCoeff(1) << (shift - 1);
+#else
   TCoeff add = 1 << (shift - 1);
+#endif
 #else
   int E, O;
   int add = 1 << (shift - 1);
@@ -192,7 +196,11 @@ void fastInverseDCT2_B4( const TCoeff *src, TCoeff *dst, int shift, int line, in
   int j;
 #if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT
   TCoeff E[2], O[2];
+#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS
+  TCoeff add = TCoeff(1) << ( shift - 1 );
+#else
   TCoeff add = 1 << ( shift - 1 );
+#endif
 #else
   int E[2], O[2];
   int add = 1 << ( shift - 1 );
@@ -236,7 +244,11 @@ template< int uiTrSize >
 inline void _fastInverseMM( const TCoeff *src, TCoeff *dst, int shift, int line, int iSkipLine, int iSkipLine2, const TCoeff outputMinimum, const TCoeff outputMaximum, const TMatrixCoeff* iT )
 {
 #if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT
+#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS
+  const TCoeff rnd_factor = TCoeff(1) << (shift - 1);
+#else
   const TCoeff rnd_factor = 1 << (shift - 1);
+#endif
 #else
   const int  rnd_factor  = 1 << (shift - 1);
 #endif
@@ -275,7 +287,11 @@ template< int uiTrSize >
 inline void _fastForwardMM( const TCoeff *src, TCoeff *dst, int shift, int line, int iSkipLine, int iSkipLine2, const TMatrixCoeff* tc )
 {
 #if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT
+#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS
+  const TCoeff rnd_factor = TCoeff(1) << (shift - 1);
+#else
   const TCoeff rnd_factor = 1 << (shift - 1);
+#endif
 #else
   const int  rnd_factor  = 1 << (shift - 1);
 #endif
@@ -393,7 +409,11 @@ void fastInverseDCT2_B8(const TCoeff *src, TCoeff *dst, int shift, int line, int
 #if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT
   TCoeff E[4], O[4];
   TCoeff EE[2], EO[2];
+#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS
+  TCoeff add = TCoeff(1) << (shift - 1);
+#else
   TCoeff add = 1 << (shift - 1);
+#endif
 #else
   int E[4], O[4];
   int EE[2], EO[2];
@@ -526,7 +546,11 @@ void fastInverseDCT2_B16( const TCoeff *src, TCoeff *dst, int shift, int line, i
   TCoeff E  [8], O  [8];
   TCoeff EE [4], EO [4];
   TCoeff EEE[2], EEO[2];
+#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS
+  TCoeff add = TCoeff(1) << ( shift - 1 );
+#else
   TCoeff add = 1 << ( shift - 1 );
+#endif
 #else
   int E  [8], O  [8];
   int EE [4], EO [4];
@@ -682,7 +706,11 @@ void fastInverseDCT2_B32(const TCoeff *src, TCoeff *dst, int shift, int line, in
   TCoeff EE[8], EO[8];
   TCoeff EEE[4], EEO[4];
   TCoeff EEEE[2], EEEO[2];
+#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS
+  TCoeff add = TCoeff(1) << (shift - 1);
+#else
   TCoeff add = 1 << (shift - 1);
+#endif
 #else
   int j, k;
   int E[16], O[16];
diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h
index 46013e69b6..b628b1c33b 100644
--- a/source/Lib/CommonLib/TypeDef.h
+++ b/source/Lib/CommonLib/TypeDef.h
@@ -111,6 +111,7 @@
 #define JVET_S0257_DUMP_360SEI_MESSAGE                    1 // Software support of 360 SEI messages
 
 #define JVET_R0351_HIGH_BIT_DEPTH_SUPPORT                 1 // JVET-R0351: high bit depth coding support (syntax changes, no mathematical differences for CTCs)
+#define JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS              1 // JVET-R0351: high bit depth coding support (syntax changes for Visual Studio)
 #define JVET_R0351_HIGH_BIT_DEPTH_ENABLED                 0 // JVET-R0351: high bit depth coding enabled (increases accuracies of some calculations, e.g. transforms)
 
 #define JVET_R0164_MEAN_SCALED_SATD                       1 // JVET-R0164: Use a mean scaled version of SATD in encoder decisions
diff --git a/source/Lib/DecoderLib/CABACReader.cpp b/source/Lib/DecoderLib/CABACReader.cpp
index 6d47ead0c9..695c4c4c04 100644
--- a/source/Lib/DecoderLib/CABACReader.cpp
+++ b/source/Lib/DecoderLib/CABACReader.cpp
@@ -1895,7 +1895,11 @@ void CABACReader::cuPaletteSubblockInfo(CodingUnit& cu, ComponentID compBegin, u
           if (compID == COMPONENT_Y || compBegin != COMPONENT_Y)
           {
             escapeValue.at(posx, posy) = exp_golomb_eqprob(5);
+#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS
+            assert(escapeValue.at(posx, posy) < (TCoeff(1) << (cu.cs->sps->getBitDepth(toChannelType((ComponentID)comp)) + 1)));
+#else
             assert(escapeValue.at(posx, posy) < (1 << (cu.cs->sps->getBitDepth(toChannelType((ComponentID)comp)) + 1)));
+#endif
             DTRACE(g_trace_ctx, D_SYNTAX, "plt_escape_val() value=%d etype=%d sp=%d\n", escapeValue.at(posx, posy), comp, curPos);
           }
           if (compBegin == COMPONENT_Y && compID != COMPONENT_Y && posy % (1 << scaleY) == 0 && posx % (1 << scaleX) == 0)
@@ -1903,7 +1907,11 @@ void CABACReader::cuPaletteSubblockInfo(CodingUnit& cu, ComponentID compBegin, u
             uint32_t posxC = posx >> scaleX;
             uint32_t posyC = posy >> scaleY;
             escapeValue.at(posxC, posyC) = exp_golomb_eqprob(5);
+#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS
+            assert(escapeValue.at(posxC, posyC) < (TCoeff(1) << (cu.cs->sps->getBitDepth(toChannelType(compID)) + 1)));
+#else
             assert(escapeValue.at(posxC, posyC) < (1 << (cu.cs->sps->getBitDepth(toChannelType(compID)) + 1)));
+#endif
             DTRACE(g_trace_ctx, D_SYNTAX, "plt_escape_val() value=%d etype=%d sp=%d\n", escapeValue.at(posx, posy), comp, curPos);
           }
       }
@@ -3328,10 +3336,18 @@ void CABACReader::residual_coding_subblock( CoeffCodingContext& cctx, TCoeff* co
   unsigned        signPattern = m_BinDecoder.decodeBinsEP( numSigns ) << ( 32 - numSigns );
 
   //===== set final coefficents =====
+#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS
+  TCoeff sumAbs = 0;
+#else
   int sumAbs = 0;
+#endif
   for( unsigned k = 0; k < numSigns; k++ )
   {
+#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS
+    TCoeff AbsCoeff       = coeff[ sigBlkPos[ k ] ];
+#else
     int AbsCoeff          = coeff[ sigBlkPos[ k ] ];
+#endif
     sumAbs               += AbsCoeff;
     coeff[ sigBlkPos[k] ] = ( signPattern & ( 1u << 31 ) ? -AbsCoeff : AbsCoeff );
     signPattern         <<= 1;
@@ -3344,7 +3360,11 @@ void CABACReader::residual_coding_subblock( CoeffCodingContext& cctx, TCoeff* co
   if( numNonZero > numSigns )
   {
     int k                 = numSigns;
+#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS
+    TCoeff AbsCoeff       = coeff[ sigBlkPos[ k ] ];
+#else
     int AbsCoeff          = coeff[ sigBlkPos[ k ] ];
+#endif
     sumAbs               += AbsCoeff;
     coeff[ sigBlkPos[k] ] = ( sumAbs & 1 ? -AbsCoeff : AbsCoeff );
 #if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT
@@ -3543,7 +3563,11 @@ void CABACReader::residual_coding_subblockTS( CoeffCodingContext& cctx, TCoeff*
   //===== set final coefficents =====
   for( unsigned k = 0; k < numNonZero; k++ )
   {
+#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS
+    TCoeff AbsCoeff       = coeff[ sigBlkPos[ k ] ];
+#else
     int AbsCoeff          = coeff[ sigBlkPos[ k ] ];
+#endif
     coeff[ sigBlkPos[k] ] = ( signPattern & 1 ? -AbsCoeff : AbsCoeff );
     signPattern         >>= 1;
 #if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT
diff --git a/source/Lib/DecoderLib/DecCu.cpp b/source/Lib/DecoderLib/DecCu.cpp
index af5e10d626..7f73d66b7d 100644
--- a/source/Lib/DecoderLib/DecCu.cpp
+++ b/source/Lib/DecoderLib/DecCu.cpp
@@ -536,7 +536,11 @@ void DecCu::xReconPLT(CodingUnit &cu, ComponentID compBegin, uint32_t numComp)
         PLTescapeBuf escapeValue = tu.getescapeValue((ComponentID)compID);
         if (curPLTIdx.at(x, y) == cu.curPLTSize[compBegin])
         {
+#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS
+          TCoeff value;
+#else
           Pel value;
+#endif
           QpParam cQP(tu, (ComponentID)compID);
           int qp = cQP.Qp(true);
           int qpRem = qp % 6;
@@ -546,8 +550,13 @@ void DecCu::xReconPLT(CodingUnit &cu, ComponentID compBegin, uint32_t numComp)
             int invquantiserRightShift = IQUANT_SHIFT;
             int add = 1 << (invquantiserRightShift - 1);
             value = ((((escapeValue.at(x, y)*g_invQuantScales[0][qpRem]) << qpPer) + add) >> invquantiserRightShift);
+#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS
+            value = ClipBD<TCoeff>(value, channelBitDepth);
+            picReco.at(x, y) = Pel(value);
+#else
             value = Pel(ClipBD<int>(value, channelBitDepth));
             picReco.at(x, y) = value;
+#endif
           }
           else if (compBegin == COMPONENT_Y && compID != COMPONENT_Y && y % (1 << scaleY) == 0 && x % (1 << scaleX) == 0)
           {
@@ -556,8 +565,13 @@ void DecCu::xReconPLT(CodingUnit &cu, ComponentID compBegin, uint32_t numComp)
             int invquantiserRightShift = IQUANT_SHIFT;
             int add = 1 << (invquantiserRightShift - 1);
             value = ((((escapeValue.at(posXC, posYC)*g_invQuantScales[0][qpRem]) << qpPer) + add) >> invquantiserRightShift);
+#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS
+            value = ClipBD<TCoeff>(value, channelBitDepth);
+            picReco.at(posXC, posYC) = Pel(value);
+#else
             value = Pel(ClipBD<int>(value, channelBitDepth));
             picReco.at(posXC, posYC) = value;
+#endif
 
           }
         }
diff --git a/source/Lib/EncoderLib/CABACWriter.cpp b/source/Lib/EncoderLib/CABACWriter.cpp
index 89bd9e2798..6a048b0d7e 100644
--- a/source/Lib/EncoderLib/CABACWriter.cpp
+++ b/source/Lib/EncoderLib/CABACWriter.cpp
@@ -2944,7 +2944,11 @@ void CABACWriter::residual_coding_subblock( CoeffCodingContext& cctx, const TCoe
   const int inferSigPos   = nextSigPos != cctx.scanPosLast() ? ( cctx.isNotFirst() ? minSubPos : -1 ) : nextSigPos;
   int       firstNZPos    = nextSigPos;
   int       lastNZPos     = -1;
+#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS
+  TCoeff    remAbsLevel   = -1;
+#else
   int       remAbsLevel   = -1;
+#endif
   int       numNonZero    =  0;
   unsigned  signPattern   =  0;
   int       remRegBins    = cctx.regBinLimit;
@@ -3010,7 +3014,11 @@ void CABACWriter::residual_coding_subblock( CoeffCodingContext& cctx, const TCoe
   {
     int       sumAll = cctx.templateAbsSum(scanPos, coeff, 4);
     ricePar = g_auiGoRiceParsCoeff[sumAll];
+#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS
+    unsigned absLevel = (unsigned) abs( coeff[ cctx.blockPos( scanPos ) ] );
+#else
     unsigned absLevel = abs( coeff[ cctx.blockPos( scanPos ) ] );
+#endif
     if( absLevel >= 4 )
     {
       unsigned rem      = ( absLevel - 4 ) >> 1;
@@ -3023,7 +3031,11 @@ void CABACWriter::residual_coding_subblock( CoeffCodingContext& cctx, const TCoe
   for( int scanPos = firstPosMode2; scanPos >= minSubPos; scanPos-- )
   {
     TCoeff    Coeff     = coeff[ cctx.blockPos( scanPos ) ];
+#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS
+    unsigned    absLevel  = (unsigned) abs( Coeff );
+#else
     unsigned  absLevel  = abs( Coeff );
+#endif
     int       sumAll = cctx.templateAbsSum(scanPos, coeff, 0);
     int       rice      = g_auiGoRiceParsCoeff                        [sumAll];
     int       pos0      = g_auiGoRicePosCoeff0(state, rice);
diff --git a/source/Lib/EncoderLib/IntraSearch.cpp b/source/Lib/EncoderLib/IntraSearch.cpp
index 4e7eb096f3..1d591be142 100644
--- a/source/Lib/EncoderLib/IntraSearch.cpp
+++ b/source/Lib/EncoderLib/IntraSearch.cpp
@@ -2323,14 +2323,25 @@ void IntraSearch::calcPixelPred(CodingStructure& cs, Partitioner& partitioner, u
       if (lossless)
       {
         escapeValue.at(xPos, yPos) = orgBuf[ch].at(xPos, yPos);
+#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS
+        recBuf.at(xPos, yPos)      = orgBuf[ch].at(xPos, yPos);
+#else
         recBuf.at(xPos, yPos)      = escapeValue.at(xPos, yPos);
+#endif
       }
       else
       {
+#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS
+      escapeValue.at(xPos, yPos) = std::max<TCoeff>(0, ((orgBuf[ch].at(xPos, yPos) * quantiserScale[ch] + rightShiftOffset[ch]) >> quantiserRightShift[ch]));
+      assert(escapeValue.at(xPos, yPos) < (TCoeff(1) << (channelBitDepth + 1)));
+      TCoeff value = (((escapeValue.at(xPos, yPos)*g_invQuantScales[0][qpRem[ch]]) << qpPer[ch]) + add[ch]) >> invquantiserRightShift[ch];
+      recBuf.at(xPos, yPos) = Pel(ClipBD<TCoeff>(value, channelBitDepth));//to be checked
+#else
       escapeValue.at(xPos, yPos) = TCoeff(std::max<int>(0, ((orgBuf[ch].at(xPos, yPos) * quantiserScale[ch] + rightShiftOffset[ch]) >> quantiserRightShift[ch])));
       assert(escapeValue.at(xPos, yPos) < (1 << (channelBitDepth + 1)));
       recBuf.at(xPos, yPos) = (((escapeValue.at(xPos, yPos)*g_invQuantScales[0][qpRem[ch]]) << qpPer[ch]) + add[ch]) >> invquantiserRightShift[ch];
       recBuf.at(xPos, yPos) = Pel(ClipBD<int>(recBuf.at(xPos, yPos), channelBitDepth));//to be checked
+#endif
       }
     }
     else if (compBegin == COMPONENT_Y && ch > 0 && yPos % (1 << scaleY) == 0 && xPos % (1 << scaleX) == 0)
@@ -2340,14 +2351,25 @@ void IntraSearch::calcPixelPred(CodingStructure& cs, Partitioner& partitioner, u
       if (lossless)
       {
         escapeValue.at(xPosC, yPosC) = orgBuf[ch].at(xPosC, yPosC);
+#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS
+        recBuf.at(xPosC, yPosC)      = orgBuf[ch].at(xPosC, yPosC);
+#else
         recBuf.at(xPosC, yPosC)      = escapeValue.at(xPosC, yPosC);
+#endif
       }
       else
       {
+#if JVET_R0351_HIGH_BIT_DEPTH_SUPPORT_VS
+      escapeValue.at(xPosC, yPosC) = std::max<TCoeff>(0, ((orgBuf[ch].at(xPosC, yPosC) * quantiserScale[ch] + rightShiftOffset[ch]) >> quantiserRightShift[ch]));
+      assert(escapeValue.at(xPosC, yPosC) < (TCoeff(1) << (channelBitDepth + 1)));
+      TCoeff value = (((escapeValue.at(xPosC, yPosC)*g_invQuantScales[0][qpRem[ch]]) << qpPer[ch]) + add[ch]) >> invquantiserRightShift[ch];
+      recBuf.at(xPosC, yPosC) = Pel(ClipBD<TCoeff>(value, channelBitDepth));//to be checked
+#else
       escapeValue.at(xPosC, yPosC) = TCoeff(std::max<int>(0, ((orgBuf[ch].at(xPosC, yPosC) * quantiserScale[ch] + rightShiftOffset[ch]) >> quantiserRightShift[ch])));
       assert(escapeValue.at(xPosC, yPosC) < (1 << (channelBitDepth + 1)));
       recBuf.at(xPosC, yPosC) = (((escapeValue.at(xPosC, yPosC)*g_invQuantScales[0][qpRem[ch]]) << qpPer[ch]) + add[ch]) >> invquantiserRightShift[ch];
       recBuf.at(xPosC, yPosC) = Pel(ClipBD<int>(recBuf.at(xPosC, yPosC), channelBitDepth));//to be checked
+#endif
       }
     }
   }
-- 
GitLab