diff --git a/src/ImageSharp/Memory/ByteMemoryManager{T}.cs b/src/ImageSharp/Memory/ByteMemoryManager{T}.cs new file mode 100644 index 000000000..3a9eb34c2 --- /dev/null +++ b/src/ImageSharp/Memory/ByteMemoryManager{T}.cs @@ -0,0 +1,67 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. +using System; +using System.Buffers; +using System.Runtime.InteropServices; + +namespace SixLabors.ImageSharp.Memory +{ + /// + /// A custom that can wrap of instances + /// and cast them to be for any arbitrary unmanaged value type. + /// + /// The value type to use when casting the wrapped instance. + internal sealed class ByteMemoryManager : MemoryManager + where T : unmanaged + { + /// + /// The wrapped of instance. + /// + private readonly Memory memory; + + /// + /// Initializes a new instance of the class. + /// + /// The of instance to wrap. + public ByteMemoryManager(Memory memory) + { + this.memory = memory; + } + + /// + protected override void Dispose(bool disposing) + { + } + + /// + public override Span GetSpan() + { + if (MemoryMarshal.TryGetArray(this.memory, out ArraySegment arraySegment)) + { + return MemoryMarshal.Cast(arraySegment.AsSpan()); + } + + if (MemoryMarshal.TryGetMemoryManager>(this.memory, out MemoryManager memoryManager)) + { + return MemoryMarshal.Cast(memoryManager.GetSpan()); + } + + // This should never be reached, as Memory can currently only be wrapping + // either a byte[] array or a MemoryManager instance in this case. + ThrowHelper.ThrowArgumentException("The input Memory instance was not valid.", nameof(this.memory)); + + return default; + } + + /// + public override MemoryHandle Pin(int elementIndex = 0) + { + return this.memory.Pin(); + } + + /// + public override void Unpin() + { + } + } +}