Add row-stride overloads for memory APIs#3066
Merged
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR extends ImageSharp’s memory APIs to support strided (row-padded) pixel buffers by introducing row-stride overloads for loading/wrapping pixel data and refactoring internal copy/clone logic to be stride-aware via Buffer2D<T>.RowStride.
Changes:
- Added stride-aware overloads for
Image.LoadPixelData,ImageFrame.LoadPixelData, andImage.WrapMemory(pixels + bytes), including validation and updated docs. - Introduced
Buffer2D<T>.RowStrideplus new copy/wrap helpers to correctly handle strided layouts across processors and frame/image APIs. - Updated/added tests to cover stride behavior (copy semantics, wrap semantics, swap-or-copy behavior) and adjusted allocator validation expectations.
Reviewed changes
Copilot reviewed 26 out of 26 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/ImageSharp.Tests/Memory/DiscontiguousBuffers/MemoryGroupTests.cs | Removes older transform-related tests no longer applicable after refactor. |
| tests/ImageSharp.Tests/Memory/DiscontiguousBuffers/MemoryGroupTests.CopyTo.cs | Adds stride-aware MemoryGroup.CopyTo tests ensuring trailing padding isn’t required. |
| tests/ImageSharp.Tests/Memory/Buffer2DTests.cs | Updates allocator behavior expectations + splits invalid vs overflow dimensions tests. |
| tests/ImageSharp.Tests/Memory/Buffer2DTests.WrapMemory.cs | New tests for Buffer2D<T>.WrapMemory (packed/strided) and single-memory behavior. |
| tests/ImageSharp.Tests/Memory/Buffer2DTests.SwapOrCopyContent.cs | Adds coverage for swap/copy behavior with differing layouts and totals. |
| tests/ImageSharp.Tests/Memory/Buffer2DTests.CopyTo.cs | New tests for Buffer2D.CopyTo(Span) behavior with strided vs packed sources. |
| tests/ImageSharp.Tests/Image/ImageTests.WrapMemory.cs | Adds tests for Image.WrapMemory with strided pixel/byte buffers and copy/export behavior. |
| tests/ImageSharp.Tests/Image/ImageTests.LoadPixelData.cs | Adds tests for new LoadPixelData stride overloads + invalid stride/length cases. |
| tests/ImageSharp.Tests/Image/ImageFrameCollectionTests.Generic.cs | Updates expected exception message type formatting (long vs int). |
| src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessor{TPixel}.cs | Uses stride-aware PixelBuffer.CopyTo instead of memory-group copy. |
| src/ImageSharp/Processing/Processors/Transforms/Linear/RotateProcessor{TPixel}.cs | Uses stride-aware PixelBuffer.CopyTo instead of memory-group copy. |
| src/ImageSharp/Processing/Processors/Transforms/CropProcessor{TPixel}.cs | Uses stride-aware PixelBuffer.CopyTo instead of memory-group copy. |
| src/ImageSharp/Memory/TransformItemsInplaceDelegate.cs | Deletes unused delegate after refactor. |
| src/ImageSharp/Memory/MemoryAllocatorExtensions.cs | Adds positive-dimension guards for 2D allocations. |
| src/ImageSharp/Memory/DiscontiguousBuffers/MemoryGroupExtensions.cs | Reworks copy logic to support 2D regions with explicit source/target strides. |
| src/ImageSharp/Memory/Buffer2D{T}.cs | Adds RowStride, WrapMemory, stride-aware copy methods, and updates row access logic. |
| src/ImageSharp/Memory/Buffer2DRegion{T}.cs | Updates Stride semantics to reflect backing stride and adjusts clear/fill optimizations. |
| src/ImageSharp/Memory/Buffer2DExtensions.cs | Updates column-copy stride math and clone path to use Buffer2D.CopyTo. |
| src/ImageSharp/Image{TPixel}.cs | Propagates stride through internal constructors and routes pixel export/single-memory queries via frame/buffer. |
| src/ImageSharp/ImageFrame{TPixel}.cs | Adds stride-aware constructors and refactors copy/export/clear logic to use Buffer2D APIs. |
| src/ImageSharp/ImageFrameCollection{TPixel}.cs | Propagates row stride when wrapping external memory groups and updates non-compatible frame copy. |
| src/ImageSharp/ImageFrame.cs | Updates CopyPixelsTo abstraction to target Buffer2D<T> instead of MemoryGroup<T>. |
| src/ImageSharp/ImageFrame.LoadPixelData.cs | Adds stride overloads and performs row-by-row copy from strided sources. |
| src/ImageSharp/Image.WrapMemory.cs | Adds row-stride overloads for wrapping pixel/byte/pointer memory and centralizes stride validation helpers. |
| src/ImageSharp/Image.LoadPixelData.cs | Adds row-stride overloads and routes to stride-aware copy-from logic. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Prerequisites
Description
See #2821 and #2932
This pull request adds support for loading and working with images that use a custom row stride, allowing more flexible memory layouts and compatibility with strided pixel buffers. It introduces new overloads for loading pixel data with row stride parameters, updates constructors and methods to handle row stride, and refactors internal buffer handling to consistently use the new stride-aware logic.
Strided Pixel Data Loading and API Extensions
Image.LoadPixelDataandImageFrame.LoadPixelDatafor loading pixel data from bothReadOnlySpan<TPixel>andReadOnlySpan<byte>with explicit row stride parameters, including comprehensive documentation and validation. [1] [2] [3] [4] [5] [6]ImageFrame<TPixel>andImageFrameCollection<TPixel>to accept and propagate row stride, ensuring correct buffer wrapping and initialization for strided data. [1] [2] [3]Buffer and Memory Handling Refactor
Buffer2D<TPixel>logic, replacing previous contiguous memory group operations. This includes changes to pixel copying, frame cloning, and pixel data export methods. [1] [2] [3] [4] [5]Validation and Error Handling