Correctly implemented image.ConverTo and added tests

This commit is contained in:
DarthAffe committed 2024-07-14 21:35:32 +02:00
1 parent 19c9143fa1
commit dd5f742b48
4 files changed
+75 -7

No files matched your search

+15 -4
View File
@@ -51,7 +51,6 @@ public sealed class Image<T> : IImage<T>
}
}
IImage IImage.this[int x, int y, int width, int height]
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -123,11 +122,23 @@ public sealed class Image<T> : IImage<T>
return new Image<T>(data, 0, 0, width, height, stride);
}
public void ConvertTo<TColor>()
public IImage<TColor> ConvertTo<TColor>()
where TColor : struct, IColor
{
for (int i = 0; i < Height; i++)
MemoryMarshal.Cast<byte, T>(_buffer.AsSpan().Slice(((i + _y) * _stride) + _x, Width)).ConvertInPlace<T, TColor>();
int targetBpp = TColor.ColorFormat.BytesPerPixel;
if (targetBpp == ColorFormat.BytesPerPixel)
{
byte[] data = ToRawArray();
MemoryMarshal.Cast<byte, T>(data.AsSpan()).ConvertInPlace<T, TColor>();
return new Image<TColor>(data, 0, 0, Width, Height, Width * targetBpp);
}
else
{
byte[] data = ToRawArray();
byte[] target = new byte[Width * Height * targetBpp];
MemoryMarshal.Cast<byte, T>(data.AsSpan()).Convert(MemoryMarshal.Cast<byte, TColor>(target));
return new Image<TColor>(target, 0, 0, Width, Height, Width * targetBpp);
}
}
public void CopyTo(Span<T> destination) => CopyTo(MemoryMarshal.AsBytes(destination));
+2 -2
View File
@@ -60,8 +60,8 @@ public interface IImage : IEnumerable<IColor>
/// <returns>The <inheritdoc cref="RefImage{TColor}"/>.</returns>
RefImage<TColor> AsRefImage<TColor>() where TColor : struct, IColor;
void ConvertTo<T>() where T : struct, IColor;
IImage<TColor> ConvertTo<TColor>() where TColor : struct, IColor;
/// <summary>
/// Copies the contents of this <see cref="IImage"/> into a destination <see cref="Span{T}"/> instance.
/// </summary>
+12 -1
View File
@@ -33,7 +33,7 @@ public static unsafe partial class PixelHelper
if (colors == null) throw new ArgumentNullException(nameof(colors));
TTarget[] buffer = new TTarget[colors.Length];
Convert<TSource, TTarget>(colors, buffer.AsSpan());
Convert(colors, buffer.AsSpan());
return buffer;
}
@@ -48,6 +48,17 @@ public static unsafe partial class PixelHelper
return buffer;
}
public static void Convert<TSource, TTarget>(this Span<TSource> source, Span<TTarget> target)
where TSource : struct, IColor
where TTarget : struct, IColor
{
if (source == null) throw new ArgumentNullException(nameof(source));
if (target == null) throw new ArgumentNullException(nameof(target));
if (target.Length < source.Length) throw new ArgumentException($"Target-buffer is not big enough. {target.Length} < {source.Length}", nameof(target));
Convert(MemoryMarshal.AsBytes(source), MemoryMarshal.AsBytes(target), TSource.ColorFormat, TTarget.ColorFormat);
}
public static void Convert<TSource, TTarget>(this ReadOnlySpan<TSource> source, Span<TTarget> target)
where TSource : struct, IColor
where TTarget : struct, IColor