Skip to content

ENH: Fix buffer ownership and a redundant copy in SimpleITK interop - #6828

Merged
hjmjohnson merged 1 commit into
InsightSoftwareConsortium:mainfrom
blowekamp:follow-up-image-from-simpleitk-deep-copy
Sep 4, 2026
Merged

ENH: Fix buffer ownership and a redundant copy in SimpleITK interop#6828
hjmjohnson merged 1 commit into
InsightSoftwareConsortium:mainfrom
blowekamp:follow-up-image-from-simpleitk-deep-copy

Conversation

@blowekamp

@blowekamp blowekamp commented Sep 2, 2026

Copy link
Copy Markdown
Member

Follow-up to #6811. Fixes buffer-ownership in image_from_simpleitk and removes a redundant copy in simpleitk_from_image.

image_from_simpleitk wrapped a numpy buffer via image_view_from_array, giving the itk::Image a pixel container that does not own its memory, which is unsafe for Graft() and in-place filters. It now reads pixels with sitk.GetArrayViewFromImage (no copy) and builds the ITK image with itk.image_from_array (deep copy into an ITK-owned buffer) — same one copy overall, with correct ownership.

simpleitk_from_image read the ITK image with itk.array_from_image (a deep copy) purely to hand it to sitk.GetImageFromArray, which deep-copies again into the buffer the new sitk.Image owns. It now reads with itk.array_view_from_image instead, dropping the redundant first copy.

Why the ownership fix matters

image_view_from_array marks the itk::Image pixel container as not managing its own memory, since it imports a pointer into a numpy-owned buffer. Filters that graft their output onto a pre-existing image, or that reuse/reallocate a buffer in place, assume the container they write into owns its memory. image_from_array deep-copies into a container ITK allocates and owns, removing that hazard.

Testing

black --target-version py310 and the project pre-commit hooks pass on the changed file. Not exercised against real SimpleITK locally (no SimpleITK/itk build environment available). The in-tree simpleitk_protocol.py test does not cover either function directly; per #6811 it stubs only the geometry accessors, by design (round-trip fidelity is owned by an out-of-tree suite).

@github-actions github-actions Bot added type:Bug Inconsistencies or issues which will cause an incorrect result under some or all circumstances area:Python wrapping Python bindings for a class labels Sep 2, 2026

@dzenanz dzenanz left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. For the other conversion direction, it seems that buffer is copied twice. Maybe replace array = itk.array_from_image(image) by array = itk.array_view_from_image(image)?

@blowekamp blowekamp changed the title BUG: image_from_simpleitk must deep-copy into an ITK-owned buffer ENH: Fix buffer ownership and a redundant copy in SimpleITK interop Sep 2, 2026
@hjmjohnson

Copy link
Copy Markdown
Member

@greptile review

@greptile-apps

greptile-apps Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The conversion updates preserve image pixels after the source image is modified or released, while avoiding an unnecessary intermediate copy.

Confidence Score: 5/5

No blocking failure remains.

The exercised SimpleITK and ITK conversion flows retained independent pixel data after source mutation and deletion.

T-Rex T-Rex Logs

What T-Rex did

  • Created an isolated runtime with ITK 5.4.7 and SimpleITK 2.5.6 and loaded the staged PR extras.py, which uses compatibility aliases for ITK type names.
  • Ran the ownership conversion probe script to exercise bidirectional image conversions, mutate sources, delete them, and force garbage collection.
  • Validated pixel preservation: both conversion directions preserved the original pixels, as shown in the baseline and post-mutation captures.
  • Noted compatibility alias behavior as part of loading extras.py, bridging ITK 5.4.7 naming with the current PR's type names.

View all artifacts

T-Rex Ran code and verified through T-Rex

Reviews (2): Last reviewed commit: "STYLE: Condense a two-line comment to on..." | Re-trigger Greptile

Comment thread Wrapping/Generators/Python/itk/support/extras.py Outdated
@github-actions github-actions Bot added type:Enhancement Improvement of existing methods or implementation and removed type:Bug Inconsistencies or issues which will cause an incorrect result under some or all circumstances labels Sep 3, 2026
@blowekamp
blowekamp marked this pull request as ready for review September 3, 2026 20:51
image_from_simpleitk used itk.image_view_from_array, giving the
itk::Image a pixel container that does not own its memory --
unsafe for Graft() and in-place filters. It now deep-copies via
itk.image_from_array instead.

simpleitk_from_image read the ITK image with itk.array_from_image
(a deep copy) only to hand it to sitk.GetImageFromArray, which
deep-copies again. It now reads a view instead, dropping the
redundant copy.
@blowekamp
blowekamp force-pushed the follow-up-image-from-simpleitk-deep-copy branch from 7325ce3 to a0a6c9e Compare September 4, 2026 12:22
@hjmjohnson
hjmjohnson merged commit 58d9115 into InsightSoftwareConsortium:main Sep 4, 2026
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:Python wrapping Python bindings for a class type:Enhancement Improvement of existing methods or implementation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants