using System;
using InlineIL;
using Robust.Shared.Maths;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats;
using Color = Robust.Shared.Maths.Color;
namespace Robust.Client.Utility
{
public static class ImageSharpExt
{
public static Color ConvertImgSharp(this Rgba32 color)
{
return new Color(color.R, color.G, color.B, color.A);
}
public static Rgba32 ConvertImgSharp(this Color color)
{
return new Rgba32(color.R, color.G, color.B, color.A);
}
///
/// Blit an image into another, with the specified offset.
///
/// The image to copy data from.
/// The sub section of that will be copied.
///
/// The offset into that data will be copied into.
///
/// The image to copy to.
/// The type of pixel stored in the images.
public static void Blit(this Image source, UIBox2i sourceRect,
Image destination, Vector2i destinationOffset)
where T : unmanaged, IPixel
{
// TODO: Bounds checks.
Blit(source.GetPixelSpan(), source.Width, sourceRect, destination, destinationOffset);
}
public static void Blit(this ReadOnlySpan source, int sourceWidth, UIBox2i sourceRect,
Image destination, Vector2i destinationOffset) where T : unmanaged, IPixel
{
var dstSpan = destination.GetPixelSpan();
var dstWidth = destination.Width;
var (ox, oy) = destinationOffset;
for (var y = 0; y < sourceRect.Height; y++)
{
var sourceRowOffset = sourceWidth * (y + sourceRect.Top) + sourceRect.Left;
var destRowOffset = dstWidth * (y + oy) + ox;
for (var x = 0; x < sourceRect.Width; x++)
{
var pixel = source[x + sourceRowOffset];
dstSpan[x + destRowOffset] = pixel;
}
}
}
///
/// Gets a to the backing data if the backing group consists of a single contiguous memory buffer.
///
/// The referencing the memory area.
public static Span GetPixelSpan(this Image image) where T : unmanaged, IPixel
{
IL.Push(image.Frames.RootFrame);
IL.Emit.Call(new MethodRef(typeof(ImageFrame), "get_PixelBuffer"));
IL.Emit.Call(new MethodRef(typeof(Buffer2D), "GetSingleSpan"));
IL.Emit.Ret();
throw IL.Unreachable();
}
}
}