diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h
index 4b8af774bcf6baf3bcd01f0117e61543e6134d7a..b03001080d23a5cef156e2262a87e1aa6441ba67 100644
--- a/source/Lib/CommonLib/TypeDef.h
+++ b/source/Lib/CommonLib/TypeDef.h
@@ -69,6 +69,8 @@
 
 #define JVET_R0388_DBF_CLEANUP                            1 // JVET-R0388: Cleanups on deblocking signalling
 
+#define JVET_R0114_NEGATIVE_SCALING_WINDOW_OFFSETS        1 // JVET-R0114: Allow negative scaling window offsets
+
 #define JVET_R0071_SPS_PPS_CELANUP                        1 // JVET-R0071 item 2-4: cleanups on subpicture signalling (item 1 has been ported in JVET_R0156_ASPECT4)
 
 #define JVET_R0271_SLICE_LEVEL_DQ_SDH_RRC                 1 // JVET-R0271/R0155: Slice level DQ and SDH granularity for mixed lossy/lossless.
diff --git a/source/Lib/CommonLib/UnitTools.cpp b/source/Lib/CommonLib/UnitTools.cpp
index 114323451f14c5c5027abae10a2bb2181a69e3aa..444ff8b32792f2a02f88064bb05665a2f3ff07b7 100644
--- a/source/Lib/CommonLib/UnitTools.cpp
+++ b/source/Lib/CommonLib/UnitTools.cpp
@@ -127,6 +127,11 @@ bool CU::getRprScaling( const SPS* sps, const PPS* curPPS, Picture* refPic, int&
   CHECK(curPicWidth > refPicWidth * 8, "curPicWidth shall be less than or equal to refPicWidth * 8");
   CHECK(curPicHeight > refPicHeight * 8, "curPicHeight shall be less than or equal to refPicHeight * 8");
 
+#if JVET_R0114_NEGATIVE_SCALING_WINDOW_OFFSETS
+  CHECK(SPS::getWinUnitX(sps->getChromaFormatIdc()) * (abs(curScalingWindow.getWindowLeftOffset()) + abs(curScalingWindow.getWindowRightOffset())) > curPPS->getPicWidthInLumaSamples(), "The value of SubWidthC * ( Abs(pps_scaling_win_left_offset) + Abs(pps_scaling_win_right_offset) ) shall be less than pic_width_in_luma_samples");
+  CHECK(SPS::getWinUnitY(sps->getChromaFormatIdc()) * (abs(curScalingWindow.getWindowTopOffset()) + abs(curScalingWindow.getWindowBottomOffset())) > curPPS->getPicHeightInLumaSamples(), "The value of SubHeightC * ( Abs(pps_scaling_win_top_offset) + Abs(pps_scaling_win_bottom_offset) ) shall be less than pic_height_in_luma_samples");
+#endif
+
   return refPic->isRefScaled( curPPS );
 }
 
diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp
index 550b5e23d61dc020cd9bae78ff5b59ba04b21ad8..8193a66945070203cdc902f63a9d79f31f30a5fc 100644
--- a/source/Lib/DecoderLib/VLCReader.cpp
+++ b/source/Lib/DecoderLib/VLCReader.cpp
@@ -452,10 +452,17 @@ void HLSyntaxReader::parsePPS( PPS* pcPPS )
   if( uiCode != 0 )
   {
     Window &scalingWindow = pcPPS->getScalingWindow();
+#if JVET_R0114_NEGATIVE_SCALING_WINDOW_OFFSETS
+    READ_SVLC( iCode, "pps_scaling_win_left_offset" );               scalingWindow.setWindowLeftOffset( iCode );
+    READ_SVLC( iCode, "pps_scaling_win_right_offset" );              scalingWindow.setWindowRightOffset( iCode );
+    READ_SVLC( iCode, "pps_scaling_win_top_offset" );                scalingWindow.setWindowTopOffset( iCode );
+    READ_SVLC( iCode, "pps_scaling_win_bottom_offset" );             scalingWindow.setWindowBottomOffset( iCode );
+#else
     READ_UVLC( uiCode, "scaling_win_left_offset" );               scalingWindow.setWindowLeftOffset( uiCode );
     READ_UVLC( uiCode, "scaling_win_right_offset" );              scalingWindow.setWindowRightOffset( uiCode );
     READ_UVLC( uiCode, "scaling_win_top_offset" );                scalingWindow.setWindowTopOffset( uiCode );
     READ_UVLC( uiCode, "scaling_win_bottom_offset" );             scalingWindow.setWindowBottomOffset( uiCode );
+#endif
   }
   else
   {
diff --git a/source/Lib/EncoderLib/VLCWriter.cpp b/source/Lib/EncoderLib/VLCWriter.cpp
index ab444f215fffec7ab3b41a70d21abce10ef68341..6a6cb98491fe9e0a1ee126cb9ccf2d6d1953c86c 100644
--- a/source/Lib/EncoderLib/VLCWriter.cpp
+++ b/source/Lib/EncoderLib/VLCWriter.cpp
@@ -277,10 +277,17 @@ void HLSWriter::codePPS( const PPS* pcPPS )
   WRITE_FLAG( scalingWindow.getWindowEnabledFlag(), "scaling_window_flag" );
   if( scalingWindow.getWindowEnabledFlag() )
   {
+#if JVET_R0114_NEGATIVE_SCALING_WINDOW_OFFSETS
+    WRITE_SVLC( scalingWindow.getWindowLeftOffset(), "pps_scaling_win_left_offset" );
+    WRITE_SVLC( scalingWindow.getWindowRightOffset(), "pps_scaling_win_right_offset" );
+    WRITE_SVLC( scalingWindow.getWindowTopOffset(), "pps_scaling_win_top_offset" );
+    WRITE_SVLC( scalingWindow.getWindowBottomOffset(), "pps_scaling_win_bottom_offset" );
+#else
     WRITE_UVLC( scalingWindow.getWindowLeftOffset(), "scaling_win_left_offset" );
     WRITE_UVLC( scalingWindow.getWindowRightOffset(), "scaling_win_right_offset" );
     WRITE_UVLC( scalingWindow.getWindowTopOffset(), "scaling_win_top_offset" );
     WRITE_UVLC( scalingWindow.getWindowBottomOffset(), "scaling_win_bottom_offset" );
+#endif
   }
 
   WRITE_FLAG( pcPPS->getOutputFlagPresentFlag() ? 1 : 0,     "output_flag_present_flag" );