From 55c3bb14e182ebe7791f79b253b0968611be86ca Mon Sep 17 00:00:00 2001 From: Bradley Lowekamp Date: Sat, 14 Dec 2024 14:36:11 -0500 Subject: [PATCH] ENH: add test to reproduce SimpleITK issue #2220 Incorrect results are being computed on windows with the Compose filter (and other filters) and VectorImages of sizes >4GB. Bug was addressed in PR #5071. --- .../ImageCompose/test/CMakeLists.txt | 14 +++ .../itkComposeBigVectorImageFilterTest.cxx | 92 +++++++++++++++++++ 2 files changed, 106 insertions(+) create mode 100644 Modules/Filtering/ImageCompose/test/itkComposeBigVectorImageFilterTest.cxx diff --git a/Modules/Filtering/ImageCompose/test/CMakeLists.txt b/Modules/Filtering/ImageCompose/test/CMakeLists.txt index 5807afcd1a0..c97bc706962 100644 --- a/Modules/Filtering/ImageCompose/test/CMakeLists.txt +++ b/Modules/Filtering/ImageCompose/test/CMakeLists.txt @@ -5,6 +5,7 @@ set(ITKImageComposeTests itkCompose3DCovariantVectorImageFilterTest.cxx itkCompose2DVectorImageFilterTest.cxx itkComposeRGBImageFilterTest.cxx + itkComposeBigVectorImageFilterTest.cxx itkImageToVectorImageFilterTest.cxx itkImageReadRealAndImaginaryWriteComplexTest.cxx itkComposeRGBAImageFilterTest.cxx @@ -44,6 +45,19 @@ itk_add_test( COMMAND ITKImageComposeTestDriver itkComposeRGBImageFilterTest) + +if(ITK_COMPUTER_MEMORY_SIZE GREATER 6) + itk_add_test( + NAME + itkComposeBigVectorImageFilterTest + COMMAND + ITKImageComposeTestDriver + itkComposeBigVectorImageFilterTest) + set_tests_properties(itkComposeBigVectorImageFilterTest + PROPERTIES + RESOURCE_LOCK + MEMORY_SIZE) +endif() itk_add_test( NAME itkImageToVectorImageFilterTest diff --git a/Modules/Filtering/ImageCompose/test/itkComposeBigVectorImageFilterTest.cxx b/Modules/Filtering/ImageCompose/test/itkComposeBigVectorImageFilterTest.cxx new file mode 100644 index 00000000000..db3f6b66655 --- /dev/null +++ b/Modules/Filtering/ImageCompose/test/itkComposeBigVectorImageFilterTest.cxx @@ -0,0 +1,92 @@ +/*========================================================================= + * + * Copyright NumFOCUS + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0.txt + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *=========================================================================*/ + +#include "itkComposeImageFilter.h" +#include "itkVectorImage.h" +#include "itkTestingMacros.h" + +int +itkComposeBigVectorImageFilterTest(int, char *[]) +{ + + // Test case for SimpleITK issue #2220 + // Reported data corruption with 4G compose on Windows system + + + const unsigned int size = 400; + const unsigned int nchannels = 100; + using ImageType = itk::Image; + using VectorImageType = itk::VectorImage; + std::vector images; + + for (unsigned int i = 0; i < nchannels; ++i) + { + auto image = ImageType::New(); + ImageType::RegionType region; + ImageType::SizeType imageSize = { { size, size, size } }; + region.SetSize(imageSize); + image->SetRegions(region); + image->Allocate(); + image->FillBuffer(i % 250); + + images.push_back(image); + } + + using ComposeFilterType = itk::ComposeImageFilter; + ComposeFilterType::Pointer composeFilter = ComposeFilterType::New(); + for (unsigned int i = 0; i < nchannels; ++i) + { + composeFilter->SetInput(i, images[i]); + } + + composeFilter->Update(); + VectorImageType::Pointer img = composeFilter->GetOutput(); + std::cout << "Compose filter executed." << std::endl; + + for (unsigned int i = 0; i < nchannels; ++i) + { + itk::IndexValueType z = i; + std::map values; + + for (itk::IndexValueType y = 0; y < size; ++y) + { + for (itk::IndexValueType x = 0; x < size; ++x) + { + itk::Index<3> idx = { { x, y, z } }; + + auto pixel = img->GetPixel(idx); + if (pixel[i] != i % 250) + { + ++values[pixel[i]]; + } + } + } + + if (!values.empty()) + { + std::cout << "unexpected values: "; + for (auto v : values) + { + std::cout << v.first << "(" << v.second << "), "; + } + std::cout << std::endl; + } + ITK_TEST_EXPECT_TRUE(values.empty()); + } + return EXIT_SUCCESS; +}