From 269e89d23f9df92223bbc87a4d8b136c138e1842 Mon Sep 17 00:00:00 2001 From: shimat Date: Mon, 19 Dec 2022 08:04:12 +0900 Subject: [PATCH] Add MatMemoryManager --- .../Fundamentals/MatMemoryManager.cs | 65 +++++++++++++++++++ src/OpenCvSharp/Modules/core/Mat/Mat.cs | 10 ++- 2 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 src/OpenCvSharp/Fundamentals/MatMemoryManager.cs diff --git a/src/OpenCvSharp/Fundamentals/MatMemoryManager.cs b/src/OpenCvSharp/Fundamentals/MatMemoryManager.cs new file mode 100644 index 0000000000..76af982737 --- /dev/null +++ b/src/OpenCvSharp/Fundamentals/MatMemoryManager.cs @@ -0,0 +1,65 @@ +using System; +using System.Buffers; + +namespace OpenCvSharp; + +/// +/// A MemoryManager over an OpenCvSharpMat +/// +/// The pointer is assumed to be fully unmanaged, or externally pinned - no attempt will be made to pin this data +public sealed unsafe class MatMemoryManager : MemoryManager + where T : unmanaged +{ + private readonly Mat wrapped; + + /// + /// Create a new UnmanagedMemoryManager instance at the given pointer and size + /// + /// It is assumed that the span provided is already unmanaged or externally pinned + public MatMemoryManager(Mat mat, bool isDataOwner = true) + { + if (!mat.IsContinuous()) + { + throw new ArgumentException("mat is not continuous", nameof(mat)); + } + + wrapped = isDataOwner ? mat : new Mat(mat); + } + + /// + public override Span GetSpan() => new((void*)wrapped.Data, (int)wrapped.Total()); + + /// + /// Provides access to a pointer that represents the data (note: no actual pin occurs) + /// + public override MemoryHandle Pin(int elementIndex = 0) + { + if (elementIndex < 0 || elementIndex >= wrapped.Total()) + { + throw new ArgumentOutOfRangeException(nameof(elementIndex)); + } + + var dims = wrapped.Dims; + var idxs = new int[dims]; + var remainIdx = elementIndex; + for (var dim = dims - 1; dim >= 0; dim--) + { + remainIdx = Math.DivRem(remainIdx, wrapped.Size(dim), out idxs[dim]); + } + + return new MemoryHandle((void*)wrapped.Ptr(idxs)); + } + + /// + /// Has no effect + /// + public override void Unpin() + { + } + + /// + /// Releases all resources associated with this object + /// + protected override void Dispose(bool disposing) + => wrapped.Dispose(); +} diff --git a/src/OpenCvSharp/Modules/core/Mat/Mat.cs b/src/OpenCvSharp/Modules/core/Mat/Mat.cs index 698c56dbf1..dc3ef4e403 100644 --- a/src/OpenCvSharp/Modules/core/Mat/Mat.cs +++ b/src/OpenCvSharp/Modules/core/Mat/Mat.cs @@ -3572,7 +3572,7 @@ public bool GetRectangularArray(out T[,] data) /// /// Primitive or Vec array to be copied /// Length of copied bytes - public bool SetArray(T[] data) + public bool SetArray(params T[] data) where T : unmanaged { CheckArgumentsForConvert(data); @@ -4107,5 +4107,13 @@ public void ForEachAsVec6d(MatForeachFunctionVec6d operation) #endregion + /// + /// Creates a new span over the Mat. + /// + /// + /// + public unsafe Span AsSpan() where T : unmanaged + => IsContinuous() ? new Span(DataPointer, (int)Total()) : Span.Empty; + #endregion }