Skip to content

Commit 7b91070

Browse files
committed
BUG: Fix casting in PeriodicBoundaryCondition
Avoid dynamic_cast failure and use reinterpret_cast for efficiency in PeriodicBoundaryCondition. The type of ConstNeighborhoodIterator is known to be compatible with PeriodicBoundaryCondition when used within PeriodicBoundaryCondition. Add test that checks for previous segfault that occurred when ConstNeighborhoodIterator was templated with PeriodicBoundaryCondition. Co-authored-by: Tobias Wood <[email protected]> Change-Id: I134a6fc26a565c8405bf579f58cc4a2aee88385f
1 parent 6d41070 commit 7b91070

File tree

3 files changed

+35
-3
lines changed

3 files changed

+35
-3
lines changed

Modules/Core/Common/include/itkConstNeighborhoodIterator.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,7 @@ class ITK_TEMPLATE_EXPORT ConstNeighborhoodIterator:
413413
/** Resets the boundary condition to the internal, default conditions
414414
* specified by the template parameter. */
415415
virtual void ResetBoundaryCondition()
416-
{ m_BoundaryCondition = &m_InternalBoundaryCondition; }
416+
{ m_BoundaryCondition = reinterpret_cast< ImageBoundaryConditionPointerType >( &m_InternalBoundaryCondition ); }
417417

418418
/** Sets the internal, default boundary condition. */
419419
void SetBoundaryCondition(const TBoundaryCondition & c)

Modules/Core/Common/include/itkPeriodicBoundaryCondition.hxx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@ PeriodicBoundaryCondition< TInputImage, TOutputImage >
2929
::operator()(const OffsetType & point_index, const OffsetType & boundary_offset,
3030
const NeighborhoodType *data) const
3131
{
32-
const auto * iterator = dynamic_cast< const ConstNeighborhoodIterator< TInputImage, Self > * >( data );
32+
// This is guaranteed to be called with an object that is using
33+
// PeriodicBoundaryCondition
34+
const auto * iterator = reinterpret_cast< const ConstNeighborhoodIterator< TInputImage, Self > * >( data );
3335
typename TInputImage::PixelType * ptr;
3436
int linear_index = 0;
3537
unsigned int i;
@@ -83,7 +85,9 @@ PeriodicBoundaryCondition< TInputImage, TOutputImage >
8385
const NeighborhoodType *data,
8486
const NeighborhoodAccessorFunctorType & neighborhoodAccessorFunctor) const
8587
{
86-
const auto * iterator = dynamic_cast< const ConstNeighborhoodIterator< TInputImage, Self > * >( data );
88+
// This is guaranteed to be called with an object that is using
89+
// PeriodicBoundaryCondition
90+
const auto * iterator = reinterpret_cast< const ConstNeighborhoodIterator< TInputImage, Self > * >( data );
8791
typename TInputImage::InternalPixelType * ptr;
8892
int linear_index = 0;
8993
unsigned int i;

Modules/Core/Common/test/itkPeriodicBoundaryConditionTest.cxx

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,5 +288,33 @@ int itkPeriodicBoundaryConditionTest(int, char* [] )
288288
bc.Print( std::cout );
289289
vbc.Print( std::cout );
290290

291+
// Check when ConstNeighborhoodIterator is templated over the
292+
// PeriodicBoundaryCondition
293+
auto testImage = ImageType::New();
294+
ImageType::SizeType testSize = {{ 64, 64 }};
295+
ImageType::RegionType testRegion( testSize );
296+
testImage->SetRegions(testRegion);
297+
testImage->Allocate();
298+
299+
using BoundaryConditionType = itk::PeriodicBoundaryCondition< ImageType, ImageType >;
300+
using IterType = itk::ConstNeighborhoodIterator<ImageType, BoundaryConditionType>;
301+
IterType testIter(radius, testImage, testRegion);
302+
BoundaryConditionType boundaryCondition;
303+
testIter.OverrideBoundaryCondition(&boundaryCondition);
304+
std::vector<IterType::OffsetType> back;
305+
back.push_back( {{-1, 0 }} );
306+
back.push_back( {{ 0,-1 }} );
307+
back.push_back( {{ 0, 0 }} );
308+
testIter.SetNeedToUseBoundaryCondition(true);
309+
testIter.GoToBegin();
310+
while (!testIter.IsAtEnd()) {
311+
float sum = 0;
312+
for (size_t j = 0; j < back.size(); ++j) {
313+
const float d = testIter.GetPixel(back[j]);
314+
sum += d*d;
315+
}
316+
++testIter;
317+
}
318+
291319
return EXIT_SUCCESS;
292320
}

0 commit comments

Comments
 (0)