From 20b0e6dea1d286ff135ac5423337f54a732c6dd8 Mon Sep 17 00:00:00 2001 From: Niels Dekker Date: Mon, 10 Oct 2022 18:44:29 +0200 Subject: [PATCH] BUG: ImageIORegion::IsInside should return false for a zero-sized region This commit ensures that `ImageIORegion::IsInside` returns false whenever its argument is an `ImageIORegion` that contains no pixels at all. Following the adjustment of `itk::ImageRegion::IsInside(const Self &)` from pull request https://github.com/InsightSoftwareConsortium/ITK/pull/3110 commit 1295d239397f111bd008c1093d9ddc5a3867669a "BUG: `region.IsInside(zeroSizedRegion)` should always return false", which was included with ITK v5.3rc04 See also "What bool value should `imageRegion.IsInside(zeroSizedRegion)` return?" at https://discourse.itk.org/t/what-bool-value-should-imageregion-isinside-zerosizedregion-return/4734 --- Modules/Core/Common/src/itkImageIORegion.cxx | 27 ++++++++++--------- .../Common/test/itkImageIORegionGTest.cxx | 19 +++++++++++++ 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/Modules/Core/Common/src/itkImageIORegion.cxx b/Modules/Core/Common/src/itkImageIORegion.cxx index 8dddf9b9776..ee0eaddf1e9 100644 --- a/Modules/Core/Common/src/itkImageIORegion.cxx +++ b/Modules/Core/Common/src/itkImageIORegion.cxx @@ -190,25 +190,28 @@ ImageIORegion::IsInside(const IndexType & index) const return true; } -/** Test if a region (the argument) is completely inside of this region */ + +/** Test if a region (the argument) is completely inside of this region. If + * the region that is passed as argument has a size of value zero, or if the + * dimensionality is zero, then it will not be considered to be inside of the + * current region, even its starting index is inside. */ bool -ImageIORegion::IsInside(const Self & region) const +ImageIORegion::IsInside(const Self & otherRegion) const { - IndexType beginCorner = region.GetIndex(); - - if (!this->IsInside(beginCorner)) + if (m_ImageDimension == 0 || otherRegion.m_ImageDimension != m_ImageDimension) { return false; } - IndexType endCorner(region.m_ImageDimension); - SizeType size = region.GetSize(); + const auto & otherIndex = otherRegion.m_Index; + const auto & otherSize = otherRegion.m_Size; + for (unsigned int i = 0; i < m_ImageDimension; ++i) { - endCorner[i] = beginCorner[i] + size[i] - 1; - } - if (!this->IsInside(endCorner)) - { - return false; + if (otherIndex[i] < m_Index[i] || otherSize[i] == 0 || + otherIndex[i] + static_cast(otherSize[i]) > m_Index[i] + static_cast(m_Size[i])) + { + return false; + } } return true; } diff --git a/Modules/Core/Common/test/itkImageIORegionGTest.cxx b/Modules/Core/Common/test/itkImageIORegionGTest.cxx index dd00dd84c3c..8af2a359f27 100644 --- a/Modules/Core/Common/test/itkImageIORegionGTest.cxx +++ b/Modules/Core/Common/test/itkImageIORegionGTest.cxx @@ -197,3 +197,22 @@ TEST(ImageIORegion, IsAssignable) Expect_Assignable(GenerateRandomRegion(2), GenerateRandomRegion(2)); Expect_Assignable(GenerateRandomRegion(2), GenerateRandomRegion(3)); } + + +// Tests that a zero-sized region is not considered to be inside of another region. +TEST(ImageIORegion, ZeroSizedRegionIsNotInside) +{ + for (const unsigned int dimension : { 0, 2, 3 }) + { + itk::ImageIORegion region(dimension); + + region.SetSize(itk::ImageIORegion::SizeType(dimension, 2)); + + for (const auto indexValue : { -1, 0, 1 }) + { + itk::ImageIORegion zeroSizedRegion(dimension); + zeroSizedRegion.SetIndex(itk::ImageIORegion::IndexType(dimension, indexValue)); + EXPECT_FALSE(region.IsInside(zeroSizedRegion)); + }; + } +}