A game framework written with osu! in mind.
1// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
2// See the LICENCE file in the repository root for full licence text.
3
4#nullable enable
5
6using System.Buffers;
7using SixLabors.ImageSharp;
8using SixLabors.ImageSharp.PixelFormats;
9
10namespace osu.Framework.Extensions.ImageExtensions
11{
12 public static class ImageExtensions
13 {
14 /// <summary>
15 /// Creates a contiguous and read-only span from the pixels of an <see cref="Image{TPixel}"/>.
16 /// Useful for retrieving unmanaged pointers to the entire pixel data of the <see cref="Image{TPixel}"/> for marshalling.
17 /// </summary>
18 /// <remarks>
19 /// The returned <see cref="ReadOnlyPixelSpan{TPixel}"/> must be disposed when usage is finished.
20 /// </remarks>
21 /// <param name="image">The <see cref="Image{TPixel}"/>.</param>
22 /// <typeparam name="TPixel">The type of pixels in <paramref name="image"/>.</typeparam>
23 /// <returns>The <see cref="ReadOnlyPixelSpan{TPixel}"/>.</returns>
24 public static ReadOnlyPixelSpan<TPixel> CreateReadOnlyPixelSpan<TPixel>(this Image<TPixel> image)
25 where TPixel : unmanaged, IPixel<TPixel>
26 => new ReadOnlyPixelSpan<TPixel>(image);
27
28 /// <summary>
29 /// Creates a contiguous and read-only memory from the pixels of an <see cref="Image{TPixel}"/>.
30 /// Useful for retrieving unmanaged pointers to the entire pixel data of the <see cref="Image{TPixel}"/> for marshalling.
31 /// </summary>
32 /// <remarks>
33 /// The returned <see cref="ReadOnlyPixelMemory{TPixel}"/> must be disposed when usage is finished.
34 /// </remarks>
35 /// <param name="image">The <see cref="Image{TPixel}"/>.</param>
36 /// <typeparam name="TPixel">The type of pixels in <paramref name="image"/>.</typeparam>
37 /// <returns>The <see cref="ReadOnlyPixelMemory{TPixel}"/>.</returns>
38 public static ReadOnlyPixelMemory<TPixel> CreateReadOnlyPixelMemory<TPixel>(this Image<TPixel> image)
39 where TPixel : unmanaged, IPixel<TPixel>
40 => new ReadOnlyPixelMemory<TPixel>(image);
41
42 /// <summary>
43 /// Creates a new contiguous memory buffer from the pixels in an <see cref="Image{TPixel}"/>.
44 /// </summary>
45 /// <remarks>
46 /// The returned <see cref="IMemoryOwner{T}"/> must be disposed when usage is finished.
47 /// </remarks>
48 /// <param name="image">The <see cref="Image{TPixel}"/>.</param>
49 /// <typeparam name="TPixel">The type of pixels in <paramref name="image"/>.</typeparam>
50 /// <returns>The <see cref="IMemoryOwner{T}"/>, containing the contiguous pixel memory.</returns>
51 internal static IMemoryOwner<TPixel> CreateContiguousMemory<TPixel>(this Image<TPixel> image)
52 where TPixel : unmanaged, IPixel<TPixel>
53 {
54 var allocatedOwner = SixLabors.ImageSharp.Configuration.Default.MemoryAllocator.Allocate<TPixel>(image.Width * image.Height);
55 var allocatedSpan = allocatedOwner.Memory.Span;
56
57 for (int r = 0; r < image.Height; r++)
58 image.GetPixelRowSpan(r).CopyTo(allocatedSpan.Slice(r * image.Width));
59
60 return allocatedOwner;
61 }
62 }
63}