diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp
index 7f40bc0665b59f4b7a77c9263995244be772ddad..f029e34f868addd75ce561bb5ce3b24e306f71a9 100644
--- a/source/App/EncoderApp/EncAppCfg.cpp
+++ b/source/App/EncoderApp/EncAppCfg.cpp
@@ -1959,7 +1959,19 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
   }
 #endif
 
-
+  if (m_chromaFormatIDC != CHROMA_420)
+  {
+    if (!m_horCollocatedChromaFlag)
+    {
+      msg(WARNING, "\nWARNING: HorCollocatedChroma is forced to 1 for chroma formats other than 4:2:0\n");
+      m_horCollocatedChromaFlag = true;
+    }
+    if (!m_verCollocatedChromaFlag)
+    {
+      msg(WARNING, "\nWARNING: VerCollocatedChroma is forced to 1 for chroma formats other than 4:2:0\n");
+      m_verCollocatedChromaFlag = true;
+    }
+  }
 #if JVET_O0756_CONFIG_HDRMETRICS && !JVET_O0756_CALCULATE_HDRMETRICS
   if ( m_calculateHdrMetrics == true)
   {
diff --git a/source/Lib/CommonLib/IntraPrediction.cpp b/source/Lib/CommonLib/IntraPrediction.cpp
index 3a24c156f18d8b2ccbc9da9a142281277bbe5a07..1b148e41e9a2fab085284a5bf5ebf042ca27a8af 100644
--- a/source/Lib/CommonLib/IntraPrediction.cpp
+++ b/source/Lib/CommonLib/IntraPrediction.cpp
@@ -1350,7 +1350,6 @@ void IntraPrediction::xGetLumaRecPixels(const PredictionUnit &pu, CompArea chrom
   int logSubHeightC = getChannelTypeScaleY(CHANNEL_TYPE_CHROMA, pu.chromaFormat);
 
   int iRecStride2       = iRecStride << logSubHeightC;
-  const int mult        =          1 << logSubWidthC ;
 
   const CodingUnit& lumaCU = isChroma( pu.chType ) ? *pu.cs->picture->cs->getCU( lumaArea.pos(), CH_L ) : *pu.cu;
   const CodingUnit&     cu = *pu.cu;
@@ -1385,24 +1384,24 @@ void IntraPrediction::xGetLumaRecPixels(const PredictionUnit &pu, CompArea chrom
   int avaiLeftBelowUnits = 0;
   bool  bNeighborFlags[4 * MAX_NUM_PART_IDXS_IN_CTU_WIDTH + 1];
   memset(bNeighborFlags, 0, totalUnits);
-  bool bAboveAvaillable, bLeftAvaillable;
+  bool aboveIsAvailable, leftIsAvailable;
 
   int availlableUnit = isLeftAvailable( isChroma( pu.chType ) ? cu : lumaCU, toChannelType( area.compID ), area.pos(), iLeftUnits, iUnitHeight,
   ( bNeighborFlags + iLeftUnits + leftBelowUnits - 1 ) );
 
-  bLeftAvaillable = availlableUnit == iTUHeightInUnits;
+  leftIsAvailable = availlableUnit == iTUHeightInUnits;
 
   availlableUnit = isAboveAvailable( isChroma( pu.chType ) ? cu : lumaCU, toChannelType( area.compID ), area.pos(), iAboveUnits, iUnitWidth,
   ( bNeighborFlags + iLeftUnits + leftBelowUnits + 1 ) );
 
-  bAboveAvaillable = availlableUnit == iTUWidthInUnits;
+  aboveIsAvailable = availlableUnit == iTUWidthInUnits;
 
-  if (bLeftAvaillable) // if left is not available, then the below left is not available
+  if (leftIsAvailable)   // if left is not available, then the below left is not available
   {
     avaiLeftBelowUnits = isBelowLeftAvailable(isChroma(pu.chType) ? cu : lumaCU, toChannelType(area.compID), area.bottomLeftComp(area.compID), leftBelowUnits, iUnitHeight, (bNeighborFlags + leftBelowUnits - 1));
   }
 
-  if (bAboveAvaillable) // if above is not available, then  the above right is not available.
+  if (aboveIsAvailable)   // if above is not available, then  the above right is not available.
   {
     avaiAboveRightUnits = isAboveRightAvailable(isChroma(pu.chType) ? cu : lumaCU, toChannelType(area.compID), area.topRightComp(area.compID), aboveRightUnits, iUnitWidth, (bNeighborFlags + iLeftUnits + leftBelowUnits + iAboveUnits + 1));
   }
@@ -1410,31 +1409,9 @@ void IntraPrediction::xGetLumaRecPixels(const PredictionUnit &pu, CompArea chrom
   Pel*       pDst  = nullptr;
   Pel const* piSrc = nullptr;
 
-  bool isFirstRowOfCtu = ( lumaArea.y & ((pu.cs->sps)->getCTUSize() - 1) ) == 0;
-  const int strOffset = (CHROMA_444 == pu.chromaFormat) ? 0 : iRecStride;
-  int c0_3tap = 2, c1_3tap = 1, c2_3tap = 1,                                        offset_3tap = 2, shift_3tap = 2; //sum = 4
-  int c0_5tap = 1, c1_5tap = 4, c2_5tap = 1, c3_5tap = 1, c4_5tap = 1,              offset_5tap = 4, shift_5tap = 3; //sum = 8
-  int c0_6tap = 2, c1_6tap = 1, c2_6tap = 1, c3_6tap = 2, c4_6tap = 1, c5_6tap = 1, offset_6tap = 4, shift_6tap = 3; //sum = 8
+  bool isFirstRowOfCtu = (lumaArea.y & ((pu.cs->sps)->getCTUSize() - 1)) == 0;
 
-  switch (pu.chromaFormat)
-  {
-    case CHROMA_422: //overwrite filter coefficient values for 422
-      c0_3tap = 2, c1_3tap = 1, c2_3tap = 1,                                        offset_3tap = 2, shift_3tap = 2; //sum = 4
-      c0_5tap = 0, c1_5tap = 1, c2_5tap = 0, c3_5tap = 0, c4_5tap = 0,              offset_5tap = 0, shift_5tap = 0; //sum = 1
-      c0_6tap = 2, c1_6tap = 1, c2_6tap = 1, c3_6tap = 0, c4_6tap = 0, c5_6tap = 0, offset_6tap = 2, shift_6tap = 2; //sum = 4
-      break;
-
-    case CHROMA_444:  //overwrite filter coefficient values for 422
-      c0_3tap = 1, c1_3tap = 0, c2_3tap = 0,                                        offset_3tap = 0, shift_3tap = 0; //sum = 1
-      c0_5tap = 0, c1_5tap = 1, c2_5tap = 0, c3_5tap = 0, c4_5tap = 0,              offset_5tap = 0, shift_5tap = 0; //sum = 1
-      c0_6tap = 1, c1_6tap = 0, c2_6tap = 0, c3_6tap = 0, c4_6tap = 0, c5_6tap = 0, offset_6tap = 0, shift_6tap = 0; //sum = 1
-      break;
-
-    default:
-      break;
-  }
-
-  if( bAboveAvaillable )
+  if (aboveIsAvailable)
   {
     pDst  = pDst0    - iDstStride;
     int addedAboveRight = 0;
@@ -1444,63 +1421,58 @@ void IntraPrediction::xGetLumaRecPixels(const PredictionUnit &pu, CompArea chrom
     }
     for (int i = 0; i < uiCWidth + addedAboveRight; i++)
     {
-      if (isFirstRowOfCtu)
+      const bool leftPadding = i == 0 && !leftIsAvailable;
+      if (pu.chromaFormat == CHROMA_444)
       {
         piSrc = pRecSrc0 - iRecStride;
+        pDst[i] = piSrc[i];
+      }
+      else if (isFirstRowOfCtu)
+      {
+        piSrc   = pRecSrc0 - iRecStride;
+        pDst[i] = (piSrc[2 * i] * 2 + piSrc[2 * i - (leftPadding ? 0 : 1)] + piSrc[2 * i + 1] + 2) >> 2;
+      }
+      else if (pu.chromaFormat == CHROMA_422)
+      {
+        piSrc = pRecSrc0 - iRecStride2;
 
-        if ((i == 0 && !bLeftAvaillable) || (i == uiCWidth + addedAboveRight - 1 + logSubWidthC))
-        {
-          pDst[i] = (piSrc[mult * i] * c0_3tap + piSrc[mult * i] * c1_3tap + piSrc[mult * i + 1] * c2_3tap + offset_3tap) >> shift_3tap;
-        }
-        else
-        {
-          pDst[i] = (piSrc[mult * i] * c0_3tap + piSrc[mult * i - 1] * c1_3tap + piSrc[mult * i + 1] * c2_3tap + offset_3tap) >> shift_3tap;
-        }
+        int s = 2;
+        s += piSrc[2 * i] * 2;
+        s += piSrc[2 * i - (leftPadding ? 0 : 1)];
+        s += piSrc[2 * i + 1];
+        pDst[i] = s >> 2;
       }
-      else if( pu.cs->sps->getCclmCollocatedChromaFlag() )
+      else if (pu.cs->sps->getCclmCollocatedChromaFlag())
       {
         piSrc = pRecSrc0 - iRecStride2;
 
-        if ((i == 0 && !bLeftAvaillable) || (i == uiCWidth + addedAboveRight - 1 + logSubWidthC))
-        {
-          pDst[i] = (piSrc[mult * i - strOffset] * c0_5tap
-                  +  piSrc[mult * i]             * c1_5tap + piSrc[mult * i] * c2_5tap + piSrc[mult * i + 1] * c3_5tap
-                  +  piSrc[mult * i + strOffset] * c4_5tap
-                  +  offset_5tap) >> shift_5tap;
-        }
-        else
-        {
-          pDst[i] = (piSrc[mult * i - strOffset] * c0_5tap
-                  +  piSrc[mult * i]             * c1_5tap + piSrc[mult * i - 1] * c2_5tap + piSrc[mult * i + 1] * c3_5tap
-                  +  piSrc[mult * i + strOffset] * c4_5tap
-                  +  offset_5tap) >> shift_5tap;
-        }
+        int s = 4;
+        s += piSrc[2 * i - iRecStride];
+        s += piSrc[2 * i] * 4;
+        s += piSrc[2 * i - (leftPadding ? 0 : 1)];
+        s += piSrc[2 * i + 1];
+        s += piSrc[2 * i + iRecStride];
+        pDst[i] = s >> 3;
       }
       else
       {
         piSrc = pRecSrc0 - iRecStride2;
-
-        if ((i == 0 && !bLeftAvaillable) || (i == uiCWidth + addedAboveRight - 1 + logSubWidthC))
-        {
-          pDst[i] = ((piSrc[mult * i]            * c0_6tap + piSrc[mult * i]             * c1_6tap + piSrc[mult * i + 1]             * c2_6tap)
-                  + (piSrc[mult * i + strOffset] * c3_6tap + piSrc[mult * i + strOffset] * c4_6tap + piSrc[mult * i + 1 + strOffset] * c5_6tap)
-                  + offset_6tap) >> shift_6tap;
-        }
-        else
-        {
-          pDst[i] = ((piSrc[mult * i]            * c0_6tap + piSrc[mult * i - 1]             * c1_6tap + piSrc[mult * i + 1]             * c2_6tap)
-                  + (piSrc[mult * i + strOffset] * c3_6tap + piSrc[mult * i - 1 + strOffset] * c4_6tap + piSrc[mult * i + 1 + strOffset] * c5_6tap)
-                  + offset_6tap) >> shift_6tap;
-        }
+        int s = 4;
+        s += piSrc[2 * i] * 2;
+        s += piSrc[2 * i + 1];
+        s += piSrc[2 * i - (leftPadding ? 0 : 1)];
+        s += piSrc[2 * i + iRecStride] * 2;
+        s += piSrc[2 * i + 1 + iRecStride];
+        s += piSrc[2 * i + iRecStride - (leftPadding ? 0 : 1)];
+        pDst[i] = s >> 3;
       }
     }
   }
 
-  if( bLeftAvaillable )
+  if (leftIsAvailable)
   {
     pDst  = pDst0    - 1;
-
-    piSrc = pRecSrc0 - 2 - logSubWidthC;
+    piSrc = pRecSrc0 - 1 - logSubWidthC;
 
     int addedLeftBelow = 0;
     if ((curChromaMode == MDLM_L_IDX) || (curChromaMode == MDLM_T_IDX))
@@ -1510,28 +1482,40 @@ void IntraPrediction::xGetLumaRecPixels(const PredictionUnit &pu, CompArea chrom
 
     for (int j = 0; j < uiCHeight + addedLeftBelow; j++)
     {
-      if( pu.cs->sps->getCclmCollocatedChromaFlag() )
+      if (pu.chromaFormat == CHROMA_444)
       {
-        if ((j == 0 && !bAboveAvaillable) || (j == uiCHeight + addedLeftBelow - 1 + logSubWidthC))
-        {
-          pDst[0] = ( piSrc[1            ] * c0_5tap
-                    + piSrc[1            ] * c1_5tap + piSrc[0] * c2_5tap + piSrc[2] * c3_5tap
-                    + piSrc[1 + strOffset] * c4_5tap
-                    + offset_5tap ) >> shift_5tap;
-        }
-        else
-        {
-          pDst[0] = ( piSrc[1 - strOffset] * c0_5tap
-                    + piSrc[1            ] * c1_5tap + piSrc[0] * c2_5tap + piSrc[2] * c3_5tap
-                    + piSrc[1 + strOffset] * c4_5tap
-                    + offset_5tap ) >> shift_5tap;
-        }
+        pDst[0] = piSrc[0];
+      }
+      else if (pu.chromaFormat == CHROMA_422)
+      {
+        int s = 2;
+        s += piSrc[0] * 2;
+        s += piSrc[-1];
+        s += piSrc[1];
+        pDst[0] = s >> 2;
+      }
+      else if (pu.cs->sps->getCclmCollocatedChromaFlag())
+      {
+        const bool abovePadding = j == 0 && !aboveIsAvailable;
+
+        int s = 4;
+        s += piSrc[-(abovePadding ? 0 : iRecStride)];
+        s += piSrc[0] * 4;
+        s += piSrc[-1];
+        s += piSrc[1];
+        s += piSrc[iRecStride];
+        pDst[0] = s >> 3;
       }
       else
       {
-        pDst[0] = ((piSrc[1]             * c0_6tap + piSrc[0]         * c1_6tap + piSrc[2]             * c2_6tap)
-                +  (piSrc[1 + strOffset] * c3_6tap + piSrc[strOffset] * c4_6tap + piSrc[2 + strOffset] * c5_6tap)
-                +   offset_6tap) >> shift_6tap;
+        int s = 4;
+        s += piSrc[0] * 2;
+        s += piSrc[1];
+        s += piSrc[-1];
+        s += piSrc[iRecStride] * 2;
+        s += piSrc[iRecStride + 1];
+        s += piSrc[iRecStride - 1];
+        pDst[0] = s >> 3;
       }
 
       piSrc += iRecStride2;
@@ -1544,71 +1528,46 @@ void IntraPrediction::xGetLumaRecPixels(const PredictionUnit &pu, CompArea chrom
   {
     for( int i = 0; i < uiCWidth; i++ )
     {
-      if( pu.cs->sps->getCclmCollocatedChromaFlag() )
+      if (pu.chromaFormat == CHROMA_444)
       {
-        if( i == 0 && !bLeftAvaillable )
-        {
-          if ( j == 0 && !bAboveAvaillable )
-          {
-            pDst0[i] = (pRecSrc0[mult * i] * c0_5tap
-                     +  pRecSrc0[mult * i] * c1_5tap + pRecSrc0[mult * i] * c2_5tap + pRecSrc0[mult * i + 1] * c3_5tap
-                     +  pRecSrc0[mult * i + strOffset] * c4_5tap
-                     +  offset_5tap) >> shift_5tap;
-          }
-          else
-          {
-            pDst0[i] = (pRecSrc0[mult * i - strOffset] * c0_5tap
-                     +  pRecSrc0[mult * i] * c1_5tap + pRecSrc0[mult * i] * c2_5tap + pRecSrc0[mult * i + 1] * c3_5tap
-                     +  pRecSrc0[mult * i + strOffset] * c4_5tap
-                     +  offset_5tap) >> shift_5tap;
-          }
-        }
-        else if ( j == 0 && !bAboveAvaillable )
-        {
-          pDst0[i] = (pRecSrc0[mult * i] * c0_5tap
-                   +  pRecSrc0[mult * i] * c1_5tap + pRecSrc0[mult * i - 1] * c2_5tap + pRecSrc0[mult * i + 1] * c3_5tap
-                   +  pRecSrc0[mult * i + strOffset] * c4_5tap
-                   +  offset_5tap) >> shift_5tap;
-        }
-        else
-        {
-          pDst0[i] = (pRecSrc0[mult * i - strOffset] * c0_5tap
-                   +  pRecSrc0[mult * i]             * c1_5tap + pRecSrc0[mult * i - 1] * c2_5tap + pRecSrc0[mult * i + 1] * c3_5tap
-                   +  pRecSrc0[mult * i + strOffset] * c4_5tap
-                   +  offset_5tap) >> shift_5tap;
-        }
+        pDst0[i] = pRecSrc0[i];
       }
-      else
+      else if (pu.chromaFormat == CHROMA_422)
       {
+        const bool leftPadding  = i == 0 && !leftIsAvailable;
 
-        if ((i == 0 && !bLeftAvaillable) || (i == uiCWidth - 1 + logSubWidthC))
-        {
-          int s = offset_6tap;
-          s += pRecSrc0[mult * i] * c0_6tap;
-          s += pRecSrc0[mult * i + 1] * c1_6tap;
-          s += pRecSrc0[mult * i] * c2_6tap;
-          if (pu.chromaFormat == CHROMA_420)
-          {
-            s += pRecSrc0[mult * i + strOffset] * c3_6tap;
-            s += pRecSrc0[mult * i + 1 + strOffset] * c4_6tap;
-            s += pRecSrc0[mult * i + strOffset] * c5_6tap;
-          }
-          pDst0[i] = s >> shift_6tap;
-        }
-        else
-        {
-          int s = offset_6tap;
-          s += pRecSrc0[mult * i] * c0_6tap;
-          s += pRecSrc0[mult * i + 1] * c1_6tap;
-          s += pRecSrc0[mult * i - 1] * c2_6tap;
-          if (pu.chromaFormat == CHROMA_420)
-          {
-            s += pRecSrc0[mult * i + strOffset] * c3_6tap;
-            s += pRecSrc0[mult * i + 1 + strOffset] * c4_6tap;
-            s += pRecSrc0[mult * i - 1 + strOffset] * c5_6tap;
-          }
-          pDst0[i] = s >> shift_6tap;
-        }
+        int s = 2;
+        s += pRecSrc0[2 * i] * 2;
+        s += pRecSrc0[2 * i - (leftPadding ? 0 : 1)];
+        s += pRecSrc0[2 * i + 1];
+        pDst0[i] = s >> 2;
+      }
+      else if (pu.cs->sps->getCclmCollocatedChromaFlag())
+      {
+        const bool leftPadding  = i == 0 && !leftIsAvailable;
+        const bool abovePadding = j == 0 && !aboveIsAvailable;
+
+        int s = 4;
+        s += pRecSrc0[2 * i - (abovePadding ? 0 : iRecStride)];
+        s += pRecSrc0[2 * i] * 4;
+        s += pRecSrc0[2 * i - (leftPadding ? 0 : 1)];
+        s += pRecSrc0[2 * i + 1];
+        s += pRecSrc0[2 * i + iRecStride];
+        pDst0[i] = s >> 3;
+      }
+      else
+      {
+        CHECK(pu.chromaFormat != CHROMA_420, "Chroma format must be 4:2:0 for vertical filtering");
+        const bool leftPadding = i == 0 && !leftIsAvailable;
+
+        int s = 4;
+        s += pRecSrc0[2 * i] * 2;
+        s += pRecSrc0[2 * i + 1];
+        s += pRecSrc0[2 * i - (leftPadding ? 0 : 1)];
+        s += pRecSrc0[2 * i + iRecStride] * 2;
+        s += pRecSrc0[2 * i + 1 + iRecStride];
+        s += pRecSrc0[2 * i + iRecStride - (leftPadding ? 0 : 1)];
+        pDst0[i] = s >> 3;
       }
     }
 
diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp
index 626a5500063fd62bc3c6a48ae5cf571b6b976687..875aab8e0479a5eae14d9352fad1908023781350 100644
--- a/source/Lib/DecoderLib/VLCReader.cpp
+++ b/source/Lib/DecoderLib/VLCReader.cpp
@@ -1807,6 +1807,11 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS)
     READ_FLAG( uiCode, "sps_chroma_horizontal_collocated_flag" );   pcSPS->setHorCollocatedChromaFlag( uiCode != 0 );
     READ_FLAG( uiCode, "sps_chroma_vertical_collocated_flag" );     pcSPS->setVerCollocatedChromaFlag( uiCode != 0 );
   }
+  else
+  {
+    pcSPS->setHorCollocatedChromaFlag(true);
+    pcSPS->setVerCollocatedChromaFlag(true);
+  }
 
   READ_FLAG( uiCode,    "sps_mts_enabled_flag" );                       pcSPS->setUseMTS                 ( uiCode != 0 );
   if ( pcSPS->getUseMTS() )
diff --git a/source/Lib/EncoderLib/VLCWriter.cpp b/source/Lib/EncoderLib/VLCWriter.cpp
index 468c2e737ae8f95227d1c7e3dc759bc374460e6e..4786fd0080224638244d8ad4a5bf7aeea9b939c3 100644
--- a/source/Lib/EncoderLib/VLCWriter.cpp
+++ b/source/Lib/EncoderLib/VLCWriter.cpp
@@ -1101,6 +1101,11 @@ void HLSWriter::codeSPS( const SPS* pcSPS )
     WRITE_FLAG( pcSPS->getHorCollocatedChromaFlag() ? 1 : 0, "sps_chroma_horizontal_collocated_flag" );
     WRITE_FLAG( pcSPS->getVerCollocatedChromaFlag() ? 1 : 0, "sps_chroma_vertical_collocated_flag" );
   }
+  else
+  {
+    CHECK(pcSPS->getHorCollocatedChromaFlag() != 1, "Invalid value for horizontal collocated chroma flag");
+    CHECK(pcSPS->getVerCollocatedChromaFlag() != 1, "Invalid value for vertical collocated chroma flag");
+  }
 
   WRITE_FLAG( pcSPS->getUseMTS() ? 1 : 0,                                                      "sps_mts_enabled_flag" );
   if ( pcSPS->getUseMTS() )