From f2a6d33a71d6f4ba0c6e0afcd30a1a1afebe6978 Mon Sep 17 00:00:00 2001 From: Hans Johnson Date: Tue, 5 May 2026 21:03:09 -0500 Subject: [PATCH 1/3] COMP: VTI test: use GetModifiableImageIO() for ITK_FUTURE_LEGACY_REMOVE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit itkVTIImageIOReadWriteTest at line 92 took the bare-name 'GetImageIO()' overload, which the 'itkGetModifiableObjectMacro(ImageIO, ImageIOBase)' declaration only emits when 'ITK_FUTURE_LEGACY_REMOVE' is OFF (the historical default). When the future-strict mode is ON, the macro emits only 'GetModifiableImageIO()' and 'const ImageIOBase * GetImageIO() const'; the bare 'GetImageIO()' returns a const pointer and the test fails to compile with four cascading errors: error: no matching member function for call to 'SetFileName' error: 'this' argument to 'ReadImageInformation' has type 'const ImageIOBase', but function is not marked const error: no matching function for call to 'internalMain' (line 104) error: no matching function for call to 'internalMain' (line 106) The PR-time CI green-lit the test because no per-PR builder configures 'ITK_FUTURE_LEGACY_REMOVE=ON'; the failure surfaced only after the nightly Mac AppleClang dbg-Universal pipelines (Rogue Research 17/19/ 20/24/25/26/27) ran, where the strict-future flag is set. Switching to 'GetModifiableImageIO()' compiles cleanly under both legacy and strict-future macro expansions. Observed on the 2026-05-05 nightly across every Mac dbg-Universal / ASanUBSan / TSan / arm64 build site (5+ buildgroups, 4 errors per site). No behavioral change for runtime users — the call site needed a non-const ImageIOBase pointer all along. --- Modules/IO/VTK/test/itkVTIImageIOReadWriteTest.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/IO/VTK/test/itkVTIImageIOReadWriteTest.cxx b/Modules/IO/VTK/test/itkVTIImageIOReadWriteTest.cxx index 7bb22e43d7e..dd9fb617c58 100644 --- a/Modules/IO/VTK/test/itkVTIImageIOReadWriteTest.cxx +++ b/Modules/IO/VTK/test/itkVTIImageIOReadWriteTest.cxx @@ -89,7 +89,7 @@ itkVTIImageIOReadWriteTest(int argc, char * argv[]) reader->SetFileName(inputImage); ITK_TRY_EXPECT_NO_EXCEPTION(reader->UpdateOutputInformation()); - auto imageIO = reader->GetImageIO(); + auto imageIO = reader->GetModifiableImageIO(); imageIO->SetFileName(inputImage); ITK_TRY_EXPECT_NO_EXCEPTION(imageIO->ReadImageInformation()); From 1b875e9262eff336e83bfe5f608b48ba58d79683 Mon Sep 17 00:00:00 2001 From: Hans Johnson Date: Tue, 5 May 2026 21:04:00 -0500 Subject: [PATCH 2/3] COMP: Spell template args on ImageRegion iterators in DispatchedCopy itkImageAlgorithm::DispatchedCopy(...) at lines 56-57 declares the input/output region iterators via class-template-argument-deduction ('ImageRegionConstIterator it(inImage, inRegion);'). AppleClang in the dbg-Universal builds with strict CTAD checking refuses the deduction with 'no viable constructor or deduction guide for deduction of template arguments of "ImageRegionConstIterator"' / "ImageRegionIterator". The neighboring 'ImageScanline*Iterator' declarations a few lines above ship their own deduction guides and are accepted on the same compiler; the Region iterators do not. Spelling out the template arguments explicitly compiles cleanly on every supported toolchain and removes the dependence on a deduction guide that AppleClang's CTAD does not synthesize. Observed on the 2026-05-05 nightly: - MacOS-Rel-Python (12 errors) - MacOS-Rel-MorphologicalContourInterpolation (12 errors) Both buildgroups configure with stricter CTAD than the per-PR Linux and Windows builders, which is why the issue surfaced only at nightly time. No behavioral or runtime change. --- Modules/Core/Common/include/itkImageAlgorithm.hxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/Core/Common/include/itkImageAlgorithm.hxx b/Modules/Core/Common/include/itkImageAlgorithm.hxx index 94fcb4925a9..9a44b4e9796 100644 --- a/Modules/Core/Common/include/itkImageAlgorithm.hxx +++ b/Modules/Core/Common/include/itkImageAlgorithm.hxx @@ -53,8 +53,8 @@ ImageAlgorithm::ReferenceCopy(const InputImageType * inIma return; } - ImageRegionConstIterator it(inImage, inRegion); - ImageRegionIterator ot(outImage, outRegion); + ImageRegionConstIterator it(inImage, inRegion); + ImageRegionIterator ot(outImage, outRegion); while (!it.IsAtEnd()) { From 020f37d9332cf58de3c0372c81e92f5db71d265b Mon Sep 17 00:00:00 2001 From: "Hans J. Johnson" Date: Wed, 6 May 2026 07:44:45 -0500 Subject: [PATCH 3/3] ENH: Add RLEImage GTest covering ImageAlgorithm::Copy iterator deduction Locks in correct iterator type deduction for itk::ImageAlgorithm::Copy when the source or destination is a partially-specialized Image-like template (RLEImage). Discovered while ingesting the MorphologicalContourInterpolation remote module: the prior CTAD form in itkImageAlgorithm.hxx silently selected the primary-template iterator for RLEImage on gcc (runtime SIGABRT) while AppleClang 17 refused to compile. The companion fix in this branch spells the template arguments explicitly; this regression test exercises both copy directions so a future CTAD re-introduction is caught at test time on every supported toolchain. The same trap can affect any future user of itk::ImageAlgorithm::Copy with a partially-specialized Image-like template. --- .../Filtering/RLEImage/test/CMakeLists.txt | 4 + .../test/itkRLEImageAlgorithmCopyGTest.cxx | 84 +++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 Modules/Filtering/RLEImage/test/itkRLEImageAlgorithmCopyGTest.cxx diff --git a/Modules/Filtering/RLEImage/test/CMakeLists.txt b/Modules/Filtering/RLEImage/test/CMakeLists.txt index 4a142680227..d148853ba79 100644 --- a/Modules/Filtering/RLEImage/test/CMakeLists.txt +++ b/Modules/Filtering/RLEImage/test/CMakeLists.txt @@ -16,6 +16,10 @@ set( createtestdriver( RLEImage "${RLEImage-Test_LIBRARIES}" "${RLEImageTests}" ) +set(RLEImageGTests itkRLEImageAlgorithmCopyGTest.cxx) + +creategoogletestdriver(RLEImage "${RLEImage-Test_LIBRARIES}" "${RLEImageGTests}") + add_executable( runFromIDE manualTest.cxx diff --git a/Modules/Filtering/RLEImage/test/itkRLEImageAlgorithmCopyGTest.cxx b/Modules/Filtering/RLEImage/test/itkRLEImageAlgorithmCopyGTest.cxx new file mode 100644 index 00000000000..3b229fbb240 --- /dev/null +++ b/Modules/Filtering/RLEImage/test/itkRLEImageAlgorithmCopyGTest.cxx @@ -0,0 +1,84 @@ +/*========================================================================= + * + * 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 "itkImageAlgorithm.h" +#include "itkRLEImage.h" + +#include + +// Locks in correct iterator deduction in ImageAlgorithm::Copy when the +// source or destination is a partially-specialized Image-like template. +namespace +{ +constexpr unsigned int Dimension = 3; +using PixelType = short; +using RLEType = itk::RLEImage; +using ImageType = itk::Image; + +RLEType::RegionType +MakeRegion() +{ + RLEType::SizeType size = { { 4, 4, 4 } }; + RLEType::IndexType start = { { 0, 0, 0 } }; + return RLEType::RegionType{ start, size }; +} +} // namespace + +TEST(RLEImageAlgorithmCopy, FromRLEToImage) +{ + const auto region = MakeRegion(); + + auto rle = RLEType::New(); + rle->SetRegions(region); + rle->Allocate(); + rle->FillBuffer(7); + + auto dst = ImageType::New(); + dst->SetRegions(region); + dst->Allocate(); + dst->FillBuffer(0); + + itk::ImageAlgorithm::Copy(rle.GetPointer(), dst.GetPointer(), region, region); + + for (itk::ImageRegionConstIterator it(dst, region); !it.IsAtEnd(); ++it) + { + ASSERT_EQ(it.Get(), 7) << "Mismatch at " << it.GetIndex(); + } +} + +TEST(RLEImageAlgorithmCopy, FromImageToRLE) +{ + const auto region = MakeRegion(); + + auto src = ImageType::New(); + src->SetRegions(region); + src->Allocate(); + src->FillBuffer(11); + + auto rleDst = RLEType::New(); + rleDst->SetRegions(region); + rleDst->Allocate(); + rleDst->FillBuffer(0); + + itk::ImageAlgorithm::Copy(src.GetPointer(), rleDst.GetPointer(), region, region); + + for (itk::ImageRegionConstIterator it(rleDst, region); !it.IsAtEnd(); ++it) + { + ASSERT_EQ(it.Get(), 11) << "Mismatch at " << it.GetIndex(); + } +}