Skip to content

Commit 63f4ab7

Browse files
committed
BUG: Fix ImageRegionSplitters with zero sized image
When the image had a zero size, undefined results of division by zero occoured. For both the ImageRegionSplitterSlowDimension and the ImageRegionSplitterDirection classes when a region's size is zero, the region has one "split" region of a zero sized region.
1 parent 0539a2c commit 63f4ab7

File tree

5 files changed

+37
-6
lines changed

5 files changed

+37
-6
lines changed

Modules/Core/Common/src/itkImageRegionSplitterDirection.cxx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,10 @@ ImageRegionSplitterDirection::GetNumberOfSplitsInternal(unsigned int dim
4141
const SizeValueType regionSize[],
4242
unsigned int requestedNumber) const
4343
{
44+
requestedNumber = std::max(1u, requestedNumber);
4445
// split on the outermost dimension available
4546
int splitAxis = dim - 1;
46-
while (regionSize[splitAxis] == 1 || splitAxis == (int)m_Direction)
47+
while (regionSize[splitAxis] <= 1 || splitAxis == (int)m_Direction)
4748
{
4849
--splitAxis;
4950
if (splitAxis < 0)
@@ -71,7 +72,7 @@ ImageRegionSplitterDirection::GetSplitInternal(unsigned int dim,
7172
// split on the outermost dimension available
7273
// and avoid the current dimension
7374
int splitAxis = dim - 1;
74-
while (regionSize[splitAxis] == 1 || splitAxis == (int)m_Direction)
75+
while (regionSize[splitAxis] <= 1 || splitAxis == (int)m_Direction)
7576
{
7677
--splitAxis;
7778
if (splitAxis < 0)

Modules/Core/Common/src/itkImageRegionSplitterSlowDimension.cxx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,10 @@ ImageRegionSplitterSlowDimension::GetNumberOfSplitsInternal(unsigned int
3030
const SizeValueType regionSize[],
3131
unsigned int requestedNumber) const
3232
{
33+
requestedNumber = std::max(1u, requestedNumber);
3334
// split on the outermost dimension available
3435
int splitAxis = dim - 1;
35-
while (regionSize[splitAxis] == 1)
36+
while (regionSize[splitAxis] <= 1)
3637
{
3738
--splitAxis;
3839
if (splitAxis < 0)
@@ -57,10 +58,9 @@ ImageRegionSplitterSlowDimension::GetSplitInternal(unsigned int dim,
5758
IndexValueType regionIndex[],
5859
SizeValueType regionSize[]) const
5960
{
60-
6161
// split on the outermost dimension available
6262
unsigned int splitAxis = dim - 1;
63-
while (regionSize[splitAxis] == 1)
63+
while (regionSize[splitAxis] <= 1)
6464
{
6565
if (splitAxis == 0)
6666
{ // cannot split

Modules/Core/Common/test/itkImageRegionSplitterDirectionTest.cxx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ itkImageRegionSplitterDirectionTest(int, char *[])
3838

3939
const itk::ImageRegion<2> lpRegion = region;
4040

41+
ITK_TEST_EXPECT_EQUAL(splitter->GetNumberOfSplits(lpRegion, 0), 1);
4142
ITK_TEST_EXPECT_EQUAL(splitter->GetNumberOfSplits(lpRegion, 1), 1);
4243
ITK_TEST_EXPECT_EQUAL(splitter->GetNumberOfSplits(lpRegion, 2), 2);
4344
ITK_TEST_EXPECT_EQUAL(splitter->GetNumberOfSplits(lpRegion, 3), 3);
@@ -66,6 +67,13 @@ itkImageRegionSplitterDirectionTest(int, char *[])
6667
ITK_TEST_EXPECT_EQUAL(region.GetSize(0), 5);
6768
ITK_TEST_EXPECT_EQUAL(region.GetSize(1), 11);
6869

70+
const itk::ImageRegion<2> lpRegion2{}; // default zero sized
71+
region = lpRegion2;
72+
ITK_TEST_EXPECT_EQUAL(1, splitter->GetNumberOfSplits(lpRegion2, 1));
73+
ITK_TEST_EXPECT_EQUAL(1, splitter->GetSplit(1, 1, region));
74+
ITK_TEST_EXPECT_EQUAL(region.GetSize(0), 0);
75+
ITK_TEST_EXPECT_EQUAL(region.GetSize(1), 0);
76+
6977

7078
return EXIT_SUCCESS;
7179
}

Modules/Core/Common/test/itkImageRegionSplitterSlowDimensionTest.cxx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ itkImageRegionSplitterSlowDimensionTest(int, char *[])
3737
region.SetIndex(1, 10);
3838

3939
const itk::ImageRegion<2> lpRegion = region;
40-
40+
ITK_TEST_EXPECT_EQUAL(splitter->GetNumberOfSplits(lpRegion, 0), 1);
4141
ITK_TEST_EXPECT_EQUAL(splitter->GetNumberOfSplits(lpRegion, 1), 1);
4242
ITK_TEST_EXPECT_EQUAL(splitter->GetNumberOfSplits(lpRegion, 2), 2);
4343
ITK_TEST_EXPECT_EQUAL(splitter->GetNumberOfSplits(lpRegion, 3), 3);
@@ -58,6 +58,12 @@ itkImageRegionSplitterSlowDimensionTest(int, char *[])
5858
ITK_TEST_EXPECT_EQUAL(region.GetSize(0), 10);
5959
ITK_TEST_EXPECT_EQUAL(region.GetSize(1), 5);
6060

61+
const itk::ImageRegion<2> lpRegion2{}; // default zero sized
62+
region = lpRegion2;
63+
ITK_TEST_EXPECT_EQUAL(1, splitter->GetNumberOfSplits(lpRegion2, 1));
64+
ITK_TEST_EXPECT_EQUAL(1, splitter->GetSplit(1, 1, region));
65+
ITK_TEST_EXPECT_EQUAL(region.GetSize(0), 0);
66+
ITK_TEST_EXPECT_EQUAL(region.GetSize(1), 0);
6167

6268
return EXIT_SUCCESS;
6369
}

Modules/Filtering/LabelMap/test/itkLabelImageToLabelMapFilterTest.cxx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,19 @@
2020
#include "itkLabelImageToLabelMapFilter.h"
2121
#include "itkTestingMacros.h"
2222

23+
void
24+
zeroSizeCase()
25+
{
26+
// test filter with zero sized image
27+
auto p_filter = itk::LabelImageToLabelMapFilter<itk::Image<unsigned char, 3>>::New();
28+
auto p_image = itk::Image<unsigned char, 3>::New();
29+
p_image->SetRegions(itk::Size<3>{ 0, 0, 0 });
30+
p_image->Allocate(true);
31+
32+
p_filter->SetInput(p_image);
33+
p_filter->Update();
34+
}
35+
2336
int
2437
itkLabelImageToLabelMapFilterTest(int argc, char * argv[])
2538
{
@@ -131,5 +144,8 @@ itkLabelImageToLabelMapFilterTest(int argc, char * argv[])
131144

132145
conversion->Print(std::cout);
133146

147+
zeroSizeCase();
148+
149+
134150
return EXIT_SUCCESS;
135151
}

0 commit comments

Comments
 (0)