From 73357bfb72f34e0cb9119f1bc87034f9b81dbc91 Mon Sep 17 00:00:00 2001
From: Julien Michel <julien.michel@orfeo-toolbox.org>
Date: Thu, 12 Sep 2019 07:24:15 +0000
Subject: [PATCH] TEST: Add a failing test to demonstrate issue 1963

---
 Modules/Core/Transform/test/CMakeLists.txt    |  2 +
 .../test/otbStreamingWarpImageFilter.cxx      | 92 +++++++++++++++++--
 .../Transform/test/otbTransformTestDriver.cxx |  1 +
 3 files changed, 86 insertions(+), 9 deletions(-)

diff --git a/Modules/Core/Transform/test/CMakeLists.txt b/Modules/Core/Transform/test/CMakeLists.txt
index dba05dea7f..5dadf55498 100644
--- a/Modules/Core/Transform/test/CMakeLists.txt
+++ b/Modules/Core/Transform/test/CMakeLists.txt
@@ -126,6 +126,8 @@ otb_add_test(NAME dmTvStreamingWarpImageFilter COMMAND otbTransformTestDriver
   5
   )
 
+otb_add_test(NAME dmTvStreamingWarpImageFilterEmtpyRegion COMMAND otbTransformTestDriver
+                  otbStreamingWarpImageFilterEmptyRegion)
 
 # Forward / Backward projection consistency checking
 set(FWDBWDChecking_INPUTS
diff --git a/Modules/Core/Transform/test/otbStreamingWarpImageFilter.cxx b/Modules/Core/Transform/test/otbStreamingWarpImageFilter.cxx
index dc089e7998..30aa78bcc1 100644
--- a/Modules/Core/Transform/test/otbStreamingWarpImageFilter.cxx
+++ b/Modules/Core/Transform/test/otbStreamingWarpImageFilter.cxx
@@ -25,6 +25,17 @@
 #include "otbImageFileWriter.h"
 #include "otbStreamingWarpImageFilter.h"
 
+// Images definition
+const unsigned int Dimension = 2;
+typedef double                                      PixelType;
+typedef otb::Image<PixelType, Dimension>            ImageType;
+typedef itk::Vector<PixelType, 2>                   DisplacementValueType;
+typedef otb::Image<DisplacementValueType, Dimension> DisplacementFieldType;
+
+  // Warper
+  typedef otb::StreamingWarpImageFilter<ImageType, ImageType, DisplacementFieldType> ImageWarperType;
+
+
 int otbStreamingWarpImageFilter(int argc, char* argv[])
 {
   if (argc != 5)
@@ -39,20 +50,11 @@ int otbStreamingWarpImageFilter(int argc, char* argv[])
   const char * outfname = argv[3];
   const double maxdef = atoi(argv[4]);
 
-  // Images definition
-  const unsigned int Dimension = 2;
-  typedef double                                      PixelType;
-  typedef otb::Image<PixelType, Dimension>            ImageType;
-  typedef itk::Vector<PixelType, 2>                   DisplacementValueType;
-  typedef otb::Image<DisplacementValueType, Dimension> DisplacementFieldType;
 
   // Change default output origin
   ImageType::PointType origin;
   origin.Fill(0.5);
 
-  // Warper
-  typedef otb::StreamingWarpImageFilter<ImageType, ImageType, DisplacementFieldType> ImageWarperType;
-
   // Reader/Writer
   typedef otb::ImageFileReader<ImageType>            ReaderType;
   typedef otb::ImageFileReader<DisplacementFieldType> DisplacementReaderType;
@@ -83,3 +85,75 @@ int otbStreamingWarpImageFilter(int argc, char* argv[])
 
   return EXIT_SUCCESS;
 }
+
+int otbStreamingWarpImageFilterEmptyRegion(int, char**)
+{
+  ImageType:: Pointer inputPtr = ImageType::New();
+
+  ImageType::RegionType largestRegion;
+  ImageType::SizeType largestSize = {{10,10}};
+  ImageType::IndexType largestIndex = {{1,1}};
+  
+  largestRegion.SetIndex(largestIndex);
+  largestRegion.SetSize(largestSize);
+
+  inputPtr->SetRegions(largestRegion);
+
+  ImageType::RegionType emptyRegion;
+  ImageType::SizeType emptySize = {{0,0}};
+  ImageType::IndexType emptyIndex = {{0,0}};
+  emptyRegion.SetSize(emptySize);
+  emptyRegion.SetIndex(emptyIndex);
+
+  inputPtr->SetRequestedRegion(emptyRegion);
+  inputPtr->SetBufferedRegion(emptyRegion);
+
+  DisplacementFieldType::Pointer dispPtr = DisplacementFieldType::New();
+  dispPtr->SetRegions(largestRegion);
+  dispPtr->Allocate();
+  
+  DisplacementValueType v;
+  v[0]=-100;
+  v[1]=-100;
+  dispPtr->FillBuffer(v);
+
+  ImageWarperType::Pointer warper = ImageWarperType::New();
+
+  warper->SetDisplacementField(dispPtr);
+  warper->SetInput(inputPtr);
+
+  ImageType::PointType outputOrigin;
+  outputOrigin.Fill(0);
+  warper->SetOutputOrigin(outputOrigin);
+
+  // requested region for full output is completely outside largest
+  // possible region of input
+  warper->GetOutput()->UpdateOutputInformation();
+
+  // Before bugfix this would lead to famous ITK exception outside of
+  // largest possible region
+  warper->GetOutput()->PropagateRequestedRegion();
+
+  // After requested region has been propagated, we need to be sure
+  // that requested region can be cropped by largest region
+  auto requestedRegion = inputPtr->GetRequestedRegion();
+
+  std::cout<<requestedRegion<<std::endl;
+  std::cout<<inputPtr->GetLargestPossibleRegion()<<std::endl;
+
+  if (! requestedRegion.Crop(inputPtr->GetLargestPossibleRegion()) )
+    {
+    std::cerr<<"Requested region can not be cropped by largest region"<<std::endl;
+    return EXIT_FAILURE;
+    }
+  
+  // And we also need to check that requested region is not largest
+  // region
+  if( inputPtr->GetRequestedRegion().GetNumberOfPixels() != 0)
+    {
+    std::cerr<<"Requested region should have {{0, 0}} size"<<std::endl;
+    return EXIT_FAILURE;
+    }
+    
+  return EXIT_SUCCESS;
+}
diff --git a/Modules/Core/Transform/test/otbTransformTestDriver.cxx b/Modules/Core/Transform/test/otbTransformTestDriver.cxx
index 484f563d6f..7ec077d492 100644
--- a/Modules/Core/Transform/test/otbTransformTestDriver.cxx
+++ b/Modules/Core/Transform/test/otbTransformTestDriver.cxx
@@ -31,6 +31,7 @@ void RegisterTests()
   REGISTER_TEST(otbCreateProjectionWithOTB);
   REGISTER_TEST(otbGenericMapProjection);
   REGISTER_TEST(otbStreamingWarpImageFilter);
+  REGISTER_TEST(otbStreamingWarpImageFilterEmptyRegion);
   REGISTER_TEST(otbInverseLogPolarTransform);
   REGISTER_TEST(otbInverseLogPolarTransformResample);
   REGISTER_TEST(otbStreamingResampleImageFilterWithAffineTransform);
-- 
GitLab